From 488825efc4fe676dc85e89f6ca1a4732063203b4 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 24 Oct 2023 12:44:26 +0200 Subject: [PATCH] Merge pull request #15383 from overleaf/jpa-remove-unused-angular-deps [web] remove unused angular dependencies GitOrigin-RevId: 58efeb5755b5f7d0f893e343b319bc4f1a6a3d76 --- .../Authentication/AuthenticationManager.js | 4 +- services/web/frontend/js/base.js | 3 - .../web/frontend/js/directives/asyncForm.js | 1 - .../frontend/js/directives/complexPassword.js | 93 ------- services/web/frontend/js/libraries.js | 4 - services/web/frontend/js/main.js | 2 - services/web/frontend/js/main/translations.js | 34 --- .../angular-autocomplete/ac_template.html | 18 -- .../angular-autocomplete.js | 258 ------------------ .../frontend/js/vendor/libs/angular-cookie.js | 112 -------- .../js/vendor/libs/ng-context-menu-0.1.4.js | 108 -------- .../web/frontend/js/vendor/libs/passfield.js | 2 - 12 files changed, 2 insertions(+), 637 deletions(-) delete mode 100644 services/web/frontend/js/directives/complexPassword.js delete mode 100644 services/web/frontend/js/main/translations.js delete mode 100755 services/web/frontend/js/vendor/libs/angular-autocomplete/ac_template.html delete mode 100644 services/web/frontend/js/vendor/libs/angular-autocomplete/angular-autocomplete.js delete mode 100644 services/web/frontend/js/vendor/libs/angular-cookie.js delete mode 100644 services/web/frontend/js/vendor/libs/ng-context-menu-0.1.4.js delete mode 100644 services/web/frontend/js/vendor/libs/passfield.js diff --git a/services/web/app/src/Features/Authentication/AuthenticationManager.js b/services/web/app/src/Features/Authentication/AuthenticationManager.js index 665cb80cc8..2fa0552f91 100644 --- a/services/web/app/src/Features/Authentication/AuthenticationManager.js +++ b/services/web/app/src/Features/Authentication/AuthenticationManager.js @@ -196,8 +196,8 @@ const AuthenticationManager = { return null }, - // validates a password based on a similar set of rules to `complexPassword.js` on the frontend - // note that `passfield.js` enforces more rules than this, but these are the most commonly set. + // validates a password based on a similar set of rules previously used by `passfield.js` on the frontend + // note that `passfield.js` enforced more rules than this, but these are the most commonly set. // returns null on success, or an error object. validatePassword(password, email) { if (password == null) { diff --git a/services/web/frontend/js/base.js b/services/web/frontend/js/base.js index 1327569685..029ea16d9a 100644 --- a/services/web/frontend/js/base.js +++ b/services/web/frontend/js/base.js @@ -27,11 +27,8 @@ import { configureMathJax } from './features/mathjax/configure' const App = angular .module('SharelatexApp', [ 'ui.bootstrap', - 'autocomplete', 'RecursionHelper', - 'ng-context-menu', 'ngSanitize', - 'ipCookie', 'ErrorCatcher', 'localStorage', 'sessionStorage', diff --git a/services/web/frontend/js/directives/asyncForm.js b/services/web/frontend/js/directives/asyncForm.js index 9348b756df..fb5c899987 100644 --- a/services/web/frontend/js/directives/asyncForm.js +++ b/services/web/frontend/js/directives/asyncForm.js @@ -1,5 +1,4 @@ import App from '../base' -import '../vendor/libs/passfield' App.directive('asyncForm', [ '$http', 'validateCaptcha', diff --git a/services/web/frontend/js/directives/complexPassword.js b/services/web/frontend/js/directives/complexPassword.js deleted file mode 100644 index 74214c7cb2..0000000000 --- a/services/web/frontend/js/directives/complexPassword.js +++ /dev/null @@ -1,93 +0,0 @@ -import _ from 'lodash' -/* global PassField */ - -/* eslint-disable - max-len -*/ -import App from '../base' -import '../vendor/libs/passfield' -App.directive('complexPassword', function () { - return { - require: ['^asyncForm', 'ngModel'], - - link(scope, element, attrs, ctrl) { - PassField.Config.blackList = [] - const defaultPasswordOpts = { - pattern: '', - length: { - min: 6, - max: 72, - }, - allowEmpty: false, - allowAnyChars: false, - isMasked: true, - showToggle: false, - showGenerate: false, - showTip: false, - showWarn: false, - checkMode: PassField.CheckModes.STRICT, - chars: { - digits: '1234567890', - letters: 'abcdefghijklmnopqrstuvwxyz', - letters_up: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', - symbols: '@#$%^&*()-_=+[]{};:<>/?!£€.,', - }, - } - - const opts = _.defaults( - window.passwordStrengthOptions || {}, - defaultPasswordOpts - ) - - if (opts.length.min === 1) { - // this allows basically anything to be a valid password - opts.acceptRate = 0 - } - - if (opts.length.max > 72) { - // there is a hard limit of 71 characters in the password at the backend - opts.length.max = 72 - } - - if (opts.length.max > 0) { - // PassField's notion of 'max' is non-inclusive - opts.length.max += 1 - } - - const passField = new PassField.Field('passwordField', opts) - const [asyncFormCtrl, ngModelCtrl] = Array.from(ctrl) - - ngModelCtrl.$parsers.unshift(function (modelValue) { - let isValid = passField.validatePass() - const email = asyncFormCtrl.getEmail() || window.usersEmail - - if (!isValid) { - scope.complexPasswordErrorMessage = - passField.getPassValidationMessage() - } else if (typeof email === 'string' && email !== '') { - const startOfEmail = email.split('@')[0] - if ( - modelValue.indexOf(email) !== -1 || - modelValue.indexOf(startOfEmail) !== -1 - ) { - isValid = false - scope.complexPasswordErrorMessage = - 'Password can not contain email address' - } - } - if (opts.length.max != null && modelValue.length >= opts.length.max) { - isValid = false - scope.complexPasswordErrorMessage = `Maximum password length ${ - opts.length.max - 1 - } exceeded` - } - if (opts.length.min != null && modelValue.length < opts.length.min) { - isValid = false - scope.complexPasswordErrorMessage = `Password too short, minimum ${opts.length.min}` - } - ngModelCtrl.$setValidity('complexPassword', isValid) - return modelValue - }) - }, - } -}) diff --git a/services/web/frontend/js/libraries.js b/services/web/frontend/js/libraries.js index ac453c8013..2decde9aa5 100644 --- a/services/web/frontend/js/libraries.js +++ b/services/web/frontend/js/libraries.js @@ -2,12 +2,8 @@ import 'jquery' import 'angular' import 'angular-sanitize' import 'lodash' -import './vendor/libs/angular-autocomplete/angular-autocomplete' import './vendor/libs/ui-bootstrap' -import './vendor/libs/ng-context-menu-0.1.4' import './vendor/libs/jquery.storage' -import './vendor/libs/angular-cookie' -import './vendor/libs/passfield' import './vendor/libs/select/select' // CSS diff --git a/services/web/frontend/js/main.js b/services/web/frontend/js/main.js index f133265ada..f57fc632ce 100644 --- a/services/web/frontend/js/main.js +++ b/services/web/frontend/js/main.js @@ -16,7 +16,6 @@ import './main/scribtex-popup' import './main/event' import './main/bonus' import './main/system-messages' -import './main/translations' import './main/annual-upgrade' import './main/subscription/team-invite-controller' import './main/learn' @@ -24,7 +23,6 @@ import './main/keys' import './main/importing' import './directives/autoSubmitForm' import './directives/asyncForm' -import './directives/complexPassword' import './directives/stopPropagation' import './directives/focus' import './directives/equals' diff --git a/services/web/frontend/js/main/translations.js b/services/web/frontend/js/main/translations.js deleted file mode 100644 index 88780d3fed..0000000000 --- a/services/web/frontend/js/main/translations.js +++ /dev/null @@ -1,34 +0,0 @@ -import App from '../base' - -App.controller('TranslationsPopupController', [ - '$scope', - 'ipCookie', - 'localStorage', - function ($scope, ipCookie, localStorage) { - function getStoredDismissal() { - const localStore = localStorage('hide-i18n-notification') - - if (localStore === null) { - // Not stored in localStorage, check cookie - const cookieStore = ipCookie('hidei18nNotification') - - // If stored in cookie, set on localStorage for forwards compat - if (cookieStore) { - localStorage('hide-i18n-notification', cookieStore) - ipCookie.remove('hidei18nNotification') - } - - return cookieStore - } - - return localStore - } - - $scope.hidei18nNotification = getStoredDismissal() - - $scope.dismiss = function () { - localStorage('hide-i18n-notification', true) - $scope.hidei18nNotification = true - } - }, -]) diff --git a/services/web/frontend/js/vendor/libs/angular-autocomplete/ac_template.html b/services/web/frontend/js/vendor/libs/angular-autocomplete/ac_template.html deleted file mode 100755 index 8058d84589..0000000000 --- a/services/web/frontend/js/vendor/libs/angular-autocomplete/ac_template.html +++ /dev/null @@ -1,18 +0,0 @@ -
- - -
diff --git a/services/web/frontend/js/vendor/libs/angular-autocomplete/angular-autocomplete.js b/services/web/frontend/js/vendor/libs/angular-autocomplete/angular-autocomplete.js deleted file mode 100644 index 895d51f420..0000000000 --- a/services/web/frontend/js/vendor/libs/angular-autocomplete/angular-autocomplete.js +++ /dev/null @@ -1,258 +0,0 @@ -/* --- Made by justgoscha and licensed under MIT license --- */ - -var app = angular.module('autocomplete', []); - -app.directive('autocomplete', function() { - var index = -1; - - return { - restrict: 'E', - scope: { - searchParam: '=ngModel', - suggestions: '=data', - onType: '=onType', - onSelect: '=onSelect' - }, - controller: ['$scope', function($scope){ - // the index of the suggestions that's currently selected - $scope.selectedIndex = -1; - - // set new index - $scope.setIndex = function(i){ - $scope.selectedIndex = parseInt(i); - }; - - this.setIndex = function(i){ - $scope.setIndex(i); - $scope.$apply(); - }; - - $scope.getIndex = function(i){ - return $scope.selectedIndex; - }; - - // watches if the parameter filter should be changed - var watching = true; - - // autocompleting drop down on/off - $scope.completing = false; - - // starts autocompleting on typing in something - $scope.$watch('searchParam', function(newValue, oldValue){ - if (oldValue === newValue) { - return; - } - - if(watching && $scope.searchParam) { - $scope.completing = true; - $scope.searchFilter = $scope.searchParam; - $scope.selectedIndex = -1; - } - - // function thats passed to on-type attribute gets executed - if($scope.onType) - $scope.onType($scope.searchParam); - }); - - // for hovering over suggestions - this.preSelect = function(suggestion){ - - watching = false; - - // this line determines if it is shown - // in the input field before it's selected: - //$scope.searchParam = suggestion; - - $scope.$apply(); - watching = true; - - }; - - $scope.preSelect = this.preSelect; - - this.preSelectOff = function(){ - watching = true; - }; - - $scope.preSelectOff = this.preSelectOff; - - // selecting a suggestion with RIGHT ARROW or ENTER - $scope.select = function(suggestion){ - if(suggestion){ - $scope.searchParam = suggestion; - $scope.searchFilter = suggestion; - if($scope.onSelect) - $scope.onSelect(suggestion); - } - watching = false; - $scope.completing = false; - setTimeout(function(){watching = true;},1000); - $scope.setIndex(-1); - }; - - - }], - link: function(scope, element, attrs){ - - var attr = ''; - - // Default atts - scope.attrs = { - "placeholder": "start typing...", - "class": "", - "id": "", - "inputclass": "", - "inputid": "" - }; - - for (var a in attrs) { - attr = a.replace('attr', '').toLowerCase(); - // add attribute overriding defaults - // and preventing duplication - if (a.indexOf('attr') === 0) { - scope.attrs[attr] = attrs[a]; - } - } - - if (attrs.clickActivation) { - element[0].onclick = function(e){ - if(!scope.searchParam){ - scope.completing = true; - scope.$apply(); - } - }; - } - - var key = {left: 37, up: 38, right: 39, down: 40 , enter: 13, esc: 27}; - - document.addEventListener("keydown", function(e){ - var keycode = e.keyCode || e.which; - - switch (keycode){ - case key.esc: - // disable suggestions on escape - scope.select(); - scope.setIndex(-1); - scope.$apply(); - e.preventDefault(); - } - }, true); - - document.addEventListener("blur", function(e){ - // disable suggestions on blur - // we do a timeout to prevent hiding it before a click event is registered - setTimeout(function() { - scope.select(); - scope.setIndex(-1); - scope.$apply(); - }, 200); - }, true); - - element[0].addEventListener("keydown",function (e){ - var keycode = e.keyCode || e.which; - - var l = angular.element(this).find('li').length; - - // implementation of the up and down movement in the list of suggestions - switch (keycode){ - case key.up: - - index = scope.getIndex()-1; - if(index<-1){ - index = l-1; - } else if (index >= l ){ - index = -1; - scope.setIndex(index); - scope.preSelectOff(); - break; - } - scope.setIndex(index); - - if(index!==-1) - scope.preSelect(angular.element(angular.element(this).find('li')[index]).text()); - - scope.$apply(); - - break; - case key.down: - index = scope.getIndex()+1; - if(index<-1){ - index = l-1; - } else if (index >= l ){ - index = -1; - scope.setIndex(index); - scope.preSelectOff(); - scope.$apply(); - break; - } - scope.setIndex(index); - - if(index!==-1) - scope.preSelect(angular.element(angular.element(this).find('li')[index]).text()); - - break; - case key.left: - break; - case key.right: - case key.enter: - - index = scope.getIndex(); - // scope.preSelectOff(); - if(index !== -1) - scope.select(angular.element(angular.element(this).find('li')[index]).text()); - scope.setIndex(-1); - scope.$apply(); - - break; - case key.esc: - // disable suggestions on escape - scope.select(); - scope.setIndex(-1); - scope.$apply(); - e.preventDefault(); - break; - default: - return; - } - - if(scope.getIndex()!==-1 || keycode == key.enter) - e.preventDefault(); - }); - }, - templateUrl: 'js/libs/angular-autocomplete/ac_template.html' - }; -}); - -app.filter('highlight', ['$sce', function ($sce) { - return function (input, searchParam) { - if (typeof input === 'function') return ''; - if (searchParam) { - var words = '(' + - searchParam.split(/\ /).join(' |') + '|' + - searchParam.split(/\ /).join('|') + - ')', - exp = new RegExp(words, 'gi'); - if (words.length) { - input = input.replace(exp, "$1"); - } - } - return $sce.trustAsHtml(input); - }; -}]); - -app.directive('suggestion', function(){ - return { - restrict: 'A', - require: '^autocomplete', // ^look for controller on parents element - link: function(scope, element, attrs, autoCtrl){ - element.bind('mouseenter', function() { - autoCtrl.preSelect(attrs.val); - autoCtrl.setIndex(attrs.index); - }); - - element.bind('mouseleave', function() { - autoCtrl.preSelectOff(); - }); - } - }; -}); diff --git a/services/web/frontend/js/vendor/libs/angular-cookie.js b/services/web/frontend/js/vendor/libs/angular-cookie.js deleted file mode 100644 index d0ffd46e0f..0000000000 --- a/services/web/frontend/js/vendor/libs/angular-cookie.js +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2013 Ivan Pusic - * Contributors: - * Matjaz Lipus - */ - //https://github.com/ivpusic/angular-cookie/blob/master/angular-cookie.js -angular.module('ivpusic.cookie', ['ipCookie']); -angular.module('ipCookie', ['ng']). -factory('ipCookie', ['$document', - function ($document) { - 'use strict'; - - return (function () { - function cookieFun(key, value, options) { - - var cookies, - list, - i, - cookie, - pos, - name, - hasCookies, - all, - expiresFor; - - options = options || {}; - - if (value !== undefined) { - // we are setting value - value = typeof value === 'object' ? JSON.stringify(value) : String(value); - - if (typeof options.expires === 'number') { - expiresFor = options.expires; - options.expires = new Date(); - // Trying to delete a cookie; set a date far in the past - if (expiresFor === -1) { - options.expires = new Date('Thu, 01 Jan 1970 00:00:00 GMT'); - // A new - } else if (options.expirationUnit !== undefined) { - if (options.expirationUnit === 'hours') { - options.expires.setHours(options.expires.getHours() + expiresFor); - } else if (options.expirationUnit === 'minutes') { - options.expires.setMinutes(options.expires.getMinutes() + expiresFor); - } else if (options.expirationUnit === 'seconds') { - options.expires.setSeconds(options.expires.getSeconds() + expiresFor); - } else { - options.expires.setDate(options.expires.getDate() + expiresFor); - } - } else { - options.expires.setDate(options.expires.getDate() + expiresFor); - } - } - return ($document[0].cookie = [ - encodeURIComponent(key), - '=', - encodeURIComponent(value), - options.expires ? '; expires=' + options.expires.toUTCString() : '', - options.path ? '; path=' + options.path : '', - options.domain ? '; domain=' + options.domain : '', - options.secure ? '; secure' : '' - ].join('')); - } - - list = []; - all = $document[0].cookie; - if (all) { - list = all.split('; '); - } - - cookies = {}; - hasCookies = false; - - for (i = 0; i < list.length; ++i) { - if (list[i]) { - cookie = list[i]; - pos = cookie.indexOf('='); - name = cookie.substring(0, pos); - value = decodeURIComponent(cookie.substring(pos + 1)); - - if (key === undefined || key === name) { - try { - cookies[name] = JSON.parse(value); - } catch (e) { - cookies[name] = value; - } - if (key === name) { - return cookies[name]; - } - hasCookies = true; - } - } - } - if (hasCookies && key === undefined) { - return cookies; - } - } - cookieFun.remove = function (key, options) { - var hasCookie = cookieFun(key) !== undefined; - - if (hasCookie) { - if (!options) { - options = {}; - } - options.expires = -1; - cookieFun(key, '', options); - } - return hasCookie; - }; - return cookieFun; - }()); - } -]); \ No newline at end of file diff --git a/services/web/frontend/js/vendor/libs/ng-context-menu-0.1.4.js b/services/web/frontend/js/vendor/libs/ng-context-menu-0.1.4.js deleted file mode 100644 index 29a7d202f8..0000000000 --- a/services/web/frontend/js/vendor/libs/ng-context-menu-0.1.4.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * ng-context-menu - v0.1.4 - An AngularJS directive to display a context menu when a right-click event is triggered - * - * @author Ian Kennington Walter (http://ianvonwalter.com) - */ -angular - .module('ng-context-menu', []) - .factory('ContextMenuService', function() { - return { - element: null, - menuElement: null, - container: null - }; - }) - .directive('contextMenu', ['$document', 'ContextMenuService', function($document, ContextMenuService) { - return { - restrict: 'A', - scope: { - 'callback': '&contextMenu', - 'disabled': '&contextMenuDisabled' - }, - link: function($scope, $element, $attrs) { - var opened = false; - - function open(event, menuElement, container) { - menuElement.addClass('open'); - - if (container) { - container.append(menuElement); - } - - var doc = $document[0].documentElement; - var docLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0), - docTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0), - elementHeight = menuElement[0].scrollHeight; - var docHeight = doc.clientHeight + docTop, - totalHeight = elementHeight + event.pageY, - top = Math.max(event.pageY - docTop, 0); - - if (totalHeight > docHeight) { - top = top - (totalHeight - docHeight); - } - - menuElement.css('top', top + 'px'); - menuElement.css('left', Math.max(event.pageX - docLeft, 0) + 'px'); - opened = true; - } - - function close(menuElement) { - menuElement.removeClass('open'); - opened = false; - } - - $element.bind('contextmenu', function(event) { - if (!$scope.disabled()) { - if (ContextMenuService.menuElement !== null) { - close(ContextMenuService.menuElement); - } - ContextMenuService.menuElement = angular.element(document.getElementById($attrs.target)); - if (typeof($attrs.contextMenuContainer) != "undefined") { - ContextMenuService.container = angular.element($attrs.contextMenuContainer) - } - ContextMenuService.element = event.target; - // console.log('set', ContextMenuService.element); - - event.preventDefault(); - event.stopPropagation(); - $scope.$apply(function() { - $scope.callback({ $event: event }); - open(event, ContextMenuService.menuElement, ContextMenuService.container); - }); - } - }); - - function handleKeyUpEvent(event) { - //console.log('keyup'); - if (!$scope.disabled() && opened && event.keyCode === 27) { - $scope.$apply(function() { - close(ContextMenuService.menuElement); - }); - } - } - - function handleClickEvent(event) { - if (!$scope.disabled() && - opened && - (event.button !== 2 || event.target !== ContextMenuService.element)) { - $scope.$apply(function() { - close(ContextMenuService.menuElement); - }); - } - } - - $document.bind('keyup', handleKeyUpEvent); - // Firefox treats a right-click as a click and a contextmenu event while other browsers - // just treat it as a contextmenu event - $document.bind('click', handleClickEvent); - $document.bind('contextmenu', handleClickEvent); - - $scope.$on('$destroy', function() { - //console.log('destroy'); - $document.unbind('keyup', handleKeyUpEvent); - $document.unbind('click', handleClickEvent); - $document.unbind('contextmenu', handleClickEvent); - }); - } - }; - }]); diff --git a/services/web/frontend/js/vendor/libs/passfield.js b/services/web/frontend/js/vendor/libs/passfield.js deleted file mode 100644 index 650da95c41..0000000000 --- a/services/web/frontend/js/vendor/libs/passfield.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! Pass*Field v1.1.9 | (c) 2014 Antelle | https://github.com/antelle/passfield/blob/master/MIT-LICENSE.txt */ -!function(a,b,c){"use strict";var d=c.PassField=c.PassField||{};d.Config=d.Config||{},d.Config.locales={en:{lower:!0,msg:{pass:"password",and:"and",showPass:"Show password",hidePass:"Hide password",genPass:"Random password",passTooShort:"password is too short (min. length: {})",noCharType:"password must contain {}",digits:"digits",letters:"letters",letters_up:"letters in UPPER case",symbols:"symbols",inBlackList:"password is in list of top used passwords",passRequired:"password is required",equalTo:"password is equal to login",repeat:"password consists of repeating characters",badChars:"password contains bad characters: “{}”",weakWarn:"weak",invalidPassWarn:"*",weakTitle:"This password is weak",generateMsg:"To generate a strong password, click {} button."}},de:{lower:!1,msg:{pass:"Passwort",and:"und",showPass:"Passwort anzeigen",hidePass:"Passwort verbergen",genPass:"Zufallspasswort",passTooShort:"Passwort ist zu kurz (Mindestlänge: {})",noCharType:"Passwort muss {} enthalten",digits:"Ziffern",letters:"Buchstaben",letters_up:"Buchstaben in GROSSSCHRIFT",symbols:"Symbole",inBlackList:"Passwort steht auf der Liste der beliebtesten Passwörter",passRequired:"Passwort wird benötigt",equalTo:"Passwort ist wie Anmeldung",repeat:"Passwort besteht aus sich wiederholenden Zeichen",badChars:"Passwort enthält ungültige Zeichen: “{}”",weakWarn:"Schwach",invalidPassWarn:"*",weakTitle:"Dieses Passwort ist schwach",generateMsg:"Klicken Sie auf den {}-Button, um ein starkes Passwort zu generieren."}},fr:{lower:!0,msg:{pass:"mot de passe",and:"et",showPass:"Montrer le mot de passe",hidePass:"Cacher le mot de passe",genPass:"Mot de passe aléatoire",passTooShort:"le mot de passe est trop court (min. longueur: {})",noCharType:"le mot de passe doit contenir des {}",digits:"chiffres",letters:"lettres",letters_up:"lettres en MAJUSCULES",symbols:"symboles",inBlackList:"le mot de passe est dans la liste des plus utilisés",passRequired:"le mot de passe est requis",equalTo:"le mot de passe est le même que l'identifiant",repeat:"le mot de passe est une répétition de caractères",badChars:"le mot de passe contient des caractères incorrects: “{}”",weakWarn:"faible",invalidPassWarn:"*",weakTitle:"Ce mot de passe est faible",generateMsg:"Pour créer un mot de passe fort cliquez sur le bouton {}."}},it:{lower:!1,msg:{pass:"password",and:"e",showPass:"Mostra password",hidePass:"Nascondi password",genPass:"Password casuale",passTooShort:"la password è troppo breve (lunghezza min.: {})",noCharType:"la password deve contenere {}",digits:"numeri",letters:"lettere",letters_up:"lettere in MAIUSCOLO",symbols:"simboli",inBlackList:"la password è nella lista delle password più usate",passRequired:"è necessaria una password",equalTo:"la password è uguale al login",repeat:"la password è composta da caratteri che si ripetono",badChars:"la password contiene caratteri non accettati: “{}”",weakWarn:"debole",invalidPassWarn:"*",weakTitle:"Questa password è debole",generateMsg:"Per generare una password forte, clicca sul tasto {}."}},ru:{lower:!0,msg:{pass:"пароль",and:"и",showPass:"Показать пароль",hidePass:"Скрыть пароль",genPass:"Случайный пароль",passTooShort:"пароль слишком короткий (мин. длина: {})",noCharType:"в пароле должны быть {}",digits:"цифры",letters:"буквы",letters_up:"буквы в ВЕРХНЕМ регистре",symbols:"символы",inBlackList:"этот пароль часто используется в Интернете",passRequired:"пароль обязателен",equalTo:"пароль совпадает с логином",repeat:"пароль состоит из повторяющихся символов",badChars:"в пароле есть недопустимые символы: «{}»",weakWarn:"слабый",invalidPassWarn:"*",weakTitle:"Пароль слабый, его легко взломать",generateMsg:"Чтобы сгенерировать пароль, нажмите кнопку {}."}},ua:{lower:!0,msg:{pass:"пароль",and:"i",showPass:"Показати пароль",hidePass:"Сховати пароль",genPass:"Випадковий пароль",passTooShort:"пароль є занадто коротким (мiн. довжина: {})",noCharType:"пароль повинен містити {}",digits:"цифри",letters:"букви",letters_up:"букви у ВЕРХНЬОМУ регістрі",symbols:"cимволи",inBlackList:"пароль входить до списку паролей, що використовуються найчастіше",passRequired:"пароль є обов'язковим",equalTo:"пароль та логін однакові",repeat:"пароль містить повторювані символи",badChars:"пароль містить неприпустимі символи: «{}»",weakWarn:"слабкий",invalidPassWarn:"*",weakTitle:"Цей пароль є слабким",generateMsg:"Щоб ​​створити надійний пароль, натисніть кнопку {}."}},es:{lower:!0,msg:{pass:"contraseña",and:"y",showPass:"Mostrar contraseña",hidePass:"Ocultar contraseña",genPass:"Contraseña aleatoria",passTooShort:"contraseña demasiado corta (longitud mín.: {})",noCharType:"la contraseña debe contener {}",digits:"dígitos",letters:"letras",letters_up:"letras en MAYÚSCULAS",symbols:"símbolos",inBlackList:"la contraseña está en la lista de las contraseñas más usadas",passRequired:"se requiere contraseña",equalTo:"la contraseña es igual al inicio de sesión",repeat:"la contraseña tiene caracteres repetidos",badChars:"la contraseña contiene caracteres no permitidos: “{}”",weakWarn:"débil",invalidPassWarn:"*",weakTitle:"Esta contraseña es débil",generateMsg:"Para generar una contraseña segura, haga clic en el botón de {}."}},el:{lower:!0,msg:{pass:"πρόσβασης",and:"και",showPass:"Προβολή κωδικού πρόσβασης",hidePass:"Απόκρυψη κωδικού πρόσβασης",genPass:"Τυχαίος κωδικός πρόσβασης",passTooShort:"ο κωδικός πρόσβασης είναι πολύ μικρός (ελάχιστο μήκος: {})",noCharType:"ο κωδικός πρόσβασης πρέπει να περιέχει {}",digits:"ψηφία",letters:"λατινικά γράμματα",letters_up:"λατινικά γράμματα με ΚΕΦΑΛΑΙΑ",symbols:"σύμβολα",inBlackList:"ο κωδικός πρόσβασης βρίσκεται σε κατάλογο δημοφιλέστερων κωδικών",passRequired:"απαιτείται κωδικός πρόσβασης",equalTo:"ο κωδικός είναι όμοιος με το όνομα χρήστη",repeat:"ο κωδικός αποτελείται από επαναλαμβανόμενους χαρακτήρες",badChars:"ο κωδικός περιέχει μη επιτρεπτούς χαρακτήρες: “{}”",weakWarn:"αδύναμος",invalidPassWarn:"*",weakTitle:"Αυτός ο κωδικός πρόσβασης είναι αδύναμος",generateMsg:"Για να δημιουργήσετε δυνατό κωδικό πρόσβασης, κάντε κλικ στο κουμπί {}."}},pt:{lower:!0,msg:{pass:"senha",and:"e",showPass:"Mostrar senha",hidePass:"Ocultar senha",genPass:"Senha aleatória",passTooShort:"senha muito curta (tamanho mínimo: {})",noCharType:"Senha deve conter {}",digits:"dígito",letters:"letras",letters_up:"letras maiúsculas",symbols:"símbolos",inBlackList:"senha está na lista das senhas mais usadas",passRequired:"senha é obrigatória",equalTo:"senha igual ao login",repeat:"senha consiste em uma repetição de caracteres",badChars:"senha tem caracteres inválidos: “{}”",weakWarn:"fraca",invalidPassWarn:"*",weakTitle:"Esta senha é fraca",generateMsg:"Para gerar uma senha forte, clique no botão {}."}}}}(window.jQuery,document,window),function(a,b,c,d){"use strict";var e=c.PassField=c.PassField||{};e.CharTypes={DIGIT:"digits",LETTER:"letters",LETTER_UP:"letters_up",SYMBOL:"symbols",UNKNOWN:"unknown"},e.CheckModes={MODERATE:0,STRICT:1},e.Config={defaults:{pattern:"abcdef12",acceptRate:.8,allowEmpty:!0,isMasked:!0,showToggle:!0,showGenerate:!0,showWarn:!0,showTip:!0,tipPopoverStyle:{},strengthCheckTimeout:500,validationCallback:null,blackList:[],locale:"",localeMsg:{},warnMsgClassName:"help-inline",errorWrapClassName:"error",allowAnyChars:!0,checkMode:e.CheckModes.MODERATE,chars:{digits:"1234567890",letters:"abcdefghijklmnopqrstuvwxyzßабвгедёжзийклмнопрстуфхцчшщъыьэюяґєåäâáàãéèêëíìîїóòôõöüúùûýñçøåæþðαβγδεζηθικλμνξοπρσςτυφχψω",letters_up:"ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГЕДЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯҐЄÅÄÂÁÀÃÉÈÊËÍÌÎЇÓÒÔÕÖÜÚÙÛÝÑÇØÅÆÞÐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ",symbols:"@#$%^&*()-_=+[]{};:<>/?!"},events:{generated:null,switched:null},nonMatchField:null,length:{min:null,max:null},maskBtn:{textMasked:"abc",textUnmasked:"•••",className:!1,classMasked:!1,classUnmasked:!1}},locales:e.Config?e.Config.locales:{},blackList:["password","123456","12345678","abc123","qwerty","monkey","letmein","dragon","111111","baseball","iloveyou","trustno1","1234567","sunshine","master","123123","welcome","shadow","ashley","football","jesus","michael","ninja","mustang","password1","p@ssw0rd","miss","root","secret"],generationChars:{digits:"1234567890",letters:"abcdefghijklmnopqrstuvwxyz",letters_up:"ABCDEFGHIJKLMNOPQRSTUVWXYZ"},dataAttr:"PassField.Field"},e.Field=function(g,h){function i(){j(),k()&&(l(),n(),C(),o(),E(),N(Cb.isMasked,!1),Q(),tb(e.Config.dataAttr,this))}function j(){Cb.blackList=(Cb.blackList||[]).concat(e.Config.blackList)}function k(){return"string"==typeof g&&(g=b.getElementById(g)),Bb.mainInput=g,!!Bb.mainInput}function l(){var a="en",b=Cb.locale;!b&&navigator.language&&(b=navigator.language.replace(/\-.*/g,"")),b&&(ub=Ab.locales[b]),ub&&(ub=f.extend({},Ab.locales[a],ub)),ub||(ub=f.extend({},Ab.locales[a])),Cb.localeMsg&&f.extend(ub.msg,Cb.localeMsg)}function m(a){Bb.mainInput.value=a,Bb.clearInput&&(Bb.clearInput.value=a),H()}function n(){vb=Bb.mainInput.id,vb||(vb="i"+Math.round(1e5*Math.random()),Bb.mainInput.id=vb)}function o(){var a=ib(Bb.mainInput);a.top+=lb(Bb.mainInput,"marginTop"),p(),q(),r(),s(),t(),u(),v(a),w(a),x(),setTimeout(y,0)}function p(){Bb.wrapper=Bb.mainInput.parentNode,pb(Bb.wrapper,"wrap"),zb.hasInlineBlock||pb(Bb.wrapper,"wrap-no-ib"),"static"==kb(Bb.wrapper,"position")&&(Bb.wrapper.style.position="relative")}function q(){Cb.length&&Cb.length.max&&Bb.mainInput.setAttribute("maxLength",Cb.length.max.toString())}function r(){if(!zb.changeType){Bb.clearInput=cb("input",{type:"text",id:"txt-clear",className:"txt-clear",value:Bb.mainInput.value},{display:"none"});var a=Bb.mainInput.className;a&&pb(Bb.clearInput,a,!0);var b=Bb.mainInput.style.cssText;b&&(Bb.clearInput.style.cssText=b),f.each(["maxLength","size","placeholder"],function(a){var b=Bb.mainInput.getAttribute(a);b&&Bb.clearInput.setAttribute(a,b)}),mb(Bb.mainInput,Bb.clearInput)}pb(Bb.mainInput,"txt-pass")}function s(){Cb.showWarn&&(Bb.warnMsg=cb("div",{id:"warn",className:"warn"},{margin:"0 0 0 3px"}),Cb.warnMsgClassName&&pb(Bb.warnMsg,Cb.warnMsgClassName,!0),mb(Bb.clearInput||Bb.mainInput,Bb.warnMsg))}function t(){Cb.showToggle&&(Bb.maskBtn=cb("div",{id:"btn-mask",className:"btn-mask",title:ub.msg.showPass},{position:"absolute",margin:"0",padding:"0"}),pb(Bb.maskBtn,"btn"),Cb.maskBtn.className&&pb(Bb.maskBtn,Cb.maskBtn.className,!0),Cb.maskBtn.classMasked&&pb(Bb.maskBtn,Cb.maskBtn.classMasked,!0),nb(Bb.maskBtn,Cb.maskBtn.textMasked),mb(Bb.mainInput,Bb.maskBtn))}function u(){Cb.showGenerate&&(Bb.genBtn=cb("div",{id:"btn-gen",className:"btn-gen",title:ub.msg.genPass},{position:"absolute",margin:"0",padding:"0"}),pb(Bb.genBtn,"btn"),mb(Bb.mainInput,Bb.genBtn),Bb.genBtnInner=cb("div",{id:"btn-gen-i",className:"btn-gen-i",title:ub.msg.genPass}),Bb.genBtn.appendChild(Bb.genBtnInner))}function v(b){if(Cb.showTip)if(Cb.tipPopoverStyle&&a&&"function"==typeof a.fn.popover)a(Bb.mainInput).popover(f.extend({title:null,placement:Cb.tipPopoverStyle.placement||function(b,d){var e=a(d).position().top-a(c).scrollTop(),f=a(c).height()-e;return f>300||f>e?"bottom":"top"},animation:!1},Cb.tipPopoverStyle,{trigger:"manual",html:!0,content:function(){return Lb}}));else{Bb.tip=cb("div",{id:"tip",className:"tip"},{position:"absolute",margin:"0",padding:"0",width:b.width+"px"}),mb(Bb.mainInput,Bb.tip);var d=cb("div",{id:"tip-arr-wrap",className:"tip-arr-wrap"});Bb.tip.appendChild(d),d.appendChild(cb("div",{id:"tip-arr",className:"tip-arr"})),d.appendChild(cb("div",{id:"tip-arr-in",className:"tip-arr-in"})),Bb.tipBody=cb("div",{id:"tip-body",className:"tip-body"}),Bb.tip.appendChild(Bb.tipBody)}}function w(a){if(zb.placeholders)!Bb.mainInput.getAttribute("placeholder")&&Bb.mainInput.getAttribute("data-placeholder")&&Bb.mainInput.setAttribute("placeholder",Bb.mainInput.getAttribute("data-placeholder"));else{var b=Bb.mainInput.getAttribute("placeholder")||Bb.mainInput.getAttribute("data-placeholder");b&&(Bb.placeholder=cb("div",{id:"placeholder",className:"placeholder"},{position:"absolute",margin:"0",padding:"0",height:a.height+"px",lineHeight:a.height+"px"}),nb(Bb.placeholder,b),mb(Bb.mainInput,Bb.placeholder))}}function x(){zb.passSymbol&&(Bb.passLengthChecker=cb("div",{id:"len"},{position:"absolute",height:kb(Bb.mainInput,"height"),top:"-10000px",left:"-10000px",display:"block",color:"transparent",border:"none"}),mb(Bb.mainInput,Bb.passLengthChecker),setTimeout(function(){f.each(["marginLeft","fontFamily","fontSize","fontWeight","fontStyle","fontVariant"],function(a){var b=kb(Bb.mainInput,a);b&&(Bb.passLengthChecker.style[a]=b)})},50))}function y(){A(),B();var a=ib(D()),b=z();Bb.maskBtn&&"none"!=Bb.maskBtn.style.display&&(b+=lb(Bb.maskBtn,"width"),jb(Bb.maskBtn,{top:a.top,left:a.left+a.width-b,height:a.height})),Bb.genBtn&&"none"!=Bb.genBtn.style.display&&(b+=lb(Bb.genBtn,"width"),jb(Bb.genBtn,{top:a.top,left:a.left+a.width-b,height:a.height}),Bb.genBtnInner.style.marginTop=Math.max(0,Math.round((a.height-19)/2))+"px"),Bb.placeholder&&"none"!=Bb.placeholder.style.display&&jb(Bb.placeholder,{top:a.top,left:a.left+7,height:a.height}),Bb.tip&&"none"!=Bb.tip.style.display&&jb(Bb.tip,{left:a.left,top:a.top+a.height,width:a.width})}function z(){var a=lb(D(),"paddingRight");return Math.max(Ob,a)}function A(){Bb.genBtn&&(Bb.genBtn.style.display=Gb||Hb&&!Ib?"block":"none"),Bb.maskBtn&&(Bb.maskBtn.style.display=Gb||Hb&&!Jb?"block":"none")}function B(){if(Cb.showTip)if(Bb.tip)Bb.tip.style.display=Eb&&Hb?"block":"none";else if(Eb&&Hb){if(!Kb||Lb!=Kb){var b=a(Bb.mainInput).data("popover")||a(Bb.mainInput).data("bs.popover"),c=b.options,d=c.animation;Kb&&(c.animation=!1);var e=D().offsetWidth-2,f=b.$tip;f?f.width(e):b.options.template&&(b.options.template=b.options.template.replace('class="popover"','class="popover" style="width: '+e+'px"')),Bb.clearInput&&(b.$element=a(D())),a(Bb.mainInput).popover("show"),Kb=Lb,c.animation=d}}else Kb&&(Kb=null,a(Bb.mainInput).popover("hide"))}function C(){var a=!0,c=!0,d=b.createElement("input");"placeholder"in d||(a=!1),d.setAttribute("style","position:absolute;left:-10000px;top:-10000px;"),b.body.appendChild(d);try{d.setAttribute("type","password")}catch(e){c=!1}b.body.removeChild(d);var f=b.createElement("div");f.setAttribute("style","display:inline-block"),f.style.paddingLeft=f.style.width="1px",b.body.appendChild(f);var g=2==f.offsetWidth,h="inline-block"===kb(f,"display");b.body.removeChild(f);var i=navigator.userAgent.indexOf("AppleWebKit")>=0||navigator.userAgent.indexOf("Opera")>=0||navigator.userAgent.indexOf("Firefox")>=0&&navigator.platform.indexOf("Mac")>=0?"•":"●";zb={placeholders:a,changeType:c,boxModel:g,hasInlineBlock:h,passSymbol:i}}function D(){return Db?Bb.mainInput:Bb.clearInput||Bb.mainInput}function E(){if(f.each(Bb.clearInput?[Bb.mainInput,Bb.clearInput]:[Bb.mainInput],function(a){f.attachEvent(a,"onkeyup",H),f.attachEvent(a,"onfocus",K),f.attachEvent(a,"onblur",L),f.attachEvent(a,"onmouseover",G),f.attachEvent(a,"onmouseout",G),Bb.placeholder&&f.attachEvent(a,"onkeydown",J)}),f.attachEvent(c,"onresize",y),Bb.maskBtn&&(f.attachEvent(Bb.maskBtn,"onclick",function(){N()}),f.attachEvent(Bb.maskBtn,"onmouseover",G),f.attachEvent(Bb.maskBtn,"onmouseout",G)),Bb.genBtn&&(f.attachEvent(Bb.genBtn,"onclick",function(){R()}),f.attachEvent(Bb.genBtn,"onmouseover",G),f.attachEvent(Bb.genBtn,"onmouseout",G)),Bb.placeholder&&f.attachEvent(Bb.placeholder,"onclick",F),Cb.nonMatchField){var a=ob(Cb.nonMatchField);a&&f.attachEvent(a,"onkeyup",M)}}function F(){D().focus()}function G(a){var b="mouseover"===a.type,c=a.relatedTarget?a.relatedTarget:b?a.fromElement:a.toElement;(!c||!c.id||0!=c.id.indexOf(Mb+"btn")&&c!==Bb.mainInput&&c!==Bb.clearInput)&&(Gb=b,y())}function H(a){var b,c=a?a.which||a.keyCode:null,d=c===Qb||c===Pb;b=Bb.clearInput?Db?Bb.clearInput.value=Bb.mainInput.value:Bb.mainInput.value=Bb.clearInput.value:Bb.mainInput.value,Cb.strengthCheckTimeout>0&&!Eb&&!d?(wb&&clearTimeout(wb),wb=setTimeout(S,Cb.strengthCheckTimeout)):S(),Bb.placeholder&&!b&&(Bb.placeholder.style.display="block"),I()}function I(){if(Bb.passLengthChecker){var a=D().value;Db&&(a=a.replace(/./g,zb.passSymbol)),nb(Bb.passLengthChecker,a);var b=Bb.passLengthChecker.offsetWidth;b+=lb(Bb.mainInput,"paddingLeft");var c=0,d=0,e=hb(D()),f=e.width,g=!1,h=z();if(Bb.maskBtn){c=lb(Bb.maskBtn,"width");var i=f-c-h,j=b>i;Jb!=j&&(g=!0,Jb=j)}if(Bb.genBtn){d=lb(Bb.genBtn,"width");var k=f-c-d-h,l=b>k;Ib!=l&&(g=!0,Ib=l)}g&&y()}}function J(){Bb.placeholder&&(Bb.placeholder.style.display="none")}function K(){xb&&(clearTimeout(xb),xb=null),yb&&(clearTimeout(yb),yb=null),Hb=!0,y()}function L(){xb=setTimeout(function(){xb=null,Hb=!1,y(),Cb.isMasked&&!yb&&(yb=setTimeout(function(){yb=null,N(!0,!1)},1500))},100)}function M(){Eb&&S()}function N(a,b){b===d&&(b=!0);var c=a!=Db;if(a=a===d?!Db:!!a,zb.changeType){var e=D(),g=O(e);e.setAttribute("type",a?"password":"text"),b&&(P(e,g),e.focus())}else{var h=kb(D(),"display")||"block",i=a?Bb.clearInput:Bb.mainInput,j=a?Bb.mainInput:Bb.clearInput;Db!=a&&f.each(["paddingRight","width","backgroundImage","backgroundPosition","backgroundRepeat","backgroundAttachment","border"],function(a){var b=i.style[a];b&&(j.style[a]=b)});var k=O(i);j.style.display=h,i.style.display="none",j.value=i.value,b&&(P(j,k),j.focus()),Bb.mainInput.nextSibling!=Bb.clearInput&&mb(Bb.mainInput,Bb.clearInput)}Bb.maskBtn&&(nb(Bb.maskBtn,a?Cb.maskBtn.textMasked:Cb.maskBtn.textUnmasked),a?(Cb.maskBtn.classUnmasked&&qb(Bb.maskBtn,Cb.maskBtn.classUnmasked,!0),Cb.maskBtn.classMasked&&pb(Bb.maskBtn,Cb.maskBtn.classMasked,!0)):(Cb.maskBtn.classMasked&&qb(Bb.maskBtn,Cb.maskBtn.classMasked,!0),Cb.maskBtn.classUnmasked&&pb(Bb.maskBtn,Cb.maskBtn.classUnmasked,!0)),Bb.maskBtn.title=a?ub.msg.showPass:ub.msg.hidePass),Db=a,I(),y(),c&&sb("switched",Db)}function O(a){return"number"==typeof a.selectionStart&&"number"==typeof a.selectionEnd?{start:a.selectionStart,end:a.selectionEnd}:null}function P(a,b){b&&"number"==typeof a.selectionStart&&"number"==typeof a.selectionEnd&&(a.selectionStart=b.start,a.selectionEnd=b.end)}function Q(){("function"==typeof Bb.mainInput.hasAttribute&&Bb.mainInput.hasAttribute("autofocus")||Bb.mainInput.getAttribute("autofocus"))&&(Bb.mainInput.focus(),K())}function R(){var a=$();Bb.mainInput.value=a,Bb.clearInput&&(Bb.clearInput.value=a),sb("generated",a),N(!1),wb&&(clearTimeout(wb),wb=null),S(),Bb.placeholder&&(Bb.placeholder.style.display="none")}function S(){wb&&(clearTimeout(wb),wb=null);var a=D().value,b=T(a);if(0==a.length)b={strength:Cb.allowEmpty?0:null,messages:[ub.msg.passRequired]};else{!Cb.allowAnyChars&&b.charTypes[e.CharTypes.UNKNOWN]&&(b={strength:null,messages:[ub.msg.badChars.replace("{}",b.charTypes[e.CharTypes.UNKNOWN])]}),delete b.charTypes;var c=!1;f.each(Cb.blackList,function(b){return b==a?(c=!0,!1):!0}),c&&(b={strength:0,messages:[ub.msg.inBlackList]}),a&&a===X()&&(b={strength:0,messages:[ub.msg.equalTo]})}if("function"==typeof Cb.validationCallback){var d,g,h=Cb.validationCallback(Bb.mainInput,b);h&&h.messages&&f.isArray(h.messages)&&(d=h.messages),h&&Object.prototype.hasOwnProperty.call(h,"strength")&&("number"==typeof h.strength||null===h.strength)&&(g=h.strength),d&&d.length?(b.messages=d,b.strength=g):g&&g>b.strength&&(b.strength=g)}return 0==a.length&&Cb.allowEmpty?(W(),Fb={strength:0},!0):null===b.strength||b.strengthf&&(h=h.substring(0,f)),b=b+" ("+h+")"}d.push(b)}});var h=1-d.length/g;if(d.length&&(d=[U(d)]),Cb.checkMode==e.CheckModes.MODERATE){var i=0;f.each(c,function(a){b[a]||i++}),h+=i/g}var j=Cb.pattern.length,k=a.length/j-1;if(Cb.length&&Cb.length.min&&a.lengthj&&(j=Cb.length.min)),0>k?(h+=k,d.push(ub.msg.passTooShort.replace("{}",j.toString()))):Cb.checkMode==e.CheckModes.MODERATE&&(h+=k/g),a.length>2){for(var l=a.charAt(0),m=!0,n=0;nh&&(h=0),h>1&&(h=1),{strength:h,messages:d,charTypes:c}}function U(a){for(var b=a[0],c=1;c",f=f.toUpperCase()),d+=f+b[e].substring(1),d&&"."!=d.charAt(d.length-1)&&(d+=".")}if(d&&"."!=d.charAt(d.length-1)&&(d+="."),Fb={strength:a,message:d},Bb.warnMsg&&(nb(Bb.warnMsg,c),Bb.warnMsg.title=d,Cb.errorWrapClassName&&pb(Bb.wrapper,Cb.errorWrapClassName,!0)),Cb.showTip){var g=d;Bb.genBtn&&(g+="
"+ub.msg.generateMsg.replace("{}",'
')),Lb=g,Bb.tipBody&&nb(Bb.tipBody,g)}Eb=!0,y()}function W(){Bb.warnMsg&&(nb(Bb.warnMsg,""),Bb.warnMsg.title="",Cb.errorWrapClassName&&qb(Bb.wrapper,Cb.errorWrapClassName,!0)),Lb=null,Eb=!1,y()}function X(){if(!Cb.nonMatchField)return null;var a=ob(Cb.nonMatchField);return a?a.value:null}function Y(){return Fb?Fb.message:null}function Z(){return Fb?Fb.strength:-1}function $(){var a="",b=_(Cb.pattern,e.CharTypes.SYMBOL),c=[];return f.each(b,function(a,b){for(var d=0;d=0?(g=a,!1):!0}),c[g]=(c[g]||"")+e}return c}function ab(a){return Mb+a+"-"+vb}function bb(a){return Mb+a}function cb(a,b,c){return b.id&&(b.id=ab(b.id)),b.className&&(b.className=bb(b.className)),f.newEl(a,b,c)}function db(a){try{return a.getBoundingClientRect()}catch(b){return{top:0,left:0}}}function eb(a){var b=a.ownerDocument;if(!b)return{top:0,left:0};var d=db(a);return{top:d.top+(c.pageYOffset||0)-(b.documentElement.clientTop||0),left:d.left+(c.pageXOffset||0)-(b.documentElement.clientLeft||0)}}function fb(a){var c;try{c=a.offsetParent}catch(d){}for(c||(c=b.documentElement);c&&"html"!=c.nodeName.toLowerCase()&&"static"===kb(c,"position");)c=c.offsetParent;return c||b.documentElement}function gb(a){var b,c={top:0,left:0};if("fixed"===kb(a,"position"))b=db(a);else{var d=fb(a);b=eb(a),"html"!=d.nodeName.toLowerCase()&&(c=eb(d)),c.top+=lb(d,"borderTopWidth"),c.left+=lb(d,"borderLeftWidth")}return{top:b.top-c.top-lb(a,"marginTop"),left:b.left-c.left-lb(a,"marginLeft")}}function hb(a){return{width:a.offsetWidth,height:a.offsetHeight}}function ib(a){return f.extend(eb(a),hb(a))}function jb(a,b){if(b.height&&!isNaN(b.height)&&(a.style.height=b.height+"px",a.style.lineHeight=b.height+"px"),b.width&&!isNaN(b.width)&&(a.style.width=b.width+"px"),b.top||b.left){if("none"==kb(a,"display"))return a.style.top=b.top+"px",a.style.left=b.left+"px",void 0;var c,d,e;if(e=eb(a),d=kb(a,"top")||0,c=kb(a,"left")||0,(d+c+"").indexOf("auto")>-1){var f=gb(a);d=f.top,c=f.left}else d=parseFloat(d)||0,c=parseFloat(c)||0;b.top&&(a.style.top=b.top-e.top+d+"px"),b.left&&(a.style.left=b.left-e.left+c+"px")}}function kb(a,b){var d="function"==typeof c.getComputedStyle?c.getComputedStyle(a,null):a.currentStyle;return d?d[b]:null}function lb(a,b){var c=kb(a,b);if(!c)return 0;var d=parseFloat(c);return isNaN(d)?0:d}function mb(a,b){a.parentNode&&a.parentNode.insertBefore(b,a.nextSibling)}function nb(a,c){try{a.innerHTML=c}catch(d){var e=b.createElement("c");for(e.innerHTML=c;a.firstChild;)a.removeChild(a.firstChild);a.appendChild(e)}}function ob(a){return"string"==typeof a?b.getElementById(a):a.jquery?a[0]:a}function pb(a,b,c){rb(a,b,c)||(a.className=a.className+(a.className?" ":"")+(c===!0?b:bb(b)))}function qb(a,b,c){rb(a,b,c)&&(a.className=(" "+a.className+" ").replace((c===!0?b:bb(b))+" ","").replace(/^\s+|\s+$/g,""))}function rb(a,b,c){return b=" "+(c===!0?b:bb(b))+" ",(" "+a.className+" ").replace(/[\n\t]/g," ").indexOf(b)>-1}function sb(b,c){if(a)try{a(Bb.mainInput).trigger(Nb+b,c)}catch(d){}if(Cb.events&&"function"==typeof Cb.events[b])try{Cb.events[b].call(Bb.mainInput,c)}catch(d){}}function tb(b,c){a&&a(Bb.mainInput).data(b,c)}var ub,vb,wb,xb,yb,zb,Ab=e.Config,Bb={},Cb=f.extend({},Ab.defaults,h),Db=!0,Eb=!1,Fb=null,Gb=!1,Hb=!1,Ib=!1,Jb=!1,Kb=!1,Lb=null,Mb="a_pf-",Nb="pass:",Ob=5,Pb=46,Qb=8;this.toggleMasking=function(a){N(a)},this.setPass=m,this.validatePass=S,this.getPassValidationMessage=Y,this.getPassStrength=Z,i.call(this)};var f={};f.extend=function(){for(var a=arguments,b=1;b