diff options
Diffstat (limited to 'core')
53 files changed, 1826 insertions, 137 deletions
diff --git a/core/css/apps.css b/core/css/apps.css index 0e6a080c9cd..a8dfc5b7ed1 100644 --- a/core/css/apps.css +++ b/core/css/apps.css @@ -29,10 +29,14 @@ -moz-box-sizing: border-box; box-sizing: border-box; } #app-navigation .active, -#app-navigation .active a, -#app-navigation li:hover > a { +#app-navigation .active a { background-color: #ddd; } +#app-navigation li:hover > a, +#app-navigation .selected, +#app-navigation .selected a { + background-color: #ccc; +} /* special rules for first-level entries and folders */ #app-navigation > ul > li { @@ -151,9 +155,6 @@ transition: padding-bottom 500ms ease 0s; padding-bottom: 40px; } -#app-navigation .personalblock > legend { /* TODO @Raydiation: still needed? */ - padding: 10px 0; margin: 0; -} #app-navigation .error { color: #dd1144; } @@ -242,3 +243,24 @@ button.loading { padding-right: 30px; } + +/* general styles for the content area */ +.section { + display: block; + padding: 30px; + color: #555; + border-top: 1px solid #ddd; +} +.section h2 { + font-size: 20px; + margin-bottom: 7px; +} +.section h3 { + font-size: 16px; +} +/* slight position correction of checkboxes and radio buttons */ +.section input[type="checkbox"], +.section input[type="radio"] { + vertical-align: -2px; + margin-right: 4px; +} diff --git a/core/css/auth.css b/core/css/auth.css deleted file mode 100644 index 70df9f0ae0f..00000000000 --- a/core/css/auth.css +++ /dev/null @@ -1,39 +0,0 @@ -h2 { - font-size:32px; - font-weight:700; - margin-bottom:16px; - white-space:nowrap; -} - -ul.scopes { - list-style:disc; -} - -ul.scopes li { - white-space:nowrap; -} - -h2 img { - width:50%; -} - -#oauth { - width:320px; - margin:64px auto 32px; -} - -#allow-auth { - background-color:#5c3; - box-shadow:0 1px 1px #fff, 0 1px 1px #5f3 inset; - color:#fff; - text-shadow:#5e3 0 1px 0; -} - -#deny-auth { - background:none; - border:0; - box-shadow:0 0 0 #fff, 0 0 0 #fff inset; - font-size:19px; - margin:11px; - padding:0; -} diff --git a/core/css/styles.css b/core/css/styles.css index 2c043ab724c..57e2c4479a1 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -101,11 +101,18 @@ input[type="time"], textarea, select, button, .button, +input[type="submit"], +input[type="button"], #quota, .pager li a { - width:10em; margin:.3em; padding:.6em .5em .4em; - font-size:1em; - background:#fff; color:#333; border:1px solid #ddd; outline:none; + width: 130px; + margin: 3px 3px 3px 0; + padding: 7px 6px 5px; + font-size: 13px; + background-color: #fff; + color: #333; + border: 1px solid #ddd; + outline: none; border-radius: 3px; } input[type="hidden"] { @@ -170,14 +177,12 @@ input[type="submit"], input[type="button"], button, .button, #quota, select, .pager li a { width: auto; - padding: .4em; + padding: 5px; background-color: rgba(240,240,240,.9); font-weight: bold; color: #555; border: 1px solid rgba(190,190,190,.9); cursor: pointer; - border-radius: 3px; - outline: none; } input[type="submit"]:hover, input[type="submit"]:focus, input[type="button"]:hover, input[type="button"]:focus, @@ -278,6 +283,10 @@ input[type="submit"].enabled { padding: 7px 10px } +#controls .button.hidden { + display: none; +} + #content { position:relative; height:100%; width:100%; } #content .hascontrols { position: relative; @@ -793,20 +802,12 @@ tr .action { width:16px; height:16px; } tr:hover .action:hover, .selectedActions a:hover, .header-action:hover { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; } tbody tr:hover, tr:active { background-color:#f8f8f8; } -#body-settings h2 { - font-size: 20px; - font-weight: normal; - margin-bottom: 7px; -} -#body-settings .personalblock, #body-settings .helpblock { - padding: 30px; - color: #555; - border-top: 1px solid #ddd; -} -#body-settings .personalblock#quota { position:relative; padding:0; } -#body-settings #controls+.helpblock { position:relative; margin-top:3em; } code { font-family:"Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", monospace; } +#quota { + position: relative; + padding: 0; +} #quota div { padding: 0; background-color: rgb(220,220,220); @@ -925,6 +926,9 @@ div.crumb { background: url('../img/breadcrumb.svg') no-repeat right center; height: 44px; } +div.crumb.hidden { + display: none; +} div.crumb a, div.crumb span { position: relative; diff --git a/core/js/compatibility.js b/core/js/compatibility.js index 6548f95d42b..c07288857f2 100644 --- a/core/js/compatibility.js +++ b/core/js/compatibility.js @@ -148,3 +148,7 @@ function outerHTML(node){ return h; })(node); } + +// devicePixelRatio for IE10 +window.devicePixelRatio = window.devicePixelRatio || + window.screen.deviceXDPI / window.screen.logicalXDPI || 1; diff --git a/core/js/core.json b/core/js/core.json index 665e2485a90..05c2a17a679 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -6,7 +6,8 @@ "jquery-showpassword.js", "jquery.infieldlabel.js", "jquery.placeholder.js", - "jquery-tipsy.js" + "jquery-tipsy.js", + "underscore.js" ], "modules": [ "compatibility.js", diff --git a/core/js/jquery.avatar.js b/core/js/jquery.avatar.js index 381c42d9dbb..7c19cb321fe 100644 --- a/core/js/jquery.avatar.js +++ b/core/js/jquery.avatar.js @@ -77,7 +77,7 @@ var url = OC.generateUrl( '/avatar/{user}/{size}?requesttoken={requesttoken}', - {user: user, size: size, requesttoken: oc_requesttoken}); + {user: user, size: size * window.devicePixelRatio, requesttoken: oc_requesttoken}); $.get(url, function(result) { if (typeof(result) === 'object') { @@ -93,9 +93,9 @@ } else { $div.show(); if (ie8fix === true) { - $div.html('<img src="'+url+'#'+Math.floor(Math.random()*1000)+'">'); + $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'#'+Math.floor(Math.random()*1000)+'">'); } else { - $div.html('<img src="'+url+'">'); + $div.html('<img width="' + size + '" height="' + size + '" src="'+url+'">'); } } if(typeof callback === 'function') { diff --git a/core/js/js.js b/core/js/js.js index 302b6b4d9fa..1cbb9636dbe 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -159,6 +159,7 @@ function escapeHTML(s) { * @param file The filename * @param dir The directory the file is in - e.g. $('#dir').val() * @return string +* @deprecated use Files.getDownloadURL() instead */ function fileDownloadPath(dir, file) { return OC.filePath('files', 'ajax', 'download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir); @@ -371,6 +372,7 @@ var OC={ */ parseQueryString:function(queryString){ var parts, + pos, components, result = {}, key, @@ -378,12 +380,25 @@ var OC={ if (!queryString){ return null; } - if (queryString[0] === '?'){ - queryString = queryString.substr(1); + pos = queryString.indexOf('?'); + if (pos >= 0){ + queryString = queryString.substr(pos + 1); } - parts = queryString.split('&'); + parts = queryString.replace(/\+/g, '%20').split('&'); for (var i = 0; i < parts.length; i++){ - components = parts[i].split('='); + // split on first equal sign + var part = parts[i] + pos = part.indexOf('='); + if (pos >= 0) { + components = [ + part.substr(0, pos), + part.substr(pos + 1) + ] + } + else { + // key only + components = [part]; + } if (!components.length){ continue; } @@ -391,8 +406,14 @@ var OC={ if (!key){ continue; } - value = components[1]; - result[key] = value && decodeURIComponent(value); + // if equal sign was there, return string + if (components.length > 1) { + result[key] = decodeURIComponent(components[1]); + } + // no equal sign => null value + else { + result[key] = null; + } } return result; }, @@ -477,7 +498,7 @@ var OC={ }); } if(!SVGSupport()) { - replaceSVG(); + OC.Util.replaceSVG(); } }).show(); }, 'html'); @@ -764,7 +785,7 @@ SVGSupport.checkMimeType=function(){ } }); if(headers["content-type"]!=='image/svg+xml'){ - replaceSVG(); + OC.Util.replaceSVG(); SVGSupport.checkMimeType.correct=false; } } @@ -772,35 +793,10 @@ SVGSupport.checkMimeType=function(){ }; SVGSupport.checkMimeType.correct=true; -//replace all svg images with png for browser compatibility -function replaceSVG(){ - $('img.svg').each(function(index,element){ - element=$(element); - var src=element.attr('src'); - element.attr('src',src.substr(0,src.length-3)+'png'); - }); - $('.svg').each(function(index,element){ - element=$(element); - var background=element.css('background-image'); - if(background){ - var i=background.lastIndexOf('.svg'); - if(i>=0){ - background=background.substr(0,i)+'.png'+background.substr(i+4); - element.css('background-image',background); - } - } - element.find('*').each(function(index,element) { - element=$(element); - var background=element.css('background-image'); - if(background){ - var i=background.lastIndexOf('.svg'); - if(i>=0){ - background=background.substr(0,i)+'.png'+background.substr(i+4); - element.css('background-image',background); - } - } - }); - }); +// replace all svg images with png for browser compatibility +// @deprecated use OC.Util.replaceSVG instead +function replaceSVG($el){ + return OC.Util.replaceSVG($el); } /** @@ -879,7 +875,7 @@ function initCore() { } if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg - replaceSVG(); + OC.Util.replaceSVG(); }else{ SVGSupport.checkMimeType(); } @@ -1113,6 +1109,72 @@ function relative_modified_date(timestamp) { else { return t('core','years ago'); } } +OC.Util = { + /** + * Returns whether the browser supports SVG + * + * @return true if the browser supports SVG, false otherwise + */ + // TODO: replace with original function + hasSVGSupport: SVGSupport, + /** + * If SVG is not supported, replaces the given icon's extension + * from ".svg" to ".png". + * If SVG is supported, return the image path as is. + * + * @param file image path with svg extension + * @return fixed image path with png extension if SVG is not + * supported + */ + replaceSVGIcon: function(file) { + if (!OC.Util.hasSVGSupport()) { + var i = file.lastIndexOf('.svg'); + if (i >= 0) { + file = file.substr(0, i) + '.png' + file.substr(i+4); + } + } + return file; + }, + /** + * Replace SVG images in all elements that have the "svg" class set + * with PNG images. + * + * @param $el root element from which to search, defaults to $('body') + */ + replaceSVG: function($el) { + if (!$el) { + $el = $('body'); + } + $el.find('img.svg').each(function(index,element){ + element=$(element); + var src=element.attr('src'); + element.attr('src',src.substr(0, src.length-3) + 'png'); + }); + $el.find('.svg').each(function(index,element){ + element = $(element); + var background = element.css('background-image'); + if (background){ + var i = background.lastIndexOf('.svg'); + if (i >= 0){ + background = background.substr(0,i) + '.png' + background.substr(i + 4); + element.css('background-image', background); + } + } + element.find('*').each(function(index, element) { + element = $(element); + var background = element.css('background-image'); + if (background) { + var i = background.lastIndexOf('.svg'); + if(i >= 0){ + background = background.substr(0,i) + '.png' + background.substr(i + 4); + element.css('background-image', background); + } + } + }); + }); + } +}; + /** * get a variable by name * @param string name diff --git a/core/js/oc-dialogs.js b/core/js/oc-dialogs.js index d1bcb4659b8..2233b983ad4 100644 --- a/core/js/oc-dialogs.js +++ b/core/js/oc-dialogs.js @@ -19,6 +19,8 @@ * */ +/* global OC, t */ + /** * this class to ease the usage of jquery dialogs */ @@ -138,6 +140,9 @@ var OCdialogs = { self.$filePicker = null; } }); + if (!OC.Util.hasSVGSupport()) { + OC.Util.replaceSVG(self.$filePicker.parent()); + } }) .fail(function(status, error) { // If the method is called while navigating away @@ -294,7 +299,7 @@ var OCdialogs = { conflict.find('.replacement .mtime').text(formatDate(replacement.lastModifiedDate)); } var path = original.directory + '/' +original.name; - Files.lazyLoadPreview(path, original.mime, function(previewpath){ + Files.lazyLoadPreview(path, original.mimetype, function(previewpath){ conflict.find('.original .icon').css('background-image','url('+previewpath+')'); }, 96, 96, original.etag); getCroppedPreview(replacement).then( @@ -343,7 +348,7 @@ var OCdialogs = { addConflict(conflicts, original, replacement); var count = $(dialog_id+ ' .conflict').length; - var title = n('files', + var title = n('core', '{count} file conflict', '{count} file conflicts', count, @@ -358,14 +363,17 @@ var OCdialogs = { //create dialog this._fileexistsshown = true; $.when(this._getFileExistsTemplate()).then(function($tmpl) { - var title = t('files','One file conflict'); + var title = t('core','One file conflict'); var $dlg = $tmpl.octemplate({ dialog_name: dialog_name, title: title, type: 'fileexists', - why: t('files','Which files do you want to keep?'), - what: t('files','If you select both versions, the copied file will have a number added to its name.') + allnewfiles: t('core','New Files'), + allexistingfiles: t('core','Already existing files'), + + why: t('core','Which files do you want to keep?'), + what: t('core','If you select both versions, the copied file will have a number added to its name.') }); $('body').append($dlg); @@ -430,10 +438,10 @@ var OCdialogs = { var count = $(dialog_id).find('.conflict .replacement input[type="checkbox"]:checked').length; if (count === $(dialog_id+ ' .conflict').length) { $(dialog_id).find('.allnewfiles').prop('checked', true); - $(dialog_id).find('.allnewfiles + .count').text(t('files','(all selected)')); + $(dialog_id).find('.allnewfiles + .count').text(t('core','(all selected)')); } else if (count > 0) { $(dialog_id).find('.allnewfiles').prop('checked', false); - $(dialog_id).find('.allnewfiles + .count').text(t('files','({count} selected)',{count:count})); + $(dialog_id).find('.allnewfiles + .count').text(t('core','({count} selected)',{count:count})); } else { $(dialog_id).find('.allnewfiles').prop('checked', false); $(dialog_id).find('.allnewfiles + .count').text(''); @@ -443,10 +451,10 @@ var OCdialogs = { var count = $(dialog_id).find('.conflict .original input[type="checkbox"]:checked').length; if (count === $(dialog_id+ ' .conflict').length) { $(dialog_id).find('.allexistingfiles').prop('checked', true); - $(dialog_id).find('.allexistingfiles + .count').text(t('files','(all selected)')); + $(dialog_id).find('.allexistingfiles + .count').text(t('core','(all selected)')); } else if (count > 0) { $(dialog_id).find('.allexistingfiles').prop('checked', false); - $(dialog_id).find('.allexistingfiles + .count').text(t('files','({count} selected)',{count:count})); + $(dialog_id).find('.allexistingfiles + .count').text(t('core','({count} selected)',{count:count})); } else { $(dialog_id).find('.allexistingfiles').prop('checked', false); $(dialog_id).find('.allexistingfiles + .count').text(''); @@ -514,7 +522,7 @@ var OCdialogs = { } return $.getJSON( - OC.filePath('files', 'ajax', 'rawlist.php'), + OC.filePath('files', 'ajax', 'list.php'), { dir: dir, mimetypes: JSON.stringify(mimeType) @@ -539,7 +547,7 @@ var OCdialogs = { this.$filelist.empty().addClass('loading'); this.$filePicker.data('path', dir); $.when(this._getFileList(dir, this.$filePicker.data('mimetype'))).then(function(response) { - $.each(response.data, function(index, file) { + $.each(response.data.files, function(index, file) { if (file.type === 'dir') { dirs.push(file); } else { @@ -555,13 +563,25 @@ var OCdialogs = { type: entry.type, dir: dir, filename: entry.name, - date: OC.mtime2date(entry.mtime) + date: OC.mtime2date(Math.floor(entry.mtime / 1000)) }); - $li.find('img').attr('src', entry.mimetype_icon); + if (entry.isPreviewAvailable) { + var urlSpec = { + file: dir + '/' + entry.name + }; + var previewUrl = OC.generateUrl('/core/preview.png?') + $.param(urlSpec); + $li.find('img').attr('src', previewUrl); + } + else { + $li.find('img').attr('src', OC.Util.replaceSVGIcon(entry.icon)); + } self.$filelist.append($li); }); self.$filelist.removeClass('loading'); + if (!OC.Util.hasSVGSupport()) { + OC.Util.replaceSVG(self.$filePicker.find('.dirtree')); + } }); }, /** diff --git a/core/js/share.js b/core/js/share.js index e769edd0a21..ef71cc7999a 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -551,7 +551,7 @@ $(document).ready(function() { var itemType = $('#dropdown').data('item-type'); var itemSource = $('#dropdown').data('item-source'); var shareType = $li.data('share-type'); - var shareWith = $li.data('share-with'); + var shareWith = $li.attr('data-share-with'); OC.Share.unshare(itemType, itemSource, shareType, shareWith, function() { $li.remove(); var index = OC.Share.itemShares[shareType].indexOf(shareWith); @@ -597,7 +597,7 @@ $(document).ready(function() { OC.Share.setPermissions($('#dropdown').data('item-type'), $('#dropdown').data('item-source'), li.data('share-type'), - li.data('share-with'), + li.attr('data-share-with'), permissions); }); @@ -782,7 +782,7 @@ $(document).ready(function() { } var shareType = $li.data('share-type'); - var shareWith = $li.data('share-with'); + var shareWith = $li.attr('data-share-with'); $.post(OC.filePath('core', 'ajax', 'share.php'), {action: action, recipient: shareWith, shareType: shareType, itemSource: itemSource, itemType: itemType}, function(result) { if (result.status !== 'success') { diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index 57ea5be8be0..89056807788 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -268,7 +268,72 @@ describe('Core base tests', function() { // still nothing expect(counter).toEqual(0); }); - + }); + describe('Parse query string', function() { + it('Parses query string from full URL', function() { + var query = OC.parseQueryString('http://localhost/stuff.php?q=a&b=x'); + expect(query).toEqual({q: 'a', b: 'x'}); + }); + it('Parses query string from query part alone', function() { + var query = OC.parseQueryString('q=a&b=x'); + expect(query).toEqual({q: 'a', b: 'x'}); + }); + it('Returns null hash when empty query', function() { + var query = OC.parseQueryString(''); + expect(query).toEqual(null); + }); + it('Returns empty hash when empty query with question mark', function() { + var query = OC.parseQueryString('?'); + expect(query).toEqual({}); + }); + it('Decodes regular query strings', function() { + var query = OC.parseQueryString('a=abc&b=def'); + expect(query).toEqual({ + a: 'abc', + b: 'def' + }); + }); + it('Ignores empty parts', function() { + var query = OC.parseQueryString('&q=a&&b=x&'); + expect(query).toEqual({q: 'a', b: 'x'}); + }); + it('Ignores lone equal signs', function() { + var query = OC.parseQueryString('&q=a&=&b=x&'); + expect(query).toEqual({q: 'a', b: 'x'}); + }); + it('Includes extra equal signs in value', function() { + var query = OC.parseQueryString('u=a=x&q=a=b'); + expect(query).toEqual({u: 'a=x', q: 'a=b'}); + }); + it('Decodes plus as space', function() { + var query = OC.parseQueryString('space+key=space+value'); + expect(query).toEqual({'space key': 'space value'}); + }); + it('Decodes special characters', function() { + var query = OC.parseQueryString('unicode=%E6%B1%89%E5%AD%97'); + expect(query).toEqual({unicode: '汉字'}); + query = OC.parseQueryString('b=spaace%20value&space%20key=normalvalue&slash%2Fthis=amp%26ersand'); + expect(query).toEqual({ + b: 'spaace value', + 'space key': 'normalvalue', + 'slash/this': 'amp&ersand' + }); + }); + it('Decodes empty values', function() { + var query = OC.parseQueryString('keywithemptystring=&keywithnostring'); + expect(query).toEqual({ + 'keywithemptystring': '', + 'keywithnostring': null + }); + }); + it('Does not interpret data types', function() { + var query = OC.parseQueryString('booleanfalse=false&booleantrue=true&number=123'); + expect(query).toEqual({ + 'booleanfalse': 'false', + 'booleantrue': 'true', + 'number': '123' + }); + }); }); describe('Generate Url', function() { it('returns absolute urls', function() { @@ -383,5 +448,31 @@ describe('Core base tests', function() { expect($navigation.is(':visible')).toEqual(true); }); }); + describe('SVG extension replacement', function() { + var svgSupportStub; + + beforeEach(function() { + svgSupportStub = sinon.stub(OC.Util, 'hasSVGSupport'); + }); + afterEach(function() { + svgSupportStub.restore(); + }); + it('does not replace svg extension with png when SVG is supported', function() { + svgSupportStub.returns(true); + expect( + OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1') + ).toEqual( + '/path/to/myicon.svg?someargs=1' + ); + }); + it('replaces svg extension with png when SVG not supported', function() { + svgSupportStub.returns(false); + expect( + OC.Util.replaceSVGIcon('/path/to/myicon.svg?someargs=1') + ).toEqual( + '/path/to/myicon.png?someargs=1' + ); + }); + }); }); diff --git a/core/js/underscore.js b/core/js/underscore.js new file mode 100644 index 00000000000..ca61fdc3a4b --- /dev/null +++ b/core/js/underscore.js @@ -0,0 +1,1344 @@ +// Underscore.js 1.6.0 +// http://underscorejs.org +// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. + +(function() { + + // Baseline setup + // -------------- + + // Establish the root object, `window` in the browser, or `exports` on the server. + var root = this; + + // Save the previous value of the `_` variable. + var previousUnderscore = root._; + + // Establish the object that gets returned to break out of a loop iteration. + var breaker = {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; + + // Create quick reference variables for speed access to core prototypes. + var + push = ArrayProto.push, + slice = ArrayProto.slice, + concat = ArrayProto.concat, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // All **ECMAScript 5** native function implementations that we hope to use + // are declared here. + var + nativeForEach = ArrayProto.forEach, + nativeMap = ArrayProto.map, + nativeReduce = ArrayProto.reduce, + nativeReduceRight = ArrayProto.reduceRight, + nativeFilter = ArrayProto.filter, + nativeEvery = ArrayProto.every, + nativeSome = ArrayProto.some, + nativeIndexOf = ArrayProto.indexOf, + nativeLastIndexOf = ArrayProto.lastIndexOf, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeBind = FuncProto.bind; + + // Create a safe reference to the Underscore object for use below. + var _ = function(obj) { + if (obj instanceof _) return obj; + if (!(this instanceof _)) return new _(obj); + this._wrapped = obj; + }; + + // Export the Underscore object for **Node.js**, with + // backwards-compatibility for the old `require()` API. If we're in + // the browser, add `_` as a global object via a string identifier, + // for Closure Compiler "advanced" mode. + if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = _; + } + exports._ = _; + } else { + root._ = _; + } + + // Current version. + _.VERSION = '1.6.0'; + + // Collection Functions + // -------------------- + + // The cornerstone, an `each` implementation, aka `forEach`. + // Handles objects with the built-in `forEach`, arrays, and raw objects. + // Delegates to **ECMAScript 5**'s native `forEach` if available. + var each = _.each = _.forEach = function(obj, iterator, context) { + if (obj == null) return obj; + if (nativeForEach && obj.forEach === nativeForEach) { + obj.forEach(iterator, context); + } else if (obj.length === +obj.length) { + for (var i = 0, length = obj.length; i < length; i++) { + if (iterator.call(context, obj[i], i, obj) === breaker) return; + } + } else { + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; + } + } + return obj; + }; + + // Return the results of applying the iterator to each element. + // Delegates to **ECMAScript 5**'s native `map` if available. + _.map = _.collect = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); + each(obj, function(value, index, list) { + results.push(iterator.call(context, value, index, list)); + }); + return results; + }; + + var reduceError = 'Reduce of empty array with no initial value'; + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available. + _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var length = obj.length; + if (length !== +length) { + var keys = _.keys(obj); + length = keys.length; + } + each(obj, function(value, index, list) { + index = keys ? keys[--length] : --length; + if (!initial) { + memo = obj[index]; + initial = true; + } else { + memo = iterator.call(context, memo, obj[index], index, list); + } + }); + if (!initial) throw new TypeError(reduceError); + return memo; + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, predicate, context) { + var result; + any(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, predicate, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); + each(obj, function(value, index, list) { + if (predicate.call(context, value, index, list)) results.push(value); + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, predicate, context) { + return _.filter(obj, function(value, index, list) { + return !predicate.call(context, value, index, list); + }, context); + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); + each(obj, function(value, index, list) { + if (!(result = result && predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, predicate, context) { + predicate || (predicate = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); + each(obj, function(value, index, list) { + if (result || (result = predicate.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if the array or object contains a given value (using `===`). + // Aliased as `include`. + _.contains = _.include = function(obj, target) { + if (obj == null) return false; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + return any(obj, function(value) { + return value === target; + }); + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + var isFunc = _.isFunction(method); + return _.map(obj, function(value) { + return (isFunc ? method : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, _.property(key)); + }; + + // Convenience version of a common use case of `filter`: selecting only objects + // containing specific `key:value` pairs. + _.where = function(obj, attrs) { + return _.filter(obj, _.matches(attrs)); + }; + + // Convenience version of a common use case of `find`: getting the first object + // containing specific `key:value` pairs. + _.findWhere = function(obj, attrs) { + return _.find(obj, _.matches(attrs)); + }; + + // Return the maximum element or (element-based computation). + // Can't optimize arrays of integers longer than 65,535 elements. + // See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797) + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.max.apply(Math, obj); + } + var result = -Infinity, lastComputed = -Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed > lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { + return Math.min.apply(Math, obj); + } + var result = Infinity, lastComputed = Infinity; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + if (computed < lastComputed) { + result = value; + lastComputed = computed; + } + }); + return result; + }; + + // Shuffle an array, using the modern version of the + // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + _.shuffle = function(obj) { + var rand; + var index = 0; + var shuffled = []; + each(obj, function(value) { + rand = _.random(index++); + shuffled[index - 1] = shuffled[rand]; + shuffled[rand] = value; + }); + return shuffled; + }; + + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `map`. + _.sample = function(obj, n, guard) { + if (n == null || guard) { + if (obj.length !== +obj.length) obj = _.values(obj); + return obj[_.random(obj.length - 1)]; + } + return _.shuffle(obj).slice(0, Math.max(0, n)); + }; + + // An internal function to generate lookup iterators. + var lookupIterator = function(value) { + if (value == null) return _.identity; + if (_.isFunction(value)) return value; + return _.property(value); + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + iterator = lookupIterator(iterator); + return _.pluck(_.map(obj, function(value, index, list) { + return { + value: value, + index: index, + criteria: iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + }; + + // An internal function used for aggregate "group by" operations. + var group = function(behavior) { + return function(obj, iterator, context) { + var result = {}; + iterator = lookupIterator(iterator); + each(obj, function(value, index) { + var key = iterator.call(context, value, index, obj); + behavior(result, key, value); + }); + return result; + }; + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = group(function(result, key, value) { + _.has(result, key) ? result[key].push(value) : result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `groupBy`, but for + // when you know that your index values will be unique. + _.indexBy = group(function(result, key, value) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + _.countBy = group(function(result, key) { + _.has(result, key) ? result[key]++ : result[key] = 1; + }); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator, context) { + iterator = lookupIterator(iterator); + var value = iterator.call(context, obj); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >>> 1; + iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely create a real, live array from anything iterable. + _.toArray = function(obj) { + if (!obj) return []; + if (_.isArray(obj)) return slice.call(obj); + if (obj.length === +obj.length) return _.map(obj, _.identity); + return _.values(obj); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + if (obj == null) return 0; + return (obj.length === +obj.length) ? obj.length : _.keys(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head` and `take`. The **guard** check + // allows it to work with `_.map`. + _.first = _.head = _.take = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[0]; + if (n < 0) return []; + return slice.call(array, 0, n); + }; + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if (array == null) return void 0; + if ((n == null) || guard) return array[array.length - 1]; + return slice.call(array, Math.max(array.length - n, 0)); + }; + + // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. + // Especially useful on the arguments object. Passing an **n** will return + // the rest N values in the array. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = _.drop = function(array, n, guard) { + return slice.call(array, (n == null) || guard ? 1 : n); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, _.identity); + }; + + // Internal implementation of a recursive `flatten` function. + var flatten = function(input, shallow, output) { + if (shallow && _.every(input, _.isArray)) { + return concat.apply(output, input); + } + each(input, function(value) { + if (_.isArray(value) || _.isArguments(value)) { + shallow ? push.apply(output, value) : flatten(value, shallow, output); + } else { + output.push(value); + } + }); + return output; + }; + + // Flatten out an array, either recursively (by default), or just one level. + _.flatten = function(array, shallow) { + return flatten(array, shallow, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Split an array into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(array, predicate, context) { + predicate = lookupIterator(predicate); + var pass = [], fail = []; + each(array, function(elem) { + (predicate.call(context, elem) ? pass : fail).push(elem); + }); + return [pass, fail]; + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator, context) { + if (_.isFunction(isSorted)) { + context = iterator; + iterator = isSorted; + isSorted = false; + } + var initial = iterator ? _.map(array, iterator, context) : array; + var results = []; + var seen = []; + each(initial, function(value, index) { + if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) { + seen.push(value); + results.push(array[index]); + } + }); + return results; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. + _.intersection = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.contains(other, item); + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = concat.apply(ArrayProto, slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.contains(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var length = _.max(_.pluck(arguments, 'length').concat(0)); + var results = new Array(length); + for (var i = 0; i < length; i++) { + results[i] = _.pluck(arguments, '' + i); + } + return results; + }; + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. + _.object = function(list, values) { + if (list == null) return {}; + var result = {}; + for (var i = 0, length = list.length; i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i = 0, length = array.length; + if (isSorted) { + if (typeof isSorted == 'number') { + i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted); + } else { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted); + for (; i < length; i++) if (array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item, from) { + if (array == null) return -1; + var hasIndex = from != null; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) { + return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item); + } + var i = (hasIndex ? from : array.length); + while (i--) if (array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(length); + + while(idx < length) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if + // available. + _.bind = function(func, context) { + var args, bound; + if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + ctor.prototype = null; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. + _.partial = function(func) { + var boundArgs = slice.call(arguments, 1); + return function() { + var position = 0; + var args = boundArgs.slice(); + for (var i = 0, length = args.length; i < length; i++) { + if (args[i] === _) args[i] = arguments[position++]; + } + while (position < arguments.length) args.push(arguments[position++]); + return func.apply(this, args); + }; + }; + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length === 0) throw new Error('bindAll must be passed function names'); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(null, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + _.throttle = function(func, wait, options) { + var context, args, result; + var timeout = null; + var previous = 0; + options || (options = {}); + var later = function() { + previous = options.leading === false ? 0 : _.now(); + timeout = null; + result = func.apply(context, args); + context = args = null; + }; + return function() { + var now = _.now(); + if (!previous && options.leading === false) previous = now; + var remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. If `immediate` is passed, trigger the function on the + // leading edge, instead of the trailing. + _.debounce = function(func, wait, immediate) { + var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + context = args = null; + } + } + }; + + return function() { + context = this; + args = arguments; + timestamp = _.now(); + var callNow = immediate && !timeout; + if (!timeout) { + timeout = setTimeout(later, wait); + } + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + + return result; + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + memo = func.apply(this, arguments); + func = null; + return memo; + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return _.partial(wrapper, func); + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys.push(key); + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var values = new Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[keys[i]]; + } + return values; + }; + + // Convert an object into a list of `[key, value]` pairs. + _.pairs = function(obj) { + var keys = _.keys(obj); + var length = keys.length; + var pairs = new Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [keys[i], obj[keys[i]]]; + } + return pairs; + }; + + // Invert the keys and values of an object. The values must be serializable. + _.invert = function(obj) { + var result = {}; + var keys = _.keys(obj); + for (var i = 0, length = keys.length; i < length; i++) { + result[obj[keys[i]]] = keys[i]; + } + return result; + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Return a copy of the object only containing the whitelisted properties. + _.pick = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + each(keys, function(key) { + if (key in obj) copy[key] = obj[key]; + }); + return copy; + }; + + // Return a copy of the object without the blacklisted properties. + _.omit = function(obj) { + var copy = {}; + var keys = concat.apply(ArrayProto, slice.call(arguments, 1)); + for (var key in obj) { + if (!_.contains(keys, key)) copy[key] = obj[key]; + } + return copy; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + if (source) { + for (var prop in source) { + if (obj[prop] === void 0) obj[prop] = source[prop]; + } + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function for `isEqual`. + var eq = function(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a instanceof _) a = a._wrapped; + if (b instanceof _) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] == a) return bStack[length] == b; + } + // Objects with different constructors are not equivalent, but `Object`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && + _.isFunction(bCtor) && (bCtor instanceof bCtor)) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + if (!(result = eq(a[size], b[size], aStack, bStack))) break; + } + } + } else { + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return result; + }; + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, [], []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (obj == null) return true; + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType === 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp. + each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) { + _['is' + name] = function(obj) { + return toString.call(obj) == '[object ' + name + ']'; + }; + }); + + // Define a fallback version of the method in browsers (ahem, IE), where + // there isn't any inspectable "Arguments" type. + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Optimize `isFunction` if appropriate. + if (typeof (/./) !== 'function') { + _.isFunction = function(obj) { + return typeof obj === 'function'; + }; + } + + // Is a given object a finite number? + _.isFinite = function(obj) { + return isFinite(obj) && !isNaN(parseFloat(obj)); + }; + + // Is the given value `NaN`? (NaN is the only number which does not equal itself). + _.isNaN = function(obj) { + return _.isNumber(obj) && obj != +obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Shortcut function for checking if an object has a given property directly + // on itself (in other words, not on a prototype). + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + _.constant = function(value) { + return function () { + return value; + }; + }; + + _.property = function(key) { + return function(obj) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of `key:value` pairs. + _.matches = function(attrs) { + return function(obj) { + if (obj === attrs) return true; //avoid comparing an object to itself. + for (var key in attrs) { + if (attrs[key] !== obj[key]) + return false; + } + return true; + } + }; + + // Run a function **n** times. + _.times = function(n, iterator, context) { + var accum = Array(Math.max(0, n)); + for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i); + return accum; + }; + + // Return a random integer between min and max (inclusive). + _.random = function(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + }; + + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { return new Date().getTime(); }; + + // List of HTML entities for escaping. + var entityMap = { + escape: { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + } + }; + entityMap.unescape = _.invert(entityMap.escape); + + // Regexes containing the keys and values listed immediately above. + var entityRegexes = { + escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'), + unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g') + }; + + // Functions for escaping and unescaping strings to/from HTML interpolation. + _.each(['escape', 'unescape'], function(method) { + _[method] = function(string) { + if (string == null) return ''; + return ('' + string).replace(entityRegexes[method], function(match) { + return entityMap[method][match]; + }); + }; + }); + + // If the value of the named `property` is a function then invoke it with the + // `object` as context; otherwise, return it. + _.result = function(object, property) { + if (object == null) return void 0; + var value = object[property]; + return _.isFunction(value) ? value.call(object) : value; + }; + + // Add your own custom functions to the Underscore object. + _.mixin = function(obj) { + each(_.functions(obj), function(name) { + var func = _[name] = obj[name]; + _.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return result.call(this, func.apply(_, args)); + }; + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\t': 't', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(text, data, settings) { + var render; + settings = _.defaults({}, settings, _.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = new RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset) + .replace(escaper, function(match) { return '\\' + escapes[match]; }); + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } + if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + index = offset + match.length; + return match; + }); + source += "';\n"; + + // If a variable is not specified, place data values in local scope. + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + "return __p;\n"; + + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + if (data) return render(data, _); + var template = function(data) { + return render.call(this, data, _); + }; + + // Provide the compiled function source as a convenience for precompilation. + template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; + + return template; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // OOP + // --------------- + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + + // Helper function to continue chaining intermediate results. + var result = function(obj) { + return this._chain ? _(obj).chain() : obj; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + var obj = this._wrapped; + method.apply(obj, arguments); + if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0]; + return result.call(this, obj); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _.prototype[name] = function() { + return result.call(this, method.apply(this._wrapped, arguments)); + }; + }); + + _.extend(_.prototype, { + + // Start chaining a wrapped Underscore object. + chain: function() { + this._chain = true; + return this; + }, + + // Extracts the result from a wrapped and chained object. + value: function() { + return this._wrapped; + } + + }); + + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } +}).call(this); diff --git a/core/l10n/ast.php b/core/l10n/ast.php new file mode 100644 index 00000000000..9ae1685347c --- /dev/null +++ b/core/l10n/ast.php @@ -0,0 +1,74 @@ +<?php +$TRANSLATIONS = array( +"Updated database" => "Base de datos anovada", +"Sunday" => "Domingu", +"Monday" => "Llunes", +"Tuesday" => "Martes", +"Wednesday" => "Miércoles", +"Thursday" => "Xueves", +"Friday" => "Vienres", +"Saturday" => "Sábadu", +"January" => "Xineru", +"February" => "Febreru", +"March" => "Marzu", +"April" => "Abril", +"May" => "Mayu", +"June" => "Xunu", +"July" => "Xunetu", +"August" => "Agostu", +"September" => "Setiembre", +"October" => "Ochobre", +"November" => "Payares", +"December" => "Avientu", +"Settings" => "Axustes", +"seconds ago" => "fai segundos", +"_%n minute ago_::_%n minutes ago_" => array("fai %n minutu","fai %n minutos"), +"_%n hour ago_::_%n hours ago_" => array("fai %n hora","fai %n hores"), +"today" => "güei", +"yesterday" => "ayeri", +"_%n day ago_::_%n days ago_" => array("fai %n día","fai %n díes"), +"last month" => "mes caberu", +"_%n month ago_::_%n months ago_" => array("fai %n mes","fai %n meses"), +"months ago" => "fai meses", +"last year" => "añu caberu", +"years ago" => "fai años", +"Choose" => "Esbillar", +"Yes" => "Sí", +"No" => "Non", +"_{count} file conflict_::_{count} file conflicts_" => array("",""), +"Which files do you want to keep?" => "¿Qué ficheros quies caltener?", +"Cancel" => "Encaboxar", +"Continue" => "Continuar", +"Shared" => "Compartíu", +"Share" => "Compartir", +"Share link" => "Compartir enllaz", +"Password" => "Contraseña", +"Send" => "Unviar", +"group" => "grupu", +"Unshare" => "Dexar de compartir", +"notify by email" => "notificar per corréu", +"can edit" => "pue editar", +"access control" => "control d'accesu", +"create" => "crear", +"update" => "xubir", +"delete" => "desaniciar", +"share" => "compartir", +"Password protected" => "Contraseña protexida", +"Email sent" => "Corréu unviáu", +"Delete" => "Desaniciar", +"Add" => "Amestar", +"Edit tags" => "Editar etiquetes", +"Username" => "Nome d'usuariu", +"Reset" => "Reaniciar", +"For the best results, please consider using a GNU/Linux server instead." => "Pa los meyores resultaos, por favor considera l'usu d'un sirvidor GNU/Linux nel so llugar.", +"Personal" => "Personal", +"Cheers!" => "¡Salú!", +"will be used" => "usaráse", +"Finishing …" => "Finando ...", +"Log out" => "Zarrar sesión", +"Lost your password?" => "¿Escaeciesti la to contraseña?", +"Log in" => "Aniciar sesión", +"Alternative Logins" => "Anicios de sesión alternativos", +"Thank you for your patience." => "Gracies pola to paciencia." +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/core/l10n/ca.php b/core/l10n/ca.php index 0a658d515d9..214b2eac0e9 100644 --- a/core/l10n/ca.php +++ b/core/l10n/ca.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Error en carregar la plantilla de missatge: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicte de fitxer","{count} conflictes de fitxer"), "One file conflict" => "Un fitxer en conflicte", +"New Files" => "Fitxers nous", "Which files do you want to keep?" => "Quin fitxer voleu conservar?", "If you select both versions, the copied file will have a number added to its name." => "Si seleccioneu les dues versions, el fitxer copiat tindrà un número afegit al seu nom.", "Cancel" => "Cancel·la", diff --git a/core/l10n/cs_CZ.php b/core/l10n/cs_CZ.php index ffe34f78280..c21d904b233 100644 --- a/core/l10n/cs_CZ.php +++ b/core/l10n/cs_CZ.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Chyba při nahrávání šablony zprávy: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} souborový konflikt","{count} souborové konflikty","{count} souborových konfliktů"), "One file conflict" => "Jeden konflikt souboru", +"New Files" => "Nové soubory", "Which files do you want to keep?" => "Které soubory chcete ponechat?", "If you select both versions, the copied file will have a number added to its name." => "Pokud zvolíte obě verze, zkopírovaný soubor bude mít název doplněný o číslo.", "Cancel" => "Zrušit", diff --git a/core/l10n/da.php b/core/l10n/da.php index d3384dac432..c7bda6fd365 100644 --- a/core/l10n/da.php +++ b/core/l10n/da.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Fejl ved indlæsning af besked skabelon: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} filkonflikt","{count} filkonflikter"), "One file conflict" => "En filkonflikt", +"New Files" => "Nye filer", "Which files do you want to keep?" => "Hvilke filer ønsker du at beholde?", "If you select both versions, the copied file will have a number added to its name." => "Hvis du vælger begge versioner, vil den kopierede fil få tilføjet et nummer til sit navn.", "Cancel" => "Annuller", diff --git a/core/l10n/de.php b/core/l10n/de.php index 79edfb725d7..4d8c583e164 100644 --- a/core/l10n/de.php +++ b/core/l10n/de.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Fehler beim Laden der Nachrichtenvorlage: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} Dateikonflikt","{count} Dateikonflikte"), "One file conflict" => "Ein Dateikonflikt", +"New Files" => "Neue Dateien", "Which files do you want to keep?" => "Welche Dateien möchtest Du behalten?", "If you select both versions, the copied file will have a number added to its name." => "Wenn Du beide Versionen auswählst, erhält die kopierte Datei eine Zahl am Ende des Dateinamens.", "Cancel" => "Abbrechen", diff --git a/core/l10n/de_CH.php b/core/l10n/de_CH.php index 42b8eb3bcea..eb2cfd233d3 100644 --- a/core/l10n/de_CH.php +++ b/core/l10n/de_CH.php @@ -40,6 +40,7 @@ $TRANSLATIONS = array( "No" => "Nein", "Ok" => "OK", "_{count} file conflict_::_{count} file conflicts_" => array("",""), +"New Files" => "Neue Dateien", "Cancel" => "Abbrechen", "Shared" => "Geteilt", "Share" => "Teilen", diff --git a/core/l10n/de_DE.php b/core/l10n/de_DE.php index a0877e792e2..900d3c03172 100644 --- a/core/l10n/de_DE.php +++ b/core/l10n/de_DE.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Fehler beim Laden der Nachrichtenvorlage: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} Dateikonflikt","{count} Dateikonflikte"), "One file conflict" => "Ein Dateikonflikt", +"New Files" => "Neue Dateien", "Which files do you want to keep?" => "Welche Dateien möchten Sie behalten?", "If you select both versions, the copied file will have a number added to its name." => "Wenn Sie beide Versionen auswählen, erhält die kopierte Datei eine Zahl am Ende des Dateinamens.", "Cancel" => "Abbrechen", diff --git a/core/l10n/el.php b/core/l10n/el.php index ed7792b7261..c899427ae30 100644 --- a/core/l10n/el.php +++ b/core/l10n/el.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => "Η ημερομηνία λήξης είναι στο παρελθόν.", "Couldn't send mail to following users: %s " => "Αδυναμία αποστολής μηνύματος στους ακόλουθους χρήστες: %s", "Turned on maintenance mode" => "Η κατάσταση συντήρησης ενεργοποιήθηκε", "Turned off maintenance mode" => "Η κατάσταση συντήρησης απενεργοποιήθηκε", @@ -49,14 +50,17 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Σφάλμα φόρτωσης προτύπου μηνυμάτων: {σφάλμα}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} αρχείο διαφέρει","{count} αρχεία διαφέρουν"), "One file conflict" => "Ένα αρχείο διαφέρει", +"New Files" => "Νέα Αρχεία", "Which files do you want to keep?" => "Ποια αρχεία θέλετε να κρατήσετε;", "If you select both versions, the copied file will have a number added to its name." => "Εάν επιλέξετε και τις δυο εκδοχές, ένας αριθμός θα προστεθεί στο αντιγραφόμενο αρχείο.", "Cancel" => "Άκυρο", "Continue" => "Συνέχεια", "(all selected)" => "(όλα τα επιλεγμένα)", "({count} selected)" => "({count} επιλέχθησαν)", +"Error loading file exists template" => "Σφάλμα κατά την φόρτωση του προτύπου ύπαρξης αρχείου", "Very weak password" => "Πολύ αδύναμο συνθηματικό", "Weak password" => "Αδύναμο συνθηματικό", +"So-so password" => "Μέτριο συνθηματικό", "Good password" => "Καλό συνθηματικό", "Strong password" => "Δυνατό συνθηματικό", "Shared" => "Κοινόχρηστα", @@ -119,6 +123,8 @@ $TRANSLATIONS = array( "To login page" => "Σελίδα εισόδου", "New password" => "Νέο συνθηματικό", "Reset password" => "Επαναφορά συνθηματικού", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Το Mac OS X δεν υποστηρίζεται και το %s δεν θα λειτουργήσει σωστά σε αυτή την πλατφόρμα. Χρησιμοποιείτε με δική σας ευθύνη!", +"For the best results, please consider using a GNU/Linux server instead." => "Για καλύτερα αποτελέσματα, παρακαλούμε εξετάστε την μετατροπή σε έναν διακομιστή GNU/Linux.", "Personal" => "Προσωπικά", "Users" => "Χρήστες", "Apps" => "Εφαρμογές", @@ -144,6 +150,7 @@ $TRANSLATIONS = array( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Ο κατάλογος δεδομένων και τα αρχεία σας είναι πιθανό προσβάσιμα από το internet γιατί δεν δουλεύει το αρχείο .htaccess.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Για πληροφορίες πως να ρυθμίσετε ορθά τον διακομιστή σας, παρακαλώ δείτε την <a href=\"%s\" target=\"_blank\">τεκμηρίωση</a>.", "Create an <strong>admin account</strong>" => "Δημιουργήστε έναν <strong>λογαριασμό διαχειριστή</strong>", +"Storage & database" => "Αποθήκευση & βάση δεδομένων", "Data folder" => "Φάκελος δεδομένων", "Configure the database" => "Ρύθμιση της βάσης δεδομένων", "will be used" => "θα χρησιμοποιηθούν", @@ -166,6 +173,7 @@ $TRANSLATIONS = array( "remember" => "απομνημόνευση", "Log in" => "Είσοδος", "Alternative Logins" => "Εναλλακτικές Συνδέσεις", +"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Γειά χαρά,<br><br>απλά σας ενημερώνω πως ο %s μοιράστηκε το<strong>%s</strong> με εσάς.<br><a href=\"%s\">Δείτε το!</a><br><br>", "This ownCloud instance is currently in single user mode." => "Αυτή η εγκατάσταση ownCloud είναι τώρα σε κατάσταση ενός χρήστη.", "This means only administrators can use the instance." => "Αυτό σημαίνει ότι μόνο διαχειριστές μπορούν να χρησιμοποιήσουν την εγκατάσταση.", "Contact your system administrator if this message persists or appeared unexpectedly." => "Επικοινωνήστε με το διαχειριστή του συστήματος αν αυτό το μήνυμα συνεχίζει να εμφανίζεται ή εμφανίστηκε απρόσμενα.", diff --git a/core/l10n/en_GB.php b/core/l10n/en_GB.php index bc36f5a4446..215bae92d1c 100644 --- a/core/l10n/en_GB.php +++ b/core/l10n/en_GB.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Error loading message template: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} file conflict","{count} file conflicts"), "One file conflict" => "One file conflict", +"New Files" => "New Files", +"Already existing files" => "Already existing files", "Which files do you want to keep?" => "Which files do you wish to keep?", "If you select both versions, the copied file will have a number added to its name." => "If you select both versions, the copied file will have a number added to its name.", "Cancel" => "Cancel", diff --git a/core/l10n/eo.php b/core/l10n/eo.php index f264b7ed7a7..05d28efb66b 100644 --- a/core/l10n/eo.php +++ b/core/l10n/eo.php @@ -41,6 +41,7 @@ $TRANSLATIONS = array( "Ok" => "Akcepti", "_{count} file conflict_::_{count} file conflicts_" => array("{count} dosierkonflikto","{count} dosierkonfliktoj"), "One file conflict" => "Unu dosierkonflikto", +"New Files" => "Novaj dosieroj", "Which files do you want to keep?" => "Kiujn dosierojn vi volas konservi?", "If you select both versions, the copied file will have a number added to its name." => "Se vi elektos ambaŭ eldonojn, la kopiota dosiero havos numeron aldonitan al sia nomo.", "Cancel" => "Nuligi", diff --git a/core/l10n/es.php b/core/l10n/es.php index 52f1a15089a..cb2d09d60fe 100644 --- a/core/l10n/es.php +++ b/core/l10n/es.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Error cargando plantilla del mensaje: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicto de archivo","{count} conflictos de archivo"), "One file conflict" => "On conflicto de archivo", +"New Files" => "Nuevos Archivos", +"Already existing files" => "Archivos ya existentes", "Which files do you want to keep?" => "¿Que archivos deseas mantener?", "If you select both versions, the copied file will have a number added to its name." => "Si seleccionas ambas versiones, el archivo copiado tendrá añadido un número en su nombre.", "Cancel" => "Cancelar", diff --git a/core/l10n/es_AR.php b/core/l10n/es_AR.php index b5b37d4825b..c9d270edefa 100644 --- a/core/l10n/es_AR.php +++ b/core/l10n/es_AR.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Error cargando la plantilla del mensaje: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("un archivo en conflicto","{count} archivos en conflicto"), "One file conflict" => "Un archivo en conflicto", +"New Files" => "Nuevos archivos", "Which files do you want to keep?" => "¿Qué archivos deseas retener?", "If you select both versions, the copied file will have a number added to its name." => "Si tu seleccionas ambas versiones, el archivo copiado tendrá un número agregado a su nombre.", "Cancel" => "Cancelar", diff --git a/core/l10n/et_EE.php b/core/l10n/et_EE.php index 5a2e34ff3a0..422caac9c15 100644 --- a/core/l10n/et_EE.php +++ b/core/l10n/et_EE.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => "Aegumise kuupäev on minevikus.", "Couldn't send mail to following users: %s " => "Kirja saatmine järgnevatele kasutajatele ebaõnnestus: %s ", "Turned on maintenance mode" => "Haldusrežiimis sisse lülitatud", "Turned off maintenance mode" => "Haldusrežiimis välja lülitatud", @@ -49,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Viga sõnumi malli laadimisel: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} failikonflikt","{count} failikonflikti"), "One file conflict" => "Üks failikonflikt", +"New Files" => "Uued failid", "Which files do you want to keep?" => "Milliseid faile sa soovid alles hoida?", "If you select both versions, the copied file will have a number added to its name." => "Kui valid mõlemad versioonid, siis lisatakse kopeeritud faili nimele number.", "Cancel" => "Loobu", @@ -56,6 +58,11 @@ $TRANSLATIONS = array( "(all selected)" => "(kõik valitud)", "({count} selected)" => "({count} valitud)", "Error loading file exists template" => "Viga faili olemasolu malli laadimisel", +"Very weak password" => "Väga nõrk parool", +"Weak password" => "Nõrk parool", +"So-so password" => "Enam-vähem sobiv parool", +"Good password" => "Hea parool", +"Strong password" => "Väga hea parool", "Shared" => "Jagatud", "Share" => "Jaga", "Error" => "Viga", @@ -103,6 +110,7 @@ $TRANSLATIONS = array( "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Uuendus ebaõnnestus. Palun teavita probleemidest <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud kogukonda</a>.", "The update was successful. Redirecting you to ownCloud now." => "Uuendus oli edukas. Kohe suunatakse Sind ownCloudi.", "%s password reset" => "%s parooli lähtestus", +"A problem has occurred whilst sending the email, please contact your administrator." => "Tekkis tõrge e-posti saatmisel, palun kontakteeru administraatoriga.", "Use the following link to reset your password: {link}" => "Kasuta järgnevat linki oma parooli taastamiseks: {link}", "The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Link parooli vahetuseks on saadetud Sinu e-posti aadressile.<br>Kui kiri pole saabunud mõistliku aja jooksul, siis kontrolli oma spam-/rämpskirjade katalooge.<br>Kui kirja pole ka seal, siis küsi abi süsteemihaldurilt.", "Request failed!<br>Did you make sure your email/username was right?" => "Päring ebaõnnestus!<br>Oled sa veendunud, et e-post/kasutajanimi on õiged?", @@ -115,6 +123,8 @@ $TRANSLATIONS = array( "To login page" => "Sisselogimise lehele", "New password" => "Uus parool", "Reset password" => "Nulli parool", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X ei ole toetatud ja %s ei pruugi korralikult toimida sellel platvormil. Kasuta seda omal vastutusel!", +"For the best results, please consider using a GNU/Linux server instead." => "Parema tulemuse saavitamiseks palun kaalu serveris GNU/Linux kasutamist.", "Personal" => "Isiklik", "Users" => "Kasutajad", "Apps" => "Rakendused", @@ -140,6 +150,7 @@ $TRANSLATIONS = array( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Su andmete kataloog ja failid on tõenäoliselt internetist vabalt saadaval kuna .htaccess fail ei toimi.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Serveri korrektseks seadistuseks palun tutvu <a href=\"%s\" target=\"_blank\">dokumentatsiooniga</a>.", "Create an <strong>admin account</strong>" => "Loo <strong>admini konto</strong>", +"Storage & database" => "Andmehoidla ja andmebaas", "Data folder" => "Andmete kaust", "Configure the database" => "Seadista andmebaasi", "will be used" => "kasutatakse", @@ -162,6 +173,7 @@ $TRANSLATIONS = array( "remember" => "pea meeles", "Log in" => "Logi sisse", "Alternative Logins" => "Alternatiivsed sisselogimisviisid", +"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Hei,<br><br>annan teada, et %s jagas sinuga <strong>%s</strong>. <a href=\"%s\">Vaata seda!</a><br><br>", "This ownCloud instance is currently in single user mode." => "See ownCloud on momendil seadistatud ühe kasutaja jaoks.", "This means only administrators can use the instance." => "See tähendab, et seda saavad kasutada ainult administraatorid.", "Contact your system administrator if this message persists or appeared unexpectedly." => "Kontakteeru oma süsteemihalduriga, kui see teade püsib või on tekkinud ootamatult.", diff --git a/core/l10n/eu.php b/core/l10n/eu.php index 33c98fb9b90..8fd554485db 100644 --- a/core/l10n/eu.php +++ b/core/l10n/eu.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Errorea mezu txantiloia kargatzean: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("fitxategi {count}ek konfliktua sortu du","{count} fitxategik konfliktua sortu dute"), "One file conflict" => "Fitxategi batek konfliktua sortu du", +"New Files" => "Fitxategi Berriak", "Which files do you want to keep?" => "Ze fitxategi mantendu nahi duzu?", "If you select both versions, the copied file will have a number added to its name." => "Bi bertsioak hautatzen badituzu, kopiatutako fitxategiaren izenean zenbaki bat atxikituko zaio.", "Cancel" => "Ezeztatu", diff --git a/core/l10n/fa.php b/core/l10n/fa.php index 3e7e246e827..a349d3b7704 100644 --- a/core/l10n/fa.php +++ b/core/l10n/fa.php @@ -37,6 +37,7 @@ $TRANSLATIONS = array( "No" => "نه", "Ok" => "قبول", "_{count} file conflict_::_{count} file conflicts_" => array(""), +"New Files" => "فایل های جدید", "Cancel" => "منصرف شدن", "Shared" => "اشتراک گذاشته شده", "Share" => "اشتراکگذاری", diff --git a/core/l10n/fi_FI.php b/core/l10n/fi_FI.php index 0af7503ee9d..7797d17c872 100644 --- a/core/l10n/fi_FI.php +++ b/core/l10n/fi_FI.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Virhe ladatessa viestipohjaa: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} tiedoston ristiriita","{count} tiedoston ristiriita"), "One file conflict" => "Yhden tiedoston ristiriita", +"New Files" => "Uudet tiedostot", +"Already existing files" => "Jo olemassa olevat tiedostot", "Which files do you want to keep?" => "Mitkä tiedostot haluat säilyttää?", "If you select both versions, the copied file will have a number added to its name." => "Jos valitset kummatkin versiot, kopioidun tiedoston nimeen lisätään numero.", "Cancel" => "Peru", @@ -122,6 +124,8 @@ $TRANSLATIONS = array( "To login page" => "Kirjautumissivulle", "New password" => "Uusi salasana", "Reset password" => "Palauta salasana", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X ei ole tuettu, joten %s ei toimi kunnolla tällä alustalla. Käytä omalla vastuulla!", +"For the best results, please consider using a GNU/Linux server instead." => "Käytä parhaan lopputuloksen saamiseksi GNU/Linux-palvelinta.", "Personal" => "Henkilökohtainen", "Users" => "Käyttäjät", "Apps" => "Sovellukset", diff --git a/core/l10n/fr.php b/core/l10n/fr.php index 3754e8c9e07..2475eddee8a 100644 --- a/core/l10n/fr.php +++ b/core/l10n/fr.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => "La date d'expiration est dans le passé.", "Couldn't send mail to following users: %s " => "Impossible d'envoyer un mail aux utilisateurs suivant : %s", "Turned on maintenance mode" => "Basculé en mode maintenance", "Turned off maintenance mode" => "Basculé en mode production (non maintenance)", @@ -49,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Erreur de chargement du modèle de message : {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} fichier en conflit","{count} fichiers en conflit"), "One file conflict" => "Un conflit de fichier", +"New Files" => "Nouveaux fichiers", "Which files do you want to keep?" => "Quels fichiers désirez-vous garder ?", "If you select both versions, the copied file will have a number added to its name." => "Si vous sélectionnez les deux versions, un nombre sera ajouté au nom du fichier copié.", "Cancel" => "Annuler", @@ -121,6 +123,8 @@ $TRANSLATIONS = array( "To login page" => "Retour à la page d'authentification", "New password" => "Nouveau mot de passe", "Reset password" => "Réinitialiser le mot de passe", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X n'est pas supporté et %s ne fonctionnera pas correctement sur cette plateforme. Son utilisation est à vos risques et périls !", +"For the best results, please consider using a GNU/Linux server instead." => "Pour des résultats meilleurs encore, pensez à utiliser un serveur GNU/Linux à la place.", "Personal" => "Personnel", "Users" => "Utilisateurs", "Apps" => "Applications", diff --git a/core/l10n/gl.php b/core/l10n/gl.php index c1c678e7e3f..eb9f1af5657 100644 --- a/core/l10n/gl.php +++ b/core/l10n/gl.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Produciuse un erro ao cargar o modelo da mensaxe: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} conflito de ficheiro","{count} conflitos de ficheiros"), "One file conflict" => "Un conflito de ficheiro", +"New Files" => "Ficheiros novos", +"Already existing files" => "Ficheiros xa existentes", "Which files do you want to keep?" => "Que ficheiros quere conservar?", "If you select both versions, the copied file will have a number added to its name." => "Se selecciona ambas versións, o ficheiro copiado terá un número engadido ao nome.", "Cancel" => "Cancelar", diff --git a/core/l10n/he.php b/core/l10n/he.php index 4579626f12d..8fb7373a143 100644 --- a/core/l10n/he.php +++ b/core/l10n/he.php @@ -37,6 +37,7 @@ $TRANSLATIONS = array( "No" => "לא", "Ok" => "בסדר", "_{count} file conflict_::_{count} file conflicts_" => array("",""), +"New Files" => "קבצים חדשים", "Cancel" => "ביטול", "Shared" => "שותף", "Share" => "שתף", diff --git a/core/l10n/hu_HU.php b/core/l10n/hu_HU.php index e81991ec7ad..096b28e2d9b 100644 --- a/core/l10n/hu_HU.php +++ b/core/l10n/hu_HU.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Nem sikerült betölteni az üzenet sablont: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} fájl ütközik","{count} fájl ütközik"), "One file conflict" => "Egy file ütközik", +"New Files" => "Új fájlok", "Which files do you want to keep?" => "Melyik file-okat akarod megtartani?", "If you select both versions, the copied file will have a number added to its name." => "Ha kiválasztod mindazokaz a verziókat, a másolt fileok neve sorszámozva lesz.", "Cancel" => "Mégsem", diff --git a/core/l10n/it.php b/core/l10n/it.php index 2f0017263fa..43e9752f5e0 100644 --- a/core/l10n/it.php +++ b/core/l10n/it.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Errore durante il caricamento del modello di messaggio: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} file in conflitto","{count} file in conflitto"), "One file conflict" => "Un file in conflitto", +"New Files" => "File nuovi", "Which files do you want to keep?" => "Quali file vuoi mantenere?", "If you select both versions, the copied file will have a number added to its name." => "Se selezioni entrambe le versioni, sarà aggiunto un numero al nome del file copiato.", "Cancel" => "Annulla", diff --git a/core/l10n/ja.php b/core/l10n/ja.php index eb3e6882578..3a99f0e598b 100644 --- a/core/l10n/ja.php +++ b/core/l10n/ja.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => "有効期限が切れています。", "Couldn't send mail to following users: %s " => "次のユーザーにメールを送信できませんでした: %s", "Turned on maintenance mode" => "メンテナンスモードがオンになりました", "Turned off maintenance mode" => "メンテナンスモードがオフになりました", @@ -49,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "メッセージテンプレートの読み込みエラー: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} ファイルが競合"), "One file conflict" => "1ファイルが競合", +"New Files" => "新しいファイル", "Which files do you want to keep?" => "どちらのファイルを保持したいですか?", "If you select both versions, the copied file will have a number added to its name." => "両方のバージョンを選択した場合は、ファイル名の後ろに数字を追加したファイルのコピーを作成します。", "Cancel" => "キャンセル", @@ -121,6 +123,8 @@ $TRANSLATIONS = array( "To login page" => "ログインページへ戻る", "New password" => "新しいパスワードを入力", "Reset password" => "パスワードをリセット", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X では、サポートされていません。このOSでは、%sは正常に動作しないかもしれません。ご自身の責任においてご利用ください。", +"For the best results, please consider using a GNU/Linux server instead." => "最も良い方法としては、代わりにGNU/Linuxサーバーを利用することをご検討ください。", "Personal" => "個人", "Users" => "ユーザー", "Apps" => "アプリ", diff --git a/core/l10n/jv.php b/core/l10n/jv.php new file mode 100644 index 00000000000..ffcdde48d47 --- /dev/null +++ b/core/l10n/jv.php @@ -0,0 +1,9 @@ +<?php +$TRANSLATIONS = array( +"_%n minute ago_::_%n minutes ago_" => array("",""), +"_%n hour ago_::_%n hours ago_" => array("",""), +"_%n day ago_::_%n days ago_" => array("",""), +"_%n month ago_::_%n months ago_" => array("",""), +"_{count} file conflict_::_{count} file conflicts_" => array("","") +); +$PLURAL_FORMS = "nplurals=2; plural=(n != 1);"; diff --git a/core/l10n/ka_GE.php b/core/l10n/ka_GE.php index 0070fd7994e..a76a8866541 100644 --- a/core/l10n/ka_GE.php +++ b/core/l10n/ka_GE.php @@ -37,6 +37,7 @@ $TRANSLATIONS = array( "No" => "არა", "Ok" => "დიახ", "_{count} file conflict_::_{count} file conflicts_" => array(""), +"New Files" => "ახალი ფაილები", "Cancel" => "უარყოფა", "Shared" => "გაზიარებული", "Share" => "გაზიარება", diff --git a/core/l10n/lv.php b/core/l10n/lv.php index 505bf46b4c9..683ff2c129a 100644 --- a/core/l10n/lv.php +++ b/core/l10n/lv.php @@ -37,6 +37,7 @@ $TRANSLATIONS = array( "No" => "Nē", "Ok" => "Labi", "_{count} file conflict_::_{count} file conflicts_" => array("","",""), +"New Files" => "Jaunās datnes", "Cancel" => "Atcelt", "Shared" => "Kopīgs", "Share" => "Dalīties", diff --git a/core/l10n/nb_NO.php b/core/l10n/nb_NO.php index 43141bc431f..c47599f5a17 100644 --- a/core/l10n/nb_NO.php +++ b/core/l10n/nb_NO.php @@ -56,6 +56,10 @@ $TRANSLATIONS = array( "(all selected)" => "(alle valgt)", "({count} selected)" => "({count} valgt)", "Error loading file exists template" => "Feil ved lasting av \"filen eksisterer\"-mal", +"Very weak password" => "Veldig svakt passord", +"Weak password" => "Svakt passord", +"Good password" => "Bra passord", +"Strong password" => "Sterkt passord", "Shared" => "Delt", "Share" => "Del", "Error" => "Feil", @@ -140,6 +144,7 @@ $TRANSLATIONS = array( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Datamappen og filene dine er sannsynligvis tilgjengelig fra Internett fordi .htaccess-filen ikke fungerer.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "For informasjon om hvordan du setter opp serveren din riktig, se <a href=\"%s\" target=\"_blank\">dokumentasjonen</a>.", "Create an <strong>admin account</strong>" => "opprett en <strong>administrator-konto</strong>", +"Storage & database" => "Lagring og database", "Data folder" => "Datamappe", "Configure the database" => "Konfigurer databasen", "will be used" => "vil bli brukt", diff --git a/core/l10n/nl.php b/core/l10n/nl.php index 05cef6afd5a..b09509e6290 100644 --- a/core/l10n/nl.php +++ b/core/l10n/nl.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Fout bij laden berichtensjabloon: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} bestandsconflict","{count} bestandsconflicten"), "One file conflict" => "Een bestandsconflict", +"New Files" => "Nieuwe bestanden", +"Already existing files" => "Al aanwezige bestanden", "Which files do you want to keep?" => "Welke bestanden wilt u bewaren?", "If you select both versions, the copied file will have a number added to its name." => "Als u beide versies selecteerde, zal het gekopieerde bestand een nummer aan de naam toegevoegd krijgen.", "Cancel" => "Annuleer", diff --git a/core/l10n/pl.php b/core/l10n/pl.php index 17fde36c7cd..fe0cf145832 100644 --- a/core/l10n/pl.php +++ b/core/l10n/pl.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Błąd podczas ładowania szablonu wiadomości: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} konfliktów plików","{count} konfliktów plików","{count} konfliktów plików"), "One file conflict" => "Konflikt pliku", +"New Files" => "Nowe pliki", +"Already existing files" => "Już istniejące pliki", "Which files do you want to keep?" => "Które pliki chcesz zachować?", "If you select both versions, the copied file will have a number added to its name." => "Jeśli wybierzesz obie wersje, skopiowany plik będzie miał dodany numerek w nazwie", "Cancel" => "Anuluj", diff --git a/core/l10n/pl_PL.php b/core/l10n/pl_PL.php deleted file mode 100644 index 15c376eb954..00000000000 --- a/core/l10n/pl_PL.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php -$TRANSLATIONS = array( -"Settings" => "Ustawienia", -"Username" => "Nazwa użytkownika" -); -$PLURAL_FORMS = "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"; diff --git a/core/l10n/pt_BR.php b/core/l10n/pt_BR.php index b31925cdf79..3545426b670 100644 --- a/core/l10n/pt_BR.php +++ b/core/l10n/pt_BR.php @@ -50,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Erro no carregamento de modelo de mensagem: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} conflito de arquivo","{count} conflitos de arquivos"), "One file conflict" => "Conflito em um arquivo", +"New Files" => "Novos Arquivos", +"Already existing files" => "Arquivos já existentes", "Which files do you want to keep?" => "Qual arquivo você quer manter?", "If you select both versions, the copied file will have a number added to its name." => "Se você selecionar ambas as versões, o arquivo copiado terá um número adicionado ao seu nome.", "Cancel" => "Cancelar", diff --git a/core/l10n/pt_PT.php b/core/l10n/pt_PT.php index a4d6785cd5e..bb1b6011a6b 100644 --- a/core/l10n/pt_PT.php +++ b/core/l10n/pt_PT.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Erro ao carregar o template: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} conflicto de ficheiro","{count} conflitos de ficheiro"), "One file conflict" => "Um conflito no ficheiro", +"New Files" => "Ficheiros Novos", "Which files do you want to keep?" => "Quais os ficheiros que pretende manter?", "If you select both versions, the copied file will have a number added to its name." => "Se escolher ambas as versões, o ficheiro copiado irá ter um número adicionado ao seu nome.", "Cancel" => "Cancelar", diff --git a/core/l10n/ru.php b/core/l10n/ru.php index e2fdc36be0b..aa784088f7a 100644 --- a/core/l10n/ru.php +++ b/core/l10n/ru.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Ошибка загрузки шаблона сообщений: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} конфликт в файлах","{count} конфликта в файлах","{count} конфликтов в файлах"), "One file conflict" => "Один конфликт в файлах", +"New Files" => "Новые файлы", "Which files do you want to keep?" => "Какие файлы вы хотите сохранить?", "If you select both versions, the copied file will have a number added to its name." => "При выборе обоих версий, к названию копируемого файла будет добавлена цифра", "Cancel" => "Отменить", diff --git a/core/l10n/sk_SK.php b/core/l10n/sk_SK.php index bb3c9863ce2..1b717bc412e 100644 --- a/core/l10n/sk_SK.php +++ b/core/l10n/sk_SK.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => " \t\nDátum expirácie spadá do minulosti.", "Couldn't send mail to following users: %s " => "Nebolo možné odoslať email týmto používateľom: %s ", "Turned on maintenance mode" => "Mód údržby je zapnutý", "Turned off maintenance mode" => "Mód údržby e vypnutý", @@ -49,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Chyba pri nahrávaní šablóny správy: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} konflikt súboru","{count} konflikty súboru","{count} konfliktov súboru"), "One file conflict" => "Jeden konflikt súboru", +"New Files" => "Nové súbory", "Which files do you want to keep?" => "Ktoré súbory chcete ponechať?", "If you select both versions, the copied file will have a number added to its name." => "Ak zvolíte obe verzie, názov nakopírovaného súboru bude doplnený o číslo.", "Cancel" => "Zrušiť", @@ -56,6 +58,11 @@ $TRANSLATIONS = array( "(all selected)" => "(všetko vybrané)", "({count} selected)" => "({count} vybraných)", "Error loading file exists template" => "Chyba pri nahrávaní šablóny existencie súboru", +"Very weak password" => "Veľmi slabé heslo", +"Weak password" => "Slabé heslo", +"So-so password" => "Priemerné heslo", +"Good password" => "Dobré heslo", +"Strong password" => "Silné heslo", "Shared" => "Zdieľané", "Share" => "Zdieľať", "Error" => "Chyba", @@ -103,6 +110,7 @@ $TRANSLATIONS = array( "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Aktualizácia nebola úspešná. Problém nahláste <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud comunite</a>.", "The update was successful. Redirecting you to ownCloud now." => "Aktualizácia bola úspešná. Presmerovávam vás na prihlasovaciu stránku.", "%s password reset" => "reset hesla %s", +"A problem has occurred whilst sending the email, please contact your administrator." => "Vyskytol sa problém pri odosielaní emailu, prosím obráťte sa na správcu.", "Use the following link to reset your password: {link}" => "Použite nasledujúci odkaz pre obnovenie vášho hesla: {link}", "The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Odkaz na obnovenie hesla bol odoslaný na vašu emailovú adresu.<br>Ak ho v krátkej dobe neobdržíte, skontrolujte si váš kôš a priečinok spam.<br>Ak ho ani tam nenájdete, kontaktujte svojho administrátora.", "Request failed!<br>Did you make sure your email/username was right?" => "Požiadavka zlyhala.<br>Uistili ste sa, že vaše používateľské meno a email sú správne?", @@ -115,6 +123,8 @@ $TRANSLATIONS = array( "To login page" => "Na prihlasovaciu stránku", "New password" => "Nové heslo", "Reset password" => "Obnovenie hesla", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X nie je podporovaný a %s nebude správne fungovať na tejto platforme. Použite ho na vlastné riziko!", +"For the best results, please consider using a GNU/Linux server instead." => "Pre dosiahnutie najlepších výsledkov, prosím zvážte použitie GNU/Linux servera.", "Personal" => "Osobné", "Users" => "Používatelia", "Apps" => "Aplikácie", @@ -129,7 +139,7 @@ $TRANSLATIONS = array( "Error unfavoriting" => "Chyba pri odobratí z obľúbených", "Access forbidden" => "Prístup odmietnutý", "Cloud not found" => "Nenájdené", -"Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" => "Ahoj,\n\nchcem ti dať navedomie, že %s s tebou zdieľa %s.\nTu je odkaz: %s\n\n", +"Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" => "Dobrý deň,\n\nPoužívateľ %s zdieľa s vami súbor, alebo priečinok s názvom %s.\nPre zobrazenie kliknite na túto linku: %s\n", "The share will expire on %s." => "Zdieľanie expiruje %s.", "Cheers!" => "Pekný deň!", "Security Warning" => "Bezpečnostné varovanie", @@ -140,6 +150,7 @@ $TRANSLATIONS = array( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Váš priečinok s dátami a súbormi je dostupný z internetu, lebo súbor .htaccess nefunguje.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "Pre informácie, ako správne nastaviť váš server, sa pozrite do <a href=\"%s\" target=\"_blank\">dokumentácie</a>.", "Create an <strong>admin account</strong>" => "Vytvoriť <strong>administrátorský účet</strong>", +"Storage & database" => "Úložislo & databáza", "Data folder" => "Priečinok dát", "Configure the database" => "Nastaviť databázu", "will be used" => "bude použité", @@ -162,6 +173,7 @@ $TRANSLATIONS = array( "remember" => "zapamätať", "Log in" => "Prihlásiť sa", "Alternative Logins" => "Alternatívne prihlásenie", +"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Dobrý deň,<br><br>Používateľ %s zdieľa s vami súbor, alebo priečinok s názvom »%s«.<br><a href=\"%s\">Pre zobrazenie kliknite na túto linku!</a><br><br>", "This ownCloud instance is currently in single user mode." => "Táto inštancia ownCloudu je teraz v jednopoužívateľskom móde.", "This means only administrators can use the instance." => "Len správca systému môže používať túto inštanciu.", "Contact your system administrator if this message persists or appeared unexpectedly." => "Kontaktujte prosím správcu systému, ak sa táto správa objavuje opakovane alebo neočakávane.", diff --git a/core/l10n/sl.php b/core/l10n/sl.php index 49eb4f9aa69..7476d9f9c7c 100644 --- a/core/l10n/sl.php +++ b/core/l10n/sl.php @@ -50,6 +50,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Napaka nalaganja predloge sporočil: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} spor datotek","{count} spora datotek","{count} spori datotek","{count} sporov datotek"), "One file conflict" => "En spor datotek", +"New Files" => "Nove datoteke", "Which files do you want to keep?" => "Katare datoteke želite ohraniti?", "If you select both versions, the copied file will have a number added to its name." => "Če izberete obe različici, bo kopirani datoteki k imenu dodana številka.", "Cancel" => "Prekliči", diff --git a/core/l10n/sv.php b/core/l10n/sv.php index c4e92e62171..d46c204d7c3 100644 --- a/core/l10n/sv.php +++ b/core/l10n/sv.php @@ -1,5 +1,6 @@ <?php $TRANSLATIONS = array( +"Expiration date is in the past." => "Utgångsdatumet är i det förflutna.", "Couldn't send mail to following users: %s " => "Gick inte att skicka e-post till följande användare: %s", "Turned on maintenance mode" => "Aktiverade underhållsläge", "Turned off maintenance mode" => "Deaktiverade underhållsläge", @@ -49,6 +50,8 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Fel uppstod under inläsningen av meddelandemallen: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} filkonflikt","{count} filkonflikter"), "One file conflict" => "En filkonflikt", +"New Files" => "Nya filer", +"Already existing files" => "Filer som redan existerar", "Which files do you want to keep?" => "Vilken fil vill du behålla?", "If you select both versions, the copied file will have a number added to its name." => "Om du väljer båda versionerna kommer de kopierade filerna ha nummer tillagda i filnamnet.", "Cancel" => "Avbryt", @@ -56,6 +59,11 @@ $TRANSLATIONS = array( "(all selected)" => "(Alla valda)", "({count} selected)" => "({count} valda)", "Error loading file exists template" => "Fel uppstod filmall existerar", +"Very weak password" => "Väldigt svagt lösenord", +"Weak password" => "Svagt lösenord", +"So-so password" => "Okej lösenord", +"Good password" => "Bra lösenord", +"Strong password" => "Starkt lösenord", "Shared" => "Delad", "Share" => "Dela", "Error" => "Fel", @@ -99,9 +107,11 @@ $TRANSLATIONS = array( "Edit tags" => "Editera taggar", "Error loading dialog template: {error}" => "Fel under laddning utav dialog mall: {fel}", "No tags selected for deletion." => "Inga taggar valda för borttagning.", +"Please reload the page." => "Vänligen ladda om sidan.", "The update was unsuccessful. Please report this issue to the <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud community</a>." => "Uppdateringen misslyckades. Rapportera detta problem till <a href=\"https://github.com/owncloud/core/issues\" target=\"_blank\">ownCloud Community</a>.", "The update was successful. Redirecting you to ownCloud now." => "Uppdateringen lyckades. Du omdirigeras nu till OwnCloud.", "%s password reset" => "%s återställ lösenord", +"A problem has occurred whilst sending the email, please contact your administrator." => "Ett problem har uppstått under tiden e-post sändes, vänligen kontakta din administratör.", "Use the following link to reset your password: {link}" => "Använd följande länk för att återställa lösenordet: {link}", "The link to reset your password has been sent to your email.<br>If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator ." => "Länken för att återställa ditt lösenorden har skickats till din e-postadress<br>Om du inte har erhållit meddelandet inom kort, vänligen kontrollera din skräppost-mapp<br>Om den inte finns där, vänligen kontakta din administratör.", "Request failed!<br>Did you make sure your email/username was right?" => "Begäran misslyckades!<br>Är du helt säker på att din e-postadress/användarnamn är korrekt?", @@ -114,6 +124,8 @@ $TRANSLATIONS = array( "To login page" => "Till logginsidan", "New password" => "Nytt lösenord", "Reset password" => "Återställ lösenordet", +"Mac OS X is not supported and %s will not work properly on this platform. Use it at your own risk! " => "Mac OS X stöds inte och %s kommer inte att fungera korrekt på denna plattform. Använd på egen risk!", +"For the best results, please consider using a GNU/Linux server instead." => "För bästa resultat, överväg att använda en GNU/Linux server istället.", "Personal" => "Personligt", "Users" => "Användare", "Apps" => "Program", @@ -139,6 +151,7 @@ $TRANSLATIONS = array( "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." => "Din datakatalog och filer är förmodligen tillgängliga från Internet, eftersom .htaccess-filen inte fungerar.", "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\">documentation</a>." => "För information hur du korrekt konfigurerar din servern, se ownCloud <a href=\"%s\" target=\"_blank\">dokumentationen</a>.", "Create an <strong>admin account</strong>" => "Skapa ett <strong>administratörskonto</strong>", +"Storage & database" => "Lagring & databas", "Data folder" => "Datamapp", "Configure the database" => "Konfigurera databasen", "will be used" => "kommer att användas", @@ -149,6 +162,7 @@ $TRANSLATIONS = array( "Database host" => "Databasserver", "Finish setup" => "Avsluta installation", "Finishing …" => "Avslutar ...", +"This application requires JavaScript to be enabled for correct operation. Please <a href=\"http://enable-javascript.com/\" target=\"_blank\">enable JavaScript</a> and re-load this interface." => "Denna applikation kräver JavaScript aktiverat för att fungera korrekt. Vänligen <a href=\"http://enable-javascript.com/\" target=\"_blank\">aktivera JavaScript</a> och ladda om gränssnittet.", "%s is available. Get more information on how to update." => "%s är tillgänglig. Få mer information om hur du går tillväga för att uppdatera.", "Log out" => "Logga ut", "Automatic logon rejected!" => "Automatisk inloggning inte tillåten!", @@ -160,6 +174,9 @@ $TRANSLATIONS = array( "remember" => "kom ihåg", "Log in" => "Logga in", "Alternative Logins" => "Alternativa inloggningar", +"Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" => "Hej där,<br><br>ville bara informera dig om att %s delade <strong>%s</strong> med dig.<br><a href=\"%s\">Visa den!</a><br><br>", +"This ownCloud instance is currently in single user mode." => "Denna ownCloud instans är för närvarande i enanvändarläge", +"This means only administrators can use the instance." => "Detta betyder att endast administartörer kan använda instansen.", "Contact your system administrator if this message persists or appeared unexpectedly." => "Hör av dig till din system administratör ifall detta meddelande fortsätter eller visas oväntat.", "Thank you for your patience." => "Tack för ditt tålamod.", "Updating ownCloud to version %s, this may take a while." => "Uppdaterar ownCloud till version %s, detta kan ta en stund.", diff --git a/core/l10n/th_TH.php b/core/l10n/th_TH.php index 85a9b4ab238..9ee3c60f947 100644 --- a/core/l10n/th_TH.php +++ b/core/l10n/th_TH.php @@ -37,6 +37,7 @@ $TRANSLATIONS = array( "No" => "ไม่ตกลง", "Ok" => "ตกลง", "_{count} file conflict_::_{count} file conflicts_" => array(""), +"New Files" => "ไฟล์ใหม่", "Cancel" => "ยกเลิก", "Shared" => "แชร์แล้ว", "Share" => "แชร์", diff --git a/core/l10n/tr.php b/core/l10n/tr.php index affa1b063d0..7e75cdf4b01 100644 --- a/core/l10n/tr.php +++ b/core/l10n/tr.php @@ -31,7 +31,7 @@ $TRANSLATIONS = array( "December" => "Aralık", "Settings" => "Ayarlar", "Saving..." => "Kaydediliyor...", -"seconds ago" => "saniye önce", +"seconds ago" => "saniyeler önce", "_%n minute ago_::_%n minutes ago_" => array("%n dakika önce","%n dakika önce"), "_%n hour ago_::_%n hours ago_" => array("%n saat önce","%n saat önce"), "today" => "bugün", @@ -50,8 +50,10 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "İleti şablonu yüklenirken hata: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} dosya çakışması","{count} dosya çakışması"), "One file conflict" => "Bir dosya çakışması", +"New Files" => "Yeni Dosyalar", +"Already existing files" => "Zaten mevcut olan dosyalar", "Which files do you want to keep?" => "Hangi dosyaları saklamak istiyorsunuz?", -"If you select both versions, the copied file will have a number added to its name." => "Eğer iki sürümü de seçerseniz, kopyalanan dosya ismine eklenmiş bir sayı içerecektir.", +"If you select both versions, the copied file will have a number added to its name." => "İki sürümü de seçerseniz, kopyalanan dosyanın ismine bir sayı ilave edilecektir.", "Cancel" => "İptal", "Continue" => "Devam et", "(all selected)" => "(tümü seçildi)", @@ -65,7 +67,7 @@ $TRANSLATIONS = array( "Shared" => "Paylaşılan", "Share" => "Paylaş", "Error" => "Hata", -"Error while sharing" => "Paylaşım sırasında hata ", +"Error while sharing" => "Paylaşım sırasında hata", "Error while unsharing" => "Paylaşım iptal edilirken hata", "Error while changing permissions" => "İzinleri değiştirirken hata oluştu", "Shared with you and the group {group} by {owner}" => "{owner} tarafından sizinle ve {group} ile paylaştırılmış", @@ -159,7 +161,7 @@ $TRANSLATIONS = array( "Database tablespace" => "Veritabanı tablo alanı", "Database host" => "Veritabanı sunucusu", "Finish setup" => "Kurulumu tamamla", -"Finishing …" => "Tamamlanıyor ..", +"Finishing …" => "Tamamlanıyor ...", "This application requires JavaScript to be enabled for correct operation. Please <a href=\"http://enable-javascript.com/\" target=\"_blank\">enable JavaScript</a> and re-load this interface." => "Uygulama, doğru çalışabilmesi için JavaScript'in etkinleştirilmesini gerektiriyor. Lütfen <a href=\"http://enable-javascript.com/\" target=\"_blank\">JavaScript'i etkinleştirin</a> ve bu arayüzü yeniden yükleyin.", "%s is available. Get more information on how to update." => "%s mevcut. Güncelleştirme hakkında daha fazla bilgi alın.", "Log out" => "Çıkış yap", diff --git a/core/l10n/uk.php b/core/l10n/uk.php index ade29981b49..f6bcfdcdc8d 100644 --- a/core/l10n/uk.php +++ b/core/l10n/uk.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Помилка при завантаженні шаблону повідомлення: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} файловий конфлікт","{count} файлових конфліктів","{count} файлових конфліктів"), "One file conflict" => "Один файловий конфлікт", +"New Files" => "Нових Файлів", "Which files do you want to keep?" => "Які файли ви хочете залишити?", "If you select both versions, the copied file will have a number added to its name." => "Якщо ви оберете обидві версії, скопійований файл буде мати номер, доданий у його ім'я.", "Cancel" => "Відмінити", diff --git a/core/l10n/vi.php b/core/l10n/vi.php index be99580d942..319f68b6355 100644 --- a/core/l10n/vi.php +++ b/core/l10n/vi.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "Lỗi khi tải mẫu thông điệp: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} tập tin xung đột"), "One file conflict" => "Một tập tin xung đột", +"New Files" => "File mới", "Which files do you want to keep?" => "Bạn muốn tiếp tục với những tập tin nào?", "If you select both versions, the copied file will have a number added to its name." => "Nếu bạn chọn cả hai phiên bản, tập tin được sao chép sẽ được đánh thêm số vào tên của nó.", "Cancel" => "Hủy", diff --git a/core/l10n/zh_CN.php b/core/l10n/zh_CN.php index e5a6a254e54..68f50baf98f 100644 --- a/core/l10n/zh_CN.php +++ b/core/l10n/zh_CN.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "加载消息模板出错: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} 个文件冲突"), "One file conflict" => "1个文件冲突", +"New Files" => "新文件", "Which files do you want to keep?" => "想要保留哪一个文件呢?", "If you select both versions, the copied file will have a number added to its name." => "如果同时选择了连个版本,复制的文件名将会添加上一个数字。", "Cancel" => "取消", diff --git a/core/l10n/zh_TW.php b/core/l10n/zh_TW.php index dae143cef40..0799344697a 100644 --- a/core/l10n/zh_TW.php +++ b/core/l10n/zh_TW.php @@ -49,6 +49,7 @@ $TRANSLATIONS = array( "Error loading message template: {error}" => "載入訊息樣板出錯: {error}", "_{count} file conflict_::_{count} file conflicts_" => array("{count} 個檔案衝突"), "One file conflict" => "一個檔案衝突", +"New Files" => "新檔案", "Which files do you want to keep?" => "您要保留哪一個檔案?", "If you select both versions, the copied file will have a number added to its name." => "如果您同時選擇兩個版本,被複製的那個檔案名稱後面會加上編號", "Cancel" => "取消", diff --git a/core/lostpassword/templates/resetpassword.php b/core/lostpassword/templates/resetpassword.php index 0ab32acca60..881455f5a9d 100644 --- a/core/lostpassword/templates/resetpassword.php +++ b/core/lostpassword/templates/resetpassword.php @@ -1,14 +1,14 @@ -<form action="<?php echo OC_Helper::linkToRoute('core_lostpassword_reset', $_['args']) ?>" method="post"> +<form action="<?php print_unescaped(OC_Helper::linkToRoute('core_lostpassword_reset', $_['args'])) ?>" method="post"> <fieldset> <?php if($_['success']): ?> - <h1><?php echo $l->t('Your password was reset'); ?></h1> - <p><a href="<?php echo OC_Helper::linkTo('', 'index.php') ?>/"><?php echo $l->t('To login page'); ?></a></p> + <h1><?php p($l->t('Your password was reset')); ?></h1> + <p><a href="<?php print_unescaped(OC_Helper::linkTo('', 'index.php')) ?>/"><?php p($l->t('To login page')); ?></a></p> <?php else: ?> <p class="infield"> - <label for="password" class="infield"><?php echo $l->t( 'New password' ); ?></label> + <label for="password" class="infield"><?php p($l->t('New password')); ?></label> <input type="password" name="password" id="password" value="" required /> </p> - <input type="submit" id="submit" value="<?php echo $l->t('Reset password'); ?>" /> + <input type="submit" id="submit" value="<?php p($l->t('Reset password')); ?>" /> <?php endif; ?> </fieldset> </form> |