/* Minification failed. Returning unminified contents.
(3004,29-32): run-time error JS1009: Expected '}': ...
(3009,21-27): run-time error JS1006: Expected ')': return
(3007,22): run-time error JS1004: Expected ';'
(3010,18-19): run-time error JS1194: Expected ',' or ']': )
(3258,9-10): run-time error JS1006: Expected ')': ]
(3258,9-10): run-time error JS1195: Expected expression: ]
(3258,10-11): run-time error JS1195: Expected expression: )
(3258,11-12): run-time error JS1195: Expected expression: .
(3293,1-2): run-time error JS1002: Syntax error: }
(3293,2-3): run-time error JS1195: Expected expression: )
(3420,7-8): run-time error JS1010: Expected identifier: .
(3420,7-8): run-time error JS1195: Expected expression: .
(3456,7-8): run-time error JS1010: Expected identifier: .
(3456,7-8): run-time error JS1195: Expected expression: .
(3814,7-8): run-time error JS1010: Expected identifier: .
(3814,7-8): run-time error JS1195: Expected expression: .
(262,145-152): run-time error JS1019: Can't have 'break' outside of loop: break a
(40,297-304): run-time error JS1019: Can't have 'break' outside of loop: break a
 */
/*
 AngularJS v1.3.15
 (c) 2010-2014 Google, Inc. http://angularjs.org
 License: MIT
*/
(function(Q,W,t){'use strict';function R(b){return function(){var a=arguments[0],c;c="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.3.15/"+(b?b+"/":"")+a;for(a=1;a<arguments.length;a++){c=c+(1==a?"?":"&")+"p"+(a-1)+"=";var d=encodeURIComponent,e;e=arguments[a];e="function"==typeof e?e.toString().replace(/ \{[\s\S]*$/,""):"undefined"==typeof e?"undefined":"string"!=typeof e?JSON.stringify(e):e;c+=d(e)}return Error(c)}}function Sa(b){if(null==b||Ta(b))return!1;var a=b.length;return b.nodeType===
qa&&a?!0:C(b)||H(b)||0===a||"number"===typeof a&&0<a&&a-1 in b}function r(b,a,c){var d,e;if(b)if(G(b))for(d in b)"prototype"==d||"length"==d||"name"==d||b.hasOwnProperty&&!b.hasOwnProperty(d)||a.call(c,b[d],d,b);else if(H(b)||Sa(b)){var f="object"!==typeof b;d=0;for(e=b.length;d<e;d++)(f||d in b)&&a.call(c,b[d],d,b)}else if(b.forEach&&b.forEach!==r)b.forEach(a,c,b);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d,b);return b}function Ed(b,a,c){for(var d=Object.keys(b).sort(),e=0;e<d.length;e++)a.call(c,
b[d[e]],d[e]);return d}function mc(b){return function(a,c){b(c,a)}}function Fd(){return++ob}function nc(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function w(b){for(var a=b.$$hashKey,c=1,d=arguments.length;c<d;c++){var e=arguments[c];if(e)for(var f=Object.keys(e),g=0,h=f.length;g<h;g++){var l=f[g];b[l]=e[l]}}nc(b,a);return b}function aa(b){return parseInt(b,10)}function Ob(b,a){return w(Object.create(b),a)}function E(){}function ra(b){return b}function ea(b){return function(){return b}}function x(b){return"undefined"===
typeof b}function y(b){return"undefined"!==typeof b}function J(b){return null!==b&&"object"===typeof b}function C(b){return"string"===typeof b}function Y(b){return"number"===typeof b}function ga(b){return"[object Date]"===Ca.call(b)}function G(b){return"function"===typeof b}function Ua(b){return"[object RegExp]"===Ca.call(b)}function Ta(b){return b&&b.window===b}function Va(b){return b&&b.$evalAsync&&b.$watch}function Wa(b){return"boolean"===typeof b}function oc(b){return!(!b||!(b.nodeName||b.prop&&
b.attr&&b.find))}function Gd(b){var a={};b=b.split(",");var c;for(c=0;c<b.length;c++)a[b[c]]=!0;return a}function va(b){return z(b.nodeName||b[0]&&b[0].nodeName)}function Xa(b,a){var c=b.indexOf(a);0<=c&&b.splice(c,1);return a}function Da(b,a,c,d){if(Ta(b)||Va(b))throw Ja("cpws");if(a){if(b===a)throw Ja("cpi");c=c||[];d=d||[];if(J(b)){var e=c.indexOf(b);if(-1!==e)return d[e];c.push(b);d.push(a)}if(H(b))for(var f=a.length=0;f<b.length;f++)e=Da(b[f],null,c,d),J(b[f])&&(c.push(b[f]),d.push(e)),a.push(e);
else{var g=a.$$hashKey;H(a)?a.length=0:r(a,function(b,c){delete a[c]});for(f in b)b.hasOwnProperty(f)&&(e=Da(b[f],null,c,d),J(b[f])&&(c.push(b[f]),d.push(e)),a[f]=e);nc(a,g)}}else if(a=b)H(b)?a=Da(b,[],c,d):ga(b)?a=new Date(b.getTime()):Ua(b)?(a=new RegExp(b.source,b.toString().match(/[^\/]*$/)[0]),a.lastIndex=b.lastIndex):J(b)&&(e=Object.create(Object.getPrototypeOf(b)),a=Da(b,e,c,d));return a}function sa(b,a){if(H(b)){a=a||[];for(var c=0,d=b.length;c<d;c++)a[c]=b[c]}else if(J(b))for(c in a=a||{},
b)if("$"!==c.charAt(0)||"$"!==c.charAt(1))a[c]=b[c];return a||b}function ha(b,a){if(b===a)return!0;if(null===b||null===a)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&"object"==c)if(H(b)){if(!H(a))return!1;if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ha(b[d],a[d]))return!1;return!0}}else{if(ga(b))return ga(a)?ha(b.getTime(),a.getTime()):!1;if(Ua(b))return Ua(a)?b.toString()==a.toString():!1;if(Va(b)||Va(a)||Ta(b)||Ta(a)||H(a)||ga(a)||Ua(a))return!1;c={};for(d in b)if("$"!==
d.charAt(0)&&!G(b[d])){if(!ha(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c.hasOwnProperty(d)&&"$"!==d.charAt(0)&&a[d]!==t&&!G(a[d]))return!1;return!0}return!1}function Ya(b,a,c){return b.concat(Za.call(a,c))}function pc(b,a){var c=2<arguments.length?Za.call(arguments,2):[];return!G(a)||a instanceof RegExp?a:c.length?function(){return arguments.length?a.apply(b,Ya(c,arguments,0)):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}}function Hd(b,a){var c=a;"string"===typeof b&&
"$"===b.charAt(0)&&"$"===b.charAt(1)?c=t:Ta(a)?c="$WINDOW":a&&W===a?c="$DOCUMENT":Va(a)&&(c="$SCOPE");return c}function $a(b,a){if("undefined"===typeof b)return t;Y(a)||(a=a?2:null);return JSON.stringify(b,Hd,a)}function qc(b){return C(b)?JSON.parse(b):b}function wa(b){b=A(b).clone();try{b.empty()}catch(a){}var c=A("<div>").append(b).html();try{return b[0].nodeType===pb?z(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+z(b)})}catch(d){return z(c)}}function rc(b){try{return decodeURIComponent(b)}catch(a){}}
function sc(b){var a={},c,d;r((b||"").split("&"),function(b){b&&(c=b.replace(/\+/g,"%20").split("="),d=rc(c[0]),y(d)&&(b=y(c[1])?rc(c[1]):!0,tc.call(a,d)?H(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Pb(b){var a=[];r(b,function(b,d){H(b)?r(b,function(b){a.push(Ea(d,!0)+(!0===b?"":"="+Ea(b,!0)))}):a.push(Ea(d,!0)+(!0===b?"":"="+Ea(b,!0)))});return a.length?a.join("&"):""}function qb(b){return Ea(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function Ea(b,a){return encodeURIComponent(b).replace(/%40/gi,
"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,a?"%20":"+")}function Id(b,a){var c,d,e=rb.length;b=A(b);for(d=0;d<e;++d)if(c=rb[d]+a,C(c=b.attr(c)))return c;return null}function Jd(b,a){var c,d,e={};r(rb,function(a){a+="app";!c&&b.hasAttribute&&b.hasAttribute(a)&&(c=b,d=b.getAttribute(a))});r(rb,function(a){a+="app";var e;!c&&(e=b.querySelector("["+a.replace(":","\\:")+"]"))&&(c=e,d=e.getAttribute(a))});c&&(e.strictDi=null!==Id(c,"strict-di"),
a(c,d?[d]:[],e))}function uc(b,a,c){J(c)||(c={});c=w({strictDi:!1},c);var d=function(){b=A(b);if(b.injector()){var d=b[0]===W?"document":wa(b);throw Ja("btstrpd",d.replace(/</,"&lt;").replace(/>/,"&gt;"));}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);c.debugInfoEnabled&&a.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);a.unshift("ng");d=ab(a,c.strictDi);d.invoke(["$rootScope","$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",
d);c(b)(a)})}]);return d},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;Q&&e.test(Q.name)&&(c.debugInfoEnabled=!0,Q.name=Q.name.replace(e,""));if(Q&&!f.test(Q.name))return d();Q.name=Q.name.replace(f,"");ca.resumeBootstrap=function(b){r(b,function(b){a.push(b)});return d()};G(ca.resumeDeferredBootstrap)&&ca.resumeDeferredBootstrap()}function Kd(){Q.name="NG_ENABLE_DEBUG_INFO!"+Q.name;Q.location.reload()}function Ld(b){b=ca.element(b).injector();if(!b)throw Ja("test");return b.get("$$testability")}
function vc(b,a){a=a||"_";return b.replace(Md,function(b,d){return(d?a:"")+b.toLowerCase()})}function Nd(){var b;wc||((ta=Q.jQuery)&&ta.fn.on?(A=ta,w(ta.fn,{scope:Ka.scope,isolateScope:Ka.isolateScope,controller:Ka.controller,injector:Ka.injector,inheritedData:Ka.inheritedData}),b=ta.cleanData,ta.cleanData=function(a){var c;if(Qb)Qb=!1;else for(var d=0,e;null!=(e=a[d]);d++)(c=ta._data(e,"events"))&&c.$destroy&&ta(e).triggerHandler("$destroy");b(a)}):A=T,ca.element=A,wc=!0)}function Rb(b,a,c){if(!b)throw Ja("areq",
a||"?",c||"required");return b}function sb(b,a,c){c&&H(b)&&(b=b[b.length-1]);Rb(G(b),a,"not a function, got "+(b&&"object"===typeof b?b.constructor.name||"Object":typeof b));return b}function La(b,a){if("hasOwnProperty"===b)throw Ja("badname",a);}function xc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,f=a.length,g=0;g<f;g++)d=a[g],b&&(b=(e=b)[d]);return!c&&G(b)?pc(e,b):b}function tb(b){var a=b[0];b=b[b.length-1];var c=[a];do{a=a.nextSibling;if(!a)break;c.push(a)}while(a!==b);return A(c)}function ia(){return Object.create(null)}
function Od(b){function a(a,b,c){return a[b]||(a[b]=c())}var c=R("$injector"),d=R("ng");b=a(b,"angular",Object);b.$$minErr=b.$$minErr||R;return a(b,"module",function(){var b={};return function(f,g,h){if("hasOwnProperty"===f)throw d("badname","module");g&&b.hasOwnProperty(f)&&(b[f]=null);return a(b,f,function(){function a(c,d,e,f){f||(f=b);return function(){f[e||"push"]([c,d,arguments]);return u}}if(!g)throw c("nomod",f);var b=[],d=[],e=[],q=a("$injector","invoke","push",d),u={_invokeQueue:b,_configBlocks:d,
_runBlocks:e,requires:g,name:f,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animateProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider","directive"),config:q,run:function(a){e.push(a);return this}};h&&q(h);return u})}})}function Pd(b){w(b,{bootstrap:uc,copy:Da,extend:w,equals:ha,
element:A,forEach:r,injector:ab,noop:E,bind:pc,toJson:$a,fromJson:qc,identity:ra,isUndefined:x,isDefined:y,isString:C,isFunction:G,isObject:J,isNumber:Y,isElement:oc,isArray:H,version:Qd,isDate:ga,lowercase:z,uppercase:ub,callbacks:{counter:0},getTestability:Ld,$$minErr:R,$$csp:bb,reloadWithDebugInfo:Kd});cb=Od(Q);try{cb("ngLocale")}catch(a){cb("ngLocale",[]).provider("$locale",Rd)}cb("ng",["ngLocale"],["$provide",function(a){a.provider({$$sanitizeUri:Sd});a.provider("$compile",yc).directive({a:Td,
input:zc,textarea:zc,form:Ud,script:Vd,select:Wd,style:Xd,option:Yd,ngBind:Zd,ngBindHtml:$d,ngBindTemplate:ae,ngClass:be,ngClassEven:ce,ngClassOdd:de,ngCloak:ee,ngController:fe,ngForm:ge,ngHide:he,ngIf:ie,ngInclude:je,ngInit:ke,ngNonBindable:le,ngPluralize:me,ngRepeat:ne,ngShow:oe,ngStyle:pe,ngSwitch:qe,ngSwitchWhen:re,ngSwitchDefault:se,ngOptions:te,ngTransclude:ue,ngModel:ve,ngList:we,ngChange:xe,pattern:Ac,ngPattern:Ac,required:Bc,ngRequired:Bc,minlength:Cc,ngMinlength:Cc,maxlength:Dc,ngMaxlength:Dc,
ngValue:ye,ngModelOptions:ze}).directive({ngInclude:Ae}).directive(vb).directive(Ec);a.provider({$anchorScroll:Be,$animate:Ce,$browser:De,$cacheFactory:Ee,$controller:Fe,$document:Ge,$exceptionHandler:He,$filter:Fc,$interpolate:Ie,$interval:Je,$http:Ke,$httpBackend:Le,$location:Me,$log:Ne,$parse:Oe,$rootScope:Pe,$q:Qe,$$q:Re,$sce:Se,$sceDelegate:Te,$sniffer:Ue,$templateCache:Ve,$templateRequest:We,$$testability:Xe,$timeout:Ye,$window:Ze,$$rAF:$e,$$asyncCallback:af,$$jqLite:bf})}])}function db(b){return b.replace(cf,
function(a,b,d,e){return e?d.toUpperCase():d}).replace(df,"Moz$1")}function Gc(b){b=b.nodeType;return b===qa||!b||9===b}function Hc(b,a){var c,d,e=a.createDocumentFragment(),f=[];if(Sb.test(b)){c=c||e.appendChild(a.createElement("div"));d=(ef.exec(b)||["",""])[1].toLowerCase();d=ja[d]||ja._default;c.innerHTML=d[1]+b.replace(ff,"<$1></$2>")+d[2];for(d=d[0];d--;)c=c.lastChild;f=Ya(f,c.childNodes);c=e.firstChild;c.textContent=""}else f.push(a.createTextNode(b));e.textContent="";e.innerHTML="";r(f,function(a){e.appendChild(a)});
return e}function T(b){if(b instanceof T)return b;var a;C(b)&&(b=N(b),a=!0);if(!(this instanceof T)){if(a&&"<"!=b.charAt(0))throw Tb("nosel");return new T(b)}if(a){a=W;var c;b=(c=gf.exec(b))?[a.createElement(c[1])]:(c=Hc(b,a))?c.childNodes:[]}Ic(this,b)}function Ub(b){return b.cloneNode(!0)}function wb(b,a){a||xb(b);if(b.querySelectorAll)for(var c=b.querySelectorAll("*"),d=0,e=c.length;d<e;d++)xb(c[d])}function Jc(b,a,c,d){if(y(d))throw Tb("offargs");var e=(d=yb(b))&&d.events,f=d&&d.handle;if(f)if(a)r(a.split(" "),
function(a){if(y(c)){var d=e[a];Xa(d||[],c);if(d&&0<d.length)return}b.removeEventListener(a,f,!1);delete e[a]});else for(a in e)"$destroy"!==a&&b.removeEventListener(a,f,!1),delete e[a]}function xb(b,a){var c=b.ng339,d=c&&zb[c];d&&(a?delete d.data[a]:(d.handle&&(d.events.$destroy&&d.handle({},"$destroy"),Jc(b)),delete zb[c],b.ng339=t))}function yb(b,a){var c=b.ng339,c=c&&zb[c];a&&!c&&(b.ng339=c=++hf,c=zb[c]={events:{},data:{},handle:t});return c}function Vb(b,a,c){if(Gc(b)){var d=y(c),e=!d&&a&&!J(a),
f=!a;b=(b=yb(b,!e))&&b.data;if(d)b[a]=c;else{if(f)return b;if(e)return b&&b[a];w(b,a)}}}function Ab(b,a){return b.getAttribute?-1<(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").indexOf(" "+a+" "):!1}function Bb(b,a){a&&b.setAttribute&&r(a.split(" "),function(a){b.setAttribute("class",N((" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ").replace(" "+N(a)+" "," ")))})}function Cb(b,a){if(a&&b.setAttribute){var c=(" "+(b.getAttribute("class")||"")+" ").replace(/[\n\t]/g," ");
r(a.split(" "),function(a){a=N(a);-1===c.indexOf(" "+a+" ")&&(c+=a+" ")});b.setAttribute("class",N(c))}}function Ic(b,a){if(a)if(a.nodeType)b[b.length++]=a;else{var c=a.length;if("number"===typeof c&&a.window!==a){if(c)for(var d=0;d<c;d++)b[b.length++]=a[d]}else b[b.length++]=a}}function Kc(b,a){return Db(b,"$"+(a||"ngController")+"Controller")}function Db(b,a,c){9==b.nodeType&&(b=b.documentElement);for(a=H(a)?a:[a];b;){for(var d=0,e=a.length;d<e;d++)if((c=A.data(b,a[d]))!==t)return c;b=b.parentNode||
11===b.nodeType&&b.host}}function Lc(b){for(wb(b,!0);b.firstChild;)b.removeChild(b.firstChild)}function Mc(b,a){a||wb(b);var c=b.parentNode;c&&c.removeChild(b)}function jf(b,a){a=a||Q;if("complete"===a.document.readyState)a.setTimeout(b);else A(a).on("load",b)}function Nc(b,a){var c=Eb[a.toLowerCase()];return c&&Oc[va(b)]&&c}function kf(b,a){var c=b.nodeName;return("INPUT"===c||"TEXTAREA"===c)&&Pc[a]}function lf(b,a){var c=function(c,e){c.isDefaultPrevented=function(){return c.defaultPrevented};var f=
a[e||c.type],g=f?f.length:0;if(g){if(x(c.immediatePropagationStopped)){var h=c.stopImmediatePropagation;c.stopImmediatePropagation=function(){c.immediatePropagationStopped=!0;c.stopPropagation&&c.stopPropagation();h&&h.call(c)}}c.isImmediatePropagationStopped=function(){return!0===c.immediatePropagationStopped};1<g&&(f=sa(f));for(var l=0;l<g;l++)c.isImmediatePropagationStopped()||f[l].call(b,c)}};c.elem=b;return c}function bf(){this.$get=function(){return w(T,{hasClass:function(b,a){b.attr&&(b=b[0]);
return Ab(b,a)},addClass:function(b,a){b.attr&&(b=b[0]);return Cb(b,a)},removeClass:function(b,a){b.attr&&(b=b[0]);return Bb(b,a)}})}}function Ma(b,a){var c=b&&b.$$hashKey;if(c)return"function"===typeof c&&(c=b.$$hashKey()),c;c=typeof b;return c="function"==c||"object"==c&&null!==b?b.$$hashKey=c+":"+(a||Fd)():c+":"+b}function eb(b,a){if(a){var c=0;this.nextUid=function(){return++c}}r(b,this.put,this)}function mf(b){return(b=b.toString().replace(Qc,"").match(Rc))?"function("+(b[1]||"").replace(/[\s\r\n]+/,
" ")+")":"fn"}function ab(b,a){function c(a){return function(b,c){if(J(b))r(b,mc(a));else return a(b,c)}}function d(a,b){La(a,"service");if(G(b)||H(b))b=q.instantiate(b);if(!b.$get)throw Fa("pget",a);return p[a+"Provider"]=b}function e(a,b){return function(){var c=s.invoke(b,this);if(x(c))throw Fa("undef",a);return c}}function f(a,b,c){return d(a,{$get:!1!==c?e(a,b):b})}function g(a){var b=[],c;r(a,function(a){function d(a){var b,c;b=0;for(c=a.length;b<c;b++){var e=a[b],f=q.get(e[0]);f[e[1]].apply(f,
e[2])}}if(!n.get(a)){n.put(a,!0);try{C(a)?(c=cb(a),b=b.concat(g(c.requires)).concat(c._runBlocks),d(c._invokeQueue),d(c._configBlocks)):G(a)?b.push(q.invoke(a)):H(a)?b.push(q.invoke(a)):sb(a,"module")}catch(e){throw H(a)&&(a=a[a.length-1]),e.message&&e.stack&&-1==e.stack.indexOf(e.message)&&(e=e.message+"\n"+e.stack),Fa("modulerr",a,e.stack||e.message||e);}}});return b}function h(b,c){function d(a,e){if(b.hasOwnProperty(a)){if(b[a]===l)throw Fa("cdep",a+" <- "+k.join(" <- "));return b[a]}try{return k.unshift(a),
b[a]=l,b[a]=c(a,e)}catch(f){throw b[a]===l&&delete b[a],f;}finally{k.shift()}}function e(b,c,f,g){"string"===typeof f&&(g=f,f=null);var k=[],h=ab.$$annotate(b,a,g),l,q,p;q=0;for(l=h.length;q<l;q++){p=h[q];if("string"!==typeof p)throw Fa("itkn",p);k.push(f&&f.hasOwnProperty(p)?f[p]:d(p,g))}H(b)&&(b=b[l]);return b.apply(c,k)}return{invoke:e,instantiate:function(a,b,c){var d=Object.create((H(a)?a[a.length-1]:a).prototype||null);a=e(a,d,b,c);return J(a)||G(a)?a:d},get:d,annotate:ab.$$annotate,has:function(a){return p.hasOwnProperty(a+
"Provider")||b.hasOwnProperty(a)}}}a=!0===a;var l={},k=[],n=new eb([],!0),p={$provide:{provider:c(d),factory:c(f),service:c(function(a,b){return f(a,["$injector",function(a){return a.instantiate(b)}])}),value:c(function(a,b){return f(a,ea(b),!1)}),constant:c(function(a,b){La(a,"constant");p[a]=b;u[a]=b}),decorator:function(a,b){var c=q.get(a+"Provider"),d=c.$get;c.$get=function(){var a=s.invoke(d,c);return s.invoke(b,null,{$delegate:a})}}}},q=p.$injector=h(p,function(a,b){ca.isString(b)&&k.push(b);
throw Fa("unpr",k.join(" <- "));}),u={},s=u.$injector=h(u,function(a,b){var c=q.get(a+"Provider",b);return s.invoke(c.$get,c,t,a)});r(g(b),function(a){s.invoke(a||E)});return s}function Be(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;Array.prototype.some.call(a,function(a){if("a"===va(a))return b=a,!0});return b}function f(b){if(b){b.scrollIntoView();var c;c=g.yOffset;G(c)?c=c():oc(c)?(c=c[0],c="fixed"!==
a.getComputedStyle(c).position?0:c.getBoundingClientRect().bottom):Y(c)||(c=0);c&&(b=b.getBoundingClientRect().top,a.scrollBy(0,b-c))}else a.scrollTo(0,0)}function g(){var a=c.hash(),b;a?(b=h.getElementById(a))?f(b):(b=e(h.getElementsByName(a)))?f(b):"top"===a&&f(null):f(null)}var h=a.document;b&&d.$watch(function(){return c.hash()},function(a,b){a===b&&""===a||jf(function(){d.$evalAsync(g)})});return g}]}function af(){this.$get=["$$rAF","$timeout",function(b,a){return b.supported?function(a){return b(a)}:
function(b){return a(b,0,!1)}}]}function nf(b,a,c,d){function e(a){try{a.apply(null,Za.call(arguments,1))}finally{if(m--,0===m)for(;F.length;)try{F.pop()()}catch(b){c.error(b)}}}function f(a,b){(function da(){r(Z,function(a){a()});L=b(da,a)})()}function g(){h();l()}function h(){a:{try{B=u.state;break a}catch(a){}B=void 0}B=x(B)?null:B;ha(B,O)&&(B=O);O=B}function l(){if(D!==n.url()||I!==B)D=n.url(),I=B,r(X,function(a){a(n.url(),B)})}function k(a){try{return decodeURIComponent(a)}catch(b){return a}}
var n=this,p=a[0],q=b.location,u=b.history,s=b.setTimeout,M=b.clearTimeout,v={};n.isMock=!1;var m=0,F=[];n.$$completeOutstandingRequest=e;n.$$incOutstandingRequestCount=function(){m++};n.notifyWhenNoOutstandingRequests=function(a){r(Z,function(a){a()});0===m?a():F.push(a)};var Z=[],L;n.addPollFn=function(a){x(L)&&f(100,s);Z.push(a);return a};var B,I,D=q.href,S=a.find("base"),P=null;h();I=B;n.url=function(a,c,e){x(e)&&(e=null);q!==b.location&&(q=b.location);u!==b.history&&(u=b.history);if(a){var f=
I===e;if(D===a&&(!d.history||f))return n;var g=D&&Ga(D)===Ga(a);D=a;I=e;!d.history||g&&f?(g||(P=a),c?q.replace(a):g?(c=q,e=a.indexOf("#"),a=-1===e?"":a.substr(e+1),c.hash=a):q.href=a):(u[c?"replaceState":"pushState"](e,"",a),h(),I=B);return n}return P||q.href.replace(/%27/g,"'")};n.state=function(){return B};var X=[],ba=!1,O=null;n.onUrlChange=function(a){if(!ba){if(d.history)A(b).on("popstate",g);A(b).on("hashchange",g);ba=!0}X.push(a);return a};n.$$checkUrlChange=l;n.baseHref=function(){var a=S.attr("href");
return a?a.replace(/^(https?\:)?\/\/[^\/]*/,""):""};var fa={},y="",ka=n.baseHref();n.cookies=function(a,b){var d,e,f,g;if(a)b===t?p.cookie=encodeURIComponent(a)+"=;path="+ka+";expires=Thu, 01 Jan 1970 00:00:00 GMT":C(b)&&(d=(p.cookie=encodeURIComponent(a)+"="+encodeURIComponent(b)+";path="+ka).length+1,4096<d&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!"));else{if(p.cookie!==y)for(y=p.cookie,d=y.split("; "),fa={},f=0;f<d.length;f++)e=d[f],g=
e.indexOf("="),0<g&&(a=k(e.substring(0,g)),fa[a]===t&&(fa[a]=k(e.substring(g+1))));return fa}};n.defer=function(a,b){var c;m++;c=s(function(){delete v[c];e(a)},b||0);v[c]=!0;return c};n.defer.cancel=function(a){return v[a]?(delete v[a],M(a),e(E),!0):!1}}function De(){this.$get=["$window","$log","$sniffer","$document",function(b,a,c,d){return new nf(b,d,a,c)}]}function Ee(){this.$get=function(){function b(b,d){function e(a){a!=p&&(q?q==a&&(q=a.n):q=a,f(a.n,a.p),f(a,p),p=a,p.n=null)}function f(a,b){a!=
b&&(a&&(a.p=b),b&&(b.n=a))}if(b in a)throw R("$cacheFactory")("iid",b);var g=0,h=w({},d,{id:b}),l={},k=d&&d.capacity||Number.MAX_VALUE,n={},p=null,q=null;return a[b]={put:function(a,b){if(k<Number.MAX_VALUE){var c=n[a]||(n[a]={key:a});e(c)}if(!x(b))return a in l||g++,l[a]=b,g>k&&this.remove(q.key),b},get:function(a){if(k<Number.MAX_VALUE){var b=n[a];if(!b)return;e(b)}return l[a]},remove:function(a){if(k<Number.MAX_VALUE){var b=n[a];if(!b)return;b==p&&(p=b.p);b==q&&(q=b.n);f(b.n,b.p);delete n[a]}delete l[a];
g--},removeAll:function(){l={};g=0;n={};p=q=null},destroy:function(){n=h=l=null;delete a[b]},info:function(){return w({},h,{size:g})}}}var a={};b.info=function(){var b={};r(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function Ve(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function yc(b,a){function c(a,b){var c=/^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/,d={};r(a,function(a,e){var f=a.match(c);if(!f)throw la("iscp",b,e,a);d[e]={mode:f[1][0],collection:"*"===
f[2],optional:"?"===f[3],attrName:f[4]||e}});return d}var d={},e=/^\s*directive\:\s*([\w\-]+)\s+(.*)$/,f=/(([\w\-]+)(?:\:([^;]+))?;?)/,g=Gd("ngSrc,ngSrcset,src,srcset"),h=/^(?:(\^\^?)?(\?)?(\^\^?)?)?/,l=/^(on[a-z]+|formaction)$/;this.directive=function p(a,e){La(a,"directive");C(a)?(Rb(e,"directiveFactory"),d.hasOwnProperty(a)||(d[a]=[],b.factory(a+"Directive",["$injector","$exceptionHandler",function(b,e){var f=[];r(d[a],function(d,g){try{var h=b.invoke(d);G(h)?h={compile:ea(h)}:!h.compile&&h.link&&
(h.compile=ea(h.link));h.priority=h.priority||0;h.index=g;h.name=h.name||a;h.require=h.require||h.controller&&h.name;h.restrict=h.restrict||"EA";J(h.scope)&&(h.$$isolateBindings=c(h.scope,h.name));f.push(h)}catch(k){e(k)}});return f}])),d[a].push(e)):r(a,mc(p));return this};this.aHrefSanitizationWhitelist=function(b){return y(b)?(a.aHrefSanitizationWhitelist(b),this):a.aHrefSanitizationWhitelist()};this.imgSrcSanitizationWhitelist=function(b){return y(b)?(a.imgSrcSanitizationWhitelist(b),this):a.imgSrcSanitizationWhitelist()};
var k=!0;this.debugInfoEnabled=function(a){return y(a)?(k=a,this):k};this.$get=["$injector","$interpolate","$exceptionHandler","$templateRequest","$parse","$controller","$rootScope","$document","$sce","$animate","$$sanitizeUri",function(a,b,c,s,M,v,m,F,Z,L,B){function I(a,b){try{a.addClass(b)}catch(c){}}function D(a,b,c,d,e){a instanceof A||(a=A(a));r(a,function(b,c){b.nodeType==pb&&b.nodeValue.match(/\S+/)&&(a[c]=A(b).wrap("<span></span>").parent()[0])});var f=S(a,b,a,c,d,e);D.$$addScopeClass(a);
var g=null;return function(b,c,d){Rb(b,"scope");d=d||{};var e=d.parentBoundTranscludeFn,h=d.transcludeControllers;d=d.futureParentElement;e&&e.$$boundTransclude&&(e=e.$$boundTransclude);g||(g=(d=d&&d[0])?"foreignobject"!==va(d)&&d.toString().match(/SVG/)?"svg":"html":"html");d="html"!==g?A(Xb(g,A("<div>").append(a).html())):c?Ka.clone.call(a):a;if(h)for(var k in h)d.data("$"+k+"Controller",h[k].instance);D.$$addScopeInfo(d,b);c&&c(d,b);f&&f(b,d,d,e);return d}}function S(a,b,c,d,e,f){function g(a,
c,d,e){var f,k,l,q,p,s,M;if(m)for(M=Array(c.length),q=0;q<h.length;q+=3)f=h[q],M[f]=c[f];else M=c;q=0;for(p=h.length;q<p;)k=M[h[q++]],c=h[q++],f=h[q++],c?(c.scope?(l=a.$new(),D.$$addScopeInfo(A(k),l)):l=a,s=c.transcludeOnThisElement?P(a,c.transclude,e,c.elementTranscludeOnThisElement):!c.templateOnThisElement&&e?e:!e&&b?P(a,b):null,c(f,l,k,d,s)):f&&f(a,k.childNodes,t,e)}for(var h=[],k,l,q,p,m,s=0;s<a.length;s++){k=new Yb;l=X(a[s],[],k,0===s?d:t,e);(f=l.length?fa(l,a[s],k,b,c,null,[],[],f):null)&&
f.scope&&D.$$addScopeClass(k.$$element);k=f&&f.terminal||!(q=a[s].childNodes)||!q.length?null:S(q,f?(f.transcludeOnThisElement||!f.templateOnThisElement)&&f.transclude:b);if(f||k)h.push(s,f,k),p=!0,m=m||f;f=null}return p?g:null}function P(a,b,c,d){return function(d,e,f,g,h){d||(d=a.$new(!1,h),d.$$transcluded=!0);return b(d,e,{parentBoundTranscludeFn:c,transcludeControllers:f,futureParentElement:g})}}function X(a,b,c,d,g){var h=c.$attr,k;switch(a.nodeType){case qa:ka(b,xa(va(a)),"E",d,g);for(var l,
q,p,m=a.attributes,s=0,M=m&&m.length;s<M;s++){var u=!1,L=!1;l=m[s];k=l.name;q=N(l.value);l=xa(k);if(p=U.test(l))k=k.replace(Sc,"").substr(8).replace(/_(.)/g,function(a,b){return b.toUpperCase()});var B=l.replace(/(Start|End)$/,"");x(B)&&l===B+"Start"&&(u=k,L=k.substr(0,k.length-5)+"end",k=k.substr(0,k.length-6));l=xa(k.toLowerCase());h[l]=k;if(p||!c.hasOwnProperty(l))c[l]=q,Nc(a,l)&&(c[l]=!0);Oa(a,b,q,l,p);ka(b,l,"A",d,g,u,L)}a=a.className;J(a)&&(a=a.animVal);if(C(a)&&""!==a)for(;k=f.exec(a);)l=xa(k[2]),
ka(b,l,"C",d,g)&&(c[l]=N(k[3])),a=a.substr(k.index+k[0].length);break;case pb:za(b,a.nodeValue);break;case 8:try{if(k=e.exec(a.nodeValue))l=xa(k[1]),ka(b,l,"M",d,g)&&(c[l]=N(k[2]))}catch(v){}}b.sort(da);return b}function ba(a,b,c){var d=[],e=0;if(b&&a.hasAttribute&&a.hasAttribute(b)){do{if(!a)throw la("uterdir",b,c);a.nodeType==qa&&(a.hasAttribute(b)&&e++,a.hasAttribute(c)&&e--);d.push(a);a=a.nextSibling}while(0<e)}else d.push(a);return A(d)}function O(a,b,c){return function(d,e,f,g,h){e=ba(e[0],
b,c);return a(d,e,f,g,h)}}function fa(a,d,e,f,g,k,l,p,m){function s(a,b,c,d){if(a){c&&(a=O(a,c,d));a.require=K.require;a.directiveName=da;if(P===K||K.$$isolateScope)a=Y(a,{isolateScope:!0});l.push(a)}if(b){c&&(b=O(b,c,d));b.require=K.require;b.directiveName=da;if(P===K||K.$$isolateScope)b=Y(b,{isolateScope:!0});p.push(b)}}function L(a,b,c,d){var e,f="data",g=!1,k=c,l;if(C(b)){l=b.match(h);b=b.substring(l[0].length);l[3]&&(l[1]?l[3]=null:l[1]=l[3]);"^"===l[1]?f="inheritedData":"^^"===l[1]&&(f="inheritedData",
k=c.parent());"?"===l[2]&&(g=!0);e=null;d&&"data"===f&&(e=d[b])&&(e=e.instance);e=e||k[f]("$"+b+"Controller");if(!e&&!g)throw la("ctreq",b,a);return e||null}H(b)&&(e=[],r(b,function(b){e.push(L(a,b,c,d))}));return e}function B(a,c,f,g,h){function k(a,b,c){var d;Va(a)||(c=b,b=a,a=t);E&&(d=F);c||(c=E?X.parent():X);return h(a,b,d,c,Wb)}var m,s,u,I,F,gb,X,O;d===f?(O=e,X=e.$$element):(X=A(f),O=new Yb(X,e));P&&(I=c.$new(!0));h&&(gb=k,gb.$$boundTransclude=h);S&&(Z={},F={},r(S,function(a){var b={$scope:a===
P||a.$$isolateScope?I:c,$element:X,$attrs:O,$transclude:gb};u=a.controller;"@"==u&&(u=O[a.name]);b=v(u,b,!0,a.controllerAs);F[a.name]=b;E||X.data("$"+a.name+"Controller",b.instance);Z[a.name]=b}));if(P){D.$$addScopeInfo(X,I,!0,!(ma&&(ma===P||ma===P.$$originalDirective)));D.$$addScopeClass(X,!0);g=Z&&Z[P.name];var ba=I;g&&g.identifier&&!0===P.bindToController&&(ba=g.instance);r(I.$$isolateBindings=P.$$isolateBindings,function(a,d){var e=a.attrName,f=a.optional,g,h,k,l;switch(a.mode){case "@":O.$observe(e,
function(a){ba[d]=a});O.$$observers[e].$$scope=c;O[e]&&(ba[d]=b(O[e])(c));break;case "=":if(f&&!O[e])break;h=M(O[e]);l=h.literal?ha:function(a,b){return a===b||a!==a&&b!==b};k=h.assign||function(){g=ba[d]=h(c);throw la("nonassign",O[e],P.name);};g=ba[d]=h(c);f=function(a){l(a,ba[d])||(l(a,g)?k(c,a=ba[d]):ba[d]=a);return g=a};f.$stateful=!0;f=a.collection?c.$watchCollection(O[e],f):c.$watch(M(O[e],f),null,h.literal);I.$on("$destroy",f);break;case "&":h=M(O[e]),ba[d]=function(a){return h(c,a)}}})}Z&&
(r(Z,function(a){a()}),Z=null);g=0;for(m=l.length;g<m;g++)s=l[g],$(s,s.isolateScope?I:c,X,O,s.require&&L(s.directiveName,s.require,X,F),gb);var Wb=c;P&&(P.template||null===P.templateUrl)&&(Wb=I);a&&a(Wb,f.childNodes,t,h);for(g=p.length-1;0<=g;g--)s=p[g],$(s,s.isolateScope?I:c,X,O,s.require&&L(s.directiveName,s.require,X,F),gb)}m=m||{};for(var I=-Number.MAX_VALUE,F,S=m.controllerDirectives,Z,P=m.newIsolateScopeDirective,ma=m.templateDirective,fa=m.nonTlbTranscludeDirective,ka=!1,x=!1,E=m.hasElementTranscludeDirective,
w=e.$$element=A(d),K,da,V,fb=f,za,z=0,Q=a.length;z<Q;z++){K=a[z];var Oa=K.$$start,U=K.$$end;Oa&&(w=ba(d,Oa,U));V=t;if(I>K.priority)break;if(V=K.scope)K.templateUrl||(J(V)?(Na("new/isolated scope",P||F,K,w),P=K):Na("new/isolated scope",P,K,w)),F=F||K;da=K.name;!K.templateUrl&&K.controller&&(V=K.controller,S=S||{},Na("'"+da+"' controller",S[da],K,w),S[da]=K);if(V=K.transclude)ka=!0,K.$$tlb||(Na("transclusion",fa,K,w),fa=K),"element"==V?(E=!0,I=K.priority,V=w,w=e.$$element=A(W.createComment(" "+da+": "+
e[da]+" ")),d=w[0],T(g,Za.call(V,0),d),fb=D(V,f,I,k&&k.name,{nonTlbTranscludeDirective:fa})):(V=A(Ub(d)).contents(),w.empty(),fb=D(V,f));if(K.template)if(x=!0,Na("template",ma,K,w),ma=K,V=G(K.template)?K.template(w,e):K.template,V=Tc(V),K.replace){k=K;V=Sb.test(V)?Uc(Xb(K.templateNamespace,N(V))):[];d=V[0];if(1!=V.length||d.nodeType!==qa)throw la("tplrt",da,"");T(g,w,d);Q={$attr:{}};V=X(d,[],Q);var aa=a.splice(z+1,a.length-(z+1));P&&y(V);a=a.concat(V).concat(aa);R(e,Q);Q=a.length}else w.html(V);if(K.templateUrl)x=
!0,Na("template",ma,K,w),ma=K,K.replace&&(k=K),B=of(a.splice(z,a.length-z),w,e,g,ka&&fb,l,p,{controllerDirectives:S,newIsolateScopeDirective:P,templateDirective:ma,nonTlbTranscludeDirective:fa}),Q=a.length;else if(K.compile)try{za=K.compile(w,e,fb),G(za)?s(null,za,Oa,U):za&&s(za.pre,za.post,Oa,U)}catch(pf){c(pf,wa(w))}K.terminal&&(B.terminal=!0,I=Math.max(I,K.priority))}B.scope=F&&!0===F.scope;B.transcludeOnThisElement=ka;B.elementTranscludeOnThisElement=E;B.templateOnThisElement=x;B.transclude=fb;
m.hasElementTranscludeDirective=E;return B}function y(a){for(var b=0,c=a.length;b<c;b++)a[b]=Ob(a[b],{$$isolateScope:!0})}function ka(b,e,f,g,h,k,l){if(e===h)return null;h=null;if(d.hasOwnProperty(e)){var q;e=a.get(e+"Directive");for(var m=0,s=e.length;m<s;m++)try{q=e[m],(g===t||g>q.priority)&&-1!=q.restrict.indexOf(f)&&(k&&(q=Ob(q,{$$start:k,$$end:l})),b.push(q),h=q)}catch(M){c(M)}}return h}function x(b){if(d.hasOwnProperty(b))for(var c=a.get(b+"Directive"),e=0,f=c.length;e<f;e++)if(b=c[e],b.multiElement)return!0;
return!1}function R(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;r(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&b[e]!==d&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});r(b,function(b,f){"class"==f?(I(e,b),a["class"]=(a["class"]?a["class"]+" ":"")+b):"style"==f?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==f.charAt(0)||a.hasOwnProperty(f)||(a[f]=b,d[f]=c[f])})}function of(a,b,c,d,e,f,g,h){var k=[],l,q,p=b[0],m=a.shift(),M=Ob(m,{templateUrl:null,transclude:null,
replace:null,$$originalDirective:m}),u=G(m.templateUrl)?m.templateUrl(b,c):m.templateUrl,L=m.templateNamespace;b.empty();s(Z.getTrustedResourceUrl(u)).then(function(s){var B,v;s=Tc(s);if(m.replace){s=Sb.test(s)?Uc(Xb(L,N(s))):[];B=s[0];if(1!=s.length||B.nodeType!==qa)throw la("tplrt",m.name,u);s={$attr:{}};T(d,b,B);var D=X(B,[],s);J(m.scope)&&y(D);a=D.concat(a);R(c,s)}else B=p,b.html(s);a.unshift(M);l=fa(a,B,c,e,b,m,f,g,h);r(d,function(a,c){a==B&&(d[c]=b[0])});for(q=S(b[0].childNodes,e);k.length;){s=
k.shift();v=k.shift();var F=k.shift(),O=k.shift(),D=b[0];if(!s.$$destroyed){if(v!==p){var Z=v.className;h.hasElementTranscludeDirective&&m.replace||(D=Ub(B));T(F,A(v),D);I(A(D),Z)}v=l.transcludeOnThisElement?P(s,l.transclude,O):O;l(q,s,D,d,v)}}k=null});return function(a,b,c,d,e){a=e;b.$$destroyed||(k?k.push(b,c,d,a):(l.transcludeOnThisElement&&(a=P(b,l.transclude,e)),l(q,b,c,d,a)))}}function da(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.name<b.name?-1:1:a.index-b.index}function Na(a,
b,c,d){if(b)throw la("multidir",b.name,c.name,a,wa(d));}function za(a,c){var d=b(c,!0);d&&a.push({priority:0,compile:function(a){a=a.parent();var b=!!a.length;b&&D.$$addBindingClass(a);return function(a,c){var e=c.parent();b||D.$$addBindingClass(e);D.$$addBindingInfo(e,d.expressions);a.$watch(d,function(a){c[0].nodeValue=a})}}})}function Xb(a,b){a=z(a||"html");switch(a){case "svg":case "math":var c=W.createElement("div");c.innerHTML="<"+a+">"+b+"</"+a+">";return c.childNodes[0].childNodes;default:return b}}
function Q(a,b){if("srcdoc"==b)return Z.HTML;var c=va(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return Z.RESOURCE_URL}function Oa(a,c,d,e,f){var h=Q(a,e);f=g[e]||f;var k=b(d,!0,h,f);if(k){if("multiple"===e&&"select"===va(a))throw la("selmulti",wa(a));c.push({priority:100,compile:function(){return{pre:function(a,c,g){c=g.$$observers||(g.$$observers={});if(l.test(e))throw la("nodomevents");var m=g[e];m!==d&&(k=m&&b(m,!0,h,f),d=m);k&&(g[e]=k(a),(c[e]||(c[e]=[])).$$inter=
!0,(g.$$observers&&g.$$observers[e].$$scope||a).$watch(k,function(a,b){"class"===e&&a!=b?g.$updateClass(a,b):g.$set(e,a)}))}}}})}}function T(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g<h;g++)if(a[g]==d){a[g++]=c;h=g+e-1;for(var k=a.length;g<k;g++,h++)h<k?a[g]=a[h]:delete a[g];a.length-=e-1;a.context===d&&(a.context=c);break}f&&f.replaceChild(c,d);a=W.createDocumentFragment();a.appendChild(d);A(c).data(A(d).data());ta?(Qb=!0,ta.cleanData([d])):delete A.cache[d[A.expando]];
d=1;for(e=b.length;d<e;d++)f=b[d],A(f).remove(),a.appendChild(f),delete b[d];b[0]=c;b.length=1}function Y(a,b){return w(function(){return a.apply(null,arguments)},a,b)}function $(a,b,d,e,f,g){try{a(b,d,e,f,g)}catch(h){c(h,wa(d))}}var Yb=function(a,b){if(b){var c=Object.keys(b),d,e,f;d=0;for(e=c.length;d<e;d++)f=c[d],this[f]=b[f]}else this.$attr={};this.$$element=a};Yb.prototype={$normalize:xa,$addClass:function(a){a&&0<a.length&&L.addClass(this.$$element,a)},$removeClass:function(a){a&&0<a.length&&
L.removeClass(this.$$element,a)},$updateClass:function(a,b){var c=Vc(a,b);c&&c.length&&L.addClass(this.$$element,c);(c=Vc(b,a))&&c.length&&L.removeClass(this.$$element,c)},$set:function(a,b,d,e){var f=this.$$element[0],g=Nc(f,a),h=kf(f,a),f=a;g?(this.$$element.prop(a,b),e=g):h&&(this[h]=b,f=h);this[a]=b;e?this.$attr[a]=e:(e=this.$attr[a])||(this.$attr[a]=e=vc(a,"-"));g=va(this.$$element);if("a"===g&&"href"===a||"img"===g&&"src"===a)this[a]=b=B(b,"src"===a);else if("img"===g&&"srcset"===a){for(var g=
"",h=N(b),k=/(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/,k=/\s/.test(h)?k:/(,)/,h=h.split(k),k=Math.floor(h.length/2),l=0;l<k;l++)var q=2*l,g=g+B(N(h[q]),!0),g=g+(" "+N(h[q+1]));h=N(h[2*l]).split(/\s/);g+=B(N(h[0]),!0);2===h.length&&(g+=" "+N(h[1]));this[a]=b=g}!1!==d&&(null===b||b===t?this.$$element.removeAttr(e):this.$$element.attr(e,b));(a=this.$$observers)&&r(a[f],function(a){try{a(b)}catch(d){c(d)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers=ia()),e=d[a]||(d[a]=[]);e.push(b);
m.$evalAsync(function(){!e.$$inter&&c.hasOwnProperty(a)&&b(c[a])});return function(){Xa(e,b)}}};var V=b.startSymbol(),ma=b.endSymbol(),Tc="{{"==V||"}}"==ma?ra:function(a){return a.replace(/\{\{/g,V).replace(/}}/g,ma)},U=/^ngAttr[A-Z]/;D.$$addBindingInfo=k?function(a,b){var c=a.data("$binding")||[];H(b)?c=c.concat(b):c.push(b);a.data("$binding",c)}:E;D.$$addBindingClass=k?function(a){I(a,"ng-binding")}:E;D.$$addScopeInfo=k?function(a,b,c,d){a.data(c?d?"$isolateScopeNoTemplate":"$isolateScope":"$scope",
b)}:E;D.$$addScopeClass=k?function(a,b){I(a,b?"ng-isolate-scope":"ng-scope")}:E;return D}]}function xa(b){return db(b.replace(Sc,""))}function Vc(b,a){var c="",d=b.split(/\s+/),e=a.split(/\s+/),f=0;a:for(;f<d.length;f++){for(var g=d[f],h=0;h<e.length;h++)if(g==e[h])continue a;c+=(0<c.length?" ":"")+g}return c}function Uc(b){b=A(b);var a=b.length;if(1>=a)return b;for(;a--;)8===b[a].nodeType&&qf.call(b,a,1);return b}function Fe(){var b={},a=!1,c=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,c){La(a,
"controller");J(a)?w(b,a):b[a]=c};this.allowGlobals=function(){a=!0};this.$get=["$injector","$window",function(d,e){function f(a,b,c,d){if(!a||!J(a.$scope))throw R("$controller")("noscp",d,b);a.$scope[b]=c}return function(g,h,l,k){var n,p,q;l=!0===l;k&&C(k)&&(q=k);if(C(g)){k=g.match(c);if(!k)throw rf("ctrlfmt",g);p=k[1];q=q||k[3];g=b.hasOwnProperty(p)?b[p]:xc(h.$scope,p,!0)||(a?xc(e,p,!0):t);sb(g,p,!0)}if(l)return l=(H(g)?g[g.length-1]:g).prototype,n=Object.create(l||null),q&&f(h,q,n,p||g.name),w(function(){d.invoke(g,
n,h,p);return n},{instance:n,identifier:q});n=d.instantiate(g,h,p);q&&f(h,q,n,p||g.name);return n}}]}function Ge(){this.$get=["$window",function(b){return A(b.document)}]}function He(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Zb(b,a){if(C(b)){var c=b.replace(sf,"").trim();if(c){var d=a("Content-Type");(d=d&&0===d.indexOf(Wc))||(d=(d=c.match(tf))&&uf[d[0]].test(c));d&&(b=qc(c))}}return b}function Xc(b){var a=ia(),c,d,e;if(!b)return a;r(b.split("\n"),
function(b){e=b.indexOf(":");c=z(N(b.substr(0,e)));d=N(b.substr(e+1));c&&(a[c]=a[c]?a[c]+", "+d:d)});return a}function Yc(b){var a=J(b)?b:t;return function(c){a||(a=Xc(b));return c?(c=a[z(c)],void 0===c&&(c=null),c):a}}function Zc(b,a,c,d){if(G(d))return d(b,a,c);r(d,function(d){b=d(b,a,c)});return b}function Ke(){var b=this.defaults={transformResponse:[Zb],transformRequest:[function(a){return J(a)&&"[object File]"!==Ca.call(a)&&"[object Blob]"!==Ca.call(a)&&"[object FormData]"!==Ca.call(a)?$a(a):
a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:sa($b),put:sa($b),patch:sa($b)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},a=!1;this.useApplyAsync=function(b){return y(b)?(a=!!b,this):a};var c=this.interceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(d,e,f,g,h,l){function k(a){function c(a){var b=w({},a);b.data=a.data?Zc(a.data,a.headers,a.status,e.transformResponse):a.data;a=a.status;return 200<=a&&300>a?
b:h.reject(b)}function d(a){var b,c={};r(a,function(a,d){G(a)?(b=a(),null!=b&&(c[d]=b)):c[d]=a});return c}if(!ca.isObject(a))throw R("$http")("badreq",a);var e=w({method:"get",transformRequest:b.transformRequest,transformResponse:b.transformResponse},a);e.headers=function(a){var c=b.headers,e=w({},a.headers),f,g,c=w({},c.common,c[z(a.method)]);a:for(f in c){a=z(f);for(g in e)if(z(g)===a)continue a;e[f]=c[f]}return d(e)}(a);e.method=ub(e.method);var f=[function(a){var d=a.headers,e=Zc(a.data,Yc(d),
t,a.transformRequest);x(e)&&r(d,function(a,b){"content-type"===z(b)&&delete d[b]});x(a.withCredentials)&&!x(b.withCredentials)&&(a.withCredentials=b.withCredentials);return n(a,e).then(c,c)},t],g=h.when(e);for(r(u,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),g=g.then(a,k)}g.success=function(a){g.then(function(b){a(b.data,b.status,b.headers,e)});return g};g.error=
function(a){g.then(null,function(b){a(b.data,b.status,b.headers,e)});return g};return g}function n(c,f){function l(b,c,d,e){function f(){m(c,b,d,e)}I&&(200<=b&&300>b?I.put(P,[b,c,Xc(d),e]):I.remove(P));a?g.$applyAsync(f):(f(),g.$$phase||g.$apply())}function m(a,b,d,e){b=Math.max(b,0);(200<=b&&300>b?L.resolve:L.reject)({data:a,status:b,headers:Yc(d),config:c,statusText:e})}function n(a){m(a.data,a.status,sa(a.headers()),a.statusText)}function u(){var a=k.pendingRequests.indexOf(c);-1!==a&&k.pendingRequests.splice(a,
1)}var L=h.defer(),B=L.promise,I,D,S=c.headers,P=p(c.url,c.params);k.pendingRequests.push(c);B.then(u,u);!c.cache&&!b.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(I=J(c.cache)?c.cache:J(b.cache)?b.cache:q);I&&(D=I.get(P),y(D)?D&&G(D.then)?D.then(n,n):H(D)?m(D[1],D[0],sa(D[2]),D[3]):m(D,200,{},"OK"):I.put(P,B));x(D)&&((D=$c(c.url)?e.cookies()[c.xsrfCookieName||b.xsrfCookieName]:t)&&(S[c.xsrfHeaderName||b.xsrfHeaderName]=D),d(c.method,P,f,l,S,c.timeout,c.withCredentials,c.responseType));
return B}function p(a,b){if(!b)return a;var c=[];Ed(b,function(a,b){null===a||x(a)||(H(a)||(a=[a]),r(a,function(a){J(a)&&(a=ga(a)?a.toISOString():$a(a));c.push(Ea(b)+"="+Ea(a))}))});0<c.length&&(a+=(-1==a.indexOf("?")?"?":"&")+c.join("&"));return a}var q=f("$http"),u=[];r(c,function(a){u.unshift(C(a)?l.get(a):l.invoke(a))});k.pendingRequests=[];(function(a){r(arguments,function(a){k[a]=function(b,c){return k(w(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){r(arguments,function(a){k[a]=
function(b,c,d){return k(w(d||{},{method:a,url:b,data:c}))}})})("post","put","patch");k.defaults=b;return k}]}function vf(){return new Q.XMLHttpRequest}function Le(){this.$get=["$browser","$window","$document",function(b,a,c){return wf(b,vf,b.defer,a.angular.callbacks,c[0])}]}function wf(b,a,c,d,e){function f(a,b,c){var f=e.createElement("script"),n=null;f.type="text/javascript";f.src=a;f.async=!0;n=function(a){f.removeEventListener("load",n,!1);f.removeEventListener("error",n,!1);e.body.removeChild(f);
f=null;var g=-1,u="unknown";a&&("load"!==a.type||d[b].called||(a={type:"error"}),u=a.type,g="error"===a.type?404:200);c&&c(g,u)};f.addEventListener("load",n,!1);f.addEventListener("error",n,!1);e.body.appendChild(f);return n}return function(e,h,l,k,n,p,q,u){function s(){m&&m();F&&F.abort()}function M(a,d,e,f,g){L!==t&&c.cancel(L);m=F=null;a(d,e,f,g);b.$$completeOutstandingRequest(E)}b.$$incOutstandingRequestCount();h=h||b.url();if("jsonp"==z(e)){var v="_"+(d.counter++).toString(36);d[v]=function(a){d[v].data=
a;d[v].called=!0};var m=f(h.replace("JSON_CALLBACK","angular.callbacks."+v),v,function(a,b){M(k,a,d[v].data,"",b);d[v]=E})}else{var F=a();F.open(e,h,!0);r(n,function(a,b){y(a)&&F.setRequestHeader(b,a)});F.onload=function(){var a=F.statusText||"",b="response"in F?F.response:F.responseText,c=1223===F.status?204:F.status;0===c&&(c=b?200:"file"==Aa(h).protocol?404:0);M(k,c,b,F.getAllResponseHeaders(),a)};e=function(){M(k,-1,null,null,"")};F.onerror=e;F.onabort=e;q&&(F.withCredentials=!0);if(u)try{F.responseType=
u}catch(Z){if("json"!==u)throw Z;}F.send(l||null)}if(0<p)var L=c(s,p);else p&&G(p.then)&&p.then(s)}}function Ie(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler","$sce",function(c,d,e){function f(a){return"\\\\\\"+a}function g(f,g,u,s){function M(c){return c.replace(k,b).replace(n,a)}function v(a){try{var b=a;a=u?e.getTrusted(u,b):e.valueOf(b);var c;if(s&&!y(a))c=a;else if(null==a)c="";
else{switch(typeof a){case "string":break;case "number":a=""+a;break;default:a=$a(a)}c=a}return c}catch(g){c=ac("interr",f,g.toString()),d(c)}}s=!!s;for(var m,F,r=0,L=[],B=[],I=f.length,D=[],S=[];r<I;)if(-1!=(m=f.indexOf(b,r))&&-1!=(F=f.indexOf(a,m+h)))r!==m&&D.push(M(f.substring(r,m))),r=f.substring(m+h,F),L.push(r),B.push(c(r,v)),r=F+l,S.push(D.length),D.push("");else{r!==I&&D.push(M(f.substring(r)));break}if(u&&1<D.length)throw ac("noconcat",f);if(!g||L.length){var P=function(a){for(var b=0,c=
L.length;b<c;b++){if(s&&x(a[b]))return;D[S[b]]=a[b]}return D.join("")};return w(function(a){var b=0,c=L.length,e=Array(c);try{for(;b<c;b++)e[b]=B[b](a);return P(e)}catch(g){a=ac("interr",f,g.toString()),d(a)}},{exp:f,expressions:L,$$watchDelegate:function(a,b,c){var d;return a.$watchGroup(B,function(c,e){var f=P(c);G(b)&&b.call(this,f,c!==e?d:f,a);d=f},c)}})}}var h=b.length,l=a.length,k=new RegExp(b.replace(/./g,f),"g"),n=new RegExp(a.replace(/./g,f),"g");g.startSymbol=function(){return b};g.endSymbol=
function(){return a};return g}]}function Je(){this.$get=["$rootScope","$window","$q","$$q",function(b,a,c,d){function e(e,h,l,k){var n=a.setInterval,p=a.clearInterval,q=0,u=y(k)&&!k,s=(u?d:c).defer(),M=s.promise;l=y(l)?l:0;M.then(null,null,e);M.$$intervalId=n(function(){s.notify(q++);0<l&&q>=l&&(s.resolve(q),p(M.$$intervalId),delete f[M.$$intervalId]);u||b.$apply()},h);f[M.$$intervalId]=s;return M}var f={};e.cancel=function(b){return b&&b.$$intervalId in f?(f[b.$$intervalId].reject("canceled"),a.clearInterval(b.$$intervalId),
delete f[b.$$intervalId],!0):!1};return e}]}function Rd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),
DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a",ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"]},pluralCat:function(b){return 1===b?"one":"other"}}}}function bc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=qb(b[a]);
return b.join("/")}function ad(b,a){var c=Aa(b);a.$$protocol=c.protocol;a.$$host=c.hostname;a.$$port=aa(c.port)||xf[c.protocol]||null}function bd(b,a){var c="/"!==b.charAt(0);c&&(b="/"+b);var d=Aa(b);a.$$path=decodeURIComponent(c&&"/"===d.pathname.charAt(0)?d.pathname.substring(1):d.pathname);a.$$search=sc(d.search);a.$$hash=decodeURIComponent(d.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function ya(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ga(b){var a=b.indexOf("#");
return-1==a?b:b.substr(0,a)}function Fb(b){return b.replace(/(#.+)|#$/,"$1")}function cc(b){return b.substr(0,Ga(b).lastIndexOf("/")+1)}function dc(b,a){this.$$html5=!0;a=a||"";var c=cc(b);ad(b,this);this.$$parse=function(a){var b=ya(c,a);if(!C(b))throw Gb("ipthprfx",a,c);bd(b,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Pb(this.$$search),b=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=bc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$parseLinkUrl=
function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;(f=ya(b,d))!==t?(g=f,g=(f=ya(a,f))!==t?c+(ya("/",f)||f):b+g):(f=ya(c,d))!==t?g=c+f:c==d+"/"&&(g=c);g&&this.$$parse(g);return!!g}}function ec(b,a){var c=cc(b);ad(b,this);this.$$parse=function(d){d=ya(b,d)||ya(c,d);var e;"#"===d.charAt(0)?(e=ya(a,d),x(e)&&(e=d)):e=this.$$html5?d:"";bd(e,this);d=this.$$path;var f=/^\/[A-Z]:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));f.exec(e)||(d=(e=f.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};
this.$$compose=function(){var c=Pb(this.$$search),e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=bc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+(this.$$url?a+this.$$url:"")};this.$$parseLinkUrl=function(a,c){return Ga(b)==Ga(a)?(this.$$parse(a),!0):!1}}function cd(b,a){this.$$html5=!0;ec.apply(this,arguments);var c=cc(b);this.$$parseLinkUrl=function(d,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;b==Ga(d)?f=d:(g=ya(c,d))?f=b+a+g:c===d+"/"&&(f=c);f&&this.$$parse(f);return!!f};this.$$compose=
function(){var c=Pb(this.$$search),e=this.$$hash?"#"+qb(this.$$hash):"";this.$$url=bc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=b+a+this.$$url}}function Hb(b){return function(){return this[b]}}function dd(b,a){return function(c){if(x(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Me(){var b="",a={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(a){return y(a)?(b=a,this):b};this.html5Mode=function(b){return Wa(b)?(a.enabled=b,this):J(b)?(Wa(b.enabled)&&(a.enabled=
b.enabled),Wa(b.requireBase)&&(a.requireBase=b.requireBase),Wa(b.rewriteLinks)&&(a.rewriteLinks=b.rewriteLinks),this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement","$window",function(c,d,e,f,g){function h(a,b,c){var e=k.url(),f=k.$$state;try{d.url(a,b,c),k.$$state=d.state()}catch(g){throw k.url(e),k.$$state=f,g;}}function l(a,b){c.$broadcast("$locationChangeSuccess",k.absUrl(),a,k.$$state,b)}var k,n;n=d.baseHref();var p=d.url(),q;if(a.enabled){if(!n&&a.requireBase)throw Gb("nobase");
q=p.substring(0,p.indexOf("/",p.indexOf("//")+2))+(n||"/");n=e.history?dc:cd}else q=Ga(p),n=ec;k=new n(q,"#"+b);k.$$parseLinkUrl(p,p);k.$$state=d.state();var u=/^\s*(javascript|mailto):/i;f.on("click",function(b){if(a.rewriteLinks&&!b.ctrlKey&&!b.metaKey&&!b.shiftKey&&2!=b.which&&2!=b.button){for(var e=A(b.target);"a"!==va(e[0]);)if(e[0]===f[0]||!(e=e.parent())[0])return;var h=e.prop("href"),l=e.attr("href")||e.attr("xlink:href");J(h)&&"[object SVGAnimatedString]"===h.toString()&&(h=Aa(h.animVal).href);
u.test(h)||!h||e.attr("target")||b.isDefaultPrevented()||!k.$$parseLinkUrl(h,l)||(b.preventDefault(),k.absUrl()!=d.url()&&(c.$apply(),g.angular["ff-684208-preventDefault"]=!0))}});Fb(k.absUrl())!=Fb(p)&&d.url(k.absUrl(),!0);var s=!0;d.onUrlChange(function(a,b){c.$evalAsync(function(){var d=k.absUrl(),e=k.$$state,f;k.$$parse(a);k.$$state=b;f=c.$broadcast("$locationChangeStart",a,d,b,e).defaultPrevented;k.absUrl()===a&&(f?(k.$$parse(d),k.$$state=e,h(d,!1,e)):(s=!1,l(d,e)))});c.$$phase||c.$digest()});
c.$watch(function(){var a=Fb(d.url()),b=Fb(k.absUrl()),f=d.state(),g=k.$$replace,q=a!==b||k.$$html5&&e.history&&f!==k.$$state;if(s||q)s=!1,c.$evalAsync(function(){var b=k.absUrl(),d=c.$broadcast("$locationChangeStart",b,a,k.$$state,f).defaultPrevented;k.absUrl()===b&&(d?(k.$$parse(a),k.$$state=f):(q&&h(b,g,f===k.$$state?null:k.$$state),l(a,f)))});k.$$replace=!1});return k}]}function Ne(){var b=!0,a=this;this.debugEnabled=function(a){return y(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof
Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||E;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a=[];r(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,
arguments)}}()}}]}function ua(b,a){if("__defineGetter__"===b||"__defineSetter__"===b||"__lookupGetter__"===b||"__lookupSetter__"===b||"__proto__"===b)throw na("isecfld",a);return b}function oa(b,a){if(b){if(b.constructor===b)throw na("isecfn",a);if(b.window===b)throw na("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw na("isecdom",a);if(b===Object)throw na("isecobj",a);}return b}function fc(b){return b.constant}function hb(b,a,c,d,e){oa(b,e);oa(a,e);c=c.split(".");for(var f,
g=0;1<c.length;g++){f=ua(c.shift(),e);var h=0===g&&a&&a[f]||b[f];h||(h={},b[f]=h);b=oa(h,e)}f=ua(c.shift(),e);oa(b[f],e);return b[f]=d}function Pa(b){return"constructor"==b}function ed(b,a,c,d,e,f,g){ua(b,f);ua(a,f);ua(c,f);ua(d,f);ua(e,f);var h=function(a){return oa(a,f)},l=g||Pa(b)?h:ra,k=g||Pa(a)?h:ra,n=g||Pa(c)?h:ra,p=g||Pa(d)?h:ra,q=g||Pa(e)?h:ra;return function(f,g){var h=g&&g.hasOwnProperty(b)?g:f;if(null==h)return h;h=l(h[b]);if(!a)return h;if(null==h)return t;h=k(h[a]);if(!c)return h;if(null==
h)return t;h=n(h[c]);if(!d)return h;if(null==h)return t;h=p(h[d]);return e?null==h?t:h=q(h[e]):h}}function yf(b,a){return function(c,d){return b(c,d,oa,a)}}function zf(b,a,c){var d=a.expensiveChecks,e=d?Af:Bf,f=e[b];if(f)return f;var g=b.split("."),h=g.length;if(a.csp)f=6>h?ed(g[0],g[1],g[2],g[3],g[4],c,d):function(a,b){var e=0,f;do f=ed(g[e++],g[e++],g[e++],g[e++],g[e++],c,d)(a,b),b=t,a=f;while(e<h);return f};else{var l="";d&&(l+="s = eso(s, fe);\nl = eso(l, fe);\n");var k=d;r(g,function(a,b){ua(a,
c);var e=(b?"s":'((l&&l.hasOwnProperty("'+a+'"))?l:s)')+"."+a;if(d||Pa(a))e="eso("+e+", fe)",k=!0;l+="if(s == null) return undefined;\ns="+e+";\n"});l+="return s;";a=new Function("s","l","eso","fe",l);a.toString=ea(l);k&&(a=yf(a,c));f=a}f.sharedGetter=!0;f.assign=function(a,c,d){return hb(a,d,b,c,b)};return e[b]=f}function gc(b){return G(b.valueOf)?b.valueOf():Cf.call(b)}function Oe(){var b=ia(),a=ia();this.$get=["$filter","$sniffer",function(c,d){function e(a){var b=a;a.sharedGetter&&(b=function(b,
c){return a(b,c)},b.literal=a.literal,b.constant=a.constant,b.assign=a.assign);return b}function f(a,b){for(var c=0,d=a.length;c<d;c++){var e=a[c];e.constant||(e.inputs?f(e.inputs,b):-1===b.indexOf(e)&&b.push(e))}return b}function g(a,b){return null==a||null==b?a===b:"object"===typeof a&&(a=gc(a),"object"===typeof a)?!1:a===b||a!==a&&b!==b}function h(a,b,c,d){var e=d.$$inputs||(d.$$inputs=f(d.inputs,[])),h;if(1===e.length){var k=g,e=e[0];return a.$watch(function(a){var b=e(a);g(b,k)||(h=d(a),k=b&&
gc(b));return h},b,c)}for(var l=[],q=0,p=e.length;q<p;q++)l[q]=g;return a.$watch(function(a){for(var b=!1,c=0,f=e.length;c<f;c++){var k=e[c](a);if(b||(b=!g(k,l[c])))l[c]=k&&gc(k)}b&&(h=d(a));return h},b,c)}function l(a,b,c,d){var e,f;return e=a.$watch(function(a){return d(a)},function(a,c,d){f=a;G(b)&&b.apply(this,arguments);y(a)&&d.$$postDigest(function(){y(f)&&e()})},c)}function k(a,b,c,d){function e(a){var b=!0;r(a,function(a){y(a)||(b=!1)});return b}var f,g;return f=a.$watch(function(a){return d(a)},
function(a,c,d){g=a;G(b)&&b.call(this,a,c,d);e(a)&&d.$$postDigest(function(){e(g)&&f()})},c)}function n(a,b,c,d){var e;return e=a.$watch(function(a){return d(a)},function(a,c,d){G(b)&&b.apply(this,arguments);e()},c)}function p(a,b){if(!b)return a;var c=a.$$watchDelegate,c=c!==k&&c!==l?function(c,d){var e=a(c,d);return b(e,c,d)}:function(c,d){var e=a(c,d),f=b(e,c,d);return y(e)?f:e};a.$$watchDelegate&&a.$$watchDelegate!==h?c.$$watchDelegate=a.$$watchDelegate:b.$stateful||(c.$$watchDelegate=h,c.inputs=
[a]);return c}var q={csp:d.csp,expensiveChecks:!1},u={csp:d.csp,expensiveChecks:!0};return function(d,f,g){var m,r,t;switch(typeof d){case "string":t=d=d.trim();var L=g?a:b;m=L[t];m||(":"===d.charAt(0)&&":"===d.charAt(1)&&(r=!0,d=d.substring(2)),g=g?u:q,m=new hc(g),m=(new ib(m,c,g)).parse(d),m.constant?m.$$watchDelegate=n:r?(m=e(m),m.$$watchDelegate=m.literal?k:l):m.inputs&&(m.$$watchDelegate=h),L[t]=m);return p(m,f);case "function":return p(d,f);default:return p(E,f)}}}]}function Qe(){this.$get=
["$rootScope","$exceptionHandler",function(b,a){return fd(function(a){b.$evalAsync(a)},a)}]}function Re(){this.$get=["$browser","$exceptionHandler",function(b,a){return fd(function(a){b.defer(a)},a)}]}function fd(b,a){function c(a,b,c){function d(b){return function(c){e||(e=!0,b.call(a,c))}}var e=!1;return[d(b),d(c)]}function d(){this.$$state={status:0}}function e(a,b){return function(c){b.call(a,c)}}function f(c){!c.processScheduled&&c.pending&&(c.processScheduled=!0,b(function(){var b,d,e;e=c.pending;
c.processScheduled=!1;c.pending=t;for(var f=0,g=e.length;f<g;++f){d=e[f][0];b=e[f][c.status];try{G(b)?d.resolve(b(c.value)):1===c.status?d.resolve(c.value):d.reject(c.value)}catch(h){d.reject(h),a(h)}}}))}function g(){this.promise=new d;this.resolve=e(this,this.resolve);this.reject=e(this,this.reject);this.notify=e(this,this.notify)}var h=R("$q",TypeError);d.prototype={then:function(a,b,c){var d=new g;this.$$state.pending=this.$$state.pending||[];this.$$state.pending.push([d,a,b,c]);0<this.$$state.status&&
f(this.$$state);return d.promise},"catch":function(a){return this.then(null,a)},"finally":function(a,b){return this.then(function(b){return k(b,!0,a)},function(b){return k(b,!1,a)},b)}};g.prototype={resolve:function(a){this.promise.$$state.status||(a===this.promise?this.$$reject(h("qcycle",a)):this.$$resolve(a))},$$resolve:function(b){var d,e;e=c(this,this.$$resolve,this.$$reject);try{if(J(b)||G(b))d=b&&b.then;G(d)?(this.promise.$$state.status=-1,d.call(b,e[0],e[1],this.notify)):(this.promise.$$state.value=
b,this.promise.$$state.status=1,f(this.promise.$$state))}catch(g){e[1](g),a(g)}},reject:function(a){this.promise.$$state.status||this.$$reject(a)},$$reject:function(a){this.promise.$$state.value=a;this.promise.$$state.status=2;f(this.promise.$$state)},notify:function(c){var d=this.promise.$$state.pending;0>=this.promise.$$state.status&&d&&d.length&&b(function(){for(var b,e,f=0,g=d.length;f<g;f++){e=d[f][0];b=d[f][3];try{e.notify(G(b)?b(c):c)}catch(h){a(h)}}})}};var l=function(a,b){var c=new g;b?c.resolve(a):
c.reject(a);return c.promise},k=function(a,b,c){var d=null;try{G(c)&&(d=c())}catch(e){return l(e,!1)}return d&&G(d.then)?d.then(function(){return l(a,b)},function(a){return l(a,!1)}):l(a,b)},n=function(a,b,c,d){var e=new g;e.resolve(a);return e.promise.then(b,c,d)},p=function u(a){if(!G(a))throw h("norslvr",a);if(!(this instanceof u))return new u(a);var b=new g;a(function(a){b.resolve(a)},function(a){b.reject(a)});return b.promise};p.defer=function(){return new g};p.reject=function(a){var b=new g;
b.reject(a);return b.promise};p.when=n;p.all=function(a){var b=new g,c=0,d=H(a)?[]:{};r(a,function(a,e){c++;n(a).then(function(a){d.hasOwnProperty(e)||(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||b.reject(a)})});0===c&&b.resolve(d);return b.promise};return p}function $e(){this.$get=["$window","$timeout",function(b,a){var c=b.requestAnimationFrame||b.webkitRequestAnimationFrame,d=b.cancelAnimationFrame||b.webkitCancelAnimationFrame||b.webkitCancelRequestAnimationFrame,e=!!c,f=e?function(a){var b=
c(a);return function(){d(b)}}:function(b){var c=a(b,16.66,!1);return function(){a.cancel(c)}};f.supported=e;return f}]}function Pe(){function b(a){function b(){this.$$watchers=this.$$nextSibling=this.$$childHead=this.$$childTail=null;this.$$listeners={};this.$$listenerCount={};this.$$watchersCount=0;this.$id=++ob;this.$$ChildScope=null}b.prototype=a;return b}var a=10,c=R("$rootScope"),d=null,e=null;this.digestTtl=function(b){arguments.length&&(a=b);return a};this.$get=["$injector","$exceptionHandler",
"$parse","$browser",function(f,g,h,l){function k(a){a.currentScope.$$destroyed=!0}function n(){this.$id=++ob;this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;this.$root=this;this.$$destroyed=!1;this.$$listeners={};this.$$listenerCount={};this.$$isolateBindings=null}function p(a){if(v.$$phase)throw c("inprog",v.$$phase);v.$$phase=a}function q(a,b,c){do a.$$listenerCount[c]-=b,0===a.$$listenerCount[c]&&delete a.$$listenerCount[c];
while(a=a.$parent)}function u(){}function s(){for(;t.length;)try{t.shift()()}catch(a){g(a)}e=null}function M(){null===e&&(e=l.defer(function(){v.$apply(s)}))}n.prototype={constructor:n,$new:function(a,c){var d;c=c||this;a?(d=new n,d.$root=this.$root):(this.$$ChildScope||(this.$$ChildScope=b(this)),d=new this.$$ChildScope);d.$parent=c;d.$$prevSibling=c.$$childTail;c.$$childHead?(c.$$childTail.$$nextSibling=d,c.$$childTail=d):c.$$childHead=c.$$childTail=d;(a||c!=this)&&d.$on("$destroy",k);return d},
$watch:function(a,b,c){var e=h(a);if(e.$$watchDelegate)return e.$$watchDelegate(this,b,c,e);var f=this.$$watchers,g={fn:b,last:u,get:e,exp:a,eq:!!c};d=null;G(b)||(g.fn=E);f||(f=this.$$watchers=[]);f.unshift(g);return function(){Xa(f,g);d=null}},$watchGroup:function(a,b){function c(){h=!1;k?(k=!1,b(e,e,g)):b(e,d,g)}var d=Array(a.length),e=Array(a.length),f=[],g=this,h=!1,k=!0;if(!a.length){var l=!0;g.$evalAsync(function(){l&&b(e,e,g)});return function(){l=!1}}if(1===a.length)return this.$watch(a[0],
function(a,c,f){e[0]=a;d[0]=c;b(e,a===c?e:d,f)});r(a,function(a,b){var k=g.$watch(a,function(a,f){e[b]=a;d[b]=f;h||(h=!0,g.$evalAsync(c))});f.push(k)});return function(){for(;f.length;)f.shift()()}},$watchCollection:function(a,b){function c(a){e=a;var b,d,g,h;if(!x(e)){if(J(e))if(Sa(e))for(f!==p&&(f=p,u=f.length=0,l++),a=e.length,u!==a&&(l++,f.length=u=a),b=0;b<a;b++)h=f[b],g=e[b],d=h!==h&&g!==g,d||h===g||(l++,f[b]=g);else{f!==n&&(f=n={},u=0,l++);a=0;for(b in e)e.hasOwnProperty(b)&&(a++,g=e[b],h=
f[b],b in f?(d=h!==h&&g!==g,d||h===g||(l++,f[b]=g)):(u++,f[b]=g,l++));if(u>a)for(b in l++,f)e.hasOwnProperty(b)||(u--,delete f[b])}else f!==e&&(f=e,l++);return l}}c.$stateful=!0;var d=this,e,f,g,k=1<b.length,l=0,q=h(a,c),p=[],n={},m=!0,u=0;return this.$watch(q,function(){m?(m=!1,b(e,e,d)):b(e,g,d);if(k)if(J(e))if(Sa(e)){g=Array(e.length);for(var a=0;a<e.length;a++)g[a]=e[a]}else for(a in g={},e)tc.call(e,a)&&(g[a]=e[a]);else g=e})},$digest:function(){var b,f,h,k,q,n,r=a,t,O=[],M,y;p("$digest");l.$$checkUrlChange();
this===v&&null!==e&&(l.defer.cancel(e),s());d=null;do{n=!1;for(t=this;m.length;){try{y=m.shift(),y.scope.$eval(y.expression,y.locals)}catch(w){g(w)}d=null}a:do{if(k=t.$$watchers)for(q=k.length;q--;)try{if(b=k[q])if((f=b.get(t))!==(h=b.last)&&!(b.eq?ha(f,h):"number"===typeof f&&"number"===typeof h&&isNaN(f)&&isNaN(h)))n=!0,d=b,b.last=b.eq?Da(f,null):f,b.fn(f,h===u?f:h,t),5>r&&(M=4-r,O[M]||(O[M]=[]),O[M].push({msg:G(b.exp)?"fn: "+(b.exp.name||b.exp.toString()):b.exp,newVal:f,oldVal:h}));else if(b===
d){n=!1;break a}}catch(A){g(A)}if(!(k=t.$$childHead||t!==this&&t.$$nextSibling))for(;t!==this&&!(k=t.$$nextSibling);)t=t.$parent}while(t=k);if((n||m.length)&&!r--)throw v.$$phase=null,c("infdig",a,O);}while(n||m.length);for(v.$$phase=null;F.length;)try{F.shift()()}catch(x){g(x)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(this!==v){for(var b in this.$$listenerCount)q(this,this.$$listenerCount[b],b);a.$$childHead==this&&(a.$$childHead=
this.$$nextSibling);a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=E;this.$on=this.$watch=this.$watchGroup=function(){return E};this.$$listeners={};this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=this.$$watchers=null}}},$eval:function(a,
b){return h(a)(this,b)},$evalAsync:function(a,b){v.$$phase||m.length||l.defer(function(){m.length&&v.$digest()});m.push({scope:this,expression:a,locals:b})},$$postDigest:function(a){F.push(a)},$apply:function(a){try{return p("$apply"),this.$eval(a)}catch(b){g(b)}finally{v.$$phase=null;try{v.$digest()}catch(c){throw g(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&t.push(b);M()},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||
(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=c.indexOf(b);-1!==d&&(c[d]=null,q(e,1,a))}},$emit:function(a,b){var c=[],d,e=this,f=!1,h={name:a,targetScope:e,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},k=Ya([h],arguments,1),l,q;do{d=e.$$listeners[a]||c;h.currentScope=e;l=0;for(q=d.length;l<q;l++)if(d[l])try{d[l].apply(null,k)}catch(p){g(p)}else d.splice(l,1),l--,q--;if(f)return h.currentScope=
null,h;e=e.$parent}while(e);h.currentScope=null;return h},$broadcast:function(a,b){var c=this,d=this,e={name:a,targetScope:this,preventDefault:function(){e.defaultPrevented=!0},defaultPrevented:!1};if(!this.$$listenerCount[a])return e;for(var f=Ya([e],arguments,1),h,l;c=d;){e.currentScope=c;d=c.$$listeners[a]||[];h=0;for(l=d.length;h<l;h++)if(d[h])try{d[h].apply(null,f)}catch(k){g(k)}else d.splice(h,1),h--,l--;if(!(d=c.$$listenerCount[a]&&c.$$childHead||c!==this&&c.$$nextSibling))for(;c!==this&&!(d=
c.$$nextSibling);)c=c.$parent}e.currentScope=null;return e}};var v=new n,m=v.$$asyncQueue=[],F=v.$$postDigestQueue=[],t=v.$$applyAsyncQueue=[];return v}]}function Sd(){var b=/^\s*(https?|ftp|mailto|tel|file):/,a=/^\s*((https?|ftp|file|blob):|data:image\/)/;this.aHrefSanitizationWhitelist=function(a){return y(a)?(b=a,this):b};this.imgSrcSanitizationWhitelist=function(b){return y(b)?(a=b,this):a};this.$get=function(){return function(c,d){var e=d?a:b,f;f=Aa(c).href;return""===f||f.match(e)?c:"unsafe:"+
f}}}function Df(b){if("self"===b)return b;if(C(b)){if(-1<b.indexOf("***"))throw Ba("iwcard",b);b=gd(b).replace("\\*\\*",".*").replace("\\*","[^:/.?&;]*");return new RegExp("^"+b+"$")}if(Ua(b))return new RegExp("^"+b.source+"$");throw Ba("imatcher");}function hd(b){var a=[];y(b)&&r(b,function(b){a.push(Df(b))});return a}function Te(){this.SCE_CONTEXTS=pa;var b=["self"],a=[];this.resourceUrlWhitelist=function(a){arguments.length&&(b=hd(a));return b};this.resourceUrlBlacklist=function(b){arguments.length&&
(a=hd(b));return a};this.$get=["$injector",function(c){function d(a,b){return"self"===a?$c(b):!!a.exec(b.href)}function e(a){var b=function(a){this.$$unwrapTrustedValue=function(){return a}};a&&(b.prototype=new a);b.prototype.valueOf=function(){return this.$$unwrapTrustedValue()};b.prototype.toString=function(){return this.$$unwrapTrustedValue().toString()};return b}var f=function(a){throw Ba("unsafe");};c.has("$sanitize")&&(f=c.get("$sanitize"));var g=e(),h={};h[pa.HTML]=e(g);h[pa.CSS]=e(g);h[pa.URL]=
e(g);h[pa.JS]=e(g);h[pa.RESOURCE_URL]=e(h[pa.URL]);return{trustAs:function(a,b){var c=h.hasOwnProperty(a)?h[a]:null;if(!c)throw Ba("icontext",a,b);if(null===b||b===t||""===b)return b;if("string"!==typeof b)throw Ba("itype",a);return new c(b)},getTrusted:function(c,e){if(null===e||e===t||""===e)return e;var g=h.hasOwnProperty(c)?h[c]:null;if(g&&e instanceof g)return e.$$unwrapTrustedValue();if(c===pa.RESOURCE_URL){var g=Aa(e.toString()),p,q,u=!1;p=0;for(q=b.length;p<q;p++)if(d(b[p],g)){u=!0;break}if(u)for(p=
0,q=a.length;p<q;p++)if(d(a[p],g)){u=!1;break}if(u)return e;throw Ba("insecurl",e.toString());}if(c===pa.HTML)return f(e);throw Ba("unsafe");},valueOf:function(a){return a instanceof g?a.$$unwrapTrustedValue():a}}}]}function Se(){var b=!0;this.enabled=function(a){arguments.length&&(b=!!a);return b};this.$get=["$parse","$sceDelegate",function(a,c){if(b&&8>Qa)throw Ba("iequirks");var d=sa(pa);d.isEnabled=function(){return b};d.trustAs=c.trustAs;d.getTrusted=c.getTrusted;d.valueOf=c.valueOf;b||(d.trustAs=
d.getTrusted=function(a,b){return b},d.valueOf=ra);d.parseAs=function(b,c){var e=a(c);return e.literal&&e.constant?e:a(c,function(a){return d.getTrusted(b,a)})};var e=d.parseAs,f=d.getTrusted,g=d.trustAs;r(pa,function(a,b){var c=z(b);d[db("parse_as_"+c)]=function(b){return e(a,b)};d[db("get_trusted_"+c)]=function(b){return f(a,b)};d[db("trust_as_"+c)]=function(b){return g(a,b)}});return d}]}function Ue(){this.$get=["$window","$document",function(b,a){var c={},d=aa((/android (\d+)/.exec(z((b.navigator||
{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),f=a[0]||{},g,h=/^(Moz|webkit|ms)(?=[A-Z])/,l=f.body&&f.body.style,k=!1,n=!1;if(l){for(var p in l)if(k=h.exec(p)){g=k[0];g=g.substr(0,1).toUpperCase()+g.substr(1);break}g||(g="WebkitOpacity"in l&&"webkit");k=!!("transition"in l||g+"Transition"in l);n=!!("animation"in l||g+"Animation"in l);!d||k&&n||(k=C(f.body.style.webkitTransition),n=C(f.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hasEvent:function(a){if("input"===
a&&11>=Qa)return!1;if(x(c[a])){var b=f.createElement("div");c[a]="on"+a in b}return c[a]},csp:bb(),vendorPrefix:g,transitions:k,animations:n,android:d}}]}function We(){this.$get=["$templateCache","$http","$q",function(b,a,c){function d(e,f){d.totalPendingRequests++;var g=a.defaults&&a.defaults.transformResponse;H(g)?g=g.filter(function(a){return a!==Zb}):g===Zb&&(g=null);return a.get(e,{cache:b,transformResponse:g})["finally"](function(){d.totalPendingRequests--}).then(function(a){return a.data},
function(a){if(!f)throw la("tpload",e);return c.reject(a)})}d.totalPendingRequests=0;return d}]}function Xe(){this.$get=["$rootScope","$browser","$location",function(b,a,c){return{findBindings:function(a,b,c){a=a.getElementsByClassName("ng-binding");var g=[];r(a,function(a){var d=ca.element(a).data("$binding");d&&r(d,function(d){c?(new RegExp("(^|\\s)"+gd(b)+"(\\s|\\||$)")).test(d)&&g.push(a):-1!=d.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b,c){for(var g=["ng-","data-ng-","ng\\:"],
h=0;h<g.length;++h){var l=a.querySelectorAll("["+g[h]+"model"+(c?"=":"*=")+'"'+b+'"]');if(l.length)return l}},getLocation:function(){return c.url()},setLocation:function(a){a!==c.url()&&(c.url(a),b.$digest())},whenStable:function(b){a.notifyWhenNoOutstandingRequests(b)}}}]}function Ye(){this.$get=["$rootScope","$browser","$q","$$q","$exceptionHandler",function(b,a,c,d,e){function f(f,l,k){var n=y(k)&&!k,p=(n?d:c).defer(),q=p.promise;l=a.defer(function(){try{p.resolve(f())}catch(a){p.reject(a),e(a)}finally{delete g[q.$$timeoutId]}n||
b.$apply()},l);q.$$timeoutId=l;g[l]=p;return q}var g={};f.cancel=function(b){return b&&b.$$timeoutId in g?(g[b.$$timeoutId].reject("canceled"),delete g[b.$$timeoutId],a.defer.cancel(b.$$timeoutId)):!1};return f}]}function Aa(b){Qa&&($.setAttribute("href",b),b=$.href);$.setAttribute("href",b);return{href:$.href,protocol:$.protocol?$.protocol.replace(/:$/,""):"",host:$.host,search:$.search?$.search.replace(/^\?/,""):"",hash:$.hash?$.hash.replace(/^#/,""):"",hostname:$.hostname,port:$.port,pathname:"/"===
$.pathname.charAt(0)?$.pathname:"/"+$.pathname}}function $c(b){b=C(b)?Aa(b):b;return b.protocol===id.protocol&&b.host===id.host}function Ze(){this.$get=ea(Q)}function Fc(b){function a(c,d){if(J(c)){var e={};r(c,function(b,c){e[c]=a(c,b)});return e}return b.factory(c+"Filter",d)}this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+"Filter")}}];a("currency",jd);a("date",kd);a("filter",Ef);a("json",Ff);a("limitTo",Gf);a("lowercase",Hf);a("number",ld);a("orderBy",md);a("uppercase",
If)}function Ef(){return function(b,a,c){if(!H(b))return b;var d;switch(typeof a){case "function":break;case "boolean":case "number":case "string":d=!0;case "object":a=Jf(a,c,d);break;default:return b}return b.filter(a)}}function Jf(b,a,c){var d=J(b)&&"$"in b;!0===a?a=ha:G(a)||(a=function(a,b){if(J(a)||J(b))return!1;a=z(""+a);b=z(""+b);return-1!==a.indexOf(b)});return function(e){return d&&!J(e)?Ha(e,b.$,a,!1):Ha(e,b,a,c)}}function Ha(b,a,c,d,e){var f=null!==b?typeof b:"null",g=null!==a?typeof a:
"null";if("string"===g&&"!"===a.charAt(0))return!Ha(b,a.substring(1),c,d);if(H(b))return b.some(function(b){return Ha(b,a,c,d)});switch(f){case "object":var h;if(d){for(h in b)if("$"!==h.charAt(0)&&Ha(b[h],a,c,!0))return!0;return e?!1:Ha(b,a,c,!1)}if("object"===g){for(h in a)if(e=a[h],!G(e)&&!x(e)&&(f="$"===h,!Ha(f?b:b[h],e,c,f,f)))return!1;return!0}return c(b,a);case "function":return!1;default:return c(b,a)}}function jd(b){var a=b.NUMBER_FORMATS;return function(b,d,e){x(d)&&(d=a.CURRENCY_SYM);x(e)&&
(e=a.PATTERNS[1].maxFrac);return null==b?b:nd(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,e).replace(/\u00A4/g,d)}}function ld(b){var a=b.NUMBER_FORMATS;return function(b,d){return null==b?b:nd(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function nd(b,a,c,d,e){if(!isFinite(b)||J(b))return"";var f=0>b;b=Math.abs(b);var g=b+"",h="",l=[],k=!1;if(-1!==g.indexOf("e")){var n=g.match(/([\d\.]+)e(-?)(\d+)/);n&&"-"==n[2]&&n[3]>e+1?b=0:(h=g,k=!0)}if(k)0<e&&1>b&&(h=b.toFixed(e),b=parseFloat(h));else{g=(g.split(od)[1]||
"").length;x(e)&&(e=Math.min(Math.max(a.minFrac,g),a.maxFrac));b=+(Math.round(+(b.toString()+"e"+e)).toString()+"e"+-e);var g=(""+b).split(od),k=g[0],g=g[1]||"",p=0,q=a.lgSize,u=a.gSize;if(k.length>=q+u)for(p=k.length-q,n=0;n<p;n++)0===(p-n)%u&&0!==n&&(h+=c),h+=k.charAt(n);for(n=p;n<k.length;n++)0===(k.length-n)%q&&0!==n&&(h+=c),h+=k.charAt(n);for(;g.length<e;)g+="0";e&&"0"!==e&&(h+=d+g.substr(0,e))}0===b&&(f=!1);l.push(f?a.negPre:a.posPre,h,f?a.negSuf:a.posSuf);return l.join("")}function Ib(b,a,
c){var d="";0>b&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=b.substr(b.length-a));return d+b}function U(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(0<c||e>-c)e+=c;0===e&&-12==c&&(e=12);return Ib(e,a,d)}}function Jb(b,a){return function(c,d){var e=c["get"+b](),f=ub(a?"SHORT"+b:b);return d[f][e]}}function pd(b){var a=(new Date(b,0,1)).getDay();return new Date(b,0,(4>=a?5:12)-a)}function qd(b){return function(a){var c=pd(a.getFullYear());a=+new Date(a.getFullYear(),a.getMonth(),a.getDate()+
(4-a.getDay()))-+c;a=1+Math.round(a/6048E5);return Ib(a,b)}}function ic(b,a){return 0>=b.getFullYear()?a.ERAS[0]:a.ERAS[1]}function kd(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=aa(b[9]+b[10]),g=aa(b[9]+b[11]));h.call(a,aa(b[1]),aa(b[2])-1,aa(b[3]));f=aa(b[4]||0)-f;g=aa(b[5]||0)-g;h=aa(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,f,g,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
return function(c,e,f){var g="",h=[],l,k;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;C(c)&&(c=Kf.test(c)?aa(c):a(c));Y(c)&&(c=new Date(c));if(!ga(c))return c;for(;e;)(k=Lf.exec(e))?(h=Ya(h,k,1),e=h.pop()):(h.push(e),e=null);f&&"UTC"===f&&(c=new Date(c.getTime()),c.setMinutes(c.getMinutes()+c.getTimezoneOffset()));r(h,function(a){l=Mf[a];g+=l?l(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ff(){return function(b,a){x(a)&&(a=2);return $a(b,a)}}function Gf(){return function(b,
a){Y(b)&&(b=b.toString());return H(b)||C(b)?(a=Infinity===Math.abs(Number(a))?Number(a):aa(a))?0<a?b.slice(0,a):b.slice(a):C(b)?"":[]:b}}function md(b){return function(a,c,d){function e(a,b){return b?function(b,c){return a(c,b)}:a}function f(a){switch(typeof a){case "number":case "boolean":case "string":return!0;default:return!1}}function g(a){return null===a?"null":"function"===typeof a.valueOf&&(a=a.valueOf(),f(a))||"function"===typeof a.toString&&(a=a.toString(),f(a))?a:""}function h(a,b){var c=
typeof a,d=typeof b;c===d&&"object"===c&&(a=g(a),b=g(b));return c===d?("string"===c&&(a=a.toLowerCase(),b=b.toLowerCase()),a===b?0:a<b?-1:1):c<d?-1:1}if(!Sa(a))return a;c=H(c)?c:[c];0===c.length&&(c=["+"]);c=c.map(function(a){var c=!1,d=a||ra;if(C(a)){if("+"==a.charAt(0)||"-"==a.charAt(0))c="-"==a.charAt(0),a=a.substring(1);if(""===a)return e(h,c);d=b(a);if(d.constant){var f=d();return e(function(a,b){return h(a[f],b[f])},c)}}return e(function(a,b){return h(d(a),d(b))},c)});return Za.call(a).sort(e(function(a,
b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(0!==e)return e}return 0},d))}}function Ia(b){G(b)&&(b={link:b});b.restrict=b.restrict||"AC";return ea(b)}function rd(b,a,c,d,e){var f=this,g=[],h=f.$$parentForm=b.parent().controller("form")||Kb;f.$error={};f.$$success={};f.$pending=t;f.$name=e(a.name||a.ngForm||"")(c);f.$dirty=!1;f.$pristine=!0;f.$valid=!0;f.$invalid=!1;f.$submitted=!1;h.$addControl(f);f.$rollbackViewValue=function(){r(g,function(a){a.$rollbackViewValue()})};f.$commitViewValue=function(){r(g,
function(a){a.$commitViewValue()})};f.$addControl=function(a){La(a.$name,"input");g.push(a);a.$name&&(f[a.$name]=a)};f.$$renameControl=function(a,b){var c=a.$name;f[c]===a&&delete f[c];f[b]=a;a.$name=b};f.$removeControl=function(a){a.$name&&f[a.$name]===a&&delete f[a.$name];r(f.$pending,function(b,c){f.$setValidity(c,null,a)});r(f.$error,function(b,c){f.$setValidity(c,null,a)});r(f.$$success,function(b,c){f.$setValidity(c,null,a)});Xa(g,a)};sd({ctrl:this,$element:b,set:function(a,b,c){var d=a[b];
d?-1===d.indexOf(c)&&d.push(c):a[b]=[c]},unset:function(a,b,c){var d=a[b];d&&(Xa(d,c),0===d.length&&delete a[b])},parentForm:h,$animate:d});f.$setDirty=function(){d.removeClass(b,Ra);d.addClass(b,Lb);f.$dirty=!0;f.$pristine=!1;h.$setDirty()};f.$setPristine=function(){d.setClass(b,Ra,Lb+" ng-submitted");f.$dirty=!1;f.$pristine=!0;f.$submitted=!1;r(g,function(a){a.$setPristine()})};f.$setUntouched=function(){r(g,function(a){a.$setUntouched()})};f.$setSubmitted=function(){d.addClass(b,"ng-submitted");
f.$submitted=!0;h.$setSubmitted()}}function jc(b){b.$formatters.push(function(a){return b.$isEmpty(a)?a:a.toString()})}function jb(b,a,c,d,e,f){var g=z(a[0].type);if(!e.android){var h=!1;a.on("compositionstart",function(a){h=!0});a.on("compositionend",function(){h=!1;l()})}var l=function(b){k&&(f.defer.cancel(k),k=null);if(!h){var e=a.val();b=b&&b.type;"password"===g||c.ngTrim&&"false"===c.ngTrim||(e=N(e));(d.$viewValue!==e||""===e&&d.$$hasNativeValidators)&&d.$setViewValue(e,b)}};if(e.hasEvent("input"))a.on("input",
l);else{var k,n=function(a,b,c){k||(k=f.defer(function(){k=null;b&&b.value===c||l(a)}))};a.on("keydown",function(a){var b=a.keyCode;91===b||15<b&&19>b||37<=b&&40>=b||n(a,this,this.value)});if(e.hasEvent("paste"))a.on("paste cut",n)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)?"":d.$viewValue)}}function Mb(b,a){return function(c,d){var e,f;if(ga(c))return c;if(C(c)){'"'==c.charAt(0)&&'"'==c.charAt(c.length-1)&&(c=c.substring(1,c.length-1));if(Nf.test(c))return new Date(c);b.lastIndex=
0;if(e=b.exec(c))return e.shift(),f=d?{yyyy:d.getFullYear(),MM:d.getMonth()+1,dd:d.getDate(),HH:d.getHours(),mm:d.getMinutes(),ss:d.getSeconds(),sss:d.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0,mm:0,ss:0,sss:0},r(e,function(b,c){c<a.length&&(f[a[c]]=+b)}),new Date(f.yyyy,f.MM-1,f.dd,f.HH,f.mm,f.ss||0,1E3*f.sss||0)}return NaN}}function kb(b,a,c,d){return function(e,f,g,h,l,k,n){function p(a){return a&&!(a.getTime&&a.getTime()!==a.getTime())}function q(a){return y(a)?ga(a)?a:c(a):t}td(e,f,g,h);
jb(e,f,g,h,l,k);var u=h&&h.$options&&h.$options.timezone,s;h.$$parserName=b;h.$parsers.push(function(b){return h.$isEmpty(b)?null:a.test(b)?(b=c(b,s),"UTC"===u&&b.setMinutes(b.getMinutes()-b.getTimezoneOffset()),b):t});h.$formatters.push(function(a){if(a&&!ga(a))throw Nb("datefmt",a);if(p(a)){if((s=a)&&"UTC"===u){var b=6E4*s.getTimezoneOffset();s=new Date(s.getTime()+b)}return n("date")(a,d,u)}s=null;return""});if(y(g.min)||g.ngMin){var r;h.$validators.min=function(a){return!p(a)||x(r)||c(a)>=r};
g.$observe("min",function(a){r=q(a);h.$validate()})}if(y(g.max)||g.ngMax){var v;h.$validators.max=function(a){return!p(a)||x(v)||c(a)<=v};g.$observe("max",function(a){v=q(a);h.$validate()})}}}function td(b,a,c,d){(d.$$hasNativeValidators=J(a[0].validity))&&d.$parsers.push(function(b){var c=a.prop("validity")||{};return c.badInput&&!c.typeMismatch?t:b})}function ud(b,a,c,d,e){if(y(d)){b=b(d);if(!b.constant)throw R("ngModel")("constexpr",c,d);return b(a)}return e}function kc(b,a){b="ngClass"+b;return["$animate",
function(c){function d(a,b){var c=[],d=0;a:for(;d<a.length;d++){for(var e=a[d],n=0;n<b.length;n++)if(e==b[n])continue a;c.push(e)}return c}function e(a){if(!H(a)){if(C(a))return a.split(" ");if(J(a)){var b=[];r(a,function(a,c){a&&(b=b.concat(c.split(" ")))});return b}}return a}return{restrict:"AC",link:function(f,g,h){function l(a,b){var c=g.data("$classCounts")||{},d=[];r(a,function(a){if(0<b||c[a])c[a]=(c[a]||0)+b,c[a]===+(0<b)&&d.push(a)});g.data("$classCounts",c);return d.join(" ")}function k(b){if(!0===
a||f.$index%2===a){var k=e(b||[]);if(!n){var u=l(k,1);h.$addClass(u)}else if(!ha(b,n)){var s=e(n),u=d(k,s),k=d(s,k),u=l(u,1),k=l(k,-1);u&&u.length&&c.addClass(g,u);k&&k.length&&c.removeClass(g,k)}}n=sa(b)}var n;f.$watch(h[b],k,!0);h.$observe("class",function(a){k(f.$eval(h[b]))});"ngClass"!==b&&f.$watch("$index",function(c,d){var g=c&1;if(g!==(d&1)){var k=e(f.$eval(h[b]));g===a?(g=l(k,1),h.$addClass(g)):(g=l(k,-1),h.$removeClass(g))}})}}}]}function sd(b){function a(a,b){b&&!f[a]?(k.addClass(e,a),
f[a]=!0):!b&&f[a]&&(k.removeClass(e,a),f[a]=!1)}function c(b,c){b=b?"-"+vc(b,"-"):"";a(lb+b,!0===c);a(vd+b,!1===c)}var d=b.ctrl,e=b.$element,f={},g=b.set,h=b.unset,l=b.parentForm,k=b.$animate;f[vd]=!(f[lb]=e.hasClass(lb));d.$setValidity=function(b,e,f){e===t?(d.$pending||(d.$pending={}),g(d.$pending,b,f)):(d.$pending&&h(d.$pending,b,f),wd(d.$pending)&&(d.$pending=t));Wa(e)?e?(h(d.$error,b,f),g(d.$$success,b,f)):(g(d.$error,b,f),h(d.$$success,b,f)):(h(d.$error,b,f),h(d.$$success,b,f));d.$pending?(a(xd,
!0),d.$valid=d.$invalid=t,c("",null)):(a(xd,!1),d.$valid=wd(d.$error),d.$invalid=!d.$valid,c("",d.$valid));e=d.$pending&&d.$pending[b]?t:d.$error[b]?!1:d.$$success[b]?!0:null;c(b,e);l.$setValidity(b,e,d)}}function wd(b){if(b)for(var a in b)return!1;return!0}var Of=/^\/(.+)\/([a-z]*)$/,z=function(b){return C(b)?b.toLowerCase():b},tc=Object.prototype.hasOwnProperty,ub=function(b){return C(b)?b.toUpperCase():b},Qa,A,ta,Za=[].slice,qf=[].splice,Pf=[].push,Ca=Object.prototype.toString,Ja=R("ng"),ca=Q.angular||
(Q.angular={}),cb,ob=0;Qa=W.documentMode;E.$inject=[];ra.$inject=[];var H=Array.isArray,N=function(b){return C(b)?b.trim():b},gd=function(b){return b.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g,"\\$1").replace(/\x08/g,"\\x08")},bb=function(){if(y(bb.isActive_))return bb.isActive_;var b=!(!W.querySelector("[ng-csp]")&&!W.querySelector("[data-ng-csp]"));if(!b)try{new Function("")}catch(a){b=!0}return bb.isActive_=b},rb=["ng-","data-ng-","ng:","x-ng-"],Md=/[A-Z]/g,wc=!1,Qb,qa=1,pb=3,Qd={full:"1.3.15",major:1,
minor:3,dot:15,codeName:"locality-filtration"};T.expando="ng339";var zb=T.cache={},hf=1;T._data=function(b){return this.cache[b[this.expando]]||{}};var cf=/([\:\-\_]+(.))/g,df=/^moz([A-Z])/,Qf={mouseleave:"mouseout",mouseenter:"mouseover"},Tb=R("jqLite"),gf=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Sb=/<|&#?\w+;/,ef=/<([\w:]+)/,ff=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja={option:[1,'<select multiple="multiple">',"</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>",
"</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ja.optgroup=ja.option;ja.tbody=ja.tfoot=ja.colgroup=ja.caption=ja.thead;ja.th=ja.td;var Ka=T.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===W.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),T(Q).on("load",a))},toString:function(){var b=[];r(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=
b?A(this[b]):A(this[this.length+b])},length:0,push:Pf,sort:[].sort,splice:[].splice},Eb={};r("multiple selected checked disabled readOnly required open".split(" "),function(b){Eb[z(b)]=b});var Oc={};r("input select option textarea button form details".split(" "),function(b){Oc[b]=!0});var Pc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};r({data:Vb,removeData:xb},function(b,a){T[a]=b});r({data:Vb,inheritedData:Db,scope:function(b){return A.data(b,"$scope")||
Db(b.parentNode||b,["$isolateScope","$scope"])},isolateScope:function(b){return A.data(b,"$isolateScope")||A.data(b,"$isolateScopeNoTemplate")},controller:Kc,injector:function(b){return Db(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Ab,css:function(b,a,c){a=db(a);if(y(c))b.style[a]=c;else return b.style[a]},attr:function(b,a,c){var d=z(a);if(Eb[d])if(y(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||E).specified?
d:t;else if(y(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?t:b},prop:function(b,a,c){if(y(c))b[a]=c;else return b[a]},text:function(){function b(a,b){if(x(b)){var d=a.nodeType;return d===qa||d===pb?a.textContent:""}a.textContent=b}b.$dv="";return b}(),val:function(b,a){if(x(a)){if(b.multiple&&"select"===va(b)){var c=[];r(b.options,function(a){a.selected&&c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(x(a))return b.innerHTML;
wb(b,!0);b.innerHTML=a},empty:Lc},function(b,a){T.prototype[a]=function(a,d){var e,f,g=this.length;if(b!==Lc&&(2==b.length&&b!==Ab&&b!==Kc?a:d)===t){if(J(a)){for(e=0;e<g;e++)if(b===Vb)b(this[e],a);else for(f in a)b(this[e],f,a[f]);return this}e=b.$dv;g=e===t?Math.min(g,1):g;for(f=0;f<g;f++){var h=b(this[f],a,d);e=e?e+h:h}return e}for(e=0;e<g;e++)b(this[e],a,d);return this}});r({removeData:xb,on:function a(c,d,e,f){if(y(f))throw Tb("onargs");if(Gc(c)){var g=yb(c,!0);f=g.events;var h=g.handle;h||(h=
g.handle=lf(c,f));for(var g=0<=d.indexOf(" ")?d.split(" "):[d],l=g.length;l--;){d=g[l];var k=f[d];k||(f[d]=[],"mouseenter"===d||"mouseleave"===d?a(c,Qf[d],function(a){var c=a.relatedTarget;c&&(c===this||this.contains(c))||h(a,d)}):"$destroy"!==d&&c.addEventListener(d,h,!1),k=f[d]);k.push(e)}}},off:Jc,one:function(a,c,d){a=A(a);a.on(c,function f(){a.off(c,d);a.off(c,f)});a.on(c,d)},replaceWith:function(a,c){var d,e=a.parentNode;wb(a);r(new T(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,
a);d=c})},children:function(a){var c=[];r(a.childNodes,function(a){a.nodeType===qa&&c.push(a)});return c},contents:function(a){return a.contentDocument||a.childNodes||[]},append:function(a,c){var d=a.nodeType;if(d===qa||11===d){c=new T(c);for(var d=0,e=c.length;d<e;d++)a.appendChild(c[d])}},prepend:function(a,c){if(a.nodeType===qa){var d=a.firstChild;r(new T(c),function(c){a.insertBefore(c,d)})}},wrap:function(a,c){c=A(c).eq(0).clone()[0];var d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},
remove:Mc,detach:function(a){Mc(a,!0)},after:function(a,c){var d=a,e=a.parentNode;c=new T(c);for(var f=0,g=c.length;f<g;f++){var h=c[f];e.insertBefore(h,d.nextSibling);d=h}},addClass:Cb,removeClass:Bb,toggleClass:function(a,c,d){c&&r(c.split(" "),function(c){var f=d;x(f)&&(f=!Ab(a,c));(f?Cb:Bb)(a,c)})},parent:function(a){return(a=a.parentNode)&&11!==a.nodeType?a:null},next:function(a){return a.nextElementSibling},find:function(a,c){return a.getElementsByTagName?a.getElementsByTagName(c):[]},clone:Ub,
triggerHandler:function(a,c,d){var e,f,g=c.type||c,h=yb(a);if(h=(h=h&&h.events)&&h[g])e={preventDefault:function(){this.defaultPrevented=!0},isDefaultPrevented:function(){return!0===this.defaultPrevented},stopImmediatePropagation:function(){this.immediatePropagationStopped=!0},isImmediatePropagationStopped:function(){return!0===this.immediatePropagationStopped},stopPropagation:E,type:g,target:a},c.type&&(e=w(e,c)),c=sa(h),f=d?[e].concat(d):[e],r(c,function(c){e.isImmediatePropagationStopped()||c.apply(a,
f)})}},function(a,c){T.prototype[c]=function(c,e,f){for(var g,h=0,l=this.length;h<l;h++)x(g)?(g=a(this[h],c,e,f),y(g)&&(g=A(g))):Ic(g,a(this[h],c,e,f));return y(g)?g:this};T.prototype.bind=T.prototype.on;T.prototype.unbind=T.prototype.off});eb.prototype={put:function(a,c){this[Ma(a,this.nextUid)]=c},get:function(a){return this[Ma(a,this.nextUid)]},remove:function(a){var c=this[a=Ma(a,this.nextUid)];delete this[a];return c}};var Rc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,Rf=/,/,Sf=/^\s*(_?)(\S+?)\1\s*$/,
Qc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg,Fa=R("$injector");ab.$$annotate=function(a,c,d){var e;if("function"===typeof a){if(!(e=a.$inject)){e=[];if(a.length){if(c)throw C(d)&&d||(d=a.name||mf(a)),Fa("strictdi",d);c=a.toString().replace(Qc,"");c=c.match(Rc);r(c[1].split(Rf),function(a){a.replace(Sf,function(a,c,d){e.push(d)})})}a.$inject=e}}else H(a)?(c=a.length-1,sb(a[c],"fn"),e=a.slice(0,c)):sb(a,"fn",!0);return e};var Tf=R("$animate"),Ce=["$provide",function(a){this.$$selectors={};this.register=function(c,
d){var e=c+"-animation";if(c&&"."!=c.charAt(0))throw Tf("notcsel",c);this.$$selectors[c.substr(1)]=e;a.factory(e,d)};this.classNameFilter=function(a){1===arguments.length&&(this.$$classNameFilter=a instanceof RegExp?a:null);return this.$$classNameFilter};this.$get=["$$q","$$asyncCallback","$rootScope",function(a,d,e){function f(d){var f,g=a.defer();g.promise.$$cancelFn=function(){f&&f()};e.$$postDigest(function(){f=d(function(){g.resolve()})});return g.promise}function g(a,c){var d=[],e=[],f=ia();
r((a.attr("class")||"").split(/\s+/),function(a){f[a]=!0});r(c,function(a,c){var g=f[c];!1===a&&g?e.push(c):!0!==a||g||d.push(c)});return 0<d.length+e.length&&[d.length?d:null,e.length?e:null]}function h(a,c,d){for(var e=0,f=c.length;e<f;++e)a[c[e]]=d}function l(){n||(n=a.defer(),d(function(){n.resolve();n=null}));return n.promise}function k(a,c){if(ca.isObject(c)){var d=w(c.from||{},c.to||{});a.css(d)}}var n;return{animate:function(a,c,d){k(a,{from:c,to:d});return l()},enter:function(a,c,d,e){k(a,
e);d?d.after(a):c.prepend(a);return l()},leave:function(a,c){k(a,c);a.remove();return l()},move:function(a,c,d,e){return this.enter(a,c,d,e)},addClass:function(a,c,d){return this.setClass(a,c,[],d)},$$addClassImmediately:function(a,c,d){a=A(a);c=C(c)?c:H(c)?c.join(" "):"";r(a,function(a){Cb(a,c)});k(a,d);return l()},removeClass:function(a,c,d){return this.setClass(a,[],c,d)},$$removeClassImmediately:function(a,c,d){a=A(a);c=C(c)?c:H(c)?c.join(" "):"";r(a,function(a){Bb(a,c)});k(a,d);return l()},setClass:function(a,
c,d,e){var k=this,l=!1;a=A(a);var m=a.data("$$animateClasses");m?e&&m.options&&(m.options=ca.extend(m.options||{},e)):(m={classes:{},options:e},l=!0);e=m.classes;c=H(c)?c:c.split(" ");d=H(d)?d:d.split(" ");h(e,c,!0);h(e,d,!1);l&&(m.promise=f(function(c){var d=a.data("$$animateClasses");a.removeData("$$animateClasses");if(d){var e=g(a,d.classes);e&&k.$$setClassImmediately(a,e[0],e[1],d.options)}c()}),a.data("$$animateClasses",m));return m.promise},$$setClassImmediately:function(a,c,d,e){c&&this.$$addClassImmediately(a,
c);d&&this.$$removeClassImmediately(a,d);k(a,e);return l()},enabled:E,cancel:E}}]}],la=R("$compile");yc.$inject=["$provide","$$sanitizeUriProvider"];var Sc=/^((?:x|data)[\:\-_])/i,rf=R("$controller"),Wc="application/json",$b={"Content-Type":Wc+";charset=utf-8"},tf=/^\[|^\{(?!\{)/,uf={"[":/]$/,"{":/}$/},sf=/^\)\]\}',?\n/,ac=R("$interpolate"),Uf=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,xf={http:80,https:443,ftp:21},Gb=R("$location"),Vf={$$html5:!1,$$replace:!1,absUrl:Hb("$$absUrl"),url:function(a){if(x(a))return this.$$url;
var c=Uf.exec(a);(c[1]||""===a)&&this.path(decodeURIComponent(c[1]));(c[2]||c[1]||""===a)&&this.search(c[3]||"");this.hash(c[5]||"");return this},protocol:Hb("$$protocol"),host:Hb("$$host"),port:Hb("$$port"),path:dd("$$path",function(a){a=null!==a?a.toString():"";return"/"==a.charAt(0)?a:"/"+a}),search:function(a,c){switch(arguments.length){case 0:return this.$$search;case 1:if(C(a)||Y(a))a=a.toString(),this.$$search=sc(a);else if(J(a))a=Da(a,{}),r(a,function(c,e){null==c&&delete a[e]}),this.$$search=
a;else throw Gb("isrcharg");break;default:x(c)||null===c?delete this.$$search[a]:this.$$search[a]=c}this.$$compose();return this},hash:dd("$$hash",function(a){return null!==a?a.toString():""}),replace:function(){this.$$replace=!0;return this}};r([cd,ec,dc],function(a){a.prototype=Object.create(Vf);a.prototype.state=function(c){if(!arguments.length)return this.$$state;if(a!==dc||!this.$$html5)throw Gb("nostate");this.$$state=x(c)?null:c;return this}});var na=R("$parse"),Wf=Function.prototype.call,
Xf=Function.prototype.apply,Yf=Function.prototype.bind,mb=ia();r({"null":function(){return null},"true":function(){return!0},"false":function(){return!1},undefined:function(){}},function(a,c){a.constant=a.literal=a.sharedGetter=!0;mb[c]=a});mb["this"]=function(a){return a};mb["this"].sharedGetter=!0;var nb=w(ia(),{"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return y(d)?y(e)?d+e:d:y(e)?e:t},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(y(d)?d:0)-(y(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},
"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},
"||":function(a,c,d,e){return d(a,c)||e(a,c)},"!":function(a,c,d){return!d(a,c)},"=":!0,"|":!0}),Zf={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'},hc=function(a){this.options=a};hc.prototype={constructor:hc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index<this.text.length;)if(a=this.text.charAt(this.index),'"'===a||"'"===a)this.readString(a);else if(this.isNumber(a)||"."===a&&this.isNumber(this.peek()))this.readNumber();else if(this.isIdent(a))this.readIdent();else if(this.is(a,
"(){}[].,;:?"))this.tokens.push({index:this.index,text:a}),this.index++;else if(this.isWhitespace(a))this.index++;else{var c=a+this.peek(),d=c+this.peek(2),e=nb[c],f=nb[d];nb[a]||e||f?(a=f?d:e?c:a,this.tokens.push({index:this.index,text:a,operator:!0}),this.index+=a.length):this.throwError("Unexpected next character ",this.index,this.index+1)}return this.tokens},is:function(a,c){return-1!==c.indexOf(a)},peek:function(a){a=a||1;return this.index+a<this.text.length?this.text.charAt(this.index+a):!1},
isNumber:function(a){return"0"<=a&&"9">=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=y(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw na("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index<
this.text.length;){var d=z(this.text.charAt(this.index));if("."==d||this.isNumber(d))a+=d;else{var e=this.peek();if("e"==d&&this.isExpOperator(e))a+=d;else if(this.isExpOperator(d)&&e&&this.isNumber(e)&&"e"==a.charAt(a.length-1))a+=d;else if(!this.isExpOperator(d)||e&&this.isNumber(e)||"e"!=a.charAt(a.length-1))break;else this.throwError("Invalid exponent")}this.index++}this.tokens.push({index:c,text:a,constant:!0,value:Number(a)})},readIdent:function(){for(var a=this.index;this.index<this.text.length;){var c=
this.text.charAt(this.index);if(!this.isIdent(c)&&!this.isNumber(c))break;this.index++}this.tokens.push({index:a,text:this.text.slice(a,this.index),identifier:!0})},readString:function(a){var c=this.index;this.index++;for(var d="",e=a,f=!1;this.index<this.text.length;){var g=this.text.charAt(this.index),e=e+g;if(f)"u"===g?(f=this.text.substring(this.index+1,this.index+5),f.match(/[\da-f]{4}/i)||this.throwError("Invalid unicode escape [\\u"+f+"]"),this.index+=4,d+=String.fromCharCode(parseInt(f,16))):
d+=Zf[g]||g,f=!1;else if("\\"===g)f=!0;else{if(g===a){this.index++;this.tokens.push({index:c,text:e,constant:!0,value:d});return}d+=g}this.index++}this.throwError("Unterminated quote",c)}};var ib=function(a,c,d){this.lexer=a;this.$filter=c;this.options=d};ib.ZERO=w(function(){return 0},{sharedGetter:!0,constant:!0});ib.prototype={constructor:ib,parse:function(a){this.text=a;this.tokens=this.lexer.lex(a);a=this.statements();0!==this.tokens.length&&this.throwError("is an unexpected token",this.tokens[0]);
a.literal=!!a.literal;a.constant=!!a.constant;return a},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.peek().identifier&&this.peek().text in mb?a=mb[this.consume().text]:this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant():this.throwError("not a primary expression",this.peek());for(var c,d;c=this.expect("(","[",".");)"("===c.text?(a=this.functionCall(a,
d),d=null):"["===c.text?(d=a,a=this.objectIndex(a)):"."===c.text?(d=a,a=this.fieldAccess(a)):this.throwError("IMPOSSIBLE");return a},throwError:function(a,c){throw na("syntax",c.text,a,c.index+1,this.text,this.text.substring(c.index));},peekToken:function(){if(0===this.tokens.length)throw na("ueoe",this.text);return this.tokens[0]},peek:function(a,c,d,e){return this.peekAhead(0,a,c,d,e)},peekAhead:function(a,c,d,e,f){if(this.tokens.length>a){a=this.tokens[a];var g=a.text;if(g===c||g===d||g===e||g===
f||!(c||d||e||f))return a}return!1},expect:function(a,c,d,e){return(a=this.peek(a,c,d,e))?(this.tokens.shift(),a):!1},consume:function(a){if(0===this.tokens.length)throw na("ueoe",this.text);var c=this.expect(a);c||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return c},unaryFn:function(a,c){var d=nb[a];return w(function(a,f){return d(a,f,c)},{constant:c.constant,inputs:[c]})},binaryFn:function(a,c,d,e){var f=nb[c];return w(function(c,e){return f(c,e,a,d)},{constant:a.constant&&
d.constant,inputs:!e&&[a,d]})},identifier:function(){for(var a=this.consume().text;this.peek(".")&&this.peekAhead(1).identifier&&!this.peekAhead(2,"(");)a+=this.consume().text+this.consume().text;return zf(a,this.options,this.text)},constant:function(){var a=this.consume().value;return w(function(){return a},{constant:!0,literal:!0})},statements:function(){for(var a=[];;)if(0<this.tokens.length&&!this.peek("}",")",";","]")&&a.push(this.filterChain()),!this.expect(";"))return 1===a.length?a[0]:function(c,
d){for(var e,f=0,g=a.length;f<g;f++)e=a[f](c,d);return e}},filterChain:function(){for(var a=this.expression();this.expect("|");)a=this.filter(a);return a},filter:function(a){var c=this.$filter(this.consume().text),d,e;if(this.peek(":"))for(d=[],e=[];this.expect(":");)d.push(this.expression());var f=[a].concat(d||[]);return w(function(f,h){var l=a(f,h);if(e){e[0]=l;for(l=d.length;l--;)e[l+1]=d[l](f,h);return c.apply(t,e)}return c(l)},{constant:!c.$stateful&&f.every(fc),inputs:!c.$stateful&&f})},expression:function(){return this.assignment()},
assignment:function(){var a=this.ternary(),c,d;return(d=this.expect("="))?(a.assign||this.throwError("implies assignment but ["+this.text.substring(0,d.index)+"] can not be assigned to",d),c=this.ternary(),w(function(d,f){return a.assign(d,c(d,f),f)},{inputs:[a,c]})):a},ternary:function(){var a=this.logicalOR(),c;if(this.expect("?")&&(c=this.assignment(),this.consume(":"))){var d=this.assignment();return w(function(e,f){return a(e,f)?c(e,f):d(e,f)},{constant:a.constant&&c.constant&&d.constant})}return a},
logicalOR:function(){for(var a=this.logicalAND(),c;c=this.expect("||");)a=this.binaryFn(a,c.text,this.logicalAND(),!0);return a},logicalAND:function(){for(var a=this.equality(),c;c=this.expect("&&");)a=this.binaryFn(a,c.text,this.equality(),!0);return a},equality:function(){for(var a=this.relational(),c;c=this.expect("==","!=","===","!==");)a=this.binaryFn(a,c.text,this.relational());return a},relational:function(){for(var a=this.additive(),c;c=this.expect("<",">","<=",">=");)a=this.binaryFn(a,c.text,
this.additive());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.text,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.text,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn(ib.ZERO,a.text,this.unary()):(a=this.expect("!"))?this.unaryFn(a.text,this.unary()):this.primary()},fieldAccess:function(a){var c=
this.identifier();return w(function(d,e,f){d=f||a(d,e);return null==d?t:c(d)},{assign:function(d,e,f){var g=a(d,f);g||a.assign(d,g={},f);return c.assign(g,e)}})},objectIndex:function(a){var c=this.text,d=this.expression();this.consume("]");return w(function(e,f){var g=a(e,f),h=d(e,f);ua(h,c);return g?oa(g[h],c):t},{assign:function(e,f,g){var h=ua(d(e,g),c),l=oa(a(e,g),c);l||a.assign(e,l={},g);return l[h]=f}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());
while(this.expect(","))}this.consume(")");var e=this.text,f=d.length?[]:null;return function(g,h){var l=c?c(g,h):y(c)?t:g,k=a(g,h,l)||E;if(f)for(var n=d.length;n--;)f[n]=oa(d[n](g,h),e);oa(l,e);if(k){if(k.constructor===k)throw na("isecfn",e);if(k===Wf||k===Xf||k===Yf)throw na("isecff",e);}l=k.apply?k.apply(l,f):k(f[0],f[1],f[2],f[3],f[4]);f&&(f.length=0);return oa(l,e)}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break;a.push(this.expression())}while(this.expect(","))
}this.consume("]");return w(function(c,d){for(var e=[],f=0,g=a.length;f<g;f++)e.push(a[f](c,d));return e},{literal:!0,constant:a.every(fc),inputs:a})},object:function(){var a=[],c=[];if("}"!==this.peekToken().text){do{if(this.peek("}"))break;var d=this.consume();d.constant?a.push(d.value):d.identifier?a.push(d.text):this.throwError("invalid key",d);this.consume(":");c.push(this.expression())}while(this.expect(","))}this.consume("}");return w(function(d,f){for(var g={},h=0,l=c.length;h<l;h++)g[a[h]]=
c[h](d,f);return g},{literal:!0,constant:c.every(fc),inputs:c})}};var Bf=ia(),Af=ia(),Cf=Object.prototype.valueOf,Ba=R("$sce"),pa={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},la=R("$compile"),$=W.createElement("a"),id=Aa(Q.location.href);Fc.$inject=["$provide"];jd.$inject=["$locale"];ld.$inject=["$locale"];var od=".",Mf={yyyy:U("FullYear",4),yy:U("FullYear",2,0,!0),y:U("FullYear",1),MMMM:Jb("Month"),MMM:Jb("Month",!0),MM:U("Month",2,1),M:U("Month",1,1),dd:U("Date",2),d:U("Date",
1),HH:U("Hours",2),H:U("Hours",1),hh:U("Hours",2,-12),h:U("Hours",1,-12),mm:U("Minutes",2),m:U("Minutes",1),ss:U("Seconds",2),s:U("Seconds",1),sss:U("Milliseconds",3),EEEE:Jb("Day"),EEE:Jb("Day",!0),a:function(a,c){return 12>a.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ib(Math[0<a?"floor":"ceil"](a/60),2)+Ib(Math.abs(a%60),2))},ww:qd(2),w:qd(1),G:ic,GG:ic,GGG:ic,GGGG:function(a,c){return 0>=a.getFullYear()?c.ERANAMES[0]:c.ERANAMES[1]}},Lf=/((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,
Kf=/^\-?\d+$/;kd.$inject=["$locale"];var Hf=ea(z),If=ea(ub);md.$inject=["$parse"];var Td=ea({restrict:"E",compile:function(a,c){if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){if("a"===c[0].nodeName.toLowerCase()){var f="[object SVGAnimatedString]"===Ca.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(f)||a.preventDefault()})}}}}),vb={};r(Eb,function(a,c){if("multiple"!=a){var d=xa("ng-"+c);vb[d]=function(){return{restrict:"A",priority:100,link:function(a,f,g){a.$watch(g[d],
function(a){g.$set(c,!!a)})}}}}});r(Pc,function(a,c){vb[c]=function(){return{priority:100,link:function(a,e,f){if("ngPattern"===c&&"/"==f.ngPattern.charAt(0)&&(e=f.ngPattern.match(Of))){f.$set("ngPattern",new RegExp(e[1],e[2]));return}a.$watch(f[c],function(a){f.$set(c,a)})}}}});r(["src","srcset","href"],function(a){var c=xa("ng-"+a);vb[c]=function(){return{priority:99,link:function(d,e,f){var g=a,h=a;"href"===a&&"[object SVGAnimatedString]"===Ca.call(e.prop("href"))&&(h="xlinkHref",f.$attr[h]="xlink:href",
g=null);f.$observe(c,function(c){c?(f.$set(h,c),Qa&&g&&e.prop(g,f[h])):"href"===a&&f.$set(h,null)})}}}});var Kb={$addControl:E,$$renameControl:function(a,c){a.$name=c},$removeControl:E,$setValidity:E,$setDirty:E,$setPristine:E,$setSubmitted:E};rd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var yd=function(a){return["$timeout",function(c){return{name:"form",restrict:a?"EAC":"E",controller:rd,compile:function(d,e){d.addClass(Ra).addClass(lb);var f=e.name?"name":a&&e.ngForm?"ngForm":
!1;return{pre:function(a,d,e,k){if(!("action"in e)){var n=function(c){a.$apply(function(){k.$commitViewValue();k.$setSubmitted()});c.preventDefault()};d[0].addEventListener("submit",n,!1);d.on("$destroy",function(){c(function(){d[0].removeEventListener("submit",n,!1)},0,!1)})}var p=k.$$parentForm;f&&(hb(a,null,k.$name,k,k.$name),e.$observe(f,function(c){k.$name!==c&&(hb(a,null,k.$name,t,k.$name),p.$$renameControl(k,c),hb(a,null,k.$name,k,k.$name))}));d.on("$destroy",function(){p.$removeControl(k);
f&&hb(a,null,e[f],t,k.$name);w(k,Kb)})}}}}}]},Ud=yd(),ge=yd(!0),Nf=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,$f=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,ag=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,bg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,zd=/^(\d{4})-(\d{2})-(\d{2})$/,Ad=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,lc=/^(\d{4})-W(\d\d)$/,Bd=/^(\d{4})-(\d\d)$/,
Cd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Dd={text:function(a,c,d,e,f,g){jb(a,c,d,e,f,g);jc(e)},date:kb("date",zd,Mb(zd,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":kb("datetimelocal",Ad,Mb(Ad,"yyyy MM dd HH mm ss sss".split(" ")),"yyyy-MM-ddTHH:mm:ss.sss"),time:kb("time",Cd,Mb(Cd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:kb("week",lc,function(a,c){if(ga(a))return a;if(C(a)){lc.lastIndex=0;var d=lc.exec(a);if(d){var e=+d[1],f=+d[2],g=d=0,h=0,l=0,k=pd(e),f=7*(f-1);c&&(d=c.getHours(),g=
c.getMinutes(),h=c.getSeconds(),l=c.getMilliseconds());return new Date(e,0,k.getDate()+f,d,g,h,l)}}return NaN},"yyyy-Www"),month:kb("month",Bd,Mb(Bd,["yyyy","MM"]),"yyyy-MM"),number:function(a,c,d,e,f,g){td(a,c,d,e);jb(a,c,d,e,f,g);e.$$parserName="number";e.$parsers.push(function(a){return e.$isEmpty(a)?null:bg.test(a)?parseFloat(a):t});e.$formatters.push(function(a){if(!e.$isEmpty(a)){if(!Y(a))throw Nb("numfmt",a);a=a.toString()}return a});if(y(d.min)||d.ngMin){var h;e.$validators.min=function(a){return e.$isEmpty(a)||
x(h)||a>=h};d.$observe("min",function(a){y(a)&&!Y(a)&&(a=parseFloat(a,10));h=Y(a)&&!isNaN(a)?a:t;e.$validate()})}if(y(d.max)||d.ngMax){var l;e.$validators.max=function(a){return e.$isEmpty(a)||x(l)||a<=l};d.$observe("max",function(a){y(a)&&!Y(a)&&(a=parseFloat(a,10));l=Y(a)&&!isNaN(a)?a:t;e.$validate()})}},url:function(a,c,d,e,f,g){jb(a,c,d,e,f,g);jc(e);e.$$parserName="url";e.$validators.url=function(a,c){var d=a||c;return e.$isEmpty(d)||$f.test(d)}},email:function(a,c,d,e,f,g){jb(a,c,d,e,f,g);jc(e);
e.$$parserName="email";e.$validators.email=function(a,c){var d=a||c;return e.$isEmpty(d)||ag.test(d)}},radio:function(a,c,d,e){x(d.name)&&c.attr("name",++ob);c.on("click",function(a){c[0].checked&&e.$setViewValue(d.value,a&&a.type)});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e,f,g,h,l){var k=ud(l,a,"ngTrueValue",d.ngTrueValue,!0),n=ud(l,a,"ngFalseValue",d.ngFalseValue,!1);c.on("click",function(a){e.$setViewValue(c[0].checked,a&&
a.type)});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return!1===a};e.$formatters.push(function(a){return ha(a,k)});e.$parsers.push(function(a){return a?k:n})},hidden:E,button:E,submit:E,reset:E,file:E},zc=["$browser","$sniffer","$filter","$parse",function(a,c,d,e){return{restrict:"E",require:["?ngModel"],link:{pre:function(f,g,h,l){l[0]&&(Dd[z(h.type)]||Dd.text)(f,g,h,l[0],c,a,d,e)}}}}],cg=/^(true|false|\d+)$/,ye=function(){return{restrict:"A",priority:100,compile:function(a,
c){return cg.test(c.ngValue)?function(a,c,f){f.$set("value",a.$eval(f.ngValue))}:function(a,c,f){a.$watch(f.ngValue,function(a){f.$set("value",a)})}}}},Zd=["$compile",function(a){return{restrict:"AC",compile:function(c){a.$$addBindingClass(c);return function(c,e,f){a.$$addBindingInfo(e,f.ngBind);e=e[0];c.$watch(f.ngBind,function(a){e.textContent=a===t?"":a})}}}}],ae=["$interpolate","$compile",function(a,c){return{compile:function(d){c.$$addBindingClass(d);return function(d,f,g){d=a(f.attr(g.$attr.ngBindTemplate));
c.$$addBindingInfo(f,d.expressions);f=f[0];g.$observe("ngBindTemplate",function(a){f.textContent=a===t?"":a})}}}}],$d=["$sce","$parse","$compile",function(a,c,d){return{restrict:"A",compile:function(e,f){var g=c(f.ngBindHtml),h=c(f.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(e);return function(c,e,f){d.$$addBindingInfo(e,f.ngBindHtml);c.$watch(h,function(){e.html(a.getTrustedHtml(g(c))||"")})}}}}],xe=ea({restrict:"A",require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),
be=kc("",!0),de=kc("Odd",0),ce=kc("Even",1),ee=Ia({compile:function(a,c){c.$set("ngCloak",t);a.removeClass("ng-cloak")}}),fe=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ec={},dg={blur:!0,focus:!0};r("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=xa("ng-"+a);Ec[c]=["$parse","$rootScope",function(d,e){return{restrict:"A",compile:function(f,g){var h=
d(g[c],null,!0);return function(c,d){d.on(a,function(d){var f=function(){h(c,{$event:d})};dg[a]&&e.$$phase?c.$evalAsync(f):c.$apply(f)})}}}}]});var ie=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(c,d,e,f,g){var h,l,k;c.$watch(e.ngIf,function(c){c?l||g(function(c,f){l=f;c[c.length++]=W.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)}):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=
tb(h.clone),a.leave(k).then(function(){k=null}),h=null))})}}}],je=["$templateRequest","$anchorScroll","$animate","$sce",function(a,c,d,e){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:ca.noop,compile:function(f,g){var h=g.ngInclude||g.src,l=g.onload||"",k=g.autoscroll;return function(f,g,q,r,s){var t=0,v,m,F,w=function(){m&&(m.remove(),m=null);v&&(v.$destroy(),v=null);F&&(d.leave(F).then(function(){m=null}),m=F,F=null)};f.$watch(e.parseAsResourceUrl(h),function(e){var h=
function(){!y(k)||k&&!f.$eval(k)||c()},m=++t;e?(a(e,!0).then(function(a){if(m===t){var c=f.$new();r.template=a;a=s(c,function(a){w();d.enter(a,null,g).then(h)});v=c;F=a;v.$emit("$includeContentLoaded",e);f.$eval(l)}},function(){m===t&&(w(),f.$emit("$includeContentError",e))}),f.$emit("$includeContentRequested",e)):(w(),r.template=null)})}}}}],Ae=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,f){/SVG/.test(d[0].toString())?(d.empty(),a(Hc(f.template,
W).childNodes)(c,function(a){d.append(a)},{futureParentElement:d})):(d.html(f.template),a(d.contents())(c))}}}],ke=Ia({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),we=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,c,d,e){var f=c.attr(d.$attr.ngList)||", ",g="false"!==d.ngTrim,h=g?N(f):f;e.$parsers.push(function(a){if(!x(a)){var c=[];a&&r(a.split(h),function(a){a&&c.push(g?N(a):a)});return c}});e.$formatters.push(function(a){return H(a)?
a.join(f):t});e.$isEmpty=function(a){return!a||!a.length}}}},lb="ng-valid",vd="ng-invalid",Ra="ng-pristine",Lb="ng-dirty",xd="ng-pending",Nb=new R("ngModel"),eg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,c,d,e,f,g,h,l,k,n){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=t;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;
this.$touched=!1;this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=t;this.$name=n(d.name||"",!1)(a);var p=f(d.ngModel),q=p.assign,u=p,s=q,M=null,v,m=this;this.$$setOptions=function(a){if((m.$options=a)&&a.getterSetter){var c=f(d.ngModel+"()"),g=f(d.ngModel+"($$$p)");u=function(a){var d=p(a);G(d)&&(d=c(a));return d};s=function(a,c){G(p(a))?g(a,{$$$p:m.$modelValue}):q(a,m.$modelValue)}}else if(!p.assign)throw Nb("nonassign",d.ngModel,wa(e));
};this.$render=E;this.$isEmpty=function(a){return x(a)||""===a||null===a||a!==a};var F=e.inheritedData("$formController")||Kb,w=0;sd({ctrl:this,$element:e,set:function(a,c){a[c]=!0},unset:function(a,c){delete a[c]},parentForm:F,$animate:g});this.$setPristine=function(){m.$dirty=!1;m.$pristine=!0;g.removeClass(e,Lb);g.addClass(e,Ra)};this.$setDirty=function(){m.$dirty=!0;m.$pristine=!1;g.removeClass(e,Ra);g.addClass(e,Lb);F.$setDirty()};this.$setUntouched=function(){m.$touched=!1;m.$untouched=!0;g.setClass(e,
"ng-untouched","ng-touched")};this.$setTouched=function(){m.$touched=!0;m.$untouched=!1;g.setClass(e,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){h.cancel(M);m.$viewValue=m.$$lastCommittedViewValue;m.$render()};this.$validate=function(){if(!Y(m.$modelValue)||!isNaN(m.$modelValue)){var a=m.$$rawModelValue,c=m.$valid,d=m.$modelValue,e=m.$options&&m.$options.allowInvalid;m.$$runValidators(a,m.$$lastCommittedViewValue,function(f){e||c===f||(m.$modelValue=f?a:t,m.$modelValue!==d&&m.$$writeModelToScope())})}};
this.$$runValidators=function(a,c,d){function e(){var d=!0;r(m.$validators,function(e,f){var h=e(a,c);d=d&&h;g(f,h)});return d?!0:(r(m.$asyncValidators,function(a,c){g(c,null)}),!1)}function f(){var d=[],e=!0;r(m.$asyncValidators,function(f,h){var k=f(a,c);if(!k||!G(k.then))throw Nb("$asyncValidators",k);g(h,t);d.push(k.then(function(){g(h,!0)},function(a){e=!1;g(h,!1)}))});d.length?k.all(d).then(function(){h(e)},E):h(!0)}function g(a,c){l===w&&m.$setValidity(a,c)}function h(a){l===w&&d(a)}w++;var l=
w;(function(){var a=m.$$parserName||"parse";if(v===t)g(a,null);else return v||(r(m.$validators,function(a,c){g(c,null)}),r(m.$asyncValidators,function(a,c){g(c,null)})),g(a,v),v;return!0})()?e()?f():h(!1):h(!1)};this.$commitViewValue=function(){var a=m.$viewValue;h.cancel(M);if(m.$$lastCommittedViewValue!==a||""===a&&m.$$hasNativeValidators)m.$$lastCommittedViewValue=a,m.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var c=m.$$lastCommittedViewValue;if(v=
x(c)?t:!0)for(var d=0;d<m.$parsers.length;d++)if(c=m.$parsers[d](c),x(c)){v=!1;break}Y(m.$modelValue)&&isNaN(m.$modelValue)&&(m.$modelValue=u(a));var e=m.$modelValue,f=m.$options&&m.$options.allowInvalid;m.$$rawModelValue=c;f&&(m.$modelValue=c,m.$modelValue!==e&&m.$$writeModelToScope());m.$$runValidators(c,m.$$lastCommittedViewValue,function(a){f||(m.$modelValue=a?c:t,m.$modelValue!==e&&m.$$writeModelToScope())})};this.$$writeModelToScope=function(){s(a,m.$modelValue);r(m.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};
this.$setViewValue=function(a,c){m.$viewValue=a;m.$options&&!m.$options.updateOnDefault||m.$$debounceViewValueCommit(c)};this.$$debounceViewValueCommit=function(c){var d=0,e=m.$options;e&&y(e.debounce)&&(e=e.debounce,Y(e)?d=e:Y(e[c])?d=e[c]:Y(e["default"])&&(d=e["default"]));h.cancel(M);d?M=h(function(){m.$commitViewValue()},d):l.$$phase?m.$commitViewValue():a.$apply(function(){m.$commitViewValue()})};a.$watch(function(){var c=u(a);if(c!==m.$modelValue){m.$modelValue=m.$$rawModelValue=c;v=t;for(var d=
m.$formatters,e=d.length,f=c;e--;)f=d[e](f);m.$viewValue!==f&&(m.$viewValue=m.$$lastCommittedViewValue=f,m.$render(),m.$$runValidators(c,f,E))}return c})}],ve=["$rootScope",function(a){return{restrict:"A",require:["ngModel","^?form","^?ngModelOptions"],controller:eg,priority:1,compile:function(c){c.addClass(Ra).addClass("ng-untouched").addClass(lb);return{pre:function(a,c,f,g){var h=g[0],l=g[1]||Kb;h.$$setOptions(g[2]&&g[2].$options);l.$addControl(h);f.$observe("name",function(a){h.$name!==a&&l.$$renameControl(h,
a)});a.$on("$destroy",function(){l.$removeControl(h)})},post:function(c,e,f,g){var h=g[0];if(h.$options&&h.$options.updateOn)e.on(h.$options.updateOn,function(a){h.$$debounceViewValueCommit(a&&a.type)});e.on("blur",function(e){h.$touched||(a.$$phase?c.$evalAsync(h.$setTouched):c.$apply(h.$setTouched))})}}}}}],fg=/(\s+|^)default(\s+|$)/,ze=function(){return{restrict:"A",controller:["$scope","$attrs",function(a,c){var d=this;this.$options=a.$eval(c.ngModelOptions);this.$options.updateOn!==t?(this.$options.updateOnDefault=
!1,this.$options.updateOn=N(this.$options.updateOn.replace(fg,function(){d.$options.updateOnDefault=!0;return" "}))):this.$options.updateOnDefault=!0}]}},le=Ia({terminal:!0,priority:1E3}),me=["$locale","$interpolate",function(a,c){var d=/{}/g,e=/^when(Minus)?(.+)$/;return{restrict:"EA",link:function(f,g,h){function l(a){g.text(a||"")}var k=h.count,n=h.$attr.when&&g.attr(h.$attr.when),p=h.offset||0,q=f.$eval(n)||{},u={},n=c.startSymbol(),s=c.endSymbol(),t=n+k+"-"+p+s,v=ca.noop,m;r(h,function(a,c){var d=
e.exec(c);d&&(d=(d[1]?"-":"")+z(d[2]),q[d]=g.attr(h.$attr[c]))});r(q,function(a,e){u[e]=c(a.replace(d,t))});f.$watch(k,function(c){c=parseFloat(c);var d=isNaN(c);d||c in q||(c=a.pluralCat(c-p));c===m||d&&isNaN(m)||(v(),v=f.$watch(u[c],l),m=c)})}}}],ne=["$parse","$animate",function(a,c){var d=R("ngRepeat"),e=function(a,c,d,e,k,n,p){a[d]=e;k&&(a[k]=n);a.$index=c;a.$first=0===c;a.$last=c===p-1;a.$middle=!(a.$first||a.$last);a.$odd=!(a.$even=0===(c&1))};return{restrict:"A",multiElement:!0,transclude:"element",
priority:1E3,terminal:!0,$$tlb:!0,compile:function(f,g){var h=g.ngRepeat,l=W.createComment(" end ngRepeat: "+h+" "),k=h.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);if(!k)throw d("iexp",h);var n=k[1],p=k[2],q=k[3],u=k[4],k=n.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/);if(!k)throw d("iidexp",n);var s=k[3]||k[1],y=k[2];if(q&&(!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(q)||/^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(q)))throw d("badident",
q);var v,m,w,x,E={$id:Ma};u?v=a(u):(w=function(a,c){return Ma(c)},x=function(a){return a});return function(a,f,g,k,n){v&&(m=function(c,d,e){y&&(E[y]=c);E[s]=d;E.$index=e;return v(a,E)});var u=ia();a.$watchCollection(p,function(g){var k,p,v=f[0],D,E=ia(),G,H,L,S,J,C,z;q&&(a[q]=g);if(Sa(g))J=g,p=m||w;else{p=m||x;J=[];for(z in g)g.hasOwnProperty(z)&&"$"!=z.charAt(0)&&J.push(z);J.sort()}G=J.length;z=Array(G);for(k=0;k<G;k++)if(H=g===J?k:J[k],L=g[H],S=p(H,L,k),u[S])C=u[S],delete u[S],E[S]=C,z[k]=C;else{if(E[S])throw r(z,
function(a){a&&a.scope&&(u[a.id]=a)}),d("dupes",h,S,L);z[k]={id:S,scope:t,clone:t};E[S]=!0}for(D in u){C=u[D];S=tb(C.clone);c.leave(S);if(S[0].parentNode)for(k=0,p=S.length;k<p;k++)S[k].$$NG_REMOVED=!0;C.scope.$destroy()}for(k=0;k<G;k++)if(H=g===J?k:J[k],L=g[H],C=z[k],C.scope){D=v;do D=D.nextSibling;while(D&&D.$$NG_REMOVED);C.clone[0]!=D&&c.move(tb(C.clone),null,A(v));v=C.clone[C.clone.length-1];e(C.scope,k,s,L,y,H,G)}else n(function(a,d){C.scope=d;var f=l.cloneNode(!1);a[a.length++]=f;c.enter(a,
null,A(v));v=f;C.clone=a;E[C.id]=C;e(C.scope,k,s,L,y,H,G)});u=E})}}}}],oe=["$animate",function(a){return{restrict:"A",multiElement:!0,link:function(c,d,e){c.$watch(e.ngShow,function(c){a[c?"removeClass":"addClass"](d,"ng-hide",{tempClasses:"ng-hide-animate"})})}}}],he=["$animate",function(a){return{restrict:"A",multiElement:!0,link:function(c,d,e){c.$watch(e.ngHide,function(c){a[c?"addClass":"removeClass"](d,"ng-hide",{tempClasses:"ng-hide-animate"})})}}}],pe=Ia(function(a,c,d){a.$watchCollection(d.ngStyle,
function(a,d){d&&a!==d&&r(d,function(a,d){c.css(d,"")});a&&c.css(a)})}),qe=["$animate",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,f){var g=[],h=[],l=[],k=[],n=function(a,c){return function(){a.splice(c,1)}};c.$watch(e.ngSwitch||e.on,function(c){var d,e;d=0;for(e=l.length;d<e;++d)a.cancel(l[d]);d=l.length=0;for(e=k.length;d<e;++d){var s=tb(h[d].clone);k[d].$destroy();(l[d]=a.leave(s)).then(n(l,d))}h.length=0;k.length=0;(g=
f.cases["!"+c]||f.cases["?"])&&r(g,function(c){c.transclude(function(d,e){k.push(e);var f=c.element;d[d.length++]=W.createComment(" end ngSwitchWhen: ");h.push({clone:d});a.enter(d,f.parent(),f)})})})}}}],re=Ia({transclude:"element",priority:1200,require:"^ngSwitch",multiElement:!0,link:function(a,c,d,e,f){e.cases["!"+d.ngSwitchWhen]=e.cases["!"+d.ngSwitchWhen]||[];e.cases["!"+d.ngSwitchWhen].push({transclude:f,element:c})}}),se=Ia({transclude:"element",priority:1200,require:"^ngSwitch",multiElement:!0,
link:function(a,c,d,e,f){e.cases["?"]=e.cases["?"]||[];e.cases["?"].push({transclude:f,element:c})}}),ue=Ia({restrict:"EAC",link:function(a,c,d,e,f){if(!f)throw R("ngTransclude")("orphan",wa(c));f(function(a){c.empty();c.append(a)})}}),Vd=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){"text/ng-template"==d.type&&a.put(d.id,c[0].text)}}}],gg=R("ngOptions"),te=ea({restrict:"A",terminal:!0}),Wd=["$compile","$parse",function(a,c){var d=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/,
e={$setViewValue:E};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var l=this,k={},n=e,p;l.databound=d.ngModel;l.init=function(a,c,d){n=a;p=d};l.addOption=function(c,d){La(c,'"option value"');k[c]=!0;n.$viewValue==c&&(a.val(c),p.parent()&&p.remove());d&&d[0].hasAttribute("selected")&&(d[0].selected=!0)};l.removeOption=function(a){this.hasOption(a)&&(delete k[a],n.$viewValue===a&&this.renderUnknownOption(a))};l.renderUnknownOption=function(c){c=
"? "+Ma(c)+" ?";p.val(c);a.prepend(p);a.val(c);p.prop("selected",!0)};l.hasOption=function(a){return k.hasOwnProperty(a)};c.$on("$destroy",function(){l.renderUnknownOption=E})}],link:function(e,g,h,l){function k(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(C.parent()&&C.remove(),c.val(a),""===a&&v.prop("selected",!0)):x(a)&&v?c.val(""):e.renderUnknownOption(a)};c.on("change",function(){a.$apply(function(){C.parent()&&C.remove();d.$setViewValue(c.val())})})}function n(a,c,d){var e;
d.$render=function(){var a=new eb(d.$viewValue);r(c.find("option"),function(c){c.selected=y(a.get(c.value))})};a.$watch(function(){ha(e,d.$viewValue)||(e=sa(d.$viewValue),d.$render())});c.on("change",function(){a.$apply(function(){var a=[];r(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function p(e,f,g){function h(a,c,d){T[x]=d;G&&(T[G]=c);return a(e,T)}function k(a){var c;if(u)if(I&&H(a)){c=new eb([]);for(var d=0;d<a.length;d++)c.put(h(I,null,a[d]),!0)}else c=
new eb(a);else I&&(a=h(I,null,a));return function(d,e){var f;f=I?I:B?B:z;return u?y(c.remove(h(f,d,e))):a===h(f,d,e)}}function l(){m||(e.$$postDigest(p),m=!0)}function n(a,c,d){a[c]=a[c]||0;a[c]+=d?1:-1}function p(){m=!1;var a={"":[]},c=[""],d,l,s,t,v;s=g.$viewValue;t=L(e)||[];var B=G?Object.keys(t).sort():t,x,A,H,z,O={};v=k(s);var N=!1,U,W;Q={};for(z=0;H=B.length,z<H;z++){x=z;if(G&&(x=B[z],"$"===x.charAt(0)))continue;A=t[x];d=h(J,x,A)||"";(l=a[d])||(l=a[d]=[],c.push(d));d=v(x,A);N=N||d;A=h(C,x,A);
A=y(A)?A:"";W=I?I(e,T):G?B[z]:z;I&&(Q[W]=x);l.push({id:W,label:A,selected:d})}u||(w||null===s?a[""].unshift({id:"",label:"",selected:!N}):N||a[""].unshift({id:"?",label:"",selected:!0}));x=0;for(B=c.length;x<B;x++){d=c[x];l=a[d];R.length<=x?(s={element:E.clone().attr("label",d),label:l.label},t=[s],R.push(t),f.append(s.element)):(t=R[x],s=t[0],s.label!=d&&s.element.attr("label",s.label=d));N=null;z=0;for(H=l.length;z<H;z++)d=l[z],(v=t[z+1])?(N=v.element,v.label!==d.label&&(n(O,v.label,!1),n(O,d.label,
!0),N.text(v.label=d.label),N.prop("label",v.label)),v.id!==d.id&&N.val(v.id=d.id),N[0].selected!==d.selected&&(N.prop("selected",v.selected=d.selected),Qa&&N.prop("selected",v.selected))):(""===d.id&&w?U=w:(U=F.clone()).val(d.id).prop("selected",d.selected).attr("selected",d.selected).prop("label",d.label).text(d.label),t.push(v={element:U,label:d.label,id:d.id,selected:d.selected}),n(O,d.label,!0),N?N.after(U):s.element.append(U),N=U);for(z++;t.length>z;)d=t.pop(),n(O,d.label,!1),d.element.remove()}for(;R.length>
x;){l=R.pop();for(z=1;z<l.length;++z)n(O,l[z].label,!1);l[0].element.remove()}r(O,function(a,c){0<a?q.addOption(c):0>a&&q.removeOption(c)})}var v;if(!(v=s.match(d)))throw gg("iexp",s,wa(f));var C=c(v[2]||v[1]),x=v[4]||v[6],A=/ as /.test(v[0])&&v[1],B=A?c(A):null,G=v[5],J=c(v[3]||""),z=c(v[2]?v[1]:x),L=c(v[7]),I=v[8]?c(v[8]):null,Q={},R=[[{element:f,label:""}]],T={};w&&(a(w)(e),w.removeClass("ng-scope"),w.remove());f.empty();f.on("change",function(){e.$apply(function(){var a=L(e)||[],c;if(u)c=[],r(f.val(),
function(d){d=I?Q[d]:d;c.push("?"===d?t:""===d?null:h(B?B:z,d,a[d]))});else{var d=I?Q[f.val()]:f.val();c="?"===d?t:""===d?null:h(B?B:z,d,a[d])}g.$setViewValue(c);p()})});g.$render=p;e.$watchCollection(L,l);e.$watchCollection(function(){var a=L(e),c;if(a&&H(a)){c=Array(a.length);for(var d=0,f=a.length;d<f;d++)c[d]=h(C,d,a[d])}else if(a)for(d in c={},a)a.hasOwnProperty(d)&&(c[d]=h(C,d,a[d]));return c},l);u&&e.$watchCollection(function(){return g.$modelValue},l)}if(l[1]){var q=l[0];l=l[1];var u=h.multiple,
s=h.ngOptions,w=!1,v,m=!1,F=A(W.createElement("option")),E=A(W.createElement("optgroup")),C=F.clone();h=0;for(var B=g.children(),G=B.length;h<G;h++)if(""===B[h].value){v=w=B.eq(h);break}q.init(l,w,C);u&&(l.$isEmpty=function(a){return!a||0===a.length});s?p(e,g,l):u?n(e,g,l):k(e,g,l,q)}}}}],Yd=["$interpolate",function(a){var c={addOption:E,removeOption:E};return{restrict:"E",priority:100,compile:function(d,e){if(x(e.value)){var f=a(d.text(),!0);f||e.$set("value",d.text())}return function(a,d,e){var k=
d.parent(),n=k.data("$selectController")||k.parent().data("$selectController");n&&n.databound||(n=c);f?a.$watch(f,function(a,c){e.$set("value",a);c!==a&&n.removeOption(c);n.addOption(a,d)}):n.addOption(e.value,d);d.on("$destroy",function(){n.removeOption(e.value)})}}}}],Xd=ea({restrict:"E",terminal:!1}),Bc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){e&&(d.required=!0,e.$validators.required=function(a,c){return!d.required||!e.$isEmpty(c)},d.$observe("required",function(){e.$validate()}))}}},
Ac=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f,g=d.ngPattern||d.pattern;d.$observe("pattern",function(a){C(a)&&0<a.length&&(a=new RegExp("^"+a+"$"));if(a&&!a.test)throw R("ngPattern")("noregexp",g,a,wa(c));f=a||t;e.$validate()});e.$validators.pattern=function(a){return e.$isEmpty(a)||x(f)||f.test(a)}}}}},Dc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=-1;d.$observe("maxlength",function(a){a=aa(a);f=isNaN(a)?-1:a;e.$validate()});
e.$validators.maxlength=function(a,c){return 0>f||e.$isEmpty(c)||c.length<=f}}}}},Cc=function(){return{restrict:"A",require:"?ngModel",link:function(a,c,d,e){if(e){var f=0;d.$observe("minlength",function(a){f=aa(a)||0;e.$validate()});e.$validators.minlength=function(a,c){return e.$isEmpty(c)||c.length>=f}}}}};Q.angular.bootstrap?console.log("WARNING: Tried to load angular more than once."):(Nd(),Pd(ca),A(W).ready(function(){Jd(W,uc)}))})(window,document);!window.angular.$$csp()&&window.angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}</style>');
//# sourceMappingURL=angular.min.js.map
;
/*
 AngularJS v1.3.15
 (c) 2010-2014 Google, Inc. http://angularjs.org
 License: MIT
*/
(function(N,f,W){'use strict';f.module("ngAnimate",["ng"]).directive("ngAnimateChildren",function(){return function(X,C,g){g=g.ngAnimateChildren;f.isString(g)&&0===g.length?C.data("$$ngAnimateChildren",!0):X.$watch(g,function(f){C.data("$$ngAnimateChildren",!!f)})}}).factory("$$animateReflow",["$$rAF","$document",function(f,C){return function(g){return f(function(){g()})}}]).config(["$provide","$animateProvider",function(X,C){function g(f){for(var n=0;n<f.length;n++){var g=f[n];if(1==g.nodeType)return g}}
function ba(f,n){return g(f)==g(n)}var t=f.noop,n=f.forEach,da=C.$$selectors,aa=f.isArray,ea=f.isString,ga=f.isObject,r={running:!0},u;X.decorator("$animate",["$delegate","$$q","$injector","$sniffer","$rootElement","$$asyncCallback","$rootScope","$document","$templateRequest","$$jqLite",function(O,N,M,Y,y,H,P,W,Z,Q){function R(a,c){var b=a.data("$$ngAnimateState")||{};c&&(b.running=!0,b.structural=!0,a.data("$$ngAnimateState",b));return b.disabled||b.running&&b.structural}function D(a){var c,b=N.defer();
b.promise.$$cancelFn=function(){c&&c()};P.$$postDigest(function(){c=a(function(){b.resolve()})});return b.promise}function I(a){if(ga(a))return a.tempClasses&&ea(a.tempClasses)&&(a.tempClasses=a.tempClasses.split(/\s+/)),a}function S(a,c,b){b=b||{};var d={};n(b,function(e,a){n(a.split(" "),function(a){d[a]=e})});var h=Object.create(null);n((a.attr("class")||"").split(/\s+/),function(e){h[e]=!0});var f=[],l=[];n(c&&c.classes||[],function(e,a){var b=h[a],c=d[a]||{};!1===e?(b||"addClass"==c.event)&&
l.push(a):!0===e&&(b&&"removeClass"!=c.event||f.push(a))});return 0<f.length+l.length&&[f.join(" "),l.join(" ")]}function T(a){if(a){var c=[],b={};a=a.substr(1).split(".");(Y.transitions||Y.animations)&&c.push(M.get(da[""]));for(var d=0;d<a.length;d++){var f=a[d],k=da[f];k&&!b[f]&&(c.push(M.get(k)),b[f]=!0)}return c}}function U(a,c,b,d){function h(e,a){var b=e[a],c=e["before"+a.charAt(0).toUpperCase()+a.substr(1)];if(b||c)return"leave"==a&&(c=b,b=null),u.push({event:a,fn:b}),J.push({event:a,fn:c}),
!0}function k(c,l,w){var E=[];n(c,function(a){a.fn&&E.push(a)});var m=0;n(E,function(c,f){var p=function(){a:{if(l){(l[f]||t)();if(++m<E.length)break a;l=null}w()}};switch(c.event){case "setClass":l.push(c.fn(a,e,A,p,d));break;case "animate":l.push(c.fn(a,b,d.from,d.to,p));break;case "addClass":l.push(c.fn(a,e||b,p,d));break;case "removeClass":l.push(c.fn(a,A||b,p,d));break;default:l.push(c.fn(a,p,d))}});l&&0===l.length&&w()}var l=a[0];if(l){d&&(d.to=d.to||{},d.from=d.from||{});var e,A;aa(b)&&(e=
b[0],A=b[1],e?A?b=e+" "+A:(b=e,c="addClass"):(b=A,c="removeClass"));var w="setClass"==c,E=w||"addClass"==c||"removeClass"==c||"animate"==c,p=a.attr("class")+" "+b;if(x(p)){var ca=t,m=[],J=[],g=t,s=[],u=[],p=(" "+p).replace(/\s+/g,".");n(T(p),function(a){!h(a,c)&&w&&(h(a,"addClass"),h(a,"removeClass"))});return{node:l,event:c,className:b,isClassBased:E,isSetClassOperation:w,applyStyles:function(){d&&a.css(f.extend(d.from||{},d.to||{}))},before:function(a){ca=a;k(J,m,function(){ca=t;a()})},after:function(a){g=
a;k(u,s,function(){g=t;a()})},cancel:function(){m&&(n(m,function(a){(a||t)(!0)}),ca(!0));s&&(n(s,function(a){(a||t)(!0)}),g(!0))}}}}}function G(a,c,b,d,h,k,l,e){function A(e){var l="$animate:"+e;J&&J[l]&&0<J[l].length&&H(function(){b.triggerHandler(l,{event:a,className:c})})}function w(){A("before")}function E(){A("after")}function p(){p.hasBeenRun||(p.hasBeenRun=!0,k())}function g(){if(!g.hasBeenRun){m&&m.applyStyles();g.hasBeenRun=!0;l&&l.tempClasses&&n(l.tempClasses,function(a){u.removeClass(b,
a)});var w=b.data("$$ngAnimateState");w&&(m&&m.isClassBased?B(b,c):(H(function(){var e=b.data("$$ngAnimateState")||{};fa==e.index&&B(b,c,a)}),b.data("$$ngAnimateState",w)));A("close");e()}}var m=U(b,a,c,l);if(!m)return p(),w(),E(),g(),t;a=m.event;c=m.className;var J=f.element._data(m.node),J=J&&J.events;d||(d=h?h.parent():b.parent());if(z(b,d))return p(),w(),E(),g(),t;d=b.data("$$ngAnimateState")||{};var L=d.active||{},s=d.totalActive||0,q=d.last;h=!1;if(0<s){s=[];if(m.isClassBased)"setClass"==q.event?
(s.push(q),B(b,c)):L[c]&&(v=L[c],v.event==a?h=!0:(s.push(v),B(b,c)));else if("leave"==a&&L["ng-leave"])h=!0;else{for(var v in L)s.push(L[v]);d={};B(b,!0)}0<s.length&&n(s,function(a){a.cancel()})}!m.isClassBased||m.isSetClassOperation||"animate"==a||h||(h="addClass"==a==b.hasClass(c));if(h)return p(),w(),E(),A("close"),e(),t;L=d.active||{};s=d.totalActive||0;if("leave"==a)b.one("$destroy",function(a){a=f.element(this);var e=a.data("$$ngAnimateState");e&&(e=e.active["ng-leave"])&&(e.cancel(),B(a,"ng-leave"))});
u.addClass(b,"ng-animate");l&&l.tempClasses&&n(l.tempClasses,function(a){u.addClass(b,a)});var fa=K++;s++;L[c]=m;b.data("$$ngAnimateState",{last:m,active:L,index:fa,totalActive:s});w();m.before(function(e){var l=b.data("$$ngAnimateState");e=e||!l||!l.active[c]||m.isClassBased&&l.active[c].event!=a;p();!0===e?g():(E(),m.after(g))});return m.cancel}function q(a){if(a=g(a))a=f.isFunction(a.getElementsByClassName)?a.getElementsByClassName("ng-animate"):a.querySelectorAll(".ng-animate"),n(a,function(a){a=
f.element(a);(a=a.data("$$ngAnimateState"))&&a.active&&n(a.active,function(a){a.cancel()})})}function B(a,c){if(ba(a,y))r.disabled||(r.running=!1,r.structural=!1);else if(c){var b=a.data("$$ngAnimateState")||{},d=!0===c;!d&&b.active&&b.active[c]&&(b.totalActive--,delete b.active[c]);if(d||!b.totalActive)u.removeClass(a,"ng-animate"),a.removeData("$$ngAnimateState")}}function z(a,c){if(r.disabled)return!0;if(ba(a,y))return r.running;var b,d,g;do{if(0===c.length)break;var k=ba(c,y),l=k?r:c.data("$$ngAnimateState")||
{};if(l.disabled)return!0;k&&(g=!0);!1!==b&&(k=c.data("$$ngAnimateChildren"),f.isDefined(k)&&(b=k));d=d||l.running||l.last&&!l.last.isClassBased}while(c=c.parent());return!g||!b&&d}u=Q;y.data("$$ngAnimateState",r);var $=P.$watch(function(){return Z.totalPendingRequests},function(a,c){0===a&&($(),P.$$postDigest(function(){P.$$postDigest(function(){r.running=!1})}))}),K=0,V=C.classNameFilter(),x=V?function(a){return V.test(a)}:function(){return!0};return{animate:function(a,c,b,d,h){d=d||"ng-inline-animate";
h=I(h)||{};h.from=b?c:null;h.to=b?b:c;return D(function(b){return G("animate",d,f.element(g(a)),null,null,t,h,b)})},enter:function(a,c,b,d){d=I(d);a=f.element(a);c=c&&f.element(c);b=b&&f.element(b);R(a,!0);O.enter(a,c,b);return D(function(h){return G("enter","ng-enter",f.element(g(a)),c,b,t,d,h)})},leave:function(a,c){c=I(c);a=f.element(a);q(a);R(a,!0);return D(function(b){return G("leave","ng-leave",f.element(g(a)),null,null,function(){O.leave(a)},c,b)})},move:function(a,c,b,d){d=I(d);a=f.element(a);
c=c&&f.element(c);b=b&&f.element(b);q(a);R(a,!0);O.move(a,c,b);return D(function(h){return G("move","ng-move",f.element(g(a)),c,b,t,d,h)})},addClass:function(a,c,b){return this.setClass(a,c,[],b)},removeClass:function(a,c,b){return this.setClass(a,[],c,b)},setClass:function(a,c,b,d){d=I(d);a=f.element(a);a=f.element(g(a));if(R(a))return O.$$setClassImmediately(a,c,b,d);var h,k=a.data("$$animateClasses"),l=!!k;k||(k={classes:{}});h=k.classes;c=aa(c)?c:c.split(" ");n(c,function(a){a&&a.length&&(h[a]=
!0)});b=aa(b)?b:b.split(" ");n(b,function(a){a&&a.length&&(h[a]=!1)});if(l)return d&&k.options&&(k.options=f.extend(k.options||{},d)),k.promise;a.data("$$animateClasses",k={classes:h,options:d});return k.promise=D(function(e){var l=a.parent(),b=g(a),c=b.parentNode;if(!c||c.$$NG_REMOVED||b.$$NG_REMOVED)e();else{b=a.data("$$animateClasses");a.removeData("$$animateClasses");var c=a.data("$$ngAnimateState")||{},d=S(a,b,c.active);return d?G("setClass",d,a,l,null,function(){d[0]&&O.$$addClassImmediately(a,
d[0]);d[1]&&O.$$removeClassImmediately(a,d[1])},b.options,e):e()}})},cancel:function(a){a.$$cancelFn()},enabled:function(a,c){switch(arguments.length){case 2:if(a)B(c);else{var b=c.data("$$ngAnimateState")||{};b.disabled=!0;c.data("$$ngAnimateState",b)}break;case 1:r.disabled=!a;break;default:a=!r.disabled}return!!a}}}]);C.register("",["$window","$sniffer","$timeout","$$animateReflow",function(r,C,M,Y){function y(){b||(b=Y(function(){c=[];b=null;x={}}))}function H(a,e){b&&b();c.push(e);b=Y(function(){n(c,
function(a){a()});c=[];b=null;x={}})}function P(a,e){var b=g(a);a=f.element(b);k.push(a);b=Date.now()+e;b<=h||(M.cancel(d),h=b,d=M(function(){X(k);k=[]},e,!1))}function X(a){n(a,function(a){(a=a.data("$$ngAnimateCSS3Data"))&&n(a.closeAnimationFns,function(a){a()})})}function Z(a,e){var b=e?x[e]:null;if(!b){var c=0,d=0,f=0,g=0;n(a,function(a){if(1==a.nodeType){a=r.getComputedStyle(a)||{};c=Math.max(Q(a[z+"Duration"]),c);d=Math.max(Q(a[z+"Delay"]),d);g=Math.max(Q(a[K+"Delay"]),g);var e=Q(a[K+"Duration"]);
0<e&&(e*=parseInt(a[K+"IterationCount"],10)||1);f=Math.max(e,f)}});b={total:0,transitionDelay:d,transitionDuration:c,animationDelay:g,animationDuration:f};e&&(x[e]=b)}return b}function Q(a){var e=0;a=ea(a)?a.split(/\s*,\s*/):[];n(a,function(a){e=Math.max(parseFloat(a)||0,e)});return e}function R(b,e,c,d){b=0<=["ng-enter","ng-leave","ng-move"].indexOf(c);var f,p=e.parent(),h=p.data("$$ngAnimateKey");h||(p.data("$$ngAnimateKey",++a),h=a);f=h+"-"+g(e).getAttribute("class");var p=f+" "+c,h=x[p]?++x[p].total:
0,m={};if(0<h){var n=c+"-stagger",m=f+" "+n;(f=!x[m])&&u.addClass(e,n);m=Z(e,m);f&&u.removeClass(e,n)}u.addClass(e,c);var n=e.data("$$ngAnimateCSS3Data")||{},k=Z(e,p);f=k.transitionDuration;k=k.animationDuration;if(b&&0===f&&0===k)return u.removeClass(e,c),!1;c=d||b&&0<f;b=0<k&&0<m.animationDelay&&0===m.animationDuration;e.data("$$ngAnimateCSS3Data",{stagger:m,cacheKey:p,running:n.running||0,itemIndex:h,blockTransition:c,closeAnimationFns:n.closeAnimationFns||[]});p=g(e);c&&(I(p,!0),d&&e.css(d));
b&&(p.style[K+"PlayState"]="paused");return!0}function D(a,e,b,c,d){function f(){e.off(D,h);u.removeClass(e,k);u.removeClass(e,t);z&&M.cancel(z);G(e,b);var a=g(e),c;for(c in s)a.style.removeProperty(s[c])}function h(a){a.stopPropagation();var b=a.originalEvent||a;a=b.$manualTimeStamp||b.timeStamp||Date.now();b=parseFloat(b.elapsedTime.toFixed(3));Math.max(a-H,0)>=C&&b>=x&&c()}var m=g(e);a=e.data("$$ngAnimateCSS3Data");if(-1!=m.getAttribute("class").indexOf(b)&&a){var k="",t="";n(b.split(" "),function(a,
b){var e=(0<b?" ":"")+a;k+=e+"-active";t+=e+"-pending"});var s=[],q=a.itemIndex,v=a.stagger,r=0;if(0<q){r=0;0<v.transitionDelay&&0===v.transitionDuration&&(r=v.transitionDelay*q);var y=0;0<v.animationDelay&&0===v.animationDuration&&(y=v.animationDelay*q,s.push(B+"animation-play-state"));r=Math.round(100*Math.max(r,y))/100}r||(u.addClass(e,k),a.blockTransition&&I(m,!1));var F=Z(e,a.cacheKey+" "+k),x=Math.max(F.transitionDuration,F.animationDuration);if(0===x)u.removeClass(e,k),G(e,b),c();else{!r&&
d&&0<Object.keys(d).length&&(F.transitionDuration||(e.css("transition",F.animationDuration+"s linear all"),s.push("transition")),e.css(d));var q=Math.max(F.transitionDelay,F.animationDelay),C=1E3*q;0<s.length&&(v=m.getAttribute("style")||"",";"!==v.charAt(v.length-1)&&(v+=";"),m.setAttribute("style",v+" "));var H=Date.now(),D=V+" "+$,q=1E3*(r+1.5*(q+x)),z;0<r&&(u.addClass(e,t),z=M(function(){z=null;0<F.transitionDuration&&I(m,!1);0<F.animationDuration&&(m.style[K+"PlayState"]="");u.addClass(e,k);
u.removeClass(e,t);d&&(0===F.transitionDuration&&e.css("transition",F.animationDuration+"s linear all"),e.css(d),s.push("transition"))},1E3*r,!1));e.on(D,h);a.closeAnimationFns.push(function(){f();c()});a.running++;P(e,q);return f}}else c()}function I(a,b){a.style[z+"Property"]=b?"none":""}function S(a,b,c,d){if(R(a,b,c,d))return function(a){a&&G(b,c)}}function T(a,b,c,d,f){if(b.data("$$ngAnimateCSS3Data"))return D(a,b,c,d,f);G(b,c);d()}function U(a,b,c,d,f){var g=S(a,b,c,f.from);if(g){var h=g;H(b,
function(){h=T(a,b,c,d,f.to)});return function(a){(h||t)(a)}}y();d()}function G(a,b){u.removeClass(a,b);var c=a.data("$$ngAnimateCSS3Data");c&&(c.running&&c.running--,c.running&&0!==c.running||a.removeData("$$ngAnimateCSS3Data"))}function q(a,b){var c="";a=aa(a)?a:a.split(/\s+/);n(a,function(a,d){a&&0<a.length&&(c+=(0<d?" ":"")+a+b)});return c}var B="",z,$,K,V;N.ontransitionend===W&&N.onwebkittransitionend!==W?(B="-webkit-",z="WebkitTransition",$="webkitTransitionEnd transitionend"):(z="transition",
$="transitionend");N.onanimationend===W&&N.onwebkitanimationend!==W?(B="-webkit-",K="WebkitAnimation",V="webkitAnimationEnd animationend"):(K="animation",V="animationend");var x={},a=0,c=[],b,d=null,h=0,k=[];return{animate:function(a,b,c,d,f,g){g=g||{};g.from=c;g.to=d;return U("animate",a,b,f,g)},enter:function(a,b,c){c=c||{};return U("enter",a,"ng-enter",b,c)},leave:function(a,b,c){c=c||{};return U("leave",a,"ng-leave",b,c)},move:function(a,b,c){c=c||{};return U("move",a,"ng-move",b,c)},beforeSetClass:function(a,
b,c,d,f){f=f||{};b=q(c,"-remove")+" "+q(b,"-add");if(f=S("setClass",a,b,f.from))return H(a,d),f;y();d()},beforeAddClass:function(a,b,c,d){d=d||{};if(b=S("addClass",a,q(b,"-add"),d.from))return H(a,c),b;y();c()},beforeRemoveClass:function(a,b,c,d){d=d||{};if(b=S("removeClass",a,q(b,"-remove"),d.from))return H(a,c),b;y();c()},setClass:function(a,b,c,d,f){f=f||{};c=q(c,"-remove");b=q(b,"-add");return T("setClass",a,c+" "+b,d,f.to)},addClass:function(a,b,c,d){d=d||{};return T("addClass",a,q(b,"-add"),
c,d.to)},removeClass:function(a,b,c,d){d=d||{};return T("removeClass",a,q(b,"-remove"),c,d.to)}}}])}])})(window,window.angular);
//# sourceMappingURL=angular-animate.min.js.map
;
/*
 AngularJS v1.3.15
 (c) 2010-2014 Google, Inc. http://angularjs.org
 License: MIT
*/
(function (n, h, p) {
    'use strict'; function E(a) { var e = []; r(e, h.noop).chars(a); return e.join("") } function g(a) { var e = {}; a = a.split(","); var d; for (d = 0; d < a.length; d++) e[a[d]] = !0; return e } function F(a, e) {
        function d(a, b, d, l) { b = h.lowercase(b); if (s[b]) for (; f.last() && t[f.last()];) c("", f.last()); u[b] && f.last() == b && c("", b); (l = v[b] || !!l) || f.push(b); var m = {}; d.replace(G, function (a, b, e, c, d) { m[b] = q(e || c || d || "") }); e.start && e.start(b, m, l) } function c(a, b) {
            var c = 0, d; if (b = h.lowercase(b)) for (c = f.length - 1; 0 <= c && f[c] != b; c--);
            if (0 <= c) { for (d = f.length - 1; d >= c; d--) e.end && e.end(f[d]); f.length = c }
        } "string" !== typeof a && (a = null === a || "undefined" === typeof a ? "" : "" + a); var b, k, f = [], m = a, l; for (f.last = function () { return f[f.length - 1] }; a;) {
            l = ""; k = !0; if (f.last() && w[f.last()]) a = a.replace(new RegExp("([\\W\\w]*)<\\s*\\/\\s*" + f.last() + "[^>]*>", "i"), function (a, b) { b = b.replace(H, "$1").replace(I, "$1"); e.chars && e.chars(q(b)); return "" }), c("", f.last()); else {
                if (0 === a.indexOf("\x3c!--")) b = a.indexOf("--", 4), 0 <= b && a.lastIndexOf("--\x3e", b) === b && (e.comment &&
                e.comment(a.substring(4, b)), a = a.substring(b + 3), k = !1); else if (x.test(a)) { if (b = a.match(x)) a = a.replace(b[0], ""), k = !1 } else if (J.test(a)) { if (b = a.match(y)) a = a.substring(b[0].length), b[0].replace(y, c), k = !1 } else K.test(a) && ((b = a.match(z)) ? (b[4] && (a = a.substring(b[0].length), b[0].replace(z, d)), k = !1) : (l += "<", a = a.substring(1))); k && (b = a.indexOf("<"), l += 0 > b ? a : a.substring(0, b), a = 0 > b ? "" : a.substring(b), e.chars && e.chars(q(l)))
            } if (a == m) throw L("badparse", a); m = a
        } c()
    } function q(a) {
        if (!a) return ""; A.innerHTML = a.replace(/</g,
        "&lt;"); return A.textContent
    } function B(a) { return a.replace(/&/g, "&amp;").replace(M, function (a) { var d = a.charCodeAt(0); a = a.charCodeAt(1); return "&#" + (1024 * (d - 55296) + (a - 56320) + 65536) + ";" }).replace(N, function (a) { return "&#" + a.charCodeAt(0) + ";" }).replace(/</g, "&lt;").replace(/>/g, "&gt;") } function r(a, e) {
        var d = !1, c = h.bind(a, a.push); return {
            start: function (a, k, f) {
                a = h.lowercase(a); !d && w[a] && (d = a); d || !0 !== C[a] || (c("<"), c(a), h.forEach(k, function (d, f) {
                    var k = h.lowercase(f), g = "img" === a && "src" === k || "background" ===
                    k; !0 !== O[k] || !0 === D[k] && !e(d, g) || (c(" "), c(f), c('="'), c(B(d)), c('"'))
                }), c(f ? "/>" : ">"))
            }, end: function (a) { a = h.lowercase(a); d || !0 !== C[a] || (c("</"), c(a), c(">")); a == d && (d = !1) }, chars: function (a) { d || c(B(a)) }
        }
    } var L = h.$$minErr("$sanitize"), z = /^<((?:[a-zA-Z])[\w:-]*)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*(>?)/, y = /^<\/\s*([\w:-]+)[^>]*>/, G = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, K = /^</, J = /^<\//, H = /\x3c!--(.*?)--\x3e/g, x = /<!DOCTYPE([^>]*?)>/i,
    I = /<!\[CDATA\[(.*?)]]\x3e/g, M = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g, N = /([^\#-~| |!])/g, v = g("area,br,col,hr,img,wbr"); n = g("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"); p = g("rp,rt"); var u = h.extend({}, p, n), s = h.extend({}, n, g("address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")), t = h.extend({}, p, g("a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
    n = g("animate,animateColor,animateMotion,animateTransform,circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,radialGradient,rect,set,stop,svg,switch,text,title,tspan,use"); var w = g("script,style"), C = h.extend({}, v, s, t, u, n), D = g("background,cite,href,longdesc,src,usemap,xlink:href"); n = g("abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,scope,scrolling,shape,size,span,start,summary,target,title,type,valign,value,vspace,width");
    p = g("accent-height,accumulate,additive,alphabetic,arabic-form,ascent,attributeName,attributeType,baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,height,horiz-adv-x,horiz-origin-x,ideographic,k,keyPoints,keySplines,keyTimes,lang,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mathematical,max,min,offset,opacity,orient,origin,overline-position,overline-thickness,panose-1,path,pathLength,points,preserveAspectRatio,r,refX,refY,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,rotate,rx,ry,slope,stemh,stemv,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,systemLanguage,target,text-anchor,to,transform,type,u1,u2,underline-position,underline-thickness,unicode,unicode-range,units-per-em,values,version,viewBox,visibility,width,widths,x,x-height,x1,x2,xlink:actuate,xlink:arcrole,xlink:role,xlink:show,xlink:title,xlink:type,xml:base,xml:lang,xml:space,xmlns,xmlns:xlink,y,y1,y2,zoomAndPan");
    var O = h.extend({}, D, p, n), A = document.createElement("pre"); h.module("ngSanitize", []).provider("$sanitize", function () { this.$get = ["$$sanitizeUri", function (a) { return function (e) { var d = []; F(e, r(d, function (c, b) { return !/^unsafe/.test(a(c, b)) })); return d.join("") } }] }); h.module("ngSanitize").filter("linky", ["$sanitize", function (a) {
        var e = /((ftp|https?):\/\/|(www\.)|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>"\u201d\u2019]/, d = /^mailto:/; return function (c, b) {
            function k(a) { a && g.push(E(a)) } function f(a, c) {
                g.push("<a ");
                h.isDefined(b) && g.push('target="', b, '" '); g.push('href="', a.replace(/"/g, "&quot;"), '">'); k(c); g.push("</a>")
            } if (!c) return c; for (var m, l = c, g = [], n, p; m = l.match(e) ;) n = m[0], m[2] || m[4] || (n = (m[3] ? "http://" : "mailto:") + n), p = m.index, k(l.substr(0, p)), f(n, m[0].replace(d, "")), l = l.substring(p + m[0].length); k(l); return a(g.join(""))
        }
    }])
})(window, window.angular);
//# sourceMappingURL=angular-sanitize.min.js.map;
/**
 * angular-drag-and-drop-lists v2.1.0
 *
 * Copyright (c) 2014 Marcel Juenemann marcel@juenemann.cc
 * Copyright (c) 2014-2017 Google Inc.
 * https://github.com/marceljuenemann/angular-drag-and-drop-lists
 *
 * License: MIT
 */
(function(dndLists) {

  // In standard-compliant browsers we use a custom mime type and also encode the dnd-type in it.
  // However, IE and Edge only support a limited number of mime types. The workarounds are described
  // in https://github.com/marceljuenemann/angular-drag-and-drop-lists/wiki/Data-Transfer-Design
  var MIME_TYPE = 'application/x-dnd';
  var EDGE_MIME_TYPE = 'application/json';
  var MSIE_MIME_TYPE = 'Text';

  // All valid HTML5 drop effects, in the order in which we prefer to use them.
  var ALL_EFFECTS = ['move', 'copy', 'link'];

  /**
   * Use the dnd-draggable attribute to make your element draggable
   *
   * Attributes:
   * - dnd-draggable      Required attribute. The value has to be an object that represents the data
   *                      of the element. In case of a drag and drop operation the object will be
   *                      serialized and unserialized on the receiving end.
   * - dnd-effect-allowed Use this attribute to limit the operations that can be performed. Valid
   *                      options are "move", "copy" and "link", as well as "all", "copyMove",
   *                      "copyLink" and "linkMove". The semantics of these operations are up to you
   *                      and have to be implemented using the callbacks described below. If you
   *                      allow multiple options, the user can choose between them by using the
   *                      modifier keys (OS specific). The cursor will be changed accordingly,
   *                      expect for IE and Edge, where this is not supported.
   * - dnd-type           Use this attribute if you have different kinds of items in your
   *                      application and you want to limit which items can be dropped into which
   *                      lists. Combine with dnd-allowed-types on the dnd-list(s). This attribute
   *                      must be a lower case string. Upper case characters can be used, but will
   *                      be converted to lower case automatically.
   * - dnd-disable-if     You can use this attribute to dynamically disable the draggability of the
   *                      element. This is useful if you have certain list items that you don't want
   *                      to be draggable, or if you want to disable drag & drop completely without
   *                      having two different code branches (e.g. only allow for admins).
   *
   * Callbacks:
   * - dnd-dragstart      Callback that is invoked when the element was dragged. The original
   *                      dragstart event will be provided in the local event variable.
   * - dnd-moved          Callback that is invoked when the element was moved. Usually you will
   *                      remove your element from the original list in this callback, since the
   *                      directive is not doing that for you automatically. The original dragend
   *                      event will be provided in the local event variable.
   * - dnd-copied         Same as dnd-moved, just that it is called when the element was copied
   *                      instead of moved, so you probably want to implement a different logic.
   * - dnd-linked         Same as dnd-moved, just that it is called when the element was linked
   *                      instead of moved, so you probably want to implement a different logic.
   * - dnd-canceled       Callback that is invoked if the element was dragged, but the operation was
   *                      canceled and the element was not dropped. The original dragend event will
   *                      be provided in the local event variable.
   * - dnd-dragend        Callback that is invoked when the drag operation ended. Available local
   *                      variables are event and dropEffect.
   * - dnd-selected       Callback that is invoked when the element was clicked but not dragged.
   *                      The original click event will be provided in the local event variable.
   * - dnd-callback       Custom callback that is passed to dropzone callbacks and can be used to
   *                      communicate between source and target scopes. The dropzone can pass user
   *                      defined variables to this callback.
   *
   * CSS classes:
   * - dndDragging        This class will be added to the element while the element is being
   *                      dragged. It will affect both the element you see while dragging and the
   *                      source element that stays at it's position. Do not try to hide the source
   *                      element with this class, because that will abort the drag operation.
   * - dndDraggingSource  This class will be added to the element after the drag operation was
   *                      started, meaning it only affects the original element that is still at
   *                      it's source position, and not the "element" that the user is dragging with
   *                      his mouse pointer.
   */
  dndLists.directive('dndDraggable', ['$parse', '$timeout', function($parse, $timeout) {
    return function(scope, element, attr) {
      // Set the HTML5 draggable attribute on the element.
      element.attr("draggable", "true");

      // If the dnd-disable-if attribute is set, we have to watch that.
      if (attr.dndDisableIf) {
        scope.$watch(attr.dndDisableIf, function(disabled) {
          element.attr("draggable", !disabled);
        });
      }

      /**
       * When the drag operation is started we have to prepare the dataTransfer object,
       * which is the primary way we communicate with the target element
       */
      element.on('dragstart', function(event) {
        event = event.originalEvent || event;

        // Check whether the element is draggable, since dragstart might be triggered on a child.
        if (element.attr('draggable') == 'false') return true;

        // Initialize global state.
        dndState.isDragging = true;
        dndState.itemType = attr.dndType && scope.$eval(attr.dndType).toLowerCase();

        // Set the allowed drop effects. See below for special IE handling.
        dndState.dropEffect = "none";
        dndState.effectAllowed = attr.dndEffectAllowed || ALL_EFFECTS[0];
        event.dataTransfer.effectAllowed = dndState.effectAllowed;

        // Internet Explorer and Microsoft Edge don't support custom mime types, see design doc:
        // https://github.com/marceljuenemann/angular-drag-and-drop-lists/wiki/Data-Transfer-Design
        var item = scope.$eval(attr.dndDraggable);
        var mimeType = MIME_TYPE + (dndState.itemType ? ('-' + dndState.itemType) : '');
        try {
          event.dataTransfer.setData(mimeType, angular.toJson(item));
        } catch (e) {
          // Setting a custom MIME type did not work, we are probably in IE or Edge.
          var data = angular.toJson({item: item, type: dndState.itemType});
          try {
            event.dataTransfer.setData(EDGE_MIME_TYPE, data);
          } catch (e) {
            // We are in Internet Explorer and can only use the Text MIME type. Also note that IE
            // does not allow changing the cursor in the dragover event, therefore we have to choose
            // the one we want to display now by setting effectAllowed.
            var effectsAllowed = filterEffects(ALL_EFFECTS, dndState.effectAllowed);
            event.dataTransfer.effectAllowed = effectsAllowed[0];
            event.dataTransfer.setData(MSIE_MIME_TYPE, data);
          }
        }

        // Add CSS classes. See documentation above.
        element.addClass("dndDragging");
        $timeout(function() { element.addClass("dndDraggingSource"); }, 0);

        // Try setting a proper drag image if triggered on a dnd-handle (won't work in IE).
        if (event._dndHandle && event.dataTransfer.setDragImage) {
          event.dataTransfer.setDragImage(element[0], 0, 0);
        }

        // Invoke dragstart callback and prepare extra callback for dropzone.
        $parse(attr.dndDragstart)(scope, {event: event});
        if (attr.dndCallback) {
          var callback = $parse(attr.dndCallback);
          dndState.callback = function(params) { return callback(scope, params || {}); };
        }

        event.stopPropagation();
      });

      /**
       * The dragend event is triggered when the element was dropped or when the drag
       * operation was aborted (e.g. hit escape button). Depending on the executed action
       * we will invoke the callbacks specified with the dnd-moved or dnd-copied attribute.
       */
      element.on('dragend', function(event) {
        event = event.originalEvent || event;

        // Invoke callbacks. Usually we would use event.dataTransfer.dropEffect to determine
        // the used effect, but Chrome has not implemented that field correctly. On Windows
        // it always sets it to 'none', while Chrome on Linux sometimes sets it to something
        // else when it's supposed to send 'none' (drag operation aborted).
        scope.$apply(function() {
          var dropEffect = dndState.dropEffect;
          var cb = {copy: 'dndCopied', link: 'dndLinked', move: 'dndMoved', none: 'dndCanceled'};
          $parse(attr[cb[dropEffect]])(scope, {event: event});
          $parse(attr.dndDragend)(scope, {event: event, dropEffect: dropEffect});
        });

        // Clean up
        dndState.isDragging = false;
        dndState.callback = undefined;
        element.removeClass("dndDragging");
        element.removeClass("dndDraggingSource");
        event.stopPropagation();

        // In IE9 it is possible that the timeout from dragstart triggers after the dragend handler.
        $timeout(function() { element.removeClass("dndDraggingSource"); }, 0);
      });

      /**
       * When the element is clicked we invoke the callback function
       * specified with the dnd-selected attribute.
       */
      element.on('click', function(event) {
        if (!attr.dndSelected) return;

        event = event.originalEvent || event;
        scope.$apply(function() {
          $parse(attr.dndSelected)(scope, {event: event});
        });

        // Prevent triggering dndSelected in parent elements.
        event.stopPropagation();
      });

      /**
       * Workaround to make element draggable in IE9
       */
      element.on('selectstart', function() {
        if (this.dragDrop) this.dragDrop();
      });
    };
  }]);

  /**
   * Use the dnd-list attribute to make your list element a dropzone. Usually you will add a single
   * li element as child with the ng-repeat directive. If you don't do that, we will not be able to
   * position the dropped element correctly. If you want your list to be sortable, also add the
   * dnd-draggable directive to your li element(s).
   *
   * Attributes:
   * - dnd-list             Required attribute. The value has to be the array in which the data of
   *                        the dropped element should be inserted. The value can be blank if used
   *                        with a custom dnd-drop handler that always returns true.
   * - dnd-allowed-types    Optional array of allowed item types. When used, only items that had a
   *                        matching dnd-type attribute will be dropable. Upper case characters will
   *                        automatically be converted to lower case.
   * - dnd-effect-allowed   Optional string expression that limits the drop effects that can be
   *                        performed in the list. See dnd-effect-allowed on dnd-draggable for more
   *                        details on allowed options. The default value is all.
   * - dnd-disable-if       Optional boolean expresssion. When it evaluates to true, no dropping
   *                        into the list is possible. Note that this also disables rearranging
   *                        items inside the list.
   * - dnd-horizontal-list  Optional boolean expresssion. When it evaluates to true, the positioning
   *                        algorithm will use the left and right halfs of the list items instead of
   *                        the upper and lower halfs.
   * - dnd-external-sources Optional boolean expression. When it evaluates to true, the list accepts
   *                        drops from sources outside of the current browser tab. This allows to
   *                        drag and drop accross different browser tabs. The only major browser
   *                        that does not support this is currently Microsoft Edge.
   *
   * Callbacks:
   * - dnd-dragover         Optional expression that is invoked when an element is dragged over the
   *                        list. If the expression is set, but does not return true, the element is
   *                        not allowed to be dropped. The following variables will be available:
   *                        - event: The original dragover event sent by the browser.
   *                        - index: The position in the list at which the element would be dropped.
   *                        - type: The dnd-type set on the dnd-draggable, or undefined if non was
   *                          set. Will be null for drops from external sources in IE and Edge,
   *                          since we don't know the type in those cases.
   *                        - dropEffect: One of move, copy or link, see dnd-effect-allowed.
   *                        - external: Whether the element was dragged from an external source.
   *                        - callback: If dnd-callback was set on the source element, this is a
   *                          function reference to the callback. The callback can be invoked with
   *                          custom variables like this: callback({var1: value1, var2: value2}).
   *                          The callback will be executed on the scope of the source element. If
   *                          dnd-external-sources was set and external is true, this callback will
   *                          not be available.
   * - dnd-drop             Optional expression that is invoked when an element is dropped on the
   *                        list. The same variables as for dnd-dragover will be available, with the
   *                        exception that type is always known and therefore never null. There
   *                        will also be an item variable, which is the transferred object. The
   *                        return value determines the further handling of the drop:
   *                        - falsy: The drop will be canceled and the element won't be inserted.
   *                        - true: Signalises that the drop is allowed, but the dnd-drop
   *                          callback already took care of inserting the element.
   *                        - otherwise: All other return values will be treated as the object to
   *                          insert into the array. In most cases you want to simply return the
   *                          item parameter, but there are no restrictions on what you can return.
   * - dnd-inserted         Optional expression that is invoked after a drop if the element was
   *                        actually inserted into the list. The same local variables as for
   *                        dnd-drop will be available. Note that for reorderings inside the same
   *                        list the old element will still be in the list due to the fact that
   *                        dnd-moved was not called yet.
   *
   * CSS classes:
   * - dndPlaceholder       When an element is dragged over the list, a new placeholder child
   *                        element will be added. This element is of type li and has the class
   *                        dndPlaceholder set. Alternatively, you can define your own placeholder
   *                        by creating a child element with dndPlaceholder class.
   * - dndDragover          Will be added to the list while an element is dragged over the list.
   */
  dndLists.directive('dndList', ['$parse', function($parse) {
    return function(scope, element, attr) {
      // While an element is dragged over the list, this placeholder element is inserted
      // at the location where the element would be inserted after dropping.
      var placeholder = getPlaceholderElement();
      placeholder.remove();

      var placeholderNode = placeholder[0];
      var listNode = element[0];
      var listSettings = {};

      /**
       * The dragenter event is fired when a dragged element or text selection enters a valid drop
       * target. According to the spec, we either need to have a dropzone attribute or listen on
       * dragenter events and call preventDefault(). It should be noted though that no browser seems
       * to enforce this behaviour.
       */
      element.on('dragenter', function (event) {
        event = event.originalEvent || event;

        // Calculate list properties, so that we don't have to repeat this on every dragover event.
        var types = attr.dndAllowedTypes && scope.$eval(attr.dndAllowedTypes);
        listSettings = {
          allowedTypes: angular.isArray(types) && types.join('|').toLowerCase().split('|'),
          disabled: attr.dndDisableIf && scope.$eval(attr.dndDisableIf),
          externalSources: attr.dndExternalSources && scope.$eval(attr.dndExternalSources),
          horizontal: attr.dndHorizontalList && scope.$eval(attr.dndHorizontalList)
        };

        var mimeType = getMimeType(event.dataTransfer.types);
        if (!mimeType || !isDropAllowed(getItemType(mimeType))) return true;
        event.preventDefault();
      });

      /**
       * The dragover event is triggered "every few hundred milliseconds" while an element
       * is being dragged over our list, or over an child element.
       */
      element.on('dragover', function(event) {
        event = event.originalEvent || event;

        // Check whether the drop is allowed and determine mime type.
        var mimeType = getMimeType(event.dataTransfer.types);
        var itemType = getItemType(mimeType);
        if (!mimeType || !isDropAllowed(itemType)) return true;

        // Make sure the placeholder is shown, which is especially important if the list is empty.
        if (placeholderNode.parentNode != listNode) {
          element.append(placeholder);
        }

        if (event.target != listNode) {
          // Try to find the node direct directly below the list node.
          var listItemNode = event.target;
          while (listItemNode.parentNode != listNode && listItemNode.parentNode) {
            listItemNode = listItemNode.parentNode;
          }

          if (listItemNode.parentNode == listNode && listItemNode != placeholderNode) {
            // If the mouse pointer is in the upper half of the list item element,
            // we position the placeholder before the list item, otherwise after it.
            var rect = listItemNode.getBoundingClientRect();
            if (listSettings.horizontal) {
              var isFirstHalf = event.clientX < rect.left + rect.width / 2;
            } else {
              var isFirstHalf = event.clientY < rect.top + rect.height / 2;
            }
            listNode.insertBefore(placeholderNode,
                isFirstHalf ? listItemNode : listItemNode.nextSibling);
          }
        }

        // In IE we set a fake effectAllowed in dragstart to get the correct cursor, we therefore
        // ignore the effectAllowed passed in dataTransfer. We must also not access dataTransfer for
        // drops from external sources, as that throws an exception.
        var ignoreDataTransfer = mimeType == MSIE_MIME_TYPE;
        var dropEffect = getDropEffect(event, ignoreDataTransfer);
        if (dropEffect == 'none') return stopDragover();

        // At this point we invoke the callback, which still can disallow the drop.
        // We can't do this earlier because we want to pass the index of the placeholder.
        if (attr.dndDragover && !invokeCallback(attr.dndDragover, event, dropEffect, itemType)) {
          return stopDragover();
        }

        // Set dropEffect to modify the cursor shown by the browser, unless we're in IE, where this
        // is not supported. This must be done after preventDefault in Firefox.
        event.preventDefault();
        if (!ignoreDataTransfer) {
          event.dataTransfer.dropEffect = dropEffect;
        }

        element.addClass("dndDragover");
        event.stopPropagation();
        return false;
      });

      /**
       * When the element is dropped, we use the position of the placeholder element as the
       * position where we insert the transferred data. This assumes that the list has exactly
       * one child element per array element.
       */
      element.on('drop', function(event) {
        event = event.originalEvent || event;

        // Check whether the drop is allowed and determine mime type.
        var mimeType = getMimeType(event.dataTransfer.types);
        var itemType = getItemType(mimeType);
        if (!mimeType || !isDropAllowed(itemType)) return true;

        // The default behavior in Firefox is to interpret the dropped element as URL and
        // forward to it. We want to prevent that even if our drop is aborted.
        event.preventDefault();

        // Unserialize the data that was serialized in dragstart.
        try {
          var data = JSON.parse(event.dataTransfer.getData(mimeType));
        } catch(e) {
          return stopDragover();
        }

        // Drops with invalid types from external sources might not have been filtered out yet.
        if (mimeType == MSIE_MIME_TYPE || mimeType == EDGE_MIME_TYPE) {
          itemType = data.type || undefined;
          data = data.item;
          if (!isDropAllowed(itemType)) return stopDragover();
        }

        // Special handling for internal IE drops, see dragover handler.
        var ignoreDataTransfer = mimeType == MSIE_MIME_TYPE;
        var dropEffect = getDropEffect(event, ignoreDataTransfer);
        if (dropEffect == 'none') return stopDragover();

        // Invoke the callback, which can transform the transferredObject and even abort the drop.
        var index = getPlaceholderIndex();
        if (attr.dndDrop) {
          data = invokeCallback(attr.dndDrop, event, dropEffect, itemType, index, data);
          if (!data) return stopDragover();
        }

        // The drop is definitely going to happen now, store the dropEffect.
        dndState.dropEffect = dropEffect;
        if (!ignoreDataTransfer) {
          event.dataTransfer.dropEffect = dropEffect;
        }

        // Insert the object into the array, unless dnd-drop took care of that (returned true).
        if (data !== true) {
          scope.$apply(function() {
            scope.$eval(attr.dndList).splice(index, 0, data);
          });
        }
        invokeCallback(attr.dndInserted, event, dropEffect, itemType, index, data);

        // Clean up
        stopDragover();
        event.stopPropagation();
        return false;
      });

      /**
       * We have to remove the placeholder when the element is no longer dragged over our list. The
       * problem is that the dragleave event is not only fired when the element leaves our list,
       * but also when it leaves a child element. Therefore, we determine whether the mouse cursor
       * is still pointing to an element inside the list or not.
       */
      element.on('dragleave', function(event) {
        event = event.originalEvent || event;

        var newTarget = document.elementFromPoint(event.clientX, event.clientY);
        if (listNode.contains(newTarget) && !event._dndPhShown) {
          // Signalize to potential parent lists that a placeholder is already shown.
          event._dndPhShown = true;
        } else {
          stopDragover();
        }
      });

      /**
       * Given the types array from the DataTransfer object, returns the first valid mime type.
       * A type is valid if it starts with MIME_TYPE, or it equals MSIE_MIME_TYPE or EDGE_MIME_TYPE.
       */
      function getMimeType(types) {
        if (!types) return MSIE_MIME_TYPE; // IE 9 workaround.
        for (var i = 0; i < types.length; i++) {
          if (types[i] == MSIE_MIME_TYPE || types[i] == EDGE_MIME_TYPE ||
              types[i].substr(0, MIME_TYPE.length) == MIME_TYPE) {
            return types[i];
          }
        }
        return null;
      }

      /**
       * Determines the type of the item from the dndState, or from the mime type for items from
       * external sources. Returns undefined if no item type was set and null if the item type could
       * not be determined.
       */
      function getItemType(mimeType) {
        if (dndState.isDragging) return dndState.itemType || undefined;
        if (mimeType == MSIE_MIME_TYPE || mimeType == EDGE_MIME_TYPE) return null;
        return (mimeType && mimeType.substr(MIME_TYPE.length + 1)) || undefined;
      }

      /**
       * Checks various conditions that must be fulfilled for a drop to be allowed, including the
       * dnd-allowed-types attribute. If the item Type is unknown (null), the drop will be allowed.
       */
      function isDropAllowed(itemType) {
        if (listSettings.disabled) return false;
        if (!listSettings.externalSources && !dndState.isDragging) return false;
        if (!listSettings.allowedTypes || itemType === null) return true;
        return itemType && listSettings.allowedTypes.indexOf(itemType) != -1;
      }

      /**
       * Determines which drop effect to use for the given event. In Internet Explorer we have to
       * ignore the effectAllowed field on dataTransfer, since we set a fake value in dragstart.
       * In those cases we rely on dndState to filter effects. Read the design doc for more details:
       * https://github.com/marceljuenemann/angular-drag-and-drop-lists/wiki/Data-Transfer-Design
       */
      function getDropEffect(event, ignoreDataTransfer) {
        var effects = ALL_EFFECTS;
        if (!ignoreDataTransfer) {
          effects = filterEffects(effects, event.dataTransfer.effectAllowed);
        }
        if (dndState.isDragging) {
          effects = filterEffects(effects, dndState.effectAllowed);
        }
        if (attr.dndEffectAllowed) {
          effects = filterEffects(effects, attr.dndEffectAllowed);
        }
        // MacOS automatically filters dataTransfer.effectAllowed depending on the modifier keys,
        // therefore the following modifier keys will only affect other operating systems.
        if (!effects.length) {
          return 'none';
        } else if (event.ctrlKey && effects.indexOf('copy') != -1) {
          return 'copy';
        } else if (event.altKey && effects.indexOf('link') != -1) {
          return 'link';
        } else {
          return effects[0];
        }
      }

      /**
       * Small helper function that cleans up if we aborted a drop.
       */
      function stopDragover() {
        placeholder.remove();
        element.removeClass("dndDragover");
        return true;
      }

      /**
       * Invokes a callback with some interesting parameters and returns the callbacks return value.
       */
      function invokeCallback(expression, event, dropEffect, itemType, index, item) {
        return $parse(expression)(scope, {
          callback: dndState.callback,
          dropEffect: dropEffect,
          event: event,
          external: !dndState.isDragging,
          index: index !== undefined ? index : getPlaceholderIndex(),
          item: item || undefined,
          type: itemType
        });
      }

      /**
       * We use the position of the placeholder node to determine at which position of the array the
       * object needs to be inserted
       */
      function getPlaceholderIndex() {
        return Array.prototype.indexOf.call(listNode.children, placeholderNode);
      }

      /**
       * Tries to find a child element that has the dndPlaceholder class set. If none was found, a
       * new li element is created.
       */
      function getPlaceholderElement() {
        var placeholder;
        angular.forEach(element.children(), function(childNode) {
          var child = angular.element(childNode);
          if (child.hasClass('dndPlaceholder')) {
            placeholder = child;
          }
        });
        return placeholder || angular.element("<li class='dndPlaceholder'></li>");
      }
    };
  }]);

  /**
   * Use the dnd-nodrag attribute inside of dnd-draggable elements to prevent them from starting
   * drag operations. This is especially useful if you want to use input elements inside of
   * dnd-draggable elements or create specific handle elements. Note: This directive does not work
   * in Internet Explorer 9.
   */
  dndLists.directive('dndNodrag', function() {
    return function(scope, element, attr) {
      // Set as draggable so that we can cancel the events explicitly
      element.attr("draggable", "true");

      /**
       * Since the element is draggable, the browser's default operation is to drag it on dragstart.
       * We will prevent that and also stop the event from bubbling up.
       */
      element.on('dragstart', function(event) {
        event = event.originalEvent || event;

        if (!event._dndHandle) {
          // If a child element already reacted to dragstart and set a dataTransfer object, we will
          // allow that. For example, this is the case for user selections inside of input elements.
          if (!(event.dataTransfer.types && event.dataTransfer.types.length)) {
            event.preventDefault();
          }
          event.stopPropagation();
        }
      });

      /**
       * Stop propagation of dragend events, otherwise dnd-moved might be triggered and the element
       * would be removed.
       */
      element.on('dragend', function(event) {
        event = event.originalEvent || event;
        if (!event._dndHandle) {
          event.stopPropagation();
        }
      });
    };
  });

  /**
   * Use the dnd-handle directive within a dnd-nodrag element in order to allow dragging with that
   * element after all. Therefore, by combining dnd-nodrag and dnd-handle you can allow
   * dnd-draggable elements to only be dragged via specific "handle" elements. Note that Internet
   * Explorer will show the handle element as drag image instead of the dnd-draggable element. You
   * can work around this by styling the handle element differently when it is being dragged. Use
   * the CSS selector .dndDragging:not(.dndDraggingSource) [dnd-handle] for that.
   */
  dndLists.directive('dndHandle', function() {
    return function(scope, element, attr) {
      element.attr("draggable", "true");

      element.on('dragstart dragend', function(event) {
        event = event.originalEvent || event;
        event._dndHandle = true;
      });
    };
  });

  /**
   * Filters an array of drop effects using a HTML5 effectAllowed string.
   */
  function filterEffects(effects, effectAllowed) {
    if (effectAllowed == 'all') return effects;
    return effects.filter(function(effect) {
      return effectAllowed.toLowerCase().indexOf(effect) != -1;
    });
  }

  /**
   * For some features we need to maintain global state. This is done here, with these fields:
   * - callback: A callback function set at dragstart that is passed to internal dropzone handlers.
   * - dropEffect: Set in dragstart to "none" and to the actual value in the drop handler. We don't
   *   rely on the dropEffect passed by the browser, since there are various bugs in Chrome and
   *   Safari, and Internet Explorer defaults to copy if effectAllowed is copyMove.
   * - effectAllowed: Set in dragstart based on dnd-effect-allowed. This is needed for IE because
   *   setting effectAllowed on dataTransfer might result in an undesired cursor.
   * - isDragging: True between dragstart and dragend. Falsy for drops from external sources.
   * - itemType: The item type of the dragged element set via dnd-type. This is needed because IE
   *   and Edge don't support custom mime types that we can use to transfer this information.
   */
  var dndState = {};

})(angular.module('dndLists', []));
;
/*
 * angular-ui-bootstrap
 * http://angular-ui.github.io/bootstrap/

 * Version: 0.14.3 - 2015-10-23
 * License: MIT
 */
angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.stackedMap","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/day.html","template/datepicker/month.html","template/datepicker/popup.html","template/datepicker/year.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-popup.html","template/tooltip/tooltip-popup.html","template/tooltip/tooltip-template-popup.html","template/popover/popover-html.html","template/popover/popover-template.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]),angular.module("ui.bootstrap.collapse",[]).directive("uibCollapse",["$animate","$injector",function(a,b){var c=b.has("$animateCss")?b.get("$animateCss"):null;return{link:function(b,d,e){function f(){d.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),c?c(d,{addClass:"in",easing:"ease",to:{height:d[0].scrollHeight+"px"}}).start()["finally"](g):a.addClass(d,"in",{to:{height:d[0].scrollHeight+"px"}}).then(g)}function g(){d.removeClass("collapsing").addClass("collapse").css({height:"auto"})}function h(){return d.hasClass("collapse")||d.hasClass("in")?(d.css({height:d[0].scrollHeight+"px"}).removeClass("collapse").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void(c?c(d,{removeClass:"in",to:{height:"0"}}).start()["finally"](i):a.removeClass(d,"in",{to:{height:"0"}}).then(i))):i()}function i(){d.css({height:"0"}),d.removeClass("collapsing").addClass("collapse")}b.$watch(e.uibCollapse,function(a){a?h():f()})}}}]),angular.module("ui.bootstrap.collapse").value("$collapseSuppressWarning",!1).directive("collapse",["$animate","$injector","$log","$collapseSuppressWarning",function(a,b,c,d){var e=b.has("$animateCss")?b.get("$animateCss"):null;return{link:function(b,f,g){function h(){f.removeClass("collapse").addClass("collapsing").attr("aria-expanded",!0).attr("aria-hidden",!1),e?e(f,{easing:"ease",to:{height:f[0].scrollHeight+"px"}}).start().done(i):a.animate(f,{},{height:f[0].scrollHeight+"px"}).then(i)}function i(){f.removeClass("collapsing").addClass("collapse in").css({height:"auto"})}function j(){return f.hasClass("collapse")||f.hasClass("in")?(f.css({height:f[0].scrollHeight+"px"}).removeClass("collapse in").addClass("collapsing").attr("aria-expanded",!1).attr("aria-hidden",!0),void(e?e(f,{to:{height:"0"}}).start().done(k):a.animate(f,{},{height:"0"}).then(k))):k()}function k(){f.css({height:"0"}),f.removeClass("collapsing").addClass("collapse")}d||c.warn("collapse is now deprecated. Use uib-collapse instead."),b.$watch(g.collapse,function(a){a?j():h()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("uibAccordionConfig",{closeOthers:!0}).controller("UibAccordionController",["$scope","$attrs","uibAccordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(c){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(b,1)}}]).directive("uibAccordion",function(){return{controller:"UibAccordionController",controllerAs:"accordion",transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/accordion/accordion.html"}}}).directive("uibAccordionGroup",function(){return{require:"^uibAccordion",transclude:!0,replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/accordion/accordion-group.html"},scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(a,b,c,d){d.addGroup(a),a.openClass=c.openClass||"panel-open",a.panelClass=c.panelClass,a.$watch("isOpen",function(c){b.toggleClass(a.openClass,!!c),c&&d.closeOthers(a)}),a.toggleOpen=function(b){a.isDisabled||b&&32!==b.which||(a.isOpen=!a.isOpen)}}}}).directive("uibAccordionHeading",function(){return{transclude:!0,template:"",replace:!0,require:"^uibAccordionGroup",link:function(a,b,c,d,e){d.setHeading(e(a,angular.noop))}}}).directive("uibAccordionTransclude",function(){return{require:["?^uibAccordionGroup","?^accordionGroup"],link:function(a,b,c,d){d=d[0]?d[0]:d[1],a.$watch(function(){return d[c.uibAccordionTransclude]},function(a){a&&(b.find("span").html(""),b.find("span").append(a))})}}}),angular.module("ui.bootstrap.accordion").value("$accordionSuppressWarning",!1).controller("AccordionController",["$scope","$attrs","$controller","$log","$accordionSuppressWarning",function(a,b,c,d,e){e||d.warn("AccordionController is now deprecated. Use UibAccordionController instead."),angular.extend(this,c("UibAccordionController",{$scope:a,$attrs:b}))}]).directive("accordion",["$log","$accordionSuppressWarning",function(a,b){return{restrict:"EA",controller:"AccordionController",controllerAs:"accordion",transclude:!0,replace:!1,templateUrl:function(a,b){return b.templateUrl||"template/accordion/accordion.html"},link:function(){b||a.warn("accordion is now deprecated. Use uib-accordion instead.")}}}]).directive("accordionGroup",["$log","$accordionSuppressWarning",function(a,b){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/accordion/accordion-group.html"},scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(c,d,e,f){b||a.warn("accordion-group is now deprecated. Use uib-accordion-group instead."),f.addGroup(c),c.openClass=e.openClass||"panel-open",c.panelClass=e.panelClass,c.$watch("isOpen",function(a){d.toggleClass(c.openClass,!!a),a&&f.closeOthers(c)}),c.toggleOpen=function(a){c.isDisabled||a&&32!==a.which||(c.isOpen=!c.isOpen)}}}}]).directive("accordionHeading",["$log","$accordionSuppressWarning",function(a,b){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(c,d,e,f,g){b||a.warn("accordion-heading is now deprecated. Use uib-accordion-heading instead."),f.setHeading(g(c,angular.noop))}}}]).directive("accordionTransclude",["$log","$accordionSuppressWarning",function(a,b){return{require:"^accordionGroup",link:function(c,d,e,f){b||a.warn("accordion-transclude is now deprecated. Use uib-accordion-transclude instead."),c.$watch(function(){return f[e.accordionTransclude]},function(a){a&&(d.find("span").html(""),d.find("span").append(a))})}}}]),angular.module("ui.bootstrap.alert",[]).controller("UibAlertController",["$scope","$attrs","$interpolate","$timeout",function(a,b,c,d){a.closeable=!!b.close;var e=angular.isDefined(b.dismissOnTimeout)?c(b.dismissOnTimeout)(a.$parent):null;e&&d(function(){a.close()},parseInt(e,10))}]).directive("uibAlert",function(){return{controller:"UibAlertController",controllerAs:"alert",templateUrl:function(a,b){return b.templateUrl||"template/alert/alert.html"},transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}),angular.module("ui.bootstrap.alert").value("$alertSuppressWarning",!1).controller("AlertController",["$scope","$attrs","$controller","$log","$alertSuppressWarning",function(a,b,c,d,e){e||d.warn("AlertController is now deprecated. Use UibAlertController instead."),angular.extend(this,c("UibAlertController",{$scope:a,$attrs:b}))}]).directive("alert",["$log","$alertSuppressWarning",function(a,b){return{controller:"AlertController",controllerAs:"alert",templateUrl:function(a,b){return b.templateUrl||"template/alert/alert.html"},transclude:!0,replace:!0,scope:{type:"@",close:"&"},link:function(){b||a.warn("alert is now deprecated. Use uib-alert instead.")}}}]),angular.module("ui.bootstrap.buttons",[]).constant("uibButtonConfig",{activeClass:"active",toggleEvent:"click"}).controller("UibButtonsController",["uibButtonConfig",function(a){this.activeClass=a.activeClass||"active",this.toggleEvent=a.toggleEvent||"click"}]).directive("uibBtnRadio",function(){return{require:["uibBtnRadio","ngModel"],controller:"UibButtonsController",controllerAs:"buttons",link:function(a,b,c,d){var e=d[0],f=d[1];b.find("input").css({display:"none"}),f.$render=function(){b.toggleClass(e.activeClass,angular.equals(f.$modelValue,a.$eval(c.uibBtnRadio)))},b.on(e.toggleEvent,function(){if(!c.disabled){var d=b.hasClass(e.activeClass);(!d||angular.isDefined(c.uncheckable))&&a.$apply(function(){f.$setViewValue(d?null:a.$eval(c.uibBtnRadio)),f.$render()})}})}}}).directive("uibBtnCheckbox",function(){return{require:["uibBtnCheckbox","ngModel"],controller:"UibButtonsController",controllerAs:"button",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){return angular.isDefined(b)?a.$eval(b):c}var h=d[0],i=d[1];b.find("input").css({display:"none"}),i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.on(h.toggleEvent,function(){c.disabled||a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("ui.bootstrap.buttons").value("$buttonsSuppressWarning",!1).controller("ButtonsController",["$controller","$log","$buttonsSuppressWarning",function(a,b,c){c||b.warn("ButtonsController is now deprecated. Use UibButtonsController instead."),angular.extend(this,a("UibButtonsController"))}]).directive("btnRadio",["$log","$buttonsSuppressWarning",function(a,b){return{require:["btnRadio","ngModel"],controller:"ButtonsController",controllerAs:"buttons",link:function(c,d,e,f){b||a.warn("btn-radio is now deprecated. Use uib-btn-radio instead.");var g=f[0],h=f[1];d.find("input").css({display:"none"}),h.$render=function(){d.toggleClass(g.activeClass,angular.equals(h.$modelValue,c.$eval(e.btnRadio)))},d.bind(g.toggleEvent,function(){if(!e.disabled){var a=d.hasClass(g.activeClass);(!a||angular.isDefined(e.uncheckable))&&c.$apply(function(){h.$setViewValue(a?null:c.$eval(e.btnRadio)),h.$render()})}})}}}]).directive("btnCheckbox",["$document","$log","$buttonsSuppressWarning",function(a,b,c){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",controllerAs:"button",link:function(d,e,f,g){function h(){return j(f.btnCheckboxTrue,!0)}function i(){return j(f.btnCheckboxFalse,!1)}function j(a,b){var c=d.$eval(a);return angular.isDefined(c)?c:b}c||b.warn("btn-checkbox is now deprecated. Use uib-btn-checkbox instead.");var k=g[0],l=g[1];e.find("input").css({display:"none"}),l.$render=function(){e.toggleClass(k.activeClass,angular.equals(l.$modelValue,h()))},e.bind(k.toggleEvent,function(){f.disabled||d.$apply(function(){l.$setViewValue(e.hasClass(k.activeClass)?i():h()),l.$render()})}),e.on("keypress",function(b){f.disabled||32!==b.which||a[0].activeElement!==e[0]||d.$apply(function(){l.$setViewValue(e.hasClass(k.activeClass)?i():h()),l.$render()})})}}}]),angular.module("ui.bootstrap.carousel",[]).controller("UibCarouselController",["$scope","$element","$interval","$animate",function(a,b,c,d){function e(b,c,e){s||(angular.extend(b,{direction:e,active:!0}),angular.extend(m.currentSlide||{},{direction:e,active:!1}),d.enabled()&&!a.noTransition&&!a.$currentTransition&&b.$element&&m.slides.length>1&&(b.$element.data(q,b.direction),m.currentSlide&&m.currentSlide.$element&&m.currentSlide.$element.data(q,b.direction),a.$currentTransition=!0,o?d.on("addClass",b.$element,function(b,c){"close"===c&&(a.$currentTransition=null,d.off("addClass",b))}):b.$element.one("$animate:close",function(){a.$currentTransition=null})),m.currentSlide=b,r=c,g())}function f(a){if(angular.isUndefined(n[a].index))return n[a];var b;n.length;for(b=0;b<n.length;++b)if(n[b].index==a)return n[b]}function g(){h();var b=+a.interval;!isNaN(b)&&b>0&&(k=c(i,b))}function h(){k&&(c.cancel(k),k=null)}function i(){var b=+a.interval;l&&!isNaN(b)&&b>0&&n.length?a.next():a.pause()}function j(b){b.length||(a.$currentTransition=null)}var k,l,m=this,n=m.slides=a.slides=[],o=angular.version.minor>=4,p="uib-noTransition",q="uib-slideDirection",r=-1;m.currentSlide=null;var s=!1;m.select=a.select=function(b,c){var d=a.indexOfSlide(b);void 0===c&&(c=d>m.getCurrentIndex()?"next":"prev"),b&&b!==m.currentSlide&&!a.$currentTransition&&e(b,d,c)},a.$on("$destroy",function(){s=!0}),m.getCurrentIndex=function(){return m.currentSlide&&angular.isDefined(m.currentSlide.index)?+m.currentSlide.index:r},a.indexOfSlide=function(a){return angular.isDefined(a.index)?+a.index:n.indexOf(a)},a.next=function(){var b=(m.getCurrentIndex()+1)%n.length;return 0===b&&a.noWrap()?void a.pause():m.select(f(b),"next")},a.prev=function(){var b=m.getCurrentIndex()-1<0?n.length-1:m.getCurrentIndex()-1;return a.noWrap()&&b===n.length-1?void a.pause():m.select(f(b),"prev")},a.isActive=function(a){return m.currentSlide===a},a.$watch("interval",g),a.$watchCollection("slides",j),a.$on("$destroy",h),a.play=function(){l||(l=!0,g())},a.pause=function(){a.noPause||(l=!1,h())},m.addSlide=function(b,c){b.$element=c,n.push(b),1===n.length||b.active?(m.select(n[n.length-1]),1===n.length&&a.play()):b.active=!1},m.removeSlide=function(a){angular.isDefined(a.index)&&n.sort(function(a,b){return+a.index>+b.index});var b=n.indexOf(a);n.splice(b,1),n.length>0&&a.active?b>=n.length?m.select(n[b-1]):m.select(n[b]):r>b&&r--,0===n.length&&(m.currentSlide=null)},a.$watch("noTransition",function(a){b.data(p,a)})}]).directive("uibCarousel",[function(){return{transclude:!0,replace:!0,controller:"UibCarouselController",controllerAs:"carousel",require:"carousel",templateUrl:function(a,b){return b.templateUrl||"template/carousel/carousel.html"},scope:{interval:"=",noTransition:"=",noPause:"=",noWrap:"&"}}}]).directive("uibSlide",function(){return{require:"^uibCarousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/carousel/slide.html"},scope:{active:"=?",actual:"=?",index:"=?"},link:function(a,b,c,d){d.addSlide(a,b),a.$on("$destroy",function(){d.removeSlide(a)}),a.$watch("active",function(b){b&&d.select(a)})}}}).animation(".item",["$injector","$animate",function(a,b){function c(a,b,c){a.removeClass(b),c&&c()}var d="uib-noTransition",e="uib-slideDirection",f=null;return a.has("$animateCss")&&(f=a.get("$animateCss")),{beforeAddClass:function(a,g,h){if("active"==g&&a.parent()&&a.parent().parent()&&!a.parent().parent().data(d)){var i=!1,j=a.data(e),k="next"==j?"left":"right",l=c.bind(this,a,k+" "+j,h);return a.addClass(j),f?f(a,{addClass:k}).start().done(l):b.addClass(a,k).then(function(){i||l(),h()}),function(){i=!0}}h()},beforeRemoveClass:function(a,g,h){if("active"===g&&a.parent()&&a.parent().parent()&&!a.parent().parent().data(d)){var i=!1,j=a.data(e),k="next"==j?"left":"right",l=c.bind(this,a,k,h);return f?f(a,{addClass:k}).start().done(l):b.addClass(a,k).then(function(){i||l(),h()}),function(){i=!0}}h()}}}]),angular.module("ui.bootstrap.carousel").value("$carouselSuppressWarning",!1).controller("CarouselController",["$scope","$element","$controller","$log","$carouselSuppressWarning",function(a,b,c,d,e){e||d.warn("CarouselController is now deprecated. Use UibCarouselController instead."),angular.extend(this,c("UibCarouselController",{$scope:a,$element:b}))}]).directive("carousel",["$log","$carouselSuppressWarning",function(a,b){return{transclude:!0,replace:!0,controller:"CarouselController",controllerAs:"carousel",require:"carousel",templateUrl:function(a,b){return b.templateUrl||"template/carousel/carousel.html"},scope:{interval:"=",noTransition:"=",noPause:"=",noWrap:"&"},link:function(){b||a.warn("carousel is now deprecated. Use uib-carousel instead.")}}}]).directive("slide",["$log","$carouselSuppressWarning",function(a,b){return{require:"^carousel",transclude:!0,replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/carousel/slide.html"},scope:{active:"=?",actual:"=?",index:"=?"},link:function(c,d,e,f){b||a.warn("slide is now deprecated. Use uib-slide instead."),f.addSlide(c,d),c.$on("$destroy",function(){f.removeSlide(c)}),c.$watch("active",function(a){a&&f.select(c)})}}}]),angular.module("ui.bootstrap.dateparser",[]).service("uibDateParser",["$log","$locale","orderByFilter",function(a,b,c){function d(a){var b=[],d=a.split("");return angular.forEach(g,function(c,e){var f=a.indexOf(e);if(f>-1){a=a.split(""),d[f]="("+c.regex+")",a[f]="$";for(var g=f+1,h=f+e.length;h>g;g++)d[g]="",a[g]="$";a=a.join(""),b.push({index:f,apply:c.apply})}}),{regex:new RegExp("^"+d.join("")+"$"),map:c(b,"index")}}function e(a,b,c){return 1>c?!1:1===b&&c>28?29===c&&(a%4===0&&a%100!==0||a%400===0):3===b||5===b||8===b||10===b?31>c:!0}var f,g,h=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;this.init=function(){f=b.id,this.parsers={},g={yyyy:{regex:"\\d{4}",apply:function(a){this.year=+a}},yy:{regex:"\\d{2}",apply:function(a){this.year=+a+2e3}},y:{regex:"\\d{1,4}",apply:function(a){this.year=+a}},MMMM:{regex:b.DATETIME_FORMATS.MONTH.join("|"),apply:function(a){this.month=b.DATETIME_FORMATS.MONTH.indexOf(a)}},MMM:{regex:b.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(a){this.month=b.DATETIME_FORMATS.SHORTMONTH.indexOf(a)}},MM:{regex:"0[1-9]|1[0-2]",apply:function(a){this.month=a-1}},M:{regex:"[1-9]|1[0-2]",apply:function(a){this.month=a-1}},dd:{regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},d:{regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},EEEE:{regex:b.DATETIME_FORMATS.DAY.join("|")},EEE:{regex:b.DATETIME_FORMATS.SHORTDAY.join("|")},HH:{regex:"(?:0|1)[0-9]|2[0-3]",apply:function(a){this.hours=+a}},hh:{regex:"0[0-9]|1[0-2]",apply:function(a){this.hours=+a}},H:{regex:"1?[0-9]|2[0-3]",apply:function(a){this.hours=+a}},h:{regex:"[0-9]|1[0-2]",apply:function(a){this.hours=+a}},mm:{regex:"[0-5][0-9]",apply:function(a){this.minutes=+a}},m:{regex:"[0-9]|[1-5][0-9]",apply:function(a){this.minutes=+a}},sss:{regex:"[0-9][0-9][0-9]",apply:function(a){this.milliseconds=+a}},ss:{regex:"[0-5][0-9]",apply:function(a){this.seconds=+a}},s:{regex:"[0-9]|[1-5][0-9]",apply:function(a){this.seconds=+a}},a:{regex:b.DATETIME_FORMATS.AMPMS.join("|"),apply:function(a){12===this.hours&&(this.hours=0),"PM"===a&&(this.hours+=12)}}}},this.init(),this.parse=function(c,g,i){if(!angular.isString(c)||!g)return c;g=b.DATETIME_FORMATS[g]||g,g=g.replace(h,"\\$&"),b.id!==f&&this.init(),this.parsers[g]||(this.parsers[g]=d(g));var j=this.parsers[g],k=j.regex,l=j.map,m=c.match(k);if(m&&m.length){var n,o;angular.isDate(i)&&!isNaN(i.getTime())?n={year:i.getFullYear(),month:i.getMonth(),date:i.getDate(),hours:i.getHours(),minutes:i.getMinutes(),seconds:i.getSeconds(),milliseconds:i.getMilliseconds()}:(i&&a.warn("dateparser:","baseDate is not a valid date"),n={year:1900,month:0,date:1,hours:0,minutes:0,seconds:0,milliseconds:0});for(var p=1,q=m.length;q>p;p++){var r=l[p-1];r.apply&&r.apply.call(n,m[p])}return e(n.year,n.month,n.date)&&(angular.isDate(i)&&!isNaN(i.getTime())?(o=new Date(i),o.setFullYear(n.year,n.month,n.date,n.hours,n.minutes,n.seconds,n.milliseconds||0)):o=new Date(n.year,n.month,n.date,n.hours,n.minutes,n.seconds,n.milliseconds||0)),o}}}]),angular.module("ui.bootstrap.dateparser").value("$dateParserSuppressWarning",!1).service("dateParser",["$log","$dateParserSuppressWarning","uibDateParser",function(a,b,c){b||a.warn("dateParser is now deprecated. Use uibDateParser instead."),angular.extend(this,c)}]),angular.module("ui.bootstrap.position",[]).factory("$uibPosition",["$document","$window",function(a,b){function c(a,c){return a.currentStyle?a.currentStyle[c]:b.getComputedStyle?b.getComputedStyle(a)[c]:a.style[c]}function d(a){return"static"===(c(a,"position")||"static")}var e=function(b){for(var c=a[0],e=b.offsetParent||c;e&&e!==c&&d(e);)e=e.offsetParent;return e||c};return{position:function(b){var c=this.offset(b),d={top:0,left:0},f=e(b[0]);f!=a[0]&&(d=this.offset(angular.element(f)),d.top+=f.clientTop-f.scrollTop,d.left+=f.clientLeft-f.scrollLeft);var g=b[0].getBoundingClientRect();return{width:g.width||b.prop("offsetWidth"),height:g.height||b.prop("offsetHeight"),top:c.top-d.top,left:c.left-d.left}},offset:function(c){var d=c[0].getBoundingClientRect();return{width:d.width||c.prop("offsetWidth"),height:d.height||c.prop("offsetHeight"),top:d.top+(b.pageYOffset||a[0].documentElement.scrollTop),left:d.left+(b.pageXOffset||a[0].documentElement.scrollLeft)}},positionElements:function(a,b,c,d){var e,f,g,h,i=c.split("-"),j=i[0],k=i[1]||"center";e=d?this.offset(a):this.position(a),f=b.prop("offsetWidth"),g=b.prop("offsetHeight");var l={center:function(){return e.left+e.width/2-f/2},left:function(){return e.left},right:function(){return e.left+e.width}},m={center:function(){return e.top+e.height/2-g/2},top:function(){return e.top},bottom:function(){return e.top+e.height}};switch(j){case"right":h={top:m[k](),left:l[j]()};break;case"left":h={top:m[k](),left:e.left-f};break;case"bottom":h={top:m[j](),left:l[k]()};break;default:h={top:e.top-g,left:l[k]()}}return h}}}]),angular.module("ui.bootstrap.position").value("$positionSuppressWarning",!1).service("$position",["$log","$positionSuppressWarning","$uibPosition",function(a,b,c){b||a.warn("$position is now deprecated. Use $uibPosition instead."),angular.extend(this,c)}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.position"]).value("$datepickerSuppressError",!1).constant("uibDatepickerConfig",{formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",datepickerMode:"day",minMode:"day",maxMode:"year",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null,shortcutPropagation:!1}).controller("UibDatepickerController",["$scope","$attrs","$parse","$interpolate","$log","dateFilter","uibDatepickerConfig","$datepickerSuppressError",function(a,b,c,d,e,f,g,h){var i=this,j={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","showWeeks","startingDay","yearRange","shortcutPropagation"],function(c,e){i[c]=angular.isDefined(b[c])?6>e?d(b[c])(a.$parent):a.$parent.$eval(b[c]):g[c]}),angular.forEach(["minDate","maxDate"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(a){i[d]=a?new Date(a):null,i.refreshView()}):i[d]=g[d]?new Date(g[d]):null}),angular.forEach(["minMode","maxMode"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(c){i[d]=angular.isDefined(c)?c:b[d],a[d]=i[d],("minMode"==d&&i.modes.indexOf(a.datepickerMode)<i.modes.indexOf(i[d])||"maxMode"==d&&i.modes.indexOf(a.datepickerMode)>i.modes.indexOf(i[d]))&&(a.datepickerMode=i[d])}):(i[d]=g[d]||null,a[d]=i[d])}),a.datepickerMode=a.datepickerMode||g.datepickerMode,a.uniqueId="datepicker-"+a.$id+"-"+Math.floor(1e4*Math.random()),angular.isDefined(b.initDate)?(this.activeDate=a.$parent.$eval(b.initDate)||new Date,a.$parent.$watch(b.initDate,function(a){a&&(j.$isEmpty(j.$modelValue)||j.$invalid)&&(i.activeDate=a,i.refreshView())})):this.activeDate=new Date,a.isActive=function(b){return 0===i.compare(b.date,i.activeDate)?(a.activeDateId=b.uid,!0):!1},this.init=function(a){j=a,j.$render=function(){i.render()}},this.render=function(){if(j.$viewValue){var a=new Date(j.$viewValue),b=!isNaN(a);b?this.activeDate=a:h||e.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var a=j.$viewValue?new Date(j.$viewValue):null;j.$setValidity("dateDisabled",!a||this.element&&!this.isDisabled(a))}},this.createDateObject=function(a,b){var c=j.$viewValue?new Date(j.$viewValue):null;return{date:a,label:f(a,b),selected:c&&0===this.compare(a,c),disabled:this.isDisabled(a),current:0===this.compare(a,new Date),customClass:this.customClass(a)}},this.isDisabled=function(c){return this.minDate&&this.compare(c,this.minDate)<0||this.maxDate&&this.compare(c,this.maxDate)>0||b.dateDisabled&&a.dateDisabled({date:c,mode:a.datepickerMode})},this.customClass=function(b){return a.customClass({date:b,mode:a.datepickerMode})},this.split=function(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c},a.select=function(b){if(a.datepickerMode===i.minMode){var c=j.$viewValue?new Date(j.$viewValue):new Date(0,0,0,0,0,0,0);c.setFullYear(b.getFullYear(),b.getMonth(),b.getDate()),j.$setViewValue(c),j.$render()}else i.activeDate=b,a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)-1]},a.move=function(a){var b=i.activeDate.getFullYear()+a*(i.step.years||0),c=i.activeDate.getMonth()+a*(i.step.months||0);i.activeDate.setFullYear(b,c,1),i.refreshView()},a.toggleMode=function(b){b=b||1,a.datepickerMode===i.maxMode&&1===b||a.datepickerMode===i.minMode&&-1===b||(a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)+b])},a.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var k=function(){i.element[0].focus()};a.$on("uib:datepicker.focus",k),a.keydown=function(b){var c=a.keys[b.which];if(c&&!b.shiftKey&&!b.altKey)if(b.preventDefault(),i.shortcutPropagation||b.stopPropagation(),"enter"===c||"space"===c){if(i.isDisabled(i.activeDate))return;a.select(i.activeDate)}else!b.ctrlKey||"up"!==c&&"down"!==c?(i.handleKeyDown(c,b),i.refreshView()):a.toggleMode("up"===c?1:-1)}}]).controller("UibDaypickerController",["$scope","$element","dateFilter",function(a,b,c){function d(a,b){return 1!==b||a%4!==0||a%100===0&&a%400!==0?f[b]:29}function e(a){var b=new Date(a);b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1}var f=[31,28,31,30,31,30,31,31,30,31,30,31];this.step={months:1},this.element=b,this.init=function(b){angular.extend(b,this),a.showWeeks=b.showWeeks,b.refreshView()},this.getDates=function(a,b){for(var c,d=new Array(b),e=new Date(a),f=0;b>f;)c=new Date(e),d[f++]=c,e.setDate(e.getDate()+1);return d},this._refreshView=function(){var b=this.activeDate.getFullYear(),d=this.activeDate.getMonth(),f=new Date(this.activeDate);f.setFullYear(b,d,1);var g=this.startingDay-f.getDay(),h=g>0?7-g:-g,i=new Date(f);h>0&&i.setDate(-h+1);for(var j=this.getDates(i,42),k=0;42>k;k++)j[k]=angular.extend(this.createDateObject(j[k],this.formatDay),{secondary:j[k].getMonth()!==d,uid:a.uniqueId+"-"+k});a.labels=new Array(7);for(var l=0;7>l;l++)a.labels[l]={abbr:c(j[l].date,this.formatDayHeader),full:c(j[l].date,"EEEE")};if(a.title=c(this.activeDate,this.formatDayTitle),a.rows=this.split(j,7),a.showWeeks){a.weekNumbers=[];for(var m=(11-this.startingDay)%7,n=a.rows.length,o=0;n>o;o++)a.weekNumbers.push(e(a.rows[o][m].date))}},this.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},this.handleKeyDown=function(a,b){var c=this.activeDate.getDate();if("left"===a)c-=1;else if("up"===a)c-=7;else if("right"===a)c+=1;else if("down"===a)c+=7;else if("pageup"===a||"pagedown"===a){var e=this.activeDate.getMonth()+("pageup"===a?-1:1);this.activeDate.setMonth(e,1),c=Math.min(d(this.activeDate.getFullYear(),this.activeDate.getMonth()),c)}else"home"===a?c=1:"end"===a&&(c=d(this.activeDate.getFullYear(),this.activeDate.getMonth()));this.activeDate.setDate(c)}}]).controller("UibMonthpickerController",["$scope","$element","dateFilter",function(a,b,c){this.step={years:1},this.element=b,this.init=function(a){angular.extend(a,this),a.refreshView()},this._refreshView=function(){for(var b,d=new Array(12),e=this.activeDate.getFullYear(),f=0;12>f;f++)b=new Date(this.activeDate),b.setFullYear(e,f,1),d[f]=angular.extend(this.createDateObject(b,this.formatMonth),{uid:a.uniqueId+"-"+f});a.title=c(this.activeDate,this.formatMonthTitle),a.rows=this.split(d,3)},this.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth())-new Date(b.getFullYear(),b.getMonth())},this.handleKeyDown=function(a,b){var c=this.activeDate.getMonth();if("left"===a)c-=1;else if("up"===a)c-=3;else if("right"===a)c+=1;else if("down"===a)c+=3;else if("pageup"===a||"pagedown"===a){var d=this.activeDate.getFullYear()+("pageup"===a?-1:1);this.activeDate.setFullYear(d)}else"home"===a?c=0:"end"===a&&(c=11);this.activeDate.setMonth(c)}}]).controller("UibYearpickerController",["$scope","$element","dateFilter",function(a,b,c){function d(a){return parseInt((a-1)/e,10)*e+1}var e;this.element=b,this.yearpickerInit=function(){e=this.yearRange,this.step={years:e}},this._refreshView=function(){for(var b,c=new Array(e),f=0,g=d(this.activeDate.getFullYear());e>f;f++)b=new Date(this.activeDate),b.setFullYear(g+f,0,1),c[f]=angular.extend(this.createDateObject(b,this.formatYear),{uid:a.uniqueId+"-"+f});a.title=[c[0].label,c[e-1].label].join(" - "),a.rows=this.split(c,5)},this.compare=function(a,b){return a.getFullYear()-b.getFullYear()},this.handleKeyDown=function(a,b){var c=this.activeDate.getFullYear();"left"===a?c-=1:"up"===a?c-=5:"right"===a?c+=1:"down"===a?c+=5:"pageup"===a||"pagedown"===a?c+=("pageup"===a?-1:1)*this.step.years:"home"===a?c=d(this.activeDate.getFullYear()):"end"===a&&(c=d(this.activeDate.getFullYear())+e-1),this.activeDate.setFullYear(c)}}]).directive("uibDatepicker",function(){return{replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/datepicker.html"},scope:{datepickerMode:"=?",dateDisabled:"&",customClass:"&",shortcutPropagation:"&?"},require:["uibDatepicker","^ngModel"],controller:"UibDatepickerController",controllerAs:"datepicker",link:function(a,b,c,d){var e=d[0],f=d[1];e.init(f)}}}).directive("uibDaypicker",function(){return{replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/day.html"},require:["^?uibDatepicker","uibDaypicker","^?datepicker"],controller:"UibDaypickerController",link:function(a,b,c,d){var e=d[0]||d[2],f=d[1];f.init(e)}}}).directive("uibMonthpicker",function(){return{replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/month.html"},require:["^?uibDatepicker","uibMonthpicker","^?datepicker"],controller:"UibMonthpickerController",link:function(a,b,c,d){var e=d[0]||d[2],f=d[1];f.init(e)}}}).directive("uibYearpicker",function(){return{replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/year.html"},require:["^?uibDatepicker","uibYearpicker","^?datepicker"],controller:"UibYearpickerController",link:function(a,b,c,d){var e=d[0]||d[2];angular.extend(e,d[1]),e.yearpickerInit(),e.refreshView()}}}).constant("uibDatepickerPopupConfig",{datepickerPopup:"yyyy-MM-dd",datepickerPopupTemplateUrl:"template/datepicker/popup.html",datepickerTemplateUrl:"template/datepicker/datepicker.html",html5Types:{date:"yyyy-MM-dd","datetime-local":"yyyy-MM-ddTHH:mm:ss.sss",month:"yyyy-MM"},currentText:"Today",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0,onOpenFocus:!0}).controller("UibDatepickerPopupController",["$scope","$element","$attrs","$compile","$parse","$document","$rootScope","$uibPosition","dateFilter","uibDateParser","uibDatepickerPopupConfig","$timeout",function(a,b,c,d,e,f,g,h,i,j,k,l){
function m(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function n(b){if(angular.isNumber(b)&&(b=new Date(b)),b){if(angular.isDate(b)&&!isNaN(b))return b;if(angular.isString(b)){var c=j.parse(b,r,a.date);return isNaN(c)?void 0:c}return void 0}return null}function o(a,b){var d=a||b;if(!c.ngRequired&&!d)return!0;if(angular.isNumber(d)&&(d=new Date(d)),d){if(angular.isDate(d)&&!isNaN(d))return!0;if(angular.isString(d)){var e=j.parse(d,r);return!isNaN(e)}return!1}return!0}function p(c){var d=A[0],e=b[0].contains(c.target),f=void 0!==d.contains&&d.contains(c.target);!a.isOpen||e||f||a.$apply(function(){a.isOpen=!1})}function q(c){27===c.which&&a.isOpen?(c.preventDefault(),c.stopPropagation(),a.$apply(function(){a.isOpen=!1}),b[0].focus()):40!==c.which||a.isOpen||(c.preventDefault(),c.stopPropagation(),a.$apply(function(){a.isOpen=!0}))}var r,s,t,u,v,w,x,y,z,A,B={},C=!1;a.watchData={},this.init=function(h){if(z=h,s=angular.isDefined(c.closeOnDateSelection)?a.$parent.$eval(c.closeOnDateSelection):k.closeOnDateSelection,t=angular.isDefined(c.datepickerAppendToBody)?a.$parent.$eval(c.datepickerAppendToBody):k.appendToBody,u=angular.isDefined(c.onOpenFocus)?a.$parent.$eval(c.onOpenFocus):k.onOpenFocus,v=angular.isDefined(c.datepickerPopupTemplateUrl)?c.datepickerPopupTemplateUrl:k.datepickerPopupTemplateUrl,w=angular.isDefined(c.datepickerTemplateUrl)?c.datepickerTemplateUrl:k.datepickerTemplateUrl,a.showButtonBar=angular.isDefined(c.showButtonBar)?a.$parent.$eval(c.showButtonBar):k.showButtonBar,k.html5Types[c.type]?(r=k.html5Types[c.type],C=!0):(r=c.datepickerPopup||c.uibDatepickerPopup||k.datepickerPopup,c.$observe("uibDatepickerPopup",function(a,b){var c=a||k.datepickerPopup;if(c!==r&&(r=c,z.$modelValue=null,!r))throw new Error("uibDatepickerPopup must have a date format specified.")})),!r)throw new Error("uibDatepickerPopup must have a date format specified.");if(C&&c.datepickerPopup)throw new Error("HTML5 date input types do not support custom formats.");if(x=angular.element("<div uib-datepicker-popup-wrap><div uib-datepicker></div></div>"),x.attr({"ng-model":"date","ng-change":"dateSelection(date)","template-url":v}),y=angular.element(x.children()[0]),y.attr("template-url",w),C&&"month"===c.type&&(y.attr("datepicker-mode",'"month"'),y.attr("min-mode","month")),c.datepickerOptions){var l=a.$parent.$eval(c.datepickerOptions);l&&l.initDate&&(a.initDate=l.initDate,y.attr("init-date","initDate"),delete l.initDate),angular.forEach(l,function(a,b){y.attr(m(b),a)})}angular.forEach(["minMode","maxMode","minDate","maxDate","datepickerMode","initDate","shortcutPropagation"],function(b){if(c[b]){var d=e(c[b]);if(a.$parent.$watch(d,function(c){a.watchData[b]=c,("minDate"===b||"maxDate"===b)&&(B[b]=new Date(c))}),y.attr(m(b),"watchData."+b),"datepickerMode"===b){var f=d.assign;a.$watch("watchData."+b,function(b,c){angular.isFunction(f)&&b!==c&&f(a.$parent,b)})}}}),c.dateDisabled&&y.attr("date-disabled","dateDisabled({ date: date, mode: mode })"),c.showWeeks&&y.attr("show-weeks",c.showWeeks),c.customClass&&y.attr("custom-class","customClass({ date: date, mode: mode })"),C?z.$formatters.push(function(b){return a.date=b,b}):(z.$$parserName="date",z.$validators.date=o,z.$parsers.unshift(n),z.$formatters.push(function(b){return a.date=b,z.$isEmpty(b)?b:i(b,r)})),z.$viewChangeListeners.push(function(){a.date=j.parse(z.$viewValue,r,a.date)}),b.bind("keydown",q),A=d(x)(a),x.remove(),t?f.find("body").append(A):b.after(A),a.$on("$destroy",function(){a.isOpen===!0&&(g.$$phase||a.$apply(function(){a.isOpen=!1})),A.remove(),b.unbind("keydown",q),f.unbind("click",p)})},a.getText=function(b){return a[b+"Text"]||k[b+"Text"]},a.isDisabled=function(b){return"today"===b&&(b=new Date),a.watchData.minDate&&a.compare(b,B.minDate)<0||a.watchData.maxDate&&a.compare(b,B.maxDate)>0},a.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},a.dateSelection=function(c){angular.isDefined(c)&&(a.date=c);var d=a.date?i(a.date,r):null;b.val(d),z.$setViewValue(d),s&&(a.isOpen=!1,b[0].focus())},a.keydown=function(c){27===c.which&&(a.isOpen=!1,b[0].focus())},a.select=function(b){if("today"===b){var c=new Date;angular.isDate(a.date)?(b=new Date(a.date),b.setFullYear(c.getFullYear(),c.getMonth(),c.getDate())):b=new Date(c.setHours(0,0,0,0))}a.dateSelection(b)},a.close=function(){a.isOpen=!1,b[0].focus()},a.$watch("isOpen",function(c){c?(a.position=t?h.offset(b):h.position(b),a.position.top=a.position.top+b.prop("offsetHeight"),l(function(){u&&a.$broadcast("uib:datepicker.focus"),f.bind("click",p)},0,!1)):f.unbind("click",p)})}]).directive("uibDatepickerPopup",function(){return{require:["ngModel","uibDatepickerPopup"],controller:"UibDatepickerPopupController",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&",customClass:"&"},link:function(a,b,c,d){var e=d[0],f=d[1];f.init(e)}}}).directive("uibDatepickerPopupWrap",function(){return{replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/popup.html"}}}),angular.module("ui.bootstrap.datepicker").value("$datepickerSuppressWarning",!1).controller("DatepickerController",["$scope","$attrs","$parse","$interpolate","$log","dateFilter","uibDatepickerConfig","$datepickerSuppressError","$datepickerSuppressWarning",function(a,b,c,d,e,f,g,h,i){i||e.warn("DatepickerController is now deprecated. Use UibDatepickerController instead.");var j=this,k={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","showWeeks","startingDay","yearRange","shortcutPropagation"],function(c,e){j[c]=angular.isDefined(b[c])?6>e?d(b[c])(a.$parent):a.$parent.$eval(b[c]):g[c]}),angular.forEach(["minDate","maxDate"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(a){j[d]=a?new Date(a):null,j.refreshView()}):j[d]=g[d]?new Date(g[d]):null}),angular.forEach(["minMode","maxMode"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(c){j[d]=angular.isDefined(c)?c:b[d],a[d]=j[d],("minMode"==d&&j.modes.indexOf(a.datepickerMode)<j.modes.indexOf(j[d])||"maxMode"==d&&j.modes.indexOf(a.datepickerMode)>j.modes.indexOf(j[d]))&&(a.datepickerMode=j[d])}):(j[d]=g[d]||null,a[d]=j[d])}),a.datepickerMode=a.datepickerMode||g.datepickerMode,a.uniqueId="datepicker-"+a.$id+"-"+Math.floor(1e4*Math.random()),angular.isDefined(b.initDate)?(this.activeDate=a.$parent.$eval(b.initDate)||new Date,a.$parent.$watch(b.initDate,function(a){a&&(k.$isEmpty(k.$modelValue)||k.$invalid)&&(j.activeDate=a,j.refreshView())})):this.activeDate=new Date,a.isActive=function(b){return 0===j.compare(b.date,j.activeDate)?(a.activeDateId=b.uid,!0):!1},this.init=function(a){k=a,k.$render=function(){j.render()}},this.render=function(){if(k.$viewValue){var a=new Date(k.$viewValue),b=!isNaN(a);b?this.activeDate=a:h||e.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var a=k.$viewValue?new Date(k.$viewValue):null;k.$setValidity("dateDisabled",!a||this.element&&!this.isDisabled(a))}},this.createDateObject=function(a,b){var c=k.$viewValue?new Date(k.$viewValue):null;return{date:a,label:f(a,b),selected:c&&0===this.compare(a,c),disabled:this.isDisabled(a),current:0===this.compare(a,new Date),customClass:this.customClass(a)}},this.isDisabled=function(c){return this.minDate&&this.compare(c,this.minDate)<0||this.maxDate&&this.compare(c,this.maxDate)>0||b.dateDisabled&&a.dateDisabled({date:c,mode:a.datepickerMode})},this.customClass=function(b){return a.customClass({date:b,mode:a.datepickerMode})},this.split=function(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c},this.fixTimeZone=function(a){var b=a.getHours();a.setHours(23===b?b+2:0)},a.select=function(b){if(a.datepickerMode===j.minMode){var c=k.$viewValue?new Date(k.$viewValue):new Date(0,0,0,0,0,0,0);c.setFullYear(b.getFullYear(),b.getMonth(),b.getDate()),k.$setViewValue(c),k.$render()}else j.activeDate=b,a.datepickerMode=j.modes[j.modes.indexOf(a.datepickerMode)-1]},a.move=function(a){var b=j.activeDate.getFullYear()+a*(j.step.years||0),c=j.activeDate.getMonth()+a*(j.step.months||0);j.activeDate.setFullYear(b,c,1),j.refreshView()},a.toggleMode=function(b){b=b||1,a.datepickerMode===j.maxMode&&1===b||a.datepickerMode===j.minMode&&-1===b||(a.datepickerMode=j.modes[j.modes.indexOf(a.datepickerMode)+b])},a.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var l=function(){j.element[0].focus()};a.$on("uib:datepicker.focus",l),a.keydown=function(b){var c=a.keys[b.which];if(c&&!b.shiftKey&&!b.altKey)if(b.preventDefault(),j.shortcutPropagation||b.stopPropagation(),"enter"===c||"space"===c){if(j.isDisabled(j.activeDate))return;a.select(j.activeDate)}else!b.ctrlKey||"up"!==c&&"down"!==c?(j.handleKeyDown(c,b),j.refreshView()):a.toggleMode("up"===c?1:-1)}}]).directive("datepicker",["$log","$datepickerSuppressWarning",function(a,b){return{replace:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/datepicker.html"},scope:{datepickerMode:"=?",dateDisabled:"&",customClass:"&",shortcutPropagation:"&?"},require:["datepicker","^ngModel"],controller:"DatepickerController",controllerAs:"datepicker",link:function(c,d,e,f){b||a.warn("datepicker is now deprecated. Use uib-datepicker instead.");var g=f[0],h=f[1];g.init(h)}}}]).directive("daypicker",["$log","$datepickerSuppressWarning",function(a,b){return{replace:!0,templateUrl:"template/datepicker/day.html",require:["^datepicker","daypicker"],controller:"UibDaypickerController",link:function(c,d,e,f){b||a.warn("daypicker is now deprecated. Use uib-daypicker instead.");var g=f[0],h=f[1];h.init(g)}}}]).directive("monthpicker",["$log","$datepickerSuppressWarning",function(a,b){return{replace:!0,templateUrl:"template/datepicker/month.html",require:["^datepicker","monthpicker"],controller:"UibMonthpickerController",link:function(c,d,e,f){b||a.warn("monthpicker is now deprecated. Use uib-monthpicker instead.");var g=f[0],h=f[1];h.init(g)}}}]).directive("yearpicker",["$log","$datepickerSuppressWarning",function(a,b){return{replace:!0,templateUrl:"template/datepicker/year.html",require:["^datepicker","yearpicker"],controller:"UibYearpickerController",link:function(c,d,e,f){b||a.warn("yearpicker is now deprecated. Use uib-yearpicker instead.");var g=f[0];angular.extend(g,f[1]),g.yearpickerInit(),g.refreshView()}}}]).directive("datepickerPopup",["$log","$datepickerSuppressWarning",function(a,b){return{require:["ngModel","datepickerPopup"],controller:"UibDatepickerPopupController",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&",customClass:"&"},link:function(c,d,e,f){b||a.warn("datepicker-popup is now deprecated. Use uib-datepicker-popup instead.");var g=f[0],h=f[1];h.init(g)}}}]).directive("datepickerPopupWrap",["$log","$datepickerSuppressWarning",function(a,b){return{replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/datepicker/popup.html"},link:function(){b||a.warn("datepicker-popup-wrap is now deprecated. Use uib-datepicker-popup-wrap instead.")}}}]),angular.module("ui.bootstrap.dropdown",["ui.bootstrap.position"]).constant("uibDropdownConfig",{openClass:"open"}).service("uibDropdownService",["$document","$rootScope",function(a,b){var c=null;this.open=function(b){c||(a.bind("click",d),a.bind("keydown",e)),c&&c!==b&&(c.isOpen=!1),c=b},this.close=function(b){c===b&&(c=null,a.unbind("click",d),a.unbind("keydown",e))};var d=function(a){if(c&&(!a||"disabled"!==c.getAutoClose())){var d=c.getToggleElement();if(!(a&&d&&d[0].contains(a.target))){var e=c.getDropdownElement();a&&"outsideClick"===c.getAutoClose()&&e&&e[0].contains(a.target)||(c.isOpen=!1,b.$$phase||c.$apply())}}},e=function(a){27===a.which?(c.focusToggleElement(),d()):c.isKeynavEnabled()&&/(38|40)/.test(a.which)&&c.isOpen&&(a.preventDefault(),a.stopPropagation(),c.focusDropdownEntry(a.which))}}]).controller("UibDropdownController",["$scope","$element","$attrs","$parse","uibDropdownConfig","uibDropdownService","$animate","$uibPosition","$document","$compile","$templateRequest",function(a,b,c,d,e,f,g,h,i,j,k){var l,m,n=this,o=a.$new(),p=e.openClass,q=angular.noop,r=c.onToggle?d(c.onToggle):angular.noop,s=!1,t=!1;b.addClass("dropdown"),this.init=function(){c.isOpen&&(m=d(c.isOpen),q=m.assign,a.$watch(m,function(a){o.isOpen=!!a})),s=angular.isDefined(c.dropdownAppendToBody),t=angular.isDefined(c.uibKeyboardNav),s&&n.dropdownMenu&&(i.find("body").append(n.dropdownMenu),b.on("$destroy",function(){n.dropdownMenu.remove()}))},this.toggle=function(a){return o.isOpen=arguments.length?!!a:!o.isOpen},this.isOpen=function(){return o.isOpen},o.getToggleElement=function(){return n.toggleElement},o.getAutoClose=function(){return c.autoClose||"always"},o.getElement=function(){return b},o.isKeynavEnabled=function(){return t},o.focusDropdownEntry=function(a){var c=n.dropdownMenu?angular.element(n.dropdownMenu).find("a"):angular.element(b).find("ul").eq(0).find("a");switch(a){case 40:angular.isNumber(n.selectedOption)?n.selectedOption=n.selectedOption===c.length-1?n.selectedOption:n.selectedOption+1:n.selectedOption=0;break;case 38:angular.isNumber(n.selectedOption)?n.selectedOption=0===n.selectedOption?0:n.selectedOption-1:n.selectedOption=c.length-1}c[n.selectedOption].focus()},o.getDropdownElement=function(){return n.dropdownMenu},o.focusToggleElement=function(){n.toggleElement&&n.toggleElement[0].focus()},o.$watch("isOpen",function(c,d){if(s&&n.dropdownMenu){var e=h.positionElements(b,n.dropdownMenu,"bottom-left",!0),i={top:e.top+"px",display:c?"block":"none"},m=n.dropdownMenu.hasClass("dropdown-menu-right");m?(i.left="auto",i.right=window.innerWidth-(e.left+b.prop("offsetWidth"))+"px"):(i.left=e.left+"px",i.right="auto"),n.dropdownMenu.css(i)}if(g[c?"addClass":"removeClass"](b,p).then(function(){angular.isDefined(c)&&c!==d&&r(a,{open:!!c})}),c)n.dropdownMenuTemplateUrl&&k(n.dropdownMenuTemplateUrl).then(function(a){l=o.$new(),j(a.trim())(l,function(a){var b=a;n.dropdownMenu.replaceWith(b),n.dropdownMenu=b})}),o.focusToggleElement(),f.open(o);else{if(n.dropdownMenuTemplateUrl){l&&l.$destroy();var t=angular.element('<ul class="dropdown-menu"></ul>');n.dropdownMenu.replaceWith(t),n.dropdownMenu=t}f.close(o),n.selectedOption=null}angular.isFunction(q)&&q(a,c)}),a.$on("$locationChangeSuccess",function(){"disabled"!==o.getAutoClose()&&(o.isOpen=!1)});var u=a.$on("$destroy",function(){o.$destroy()});o.$on("$destroy",u)}]).directive("uibDropdown",function(){return{controller:"UibDropdownController",link:function(a,b,c,d){d.init()}}}).directive("uibDropdownMenu",function(){return{restrict:"AC",require:"?^uibDropdown",link:function(a,b,c,d){if(d&&!angular.isDefined(c.dropdownNested)){b.addClass("dropdown-menu");var e=c.templateUrl;e&&(d.dropdownMenuTemplateUrl=e),d.dropdownMenu||(d.dropdownMenu=b)}}}}).directive("uibKeyboardNav",function(){return{restrict:"A",require:"?^uibDropdown",link:function(a,b,c,d){b.bind("keydown",function(a){if(-1!==[38,40].indexOf(a.which)){a.preventDefault(),a.stopPropagation();var b=d.dropdownMenu.find("a");switch(a.which){case 40:angular.isNumber(d.selectedOption)?d.selectedOption=d.selectedOption===b.length-1?d.selectedOption:d.selectedOption+1:d.selectedOption=0;break;case 38:angular.isNumber(d.selectedOption)?d.selectedOption=0===d.selectedOption?0:d.selectedOption-1:d.selectedOption=b.length-1}b[d.selectedOption].focus()}})}}}).directive("uibDropdownToggle",function(){return{require:"?^uibDropdown",link:function(a,b,c,d){if(d){b.addClass("dropdown-toggle"),d.toggleElement=b;var e=function(e){e.preventDefault(),b.hasClass("disabled")||c.disabled||a.$apply(function(){d.toggle()})};b.bind("click",e),b.attr({"aria-haspopup":!0,"aria-expanded":!1}),a.$watch(d.isOpen,function(a){b.attr("aria-expanded",!!a)}),a.$on("$destroy",function(){b.unbind("click",e)})}}}}),angular.module("ui.bootstrap.dropdown").value("$dropdownSuppressWarning",!1).service("dropdownService",["$log","$dropdownSuppressWarning","uibDropdownService",function(a,b,c){b||a.warn("dropdownService is now deprecated. Use uibDropdownService instead."),angular.extend(this,c)}]).controller("DropdownController",["$scope","$element","$attrs","$parse","uibDropdownConfig","uibDropdownService","$animate","$uibPosition","$document","$compile","$templateRequest","$log","$dropdownSuppressWarning",function(a,b,c,d,e,f,g,h,i,j,k,l,m){m||l.warn("DropdownController is now deprecated. Use UibDropdownController instead.");var n,o,p=this,q=a.$new(),r=e.openClass,s=angular.noop,t=c.onToggle?d(c.onToggle):angular.noop,u=!1,v=!1;b.addClass("dropdown"),this.init=function(){c.isOpen&&(o=d(c.isOpen),s=o.assign,a.$watch(o,function(a){q.isOpen=!!a})),u=angular.isDefined(c.dropdownAppendToBody),v=angular.isDefined(c.uibKeyboardNav),u&&p.dropdownMenu&&(i.find("body").append(p.dropdownMenu),b.on("$destroy",function(){p.dropdownMenu.remove()}))},this.toggle=function(a){return q.isOpen=arguments.length?!!a:!q.isOpen},this.isOpen=function(){return q.isOpen},q.getToggleElement=function(){return p.toggleElement},q.getAutoClose=function(){return c.autoClose||"always"},q.getElement=function(){return b},q.isKeynavEnabled=function(){return v},q.focusDropdownEntry=function(a){var c=p.dropdownMenu?angular.element(p.dropdownMenu).find("a"):angular.element(b).find("ul").eq(0).find("a");switch(a){case 40:angular.isNumber(p.selectedOption)?p.selectedOption=p.selectedOption===c.length-1?p.selectedOption:p.selectedOption+1:p.selectedOption=0;break;case 38:angular.isNumber(p.selectedOption)?p.selectedOption=0===p.selectedOption?0:p.selectedOption-1:p.selectedOption=c.length-1}c[p.selectedOption].focus()},q.getDropdownElement=function(){return p.dropdownMenu},q.focusToggleElement=function(){p.toggleElement&&p.toggleElement[0].focus()},q.$watch("isOpen",function(c,d){if(u&&p.dropdownMenu){var e=h.positionElements(b,p.dropdownMenu,"bottom-left",!0),i={top:e.top+"px",display:c?"block":"none"},l=p.dropdownMenu.hasClass("dropdown-menu-right");l?(i.left="auto",i.right=window.innerWidth-(e.left+b.prop("offsetWidth"))+"px"):(i.left=e.left+"px",i.right="auto"),p.dropdownMenu.css(i)}if(g[c?"addClass":"removeClass"](b,r).then(function(){angular.isDefined(c)&&c!==d&&t(a,{open:!!c})}),c)p.dropdownMenuTemplateUrl&&k(p.dropdownMenuTemplateUrl).then(function(a){n=q.$new(),j(a.trim())(n,function(a){var b=a;p.dropdownMenu.replaceWith(b),p.dropdownMenu=b})}),q.focusToggleElement(),f.open(q);else{if(p.dropdownMenuTemplateUrl){n&&n.$destroy();var m=angular.element('<ul class="dropdown-menu"></ul>');p.dropdownMenu.replaceWith(m),p.dropdownMenu=m}f.close(q),p.selectedOption=null}angular.isFunction(s)&&s(a,c)}),a.$on("$locationChangeSuccess",function(){"disabled"!==q.getAutoClose()&&(q.isOpen=!1)});var w=a.$on("$destroy",function(){q.$destroy()});q.$on("$destroy",w)}]).directive("dropdown",["$log","$dropdownSuppressWarning",function(a,b){return{controller:"DropdownController",link:function(c,d,e,f){b||a.warn("dropdown is now deprecated. Use uib-dropdown instead."),f.init()}}}]).directive("dropdownMenu",["$log","$dropdownSuppressWarning",function(a,b){return{restrict:"AC",require:"?^dropdown",link:function(c,d,e,f){if(f&&!angular.isDefined(e.dropdownNested)){b||a.warn("dropdown-menu is now deprecated. Use uib-dropdown-menu instead."),d.addClass("dropdown-menu");var g=e.templateUrl;g&&(f.dropdownMenuTemplateUrl=g),f.dropdownMenu||(f.dropdownMenu=d)}}}}]).directive("keyboardNav",["$log","$dropdownSuppressWarning",function(a,b){return{restrict:"A",require:"?^dropdown",link:function(c,d,e,f){b||a.warn("keyboard-nav is now deprecated. Use uib-keyboard-nav instead."),d.bind("keydown",function(a){if(-1!==[38,40].indexOf(a.which)){a.preventDefault(),a.stopPropagation();var b=f.dropdownMenu.find("a");switch(a.which){case 40:angular.isNumber(f.selectedOption)?f.selectedOption=f.selectedOption===b.length-1?f.selectedOption:f.selectedOption+1:f.selectedOption=0;break;case 38:angular.isNumber(f.selectedOption)?f.selectedOption=0===f.selectedOption?0:f.selectedOption-1:f.selectedOption=b.length-1}b[f.selectedOption].focus()}})}}}]).directive("dropdownToggle",["$log","$dropdownSuppressWarning",function(a,b){return{require:"?^dropdown",link:function(c,d,e,f){if(b||a.warn("dropdown-toggle is now deprecated. Use uib-dropdown-toggle instead."),f){d.addClass("dropdown-toggle"),f.toggleElement=d;var g=function(a){a.preventDefault(),d.hasClass("disabled")||e.disabled||c.$apply(function(){f.toggle()})};d.bind("click",g),d.attr({"aria-haspopup":!0,"aria-expanded":!1}),c.$watch(f.isOpen,function(a){d.attr("aria-expanded",!!a)}),c.$on("$destroy",function(){d.unbind("click",g)})}}}}]),angular.module("ui.bootstrap.stackedMap",[]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c<a.length;c++)if(b==a[c].key)return a[c]},keys:function(){for(var b=[],c=0;c<a.length;c++)b.push(a[c].key);return b},top:function(){return a[a.length-1]},remove:function(b){for(var c=-1,d=0;d<a.length;d++)if(b==a[d].key){c=d;break}return a.splice(c,1)[0]},removeTop:function(){return a.splice(a.length-1,1)[0]},length:function(){return a.length}}}}}),angular.module("ui.bootstrap.modal",["ui.bootstrap.stackedMap"]).factory("$$multiMap",function(){return{createNew:function(){var a={};return{entries:function(){return Object.keys(a).map(function(b){return{key:b,value:a[b]}})},get:function(b){return a[b]},hasKey:function(b){return!!a[b]},keys:function(){return Object.keys(a)},put:function(b,c){a[b]||(a[b]=[]),a[b].push(c)},remove:function(b,c){var d=a[b];if(d){var e=d.indexOf(c);-1!==e&&d.splice(e,1),d.length||delete a[b]}}}}}}).directive("uibModalBackdrop",["$animate","$injector","$uibModalStack",function(a,b,c){function d(b,d,f){d.addClass("modal-backdrop"),f.modalInClass&&(e?e(d,{addClass:f.modalInClass}).start():a.addClass(d,f.modalInClass),b.$on(c.NOW_CLOSING_EVENT,function(b,c){var g=c();e?e(d,{removeClass:f.modalInClass}).start().then(g):a.removeClass(d,f.modalInClass).then(g)}))}var e=null;return b.has("$animateCss")&&(e=b.get("$animateCss")),{replace:!0,templateUrl:"template/modal/backdrop.html",compile:function(a,b){return a.addClass(b.backdropClass),d}}}]).directive("uibModalWindow",["$uibModalStack","$q","$animate","$injector",function(a,b,c,d){var e=null;return d.has("$animateCss")&&(e=d.get("$animateCss")),{scope:{index:"@"},replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/modal/window.html"},link:function(d,f,g){f.addClass(g.windowClass||""),f.addClass(g.windowTopClass||""),d.size=g.size,d.close=function(b){var c=a.getTop();c&&c.value.backdrop&&"static"!==c.value.backdrop&&b.target===b.currentTarget&&(b.preventDefault(),b.stopPropagation(),a.dismiss(c.key,"backdrop click"))},f.on("click",d.close),d.$isRendered=!0;var h=b.defer();g.$observe("modalRender",function(a){"true"==a&&h.resolve()}),h.promise.then(function(){var h=null;g.modalInClass&&(h=e?e(f,{addClass:g.modalInClass}).start():c.addClass(f,g.modalInClass),d.$on(a.NOW_CLOSING_EVENT,function(a,b){var d=b();e?e(f,{removeClass:g.modalInClass}).start().then(d):c.removeClass(f,g.modalInClass).then(d)})),b.when(h).then(function(){var a=f[0].querySelector("[autofocus]");a?a.focus():f[0].focus()});var i=a.getTop();i&&a.modalRendered(i.key)})}}}]).directive("uibModalAnimationClass",function(){return{compile:function(a,b){b.modalAnimation&&a.addClass(b.uibModalAnimationClass)}}}).directive("uibModalTransclude",function(){return{link:function(a,b,c,d,e){e(a.$parent,function(a){b.empty(),b.append(a)})}}}).factory("$uibModalStack",["$animate","$timeout","$document","$compile","$rootScope","$q","$injector","$$multiMap","$$stackedMap",function(a,b,c,d,e,f,g,h,i){function j(){for(var a=-1,b=u.keys(),c=0;c<b.length;c++)u.get(b[c]).value.backdrop&&(a=c);return a}function k(a,b){var d=c.find("body").eq(0),e=u.get(a).value;u.remove(a),n(e.modalDomEl,e.modalScope,function(){var b=e.openedClass||t;v.remove(b,a),d.toggleClass(b,v.hasKey(b)),l(!0)}),m(),b&&b.focus?b.focus():d.focus()}function l(a){var b;u.length()>0&&(b=u.top().value,b.modalDomEl.toggleClass(b.windowTopClass||"",a))}function m(){if(q&&-1==j()){var a=r;n(q,r,function(){a=null}),q=void 0,r=void 0}}function n(b,c,d){function e(){e.done||(e.done=!0,p?p(b,{event:"leave"}).start().then(function(){b.remove()}):a.leave(b),c.$destroy(),d&&d())}var g,h=null,i=function(){return g||(g=f.defer(),h=g.promise),function(){g.resolve()}};return c.$broadcast(w.NOW_CLOSING_EVENT,i),f.when(h).then(e)}function o(a,b,c){return!a.value.modalScope.$broadcast("modal.closing",b,c).defaultPrevented}var p=null;g.has("$animateCss")&&(p=g.get("$animateCss"));var q,r,s,t="modal-open",u=i.createNew(),v=h.createNew(),w={NOW_CLOSING_EVENT:"modal.stack.now-closing"},x=0,y="a[href], area[href], input:not([disabled]), button:not([disabled]),select:not([disabled]), textarea:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable=true]";return e.$watch(j,function(a){r&&(r.index=a)}),c.bind("keydown",function(a){if(a.isDefaultPrevented())return a;var b=u.top();if(b&&b.value.keyboard)switch(a.which){case 27:a.preventDefault(),e.$apply(function(){w.dismiss(b.key,"escape key press")});break;case 9:w.loadFocusElementList(b);var c=!1;a.shiftKey?w.isFocusInFirstItem(a)&&(c=w.focusLastFocusableElement()):w.isFocusInLastItem(a)&&(c=w.focusFirstFocusableElement()),c&&(a.preventDefault(),a.stopPropagation())}}),w.open=function(a,b){var f=c[0].activeElement,g=b.openedClass||t;l(!1),u.add(a,{deferred:b.deferred,renderDeferred:b.renderDeferred,modalScope:b.scope,backdrop:b.backdrop,keyboard:b.keyboard,openedClass:b.openedClass,windowTopClass:b.windowTopClass}),v.put(g,a);var h=c.find("body").eq(0),i=j();if(i>=0&&!q){r=e.$new(!0),r.index=i;var k=angular.element('<div uib-modal-backdrop="modal-backdrop"></div>');k.attr("backdrop-class",b.backdropClass),b.animation&&k.attr("modal-animation","true"),q=d(k)(r),h.append(q)}var m=angular.element('<div uib-modal-window="modal-window"></div>');m.attr({"template-url":b.windowTemplateUrl,"window-class":b.windowClass,"window-top-class":b.windowTopClass,size:b.size,index:u.length()-1,animate:"animate"}).html(b.content),b.animation&&m.attr("modal-animation","true");var n=d(m)(b.scope);u.top().value.modalDomEl=n,u.top().value.modalOpener=f,h.append(n),h.addClass(g),w.clearFocusListCache()},w.close=function(a,b){var c=u.get(a);return c&&o(c,b,!0)?(c.value.modalScope.$$uibDestructionScheduled=!0,c.value.deferred.resolve(b),k(a,c.value.modalOpener),!0):!c},w.dismiss=function(a,b){var c=u.get(a);return c&&o(c,b,!1)?(c.value.modalScope.$$uibDestructionScheduled=!0,c.value.deferred.reject(b),k(a,c.value.modalOpener),!0):!c},w.dismissAll=function(a){for(var b=this.getTop();b&&this.dismiss(b.key,a);)b=this.getTop()},w.getTop=function(){return u.top()},w.modalRendered=function(a){var b=u.get(a);b&&b.value.renderDeferred.resolve()},w.focusFirstFocusableElement=function(){return s.length>0?(s[0].focus(),!0):!1},w.focusLastFocusableElement=function(){return s.length>0?(s[s.length-1].focus(),!0):!1},w.isFocusInFirstItem=function(a){return s.length>0?(a.target||a.srcElement)==s[0]:!1},w.isFocusInLastItem=function(a){return s.length>0?(a.target||a.srcElement)==s[s.length-1]:!1},w.clearFocusListCache=function(){s=[],x=0},w.loadFocusElementList=function(a){if((void 0===s||!s.length)&&a){var b=a.value.modalDomEl;b&&b.length&&(s=b[0].querySelectorAll(y))}},w}]).provider("$uibModal",function(){var a={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$injector","$rootScope","$q","$templateRequest","$controller","$uibModalStack","$modalSuppressWarning","$log",function(b,c,d,e,f,g,h,i){function j(a){return a.template?d.when(a.template):e(angular.isFunction(a.templateUrl)?a.templateUrl():a.templateUrl)}function k(a){var c=[];return angular.forEach(a,function(a){angular.isFunction(a)||angular.isArray(a)?c.push(d.when(b.invoke(a))):angular.isString(a)?c.push(d.when(b.get(a))):c.push(d.when(a))}),c}var l={},m=null;return l.getPromiseChain=function(){return m},l.open=function(b){function e(){return r}var l=d.defer(),n=d.defer(),o=d.defer(),p={result:l.promise,opened:n.promise,rendered:o.promise,close:function(a){return g.close(p,a)},dismiss:function(a){return g.dismiss(p,a)}};if(b=angular.extend({},a.options,b),b.resolve=b.resolve||{},!b.template&&!b.templateUrl)throw new Error("One of template or templateUrl options is required.");var q,r=d.all([j(b)].concat(k(b.resolve)));return q=m=d.all([m]).then(e,e).then(function(a){var d=(b.scope||c).$new();d.$close=p.close,d.$dismiss=p.dismiss,d.$on("$destroy",function(){d.$$uibDestructionScheduled||d.$dismiss("$uibUnscheduledDestruction")});var e,j={},k=1;b.controller&&(j.$scope=d,j.$uibModalInstance=p,Object.defineProperty(j,"$modalInstance",{get:function(){return h||i.warn("$modalInstance is now deprecated. Use $uibModalInstance instead."),p}}),angular.forEach(b.resolve,function(b,c){j[c]=a[k++]}),e=f(b.controller,j),b.controllerAs&&(b.bindToController&&angular.extend(e,d),d[b.controllerAs]=e)),g.open(p,{scope:d,deferred:l,renderDeferred:o,content:a[0],animation:b.animation,backdrop:b.backdrop,keyboard:b.keyboard,backdropClass:b.backdropClass,windowTopClass:b.windowTopClass,windowClass:b.windowClass,windowTemplateUrl:b.windowTemplateUrl,size:b.size,openedClass:b.openedClass}),n.resolve(!0)},function(a){n.reject(a),l.reject(a)})["finally"](function(){m===q&&(m=null)}),p},l}]};return a}),angular.module("ui.bootstrap.modal").value("$modalSuppressWarning",!1).directive("modalBackdrop",["$animate","$injector","$modalStack","$log","$modalSuppressWarning",function(a,b,c,d,e){function f(b,f,h){e||d.warn("modal-backdrop is now deprecated. Use uib-modal-backdrop instead."),f.addClass("modal-backdrop"),h.modalInClass&&(g?g(f,{addClass:h.modalInClass}).start():a.addClass(f,h.modalInClass),b.$on(c.NOW_CLOSING_EVENT,function(b,c){var d=c();g?g(f,{removeClass:h.modalInClass}).start().then(d):a.removeClass(f,h.modalInClass).then(d)}))}var g=null;return b.has("$animateCss")&&(g=b.get("$animateCss")),{replace:!0,templateUrl:"template/modal/backdrop.html",compile:function(a,b){return a.addClass(b.backdropClass),f}}}]).directive("modalWindow",["$modalStack","$q","$animate","$injector","$log","$modalSuppressWarning",function(a,b,c,d,e,f){var g=null;return d.has("$animateCss")&&(g=d.get("$animateCss")),{scope:{index:"@"},replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/modal/window.html"},link:function(d,h,i){f||e.warn("modal-window is now deprecated. Use uib-modal-window instead."),h.addClass(i.windowClass||""),h.addClass(i.windowTopClass||""),d.size=i.size,d.close=function(b){var c=a.getTop();c&&c.value.backdrop&&"static"!==c.value.backdrop&&b.target===b.currentTarget&&(b.preventDefault(),b.stopPropagation(),a.dismiss(c.key,"backdrop click"))},h.on("click",d.close),d.$isRendered=!0;var j=b.defer();i.$observe("modalRender",function(a){"true"==a&&j.resolve()}),j.promise.then(function(){var e=null;i.modalInClass&&(e=g?g(h,{addClass:i.modalInClass}).start():c.addClass(h,i.modalInClass),d.$on(a.NOW_CLOSING_EVENT,function(a,b){var d=b();g?g(h,{removeClass:i.modalInClass}).start().then(d):c.removeClass(h,i.modalInClass).then(d)})),b.when(e).then(function(){var a=h[0].querySelector("[autofocus]");a?a.focus():h[0].focus()});var f=a.getTop();f&&a.modalRendered(f.key)})}}}]).directive("modalAnimationClass",["$log","$modalSuppressWarning",function(a,b){return{compile:function(c,d){b||a.warn("modal-animation-class is now deprecated. Use uib-modal-animation-class instead."),d.modalAnimation&&c.addClass(d.modalAnimationClass)}}}]).directive("modalTransclude",["$log","$modalSuppressWarning",function(a,b){return{link:function(c,d,e,f,g){
b||a.warn("modal-transclude is now deprecated. Use uib-modal-transclude instead."),g(c.$parent,function(a){d.empty(),d.append(a)})}}}]).service("$modalStack",["$animate","$timeout","$document","$compile","$rootScope","$q","$injector","$$multiMap","$$stackedMap","$uibModalStack","$log","$modalSuppressWarning",function(a,b,c,d,e,f,g,h,i,j,k,l){l||k.warn("$modalStack is now deprecated. Use $uibModalStack instead."),angular.extend(this,j)}]).provider("$modal",["$uibModalProvider",function(a){angular.extend(this,a),this.$get=["$injector","$log","$modalSuppressWarning",function(b,c,d){return d||c.warn("$modal is now deprecated. Use $uibModal instead."),b.invoke(a.$get)}]}]),angular.module("ui.bootstrap.pagination",[]).controller("UibPaginationController",["$scope","$attrs","$parse",function(a,b,c){var d=this,e={$setViewValue:angular.noop},f=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(g,h){e=g,this.config=h,e.$render=function(){d.render()},b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){d.itemsPerPage=parseInt(b,10),a.totalPages=d.calculateTotalPages()}):this.itemsPerPage=h.itemsPerPage,a.$watch("totalItems",function(){a.totalPages=d.calculateTotalPages()}),a.$watch("totalPages",function(b){f(a.$parent,b),a.page>b?a.selectPage(b):e.$render()})},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.render=function(){a.page=parseInt(e.$viewValue,10)||1},a.selectPage=function(b,c){c&&c.preventDefault();var d=!a.ngDisabled||!c;d&&a.page!==b&&b>0&&b<=a.totalPages&&(c&&c.target&&c.target.blur(),e.$setViewValue(b),e.$render())},a.getText=function(b){return a[b+"Text"]||d.config[b+"Text"]},a.noPrevious=function(){return 1===a.page},a.noNext=function(){return a.page===a.totalPages}}]).constant("uibPaginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("uibPagination",["$parse","uibPaginationConfig",function(a,b){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@",ngDisabled:"="},require:["uibPagination","?ngModel"],controller:"UibPaginationController",controllerAs:"pagination",templateUrl:function(a,b){return b.templateUrl||"template/pagination/pagination.html"},replace:!0,link:function(c,d,e,f){function g(a,b,c){return{number:a,text:b,active:c}}function h(a,b){var c=[],d=1,e=b,f=angular.isDefined(k)&&b>k;f&&(l?(d=Math.max(a-Math.floor(k/2),1),e=d+k-1,e>b&&(e=b,d=e-k+1)):(d=(Math.ceil(a/k)-1)*k+1,e=Math.min(d+k-1,b)));for(var h=d;e>=h;h++){var i=g(h,h,h===a);c.push(i)}if(f&&!l){if(d>1){var j=g(d-1,"...",!1);c.unshift(j)}if(b>e){var m=g(e+1,"...",!1);c.push(m)}}return c}var i=f[0],j=f[1];if(j){var k=angular.isDefined(e.maxSize)?c.$parent.$eval(e.maxSize):b.maxSize,l=angular.isDefined(e.rotate)?c.$parent.$eval(e.rotate):b.rotate;c.boundaryLinks=angular.isDefined(e.boundaryLinks)?c.$parent.$eval(e.boundaryLinks):b.boundaryLinks,c.directionLinks=angular.isDefined(e.directionLinks)?c.$parent.$eval(e.directionLinks):b.directionLinks,i.init(j,b),e.maxSize&&c.$parent.$watch(a(e.maxSize),function(a){k=parseInt(a,10),i.render()});var m=i.render;i.render=function(){m(),c.page>0&&c.page<=c.totalPages&&(c.pages=h(c.page,c.totalPages))}}}}}]).constant("uibPagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("uibPager",["uibPagerConfig",function(a){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@",ngDisabled:"="},require:["uibPager","?ngModel"],controller:"UibPaginationController",controllerAs:"pagination",templateUrl:function(a,b){return b.templateUrl||"template/pagination/pager.html"},replace:!0,link:function(b,c,d,e){var f=e[0],g=e[1];g&&(b.align=angular.isDefined(d.align)?b.$parent.$eval(d.align):a.align,f.init(g,a))}}}]),angular.module("ui.bootstrap.pagination").value("$paginationSuppressWarning",!1).controller("PaginationController",["$scope","$attrs","$parse","$log","$paginationSuppressWarning",function(a,b,c,d,e){e||d.warn("PaginationController is now deprecated. Use UibPaginationController instead.");var f=this,g={$setViewValue:angular.noop},h=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(d,e){g=d,this.config=e,g.$render=function(){f.render()},b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){f.itemsPerPage=parseInt(b,10),a.totalPages=f.calculateTotalPages()}):this.itemsPerPage=e.itemsPerPage,a.$watch("totalItems",function(){a.totalPages=f.calculateTotalPages()}),a.$watch("totalPages",function(b){h(a.$parent,b),a.page>b?a.selectPage(b):g.$render()})},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.render=function(){a.page=parseInt(g.$viewValue,10)||1},a.selectPage=function(b,c){c&&c.preventDefault();var d=!a.ngDisabled||!c;d&&a.page!==b&&b>0&&b<=a.totalPages&&(c&&c.target&&c.target.blur(),g.$setViewValue(b),g.$render())},a.getText=function(b){return a[b+"Text"]||f.config[b+"Text"]},a.noPrevious=function(){return 1===a.page},a.noNext=function(){return a.page===a.totalPages}}]).directive("pagination",["$parse","uibPaginationConfig","$log","$paginationSuppressWarning",function(a,b,c,d){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@",ngDisabled:"="},require:["pagination","?ngModel"],controller:"PaginationController",controllerAs:"pagination",templateUrl:function(a,b){return b.templateUrl||"template/pagination/pagination.html"},replace:!0,link:function(e,f,g,h){function i(a,b,c){return{number:a,text:b,active:c}}function j(a,b){var c=[],d=1,e=b,f=angular.isDefined(m)&&b>m;f&&(n?(d=Math.max(a-Math.floor(m/2),1),e=d+m-1,e>b&&(e=b,d=e-m+1)):(d=(Math.ceil(a/m)-1)*m+1,e=Math.min(d+m-1,b)));for(var g=d;e>=g;g++){var h=i(g,g,g===a);c.push(h)}if(f&&!n){if(d>1){var j=i(d-1,"...",!1);c.unshift(j)}if(b>e){var k=i(e+1,"...",!1);c.push(k)}}return c}d||c.warn("pagination is now deprecated. Use uib-pagination instead.");var k=h[0],l=h[1];if(l){var m=angular.isDefined(g.maxSize)?e.$parent.$eval(g.maxSize):b.maxSize,n=angular.isDefined(g.rotate)?e.$parent.$eval(g.rotate):b.rotate;e.boundaryLinks=angular.isDefined(g.boundaryLinks)?e.$parent.$eval(g.boundaryLinks):b.boundaryLinks,e.directionLinks=angular.isDefined(g.directionLinks)?e.$parent.$eval(g.directionLinks):b.directionLinks,k.init(l,b),g.maxSize&&e.$parent.$watch(a(g.maxSize),function(a){m=parseInt(a,10),k.render()});var o=k.render;k.render=function(){o(),e.page>0&&e.page<=e.totalPages&&(e.pages=j(e.page,e.totalPages))}}}}}]).directive("pager",["uibPagerConfig","$log","$paginationSuppressWarning",function(a,b,c){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@",ngDisabled:"="},require:["pager","?ngModel"],controller:"PaginationController",controllerAs:"pagination",templateUrl:function(a,b){return b.templateUrl||"template/pagination/pager.html"},replace:!0,link:function(d,e,f,g){c||b.warn("pager is now deprecated. Use uib-pager instead.");var h=g[0],i=g[1];i&&(d.align=angular.isDefined(f.align)?d.$parent.$eval(f.align):a.align,h.init(i,a))}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.stackedMap"]).provider("$uibTooltip",function(){function a(a){var b=/[A-Z]/g,c="-";return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",animation:!0,popupDelay:0,popupCloseDelay:0,useContentExp:!1},c={mouseenter:"mouseleave",click:"click",focus:"blur",none:""},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$document","$uibPosition","$interpolate","$rootScope","$parse","$$stackedMap",function(e,f,g,h,i,j,k,l,m){var n=m.createNew();return h.on("keypress",function(a){if(27===a.which){var b=n.top();b&&(b.value.close(),n.removeTop(),b=null)}}),function(e,k,m,o){function p(a){var b=(a||o.trigger||m).split(" "),d=b.map(function(a){return c[a]||a});return{show:b,hide:d}}o=angular.extend({},b,d,o);var q=a(e),r=j.startSymbol(),s=j.endSymbol(),t="<div "+q+'-popup title="'+r+"title"+s+'" '+(o.useContentExp?'content-exp="contentExp()" ':'content="'+r+"content"+s+'" ')+'placement="'+r+"placement"+s+'" popup-class="'+r+"popupClass"+s+'" animation="animation" is-open="isOpen"origin-scope="origScope" style="visibility: hidden; display: block; top: -9999px; left: -9999px;"></div>';return{compile:function(a,b){var c=f(t);return function(a,b,d,f){function j(){L.isOpen?q():m()}function m(){(!K||a.$eval(d[k+"Enable"]))&&(u(),x(),L.popupDelay?F||(F=g(r,L.popupDelay,!1)):r())}function q(){s(),L.popupCloseDelay?G||(G=g(t,L.popupCloseDelay,!1)):t()}function r(){return s(),u(),L.content?(v(),void L.$evalAsync(function(){L.isOpen=!0,y(!0),Q()})):angular.noop}function s(){F&&(g.cancel(F),F=null),H&&(g.cancel(H),H=null)}function t(){s(),u(),L&&L.$evalAsync(function(){L.isOpen=!1,y(!1),L.animation?E||(E=g(w,150,!1)):w()})}function u(){G&&(g.cancel(G),G=null),E&&(g.cancel(E),E=null)}function v(){C||(D=L.$new(),C=c(D,function(a){I?h.find("body").append(a):b.after(a)}),z())}function w(){A(),E=null,C&&(C.remove(),C=null),D&&(D.$destroy(),D=null)}function x(){L.title=d[k+"Title"],O?L.content=O(a):L.content=d[e],L.popupClass=d[k+"Class"],L.placement=angular.isDefined(d[k+"Placement"])?d[k+"Placement"]:o.placement;var b=parseInt(d[k+"PopupDelay"],10),c=parseInt(d[k+"PopupCloseDelay"],10);L.popupDelay=isNaN(b)?o.popupDelay:b,L.popupCloseDelay=isNaN(c)?o.popupCloseDelay:c}function y(b){N&&angular.isFunction(N.assign)&&N.assign(a,b)}function z(){P.length=0,O?(P.push(a.$watch(O,function(a){L.content=a,!a&&L.isOpen&&t()})),P.push(D.$watch(function(){M||(M=!0,D.$$postDigest(function(){M=!1,L&&L.isOpen&&Q()}))}))):P.push(d.$observe(e,function(a){L.content=a,!a&&L.isOpen?t():Q()})),P.push(d.$observe(k+"Title",function(a){L.title=a,L.isOpen&&Q()})),P.push(d.$observe(k+"Placement",function(a){L.placement=a?a:o.placement,L.isOpen&&Q()}))}function A(){P.length&&(angular.forEach(P,function(a){a()}),P.length=0)}function B(){var a=d[k+"Trigger"];R(),J=p(a),"none"!==J.show&&J.show.forEach(function(a,c){a===J.hide[c]?b[0].addEventListener(a,j):a&&(b[0].addEventListener(a,m),J.hide[c].split(" ").forEach(function(a){b[0].addEventListener(a,q)})),b.on("keypress",function(a){27===a.which&&q()})})}var C,D,E,F,G,H,I=angular.isDefined(o.appendToBody)?o.appendToBody:!1,J=p(void 0),K=angular.isDefined(d[k+"Enable"]),L=a.$new(!0),M=!1,N=angular.isDefined(d[k+"IsOpen"])?l(d[k+"IsOpen"]):!1,O=o.useContentExp?l(d[e]):!1,P=[],Q=function(){C&&C.html()&&(H||(H=g(function(){C.css({top:0,left:0});var a=i.positionElements(b,C,L.placement,I);a.top+="px",a.left+="px",a.visibility="visible",C.css(a),H=null},0,!1)))};L.origScope=a,L.isOpen=!1,n.add(L,{close:t}),L.contentExp=function(){return L.content},d.$observe("disabled",function(a){a&&s(),a&&L.isOpen&&t()}),N&&a.$watch(N,function(a){L&&!a===L.isOpen&&j()});var R=function(){J.show.forEach(function(a){b.unbind(a,m)}),J.hide.forEach(function(a){a.split(" ").forEach(function(a){b[0].removeEventListener(a,q)})})};B();var S=a.$eval(d[k+"Animation"]);L.animation=angular.isDefined(S)?!!S:o.animation;var T=a.$eval(d[k+"AppendToBody"]);I=angular.isDefined(T)?T:I,I&&a.$on("$locationChangeSuccess",function(){L.isOpen&&t()}),a.$on("$destroy",function(){s(),u(),R(),w(),n.remove(L),L=null})}}}}}]}).directive("uibTooltipTemplateTransclude",["$animate","$sce","$compile","$templateRequest",function(a,b,c,d){return{link:function(e,f,g){var h,i,j,k=e.$eval(g.tooltipTemplateTranscludeScope),l=0,m=function(){i&&(i.remove(),i=null),h&&(h.$destroy(),h=null),j&&(a.leave(j).then(function(){i=null}),i=j,j=null)};e.$watch(b.parseAsResourceUrl(g.uibTooltipTemplateTransclude),function(b){var g=++l;b?(d(b,!0).then(function(d){if(g===l){var e=k.$new(),i=d,n=c(i)(e,function(b){m(),a.enter(b,f)});h=e,j=n,h.$emit("$includeContentLoaded",b)}},function(){g===l&&(m(),e.$emit("$includeContentError",b))}),e.$emit("$includeContentRequested",b)):m()}),e.$on("$destroy",m)}}}]).directive("uibTooltipClasses",function(){return{restrict:"A",link:function(a,b,c){a.placement&&b.addClass(a.placement),a.popupClass&&b.addClass(a.popupClass),a.animation()&&b.addClass(c.tooltipAnimationClass)}}}).directive("uibTooltipPopup",function(){return{replace:!0,scope:{content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html",link:function(a,b){b.addClass("tooltip")}}}).directive("uibTooltip",["$uibTooltip",function(a){return a("uibTooltip","tooltip","mouseenter")}]).directive("uibTooltipTemplatePopup",function(){return{replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/tooltip/tooltip-template-popup.html",link:function(a,b){b.addClass("tooltip")}}}).directive("uibTooltipTemplate",["$uibTooltip",function(a){return a("uibTooltipTemplate","tooltip","mouseenter",{useContentExp:!0})}]).directive("uibTooltipHtmlPopup",function(){return{replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-popup.html",link:function(a,b){b.addClass("tooltip")}}}).directive("uibTooltipHtml",["$uibTooltip",function(a){return a("uibTooltipHtml","tooltip","mouseenter",{useContentExp:!0})}]),angular.module("ui.bootstrap.tooltip").value("$tooltipSuppressWarning",!1).provider("$tooltip",["$uibTooltipProvider",function(a){angular.extend(this,a),this.$get=["$log","$tooltipSuppressWarning","$injector",function(b,c,d){return c||b.warn("$tooltip is now deprecated. Use $uibTooltip instead."),d.invoke(a.$get)}]}]).directive("tooltipTemplateTransclude",["$animate","$sce","$compile","$templateRequest","$log","$tooltipSuppressWarning",function(a,b,c,d,e,f){return{link:function(g,h,i){f||e.warn("tooltip-template-transclude is now deprecated. Use uib-tooltip-template-transclude instead.");var j,k,l,m=g.$eval(i.tooltipTemplateTranscludeScope),n=0,o=function(){k&&(k.remove(),k=null),j&&(j.$destroy(),j=null),l&&(a.leave(l).then(function(){k=null}),k=l,l=null)};g.$watch(b.parseAsResourceUrl(i.tooltipTemplateTransclude),function(b){var e=++n;b?(d(b,!0).then(function(d){if(e===n){var f=m.$new(),g=d,i=c(g)(f,function(b){o(),a.enter(b,h)});j=f,l=i,j.$emit("$includeContentLoaded",b)}},function(){e===n&&(o(),g.$emit("$includeContentError",b))}),g.$emit("$includeContentRequested",b)):o()}),g.$on("$destroy",o)}}}]).directive("tooltipClasses",["$log","$tooltipSuppressWarning",function(a,b){return{restrict:"A",link:function(c,d,e){b||a.warn("tooltip-classes is now deprecated. Use uib-tooltip-classes instead."),c.placement&&d.addClass(c.placement),c.popupClass&&d.addClass(c.popupClass),c.animation()&&d.addClass(e.tooltipAnimationClass)}}}]).directive("tooltipPopup",["$log","$tooltipSuppressWarning",function(a,b){return{replace:!0,scope:{content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html",link:function(c,d){b||a.warn("tooltip-popup is now deprecated. Use uib-tooltip-popup instead."),d.addClass("tooltip")}}}]).directive("tooltip",["$tooltip",function(a){return a("tooltip","tooltip","mouseenter")}]).directive("tooltipTemplatePopup",["$log","$tooltipSuppressWarning",function(a,b){return{replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/tooltip/tooltip-template-popup.html",link:function(c,d){b||a.warn("tooltip-template-popup is now deprecated. Use uib-tooltip-template-popup instead."),d.addClass("tooltip")}}}]).directive("tooltipTemplate",["$tooltip",function(a){return a("tooltipTemplate","tooltip","mouseenter",{useContentExp:!0})}]).directive("tooltipHtmlPopup",["$log","$tooltipSuppressWarning",function(a,b){return{replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-popup.html",link:function(c,d){b||a.warn("tooltip-html-popup is now deprecated. Use uib-tooltip-html-popup instead."),d.addClass("tooltip")}}}]).directive("tooltipHtml",["$tooltip",function(a){return a("tooltipHtml","tooltip","mouseenter",{useContentExp:!0})}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("uibPopoverTemplatePopup",function(){return{replace:!0,scope:{title:"@",contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/popover/popover-template.html",link:function(a,b){b.addClass("popover")}}}).directive("uibPopoverTemplate",["$uibTooltip",function(a){return a("uibPopoverTemplate","popover","click",{useContentExp:!0})}]).directive("uibPopoverHtmlPopup",function(){return{replace:!0,scope:{contentExp:"&",title:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover-html.html",link:function(a,b){b.addClass("popover")}}}).directive("uibPopoverHtml",["$uibTooltip",function(a){return a("uibPopoverHtml","popover","click",{useContentExp:!0})}]).directive("uibPopoverPopup",function(){return{replace:!0,scope:{title:"@",content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html",link:function(a,b){b.addClass("popover")}}}).directive("uibPopover",["$uibTooltip",function(a){return a("uibPopover","popover","click")}]),angular.module("ui.bootstrap.popover").value("$popoverSuppressWarning",!1).directive("popoverTemplatePopup",["$log","$popoverSuppressWarning",function(a,b){return{replace:!0,scope:{title:"@",contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/popover/popover-template.html",link:function(c,d){b||a.warn("popover-template-popup is now deprecated. Use uib-popover-template-popup instead."),d.addClass("popover")}}}]).directive("popoverTemplate",["$tooltip",function(a){return a("popoverTemplate","popover","click",{useContentExp:!0})}]).directive("popoverHtmlPopup",["$log","$popoverSuppressWarning",function(a,b){return{replace:!0,scope:{contentExp:"&",title:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover-html.html",link:function(c,d){b||a.warn("popover-html-popup is now deprecated. Use uib-popover-html-popup instead."),d.addClass("popover")}}}]).directive("popoverHtml",["$tooltip",function(a){return a("popoverHtml","popover","click",{useContentExp:!0})}]).directive("popoverPopup",["$log","$popoverSuppressWarning",function(a,b){return{replace:!0,scope:{title:"@",content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html",link:function(c,d){b||a.warn("popover-popup is now deprecated. Use uib-popover-popup instead."),d.addClass("popover")}}}]).directive("popover",["$tooltip",function(a){return a("popover","popover","click")}]),angular.module("ui.bootstrap.progressbar",[]).constant("uibProgressConfig",{animate:!0,max:100}).controller("UibProgressController",["$scope","$attrs","uibProgressConfig",function(a,b,c){var d=this,e=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.bars=[],a.max=angular.isDefined(a.max)?a.max:c.max,this.addBar=function(b,c,f){e||c.css({transition:"none"}),this.bars.push(b),b.max=a.max,b.title=f&&angular.isDefined(f.title)?f.title:"progressbar",b.$watch("value",function(a){b.recalculatePercentage()}),b.recalculatePercentage=function(){var a=d.bars.reduce(function(a,b){return b.percent=+(100*b.value/b.max).toFixed(2),a+b.percent},0);a>100&&(b.percent-=a-100)},b.$on("$destroy",function(){c=null,d.removeBar(b)})},this.removeBar=function(a){this.bars.splice(this.bars.indexOf(a),1),this.bars.forEach(function(a){a.recalculatePercentage()})},a.$watch("max",function(b){d.bars.forEach(function(b){b.max=a.max,b.recalculatePercentage()})})}]).directive("uibProgress",function(){return{replace:!0,transclude:!0,controller:"UibProgressController",require:"uibProgress",scope:{max:"=?"},templateUrl:"template/progressbar/progress.html"}}).directive("uibBar",function(){return{replace:!0,transclude:!0,require:"^uibProgress",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b,c)}}}).directive("uibProgressbar",function(){return{replace:!0,transclude:!0,controller:"UibProgressController",scope:{value:"=",max:"=?",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]),{title:c.title})}}}),angular.module("ui.bootstrap.progressbar").value("$progressSuppressWarning",!1).controller("ProgressController",["$scope","$attrs","uibProgressConfig","$log","$progressSuppressWarning",function(a,b,c,d,e){e||d.warn("ProgressController is now deprecated. Use UibProgressController instead.");var f=this,g=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.bars=[],a.max=angular.isDefined(a.max)?a.max:c.max,this.addBar=function(b,c,d){g||c.css({transition:"none"}),this.bars.push(b),b.max=a.max,b.title=d&&angular.isDefined(d.title)?d.title:"progressbar",b.$watch("value",function(a){b.recalculatePercentage()}),b.recalculatePercentage=function(){b.percent=+(100*b.value/b.max).toFixed(2);var a=f.bars.reduce(function(a,b){return a+b.percent},0);a>100&&(b.percent-=a-100)},b.$on("$destroy",function(){c=null,f.removeBar(b)})},this.removeBar=function(a){this.bars.splice(this.bars.indexOf(a),1)},a.$watch("max",function(b){f.bars.forEach(function(b){b.max=a.max,b.recalculatePercentage()})})}]).directive("progress",["$log","$progressSuppressWarning",function(a,b){return{replace:!0,transclude:!0,controller:"ProgressController",require:"progress",scope:{max:"=?",title:"@?"},templateUrl:"template/progressbar/progress.html",link:function(){b||a.warn("progress is now deprecated. Use uib-progress instead.")}}}]).directive("bar",["$log","$progressSuppressWarning",function(a,b){return{replace:!0,transclude:!0,require:"^progress",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(c,d,e,f){b||a.warn("bar is now deprecated. Use uib-bar instead."),f.addBar(c,d)}}}]).directive("progressbar",["$log","$progressSuppressWarning",function(a,b){return{replace:!0,transclude:!0,controller:"ProgressController",scope:{value:"=",max:"=?",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(c,d,e,f){b||a.warn("progressbar is now deprecated. Use uib-progressbar instead."),f.addBar(c,angular.element(d.children()[0]),{title:e.title})}}}]),angular.module("ui.bootstrap.rating",[]).constant("uibRatingConfig",{max:5,stateOn:null,stateOff:null,titles:["one","two","three","four","five"]}).controller("UibRatingController",["$scope","$attrs","uibRatingConfig",function(a,b,c){var d={$setViewValue:angular.noop};this.init=function(e){d=e,d.$render=this.render,d.$formatters.push(function(a){return angular.isNumber(a)&&a<<0!==a&&(a=Math.round(a)),a}),this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):c.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):c.stateOff;var f=angular.isDefined(b.titles)?a.$parent.$eval(b.titles):c.titles;this.titles=angular.isArray(f)&&f.length>0?f:c.titles;var g=angular.isDefined(b.ratingStates)?a.$parent.$eval(b.ratingStates):new Array(angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max);a.range=this.buildTemplateObjects(g)},this.buildTemplateObjects=function(a){for(var b=0,c=a.length;c>b;b++)a[b]=angular.extend({index:b},{stateOn:this.stateOn,stateOff:this.stateOff,title:this.getTitle(b)},a[b]);return a},this.getTitle=function(a){return a>=this.titles.length?a+1:this.titles[a]},a.rate=function(b){!a.readonly&&b>=0&&b<=a.range.length&&(d.$setViewValue(d.$viewValue===b?0:b),d.$render())},a.enter=function(b){a.readonly||(a.value=b),a.onHover({value:b})},a.reset=function(){a.value=d.$viewValue,a.onLeave()},a.onKeydown=function(b){/(37|38|39|40)/.test(b.which)&&(b.preventDefault(),b.stopPropagation(),a.rate(a.value+(38===b.which||39===b.which?1:-1)))},this.render=function(){a.value=d.$viewValue}}]).directive("uibRating",function(){return{require:["uibRating","ngModel"],scope:{readonly:"=?",onHover:"&",onLeave:"&"},controller:"UibRatingController",templateUrl:"template/rating/rating.html",replace:!0,link:function(a,b,c,d){var e=d[0],f=d[1];e.init(f)}}}),angular.module("ui.bootstrap.rating").value("$ratingSuppressWarning",!1).controller("RatingController",["$scope","$attrs","$controller","$log","$ratingSuppressWarning",function(a,b,c,d,e){e||d.warn("RatingController is now deprecated. Use UibRatingController instead."),angular.extend(this,c("UibRatingController",{$scope:a,$attrs:b}))}]).directive("rating",["$log","$ratingSuppressWarning",function(a,b){return{require:["rating","ngModel"],scope:{readonly:"=?",onHover:"&",onLeave:"&"},controller:"RatingController",templateUrl:"template/rating/rating.html",replace:!0,link:function(c,d,e,f){b||a.warn("rating is now deprecated. Use uib-rating instead.");var g=f[0],h=f[1];g.init(h)}}}]),angular.module("ui.bootstrap.tabs",[]).controller("UibTabsetController",["$scope",function(a){var b=this,c=b.tabs=a.tabs=[];b.select=function(a){angular.forEach(c,function(b){b.active&&b!==a&&(b.active=!1,b.onDeselect(),a.selectCalled=!1)}),a.active=!0,a.selectCalled||(a.onSelect(),a.selectCalled=!0)},b.addTab=function(a){c.push(a),1===c.length&&a.active!==!1?a.active=!0:a.active?b.select(a):a.active=!1},b.removeTab=function(a){var e=c.indexOf(a);if(a.active&&c.length>1&&!d){var f=e==c.length-1?e-1:e+1;b.select(c[f])}c.splice(e,1)};var d;a.$on("$destroy",function(){d=!0})}]).directive("uibTabset",function(){return{restrict:"EA",transclude:!0,replace:!0,scope:{type:"@"},controller:"UibTabsetController",templateUrl:"template/tabs/tabset.html",link:function(a,b,c){a.vertical=angular.isDefined(c.vertical)?a.$parent.$eval(c.vertical):!1,a.justified=angular.isDefined(c.justified)?a.$parent.$eval(c.justified):!1}}}).directive("uibTab",["$parse",function(a){return{require:"^uibTabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{active:"=?",heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},link:function(b,c,d,e,f){b.$watch("active",function(a){a&&e.select(b)}),b.disabled=!1,d.disable&&b.$parent.$watch(a(d.disable),function(a){b.disabled=!!a}),b.select=function(){b.disabled||(b.active=!0)},e.addTab(b),b.$on("$destroy",function(){e.removeTab(b)}),b.$transcludeFn=f}}}]).directive("uibTabHeadingTransclude",function(){return{restrict:"A",require:["?^uibTab","?^tab"],link:function(a,b){a.$watch("headingElement",function(a){a&&(b.html(""),b.append(a))})}}}).directive("uibTabContentTransclude",function(){function a(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||a.hasAttribute("x-tab-heading")||a.hasAttribute("uib-tab-heading")||a.hasAttribute("data-uib-tab-heading")||a.hasAttribute("x-uib-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase()||"x-tab-heading"===a.tagName.toLowerCase()||"uib-tab-heading"===a.tagName.toLowerCase()||"data-uib-tab-heading"===a.tagName.toLowerCase()||"x-uib-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:["?^uibTabset","?^tabset"],link:function(b,c,d){var e=b.$eval(d.uibTabContentTransclude);e.$transcludeFn(e.$parent,function(b){angular.forEach(b,function(b){a(b)?e.headingElement=b:c.append(b)})})}}}),angular.module("ui.bootstrap.tabs").value("$tabsSuppressWarning",!1).controller("TabsetController",["$scope","$controller","$log","$tabsSuppressWarning",function(a,b,c,d){d||c.warn("TabsetController is now deprecated. Use UibTabsetController instead."),angular.extend(this,b("UibTabsetController",{$scope:a}))}]).directive("tabset",["$log","$tabsSuppressWarning",function(a,b){return{restrict:"EA",transclude:!0,replace:!0,scope:{type:"@"},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(c,d,e){b||a.warn("tabset is now deprecated. Use uib-tabset instead."),c.vertical=angular.isDefined(e.vertical)?c.$parent.$eval(e.vertical):!1,c.justified=angular.isDefined(e.justified)?c.$parent.$eval(e.justified):!1}}}]).directive("tab",["$parse","$log","$tabsSuppressWarning",function(a,b,c){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{active:"=?",heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},link:function(d,e,f,g,h){c||b.warn("tab is now deprecated. Use uib-tab instead."),d.$watch("active",function(a){a&&g.select(d)}),d.disabled=!1,f.disable&&d.$parent.$watch(a(f.disable),function(a){d.disabled=!!a}),d.select=function(){d.disabled||(d.active=!0)},g.addTab(d),d.$on("$destroy",function(){g.removeTab(d)}),d.$transcludeFn=h}}}]).directive("tabHeadingTransclude",["$log","$tabsSuppressWarning",function(a,b){return{restrict:"A",require:"^tab",link:function(c,d){b||a.warn("tab-heading-transclude is now deprecated. Use uib-tab-heading-transclude instead."),c.$watch("headingElement",function(a){a&&(d.html(""),d.append(a))})}}}]).directive("tabContentTransclude",["$log","$tabsSuppressWarning",function(a,b){function c(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||a.hasAttribute("x-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase()||"x-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:"^tabset",link:function(d,e,f){b||a.warn("tab-content-transclude is now deprecated. Use uib-tab-content-transclude instead.");var g=d.$eval(f.tabContentTransclude);g.$transcludeFn(g.$parent,function(a){angular.forEach(a,function(a){c(a)?g.headingElement=a:e.append(a)})})}}}]),angular.module("ui.bootstrap.timepicker",[]).constant("uibTimepickerConfig",{hourStep:1,minuteStep:1,showMeridian:!0,meridians:null,readonlyInput:!1,mousewheel:!0,arrowkeys:!0,showSpinners:!0}).controller("UibTimepickerController",["$scope","$element","$attrs","$parse","$log","$locale","uibTimepickerConfig",function(a,b,c,d,e,f,g){function h(){var b=parseInt(a.hours,10),c=a.showMeridian?b>0&&13>b:b>=0&&24>b;return c?(a.showMeridian&&(12===b&&(b=0),a.meridian===r[1]&&(b+=12)),b):void 0}function i(){var b=parseInt(a.minutes,10);return b>=0&&60>b?b:void 0}function j(a){return angular.isDefined(a)&&a.toString().length<2?"0"+a:a.toString()}function k(a){l(),q.$setViewValue(new Date(p)),m(a)}function l(){q.$setValidity("time",!0),a.invalidHours=!1,a.invalidMinutes=!1}function m(b){var c=p.getHours(),d=p.getMinutes();a.showMeridian&&(c=0===c||12===c?12:c%12),a.hours="h"===b?c:j(c),"m"!==b&&(a.minutes=j(d)),a.meridian=p.getHours()<12?r[0]:r[1]}function n(a,b){var c=new Date(a.getTime()+6e4*b),d=new Date(a);return d.setHours(c.getHours(),c.getMinutes()),d}function o(a){p=n(p,a),k()}var p=new Date,q={$setViewValue:angular.noop},r=angular.isDefined(c.meridians)?a.$parent.$eval(c.meridians):g.meridians||f.DATETIME_FORMATS.AMPMS;a.tabindex=angular.isDefined(c.tabindex)?c.tabindex:0,b.removeAttr("tabindex"),this.init=function(b,d){q=b,q.$render=this.render,q.$formatters.unshift(function(a){return a?new Date(a):null});var e=d.eq(0),f=d.eq(1),h=angular.isDefined(c.mousewheel)?a.$parent.$eval(c.mousewheel):g.mousewheel;h&&this.setupMousewheelEvents(e,f);var i=angular.isDefined(c.arrowkeys)?a.$parent.$eval(c.arrowkeys):g.arrowkeys;i&&this.setupArrowkeyEvents(e,f),a.readonlyInput=angular.isDefined(c.readonlyInput)?a.$parent.$eval(c.readonlyInput):g.readonlyInput,this.setupInputEvents(e,f)};var s=g.hourStep;c.hourStep&&a.$parent.$watch(d(c.hourStep),function(a){s=parseInt(a,10)});var t=g.minuteStep;c.minuteStep&&a.$parent.$watch(d(c.minuteStep),function(a){t=parseInt(a,10)});var u;a.$parent.$watch(d(c.min),function(a){var b=new Date(a);u=isNaN(b)?void 0:b});var v;a.$parent.$watch(d(c.max),function(a){var b=new Date(a);v=isNaN(b)?void 0:b}),a.noIncrementHours=function(){var a=n(p,60*s);
return a>v||p>a&&u>a},a.noDecrementHours=function(){var a=n(p,60*-s);return u>a||a>p&&a>v},a.noIncrementMinutes=function(){var a=n(p,t);return a>v||p>a&&u>a},a.noDecrementMinutes=function(){var a=n(p,-t);return u>a||a>p&&a>v},a.noToggleMeridian=function(){return p.getHours()<13?n(p,720)>v:n(p,-720)<u},a.showMeridian=g.showMeridian,c.showMeridian&&a.$parent.$watch(d(c.showMeridian),function(b){if(a.showMeridian=!!b,q.$error.time){var c=h(),d=i();angular.isDefined(c)&&angular.isDefined(d)&&(p.setHours(c),k())}else m()}),this.setupMousewheelEvents=function(b,c){var d=function(a){a.originalEvent&&(a=a.originalEvent);var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0};b.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementHours():a.decrementHours()),b.preventDefault()}),c.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementMinutes():a.decrementMinutes()),b.preventDefault()})},this.setupArrowkeyEvents=function(b,c){b.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementHours(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementHours(),a.$apply())}),c.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementMinutes(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementMinutes(),a.$apply())})},this.setupInputEvents=function(b,c){if(a.readonlyInput)return a.updateHours=angular.noop,void(a.updateMinutes=angular.noop);var d=function(b,c){q.$setViewValue(null),q.$setValidity("time",!1),angular.isDefined(b)&&(a.invalidHours=b),angular.isDefined(c)&&(a.invalidMinutes=c)};a.updateHours=function(){var a=h(),b=i();angular.isDefined(a)&&angular.isDefined(b)?(p.setHours(a),u>p||p>v?d(!0):k("h")):d(!0)},b.bind("blur",function(b){!a.invalidHours&&a.hours<10&&a.$apply(function(){a.hours=j(a.hours)})}),a.updateMinutes=function(){var a=i(),b=h();angular.isDefined(a)&&angular.isDefined(b)?(p.setMinutes(a),u>p||p>v?d(void 0,!0):k("m")):d(void 0,!0)},c.bind("blur",function(b){!a.invalidMinutes&&a.minutes<10&&a.$apply(function(){a.minutes=j(a.minutes)})})},this.render=function(){var b=q.$viewValue;isNaN(b)?(q.$setValidity("time",!1),e.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):(b&&(p=b),u>p||p>v?(q.$setValidity("time",!1),a.invalidHours=!0,a.invalidMinutes=!0):l(),m())},a.showSpinners=angular.isDefined(c.showSpinners)?a.$parent.$eval(c.showSpinners):g.showSpinners,a.incrementHours=function(){a.noIncrementHours()||o(60*s)},a.decrementHours=function(){a.noDecrementHours()||o(60*-s)},a.incrementMinutes=function(){a.noIncrementMinutes()||o(t)},a.decrementMinutes=function(){a.noDecrementMinutes()||o(-t)},a.toggleMeridian=function(){a.noToggleMeridian()||o(720*(p.getHours()<12?1:-1))}}]).directive("uibTimepicker",function(){return{restrict:"EA",require:["uibTimepicker","?^ngModel"],controller:"UibTimepickerController",controllerAs:"timepicker",replace:!0,scope:{},templateUrl:function(a,b){return b.templateUrl||"template/timepicker/timepicker.html"},link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f,b.find("input"))}}}),angular.module("ui.bootstrap.timepicker").value("$timepickerSuppressWarning",!1).controller("TimepickerController",["$scope","$element","$attrs","$controller","$log","$timepickerSuppressWarning",function(a,b,c,d,e,f){f||e.warn("TimepickerController is now deprecated. Use UibTimepickerController instead."),angular.extend(this,d("UibTimepickerController",{$scope:a,$element:b,$attrs:c}))}]).directive("timepicker",["$log","$timepickerSuppressWarning",function(a,b){return{restrict:"EA",require:["timepicker","?^ngModel"],controller:"TimepickerController",controllerAs:"timepicker",replace:!0,scope:{},templateUrl:function(a,b){return b.templateUrl||"template/timepicker/timepicker.html"},link:function(c,d,e,f){b||a.warn("timepicker is now deprecated. Use uib-timepicker instead.");var g=f[0],h=f[1];h&&g.init(h,d.find("input"))}}}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position"]).factory("uibTypeaheadParser",["$parse",function(a){var b=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error('Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_" but got "'+c+'".');return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).controller("UibTypeaheadController",["$scope","$element","$attrs","$compile","$parse","$q","$timeout","$document","$window","$rootScope","$uibPosition","uibTypeaheadParser",function(a,b,c,d,e,f,g,h,i,j,k,l){function m(){K.moveInProgress||(K.moveInProgress=!0,K.$digest()),S&&g.cancel(S),S=g(function(){K.matches.length&&n(),K.moveInProgress=!1},r)}function n(){K.position=C?k.offset(b):k.position(b),K.position.top+=b.prop("offsetHeight")}var o,p,q=[9,13,27,38,40],r=200,s=a.$eval(c.typeaheadMinLength);s||0===s||(s=1);var t,u,v=a.$eval(c.typeaheadWaitMs)||0,w=a.$eval(c.typeaheadEditable)!==!1,x=e(c.typeaheadLoading).assign||angular.noop,y=e(c.typeaheadOnSelect),z=angular.isDefined(c.typeaheadSelectOnBlur)?a.$eval(c.typeaheadSelectOnBlur):!1,A=e(c.typeaheadNoResults).assign||angular.noop,B=c.typeaheadInputFormatter?e(c.typeaheadInputFormatter):void 0,C=c.typeaheadAppendToBody?a.$eval(c.typeaheadAppendToBody):!1,D=c.typeaheadAppendToElementId||!1,E=a.$eval(c.typeaheadFocusFirst)!==!1,F=c.typeaheadSelectOnExact?a.$eval(c.typeaheadSelectOnExact):!1,G=e(c.ngModel),H=e(c.ngModel+"($$$p)"),I=function(b,c){return angular.isFunction(G(a))&&p&&p.$options&&p.$options.getterSetter?H(b,{$$$p:c}):G.assign(b,c)},J=l.parse(c.uibTypeahead),K=a.$new(),L=a.$on("$destroy",function(){K.$destroy()});K.$on("$destroy",L);var M="typeahead-"+K.$id+"-"+Math.floor(1e4*Math.random());b.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":M});var N=angular.element("<div uib-typeahead-popup></div>");N.attr({id:M,matches:"matches",active:"activeIdx",select:"select(activeIdx)","move-in-progress":"moveInProgress",query:"query",position:"position"}),angular.isDefined(c.typeaheadTemplateUrl)&&N.attr("template-url",c.typeaheadTemplateUrl),angular.isDefined(c.typeaheadPopupTemplateUrl)&&N.attr("popup-template-url",c.typeaheadPopupTemplateUrl);var O=function(){K.matches=[],K.activeIdx=-1,b.attr("aria-expanded",!1)},P=function(a){return M+"-option-"+a};K.$watch("activeIdx",function(a){0>a?b.removeAttr("aria-activedescendant"):b.attr("aria-activedescendant",P(a))});var Q=function(a,b){return K.matches.length>b&&a?a.toUpperCase()===K.matches[b].label.toUpperCase():!1},R=function(c){var d={$viewValue:c};x(a,!0),A(a,!1),f.when(J.source(a,d)).then(function(e){var f=c===o.$viewValue;if(f&&t)if(e&&e.length>0){K.activeIdx=E?0:-1,A(a,!1),K.matches.length=0;for(var g=0;g<e.length;g++)d[J.itemName]=e[g],K.matches.push({id:P(g),label:J.viewMapper(K,d),model:e[g]});K.query=c,n(),b.attr("aria-expanded",!0),F&&1===K.matches.length&&Q(c,0)&&K.select(0)}else O(),A(a,!0);f&&x(a,!1)},function(){O(),x(a,!1),A(a,!0)})};C&&(angular.element(i).bind("resize",m),h.find("body").bind("scroll",m));var S;K.moveInProgress=!1,K.query=void 0;var T,U=function(a){T=g(function(){R(a)},v)},V=function(){T&&g.cancel(T)};O(),K.select=function(d){var e,f,h={};u=!0,h[J.itemName]=f=K.matches[d].model,e=J.modelMapper(a,h),I(a,e),o.$setValidity("editable",!0),o.$setValidity("parse",!0),y(a,{$item:f,$model:e,$label:J.viewMapper(a,h)}),O(),K.$eval(c.typeaheadFocusOnSelect)!==!1&&g(function(){b[0].focus()},0,!1)},b.bind("keydown",function(a){if(0!==K.matches.length&&-1!==q.indexOf(a.which)){if(-1===K.activeIdx&&(9===a.which||13===a.which))return O(),void K.$digest();a.preventDefault(),40===a.which?(K.activeIdx=(K.activeIdx+1)%K.matches.length,K.$digest()):38===a.which?(K.activeIdx=(K.activeIdx>0?K.activeIdx:K.matches.length)-1,K.$digest()):13===a.which||9===a.which?K.$apply(function(){K.select(K.activeIdx)}):27===a.which&&(a.stopPropagation(),O(),K.$digest())}}),b.bind("blur",function(){z&&K.matches.length&&-1!==K.activeIdx&&!u&&(u=!0,K.$apply(function(){K.select(K.activeIdx)})),t=!1,u=!1});var W=function(a){b[0]!==a.target&&3!==a.which&&0!==K.matches.length&&(O(),j.$$phase||K.$digest())};h.bind("click",W),a.$on("$destroy",function(){h.unbind("click",W),(C||D)&&X.remove(),C&&(angular.element(i).unbind("resize",m),h.find("body").unbind("scroll",m)),N.remove()});var X=d(N)(K);C?h.find("body").append(X):D!==!1?angular.element(h[0].getElementById(D)).append(X):b.after(X),this.init=function(b,c){o=b,p=c,o.$parsers.unshift(function(b){return t=!0,0===s||b&&b.length>=s?v>0?(V(),U(b)):R(b):(x(a,!1),V(),O()),w?b:b?void o.$setValidity("editable",!1):(o.$setValidity("editable",!0),null)}),o.$formatters.push(function(b){var c,d,e={};return w||o.$setValidity("editable",!0),B?(e.$model=b,B(a,e)):(e[J.itemName]=b,c=J.viewMapper(a,e),e[J.itemName]=void 0,d=J.viewMapper(a,e),c!==d?c:b)})}}]).directive("uibTypeahead",function(){return{controller:"UibTypeaheadController",require:["ngModel","^?ngModelOptions","uibTypeahead"],link:function(a,b,c,d){d[2].init(d[0],d[1])}}}).directive("uibTypeaheadPopup",function(){return{scope:{matches:"=",query:"=",active:"=",position:"&",moveInProgress:"=",select:"&"},replace:!0,templateUrl:function(a,b){return b.popupTemplateUrl||"template/typeahead/typeahead-popup.html"},link:function(a,b,c){a.templateUrl=c.templateUrl,a.isOpen=function(){return a.matches.length>0},a.isActive=function(b){return a.active==b},a.selectActive=function(b){a.active=b},a.selectMatch=function(b){a.select({activeIdx:b})}}}}).directive("uibTypeaheadMatch",["$templateRequest","$compile","$parse",function(a,b,c){return{scope:{index:"=",match:"=",query:"="},link:function(d,e,f){var g=c(f.templateUrl)(d.$parent)||"template/typeahead/typeahead-match.html";a(g).then(function(a){b(a.trim())(d,function(a){e.replaceWith(a)})})}}}]).filter("uibTypeaheadHighlight",["$sce","$injector","$log",function(a,b,c){function d(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function e(a){return/<.*>/g.test(a)}var f;return f=b.has("$sanitize"),function(b,g){return!f&&e(b)&&c.warn("Unsafe use of typeahead please use ngSanitize"),b=g?(""+b).replace(new RegExp(d(g),"gi"),"<strong>$&</strong>"):b,f||(b=a.trustAsHtml(b)),b}}]),angular.module("ui.bootstrap.typeahead").value("$typeaheadSuppressWarning",!1).service("typeaheadParser",["$parse","uibTypeaheadParser","$log","$typeaheadSuppressWarning",function(a,b,c,d){return d||c.warn("typeaheadParser is now deprecated. Use uibTypeaheadParser instead."),b}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$window","$rootScope","$uibPosition","typeaheadParser","$log","$typeaheadSuppressWarning",function(a,b,c,d,e,f,g,h,i,j,k){var l=[9,13,27,38,40],m=200;return{require:["ngModel","^?ngModelOptions"],link:function(n,o,p,q){function r(){N.moveInProgress||(N.moveInProgress=!0,N.$digest()),V&&d.cancel(V),V=d(function(){N.matches.length&&s(),N.moveInProgress=!1},m)}function s(){N.position=F?h.offset(o):h.position(o),N.position.top+=o.prop("offsetHeight")}k||j.warn("typeahead is now deprecated. Use uib-typeahead instead.");var t=q[0],u=q[1],v=n.$eval(p.typeaheadMinLength);v||0===v||(v=1);var w,x,y=n.$eval(p.typeaheadWaitMs)||0,z=n.$eval(p.typeaheadEditable)!==!1,A=b(p.typeaheadLoading).assign||angular.noop,B=b(p.typeaheadOnSelect),C=angular.isDefined(p.typeaheadSelectOnBlur)?n.$eval(p.typeaheadSelectOnBlur):!1,D=b(p.typeaheadNoResults).assign||angular.noop,E=p.typeaheadInputFormatter?b(p.typeaheadInputFormatter):void 0,F=p.typeaheadAppendToBody?n.$eval(p.typeaheadAppendToBody):!1,G=p.typeaheadAppendToElementId||!1,H=n.$eval(p.typeaheadFocusFirst)!==!1,I=p.typeaheadSelectOnExact?n.$eval(p.typeaheadSelectOnExact):!1,J=b(p.ngModel),K=b(p.ngModel+"($$$p)"),L=function(a,b){return angular.isFunction(J(n))&&u&&u.$options&&u.$options.getterSetter?K(a,{$$$p:b}):J.assign(a,b)},M=i.parse(p.typeahead),N=n.$new(),O=n.$on("$destroy",function(){N.$destroy()});N.$on("$destroy",O);var P="typeahead-"+N.$id+"-"+Math.floor(1e4*Math.random());o.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":P});var Q=angular.element("<div typeahead-popup></div>");Q.attr({id:P,matches:"matches",active:"activeIdx",select:"select(activeIdx)","move-in-progress":"moveInProgress",query:"query",position:"position"}),angular.isDefined(p.typeaheadTemplateUrl)&&Q.attr("template-url",p.typeaheadTemplateUrl),angular.isDefined(p.typeaheadPopupTemplateUrl)&&Q.attr("popup-template-url",p.typeaheadPopupTemplateUrl);var R=function(){N.matches=[],N.activeIdx=-1,o.attr("aria-expanded",!1)},S=function(a){return P+"-option-"+a};N.$watch("activeIdx",function(a){0>a?o.removeAttr("aria-activedescendant"):o.attr("aria-activedescendant",S(a))});var T=function(a,b){return N.matches.length>b&&a?a.toUpperCase()===N.matches[b].label.toUpperCase():!1},U=function(a){var b={$viewValue:a};A(n,!0),D(n,!1),c.when(M.source(n,b)).then(function(c){var d=a===t.$viewValue;if(d&&w)if(c&&c.length>0){N.activeIdx=H?0:-1,D(n,!1),N.matches.length=0;for(var e=0;e<c.length;e++)b[M.itemName]=c[e],N.matches.push({id:S(e),label:M.viewMapper(N,b),model:c[e]});N.query=a,s(),o.attr("aria-expanded",!0),I&&1===N.matches.length&&T(a,0)&&N.select(0)}else R(),D(n,!0);d&&A(n,!1)},function(){R(),A(n,!1),D(n,!0)})};F&&(angular.element(f).bind("resize",r),e.find("body").bind("scroll",r));var V;N.moveInProgress=!1,R(),N.query=void 0;var W,X=function(a){W=d(function(){U(a)},y)},Y=function(){W&&d.cancel(W)};t.$parsers.unshift(function(a){return w=!0,0===v||a&&a.length>=v?y>0?(Y(),X(a)):U(a):(A(n,!1),Y(),R()),z?a:a?void t.$setValidity("editable",!1):(t.$setValidity("editable",!0),null)}),t.$formatters.push(function(a){var b,c,d={};return z||t.$setValidity("editable",!0),E?(d.$model=a,E(n,d)):(d[M.itemName]=a,b=M.viewMapper(n,d),d[M.itemName]=void 0,c=M.viewMapper(n,d),b!==c?b:a)}),N.select=function(a){var b,c,e={};x=!0,e[M.itemName]=c=N.matches[a].model,b=M.modelMapper(n,e),L(n,b),t.$setValidity("editable",!0),t.$setValidity("parse",!0),B(n,{$item:c,$model:b,$label:M.viewMapper(n,e)}),R(),N.$eval(p.typeaheadFocusOnSelect)!==!1&&d(function(){o[0].focus()},0,!1)},o.bind("keydown",function(a){if(0!==N.matches.length&&-1!==l.indexOf(a.which)){if(-1===N.activeIdx&&(9===a.which||13===a.which))return R(),void N.$digest();a.preventDefault(),40===a.which?(N.activeIdx=(N.activeIdx+1)%N.matches.length,N.$digest()):38===a.which?(N.activeIdx=(N.activeIdx>0?N.activeIdx:N.matches.length)-1,N.$digest()):13===a.which||9===a.which?N.$apply(function(){N.select(N.activeIdx)}):27===a.which&&(a.stopPropagation(),R(),N.$digest())}}),o.bind("blur",function(){C&&N.matches.length&&-1!==N.activeIdx&&!x&&(x=!0,N.$apply(function(){N.select(N.activeIdx)})),w=!1,x=!1});var Z=function(a){o[0]!==a.target&&3!==a.which&&0!==N.matches.length&&(R(),g.$$phase||N.$digest())};e.bind("click",Z),n.$on("$destroy",function(){e.unbind("click",Z),(F||G)&&$.remove(),F&&(angular.element(f).unbind("resize",r),e.find("body").unbind("scroll",r)),Q.remove()});var $=a(Q)(N);F?e.find("body").append($):G!==!1?angular.element(e[0].getElementById(G)).append($):o.after($)}}}]).directive("typeaheadPopup",["$typeaheadSuppressWarning","$log",function(a,b){return{scope:{matches:"=",query:"=",active:"=",position:"&",moveInProgress:"=",select:"&"},replace:!0,templateUrl:function(a,b){return b.popupTemplateUrl||"template/typeahead/typeahead-popup.html"},link:function(c,d,e){a||b.warn("typeahead-popup is now deprecated. Use uib-typeahead-popup instead."),c.templateUrl=e.templateUrl,c.isOpen=function(){return c.matches.length>0},c.isActive=function(a){return c.active==a},c.selectActive=function(a){c.active=a},c.selectMatch=function(a){c.select({activeIdx:a})}}}}]).directive("typeaheadMatch",["$templateRequest","$compile","$parse","$typeaheadSuppressWarning","$log",function(a,b,c,d,e){return{restrict:"EA",scope:{index:"=",match:"=",query:"="},link:function(f,g,h){d||e.warn("typeahead-match is now deprecated. Use uib-typeahead-match instead.");var i=c(h.templateUrl)(f.$parent)||"template/typeahead/typeahead-match.html";a(i).then(function(a){b(a.trim())(f,function(a){g.replaceWith(a)})})}}}]).filter("typeaheadHighlight",["$sce","$injector","$log","$typeaheadSuppressWarning",function(a,b,c,d){function e(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}function f(a){return/<.*>/g.test(a)}var g;return g=b.has("$sanitize"),function(b,h){return d||c.warn("typeaheadHighlight is now deprecated. Use uibTypeaheadHighlight instead."),!g&&f(b)&&c.warn("Unsafe use of typeahead please use ngSanitize"),b=h?(""+b).replace(new RegExp(e(h),"gi"),"<strong>$&</strong>"):b,g||(b=a.trustAsHtml(b)),b}}]),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion-group.html",'<div class="panel {{panelClass || \'panel-default\'}}">\n  <div class="panel-heading" ng-keypress="toggleOpen($event)">\n    <h4 class="panel-title">\n      <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span ng-class="{\'text-muted\': isDisabled}">{{heading}}</span></a>\n    </h4>\n  </div>\n  <div class="panel-collapse collapse" uib-collapse="!isOpen">\n	  <div class="panel-body" ng-transclude></div>\n  </div>\n</div>\n')}]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion.html",'<div class="panel-group" ng-transclude></div>')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(a){a.put("template/alert/alert.html",'<div class="alert" ng-class="[\'alert-\' + (type || \'warning\'), closeable ? \'alert-dismissible\' : null]" role="alert">\n    <button ng-show="closeable" type="button" class="close" ng-click="close({$event: $event})">\n        <span aria-hidden="true">&times;</span>\n        <span class="sr-only">Close</span>\n    </button>\n    <div ng-transclude></div>\n</div>\n')}]),angular.module("template/carousel/carousel.html",[]).run(["$templateCache",function(a){a.put("template/carousel/carousel.html",'<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel" ng-swipe-right="prev()" ng-swipe-left="next()">\n  <div class="carousel-inner" ng-transclude></div>\n  <a role="button" href class="left carousel-control" ng-click="prev()" ng-show="slides.length > 1">\n    <span aria-hidden="true" class="glyphicon glyphicon-chevron-left"></span>\n    <span class="sr-only">previous</span>\n  </a>\n  <a role="button" href class="right carousel-control" ng-click="next()" ng-show="slides.length > 1">\n    <span aria-hidden="true" class="glyphicon glyphicon-chevron-right"></span>\n    <span class="sr-only">next</span>\n  </a>\n  <ol class="carousel-indicators" ng-show="slides.length > 1">\n    <li ng-repeat="slide in slides | orderBy:indexOfSlide track by $index" ng-class="{ active: isActive(slide) }" ng-click="select(slide)">\n      <span class="sr-only">slide {{ $index + 1 }} of {{ slides.length }}<span ng-if="isActive(slide)">, currently active</span></span>\n    </li>\n  </ol>\n</div>')}]),angular.module("template/carousel/slide.html",[]).run(["$templateCache",function(a){a.put("template/carousel/slide.html",'<div ng-class="{\n    \'active\': active\n  }" class="item text-center" ng-transclude></div>\n')}]),angular.module("template/datepicker/datepicker.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/datepicker.html",'<div ng-switch="datepickerMode" role="application" ng-keydown="keydown($event)">\n  <uib-daypicker ng-switch-when="day" tabindex="0"></uib-daypicker>\n  <uib-monthpicker ng-switch-when="month" tabindex="0"></uib-monthpicker>\n  <uib-yearpicker ng-switch-when="year" tabindex="0"></uib-yearpicker>\n</div>')}]),angular.module("template/datepicker/day.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/day.html",'<table role="grid" aria-labelledby="{{::uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n  <thead>\n    <tr>\n      <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n      <th colspan="{{::5 + showWeeks}}"><button id="{{::uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n      <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n    </tr>\n    <tr>\n      <th ng-if="showWeeks" class="text-center"></th>\n      <th ng-repeat="label in ::labels track by $index" class="text-center"><small aria-label="{{::label.full}}">{{::label.abbr}}</small></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr ng-repeat="row in rows track by $index">\n      <td ng-if="showWeeks" class="text-center h6"><em>{{ weekNumbers[$index] }}</em></td>\n      <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{::dt.uid}}" ng-class="::dt.customClass">\n        <button type="button" style="min-width:100%;" class="btn btn-default btn-sm" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="::{\'text-muted\': dt.secondary, \'text-info\': dt.current}">{{::dt.label}}</span></button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n')}]),angular.module("template/datepicker/month.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/month.html",'<table role="grid" aria-labelledby="{{::uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n  <thead>\n    <tr>\n      <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n      <th><button id="{{::uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n      <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr ng-repeat="row in rows track by $index">\n      <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{::dt.uid}}" ng-class="::dt.customClass">\n        <button type="button" style="min-width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="::{\'text-info\': dt.current}">{{::dt.label}}</span></button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n')}]),angular.module("template/datepicker/popup.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/popup.html",'<ul class="dropdown-menu" dropdown-nested ng-if="isOpen" style="display: block" ng-style="{top: position.top+\'px\', left: position.left+\'px\'}" ng-keydown="keydown($event)" ng-click="$event.stopPropagation()">\n	<li ng-transclude></li>\n	<li ng-if="showButtonBar" style="padding:10px 9px 2px">\n		<span class="btn-group pull-left">\n			<button type="button" class="btn btn-sm btn-info" ng-click="select(\'today\')" ng-disabled="isDisabled(\'today\')">{{ getText(\'current\') }}</button>\n			<button type="button" class="btn btn-sm btn-danger" ng-click="select(null)">{{ getText(\'clear\') }}</button>\n		</span>\n		<button type="button" class="btn btn-sm btn-success pull-right" ng-click="close()">{{ getText(\'close\') }}</button>\n	</li>\n</ul>\n')}]),angular.module("template/datepicker/year.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/year.html",'<table role="grid" aria-labelledby="{{::uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n  <thead>\n    <tr>\n      <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n      <th colspan="3"><button id="{{::uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n      <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr ng-repeat="row in rows track by $index">\n      <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{::dt.uid}}" ng-class="::dt.customClass">\n        <button type="button" style="min-width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="::{\'text-info\': dt.current}">{{::dt.label}}</span></button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n')}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'<div uib-modal-animation-class="fade"\n     modal-in-class="in"\n     ng-style="{\'z-index\': 1040 + (index && 1 || 0) + index*10}"\n></div>\n')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'<div modal-render="{{$isRendered}}" tabindex="-1" role="dialog" class="modal"\n    uib-modal-animation-class="fade"\n    modal-in-class="in"\n    ng-style="{\'z-index\': 1050 + index*10, display: \'block\'}">\n    <div class="modal-dialog" ng-class="size ? \'modal-\' + size : \'\'"><div class="modal-content" uib-modal-transclude></div></div>\n</div>\n')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pager.html",'<ul class="pager">\n  <li ng-class="{disabled: noPrevious()||ngDisabled, previous: align}"><a href ng-click="selectPage(page - 1, $event)">{{::getText(\'previous\')}}</a></li>\n  <li ng-class="{disabled: noNext()||ngDisabled, next: align}"><a href ng-click="selectPage(page + 1, $event)">{{::getText(\'next\')}}</a></li>\n</ul>\n')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pagination.html",'<ul class="pagination">\n  <li ng-if="::boundaryLinks" ng-class="{disabled: noPrevious()||ngDisabled}" class="pagination-first"><a href ng-click="selectPage(1, $event)">{{::getText(\'first\')}}</a></li>\n  <li ng-if="::directionLinks" ng-class="{disabled: noPrevious()||ngDisabled}" class="pagination-prev"><a href ng-click="selectPage(page - 1, $event)">{{::getText(\'previous\')}}</a></li>\n  <li ng-repeat="page in pages track by $index" ng-class="{active: page.active,disabled: ngDisabled&&!page.active}" class="pagination-page"><a href ng-click="selectPage(page.number, $event)">{{page.text}}</a></li>\n  <li ng-if="::directionLinks" ng-class="{disabled: noNext()||ngDisabled}" class="pagination-next"><a href ng-click="selectPage(page + 1, $event)">{{::getText(\'next\')}}</a></li>\n  <li ng-if="::boundaryLinks" ng-class="{disabled: noNext()||ngDisabled}" class="pagination-last"><a href ng-click="selectPage(totalPages, $event)">{{::getText(\'last\')}}</a></li>\n</ul>\n')}]),angular.module("template/tooltip/tooltip-html-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-popup.html",'<div\n  tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="tooltip-arrow"></div>\n  <div class="tooltip-inner" ng-bind-html="contentExp()"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-popup.html",'<div\n  tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="tooltip-arrow"></div>\n  <div class="tooltip-inner" ng-bind="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-template-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-template-popup.html",'<div\n  tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="tooltip-arrow"></div>\n  <div class="tooltip-inner"\n    uib-tooltip-template-transclude="contentExp()"\n    tooltip-template-transclude-scope="originScope()"></div>\n</div>\n')}]),angular.module("template/popover/popover-html.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover-html.html",'<div tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="arrow"></div>\n\n  <div class="popover-inner">\n      <h3 class="popover-title" ng-bind="title" ng-if="title"></h3>\n      <div class="popover-content" ng-bind-html="contentExp()"></div>\n  </div>\n</div>\n')}]),angular.module("template/popover/popover-template.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover-template.html",'<div tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="arrow"></div>\n\n  <div class="popover-inner">\n      <h3 class="popover-title" ng-bind="title" ng-if="title"></h3>\n      <div class="popover-content"\n        uib-tooltip-template-transclude="contentExp()"\n        tooltip-template-transclude-scope="originScope()"></div>\n  </div>\n</div>\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover.html",'<div tooltip-animation-class="fade"\n  uib-tooltip-classes\n  ng-class="{ in: isOpen() }">\n  <div class="arrow"></div>\n\n  <div class="popover-inner">\n      <h3 class="popover-title" ng-bind="title" ng-if="title"></h3>\n      <div class="popover-content" ng-bind="content"></div>\n  </div>\n</div>\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/bar.html",'<div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: (percent < 100 ? percent : 100) + \'%\'}" aria-valuetext="{{percent | number:0}}%" aria-labelledby="{{::title}}" style="min-width: 0;" ng-transclude></div>\n')}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progress.html",'<div class="progress" ng-transclude aria-labelledby="{{::title}}"></div>')}]),angular.module("template/progressbar/progressbar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progressbar.html",'<div class="progress">\n  <div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: (percent < 100 ? percent : 100) + \'%\'}" aria-valuetext="{{percent | number:0}}%" aria-labelledby="{{::title}}" style="min-width: 0;" ng-transclude></div>\n</div>\n')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(a){a.put("template/rating/rating.html",'<span ng-mouseleave="reset()" ng-keydown="onKeydown($event)" tabindex="0" role="slider" aria-valuemin="0" aria-valuemax="{{range.length}}" aria-valuenow="{{value}}">\n    <span ng-repeat-start="r in range track by $index" class="sr-only">({{ $index < value ? \'*\' : \' \' }})</span>\n    <i ng-repeat-end ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < value && (r.stateOn || \'glyphicon-star\') || (r.stateOff || \'glyphicon-star-empty\')" ng-attr-title="{{r.title}}" aria-valuetext="{{r.title}}"></i>\n</span>\n');
}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tab.html",'<li ng-class="{active: active, disabled: disabled}">\n  <a href ng-click="select()" uib-tab-heading-transclude>{{heading}}</a>\n</li>\n')}]),angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset.html",'<div>\n  <ul class="nav nav-{{type || \'tabs\'}}" ng-class="{\'nav-stacked\': vertical, \'nav-justified\': justified}" ng-transclude></ul>\n  <div class="tab-content">\n    <div class="tab-pane" \n         ng-repeat="tab in tabs" \n         ng-class="{active: tab.active}"\n         uib-tab-content-transclude="tab">\n    </div>\n  </div>\n</div>\n')}]),angular.module("template/timepicker/timepicker.html",[]).run(["$templateCache",function(a){a.put("template/timepicker/timepicker.html",'<table>\n  <tbody>\n    <tr class="text-center" ng-show="::showSpinners">\n      <td><a ng-click="incrementHours()" ng-class="{disabled: noIncrementHours()}" class="btn btn-link" ng-disabled="noIncrementHours()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n      <td>&nbsp;</td>\n      <td><a ng-click="incrementMinutes()" ng-class="{disabled: noIncrementMinutes()}" class="btn btn-link" ng-disabled="noIncrementMinutes()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n      <td ng-show="showMeridian"></td>\n    </tr>\n    <tr>\n      <td class="form-group" ng-class="{\'has-error\': invalidHours}">\n        <input style="width:50px;" type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2" tabindex="{{::tabindex}}">\n      </td>\n      <td>:</td>\n      <td class="form-group" ng-class="{\'has-error\': invalidMinutes}">\n        <input style="width:50px;" type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="::readonlyInput" maxlength="2" tabindex="{{::tabindex}}">\n      </td>\n      <td ng-show="showMeridian"><button type="button" ng-class="{disabled: noToggleMeridian()}" class="btn btn-default text-center" ng-click="toggleMeridian()" ng-disabled="noToggleMeridian()" tabindex="{{::tabindex}}">{{meridian}}</button></td>\n    </tr>\n    <tr class="text-center" ng-show="::showSpinners">\n      <td><a ng-click="decrementHours()" ng-class="{disabled: noDecrementHours()}" class="btn btn-link" ng-disabled="noDecrementHours()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n      <td>&nbsp;</td>\n      <td><a ng-click="decrementMinutes()" ng-class="{disabled: noDecrementMinutes()}" class="btn btn-link" ng-disabled="noDecrementMinutes()" tabindex="{{::tabindex}}"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n      <td ng-show="showMeridian"></td>\n    </tr>\n  </tbody>\n</table>\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'<a href tabindex="-1" ng-bind-html="match.label | uibTypeaheadHighlight:query"></a>\n')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html",'<ul class="dropdown-menu" ng-show="isOpen() && !moveInProgress" ng-style="{top: position().top+\'px\', left: position().left+\'px\'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">\n    <li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{::match.id}}">\n        <div uib-typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>\n    </li>\n</ul>\n')}]),!angular.$$csp()&&angular.element(document).find("head").prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');;
var common = angular.module('ngp.email-common', []).factory('ngp.email-common', ['$http', '$window', function($http, $window) {
  var service = {};

  service.getContacts = function ($scope, searchString) {
      if (!$scope.searchingForContacts) {
          $scope.searchingForContacts = true;
          $http({
              url: "/EmailMessage/GetContacts",
              method: "GET",
              params: { searchString: searchString }
          }).then(function successCallback(result) {
              $scope.searchingForContacts = false;
              $scope.contactsList = result.data;

          }, function failureCallback(result) {
              $scope.searchingForContacts = false;
              FeedBack.update(result.data);
          });
      }
  };

    service.getColor = function(index) {
        var colors = {
            0: 'blue',
            1: 'green',
            2: 'red',
            3: 'purple',
            4: 'orange',
            5: 'pink',
            6: 'yellow',
            7: 'teal',
            8: 'gray-dark',
            9: 'gray-light'
        };
        return colors[index];
    };

    service.getVariantChar = function(index) {
        var charCode = 65 + parseInt(index);
        var tabName = String.fromCharCode(parseInt(charCode));
        return tabName;
    };

    //function that will update an email name if the email name is unique.
    service.updateEmailName = function ($scope, event, email, validateEmailNameLink, updateEmailNameLink, cancelModal, failureCallback, successMessage, sessionKey, $window) {
        var updateEmailNameCallback = function () {
            $http({
                url: updateEmailNameLink,
                method: 'POST',
                dataType: 'json',
                data: {
                    'emailName': email.Name,
                    'emailMessageId': email.EmailMessageId,
                    'triggeredEmailId': email.TriggeredEmailTypeId ? email.Id : null
                }
            }).then(function successCallback() {
                FeedBack.update({
                    ResponseResultCode: 1, DisplayMessageType: Constants.MessageType.Success,
                    MessagesHeader: successMessage,
                    Messages: []
                });
                cancelModal();
            }, function failureCallback(result) {
                FeedBack.update(result.data);
            });
        };
        this.checkEmailNameIsUnique($scope, event, email, validateEmailNameLink, 'emailName', updateEmailNameCallback, failureCallback, sessionKey, $window);
    };

    //function that will update an email name if the email name is unique.
    service.updateEmailDetails = function ($scope, event, email, validateEmailNameLink, updateEmailNameLink, cancelModal, failureCallback, successMessage, sessionKey, $window) {
        var updateEmailNameCallback = function () {
            $http({
                url: updateEmailNameLink,
                method: 'POST',
                dataType: 'json',
                data: {
                    
                        'name': email.Name,
                        'askTypeId': email.AskTypeId,
                        'campaignId': email.CampaignId,
                        'emailMessageId': email.EmailMessageId
                }
            }).then(function successCallback() {
                FeedBack.update({
                    ResponseResultCode: 1, DisplayMessageType: Constants.MessageType.Success,
                    MessagesHeader: successMessage,
                    Messages:[]
                });
                cancelModal();
            }, function failureCallback(result) {
                FeedBack.update(result.data);
            });
        };
        if (email.Name == email.originalName) {
            updateEmailNameCallback();
        }
        else {
            this.checkEmailNameIsUnique($scope, event, email, validateEmailNameLink, 'emailName', updateEmailNameCallback, failureCallback, sessionKey, $window);
        }
    };


    service.checkEmailNameIsUnique = function ($scope, event, email, validationLink, parameterName, updateCallback, failureCallback, sessionKey, $window) {
        $scope.validationTriggered = true;
        var parameters = this.loadCacheBuster({ emailName: email.Name, emailMessageId: email.EmailMessageId, sessionKey : sessionKey });
        if (parameters[parameterName] && parameters[parameterName].trim()) {
            this.validateNameIsUnique($scope, $window, event, parameters, updateCallback, failureCallback, validationLink, parameterName);
        }
    };

    //function that will create an email if the email name is unique.
    service.createEmail = function ($scope, form, event, emailName, validateEmailNameLink, failureCallback, sessionKey, $window) {
        this.CreateUniqueItem($scope, form, event, this.loadCacheBuster({ emailName: emailName, sessionKey: sessionKey }), validateEmailNameLink, "emailName", null, failureCallback, $window);
    };

    //function that is used by create email and create email series
    service.CreateUniqueItem = function ($scope, form, event, parameters, validationLink, parameterName, createCallback, failureCallback, $window) {
        $scope.validationTriggered = true;
        if (form.$valid && parameters[parameterName] && parameters[parameterName].trim()) {
            this.validateNameIsUnique($scope, $window, event, parameters, createCallback, failureCallback, validationLink, parameterName);
        }
    };

    //attempts to use the url to validate that a name is unique.  If the return value is false (the name is considered a duplicate)
    //and the method will call a failure callback method (if applicable).
    service.validateNameIsUnique = function ($scope, $window, event, parameters, successCallback, failureCallback, validationLink, parameterName) {
        $scope.creating = true;
        $http({
            url: validationLink,
            method: 'GET',
            params: parameters
        }).then(function(result) {
            result = result.data;
            if (result === 'false') {
                // set and show the error message
                $scope.warningShow = 'show';
                $scope.duplicateMessageName = parameters[parameterName];
                $scope.creating = false;
            } else if (result === 'reload') {
                $window.location.reload();
            } else {
                $scope.creating = false;
                $scope.warningShow = 'hide';
                if (successCallback) {
                    successCallback();
                } else {
                    $(event.target).parents('form')[0].submit();
                }
            }
        }).catch(function(res) {
            $scope.creating = false;
            if (failureCallback) {
                failureCallback(res);
            }
        });
    };

    //function that will update an emails group name if the emails group name is unique.
    service.updateEmailGroupName = function ($scope, event, emailGroup, validateEmailGroupNameLink, updateEmailGroupNameLink, cancelModal, failureCallback, sessionKey, $window) {
        var updateEmailGroupNameCallback = function () {
            $http({
                url: updateEmailGroupNameLink,
                method: 'POST',
                dataType: 'json',
                data: {
                    'groupName': emailGroup.EmailMessageSendGroupName,
                    'emailGroupId': emailGroup.EmailMessageSendGroupId,
                }
            }).then(function successCallback() {
                cancelModal();
            }, function failureCallback(result) {
                FeedBack.update(result.data);
            });
        };
        this.checkEmailGroupNameIsUnique($scope, event, emailGroup, validateEmailGroupNameLink, 'groupName', updateEmailGroupNameCallback, failureCallback, sessionKey, $window);
    };

    service.checkEmailGroupNameIsUnique = function ($scope, event, emailGroup, validationLink, parameterName, updateCallback, failureCallback, sessionKey, $window) {
        $scope.validationTriggered = true;
        var parameters = this.loadCacheBuster({ groupName: emailGroup.EmailMessageSendGroupName, emailGroupId: emailGroup.EmailMessageSendGroupId, sessionKey: sessionKey });
        if (parameters[parameterName] && parameters[parameterName].trim()) {
            this.validateNameIsUnique($scope, $window, event, parameters, updateCallback, failureCallback, validationLink, parameterName);
        }
    };
    service.CreateEmailGroup = function ($scope, form, model, groupName, validateGroupNameLink, cancelModal, failureCallback, sessionKey, $window) {
        this.CreateUniqueItem($scope, form, model, this.loadCacheBuster({ groupName: groupName, sessionKey: sessionKey }), validateGroupNameLink, "groupName",
            function () {
                $http({
                    method: "POST",
                    url: "/emailgroup/create",
                    data: model
                }).then(function successCallback(result) {
                    var id = result.data.Data;
                    cancelModal();
                    window.location = "/emailgroup/update/" + id;
                }, function failureCallback(result) {
                    FeedBack.update(result.data);
                });
        }, failureCallback, $window);
    };

    service.saveEmailGroup = function($scope, form, event, groupDto, validateEmailGroupNameLink, $window) {
        this.CreateUniqueItem($scope, form, event, this.loadCacheBuster({ groupName: groupDto.EmailMessageSendGroupName }), validateEmailGroupNameLink, "groupName", null, null, $window);
    }

    service.saveEmailSeries = function($scope, form, event, seriesDto, validateEmailSeriesNameLink, $window) {
        this.CreateUniqueItem($scope, form, event, this.loadCacheBuster({ seriesName: seriesDto.Name }), validateEmailSeriesNameLink, "seriesName", null, null, $window);
    };

    //function that will create an email if the series name is unique.
    service.createEmailSeries = function ($scope, form, event, seriesDto, validateEmailSeriesNameLink, createEmailSeriesLink, $window) {
        var createEmailSeriesCallback = function() {
            $http({
                url: createEmailSeriesLink,
                method: "POST",
                dataType: 'json',
                data: seriesDto
            }).then(function successCallback(result) {
                var response = result.data;
                FeedBack.update(response);
                if (response.ResponseResultCode !== Constants.ResponseResultCode.Failure) {
                    $scope.Model.SeriesDto = response.Data;

                    //Reset state and open modal
                    $scope.creating = false;
                    $scope.validationTriggered = false;
                    $scope.updateCreationType('new');
                    $scope.openModal('createModal.html');
                }
            }, function failureCallback(result) {
                FeedBack.update(result.data);
                $scope.creating = false;
            });
        };
        this.CreateUniqueItem($scope, form, event, this.loadCacheBuster({ seriesName: seriesDto.Name, seriesGuid: seriesDto.EmailSeriesId }), validateEmailSeriesNameLink, "seriesName", createEmailSeriesCallback, function(res) {
            FeedBack.update(
                {
                    MessagesHeader: window.ngpvan.translations.Pages.removeHtmlFromSeriesName,
                    DisplayMessageType: Constants.MessageType.Error
                }, $window);
        });
    };

    //Method to update an email series status by posting to the controller.  
    //This is used for pausing, ending, and launching email seris
    service.updateEmailSeriesStatus = function ($scope, event, statusUrl) {
        $scope.statusChanging = true;
        $http({
            url: statusUrl,
            method: "POST",
            dataType: 'json'
        }).then(function successCallback(result) {            
            $scope.statusChanging = false;
            var response = result.data;
            if (response.ResponseResultCode !== Constants.ResponseResultCode.Failure) {
                $scope.Model.SeriesDto = response.Data;
            } else {
                FeedBack.update(response);
            }
        }, function failureCallback(result) {
            // Handle the unlikely case where result is not set
            if (!result) {
                result = {};
            }
            // In theory, this codepath should not be reached if permission info is in sync between the client and the server.  
            // Just in case, we pass the failure status back to the status handler.  Map the fields in the response to
            // the fields that are excpected by the Feedback.update proc.  This will generate a red/pink popup with the status text.
            FeedBack.update({
                ResponseResultCode: result.status || 403, // Set to 403 if status does not exist as an attribute of status
                MessagesHeader: result.statusText || 'forbidden', // Set to a default string.  Not i18n
                DisplayMessageType: Constants.MessageType.Error
            });
            $scope.statusChanging = false;
            FeedBack.update(result.data);
        });
    };

    service.sendPreview = function (previewLink, previewRecipientList, emailMessageId, vanId, $scope, $window, sendPlaintext) {
        if ($scope.select !== undefined) {
            $scope.select.select(undefined);
        }
        $http({
            url: previewLink,
            method: 'POST',
            dataType: 'json',
            data: {
                emailMessageId: emailMessageId,
                recipients: previewRecipientList,
                vanId: vanId,
                sendPlaintext: sendPlaintext
            }
        }).then(function successCallback(result) {
            FeedBack.update(result.data);
            if (result.ResponseResultCode === false) {
                //If the content is not found that means a user has probably switched tenants.  In this case we reload the page to force them
                //back to home index so that tenancy is updated.
                if (result.reloadPage) {
                    $window.location.reload();
                }
            }
        }, function failureCallback(result) {
            FeedBack.update(result.data);
        });
    };

    // Posts the data to the url, then
    // - On success, opens a new window using the url indicated by the response
    // - On failure, shows an alert
    service.openWindow = function (url, data, callbackOnSuccess, callbackOnFailure) {
        $http({
            url: url,
            method: 'POST',
            dataType: 'json',
            data: data
        }).then(function successCallback(result) {
            if (result.data.ResponseResultCode === 1) {
                if (callbackOnSuccess) {
                    callbackOnSuccess(result.data);
                }
                window.open(result.data.NewLocation, '_blank');
            } else if (result.data.ResponseResultCode === 0) {
                if (callbackOnFailure) {
                    callbackOnFailure(result.data);
                }
                FeedBack.update(result.data);
            }
        }, function failureCallback(result) {
            if (callbackOnFailure) {
                callbackOnFailure(result.data);
            }
            FeedBack.update(result.data);
        });
    };

    service.footerSubmit = function(form, footerSubmitLink, data, modal) {
        if (form.$valid) {
            $http({
                url: footerSubmitLink,
                method: 'POST',
                dataType: 'json',
                data: data
            }).then(function(result) {
                result = result.data;
                if (result.ResponseResultCode !== Constants.ResponseResultCode.Failure) {
                    var openedModal = modal.getTop();
                    modal.close(openedModal.key);
                } else {
                    FeedBack.update(result);
                }
            });
        }
    };

  //function to get data from a server-side controller to an angular grid
  service.fillGrid = function(url, dest, paged, params) {
    dest.isLoading = true;
    $http({
      url: url,
      method: "GET",
      params: this.loadCacheBuster(params)
    }).then(function (result) {
      result = result.data;
      dest.data = paged ? result.Data : result;
      dest.count = paged ? result.TotalRows : result.length;
      dest.unfilteredCount = paged ? result.UnfilteredTotalRows : result.length;
      dest.isLoading = false;

      if (paged) {
        dest.first = ((dest.currentPage - 1) * dest.pageSize) + 1;
        dest.last = dest.first + dest.data.length - 1;
      }
    });
  };

  service.grid = function(url, countUrl, paginated, selectionId) {
    var that = this;
    var obj = {};

    obj.selectedId = null;
    obj.currentPage = 1;
    obj.pageSize = 5;
    obj.maxSize = 5;
    obj.search = null;

    obj.selectItem = function(id) {
      if (selectionId !== undefined) {
        $(selectionId).val(id);
      }
      obj.selectedId = id;
    };

    obj.pageChanged = function() {
      obj.fillGrid();
    };
        
    obj.showPerPage = function(pageSize) {
      obj.pageSize = pageSize;
      that.fillGrid(url, obj, paginated, paginated ? { pageSize: obj.pageSize, nameFilter: obj.search  } : null);
    };

    obj.fillGrid = function () { return that.fillGrid(url, obj, paginated, paginated ? { pageNumber: obj.currentPage, pageSize: obj.pageSize, nameFilter: obj.search } : null); };

    obj.getCount = function() {
        obj.isLoading = true;
        $http({
            url: countUrl,
            method: 'GET'
        }).then(function (result) {
            obj.unfilteredCount = result.data;
            obj.isLoading = false;
        });
    }

    obj.numItemsFirst = function(pageSize) {
      var num1 = ((obj.currentPage - 1) * pageSize) + 1;
      return num1;
    };

    obj.numItemsLast = function(pageSize, sentEmails) {
      if (typeof sentEmails === "undefined" || typeof sentEmails.data === "undefined") return 0;
      return obj.numItemsFirst(pageSize) + sentEmails.data.length - 1;
    };

    return obj;
  };

  service.actionLink = function(grid, url, paramPlaceholder) {
    return function(id) {
      if (paramPlaceholder === undefined) {
        return url;
      }
      if (id === undefined) {
        if (grid.selectedId === undefined) {
          return url;
        }
        return url.replace(paramPlaceholder, grid.selectedId);
      }
      return url.replace(paramPlaceholder, id);
    };
  };

  service.getRecipients = function(url, method, params, $scope, callback) {
    $http({
      url: url,
      method: method,
      params: this.loadCacheBuster(params)
    }).then(function successCallback(result) {
        if (result.data.ResponseResultCode !== Constants.ResponseResultCode.Failure) {
            var data = result.data.Data;
            $scope.Active = data.ActiveCount;
            $scope.Unsubscribed = data.UnsubscribedCount;
            $scope.Duplicates = data.DuplicateCount;
            $scope.Excludes = data.ExcludeCount;
            $scope.Bounced = data.BouncedCount;
            $scope.DoNotEmail = data.DoNotEmailCount;
            typeof callback === 'function' && callback();
            $scope.areCountsLoading = false;
            $scope.countLoadFailed = false;
            FeedBack.reset();
            FeedBack.hide();
            //This else case represents a failure that we planned for in the c# code (generally a failed validation)
        } else {
            $scope.areCountsLoading = false;
            $scope.Active = "-";
            $scope.Unsubscribed = "-";
            $scope.Duplicates = "-";
            $scope.Excludes = "-";
            $scope.Bounced = "-";
            $scope.DoNotEmail = "-";
            $scope.countLoadFailed = true;
            FeedBack.update(result.data);
        }
        //This handles the case of a server error that was not part of our planned responses.
    }, function failureCallback(result) {
      $scope.Active = "-";
      $scope.Unsubscribed = "-";
      $scope.Duplicates = "-";
      $scope.Excludes = "-";
      $scope.Bounced = "-";
      $scope.DoNotEmail = "-";
      $scope.areCountsCurrent = false;
      $scope.areCountsLoading = false;
      $scope.countLoadFailed = true;
      FeedBack.showError(window.ngpvan.translations.Pages.unableToLoadRecipientCounts);

    });
  };

  service.loadCacheBuster = function(params) {
    if (params !== null) {
      params['ieCacheBuster'] = new Date().getTime();
      return params;
    }
    return { 'ieCacheBuster': new Date().getTime() };
  };

  service.navigateTo = function(url) {
    $window.location.href = url;
  };
  

  // For use in fetching AjaxResults
  // If the action is successful, navigates to the indicated page
  // Otherwise, calls the feedback function specified in options
  service.ajaxWithFeedback = function(options)
  {
    $http({
      url: options.url,
      method: 'POST',
      dataType: 'json',
      data: options.data
    }).then(function (result) {
      result = result.data;
        // ResponseResultCode.Success = 1
      if (result.NewLocation && result.ResponseResultCode === 1) {
          service.navigateTo(result.NewLocation);
      } else if (typeof(options.feedback) === "function") {
        options.feedback(result);
      }

    });
  };

  service.openModal = function(template, size, $scope, $uibModal) {
      var modalInstance = $uibModal.open({
          scope: $scope,
          controller: "modalControl",
          templateUrl: template,
          backdrop: 'static',
          keyboard: true,
          size: size
      });
      return modalInstance;
  };

  service.addSegmentIfMissing = function(segmentCollection, resultData, segmentId, segmentType, name, description) {
      if (!(segmentCollection.contains(function(i) { return i.segmentId === segmentId; }))) {
          var segmentObject = {
              segmentId: segmentId,
              segmentType: segmentType,
              name: name,
              description: description
          };
          resultData.push(segmentObject);
          segmentCollection.push(segmentObject);
      }
  };

  service.DisplayStatus = {
        'Draft': 0,
        'Pending': 1,
        'Sent': 2,
        'Failed': 3
  };

  service.EmailMessageStatusId = {
      'Draft': 0,
      'Scheduled': 1,
      'Sending': 2,
      'PendingSelectWinner': 4,
      'Withdrawn': 5,
      'Sent': 6,
      'Series': 7
  };

  service.getReusableUsage = function ($scope, id, clientCallback) {
      if (!$scope.gettingReusableUsage) {
          $scope.gettingReusableUsage = true;

          $http({
              url: "/Reusable/GetReusableContentUsage",
              params: { id: id },
              method: "GET"
          }).then(function successCallback(result) {
              $scope.gettingReusableUsage = false;

              if (clientCallback !== null) {
                  clientCallback(result.data);
              }

          }, function failureCallback(result) {
              $scope.gettingReusableUsage = false;
              FeedBack.update(result.data);
          });
      }
  };

    service.getThemeUsage = function ($scope, id, clientCallback) {
        if (!$scope.gettingThemeUsage) {
            $scope.gettingThemeUsage = true;

            $http({
                url: "/Themes/GetThemeUsage",
                params: { id: id },
                method: "GET"
            }).then(function successCallback(result) {
                $scope.gettingThemeUsage = false;

                if (clientCallback !== null) {
                    clientCallback(result.data);
                }

            }, function failureCallback(result) {
                $scope.gettingThemeUsage = false;
                FeedBack.update(result.data);
            });
        }
    };

    service.getFormsThemeUsage = function ($scope, id, clientSuccessCallback, clientFailureCallback) {
        if (!$scope.gettingThemeUsage) {
            $scope.gettingThemeUsage = true;

            $http({
                url: "/Themes/GetFormsThemeUsage",
                params: { id: id },
                method: "GET"
            }).then(function successCallback(result) {
                $scope.gettingThemeUsage = false;

                if (clientSuccessCallback !== null) {
                    clientSuccessCallback(result.data);
                }

            }, function failureCallback() {
                $scope.gettingThemeUsage = false;
                if (clientFailureCallback !== null) {
                    clientFailureCallback();
                }
            });
        }
    };

    // Sort function for ng-repeat that sorts templates in case insensitive manner
    service.templateSortFormat = function (template) {
        // This will throw if the Title is not set
        return template.Title.toLowerCase();
    };

    service.themeSortFormat = function(theme) {
        return -Date.parse(theme.ModifiedOn);
    };

  // Sorts by template title.  Not currently being used.  
  // Can be used with array/list of template objects
  service.templateSortFunction = function (a, b) {
      if (templateSortFormat(a) < templateSortFormat(b))
          return -1;
      if (templateSortFormat(a) > templateSortFormat(b))
          return 1;

      return 0;
  };

  service.getReusables = function ($scope, clientCallback, reusableStatuses, isLightWeightFetch) {
      if (!$scope.gettingReusables) {
          $scope.gettingReusables = true;

          var lightweight = typeof isLightWeightFetch !== 'undefined' && isLightWeightFetch ? true : false;
          $http({
              url: "/Reusable/List",
              params: { statuses: reusableStatuses, lightweight: isLightWeightFetch },
              method: "GET"
          }).then(function successCallback(result) {
              $scope.gettingReusables = false;

              if (clientCallback !== null) {
                  clientCallback(result.data);
              }

          }, function failureCallback(result) {
              $scope.gettingReusables = false;
              FeedBack.update(result.data);
          });
      }
  };

    service.getThemes = function ($scope, clientCallback, reusableStatuses, isLightWeightFetch) {
        if (!$scope.gettingThemes) {
            $scope.gettingThemes = true;

            var lightweight = typeof isLightWeightFetch !== 'undefined' && isLightWeightFetch ? true : false;
            $http({
                url: "/Themes/List",
                params: { statuses: reusableStatuses, lightweight: isLightWeightFetch },
                method: "GET"
            }).then(function successCallback(result) {
                $scope.gettingThemes = false;

                if (clientCallback !== null) {
                    clientCallback(result.data);
                }

            }, function failureCallback(result) {
                $scope.gettingThemes = false;
                FeedBack.update(result.data);
            });
        }
    };


    service.getTemplates = function ($scope, clientCallback, reusableStatuses, isLightWeightFetch) {
        if (!$scope.gettingTemplates) {
            $scope.gettingTemplates = true;

            var lightweight = typeof isLightWeightFetch !== 'undefined' && isLightWeightFetch ? true : false;
            $http({
                url: "/Template/List",
                params: { statuses: reusableStatuses, lightweight: isLightWeightFetch },
                method: "GET"
            }).then(function successCallback(result) {
                $scope.gettingTemplates = false;

                if (clientCallback !== null) {
                    clientCallback(result.data);
                }

            }, function failureCallback(result) {
                $scope.gettingTemplates = false;
                FeedBack.update(result.data);
            });
        }
    };
  service.buildCommitteeList = function(templateList) {
        // Be safe with old browsers, and use a dict to generate a unique list of 
        // committee names based on the templates in the passed in template list
        // Eventually, this function may call into VAN or TGE to get actual visible committee
        // names.
        var tenantDict = {};
        templateList.forEach(function(item) { 
            if (item.tenantName !== null && item.TenantName !== '') {
                tenantDict[item.TenantName] = '';
            } 
        });

        var committeeNames = [];

        for (var key in tenantDict) {
            // TenantName is what is used in the DTO.  Might help things work
            // 'first time' someone tries to use this in an angular filter expression
            committeeNames.push({ DisplayName: key, TenantName: key });
        }
    
        // Sort the by name
        committeeNames = committeeNames.sort(function(a, b) {
            if (a.TenantName > b.TenantName)
                return -1;
            if (a.TenantName < b.TenantName)
                return 1;
            return 0;
        });
      
        return committeeNames;
  };

    service.buildReusablesUsageLists = function(list) {
        // Be safe with old browsers, and use a dict to generate a unique list of 
        // committee names based on the templates in the passed in template list
        // Eventually, this function may call into VAN or TGE to get actual visible committee
        // names.
        var typeDict = {};
        var tenantDict = {};
        var embedDict = {};
        list.forEach(function (item) {
            if (item.AncestorType !== null && item.AncestorType !== '') {
                typeDict[item.AncestorType] = '';
            }
            if (item.tenantName !== null && item.TenantName !== '') {
                tenantDict[item.TenantName] = '';
            }
            if (item.EmbedLevel !== null && item.EmbedLevel !== '') {
                embedDict[item.EmbedLevel] = '';
            }
        });

        var typeNames = [];

        for (let key in typeDict) {
            // AncestorType is what is used in the DTO.  Might help things work
            // 'first time' someone tries to use this in an angular filter expression
            typeNames.push({ DisplayName: key, AncestorType: key });
        }


        var committeeNames = [];

        for (let key in tenantDict) {
            // TenantName is what is used in the DTO.  Might help things work
            // 'first time' someone tries to use this in an angular filter expression
            committeeNames.push({ DisplayName: key, TenantName: key });
        }

        var embedLevels = [];

        for (let key in embedDict) {
            // TenantName is what is used in the DTO.  Might help things work
            // 'first time' someone tries to use this in an angular filter expression
            embedLevels.push({ DisplayName: key, EmbedLevel: key });
        }

        // Sort the by name
        typeNames = typeNames.sort(function (a, b) {
            if (a.AncestorType > b.AncestorType)
                return -1;
            if (a.AncestorType < b.AncestorType)
                return 1;
            return 0;
        });

        // Sort the by name
        committeeNames = committeeNames.sort(function (a, b) {
            if (a.TenantName > b.TenantName)
                return -1;
            if (a.TenantName < b.TenantName)
                return 1;
            return 0;
        });

        // Sort the by name
        embedLevels = embedLevels.sort(function (a, b) {
            if (a.EmbedLevel > b.EmbedLevel)
                return -1;
            if (a.EmbedLevel < b.EmbedLevel)
                return 1;
            return 0;
        });
        return { "type": typeNames, "tenant": committeeNames, "embed": embedLevels };
  };

    service.ResetSelection = function ($scope, textAreaId) {
        // This will make the select dbox reset to it's default (nothing selected) state.
        $scope.Model.reusableToInsert = null;
        // Only a problem when Wysywig is disabled: Pasting marking
        // The input appears to steal/keep
        // focus after the model is cleared (above).  
        setTimeout(function () {
            $("#" + textAreaId + " input").blur();
        }, 250, textAreaId);
    };

    service.InsertReusableReference = function (htmlEditorId, reusable, isHtmlContent) {
        InsertMergeField(htmlEditorId, reusable.EmbedShortCode, isHtmlContent);
    };

    service.PasteReusableContent = function (editorId, reusable, isHtmlContent) {
        $http({
            method: 'GET',
            url: '/Reusable/GetById/' + reusable.Id + '?forDelivery=false'
        }).then(function successCallback(result) {
            var response = result.data;
            if (response.ResponseResultCode !== Constants.ResponseResultCode.Failure) {
                var markup = response.Data.Html;
                var isMarkup = true;
                if (isHtmlContent === 'textEditor' && response.Data.Plaintext) {
                    markup = response.Data.Plaintext;
                    InsertMergeField(editorId,
                        markup,
                        isHtmlContent,
                        false,
                        true);
                } else {
                    InsertMergeField(editorId,
                        markup,
                        isHtmlContent,
                        isMarkup);
                }
            } else {
                // Only want to show feedback if there's a problem.
                FeedBack.update(response);
            }
        }, function errorCallback(result) {
            // called asynchronously if an error occurs
            // or server returns response with an error status.
            FeedBack.update(result.data);

        });

    };

    service.setEmailEditorPreference = function (document, isPreferenceDragAndDrop) {
        var editorPreference = isPreferenceDragAndDrop === null || isPreferenceDragAndDrop
            ? 'DragAndDropEditor'
            : 'ClassicEditor';

        var cookieValue = 'emailEditorPreference=' + editorPreference + ';';
        var cookiePath = 'path=/;';
        var expiration = formatCookieExpirationDate(365);
        var sameSite = 'SameSite=None;Secure;';
        document.cookie = cookieValue + cookiePath + expiration + sameSite;
    };

    service.getEmailEditorPreference = function (document) {
        var preference = getCookie(document, 'emailEditorPreference');
        return preference === null || preference === 'DragAndDropEditor';
    };

    service.getCookie = function(document, cookieName) {
        return getCookie(document, cookieName);
    };

    function formatCookieExpirationDate(daysToAdd) {
        var currentDate = new Date();
        if (daysToAdd !== null && daysToAdd >= 0) {
            currentDate.setDate(currentDate.getDate() + daysToAdd);
        }

        return 'expires=' + currentDate.toUTCString() + ';';
    }

    function getCookie(document, cookieName) {
        var cookies = document.cookie.split(';');
        var regex = new RegExp('^\\s*?' + cookieName + '=(.*)$');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i];
            var match = cookie.match(regex);
            if (match && match[1]) {
                return match[1];
            }
        }

        return null;
    }

    service.setCookie = function (document, cookieName, preference, expiration = formatCookieExpirationDate(365))
    {
        return setCookie(document, cookieName, preference, expiration);
    };


    function setCookie(document, cookieName, preference, expiration) {
        var cookieValue = cookieName + '=' + preference + ';';
        var cookiePath = 'path=/;';
        var sameSite = 'SameSite=None;Secure;';
        document.cookie = cookieValue + cookiePath + expiration + sameSite;
    }

    service.moxieManagerInsertFilter = function (file, regexString) {
        var oldUrl = file.url;
        var regex = new RegExp(regexString, 'i');
        var match = oldUrl.match(regex);
        if (match == null) {
            return;
        }

        var env = match.groups['env'];
        if (env == '') {
            env = 'prod';
        }
        var newBaseUrl = env + '.cdn.everyaction.com';

        var newUrl = oldUrl.replace(regex, newBaseUrl);
        file.url = newUrl;
        file.meta.url = newUrl;
    }

    ngp.extend('ngp.HtmlEditor', { moxieManagerInsertFilter: service.moxieManagerInsertFilter });

    return service;
}]);

common.directive("formatEventMessage", function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            statusColor: '@statusColor',
            verb: '@verb',
            person: '=person',
            time: '=time'
        },
        template: '<span><span ng-show="statusColor" class="indicator {{statusColor}}"></span><span class="item-status">{{verb}}</span>{{person | person}}<br/>{{time | formatDate}}</span>'
    };
});

common.directive("formatEventMessageOffset", function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            verb: '@verb',
            person: '=person',
            time: '=time'
        },
        template: '<span><span class="item-status">{{verb}}</span>{{person | person}}<br/>{{time | formatDateTimeOffset}}</span>'
    };
});

common.directive("formatEventMessageOverwriteProtection", function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            statusColor: '@statusColor',
            verb: '@verb',
            person: '=person',
            time: '=time'
        },
        template: '<span><span ng-show="statusColor" class="indicator {{statusColor}}"></span><span class="item-status text">{{verb}}</span><span class="text">{{person | person}}</span><br/><span class="text-xs">{{time | formatDate}}</span></span>'
    };
});


;
var multivariatetabs = angular.module('ngp.multivariatetabs', []).factory('ngp.multivariatetabs', ['ngp.email-common', function (common) {
    var service = {};

    service.deleteTab = function (tabIndex, $scope) {
        //Change Focus(You can always do -1 since the first tab cant be removed)
        $('#content_' + tabIndex + '_IsDeleted').val('true');
        $scope.openModal('deleteVariantModal.html', 'small', 'DeleteVariantModalControl');
        window.SetupDeleteVariantModal($scope, tabIndex);
    };

    service.variantDeleteOnClick = function (event) {
        var tabId = $(this).attr('data-id');
        service.deleteTab(tabId, event.data.scope);
        return false; //Don't trigger tab click event
    };

    //construct the html to insert a new tab object just before the add new test case button
    service.addTabHeader = function (tabIndex, tabName) {
        var formaction = 'form="UpdateForm' +
            tabIndex +
            '" formaction="/EmailMessage/SaveContent" ng-click="multivariatetabs.deleteTab(' +
            tabIndex +
            ')"';
        var deleteLink = '<a class="inline text-sm tab-remove delete text-gray" ' +
            formaction +
            ' data-id="' +
            tabIndex +
            '" href="javascript:void(0);">' +
            '<span class="glyphicons glyphicons-remove" aria-hidden="true"></span><span class="reader-only">@HttpUtility.JavaScriptStringEncode(Resources.RemoveTestCase)' +
            tabName +
            '</span></a>';
        var tabNameSpan = '<span id="content_' +
            tabIndex +
            '_tabName" class="text-base text-gray-dark">' +
            tabName +
            '</span>';
        var content =
            '<h6><a class="inline" href="javascript:void(0);"><span ng-class="indicator-square" class="indicator-square"></span>' +
                tabNameSpan +
                '</a>' +
                deleteLink +
                '</h6>';
        $('<div data-contenteditor-area-id="content_' +
            tabIndex +
            '_contentArea" class="tab">' +
            content +
            '</div>').insertBefore('.tab.add');
    };

    service.tabSelector = function (index) {
        return '[data-contenteditor-area-id="content_' + index + '_contentArea"]';
    };

    service.getName = function (tabId) {
        return common.getVariantChar(tabId);
    };

    service.setTabFocusInternal = function(tabElement, isNew, $scope, isDragAndDrop, bee) {
        if (tabElement.hasClass('active') || tabElement.hasClass('action'))
            return false;

        tabElement.addClass('active').siblings('div').removeClass('active');

        var contentId = tabElement.attr('data-contenteditor-area-id');
        $('#' + contentId).show().siblings('.htmlContentArea').hide();

        // We need to know what the currently selected tab so that the angular substitutions for
        // any associated template can happen.
        // This should be safe.  It depends on the attribute value and not on the current
        // index of the tab, so handles cases where variants are added and removed from the middle
        // of the variant set
        $scope.VisibleVariantId = parseInt(contentId.split('_')[1]);

        if (isDragAndDrop) {
            // If bee is authenticated, load the new editor content as you switch tabs
            $scope.beeLoaded = false;

            if (!!bee) {
                //check for empty. If empty load default in
                if ($scope.DragAndDropJson[$scope.VisibleVariantId] === '{}') {
                    bee.load(JSON.parse($scope.templates[0].json));
                } else {
                    bee.load(JSON.parse($scope.DragAndDropJson[$scope.VisibleVariantId]));
                }
            }
        }
        // In this case, the angular substitution won't happen until we tell it to.
        // Might be another way of triggering this via hidden form field and ng-model, but
        // this is not as indirect and we have a comment to describe why we're doing it.
        if (!isNew) {
            try {
                $scope.$apply();
            } catch (e) {

            }
        }

        return true;
    };

    return service;
}]);;
var directivesModule = angular.module('ngp.directives', ['ui.bootstrap']);
// documentation: https://ngpvan.atlassian.net/wiki/display/BCE/Angular+Directives+in+TGE

// trigger attribute is optional and would likely be $touched or $dirty -- it defaults to $touched.
//
// Usage: <validation-message for="inputName" rule="errorPropertyName" trigger="$touched"/>
directivesModule.directive("validationMessage", function () {

  // Helper function to grab the form enclosing this element
  function getContainingForm(el) {
    while (el && el[0]) {
      if (el[0].tagName.toLowerCase() === "form") {
        return el.attr("name");
      }
      el = el.parent();
    }
    return "";
  }

  return {
    scope: true,
    restrict: 'E',
    template: "<span ng-show='showMessage()'><ng-transclude/></span>",
    replace: true,
    transclude: true,
    priority: 1000,
    link: function (scope, spanElement, tAttrs) {
      var formName = getContainingForm(spanElement);
      var inputName = tAttrs['for'];
      var rule = tAttrs['rule'];
      var trigger = tAttrs['trigger'] || "$touched";
      var form = scope[formName];
      var input = scope[formName][inputName];
      var errors = input.$error;

      // Show the errors if the rule is broken AND either the trigger condition is met, or the form is in the submitted state
      scope.showMessage = function() {
        return (errors[rule] && (input[trigger] || form.$submitted));
      };

      // Add error message styles
      spanElement
          .addClass("input-message")
          .addClass("error");
    }
  };
});



// Directive that automatically adds validation warnings after an input element
// Currently adds warnings for ngMaxlength, ngMinlength, ngRequired, and type='email'
//
// Usage: <input auto-validate-messages ng-maxlength="5" required/>
directivesModule.directive("autoValidateMessages", function () {

  return {
    restrict: 'A',
    compile: function (inputElement, attributes) {
      // function that handles creating each rule
      function createValidationMessage(rule, trigger) {
        var name = attributes['name'];
        // Get the 'fieldname' to use in  validation messages.  
        // Use the string value if the attribute is missing
        var fieldName = attributes['fieldName'] ? ("'" + attributes['fieldName'] + "'") : "Value";
        var v = angular.element("<validation-message />")
                      .attr('for', name)
                      .attr('rule', rule);
        if (trigger) {
          v.attr('trigger', trigger);
        }
        switch (rule) {
          case "minlength":
              v.text(fieldName + " " + window.ngpvan.translations.seriesCreate.mustBeAtLeast + " " + attributes["ngMinlength"] + " " + window.ngpvan.translations.seriesCreate.characters);
                break;
          case "maxlength":
              v.text(fieldName + " " + window.ngpvan.translations.seriesCreate.mustBeNoMoreThan + " " + attributes["ngMaxlength"] + " " + window.ngpvan.translations.seriesCreate.characters);
            break;
          case "required":
              v.text(fieldName + window.ngpvan.translations.seriesCreate.isRequired);
            break;
          case "email":
              v.text(fieldName + window.ngpvan.translations.seriesCreate.mustBeAValidEmail);
            break;
        }
        inputElement.after(v);
      }

      // Look for the validation types this directive handles
      if (attributes['ngMaxlength']) {
        // For maxlength, we'll want to show the message right away, not when the element loses focus
        createValidationMessage("maxlength", "$dirty");
      }
      if (attributes['ngMinlength']) {
        createValidationMessage("minlength", "$touched");
      }
      if (attributes['ngRequired']) {
        createValidationMessage("required", "$touched");
      }
      if (attributes['type'] && attributes['type'].toLowerCase() === "email") {
        createValidationMessage("email", "$touched");
      }
    }
  };
});

directivesModule.directive("stylebutton", function() {
  return {
    restrict: 'A',
    compile: function(tElem, tAttrs) {
        var label = tAttrs.label;

      //Set text and title to the indicated button label
      tElem.text(label);
      tElem.attr("title", label);
    }
  };
});


// Wraps an input in a standard set of divs, and adds a label.  Replicates most of the behavior of @Html.TextBoxFieldRowFor()
// 
// Usage: <input textbox-for="{label:'labelstring', name:'inputName', path:'Model.dto.property'}" />
// Usage with Razor helper: <input textbox-for="@Html.ModelInfo(m=>m.property)" />
directivesModule.directive("textboxFor", function () {
  // TODO extract as much as possible into a template
  return {
    scope: false,
    restrict: 'A',
    template: "<input>",
    replace: true,
    compile: function (inputElement, tAttrs) {
        var modelInfo = JSON.parse(tAttrs['textboxFor']);
        var label = modelInfo.label;
        var name = modelInfo.name;
        var ngModel = modelInfo.path;
        var id = modelInfo.id;
        var required = modelInfo.required;

        // If an id is not explicitly provided,
        // set up an id by cutting off the "Model" part and replacing dots with underscores
        // This matches how razor was setting up ids -- we could change this but it would probably require altering functional tests
        id = id || ngModel.replace("Model.", "").replace(".", "_", "g");


        var baseDiv = angular.element("<div>").addClass("input-unit"),
            divControl = angular.element("<div>").addClass("input-control input-control-anchor").attr('id', id + '-anchor'),
            labelEl = angular.element("<label/>").text(label)
                .attr("for", id)
                .addClass("input-label");

        if (modelInfo.required === "required") {
            labelEl.addClass("required");
        }

        inputElement
            .attr("id", id)
            .addClass("input-element")
            .attr("ng-model", ngModel)
            .attr("name", name)
            .attr("field-name", label)
            .attr("auto-validate-messages", "")
            .removeAttr('textbox-for'); // if you don't remove the attribute, it will recursively compile!
        //TODO look to see if splitting between compile/pre/post linking will help

        if (!inputElement.attr("type")) {
            inputElement.attr("type", "text");
        }

        inputElement.after(baseDiv);
        baseDiv.append(labelEl);
        baseDiv.append(divControl);
        divControl.append(inputElement);

        return baseDiv;
    }
  };
});

// Wraps an input in a standard set of divs, and adds a label.  Replicates most of the behavior of @Html.TextBoxFieldRowFor()
// 
// Usage: <input textbox-for="{label:'labelstring', name:'inputName', path:'Model.dto.property'}" />
// Usage with Razor helper: <input textbox-for="@Html.ModelInfo(m=>m.property)" />
directivesModule.directive("textareaFor", function () {
    // TODO extract as much as possible into a template
    return {
        scope: false,
        restrict: 'A',
        template: "<textarea>",
        replace: true,
        compile: function (inputElement, tAttrs) {
            var modelInfo = JSON.parse(tAttrs['textareaFor']);

            var label = modelInfo.label;
            var name = modelInfo.name;
            var ngModel = modelInfo.path;
            var id = modelInfo.id;
            var required = modelInfo.required;
            // If an id is not explicitly provided,
            // set up an id by cutting off the "Model" part and replacing dots with underscores
            // This matches how razor was setting up ids -- we could change this but it would probably require altering functional tests
            id = id || ngModel.replace("Model.", "").replace(".", "_", "g");
            var baseDiv = angular.element("<div>").addClass("input-unit");
            var divControl = angular.element("<div>").addClass("input-control input-control-anchor").attr('id', id + '-anchor');
            var labelEl = angular.element("<label/>").text(label)
                .attr("for", name)
                .addClass("input-label");

            if (modelInfo.required === "required") {
                labelEl.addClass("required");
            }

            inputElement
                .addClass("input-element")
                .attr("ng-model", ngModel)
                .attr("name", name)
                .attr("field-name", label)
                .attr("auto-validate-messages", "")
                .removeAttr('textarea-for'); // if you don't remove the attribute, it will recursively compile!
            //TODO look to see if splitting between compile/pre/post linking will help

            if (!inputElement.attr("type")) {
                inputElement.attr("type", "text");
            }

            inputElement.attr("id", id);

            inputElement.after(baseDiv);
            baseDiv.append(labelEl);
            baseDiv.append(divControl);
            divControl.append(inputElement);

            return baseDiv;
        }
    };
});

directivesModule.directive('textValidator', function() {
    return {

        link: function(scope, $element, $attributes) {
            $element.bind('keypress', function(e) {
                var char = String.fromCharCode(e.which || e.charCode || e.KeyCode);
                angular.forEach(scope.invalidValues, function(value, key) {
                    if (char === value) {
                        e.preventDefault();
                        return false;
                    }
                });
            });
        }
    };
});

// This is a workaround solution for a problem related to angular focusing. 
// It was shamelessly taken from https://github.com/angular-ui/ui-select/issues/1201
directivesModule.directive('tgeSelectFocusInput', function ($timeout) {
    return {
        require: 'ui-select',
        link: function (scope, $element, $attributes, selectController) {
            scope.$on('uis:activate', function () {
                // Give it time to appear before focus		
                $timeout(function () {
                    scope.$select.focusSearchInput();
                }, 100);
            });
        }
    };
});

// this forces input to conform to the pattern attribute in the element
directivesModule.directive("ngpPatternValidate", function () {
    return {
        require: 'ngModel',
        link: function ($scope, $element, attrs, ctrl) {
            ctrl.$parsers.push(function (regex, ctrl, newVal) {
                var oldVal = ctrl.$modelValue;
                if (regex.test(newVal)) {
                    return newVal;
                } else {
                    ctrl.$setViewValue(oldVal);
                    ctrl.$render();
                    return oldVal;
                }
            }.bind(null, new RegExp(attrs.pattern), ctrl));
        }
    }
});

// closes the SmartLink UiSelect when it is hidden by changing link type
directivesModule.directive('closeOnChange', function () {
    return {
        require: 'uiSelect',
        link: function ($scope, $element, attrs, $select) {
            $scope.$watch("SmartLinkTypeDropdown.RadioGroup",
                function () {
                    $select.close();
                });
        }
    }
});

// Detect when the last element in a container is in view.  Can be useful for "infinite scrolling" applications
directivesModule.directive('lastInView', function(){
    return function(scope, el, attr) {
        if (!scope.$last) {
            return;
        }

        var options = {
            threshold: 0 // 0%, i.e. fire if even one pixel is in frame
        };
        var callback = function(entries) {
            if (!scope.$last) {
                // No longer the last element - unregister callback
                observer.disconnect();
            }

            if (!entries[0].isIntersecting) {
                return;
            }
            scope.$eval(attr.onLastInView);
        }
        var observer = new IntersectionObserver(callback, options);
        observer.observe(el[0]);
    };
});;
var formatters = angular.module('ngp.formatters', []);

formatters.filter('localdate', ['$filter', function ($filter) {

    return function (input, localFormatName, isDateTimeOffset) {
        var date = input;
        if (!(date instanceof Date)) {
            // is NOT already a Date object
            var dateString = input.endsWith('Z') || isDateTimeOffset ? input : input + 'Z';
            date = new Date(dateString);
        }
        return $filter('date')(date, window.ngpvan.localization.current.dateFormats[localFormatName] || localFormatName);
    };

}]);

formatters.filter('fromNow', function () {
    return function (date) {
        return moment(date).fromNow(true);
    };
});

formatters.filter('formatDate', ['$filter', function ($filter) {
    return function (input) {
        // So that empty inputs don't break the page.
        if (!input) {
            return input;
        }
        // Format is defined here: https://docs.angularjs.org/api/ng/filter/date
        // Produces dates in the format "Nov 5, 2015 11:55 a.m."
        // Also, because we are omitting the timezone argument, angular will use the timezone of the browser
        // However, we may need to add 'Z' to the end of the date string to tell the browsers JS interpreter that the time is in UTC.
        // Without this clarification, browsers will do different things: Safari and Chrome will treat the time as UTC.  Firefox and IR will treat the time as local.
        var dateString = input.endsWith('Z') ? input : input + 'Z';
        return $filter('date')(new Date(dateString), window.ngpvan.localization.current.dateFormats.abbrevDatetime);
    };
}]);

formatters.filter('formatNumericDate', ['$filter', function ($filter) {
  return function (input) {
    // So that empty inputs don't break the page.
    if (!input) {
        return input;
    }
    // Format is defined here: https://docs.angularjs.org/api/ng/filter/date
    // Produces dates in the format "11/5/2015 11:55 a.m."
    // Also, because we are omitting the timezone argument, angular will use the timezone of the browser
    // However, we may need to add 'Z' to the end of the date string to tell the browsers JS interpreter that the time is in UTC.
    // Without this clarification, browsers will do different things: Safari and Chrome will treat the time as UTC.  Firefox and IR will treat the time as local.
    var dateString = input.endsWith('Z') ? input : input + 'Z';
    return $filter('date')(new Date(dateString), window.ngpvan.localization.current.dateFormats.numericDatetime);
  };
}]);


formatters.filter('formatDateTimeOffset', ['$filter', function ($filter) {
    return function (dateValue, templateStatus) {
        if (!dateValue || templateStatus === 0) {
            return '';
        }
        // Format is defined here: https://docs.angularjs.org/api/ng/filter/date
        return $filter('date')(new Date(dateValue), window.ngpvan.localization.current.dateFormats.abbrevDatetime);
    };
}]);

formatters.filter('formatDateTimeVan', ['$filter', function ($filter) {
    return function (dateValue, templateStatus) {
        if (!dateValue || templateStatus === 0) {
            return '';
        }
        // Format is defined here: https://docs.angularjs.org/api/ng/filter/date
        // Remove the Z character indicating this is UTC
        // (VAN stores DateTimes in EST - we want to format whatever VAN has sent over without applying any offsets)
        var trimmedDate = dateValue.substring(0, dateValue.length - 1);
        return $filter('date')(new Date(trimmedDate), window.ngpvan.localization.current.dateFormats.abbrevDatetime);
    };
}]);

formatters.filter('percentage', function ($filter) {
  return function (number, defaultValue, decimalPlaces) {
    // If a default is provided, use it if the value is null OR 0
    // (The last one is a bit of a hack)
    if (typeof (number) !== "number" && typeof (defaultValue) !== "undefined" ) {
      return defaultValue;
      }
      if (typeof (decimalPlaces) !== "number" || typeof (decimalPlaces) === "undefined") {
          decimalPlaces = 2;
      }
    return $filter('number')(number*100, decimalPlaces) + "%";
  };
});

formatters.filter('ordinal', function () {
    return function (number) {
        var s = [
                window.ngpvan.translations.seriesCreate.th,
                window.ngpvan.translations.seriesCreate.st,
                window.ngpvan.translations.seriesCreate.nd,
                window.ngpvan.translations.seriesCreate.rd
        ],
            v = number % 100;
        return number + (s[(v - 20) % 10] || s[v] || s[0]);
    };
});

formatters.filter('numeral', function () {
    return function (number, format) {
        return numeral(number).format(format);
    };
});

formatters.filter('kNum', function () {
    return function(number) {
        var format = number > 9999 ? '0.[0]a' : '0,0';
        return numeral(number).format(format);
    };
});

formatters.filter('metricsChevron', function () {
  return function (metricsObject) {
    if (!metricsObject) return;
    return metricsObject.Current >= metricsObject.Previous ? 'glyphicons-chevron-up' : 'glyphicons-chevron-down';
  };
});

formatters.constant('statusValues', {
    1: "Scheduled",
    2: "Sending",
    4: "SelectWinner",
    5: "Withdrawn",
    6: "Sent",
    7: "Series",
    8: "ActiveSubscriptionConfirmation",
    9: "DraftSubscriptionConfirmation",
    10: "NotSentCommitteeInactive"
});

// Maps the email message status to the status value
formatters.filter('emailStatus', ['statusValues', function (statusValues) {
    return function(email) {
        var status = getStatus(statusValues, email);

        if (status == statusValues[4] && email.IsAutoPickWinner) {
            return statusValues[1];
        }

        return status;
    };
}]);

// Maps the email message status to the status display name
formatters.filter('emailStatusName', function () {
    var statusNames = {
        1: window.ngpvan.translations.Pages.scheduled,
        2: window.ngpvan.translations.Pages.sending,
        4: window.ngpvan.translations.Pages.selectWinner,
        5: window.ngpvan.translations.Pages.withdrawn,
        6: window.ngpvan.translations.Pages.sent,
        10: window.ngpvan.translations.Pages.notSentCommitteeInactive
    };

    return function(email) {
        var status = getStatus(statusNames, email);

        if (status == "InvalidTargeting") {
            return window.ngpvan.translations.Pages.invalidTargeting;
        }

        if (status == window.ngpvan.translations.Pages.scheduled && email.IsVariant) {
            return window.ngpvan.translations.Pages.testScheduled;
        }

        if (status == window.ngpvan.translations.Pages.selectWinner && email.IsAutoPickWinner) {
            return window.ngpvan.translations.Pages.autoSelectWinnerScheduled;
        }

        if (status == window.ngpvan.translations.Pages.sending && email.IsWinnerContent) {
            return window.ngpvan.translations.Pages.winnerSending;
        }

        return status;
    };
});

// Maps the email series status to the status display name
formatters.filter('seriesStatusName', function () {
    return function(series, toLower) {
        var statusNames = {
            1: window.ngpvan.translations.Pages.inactive,
            2: window.ngpvan.translations.Pages.active,
            3: window.ngpvan.translations.Pages.paused,
            4: window.ngpvan.translations.Pages.ended,
            5: window.ngpvan.translations.Pages.paused
        };
        var status = series.EmailSeriesStatusId;
        if (statusNames[status] != undefined) {
            if (toLower) {
                return statusNames[status].toLowerCase();
            }
            return statusNames[status];
        } else {
            return "(ERROR -- Unknown Status)";
        }
    }
});

// Maps the email series status to the status class name
formatters.filter('seriesStatusClassName', function () {
    return function (series, toLower) {
        var statusNames = {
            1: "Inactive",
            2: "Active",
            3: "Paused",
            4: "Ended",
            5: "Paused"
        };
        var status = series.EmailSeriesStatusId;
        if (statusNames[status] !== undefined) {
            if (toLower) {
                return statusNames[status].toLowerCase();
            }
            return statusNames[status];
        } else {
            return "(ERROR -- Unknown Status)";
        }
    };
});

formatters.filter('statusName', function() {

    var reusableStatus =
    {
        0: window.ngpvan.translations.Pages.def,
        1: window.ngpvan.translations.Pages.published,
        2: window.ngpvan.translations.Pages.deactivated,
        3: window.ngpvan.translations.Pages.draft
    }

    return function (dto) {

        if (dto.HasUnpublishedChanges && reusableStatus[dto.ReusableStatus] == reusableStatus[1]) {
            return window.ngpvan.translations.Pages.publishedWithUnpublishedChanges;
        } else {
            return reusableStatus[dto.ReusableStatus];
        }
    };
});

formatters.filter('statusPip', function() {
    var statusIndicators = {
        0: "indicator empty-gray",
        1: "indicator green",
        2: "indicator gray",
        3: "indicator yellow",
        4: "indicator orange"
    };
    return function(input) {
        return statusIndicators[input];
    };
});

formatters.filter('reusableAncestor', function () {
    var urlMap = {
        "Reusable": "/Reusable/Update/",
        "Email4": "/EmailMessage/RecipientsContent/",
        "Email0": "/EmailMessage/UpdateContent/",
        "Email1": "/EmailMessage/DeliverMessageContent/",
        "Email in Series": "/EmailSeries/Update/",
        "Theme": "/Themes/Update/",
        "Subscription Confirmation Email": "/EmailMessage/UpdateContent/"
    };

    return function (reusable) {
        if (reusable.AncestorType === "Email" && reusable.EmailSeriesId === "00000000-0000-0000-0000-000000000000") {
            return urlMap[reusable.AncestorType + reusable.Status]+reusable.AncestorId;
        } else if (reusable.AncestorType === "Email in Series" && reusable.EmailSeriesId !== "00000000-0000-0000-0000-000000000000") {
            return urlMap[reusable.AncestorType]+reusable.EmailSeriesId;
        } else {
            return urlMap[reusable.AncestorType] + reusable.AncestorId;
        }
    };
});

formatters.filter('scePip', ['statusValues', function (statusValues) {
    return function(sce) {
        if (sce.Status && statusValues[sce.Status] === 'DraftSubscriptionConfirmation') {
            return "yellow";
        } else if (sce.HasUnpublishedChanges) {
            return "orange";
        } else {
            return "green";
        }
    };
}]);

formatters.filter('person', function() {
    return function(person) {
        if (person === null) {
            return '';
        } else {
            return ' ' + window.ngpvan.translations.Pages.by + ' ' + person + ' ';
        }
    };
});

formatters.filter('stripSpaces', function() {
    return function(name) {
        if (name === null) {
            return '';
        } else {
            return name.replace(/\s+/g, '');
        }
    };
});

function getStatus(statusMap, email) {
    // if any distribution failed, then return the failure state
    if (email.DistributionStatusId === 3 && email.EmailMessageSendGroupStepId == null) {
        return "Failed";
    }
    if (email.DistributionStatusId === 5 && email.EmailMessageSendGroupStepId == null) {
        return "InvalidTargeting";
    }

    // Otherwise return the overall email message status
    var status = email.EmailMessageStatusId;
    if (statusMap[status] !== undefined) {
        return statusMap[status];
    } else {
        return "(ERROR -- Unknown Status)";
    }
}

formatters.filter('truncate', function() {
    return function(text, len) {
        if (text.length <= len) {
            return text;
        }
        return text.substring(0, len) + '…';
    }
});
;
(function (angular) {
    var fetchedLists = [];
    var fetchedSearches = [];
    var fetchedDesignations = [];
    //Configure the ngpvan.ui.mergefields module to handle TGE specific needs

    angular.module('ngpvan.tge.mergefields.config', ['ngpvan.ui.mergefields'])
        .config([
            'mergeFieldConfigProvider', 'languageConfigProvider',
            function (mergeFieldConfigProvider, languageConfigProvider) {

                var localizedText = window.ngpvan.translations.Pages;

                mergeFieldConfigProvider.setDefaultDropdownType('tree');

                // set localized text
                languageConfigProvider.set('ngpvan.ui.mergefields', {
                    dropdownLabel: localizedText.mergeFields,
                    dropdownSearchPlaceholder: localizedText.mergeFieldDropdownPlaceholder,
                    modalCancel: localizedText.cancel,
                    modalConfirm: localizedText.add,
                    modalXReaderText: localizedText.closeModal,
                    modalTitle: localizedText.mergeFields,
                    modalConditionalTemplateInclusionLabel: localizedText.modalConditionalTemplateInclusionLabel,
                    modalSegmentPlaceholder: localizedText.modalSegmentPlaceholder
                });

                //Global default text
                mergeFieldConfigProvider.setGlobalDefault({
                    outroPrompt: localizedText.mergeFieldModalOutro
                });

                var advocacyMergeFieldProperties = [
                    {
                        label: 'Name',
                        type: 'radio',
                        options: [
                            { label: 'Prefix and Full Name', key: 'Prefix_FullName' },
                            { label: 'Prefix and Last Name', key: 'Prefix_LastName' },
                            { label: 'Do Not Display Name', key: '' }
                        ]
                    },
                    {
                        label: 'Contact Information',
                        type: 'checkbox',
                        errorMessage: 'Contact Information is required.',
                        options: [
                            { label: 'Phone Number', key: 'Phone' },
                            { label: 'Twitter Handle', key: 'Twitter' }
                        ]
                    }
                ];

                function advocacyMergeFieldIntro(target) {
                    return 'What information about the email recipient\'s ' + target + ' should display?';
                }

                function advocacyMergeFieldOutro(target) {
                    return 'If the email recipient\'s ' +
                        target +
                        ' cannot be determined due to a seat vacancy or missing address information, what value should display by default? ' +
                        'Leave the default value blank if you\'d like nothing to be displayed.';
                }

                function advocacyMergeFieldOnPropertyChange(key, prop, option, value, config) {
                    var contactInformation = config.properties[1]; //see advocacyMergeFieldProperties above

                    if (prop.label === 'Name') {
                        //if no value for Name, require the contact information
                        contactInformation.required = !value;
                    }
                }

                var advocacyMergeFields = _.map([
                    { mf: 'UsSenators', target: 'US Senators', defaultValue: 'your senators' },
                    { mf: 'UsRepresentative', target: 'US Represenative', defaultValue: 'your representative' },
                    { mf: 'StateGovernor', target: 'Governor', defaultValue: 'your governor' },
                    { mf: 'StateLieutenantGovernor', target: 'Lieutenant Governor', defaultValue: 'your lieutenant governor' },
                    { mf: 'StateAttorneyGeneral', target: 'Attorney General', defaultValue: 'your attorney general' },
                    { mf: 'StateSecretaryOfState', target: 'Secretary Of State', defaultValue: 'your secretary of state' },
                    { mf: 'StateTreasurer', target: 'State Treasurer', defaultValue: 'your state treasurer' },
                    { mf: 'StateSenators', target: 'State Senators', defaultValue: 'your senators' },
                    {
                        mf: 'StateRepresentatives',
                        target: 'State Representatives',
                        defaultValue: 'your representatives'
                    }
                ],
                    function (simple) {
                        return {
                            key: simple.mf,
                            defaultValue: simple.defaultValue,
                            introPrompt: advocacyMergeFieldIntro(simple.target),
                            outroPrompt: advocacyMergeFieldOutro(simple.target),
                            properties: advocacyMergeFieldProperties,
                            callbacks: {
                                onPropertyChange: advocacyMergeFieldOnPropertyChange
                            }
                        };
                    });

                var footerFieldOrdering =  {
                    Disclaimer:footerPad(1),
                    OrganizationAddress:footerPad(2),
                    UnsubscribeLink:footerPad(3),
                    ConfirmationLink:footerPad(4),
                    UnsubscribeUrl:footerPad(5),
                    ConfirmationUrl:footerPad(6),
                    CommitteeId:footerPad(7),
                    EditFooterOptions:footerPad(8)
                };

                //Moves specified group to top of alphabetical list in dropdown
                var triggeredEmailOrdering = {
                    "Recurring Commitment Information": footerPad(1),
                    "Self-Service Contribution Receipt Information": footerPad(1)
                };

                function footerPad(num) {
                    var s = "00000000" + num;
                    // Assume never more than 999 footer options
                    return s.substr(s.length-3);
                }

                var conditionalContentTemplate =
                    '{{if #MERGEFIELD#}}' + localizedText.conditionalContentTemplateIf + '{{else}}' + localizedText.conditionalContentTemplateElse + '{{end}}';
                //Map from MergeFieldDto.cs to expected object
                mergeFieldConfigProvider.setMapperFunction(function (origMf) {

                    // Initialize default mapped field here
                    var mfObject = {
                        key: origMf.MergeFieldTag,
                        label: origMf.DisplayName,
                        group: origMf.GroupName
                    };

                    // If it's in Targets
                    if (origMf.GroupName === "Targets") {
                        // Give it special 'Targets' properties
                        var targetObject = {
                            key: origMf.MergeFieldTag,
                            label: origMf.DisplayName,
                            group: origMf.GroupName,
                            isConditionalField: true,
                            skipBraces: true,
                            contentTemplate: conditionalContentTemplate,
                            introPrompt: localizedText.modalTargetsIntro,
                            outroPrompt: localizedText.modalTargetsOutro,
                            noTemplatePrompt: localizedText.modalNoTemplate,
                            callbacks: {
                                onBeforeInsert: function(result) {
                                    result.fieldOptions.humanReadableName = origMf.DisplayName;
                                }
                            }
                        };
                        // And extend default object
                        _.extend(mfObject, targetObject);
                    } else if (origMf.GroupName === "Footer" || origMf.GroupName === "Bas de page" ) {
                        var footerObject = {
                            key: origMf.MergeFieldTag,
                            label: origMf.DisplayName,
                            group: origMf.GroupName,
                            disableDefault: true
                        };
                        // We create a special property used for sorting.  
                        // Only add it to footer merge fields
                        Object.defineProperty(mfObject, "tgeLabel", {
                            //return label prefixed by 00X to help setup correct ordering
                            get: function () {
                                return footerFieldOrdering[origMf.MergeFieldTag] + origMf.DisplayName;
                            }
                        });

                        // Only configure special mergeField for UnsubscribeUrl and ConfirmationUrl
                        if (origMf.MergeFieldTag === "UnsubscribeUrl") {
                            mfObject.callbacks = {
                                onBeforeInsert:function(result, config) {
                                                    if (!origMf.isDragAndDrop && config.editorId.endsWith('_HtmlMessage')) {
                                                        result.mergeField =
                                                    '<a style="" href="{{UnsubscribeUrl}}">' + window.ngpvan.constants.Unsubscribe + '</a>';
                                                    } else {
                                                        result.mergeField =
                                                            window.ngpvan.constants.Unsubscribe + ' {{UnsubscribeUrl}}';
                                                    }
                                                }
                            };                            
                        // With themes, we must wrap the url with a conditional that check IsSentByTargetedEmail
                        } else if (origMf.MergeFieldTag.includes('UnsubscribeUrl')  && origMf.MergeFieldTag.includes(window.ngpvan.constants.IsSentByTargetedEmail)) {
                                mfObject.callbacks = {
                                    onBeforeInsert:function(result, config) {
                                        if (!origMf.isDragAndDrop && config.editorId.endsWith('_HtmlMessage')) {
                                            result.mergeField =
                                                '{{if IsSentByTargetedEmail}} <a style="" href="{{UnsubscribeUrl}}">' + window.ngpvan.constants.Unsubscribe + '</a>{{end}}';
                                        } else {
                                            result.mergeField =
                                                '{{if IsSentByTargetedEmail}} ' + window.ngpvan.constants.Unsubscribe + ' {{UnsubscribeUrl}} ' + '{{end}}';
                                        }
                                    }
                                };                            
                        } else if (origMf.MergeFieldTag === "ConfirmationUrl") {
                            mfObject.callbacks = {
                                onBeforeInsert: function(result, config) {
                                                    if (!origMf.isDragAndDrop && config.editorId.endsWith('_HtmlMessage')) {
                                                        result.mergeField =
                                                    '<a style="" href="{{ConfirmationUrl}}">' + window.ngpvan.constants.Confirm + '</a>';
                                                    } else {
                                                        result.mergeField =
                                                            window.ngpvan.constants.Confirm + ' {{ConfirmationUrl}}' ;
                                                    }
                                                }
                            };
                        } else if (origMf.MergeFieldTag === "EditFooterOptions") {
                            mfObject.callbacks = {
                                onBeforeInsert: function(result, config) {
                                    result.mergeField = ''; // Don't insert anything to text area
                                    // Throw up the modal for configuring footer options

                                    if (config.editorId != null) {
                                        angular.element(document.getElementById(config.editorId)).scope()
                                            .openModal('footerModal.html');
                                    } else {
                                        origMf.openModal('footerModal.html');
                                    }
                                }
                            };
                        }
                        _.extend(mfObject, footerObject);
                    };

                    if (origMf.isDragAndDrop) {
                        var callbacks = {
                            onInsert: origMf.callbacks.onInsert,
                            onOpenDetailsModal: origMf.callbacks.onOpenDetailsModal,
                            onDismissDetailsModal: origMf.callbacks.onDismissDetailsModal
                        }

                        mfObject.callbacks = {
                            ...mfObject.callbacks,
                            ...callbacks
                        }
                    }

                    return mfObject;
                });

                mergeFieldConfigProvider.setGroupsArrayMapperFunction(function(groups) {
                    var footerGroup = groups.forEach(function (group) {
                        //if no special ordering of group, order alphabetically by label
                        group.tgeLabel = triggeredEmailOrdering[group.label] || group.label;
                    })

                    return groups;
                });

                var footerMergeFields = [
                    {
                        key: "UnsubscribeUrl",
                        skipBraces:true
                    },
                    {
                        key: "ConfirmationUrl",
                        skipBraces:true
                    },
                    {
                        key: "EditFooterOptions",
                        skipBraces:true
                    },
                    {
                        key: "{{if " + window.ngpvan.constants.IsSentByTargetedEmail+ "}} {{UnsubscribeUrl}} {{end}}",
                        skipBraces:true
                    },
                    {
                        key: "{{if " + window.ngpvan.constants.IsSentByTargetedEmail+ "}} {{UnsubscribeLink}} {{end}}",
                        skipBraces:true
                    }

                ];

                var segmentMergeFields = [
                    {
                        key: "SavedList",
                        introPrompt: localizedText.modalSavedListIntro,
                        outroPrompt: localizedText.modalSavedListOutro,
                        noTemplatePrompt: localizedText.modalNoTemplate,
                        isConditionalField: true,
                        skipBraces: true,
                        segmentSelection: {
                            label: localizedText.modalSavedListLabel,
                            segments: fetchedLists,
                            missingText: localizedText.modalMissingSavedLists,
                            requiredText: localizedText.modalSavedListRequired,
                            modalSelectorPlaceholder: localizedText.modalSegmentPlaceholder
                        },
                        contentTemplate: conditionalContentTemplate

                    },
                    {
                        key: "SavedSearch",
                        introPrompt: localizedText.modalSavedSearchIntro,
                        outroPrompt: localizedText.modalSavedSearchOutro,
                        noTemplatePrompt: localizedText.modalNoTemplate,
                        isConditionalField: true,
                        skipBraces: true,
                        segmentSelection: {
                            label: localizedText.modalSavedSearchLabel,
                            segments: fetchedSearches,
                            missingText: localizedText.modalMissingSavedSearches,
                            requiredText: localizedText.modalSavedSearchRequired,
                            modalSelectorPlaceholder: localizedText.modalSegmentPlaceholder
                        },
                        contentTemplate: conditionalContentTemplate

                    }
                ];

                function amountMergeField(mergeField, defaultValue, currencyMergeField) {
                  return {
                    key: mergeField,
                    defaultValue: defaultValue,
                    callbacks: {
                      onBeforeInsert: function(result) {
                        result.mergeField = 'format_currency(' +
                            result.mergeField + ', ' + currencyMergeField + ')';
                      }
                    }
                  };
                }

                // Map merge fields that should be formatted as a currency to the currency argument
                // Most will use a default currency of USD
                var defaultCurrency = '\'USD\'';
                var currencyFormattedFieldDeclarations = {
                    'HighestPreviousContributionAmount': defaultCurrency,
                    'HighestPreviousContributionAmount12Months': defaultCurrency,
                    'HighestPreviousContributionAmount24Months': defaultCurrency,
                    'HighestPreviousContributionAmount36Months': defaultCurrency,
                    'MostRecentContributionAmount': defaultCurrency,
                    'MostRecentContributionAmount12Months': defaultCurrency,
                    'MostRecentContributionAmount24Months': defaultCurrency,
                    'MostRecentContributionAmount36Months': defaultCurrency,
                    'MostRecentContributionTaxDeductibleAmount': defaultCurrency,
                    'MostRecentRecurringCommitmentAmount': defaultCurrency,
                    'MostRecentPledgeAmount': defaultCurrency,
                    'MostRecentPledgeAmountContributed': defaultCurrency,
                    'MostRecentPledgeAmountRemaining': defaultCurrency,
                    'MostRecentContributionProcessedAmount': 'MostRecentContributionProcessedCurrency',
                    'HighestPreviousContributionProcessedAmount': 'HighestPreviousContributionProcessedCurrency',
                    'MostRecentRecurringCommitmentProcessedAmount': 'MostRecentRecurringCommitmentProcessedCurrency',
                    'DuesAmount' : defaultCurrency,
                    'TotalDuesPaidAmount': defaultCurrency,
                    'RecurringCommitmentAmount': defaultCurrency,
                    'RecurringCommitmentProcessedAmount': 'RecurringCommitmentProcessedCurrency',
                    'RecurringCommitmentTotalToDate': defaultCurrency,
                    'AverageContributionAmount': defaultCurrency,
                    'FirstContributionAmount': defaultCurrency,
                    'TotalAmountOfAttributedContributions': defaultCurrency,
                    'TotalAmountOfContributionsLast365Days': defaultCurrency,
                    'TotalAmountOfContributionsTwoYearsAgo': defaultCurrency,
                    'TotalContributionAmountYTD': defaultCurrency,
                    'NextInstallmentAmount': defaultCurrency,
                    'FinalScheduledPaymentAmount': defaultCurrency,
                    'HighestPreviousFhhContributionAmount': defaultCurrency,
                    'HighestPreviousFhhContributionAmount12Months': defaultCurrency,
                    'HighestPreviousFhhContributionAmount24Months': defaultCurrency,
                    'HighestPreviousFhhContributionAmount36Months': defaultCurrency,
                    'MostRecentFhhContributionAmount': defaultCurrency,
                    'MostRecentFhhContributionAmount12Months': defaultCurrency,
                    'MostRecentFhhContributionAmount24Months': defaultCurrency,
                    'MostRecentFhhContributionAmount36Months': defaultCurrency,
                    'AverageFhhContributionAmount': defaultCurrency,
                    'FirstFhhContributionAmount': defaultCurrency,
                    'TotalAmountOfFhhAttributedContributions': defaultCurrency,
                    'TotalAmountOfFhhContributionsLast365Days': defaultCurrency,
                    'TotalAmountOfFhhContributionsLastYear': defaultCurrency,
                    'TotalAmountOfFhhContributionsTwoYearsAgo': defaultCurrency,
                    'TotalFhhContributionAmountYTD': defaultCurrency,
                    'TotalOfFhhContributions': defaultCurrency,
                    'AskAmount': defaultCurrency,
                    'CommittedAmount': defaultCurrency,
                    'ContributionTaxDeductibleAmount': defaultCurrency,
                    'ContributionAmount': defaultCurrency
                };

                var currencyFormattedFields = _.map(currencyFormattedFieldDeclarations, function (currencyExpression, mergeField) {
                    return amountMergeField(mergeField, '', currencyExpression);
                 });

                var yearEndGiftsMergeField = [
                    {
                        key: "YearEndGiftReceipt",
                        introPrompt: localizedText.modalYearEndGiftsIntro,
                        outroPrompt: "",
                        defaultSubtitle: localizedText.modalYearEndDefaultSubtitle,
                        isConditionalField: false,
                        defaultLabel: localizedText.modalYearEndDefaultLabel,
                        skipBraces: false,
                        entitySelection: {
                            label: localizedText.modalDesignationsLabel,
                            entities: fetchedDesignations,
                            missingText: localizedText.modalMissingDesignations,
                            requiredText: localizedText.modalDesignationRequired,
                            allowMultiSelect: true,
                            autoSelectEnabled: true,
                            includeHumanReadable: false,
                            selectSubtitle: localizedText.modalYearEndSelectSubtitle
                        },
                        properties: [
                            {
                                label: 'Status',
                                type: 'inline-radio',
                                options: [
                                    { label: 'Settled', key: 'Settled', selected: 'true' },
                                    { label: 'Settled & Pending', key: 'SettledPending' }
                                ],
                                subtitle: localizedText.modalYearEndRadioSubtitle
                            },
                            {
                                label: localizedText.modalYearEndColumnSelectionLabel,
                                type: 'checkbox-grid',
                                options: [
                                    {
                                        colGroup: [
                                            { label: 'Contribution Date', key: 'contribdate', selected: 'true', disabled: 'true' },
                                            { label: 'Amount', key: 'amount', selected: 'true', disabled: 'true' },
                                            { label: 'Name on Gift', key: 'name', selected: 'true'}
                                        ]
                                    },
                                    {
                                        colGroup: [
                                            { label: 'Tax Deductible Amount', key: 'deductamount', selected: 'true'},
                                            { label: 'Type', key: 'type', selected: 'true'},
                                            { label: 'Contribution ID', key: 'contributionid', selected: 'true' }
                                        ]
                                    }
                                ],
                                description: localizedText.modalYearEndColumnDescription
                            }
                        ],
                        callbacks: {
                            onBeforeInsert: function(result) {
                                var yeMerge = result.mergeField.split('_')[0];

                                // Append settlement status
                                yeMerge += '_' + result.properties[0];

                                // Append designation Ids
                                if (result.fieldOptions.selectedEntity) {
                                    if (_.isArray(result.fieldOptions.selectedEntity) && result.fieldOptions.selectedEntity.length > 0) {
                                        yeMerge += '_' + _(result.fieldOptions.selectedEntity).map('Id').filter().value().join('_');
                                    } else {
                                        yeMerge += '_' + result.fieldOptions.selectedEntity.Id;
                                    }
                                }

                                // Append column specification
                                if (result.properties.length !== 7) {
                                    // Append columns
                                    yeMerge += '_cols_' + result.properties.slice(1).join('_');
                                }

                                result.mergeField = yeMerge;
                            }
                        }
                    }];

                var themeMergeFieldsKeyedDefaults = [
                    {
                        key: "EmailContent",
                        disableDefault: true
                    }
                ];

                var emailContextKeyedDefaults = [
                    {
                        key: "IsSentByTargetedEmail",
                        isConditionalField: true,
                        contentTemplate: conditionalContentTemplate,
                        introPrompt: localizedText.isSentByTargetedEmailModalDescription,
                        outroPrompt: ''
                    }
                ];

                //setup fancy advocacy stuff (only gets applied when the merge fields are present)
                var allFields = advocacyMergeFields.concat(segmentMergeFields)
                    .concat(yearEndGiftsMergeField)
                    .concat(themeMergeFieldsKeyedDefaults)
                    .concat(emailContextKeyedDefaults)
                    .concat(footerMergeFields)
					.concat(currencyFormattedFields);
                mergeFieldConfigProvider.setKeyedDefaults(allFields);
            }
        ]).run([
            '$http', 'ngp.email-common', function ($http, emailCommon) {

                // Grab the saved lists and searches for the segment merge field options
                $http({
                    url: "/EmailMessage/GetSegments",
                    method: "GET",
                    params: emailCommon.loadCacheBuster(null)
                }).then(function (result) {
                    var Data = result && result.data && result.data.Data;
                    if (Data && Data.length > 0) {
                        // We want to push the results onto the existing arrays without creating a new one,
                        // since it is those *instances* which are bound to the angular model
                        var lists = Data.filter(function (i) { return i.segmentType === 1; });
                        Array.prototype.push.apply(fetchedLists, lists);
                        var searches = Data.filter(function (i) { return i.segmentType === 2; });
                        Array.prototype.push.apply(fetchedSearches, searches);
                    }
                });

                $http({
                    url: "/Designation/GetDesignations",
                    method: "GET",
                    params: emailCommon.loadCacheBuster(null)
                }).then(function (result) {
                    var Data = result && result.data && result.data.Data;
                    if (Data && Data.length > 0) {
                        Data.forEach(function (designation) {
                            fetchedDesignations.push({ name: designation.Name, Id: designation.DesignationId });
                        });
                    }
                });
            }
        ]);

})(window.angular);;
angular.module('reusables.helpers', [])
.factory('reusableDropdownHelper', [function () {
    function initReusables($scope, reusables) {

        if (reusables) {
            // Reassign blank tenant name to Default for sorting and grouping purposes
            reusables.forEach(function (reusable) {
                reusable.isDefault = !reusable.TenantName || reusable.TenantName === 'Default' || reusable.TenantName === window.ngpvan.translations.Pages.defaultReusableGroup;
                if (reusable.isDefault) {
                    reusable.TenantName = window.ngpvan.translations.Pages.defaultReusableGroup || 'Default';
                } else {
                    reusable.TenantName = reusable.TenantName || window.ngpvan.translations.Pages.defaultReusableGroup || 'Default';
                }
            });
        }

        // Default reusables should appear above all other reusables in the dropdown menu
        $scope.defaultReusablesFirst = function(reusable) {
            return reusable.isDefault ? 1 : 2;
        };
    }

    return {
        init: initReusables
    };
}]);;
angular.module('templategallery.helpers', [])
    .factory('templateGalleryHelpers', ['$http', 'ngp.email-common', function ($http, common) {
        var initializeGalleryPagingAndFiltering = function($scope, pageSize, tenantId, initialTemplates, totalNumberOfTemplates, doesHaveSharedTemplates, mostRecentlyPublishedTemplates) {
            // Augment the provided scope with the properties and methods used for Template Gallery paging and filtering
            // This is shared by both User Templates and the Drag & Drop email designer.
            $scope.templateSearchText = '';
            $scope.templateTypeFilter = "1"; // default to include all types
            
            // These correspond to the above, but will only be updated after a page has finished load.
            // This way, we avoid flickering UI updates between search/type filter changes.
            $scope.templateSearchTextLoaded = $scope.templateSearchText
            $scope.templateTypeFilterLoaded = $scope.templateTypeFilter;
            
            $scope.currentPage = 1;
            $scope.pageSize = pageSize;
            $scope.totalNumberOfTemplates = totalNumberOfTemplates;

            $scope.clearTemplateSearchText = function() {
                $scope.templateSearchText = '';
                $scope.filterTemplateBySearchCriteria();
            }

            $scope.filterTemplateBySearchCriteria = function() {
                $scope.currentPage = 0;
                $scope.loadNextPageOfTemplates();
            }

            var mapTemplateViewModel = function (template, index) {
                return {
                    "id": index,
                    "reusableId": template.Id,
                    "name": template.Title,
                    "thumbnail": template.ThumbnailLink,
                    "preview": template.PreviewLink,
                    "description": template.Description,
                    "tenantId": template.TenantId,
                    "tenantName": template.TenantName,
                    "isShared": template.TenantId && template.TenantId !== tenantId,
                    "isDefault": template.ReusableStatus === 0,  // Default
                    "modifiedBy": template.ModifiedBy,
                    "modifiedOn": template.ModifiedOn
                };
            }

            $scope.loadNextPageOfTemplates = function () {
                if ($scope.currentPage !== 0 && $scope.currentTemplates.length === $scope.totalNumberOfTemplates) {
                    // Do nothing, you have already reached the last page
                    return;
                }

                $scope.currentPage = $scope.currentPage + 1;

                // Store the current state so we can compare once the results come back
                var nameSearch = $scope.templateSearchText,
                    filtering = $scope.templateTypeFilter,
                    page = $scope.currentPage;

                $http({
                    method: 'GET',
                    url: '/Template/GetLightweightJsonTemplatesForGallery',
                    params: common.loadCacheBuster({
                        nameSearch: nameSearch,
                        filtering: filtering,
                        pageNumber: page,
                        pageSize: $scope.pageSize
                    })
                }).then(function (results) {
                    // If any of the filter criteria have changed, throw away these results assuming we have already
                    // launched a new request
                    if ($scope.templateSearchText !== nameSearch ||
                        $scope.templateTypeFilter !== filtering ||
                        $scope.currentPage !== page) {
                        return;
                    }

                    $scope.templateSearchTextLoaded = $scope.templateSearchText;
                    $scope.templateTypeFilterLoaded = $scope.templateTypeFilter;
                    
                    var pageData = results.data;
                    var newTemplates = pageData.Data.map(mapTemplateViewModel);
                    if ($scope.currentPage === 1) {
                        $scope.currentTemplates = newTemplates;
                        $(".template-library-thumbnails").scrollTop(0);
                    } else {
                        $scope.currentTemplates = $scope.currentTemplates.concat(newTemplates);
                    }
                    $scope.totalNumberOfTemplates = pageData.TotalRows;
                });
            };

            $scope.currentTemplates = initialTemplates.map(mapTemplateViewModel);
            $scope.hasSharedTemplates = doesHaveSharedTemplates;
            $scope.mostRecentlyPublishedTemplates = mostRecentlyPublishedTemplates.map(mapTemplateViewModel);
        };
        
        return {
            init: initializeGalleryPagingAndFiltering
        };
    }]);;
var module = angular.module('ngp.smartlink.service', []);
module.factory('urlValidator', [function() {
   
    var factory = {};

    factory.validateUrl = function (url, urlRequirements) {
            if (url == undefined) {
                return { isValid: false };
            }

        var regex = urlRequirements.validationRegex ? cleanValidationRegex(urlRequirements.validationRegex) : '^https?:\/\/|mailto:|tel:';

            url = url.replace(/\s*$/, "");
            if (url.length > urlRequirements.maxUrlLength) {
                return { isValid: false, message: urlRequirements.maxLengthErrorMessage };
            }

            if (!new RegExp(regex).test(url)) {
                return { isValid: false, message: urlRequirements.badUrlErrorMessage };
            }
            return { isValid: true };
        };

        // strip the leading and ending forward slash from regex string if it exists
        function cleanValidationRegex(validationRegex) {
            if (validationRegex.charAt(0) === '/') {
                validationRegex = validationRegex.substring(1);
            }
            if (validationRegex.charAt(validationRegex.length - 1) === '/') {
                validationRegex = validationRegex.substring(0, validationRegex.length - 1);
            }
            return validationRegex;
        }

        return factory;
}]);

module.factory('smartlinkModelFactory', [function() {
    var modelFactory = {};
    modelFactory.createNew = function(initialSmartLinkType, labels, actBlueEntityId, smartLinksConstants, triggeredEmailType, hasApplyLimitsFeature) {
        return {
            /**
             * object for capturing url information and error messages
             */
            smartLinkType: initialSmartLinkType,
            urlInfo: {
                url: undefined,
                urlErrorMessage: undefined,

                isUrlEmpty: function() {
                    return this.url == undefined || this.url.length == 0;
                },

                reset: function() {
                    this.url = undefined;
                    this.urlErrorMessage = undefined;
                }
            },
            /**
             * object for storing form/page related information
             */
            form: {
                selectedForm: undefined,
                sspStartingTab: smartLinksConstants.welcome,
                canShowLinkDirectlyRadioButtons: false,
                linkDirectlyToFailingCommitmentModal: false,
                isEmbeddedContributionForm: false,
                enableFastAction: false,
                enableOneClickSubmission: false,
                hasApplyLimitsFeature: hasApplyLimitsFeature,
                formChanged: function () {
                    this.enableFastAction = false;
                    this.enableOneClickSubmission = false;
                    if (this.isSelfServicePage()) {
                        if (this.isWelcomeTabEnabled()) {
                            this.sspStartingTab = smartLinksConstants.welcome;
                        } else if (this.isContributionsTabEnabled()) {
                            this.sspStartingTab = smartLinksConstants.contributions;
                        } else if (this.isContactInfoTabEnabled()) {
                            this.sspStartingTab = smartLinksConstants.contactInfo;
                        }
                    }

                    // together with sspStartingTab == contributions, this decides ng-show for the "link directly" radio buttons.
                    // we also check this when the query string is created, just to be sure
                    this.canShowLinkDirectlyRadioButtons =
                        triggeredEmailType === smartLinksConstants.recurringCommitmentFailureTriggeredEmailTypeId &&
                        this.isSelfServicePage() &&
                        this.isContributionsTabEnabled() &&
                        this.isManageRecurringCommitmentsEnabled() &&
                        this.isUpdatePaymentMethodEnabled();

                    if (this.canShowLinkDirectlyRadioButtons) {
                        // set initial / default value for the "link directly" radio buttons
                        this.linkDirectlyToFailingCommitmentModal = true;
                    }
                },

                // Self service portal page methods
                isSelfServicePage: function () {
                    return this.selectedForm && this.selectedForm.IsSelfService;
                },
                areSspTabsEnabled: function() {
                    return this.isWelcomeTabEnabled() ||
                        this.isContributionsTabEnabled() ||
                        this.isContactInfoTabEnabled();
                },
                isWelcomeTabEnabled: function() {
                    return this.selectedForm && this.selectedForm.IsSspWelcomeTabEnabled;
                },
                isContributionsTabEnabled: function() {
                    return this.selectedForm && this.selectedForm.IsSspContributionsTabEnabled;
                },
                isContactInfoTabEnabled: function() {
                    return this.selectedForm && this.selectedForm.IsSspContactInfoTabEnabled;
                },
                isManageRecurringCommitmentsEnabled: function () {
                    return this.selectedForm && this.selectedForm.IsSspManageRecurringCommitmentsEnabled;
                },
                isUpdatePaymentMethodEnabled: function() {
                    return this.selectedForm && this.selectedForm.IsSspUpdatePaymentMethodEnabled;
                },
                isDeprecatedSelfServicePortal: function() {
                    return this.selectedForm &&
                        this.selectedForm.EntityType === smartLinksConstants.formEntityId &&
                        this.selectedForm.EntityTypeName === labels.selfServicePortal;
                },
                isFastActionEnabled: function() {
                    return (this.selectedForm && this.selectedForm.EnableFastActionAutoProcessing) ||
                        this.isEmbeddedContributionForm;
                },
                // checks whether the form is either a Contribution Form or Optimized Contribution Form
                isContributionForm: function() {
                    return this.selectedForm && (this.selectedForm.EntityTypeName === labels.contributionEntityName || this.selectedForm.EntityTypeName === labels.optimizedContributionEntityName) ;
                },
                isOptimizedContributionForm: function() {
                    return this.selectedForm && this.selectedForm.EntityTypeName === labels.optimizedContributionEntityName ;
                },
                isUnsubscribePage: function() {
                    return this.selectedForm && this.selectedForm.IsUnsubscribe;
                },
                reset: function() {
                    this.selectedForm = undefined;
                    this.enableFastAction = false;
                    this.enableOneClickSubmission = false;
                    this.isEmbeddedContributionForm = false;
                    this.sspStartingTab = 1;
                    this.canShowLinkDirectlyRadioButtons = false;
                    this.linkDirectlyToFailingCommitmentModal = false;
                },
                // returns an array of query string parameters
                getQueryStrings: function(smartLinkType) {
                    var queryStrings = [];

                    if (this.enableFastAction && (this.isContributionForm() || this.isEmbeddedContributionForm)) {
                        queryStrings.push('tknfa={{AutoProcessToken}}');
                    }

                    var isSspPageOrForm = false;
                    if (this.isDeprecatedSelfServicePortal()) {
                        queryStrings.push('secureToken={{SecureToken}}');
                        isSspPageOrForm = true;
                    }

                    if (this.isSelfServicePage()) {
                        queryStrings.push('accessCode={{SecureToken}}');
                        if (this.areSspTabsEnabled()) {
                            queryStrings.push('sspStartingTab=' + smartLinksConstants[this.sspStartingTab]);
                        }
                        isSspPageOrForm = true;
                    }
                    
                    if (this.canShowLinkDirectlyRadioButtons
                        && this.sspStartingTab === smartLinksConstants.contributions
                        && this.linkDirectlyToFailingCommitmentModal) {
                        queryStrings.push('directLinkFailedPaymentConfirmationId={{PaymentConfirmationID}}');
                    }
                        
                    if (this.isUnsubscribePage()) {
                        // The triple brackets are intentional - this merge field needs to be pre-escaped so it can be used
                        // correctly in the list-unsubscribe header as well.
                        queryStrings.push('unsubscribedata={{{UnsubscribeData}}}')
                    }

                    var isSelectedFormAPage = this.selectedForm && this.selectedForm.EntityType == 2;

                    if (!isSspPageOrForm
                        && !isSelectedFormAPage
                        && smartLinkType !== smartLinksConstants.externalUrlLinkType) {
                        queryStrings.push('contactdata={{ContactData}}');
                    }

                    if (this.enableOneClickSubmission &&
                        !this.isEmbeddedContributionForm &&
                        !this.isContributionForm()) {
                        queryStrings.push('quick=true');
                    }

                    return queryStrings;
                }
            },

            /**
             * ContributionInfo
             *
             * captures 
             */
            contributionInfo: {
                minimumAmount: '20.00',
                multiplier: 1,
                amountField: undefined,
                applyLeftToGive: true,
                form: undefined,
                reset: function() {
                    this.minimumAmount = '20.00';
                    this.multiplier = 1;
                    this.applyLeftToGive = true;
                },
                isMinimumAmountValid: function() {
                    return this.minimumAmount && this.minimumAmount > 0;
                },
                isMultiplierValid: function() {
                    return this.multiplier && this.multiplier > 0;
                },
                isContributionValid: function() {
                    return this.isMinimumAmountValid() && this.isMultiplierValid();
                },
                getQueryStrings: function(shouldExcludeRecurringQueryStrings = false) {
                    var queryStrings = [];

                    if (this.amountField && this.amountField.id) {
                        if (this.amountField.id == "OneTimeDefaultOptimizedAskAmount") {

                            queryStrings = [
                                'am={{round_min_max(zero_if_null(' 
                                + this.amountField.id + ')*' + this.multiplier 
                                + ',1,' 
                                + this.minimumAmount 
                                + ',2500)}}',
                            ];

                            queryStrings.push("amtOpts={{OneTimeOptimizedAskArray}}");

                            if (!shouldExcludeRecurringQueryStrings)
                            {
                                queryStrings.push("recurringAm={{round_min_max(zero_if_null(RecurringDefaultOptimizedAskAmount)*1,1," + this.minimumAmount + ",2500)}}");
                                queryStrings.push("recurringAmtOpts={{RecurringOptimizedAskArray}}");
                            }

                            queryStrings.push("is_optimized_ask=true")


                            // Only append left_to_give if all required values are present and it's a valid contribution form
                            if (hasApplyLimitsFeature &&
                                this.applyLeftToGive && 
                                this.form && 
                                this.form.selectedForm && 
                                this.form.selectedForm.DesignationId != null && 
                                this.form.selectedForm.Cycle != null && 
                                this.form.selectedForm.PeriodId != null) {
                                queryStrings.push('left_to_give={{LeftToGive_' + this.form.selectedForm.DesignationId + '_' + this.form.selectedForm.Cycle + '_' + (this.form.selectedForm.PeriodId + 2) + '}}');
                            }
                        } else {
                            queryStrings = [
                                'am={{round_min_max(zero_if_null(' +
                                this.amountField.id +
                                ')*' +
                                this.multiplier +
                                ',1,' +
                                this.minimumAmount +
                                ',2500)}}'
                            ];
                        }
                    } else {
                        queryStrings = ['am=' + this.minimumAmount];
                    }

                    return queryStrings;
                }
            },
            /**
             *  Conversion Tracking
             */
            conversionTracking: {
                enabled: true,
                isActBlueTracking: false,
                reset: function() {
                    this.enabled = true;
                },
                getQueryStrings: function () {
                    if (this.isActBlueTracking) {
                        return this.enabled ? ['refcode2={{DistributionId}}'] : [];
                    }
                   
                    return !this.enabled ? ['{{notrack}}'] : undefined;
                }
            },
            // helper methods
            formName: function () {
                return this.form.selectedForm
                    ? this.form.selectedForm.EntityTypeName + ':' + this.form.selectedForm.PageName
                    : undefined;
            },
            isEmbeddedContributionForm: function () {
                return this.form.isEmbeddedContributionForm;
            },
            isActBlue: function () {
                var regex = new RegExp("^[^.]*?\\/\\/(" + labels.actBlueDomain + ")", 'i');
                regex.ignoreCase = true;
                return regex.test(this.urlInfo.url);
            },
            canTrackActBlue: function () {
                return !!actBlueEntityId && actBlueEntityId != false;
            },
            url: function () {
                return this.urlInfo.url ? this.urlInfo.url : undefined;
            },

            // resets the smartlink object to its default values
            reset: function() {
                this.urlInfo.reset();
                this.form.reset();
                this.contributionInfo.reset();
                this.conversionTracking.reset();
            },
            // generates the smart link from the query string methods
            // of the contained object
            assembleLink: function() {
                var link = this.urlInfo.url ? this.urlInfo.url : this.form.selectedForm.UserFacingUrl;

                var existingLinkParts = this.GetExistingLinkParts(link.trim());

                var hasContribution =
                    (this.smartLinkType == smartLinksConstants.formOrPageLinkType && this.form.isContributionForm()) ||
                    (this.smartLinkType == smartLinksConstants.embeddedFormLinkType && this.isEmbeddedContributionForm());

                var queryStrings = existingLinkParts.queryStrings
                    .concat((hasContribution ? this.contributionInfo.getQueryStrings(this.form.isOptimizedContributionForm()) : []))
                    .concat(!this.form.isUnsubscribePage() ? this.conversionTracking.getQueryStrings() : [])
                    .concat(this.form.getQueryStrings(this.smartLinkType))
                    .filter(function(queryString) {
                        return queryString != undefined;
                    }).join('&');

                return existingLinkParts.url +
                    (queryStrings !== undefined && queryStrings.length > 0 ? '?' + queryStrings : '') +
                    existingLinkParts.formatAnchor();
            },

            // if the link entered has querystrings or anchors, preserve them
            // and return an object with link, querystrings and anchor separated
            GetExistingLinkParts: function(link)
            {
                var splitOnAnchors = link.split('#');
                var linkAndQueryString = splitOnAnchors[0];
                // assuming only 1 anchor is present
                var anchor = splitOnAnchors.length > 1 ? splitOnAnchors[1] : '';

                // split existing link on ? to get the plain link and 
                var urlParts = linkAndQueryString.split('?');

                var existingQueryStrings = [];

                // parse out each querystring into an array
                if (urlParts.length > 1) {
                    existingQueryStrings = urlParts.slice(1).map(function (queryString) {
                        return queryString.split('&');
                    });

                    existingQueryStrings = existingQueryStrings.reduce(function (flatten, val) {
                        return flatten.concat(val);
                    });
                }

                // remove any querystrings that are undefined or empty strings
                existingQueryStrings = existingQueryStrings.filter(function (queryString) {
                    return queryString != undefined && queryString.length > 0;
                });

                var toReturn = {
                    url: urlParts[0],
                    queryStrings: existingQueryStrings,
                    anchor: anchor,
                    formatAnchor: function() {
                        return this.anchor != undefined && this.anchor.length > 0 ? '#' + this.anchor : '';
                    }
                };
                return toReturn;
            }
        };
    };

    return modelFactory;
}]);

module.factory('formsService', ['$http', function($http) {
    var formsService = {
        formsPagesList: undefined,
        areFormsLoading: false,
        loadPromise: null,

        getForms: function() {
            // If we're already loading, return the existing promise
            if (this.areFormsLoading) {
                return this.loadPromise;
            }
            
            // If we already have the forms, return a resolved promise
            if (this.formsPagesList) {
                return Promise.resolve(this.formsPagesList);
            }

            // Otherwise, load the forms
            this.areFormsLoading = true;
            this.loadPromise = $http({
                url: "/ReadOnlyForms/GetForms",
                method: "GET",
            }).then(function(result) {
                formsService.areFormsLoading = false;
                formsService.formsPagesList = result.data;
                return result.data;
            }, function() {
                formsService.areFormsLoading = false;
                console.error("Error loading forms from view");
            });

            return this.loadPromise;
        }
    };

    return formsService;
}]);;
var directivesModule = angular.module('ngp.directives');

directivesModule.directive('queryStringSourceCodeTree', 
    function ($timeout) {
        function initializeSourceCodeTree($scope) {
            var variantId = $scope.variantId;
            var hideTree = $scope.hideTree;

            // setting timeout of zero postpones this function until all of the angular dom binding are finished
            // without this the code tree div cannot be found
            $timeout(function () {
                var tree = ngpVan.codeTree();
                var settings =
                {
                    'entityTypes': 'OnlineForms',
                    'applyAllEntities': true,
                    'selectedNodeIdsForLoadAndPost': 'SourceCodeId' + variantId,
                    'renderNode': function (event, data) {
                        if (data.node.data.applicability && data.node.data.applicability < 2
                        ) { // Entity applicability. 2 is applicable and searchable. 1 is searchable-only
                            data.node.unselectable = true;
                            data.node.renderStatus();
                        }
                    },
                    'initialLoadHandler': function (event, theTree) {
                        var count = theTree.count();
                        if (!count || count === 0) {
                            var noSourceCodesMarkup = '<div><p id="NoSourceCodes" class="text-info">' +
                                $scope.noSourceCodesLabel +
                                '</p></div>';
                            $("#" + theTree.options.treeViewContainerId).parent().html(noSourceCodesMarkup);
                        }
                        if (hideTree) {
                            $('#' + settings.treeViewDropdownId).hide();
                        }
                        event.stopPropagation();
                    },
                    'containerId': 'treeContainerId' + variantId,
                    'idPrefix': 'ft' + variantId + '_',
                    'selectedNodesIdsElementId': 'selectedNodes' + variantId,
                    'treeViewContainerId': 'treeViewContainer' + variantId,
                    'treeId': 'TreeId' + variantId,
                    'treeViewDropdownId': 'treeViewDropdownId' + variantId,
                    'endpointUrl': '/EmailMessage/RetrieveCodesPaged',
                    'filterBoxId': 'filterBoxId' + variantId,
                    'debounceInterval': 300,
                    //'pageSize':500,
                    'selectedNodeIdPrefix': 'selectedNodeValueTag' + variantId,
                    'blockUiElementId': 'treeview-dropdown' + variantId,
                };
                tree.initSingleSelect(settings);
            },
                0);
        }

        return {
            restrict: 'E',
            scope: { variantId: '=', sourceCodeId: '=', onSourceCodeChanged: '&', hideTree: '=', noSourceCodesLabel: '=' },
            link: initializeSourceCodeTree,
            templateUrl: function() {
                return '/Content/angular/querystring-source-code-tree-template.html';
            },
            controller: [
                '$scope',
                function queryStringSourceCodeTreeController($scope) {
                    $scope.localSourceCodeId = $scope.sourceCodeId;
                    $scope.sourceCodeTreeOptionChanged = function() {
                        $scope.onSourceCodeChanged({ newSourceCodeId: $scope.localSourceCodeId });
                    };
                }
            ]
        };
    });

directivesModule.directive('clearAllQueryStringConfirmModal',

    function () {
        var modalController = ['$scope', function ($scope) {
        }];
        return {
            restrict: 'E',
            scope: { onConfirm: '&', onCancel: '&', variantId: '=', labels: '=', linkTitle: '=', confirmLabel: '=', cancelLabel: '=', confirmMessage: '=' },

            template: '<a class="remove-all" id="variant_{{variantId}}_removeAll"  ng-click="openModal()">{{linkTitle}}</a>',
            controller: ['$scope', '$uibModal',
                function clearAllQueryStringConfirmModalController(
                    $scope,
                    $uibModal) {
                    $scope.modalInstance;
                    $scope.cancelModal = function () {
                        $scope.modalInstance.close();
                        if ($scope.onCancel) {
                            $scope.onCancel();
                        }
                    },
                        $scope.confirmModal = function () {
                            $scope.modalInstance.close();
                            if ($scope.onConfirm) {
                                $scope.onConfirm();
                            }
                        },
                        $scope.openModal = function () {
                            $scope.modalInstance = $uibModal.open({
                                scope: $scope,
                                controller: modalController,
                                templateUrl: '/Content/angular/clear-all-querystring-confirmation-modal-template.html',
                                backdrop: 'static',
                                keyboard: true
                            });
                        }
                }]
        }
    });

directivesModule.directive('querystringTracker',
    function () {
        function intializeQueryStringOptions($scope) {
            var endpoint = "../../EmailMessage/QueryStringOptionsAndLabels";
            $.get(endpoint).done(function (results) {
                var parsedResults = JSON.parse(results);
                $scope.labels = parsedResults.Labels;
                $scope.queryStringOptions = parsedResults.QueryStringOptions;
                $scope.QueryStringOptions = [
                    {
                        id: 0, // Used for sorting
                        name: $scope.queryStringOptions.SourceCode,
                        encodedName: 'sourceid',
                        value: '',
                    },
                    {
                        id: 1,
                        name: $scope.queryStringOptions.MarketSourceCode,
                        encodedName: 'ms',
                        maxlen: 150,
                        value: '',
                    },
                    {
                        id: 2,
                        name: $scope.queryStringOptions.UTMCampaign,
                        encodedName: 'utm_campaign',
                        maxlen: 250,
                        value: ''
                    },
                    {
                        id: 3,
                        name: $scope.queryStringOptions.UTMMedium,
                        encodedName: 'utm_medium',
                        maxlen: 250,
                        value: ''
                    },
                    {
                        id: 4,
                        name: $scope.queryStringOptions.UTMSource,
                        encodedName: 'utm_source',
                        maxlen: 250,
                        value: ''
                    },
                    {
                        id: 5,
                        name: $scope.queryStringOptions.Custom,
                        customName: '',
                        maxlen: 250,
                        value: ''
                    }
                ];

                $scope.buildQueryStringState($scope.variant);
            });
        }

        return {
            restrict: 'E',
            // formChanged: callback to notify parent that query string information has changed
            // description: description of the purpose of the track your efforts
            // variant: reference to the variant that the query strings are being added to / removed from
            // panelClass: css class name added to wrapping div
            scope: { formChanged: '&', isTotalQueryStringLengthInvalid: '&' , description: '@', variant: '=', panelClass: '@' },
            link: {
                pre: intializeQueryStringOptions
            },
            controller: ['$scope', function trackYourEffortsController($scope) {
                
                $scope.Model = {
                    selectedQueryStringOption: undefined
                };

                $scope.queryStringOptions = {};
                $scope.labels = {};

                $scope.generateId = function () {
                    return Math.floor(Math.random() * 1000000000);
                };

                $scope.getValidationMessage = function (message, subst) {
                    if (!message) {
                        return '';
                    }
                    return message.replace('{0}', subst);
                };

                $scope.findQueryStringOption = function(optionName) {
                    return $scope.QueryStringOptions.find(function(option) {
                        return option.name.toLowerCase() === optionName.toLowerCase();
                    });
                };

                $scope.getNumCustomQueryStrings = function () {
                    return $scope.variant.queryStringOptions.filter(function (option) {
                        return option.name === $scope.queryStringOptions.Custom;
                    }).length;
                };

                $scope.buildQueryStringState = function (variant) {
                    if (variant.Content.CustomQueryStrings && variant.Content.CustomQueryStrings.trim().length > 0) {
                        // When loading the page, build the arrays based on the above constant and whatever we have stored on the variant (from the database)
                        variant.queryStringOptions = variant.Content.CustomQueryStrings.split('&').map(function (item) {
                            // Split the query string fragment into name and value
                            var nameValueArr = item.trim().split('=');

                            var option;

                            // Look for non-custom query string parameters
                            switch (nameValueArr[0]) {
                                case 'sourceid':
                                    option = $scope.findQueryStringOption($scope.queryStringOptions.SourceCode);
                                    break;
                                case 'ms':
                                    option = $scope.findQueryStringOption($scope.queryStringOptions.MarketSourceCode);
                                    break;
                                case 'utm_campaign':
                                    option = $scope.findQueryStringOption($scope.queryStringOptions.UTMCampaign);
                                    break;

                                case 'utm_medium':
                                    option = $scope.findQueryStringOption($scope.queryStringOptions.UTMMedium);
                                    break;
                                case 'utm_source':
                                    option = $scope.findQueryStringOption($scope.queryStringOptions.UTMSource);
                                    break;
                                default:
                                    option = $scope.findQueryStringOption(nameValueArr[0].trim());
                                    break;
                            }

                            if (!option) {
                                // Custom Query String
                                option = $scope.findQueryStringOption($scope.queryStringOptions.Custom);
                            }
                            // Make a deep copy
                            var newOption = JSON.parse(JSON.stringify(option));
                            switch (newOption.name) {
                                case $scope.queryStringOptions.Custom:
                                    // Custom query strings have a 'custom' name property which is editable
                                    newOption.customName = nameValueArr[0].trim();
                                    // Generate a new id for custom options, so we can differentiate between instances
                                    newOption.id = $scope.generateId();
                                    break;
                                case $scope.queryStringOptions.SourceCode:
                                    // The source code picker will fetch the selected code when it initializes.
                                    newOption.sourceCodeId = nameValueArr[1].trim();
                                    break;
                                default:
                                    break;
                            }

                            // Set the value based on the stored db value
                            if (nameValueArr[1]) {
                                newOption.value = nameValueArr[1].trim();
                            }
                            return newOption;
                        });
                    } else {
                        variant.queryStringOptions = [];
                    }

                    // Now build copies of the remaining (available) query strings and add them to each variant if they are not already present
                    variant.availableQueryStringOptions = [];
                    // Go over baseline query options.  Add those that aren't already on the model
                    $scope.QueryStringOptions.forEach(function (option) {
                        //Make a deep copy
                        let optionCopy = JSON.parse(JSON.stringify(option));
                        //Add it to the available query string options if it's not already selected as a query string
                        if (!variant.queryStringOptions.find(function (opt) {
                            return opt.id === optionCopy.id && opt.name !== $scope.queryStringOptions.Custom;
                        })) {
                            // When rebuilding the state, don't add custom query string to options if we're already maxed out
                            if (optionCopy.name === $scope.queryStringOptions.Custom && $scope.getNumCustomQueryStrings(variant.VariantId) == 10) {
                                return;
                            }
                            variant.availableQueryStringOptions.push(optionCopy);
                        }
                    });
                };

                // This is called whenever an option is selected
                $scope.queryStringOptionSelected = function () {
                    // Keep track of how many 'Custom' query strings are present.
                    var numCustomQueryStrings = $scope.getNumCustomQueryStrings();

                    // Remove the option from the available set unless it's Custom.
                    // However, it's ok to remove the 'Custom' option if there are already 9 and we are adding a 10th.
                    $scope.variant.availableQueryStringOptions = $scope.variant.availableQueryStringOptions.filter(function (option) {
                        // Remove option, unless it is a custom query string
                        return option.id !== $scope.Model.selectedQueryStringOption.id || (option.name === $scope.queryStringOptions.Custom && numCustomQueryStrings < 9);
                    });

                    if ($scope.Model.selectedQueryStringOption.name == $scope.queryStringOptions.Custom) {
                        // Always make a deep copy of custom options, because there can be many instances per variant
                        let optionCopy = JSON.parse(JSON.stringify($scope.Model.selectedQueryStringOption));
                        // Generate a new id for custom options, so we can differentiate between instances
                        optionCopy.id = $scope.generateId();

                        $scope.variant.queryStringOptions.push(optionCopy);
                    } else {
                        $scope.variant.queryStringOptions.push($scope.Model.selectedQueryStringOption);
                    }

                    //Now update the form field that gets sent down with the POST
                    // But, don't update yet if it's a Source Code.  Wait until one is selected from the source code dropdown
                    if ($scope.Model.selectedQueryStringOption.name !== $scope.queryStringOptions.SourceCode) {
                        $scope.updateQueryStringField();
                    }

                    // Don't care that same model is used across variants for this.  It's just for UI management.
                    $scope.Model.selectedQueryStringOption = undefined;
                };

                // This is called when the X is clicked next to a query string option
                $scope.removeQueryString = function (variantId, removedOption) {
                    // Get number of custom query strings in use

                    var numCustomQueryStrings = $scope.getNumCustomQueryStrings(variantId);

                    $scope.variant.queryStringOptions = $scope.variant.queryStringOptions.filter(function (option) {
                        return option.id !== removedOption.id;
                    });

                    // If num custom query strings was 10, then we removed the option, so we might need to reAdd it
                    if (removedOption.name !== $scope.queryStringOptions.Custom || (removedOption.name === $scope.queryStringOptions.Custom && numCustomQueryStrings >= 10)) {
                        $scope.variant.availableQueryStringOptions.push(removedOption);
                        // Reset it
                        removedOption.value = '';
                        // If we're readding the custom query string
                        if (removedOption.name == $scope.queryStringOptions.Custom) {
                            // Clear the custom name
                            removedOption.customName = '';
                            // set the id back to 5
                            removedOption.id = 5;
                        }
                        if (removedOption.name == $scope.queryStringOptions.SourceCode) {
                            delete removedOption.sourceCodeId;
                        }
                    }

                    $scope.variant.availableQueryStringOptions.sort((left, right) => {
                        return left.id - right.id;
                    });

                    //Now update the form field that gets sent down with the POST
                    $scope.updateQueryStringField();
                };

                $scope.updateQueryStringField = function () {
                    // We don't want to update the stored query string with any duplicates or custom strings with empty custom names
                    var validOptions = $scope.variant.queryStringOptions.reduce((acc, qs) => {
                        // Don't include customs where the name is not set
                        if (qs.name === $scope.queryStringOptions.Custom && qs.customName.length === 0) {
                            return acc;
                        }
                        // Look for duplicate query string name or custom name
                        if (acc.find(function (option) {
                            if (option.name === $scope.queryStringOptions.Custom && qs.name === $scope.queryStringOptions.Custom) {
                                return option.customName === qs.customName;
                            } else if (option.name == $scope.queryStringOptions.Custom) {
                                return option.customName === qs.name;
                            }
                            return option.name == qs.name;
                        }) != null) {
                            return acc;
                        }
                        // No duplicates or otherwise invalids found so add query string to valid array
                        acc.push(qs);
                        return acc;
                    }, []);

                    //Now update the form field that gets sent down with the POST
                    $scope.variant.Content.CustomQueryStrings =
                        validOptions.reduce((acc, qs) => {
                            switch (qs.name) {
                                case $scope.queryStringOptions.Custom:
                                    return acc + qs.customName + '=' + qs.value + '&';
                                case $scope.queryStringOptions.SourceCode:
                                    return acc + qs.encodedName + '=' + (qs.sourceCodeId && qs.sourceCodeId.length > 0 ? qs.sourceCodeId : "") + '&';
                                case $scope.queryStringOptions.UTMCampaign:
                                case $scope.queryStringOptions.UTMMedium:
                                case $scope.queryStringOptions.UTMSource:
                                    return acc + qs.encodedName + '=' + (qs.value ? qs.value.toLowerCase() : '') + '&';
                                default:
                                    return acc + qs.encodedName + '=' + qs.value + '&';
                            }
                        },
                            // Initialize the accumulator to an empty string
                            '').replace(/&+$/, ''); // Replace any trailing ampersand

                    // This ensures that the autosave is triggered when the hidden form field has been cleared
                    $scope.formChanged();

                };

                $scope.sourceCodeUpdated = function (newSourceCodeId) {
                    var sourceCodeQueryStringOption = $scope.variant.queryStringOptions.find(
                        function (queryStringOption) {
                            return queryStringOption.name === $scope.queryStringOptions.SourceCode;
                        });

                    if (sourceCodeQueryStringOption) {
                        sourceCodeQueryStringOption.sourceCodeId = newSourceCodeId;
                        $scope.updateQueryStringField();
                    }
                };

                $scope.removeAllQueryStringsCallback = function () {
                    removeAllQueryStrings($scope, $scope.variant.VariantId);
                };

                // This is called when removeAll is clicked
                function removeAllQueryStrings($scope) {
                    $scope.variant.queryStringOptions = [];
                    $scope.variant.availableQueryStringOptions = [];
                    $scope.variant.Content.CustomQueryStrings = '';
                    $scope.buildQueryStringState($scope.variant);
                    $scope.updateQueryStringField();
                };
                
                $scope.queryStringOptionSourceCodeSelected = function (option, variantId) {
                    $scope.updateQueryStringField(variantId);
                };

                $scope.findQueryStringOption = function (optionName) {
                    return $scope.QueryStringOptions.find(function (option) {
                        return option.name.toLowerCase() === optionName.toLowerCase();
                    });
                };

                // if each variant should display its own total length validation message
                /*$scope.IsTotalQueryStringLengthInvalid = function(maxLength) {
                    return $scope.variant.Content.CustomQueryStrings.length > maxLength;
                };*/
            }],
            templateUrl: function () {
                return '/Content/angular/querystring-tracker-template.html';
            }
        };
    });;
var directivesModule = angular.module('ngp.directives');

// component for handling the Online Actions Forms and Page smartlink option
directivesModule.directive('smartlinksOnlineActionFormsPage',
    function () {
        return {
            restrict: 'E',
            scope: { variantId: '=', labels: '=', stepInfo: '=', suggestedAmountTypes: '=', smartLink: '=', constants: '=' },
            controller: [
                '$scope', function smartlinksOnlineActionFormsPageController($scope) {
                    $scope.showFastActionInstruction = false;
                    $scope.$watch('smartLink.form',
                        function () {
                            $scope.stepInfo.isStepValid = validate();
                        },
                        true);

                    $scope.$watch('smartLink.form.selectedForm',
                        function() {
                            $scope.smartLink.form.formChanged();
                        });

                    // listen for changes to a contribution forms validity 
                    // and update the app to reflect it
                    $scope.onContributionValidityChange = function (isContributionValid) {
                        $scope.stepInfo.isStepValid = isContributionValid;
                    };

                    // validate the step before the link is inserted
                    $scope.$on('finish_' + $scope.variantId, function (event, args) {
                        if ($scope.smartLink.form.enableFastAction && $scope.stepInfo.step === 1) {
                            $scope.stepInfo.step = 2;
                        } else {
                            if (validate()) {
                                args.onSuccess();
                            }
                        }
                    });

                    // validate that a form was selected and if the form is a contribution form
                    // that it's data is correct
                    function validate() {
                        $scope.stepInfo.isStepValid =
                            $scope.smartLink.form.selectedForm != undefined &&
                            (!$scope.smartLink.form.isContributionForm() ||
                            $scope.smartLink.contributionInfo.isContributionValid());

                        return $scope.stepInfo.isStepValid;
                    }
                }
            ],
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-online-actions-forms-pages-template.html';
            }
        };
    });

// component for handling the Embedded Online Actions Form Smart Link option
directivesModule.directive('smartlinksEmbeddedForm',
    function() {
        return {
            restrict: 'E',
            scope: { labels: '=', smartLink: '=', stepInfo: '=', urlInfo: '=', variantId: '=', suggestedAmountTypes: '=', urlRequirements: '='},
            controller: [
                '$scope', 'urlValidator', 'formsService', function smartLinksEmbeddedFormController($scope, urlValidator, formsService) {
                    $scope.showErrorMessage = true;
                    $scope.formsPagesList = formsService.formsPagesList;
                    $scope.areFormsLoading = formsService.areFormsLoading;

                    // Always try to load forms, but the service will handle deduplication
                    formsService.getForms().then(function(forms) {
                        $scope.formsPagesList = forms;
                    });

                    $scope.isEmbeddedContributionFormChanged = function() {
                        $scope.smartLink.form.enableOneClickSubmission = false;
                        // When user marks it as a contribution form, look up the form metadata
                        if ($scope.smartLink.form.isEmbeddedContributionForm && $scope.smartLink.urlInfo.url) {
                            var matchingForm = $scope.formsPagesList.find(function(form) {
                                return form.FormUrl === $scope.smartLink.urlInfo.url;
                            });
                            if (matchingForm) {
                                $scope.smartLink.form.selectedForm = matchingForm;
                                $scope.smartLink.form.formChanged();
                            }
                        }
                    };

                    $scope.validState =
                    {
                        isUrlValid: false,
                        isContributionValid: false,
                        isValid: function() {
                            return this.isUrlValid &&
                                (!$scope.smartLink.isEmbeddedContributionForm() || this.isContributionValid);
                        }

                    };
                    // callback passed to url component for notifications of whether a url is valid or not
                    $scope.onUrlValidityChanged = function (isValid) {
                        $scope.validState.isUrlValid = isValid;
                        $scope.stepInfo.isStepValid = $scope.validState.isValid();
                    };

                    // callback passed to contribution component for notifications of whether a contribution is valid or not
                    $scope.onContributionValidityChange = function (isContributionValid) {
                        
                        $scope.validState.isContributionValid = isContributionValid;
                        $scope.stepInfo.isStepValid = $scope.validState.isValid();
                    };

                    // listen for parent container button click, and revalidate all inputs.
                    // validation happens on input blur, but on the off chance that the blur does not fire
                    // fast enough, still want to validate the inputs when the insert button is clicked
                    $scope.$on('finish_' + $scope.variantId, function (event, args) {
                        if ($scope.smartLink.form.enableFastAction && $scope.stepInfo.step === 1) {
                            $scope.stepInfo.step = 2;
                        } else {
                            if (validate()) {
                                // onSuccess will passed in from parent, will trigger link assembly and insertion
                                args.onSuccess();
                            }
                        }
                    });

                    // check that the url entered is valid and if contribution data is included that it is also valid
                    function validate() {
                        $scope.stepInfo.isStepValid = false;
                        $scope.stepInfo.isStepValid = validateUrl() &&
                        (
                            !$scope.smartLink.isEmbeddedContributionForm ||
                            $scope.smartLink.contributionInfo.isContributionValid()
                        );
                        return $scope.stepInfo.isStepValid;
                    }

                    // validate that the url is not empty and abides by length and regex requirements
                    // passed into $scope.urlSettiurlRequirementsngs
                    function validateUrl() {
                        var validationResult = urlValidator.validateUrl($scope.smartLink.urlInfo.url, $scope.urlRequirements);
                        $scope.smartLink.urlInfo.urlErrorMessage = validationResult.message;
                        $scope.stepInfo.isStepValid = validationResult.isValid;

                        return validationResult.isValid;
                    };
                   
                }
            ],
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-embedded-form-template.html';
            }
        };
    });

// Component for handling the External URL SmartLink option
directivesModule.directive('smartlinksExternalUrl',
    function () {
        return {
            restrict: 'E',
            scope: { variantId: '=', labels: '=', urlRequirements: '=', stepInfo: '=', smartLink: '=' },
            controller: ['$scope', 'urlValidator', function trackYourEffortsController($scope, urlValidator) {
                
                $scope.urlInfo = { url: undefined },
                $scope.showErrorMessage = true;

                // callback to be notified when the validity of the url has changed,
                // this is used to notify the app that whether or not to enable/disable insert
                $scope.onUrlValidityChanged = function (isValid) {
                    $scope.stepInfo.isStepValid = isValid;
                };

                // validate the step before the link is inserted
                $scope.$on('finish_' + $scope.variantId, function (event, args) {
                    
                    if ($scope.validateUrl()) {
                        args.onSuccess();
                    }
                });

                // validate that the url is not empty and abides by length and regex requirements
                // passed into $scope.urlRequirements
                $scope.validateUrl = function () {
                    var validationResult = urlValidator.validateUrl($scope.smartLink.urlInfo.url, $scope.urlRequirements);
                    $scope.smartLink.urlInfo.urlErrorMessage = validationResult.message;
                    $scope.stepInfo.isStepValid = validationResult.isValid;

                    return validationResult.isValid;
                };

            }],
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-external-url-template.html';
            }
        };
    });

// Component for handling handling Online Action Forms that are Self Service Pages.  Input is capture 
// 
//labels: string resource used for rendering the component
// page: the form object used to capture details about the Self Service Page (ie starting tab preference)
// constants: 
directivesModule.directive('smartlinksLinkToSelfServicePage',
    function() {
        return {
            restrict: 'E',
            scope: { labels: '=', page: '=', constants: '='},
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-self-service-page-template.html';
            }
        };
    });

// Component for toggling recurring commitment failure emails linking directly to SSP update payment method modal
//
//labels: string resource used for rendering the component
// page: the form object used to capture details about the Self Service Page (ie starting tab preference)
// constants:
directivesModule.directive('smartlinksLinkDirectlyToFailingCommitmentModal',
    function () {
        return {
            restrict: 'E',
            scope: {labels: '=', page: '='},
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-link-directly-to-failing-commitment-modal-template.html';
            }
        };
    })

// Component for handling handling One Click Submission option.
// 
// labels: string resource used for rendering the component
// form: the form object used to capture the one click submission flag
directivesModule.directive('smartlinksOneClickSubmission',
    function() {
        return {
            restrict: 'E',
            scope: { labels: '=', form: '=' },
            controller: [function smartLinksOneClickSubmissionController() {

            }],
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-one-click-submission-template.html';
            }
        };
    });

directivesModule.directive('smartlinksContributionForm',
    function() {
        return {
            restrict: 'E',
            scope: { variantId: '=', labels: '=', contributionInfo: '=', suggestedAmountTypes: '=', form:'=', isFastActionEnabled:'=', onValidityChange:'=' },
            controller: [
                '$scope', function smartlinksContributionFormController($scope) {

                    // set the default selected values when the component loads
                    $scope.suggestedAmountType =
                    {
                        selected: $scope.suggestedAmountTypes[0]
                    };

                    $scope.contributionInfo.amountField = $scope.suggestedAmountType.selected;
                    $scope.contributionInfo.form = $scope.form;

                    // if amount type changes, reset the entered values
                    $scope.amountTypeChanged = function() {
                        $scope.resetMultiplier();
                        $scope.contributionInfo.amountField = $scope.suggestedAmountType.selected;
                    };

                    // listen for changes to the inputs fields (min amount and multiplier)
                    // and notify listener that the validity of the form has changed
                    $scope.$watch('contributionInfo',
                        function () {
                            validateAndFormatMinimumAmount();
                            validateMultiplier();

                            //notify caller that the contribution is either valid or invalid
                            if ($scope.onValidityChange) {
                                $scope.onValidityChange(!$scope.errors.hasErrors());
                            }
                        },
                        true);

                    // manages the different error scenarios for a contribution
                    $scope.errors =
                    {
                        minimumRequiredError: false,
                        minimumRangeError: false,
                        multiplierRequiredError: false,
                        multiplierRangeError: false,
                        isMultiplierError: function() {
                            return this.multiplierRangeError || this.multiplierRequiredError;
                        },
                        isMinimumError: function() {
                            return this.minimumRequiredError || this.minimumRangeError;
                        },
                        hasErrors: function() {
                            return this.isMultiplierError() || this.isMinimumError();
                        },
                        reset: function() {
                            this.minimumRequiredError = false;
                            this.minimumRangeError = false;
                            this.multiplierRequiredError = false;
                            this.multiplierRangeError = false;
                        }
                    };

                    // resets the input fields and errors of the component
                    $scope.resetMultiplier = function() {
                        $scope.contributionInfo.reset();
                        $scope.errors.reset();
                    };

                    // validates that the minimum amount is present and between 3 and 999999.9
                    // after
                    function validateAndFormatMinimumAmount() {
                        $scope.errors.minimumRequiredError = false;
                        $scope.errors.minimumRangeError = false;
                        $scope.contributionInfo.minimumAmount = $scope.contributionInfo.minimumAmount.replace(/,/g, '');

                        if (isEmpty($scope.contributionInfo.minimumAmount)) {
                            $scope.errors.minimumRequiredError = true;
                        } else if (isNotInRange($scope.contributionInfo.minimumAmount, 3, 999999.99)) {
                            $scope.errors.minimumRangeError = true;
                        }

                        if (!isEmpty($scope.contributionInfo.minimumAmount)) {
                            $scope.contributionInfo.minimumAmount =
                                formatMinimumAmount($scope.contributionInfo.minimumAmount);
                        }
                    }

                    // validates that the multiplier is not empty and between the range .1 and 5
                    function validateMultiplier() {
                        $scope.errors.multiplierRequiredError = false;
                        $scope.errors.multiplierRangeError = false;

                        if (isEmpty($scope.contributionInfo.multiplier)) {
                            $scope.errors.multiplierRequiredError = true;
                        } else if (isNotInRange($scope.contributionInfo.multiplier, 0.1, 5)) {
                            $scope.errors.multiplierRangeError = true;
                        }
                    }

                    function isEmpty(valueToTest) {
                        return valueToTest === undefined || valueToTest === null || valueToTest.toString().trim() === "";
                    }
                  
                    function isNotInRange(valueToTest, lowRange, highRange) {
                        return isEmpty(valueToTest) || valueToTest < lowRange || valueToTest > highRange;
                    }

                    // formats the minimum amount to add commas and 2 decimal point
                    function formatMinimumAmount(minimumAmount) {
                        var split = minimumAmount.split('.');
                        var csv = split[0];
                        var decimal = split.length > 1 ? split[1] : "";
                        if (csv.length >= 5) {
                            var commaIndex = csv.length % 3;
                            if (commaIndex == 0) { commaIndex = 3; }
                            while (commaIndex < csv.length) {
                                csv = csv.slice(0, commaIndex) + ',' + csv.slice(commaIndex);
                                commaIndex = commaIndex + 4;
                            }
                        }
                        if (decimal.length < 2) {
                            decimal = decimal + '0'.repeat(2 - decimal.length);
                        }
                        return csv + '.' + decimal;
                    }
                }
            ],
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-contribution-form-template.html';
            }
        };
    });

// Captures Fast Action Enablement is the option for fast action is allowed
//
// isFastActionEnabled: flag to enable disable fast action checkbox
// form: object to capture whether to enable fastaction on the smartlink
directivesModule.directive('smartlinksSuggestedAskAmount',
    function() {
        return {
            restrict: 'E',
            scope: { labels: '=', isFastActionEnabled:'=', form: '='},
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-suggested-ask-amount-template.html';
            }
        };
    });

// Component for querying the available forms and presenting the dropdown list for selection
// the selected form is stored in form.selectedForm property
//
//
directivesModule.directive('smartlinksFormsSelector',
    function() {
        return {
            restrict: 'E',
            scope: { variantId: '=', labels: '=', stepInfo: '=', form: '=' },
            controller: ['$scope', 'formsService', function smartlinksFormsSelectorController($scope, formsService) {
                $scope.formsPagesList = formsService.formsPagesList;
                $scope.areFormsLoading = formsService.areFormsLoading;

                // Always try to load forms, but the service will handle deduplication
                formsService.getForms().then(function(forms) {
                    $scope.formsPagesList = forms;
                });

                $scope.selectedForm =
                {
                    selected: $scope.form.selectedForm
                };

                $scope.isFormsPageListEmpty = function() {
                    return !$scope.formsPagesList || $scope.formsPagesList.length == 0;
                };

                $scope.placeholderText = function() {
                    if ($scope.isFormsPageListEmpty()) {
                        return $scope.areFormsLoading
                            ? $scope.labels.loadingForms
                            : $scope.labels.noPublishedFormsFound;
                    }
                    return '';
                };

                $scope.$watch('selectedForm.selected',
                    function () {
                        $scope.stepInfo.isStepValid = $scope.selectedForm.selected != undefined;
                        $scope.form.selectedForm = $scope.selectedForm.selected;
                    });

                $scope.getForms = function() {
                    formsService.getForms().then(function(forms) {
                        $scope.formsPagesList = forms;
                    });
                };

                // show fast action not enabled warning if the form does not allow fast action
                // and it is a contribution form
                $scope.showFastActionNotEnabledWarning = function() {
                    return $scope.selectedForm &&
                        !$scope.selectedForm.EnableFastActionAutoProcessing &&
                        $scope.selectedForm.EntityTypeName === 'Contribution';
                };

                $scope.getForms();
            }],
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-forms-selector-template.html';
            }
        };
    });

// component for capturing and validating a url
// 
// urlInfo: input for capturing the url and passing any error messages
// urlRequirements: settings for what constitutes a valid url
// onUrlValidityChanged: callback for to notify that the url is valid or invalid
directivesModule.directive('smartlinksUrlEntry',
    function() {
        return {
            restrict: 'E',
            scope: { urlInfo: '=', urlRequirements: '=', variantId: '=', showErrorMessage: '=', placeholderText: '=', onUrlValidityChanged:'=' },
            controller: ['$scope', 'urlValidator', function smartlinksUrlEntryController($scope, urlValidator) {
                $scope.errorMessage = undefined;
               
                // if url passed in has an error message, display it first
                $scope.$watch('urlInfo.urlErrorMessage',
                    function() {
                        if ($scope.urlInfo.urlErrorMessage) {
                            $scope.errorMessage = $scope.urlInfo.urlErrorMessage;
                        } 
                    });

                // validates the url whenever it is changed (onblur)
                $scope.validateUrl = function() {
                    var validationResult = urlValidator.validateUrl($scope.urlInfo.url, $scope.urlRequirements);
                    $scope.errorMessage = validationResult.message;
                    if ($scope.onUrlValidityChanged) {
                        $scope.onUrlValidityChanged(validationResult.isValid);
                    }
                };

                $scope.validateUrl();
            }],
            templateUrl: function() {
                return '/Content/angular/templates/smartlinks-url-entry-template.html';
            }
        };
    });

// component for capturing conversion tracking flags both actblue and non-actblue
//
// isActBlue: is the url that is being worked on an ActBlue url
// canTrackActBlue:  can the current user use the track act blue option
// conversionTracking: object used to capture the tracking decision
directivesModule.directive('smartlinksConversionCheckbox',
    function () {
        return {
            restrict: 'E',
            scope: { variantId: '=', isActBlue: '=', canTrackActBlue: '=', conversionTracking: '=', labels: '=' },
            controller: ['$scope', function smartlinksConversionCheckbox($scope) {
                $scope.$watch('isActBlue',
                    function() {
                        $scope.conversionTracking.isActBlueTracking = $scope.isActBlue && $scope.canTrackActBlue;
                    });
            }],
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-conversion-checkbox-template.html';
            }
        };
    });

// component for capturing conversion tracking flags both actblue and non-actblue
//
// isActBlue: is the url that is being worked on an ActBlue url
// canTrackActBlue:  can the current user use the track act blue option
// conversionTracking: object used to capture the tracking decision
directivesModule.directive('smartlinksFastActionInstruction',
    function () {
        return {
            restrict: 'E',
            scope: { variantId: '=', isActBlue: '=', canTrackActBlue: '=', conversionTracking: '=', labels: '=' },
            controller: ['$scope', function smartlinksFastActionInstruction($scope) {
                
            }],
            templateUrl: function () {
                return '/Content/angular/templates/smartlinks-fast-action-instruction-template.html';
            }
        };
    });;
var directivesModule = angular.module('ngp.directives');

directivesModule.directive('updateEmailDetails',
    function () {
        return {
            restrict: 'E',
            scope: { isGroupEmail: '=', linkText: '=', labels: '=', links: '=', email: '=', canDetailsBeUpdated: '=', sessionKey: '=', successfulUpdateCallback: '=' },
            controller: ['$scope', '$window', 'ngp.email-common', '$uibModal', '$http',
                function ($scope, $window, common, $uibModal) {

                    $scope.canDetailsBeUpdated = $scope.canDetailsBeUpdated;
                    var selectedAskType = null;
                    var selectedCampaignId = null;
                    var selectedAskTypeName = null;
                    var selectedCampaignName = null;

                    var modalInstance;

                    $scope.cancelModal = function (originalName, originalGroupName) {
                        modalInstance.dismiss('cancel');
                        if (originalName) {
                            $scope.email.Name = originalName;
                        }
                        if (originalGroupName) {
                            $scope.email.EmailMessageSendGroupName = originalGroupName;
                        }
                    };

                    $scope.openEditEmailNameModal = function (inputEmail) {
                        modalInstance = this.openModal('/Content/angular/templates/edit-email-details.html', 'small', inputEmail);
                    }

                    $scope.openModal = function (template, size, inputEmail, validationLink) {
                        if (validationLink == null) {
                            validationLink = $scope.links.validateEmailNameLink
                        }
                        $scope.warningShow = 'hide';
                        $scope.email.originalName = $scope.email.Name;
                        $scope.originalName = $scope.email.Name;
                        $scope.originalAskTypeName = $scope.email.AskTypeName;
                        $scope.originalCampaignName = $scope.email.CampaignName;
                        $scope.originalGroupName = $scope.email.EmailMessageSendGroupName;
                        $scope.EmailMessageSendGroupNameUpdated = $scope.email.EmailMessageSendGroupName;
                        $scope.EmailMessageNameUpdated = $scope.isGroupEmail ? $scope.email.EmailMessageSendGroupName : $scope.email.Name;
                        
                        $scope.getAskTypes();
                        $scope.getCampaigns();
                        var modalInstance = $uibModal.open({
                            scope: $scope,
                            templateUrl: template,
                            backdrop: 'static',
                            keyboard: true,
                            size: size,
                            resolve: {
                                validateNameLink: function () {
                                    return validationLink;
                                },
                                'email': function () {
                                    return inputEmail;
                                },
                                'askTypes': function () {
                                    return $scope.askTypes;
                                },
                                updateEmailNameLink: function () {
                                    return $scope.updateEmailNameLink;
                                },
                                updateEmailDetailsLink: function () {
                                    return $scope.updateEmailDetailsLink;
                                }
                            }
                        });
                        return modalInstance;
                    };

                    $scope.$on('modal.closing', function (event, reason) {
                        if (reason === 'escape key press') {
                            email.Name = event.targetScope.originalName;
                        }
                    });

                    $scope.updateEmailName = function (event, email) {
                        email.Name = this.EmailMessageNameUpdated;
                        $scope.email.Name = this.EmailMessageNameUpdated;
                        common.updateEmailName($scope, event, $scope.email, $scope.links.validateEmailNameLink, $scope.links.updateEmailNameLink, $scope.cancelModal, function (res) {
                            // failure
                            $scope.email.Name = $scope.email.originalName;
                            $scope.creationError = res && res.status === 500 ?
                                'Please remove any HTML content from the \'Email Name\'' : 'Unable to create Email. Please try again.';
                        }, $scope.labels.emailNameUpdateSuccessful, $scope.sessionKey, $window);
                    };

                    $scope.getAskTypes = function () {

                        var updateAskTypes = function (result) {
                            var localAskTypes = result.Data;
                            localAskTypes.selected = localAskTypes.find(x => x.AskTypeId == $scope.email.AskTypeId);
                            selectedAskType = $scope.email.AskTypeId;
                            selectedAskTypeName = $scope.email.AskTypeName;
                            $scope.askTypes = localAskTypes;
                            $scope.$apply();
                        };

                        $scope.askTypes = null;

                        $.ajax({
                            url: $scope.links.getAskTypesLink,
                            type: "GET",
                            success: function (result) {
                                updateAskTypes(result);
                            }
                        });
                    }

                    $scope.getCampaigns = function () {

                        var updateAvailableCampaigns = function (result) {
                            if (result.ResponseResultCode === Constants.ResponseResultCode.Success) {
                                $scope.hasCampaigns = result.Data.length > 0;
                                if ($scope.hasCampaigns) {
                                    $scope.availableCampaigns = result.Data;
                                    selectedCampaignId = $scope.email.CampaignId;
                                    selectedCampaignName = $scope.email.CampaignName;
                                    if (selectedCampaignId != null) {
                                        // If the previously saved campaign is no longer available in VAN, clear the select2 option
                                        var selectedCampaign = result.Data.filter(function (i) {
                                            return i.CampaignId === selectedCampaignId;
                                        });
                                        $scope.availableCampaigns.selected = selectedCampaign.length > 0 ? selectedCampaign[0] : null;
                                    }
                                    $scope.$apply();
                                }
                            }
                            else {
                                FeedBack.update(result);
                            }
                        }

                        // Get the available campaigns on page load
                        $.ajax({
                            url: "/EmailMessage/GetCampaigns",
                            method: "GET",
                            params: common.loadCacheBuster(null)
                        }).then(function (result) {
                            updateAvailableCampaigns(result);
                        });
                    }

                    $scope.updateEmailDetails = function (event, email) {
                        email.Name = this.EmailMessageNameUpdated;
                        $scope.email.Name = this.EmailMessageNameUpdated;
                        $scope.email.AskTypeName = selectedAskTypeName;
                        $scope.email.CampaignName = selectedCampaignName;
                        $scope.email.AskTypeId = selectedAskType;
                        $scope.email.CampaignId = selectedCampaignId;
                        common.updateEmailDetails($scope, event, email, $scope.links.validateEmailNameLink, $scope.links.updateEmailDetailsLink, $scope.cancelModal, function (res) {
                            // failure
                            email.Name = $scope.email.originalName;
                            email.AskTypeName = $scope.email.originalAskTypeName;
                            email.CampaignName = $scope.email.originalCampaignName;
                            $scope.creationError = res && res.status === 500 ?
                                'Please remove any HTML content from the \'Email Name\'' : 'Unable to update Email. Please try again.';
                        },
                        $scope.labels.emailUpdateSuccessful, $scope.sessionKey, $window);
                    };

                    $scope.selectAskType = function (item) {
                        selectedAskType = item ? item.AskTypeId : null;
                        selectedAskTypeName = item ? item.Name : 'Not selected';
                    }

                    $scope.selectCampaign = function (item) {
                        selectedCampaignId = item ? item.CampaignId : null;
                        selectedCampaignName = item ? item.CampaignName : 'Not selected';
                    }

                    $scope.nameLabel = function () {
                        return $scope.isGroupEmail ? $scope.labels.emailGroupName : $scope.labels.emailName;
                    }

                    $scope.updateEmailGroupName = function (event, email) {
                        email.EmailMessageSendGroupName = this.EmailMessageNameUpdated;
                        common.updateEmailGroupName($scope, event, email, $scope.links.validateGroupNameLink, $scope.links.updateEmailGroupNameLink, $scope.cancelModal, function (res) {
                            // failure
                            email.EmailMessageSendGroupName = originalGroupName;
                            $scope.creationError = res && res.status === 500 ?
                                window.ngpvan.translations.Pages.removeHtmlFromEmailName : window.ngpvan.translations.Pages.unableToCreateEmail;
                        }, $scope.sessionKey, $window);
                    };
                }
            ],
            template: '<a ng-click="openEditEmailNameModal(email)" href="javascript:void(0);">{{linkText}}</a>'
        };
    });;
/*!
 * ngpvan-angular-libraries : https://github.com/NGPVAN/Angular-Libraries
 * ngpvan.ui.helpers : https://github.com/NGPVAN/Angular-Libraries/tree/master/modules/ngpvan.ui.helpers
 * Version: 1.1.12 - 2017-12-20T20:05:04.005Z
 */

(function (angular,$,_) { 
// module.js

angular.module('ngpvan.ui.helpers',[])
  .factory('attributeValueHelper', [
    function () {

      return {
        truthy: function (val) {
          return angular.isDefined(val) && (val === '' || val.toLowerCase() === 'true');
        }
      };

    }])
  .directive('compileTemplate', ['$compile', '$parse', function ($compile, $parse) {
    //src: http://stackoverflow.com/questions/25406461/angularjs-ng-bind-html-2way-data-binding
    return {
      restrict: 'A',
      link: function ($scope, element, attr) {
        var parse = $parse(attr.ngBindHtml);
        function value() { return (parse($scope) || '').toString(); }

        $scope.$watch(value, function () {
          $compile(element, null, -9999)($scope);
        });
      }
    };
  }]).directive('outsideClick', ['$document', '$parse', '$timeout', function ($document, $parse, $timeout) {
  //src: https://github.com/IamAdamJowett/angular-click-outside/blob/master/clickoutside.directive.js

  return {
    link: function ($scope, elem, attr) {

      // postpone linking to next digest to allow for unique id generation
      $timeout(function() {
        var classList = (attr.outsideIfNot !== undefined) ? attr.outsideIfNot.split(/[ ,]+/) : [],
          fn;

        function eventHandler(e) {
          var i,
            element,
            r,
            id,
            classNames,
            l;

          // check if our element already hidden and abort if so
          if (angular.element(elem).hasClass('ng-hide')) {
            return;
          }

          // if there is no click target, no point going on
          if (!e || !e.target || e.isDefaultPrevented()) {
            return;
          }

          // loop through the available elements, looking for classes in the class list that might match and so will eat
          for (element = e.target; element; element = element.parentNode) {
            // check if the element is the same element the directive is attached to and exit if so (props @CosticaPuntaru)
            if (element === elem[0]) {
              return;
            }

            // now we have done the initial checks, start gathering id's and classes
            id = element.id;
            classNames = element.className;
            l = classList.length;

            // Unwrap SVGAnimatedString classes
            if (classNames && classNames.baseVal !== undefined) {
              classNames = classNames.baseVal;
            }

            // if there are no class names on the element clicked, skip the check
            if (classNames || id) {

              // loop through the elements id's and classnames looking for exceptions
              for (i = 0; i < l; i++) {
                //prepare regex for class word matching
                r = new RegExp('\\b' + classList[i] + '\\b');

                // check for exact matches on id's or classes, but only if they exist in the first place
                if ((id !== undefined && id === classList[i]) || (classNames && r.test(classNames))) {
                  // now let's exit out as it is an element that has been defined as being ignored for clicking outside
                  return;
                }
              }
            }
          }

          // if we have got this far, then we are good to go with processing the command passed in via the click-outside attribute
          $timeout(function() {
            fn = $parse(attr.outsideClick);
            fn($scope, { event: e });
          });
        }

        // if the devices has a touchscreen, listen for this event
        if (_hasTouch()) {
          $document.on('touchstart', eventHandler);
        }

        // still listen for the click event even if there is touch to cater for touchscreen laptops
        $document.on('click', eventHandler);

        // when the scope is destroyed, clean up the documents event handlers as we don't want it hanging around
        $scope.$on('$destroy', function() {
          if (_hasTouch()) {
            $document.off('touchstart', eventHandler);
          }

          $document.off('click', eventHandler);
        });

        function _hasTouch() {
          // works on most browsers, IE10/11 and Surface
          return 'ontouchstart' in window || navigator.maxTouchPoints;
        }
      });
    }
  };
}]).directive('focusMe', ['$timeout','$parse',function ($timeout, $parse) {
  //based on watching a flag, set focus to an element
  //src: http://stackoverflow.com/questions/14833326/how-to-set-focus-on-input-field
  return {
    link: function (scope, element, attrs) {
      var model = $parse(attrs.focusMe);
      var w = scope.$watch(model, function (value) {
        if (value === true) {
          $timeout(function () {
            element[0].focus();
          });
        }
      });
      function deregister(){
        if(w){
          w();
          w = null;
        }
      }
      scope.$on('$destroy',deregister);
      element.on('destroy', deregister);

    }
  };
}]).factory('uiTextHelper', [
  function () {

    function insertTextIntoString(stringToInsert, existingString, lastCursorPosition) {
      if (existingString === null) {
        existingString = '';
      }

      if (stringToInsert === null) {
        stringToInsert = '';
      }

      if (lastCursorPosition) {
        var firstPart = existingString.substring(0, lastCursorPosition);
        var secondPart = existingString.substring(lastCursorPosition);
        return (firstPart + stringToInsert + secondPart);
      } else {
        return (stringToInsert + ' ' + existingString);
      }
    }

    function getCursorPosition(textElement) {
      if (typeof textElement === 'string') {
        textElement = $('#' + textElement)[0];
      }

      var dummyString = '#%~';
      var objRange;
      var oldRange;
      var newText;
      //IE
      var i;
      if (document.selection) {
        objRange = document.selection.createRange();
        oldRange = objRange.text;
        objRange.text = oldRange + dummyString;
        objRange.moveStart('character', (0 - oldRange.length - dummyString.length));

        newText = textElement.value;

        objRange.text = oldRange;
        
        for (i = 0; i <= newText.length; i++) {
          var sTemp = newText.substring(i, i + dummyString.length);
          if (sTemp === dummyString) {
            var cursorPos = (i - oldRange.length);
            return cursorPos;
          }
        }
      }
      //GECKO (Other Browsers)
      else if (textElement.selectionStart || textElement.selectionStart === '0') {
        var startPos = textElement.selectionStart;
        var endPos = textElement.selectionEnd;

        newText = textElement.value.substring(0, startPos) +
          dummyString + textElement.value.substring(endPos, textElement.value.length);

        for (i = 0; i < newText.length; i++) {
          var temp = newText.substring(i, i + dummyString.length);
          if (temp === dummyString) {
            return i;
          }
        }
      }
      return 0;
    }

    // Insert text into element. Supports textbox, textarea, ace editor, ck editor
    function insertText(text, editorId){
      var element = $('#' + editorId);

      if (typeof window.CKEDITOR !== 'undefined' && window.CKEDITOR && window.CKEDITOR.instances[editorId]) {
        if (window.CKEDITOR.instances[editorId].mode === 'wysiwyg') {
          window.CKEDITOR.instances[editorId].insertHtml(text);
        } else {
          // CKEditor is in source mode.  
          // When cke goes into source mode, it replaces the iframe with a textarea (nested within a div)
          // The id of the containing div is 'cke_' prepended to the editorId
          // We locate the correct text area by selecting the textarea that is a child of the ckeditor-generated id
          var textArea = $('#cke_' + editorId + ' textarea')[0];
          var caretPos = getCursorPosition(textArea);
          textArea.value = insertTextIntoString(text, textArea.value, caretPos);
          // If user doesn't exit source mode, changes are not saved
          // so, fire ck editor event that tells it to update its internal state so changes are persisted
          // Works with CKEditor 4.7.3+
          window.CKEDITOR.instances[editorId].fire('change');
        }
      } else if (typeof window.ace !== 'undefined' && window.ace && element.hasClass('code-editor') ) {
        var editor = window.ace.edit(editorId);
        editor.session.insert(editor.getCursorPosition(), text);
      } else {
        var cursorPos = getCursorPosition(editorId);
        var newString = insertTextIntoString(text, element.val(), cursorPos);
        element.val(newString);
        element.change();
      }
    }

    function insertMergeField(mergeFieldKey, defaultVal, editorId) {
      var tokenPattern = '{{' + mergeFieldKey + (defaultVal ? ' or \'' + defaultVal + '\'' : '')+ '}}';
      insertText(tokenPattern, editorId);
    }

    return {
      insertMergeField: insertMergeField,
      insertText: insertText,
      getCursorPosition: getCursorPosition
    };
  }
]);

})(window.angular, window.jQuery||window.$, window._);;
/*!
 * ngpvan-angular-libraries : https://github.com/NGPVAN/Angular-Libraries
 * ngpvan.ui.mergefields : https://github.com/NGPVAN/Angular-Libraries/tree/master/modules/ngpvan.ui.mergefields
 * Version: 1.5.3 - 2020-12-23T16:18:55.025Z
 */

(function (angular, $, _) {
    // module.js


    angular.module('ngpvan.ui.mergefields',
        [
            'ngpvan.ui.treeview',
            'ngpvan.ui.helpers',
            'ngpvan.util.localization',
            'ui.bootstrap',       //External
            'ngAnimate',          //External
            'ui.select'           //External  
        ])
        .config(['languageConfigProvider', function (languageConfigProvider) {

            // Set default language to use
            languageConfigProvider.set('ngpvan.ui.mergefields', {
                catchAllGroup: 'Other',
                dropdownLabel: 'Merge Fields',
                dropdownSearchPlaceholder: 'Search...',
                modalCancel: 'Cancel',
                modalConfirm: 'Add',
                modalXReaderText: 'Close Modal',
                modalTitle: 'Merge Fields',
                modalConditionalTemplateInclusionLabel: 'Insert with example conditional content syntax',
                modalSegmentPlaceholder: 'Choose a segment'
            });
        }])
        .provider('mergeFieldConfig', [function () {

            //Configure using: angular.module(...).config(['mergeFieldConfigProvider', function(mergeFieldConfigProvider){ ... }])

            var constants = {
                modes: {
                    tree: 'tree',
                    simple: 'simple',
                    inline: 'inline'
                },
                templates: {
                    tree: 'ngpvan.ui.mergefields/tree-dropdown.tpl.html',
                    simple: 'ngpvan.ui.mergefields/simple-dropdown.tpl.html',
                    inline: 'ngpvan.ui.mergefields/tree-inline.tpl.html'
                },
                defaults: {
                    mapperFunction: _.identity,
                    groupsMapperFunction: _.identity
                }
            };

            var config = {
                globalDefault: {},
                keyedDefaults: {},
                mapperFunction: constants.defaults.mapperFunction,
                groupsMapperFunction: constants.defaults.groupsMapperFunction,
                defaultDropdownType: constants.modes.simple
            };


            //Provider Methods

            this.setGlobalDefault = function setGlobalDefault(defaultObj) {

                config.globalDefault = defaultObj || {};

                delete config.globalDefault.key; // Be sure this value isn't being set here

            };

            this.setKeyedDefaults = function setKeyedDefaults(keyedDefaultsArray) {
                //_.indexBy -> lodash v3
                //_.keyBy -> lodash v4
                config.keyedDefaults = (_.indexBy || _.keyBy)(keyedDefaultsArray, 'key') || {};

            };

            this.setMapperFunction = function setMapperFunction(fn) {

                if (_.isFunction(fn)) {
                    config.mapperFunction = fn;
                }

            };

            this.setGroupsArrayMapperFunction = function setGroupsArrayMapperFunction(fn) {
                if (_.isFunction(fn)) {
                    config.groupsMapperFunction = fn;
                }
            };


            this.setDefaultDropdownType = function setDefaultDropdownType(type) {
                config.defaultDropdownType = type;
            };


            //Factory Functionality

            this.$get = ['languageConfig', function (languageConfig) {

                config.language = languageConfig.get('ngpvan.ui.mergefields');

                function normalizeMergeField(origMf) {
                    var mf = config.mapperFunction(origMf); // should now be { key, label, group }

                    //add keyed defaults
                    if (_.has(config.keyedDefaults, mf.key)) {
                        mf = _.defaultsDeep(mf, _.get(config.keyedDefaults, mf.key));
                    }

                    //add global defaults
                    mf = _.defaultsDeep(mf, config.globalDefault);

                    //add tree view id
                    return _.extend(mf, {
                        id: 'mergefield_' + mf.key
                    });

                }

                function normalizeMergeFieldArray(mfArr, includeGroups) {
                    //normalize merge field object & handle groups
                    var arr = [];
                    var groups = {};
                    _.forEach(mfArr, function (origMf) {
                        var mf = normalizeMergeField(origMf);
                        if (includeGroups) {
                            var g = mf.group || config.language.catchAllGroup; //catch-all

                            //if no valid group, skip it
                            if (g) {
                                mf.parentId = 'group_' + g;
                                if (!_.has(groups, mf.parentId)) {
                                    _.set(groups, mf.parentId, { id: mf.parentId, label: g });
                                }
                            }
                        }

                        arr.push(mf);
                    });

                    var groupsArr = [];
                    if (includeGroups) {
                        _.forOwn(groups, function (mfGroup) {
                            groupsArr.push(mfGroup);
                        });
                    }
                    groupsArr = config.groupsMapperFunction(groupsArr);
                    if (_.isArray(groupsArr)) {
                        arr = arr.concat(groupsArr);
                    }

                    return arr;
                }

                var factory = {
                    normalizeMergeField: normalizeMergeField,
                    normalizeMergeFieldArray: normalizeMergeFieldArray
                };

                //readonly
                Object.defineProperty(factory, 'constants', {
                    get: function () {
                        return _.cloneDeep(constants);
                    }
                });

                //readonly
                Object.defineProperty(factory, 'config', {
                    get: function () {
                        return _.cloneDeep(config);
                    }
                });

                return factory;
            }];

        }])
        .factory('mergeFieldHelper', [
            'uiTextHelper',
            function (uiTextHelper) {

                // Adds an inline lua comment describing the merge field in a human-readable way
                // e.g.  {{if --[[People in DC]] SavedSearch_57}}
                function wrapInHumanReadable(humanReadableName, mergeField) {
                    // Strip some problematic characters (square and curly brackets, dashes, and  & < and >) from the HR name
                    return '--[[' + humanReadableName.replace(/[\[\]\-<>\{\}\&]/g, '') + ']] ' + mergeField;
                }

                function formatMergeField(result, config, mergeFieldConfig) {
                    var fieldOptions = result.fieldOptions || {};
                    mergeFieldConfig = mergeFieldConfig || {};

                    // attach some stuff for any callbacks to use
                    config.skipBraces = mergeFieldConfig.skipBraces;
                    config.ifElseDefault = mergeFieldConfig.ifElseDefault;
                    config.key = result.mergeField || mergeFieldConfig.key;
                    config.label = mergeFieldConfig.label;

                    //add in properties
                    if (_.isArray(result.properties) && result.properties.length > 0) {
                        result.mergeField += '_' + result.properties.join('_');
                    }

                    if (fieldOptions.selectedSegment) {
                        result.mergeField += '_' + fieldOptions.selectedSegment.segmentId;
                    }

                    if (fieldOptions.selectedEntity) {
                        if (_.isArray(fieldOptions.selectedEntity) && fieldOptions.selectedEntity.length > 0) {
                            result.mergeField += '_' + _(fieldOptions.selectedEntity).map('Id').filter().value().join('_');
                        } else {
                            result.mergeField += '_' + fieldOptions.selectedEntity.Id;
                        }
                    }

                    if (mergeFieldConfig.callbacks && _.isFunction(mergeFieldConfig.callbacks.onBeforeInsert)) {
                        // give callback a chance to manipulate result
                        mergeFieldConfig.callbacks.onBeforeInsert(result, config);
                    }

                    // Build out the string to insert

                    var tokenPattern = result.mergeField;

                    // Add human readable names for any case which needs it
                    if (fieldOptions.humanReadableName) {
                        tokenPattern = wrapInHumanReadable(fieldOptions.humanReadableName, tokenPattern);
                    }

                    if (fieldOptions.includeTemplate && config.contentTemplate) {
                        tokenPattern = config.contentTemplate.replace('#MERGEFIELD#', tokenPattern);
                    } else if (config.ifElseDefault) {
                        // Use the {{if <key>}}<mergefield>{{else}}<default>{{end}} syntax
                        if (!config.skipBraces) {
                            tokenPattern = '{{' + tokenPattern + '}}';
                        }

                        if (result.defaultValue) {
                            tokenPattern = '{{ if ' + config.key + '}}' + tokenPattern + '{{else}}' + result.defaultValue + '{{end}}';
                        }

                    } else {

                        tokenPattern += (result.defaultValue ? ' or \'' + result.defaultValue + '\'' : '');

                        if (!config.skipBraces) {
                            tokenPattern = '{{' + tokenPattern + '}}';
                        }

                    }

                    return tokenPattern;
                }

                // handler inserts text into either a CKEditor or textarea
                // supports merge field "properties" and onBeforeInsert callback
                function formatAndInsertMergeField(result, config, mergeFieldConfig) {

                    var tokenPattern = formatMergeField(result, config, mergeFieldConfig);

                    if (mergeFieldConfig.callbacks && _.isFunction(mergeFieldConfig.callbacks.onInsert)) {
                        mergeFieldConfig.callbacks.onInsert(tokenPattern, result, config);
                    }

                    if (config.editorId) {
                        uiTextHelper.insertText(tokenPattern, config.editorId);
                    }
                }


                return {
                    formatMergeField: formatMergeField,
                    formatAndInsertMergeField: formatAndInsertMergeField
                };

            }]);


    // dropdown.js


    angular.module('ngpvan.ui.mergefields')
        .directive('mergeFieldDropdown', [
            'mergeFieldModal',
            'mergeFieldConfig',
            'mergeFieldHelper',
            'attributeValueHelper',
            function (mergeFieldModal, mergeFieldConfig, mergeFieldHelper, attributeValueHelper) {
                //See top of file for usage documentation

                function determineMode(attrs) {

                    var m = attrs.dropdownType || mergeFieldConfig.config.defaultDropdownType || '';

                    switch (m.toLowerCase()) {
                        case 'simple':
                        case 'basic':
                            return mergeFieldConfig.constants.modes.simple;
                        case 'tree':
                        case 'groups':
                        case 'grouped':
                            return mergeFieldConfig.constants.modes.tree;
                        case 'inline-tree':
                            return mergeFieldConfig.constants.modes.inline;
                        default:
                            return mergeFieldConfig.constants.modes.simple;
                    }
                }

                function determineTemplate(attrs) {
                    var mode = determineMode(attrs);
                    switch (mode) {
                        case mergeFieldConfig.constants.modes.simple:
                            return mergeFieldConfig.constants.templates.simple;
                        case mergeFieldConfig.constants.modes.tree:
                            return mergeFieldConfig.constants.templates.tree;
                        case mergeFieldConfig.constants.modes.inline:
                            return mergeFieldConfig.constants.templates.inline;
                        default:
                            return mergeFieldConfig.constants.modes.simple;
                    }
                }

                return {

                    restrict: 'E',
                    scope: true,
                    templateUrl: function (elem, attrs) {
                        return attrs.templateUrl || determineTemplate(attrs);
                    },
                    link: function (scope, elem, attrs) {

                        scope.mergeFieldDropdown = {
                            mergeFieldList: [],
                            dropdownSearchPlaceholder: attrs.dropdownSearchPlaceholder || mergeFieldConfig.config.language.dropdownSearchPlaceholder,
                            dropdownLabel: attrs.dropdownLabel || mergeFieldConfig.config.language.dropdownLabel,
                            orderBy: attrs.orderBy || 'label'
                        };
                        var controlId = null;

                        //Do not prompt for Default value (effectively skipping the modal)
                        // however, if the Merge field has properties defined, modal will still open
                        var disableDefault = attributeValueHelper.truthy(attrs.disableDefault);

                        // Reinitialize the fields on a watch expression, as well as a specific event
                        function reinitFields(fields) {
                            scope.mergeFieldDropdown.mergeFieldList =
                                mergeFieldConfig.normalizeMergeFieldArray(fields,
                                    determineMode(attrs) === mergeFieldConfig.constants.modes.tree ||
                                    determineMode(attrs) === mergeFieldConfig.constants.modes.inline);
                        }

                        scope.$watch(attrs.mergeFields, function (val) {
                            reinitFields(val);
                        });

                        scope.$on('ngpvan.ui.mergefields.reinit', function (event, args) {
                            if (!args.id || attrs.id === args.id) {
                                reinitFields(args.newFields);
                            }
                        });

                        scope.$watch(attrs.controlId, function (val) {
                            controlId = val || attrs.controlId;
                        });


                        scope.clickedMergeField = function (mf) {

                            if ((disableDefault || mf.disableDefault) && (!_.isArray(mf.properties) || !_.some(mf.properties))) {
                                //default is disabled and there are no properties to configure, just insert it

                                return mergeFieldHelper.formatAndInsertMergeField({
                                    mergeField: mf.key,
                                    defaultValue: mf.defaultValue || '',
                                },
                                    {
                                        editorId: controlId
                                    }, mf);
                            }

                            if (mf.callbacks && _.isFunction(mf.callbacks.onOpenDetailsModal)) {
                                mf.callbacks.onOpenDetailsModal();
                            }

                            var cancelled = null;
                            if (mf.callbacks && _.isFunction(mf.callbacks.onDismissDetailsModal)) {
                                cancelled = mf.callbacks.onDismissDetailsModal;
                            }

                            return mergeFieldModal(_.extend(mf, {
                                editorId: controlId,
                                animate: determineMode(attrs) !== mergeFieldConfig.constants.modes.inline
                            }), _.partialRight(mergeFieldHelper.formatAndInsertMergeField, mf), cancelled);
                        };

                        scope.mergeFieldItemId = function (mf) {
                            return controlId + '_mf_' + mf.key;
                        };

                    }

                };

            }

        ]);

    // modal.js

    //Code needed for the Merge Field Modal

    angular.module('ngpvan.ui.mergefields')
        .controller('MergeFieldModalCtrl', [
            '$scope',
            'modalInstanceConfig',
            '$uibModalInstance',
            'mergeFieldConfig',
            function ($scope, modalInstanceConfig, $uibModalInstance, mergeFieldConfig) {

                $scope.language = _.cloneDeep(mergeFieldConfig.config.language);
                var config = $scope.config = _.cloneDeep(modalInstanceConfig);
                //Expects:
                // key
                // label
                // introPrompt
                // outroPrompt
                // defaultLabel (optional, will use mergeFieldName as fallback)
                // disableDefault
                // properties (object array)
                // callbacks { onPropertyChange: fn(Key, prop, option, value, config) }

                //properties array objects:
                // label
                // type : 'radio' or 'checkbox'
                // options (object array)

                //options array objects
                // label
                // key: property value
                // selected

                $scope.input = {
                    defaultValue: '',
                    includeTemplate: !!config.isConditionalField
                };

                //if there is an initial default, initialize to that
                if (config.defaultValue) {
                    $scope.input.defaultValue = config.defaultValue;
                }

                //initialize the properties
                _.forEach(config.properties, function (propConfig, idx) {

                    if (propConfig.type === 'radio' || propConfig.type === 'inline-radio') {

                        var defaultSelected = _.findLast(propConfig.options, { selected: true });
                        if (defaultSelected) {
                            propConfig.$value = defaultSelected.key;
                        } else {
                            propConfig.$value = _.get(_.first(propConfig.options), 'key');
                        }
                    } else if (propConfig.type === 'checkbox') {

                        _.forEach(propConfig.options, function (opt) {
                            opt.$value = !!opt.selected;
                        });

                    } else if (propConfig.type === 'checkbox-grid') {
                        _.forEach(propConfig.options, function (opt) {
                            _.forEach(opt.colGroup, function (tableEntry) {
                                tableEntry.$value = !!tableEntry.selected;
                            });
                        });
                    }

                    propConfig.$inputName = propConfig.type + '-' + idx;

                });


                if (!config.callbacks) {
                    config.callbacks = {};
                }

                function validateProperties() {
                    var props = [];
                    _.forEach(config.properties, function (prop) {

                        var hasValue = false;
                        if ((prop.type === 'radio' || prop.type === 'inline-radio') && prop.$value) {
                            props.push(prop.$value); //key of selected option
                            hasValue = true;
                        } else if (prop.type === 'checkbox') {
                            _.forEach(prop.options, function (opt) {
                                if (opt.$value) {
                                    props.push(opt.key);
                                    hasValue = true;
                                }
                            });
                        } else if (prop.type === 'checkbox-grid') {
                            _.forEach(prop.options, function (opt) {
                                _.forEach(opt.colGroup, function (tableEntry) {
                                    if (tableEntry.$value) {
                                        props.push(tableEntry.key);
                                        hasValue = true;
                                    }
                                });
                            });
                        }

                        //validate
                        if (!hasValue && prop.required) {
                            prop.$invalid = true;
                        } else {
                            //valid!
                            prop.$invalid = false;
                        }

                    });
                    return props;
                }

                function isInvalid() {
                    return _.some(config.properties, '$invalid');
                }
                $scope.isInvalid = isInvalid;

                //callbacks
                $scope.checkboxPropertyChanged = function checkboxPropertyChanged(prop, opt) {
                    if (_.isFunction(config.callbacks.onPropertyChange)) {
                        config.callbacks.onPropertyChange(config.key, prop, opt, opt.$value ? opt.key : '', config);
                    }
                    validateProperties();
                };

                $scope.radioPropertyChanged = function radioPropertyChanged(prop, opt) {
                    if (_.isFunction(config.callbacks.onPropertyChange)) {
                        config.callbacks.onPropertyChange(config.key, prop, opt, prop.$value, config);
                    }
                    validateProperties();
                };

                $scope.hasAttemptedSubmit = false;

                //if using the entity selector with autoselect enabled, preselect if there is only one option to select from
                if (config.entitySelection && config.entitySelection.autoSelectEnabled && config.entitySelection.entities && config.entitySelection.entities.length === 1) {
                    $scope.input.selectedEntity = [config.entitySelection.entities[0]];
                }

                //confirm
                $scope.modalConfirm = function () {
                    $scope.hasAttemptedSubmit = true;
                    var props = validateProperties();

                    var fieldOptions = {};
                    if (config.segmentSelection) {
                        if ($scope.segmentSelectionInputs.$invalid) {
                            return;
                        }
                        if ($scope.input.selectedSegment) {
                            fieldOptions.selectedSegment = $scope.input.selectedSegment;
                            fieldOptions.humanReadableName = $scope.input.selectedSegment.name;
                        }
                    }

                    if (config.entitySelection) {
                        if ($scope.entitySelectionInputs.$invalid) {
                            return;
                        }

                        if ($scope.input.selectedEntity) {
                            fieldOptions.selectedEntity = $scope.input.selectedEntity;
                            if (config.entitySelection.includeHumanReadable) {
                                fieldOptions.humanReadableName = $scope.input.selectedEntity.name;
                            }
                        }
                    }

                    if (config.isConditionalField) {
                        fieldOptions.includeTemplate = $scope.input.includeTemplate;
                    }

                    if (isInvalid()) {
                        return; //no bueno
                    }

                    $uibModalInstance.close({ defaultValue: $scope.input.defaultValue, properties: props, fieldOptions: fieldOptions });
                };

                $scope.modalCancel = function () {
                    $uibModalInstance.dismiss('cancel');
                };

            }])
        .factory('modalInstanceConfig', [
            function () {
                //default modal configuration
                return {};
            }])
        .factory('mergeFieldModal', [
            '$uibModal',
            'mergeFieldHelper',
            function ($uibModal, mergeFieldHelper) {
                //See top of file for usage documentation

                //config expects: Name, Key & editorId
                function confirm(config, callback, canceled) {

                    config = config || {};
                    callback = callback || mergeFieldHelper.formatAndInsertMergeField;

                    var m = $uibModal.open({
                        keyboard: true,
                        animation: config.animate == null ? true : config.animate,
                        controller: 'MergeFieldModalCtrl',
                        templateUrl: config.templateUrl || 'ngpvan.ui.mergefields/modal.tpl.html',
                        size: config.size || 'small',
                        resolve: {
                            //Override default configuration
                            'modalInstanceConfig': function () {
                                return config;
                            }
                        }
                    });


                    m.result.then(
                        function (res) {
                            //confirmed
                            if (callback) {
                                var result = {
                                    mergeField: config.key,
                                    defaultValue: res.defaultValue,
                                    properties: res.properties,
                                    fieldOptions: res.fieldOptions
                                };
                                callback(result, config);
                            }
                        },
                        function () {
                            //dismissed
                            if (canceled)
                                canceled();
                        }
                    );
                }

                return confirm;

            }
        ]);

    angular.module("ngpvan.ui.mergefields").run(["$templateCache", function ($templateCache) {
        $templateCache.put("ngpvan.ui.mergefields/modal.tpl.html", "<header class=\"modal-header panel-header\"><h6 class=\"panel-title\">{{language.modalTitle}}</h6><nav class=\"panel-nav\"><button type=\"button\" class=\"btn btn-link dismiss\" ng-click=\"modalCancel();\"><span aria-hidden=\"true\">&times;</span><span class=\"reader-only\">{{language.modalXReaderText}}</span></button></nav></header><div class=\"modal-body panel-content\"><p class=\"modal-intro\" ng-show=\"config.introPrompt\">{{config.introPrompt}}</p><div class=\"modal-property-group input-unit\" ng-show=\"config.entitySelection\" ng-form=\"entitySelectionInputs\"><div class=\"grid-half\"><div class=\"clearfix\"><label for=\"staticEntity\" class=\"radio-label\"><strong>{{config.entitySelection.label}}<span class=\"required text-red\">*</span></strong></label></div></div><div class=\"modal-property-group input-unit\"><div class=\"col-md-12\"><div><ui-select ng-disabled=\"!config.entitySelection.entities || config.entitySelection.entities.length == 0 || (config.entitySelection.entities.length <= 1 && config.entitySelection.autoSelectEnabled)\" ng-required=\"true\" id=\"entitySelectionInput\" name=\"entitySelectionInput\" ng-model=\"input.selectedEntity\" theme=\"select2\" class=\"input-select2\" style=\"width: 100%\" role=\"combobox\" multiple=\"{{config.entitySelection.enableMultiSelect}}\"><ui-select-match placeholder=\"{{config.entitySelection.entitySelectorPlaceholder}}\" allow-clear=\"true\">{{$item.name}}</ui-select-match><ui-select-choices position=\"down\" repeat=\"entity in config.entitySelection.entities\" role=\"listbox\"><div><div ng-bind=\"entity.name\" class=\"selectSegmentName\"></div></div></ui-select-choices></ui-select></div><div class=\"modal-property-error\" ng-show=\"!entitySelectionInputs.$valid && hasAttemptedSubmit\"><small class=\"text-red\">{{config.entitySelection.requiredText}}</small></div><div ng-show=\"!config.entitySelection.entities || config.entitySelection.entities.length == 0\"><small class=\"text-red\">{{config.entitySelection.missingText}}</small></div></div><div ng-show=\"config.entitySelection.selectSubtitle\"><small class=\"form-text\">{{config.entitySelection.selectSubtitle}}</small></div></div></div><div class=\"modal-property-group input-unit\" ng-repeat=\"prop in config.properties\"><div class=\"modal-property-radio-group grid-half\" ng-if=\"prop.type == \'radio\'\"><div class=\"modal-property-label col-sm-4 bold right\">{{prop.label}} <span ng-if=\"prop.required\" class=\"required text-red\">*</span></div><div class=\"modal-property-options col-sm-8\"><div ng-repeat=\"opt in prop.options\" style=\"display:table-row;\"><input type=\"radio\" class=\"radio\" ng-model=\"prop.$value\" value=\"{{opt.key}}\" name=\"{{prop.$inputName}}\" id=\"{{prop.$inputName + \'-\' + $index}}\" ng-change=\"radioPropertyChanged(prop, opt)\"> <label for=\"{{prop.$inputName + \'-\' + $index}}\">{{opt.label}}</label></div><div class=\"modal-property-error\" ng-if=\"prop.errorMessage\" ng-show=\"prop.$invalid && hasAttemptedSubmit\"><small class=\"text-red\">{{prop.errorMessage}}</small></div></div></div><div class=\"modal-property-checkbox-group grid-half\" ng-if=\"prop.type == \'checkbox\'\"><div class=\"modal-property-label col-sm-4 bold right\">{{prop.label}}<span ng-if=\"prop.required\" class=\"required text-red\">*</span></div><div class=\"modal-property-options col-sm-8\"><div ng-repeat=\"opt in prop.options\" style=\"display:table-row;\"><input type=\"checkbox\" class=\"checkbox\" ng-model=\"opt.$value\" value=\"{{opt.Key}}\" id=\"{{prop.$inputName + \'-\' + $index}}\" ng-change=\"checkboxPropertyChanged(prop, opt)\"> <label for=\"{{prop.$inputName + \'-\' + $index}}\">{{opt.label}}</label></div><div class=\"modal-property-error\" ng-if=\"prop.errorMessage\" ng-show=\"prop.$invalid && hasAttemptedSubmit\"><small class=\"text-red\">{{prop.errorMessage}}</small></div></div></div><div class=\"modal-property-radio-group grid-half\" ng-if=\"prop.type == \'inline-radio\'\"><div class=\"modal-property-label col-sm-1 bold right\">{{prop.label}} <span ng-if=\"prop.required\" class=\"required text-red\">*</span></div><div class=\"modal-property-options col-sm-12\"><div class=\"inline-block\" ng-repeat=\"opt in prop.options\" style=\"padding-right:24px\"><input type=\"radio\" class=\"radio\" ng-model=\"prop.$value\" value=\"{{opt.key}}\" name=\"{{prop.$inputName}}\" id=\"{{prop.$inputName + \'-\' + $index}}\" ng-change=\"radioPropertyChanged(prop, opt)\"> <label for=\"{{prop.$inputName + \'-\' + $index}}\">{{opt.label}}</label></div><div class=\"modal-property-error\" ng-if=\"prop.errorMessage\" ng-show=\"prop.$invalid && hasAttemptedSubmit\"><small class=\"text-red\">{{prop.errorMessage}}</small></div></div></div><div ng-show=\"prop.subtitle\"><small class=\"form-text\">{{prop.subtitle}}</small></div><div class=\"modal-property-checkbox-group grid-half\" ng-if=\"prop.type == \'checkbox-grid\'\"><div class=\"modal-property-label bold\">{{prop.label}}<span ng-if=\"prop.required\" class=\"required text-red\">*</span></div><div ng-show=\"prop.description\"><small class=\"form-text\">{{prop.description}}</small></div><div ng-repeat=\"opt in prop.options\" class=\"checkbox-grid-table\"><div ng-repeat=\"tableEntry in opt.colGroup\" style=\"display:table-row;\"><input type=\"checkbox\" class=\"checkbox\" ng-model=\"tableEntry.$value\" value=\"{{tableEntry.key}}\" id=\"{{prop.$inputName + \'-\' + tableEntry.key}}\" ng-change=\"checkboxPropertyChanged(prop, tableEntry)\" ng-disabled=\"tableEntry.disabled\"> <label for=\"{{prop.$inputName + \'-\' + tableEntry.key}}\">{{tableEntry.label}}</label></div></div></div></div><div class=\"modal-property-group input-unit\" ng-show=\"config.segmentSelection\" ng-form=\"segmentSelectionInputs\"><div class=\"grid-half\"><div class=\"clearfix\"><label for=\"staticSavedList\" class=\"radio-label\"><strong>{{config.segmentSelection.label}} <span class=\"required text-red\">*</span></strong></label></div></div><div class=\"modal-property-group input-unit\"><div class=\"col-md-12\"><div><ui-select ng-disabled=\"!config.segmentSelection.segments || config.segmentSelection.segments.length == 0\" ng-required=\"true\" id=\"segmentSelectionInput\" name=\"segmentSelectionInput\" ng-model=\"input.selectedSegment\" theme=\"select2\" class=\"input-select2\" style=\"width: 100%\" role=\"combobox\"><ui-select-match placeholder=\"{{language.modalSegmentPlaceholder}}\" allow-clear=\"true\">{{$select.selected.name}}</ui-select-match><ui-select-choices position=\"down\" repeat=\"segment in config.segmentSelection.segments | filter: $select.search\" group-by=\"\'Folder\'\" role=\"listbox\"><div><div ng-bind=\"segment.name\" class=\"selectSegmentName\"></div><div class=\"selectAddInfo small\"><span class=\"glyphicons glyphicons-folder-closed\"></span>{{segment.folder}}</div></div></ui-select-choices></ui-select></div><div class=\"modal-property-error\" ng-show=\"!segmentSelectionInputs.$valid && hasAttemptedSubmit\"><small class=\"text-red\">{{config.segmentSelection.requiredText}}</small></div><div ng-show=\"!config.segmentSelection.segments || config.segmentSelection.segments.length == 0\"><small class=\"text-red\">{{config.segmentSelection.missingText}}</small></div></div></div></div><div class=\"modal-property-group input-unit\" ng-show=\"config.isConditionalField\"><div class=\"modal-property-checkbox-group grid-half\"><div class=\"modal-property-options col-sm-12\"><input type=\"checkbox\" class=\"checkbox\" ng-model=\"input.includeTemplate\" id=\"conditional-template-inclusion\"> <label for=\"conditional-template-inclusion\">{{language.modalConditionalTemplateInclusionLabel}}</label></div></div></div><p class=\"modal-outro\" ng-show=\"config.outroPrompt\">{{config.outroPrompt}}</p><p class=\"modal-outro\" ng-if=\"config.noTemplatePrompt\" ng-show=\"!input.includeTemplate\">{{config.noTemplatePrompt}}</p><div class=\"row\" ng-if=\"!config.disableDefault && !config.isConditionalField\"><div class=\"input-unit\"><div class=\"input-control\"><label class=\"input-label\" for=\"defaultValue\">{{config.defaultLabel || config.label}}</label> <input class=\"input-element\" id=\"defaultValue\" name=\"MergeFieldName\" ng-model=\"input.defaultValue\" type=\"text\"></div><div ng-show=\"config.defaultSubtitle\"><small class=\"form-text\">{{config.defaultSubtitle}}</small></div></div></div></div><footer class=\"modal-footer panel-footer\"><div class=\"panel-buttons\"><a class=\"btn btn-gray\" id=\"cancel\" href=\"javascript:void(0);\" ng-click=\"modalCancel();\">{{language.modalCancel}}</a> <a class=\"btn btn-blue\" id=\"mergeFieldSubmit\" ng-click=\"modalConfirm()\" href=\"javascript:void(0);\">{{language.modalConfirm}}</a></div></footer>");
        $templateCache.put("ngpvan.ui.mergefields/simple-dropdown.tpl.html", "<div class=\"dropdown merge-dropdown\" uib-dropdown=\"\" uib-keyboard-nav=\"\"><button class=\"btn select btn\" uib-dropdown-toggle=\"\">{{mergeFieldDropdown.dropdownLabel}}</button><ul class=\"dropdown-menu merge-dropdown\" role=\"menu\"><li ng-repeat=\"mf in mergeFieldDropdown.mergeFieldList\" role=\"menuitem\"><a data-key=\"{{mf.key}}\" data-label=\"{{mf.label}}\" id=\"{{mergeFieldItemId(mf)}}\" ng-click=\"clickedMergeField(mf)\" href=\"javascript:void(0);\">{{mf.label}}</a></li></ul></div>");
        $templateCache.put("ngpvan.ui.mergefields/tree-dropdown.tpl.html", "<div class=\"dropdown merge-dropdown select2-menu\" style=\"margin-left: 0;\"><tree-view tree-data=\"mergeFieldDropdown.mergeFieldList\" on-node-click=\"clickedMergeField($item)\" filter-by=\"label\" order-by=\"{{mergeFieldDropdown.orderBy}}\" dropdown=\"\" class=\"\" tree-mode=\"menu\" leaf-only=\"\" filter-mode=\"leaf\" display-property-tree=\"label\" expand-disabled-parent-on-click=\"\" dropdown-search-placeholder=\"{{mergeFieldDropdown.dropdownSearchPlaceholder}}\" dropdown-label=\"{{mergeFieldDropdown.dropdownLabel}}\"></tree-view></div>");
        $templateCache.put("ngpvan.ui.mergefields/tree-inline.tpl.html", "<div class=\"select2-menu\" style=\"margin-left: 0;\"><tree-view tree-data=\"mergeFieldDropdown.mergeFieldList\" on-node-click=\"clickedMergeField($item)\" filter-by=\"label\" order-by=\"{{mergeFieldDropdown.orderBy}}\" class=\"\" tree-mode=\"menu\" leaf-only=\"\" filter-mode=\"leaf\" display-property-tree=\"label\" expand-disabled-parent-on-click=\"\" dropdown-search-placeholder=\"{{mergeFieldDropdown.dropdownSearchPlaceholder}}\" dropdown-label=\"{{mergeFieldDropdown.dropdownLabel}}\"></tree-view></div>");
    }]);
})(window.angular, window.jQuery || window.$, window._);;
/*!
 * ngpvan-angular-libraries : https://github.com/NGPVAN/Angular-Libraries
 * ngpvan.ui.treeview : https://github.com/NGPVAN/Angular-Libraries/tree/master/modules/ngpvan.ui.treeview
 * Version: 1.5.3 - 2020-12-08T13:52:15.848Z
 */

(function (angular, $, _) {
    // treeview.js

    'use strict';

    angular.module('ngpvan.ui.treeview', ['ngSanitize', 'ngpvan.ui.helpers'])
        .constant('treeViewConfig', {
            templates: {
                dropdown: {
                    multiple: 'ngpvan.ui.treeview/multi-select.tpl.html',
                    single: 'ngpvan.ui.treeview/single-select.tpl.html',
                    menu: 'ngpvan.ui.treeview/menu-select.tpl.html'
                },
                simple: 'ngpvan.ui.treeview/core.tpl.html',
                menu: 'ngpvan.ui.treeview/search-inline.tpl.html'
            },
            modes: {
                singleSelect: 'single-select',
                multiSelect: 'multi-select',
                menu: 'menu'
            },
            filterModes: {
                leafOnly: 'leaf',
                all: 'all'
            }
        })
        .directive('treeView', ['treeViewConfig', 'attributeValueHelper',
            function (treeViewConfig, attributeValueHelper) {

                function noop() { }

                function determineMode(attrs) {
                    //parse out tree mode
                    var mode = treeViewConfig.modes.singleSelect;
                    if (attributeValueHelper.truthy(attrs.multiple)) {
                        mode = treeViewConfig.modes.multiSelect;
                    } else if (attrs.treeMode) {
                        var m = attrs.treeMode;
                        switch (m) {
                            case 'multi':
                            case 'multiple':
                            case 'multi-select':
                            case 'multiSelect':
                                mode = treeViewConfig.modes.multiSelect;
                                break;
                            case 'menu':
                            case 'options':
                            case 'callbacks':
                                mode = treeViewConfig.modes.menu;
                                break;
                        }
                    }
                    return mode;
                }

                function determineFilterMode(attrs) {

                    var mode = attrs.filterMode;
                    if (mode) {
                        mode = mode.toLowerCase();
                    }

                    switch (mode) {
                        case 'child-only':
                        case 'child':
                        case 'leaf':
                            mode = treeViewConfig.filterModes.leafOnly;
                            break;
                        default:
                            mode = treeViewConfig.filterModes.all;
                    }

                    return mode;
                }

                return {

                    restrict: 'E',
                    controllerAs: '$tree',
                    require: ['treeView', 'ngModel'],
                    bindToController: {
                        treeData: '='
                    },
                    scope: true,
                    templateUrl: function (elem, attrs) {

                        var mode = determineMode(attrs);
                        var dropdown = attributeValueHelper.truthy(attrs.dropdown);

                        var tpl = treeViewConfig.templates.simple;
                        if (dropdown) {
                            switch (mode) {
                                case treeViewConfig.modes.multiSelect:
                                    tpl = treeViewConfig.templates.dropdown.multiple;
                                    break;
                                case treeViewConfig.modes.menu:
                                    tpl = treeViewConfig.templates.dropdown.menu;
                                    break;
                                default:
                                    tpl = treeViewConfig.templates.dropdown.single;
                                    break;
                            }
                        } else if (mode === treeViewConfig.modes.menu) {
                            tpl = treeViewConfig.templates.menu;
                        }

                        return attrs.templateUrl || tpl;
                    },
                    controller: [
                        '$scope', '$attrs', '$parse', 'attributeValueHelper',
                        function ($scope, $attrs, $parse, attributeValueHelper) {

                            var ctrl = this;
                            ctrl.selected = angular.noop; //incase it gets touched before initialized

                            function defer(cb, delay) {
                                if (delay) {
                                    setTimeout(cb, delay);
                                } else {
                                    setTimeout(cb);
                                }
                            }

                            function parse(attr) {

                                var parsed = $parse(attr);

                                return function (val) {

                                    if (arguments.length) {
                                        //set
                                        parsed.assign($scope.$parent, val);
                                    } else {
                                        //get
                                        return parsed($scope.$parent);
                                    }

                                };
                            }

                            function parseCallback(attr) {
                                if (!attr) {
                                    return noop;
                                }

                                var parsed = $parse(attr);
                                return function (args) {
                                    return parsed($scope, args);
                                };
                            }

                            function callCallback(parsedCb, dataWrapper) {
                                if (!_.isFunction(parsedCb)) {
                                    return;
                                }

                                return parsedCb({
                                    $item: dataWrapper.item
                                });
                            }

                            function isInitiallySelected(item) {
                                var modelData = ctrl.selected();
                                if (!modelData || !modelData.length) {
                                    return false;
                                }
                                return _.some(modelData, function (value) {
                                    if (ctrl.config.outputProperty) {
                                        return _.isEqual(value, _.get(item, ctrl.config.outputProperty));
                                    }
                                    return _.isEqual(value, item);
                                });
                            }

                            function initWrapper(item, depth, childrenItems) {


                                var id = _.get(item, ctrl.config.idProperty);
                                var parentId = _.get(item, ctrl.config.parentIdProperty);

                                var data = {
                                    children: [],
                                    id: id,
                                    parentId: parentId,
                                    selected: isInitiallySelected(item),
                                    canSelect: true,
                                    canExpand: false,
                                    expanded: false,
                                    filterExpanded: false,
                                    filterMatch: false,
                                    $hasExpanded: false,
                                    item: item,
                                    isChild: true,
                                    depth: depth,
                                    show: true,
                                    childrenItems: childrenItems,
                                    init: _.extend({ canSelect: true, expanded: false }, _.get(item, '$$tree') || {})
                                };

                                if (!data.init.canSelect || (ctrl.config.leafOnly && childrenItems.length)) {
                                    data.canSelect = false;
                                }

                                if (childrenItems.length > 0) {
                                    data.canExpand = true; //for css class
                                    if (data.init.expanded) {
                                        data.expanded = true;
                                    }
                                }


                                Object.defineProperties(data, {
                                    canClick: {
                                        //is it clickable? really only for CSS
                                        get: function () {
                                            return data.canSelect || (data.canExpand && ctrl.config.behavior.expandDisabledParentOnClick);
                                        }
                                    },
                                    displayHtml: {
                                        get: function () {
                                            return _.get(data.item, ctrl.config.displayProperties.tree);
                                        }
                                    },
                                    selectedHtml: {
                                        get: function () {
                                            return _.get(data.item, ctrl.config.displayProperties.dropdown);
                                        }
                                    },
                                    hasExpanded: {
                                        get: function () {
                                            if (data.$hasExpanded || data.expanded || data.filterExpanded) {
                                                return (data.$hasExpanded = true);
                                            }
                                            return false;
                                        }
                                    }
                                });

                                ctrl.allData.push(data);
                                return data;
                            }

                            function syncToModel() {
                                ctrl.status.modifyingSelected = true;

                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect) {
                                    var selectedOutput = ctrl.config.outputProperty ?
                                        _.map($scope.dropdown.selected, ctrl.config.outputProperty) :
                                        $scope.dropdown.selected;
                                    ctrl.selected(selectedOutput);
                                } else if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    var output = ctrl.config.outputProperty ?
                                        _.get($scope.item, ctrl.config.outputProperty) :
                                        $scope.item;
                                    ctrl.selected(output);
                                }
                                defer(function () {
                                    ctrl.status.modifyingSelected = false;
                                });
                            }

                            function getDataForItem(item) {
                                return _.find(ctrl.allData, function (data) {
                                    return angular.equals(data.item, item);
                                });
                            }

                            function getDataForOutputValue(val) {
                                if (!ctrl.config.outputProperty) {
                                    return getDataForItem(val);
                                }
                                return _.find(ctrl.allData, function (data) {
                                    var item = data.item;
                                    var oVal = _.get(item, ctrl.config.outputProperty);
                                    return angular.equals(oVal, val);
                                });
                            }

                            function syncFromModel() {
                                ctrl.status.modifyingSelected = true;

                                var selected = ctrl.selected();
                                deselectAll();
                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect) {
                                    if (!_.isArray(selected)) {
                                        selected = [selected];
                                    }
                                    $scope.selectedData = [];
                                    $scope.dropdown.selected = _(selected).map(getDataForOutputValue).filter().map(function (data) {
                                        _.set(data, 'selected', true);
                                        $scope.selectedData.push(data);
                                        return _.get(data, 'item');
                                    }).filter().value();
                                } else if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    var selectedData = getDataForOutputValue(selected);
                                    _.set(selectedData, 'selected', true);
                                    $scope.item = _.get(selectedData, 'item');
                                    $scope.selectedData = selectedData;
                                }

                                defer(function () {
                                    ctrl.status.modifyingSelected = false;
                                    if (!$scope.$$phase) {
                                        $scope.$apply();
                                    }
                                });
                            }

                            function addToData(data) {

                                var item = data.item;

                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect) {
                                    $scope.selectedData = $scope.selectedData || [];
                                    $scope.dropdown.selected = $scope.dropdown.selected || [];
                                    $scope.dropdown.selected.push(item);
                                    $scope.selectedData.push(data);
                                } else if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    $scope.item = item;
                                    $scope.selectedData = data;
                                }
                                syncToModel();
                            }

                            function removeFromData(data) {
                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect) {
                                    //is array
                                    var mData = $scope.dropdown.selected;
                                    var idx = _.indexOf(mData, data.item);
                                    _.pullAt(mData, idx);
                                    _.pullAt($scope.selectedData, _.indexOf($scope.selectedData, data));

                                } else if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    $scope.item = null;
                                    $scope.selectedData = null;
                                }
                                syncToModel();
                            }

                            function deselectAll() {
                                //deselect everything
                                if (_.isArray($scope.selectedData)) {
                                    _.forEach($scope.selectedData, function (data) {
                                        data.selected = false;
                                    });
                                } else if (_.isObject($scope.selectedData)) {
                                    $scope.selectedData.selected = false;
                                }
                                $scope.selectedData = null;
                            }

                            function doSelect(data) {
                                if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    //deselect everything
                                    deselectAll();
                                }
                                data.selected = true;
                                addToData(data);
                                $scope.dropdown.filter = '';
                                callCallback(ctrl.config.callbacks.onSelect, data);
                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect && ctrl.config.behavior.selectChildrenWithParent) {
                                    _.forEach(data.children, function (child) {
                                        doSelect(child);
                                    });
                                }
                            }

                            function doDeselect(data) {
                                //deselect
                                data.selected = false;
                                removeFromData(data);
                                callCallback(ctrl.config.callbacks.onDeselect, data);
                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect && ctrl.config.behavior.deselectChildrenWithParent) {
                                    _.forEach(data.children, function (child) {
                                        doDeselect(child);
                                    });
                                }
                            }

                            //called from UI
                            function toggleSelect(data) {
                                if (!data.canSelect) {
                                    return;
                                }
                                callCallback(ctrl.config.callbacks.onClick, data);
                                if (ctrl.config.mode === treeViewConfig.modes.menu) {
                                    //menu mode, just close the dropdown if its open
                                    closeDropdown();
                                } else {
                                    if (!data.selected) {
                                        var selected = ctrl.selected();
                                        var children = data.children;
                                        if (ctrl.config.leafOnly && children && children.length > 0) {
                                            return;
                                        }
                                        if (ctrl.config.mode === treeViewConfig.modes.singleSelect && selected) {
                                            //deselect current
                                            var other = _.find(ctrl.allData, { selected: true });
                                            if (other) {
                                                doDeselect(other);
                                            }
                                        }
                                        doSelect(data);
                                        $scope.dropdown.expanded = false;
                                    } else {
                                        doDeselect(data);
                                    }
                                }
                            }

                            //called from UI
                            function toggleExpand(data) {
                                if (data.filterExpanded) {
                                    data.filterExpanded = false;
                                    data.expanded = false;
                                } else {
                                    data.expanded = !data.expanded;
                                }
                            }

                            //called from UI
                            function clickNode(data) {
                                if (data.canSelect) {
                                    toggleSelect(data);
                                } else if (data.canExpand && ctrl.config.behavior.expandDisabledParentOnClick) {
                                    toggleExpand(data);
                                }
                            }

                            var matchesFilters = _.memoize(function (data, filterValue) {
                                var ret = false;
                                _.forEach(ctrl.filters, function (prop) {
                                    var val = _.get(data.item, prop);
                                    val = val ? val.toString() : val;
                                    if (val && val.toLowerCase().indexOf(filterValue) >= 0) {
                                        ret = true;
                                        return false;//short-circuit
                                    }
                                });
                                return ret;
                            }, function (data, filterValue) {
                                return JSON.stringify(data.item) + '::' + filterValue;
                            });

                            // Dropdown stuff
                            function doNotClose(event) {
                                if ($scope.dropdown.expanded) {
                                    event.stopPropagation();
                                }
                            }

                            function closeDropdown() {
                                $scope.dropdown.expanded = false;
                                $scope.dropdown.filter = '';
                            }

                            var blurDebounce = false;
                            function blur() {
                                if ($scope.dropdown.expanded && !blurDebounce) {
                                    closeDropdown();
                                }
                            }
                            function expandDropdown() {
                                if (!$scope.dropdown.expanded) {
                                    $scope.dropdown.expanded = true;

                                    //to prevent immediate closing of dropdown when browser under load
                                    // briefly lock the blur function
                                    blurDebounce = true;
                                    defer(function () {
                                        blurDebounce = false;
                                    }, 1);
                                } else {
                                    closeDropdown();
                                }
                            }

                            function deselectData(data, event) {
                                if (!arguments.length) {
                                    data = $scope.selectedData;
                                }
                                if (data && data.selected) {
                                    toggleSelect(data);
                                }
                                if (event) {
                                    event.stopPropagation();
                                }
                            }
                            // ---

                            function orderTree(data) {
                                if (!ctrl.config.orderBy) {
                                    return;
                                }

                                _.forEach(data.children, function (child) {
                                    orderTree(child);
                                });

                                data.children = _.sortBy(data.children, function (child) {
                                    return _.get(child.item, ctrl.config.orderBy);
                                });
                            }

                            function initSelections(skipSyncToModel) {
                                syncFromModel();
                                if (!skipSyncToModel) {
                                    syncToModel();
                                }
                            }

                            function determineItemDepth(item) {
                                var id = _.get(item, ctrl.config.idProperty);
                                var parentId = _.get(item, ctrl.config.parentIdProperty);

                                if (!parentId && parentId !== 0) {
                                    return 0;
                                }

                                var depth;
                                //determine depth
                                if (_.isNumber(ctrl.inputData.depthById[id])) {
                                    depth = ctrl.inputData.depthById[id];
                                } else if (_.isNumber(ctrl.inputData.depthById[parentId])) {
                                    depth = ctrl.inputData.depthById[id] = ctrl.inputData.depthById[parentId] + 1;
                                } else {
                                    depth = ctrl.inputData.depthById[id] = determineItemDepth(ctrl.inputData.byId[parentId]) + 1;
                                }
                                return depth;
                            }

                            function init(treeData) {
                                ctrl.config = {
                                    data: treeData || ctrl.treeData,
                                    mode: determineMode($attrs),
                                    idProperty: $attrs.itemIdProperty || 'id',
                                    parentIdProperty: $attrs.itemParentIdProperty || $attrs.parentIdProperty || 'parentId',
                                    outputProperty: $attrs.itemOutputProperty,
                                    orderBy: $attrs.orderBy,
                                    leafOnly: attributeValueHelper.truthy($attrs.leafOnly),
                                    displayProperties: {
                                        tree: $attrs.displayPropertyTree || 'name',
                                        dropdown: $attrs.displayPropertyDropdown || 'name'
                                    },
                                    dropdown: {
                                        enabled: attributeValueHelper.truthy($attrs.dropdown),
                                        placeholder: $attrs.dropdownPlaceholder || $attrs.dropdownLabel || 'Select something...',
                                        searchPlaceholder: $attrs.dropdownSearchPlaceholder || 'Search...'
                                    },
                                    tweaks: {
                                        disableChangeListener: attributeValueHelper.truthy($attrs.disableChangeListener)
                                    },
                                    behavior: {
                                        selectChildrenWithParent: attributeValueHelper.truthy($attrs.selectChildrenWithParent),
                                        deselectChildrenWithParent: attributeValueHelper.truthy($attrs.deselectChildrenWithParent),
                                        expandDisabledParentOnClick: attributeValueHelper.truthy($attrs.expandDisabledParentOnClick),
                                        filterMode: determineFilterMode($attrs)
                                    },
                                    callbacks: {
                                        onClick: parseCallback($attrs.onNodeClick),
                                        onSelect: parseCallback($attrs.onSelect),
                                        onDeselect: parseCallback($attrs.onDeselect)
                                    }
                                };

                                ctrl.inputData = {
                                    topLevel: [],
                                    byParentId: {},
                                    byId: {},
                                    depthById: {}
                                };
                                ctrl.mappedData = {
                                    topLevel: [],
                                    byParentId: {},
                                    byId: {}
                                };

                                ctrl.filters = _.filter(($attrs.filterBy || '').split(/\s+|,/));
                                $scope.hasFilters = !!ctrl.filters.length;
                                $scope.dropdown = {
                                    expanded: false,
                                    filter: '',
                                    placeholder: ctrl.config.dropdown.placeholder,
                                    searchPlaceholder: ctrl.config.dropdown.searchPlaceholder,
                                    doNotClose: doNotClose,
                                    blur: blur,
                                    expand: expandDropdown,
                                    deselect: deselectData
                                };


                                ctrl.status = {
                                    modifyingSelected: false
                                };


                                defer(function () {

                                    //organize data to optimize lookups
                                    _.forEach(ctrl.config.data, function (item) {

                                        var id = _.get(item, ctrl.config.idProperty);
                                        var parentId = _.get(item, ctrl.config.parentIdProperty);

                                        if (parentId) {
                                            ctrl.inputData.byParentId[parentId] = ctrl.inputData.byParentId[parentId] || [];
                                            ctrl.inputData.byParentId[parentId].push(item);
                                        } else {
                                            ctrl.inputData.topLevel.push(item);
                                        }

                                        if (ctrl.inputData.byId[id]) {
                                            //overwriting
                                            console.error('duplicate id:', id);
                                        }
                                        ctrl.inputData.byId[id] = item;
                                    });


                                    ctrl.allData = [];
                                    ctrl.selected = parse($attrs.ngModel);

                                    //initialize wrappers
                                    _.forEach(ctrl.config.data, function (item) {

                                        var children = ctrl.inputData.byParentId[_.get(item, ctrl.config.idProperty)] || [];
                                        var depth = determineItemDepth(item);
                                        var data = initWrapper(item, depth, children);

                                        if (!data.parentId && data.parentId !== 0) {
                                            ctrl.mappedData.topLevel.push(data);
                                        } else {
                                            ctrl.mappedData.byParentId[data.parentId] = ctrl.mappedData.byParentId[data.parentId] || [];
                                            ctrl.mappedData.byParentId[data.parentId].push(data);
                                        }

                                        ctrl.mappedData.byId[data.id] = data;

                                    });

                                    //one more pass to attach children
                                    _.forOwn(ctrl.mappedData.byParentId, function (children, parentId) {
                                        var parent = ctrl.mappedData.byId[parentId];
                                        parent.children = children;
                                    });

                                    //get all top level items
                                    var root = {
                                        children: ctrl.mappedData.topLevel
                                    };
                                    orderTree(root);
                                    $scope.data = root;

                                    //init selections
                                    initSelections(true);

                                    finishInit();

                                });

                            }

                            //handle init queuing
                            var initQueue = null;
                            function startInit(data) {
                                if (ctrl.initInProgress) {
                                    if (data) {
                                        initQueue = data;
                                    }
                                } else {
                                    ctrl.initInProgress = true;
                                    init(data);
                                }
                            }

                            function finishInit() {
                                ctrl.initInProgress = false;
                                if (initQueue) {
                                    var d = initQueue;
                                    initQueue = null;
                                    startInit(d);
                                }
                            }


                            function handleFilter(data, filterValue, parentIsMatch) {
                                var isMatch = matchesFilters(data, filterValue);
                                var childIsMatch = false;
                                if (data.children && data.children.length) {

                                    if (ctrl.config.behavior.filterMode === treeViewConfig.filterModes.leafOnly) {
                                        isMatch = false; //don't care if parent matches
                                    }

                                    _.forEach(data.children, function (child) {
                                        handleFilter(child, filterValue, isMatch || parentIsMatch);
                                        if (child.filterMatch || child.filterExpanded) {
                                            childIsMatch = true;
                                        }
                                    });
                                }

                                data.filterMatch = isMatch;
                                data.filterExpanded = childIsMatch;
                                data.show = isMatch || parentIsMatch || childIsMatch;

                            }

                            function resetAll() {

                                _.forEach(ctrl.allData, function (data) {
                                    data.filterMatch = false;
                                    data.filterExpanded = false;
                                    data.show = true;
                                });

                            }

                            // Wire up $scope functions
                            $scope.toggleExpand = toggleExpand;
                            $scope.toggleSelect = toggleSelect;
                            $scope.clickNode = clickNode;

                            // Initialize

                            defer(function treeviewFirstTimeInit() {

                                startInit();

                                if (!ctrl.config.data || !ctrl.config.tweaks.disableChangeListener) {
                                    var dataWatcher = $scope.$parent.$watchCollection($attrs.treeData, function (newValue) {
                                        startInit(newValue);
                                        if (ctrl.config.data && ctrl.config.tweaks.disableChangeListener) {
                                            dataWatcher(); //deregister
                                        }
                                    });
                                }

                                if (ctrl.config.mode === treeViewConfig.modes.multiSelect) {
                                    $scope.$parent.$watchCollection($attrs.ngModel, function (newValue, oldValue) {
                                        if (!_.isEqual(oldValue, newValue) && !ctrl.status.modifyingSelected && !ctrl.initInProgress) {
                                            initSelections();
                                        }
                                    });
                                } else if (ctrl.config.mode === treeViewConfig.modes.singleSelect) {
                                    $scope.$parent.$watch($attrs.ngModel, function (newValue, oldValue) {
                                        if (!_.isEqual(oldValue, newValue) && !ctrl.status.modifyingSelected && !ctrl.initInProgress) {
                                            initSelections();
                                        }
                                    });
                                }

                                if ((ctrl.config.dropdown.enabled || ctrl.config.mode === treeViewConfig.modes.menu) && ctrl.filters.length) {
                                    //filters and dropdown are enabled

                                    $scope.$parent.$watch(function () {
                                        return $scope.dropdown.filter;
                                    }, function (newValue, oldValue) {
                                        if (!_.isEqual(oldValue, newValue)) {
                                            if (!newValue) {
                                                //show all
                                                resetAll();
                                            } else {
                                                //figure out what should be visible
                                                newValue = newValue.toLowerCase();
                                                _.forEach($scope.data.children, function (topData) {
                                                    handleFilter(topData, newValue);
                                                });
                                            }
                                        }
                                    });
                                }

                            }, 1); //defer init

                        }]
                };

            }]);

    angular.module("ngpvan.ui.treeview").run(["$templateCache", function ($templateCache) {
        $templateCache.put("ngpvan.ui.treeview/core.tpl.html", "<script type=\"text/ng-template\" id=\"ngpvan.ui.treeview/treeNode.tpl.html\"><ul> <li ng-repeat=\"data in data.children\" data-depth=\"{{data.depth}}\" ng-show=\"data.show\" class=\"tree-item-row\" ng-class=\"{\'tree-item-row-expanded\':data.expanded, \'tree-item-row-collapsed\': data.canExpand && !data.expanded, \'tree-item-row-selected\':data.selected, \'tree-item-row-can-select\':data.canSelect, \'tree-item-row-cannot-select\':!data.canSelect, \'tree-item-row-cannot-expand\': !data.children || !data.children.length, \'tree-item-row-can-click\': data.canClick, \'tree-item-row-cannot-click\': !data.canClick}\"> <a ng-click=\"toggleExpand(data)\" ng-show=\"data.canExpand\" class=\"tree-item-expand\" ng-class=\"{\'tree-expand-arrow-expanded\': data.expanded, \'tree-expand-arrow-collapsed\':!data.expanded}\"> <span class=\"glyphicons\" ng-class=\"{\'glyphicons-chevron-down\': data.expanded || data.filterExpanded, \'glyphicons-chevron-right\': !(data.expanded || data.filterExpanded)}\"></span> </a> <a ng-click=\"clickNode(data)\" class=\"tree-item\" ng-class=\"{\'selected\':data.selected,\'can-select\':data.canSelect, \'cannot-select\':!data.canSelect, \'can-click\' : data.canClick, \'cannot-click\': !data.canClick }\" title=\"{{data.displayHtml}}\" >{{data.displayHtml}}</a> <div class=\"child-tree\" ng-show=\"data.expanded || data.filterExpanded\" ng-if=\"data.hasExpanded\" ng-include=\"\'ngpvan.ui.treeview/treeNode.tpl.html\'\"></div> </li> </ul></script><div ng-include=\"\'ngpvan.ui.treeview/treeNode.tpl.html\'\" class=\"treeview-root root-tree\"></div>");
        $templateCache.put("ngpvan.ui.treeview/menu-select.tpl.html", "<div class=\"treeview-container\" outside-click=\"dropdown.blur()\" ng-class=\"{\'collapsed\':!dropdown.expanded}\" outside-not-if=\"collapsed\"><div class=\"selected-items-wrapper\" ng-click=\"dropdown.expand()\"><div class=\"menu-title\"><span>{{dropdown.placeholder}}</span></div></div><div class=\"dropdown-list\" ng-show=\"dropdown.expanded\"><div class=\"typeahead-container\" ng-if=\"hasFilters\"><input type=\"text\" ng-model=\"dropdown.filter\" placeholder=\"{{dropdown.searchPlaceholder}}\" ng-click=\"dropdown.doNotClose($event)\" class=\"input-element\" focus-me=\"dropdown.expanded\" ng-model-options=\"{debounce:250}\"></div><div ng-include=\"\'ngpvan.ui.treeview/core.tpl.html\'\"></div></div></div>");
        $templateCache.put("ngpvan.ui.treeview/multi-select.tpl.html", "<div class=\"treeview-container\" outside-click=\"dropdown.blur()\" ng-class=\"{\'collapsed\':!dropdown.expanded}\" outside-not-if=\"collapsed\"><div class=\"selected-items-wrapper\" ng-click=\"dropdown.expand()\"><div class=\"no-selection-placeholder\"><span ng-hide=\"dropdown.selected.length\">{{dropdown.placeholder}}</span> <span class=\"glyphicons glyphicons-plus open\"></span></div><div class=\"selected-item-container\" ng-repeat=\"selectedData in selectedData\"><span ng-click=\"$event.stopPropagation()\" class=\"selected-item\"><span>{{selectedData.selectedHtml}}</span>&nbsp;<a class=\"selected-item-deselect\" ng-click=\"dropdown.deselect(selectedData,$event)\">&times;</a></span></div></div><div class=\"dropdown-list\" ng-show=\"dropdown.expanded\"><div class=\"typeahead-container\" ng-if=\"hasFilters\"><input type=\"text\" ng-model=\"dropdown.filter\" placeholder=\"{{dropdown.searchPlaceholder}}\" ng-click=\"dropdown.doNotClose($event)\" class=\"input-element\" focus-me=\"dropdown.expanded\" ng-model-options=\"{debounce:250}\"></div><div ng-include=\"\'ngpvan.ui.treeview/core.tpl.html\'\"></div></div></div>");
        $templateCache.put("ngpvan.ui.treeview/search-inline.tpl.html", "<div class=\"treeview-container\" outside-click=\"dropdown.blur()\" ng-class=\"{\'collapsed\':!dropdown.expanded}\" outside-not-if=\"collapsed\"><div><div class=\"typeahead-container\" ng-if=\"hasFilters\"><input type=\"text\" ng-model=\"dropdown.filter\" placeholder=\"{{dropdown.searchPlaceholder}}\" ng-click=\"dropdown.doNotClose($event)\" class=\"input-element\" focus-me=\"dropdown.expanded\" ng-model-options=\"{debounce:250}\"></div><div ng-include=\"\'ngpvan.ui.treeview/core.tpl.html\'\"></div></div></div>");
        $templateCache.put("ngpvan.ui.treeview/single-select.tpl.html", "<div class=\"treeview-container\" outside-click=\"dropdown.blur()\" ng-class=\"{\'collapsed\':!dropdown.expanded}\" outside-not-if=\"collapsed\"><div class=\"selected-items-wrapper\" ng-click=\"dropdown.expand()\"><div ng-show=\"selectedData\" class=\"selected-single-item-wrapper\"><span class=\"selected-single-item\"><span>{{selectedData.selectedHtml}}</span> <a ng-click=\"dropdown.deselect()\" style=\"float:right\"><span class=\"glyphicons glyphicons-remove single-item-remove\"></span></a></span></div><div ng-hide=\"item\" class=\"no-selection-placeholder\"><span>{{dropdown.placeholder}}</span></div></div><div class=\"dropdown-list\" ng-show=\"dropdown.expanded\"><div class=\"typeahead-container\" ng-if=\"hasFilters\"><input type=\"text\" ng-model=\"dropdown.filter\" placeholder=\"{{dropdown.searchPlaceholder}}\" ng-click=\"dropdown.doNotClose($event)\" class=\"input-element\" focus-me=\"dropdown.expanded\" ng-model-options=\"{debounce:250}\"></div><div ng-include=\"\'ngpvan.ui.treeview/core.tpl.html\'\"></div></div></div>");
    }]);
})(window.angular, window.jQuery || window.$, window._);;
/*!
 * ngpvan-angular-libraries : https://github.com/NGPVAN/Angular-Libraries
 * ngpvan.util.localization : https://github.com/NGPVAN/Angular-Libraries/tree/master/modules/ngpvan.util.localization
 * Version: 1.2 - 2018-08-10T15:34:39.053Z
 */

(function (angular,$,_) { 
// module.js

    angular.module('ngpvan.util.localization', [])
        .provider('languageConfig', [function(){

            //Configure using: angular.module(...).config(['languageConfigProvider', function(languageConfigProvider){ ... }])

            var language = {};

            this.set = function setLanguage(moduleName, wordLookup) {
                if(moduleName && wordLookup){
                    if(!language[moduleName]){
                        language[moduleName] = wordLookup;
                    } else {
                        language[moduleName] = _.extend({}, language[moduleName], wordLookup);
                    }
                }
            };

            // Factory

            function getLanguage(moduleName){
                return _.cloneDeep(language[moduleName]);
            }

            this.$get = [function() {
                return {
                    get: getLanguage
                };
            }];

        }]);

})(window.angular, window.jQuery||window.$, window._);;
