sogo/UI/WebServerResources/js/Common.js.map
2015-12-11 15:44:55 -05:00

1 line
190 KiB
Plaintext

{"version":3,"sources":["Common/utils.js","Common/Common.app.js","Common/mdColors.app.js","Common/decodeUri.filter.js","Common/encodeUri.filter.js","Common/ensureTarget.filter.js","Common/loc.filter.js","Common/range.filter.js","Common/AclController.js","Common/navController.js","Common/Acl.service.js","Common/Alarm.service.js","Common/Authentication.service.js","Common/Dialog.service.js","Common/Gravatar.service.js","Common/Resource.service.js","Common/User.service.js","Common/sgFocus.service.js","Common/sgAvatarImage.directive.js","Common/sgColorPicker.directive.js","Common/sgCompile.directive.js","Common/sgEnter.directive.js","Common/sgEscape.directive.js","Common/sgFocus.directive.js","Common/sgFolderStylesheet.directive.js","Common/sgPlaceholder.directive.js","Common/sgSearch.directive.js","Common/sgSubscribe.directive.js","Common/sgTimepicker.directive.js","Common/sgToggleGrid.directive.js","Common/sgVariableScrollShrink.directive.js"],"names":["l","key","arguments","value","labels","clabels","i","j","length","replace","hexToRgb","hex","result","exec","r","parseInt","g","b","contrast","color","c","Math","pow","guid","S4","random","toString","substring","substr","toLowerCase","configure","$logProvider","$compileProvider","$httpProvider","$mdThemingProvider","definePalette","50","100","200","300","400","500","600","700","800","900","A100","A200","A400","A700","contrastDefaultColor","contrastLightColors","contrastDarkColors","1000","theme","primaryPalette","default","hue-1","hue-2","hue-3","accentPalette","backgroundPalette","DebugEnabled","debugEnabled","debugInfoEnabled","interceptors","push","AuthInterceptor","$window","$q","response","test","config","headers","Accept","data","location","reload","reject","ErrorInterceptor","$rootScope","responseError","rejection","$broadcast","angular","module","isPopup","document","body","classList","contains","baseURL","ApplicationBaseURL","activeUser","param","settings","login","UserLogin","identification","UserIdentification","email","UserEmail","language","UserLanguage","folderURL","UserFolderURL","isSuperUser","IsSuperUser","path","calendar","UserCalendarPath","contacts","UserContactsPath","mail","UserMailPath","preferences","UserPreferencesPath","administration","UserAdministrationPath","logoff","UserLogoffPath","constant","selection","xs","gt-xs","sm","gt-sm","md","gt-md","lg","gt-lg","xl","factory","$inject","_$mdThemingProvider","runBlock","$interpolate","$document","$log","buildCssSelectors","selectors","join","addRule","fgInterpolate","bgInterpolate","themeName","paletteName","colorArray","hueName","colorValue","colorContrast","context","palette","hue","customSheet","insertRule","index","addBorderRule","bdrInterpolate","getStyleSheet","style","head","querySelector","createElement","title","appendChild","createTextNode","sheet","fgDefault","bgDefault","bdrDefault","fgDefaultHue","bgDefaultHue","fgColor","bgColor","bdrColor","fgHue","bgHue","cssRules","deleteRule","forEach","_THEMES","_PALETTES","colors","primary","name","hues","run","decodeUri","decodeURIComponent","filter","encodeUri","encodeURIComponent","ensureTarget","$sce","element","tree","find","attr","trustAs","html","loc","range","n","res","AclController","$mdDialog","Dialog","usersWithACL","User","folder","userFilter","$query","$filter","$acl","users","closeModal","$resetUsersRights","hide","saveModal","$saveUsersRights","then","status","alert","confirmChange","user","confirmation","$confirmRights","vm","showing","message","removeUser","$removeUser","uid","addUser","$addUser","userToAdd","searchText","selectedUid","selectUser","error","selectedUser","$rights","this","controller","navController","$scope","$timeout","$interval","$http","$mdSidenav","$mdToast","$mdMedia","sgConstant","sgSettings","Alarm","leftIsClose","isOpen","onHttpError","event","statusText","show","template","hideDelay","position","currentDay","window","get","success","secondsBeforeTomorrow","toggleLeft","toggle","debug","toggleRight","$watch","newVal","isGtMedium","$on","getAlarms","Acl","folderId","Settings","Resource","extend","$$resource","$User","prototype","$users","owner","_this","deferred","defer","acls","isDefined","userResource","fetch","canSubscribeUser","isSubscribed","wasSubscribed","bind","resolve","promise","_","indexOf","pluck","userClass","isGroup","splice","$resetRights","deferredSave","deferredSubscribe","action","$rightsAreDirty","$omit","save","$shadowRights","copy","rights","uids","all","currentAlarm","AlarmService","$toast","now","Date","browserTime","floor","getTime","alarms","sort","a","x","y","next","pop","utc","url","alarmTime","delay","f","showAlarm","cancel","AlarmController","scope","reminder","ok","summary","locals","Authentication","readCookie","foundCookie","prefix","pairs","currentPair","start","cookie","split","charAt","readLoginCookie","loginValues","base64decode","redirectUrl","username","domain","userName","address","baseAddress","altBaseAddress","parts","hostpart","protocol","newAddress","href","startsWith","endsWith","getService","passwordPolicyConfig","service","d","password","rememberLogin","loginSuffix","method","loginCookie","expire","grace","msg","perr","LDAPPasswordPolicyError","PolicyNoError","PolicyAccountLocked","changePassword","newPassword","PolicyPasswordModNotAllowed","PolicyInsufficientPasswordQuality","PolicyPasswordTooShort","PolicyPasswordTooYoung","PolicyPasswordInHistory","formatted","PolicyPasswordUnknown","PolicyPasswordSystemUnknown","$get","PolicyPasswordChangeUnsupported","PolicyPasswordExpired","PolicyChangeAfterReset","PolicyMustSupplyOldPassword","provider","DialogService","$modal","content","textContent","confirm","options","prompt","label","PromptDialogController","o","parent","clickOutsideToClose","escapeToClose","inputType","Gravatar","size","alternate_avatar","hash","s","md5","_http","_q","_path","_activeUser","$factory","compact","escape","params","flatten","newguid","create","post","id","newValue","remove","userData","init","$gravatar","search","excludedUsers","dry","when","results","compareUids","each","isUndefined","$$shortFormat","$shortFormat","$$image","image","c_email","$alternateAvatar","empty","fullname","cn","no_email","$isAnonymous","$isSpecial","$confirmation","some","values","isEqual","zero","map","keys","isString","$folders","type","$$folders","folders","sgFocus","sgAvatarImage","restrict","src","link","bindToController","controllerAs","attrs","el","imgElement","className","img","insertGenericAvatar","sgAvatarImageController","$element","Preferences","ready","genericAvatar","parentNode","removeChild","defaults","SOGoAlternateAvatar","attributes","avatar","add","insertBefore","directive","sgColorPicker","iElement","iAttr","ngModelController","$render","sgColor","$viewValue","sgIconColor","require","sgColorPickerController","sgColors","setColor","$setViewValue","sgCompile","$compile","sgCompileLink","ensureCompileRunsOnce","$eval","contents","sgEnter","ENTER_KEY","which","$apply","preventDefault","sgEscape","ESCAPE_KEY","elem","keyCode","sgFocusOn","e","focus","select","sgFolderStylesheet","sgFolderStylesheetController","ngModel","sgPlaceholder","placeholder","sgSearchPreTransclude","$parse","compile","tElement","tAttr","inputEl","selectEl","buttonEl","removeAttr","compiledButtonEl","doSearch","on","cancelSearch","priority","sgSearch","transclude","clone","append","sgSearchController","previous","searchField","searchTextOptions","updateOn","debounce","blur","onChange","sgSubscribe","folderType","onFolderSelect","sgSubscribeDialogController","showDialog","templateUrl","sgSubscribeController","selectFolder","folderData","close","timePaneDirective","TimePaneCtrl","controllers","ngModelCtrl","sgTimePaneCtrl","timePaneElement","configureNgModel","$attrs","$animate","$mdConstant","$mdTheming","$$mdDateUtil","$mdDateLocale","$mdInkRipple","$mdUtil","m","KEY_CODE","dateUtil","nextTimePaneUniqueId","selectedTime","displayTime","isInitialized","hours","displayName","selected","min5","min1","ii","show5min","getToggleBtnLbl","is5min","toggleManual5min","manual5min","tabindex","self","hourClickHandler","displayVal","updated","setHours","Number","setNgModelValue","minuteClickHandler","val","setMinutes","attachTimePaneEventListeners","SELECTED_TIME_CLASS","FOCUSED_TIME_CLASS","changeSelectedTime","date","previousSelectedTime","changeDisplayTime","prevH","getHours","prevHCell","getElementById","setAttribute","prevM","getMinutes","prevMCell","prevM5Cell","mCell","newH","hCell","newM","isValidDate","buildInitialTimePaneDisplay","today","handleKeyEvent","ESCAPE","TAB","$emit","ENTER","mode","changed","opt_date","previousFocus","timePickerDirective","TimePickerCtrl","mdTimePickerCtrl","$$rAF","dateLocale","inputElement","inputContainer","ngInputElement","timePane","timeButton","inputMask","isFocused","isDisabled","setDisabled","disabled","isTimeOpen","timePaneOpenedFrom","nextUid","bodyClickHandler","handleBodyClick","windowResizeHandler","closeTimePane","installPropertyInterceptors","attachChangeListeners","attachInteractionListeners","detachTimePane","EXTRA_INPUT_SIZE","INVALID_CLASS","DEFAULT_DEBOUNCE_INTERVAL","TIME_PANE_HEIGHT","MIN5","GTSM","SM","MIN1","TIME_PANE_WIDTH","time","formatTime","resizeInputElement","t","h","handleInputEvent","keyCodes","altKey","DOWN_ARROW","openTimePane","$digest","ngDisabled","validateScope","Object","defineProperty","set","inputString","arr","isDate","attachTimePane","addClass","elementRect","getBoundingClientRect","bodyRect","paneTop","top","paneLeft","left","paneWidth","right","min","paneHeight","bottom","width","removeClass","target","disableScrollAround","nextTick","addEventListener","enableScrolling","removeEventListener","getTimePaneCtrl","focusTime","ctrl","setFocused","isInTime","getClosest","sgToggleGrid","day","findIndex","modelDays","modelAttr","tile","ensureInitRunsOnce","toggleClass","tiles","days","flattenedDays","sgToggleGridAttr","sgVariableScrollShrink","console","prop","String","suffix","pattern","isNumber","lastIndexOf","_base64_keyStr","base64encode","chr1","chr2","chr3","enc1","enc2","enc3","enc4","output","input","utf8encode","charCodeAt","isNaN","fromCharCode","L","k","K","G","I","F","H","q","p","u","aa","Z","D","Array","B","J","P","E","v","Y","X","W","V","C","S","Q","N","M","A","z","w","U","T","R","O","capitalize","toUpperCase","slice","asDate","newDate","minutes","newString","isValidEmail","emailRE","asCSSIdentifier","characters","escapeds","re","RegExp","timeInterval","interval","daysUpTo","otherDate","day1","day2","tmp","nbrDays","round","setTime","minutesTo","delta","dstOffset","valueOf","getTimezoneOffset","stringWithSeparator","separator","month","getMonth","getDate","year","getYear","str","addDays","initialDate","milliSeconds","addHours","nbrHours","addMinutes","nbrMinutes","beginOfDay","setSeconds","setMilliseconds","beginOfWeek","offset","firstDayOfWeek","getDay","endOfWeek","getDayString","getHourString"],"mappings":"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","file":"Common.js","sourcesContent":["/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\nString.prototype.endsWith = function(suffix) {\n return this.indexOf(suffix, this.length - suffix.length) !== -1;\n};\n\nString.prototype.startsWith = function(pattern, position) {\n position = angular.isNumber(position) ? position : 0;\n return this.lastIndexOf(pattern, position) === position;\n};\n\nString.prototype._base64_keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\nString.prototype.base64encode = function () {\n var output = \"\";\n var chr1, chr2, chr3, enc1, enc2, enc3, enc4;\n var i = 0;\n \n var input = this.utf8encode();\n\n while (i < input.length) {\n chr1 = input.charCodeAt(i++);\n chr2 = input.charCodeAt(i++);\n chr3 = input.charCodeAt(i++);\n \n enc1 = chr1 >> 2;\n enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);\n enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);\n enc4 = chr3 & 63;\n \n if (isNaN(chr2)) {\n enc3 = enc4 = 64;\n } else if (isNaN(chr3)) {\n enc4 = 64;\n }\n \n output = output +\n this._base64_keyStr.charAt(enc1) + this._base64_keyStr.charAt(enc2) +\n this._base64_keyStr.charAt(enc3) + this._base64_keyStr.charAt(enc4);\n }\n \n return output;\n};\n\nString.prototype.base64decode = function() { \n var output = \"\";\n var chr1, chr2, chr3;\n var enc1, enc2, enc3, enc4;\n var i = 0;\n \n var input = \"\" + this; // .replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\")\n while (i < input.length) {\n enc1 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc2 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc3 = this._base64_keyStr.indexOf(input.charAt(i++));\n enc4 = this._base64_keyStr.indexOf(input.charAt(i++));\n\n chr1 = (enc1 << 2) | (enc2 >> 4);\n chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);\n chr3 = ((enc3 & 3) << 6) | enc4;\n \n output = output + String.fromCharCode(chr1);\n \n if (enc3 != 64) {\n output = output + String.fromCharCode(chr2);\n }\n if (enc4 != 64) {\n output = output + String.fromCharCode(chr3);\n }\n }\n\n return output;\n};\n\nString.prototype.md5 = function() {\n if (!this.length) { return; }\n // MD5 (Message-Digest Algorithm) by WebToolkit\n var md5 = function(s){function L(k,d){return(k<<d)|(k>>>(32-d));}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H);}if(I|d){if(x&1073741824){return(x^3221225472^F^H);}else{return(x^1073741824^F^H);}}else{return(x^F^H);}}function r(d,F,k){return(d&F)|((~d)&k);}function q(d,F,k){return(d&k)|(F&(~k));}function p(d,F,k){return(d^F^k);}function n(d,F,k){return(F^(d|(~k)));}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F);}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F);}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F);}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F);}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H<F){Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=(aa[Z]|(G.charCodeAt(H)<<d));H++;}Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=aa[Z]|(128<<d);aa[I-2]=F<<3;aa[I-1]=F>>>29;return aa;}function B(x){var k=\"\",F=\"\",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F=\"0\"+G.toString(16);k=k+F.substr(F.length-2,2);}return k;}function J(k){k=k.replace(/rn/g,\"n\");var d=\"\";for(var F=0;F<k.length;F++){var x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x);}else{if((x>127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128);}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128);}}}return d;}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g);}var i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase();};\n return md5(this.toLowerCase());\n};\n\nString.prototype.capitalize = function() {\n return this.charAt(0).toUpperCase() + this.slice(1);\n};\n\nString.prototype.asDate = function () {\n var newDate;\n var date = this.split(\"/\");\n if (date.length == 3)\n newDate = new Date(date[2], date[1] - 1, date[0]); // dd/mm/yyyy\n else {\n date = this.split(\"-\");\n if (date.length == 3)\n newDate = new Date(date[0], date[1] - 1, date[2]); // yyyy-mm-dd\n else {\n if (this.length == 8) {\n newDate = new Date(this.substring(0, 4),\n this.substring(4, 6) - 1,\n this.substring(6, 8)); // yyyymmdd\n }\n }\n }\n\n return newDate;\n};\n\nString.prototype.formatTime = function(hours, minutes) {\n var newString = this;\n\n // See http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSCalendarDate.html#method$NSCalendarDate-descriptionWithCalendarFormat$\n var p = 'am', i = hours, m = minutes;\n if (hours > 12) {\n p = 'pm';\n i = hours % 12;\n }\n if (minutes < 10) {\n m = '0' + minutes;\n }\n\n // %H : hour as a decimal number using 24-hour clock\n newString = newString.replace(\"%H\", hours < 10 ? '0' + hours : hours);\n // %I : hour as a decimal number using 12-hour clock\n newString = newString.replace(\"%I\", i < 10 ? '0' + i : i);\n // %M : minute as decimal number\n newString = newString.replace(\"%M\", m);\n // %p : 'am' or 'pm'\n newString = newString.replace(\"%p\", p);\n\n return newString;\n};\n\nString.prototype.isValidEmail = function() {\n var emailRE = /^([\\w\\!\\#$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\`{\\|\\}\\~]+\\.)*[\\w\\!\\#$\\%\\&\\'\\*\\+\\-\\/\\=\\?\\^\\`{\\|\\}\\~]+@((((([a-z0-9]{1}[a-z0-9\\-]{0,62}[a-z0-9]{1})|[a-z])\\.)+[a-z]{2,})|(\\d{1,3}\\.){3}\\d{1,3}(\\:\\d{1,5})?)$/i;\n return emailRE.test(this);\n};\n\nString.prototype.asCSSIdentifier = function() {\n var characters = [ '_' , '\\\\.', '#' , '@' , '\\\\*', ':' , ',' , ' ', \"'\", '&', '\\\\+' ];\n var escapeds = [ '_U_', '_D_', '_H_', '_A_', '_S_', '_C_', '_CO_', '_SP_', '_SQ_', '_AM_', '_P_' ];\n\n var newString = this;\n for (var i = 0; i < characters.length; i++) {\n var re = new RegExp(characters[i], 'g');\n newString = newString.replace(re, escapeds[i]);\n }\n\n if (/^\\d+/.test(newString)) {\n newString = '_' + newString;\n }\n\n return newString;\n};\n\nString.prototype.timeInterval = function () {\n var interval;\n if (this == \"once_per_hour\")\n interval = 3600;\n else if (this == \"every_minute\")\n interval = 60;\n else {\n interval = parseInt(this.substr(6)) * 60;\n }\n\n return interval;\n};\n\nDate.prototype.daysUpTo = function(otherDate) {\n var days = [];\n\n var day1 = this.getTime();\n var day2 = otherDate.getTime();\n if (day1 > day2) {\n var tmp = day1;\n day1 = day2;\n day2 = tmp;\n }\n\n var nbrDays = Math.round((day2 - day1) / 86400000) + 1;\n for (var i = 0; i < nbrDays; i++) {\n var newDate = new Date();\n newDate.setTime(day1 + (i * 86400000));\n days.push(newDate);\n }\n\n return days;\n};\n\nDate.prototype.minutesTo = function(otherDate) {\n var delta, dstOffset;\n\n delta = Math.floor(otherDate.valueOf() - this.valueOf())/1000/60;\n dstOffset = otherDate.getTimezoneOffset() - this.getTimezoneOffset();\n\n return delta - dstOffset;\n};\n\nDate.prototype.stringWithSeparator = function(separator) {\n var month = '' + (this.getMonth() + 1);\n var day = '' + this.getDate();\n var year = this.getYear();\n if (year < 1000)\n year = '' + (year + 1900);\n if (month.length == 1)\n month = '0' + month;\n if (day.length == 1)\n day = '0' + day;\n\n if (separator == '-')\n str = year + '-' + month + '-' + day;\n else\n str = day + '/' + month + '/' + year;\n\n return str;\n};\n\nDate.prototype.addDays = function(nbrDays) {\n var initialDate, milliSeconds, dstOffset;\n\n milliSeconds = this.getTime();\n initialDate = new Date(milliSeconds);\n milliSeconds += 86400000 * nbrDays;\n this.setTime(milliSeconds);\n\n dstOffset = this.getTimezoneOffset() - initialDate.getTimezoneOffset();\n if (dstOffset !== 0) {\n milliSeconds = this.getTime() + dstOffset*60*1000;\n this.setTime(milliSeconds);\n }\n};\n\nDate.prototype.addHours = function(nbrHours) {\n var milliSeconds = this.getTime();\n milliSeconds += 3600000 * nbrHours;\n this.setTime(milliSeconds);\n};\n\nDate.prototype.addMinutes = function(nbrMinutes) {\n var milliSeconds = this.getTime();\n milliSeconds += 60000 * nbrMinutes;\n this.setTime(milliSeconds);\n};\n\nDate.prototype.beginOfDay = function() {\n var beginOfDay = new Date(this.getTime());\n beginOfDay.setHours(0);\n beginOfDay.setMinutes(0);\n beginOfDay.setSeconds(0);\n beginOfDay.setMilliseconds(0);\n\n return beginOfDay;\n};\n\nDate.prototype.beginOfWeek = function() {\n var offset = firstDayOfWeek - this.getDay();\n if (offset > 0)\n offset -= 7;\n\n var beginOfWeek = this.beginOfDay();\n beginOfWeek.setHours(12);\n beginOfWeek.addDays(offset);\n\n return beginOfWeek;\n};\n\nDate.prototype.endOfWeek = function() {\n var endOfWeek = this.beginOfWeek();\n endOfWeek.addDays(6);\n\n endOfWeek.setHours(23);\n endOfWeek.setMinutes(59);\n endOfWeek.setSeconds(59);\n endOfWeek.setMilliseconds(999);\n\n return endOfWeek;\n};\n\n// YYYYMMDD\nDate.prototype.getDayString = function() {\n var newString = this.getYear();\n if (newString < 1000) newString += 1900;\n var month = '' + (this.getMonth() + 1);\n if (month.length == 1)\n month = '0' + month;\n newString += month;\n var day = '' + this.getDate();\n if (day.length == 1)\n day = '0' + day;\n newString += day;\n\n return newString;\n};\n\n// MMHH\nDate.prototype.getHourString = function() {\n var newString = this.getHours() + '00';\n if (newString.length == 3)\n newString = '0' + newString;\n\n return newString;\n};\n\n/* Functions */\n\nfunction l() {\n var key = arguments[0];\n var value = key;\n if (labels[key]) {\n value = labels[key];\n }\n else if (clabels[key]) {\n value = clabels[key];\n }\n for (var i = 1, j = 0; i < arguments.length; i++, j++) {\n value = value.replace('%{' + j + '}', arguments[i]);\n }\n\n return value;\n}\n\nfunction hexToRgb(hex) {\n var result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16)\n } : null;\n}\n\n// Respect contrast ratio recommendation from W3C:\n// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\nfunction contrast(hex) {\n var color, c, l = 1;\n\n color = hexToRgb(hex);\n if (color) {\n c = [color.r / 255, color.g / 255, color.b / 255];\n\n for (var i = 0; i < c.length; ++i) {\n if (c[i] <= 0.03928) {\n\tc[i] = c[i] / 12.92;\n }\n else {\n\tc[i] = Math.pow((c[i] + 0.055) / 1.055, 2.4);\n }\n }\n\n l = 0.2126 * c[0] + 0.7152 * c[1] + 0.0722 * c[2];\n }\n\n if (l > 0.179) {\n return 'black';\n }\n else {\n return 'white';\n }\n}\n\nfunction guid() {\n function S4() {\n return (((1+Math.random())*0x10000)|0).toString(16).substring(1); \n }\n \n return (S4() + S4() + \"-\" + S4() + \"-4\" + S4().substr(0,3) + \"-\" + S4() + \"-\" + S4() + S4() + S4()).toLowerCase();\n}\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n angular.module('SOGo.Common', ['ngAnimate', 'ngMaterial', 'mdColors'])\n .value('sgSettings', {\n isPopup: document.body.classList.contains('popup'),\n baseURL: function() {\n return ApplicationBaseURL || null;\n },\n activeUser: function(param) {\n var settings = {\n login: UserLogin || null,\n identification: UserIdentification || null,\n email: UserEmail || null,\n language: UserLanguage || null,\n folderURL: UserFolderURL || null,\n isSuperUser: IsSuperUser || null,\n path: {\n calendar: UserCalendarPath || null,\n contacts: UserContactsPath || null,\n mail: UserMailPath || null,\n preferences: UserPreferencesPath || null,\n administration: (IsSuperUser ? UserAdministrationPath : null),\n logoff: UserLogoffPath || null\n }\n };\n if (param)\n return settings[param];\n else\n return settings;\n }\n })\n\n .constant('sgColors', {\n selection: [\n '#FFFFFF',\n '#330033',\n '#C0C0C0',\n '#999999',\n '#666666',\n '#333333',\n '#000000',\n '#FFCCCC',\n '#FF6666',\n '#FF0000',\n '#CC0000',\n '#990000',\n '#660000',\n '#330000',\n '#FFCC99',\n '#FF9966',\n '#FF9900',\n '#FF6600',\n '#CC6600',\n '#993300',\n '#663300',\n '#FFFF99',\n '#FFFF66',\n '#FFCC66',\n '#FFCC33',\n '#CC9933',\n '#996633',\n '#663333',\n '#FFFFCC',\n '#FFFF33',\n '#FFFF00',\n '#FFCC00',\n '#999900',\n '#666600',\n '#333300',\n '#CCCCCC',\n '#66FF99',\n '#33FF33',\n '#33CC00',\n '#009900',\n '#006600',\n '#003300',\n '#99FFFF',\n '#33FFFF',\n '#66CCCC',\n '#00CCCC',\n '#339999',\n '#336666',\n '#003333',\n '#CCFFFF',\n '#66FFFF',\n '#33CCFF',\n '#3366FF',\n '#3333FF',\n '#000099',\n '#000066',\n '#CCCCFF',\n '#9999FF',\n '#6666CC',\n '#6633FF',\n '#6600CC',\n '#333399',\n '#330099',\n '#FFCCFF',\n '#FF99FF',\n '#CC66CC',\n '#CC33CC',\n '#993399',\n '#663366',\n '#99FF99'\n ]\n })\n\n // md break-points values are hard-coded in angular-material/src/core/util/constant.js\n // $mdMedia has a built-in support for those values but can also evaluate others\n .constant('sgConstant', {\n 'xs' : '(max-width: 599px)' ,\n 'gt-xs' : '(min-width: 600px)' ,\n 'sm' : '(min-width: 600px) and (max-width: 959px)' ,\n 'gt-sm' : '(min-width: 960px)' ,\n 'md' : '(min-width: 960px) and (max-width: 1279px)' ,\n 'gt-md' : '(min-width: 1280px)' ,\n 'lg' : '(min-width: 1280px) and (max-width: 1919px)',\n 'gt-lg' : '(min-width: 1920px)' ,\n 'xl' : '(min-width: 1920px)'\n })\n\n .config(configure)\n\n .factory('AuthInterceptor', AuthInterceptor)\n .factory('ErrorInterceptor', ErrorInterceptor);\n\n /**\n * @ngInject\n */\n configure.$inject = ['$logProvider', '$compileProvider', '$httpProvider', '$mdThemingProvider'];\n function configure($logProvider, $compileProvider, $httpProvider, $mdThemingProvider) {\n // Accent palette\n $mdThemingProvider.definePalette('sogo-green', {\n '50': 'eaf5e9',\n '100': 'cbe5c8',\n '200': 'aad6a5',\n '300': '88c781',\n '400': '66b86a',\n '500': '56b04c',\n '600': '4da143',\n '700': '388e3c',\n '800': '367d2e',\n '900': '225e1b',\n // 'A100': 'b9f6ca',\n 'A100': 'ffffff', // assigned to md-hue-1\n 'A200': '69f0ae',\n 'A400': '00e676',\n 'A700': '00c853',\n 'contrastDefaultColor': 'dark',\n // 'contrastDarkColors': ['50', '100', '200', 'A100'],\n 'contrastLightColors': ['300', '400', '500', '600', '700', '800', '900']\n });\n // Primary palette\n $mdThemingProvider.definePalette('sogo-blue', {\n '50': 'f0faf9',\n '100': 'e1f5f3',\n '200': 'ceebe8',\n '300': 'bfe0dd',\n '400': 'b2d6d3',\n '500': 'a1ccc8',\n '600': '8ebfbb',\n '700': '7db3b0',\n '800': '639997',\n '900': '4d8080',\n 'A100': 'd4f7fa',\n 'A200': 'c3f5fa',\n 'A400': '53e3f0',\n 'A700': '00b0c0',\n 'contrastDefaultColor': 'light',\n 'contrastDarkColors': ['50', '100', '200'],\n // 'contrastLightColors': ['300', '400', '500', '600', '700', '800', '900', 'A100', 'A200', 'A400', 'A700']\n });\n // Background palette\n $mdThemingProvider.definePalette('sogo-paper', {\n '50': 'fcf7f8',\n '100': 'f7f1dc',\n '200': 'ede5ca',\n '300': 'e6d8ba',\n '400': 'e2d2a3',\n '500': 'd6c48d',\n '600': 'baa870',\n '700': '857545',\n '800': '524517',\n '900': '433809',\n '1000': '000000',\n 'A100': 'ffffff',\n 'A200': 'eeeeee',\n 'A400': 'bdbdbd',\n 'A700': '616161',\n 'contrastDefaultColor': 'dark',\n 'contrastLightColors': ['800', '900']\n });\n // Default theme definition\n $mdThemingProvider.theme('default')\n .primaryPalette('sogo-blue', {\n 'default': '900',\n 'hue-1': '400',\n 'hue-2': '800',\n 'hue-3': 'A700'\n })\n .accentPalette('sogo-green', {\n 'default': '500',\n // 'hue-1': '200',\n 'hue-1': 'A100',\n 'hue-2': '300',\n 'hue-3': 'A700'\n })\n .backgroundPalette('grey', {\n 'default': 'A100',\n 'hue-1': '200',\n 'hue-2': '300',\n 'hue-3': '500'\n });\n\n if (!DebugEnabled) {\n // Disable debug data\n $logProvider.debugEnabled(false);\n $compileProvider.debugInfoEnabled(false);\n }\n\n $httpProvider.interceptors.push('AuthInterceptor');\n $httpProvider.interceptors.push('ErrorInterceptor');\n }\n\n AuthInterceptor.$inject = ['$window', '$q'];\n function AuthInterceptor($window, $q) {\n return {\n response: function(response) {\n // When expecting JSON but receiving HTML, assume session has expired and reload page\n if (/^application\\/json/.test(response.config.headers.Accept) &&\n /^<!DOCTYPE html>/.test(response.data)) {\n $window.location.reload(true);\n return $q.reject();\n }\n return response;\n }\n };\n }\n\n /**\n * @ngInject\n */\n ErrorInterceptor.$inject = ['$rootScope', '$q'];\n function ErrorInterceptor($rootScope, $q) {\n return {\n responseError: function(rejection) {\n // Broadcast the response error\n $rootScope.$broadcast('http:Error', rejection);\n return $q.reject(rejection);\n }\n };\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/*\n * https://github.com/angular/material/issues/1269\n * https://gist.github.com/senthilprabhut/dd2147ebabc89bf223e7\n */\n\n(function() {\n 'use strict';\n\n var _$mdThemingProvider;\n\n angular\n .module('mdColors', ['ngMaterial'])\n .config(configure)\n .run(runBlock);\n\n /**\n * @ngInject\n */\n configure.$inject = ['$mdThemingProvider'];\n function configure($mdThemingProvider) {\n _$mdThemingProvider = $mdThemingProvider;\n }\n \n /**\n * @ngInject\n */\n runBlock.$inject = ['$interpolate', '$document', '$log'];\n function runBlock($interpolate, $document, $log) {\n\n function buildCssSelectors(selectors) {\n var result = selectors.join('');\n return result;\n }\n\n var fgDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-fg']) + ' { color:{{value}};}'),\n bgDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-bg']) + ' { background-color:{{value}};}'),\n bdrDefault = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-bdr']) + ' { border-color:{{value}};}'),\n fgDefaultHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{hue}}','.md-fg']) + ' { color:{{value}};}'),\n bgDefaultHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{hue}}','.md-bg']) + ' { background-color:{{value}};}'),\n fgColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-fg']) + ' { color:{{value}};}'),\n bgColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-bg']) + ' { background-color:{{value}}; color:{{contrast}}; }'),\n bdrColor = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}','.md-bdr']) + ' { border-color:{{value}};}'),\n fgHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}.md-{{hue}}','.md-fg']) + ' { color:{{value}};}'),\n bgHue = $interpolate(buildCssSelectors(['.md-{{theme}}-theme','.md-{{palette}}.md-{{hue}}','.md-bg']) + ' { background-color:{{value}};}'),\n customSheet = getStyleSheet(),\n index = 0;\n\n // Clear out old rules from stylesheet\n while (customSheet.cssRules.length > 0 ) {\n customSheet.deleteRule(0);\n }\n angular.forEach(_$mdThemingProvider._THEMES, function(theme, themeName){\n // Add default selectors - primary is the default palette\n addRule(fgDefault, bgDefault, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues.default]);\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-2'] ], 'hue-2');\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-3'] ], 'hue-3');\n addRule(fgDefaultHue, bgDefaultHue, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues['hue-1'] ], 'hue-1');\n addBorderRule(bdrDefault, themeName, 'primary',\n _$mdThemingProvider._PALETTES[theme.colors.primary.name][theme.colors.primary.hues.default]);\n\n // Add selectors for palettes - accent, background, primary and warn\n angular.forEach(theme.colors, function(color, paletteName){\n addRule(fgColor, bgColor, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues.default]);\n addBorderRule(bdrColor, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues.default]);\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-2'] ], 'hue-2');\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-3'] ], 'hue-3');\n addRule(fgHue, bgHue, themeName, paletteName, _$mdThemingProvider._PALETTES[color.name][color.hues['hue-1'] ], 'hue-1');\n });\n\n //$log.debug(_.pluck(customSheet.cssRules, 'cssText').join(\"\\n\"));\n });\n\n function addRule(fgInterpolate, bgInterpolate, themeName, paletteName, colorArray, hueName){\n // Set up interpolation functions to build css rules.\n if (!colorArray) return;\n var colorValue = 'rgb(' + colorArray.value[0] + ',' + colorArray.value[1] + ',' + colorArray.value[2] + ')',\n colorContrast = 'rgb(' + colorArray.contrast[0] + ',' + colorArray.contrast[1] + ',' + colorArray.contrast[2] + ')',\n context = {\n theme: themeName,\n palette: paletteName,\n value: colorValue,\n contrast: colorContrast,\n hue: hueName\n };\n\n // Insert foreground color rule\n customSheet.insertRule(fgInterpolate(context), index);\n index += 1;\n\n // Insert background color rule\n customSheet.insertRule(bgInterpolate(context), index);\n index += 1;\n }\n\n function addBorderRule(bdrInterpolate, themeName, paletteName, colorArray, hueName){\n // Set up interpolation functions to build css rule for border color.\n if (!colorArray) return;\n var colorValue = 'rgb(' + colorArray.value[0] + ',' + colorArray.value[1] + ',' + colorArray.value[2] + ')';\n\n customSheet.insertRule(bdrInterpolate({\n theme: themeName,\n palette: paletteName,\n value: colorValue,\n hue: hueName\n }), index);\n index += 1;\n }\n\n function getStyleSheet() {\n // function to add a dynamic style-sheet to the document\n var style = $document[0].head.querySelector('style[title=\"Dynamic-Generated-by-mdColors\"]');\n if (style === null) {\n style = $document[0].createElement('style');\n style.title = 'Dynamic-Generated-by-mdColors';\n // WebKit hack... (not sure if still needed)\n style.appendChild($document[0].createTextNode(''));\n $document[0].head.appendChild(style);\n }\n return style.sheet;\n }\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n decodeUri.$inject = ['$window'];\n function decodeUri($window) {\n return $window.decodeURIComponent;\n }\n\n angular.module('SOGo.Common')\n .filter('decodeUri', decodeUri);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n encodeUri.$inject = ['$window'];\n function encodeUri($window) {\n return $window.encodeURIComponent;\n }\n\n angular.module('SOGo.Common')\n .filter('encodeUri', encodeUri);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function () {\n 'use strict';\n\n /**\n * ensureTarget - A filter to set a blank target to all links.\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <div ng-bind-html=\"part.content | ensureTarget\"><!-- msg --></div>\n */\n ensureTarget.$inject = ['$sce'];\n function ensureTarget($sce) {\n return function(element) {\n var tree = angular.element('<div>' + element + '</div>');\n tree.find('a').attr('target', '_blank');\n return $sce.trustAs('html', tree.html());\n };\n }\n\n angular.module('SOGo.Common')\n .filter('ensureTarget', ensureTarget);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * loc - A simple filter to return the localized version of a string.\n * @memberof SOGo.Common\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n function loc() {\n return l;\n }\n\n angular.module('SOGo.Common')\n .filter('loc', loc);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * range - A simple filter that will return an array of the size of its argument.\n * @memberof SOGo.Common\n */\n(function () {\n 'use strict';\n\n function range() {\n return function(n) {\n var res = [];\n for (var i = 0; i < parseInt(n); i++) {\n res.push(i);\n }\n return res;\n };\n }\n\n angular.module('SOGo.Common')\n .filter('range', range);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @ngInject\n */\n AclController.$inject = ['$mdDialog', 'Dialog', 'usersWithACL', 'User', 'folder'];\n function AclController($mdDialog, Dialog, usersWithACL, User, folder) {\n var vm = this;\n\n vm.users = usersWithACL; // ACL users\n vm.folder = folder;\n vm.selectedUser = null;\n vm.selectedUid = null;\n vm.userToAdd = '';\n vm.searchText = '';\n vm.userFilter = userFilter;\n vm.closeModal = closeModal;\n vm.saveModal = saveModal;\n vm.confirmChange = confirmChange;\n vm.removeUser = removeUser;\n vm.addUser = addUser;\n vm.selectUser = selectUser;\n vm.confirmation = { showing: false,\n message: ''};\n\n function userFilter($query) {\n return User.$filter($query, folder.$acl.users);\n }\n\n function closeModal() {\n folder.$acl.$resetUsersRights(); // cancel changes\n $mdDialog.hide();\n }\n\n function saveModal() {\n folder.$acl.$saveUsersRights().then(function() {\n $mdDialog.hide();\n }, function(data, status) {\n Dialog.alert(l('Warning'), l('An error occured please try again.'));\n });\n }\n\n function confirmChange(user) {\n var confirmation = user.$confirmRights();\n if (confirmation) {\n vm.confirmation.showing = true;\n vm.confirmation.message = confirmation;\n }\n }\n\n function removeUser(user) {\n folder.$acl.$removeUser(user.uid).catch(function(data, status) {\n Dialog.alert(l('Warning'), l('An error occured please try again.'));\n });\n }\n\n function addUser(data) {\n if (data) {\n folder.$acl.$addUser(data).then(function(user) {\n vm.userToAdd = '';\n vm.searchText = '';\n vm.selectedUid = null;\n if (user)\n selectUser(user);\n }, function(error) {\n Dialog.alert(l('Warning'), error);\n });\n }\n }\n\n function selectUser(user) {\n if (vm.selectedUid == user.uid) {\n vm.selectedUid = null;\n }\n else {\n vm.selectedUid = user.uid;\n vm.selectedUser = user;\n vm.selectedUser.$rights();\n }\n }\n }\n\n angular\n .module('SOGo.Common')\n .controller('AclController', AclController);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n/**\n * @type {angular.Module}\n */\n(function () {\n 'use strict';\n\n /**\n * @ngInject\n */\n navController.$inject = ['$rootScope', '$scope', '$timeout', '$interval', '$http', '$mdSidenav', '$mdToast', '$mdMedia', '$log', 'sgConstant', 'sgSettings', 'Alarm'];\n function navController($rootScope, $scope, $timeout, $interval, $http, $mdSidenav, $mdToast, $mdMedia, $log, sgConstant, sgSettings, Alarm) {\n\n $scope.isPopup = sgSettings.isPopup;\n $scope.activeUser = sgSettings.activeUser();\n $scope.baseURL = sgSettings.baseURL();\n $scope.leftIsClose = $mdMedia(sgConstant.xs);\n\n // Show current day in top bar\n $scope.currentDay = window.currentDay;\n $timeout(function() {\n // Update date when day ends\n $interval(function() {\n $http.get('../date').success(function(data) {\n $scope.currentDay = data;\n });\n }, 24 * 3600 * 1000);\n }, window.currentDay.secondsBeforeTomorrow * 1000);\n\n $scope.toggleLeft = function() {\n $scope.leftIsClose = leftIsClose();\n $mdSidenav('left').toggle()\n .then(function () {\n $log.debug(\"toggle left is done\");\n });\n };\n $scope.toggleRight = function() {\n $mdSidenav('right').toggle()\n .then(function () {\n $log.debug(\"toggle right is done\");\n });\n };\n // $scope.openBottomSheet = function() {\n // $mdBottomSheet.show({\n // parent: angular.element(document.getElementById('left-sidenav')),\n // templateUrl: 'bottomSheetTemplate.html'\n // });\n // };\n // $scope.toggleDetailView = function() {\n // var detail = angular.element(document.getElementById('detailView'));\n // detail.toggleClass('sg-close');\n // };\n $scope.$watch(function() {\n return $mdMedia(sgConstant['gt-sm']);\n }, function(newVal) {\n $scope.isGtMedium = newVal;\n if (newVal) {\n $scope.leftIsClose = false;\n }\n });\n\n function leftIsClose() {\n return !$mdSidenav('left').isOpen();\n }\n\n function onHttpError(event, response) {\n var message;\n if (response.data.message)\n message = response.data.message;\n else\n message = response.statusText;\n\n $mdToast.show({\n template: [\n '<md-toast>',\n ' <div class=\"md-toast-content\">',\n ' <md-icon class=\"md-warn md-hue-1\">error_outline</md-icon>',\n ' <span flex>' + l(message) + '</span>',\n ' </div>',\n '</md-toast>'\n ].join(''),\n hideDelay: 5000,\n position: 'top right'\n });\n }\n\n // Listen to HTTP errors broadcasted from HTTP interceptor\n $rootScope.$on('http:Error', onHttpError);\n\n Alarm.getAlarms();\n }\n\n angular.module('SOGo.Common')\n .controller('navController', navController);\n})();\n","(function() {\n 'use strict';\n\n /**\n * @name Acl\n * @constructor\n * @param {String} folderId - the folder ID associated to the ACLs\n */\n function Acl(folderId) {\n this.folderId = folderId;\n }\n\n /**\n * @memberof Acl\n * @desc The factory we'll use to register with Angular.\n * @return the Acl constructor\n */\n Acl.factory = ['$q', '$timeout', 'sgSettings', 'Resource', 'User', function($q, $timeout, Settings, Resource, User) {\n angular.extend(Acl, {\n $q: $q,\n $timeout: $timeout,\n $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()),\n $User: User\n });\n\n return Acl;\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of User in Angular module.\n */\n angular.module('SOGo.Common').factory('Acl', Acl.factory);\n\n /**\n * @function $users\n * @memberof Acl.prototype\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @desc Fetch the list of users that have specific rights for the current folder.\n * @return a promise of an array of User objects\n */\n Acl.prototype.$users = function(owner) {\n var _this = this,\n deferred = Acl.$q.defer(),\n user;\n if (this.users) {\n deferred.resolve(this.users);\n }\n else {\n var acls;\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'acls');\n else\n acls = Acl.$$resource.fetch(this.folderId, 'acls');\n\n return acls.then(function(response) {\n _this.users = [];\n //console.debug(JSON.stringify(users, undefined, 2));\n angular.forEach(response.users, function(data) {\n user = new Acl.$User(data);\n user.canSubscribeUser = user.isSubscribed;\n user.wasSubscribed = user.isSubscribed;\n user.$rights = angular.bind(user, user.$acl, _this.folderId, owner);\n _this.users.push(user);\n });\n deferred.resolve(_this.users);\n return _this.users;\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $addUser\n * @memberof Acl.prototype\n * @param {Object} user - a User object with minimal set of attributes (uid, isGroup, cn, c_email)\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @see {@link User.$filter}\n */\n Acl.prototype.$addUser = function(user, owner) {\n var _this = this,\n deferred = Acl.$q.defer(),\n param = {uid: user.uid};\n if (!user.uid || _.indexOf(_.pluck(this.users, 'uid'), user.uid) > -1) {\n // No UID specified or user already in ACLs\n deferred.resolve();\n }\n else {\n var acls;\n\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'addUserInAcls', param);\n else\n acls = Acl.$$resource.fetch(this.folderId, 'addUserInAcls', param);\n\n acls.then(function() {\n user.wasSubscribed = false;\n user.userClass = user.isGroup ? 'normal-group' : 'normal-user';\n user.$rights = angular.bind(user, user.$acl, _this.folderId);\n _this.users.push(user);\n deferred.resolve(user);\n }, function(data, status) {\n deferred.reject(l('An error occured please try again.'));\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $removeUser\n * @memberof Acl.prototype\n * @desc Remove a user from the folder's ACL\n * @return a promise of the server call to remove the user from the folder's ACL\n */\n Acl.prototype.$removeUser = function(uid) {\n var _this = this,\n param = {uid: uid};\n return Acl.$$resource.fetch(this.folderId, 'removeUserFromAcls', param).then(function() {\n var i = _.indexOf(_.pluck(_this.users, 'uid'), uid);\n if (i >= 0) {\n _this.users.splice(i, 1);\n }\n });\n };\n\n /**\n * @function $resetUsersRights\n * @memberof Acl.prototype\n * @desc Restore initial rights of all users.\n */\n Acl.prototype.$resetUsersRights = function() {\n angular.forEach(this.users, function(user) {\n user.$resetRights();\n });\n };\n\n /**\n * @function $saveUsersRights\n * @memberof Acl.prototype\n * @desc Save user rights that have changed and subscribe users that have been selected.\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @return a promise that resolved only if the modifications and subscriptions were successful\n */\n Acl.prototype.$saveUsersRights = function(owner) {\n var _this = this,\n deferredSave = Acl.$q.defer(),\n deferredSubscribe = Acl.$q.defer(),\n param = {action: 'saveUserRights'},\n users = [];\n\n // Save user rights\n angular.forEach(this.users, function(user) {\n if (user.$rightsAreDirty()) {\n users.push(user.$omit());\n // console.debug('save ' + JSON.stringify(user.$omit(), undefined, 2));\n }\n });\n if (users.length) {\n var acls;\n\n if (angular.isDefined(owner))\n acls = Acl.$$resource.userResource(owner).save(this.folderId, users, param);\n else\n acls = Acl.$$resource.save(this.folderId, users, param);\n\n acls.then(function() {\n // Save was successful; copy rights to shadow rights\n angular.forEach(_this.users, function(user) {\n if (user.$rightsAreDirty()) {\n user.$shadowRights = angular.copy(user.rights);\n }\n });\n deferredSave.resolve();\n }, deferredSave.reject);\n }\n else {\n deferredSave.resolve();\n }\n\n // Subscribe users\n users = [];\n angular.forEach(this.users, function(user) {\n if (!user.wasSubscribed && user.isSubscribed) {\n users.push(user.uid);\n // console.debug('subscribe ' + user.uid);\n }\n });\n if (users.length) {\n param = {uids: users.join(',')};\n Acl.$$resource.fetch(this.folderId, 'subscribeUsers', param)\n .then(function() {\n // Subscribe was successful; reset \"wasSubscribed\" attribute\n angular.forEach(_this.users, function(user) {\n user.wasSubscribed = user.isSubscribed;\n });\n deferredSubscribe.resolve();\n }, deferredSubscribe.reject);\n }\n else {\n deferredSubscribe.resolve();\n }\n return Acl.$q.all([deferredSave.promise, deferredSubscribe.promise]);\n };\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Alarm\n * @constructor\n */\n function Alarm() {\n this.currentAlarm = null;\n }\n\n /**\n * @name getAlarms\n * @desc Fetch the list of alarms from the server and use the last one\n */\n Alarm.getAlarms = function() {\n var _this = this;\n var now = new Date();\n var browserTime = Math.floor(now.getTime()/1000);\n\n this.$$resource.fetch('', 'alarmslist?browserTime=' + browserTime).then(function(data) {\n \n var alarms = data.alarms.sort(function reverseSortByAlarmTime(a, b) {\n var x = parseInt(a[2]);\n var y = parseInt(b[2]);\n return (y - x);\n });\n\n if (alarms.length > 0) {\n var next = alarms.pop();\n var now = new Date();\n var utc = Math.floor(now.getTime()/1000);\n var url = next[0] + '/' + next[1];\n var alarmTime = parseInt(next[2]);\n var delay = alarmTime;\n if (alarmTime > 0) delay -= utc;\n var d = new Date(alarmTime*1000);\n //console.log (\"now = \" + now.toUTCString());\n //console.log (\"next event \" + url + \" in \" + delay + \" seconds (on \" + d.toUTCString() + \")\");\n\n var f = angular.bind(_this, Alarm.showAlarm, url);\n\n if (_this.currentAlarm)\n _this.$timeout.cancel(_this.currentAlarm);\n\n _this.currentAlarm = _this.$timeout(f, delay*1000);\n }\n });\n };\n \n /**\n * @name showAlarm\n * @desc Show the latest alarm using a toast\n * @param url The URL of the calendar component for snoozing\n */\n Alarm.showAlarm = function(url) {\n var _this = this;\n\n this.$$resource.fetch(url, '?resetAlarm=yes').then(function(data) {\n _this.$toast.show({\n position: 'top right',\n hideDelay: 0,\n template: [\n '<md-toast>',\n ' <div class=\"md-toast-content\">',\n ' <md-input-container>',\n ' <label style=\"color: white;\">' + data.summary + '</label>',\n ' <md-select ng-model=\"reminder\">',\n ' <md-option value=5>',\n l('5 minutes'),\n ' </md-option>',\n ' <md-option value=10>',\n l('10 minutes'),\n ' </md-option>',\n ' <md-option value=15>',\n l('15 minutes'),\n ' </md-option>',\n ' <md-option value=30>',\n l('30 minutes'),\n ' </md-option>',\n ' <md-option value=45>',\n l('45 minutes'),\n ' </md-option>',\n ' <md-option value=60>',\n l('1 hour'),\n ' </md-option>',\n ' <md-option value=1440>',\n l('1 day'),\n ' </md-option>',\n ' </md-select>',\n ' </md-input-container>',\n ' <md-button ng-click=\"cancel()\">',\n l('Cancel'),\n ' </md-button>',\n ' <md-button ng-click=\"ok()\">',\n l('Ok'),\n ' </md-button>',\n ' </div>',\n '</md-toast>'\n ].join(''),\n locals: {\n url: url\n },\n controller: AlarmController\n });\n\n /**\n * @ngInject\n */\n AlarmController.$inject = ['scope', '$mdToast', 'url'];\n function AlarmController(scope, $mdToast, url) {\n scope.reminder = '10';\n scope.cancel = function() {\n $mdToast.hide();\n };\n scope.ok = function() {\n _this.$$resource.fetch(url, 'view?snoozeAlarm=' + scope.reminder);\n $mdToast.hide();\n };\n }\n });\n };\n\n /**\n * @memberof Alarm\n * @desc The factory we'll register as Alarm in the Angular module SOGo.Common\n * @ngInject\n */\n AlarmService.$inject = ['$timeout', 'sgSettings', 'Resource', '$mdToast'];\n function AlarmService($timeout, Settings, Resource, $mdToast) {\n angular.extend(Alarm, {\n $timeout: $timeout,\n $$resource: new Resource(Settings.activeUser('folderURL') + 'Calendar', Settings.activeUser()),\n $toast: $mdToast\n });\n\n return Alarm; // return constructor\n }\n\n /* Factory registration in Angular module */\n angular\n .module('SOGo.Common')\n .factory('Alarm', AlarmService);\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n/* JavaScript for Authentication */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n angular.module('SOGo.Authentication', [])\n\n .constant('passwordPolicyConfig', {\n PolicyPasswordChangeUnsupported: -3,\n PolicyPasswordSystemUnknown: -2,\n PolicyPasswordUnknown: -1,\n PolicyPasswordExpired: 0,\n PolicyAccountLocked: 1,\n PolicyChangeAfterReset: 2,\n PolicyPasswordModNotAllowed: 3,\n PolicyMustSupplyOldPassword: 4,\n PolicyInsufficientPasswordQuality: 5,\n PolicyPasswordTooShort: 6,\n PolicyPasswordTooYoung: 7,\n PolicyPasswordInHistory: 8,\n PolicyNoError: 65535\n })\n\n // TODO: convert to a Factory recipe?\n .provider('Authentication', Authentication);\n\n function Authentication() {\n function readCookie(name) {\n var foundCookie, prefix, pairs, i, currentPair, start;\n foundCookie = null;\n prefix = name + '=';\n pairs = document.cookie.split(';');\n for (i = 0; !foundCookie && i < pairs.length; i++) {\n currentPair = pairs[i];\n start = 0;\n while (currentPair.charAt(start) == ' ')\n start++;\n if (start > 0)\n currentPair = currentPair.substr(start);\n if (currentPair.indexOf(prefix) === 0)\n foundCookie = currentPair.substr(prefix.length);\n }\n\n return foundCookie;\n }\n\n function readLoginCookie() {\n var loginValues = null,\n cookie = readCookie('0xHIGHFLYxSOGo'),\n value;\n if (cookie && cookie.length > 8) {\n value = decodeURIComponent(cookie.substr(8));\n loginValues = value.base64decode().split(':');\n }\n\n return loginValues;\n }\n\n function redirectUrl(username, domain) {\n var userName, address, baseAddress, altBaseAddress, parts, hostpart, protocol, newAddress;\n\n userName = username;\n if (domain)\n userName += '@' + domain.value;\n address = '' + window.location.href;\n baseAddress = ApplicationBaseURL + '/' + encodeURIComponent(userName);\n if (baseAddress[0] == '/') {\n parts = address.split('/');\n hostpart = parts[2];\n protocol = parts[0];\n baseAddress = protocol + '//' + hostpart + baseAddress;\n }\n parts = baseAddress.split('/');\n parts.splice(0, 3);\n altBaseAddress = parts.join('/');\n if ((address.startsWith(baseAddress) || address.startsWith(altBaseAddress)) &&\n !address.endsWith('/logoff')) {\n newAddress = address;\n }\n else {\n newAddress = baseAddress;\n }\n\n return newAddress;\n }\n\n this.$get = getService;\n\n /**\n * @ngInject\n */\n getService.$inject = ['$q', '$http', 'passwordPolicyConfig'];\n function getService($q, $http, passwordPolicyConfig) {\n var _this = this, service;\n\n service = {\n login: function(data) {\n var d = $q.defer(),\n username = data.username,\n password = data.password,\n domain = data.domain,\n language,\n rememberLogin = data.rememberLogin ? 1 : 0;\n\n if (data.loginSuffix && !username.endsWith(data.loginSuffix)) {\n username += loginSuffix;\n domain = false;\n }\n if (data.language && data.language != 'WONoSelectionString') {\n language = data.language;\n }\n\n $http({\n method: 'POST',\n url: '/SOGo/connect',\n data: {\n userName: username,\n password: password,\n domain: domain,\n language: language,\n rememberLogin: rememberLogin\n }\n }).success(function(data, status) {\n // Make sure browser's cookies are enabled\n var loginCookie = readLoginCookie();\n if (!loginCookie) {\n d.reject(l('cookiesNotEnabled'));\n }\n else {\n // Check password policy\n if (typeof data.expire != 'undefined' && typeof data.grace != 'undefined') {\n if (data.expire < 0 && data.grace > 0) {\n d.reject({grace: data.grace});\n //showPasswordDialog('grace', createPasswordGraceDialog, data['grace']);\n } else if (data.expire > 0 && data.grace == -1) {\n d.reject({expire: data.expire});\n //showPasswordDialog('expiration', createPasswordExpirationDialog, data['expire']);\n }\n else {\n d.resolve(redirectUrl(username, domain));\n }\n }\n else {\n d.resolve(redirectUrl(username, domain));\n }\n }\n }).error(function(data, status) {\n var msg, perr;\n if (data && data.LDAPPasswordPolicyError) {\n perr = data.LDAPPasswordPolicyError;\n if (perr == passwordPolicyConfig.PolicyNoError) {\n msg = l('Wrong username or password.');\n }\n else if (perr == passwordPolicyConfig.PolicyAccountLocked) {\n msg = l('Your account was locked due to too many failed attempts.');\n }\n else {\n msg = l('Login failed due to unhandled error case: ') + perr;\n }\n }\n else {\n msg = l('Unhandled error response');\n }\n d.reject({error: msg});\n });\n return d.promise;\n }, // login: function(data) { ...\n\n changePassword: function(newPassword) {\n var d = $q.defer(),\n loginCookie = _this.readLoginCookie();\n\n $http({\n method: 'POST',\n url: '/SOGo/so/changePassword',\n data: {\n userName: loginCookie[0],\n password: loginCookie[1],\n newPassword: newPassword }\n }).success(function(data, status) {\n d.resolve();\n }).error(function(data, status) {\n var error,\n perr = data.LDAPPasswordPolicyError;\n\n if (!perr) {\n perr = passwordPolicyConfig.PolicyPasswordSystemUnknown;\n error = _(\"Unhandled error response\");\n }\n else if (perr == passwordPolicyConfig.PolicyNoError) {\n error = l(\"Password change failed\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordModNotAllowed) {\n error = l(\"Password change failed - Permission denied\");\n } else if (perr == passwordPolicyConfig.PolicyInsufficientPasswordQuality) {\n error = l(\"Password change failed - Insufficient password quality\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordTooShort) {\n error = l(\"Password change failed - Password is too short\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordTooYoung) {\n error = l(\"Password change failed - Password is too young\");\n } else if (perr == passwordPolicyConfig.PolicyPasswordInHistory) {\n error = l(\"Password change failed - Password is in history\");\n } else {\n error = l(\"Unhandled policy error: %{0}\").formatted(perr);\n perr = passwordPolicyConfig.PolicyPasswordUnknown;\n }\n\n d.reject(error);\n });\n return d.promise;\n }\n };\n return service;\n }\n }\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Dialog\n * @constructor\n */\n function Dialog() {\n }\n\n /**\n * @name alert\n * @desc Show an alert dialog box with a single \"OK\" button\n * @param {string} title\n * @param {string} content\n */\n Dialog.alert = function(title, content) {\n var alert = this.$modal.alert()\n .title(title)\n .textContent(content)\n .ok(l('OK'));\n this.$modal.show(alert);\n };\n\n /**\n * @name confirm\n * @desc Show a confirmation dialog box with buttons 'Cancel' and 'OK'\n * @param {string} title\n * @param {string} content\n * @returns a promise that resolves if the user has clicked on the 'OK' button\n */\n Dialog.confirm = function(title, content, options) {\n var confirm = this.$modal.confirm()\n .title(title)\n .textContent(content)\n .ok((options && options.ok)? options.ok : l('OK'))\n .cancel((options && options.cancel)? options.cancel : l('Cancel'));\n return this.$modal.show(confirm);\n };\n\n /**\n * @name prompt\n * @desc Show a primpt dialog box with a input text field and the 'Cancel' and 'OK' buttons\n * @param {string} title\n * @param {string} label\n * @param {object} [options] - use a different input type by setting 'inputType'\n * @returns a promise that resolves with the input field value\n */\n Dialog.prompt = function(title, label, options) {\n var o = options || {},\n d = this.$q.defer();\n\n this.$modal.show({\n parent: angular.element(document.body),\n clickOutsideToClose: true,\n escapeToClose: true,\n template: [\n '<md-dialog flex=\"50\" flex-sm=\"100\">',\n ' <md-dialog-content class=\"md-dialog-content\" layout=\"column\">',\n ' <h2 class=\"md-title\" ng-bind=\"title\"></h2>',\n ' <md-input-container>',\n ' <label>' + label + '</label>',\n ' <input type=\"' + (o.inputType || 'text') + '\"',\n ' aria-label=\"' + title + '\"',\n ' ng-model=\"name\" required=\"required\"/>',\n ' </md-input-container>',\n ' </md-dialog-content>',\n ' <md-dialog-actions>',\n ' <md-button ng-click=\"cancel()\">',\n ' ' + l('Cancel'),\n ' </md-button>',\n ' <md-button class=\"md-primary\" ng-click=\"ok()\" ng-disabled=\"!name.length\">',\n ' ' + l('OK'),\n ' </md-button>',\n ' </md-dialog-actions>',\n '</md-dialog>'\n ].join(''),\n controller: PromptDialogController\n });\n\n /**\n * @ngInject\n */\n PromptDialogController.$inject = ['scope', '$mdDialog'];\n function PromptDialogController(scope, $mdDialog) {\n scope.title = title;\n scope.name = \"\";\n scope.cancel = function() {\n d.reject();\n $mdDialog.hide();\n };\n scope.ok = function() {\n d.resolve(scope.name);\n $mdDialog.hide();\n };\n }\n\n return d.promise;\n };\n\n /**\n * @memberof Dialog\n * @desc The factory we'll register as Dialog in the Angular module SOGo.Common\n * @ngInject\n */\n DialogService.$inject = ['$q', '$mdDialog'];\n function DialogService($q, $mdDialog) {\n angular.extend(Dialog, { $q: $q , $modal: $mdDialog });\n\n return Dialog; // return constructor\n }\n\n /* Factory registration in Angular module */\n angular\n .module('SOGo.Common')\n .factory('Dialog', DialogService);\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * Gravatar - A service to build the Gravatar URL for an email address\n * @memberof SOGo.Common\n * @param {string} email\n * @param {number} [size] - the size of the image\n * @param {string} alternate avatar to use\n * @ngInject\n */\n function Gravatar() {\n return function(email, size, alternate_avatar) {\n var x, y, hash, s = size;\n if (!email) {\n return '';\n }\n x = email.indexOf('<');\n if (x >= 0) {\n y = email.indexOf('>', x);\n if (y > x)\n email = email.substring(x+1,y);\n }\n if (!size) {\n s = 48; // default to 48 pixels\n }\n hash = email.md5();\n\n if (alternate_avatar == \"none\")\n alternate_avatar = \"404\";\n\n return 'https://www.gravatar.com/avatar/' + hash + '?s=' + s + '&d=' + alternate_avatar;\n };\n }\n\n angular\n .module('SOGo.Common')\n .factory('Gravatar', Gravatar);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * @name Resource\n * @constructor\n * @param {Object} $http - the Angular HTTP service\n * @param {Object} $q - the Angular promise/deferred service\n * @param {String} path - the base path of the external resource\n * @param {Object} options - extra attributes to be associated to the object\n */\n function Resource($http, $q, path, activeUser, options) {\n angular.extend(this, {\n _http: $http,\n _q: $q,\n _path: path,\n _activeUser: activeUser\n });\n angular.extend(this, options);\n // Trim trailing slash\n this._path = this._path.replace(/\\/$/, '');\n }\n\n /**\n * @memberof Resource\n * @desc The factory we'll use to register with Angular.\n * @return a new Resource object\n */\n Resource.$factory = ['$http', '$q', function($http, $q) {\n return function(path, activeUser, options) {\n return new Resource($http, $q, path, activeUser, options);\n };\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of Resource in Angular module.\n */\n angular.module('SOGo.Common').factory('Resource', Resource.$factory);\n\n /**\n * @function userResource\n * @memberof Resource.prototype\n * @desc Create a new Resource object associated to a username different than the active user.\n * @param {String} uid - the user UID\n * @return a new Resource object\n */\n Resource.prototype.userResource = function(uid) {\n var path = _.compact(this._activeUser.folderURL.split('/'));\n path.splice(path.length - 1, 1, escape(uid));\n\n return new Resource(this._http, this._q, '/' + path.join('/'), this._activeUser);\n };\n\n /**\n * @function fetch\n * @memberof Resource.prototype\n * @desc Fetch resource using a specific folder, action and/or parameters.\n * @param {string} folderId - the folder on which the action will be applied (ex: addressbook, calendar)\n * @param {string} action - the action to be used in the URL\n * @param {Object} params - Object parameters injected through the $http service\n * @return a promise\n */\n Resource.prototype.fetch = function(folderId, action, params) {\n var deferred = this._q.defer(),\n path = [this._path];\n if (folderId) path.push(folderId.split('/'));\n if (action) path.push(action);\n path = _.compact(_.flatten(path)).join('/');\n\n this._http({\n method: 'GET',\n url: path,\n params: params\n })\n .success(deferred.resolve)\n .error(function(data, status) {\n if (status == 404)\n return deferred.reject();\n });\n\n return deferred.promise;\n };\n\n /**\n * @function newguid\n * @memberof Resource.prototype\n * @desc Fetch a new GUID on the specified folder ID.\n * @return a promise of the new data structure\n */\n Resource.prototype.newguid = function(folderId) {\n var deferred = this._q.defer(),\n path = this._path + '/' + folderId + '/newguid';\n\n this._http\n .get(path)\n .success(deferred.resolve)\n .error(deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function create\n * @memberof Resource.prototype\n * @desc Create a new resource using a specific action (post).\n * @param {string} action - the action to be used in the URL\n * @param {string} name - the new resource's name\n * @return a promise\n */\n Resource.prototype.create = function(action, name) {\n var deferred = this._q.defer(),\n path = this._path + '/' + action;\n\n this._http\n .post(path, { name: name })\n .success(deferred.resolve)\n .error(deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function post\n * @memberof Resource.prototype\n * @desc Post a resource attributes on the server.\n * @return a promise\n */\n Resource.prototype.post = function(id, action, data) {\n var deferred = this._q.defer(),\n path = [this._path];\n if (id) path.push(id);\n if (action) path.push(action);\n path = _.compact(_.flatten(path)).join('/');\n\n this._http\n .post(path, data)\n .success(deferred.resolve)\n .error(deferred.reject);\n\n return deferred.promise;\n };\n\n /**\n * @function save\n * @memberof Resource.prototype\n * @desc Save a resource attributes on the server (post /save).\n * @return a promise\n */\n Resource.prototype.save = function(id, newValue, options) {\n var deferred = this._q.defer(),\n action = (options && options.action)? options.action : 'save';\n\n return this.post(id, action, newValue);\n };\n\n /**\n * @function remove\n * @memberof Resource.prototype\n * @desc Delete a resource (get /delete).\n * @return a promise\n */\n Resource.prototype.remove = function(uid) {\n var deferred = this._q.defer(),\n path = this._path + '/' + uid + '/delete';\n\n this._http\n .get(path)\n .success(deferred.resolve)\n .error(deferred.reject);\n\n return deferred.promise;\n };\n\n})();\n","(function() {\n 'use strict';\n\n /**\n * @name User\n * @constructor\n * @param {object} [userData] - some default values for the user\n */\n function User(userData) {\n if (userData) {\n this.init(userData);\n }\n }\n\n /**\n * @memberof User\n * @desc The factory we'll use to register with Angular.\n * @return the User constructor\n */\n User.factory = ['$q', '$log', 'sgSettings', 'Resource', 'Gravatar', function($q, $log, Settings, Resource, Gravatar) {\n angular.extend(User, {\n $q: $q,\n $log: $log,\n $$resource: new Resource(Settings.activeUser('folderURL'), Settings.activeUser()),\n $gravatar: Gravatar,\n $query: '',\n $users: []\n });\n\n return User;\n }];\n\n /**\n * @module SOGo.Common\n * @desc Factory registration of User in Angular module.\n */\n angular.module('SOGo.Common').factory('User', User.factory);\n\n /**\n * @memberof User\n * @desc Search for users that match a string.\n * @param {string} search - a string used to performed the search\n * @param {object[]} excludedUsers - a list of User objects that must be excluded from the results\n * @return a promise of an array of matching User objects\n */\n User.$filter = function(search, excludedUsers, options) {\n var _this = this, param = {search: search};\n\n if (!options || !options.dry) {\n if (!search) {\n // No query specified\n User.$users.splice(0, User.$users.length);\n return User.$q.when(User.$users);\n }\n if (User.$query == search) {\n // Query hasn't changed\n return User.$q.when(User.$users);\n }\n User.$query = search;\n }\n\n return User.$$resource.fetch(null, 'usersSearch', param).then(function(response) {\n var results, index, user, users,\n compareUids = function(data) {\n return this.uid == data.uid;\n };\n\n if (options && options.dry)\n users = [];\n else\n users = User.$users;\n\n if (excludedUsers) {\n // Remove excluded users from response\n results = _.filter(response.users, function(user) {\n return !_.find(excludedUsers, compareUids, user);\n });\n }\n else {\n results = response.users;\n }\n\n // Remove users that no longer match the search query\n for (index = users.length - 1; index >= 0; index--) {\n user = users[index];\n if (!_.find(results, compareUids, user)) {\n users.splice(index, 1);\n }\n }\n // Add new users matching the search query\n _.each(results, function(data, index) {\n if (_.isUndefined(_.find(users, compareUids, data))) {\n var user = new User(data);\n users.splice(index, 0, user);\n }\n });\n User.$log.debug(users);\n return users;\n });\n };\n\n /**\n * @function init\n * @memberof User.prototype\n * @desc Extend instance with required attributes and new data.\n * @param {object} data - attributes of user\n */\n User.prototype.init = function(data) {\n angular.extend(this, data);\n if (!this.$$shortFormat)\n this.$$shortFormat = this.$shortFormat();\n if (!this.$$image)\n this.$$image = this.image || User.$gravatar(this.c_email, 32, User.$alternateAvatar);\n\n // An empty attribute to trick md-autocomplete when adding users from the ACLs editor\n this.empty = ' ';\n };\n\n /**\n * @function $shortFormat\n * @memberof User.prototype\n * @return the fullname along with the email address\n */\n User.prototype.$shortFormat = function(options) {\n var fullname = this.cn || this.c_email;\n var email = this.c_email;\n var no_email = options && options.email === false;\n if (!no_email && email && fullname != email) {\n fullname += ' <' + email + '>';\n }\n return fullname;\n };\n\n /**\n * @function $acl\n * @memberof User.prototype\n * @desc Fetch the user rights associated to a specific folder and populate the 'rights' attribute.\n * @param {string} the folder ID\n * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser\n * @return a promise\n */\n User.prototype.$acl = function(folderId, owner) {\n var _this = this,\n deferred = User.$q.defer(),\n param = {uid: this.uid};\n if (this.$shadowRights) {\n deferred.resolve(this.rights);\n }\n else {\n var rights;\n\n if (angular.isDefined(owner))\n rights = User.$$resource.userResource(owner).fetch(folderId, 'userRights', param);\n else\n rights = User.$$resource.fetch(folderId, 'userRights', param);\n\n rights.then(function(data) {\n _this.rights = data;\n // Convert numbers (0|1) to boolean values\n //angular.forEach(_.keys(_this.rights), function(key) {\n // _this.rights[key] = _this.rights[key] ? true : false;\n //});\n // console.debug('rights ' + _this.uid + ' => ' + JSON.stringify(data, undefined, 2));\n // Keep a copy of the server's version\n _this.$shadowRights = angular.copy(data);\n deferred.resolve(data);\n return data;\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $isAnonymous\n * @memberof User.prototype\n * @return true if it's the special anonymous user\n */\n User.prototype.$isAnonymous = function() {\n return this.uid == 'anonymous';\n };\n\n /**\n * @function $isSpecial\n * @memberof User.prototype\n * @desc Only accurate from the ACL editor.\n * @return true if the user is not a regular system user\n */\n User.prototype.$isSpecial = function() {\n return this.userClass && this.userClass == 'public-user';\n };\n\n /**\n * @function $confirmRights\n * @memberof User.prototype\n * @desc Check if a confirmation is required before giving some rights.\n * @return the confirmation message or false if no confirmation is required\n */\n User.prototype.$confirmRights = function() {\n var confirmation = false;\n\n if (this.$confirmation) {\n // Don't bother the user more than once\n return false;\n }\n\n if (_.some(_.values(this.rights))) {\n if (this.uid == 'anonymous') {\n confirmation = l('Potentially anyone on the Internet will be able to access your folder, even if they do not have an account on this system. Is this information suitable for the public Internet?');\n }\n else if (this.uid == '<default>') {\n confirmation = l('Any user with an account on this system will be able to access your folder. Are you certain you trust them all?');\n }\n }\n\n this.$confirmation = confirmation;\n\n return confirmation;\n };\n\n /**\n * @function $rightsAreDirty\n * @memberof User.prototype\n * @return whether or not the rights have changed from their initial values\n */\n User.prototype.$rightsAreDirty = function() {\n return this.rights && !_.isEqual(this.rights, this.$shadowRights);\n };\n\n /**\n * @function $resetRights\n * @memberof User.prototype\n * @desc Restore initial rights or disable all rights\n * @param {boolean} [zero] - reset all rights to zero when true\n */\n User.prototype.$resetRights = function(zero) {\n var _this = this;\n if (zero) {\n // Disable all rights\n _.map(_.keys(this.rights), function(key) {\n if (angular.isString(_this.rights[key]))\n _this.rights[key] = 'None';\n else\n _this.rights[key] = 0;\n });\n }\n else {\n // Restore initial rights\n this.rights = angular.copy(this.$shadowRights);\n }\n };\n\n /**\n * @function $folders\n * @memberof User.prototype\n * @desc Retrieve the list of folders of a specific type\n * @param {string} type - either 'contact' or 'calendar'\n * @return a promise of the HTTP query result or the cached result\n */\n User.prototype.$folders = function(type) {\n var _this = this,\n deferred = User.$q.defer(),\n param = {type: type};\n if (this.$$folders) {\n deferred.resolve(this.$$folders);\n }\n else {\n User.$$resource.userResource(this.uid).fetch(null, 'foldersSearch', param).then(function(response) {\n _this.$$folders = response.folders;\n deferred.resolve(response.folders);\n });\n }\n return deferred.promise;\n };\n\n /**\n * @function $omit\n * @memberof User.prototype\n * @desc Return a sanitized object used to send to the server.\n * @return an object literal copy of the User instance\n */\n User.prototype.$omit = function() {\n var user = {};\n angular.forEach(this, function(value, key) {\n if (key != 'constructor' && key[0] != '$') {\n user[key] = value;\n }\n });\n return user;\n };\n\n User.prototype.toString = function() {\n return '[User ' + this.c_email + ']';\n };\n\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n \n /**\n * sgFocus - A service to set the focus on the element associated to a specific string\n * @memberof SOGo.Common\n * @param {string} name - the string identifier of the element\n * @see {@link SOGo.Common.sgFocusOn}\n * @ngInject\n */\n sgFocus.$inject = ['$rootScope', '$timeout'];\n function sgFocus($rootScope, $timeout) {\n return function(name) {\n $timeout(function() {\n $rootScope.$broadcast('sgFocusOn', name);\n });\n };\n }\n\n angular\n .module('SOGo.Common')\n .factory('sgFocus', sgFocus);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true, newcap: false */\n 'use strict';\n\n /**\n * sgAvatarImage - An avatar directive that returns un img element with either a local URL (if sg-src is specified)\n * or a Gravatar URL built from the Gravatar factory.\n * Based on http://blog.lingohub.com/2014/08/better-ux-with-angularjs-directives/.\n * @memberof SOGo.Common\n * @example:\n <sg-avatar-image sg-email=\"test@email.com\" size=\"50\"></sg-avatar-image>\n */\n function sgAvatarImage() {\n return {\n restrict: 'AE',\n scope: {\n size: '@',\n email: '=sgEmail',\n src: '=sgSrc'\n },\n template: '<img ng-src=\"{{vm.url}}\"/>',\n link: link,\n bindToController: true,\n controller: 'sgAvatarImageController',\n controllerAs: 'vm'\n };\n }\n\n function link(scope, element, attrs, controller) {\n var el = element[0],\n className = el.className,\n imgElement = element.find('img'),\n img = imgElement[0];\n\n if (attrs.size) {\n imgElement.attr('width', attrs.size);\n imgElement.attr('height', attrs.size);\n }\n\n imgElement.bind('error', function() {\n // Error while loading external link; insert a generic avatar\n controller.insertGenericAvatar(img);\n });\n }\n\n /**\n * @ngInject\n */\n sgAvatarImageController.$inject = ['$scope', '$element', 'Preferences', 'Gravatar'];\n function sgAvatarImageController($scope, $element, Preferences, Gravatar) {\n var vm = this;\n\n $scope.$watch('vm.email', function(email) {\n\n Preferences.ready().then(function() {\n var img = $element.find('img')[0];\n if (!email && !vm.genericAvatar) {\n // If no email is specified, insert a generic avatar\n vm.insertGenericAvatar(img);\n }\n else if (email && !vm.url) {\n if (vm.genericAvatar) {\n // Remove generic avatar and restore visibility of image\n vm.genericAvatar.parentNode.removeChild(vm.genericAvatar);\n delete vm.genericAvatar;\n img.classList.remove('ng-hide');\n }\n vm.url = Gravatar(email, vm.size, Preferences.defaults.SOGoAlternateAvatar);\n }\n });\n });\n\n // If sg-src is defined, watch the expression for the URL of a local image\n if ('sg-src' in $element[0].attributes) {\n $scope.$watch('vm.src', function(src) {\n if (src) {\n vm.url = src;\n }\n });\n }\n\n vm.insertGenericAvatar = function(img) {\n var avatar;\n\n if (!vm.genericAvatar) {\n avatar = document.createElement('md-icon');\n avatar.className = 'material-icons icon-person';\n img.classList.add('ng-hide');\n vm.genericAvatar = img.parentNode.insertBefore(avatar, img);\n }\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgAvatarImage', sgAvatarImage)\n .controller('sgAvatarImageController', sgAvatarImageController);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgColorPicker - Color picker widget\n * @restrict element\n * @param {function} sgOnSelect - the function to call when clicking on a color.\n * One variable is available: color.\n * @ngInject\n * @example:\n\n <sg-color-picker sg-on-select=\"properties.calendar.color = color\"></sg-color-picker>\n */\n function sgColorPicker() {\n return {\n restrict: 'E',\n require: 'ngModel',\n template: [\n '<md-menu>',\n ' <md-button class=\"md-icon-button\"',\n ' label:aria-label=\"Options\"',\n ' ng-style=\"{ \\'background-color\\': sgColor }\"',\n ' ng-click=\"$mdOpenMenu()\"',\n ' md-menu-origin=\"md-menu-origin\">',\n ' <md-icon ng-style=\"{ color: sgIconColor }\">color_lens</md-icon>',\n ' </md-button>',\n ' <md-menu-content width=\"3\">',\n ' <md-content class=\"md-padding\">',\n ' <md-grid-list class=\"sg-color-picker\" md-cols=\"7\" md-row-height=\"1:1\" md-gutter=\"0.5em\">',\n ' <md-grid-tile ng-repeat=\"color in ::sgColors track by $index\"',\n ' ng-style=\"{ \\'background-color\\': color }\"',\n ' ng-class=\"{ selected: color == sgColor }\"',\n ' ng-click=\"setColor(color)\"><md-icon ng-style=\"{ color: color }\">check_box</md-icon></md-grid-tile>',\n ' </md-grid-list>',\n ' </md-content>',\n ' </md-menu-content>',\n '</md-menu>'\n ].join(''),\n replace: true,\n controller: sgColorPickerController,\n link: link\n };\n\n function link(scope, iElement, iAttr, ngModelController) {\n // Expose ng-model value to scope\n ngModelController.$render = function() {\n scope.sgColor = ngModelController.$viewValue;\n scope.sgIconColor = contrast(ngModelController.$viewValue);\n };\n }\n }\n \n /**\n * @ngInject\n */\n sgColorPickerController.$inject = ['$scope', '$element', 'sgColors'];\n function sgColorPickerController($scope, $element, sgColors) {\n var ngModelController = $element.controller('ngModel');\n\n $scope.sgColors = sgColors.selection;\n $scope.setColor = function(color) {\n // Update scope value and ng-model\n $scope.sgColor = color;\n $scope.sgIconColor = contrast(color);\n ngModelController.$setViewValue(color);\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgColorPicker', sgColorPicker);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /*\n * sgCompile - Assign an expression to a DOM element and compile it.\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} sgCompile - the expression to compile\n * @ngInject\n * @example:\n\n <div sg-compile=\"part.content\"><!-- msg --></div>\n */\n sgCompile.$inject = ['$compile'];\n function sgCompile($compile) {\n return {\n restrict: 'A',\n link: sgCompileLink\n };\n\n function sgCompileLink(scope, element, attrs) {\n var ensureCompileRunsOnce = scope.$watch(\n function(scope) {\n // Watch the sg-compile expression for changes\n return scope.$eval(attrs.sgCompile);\n },\n function(value) {\n // When the sg-compile expression changes, assign it into the current DOM\n element.html(value);\n \n // Compile the new DOM and link it to the current scope.\n // NOTE: we only compile .childNodes so that we don't get into infinite loop compiling ourselves\n $compile(element.contents())(scope);\n \n // Use un-watch feature to ensure compilation happens only once.\n ensureCompileRunsOnce();\n }\n );\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgCompile', sgCompile);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgEnter - A directive evaluated when the enter key is pressed\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-enter=\"save($index)\" />\n */\n function sgEnter() {\n var ENTER_KEY = 13;\n return function(scope, element, attrs) {\n element.bind(\"keydown keypress\", function(event) {\n if (event.which === ENTER_KEY) {\n scope.$apply(attrs.sgEnter);\n event.preventDefault();\n }\n });\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgEnter', sgEnter);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgEscape - A directive evaluated when the escape key is pressed\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-escape=\"revertEditing($index)\" />\n */\n function sgEscape() {\n var ESCAPE_KEY = 27;\n return function(scope, elem, attrs) {\n elem.bind('keydown', function(event) {\n if (event.keyCode === ESCAPE_KEY) {\n scope.$apply(attrs.sgEscape);\n }\n });\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgEscape', sgEscape);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgFocusOn - A directive that sets the focus on its element when the specified string is broadcasted\n * @memberof SOGo.Common\n * @see {@link SOGo.Common.sgFocus}\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-focus-on=\"username\" />\n */\n function sgFocusOn() {\n return function(scope, elem, attr) {\n scope.$on('sgFocusOn', function(e, name) {\n if (name === attr.sgFocusOn) {\n elem[0].focus();\n elem[0].select();\n }\n });\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgFocusOn', sgFocusOn);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgFolderStylesheet - Add CSS stylesheet for a folder's color (addressbook or calendar)\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} ngModel - the object literal describing the folder (an Addressbook or Calendar instance)\n * @example:\n\n <sg-folder-stylesheet\n ng-repeat=\"calendar in calendars.list\"\n ng-model=\"calendar\" />\n */\n function sgFolderStylesheet() {\n return {\n restrict: 'E',\n require: 'ngModel',\n scope: {\n ngModel: '='\n },\n replace: true,\n bindToController: true,\n controller: sgFolderStylesheetController,\n controllerAs: 'cssCtrl',\n template: [\n '<style type=\"text/css\">',\n /* Background color */\n ' .bg-folder{{ cssCtrl.ngModel.id }},',\n ' .bg-folder{{ cssCtrl.ngModel.id }} label,',\n ' .bg-folder{{ cssCtrl.ngModel.id }} .md-input {',\n ' background-color: {{ cssCtrl.ngModel.color }} !important;',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n ' .sg-event.bg-folder{{ cssCtrl.ngModel.id }} md-icon {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n // Set the contrast color of toolbar icons except the one of the background\n ' md-toolbar.bg-folder{{ cssCtrl.ngModel.id }} md-icon:not(.sg-icon-toolbar-bg) {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n // Set the contrast color of input labels\n ' .bg-folder{{ cssCtrl.ngModel.id }} label {',\n ' color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' opacity: 0.8;',\n ' }',\n /* Foreground color */\n ' .fg-folder{{ cssCtrl.ngModel.id }},',\n ' .sg-event.fg-folder{{ cssCtrl.ngModel.id }} md-icon {',\n ' color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n /* Border color */\n ' .bdr-folder{{ cssCtrl.ngModel.id }} {',\n ' border-color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n /* Checkbox color */\n ' .checkbox-folder{{ cssCtrl.ngModel.id }} .md-icon {',\n ' background-color: {{ cssCtrl.ngModel.color }} !important;',\n ' }',\n ' .checkbox-folder{{ cssCtrl.ngModel.id }}.md-checked .md-icon:after {',\n ' border-color: {{ cssCtrl.contrast(cssCtrl.ngModel.color) }} !important;',\n ' }',\n '</style>'\n ].join('')\n };\n\n function sgFolderStylesheetController() {\n var vm = this;\n\n vm.contrast = contrast;\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgFolderStylesheet', sgFolderStylesheet);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /**\n * sgPlaceholder - A directive for dynamic placeholder\n * @memberof SOGo.Common\n * @ngInject\n * @example:\n\n <input type=\"text\"\n sg-placeholder=\"this_is_a_variable\" />\n */\n function sgPlaceholder() {\n return {\n restrict: 'A',\n scope: {\n placeholder: '=sgPlaceholder'\n },\n link: function(scope, elem, attr) {\n scope.$watch('placeholder',function() {\n elem[0].placeholder = scope.placeholder;\n });\n }\n };\n }\n \n angular\n .module('SOGo.Common')\n .directive('sgPlaceholder', sgPlaceholder);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgSearch - Search within a list of items\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {function} sgSearch - the function to call when performing a search.\n * Two variables are available: searchField and searchText.\n * @example:\n\n <div sg-search=\"mailbox.$filter({ sort: 'date', asc: false }, [{ searchBy: searchField, searchInput: searchText }])\">\n <md-button class=\"sg-icon-button\"\n sg-search-cancel=\"ctrl.cancelSearch()\">\n <md-icon>arrow_back</md-icon>\n </md-button>\n <md-input-container>\n <input name=\"search\" type=\"search\"/>\n </md-input-container>\n <md-select class=\"sg-toolbar-sort md-contrast-light\">\n <md-option value=\"subject\">Subject</md-option>\n <md-option value=\"sender\">sender</md-option>\n </md-select>\n </div>\n */\n sgSearchPreTransclude.$inject = ['$parse'];\n function sgSearchPreTransclude($parse) {\n return {\n restrict: 'A',\n controller: 'sgSearchController',\n controllerAs: '$sgSearchController',\n priority: 1001,\n compile: compile\n };\n\n function compile(tElement, tAttr) {\n var mdInputEl = tElement.find('md-input-container'),\n inputEl = tElement.find('input'),\n selectEl = tElement.find('md-select'),\n buttonEl = tElement.find('md-button');\n\n inputEl.attr('ng-model', '$sgSearchController.searchText');\n inputEl.attr('ng-model-options', '$sgSearchController.searchTextOptions');\n inputEl.attr('ng-change', '$sgSearchController.onChange()');\n if (selectEl) {\n selectEl.attr('ng-model', '$sgSearchController.searchField');\n selectEl.attr('ng-change', '$sgSearchController.onChange()');\n }\n if (buttonEl && buttonEl.attr('sg-search-cancel')) {\n buttonEl.attr('ng-click', buttonEl.attr('sg-search-cancel'));\n buttonEl.removeAttr('sg-search-cancel');\n }\n else {\n buttonEl = null;\n }\n\n return function postLink(scope, iElement, iAttr, controller) {\n var compiledButtonEl = iElement.find('button');\n\n // Associate callback to controller\n controller.doSearch = $parse(iElement.attr('sg-search'));\n\n // Reset the input field when cancelling the search\n if (buttonEl && compiledButtonEl) {\n compiledButtonEl.on('click', controller.cancelSearch);\n }\n };\n }\n }\n\n function sgSearch() {\n return {\n restrict: 'A',\n priority: 1000,\n transclude: true,\n compile: compile\n };\n\n function compile(tElement, tAttr) {\n return function postLink(scope, iElement, iAttr, controller, transclude) {\n transclude(function(clone) {\n iElement.append(clone);\n });\n };\n }\n }\n\n /**\n * @ngInject\n */\n sgSearchController.$inject = ['$scope', '$element'];\n function sgSearchController($scope, $element) {\n var vm = this;\n\n // Controller variables\n vm.previous = { searchText: '', searchField: '' };\n vm.searchText = null;\n\n // Model options\n vm.searchTextOptions = {\n updateOn: 'default blur',\n debounce: {\n default: 300,\n blur: 0\n }\n };\n\n // Method to call on data changes\n vm.onChange = function() {\n if (typeof vm.searchText !== 'undefined' && vm.searchText !== null) {\n if (vm.searchText != vm.previous.searchText || vm.searchField != vm.previous.searchField) {\n if (vm.searchText.length > 2 || vm.searchText.length === 0 || vm.searchText == '.') {\n // doSearch is the compiled expression of the sg-search attribute\n vm.doSearch($scope, { searchText: vm.searchText, searchField: vm.searchField });\n }\n vm.previous = { searchText: vm.searchText, searchField: vm.searchField };\n }\n }\n };\n\n // Reset input field when cancelling the search\n vm.cancelSearch = function() {\n vm.searchText = \"\";\n };\n }\n\n angular\n .module('SOGo.Common')\n .controller('sgSearchController', sgSearchController)\n .directive('sgSearch', sgSearchPreTransclude)\n .directive('sgSearch', sgSearch);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n /* jshint validthis: true */\n 'use strict';\n\n /*\n * sgSubscribe - Common subscription widget\n * @restrict attribute\n * @param {string} sgSubscribe - the folder type\n * @param {function} sgSubscribeOnSelect - the function to call when subscribing to a folder.\n * One variable is available: folderData.\n * @ngInject\n * @example:\n\n <md-button sg-subscribe=\"contact\" sg-subscribe-on-select=\"subscribeToFolder\">Subscribe ..</md-button>\n */\n sgSubscribe.$inject = ['User'];\n function sgSubscribe(User) {\n return {\n restrict: 'A',\n scope: {\n folderType: '@sgSubscribe',\n onFolderSelect: '&sgSubscribeOnSelect'\n },\n replace: false,\n bindToController: true,\n controller: sgSubscribeDialogController,\n controllerAs: '$sgSubscribeDialogController',\n link: link\n };\n }\n\n function link(scope, element, attrs, controller) {\n var inputEl = element.find('input');\n element.on('click', controller.showDialog);\n }\n\n /**\n * @ngInject\n */\n sgSubscribeDialogController.$inject = ['$mdDialog'];\n function sgSubscribeDialogController($mdDialog) {\n var vm = this;\n vm.showDialog = function() {\n $mdDialog.show({\n templateUrl: '../Contacts/UIxContactsUserFolders',\n clickOutsideToClose: true,\n locals: {\n folderType: vm.folderType,\n onFolderSelect: vm.onFolderSelect\n },\n controller: sgSubscribeController,\n controllerAs: 'subscribe'\n });\n };\n }\n\n /**\n * @ngInject\n */\n sgSubscribeController.$inject = ['$mdDialog', 'folderType', 'onFolderSelect', 'User'];\n function sgSubscribeController($mdDialog, folderType, onFolderSelect, User) {\n var vm = this;\n\n vm.selectedUser = null;\n vm.users = User.$users;\n\n vm.searchTextOptions = {\n updateOn: 'default blur',\n debounce: {\n default: 300,\n blur: 0\n }\n };\n\n vm.onChange = function() {\n User.$filter(vm.searchText).then(function() {\n if (vm.selectedUser) {\n // If selected user is no longer part of the matching users, unselect it\n if (_.isUndefined(_.find(User.$users, function(user) {\n return user.uid == vm.selectedUser.uid;\n }))) {\n vm.selectedUser = null;\n }\n }\n });\n };\n\n vm.selectUser = function(i) {\n if (vm.selectedUser == vm.users[i]) {\n vm.selectedUser = null;\n }\n else {\n // Fetch folders of specific type for selected user\n vm.users[i].$folders(folderType).then(function() {\n vm.selectedUser = vm.users[i];\n });\n }\n };\n\n // Callback upon subscription to a folder\n vm.selectFolder = function(folder) {\n onFolderSelect({folderData: folder});\n };\n\n vm.close = function() {\n $mdDialog.hide();\n };\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgSubscribe', sgSubscribe);\n})();\n","(function() {\n 'use strict';\n\n angular\n .module('SOGo.Common')\n .directive('sgTimePane', timePaneDirective);\n \n function timePaneDirective() {\n return {\n template: [\n '<div class=\"sg-time-pane\">',\n ' <div class=\"hours-pane\">',\n ' <div ng-repeat=\"hoursBigLine in hours\" layout=\"row\" layout-sm=\"column\">',\n ' <div ng-repeat=\"hoursLine in hoursBigLine\" layout=\"row\" class=\"hours\">',\n ' <md-button class=\"hourBtn md-fab md-mini\" ng-repeat=\"hour in hoursLine\" id=\"{{hour.id}}\"',\n ' ng-click=\"hourClickHandler(hour.displayName)\">{{hour.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div class=\"min5\" ng-show=\"is5min()\">',\n ' <div layout=\"row\" layout-sm=\"column\">',\n ' <div ng-repeat=\"minutesLine in min5\" layout=\"row\">',\n ' <md-button class=\"minuteBtn md-fab md-mini\" ng-repeat=\"minute in minutesLine\" id=\"{{minute.id}}\"',\n ' ng-click=\"minuteClickHandler(minute.displayName)\">{{minute.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div class=\"sg-time-scroll-mask\" ng-hide=\"is5min()\">',\n ' <div class=\"min1\" layout=\"row\" layout-sm=\"column\" layout-wrap>',\n ' <div ng-repeat=\"minutesLine in min1\" layout=\"row\" layout-align=\"space-around center\" flex=\"50\">',\n ' <md-button class=\"minuteBtn md-fab md-mini\" ng-repeat=\"minute in minutesLine\" id=\"{{minute.id}}\"',\n ' ng-click=\"minuteClickHandler(minute.displayName)\">{{minute.displayName}}</md-button>',\n ' </div>',\n ' </div>',\n ' </div>',\n ' <div flex layout=\"row\" layout-align=\"center center\" class=\"toggle-pane\">',\n ' <md-button class=\"toggleBtn md-fab md-mini\" ng-bind=\"getToggleBtnLbl()\" ng-click=\"toggleManual5min()\"></md-button>',\n ' </div>',\n '</div>'\n ].join(''),\n scope: {},\n require: ['ngModel', 'sgTimePane'],\n controller: TimePaneCtrl,\n controllerAs: 'ctrl',\n bindToController: true,\n link: function(scope, element, attrs, controllers) {\n var ngModelCtrl = controllers[0];\n var sgTimePaneCtrl = controllers[1];\n var timePaneElement = element;\n sgTimePaneCtrl.configureNgModel(ngModelCtrl, sgTimePaneCtrl, timePaneElement);\n }\n };\n }\n\n /** Class applied to the selected hour or minute cell/. */\n var SELECTED_TIME_CLASS = 'md-bg';\n\n /** Class applied to the focused hour or minute cell/. */\n var FOCUSED_TIME_CLASS = 'md-focus';\n\n /** Next identifier for calendar instance. */\n var nextTimePaneUniqueId = 0;\n\n function TimePaneCtrl($element, $attrs, $scope, $animate, $q, $mdConstant,\n $mdTheming, $$mdDateUtil, $mdDateLocale, $mdInkRipple, $mdUtil) {\n var m;\n this.$scope = $scope;\n this.$element = $element;\n this.timePaneElement = $element[0].querySelector('.sg-time-pane');\n this.$animate = $animate;\n this.$q = $q;\n this.$mdInkRipple = $mdInkRipple;\n this.$mdUtil = $mdUtil;\n this.keyCode = $mdConstant.KEY_CODE;\n this.dateUtil = $$mdDateUtil;\n this.id = nextTimePaneUniqueId++;\n this.ngModelCtrl = null;\n this.selectedTime = null;\n this.displayTime = null;\n this.isInitialized = false;\n\n $scope.hours=[];\n $scope.hours[0]=[];\n $scope.hours[0][0]=[];\n $scope.hours[0][1]=[];\n $scope.hours[1]=[];\n $scope.hours[1][0]=[];\n $scope.hours[1][1]=[];\n for(var i=0; i<6; i++){\n $scope.hours[0][0][i] = {id:'tp-'+this.id+'-hour-'+i, displayName:i<10?\"0\"+i:\"\"+i, selected:false};\n $scope.hours[0][1][i] = {id:'tp-'+this.id+'-hour-'+(i+6),displayName:(i+6)<10?\"0\"+(i+6):\"\"+(i+6), selected:false};\n $scope.hours[1][0][i] = {id:'tp-'+this.id+'-hour-'+(i+12), displayName:\"\"+(i+12), selected:false};\n $scope.hours[1][1][i] = {id:'tp-'+this.id+'-hour-'+(i+18), displayName:\"\"+(i+18), selected:false};\n }\n\n $scope.min5=[];\n $scope.min5[0]=[];\n $scope.min5[1]=[];\n for(i=0; i<6; i++){\n m=i*5;\n $scope.min5[0][i] = {id:'tp-'+this.id+'-minute5-'+m, displayName:m<10?\":0\"+m:\":\"+m, selected:true};\n $scope.min5[1][i] = {id:'tp-'+this.id+'-minute5-'+(m+30), displayName:\":\"+(m+30), selected:false};\n }\n\n $scope.min1=[];\n for(i=0; i<12; i++){\n $scope.min1[i]=[];\n for(var ii=0; ii<5; ii++){\n m=i*5 + ii;\n $scope.min1[i][ii] = {id:'tp-'+this.id+'-minute-'+m, displayName:m<10?\":0\"+m:\":\"+m, selected:true};\n }\n }\n\n $scope.show5min = true;\n $scope.getToggleBtnLbl = function() {\n return ($scope.is5min()) ? '>>' : '<<';\n };\n $scope.toggleManual5min = function() {\n $scope.manual5min = !$scope.is5min();\n };\n $scope.is5min = function() {\n if ($scope.manual5min === true || $scope.manual5min === false) {\n return $scope.manual5min;\n }\n else {\n return $scope.show5min;\n }\n };\n\n if (!$attrs.tabindex) {\n $element.attr('tabindex', '-1');\n }\n\n var self = this;\n\n this.hourClickHandler = function(displayVal) {\n var updated = new Date(self.displayTime);\n updated.setHours(Number(displayVal));\n self.setNgModelValue(updated, 'hours');\n };\n $scope.hourClickHandler = this.hourClickHandler;\n\n this.minuteClickHandler = function(displayVal) {\n //remove leading ':'\n var val = displayVal.substr(1);\n var updated = new Date(self.displayTime);\n updated.setMinutes(Number(val));\n self.setNgModelValue(updated, 'minutes');\n };\n $scope.minuteClickHandler = this.minuteClickHandler;\n\n this.attachTimePaneEventListeners();\n }\n TimePaneCtrl.$inject = [\"$element\", \"$attrs\", \"$scope\", \"$animate\", \"$q\", \"$mdConstant\", \"$mdTheming\", \"$$mdDateUtil\", \"$mdDateLocale\", \"$mdInkRipple\", \"$mdUtil\"];\n\n TimePaneCtrl.prototype.configureNgModel = function(ngModelCtrl, sgTimePaneCtrl, timePaneElement) {\n this.ngModelCtrl = ngModelCtrl;\n\n var self = this;\n ngModelCtrl.$render = function() {\n self.changeSelectedTime(self.ngModelCtrl.$viewValue, sgTimePaneCtrl, timePaneElement);\n };\n };\n\n /**\n * Change the selected date in the time (ngModel value has already been changed).\n */\n TimePaneCtrl.prototype.changeSelectedTime = function(date, sgTimePaneCtrl, timePaneElement) {\n var self = this;\n var previousSelectedTime = this.selectedTime;\n this.selectedTime = date;\n this.changeDisplayTime(date).then(function() {\n\n // Remove the selected class from the previously selected date, if any.\n if (previousSelectedTime) {\n var prevH = previousSelectedTime.getHours();\n var prevHCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+prevH);\n if (prevHCell) {\n prevHCell.classList.remove(SELECTED_TIME_CLASS);\n prevHCell.setAttribute('aria-selected', 'false');\n }\n var prevM = previousSelectedTime.getMinutes();\n var prevMCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+prevM);\n if (prevMCell) {\n prevMCell.classList.remove(SELECTED_TIME_CLASS);\n prevMCell.setAttribute('aria-selected', 'false');\n }\n var prevM5Cell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+prevM);\n if (prevM5Cell) {\n prevM5Cell.classList.remove(SELECTED_TIME_CLASS);\n prevM5Cell.setAttribute('aria-selected', 'false');\n }\n }\n\n // Apply the select class to the new selected date if it is set.\n if (date) {\n var newH = date.getHours();\n var mCell, hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);\n if (hCell) {\n hCell.classList.add(SELECTED_TIME_CLASS);\n hCell.setAttribute('aria-selected', 'true');\n }\n var newM = date.getMinutes();\n if (newM % 5 === 0) {\n sgTimePaneCtrl.$scope.show5min = true;\n mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute5-'+newM);\n if (mCell) {\n mCell.classList.add(SELECTED_TIME_CLASS);\n mCell.setAttribute('aria-selected', 'true');\n }\n }\n else {\n sgTimePaneCtrl.$scope.show5min = false;\n }\n mCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-minute-'+newM);\n if (mCell) {\n mCell.classList.add(SELECTED_TIME_CLASS);\n mCell.setAttribute('aria-selected', 'true');\n }\n\n }\n });\n };\n\n TimePaneCtrl.prototype.changeDisplayTime = function(date) {\n var d = new Date(date);\n if (!this.isInitialized) {\n this.buildInitialTimePaneDisplay();\n return this.$q.when();\n }\n if (!this.dateUtil.isValidDate(d)) {\n return this.$q.when();\n }\n\n this.displayTime = d;\n\n return this.$q.when();\n };\n TimePaneCtrl.prototype.buildInitialTimePaneDisplay = function() {\n this.displayTime = this.selectedTime || this.today;\n this.isInitialized = true;\n };\n\n TimePaneCtrl.prototype.attachTimePaneEventListeners = function() {\n // Keyboard interaction.\n this.$element.on('keydown', angular.bind(this, this.handleKeyEvent));\n };\n\n /*** User input handling ***/\n\n /**\n * Handles a key event in the calendar with the appropriate action. The action will either\n * be to select the focused date or to navigate to focus a new date.\n * @param {KeyboardEvent} event\n */\n TimePaneCtrl.prototype.handleKeyEvent = function(event) {\n var self = this;\n this.$scope.$apply(function() {\n // Capture escape and emit back up so that a wrapping component\n // (such as a time-picker) can decide to close.\n if (event.which == self.keyCode.ESCAPE || event.which == self.keyCode.TAB) {\n self.$scope.$emit('md-time-pane-close');\n\n if (event.which == self.keyCode.TAB) {\n event.preventDefault();\n }\n\n return;\n }\n\n // Remaining key events fall into two categories: selection and navigation.\n // Start by checking if this is a selection event.\n if (event.which === self.keyCode.ENTER) {\n self.setNgModelValue(self.displayTime, 'enter');\n event.preventDefault();\n return;\n }\n\n // Selection isn't occuring, so the key event is either navigation or nothing.\n /*var date = self.getFocusDateFromKeyEvent(event);\n if (date) {\n event.preventDefault();\n event.stopPropagation();\n\n // Since this is a keyboard interaction, actually give the newly focused date keyboard\n // focus after the been brought into view.\n self.changeDisplayTime(date).then(function () {\n self.focus(date);\n });\n }*/\n });\n };\n\n /**\n * Sets the ng-model value for the time pane and emits a change event.\n * @param {Date} date\n */\n TimePaneCtrl.prototype.setNgModelValue = function(date, mode) {\n this.$scope.$emit('sg-time-pane-change', {date:date, changed:mode});\n this.ngModelCtrl.$setViewValue(date);\n this.ngModelCtrl.$render();\n };\n\n /**\n * Focus the cell corresponding to the given date.\n * @param {Date=} opt_date\n */\n TimePaneCtrl.prototype.focus = function(opt_date, sgTimePaneCtrl) {\n var date = opt_date || this.selectedTime || this.today;\n\n var previousFocus = this.timePaneElement.querySelector('.md-focus');\n if (previousFocus) {\n previousFocus.classList.remove(FOCUSED_TIME_CLASS);\n }\n\n if (date) {\n var newH = date.getHours();\n var hCell = document.getElementById('tp-'+sgTimePaneCtrl.id+'-hour-'+newH);\n if (hCell) {\n hCell.classList.add(FOCUSED_TIME_CLASS);\n hCell.focus();\n }\n }\n };\n})();\n\n(function() {\n 'use strict';\n \n angular.module('SOGo.Common')\n .directive('sgTimepicker', timePickerDirective);\n\n /**\n * @ngdoc directive\n * @name mdTimepicker\n * @module material.components.timepicker\n *\n * @param {Date} ng-model The component's model. Expects a JavaScript Date object.\n * @param {expression=} ng-change Expression evaluated when the model value changes.\n * @param {boolean=} disabled Whether the timepicker is disabled.\n *\n * @description\n * `<sg-timepicker>` is a component used to select a single time.\n * For information on how to configure internationalization for the time picker,\n * see `$mdTimeLocaleProvider`.\n *\n * @usage\n * <hljs lang=\"html\">\n * <sg-timepicker ng-model=\"birthday\"></sg-timepicker>\n * </hljs>\n *\n */\n function timePickerDirective() {\n return {\n template: [\n // Buttons are not in the tab order because users can open the hours pane via keyboard\n // interaction on the text input, and multiple tab stops for one component (picker)\n // may be confusing.\n '<md-button class=\"sg-timepicker-button md-icon-button\" type=\"button\" ',\n ' tabindex=\"-1\" aria-hidden=\"true\" ',\n ' ng-click=\"ctrl.openTimePane($event)\">',\n ' <md-icon>access_time</md-icon>',\n '</md-button>',\n '<div class=\"md-default-theme sg-timepicker-input-container\" ',\n ' ng-class=\"{\\'sg-timepicker-focused\\': ctrl.isFocused,',\n ' \\'md-bdr\\': ctrl.isFocused}\">',\n ' <input class=\"sg-timepicker-input\" aria-haspopup=\"true\" ',\n ' ng-focus=\"ctrl.setFocused(true)\" ng-blur=\"ctrl.setFocused(false)\">',\n ' <md-button type=\"button\" md-no-ink ',\n ' class=\"sg-timepicker-triangle-button md-icon-button\" ',\n ' ng-click=\"ctrl.openTimePane($event)\" ',\n ' aria-label=\"{{::ctrl.dateLocale.msgOpenCalendar}}\">',\n ' <div class=\"sg-timepicker-expand-triangle\"></div>',\n ' </md-button>',\n '</div>',\n // This pane will be detached from here and re-attached to the document body.\n '<div class=\"sg-timepicker-time-pane md-whiteframe-z1\">',\n ' <div class=\"sg-timepicker-input-mask\">',\n ' <div class=\"sg-timepicker-input-mask-opaque',\n ' md-default-theme md-background md-bg\"></div>', // using mdColors\n ' </div>',\n ' <div class=\"sg-timepicker-time md-default-theme md-bg md-background\">',\n ' <sg-time-pane role=\"dialog\" aria-label=\"{{::ctrl.dateLocale.msgCalendar}}\" ',\n ' ng-model=\"ctrl.time\" ng-if=\"ctrl.isTimeOpen\"></sg-time-pane>',\n ' </div>',\n '</div>'\n ].join(''),\n require: ['ngModel', 'sgTimepicker'],\n scope: {\n placeholder: '@mdPlaceholder'\n },\n controller: TimePickerCtrl,\n controllerAs: 'ctrl',\n bindToController: true,\n link: function(scope, element, attr, controllers) {\n var ngModelCtrl = controllers[0];\n var mdTimePickerCtrl = controllers[1];\n\n mdTimePickerCtrl.configureNgModel(ngModelCtrl);\n }\n };\n }\n\n /** Additional offset for the input's `size` attribute, which is updated based on its content. */\n var EXTRA_INPUT_SIZE = 3;\n\n /** Class applied to the container if the date is invalid. */\n var INVALID_CLASS = 'sg-timepicker-invalid';\n\n /** Default time in ms to debounce input event by. */\n var DEFAULT_DEBOUNCE_INTERVAL = 500;\n\n /**\n * Height of the calendar pane used to check if the pane is going outside the boundary of\n * the viewport. See calendar.scss for how $md-calendar-height is computed; an extra 20px is\n * also added to space the pane away from the exact edge of the screen.\n *\n * This is computed statically now, but can be changed to be measured if the circumstances\n * of calendar sizing are changed.\n */\n var TIME_PANE_HEIGHT = { MIN5: { GTSM: 172 + 20, SM: 292 + 20 },\n MIN1: { GTSM: 364 + 20, SM: 454 + 20 } };\n\n /**\n * Width of the calendar pane used to check if the pane is going outside the boundary of\n * the viewport. See calendar.scss for how $md-calendar-width is computed; an extra 20px is\n * also added to space the pane away from the exact edge of the screen.\n *\n * This is computed statically now, but can be changed to be measured if the circumstances\n * of calendar sizing are changed.\n */\n var TIME_PANE_WIDTH = { GTSM: 510 + 20, SM: 272 + 20 };\n\n /**\n * Controller for sg-timepicker.\n *\n * ngInject @constructor\n */\n function TimePickerCtrl($scope, $element, $attrs, $compile, $timeout, $mdConstant, $mdMedia, $mdTheming,\n $mdUtil, $mdDateLocale, $$mdDateUtil, $$rAF) {\n /** @final */\n this.$compile = $compile;\n\n /** @final */\n this.$timeout = $timeout;\n\n /** @final */\n this.dateLocale = $mdDateLocale;\n\n /** @final */\n this.dateUtil = $$mdDateUtil;\n\n /** @final */\n this.$mdConstant = $mdConstant;\n\n /** @final */\n this.$mdMedia = $mdMedia;\n\n /* @final */\n this.$mdUtil = $mdUtil;\n\n /** @final */\n this.$$rAF = $$rAF;\n\n /** @type {!angular.NgModelController} */\n this.ngModelCtrl = null;\n\n /** @type {HTMLInputElement} */\n this.inputElement = $element[0].querySelector('input');\n\n /** @type {HTMLElement} */\n this.inputContainer = $element[0].querySelector('.sg-timepicker-input-container');\n\n /** @final {!angular.JQLite} */\n this.ngInputElement = angular.element(this.inputElement);\n\n /** @type {HTMLElement} Floating time pane. */\n this.timePane = $element[0].querySelector('.sg-timepicker-time-pane');\n\n /** @type {HTMLElement} Time icon button. */\n this.timeButton = $element[0].querySelector('.sg-timepicker-button');\n\n /**\n * Element covering everything but the input in the top of the floating calendar pane.\n * @type {HTMLElement}\n */\n this.inputMask = $element[0].querySelector('.sg-timepicker-input-mask-opaque');\n\n /** @final {!angular.JQLite} */\n this.$element = $element;\n\n /** @final {!angular.Attributes} */\n this.$attrs = $attrs;\n\n /** @final {!angular.Scope} */\n this.$scope = $scope;\n\n /** @type {Date} */\n this.date = null;\n\n /** @type {boolean} */\n this.isFocused = false;\n\n /** @type {boolean} */\n this.isDisabled = false;\n this.setDisabled($element[0].disabled || angular.isString($attrs.disabled));\n\n /** @type {boolean} Whether the date-picker's calendar pane is open. */\n this.isTimeOpen = false;\n\n /**\n * Element from which the calendar pane was opened. Keep track of this so that we can return\n * focus to it when the pane is closed.\n * @type {HTMLElement}\n */\n this.timePaneOpenedFrom = null;\n\n this.timePane.id = 'sg-time-pane' + $mdUtil.nextUid();\n\n $mdTheming($element);\n\n /** Pre-bound click handler is saved so that the event listener can be removed. */\n this.bodyClickHandler = angular.bind(this, this.handleBodyClick);\n\n /** Pre-bound resize handler so that the event listener can be removed. */\n this.windowResizeHandler = $mdUtil.debounce(angular.bind(this, this.closeTimePane), 100);\n\n // Unless the user specifies so, the datepicker should not be a tab stop.\n // This is necessary because ngAria might add a tabindex to anything with an ng-model\n // (based on whether or not the user has turned that particular feature on/off).\n if (!$attrs.tabindex) {\n $element.attr('tabindex', '-1');\n }\n\n this.installPropertyInterceptors();\n this.attachChangeListeners();\n this.attachInteractionListeners();\n\n var self = this;\n $scope.$on('$destroy', function() {\n self.detachTimePane();\n });\n }\n\n TimePickerCtrl.$inject = [\"$scope\", \"$element\", \"$attrs\", \"$compile\", \"$timeout\", \"$mdConstant\", \"$mdMedia\", \"$mdTheming\",\n \"$mdUtil\", \"$mdDateLocale\", \"$$mdDateUtil\", \"$$rAF\"];\n\n /**\n * Sets up the controller's reference to ngModelController.\n * @param {!angular.NgModelController} ngModelCtrl\n */\n TimePickerCtrl.prototype.configureNgModel = function(ngModelCtrl) {\n this.ngModelCtrl = ngModelCtrl;\n var self = this;\n ngModelCtrl.$render = function() {\n self.time = self.ngModelCtrl.$viewValue;\n self.inputElement.value = self.formatTime(self.time);\n self.resizeInputElement();\n };\n };\n\n TimePickerCtrl.prototype.formatTime = function(time) {\n var t = new Date(time);\n if (t) {\n var h = t.getHours();\n var m = t.getMinutes();\n return (h < 10? ('0' + h) : h) + ':' + (m < 10? ('0' + m) : m);\n }\n else return '';\n };\n /**\n * Attach event listeners for both the text input and the md-time.\n * Events are used instead of ng-model so that updates don't infinitely update the other\n * on a change. This should also be more performant than using a $watch.\n */\n TimePickerCtrl.prototype.attachChangeListeners = function() {\n var self = this;\n\n self.$scope.$on('sg-time-pane-change', function(event, data) {\n var time = new Date(data.date);\n self.ngModelCtrl.$setViewValue(time);\n self.time = time;\n self.inputElement.value = self.formatTime(self.time);\n if (data.changed == 'minutes') {\n self.closeTimePane();\n }\n self.resizeInputElement();\n self.inputContainer.classList.remove(INVALID_CLASS);\n });\n\n self.ngInputElement.on('input', angular.bind(self, self.resizeInputElement));\n self.ngInputElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,\n DEFAULT_DEBOUNCE_INTERVAL, self));\n };\n\n /** Attach event listeners for user interaction. */\n TimePickerCtrl.prototype.attachInteractionListeners = function() {\n var self = this;\n var $scope = this.$scope;\n var keyCodes = this.$mdConstant.KEY_CODE;\n\n // Add event listener through angular so that we can triggerHandler in unit tests.\n self.ngInputElement.on('keydown', function(event) {\n if (event.altKey && event.keyCode == keyCodes.DOWN_ARROW) {\n self.openTimePane(event);\n $scope.$digest();\n }\n });\n\n $scope.$on('md-time-close', function() {\n self.closeTimePane();\n });\n };\n\n /**\n * Capture properties set to the time-picker and imperitively handle internal changes.\n * This is done to avoid setting up additional $watches.\n */\n TimePickerCtrl.prototype.installPropertyInterceptors = function() {\n var self = this;\n\n if (this.$attrs.ngDisabled) {\n // The expression is to be evaluated against the directive element's scope and not\n // the directive's isolate scope.\n var scope = this.$mdUtil.validateScope(this.$element) ? this.$element.scope() : null;\n if (scope) {\n scope.$watch(this.$attrs.ngDisabled, function(isDisabled) {\n self.setDisabled(isDisabled);\n });\n }\n }\n\n Object.defineProperty(this, 'placeholder', {\n get: function() { return self.inputElement.placeholder; },\n set: function(value) { self.inputElement.placeholder = value || ''; }\n });\n };\n\n /**\n * Sets whether the date-picker is disabled.\n * @param {boolean} isDisabled\n */\n TimePickerCtrl.prototype.setDisabled = function(isDisabled) {\n this.isDisabled = isDisabled;\n this.inputElement.disabled = isDisabled;\n this.timeButton.disabled = isDisabled;\n };\n\n /**\n * Resizes the input element based on the size of its content.\n */\n TimePickerCtrl.prototype.resizeInputElement = function() {\n this.inputElement.size = this.inputElement.value.length + EXTRA_INPUT_SIZE;\n };\n\n /**\n * Sets the model value if the user input is a valid time.\n * Adds an invalid class to the input element if not.\n */\n TimePickerCtrl.prototype.handleInputEvent = function(self) {\n var inputString = this.inputElement.value;\n var arr = inputString.split(':');\n\n if (inputString === '') {\n this.ngModelCtrl.$setViewValue(null);\n this.time = null;\n this.inputContainer.classList.remove(INVALID_CLASS);\n }\n else if (arr.length < 2) {\n this.inputContainer.classList.toggle(INVALID_CLASS, inputString);\n }\n else {\n var h = Number(arr[0]);\n var m = Number(arr[1]);\n var newVal = new Date(this.time);\n if (h && h >= 0 && h <= 23 && m && m >= 0 && m <= 59 && angular.isDate(newVal)) {\n newVal.setHours(h);\n newVal.setMinutes(m);\n this.ngModelCtrl.$setViewValue(newVal);\n this.time = newVal;\n this.inputContainer.classList.remove(INVALID_CLASS);\n }\n else {\n this.inputContainer.classList.toggle(INVALID_CLASS, inputString);\n }\n }\n };\n\n /** Position and attach the floating calendar to the document. */\n TimePickerCtrl.prototype.attachTimePane = function() {\n var timePane = this.timePane;\n this.$element.addClass('sg-timepicker-open');\n this.$element.find('button').addClass('md-primary');\n\n var elementRect = this.inputContainer.getBoundingClientRect();\n var bodyRect = document.body.getBoundingClientRect();\n\n // Check to see if the calendar pane would go off the screen. If so, adjust position\n // accordingly to keep it within the viewport.\n var paneTop = elementRect.top - bodyRect.top;\n var paneLeft = elementRect.left - bodyRect.left;\n\n // If the right edge of the pane would be off the screen and shifting it left by the\n // difference would not go past the left edge of the screen.\n var paneWidth = this.$mdMedia('sm')? TIME_PANE_WIDTH.SM : TIME_PANE_WIDTH.GTSM;\n if (paneLeft + paneWidth > bodyRect.right &&\n bodyRect.right - paneWidth > 0) {\n paneLeft = bodyRect.right - paneWidth;\n timePane.classList.add('sg-timepicker-pos-adjusted');\n }\n timePane.style.left = paneLeft + 'px';\n\n // If the bottom edge of the pane would be off the screen and shifting it up by the\n // difference would not go past the top edge of the screen.\n var min = (typeof this.time == 'object' && this.time.getMinutes() % 5 === 0)? 'MIN5' : 'MIN1';\n var paneHeight = this.$mdMedia('sm')? TIME_PANE_HEIGHT[min].SM : TIME_PANE_HEIGHT[min].GTSM;\n if (paneTop + paneHeight > bodyRect.bottom &&\n bodyRect.bottom - paneHeight > 0) {\n paneTop = bodyRect.bottom - paneHeight;\n timePane.classList.add('sg-timepicker-pos-adjusted');\n }\n\n timePane.style.top = paneTop + 'px';\n document.body.appendChild(this.timePane);\n\n // The top of the calendar pane is a transparent box that shows the text input underneath.\n // Since the pane is floating, though, the page underneath the pane *adjacent* to the input is\n // also shown unless we cover it up. The inputMask does this by filling up the remaining space\n // based on the width of the input.\n this.inputMask.style.left = elementRect.width + 'px';\n\n // Add CSS class after one frame to trigger open animation.\n this.$$rAF(function() {\n timePane.classList.add('md-pane-open');\n });\n };\n\n /** Detach the floating time pane from the document. */\n TimePickerCtrl.prototype.detachTimePane = function() {\n this.$element.removeClass('sg-timepicker-open');\n this.$element.find('button').removeClass('md-primary');\n this.timePane.classList.remove('md-pane-open');\n this.timePane.classList.remove('md-timepicker-pos-adjusted');\n\n if (this.timePane.parentNode) {\n // Use native DOM removal because we do not want any of the angular state of this element\n // to be disposed.\n this.timePane.parentNode.removeChild(this.timePane);\n }\n };\n\n /**\n * Open the floating time pane.\n * @param {Event} event\n */\n TimePickerCtrl.prototype.openTimePane = function(event) {\n if (!this.isTimeOpen && !this.isDisabled) {\n this.isTimeOpen = true;\n this.timePaneOpenedFrom = event.target;\n this.attachTimePane();\n //this.focusTime();\n\n // Because the time pane is attached directly to the body, it is possible that the\n // rest of the component (input, etc) is in a different scrolling container, such as\n // an md-content. This means that, if the container is scrolled, the pane would remain\n // stationary. To remedy this, we disable scrolling while the time pane is open, which\n // also matches the native behavior for things like `<select>` on Mac and Windows.\n this.$mdUtil.disableScrollAround(this.timePane);\n\n // Attach click listener inside of a timeout because, if this open call was triggered by a\n // click, we don't want it to be immediately propogated up to the body and handled.\n var self = this;\n this.$mdUtil.nextTick(function() {\n document.body.addEventListener('click', self.bodyClickHandler);\n }, false);\n\n window.addEventListener('resize', this.windowResizeHandler);\n }\n };\n\n /** Close the floating time pane. */\n TimePickerCtrl.prototype.closeTimePane = function() {\n this.isTimeOpen = false;\n this.detachTimePane();\n this.timePaneOpenedFrom.focus();\n this.timePaneOpenedFrom = null;\n this.$mdUtil.enableScrolling();\n\n document.body.removeEventListener('click', this.bodyClickHandler);\n window.removeEventListener('resize', this.windowResizeHandler);\n };\n\n /** Gets the controller instance for the time in the floating pane. */\n TimePickerCtrl.prototype.getTimePaneCtrl = function() {\n return angular.element(this.timePane.querySelector('sg-time-pane')).controller('sgTimePane');\n };\n\n /** Focus the time in the floating pane. */\n TimePickerCtrl.prototype.focusTime = function() {\n // Use a timeout in order to allow the time to be rendered, as it is gated behind an ng-if.\n var self = this;\n this.$mdUtil.nextTick(function() {\n var ctrl = self.getTimePaneCtrl();\n self.getTimePaneCtrl().focus(null, ctrl);\n }, false);\n };\n\n /**\n * Sets whether the input is currently focused.\n * @param {boolean} isFocused\n */\n TimePickerCtrl.prototype.setFocused = function(isFocused) {\n this.isFocused = isFocused;\n };\n\n /**\n * Handles a click on the document body when the floating time pane is open.\n * Closes the floating time pane if the click is not inside of it.\n * @param {MouseEvent} event\n */\n TimePickerCtrl.prototype.handleBodyClick = function(event) {\n if (this.isTimeOpen) {\n // TODO(jelbourn): way want to also include the md-datepicker itself in this check.\n var isInTime = this.$mdUtil.getClosest(event.target, 'sg-time-pane');\n if (!isInTime) {\n this.closeTimePane();\n }\n\n this.$scope.$digest();\n }\n };\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /*\n * sgToggleGrid - Convert the tiles of a grid to toggle buttons\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} sgToggleGrid - the model of the source objects\n * @param {string} [sgToggleGridAttr] - the attribute that specifies if an object is enabled (toggled)\n * @ngInject\n * @example:\n\n <md-grid-list md-cols=\"7\" md-row-height=\"1:1\"\n sg-toggle-grid=\"editor.event.repeat.days\"\n sg-toggle-grid-attr=\"day\">..</md-grid-list>\n */\n sgToggleGrid.$inject = ['$parse'];\n function sgToggleGrid($parse) {\n return {\n restrict: 'A',\n link: link\n };\n\n function link(scope, iElement, attrs, ctrl) {\n var tiles = iElement.find('md-grid-tile'),\n tile,\n i,\n modelDays,\n modelAttr,\n ensureInitRunsOnce,\n toggleClass;\n\n ensureInitRunsOnce = scope.$watch(function() {\n // Parse attribute until it returns a valid object\n return $parse(attrs.sgToggleGrid)(scope);\n }, function(days) {\n if (angular.isDefined(days)) {\n var flattenedDays = days;\n modelDays = days;\n if (attrs.sgToggleGridAttr) {\n modelAttr = attrs.sgToggleGridAttr;\n flattenedDays = _.pluck(days, attrs.sgToggleGridAttr);\n }\n _.each(tiles, function(o) {\n var tile = angular.element(o);\n if (_.contains(flattenedDays, tile.attr('value'))) {\n tile.addClass('sg-active');\n }\n });\n ensureInitRunsOnce();\n }\n });\n\n toggleClass = function() {\n // Toggle class on click event and call toggle function\n var tile = angular.element(this),\n day = tile.attr('value');\n tile.toggleClass('sg-active');\n toggle(day);\n };\n\n for (i = 0; i < tiles.length; i++) {\n tile = angular.element(tiles[i]);\n tile.addClass('iconButton');\n tile.find('figure').addClass('md-icon');\n tile.on('click', toggleClass);\n }\n\n function toggle(day) {\n var i = _.findIndex(modelDays, function(o) {\n if (modelAttr)\n return o[modelAttr] == day;\n else\n return o == day;\n });\n if (i < 0) {\n if (modelAttr) {\n var o = {};\n o[modelAttr] = day;\n modelDays.push(o);\n }\n else\n modelDays.push(day);\n }\n else\n modelDays.splice(i, 1);\n }\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgToggleGrid', sgToggleGrid);\n})();\n","/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */\n\n(function() {\n 'use strict';\n\n /*\n * sgToggleGrid - Convert the tiles of a grid to toggle buttons\n * @memberof SOGo.Common\n * @restrict attribute\n * @param {object} sgToggleGrid - the model of the source objects\n * @param {string} [sgToggleGridAttr] - the attribute that specifies if an object is enabled (toggled)\n * @ngInject\n * @example:\n\n <md-grid-list md-cols=\"7\" md-row-height=\"1:1\"\n sg-toggle-grid=\"editor.event.repeat.days\"\n sg-toggle-grid-attr=\"day\">..</md-grid-list>\n */\n function sgVariableScrollShrink() {\n return {\n restrict: 'C',\n link: link\n };\n\n function link(scope, element, attrs, ctrl) {\n console.debug('scroll shrink height = ' + element.prop('offsetHeight'));\n }\n }\n\n angular\n .module('SOGo.Common')\n .directive('sgVariableScrollShrink', sgVariableScrollShrink);\n})();\n"]}