aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/files/ajax/delete.php2
-rw-r--r--apps/files/ajax/download.php2
-rw-r--r--apps/files/ajax/getstoragestats.php2
-rw-r--r--apps/files/ajax/list.php4
-rw-r--r--apps/files/ajax/mimeicon.php2
-rw-r--r--apps/files/ajax/move.php4
-rw-r--r--apps/files/ajax/newfile.php4
-rw-r--r--apps/files/ajax/newfolder.php4
-rw-r--r--apps/files/ajax/rename.php4
-rw-r--r--apps/files/ajax/scan.php2
-rw-r--r--apps/files/ajax/upload.php4
-rw-r--r--apps/files/appinfo/app.php2
-rw-r--r--apps/files/js/filelist.js2
-rw-r--r--apps/files/l10n/bn_BD.php1
-rw-r--r--apps/files/l10n/et_EE.php1
-rw-r--r--apps/files/l10n/he.php1
-rw-r--r--apps/files/l10n/hu_HU.php12
-rw-r--r--apps/files/l10n/nn_NO.php1
-rw-r--r--apps/files/l10n/pt_PT.php2
-rw-r--r--apps/files/l10n/zh_TW.php1
-rw-r--r--apps/files_encryption/ajax/adminrecovery.php2
-rw-r--r--apps/files_encryption/ajax/changeRecoveryPassword.php2
-rw-r--r--apps/files_encryption/ajax/updatePrivateKeyPassword.php2
-rw-r--r--apps/files_encryption/files/error.php2
-rw-r--r--apps/files_encryption/l10n/bn_BD.php3
-rw-r--r--apps/files_encryption/l10n/da.php2
-rw-r--r--apps/files_encryption/l10n/et_EE.php1
-rw-r--r--apps/files_encryption/lib/session.php22
-rw-r--r--apps/files_external/3rdparty/select2/LICENSE18
-rw-r--r--apps/files_external/3rdparty/select2/README.md90
-rw-r--r--apps/files_external/3rdparty/select2/bower.json8
-rw-r--r--apps/files_external/3rdparty/select2/component.json66
-rw-r--r--apps/files_external/3rdparty/select2/composer.json29
-rw-r--r--apps/files_external/3rdparty/select2/package.json20
-rwxr-xr-xapps/files_external/3rdparty/select2/release.sh79
-rw-r--r--apps/files_external/3rdparty/select2/select2-bootstrap.css87
-rw-r--r--apps/files_external/3rdparty/select2/select2-spinner.gifbin0 -> 1849 bytes
-rw-r--r--apps/files_external/3rdparty/select2/select2.css646
-rw-r--r--apps/files_external/3rdparty/select2/select2.jquery.json36
-rw-r--r--apps/files_external/3rdparty/select2/select2.js3448
-rw-r--r--apps/files_external/3rdparty/select2/select2.pngbin0 -> 613 bytes
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ar.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_bg.js18
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ca.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_cs.js49
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_da.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_de.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_el.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_en.js.template18
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_es.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_et.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_eu.js43
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_fa.js19
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_fi.js28
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_fr.js16
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_gl.js43
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_he.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_hr.js22
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_hu.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_id.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_is.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_it.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ja.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ka.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ko.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_lt.js24
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_lv.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_mk.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ms.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_nl.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_no.js18
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_pl.js22
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_pt-BR.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_pt-PT.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ro.js15
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_rs.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_ru.js21
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_sk.js48
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_sv.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_th.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_tr.js17
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_uk.js23
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_vi.js18
-rw-r--r--apps/files_external/3rdparty/select2/select2_locale_zh-CN.js14
-rwxr-xr-xapps/files_external/3rdparty/select2/select2_locale_zh-TW.js14
-rw-r--r--apps/files_external/3rdparty/select2/select2x2.pngbin0 -> 845 bytes
-rw-r--r--apps/files_external/ajax/applicable.php26
-rw-r--r--apps/files_external/ajax/dropbox.php2
-rw-r--r--apps/files_external/ajax/google.php2
-rw-r--r--apps/files_external/appinfo/app.php14
-rw-r--r--apps/files_external/appinfo/routes.php3
-rw-r--r--apps/files_external/css/settings.css19
-rw-r--r--apps/files_external/js/settings.js236
-rw-r--r--apps/files_external/l10n/af_ZA.php3
-rw-r--r--apps/files_external/l10n/ar.php3
-rw-r--r--apps/files_external/l10n/ast.php10
-rw-r--r--apps/files_external/l10n/az.php4
-rw-r--r--apps/files_external/l10n/bg_BG.php12
-rw-r--r--apps/files_external/l10n/bn_BD.php6
-rw-r--r--apps/files_external/l10n/ca.php10
-rw-r--r--apps/files_external/l10n/cs_CZ.php13
-rw-r--r--apps/files_external/l10n/cy_GB.php2
-rw-r--r--apps/files_external/l10n/da.php10
-rw-r--r--apps/files_external/l10n/de.php10
-rw-r--r--apps/files_external/l10n/de_CH.php3
-rw-r--r--apps/files_external/l10n/de_DE.php10
-rw-r--r--apps/files_external/l10n/el.php11
-rw-r--r--apps/files_external/l10n/en_GB.php12
-rw-r--r--apps/files_external/l10n/eo.php8
-rw-r--r--apps/files_external/l10n/es.php12
-rw-r--r--apps/files_external/l10n/es_AR.php3
-rw-r--r--apps/files_external/l10n/es_CL.php3
-rw-r--r--apps/files_external/l10n/es_MX.php3
-rw-r--r--apps/files_external/l10n/et_EE.php12
-rw-r--r--apps/files_external/l10n/eu.php9
-rw-r--r--apps/files_external/l10n/fa.php3
-rw-r--r--apps/files_external/l10n/fi_FI.php12
-rw-r--r--apps/files_external/l10n/fr.php10
-rw-r--r--apps/files_external/l10n/gl.php10
-rw-r--r--apps/files_external/l10n/he.php3
-rw-r--r--apps/files_external/l10n/hi.php3
-rw-r--r--apps/files_external/l10n/hr.php2
-rw-r--r--apps/files_external/l10n/hu_HU.php3
-rw-r--r--apps/files_external/l10n/ia.php2
-rw-r--r--apps/files_external/l10n/id.php8
-rw-r--r--apps/files_external/l10n/is.php3
-rw-r--r--apps/files_external/l10n/it.php12
-rw-r--r--apps/files_external/l10n/ja.php10
-rw-r--r--apps/files_external/l10n/ka_GE.php3
-rw-r--r--apps/files_external/l10n/km.php3
-rw-r--r--apps/files_external/l10n/ko.php3
-rw-r--r--apps/files_external/l10n/ku_IQ.php3
-rw-r--r--apps/files_external/l10n/lb.php2
-rw-r--r--apps/files_external/l10n/lt_LT.php3
-rw-r--r--apps/files_external/l10n/lv.php3
-rw-r--r--apps/files_external/l10n/mk.php3
-rw-r--r--apps/files_external/l10n/ms_MY.php2
-rw-r--r--apps/files_external/l10n/my_MM.php3
-rw-r--r--apps/files_external/l10n/nb_NO.php10
-rw-r--r--apps/files_external/l10n/nl.php12
-rw-r--r--apps/files_external/l10n/nn_NO.php2
-rw-r--r--apps/files_external/l10n/oc.php2
-rw-r--r--apps/files_external/l10n/pa.php1
-rw-r--r--apps/files_external/l10n/pl.php10
-rw-r--r--apps/files_external/l10n/pt_BR.php12
-rw-r--r--apps/files_external/l10n/pt_PT.php10
-rw-r--r--apps/files_external/l10n/ro.php4
-rw-r--r--apps/files_external/l10n/ru.php10
-rw-r--r--apps/files_external/l10n/si_LK.php3
-rw-r--r--apps/files_external/l10n/sk_SK.php10
-rw-r--r--apps/files_external/l10n/sl.php12
-rw-r--r--apps/files_external/l10n/sq.php2
-rw-r--r--apps/files_external/l10n/sr.php2
-rw-r--r--apps/files_external/l10n/sr@latin.php2
-rw-r--r--apps/files_external/l10n/sv.php10
-rw-r--r--apps/files_external/l10n/ta_LK.php3
-rw-r--r--apps/files_external/l10n/te.php1
-rw-r--r--apps/files_external/l10n/th_TH.php3
-rw-r--r--apps/files_external/l10n/tr.php12
-rw-r--r--apps/files_external/l10n/ug.php2
-rw-r--r--apps/files_external/l10n/uk.php3
-rw-r--r--apps/files_external/l10n/ur_PK.php1
-rw-r--r--apps/files_external/l10n/vi.php3
-rw-r--r--apps/files_external/l10n/zh_CN.php10
-rw-r--r--apps/files_external/l10n/zh_HK.php2
-rw-r--r--apps/files_external/l10n/zh_TW.php8
-rwxr-xr-xapps/files_external/lib/config.php1
-rw-r--r--apps/files_external/lib/sftp.php3
-rw-r--r--apps/files_external/lib/smb_oc.php8
-rw-r--r--apps/files_external/settings.php8
-rw-r--r--apps/files_external/templates/settings.php27
-rw-r--r--apps/files_sharing/ajax/external.php2
-rw-r--r--apps/files_sharing/appinfo/app.php2
-rw-r--r--apps/files_sharing/l10n/ast.php1
-rw-r--r--apps/files_sharing/l10n/bn_BD.php5
-rw-r--r--apps/files_sharing/l10n/cs_CZ.php4
-rw-r--r--apps/files_sharing/l10n/et_EE.php1
-rw-r--r--apps/files_sharing/lib/helper.php6
-rw-r--r--apps/files_sharing/public.php6
-rw-r--r--apps/files_trashbin/ajax/delete.php2
-rw-r--r--apps/files_trashbin/ajax/undelete.php2
-rw-r--r--apps/files_trashbin/appinfo/app.php2
-rw-r--r--apps/files_trashbin/l10n/az.php1
-rw-r--r--apps/files_trashbin/l10n/bn_BD.php9
-rw-r--r--apps/files_trashbin/lib/trashbin.php2
-rw-r--r--apps/files_versions/ajax/rollbackVersion.php2
-rw-r--r--apps/files_versions/l10n/bn_BD.php7
-rw-r--r--apps/user_ldap/ajax/clearMappings.php2
-rw-r--r--apps/user_ldap/ajax/deleteConfiguration.php2
-rw-r--r--apps/user_ldap/ajax/testConfiguration.php2
-rw-r--r--apps/user_ldap/ajax/wizard.php22
-rw-r--r--apps/user_ldap/js/ldapFilter.js5
-rw-r--r--apps/user_ldap/js/settings.js18
-rw-r--r--apps/user_ldap/l10n/az.php1
-rw-r--r--apps/user_ldap/l10n/bn_BD.php5
-rw-r--r--apps/user_ldap/l10n/cs_CZ.php8
-rw-r--r--apps/user_ldap/l10n/hu_HU.php2
-rw-r--r--apps/user_ldap/lib/wizard.php112
-rw-r--r--apps/user_ldap/settings.php2
-rw-r--r--apps/user_ldap/tests/wizard.php241
-rw-r--r--apps/user_webdavauth/l10n/bn_BD.php1
201 files changed, 6159 insertions, 607 deletions
diff --git a/apps/files/ajax/delete.php b/apps/files/ajax/delete.php
index aed53d5db5a..323b70706ce 100644
--- a/apps/files/ajax/delete.php
+++ b/apps/files/ajax/delete.php
@@ -2,7 +2,7 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-\OC::$session->close();
+\OC::$server->getSession()->close();
// Get data
diff --git a/apps/files/ajax/download.php b/apps/files/ajax/download.php
index 4b4a7f8948d..b2e144c4b8f 100644
--- a/apps/files/ajax/download.php
+++ b/apps/files/ajax/download.php
@@ -23,7 +23,7 @@
// Check if we are a user
OCP\User::checkLoggedIn();
-\OC::$session->close();
+\OC::$server->getSession()->close();
$files = $_GET["files"];
$dir = $_GET["dir"];
diff --git a/apps/files/ajax/getstoragestats.php b/apps/files/ajax/getstoragestats.php
index dd8af39bada..4ab5b9a779c 100644
--- a/apps/files/ajax/getstoragestats.php
+++ b/apps/files/ajax/getstoragestats.php
@@ -7,7 +7,7 @@ if (isset($_GET['dir'])) {
}
OCP\JSON::checkLoggedIn();
-\OC::$session->close();
+\OC::$server->getSession()->close();
// send back json
OCP\JSON::success(array('data' => \OCA\Files\Helper::buildFileStorageStatistics($dir)));
diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php
index b4641343ed4..16e48a2c2af 100644
--- a/apps/files/ajax/list.php
+++ b/apps/files/ajax/list.php
@@ -1,8 +1,8 @@
<?php
OCP\JSON::checkLoggedIn();
-\OC::$session->close();
-$l = OC_L10N::get('files');
+\OC::$server->getSession()->close();
+$l = \OC::$server->getL10N('files');
// Load the files
$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
diff --git a/apps/files/ajax/mimeicon.php b/apps/files/ajax/mimeicon.php
index 6557ff941ac..fdbcc441a78 100644
--- a/apps/files/ajax/mimeicon.php
+++ b/apps/files/ajax/mimeicon.php
@@ -1,4 +1,4 @@
<?php
-\OC::$session->close();
+\OC::$server->getSession()->close();
print OC_Helper::mimetypeIcon($_GET['mime']);
diff --git a/apps/files/ajax/move.php b/apps/files/ajax/move.php
index 0a8dbc24a65..3a07554ad00 100644
--- a/apps/files/ajax/move.php
+++ b/apps/files/ajax/move.php
@@ -2,14 +2,14 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-\OC::$session->close();
+\OC::$server->getSession()->close();
// Get data
$dir = stripslashes($_POST["dir"]);
$file = stripslashes($_POST["file"]);
$target = stripslashes(rawurldecode($_POST["target"]));
-$l = OC_L10N::get('files');
+$l = \OC::$server->getL10N('files');
if(\OC\Files\Filesystem::file_exists($target . '/' . $file)) {
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not move %s - File with this name already exists", array($file)) )));
diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php
index 9cfe51a6218..606576760ec 100644
--- a/apps/files/ajax/newfile.php
+++ b/apps/files/ajax/newfile.php
@@ -7,7 +7,7 @@ if(!OC_User::isLoggedIn()) {
exit;
}
-\OC::$session->close();
+\OC::$server->getSession()->close();
// Get the params
$dir = isset( $_REQUEST['dir'] ) ? '/'.trim($_REQUEST['dir'], '/\\') : '';
@@ -46,7 +46,7 @@ function progress($notification_code, $severity, $message, $message_code, $bytes
}
}
-$l10n = \OC_L10n::get('files');
+$l10n = \OC::$server->getL10N('files');
$result = array(
'success' => false,
diff --git a/apps/files/ajax/newfolder.php b/apps/files/ajax/newfolder.php
index 89c241189d7..ea7a10c2ab9 100644
--- a/apps/files/ajax/newfolder.php
+++ b/apps/files/ajax/newfolder.php
@@ -5,13 +5,13 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-\OC::$session->close();
+\OC::$server->getSession()->close();
// Get the params
$dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : '';
$foldername = isset( $_POST['foldername'] ) ? stripslashes($_POST['foldername']) : '';
-$l10n = \OC_L10n::get('files');
+$l10n = \OC::$server->getL10N('files');
$result = array(
'success' => false,
diff --git a/apps/files/ajax/rename.php b/apps/files/ajax/rename.php
index fa3ddace63d..00c8a1e44db 100644
--- a/apps/files/ajax/rename.php
+++ b/apps/files/ajax/rename.php
@@ -23,11 +23,11 @@
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-\OC::$session->close();
+\OC::$server->getSession()->close();
$files = new \OCA\Files\App(
\OC\Files\Filesystem::getView(),
- \OC_L10n::get('files')
+ \OC::$server->getL10N('files')
);
$result = $files->rename(
$_GET["dir"],
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index d5d88483801..3ec7f9394b1 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -1,6 +1,6 @@
<?php
set_time_limit(0); //scanning can take ages
-\OC::$session->close();
+\OC::$server->getSession()->close();
$force = (isset($_GET['force']) and ($_GET['force'] === 'true'));
$dir = isset($_GET['dir']) ? $_GET['dir'] : '';
diff --git a/apps/files/ajax/upload.php b/apps/files/ajax/upload.php
index b737d5f8710..b960e02ced7 100644
--- a/apps/files/ajax/upload.php
+++ b/apps/files/ajax/upload.php
@@ -10,7 +10,7 @@ OCP\JSON::setContentTypeHeader('text/plain');
$allowedPermissions = OCP\PERMISSION_ALL;
$errorCode = null;
-$l = OC_L10N::get('files');
+$l = \OC::$server->getL10N('files');
if (empty($_POST['dirToken'])) {
// The standard case, files are uploaded through logged in users :)
OCP\JSON::checkLoggedIn();
@@ -68,7 +68,7 @@ if (empty($_POST['dirToken'])) {
OCP\JSON::callCheck();
if (!\OCP\App::isEnabled('files_encryption')) {
// encryption app need to create keys later, so can't close too early
- \OC::$session->close();
+ \OC::$server->getSession()->close();
}
diff --git a/apps/files/appinfo/app.php b/apps/files/appinfo/app.php
index 9af36c682fd..3567bc26def 100644
--- a/apps/files/appinfo/app.php
+++ b/apps/files/appinfo/app.php
@@ -1,6 +1,6 @@
<?php
-$l = OC_L10N::get('files');
+$l = \OC::$server->getL10N('files');
OCP\App::registerAdmin('files', 'admin');
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 3cbc25fc24b..fd11a80248d 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -703,7 +703,7 @@
"class": "modified",
"title": formatDate(mtime),
"style": 'color:rgb('+modifiedColor+','+modifiedColor+','+modifiedColor+')'
- }).text( relative_modified_date(mtime / 1000) ));
+ }).text(OC.Util.relativeModifiedDate(mtime)));
tr.find('.filesize').text(simpleSize);
tr.append(td);
return tr;
diff --git a/apps/files/l10n/bn_BD.php b/apps/files/l10n/bn_BD.php
index b2eec2a830c..7e7b8461720 100644
--- a/apps/files/l10n/bn_BD.php
+++ b/apps/files/l10n/bn_BD.php
@@ -15,6 +15,7 @@ $TRANSLATIONS = array(
"Failed to write to disk" => "ডিস্কে লিখতে ব্যর্থ",
"Invalid directory." => "ভুল ডিরেক্টরি",
"Files" => "ফাইল",
+"All files" => "সব ফাইল",
"Upload cancelled." => "আপলোড বাতিল করা হয়েছে।",
"File upload is in progress. Leaving the page now will cancel the upload." => "ফাইল আপলোড চলমান। এই পৃষ্ঠা পরিত্যাগ করলে আপলোড বাতিল করা হবে।",
"{new_name} already exists" => "{new_name} টি বিদ্যমান",
diff --git a/apps/files/l10n/et_EE.php b/apps/files/l10n/et_EE.php
index 91ea214445a..46246047ac9 100644
--- a/apps/files/l10n/et_EE.php
+++ b/apps/files/l10n/et_EE.php
@@ -68,6 +68,7 @@ $TRANSLATIONS = array(
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Vigane Krüpteerimisrakendi privaatvõti . Palun uuenda oma privaatse võtme parool oma personaasete seadete all taastamaks ligipääsu oma krüpteeritud failidele.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "Krüpteering on keelatud, kuid sinu failid on endiselt krüpteeritud. Palun vaata oma personaalseid seadeid oma failide dekrüpteerimiseks.",
"{dirs} and {files}" => "{dirs} ja {files}",
+"%s could not be renamed as it has been deleted" => "%s ei saa ümber nimetada, kuna see on kustutatud",
"%s could not be renamed" => "%s ümbernimetamine ebaõnnestus",
"Upload (max. %s)" => "Üleslaadimine (max. %s)",
"File handling" => "Failide käsitlemine",
diff --git a/apps/files/l10n/he.php b/apps/files/l10n/he.php
index 77dd4516199..5eae5e46f27 100644
--- a/apps/files/l10n/he.php
+++ b/apps/files/l10n/he.php
@@ -43,6 +43,7 @@ $TRANSLATIONS = array(
"WebDAV" => "WebDAV",
"New" => "חדש",
"Text file" => "קובץ טקסט",
+"New folder" => "תיקייה חדשה",
"Folder" => "תיקייה",
"From link" => "מקישור",
"Nothing in here. Upload something!" => "אין כאן שום דבר. אולי ברצונך להעלות משהו?",
diff --git a/apps/files/l10n/hu_HU.php b/apps/files/l10n/hu_HU.php
index b44cd02a8af..85c439ecab1 100644
--- a/apps/files/l10n/hu_HU.php
+++ b/apps/files/l10n/hu_HU.php
@@ -11,14 +11,14 @@ $TRANSLATIONS = array(
"The target folder has been moved or deleted." => "A célmappa törlődött, vagy áthelyezésre került.",
"The name %s is already used in the folder %s. Please choose a different name." => "A %s név már létezik a %s mappában. Kérem válasszon másik nevet!",
"Not a valid source" => "A kiinduló állomány érvénytelen",
-"Server is not allowed to open URLs, please check the server configuration" => "A kiszolgálón nincs engedélyezve URL-ek megnyitása, kérem ellenőrizze a beállításokat",
-"The file exceeds your quota by %s" => "A fájl meghaladja kvótádat %s-kal",
+"Server is not allowed to open URLs, please check the server configuration" => "A kiszolgálón nincs engedélyezve URL-ek megnyitása, kérem ellenőrizze a beállításokat!",
+"The file exceeds your quota by %s" => "A fájl ennyivel meghaladja a kvótáját: %s",
"Error while downloading %s to %s" => "Hiba történt miközben %s-t letöltöttük %s-be",
"Error when creating the file" => "Hiba történt az állomány létrehozásakor",
"Folder name cannot be empty." => "A mappa neve nem maradhat kitöltetlenül",
"Error when creating the folder" => "Hiba történt a mappa létrehozásakor",
"Unable to set upload directory." => "Nem található a mappa, ahova feltölteni szeretne.",
-"Invalid Token" => "Hibás mappacím",
+"Invalid Token" => "Hibás token",
"No file was uploaded. Unknown error" => "Nem történt feltöltés. Ismeretlen hiba",
"There is no error, the file uploaded with success" => "A fájlt sikerült feltölteni",
"The uploaded file exceeds the upload_max_filesize directive in php.ini: " => "A feltöltött fájl mérete meghaladja a php.ini állományban megadott upload_max_filesize paraméter értékét.",
@@ -31,13 +31,13 @@ $TRANSLATIONS = array(
"Upload failed. Could not find uploaded file" => "A feltöltés nem sikerült. Nem található a feltöltendő állomány.",
"Upload failed. Could not get file info." => "A feltöltés nem sikerült. Az állományt leíró információk nem érhetők el.",
"Invalid directory." => "Érvénytelen mappa.",
-"Files" => "Fájlok",
+"Files" => "Fájlkezelő",
"All files" => "Az összes állomány",
"Unable to upload {filename} as it is a directory or has 0 bytes" => "A(z) {filename} állomány nem tölthető fel, mert ez vagy egy mappa, vagy pedig 0 bájtból áll.",
"Total file size {size1} exceeds upload limit {size2}" => "A teljes fájlméret: {size1} meghaladja a feltöltési limitet: {size2}",
"Not enough free space, you are uploading {size1} but only {size2} is left" => "Nincs elég szabad hely. A feltöltés mérete {size1}, de csak ennyi hely van: {size2}.",
"Upload cancelled." => "A feltöltést megszakítottuk.",
-"Could not get result from server." => "A kiszolgálótól nem kapható meg az eredmény.",
+"Could not get result from server." => "A kiszolgálótól nem kapható meg a művelet eredménye.",
"File upload is in progress. Leaving the page now will cancel the upload." => "Fájlfeltöltés van folyamatban. Az oldal elhagyása megszakítja a feltöltést.",
"URL cannot be empty" => "Az URL-cím nem maradhat kitöltetlenül",
"{new_name} already exists" => "{new_name} már létezik",
@@ -79,7 +79,7 @@ $TRANSLATIONS = array(
"WebDAV" => "WebDAV",
"Use this address to <a href=\"%s\" target=\"_blank\">access your Files via WebDAV</a>" => "Ezt a címet használja, ha <a href=\"%s\" target=\"_blank\">WebDAV-on keresztül szeretné elérni a fájljait</a>",
"New" => "Új",
-"New text file" => "Új szöveges file",
+"New text file" => "Új szövegfájl",
"Text file" => "Szövegfájl",
"New folder" => "Új mappa",
"Folder" => "Mappa",
diff --git a/apps/files/l10n/nn_NO.php b/apps/files/l10n/nn_NO.php
index f610ee902d5..502c313aa06 100644
--- a/apps/files/l10n/nn_NO.php
+++ b/apps/files/l10n/nn_NO.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Unknown error" => "Ukjend feil",
"Could not move %s - File with this name already exists" => "Klarte ikkje flytta %s – det finst allereie ei fil med dette namnet",
"Could not move %s" => "Klarte ikkje flytta %s",
"File name cannot be empty." => "Filnamnet kan ikkje vera tomt.",
diff --git a/apps/files/l10n/pt_PT.php b/apps/files/l10n/pt_PT.php
index 1fcf85fc856..dfa599e10ac 100644
--- a/apps/files/l10n/pt_PT.php
+++ b/apps/files/l10n/pt_PT.php
@@ -12,6 +12,7 @@ $TRANSLATIONS = array(
"The name %s is already used in the folder %s. Please choose a different name." => "O nome %s já está em uso na pasta %s. Por favor escolha um nome diferente.",
"Not a valid source" => "Não é uma fonte válida",
"Server is not allowed to open URLs, please check the server configuration" => "O servidor não consegue abrir URLs, por favor verifique a configuração do servidor",
+"The file exceeds your quota by %s" => "O ficheiro excede a sua quota por %s",
"Error while downloading %s to %s" => "Erro ao transferir %s para %s",
"Error when creating the file" => "Erro ao criar o ficheiro",
"Folder name cannot be empty." => "O nome da pasta não pode estar vazio.",
@@ -68,6 +69,7 @@ $TRANSLATIONS = array(
"Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files." => "Chave privada inválida da Aplicação de Encriptação. Por favor atualize a sua senha de chave privada nas definições pessoais, para recuperar o acesso aos seus ficheiros encriptados.",
"Encryption was disabled but your files are still encrypted. Please go to your personal settings to decrypt your files." => "A encriptação foi desactivada mas os seus ficheiros continuam encriptados. Por favor consulte as suas definições pessoais para desencriptar os ficheiros.",
"{dirs} and {files}" => "{dirs} e {files}",
+"%s could not be renamed as it has been deleted" => "Não foi possível renomear %s devido a ter sido eliminado",
"%s could not be renamed" => "%s não pode ser renomeada",
"Upload (max. %s)" => "Enviar (max. %s)",
"File handling" => "Manuseamento do ficheiro",
diff --git a/apps/files/l10n/zh_TW.php b/apps/files/l10n/zh_TW.php
index 39ec148fba0..e269cca3168 100644
--- a/apps/files/l10n/zh_TW.php
+++ b/apps/files/l10n/zh_TW.php
@@ -12,6 +12,7 @@ $TRANSLATIONS = array(
"The name %s is already used in the folder %s. Please choose a different name." => "%s 已經被使用於資料夾 %s ,請換一個名字",
"Not a valid source" => "不是有效的來源",
"Server is not allowed to open URLs, please check the server configuration" => "伺服器上不允許開啓 URL ,請檢查伺服器設定",
+"The file exceeds your quota by %s" => "這個檔案大小超出配額 %s",
"Error while downloading %s to %s" => "下載 %s 到 %s 失敗",
"Error when creating the file" => "建立檔案失敗",
"Folder name cannot be empty." => "資料夾名稱不能留空",
diff --git a/apps/files_encryption/ajax/adminrecovery.php b/apps/files_encryption/ajax/adminrecovery.php
index 303ba0e16e1..070ca6f667e 100644
--- a/apps/files_encryption/ajax/adminrecovery.php
+++ b/apps/files_encryption/ajax/adminrecovery.php
@@ -13,7 +13,7 @@ use OCA\Encryption;
\OCP\JSON::checkAppEnabled('files_encryption');
\OCP\JSON::callCheck();
-$l = OC_L10N::get('files_encryption');
+$l = \OC::$server->getL10N('files_encryption');
$return = false;
// Enable recoveryAdmin
diff --git a/apps/files_encryption/ajax/changeRecoveryPassword.php b/apps/files_encryption/ajax/changeRecoveryPassword.php
index 99cc7b3cdde..71fbe333fe0 100644
--- a/apps/files_encryption/ajax/changeRecoveryPassword.php
+++ b/apps/files_encryption/ajax/changeRecoveryPassword.php
@@ -15,7 +15,7 @@ use OCA\Encryption;
\OCP\JSON::checkAppEnabled('files_encryption');
\OCP\JSON::callCheck();
-$l = OC_L10N::get('core');
+$l = \OC::$server->getL10N('core');
$return = false;
diff --git a/apps/files_encryption/ajax/updatePrivateKeyPassword.php b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
index a14c9fe5076..f88e9c64dfd 100644
--- a/apps/files_encryption/ajax/updatePrivateKeyPassword.php
+++ b/apps/files_encryption/ajax/updatePrivateKeyPassword.php
@@ -15,7 +15,7 @@ use OCA\Encryption;
\OCP\JSON::checkAppEnabled('files_encryption');
\OCP\JSON::callCheck();
-$l = OC_L10N::get('core');
+$l = \OC::$server->getL10N('core');
$return = false;
diff --git a/apps/files_encryption/files/error.php b/apps/files_encryption/files/error.php
index b436587dfaf..c33a5a531f5 100644
--- a/apps/files_encryption/files/error.php
+++ b/apps/files_encryption/files/error.php
@@ -4,7 +4,7 @@ if (!isset($_)) { //also provide standalone error page
require_once __DIR__ . '/../../../lib/base.php';
require_once __DIR__ . '/../lib/crypt.php';
- $l = OC_L10N::get('files_encryption');
+ $l = \OC::$server->getL10N('files_encryption');
if (isset($_GET['errorCode'])) {
$errorCode = $_GET['errorCode'];
diff --git a/apps/files_encryption/l10n/bn_BD.php b/apps/files_encryption/l10n/bn_BD.php
index 63e335bd2b9..43699906e4d 100644
--- a/apps/files_encryption/l10n/bn_BD.php
+++ b/apps/files_encryption/l10n/bn_BD.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
-"Encryption" => "সংকেতায়ন"
+"Encryption" => "সংকেতায়ন",
+"Change Password" => "কূটশব্দ পরিবর্তন করুন"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_encryption/l10n/da.php b/apps/files_encryption/l10n/da.php
index b455bf09bc4..dc2cf9e2475 100644
--- a/apps/files_encryption/l10n/da.php
+++ b/apps/files_encryption/l10n/da.php
@@ -30,6 +30,8 @@ $TRANSLATIONS = array(
"New Recovery key password" => "Ny Gendannelsesnøgle kodeord",
"Repeat New Recovery key password" => "Gentag dannelse af ny gendannaleses nøglekode",
"Change Password" => "Skift Kodeord",
+"Your private key password no longer matches your log-in password." => "Dit private nøglekodeord stemmer ikke længere overens med dit login-kodeord.",
+"Set your old private key password to your current log-in password:" => "Sæt dit gamle, private nøglekodeord til at være dit nuværende login-kodeord. ",
" If you don't remember your old password you can ask your administrator to recover your files." => "Hvis du ikke kan huske dit gamle kodeord kan du bede din administrator om at gendanne dine filer.",
"Old log-in password" => "Gammelt login kodeord",
"Current log-in password" => "Nuvrende login kodeord",
diff --git a/apps/files_encryption/l10n/et_EE.php b/apps/files_encryption/l10n/et_EE.php
index f6ef4d09956..7e298d8e663 100644
--- a/apps/files_encryption/l10n/et_EE.php
+++ b/apps/files_encryption/l10n/et_EE.php
@@ -30,6 +30,7 @@ $TRANSLATIONS = array(
"New Recovery key password" => "Uus taastevõtme parool",
"Repeat New Recovery key password" => "Korda uut taastevõtme parooli",
"Change Password" => "Muuda parooli",
+"Your private key password no longer matches your log-in password." => "Sinu provaatvõtme parool ei kattu enam sinu sisselogimise parooliga.",
" If you don't remember your old password you can ask your administrator to recover your files." => "Kui sa ei mäleta oma vana parooli, siis palu oma süsteemihalduril taastada ligipääs failidele.",
"Old log-in password" => "Vana sisselogimise parool",
"Current log-in password" => "Praegune sisselogimise parool",
diff --git a/apps/files_encryption/lib/session.php b/apps/files_encryption/lib/session.php
index ff8fbd24ecb..7bd4fd02421 100644
--- a/apps/files_encryption/lib/session.php
+++ b/apps/files_encryption/lib/session.php
@@ -117,7 +117,7 @@ class Session {
*/
public function setPrivateKey($privateKey) {
- \OC::$session->set('privateKey', $privateKey);
+ \OC::$server->getSession()->set('privateKey', $privateKey);
return true;
@@ -140,7 +140,7 @@ class Session {
*/
public function setInitialized($init) {
- \OC::$session->set('encryptionInitialized', $init);
+ \OC::$server->getSession()->set('encryptionInitialized', $init);
return true;
@@ -150,8 +150,8 @@ class Session {
* remove encryption keys and init status from session
*/
public function closeSession() {
- \OC::$session->remove('encryptionInitialized');
- \OC::$session->remove('privateKey');
+ \OC::$server->getSession()->remove('encryptionInitialized');
+ \OC::$server->getSession()->remove('privateKey');
}
@@ -162,8 +162,8 @@ class Session {
* @note this doesn not indicate of the init was successful, we just remeber the try!
*/
public function getInitialized() {
- if (!is_null(\OC::$session->get('encryptionInitialized'))) {
- return \OC::$session->get('encryptionInitialized');
+ if (!is_null(\OC::$server->getSession()->get('encryptionInitialized'))) {
+ return \OC::$server->getSession()->get('encryptionInitialized');
} else {
return self::NOT_INITIALIZED;
}
@@ -179,8 +179,8 @@ class Session {
if (\OCA\Encryption\Helper::isPublicAccess()) {
return $this->getPublicSharePrivateKey();
} else {
- if (!is_null(\OC::$session->get('privateKey'))) {
- return \OC::$session->get('privateKey');
+ if (!is_null(\OC::$server->getSession()->get('privateKey'))) {
+ return \OC::$server->getSession()->get('privateKey');
} else {
return false;
}
@@ -194,7 +194,7 @@ class Session {
*/
public function setPublicSharePrivateKey($privateKey) {
- \OC::$session->set('publicSharePrivateKey', $privateKey);
+ \OC::$server->getSession()->set('publicSharePrivateKey', $privateKey);
return true;
@@ -207,8 +207,8 @@ class Session {
*/
public function getPublicSharePrivateKey() {
- if (!is_null(\OC::$session->get('publicSharePrivateKey'))) {
- return \OC::$session->get('publicSharePrivateKey');
+ if (!is_null(\OC::$server->getSession()->get('publicSharePrivateKey'))) {
+ return \OC::$server->getSession()->get('publicSharePrivateKey');
} else {
return false;
}
diff --git a/apps/files_external/3rdparty/select2/LICENSE b/apps/files_external/3rdparty/select2/LICENSE
new file mode 100644
index 00000000000..0247cc76273
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/LICENSE
@@ -0,0 +1,18 @@
+Copyright 2014 Igor Vaynberg
+
+Version: @@ver@@ Timestamp: @@timestamp@@
+
+This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
+General Public License version 2 (the "GPL License"). You may choose either license to govern your
+use of this software only upon the condition that you accept all of the terms of either the Apache
+License or the GPL License.
+
+You may obtain a copy of the Apache License and the GPL License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+http://www.gnu.org/licenses/gpl-2.0.html
+
+Unless required by applicable law or agreed to in writing, software distributed under the Apache License
+or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied. See the Apache License and the GPL License for the specific language governing
+permissions and limitations under the Apache License and the GPL License.
diff --git a/apps/files_external/3rdparty/select2/README.md b/apps/files_external/3rdparty/select2/README.md
new file mode 100644
index 00000000000..406fe79dc95
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/README.md
@@ -0,0 +1,90 @@
+Select2
+=======
+
+Select2 is a jQuery-based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.
+
+To get started, checkout examples and documentation at http://ivaynberg.github.com/select2
+
+Use cases
+---------
+
+* Enhancing native selects with search.
+* Enhancing native selects with a better multi-select interface.
+* Loading data from JavaScript: easily load items via ajax and have them searchable.
+* Nesting optgroups: native selects only support one level of nested. Select2 does not have this restriction.
+* Tagging: ability to add new items on the fly.
+* Working with large, remote datasets: ability to partially load a dataset based on the search term.
+* Paging of large datasets: easy support for loading more pages when the results are scrolled to the end.
+* Templating: support for custom rendering of results and selections.
+
+Browser compatibility
+---------------------
+* IE 8+
+* Chrome 8+
+* Firefox 10+
+* Safari 3+
+* Opera 10.6+
+
+Usage
+-----
+You can source Select2 directly from a [CDN like JSDliver](http://www.jsdelivr.com/#!select2), [download it from this GitHub repo](https://github.com/ivaynberg/select2/tags), or use one of the integrations below.
+
+Integrations
+------------
+
+* [Wicket-Select2](https://github.com/ivaynberg/wicket-select2) (Java / [Apache Wicket](http://wicket.apache.org))
+* [select2-rails](https://github.com/argerim/select2-rails) (Ruby on Rails)
+* [AngularUI](http://angular-ui.github.com/#directives-select2) ([AngularJS](angularjs.org))
+* [Django](https://github.com/applegrew/django-select2)
+* [Symfony](https://github.com/19Gerhard85/sfSelect2WidgetsPlugin)
+* [Symfony2](https://github.com/avocode/FormExtensions)
+* [Bootstrap 2](https://github.com/t0m/select2-bootstrap-css) and [Bootstrap 3](https://github.com/t0m/select2-bootstrap-css/tree/bootstrap3) (CSS skins)
+* [Meteor](https://github.com/nate-strauser/meteor-select2) (modern reactive JavaScript framework; + [Bootstrap 3 skin](https://github.com/esperadomedia/meteor-select2-bootstrap3-css/))
+* [Yii 2.x](http://demos.krajee.com/widgets#select2)
+* [Yii 1.x](https://github.com/tonybolzan/yii-select2)
+
+Internationalization (i18n)
+---------------------------
+
+Select2 supports multiple languages by simply including the right
+language JS file (`select2_locale_it.js`, `select2_locale_nl.js`, etc.).
+
+Missing a language? Just copy `select2_locale_en.js.template`, translate
+it, and make a pull request back to Select2 here on GitHub.
+
+Bug tracker
+-----------
+
+Have a bug? Please create an issue here on GitHub!
+
+https://github.com/ivaynberg/select2/issues
+
+Mailing list
+------------
+
+Have a question? Ask on our mailing list!
+
+select2@googlegroups.com
+
+https://groups.google.com/d/forum/select2
+
+
+Copyright and license
+---------------------
+
+Copyright 2012 Igor Vaynberg
+
+This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
+General Public License version 2 (the "GPL License"). You may choose either license to govern your
+use of this software only upon the condition that you accept all of the terms of either the Apache
+License or the GPL License.
+
+You may obtain a copy of the Apache License and the GPL License in the LICENSE file, or at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+http://www.gnu.org/licenses/gpl-2.0.html
+
+Unless required by applicable law or agreed to in writing, software distributed under the Apache License
+or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied. See the Apache License and the GPL License for the specific language governing
+permissions and limitations under the Apache License and the GPL License.
diff --git a/apps/files_external/3rdparty/select2/bower.json b/apps/files_external/3rdparty/select2/bower.json
new file mode 100644
index 00000000000..80e8596e806
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/bower.json
@@ -0,0 +1,8 @@
+{
+ "name": "select2",
+ "version": "3.4.8",
+ "main": ["select2.js", "select2.css", "select2.png", "select2x2.png", "select2-spinner.gif"],
+ "dependencies": {
+ "jquery": ">= 1.7.1"
+ }
+}
diff --git a/apps/files_external/3rdparty/select2/component.json b/apps/files_external/3rdparty/select2/component.json
new file mode 100644
index 00000000000..ad7abf9d9fa
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/component.json
@@ -0,0 +1,66 @@
+{
+ "name": "select2",
+ "repo": "ivaynberg/select2",
+ "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
+ "version": "3.4.8",
+ "demo": "http://ivaynberg.github.io/select2/",
+ "keywords": [
+ "jquery"
+ ],
+ "main": "select2.js",
+ "styles": [
+ "select2.css",
+ "select2-bootstrap.css"
+ ],
+ "scripts": [
+ "select2.js",
+ "select2_locale_ar.js",
+ "select2_locale_bg.js",
+ "select2_locale_ca.js",
+ "select2_locale_cs.js",
+ "select2_locale_da.js",
+ "select2_locale_de.js",
+ "select2_locale_el.js",
+ "select2_locale_es.js",
+ "select2_locale_et.js",
+ "select2_locale_eu.js",
+ "select2_locale_fa.js",
+ "select2_locale_fi.js",
+ "select2_locale_fr.js",
+ "select2_locale_gl.js",
+ "select2_locale_he.js",
+ "select2_locale_hr.js",
+ "select2_locale_hu.js",
+ "select2_locale_id.js",
+ "select2_locale_is.js",
+ "select2_locale_it.js",
+ "select2_locale_ja.js",
+ "select2_locale_ka.js",
+ "select2_locale_ko.js",
+ "select2_locale_lt.js",
+ "select2_locale_lv.js",
+ "select2_locale_mk.js",
+ "select2_locale_ms.js",
+ "select2_locale_nl.js",
+ "select2_locale_no.js",
+ "select2_locale_pl.js",
+ "select2_locale_pt-BR.js",
+ "select2_locale_pt-PT.js",
+ "select2_locale_ro.js",
+ "select2_locale_ru.js",
+ "select2_locale_sk.js",
+ "select2_locale_sv.js",
+ "select2_locale_th.js",
+ "select2_locale_tr.js",
+ "select2_locale_uk.js",
+ "select2_locale_vi.js",
+ "select2_locale_zh-CN.js",
+ "select2_locale_zh-TW.js"
+ ],
+ "images": [
+ "select2-spinner.gif",
+ "select2.png",
+ "select2x2.png"
+ ],
+ "license": "MIT"
+}
diff --git a/apps/files_external/3rdparty/select2/composer.json b/apps/files_external/3rdparty/select2/composer.json
new file mode 100644
index 00000000000..c50fadba855
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/composer.json
@@ -0,0 +1,29 @@
+{
+ "name":
+ "ivaynberg/select2",
+ "description": "Select2 is a jQuery based replacement for select boxes.",
+ "version": "3.4.8",
+ "type": "component",
+ "homepage": "http://ivaynberg.github.io/select2/",
+ "license": "Apache-2.0",
+ "require": {
+ "robloach/component-installer": "*",
+ "components/jquery": ">=1.7.1"
+ },
+ "extra": {
+ "component": {
+ "scripts": [
+ "select2.js"
+ ],
+ "files": [
+ "select2.js",
+ "select2_locale_*.js",
+ "select2.css",
+ "select2-bootstrap.css",
+ "select2-spinner.gif",
+ "select2.png",
+ "select2x2.png"
+ ]
+ }
+ }
+}
diff --git a/apps/files_external/3rdparty/select2/package.json b/apps/files_external/3rdparty/select2/package.json
new file mode 100644
index 00000000000..75ad84acaf8
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/package.json
@@ -0,0 +1,20 @@
+{
+ "name" : "Select2",
+ "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
+ "homepage": "http://ivaynberg.github.io/select2",
+ "author": "Igor Vaynberg",
+ "repository": {"type": "git", "url": "git://github.com/ivaynberg/select2.git"},
+ "main": "select2.js",
+ "version": "3.4.8",
+ "jspm": {
+ "main": "select2",
+ "files": ["select2.js", "select2.png", "select2.css", "select2-spinner.gif"],
+ "shim": {
+ "select2": {
+ "imports": ["jquery", "./select2.css!"],
+ "exports": "$"
+ }
+ },
+ "buildConfig": { "uglify": true }
+ }
+}
diff --git a/apps/files_external/3rdparty/select2/release.sh b/apps/files_external/3rdparty/select2/release.sh
new file mode 100755
index 00000000000..0d2e279ead4
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/release.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+set -e
+
+echo -n "Enter the version for this release: "
+
+read ver
+
+if [ ! $ver ]; then
+ echo "Invalid version."
+ exit
+fi
+
+name="select2"
+js="$name.js"
+mini="$name.min.js"
+css="$name.css"
+release="$name-$ver"
+tag="$ver"
+branch="build-$ver"
+curbranch=`git branch | grep "*" | sed "s/* //"`
+timestamp=$(date)
+tokens="s/@@ver@@/$ver/g;s/\@@timestamp@@/$timestamp/g"
+remote="github"
+
+echo "Pulling from origin"
+
+git pull
+
+echo "Updating Version Identifiers"
+
+sed -E -e "s/\"version\": \"([0-9\.]+)\",/\"version\": \"$ver\",/g" -i -- bower.json select2.jquery.json component.json composer.json package.json
+
+git add bower.json
+git add select2.jquery.json
+git add component.json
+git add composer.json
+git add package.json
+
+git commit -m "modified version identifiers in descriptors for release $ver"
+git push
+
+git branch "$branch"
+git checkout "$branch"
+
+echo "Tokenizing..."
+
+find . -name "$js" | xargs -I{} sed -e "$tokens" -i -- {}
+find . -name "$css" | xargs -I{} sed -e "$tokens" -i -- {}
+
+sed -e "s/latest/$ver/g" -i -- bower.json
+
+git add "$js"
+git add "$css"
+
+echo "Minifying..."
+
+echo "/*" > "$mini"
+cat LICENSE | sed "$tokens" >> "$mini"
+echo "*/" >> "$mini"
+
+curl -s \
+ --data-urlencode "js_code@$js" \
+ http://marijnhaverbeke.nl/uglifyjs \
+ >> "$mini"
+
+git add "$mini"
+
+git commit -m "release $ver"
+
+echo "Tagging..."
+git tag -a "$tag" -m "tagged version $ver"
+git push "$remote" --tags
+
+echo "Cleaning Up..."
+
+git checkout "$curbranch"
+git branch -D "$branch"
+
+echo "Done"
diff --git a/apps/files_external/3rdparty/select2/select2-bootstrap.css b/apps/files_external/3rdparty/select2/select2-bootstrap.css
new file mode 100644
index 00000000000..3b83f0a2297
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2-bootstrap.css
@@ -0,0 +1,87 @@
+.form-control .select2-choice {
+ border: 0;
+ border-radius: 2px;
+}
+
+.form-control .select2-choice .select2-arrow {
+ border-radius: 0 2px 2px 0;
+}
+
+.form-control.select2-container {
+ height: auto !important;
+ padding: 0;
+}
+
+.form-control.select2-container.select2-dropdown-open {
+ border-color: #5897FB;
+ border-radius: 3px 3px 0 0;
+}
+
+.form-control .select2-container.select2-dropdown-open .select2-choices {
+ border-radius: 3px 3px 0 0;
+}
+
+.form-control.select2-container .select2-choices {
+ border: 0 !important;
+ border-radius: 3px;
+}
+
+.control-group.warning .select2-container .select2-choice,
+.control-group.warning .select2-container .select2-choices,
+.control-group.warning .select2-container-active .select2-choice,
+.control-group.warning .select2-container-active .select2-choices,
+.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choice,
+.control-group.warning .select2-dropdown-open.select2-drop-above .select2-choices,
+.control-group.warning .select2-container-multi.select2-container-active .select2-choices {
+ border: 1px solid #C09853 !important;
+}
+
+.control-group.warning .select2-container .select2-choice div {
+ border-left: 1px solid #C09853 !important;
+ background: #FCF8E3 !important;
+}
+
+.control-group.error .select2-container .select2-choice,
+.control-group.error .select2-container .select2-choices,
+.control-group.error .select2-container-active .select2-choice,
+.control-group.error .select2-container-active .select2-choices,
+.control-group.error .select2-dropdown-open.select2-drop-above .select2-choice,
+.control-group.error .select2-dropdown-open.select2-drop-above .select2-choices,
+.control-group.error .select2-container-multi.select2-container-active .select2-choices {
+ border: 1px solid #B94A48 !important;
+}
+
+.control-group.error .select2-container .select2-choice div {
+ border-left: 1px solid #B94A48 !important;
+ background: #F2DEDE !important;
+}
+
+.control-group.info .select2-container .select2-choice,
+.control-group.info .select2-container .select2-choices,
+.control-group.info .select2-container-active .select2-choice,
+.control-group.info .select2-container-active .select2-choices,
+.control-group.info .select2-dropdown-open.select2-drop-above .select2-choice,
+.control-group.info .select2-dropdown-open.select2-drop-above .select2-choices,
+.control-group.info .select2-container-multi.select2-container-active .select2-choices {
+ border: 1px solid #3A87AD !important;
+}
+
+.control-group.info .select2-container .select2-choice div {
+ border-left: 1px solid #3A87AD !important;
+ background: #D9EDF7 !important;
+}
+
+.control-group.success .select2-container .select2-choice,
+.control-group.success .select2-container .select2-choices,
+.control-group.success .select2-container-active .select2-choice,
+.control-group.success .select2-container-active .select2-choices,
+.control-group.success .select2-dropdown-open.select2-drop-above .select2-choice,
+.control-group.success .select2-dropdown-open.select2-drop-above .select2-choices,
+.control-group.success .select2-container-multi.select2-container-active .select2-choices {
+ border: 1px solid #468847 !important;
+}
+
+.control-group.success .select2-container .select2-choice div {
+ border-left: 1px solid #468847 !important;
+ background: #DFF0D8 !important;
+}
diff --git a/apps/files_external/3rdparty/select2/select2-spinner.gif b/apps/files_external/3rdparty/select2/select2-spinner.gif
new file mode 100644
index 00000000000..5b33f7e54f4
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2-spinner.gif
Binary files differ
diff --git a/apps/files_external/3rdparty/select2/select2.css b/apps/files_external/3rdparty/select2/select2.css
new file mode 100644
index 00000000000..1eb4d229f6d
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2.css
@@ -0,0 +1,646 @@
+/*
+Version: 3.4.8 Timestamp: Thu May 1 09:50:32 EDT 2014
+*/
+.select2-container {
+ margin: 0;
+ position: relative;
+ display: inline-block;
+ /* inline-block for ie7 */
+ zoom: 1;
+ *display: inline;
+ vertical-align: middle;
+}
+
+.select2-container,
+.select2-drop,
+.select2-search,
+.select2-search input {
+ /*
+ Force border-box so that % widths fit the parent
+ container without overlap because of margin/padding.
+ More Info : http://www.quirksmode.org/css/box.html
+ */
+ -webkit-box-sizing: border-box; /* webkit */
+ -moz-box-sizing: border-box; /* firefox */
+ box-sizing: border-box; /* css3 */
+}
+
+.select2-container .select2-choice {
+ display: block;
+ height: 26px;
+ padding: 0 0 0 8px;
+ overflow: hidden;
+ position: relative;
+
+ border: 1px solid #aaa;
+ white-space: nowrap;
+ line-height: 26px;
+ color: #444;
+ text-decoration: none;
+
+ border-radius: 4px;
+
+ background-clip: padding-box;
+
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.5, #fff));
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 50%);
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 50%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#ffffff', endColorstr = '#eeeeee', GradientType = 0);
+ background-image: linear-gradient(to top, #eee 0%, #fff 50%);
+}
+
+.select2-container.select2-drop-above .select2-choice {
+ border-bottom-color: #aaa;
+
+ border-radius: 0 0 4px 4px;
+
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eee), color-stop(0.9, #fff));
+ background-image: -webkit-linear-gradient(center bottom, #eee 0%, #fff 90%);
+ background-image: -moz-linear-gradient(center bottom, #eee 0%, #fff 90%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
+ background-image: linear-gradient(to bottom, #eee 0%, #fff 90%);
+}
+
+.select2-container.select2-allowclear .select2-choice .select2-chosen {
+ margin-right: 42px;
+}
+
+.select2-container .select2-choice > .select2-chosen {
+ margin-right: 26px;
+ display: block;
+ overflow: hidden;
+
+ white-space: nowrap;
+
+ text-overflow: ellipsis;
+ float: none;
+ width: auto;
+}
+
+.select2-container .select2-choice abbr {
+ display: none;
+ width: 12px;
+ height: 12px;
+ position: absolute;
+ right: 24px;
+ top: 8px;
+
+ font-size: 1px;
+ text-decoration: none;
+
+ border: 0;
+ background: url('select2.png') right top no-repeat;
+ cursor: pointer;
+ outline: 0;
+}
+
+.select2-container.select2-allowclear .select2-choice abbr {
+ display: inline-block;
+}
+
+.select2-container .select2-choice abbr:hover {
+ background-position: right -11px;
+ cursor: pointer;
+}
+
+.select2-drop-mask {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ position: fixed;
+ left: 0;
+ top: 0;
+ min-height: 100%;
+ min-width: 100%;
+ height: auto;
+ width: auto;
+ opacity: 0;
+ z-index: 9998;
+ /* styles required for IE to work */
+ background-color: #fff;
+ filter: alpha(opacity=0);
+}
+
+.select2-drop {
+ width: 100%;
+ margin-top: -1px;
+ position: absolute;
+ z-index: 9999;
+ top: 100%;
+
+ background: #fff;
+ color: #000;
+ border: 1px solid #aaa;
+ border-top: 0;
+
+ border-radius: 0 0 4px 4px;
+
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
+}
+
+.select2-drop.select2-drop-above {
+ margin-top: 1px;
+ border-top: 1px solid #aaa;
+ border-bottom: 0;
+
+ border-radius: 4px 4px 0 0;
+
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
+}
+
+.select2-drop-active {
+ border: 1px solid #5897fb;
+ border-top: none;
+}
+
+.select2-drop.select2-drop-above.select2-drop-active {
+ border-top: 1px solid #5897fb;
+}
+
+.select2-drop-auto-width {
+ border-top: 1px solid #aaa;
+ width: auto;
+}
+
+.select2-drop-auto-width .select2-search {
+ padding-top: 4px;
+}
+
+.select2-container .select2-choice .select2-arrow {
+ display: inline-block;
+ width: 18px;
+ height: 100%;
+ position: absolute;
+ right: 0;
+ top: 0;
+
+ border-left: 1px solid #aaa;
+ border-radius: 0 4px 4px 0;
+
+ background-clip: padding-box;
+
+ background: #ccc;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+ background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr = '#eeeeee', endColorstr = '#cccccc', GradientType = 0);
+ background-image: linear-gradient(to top, #ccc 0%, #eee 60%);
+}
+
+.select2-container .select2-choice .select2-arrow b {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: url('select2.png') no-repeat 0 1px;
+}
+
+.select2-search {
+ display: inline-block;
+ width: 100%;
+ min-height: 26px;
+ margin: 0;
+ padding-left: 4px;
+ padding-right: 4px;
+
+ position: relative;
+ z-index: 10000;
+
+ white-space: nowrap;
+}
+
+.select2-search input {
+ width: 100%;
+ height: auto !important;
+ min-height: 26px;
+ padding: 4px 20px 4px 5px;
+ margin: 0;
+
+ outline: 0;
+ font-family: sans-serif;
+ font-size: 1em;
+
+ border: 1px solid #aaa;
+ border-radius: 0;
+
+ -webkit-box-shadow: none;
+ box-shadow: none;
+
+ background: #fff url('select2.png') no-repeat 100% -22px;
+ background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+ background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url('select2.png') no-repeat 100% -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
+}
+
+.select2-drop.select2-drop-above .select2-search input {
+ margin-top: 4px;
+}
+
+.select2-search input.select2-active {
+ background: #fff url('select2-spinner.gif') no-repeat 100%;
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
+ background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
+ background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
+}
+
+.select2-container-active .select2-choice,
+.select2-container-active .select2-choices {
+ border: 1px solid #5897fb;
+ outline: none;
+
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+}
+
+.select2-dropdown-open .select2-choice {
+ border-bottom-color: transparent;
+ -webkit-box-shadow: 0 1px 0 #fff inset;
+ box-shadow: 0 1px 0 #fff inset;
+
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+
+ background-color: #eee;
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #fff), color-stop(0.5, #eee));
+ background-image: -webkit-linear-gradient(center bottom, #fff 0%, #eee 50%);
+ background-image: -moz-linear-gradient(center bottom, #fff 0%, #eee 50%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+ background-image: linear-gradient(to top, #fff 0%, #eee 50%);
+}
+
+.select2-dropdown-open.select2-drop-above .select2-choice,
+.select2-dropdown-open.select2-drop-above .select2-choices {
+ border: 1px solid #5897fb;
+ border-top-color: transparent;
+
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), color-stop(0.5, #eee));
+ background-image: -webkit-linear-gradient(center top, #fff 0%, #eee 50%);
+ background-image: -moz-linear-gradient(center top, #fff 0%, #eee 50%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
+ background-image: linear-gradient(to bottom, #fff 0%, #eee 50%);
+}
+
+.select2-dropdown-open .select2-choice .select2-arrow {
+ background: transparent;
+ border-left: none;
+ filter: none;
+}
+.select2-dropdown-open .select2-choice .select2-arrow b {
+ background-position: -18px 1px;
+}
+
+.select2-hidden-accessible {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+
+/* results */
+.select2-results {
+ max-height: 200px;
+ padding: 0 0 0 4px;
+ margin: 4px 4px 4px 0;
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: auto;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.select2-results ul.select2-result-sub {
+ margin: 0;
+ padding-left: 0;
+}
+
+.select2-results li {
+ list-style: none;
+ display: list-item;
+ background-image: none;
+}
+
+.select2-results li.select2-result-with-children > .select2-result-label {
+ font-weight: bold;
+}
+
+.select2-results .select2-result-label {
+ padding: 3px 7px 4px;
+ margin: 0;
+ cursor: pointer;
+
+ min-height: 1em;
+
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+
+.select2-results-dept-1 .select2-result-label { padding-left: 20px }
+.select2-results-dept-2 .select2-result-label { padding-left: 40px }
+.select2-results-dept-3 .select2-result-label { padding-left: 60px }
+.select2-results-dept-4 .select2-result-label { padding-left: 80px }
+.select2-results-dept-5 .select2-result-label { padding-left: 100px }
+.select2-results-dept-6 .select2-result-label { padding-left: 110px }
+.select2-results-dept-7 .select2-result-label { padding-left: 120px }
+
+.select2-results .select2-highlighted {
+ background: #3875d7;
+ color: #fff;
+}
+
+.select2-results li em {
+ background: #feffde;
+ font-style: normal;
+}
+
+.select2-results .select2-highlighted em {
+ background: transparent;
+}
+
+.select2-results .select2-highlighted ul {
+ background: #fff;
+ color: #000;
+}
+
+
+.select2-results .select2-no-results,
+.select2-results .select2-searching,
+.select2-results .select2-selection-limit {
+ background: #f4f4f4;
+ display: list-item;
+ padding-left: 5px;
+}
+
+/*
+disabled look for disabled choices in the results dropdown
+*/
+.select2-results .select2-disabled.select2-highlighted {
+ color: #666;
+ background: #f4f4f4;
+ display: list-item;
+ cursor: default;
+}
+.select2-results .select2-disabled {
+ background: #f4f4f4;
+ display: list-item;
+ cursor: default;
+}
+
+.select2-results .select2-selected {
+ display: none;
+}
+
+.select2-more-results.select2-active {
+ background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
+}
+
+.select2-more-results {
+ background: #f4f4f4;
+ display: list-item;
+}
+
+/* disabled styles */
+
+.select2-container.select2-container-disabled .select2-choice {
+ background-color: #f4f4f4;
+ background-image: none;
+ border: 1px solid #ddd;
+ cursor: default;
+}
+
+.select2-container.select2-container-disabled .select2-choice .select2-arrow {
+ background-color: #f4f4f4;
+ background-image: none;
+ border-left: 0;
+}
+
+.select2-container.select2-container-disabled .select2-choice abbr {
+ display: none;
+}
+
+
+/* multiselect */
+
+.select2-container-multi .select2-choices {
+ height: auto !important;
+ height: 1%;
+ margin: 0;
+ padding: 0;
+ position: relative;
+
+ border: 1px solid #aaa;
+ cursor: text;
+ overflow: hidden;
+
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eee), color-stop(15%, #fff));
+ background-image: -webkit-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: -moz-linear-gradient(top, #eee 1%, #fff 15%);
+ background-image: linear-gradient(to bottom, #eee 1%, #fff 15%);
+}
+
+.select2-locked {
+ padding: 3px 5px 3px 5px !important;
+}
+
+.select2-container-multi .select2-choices {
+ min-height: 26px;
+}
+
+.select2-container-multi.select2-container-active .select2-choices {
+ border: 1px solid #5897fb;
+ outline: none;
+
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
+}
+.select2-container-multi .select2-choices li {
+ float: left;
+ list-style: none;
+}
+html[dir="rtl"] .select2-container-multi .select2-choices li
+{
+ float: right;
+}
+.select2-container-multi .select2-choices .select2-search-field {
+ margin: 0;
+ padding: 0;
+ white-space: nowrap;
+}
+
+.select2-container-multi .select2-choices .select2-search-field input {
+ padding: 5px;
+ margin: 1px 0;
+
+ font-family: sans-serif;
+ font-size: 100%;
+ color: #666;
+ outline: 0;
+ border: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ background: transparent !important;
+}
+
+.select2-container-multi .select2-choices .select2-search-field input.select2-active {
+ background: #fff url('select2-spinner.gif') no-repeat 100% !important;
+}
+
+.select2-default {
+ color: #999 !important;
+}
+
+.select2-container-multi .select2-choices .select2-search-choice {
+ padding: 3px 5px 3px 18px;
+ margin: 3px 0 3px 5px;
+ position: relative;
+
+ line-height: 13px;
+ color: #333;
+ cursor: default;
+ border: 1px solid #aaaaaa;
+
+ border-radius: 3px;
+
+ -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+ box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+
+ background-clip: padding-box;
+
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ background-color: #e4e4e4;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+ background-image: linear-gradient(to top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
+}
+html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice
+{
+ margin-left: 0;
+ margin-right: 5px;
+}
+.select2-container-multi .select2-choices .select2-search-choice .select2-chosen {
+ cursor: default;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus {
+ background: #d4d4d4;
+}
+
+.select2-search-choice-close {
+ display: block;
+ width: 12px;
+ height: 13px;
+ position: absolute;
+ right: 3px;
+ top: 4px;
+
+ font-size: 1px;
+ outline: none;
+ background: url('select2.png') right top no-repeat;
+}
+html[dir="rtl"] .select2-search-choice-close {
+ right: auto;
+ left: 3px;
+}
+
+.select2-container-multi .select2-search-choice-close {
+ left: 3px;
+}
+
+.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
+ background-position: right -11px;
+}
+.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
+ background-position: right -11px;
+}
+
+/* disabled styles */
+.select2-container-multi.select2-container-disabled .select2-choices {
+ background-color: #f4f4f4;
+ background-image: none;
+ border: 1px solid #ddd;
+ cursor: default;
+}
+
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
+ padding: 3px 5px 3px 5px;
+ border: 1px solid #ddd;
+ background-image: none;
+ background-color: #f4f4f4;
+}
+
+.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close { display: none;
+ background: none;
+}
+/* end multiselect */
+
+
+.select2-result-selectable .select2-match,
+.select2-result-unselectable .select2-match {
+ text-decoration: underline;
+}
+
+.select2-offscreen, .select2-offscreen:focus {
+ clip: rect(0 0 0 0) !important;
+ width: 1px !important;
+ height: 1px !important;
+ border: 0 !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow: hidden !important;
+ position: absolute !important;
+ outline: 0 !important;
+ left: 0px !important;
+ top: 0px !important;
+}
+
+.select2-display-none {
+ display: none;
+}
+
+.select2-measure-scrollbar {
+ position: absolute;
+ top: -10000px;
+ left: -10000px;
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+}
+
+/* Retina-ize icons */
+
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 2dppx) {
+ .select2-search input,
+ .select2-search-choice-close,
+ .select2-container .select2-choice abbr,
+ .select2-container .select2-choice .select2-arrow b {
+ background-image: url('select2x2.png') !important;
+ background-repeat: no-repeat !important;
+ background-size: 60px 40px !important;
+ }
+
+ .select2-search input {
+ background-position: 100% -21px !important;
+ }
+}
diff --git a/apps/files_external/3rdparty/select2/select2.jquery.json b/apps/files_external/3rdparty/select2/select2.jquery.json
new file mode 100644
index 00000000000..e9119279f11
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2.jquery.json
@@ -0,0 +1,36 @@
+{
+ "name": "select2",
+ "title": "Select2",
+ "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.",
+ "keywords": [
+ "select",
+ "autocomplete",
+ "typeahead",
+ "dropdown",
+ "multiselect",
+ "tag",
+ "tagging"
+ ],
+ "version": "3.4.8",
+ "author": {
+ "name": "Igor Vaynberg",
+ "url": "https://github.com/ivaynberg"
+ },
+ "licenses": [
+ {
+ "type": "Apache",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0"
+ },
+ {
+ "type": "GPL v2",
+ "url": "http://www.gnu.org/licenses/gpl-2.0.html"
+ }
+ ],
+ "bugs": "https://github.com/ivaynberg/select2/issues",
+ "homepage": "http://ivaynberg.github.com/select2",
+ "docs": "http://ivaynberg.github.com/select2/",
+ "download": "https://github.com/ivaynberg/select2/tags",
+ "dependencies": {
+ "jquery": ">=1.7.1"
+ }
+}
diff --git a/apps/files_external/3rdparty/select2/select2.js b/apps/files_external/3rdparty/select2/select2.js
new file mode 100644
index 00000000000..2969da5d1f7
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2.js
@@ -0,0 +1,3448 @@
+/*
+Copyright 2012 Igor Vaynberg
+
+Version: 3.4.8 Timestamp: Thu May 1 09:50:32 EDT 2014
+
+This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
+General Public License version 2 (the "GPL License"). You may choose either license to govern your
+use of this software only upon the condition that you accept all of the terms of either the Apache
+License or the GPL License.
+
+You may obtain a copy of the Apache License and the GPL License at:
+
+ http://www.apache.org/licenses/LICENSE-2.0
+ http://www.gnu.org/licenses/gpl-2.0.html
+
+Unless required by applicable law or agreed to in writing, software distributed under the
+Apache License or the GPL License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
+the specific language governing permissions and limitations under the Apache License and the GPL License.
+*/
+(function ($) {
+ if(typeof $.fn.each2 == "undefined") {
+ $.extend($.fn, {
+ /*
+ * 4-10 times faster .each replacement
+ * use it carefully, as it overrides jQuery context of element on each iteration
+ */
+ each2 : function (c) {
+ var j = $([0]), i = -1, l = this.length;
+ while (
+ ++i < l
+ && (j.context = j[0] = this[i])
+ && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
+ );
+ return this;
+ }
+ });
+ }
+})(jQuery);
+
+(function ($, undefined) {
+ "use strict";
+ /*global document, window, jQuery, console */
+
+ if (window.Select2 !== undefined) {
+ return;
+ }
+
+ var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
+ lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,
+
+ KEY = {
+ TAB: 9,
+ ENTER: 13,
+ ESC: 27,
+ SPACE: 32,
+ LEFT: 37,
+ UP: 38,
+ RIGHT: 39,
+ DOWN: 40,
+ SHIFT: 16,
+ CTRL: 17,
+ ALT: 18,
+ PAGE_UP: 33,
+ PAGE_DOWN: 34,
+ HOME: 36,
+ END: 35,
+ BACKSPACE: 8,
+ DELETE: 46,
+ isArrow: function (k) {
+ k = k.which ? k.which : k;
+ switch (k) {
+ case KEY.LEFT:
+ case KEY.RIGHT:
+ case KEY.UP:
+ case KEY.DOWN:
+ return true;
+ }
+ return false;
+ },
+ isControl: function (e) {
+ var k = e.which;
+ switch (k) {
+ case KEY.SHIFT:
+ case KEY.CTRL:
+ case KEY.ALT:
+ return true;
+ }
+
+ if (e.metaKey) return true;
+
+ return false;
+ },
+ isFunctionKey: function (k) {
+ k = k.which ? k.which : k;
+ return k >= 112 && k <= 123;
+ }
+ },
+ MEASURE_SCROLLBAR_TEMPLATE = "<div class='select2-measure-scrollbar'></div>",
+
+ DIACRITICS = {"\u24B6":"A","\uFF21":"A","\u00C0":"A","\u00C1":"A","\u00C2":"A","\u1EA6":"A","\u1EA4":"A","\u1EAA":"A","\u1EA8":"A","\u00C3":"A","\u0100":"A","\u0102":"A","\u1EB0":"A","\u1EAE":"A","\u1EB4":"A","\u1EB2":"A","\u0226":"A","\u01E0":"A","\u00C4":"A","\u01DE":"A","\u1EA2":"A","\u00C5":"A","\u01FA":"A","\u01CD":"A","\u0200":"A","\u0202":"A","\u1EA0":"A","\u1EAC":"A","\u1EB6":"A","\u1E00":"A","\u0104":"A","\u023A":"A","\u2C6F":"A","\uA732":"AA","\u00C6":"AE","\u01FC":"AE","\u01E2":"AE","\uA734":"AO","\uA736":"AU","\uA738":"AV","\uA73A":"AV","\uA73C":"AY","\u24B7":"B","\uFF22":"B","\u1E02":"B","\u1E04":"B","\u1E06":"B","\u0243":"B","\u0182":"B","\u0181":"B","\u24B8":"C","\uFF23":"C","\u0106":"C","\u0108":"C","\u010A":"C","\u010C":"C","\u00C7":"C","\u1E08":"C","\u0187":"C","\u023B":"C","\uA73E":"C","\u24B9":"D","\uFF24":"D","\u1E0A":"D","\u010E":"D","\u1E0C":"D","\u1E10":"D","\u1E12":"D","\u1E0E":"D","\u0110":"D","\u018B":"D","\u018A":"D","\u0189":"D","\uA779":"D","\u01F1":"DZ","\u01C4":"DZ","\u01F2":"Dz","\u01C5":"Dz","\u24BA":"E","\uFF25":"E","\u00C8":"E","\u00C9":"E","\u00CA":"E","\u1EC0":"E","\u1EBE":"E","\u1EC4":"E","\u1EC2":"E","\u1EBC":"E","\u0112":"E","\u1E14":"E","\u1E16":"E","\u0114":"E","\u0116":"E","\u00CB":"E","\u1EBA":"E","\u011A":"E","\u0204":"E","\u0206":"E","\u1EB8":"E","\u1EC6":"E","\u0228":"E","\u1E1C":"E","\u0118":"E","\u1E18":"E","\u1E1A":"E","\u0190":"E","\u018E":"E","\u24BB":"F","\uFF26":"F","\u1E1E":"F","\u0191":"F","\uA77B":"F","\u24BC":"G","\uFF27":"G","\u01F4":"G","\u011C":"G","\u1E20":"G","\u011E":"G","\u0120":"G","\u01E6":"G","\u0122":"G","\u01E4":"G","\u0193":"G","\uA7A0":"G","\uA77D":"G","\uA77E":"G","\u24BD":"H","\uFF28":"H","\u0124":"H","\u1E22":"H","\u1E26":"H","\u021E":"H","\u1E24":"H","\u1E28":"H","\u1E2A":"H","\u0126":"H","\u2C67":"H","\u2C75":"H","\uA78D":"H","\u24BE":"I","\uFF29":"I","\u00CC":"I","\u00CD":"I","\u00CE":"I","\u0128":"I","\u012A":"I","\u012C":"I","\u0130":"I","\u00CF":"I","\u1E2E":"I","\u1EC8":"I","\u01CF":"I","\u0208":"I","\u020A":"I","\u1ECA":"I","\u012E":"I","\u1E2C":"I","\u0197":"I","\u24BF":"J","\uFF2A":"J","\u0134":"J","\u0248":"J","\u24C0":"K","\uFF2B":"K","\u1E30":"K","\u01E8":"K","\u1E32":"K","\u0136":"K","\u1E34":"K","\u0198":"K","\u2C69":"K","\uA740":"K","\uA742":"K","\uA744":"K","\uA7A2":"K","\u24C1":"L","\uFF2C":"L","\u013F":"L","\u0139":"L","\u013D":"L","\u1E36":"L","\u1E38":"L","\u013B":"L","\u1E3C":"L","\u1E3A":"L","\u0141":"L","\u023D":"L","\u2C62":"L","\u2C60":"L","\uA748":"L","\uA746":"L","\uA780":"L","\u01C7":"LJ","\u01C8":"Lj","\u24C2":"M","\uFF2D":"M","\u1E3E":"M","\u1E40":"M","\u1E42":"M","\u2C6E":"M","\u019C":"M","\u24C3":"N","\uFF2E":"N","\u01F8":"N","\u0143":"N","\u00D1":"N","\u1E44":"N","\u0147":"N","\u1E46":"N","\u0145":"N","\u1E4A":"N","\u1E48":"N","\u0220":"N","\u019D":"N","\uA790":"N","\uA7A4":"N","\u01CA":"NJ","\u01CB":"Nj","\u24C4":"O","\uFF2F":"O","\u00D2":"O","\u00D3":"O","\u00D4":"O","\u1ED2":"O","\u1ED0":"O","\u1ED6":"O","\u1ED4":"O","\u00D5":"O","\u1E4C":"O","\u022C":"O","\u1E4E":"O","\u014C":"O","\u1E50":"O","\u1E52":"O","\u014E":"O","\u022E":"O","\u0230":"O","\u00D6":"O","\u022A":"O","\u1ECE":"O","\u0150":"O","\u01D1":"O","\u020C":"O","\u020E":"O","\u01A0":"O","\u1EDC":"O","\u1EDA":"O","\u1EE0":"O","\u1EDE":"O","\u1EE2":"O","\u1ECC":"O","\u1ED8":"O","\u01EA":"O","\u01EC":"O","\u00D8":"O","\u01FE":"O","\u0186":"O","\u019F":"O","\uA74A":"O","\uA74C":"O","\u01A2":"OI","\uA74E":"OO","\u0222":"OU","\u24C5":"P","\uFF30":"P","\u1E54":"P","\u1E56":"P","\u01A4":"P","\u2C63":"P","\uA750":"P","\uA752":"P","\uA754":"P","\u24C6":"Q","\uFF31":"Q","\uA756":"Q","\uA758":"Q","\u024A":"Q","\u24C7":"R","\uFF32":"R","\u0154":"R","\u1E58":"R","\u0158":"R","\u0210":"R","\u0212":"R","\u1E5A":"R","\u1E5C":"R","\u0156":"R","\u1E5E":"R","\u024C":"R","\u2C64":"R","\uA75A":"R","\uA7A6":"R","\uA782":"R","\u24C8":"S","\uFF33":"S","\u1E9E":"S","\u015A":"S","\u1E64":"S","\u015C":"S","\u1E60":"S","\u0160":"S","\u1E66":"S","\u1E62":"S","\u1E68":"S","\u0218":"S","\u015E":"S","\u2C7E":"S","\uA7A8":"S","\uA784":"S","\u24C9":"T","\uFF34":"T","\u1E6A":"T","\u0164":"T","\u1E6C":"T","\u021A":"T","\u0162":"T","\u1E70":"T","\u1E6E":"T","\u0166":"T","\u01AC":"T","\u01AE":"T","\u023E":"T","\uA786":"T","\uA728":"TZ","\u24CA":"U","\uFF35":"U","\u00D9":"U","\u00DA":"U","\u00DB":"U","\u0168":"U","\u1E78":"U","\u016A":"U","\u1E7A":"U","\u016C":"U","\u00DC":"U","\u01DB":"U","\u01D7":"U","\u01D5":"U","\u01D9":"U","\u1EE6":"U","\u016E":"U","\u0170":"U","\u01D3":"U","\u0214":"U","\u0216":"U","\u01AF":"U","\u1EEA":"U","\u1EE8":"U","\u1EEE":"U","\u1EEC":"U","\u1EF0":"U","\u1EE4":"U","\u1E72":"U","\u0172":"U","\u1E76":"U","\u1E74":"U","\u0244":"U","\u24CB":"V","\uFF36":"V","\u1E7C":"V","\u1E7E":"V","\u01B2":"V","\uA75E":"V","\u0245":"V","\uA760":"VY","\u24CC":"W","\uFF37":"W","\u1E80":"W","\u1E82":"W","\u0174":"W","\u1E86":"W","\u1E84":"W","\u1E88":"W","\u2C72":"W","\u24CD":"X","\uFF38":"X","\u1E8A":"X","\u1E8C":"X","\u24CE":"Y","\uFF39":"Y","\u1EF2":"Y","\u00DD":"Y","\u0176":"Y","\u1EF8":"Y","\u0232":"Y","\u1E8E":"Y","\u0178":"Y","\u1EF6":"Y","\u1EF4":"Y","\u01B3":"Y","\u024E":"Y","\u1EFE":"Y","\u24CF":"Z","\uFF3A":"Z","\u0179":"Z","\u1E90":"Z","\u017B":"Z","\u017D":"Z","\u1E92":"Z","\u1E94":"Z","\u01B5":"Z","\u0224":"Z","\u2C7F":"Z","\u2C6B":"Z","\uA762":"Z","\u24D0":"a","\uFF41":"a","\u1E9A":"a","\u00E0":"a","\u00E1":"a","\u00E2":"a","\u1EA7":"a","\u1EA5":"a","\u1EAB":"a","\u1EA9":"a","\u00E3":"a","\u0101":"a","\u0103":"a","\u1EB1":"a","\u1EAF":"a","\u1EB5":"a","\u1EB3":"a","\u0227":"a","\u01E1":"a","\u00E4":"a","\u01DF":"a","\u1EA3":"a","\u00E5":"a","\u01FB":"a","\u01CE":"a","\u0201":"a","\u0203":"a","\u1EA1":"a","\u1EAD":"a","\u1EB7":"a","\u1E01":"a","\u0105":"a","\u2C65":"a","\u0250":"a","\uA733":"aa","\u00E6":"ae","\u01FD":"ae","\u01E3":"ae","\uA735":"ao","\uA737":"au","\uA739":"av","\uA73B":"av","\uA73D":"ay","\u24D1":"b","\uFF42":"b","\u1E03":"b","\u1E05":"b","\u1E07":"b","\u0180":"b","\u0183":"b","\u0253":"b","\u24D2":"c","\uFF43":"c","\u0107":"c","\u0109":"c","\u010B":"c","\u010D":"c","\u00E7":"c","\u1E09":"c","\u0188":"c","\u023C":"c","\uA73F":"c","\u2184":"c","\u24D3":"d","\uFF44":"d","\u1E0B":"d","\u010F":"d","\u1E0D":"d","\u1E11":"d","\u1E13":"d","\u1E0F":"d","\u0111":"d","\u018C":"d","\u0256":"d","\u0257":"d","\uA77A":"d","\u01F3":"dz","\u01C6":"dz","\u24D4":"e","\uFF45":"e","\u00E8":"e","\u00E9":"e","\u00EA":"e","\u1EC1":"e","\u1EBF":"e","\u1EC5":"e","\u1EC3":"e","\u1EBD":"e","\u0113":"e","\u1E15":"e","\u1E17":"e","\u0115":"e","\u0117":"e","\u00EB":"e","\u1EBB":"e","\u011B":"e","\u0205":"e","\u0207":"e","\u1EB9":"e","\u1EC7":"e","\u0229":"e","\u1E1D":"e","\u0119":"e","\u1E19":"e","\u1E1B":"e","\u0247":"e","\u025B":"e","\u01DD":"e","\u24D5":"f","\uFF46":"f","\u1E1F":"f","\u0192":"f","\uA77C":"f","\u24D6":"g","\uFF47":"g","\u01F5":"g","\u011D":"g","\u1E21":"g","\u011F":"g","\u0121":"g","\u01E7":"g","\u0123":"g","\u01E5":"g","\u0260":"g","\uA7A1":"g","\u1D79":"g","\uA77F":"g","\u24D7":"h","\uFF48":"h","\u0125":"h","\u1E23":"h","\u1E27":"h","\u021F":"h","\u1E25":"h","\u1E29":"h","\u1E2B":"h","\u1E96":"h","\u0127":"h","\u2C68":"h","\u2C76":"h","\u0265":"h","\u0195":"hv","\u24D8":"i","\uFF49":"i","\u00EC":"i","\u00ED":"i","\u00EE":"i","\u0129":"i","\u012B":"i","\u012D":"i","\u00EF":"i","\u1E2F":"i","\u1EC9":"i","\u01D0":"i","\u0209":"i","\u020B":"i","\u1ECB":"i","\u012F":"i","\u1E2D":"i","\u0268":"i","\u0131":"i","\u24D9":"j","\uFF4A":"j","\u0135":"j","\u01F0":"j","\u0249":"j","\u24DA":"k","\uFF4B":"k","\u1E31":"k","\u01E9":"k","\u1E33":"k","\u0137":"k","\u1E35":"k","\u0199":"k","\u2C6A":"k","\uA741":"k","\uA743":"k","\uA745":"k","\uA7A3":"k","\u24DB":"l","\uFF4C":"l","\u0140":"l","\u013A":"l","\u013E":"l","\u1E37":"l","\u1E39":"l","\u013C":"l","\u1E3D":"l","\u1E3B":"l","\u017F":"l","\u0142":"l","\u019A":"l","\u026B":"l","\u2C61":"l","\uA749":"l","\uA781":"l","\uA747":"l","\u01C9":"lj","\u24DC":"m","\uFF4D":"m","\u1E3F":"m","\u1E41":"m","\u1E43":"m","\u0271":"m","\u026F":"m","\u24DD":"n","\uFF4E":"n","\u01F9":"n","\u0144":"n","\u00F1":"n","\u1E45":"n","\u0148":"n","\u1E47":"n","\u0146":"n","\u1E4B":"n","\u1E49":"n","\u019E":"n","\u0272":"n","\u0149":"n","\uA791":"n","\uA7A5":"n","\u01CC":"nj","\u24DE":"o","\uFF4F":"o","\u00F2":"o","\u00F3":"o","\u00F4":"o","\u1ED3":"o","\u1ED1":"o","\u1ED7":"o","\u1ED5":"o","\u00F5":"o","\u1E4D":"o","\u022D":"o","\u1E4F":"o","\u014D":"o","\u1E51":"o","\u1E53":"o","\u014F":"o","\u022F":"o","\u0231":"o","\u00F6":"o","\u022B":"o","\u1ECF":"o","\u0151":"o","\u01D2":"o","\u020D":"o","\u020F":"o","\u01A1":"o","\u1EDD":"o","\u1EDB":"o","\u1EE1":"o","\u1EDF":"o","\u1EE3":"o","\u1ECD":"o","\u1ED9":"o","\u01EB":"o","\u01ED":"o","\u00F8":"o","\u01FF":"o","\u0254":"o","\uA74B":"o","\uA74D":"o","\u0275":"o","\u01A3":"oi","\u0223":"ou","\uA74F":"oo","\u24DF":"p","\uFF50":"p","\u1E55":"p","\u1E57":"p","\u01A5":"p","\u1D7D":"p","\uA751":"p","\uA753":"p","\uA755":"p","\u24E0":"q","\uFF51":"q","\u024B":"q","\uA757":"q","\uA759":"q","\u24E1":"r","\uFF52":"r","\u0155":"r","\u1E59":"r","\u0159":"r","\u0211":"r","\u0213":"r","\u1E5B":"r","\u1E5D":"r","\u0157":"r","\u1E5F":"r","\u024D":"r","\u027D":"r","\uA75B":"r","\uA7A7":"r","\uA783":"r","\u24E2":"s","\uFF53":"s","\u00DF":"s","\u015B":"s","\u1E65":"s","\u015D":"s","\u1E61":"s","\u0161":"s","\u1E67":"s","\u1E63":"s","\u1E69":"s","\u0219":"s","\u015F":"s","\u023F":"s","\uA7A9":"s","\uA785":"s","\u1E9B":"s","\u24E3":"t","\uFF54":"t","\u1E6B":"t","\u1E97":"t","\u0165":"t","\u1E6D":"t","\u021B":"t","\u0163":"t","\u1E71":"t","\u1E6F":"t","\u0167":"t","\u01AD":"t","\u0288":"t","\u2C66":"t","\uA787":"t","\uA729":"tz","\u24E4":"u","\uFF55":"u","\u00F9":"u","\u00FA":"u","\u00FB":"u","\u0169":"u","\u1E79":"u","\u016B":"u","\u1E7B":"u","\u016D":"u","\u00FC":"u","\u01DC":"u","\u01D8":"u","\u01D6":"u","\u01DA":"u","\u1EE7":"u","\u016F":"u","\u0171":"u","\u01D4":"u","\u0215":"u","\u0217":"u","\u01B0":"u","\u1EEB":"u","\u1EE9":"u","\u1EEF":"u","\u1EED":"u","\u1EF1":"u","\u1EE5":"u","\u1E73":"u","\u0173":"u","\u1E77":"u","\u1E75":"u","\u0289":"u","\u24E5":"v","\uFF56":"v","\u1E7D":"v","\u1E7F":"v","\u028B":"v","\uA75F":"v","\u028C":"v","\uA761":"vy","\u24E6":"w","\uFF57":"w","\u1E81":"w","\u1E83":"w","\u0175":"w","\u1E87":"w","\u1E85":"w","\u1E98":"w","\u1E89":"w","\u2C73":"w","\u24E7":"x","\uFF58":"x","\u1E8B":"x","\u1E8D":"x","\u24E8":"y","\uFF59":"y","\u1EF3":"y","\u00FD":"y","\u0177":"y","\u1EF9":"y","\u0233":"y","\u1E8F":"y","\u00FF":"y","\u1EF7":"y","\u1E99":"y","\u1EF5":"y","\u01B4":"y","\u024F":"y","\u1EFF":"y","\u24E9":"z","\uFF5A":"z","\u017A":"z","\u1E91":"z","\u017C":"z","\u017E":"z","\u1E93":"z","\u1E95":"z","\u01B6":"z","\u0225":"z","\u0240":"z","\u2C6C":"z","\uA763":"z"};
+
+ $document = $(document);
+
+ nextUid=(function() { var counter=1; return function() { return counter++; }; }());
+
+
+ function reinsertElement(element) {
+ var placeholder = $(document.createTextNode(''));
+
+ element.before(placeholder);
+ placeholder.before(element);
+ placeholder.remove();
+ }
+
+ function stripDiacritics(str) {
+ // Used 'uni range + named function' from http://jsperf.com/diacritics/18
+ function match(a) {
+ return DIACRITICS[a] || a;
+ }
+
+ return str.replace(/[^\u0000-\u007E]/g, match);
+ }
+
+ function indexOf(value, array) {
+ var i = 0, l = array.length;
+ for (; i < l; i = i + 1) {
+ if (equal(value, array[i])) return i;
+ }
+ return -1;
+ }
+
+ function measureScrollbar () {
+ var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
+ $template.appendTo('body');
+
+ var dim = {
+ width: $template.width() - $template[0].clientWidth,
+ height: $template.height() - $template[0].clientHeight
+ };
+ $template.remove();
+
+ return dim;
+ }
+
+ /**
+ * Compares equality of a and b
+ * @param a
+ * @param b
+ */
+ function equal(a, b) {
+ if (a === b) return true;
+ if (a === undefined || b === undefined) return false;
+ if (a === null || b === null) return false;
+ // Check whether 'a' or 'b' is a string (primitive or object).
+ // The concatenation of an empty string (+'') converts its argument to a string's primitive.
+ if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object
+ if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object
+ return false;
+ }
+
+ /**
+ * Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty
+ * strings
+ * @param string
+ * @param separator
+ */
+ function splitVal(string, separator) {
+ var val, i, l;
+ if (string === null || string.length < 1) return [];
+ val = string.split(separator);
+ for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
+ return val;
+ }
+
+ function getSideBorderPadding(element) {
+ return element.outerWidth(false) - element.width();
+ }
+
+ function installKeyUpChangeEvent(element) {
+ var key="keyup-change-value";
+ element.on("keydown", function () {
+ if ($.data(element, key) === undefined) {
+ $.data(element, key, element.val());
+ }
+ });
+ element.on("keyup", function () {
+ var val= $.data(element, key);
+ if (val !== undefined && element.val() !== val) {
+ $.removeData(element, key);
+ element.trigger("keyup-change");
+ }
+ });
+ }
+
+ $document.on("mousemove", function (e) {
+ lastMousePosition.x = e.pageX;
+ lastMousePosition.y = e.pageY;
+ });
+
+ /**
+ * filters mouse events so an event is fired only if the mouse moved.
+ *
+ * filters out mouse events that occur when mouse is stationary but
+ * the elements under the pointer are scrolled.
+ */
+ function installFilteredMouseMove(element) {
+ element.on("mousemove", function (e) {
+ var lastpos = lastMousePosition;
+ if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
+ $(e.target).trigger("mousemove-filtered", e);
+ }
+ });
+ }
+
+ /**
+ * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made
+ * within the last quietMillis milliseconds.
+ *
+ * @param quietMillis number of milliseconds to wait before invoking fn
+ * @param fn function to be debounced
+ * @param ctx object to be used as this reference within fn
+ * @return debounced version of fn
+ */
+ function debounce(quietMillis, fn, ctx) {
+ ctx = ctx || undefined;
+ var timeout;
+ return function () {
+ var args = arguments;
+ window.clearTimeout(timeout);
+ timeout = window.setTimeout(function() {
+ fn.apply(ctx, args);
+ }, quietMillis);
+ };
+ }
+
+ function installDebouncedScroll(threshold, element) {
+ var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);});
+ element.on("scroll", function (e) {
+ if (indexOf(e.target, element.get()) >= 0) notify(e);
+ });
+ }
+
+ function focus($el) {
+ if ($el[0] === document.activeElement) return;
+
+ /* set the focus in a 0 timeout - that way the focus is set after the processing
+ of the current event has finished - which seems like the only reliable way
+ to set focus */
+ window.setTimeout(function() {
+ var el=$el[0], pos=$el.val().length, range;
+
+ $el.focus();
+
+ /* make sure el received focus so we do not error out when trying to manipulate the caret.
+ sometimes modals or others listeners may steal it after its set */
+ var isVisible = (el.offsetWidth > 0 || el.offsetHeight > 0);
+ if (isVisible && el === document.activeElement) {
+
+ /* after the focus is set move the caret to the end, necessary when we val()
+ just before setting focus */
+ if(el.setSelectionRange)
+ {
+ el.setSelectionRange(pos, pos);
+ }
+ else if (el.createTextRange) {
+ range = el.createTextRange();
+ range.collapse(false);
+ range.select();
+ }
+ }
+ }, 0);
+ }
+
+ function getCursorInfo(el) {
+ el = $(el)[0];
+ var offset = 0;
+ var length = 0;
+ if ('selectionStart' in el) {
+ offset = el.selectionStart;
+ length = el.selectionEnd - offset;
+ } else if ('selection' in document) {
+ el.focus();
+ var sel = document.selection.createRange();
+ length = document.selection.createRange().text.length;
+ sel.moveStart('character', -el.value.length);
+ offset = sel.text.length - length;
+ }
+ return { offset: offset, length: length };
+ }
+
+ function killEvent(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ function killEventImmediately(event) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+
+ function measureTextWidth(e) {
+ if (!sizer){
+ var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
+ sizer = $(document.createElement("div")).css({
+ position: "absolute",
+ left: "-10000px",
+ top: "-10000px",
+ display: "none",
+ fontSize: style.fontSize,
+ fontFamily: style.fontFamily,
+ fontStyle: style.fontStyle,
+ fontWeight: style.fontWeight,
+ letterSpacing: style.letterSpacing,
+ textTransform: style.textTransform,
+ whiteSpace: "nowrap"
+ });
+ sizer.attr("class","select2-sizer");
+ $("body").append(sizer);
+ }
+ sizer.text(e.val());
+ return sizer.width();
+ }
+
+ function syncCssClasses(dest, src, adapter) {
+ var classes, replacements = [], adapted;
+
+ classes = dest.attr("class");
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
+ $(classes.split(" ")).each2(function() {
+ if (this.indexOf("select2-") === 0) {
+ replacements.push(this);
+ }
+ });
+ }
+ classes = src.attr("class");
+ if (classes) {
+ classes = '' + classes; // for IE which returns object
+ $(classes.split(" ")).each2(function() {
+ if (this.indexOf("select2-") !== 0) {
+ adapted = adapter(this);
+ if (adapted) {
+ replacements.push(adapted);
+ }
+ }
+ });
+ }
+ dest.attr("class", replacements.join(" "));
+ }
+
+
+ function markMatch(text, term, markup, escapeMarkup) {
+ var match=stripDiacritics(text.toUpperCase()).indexOf(stripDiacritics(term.toUpperCase())),
+ tl=term.length;
+
+ if (match<0) {
+ markup.push(escapeMarkup(text));
+ return;
+ }
+
+ markup.push(escapeMarkup(text.substring(0, match)));
+ markup.push("<span class='select2-match'>");
+ markup.push(escapeMarkup(text.substring(match, match + tl)));
+ markup.push("</span>");
+ markup.push(escapeMarkup(text.substring(match + tl, text.length)));
+ }
+
+ function defaultEscapeMarkup(markup) {
+ var replace_map = {
+ '\\': '&#92;',
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#39;',
+ "/": '&#47;'
+ };
+
+ return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
+ return replace_map[match];
+ });
+ }
+
+ /**
+ * Produces an ajax-based query function
+ *
+ * @param options object containing configuration parameters
+ * @param options.params parameter map for the transport ajax call, can contain such options as cache, jsonpCallback, etc. see $.ajax
+ * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
+ * @param options.url url for the data
+ * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
+ * @param options.dataType request data type: ajax, jsonp, other datatypes supported by jQuery's $.ajax function or the transport function if specified
+ * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
+ * @param options.results a function(remoteData, pageNumber) that converts data returned form the remote request to the format expected by Select2.
+ * The expected format is an object containing the following keys:
+ * results array of objects that will be used as choices
+ * more (optional) boolean indicating whether there are more results available
+ * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
+ */
+ function ajax(options) {
+ var timeout, // current scheduled but not yet executed request
+ handler = null,
+ quietMillis = options.quietMillis || 100,
+ ajaxUrl = options.url,
+ self = this;
+
+ return function (query) {
+ window.clearTimeout(timeout);
+ timeout = window.setTimeout(function () {
+ var data = options.data, // ajax data function
+ url = ajaxUrl, // ajax url string or function
+ transport = options.transport || $.fn.select2.ajaxDefaults.transport,
+ // deprecated - to be removed in 4.0 - use params instead
+ deprecated = {
+ type: options.type || 'GET', // set type of request (GET or POST)
+ cache: options.cache || false,
+ jsonpCallback: options.jsonpCallback||undefined,
+ dataType: options.dataType||"json"
+ },
+ params = $.extend({}, $.fn.select2.ajaxDefaults.params, deprecated);
+
+ data = data ? data.call(self, query.term, query.page, query.context) : null;
+ url = (typeof url === 'function') ? url.call(self, query.term, query.page, query.context) : url;
+
+ if (handler && typeof handler.abort === "function") { handler.abort(); }
+
+ if (options.params) {
+ if ($.isFunction(options.params)) {
+ $.extend(params, options.params.call(self));
+ } else {
+ $.extend(params, options.params);
+ }
+ }
+
+ $.extend(params, {
+ url: url,
+ dataType: options.dataType,
+ data: data,
+ success: function (data) {
+ // TODO - replace query.page with query so users have access to term, page, etc.
+ var results = options.results(data, query.page);
+ query.callback(results);
+ }
+ });
+ handler = transport.call(self, params);
+ }, quietMillis);
+ };
+ }
+
+ /**
+ * Produces a query function that works with a local array
+ *
+ * @param options object containing configuration parameters. The options parameter can either be an array or an
+ * object.
+ *
+ * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.
+ *
+ * If the object form is used it is assumed that it contains 'data' and 'text' keys. The 'data' key should contain
+ * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'
+ * key can either be a String in which case it is expected that each element in the 'data' array has a key with the
+ * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract
+ * the text.
+ */
+ function local(options) {
+ var data = options, // data elements
+ dataText,
+ tmp,
+ text = function (item) { return ""+item.text; }; // function used to retrieve the text portion of a data item that is matched against the search
+
+ if ($.isArray(data)) {
+ tmp = data;
+ data = { results: tmp };
+ }
+
+ if ($.isFunction(data) === false) {
+ tmp = data;
+ data = function() { return tmp; };
+ }
+
+ var dataItem = data();
+ if (dataItem.text) {
+ text = dataItem.text;
+ // if text is not a function we assume it to be a key name
+ if (!$.isFunction(text)) {
+ dataText = dataItem.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
+ text = function (item) { return item[dataText]; };
+ }
+ }
+
+ return function (query) {
+ var t = query.term, filtered = { results: [] }, process;
+ if (t === "") {
+ query.callback(data());
+ return;
+ }
+
+ process = function(datum, collection) {
+ var group, attr;
+ datum = datum[0];
+ if (datum.children) {
+ group = {};
+ for (attr in datum) {
+ if (datum.hasOwnProperty(attr)) group[attr]=datum[attr];
+ }
+ group.children=[];
+ $(datum.children).each2(function(i, childDatum) { process(childDatum, group.children); });
+ if (group.children.length || query.matcher(t, text(group), datum)) {
+ collection.push(group);
+ }
+ } else {
+ if (query.matcher(t, text(datum), datum)) {
+ collection.push(datum);
+ }
+ }
+ };
+
+ $(data().results).each2(function(i, datum) { process(datum, filtered.results); });
+ query.callback(filtered);
+ };
+ }
+
+ // TODO javadoc
+ function tags(data) {
+ var isFunc = $.isFunction(data);
+ return function (query) {
+ var t = query.term, filtered = {results: []};
+ var result = isFunc ? data(query) : data;
+ if ($.isArray(result)) {
+ $(result).each(function () {
+ var isObject = this.text !== undefined,
+ text = isObject ? this.text : this;
+ if (t === "" || query.matcher(t, text)) {
+ filtered.results.push(isObject ? this : {id: this, text: this});
+ }
+ });
+ query.callback(filtered);
+ }
+ };
+ }
+
+ /**
+ * Checks if the formatter function should be used.
+ *
+ * Throws an error if it is not a function. Returns true if it should be used,
+ * false if no formatting should be performed.
+ *
+ * @param formatter
+ */
+ function checkFormatter(formatter, formatterName) {
+ if ($.isFunction(formatter)) return true;
+ if (!formatter) return false;
+ if (typeof(formatter) === 'string') return true;
+ throw new Error(formatterName +" must be a string, function, or falsy value");
+ }
+
+ function evaluate(val) {
+ if ($.isFunction(val)) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ return val.apply(null, args);
+ }
+ return val;
+ }
+
+ function countResults(results) {
+ var count = 0;
+ $.each(results, function(i, item) {
+ if (item.children) {
+ count += countResults(item.children);
+ } else {
+ count++;
+ }
+ });
+ return count;
+ }
+
+ /**
+ * Default tokenizer. This function uses breaks the input on substring match of any string from the
+ * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those
+ * two options have to be defined in order for the tokenizer to work.
+ *
+ * @param input text user has typed so far or pasted into the search field
+ * @param selection currently selected choices
+ * @param selectCallback function(choice) callback tho add the choice to selection
+ * @param opts select2's opts
+ * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value
+ */
+ function defaultTokenizer(input, selection, selectCallback, opts) {
+ var original = input, // store the original so we can compare and know if we need to tell the search to update its text
+ dupe = false, // check for whether a token we extracted represents a duplicate selected choice
+ token, // token
+ index, // position at which the separator was found
+ i, l, // looping variables
+ separator; // the matched separator
+
+ if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
+
+ while (true) {
+ index = -1;
+
+ for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
+ separator = opts.tokenSeparators[i];
+ index = input.indexOf(separator);
+ if (index >= 0) break;
+ }
+
+ if (index < 0) break; // did not find any token separator in the input string, bail
+
+ token = input.substring(0, index);
+ input = input.substring(index + separator.length);
+
+ if (token.length > 0) {
+ token = opts.createSearchChoice.call(this, token, selection);
+ if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
+ dupe = false;
+ for (i = 0, l = selection.length; i < l; i++) {
+ if (equal(opts.id(token), opts.id(selection[i]))) {
+ dupe = true; break;
+ }
+ }
+
+ if (!dupe) selectCallback(token);
+ }
+ }
+ }
+
+ if (original!==input) return input;
+ }
+
+ function cleanupJQueryElements() {
+ var self = this;
+
+ Array.prototype.forEach.call(arguments, function (element) {
+ self[element].remove();
+ self[element] = null;
+ });
+ }
+
+ /**
+ * Creates a new class
+ *
+ * @param superClass
+ * @param methods
+ */
+ function clazz(SuperClass, methods) {
+ var constructor = function () {};
+ constructor.prototype = new SuperClass;
+ constructor.prototype.constructor = constructor;
+ constructor.prototype.parent = SuperClass.prototype;
+ constructor.prototype = $.extend(constructor.prototype, methods);
+ return constructor;
+ }
+
+ AbstractSelect2 = clazz(Object, {
+
+ // abstract
+ bind: function (func) {
+ var self = this;
+ return function () {
+ func.apply(self, arguments);
+ };
+ },
+
+ // abstract
+ init: function (opts) {
+ var results, search, resultsSelector = ".select2-results";
+
+ // prepare options
+ this.opts = opts = this.prepareOpts(opts);
+
+ this.id=opts.id;
+
+ // destroy if called on an existing component
+ if (opts.element.data("select2") !== undefined &&
+ opts.element.data("select2") !== null) {
+ opts.element.data("select2").destroy();
+ }
+
+ this.container = this.createContainer();
+
+ this.liveRegion = $("<span>", {
+ role: "status",
+ "aria-live": "polite"
+ })
+ .addClass("select2-hidden-accessible")
+ .appendTo(document.body);
+
+ this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
+ this.containerEventName= this.containerId
+ .replace(/([.])/g, '_')
+ .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
+ this.container.attr("id", this.containerId);
+
+ this.container.attr("title", opts.element.attr("title"));
+
+ this.body = $("body");
+
+ syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
+
+ this.container.attr("style", opts.element.attr("style"));
+ this.container.css(evaluate(opts.containerCss));
+ this.container.addClass(evaluate(opts.containerCssClass));
+
+ this.elementTabIndex = this.opts.element.attr("tabindex");
+
+ // swap container for the element
+ this.opts.element
+ .data("select2", this)
+ .attr("tabindex", "-1")
+ .before(this.container)
+ .on("click.select2", killEvent); // do not leak click events
+
+ this.container.data("select2", this);
+
+ this.dropdown = this.container.find(".select2-drop");
+
+ syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
+
+ this.dropdown.addClass(evaluate(opts.dropdownCssClass));
+ this.dropdown.data("select2", this);
+ this.dropdown.on("click", killEvent);
+
+ this.results = results = this.container.find(resultsSelector);
+ this.search = search = this.container.find("input.select2-input");
+
+ this.queryCount = 0;
+ this.resultsPage = 0;
+ this.context = null;
+
+ // initialize the container
+ this.initContainer();
+
+ this.container.on("click", killEvent);
+
+ installFilteredMouseMove(this.results);
+
+ this.dropdown.on("mousemove-filtered", resultsSelector, this.bind(this.highlightUnderEvent));
+ this.dropdown.on("touchstart touchmove touchend", resultsSelector, this.bind(function (event) {
+ this._touchEvent = true;
+ this.highlightUnderEvent(event);
+ }));
+ this.dropdown.on("touchmove", resultsSelector, this.bind(this.touchMoved));
+ this.dropdown.on("touchstart touchend", resultsSelector, this.bind(this.clearTouchMoved));
+
+ // Waiting for a click event on touch devices to select option and hide dropdown
+ // otherwise click will be triggered on an underlying element
+ this.dropdown.on('click', this.bind(function (event) {
+ if (this._touchEvent) {
+ this._touchEvent = false;
+ this.selectHighlighted();
+ }
+ }));
+
+ installDebouncedScroll(80, this.results);
+ this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded));
+
+ // do not propagate change event from the search field out of the component
+ $(this.container).on("change", ".select2-input", function(e) {e.stopPropagation();});
+ $(this.dropdown).on("change", ".select2-input", function(e) {e.stopPropagation();});
+
+ // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
+ if ($.fn.mousewheel) {
+ results.mousewheel(function (e, delta, deltaX, deltaY) {
+ var top = results.scrollTop();
+ if (deltaY > 0 && top - deltaY <= 0) {
+ results.scrollTop(0);
+ killEvent(e);
+ } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
+ results.scrollTop(results.get(0).scrollHeight - results.height());
+ killEvent(e);
+ }
+ });
+ }
+
+ installKeyUpChangeEvent(search);
+ search.on("keyup-change input paste", this.bind(this.updateResults));
+ search.on("focus", function () { search.addClass("select2-focused"); });
+ search.on("blur", function () { search.removeClass("select2-focused");});
+
+ this.dropdown.on("mouseup", resultsSelector, this.bind(function (e) {
+ if ($(e.target).closest(".select2-result-selectable").length > 0) {
+ this.highlightUnderEvent(e);
+ this.selectHighlighted(e);
+ }
+ }));
+
+ // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
+ // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
+ // dom it will trigger the popup close, which is not what we want
+ // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.
+ this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); });
+
+ this.nextSearchTerm = undefined;
+
+ if ($.isFunction(this.opts.initSelection)) {
+ // initialize selection based on the current value of the source element
+ this.initSelection();
+
+ // if the user has provided a function that can set selection based on the value of the source element
+ // we monitor the change event on the element and trigger it, allowing for two way synchronization
+ this.monitorSource();
+ }
+
+ if (opts.maximumInputLength !== null) {
+ this.search.attr("maxlength", opts.maximumInputLength);
+ }
+
+ var disabled = opts.element.prop("disabled");
+ if (disabled === undefined) disabled = false;
+ this.enable(!disabled);
+
+ var readonly = opts.element.prop("readonly");
+ if (readonly === undefined) readonly = false;
+ this.readonly(readonly);
+
+ // Calculate size of scrollbar
+ scrollBarDimensions = scrollBarDimensions || measureScrollbar();
+
+ this.autofocus = opts.element.prop("autofocus");
+ opts.element.prop("autofocus", false);
+ if (this.autofocus) this.focus();
+
+ this.search.attr("placeholder", opts.searchInputPlaceholder);
+ },
+
+ // abstract
+ destroy: function () {
+ var element=this.opts.element, select2 = element.data("select2");
+
+ this.close();
+
+ if (this.propertyObserver) {
+ this.propertyObserver.disconnect();
+ this.propertyObserver = null;
+ }
+
+ if (select2 !== undefined) {
+ select2.container.remove();
+ select2.liveRegion.remove();
+ select2.dropdown.remove();
+ element
+ .removeClass("select2-offscreen")
+ .removeData("select2")
+ .off(".select2")
+ .prop("autofocus", this.autofocus || false);
+ if (this.elementTabIndex) {
+ element.attr({tabindex: this.elementTabIndex});
+ } else {
+ element.removeAttr("tabindex");
+ }
+ element.show();
+ }
+
+ cleanupJQueryElements.call(this,
+ "container",
+ "liveRegion",
+ "dropdown",
+ "results",
+ "search"
+ );
+ },
+
+ // abstract
+ optionToData: function(element) {
+ if (element.is("option")) {
+ return {
+ id:element.prop("value"),
+ text:element.text(),
+ element: element.get(),
+ css: element.attr("class"),
+ disabled: element.prop("disabled"),
+ locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true)
+ };
+ } else if (element.is("optgroup")) {
+ return {
+ text:element.attr("label"),
+ children:[],
+ element: element.get(),
+ css: element.attr("class")
+ };
+ }
+ },
+
+ // abstract
+ prepareOpts: function (opts) {
+ var element, select, idKey, ajaxUrl, self = this;
+
+ element = opts.element;
+
+ if (element.get(0).tagName.toLowerCase() === "select") {
+ this.select = select = opts.element;
+ }
+
+ if (select) {
+ // these options are not allowed when attached to a select because they are picked up off the element itself
+ $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
+ if (this in opts) {
+ throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
+ }
+ });
+ }
+
+ opts = $.extend({}, {
+ populateResults: function(container, results, query) {
+ var populate, id=this.opts.id, liveRegion=this.liveRegion;
+
+ populate=function(results, container, depth) {
+
+ var i, l, result, selectable, disabled, compound, node, label, innerContainer, formatted;
+
+ results = opts.sortResults(results, container, query);
+
+ for (i = 0, l = results.length; i < l; i = i + 1) {
+
+ result=results[i];
+
+ disabled = (result.disabled === true);
+ selectable = (!disabled) && (id(result) !== undefined);
+
+ compound=result.children && result.children.length > 0;
+
+ node=$("<li></li>");
+ node.addClass("select2-results-dept-"+depth);
+ node.addClass("select2-result");
+ node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
+ if (disabled) { node.addClass("select2-disabled"); }
+ if (compound) { node.addClass("select2-result-with-children"); }
+ node.addClass(self.opts.formatResultCssClass(result));
+ node.attr("role", "presentation");
+
+ label=$(document.createElement("div"));
+ label.addClass("select2-result-label");
+ label.attr("id", "select2-result-label-" + nextUid());
+ label.attr("role", "option");
+
+ formatted=opts.formatResult(result, label, query, self.opts.escapeMarkup);
+ if (formatted!==undefined) {
+ label.html(formatted);
+ node.append(label);
+ }
+
+
+ if (compound) {
+
+ innerContainer=$("<ul></ul>");
+ innerContainer.addClass("select2-result-sub");
+ populate(result.children, innerContainer, depth+1);
+ node.append(innerContainer);
+ }
+
+ node.data("select2-data", result);
+ container.append(node);
+ }
+
+ liveRegion.text(opts.formatMatches(results.length));
+ };
+
+ populate(results, container, 0);
+ }
+ }, $.fn.select2.defaults, opts);
+
+ if (typeof(opts.id) !== "function") {
+ idKey = opts.id;
+ opts.id = function (e) { return e[idKey]; };
+ }
+
+ if ($.isArray(opts.element.data("select2Tags"))) {
+ if ("tags" in opts) {
+ throw "tags specified as both an attribute 'data-select2-tags' and in options of Select2 " + opts.element.attr("id");
+ }
+ opts.tags=opts.element.data("select2Tags");
+ }
+
+ if (select) {
+ opts.query = this.bind(function (query) {
+ var data = { results: [], more: false },
+ term = query.term,
+ children, placeholderOption, process;
+
+ process=function(element, collection) {
+ var group;
+ if (element.is("option")) {
+ if (query.matcher(term, element.text(), element)) {
+ collection.push(self.optionToData(element));
+ }
+ } else if (element.is("optgroup")) {
+ group=self.optionToData(element);
+ element.children().each2(function(i, elm) { process(elm, group.children); });
+ if (group.children.length>0) {
+ collection.push(group);
+ }
+ }
+ };
+
+ children=element.children();
+
+ // ignore the placeholder option if there is one
+ if (this.getPlaceholder() !== undefined && children.length > 0) {
+ placeholderOption = this.getPlaceholderOption();
+ if (placeholderOption) {
+ children=children.not(placeholderOption);
+ }
+ }
+
+ children.each2(function(i, elm) { process(elm, data.results); });
+
+ query.callback(data);
+ });
+ // this is needed because inside val() we construct choices from options and there id is hardcoded
+ opts.id=function(e) { return e.id; };
+ } else {
+ if (!("query" in opts)) {
+
+ if ("ajax" in opts) {
+ ajaxUrl = opts.element.data("ajax-url");
+ if (ajaxUrl && ajaxUrl.length > 0) {
+ opts.ajax.url = ajaxUrl;
+ }
+ opts.query = ajax.call(opts.element, opts.ajax);
+ } else if ("data" in opts) {
+ opts.query = local(opts.data);
+ } else if ("tags" in opts) {
+ opts.query = tags(opts.tags);
+ if (opts.createSearchChoice === undefined) {
+ opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; };
+ }
+ if (opts.initSelection === undefined) {
+ opts.initSelection = function (element, callback) {
+ var data = [];
+ $(splitVal(element.val(), opts.separator)).each(function () {
+ var obj = { id: this, text: this },
+ tags = opts.tags;
+ if ($.isFunction(tags)) tags=tags();
+ $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } });
+ data.push(obj);
+ });
+
+ callback(data);
+ };
+ }
+ }
+ }
+ }
+ if (typeof(opts.query) !== "function") {
+ throw "query function not defined for Select2 " + opts.element.attr("id");
+ }
+
+ if (opts.createSearchChoicePosition === 'top') {
+ opts.createSearchChoicePosition = function(list, item) { list.unshift(item); };
+ }
+ else if (opts.createSearchChoicePosition === 'bottom') {
+ opts.createSearchChoicePosition = function(list, item) { list.push(item); };
+ }
+ else if (typeof(opts.createSearchChoicePosition) !== "function") {
+ throw "invalid createSearchChoicePosition option must be 'top', 'bottom' or a custom function";
+ }
+
+ return opts;
+ },
+
+ /**
+ * Monitor the original element for changes and update select2 accordingly
+ */
+ // abstract
+ monitorSource: function () {
+ var el = this.opts.element, sync, observer;
+
+ el.on("change.select2", this.bind(function (e) {
+ if (this.opts.element.data("select2-change-triggered") !== true) {
+ this.initSelection();
+ }
+ }));
+
+ sync = this.bind(function () {
+
+ // sync enabled state
+ var disabled = el.prop("disabled");
+ if (disabled === undefined) disabled = false;
+ this.enable(!disabled);
+
+ var readonly = el.prop("readonly");
+ if (readonly === undefined) readonly = false;
+ this.readonly(readonly);
+
+ syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
+ this.container.addClass(evaluate(this.opts.containerCssClass));
+
+ syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
+ this.dropdown.addClass(evaluate(this.opts.dropdownCssClass));
+
+ });
+
+ // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener)
+ if (el.length && el[0].attachEvent) {
+ el.each(function() {
+ this.attachEvent("onpropertychange", sync);
+ });
+ }
+
+ // safari, chrome, firefox, IE11
+ observer = window.MutationObserver || window.WebKitMutationObserver|| window.MozMutationObserver;
+ if (observer !== undefined) {
+ if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null; }
+ this.propertyObserver = new observer(function (mutations) {
+ mutations.forEach(sync);
+ });
+ this.propertyObserver.observe(el.get(0), { attributes:true, subtree:false });
+ }
+ },
+
+ // abstract
+ triggerSelect: function(data) {
+ var evt = $.Event("select2-selecting", { val: this.id(data), object: data });
+ this.opts.element.trigger(evt);
+ return !evt.isDefaultPrevented();
+ },
+
+ /**
+ * Triggers the change event on the source element
+ */
+ // abstract
+ triggerChange: function (details) {
+
+ details = details || {};
+ details= $.extend({}, details, { type: "change", val: this.val() });
+ // prevents recursive triggering
+ this.opts.element.data("select2-change-triggered", true);
+ this.opts.element.trigger(details);
+ this.opts.element.data("select2-change-triggered", false);
+
+ // some validation frameworks ignore the change event and listen instead to keyup, click for selects
+ // so here we trigger the click event manually
+ this.opts.element.click();
+
+ // ValidationEngine ignores the change event and listens instead to blur
+ // so here we trigger the blur event manually if so desired
+ if (this.opts.blurOnChange)
+ this.opts.element.blur();
+ },
+
+ //abstract
+ isInterfaceEnabled: function()
+ {
+ return this.enabledInterface === true;
+ },
+
+ // abstract
+ enableInterface: function() {
+ var enabled = this._enabled && !this._readonly,
+ disabled = !enabled;
+
+ if (enabled === this.enabledInterface) return false;
+
+ this.container.toggleClass("select2-container-disabled", disabled);
+ this.close();
+ this.enabledInterface = enabled;
+
+ return true;
+ },
+
+ // abstract
+ enable: function(enabled) {
+ if (enabled === undefined) enabled = true;
+ if (this._enabled === enabled) return;
+ this._enabled = enabled;
+
+ this.opts.element.prop("disabled", !enabled);
+ this.enableInterface();
+ },
+
+ // abstract
+ disable: function() {
+ this.enable(false);
+ },
+
+ // abstract
+ readonly: function(enabled) {
+ if (enabled === undefined) enabled = false;
+ if (this._readonly === enabled) return;
+ this._readonly = enabled;
+
+ this.opts.element.prop("readonly", enabled);
+ this.enableInterface();
+ },
+
+ // abstract
+ opened: function () {
+ return this.container.hasClass("select2-dropdown-open");
+ },
+
+ // abstract
+ positionDropdown: function() {
+ var $dropdown = this.dropdown,
+ offset = this.container.offset(),
+ height = this.container.outerHeight(false),
+ width = this.container.outerWidth(false),
+ dropHeight = $dropdown.outerHeight(false),
+ $window = $(window),
+ windowWidth = $window.width(),
+ windowHeight = $window.height(),
+ viewPortRight = $window.scrollLeft() + windowWidth,
+ viewportBottom = $window.scrollTop() + windowHeight,
+ dropTop = offset.top + height,
+ dropLeft = offset.left,
+ enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
+ enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(),
+ dropWidth = $dropdown.outerWidth(false),
+ enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
+ aboveNow = $dropdown.hasClass("select2-drop-above"),
+ bodyOffset,
+ above,
+ changeDirection,
+ css,
+ resultsListNode;
+
+ // always prefer the current above/below alignment, unless there is not enough room
+ if (aboveNow) {
+ above = true;
+ if (!enoughRoomAbove && enoughRoomBelow) {
+ changeDirection = true;
+ above = false;
+ }
+ } else {
+ above = false;
+ if (!enoughRoomBelow && enoughRoomAbove) {
+ changeDirection = true;
+ above = true;
+ }
+ }
+
+ //if we are changing direction we need to get positions when dropdown is hidden;
+ if (changeDirection) {
+ $dropdown.hide();
+ offset = this.container.offset();
+ height = this.container.outerHeight(false);
+ width = this.container.outerWidth(false);
+ dropHeight = $dropdown.outerHeight(false);
+ viewPortRight = $window.scrollLeft() + windowWidth;
+ viewportBottom = $window.scrollTop() + windowHeight;
+ dropTop = offset.top + height;
+ dropLeft = offset.left;
+ dropWidth = $dropdown.outerWidth(false);
+ enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
+ $dropdown.show();
+
+ // fix so the cursor does not move to the left within the search-textbox in IE
+ this.focusSearch();
+ }
+
+ if (this.opts.dropdownAutoWidth) {
+ resultsListNode = $('.select2-results', $dropdown)[0];
+ $dropdown.addClass('select2-drop-auto-width');
+ $dropdown.css('width', '');
+ // Add scrollbar width to dropdown if vertical scrollbar is present
+ dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
+ dropWidth > width ? width = dropWidth : dropWidth = width;
+ dropHeight = $dropdown.outerHeight(false);
+ enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
+ }
+ else {
+ this.container.removeClass('select2-drop-auto-width');
+ }
+
+ //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
+ //console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body.scrollTop(), "enough?", enoughRoomAbove);
+
+ // fix positioning when body has an offset and is not position: static
+ if (this.body.css('position') !== 'static') {
+ bodyOffset = this.body.offset();
+ dropTop -= bodyOffset.top;
+ dropLeft -= bodyOffset.left;
+ }
+
+ if (!enoughRoomOnRight) {
+ dropLeft = offset.left + this.container.outerWidth(false) - dropWidth;
+ }
+
+ css = {
+ left: dropLeft,
+ width: width
+ };
+
+ if (above) {
+ css.top = offset.top - dropHeight;
+ css.bottom = 'auto';
+ this.container.addClass("select2-drop-above");
+ $dropdown.addClass("select2-drop-above");
+ }
+ else {
+ css.top = dropTop;
+ css.bottom = 'auto';
+ this.container.removeClass("select2-drop-above");
+ $dropdown.removeClass("select2-drop-above");
+ }
+ css = $.extend(css, evaluate(this.opts.dropdownCss));
+
+ $dropdown.css(css);
+ },
+
+ // abstract
+ shouldOpen: function() {
+ var event;
+
+ if (this.opened()) return false;
+
+ if (this._enabled === false || this._readonly === true) return false;
+
+ event = $.Event("select2-opening");
+ this.opts.element.trigger(event);
+ return !event.isDefaultPrevented();
+ },
+
+ // abstract
+ clearDropdownAlignmentPreference: function() {
+ // clear the classes used to figure out the preference of where the dropdown should be opened
+ this.container.removeClass("select2-drop-above");
+ this.dropdown.removeClass("select2-drop-above");
+ },
+
+ /**
+ * Opens the dropdown
+ *
+ * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example,
+ * the dropdown is already open, or if the 'open' event listener on the element called preventDefault().
+ */
+ // abstract
+ open: function () {
+
+ if (!this.shouldOpen()) return false;
+
+ this.opening();
+
+ return true;
+ },
+
+ /**
+ * Performs the opening of the dropdown
+ */
+ // abstract
+ opening: function() {
+ var cid = this.containerEventName,
+ scroll = "scroll." + cid,
+ resize = "resize."+cid,
+ orient = "orientationchange."+cid,
+ mask;
+
+ this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
+
+ this.clearDropdownAlignmentPreference();
+
+ if(this.dropdown[0] !== this.body.children().last()[0]) {
+ this.dropdown.detach().appendTo(this.body);
+ }
+
+ // create the dropdown mask if doesn't already exist
+ mask = $("#select2-drop-mask");
+ if (mask.length == 0) {
+ mask = $(document.createElement("div"));
+ mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
+ mask.hide();
+ mask.appendTo(this.body);
+ mask.on("mousedown touchstart click", function (e) {
+ // Prevent IE from generating a click event on the body
+ reinsertElement(mask);
+
+ var dropdown = $("#select2-drop"), self;
+ if (dropdown.length > 0) {
+ self=dropdown.data("select2");
+ if (self.opts.selectOnBlur) {
+ self.selectHighlighted({noFocus: true});
+ }
+ self.close();
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ }
+
+ // ensure the mask is always right before the dropdown
+ if (this.dropdown.prev()[0] !== mask[0]) {
+ this.dropdown.before(mask);
+ }
+
+ // move the global id to the correct dropdown
+ $("#select2-drop").removeAttr("id");
+ this.dropdown.attr("id", "select2-drop");
+
+ // show the elements
+ mask.show();
+
+ this.positionDropdown();
+ this.dropdown.show();
+ this.positionDropdown();
+
+ this.dropdown.addClass("select2-drop-active");
+
+ // attach listeners to events that can change the position of the container and thus require
+ // the position of the dropdown to be updated as well so it does not come unglued from the container
+ var that = this;
+ this.container.parents().add(window).each(function () {
+ $(this).on(resize+" "+scroll+" "+orient, function (e) {
+ if (that.opened()) that.positionDropdown();
+ });
+ });
+
+
+ },
+
+ // abstract
+ close: function () {
+ if (!this.opened()) return;
+
+ var cid = this.containerEventName,
+ scroll = "scroll." + cid,
+ resize = "resize."+cid,
+ orient = "orientationchange."+cid;
+
+ // unbind event listeners
+ this.container.parents().add(window).each(function () { $(this).off(scroll).off(resize).off(orient); });
+
+ this.clearDropdownAlignmentPreference();
+
+ $("#select2-drop-mask").hide();
+ this.dropdown.removeAttr("id"); // only the active dropdown has the select2-drop id
+ this.dropdown.hide();
+ this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
+ this.results.empty();
+
+
+ this.clearSearch();
+ this.search.removeClass("select2-active");
+ this.opts.element.trigger($.Event("select2-close"));
+ },
+
+ /**
+ * Opens control, sets input value, and updates results.
+ */
+ // abstract
+ externalSearch: function (term) {
+ this.open();
+ this.search.val(term);
+ this.updateResults(false);
+ },
+
+ // abstract
+ clearSearch: function () {
+
+ },
+
+ //abstract
+ getMaximumSelectionSize: function() {
+ return evaluate(this.opts.maximumSelectionSize);
+ },
+
+ // abstract
+ ensureHighlightVisible: function () {
+ var results = this.results, children, index, child, hb, rb, y, more;
+
+ index = this.highlight();
+
+ if (index < 0) return;
+
+ if (index == 0) {
+
+ // if the first element is highlighted scroll all the way to the top,
+ // that way any unselectable headers above it will also be scrolled
+ // into view
+
+ results.scrollTop(0);
+ return;
+ }
+
+ children = this.findHighlightableChoices().find('.select2-result-label');
+
+ child = $(children[index]);
+
+ hb = child.offset().top + child.outerHeight(true);
+
+ // if this is the last child lets also make sure select2-more-results is visible
+ if (index === children.length - 1) {
+ more = results.find("li.select2-more-results");
+ if (more.length > 0) {
+ hb = more.offset().top + more.outerHeight(true);
+ }
+ }
+
+ rb = results.offset().top + results.outerHeight(true);
+ if (hb > rb) {
+ results.scrollTop(results.scrollTop() + (hb - rb));
+ }
+ y = child.offset().top - results.offset().top;
+
+ // make sure the top of the element is visible
+ if (y < 0 && child.css('display') != 'none' ) {
+ results.scrollTop(results.scrollTop() + y); // y is negative
+ }
+ },
+
+ // abstract
+ findHighlightableChoices: function() {
+ return this.results.find(".select2-result-selectable:not(.select2-disabled):not(.select2-selected)");
+ },
+
+ // abstract
+ moveHighlight: function (delta) {
+ var choices = this.findHighlightableChoices(),
+ index = this.highlight();
+
+ while (index > -1 && index < choices.length) {
+ index += delta;
+ var choice = $(choices[index]);
+ if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled") && !choice.hasClass("select2-selected")) {
+ this.highlight(index);
+ break;
+ }
+ }
+ },
+
+ // abstract
+ highlight: function (index) {
+ var choices = this.findHighlightableChoices(),
+ choice,
+ data;
+
+ if (arguments.length === 0) {
+ return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
+ }
+
+ if (index >= choices.length) index = choices.length - 1;
+ if (index < 0) index = 0;
+
+ this.removeHighlight();
+
+ choice = $(choices[index]);
+ choice.addClass("select2-highlighted");
+
+ // ensure assistive technology can determine the active choice
+ this.search.attr("aria-activedescendant", choice.find(".select2-result-label").attr("id"));
+
+ this.ensureHighlightVisible();
+
+ this.liveRegion.text(choice.text());
+
+ data = choice.data("select2-data");
+ if (data) {
+ this.opts.element.trigger({ type: "select2-highlight", val: this.id(data), choice: data });
+ }
+ },
+
+ removeHighlight: function() {
+ this.results.find(".select2-highlighted").removeClass("select2-highlighted");
+ },
+
+ touchMoved: function() {
+ this._touchMoved = true;
+ },
+
+ clearTouchMoved: function() {
+ this._touchMoved = false;
+ },
+
+ // abstract
+ countSelectableResults: function() {
+ return this.findHighlightableChoices().length;
+ },
+
+ // abstract
+ highlightUnderEvent: function (event) {
+ var el = $(event.target).closest(".select2-result-selectable");
+ if (el.length > 0 && !el.is(".select2-highlighted")) {
+ var choices = this.findHighlightableChoices();
+ this.highlight(choices.index(el));
+ } else if (el.length == 0) {
+ // if we are over an unselectable item remove all highlights
+ this.removeHighlight();
+ }
+ },
+
+ // abstract
+ loadMoreIfNeeded: function () {
+ var results = this.results,
+ more = results.find("li.select2-more-results"),
+ below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible
+ page = this.resultsPage + 1,
+ self=this,
+ term=this.search.val(),
+ context=this.context;
+
+ if (more.length === 0) return;
+ below = more.offset().top - results.offset().top - results.height();
+
+ if (below <= this.opts.loadMorePadding) {
+ more.addClass("select2-active");
+ this.opts.query({
+ element: this.opts.element,
+ term: term,
+ page: page,
+ context: context,
+ matcher: this.opts.matcher,
+ callback: this.bind(function (data) {
+
+ // ignore a response if the select2 has been closed before it was received
+ if (!self.opened()) return;
+
+
+ self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
+ self.postprocessResults(data, false, false);
+
+ if (data.more===true) {
+ more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore, page+1));
+ window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
+ } else {
+ more.remove();
+ }
+ self.positionDropdown();
+ self.resultsPage = page;
+ self.context = data.context;
+ this.opts.element.trigger({ type: "select2-loaded", items: data });
+ })});
+ }
+ },
+
+ /**
+ * Default tokenizer function which does nothing
+ */
+ tokenize: function() {
+
+ },
+
+ /**
+ * @param initial whether or not this is the call to this method right after the dropdown has been opened
+ */
+ // abstract
+ updateResults: function (initial) {
+ var search = this.search,
+ results = this.results,
+ opts = this.opts,
+ data,
+ self = this,
+ input,
+ term = search.val(),
+ lastTerm = $.data(this.container, "select2-last-term"),
+ // sequence number used to drop out-of-order responses
+ queryNumber;
+
+ // prevent duplicate queries against the same term
+ if (initial !== true && lastTerm && equal(term, lastTerm)) return;
+
+ $.data(this.container, "select2-last-term", term);
+
+ // if the search is currently hidden we do not alter the results
+ if (initial !== true && (this.showSearchInput === false || !this.opened())) {
+ return;
+ }
+
+ function postRender() {
+ search.removeClass("select2-active");
+ self.positionDropdown();
+ if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) {
+ self.liveRegion.text(results.text());
+ }
+ else {
+ self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable').length));
+ }
+ }
+
+ function render(html) {
+ results.html(html);
+ postRender();
+ }
+
+ queryNumber = ++this.queryCount;
+
+ var maxSelSize = this.getMaximumSelectionSize();
+ if (maxSelSize >=1) {
+ data = this.data();
+ if ($.isArray(data) && data.length >= maxSelSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
+ render("<li class='select2-selection-limit'>" + evaluate(opts.formatSelectionTooBig, maxSelSize) + "</li>");
+ return;
+ }
+ }
+
+ if (search.val().length < opts.minimumInputLength) {
+ if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
+ render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooShort, search.val(), opts.minimumInputLength) + "</li>");
+ } else {
+ render("");
+ }
+ if (initial && this.showSearch) this.showSearch(true);
+ return;
+ }
+
+ if (opts.maximumInputLength && search.val().length > opts.maximumInputLength) {
+ if (checkFormatter(opts.formatInputTooLong, "formatInputTooLong")) {
+ render("<li class='select2-no-results'>" + evaluate(opts.formatInputTooLong, search.val(), opts.maximumInputLength) + "</li>");
+ } else {
+ render("");
+ }
+ return;
+ }
+
+ if (opts.formatSearching && this.findHighlightableChoices().length === 0) {
+ render("<li class='select2-searching'>" + evaluate(opts.formatSearching) + "</li>");
+ }
+
+ search.addClass("select2-active");
+
+ this.removeHighlight();
+
+ // give the tokenizer a chance to pre-process the input
+ input = this.tokenize();
+ if (input != undefined && input != null) {
+ search.val(input);
+ }
+
+ this.resultsPage = 1;
+
+ opts.query({
+ element: opts.element,
+ term: search.val(),
+ page: this.resultsPage,
+ context: null,
+ matcher: opts.matcher,
+ callback: this.bind(function (data) {
+ var def; // default choice
+
+ // ignore old responses
+ if (queryNumber != this.queryCount) {
+ return;
+ }
+
+ // ignore a response if the select2 has been closed before it was received
+ if (!this.opened()) {
+ this.search.removeClass("select2-active");
+ return;
+ }
+
+ // save context, if any
+ this.context = (data.context===undefined) ? null : data.context;
+ // create a default choice and prepend it to the list
+ if (this.opts.createSearchChoice && search.val() !== "") {
+ def = this.opts.createSearchChoice.call(self, search.val(), data.results);
+ if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
+ if ($(data.results).filter(
+ function () {
+ return equal(self.id(this), self.id(def));
+ }).length === 0) {
+ this.opts.createSearchChoicePosition(data.results, def);
+ }
+ }
+ }
+
+ if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
+ render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, search.val()) + "</li>");
+ return;
+ }
+
+ results.empty();
+ self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null});
+
+ if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
+ results.append("<li class='select2-more-results'>" + self.opts.escapeMarkup(evaluate(opts.formatLoadMore, this.resultsPage)) + "</li>");
+ window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
+ }
+
+ this.postprocessResults(data, initial);
+
+ postRender();
+
+ this.opts.element.trigger({ type: "select2-loaded", items: data });
+ })});
+ },
+
+ // abstract
+ cancel: function () {
+ this.close();
+ },
+
+ // abstract
+ blur: function () {
+ // if selectOnBlur == true, select the currently highlighted option
+ if (this.opts.selectOnBlur)
+ this.selectHighlighted({noFocus: true});
+
+ this.close();
+ this.container.removeClass("select2-container-active");
+ // synonymous to .is(':focus'), which is available in jquery >= 1.6
+ if (this.search[0] === document.activeElement) { this.search.blur(); }
+ this.clearSearch();
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
+ },
+
+ // abstract
+ focusSearch: function () {
+ focus(this.search);
+ },
+
+ // abstract
+ selectHighlighted: function (options) {
+ if (this._touchMoved) {
+ this.clearTouchMoved();
+ return;
+ }
+ var index=this.highlight(),
+ highlighted=this.results.find(".select2-highlighted"),
+ data = highlighted.closest('.select2-result').data("select2-data");
+
+ if (data) {
+ this.highlight(index);
+ this.onSelect(data, options);
+ } else if (options && options.noFocus) {
+ this.close();
+ }
+ },
+
+ // abstract
+ getPlaceholder: function () {
+ var placeholderOption;
+ return this.opts.element.attr("placeholder") ||
+ this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
+ this.opts.element.data("placeholder") ||
+ this.opts.placeholder ||
+ ((placeholderOption = this.getPlaceholderOption()) !== undefined ? placeholderOption.text() : undefined);
+ },
+
+ // abstract
+ getPlaceholderOption: function() {
+ if (this.select) {
+ var firstOption = this.select.children('option').first();
+ if (this.opts.placeholderOption !== undefined ) {
+ //Determine the placeholder option based on the specified placeholderOption setting
+ return (this.opts.placeholderOption === "first" && firstOption) ||
+ (typeof this.opts.placeholderOption === "function" && this.opts.placeholderOption(this.select));
+ } else if ($.trim(firstOption.text()) === "" && firstOption.val() === "") {
+ //No explicit placeholder option specified, use the first if it's blank
+ return firstOption;
+ }
+ }
+ },
+
+ /**
+ * Get the desired width for the container element. This is
+ * derived first from option `width` passed to select2, then
+ * the inline 'style' on the original element, and finally
+ * falls back to the jQuery calculated element width.
+ */
+ // abstract
+ initContainerWidth: function () {
+ function resolveContainerWidth() {
+ var style, attrs, matches, i, l, attr;
+
+ if (this.opts.width === "off") {
+ return null;
+ } else if (this.opts.width === "element"){
+ return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
+ } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
+ // check if there is inline style on the element that contains width
+ style = this.opts.element.attr('style');
+ if (style !== undefined) {
+ attrs = style.split(';');
+ for (i = 0, l = attrs.length; i < l; i = i + 1) {
+ attr = attrs[i].replace(/\s/g, '');
+ matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
+ if (matches !== null && matches.length >= 1)
+ return matches[1];
+ }
+ }
+
+ if (this.opts.width === "resolve") {
+ // next check if css('width') can resolve a width that is percent based, this is sometimes possible
+ // when attached to input type=hidden or elements hidden via css
+ style = this.opts.element.css('width');
+ if (style.indexOf("%") > 0) return style;
+
+ // finally, fallback on the calculated width of the element
+ return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
+ }
+
+ return null;
+ } else if ($.isFunction(this.opts.width)) {
+ return this.opts.width();
+ } else {
+ return this.opts.width;
+ }
+ };
+
+ var width = resolveContainerWidth.call(this);
+ if (width !== null) {
+ this.container.css("width", width);
+ }
+ }
+ });
+
+ SingleSelect2 = clazz(AbstractSelect2, {
+
+ // single
+
+ createContainer: function () {
+ var container = $(document.createElement("div")).attr({
+ "class": "select2-container"
+ }).html([
+ "<a href='javascript:void(0)' class='select2-choice' tabindex='-1'>",
+ " <span class='select2-chosen'>&#160;</span><abbr class='select2-search-choice-close'></abbr>",
+ " <span class='select2-arrow' role='presentation'><b role='presentation'></b></span>",
+ "</a>",
+ "<label for='' class='select2-offscreen'></label>",
+ "<input class='select2-focusser select2-offscreen' type='text' aria-haspopup='true' role='button' />",
+ "<div class='select2-drop select2-display-none'>",
+ " <div class='select2-search'>",
+ " <label for='' class='select2-offscreen'></label>",
+ " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input' role='combobox' aria-expanded='true'",
+ " aria-autocomplete='list' />",
+ " </div>",
+ " <ul class='select2-results' role='listbox'>",
+ " </ul>",
+ "</div>"].join(""));
+ return container;
+ },
+
+ // single
+ enableInterface: function() {
+ if (this.parent.enableInterface.apply(this, arguments)) {
+ this.focusser.prop("disabled", !this.isInterfaceEnabled());
+ }
+ },
+
+ // single
+ opening: function () {
+ var el, range, len;
+
+ if (this.opts.minimumResultsForSearch >= 0) {
+ this.showSearch(true);
+ }
+
+ this.parent.opening.apply(this, arguments);
+
+ if (this.showSearchInput !== false) {
+ // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range
+ // all other browsers handle this just fine
+
+ this.search.val(this.focusser.val());
+ }
+ if (this.opts.shouldFocusInput(this)) {
+ this.search.focus();
+ // move the cursor to the end after focussing, otherwise it will be at the beginning and
+ // new text will appear *before* focusser.val()
+ el = this.search.get(0);
+ if (el.createTextRange) {
+ range = el.createTextRange();
+ range.collapse(false);
+ range.select();
+ } else if (el.setSelectionRange) {
+ len = this.search.val().length;
+ el.setSelectionRange(len, len);
+ }
+ }
+
+ // initializes search's value with nextSearchTerm (if defined by user)
+ // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
+ if(this.search.val() === "") {
+ if(this.nextSearchTerm != undefined){
+ this.search.val(this.nextSearchTerm);
+ this.search.select();
+ }
+ }
+
+ this.focusser.prop("disabled", true).val("");
+ this.updateResults(true);
+ this.opts.element.trigger($.Event("select2-open"));
+ },
+
+ // single
+ close: function () {
+ if (!this.opened()) return;
+ this.parent.close.apply(this, arguments);
+
+ this.focusser.prop("disabled", false);
+
+ if (this.opts.shouldFocusInput(this)) {
+ this.focusser.focus();
+ }
+ },
+
+ // single
+ focus: function () {
+ if (this.opened()) {
+ this.close();
+ } else {
+ this.focusser.prop("disabled", false);
+ if (this.opts.shouldFocusInput(this)) {
+ this.focusser.focus();
+ }
+ }
+ },
+
+ // single
+ isFocused: function () {
+ return this.container.hasClass("select2-container-active");
+ },
+
+ // single
+ cancel: function () {
+ this.parent.cancel.apply(this, arguments);
+ this.focusser.prop("disabled", false);
+
+ if (this.opts.shouldFocusInput(this)) {
+ this.focusser.focus();
+ }
+ },
+
+ // single
+ destroy: function() {
+ $("label[for='" + this.focusser.attr('id') + "']")
+ .attr('for', this.opts.element.attr("id"));
+ this.parent.destroy.apply(this, arguments);
+
+ cleanupJQueryElements.call(this,
+ "selection",
+ "focusser"
+ );
+ },
+
+ // single
+ initContainer: function () {
+
+ var selection,
+ container = this.container,
+ dropdown = this.dropdown,
+ idSuffix = nextUid(),
+ elementLabel;
+
+ if (this.opts.minimumResultsForSearch < 0) {
+ this.showSearch(false);
+ } else {
+ this.showSearch(true);
+ }
+
+ this.selection = selection = container.find(".select2-choice");
+
+ this.focusser = container.find(".select2-focusser");
+
+ // add aria associations
+ selection.find(".select2-chosen").attr("id", "select2-chosen-"+idSuffix);
+ this.focusser.attr("aria-labelledby", "select2-chosen-"+idSuffix);
+ this.results.attr("id", "select2-results-"+idSuffix);
+ this.search.attr("aria-owns", "select2-results-"+idSuffix);
+
+ // rewrite labels from original element to focusser
+ this.focusser.attr("id", "s2id_autogen"+idSuffix);
+
+ elementLabel = $("label[for='" + this.opts.element.attr("id") + "']");
+
+ this.focusser.prev()
+ .text(elementLabel.text())
+ .attr('for', this.focusser.attr('id'));
+
+ // Ensure the original element retains an accessible name
+ var originalTitle = this.opts.element.attr("title");
+ this.opts.element.attr("title", (originalTitle || elementLabel.text()));
+
+ this.focusser.attr("tabindex", this.elementTabIndex);
+
+ // write label for search field using the label from the focusser element
+ this.search.attr("id", this.focusser.attr('id') + '_search');
+
+ this.search.prev()
+ .text($("label[for='" + this.focusser.attr('id') + "']").text())
+ .attr('for', this.search.attr('id'));
+
+ this.search.on("keydown", this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
+ // prevent the page from scrolling
+ killEvent(e);
+ return;
+ }
+
+ switch (e.which) {
+ case KEY.UP:
+ case KEY.DOWN:
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
+ killEvent(e);
+ return;
+ case KEY.ENTER:
+ this.selectHighlighted();
+ killEvent(e);
+ return;
+ case KEY.TAB:
+ this.selectHighlighted({noFocus: true});
+ return;
+ case KEY.ESC:
+ this.cancel(e);
+ killEvent(e);
+ return;
+ }
+ }));
+
+ this.search.on("blur", this.bind(function(e) {
+ // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
+ // without this the search field loses focus which is annoying
+ if (document.activeElement === this.body.get(0)) {
+ window.setTimeout(this.bind(function() {
+ if (this.opened()) {
+ this.search.focus();
+ }
+ }), 0);
+ }
+ }));
+
+ this.focusser.on("keydown", this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
+ return;
+ }
+
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
+ killEvent(e);
+ return;
+ }
+
+ if (e.which == KEY.DOWN || e.which == KEY.UP
+ || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
+
+ if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;
+
+ this.open();
+ killEvent(e);
+ return;
+ }
+
+ if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
+ if (this.opts.allowClear) {
+ this.clear();
+ }
+ killEvent(e);
+ return;
+ }
+ }));
+
+
+ installKeyUpChangeEvent(this.focusser);
+ this.focusser.on("keyup-change input", this.bind(function(e) {
+ if (this.opts.minimumResultsForSearch >= 0) {
+ e.stopPropagation();
+ if (this.opened()) return;
+ this.open();
+ }
+ }));
+
+ selection.on("mousedown touchstart", "abbr", this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+ this.clear();
+ killEventImmediately(e);
+ this.close();
+ this.selection.focus();
+ }));
+
+ selection.on("mousedown touchstart", this.bind(function (e) {
+ // Prevent IE from generating a click event on the body
+ reinsertElement(selection);
+
+ if (!this.container.hasClass("select2-container-active")) {
+ this.opts.element.trigger($.Event("select2-focus"));
+ }
+
+ if (this.opened()) {
+ this.close();
+ } else if (this.isInterfaceEnabled()) {
+ this.open();
+ }
+
+ killEvent(e);
+ }));
+
+ dropdown.on("mousedown touchstart", this.bind(function() {
+ if (this.opts.shouldFocusInput(this)) {
+ this.search.focus();
+ }
+ }));
+
+ selection.on("focus", this.bind(function(e) {
+ killEvent(e);
+ }));
+
+ this.focusser.on("focus", this.bind(function(){
+ if (!this.container.hasClass("select2-container-active")) {
+ this.opts.element.trigger($.Event("select2-focus"));
+ }
+ this.container.addClass("select2-container-active");
+ })).on("blur", this.bind(function() {
+ if (!this.opened()) {
+ this.container.removeClass("select2-container-active");
+ this.opts.element.trigger($.Event("select2-blur"));
+ }
+ }));
+ this.search.on("focus", this.bind(function(){
+ if (!this.container.hasClass("select2-container-active")) {
+ this.opts.element.trigger($.Event("select2-focus"));
+ }
+ this.container.addClass("select2-container-active");
+ }));
+
+ this.initContainerWidth();
+ this.opts.element.addClass("select2-offscreen");
+ this.setPlaceholder();
+
+ },
+
+ // single
+ clear: function(triggerChange) {
+ var data=this.selection.data("select2-data");
+ if (data) { // guard against queued quick consecutive clicks
+ var evt = $.Event("select2-clearing");
+ this.opts.element.trigger(evt);
+ if (evt.isDefaultPrevented()) {
+ return;
+ }
+ var placeholderOption = this.getPlaceholderOption();
+ this.opts.element.val(placeholderOption ? placeholderOption.val() : "");
+ this.selection.find(".select2-chosen").empty();
+ this.selection.removeData("select2-data");
+ this.setPlaceholder();
+
+ if (triggerChange !== false){
+ this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
+ this.triggerChange({removed:data});
+ }
+ }
+ },
+
+ /**
+ * Sets selection based on source element's value
+ */
+ // single
+ initSelection: function () {
+ var selected;
+ if (this.isPlaceholderOptionSelected()) {
+ this.updateSelection(null);
+ this.close();
+ this.setPlaceholder();
+ } else {
+ var self = this;
+ this.opts.initSelection.call(null, this.opts.element, function(selected){
+ if (selected !== undefined && selected !== null) {
+ self.updateSelection(selected);
+ self.close();
+ self.setPlaceholder();
+ self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());
+ }
+ });
+ }
+ },
+
+ isPlaceholderOptionSelected: function() {
+ var placeholderOption;
+ if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered
+ return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop("selected"))
+ || (this.opts.element.val() === "")
+ || (this.opts.element.val() === undefined)
+ || (this.opts.element.val() === null);
+ },
+
+ // single
+ prepareOpts: function () {
+ var opts = this.parent.prepareOpts.apply(this, arguments),
+ self=this;
+
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
+ // install the selection initializer
+ opts.initSelection = function (element, callback) {
+ var selected = element.find("option").filter(function() { return this.selected && !this.disabled });
+ // a single select box always has a value, no need to null check 'selected'
+ callback(self.optionToData(selected));
+ };
+ } else if ("data" in opts) {
+ // install default initSelection when applied to hidden input and data is local
+ opts.initSelection = opts.initSelection || function (element, callback) {
+ var id = element.val();
+ //search in data by id, storing the actual matching item
+ var match = null;
+ opts.query({
+ matcher: function(term, text, el){
+ var is_match = equal(id, opts.id(el));
+ if (is_match) {
+ match = el;
+ }
+ return is_match;
+ },
+ callback: !$.isFunction(callback) ? $.noop : function() {
+ callback(match);
+ }
+ });
+ };
+ }
+
+ return opts;
+ },
+
+ // single
+ getPlaceholder: function() {
+ // if a placeholder is specified on a single select without a valid placeholder option ignore it
+ if (this.select) {
+ if (this.getPlaceholderOption() === undefined) {
+ return undefined;
+ }
+ }
+
+ return this.parent.getPlaceholder.apply(this, arguments);
+ },
+
+ // single
+ setPlaceholder: function () {
+ var placeholder = this.getPlaceholder();
+
+ if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {
+
+ // check for a placeholder option if attached to a select
+ if (this.select && this.getPlaceholderOption() === undefined) return;
+
+ this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder));
+
+ this.selection.addClass("select2-default");
+
+ this.container.removeClass("select2-allowclear");
+ }
+ },
+
+ // single
+ postprocessResults: function (data, initial, noHighlightUpdate) {
+ var selected = 0, self = this, showSearchInput = true;
+
+ // find the selected element in the result list
+
+ this.findHighlightableChoices().each2(function (i, elm) {
+ if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
+ selected = i;
+ return false;
+ }
+ });
+
+ // and highlight it
+ if (noHighlightUpdate !== false) {
+ if (initial === true && selected >= 0) {
+ this.highlight(selected);
+ } else {
+ this.highlight(0);
+ }
+ }
+
+ // hide the search box if this is the first we got the results and there are enough of them for search
+
+ if (initial === true) {
+ var min = this.opts.minimumResultsForSearch;
+ if (min >= 0) {
+ this.showSearch(countResults(data.results) >= min);
+ }
+ }
+ },
+
+ // single
+ showSearch: function(showSearchInput) {
+ if (this.showSearchInput === showSearchInput) return;
+
+ this.showSearchInput = showSearchInput;
+
+ this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput);
+ this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput);
+ //add "select2-with-searchbox" to the container if search box is shown
+ $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput);
+ },
+
+ // single
+ onSelect: function (data, options) {
+
+ if (!this.triggerSelect(data)) { return; }
+
+ var old = this.opts.element.val(),
+ oldData = this.data();
+
+ this.opts.element.val(this.id(data));
+ this.updateSelection(data);
+
+ this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
+
+ this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
+ this.close();
+
+ if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {
+ this.focusser.focus();
+ }
+
+ if (!equal(old, this.id(data))) {
+ this.triggerChange({ added: data, removed: oldData });
+ }
+ },
+
+ // single
+ updateSelection: function (data) {
+
+ var container=this.selection.find(".select2-chosen"), formatted, cssClass;
+
+ this.selection.data("select2-data", data);
+
+ container.empty();
+ if (data !== null) {
+ formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);
+ }
+ if (formatted !== undefined) {
+ container.append(formatted);
+ }
+ cssClass=this.opts.formatSelectionCssClass(data, container);
+ if (cssClass !== undefined) {
+ container.addClass(cssClass);
+ }
+
+ this.selection.removeClass("select2-default");
+
+ if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
+ this.container.addClass("select2-allowclear");
+ }
+ },
+
+ // single
+ val: function () {
+ var val,
+ triggerChange = false,
+ data = null,
+ self = this,
+ oldData = this.data();
+
+ if (arguments.length === 0) {
+ return this.opts.element.val();
+ }
+
+ val = arguments[0];
+
+ if (arguments.length > 1) {
+ triggerChange = arguments[1];
+ }
+
+ if (this.select) {
+ this.select
+ .val(val)
+ .find("option").filter(function() { return this.selected }).each2(function (i, elm) {
+ data = self.optionToData(elm);
+ return false;
+ });
+ this.updateSelection(data);
+ this.setPlaceholder();
+ if (triggerChange) {
+ this.triggerChange({added: data, removed:oldData});
+ }
+ } else {
+ // val is an id. !val is true for [undefined,null,'',0] - 0 is legal
+ if (!val && val !== 0) {
+ this.clear(triggerChange);
+ return;
+ }
+ if (this.opts.initSelection === undefined) {
+ throw new Error("cannot call val() if initSelection() is not defined");
+ }
+ this.opts.element.val(val);
+ this.opts.initSelection(this.opts.element, function(data){
+ self.opts.element.val(!data ? "" : self.id(data));
+ self.updateSelection(data);
+ self.setPlaceholder();
+ if (triggerChange) {
+ self.triggerChange({added: data, removed:oldData});
+ }
+ });
+ }
+ },
+
+ // single
+ clearSearch: function () {
+ this.search.val("");
+ this.focusser.val("");
+ },
+
+ // single
+ data: function(value) {
+ var data,
+ triggerChange = false;
+
+ if (arguments.length === 0) {
+ data = this.selection.data("select2-data");
+ if (data == undefined) data = null;
+ return data;
+ } else {
+ if (arguments.length > 1) {
+ triggerChange = arguments[1];
+ }
+ if (!value) {
+ this.clear(triggerChange);
+ } else {
+ data = this.data();
+ this.opts.element.val(!value ? "" : this.id(value));
+ this.updateSelection(value);
+ if (triggerChange) {
+ this.triggerChange({added: value, removed:data});
+ }
+ }
+ }
+ }
+ });
+
+ MultiSelect2 = clazz(AbstractSelect2, {
+
+ // multi
+ createContainer: function () {
+ var container = $(document.createElement("div")).attr({
+ "class": "select2-container select2-container-multi"
+ }).html([
+ "<ul class='select2-choices'>",
+ " <li class='select2-search-field'>",
+ " <label for='' class='select2-offscreen'></label>",
+ " <input type='text' autocomplete='off' autocorrect='off' autocapitalize='off' spellcheck='false' class='select2-input'>",
+ " </li>",
+ "</ul>",
+ "<div class='select2-drop select2-drop-multi select2-display-none'>",
+ " <ul class='select2-results'>",
+ " </ul>",
+ "</div>"].join(""));
+ return container;
+ },
+
+ // multi
+ prepareOpts: function () {
+ var opts = this.parent.prepareOpts.apply(this, arguments),
+ self=this;
+
+ // TODO validate placeholder is a string if specified
+
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
+ // install the selection initializer
+ opts.initSelection = function (element, callback) {
+
+ var data = [];
+
+ element.find("option").filter(function() { return this.selected && !this.disabled }).each2(function (i, elm) {
+ data.push(self.optionToData(elm));
+ });
+ callback(data);
+ };
+ } else if ("data" in opts) {
+ // install default initSelection when applied to hidden input and data is local
+ opts.initSelection = opts.initSelection || function (element, callback) {
+ var ids = splitVal(element.val(), opts.separator);
+ //search in data by array of ids, storing matching items in a list
+ var matches = [];
+ opts.query({
+ matcher: function(term, text, el){
+ var is_match = $.grep(ids, function(id) {
+ return equal(id, opts.id(el));
+ }).length;
+ if (is_match) {
+ matches.push(el);
+ }
+ return is_match;
+ },
+ callback: !$.isFunction(callback) ? $.noop : function() {
+ // reorder matches based on the order they appear in the ids array because right now
+ // they are in the order in which they appear in data array
+ var ordered = [];
+ for (var i = 0; i < ids.length; i++) {
+ var id = ids[i];
+ for (var j = 0; j < matches.length; j++) {
+ var match = matches[j];
+ if (equal(id, opts.id(match))) {
+ ordered.push(match);
+ matches.splice(j, 1);
+ break;
+ }
+ }
+ }
+ callback(ordered);
+ }
+ });
+ };
+ }
+
+ return opts;
+ },
+
+ // multi
+ selectChoice: function (choice) {
+
+ var selected = this.container.find(".select2-search-choice-focus");
+ if (selected.length && choice && choice[0] == selected[0]) {
+
+ } else {
+ if (selected.length) {
+ this.opts.element.trigger("choice-deselected", selected);
+ }
+ selected.removeClass("select2-search-choice-focus");
+ if (choice && choice.length) {
+ this.close();
+ choice.addClass("select2-search-choice-focus");
+ this.opts.element.trigger("choice-selected", choice);
+ }
+ }
+ },
+
+ // multi
+ destroy: function() {
+ $("label[for='" + this.search.attr('id') + "']")
+ .attr('for', this.opts.element.attr("id"));
+ this.parent.destroy.apply(this, arguments);
+
+ cleanupJQueryElements.call(this,
+ "searchContainer",
+ "selection"
+ );
+ },
+
+ // multi
+ initContainer: function () {
+
+ var selector = ".select2-choices", selection;
+
+ this.searchContainer = this.container.find(".select2-search-field");
+ this.selection = selection = this.container.find(selector);
+
+ var _this = this;
+ this.selection.on("click", ".select2-search-choice:not(.select2-locked)", function (e) {
+ //killEvent(e);
+ _this.search[0].focus();
+ _this.selectChoice($(this));
+ });
+
+ // rewrite labels from original element to focusser
+ this.search.attr("id", "s2id_autogen"+nextUid());
+
+ this.search.prev()
+ .text($("label[for='" + this.opts.element.attr("id") + "']").text())
+ .attr('for', this.search.attr('id'));
+
+ this.search.on("input paste", this.bind(function() {
+ if (!this.isInterfaceEnabled()) return;
+ if (!this.opened()) {
+ this.open();
+ }
+ }));
+
+ this.search.attr("tabindex", this.elementTabIndex);
+
+ this.keydowns = 0;
+ this.search.on("keydown", this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+
+ ++this.keydowns;
+ var selected = selection.find(".select2-search-choice-focus");
+ var prev = selected.prev(".select2-search-choice:not(.select2-locked)");
+ var next = selected.next(".select2-search-choice:not(.select2-locked)");
+ var pos = getCursorInfo(this.search);
+
+ if (selected.length &&
+ (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) {
+ var selectedChoice = selected;
+ if (e.which == KEY.LEFT && prev.length) {
+ selectedChoice = prev;
+ }
+ else if (e.which == KEY.RIGHT) {
+ selectedChoice = next.length ? next : null;
+ }
+ else if (e.which === KEY.BACKSPACE) {
+ if (this.unselect(selected.first())) {
+ this.search.width(10);
+ selectedChoice = prev.length ? prev : next;
+ }
+ } else if (e.which == KEY.DELETE) {
+ if (this.unselect(selected.first())) {
+ this.search.width(10);
+ selectedChoice = next.length ? next : null;
+ }
+ } else if (e.which == KEY.ENTER) {
+ selectedChoice = null;
+ }
+
+ this.selectChoice(selectedChoice);
+ killEvent(e);
+ if (!selectedChoice || !selectedChoice.length) {
+ this.open();
+ }
+ return;
+ } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1)
+ || e.which == KEY.LEFT) && (pos.offset == 0 && !pos.length)) {
+
+ this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last());
+ killEvent(e);
+ return;
+ } else {
+ this.selectChoice(null);
+ }
+
+ if (this.opened()) {
+ switch (e.which) {
+ case KEY.UP:
+ case KEY.DOWN:
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
+ killEvent(e);
+ return;
+ case KEY.ENTER:
+ this.selectHighlighted();
+ killEvent(e);
+ return;
+ case KEY.TAB:
+ this.selectHighlighted({noFocus:true});
+ this.close();
+ return;
+ case KEY.ESC:
+ this.cancel(e);
+ killEvent(e);
+ return;
+ }
+ }
+
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e)
+ || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
+ return;
+ }
+
+ if (e.which === KEY.ENTER) {
+ if (this.opts.openOnEnter === false) {
+ return;
+ } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {
+ return;
+ }
+ }
+
+ this.open();
+
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
+ // prevent the page from scrolling
+ killEvent(e);
+ }
+
+ if (e.which === KEY.ENTER) {
+ // prevent form from being submitted
+ killEvent(e);
+ }
+
+ }));
+
+ this.search.on("keyup", this.bind(function (e) {
+ this.keydowns = 0;
+ this.resizeSearch();
+ })
+ );
+
+ this.search.on("blur", this.bind(function(e) {
+ this.container.removeClass("select2-container-active");
+ this.search.removeClass("select2-focused");
+ this.selectChoice(null);
+ if (!this.opened()) this.clearSearch();
+ e.stopImmediatePropagation();
+ this.opts.element.trigger($.Event("select2-blur"));
+ }));
+
+ this.container.on("click", selector, this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+ if ($(e.target).closest(".select2-search-choice").length > 0) {
+ // clicked inside a select2 search choice, do not open
+ return;
+ }
+ this.selectChoice(null);
+ this.clearPlaceholder();
+ if (!this.container.hasClass("select2-container-active")) {
+ this.opts.element.trigger($.Event("select2-focus"));
+ }
+ this.open();
+ this.focusSearch();
+ e.preventDefault();
+ }));
+
+ this.container.on("focus", selector, this.bind(function () {
+ if (!this.isInterfaceEnabled()) return;
+ if (!this.container.hasClass("select2-container-active")) {
+ this.opts.element.trigger($.Event("select2-focus"));
+ }
+ this.container.addClass("select2-container-active");
+ this.dropdown.addClass("select2-drop-active");
+ this.clearPlaceholder();
+ }));
+
+ this.initContainerWidth();
+ this.opts.element.addClass("select2-offscreen");
+
+ // set the placeholder if necessary
+ this.clearSearch();
+ },
+
+ // multi
+ enableInterface: function() {
+ if (this.parent.enableInterface.apply(this, arguments)) {
+ this.search.prop("disabled", !this.isInterfaceEnabled());
+ }
+ },
+
+ // multi
+ initSelection: function () {
+ var data;
+ if (this.opts.element.val() === "" && this.opts.element.text() === "") {
+ this.updateSelection([]);
+ this.close();
+ // set the placeholder if necessary
+ this.clearSearch();
+ }
+ if (this.select || this.opts.element.val() !== "") {
+ var self = this;
+ this.opts.initSelection.call(null, this.opts.element, function(data){
+ if (data !== undefined && data !== null) {
+ self.updateSelection(data);
+ self.close();
+ // set the placeholder if necessary
+ self.clearSearch();
+ }
+ });
+ }
+ },
+
+ // multi
+ clearSearch: function () {
+ var placeholder = this.getPlaceholder(),
+ maxWidth = this.getMaxSearchWidth();
+
+ if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
+ this.search.val(placeholder).addClass("select2-default");
+ // stretch the search box to full width of the container so as much of the placeholder is visible as possible
+ // we could call this.resizeSearch(), but we do not because that requires a sizer and we do not want to create one so early because of a firefox bug, see #944
+ this.search.width(maxWidth > 0 ? maxWidth : this.container.css("width"));
+ } else {
+ this.search.val("").width(10);
+ }
+ },
+
+ // multi
+ clearPlaceholder: function () {
+ if (this.search.hasClass("select2-default")) {
+ this.search.val("").removeClass("select2-default");
+ }
+ },
+
+ // multi
+ opening: function () {
+ this.clearPlaceholder(); // should be done before super so placeholder is not used to search
+ this.resizeSearch();
+
+ this.parent.opening.apply(this, arguments);
+
+ this.focusSearch();
+
+ // initializes search's value with nextSearchTerm (if defined by user)
+ // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
+ if(this.search.val() === "") {
+ if(this.nextSearchTerm != undefined){
+ this.search.val(this.nextSearchTerm);
+ this.search.select();
+ }
+ }
+
+ this.updateResults(true);
+ if (this.opts.shouldFocusInput(this)) {
+ this.search.focus();
+ }
+ this.opts.element.trigger($.Event("select2-open"));
+ },
+
+ // multi
+ close: function () {
+ if (!this.opened()) return;
+ this.parent.close.apply(this, arguments);
+ },
+
+ // multi
+ focus: function () {
+ this.close();
+ this.search.focus();
+ },
+
+ // multi
+ isFocused: function () {
+ return this.search.hasClass("select2-focused");
+ },
+
+ // multi
+ updateSelection: function (data) {
+ var ids = [], filtered = [], self = this;
+
+ // filter out duplicates
+ $(data).each(function () {
+ if (indexOf(self.id(this), ids) < 0) {
+ ids.push(self.id(this));
+ filtered.push(this);
+ }
+ });
+ data = filtered;
+
+ this.selection.find(".select2-search-choice").remove();
+ $(data).each(function () {
+ self.addSelectedChoice(this);
+ });
+ self.postprocessResults();
+ },
+
+ // multi
+ tokenize: function() {
+ var input = this.search.val();
+ input = this.opts.tokenizer.call(this, input, this.data(), this.bind(this.onSelect), this.opts);
+ if (input != null && input != undefined) {
+ this.search.val(input);
+ if (input.length > 0) {
+ this.open();
+ }
+ }
+
+ },
+
+ // multi
+ onSelect: function (data, options) {
+
+ if (!this.triggerSelect(data)) { return; }
+
+ this.addSelectedChoice(data);
+
+ this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
+
+ // keep track of the search's value before it gets cleared
+ this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
+
+ this.clearSearch();
+ this.updateResults();
+
+ if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);
+
+ if (this.opts.closeOnSelect) {
+ this.close();
+ this.search.width(10);
+ } else {
+ if (this.countSelectableResults()>0) {
+ this.search.width(10);
+ this.resizeSearch();
+ if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
+ // if we reached max selection size repaint the results so choices
+ // are replaced with the max selection reached message
+ this.updateResults(true);
+ } else {
+ // initializes search's value with nextSearchTerm and update search result
+ if(this.nextSearchTerm != undefined){
+ this.search.val(this.nextSearchTerm);
+ this.updateResults();
+ this.search.select();
+ }
+ }
+ this.positionDropdown();
+ } else {
+ // if nothing left to select close
+ this.close();
+ this.search.width(10);
+ }
+ }
+
+ // since its not possible to select an element that has already been
+ // added we do not need to check if this is a new element before firing change
+ this.triggerChange({ added: data });
+
+ if (!options || !options.noFocus)
+ this.focusSearch();
+ },
+
+ // multi
+ cancel: function () {
+ this.close();
+ this.focusSearch();
+ },
+
+ addSelectedChoice: function (data) {
+ var enableChoice = !data.locked,
+ enabledItem = $(
+ "<li class='select2-search-choice'>" +
+ " <div></div>" +
+ " <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" +
+ "</li>"),
+ disabledItem = $(
+ "<li class='select2-search-choice select2-locked'>" +
+ "<div></div>" +
+ "</li>");
+ var choice = enableChoice ? enabledItem : disabledItem,
+ id = this.id(data),
+ val = this.getVal(),
+ formatted,
+ cssClass;
+
+ formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup);
+ if (formatted != undefined) {
+ choice.find("div").replaceWith("<div>"+formatted+"</div>");
+ }
+ cssClass=this.opts.formatSelectionCssClass(data, choice.find("div"));
+ if (cssClass != undefined) {
+ choice.addClass(cssClass);
+ }
+
+ if(enableChoice){
+ choice.find(".select2-search-choice-close")
+ .on("mousedown", killEvent)
+ .on("click dblclick", this.bind(function (e) {
+ if (!this.isInterfaceEnabled()) return;
+
+ this.unselect($(e.target));
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
+ killEvent(e);
+ this.close();
+ this.focusSearch();
+ })).on("focus", this.bind(function () {
+ if (!this.isInterfaceEnabled()) return;
+ this.container.addClass("select2-container-active");
+ this.dropdown.addClass("select2-drop-active");
+ }));
+ }
+
+ choice.data("select2-data", data);
+ choice.insertBefore(this.searchContainer);
+
+ val.push(id);
+ this.setVal(val);
+ },
+
+ // multi
+ unselect: function (selected) {
+ var val = this.getVal(),
+ data,
+ index;
+ selected = selected.closest(".select2-search-choice");
+
+ if (selected.length === 0) {
+ throw "Invalid argument: " + selected + ". Must be .select2-search-choice";
+ }
+
+ data = selected.data("select2-data");
+
+ if (!data) {
+ // prevent a race condition when the 'x' is clicked really fast repeatedly the event can be queued
+ // and invoked on an element already removed
+ return;
+ }
+
+ var evt = $.Event("select2-removing");
+ evt.val = this.id(data);
+ evt.choice = data;
+ this.opts.element.trigger(evt);
+
+ if (evt.isDefaultPrevented()) {
+ return false;
+ }
+
+ while((index = indexOf(this.id(data), val)) >= 0) {
+ val.splice(index, 1);
+ this.setVal(val);
+ if (this.select) this.postprocessResults();
+ }
+
+ selected.remove();
+
+ this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data });
+ this.triggerChange({ removed: data });
+
+ return true;
+ },
+
+ // multi
+ postprocessResults: function (data, initial, noHighlightUpdate) {
+ var val = this.getVal(),
+ choices = this.results.find(".select2-result"),
+ compound = this.results.find(".select2-result-with-children"),
+ self = this;
+
+ choices.each2(function (i, choice) {
+ var id = self.id(choice.data("select2-data"));
+ if (indexOf(id, val) >= 0) {
+ choice.addClass("select2-selected");
+ // mark all children of the selected parent as selected
+ choice.find(".select2-result-selectable").addClass("select2-selected");
+ }
+ });
+
+ compound.each2(function(i, choice) {
+ // hide an optgroup if it doesn't have any selectable children
+ if (!choice.is('.select2-result-selectable')
+ && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
+ choice.addClass("select2-selected");
+ }
+ });
+
+ if (this.highlight() == -1 && noHighlightUpdate !== false){
+ self.highlight(0);
+ }
+
+ //If all results are chosen render formatNoMatches
+ if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){
+ if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) {
+ if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) {
+ this.results.append("<li class='select2-no-results'>" + evaluate(self.opts.formatNoMatches, self.search.val()) + "</li>");
+ }
+ }
+ }
+
+ },
+
+ // multi
+ getMaxSearchWidth: function() {
+ return this.selection.width() - getSideBorderPadding(this.search);
+ },
+
+ // multi
+ resizeSearch: function () {
+ var minimumWidth, left, maxWidth, containerLeft, searchWidth,
+ sideBorderPadding = getSideBorderPadding(this.search);
+
+ minimumWidth = measureTextWidth(this.search) + 10;
+
+ left = this.search.offset().left;
+
+ maxWidth = this.selection.width();
+ containerLeft = this.selection.offset().left;
+
+ searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
+
+ if (searchWidth < minimumWidth) {
+ searchWidth = maxWidth - sideBorderPadding;
+ }
+
+ if (searchWidth < 40) {
+ searchWidth = maxWidth - sideBorderPadding;
+ }
+
+ if (searchWidth <= 0) {
+ searchWidth = minimumWidth;
+ }
+
+ this.search.width(Math.floor(searchWidth));
+ },
+
+ // multi
+ getVal: function () {
+ var val;
+ if (this.select) {
+ val = this.select.val();
+ return val === null ? [] : val;
+ } else {
+ val = this.opts.element.val();
+ return splitVal(val, this.opts.separator);
+ }
+ },
+
+ // multi
+ setVal: function (val) {
+ var unique;
+ if (this.select) {
+ this.select.val(val);
+ } else {
+ unique = [];
+ // filter out duplicates
+ $(val).each(function () {
+ if (indexOf(this, unique) < 0) unique.push(this);
+ });
+ this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
+ }
+ },
+
+ // multi
+ buildChangeDetails: function (old, current) {
+ var current = current.slice(0),
+ old = old.slice(0);
+
+ // remove intersection from each array
+ for (var i = 0; i < current.length; i++) {
+ for (var j = 0; j < old.length; j++) {
+ if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
+ current.splice(i, 1);
+ if(i>0){
+ i--;
+ }
+ old.splice(j, 1);
+ j--;
+ }
+ }
+ }
+
+ return {added: current, removed: old};
+ },
+
+
+ // multi
+ val: function (val, triggerChange) {
+ var oldData, self=this;
+
+ if (arguments.length === 0) {
+ return this.getVal();
+ }
+
+ oldData=this.data();
+ if (!oldData.length) oldData=[];
+
+ // val is an id. !val is true for [undefined,null,'',0] - 0 is legal
+ if (!val && val !== 0) {
+ this.opts.element.val("");
+ this.updateSelection([]);
+ this.clearSearch();
+ if (triggerChange) {
+ this.triggerChange({added: this.data(), removed: oldData});
+ }
+ return;
+ }
+
+ // val is a list of ids
+ this.setVal(val);
+
+ if (this.select) {
+ this.opts.initSelection(this.select, this.bind(this.updateSelection));
+ if (triggerChange) {
+ this.triggerChange(this.buildChangeDetails(oldData, this.data()));
+ }
+ } else {
+ if (this.opts.initSelection === undefined) {
+ throw new Error("val() cannot be called if initSelection() is not defined");
+ }
+
+ this.opts.initSelection(this.opts.element, function(data){
+ var ids=$.map(data, self.id);
+ self.setVal(ids);
+ self.updateSelection(data);
+ self.clearSearch();
+ if (triggerChange) {
+ self.triggerChange(self.buildChangeDetails(oldData, self.data()));
+ }
+ });
+ }
+ this.clearSearch();
+ },
+
+ // multi
+ onSortStart: function() {
+ if (this.select) {
+ throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");
+ }
+
+ // collapse search field into 0 width so its container can be collapsed as well
+ this.search.width(0);
+ // hide the container
+ this.searchContainer.hide();
+ },
+
+ // multi
+ onSortEnd:function() {
+
+ var val=[], self=this;
+
+ // show search and move it to the end of the list
+ this.searchContainer.show();
+ // make sure the search container is the last item in the list
+ this.searchContainer.appendTo(this.searchContainer.parent());
+ // since we collapsed the width in dragStarted, we resize it here
+ this.resizeSearch();
+
+ // update selection
+ this.selection.find(".select2-search-choice").each(function() {
+ val.push(self.opts.id($(this).data("select2-data")));
+ });
+ this.setVal(val);
+ this.triggerChange();
+ },
+
+ // multi
+ data: function(values, triggerChange) {
+ var self=this, ids, old;
+ if (arguments.length === 0) {
+ return this.selection
+ .children(".select2-search-choice")
+ .map(function() { return $(this).data("select2-data"); })
+ .get();
+ } else {
+ old = this.data();
+ if (!values) { values = []; }
+ ids = $.map(values, function(e) { return self.opts.id(e); });
+ this.setVal(ids);
+ this.updateSelection(values);
+ this.clearSearch();
+ if (triggerChange) {
+ this.triggerChange(this.buildChangeDetails(old, this.data()));
+ }
+ }
+ }
+ });
+
+ $.fn.select2 = function () {
+
+ var args = Array.prototype.slice.call(arguments, 0),
+ opts,
+ select2,
+ method, value, multiple,
+ allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "disable", "readonly", "positionDropdown", "data", "search"],
+ valueMethods = ["opened", "isFocused", "container", "dropdown"],
+ propertyMethods = ["val", "data"],
+ methodsMap = { search: "externalSearch" };
+
+ this.each(function () {
+ if (args.length === 0 || typeof(args[0]) === "object") {
+ opts = args.length === 0 ? {} : $.extend({}, args[0]);
+ opts.element = $(this);
+
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
+ multiple = opts.element.prop("multiple");
+ } else {
+ multiple = opts.multiple || false;
+ if ("tags" in opts) {opts.multiple = multiple = true;}
+ }
+
+ select2 = multiple ? new window.Select2["class"].multi() : new window.Select2["class"].single();
+ select2.init(opts);
+ } else if (typeof(args[0]) === "string") {
+
+ if (indexOf(args[0], allowedMethods) < 0) {
+ throw "Unknown method: " + args[0];
+ }
+
+ value = undefined;
+ select2 = $(this).data("select2");
+ if (select2 === undefined) return;
+
+ method=args[0];
+
+ if (method === "container") {
+ value = select2.container;
+ } else if (method === "dropdown") {
+ value = select2.dropdown;
+ } else {
+ if (methodsMap[method]) method = methodsMap[method];
+
+ value = select2[method].apply(select2, args.slice(1));
+ }
+ if (indexOf(args[0], valueMethods) >= 0
+ || (indexOf(args[0], propertyMethods) >= 0 && args.length == 1)) {
+ return false; // abort the iteration, ready to return first matched value
+ }
+ } else {
+ throw "Invalid arguments to select2 plugin: " + args;
+ }
+ });
+ return (value === undefined) ? this : value;
+ };
+
+ // plugin defaults, accessible to users
+ $.fn.select2.defaults = {
+ width: "copy",
+ loadMorePadding: 0,
+ closeOnSelect: true,
+ openOnEnter: true,
+ containerCss: {},
+ dropdownCss: {},
+ containerCssClass: "",
+ dropdownCssClass: "",
+ formatResult: function(result, container, query, escapeMarkup) {
+ var markup=[];
+ markMatch(result.text, query.term, markup, escapeMarkup);
+ return markup.join("");
+ },
+ formatSelection: function (data, container, escapeMarkup) {
+ return data ? escapeMarkup(data.text) : undefined;
+ },
+ sortResults: function (results, container, query) {
+ return results;
+ },
+ formatResultCssClass: function(data) {return data.css;},
+ formatSelectionCssClass: function(data, container) {return undefined;},
+ formatMatches: function (matches) { return matches + " results are available, use up and down arrow keys to navigate."; },
+ formatNoMatches: function () { return "No matches found"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1? "" : "s"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1? "" : "s"); },
+ formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Loading more results…"; },
+ formatSearching: function () { return "Searching…"; },
+ minimumResultsForSearch: 0,
+ minimumInputLength: 0,
+ maximumInputLength: null,
+ maximumSelectionSize: 0,
+ id: function (e) { return e == undefined ? null : e.id; },
+ matcher: function(term, text) {
+ return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0;
+ },
+ separator: ",",
+ tokenSeparators: [],
+ tokenizer: defaultTokenizer,
+ escapeMarkup: defaultEscapeMarkup,
+ blurOnChange: false,
+ selectOnBlur: false,
+ adaptContainerCssClass: function(c) { return c; },
+ adaptDropdownCssClass: function(c) { return null; },
+ nextSearchTerm: function(selectedObject, currentSearchTerm) { return undefined; },
+ searchInputPlaceholder: '',
+ createSearchChoicePosition: 'top',
+ shouldFocusInput: function (instance) {
+ // Attempt to detect touch devices
+ var supportsTouchEvents = (('ontouchstart' in window) ||
+ (navigator.msMaxTouchPoints > 0));
+
+ // Only devices which support touch events should be special cased
+ if (!supportsTouchEvents) {
+ return true;
+ }
+
+ // Never focus the input if search is disabled
+ if (instance.opts.minimumResultsForSearch < 0) {
+ return false;
+ }
+
+ return true;
+ }
+ };
+
+ $.fn.select2.ajaxDefaults = {
+ transport: $.ajax,
+ params: {
+ type: "GET",
+ cache: false,
+ dataType: "json"
+ }
+ };
+
+ // exports
+ window.Select2 = {
+ query: {
+ ajax: ajax,
+ local: local,
+ tags: tags
+ }, util: {
+ debounce: debounce,
+ markMatch: markMatch,
+ escapeMarkup: defaultEscapeMarkup,
+ stripDiacritics: stripDiacritics
+ }, "class": {
+ "abstract": AbstractSelect2,
+ "single": SingleSelect2,
+ "multi": MultiSelect2
+ }
+ };
+
+}(jQuery));
diff --git a/apps/files_external/3rdparty/select2/select2.png b/apps/files_external/3rdparty/select2/select2.png
new file mode 100644
index 00000000000..1d804ffb996
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2.png
Binary files differ
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ar.js b/apps/files_external/3rdparty/select2/select2_locale_ar.js
new file mode 100644
index 00000000000..acb33a2f6ad
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ar.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Arabic translation.
+ *
+ * Author: Adel KEDJOUR <adel@kedjour.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "لم يتم العثور على مطابقات"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; if (n == 1){ return "الرجاء إدخال حرف واحد على الأكثر"; } return n == 2 ? "الرجاء إدخال حرفين على الأكثر" : "الرجاء إدخال " + n + " على الأكثر"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; if (n == 1){ return "الرجاء إدخال حرف واحد على الأقل"; } return n == 2 ? "الرجاء إدخال حرفين على الأقل" : "الرجاء إدخال " + n + " على الأقل "; },
+ formatSelectionTooBig: function (limit) { if (n == 1){ return "يمكنك أن تختار إختيار واحد فقط"; } return n == 2 ? "يمكنك أن تختار إختيارين فقط" : "يمكنك أن تختار " + n + " إختيارات فقط"; },
+ formatLoadMore: function (pageNumber) { return "تحميل المزيد من النتائج…"; },
+ formatSearching: function () { return "البحث…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_bg.js b/apps/files_external/3rdparty/select2/select2_locale_bg.js
new file mode 100644
index 00000000000..585d28a2b0b
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_bg.js
@@ -0,0 +1,18 @@
+/**
+ * Select2 Bulgarian translation.
+ *
+ * @author Lubomir Vikev <lubomirvikev@gmail.com>
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Няма намерени съвпадения"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Моля въведете още " + n + " символ" + (n > 1 ? "а" : ""); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Моля въведете с " + n + " по-малко символ" + (n > 1 ? "а" : ""); },
+ formatSelectionTooBig: function (limit) { return "Можете да направите до " + limit + (limit > 1 ? " избора" : " избор"); },
+ formatLoadMore: function (pageNumber) { return "Зареждат се още…"; },
+ formatSearching: function () { return "Търсене…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ca.js b/apps/files_external/3rdparty/select2/select2_locale_ca.js
new file mode 100644
index 00000000000..7e19d3ce966
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ca.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Catalan translation.
+ *
+ * Author: David Planella <david.planella@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "No s'ha trobat cap coincidència"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Introduïu " + n + " caràcter" + (n == 1 ? "" : "s") + " més"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Introduïu " + n + " caràcter" + (n == 1? "" : "s") + "menys"; },
+ formatSelectionTooBig: function (limit) { return "Només podeu seleccionar " + limit + " element" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "S'estan carregant més resultats…"; },
+ formatSearching: function () { return "S'està cercant…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_cs.js b/apps/files_external/3rdparty/select2/select2_locale_cs.js
new file mode 100644
index 00000000000..376b54a1352
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_cs.js
@@ -0,0 +1,49 @@
+/**
+ * Select2 Czech translation.
+ *
+ * Author: Michal Marek <ahoj@michal-marek.cz>
+ * Author - sklonovani: David Vallner <david@vallner.net>
+ */
+(function ($) {
+ "use strict";
+ // use text for the numbers 2 through 4
+ var smallNumbers = {
+ 2: function(masc) { return (masc ? "dva" : "dvě"); },
+ 3: function() { return "tři"; },
+ 4: function() { return "čtyři"; }
+ }
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nenalezeny žádné položky"; },
+ formatInputTooShort: function (input, min) {
+ var n = min - input.length;
+ if (n == 1) {
+ return "Prosím zadejte ještě jeden znak";
+ } else if (n <= 4) {
+ return "Prosím zadejte ještě další "+smallNumbers[n](true)+" znaky";
+ } else {
+ return "Prosím zadejte ještě dalších "+n+" znaků";
+ }
+ },
+ formatInputTooLong: function (input, max) {
+ var n = input.length - max;
+ if (n == 1) {
+ return "Prosím zadejte o jeden znak méně";
+ } else if (n <= 4) {
+ return "Prosím zadejte o "+smallNumbers[n](true)+" znaky méně";
+ } else {
+ return "Prosím zadejte o "+n+" znaků méně";
+ }
+ },
+ formatSelectionTooBig: function (limit) {
+ if (limit == 1) {
+ return "Můžete zvolit jen jednu položku";
+ } else if (limit <= 4) {
+ return "Můžete zvolit maximálně "+smallNumbers[limit](false)+" položky";
+ } else {
+ return "Můžete zvolit maximálně "+limit+" položek";
+ }
+ },
+ formatLoadMore: function (pageNumber) { return "Načítají se další výsledky…"; },
+ formatSearching: function () { return "Vyhledávání…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_da.js b/apps/files_external/3rdparty/select2/select2_locale_da.js
new file mode 100644
index 00000000000..dbce3e1748d
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_da.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Danish translation.
+ *
+ * Author: Anders Jenbo <anders@jenbo.dk>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Ingen resultater fundet"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Angiv venligst " + n + " tegn mere"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Angiv venligst " + n + " tegn mindre"; },
+ formatSelectionTooBig: function (limit) { return "Du kan kun vælge " + limit + " emne" + (limit === 1 ? "" : "r"); },
+ formatLoadMore: function (pageNumber) { return "Indlæser flere resultater…"; },
+ formatSearching: function () { return "Søger…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_de.js b/apps/files_external/3rdparty/select2/select2_locale_de.js
new file mode 100644
index 00000000000..93b18e81f85
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_de.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 German translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Keine Übereinstimmungen gefunden"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Bitte " + n + " Zeichen mehr eingeben"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Bitte " + n + " Zeichen weniger eingeben"; },
+ formatSelectionTooBig: function (limit) { return "Sie können nur " + limit + " Eintr" + (limit === 1 ? "ag" : "äge") + " auswählen"; },
+ formatLoadMore: function (pageNumber) { return "Lade mehr Ergebnisse…"; },
+ formatSearching: function () { return "Suche…"; }
+ });
+})(jQuery); \ No newline at end of file
diff --git a/apps/files_external/3rdparty/select2/select2_locale_el.js b/apps/files_external/3rdparty/select2/select2_locale_el.js
new file mode 100644
index 00000000000..e94b02cbc5f
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_el.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Greek translation.
+ *
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Δεν βρέθηκαν αποτελέσματα"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Παρακαλούμε εισάγετε " + n + " περισσότερο" + (n > 1 ? "υς" : "") + " χαρακτήρ" + (n > 1 ? "ες" : "α"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Παρακαλούμε διαγράψτε " + n + " χαρακτήρ" + (n > 1 ? "ες" : "α"); },
+ formatSelectionTooBig: function (limit) { return "Μπορείτε να επιλέξετε μόνο " + limit + " αντικείμεν" + (limit > 1 ? "α" : "ο"); },
+ formatLoadMore: function (pageNumber) { return "Φόρτωση περισσότερων…"; },
+ formatSearching: function () { return "Αναζήτηση…"; }
+ });
+})(jQuery); \ No newline at end of file
diff --git a/apps/files_external/3rdparty/select2/select2_locale_en.js.template b/apps/files_external/3rdparty/select2/select2_locale_en.js.template
new file mode 100644
index 00000000000..f66bcc844db
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_en.js.template
@@ -0,0 +1,18 @@
+/**
+ * Select2 <Language> translation.
+ *
+ * Author: Your Name <your@email>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatMatches: function (matches) { return matches + " results are available, use up and down arrow keys to navigate."; },
+ formatNoMatches: function () { return "No matches found"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " more character" + (n == 1 ? "" : "s"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); },
+ formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Loading more results…"; },
+ formatSearching: function () { return "Searching…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_es.js b/apps/files_external/3rdparty/select2/select2_locale_es.js
new file mode 100644
index 00000000000..f2b581791eb
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_es.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Spanish translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "No se encontraron resultados"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Por favor, introduzca " + n + " car" + (n == 1? "ácter" : "acteres"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Por favor, elimine " + n + " car" + (n == 1? "ácter" : "acteres"); },
+ formatSelectionTooBig: function (limit) { return "Sólo puede seleccionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Cargando más resultados…"; },
+ formatSearching: function () { return "Buscando…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_et.js b/apps/files_external/3rdparty/select2/select2_locale_et.js
new file mode 100644
index 00000000000..a4045d22df7
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_et.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Estonian translation.
+ *
+ * Author: Kuldar Kalvik <kuldar@kalvik.ee>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Tulemused puuduvad"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Sisesta " + n + " täht" + (n == 1 ? "" : "e") + " rohkem"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Sisesta " + n + " täht" + (n == 1? "" : "e") + " vähem"; },
+ formatSelectionTooBig: function (limit) { return "Saad vaid " + limit + " tulemus" + (limit == 1 ? "e" : "t") + " valida"; },
+ formatLoadMore: function (pageNumber) { return "Laen tulemusi.."; },
+ formatSearching: function () { return "Otsin.."; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_eu.js b/apps/files_external/3rdparty/select2/select2_locale_eu.js
new file mode 100644
index 00000000000..1da1a709481
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_eu.js
@@ -0,0 +1,43 @@
+/**
+ * Select2 Basque translation.
+ *
+ * Author: Julen Ruiz Aizpuru <julenx at gmail dot com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () {
+ return "Ez da bat datorrenik aurkitu";
+ },
+ formatInputTooShort: function (input, min) {
+ var n = min - input.length;
+ if (n === 1) {
+ return "Idatzi karaktere bat gehiago";
+ } else {
+ return "Idatzi " + n + " karaktere gehiago";
+ }
+ },
+ formatInputTooLong: function (input, max) {
+ var n = input.length - max;
+ if (n === 1) {
+ return "Idatzi karaktere bat gutxiago";
+ } else {
+ return "Idatzi " + n + " karaktere gutxiago";
+ }
+ },
+ formatSelectionTooBig: function (limit) {
+ if (limit === 1 ) {
+ return "Elementu bakarra hauta dezakezu";
+ } else {
+ return limit + " elementu hauta ditzakezu soilik";
+ }
+ },
+ formatLoadMore: function (pageNumber) {
+ return "Emaitza gehiago kargatzen…";
+ },
+ formatSearching: function () {
+ return "Bilatzen…";
+ }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_fa.js b/apps/files_external/3rdparty/select2/select2_locale_fa.js
new file mode 100644
index 00000000000..a9e95af4dba
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_fa.js
@@ -0,0 +1,19 @@
+/**
+ * Select2 Persian translation.
+ *
+ * Author: Ali Choopan <choopan@arsh.co>
+ * Author: Ebrahim Byagowi <ebrahim@gnu.org>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatMatches: function (matches) { return matches + " نتیجه موجود است، کلیدهای جهت بالا و پایین را برای گشتن استفاده کنید."; },
+ formatNoMatches: function () { return "نتیجه‌ای یافت نشد."; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "لطفاً " + n + " نویسه بیشتر وارد نمایید"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "لطفاً " + n + " نویسه را حذف کنید."; },
+ formatSelectionTooBig: function (limit) { return "شما فقط می‌توانید " + limit + " مورد را انتخاب کنید"; },
+ formatLoadMore: function (pageNumber) { return "در حال بارگیری موارد بیشتر…"; },
+ formatSearching: function () { return "در حال جستجو…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_fi.js b/apps/files_external/3rdparty/select2/select2_locale_fi.js
new file mode 100644
index 00000000000..9bed310f717
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_fi.js
@@ -0,0 +1,28 @@
+/**
+ * Select2 Finnish translation
+ */
+(function ($) {
+ "use strict";
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () {
+ return "Ei tuloksia";
+ },
+ formatInputTooShort: function (input, min) {
+ var n = min - input.length;
+ return "Ole hyvä ja anna " + n + " merkkiä lisää";
+ },
+ formatInputTooLong: function (input, max) {
+ var n = input.length - max;
+ return "Ole hyvä ja anna " + n + " merkkiä vähemmän";
+ },
+ formatSelectionTooBig: function (limit) {
+ return "Voit valita ainoastaan " + limit + " kpl";
+ },
+ formatLoadMore: function (pageNumber) {
+ return "Ladataan lisää tuloksia…";
+ },
+ formatSearching: function () {
+ return "Etsitään…";
+ }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_fr.js b/apps/files_external/3rdparty/select2/select2_locale_fr.js
new file mode 100644
index 00000000000..9afda2abdcd
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_fr.js
@@ -0,0 +1,16 @@
+/**
+ * Select2 French translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatMatches: function (matches) { return matches + " résultats sont disponibles, utilisez les flèches haut et bas pour naviguer."; },
+ formatNoMatches: function () { return "Aucun résultat trouvé"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Merci de saisir " + n + " caractère" + (n == 1 ? "" : "s") + " de plus"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Merci de supprimer " + n + " caractère" + (n == 1 ? "" : "s"); },
+ formatSelectionTooBig: function (limit) { return "Vous pouvez seulement sélectionner " + limit + " élément" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Chargement de résultats supplémentaires…"; },
+ formatSearching: function () { return "Recherche en cours…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_gl.js b/apps/files_external/3rdparty/select2/select2_locale_gl.js
new file mode 100644
index 00000000000..80326320bf0
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_gl.js
@@ -0,0 +1,43 @@
+/**
+ * Select2 Galician translation
+ *
+ * Author: Leandro Regueiro <leandro.regueiro@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () {
+ return "Non se atoparon resultados";
+ },
+ formatInputTooShort: function (input, min) {
+ var n = min - input.length;
+ if (n === 1) {
+ return "Engada un carácter";
+ } else {
+ return "Engada " + n + " caracteres";
+ }
+ },
+ formatInputTooLong: function (input, max) {
+ var n = input.length - max;
+ if (n === 1) {
+ return "Elimine un carácter";
+ } else {
+ return "Elimine " + n + " caracteres";
+ }
+ },
+ formatSelectionTooBig: function (limit) {
+ if (limit === 1 ) {
+ return "Só pode seleccionar un elemento";
+ } else {
+ return "Só pode seleccionar " + limit + " elementos";
+ }
+ },
+ formatLoadMore: function (pageNumber) {
+ return "Cargando máis resultados…";
+ },
+ formatSearching: function () {
+ return "Buscando…";
+ }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_he.js b/apps/files_external/3rdparty/select2/select2_locale_he.js
new file mode 100644
index 00000000000..00385410804
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_he.js
@@ -0,0 +1,17 @@
+/**
+* Select2 Hebrew translation.
+*
+* Author: Yakir Sitbon <http://www.yakirs.net/>
+*/
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "לא נמצאו התאמות"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "נא להזין עוד " + n + " תווים נוספים"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "נא להזין פחות " + n + " תווים"; },
+ formatSelectionTooBig: function (limit) { return "ניתן לבחור " + limit + " פריטים"; },
+ formatLoadMore: function (pageNumber) { return "טוען תוצאות נוספות…"; },
+ formatSearching: function () { return "מחפש…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_hr.js b/apps/files_external/3rdparty/select2/select2_locale_hr.js
new file mode 100644
index 00000000000..c29372524b6
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_hr.js
@@ -0,0 +1,22 @@
+/**
+ * Select2 Croatian translation.
+ *
+ * @author Edi Modrić <edi.modric@gmail.com>
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nema rezultata"; },
+ formatInputTooShort: function (input, min) { return "Unesite još" + character(min - input.length); },
+ formatInputTooLong: function (input, max) { return "Unesite" + character(input.length - max) + " manje"; },
+ formatSelectionTooBig: function (limit) { return "Maksimalan broj odabranih stavki je " + limit; },
+ formatLoadMore: function (pageNumber) { return "Učitavanje rezultata…"; },
+ formatSearching: function () { return "Pretraga…"; }
+ });
+
+ function character (n) {
+ return " " + n + " znak" + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 19) ? n%10 > 1 ? "a" : "" : "ova");
+ }
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_hu.js b/apps/files_external/3rdparty/select2/select2_locale_hu.js
new file mode 100644
index 00000000000..a8c30881928
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_hu.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Hungarian translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nincs találat."; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Túl rövid. Még " + n + " karakter hiányzik."; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Túl hosszú. " + n + " karakterrel több, mint kellene."; },
+ formatSelectionTooBig: function (limit) { return "Csak " + limit + " elemet lehet kiválasztani."; },
+ formatLoadMore: function (pageNumber) { return "Töltés…"; },
+ formatSearching: function () { return "Keresés…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_id.js b/apps/files_external/3rdparty/select2/select2_locale_id.js
new file mode 100644
index 00000000000..547454079ba
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_id.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Indonesian translation.
+ *
+ * Author: Ibrahim Yusuf <ibrahim7usuf@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Tidak ada data yang sesuai"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Masukkan " + n + " huruf lagi" + (n == 1 ? "" : "s"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Hapus " + n + " huruf" + (n == 1 ? "" : "s"); },
+ formatSelectionTooBig: function (limit) { return "Anda hanya dapat memilih " + limit + " pilihan" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Mengambil data…"; },
+ formatSearching: function () { return "Mencari…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_is.js b/apps/files_external/3rdparty/select2/select2_locale_is.js
new file mode 100644
index 00000000000..aecc6cd7194
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_is.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Icelandic translation.
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Ekkert fannst"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Vinsamlegast skrifið " + n + " staf" + (n > 1 ? "i" : "") + " í viðbót"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Vinsamlegast styttið texta um " + n + " staf" + (n > 1 ? "i" : ""); },
+ formatSelectionTooBig: function (limit) { return "Þú getur aðeins valið " + limit + " atriði"; },
+ formatLoadMore: function (pageNumber) { return "Sæki fleiri niðurstöður…"; },
+ formatSearching: function () { return "Leita…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_it.js b/apps/files_external/3rdparty/select2/select2_locale_it.js
new file mode 100644
index 00000000000..d4e24de7000
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_it.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Italian translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nessuna corrispondenza trovata"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Inserisci ancora " + n + " caratter" + (n == 1? "e" : "i"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Inserisci " + n + " caratter" + (n == 1? "e" : "i") + " in meno"; },
+ formatSelectionTooBig: function (limit) { return "Puoi selezionare solo " + limit + " element" + (limit == 1 ? "o" : "i"); },
+ formatLoadMore: function (pageNumber) { return "Caricamento in corso…"; },
+ formatSearching: function () { return "Ricerca…"; }
+ });
+})(jQuery); \ No newline at end of file
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ja.js b/apps/files_external/3rdparty/select2/select2_locale_ja.js
new file mode 100644
index 00000000000..81106e78a80
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ja.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Japanese translation.
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "該当なし"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "後" + n + "文字入れてください"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "検索文字列が" + n + "文字長すぎます"; },
+ formatSelectionTooBig: function (limit) { return "最多で" + limit + "項目までしか選択できません"; },
+ formatLoadMore: function (pageNumber) { return "読込中・・・"; },
+ formatSearching: function () { return "検索中・・・"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ka.js b/apps/files_external/3rdparty/select2/select2_locale_ka.js
new file mode 100644
index 00000000000..366cc2d9c4d
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ka.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Georgian (Kartuli) translation.
+ *
+ * Author: Dimitri Kurashvili dimakura@gmail.com
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "ვერ მოიძებნა"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "გთხოვთ შეიყვანოთ კიდევ " + n + " სიმბოლო"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "გთხოვთ წაშალოთ " + n + " სიმბოლო"; },
+ formatSelectionTooBig: function (limit) { return "თქვენ შეგიძლიათ მხოლოდ " + limit + " ჩანაწერის მონიშვნა"; },
+ formatLoadMore: function (pageNumber) { return "შედეგის ჩატვირთვა…"; },
+ formatSearching: function () { return "ძებნა…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ko.js b/apps/files_external/3rdparty/select2/select2_locale_ko.js
new file mode 100644
index 00000000000..1a84d21eae6
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ko.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Korean translation.
+ *
+ * @author Swen Mun <longfinfunnel@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "결과 없음"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "너무 짧습니다. "+n+"글자 더 입력해주세요."; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "너무 깁니다. "+n+"글자 지워주세요."; },
+ formatSelectionTooBig: function (limit) { return "최대 "+limit+"개까지만 선택하실 수 있습니다."; },
+ formatLoadMore: function (pageNumber) { return "불러오는 중…"; },
+ formatSearching: function () { return "검색 중…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_lt.js b/apps/files_external/3rdparty/select2/select2_locale_lt.js
new file mode 100644
index 00000000000..2e2f950b00d
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_lt.js
@@ -0,0 +1,24 @@
+/**
+ * Select2 Lithuanian translation.
+ *
+ * @author CRONUS Karmalakas <cronus dot karmalakas at gmail dot com>
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Atitikmenų nerasta"; },
+ formatInputTooShort: function (input, min) { return "Įrašykite dar" + character(min - input.length); },
+ formatInputTooLong: function (input, max) { return "Pašalinkite" + character(input.length - max); },
+ formatSelectionTooBig: function (limit) {
+ return "Jūs galite pasirinkti tik " + limit + " element" + ((limit%100 > 9 && limit%100 < 21) || limit%10 == 0 ? "ų" : limit%10 > 1 ? "us" : "ą");
+ },
+ formatLoadMore: function (pageNumber) { return "Kraunama daugiau rezultatų…"; },
+ formatSearching: function () { return "Ieškoma…"; }
+ });
+
+ function character (n) {
+ return " " + n + " simbol" + ((n%100 > 9 && n%100 < 21) || n%10 == 0 ? "ių" : n%10 > 1 ? "ius" : "į");
+ }
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_lv.js b/apps/files_external/3rdparty/select2/select2_locale_lv.js
new file mode 100644
index 00000000000..b300ec770f4
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_lv.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Latvian translation.
+ *
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Sakritību nav"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Lūdzu ievadiet vēl " + n + " simbol" + (n == 11 ? "us" : n%10 == 1 ? "u" : "us"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Lūdzu ievadiet par " + n + " simbol" + (n == 11 ? "iem" : n%10 == 1 ? "u" : "iem") + " mazāk"; },
+ formatSelectionTooBig: function (limit) { return "Jūs varat izvēlēties ne vairāk kā " + limit + " element" + (limit == 11 ? "us" : limit%10 == 1 ? "u" : "us"); },
+ formatLoadMore: function (pageNumber) { return "Datu ielāde…"; },
+ formatSearching: function () { return "Meklēšana…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_mk.js b/apps/files_external/3rdparty/select2/select2_locale_mk.js
new file mode 100644
index 00000000000..513562c51bf
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_mk.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Macedonian translation.
+ *
+ * Author: Marko Aleksic <psybaron@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Нема пронајдено совпаѓања"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Ве молиме внесете уште " + n + " карактер" + (n == 1 ? "" : "и"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Ве молиме внесете " + n + " помалку карактер" + (n == 1? "" : "и"); },
+ formatSelectionTooBig: function (limit) { return "Можете да изберете само " + limit + " ставк" + (limit == 1 ? "а" : "и"); },
+ formatLoadMore: function (pageNumber) { return "Вчитување резултати…"; },
+ formatSearching: function () { return "Пребарување…"; }
+ });
+})(jQuery); \ No newline at end of file
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ms.js b/apps/files_external/3rdparty/select2/select2_locale_ms.js
new file mode 100644
index 00000000000..262042aab15
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ms.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Malay translation.
+ *
+ * Author: Kepoweran <kepoweran@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Tiada padanan yang ditemui"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Sila masukkan " + n + " aksara lagi"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Sila hapuskan " + n + " aksara"; },
+ formatSelectionTooBig: function (limit) { return "Anda hanya boleh memilih " + limit + " pilihan"; },
+ formatLoadMore: function (pageNumber) { return "Sedang memuatkan keputusan…"; },
+ formatSearching: function () { return "Mencari…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_nl.js b/apps/files_external/3rdparty/select2/select2_locale_nl.js
new file mode 100644
index 00000000000..5b5c4156ce1
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_nl.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Dutch translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Geen resultaten gevonden"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Vul " + n + " karakter" + (n == 1? "" : "s") + " meer in"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Vul " + n + " karakter" + (n == 1? "" : "s") + " minder in"; },
+ formatSelectionTooBig: function (limit) { return "Maximaal " + limit + " item" + (limit == 1 ? "" : "s") + " toegestaan"; },
+ formatLoadMore: function (pageNumber) { return "Meer resultaten laden…"; },
+ formatSearching: function () { return "Zoeken…"; }
+ });
+})(jQuery); \ No newline at end of file
diff --git a/apps/files_external/3rdparty/select2/select2_locale_no.js b/apps/files_external/3rdparty/select2/select2_locale_no.js
new file mode 100644
index 00000000000..ab61c082a02
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_no.js
@@ -0,0 +1,18 @@
+/**
+ * Select2 Norwegian translation.
+ *
+ * Author: Torgeir Veimo <torgeir.veimo@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Ingen treff"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Vennligst skriv inn " + n + (n>1 ? " flere tegn" : " tegn til"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Vennligst fjern " + n + " tegn"; },
+ formatSelectionTooBig: function (limit) { return "Du kan velge maks " + limit + " elementer"; },
+ formatLoadMore: function (pageNumber) { return "Laster flere resultater…"; },
+ formatSearching: function () { return "Søker…"; }
+ });
+})(jQuery);
+
diff --git a/apps/files_external/3rdparty/select2/select2_locale_pl.js b/apps/files_external/3rdparty/select2/select2_locale_pl.js
new file mode 100644
index 00000000000..75054e76578
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_pl.js
@@ -0,0 +1,22 @@
+/**
+ * Select2 Polish translation.
+ *
+ * @author Jan Kondratowicz <jan@kondratowicz.pl>
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Brak wyników"; },
+ formatInputTooShort: function (input, min) { return "Wpisz jeszcze" + character(min - input.length, "znak", "i"); },
+ formatInputTooLong: function (input, max) { return "Wpisana fraza jest za długa o" + character(input.length - max, "znak", "i"); },
+ formatSelectionTooBig: function (limit) { return "Możesz zaznaczyć najwyżej" + character(limit, "element", "y"); },
+ formatLoadMore: function (pageNumber) { return "Ładowanie wyników…"; },
+ formatSearching: function () { return "Szukanie…"; }
+ });
+
+ function character (n, word, pluralSuffix) {
+ return " " + n + " " + word + (n == 1 ? "" : n%10 < 5 && n%10 > 1 && (n%100 < 5 || n%100 > 20) ? pluralSuffix : "ów");
+ }
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_pt-BR.js b/apps/files_external/3rdparty/select2/select2_locale_pt-BR.js
new file mode 100644
index 00000000000..ac4969acfbb
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_pt-BR.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Brazilian Portuguese translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nenhum resultado encontrado"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Digite mais " + n + " caracter" + (n == 1? "" : "es"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Apague " + n + " caracter" + (n == 1? "" : "es"); },
+ formatSelectionTooBig: function (limit) { return "Só é possível selecionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Carregando mais resultados…"; },
+ formatSearching: function () { return "Buscando…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_pt-PT.js b/apps/files_external/3rdparty/select2/select2_locale_pt-PT.js
new file mode 100644
index 00000000000..cced7cf3ec1
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_pt-PT.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Portuguese (Portugal) translation
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nenhum resultado encontrado"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Introduza " + n + " car" + (n == 1 ? "ácter" : "acteres"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Apague " + n + " car" + (n == 1 ? "ácter" : "acteres"); },
+ formatSelectionTooBig: function (limit) { return "Só é possível selecionar " + limit + " elemento" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "A carregar mais resultados…"; },
+ formatSearching: function () { return "A pesquisar…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ro.js b/apps/files_external/3rdparty/select2/select2_locale_ro.js
new file mode 100644
index 00000000000..87eca4cf740
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ro.js
@@ -0,0 +1,15 @@
+/**
+ * Select2 Romanian translation.
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nu a fost găsit nimic"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Vă rugăm să introduceți incă " + n + " caracter" + (n == 1 ? "" : "e"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Vă rugăm să introduceți mai puțin de " + n + " caracter" + (n == 1? "" : "e"); },
+ formatSelectionTooBig: function (limit) { return "Aveți voie să selectați cel mult " + limit + " element" + (limit == 1 ? "" : "e"); },
+ formatLoadMore: function (pageNumber) { return "Se încarcă…"; },
+ formatSearching: function () { return "Căutare…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_rs.js b/apps/files_external/3rdparty/select2/select2_locale_rs.js
new file mode 100644
index 00000000000..300c01bc5e5
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_rs.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Serbian translation.
+ *
+ * @author Limon Monte <limon.monte@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Ništa nije pronađeno"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Ukucajte bar još " + n + " simbol" + (n % 10 == 1 && n % 100 != 11 ? "" : "a"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Obrišite " + n + " simbol" + (n % 10 == 1 && n % 100 != 11 ? "" : "a"); },
+ formatSelectionTooBig: function (limit) { return "Možete izabrati samo " + limit + " stavk" + (limit % 10 == 1 && limit % 100 != 11 ? "u" : (limit % 10 >= 2 && limit % 10 <= 4 && (limit % 100 < 12 || limit % 100 > 14)? "e" : "i")); },
+ formatLoadMore: function (pageNumber) { return "Preuzimanje još rezultata…"; },
+ formatSearching: function () { return "Pretraga…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_ru.js b/apps/files_external/3rdparty/select2/select2_locale_ru.js
new file mode 100644
index 00000000000..0f45ce0dddf
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_ru.js
@@ -0,0 +1,21 @@
+/**
+ * Select2 Russian translation.
+ *
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Совпадений не найдено"; },
+ formatInputTooShort: function (input, min) { return "Пожалуйста, введите еще" + character(min - input.length); },
+ formatInputTooLong: function (input, max) { return "Пожалуйста, введите на" + character(input.length - max) + " меньше"; },
+ formatSelectionTooBig: function (limit) { return "Вы можете выбрать не более " + limit + " элемент" + (limit%10 == 1 && limit%100 != 11 ? "а" : "ов"); },
+ formatLoadMore: function (pageNumber) { return "Загрузка данных…"; },
+ formatSearching: function () { return "Поиск…"; }
+ });
+
+ function character (n) {
+ return " " + n + " символ" + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 20) ? n%10 > 1 ? "a" : "" : "ов");
+ }
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_sk.js b/apps/files_external/3rdparty/select2/select2_locale_sk.js
new file mode 100644
index 00000000000..772f304aca9
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_sk.js
@@ -0,0 +1,48 @@
+/**
+ * Select2 Slovak translation.
+ *
+ * Author: David Vallner <david@vallner.net>
+ */
+(function ($) {
+ "use strict";
+ // use text for the numbers 2 through 4
+ var smallNumbers = {
+ 2: function(masc) { return (masc ? "dva" : "dve"); },
+ 3: function() { return "tri"; },
+ 4: function() { return "štyri"; }
+ }
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Nenašli sa žiadne položky"; },
+ formatInputTooShort: function (input, min) {
+ var n = min - input.length;
+ if (n == 1) {
+ return "Prosím zadajte ešte jeden znak";
+ } else if (n <= 4) {
+ return "Prosím zadajte ešte ďalšie "+smallNumbers[n](true)+" znaky";
+ } else {
+ return "Prosím zadajte ešte ďalších "+n+" znakov";
+ }
+ },
+ formatInputTooLong: function (input, max) {
+ var n = input.length - max;
+ if (n == 1) {
+ return "Prosím zadajte o jeden znak menej";
+ } else if (n <= 4) {
+ return "Prosím zadajte o "+smallNumbers[n](true)+" znaky menej";
+ } else {
+ return "Prosím zadajte o "+n+" znakov menej";
+ }
+ },
+ formatSelectionTooBig: function (limit) {
+ if (limit == 1) {
+ return "Môžete zvoliť len jednu položku";
+ } else if (limit <= 4) {
+ return "Môžete zvoliť najviac "+smallNumbers[limit](false)+" položky";
+ } else {
+ return "Môžete zvoliť najviac "+limit+" položiek";
+ }
+ },
+ formatLoadMore: function (pageNumber) { return "Načítavajú sa ďalšie výsledky…"; },
+ formatSearching: function () { return "Vyhľadávanie…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_sv.js b/apps/files_external/3rdparty/select2/select2_locale_sv.js
new file mode 100644
index 00000000000..d611189a593
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_sv.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Swedish translation.
+ *
+ * Author: Jens Rantil <jens.rantil@telavox.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Inga träffar"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Var god skriv in " + n + (n>1 ? " till tecken" : " tecken till"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Var god sudda ut " + n + " tecken"; },
+ formatSelectionTooBig: function (limit) { return "Du kan max välja " + limit + " element"; },
+ formatLoadMore: function (pageNumber) { return "Laddar fler resultat…"; },
+ formatSearching: function () { return "Söker…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_th.js b/apps/files_external/3rdparty/select2/select2_locale_th.js
new file mode 100644
index 00000000000..df59bdac36d
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_th.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Thai translation.
+ *
+ * Author: Atsawin Chaowanakritsanakul <joke@nakhon.net>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "ไม่พบข้อมูล"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "โปรดพิมพ์เพิ่มอีก " + n + " ตัวอักษร"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "โปรดลบออก " + n + " ตัวอักษร"; },
+ formatSelectionTooBig: function (limit) { return "คุณสามารถเลือกได้ไม่เกิน " + limit + " รายการ"; },
+ formatLoadMore: function (pageNumber) { return "กำลังค้นข้อมูลเพิ่ม…"; },
+ formatSearching: function () { return "กำลังค้นข้อมูล…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_tr.js b/apps/files_external/3rdparty/select2/select2_locale_tr.js
new file mode 100644
index 00000000000..f834dad2b89
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_tr.js
@@ -0,0 +1,17 @@
+/**
+ * Select2 Turkish translation.
+ *
+ * Author: Salim KAYABAŞI <salim.kayabasi@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Sonuç bulunamadı"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "En az " + n + " karakter daha girmelisiniz"; },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return n + " karakter azaltmalısınız"; },
+ formatSelectionTooBig: function (limit) { return "Sadece " + limit + " seçim yapabilirsiniz"; },
+ formatLoadMore: function (pageNumber) { return "Daha fazla…"; },
+ formatSearching: function () { return "Aranıyor…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_uk.js b/apps/files_external/3rdparty/select2/select2_locale_uk.js
new file mode 100644
index 00000000000..8d31a056080
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_uk.js
@@ -0,0 +1,23 @@
+/**
+ * Select2 Ukrainian translation.
+ *
+ * @author bigmihail <bigmihail@bigmir.net>
+ * @author Uriy Efremochkin <efremochkin@uriy.me>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatMatches: function (matches) { return character(matches, "результат") + " знайдено, використовуйте клавіші зі стрілками вверх та вниз для навігації."; },
+ formatNoMatches: function () { return "Нічого не знайдено"; },
+ formatInputTooShort: function (input, min) { return "Введіть буль ласка ще " + character(min - input.length, "символ"); },
+ formatInputTooLong: function (input, max) { return "Введіть буль ласка на " + character(input.length - max, "символ") + " менше"; },
+ formatSelectionTooBig: function (limit) { return "Ви можете вибрати лише " + character(limit, "елемент"); },
+ formatLoadMore: function (pageNumber) { return "Завантаження даних…"; },
+ formatSearching: function () { return "Пошук…"; }
+ });
+
+ function character (n, word) {
+ return n + " " + word + (n%10 < 5 && n%10 > 0 && (n%100 < 5 || n%100 > 19) ? n%10 > 1 ? "и" : "" : "ів");
+ }
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_vi.js b/apps/files_external/3rdparty/select2/select2_locale_vi.js
new file mode 100644
index 00000000000..5dbc275361f
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_vi.js
@@ -0,0 +1,18 @@
+/**
+ * Select2 Vietnamese translation.
+ *
+ * Author: Long Nguyen <olragon@gmail.com>
+ */
+(function ($) {
+ "use strict";
+
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "Không tìm thấy kết quả"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "Vui lòng nhập nhiều hơn " + n + " ký tự" + (n == 1 ? "" : "s"); },
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "Vui lòng nhập ít hơn " + n + " ký tự" + (n == 1? "" : "s"); },
+ formatSelectionTooBig: function (limit) { return "Chỉ có thể chọn được " + limit + " tùy chọn" + (limit == 1 ? "" : "s"); },
+ formatLoadMore: function (pageNumber) { return "Đang lấy thêm kết quả…"; },
+ formatSearching: function () { return "Đang tìm…"; }
+ });
+})(jQuery);
+
diff --git a/apps/files_external/3rdparty/select2/select2_locale_zh-CN.js b/apps/files_external/3rdparty/select2/select2_locale_zh-CN.js
new file mode 100644
index 00000000000..6add3c52518
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_zh-CN.js
@@ -0,0 +1,14 @@
+/**
+ * Select2 Chinese translation
+ */
+(function ($) {
+ "use strict";
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "没有找到匹配项"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "请再输入" + n + "个字符";},
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "请删掉" + n + "个字符";},
+ formatSelectionTooBig: function (limit) { return "你只能选择最多" + limit + "项"; },
+ formatLoadMore: function (pageNumber) { return "加载结果中…"; },
+ formatSearching: function () { return "搜索中…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2_locale_zh-TW.js b/apps/files_external/3rdparty/select2/select2_locale_zh-TW.js
new file mode 100755
index 00000000000..f072381faae
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2_locale_zh-TW.js
@@ -0,0 +1,14 @@
+/**
+ * Select2 Traditional Chinese translation
+ */
+(function ($) {
+ "use strict";
+ $.extend($.fn.select2.defaults, {
+ formatNoMatches: function () { return "沒有找到相符的項目"; },
+ formatInputTooShort: function (input, min) { var n = min - input.length; return "請再輸入" + n + "個字元";},
+ formatInputTooLong: function (input, max) { var n = input.length - max; return "請刪掉" + n + "個字元";},
+ formatSelectionTooBig: function (limit) { return "你只能選擇最多" + limit + "項"; },
+ formatLoadMore: function (pageNumber) { return "載入中…"; },
+ formatSearching: function () { return "搜尋中…"; }
+ });
+})(jQuery);
diff --git a/apps/files_external/3rdparty/select2/select2x2.png b/apps/files_external/3rdparty/select2/select2x2.png
new file mode 100644
index 00000000000..4bdd5c961d4
--- /dev/null
+++ b/apps/files_external/3rdparty/select2/select2x2.png
Binary files differ
diff --git a/apps/files_external/ajax/applicable.php b/apps/files_external/ajax/applicable.php
new file mode 100644
index 00000000000..1f0147758e7
--- /dev/null
+++ b/apps/files_external/ajax/applicable.php
@@ -0,0 +1,26 @@
+<?php
+
+OCP\JSON::checkAppEnabled('files_external');
+OCP\JSON::callCheck();
+
+OCP\JSON::checkAdminUser();
+
+$pattern = '';
+$limit = null;
+$offset = null;
+if (isset($_GET['pattern'])) {
+ $pattern = $_GET['pattern'];
+}
+if (isset($_GET['limit'])) {
+ $limit = $_GET['limit'];
+}
+if (isset($_GET['offset'])) {
+ $offset = $_GET['offset'];
+}
+
+$groups = \OC_Group::getGroups($pattern, $limit, $offset);
+$users = \OCP\User::getDisplayNames($pattern, $limit, $offset);
+
+$results = array('groups' => $groups, 'users' => $users);
+
+\OCP\JSON::success($results);
diff --git a/apps/files_external/ajax/dropbox.php b/apps/files_external/ajax/dropbox.php
index bbedf8e9cac..db417de4b2d 100644
--- a/apps/files_external/ajax/dropbox.php
+++ b/apps/files_external/ajax/dropbox.php
@@ -5,7 +5,7 @@ require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php';
OCP\JSON::checkAppEnabled('files_external');
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-$l = OC_L10N::get('files_external');
+$l = \OC::$server->getL10N('files_external');
if (isset($_POST['app_key']) && isset($_POST['app_secret'])) {
$oauth = new Dropbox_OAuth_Curl($_POST['app_key'], $_POST['app_secret']);
diff --git a/apps/files_external/ajax/google.php b/apps/files_external/ajax/google.php
index 13e74071846..40c10aa5d07 100644
--- a/apps/files_external/ajax/google.php
+++ b/apps/files_external/ajax/google.php
@@ -6,7 +6,7 @@ require_once 'Google_Client.php';
OCP\JSON::checkAppEnabled('files_external');
OCP\JSON::checkLoggedIn();
OCP\JSON::callCheck();
-$l = OC_L10N::get('files_external');
+$l = \OC::$server->getL10N('files_external');
if (isset($_POST['client_id']) && isset($_POST['client_secret']) && isset($_POST['redirect'])) {
$client = new Google_Client();
diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php
index 3b8793a075b..50a73bd5f9a 100644
--- a/apps/files_external/appinfo/app.php
+++ b/apps/files_external/appinfo/app.php
@@ -6,7 +6,7 @@
* later.
* See the COPYING-README file.
*/
-$l = \OC_L10N::get('files_external');
+$l = \OC::$server->getL10N('files_external');
OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php';
OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php';
@@ -62,9 +62,9 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\AmazonS3', array(
'key' => (string)$l->t('Access Key'),
'secret' => '*'.$l->t('Secret Key'),
'bucket' => (string)$l->t('Bucket'),
- 'hostname' => '&'.$l->t('Hostname (optional)'),
- 'port' => '&'.$l->t('Port (optional)'),
- 'region' => '&'.$l->t('Region (optional)'),
+ 'hostname' => '&'.$l->t('Hostname'),
+ 'port' => '&'.$l->t('Port'),
+ 'region' => '&'.$l->t('Region'),
'use_ssl' => '!'.$l->t('Enable SSL'),
'use_path_style' => '!'.$l->t('Enable Path Style')),
'has_dependencies' => true));
@@ -108,15 +108,15 @@ OC_Mount_Config::registerBackend('\OC\Files\Storage\Swift', array(
'backend' => (string)$l->t('OpenStack Object Storage'),
'priority' => 100,
'configuration' => array(
- 'user' => (string)$l->t('Username (required)'),
- 'bucket' => (string)$l->t('Bucket (required)'),
+ 'user' => (string)$l->t('Username'),
+ 'bucket' => (string)$l->t('Bucket'),
'region' => '&'.$l->t('Region (optional for OpenStack Object Storage)'),
'key' => '*'.$l->t('API Key (required for Rackspace Cloud Files)'),
'tenant' => '&'.$l->t('Tenantname (required for OpenStack Object Storage)'),
'password' => '*'.$l->t('Password (required for OpenStack Object Storage)'),
'service_name' => '&'.$l->t('Service Name (required for OpenStack Object Storage)'),
'url' => '&'.$l->t('URL of identity endpoint (required for OpenStack Object Storage)'),
- 'timeout' => '&'.$l->t('Timeout of HTTP requests in seconds (optional)'),
+ 'timeout' => '&'.$l->t('Timeout of HTTP requests in seconds'),
),
'has_dependencies' => true));
diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php
index 0a1e261a189..b852b34c5d3 100644
--- a/apps/files_external/appinfo/routes.php
+++ b/apps/files_external/appinfo/routes.php
@@ -37,6 +37,9 @@ $this->create('files_external_dropbox', 'ajax/dropbox.php')
$this->create('files_external_google', 'ajax/google.php')
->actionInclude('files_external/ajax/google.php');
+$this->create('files_external_list_applicable', '/applicable')
+ ->actionInclude('files_external/ajax/applicable.php');
+
OC_API::register('get',
'/apps/files_external/api/v1/mounts',
array('\OCA\Files\External\Api', 'getUserMounts'),
diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css
index 0da769d992b..101c224c5f5 100644
--- a/apps/files_external/css/settings.css
+++ b/apps/files_external/css/settings.css
@@ -20,6 +20,9 @@ tr:hover>td.remove>img { visibility:visible; cursor:pointer; }
#externalStorage td.backend {
white-space: normal;
}
+#externalStorage td.configuration > * {
+ white-space: nowrap;
+}
#externalStorage td.configuration input.added {
margin-right: 6px;
@@ -42,3 +45,19 @@ tr:hover>td.remove>img { visibility:visible; cursor:pointer; }
#userMountingBackends {
padding-left: 25px;
}
+
+#body-settings .select2-results .select2-result-label {
+ height: 32px;
+ padding: 3px;
+}
+.select2-results .select2-result-label .avatardiv {
+ display:inline-block;
+}
+.select2-results .select2-result-label .avatardiv + span {
+ margin-left: 10px;
+}
+.select2-results .select2-result-label .avatardiv[data-type="group"] + span {
+ vertical-align: top;
+ top: 6px;
+ position: relative;
+}
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index 8a1bb2bec6f..00d2a920cbf 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -2,7 +2,7 @@
function updateStatus(statusEl, result){
statusEl.removeClass('success error loading-small');
- if (result && result.status == 'success' && result.data.message) {
+ if (result && result.status === 'success' && result.data.message) {
statusEl.addClass('success');
return true;
} else {
@@ -11,11 +11,31 @@ function updateStatus(statusEl, result){
}
}
+function getSelection($row) {
+ var values = $row.find('.applicableUsers').select2('val');
+ if (!values || values.length === 0) {
+ values = ['all'];
+ }
+ return values;
+}
+
+function highlightBorder(element, highlight) {
+ $(element).toggleClass('warning-input', highlight);
+ return highlight;
+}
+
+function highlightInput(input) {
+ if ($(input).attr('type') === 'text' || $(input).attr('type') === 'password') {
+ return highlightBorder(input,
+ ($(input).val() === '' && !$(input).hasClass('optional')));
+ }
+}
+
OC.MountConfig={
saveStorage:function(tr, callback) {
var mountPoint = $(tr).find('.mountPoint input').val();
var oldMountPoint = $(tr).find('.mountPoint input').data('mountpoint');
- if (mountPoint == '') {
+ if (mountPoint === '') {
return false;
}
var statusSpan = $(tr).closest('tr').find('.status span');
@@ -27,7 +47,7 @@ OC.MountConfig={
}
var classOptions = {};
$.each(configuration, function(index, input) {
- if ($(input).val() == '' && !$(input).hasClass('optional')) {
+ if ($(input).val() === '' && !$(input).hasClass('optional')) {
addMountPoint = false;
return false;
}
@@ -42,10 +62,7 @@ OC.MountConfig={
}
});
if ($('#externalStorage').data('admin') === true) {
- var multiselect = $(tr).find('.chzn-select').val();
- if (multiselect == null) {
- return false;
- }
+ var multiselect = getSelection($(tr));
}
if (addMountPoint) {
var status = false;
@@ -166,16 +183,137 @@ OC.MountConfig={
};
$(document).ready(function() {
- $('.chzn-select').chosen();
+ //initialize hidden input field with list of users and groups
+ $('#externalStorage').find('tr:not(#addMountPoint)').each(function(i,tr) {
+ var applicable = $(tr).find('.applicable');
+ if (applicable.length > 0) {
+ var groups = applicable.data('applicable-groups');
+ var groupsId = [];
+ $.each(groups, function () {
+ groupsId.push(this+"(group)");
+ });
+ var users = applicable.data('applicable-users');
+ if (users.indexOf('all') > -1) {
+ $(tr).find('.applicableUsers').val('');
+ } else {
+ $(tr).find('.applicableUsers').val(groupsId.concat(users).join(','));
+ }
+ }
+ });
+
+ var userListLimit = 30;
+ function addSelect2 ($elements) {
+ if ($elements.length > 0) {
+ $elements.select2({
+ placeholder: t('files_external', 'All users. Type to select user or group.'),
+ allowClear: true,
+ multiple: true,
+ //minimumInputLength: 1,
+ ajax: {
+ url: OC.generateUrl('apps/files_external/applicable'),
+ dataType: 'json',
+ quietMillis: 100,
+ data: function (term, page) { // page is the one-based page number tracked by Select2
+ return {
+ pattern: term, //search term
+ limit: userListLimit, // page size
+ offset: userListLimit*(page-1) // page number starts with 0
+ };
+ },
+ results: function (data, page) {
+ if (data.status === "success") {
+
+ var results = [];
+ var userCount = 0; // users is an object
+
+ // add groups
+ $.each(data.groups, function(i, group) {
+ results.push({name:group+'(group)', displayname:group, type:'group' });
+ });
+ // add users
+ $.each(data.users, function(id, user) {
+ userCount++;
+ results.push({name:id, displayname:user, type:'user' });
+ });
+
+ var more = (userCount >= userListLimit) || (data.groups.length >= userListLimit);
+ return {results: results, more: more};
+ } else {
+ //FIXME add error handling
+ }
+ }
+ },
+ initSelection: function(element, callback) {
+ var users = {};
+ users['users'] = [];
+ var toSplit = element.val().split(",");
+ for (var i = 0; i < toSplit.length; i++) {
+ users['users'].push(toSplit[i]);
+ }
+
+ $.ajax(OC.generateUrl('displaynames'), {
+ type: 'POST',
+ contentType: 'application/json',
+ data: JSON.stringify(users),
+ dataType: "json"
+ }).done(function(data) {
+ var results = [];
+ if (data.status === "success") {
+ $.each(data.users, function(user, displayname) {
+ if (displayname !== false) {
+ results.push({name:user, displayname:displayname, type:'user'});
+ }
+ });
+ callback(results);
+ } else {
+ //FIXME add error handling
+ }
+ });
+ },
+ id: function(element) {
+ return element.name;
+ },
+ formatResult: function (element) {
+ var $result = $('<span><div class="avatardiv"/><span>'+escapeHTML(element.displayname)+'</span></span>');
+ var $div = $result.find('.avatardiv')
+ .attr('data-type', element.type)
+ .attr('data-name', element.name)
+ .attr('data-displayname', element.displayname);
+ if (element.type === 'group') {
+ var url = OC.imagePath('core','places/contacts-dark'); // TODO better group icon
+ $div.html('<img width="32" height="32" src="'+url+'">');
+ }
+ return $result.get(0).outerHTML;
+ },
+ formatSelection: function (element) {
+ if (element.type === 'group') {
+ return '<span title="'+escapeHTML(element.name)+'" class="group">'+escapeHTML(element.displayname+' '+t('files_external', '(group)'))+'</span>';
+ } else {
+ return '<span title="'+escapeHTML(element.name)+'" class="user">'+escapeHTML(element.displayname)+'</span>';
+ }
+ },
+ escapeMarkup: function (m) { return m; } // we escape the markup in formatResult and formatSelection
+ }).on("select2-loaded", function() {
+ $.each($(".avatardiv"), function(i, div) {
+ $div = $(div);
+ if ($div.data('type') === 'user') {
+ $div.avatar($div.data('name'),32);
+ }
+ })
+ });
+ }
+ }
+ addSelect2($('tr:not(#addMountPoint) .applicableUsers'));
+
$('#externalStorage').on('change', '#selectBackend', function() {
- var tr = $(this).parent().parent();
+ var tr = $(this).closest("tr");
$('#externalStorage tbody').append($(tr).clone());
$('#externalStorage tbody tr').last().find('.mountPoint input').val('');
var selected = $(this).find('option:selected').text();
var backendClass = $(this).val();
- $(this).parent().text(selected);
- if ($(tr).find('.mountPoint input').val() == '') {
+ $(tr).find('.backend').text(selected);
+ if ($(tr).find('.mountPoint input').val() === '') {
$(tr).find('.mountPoint input').val(suggestMountPoint(selected));
}
$(tr).addClass(backendClass);
@@ -184,40 +322,40 @@ $(document).ready(function() {
var configurations = $(this).data('configurations');
var td = $(tr).find('td.configuration');
$.each(configurations, function(backend, parameters) {
- if (backend == backendClass) {
+ if (backend === backendClass) {
$.each(parameters['configuration'], function(parameter, placeholder) {
var is_optional = false;
if (placeholder.indexOf('&') === 0) {
is_optional = true;
placeholder = placeholder.substring(1);
}
+ var newElement;
if (placeholder.indexOf('*') === 0) {
var class_string = is_optional ? ' optional' : '';
- td.append('<input type="password" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
+ newElement = $('<input type="password" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
} else if (placeholder.indexOf('!') === 0) {
- td.append('<label><input type="checkbox" class="added" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
+ newElement = $('<label><input type="checkbox" class="added" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');
} else if (placeholder.indexOf('#') === 0) {
- td.append('<input type="hidden" class="added" data-parameter="'+parameter+'" />');
+ newElement = $('<input type="hidden" class="added" data-parameter="'+parameter+'" />');
} else {
var class_string = is_optional ? ' optional' : '';
- td.append('<input type="text" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
+ newElement = $('<input type="text" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
}
+ highlightInput(newElement);
+ td.append(newElement);
});
- if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) {
+ if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length === 1) {
OC.addScript('files_external', parameters['custom']);
}
+ td.children().not('[type=hidden]').first().focus();
return false;
}
});
- // Reset chosen
- var chosen = $(tr).find('.applicable select');
- chosen.parent().find('div').remove();
- chosen.removeAttr('id').removeClass('chzn-done').css({display:'inline-block'});
- chosen.chosen();
$(tr).find('td').last().attr('class', 'remove');
$(tr).find('td').last().removeAttr('style');
$(tr).removeAttr('id');
$(this).remove();
+ addSelect2($('tr:not(#addMountPoint) .applicableUsers'));
});
function suggestMountPoint(defaultMountPoint) {
@@ -232,7 +370,7 @@ $(document).ready(function() {
while (match && i < 20) {
match = false;
$('#externalStorage tbody td.mountPoint input').each(function(index, mountPoint) {
- if ($(mountPoint).val() == defaultMountPoint+append) {
+ if ($(mountPoint).val() === defaultMountPoint+append) {
match = true;
return false;
}
@@ -247,9 +385,11 @@ $(document).ready(function() {
return defaultMountPoint+append;
}
- $('#externalStorage').on('paste', 'td', function() {
- var tr = $(this).parent();
+ $('#externalStorage').on('paste', 'td input', function() {
+ var tr = $(this).closest("tr");
+ var me = this;
setTimeout(function() {
+ highlightInput($(me));
OC.MountConfig.saveStorage(tr);
}, 20);
});
@@ -258,7 +398,8 @@ $(document).ready(function() {
$('#externalStorage').on('keyup', 'td input', function() {
clearTimeout(timer);
- var tr = $(this).parent().parent();
+ var tr = $(this).closest("tr");
+ highlightInput($(this));
if ($(this).val) {
timer = setTimeout(function() {
OC.MountConfig.saveStorage(tr);
@@ -267,41 +408,42 @@ $(document).ready(function() {
});
$('#externalStorage').on('change', 'td input:checkbox', function() {
- OC.MountConfig.saveStorage($(this).parent().parent().parent());
+ OC.MountConfig.saveStorage($(this).closest("tr"));
+ });
+
+ $('#externalStorage').on('change', '.applicable', function() {
+ OC.MountConfig.saveStorage($(this).closest("tr"));
});
- $('#externalStorage').on('change', '.applicable .chzn-select', function() {
- OC.MountConfig.saveStorage($(this).parent().parent());
+ $('#externalStorage').on('click', '.status>span', function() {
+ OC.MountConfig.saveStorage($(this).closest("tr"));
});
$('#sslCertificate').on('click', 'td.remove>img', function() {
- var $tr = $(this).parent().parent();
- var row = this.parentNode.parentNode;
- $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id});
+ var $tr = $(this).closest("tr");
+ $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: $tr.attr('id')});
$tr.remove();
return true;
});
$('#externalStorage').on('click', 'td.remove>img', function() {
- var tr = $(this).parent().parent();
+ var tr = $(this).closest('tr');
var mountPoint = $(tr).find('.mountPoint input').val();
if ($('#externalStorage').data('admin') === true) {
var isPersonal = false;
- var multiselect = $(tr).find('.chzn-select').val();
- if (multiselect != null) {
- $.each(multiselect, function(index, value) {
- var pos = value.indexOf('(group)');
- if (pos != -1) {
- var mountType = 'group';
- var applicable = value.substr(0, pos);
- } else {
- var mountType = 'user';
- var applicable = value;
- }
- $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
- });
- }
+ var multiselect = getSelection($(tr));
+ $.each(multiselect, function(index, value) {
+ var pos = value.indexOf('(group)');
+ if (pos != -1) {
+ var mountType = 'group';
+ var applicable = value.substr(0, pos);
+ } else {
+ var mountType = 'user';
+ var applicable = value;
+ }
+ $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+ });
} else {
var mountType = 'user';
var applicable = OC.currentUser;
diff --git a/apps/files_external/l10n/af_ZA.php b/apps/files_external/l10n/af_ZA.php
index fc60a7f25a4..7b416fc117a 100644
--- a/apps/files_external/l10n/af_ZA.php
+++ b/apps/files_external/l10n/af_ZA.php
@@ -3,7 +3,6 @@ $TRANSLATIONS = array(
"Username" => "Gebruikersnaam",
"Password" => "Wagwoord",
"Share" => "Deel",
-"Personal" => "Persoonlik",
-"Users" => "Gebruikers"
+"Personal" => "Persoonlik"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/ar.php b/apps/files_external/l10n/ar.php
index 32709aa170f..4e57a092120 100644
--- a/apps/files_external/l10n/ar.php
+++ b/apps/files_external/l10n/ar.php
@@ -11,9 +11,6 @@ $TRANSLATIONS = array(
"Name" => "اسم",
"Folder name" => "اسم المجلد",
"Configuration" => "إعداد",
-"All Users" => "كل المستخدمين",
-"Groups" => "مجموعات",
-"Users" => "المستخدمين",
"Delete" => "إلغاء"
);
$PLURAL_FORMS = "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;";
diff --git a/apps/files_external/l10n/ast.php b/apps/files_external/l10n/ast.php
index 7c399a0a62f..6351238356e 100644
--- a/apps/files_external/l10n/ast.php
+++ b/apps/files_external/l10n/ast.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 y compatibilidá",
"Access Key" => "Clave d'accesu",
"Secret Key" => "Clave Secreta",
-"Hostname (optional)" => "Nome d'equipu (opcional)",
-"Port (optional)" => "Puertu (opcional)",
-"Region (optional)" => "Rexón (opcional)",
"Enable SSL" => "Habilitar SSL",
"Enable Path Style" => "Habilitar Estilu de ruta",
"App key" => "App principal",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID de veceru",
"Client secret" => "Veceru secretu",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Nome d'usuariu (necesariu)",
-"Bucket (required)" => "Depósitu (necesariu)",
"Region (optional for OpenStack Object Storage)" => "Rexón (opcional pa OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Clave API (necesaria pa Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Nome d'inquilín (necesariu pa OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Contraseña (necesaria pa OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nome de Serviciu (necesariu pa OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL d'identidá de puntu final (necesariu pa OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Tiempu d'espera de peticiones HTTP en segundos (opcional)",
"Share" => "Compartir",
"SMB / CIFS using OC login" => "SMB / CIFS usando accesu OC",
"Username as share" => "Nome d'usuariu como Compartición",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuración",
"Available for" => "Disponible pa",
"Add storage" => "Amestar almacenamientu",
-"No user or group" => "Nengún usuariu o grupu",
-"All Users" => "Tolos usuarios",
-"Groups" => "Grupos",
-"Users" => "Usuarios",
"Delete" => "Desaniciar",
"Enable User External Storage" => "Habilitar almacenamientu esterno d'usuariu",
"Allow users to mount the following external storage" => "Permitir a los usuarios montar el siguiente almacenamientu esternu",
diff --git a/apps/files_external/l10n/az.php b/apps/files_external/l10n/az.php
index 5c4e2701178..330e8234a61 100644
--- a/apps/files_external/l10n/az.php
+++ b/apps/files_external/l10n/az.php
@@ -8,16 +8,16 @@ $TRANSLATIONS = array(
"Location" => "Yerləşdiyiniz ünvan",
"Key" => "Açar",
"Secret" => "Gizli",
-"Hostname (optional)" => "Avadanlığın adı(məcburi deyil)",
"Enable SSL" => "SSL-i işə sal",
"Host" => "Şəbəkədə ünvan",
"Username" => "İstifadəçi adı",
"Password" => "Şifrə",
"Share" => "Yayımla",
+"URL" => "URL",
+"Personal" => "Şəxsi",
"Saved" => "Saxlanıldı",
"Name" => "Ad",
"Folder name" => "Qovluq adı",
-"Users" => "İstifadəçilər",
"Delete" => "Sil"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/bg_BG.php b/apps/files_external/l10n/bg_BG.php
index 7f18f95b0fb..88848b9b68d 100644
--- a/apps/files_external/l10n/bg_BG.php
+++ b/apps/files_external/l10n/bg_BG.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 и съвместими",
"Access Key" => "Access Key",
"Secret Key" => "Secret Key",
-"Hostname (optional)" => "Сървър (незадължително)",
-"Port (optional)" => "Порт (незадължително)",
-"Region (optional)" => "Регион (незадължително)",
"Enable SSL" => "Включи SSL",
"Enable Path Style" => "Включи Path Style",
"App key" => "App key",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Client secret",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Потребителско Име (задължително)",
-"Bucket (required)" => "Bucket (задължително)",
"Region (optional for OpenStack Object Storage)" => "Регион (незадължително за OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API Key (задължително за Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (задължително за OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Парола (задължително за OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Service Name (задължително за OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL of identity endpoint (задължително за OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Максимално време за HTTP заявки в секунди (незадължително)",
"Share" => "Споделяне",
"SMB / CIFS using OC login" => "SMB / CIFS използвайки OC профил",
"Username as share" => "Потребителско име като споделена папка",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Грешка при настройката на Dropbox дисковото пространство.",
"Personal" => "Личен",
"System" => "Системен",
+"All users. Type to select user or group." => "Всички потребители. Пиши, за да избереш потребител или група.",
+"(group)" => "(група)",
"Saved" => "Запазено",
"<b>Note:</b> " => "<b>Бележка:</b> ",
" and " => "и",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Настройки",
"Available for" => "Достъпно за",
"Add storage" => "Добави дисково пространство",
-"No user or group" => "Липсва потребител или група",
-"All Users" => "Всички Потребители",
-"Groups" => "Групи",
-"Users" => "Потребители",
"Delete" => "Изтрий",
"Enable User External Storage" => "Разреши Потребителско Външно Дисково Пространство",
"Allow users to mount the following external storage" => "Разреши на потребителите да прикачват следното външно дисково пространство",
diff --git a/apps/files_external/l10n/bn_BD.php b/apps/files_external/l10n/bn_BD.php
index f878eafba83..a0ec26a0a64 100644
--- a/apps/files_external/l10n/bn_BD.php
+++ b/apps/files_external/l10n/bn_BD.php
@@ -1,7 +1,7 @@
<?php
$TRANSLATIONS = array(
"Please provide a valid Dropbox app key and secret." => "দয়া করে সঠিক এবং বৈধ Dropbox app key and secret প্রদান করুন।",
-"Location" => "াবস্থান",
+"Location" => "অবস্থান",
"Host" => "হোস্ট",
"Username" => "ব্যবহারকারী",
"Password" => "কূটশব্দ",
@@ -12,13 +12,11 @@ $TRANSLATIONS = array(
"Grant access" => "অধিগমনের অনুমতি প্রদান কর",
"Error configuring Google Drive storage" => "Google Drive সংরক্ষণাগার নির্ধারণ করতে সমস্যা ",
"Personal" => "ব্যক্তিগত",
+"Saved" => "সংরক্ষণ করা হলো",
"Name" => "রাম",
"External Storage" => "বাহ্যিক সংরক্ষণাগার",
"Folder name" => "ফোলডারের নাম",
"Configuration" => "কনফিগারেসন",
-"All Users" => "সমস্ত ব্যবহারকারী",
-"Groups" => "গোষ্ঠীসমূহ",
-"Users" => "ব্যবহারকারী",
"Delete" => "মুছে",
"Enable User External Storage" => "ব্যবহারকারীর বাহ্যিক সংরক্ষণাগার সক্রিয় কর",
"SSL root certificates" => "SSL রুট সনদপত্র",
diff --git a/apps/files_external/l10n/ca.php b/apps/files_external/l10n/ca.php
index 37d5084538d..26ca6d95035 100644
--- a/apps/files_external/l10n/ca.php
+++ b/apps/files_external/l10n/ca.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 i similars",
"Access Key" => "Clau d'accés",
"Secret Key" => "Clau secreta",
-"Hostname (optional)" => "Nom de l'equip (opcional)",
-"Port (optional)" => "Port (opcional)",
-"Region (optional)" => "Regió (opcional)",
"Enable SSL" => "Habilita SSL",
"Enable Path Style" => "Permet l'estil del camí",
"App key" => "Clau de l'aplicació",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Secret del client",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Nom d'usuari (necessari)",
-"Bucket (required)" => "Cub (requerit)",
"Region (optional for OpenStack Object Storage)" => "Regió (opcional per OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Clau API (requerit per fitxers al núvol Rackspace)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (requerit per OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Contrasenya (requerit per OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nom del servei (requerit per OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL del punt identificador final (requerit per OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Temps d'espera dels requeriments HTTP en segons (opcional)",
"Share" => "Comparteix",
"SMB / CIFS using OC login" => "SMB / CIFS usant acreditació OC",
"Username as share" => "Nom d'usuari per compartir",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuració",
"Available for" => "Disponible per",
"Add storage" => "Afegeix emmagatzemament",
-"No user or group" => "Sense usuaris o grups",
-"All Users" => "Tots els usuaris",
-"Groups" => "Grups",
-"Users" => "Usuaris",
"Delete" => "Esborra",
"Enable User External Storage" => "Habilita l'emmagatzemament extern d'usuari",
"Allow users to mount the following external storage" => "Permet als usuaris muntar els dispositius externs següents",
diff --git a/apps/files_external/l10n/cs_CZ.php b/apps/files_external/l10n/cs_CZ.php
index 4eb029d8a54..6b65a421c76 100644
--- a/apps/files_external/l10n/cs_CZ.php
+++ b/apps/files_external/l10n/cs_CZ.php
@@ -11,13 +11,12 @@ $TRANSLATIONS = array(
"Amazon S3" => "Amazon S3",
"Key" => "Klíč",
"Secret" => "Tajemství",
+"Bucket" => "Bucket",
"Amazon S3 and compliant" => "Amazon S3 a kompatibilní",
"Access Key" => "Přístupový klíč",
"Secret Key" => "Tajný klíč",
-"Hostname (optional)" => "Hostname (nepovinný)",
-"Port (optional)" => "Port (nepovinný)",
-"Region (optional)" => "Region (nepovinný)",
"Enable SSL" => "Povolit SSL",
+"Enable Path Style" => "Povolit Path Style",
"App key" => "Klíč aplikace",
"App secret" => "Tajemství aplikace",
"Host" => "Počítač",
@@ -28,14 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Klientské ID",
"Client secret" => "Klientské tajemství",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Uživatelské jméno (povinné)",
"Region (optional for OpenStack Object Storage)" => "Region (nepovinný pro OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API klíč (vyžadován pro Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Jméno nájemce (vyžadováno pro OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Heslo (vyžadováno pro OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Název služby (vyžadováno pro OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL identity koncového bodu (vyžadováno pro OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Časový limit HTTP požadavků v sekundách (nepovinné)",
"Share" => "Sdílet",
"SMB / CIFS using OC login" => "SMB / CIFS za použití přihlašovacího jména OC",
"Username as share" => "Uživatelské jméno jako sdílený adresář",
@@ -48,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Chyba při nastavení úložiště Google Drive",
"Personal" => "Osobní",
"System" => "Systém",
+"All users. Type to select user or group." => "Všichni uživatelé. Začněte psát pro výběr uživatelů a skupin.",
+"(group)" => "(skupina)",
"Saved" => "Uloženo",
"<b>Note:</b> " => "<b>Poznámka:</b>",
" and " => "a",
@@ -63,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Nastavení",
"Available for" => "Dostupné pro",
"Add storage" => "Přidat úložiště",
-"No user or group" => "Žádný uživatel nebo skupina",
-"All Users" => "Všichni uživatelé",
-"Groups" => "Skupiny",
-"Users" => "Uživatelé",
"Delete" => "Smazat",
"Enable User External Storage" => "Zapnout externí uživatelské úložiště",
"Allow users to mount the following external storage" => "Povolit uživatelů připojit následující externí úložiště",
diff --git a/apps/files_external/l10n/cy_GB.php b/apps/files_external/l10n/cy_GB.php
index 011dbb371a5..26420c555c4 100644
--- a/apps/files_external/l10n/cy_GB.php
+++ b/apps/files_external/l10n/cy_GB.php
@@ -7,8 +7,6 @@ $TRANSLATIONS = array(
"URL" => "URL",
"Personal" => "Personol",
"Name" => "Enw",
-"Groups" => "Grwpiau",
-"Users" => "Defnyddwyr",
"Delete" => "Dileu"
);
$PLURAL_FORMS = "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;";
diff --git a/apps/files_external/l10n/da.php b/apps/files_external/l10n/da.php
index e54f28826c3..e701694105e 100644
--- a/apps/files_external/l10n/da.php
+++ b/apps/files_external/l10n/da.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 og kompatible",
"Access Key" => "Adgangsnøgle",
"Secret Key" => "Hemmelig Nøgle ",
-"Hostname (optional)" => "Værtsnavn (valgfri)",
-"Port (optional)" => "Port (valgfri)",
-"Region (optional)" => "Region (valgfri)",
"Enable SSL" => "Aktiver SSL",
"Enable Path Style" => "Aktivér stil for sti",
"App key" => "App-nøgle",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Klient ID",
"Client secret" => "Klient hemmelighed",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Brugernavn (påkrævet)",
-"Bucket (required)" => "Bucket (påkrævet)",
"Region (optional for OpenStack Object Storage)" => "Region (valgfri for OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API-nøgle (påkrævet for Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Lejers navn (påkrævet for OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Adgangskode (påkrævet for OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Service Navn (påkrævet for OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL på slutpunkt for identitet (påkrævet for OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Timeout på HTTP forespørgsler i sekunder (valgfri)",
"Share" => "Del",
"SMB / CIFS using OC login" => "SMB / CIFS med OC-login",
"Username as share" => "Brugernavn som deling",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Opsætning",
"Available for" => "Tilgængelig for",
"Add storage" => "Tilføj lager",
-"No user or group" => "Ingen bruger eller gruppe",
-"All Users" => "Alle brugere",
-"Groups" => "Grupper",
-"Users" => "Brugere",
"Delete" => "Slet",
"Enable User External Storage" => "Aktiver ekstern opbevaring for brugere",
"Allow users to mount the following external storage" => "Tillad brugere at montere følgende som eksternt lager",
diff --git a/apps/files_external/l10n/de.php b/apps/files_external/l10n/de.php
index d99cce64a2e..d0377b269a6 100644
--- a/apps/files_external/l10n/de.php
+++ b/apps/files_external/l10n/de.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 und kompatible",
"Access Key" => "Zugriffsschlüssel",
"Secret Key" => "Sicherheitssschlüssel",
-"Hostname (optional)" => "Host-Name (Optional)",
-"Port (optional)" => "Port (Optional)",
-"Region (optional)" => "Region (Optional)",
"Enable SSL" => "SSL aktivieren",
"Enable Path Style" => "Pfad-Stil aktivieren",
"App key" => "App-Schlüssel",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client-ID",
"Client secret" => "Geheime Zeichenkette des Client",
"OpenStack Object Storage" => "Openstack-Objektspeicher",
-"Username (required)" => "Benutzername (Erforderlich)",
-"Bucket (required)" => "Bucket (Erforderlich)",
"Region (optional for OpenStack Object Storage)" => "Region (Optional für Openstack-Objektspeicher)",
"API Key (required for Rackspace Cloud Files)" => "API-Schlüssel (Erforderlich für Rackspace Cloud-Dateien)",
"Tenantname (required for OpenStack Object Storage)" => "Mietername (Erforderlich für Openstack-Objektspeicher)",
"Password (required for OpenStack Object Storage)" => "Passwort (Erforderlich für Openstack-Objektspeicher)",
"Service Name (required for OpenStack Object Storage)" => "Name der Dienstleistung (Erforderlich für Openstack-Objektspeicher)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL des Identitätsendpunktes (Erforderlich für Openstack-Objektspeicher)",
-"Timeout of HTTP requests in seconds (optional)" => "Zeitüberschreitung von HTTP-Anfragen in Sekunden (Optional)",
"Share" => "Teilen",
"SMB / CIFS using OC login" => "SMB / CIFS mit OC-Login",
"Username as share" => "Benutzername als Freigabe",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfiguration",
"Available for" => "Verfügbar für",
"Add storage" => "Speicher hinzufügen",
-"No user or group" => "Kein Nutzer oder Gruppe",
-"All Users" => "Alle Benutzer",
-"Groups" => "Gruppen",
-"Users" => "Benutzer",
"Delete" => "Löschen",
"Enable User External Storage" => "Externen Speicher für Benutzer aktivieren",
"Allow users to mount the following external storage" => "Erlaube es Benutzern, den folgenden externen Speicher einzubinden",
diff --git a/apps/files_external/l10n/de_CH.php b/apps/files_external/l10n/de_CH.php
index 1fa6b28bced..5d11539cba7 100644
--- a/apps/files_external/l10n/de_CH.php
+++ b/apps/files_external/l10n/de_CH.php
@@ -20,9 +20,6 @@ $TRANSLATIONS = array(
"Folder name" => "Ordnername",
"Configuration" => "Konfiguration",
"Add storage" => "Speicher hinzufügen",
-"All Users" => "Alle Benutzer",
-"Groups" => "Gruppen",
-"Users" => "Benutzer",
"Delete" => "Löschen",
"Enable User External Storage" => "Externen Speicher für Benutzer aktivieren",
"SSL root certificates" => "SSL-Root-Zertifikate",
diff --git a/apps/files_external/l10n/de_DE.php b/apps/files_external/l10n/de_DE.php
index d9297243f1f..1a47495c155 100644
--- a/apps/files_external/l10n/de_DE.php
+++ b/apps/files_external/l10n/de_DE.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 und Kompatible",
"Access Key" => "Zugriffsschlüssel",
"Secret Key" => "Sicherheitsschlüssel",
-"Hostname (optional)" => "Host-Name (Optional)",
-"Port (optional)" => "Port (Optional)",
-"Region (optional)" => "Region (Optional)",
"Enable SSL" => "SSL aktivieren",
"Enable Path Style" => "Pfad-Stil aktivieren",
"App key" => "App-Schlüssel",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client-ID",
"Client secret" => "Geheime Zeichenkette des Client",
"OpenStack Object Storage" => "Openstack-Objektspeicher",
-"Username (required)" => "Benutzername (Erforderlich)",
-"Bucket (required)" => "Bucket (Erforderlich)",
"Region (optional for OpenStack Object Storage)" => "Region (Optional für Openstack-Objektspeicher)",
"API Key (required for Rackspace Cloud Files)" => "API-Schlüssel (Erforderlich für Rackspace Cloud-Dateien)",
"Tenantname (required for OpenStack Object Storage)" => "Mietername (Erforderlich für Openstack-Objektspeicher)",
"Password (required for OpenStack Object Storage)" => "Passwort (Erforderlich für Openstack-Objektspeicher)",
"Service Name (required for OpenStack Object Storage)" => "Name der Dienstleistung (Erforderlich für Openstack-Objektspeicher)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL des Identitätsendpunktes (Erforderlich für Openstack-Objektspeicher)",
-"Timeout of HTTP requests in seconds (optional)" => "Zeitüberschreitung von HTTP-Anfragen in Sekunden (Optional)",
"Share" => "Teilen",
"SMB / CIFS using OC login" => "SMB / CIFS mit OC-Login",
"Username as share" => "Benutzername als Freigabe",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfiguration",
"Available for" => "Verfügbar für",
"Add storage" => "Speicher hinzufügen",
-"No user or group" => "Kein Nutzer oder Gruppe",
-"All Users" => "Alle Benutzer",
-"Groups" => "Gruppen",
-"Users" => "Benutzer",
"Delete" => "Löschen",
"Enable User External Storage" => "Externen Speicher für Benutzer aktivieren",
"Allow users to mount the following external storage" => "Erlauben Sie Benutzern, folgende externe Speicher einzubinden",
diff --git a/apps/files_external/l10n/el.php b/apps/files_external/l10n/el.php
index fd27e6b8063..852f5f6c614 100644
--- a/apps/files_external/l10n/el.php
+++ b/apps/files_external/l10n/el.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 και συμμορφούμενα",
"Access Key" => "Κλειδί πρόσβασης",
"Secret Key" => "Μυστικό κλειδί",
-"Hostname (optional)" => "Όνομα μηχανήματος (προαιρετικά)",
-"Port (optional)" => "Πόρτα (προαιρετικά)",
-"Region (optional)" => "Περιοχή (προαιρετικά)",
"Enable SSL" => "Ενεργοποίηση SSL",
"Enable Path Style" => "Ενεργοποίηση μορφής διαδρομής",
"App key" => "Κλειδί εφαρμογής",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID πελάτη",
"Client secret" => "Μυστικό πελάτη",
"OpenStack Object Storage" => "Αποθήκη αντικειμένων OpenStack",
-"Username (required)" => "Όνομα χρήστη (απαιτείται)",
-"Bucket (required)" => "Κάδος (απαιτείται)",
"Region (optional for OpenStack Object Storage)" => "Περιοχή (προαιρετικά για την αποθήκευση αντικειμένων OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Κλειδί API (απαιτείται για αρχεία Rackspace Cloud)",
"Tenantname (required for OpenStack Object Storage)" => "Όνομα ενοίκου (απαιτείται για την Αποθήκευση Αντικειμένων OpenStack)",
"Password (required for OpenStack Object Storage)" => "Μυστικός κωδικός (απαιτείται για την αποθήκευση αντικειμένων OpenStack)",
"Service Name (required for OpenStack Object Storage)" => "Όνομα υπηρεσίας (απαιτείται για την αποθήκευση αντικειμένων OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Διεύθυνση URL της ταυτότητας τελικού σημείου (απαιτείται για την αποθήκευση αντικειμένων OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Χρονικό όριο των αιτήσεων HTTP σε δευτερόλεπτα (προαιρετικά)",
"Share" => "Διαμοιράστε",
"SMB / CIFS using OC login" => "SMB / CIFS χρησιμοποιώντας λογαριασμό OC",
"Username as share" => "Όνομα χρήστη ως διαμοιραζόμενος φάκελος",
@@ -51,6 +45,7 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Σφάλμα ρυθμίζωντας αποθήκευση Google Drive ",
"Personal" => "Προσωπικά",
"System" => "Σύστημα",
+"(group)" => "(ομάδα)",
"Saved" => "Αποθηκεύτηκαν",
"<b>Note:</b> " => "<b>Σημείωση:</b> ",
" and " => "και",
@@ -66,10 +61,6 @@ $TRANSLATIONS = array(
"Configuration" => "Ρυθμίσεις",
"Available for" => "Διαθέσιμο για",
"Add storage" => "Προσθηκη αποθηκευσης",
-"No user or group" => "Μη διαθέσιμος χρήστης ή ομάδα",
-"All Users" => "Όλοι οι Χρήστες",
-"Groups" => "Ομάδες",
-"Users" => "Χρήστες",
"Delete" => "Διαγραφή",
"Enable User External Storage" => "Ενεργοποίηση Εξωτερικού Αποθηκευτικού Χώρου Χρήστη",
"Allow users to mount the following external storage" => "Χορήγηση άδειας στους χρήστες να συνδέσουν τα παρακάτω εξωτερικά μέσα αποθήκευσης",
diff --git a/apps/files_external/l10n/en_GB.php b/apps/files_external/l10n/en_GB.php
index 8d284878674..ac3ef63b47a 100644
--- a/apps/files_external/l10n/en_GB.php
+++ b/apps/files_external/l10n/en_GB.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 and compliant",
"Access Key" => "Access Key",
"Secret Key" => "Secret Key",
-"Hostname (optional)" => "Hostname (optional)",
-"Port (optional)" => "Port (optional)",
-"Region (optional)" => "Region (optional)",
"Enable SSL" => "Enable SSL",
"Enable Path Style" => "Enable Path Style",
"App key" => "App key",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Client secret",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Username (required)",
-"Bucket (required)" => "Bucket (required)",
"Region (optional for OpenStack Object Storage)" => "Region (optional for OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API Key (required for Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (required for OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Password (required for OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Service Name (required for OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL of identity endpoint (required for OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Timeout of HTTP requests in seconds (optional)",
"Share" => "Share",
"SMB / CIFS using OC login" => "SMB / CIFS using OC login",
"Username as share" => "Username as share",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Error configuring Google Drive storage",
"Personal" => "Personal",
"System" => "System",
+"All users. Type to select user or group." => "All users. Type to select user or group.",
+"(group)" => "(group)",
"Saved" => "Saved",
"<b>Note:</b> " => "<b>Note:</b> ",
" and " => " and ",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuration",
"Available for" => "Available for",
"Add storage" => "Add storage",
-"No user or group" => "No user or group",
-"All Users" => "All Users",
-"Groups" => "Groups",
-"Users" => "Users",
"Delete" => "Delete",
"Enable User External Storage" => "Enable User External Storage",
"Allow users to mount the following external storage" => "Allow users to mount the following external storage",
diff --git a/apps/files_external/l10n/eo.php b/apps/files_external/l10n/eo.php
index 065379f0c05..4edc0b4d1fd 100644
--- a/apps/files_external/l10n/eo.php
+++ b/apps/files_external/l10n/eo.php
@@ -9,9 +9,6 @@ $TRANSLATIONS = array(
"Secret" => "Sekreto",
"Access Key" => "Aliroklavo",
"Secret Key" => "Sekretoklavo",
-"Hostname (optional)" => "Gastigonomo (malnepra)",
-"Port (optional)" => "Pordo (malnepra)",
-"Region (optional)" => "Regiono (malnepra)",
"Enable SSL" => "Kapabligi SSL-on",
"App key" => "Aplikaĵoklavo",
"App secret" => "Aplikaĵosekreto",
@@ -23,7 +20,6 @@ $TRANSLATIONS = array(
"Client ID" => "Klientidentigilo",
"Client secret" => "Klientosekreto",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Uzantonomo (nepra)",
"Region (optional for OpenStack Object Storage)" => "Regiono (malnepra por OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API-klavo (nepra por Rackspace Cloud Files)",
"Password (required for OpenStack Object Storage)" => "Pasvorto (nepra por OpenStack Object Storage)",
@@ -46,10 +42,6 @@ $TRANSLATIONS = array(
"Configuration" => "Agordo",
"Available for" => "Disponebla por",
"Add storage" => "Aldoni memorilon",
-"No user or group" => "Neniu uzanto aŭ grupo",
-"All Users" => "Ĉiuj uzantoj",
-"Groups" => "Grupoj",
-"Users" => "Uzantoj",
"Delete" => "Forigi",
"Enable User External Storage" => "Kapabligi malenan memorilon de uzanto",
"Allow users to mount the following external storage" => "Permesi uzantojn munti la jenajn malenajn memorilojn",
diff --git a/apps/files_external/l10n/es.php b/apps/files_external/l10n/es.php
index 211fe79c62f..978635e5247 100644
--- a/apps/files_external/l10n/es.php
+++ b/apps/files_external/l10n/es.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 y compatibilidad",
"Access Key" => "Clave de Acceso",
"Secret Key" => "Clave Secreta",
-"Hostname (optional)" => "Nombre de Equipo (opcional)",
-"Port (optional)" => "Puerto (opcional)",
-"Region (optional)" => "Región (opcional)",
"Enable SSL" => "Habilitar SSL",
"Enable Path Style" => "Habilitar Estilo de Ruta",
"App key" => "App principal",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID de Cliente",
"Client secret" => "Cliente secreto",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Nombre de Usuario (requerido)",
-"Bucket (required)" => "Depósito (requerido)",
"Region (optional for OpenStack Object Storage)" => "Región (opcional para OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Clave API (requerida para Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Nombre de Inquilino (requerido para OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Contraseña (requerida para OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nombre de Servicio (requerido para OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL de identidad de punto final (requerido para OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Tiempo de espera de peticiones HTTP en segundos (opcional)",
"Share" => "Compartir",
"SMB / CIFS using OC login" => "SMB / CIFS usando acceso OC",
"Username as share" => "Nombre de Usuario como compartir",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Error configurando el almacenamiento de Google Drive",
"Personal" => "Personal",
"System" => "Sistema",
+"All users. Type to select user or group." => "Todos los usuarios. Teclee para seleccionar un usuario o grupo.",
+"(group)" => "(grupo)",
"Saved" => "Guardado",
"<b>Note:</b> " => "<b>Nota:</b> ",
" and " => "y",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuración",
"Available for" => "Disponible para",
"Add storage" => "Añadir almacenamiento",
-"No user or group" => "Ningún usuario o grupo",
-"All Users" => "Todos los usuarios",
-"Groups" => "Grupos",
-"Users" => "Usuarios",
"Delete" => "Eliminar",
"Enable User External Storage" => "Habilitar almacenamiento externo de usuario",
"Allow users to mount the following external storage" => "Permitir a los usuarios montar el siguiente almacenamiento externo",
diff --git a/apps/files_external/l10n/es_AR.php b/apps/files_external/l10n/es_AR.php
index 68fb080c863..1e9b61b64ac 100644
--- a/apps/files_external/l10n/es_AR.php
+++ b/apps/files_external/l10n/es_AR.php
@@ -19,9 +19,6 @@ $TRANSLATIONS = array(
"Folder name" => "Nombre de la carpeta",
"Configuration" => "Configuración",
"Add storage" => "Añadir almacenamiento",
-"All Users" => "Todos los usuarios",
-"Groups" => "Grupos",
-"Users" => "Usuarios",
"Delete" => "Borrar",
"Enable User External Storage" => "Habilitar almacenamiento de usuario externo",
"SSL root certificates" => "certificados SSL raíz",
diff --git a/apps/files_external/l10n/es_CL.php b/apps/files_external/l10n/es_CL.php
index 00e6c7c0793..cd9a32fdd10 100644
--- a/apps/files_external/l10n/es_CL.php
+++ b/apps/files_external/l10n/es_CL.php
@@ -4,7 +4,6 @@ $TRANSLATIONS = array(
"Password" => "Clave",
"Share" => "Compartir",
"Personal" => "Personal",
-"Folder name" => "Nombre del directorio",
-"Users" => "Usuarios"
+"Folder name" => "Nombre del directorio"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/es_MX.php b/apps/files_external/l10n/es_MX.php
index a837ac210db..51fe29f8e86 100644
--- a/apps/files_external/l10n/es_MX.php
+++ b/apps/files_external/l10n/es_MX.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "Nombre de la carpeta",
"Configuration" => "Configuración",
"Add storage" => "Añadir almacenamiento",
-"All Users" => "Todos los usuarios",
-"Groups" => "Grupos",
-"Users" => "Usuarios",
"Delete" => "Eliminar",
"Enable User External Storage" => "Habilitar almacenamiento externo de usuario",
"SSL root certificates" => "Certificados raíz SSL",
diff --git a/apps/files_external/l10n/et_EE.php b/apps/files_external/l10n/et_EE.php
index 7df651c7b8d..243567e2255 100644
--- a/apps/files_external/l10n/et_EE.php
+++ b/apps/files_external/l10n/et_EE.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 ja ühilduv",
"Access Key" => "Ligipääsu võti",
"Secret Key" => "Salavõti",
-"Hostname (optional)" => "Hostinimi (valikuline)",
-"Port (optional)" => "Post (valikuline)",
-"Region (optional)" => "Regioon (valikuline)",
"Enable SSL" => "SSL-i kasutamine",
"Enable Path Style" => "Luba otsingtee stiilis",
"App key" => "Rakenduse võti",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Kliendi ID",
"Client secret" => "Kliendi salasõna",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Kasutajanimi (kohustuslik)",
-"Bucket (required)" => "Korv (kohustuslik)",
"Region (optional for OpenStack Object Storage)" => "Regioon (valikuline OpenStack Object Storage puhul)",
"API Key (required for Rackspace Cloud Files)" => "API võti (vajalik Rackspace Cloud Files puhul)",
"Tenantname (required for OpenStack Object Storage)" => "Rendinimi (tenantname , vajalik OpenStack Object Storage puhul)",
"Password (required for OpenStack Object Storage)" => "Parool (vajalik OpenStack Object Storage puhul)",
"Service Name (required for OpenStack Object Storage)" => "Teenuse nimi (vajalik OpenStack Object Storage puhul)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Tuvastuse URL lõpp-punkt (vajalik OpenStack Object Storage puhul)",
-"Timeout of HTTP requests in seconds (optional)" => "HTTP päringu aegumine sekundites (valikuline)",
"Share" => "Jaga",
"SMB / CIFS using OC login" => "SMB / CIFS kasutades OC logimist",
"Username as share" => "Kasutajanimi kui jagamine",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Viga Google Drive'i salvestusruumi seadistamisel",
"Personal" => "Isiklik",
"System" => "Süsteem",
+"All users. Type to select user or group." => "Kõik kasutajad. Kirjuta, et valida kasutaja või grupp.",
+"(group)" => "(grupp)",
"Saved" => "Salvestatud",
"<b>Note:</b> " => "<b>Märkus:</b>",
" and " => "ja",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Seadistamine",
"Available for" => "Saadaval",
"Add storage" => "Lisa andmehoidla",
-"No user or group" => "Ühtki kasutajat või gruppi",
-"All Users" => "Kõik kasutajad",
-"Groups" => "Grupid",
-"Users" => "Kasutajad",
"Delete" => "Kustuta",
"Enable User External Storage" => "Luba kasutajatele väline salvestamine",
"Allow users to mount the following external storage" => "Võimalda kasutajatel ühendada järgmist välist andmehoidlat",
diff --git a/apps/files_external/l10n/eu.php b/apps/files_external/l10n/eu.php
index d93d701297c..71615a973a5 100644
--- a/apps/files_external/l10n/eu.php
+++ b/apps/files_external/l10n/eu.php
@@ -14,9 +14,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 eta baliokideak",
"Access Key" => "Sarbide gakoa",
"Secret Key" => "Giltza Sekretua",
-"Hostname (optional)" => "Hostalari izena (hautazkoa)",
-"Port (optional)" => "Portua (hautazkoa)",
-"Region (optional)" => "Eskualdea (hautazkoa)",
"Enable SSL" => "Gaitu SSL",
"Enable Path Style" => "Gaitu Bide Estiloa",
"App key" => "Aplikazio gakoa",
@@ -29,14 +26,12 @@ $TRANSLATIONS = array(
"Client ID" => "Bezero ID",
"Client secret" => "Bezeroaren Sekretua",
"OpenStack Object Storage" => "OpenStack Objektu Biltegiratzea",
-"Username (required)" => "Erabiltzaile izena (beharrezkoa)",
"Region (optional for OpenStack Object Storage)" => "Eskualdea (hautazkoa OpenStack Objektu Biltegiratzerako)",
"API Key (required for Rackspace Cloud Files)" => "API Giltza (beharrezkoa Rackspace Cloud Filesentzako)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (beharrezkoa OpenStack Objektu Biltegiratzerko)",
"Password (required for OpenStack Object Storage)" => "Pasahitza (beharrezkoa OpenStack Objektu Biltegiratzerako)",
"Service Name (required for OpenStack Object Storage)" => "Zerbitzuaren Izena (beharrezkoa OpenStack Objektu Biltegiratzerako)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Nortasun amaierako puntuaren URLa (beharrezkoa OpenStack Objektu Biltegiratzerako)",
-"Timeout of HTTP requests in seconds (optional)" => "HTTP eskarien gehienezko denbora segundutan (hautazkoa)",
"Share" => "Partekatu",
"SMB / CIFS using OC login" => "SMB / CIFS saioa hasteko OC erabiliz",
"Username as share" => "Erabiltzaile izena elkarbanaketa bezala",
@@ -63,10 +58,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfigurazioa",
"Available for" => "Hauentzat eskuragarri",
"Add storage" => "Gehitu biltegiratzea",
-"No user or group" => "Talde edo erabiltzailerik ez",
-"All Users" => "Erabiltzaile guztiak",
-"Groups" => "Taldeak",
-"Users" => "Erabiltzaileak",
"Delete" => "Ezabatu",
"Enable User External Storage" => "Gaitu erabiltzaileentzako kanpo biltegiratzea",
"Allow users to mount the following external storage" => "Baimendu erabiltzaileak hurrengo kanpo biltegiratzeak muntatzen",
diff --git a/apps/files_external/l10n/fa.php b/apps/files_external/l10n/fa.php
index dbe0569916e..b3f8e134ae9 100644
--- a/apps/files_external/l10n/fa.php
+++ b/apps/files_external/l10n/fa.php
@@ -19,9 +19,6 @@ $TRANSLATIONS = array(
"Folder name" => "نام پوشه",
"Configuration" => "پیکربندی",
"Add storage" => "اضافه کردن حافظه",
-"All Users" => "تمام کاربران",
-"Groups" => "گروه ها",
-"Users" => "کاربران",
"Delete" => "حذف",
"Enable User External Storage" => "فعال سازی حافظه خارجی کاربر",
"SSL root certificates" => "گواهی های اصلی SSL ",
diff --git a/apps/files_external/l10n/fi_FI.php b/apps/files_external/l10n/fi_FI.php
index 01ce90241cd..706f4c8ac33 100644
--- a/apps/files_external/l10n/fi_FI.php
+++ b/apps/files_external/l10n/fi_FI.php
@@ -9,15 +9,11 @@ $TRANSLATIONS = array(
"Amazon S3" => "Amazon S3",
"Key" => "Avain",
"Amazon S3 and compliant" => "Amazon S3 ja yhteensopivat",
-"Hostname (optional)" => "Verkkonimi (valinnainen)",
-"Port (optional)" => "Portti (valinnainen)",
-"Region (optional)" => "Alue (valinnainen)",
"Enable SSL" => "Käytä SSL:ää",
"Host" => "Isäntä",
"Username" => "Käyttäjätunnus",
"Password" => "Salasana",
-"Username (required)" => "Käyttäjätunnus (vaaditaan)",
-"Timeout of HTTP requests in seconds (optional)" => "HTTP-pyyntöjen aikakatkaisu sekunneissa (valinnainen)",
+"Secure ftps://" => "Salattu ftps://",
"Share" => "Jaa",
"URL" => "Verkko-osoite",
"Secure https://" => "Salattu https://",
@@ -27,6 +23,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Virhe Google Drive levyn asetuksia tehtäessä",
"Personal" => "Henkilökohtainen",
"System" => "Järjestelmä",
+"All users. Type to select user or group." => "Kaikki käyttäjät. Kirjoita valitaksesi käyttäjän tai ryhmän.",
+"(group)" => "(ryhmä)",
"Saved" => "Tallennettu",
"<b>Note:</b> " => "<b>Huomio:</b> ",
" and " => "ja",
@@ -41,10 +39,6 @@ $TRANSLATIONS = array(
"Configuration" => "Asetukset",
"Available for" => "Saatavuus",
"Add storage" => "Lisää tallennustila",
-"No user or group" => "Ei käyttäjää tai ryhmää",
-"All Users" => "Kaikki käyttäjät",
-"Groups" => "Ryhmät",
-"Users" => "Käyttäjät",
"Delete" => "Poista",
"Enable User External Storage" => "Ota käyttöön ulkopuoliset tallennuspaikat",
"Allow users to mount the following external storage" => "Salli käyttäjien liittää seuraavat erilliset tallennusvälineet",
diff --git a/apps/files_external/l10n/fr.php b/apps/files_external/l10n/fr.php
index be817a97ea6..b55611a0fba 100644
--- a/apps/files_external/l10n/fr.php
+++ b/apps/files_external/l10n/fr.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Compatible avec Amazon S3",
"Access Key" => "Clé d'accès",
"Secret Key" => "Clé secrète",
-"Hostname (optional)" => "Nom machine (optionnel)",
-"Port (optional)" => "Port (optionnel)",
-"Region (optional)" => "Région (facultatif)",
"Enable SSL" => "Activer SSL",
"Enable Path Style" => "Activer le style de chemin",
"App key" => "Clé App",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID Client",
"Client secret" => "Secret client",
"OpenStack Object Storage" => "Object de Stockage OpenStack",
-"Username (required)" => "Nom d'utilisation (requis)",
-"Bucket (required)" => "Bucket (requis)",
"Region (optional for OpenStack Object Storage)" => "Region (optionnel pour Object de Stockage OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Clé API (requis pour Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Nom du locataire (requis pour le stockage OpenStack)",
"Password (required for OpenStack Object Storage)" => "Mot de passe (requis pour OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nom du service (requit pour le stockage OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL du point d'accès d'identité (requis pour le stockage OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Temps maximal de requête HTTP en seconde (facultatif)",
"Share" => "Partager",
"SMB / CIFS using OC login" => "SMB / CIFS utilise le nom d'utilisateur OC",
"Username as share" => "Nom d'utilisateur du partage",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuration",
"Available for" => "Disponible pour",
"Add storage" => "Ajouter un support de stockage",
-"No user or group" => "Aucun utilisateur ou groupe",
-"All Users" => "Tous les utilisateurs",
-"Groups" => "Groupes",
-"Users" => "Utilisateurs",
"Delete" => "Supprimer",
"Enable User External Storage" => "Activer le stockage externe pour les utilisateurs",
"Allow users to mount the following external storage" => "Autorise les utilisateurs à monter les stockage externes suivants",
diff --git a/apps/files_external/l10n/gl.php b/apps/files_external/l10n/gl.php
index 006507a4ba2..0ee7c4d255b 100644
--- a/apps/files_external/l10n/gl.php
+++ b/apps/files_external/l10n/gl.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 e compatíbeis",
"Access Key" => "Clave de acceso",
"Secret Key" => "Clave secreta",
-"Hostname (optional)" => "Nome de máquina (opcional)",
-"Port (optional)" => "Porto (opcional)",
-"Region (optional)" => "Rexión (opcional)",
"Enable SSL" => "Activar SSL",
"Enable Path Style" => "Activar o estilo de ruta",
"App key" => "Clave da API",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID do cliente",
"Client secret" => "Secreto do cliente",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Nome de usuario (obrigatorio)",
-"Bucket (required)" => "Bucket (obrigatorio)",
"Region (optional for OpenStack Object Storage)" => "Rexión (opcional para OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Clave da API (obrigatoria para Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Nome do inquilino (obrigatorio para OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Contrasinal (obrigatorio para OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nome do servizo (obrigatorio para OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL do punto final da identidade (obrigatorio para OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Tempo de espera de peticións HTTP en segundos (opcional)",
"Share" => "Compartir",
"SMB / CIFS using OC login" => "SMB / CIFS usando acceso OC",
"Username as share" => "Nome de usuario como compartición",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuración",
"Available for" => "Dispoñíbel para",
"Add storage" => "Engadir almacenamento",
-"No user or group" => "Non hai usuario ou grupo",
-"All Users" => "Todos os usuarios",
-"Groups" => "Grupos",
-"Users" => "Usuarios",
"Delete" => "Eliminar",
"Enable User External Storage" => "Activar o almacenamento externo do usuario",
"Allow users to mount the following external storage" => "Permitirlle aos usuarios montar o seguinte almacenamento externo",
diff --git a/apps/files_external/l10n/he.php b/apps/files_external/l10n/he.php
index 100e3b2866b..43903915bfb 100644
--- a/apps/files_external/l10n/he.php
+++ b/apps/files_external/l10n/he.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"External Storage" => "אחסון חיצוני",
"Folder name" => "שם התיקייה",
"Configuration" => "הגדרות",
-"All Users" => "כל המשתמשים",
-"Groups" => "קבוצות",
-"Users" => "משתמשים",
"Delete" => "מחיקה",
"Enable User External Storage" => "הפעלת אחסון חיצוני למשתמשים",
"SSL root certificates" => "שורש אישורי אבטחת SSL ",
diff --git a/apps/files_external/l10n/hi.php b/apps/files_external/l10n/hi.php
index e0011dc46e4..ca41287841e 100644
--- a/apps/files_external/l10n/hi.php
+++ b/apps/files_external/l10n/hi.php
@@ -3,7 +3,6 @@ $TRANSLATIONS = array(
"Username" => "प्रयोक्ता का नाम",
"Password" => "पासवर्ड",
"Share" => "साझा करें",
-"Personal" => "यक्तिगत",
-"Users" => "उपयोगकर्ता"
+"Personal" => "यक्तिगत"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/hr.php b/apps/files_external/l10n/hr.php
index 1074f126795..0e8e029f4e1 100644
--- a/apps/files_external/l10n/hr.php
+++ b/apps/files_external/l10n/hr.php
@@ -16,8 +16,6 @@ $TRANSLATIONS = array(
"Personal" => "Osobno",
"Saved" => "Snimljeno",
"Name" => "Ime",
-"Groups" => "Grupe",
-"Users" => "Korisnici",
"Delete" => "Obriši"
);
$PLURAL_FORMS = "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;";
diff --git a/apps/files_external/l10n/hu_HU.php b/apps/files_external/l10n/hu_HU.php
index 9cb8d26bd6e..8cbff0a1757 100644
--- a/apps/files_external/l10n/hu_HU.php
+++ b/apps/files_external/l10n/hu_HU.php
@@ -20,9 +20,6 @@ $TRANSLATIONS = array(
"Folder name" => "Mappanév",
"Configuration" => "Beállítások",
"Add storage" => "Tároló becsatolása",
-"All Users" => "Az összes felhasználó",
-"Groups" => "Csoportok",
-"Users" => "Felhasználók",
"Delete" => "Törlés",
"Enable User External Storage" => "Külső tárolók engedélyezése a felhasználók részére",
"SSL root certificates" => "SSL tanúsítványok",
diff --git a/apps/files_external/l10n/ia.php b/apps/files_external/l10n/ia.php
index 1f723cef8fb..65e87c81cc8 100644
--- a/apps/files_external/l10n/ia.php
+++ b/apps/files_external/l10n/ia.php
@@ -8,8 +8,6 @@ $TRANSLATIONS = array(
"Personal" => "Personal",
"Name" => "Nomine",
"Folder name" => "Nomine de dossier",
-"Groups" => "Gruppos",
-"Users" => "Usatores",
"Delete" => "Deler"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/id.php b/apps/files_external/l10n/id.php
index 8b89ef79fa2..3f54f55cea1 100644
--- a/apps/files_external/l10n/id.php
+++ b/apps/files_external/l10n/id.php
@@ -5,15 +5,11 @@ $TRANSLATIONS = array(
"Local" => "Lokal",
"Location" => "lokasi",
"Amazon S3" => "Amazon S3",
-"Hostname (optional)" => "Hostname (tambahan)",
-"Port (optional)" => "Port (tambahan)",
-"Region (optional)" => "Wilayah (tambahan)",
"Enable SSL" => "Aktifkan SSL",
"Host" => "Host",
"Username" => "Nama Pengguna",
"Password" => "Sandi",
"Root" => "Root",
-"Username (required)" => "Nama pengguna (dibutuhkan)",
"Share" => "Bagikan",
"URL" => "tautan",
"Access granted" => "Akses diberikan",
@@ -33,10 +29,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfigurasi",
"Available for" => "Tersedia untuk",
"Add storage" => "Tambahkan penyimpanan",
-"No user or group" => "Tidak ada pengguna dan grup",
-"All Users" => "Semua Pengguna",
-"Groups" => "Grup",
-"Users" => "Pengguna",
"Delete" => "Hapus",
"Enable User External Storage" => "Aktifkan Penyimpanan Eksternal Pengguna",
"Allow users to mount the following external storage" => "Izinkan pengguna untuk mengaitkan penyimpanan eksternal berikut",
diff --git a/apps/files_external/l10n/is.php b/apps/files_external/l10n/is.php
index 67aa2121e7d..848ea06c8c8 100644
--- a/apps/files_external/l10n/is.php
+++ b/apps/files_external/l10n/is.php
@@ -16,9 +16,6 @@ $TRANSLATIONS = array(
"External Storage" => "Ytri gagnageymsla",
"Folder name" => "Nafn möppu",
"Configuration" => "Uppsetning",
-"All Users" => "Allir notendur",
-"Groups" => "Hópar",
-"Users" => "Notendur",
"Delete" => "Eyða",
"Enable User External Storage" => "Virkja ytra gagnasvæði notenda",
"SSL root certificates" => "SSL rótar skilríki",
diff --git a/apps/files_external/l10n/it.php b/apps/files_external/l10n/it.php
index d3107ec54d6..1b5d2f46116 100644
--- a/apps/files_external/l10n/it.php
+++ b/apps/files_external/l10n/it.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 e conformi",
"Access Key" => "Chiave di accesso",
"Secret Key" => "Chiave segreta",
-"Hostname (optional)" => "Nome host (opzionale)",
-"Port (optional)" => "Porta (opzionale)",
-"Region (optional)" => "Regione (opzionale)",
"Enable SSL" => "Abilita SSL",
"Enable Path Style" => "Abilita stile percorsi",
"App key" => "Chiave applicazione",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID client",
"Client secret" => "Segreto del client",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Nome utente (richiesto)",
-"Bucket (required)" => "Bucket (richiesto)",
"Region (optional for OpenStack Object Storage)" => "Regione (facoltativa per OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Chiave API (richiesta per Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Nome tenant (richiesto per OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Password (richiesta per OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nome servizio (richiesta per OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL del servizio di identità (richiesto per OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Tempo massimo in secondi delle richieste HTTP (opzionale)",
"Share" => "Condividi",
"SMB / CIFS using OC login" => "SMB / CIFS utilizzando le credenziali di OC",
"Username as share" => "Nome utente come condivisione",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Errore durante la configurazione dell'archivio Google Drive",
"Personal" => "Personale",
"System" => "Sistema",
+"All users. Type to select user or group." => "Tutti gli utenti. Digita per selezionare utente o gruppo.",
+"(group)" => "(gruppo)",
"Saved" => "Salvato",
"<b>Note:</b> " => "<b>Nota:</b>",
" and " => "e",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configurazione",
"Available for" => "Disponibile per",
"Add storage" => "Aggiungi archiviazione",
-"No user or group" => "Nessun utente o gruppo",
-"All Users" => "Tutti gli utenti",
-"Groups" => "Gruppi",
-"Users" => "Utenti",
"Delete" => "Elimina",
"Enable User External Storage" => "Abilita la memoria esterna dell'utente",
"Allow users to mount the following external storage" => "Consenti agli utenti di montare la seguente memoria esterna",
diff --git a/apps/files_external/l10n/ja.php b/apps/files_external/l10n/ja.php
index 0350dbf169e..ce4b336facb 100644
--- a/apps/files_external/l10n/ja.php
+++ b/apps/files_external/l10n/ja.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 と互換ストレージ",
"Access Key" => "アクセスキー",
"Secret Key" => "シークレットキー",
-"Hostname (optional)" => "ホスト名 (オプション)",
-"Port (optional)" => "ポート (オプション)",
-"Region (optional)" => "リージョン (オプション)",
"Enable SSL" => "SSLを有効",
"Enable Path Style" => "パス形式を有効",
"App key" => "アプリキー",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "クライアントID",
"Client secret" => "クライアント秘密キー",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "ユーザー名 (必須)",
-"Bucket (required)" => "バケット (必須)",
"Region (optional for OpenStack Object Storage)" => "リージョン (OpenStack Object Storage用のオプション)",
"API Key (required for Rackspace Cloud Files)" => "APIキー (Rackspace Cloud Filesに必須)",
"Tenantname (required for OpenStack Object Storage)" => "テナント名 (OpenStack Object Storage用に必要)",
"Password (required for OpenStack Object Storage)" => "パスワード (OpenStack Object Storage用に必要)",
"Service Name (required for OpenStack Object Storage)" => "サービス名 (OpenStack Object Storage用に必要)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "識別用エンドポイントURL (OpenStack Object Storage用に必要)",
-"Timeout of HTTP requests in seconds (optional)" => "HTTPリクエストのタイムアウト秒数 (オプション)",
"Share" => "共有",
"SMB / CIFS using OC login" => "ownCloudログインで SMB/CIFSを使用",
"Username as share" => "共有名",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "設定",
"Available for" => "以下が利用可能",
"Add storage" => "ストレージを追加",
-"No user or group" => "ユーザーもしくはグループがありません",
-"All Users" => "すべてのユーザー",
-"Groups" => "グループ",
-"Users" => "ユーザー",
"Delete" => "削除",
"Enable User External Storage" => "ユーザーの外部ストレージを有効にする",
"Allow users to mount the following external storage" => "ユーザーに以下の外部ストレージのマウントを許可する",
diff --git a/apps/files_external/l10n/ka_GE.php b/apps/files_external/l10n/ka_GE.php
index 0fa65b83505..38fcc433c6e 100644
--- a/apps/files_external/l10n/ka_GE.php
+++ b/apps/files_external/l10n/ka_GE.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "ფოლდერის სახელი",
"Configuration" => "კონფიგურაცია",
"Add storage" => "საცავის დამატება",
-"All Users" => "ყველა მომხმარებელი",
-"Groups" => "ჯგუფები",
-"Users" => "მომხმარებელი",
"Delete" => "წაშლა",
"Enable User External Storage" => "მომხმარებლის ექსტერნალ საცავის აქტივირება",
"SSL root certificates" => "SSL root სერთიფიკატები",
diff --git a/apps/files_external/l10n/km.php b/apps/files_external/l10n/km.php
index 3f6e0395a68..f9101ff38da 100644
--- a/apps/files_external/l10n/km.php
+++ b/apps/files_external/l10n/km.php
@@ -17,9 +17,6 @@ $TRANSLATIONS = array(
"Folder name" => "ឈ្មោះ​ថត",
"Configuration" => "ការ​កំណត់​សណ្ឋាន",
"Add storage" => "បន្ថែម​ឃ្លាំងផ្ទុក",
-"All Users" => "អ្នក​ប្រើ​ទាំងអស់",
-"Groups" => "ក្រុ",
-"Users" => "អ្នកប្រើ",
"Delete" => "លុប"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/apps/files_external/l10n/ko.php b/apps/files_external/l10n/ko.php
index 706f824de6e..e43f21a1fdd 100644
--- a/apps/files_external/l10n/ko.php
+++ b/apps/files_external/l10n/ko.php
@@ -20,9 +20,6 @@ $TRANSLATIONS = array(
"Folder name" => "폴더 이름",
"Configuration" => "설정",
"Add storage" => "저장소 추가",
-"All Users" => "모든 사용자",
-"Groups" => "그룹",
-"Users" => "사용자",
"Delete" => "삭제",
"Enable User External Storage" => "사용자 외부 저장소 사용",
"SSL root certificates" => "SSL 루트 인증서",
diff --git a/apps/files_external/l10n/ku_IQ.php b/apps/files_external/l10n/ku_IQ.php
index 9c4b2a3d498..097f8d3199c 100644
--- a/apps/files_external/l10n/ku_IQ.php
+++ b/apps/files_external/l10n/ku_IQ.php
@@ -6,7 +6,6 @@ $TRANSLATIONS = array(
"Share" => "هاوبەشی کردن",
"URL" => "ناونیشانی به‌سته‌ر",
"Name" => "ناو",
-"Folder name" => "ناوی بوخچه",
-"Users" => "به‌كارهێنه‌ر"
+"Folder name" => "ناوی بوخچه"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/lb.php b/apps/files_external/l10n/lb.php
index 0b78eb91a8d..737291269c3 100644
--- a/apps/files_external/l10n/lb.php
+++ b/apps/files_external/l10n/lb.php
@@ -9,8 +9,6 @@ $TRANSLATIONS = array(
"Personal" => "Perséinlech",
"Name" => "Numm",
"Folder name" => "Dossiers Numm:",
-"Groups" => "Gruppen",
-"Users" => "Benotzer",
"Delete" => "Läschen"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/lt_LT.php b/apps/files_external/l10n/lt_LT.php
index ff4fc0a4456..6440460da3f 100644
--- a/apps/files_external/l10n/lt_LT.php
+++ b/apps/files_external/l10n/lt_LT.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "Katalogo pavadinimas",
"Configuration" => "Konfigūracija",
"Add storage" => "Pridėti saugyklą",
-"All Users" => "Visi vartotojai",
-"Groups" => "Grupės",
-"Users" => "Vartotojai",
"Delete" => "Ištrinti",
"Enable User External Storage" => "Įjungti vartotojų išorines saugyklas",
"SSL root certificates" => "SSL sertifikatas",
diff --git a/apps/files_external/l10n/lv.php b/apps/files_external/l10n/lv.php
index 5abf7aa4b7c..debbe4c3e06 100644
--- a/apps/files_external/l10n/lv.php
+++ b/apps/files_external/l10n/lv.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "Mapes nosaukums",
"Configuration" => "Konfigurācija",
"Add storage" => "Pievienot krātuvi",
-"All Users" => "Visi lietotāji",
-"Groups" => "Grupas",
-"Users" => "Lietotāji",
"Delete" => "Dzēst",
"Enable User External Storage" => "Aktivēt lietotāja ārējo krātuvi",
"SSL root certificates" => "SSL saknes sertifikāti",
diff --git a/apps/files_external/l10n/mk.php b/apps/files_external/l10n/mk.php
index def422f4072..db340d09c4f 100644
--- a/apps/files_external/l10n/mk.php
+++ b/apps/files_external/l10n/mk.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"External Storage" => "Надворешно складиште",
"Folder name" => "Име на папка",
"Configuration" => "Конфигурација",
-"All Users" => "Сите корисници",
-"Groups" => "Групи",
-"Users" => "Корисници",
"Delete" => "Избриши",
"Enable User External Storage" => "Овозможи надворешни за корисници",
"SSL root certificates" => "SSL root сертификати",
diff --git a/apps/files_external/l10n/ms_MY.php b/apps/files_external/l10n/ms_MY.php
index 22e5f30c4dd..12957844ccb 100644
--- a/apps/files_external/l10n/ms_MY.php
+++ b/apps/files_external/l10n/ms_MY.php
@@ -7,8 +7,6 @@ $TRANSLATIONS = array(
"URL" => "URL",
"Personal" => "Peribadi",
"Name" => "Nama",
-"Groups" => "Kumpulan",
-"Users" => "Pengguna",
"Delete" => "Padam"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/apps/files_external/l10n/my_MM.php b/apps/files_external/l10n/my_MM.php
index 775fa4d9885..bf50d1b1b6d 100644
--- a/apps/files_external/l10n/my_MM.php
+++ b/apps/files_external/l10n/my_MM.php
@@ -2,7 +2,6 @@
$TRANSLATIONS = array(
"Location" => "တည်နေရာ",
"Username" => "သုံးစွဲသူအမည်",
-"Password" => "စကားဝှက်",
-"Users" => "သုံးစွဲသူ"
+"Password" => "စကားဝှက်"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/apps/files_external/l10n/nb_NO.php b/apps/files_external/l10n/nb_NO.php
index caeeb8eed6b..024f6c46ca1 100644
--- a/apps/files_external/l10n/nb_NO.php
+++ b/apps/files_external/l10n/nb_NO.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 og tilsvarende",
"Access Key" => "Access Key",
"Secret Key" => "Secret Key",
-"Hostname (optional)" => "Servernavn (ikke påkrevd)",
-"Port (optional)" => "Port (ikke påkrevd)",
-"Region (optional)" => "Region (ikke påkrevd)",
"Enable SSL" => "Aktiver SSL",
"Enable Path Style" => "Aktiver Path Style",
"App key" => "App key",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Client secret",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Brukernavn (påkrevet)",
-"Bucket (required)" => "Bucket (påkrevet)",
"Region (optional for OpenStack Object Storage)" => "Region (ikke påkrevet for OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API Key (påkrevet for Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (påkrevet for OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Passord (påkrevet for OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Tjenestenavn (påkrevet for OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL for identity endpoint (påkrevet for OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Tidsavbrudd for HTTP-spørringer i sekunder (ikke påkrevet)",
"Share" => "Del",
"SMB / CIFS using OC login" => "SMB / CIFS med OC-pålogging",
"Username as share" => "Brukernavn som share",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfigurasjon",
"Available for" => "Tilgjengelig for",
"Add storage" => "Legg til lagringsplass",
-"No user or group" => "Ingen bruker eller gruppe",
-"All Users" => "Alle brukere",
-"Groups" => "Grupper",
-"Users" => "Brukere",
"Delete" => "Slett",
"Enable User External Storage" => "Aktiver ekstern lagring for bruker",
"Allow users to mount the following external storage" => "Tillat brukere å koble opp følgende eksterne lagring",
diff --git a/apps/files_external/l10n/nl.php b/apps/files_external/l10n/nl.php
index 8e0790f15be..f66e9f1c292 100644
--- a/apps/files_external/l10n/nl.php
+++ b/apps/files_external/l10n/nl.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 en overeenkomstig",
"Access Key" => "Access Key",
"Secret Key" => "Secret Key",
-"Hostname (optional)" => "Hostname (optioneel)",
-"Port (optional)" => "Poort (optioneel)",
-"Region (optional)" => "Regio (optioneel)",
"Enable SSL" => "Activeren SSL",
"Enable Path Style" => "Activeren pad stijl",
"App key" => "App key",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Client secret",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Gebruikersnaam (verplicht)",
-"Bucket (required)" => "Bucket (verplicht)",
"Region (optional for OpenStack Object Storage)" => "Regio (optioneel voor OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API Key (verplicht voor Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (Verplicht voor OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Wachtwoord (verplicht voor OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Service Name (verplicht voor OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL van identity endpoint (verplicht voor OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Time-out van HTTP aanvragen in seconden (optioneel)",
"Share" => "Share",
"SMB / CIFS using OC login" => "SMB / CIFS via OC inlog",
"Username as share" => "Gebruikersnaam als share",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Fout tijdens het configureren van Google Drive opslag",
"Personal" => "Persoonlijk",
"System" => "Systeem",
+"All users. Type to select user or group." => "Alle gebruikers. Tikken om een gebruiker of groep te selecteren.",
+"(group)" => "(groep)",
"Saved" => "Bewaard",
"<b>Note:</b> " => "<b>Let op:</b> ",
" and " => "en",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuratie",
"Available for" => "Beschikbaar voor",
"Add storage" => "Toevoegen opslag",
-"No user or group" => "Geen gebruiker of groep",
-"All Users" => "Alle gebruikers",
-"Groups" => "Groepen",
-"Users" => "Gebruikers",
"Delete" => "Verwijder",
"Enable User External Storage" => "Externe opslag voor gebruikers activeren",
"Allow users to mount the following external storage" => "Sta gebruikers toe de volgende externe opslag aan te koppelen",
diff --git a/apps/files_external/l10n/nn_NO.php b/apps/files_external/l10n/nn_NO.php
index ce0a76f33c2..5362b4e285a 100644
--- a/apps/files_external/l10n/nn_NO.php
+++ b/apps/files_external/l10n/nn_NO.php
@@ -10,8 +10,6 @@ $TRANSLATIONS = array(
"Name" => "Namn",
"Folder name" => "Mappenamn",
"Configuration" => "Innstillingar",
-"Groups" => "Grupper",
-"Users" => "Brukarar",
"Delete" => "Slett"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/oc.php b/apps/files_external/l10n/oc.php
index 1ffdf1b10f6..af4b03e3c15 100644
--- a/apps/files_external/l10n/oc.php
+++ b/apps/files_external/l10n/oc.php
@@ -7,8 +7,6 @@ $TRANSLATIONS = array(
"URL" => "URL",
"Personal" => "Personal",
"Name" => "Nom",
-"Groups" => "Grops",
-"Users" => "Usancièrs",
"Delete" => "Escafa"
);
$PLURAL_FORMS = "nplurals=2; plural=(n > 1);";
diff --git a/apps/files_external/l10n/pa.php b/apps/files_external/l10n/pa.php
index 0bdcf0b7f67..14e0fe78ae0 100644
--- a/apps/files_external/l10n/pa.php
+++ b/apps/files_external/l10n/pa.php
@@ -3,7 +3,6 @@ $TRANSLATIONS = array(
"Username" => "ਯੂਜ਼ਰ-ਨਾਂ",
"Password" => "ਪਾਸਵਰ",
"Share" => "ਸਾਂਝਾ ਕਰੋ",
-"Groups" => "ਗਰੁੱਪ",
"Delete" => "ਹਟਾਓ"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/pl.php b/apps/files_external/l10n/pl.php
index 9395c85307b..99f4ec2d39b 100644
--- a/apps/files_external/l10n/pl.php
+++ b/apps/files_external/l10n/pl.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 i zgodne",
"Access Key" => "Klucz dostępu",
"Secret Key" => "Klucz hasła",
-"Hostname (optional)" => "Nazwa hosta (opcjonalnie)",
-"Port (optional)" => "Port (opcjonalnie)",
-"Region (optional)" => "Region (opcjonalnie)",
"Enable SSL" => "Włącz SSL",
"Enable Path Style" => "Włącz styl ścieżki",
"App key" => "Klucz aplikacji",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID klienta",
"Client secret" => "Hasło klienta",
"OpenStack Object Storage" => "Magazyn obiektów OpenStack",
-"Username (required)" => "Użytkownik (wymagany)",
-"Bucket (required)" => "Kosz (wymagany)",
"Region (optional for OpenStack Object Storage)" => "Region (opcjonalny dla magazynu obiektów OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Klucz API (wymagany dla plików Rackspace Cloud)",
"Tenantname (required for OpenStack Object Storage)" => "Nazwa najemcy (wymagana dla magazynu obiektów OpenStack)",
"Password (required for OpenStack Object Storage)" => "Hasło (wymagane dla magazynu obiektów OpenStack)",
"Service Name (required for OpenStack Object Storage)" => "Nazwa usługi (wymagana dla magazynu obiektów OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL lub zakończenie jednostki (wymagane dla magazynu obiektów OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Czas wygaśnięcia żądań HTTP w sekundach (opcjonalne)",
"Share" => "Udostępnij",
"SMB / CIFS using OC login" => "SMB / CIFS przy użyciu loginu OC",
"Username as share" => "Użytkownik jako zasób",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfiguracja",
"Available for" => "Dostępne przez",
"Add storage" => "Dodaj zasoby dyskowe",
-"No user or group" => "Brak użytkownika lub grupy",
-"All Users" => "Wszyscy uzytkownicy",
-"Groups" => "Grupy",
-"Users" => "Użytkownicy",
"Delete" => "Usuń",
"Enable User External Storage" => "Włącz zewnętrzne zasoby dyskowe użytkownika",
"Allow users to mount the following external storage" => "Pozwól użytkownikom montować następujące zewnętrzne zasoby dyskowe",
diff --git a/apps/files_external/l10n/pt_BR.php b/apps/files_external/l10n/pt_BR.php
index f422b712053..8a269218a6b 100644
--- a/apps/files_external/l10n/pt_BR.php
+++ b/apps/files_external/l10n/pt_BR.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 e compatível",
"Access Key" => "Chave de Acesso",
"Secret Key" => "Chave Secreta",
-"Hostname (optional)" => "Nome do Host (opcional)",
-"Port (optional)" => "Porta (opcional)",
-"Region (optional)" => "Região (opcional)",
"Enable SSL" => "Habilitar SSL",
"Enable Path Style" => "Habilitar Estilo do Caminho",
"App key" => "Chave do Aplicativo",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID do Cliente",
"Client secret" => "Segredo do cliente",
"OpenStack Object Storage" => "Armazenamento de Objetos OpenStack",
-"Username (required)" => "Nome do Usuário (requerido)",
-"Bucket (required)" => "Cesta (requerido)",
"Region (optional for OpenStack Object Storage)" => "Região (opcional para armazenamento de objetos OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Chave API (necessário para Rackspace Cloud File)",
"Tenantname (required for OpenStack Object Storage)" => "Nome Tenant (necessário para armazenamento de objetos OpenStack)",
"Password (required for OpenStack Object Storage)" => "Senha (necessário para armazenamento de objetos OpenStack)",
"Service Name (required for OpenStack Object Storage)" => "Nome do Serviço (necessário para armazenamento de objetos OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Ponto final de identidade da URL (obrigatório para armazenamento de objetos OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Tempo limite de solicitações HTTP em segundos (opcional)",
"Share" => "Compartilhar",
"SMB / CIFS using OC login" => "SMB / CIFS usando OC login",
"Username as share" => "Nome de usuário como compartilhado",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Erro ao configurar armazenamento do Google Drive",
"Personal" => "Pessoal",
"System" => "Sistema",
+"All users. Type to select user or group." => "Todos os usuários. Digite para selecionar usuário ou grupo.",
+"(group)" => "(grupo)",
"Saved" => "Salvo",
"<b>Note:</b> " => "<b>Nota:</b>",
" and " => "e",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuração",
"Available for" => "Disponível para",
"Add storage" => "Adicionar Armazenamento",
-"No user or group" => "Nenhum usuário ou grupo",
-"All Users" => "Todos os Usuários",
-"Groups" => "Grupos",
-"Users" => "Usuários",
"Delete" => "Excluir",
"Enable User External Storage" => "Habilitar Armazenamento Externo do Usuário",
"Allow users to mount the following external storage" => "Permitir que usuários montem o seguinte armazenamento externo",
diff --git a/apps/files_external/l10n/pt_PT.php b/apps/files_external/l10n/pt_PT.php
index 486456c810c..a95439fbfed 100644
--- a/apps/files_external/l10n/pt_PT.php
+++ b/apps/files_external/l10n/pt_PT.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 e compatível",
"Access Key" => "Chave de acesso",
"Secret Key" => "Chave Secreta",
-"Hostname (optional)" => "Nome do Hospedeiro (opcional)",
-"Port (optional)" => "Porta (opcional)",
-"Region (optional)" => "Região (opcional)",
"Enable SSL" => "Activar SSL",
"Enable Path Style" => "Ativar Estilo do Caminho",
"App key" => "Chave da aplicação",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID Cliente",
"Client secret" => "Segredo do cliente",
"OpenStack Object Storage" => "Armazenamento de objetos OpenStack",
-"Username (required)" => "Utilizador (requerido)",
-"Bucket (required)" => "Bucket (necessário)",
"Region (optional for OpenStack Object Storage)" => "Região (opcional para OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "Chave API (necessário para Rackspace Cloud File)",
"Tenantname (required for OpenStack Object Storage)" => "Nome do Serviço (necessário para OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Senha (necessária para OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Nome do Serviço (necessário para OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Nome do Serviço (necessário para OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Timeout de solicitações HTTP em segundos (opcional)",
"Share" => "Partilhar",
"SMB / CIFS using OC login" => "SMB / CIFS utilizando o início de sessão OC",
"Username as share" => "Utilizar nome de utilizador como partilha",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Configuração",
"Available for" => "Disponível para ",
"Add storage" => "Adicionar armazenamento",
-"No user or group" => "Sem utilizador nem grupo",
-"All Users" => "Todos os utilizadores",
-"Groups" => "Grupos",
-"Users" => "Utilizadores",
"Delete" => "Eliminar",
"Enable User External Storage" => "Activar Armazenamento Externo para o Utilizador",
"Allow users to mount the following external storage" => "Permitir que os utilizadores montem o seguinte armazenamento externo",
diff --git a/apps/files_external/l10n/ro.php b/apps/files_external/l10n/ro.php
index eaed049e865..130187dd585 100644
--- a/apps/files_external/l10n/ro.php
+++ b/apps/files_external/l10n/ro.php
@@ -4,7 +4,6 @@ $TRANSLATIONS = array(
"External storage" => "Stocare externă",
"Location" => "Locație",
"Amazon S3" => "Amazon S3",
-"Region (optional)" => "Regiune",
"Host" => "Gazdă",
"Username" => "Nume utilizator",
"Password" => "Parolă",
@@ -23,9 +22,6 @@ $TRANSLATIONS = array(
"Folder name" => "Denumire director",
"Configuration" => "Configurație",
"Add storage" => "Adauga stocare",
-"All Users" => "Toți utilizatorii",
-"Groups" => "Grupuri",
-"Users" => "Utilizatori",
"Delete" => "Șterge",
"Enable User External Storage" => "Permite stocare externă pentru utilizatori",
"Allow users to mount the following external storage" => "Permite utilizatorilor să monteze următoarea unitate de stocare",
diff --git a/apps/files_external/l10n/ru.php b/apps/files_external/l10n/ru.php
index 75b3dcd100a..76c0011c473 100644
--- a/apps/files_external/l10n/ru.php
+++ b/apps/files_external/l10n/ru.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 и совместимый",
"Access Key" => "Ключ доступа",
"Secret Key" => "Секретный ключ",
-"Hostname (optional)" => "Хост (опц.)",
-"Port (optional)" => "Порт (опц.)",
-"Region (optional)" => "Регион (опц.)",
"Enable SSL" => "Включить SSL",
"Enable Path Style" => "Включить стиль пути",
"App key" => "Ключ приложения",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Идентификатор клиента",
"Client secret" => "Клиентский ключ ",
"OpenStack Object Storage" => "Хранилище объектов OpenStack",
-"Username (required)" => "Имя пользователя (обяз.)",
-"Bucket (required)" => "Bucket (обяз.)",
"Region (optional for OpenStack Object Storage)" => "Регион (необяз. для Хранилища объектов OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Ключ API (обяз. для Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Имя арендатора (обяз. для Хранилища объектов OpenStack)",
"Password (required for OpenStack Object Storage)" => "Пароль (обяз. для Хранилища объектов OpenStack)",
"Service Name (required for OpenStack Object Storage)" => "Имя Службы (обяз. для Хранилища объектов OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL для удостоверения конечной точки (обяз. для Хранилища объектов OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Тайм-аут HTTP запросов в секундах (опционально)",
"Share" => "Открыть доступ",
"SMB / CIFS using OC login" => "SMB / CIFS с ипользованием логина OC",
"Username as share" => "Имя для открытого доступа",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Конфигурация",
"Available for" => "Доступно для",
"Add storage" => "Добавить хранилище",
-"No user or group" => "Нет пользователя или группы",
-"All Users" => "Все пользователи",
-"Groups" => "Группы",
-"Users" => "Пользователи",
"Delete" => "Удалить",
"Enable User External Storage" => "Включить пользовательские внешние носители",
"Allow users to mount the following external storage" => "Разрешить пользователям монтировать следующее внешнее хранилище данных",
diff --git a/apps/files_external/l10n/si_LK.php b/apps/files_external/l10n/si_LK.php
index 06b3c7616e6..533f4ce87a7 100644
--- a/apps/files_external/l10n/si_LK.php
+++ b/apps/files_external/l10n/si_LK.php
@@ -16,9 +16,6 @@ $TRANSLATIONS = array(
"External Storage" => "භාහිර ගබඩාව",
"Folder name" => "ෆොල්ඩරයේ නම",
"Configuration" => "වින්‍යාසය",
-"All Users" => "සියළු පරිශීලකයන්",
-"Groups" => "කණ්ඩායම්",
-"Users" => "පරිශීලකයන්",
"Delete" => "මකා දමන්න",
"Enable User External Storage" => "පරිශීලක භාහිර ගබඩාවන් සක්‍රිය කරන්න",
"SSL root certificates" => "SSL මූල සහතිකයන්",
diff --git a/apps/files_external/l10n/sk_SK.php b/apps/files_external/l10n/sk_SK.php
index 3bd9587eee9..2bbcf511a9b 100644
--- a/apps/files_external/l10n/sk_SK.php
+++ b/apps/files_external/l10n/sk_SK.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 a kompatibilné",
"Access Key" => "Prístupový kľúč",
"Secret Key" => "Tajný kľúč",
-"Hostname (optional)" => "Hostname (voliteľný)",
-"Port (optional)" => "Port (voliteľný)",
-"Region (optional)" => "Región (voliteľný)",
"Enable SSL" => "Povoliť SSL",
"Enable Path Style" => "Povoliť štýl cesty",
"App key" => "Kľúč aplikácie",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "Client ID",
"Client secret" => "Heslo klienta",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Používateľské meno (povinné)",
-"Bucket (required)" => "Sektor (povinné)",
"Region (optional for OpenStack Object Storage)" => "Región (voliteľné pre OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API Key (požadované pre Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (požadované pre OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Heslo (požadované pre OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Meno služby (požadované pre OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL of identity endpoint (požadované pre OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Vypršanie HTTP požadiavkiek v sekundách (voliteľné)",
"Share" => "Zdieľať",
"SMB / CIFS using OC login" => "SMB / CIFS s použitím OC prihlásenia",
"Username as share" => "Používateľské meno ako zdieľaný priečinok",
@@ -66,10 +60,6 @@ $TRANSLATIONS = array(
"Configuration" => "Nastavenia",
"Available for" => "K dispozícii pre",
"Add storage" => "Pridať úložisko",
-"No user or group" => "Žiadny používateľ alebo skupina",
-"All Users" => "Všetci používatelia",
-"Groups" => "Skupiny",
-"Users" => "Používatelia",
"Delete" => "Zmazať",
"Enable User External Storage" => "Povoliť externé úložisko",
"Allow users to mount the following external storage" => "Povoliť používateľom pripojiť tieto externé úložiská",
diff --git a/apps/files_external/l10n/sl.php b/apps/files_external/l10n/sl.php
index 2bbb29b7ac5..d8b9dda0e0c 100644
--- a/apps/files_external/l10n/sl.php
+++ b/apps/files_external/l10n/sl.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 in podobno",
"Access Key" => "Ključ za dostop",
"Secret Key" => "Skrivni ključ",
-"Hostname (optional)" => "Ime gostitelja (izbirno)",
-"Port (optional)" => "Vrata (izbirno)",
-"Region (optional)" => "Območje (izbirno)",
"Enable SSL" => "Omogoči SSL",
"Enable Path Style" => "Omogoči slog poti",
"App key" => "Programski ključ",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "ID odjemalca",
"Client secret" => "Skrivni ključ odjemalca",
"OpenStack Object Storage" => "Shramba predmeta OpenStack",
-"Username (required)" => "Uporabniško ime (zahtevano)",
-"Bucket (required)" => "Pomnilniško vedro (zahtevano)",
"Region (optional for OpenStack Object Storage)" => "Območje (zahtevano za shrambo predmeta OpenStack)",
"API Key (required for Rackspace Cloud Files)" => "Ključ programskega vmesnika (API) (zahtevan je za datoteke v oblaku Rackspace)",
"Tenantname (required for OpenStack Object Storage)" => "Ime uporabnika (zahtevano za shrambo predmeta OpenStack)",
"Password (required for OpenStack Object Storage)" => "Geslo (zahtevano za shrambo predmeta OpenStack)",
"Service Name (required for OpenStack Object Storage)" => "Ime storitve (zahtevano za shrambo predmeta OpenStack)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Naslov URL končne točke uporabnika (zahtevano za shrambo predmeta OpenStack)",
-"Timeout of HTTP requests in seconds (optional)" => "Časovni zamik zahtev HTTP v sekundah (izbirno)",
"Share" => "Souporaba",
"SMB / CIFS using OC login" => "SMB / CIFS z uporabo prijave OC",
"Username as share" => "Uporabniško ime za souporabo",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Napaka nastavljanja shrambe Google Drive",
"Personal" => "Osebno",
"System" => "Sistem",
+"All users. Type to select user or group." => "Vsi uporabniki. Skupino ali uporabnika je mogoče tudi izbrati.",
+"(group)" => "(skupina)",
"Saved" => "Shranjeno",
"<b>Note:</b> " => "<b>Opomba:</b> ",
" and " => "in",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Nastavitve",
"Available for" => "Na voljo za",
"Add storage" => "Dodaj shrambo",
-"No user or group" => "Ni uporabnika ali skupine",
-"All Users" => "Vsi uporabniki",
-"Groups" => "Skupine",
-"Users" => "Uporabniki",
"Delete" => "Izbriši",
"Enable User External Storage" => "Omogoči zunanjo uporabniško podatkovno shrambo",
"Allow users to mount the following external storage" => "Dovoli uporabnikom priklapljanje navedenih zunanjih shramb.",
diff --git a/apps/files_external/l10n/sq.php b/apps/files_external/l10n/sq.php
index dff94158b53..d6bffb90570 100644
--- a/apps/files_external/l10n/sq.php
+++ b/apps/files_external/l10n/sq.php
@@ -10,8 +10,6 @@ $TRANSLATIONS = array(
"Saved" => "U ruajt",
"Name" => "Emri",
"Folder name" => "Emri i Skedarit",
-"Groups" => "Grupet",
-"Users" => "Përdoruesit",
"Delete" => "Elimino"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/sr.php b/apps/files_external/l10n/sr.php
index 532cdb50ed4..28247f8d7ce 100644
--- a/apps/files_external/l10n/sr.php
+++ b/apps/files_external/l10n/sr.php
@@ -7,8 +7,6 @@ $TRANSLATIONS = array(
"Share" => "Дели",
"Personal" => "Лично",
"Name" => "Име",
-"Groups" => "Групе",
-"Users" => "Корисници",
"Delete" => "Обриши"
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/apps/files_external/l10n/sr@latin.php b/apps/files_external/l10n/sr@latin.php
index 820ec7288ed..8a476118eba 100644
--- a/apps/files_external/l10n/sr@latin.php
+++ b/apps/files_external/l10n/sr@latin.php
@@ -6,8 +6,6 @@ $TRANSLATIONS = array(
"Share" => "Podeli",
"Personal" => "Lično",
"Name" => "Ime",
-"Groups" => "Grupe",
-"Users" => "Korisnici",
"Delete" => "Obriši"
);
$PLURAL_FORMS = "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);";
diff --git a/apps/files_external/l10n/sv.php b/apps/files_external/l10n/sv.php
index de412f66eb2..deb78cb3749 100644
--- a/apps/files_external/l10n/sv.php
+++ b/apps/files_external/l10n/sv.php
@@ -13,9 +13,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 och compliant",
"Access Key" => "Accessnyckel",
"Secret Key" => "Hemlig nyckel",
-"Hostname (optional)" => "Värdnamn (valfritt)",
-"Port (optional)" => "Port (valfritt)",
-"Region (optional)" => "Region (valfritt)",
"Enable SSL" => "Aktivera SSL",
"Enable Path Style" => "Aktivera Path Style",
"App key" => "App-nyckel",
@@ -28,15 +25,12 @@ $TRANSLATIONS = array(
"Client ID" => "Klient ID",
"Client secret" => "klient secret",
"OpenStack Object Storage" => "OpenStack Object Storage",
-"Username (required)" => "Användarnamn (måste anges)",
-"Bucket (required)" => "Bucket (krävs)",
"Region (optional for OpenStack Object Storage)" => "Region (valfritt för OpenStack Object Storage)",
"API Key (required for Rackspace Cloud Files)" => "API-nyckel (krävs för Rackspace Cloud Files)",
"Tenantname (required for OpenStack Object Storage)" => "Tenantname (krävs för OpenStack Object Storage)",
"Password (required for OpenStack Object Storage)" => "Lösenord (krävs för OpenStack Object Storage)",
"Service Name (required for OpenStack Object Storage)" => "Tjänstens namn (krävs för OpenStack Object Storage)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "URL för identitetens slutpunkt (krävs för OpenStack Object Storage)",
-"Timeout of HTTP requests in seconds (optional)" => "Timeout för HTTP-förfrågningar i sekunder (tillval)",
"Share" => "Dela",
"SMB / CIFS using OC login" => "SMB / CIFS använder OC inloggning",
"Username as share" => "Användarnamn till utdelning",
@@ -64,10 +58,6 @@ $TRANSLATIONS = array(
"Configuration" => "Konfiguration",
"Available for" => "Tillgänglig för",
"Add storage" => "Lägg till lagring",
-"No user or group" => "Ingen användare eller grupp",
-"All Users" => "Alla användare",
-"Groups" => "Grupper",
-"Users" => "Användare",
"Delete" => "Radera",
"Enable User External Storage" => "Aktivera extern lagring för användare",
"Allow users to mount the following external storage" => "Tillåt användare att montera följande extern lagring",
diff --git a/apps/files_external/l10n/ta_LK.php b/apps/files_external/l10n/ta_LK.php
index 4f2b2c8a26b..212e9b64ea9 100644
--- a/apps/files_external/l10n/ta_LK.php
+++ b/apps/files_external/l10n/ta_LK.php
@@ -16,9 +16,6 @@ $TRANSLATIONS = array(
"External Storage" => "வெளி சேமிப்பு",
"Folder name" => "கோப்புறை பெயர்",
"Configuration" => "தகவமைப்பு",
-"All Users" => "பயனாளர்கள் எல்லாம்",
-"Groups" => "குழுக்கள்",
-"Users" => "பயனாளர்",
"Delete" => "நீக்குக",
"Enable User External Storage" => "பயனாளர் வெளி சேமிப்பை இயலுமைப்படுத்துக",
"SSL root certificates" => "SSL வேர் சான்றிதழ்கள்",
diff --git a/apps/files_external/l10n/te.php b/apps/files_external/l10n/te.php
index 98a31a2e314..73e828ebfcb 100644
--- a/apps/files_external/l10n/te.php
+++ b/apps/files_external/l10n/te.php
@@ -5,7 +5,6 @@ $TRANSLATIONS = array(
"Personal" => "వ్యక్తిగతం",
"Name" => "పేరు",
"Folder name" => "సంచయం పేరు",
-"Users" => "వాడుకరులు",
"Delete" => "తొలగించు"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/th_TH.php b/apps/files_external/l10n/th_TH.php
index 63a221e7ea4..27c49f5fbd4 100644
--- a/apps/files_external/l10n/th_TH.php
+++ b/apps/files_external/l10n/th_TH.php
@@ -16,9 +16,6 @@ $TRANSLATIONS = array(
"External Storage" => "พื้นทีจัดเก็บข้อมูลจากภายนอก",
"Folder name" => "ชื่อโฟลเดอร์",
"Configuration" => "การกำหนดค่า",
-"All Users" => "ผู้ใช้งานทั้งหมด",
-"Groups" => "กลุ่ม",
-"Users" => "ผู้ใช้งาน",
"Delete" => "ลบ",
"Enable User External Storage" => "เปิดให้มีการใช้พื้นที่จัดเก็บข้อมูลของผู้ใช้งานจากภายนอกได้",
"SSL root certificates" => "ใบรับรองความปลอดภัยด้วยระบบ SSL จาก Root",
diff --git a/apps/files_external/l10n/tr.php b/apps/files_external/l10n/tr.php
index 26537b75879..705e812208f 100644
--- a/apps/files_external/l10n/tr.php
+++ b/apps/files_external/l10n/tr.php
@@ -15,9 +15,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 ve uyumlu olanlar",
"Access Key" => "Erişim Anahtarı",
"Secret Key" => "Gizli Anahtar",
-"Hostname (optional)" => "Makine Adı (isteğe bağlı)",
-"Port (optional)" => "Bağl. Nok. (isteğe bağlı)",
-"Region (optional)" => "Bölge (isteğe bağlı)",
"Enable SSL" => "SSL'yi Etkinleştir",
"Enable Path Style" => "Yol Biçemini Etkinleştir",
"App key" => "Uyg. anahtarı",
@@ -30,15 +27,12 @@ $TRANSLATIONS = array(
"Client ID" => "İstemci kimliği",
"Client secret" => "İstemci parolası",
"OpenStack Object Storage" => "OpenStack Nesne Depolama",
-"Username (required)" => "Kullanıcı adı (gerekli)",
-"Bucket (required)" => "Bucket (gerekli)",
"Region (optional for OpenStack Object Storage)" => "Bölge (OpenStack Nesne Depolaması için isteğe bağlı)",
"API Key (required for Rackspace Cloud Files)" => "API Anahtarı (Rackspace Bulut Dosyaları için gerekli)",
"Tenantname (required for OpenStack Object Storage)" => "Kiracı Adı (OpenStack Nesne Depolaması için gerekli)",
"Password (required for OpenStack Object Storage)" => "Parola (OpenStack Nesne Depolaması için gerekli)",
"Service Name (required for OpenStack Object Storage)" => "Hizmet Adı (OpenStack Nesne Depolaması için gerekli)",
"URL of identity endpoint (required for OpenStack Object Storage)" => "Kimlik uç nokta adresi (OpenStack Nesne Depolaması için gerekli)",
-"Timeout of HTTP requests in seconds (optional)" => "Saniye cinsinden HTTP istek zaman aşımı (isteğe bağlı)",
"Share" => "Paylaş",
"SMB / CIFS using OC login" => "OC oturumu kullanarak SMB / CIFS",
"Username as share" => "Paylaşım olarak kullanıcı adı",
@@ -51,6 +45,8 @@ $TRANSLATIONS = array(
"Error configuring Google Drive storage" => "Google Drive depo yapılandırma hatası",
"Personal" => "Kişisel",
"System" => "Sistem",
+"All users. Type to select user or group." => "Tüm kullanıcılar. Kullanıcı veya grup seçmek için yazın.",
+"(group)" => "(grup)",
"Saved" => "Kaydedildi",
"<b>Note:</b> " => "<b>Not:</b> ",
" and " => "ve",
@@ -66,10 +62,6 @@ $TRANSLATIONS = array(
"Configuration" => "Yapılandırma",
"Available for" => "Kullanabilenler",
"Add storage" => "Depo ekle",
-"No user or group" => "Kullanıcı veya grup yok",
-"All Users" => "Tüm Kullanıcılar",
-"Groups" => "Gruplar",
-"Users" => "Kullanıcılar",
"Delete" => "Sil",
"Enable User External Storage" => "Kullanıcılar için Harici Depolamayı Etkinleştir",
"Allow users to mount the following external storage" => "Kullanıcıların aşağıdaki harici depolamayı bağlamalarına izin ver",
diff --git a/apps/files_external/l10n/ug.php b/apps/files_external/l10n/ug.php
index 6574fa59cc9..6508595118e 100644
--- a/apps/files_external/l10n/ug.php
+++ b/apps/files_external/l10n/ug.php
@@ -11,8 +11,6 @@ $TRANSLATIONS = array(
"Name" => "ئاتى",
"Folder name" => "قىسقۇچ ئاتى",
"Configuration" => "سەپلىمە",
-"Groups" => "گۇرۇپپا",
-"Users" => "ئىشلەتكۈچىلەر",
"Delete" => "ئۆچۈر"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/apps/files_external/l10n/uk.php b/apps/files_external/l10n/uk.php
index 50ce1beb609..b64ace85883 100644
--- a/apps/files_external/l10n/uk.php
+++ b/apps/files_external/l10n/uk.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "Ім'я теки",
"Configuration" => "Налаштування",
"Add storage" => "Додати сховище",
-"All Users" => "Усі користувачі",
-"Groups" => "Групи",
-"Users" => "Користувачі",
"Delete" => "Видалити",
"Enable User External Storage" => "Активувати користувацькі зовнішні сховища",
"SSL root certificates" => "SSL корневі сертифікати",
diff --git a/apps/files_external/l10n/ur_PK.php b/apps/files_external/l10n/ur_PK.php
index 69791cabe81..e5b9089328d 100644
--- a/apps/files_external/l10n/ur_PK.php
+++ b/apps/files_external/l10n/ur_PK.php
@@ -7,7 +7,6 @@ $TRANSLATIONS = array(
"URL" => "یو ار ایل",
"Personal" => "شخصی",
"Name" => "اسم",
-"Users" => "یوزرز",
"Delete" => "حذف کریں"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_external/l10n/vi.php b/apps/files_external/l10n/vi.php
index b2dd7a261ba..b1b8def80b1 100644
--- a/apps/files_external/l10n/vi.php
+++ b/apps/files_external/l10n/vi.php
@@ -18,9 +18,6 @@ $TRANSLATIONS = array(
"Folder name" => "Tên thư mục",
"Configuration" => "Cấu hình",
"Add storage" => "Thêm bộ nhớ",
-"All Users" => "Tất cả người dùng",
-"Groups" => "Nhóm",
-"Users" => "Người dùng",
"Delete" => "Xóa",
"Enable User External Storage" => "Kích hoạt tính năng lưu trữ ngoài",
"SSL root certificates" => "Chứng chỉ SSL root",
diff --git a/apps/files_external/l10n/zh_CN.php b/apps/files_external/l10n/zh_CN.php
index 031ffd9cb92..9b576691363 100644
--- a/apps/files_external/l10n/zh_CN.php
+++ b/apps/files_external/l10n/zh_CN.php
@@ -10,9 +10,6 @@ $TRANSLATIONS = array(
"Amazon S3 and compliant" => "Amazon S3 和兼容协议",
"Access Key" => "访问密钥",
"Secret Key" => "秘钥",
-"Hostname (optional)" => "域名 (可选)",
-"Port (optional)" => "端口 (可选)",
-"Region (optional)" => "区域 (optional)",
"Enable SSL" => "启用 SSL",
"Enable Path Style" => "启用 Path Style",
"Host" => "主机",
@@ -21,9 +18,6 @@ $TRANSLATIONS = array(
"Root" => "根路径",
"Secure ftps://" => "安全 ftps://",
"OpenStack Object Storage" => "OpenStack 对象存储",
-"Username (required)" => "用户名 (必须)",
-"Bucket (required)" => "Bucket (必须)",
-"Timeout of HTTP requests in seconds (optional)" => "HTTP 请求超时(秒) (可选)",
"Share" => "共享",
"SMB / CIFS using OC login" => "SMB / CIFS 使用 OC 登录信息",
"URL" => "URL",
@@ -47,10 +41,6 @@ $TRANSLATIONS = array(
"Configuration" => "配置",
"Available for" => "可用于",
"Add storage" => "增加存储",
-"No user or group" => "无用户或组",
-"All Users" => "所有用户",
-"Groups" => "组",
-"Users" => "用户",
"Delete" => "删除",
"Enable User External Storage" => "启用用户外部存储",
"Allow users to mount the following external storage" => "允许用户挂载以下外部存储",
diff --git a/apps/files_external/l10n/zh_HK.php b/apps/files_external/l10n/zh_HK.php
index c31b20dbc99..33fc2113f92 100644
--- a/apps/files_external/l10n/zh_HK.php
+++ b/apps/files_external/l10n/zh_HK.php
@@ -8,8 +8,6 @@ $TRANSLATIONS = array(
"Saved" => "已儲存",
"Name" => "名稱",
"Folder name" => "資料夾名稱",
-"Groups" => "群組",
-"Users" => "用戶",
"Delete" => "刪除"
);
$PLURAL_FORMS = "nplurals=1; plural=0;";
diff --git a/apps/files_external/l10n/zh_TW.php b/apps/files_external/l10n/zh_TW.php
index 93e341fa516..66523be7fdd 100644
--- a/apps/files_external/l10n/zh_TW.php
+++ b/apps/files_external/l10n/zh_TW.php
@@ -8,14 +8,10 @@ $TRANSLATIONS = array(
"Key" => "鑰",
"Secret" => "密",
"Secret Key" => "密鑰",
-"Hostname (optional)" => "主機名稱 (選填)",
-"Port (optional)" => "埠號 (選填)",
-"Region (optional)" => "區域 (選填)",
"Enable SSL" => "啟用 SSL",
"Host" => "主機",
"Username" => "使用者名稱:",
"Password" => "密碼",
-"Username (required)" => "使用者名稱 (必填)",
"Share" => "分享",
"URL" => "URL",
"Access granted" => "允許存取",
@@ -37,10 +33,6 @@ $TRANSLATIONS = array(
"Configuration" => "設定",
"Available for" => "可用的",
"Add storage" => "增加儲存區",
-"No user or group" => "沒有使用者或群組",
-"All Users" => "所有使用者",
-"Groups" => "群組",
-"Users" => "使用者",
"Delete" => "刪除",
"Enable User External Storage" => "啓用使用者外部儲存",
"Allow users to mount the following external storage" => "允許使用者自行掛載以下的外部儲存",
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index c71132d0a5a..85e36fd9043 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -169,6 +169,7 @@ class OC_Mount_Config {
foreach ($options as &$option) {
$option = self::setUserVars($user, $option);
}
+ $options['personal'] = false;
$options['options'] = self::decryptPasswords($options['options']);
if (!isset($options['priority'])) {
$options['priority'] = $backends[$options['class']]['priority'];
diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/sftp.php
index e0655cc8d3d..aec56d088d5 100644
--- a/apps/files_external/lib/sftp.php
+++ b/apps/files_external/lib/sftp.php
@@ -166,6 +166,9 @@ class SFTP extends \OC\Files\Storage\Common {
public function opendir($path) {
try {
$list = $this->client->nlist($this->absPath($path));
+ if ($list === false) {
+ return false;
+ }
$id = md5('sftp:' . $path);
$dirStream = array();
diff --git a/apps/files_external/lib/smb_oc.php b/apps/files_external/lib/smb_oc.php
index 0c79c06c5df..e6f3aaf4052 100644
--- a/apps/files_external/lib/smb_oc.php
+++ b/apps/files_external/lib/smb_oc.php
@@ -14,12 +14,12 @@ class SMB_OC extends \OC\Files\Storage\SMB {
private $username_as_share;
public function __construct($params) {
- if (isset($params['host']) && \OC::$session->exists('smb-credentials')) {
+ if (isset($params['host']) && \OC::$server->getSession()->exists('smb-credentials')) {
$host=$params['host'];
$this->username_as_share = ($params['username_as_share'] === 'true');
- $params_auth = \OC::$session->get('smb-credentials');
- $user = \OC::$session->get('loginname');
+ $params_auth = \OC::$server->getSession()->get('smb-credentials');
+ $user = \OC::$server->getSession()->get('loginname');
$password = $params_auth['password'];
$root=isset($params['root'])?$params['root']:'/';
@@ -45,7 +45,7 @@ class SMB_OC extends \OC\Files\Storage\SMB {
}
public static function login( $params ) {
- \OC::$session->set('smb-credentials', $params);
+ \OC::$server->getSession()->set('smb-credentials', $params);
}
public function isSharable($path) {
diff --git a/apps/files_external/settings.php b/apps/files_external/settings.php
index 5b62b542200..4c87360486a 100644
--- a/apps/files_external/settings.php
+++ b/apps/files_external/settings.php
@@ -23,9 +23,10 @@
OC_Util::checkAdminUser();
OCP\Util::addScript('files_external', 'settings');
-OCP\Util::addscript('3rdparty', 'chosen/chosen.jquery.min');
OCP\Util::addStyle('files_external', 'settings');
-OCP\Util::addStyle('3rdparty', 'chosen/chosen');
+
+OCP\Util::addScript('files_external', '../3rdparty/select2/select2');
+OCP\Util::addStyle('files_external', '../3rdparty/select2/select2');
$backends = OC_Mount_Config::getBackends();
$personal_backends = array();
@@ -46,9 +47,6 @@ $tmpl->assign('isAdminPage', true);
$tmpl->assign('mounts', OC_Mount_Config::getSystemMountPoints());
$tmpl->assign('backends', $backends);
$tmpl->assign('personal_backends', $personal_backends);
-$tmpl->assign('groups', OC_Group::getGroups());
-$tmpl->assign('users', OCP\User::getUsers());
-$tmpl->assign('userDisplayNames', OC_User::getDisplayNames());
$tmpl->assign('dependencies', OC_Mount_Config::checkDependencies());
$tmpl->assign('allowUserMounting', OCP\Config::getAppValue('files_external', 'allow_user_mounting', 'yes'));
return $tmpl->fetchPage();
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 14f8ebc8000..dd283f9ff55 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -88,31 +88,8 @@
print_unescaped(json_encode($mount['applicable']['groups'])); ?>'
data-applicable-users='<?php if (isset($mount['applicable']['users']))
print_unescaped(json_encode($mount['applicable']['users'])); ?>'>
- <select class="chzn-select"
- multiple style="width:20em;"
- data-placeholder="<?php p($l->t('No user or group')); ?>">
- <option value="all"
- <?php if (empty($mount['class']) || (isset($mount['applicable']['users']) && in_array('all', $mount['applicable']['users']))) print_unescaped('selected="selected"');?> >
- <?php p($l->t('All Users')); ?>
- </option>
- <optgroup label="<?php p($l->t('Groups')); ?>">
- <?php foreach ($_['groups'] as $group): ?>
- <option value="<?php p($group); ?>(group)"
- <?php if (isset($mount['applicable']['groups']) && in_array($group, $mount['applicable']['groups'])): ?>
- selected="selected"
- <?php endif; ?>><?php p($group); ?></option>
- <?php endforeach; ?>
- </optgroup>
- <optgroup label="<?php p($l->t('Users')); ?>">
- <?php foreach ($_['users'] as $user): ?>
- <option value="<?php p($user); ?>"
- <?php if (isset($mount['applicable']['users']) && in_array($user, $mount['applicable']['users'])): ?>
- selected="selected"
- <?php endif; ?>><?php p($_['userDisplayNames'][$user]); ?></option>
- <?php endforeach; ?>
- </optgroup>
- </select>
- </td>
+ <input type="hidden" class="applicableUsers" style="width:20em;" value=""/>
+ </td>
<?php endif; ?>
<td <?php if (isset($mount['mountpoint'])): ?>class="remove"
<?php else: ?>style="visibility:hidden;"
diff --git a/apps/files_sharing/ajax/external.php b/apps/files_sharing/ajax/external.php
index 37d0607cd3f..544a97e80be 100644
--- a/apps/files_sharing/ajax/external.php
+++ b/apps/files_sharing/ajax/external.php
@@ -10,7 +10,7 @@ OCP\JSON::callCheck();
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('files_sharing');
-$l = OC_L10N::get('files_sharing');
+$l = \OC::$server->getL10N('files_sharing');
// check if server admin allows to mount public links from other servers
if (OCA\Files_Sharing\Helper::isIncomingServer2serverShareEnabled() === false) {
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index b22c553ec93..543cae7b0c1 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -1,5 +1,5 @@
<?php
-$l = OC_L10N::get('files_sharing');
+$l = \OC::$server->getL10N('files_sharing');
OC::$CLASSPATH['OC_Share_Backend_File'] = 'files_sharing/lib/share/file.php';
OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'files_sharing/lib/share/folder.php';
diff --git a/apps/files_sharing/l10n/ast.php b/apps/files_sharing/l10n/ast.php
index 879f231bf92..2a5004811b8 100644
--- a/apps/files_sharing/l10n/ast.php
+++ b/apps/files_sharing/l10n/ast.php
@@ -1,6 +1,7 @@
<?php
$TRANSLATIONS = array(
"Server to server sharing is not enabled on this server" => "La compartición sirvidor a sirvidor nun ta habilitada nesti sirvidor",
+"Invalid or untrusted SSL certificate" => "Certificáu SSL inválidu o ensín validar",
"Couldn't add remote share" => "Nun pudo amestase una compartición remota",
"Shared with you" => "Compartíos contigo",
"Shared with others" => "Compartíos con otros",
diff --git a/apps/files_sharing/l10n/bn_BD.php b/apps/files_sharing/l10n/bn_BD.php
index 2545c4760ec..50cc21e43dd 100644
--- a/apps/files_sharing/l10n/bn_BD.php
+++ b/apps/files_sharing/l10n/bn_BD.php
@@ -1,8 +1,9 @@
<?php
$TRANSLATIONS = array(
-"Cancel" => "বাতির",
+"Cancel" => "বাতিল",
+"Shared by" => "যাদের মাঝে ভাগাভাগি করা হয়েছে",
"Password" => "কূটশব্দ",
-"Name" => "রাম",
+"Name" => "নাম",
"Download" => "ডাউনলোড"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_sharing/l10n/cs_CZ.php b/apps/files_sharing/l10n/cs_CZ.php
index b4f52dbef7e..45019e34708 100644
--- a/apps/files_sharing/l10n/cs_CZ.php
+++ b/apps/files_sharing/l10n/cs_CZ.php
@@ -8,13 +8,13 @@ $TRANSLATIONS = array(
"Shared by link" => "Sdíleno pomocí odkazu",
"No files have been shared with you yet." => "Zatím s vámi nikdo žádné soubory nesdílel.",
"You haven't shared any files yet." => "Zatím jste nesdíleli žádné soubory.",
-"You haven't shared any files by link yet." => "Zatím jste nesdíleli pomocí odkazu žádný soubor.",
+"You haven't shared any files by link yet." => "Zatím jste nesdíleli pomocí odkazu žádné soubory.",
"Do you want to add the remote share {name} from {owner}@{remote}?" => "Chcete přidat vzdálené úložiště {name} uživatele {owner}@{remote}?",
"Remote share" => "Vzdálené úložiště",
"Remote share password" => "Heslo ke vzdálenému úložišti",
"Cancel" => "Zrušit",
"Add remote share" => "Přidat vzdálené úložiště",
-"No ownCloud installation found at {remote}" => "Nebyla nalezen žádný funkční ownCloud na {remote}",
+"No ownCloud installation found at {remote}" => "Nebyla nalezena instalace ownCloud na {remote}",
"Invalid ownCloud url" => "Neplatná ownCloud url",
"Shared by" => "Sdílí",
"This share is password-protected" => "Toto sdílení je chráněno heslem",
diff --git a/apps/files_sharing/l10n/et_EE.php b/apps/files_sharing/l10n/et_EE.php
index 71df34108ba..d0fb98e4ee2 100644
--- a/apps/files_sharing/l10n/et_EE.php
+++ b/apps/files_sharing/l10n/et_EE.php
@@ -1,6 +1,7 @@
<?php
$TRANSLATIONS = array(
"Server to server sharing is not enabled on this server" => "Serverist serverisse jagamine pole antud serveris lubatud",
+"Invalid or untrusted SSL certificate" => "Vigane või tundmatu SSL sertifikaat",
"Couldn't add remote share" => "Ei suutnud lisada kaugjagamist",
"Shared with you" => "Sinuga jagatud",
"Shared with others" => "Teistega jagatud",
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index f444404c2b1..e7ca4fcccd4 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -106,7 +106,7 @@ class Helper {
return false;
} else {
// Save item id in session for future requests
- \OC::$session->set('public_link_authenticated', $linkItem['id']);
+ \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']);
}
} else {
\OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type']
@@ -117,8 +117,8 @@ class Helper {
}
else {
// not authenticated ?
- if ( ! \OC::$session->exists('public_link_authenticated')
- || \OC::$session->get('public_link_authenticated') !== $linkItem['id']) {
+ if ( ! \OC::$server->getSession()->exists('public_link_authenticated')
+ || \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id']) {
return false;
}
}
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index 746bdf87c17..bcf99d01edb 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -63,7 +63,7 @@ if (isset($path)) {
exit();
} else {
// Save item id in session for future requests
- \OC::$session->set('public_link_authenticated', $linkItem['id']);
+ \OC::$server->getSession()->set('public_link_authenticated', $linkItem['id']);
}
} else {
OCP\Util::writeLog('share', 'Unknown share type '.$linkItem['share_type']
@@ -76,8 +76,8 @@ if (isset($path)) {
} else {
// Check if item id is set in session
- if ( ! \OC::$session->exists('public_link_authenticated')
- || \OC::$session->get('public_link_authenticated') !== $linkItem['id']
+ if ( ! \OC::$server->getSession()->exists('public_link_authenticated')
+ || \OC::$server->getSession()->get('public_link_authenticated') !== $linkItem['id']
) {
// Prompt for password
OCP\Util::addStyle('files_sharing', 'authenticate');
diff --git a/apps/files_trashbin/ajax/delete.php b/apps/files_trashbin/ajax/delete.php
index 9d9c1dd100f..a2302802649 100644
--- a/apps/files_trashbin/ajax/delete.php
+++ b/apps/files_trashbin/ajax/delete.php
@@ -55,7 +55,7 @@ if ( $error ) {
foreach ( $error as $e ) {
$filelist .= $e.', ';
}
- $l = OC_L10N::get('files_trashbin');
+ $l = \OC::$server->getL10N('files_trashbin');
$message = $l->t("Couldn't delete %s permanently", array(rtrim($filelist, ', ')));
OCP\JSON::error(array("data" => array("message" => $message,
"success" => $success, "error" => $error)));
diff --git a/apps/files_trashbin/ajax/undelete.php b/apps/files_trashbin/ajax/undelete.php
index afab79fcac6..02d651925ca 100644
--- a/apps/files_trashbin/ajax/undelete.php
+++ b/apps/files_trashbin/ajax/undelete.php
@@ -60,7 +60,7 @@ if ( $error ) {
foreach ( $error as $e ) {
$filelist .= $e.', ';
}
- $l = OC_L10N::get('files_trashbin');
+ $l = OC::$server->getL10N('files_trashbin');
$message = $l->t("Couldn't restore %s", array(rtrim($filelist, ', ')));
OCP\JSON::error(array("data" => array("message" => $message,
"success" => $success, "error" => $error)));
diff --git a/apps/files_trashbin/appinfo/app.php b/apps/files_trashbin/appinfo/app.php
index 718c2f45a34..fe428121a25 100644
--- a/apps/files_trashbin/appinfo/app.php
+++ b/apps/files_trashbin/appinfo/app.php
@@ -1,5 +1,5 @@
<?php
-$l = OC_L10N::get('files_trashbin');
+$l = \OC::$server->getL10N('files_trashbin');
OC::$CLASSPATH['OCA\Files_Trashbin\Exceptions\CopyRecursiveException'] = 'files_trashbin/lib/exceptions.php';
diff --git a/apps/files_trashbin/l10n/az.php b/apps/files_trashbin/l10n/az.php
index 60a214eea59..9d07ff60499 100644
--- a/apps/files_trashbin/l10n/az.php
+++ b/apps/files_trashbin/l10n/az.php
@@ -6,6 +6,7 @@ $TRANSLATIONS = array(
"Restore" => "Geri qaytar",
"Error" => "Səhv",
"restored" => "geriqaytarılıb",
+"Nothing in here. Your trash bin is empty!" => "Burda heçnə yoxdur. Sizin zibil qutusu boşdur!",
"Name" => "Ad",
"Deleted" => "Silinib",
"Delete" => "Sil"
diff --git a/apps/files_trashbin/l10n/bn_BD.php b/apps/files_trashbin/l10n/bn_BD.php
index d3a9f23b377..e0e44bf8c60 100644
--- a/apps/files_trashbin/l10n/bn_BD.php
+++ b/apps/files_trashbin/l10n/bn_BD.php
@@ -1,7 +1,14 @@
<?php
$TRANSLATIONS = array(
+"Couldn't delete %s permanently" => "%s স্থায়ীভাবে মুছে ফেলা গেলনা",
+"Couldn't restore %s" => "%s ফেরত আনা গেলনা",
+"Deleted files" => "মুছে ফেলা ফাইলসমূহ",
+"Restore" => "ফিরিয়ে দাও",
"Error" => "সমস্যা",
-"Name" => "রাম",
+"restored" => "পূণঃসংরক্ষিত",
+"Nothing in here. Your trash bin is empty!" => "এখানে কিছু নেই। আপনার ট্র্যাসবিন শুন্য",
+"Name" => "নাম",
+"Deleted" => "মুছে ফেলা",
"Delete" => "মুছে"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/files_trashbin/lib/trashbin.php b/apps/files_trashbin/lib/trashbin.php
index ee3969323cf..69eef09d1e9 100644
--- a/apps/files_trashbin/lib/trashbin.php
+++ b/apps/files_trashbin/lib/trashbin.php
@@ -891,7 +891,7 @@ class Trashbin {
private static function getUniqueFilename($location, $filename, $view) {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$name = pathinfo($filename, PATHINFO_FILENAME);
- $l = \OC_L10N::get('files_trashbin');
+ $l = \OC::$server->getL10N('files_trashbin');
// if extension is not empty we set a dot in front of it
if ($ext !== '') {
diff --git a/apps/files_versions/ajax/rollbackVersion.php b/apps/files_versions/ajax/rollbackVersion.php
index 900d8cd6e28..e6133507738 100644
--- a/apps/files_versions/ajax/rollbackVersion.php
+++ b/apps/files_versions/ajax/rollbackVersion.php
@@ -9,6 +9,6 @@ $revision=(int)$_GET['revision'];
if(OCA\Files_Versions\Storage::rollback( $file, $revision )) {
OCP\JSON::success(array("data" => array( "revision" => $revision, "file" => $file )));
}else{
- $l = OC_L10N::get('files_versions');
+ $l = \OC::$server->getL10N('files_versions');
OCP\JSON::error(array("data" => array( "message" => $l->t("Could not revert: %s", array($file) ))));
}
diff --git a/apps/files_versions/l10n/bn_BD.php b/apps/files_versions/l10n/bn_BD.php
index ce7f81b0095..2b57275d274 100644
--- a/apps/files_versions/l10n/bn_BD.php
+++ b/apps/files_versions/l10n/bn_BD.php
@@ -1,5 +1,10 @@
<?php
$TRANSLATIONS = array(
-"Versions" => "ভার্সন"
+"Could not revert: %s" => "ফিরে যাওয়া গেলনা: %s",
+"Versions" => "সংষ্করন",
+"Failed to revert {file} to revision {timestamp}." => " {file} সংশোধিত {timestamp} এ ফিরে যেতে ব্যার্থ হলো।",
+"More versions..." => "আরো সংষ্করণ....",
+"No other versions available" => "আর কোন সংষ্করণ প্রাপ্তব্য নয়",
+"Restore" => "ফিরিয়ে দাও"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/apps/user_ldap/ajax/clearMappings.php b/apps/user_ldap/ajax/clearMappings.php
index 9118d58c5cf..4e713c59f96 100644
--- a/apps/user_ldap/ajax/clearMappings.php
+++ b/apps/user_ldap/ajax/clearMappings.php
@@ -30,6 +30,6 @@ $subject = $_POST['ldap_clear_mapping'];
if(\OCA\user_ldap\lib\Helper::clearMapping($subject)) {
OCP\JSON::success();
} else {
- $l=OC_L10N::get('user_ldap');
+ $l = \OC::$server->getL10N('user_ldap');
OCP\JSON::error(array('message' => $l->t('Failed to clear the mappings.')));
}
diff --git a/apps/user_ldap/ajax/deleteConfiguration.php b/apps/user_ldap/ajax/deleteConfiguration.php
index ade57110d34..bca687c81ab 100644
--- a/apps/user_ldap/ajax/deleteConfiguration.php
+++ b/apps/user_ldap/ajax/deleteConfiguration.php
@@ -30,6 +30,6 @@ $prefix = $_POST['ldap_serverconfig_chooser'];
if(\OCA\user_ldap\lib\Helper::deleteServerConfiguration($prefix)) {
OCP\JSON::success();
} else {
- $l=OC_L10N::get('user_ldap');
+ $l = \OC::$server->getL10N('user_ldap');
OCP\JSON::error(array('message' => $l->t('Failed to delete the server configuration')));
}
diff --git a/apps/user_ldap/ajax/testConfiguration.php b/apps/user_ldap/ajax/testConfiguration.php
index a6375209611..c6372eb2ced 100644
--- a/apps/user_ldap/ajax/testConfiguration.php
+++ b/apps/user_ldap/ajax/testConfiguration.php
@@ -26,7 +26,7 @@ OCP\JSON::checkAdminUser();
OCP\JSON::checkAppEnabled('user_ldap');
OCP\JSON::callCheck();
-$l=OC_L10N::get('user_ldap');
+$l = \OC::$server->getL10N('user_ldap');
$ldapWrapper = new OCA\user_ldap\lib\LDAP();
$connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, '', null);
diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php
index ad75a384369..ef1241b9147 100644
--- a/apps/user_ldap/ajax/wizard.php
+++ b/apps/user_ldap/ajax/wizard.php
@@ -26,7 +26,7 @@ OCP\JSON::checkAdminUser();
OCP\JSON::checkAppEnabled('user_ldap');
OCP\JSON::callCheck();
-$l=OC_L10N::get('user_ldap');
+$l = \OC::$server->getL10N('user_ldap');
if(!isset($_POST['action'])) {
\OCP\JSON::error(array('message' => $l->t('No action specified')));
@@ -39,13 +39,29 @@ if(!isset($_POST['ldap_serverconfig_chooser'])) {
}
$prefix = $_POST['ldap_serverconfig_chooser'];
-$ldapWrapper = new OCA\user_ldap\lib\LDAP();
+$ldapWrapper = new \OCA\user_ldap\lib\LDAP();
$configuration = new \OCA\user_ldap\lib\Configuration($prefix);
-$wizard = new \OCA\user_ldap\lib\Wizard($configuration, $ldapWrapper);
+
+$con = new \OCA\user_ldap\lib\Connection($ldapWrapper, '', null);
+$con->setConfiguration($configuration->getConfiguration());
+$con->ldapConfigurationActive = true;
+$con->setIgnoreValidation(true);
+
+$userManager = new \OCA\user_ldap\lib\user\Manager(
+ \OC::$server->getConfig(),
+ new \OCA\user_ldap\lib\FilesystemHelper(),
+ new \OCA\user_ldap\lib\LogWrapper(),
+ \OC::$server->getAvatarManager(),
+ new \OCP\Image());
+
+$access = new \OCA\user_ldap\lib\Access($con, $ldapWrapper, $userManager);
+
+$wizard = new \OCA\user_ldap\lib\Wizard($configuration, $ldapWrapper, $access);
switch($action) {
case 'guessPortAndTLS':
case 'guessBaseDN':
+ case 'detectEmailAttribute':
case 'determineGroupMemberAssoc':
case 'determineUserObjectClasses':
case 'determineGroupObjectClasses':
diff --git a/apps/user_ldap/js/ldapFilter.js b/apps/user_ldap/js/ldapFilter.js
index df3bd67aec2..e9f60e7ba3c 100644
--- a/apps/user_ldap/js/ldapFilter.js
+++ b/apps/user_ldap/js/ldapFilter.js
@@ -14,7 +14,7 @@ function LdapFilter(target) {
}
}
-LdapFilter.prototype.compose = function() {
+LdapFilter.prototype.compose = function(callback) {
var action;
if(this.locked) {
@@ -50,6 +50,9 @@ LdapFilter.prototype.compose = function() {
LdapWizard.countGroups();
LdapWizard.detectGroupMemberAssoc();
}
+ if(typeof callback !== 'undefined') {
+ callback();
+ }
},
function () {
console.log('LDAP Wizard: could not compose filter. '+
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
index 87d755697cb..fd84ca1980b 100644
--- a/apps/user_ldap/js/settings.js
+++ b/apps/user_ldap/js/settings.js
@@ -340,6 +340,14 @@ var LdapWizard = {
LdapWizard._countThings('countUsers');
},
+ detectEmailAttribute: function() {
+ param = 'action=detectEmailAttribute'+
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
+ //runs in the background, no callbacks necessary
+ LdapWizard.ajax(param, LdapWizard.applyChanges, function(){});
+ },
+
detectGroupMemberAssoc: function() {
param = 'action=determineGroupMemberAssoc'+
'&ldap_serverconfig_chooser='+
@@ -577,7 +585,7 @@ var LdapWizard = {
postInitUserFilter: function() {
if(LdapWizard.userFilterObjectClassesHasRun &&
LdapWizard.userFilterAvailableGroupsHasRun) {
- LdapWizard.userFilter.compose();
+ LdapWizard.userFilter.compose(LdapWizard.detectEmailAttribute);
LdapWizard.countUsers();
}
},
@@ -619,6 +627,7 @@ var LdapWizard = {
if(triggerObj.id == 'ldap_userlist_filter') {
LdapWizard.countUsers();
+ LdapWizard.detectEmailAttribute();
} else if(triggerObj.id == 'ldap_group_filter') {
LdapWizard.countGroups();
LdapWizard.detectGroupMemberAssoc();
@@ -656,9 +665,12 @@ var LdapWizard = {
LdapWizard._save($('#'+originalObj)[0], $.trim(values));
if(originalObj == 'ldap_userfilter_objectclass'
|| originalObj == 'ldap_userfilter_groups') {
- LdapWizard.userFilter.compose();
+ LdapWizard.userFilter.compose(LdapWizard.detectEmailAttribute);
//when user filter is changed afterwards, login filter needs to
//be adjusted, too
+ if(!LdapWizard.loginFilter) {
+ LdapWizard.initLoginFilter();
+ }
LdapWizard.loginFilter.compose();
} else if(originalObj == 'ldap_loginfilter_attributes') {
LdapWizard.loginFilter.compose();
@@ -720,7 +732,7 @@ var LdapWizard = {
LdapWizard._save({ id: modeKey }, LdapWizard.filterModeAssisted);
if(moc.indexOf('user') >= 0) {
LdapWizard.blacklistRemove('ldap_userlist_filter');
- LdapWizard.userFilter.compose();
+ LdapWizard.userFilter.compose(LdapWizard.detectEmailAttribute);
} else {
LdapWizard.blacklistRemove('ldap_group_filter');
LdapWizard.groupFilter.compose();
diff --git a/apps/user_ldap/l10n/az.php b/apps/user_ldap/l10n/az.php
index 5e66b2e5885..6d3e01b8a8e 100644
--- a/apps/user_ldap/l10n/az.php
+++ b/apps/user_ldap/l10n/az.php
@@ -14,6 +14,7 @@ $TRANSLATIONS = array(
"_%s group found_::_%s groups found_" => array("",""),
"_%s user found_::_%s users found_" => array("",""),
"Save" => "Saxlamaq",
+"Help" => "Kömək",
"Host" => "Şəbəkədə ünvan",
"Password" => "Şifrə"
);
diff --git a/apps/user_ldap/l10n/bn_BD.php b/apps/user_ldap/l10n/bn_BD.php
index 63f1df3e054..8cabd10a5d2 100644
--- a/apps/user_ldap/l10n/bn_BD.php
+++ b/apps/user_ldap/l10n/bn_BD.php
@@ -1,9 +1,11 @@
<?php
$TRANSLATIONS = array(
"Deletion failed" => "মুছার আদেশ ব্যার্থ হলো",
+"Success" => "সাফল্য",
"Error" => "সমস্যা",
"_%s group found_::_%s groups found_" => array("",""),
"_%s user found_::_%s users found_" => array("",""),
+"Server" => "সার্ভার",
"Group Filter" => "গোষ্ঠী ছাঁকনী",
"Save" => "সংরক্ষণ",
"Help" => "সহায়িকা",
@@ -15,6 +17,9 @@ $TRANSLATIONS = array(
"Password" => "কূটশব্দ",
"For anonymous access, leave DN and Password empty." => "অজ্ঞাতকুলশীল অধিগমনের জন্য DN এবং কূটশব্দটি ফাঁকা রাখুন।",
"You can specify Base DN for users and groups in the Advanced tab" => "সুচারু ট্যঅবে গিয়ে আপনি ব্যবহারকারি এবং গোষ্ঠীসমূহের জন্য ভিত্তি DN নির্ধারণ করতে পারেন।",
+"Back" => "পেছনে যাও",
+"Continue" => "চালিয়ে যাও",
+"Expert" => "দক্ষ",
"Advanced" => "সুচারু",
"Turn off SSL certificate validation." => "SSL সনদপত্র যাচাইকরণ বন্ধ রাক।",
"in seconds. A change empties the cache." => "সেকেন্ডে। কোন পরিবর্তন ক্যাসে খালি করবে।",
diff --git a/apps/user_ldap/l10n/cs_CZ.php b/apps/user_ldap/l10n/cs_CZ.php
index 3be197a1b26..e3b76799fb1 100644
--- a/apps/user_ldap/l10n/cs_CZ.php
+++ b/apps/user_ldap/l10n/cs_CZ.php
@@ -17,9 +17,9 @@ $TRANSLATIONS = array(
"mappings cleared" => "mapování zrušeno",
"Success" => "Úspěch",
"Error" => "Chyba",
-"Please specify a Base DN" => "Uveď prosím základní DN",
-"Could not determine Base DN" => "Nelze určit základní DN",
-"Please specify the port" => "Prosím zadej port",
+"Please specify a Base DN" => "Uveďte prosím Base DN",
+"Could not determine Base DN" => "Nelze určit Base DN",
+"Please specify the port" => "Prosím zadejte port",
"Configuration OK" => "Konfigurace v pořádku",
"Configuration incorrect" => "Nesprávná konfigurace",
"Configuration incomplete" => "Nekompletní konfigurace",
@@ -103,6 +103,8 @@ $TRANSLATIONS = array(
"Group-Member association" => "Asociace člena skupiny",
"Nested Groups" => "Vnořené skupiny",
"When switched on, groups that contain groups are supported. (Only works if the group member attribute contains DNs.)" => "Pokud zapnuto, je možno používat skupiny, které obsahují jiné skupiny. (Funguje pouze pokud atribut člena skupiny obsahuje DN.)",
+"Paging chunksize" => "Velikost bloku stránkování",
+"Chunksize used for paged LDAP searches that may return bulky results like user or group enumeration. (Setting it 0 disables paged LDAP searches in those situations.)" => "Velikost bloku použitá pro stránkování vyhledávání v LDAP, které může vracet objemné výsledky jako třeba výčet uživatelů či skupin. (Nastavení na 0 zakáže stránkovaná vyhledávání pro tyto situace.)",
"Special Attributes" => "Speciální atributy",
"Quota Field" => "Pole pro kvótu",
"Quota Default" => "Výchozí kvóta",
diff --git a/apps/user_ldap/l10n/hu_HU.php b/apps/user_ldap/l10n/hu_HU.php
index 240051c7dc0..af7100da1a9 100644
--- a/apps/user_ldap/l10n/hu_HU.php
+++ b/apps/user_ldap/l10n/hu_HU.php
@@ -71,7 +71,7 @@ $TRANSLATIONS = array(
"users found" => "felhasználó van",
"Back" => "Vissza",
"Continue" => "Folytatás",
-"Expert" => "Gyakorlott",
+"Expert" => "Profi",
"Advanced" => "Haladó",
"<b>Warning:</b> Apps user_ldap and user_webdavauth are incompatible. You may experience unexpected behavior. Please ask your system administrator to disable one of them." => "<b>Figyelem:</b> a user_ldap és user_webdavauth alkalmazások nem kompatibilisek. Együttes használatuk váratlan eredményekhez vezethet. Kérje meg a rendszergazdát, hogy a kettő közül kapcsolja ki az egyiket.",
"<b>Warning:</b> The PHP LDAP module is not installed, the backend will not work. Please ask your system administrator to install it." => "<b>Figyelmeztetés:</b> Az LDAP PHP modul nincs telepítve, ezért ez az alrendszer nem fog működni. Kérje meg a rendszergazdát, hogy telepítse!",
diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php
index eb2a1ab02de..dceb2206dbe 100644
--- a/apps/user_ldap/lib/wizard.php
+++ b/apps/user_ldap/lib/wizard.php
@@ -25,6 +25,7 @@ namespace OCA\user_ldap\lib;
class Wizard extends LDAPUtility {
static protected $l;
+ protected $access;
protected $cr;
protected $configuration;
protected $result;
@@ -48,12 +49,13 @@ class Wizard extends LDAPUtility {
* @param Configuration $configuration an instance of Configuration
* @param ILDAPWrapper $ldap an instance of ILDAPWrapper
*/
- public function __construct(Configuration $configuration, ILDAPWrapper $ldap) {
+ public function __construct(Configuration $configuration, ILDAPWrapper $ldap, Access $access) {
parent::__construct($ldap);
$this->configuration = $configuration;
if(is_null(Wizard::$l)) {
- Wizard::$l = \OC_L10N::get('user_ldap');
+ Wizard::$l = \OC::$server->getL10N('user_ldap');
}
+ $this->access = $access;
$this->result = new WizardResult;
}
@@ -78,11 +80,10 @@ class Wizard extends LDAPUtility {
throw new \Exception('Requirements not met', 400);
}
- $ldapAccess = $this->getAccess();
if($type === 'groups') {
- $result = $ldapAccess->countGroups($filter);
+ $result = $this->access->countGroups($filter);
} else if($type === 'users') {
- $result = $ldapAccess->countUsers($filter);
+ $result = $this->access->countUsers($filter);
} else {
throw new \Exception('internal error: invald object type', 500);
}
@@ -129,6 +130,77 @@ class Wizard extends LDAPUtility {
}
/**
+ * counts users with a specified attribute
+ * @param string $attr
+ * @return int|bool
+ */
+ public function countUsersWithAttribute($attr) {
+ if(!$this->checkRequirements(array('ldapHost',
+ 'ldapPort',
+ 'ldapBase',
+ 'ldapUserFilter',
+ ))) {
+ return false;
+ }
+
+ $filter = $this->access->combineFilterWithAnd(array(
+ $this->configuration->ldapUserFilter,
+ $attr . '=*'
+ ));
+
+ return $this->access->countUsers($filter);
+ }
+
+ /**
+ * detects the most often used email attribute for users applying to the
+ * user list filter. If a setting is already present that returns at least
+ * one hit, the detection will be canceled.
+ * @return WizardResult|bool
+ */
+ public function detectEmailAttribute() {
+ if(!$this->checkRequirements(array('ldapHost',
+ 'ldapPort',
+ 'ldapBase',
+ 'ldapUserFilter',
+ ))) {
+ return false;
+ }
+
+ $attr = $this->configuration->ldapEmailAttribute;
+ if(!empty($attr)) {
+ $count = intval($this->countUsersWithAttribute($attr));
+ if($count > 0) {
+ return false;
+ }
+ $writeLog = true;
+ } else {
+ $writeLog = false;
+ }
+
+ $emailAttributes = array('mail', 'mailPrimaryAddress');
+ $winner = '';
+ $maxUsers = 0;
+ foreach($emailAttributes as $attr) {
+ $count = $this->countUsersWithAttribute($attr);
+ if($count > $maxUsers) {
+ $maxUsers = $count;
+ $winner = $attr;
+ }
+ }
+
+ if($winner !== '') {
+ $this->result->addChange('ldap_email_attr', $winner);
+ if($writeLog) {
+ \OCP\Util::writeLog('user_ldap', 'The mail attribute has ' .
+ 'automatically been reset, because the original value ' .
+ 'did not return any results.', \OCP\Util::INFO);
+ }
+ }
+
+ return $this->result;
+ }
+
+ /**
* @return WizardResult
* @throws \Exception
*/
@@ -289,7 +361,6 @@ class Wizard extends LDAPUtility {
*/
public function fetchGroups($dbKey, $confKey) {
$obclasses = array('posixGroup', 'group', 'zimbraDistributionList', 'groupOfNames');
- $ldapAccess = $this->getAccess();
$filterParts = array();
foreach($obclasses as $obclass) {
@@ -298,15 +369,15 @@ class Wizard extends LDAPUtility {
//we filter for everything
//- that looks like a group and
//- has the group display name set
- $filter = $ldapAccess->combineFilterWithOr($filterParts);
- $filter = $ldapAccess->combineFilterWithAnd(array($filter, 'cn=*'));
+ $filter = $this->access->combineFilterWithOr($filterParts);
+ $filter = $this->access->combineFilterWithAnd(array($filter, 'cn=*'));
$groupNames = array();
$groupEntries = array();
$limit = 400;
$offset = 0;
do {
- $result = $ldapAccess->searchGroups($filter, array('cn','dn'), $limit, $offset);
+ $result = $this->access->searchGroups($filter, array('cn'), $limit, $offset);
foreach($result as $item) {
$groupNames[] = $item['cn'];
$groupEntries[] = $item;
@@ -994,6 +1065,7 @@ class Wizard extends LDAPUtility {
if(!$this->ldap->isResource($entry)) {
continue 2;
}
+ $rr = $entry; //will be expected by nextEntry next round
$attributes = $this->ldap->getAttributes($cr, $entry);
$dn = $this->ldap->getDN($cr, $entry);
if($dn === false || in_array($dn, $dnRead)) {
@@ -1007,7 +1079,6 @@ class Wizard extends LDAPUtility {
$foundItems = array_merge($foundItems, $newItems);
$this->resultCache[$dn][$attr] = $newItems;
$dnRead[] = $dn;
- $rr = $entry; //will be expected by nextEntry next round
} while(($state === self::LRESULT_PROCESSED_SKIP
|| $this->ldap->isResource($entry))
&& ($dnReadLimit === 0 || $dnReadCount < $dnReadLimit));
@@ -1105,27 +1176,6 @@ class Wizard extends LDAPUtility {
}
/**
- * creates and returns an Access instance
- * @return \OCA\user_ldap\lib\Access
- */
- private function getAccess() {
- $con = new Connection($this->ldap, '', null);
- $con->setConfiguration($this->configuration->getConfiguration());
- $con->ldapConfigurationActive = true;
- $con->setIgnoreValidation(true);
-
- $userManager = new user\Manager(
- \OC::$server->getConfig(),
- new FilesystemHelper(),
- new LogWrapper(),
- \OC::$server->getAvatarManager(),
- new \OCP\Image());
-
- $ldapAccess = new Access($con, $this->ldap, $userManager);
- return $ldapAccess;
- }
-
- /**
* @return bool|mixed
*/
private function getConnection() {
diff --git a/apps/user_ldap/settings.php b/apps/user_ldap/settings.php
index fcde5df3716..e7cdd0d926a 100644
--- a/apps/user_ldap/settings.php
+++ b/apps/user_ldap/settings.php
@@ -46,7 +46,7 @@ $wControls = $wControls->fetchPage();
$sControls = new OCP\Template('user_ldap', 'part.settingcontrols');
$sControls = $sControls->fetchPage();
-$l = \OC_L10N::get('user_ldap');
+$l = \OC::$server->getL10N('user_ldap');
$wizTabs = array();
$wizTabs[] = array('tpl' => 'part.wizard-server', 'cap' => $l->t('Server'));
diff --git a/apps/user_ldap/tests/wizard.php b/apps/user_ldap/tests/wizard.php
index ff5ee010b71..1f420f9ee8a 100644
--- a/apps/user_ldap/tests/wizard.php
+++ b/apps/user_ldap/tests/wizard.php
@@ -43,16 +43,29 @@ class Test_Wizard extends \PHPUnit_Framework_TestCase {
}
private function getWizardAndMocks() {
- static $conMethods;
-
- if(is_null($conMethods)) {
- $conMethods = get_class_methods('\OCA\user_ldap\lib\Configuration');
+ static $confMethods;
+ static $connMethods;
+ static $accMethods;
+
+ if(is_null($confMethods)) {
+ $confMethods = get_class_methods('\OCA\user_ldap\lib\Configuration');
+ $connMethods = get_class_methods('\OCA\user_ldap\lib\Connection');
+ $accMethods = get_class_methods('\OCA\user_ldap\lib\Access');
}
$lw = $this->getMock('\OCA\user_ldap\lib\ILDAPWrapper');
$conf = $this->getMock('\OCA\user_ldap\lib\Configuration',
- $conMethods,
+ $confMethods,
array($lw, null, null));
- return array(new Wizard($conf, $lw), $conf, $lw);
+
+ $connector = $this->getMock('\OCA\user_ldap\lib\Connection',
+ $connMethods, array($lw, null, null));
+ $um = $this->getMockBuilder('\OCA\user_ldap\lib\user\Manager')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $access = $this->getMock('\OCA\user_ldap\lib\Access',
+ $accMethods, array($connector, $lw, $um));
+
+ return array(new Wizard($conf, $lw, $access), $conf, $lw, $access);
}
private function prepareLdapWrapperForConnections(&$ldap) {
@@ -207,4 +220,220 @@ class Test_Wizard extends \PHPUnit_Framework_TestCase {
unset($uidnumber);
}
+ public function testDetectEmailAttributeAlreadySet() {
+ list($wizard, $configuration, $ldap, $access)
+ = $this->getWizardAndMocks();
+
+ $configuration->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function ($name) {
+ if($name === 'ldapEmailAttribute') {
+ return 'myEmailAttribute';
+ } else {
+ //for requirement checks
+ return 'let me pass';
+ }
+ }));
+
+ $access->expects($this->once())
+ ->method('countUsers')
+ ->will($this->returnValue(42));
+
+ $wizard->detectEmailAttribute();
+ }
+
+ public function testDetectEmailAttributeOverrideSet() {
+ list($wizard, $configuration, $ldap, $access)
+ = $this->getWizardAndMocks();
+
+ $configuration->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function ($name) {
+ if($name === 'ldapEmailAttribute') {
+ return 'myEmailAttribute';
+ } else {
+ //for requirement checks
+ return 'let me pass';
+ }
+ }));
+
+ $access->expects($this->exactly(3))
+ ->method('combineFilterWithAnd')
+ ->will($this->returnCallback(function ($filterParts) {
+ return str_replace('=*', '', array_pop($filterParts));
+ }));
+
+ $access->expects($this->exactly(3))
+ ->method('countUsers')
+ ->will($this->returnCallback(function ($filter) {
+ if($filter === 'myEmailAttribute') {
+ return 0;
+ } else if($filter === 'mail') {
+ return 3;
+ } else if($filter === 'mailPrimaryAddress') {
+ return 17;
+ }
+ var_dump($filter);
+ }));
+
+ $result = $wizard->detectEmailAttribute()->getResultArray();
+ $this->assertSame('mailPrimaryAddress',
+ $result['changes']['ldap_email_attr']);
+ }
+
+ public function testDetectEmailAttributeFind() {
+ list($wizard, $configuration, $ldap, $access)
+ = $this->getWizardAndMocks();
+
+ $configuration->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function ($name) {
+ if($name === 'ldapEmailAttribute') {
+ return '';
+ } else {
+ //for requirement checks
+ return 'let me pass';
+ }
+ }));
+
+ $access->expects($this->exactly(2))
+ ->method('combineFilterWithAnd')
+ ->will($this->returnCallback(function ($filterParts) {
+ return str_replace('=*', '', array_pop($filterParts));
+ }));
+
+ $access->expects($this->exactly(2))
+ ->method('countUsers')
+ ->will($this->returnCallback(function ($filter) {
+ if($filter === 'myEmailAttribute') {
+ return 0;
+ } else if($filter === 'mail') {
+ return 3;
+ } else if($filter === 'mailPrimaryAddress') {
+ return 17;
+ }
+ var_dump($filter);
+ }));
+
+ $result = $wizard->detectEmailAttribute()->getResultArray();
+ $this->assertSame('mailPrimaryAddress',
+ $result['changes']['ldap_email_attr']);
+ }
+
+ public function testDetectEmailAttributeFindNothing() {
+ list($wizard, $configuration, $ldap, $access)
+ = $this->getWizardAndMocks();
+
+ $configuration->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function ($name) {
+ if($name === 'ldapEmailAttribute') {
+ return 'myEmailAttribute';
+ } else {
+ //for requirement checks
+ return 'let me pass';
+ }
+ }));
+
+ $access->expects($this->exactly(3))
+ ->method('combineFilterWithAnd')
+ ->will($this->returnCallback(function ($filterParts) {
+ return str_replace('=*', '', array_pop($filterParts));
+ }));
+
+ $access->expects($this->exactly(3))
+ ->method('countUsers')
+ ->will($this->returnCallback(function ($filter) {
+ if($filter === 'myEmailAttribute') {
+ return 0;
+ } else if($filter === 'mail') {
+ return 0;
+ } else if($filter === 'mailPrimaryAddress') {
+ return 0;
+ }
+ var_dump($filter);
+ }));
+
+ $result = $wizard->detectEmailAttribute();
+ $this->assertSame(false, $result->hasChanges());
+ }
+
+ public function testCumulativeSearchOnAttributeSkipReadDN() {
+ // tests that there is no infinite loop, when skipping already processed
+ // DNs (they can be returned multiple times for multiple filters )
+ list($wizard, $configuration, $ldap) = $this->getWizardAndMocks();
+
+ $configuration->expects($this->any())
+ ->method('__get')
+ ->will($this->returnCallback(function($name) {
+ if($name === 'ldapBase') {
+ return array('base');
+ }
+ return null;
+ }));
+
+ $this->prepareLdapWrapperForConnections($ldap);
+
+ $ldap->expects($this->any())
+ ->method('isResource')
+ ->will($this->returnCallback(function($res) {
+ return (bool)$res;
+ }));
+
+ $ldap->expects($this->any())
+ ->method('search')
+ //dummy value, usually invalid
+ ->will($this->returnValue(true));
+
+ $ldap->expects($this->any())
+ ->method('countEntries')
+ //an is_resource check will follow, so we need to return a dummy resource
+ ->will($this->returnValue(7));
+
+ //5 DNs per filter means 2x firstEntry and 8x nextEntry
+ $ldap->expects($this->any())
+ ->method('firstEntry')
+ //dummy value, usually invalid
+ ->will($this->returnValue(1));
+
+ global $mark;
+ $mark = false;
+ // entries return order: 1, 2, 3, 4, 4, 5, 6
+ $ldap->expects($this->any())
+ ->method('nextEntry')
+ //dummy value, usually invalid
+ ->will($this->returnCallback(function($a, $prev){
+ $current = $prev + 1;
+ if($current === 7) {
+ return false;
+ }
+ global $mark;
+ if($prev === 4 && !$mark) {
+ $mark = true;
+ return 4;
+ }
+ return $current;
+ }));
+
+ $ldap->expects($this->any())
+ ->method('getAttributes')
+ //dummy value, usually invalid
+ ->will($this->returnCallback(function($a, $entry) {
+ return array('cn' => array($entry), 'count' => 1);
+ }));
+
+ $ldap->expects($this->any())
+ ->method('getDN')
+ //dummy value, usually invalid
+ ->will($this->returnCallback(function($a, $b) {
+ return $b;
+ }));
+
+ # The following expectations are the real test #
+ $filters = array('f1', 'f2', '*');
+ $resultArray = $wizard->cumulativeSearchOnAttribute($filters, 'cn', 0);
+ $this->assertSame(6, count($resultArray));
+ unset($mark);
+ }
+
}
diff --git a/apps/user_webdavauth/l10n/bn_BD.php b/apps/user_webdavauth/l10n/bn_BD.php
index 354df7c32d9..30ca2cdfa06 100644
--- a/apps/user_webdavauth/l10n/bn_BD.php
+++ b/apps/user_webdavauth/l10n/bn_BD.php
@@ -1,5 +1,6 @@
<?php
$TRANSLATIONS = array(
+"Address:" => "ঠিকানা",
"Save" => "সংরক্ষণ"
);
$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";