text: !function(){"use strict";function _slicedToArray(arr,i){return function _arrayWithHoles(arr){if(Array.isArray(arr))return arr}(arr)||function _iterableToArrayLimit(arr,i){if(!(Symbol.iterator in Object(arr)||"[object Arguments]"===Object.prototype.toString.call(arr)))return;var _arr=[],_n=!0,_d=!1,_e=void 0;try{for(var _s,_i=arr[Symbol.iterator]();!(_n=(_s=_i.next()).done)&&(_arr.push(_s.value),!i||_arr.length!==i);_n=!0);}catch(err){_d=!0,_e=err}finally{try{_n||null==_i.return||_i.return()}finally{if(_d)throw _e}}return _arr}(arr,i)||function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function _toConsumableArray(arr){return _arrayWithoutHoles(arr)||_iterableToArray(arr)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function _iterableToArray(iter){if(Symbol.iterator in Object(iter)||"[object Arguments]"===Object.prototype.toString.call(iter))return Array.from(iter)}function _arrayWithoutHoles(arr){if(Array.isArray(arr)){for(var i=0,arr2=new Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);enumerableOnly&&(symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})),keys.push.apply(keys,symbols)}return keys}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=null!=arguments[i]?arguments[i]:{};i%2?ownKeys(source,!0).forEach(function(key){_defineProperty(target,key,source[key])}):Object.getOwnPropertyDescriptors?Object.defineProperties(target,Object.getOwnPropertyDescriptors(source)):ownKeys(source).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}return target}function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}function _toConsumableArray(arr){return _arrayWithoutHoles(arr)||_iterableToArray(arr)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function _iterableToArray(iter){if(Symbol.iterator in Object(iter)||"[object Arguments]"===Object.prototype.toString.call(iter))return Array.from(iter)}function _arrayWithoutHoles(arr){if(Array.isArray(arr)){for(var i=0,arr2=new Array(arr.length);i<arr.length;i++)arr2[i]=arr[i];return arr2}}function _typeof(obj){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function _typeof(obj){return typeof obj}:function _typeof(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj})(obj)}angular.module("umbraco.directives",["umbraco.directives.editors","umbraco.directives.html","umbraco.directives.validation","ui.sortable"]),angular.module("umbraco.directives.editors",[]),angular.module("umbraco.directives.html",[]),angular.module("umbraco.directives.validation",[]),angular.module("umbraco.directives").directive("navResize",function(appState,eventsService,windowResizeListener){return{restrict:"A",link:function link(scope,element,attrs,ctrl){var resizeEnabled=!1;function setTreeMode(){appState.setGlobalState("showNavigation",!1===appState.getGlobalState("isTablet"))}var evts=[];evts.push(eventsService.on("appState.globalState.changed",function(e,args){"showNavigation"===args.key&&(!1===args.value?function resetResize(){resizeEnabled&&(element.resizable("destroy"),element.css("width",""),element.find(".navigation-inner-container").css("width",""),$("#contentwrapper").css("left",""),$("#umb-notifications-wrapper").css("left",""),$("#navOffset").css("margin-left",""),resizeEnabled=!1)}():function enableResize(){resizeEnabled||!1!==appState.getGlobalState("isTablet")||(element.resizable({containment:$("#mainwrapper"),autoHide:!0,handles:"e",alsoResize:".navigation-inner-container",resize:function resize(e,ui){$("#mainwrapper");var contentPanel=$("#contentwrapper"),umbNotification=$("#umb-notifications-wrapper"),bottomBar=contentPanel.find(".umb-bottom-bar"),navOffeset=$("#navOffset"),leftPanelWidth=ui.element.width();contentPanel.css({left:leftPanelWidth}),bottomBar.css({left:leftPanelWidth}),umbNotification.css({left:leftPanelWidth}),navOffeset.css({"margin-left":ui.element.outerWidth()})},stop:function stop(e,ui){}}),resizeEnabled=!0)}())}));var resizeCallback=function resizeCallback(size){appState.setGlobalState("isTablet",size.width<=1100),setTreeMode()};windowResizeListener.register(resizeCallback),scope.$on("$destroy",function(){for(var e in windowResizeListener.unregister(resizeCallback),evts)eventsService.unsubscribe(evts[e]);element.find(".navigation-inner-container").resizable("destroy")}),appState.setGlobalState("isTablet",$(window).width()<=1100),setTreeMode()}}}),function(){angular.module("umbraco.directives").directive("umbAppHeader",function AppHeaderDirective(eventsService,appState,userService,focusService,backdropService,overlayService){return{transclude:!0,restrict:"E",replace:!0,template:' <div> <div class="umb-app-header"> <umb-sections ng-if="authenticated" sections="sections"> </umb-sections> <div class="flex items-center"> <ul class="umb-app-header__actions"> <li data-element="global-search" class="umb-app-header__action"> <button type="button" class="umb-app-header__button btn-reset" hotkey="ctrl+space" ng-click="searchClick()" ng-mousedown="rememberFocus()"> <span class="sr-only"> <localize key="visuallyHiddenTexts_openBackofficeSearch">Open backoffice search</localize>... </span> <umb-icon icon="icon-search" class="umb-app-header__action-icon"></umb-icon> </button> </li> <li data-element="global-help" class="umb-app-header__action"> <button type="button" class="umb-app-header__button btn-reset" hotkey="ctrl+shift+h" ng-click="helpClick()"> <span class="sr-only"> <localize key="visuallyHiddenTexts_openCloseBackofficeHelp">Open/Close backoffice help</localize>... </span> <umb-icon icon="icon-help-alt" class="umb-app-header__action-icon"></umb-icon> </button> </li> <li data-element="global-user" class="umb-app-header__action"> <button type="button" class="umb-app-header__button btn-reset" ng-click="avatarClick()" hotkey="ctrl+shift+u" title="{{user.name}}"> <span class="sr-only"> <localize key="visuallyHiddenTexts_openCloseBackofficeProfileOptions">Open/Close your profile options</localize>... </span> <umb-avatar class="umb-app-header__action-icon" size="xxs" color="secondary" name="{{user.name}}" img-src="{{avatar[0].value}}" img-srcset="{{avatar[1].value}} 2x, {{avatar[2].value}} 3x"> </umb-avatar> </button> </li> </ul> </div> </div> </div> ',link:function link(scope,el,attr,ctrl){var evts=[];scope.authenticated=null,scope.user=null,scope.avatar=[{value:"assets/img/application/logo.png"},{value:"assets/img/application/logo@2x.png"},{value:"assets/img/application/logo@3x.png"}],evts.push(eventsService.on("app.notAuthenticated",function(){scope.authenticated=!1,scope.user=null})),evts.push(eventsService.on("app.ready",function(evt,data){if(scope.authenticated=!0,scope.user=data.user,scope.user.avatars&&(scope.avatar=[],Utilities.isArray(scope.user.avatars)))for(var i=0;i<scope.user.avatars.length;i++)scope.avatar.push({value:scope.user.avatars[i]})})),evts.push(eventsService.on("app.userRefresh",function(evt){userService.refreshCurrentUser().then(function(data){if(scope.user=data,scope.user.avatars&&(scope.avatar=[],Utilities.isArray(scope.user.avatars)))for(var i=0;i<scope.user.avatars.length;i++)scope.avatar.push({value:scope.user.avatars[i]})})})),scope.rememberFocus=focusService.rememberFocus,scope.searchClick=function(){var showSearch=appState.getSearchState("show");appState.setSearchState("show",!showSearch)},scope.helpClick=function(){var drawer={view:"help",show:!appState.getDrawerState("showDrawer")};appState.setDrawerState("view",drawer.view),appState.setDrawerState("showDrawer",drawer.show)},scope.avatarClick=function(){var dialog={view:"user",position:"right",name:"overlay-user",close:function close(){overlayService.close()}};overlayService.open(dialog)}},scope:{}}})}(),function(){angular.module("umbraco.directives").directive("umbBackdrop",function BackdropDirective($timeout,$http){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-backdrop" ng-click="clickBackdrop($event)">  <div ng-if="highlightElement && !loading" class="umb-backdrop__backdrop"> <div class="umb-backdrop__rect umb-backdrop__rect--top" ng-style="rectTopCss"></div> <div class="umb-backdrop__rect umb-backdrop__rect--right" ng-style="rectRightCss"></div> <div class="umb-backdrop__rect umb-backdrop__rect--bottom" ng-style="rectBottomCss"></div> <div class="umb-backdrop__rect umb-backdrop__rect--left" ng-style="rectLeftCss"></div> </div>  <div ng-if="!highlightElement || loading" class="umb-backdrop__backdrop"> <div class="umb-backdrop__rect" ng-style="{\'opacity\': backdropOpacity }"></div> </div>  <div ng-if="highlightPreventClick" class="umb-backdrop__highlight-prevent-click"></div> </div>',link:function link(scope,el,attr,ctrl){var events=[];function setHighlight(){scope.loading=!0,$timeout(function(){var highlightElement=$(scope.highlightElement);if(highlightElement&&highlightElement.length>0){var offset=highlightElement.offset(),width=highlightElement.outerWidth(),height=highlightElement.outerHeight(),topDistance=offset.top.toFixed(),topAndHeight=(offset.top+height).toFixed(),leftDistance=offset.left.toFixed(),leftAndWidth=(offset.left+width).toFixed();el.find(".umb-backdrop__rect--top"),el.find(".umb-backdrop__rect--right"),el.find(".umb-backdrop__rect--bottom"),el.find(".umb-backdrop__rect--left"),scope.rectTopCss={height:topDistance,left:leftDistance+"px",opacity:scope.backdropOpacity},scope.rectRightCss={left:leftAndWidth+"px",top:topDistance+"px",height:height,opacity:scope.backdropOpacity},scope.rectBottomCss={height:"100%",top:topAndHeight+"px",left:leftDistance+"px",opacity:scope.backdropOpacity},scope.rectLeftCss={width:leftDistance,opacity:scope.backdropOpacity},scope.highlightPreventClick&&el.find(".umb-backdrop__highlight-prevent-click").css({width:width,height:height,left:offset.left,top:offset.top})}scope.loading=!1})}scope.clickBackdrop=function(event){!0===scope.disableEventsOnClick&&(event.preventDefault(),event.stopPropagation())},events.push(scope.$watch("highlightElement",function(newValue,oldValue){newValue&&newValue!==oldValue&&setHighlight()})),$(window).on("resize.umbBackdrop",function resize(){setHighlight()}),scope.$on("$destroy",function(){for(var e in events)events[e]();$(window).off("resize.umbBackdrop")}),function onInit(){scope.highlightElement&&setHighlight()}()},scope:{backdropOpacity:"=?",highlightElement:"=?",highlightPreventClick:"=?",disableEventsOnClick:"=?"}}})}(),angular.module("umbraco.directives").directive("umbContextMenu",function(navigationService,keyboardService,backdropService){return{scope:{menuDialogTitle:"@",currentSection:"@",currentNode:"=",menuActions:"="},restrict:"E",replace:!0,template:'<div id="contextMenu" class="umb-modalcolumn fill shadow" ng-animate="\'slide\'" umb-focus-lock role="dialog" aria-labelledby="contextmenu-title" aria-describedby="contextmenu-description" on-outside-click="outSideClick()"> <div> <div class="umb-modalcolumn-header"> <h1 id="contextmenu-title">{{menuDialogTitle}}</h1> <p id="contextmenu-description" class="sr-only"> <localize key="visuallyHiddenTexts_contextMenuDescription">Select one of the options to edit the node.</localize> </p> </div> <div class="umb-modalcolumn-body"> <ul class="umb-actions"> <li data-element="action-{{action.alias}}" class="umb-action" ng-class="{sep:action.separator, \'-opens-dialog\': action.opensDialog}" ng-repeat="action in menuActions"> <button type="button" ng-click="executeMenuItem(action)" class="umb-action-link btn-reset umb-outline"> <umb-icon icon="icon-{{action.cssclass}}" class="icon"></umb-icon> <span class="menu-label">{{action.name}}</span> </button> </li> </ul> </div> </div> </div> ',link:function link(scope,element,attrs,ctrl){scope.executeMenuItem=function(action){navigationService.executeMenuAction(action,scope.currentNode,scope.currentSection)},scope.outSideClick=function(){navigationService.hideNavigation()},keyboardService.bind("esc",function(){navigationService.hideNavigation()}),scope.$on("$destroy",function(){keyboardService.unbind("esc")})}}}),angular.module("umbraco.directives").directive("umbDrawer",function Drawer($location,$routeParams,helpService,userService,localizationService,dashboardResource){return{restrict:"E",replace:!0,template:'<div class="umb-drawer"> <div style="height: 100%;" ng-if="configuredView" ng-include="configuredView"></div> </div>',transclude:!0,scope:{view:"=?",model:"=?"},link:function link(scope,element,attr,ctrl){!function onInit(){!function setView(){if(scope.view){var configuredView=scope.view;if(-1===scope.view.indexOf(".html")){var viewAlias=scope.view.toLowerCase();configuredView="views/common/drawers/"+viewAlias+"/"+viewAlias+".html"}configuredView!==scope.configuredView&&(scope.configuredView=configuredView)}}()}()}}}),function(){angular.module("umbraco.directives").directive("umbDrawerContent",function DrawerContentDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-drawer-content" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").directive("umbDrawerFooter",function DrawerFooterDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-drawer-footer" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").directive("umbDrawerHeader",function DrawerHeaderDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-drawer-header"> <div class="umb-drawer-header__title">{{ title }}</div> <div class="umb-drawer-header__subtitle">{{ description }}</div> </div>',scope:{title:"@?",description:"@?"}}})}(),function(){angular.module("umbraco.directives").directive("umbDrawerView",function DrawerViewDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-drawer-view" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").component("umbLogin",{template:'<div class="login-overlay"> <div id="login" class="umb-modalcolumn umb-dialog" ng-class="{\'show-validation\': vm.loginForm.$invalid}" ng-cloak> <div class="login-overlay__background-image" ng-style="{\'background-image\': \'url(\'+vm.backgroundImage+\')\'}"></div> <div class="login-overlay__logo"> <img ng-src="{{vm.logoImage}}"> </div> <div ng-if="!vm.denyLocalLogin" ng-show="vm.invitedUser != null" class="umb-login-container"> <form name="vm.inviteUserPasswordForm" novalidate ng-submit="vm.inviteSavePassword()" val-form-manager> <div class="form" ng-if="vm.inviteStep === 1"> <h1 style="margin-bottom: 10px; text-align: left;">Hi, {{vm.invitedUser.name}}</h1> <p style="line-height: 1.6; margin-bottom: 25px;"> <localize key="user_userinviteWelcomeMessage">Welcome to Umbraco! Just need to get your password and avatar setup and then you\'re good to go</localize> </p> <div class="control-group" ng-class="{error: vm.setPasswordForm.password.$invalid}"> <label for="umb-passwordOne"> <localize key="user_newPassword">New password</localize> <small style="font-size: 13px;">{{vm.invitedUserPasswordModel.passwordPolicyText}}</small> </label> <input type="password" ng-model="vm.invitedUserPasswordModel.password" name="password" id="umb-passwordOne" class="-full-width-input" umb-auto-focus required val-server-field="value" ng-minlength="{{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}}"> <span ng-messages="inviteUserPasswordForm.password.$error" show-validation-on-submit> <span class="help-inline" ng-message="required"><localize key="user_passwordIsBlank">Your new password cannot be blank!</localize></span> <span class="help-inline" ng-message="minlength">Minimum {{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}} characters</span> <span class="help-inline" ng-message="valServerField">{{inviteUserPasswordForm.password.errorMsg}}</span> </span> </div> <div class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}"> <label for="umb-confirmPasswordOne"><localize key="user_confirmNewPassword">Confirm new password</localize></label> <input type="password" ng-model="vm.invitedUserPasswordModel.confirmPassword" name="confirmPassword" id="umb-confirmPasswordOne" class="-full-width-input" required val-compare="password"> <span ng-messages="inviteUserPasswordForm.confirmPassword.$error" show-validation-on-submit> <span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span> <span class="help-inline" ng-message="valCompare"><localize key="user_passwordMismatch">The confirmed password doesn\'t match the new password!</localize></span> </span> </div> <div class="flex justify-between items-center"> <umb-button type="submit" button-style="success" state="vm.invitedUserPasswordModel.buttonState" label="Save password"> </umb-button> </div> </div> </form> <div class="form" ng-if="vm.inviteStep === 2"> <div class="flex justify-center items-center"> <ng-form name="vm.avatarForm"> <umb-progress-bar style="max-width: 100px; margin-bottom: 5px;" ng-show="vm.avatarFile.uploadStatus === \'uploading\'" progress="{{ vm.avatarFile.uploadProgress }}" size="s"> </umb-progress-bar> <div class="umb-info-local-item text-error mt3" ng-if="vm.avatarFile.uploadStatus === \'error\'"> {{ vm.avatarFile.serverErrorMessage }} </div> <a class="umb-avatar-btn" ngf-select ng-model="vm.avatarFile.filesHolder" ngf-change="vm.changeAvatar($files, $event)" ngf-multiple="false" ngf-pattern="{{vm.avatarFile.acceptedFileTypes}}" ngf-max-size="{{ vm.avatarFile.maxFileSize }}"> <umb-avatar color="gray" size="xl" unknown-char="+" img-src="{{vm.invitedUser.avatars[3]}}" img-srcset="{{vm.invitedUser.avatars[4]}} 2x, {{vm.invitedUser.avatars[4]}} 3x"> </umb-avatar> </a> </ng-form> </div> <h1 style="margin-bottom: 10px;">Upload a photo</h1> <p style="text-align: center; margin-bottom: 25px; line-height: 1.6em;"> <localize key="user_userinviteAvatarMessage"></localize> </p> <div class="flex justify-center items-center"> <umb-button type="button" button-style="success" label="Done" action="vm.getStarted()"> </umb-button> </div> </div> </div> <div ng-show="vm.invitedUser == null && vm.inviteStep === 3" ng-if="!vm.denyLocalLogin && vm.inviteStep === 3" class="umb-login-container"> <div class="form"> <h1 style="margin-bottom: 10px; text-align: left;">Hi there</h1> <p style="line-height: 1.6; margin-bottom: 25px;"> <localize key="user_userinviteExpiredMessage">Welcome to Umbraco! Unfortunately your invite has expired. Please contact your administrator and ask them to resend it.</localize> </p> </div> </div> <div ng-show="vm.invitedUser == null && !vm.inviteStep" class="umb-login-container"> <div class="form"> <h1>{{greeting}}</h1> <div ng-show="vm.view == \'login\'"> <p> <span ng-show="vm.isTimedOut"><localize key="login_timeout">Log in below</localize>.</span> </p> <div class="external-logins" ng-if="vm.externalLoginProviders.length > 0"> <div ng-repeat="login in vm.externalLoginProviders"> <div ng-if="!login.customView"> <form method="POST" action="{{vm.externalLoginFormAction}}"> <button type="submit" class="btn btn-block btn-social" ng-class="login.properties.ButtonStyle" id="{{login.authType}}" name="provider" value="{{login.authType}}" title="Log in using your {{login.caption}} account"> <umb-icon icon="{{login.properties.Icon}}" class="{{login.properties.Icon}}" style="height:100%;"></umb-icon> <localize key="login_signInWith">Sign in with</localize>&nbsp;{{login.caption}} </button> </form> <div ng-if="login.errors"> <div class="text-error" ng-repeat="error in login.errors"> <span>{{error}}</span> </div> </div> </div> <div ng-if="login.customView" ng-include="login.customView"></div> </div> </div> <form ng-if="!vm.denyLocalLogin" method="POST" name="vm.loginForm" ng-submit="vm.loginSubmit()"> <div ng-messages="vm.loginForm.$error" class="control-group" aria-live="assertive"> <p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p> </div> <div class="control-group" ng-class="{error: vm.loginForm.username.$invalid}"> <label for="umb-username">{{vm.labels.usernameLabel}}</label> <input type="text" ng-model="vm.login" name="username" id="umb-username" class="-full-width-input" placeholder="{{vm.labels.usernamePlaceholder}}" focus-when="{{vm.view === \'login\'}}" aria-required="true"> </div> <div class="control-group" ng-class="{error: vm.loginForm.password.$invalid}"> <label for="umb-passwordTwo"><localize key="general_password">Password</localize></label> <input type="password" ng-model="vm.password" name="password" id="umb-passwordTwo" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" aria-required="true"> <div class="password-toggle"> <button type="button" class="btn-reset" ng-click="vm.togglePassword()"> <span class="password-text show"><localize key="login_showPassword">Show password</localize></span> <span class="password-text hide"><localize key="login_hidePassword">Hide password</localize></span> </button> </div> </div> <div class="flex justify-between items-center"> <umb-button button-style="success" size="m" label-key="general_login" state="vm.loginStates.submitButton" type="submit"> </umb-button> <div ng-show="vm.allowPasswordReset"> <button type="button" class="btn-reset muted" style="text-decoration: underline;" ng-click="vm.showRequestPasswordReset()"> <localize key="login_forgottenPassword">Forgotten password?</localize> </button> </div> </div> </form> </div> <div ng-if="!vm.denyLocalLogin" ng-show="vm.view == \'request-password-reset\'"> <p tabindex="0"> <localize key="login_forgottenPasswordInstruction">An email will be sent to the address specified with a link to reset your password</localize> </p> <form method="POST" name="vm.requestPasswordResetForm" ng-submit="vm.requestPasswordResetSubmit(email)"> <div class="control-group" ng-class="{error: vm.requestPasswordResetForm.email.$invalid}"> <label for="umb-email"><localize key="general_email">Email</localize></label> <input type="email" val-email ng-model="email" name="email" id="umb-email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" focus-when="{{vm.view === \'request-password-reset\'}}"> </div> <div ng-messages="vm.requestPasswordResetForm.$error" class="control-group" ng-show="vm.requestPasswordResetForm.$invalid"> <p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p> </div> <div class="control-group" ng-show="vm.showEmailResetConfirmation"> <div class="text-info" role="alert"> <p tabindex="0"> <localize key="login_requestPasswordResetConfirmation">An email with password reset instructions will be sent to the specified address if it matched our records</localize> </p> </div> </div> <div class="flex justify-between items-center"> <button type="submit" class="btn btn-success" val-trigger-change="#login .form input"><localize key="general_submit">Submit</localize></button> <button type="button" class="btn-reset muted" ng-click="vm.showLogin()" style="text-decoration: underline;"> <localize key="login_returnToLogin">Return to login form</localize> </button> </div> </form> </div> <div ng-if="!vm.denyLocalLogin" ng-show="vm.view == \'set-password\'"> <p ng-hide="vm.resetComplete"> <localize key="login_setPasswordInstruction">Please provide a new password.</localize> </p> <form method="POST" name="vm.setPasswordForm" ng-submit="vm.setPasswordSubmit(vm.password, vm.confirmPassword)"> <div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.password.$invalid}"> <label for="umb-passwordThree"><localize key="user_newPassword">New password</localize></label> <input type="password" ng-model="vm.password" name="password" id="umb-passwordThree" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" focus-when="{{vm.view === \'set-password\'}}" ng-keyup="vm.newPasswordKeyUp($event)"> <umb-password-tip password-val="vm.passwordVal"></umb-password-tip> </div> <div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}"> <label for="umb-confirmPasswordThree"><localize key="user_confirmNewPassword">Confirm new password</localize></label> <input type="password" ng-model="vm.confirmPassword" name="confirmPassword" id="umb-confirmPasswordThree" class="-full-width-input" localize="placeholder" placeholder="@placeholders_confirmPassword"> </div> <div ng-messages="vm.setPasswordForm.$error" class="control-group" ng-show="vm.setPasswordForm.$invalid"> <p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p> </div> <div class="control-group" ng-show="vm.showSetPasswordConfirmation"> <div class="text-info"> <p tabindex="0"> <localize key="login_setPasswordConfirmation">Your new password has been set and you may now use it to log in.</localize> </p> </div> </div> <div class="flex justify-between items-center"> <button ng-hide="vm.resetComplete" type="submit" class="btn btn-success" val-trigger-change="#login .form input"><localize key="general_submit">Submit</localize></button> <button type="button" class="btn-reset muted" ng-click="vm.showLogin()"> <localize key="login_returnToLogin">Return to login form</localize> </button> </div> </form> </div> <div ng-if="!vm.denyLocalLogin" ng-show="vm.view == \'password-reset-code-expired\'"> <div class="text-error" ng-repeat="error in vm.resetPasswordCodeInfo.errors"> <p class="text-error">{{error}}</p> </div> <div class="switch-view"> <button type="button" class="btn-reset muted" ng-click="vm.showLogin()"> <localize key="login_returnToLogin">Return to login form</localize> </button> </div> </div> <div ng-if="!vm.denyLocalLogin" ng-show="vm.view == \'2fa-login\'"> <div ng-include="vm.twoFactor.view"></div> </div> </div> </div> </div> </div> ',controller:function UmbLoginController($scope,$location,currentUserResource,formHelper,mediaHelper,umbRequestHelper,Upload,localizationService,userService,externalLoginInfo,externalLoginInfoService,resetPasswordCodeInfo,authResource,$q){var vm=this;function loginSuccess(){vm.loginStates.submitButton="success",userService._retryRequestQueue(!0),vm.onLogin&&vm.onLogin()}function resetInputValidation(){vm.confirmPassword="",vm.password="",vm.login="",vm.loginForm&&(vm.loginForm.username.$setValidity("auth",!0),vm.loginForm.password.$setValidity("auth",!0)),vm.requestPasswordResetForm&&vm.requestPasswordResetForm.email.$setValidity("auth",!0),vm.setPasswordForm&&(vm.setPasswordForm.password.$setValidity("auth",!0),vm.setPasswordForm.confirmPassword.$setValidity("auth",!0))}function SetTitle(){var title=null;switch(vm.view.toLowerCase()){case"login":title="Login";break;case"password-reset-code-expired":case"request-password-reset":title="Password Reset";break;case"set-password":title="Change Password";break;case"2fa-login":title="Two Factor Authentication"}$scope.$emit("$changeTitle",title)}vm.invitedUser=null,vm.invitedUserPasswordModel={password:"",confirmPassword:"",buttonState:"",passwordPolicies:null,passwordPolicyText:""},vm.loginStates={submitButton:"init"},vm.avatarFile={filesHolder:null,uploadStatus:null,uploadProgress:0,maxFileSize:Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize+"KB",acceptedFileTypes:mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes),uploaded:!1},vm.allowPasswordReset=Umbraco.Sys.ServerVariables.umbracoSettings.canSendRequiredEmail&&Umbraco.Sys.ServerVariables.umbracoSettings.allowPasswordReset,vm.errorMsg="",vm.externalLoginFormAction=Umbraco.Sys.ServerVariables.umbracoUrls.externalLoginsUrl,vm.externalLoginProviders=externalLoginInfoService.getLoginProviders(),vm.externalLoginProviders.forEach(function(x){x.customView=externalLoginInfoService.getLoginProviderView(x),externalLoginInfo.errorProvider===x.authType&&(x.errors=externalLoginInfo.errors)}),vm.denyLocalLogin=externalLoginInfoService.hasDenyLocalLogin(),vm.externalLoginInfo=externalLoginInfo,vm.resetPasswordCodeInfo=resetPasswordCodeInfo,vm.logoImage=Umbraco.Sys.ServerVariables.umbracoSettings.loginLogoImage,vm.backgroundImage=Umbraco.Sys.ServerVariables.umbracoSettings.loginBackgroundImage,vm.usernameIsEmail=Umbraco.Sys.ServerVariables.umbracoSettings.usernameIsEmail,vm.$onInit=function onInit(){var inviteVal=$location.search().invite;!inviteVal||"1"!==inviteVal&&"2"!==inviteVal?inviteVal&&"3"===inviteVal&&(vm.inviteStep=Number(inviteVal)):$q.all([authResource.getCurrentInvitedUser().then(function(data){vm.invitedUser=data},function(){$location.search("invite",null)}),authResource.getPasswordConfig(0).then(function(data){vm.invitedUserPasswordModel.passwordPolicies=data,localizationService.localize("errorHandling_errorInPasswordFormat",[vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength,vm.invitedUserPasswordModel.passwordPolicies.minNonAlphaNumericChars]).then(function(data){vm.invitedUserPasswordModel.passwordPolicyText=data})})]).then(function(){vm.inviteStep=Number(inviteVal)});(function setGreeting(){var date=new Date;localizationService.localize("login_greeting"+date.getDay()).then(function(label){$scope.greeting=label})})(),vm.resetPasswordCodeInfo.resetCodeModel?vm.showSetPassword():vm.resetPasswordCodeInfo.errors.length>0?vm.view="password-reset-code-expired":vm.showLogin();SetTitle()},vm.togglePassword=function togglePassword(){var elem=$("form[name='vm.loginForm'] input[name='password']");elem.attr("type","text"===elem.attr("type")?"password":"text"),elem.focus(),$(".password-text.show, .password-text.hide").toggle()},vm.changeAvatar=function changeAvatar(files,event){files&&files.length>0&&function upload(file){vm.avatarFile.uploadProgress=0,Upload.upload({url:umbRequestHelper.getApiUrl("currentUserApiBaseUrl","PostSetAvatar"),fields:{},file:file}).progress(function(evt){if("done"!==vm.avatarFile.uploadStatus&&"error"!==vm.avatarFile.uploadStatus){vm.avatarFile.uploadStatus="uploading";var progressPercentage=parseInt(100*evt.loaded/evt.total,10);vm.avatarFile.uploadProgress=progressPercentage}}).success(function(data,status,headers,config){vm.avatarFile.uploadProgress=100,vm.avatarFile.uploadStatus="done",vm.invitedUser.avatars=data,vm.avatarFile.uploaded=!0}).error(function(evt,status,headers,config){vm.avatarFile.uploadStatus="error",404===status?vm.avatarFile.serverErrorMessage="File not found":400==status?vm.avatarFile.serverErrorMessage=evt.message:evt.InnerException?(vm.avatarFile.serverErrorMessage=evt.InnerException.ExceptionMessage,evt.InnerException.StackTrace&&evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength")>0&&(vm.avatarFile.serverErrorMessage="File too large to upload")):evt.Message&&(vm.avatarFile.serverErrorMessage=evt.Message)})}(files[0])},vm.getStarted=function getStarted(){$location.search("invite",null),vm.onLogin&&vm.onLogin()},vm.inviteSavePassword=function inviteSavePassword(){formHelper.submitForm({scope:$scope,formCtrl:vm.inviteUserPasswordForm})&&(vm.invitedUserPasswordModel.buttonState="busy",currentUserResource.performSetInvitedUserPassword(vm.invitedUserPasswordModel.password).then(function(data){formHelper.resetForm({scope:$scope,formCtrl:vm.inviteUserPasswordForm}),vm.invitedUserPasswordModel.buttonState="success",vm.invitedUser=data,userService.setAuthenticationSuccessful(data),vm.inviteStep=2},function(err){formHelper.resetForm({scope:$scope,hasErrors:!0,formCtrl:vm.inviteUserPasswordForm}),formHelper.handleError(err),vm.invitedUserPasswordModel.buttonState="error"}))},vm.showLogin=function showLogin(){vm.errorMsg="",resetInputValidation(),vm.view="login",SetTitle()},vm.showRequestPasswordReset=function showRequestPasswordReset(){vm.errorMsg="",resetInputValidation(),vm.view="request-password-reset",vm.showEmailResetConfirmation=!1,SetTitle()},vm.showSetPassword=function showSetPassword(){vm.errorMsg="",resetInputValidation(),vm.view="set-password",SetTitle()},vm.loginSubmit=function loginSubmit(){if(formHelper.submitForm({scope:$scope,formCtrl:vm.loginForm})){if(vm.login&&vm.password&&vm.login.length>0&&vm.password.length>0&&(vm.loginForm.username.$setValidity("auth",!0),vm.loginForm.password.$setValidity("auth",!0)),vm.loginForm.$invalid)return void SetTitle();vm.view="login",vm.loginStates.submitButton="busy",userService.authenticate(vm.login,vm.password).then(function(data){loginSuccess()},function(reason){402===reason.status?(vm.errorMsg="Additional authentication required",function show2FALoginDialog(viewPath){vm.twoFactor.submitCallback=function submitCallback(){vm.onLogin()},vm.twoFactor.view=viewPath,vm.view="2fa-login",SetTitle()}(reason.data.twoFactorView)):(vm.loginStates.submitButton="error",vm.errorMsg=reason.errorMsg,vm.loginForm.username.$setValidity("auth",!1),vm.loginForm.password.$setValidity("auth",!1)),userService._retryRequestQueue()}),vm.loginForm.username.$viewChangeListeners.push(function(){vm.loginForm.$invalid&&(vm.loginForm.username.$setValidity("auth",!0),vm.loginForm.password.$setValidity("auth",!0))}),vm.loginForm.password.$viewChangeListeners.push(function(){vm.loginForm.$invalid&&(vm.loginForm.username.$setValidity("auth",!0),vm.loginForm.password.$setValidity("auth",!0))})}},vm.requestPasswordResetSubmit=function requestPasswordResetSubmit(email){email&&email.length>0&&vm.requestPasswordResetForm.email.$setValidity("auth",!0);if(vm.showEmailResetConfirmation=!1,vm.requestPasswordResetForm.$invalid)return void(vm.errorMsg="Email address cannot be empty");vm.errorMsg="",authResource.performRequestPasswordReset(email).then(function(){vm.email="",vm.showEmailResetConfirmation=!0},function(reason){vm.errorMsg=reason.errorMsg,vm.requestPasswordResetForm.email.$setValidity("auth",!1)}),vm.requestPasswordResetForm.email.$viewChangeListeners.push(function(){vm.requestPasswordResetForm.email.$invalid&&vm.requestPasswordResetForm.email.$setValidity("auth",!0)})},vm.setPasswordSubmit=function setPasswordSubmit(password,confirmPassword){vm.showSetPasswordConfirmation=!1,password&&confirmPassword&&password.length>0&&confirmPassword.length>0&&(vm.setPasswordForm.password.$setValidity("auth",!0),vm.setPasswordForm.confirmPassword.$setValidity("auth",!0));if(vm.setPasswordForm.$invalid)return;authResource.performSetPassword(vm.resetPasswordCodeInfo.resetCodeModel.userId,password,confirmPassword,vm.resetPasswordCodeInfo.resetCodeModel.resetCode).then(function(){vm.showSetPasswordConfirmation=!0,vm.resetComplete=!0,resetPasswordCodeInfo.resetCodeModel=null},function(reason){reason.data&&reason.data.Message?vm.errorMsg=reason.data.Message:vm.errorMsg=reason.errorMsg,vm.setPasswordForm.password.$setValidity("auth",!1),vm.setPasswordForm.confirmPassword.$setValidity("auth",!1)}),vm.setPasswordForm.password.$viewChangeListeners.push(function(){vm.setPasswordForm.password.$invalid&&vm.setPasswordForm.password.$setValidity("auth",!0)}),vm.setPasswordForm.confirmPassword.$viewChangeListeners.push(function(){vm.setPasswordForm.confirmPassword.$invalid&&vm.setPasswordForm.confirmPassword.$setValidity("auth",!0)})},vm.newPasswordKeyUp=function newPasswordKeyUp(event){vm.passwordVal=event.target.value},vm.labels={},localizationService.localizeMany([vm.usernameIsEmail?"general_email":"general_username",vm.usernameIsEmail?"placeholders_email":"placeholders_usernameHint",vm.usernameIsEmail?"placeholders_emptyEmail":"placeholders_emptyUsername","placeholders_emptyPassword"]).then(function(data){vm.labels.usernameLabel=data[0],vm.labels.usernamePlaceholder=data[1],vm.labels.usernameError=data[2],vm.labels.passwordError=data[3]}),vm.twoFactor={},vm.loginSuccess=loginSuccess},controllerAs:"vm",bindings:{isTimedOut:"<",onLogin:"&"}})}(),angular.module("umbraco.directives").directive("umbNavigation",function umbNavigationDirective(){return{restrict:"E",replace:!0,template:'<div id="leftcolumn" ng-controller="Umbraco.NavigationController" ng-mouseleave="leaveTree($event)" ng-mouseenter="enterTree($event)" on-outside-click="onOutsideClick()">  <div id="navigation" ng-show="showNavigation" class="fill umb-modalcolumn" ng-animate="\'slide\'" nav-resize ng-class="{\'--notInFront\': infiniteMode}"> <div class="navigation-inner-container"> <div class="umb-language-picker" ng-if="currentSection === \'content\' && languages.length > 1" deep-blur="page.languageSelectorIsOpen = false" on-outside-click="page.languageSelectorIsOpen = false"> <button type="button" class="umb-language-picker__toggle" ng-click="toggleLanguageSelector()" aria-haspopup="true" aria-expanded="{{page.languageSelectorIsOpen}}"> <span> <span class="sr-only"> <localize key="visuallyHiddenTexts_currentLanguage">Current language</localize> <span>: </span> </span> <span>{{selectedLanguage.name}}</span> </span> <umb-icon icon="{{page.languageSelectorIsOpen ? \'icon-navigation-up\' : \'icon-navigation-down\'}}" class="umb-language-picker__expand"></umb-icon> </button> <div class="umb-language-picker__dropdown" ng-if="page.languageSelectorIsOpen"> <button type="button" class="umb-language-picker__dropdown-item" ng-class="{\'umb-language-picker__dropdown-item--current\': language.active}" ng-click="selectLanguage(language)" ng-repeat="language in languages"> <span class="sr-only"> <localize key="visuallyHiddenTexts_switchLanguage">Switch language to</localize> <span>: </span> </span> <span>{{language.name}}</span> </button> </div> </div>  <div id="tree" ng-show="authenticated"> <umb-tree api="treeApi" on-init="onTreeInit()"> </umb-tree> </div> </div> <div class="offset6" id="navOffset" style="z-index: 10"> <umb-context-menu ng-if="showContextMenu" menu-dialog-title="{{menuDialogTitle}}" current-section="{{currentSection}}" current-node="menuNode" menu-actions="menuActions"> </umb-context-menu> <umb-context-dialog ng-if="showContextMenuDialog" dialog-title="menuDialogTitle" current-node="menuNode" view="dialogTemplateUrl"> </umb-context-dialog> </div> <div class="umb-editor__overlay"></div> </div> </div> '}}),function(){angular.module("umbraco.directives").component("umbPasswordTip",{controller:function UmbPasswordTipController(localizationService){var defaultMinPwdLength=Umbraco.Sys.ServerVariables.umbracoSettings.minimumPasswordLength,defaultMinPwdNonAlphaNum=Umbraco.Sys.ServerVariables.umbracoSettings.minimumPasswordNonAlphaNum,vm=this;vm.passwordNonAlphaTip="",vm.passwordTip="",vm.passwordLength=0,vm.$onInit=function onInit(){void 0===vm.minPwdLength&&(vm.minPwdLength=defaultMinPwdLength);void 0===vm.minPwdNonAlphaNum&&(vm.minPwdNonAlphaNum=defaultMinPwdNonAlphaNum);vm.minPwdNonAlphaNum>0?localizationService.localize("user_newPasswordFormatNonAlphaTip",[vm.minPwdNonAlphaNum]).then(function(data){vm.passwordNonAlphaTip=data,updatePasswordTip(vm.passwordLength)}):(vm.passwordNonAlphaTip="",updatePasswordTip(vm.passwordLength))},vm.$onChanges=function onChanges(simpleChanges){simpleChanges.passwordVal&&(vm.passwordLength=simpleChanges.passwordVal.currentValue?simpleChanges.passwordVal.currentValue.length:0,updatePasswordTip(vm.passwordLength))};var updatePasswordTip=function updatePasswordTip(passwordLength){var remainingLength=vm.minPwdLength-passwordLength;remainingLength>0?localizationService.localize("user_newPasswordFormatLengthTip",[remainingLength]).then(function(data){vm.passwordTip=data,vm.passwordNonAlphaTip&&(vm.passwordTip+="<br/>".concat(vm.passwordNonAlphaTip))}):vm.passwordTip=vm.passwordNonAlphaTip}},controllerAs:"vm",template:'<span class="help-inline" style="display: block;" ng-if="vm.passwordTip" ng-bind-html="vm.passwordTip"></span>',bindings:{passwordVal:"<",minPwdLength:"<",minPwdNonAlphaNum:"<"}})}(),function(){var umbSearch={template:' <div class="umb-search" on-outside-click="vm.closeSearch()" ng-keydown="vm.handleKeyDown($event)" role="dialog" aria-labelledby="search-overlay-title" aria-describedby="search-overlay-description"> <div class="sr-only"> <h1 id="search-overlay-title"> <localize key="visuallyHiddenTexts_searchOverlayTitle">Search the Umbraco backoffice</localize> </h1> <p id="search-overlay-description"> <localize key="visuallyHiddenTexts_searchOverlayDescription">Search for content nodes, media nodes etc. across the backoffice.</localize> </p> </div> <div class="flex items-center"> <label for="app-search" class="umb-search__label"> <umb-icon icon="icon-search" class="umb-search-input-icon"></umb-icon> <span class="sr-only"> <localize key="general_search">Search...</localize> </span> </label> <span class="sr-only" id="search-input-description"> <localize key="visuallyHiddenTexts_searchInputDescription">When autocomplete results are available, press up and down arrows, or use the tab key and use the enter key to select.</localize> </span> <input class="umb-search-input" type="text" ng-model="vm.searchQuery" ng-model-options="{ debounce: 200 }" ng-change="vm.search(vm.searchQuery)" localize="placeholder" placeholder="@placeholders_search" id="app-search" focus-when="{{vm.searchHasFocus}}" aria-describedby="search-input-description" aria-expanded="{{vm.hasResults}}" aria-owns="search-results" aria-autocomplete="list"> <button ng-show="vm.searchQuery.length > 0" class="umb-search-input-clear umb-animated" ng-click="vm.clearSearch()"> <localize key="general_clear">Clear</localize> </button> </div> <div class="umb-search-results"> <div class="umb-search-group" ng-repeat="(key, group) in vm.searchResults" id="search-results" role="listbox"> <div class="umb-search-group__title" aria-hidden="true">{{key}}</div> <ul class="umb-search-items"> <li class="umb-search-item" ng-repeat="result in group.results" active-result="{{result === vm.activeResult}}"> <a class="umb-search-result__link" ng-href="#/{{result.editorPath}}" ng-click="vm.clickItem(result)"> <umb-icon icon="{{result.icon}}" class="umb-search-result__icon"></umb-icon> <span class="umb-search-result__meta"> <span class="umb-search-result__name">{{result.name}}</span> <span class="umb-search-result__description" ng-show="result.subTitle"> <span class="sr-only"> <localize key="visuallyHiddenTexts_path">Path:</localize> </span> <span>{{result.subTitle}}</span> </span> </span> </a> <span class="sr-only"> <localize key="visuallyHiddenTexts_foundIn">Found in</localize> {{key}} </span> </li> </ul> </div> </div> </div> ',controllerAs:"vm",controller:function umbSearchController($timeout,backdropService,searchService,focusService){var vm=this;function clearSearch(){vm.searchQuery="",vm.searchResults=[],vm.hasResults=!1,focusSearch()}function focusSearch(){vm.searchHasFocus=!1,$timeout(function(){vm.searchHasFocus=!0})}function closeSearch(){vm.focusBeforeOpening&&vm.focusBeforeOpening.focus(),vm.onClose&&vm.onClose()}vm.$onInit=function onInit(){vm.searchQuery="",vm.searchResults=[],vm.hasResults=!1,focusSearch(),backdropService.open()},vm.$onDestroy=function onDestroy(){backdropService.close()},vm.search=function search(searchQuery){if(searchQuery.length>0){var search={term:searchQuery};searchService.searchAll(search).then(function(result){var filtered={};Object.keys(result).forEach(function(key){var value=result[key];value.results.length>0&&(filtered[key]=value)}),vm.searchResults=filtered,vm.hasResults=Object.keys(vm.searchResults).length>0})}else clearSearch()},vm.clickItem=function clickItem(){closeSearch()},vm.clearSearch=clearSearch,vm.handleKeyDown=function handleKeyDown(event){if(27===event.keyCode)return event.stopPropagation(),event.preventDefault(),void closeSearch();if(vm.hasResults&&(38===event.keyCode||40===event.keyCode)){event.stopPropagation(),event.preventDefault();var allGroups=_.values(vm.searchResults),down=40===event.keyCode;null===vm.activeResultGroup?(vm.activeResultGroup=down?_.first(allGroups):_.last(allGroups),vm.activeResult=down?_.first(vm.activeResultGroup.results):_.last(vm.activeResultGroup.results)):down?vm.activeResult===_.last(vm.activeResultGroup.results)?(vm.activeResultGroup===_.last(allGroups)?vm.activeResultGroup=_.first(allGroups):vm.activeResultGroup=allGroups[allGroups.indexOf(vm.activeResultGroup)+1],vm.activeResult=_.first(vm.activeResultGroup.results)):vm.activeResult=vm.activeResultGroup.results[vm.activeResultGroup.results.indexOf(vm.activeResult)+1]:vm.activeResult===_.first(vm.activeResultGroup.results)?(vm.activeResultGroup===_.first(allGroups)?vm.activeResultGroup=_.last(allGroups):vm.activeResultGroup=allGroups[allGroups.indexOf(vm.activeResultGroup)-1],vm.activeResult=_.last(vm.activeResultGroup.results)):vm.activeResult=vm.activeResultGroup.results[vm.activeResultGroup.results.indexOf(vm.activeResult)-1],$timeout(function(){var resultElementLink=$(".umb-search-item[active-result='true'] .umb-search-result__link");resultElementLink[0].focus()})}},vm.closeSearch=closeSearch,vm.focusSearch=focusSearch,vm.focusBeforeOpening=focusService.getLastKnownFocus(),vm.activeResult=null,vm.activeResultGroup=null},bindings:{onClose:"&"}};angular.module("umbraco.directives").component("umbSearch",umbSearch)}(),angular.module("umbraco.directives").directive("umbSections",function sectionsDirective($timeout,$window,navigationService,treeService,sectionService,appState,eventsService,$location,historyService){return{restrict:"E",replace:!0,template:'<div> <div id="applications" ng-class="{faded:stickyNavigation}"> <ul class="sections" data-element="sections"> <li data-element="section-{{section.alias}}" ng-repeat="section in sections | limitTo: visibleSections" ng-class="{current: section.alias == currentSection}"> <a href="#/{{section.alias}}" ng-dblclick="sectionDblClick(section)" ng-click="sectionClick($event, section)" prevent-default ng-attr-aria-current="{{section.alias == currentSection ? \'page\' : undefined}}" aria-label="{{section.name + (section.alias == currentSection ? \' (active)\' : \'\')}}"> <span class="section__name">{{section.name}}</span> </a> </li> <li data-element="section-expand" class="expand" ng-class="{ \'open\': showTray === true, current: currentSectionInOverflow() }" ng-show="visibleSections < sections.length"> <umb-button-ellipsis action="trayClick()" text="More sections" color="#ffffff"> </umb-button-ellipsis> <ul id="applications-tray" class="sections-tray shadow-depth-2" ng-if="showTray" on-outside-click="trayClick()"> <li ng-repeat="section in sections | limitTo: sections.length | limitTo: -(sections.length - visibleSections)" ng-class="{current: section.alias == currentSection}"> <a href="#/{{section.alias}}" ng-dblclick="sectionDblClick(section)" ng-click="sectionClick($event, section)" prevent-default ng-attr-aria-current="{{section.alias == currentSection ? \'page\' : undefined}}" aria-label="{{section.name + (section.alias == currentSection ? \' (active)\' : \'\')}}"> <span class="section__name">{{section.name}}</span> </a> </li> </ul> </li> </ul> </div> </div> ',link:function link(scope,element,attr,ctrl){var sectionItemsWidth=[],evts=[];function loadSections(){sectionService.getSectionsForUser().then(function(result){scope.sections=result,scope.visibleSections=scope.sections.length,$timeout(function(){$("#applications .sections li:not(:last)").each(function(index){sectionItemsWidth.push($(this).outerWidth())})}),calculateWidth()})}function calculateWidth(){$timeout(function(){for(var containerWidth=$(".umb-app-header").outerWidth()-$(".umb-app-header__actions").outerWidth(),trayToggleWidth=$("#applications .sections li.expand").outerWidth(),sectionsWidth=0,i=0;i<sectionItemsWidth.length;i++)if((sectionsWidth+=sectionItemsWidth[i])+trayToggleWidth>containerWidth)return void(scope.visibleSections=i);scope.visibleSections=scope.sections.length})}scope.sections=[],scope.visibleSections=0,scope.currentSection=appState.getSectionState("currentSection"),scope.showTray=!1,scope.stickyNavigation=appState.getGlobalState("stickyNavigation"),evts.push(eventsService.on("appState.globalState.changed",function(e,args){"showTray"===args.key&&(scope.showTray=args.value),"stickyNavigation"===args.key&&(scope.stickyNavigation=args.value)})),evts.push(eventsService.on("appState.sectionState.changed",function(e,args){"currentSection"===args.key&&(scope.currentSection=args.value)})),evts.push(eventsService.on("app.reInitialize",function(e,args){loadSections()})),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])}),window.onresize=calculateWidth,scope.sectionClick=function(event,section){if(!(event.ctrlKey||event.shiftKey||event.metaKey||event.button&&1===event.button)){if(navigationService.hideSearch(),navigationService.showTree(section.alias),section.routePath)$location.path(section.routePath);else{var lastAccessed=historyService.getLastAccessedItemForSection(section.alias),path=null!=lastAccessed?lastAccessed.link:section.alias;$location.path(path)}navigationService.clearSearch()}},scope.sectionDblClick=function(section){navigationService.reloadSection(section.alias)},scope.trayClick=function(){!0===appState.getGlobalState("showTray")?navigationService.hideTray():navigationService.showTray()},scope.currentSectionInOverflow=function(){var currentSection=scope.sections.filter(function(s){return s.alias===scope.currentSection});return currentSection.length>0&&scope.sections.indexOf(currentSection[0])>scope.visibleSections-1},loadSections()}}}),function(){angular.module("umbraco.directives").directive("umbTour",function TourDirective($timeout,$http,$q,tourService,backdropService){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-tour"> <umb-loader class="umb-tour__loader" ng-if="loadingStep"></umb-loader> <div class="umb-tour__pulse"></div> <div class="umb-tour__popover shadow-depth-2" ng-class="{\'umb-tour__popover--l\': model.currentStep.type === \'intro\' || model.currentStepIndex === model.steps.length, \'umb-tour__popover--promotion\': model.currentStep.type === \'promotion\'}"> <div ng-if="!configuredView && !elementNotFound">  <umb-tour-step ng-if="model.currentStepIndex < model.steps.length" on-close="model.endTour()"> <umb-tour-step-header title="model.currentStep.title"> </umb-tour-step-header> <umb-tour-step-content content="model.currentStep.content"> </umb-tour-step-content> <umb-tour-step-footer> <div class="flex justify-between items-center"> <div> <umb-tour-step-counter current-step="model.currentStepIndex + 1" total-steps="model.steps.length"> </umb-tour-step-counter> <div ng-if="model.allowDisable && model.currentStep.type === \'intro\'"> <button type="button" class="underline" ng-click="model.disableTour()" prevent-default>Don\'t show this tour again</button> </div> </div> <div ng-if="model.currentStep.type !== \'intro\'"> <umb-button size="xs" ng-if="!model.currentStep.event" button-style="action" type="button" action="model.nextStep()" label="Next"></umb-button> </div> <div ng-if="model.currentStep.type === \'intro\'"> <umb-button size="m" button-style="action" type="button" action="model.nextStep()" label="Start tour"></umb-button> </div> </div> </umb-tour-step-footer> </umb-tour-step>  <umb-tour-step ng-if="model.currentStepIndex === model.steps.length" class="tc" hide-close="model.currentStepIndex === model.steps.length"> <umb-tour-step-content> <div class="flex items-center justify-center"> <umb-checkmark size="xl" checked="true"></umb-checkmark> </div> <h3 class="bold">Congratulations!</h3> <p>You have reached the end of the <b>{{model.name}}</b> tour - way to go!</p> </umb-tour-step-content> <umb-tour-step-footer> <umb-button type="button" button-style="action" size="m" action="model.completeTour()" label="Complete"></umb-button> </umb-tour-step-footer> </umb-tour-step> </div>  <div ng-if="configuredView && !loadingStep && !elementNotFound" ng-include="configuredView"></div>  <div ng-if="elementNotFound && !loadingStep"> <umb-tour-step class="tc" on-close="model.endTour()"> <umb-tour-step-header> <h4 class="bold color-red">Oh, we got lost!</h4> </umb-tour-step-header> <umb-tour-step-content> <p>We lost the next step <b>{{ model.currentStep.title }}</b> and don\'t know where to go.</p> <p>Please go back and start the tour again.</p> </umb-tour-step-content> <umb-tour-step-footer> <umb-button size="s" button-style="action" type="button" action="model.endTour()" label="End tour"></umb-button> </umb-tour-step-footer> </umb-tour-step> </div> </div> </div> ',link:function link(scope,el,attr,ctrl){var popover,pulseElement,pulseTimer;function nextStep(){if(popover.hide(),pulseElement.hide(),$timeout.cancel(pulseTimer),scope.model.currentStepIndex++,scope.model.currentStepIndex!==scope.model.steps.length){var upcomingStep=scope.model.steps[scope.model.currentStepIndex];if(upcomingStep.skipStepIfVisible){var tryFindDomEl=document.querySelector(upcomingStep.skipStepIfVisible);if(tryFindDomEl&&(tryFindDomEl.offsetWidth||tryFindDomEl.offsetHeight||tryFindDomEl.getClientRects().length))return void nextStep()}startStep()}else scope.loadingStep=!0,waitForPendingRerequests().then(function(){scope.loadingStep=!1,scope.model.currentStep={},setPopoverPosition(null),backdropService.setHighlight(null),backdropService.setOpacity(null)})}function startStep(){scope.loadingStep=!0,backdropService.setOpacity(scope.model.steps[scope.model.currentStepIndex].backdropOpacity),backdropService.setHighlight(null),waitForPendingRerequests().then(function(){scope.model.currentStep=scope.model.steps[scope.model.currentStepIndex],function setView(){if(scope.model.currentStep.view&&scope.model.alias){var configuredView=scope.model.currentStep.view;if(-1===scope.model.currentStep.view.indexOf(".html")){var viewAlias=scope.model.currentStep.view.toLowerCase();configuredView="views/common/tours/"+scope.model.alias.toLowerCase()+"/"+viewAlias+"/"+viewAlias+".html"}configuredView!==scope.configuredView&&(scope.configuredView=configuredView)}else scope.configuredView=null}(),findHighlightElement(),scope.model.currentStep.event&&function bindEvent(){var bindToElement=scope.model.currentStep.element,eventName=scope.model.currentStep.event+".step-"+scope.model.currentStepIndex,removeEventName="remove.step-"+scope.model.currentStepIndex,handled=!1;scope.model.currentStep.eventElement&&(bindToElement=scope.model.currentStep.eventElement),$(bindToElement).on(eventName,function(){handled||(unbindEvent(),nextStep(),handled=!0)}),$(bindToElement).on(removeEventName,function(){handled||(unbindEvent(),nextStep(),handled=!0)})}(),scope.loadingStep=!1})}function findHighlightElement(){scope.elementNotFound=!1,$timeout(function(){if(scope.model.currentStep&&"intro"===scope.model.currentStep.type&&(scope.model.currentStep.element=null,scope.model.currentStep.eventElement=null,scope.model.currentStep.event=null),!scope.model.currentStep||scope.model.currentStep.element){var element=$(scope.model.currentStep.element);if(0===element.length)return scope.elementNotFound=!0,void setPopoverPosition(null);var scrollParent=element.scrollParent(),el=element,offsetTop=0;if(scrollParent[0]===document)offsetTop=el[0].offsetTop;else for(;$.contains(scrollParent[0],el[0]);)offsetTop+=el[0].offsetTop,el=el.offsetParent();var scrollToCenterOfContainer=offsetTop-scrollParent[0].clientHeight/2;element[0].clientHeight<scrollParent[0].clientHeight&&(scrollToCenterOfContainer+=element[0].clientHeight/2),offsetTop>scrollParent[0].clientHeight-200?scrollParent.animate({scrollTop:scrollToCenterOfContainer},function(){setPopoverPosition(element),setPulsePosition(),backdropService.setHighlight(scope.model.currentStep.element,scope.model.currentStep.elementPreventClick)}):(setPopoverPosition(element),setPulsePosition(),backdropService.setHighlight(scope.model.currentStep.element,scope.model.currentStep.elementPreventClick))}else setPopoverPosition(null)})}function setPopoverPosition(element){$timeout(function(){var position="center",css={},popoverWidth=popover.outerWidth(),popoverHeight=popover.outerHeight(),documentWidth=(popover.offset(),$(document).width()),documentHeight=$(document).height();if(element){var offset=element.offset(),width=element.outerWidth(),height=element.outerHeight();"top"===(position=function findMax(obj){for(var keys=Object.keys(obj),max=keys[0],i=1,n=keys.length;i<n;++i){var k=keys[i];obj[k]>obj[max]&&(max=k)}return max}({top:offset.top,right:documentWidth-(offset.left+width),bottom:documentHeight-(offset.top+height),left:offset.left}))&&(offset.left<documentWidth/2?(css.top=offset.top-popoverHeight-20,css.left=offset.left):(css.top=offset.top-popoverHeight-20,css.left=offset.left-popoverWidth+width)),"right"===position&&(offset.top+popoverHeight<documentHeight?(css.top=offset.top,css.left=offset.left+width+20):(css.top=offset.top+height-popoverHeight,css.left=offset.left+width+20)),"bottom"===position&&(offset.left<documentWidth/2?(css.top=offset.top+height+20,css.left=offset.left):(css.top=offset.top+height+20,css.left=offset.left-popoverWidth+width)),"left"===position&&(offset.top+popoverHeight<documentHeight?(css.top=offset.top,css.left=offset.left-popoverWidth-20):(css.top=offset.top+height-popoverHeight,css.left=offset.left-popoverWidth-20))}else css.top="calc(50% - "+popoverHeight/2+"px)",css.left="calc(50% - "+popoverWidth/2+"px)";popover.css(css).fadeIn("fast")})}function setPulsePosition(){scope.model.currentStep.event&&(pulseTimer=$timeout(function(){var clickElementSelector=scope.model.currentStep.eventElement?scope.model.currentStep.eventElement:scope.model.currentStep.element,clickElement=$(clickElementSelector),offset=clickElement.offset(),width=clickElement.outerWidth(),height=clickElement.outerHeight();pulseElement.css({width:width,height:height,left:offset.left,top:offset.top}),pulseElement.fadeIn()},1e3))}function waitForPendingRerequests(){var deferred=$q.defer(),timer=window.setInterval(function(){var requestsReady=!1,animationsDone=!1;0===$http.pendingRequests.length&&"complete"===document.readyState&&(requestsReady=!0),0===document.querySelectorAll(".ng-enter, .ng-leave, .umb-editor--animating").length&&(animationsDone=!0),requestsReady&&animationsDone&&$timeout(function(){deferred.resolve(),clearInterval(timer)})},50);return deferred.promise}function unbindEvent(){var eventName=scope.model.currentStep.event+".step-"+scope.model.currentStepIndex,removeEventName="remove.step-"+scope.model.currentStepIndex;scope.model.currentStep.eventElement?($(scope.model.currentStep.eventElement).off(eventName),$(scope.model.currentStep.eventElement).off(removeEventName)):($(scope.model.currentStep.element).off(eventName),$(scope.model.currentStep.element).off(removeEventName))}scope.loadingStep=!1,scope.elementNotFound=!1,scope.model.nextStep=function(){nextStep()},scope.model.endTour=function(){unbindEvent(),tourService.endTour(scope.model),backdropService.close()},scope.model.completeTour=function(){unbindEvent(),tourService.completeTour(scope.model).then(function(){backdropService.close()})},scope.model.disableTour=function(){unbindEvent(),tourService.disableTour(scope.model).then(function(){backdropService.close()})},function onInit(){popover=el.find(".umb-tour__popover"),pulseElement=el.find(".umb-tour__pulse"),popover.hide(),scope.model.currentStepIndex=0,backdropService.open({disableEventsOnClick:!0}),startStep()}(),$(window).on("resize.umbTour",function resize(){findHighlightElement()}),scope.$on("$destroy",function(){$(window).off("resize.umbTour"),unbindEvent(),$timeout.cancel(pulseTimer)})},scope:{model:"="}}})}(),function(){angular.module("umbraco.directives").directive("umbTourStep",function TourStepDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-tour-step umb-tour-step--{{size}}"> <div ng-if="hideClose !== true"> <button type="button" class="umb-tour-step__close" hotkey="esc" ng-click="close()"> <umb-icon icon="icon-wrong"></umb-icon> <span class="sr-only"> <localize key="general_close">Close</localize> </span> </button> </div> <div ng-transclude></div> </div> ',scope:{size:"@?",onClose:"&?",hideClose:"=?"},link:function link(scope,element,attrs,ctrl){scope.close=function(){scope.onClose&&scope.onClose()}}}})}(),function(){angular.module("umbraco.directives").directive("umbTourStepContent",function TourStepContentDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-tour-step__content"> <div ng-bind-html="content"></div> <div ng-transclude></div> </div>',scope:{content:"="}}})}(),function(){angular.module("umbraco.directives").directive("umbTourStepCounter",function TourStepCounterDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-tour-step__counter">{{ currentStep }}/{{ totalSteps }}</div>',scope:{currentStep:"=",totalSteps:"="}}})}(),function(){angular.module("umbraco.directives").directive("umbTourStepFooter",function TourStepFooterDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-tour-step__footer" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").directive("umbTourStepHeader",function TourStepHeaderDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-tour-step__header"> <div class="umb-tour-step__title">{{title}}</div> <div ng-transclude></div> </div>',scope:{title:"="}}})}(),function(){function UmbButtonController($timeout,localizationService){var vm=this;function setButtonLabel(){"true"===vm.addEllipsis&&(vm.buttonLabel=vm.buttonLabel+"..."),vm.labelKey&&localizationService.localize(vm.labelKey).then(function(value){vm.buttonLabel=value,"true"===vm.addEllipsis&&(vm.buttonLabel=vm.buttonLabel+"...")})}vm.$onInit=function onInit(){vm.blockElement=!1,vm.style=null,vm.innerState="init",vm.generalActions="general_actions"===vm.labelKey,vm.type||(vm.type="button");if(vm.buttonLabel=vm.label,vm.isPrimaryButtonStyle=vm.buttonStyle&&"info"!==vm.buttonStyle,vm.buttonStyle)if(vm.buttonStyle.startsWith("[")&&vm.buttonStyle.endsWith("]")){var withoutBrackets=vm.buttonStyle.replace(/[\[\]']+/g,""),array=withoutBrackets.split(/\s?,\s?/g);Utilities.forEach(array,function(item){vm.style=vm.style+" btn-"+item,"block"===item&&(vm.blockElement=!0)})}else vm.style="btn-"+vm.buttonStyle,"block"===vm.buttonStyle&&(vm.blockElement=!0);setButtonLabel()},vm.$onChanges=function onChanges(changes){changes.state&&(changes.state.currentValue&&(vm.innerState=changes.state.currentValue),"success"!==changes.state.currentValue&&"error"!==changes.state.currentValue||$timeout(function(){vm.innerState="init"},2e3));changes.disabled&&changes.disabled.currentValue&&(vm.disabled=changes.disabled.currentValue);changes.label&&changes.label.currentValue&&(vm.buttonLabel=changes.label.currentValue,setButtonLabel());changes.labelKey&&changes.labelKey.currentValue&&setButtonLabel();changes.type&&(vm.type||(vm.type="button"))},vm.clickButton=function clickButton(event){vm.action&&vm.action({$event:event})}}angular.module("umbraco.directives").component("umbButton",{transclude:!0,template:'<div class="umb-button" ng-class="{\'ml0\': vm.generalActions, \'umb-button--block\': vm.blockElement}" data-element="{{ vm.alias ? \'button-\' + vm.alias : \'\' }}"> <div ng-if="vm.innerState"> <umb-icon icon="icon-check" class="umb-button__success" ng-class="{\'-hidden\': vm.innerState !== \'success\', \'-white\': vm.isPrimaryButtonStyle}"></umb-icon> <umb-icon icon="icon-delete" class="umb-button__error" ng-class="{\'-hidden\': vm.innerState !== \'error\', \'-white\': vm.isPrimaryButtonStyle}"></umb-icon> <div class="umb-button__progress" ng-class="{\'-hidden\': vm.innerState !== \'busy\', \'-white\': vm.isPrimaryButtonStyle}"></div> <div ng-if="vm.innerState !== \'init\'" class="umb-button__overlay"></div> </div> <a ng-if="vm.type === \'link\'" ng-href="{{vm.href}}" ng-attr-target="{{(vm.hrefTarget) ? vm.hrefTarget : undefined}}" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}} umb-outline" ng-click="vm.clickButton($event)" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}"> <span class="umb-button__content" ng-class="{\'-hidden\': vm.innerState !== \'init\'}"> <umb-icon icon="{{vm.icon}}" class="umb-button__icon" ng-if="vm.icon"></umb-icon> {{vm.buttonLabel}} <span ng-if="vm.showCaret" class="umb-button__caret caret" aria-hidden="true"></span> </span> </a> <button ng-if="vm.type === \'button\'" type="button" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}} umb-outline" ng-click="vm.clickButton($event)" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled" umb-auto-focus="{{vm.autoFocus && !vm.disabled ? \'true\' : \'false\'}}" aria-haspopup="{{vm.hasPopup}}" aria-expanded="{{vm.isExpanded}}"> <span class="umb-button__content" ng-class="{\'-hidden\': vm.innerState !== \'init\'}"> <umb-icon icon="{{vm.icon}}" class="umb-button__icon" ng-if="vm.icon"></umb-icon> {{vm.buttonLabel}} <span ng-if="vm.showCaret" class="umb-button__caret caret" aria-hidden="true"></span> </span> </button> <button ng-if="vm.type === \'submit\'" type="submit" class="btn umb-button__button {{vm.style}} umb-button--{{vm.size}} umb-outline" hotkey="{{vm.shortcut}}" hotkey-when-hidden="{{vm.shortcutWhenHidden}}" ng-disabled="vm.disabled" umb-auto-focus="{{vm.autoFocus && !vm.disabled ? \'true\' : \'false\'}}"> <span class="umb-button__content" ng-class="{\'-hidden\': vm.innerState !== \'init\'}"> <umb-icon icon="{{vm.icon}}" class="umb-button__icon" ng-if="vm.icon"></umb-icon> {{vm.buttonLabel}} <span ng-if="vm.showCaret" class="umb-button__caret caret" aria-hidden="true"></span> </span> </button> </div> ',controller:UmbButtonController,controllerAs:"vm",bindings:{action:"&?",href:"@?",hrefTarget:"@?",type:"@",buttonStyle:"@?",state:"<?",shortcut:"@?",shortcutWhenHidden:"@",label:"@?",labelKey:"@?",icon:"@?",disabled:"<?",size:"@?",alias:"@?",addEllipsis:"@?",showCaret:"@?",autoFocus:"<?",hasPopup:"@?",isExpanded:"<?"}}),UmbButtonController.$inject=["$timeout","localizationService"]}(),function(){var component={template:'<button type="button" data-element="{{vm.element}}" class="btn-reset umb-button-ellipsis {{vm.cssClass}}" style="color:{{vm.color}};" ng-class="{\'umb-button-ellipsis--hidden\': vm.state === \'hidden\', \'show-text\': vm.showText, \'umb-button-ellipsis--tab\' : vm.mode === \'tab\', \'umb-button-ellipsis--small\' : vm.mode === \'small\'}" ng-click="vm.clickButton($event)"> <span class="umb-button-ellipsis__content"> <span class="umb-button-ellipsis__icon" aria-hidden="true">&bull;&bull;&bull;</span> <span class="umb-button-ellipsis__text" ng-class="{\'sr-only\': vm.showText !== true}">{{vm.text}}</span> </span> <ng-transclude></ng-transclude> </button> ',controller:function UmbButtonEllipsis($timeout,localizationService){var vm=this;vm.$onInit=function onInit(){(function setText(){vm.labelKey&&localizationService.localize(vm.labelKey).then(function(data){-1===data.indexOf("[")&&(vm.text=data)})})(),function setColor(){vm.color=vm.color?vm.color:"#000000"}()},vm.clickButton=function clickButton(event){vm.action&&vm.action({$event:event})}},controllerAs:"vm",transclude:!0,bindings:{text:"@",labelKey:"@?",action:"&",cssClass:"@?",color:"@?",showText:"<?",element:"@?",state:"@?",mode:"@?"}};angular.module("umbraco.directives").component("umbButtonEllipsis",component)}(),function(){angular.module("umbraco.directives").directive("umbButtonGroup",function ButtonGroupDirective(){return{restrict:"E",replace:!0,template:'<div class="btn-group umb-button-group" ng-class="{ \'dropup\': direction === \'up\', \'-with-button-group-toggle\': subButtons.length > 0 }"> <umb-button ng-if="defaultButton" alias="{{defaultButton.alias ? defaultButton.alias : \'groupPrimary\' }}" type="{{defaultButton.type}}" action="defaultButton.handler()" href="{{defaultButton.href}}" href-target="{{defaultButton.hrefTarget}}" button-style="{{buttonStyle}}" state="state" label="{{defaultButton.labelKey}}" label-key="{{defaultButton.labelKey}}" shortcut="{{defaultButton.hotKey}}" shortcut-when-hidden="{{defaultButton.hotKeyWhenHidden}}" size="{{size}}" icon="{{icon}}" add-ellipsis="{{defaultButton.addEllipsis}}"> </umb-button> <button type="button" data-element="button-group-toggle" class="btn btn-{{buttonStyle}} dropdown-toggle umb-button-group__toggle umb-button--{{size}}" ng-if="subButtons.length > 0" ng-click="toggleDropdown()" aria-haspopup="true" aria-expanded="{{dropdown.isOpen}}"> <span class="caret"> <span class="sr-only"> <localize key="{{labelKey}}">{{label}}</localize> </span> </span> </button> <umb-dropdown ng-if="subButtons.length > 0 && dropdown.isOpen" class="umb-button-group__sub-buttons" on-close="closeDropdown()" deep-blur="closeDropdown()" ng-class="{\'-align-right\': float === \'right\'}"> <umb-dropdown-item ng-repeat="subButton in subButtons"> <button type="button" data-element="{{subButton.alias ? \'button-\' + subButton.alias : \'button-group-secondary-\' + $index }}" ng-click="executeMenuItem(subButton)" hotkey="{{subButton.hotKey}}" hotkey-when-hidden="{{subButton.hotKeyWhenHidden}}"> <localize key="{{subButton.labelKey}}">{{subButton.labelKey}}</localize> <span ng-if="subButton.addEllipsis === \'true\'">...</span> </button> </umb-dropdown-item> </umb-dropdown> </div> ',scope:{defaultButton:"=",subButtons:"=",state:"=?",direction:"@?",float:"@?",buttonStyle:"@?",size:"@?",icon:"@?",label:"@?",labelKey:"@?"},link:function link(scope){scope.dropdown={isOpen:!1},scope.toggleDropdown=function(){scope.dropdown.isOpen=!scope.dropdown.isOpen},scope.closeDropdown=function(){scope.dropdown.isOpen=!1},scope.executeMenuItem=function(subButton){subButton.handler(),scope.closeDropdown()}}}})}(),function(){angular.module("umbraco.directives").directive("umbToggle",function ToggleDirective(localizationService,eventsService,$timeout){return{restrict:"E",replace:!0,template:'<button role="checkbox" aria-checked="{{checked}}" ng-click="click()" type="button" class="umb-toggle" ng-disabled="disabled" ng-class="{\'umb-toggle--checked\': checked, \'umb-toggle--disabled\': disabled}" id="{{inputId}}"> <span ng-if="!labelPosition && showLabels === \'true\' || labelPosition === \'left\' && showLabels === \'true\'"> <span class="umb-toggle__label umb-toggle__label--left">{{ checked ? displayLabelOn : displayLabelOff }}</span> </span> <div class="umb-toggle__toggle"> <umb-icon ng-show="hideIcons !== \'true\'" icon="icon-check" class="umb-toggle__icon umb-toggle__icon--left"></umb-icon> <umb-icon ng-show="hideIcons !== \'true\'" icon="icon-wrong" class="umb-toggle__icon umb-toggle__icon--right"></umb-icon> <div class="umb-toggle__handler"></div> </div> <span ng-if="labelPosition === \'right\' && showLabels === \'true\'"> <span class="umb-toggle__label umb-toggle__label--right">{{ checked ? displayLabelOn : displayLabelOff }}</span> </span> </button> ',scope:{checked:"=",disabled:"=",inputId:"@",onClick:"&",labelOn:"@?",labelOff:"@?",labelPosition:"@?",showLabels:"@?",hideIcons:"@?"},link:function link(scope,el,attr,ctrl){scope.displayLabelOn="",scope.displayLabelOff="",scope.click=function(){scope.onClick&&(eventsService.emit("toggleValue",{value:!scope.checked}),scope.onClick())},function onInit(){scope.inputId=scope.inputId||"umb-toggle_"+String.CreateGuid(),function setLabelText(){scope.labelOn&&(scope.displayLabelOn=scope.labelOn),scope.labelOff&&(scope.displayLabelOff=scope.labelOff),0===scope.displayLabelOn.length&&0===scope.displayLabelOff.length&&localizationService.localizeMany(["general_on","general_off"]).then(function(data){scope.displayLabelOn=data[0],scope.displayLabelOff=data[1]})}(),$timeout(function(){eventsService.emit("toggleValue",{value:scope.checked})},100)}()}}})}(),function(){angular.module("umbraco.directives").directive("umbToggleGroup",function ToggleGroupDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-toggle-group"> <div class="umb-toggle-group-item" ng-repeat="item in items" ng-class="{\'umb-toggle-group-item--disabled\': item.disabled}"> <umb-toggle class="umb-toggle-group-item__toggle" checked="item.checked" disabled="item.disabled" input-id="{{item.inputId}}" on-click="change(item)"> </umb-toggle> <div class="umb-toggle-group-item__content" ng-click="change(item)"> <div><label for="{{item.inputId}}">{{ item.name }}</label> </div> <div class="umb-toggle-group-item__description">{{ item.description }}</div> </div> </div> </div> ',scope:{items:"=",onClick:"&"},link:function link(scope,el,attr,ctrl){for(var i=0;i<scope.items.length;i++)scope.items[i].inputId="umb-toggle-group-item_"+String.CreateGuid();scope.change=function(item){item.disabled||(item.checked=!item.checked,scope.onClick&&scope.onClick({item:item}))}}}})}(),function(){angular.module("umbraco.directives").controller("Umbraco.Editors.Content.EditorDirectiveController",function ContentEditController($rootScope,$scope,$routeParams,$q,$window,appState,contentResource,entityResource,navigationService,notificationsService,contentAppHelper,serverValidationManager,contentEditingHelper,localizationService,formHelper,umbRequestHelper,editorState,$http,eventsService,overlayService,$location,localStorageService,treeService,$exceptionHandler){var evts=[],infiniteMode=$scope.infiniteModel&&$scope.infiniteModel.infiniteMode,watchingCulture=!1;function startWatches(content){$scope.$watch("isNew",function(newVal,oldVal){$scope.page.isNew=Object.toBoolean(newVal),content.parentId&&-1!==content.parentId&&-20!==content.parentId&&(loadBreadcrumb(),watchingCulture||$scope.$watch("culture",function(value,oldValue){value!==oldValue&&loadBreadcrumb()}))})}function init(){var content=$scope.content;content.id&&content.isChildOfListView&&!1===content.trashed&&($scope.page.listViewPath="/content/content/edit/"+content.parentId+"?list="+$routeParams.list+"&page="+$routeParams.page+"&filter="+$routeParams.filter+"&orderBy="+$routeParams.orderBy+"&orderDirection="+$routeParams.orderDirection);var isAppPresent=!1;$scope.activeApp&&(_.forEach(content.apps,function(app){app.alias===$scope.activeApp.alias&&(isAppPresent=!0,$scope.appChanged(app))}),!1===isAppPresent&&($scope.activeApp=null)),null===$scope.activeApp&&content.apps.length?$scope.appChanged(content.apps[0]):createButtons($scope.content),editorState.set(content),function bindEvents(){for(var e in evts)eventsService.unsubscribe(evts[e]);evts.push(eventsService.on("editors.documentType.saved",function(name,args){args&&args.documentType&&$scope.content.documentType.id===args.documentType.id&&reload()})),evts.push(eventsService.on("editors.content.reload",function(name,args){args&&args.node&&$scope.content.id===args.node.id&&(reload(),loadBreadcrumb(),syncTreeNode($scope.content,$scope.content.path))})),evts.push(eventsService.on("rte.file.uploading",function(){$scope.page.saveButtonState="busy",$scope.page.buttonGroupState="busy"})),evts.push(eventsService.on("rte.file.uploaded",function(){$scope.page.saveButtonState="success",$scope.page.buttonGroupState="success"})),evts.push(eventsService.on("rte.shortcut.save",function(){$scope.page.showSaveButton&&$scope.save()})),evts.push(eventsService.on("content.saved",function(){localStorageService.clearAll(/^tinymce__/)}))}(),function resetVariantFlags(){if($scope.content.variants.length>1)for(var i=0;i<$scope.content.variants.length;i++){var v=$scope.content.variants[i];v.save&&(v.isDirty=!1),v.save=!1,v.publish=!1}else $scope.content.variants[0].save&&($scope.content.variants[0].isDirty=!1),$scope.content.variants[0].save=!0,$scope.content.variants[0].publish=!1}()}function loadBreadcrumb(){var id=$scope.page.isNew?$scope.content.parentId:$scope.content.id;id&&entityResource.getAncestors(id,"document",$scope.culture).then(function(anc){$scope.ancestors=anc})}function hasVariants(content){return content.variants.length>1}function reload(){$scope.page.loading=!0,$scope.page.isNew?loadScaffold().then(function(){$scope.page.loading=!1}):loadContent().then(function(){$scope.page.loading=!1})}function appendRuntimeData(){$scope.content.variants.forEach(function(variant){variant.compositeId=contentEditingHelper.buildCompositeVariantId(variant),variant.htmlId="_content_variant_"+variant.compositeId+"_"})}function loadContent(){return $scope.getMethod()($scope.contentId).then(function(data){return $scope.content=data,appendRuntimeData(),init(),syncTreeNode($scope.content,$scope.content.path,!0),resetLastListPageNumber($scope.content),eventsService.emit("content.loaded",{content:$scope.content}),$q.resolve($scope.content)})}function loadScaffold(){return $scope.getScaffoldMethod()().then(function(data){return $scope.content=data,appendRuntimeData(),init(),startWatches($scope.content),resetLastListPageNumber($scope.content),eventsService.emit("content.newReady",{content:$scope.content}),$q.resolve($scope.content)})}function createButtons(content){var isBlueprint=content.isBlueprint;if($scope.page.isNew&&-1!==$location.path().search(/contentBlueprints/i)&&(isBlueprint=!0),$scope.page.saveButtonStyle=content.trashed||content.isElement||isBlueprint?"primary":"info",$scope.activeApp&&!contentAppHelper.isContentBasedApp($scope.activeApp))return $scope.defaultButton=null,$scope.subButtons=null,$scope.page.showSaveButton=!1,void($scope.page.showPreviewButton=!1);_.contains($scope.content.allowedActions,"A")?($scope.page.showSaveButton=!0,$scope.page.saveButtonEllipsis=content.variants&&content.variants.length>1?"true":"false"):$scope.page.showSaveButton=!1,$scope.page.buttonGroupState="init";var buttons=contentEditingHelper.configureContentEditorButtons({create:$scope.page.isNew,content:content,methods:{saveAndPublish:$scope.saveAndPublish,sendToPublish:$scope.sendToPublish,unpublish:$scope.unpublish,schedulePublish:$scope.schedule,publishDescendants:$scope.publishDescendants}});$scope.defaultButton=buttons.defaultButton,$scope.subButtons=buttons.subButtons,$scope.page.showPreviewButton=!0}function syncTreeNode(content,path,initialLoad,reloadChildren){!infiniteMode&&path&&($scope.content.isChildOfListView?!0===initialLoad&&(navigationService.syncTree({tree:$scope.treeAlias,path:path.substring(0,path.lastIndexOf(",")).split(","),forceReload:!0!==initialLoad}),umbRequestHelper.resourcePromise($http.get(content.treeNodeUrl),"Failed to retrieve data for child node "+content.id).then(function(node){$scope.page.menu.currentNode=node})):navigationService.syncTree({tree:$scope.treeAlias,path:path.split(","),forceReload:!0!==initialLoad}).then(function(syncArgs){$scope.page.menu.currentNode=syncArgs.node,reloadChildren&&syncArgs.node.expanded&&treeService.loadNodeChildren({node:syncArgs.node})},function(){console.log("A problem occurred syncing the tree! A path is probably incorrect.")}))}function recurseFormControls(controls,array){for(var i=0;i<controls.length;i++){var controlItem=controls[i];if(controlItem.hasOwnProperty("$submitted"))recurseFormControls(controlItem.$getControls(),array);else if(controlItem.hasOwnProperty("$error")){var errorKeys=[];for(var key in controlItem.$error)errorKeys.push(key),controlItem.$setValidity(key,!0);var obj={control:controlItem,errorKeys:errorKeys};array.push(obj)}}return array}function resetNestedFieldValiation(array){for(var i=0;i<array.length;i++)for(var item=array[i],fieldControl=item.control,fieldErrorKeys=item.errorKeys,j=0;j<fieldErrorKeys.length;j++)fieldControl.$setValidity(fieldErrorKeys[j],!1)}function performSave(args){var fieldsToRollback=function checkValidility(){var allControls=$scope.contentForm.$getControls(),childFieldsToMarkAsValid=[];allControls=_.filter(allControls,function(obj){return"contentHeaderForm"!==obj.$name&&"tabbedContentForm"!==obj.$name&&obj.hasOwnProperty("$submitted")});for(var i=0;i<allControls.length;i++)childFieldsToMarkAsValid=recurseFormControls(allControls[i].$getControls(),childFieldsToMarkAsValid);return childFieldsToMarkAsValid}();return eventsService.emit("content.saving",{content:$scope.content,action:args.action}),contentEditingHelper.contentEditorPerformSave({saveMethod:args.saveMethod,scope:$scope,content:$scope.content,create:$scope.page.isNew,action:args.action,showNotifications:args.showNotifications,softRedirect:!0,skipValidation:args.skipValidation}).then(function(data){return init(),$scope.page.isNew=!1,syncTreeNode($scope.content,data.path,!1,args.reloadChildren),eventsService.emit("content.saved",{content:$scope.content,action:args.action,valid:!0}),!0!==$scope.contentForm.$invalid&&resetNestedFieldValiation(fieldsToRollback),function ensureDirtyIsSetIfAnyVariantIsDirty(){$scope.contentForm.$dirty=!1;for(var i=0;i<$scope.content.variants.length;i++)if($scope.content.variants[i].isDirty)return void($scope.contentForm.$dirty=!0)}(),$q.when(data)},function(err){return syncTreeNode($scope.content,$scope.content.path),!0!==$scope.contentForm.$invalid&&resetNestedFieldValiation(fieldsToRollback),err&&400===err.status&&err.data&&eventsService.emit("content.saved",{content:$scope.content,action:args.action,valid:!1}),$q.reject(err)})}function clearNotifications(content){if(content.notifications&&(content.notifications=[]),content.variants)for(var i=0;i<content.variants.length;i++)content.variants[i].notifications&&(content.variants[i].notifications=[])}function resetLastListPageNumber(content){content.isChildOfListView||content.isContainer||($rootScope.lastListViewPageViewed=null)}function clearDirtyState(variants){for(var i=0;i<variants.length;i++){var v=variants[i];v.notifications&&_.find(v.notifications,function(n){return 3===n.type})&&(v.isDirty=!1)}}function handleHttpException(err){err&&!err.status&&$exceptionHandler(err)}function showValidationNotification(){localizationService.localizeMany(["speechBubbles_validationFailedHeader","speechBubbles_validationFailedMessage"]).then(function(data){notificationsService.error(data[0],data[1])})}$scope.defaultButton=null,$scope.subButtons=[],$scope.page={},$scope.page.loading=!1,$scope.page.menu={},$scope.page.menu.currentNode=null,$scope.page.menu.currentSection=appState.getSectionState("currentSection"),$scope.page.listViewPath=null,$scope.page.isNew=!!$scope.isNew,infiniteMode&&($scope.page.allowInfinitePublishAndClose=$scope.infiniteModel.allowPublishAndClose,$scope.page.allowInfiniteSaveAndClose=$scope.infiniteModel.allowSaveAndClose),$scope.page.buttonGroupState="init",$scope.page.hideActionsMenu=!!infiniteMode,$scope.page.hideChangeVariant=!1,$scope.allowOpen=!0,$scope.activeApp=null,$scope.page.isNew?($scope.page.loading=!0,loadScaffold().then(function(){$scope.page.loading=!1})):($scope.page.loading=!0,loadContent().then(function(){startWatches($scope.content),$scope.page.loading=!1})),$scope.unpublish=function(){if(clearNotifications($scope.content),formHelper.submitForm({scope:$scope,action:"unpublish",skipValidation:!0})){var dialog={parentScope:$scope,view:"views/content/overlays/unpublish.html",variants:$scope.content.variants,skipFormValidation:!0,includeUnpublished:!1,submitButtonLabelKey:"content_unpublish",submitButtonStyle:"warning",submit:function submit(model){model.submitButtonState="busy";var selectedVariants=_.filter(model.variants,function(v){return v.save&&v.language}),culturesForUnpublishing=_.map(selectedVariants,function(v){return v.language.culture});contentResource.unpublish($scope.content.id,culturesForUnpublishing).then(function(data){formHelper.resetForm({scope:$scope}),contentEditingHelper.reBindChangedProperties($scope.content,data),init(),syncTreeNode($scope.content,data.path),$scope.page.buttonGroupState="success",eventsService.emit("content.unpublished",{content:$scope.content}),overlayService.close()},function(err){formHelper.resetForm({scope:$scope,hasErrors:!0}),$scope.page.buttonGroupState="error",handleHttpException(err)})},close:function close(){overlayService.close()}};overlayService.open(dialog)}},$scope.sendToPublish=function(){if(clearNotifications($scope.content),!hasVariants($scope.content))return $scope.page.buttonGroupState="busy",performSave({saveMethod:contentResource.sendToPublish,action:"sendToPublish"}).then(function(){$scope.page.buttonGroupState="success"},function(err){$scope.page.buttonGroupState="error",handleHttpException(err)});if(formHelper.submitForm({scope:$scope,action:"publish"})){var dialog={parentScope:$scope,view:"views/content/overlays/sendtopublish.html",variants:$scope.content.variants,skipFormValidation:!0,submitButtonLabelKey:"buttons_saveToPublish",submit:function submit(model){return model.submitButtonState="busy",clearNotifications($scope.content),performSave({saveMethod:contentResource.sendToPublish,action:"sendToPublish",showNotifications:!1}).then(function(data){return formHelper.showNotifications(data),clearNotifications($scope.content),overlayService.close(),$q.when(data)},function(err){clearDirtyState($scope.content.variants),model.submitButtonState="error",dialog.variants=$scope.content.variants,handleHttpException(err)})},close:function close(){overlayService.close()}};overlayService.open(dialog)}else showValidationNotification()},$scope.saveAndPublish=function(){if(clearNotifications($scope.content),!hasVariants($scope.content))return $scope.content.variants[0].save=!0,$scope.content.variants[0].publish=!0,$scope.page.buttonGroupState="busy",performSave({saveMethod:contentResource.publish,action:"publish"}).then(function(){$scope.page.buttonGroupState="success"},function(err){$scope.page.buttonGroupState="error",handleHttpException(err)});if(formHelper.submitForm({scope:$scope,action:"publish"})){var dialog={parentScope:$scope,view:"views/content/overlays/publish.html",variants:$scope.content.variants,skipFormValidation:!0,submitButtonLabelKey:"buttons_saveAndPublish",submit:function submit(model){return model.submitButtonState="busy",clearNotifications($scope.content),performSave({saveMethod:contentResource.publish,action:"publish",showNotifications:!1}).then(function(data){return formHelper.showNotifications(data),clearNotifications($scope.content),overlayService.close(),$q.when(data)},function(err){clearDirtyState($scope.content.variants),model.submitButtonState="error",dialog.variants=$scope.content.variants,handleHttpException(err)})},close:function close(){overlayService.close()}};overlayService.open(dialog)}else showValidationNotification()},$scope.save=function(){if(clearNotifications($scope.content),!hasVariants($scope.content))return $scope.content.variants[0].save=!0,$scope.page.saveButtonState="busy",performSave({saveMethod:$scope.saveMethod(),action:"save",skipValidation:!0}).then(function(){$scope.page.saveButtonState="success"},function(err){err&&err.data&&err.data.ModelState&&Object.keys(err.data.ModelState).length>0?$scope.page.saveButtonState="success":$scope.page.saveButtonState="error",handleHttpException(err)});var dialog={parentScope:$scope,view:"views/content/overlays/save.html",variants:$scope.content.variants,skipFormValidation:!0,submitButtonLabelKey:"buttons_save",submit:function submit(model){return model.submitButtonState="busy",clearNotifications($scope.content),performSave({saveMethod:$scope.saveMethod(),action:"save",showNotifications:!1,skipValidation:!0}).then(function(data){return formHelper.showNotifications(data),clearNotifications($scope.content),overlayService.close(),$q.when(data)},function(err){clearDirtyState($scope.content.variants),err&&err.data&&err.data.ModelState&&Object.keys(err.data.ModelState).length>0?model.submitButtonState="success":model.submitButtonState="error",dialog.variants=$scope.content.variants,handleHttpException(err)})},close:function close(oldModel){overlayService.close()}};overlayService.open(dialog)},$scope.schedule=function(){if(clearNotifications($scope.content),formHelper.submitForm({scope:$scope,action:"schedule"})){hasVariants($scope.content)||($scope.content.variants[0].save=!0);var dialog={parentScope:$scope,view:"views/content/overlays/schedule.html",variants:Utilities.copy($scope.content.variants),skipFormValidation:!0,submitButtonLabelKey:"buttons_schedulePublish",submit:function submit(model){for(var i=0;i<$scope.content.variants.length;i++)$scope.content.variants[i].releaseDate=model.variants[i].releaseDate,$scope.content.variants[i].expireDate=model.variants[i].expireDate,$scope.content.variants[i].releaseDateFormatted=model.variants[i].releaseDateFormatted,$scope.content.variants[i].expireDateFormatted=model.variants[i].expireDateFormatted,$scope.content.variants[i].save=model.variants[i].save;return model.submitButtonState="busy",clearNotifications($scope.content),performSave({saveMethod:contentResource.saveSchedule,action:"schedule",showNotifications:!1}).then(function(data){return formHelper.showNotifications(data),clearNotifications($scope.content),overlayService.close(),$q.when(data)},function(err){clearDirtyState($scope.content.variants),hasVariants($scope.content)||formHelper.showNotifications(err.data),model.submitButtonState="error",dialog.variants=Utilities.copy($scope.content.variants),handleHttpException(err)})},close:function close(){overlayService.close()}};overlayService.open(dialog)}else showValidationNotification()},$scope.publishDescendants=function(){if(clearNotifications($scope.content),formHelper.submitForm({scope:$scope,action:"publishDescendants"})){hasVariants($scope.content)||($scope.content.variants[0].save=!0,$scope.content.variants[0].publish=!0);var dialog={parentScope:$scope,view:"views/content/overlays/publishdescendants.html",variants:$scope.content.variants,skipFormValidation:!0,submitButtonLabelKey:"buttons_publishDescendants",submit:function submit(model){return model.submitButtonState="busy",clearNotifications($scope.content),performSave({saveMethod:function saveMethod(content,create,files,showNotifications){return contentResource.publishWithDescendants(content,create,model.includeUnpublished,files,showNotifications)},action:"publishDescendants",showNotifications:!1,reloadChildren:model.includeUnpublished}).then(function(data){return formHelper.showNotifications(data),clearNotifications($scope.content),overlayService.close(),$q.when(data)},function(err){clearDirtyState($scope.content.variants),hasVariants($scope.content)||formHelper.showNotifications(err.data),model.submitButtonState="error",dialog.variants=$scope.content.variants,handleHttpException(err)})},close:function close(){overlayService.close()}};overlayService.open(dialog)}else showValidationNotification()},$scope.preview=function(content){var previewWindow=$window.open("preview/?init=true","umbpreview"),query="id="+content.id;$scope.culture&&(query+="#?culture="+$scope.culture);var redirect=Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath+"/preview/?"+query;if(_.contains(content.allowedActions,"A")){var selectedVariant=$scope.content.variants[0];if($scope.culture){var found=_.find($scope.content.variants,function(v){return v.language&&v.language.culture===$scope.culture});found&&(selectedVariant=found)}selectedVariant.save=!0,performSave({saveMethod:$scope.saveMethod(),action:"save"}).then(function(data){previewWindow.location.href=redirect},function(err){})}else previewWindow.location.href=redirect},$scope.publishAndClose=function(content){$scope.publishAndCloseButtonState="busy",performSave({saveMethod:contentResource.publish,action:"publish"}).then(function(){$scope.infiniteModel.submit&&($scope.infiniteModel.contentNode=content,$scope.infiniteModel.submit($scope.infiniteModel)),$scope.publishAndCloseButtonState="success"})},$scope.saveAndClose=function(content){$scope.saveAndCloseButtonState="busy",performSave({saveMethod:$scope.saveMethod(),action:"save"}).then(function(){$scope.infiniteModel.submit&&($scope.infiniteModel.contentNode=content,$scope.infiniteModel.submit($scope.infiniteModel)),$scope.saveAndCloseButtonState="success"})},$scope.appChanged=function(activeApp){$scope.activeApp=activeApp,_.forEach($scope.content.apps,function(app){app.active=!1,app.alias===$scope.activeApp.alias&&(app.active=!0)}),$scope.$broadcast("editors.apps.appChanged",{app:activeApp}),createButtons($scope.content)},$scope.appAnchorChanged=function(app,anchor){$scope.$broadcast("editors.apps.appAnchorChanged",{app:app,anchor:anchor})},$scope.close=function(){$scope.infiniteModel.close&&$scope.infiniteModel.close($scope.infiniteModel)},$scope.onBack=function(){$scope.infiniteModel&&$scope.infiniteModel.close?$scope.infiniteModel.close($scope.infiniteModel):$location.path("/"+$routeParams.section+"/"+$routeParams.tree+"/"+$routeParams.method+"/"+$scope.content.parentId)},$scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e]);serverValidationManager.clear()})}),angular.module("umbraco.directives").directive("contentEditor",function createDirective(){return{restrict:"E",replace:!0,template:'<div> <umb-load-indicator ng-if="page.loading"></umb-load-indicator> <form name="contentForm" ng-submit="save()" novalidate val-form-manager> <umb-editor-view ng-if="!page.loading"> <umb-variant-content-editors page="page" content="content" culture="culture" segment="segment" on-select-app="appChanged(app)" on-select-app-anchor="appAnchorChanged(app, anchor)" on-back="onBack()" show-back="!(infiniteModel && infiniteModel.infiniteMode)"> </umb-variant-content-editors> <umb-editor-footer> <umb-editor-footer-content-left> <umb-breadcrumbs ng-if="ancestors && ancestors.length > 0" ancestors="ancestors" for-new-entity="page.isNew" entity-type="content"> </umb-breadcrumbs> </umb-editor-footer-content-left> <umb-editor-footer-content-right> <umb-button ng-if="infiniteModel.infiniteMode" action="close()" button-style="link" label-key="general_close" shortcut="esc" type="button"> </umb-button> <umb-button alias="preview" ng-if="!page.isNew && content.allowPreview && page.showPreviewButton" type="button" button-style="link" action="preview(content)" label-key="buttons_saveAndPreview"> </umb-button> <umb-button ng-if="page.showSaveButton" alias="save" type="button" button-style="{{page.saveButtonStyle}}" state="page.saveButtonState" action="save(content)" label-key="buttons_save" shortcut="ctrl+s" add-ellipsis="{{page.saveButtonEllipsis}}"> </umb-button> <umb-button-group ng-if="defaultButton && !content.trashed && !content.isElement" button-style="success" default-button="defaultButton" sub-buttons="subButtons" state="page.buttonGroupState" direction="up" float="right" label-key="buttons_morePublishingOptions" label="More publishing options"> </umb-button-group> <umb-button ng-if="infiniteModel.infiniteMode && page.allowInfiniteSaveAndClose" action="saveAndClose(content)" button-style="primary" state="saveAndCloseButtonState" label-key="buttons_saveAndClose" type="button"> </umb-button> <umb-button ng-if="infiniteModel.infiniteMode && page.allowInfinitePublishAndClose" action="publishAndClose(content)" button-style="primary" state="publishAndCloseButtonState" label-key="buttons_publishAndClose" type="button"> </umb-button> </umb-editor-footer-content-right> </umb-editor-footer> </umb-editor-view> </form> </div> ',controller:"Umbraco.Editors.Content.EditorDirectiveController",scope:{contentId:"=",isNew:"=?",treeAlias:"@",page:"=?",saveMethod:"&",getMethod:"&",getScaffoldMethod:"&?",culture:"=?",segment:"=?",infiniteModel:"=?"}}})}(),function(){angular.module("umbraco.directives").directive("umbContentNodeInfo",function ContentNodeInfoDirective($timeout,logResource,eventsService,userService,localizationService,dateHelper,editorService,redirectUrlsResource,overlayService,entityResource){return{require:"^^umbVariantContent",restrict:"E",replace:!0,template:'<div class="umb-package-details"> <div class="umb-package-details__main-content"> <umb-box ng-if="currentUrls" data-element="node-info-urls"> <umb-box-header title-key="general_links"></umb-box-header> <umb-box-content class="block-form"> <ul class="nav nav-stacked mb0"> <li ng-repeat="url in currentUrls"> <a href="{{url.text}}" target="_blank" rel="noopener" ng-if="url.isUrl" class="umb-outline"> <span ng-if="currentUrlsHaveMultipleCultures && url.culture" style="font-size: 13px; color: #cccccc; width: 55px;display: inline-block">{{url.culture}}</span> <umb-icon icon="icon-out" class="icon"></umb-icon> <span>{{url.text}}</span> </a> <div ng-if="!url.isUrl" style="margin-top: 4px;"> <span ng-if="currentUrlsHaveMultipleCultures && url.culture" style="font-size: 13px; color: #cccccc; width: 55px;display: inline-block">{{url.culture}}</span> <em>{{url.text}}</em> </div> </li> </ul> </umb-box-content> </umb-box> <umb-box data-element="node-info-redirects" ng-cloak ng-show="!urlTrackerDisabled && hasRedirects"> <umb-box-header title-key="redirectUrls_redirectUrlManagement"></umb-box-header> <umb-box-content class="block-form"> <div style="position: relative;"> <div ng-if="loadingRedirectUrls" style="background: rgba(255, 255, 255, 0.8); position: absolute; top: 0; left: 0; right: 0; bottom: 0;"></div> <umb-load-indicator ng-if="loadingRedirectUrls"></umb-load-indicator> <div ng-show="hasRedirects"> <p><localize key="redirectUrls_panelInformation" class="ng-isolate-scope ng-scope">The following URLs redirect to this content item:</localize></p> <ul class="nav nav-stacked" style="margin-bottom: 0;"> <li ng-repeat="redirectUrl in redirectUrls"> <a href="{{redirectUrl.originalUrl}}" target="_blank" rel="noopener" class="umb-outline"> <umb-icon icon="icon-out" class="icon"></umb-icon> {{redirectUrl.originalUrl}} </a> </li> </ul> </div> </div> </umb-box-content> </umb-box> <umb-box data-element="node-info-history"> <umb-box-header title-key="{{historyLabelKey}}" ng-if="historyLabelKey"> <umb-button ng-hide="node.trashed || node.id === 0" type="button" button-style="outline" action="openRollback()" label-key="actions_rollback" size="xs" add-ellipsis="true"> </umb-button> </umb-box-header> <umb-box-content class="block-form"> <div style="position: relative;"> <div ng-show="loadingAuditTrail" style="background: rgba(255, 255, 255, 0.8); position: absolute; top: 0; left: 0; right: 0; bottom: 0;"></div> <umb-load-indicator ng-show="loadingAuditTrail"></umb-load-indicator> <div ng-show="auditTrail.length === 0" style="padding: 10px;"> <umb-empty-state position="center" size="small"> <localize key="content_noChanges"></localize> </umb-empty-state> </div> <div class="history"> <div ng-show="auditTrail.length > 1" class="history-line"></div> <div class="history-item" ng-repeat="item in auditTrail"> <div class="history-item__break"> <div class="history-item__avatar"> <umb-avatar color="secondary" size="xs" name="{{item.userName}}" img-src="{{item.userAvatars[3]}}" img-srcset="{{item.userAvatars[4]}} 2x, {{item.userAvatars[4]}} 3x"> </umb-avatar> </div> <div> <div>{{ item.userName }}</div> <div class="history-item__date">{{item.timestampFormatted}}</div> </div> </div> <div class="history-item__break"> <umb-badge class="history-item__badge" size="xs" color="{{item.logTypeColor}}"> <localize key="auditTrails_small{{ item.logType }}">{{ item.logType }}</localize> </umb-badge> <span class="history-item__description"> <localize key="auditTrails_{{ item.logType | lowercase }}" tokens="[item.parameters]">{{ item.comment }}</localize> </span> </div> </div> </div> </div> <div class="flex justify-center"> <umb-pagination ng-if="auditTrailOptions.totalPages > 1" page-number="auditTrailOptions.pageNumber" total-pages="auditTrailOptions.totalPages" on-change="auditTrailPageChange(pageNumber)"> </umb-pagination> </div> </umb-box-content> </umb-box> </div> <div class="umb-package-details__sidebar"> <umb-box data-element="node-info-general"> <umb-box-header title-key="general_general"></umb-box-header> <umb-box-content class="block-form"> <umb-control-group data-element="node-info-status" label="@general_status"> <umb-badge size="xs" color="{{status.color}}"> <umb-variant-state variant="currentVariant"></umb-variant-state> </umb-badge> </umb-control-group> <umb-control-group ng-show="node.id !== 0" data-element="node-info-create-date" label="@template_createdDate"> {{currentVariant.createDateFormatted}} </umb-control-group> <umb-control-group ng-show="node.id !== 0 && currentVariant.releaseDateFormatted" data-element="node-info-publish-date" label="@content_releaseDate"> {{currentVariant.releaseDateFormatted}} </umb-control-group> <umb-control-group ng-show="node.id !== 0 && currentVariant.expireDateFormatted" data-element="node-info-expire-date" label="@content_expireDate"> {{currentVariant.expireDateFormatted}} </umb-control-group> <umb-control-group data-element="node-info-document-type" label="@content_documentType"> <umb-node-preview style="min-width: 100%; margin-bottom: 0;" icon="node.icon" name="node.contentTypeName" alias="documentType.alias" allow-open="allowChangeDocumentType" on-open="openDocumentType(documentType)"> </umb-node-preview> </umb-control-group> <umb-control-group ng-if="disableTemplates == false" data-element="node-info-template" label="@template_template" alias="template"> <div class="flex items-center"> <select class="input-block-level" id="template" ng-model="node.template" ng-options="key as value for (key, value) in availableTemplates" ng-change="updateTemplate(node.template)"> <option>{{chooseLabel}}...</option> </select> <button type="button" ng-show="allowChangeTemplate && node.template !== null" class="umb-node-preview__action" style="margin-left:15px;" ng-click="openTemplate()"> <localize key="general_open">Open</localize><span class="sr-only">&nbsp;{{node.template}} <localize key="template_template"></localize></span> </button> </div> </umb-control-group> <umb-control-group ng-show="node.id !== 0" data-element="node-info-id" label="Id"> <div>{{ node.id }}</div> <small>{{ node.key }}</small> </umb-control-group> </umb-box-content> </umb-box> </div> </div> ',scope:{node:"="},link:function link(scope){var evts=[],isInfoTab=!1,auditTrailLoaded=!1,labels={};function openDocTypeEditor(documentType){var editor={id:documentType.id,submit:function submit(model){editorService.close()},close:function close(){editorService.close()}};editorService.documentTypeEditor(editor)}function loadAuditTrail(forceReload){auditTrailLoaded&&!forceReload||(scope.loadingAuditTrail=!0,logResource.getPagedEntityLog(scope.auditTrailOptions).then(function(data){userService.getCurrentUser().then(function(currentUser){Utilities.forEach(data.items,function(item){item.timestampFormatted=dateHelper.getLocalDate(item.timestamp,currentUser.locale,"LLL")})}),scope.auditTrail=data.items,scope.auditTrailOptions.pageNumber=data.pageNumber,scope.auditTrailOptions.pageSize=data.pageSize,scope.auditTrailOptions.totalItems=data.totalItems,scope.auditTrailOptions.totalPages=data.totalPages,function setAuditTrailLogTypeColor(auditTrail){Utilities.forEach(auditTrail,function(item){switch(item.logType){case"Save":item.logTypeColor="primary";break;case"Publish":case"PublishVariant":item.logTypeColor="success";break;case"Unpublish":case"UnpublishVariant":item.logTypeColor="warning";break;case"Delete":item.logTypeColor="danger";break;default:item.logTypeColor="gray"}})}(scope.auditTrail),scope.loadingAuditTrail=!1,auditTrailLoaded=!0}))}function loadRedirectUrls(){scope.loadingRedirectUrls=!0,redirectUrlsResource.getEnableState().then(function(response){scope.urlTrackerDisabled=!0!==response.enabled,!1===scope.urlTrackerDisabled?redirectUrlsResource.getRedirectsForContentItem(scope.node.udi).then(function(data){scope.redirectUrls=data.searchResults,scope.hasRedirects=void 0!==data.searchResults&&data.searchResults.length>0,scope.loadingRedirectUrls=!1}):scope.loadingRedirectUrls=!1})}function setNodePublishStatus(){scope.status={},!0!==scope.node.trashed?"NotCreated"===scope.currentVariant.state?scope.status.color="gray":"Draft"===scope.currentVariant.state?scope.status.color="gray":"Published"===scope.currentVariant.state?scope.status.color="success":"PublishedPendingChanges"===scope.currentVariant.state&&(scope.status.color="success"):scope.status.color="danger"}function formatDatesToLocal(){userService.getCurrentUser().then(function(currentUser){scope.currentVariant.createDateFormatted=dateHelper.getLocalDate(scope.currentVariant.createDate,currentUser.locale,"LLL"),scope.currentVariant.releaseDateFormatted=dateHelper.getLocalDate(scope.currentVariant.releaseDate,currentUser.locale,"LLL"),scope.currentVariant.expireDateFormatted=dateHelper.getLocalDate(scope.currentVariant.expireDate,currentUser.locale,"LLL")})}function updateCurrentUrls(){scope.node.isElement||null===scope.node.urls?scope.currentUrls=null:(scope.currentUrls=_.filter(scope.node.urls,function(url){return null==scope.currentVariant.language||scope.currentVariant.language.culture===url.culture}),scope.currentUrlsHaveMultipleCultures=_.keys(_.groupBy(scope.currentUrls,function(url){return url.culture})).length>1)}scope.publishStatus=[],scope.currentVariant=null,scope.currentUrls=[],scope.disableTemplates=Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates,scope.allowChangeDocumentType=!1,scope.allowChangeTemplate=!1,scope.allTemplates=[],scope.historyLabelKey=scope.node.variants&&1===scope.node.variants.length?"general_history":"auditTrails_historyIncludingVariants",scope.auditTrailPageChange=function(pageNumber){scope.auditTrailOptions.pageNumber=pageNumber,loadAuditTrail(!0)},scope.openDocumentType=function(documentType){if(_.some(scope.node.variants,function(variant){return variant.isDirty})){var confirm={title:labels.unsavedChanges,view:"default",content:labels.doctypeChangeWarning,submitButtonLabelKey:"general_continue",submitButtonStyle:"warning",closeButtonLabelKey:"general_cancel",submit:function submit(){openDocTypeEditor(documentType),overlayService.close()},close:function close(){overlayService.close()}};overlayService.open(confirm)}else openDocTypeEditor(documentType)},scope.openTemplate=function(){var template=_.findWhere(scope.allTemplates,{alias:scope.node.template});if(template){var templateEditor={id:template.id,submit:function submit(model){editorService.close()},close:function close(){editorService.close()}};editorService.templateEditor(templateEditor)}},scope.updateTemplate=function(templateAlias){scope.node.template=templateAlias},scope.openRollback=function(){var rollback={node:scope.node,submit:function submit(model){var args={node:scope.node};eventsService.emit("editors.content.reload",args),editorService.close()},close:function close(){editorService.close()}};editorService.rollback(rollback)},evts.push(eventsService.on("app.tabChange",function(event,args){$timeout(function(){"umbInfo"===args.alias?(isInfoTab=!0,loadAuditTrail(),loadRedirectUrls(),setNodePublishStatus(),formatDatesToLocal()):isInfoTab=!1})})),scope.$watch("node.updateDate",function(newValue,oldValue){newValue&&newValue!==oldValue&&(isInfoTab&&(loadAuditTrail(!0),loadRedirectUrls(),setNodePublishStatus(),formatDatesToLocal()),updateCurrentUrls())}),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])}),function onInit(){entityResource.getAll("Template").then(function(templates){scope.allTemplates=templates}),scope.currentVariant=_.find(scope.node.variants,function(v){return v.active}),updateCurrentUrls(),scope.isInfiniteMode=editorService.getNumberOfEditors()>0,userService.getCurrentUser().then(function(user){var hasAccessToSettings=-1!==user.allowedSections.indexOf("settings");scope.allowChangeDocumentType=hasAccessToSettings,scope.allowChangeTemplate=hasAccessToSettings}),localizationService.localizeMany(["general_deleted","content_unpublished","content_published","content_publishedPendingChanges","content_notCreated","prompt_unsavedChanges","prompt_doctypeChangeWarning","content_itemNotPublished","general_choose"]).then(function(data){var _data=_slicedToArray(data,9);labels.deleted=_data[0],labels.unpublished=_data[1],labels.published=_data[2],labels.publishedPendingChanges=_data[3],labels.notCreated=_data[4],labels.unsavedChanges=_data[5],labels.doctypeChangeWarning=_data[6],labels.notPublished=_data[7],scope.chooseLabel=_data[8],setNodePublishStatus(),scope.currentUrls&&0===scope.currentUrls.length&&(scope.node.id>0?scope.currentUrls.push({text:labels.notPublished,isUrl:!1}):scope.currentUrls.push({text:labels.notCreated,isUrl:!1}))}),scope.auditTrailOptions={id:scope.node.id},formatDatesToLocal(),scope.availableTemplates=scope.node.allowedTemplates,scope.documentType=scope.node.documentType,scope.urlTrackerDisabled=!1,null!==scope.documentType&&(scope.previewOpenUrl="#/settings/documentTypes/edit/"+scope.documentType.id),"umbInfo"===_.find(scope.node.apps,function(a){return a.active}).alias&&(loadRedirectUrls(),loadAuditTrail()),scope.disableTemplates=scope.disableTemplates||scope.node.isElement}()}}})}(),function(){angular.module("umbraco.directives").directive("umbTabbedContent",function tabbedContentDirective($timeout,$filter,contentEditingHelper,contentTypeHelper){return{restrict:"E",replace:!0,template:'<div> <ng-form name="tabbedContentForm"> <umb-editor-tab-bar ng-if="tabs.length > 0"> <umb-tabs-nav tabs="tabs" on-tab-change="setActiveTab(tab)"></umb-tabs-nav> </umb-editor-tab-bar> <umb-box ng-repeat="tab in tabs track by tab.key" ng-show="tab.alias === activeTabAlias && tab.properties.length > 0"> <umb-box-content data-element="tab-content-{{tab.alias}}"> <umb-property data-element="property-{{property.alias}}" ng-repeat="property in tab.properties track by property.alias" property="property" show-inherit="propertyEditorDisabled(property)" inherits-from="defaultVariant.displayName"> <div ng-class="{\'o-40 cursor-not-allowed\': propertyEditorDisabled(property) }"> <umb-property-editor model="property" preview="propertyEditorDisabled(property)"> </umb-property-editor> </div> </umb-property> </umb-box-content> </umb-box> <div class="umb-group-panel" retrive-dom-element="registerPropertyGroup(element[0], attributes.appAnchor)" data-app-anchor="{{group.id}}" data-element="group-{{group.alias}}" ng-repeat="group in content.tabs track by group.key" ng-if="group.type === \'Group\'" ng-show="group.parentAlias === activeTabAlias || tabs.length === 0"> <div class="umb-group-panel__header"> <div id="group-{{group.id}}">{{ group.label }}</div> </div> <div class="umb-group-panel__content" data-element="tab-content-{{group.type === \'Group\' ? group.parentAlias : group.alias}}"> <umb-property data-element="property-{{property.alias}}" ng-repeat="property in group.properties track by property.alias" property="property" show-inherit="propertyEditorDisabled(property)" inherits-from="defaultVariant.displayName"> <div ng-class="{\'o-40 cursor-not-allowed\': propertyEditorDisabled(property) }"> <umb-property-editor model="property" preview="propertyEditorDisabled(property)"> </umb-property-editor> </div> </umb-property> </div> </div> <umb-empty-state ng-if="content.tabs.length === 0" position="center"> <localize key="content_noProperties"></localize> </umb-empty-state> </ng-form> </div> ',controller:function controller($scope){this.content=$scope.content,$scope.contentNodeModel&&($scope.defaultVariant=_.find($scope.contentNodeModel.variants,function(variant){return!variant.segment&&(variant.language&&variant.language.isDefault||!variant.language)})),$scope.unlockInvariantValue=function(property){property.unlockInvariantValue=!property.unlockInvariantValue},$scope.$watch("tabbedContentForm.$dirty",function(newValue,oldValue){!0===newValue&&($scope.content.isDirty=!0)}),$scope.propertyEditorDisabled=function(property){if(property.unlockInvariantValue)return!1;var contentLanguage=$scope.content.language,canEditCulture=!contentLanguage||property.culture===contentLanguage.culture||null==property.culture&&contentLanguage.isDefault,canEditSegment=property.segment===$scope.content.segment;return!canEditCulture||!canEditSegment}},link:function link($scope,$element){var appRootNode=$element[0],propertyGroupNodesDictionary={},scrollableNode=appRootNode.closest(".umb-scrollable");function onScroll(event){var viewFocusY=scrollableNode.scrollTop+.5*scrollableNode.clientHeight;for(var i in $scope.content.tabs){var group=$scope.content.tabs[i],node=propertyGroupNodesDictionary[group.id];if(!node)return;if(viewFocusY>=node.offsetTop&&viewFocusY<=node.offsetTop+node.clientHeight)return void setActiveAnchor(group)}}function setActiveAnchor(tab){if(!0!==tab.active){for(var i=$scope.content.tabs.length;i--;)$scope.content.tabs[i].active=!1;tab.active=!0}}function getScrollPositionFor(id){return propertyGroupNodesDictionary[id]?propertyGroupNodesDictionary[id].offsetTop-20:null}function cancelScrollTween(){$scope.scrollTween&&$scope.scrollTween.pause()}$scope.activeTabAlias=null,$scope.tabs=[],$scope.$watchCollection("content.tabs",function(newValue){contentTypeHelper.defineParentAliasOnGroups(newValue),contentTypeHelper.relocateDisorientedGroups(newValue),$scope.tabs=$filter("filter")(newValue,function(tab){return tab.type===contentTypeHelper.TYPE_TAB}),$scope.tabs.length>0?(contentEditingHelper.registerGenericTab(newValue),$scope.setActiveTab($scope.tabs[0]),scrollableNode.removeEventListener("scroll",onScroll),scrollableNode.removeEventListener("mousewheel",cancelScrollTween)):(scrollableNode.addEventListener("scroll",onScroll),scrollableNode.addEventListener("mousewheel",cancelScrollTween))}),$scope.registerPropertyGroup=function(element,appAnchor){propertyGroupNodesDictionary[appAnchor]=element},$scope.setActiveTab=function(tab){$scope.activeTabAlias=tab.alias,$scope.tabs.forEach(function(tab){return tab.active=!1}),tab.active=!0},$scope.$on("editors.apps.appChanged",function($event,$args){if("umbContent"===$args.app.alias&&0===$scope.tabs.length){var activeAnchor=function getActiveAnchor(){for(var i=$scope.content.tabs.length;i--;)if(!0===$scope.content.tabs[i].active)return $scope.content.tabs[i];return!1}();$timeout(function jumpTo(id){var y=getScrollPositionFor(id);null!==getScrollPositionFor&&(cancelScrollTween(),scrollableNode.scrollTo(0,y))}.bind(null,[activeAnchor.id]))}}),$scope.$on("editors.apps.appAnchorChanged",function($event,$args){"umbContent"===$args.app.alias&&(setActiveAnchor($args.anchor),function scrollTo(id){var y=getScrollPositionFor(id);if(null!==getScrollPositionFor){var viewportHeight=scrollableNode.clientHeight,from=scrollableNode.scrollTop,to=Math.min(y,scrollableNode.scrollHeight-viewportHeight),animeObject={_y:from};$scope.scrollTween=anime({targets:animeObject,_y:to,easing:"easeOutExpo",duration:200+Math.min(Math.abs(to-from)/viewportHeight*100,400),update:function update(){scrollableNode.scrollTo(0,animeObject._y)}})}}($args.anchor.id))}),$scope.$on("$destroy",function(){cancelScrollTween(),scrollableNode.removeEventListener("scroll",onScroll),scrollableNode.removeEventListener("mousewheel",cancelScrollTween)})},scope:{content:"=",contentNodeModel:"=?",contentApp:"=?"}}})}(),function(){var umbVariantContent={template:' <div> <umb-load-indicator ng-if="vm.editor.loading"> </umb-load-indicator> <div class="umb-split-view__content" ng-show="!vm.editor.loading"> <ng-form name="contentHeaderForm" ng-if="vm.content.apps.length > 0"> <umb-editor-content-header menu="vm.page.menu" hide-actions-menu="vm.page.hideActionsMenu" disable-actions-menu="vm.disableActionsMenu" name="vm.editor.content.name" name-disabled="vm.nameDisabled" editor="vm.editor" content="vm.content" on-select-navigation-item="vm.selectApp(item)" on-select-anchor-item="vm.selectAppAnchor(item, anchor)" hide-change-variant="vm.page.hideChangeVariant" show-back-button="vm.showBackButton()" on-back="vm.onBack()" split-view-open="vm.editorCount > 1" on-open-in-split-view="vm.openSplitView(variant)" on-close-split-view="vm.onCloseSplitView()" on-select-variant="vm.selectVariant(variant)" server-validation-name-field="{{\'Variants[\' + vm.editorIndex + \'].Name\'}}"> </umb-editor-content-header> </ng-form> <umb-editor-container ng-if="vm.content.apps.length > 0">  <div ng-show="vm.content.trashed" class="umb-editor--trashed-message"> <umb-icon icon="icon-trash" class="icon"></umb-icon> <localize key="content_nodeIsInTrash">This item is in the Recycle Bin</localize> </div> <div class="umb-editor-sub-views"> <div ng-repeat="app in vm.editor.variantApps track by app.alias"> <umb-editor-sub-view model="app" content="vm.content" variant-content="vm.editor.content"> </umb-editor-sub-view> </div> </div> </umb-editor-container> <umb-empty-state ng-if="vm.content.apps.length === 0" position="center"> <localize key="content_noProperties"></localize> </umb-empty-state> </div> </div> ',bindings:{content:"<",page:"<",editor:"<",editorIndex:"<",editorCount:"<",onCloseSplitView:"&",onSelectVariant:"&",onOpenSplitView:"&",onSelectApp:"&",onSelectAppAnchor:"&",onBack:"&?",showBack:"<?"},controllerAs:"vm",controller:function umbVariantContentController($scope,contentAppHelper){var unsubscribe=[],vm=this;function onAppChanged(activeApp){vm.nameDisabled=activeApp&&!contentAppHelper.isContentBasedApp(activeApp)}vm.$onInit=function onInit(){vm.editor.variantApps=Utilities.copy(vm.content.apps),onAppChanged(vm.content.apps.find(function(app){return app.active}))},vm.$postLink=function postLink(){unsubscribe.push($scope.$watch("vm.editor.content.name",function(newValue,oldValue){newValue!==oldValue&&(vm.editor.content.isDirty=!0)}))},vm.$onDestroy=function onDestroy(){for(var i=0;i<unsubscribe.length;i++)unsubscribe[i]()},vm.selectVariant=function selectVariant(variant){vm.onSelectVariant&&vm.onSelectVariant({variant:variant})},vm.openSplitView=function openSplitView(variant){vm.onOpenSplitView&&vm.onOpenSplitView({variant:variant})},vm.selectApp=function selectApp(item){vm.onSelectApp&&vm.onSelectApp({app:item})},vm.selectAppAnchor=function selectAppAnchor(item,anchor){vm.onSelectAppAnchor&&vm.onSelectAppAnchor({app:item,anchor:anchor})},vm.showBackButton=function showBackButton(){return null!==vm.page.listViewPath&&vm.showBack},$scope.$on("editors.apps.appChanged",function($event,$args){var activeApp=$args.app;_.forEach(vm.editor.variantApps,function(app){app.active=app.alias===activeApp.alias}),onAppChanged(activeApp)}),$scope.$on("listView.itemsChanged",function($event,$args){vm.disableActionsMenu=$args.items.length>0})}};angular.module("umbraco.directives").component("umbVariantContent",umbVariantContent)}(),function(){var umbVariantContentEditors={template:' <div class="umb-split-views"> <div class="umb-split-view" ng-repeat="editor in vm.editors track by editor.compositeId"> <umb-variant-content page="vm.page" content="vm.content" editor="editor" editor-index="$index" editor-count="vm.editors.length" on-open-split-view="vm.openSplitView(variant)" on-close-split-view="vm.closeSplitView($index)" on-select-variant="vm.selectVariant(variant, $index)" on-select-app="vm.selectApp(app)" on-select-app-anchor="vm.selectAppAnchor(app, anchor)" on-back="vm.onBack()" show-back="vm.showBack"> </umb-variant-content> </div> </div> ',bindings:{page:"<",content:"<",culture:"<",segment:"<",onSelectApp:"&?",onSelectAppAnchor:"&?",onBack:"&?",showBack:"<?"},controllerAs:"vm",controller:function umbVariantContentEditorsController($scope,$location,eventsService){var prevContentDateUpdated=null,vm=this;function splitViewChanged(){$scope.$broadcast("editors.content.splitViewChanged",{editors:vm.editors})}function setActiveVariant(){var activeVariant=null;if(vm.content.variants.forEach(function(v){("invariant"===vm.culture||v.language&&v.language.culture===vm.culture)&&v.segment===vm.segment&&(activeVariant=v)}),activeVariant||(activeVariant=vm.content.variants[0]),insertVariantEditor(0,activeVariant),vm.editors.length>1)for(var s=1;s<vm.editors.length;s++){var variant=vm.content.variants.find(function(v){return(!v.language||v.language.culture===vm.editors[s].content.language.culture)&&v.segment===vm.editors[s].content.segment});vm.editors[s].content=variant}vm.content.variants.length>1&&eventsService.emit("editors.content.cultureChanged",activeVariant.language)}function insertVariantEditor(index,variant){if(vm.editors[index]){if(vm.editors[index].content===variant)return;vm.editors[index].content.active=!1}variant.active=!0;var variantCulture=variant.language?variant.language.culture:"invariant",variantSegment=variant.segment,currentCulture=index<vm.editors.length?vm.editors[index].culture:null,currentSegment=index<vm.editors.length?vm.editors[index].segment:null;index>=vm.editors.length||currentCulture!==variantCulture||currentSegment!==variantSegment?vm.editors.splice(index,1,{compositeId:variant.compositeId,content:variant,culture:variantCulture,segment:variantSegment}):vm.editors[index].content=variant}function openSplitView(selectedVariant){var contentApp=vm.content.apps.find(function(app){return"umbContent"===app.alias});contentApp&&selectApp(contentApp),insertVariantEditor(vm.editors.length,selectedVariant),splitViewChanged()}function requestSplitView(args){var culture=args.culture,segment=args.segment,variant=vm.content.variants.find(function(v){return(!v.language||v.language.culture===culture)&&v.segment===segment});null!=variant&&openSplitView(variant)}vm.$onInit=function onInit(){prevContentDateUpdated=Utilities.copy(vm.content.updateDate),setActiveVariant()},vm.$onChanges=function onChanges(changes){changes.culture&&!changes.culture.isFirstChange()&&changes.culture.currentValue!==changes.culture.previousValue?setActiveVariant():changes.segment&&!changes.segment.isFirstChange()&&changes.segment.currentValue!==changes.segment.previousValue&&setActiveVariant()},vm.$doCheck=function doCheck(){Utilities.equals(vm.content.updateDate,prevContentDateUpdated)||(setActiveVariant(),prevContentDateUpdated=Utilities.copy(vm.content.updateDate))},vm.$postLink=function postLink(){},vm.openSplitView=openSplitView,vm.closeSplitView=function closeSplitView(editorIndex){var editor=vm.editors[editorIndex];vm.editors.splice(editorIndex,1),editor.content.active=!1;var culture=vm.editors[0].content.language?vm.editors[0].content.language.culture:null;$location.search({cculture:culture,csegment:vm.editors[0].content.segment}),splitViewChanged(),unbindSplitViewRequest()},vm.selectVariant=function selectVariant(variant,editorIndex){var variantCulture=variant.language?variant.language.culture:"invariant",variantSegment=variant.segment||null;if(vm.editors.find(function(editor){return(!editor.content.language||editor.content.language.culture===variantCulture)&&editor.content.segment===variantSegment}))return;0===editorIndex?$location.search("cculture",variantCulture).search("csegment",variantSegment):insertVariantEditor(editorIndex,variant)},vm.selectApp=selectApp,vm.selectAppAnchor=function selectAppAnchor(app,anchor){vm.onSelectAppAnchor&&vm.onSelectAppAnchor({app:app,anchor:anchor})},vm.requestSplitView=requestSplitView,vm.getScope=function getScope(){return $scope},vm.editors=[];var unbindSplitViewRequest=eventsService.on("editors.content.splitViewRequest",function(_,args){return requestSplitView(args)});function selectApp(app){vm.onSelectApp&&vm.onSelectApp({app:app})}$scope.$on("$destroy",function(){return unbindSplitViewRequest()})}};angular.module("umbraco.directives").component("umbVariantContentEditors",umbVariantContentEditors)}(),function(){var umbNotificationListComponent={template:' <span class="db" ng-repeat="notification in vm.notifications">   <span class="db umb-list-item__description" ng-class="{\'text-success\': notification.type === 3, \'text-error\': notification.type === 2 || notification.type === 4}"> {{notification.message}} </span> </span> ',bindings:{notifications:"<"},controllerAs:"vm",controller:function umbNotificationList(){}};angular.module("umbraco.directives").component("umbVariantNotificationList",umbNotificationListComponent)}(),function(){var umbVariantStateComponent={template:' <span ng-switch="vm.variant.state"> <span ng-switch-when="NotCreated"><localize key="content_notCreated"></localize></span> <span ng-switch-when="Draft"><localize key="content_unpublished"></localize></span> <span ng-switch-when="PublishedPendingChanges"><localize key="content_publishedPendingChanges"></localize></span> <span ng-switch-when="Published"><localize key="content_published"></localize></span> </span> ',bindings:{variant:"<"},controllerAs:"vm",controller:function umbVariantStateController($scope,$element){}};angular.module("umbraco.directives").component("umbVariantState",umbVariantStateComponent)}(),function(){var umbContentTypeGroupComponent={template:'<div data-element="group-{{vm.group.name}}" class="umb-group-builder__group" ng-class="{\'-inherited\': vm.group.inherited, \'umb-group-builder__group-handle -sortable\': vm.sorting && !vm.group.inherited}" tabindex="0" ng-focus="vm.whenFocus()"> <div class="umb-group-builder__group-title-wrapper" ng-if="vm.allowName" data-element="{{vm.valTabAlias}}"> <ng-form name="groupNameForm" data-element="group-name"> <div class="umb-group-builder__group-title control-group -no-margin" ng-class="{\'-inherited\': vm.group.inherited}"> <i class="umb-group-builder__group-title-icon icon-navigation" ng-if="vm.sorting && !vm.group.inherited"></i> <input data-element="group-name-field" class="umb-group-builder__group-title-input" type="text" localize="placeholder" placeholder="@placeholders_entername" name="groupName" title="{{vm.group.alias}}" ng-model="vm.group.name" ng-class="{\'-placeholder\': vm.group.name == \'\'}" ng-change="vm.updateName(vm.group)" ng-disabled="vm.group.inherited" umb-auto-focus ng-focus="vm.whenNameFocus()" required val-server-field="{{vm.valServerFieldName}}" data-lpignore="true"> <div class="umb-group-builder__group-title-val-message" ng-messages="groupNameForm.groupName.$error" show-validation-on-submit> <div class="umb-validation-label -arrow-left" ng-message="valServerField">{{groupNameForm.groupName.errorMsg}}</div> <div class="umb-validation-label -arrow-left" ng-message="required"><localize key="required"></localize></div> </div> </div> </ng-form> <div class="umb-group-builder__group-title-right"> <div class="umb-group-builder__group-inherited-label" ng-if="vm.group.inherited"> <i class="icon icon-merge"></i> <localize key="contentTypeEditor_inheritedFrom"></localize>: {{ vm.group.inheritedFromName }} <span ng-repeat="contentTypeName in vm.group.parentTabContentTypeNames"> <button type="button" class="btn-link btn-small p0" ng-click="vm.clickComposition(vm.group.parentTabContentTypes[$index])">{{ contentTypeName }}</button> <span ng-if="!$last">, </span> </span> </div> <ng-form name="groupSortOrderForm" class="umb-group-builder__group-sort-order"> <div ng-if="vm.sorting"> <input name="groupSortOrder" type="number" class="umb-property-editor-tiny" style="margin-bottom: 0;" ng-model="vm.group.sortOrder" ng-disabled="vm.group.inherited" ng-blur="vm.changeSortOrderValue()" required>  <div class="umb-validation-label -arrow-left" ng-if="groupSortOrderForm.groupSortOrder.$error.required && tab.showSortOrderMissing"><localize key="required"></localize></div> <div ng-messages="groupSortOrderForm.groupSortOrder.$error" show-validation-on-submit> <div class="umb-validation-label -arrow-left" ng-message="required"><localize key="required"></localize></div> </div> </div> </ng-form> </div> <div class="umb-group-builder__group-remove" ng-if="vm.allowRemove"> <i class="icon-trash" ng-click="vm.removeGroup()"></i> </div> </div> <div class="umb-group-builder__group-content"> <ng-transclude></ng-transclude> </div> </div> ',controllerAs:"vm",transclude:!0,bindings:{group:"<",allowName:"<",onUpdateName:"&",allowRemove:"<",onRemove:"&",sorting:"<",onNameFocus:"&",onFocus:"&",onChangeSortOrderValue:"&",valServerFieldName:"@",valTabAlias:"@",onClickComposition:"&?"},controller:function umbContentTypeGroupController(){var vm=this;vm.updateName=function updateName(group){vm.onUpdateName&&vm.onUpdateName({group:group})},vm.removeGroup=function removeGroup(){vm.onRemove&&vm.onRemove({group:vm.group})},vm.whenNameFocus=function whenNameFocus(){vm.onNameFocus&&vm.onNameFocus()},vm.whenFocus=function whenFocus(){vm.onFocus&&vm.onFocus()},vm.changeSortOrderValue=function changeSortOrderValue(){vm.onChangeSortOrderValue&&vm.onChangeSortOrderValue({group:vm.group})},vm.clickComposition=function clickComposition(documentTypeId){vm.onClickComposition&&vm.onClickComposition({documentTypeId:documentTypeId})}}};angular.module("umbraco.directives").component("umbContentTypeGroup",umbContentTypeGroupComponent)}(),function(){var umbContentTypeGroupsComponent={template:'<div class="umb-group-builder__groups" ng-transclude></div>',controllerAs:"vm",transclude:!0,controller:function umbContentTypeGroupsController(){}};angular.module("umbraco.directives").component("umbContentTypeGroups",umbContentTypeGroupsComponent)}(),function(){var umbContentTypePropertyComponent={template:'<div data-element="property-{{vm.property.alias}}" class="umb-group-builder__property" ng-class="{\'-active\': vm.dialogIsOpen, \'-active\': vm.property.propertyState==\'active\', \'-inherited\': vm.property.inherited, \'-locked\': vm.property.locked, \'umb-group-builder__property-handle -sortable\': vm.sortable && !vm.property.inherited, \'-sortable-locked\': vm.sortable && vm.property.inherited}">  <div class="umb-group-builder__property-meta" ng-class="{\'-full-width\': vm.sortable}" data-element="{{vm.valTabAlias}}"> <ng-form name="propertyTypeForm"> <div class="control-group -no-margin" ng-if="!vm.sortable"> <div class="umb-group-builder__property-meta-alias umb-locked-field__text cursor-not-allowed" style="padding-left: 1px" ng-if="vm.property.inherited || vm.property.locked">{{ vm.property.alias }}</div> <umb-locked-field ng-if="!vm.property.inherited && !vm.property.locked" locked="locked" ng-model="vm.property.alias" placeholder-text="\'Alias...\'" server-validation-field="{{ vm.valServerFieldAlias }}"> </umb-locked-field> <div class="umb-group-builder__property-meta-label"> <textarea localize="placeholder" placeholder="@placeholders_label" ng-model="vm.property.label" ng-disabled="vm.property.inherited || vm.property.locked" name="groupName" umb-auto-resize required val-server-field="{{ vm.valServerFieldLabel }}">\r\n                  </textarea> <div ng-messages="propertyTypeForm.groupName.$error" show-validation-on-submit> <div class="umb-validation-label" ng-message="valServerField">{{propertyTypeForm.groupName.errorMsg}}</div> <div class="umb-validation-label" ng-message="required"><localize key="contentTypeEditor_requiredLabel"></localize></div> </div> </div> <div class="umb-group-builder__property-meta-description"> <textarea localize="placeholder" placeholder="@placeholders_enterDescription" ng-model="vm.property.description" ng-disabled="vm.property.inherited || vm.property.locked" umb-auto-resize>\r\n                  </textarea> </div> </div> </ng-form> <div ng-if="vm.sortable" class="flex items-center"> <i class="icon icon-navigation" ng-if="!vm.property.inherited" style="margin-right: 10px;"></i> <span class="umb-group-builder__property-meta-label">{{ vm.property.label }}</span> <span class="umb-group-builder__property-meta-alias" style="margin-bottom: 0; margin-left: 5px; margin-top: 1px;">({{ vm.property.alias }})</span> <input name="propertySortOrder" type="number" class="umb-group-builder__group-sort-value umb-property-editor-tiny" ng-model="vm.property.sortOrder" ng-disabled="vm.property.inherited" ng-blur="vm.changeSortOrderValue()"> </div> </div> <div tabindex="-1" class="umb-group-builder__property-preview" ng-if="!vm.sortable" ng-class="{\'-not-clickable\': !vm.sortable && (vm.property.inherited || vm.property.locked)}"> <div class="umb-group-builder__property-tags"> <span class="umb-group-builder__property-tag -white"> <span ng-if="vm.property.dataTypeName !== undefined">{{vm.property.dataTypeName}}</span> <span ng-if="vm.property.dataTypeName == undefined"><localize key="general_preview"></localize></span> </span> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.validation.mandatory"> <i class="umb-group-builder__property-tag-icon">*</i> <localize key="general_mandatory"></localize> </div> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.showOnMemberProfile"> <i class="icon-eye umb-group-builder__property-tag-icon"></i> <localize key="contentTypeEditor_showOnMemberProfile"></localize> </div> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.memberCanEdit"> <i class="icon-edit umb-group-builder__property-tag-icon"></i> <localize key="contentTypeEditor_memberCanEdit"></localize> </div> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.isSensitiveData"> <i class="icon-lock umb-group-builder__property-tag-icon"></i> <localize key="contentTypeEditor_isSensitiveData"></localize> </div> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.allowCultureVariant"> <i class="icon-shuffle umb-group-builder__property-tag-icon"></i> <localize key="contentTypeEditor_cultureVariantLabel"></localize> </div> <div class="umb-group-builder__property-tag -white" ng-if="vm.property.allowSegmentVariant"> <i class="icon-shuffle umb-group-builder__property-tag-icon"></i> <localize key="contentTypeEditor_segmentVariantLabel"></localize> </div> </div> <div class="umb-group-builder__property-tags -right"> <div class="umb-group-builder__property-tag" ng-if="vm.property.inherited"> <umb-icon icon="icon-merge" class="icon-merge"></umb-icon> <span style="margin-right: 3px"><localize key="contentTypeEditor_inheritedFrom"></localize></span> {{vm.property.contentTypeName}} </div> <div class="umb-group-builder__property-tag" ng-if="vm.property.locked"> <umb-icon icon="icon-lock" class="icon-lock"></umb-icon> <localize key="general_locked"></localize> </div> </div> <ng-form inert class="umb-group-builder__property-preview-form" name="propertyEditorPreviewForm" umb-disable-form-validation ng-click="vm.edit()" tabindex="-1"> <umb-property-editor ng-if="vm.property.view !== undefined" model="vm.property" preview="true"> </umb-property-editor> </ng-form> <button aria-label="Open settings" class="umb-group-builder__open-settings" ng-if="!vm.property.inherited && !vm.property.locked" ng-click="vm.edit()"></button> </div>  <div class="umb-group-builder__property-actions" ng-if="!vm.sortable"> <div ng-if="!vm.property.inherited">  <div class="umb-group-builder__property-action"> <button aria-label="Open settings" class="btn-icon" ng-click="vm.edit()" localize="title" title="@general_edit"> <umb-icon icon="icon-settings" class="icon-settings"></umb-icon> </button> </div>  <div ng-if="!vm.property.locked" class="umb-group-builder__property-action"> <button aria-label="Delete property" class="btn-icon" ng-click="vm.remove()"> <umb-icon icon="icon-trash" class="icon-trash"></umb-icon> </button> </div> </div> </div> </div>',bindings:{property:"<",sortable:"<",onEdit:"&",onRemove:"&",onChangeSortOrderValue:"&",valServerFieldAlias:"@",valServerFieldLabel:"@",valTabAlias:"@"},controllerAs:"vm",controller:function umbContentTypePropertyController(){var vm=this;vm.edit=function edit(){vm.onEdit&&vm.onEdit()},vm.remove=function remove(){vm.onRemove&&vm.onRemove({property:vm.property})},vm.changeSortOrderValue=function changeSortOrderValue(){vm.onChangeSortOrderValue&&vm.onChangeSortOrderValue({property:vm.property})}}};angular.module("umbraco.directives").component("umbContentTypeProperty",umbContentTypePropertyComponent)}(),function(){var umbContentTypeTabComponent={template:'<div ng-click="vm.click()" class="umb-group-builder__tab" ng-class="{ \'is-active\': vm.isOpen, \'is-inherited\': vm.tab.inherited, \'is-deletable\': vm.allowRemove, \'umb-group-builder__tab-handle -sortable\': vm.sorting && !vm.tab.inherited, \'has-error\': vm.tab.hasError }" val-tab="vm.tab" ng-mouseenter="vm.mouseenter()" ng-mouseleave="vm.mouseleave()"> <div> <div class="umb-group-builder__tab-inherited-label" ng-if="vm.compositionLabelIsVisible"> <localize key="contentTypeEditor_inheritedFrom"></localize>: {{ vm.tab.inheritedFromName }} <span ng-repeat="contentTypeName in vm.tab.parentTabContentTypeNames"> <button type="button" class="btn-link btn-small p0" ng-click="vm.clickComposition(vm.tab.parentTabContentTypes[$index])">{{ contentTypeName }}</button> <span ng-if="!$last">, </span> </span> </div> <div class="umb-group-builder__tab-title-wrapper"> <i class="umb-group-builder__tab-title-icon icon-navigation" ng-if="vm.sorting && !vm.tab.inherited"></i> <i class="umb-group-builder__tab-title-icon icon-merge" ng-if="vm.tab.inherited"></i> <ng-form name="tabNameForm" data-element="tab-name"> <div class="umb-group-builder__tab-name" ng-if="vm.tab.inherited" title="{{vm.tab.alias}}">{{ vm.tab.name }}</div> <input ng-if="!vm.tab.inherited" class="umb-group-builder__group-title-input" data-element="tab-name-field" type="text" localize="placeholder" placeholder="@placeholders_entername" name="tabName" title="{{vm.tab.alias}}" ng-model="vm.tab.name" ng-class="{\'-placeholder\': vm.tab.name == \'\'}" ng-disabled="!vm.isOpen || vm.allowChangeName === false" ng-change="vm.changeName()" umb-auto-focus umb-auto-resize val-server-field="{{ vm.valServerFieldName }}" data-lpignore="true" required> <div class="umb-group-builder__tab-val-message" ng-messages="tabNameForm.tabName.$error" show-validation-on-submit> <div class="umb-validation-label" ng-message="valServerField">{{tabNameForm.tabName.errorMsg}}</div> <div class="umb-validation-label" ng-message="required"><localize key="required"></localize></div> </div> </ng-form> <div ng-show="vm.tab.hasError && !vm.isOpen" class="badge">!</div> <ng-form name="tabSortOrderForm"> <div class="umb-group-builder__tab-sort-order" ng-if="vm.sorting"> <input name="tabSortOrder" type="number" class="umb-property-editor-tiny" style="margin-bottom: 0;" ng-model="vm.tab.sortOrder" ng-disabled="vm.tab.inherited" ng-blur="vm.changeSortOrderValue()" required>  <div class="umb-validation-label -arrow-left" ng-if="tabSortOrderForm.tabSortOrder.$error.required && vm.tab.showSortOrderMissing"><localize key="required"></localize></div> <div ng-messages="tabSortOrderForm.tabSortOrder.$error" show-validation-on-submit> <div class="umb-validation-label -arrow-left" ng-message="required"><localize key="required"></localize></div> </div> </div> </ng-form> </div> </div> <div class="umb-group-builder__tab-remove" ng-if="vm.allowRemove"> <button type="button" class="btn-reset" ng-click="vm.removeTab()"> <i class="icon-trash"></i> </button> </div> </div> ',controllerAs:"vm",transclude:!0,bindings:{tab:"<",onClick:"&?",onClickComposition:"&?",isOpen:"<?",allowRemove:"<?",onRemove:"&?",sorting:"<?",onFocusName:"&?",onFocus:"&?",onChangeSortOrderValue:"&?",allowChangeName:"<?",onChangeName:"&?",valServerFieldName:"@"},controller:function umbContentTypeTabController($timeout){var vm=this;vm.compositionLabelIsVisible=!1,vm.click=function click(){vm.onClick&&vm.onClick({tab:vm.tab})},vm.removeTab=function removeTab(){vm.onRemove&&vm.onRemove({tab:vm.tab})},vm.whenFocusName=function whenFocusName(){vm.onFocusName&&vm.onFocusName()},vm.whenFocus=function whenFocus(){vm.onFocus&&vm.onFocus()},vm.changeSortOrderValue=function changeSortOrderValue(){vm.onChangeSortOrderValue&&vm.onChangeSortOrderValue({tab:vm.tab})},vm.changeName=function changeName(){vm.onChangeName&&vm.onChangeName({key:vm.tab.key,name:vm.tab.name})},vm.clickComposition=function clickComposition(documentTypeId){vm.onClickComposition&&vm.onClickComposition({documentTypeId:documentTypeId})},vm.mouseenter=function mouseenter(){vm.tab.inherited&&(vm.compositionLabelIsVisible=!0,$timeout.cancel(timeout))},vm.mouseleave=function mouseleave(){vm.tab.inherited&&(timeout=$timeout(function(){vm.compositionLabelIsVisible=!1},300))};var timeout=null}};angular.module("umbraco.directives").component("umbContentTypeTab",umbContentTypeTabComponent)}(),function(){angular.module("umbraco.directives").directive("umbEditorSubHeader",function EditorSubHeaderDirective(){return{transclude:!0,restrict:"E",replace:!0,scope:{appearance:"@?"},template:'<div class="umb-editor-sub-header umb-editor-sub-header--{{appearance}}" umb-sticky-bar ng-transclude> </div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorSubHeaderContentLeft",function EditorSubHeaderContentLeftDirective(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-editor-sub-header__content-left" ng-transclude></div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorSubHeaderContentRight",function EditorSubHeaderContentRightDirective(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-editor-sub-header__content-right" ng-transclude></div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorSubHeaderSection",function EditorSubHeaderSectionDirective(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-editor-sub-header__section" ng-transclude></div> '}})}(),function(){angular.module("umbraco.directives").directive("umbBreadcrumbs",function BreadcrumbsDirective($location,navigationService){return{restrict:"E",replace:!0,template:'<ul class="umb-breadcrumbs"> <li class="umb-breadcrumbs__ancestor" ng-repeat="ancestor in ancestors">  <a ng-if="(!$last || forNewEntity) && !allowOnOpen" ng-href="#{{::pathTo(ancestor)}}" ng-click="openPath(ancestor, $event)" class="umb-breadcrumbs__ancestor-link" title="{{ancestor.name}}">{{ancestor.name}}</a>  <a ng-if="(!$last || forNewEntity) && allowOnOpen" href="#" ng-click="open(ancestor)" class="umb-breadcrumbs__ancestor-link" title="{{ancestor.name}}" prevent-default>{{ancestor.name}}</a> <span ng-if="(!$last || forNewEntity)" class="umb-breadcrumbs__separator">&#47;</span> <span class="umb-breadcrumbs__ancestor-text" ng-if="$last && !forNewEntity" title="{{ancestor.name}}">{{ancestor.name}}</span> </li> </ul> ',scope:{ancestors:"=",forNewEntity:"=",entityType:"@",onOpen:"&"},link:function link(scope,el,attr,ctrl){scope.allowOnOpen=!1,scope.open=function(ancestor){scope.onOpen&&scope.allowOnOpen&&scope.onOpen({ancestor:ancestor})},scope.openPath=function(ancestor,event){if(!(event.ctrlKey||event.shiftKey||event.metaKey||event.button&&1===event.button)){event.stopPropagation(),event.preventDefault();var path=scope.pathTo(ancestor);$location.path(path),navigationService.clearSearch(["cculture","csegment"])}},scope.pathTo=function(ancestor){return"/"+scope.entityType+"/"+scope.entityType+"/edit/"+ancestor.id},function onInit(){"onOpen"in attr&&(scope.allowOnOpen=!0)}()}}})}(),function(){angular.module("umbraco.directives").directive("umbEditor",function EditorDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-editor" ng-style="model.style" ng-class="{\'umb-editor--small\': model.size === \'small\', \'umb-editor--animating\': model.animating}"> <div ng-if="!model.view && !model.animating" ng-transclude></div> <div ng-if="model.view && !model.animating" ng-include="model.view"></div> <div ng-if="model.showOverlay" class="umb-editor__overlay"></div> </div>',scope:{model:"="}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorContainer",function EditorContainerDirective(overlayHelper){return{transclude:!0,restrict:"E",replace:!0,template:' <div data-element="editor-container" class="umb-editor-container umb-panel-body umb-scrollable row-fluid" ng-class="{\'-stop-scrolling\': numberOfOverlays > 0}">  <div> <umb-overlay-backdrop></umb-overlay-backdrop> </div> <div class="umb-pane"> <div ng-transclude></div> </div> </div> ',link:function link(scope,el,attr,ctrl){scope.numberOfOverlays=0,scope.$watch(function(){return overlayHelper.getNumberOfOverlays()},function(newValue){scope.numberOfOverlays=newValue})}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorContentHeader",function EditorContentHeader(serverValidationManager,localizationService,editorState,contentEditingHelper,contentTypeHelper){return{transclude:!0,restrict:"E",replace:!0,template:'<div data-element="editor-header" class="umb-editor-header" ng-class="{\'-split-view-active\': splitViewOpen === true}"> <div class="flex items-center" style="height: 100%;"> <div ng-if="showBackButton === true && splitViewOpen !== true" style="margin-right: 15px;"> <button type="button" class="umb-editor-header__back" ng-click="goBack()"> <umb-icon icon="fa fa-arrow-left"></umb-icon> <span class="sr-only"><localize key="visuallyHiddenTexts_goBack">Go back</localize></span> </button> </div> <div class="flex items-center" style="flex: 1;"> <div id="nameField" class="umb-editor-header__name-and-description" style="flex: 1 1 auto;"> <div> <p tabindex="0" class="sr-only">{{a11yMessage}}</p> </div> <div class="umb-editor-header__name-wrapper"> <label for="headerName" class="sr-only">{{a11yName}}</label> <ng-form name="headerNameForm"> <input data-element="editor-name-field" type="text" class="umb-editor-header__name-input" localize="placeholder" placeholder="@placeholders_entername" name="headerName" id="headerName" ng-model="name" ng-class="{\'name-is-empty\': $parent.name===null || $parent.name===\'\'}" ng-disabled="nameDisabled" umb-auto-focus focus-on-filled="true" val-server-field="{{serverValidationNameField}}" required aria-required="true" aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}" autocomplete="off" maxlength="255"> </ng-form> <button type="button" ng-if="vm.hasVariants === true && hideChangeVariant !== true" class="umb-variant-switcher__toggle umb-outline" ng-click="toggleDropdown()" ng-class="{\'--error\': vm.errorsOnOtherVariants}" aria-haspopup="true" aria-expanded="{{vm.dropdownOpen}}"> <span ng-bind="editor.content.displayName"></span> <umb-icon icon="{{vm.dropdownOpen ? \'icon-navigation-up\' : \'icon-navigation-down\'}}" class="umb-variant-switcher__expand"></umb-icon> </button> <span ng-if="vm.hasVariants === true && hideChangeVariant" class="umb-variant-switcher__toggle"> <span ng-bind="editor.content.displayName"></span> </span> <umb-dropdown ng-if="vm.dropdownOpen" class="umb-variant-switcher" ng-class="{\'--has-sub-variants\': vm.hasSubVariants === true}" on-close="vm.dropdownOpen = false" umb-keyboard-list> <umb-dropdown-item ng-repeat-start="entry in vm.variantMenu track by entry.key" class="umb-variant-switcher__item" ng-class="{\'--current\': entry.variant === editor.content, \'--active\': entry.variant.active && vm.dropdownOpen, \'--error\': entry.variant.active !== true && entry.variant.hasError, \'--state-notCreated\':entry.variant.state===\'NotCreated\' && entry.variant.name == null, \'--state-draft\':entry.variant.state===\'Draft\' || (entry.variant.state===\'NotCreated\' && entry.variant.name != null)}"> <button type="button" ng-if="entry.subVariants && entry.subVariants.length > 0" class="umb-variant-switcher__item-expand-button umb-outline" ng-click="entry.open = !entry.open"> <umb-icon icon="{{entry.open ? \'icon-navigation-down\' : \'icon-navigation-right\'}}" class="icon"></umb-icon> </button> <button type="button" class="umb-variant-switcher__name-wrapper umb-outline" ng-click="selectVariant($event, entry.variant)"> <span class="umb-variant-switcher__name-content"> <span class="umb-variant-switcher__name" ng-bind="entry.variant.displayName"></span> <span class="umb-variant-switcher__state"> <umb-variant-state variant="entry.variant"></umb-variant-state> <span ng-if="entry.variant.language.isMandatory"> - <localize key="general_mandatory"></localize></span> <span ng-if="entry.variant.language.isDefault"> - <localize key="general_default"></localize></span> </span> </span> </button> <div ng-if="splitViewOpen !== true && !entry.variant.active" class="umb-variant-switcher__split-view umb-outline" ng-click="openInSplitView($event, entry.variant)">Open in split view</div> </umb-dropdown-item> <div ng-repeat-end ng-if="entry.open === true && entry.subVariants && entry.subVariants.length > 0" class="umb-variant-switcher__sub-variants umb-outline"> <umb-dropdown-item ng-repeat="subVariant in entry.subVariants track by $index" class="umb-variant-switcher__item" ng-class="{\'--current\': subVariant === editor.content, \'--active\': subVariant.active && vm.dropdownOpen, \'--error\': subVariant.active !== true && subVariant.hasError, \'--state-notCreated\':subVariant.state===\'NotCreated\', \'--state-draft\':subVariant.state===\'Draft\'}"> <button type="button" class="umb-variant-switcher__name-wrapper umb-outline" ng-click="selectVariant($event, subVariant)"> <span class="umb-variant-switcher__name-content"> <span class="umb-variant-switcher__name" ng-bind="subVariant.segment"></span> <umb-variant-state variant="subVariant" class="umb-variant-switcher__state"></umb-variant-state> </span> </button> <div ng-if="splitViewOpen !== true && !subVariant.active" class="umb-variant-switcher__split-view umb-outline" ng-click="openInSplitView($event, subVariant)">Open in split view</div> </umb-dropdown-item> </div> </umb-dropdown> </div> </div> </div> <div ng-if="editor.variantApps && splitViewOpen !== true"> <umb-editor-navigation data-element="editor-sub-views" navigation="editor.variantApps" on-select="selectNavigationItem(item)" on-anchor-select="selectAnchorItem(item, anchor)" limit="vm.navigationItemLimit"> </umb-editor-navigation> </div> <div ng-if="menu.currentNode && splitViewOpen !== true && hideActionsMenu !== true"> <umb-editor-menu data-element="editor-actions" current-node="menu.currentNode" current-section="{{menu.currentSection}}" is-disabled="disableActionsMenu"> </umb-editor-menu> </div> <div ng-if="splitViewOpen"> <button type="button" class="btn-reset umb-editor-header__close-split-view" ng-click="closeSplitView()"> <umb-icon icon="icon-delete" class="icon-delete"></umb-icon> <span class="sr-only"><localize key="general_closepane">Close Pane</localize></span> </button> </div> </div> </div> ',scope:{name:"=",nameDisabled:"<?",menu:"=",hideActionsMenu:"<?",disableActionsMenu:"<?",content:"=",editor:"=",hideChangeVariant:"<?",onSelectNavigationItem:"&?",onSelectAnchorItem:"&?",showBackButton:"<?",onBack:"&?",splitViewOpen:"=?",onOpenInSplitView:"&?",onCloseSplitView:"&?",onSelectVariant:"&?",serverValidationNameField:"@?",serverValidationAliasField:"@?"},link:function link(scope){var unsubscribe=[];function updateVaraintErrors(){scope.content.variants.forEach(function(variant){variant.hasError=scope.variantHasError(variant)}),function checkErrorsOnOtherVariants(){var check=!1;scope.content.variants.forEach(function(variant){!0!==variant.active&&variant.hasError&&(check=!0)}),scope.vm.errorsOnOtherVariants=check}()}function onVariantValidation(valid,errors,allErrors,culture,segment){if(-1!==errors.findIndex(function(error){return null!==error.propertyAlias})){"invariant"===culture&&scope.vm.defaultVariant&&(culture=scope.vm.defaultVariant.language.culture);var index=scope.vm.variantsWithError.findIndex(function(item){return item.culture===culture&&item.segment===segment});!0===valid?-1!==index&&scope.vm.variantsWithError.splice(index,1):-1===index&&scope.vm.variantsWithError.push({culture:culture,segment:segment}),scope.$evalAsync(updateVaraintErrors)}}function sortVariantsMenu(a,b){return contentEditingHelper.sortVariants(a.variant,b.variant)}scope.serverValidationNameField||(scope.serverValidationNameField="Name"),scope.serverValidationAliasField||(scope.serverValidationAliasField="Alias"),scope.isNew="NotCreated"==scope.editor.content.state,localizationService.localizeMany([scope.isNew?"placeholders_a11yCreateItem":"placeholders_a11yEdit","placeholders_a11yName",scope.isNew?"general_new":"general_edit"]).then(function(data){scope.a11yMessage=data[0],scope.a11yName=data[1];var title=data[2]+": ";if(scope.isNew){var name=editorState.current.contentTypeName;scope.a11yMessage+=" "+name,scope.a11yName=name+" "+scope.a11yName,title+=name}else scope.a11yMessage+=" "+scope.editor.content.name,title+=scope.editor.content.name;scope.$emit("$changeTitle",title)}),scope.vm={},scope.vm.hasVariants=!1,scope.vm.hasSubVariants=!1,scope.vm.hasCulture=!1,scope.vm.hasSegments=!1,scope.vm.dropdownOpen=!1,scope.vm.variantsWithError=[],scope.vm.defaultVariant=null,scope.vm.errorsOnOtherVariants=!1,scope.goBack=function(){scope.onBack&&scope.onBack()},scope.selectVariant=function(event,variant){scope.onSelectVariant&&(scope.vm.dropdownOpen=!1,scope.onSelectVariant({variant:variant}))},scope.selectNavigationItem=function(item){scope.onSelectNavigationItem&&scope.onSelectNavigationItem({item:item})},scope.selectAnchorItem=function(item,anchor){scope.onSelectAnchorItem&&scope.onSelectAnchorItem({item:item,anchor:anchor})},scope.closeSplitView=function(){scope.onCloseSplitView&&scope.onCloseSplitView()},scope.openInSplitView=function(event,variant){scope.onOpenInSplitView&&(scope.vm.dropdownOpen=!1,scope.onOpenInSplitView({variant:variant}))},scope.variantHasError=function(variant){return void 0!==scope.vm.variantsWithError.find(function(item){return(!variant.language||item.culture===variant.language.culture)&&item.segment===variant.segment})},scope.toggleDropdown=function(){scope.vm.dropdownOpen=!scope.vm.dropdownOpen,scope.vm.dropdownOpen&&scope.vm.variantMenu.sort(sortVariantsMenu)},unsubscribe.push(scope.$watch("splitViewOpen",function(newVal){scope.vm.navigationItemLimit=!0===newVal?0:void 0})),function onInit(){scope.content.variants.forEach(function(variant){null!==variant.language&&variant.language.isDefault&&(scope.vm.defaultVariant=variant),null!==variant.language&&(scope.vm.hasCulture=!0),null!==variant.segment&&(scope.vm.hasSegments=!0)}),scope.vm.hasVariants=scope.content.variants.length>1&&(scope.vm.hasCulture||scope.vm.hasSegments),scope.vm.hasSubVariants=scope.content.variants.length>1&&scope.vm.hasCulture&&scope.vm.hasSegments,updateVaraintErrors(),scope.vm.variantMenu=[],scope.vm.hasCulture?scope.content.variants.forEach(function(v){if(null!==v.language&&null===v.segment){var subVariants=scope.content.variants.filter(function(subVariant){return subVariant.language.culture===v.language.culture&&null!==subVariant.segment}).sort(contentEditingHelper.sortVariants),variantMenuEntry={key:String.CreateGuid(),open:v.language&&v.language.culture===scope.editor.culture,variant:v,subVariants:subVariants};scope.vm.variantMenu.push(variantMenuEntry)}}):scope.content.variants.forEach(function(v){scope.vm.variantMenu.push({key:String.CreateGuid(),variant:v})}),scope.editor.variantApps.forEach(function(app){if("umbContent"===app.alias){var hasTabs=scope.editor.content.tabs&&scope.editor.content.tabs.filter(function(group){return group.type===contentTypeHelper.TYPE_TAB}).length>0;app.anchors=hasTabs?[]:scope.editor.content.tabs}}),scope.content.variants.forEach(function(variant){variant.language&&scope.vm.defaultVariant&&variant.language.culture===scope.vm.defaultVariant.language.culture&&null===variant.segment&&unsubscribe.push(serverValidationManager.subscribe(null,"invariant",null,onVariantValidation,null)),unsubscribe.push(serverValidationManager.subscribe(null,null!==variant.language?variant.language.culture:null,null,onVariantValidation,variant.segment))}),scope.vm.variantMenu.sort(sortVariantsMenu)}(),scope.$on("$destroy",function(){for(var u in unsubscribe)unsubscribe[u]()})}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorFooter",function EditorFooterDirective(){return{transclude:!0,restrict:"E",replace:!0,template:' <div data-element="editor-footer" class="umb-editor-footer"> <div class="umb-editor-footer-content" ng-transclude></div> </div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorFooterContentLeft",function EditorFooterContentLeftDirective(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-editor-footer-content__left-side" ng-transclude></div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorFooterContentRight",function EditorFooterContentRightDirective(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-editor-footer-content__right-side" ng-transclude></div> '}})}(),function(){angular.module("umbraco.directives").directive("umbEditorHeader",function EditorHeaderDirective(editorService,localizationService,editorState,$rootScope){return{transclude:!0,restrict:"E",replace:!0,template:' <div data-element="editor-header" class="umb-editor-header" ng-class="{\'-split-view-active\': splitViewOpen === true}"> <umb-loader ng-show="loading"></umb-loader> <div class="flex items-center" style="height: 100%;" ng-hide="loading"> <div ng-if="showBackButton === true && splitViewOpen !== true" style="margin-right: 15px;"> <button type="button" class="umb-editor-header__back" ng-click="goBack()"> <umb-icon icon="fa fa-arrow-left"></umb-icon> <span class="sr-only"><localize key="visuallyHiddenTexts_goBack">Go back</localize></span> </button> </div> <div class="flex items-center" style="flex: 1;"> <ng-form data-element="editor-icon" name="iconForm"> <button type="button" class="umb-panel-header-icon" ng-if="!hideIcon" ng-click="openIconPicker()" ng-class="{\'-placeholder\': $parent.icon === \'\' || $parent.icon === null}" title="{{$parent.icon}}"> <umb-icon icon="{{$parent.icon}}" class="icon" ng-if="$parent.icon !== \'\' && $parent.icon !== null"></umb-icon> <span class="umb-panel-header-icon-text" ng-if="$parent.icon === \'\' || $parent.icon === null"> <localize key="settings_addIcon">Add icon</localize> </span> </button> </ng-form> <div id="nameField" class="umb-editor-header__name-and-description" style="flex: 1 1 auto;"> <div> <p tabindex="0" class="sr-only" ng-show="accessibility.a11yMessageVisible"> {{accessibility.a11yMessage}} </p> </div> <div class="umb-editor-header__name-wrapper" ng-show="!nameLocked || !hideAlias"> <label for="headerName" class="sr-only" ng-show="accessibility.a11yNameVisible">{{accessibility.a11yName}}</label> <ng-form name="headerNameForm"> <input data-element="editor-name-field" no-password-manager type="text" id="headerName" class="umb-editor-header__name-input" localize="placeholder" placeholder="@placeholders_entername" name="headerName" ng-show="!nameLocked" ng-model="name" ng-class="{\'name-is-empty\': $parent.name===null || $parent.name===\'\'}" umb-auto-focus focus-on-filled="true" val-server-field="Name" ng-required="nameRequired != null ? nameRequired : true" aria-required="{{nameRequired != null ? nameRequired : true}}" aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}" autocomplete="off" maxlength="255"> </ng-form> <umb-generate-alias data-element="editor-alias" class="umb-panel-header-alias" ng-if="!hideAlias" alias="$parent.alias" alias-from="$parent.name" enable-lock="aliasLocked !== true" validation-position="\'right\'" server-validation-field="Alias"> </umb-generate-alias> </div> <h1 class="umb-panel-header-name" id="editor-headline-{{$id}}" ng-if="nameLocked" title="{{key}}">{{ name }}</h1> <input data-element="editor-description" no-password-manager type="text" class="umb-panel-header-description" localize="placeholder" placeholder="@placeholders_enterDescription" ng-if="!hideDescription && !descriptionLocked" ng-model="$parent.description"> <p class="umb-panel-header-locked-description" id="editor-description-{{$id}}" ng-if="descriptionLocked">{{ description }}</p> </div> </div> <div ng-if="navigation && splitViewOpen !== true"> <umb-editor-navigation data-element="editor-sub-views" navigation="navigation" on-select="selectNavigationItem(item)"> </umb-editor-navigation> </div> <div ng-if="menu.currentNode && splitViewOpen !== true && hideActionsMenu !== true"> <umb-editor-menu data-element="editor-actions" current-node="menu.currentNode" current-section="{{menu.currentSection}}"> </umb-editor-menu> </div> </div> </div> ',scope:{name:"=",nameLocked:"=",nameRequired:"=?",menu:"=",hideActionsMenu:"<?",icon:"=",hideIcon:"@",alias:"=",aliasLocked:"<",hideAlias:"=",description:"=",hideDescription:"@",descriptionLocked:"@",navigation:"=",onSelectNavigationItem:"&?",key:"=",onBack:"&?",showBackButton:"<?",editorfor:"=",setpagetitle:"="},link:function link(scope,$injector){function setAccessibilityHeaderDirective(isNew,editorFor,nameLocked,entityName,contentTypeName,setTitle){var localizeVars=[isNew?"visuallyHiddenTexts_createItem":"visuallyHiddenTexts_edit","visuallyHiddenTexts_name",isNew?"general_new":"general_edit"];editorFor&&localizeVars.push(editorFor),localizationService.localizeMany(localizeVars).then(function(data){if(nameLocked)scope.accessibility.a11yName=entityName,setTitle&&SetPageTitle(entityName);else{scope.accessibility.a11yMessage=data[0],scope.accessibility.a11yName=data[1];var title=data[2]+":";if(isNew){var name="";contentTypeName?name=editorState.current.contentTypeName:editorFor&&(name=data[3]),""!==name&&(scope.accessibility.a11yMessage+=" "+name,scope.accessibility.a11yName=name+" "+scope.accessibility.a11yName,title+=" "+name)}else scope.accessibility.a11yMessage+=" "+entityName,title+=" "+entityName;setTitle&&title!==data[2]+":"&&SetPageTitle(title)}scope.accessibility.a11yMessageVisible=!isNullOrWhitespace(scope.accessibility.a11yMessage),scope.accessibility.a11yNameVisible=!isNullOrWhitespace(scope.accessibility.a11yName)})}function isNullOrWhitespace(str){return null==str||""===str.trim()}function SetPageTitle(title){scope.$emit("$changeTitle",title)}scope.vm={},scope.vm.dropdownOpen=!1,scope.vm.currentVariant="",scope.loading=!0,scope.accessibility={},scope.accessibility.a11yMessage="",scope.accessibility.a11yName="",scope.accessibility.a11yMessageVisible=!1,scope.accessibility.a11yNameVisible=!1,editorState.current?(function setAccessibilityForEditorState(){var isNew=0===editorState.current.id||"0"===editorState.current.id||-1===editorState.current.id||0===editorState.current.id||"-1"===editorState.current.id,contentTypeName="";editorState.current.contentTypeName&&(contentTypeName=editorState.current.contentTypeName);var setTitle=!1;void 0!==scope.setpagetitle&&(setTitle=scope.setpagetitle),setAccessibilityHeaderDirective(isNew,scope.editorfor,scope.nameLocked,scope.name,contentTypeName,setTitle)}(),scope.loading=!1):scope.name?(function setAccessibilityForName(){var setTitle=!1;void 0!==scope.setpagetitle&&(setTitle=scope.setpagetitle),setTitle&&setAccessibilityHeaderDirective(!1,scope.editorfor,scope.nameLocked,scope.name,"",!0)}(),scope.loading=!1):scope.loading=!1,scope.goBack=function(){scope.onBack&&scope.onBack()},scope.selectNavigationItem=function(item){scope.onSelectNavigationItem&&scope.onSelectNavigationItem({item:item})},scope.openIconPicker=function(){var iconPicker={icon:scope.icon.split(" ")[0],color:scope.icon.split(" ")[1],submit:function submit(model){model.icon&&(model.color?scope.icon=model.icon+" "+model.color:scope.icon=model.icon,scope.iconForm.$setDirty()),editorService.close()},close:function close(){editorService.close()}};editorService.iconPicker(iconPicker)};var unbindEventHandler=$rootScope.$on("$setAccessibleHeader",function(event,isNew,editorFor,nameLocked,name,contentTypeName,setTitle){setAccessibilityHeaderDirective(isNew,editorFor,nameLocked,name,contentTypeName,setTitle)});scope.$on("$destroy",function(){unbindEventHandler()})}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorMenu",function EditorMenuDirective($injector,treeService,navigationService,umbModelMapper,appState){return{restrict:"E",replace:!0,template:'<div class="pull-right" style="position: relative;"> <umb-button type="button" button-style="white" action="dropdown.isOpen = !dropdown.isOpen" label-key="general_actions" show-caret="true" has-popup="true" is-expanded="dropdown.isOpen" disabled="!actions || !actions.length || isDisabled"> </umb-button> <umb-dropdown ng-if="dropdown.isOpen" class="umb-actions" on-close="dropdown.isOpen = false" deep-blur="dropdown.isOpen = false"> <umb-dropdown-item class="umb-action" ng-class="{\'sep\':action.separatorm, \'-opens-dialog\': action.opensDialog}" ng-repeat="action in actions"> <button type="button" ng-click="executeMenuItem(action)"> <umb-icon icon="icon-{{action.cssclass}}" class="icon"></umb-icon>  <span class="menu-label" aria-hidden="true">{{action.name}}</span>  <span class="sr-only" ng-if="action.textDescription"> <localize key="visuallyHiddenTexts_{{action.alias}}Description" tokens="[currentNode.name]"></localize> </span>  <span class="sr-only" ng-if="!action.textDescription">{{action.name}} {{currentNode.name}}</span> </button> </umb-dropdown-item> </umb-dropdown> </div> ',link:function link(scope,el,attr,ctrl){scope.dropdown={isOpen:!1},scope.executeMenuItem=function(action){appState.setMenuState("currentNode",scope.currentNode),navigationService.executeMenuAction(action,scope.currentNode,scope.currentSection),scope.dropdown.isOpen=!1},function onInit(){!function getOptions(){scope.currentNode&&(scope.actions||treeService.getMenu({treeNode:scope.currentNode}).then(function(data){scope.actions=data.menuItems}))}()}()},scope:{currentNode:"=",currentSection:"@",isDisabled:"<?"}}})}(),function(){angular.module("umbraco.directives.html").directive("umbEditorNavigation",function EditorNavigationDirective($window,$timeout,eventsService,windowResizeListener){return{restrict:"E",replace:!0,template:'<ul class="umb-sub-views-nav" ng-show="showNavigation"> <li ng-repeat="navItem in navigation | limitTo: itemsLimit"> <div ng-show="navItem.alias !== \'more\'" ng-class="navItem.errorClass"> <umb-editor-navigation-item item="navItem" on-open="openNavigationItem(item)" on-open-anchor="openAnchorItem(item, anchor)" hotkey="$index + 1"> </umb-editor-navigation-item> </div> </li> <li ng-show="showMoreButton"> <div class="umb-sub-views-nav-item umb-sub-views-nav-item-more"> <umb-button-ellipsis element="sub-view-{{moreButton.alias}}" action="toggleDropdown()" color="{{ moreButton.hasError ? \'#d42054\' : \'#1b264f\' }}" text="{{moreButton.name}}" show-text="true" mode="tab" css-class="umb-sub-views-nav-item__action umb-outline umb-outline--thin {{moreButton.active ? \'is-active\' : \'\'}} {{ moreButton.hasError ? \'-has-error\' : \'\' }} {{moreButton.activeHasError ? \'-active-has-error\' : \'\'}}"> <div class="badge -type-alert --error-badge">!</div> </umb-button-ellipsis> </div> </li> <li style="position: relative;"> <umb-dropdown ng-show="showDropdown" on-close="hideDropdown()" class="umb-sub-views-nav-item-more__dropdown"> <umb-dropdown-item ng-repeat="navItem in navigation | limitTo: overflowingItems"> <umb-editor-navigation-item item="navItem" on-open="openNavigationItem(item)" on-open-anchor="openAnchorItem(item, anchor)" index="{{$index}}"> </umb-editor-navigation-item> </umb-dropdown-item> </umb-dropdown> </li> </ul>',scope:{navigation:"=",onSelect:"&",onAnchorSelect:"&",limit:"<"},link:function link(scope){var unsubscribe=[];function calculateVisibleItems(windowWidth){windowWidth&&(void 0===scope.limit&&(scope.itemsLimit=0,windowWidth>1500?scope.itemsLimit=6:windowWidth>700&&(scope.itemsLimit=4)),scope.navigation.length>scope.itemsLimit?(scope.showMoreButton=!0,scope.overflowingItems=scope.itemsLimit-scope.navigation.length):(scope.showMoreButton=!1,scope.overflowingItems=0),scope.moreButton.name=0===scope.itemsLimit?"Menu":"More",setMoreButtonActiveState(),setMoreButtonErrorState())}function setMoreButtonActiveState(){scope.moreButton.active=scope.navigation.findIndex(function(item){return item.active})+1>scope.itemsLimit}function setMoreButtonErrorState(){if(0!==scope.overflowingItems){var overflow=scope.navigation.slice(scope.itemsLimit,scope.navigation.length),active=scope.navigation.find(function(item){return item.active});scope.moreButton.hasError=overflow.filter(function(item){return item.hasError}).length>0,scope.moreButton.activeHasError=active.hasError}}scope.showNavigation=!0,scope.showMoreButton=!1,scope.showDropdown=!1,scope.overflowingItems=0,scope.itemsLimit=Number.isInteger(scope.limit)?scope.limit:6,scope.moreButton={alias:"more",active:!1,name:"More"},scope.openNavigationItem=function(item){scope.showDropdown=!1,function runItemAction(selectedItem){selectedItem.action&&selectedItem.action(selectedItem)}(item),function setItemToActive(selectedItem){selectedItem.view&&(Utilities.forEach(scope.navigation,function(item){item.active=!1}),selectedItem.active=!0,setMoreButtonActiveState(),setMoreButtonErrorState())}(item),scope.onSelect&&scope.onSelect({item:item}),eventsService.emit("app.tabChange",item)},scope.openAnchorItem=function(item,anchor){scope.onAnchorSelect&&scope.onAnchorSelect({item:item,anchor:anchor}),!0!==item.active&&scope.openNavigationItem(item)},scope.toggleDropdown=function(){scope.showDropdown=!scope.showDropdown},scope.hideDropdown=function(){scope.showDropdown=!1};var resizeCallback=function resizeCallback(size){size&&size.width&&calculateVisibleItems(size.width)};windowResizeListener.register(resizeCallback),unsubscribe.push(scope.$watch("limit",function(newVal){scope.itemsLimit=newVal,calculateVisibleItems($window.innerWidth)})),scope.$on("$destroy",function(){for(var u in windowResizeListener.unregister(resizeCallback),unsubscribe)unsubscribe[u]()}),function onInit(){var firstRun=!0;calculateVisibleItems($window.innerWidth),unsubscribe.push(scope.$watch("navigation",function(newVal,oldVal){var newLength=newVal.length,oldLength=oldVal.length;(firstRun||void 0!==newLength&&newLength!==oldLength)&&(firstRun=!1,scope.showNavigation=newLength>1,calculateVisibleItems($window.innerWidth)),setMoreButtonErrorState()},!0))}()}}})}(),function(){angular.module("umbraco.directives.html").component("umbEditorNavigationItem",{template:'<button data-element="sub-view-{{vm.item.alias}}" type="button" ng-click="vm.clicked()" hotkey="{{::vm.hotkey}}" hotkey-when-hidden="true" ng-class="{\'is-active\': vm.item.active, \'-has-error\': vm.item.hasError }" ng-disabled="vm.item.disabled" class="umb-sub-views-nav-item__action umb-outline umb-outline--thin" aria-haspopup="{{ vm.item.anchors && vm.item.anchors.length > 1 }}" aria-expanded="{{ vm.expanded }}"> <umb-icon icon="{{vm.item.icon}}" class="icon"></umb-icon> <span class="umb-sub-views-nav-item-text">{{ vm.item.name }}</span> <div ng-show="vm.item.badge" class="badge -type-{{vm.item.badge.type}}">{{vm.item.badge.count}}</div> <div ng-show="!vm.item.badge" class="badge -type-alert --error-badge">!</div> </button> <umb-dropdown on-close="vm.close()" deep-blur="vm.close()" umb-keyboard-list class="umb-sub-views-nav-item__anchor_dropdown" ng-class="{\'is-expanded\': vm.expanded}" ng-if="vm.item.anchors && vm.item.anchors.length > 1"> <umb-dropdown-item ng-repeat="anchor in vm.item.anchors" ng-class="{\'is-active\': vm.item.active && anchor.active}"> <a href="#group-{{anchor.id}}" ng-click="vm.anchorClicked(anchor, $event)" prevent-default> <span class="sr-only"><localize key="visuallyHiddenTexts_jumpTo">Jump to</localize></span> {{anchor.label}} <span class="sr-only"><localize key="visuallyHiddenTexts_group"> group</localize></span> </a> </umb-dropdown-item> </umb-dropdown> ',controller:function UmbEditorNavigationItemController($scope,$element,$attrs){var vm=this;vm.close=function(){vm.expanded=!1},vm.clicked=function(){vm.expanded=vm.item.anchors&&vm.item.anchors.length>1&&!vm.expanded,vm.onOpen({item:vm.item})},vm.anchorClicked=function(anchor,$event){vm.onOpenAnchor({item:vm.item,anchor:anchor}),$event.stopPropagation(),$event.preventDefault()},vm.mouseOver=function(){$scope.$digest()};var componentNode=$element[0];componentNode.classList.add("umb-sub-views-nav-item"),componentNode.addEventListener("mouseover",vm.mouseOver),$scope.$on("$destroy",function(){componentNode.removeEventListener("mouseover",vm.mouseOver)})},controllerAs:"vm",bindings:{item:"=",onOpen:"&",onOpenAnchor:"&",hotkey:"<"}})}(),function(){angular.module("umbraco.directives").directive("umbEditors",function EditorsDirective($timeout,eventsService,focusLockService){return{restrict:"E",replace:!0,template:"<div class=\"umb-editors\"> <umb-editor-repeater class=\"umb-editor\" ng-repeat=\"model in editors\" ng-attr-umb-focus-lock=\"{{$last || undefined}}\" ng-attr-inert=\"{{$last ? undefined : true}}\" ng-class=\"{'umb-editor--small': model.size === 'small', 'umb-editor--medium': model.size === 'medium', 'umb-editor--animating': model.animating, 'umb-editor--notInFront': model.inFront !== true, 'umb-editor--infiniteMode': model.infiniteMode, 'umb-editor--moveRight': model.moveRight, 'umb-editor--n0': model.styleIndex === 0, 'umb-editor--n1': model.styleIndex === 1, 'umb-editor--n2': model.styleIndex === 2, 'umb-editor--n3': model.styleIndex === 3, 'umb-editor--outOfRange': model.level === -1, 'umb-editor--level0': model.level === 0, 'umb-editor--level1': model.level === 1, 'umb-editor--level2': model.level === 2, 'umb-editor--level3': model.level === 3}\"> <div ng-if=\"!model.view && !model.animating\" ng-transclude></div> <div ng-if=\"model.view && !model.animating && !model.$parentScope\" ng-include=\"model.view\"></div> <div ng-show=\"model.$parentScope\" class=\"scoped-view\"></div> <div class=\"umb-editor__overlay\"></div> </umb-editor-repeater> </div> ",link:function link(scope,el,attr,ctrl){var evts=[],allowedNumberOfVisibleEditors=3,aboveBackDropCssClass="above-backdrop",sectionId="#leftcolumn",isLeftColumnAbove=!1;scope.editors=[];var editorCount=0;function addEditor(editor){editor.inFront=!0,editor.moveRight=!0,editor.level=0,editor.styleIndex=0,scope.editors.push(editor),1===scope.editors.length&&((isLeftColumnAbove=$(sectionId).hasClass(aboveBackDropCssClass))&&$(sectionId).removeClass(aboveBackDropCssClass),focusLockService.addInertAttribute()),$timeout(function(){editor.moveRight=!1}),editor.animating=!0,setTimeout(function revealEditorContent(editor){editor.animating=!1,scope.$digest()}.bind(this,editor),400),updateEditors()}function removeEditor(editor){editor.moveRight=!0,editor.animating=!0,setTimeout(function removeEditorFromDOM(editor){var index=scope.editors.indexOf(editor);-1!==index&&scope.editors.splice(index,1),updateEditors(),scope.$digest()}.bind(this,editor),400),updateEditors(-1),1===scope.editors.length&&(isLeftColumnAbove&&$("#leftcolumn").addClass(aboveBackDropCssClass),isLeftColumnAbove=!1),0===editorCount&&focusLockService.removeInertAttribute()}function updateEditors(offset){offset=offset||0;for(var len=scope.editors.length,calcLen=len+offset,ceiling=Math.min(calcLen,allowedNumberOfVisibleEditors),origin=Math.max(calcLen-1,0)-ceiling,i=0;i<len;){var iEditor=scope.editors[i];iEditor.styleIndex=Math.min(i+1,allowedNumberOfVisibleEditors),iEditor.level=Math.max(i-origin,-1),iEditor.inFront=iEditor.level>=ceiling,i++}}evts.push(eventsService.on("appState.editors.open",function(name,args){editorCount+=1,addEditor(args.editor)})),evts.push(eventsService.on("appState.editors.close",function(name,args){args&&args.editor&&(editorCount-=1,removeEditor(args.editor)),args&&!args.editor&&0===args.editors.length&&(editorCount=0,scope.editors=[],focusLockService.removeInertAttribute())})),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])})}}}),angular.module("umbraco.directives").directive("umbEditorRepeater",function EditorRepeaterDirective($http,$templateCache,$compile,angularHelper){return{restrict:"E",replace:!0,transclude:!0,scope:{editors:"="},template:"<div ng-transclude></div>",link:function link(scope,el){var editor=scope&&scope.$parent?scope.$parent.model:null;if(editor){var unsubscribe=[];if(editor.$parentScope){var element=el.find(".scoped-view");$http.get(editor.view,{cache:$templateCache}).then(function(response){var templateScope=editor.$parentScope.$new();unsubscribe.push(function(){templateScope.$destroy()}),templateScope.model=editor,element.show(),editor.$parentForm&&element.html("<ng-form name='infiniteEditorForm'>"+response.data+"</ng-form>"),$compile(element)(templateScope),editor.$parentForm&&editor.$parentForm.$addControl(templateScope.infiniteEditorForm)})}scope.$on("$destroy",function(){for(var i=0;i<unsubscribe.length;i++)unsubscribe[i]()})}}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorSubView",function EditorSubViewDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-editor-sub-view" ng-class="\'sub-view-\' + model.name" val-sub-view="model"> <div class="umb-editor-sub-view__content" ng-show="model.active === true" ng-include="model.view"> </div> </div> ',scope:{model:"=",variantContent:"=?",content:"="},link:function link(scope){if(!scope.model.view)throw"No view defined for the content app"}}})}(),function(){angular.module("umbraco.directives").directive("umbEditorSubViews",function EditorSubViewsDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-editor-sub-views"> <div id="sub-view-{{$index}}" class="umb-editor-sub-view" ng-repeat="subView in subViews track by subView.alias" ng-class="\'sub-view-\' + subView.name" val-sub-view="subView"> <div class="umb-editor-sub-view__content" ng-show="subView.active === true" ng-include="subView.view"> </div> </div> </div> ',scope:{subViews:"=",model:"="},link:function link(scope,el,attr,ctrl){}}})}(),function(){var umbEditorTabBarComponent={template:'<div data-element="editor-tab-bar" class="umb-editor-tab-bar"> <ng-transclude></ng-transclude> </div> ',controllerAs:"vm",transclude:!0,controller:function umbEditorTabBarController(){}};angular.module("umbraco.directives").component("umbEditorTabBar",umbEditorTabBarComponent)}(),function(){angular.module("umbraco.directives").directive("umbEditorView",function EditorViewDirective(){return{transclude:!0,restrict:"E",replace:!0,template:" <div class=\"umb-panel umb-editor-wrapper\" ng-class=\"{ '-no-footer': footer === 'false' }\" ng-transclude> </div> ",link:function link(scope,el,attr){attr.footer&&(scope.footer=attr.footer)}}})}(),function(){angular.module("umbraco.directives").directive("deepBlur",function DeepBlurDirective($timeout){return{restrict:"A",controller:function controller($scope,$element,$attrs){var leaveExpr=$attrs.deepBlur,dom=$element[0];dom.addEventListener("blur",function onBlur(e){var targetElement=e.relatedTarget;(function containsDom(parent,dom){for(;dom;){if(dom===parent)return!0;dom=dom.parentNode}return!1})(dom,targetElement)||$timeout(function(){$scope.$apply(leaveExpr)},10)},!0)}}})}(),function(){angular.module("umbraco.directives").directive("onDelayedMouseleave",function onDelayedMouseleaveDirective($timeout,$parse){return{restrict:"A",link:function link(scope,element,attrs,ctrl){var active=!1,fn=$parse(attrs.onDelayedMouseleave),leave_f=function leave_f(event){var callback=function callback(){fn(scope,{$event:event})};active=!1,$timeout(function(){!1===active&&scope.$apply(callback)},650)},enter_f=function enter_f(event,args){active=!0};element.on("mouseleave",leave_f),element.on("mouseenter",enter_f),scope.$on("$destroy",function(){element.off("mouseleave",leave_f),element.off("mouseenter",enter_f)})}}})}(),function(){angular.module("umbraco.directives").directive("onDragEnd",function onDragEndDirective(){return{link:function link(scope,elm,attrs){var f=function f(){scope.$apply(attrs.onDragEnd)};elm.on("dragend",f),scope.$on("$destroy",function(){elm.off("dragend",f)})}}})}(),function(){angular.module("umbraco.directives").directive("onDragEnter",function onDragEnterDirective(){return{link:function link(scope,elm,attrs){var f=function f(){scope.$apply(attrs.onDragEnter)};elm.on("dragenter",f),scope.$on("$destroy",function(){elm.off("dragenter",f)})}}})}(),function(){angular.module("umbraco.directives").directive("onDragLeave",function onDragLeaveDirective($timeout){return function(scope,elm,attrs){var f=function f(event){var rect=this.getBoundingClientRect(),e=function getCursorPosition(event){var x,y;return void 0===event.clientX?(x=event.pageX+document.documentElement.scrollLeft,y=event.pageY+document.documentElement.scrollTop):(x=event.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,y=event.clientY+document.body.scrollTop+document.documentElement.scrollTop),{x:x,y:y}}(event.originalEvent);(e.x>rect.left+rect.width-1||e.x<rect.left||e.y>rect.top+rect.height-1||e.y<rect.top)&&scope.$apply(attrs.onDragLeave)};elm.on("dragleave",f),scope.$on("$destroy",function(){elm.off("dragleave",f)})}})}(),function(){angular.module("umbraco.directives").directive("onDragOver",function onDragOverDirective(){return{link:function link(scope,elm,attrs){var f=function f(){scope.$apply(attrs.onDragOver)};elm.on("dragover",f),scope.$on("$destroy",function(){elm.off("dragover",f)})}}})}(),function(){angular.module("umbraco.directives").directive("onDragStart",function onDragStartDirective($timeout){return{link:function link(scope,elm,attrs){var f=function f(){scope.$apply(attrs.onDragStart)};elm.on("dragstart",f),scope.$on("$destroy",function(){elm.off("dragstart",f)})}}})}(),function(){angular.module("umbraco.directives").directive("onDrop",function onDropDirective(){return{link:function link(scope,elm,attrs){var f=function f(){scope.$apply(attrs.onDrop)};elm.on("drop",f),scope.$on("$destroy",function(){elm.off("drop",f)})}}})}(),function(){angular.module("umbraco.directives").directive("onOutsideClick",function onOutsideClickDirective($timeout,angularHelper){return function(scope,element,attrs){var eventBindings=[];function oneTimeClick(event){var el=event.target.nodeName;["INPUT","A","BUTTON"].indexOf(el)>=0||$(event.target).parents("a,button,.umb-overlay,.umb-tour").length>0||1!==$(event.target).parents("#old-dialog-service").length&&1!==$(event.target).closest(".mce-floatpanel").length&&1!==$(event.target).closest(".flatpickr-calendar").length&&($(element).has($(event.target)).length>0||scope.$evalAsync(attrs.onOutsideClick))}$timeout(function(){"bindClickOn"in attrs?eventBindings.push(scope.$watch(function(){return attrs.bindClickOn},function(newValue){"true"===newValue?$(document).on("click",oneTimeClick):$(document).off("click",oneTimeClick)})):$(document).on("click",oneTimeClick),scope.$on("$destroy",function(){for(var e in $(document).off("click",oneTimeClick),eventBindings)eventBindings[e]()})})}})}(),function(){angular.module("umbraco.directives").directive("onRightClick",function onRightClickDirective($parse){return document.oncontextmenu=function(e){if(e.target.hasAttribute("on-right-click"))return e.preventDefault(),e.stopPropagation(),!1},function(scope,el,attrs){el.on("contextmenu",function(e){e.preventDefault(),e.stopPropagation();var fn=$parse(attrs.onRightClick);return scope.$apply(function(){fn(scope,{$event:e})}),!1})}})}(),angular.module("umbraco.directives").directive("checklistModel",["$parse","$compile",function($parse,$compile){function postLinkFn(scope,elem,attrs){$compile(elem)(scope);var getter=$parse(attrs.checklistModel),setter=getter.assign,value=$parse(attrs.checklistValue)(scope.$parent);scope.$watch("checked",function(newValue,oldValue){if(newValue!==oldValue){var current=getter(scope.$parent);setter(scope.$parent,!0===newValue?function add(arr,item){arr=Utilities.isArray(arr)?arr:[];for(var i=0;i<arr.length;i++)if(Utilities.equals(arr[i],item))return arr;return arr.push(item),arr}(current,value):function remove(arr,item){if(Utilities.isArray(arr))for(var i=0;i<arr.length;i++)if(Utilities.equals(arr[i],item)){arr.splice(i,1);break}return arr}(current,value))}}),scope.$parent.$watch(attrs.checklistModel,function(newArr,oldArr){scope.checked=function contains(arr,item){if(Utilities.isArray(arr))for(var i=0;i<arr.length;i++)if(Utilities.equals(arr[i],item))return!0;return!1}(newArr,value)},!0)}return{restrict:"A",priority:1e3,terminal:!0,scope:!0,compile:function compile(tElement,tAttrs){if("INPUT"!==tElement[0].tagName||!tElement.attr("type","checkbox"))throw'checklist-model should be applied to `input[type="checkbox"]`.';if(!tAttrs.checklistValue)throw"You should provide `checklist-value`.";return tElement.removeAttr("checklist-model"),tElement.attr("ng-model","checked"),postLinkFn}}}]),angular.module("umbraco.directives").directive("contenteditable",function(){return{require:"ngModel",link:function link(scope,element,attrs,ngModel){function read(){ngModel.$setViewValue(element.html())}ngModel.$render=function(){element.html(ngModel.$viewValue||"")},element.on("focus",function(){var range=document.createRange();range.selectNodeContents(element[0]);var sel=window.getSelection();sel.removeAllRanges(),sel.addRange(range)}),element.on("blur keyup change",function(){scope.$apply(read)})}}}),angular.module("umbraco.directives").directive("fixNumber",function fixNumber($parse){return{restrict:"A",require:"ngModel",link:function link(scope,elem,attrs,ctrl){var modelVal=scope.$eval(attrs.ngModel);if(modelVal){var asNum=parseFloat(modelVal,10);isNaN(asNum)||$parse(attrs.ngModel).assign(scope,asNum)}ctrl.$parsers.push(function(value){return 0===value?0:parseFloat(value||"",10)}),ctrl.$formatters.push(function(value){return Utilities.isString(value)?parseFloat(value,10):value}),void 0!==elem.prop("validity")&&elem.on("input",function(e){var validity=elem.prop("validity");scope.$apply(function(){ctrl.$setValidity("number",!validity.badInput)})})}}}),angular.module("umbraco.directives").directive("focusWhen",function($timeout){return{restrict:"A",link:function link(scope,elm,attrs,ctrl){var delayTimer;attrs.$observe("focusWhen",function(newValue){"true"===newValue&&document.activeelement!==elm[0]&&(delayTimer=$timeout(function(){elm[0].focus()}))}),scope.$on("$destroy",function(){$timeout.cancel(delayTimer)})}}}),angular.module("umbraco.directives").directive("hexBgColor",function hexBgColor(){return{restrict:"A",link:function link(scope,element,attr,formCtrl){function setBackgroundColor(color){element[0].style.backgroundColor="#"+color}if(void 0===attr.hexBgInline||void 0!==attr.hexBgInline&&"true"===attr.hexBgInline){var origColor=null;attr.hexBgOrig&&(origColor=attr.hexBgOrig),attr.$observe("hexBgColor",function(newVal){if(newVal){origColor||(origColor=element.css("border-color"));var match=newVal.match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);if(match&&match.length)return void setBackgroundColor(match[1]);if((match=newVal.match(/^#?([0-9a-f]{4}|[0-9a-f]{8})$/i))&&match.length)return void setBackgroundColor(match[1])}setBackgroundColor(origColor)})}}}}),angular.module("umbraco.directives").directive("hotkey",function($window,keyboardService,$log,focusService){return function(scope,el,attrs){var options={},keyCombo=attrs.hotkey;keyCombo||(keyCombo=scope.$eval(attrs.hotkey)),function activate(){keyCombo&&(1===keyCombo.length&&(options={inputDisabled:!0}),keyboardService.bind(keyCombo,function(){focusService.rememberFocus();var element=$(el),activeElementType=document.activeElement.tagName;if(element.is("a,div,button,input[type='button'],input[type='submit'],input[type='checkbox']")&&!element.is(":disabled")){if(element.is(":visible")||attrs.hotkeyWhenHidden){if(attrs.hotkeyWhen&&"false"===attrs.hotkeyWhen)return;"enter"===keyCombo&&0===["A","BUTTON"].indexOf(activeElementType)?document.activeElement.trigger("click"):element.trigger("click")}}else element.trigger("focus")},options),el.on("$destroy",function(){keyboardService.unbind(keyCombo)}))}()}}),angular.module("umbraco.directives").directive("preventDefault",function(){return function(scope,element,attrs){var enabled=!0;attrs.preventDefault&&attrs.$observe("preventDefault",function(newVal){enabled="false"!==newVal&&0!==newVal&&!1!==newVal}),$(element).on("click",function(event){event.metaKey||event.ctrlKey||!0===enabled&&event.preventDefault()})}}),angular.module("umbraco.directives").directive("preventEnterSubmit",function(){return function(scope,element,attrs){var enabled=!0;attrs.preventEnterSubmit&&attrs.$observe("preventEnterSubmit",function(newVal){enabled="false"!==newVal&&0!==newVal&&!1!==newVal}),$(element).on("keypress",function(event){13===event.which&&!0===enabled&&event.preventDefault()})}}),angular.module("umbraco.directives").directive("resizeToContent",function($window,$timeout){return function(scope,el,attrs){var iframe=el[0],iframeWin=iframe.contentWindow||iframe.contentDocument.parentWindow;iframeWin.document.body&&$timeout(function(){var height=iframeWin.document.documentElement.scrollHeight||iframeWin.document.body.scrollHeight;el.height(height)},3e3)}}),angular.module("umbraco.directives").directive("selectOnFocus",function(){return function(scope,el,attrs){$(el).on("click",function(){$(el).data("editmode")||(this.select(),$(el).data("editmode",!0))}).on("blur",function(){$(el).data("editmode",!1)})}}),angular.module("umbraco.directives").directive("umbAutoFocus",function($timeout){return function(scope,element,attrs){attrs.$observe("umbAutoFocus",function(newVal){"false"!==newVal&&0!==newVal&&!1!==newVal&&$timeout(function(){!function update(){(""===element.val()||attrs.focusOnFilled)&&element.trigger("focus")}()})})}}),angular.module("umbraco.directives").directive("umbAutoResize",function($timeout){return{require:["^?umbTabs","ngModel"],link:function link(scope,element,attr,controllersArr){var domEl=element[0],domElType=domEl.type,umbTabsController=controllersArr[0],ngModelController=controllersArr[1];var update=function update(force){!0===force&&("textarea"===domElType?element.height(0):"text"===domElType&&element.width(0)),"textarea"===domElType?function resizeTextarea(){domEl.scrollHeight!==domEl.clientHeight&&element.height(domEl.scrollHeight)}():"text"===domElType&&function resizeInput(){domEl.scrollWidth!==domEl.clientWidth&&ngModelController.$modelValue&&element.width(domEl.scrollWidth),ngModelController.$modelValue&&0===domEl.clientWidth&&element.width("auto"),!ngModelController.$modelValue&&attr.placeholder&&(attr.$set("size",attr.placeholder.length),element.width("auto"))}()};null!=umbTabsController&&umbTabsController.onTabShown(function(args){update()});var unbindModelWatcher=scope.$watch(function(){return ngModelController.$modelValue},function(newValue){$timeout(function(){update(!0)})});scope.$on("$destroy",function(){element.off("keyup keydown keypress change",update),element.off("blur",update(!0)),unbindModelWatcher()})}}}),function(){var component={template:'<label class="checkbox umb-form-check umb-form-check--checkbox {{vm.cssClass}}" ng-class="{ \'umb-form-check--disabled\': vm.disabled }"> <span class="umb-form-check__symbol"> <input type="checkbox" id="{{vm.inputId}}" name="{{vm.name}}" value="{{vm.value}}" class="umb-form-check__input" val-server-field="{{vm.serverValidationField}}" ng-model="vm.model" ng-disabled="vm.disabled" ng-required="vm.required" ng-change="vm.change()" no-dirty-check="{{vm.disableDirtyCheck}}"> <span class="umb-form-check__state" aria-hidden="true"> <span class="umb-form-check__check"> <umb-icon icon="icon-check" class="umb-form-check__icon"></umb-icon> </span> </span> </span> <span class="umb-form-check__info" ng-transclude> <umb-icon ng-if="vm.icon.length" icon="{{vm.icon}}"></umb-icon> <span ng-if="vm.text.length" class="umb-form-check__text">{{vm.text}}</span> </span> </label> ',controller:function UmbCheckboxController($timeout,$attrs,localizationService){var vm=this;vm.$onInit=function onInit(){vm.inputId=vm.inputId||"umb-check_"+String.CreateGuid(),vm.disableDirtyCheck=$attrs.hasOwnProperty("disableDirtyCheck")&&"0"!==vm.disableDirtyCheck&&0!==vm.disableDirtyCheck&&"false"!==vm.disableDirtyCheck&&!1!==vm.disableDirtyCheck,vm.icon=vm.icon||vm.iconClass||null,vm.labelKey&&localizationService.localize(vm.labelKey).then(function(data){-1===data.indexOf("[")&&(vm.text=data)})},vm.change=function change(){vm.onChange&&$timeout(function(){vm.onChange({model:vm.model,value:vm.value})},0)}},controllerAs:"vm",transclude:!0,bindings:{model:"=",inputId:"@",value:"@",name:"@",text:"@",labelKey:"@?",serverValidationField:"@",disabled:"<",required:"<",onChange:"&?",cssClass:"@?",iconClass:"@?",icon:"@?",disableDirtyCheck:"=?"}};angular.module("umbraco.directives").component("umbCheckbox",component)}(),function(){angular.module("umbraco.directives").directive("umbFocusLock",function FocusLock($timeout,$rootScope,angularHelper){return{restrict:"A",link:function link(scope,element){var focusableElements,firstFocusableElement,lastFocusableElement,infiniteEditorsWrapper,infiniteEditors,target=element[0],disconnectObserver=!1,closingEditor=!1;$rootScope.lastKnownFocusableElements||($rootScope.lastKnownFocusableElements=[]),$rootScope.lastKnownFocusableElements.push(document.activeElement);var focusableElementsSelector='[role="button"], a[href]:not([disabled]):not(.ng-hide), button:not([disabled]):not(.ng-hide), textarea:not([disabled]):not(.ng-hide), input:not([disabled]):not(.ng-hide), select:not([disabled]):not(.ng-hide)';function getFocusableElements(targetElm){focusableElements=(targetElm||target).querySelectorAll(focusableElementsSelector),firstFocusableElement=focusableElements[0],lastFocusableElement=focusableElements[focusableElements.length-1]}function handleKeydown(event){("Tab"===event.key||9===event.keyCode)&&(event.shiftKey?document.activeElement===firstFocusableElement&&(lastFocusableElement.focus(),event.preventDefault()):document.activeElement===lastFocusableElement&&(firstFocusableElement.focus(),event.preventDefault()))}function clearLastKnownFocusedElements(){$rootScope.lastKnownFocusableElements=[]}function onInit(targetElm){$timeout(function(){!function getDomNodes(){(infiniteEditorsWrapper=document.querySelector(".umb-editors"))&&(infiniteEditors=Array.from(infiniteEditorsWrapper.querySelectorAll(".umb-editor")||[]))}(),function cleanupEventHandlers(){if(infiniteEditors.length>0){var activeEditor=infiniteEditors[infiniteEditors.length-1],inactiveEditors=infiniteEditors.filter(function(editor){return editor!==activeEditor});if(inactiveEditors.length>0)for(var index=0;index<inactiveEditors.length;index++)inactiveEditors[index].removeEventListener("keydown",handleKeydown);else activeEditor.removeEventListener("keydown",handleKeydown)}}(),getFocusableElements(targetElm),focusableElements.length>0&&(function observeDomChanges(){var observer=new MutationObserver(_.debounce(function domChange(){getFocusableElements()},200));observer.observe(target,{attributes:!0,childList:!0,subtree:!0}),disconnectObserver&&observer.disconnect()}(),function setElementFocus(){var lastKnownElement,defaultFocusedElement=function getAutoFocusElement(elements){var elmentWithAutoFocus=null;return elements.forEach(function(element){"true"===element.getAttribute("umb-auto-focus")&&(elmentWithAutoFocus=element)}),elmentWithAutoFocus}(focusableElements);if(closingEditor){if(infiniteEditors&&1===infiniteEditors.length){var editorInfo=infiniteEditors[0].querySelector(".editor-info");infiniteEditors&&1===infiniteEditors.length&&null!==editorInfo&&(lastKnownElement=editorInfo,clearLastKnownFocusedElements())}else{var lastItemIndex=$rootScope.lastKnownFocusableElements.length-1;lastKnownElement=$rootScope.lastKnownFocusableElements[lastItemIndex],$rootScope.lastKnownFocusableElements.splice(lastItemIndex,1)}closingEditor=!1}lastKnownElement?lastKnownElement.focus():null===defaultFocusedElement?firstFocusableElement.focus():defaultFocusedElement.focus()}(),target.addEventListener("keydown",handleKeydown))})}document.querySelector("body"),scope.$on("$includeContentLoaded",function(){angularHelper.safeApply(scope,function(){onInit()})}),scope.$on("$destroy",function(){if(disconnectObserver=!0,infiniteEditors&&infiniteEditors.length>1){var newTarget=infiniteEditors[infiniteEditors.length-2];if(infiniteEditors.length>1)return closingEditor=!0,void onInit(newTarget)}clearLastKnownFocusedElements(),target.removeEventListener("keydown",handleKeydown)})}}})}(),function(){var component={template:'<label class="radio umb-form-check umb-form-check--radiobutton {{vm.cssClass}}" ng-class="{ \'umb-form-check--disabled\': vm.disabled }"> <span class="umb-form-check__symbol"> <input type="radio" id="{{vm.inputId}}" name="{{vm.name}}" value="{{vm.value}}" class="umb-form-check__input" val-server-field="{{vm.serverValidationField}}" ng-model="vm.model" ng-disabled="vm.disabled" ng-required="vm.required" ng-change="vm.change()" no-dirty-check="{{vm.disableDirtyCheck}}"> <span class="umb-form-check__state" aria-hidden="true"> <span class="umb-form-check__check"></span> </span> </span> <span class="umb-form-check__info" ng-transclude> <umb-icon ng-if="vm.icon.length" icon="{{vm.icon}}"></umb-icon> <span ng-if="vm.text.length" class="umb-form-check__text">{{vm.text}}</span> </span> </label> ',controller:function UmbRadiobuttonController($timeout,$attrs,localizationService){var vm=this;vm.$onInit=function onInit(){vm.inputId=vm.inputId||"umb-radio_"+String.CreateGuid(),vm.disableDirtyCheck=$attrs.hasOwnProperty("disableDirtyCheck")&&"0"!==vm.disableDirtyCheck&&0!==vm.disableDirtyCheck&&"false"!==vm.disableDirtyCheck&&!1!==vm.disableDirtyCheck,vm.icon=vm.icon||vm.iconClass||null,vm.labelKey&&localizationService.localize(vm.labelKey).then(function(data){-1===data.indexOf("[")&&(vm.text=data)})},vm.change=function change(){vm.onChange&&$timeout(function(){vm.onChange({model:vm.model,value:vm.value})},0)}},controllerAs:"vm",transclude:!0,bindings:{model:"=",inputId:"@",value:"@",name:"@",text:"@",labelKey:"@?",serverValidationField:"@",disabled:"<",required:"<",onChange:"&?",cssClass:"@?",iconClass:"@?",icon:"@?",disableDirtyCheck:"=?"}};angular.module("umbraco.directives").component("umbRadiobutton",component)}(),angular.module("umbraco.directives").directive("umbRawModel",function(){return{restrict:"A",require:"ngModel",template:'<textarea ng-model="jsonEditing"></textarea>',replace:!0,scope:{model:"=umbRawModel",validateOn:"="},link:function link(scope,element,attrs,ngModelCtrl){function setEditing(value){scope.jsonEditing=Utilities.copy(function jsonToString(object){return Utilities.toJson(object,!0)}(value))}function updateModel(value){scope.model=function stringToJson(text){try{return Utilities.fromJson(text)}catch(err){return setInvalid(),text}}(value)}function setInvalid(){ngModelCtrl.$setValidity("json",!1)}setEditing(scope.model);var onInputChange=function onInputChange(newval,oldval){newval!==oldval&&(!function isValidJson(model){var flag=!0;try{Utilities.fromJson(model)}catch(err){flag=!1}return flag}(newval)?setInvalid():(!function setValid(){ngModelCtrl.$setValidity("json",!0)}(),updateModel(newval)))};scope.validateOn?element.on(scope.validateOn,function(){scope.$apply(function(){onInputChange(scope.jsonEditing)})}):scope.$watch("jsonEditing",onInputChange,!0),scope.$watch("model",function(newval,oldval){newval!==oldval&&setEditing(newval)},!0)}}}),function(){var component={template:'<div class="umb-control-group -no-border"> <div class="umb-search-filter" ng-class="vm.cssClass"> <label for="{{vm.inputId}}" class="sr-only">{{vm.text}}</label> <button type="button" class="btn-reset icon icon-arrow-left" ng-if="vm.showBackButton && vm.model.length > 0" ng-click="vm.goBack()" localize="title" title="@general_back"> </button> <umb-icon icon="icon-search" ng-if="!vm.showBackButton || vm.model.length === 0"></umb-icon> <input type="text" id="{{vm.inputId}}" ng-change="vm.change()" ng-keydown="vm.keyDown($event)" ng-blur="vm.blur($event)" ng-model="vm.model" class="umb-search-filter__input" placeholder="{{vm.text}}" umb-auto-focus="{{vm.autoFocus}}" prevent-enter-submit="{{vm.preventSubmitOnEnter}}" no-dirty-check> </div> </div> ',controller:function UmbSearchFilterController($timeout,localizationService){var vm=this;vm.$onInit=function onInit(){vm.inputId=vm.inputId||"umb-search-filter_"+String.CreateGuid(),vm.autoFocus=!0===Object.toBoolean(vm.autoFocus),vm.preventSubmitOnEnter=!0===Object.toBoolean(vm.preventSubmitOnEnter),vm.showBackButton=!0===Object.toBoolean(vm.showBackButton),vm.labelKey&&localizationService.localize(vm.labelKey).then(function(data){-1===data.indexOf("[")&&(vm.text=data)})},vm.change=function change(){vm.onChange&&$timeout(function(){vm.onChange({model:vm.model,value:vm.value})},0)},vm.keyDown=function keyDown(evt){switch(evt.keyCode){case 13:vm.onSearch&&vm.onSearch()}},vm.blur=function blur(){vm.onBlur&&vm.onBlur()},vm.goBack=function goBack(){vm.onBack&&vm.onBack()}},controllerAs:"vm",transclude:!0,bindings:{model:"=",inputId:"@",text:"@",labelKey:"@?",onChange:"&?",onSearch:"&?",onBlur:"&?",onBack:"&?",autoFocus:"<?",preventSubmitOnEnter:"<?",showBackButton:"<?",cssClass:"@?"}};angular.module("umbraco.directives").component("umbSearchFilter",component)}(),function(){angular.module("umbraco.directives").directive("umbSelectWhen",function SelectWhen($timeout){return{restrict:"A",link:function link(scope,el,attr,ctrl){attr.$observe("umbSelectWhen",function(newValue){"true"===newValue&&$timeout(function(){el.select()})})}}})}(),angular.module("umbraco.directives").directive("validWhen",function(){return{require:"ngModel",restrict:"A",link:function link(scope,element,attr,ngModel){attr.$observe("validWhen",function(newValue){ngModel.$setValidity("validWhen","true"===newValue)})}}}),angular.module("umbraco.directives").directive("gridRte",function(tinyMceService,angularHelper,assetsService,$q,$timeout,eventsService,tinyMceAssets){return{scope:{uniqueId:"=",value:"=",configuration:"=",datatypeKey:"@",ignoreUserStartNodes:"@"},template:' <div> <umb-load-indicator ng-if="isLoading"></umb-load-indicator> <div disable-hotkeys class="umb-rte" id="{{textAreaHtmlId}}" ng-style="{ visibility : isLoading ? \'hidden\' : \'visible\' }"></div> </div> ',replace:!0,link:function link(scope,element,attrs){scope.isLoading=!0;var promises=[];scope.textAreaHtmlId=scope.uniqueId+"_"+String.CreateGuid();var editorConfig=scope.configuration?scope.configuration:null;editorConfig&&!Utilities.isString(editorConfig)||((editorConfig=tinyMceService.defaultPrevalues()).toolbar=_.without(editorConfig,"umbmacro")),scope.configuration.maxImageSize||0===scope.configuration.maxImageSize||(editorConfig.maxImageSize=tinyMceService.defaultPrevalues().maxImageSize),scope.config={ignoreUserStartNodes:"true"===scope.ignoreUserStartNodes},scope.dataTypeKey=scope.datatypeKey;var tinyMceEditor=null;function pinToolbar(){tinyMceService.pinToolbar(tinyMceEditor)}tinyMceAssets.forEach(function(tinyJsAsset){promises.push(assetsService.loadJs(tinyJsAsset,scope))}),promises.push(tinyMceService.getTinyMceEditorConfig({htmlId:scope.textAreaHtmlId,stylesheets:editorConfig.stylesheets,toolbar:editorConfig.toolbar,mode:editorConfig.mode})),$q.all(promises).then(function(result){var standardConfig=result[promises.length-1],baseLineConfigObj={maxImageSize:editorConfig.maxImageSize};Utilities.extend(baseLineConfigObj,standardConfig),baseLineConfigObj.setup=function(editor){tinyMceEditor=editor,tinyMceService.initializeEditor({editor:editor,model:scope,currentForm:angularHelper.getCurrentForm(scope.$parent)}),editor.on("init",function(e){scope.isLoading=!1,editor.getBody().style.overflow="hidden",$timeout(function(){null===scope.value&&editor.focus()},400)}),editor.on("blur",function(e){angularHelper.safeApply(scope,function(){!function unpinToolbar(){tinyMceService.unpinToolbar(tinyMceEditor)}(),$(".umb-panel-body").off("scroll",pinToolbar)})}),editor.on("focus",function(e){angularHelper.safeApply(scope,function(){pinToolbar(),$(".umb-panel-body").on("scroll",pinToolbar)})}),editor.on("click",function(e){angularHelper.safeApply(scope,function(){pinToolbar(),$(".umb-panel-body").on("scroll",pinToolbar)})})},function loadTinyMce(){$timeout(function(){tinymce.init(baseLineConfigObj)},150,!1)}();var tabShownListener=eventsService.on("app.tabChange",function(e,args){var tabId=args.id,myTabId=element.closest(".umb-tab-pane").attr("rel");String(tabId)===myTabId&&void 0!==tinyMceEditor&&null!=tinyMceEditor&&tinyMceEditor.execCommand("mceAutoResize",!1,null,null)});scope.$on("$destroy",function(){eventsService.unsubscribe(tabShownListener),$(".umb-panel-body").off("scroll",pinToolbar),void 0!==tinyMceEditor&&null!=tinyMceEditor&&tinyMceEditor.destroy()})})}}}),function(){angular.module("umbraco.directives").directive("umbBox",function BoxDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-box" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").directive("umbBoxContent",function BoxContentDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-box-content" ng-transclude></div>'}})}(),function(){angular.module("umbraco.directives").directive("umbBoxHeader",function BoxHeaderDirective(localizationService){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-box-header"> <div> <div class="umb-box-header-title" ng-if="titleLabel"> {{titleLabel}} </div> <div class="umb-box-header-description" ng-if="descriptionLabel"> {{descriptionLabel}} </div> </div> <ng-transclude></ng-transclude> </div> ',scope:{titleKey:"@?",title:"@?",descriptionKey:"@?",description:"@?"},link:function link(scope){scope.titleLabel=scope.title,scope.titleKey&&localizationService.localize(scope.titleKey,[],scope.title).then(function(data){scope.titleLabel=data}),scope.descriptionLabel=scope.description,scope.descriptionKey&&localizationService.localize(scope.descriptionKey,[],scope.description).then(function(data){scope.descriptionLabel=data})}}})}(),angular.module("umbraco.directives.html").directive("umbControlGroup",function(localizationService){return{scope:{label:"@label",description:"@",hideLabel:"@",alias:"@",labelFor:"@",required:"@?"},require:"?^^form",transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-property"> <div class="control-group umb-control-group" ng-class="{error: !formValid(), hidelabel:hideLabel==\'true\'}"> <div class="umb-el-wrap"> <label ng-if="hideLabel!==\'true\'" class="control-label" for="{{alias}}"> <span ng-bind-html="labelstring"></span> <span ng-if="required"> <strong class="umb-control-required">*</strong> </span> <small ng-if="descriptionstring">{{descriptionstring}}</small> </label> <div class="controls" ng-transclude></div> </div> </div> </div> ',link:function link(scope,element,attr,formCtrl){scope.formValid=function(){return!formCtrl||!scope.labelFor||formCtrl[scope.labelFor].$valid},scope.label&&"@"===scope.label[0]?localizationService.localize(scope.label.substring(1)).then(function(data){scope.labelstring=data}):scope.labelstring=scope.label,scope.description&&"@"===scope.description[0]?localizationService.localize(scope.description.substring(1)).then(function(data){scope.descriptionstring=data}):scope.descriptionstring=scope.description}}}),angular.module("umbraco.directives.html").directive("umbPane",function(){return{transclude:!0,restrict:"E",replace:!0,template:'<div class="umb-pane" ng-transclude> </div>'}}),angular.module("umbraco.directives.html").directive("umbPanel",function($timeout,$log){return{restrict:"E",replace:!0,transclude:"true",template:'<div class="umb-panel tabbable" ng-transclude> </div> '}}),angular.module("umbraco.directives").directive("umbImageCrop",function($timeout,cropperHelper,windowResizeListener){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-cropper umb-property-editor" ng-show="src"> <div class="crop-container"> <div class="viewport"> <img ng-src="{{src}}" ng-style="{ \'top\': dimensions.image.top + dimensions.margin.top, \'left\': dimensions.image.left + dimensions.margin.left, \'width\': dimensions.image.width, \'height\': dimensions.image.height }"> <div class="__mask" ng-style="maskStyle"> <div class="__mask-info">{{width}}px x {{height}}px</div> </div> <div class="overlay" tabindex="1"></div> </div> </div> <div class="crop-controls-wrapper" ng-if="loaded"> <div class="crop-slider-wrapper"> <umb-icon icon="icon-picture" class="crop-controls-wrapper__icon-left"></umb-icon> <div class="crop-slider"> <umb-range-slider ng-model="sliderValue" options="sliderOptions" on-setup="setup(slider)" on-slide="slide(values)" on-change="change(values)"> </umb-range-slider> </div> <umb-icon icon="icon-picture" class="crop-controls-wrapper__icon-right"></umb-icon> </div> <ng-transclude></ng-transclude> </div> </div> ',scope:{src:"=",width:"@",height:"@",crop:"=",center:"=",maxSize:"@?",alias:"@?",forceUpdate:"@?"},link:function link(scope,element,attrs){var unsubscribe=[],sliderRef=null;function updateSlider(){sliderRef&&(sliderRef.noUiSlider.updateOptions({range:{min:scope.dimensions.scale.min,max:scope.dimensions.scale.max}}),sliderRef.noUiSlider.set(scope.dimensions.scale.current))}function onScroll(event){var delta=Math.max(-50,Math.min(50,event.wheelDelta||-event.detail));if(sliderRef){var currentScale=sliderRef.noUiSlider.get(),newScale=Math.min(Math.max(currentScale+.001*delta*scope.dimensions.image.ratio,scope.dimensions.scale.min),scope.dimensions.scale.max);sliderRef.noUiSlider.set(newScale),scope.$evalAsync(function(){scope.dimensions.scale.current=newScale}),event.preventDefault&&event.preventDefault()}}function updateStyles(){scope.maskStyle={height:parseInt(scope.dimensions.cropper.height,10)+"px",width:parseInt(scope.dimensions.cropper.width,10)+"px",top:parseInt(scope.dimensions.margin.top,10)+"px",left:parseInt(scope.dimensions.margin.left,10)+"px"}}scope.loaded=!1,scope.width=0,scope.height=0,scope.dimensions={element:{},image:{},cropper:{},viewport:{},margin:{},scale:{min:1,max:4,current:1}},scope.sliderOptions={start:scope.dimensions.scale.current,step:.001,tooltips:[!1],format:{to:function to(value){return parseFloat(parseFloat(value).toFixed(3))},from:function from(value){return parseFloat(parseFloat(value).toFixed(3))}},range:{min:scope.dimensions.scale.min,max:scope.dimensions.scale.max}},scope.setup=function(slider){sliderRef=slider,updateSlider()},scope.slide=function(values){values&&(scope.dimensions.scale.current=parseFloat(values))},scope.change=function(values){values&&(scope.dimensions.scale.current=parseFloat(values))},updateStyles();var $viewport=element.find(".viewport"),$image=element.find("img"),$overlay=element.find(".overlay");$overlay.bind("focus",function(){$overlay.bind("DOMMouseScroll mousewheel onmousewheel",onScroll)}),$overlay.bind("blur",function(){$overlay.unbind("DOMMouseScroll mousewheel onmousewheel",onScroll)});var constraints={left:{max:0,min:0},top:{max:0,min:0}};scope.constraints=constraints;var setConstraints=function setConstraints(){constraints.left.min=scope.dimensions.cropper.width-scope.dimensions.image.width,constraints.top.min=scope.dimensions.cropper.height-scope.dimensions.image.height},setDimensions=function setDimensions(){scope.dimensions.image.width=scope.dimensions.image.originalWidth,scope.dimensions.image.height=scope.dimensions.image.originalHeight;var _cropW=parseInt(scope.width,10),_cropH=parseInt(scope.height,10),ratioCalculation=cropperHelper.scaleToMaxSize(_cropW,_cropH,scope.dimensions.viewport.width-40,scope.dimensions.viewport.height-40);_cropW=ratioCalculation.width,_cropH=ratioCalculation.height,scope.dimensions.margin.left=.5*(scope.dimensions.viewport.width-_cropW),scope.dimensions.margin.top=.5*(scope.dimensions.viewport.height-_cropH),scope.dimensions.cropper.width=_cropW,scope.dimensions.cropper.height=_cropH,updateStyles()},resizeImageToScale=function resizeImageToScale(ratio){var prevWidth=scope.dimensions.image.width,prevHeight=scope.dimensions.image.height;scope.dimensions.image.width=scope.dimensions.image.originalWidth*ratio,scope.dimensions.image.height=scope.dimensions.image.originalHeight*ratio;var difW=scope.dimensions.image.width-prevWidth,difH=scope.dimensions.image.height-prevHeight,focusNormX=(-scope.dimensions.image.left+.5*scope.dimensions.cropper.width)/prevWidth,focusNormY=(-scope.dimensions.image.top+.5*scope.dimensions.cropper.height)/prevHeight;scope.dimensions.image.left=scope.dimensions.image.left-difW*focusNormX,scope.dimensions.image.top=scope.dimensions.image.top-difH*focusNormY,setConstraints(),validatePosition(scope.dimensions.image.left,scope.dimensions.image.top)},resizeImageToCrop=function resizeImageToCrop(){scope.dimensions.image=cropperHelper.convertToStyle(runtimeCrop,{width:scope.dimensions.image.originalWidth,height:scope.dimensions.image.originalHeight},scope.dimensions.cropper,0);var ratioCalculation=cropperHelper.calculateAspectRatioFit(scope.dimensions.image.originalWidth,scope.dimensions.image.originalHeight,scope.dimensions.cropper.width,scope.dimensions.cropper.height,!0);scope.dimensions.scale.current=scope.dimensions.image.ratio,scope.dimensions.scale.min=ratioCalculation.ratio,scope.dimensions.scale.max=4*ratioCalculation.ratio,updateSlider()},validatePosition=function validatePosition(left,top){left=Math.min(Math.max(left,constraints.left.min),constraints.left.max),top=Math.min(Math.max(top,constraints.top.min),constraints.top.max),scope.dimensions.image.left!==left&&(scope.dimensions.image.left=left),scope.dimensions.image.top!==top&&(scope.dimensions.image.top=top)};function calculateCropBox(){runtimeCrop=cropperHelper.pixelsToCoordinates(scope.dimensions.image,scope.dimensions.cropper.width,scope.dimensions.cropper.height,0)}function saveCropBox(){scope.crop=Utilities.copy(runtimeCrop)}var runtimeCrop,dragStartPosition={};$overlay.draggable({start:function start(event,ui){dragStartPosition.left=scope.dimensions.image.left,dragStartPosition.top=scope.dimensions.image.top},drag:function drag(event,ui){scope.$apply(function(){validatePosition(dragStartPosition.left+(ui.position.left-ui.originalPosition.left),dragStartPosition.top+(ui.position.top-ui.originalPosition.top))})},stop:function stop(event,ui){scope.$apply(function(){validatePosition(dragStartPosition.left+(ui.position.left-ui.originalPosition.left),dragStartPosition.top+(ui.position.top-ui.originalPosition.top)),calculateCropBox(),saveCropBox()})}});function setCrop(){var createDefaultCrop=!scope.crop;if(createDefaultCrop&&calculateCropBox(),resizeImageToCrop(),createDefaultCrop&&(scope.dimensions.scale.current=scope.dimensions.scale.min,resizeImageToScale(scope.dimensions.scale.min),scope.center)){var x1=Math.min(Math.max(scope.center.left*scope.dimensions.image.width-scope.dimensions.cropper.width/2,0),scope.dimensions.image.width-scope.dimensions.cropper.width),y1=Math.min(Math.max(scope.center.top*scope.dimensions.image.height-scope.dimensions.cropper.height/2,0),scope.dimensions.image.height-scope.dimensions.cropper.height);scope.dimensions.image.left=x1,scope.dimensions.image.top=y1,calculateCropBox(),resizeImageToCrop()}}function onViewportSizeChanged(){scope.dimensions.viewport.width=$viewport.width(),scope.dimensions.viewport.height=$viewport.height(),setDimensions(),setCrop(),setConstraints()}unsubscribe.push(scope.$watchCollection("[width, height, alias, forceUpdate]",function(newValues,oldValues){newValues!==oldValues&&(runtimeCrop=Utilities.copy(scope.crop),setDimensions(),setCrop(),setConstraints())}));var throttledScale=_.throttle(function(){return scope.$evalAsync(function(){resizeImageToScale(scope.dimensions.scale.current),calculateCropBox(),saveCropBox()})},16);unsubscribe.push(scope.$watch("dimensions.scale.current",function(newValue,oldValue){scope.loaded&&throttledScale()})),scope.maxSize&&(element.css("max-width",parseInt(scope.maxSize,10)+"px"),element.css("max-height",parseInt(scope.maxSize,10)+"px")),$image.on("load",function(){$timeout(function(){!function init(){scope.dimensions.image.originalWidth=$image.width(),scope.dimensions.image.originalHeight=$image.height(),runtimeCrop=Utilities.copy(scope.crop),onViewportSizeChanged(),scope.loaded=!0}()})}),windowResizeListener.register(onViewportSizeChanged),scope.$on("$destroy",function(){$image.prop("src",""),windowResizeListener.unregister(onViewportSizeChanged),unsubscribe.forEach(function(u){return u()})})}}}),function(){var umbImageGravityComponent={template:'<div class="umb-cropper-gravity"> <div class="gravity-container" ng-show="vm.loaded"> <div class="viewport"> <img ng-show="vm.isCroppable" ng-src="{{vm.src}}" draggable="false"> <img ng-show="!vm.isCroppable && !vm.hasDimensions" ng-src="{{vm.src}}" draggable="false" class="cursor-default"> </div> <div class="overlayViewport"> <div ng-show="vm.isCroppable && vm.disableFocalPoint !== true" class="overlay umb-outline" ng-style="vm.overlayStyle" ng-click="vm.setFocalPoint($event)"> <div class="focalPoint" ng-style="vm.style"> </div> </div> </div> </div> </div> ',bindings:{src:"<",center:"<",onImageLoaded:"&?",onValueChanged:"&",disableFocalPoint:"<?"},controllerAs:"vm",controller:function umbImageGravityController($scope,$element,$timeout){var vm=this;vm.dimensions={width:0,height:0,left:0,top:0};var imageElement=null;function updateStyle(){vm.style={top:vm.dimensions.top+"px",left:vm.dimensions.left+"px"},vm.overlayStyle={width:vm.dimensions.width+"px",height:vm.dimensions.height+"px"}}function resized(){$timeout(function(){setDimensions(),updateStyle()})}function onResizeHandler(){$scope.$evalAsync(resized)}function setDimensions(){return vm.isCroppable&&imageElement&&vm.center&&(vm.dimensions.width=imageElement.width(),vm.dimensions.height=imageElement.height(),vm.dimensions.left=vm.center.left*vm.dimensions.width,vm.dimensions.top=vm.center.top*vm.dimensions.height),vm.dimensions.width}function calculateGravity(offsetX,offsetY){vm.onValueChanged({left:Math.min(Math.max(offsetX,0),vm.dimensions.width)/vm.dimensions.width,top:Math.min(Math.max(offsetY,0),vm.dimensions.height)/vm.dimensions.height})}vm.loaded=!1,vm.$onInit=function onInit(){vm.center||(vm.center={left:.5,top:.5})},vm.$onChanges=function onChanges(changes){changes.center&&!changes.center.isFirstChange()&&changes.center.currentValue&&!Utilities.equals(changes.center.currentValue,changes.center.previousValue)&&(setDimensions(),updateStyle())},vm.$postLink=function postLink(){imageElement=$element.find("img"),$element.find(".focalPoint").draggable({containment:"parent",start:function start(){$scope.$emit("imageFocalPointStart")},stop:function stop(event,ui){var offsetX=ui.position.left,offsetY=ui.position.top;$scope.$evalAsync(calculateGravity(offsetX,offsetY)),$scope.$emit("imageFocalPointStop")}}),window.addEventListener("resize.umbImageGravity",onResizeHandler),window.addEventListener("resize",onResizeHandler),$scope.$on("editors.content.splitViewChanged",function(){$timeout(resized,200)}),imageElement.on("load",function(){$timeout(function(){if(vm.isCroppable=!0,vm.hasDimensions=!0,vm.src)if(vm.src.endsWith(".svg"))vm.isCroppable=!1,vm.hasDimensions=!1;else{var type=vm.src.substring(vm.src.indexOf("/")+1,vm.src.indexOf(";base64"));type.startsWith("svg")&&(vm.isCroppable=!1,vm.hasDimensions=!1)}setDimensions(),updateStyle(),vm.loaded=!0,vm.onImageLoaded&&vm.onImageLoaded({isCroppable:vm.isCroppable,hasDimensions:vm.hasDimensions})},100)})},vm.$onDestroy=function onDestroy(){window.removeEventListener("resize.umbImageGravity",onResizeHandler),window.removeEventListener("resize",onResizeHandler),imageElement&&imageElement.off("load")},vm.style={},vm.overlayStyle={},vm.setFocalPoint=function setFocalPoint(event){$scope.$emit("imageFocalPointStart");var viewportPosition=imageElement[0].getBoundingClientRect(),offsetX=event.clientX-viewportPosition.left,offsetY=event.clientY-viewportPosition.top;calculateGravity(offsetX,offsetY),$scope.$emit("imageFocalPointStop")},vm.resetFocalPoint=function resetFocalPoint(){vm.onValueChanged({left:.5,top:.5})}}};angular.module("umbraco.directives").component("umbImageGravity",umbImageGravityComponent)}(),angular.module("umbraco.directives").directive("umbImageThumbnail",function($timeout,localizationService,cropperHelper,$log){return{restrict:"E",replace:!0,template:'<div class="umb-crop-thumbnail-container" ng-style="{height: height, width: width, overflow: \'hidden\', position: \'relative\'}" ng-show="loaded"> <img ng-src="{{src}}" ng-style="preview" class="noScale"> </div> ',scope:{src:"=",width:"@",height:"@",center:"=",crop:"=",maxSize:"@"},link:function link(scope,element,attrs){var $image=element.find("img");function setPreviewStyle(){if(scope.crop&&scope.image)scope.preview=cropperHelper.convertToStyle(scope.crop,scope.image,{width:scope.width,height:scope.height},0);else if(scope.image){var p=cropperHelper.calculateAspectRatioFit(scope.image.width,scope.image.height,scope.width,scope.height,!0);if(scope.center){var xy=cropperHelper.alignToCoordinates(p,scope.center,{width:scope.width,height:scope.height});p.top=xy.top,p.left=xy.left}p.position="absolute",scope.preview=p}}scope.loaded=!1,$image.on("load",function(){$timeout(function(){if($image.width("auto"),$image.height("auto"),scope.image={},scope.image.width=$image[0].width,scope.image.height=$image[0].height,scope.maxSize){var ratioCalculation=cropperHelper.calculateAspectRatioFit(scope.width,scope.height,scope.maxSize,scope.maxSize,!1);scope.width=ratioCalculation.width,scope.height=ratioCalculation.height}setPreviewStyle(),scope.loaded=!0})}),scope.$watchCollection("[crop, center]",function(newValues,oldValues){setPreviewStyle()}),scope.$watch("center",function(){setPreviewStyle()},!0)}}}),angular.module("umbraco.directives").directive("localize",function($log,localizationService){return{restrict:"E",scope:{key:"@",tokens:"=",watchTokens:"@"},replace:!0,link:function link(scope,element,attrs){var key=scope.key;function render(){element.html(localizationService.tokenReplace(scope.text,scope.tokens||null))}scope.text="",localizationService.localize(key).then(function(value){scope.text=value,render()}),"true"===scope.watchTokens&&scope.$watch("tokens",render,!0)}}}).directive("localize",function($log,localizationService){return{restrict:"A",link:function link(scope,element,attrs){var keys=attrs.localize.split(",");Utilities.forEach(keys,function(value,key){var attr=element.attr(value);if(attr){"@"===attr[0]&&(attr=attr.substring(1));var t=localizationService.tokenize(attr,scope);localizationService.localize(t.key,t.tokens).then(function(val){element.attr(value,val)})}})}}}),function(){angular.module("umbraco.directives").directive("umbMediaNodeInfo",function MediaNodeInfoDirective($timeout,$location,$q,eventsService,userService,dateHelper,editorService,mediaHelper,mediaResource){return{restrict:"E",replace:!0,template:'<div class="umb-package-details"> <umb-load-indicator ng-if="loading === true"></umb-load-indicator>  <div class="umb-package-details__main-content" ng-if="loading === false">  <umb-box data-element="node-info-urls" class="mb4"> <umb-box-header title-key="general_links"></umb-box-header> <umb-box-content class="block-form"> <umb-empty-state ng-if="!nodeUrl" size="small"> <localize key="content_noMediaLink"></localize> </umb-empty-state> <ul ng-if="nodeUrl" class="nav nav-stacked mb0"> <li> <a ng-attr-href="{{node.extension !== \'svg\' ? nodeUrl : undefined}}" ng-click="node.extension === \'svg\' && openSVG()" target="_blank" rel="noopener" class="umb-outline"> <umb-icon icon="icon-out" class="icon"></umb-icon> <span>{{nodeFileName}}</span> </a> </li> </ul> </umb-box-content> </umb-box>  <umb-box ng-if="(hasContentReferences === false) && (hasMediaReferences === false) && (hasMemberReferences === false) && loading === false"> <umb-box-header title-key="references_tabName"></umb-box-header> <umb-box-content> <umb-empty-state size="small"> This Media item has no references. </umb-empty-state> </umb-box-content> </umb-box>  <div ng-if="loading === false">  <div ng-if="contentReferences.items.length > 0"> <h5 class="mt0" style="margin-bottom: 20px;"> <localize key="references_labelUsedByDocuments">Used in Documents</localize> </h5> <div class="umb-table"> <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell"></div> <div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div> <div class="umb-table-cell"><localize key="content_alias">Alias</localize></div> <div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div> </div> </div> <div class="umb-table-body"> <div class="umb-table-row" ng-repeat="reference in contentReferences.items"> <div class="umb-table-cell"><umb-icon icon="{{reference.icon}}" class="umb-table-body__icon"></umb-icon></div> <div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div> <div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div> <div class="umb-table-cell umb-table-cell--nano"><a ng-href="#/content/content/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div> </div> </div> </div>  <div class="flex justify-center"> <umb-pagination ng-if="contentReferences.totalPages" page-number="contentReferences.pageNumber" total-pages="contentReferences.totalPages" on-change="changeContentPageNumber(pageNumber)"> </umb-pagination> </div> </div>  <div ng-if="memberReferences.items.length > 0"> <h5 class="mt0" style="margin-bottom: 20px;"> <localize key="references_labelUsedByMembers">Used in Members</localize> </h5> <div class="umb-table"> <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell"></div> <div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div> <div class="umb-table-cell"><localize key="content_alias">Alias</localize></div> <div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div> </div> </div> <div class="umb-table-body"> <div class="umb-table-row" ng-repeat="reference in memberReferences.items"> <div class="umb-table-cell"><umb-icon icon="{{reference.icon}}" class="umb-table-body__icon"></umb-icon></div> <div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div> <div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div> <div class="umb-table-cell umb-table-cell--nano"><a href="#/member/member/edit/{{::reference.key}}"><localize key="general_open">Open</localize></a></div> </div> </div> </div>  <div class="flex justify-center"> <umb-pagination ng-if="memberReferences.totalPages" page-number="memberReferences.pageNumber" total-pages="memberReferences.totalPages" on-change="changeMemberPageNumber(pageNumber)"> </umb-pagination> </div> </div>  <div ng-if="mediaReferences.items.length > 0"> <h5 class="mt0" style="margin-bottom: 20px;"> <localize key="references_labelUsedByMedia">Used in Media</localize> </h5> <div class="umb-table"> <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell"></div> <div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div> <div class="umb-table-cell"><localize key="content_alias">Alias</localize></div> <div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div> </div> </div> <div class="umb-table-body"> <div class="umb-table-row" ng-repeat="reference in mediaReferences.items"> <div class="umb-table-cell"><umb-icon icon="{{reference.icon}}" class="umb-table-body__icon"></umb-icon></div> <div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div> <div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div> <div class="umb-table-cell umb-table-cell--nano"><a href="#/media/media/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div> </div> </div> </div>  <div class="flex justify-center"> <umb-pagination ng-if="mediaReferences.totalPages" page-number="mediaReferences.pageNumber" total-pages="mediaReferences.totalPages" on-change="changeMediaPageNumber(pageNumber)"> </umb-pagination> </div> </div> </div> </div>  <div class="umb-package-details__sidebar" ng-if="loading === false">  <umb-box data-element="node-info-general"> <umb-box-header title-key="general_general"></umb-box-header> <umb-box-content class="block-form"> <umb-control-group ng-if="node.id !== 0" data-element="node-info-create-date" label="@content_createDate"> {{node.createDateFormatted}} by {{ node.owner.name }} </umb-control-group> <umb-control-group ng-if="node.id !== 0" data-element="node-info-update-date" label="@content_updateDate"> {{node.updateDateFormatted}} </umb-control-group> <umb-control-group data-element="node-info-media-type" label="@content_mediatype"> <umb-node-preview style="max-width: 100%; margin-bottom: 0px;" icon="node.icon" name="node.contentTypeName" allow-open="allowChangeMediaType" on-open="openMediaType(mediaType)"> </umb-node-preview> </umb-control-group> <umb-control-group ng-if="node.id !== 0" data-element="node-info-id" label="Id"> <div>{{ node.id }}</div> <small>{{ node.key }}</small> </umb-control-group> </umb-box-content> </umb-box> </div> </div> ',scope:{node:"="},link:function link(scope,element,attrs,ctrl){var evts=[];function formatDatesToLocal(){userService.getCurrentUser().then(function(currentUser){scope.node.createDateFormatted=dateHelper.getLocalDate(scope.node.createDate,currentUser.locale,"LLL"),scope.node.updateDateFormatted=dateHelper.getLocalDate(scope.node.updateDate,currentUser.locale,"LLL")})}function setMediaLink(){scope.nodeUrl=scope.node.mediaLink;var match=/.*\/(.*)/.exec(scope.nodeUrl);scope.nodeFileName=match?match[1]:scope.nodeUrl}function setMediaExtension(){scope.node.extension=mediaHelper.getFileExtension(scope.nodeUrl)}function loadContentRelations(){return mediaResource.getPagedReferences(scope.node.id,scope.contentOptions).then(function(data){scope.contentReferences=data,scope.hasContentReferences=data.items.length>0})}function loadMediaRelations(){return mediaResource.getPagedReferences(scope.node.id,scope.mediaOptions).then(function(data){scope.mediaReferences=data,scope.hasMediaReferences=data.items.length>0})}function loadMemberRelations(){return mediaResource.getPagedReferences(scope.node.id,scope.memberOptions).then(function(data){scope.memberReferences=data,scope.hasMemberReferences=data.items.length>0})}scope.allowChangeMediaType=!1,scope.loading=!0,scope.changeContentPageNumber=function changeContentPageNumber(pageNumber){scope.contentOptions.pageNumber=pageNumber,loadContentRelations()},scope.contentOptions={},scope.contentOptions.entityType="DOCUMENT",scope.hasContentReferences=!1,scope.changeMediaPageNumber=function changeMediaPageNumber(pageNumber){scope.mediaOptions.pageNumber=pageNumber,loadMediaRelations()},scope.mediaOptions={},scope.mediaOptions.entityType="MEDIA",scope.hasMediaReferences=!1,scope.changeMemberPageNumber=function changeMemberPageNumber(pageNumber){scope.memberOptions.pageNumber=pageNumber,loadMemberRelations()},scope.memberOptions={},scope.memberOptions.entityType="MEMBER",scope.hasMemberReferences=!1,scope.openMediaType=function(mediaType){var editor={id:mediaType.id,submit:function submit(model){editorService.close()},close:function close(){editorService.close()}};editorService.mediaTypeEditor(editor)},scope.openSVG=function(){var popup=window.open("","_blank"),html='<!DOCTYPE html><body><img src="'+scope.nodeUrl+'"/><script>history.pushState(null, null,"'+$location.$$absUrl+'");<\/script></body>';popup.document.open(),popup.document.write(html),popup.document.close()},scope.$watch("node.updateDate",function(newValue,oldValue){newValue&&newValue!==oldValue&&(setMediaLink(),formatDatesToLocal(),setMediaExtension())}),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])}),function onInit(){userService.getCurrentUser().then(function(user){Utilities.forEach(user.sections,function(section){"settings"===section.alias&&(scope.allowChangeMediaType=!0)})}),scope.mediaType=scope.node.contentType,setMediaLink(),formatDatesToLocal(),setMediaExtension()}(),evts.push(eventsService.on("app.tabChange",function(event,args){$timeout(function(){"umbInfo"===args.alias&&$q.all([loadContentRelations(),loadMediaRelations(),loadMemberRelations()]).then(function(){scope.loading=!1})})}))}}})}(),function(){angular.module("umbraco.directives").directive("umbMembergroupNodeInfo",function MemberGroupNodeInfoDirective(eventsService,userService,dateHelper){return{restrict:"E",replace:!0,template:'<div class="umb-package-details"> <div class="umb-package-details__main-content"> <umb-box> <umb-box-header title-key="content_membergroup"></umb-box-header> <umb-box-content class="block-form"> <umb-empty-state size="small"> <localize key="member_memberGroupNoProperties">Member groups have no additional properties for editing.</localize> </umb-empty-state> </umb-box-content> </umb-box> </div> <div class="umb-package-details__sidebar"> <umb-box data-element="node-info-general"> <umb-box-header title-key="general_general"></umb-box-header> <umb-box-content class="block-form"> <umb-control-group ng-if="node.id !== 0" data-element="node-info-id" label="Id"> <div>{{ node.id }}</div> <small>{{ node.key }}</small> </umb-control-group> </umb-box-content> </umb-box> </div> </div> ',scope:{node:"="},link:function link(scope,element,attrs,ctrl){var evts=[];function formatDatesToLocal(){userService.getCurrentUser().then(function(currentUser){scope.node.createDateFormatted=dateHelper.getLocalDate(scope.node.createDate,currentUser.locale,"LLL"),scope.node.updateDateFormatted=dateHelper.getLocalDate(scope.node.updateDate,currentUser.locale,"LLL")})}scope.$watch("node.updateDate",function(newValue,oldValue){newValue&&newValue!==oldValue&&formatDatesToLocal()}),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])}),function onInit(){formatDatesToLocal()}()}}})}(),function(){angular.module("umbraco.directives").directive("umbMemberNodeInfo",function MemberNodeInfoDirective($timeout,$location,eventsService,userService,dateHelper,editorService){return{restrict:"E",replace:!0,template:'<div class="umb-package-details"> <div class="umb-package-details__main-content"> <umb-box data-element="node-info-membership" ng-repeat="group in node.tabs| filter: {properties:{view:\'readonlyvalue\'}} track by group.id"> <div class="umb-group-panel__header"> <div>{{ group.label }}</div> </div> <div class="umb-group-panel__content"> <umb-property data-element="property-{{group.alias}}" ng-repeat="property in group.properties | filter: {view:\'readonlyvalue\'} track by property.alias" property="property"> <umb-property-editor model="property"></umb-property-editor> </umb-property> </div> </umb-box> </div> <div class="umb-package-details__sidebar"> <umb-box data-element="node-info-general"> <umb-box-header title-key="general_general"></umb-box-header> <umb-box-content class="block-form"> <umb-control-group ng-if="node.id !== 0" data-element="node-info-create-date" label="@content_createDate"> {{node.createDateFormatted}} by {{ node.owner.name }} </umb-control-group> <umb-control-group ng-if="node.id !== 0" data-element="node-info-update-date" label="@content_updateDate"> {{node.updateDateFormatted}} </umb-control-group> <umb-control-group data-element="node-info-member-type" label="@content_membertype"> <umb-node-preview style="max-width: 100%; margin-bottom: 0px;" icon="node.icon" name="node.contentTypeName" alias="node.contentTypeAlias" allow-open="allowChangeMemberType" on-open="openMemberType(memberType)"> </umb-node-preview> </umb-control-group> <umb-control-group ng-if="node.id !== 0" data-element="node-info-id" label="Id"> <div>{{ node.id }}</div> <small>{{ node.key }}</small> </umb-control-group> </umb-box-content> </umb-box> </div> </div> ',scope:{node:"="},link:function link(scope,element,attrs,ctrl){var evts=[];function formatDatesToLocal(){userService.getCurrentUser().then(function(currentUser){scope.node.createDateFormatted=dateHelper.getLocalDate(scope.node.createDate,currentUser.locale,"LLL"),scope.node.updateDateFormatted=dateHelper.getLocalDate(scope.node.updateDate,currentUser.locale,"LLL")})}scope.allowChangeMemberType=!1,scope.openMemberType=function(memberType){var editor={id:memberType.id,submit:function submit(model){editorService.close()},close:function close(){editorService.close()}};editorService.memberTypeEditor(editor)},scope.$watch("node.updateDate",function(newValue,oldValue){newValue&&newValue!==oldValue&&formatDatesToLocal()}),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])}),function onInit(){userService.getCurrentUser().then(function(user){Utilities.forEach(user.sections,function(section){"settings"===section.alias&&(scope.allowChangeMemberType=!0)})}),scope.memberType=scope.node.contentType,formatDatesToLocal()}()}}})}(),function(){angular.module("umbraco.directives").directive("umbNotifications",function NotificationDirective(notificationsService){return{restrict:"E",replace:!0,template:'<div class="umb-notifications" id="umb-notifications-wrapper" ng-cloak> <ul class="umb-notifications__notifications" aria-live="assertive" aria-relevant="additions"> <li ng-repeat="notification in notifications" class="alert alert-block alert-{{notification.type}} umb-notifications__notification animated -half-second fadeIn" ng-class="{\'-no-border -extra-padding\': notification.type === \'form\'}"> <div ng-if="notification.view"> <div ng-include="notification.view"></div> </div> <div ng-if="notification.headline"> <a ng-if="notification.url" ng-href="{{notification.url}}" target="{{notification.target}}" rel="noreferrer"> <strong ng-bind="notification.headline"></strong> <span ng-bind-html="notification.message"></span> </a> <div ng-if="!notification.url"> <strong ng-bind="notification.headline"></strong> <span ng-bind-html="notification.message"></span> </div> </div> <button type="button" class="close -align-right" ng-click="removeNotification($index)" aria-hidden="true"> <span>&times;</span> </button> </li> </ul> </div> ',link:function link(scope,el,attr,ctrl){scope.notifications=notificationsService.current,scope.$watch("notificationsService.current",function(newVal,oldVal,scope){newVal&&(scope.notifications=newVal)})}}})}(),function(){angular.module("umbraco.directives").directive("umbOverlay",function OverlayDirective($timeout,formHelper,overlayHelper,localizationService,$q,$templateCache,$http,$compile){return{transclude:!0,restrict:"E",replace:!0,template:'<div data-element="{{name}}" class="umb-overlay umb-overlay-{{position}} umb-overlay--{{size}}" on-outside-click="outSideClick()" umb-focus-lock role="dialog" aria-labelledby="umb-overlay-title" aria-describedby="umb-overlay-description"> <ng-form class="umb-overlay__form" name="overlayForm" novalidate val-form-manager> <div data-element="overlay-header" class="umb-overlay-header" ng-show="!model.hideHeader"> <h1 class="umb-overlay__title" id="umb-overlay-title">{{model.title}}</h1> <p class="umb-overlay__subtitle" id="umb-overlay-description" ng-if="model.subtitle">{{model.subtitle}}</p> </div> <div data-element="overlay-content" class="umb-overlay-container form-horizontal"> <ng-transclude></ng-transclude> <div ng-if="view && !parentScope" ng-include="view"></div> <div class="scoped-view"></div> </div>  <div class="umb-overlay__item-details" ng-if="model.itemDetails"> <div class="umb-overlay__item-details-title-wrapper" ng-if="model.itemDetails.icon || model.itemDetails.title"> <umb-icon icon="{{model.itemDetails.icon}}" class="umb-overlay__item-details-icon" ng-if="model.itemDetails.icon"> </umb-icon> <h2 class="umb-overlay__item-details-title" ng-if="model.itemDetails.title">{{model.itemDetails.title}}</h2> </div> <p class="umb-overlay__item-details-description" ng-if="model.itemDetails.description">{{model.itemDetails.description}}</p> </div> <div data-element="overlay-footer" class="umb-overlay-drawer" ng-class="{\'-auto-height\': model.confirmSubmit.show}"> <div ng-if="model.confirmSubmit.show"> <h2 class="red" ng-if="model.confirmSubmit.title"> <umb-icon icon="icon-alert"></umb-icon> {{model.confirmSubmit.title}} </h2> <p ng-if="model.confirmSubmit.description">{{model.confirmSubmit.description}}</p> <label class="checkbox no-indent"> <input type="checkbox" ng-model="directive.enableConfirmButton"> <strong>{{model.confirmSubmit.checkboxLabel}}</strong> </label> <div class="umb-overlay-drawer__align-right"> <umb-button alias="overlayCancelSubmit" action="cancelConfirmSubmit()" button-style="link" label="Cancel" type="button"> </umb-button> <umb-button data-element="overlay-confirm-submit" button-style="success" label="Confirm" type="button" disabled="!directive.enableConfirmButton" action="submitForm(model)" auto-focus="true"> </umb-button> </div> </div> <div class="umb-overlay-drawer__align-right" ng-if="!model.confirmSubmit.show"> <umb-button alias="overlayClose" action="closeOverLay()" button-style="link" label-key="{{model.closeButtonLabelKey}}" label="{{model.closeButtonLabel}}" type="button"> </umb-button> <umb-button alias="overlaySubmit" button-style="{{model.submitButtonStyle || \'success\'}}" label-key="{{model.submitButtonLabelKey}}" label="{{model.submitButtonLabel}}" ng-if="model.submit && model.hideSubmitButton !== true" type="button" disabled="model.disableSubmitButton" action="submitForm(model)" state="model.submitButtonState" auto-focus="true"> </umb-button> </div> </div> </ng-form> </div> ',scope:{ngShow:"=",model:"=",view:"=",position:"@",size:"=?",name:"=?",parentScope:"=?"},link:function link(scope,el,attr,ctrl){scope.directive={enableConfirmButton:!1};var overlayNumber=0,isRegistered=!1,modelCopy={},unsubscribe=[];function unregisterOverlay(){isRegistered&&(overlayHelper.unregisterOverlay(),$(document).off("keydown.overlay-"+overlayNumber),isRegistered=!1)}function setTargetPosition(){var mousePositionClickX,mousePositionClickY,elementHeight,elementWidth,overlay=$(scope.model.event.target).closest(".umb-overlay"),rect=(overlay.length>0?overlay:$("#contentwrapper"))[0].getBoundingClientRect(),containerLeft=rect.left,containerRight=containerLeft+rect.width,containerTop=rect.top,containerBottom=containerTop+rect.height,position={right:"inherit",left:"inherit",top:"inherit",bottom:"inherit"};mousePositionClickX=scope.model.event.pageX,mousePositionClickY=scope.model.event.pageY,elementHeight=el[0].clientHeight,elementWidth=el[0].clientWidth,position.left=mousePositionClickX?mousePositionClickX-elementWidth/2:(containerLeft+containerRight)/2-elementWidth/2,position.top=mousePositionClickY?mousePositionClickY-elementHeight/2:(containerTop+containerBottom)/2-elementHeight/2,position.left+elementWidth>containerRight&&(position.right=10,position.left="inherit"),position.top+elementHeight>containerBottom&&(position.bottom=10,position.top="inherit"),position.left<containerLeft&&(position.left=containerLeft+10,position.right="inherit"),position.top<containerTop&&(position.top=10,position.bottom="inherit"),el.css(position),el.css("visibility","visible")}scope.submitForm=function(model){scope.model.submit&&formHelper.submitForm({scope:scope,skipValidation:scope.model.skipFormValidation,keepServerValidation:!0})&&(scope.model.confirmSubmit&&scope.model.confirmSubmit.enable&&!scope.directive.enableConfirmButton?$q.when(scope.model.submit(model,modelCopy,scope.directive.enableConfirmButton)).then(function(){formHelper.resetForm({scope:scope})}):(unregisterOverlay(),$q.when(scope.model.submit(model,modelCopy,scope.directive.enableConfirmButton)).then(function(){formHelper.resetForm({scope:scope})})))},scope.cancelConfirmSubmit=function(){scope.model.confirmSubmit.show=!1},scope.closeOverLay=function(){unregisterOverlay(),scope.model&&scope.model.close?(scope.model=modelCopy,scope.model.close(scope.model)):(scope.model.show=!1,scope.model=null)},scope.outSideClick=function(){scope.model.disableBackdropClick||scope.closeOverLay()},unsubscribe.push(unregisterOverlay),scope.$on("$destroy",function(){for(var i=0;i<unsubscribe.length;i++)unsubscribe[i]()}),function activate(){!function setView(){if(scope.view){if(-1===scope.view.indexOf(".html")){var viewAlias=scope.view.toLowerCase();scope.view="views/common/overlays/"+viewAlias+"/"+viewAlias+".html"}if(scope.parentScope){var element=el.find(".scoped-view");$http.get(scope.view,{cache:$templateCache}).then(function(response){var templateScope=scope.parentScope.$new();unsubscribe.push(function(){templateScope.$destroy()}),templateScope.model=scope.model,element.html(response.data),element.show(),$compile(element)(templateScope)})}}}(),function setButtonText(){localizationService.localizeMany(["general_close","general_submit"]).then(function(values){scope.model.closeButtonLabelKey||scope.model.closeButtonLabel||(scope.model.closeButtonLabel=values[0]),scope.model.submitButtonLabelKey||scope.model.submitButtonLabel||(scope.model.submitButtonLabel=values[1])})}(),modelCopy=function makeModelCopy(object){var newObject={};for(var key in object)"event"!==key&&"parentScope"!==key&&(newObject[key]=Utilities.copy(object[key]));return newObject}(scope.model),$timeout(function(){if(scope.name||(scope.name="overlay"),"target"===scope.position&&scope.model.event&&(setTargetPosition(),"ResizeObserver"in window)){var resizeObserver=new ResizeObserver(setTargetPosition),contentArea=document.getElementById("contentwrapper");resizeObserver.observe(el[0]),contentArea&&resizeObserver.observe(contentArea),unsubscribe.push(function(){resizeObserver.disconnect()})}!function registerOverlay(){overlayNumber=overlayHelper.registerOverlay(),$(document).on("keydown.overlay-"+overlayNumber,function(event){if(27===event.which&&(overlayHelper.getNumberOfOverlays()!==overlayNumber||scope.model.disableEscKey||scope.$apply(function(){scope.closeOverLay()}),event.stopPropagation(),event.preventDefault()),13===event.which&&overlayHelper.getNumberOfOverlays()===overlayNumber){var activeElementType=document.activeElement.tagName,submitOnEnter=document.activeElement.hasAttribute("overlay-submit-on-enter"),submitOnEnterValue=submitOnEnter?document.activeElement.getAttribute("overlay-submit-on-enter"):"";["A","BUTTON"].indexOf(activeElementType)>=0||("TEXTAREA"!==activeElementType||submitOnEnter)&&(submitOnEnter&&"false"===submitOnEnterValue||(scope.$apply(function(){scope.submitForm(scope.model)}),event.preventDefault()))}}),isRegistered=!0}(),function setOverlayIndent(){var overlayIndex=overlayNumber-1,indentSize=20*overlayIndex,overlayWidth=el[0].clientWidth;if(el.css("width",overlayWidth-indentSize),"center"===scope.position&&overlayIndex>0||"target"===scope.position&&overlayIndex>0){var overlayTopPosition=el[0].offsetTop;el.css("top",overlayTopPosition+indentSize)}}(),function focusOnOverlayHeading(){var heading=el.find(".umb-overlay__title");heading&&heading.focus()}()})}()}}})}(),function(){angular.module("umbraco.directives").directive("umbOverlayBackdrop",function OverlayBackdropDirective(overlayHelper){return{restrict:"E",replace:!0,template:'<div class="umb-overlay-backdrop animate umb-animated" ng-if="numberOfOverlays > 0"></div> ',link:function link(scope,el,attr,ctrl){scope.numberOfOverlays=0,scope.$watch(function(){return overlayHelper.getNumberOfOverlays()},function(newValue){scope.numberOfOverlays=newValue})}}})}(),function(){angular.module("umbraco.directives").component("umbProperty",{template:'<div class="umb-property"> <ng-form name="propertyForm"> <div class="control-group umb-control-group" ng-class="{\'hidelabel\':vm.property.hideLabel, \'--label-on-top\':vm.property.labelOnTop, \'umb-control-group__listview\': vm.property.alias === \'_umb_containerView\'}"> <val-property-msg></val-property-msg> <div class="umb-el-wrap"> <div class="control-header" ng-hide="vm.property.hideLabel === true"> <small ng-if="vm.showInherit" class="db" style="padding-top: 0; margin-bottom: 5px;"> <localize key="contentTypeEditor_inheritedFrom"></localize> {{vm.inheritsFrom}} </small> <label class="control-label" for="{{vm.property.alias}}" ng-attr-title="{{vm.controlLabelTitle}}"> {{vm.property.label}} <span ng-if="vm.property.validation.mandatory || vm.property.ncMandatory"> <strong class="umb-control-required">*</strong> </span> </label> <umb-property-actions ng-if="!vm.showInherit" actions="vm.propertyActions"></umb-property-actions> <small class="control-description" ng-if="vm.property.description" ng-bind-html="vm.property.description | preserveNewLineInHtml"></small> </div> <div class="controls" ng-transclude> </div> </div> </div> </ng-form> </div> ',controller:function UmbPropertyController($scope,userService,serverValidationManager,udiService,angularHelper){var vm=this;vm.$onInit=function onInit(){vm.controlLabelTitle=null,Umbraco.Sys.ServerVariables.isDebuggingEnabled&&userService.getCurrentUser().then(function(u){-1!==u.allowedSections.indexOf("settings")&&(vm.controlLabelTitle=vm.property.alias)});if(!vm.parentUmbProperty){var found=angularHelper.traverseScopeChain($scope,function(s){return s&&s.vm&&"UmbPropertyController"===s.vm.constructor.name});vm.parentUmbProperty=found?found.vm:null}},vm.setDirty=function(){$scope.propertyForm.$setDirty()},vm.setPropertyError=function(errorMsg){vm.property.propertyErrorMessage=errorMsg},vm.propertyActions=[],vm.setPropertyActions=function(actions){vm.propertyActions=actions},vm.getValidationPath=function(){var parentValidationPath=vm.parentUmbProperty?vm.parentUmbProperty.getValidationPath():null,propAlias=vm.propertyAlias?vm.propertyAlias:vm.property.alias,valPath=vm.elementKey?vm.elementKey+"/"+propAlias:propAlias;return serverValidationManager.createPropertyValidationKey(valPath,parentValidationPath)}},controllerAs:"vm",transclude:!0,require:{parentUmbProperty:"?^^umbProperty",parentForm:"?^^form"},bindings:{property:"=",elementKey:"@",propertyAlias:"@",showInherit:"<",inheritsFrom:"<"}})}(),function(){var umbPropertyActionsComponent={template:'<div class="umb-property-actions" ng-class="{ \'-open\': vm.isOpen }" ng-if="vm.actions.length > 0"> <umb-button-ellipsis css-class="umb-outline umb-property-actions__toggle" action="vm.toggle()" mode="small" text="{{vm.isOpen ? vm.labels.closeText : vm.labels.openText}}"> </umb-button-ellipsis> <div class="umb-property-actions__menu" role="menu" ng-if="vm.isOpen" on-outside-click="vm.close()" on-close="vm.close()" deep-blur="vm.close()"> <ul class="umb-contextmenu"> <li ng-repeat="action in vm.actions" role="menuitem" class="umb-contextmenu-item" ng-class="{\'-opens-dialog\': action.opensDialog}"> <button type="button" class="btn-reset umb-outline" ng-click="vm.executeAction(action)" ng-disabled="action.isDisabled === true"> <umb-icon icon="icon-{{action.icon}}" class="icon"></umb-icon> <span class="menu-label"><localize key="{{::action.labelKey}}" tokens="action.labelTokens"></localize></span> </button> </li> </ul> </div> </div> ',bindings:{actions:"<"},controllerAs:"vm",controller:function umbPropertyActionsController(keyboardService,localizationService){var vm=this;function destroyDropDown(){keyboardService.unbind("esc")}vm.isOpen=!1,vm.labels={openText:"Open Property Actions",closeText:"Close Property Actions"},vm.open=function open(){vm.isOpen=!0,function initDropDown(){keyboardService.bind("esc",vm.close)}()},vm.close=function close(){vm.isOpen=!1,destroyDropDown()},vm.toggle=function toggle(){!0===vm.isOpen?vm.close():vm.open()},vm.executeAction=function executeAction(action){action.method(),vm.close()},vm.$onDestroy=function onDestroy(){!0===vm.isOpen&&destroyDropDown()},vm.$onInit=function onInit(){localizationService.localizeMany(["propertyActions_tooltipForPropertyActionsMenu","propertyActions_tooltipForPropertyActionsMenuClose"]).then(function(values){vm.labels.openText=values[0],vm.labels.closeText=values[1]})}}};angular.module("umbraco.directives").component("umbPropertyActions",umbPropertyActionsComponent)}(),angular.module("umbraco.directives").directive("umbPropertyEditor",function umbPropEditor(umbPropEditorHelper){return{scope:{model:"=",isPreValue:"@",preview:"<"},require:["^^form","?^umbProperty"],restrict:"E",replace:!0,template:'<div class="umb-property-editor db" ng-class="{\'umb-property-editor--preview\': preview}"> <div disable-tabindex="preview"> <div ng-include="propertyEditorView"></div> </div> </div> ',link:function link(scope,element,attrs,ctrl){scope[ctrl[0].$name]=ctrl[0],scope.umbProperty=ctrl[1],scope.model.alias||(scope.model.alias=Math.random().toString(36).slice(2));var unbindWatcher=scope.$watch("model.view",function(){scope.propertyEditorView=umbPropEditorHelper.getViewPath(scope.model.view,scope.isPreValue)});scope.$on("$destroy",function(){unbindWatcher()})}}}),angular.module("umbraco.directives.html").directive("umbPropertyGroup",function(){return{transclude:!0,restrict:"E",replace:!0,template:""}}),angular.module("umbraco.directives").component("umbTabContent",{transclude:!0,template:'<div data-element="tab-content-{{vm.tab.alias}}"> <ng-transclude></ng-transclude> </div> ',controllerAs:"vm",bindings:{tab:"<"}}),function(){angular.module("umbraco.directives").directive("umbTabsNav",function TabsNavDirective($timeout,$window,eventsService){return{restrict:"E",transclude:!0,template:'<ul role="tablist" class="umb-tabs-nav"> <li class="umb-tab" ng-repeat="tab in vm.tabs | limitTo: vm.maxTabs" data-element="tab-{{tab.alias}}" ng-class="{\'umb-tab--active\': tab.active, \'umb-tab--error\': valTab_tabHasError}" val-tab> <button class="btn-reset umb-tab-button" ng-click="vm.clickTab($event, tab)" role="tab" aria-selected="{{tab.active}}" type="button"> {{ tab.label }} <div ng-show="valTab_tabHasError && !tab.active" class="badge">!</div> </button> </li> <li data-element="tab-expand" class="umb-tab umb-tab--expand" ng-class="{ \'open\': vm.showTray }" ng-show="vm.needTray"> <umb-button-ellipsis action="vm.toggleTray()" text="View more options" label-key="visuallyHiddenTexts_tabExpand" color="#68676b"> </umb-button-ellipsis> <umb-dropdown class="umb-tabs-tray" ng-if="vm.showTray" on-close="vm.hideTray()"> <umb-dropdown-item ng-repeat="tab in vm.tabs | limitTo: vm.overflowingTabs" ng-class="{\'umb-tab--error\': valTab_tabHasError}" val-tab> <button type="button" class="btn-reset umb-tray-button" ng-class="{\'dropdown-menu--active\': tab.active}" ng-click="vm.clickTab($event, tab)" role="tab" aria-selected="{{tab.active}}"> {{ tab.label }} <div ng-show="valTab_tabHasError && !tab.active" class="badge">!</div> </button> </umb-dropdown-item> </umb-dropdown> </li> </ul> ',link:function link(scope,element,attrs,ctrl){var tabNavItemsWidths=[],container=element.parent().parent(),ro=new ResizeObserver(function(){!function calculateWidth(){$timeout(function(){var containerWidth=container.width()-90,tabsWidth=0;ctrl.overflowingSections=0,ctrl.needTray=!1,ctrl.maxTabs=tabNavItemsWidths.length;for(var i=0;i<=tabNavItemsWidths.length;i++){var tabWidth=tabNavItemsWidths[i];if((tabsWidth+=tabWidth)>=containerWidth){ctrl.needTray=!0,ctrl.maxTabs=i,ctrl.overflowingTabs=ctrl.maxTabs-ctrl.tabs.length;break}}})}()});ro.observe(container[0]),$timeout(function(){element.find("li:not(umb-tab--expand)").each(function(){tabNavItemsWidths.push($(this).outerWidth())})}),scope.$on("$destroy",function(){ro.unobserve(container[0])})},bindToController:!0,controller:function UmbTabsNavController(eventsService){var vm=this;function hideTray(){vm.showTray=!1}vm.needTray=!1,vm.showTray=!1,vm.overflowingSections=0,vm.clickTab=function clickTab($event,tab){if(vm.onTabChange){hideTray();var args={tab:tab,tabs:vm.tabs};eventsService.emit("app.tabChange",args),vm.onTabChange({event:$event,tab:tab})}},vm.toggleTray=function toggleTray(){vm.showTray=!vm.showTray},vm.hideTray=hideTray},controllerAs:"vm",scope:{tabs:"<",onTabChange:"&"}}})}(),function(){angular.module("umbraco.directives").component("umbTagsEditor",{transclude:!0,template:'<div class="umb-tags-editor"> <ng-form name="vm.tagEditorForm"> <div ng-if="vm.isLoading"> <localize key="loading">Loading</localize>... </div> <div ng-if="!isLoading"> <input type="hidden" name="tagCount" ng-model="vm.viewModel.length" val-property-validator="vm.validateMandatory"> <span ng-repeat="tag in vm.viewModel track by $index" class="label label-primary tag" ng-keyup="vm.onKeyUpOnTag(tag, $event)" tabindex="0"> <span ng-bind-html="tag"></span> <umb-icon icon="icon-trash" ng-click="vm.showPrompt($index, tag)" localize="title" title="@buttons_deleteTag"> </umb-icon> <umb-confirm-action ng-if="vm.promptIsVisible === $index" direction="left" on-confirm="vm.removeTag(tag)" on-cancel="vm.hidePrompt()"> </umb-confirm-action> </span> <input type="text" id="{{vm.inputId}}" class="typeahead tags-{{vm.inputId}}" ng-model="vm.tagToAdd" ng-keydown="vm.addTagOnEnter($event)" ng-blur="vm.addTag()" ng-maxlength="200" maxlength="200" localize="placeholder" placeholder="@placeholders_enterTags"> </div> </ng-form> </div> ',controller:function umbTagsEditorController($rootScope,assetsService,umbRequestHelper,angularHelper,$timeout,$element){var typeahead,tagsHound,vm=this;function configureViewModel(isInitLoad){if(vm.value)if(Utilities.isString(vm.value)&&vm.value.length>0)if("Json"===vm.config.storageType)vm.viewModel=JSON.parse(vm.value),isInitLoad||updateModelValue(vm.viewModel);else{var tempArray=vm.value.split(",").map(function(v){return v.trim()});vm.viewModel=tempArray.filter(function(v,i,self){return self.indexOf(v)===i}),isInitLoad||updateModelValue(vm.viewModel)}else Utilities.isArray(vm.value)&&(vm.viewModel=vm.value)}function updateModelValue(val){val=val||[],vm.onValueChanged({value:val}),reValidate()}function addTagInternal(tagToAdd){null!=tagToAdd&&tagToAdd.length>0&&vm.viewModel.indexOf(tagToAdd)<0&&(vm.viewModel.push(tagToAdd),updateModelValue(vm.viewModel))}function addTag(){addTagInternal(vm.tagToAdd),vm.tagToAdd="",typeahead.typeahead("val","")}function removeTag(tag){var i=vm.viewModel.indexOf(tag);i>=0&&(vm.promptIsVisible="-1",vm.viewModel.splice(i,1),updateModelValue(vm.viewModel))}function removeCurrentTagsFromSuggestions(suggestions){return $.grep(suggestions,function(suggestion){return-1===$.inArray(suggestion.text,vm.viewModel)})}function reValidate(){vm.tagEditorForm&&vm.tagEditorForm.tagCount&&vm.tagEditorForm.tagCount.$setViewValue(vm.viewModel.length)}vm.$onInit=function onInit(){vm.inputId=vm.inputId||"t"+String.CreateGuid(),assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js").then(function(){vm.isLoading=!1,configureViewModel(!0),vm.promptIsVisible="-1",(tagsHound=new Bloodhound({initialize:!1,identify:function identify(obj){return obj.id},datumTokenizer:Bloodhound.tokenizers.obj.whitespace("text"),queryTokenizer:Bloodhound.tokenizers.whitespace,prefetch:{url:umbRequestHelper.getApiUrl("tagsDataBaseUrl","GetTags",{tagGroup:vm.config.group,culture:vm.culture}),ttl:3e5},remote:{url:umbRequestHelper.getApiUrl("tagsDataBaseUrl","GetTags",{tagGroup:vm.config.group,culture:vm.culture,query:"%QUERY"}),wildcard:"%QUERY"}})).initialize().then(function(){var sources={name:vm.config.group+(vm.culture?vm.culture:""),display:"text",source:function source(query,syncCallback,asyncCallback){tagsHound.search(query,function(suggestions){syncCallback(removeCurrentTagsFromSuggestions(suggestions))},function(suggestions){asyncCallback(removeCurrentTagsFromSuggestions(suggestions))})}},opts={hint:!0,highlight:!0,cacheKey:new Date,minLength:1};typeahead=$element.find(".tags-"+vm.inputId).typeahead(opts,sources).bind("typeahead:selected",function(obj,datum,name){angularHelper.safeApply($rootScope,function(){addTagInternal(datum.text),vm.tagToAdd="",typeahead.typeahead("val","")})}).bind("typeahead:autocompleted",function(obj,datum,name){angularHelper.safeApply($rootScope,function(){addTagInternal(datum.text),vm.tagToAdd="",typeahead.typeahead("val","")})}).bind("typeahead:opened",function(obj){})})})},vm.$onChanges=function onChanges(changes){changes.value&&(changes.value.isFirstChange()||changes.value.currentValue===changes.value.previousValue||(configureViewModel(),reValidate()))},vm.$onDestroy=function onDestroy(){tagsHound&&(tagsHound.clearPrefetchCache(),tagsHound.clearRemoteCache(),tagsHound=null);$element.find(".tags-"+vm.inputId).typeahead("destroy")},vm.validateMandatory=function validateMandatory(){return{isValid:!vm.validation.mandatory||null!=vm.viewModel&&vm.viewModel.length>0||null!=vm.value&&vm.value.length>0,errorMsg:"Value cannot be empty",errorKey:"required"}},vm.addTagOnEnter=function addTagOnEnter(e){13==(e.keyCode||e.which)&&0===$element.find(".tags-"+vm.inputId).parent().find(".tt-menu .tt-cursor").length&&(e.preventDefault(),addTag())},vm.addTag=addTag,vm.removeTag=removeTag,vm.showPrompt=function showPrompt(idx,tag){var i=vm.viewModel.indexOf(tag);i===idx&&(vm.promptIsVisible=i)},vm.hidePrompt=function hidePrompt(){vm.promptIsVisible="-1"},vm.onKeyUpOnTag=function onKeyUpOnTag(tag,$event){8!==$event.keyCode&&46!==$event.keyCode||removeTag(tag)},vm.isLoading=!0,vm.tagToAdd="",vm.promptIsVisible="-1",vm.viewModel=[]},controllerAs:"vm",bindings:{value:"<",config:"<",validation:"<",culture:"<?",inputId:"@?",onValueChanged:"&"}})}(),function(){angular.module("umbraco.directives").directive("umbContextDialog",function UmbContextDialog(navigationService,keyboardService,localizationService,overlayService,backdropService){return{restrict:"E",transclude:!0,template:'<div id="dialog" class="umb-modalcolumn fill shadow" on-outside-click="outSideClick()" role="dialog" aria-labelledby="contextdialog-title" aria-describedby="contextdialog-description"> <div class="umb-modalcolumn-header"> <h1 id="contextdialog-title">{{dialogTitle}}</h1> <p id="contextdialog-description" class="sr-only"> <localize key="visuallyHiddenTexts_contextDialogDescription" tokens="[dialogTitle,currentNode.name]">Perform action {{dialogTitle}} on the {{currentNode.name}} node</localize> </p> </div> <div class="umb-modalcolumn-body" ng-include="view"></div> </div> ',scope:{dialogTitle:"<",currentNode:"<",view:"<"},link:function link($scope){function hide(){$scope.dialog.confirmDiscardChanges?localizationService.localizeMany(["prompt_unsavedChanges","prompt_unsavedChangesWarning","prompt_discardChanges","prompt_stay"]).then(function(values){var overlay={view:"default",title:values[0],content:values[1],disableBackdropClick:!0,disableEscKey:!0,submitButtonLabel:values[2],closeButtonLabel:values[3],submit:function submit(){overlayService.close(),navigationService.hideDialog()},close:function close(){overlayService.close()}};overlayService.open(overlay)}):navigationService.hideDialog()}$scope.dialog={confirmDiscardChanges:!1},$scope.outSideClick=function(){hide()},keyboardService.bind("esc",function(){hide()}),$scope.$on("$destroy",function(){keyboardService.unbind("esc")})}}})}(),angular.module("umbraco.directives").directive("umbTree",function umbTreeDirective($q,treeService,notificationsService){return{restrict:"E",replace:!0,terminal:!1,template:'<ul class="umb-tree" ng-class="{\'hide-options\': hideoptions === \'true\'}"> <li ng-if="!tree.root.containsGroups"> <div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(tree.root)" ng-if="hideheader !== \'true\'" on-right-click="altSelect(tree.root, $event)"> <h5> <a ng-href="#/{{section}}" ng-click="select(tree.root, $event)" class="umb-tree-root-link umb-outline" data-element="tree-root-link"> <umb-icon icon="icon-check" class="umb-tree-icon" ng-class="selectEnabledNodeClass(tree.root)" ng-if="enablecheckboxes === \'true\'"> </umb-icon> {{tree.name}} </a> </h5> <umb-button-ellipsis element="tree-item-options" action="options(tree.root, $event)" text="Open context node for {{tree.name}}" state="hidden" class="umb-options" ng-hide="tree.root.isContainer || !tree.root.menuUrl" ng-swipe-right="options(tree.root, $event)"> </umb-button-ellipsis> </div> <ul ng-if="tree.root.children.length > 0"> <umb-tree-item class="umb-animated" ng-repeat="child in tree.root.children" enablelistviewexpand="{{enablelistviewexpand}}" node="child" current-node="currentNode" tree="this" is-dialog="isdialog" section="{{section}}"> </umb-tree-item> </ul> </li>  <li ng-if="tree.root.containsGroups" ng-repeat="group in tree.root.children"> <div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(group)" ng-hide="hideheader === \'true\'" on-right-click="altSelect(group, $event)"> <h5> <a ng-href="#/{{section}}" ng-click="select(group, $event)" class="umb-tree-root-link umb-outline" data-element="tree-root-link"> <umb-icon icon="icon-check" class="umb-tree-icon" ng-class="selectEnabledNodeClass(group)" ng-if="enablecheckboxes === \'true\'"> </umb-icon> {{group.name}} </a> </h5> <umb-button-ellipsis element="tree-item-options" action="options(group, $event)" text="Open context node for {{group.name}}" state="hidden" class="umb-options" ng-hide="group.isContainer || !group.menuUrl" ng-swipe-right="options(group, $event)"> </umb-button-ellipsis> </div> <ul ng-if="group.children.length > 0"> <umb-tree-item class="umb-animated" ng-repeat="child in group.children" enablelistviewexpand="{{enablelistviewexpand}}" node="child" current-node="currentNode" tree="this" is-dialog="isdialog" section="{{section}}"> </umb-tree-item> </ul> </li>  </ul> ',scope:{section:"@",treealias:"@",hideoptions:"@",hideheader:"@",cachekey:"@",isdialog:"@",onlyInitialized:"@",customtreeparams:"@",enablecheckboxes:"@",enablelistviewsearch:"@",enablelistviewexpand:"@",api:"=?",onInit:"&?"},controller:function controller($scope,$element){var vm=this,registeredCallbacks={treeNodeExpanded:[],treeNodeSelect:[],treeLoaded:[],treeSynced:[],treeOptionsClick:[],treeNodeAltSelect:[]};function emitEvent(eventName,args){registeredCallbacks[eventName]&&Utilities.isArray(registeredCallbacks[eventName])&&registeredCallbacks[eventName].forEach(function(c){return c(args)})}function getTreeRootNodes(){var roots;return roots=$scope.tree.root.containsGroups?_.reduce(_.map($scope.tree.root.children,function(n){return n.children}),function(m,p){return m.concat(p)}):[$scope.tree.root].concat($scope.tree.root.children),_.filter(roots,function(node){return node&&node.metaData&&node.metaData.treeAlias})}function loadTree(){if($scope.section){var args={section:$scope.section,tree:$scope.treealias,cacheKey:$scope.cachekey,isDialog:!!$scope.isdialog&&$scope.isdialog};return $scope.customtreeparams&&(args.queryString=$scope.customtreeparams),treeService.getTree(args).then(function(data){return data.alias!==$scope.section?$q.reject():($scope.tree=data,$scope.activeTree=$scope.tree.root,emitEvent("treeLoaded",{tree:$scope.tree}),emitEvent("treeNodeExpanded",{tree:$scope.tree,node:$scope.tree.root,children:$scope.tree.root.children}),$q.when(data))},function(reason){return notificationsService.error("Tree Error",reason),$q.reject(reason)})}return $q.reject()}function loadChildren(node,forceReload){return emitEvent("treeNodeExpanding",{tree:$scope.tree,node:node}),node.children||(node.children=[]),forceReload||node.hasChildren&&0===node.children.length?treeService.loadNodeChildren({node:node,section:$scope.section,isDialog:$scope.isdialog}).then(function(data){return emitEvent("treeNodeExpanded",{tree:$scope.tree,node:node,children:data}),$q.when(data)}):(emitEvent("treeNodeExpanded",{tree:$scope.tree,node:node,children:node.children}),node.expanded=!0,$q.when(node.children))}vm.callbacks={treeNodeExpanded:function treeNodeExpanded(f){registeredCallbacks.treeNodeExpanded.push(f)},treeNodeSelect:function treeNodeSelect(f){registeredCallbacks.treeNodeSelect.push(f)},treeLoaded:function treeLoaded(f){registeredCallbacks.treeLoaded.push(f)},treeSynced:function treeSynced(f){registeredCallbacks.treeSynced.push(f)},treeOptionsClick:function treeOptionsClick(f){registeredCallbacks.treeOptionsClick.push(f)},treeNodeAltSelect:function treeNodeAltSelect(f){registeredCallbacks.treeNodeAltSelect.push(f)}},vm.emitEvent=emitEvent,vm.load=function load(args){return Utilities.isString(args)?$scope.section=args:args&&(args.section&&($scope.section=args.section),args.customTreeParams&&($scope.customtreeparams=args.customTreeParams),args.treeAlias&&($scope.treealias=args.treeAlias),args.cacheKey&&($scope.cachekey=args.cacheKey)),loadTree()},vm.reloadNode=function reloadNode(node){return node||(node=$scope.currentNode),node?$scope.loadChildren(node,!0):$q.reject()},vm.syncTree=function syncTree(args){if(!args)throw"args cannot be null";if(!args.path)throw"args.path cannot be null";Utilities.isString(args.path)&&(args.path=args.path.replace('"',"").split(",")),args.path=_.filter(args.path,function(item){return"init"!==item&&"-1"!==item});var treeNode=function loadActiveTree(treeAlias){if(!$scope.tree)throw"Err in umbtree.directive.loadActiveTree, $scope.tree is null";if(!treeAlias){if(!$scope.activeTree)throw"Err in umbtree.directive.loadActiveTree, $scope.activeTree is null";return $scope.activeTree}var treeRoots=getTreeRootNodes();if($scope.activeTree=_.find(treeRoots,function(node){return node.metaData.treeAlias.toUpperCase()===treeAlias.toUpperCase()}),!$scope.activeTree)throw"Could not find the tree "+treeAlias;return emitEvent("activeTreeLoaded",{tree:$scope.activeTree}),$scope.activeTree}(args.tree);return treeService.syncTree({node:treeNode,path:args.path,forceReload:args.forceReload}).then(function(data){return void 0!==args.activate&&!0!==args.activate||($scope.currentNode=data),emitEvent("treeSynced",{node:data,activate:args.activate}),$q.when({node:data,activate:args.activate})},function(data){return $q.reject(data)},function(data){"treeNodeExpanded"===data.type&&emitEvent("treeNodeExpanded",{tree:$scope.tree,node:data.node,children:data.children})})},vm.loadChildren=loadChildren,vm.hasTree=function hasTree(treeAlias){if(!$scope.tree)throw"Err in umbtree.directive.loadActiveTree, $scope.tree is null";if(!treeAlias)return!1;var treeRoots=getTreeRootNodes();return void 0!==_.find(treeRoots,function(node){return node.metaData.treeAlias.toUpperCase()===treeAlias.toUpperCase()})},$scope.api&&($scope.api.callbacks=vm.callbacks,$scope.api.load=vm.load,$scope.api.reloadNode=vm.reloadNode,$scope.api.syncTree=vm.syncTree,$scope.api.hasTree=vm.hasTree),$scope.getNodeCssClass=function(node){if(!node)return"";var css=[];return node.cssClasses&&node.cssClasses.forEach(function(c){return css.push(c)}),css.join(" ")},$scope.selectEnabledNodeClass=function(node){return node&&node.selected?"icon sprTree icon-check green temporary":"-hidden"},$scope.loadChildren=function(node,forceReload){return loadChildren(node,forceReload)},$scope.options=function(n,ev){emitEvent("treeOptionsClick",{element:$element,node:n,event:ev})},$scope.select=function(n,ev){n.metaData&&!0===n.metaData.noAccess?ev.preventDefault():($scope.currentNode=null,emitEvent("treeNodeSelect",{element:$element,node:n,event:ev}))},$scope.altSelect=function(n,ev){emitEvent("treeNodeAltSelect",{element:$element,tree:$scope.tree,node:n,event:ev})},$q.when($scope.onInit(),function(args){args&&(args.section&&($scope.section=args.section),args.cacheKey&&($scope.cachekey=args.cacheKey),args.customTreeParams&&($scope.customtreeparams=args.customTreeParams)),loadTree().then(function(){args&&args.onLoaded&&Utilities.isFunction(args.onLoaded)&&args.onLoaded()})})}}}),angular.module("umbraco.directives").directive("umbTreeItem",function(treeService,$timeout,localizationService,eventsService,appState,navigationService){return{restrict:"E",replace:!0,require:"^umbTree",template:'<li class="umb-tree-item" data-element="tree-item-{{::node.dataElement}}" ng-class="getNodeCssClass(node)" on-right-click="altSelect(node, $event)"> <div class="umb-tree-item__inner" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" tabindex="-1"> <button data-element="tree-item-expand" class="umb-tree-item__arrow umb-outline btn-reset" ng-style="{\'visibility\': (scope.enablelistviewexpand === \'true\' || node.hasChildren && (!node.metaData.isContainer || isDialog)) ? \'visible\' : \'hidden\'}" ng-click="load(node)"> <umb-icon icon="{{(node.expanded && !node.metaData.isContainer) ? \'icon-navigation-down\' : \'icon-navigation-right\'}}"></umb-icon>  <span class="sr-only">Expand child items for {{node.name}}</span> </button> <umb-icon icon="{{node.selected ? \'icon-check\' : node.icon}}" class="icon umb-tree-icon sprTree" ng-class="node.cssClass" title="{{::node.title}}" ng-click="select(node, $event)" ng-style="::node.style" tabindex="-1"></umb-icon> <span class="umb-tree-item__annotation"></span> <a class="umb-tree-item__label" ng-href="#/{{::node.routePath}}" ng-click="select(node, $event)" title="{{::node.title}}">{{node.name}}</a>  <umb-button-ellipsis ng-if="::node.menuUrl" element="tree-item-options" action="options(node, $event)" text="{{optionsText}} {{node.name}}" state="hidden" class="umb-options"> </umb-button-ellipsis> <umb-loader ng-show="node.loading" position="bottom" class="umb-tree-item__loader"></umb-loader> </div> <ul ng-class="{collapsed: !node.expanded}"> <umb-tree-item class="umb-animated" ng-repeat="child in node.children track by child.id" enablelistviewexpand="{{enablelistviewexpand}}" tree="tree" current-node="currentNode" node="child" is-dialog="isDialog" section="{{section}}"></umb-tree-item> </ul> </li> ',scope:{section:"@",currentNode:"=",enablelistviewexpand:"@",node:"=",tree:"=",isDialog:"="},link:function link(scope,element,attrs,umbTreeCtrl){function setupNodeDom(node,tree){element.children(":first").css("padding-left",20*node.level+"px"),node.metaData.treeAlias?node.dataElement=node.metaData.treeAlias:node.dataElement=node.name}localizationService.localizeMany(["general_search","visuallyHiddenTexts_openContextMenu"]).then(function(value){scope.searchAltText=value[0],scope.optionsText=value[1]}),scope.getNodeCssClass=function(node){if(!node)return"";var actionNode=appState.getMenuState("currentNode"),css=[];return node.cssClasses&&node.cssClasses.forEach(function(c){return css.push(c)}),node.selected&&css.push("umb-tree-node-checked"),node==scope.currentNode&&(css.push("current"),actionNode&&actionNode.id!==node.id&&css.push("current-not-active")),node.hasChildren&&css.push("has-children"),node.deleteAnimations&&css.push("umb-tree-item--deleted"),actionNode&&actionNode.nodeType===node.nodeType&&(actionNode.id===node.id&&"-1"!==String(node.id)&&css.push("active"),"-1"===String(node.id)&&actionNode.metaData.treeAlias===node.metaData.treeAlias&&css.push("active")),css.join(" ")},scope.node.updateNodeData=function(newNode){_.extend(scope.node,newNode),setupNodeDom(scope.node,scope.tree)},scope.options=function(n,ev){umbTreeCtrl.emitEvent("treeOptionsClick",{element:element,tree:scope.tree,node:n,event:ev})},scope.select=function(n,ev){ev.ctrlKey||ev.shiftKey||ev.metaKey||ev.button&&1===ev.button||(n.metaData&&!0===n.metaData.noAccess?ev.preventDefault():(umbTreeCtrl.emitEvent("treeNodeSelect",{element:element,tree:scope.tree,node:n,event:ev}),ev.preventDefault()))},scope.altSelect=function(n,ev){if(ev.altKey)return!1;umbTreeCtrl.emitEvent("treeNodeAltSelect",{element:element,tree:scope.tree,node:n,event:ev})},scope.load=function(node){node.expanded&&!node.metaData.isContainer?(umbTreeCtrl.emitEvent("treeNodeCollapsing",{tree:scope.tree,node:node,element:element}),node.expanded=!1):scope.loadChildren(node,!1)},scope.loadChildren=function(node,forceReload){return umbTreeCtrl.loadChildren(node,forceReload)},setupNodeDom(scope.node,scope.tree),scope.node.hasChildren&&scope.node.metaData.noAccess&&scope.loadChildren(scope.node);var evts=[];evts.push(eventsService.on("appState.sectionState.changed",function(e,args){"currentSection"===args.key&&(scope.node.deleteAnimations=!1)})),evts.push(eventsService.on("editors.tree.icon.changed",function(e,args){args.icon!==scope.node.icon&&args.id===scope.node.id&&(scope.node.icon=args.icon)})),evts.push(eventsService.on("appState.menuState.changed",function(e,args){"showMenuDialog"!==args.key&&"showMenu"!=args.key&&"currentNode"!=args.key||function toggleDeleteAnimations(){if(appState.getMenuState("showMenuDialog")||appState.getMenuState("showMenu")){var currentNode=appState.getMenuState("currentNode");currentNode&&currentNode.id==scope.node.id?scope.node.deleteAnimations=!0:scope.node.deleteAnimations=!1}else scope.node.deleteAnimations=!1}()})),scope.$on("$destroy",function(){for(var e in evts)eventsService.unsubscribe(evts[e])})}}}),angular.module("umbraco.directives").directive("umbTreeSearchBox",function treeSearchBox($q,searchService){return{scope:{searchFromId:"@",searchFromName:"@",showSearch:"@",section:"@",datatypeKey:"@",hideSearchCallback:"=",searchCallback:"=",inputId:"@",autoFocus:"="},restrict:"E",replace:!0,template:'<div class="form-search"> <umb-search-filter input-id="{{inputId}}" model="term" label-key="general_typeToSearch" text="Type to search..." css-class="w-100" auto-focus="autoFocus" show-back-button="showSearch" on-back="hideSearch()"> </umb-search-filter> <h4 ng-if="showSearch && searchFromName"> <small><localize key="general_search">Search</localize>:&nbsp;</small> {{searchFromName}} </h4> </div> ',link:function link(scope,element,attrs,ctrl){scope.term="",scope.hideSearch=function(){scope.term="",scope.hideSearchCallback()},scope.showSearch||(scope.showSearch="false");var canceler=null;scope.$watch("term",_.debounce(function(newVal,oldVal){scope.$apply(function(){null!=newVal&&newVal!==oldVal&&function performSearch(){if(scope.term){scope.results=[],canceler?(canceler.resolve(),canceler=$q.defer()):canceler=$q.defer();var searchArgs={term:scope.term,canceler:canceler};scope.searchFromId&&(searchArgs.searchFrom=scope.searchFromId),scope.datatypeKey&&(searchArgs.dataTypeKey=scope.datatypeKey),searcher(searchArgs).then(function(data){scope.searchCallback(data),canceler=null})}else scope.hideSearch()}()})},200));var searcher=searchService.searchContent;"member"===scope.section?searcher=searchService.searchMembers:"media"===scope.section&&(searcher=searchService.searchMedia)}}}),angular.module("umbraco.directives").directive("umbTreeSearchResults",function treeSearchResults(){return{scope:{results:"=",selectResultCallback:"=",emptySearchResultPosition:"@"},restrict:"E",replace:!0,template:'<div> <umb-empty-state ng-if="results.length === 0" position="{{emptySearchResultPosition}}"> <p role="alert"><localize key="general_searchNoResult">Sorry, we can not find what you are looking for.</localize></p> </umb-empty-state> <p ng-if="results.length === 1" role="alert">1 <localize key="treeSearch_searchResult">item returned</localize></p> <p ng-if="results.length > 1" role="alert">{{results.length}} <localize key="treeSearch_searchResults">items returned</localize></p> <ul class="umb-tree"> <li class="root"> <ul class="umb-search-group"> <li class="umb-search-group-item" ng-repeat="result in results"> <div ng-class="{ \'umb-tree-node-checked\': result.selected }"> <button type="button" class="btn-reset umb-search-group-item-link" ng-class="{ first: $first }" ng-click="selectResultCallback($event, result)"> <span class="umb-search-group-item-name"> <umb-icon icon="{{result.selected ? \'icon-check\' : result.icon}}" class="icon umb-tree-icon sprTree"></umb-icon> <span class="umb-search-group-item-name__text">{{ result.name }}</span> </span> <small class="search-subtitle" ng-if="result.subTitle">{{ result.subTitle }}</small> </button> </div> </li> </ul> </li> </ul> </div> ',link:function link(scope,element,attrs,ctrl){scope.emptySearchResultPosition=scope.emptySearchResultPosition||"center"}}}),function(){angular.module("umbraco.directives").constant("umbAceEditorConfig",{}).directive("umbAceEditor",function AceEditorDirective(umbAceEditorConfig,assetsService,angularHelper){var setOptions=function setOptions(acee,session,opts){var key,obj;if(Utilities.isDefined(opts.workerPath)&&window.ace.require("ace/config").set("workerPath",opts.workerPath),Utilities.isDefined(opts.require)&&opts.require.forEach(function(n){window.ace.require(n)}),Utilities.isDefined(opts.showGutter)&&acee.renderer.setShowGutter(opts.showGutter),Utilities.isDefined(opts.useWrapMode)&&session.setUseWrapMode(opts.useWrapMode),Utilities.isDefined(opts.showInvisibles)&&acee.renderer.setShowInvisibles(opts.showInvisibles),Utilities.isDefined(opts.showIndentGuides)&&acee.renderer.setDisplayIndentGuides(opts.showIndentGuides),Utilities.isDefined(opts.useSoftTabs)&&session.setUseSoftTabs(opts.useSoftTabs),Utilities.isDefined(opts.showPrintMargin)&&acee.setShowPrintMargin(opts.showPrintMargin),Utilities.isDefined(opts.disableSearch)&&opts.disableSearch&&acee.commands.addCommands([{name:"unfind",bindKey:{win:"Ctrl-F",mac:"Command-F"},exec:function exec(){return!1},readOnly:!0}]),Utilities.isString(opts.theme)&&acee.setTheme("ace/theme/"+opts.theme),Utilities.isString(opts.mode)&&session.setMode("ace/mode/"+opts.mode),Utilities.isDefined(opts.firstLineNumber)&&(Utilities.isNumber(opts.firstLineNumber)?session.setOption("firstLineNumber",opts.firstLineNumber):Utilities.isFunction(opts.firstLineNumber)&&session.setOption("firstLineNumber",opts.firstLineNumber())),Utilities.isDefined(opts.advanced))for(key in opts.advanced)obj={name:key,value:opts.advanced[key]},acee.setOption(obj.name,obj.value);if(Utilities.isDefined(opts.rendererOptions))for(key in opts.rendererOptions)obj={name:key,value:opts.rendererOptions[key]},acee.renderer.setOption(obj.name,obj.value);Utilities.forEach(opts.callbacks,function(cb){Utilities.isFunction(cb)&&cb(acee)})};return{restrict:"EA",scope:{umbAceEditor:"=",model:"="},link:function link(scope,el,attr,ngModel){assetsService.load(["lib/ace-builds/src-min-noconflict/ace.js","lib/ace-builds/src-min-noconflict/ext-language_tools.js"],scope).then(function(){if(Utilities.isUndefined(window.ace))throw new Error("ui-ace need ace to work... (o rly?)");!function init(){var options=umbAceEditorConfig.ace||{},opts=Utilities.extend({},options,scope.umbAceEditor),acee=window.ace.edit(el[0]);acee.$blockScrolling=1/0;var onChangeListener,onBlurListener,session=acee.getSession(),executeUserCallback=function executeUserCallback(){var callback=arguments[0],args=Array.prototype.slice.call(arguments,1);Utilities.isDefined(callback)&&scope.$evalAsync(function(){if(!Utilities.isFunction(callback))throw new Error("ui-ace use a function as callback.");callback(args)})},listenerFactory={onChange:function onChange(callback){return function(e){var newValue=session.getValue();angularHelper.safeApply(scope,function(){scope.model=newValue}),executeUserCallback(callback,e,acee)}},onBlur:function onBlur(callback){return function(){executeUserCallback(callback,acee)}}};attr.$observe("readonly",function(value){acee.setReadOnly(!!value||""===value)}),scope.model&&session.setValue(scope.model);var updateOptions=function updateOptions(current,previous){current!==previous&&((opts=Utilities.extend({},options,scope.umbAceEditor)).callbacks=[opts.onLoad],opts.onLoad!==options.onLoad&&opts.callbacks.unshift(options.onLoad),!0===opts.autoFocus&&acee.focus(),session.removeListener("change",onChangeListener),onChangeListener=listenerFactory.onChange(opts.onChange),session.on("change",onChangeListener),acee.removeListener("blur",onBlurListener),onBlurListener=listenerFactory.onBlur(opts.onBlur),acee.on("blur",onBlurListener),setOptions(acee,session,opts))};scope.$watch(scope.umbAceEditor,updateOptions,!0),updateOptions(options),el.on("$destroy",function(){acee.session.$stopWorker(),acee.destroy()}),scope.$watch(function(){return[el[0].offsetWidth,el[0].offsetHeight]},function(){acee.resize(),acee.renderer.updateFull()},!0)}()})}}})}(),function(){angular.module("umbraco.directives").directive("umbAvatar",function AvatarDirective(localizationService){return{restrict:"E",replace:!0,template:'<div> <img class="umb-avatar umb-avatar--{{size}}" ng-if="imgSrc" ng-src="{{imgSrc}}" ng-srcset="{{imgSrcset}}" alt="{{avatarAlt}}"> <div class="umb-avatar umb-avatar--{{size}} umb-avatar--{{color}}" ng-if="!imgSrc"> <span ng-if="name">{{ initials }}</span> <span ng-if="!name">{{unknownChar}}</span> </div> </div> ',scope:{size:"@",name:"@",color:"@",imgSrc:"@",imgSrcset:"@",unknownChar:"@"},link:function link(scope,element,attrs,ctrl){function getNameInitials(name){if(name){var names=name.split(" "),initials=names[0].substring(0,1);return names.length>1&&(initials+=names[names.length-1].substring(0,1)),initials.toUpperCase()}return null}function setAvatarAlt(name){name&&localizationService.localize("general_avatar").then(function(data){scope.avatarAlt=data+" "+name}),scope.avatarAlt=null}scope.initials="",scope.avatarAlt="",[].push(scope.$watch("name",function(newValue,oldValue){newValue!==oldValue&&void 0!==oldValue&&void 0!==newValue&&(scope.initials=getNameInitials(newValue),setAvatarAlt(newValue))})),function onInit(){scope.unknownChar||(scope.unknownChar="?"),scope.initials=getNameInitials(scope.name),setAvatarAlt(scope.name)}()}}})}(),function(){angular.module("umbraco.directives").directive("umbBadge",function BadgeDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<span class="umb-badge umb-badge--{{color}} umb-badge--{{size}}" ng-transclude></span>',scope:{size:"@?",color:"@?"}}})}(),function(){angular.module("umbraco.directives").directive("umbCheckmark",function CheckmarkDirective(){return{restrict:"E",replace:!0,transclude:!0,template:'<div class="umb-checkmark umb-checkmark--{{size}} umb-outline" ng-class="{\'umb-checkmark--checked\': checked, \'cursor-auto\': readonly}"> <umb-icon icon="icon-check"></umb-icon> </div> ',scope:{size:"@?",checked:"=",readonly:"@?"}}})}(),function(){angular.module("umbraco.directives").directive("umbChildSelector",function ChildSelectorDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-child-selector"> <div class="umb-child-selector__child -parent"> <div class="umb-child-selector__child-description"> <div class="umb-child-selector__child-icon-holder"> <umb-icon icon="{{parentIcon}}" class="umb-child-selector__child-icon"></umb-icon> </div> <span class="umb-child-selector__child-name"> <strong>{{parentName}}</strong> </span> <small> (<localize key="general_current"></localize>) </small> </div> </div> <div class="umb-child-selector__children-container" ui-sortable="sortableOptions" ng-model="selectedChildren"> <div class="umb-child-selector__child" ng-repeat="selectedChild in selectedChildren"> <div class="umb-child-selector__child-description"> <div class="umb-child-selector__child-icon-holder"> <umb-icon icon="{{selectedChild.icon}}" class="umb-child-selector__child-icon"></umb-icon> </div> <span class="umb-child-selector__child-name">{{selectedChild.name}}</span> </div> <div class="umb-child-selector__child-actions"> <button type="button" class="umb-child-selector__child-remove" ng-click="removeChild(selectedChild, $index)"> <umb-icon icon="icon-trash"></umb-icon> </button> </div> </div> <button type="button" class="umb-child-selector__child -placeholder unsortable" ng-click="addChild($event)" hotkey="alt+shift+c"> <div class="umb-child-selector__child-name -blue"><strong><localize key="shortcuts_addChild">Add Child</localize></strong></div> </button> </div> </div> ',scope:{selectedChildren:"=",availableChildren:"=",parentName:"=",parentIcon:"=",parentId:"=",onRemove:"=",onAdd:"=",onSort:"="},link:function link(scope,el,attr,ctrl){var eventBindings=[];scope.dialogModel={},scope.showDialog=!1,scope.removeChild=function(selectedChild,$index){scope.onRemove&&scope.onRemove(selectedChild,$index)},scope.addChild=function($event){scope.onAdd&&scope.onAdd($event)},eventBindings.push(scope.$watch("parentName",function(newValue,oldValue){newValue!==oldValue&&void 0!==oldValue&&void 0!==newValue&&function syncParentName(){Utilities.forEach(scope.availableChildren,function(availableChild){availableChild.id===scope.parentId&&(availableChild.name=scope.parentName)}),Utilities.forEach(scope.selectedChildren,function(selectedChild){selectedChild.id===scope.parentId&&(selectedChild.name=scope.parentName)})}()})),eventBindings.push(scope.$watch("parentIcon",function(newValue,oldValue){newValue!==oldValue&&void 0!==oldValue&&void 0!==newValue&&function syncParentIcon(){Utilities.forEach(scope.availableChildren,function(availableChild){availableChild.id===scope.parentId&&(availableChild.icon=scope.parentIcon)}),Utilities.forEach(scope.selectedChildren,function(selectedChild){selectedChild.id===scope.parentId&&(selectedChild.icon=scope.parentIcon)})}()})),scope.sortableOptions={axis:"y",cancel:".unsortable",containment:"parent",distance:10,opacity:.7,tolerance:"pointer",scroll:!0,zIndex:6e3,update:function update(e,ui){scope.onSort&&scope.onSort()}},scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]()})}}})}(),function(){angular.module("umbraco.directives").directive("umbClipboard",function umbClipboardDirective($timeout,assetsService,$parse){return{restrict:"A",link:function link(scope,element,attrs,ctrl){var clipboard,target=element[0];assetsService.loadJs("lib/clipboard/clipboard.min.js",scope).then(function(){attrs.umbClipboardTarget&&target.setAttribute("data-clipboard-target",attrs.umbClipboardTarget),attrs.umbClipboardAction&&target.setAttribute("data-clipboard-action",attrs.umbClipboardAction),attrs.umbClipboardText&&target.setAttribute("data-clipboard-text",attrs.umbClipboardText),clipboard=new ClipboardJS(target);var expressionHandlerSuccess=$parse(attrs.umbClipboardSuccess);clipboard.on("success",function(e){e.clearSelection(),attrs.umbClipboardSuccess&&expressionHandlerSuccess(scope,{msg:"success"})});var expressionHandlerError=$parse(attrs.umbClipboardError);clipboard.on("error",function(e){attrs.umbClipboardError&&expressionHandlerError(scope,{msg:"error"})})}),scope.$on("$destroy",function(){clipboard.destroy()})}}})}(),function(){var umbCodeSnippet={template:' <div class="umb-code-snippet"> <div class="umb-code-snippet__header"> <span class="language" ng-if="vm.language">{{vm.language}}</span> <umb-button umb-clipboard umb-clipboard-success="vm.copySuccess()" umb-clipboard-error="vm.copyError()" umb-clipboard-target="#umbCodeSnippet_{{vm.guid}}" state="vm.page.copyCodeButtonState" icon="icon-documents" type="button" size="s" label="Copy" label-key="general_copy"> </umb-button> </div> <div class="umb-code-snippet__content"> <pre id="umbCodeSnippet_{{vm.guid}}">\r\n            <code ng-transclude></code>\r\n        </pre> </div> </div> ',controller:function UmbCodeSnippetController($timeout){var vm=this;function resetClipboardButtonState(){vm.page.copyCodeButtonState="init"}vm.page={},vm.$onInit=function onInit(){if(vm.guid=String.CreateGuid(),vm.language)switch(vm.language.toLowerCase()){case"csharp":case"c#":vm.language="C#";break;case"html":vm.language="HTML";break;case"css":vm.language="CSS";break;case"javascript":vm.language="JavaScript"}},vm.copySuccess=function copySuccess(){"success"!==vm.page.copyCodeButtonState&&($timeout(function(){vm.page.copyCodeButtonState="success"}),$timeout(function(){resetClipboardButtonState()},1e3))},vm.copyError=function copyError(){"error"!==vm.page.copyCodeButtonState&&($timeout(function(){vm.page.copyCodeButtonState="error"}),$timeout(function(){resetClipboardButtonState()},1e3))}},controllerAs:"vm",transclude:!0,bindings:{language:"<"}};angular.module("umbraco.directives").component("umbCodeSnippet",umbCodeSnippet)}(),function(){angular.module("umbraco.directives").component("umbColorPicker",{template:'<div class="umb-color-picker"><input type="hidden" /></div>',controller:function ColorPickerController($scope,$element,$timeout,assetsService,localizationService){var ctrl=this,colorPickerInstance=null,labels={};ctrl.$onInit=function(){assetsService.loadCss("lib/spectrum/spectrum.min.css",$scope),assetsService.load(["lib/spectrum/spectrum.js"],$scope).then(function(){!function grabElementAndRun(){localizationService.localizeMany(["general_cancel","general_choose","general_clear"]).then(function(values){labels.cancel=values[0],labels.choose=values[1],labels.clear=values[2]}),$timeout(function(){var element=$element.find(".umb-color-picker > input")[0];!function setColorPicker(element,labels){var defaultOptions={type:"color",color:null,showAlpha:!1,showInitial:!1,showInput:!0,cancelText:labels.cancel,clearText:labels.clear,chooseText:labels.choose,preferredFormat:"hex",clickoutFiresChange:!0};ctrl.ngModel&&(defaultOptions.color=ctrl.ngModel);var options=Utilities.extend(defaultOptions,ctrl.options),elem=angular.element(element),colorPicker=elem.spectrum(options);(colorPickerInstance=colorPicker)&&elem.on("$destroy",function(){colorPickerInstance.spectrum("destroy")}),function setUpCallbacks(){colorPickerInstance&&(ctrl.onBeforeShow&&colorPickerInstance.on("beforeShow.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onBeforeShow({color:tinycolor})})}),ctrl.onShow&&colorPickerInstance.on("show.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onShow({color:tinycolor})})}),ctrl.onHide&&colorPickerInstance.on("hide.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onHide({color:tinycolor})})}),ctrl.onChange&&colorPickerInstance.on("change.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onChange({color:tinycolor})})}),ctrl.onMove&&colorPickerInstance.on("move.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onMove({color:tinycolor})})}),ctrl.onDragStart&&colorPickerInstance.on("dragstart.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onDragStart({color:tinycolor})})}),ctrl.onDragStop&&colorPickerInstance.on("dragstop.spectrum",function(e,tinycolor){$timeout(function(){ctrl.onDragStop({color:tinycolor})})}))}(),$scope.$applyAsync()}(element,labels)},0,!0)}()})},ctrl.$onChanges=function(changes){colorPickerInstance&&changes.ngModel&&colorPickerInstance.spectrum("set",changes.ngModel.currentValue)}},bindings:{ngModel:"<",options:"<",onBeforeShow:"&?",onShow:"&?",onHide:"&?",onChange:"&?",onMove:"&?",onDragStart:"&?",onDragStop:"&?"}})}(),function(){angular.module("umbraco.directives").directive("umbColorSwatches",function ColorSwatchesDirective(){return{restrict:"E",replace:!0,transclude:!0,template:' <div class="umb-color-swatches" ng-class="{ \'with-labels\': useLabel }"> <button type="button" class="umb-color-box umb-color-box--{{size}} {{colorClassNamePrefix}}-{{color.value}}" ng-repeat="color in colors" title="{{useLabel || useColorClass ? (color.label || color.value) : (\'#\' + color.value)}}" hex-bg-inline="{{useColorClass === false}}" hex-bg-color="{{color.value}}" ng-class="{ \'active\': isSelectedColor(color) }" ng-click="setColor(color, $index, $event)"> <div class="umb-color-box-inner"> <div class="check_circle"> <umb-icon icon="icon-check" class="icon small" ng-show="isSelectedColor(color)"></umb-icon> </div> <div class="umb-color-box__label" ng-if="useLabel"> <div class="umb-color-box__name truncate">{{color.label || color.value}}</div> <div class="umb-color-box__description">#{{color.value}}</div> </div> </div> </button> </div> ',scope:{colors:"=?",size:"@",selectedColor:"=",onSelect:"&",useLabel:"=",useColorClass:"=?",colorClassNamePrefix:"@?"},link:function link(scope,el,attr,ctrl){Utilities.isUndefined(scope.useColorClass)&&(scope.useColorClass=!1),Utilities.isUndefined(scope.colorClassNamePrefix)&&(scope.colorClassNamePrefix="btn"),scope.setColor=function(color,$index,$event){scope.onSelect&&(null!=scope.selectedColor&&scope.selectedColor.value===color.value&&(color=null),scope.selectedColor=color,scope.onSelect({color:color,$index:$index,$event:$event}),$event.stopPropagation())},scope.isSelectedColor=function(color){return scope.selectedColor&&color.value===scope.selectedColor.value}}}})}(),angular.module("umbraco.directives").directive("umbConfirm",function confirmDirective(){return{restrict:"E",replace:!0,template:'<div> <p ng-hide="!caption" class="umb-abstract">{{caption}}</p> <div class="btn-toolbar umb-btn-toolbar"> <umb-button ng-if="showCancel" type="button" action="onCancel()" button-style="link" disabled="confirmButtonState === \'busy\'" label-key="general_cancel"> </umb-button> <umb-button ng-if="showConfirm" type="button" action="confirm()" button-style="{{confirmButtonStyle || \'primary\'}}" state="confirmButtonState" disabled="confirmDisabled === true" label-key="{{confirmLabelKey || \'general_ok\'}}"> </umb-button> </div> </div>',scope:{onConfirm:"=",onCancel:"=",caption:"@",confirmButtonStyle:"@",confirmDisabled:"<?",confirmLabelKey:"@"},link:function link(scope,element,attr,ctrl){scope.showCancel=!1,scope.showConfirm=!1,scope.confirmButtonState="init",scope.onConfirm&&(scope.showConfirm=!0),scope.onCancel&&(scope.showCancel=!0),scope.confirm=function(){scope.onConfirm&&(scope.confirmButtonState="busy",scope.onConfirm())}}}}),function(){angular.module("umbraco.directives").directive("umbConfirmAction",function ConfirmAction(){return{restrict:"E",replace:!0,template:'<div class="umb_confirm-action__overlay" ng-class="{ \'-top\': direction === \'top\', \'-right\': direction === \'right\', \'-bottom\': direction === \'bottom\', \'-left\': direction === \'left\'}" on-outside-click="clickCancel()"> <button type="button" class="umb_confirm-action__overlay-action -confirm btn-reset" ng-click="clickConfirm()" localize="title" title="@buttons_confirmActionConfirm"> <umb-icon icon="icon-check"></umb-icon> <span class="sr-only"> <localize key="buttons_confirmActionConfirm">Confirm</localize> </span> </button> <button type="button" class="umb_confirm-action__overlay-action -cancel btn-reset" ng-click="clickCancel()" localize="title" title="@buttons_confirmActionCancel"> <umb-icon icon="icon-delete"></umb-icon> <span class="sr-only"> <localize key="buttons_confirmActionCancel">Cancel</localize> </span> </button> </div> ',scope:{direction:"@",onConfirm:"&",onCancel:"&"},link:function link(scope,el,attr,ctrl){scope.clickConfirm=function(){scope.onConfirm&&scope.onConfirm()},scope.clickCancel=function(){scope.onCancel&&scope.onCancel()}}}})}(),function(){angular.module("umbraco.directives").directive("umbContentGrid",function ContentGridDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-content-grid"> <div class="umb-content-grid__item umb-outline umb-outline--surrounding" ng-repeat="item in content" ng-class="{\'-selected\': item.selected}" ng-click="clickItem(item, $event, $index)"> <div class="umb-content-grid__content"> <a class="umb-content-grid__item-name umb-outline" ng-href="{{\'#\' + item.editPath}}" ng-click="clickItemName(item, $event, $index)" ng-class="{\'-light\': !item.published && item.updater != null}"> <umb-icon icon="{{item.icon}}" class="umb-content-grid__icon"></umb-icon> <span>{{item.name}}</span> </a> <ul class="umb-content-grid__details-list" ng-class="{\'-light\': !item.published && item.updater != null}"> <li class="umb-content-grid__details-item" ng-if="item.state"> <div class="umb-content-grid__details-label"><localize key="general_status"></localize>:</div> <div class="umb-content-grid__details-value"><umb-variant-state variant="item"></umb-variant-state></div> </li> <li class="umb-content-grid__details-item" ng-repeat="property in contentProperties"> <div class="umb-content-grid__details-label">{{ property.header }}:</div> <div class="umb-content-grid__details-value">{{ item[property.alias] }}</div> </li> </ul> </div> </div> <umb-empty-state ng-if="!content" position="center"> <localize key="content_noItemsToShow">There are no items to show</localize> </umb-empty-state> </div> ',scope:{content:"=",contentProperties:"=",onClick:"=",onClickName:"="},link:function link(scope,el,attr,ctrl){scope.clickItem=function(item,$event,$index){scope.onClick&&scope.onClick(item,$event,$index)},scope.clickItemName=function(item,$event,$index){!scope.onClickName||$event.metaKey||$event.ctrlKey||(scope.onClickName(item,$event,$index),$event.preventDefault()),$event.stopPropagation()}}}})}(),function(){var umbDateTimePicker={template:'<ng-transclude><input type="text" ng-if="!$ctrl.options.inline" ng-model="$ctrl.ngModel" placeholder="Select Date.."></input><div ng-if="$ctrl.options.inline"></div></ng-transclude>',controller:function umbDateTimePickerCtrl($element,$timeout,$scope,assetsService,userService){var ctrl=this,userLocale=null;function grabElementAndRunFlatpickr(){$timeout(function(){var transcludeEl=$element.find("ng-transclude")[0],element=transcludeEl.children[0];!function setDatepicker(element){var fpInstance,fpLib=flatpickr||FlatpickrInstance;if(!fpLib)return console.warn("Unable to find any flatpickr installation");(function setUpCallbacks(){ctrl.options&&ctrl.onChange&&(ctrl.options.onChange=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onChange({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.options&&ctrl.onOpen&&(ctrl.options.onOpen=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onOpen({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.options&&ctrl.onClose&&(ctrl.options.onClose=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onClose({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.options&&ctrl.onMonthChange&&(ctrl.options.onMonthChange=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onMonthChange({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.options&&ctrl.onYearChange&&(ctrl.options.onYearChange=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onYearChange({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.options&&ctrl.onReady&&(ctrl.options.onReady=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onReady({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.onValueUpdate&&(ctrl.options.onValueUpdate=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onValueUpdate({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})}),ctrl.onDayCreate&&(ctrl.options.onDayCreate=function(selectedDates,dateStr,instance){$timeout(function(){ctrl.onDayCreate({selectedDates:selectedDates,dateStr:dateStr,instance:instance})})})})(),ctrl.options.locale||(ctrl.options.locale=userLocale);ctrl.options.onKeyDown=function(selectedDates,dateStr,instance,event){13===(event.keyCode||event.which)&&fpInstance.close()},fpInstance=new fpLib(element,ctrl.options),ctrl.onSetup&&ctrl.onSetup({fpItem:fpInstance});ctrl.ngModel&&fpInstance.setDate(ctrl.ngModel);$(element).on("$destroy",function(){fpInstance.destroy()}),$scope.$applyAsync()}(element)},0,!0)}ctrl.$onInit=function(){assetsService.loadCss("lib/flatpickr/flatpickr.min.css",$scope).then(function(){userService.getCurrentUser().then(function(user){(userLocale=user.locale).indexOf("-")>-1&&(userLocale=userLocale.split("-")[0]),grabElementAndRunFlatpickr()})})}},transclude:!0,bindings:{ngModel:"<",options:"<",onSetup:"&?",onChange:"&?",onOpen:"&?",onClose:"&?",onMonthChange:"&?",onYearChange:"&?",onReady:"&?",onValueUpdate:"&?",onDayCreate:"&?"}};angular.module("umbraco.directives").component("umbFlatpickr",umbDateTimePicker),angular.module("umbraco.directives").component("umbDateTimePicker",umbDateTimePicker)}(),function(){angular.module("umbraco.directives").directive("umbDisableFormValidation",function UmbDisableFormValidation(){return{restrict:"A",require:"?form",link:function link(scope,elm,attrs,ctrl){ctrl.$setValidity=function(){}}}})}(),function(){angular.module("umbraco.directives").directive("umbDropdown",function umbDropdown($document){return{restrict:"E",replace:!0,transclude:!0,template:'<ul class="dropdown-menu" role="menu" on-outside-click="close()" ng-transclude></ul> ',scope:{onClose:"&"},link:function link(scope,element,attr,ctrl){function keydown(event){27===event.keyCode&&scope.onClose()}scope.close=function(){scope.onClose&&scope.onClose()},$document.on("keydown",keydown),scope.$on("$destroy",function stopListening(){$document.off("keydown",keydown)})}}})}(),function(){angular.module("umbraco.directives").directive("umbDropdownItem",function umbDropdownItem(){return{restrict:"E",replace:!0,transclude:!0,template:'<li role="menuitem" ng-transclude></li> '}})}(),function(){angular.module("umbraco.directives").directive("umbEmptyState",function EmptyStateDirective(){return{restrict:"E",replace:!0,transclude:!0,template:"<div class=\"umb-empty-state\" ng-class=\"{ '-small': size === 'small', '-large': size === 'large', '-center': position === 'center' }\" ng-transclude> </div> ",scope:{size:"@",position:"@"}}})}(),function(){var component={template:'<span class="umb-file-icon umb-file-icon--{{vm.size}}"> <span class="umb-file-icon__inner"> <umb-icon icon="{{vm.icon}}" class="icon"></umb-icon> <span ng-if="vm.extension" class="umb-file-icon__extension">.{{vm.extension}}</span> </span> <small ng-if="vm.text" class="umb-file-icon__text">{{vm.text}}</small> </span> ',bindings:{extension:"@?",icon:"@?",size:"@?",text:"@?"},controllerAs:"vm",controller:function umbFileIconController(){this.icon||(this.icon="icon-document")}};angular.module("umbraco.directives").component("umbFileIcon",component)}(),function(){angular.module("umbraco.directives").directive("umbFolderGrid",function FolderGridDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-folder-grid"> <div class="umb-folder-grid__folder" ng-repeat="folder in folders" ng-class="{\'-selected\': folder.selected}" ng-click="clickFolder(folder, $event, $index)"> <div class="umb-folder-grid__folder-description"> <umb-icon icon="{{folder.icon}}" class="umb-folder-grid__folder-icon"></umb-icon> <div ng-click="clickFolderName(folder, $event, $index)" class="umb-folder-grid__folder-name">{{folder.name}}</div> </div> </div> </div> ',scope:{folders:"=",onClick:"=",onClickName:"="},link:function link(scope,el,attr,ctrl){scope.clickFolder=function(folder,$event,$index){scope.onClick&&(scope.onClick(folder,$event,$index),$event.stopPropagation())},scope.clickFolderName=function(folder,$event,$index){scope.onClickName&&(scope.onClickName(folder,$event,$index),$event.stopPropagation())}}}})}(),angular.module("umbraco.directives").directive("umbGenerateAlias",function($timeout,entityResource,localizationService){return{restrict:"E",template:'<div> <span class="umb-locked-field__text cursor-not-allowed" ng-show="!enableLock">{{ alias }}</span> <div ng-show="enableLock"> <umb-locked-field locked="locked" ng-model="alias" placeholder-text="placeholderText" validation-position="validationPosition" server-validation-field="{{serverValidationField}}"> </umb-locked-field> </div> </div> ',replace:!0,scope:{alias:"=",aliasFrom:"=",enableLock:"=?",validationPosition:"=?",serverValidationField:"@"},link:function link(scope,element,attrs,ctrl){var eventBindings=[],bindWatcher=!0,generateAliasTimeout="",updateAlias=!1;scope.locked=!0,scope.labels={idle:"Enter alias...",busy:"Generating alias..."},scope.placeholderText=scope.labels.idle,localizationService.localize("placeholders_enterAlias").then(function(value){scope.labels.idle=scope.placeholderText=value}),localizationService.localize("placeholders_generatingAlias").then(function(value){scope.labels.busy=value}),eventBindings.push(scope.$watch("locked",function(newValue,oldValue){!1===newValue&&(bindWatcher=!1)})),eventBindings.push(scope.$watch("alias",function(newValue,oldValue){""!==scope.alias&&null!==scope.alias&&void 0!==scope.alias||!0===bindWatcher&&eventBindings.push(scope.$watch("aliasFrom",function(newValue,oldValue){bindWatcher&&function generateAlias(value){generateAliasTimeout&&$timeout.cancel(generateAliasTimeout),void 0!==value&&""!==value&&null!==value?(scope.alias="",scope.placeholderText=scope.labels.busy,generateAliasTimeout=$timeout(function(){updateAlias=!0,entityResource.getSafeAlias(value,!0).then(function(safeAlias){updateAlias&&(scope.alias=safeAlias.alias),scope.placeholderText=scope.labels.idle})},500)):(updateAlias=!0,scope.alias="",scope.placeholderText=scope.labels.idle)}(newValue)}))})),scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]()})}}}),function(){angular.module("umbraco.directives").directive("umbGridSelector",function GridSelector($location,overlayService,editorService){return{restrict:"E",replace:!0,template:'<div class="umb-grid-selector"> <div class="umb-grid-selector__items"> <div class="umb-grid-selector__item -default" ng-if="defaultItem !== null"> <div class="umb-grid-selector__item-content"> <umb-icon icon="{{defaultItem.icon}}" class="umb-grid-selector__item-icon"></umb-icon> <div class="umb-grid-selector__item-label">{{ defaultItem.name }}</div> <div ng-show="defaultItem.id"><button class="umb-grid-selector__item-default-label btn-link -blue" ng-click="openTemplate(defaultItem)"><localize key="general_open">Open</localize></button></div> <span class="umb-grid-selector__item-default-label">(<localize key="general_default">Default</localize> {{itemLabel}})</span> </div> <button type="button" class="btn-reset" ng-if="selectedItems.length === 1" ng-click="removeDefaultItem()"> <umb-icon icon="icon-trash" class="umb-grid-selector__item-remove"></umb-icon> <span class="sr-only">Remove Template</span> </button> </div> <div class="umb-grid-selector__item" ng-repeat="selectedItem in selectedItems | filter: { alias:\'!\'+defaultItem.alias }:true"> <div class="umb-grid-selector__item-content"> <umb-icon icon="{{selectedItem.icon}}" class="umb-grid-selector__item-icon"></umb-icon> <div class="umb-grid-selector__item-label">{{ selectedItem.name }}</div> <div><button class="umb-grid-selector__item-default-label btn-link -blue" ng-click="openTemplate(selectedItem)"><localize key="general_open">Open</localize></button></div> <div><button class="umb-grid-selector__item-default-label btn-link -blue" ng-click="setAsDefaultItem(selectedItem)"><localize key="grid_setAsDefault">Set as default</localize></button></div> </div> <button type="button" class="btn-reset" ng-click="removeItem(selectedItem)"> <umb-icon icon="icon-trash" class="umb-grid-selector__item-remove"></umb-icon> <span class="sr-only">Remove Template</span> </button> </div> <button type="button" class="umb-grid-selector__item -placeholder" ng-if="(availableItems | compareArrays:selectedItems:\'alias\').length > 0" ng-click="openItemPicker($event)" hotkey="alt+shift+t"> <div class="umb-grid-selector__item-content"> <div class="umb-grid-selector__item-label -blue" ng-if="defaultItem !== null"><localize key="grid_chooseExtra">Choose extra</localize> {{itemLabel}}</div> <div class="umb-grid-selector__item-label -blue" ng-if="defaultItem === null"><localize key="grid_chooseDefault">Choose default</localize> {{itemLabel}}</div> </div> </button> </div> <div class="text-center" ng-if="(availableItems | compareArrays:selectedItems:\'alias\').length === 0"> <small><localize key="general_all">All</localize> {{itemLabel}}s <localize key="grid_areAdded">are added</localize></small> </div> </div> ',scope:{name:"=",alias:"=",selectedItems:"=",availableItems:"=",defaultItem:"=",itemName:"@",updatePlaceholder:"="},link:function link(scope,el,attr,ctrl){var eventBindings=[];function updatePlaceholders(){null!==scope.defaultItem&&scope.defaultItem.placeholder&&(scope.defaultItem.name=scope.name,null!==scope.alias&&void 0!==scope.alias&&(scope.defaultItem.alias=scope.alias)),Utilities.forEach(scope.selectedItems,function(selectedItem){selectedItem.placeholder&&(selectedItem.name=scope.name,null!==scope.alias&&void 0!==scope.alias&&(selectedItem.alias=scope.alias))}),Utilities.forEach(scope.availableItems,function(availableItem){availableItem.placeholder&&(availableItem.name=scope.name,null!==scope.alias&&void 0!==scope.alias&&(availableItem.alias=scope.alias))})}scope.dialogModel={},scope.showDialog=!1,scope.itemLabel="",scope.itemName?scope.itemLabel=scope.itemName:scope.itemLabel="item",scope.removeItem=function(selectedItem){var selectedItemIndex=scope.selectedItems.indexOf(selectedItem);scope.selectedItems.splice(selectedItemIndex,1)},scope.removeDefaultItem=function(){scope.selectedItems=[],scope.defaultItem=null},scope.openItemPicker=function($event){var dialogModel={view:"itempicker",title:"Choose "+scope.itemLabel,availableItems:scope.availableItems,selectedItems:scope.selectedItems,position:"target",event:$event,submit:function submit(model){scope.selectedItems.push(model.selectedItem),null===scope.defaultItem&&scope.setAsDefaultItem(model.selectedItem),overlayService.close()},close:function close(){overlayService.close()}};overlayService.open(dialogModel)},scope.openTemplate=function(selectedItem){var editor={id:selectedItem.id,submit:function submit(){editorService.close()},close:function close(){editorService.close()}};editorService.templateEditor(editor)},scope.setAsDefaultItem=function(selectedItem){scope.defaultItem={},scope.defaultItem=selectedItem},function activate(){scope.updatePlaceholder&&(eventBindings.push(scope.$watch("name",function(newValue,oldValue){updatePlaceholders()})),eventBindings.push(scope.$watch("alias",function(newValue,oldValue){updatePlaceholders()})))}(),scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]()})}}})}(),function(){angular.module("umbraco.directives").directive("umbGroupsBuilder",function GroupsBuilderDirective(contentTypeHelper,contentTypeResource,mediaTypeResource,$filter,iconHelper,$q,$timeout,notificationsService,localizationService,editorService,eventsService,overlayService){return{restrict:"E",replace:!0,template:'<div data-element="groups-builder" class="clearfix"> <umb-editor-sub-header class="umb-group-builder__toolbar" appearance="white"> <umb-editor-sub-header-content-left class="left"> <div class="umb-group-builder__tabs" ng-if="(sortingMode && tabs.length > 0) || (!sortingMode)"> <button ng-show="overflow.left > 0" class="btn-reset umb-group-builder__tabs-overflow umb-group-builder__tabs-overflow--left" ng-click="moveTabsOverflowLeft()"> <span class="caret"></span> </button> <ul class="umb-group-builder__tabs-list" ui-sortable="sortableOptionsTab" ng-model="tabs" umb-overflow-checker on-overflow="setTabOverflowState(overflowLeft, overflowRight)"> <li ng-if="hasGenericTab" umb-droppable="droppableOptionsTab" data-tab-alias="{{genericTab.alias}}"> <umb-content-type-tab tab="genericTab" is-open="genericTab.alias == openTabAlias" on-click="changeTab(genericTab)" allow-change-name="false"> </umb-content-type-tab> </li> <li ng-repeat="(tabIndex, tab) in tabs track by tab.key" ng-class="{\'umb-group-builder__tab-sortable\': sortingMode}" umb-droppable="droppableOptionsTab" data-tab-key="{{tab.key}}" data-tab-alias="{{tab.alias}}"> <umb-content-type-tab tab="tab" is-open="tab.alias === openTabAlias" on-click="changeTab(tab)" on-click-composition="openDocumentType(documentTypeId)" sorting="sortingMode" allow-remove="canRemoveTab(tab) && !sortingMode" on-remove="removeTab(tab, tabIndex)" val-server-field-name="{{\'Groups[\' + tab.serverValidationIndex + \'].Name\'}}" on-change-sort-order-value="orderTabs()" on-change-name="onChangeTabName(tab)"> </umb-content-type-tab> </li> <li class="umb-group-builder__tabs-list__add-tab"> <umb-button ng-if="!sortingMode" class="umb-group-builder__tabs__add-tab" type="button" label-key="contentTypeEditor_addTab" icon="icon-add" button-style="white" action="addTab();"> </umb-button> </li> </ul> <button ng-if="overflow.right < 0" class="btn-reset umb-group-builder__tabs-overflow umb-group-builder__tabs-overflow--right" ng-click="moveTabsOverflowRight()"> <span class="caret"></span> </button> </div> </umb-editor-sub-header-content-left> <umb-editor-sub-header-content-right class="right"> <div ng-if="sortingMode" class="umb-group-builder__convert-dropzone" umb-droppable="droppableOptionsConvert"> <localize key="contentTypeEditor_convertToTab"> </localize></div> <umb-button style="margin-right: 5px;" alias="compositions" ng-if="compositions !== false" type="button" button-style="outline" label-key="contentTypeEditor_compositions" icon="icon-merge" action="openCompositionsDialog()" size="xs" add-ellipsis="true" state="compositionsButtonState"> </umb-button> <umb-button alias="reorder" ng-if="sorting !== false" type="button" button-style="outline" label-key="{{sortingButtonKey}}" icon="icon-navigation" action="toggleSortingMode();" size="xs"> </umb-button> </umb-editor-sub-header-content-right> </umb-editor-sub-header> <a ng-if="!sortingMode" hotkey="alt+shift+p" ng-click="addPropertyToActiveGroup()"></a> <a ng-if="!sortingMode" hotkey="alt+shift+g" ng-click="addGroupToActiveTab()"></a> <div ng-if="sortingMode && model.groups.length === 0" class="umb-group-builder__no-data-text"> <localize key="contentTypeEditor_noGroups"></localize> </div>  <umb-box ng-repeat="(tabIndex, tab) in tabs track by tab.key" ng-show="isUngroupedPropertiesVisible(tab)" class="umb-group-builder__ungrouped-properties"> <umb-box-content> <ul class="umb-group-builder__properties" ui-sortable="sortableOptionsProperty" ng-model="tab.properties" ng-show="tab.properties.length > 0 || sortingMode"> <li ng-repeat="(propertyIndex, property) in tab.properties track by propertyIndex" ng-class="{\'umb-group-builder__property-sortable\': sortingMode && !property.inherited}"> <umb-content-type-property ng-if="property.propertyState !== \'init\'" property="property" sortable="sortingMode" on-edit="editPropertyTypeSettings(property)" on-remove="deleteProperty(tab.properties, property)" val-server-field-alias="{{\'Groups[\' + tab.serverValidationIndex + \'].Properties[\' + propertyIndex + \'].Alias\'}}" val-server-field-label="{{\'Groups[\' + tab.serverValidationIndex + \'].Properties[\' + propertyIndex + \'].Label\'}}" on-change-sort-order-value="onChangePropertySortOrderValue(tab)" val-tab-alias="tab-content-{{tab.alias}}"> </umb-content-type-property> </li> </ul> <button ng-if="!sortingMode" type="button" data-element="property-add" class="umb-group-builder__group-add-property" ng-click="addNewProperty(tab)"> <localize key="contentTypeEditor_addProperty"></localize> </button> <umb-empty-state ng-if="sortingMode && tab.properties.length === 0" position="center"> {{ tabDirectPropertiesDropZoneLabel }} </umb-empty-state> </umb-box-content> </umb-box>  <div class="umb-group-builder__groups" ui-sortable="sortableOptionsGroup" ng-model="model.groups"> <div ng-repeat="(groupIndex, group) in model.groups track by group.key" ng-show="group.type === \'Group\' && group.parentAlias === openTabAlias" ng-class="{\'umb-group-builder__group-sortable\': sortingMode && !group.inherited}" data-group-key="{{group.key}}"> <umb-content-type-group ng-if="group.tabState !== \'init\'" on-focus="activateGroup(group)" allow-name="true" group="group" allow-remove="canRemoveGroup(group) && !sortingMode" on-click-composition="openDocumentType(documentTypeId)" on-remove="removeGroup(group)" on-update-name="onChangeGroupName(group)" sorting="sortingMode" on-change-sort-order-value="onChangeGroupSortOrderValue(group)" val-server-field-name="{{\'Groups[\' + group.serverValidationIndex + \'].Name\'}}" val-tab-alias="tab-content-{{group.type === \'Group\' ? group.parentAlias : group.alias}}"> <ul class="umb-group-builder__properties" ui-sortable="sortableOptionsProperty" ng-model="group.properties" ng-show="group.properties.length > 0 || sortingMode"> <li ng-repeat="(propertyIndex, property) in group.properties track by propertyIndex" ng-class="{\'umb-group-builder__property-sortable\': sortingMode && !property.inherited}"> <umb-content-type-property ng-if="property.propertyState !== \'init\'" property="property" sortable="sortingMode" on-edit="editPropertyTypeSettings(property)" on-remove="deleteProperty(group.properties, property)" on-change-sort-order-value="onChangePropertySortOrderValue(group)" val-server-field-alias="{{\'Groups[\' + group.serverValidationIndex + \'].Properties[\' + propertyIndex + \'].Alias\'}}" val-server-field-label="{{\'Groups[\' + group.serverValidationIndex + \'].Properties[\' + propertyIndex + \'].Label\'}}" val-tab-alias="tab-content-{{group.type === \'Group\' ? group.parentAlias : group.alias}}"> </umb-content-type-property> </li> </ul> <button ng-if="!sortingMode" type="button" data-element="property-add" class="umb-group-builder__group-add-property" ng-click="addNewProperty(group)"> <localize key="contentTypeEditor_addProperty"></localize> </button> </umb-content-type-group> </div> </div> <button ng-if="!sortingMode" type="button" class="umb-group-builder__group -placeholder" ng-click="addGroupToActiveTab()" data-element="group-add"> <localize key="contentTypeEditor_addGroup"></localize> </button> </div> ',scope:{model:"=",compositions:"=",sorting:"=",contentType:"@"},link:function link(scope,element){var TYPE_GROUP=contentTypeHelper.TYPE_GROUP,TYPE_TAB=contentTypeHelper.TYPE_TAB,eventBindings=[],validationTranslated="",tabNoSortOrderTranslated="";scope.dataTypeHasChanged=!1,scope.sortingMode=!1,scope.toolbar=[],scope.sortingButtonKey="general_reorder",scope.compositionsButtonState="init",scope.tabs=[],scope.genericGroups=[],scope.openTabAlias=null,scope.hasGenericTab=!1,scope.genericTab={key:String.CreateGuid(),type:TYPE_TAB,name:"Generic",alias:null,parentAlias:null,sortOrder:0,properties:[]};var tabsInitialized=!1;function activate(){!function setSortingOptions(){var defaultOptions={axis:"",tolerance:"pointer",opacity:.7,scroll:!0,cursor:"move",zIndex:6e3,forcePlaceholderSize:!0,dropOnEmpty:!0,helper:"clone",appendTo:"body"};scope.sortableOptionsTab=_objectSpread(_objectSpread({},defaultOptions),{},{connectWith:".umb-group-builder__tabs",placeholder:"umb-group-builder__tab-sortable-placeholder",handle:".umb-group-builder__tab-handle",items:".umb-group-builder__tab-sortable",stop:function stop(event,ui){var tabKey=!!ui.item[0].dataset.tabKey&&ui.item[0].dataset.tabKey,dropIndex=scope.tabs.findIndex(function(tab){return tab.key===tabKey});updateSortOrder(scope.tabs,dropIndex)}}),scope.sortableOptionsGroup=_objectSpread(_objectSpread({},defaultOptions),{},{connectWith:".umb-group-builder__groups",placeholder:"umb-group-builder__group-sortable-placeholder",handle:".umb-group-builder__group-handle",items:".umb-group-builder__group-sortable",stop:function stop(e,ui){var groupKey=!!ui.item[0].dataset.groupKey&&ui.item[0].dataset.groupKey,group=groupKey?scope.model.groups.find(function(group){return group.key===groupKey}):{};if(group&&group.type===TYPE_GROUP){var parentAlias=scope.openTabAlias,oldAlias=group.alias||null,newAlias=contentTypeHelper.updateParentAlias(oldAlias,parentAlias);group.alias=newAlias,group.parentAlias=parentAlias,contentTypeHelper.updateDescendingAliases(scope.model.groups,oldAlias,newAlias);var groupsInTab=scope.model.groups.filter(function(group){return group.parentAlias===parentAlias}),dropIndex=groupsInTab.findIndex(function(group){return group.key===groupKey});updateSortOrder(groupsInTab,dropIndex),scope.sortableRequestedTabAlias=void 0}}}),scope.sortableOptionsProperty=_objectSpread(_objectSpread({},defaultOptions),{},{connectWith:".umb-group-builder__properties",placeholder:"umb-group-builder__property_sortable-placeholder",handle:".umb-group-builder__property-handle",items:".umb-group-builder__property-sortable",stop:function stop(e,ui){!function updatePropertiesSortOrder(){scope.model.groups.forEach(function(group){return group.properties=contentTypeHelper.updatePropertiesSortOrder(group.properties)})}()}}),scope.droppableOptionsConvert={accept:".umb-group-builder__group-sortable",tolerance:"pointer",drop:function drop(evt,ui){var groupKey=!!ui.draggable[0].dataset.groupKey&&ui.draggable[0].dataset.groupKey,group=groupKey?scope.model.groups.find(function(group){return group.key===groupKey}):{};group&&(contentTypeHelper.convertGroupToTab(scope.model.groups,group),scope.tabs.push(group),scope.$broadcast("umbOverflowChecker.checkOverflow"),scope.$broadcast("umbOverflowChecker.scrollTo",{position:"end"}))}},scope.sortableRequestedTabAlias=void 0,scope.sortableRequestedTabTimeout=null,scope.droppableOptionsTab={accept:".umb-group-builder__property-sortable, .umb-group-builder__group-sortable",tolerance:"pointer",over:function over(evt,ui){var hoveredTabAlias=""===evt.target.dataset.tabAlias?null:evt.target.dataset.tabAlias;if(ui.draggable[0].dataset.groupKey){var groupKey=!!ui.draggable[0].dataset.groupKey&&ui.draggable[0].dataset.groupKey,group=groupKey?scope.model.groups.find(function(group){return group.key===groupKey}):{},newAlias=contentTypeHelper.updateParentAlias(group.alias||null,hoveredTabAlias);if(group.alias!==newAlias&&!1===contentTypeHelper.isAliasUnique(scope.model.groups,newAlias))return void localizationService.localize("contentTypeEditor_groupReorderSameAliasError",[group.name,newAlias]).then(function(value){notificationsService.error(value)})}scope.sortableRequestedTabAlias!==hoveredTabAlias&&(null!==scope.sortableRequestedTabTimeout&&($timeout.cancel(scope.sortableRequestedTabTimeout),scope.sortableRequestedTabTimeout=null,scope.sortableRequestedTabAlias=void 0),scope.sortableRequestedTabAlias=hoveredTabAlias,scope.sortableRequestedTabTimeout=$timeout(function(){scope.openTabAlias=scope.sortableRequestedTabAlias,scope.sortableRequestedTabTimeout=null,scope.$apply(),$(".umb-group-builder__ungrouped-properties .umb-group-builder__properties").sortable("refresh"),$(".umb-group-builder__groups").sortable("refresh")},400))},out:function out(evt,ui){var hoveredTabAlias=""===evt.target.dataset.tabAlias?null:evt.target.dataset.tabAlias;null===scope.sortableRequestedTabTimeout||void 0!==hoveredTabAlias&&scope.sortableRequestedTabAlias!==hoveredTabAlias||($timeout.cancel(scope.sortableRequestedTabTimeout),scope.sortableRequestedTabTimeout=null,scope.sortableRequestedTabAlias=null)}}}(),localizationService.localizeMany(["validation_validation","contentTypeEditor_tabHasNoSortOrder","general_generic","contentTypeEditor_tabDirectPropertiesDropZone"]).then(function(data){validationTranslated=data[0],tabNoSortOrderTranslated=data[1],scope.genericTab.name=data[2],scope.tabDirectPropertiesDropZoneLabel=data[3]})}function updateSortOrder(items,movedIndex){if(!(items&&items.length<=1)){var movedItem=items[movedIndex];if(0===movedIndex){var nextItem=items[movedIndex+1];movedItem.sortOrder=nextItem.sortOrder-1}else{var prevItem=items[movedIndex-1];movedItem.sortOrder=prevItem.sortOrder+1}for(var i=movedIndex;i<items.length;i++){var item=items[i];if(!item.inherited&&0!==i){var prev=items[i-1];item.sortOrder===prev.sortOrder&&(item.sortOrder=item.sortOrder+1)}}}}function filterAvailableCompositions(selectedContentType,selecting){var selectedContentTypeAliases=selecting?_.union(scope.compositionsDialogModel.compositeContentTypes,[selectedContentType.alias]):_.reject(scope.compositionsDialogModel.compositeContentTypes,function(i){return i===selectedContentType.alias}),propAliasesExisting=_.filter(_.flatten(_.map(scope.model.groups,function(g){return _.map(g.properties,function(p){return p.alias})})),function(f){return null!=f});return("documentType"===scope.contentType?contentTypeResource.getAvailableCompositeContentTypes:mediaTypeResource.getAvailableCompositeContentTypes)(scope.model.id,selectedContentTypeAliases,propAliasesExisting).then(function(filteredAvailableCompositeTypes){scope.compositionsDialogModel.availableCompositeContentTypes.forEach(function(current){current.allowed=!0;var found=filteredAvailableCompositeTypes.find(function(f){return current.contentType.alias===f.contentType.alias});current.allowed=scope.model.lockedCompositeContentTypes.includes(current.contentType.alias)&&selectedContentTypeAliases.includes(current.contentType.alias)||!!found&&found.allowed})})}function updateGroupAlias(group){var localAlias=contentTypeHelper.generateLocalAlias(group.name),oldAlias=group.alias,newAlias=contentTypeHelper.updateLocalAlias(oldAlias,localAlias);return!1===contentTypeHelper.isAliasUnique(scope.model.groups,newAlias)&&(newAlias=contentTypeHelper.createUniqueAlias(scope.model.groups,newAlias)),group.alias=newAlias,group.parentAlias=contentTypeHelper.getParentAlias(newAlias),contentTypeHelper.updateDescendingAliases(scope.model.groups,oldAlias,newAlias),!0}function checkGenericTabVisibility(){var hasRootGroups=scope.model.groups.filter(function(group){return group.type===TYPE_GROUP&&null===group.parentAlias}).length>0;scope.hasGenericTab=hasRootGroups&&scope.tabs.length>0||scope.sortingMode}function notifyChanged(){eventsService.emit("editors.groupsBuilder.changed")}eventBindings.push(scope.$watchCollection("model.groups",function(newValue,oldValue){newValue.length===oldValue.length&&tabsInitialized?tabsInitialized=!0:(contentTypeHelper.defineParentAliasOnGroups(newValue),contentTypeHelper.relocateDisorientedGroups(newValue),scope.tabs=$filter("filter")(newValue,function(group){return group.type===TYPE_TAB&&null==group.parentAlias}),scope.orderTabs(),newValue.filter(function(group){return!group.inherited||group.inherited&&group.properties.filter(function(property){return!property.inherited}).length>0}).forEach(function(group,index){group.serverValidationIndex=group.inherited?void 0:index}),checkGenericTabVisibility(),!scope.openTabAlias&&scope.hasGenericTab?scope.openTabAlias=null:!scope.openTabAlias&&scope.tabs.length>0&&(scope.openTabAlias=scope.tabs[0].alias),tabsInitialized=!0)})),scope.togglePrompt=function(object){object.deletePrompt=!object.deletePrompt},scope.hidePrompt=function(object){object.deletePrompt=!1},scope.toggleSortingMode=function(){if(!0===scope.sortingMode){for(var sortOrderMissing=!1,i=0;i<scope.model.groups.length;i++){var group=scope.model.groups[i];"init"!==group.tabState&&void 0===group.sortOrder&&(sortOrderMissing=!0,group.showSortOrderMissing=!0,notificationsService.error(validationTranslated+": "+group.name+" "+tabNoSortOrderTranslated))}sortOrderMissing||(scope.sortingMode=!1,scope.sortingButtonKey="general_reorder"),scope.tabs.length>0&&!scope.openTabAlias&&(scope.openTabAlias=scope.tabs[0].alias)}else scope.sortingMode=!0,scope.sortingButtonKey="general_reorderDone";checkGenericTabVisibility(),scope.$broadcast("umbOverflowChecker.checkOverflow")},scope.openCompositionsDialog=function(){scope.compositionsDialogModel={contentType:scope.model,compositeContentTypes:scope.model.compositeContentTypes,view:"views/common/infiniteeditors/compositions/compositions.html",size:"small",submit:function submit(){editorService.close()},close:function close(oldModel){scope.model.groups=oldModel.contentType.groups,scope.model.compositeContentTypes=oldModel.contentType.compositeContentTypes,editorService.close()},selectCompositeContentType:function selectCompositeContentType(selectedContentType){var deferred=$q.defer(),newSelection=-1===scope.model.compositeContentTypes.indexOf(selectedContentType.alias);return newSelection?("documentType"===scope.contentType?contentTypeResource.getById:mediaTypeResource.getById)(selectedContentType.id).then(function(composition){contentTypeHelper.validateAddingComposition(scope.model,composition).length>0?(scope.compositionsDialogModel.compositeContentTypes.splice(scope.compositionsDialogModel.compositeContentTypes.indexOf(composition.alias),1),selectedContentType.allowed=!1):contentTypeHelper.mergeCompositeContentType(scope.model,composition),filterAvailableCompositions(selectedContentType,newSelection).then(function(){deferred.resolve({selectedContentType:selectedContentType,newSelection:newSelection})},function(){deferred.reject()})}):(contentTypeHelper.splitCompositeContentType(scope.model,selectedContentType),filterAvailableCompositions(selectedContentType,newSelection).then(function(){deferred.resolve({selectedContentType:selectedContentType,newSelection:newSelection})},function(){deferred.reject()})),deferred.promise}};var availableContentTypeResource="documentType"===scope.contentType?contentTypeResource.getAvailableCompositeContentTypes:mediaTypeResource.getAvailableCompositeContentTypes,whereUsedContentTypeResource="documentType"===scope.contentType?contentTypeResource.getWhereCompositionIsUsedInContentTypes:mediaTypeResource.getWhereCompositionIsUsedInContentTypes,countContentTypeResource="documentType"===scope.contentType?contentTypeResource.getCount:mediaTypeResource.getCount,propAliasesExisting=_.filter(_.flatten(_.map(scope.model.groups,function(g){return _.map(g.properties,function(p){return p.alias})})),function(f){return null!=f});scope.compositionsButtonState="busy",$q.all([availableContentTypeResource(scope.model.id,[],propAliasesExisting,scope.model.isElement).then(function(result){!function setupAvailableContentTypesModel(result){scope.compositionsDialogModel.availableCompositeContentTypes=result,scope.compositionsDialogModel.availableCompositeContentTypes.forEach(function(c){scope.compositionsDialogModel.compositeContentTypes.includes(c.contentType.alias)&&(c.allowed=!0),c.inherited=!1,scope.model.lockedCompositeContentTypes.includes(c.contentType.alias)&&(c.inherited=!0),iconHelper.formatContentTypeIcons([c.contentType])})}(result)}),whereUsedContentTypeResource(scope.model.id).then(function(whereUsed){scope.compositionsDialogModel.section=scope.contentType,scope.compositionsDialogModel.whereCompositionUsed=whereUsed}),countContentTypeResource().then(function(result){scope.compositionsDialogModel.totalContentTypes=parseInt(result,10)})]).then(function(){editorService.open(scope.compositionsDialogModel),scope.compositionsButtonState="init"})},scope.openDocumentType=function(documentTypeId){var editor={id:documentTypeId,submit:function submit(){var args={node:scope.model};eventsService.emit("editors.documentType.reload",args),editorService.close()},close:function close(){editorService.close()}};editorService.documentTypeEditor(editor)},scope.changeTab=function(_ref){var alias=_ref.alias;scope.openTabAlias=alias},scope.addTab=function(){var newTabIndex=scope.tabs.length,lastTab=scope.tabs[newTabIndex-1],sortOrder=lastTab&&void 0!==lastTab.sortOrder?lastTab.sortOrder+1:0,key=String.CreateGuid(),tab={key:key,type:TYPE_TAB,name:"",alias:key,parentAlias:null,sortOrder:sortOrder,properties:[]};0===newTabIndex&&!1===scope.hasGenericTab&&scope.model.groups.forEach(function(group){group.inherited||null!=group.parentAlias||(group.parentAlias=tab.alias,group.alias=contentTypeHelper.updateParentAlias(group.alias,group.parentAlias))}),scope.model.groups=[].concat(_toConsumableArray(scope.model.groups),[tab]),scope.openTabAlias=tab.alias,notifyChanged(),scope.$broadcast("umbOverflowChecker.checkOverflow"),scope.$broadcast("umbOverflowChecker.scrollTo",{position:"end"})},scope.removeTab=function(tab,indexInTabs){var tabName=tab.name||"",localizeMany=localizationService.localizeMany(["general_delete","contentTypeEditor_confirmDeleteTabNotice"]),localize=localizationService.localize("contentTypeEditor_confirmDeleteTabMessage",[tabName]);$q.all([localizeMany,localize]).then(function(values){var translations=values[0],message=values[1];overlayService.confirmDelete({title:"".concat(translations[0]," ").concat(tabName),content:message,confirmMessage:translations[1],submitButtonLabelKey:"actions_delete",submit:function submit(){var indexInGroups=scope.model.groups.findIndex(function(group){return group.alias===tab.alias});scope.model.groups.splice(indexInGroups,1),scope.model.groups=scope.model.groups.filter(function(group){return group.parentAlias!==tab.alias}),$timeout(function(){scope.tabs.length>0?scope.openTabAlias=indexInTabs>0?scope.tabs[indexInTabs-1].alias:scope.tabs[0].alias:scope.openTabAlias=null}),scope.$broadcast("umbOverflowChecker.checkOverflow"),notifyChanged(),overlayService.close()}})})},scope.canRemoveTab=function(tab){return!0!==tab.inherited},scope.setTabOverflowState=function(overflowLeft,overflowRight){scope.overflow={left:overflowLeft,right:overflowRight}},scope.moveTabsOverflowLeft=function(){var el=element[0].querySelector(".umb-group-builder__tabs-list");el.scrollLeft-=.5*el.clientWidth},scope.moveTabsOverflowRight=function(){var el=element[0].querySelector(".umb-group-builder__tabs-list");el.scrollLeft+=.5*el.clientWidth},scope.orderTabs=function(){scope.tabs=$filter("orderBy")(scope.tabs,"sortOrder")},scope.onChangeTabName=function(tab){updateGroupAlias(tab)&&(scope.openTabAlias=tab.alias,scope.$broadcast("umbOverflowChecker.checkOverflow"))},scope.isUngroupedPropertiesVisible=function(_ref2){var alias=_ref2.alias,properties=_ref2.properties,isOpenTab=alias===scope.openTabAlias;if(isOpenTab&&properties.length>0)return!0;if(isOpenTab&&scope.sortingMode)return!0;var tabHasGroups=scope.model.groups.filter(function(group){return group.parentAlias===alias}).length>0;return!(!isOpenTab||tabHasGroups)||void 0},scope.addNewProperty=function(group){var newProperty={label:null,alias:null,propertyState:"init",validation:{mandatory:!1,mandatoryMessage:null,pattern:null,patternMessage:null},labelOnTop:!1},propertySettings={title:"Property settings",property:newProperty,contentType:scope.contentType,contentTypeName:scope.model.name,contentTypeAllowCultureVariant:scope.model.allowCultureVariant,contentTypeAllowSegmentVariant:scope.model.allowSegmentVariant,view:"views/common/infiniteeditors/propertysettings/propertysettings.html",size:"small",submit:function submit(model){(newProperty=_objectSpread({},model.property)).propertyState="active",group.properties.push(newProperty),editorService.close()},close:function close(){editorService.close()}};editorService.open(propertySettings)},scope.addGroup=function(tabAlias){scope.model.groups=scope.model.groups||[];var groupsInTab=scope.model.groups.filter(function(group){return group.parentAlias===tabAlias}),lastGroupSortOrder=groupsInTab.length>0?groupsInTab[groupsInTab.length-1].sortOrder+1:0,key=String.CreateGuid(),group={key:key,type:TYPE_GROUP,name:"",alias:contentTypeHelper.updateParentAlias(key,tabAlias),parentAlias:tabAlias||null,sortOrder:lastGroupSortOrder,properties:[],parentTabContentTypes:[],parentTabContentTypeNames:[]};scope.model.groups=[].concat(_toConsumableArray(scope.model.groups),[group]),scope.activateGroup(group),notifyChanged()},scope.activateGroup=function(selectedGroup){selectedGroup&&(scope.model.groups.forEach(function(group){"init"!==group.tabState&&(group.tabState="inActive")}),selectedGroup.tabState="active")},scope.onChangeGroupName=function(group){updateGroupAlias(group)},scope.canRemoveGroup=function(group){return!0!==group.inherited&&null==_.find(group.properties,function(property){return!0===property.locked})},scope.removeGroup=function(selectedGroup){var groupName=selectedGroup.name||"",localizeMany=localizationService.localizeMany(["general_delete","contentTypeEditor_confirmDeleteGroupNotice"]),localize=localizationService.localize("contentTypeEditor_confirmDeleteGroupMessage",[groupName]);$q.all([localizeMany,localize]).then(function(values){var translations=values[0],message=values[1];overlayService.confirmDelete({title:"".concat(translations[0]," ").concat(groupName),content:message,confirmMessage:translations[1],submitButtonLabelKey:"actions_delete",submit:function submit(){var index=scope.model.groups.findIndex(function(group){return group.alias===selectedGroup.alias});scope.model.groups.splice(index,1),overlayService.close(),notifyChanged()}})})},scope.addGroupToActiveTab=function(){scope.addGroup(scope.openTabAlias)},scope.changeSortOrderValue=function(group){void 0!==group.sortOrder&&(group.showSortOrderMissing=!1),scope.model.groups=$filter("orderBy")(scope.model.groups,"sortOrder")},scope.onChangeGroupSortOrderValue=function(sortedGroup){var groupsInTab=scope.model.groups.filter(function(group){return group.parentAlias===sortedGroup.parentAlias}),otherGroups=scope.model.groups.filter(function(group){return group.parentAlias!==sortedGroup.parentAlias}),sortedGroups=$filter("orderBy")(groupsInTab,"sortOrder");scope.model.groups=[].concat(_toConsumableArray(otherGroups),_toConsumableArray(sortedGroups))},scope.addPropertyToActiveGroup=function(){var activeGroup=scope.model.groups.find(function(group){return"active"===group.tabState});!activeGroup&&scope.model.groups.length&&(activeGroup=scope.model.groups[0]),scope.addNewProperty(activeGroup)},scope.addProperty=function(property,group){var index=group.properties.indexOf(property),prevProperty=group.properties[index-1];property.sortOrder=index>0?prevProperty.sortOrder+1:0,scope.editPropertyTypeSettings(property,group)},scope.editPropertyTypeSettings=function(property,group){if(!property.inherited){var oldPropertyModel=Utilities.copy(property);void 0===oldPropertyModel.allowCultureVariant&&(oldPropertyModel.allowCultureVariant=scope.model.allowCultureVariant,oldPropertyModel.alias="");var propertyModel=Utilities.copy(property),propertySettings={title:"Property settings",property:propertyModel,contentType:scope.contentType,contentTypeName:scope.model.name,contentTypeAllowCultureVariant:scope.model.allowCultureVariant,contentTypeAllowSegmentVariant:scope.model.allowSegmentVariant,view:"views/common/infiniteeditors/propertysettings/propertysettings.html",size:"small",submit:function submit(model){if(property.inherited=!1,property.dialogIsOpen=!1,property.propertyState="active",property.label=propertyModel.label,property.alias=propertyModel.alias,property.description=propertyModel.description,property.config=propertyModel.config,property.editor=propertyModel.editor,property.view=propertyModel.view,property.dataTypeId=propertyModel.dataTypeId,property.dataTypeIcon=propertyModel.dataTypeIcon,property.dataTypeName=propertyModel.dataTypeName,property.validation.mandatory=propertyModel.validation.mandatory,property.validation.mandatoryMessage=propertyModel.validation.mandatoryMessage,property.validation.pattern=propertyModel.validation.pattern,property.validation.patternMessage=propertyModel.validation.patternMessage,property.showOnMemberProfile=propertyModel.showOnMemberProfile,property.memberCanEdit=propertyModel.memberCanEdit,property.isSensitiveData=propertyModel.isSensitiveData,property.isSensitiveValue=propertyModel.isSensitiveValue,property.allowCultureVariant=propertyModel.allowCultureVariant,property.allowSegmentVariant=propertyModel.allowSegmentVariant,property.labelOnTop=propertyModel.labelOnTop,model.updateSameDataTypes&&function updateSameDataTypes(newProperty){Utilities.forEach(scope.model.groups,function(group){Utilities.forEach(group.properties,function(property){property.dataTypeId===newProperty.dataTypeId&&(property.config=newProperty.config,property.editor=newProperty.editor,property.view=newProperty.view,property.dataTypeId=newProperty.dataTypeId,property.dataTypeIcon=newProperty.dataTypeIcon,property.dataTypeName=newProperty.dataTypeName)})})}(property),editorService.close(),group){!function addInitProperty(group){var addInitPropertyBool=!0;return Utilities.forEach(group.properties,function(property){"init"===property.propertyState&&(addInitPropertyBool=!1)}),addInitPropertyBool&&group.properties.push({label:null,alias:null,propertyState:"init",validation:{mandatory:!1,mandatoryMessage:null,pattern:null,patternMessage:null},labelOnTop:!1}),group}(group);var numberOfProperties=group.properties.length;group.properties[numberOfProperties-1].focus=!0}notifyChanged()},close:function close(){!1===_.isEqual(oldPropertyModel,propertyModel)?localizationService.localizeMany(["general_confirm","contentTypeEditor_propertyHasChanges","general_cancel","general_ok"]).then(function(data){var overlay={title:data[0],content:data[1],closeButtonLabel:data[2],submitButtonLabel:data[3],submitButtonStyle:"danger",close:function close(){overlayService.close()},submit:function submit(){overlayService.close(),editorService.close()}};overlayService.open(overlay)}):editorService.close()}};editorService.open(propertySettings),property.dialogIsOpen=!0}},scope.deleteProperty=function(properties,_ref3){var id=_ref3.id,propertyName=_ref3.label||"",localizeMany=localizationService.localizeMany(["general_delete"]),localize=localizationService.localize("contentTypeEditor_confirmDeletePropertyMessage",[propertyName]);$q.all([localizeMany,localize]).then(function(values){var translations=values[0],message=values[1];overlayService.confirmDelete({title:"".concat(translations[0]," ").concat(propertyName),content:message,submitButtonLabelKey:"actions_delete",submit:function submit(){var index=properties.findIndex(function(property){return property.id===id});properties.splice(index,1),notifyChanged(),overlayService.close()}})})},scope.onChangePropertySortOrderValue=function(group){group.properties=$filter("orderBy")(group.properties,"sortOrder")},eventBindings.push(scope.$watch("model",function(newValue,oldValue){void 0!==newValue&&void 0!==newValue.groups&&activate()})),eventBindings.push(eventsService.on("editors.dataTypeSettings.saved",function(name,args){(function hasPropertyOfDataTypeId(dataTypeId){return _.filter(scope.model.groups,function(group){return _.filter(group.properties,function(property){return property.dataTypeId===dataTypeId})}).length>0})(args.dataType.id)&&(scope.dataTypeHasChanged=!0)})),eventBindings.push(scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]();if(!0===scope.dataTypeHasChanged){var args={documentType:scope.model};eventsService.emit("editors.documentType.saved",args)}}))}}})}(),function(){angular.module("umbraco.directives").directive("umbIcon",function UmbIconDirective(iconHelper){return{replace:!0,transclude:!0,template:'<span aria-hidden="true" class="umb-icon"> <span class="umb-icon__inner {{icon}}"> <ng-transclude> <span ng-if="svgString" ng-bind-html="svgString"></span> <i ng-if="!svgString && icon" class="{{icon}}"></i> </ng-transclude> </span> </span> ',scope:{icon:"@",svgString:"=?"},link:function link(scope,element){if(void 0===scope.svgString&&null!==scope.svgString&&void 0!==scope.icon&&null!==scope.icon){var observer=new IntersectionObserver(function _lazyRequestIcon(entries,observer){entries.forEach(function(entry){if(!0===entry.isIntersecting){observer.disconnect();var icon=scope.icon.split(" ")[0];_requestIcon(icon)}})},{rootMargin:"100px"}),iconEl=element[0];observer.observe(iconEl),scope.$on("$destroy",function(){observer.disconnect()})}function _requestIcon(icon){scope.svgString=null,iconHelper.getIcon(icon).then(function(data){data&&data.svgString&&(scope.svgString=data.svgString)})}scope.$watch("icon",function(newValue,oldValue){if(newValue&&oldValue){var newicon=newValue.split(" ")[0];newicon!==oldValue.split(" ")[0]&&_requestIcon(newicon)}})}}})}(),function(){angular.module("umbraco.directives").directive("umbImageLazyLoad",function ImageLazyLoadDirective(){var placeholder="assets/img/transparent.png";return{restrict:"A",link:function link(scope,element,attrs){var observer=new IntersectionObserver(function loadImg(changes){changes.forEach(function(change){change.intersectionRatio>0&&change.target.src.indexOf(placeholder)>0&&(change.target.src=attrs.umbImageLazyLoad)})}),img=element[0];img.src=placeholder,observer.observe(img),scope.$on("$destroy",function(){observer.disconnect()})}}})}(),function(){angular.module("umbraco.directives").directive("umbKeyboardShortcutsOverview",function KeyboardShortcutsOverviewDirective(platformService,overlayService){return{restrict:"E",replace:!0,template:'<div class="umb-keyboard-shortcuts-overview flex items-center" data-hotkey="alt+shift+k" ng-click="toggleShortcutsOverlay()"> <div class="umb-keyboard-shortcuts-overview__description"><localize key="shortcuts_showShortcuts">show shortcuts</localize></div> <div class="umb-keyboard-keys"> <div class="umb-keyboard-key-wrapper"> <div class="umb-keyboard-key">alt</div> <div>+</div> </div> <div class="umb-keyboard-key-wrapper"> <div class="umb-keyboard-key">shift</div> <div>+</div> </div> <div class="umb-keyboard-key-wrapper"> <div class="umb-keyboard-key">k</div> </div> </div> </div> ',link:function link(scope,el,attr,ctrl){var eventBindings=[],isMac=platformService.isMac(),overlay=null;function onInit(){Utilities.forEach(scope.model,function(shortcutGroup){Utilities.forEach(shortcutGroup.shortcuts,function(shortcut){shortcut.platformKeys=[],isMac&&shortcut.keys&&shortcut.keys.mac?shortcut.platformKeys=shortcut.keys.mac:!isMac&&shortcut.keys&&shortcut.keys.win?shortcut.platformKeys=shortcut.keys.win:shortcut.keys&&shortcut&&shortcut.keys.length>0&&(shortcut.platformKeys=shortcut.keys)})})}scope.toggleShortcutsOverlay=function(){overlay?scope.close():scope.open(),scope.onToggle&&scope.onToggle()},scope.open=function(){overlay||(overlay={title:"Keyboard shortcuts",view:"keyboardshortcuts",hideSubmitButton:!0,shortcuts:scope.model,close:function close(){scope.close()}},overlayService.open(overlay))},scope.close=function(){overlay&&(overlayService.close(),overlay=null,scope.onClose&&scope.onClose())},onInit(),eventBindings.push(scope.$watch("model",function(newValue,oldValue){newValue!==oldValue&&onInit()})),eventBindings.push(scope.$watch("showOverlay",function(newValue,oldValue){newValue!==oldValue&&(!0===newValue&&scope.open(),!1===newValue&&scope.close())})),scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]()})},scope:{model:"=",onToggle:"&",showOverlay:"=?",onClose:"&"}}})}(),function(){angular.module("umbraco.directives").component("umbLayoutSelector",{template:'<div class="umb-layout-selector" ng-show="vm.showLayoutSelector"> <button type="button" aria-expanded="{{vm.layoutDropDownIsOpen}}" class="umb-layout-selector__active-layout umb-outline" ng-click="vm.toggleLayoutDropdown()"> <umb-icon icon="{{vm.activeLayout.icon}}"></umb-icon> <span class="sr-only"> <localize key="visuallyHiddenTexts_activeListLayout">Active layout:</localize>&nbsp; {{vm.activeLayout.name}} </span> </button> <div ng-if="vm.layoutDropDownIsOpen" class="umb-layout-selector__dropdown shadow-depth-3 animated -half-second fadeIn" on-outside-click="vm.closeLayoutDropdown()" deep-blur="vm.leaveLayoutDropdown()"> <button type="button" ng-repeat="layout in vm.layouts | filter: { selected: true } track by $id(layout)" class="umb-layout-selector__dropdown-item" ng-click="vm.pickLayout(layout)" ng-class="{\'-active\': layout.active }" ng-attr-title="{{layout.name}}"> <umb-icon icon="{{layout.icon}}" class="umb-layout-selector__dropdown-item-icon"></umb-icon> <span class="sr-only">{{layout.name}}</span> </button> </div> </div> ',controller:function LayoutSelectorController($scope,$element){var vm=this;function activate(){!function setVisibility(){1===function getNumberOfAllowedLayouts(layouts){for(var allowedLayouts=0,i=0;layouts.length>i;i++){var layout=layouts[i];!0===layout.selected&&allowedLayouts++}return allowedLayouts}(vm.layouts)&&(vm.showLayoutSelector=!1)}(),function setActiveLayout(layouts){for(var i=0;layouts.length>i;i++){var layout=layouts[i];layout.path===vm.activeLayout.path&&(layout.active=!0)}}(vm.layouts)}vm.$onInit=function onInit(){activate()},vm.layoutDropDownIsOpen=!1,vm.showLayoutSelector=!0,vm.pickLayout=function pickLayout(selectedLayout){vm.onLayoutSelect&&(vm.onLayoutSelect({layout:selectedLayout}),vm.layoutDropDownIsOpen=!1)},vm.toggleLayoutDropdown=function toggleLayoutDropdown(){vm.layoutDropDownIsOpen=!vm.layoutDropDownIsOpen},vm.leaveLayoutDropdown=function leaveLayoutDropdown(){vm.layoutDropDownIsOpen=!1},vm.closeLayoutDropdown=function closeLayoutDropdown(){vm.layoutDropDownIsOpen=!1}},controllerAs:"vm",bindings:{layouts:"<",activeLayout:"<",onLayoutSelect:"&"}})}(),function(){angular.module("umbraco.directives").directive("umbLightbox",function LightboxDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-lightbox"> <div class="umb-lightbox__backdrop" ng-click="close()" hotkey="esc"></div> <button type="button" class="btn-reset umb-lightbox__close" localize="title" title="@general_close" ng-click="close()"> <umb-icon icon="icon-delete" class="umb-lightbox__control"></umb-icon> <span class="sr-only"> <localize key="general_close">Close</localize> </span> </button> <div class="umb-lightbox__images"> <div class="umb-lightbox__image shadow-depth-2" ng-repeat="item in items" ng-show="$index === activeItemIndex"> <img ng-src="{{ item.source }}"> </div> </div> <button type="button" class="btn-reset umb-lightbox__control -prev" localize="title" title="@general_previous" ng-if="activeItemIndex > 0" ng-click="prev()" hotkey="left"> <umb-icon icon="icon-previous" class="umb-lightbox__control-icon"></umb-icon> <span class="sr-only"> <localize key="general_previous">Previous</localize> </span> </button> <button type="button" class="btn-reset umb-lightbox__control -next" localize="title" title="general_next" ng-if="activeItemIndex + 1 < items.length" ng-click="next()" hotkey="right"> <umb-icon icon="icon-next" class="umb-lightbox__control-icon"></umb-icon> <span class="sr-only"> <localize key="general_next">Next</localize> </span> </button> </div> ',scope:{items:"=",onClose:"=",activeItemIndex:"="},link:function link(scope,el,attr,ctrl){scope.next=function(){var nextItemIndex=scope.activeItemIndex+1;nextItemIndex<scope.items.length&&(scope.items[scope.activeItemIndex].active=!1,scope.items[nextItemIndex].active=!0,scope.activeItemIndex=nextItemIndex)},scope.prev=function(){var prevItemIndex=scope.activeItemIndex-1;prevItemIndex>=0&&(scope.items[scope.activeItemIndex].active=!1,scope.items[prevItemIndex].active=!0,scope.activeItemIndex=prevItemIndex)},scope.close=function(){scope.onClose&&scope.onClose()},function activate(){var eventBindings=[];el.appendTo("body"),scope.$on("$destroy",function(){for(var e in eventBindings)eventBindings[e]()})}()}}})}(),function(){angular.module("umbraco.directives").directive("umbListViewLayout",function ListViewLayoutDirective(){return{restrict:"E",replace:!0,template:'<div> <div ng-include="options.layout.activeLayout.path"></div> </div> ',scope:{contentId:"<",folders:"<",items:"<",selection:"<",options:"<",entityType:"@",onGetContent:"&"},link:function link(scope,el,attr,ctrl){scope.getContent=function(contentId){scope.onGetContent&&scope.onGetContent({contentId:contentId})}}}})}(),function(){angular.module("umbraco.directives").directive("umbListViewSettings",function ListViewSettingsDirective(dataTypeResource,dataTypeHelper,editorService,listViewPrevalueHelper){return{restrict:"E",replace:!0,template:'<div class="umb-list-view-settings"> <div class="umb-list-view-settings__trigger"> <umb-toggle checked="enableListView" on-click="toggle()" hotkey="alt+shift+l"> </umb-toggle> </div>  <div ng-if="enableListView" class="flex"> <div class="umb-list-view-settings__box"> <div class="flex"> <umb-icon icon="icon-list" class="umb-list-view-settings__list-view-icon"></umb-icon> <div> <div class="umb-list-view-settings__name"> {{dataType.name}} <em ng-if="!customListViewCreated">(<localize key="general_default">default</localize>)</em> </div> <button type="button" class="btn-link umb-list-view-settings__create-new" ng-if="!customListViewCreated" ng-click="createCustomListViewDataType()"> <localize key="editcontenttype_createListView">Create custom list view</localize> </button> <button type="button" class="btn-link umb-list-view-settings__remove-new" ng-if="customListViewCreated" ng-click="removeCustomListDataType()"> <localize key="editcontenttype_removeListView">Remove custom list view</localize> </button> </div> </div> <umb-load-indicator ng-show="loading"></umb-load-indicator> </div> <div class="umb-group-builder__property-actions"> <div class="umb-group-builder__property-action"> <button type="button" class="btn-icon" ng-click="showSettingsOverlay()" aria-label="Edit" localize="title" title="@general_edit"> <umb-icon icon="icon-settings"></umb-icon> </button> </div> </div> </div> </div> ',scope:{enableListView:"=",listViewName:"=",modelAlias:"=",contentType:"@"},link:function link(scope){scope.dataType={},scope.customListViewCreated=!1;var checkForCustomListView=function checkForCustomListView(){return function invariantEquals(a,b){return"string"==typeof a&&"string"==typeof b?0===a.localeCompare(b,void 0,{sensitivity:"base"}):a===b}(scope.dataType.name,"List View - "+scope.modelAlias)},setDataType=function setDataType(dataType){scope.dataType=dataType,listViewPrevalueHelper.setPrevalues(dataType.preValues)},showSettingsOverlay=function showSettingsOverlay(){var overlay={view:"views/components/umb-list-view-settings-overlay.html",hideDescription:!0,hideIcon:!0,size:"medium",dataType:scope.dataType,title:"List view settings",submit:function submit(model){var preValues=dataTypeHelper.createPreValueProps(model.dataType.preValues);dataTypeResource.save(model.dataType,preValues,!1).then(function(dataType){return scope.dataType=dataType}),editorService.close()},close:function close(){return editorService.close()}};editorService.open(overlay)};scope.createCustomListViewDataType=function(){scope.loading=!0,dataTypeResource.createCustomListView(scope.modelAlias).then(function(dataType){setDataType(dataType),scope.listViewName=dataType.name,scope.customListViewCreated=!0,showSettingsOverlay(),scope.loading=!1})},scope.removeCustomListDataType=function(){scope.loading=!0,dataTypeResource.deleteById(scope.dataType.id).then(function(dataType){scope.listViewName="List View - ".concat("documentType"===scope.contentType?"Content":"Media"),dataTypeResource.getByName(scope.listViewName).then(function(defaultDataType){setDataType(defaultDataType),scope.customListViewCreated=!1,scope.loading=!1})})},scope.toggle=function(){return scope.enableListView=!scope.enableListView},scope.showSettingsOverlay=function(){return showSettingsOverlay()};var unbindEnableListViewWatcher=scope.$watch("enableListView",function(newValue){void 0!==newValue&&function activate(){scope.enableListView?dataTypeResource.getByName(scope.listViewName).then(function(dataType){setDataType(dataType),scope.customListViewCreated=checkForCustomListView()}):scope.dataType={}}()});scope.$on("$destroy",function(){return unbindEnableListViewWatcher()})}}})}(),function(){angular.module("umbraco.directives").directive("umbLoader",function UmbLoaderDirective(){return{restrict:"E",replace:!0,template:"<div class=\"umb-loader-wrapper\" ng-class=\"{ '-top': position === 'top', '-bottom': position === 'bottom' }\"> <div class=\"umb-loader\"></div> </div> ",scope:{position:"@?"},link:function link(scope,el,attr,ctrl){}}})}(),function(){angular.module("umbraco.directives").directive("umbLoadIndicator",function UmbLoadIndicatorDirective(){return{restrict:"E",replace:!0,template:'<ul class="umb-load-indicator animated -half-second"> <li class="umb-load-indicator__bubble"></li> <li class="umb-load-indicator__bubble"></li> <li class="umb-load-indicator__bubble"></li> </ul> '}})}(),function(){angular.module("umbraco.directives").directive("umbLockedField",function LockedFieldDirective($timeout,localizationService){return{require:"ngModel",restrict:"E",replace:!0,template:'<ng-form name="lockedFieldForm" class="umb-locked-field"> <div class="umb-locked-field__wrapper"> <button aria-label="Unlock" ng-if="locked" ng-click="unlock()" class="umb-locked-field__toggle"> <umb-icon icon="icon-lock" class="umb-locked-field__lock-icon"></umb-icon> </button> <button aria-label="Lock" ng-if="!locked" ng-click="lock()" class="umb-locked-field__toggle"> <umb-icon icon="icon-unlocked" class="umb-locked-field__lock-icon -unlocked"></umb-icon> </button> <input type="text" no-password-manager class="umb-locked-field__input" name="lockedField" ng-model="ngModel" ng-disabled="locked" ng-class="{\'-unlocked\': !locked}" placeholder="{{placeholderText}}" val-regex="{{regexValidation}}" umb-auto-resize required val-server-field="{{serverValidationField}}" title="{{ngModel}}" focus-when="{{!locked}}" umb-select-when="{{!locked}}" ng-blur="lock()"> </div> <div ng-messages="lockedFieldForm.lockedField.$error" show-validation-on-submit> <div class="umb-validation-label" ng-class="{ \'-left\': validationPosition === \'left\', \'-right\': validationPosition === \'right\' }" ng-message="required"> <localize key="general_required">Required</localize> <localize key="content_alias">alias</localize> </div> <div class="umb-validation-label" ng-class="{ \'-left\': validationPosition === \'left\', \'-right\': validationPosition === \'right\' }" ng-if="regexValidation.length > 0" ng-message="valRegex"> <localize key="general_invalid">Invalid</localize> <localize key="content_alias">alias</localize> </div> <div class="umb-validation-label" ng-class="{ \'-left\': validationPosition === \'left\', \'-right\': validationPosition === \'right\' }" ng-if="serverValidationField.length > 0" ng-message="valServerField">{{lockedFieldForm.lockedField.errorMsg}} </div> </div> </ng-form> ',scope:{ngModel:"=",locked:"=?",placeholderText:"=?",regexValidation:"=?",validationPosition:"=?",serverValidationField:"@"},link:function link(scope,el,attr,ngModelCtrl){scope.lock=function(){scope.locked=!0},scope.unlock=function(){scope.locked=!1},function activate(){void 0!==scope.locked&&null!==scope.locked||(scope.locked=!0),void 0!==scope.regexValidation&&null!==scope.regexValidation||(scope.regexValidation="^[a-zA-Z]\\w.*$"),void 0!==scope.serverValidationField&&null!==scope.serverValidationField||(scope.serverValidationField=""),void 0!==scope.placeholderText&&null!==scope.placeholderText||(scope.placeholderText="Enter value..."),void 0!==scope.validationPosition&&null!==scope.validationPosition||(scope.validationPosition="left")}()}}})}(),function(){angular.module("umbraco.directives").directive("umbMediaGrid",function MediaGridDirective($filter,mediaHelper){return{restrict:"E",replace:!0,template:'<div class="media-list-grid"> <div data-element="media-grid" class="umb-media-grid" ng-show="!showMediaList"> <div data-element="media-grid-item-{{$index}}" class="umb-media-grid__item umb-outline umb-outline--surrounding" title="{{item.name}}" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{\'-selected\': item.selected, \'-file\': !item.thumbnail, \'-folder\': item.isFolder, \'-svg\': item.extension == \'svg\', \'-selectable\': item.selectable, \'-unselectable\': !item.selectable, \'-filtered\': item.filtered}"> <div data-element="media-grid-item-edit" class="umb-media-grid__item-overlay umb-outline" ng-class="{\'-locked\': item.selected || !item.file || !item.thumbnail, \'-can-open\': (item.isFolder ? allowOpenFolder : allowOpenFile)}" ng-click="clickItemName(item, $event, $index)" tabindex="{{item.isFolder && item.selectable ? \'0\' : \'-1\'}}"> <umb-icon icon="icon-info" class="umb-media-grid__info" ng-if="onDetailsHover" ng-mouseover="hoverItemDetails(item, $event, true)" ng-mouseleave="hoverItemDetails(item, $event, false)"> </umb-icon> <div class="umb-media-grid__item-name">{{item.name}}</div> </div>  <div class="umb-media-grid__item-select"></div>  <div class="umb-media-grid__image-background" ng-if="item.thumbnail || item.extension === \'svg\'"></div>  <img umb-image-lazy-load="{{item.thumbnail}}" class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="item.thumbnail" alt="{{item.name}}" draggable="false">  <img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="!item.thumbnail && item.extension === \'svg\'" ng-src="{{item.image}}" alt="{{item.name}}" draggable="false">  <img class="umb-media-grid__item-image-placeholder" ng-if="!item.thumbnail && item.extension !== \'svg\'" src="assets/img/transparent.png" alt="{{item.name}}" draggable="false">  <umb-file-icon ng-if="!item.thumbnail && item.extension !== \'svg\'" class="umb-media-grid__item-file-icon" extension="{{item.extension}}" icon="{{item.icon}}" size="s"> </umb-file-icon> </div> </div>  <div class="umb-media-grid__list-view" ng-show="showMediaList"> <div class="umb-table umb-table--condensed"> <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell"> <input class="umb-table__input" type="checkbox" ng-show="vm.allowSelectAll" ng-click="vm.selectAll($event)" ng-checked="vm.isSelectedAll()"> </div> <div class="umb-table-cell umb-table__name"> <button type="button" class="umb-table-head__link sortable" ng-click="setSort(\'name\')"> <localize key="general_name">Name</localize> <i class="umb-table-head__icon icon" aria-hidden="true" ng-class="{\'icon-navigation-up\': isSortDirection(\'name\', \'asc\'), \'icon-navigation-down\': isSortDirection(\'name\', \'desc\')}"></i> </button> </div> <div class="umb-table-cell"> <button type="button" class="umb-table-head__link sortable" ng-click="setSort(\'updateDate\')"> Last Updated <i class="umb-table-head__icon icon" aria-hidden="true" ng-class="{\'icon-navigation-up\': isSortDirection(\'updateDate\', \'asc\'), \'icon-navigation-down\': isSortDirection(\'updateDate\', \'desc\')}"></i> </button> </div> </div> </div> <div class="umb-table-body"> <div class="umb-table-row umb-media-grid__list-item -selectable" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy | orderBy:sortBy:sortReverse" ng-class="{\'-selected\': item.selected}"> <div class="umb-table-cell"> <umb-icon icon="icon-check" class="umb-table-body__icon umb-table-body__checkicon" ng-if="item.selected"></umb-icon> <umb-icon icon="{{item.thumbnail ? \'icon-picture\' : item.icon}}" class="umb-table-body__icon" ng-if="!item.selected"></umb-icon> </div> <div class="umb-table-cell umb-table__name"> <umb-icon icon="icon-navigation-right" ng-show="item.isFolder" ng-class="{\'-locked\': item.selected || !item.file || !item.thumbnail}" ng-click="clickItemName(item, $event, $index)"> </umb-icon> <span data-src="{{item.value.src}}" class="item-name">{{item.name}}</span> </div> <div class="umb-table-cell"> <span class="muted small" style="font-size:0.8em">{{item.updateDate | date:\'medium\'}}</span> </div> </div> </div> </div> </div> </div> ',scope:{items:"=",onDetailsHover:"=",onClick:"=",onClickName:"=",allowOpenFolder:"=",allowOpenFile:"=",filterBy:"=",itemMaxWidth:"@",itemMaxHeight:"@",itemMinWidth:"@",itemMinHeight:"@",disableFolderSelect:"@",onlyImages:"@",onlyFolders:"@",includeSubFolders:"@",currentFolderId:"@",showMediaList:"="},link:function link(scope,el,attr,ctrl){var itemDefaultHeight=200,itemDefaultWidth=200,itemMaxWidth=200,itemMaxHeight=200,itemMinWidth=125,itemMinHeight=125;function activate(){scope.itemMaxWidth&&(itemMaxWidth=scope.itemMaxWidth),scope.itemMaxHeight&&(itemMaxHeight=scope.itemMaxHeight),scope.itemMinWidth&&(itemMinWidth=scope.itemMinWidth),scope.itemMinHeight&&(itemMinHeight=scope.itemMinHeight);for(var i=0;scope.items.length>i;i++){var item=scope.items[i];setItemData(item),setOriginalSize(item),item.selectable=getSelectableState(item),"true"!==scope.onlyImages||item.isFolder||item.thumbnail||(scope.items.splice(i,1),i--),void 0!==scope.includeSubFolders&&"true"!==scope.includeSubFolders&&item.parentId!==parseInt(scope.currentFolderId)&&(scope.items.splice(i,1),i--)}scope.items.length>0&&function setFlexValues(mediaItems){var flexSortArray=mediaItems,smallestImageWidth=null,widestImageAspectRatio=null;flexSortArray=$filter("orderBy")(flexSortArray,"width",!0),widestImageAspectRatio=flexSortArray[0].aspectRatio,smallestImageWidth=flexSortArray[flexSortArray.length-1].width;for(var i=0;flexSortArray.length>i;i++){var mediaItem=flexSortArray[i],flex=1/(widestImageAspectRatio/mediaItem.aspectRatio);0===flex&&(flex=1);var imageMinFlexWidth=smallestImageWidth*flex,flexStyle={flex:flex+" 1 "+imageMinFlexWidth+"px","max-width":mediaItem.width+"px","min-width":itemMinWidth+"px","min-height":itemMinHeight+"px"};mediaItem.flexStyle=flexStyle}}(scope.items)}function setItemData(item){if(item.image?item.isFolder=!1:item.isFolder=!mediaHelper.hasFilePropertyType(item),!item.isFolder&&!item.thumbnail)if(item.image)item.thumbnail=mediaHelper.resolveFileFromEntity(item,!0),item.extension=mediaHelper.getFileExtension(item.image);else{item.thumbnail=mediaHelper.resolveFile(item,!0),item.image=mediaHelper.resolveFile(item,!1);var fileProp=_.find(item.properties,function(v){return"umbracoFile"===v.alias});fileProp&&fileProp.value&&(item.file=fileProp.value);var extensionProp=_.find(item.properties,function(v){return"umbracoExtension"===v.alias});extensionProp&&extensionProp.value&&(item.extension=extensionProp.value)}}function getSelectableState(item){return!item.filtered&&(!0===item.isFolder?"true"!==scope.disableFolderSelect&&"true"!==scope.onlyImages:"true"!==scope.onlyFolders)}function setOriginalSize(item,maxHeight){item.width=itemDefaultWidth,item.height=itemDefaultHeight,item.aspectRatio=1;var widthProp=_.find(item.properties,function(v){return"umbracoWidth"===v.alias});widthProp&&widthProp.value&&(item.width=parseInt(widthProp.value,10),isNaN(item.width)&&(item.width=itemDefaultWidth));var heightProp=_.find(item.properties,function(v){return"umbracoHeight"===v.alias});heightProp&&heightProp.value&&(item.height=parseInt(heightProp.value,10),isNaN(item.height)&&(item.height=itemDefaultWidth)),item.aspectRatio=item.width/item.height,item.aspectRatio>=1?item.width>itemMaxWidth&&(item.width=itemMaxWidth,item.height=itemMaxWidth/item.aspectRatio):item.height>itemMaxHeight&&(item.height=itemMaxHeight,item.width=itemMaxHeight*item.aspectRatio)}scope.clickItem=function(item,$event,$index){!0===item.isFolder&&item.filtered&&scope.clickItemName(item,$event,$index),scope.onClick&&(scope.onClick(item,$event,$index),$event.stopPropagation())},scope.clickItemName=function(item,$event,$index){scope.onClickName&&(scope.onClickName(item,$event,$index),$event.stopPropagation())},scope.hoverItemDetails=function(item,$event,hover){scope.onDetailsHover&&scope.onDetailsHover(item,$event,hover)};var unbindItemsWatcher=scope.$watch("items",function(newValue,oldValue){Utilities.isArray(newValue)&&activate()});scope.$on("$destroy",function(){unbindItemsWatcher()}),scope.sortColumn="name",scope.sortReverse=!1,scope.sortDirection="asc",scope.isSortDirection=function(col,direction){return col===scope.sortColumn&&direction===scope.sortDirection},scope.setSort=function(col){scope.sortColumn===col?scope.sortReverse=!scope.sortReverse:(scope.sortColumn=col,scope.sortReverse="updateDate"===col),scope.sortDirection=scope.sortReverse?"desc":"asc"},scope.sortBy=function(item){return"updateDate"===scope.sortColumn?[-item.isFolder,item.updateDate]:[-item.isFolder,item.name]}}}})}(),function(){angular.module("umbraco.directives").directive("umbMiniListView",function MiniListViewDirective(entityResource,iconHelper){return{restrict:"E",replace:!0,template:'<div class="umb-minilistview"> <div class="umb-mini-list-view umb-animated" ng-class="{\'umb-mini-list-view--forward\': listViewAnimation === \'in\', \'umb-mini-list-view--backwards\': listViewAnimation === \'out\'}" ng-repeat="miniListView in miniListViews"> <div class="umb-mini-list-view__title"> <umb-icon icon="{{miniListView.node.icon}}" class="umb-mini-list-view__title-icon"></umb-icon> <h4 class="umb-mini-list-view__title-text">{{ miniListView.node.name }}</h4> </div> <div class="umb-mini-list-view__breadcrumb"> <button type="button" ng-if="showBackButton()" class="btn-reset umb-mini-list-view__back" ng-click="exitMiniListView()"> <umb-icon icon="icon-arrow-left" class="umb-mini-list-view__back-icon"></umb-icon> <span class="umb-mini-list-view__back-text"><localize key="general_back">Back</localize></span> / </button> <umb-breadcrumbs ng-if="breadcrumb && breadcrumb.length > 0" ancestors="breadcrumb" entity-type="content" on-open="clickBreadcrumb(ancestor)"> </umb-breadcrumbs> </div> <div class="umb-table umb-table--condensed">  <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell no-display"></div> <div class="umb-table-cell umb-table-cell-padding"> <form class="flex w-100 -no-margin-bottom" novalidate> <div class="flex-auto"> <umb-search-filter input-id="mini-listview-search" model="search" label-key="general_typeToSearch" text="Type to search..." on-change="searchMiniListView(search, miniListView)" css-class="w-100 mb-15" auto-focus="true"> </umb-search-filter> </div> </form> </div> </div> </div>  <div class="umb-table-body">  <div class="umb-table__loading-overlay" ng-if="miniListView.loading && miniListView.children.length > 0"> <umb-load-indicator></umb-load-indicator> </div>  <div class="umb-table-row cursor-pointer umb-outline" ng-repeat="child in miniListView.children" ng-click="selectNode(child)" ng-class="{\'-selected\':child.selected, \'not-allowed\':!child.allowed}"> <div class="umb-table-cell umb-table-cell--auto-width" ng-class="{\'umb-table-cell--faded\':child.published === false}"> <div class="flex items-center"> <umb-icon icon="icon-navigation-right" class="umb-table__row-expand" ng-click="openNode($event, child)" ng-class="{\'umb-table__row-expand--hidden\': child.metaData.hasChildren !== true}">&nbsp;</umb-icon> <umb-icon icon="{{child.icon}}" class="umb-table-body__icon umb-table-body__fileicon"></umb-icon> <umb-icon icon="icon-check" class="umb-table-body__icon umb-table-body__checkicon"></umb-icon> </div> </div> <div class="umb-table-cell black" ng-class="{\'umb-table-cell--faded\':child.published === false}">{{ child.name }}</div> </div>  <div ng-if="!miniListView.loading && miniListView.children.length === 0" class="umb-table-row umb-table-row--empty"> <span ng-if="search === \'\'"><localize key="general_noItemsInList">No items have been added</localize></span> <span ng-if="search !== \'\'"><localize key="general_searchNoResult">Sorry, we can not find what you are looking for.</localize></span> </div>  <div ng-if="miniListView.loading && miniListView.children.length === 0" class="umb-table-row umb-table-row--empty"> <umb-load-indicator></umb-load-indicator> </div> </div> </div> <div class="flex justify-center"> <umb-pagination ng-if="miniListView.pagination.totalPages > 0 && !miniListView.loading" page-number="miniListView.pagination.pageNumber" total-pages="miniListView.pagination.totalPages" on-change="goToPage(pageNumber, miniListView)"> </umb-pagination> </div> </div> </div> ',scope:{node:"=",entityType:"@",startNodeId:"=",onSelect:"&",onClose:"&",onItemsLoaded:"&",entityTypeFilter:"="},link:function link(scope,el,attr,ctrl){scope.search="",scope.miniListViews=[],scope.breadcrumb=[],scope.listViewAnimation="";var miniListViewsHistory=[];function open(node){node&&node.icon&&(node.icon=iconHelper.convertFromLegacyIcon(node.icon));var miniListView={node:node,loading:!0,pagination:{pageSize:10,pageNumber:1,filter:"",orderDirection:"Ascending",orderBy:"SortOrder",orderBySystemField:!0}};scope.miniListViews=[],scope.listViewAnimation="in",scope.miniListViews.push(miniListView),miniListViewsHistory.push(miniListView),getChildrenForMiniListView(miniListView),makeBreadcrumb()}function getChildrenForMiniListView(miniListView){miniListView.loading=!0,entityResource.getPagedChildren(miniListView.node.id,scope.entityType,miniListView.pagination).then(function(data){data.items||(data.items=[]),scope.onItemsLoaded&&scope.onItemsLoaded({items:data.items}),miniListView.children=data.items,miniListView.children.forEach(function(c){if(c.allowed=!0,c.icon&&(c.icon=iconHelper.convertFromLegacyIcon(c.icon)),c.metaData&&(c.hasChildren=c.metaData.hasChildren,"Document"===scope.entityType&&(c.published=c.metaData.IsPublished)),scope.entityTypeFilter&&scope.entityTypeFilter.filter&&!scope.entityTypeFilter.filterAdvanced){var found=scope.entityTypeFilter.filter.toLowerCase().replace(/\s/g,"").split(",").indexOf(c.metaData.ContentTypeAlias.toLowerCase())>=0;(!scope.entityTypeFilter.filterExclude&&!found||scope.entityTypeFilter.filterExclude&&found)&&(c.allowed=!1)}}),scope.entityTypeFilter&&scope.entityTypeFilter.filter&&scope.entityTypeFilter.filterAdvanced&&(Utilities.isFunction(scope.entityTypeFilter.filter)?_.filter(miniListView.children,scope.entityTypeFilter.filter):_.where(miniListView.children,scope.entityTypeFilter.filter)).forEach(function(node){return node.allowed=!1}),miniListView.pagination.totalItems=data.totalItems,miniListView.pagination.totalPages=data.totalPages,miniListView.loading=!1})}function makeBreadcrumb(){scope.breadcrumb=[],Utilities.forEach(miniListViewsHistory,function(historyItem){scope.breadcrumb.push(historyItem.node)})}scope.openNode=function(event,node){open(node),event.stopPropagation()},scope.selectNode=function(node){scope.onSelect&&node.allowed&&scope.onSelect({node:node})},scope.goToPage=function(pageNumber,miniListView){miniListView.pagination.pageNumber=pageNumber,getChildrenForMiniListView(miniListView)},scope.clickBreadcrumb=function(ancestor){var found=!1;scope.listViewAnimation="out",Utilities.forEach(miniListViewsHistory,function(historyItem,index){historyItem.node.id.toString()===ancestor.id.toString()&&(scope.miniListViews=[],scope.miniListViews.push(historyItem),miniListViewsHistory.splice(index+1,miniListViewsHistory.length),found=!0)}),found||scope.exitMiniListView(),makeBreadcrumb()},scope.showBackButton=function(){return!(scope.node.metaData&&scope.node.metaData.IsContainer||scope.node.isContainer)},scope.exitMiniListView=function(){miniListViewsHistory=[],scope.miniListViews=[],scope.onClose&&scope.onClose()},scope.searchMiniListView=function(search,miniListView){miniListView.pagination.filter=search,miniListView.pagination.pageNumber=1,miniListView.loading=!0,searchMiniListView(miniListView)};var searchMiniListView=_.debounce(function(miniListView){scope.$apply(function(){getChildrenForMiniListView(miniListView)})},500);!function onInit(){open(scope.node)}()}}})}(),function(){angular.module("umbraco").component("umbMiniSearch",{template:'<ng-form class="umb-mini-search" ng-class="{\'--has-value\': vm.model !== null && vm.model !== \'\'}" novalidate> <umb-icon icon="icon-search" class="icon"></umb-icon> <label class="sr-only" for="{{vm.inputId}}"> {{vm.text}} </label> <input type="text" id="{{vm.inputId}}" class="form-control search-input" localize="placeholder,label" label="@general_typeToSearch" placeholder="@general_typeToSearch" ng-model="vm.model" ng-change="vm.onChange()" ng-keydown="vm.onKeyDown($event)" ng-blur="vm.onBlur($event)" prevent-enter-submit no-dirty-check> </ng-form> ',controller:function UmbMiniSearchController($scope,localizationService){var vm=this;vm.onKeyDown=function onKeyDown(evt){switch(evt.keyCode){case 13:vm.onSearch&&vm.onSearch()}},vm.onChange=function onChange(){vm.onStartTyping&&vm.onStartTyping();searchDelay()},vm.$onInit=function onInit(){vm.inputId=vm.inputId||"search_"+String.CreateGuid(),function setText(){var keyToLocalize=vm.labelKey||"general_search";localizationService.localize(keyToLocalize).then(function(data){-1===data.indexOf("[")&&(vm.text=data)})}()};var searchDelay=_.debounce(function(){$scope.$apply(function(){vm.onSearch&&vm.onSearch()})},500)},controllerAs:"vm",bindings:{model:"=",onStartTyping:"&?",onSearch:"&?",onBlur:"&?",labelKey:"@?",inputId:"@?"}})}(),angular.module("umbraco.directives").directive("umbNestedContentEditor",[function(){return{restrict:"E",replace:!0,templateUrl:Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath+"/views/propertyeditors/nestedcontent/nestedcontent.editor.html",scope:{ngModel:"=",tabAlias:"="},link:function link($scope){$scope.model=Utilities.copy($scope.ngModel),$scope.nodeContext=$scope.model;var selectedTab=$scope.model.variants[0].tabs[0];$scope.tabAlias&&Utilities.forEach($scope.model.variants[0].tabs,function(tab){tab.alias.toLowerCase()!==$scope.tabAlias.toLowerCase()||(selectedTab=tab)}),$scope.tab=selectedTab;var unsubscribe=$scope.$on("ncSyncVal",function(ev,args){args.key===$scope.model.key&&($scope.$broadcast("formSubmitting",{scope:$scope}),Utilities.forEach($scope.ngModel.variants[0].tabs,function(tab){if(tab.alias.toLowerCase()===selectedTab.alias.toLowerCase()){var localPropsMap=selectedTab.properties.reduce(function(map,obj){return map[obj.alias]=obj,map},{});Utilities.forEach(tab.properties,function(prop){localPropsMap.hasOwnProperty(prop.alias)&&(prop.value=localPropsMap[prop.alias].value)})}}))});$scope.$on("$destroy",function(){unsubscribe()})}}}]),function(){angular.module("umbraco.directives").directive("umbNodePreview",function NodePreviewDirective(userService){return{restrict:"E",replace:!0,template:'<div class="umb-node-preview" ng-class="{\'umb-node-preview--sortable\': sortable, \'umb-node-preview--unpublished\': published === false }"> <div class="flex">  <umb-icon ng-if="icon" icon="{{icon}}" class="umb-node-preview__icon"></umb-icon> <div class="umb-node-preview__content"> <div class="umb-node-preview__name" ng-attr-title="{{nodeNameTitle}}">{{name}}</div> <div class="umb-node-preview__description" ng-if="description">{{description}}</div> <div class="umb-user-group-preview__permissions" ng-if="permissions"> <span> <span class="bold"><localize key="general_rights">Permissions</localize>:</span> <span ng-repeat="permission in permissions" class="umb-user-group-preview__permission">{{permission.name}}</span> </span> </div> </div> </div> <div class="umb-node-preview__actions">  <a class="umb-node-preview__action" ng-href="{{editUrl}}" ng-if="allowEdit && editUrl" ng-click="onEdit()"> <localize key="general_edit">Edit</localize><span class="sr-only">&nbsp;{{name}}</span> </a> <button type="button" class="umb-node-preview__action" ng-if="allowEdit && !editUrl" ng-click="onEdit()"> <localize key="general_edit">Edit</localize><span class="sr-only">&nbsp;{{name}}...</span> </button>  <a class="umb-node-preview__action" ng-href="{{openUrl}}" ng-if="allowOpen && openUrl" ng-click="onOpen()"> <localize key="general_open">Open</localize><span class="sr-only">&nbsp;{{name}}</span> </a> <button type="button" class="umb-node-preview__action" ng-if="allowOpen && !openUrl" ng-click="onOpen()"> <localize key="general_open">Open</localize><span class="sr-only">&nbsp;{{name}}...</span> </button>  <a class="umb-node-preview__action umb-node-preview__action--red" ng-href="{{removeUrl}}" ng-if="allowRemove && removeUrl" ng-click="onRemove()"> <localize key="general_remove">Remove</localize><span class="sr-only">&nbsp;{{name}}</span> </a> <button type="button" class="umb-node-preview__action umb-node-preview__action--red" ng-if="allowRemove && !removeUrl" ng-click="onRemove()"> <localize key="general_remove">Remove</localize><span class="sr-only">&nbsp;{{name}}</span> </button> </div> </div> ',scope:{icon:"=?",name:"=",alias:"=?",description:"=?",permissions:"=?",published:"=?",sortable:"=?",allowOpen:"=?",allowRemove:"=?",allowEdit:"=?",onOpen:"&?",onRemove:"&?",onEdit:"&?",openUrl:"=?",editUrl:"=?",removeUrl:"=?"},link:function link(scope,el,attr,ctrl){scope.editLabelKey||(scope.editLabelKey="general_edit"),scope.nodeNameTitle=null,Umbraco.Sys.ServerVariables.isDebuggingEnabled&&userService.getCurrentUser().then(function(u){-1!==u.allowedSections.indexOf("settings")&&(scope.nodeNameTitle=scope.alias)})}}})}(),function(){angular.module("umbraco.directives").directive("umbPagination",function PaginationDirective(localizationService){return{restrict:"E",replace:!0,template:'<div class="umb-pagination pagination"> <div ng-show="pagination.length > 1"> <ul> <li ng-class="{disabled:pageNumber <= 1}"> <button type="button" class="btn-reset" ng-disabled="pageNumber <= 1" ng-click="prev()"> <localize key="general_previous">Previous</localize> </button> </li> <li ng-repeat="pgn in pagination track by $index" ng-class="{active:pgn.isActive}"> <button type="button" class="btn-reset" ng-click="goToPage(pgn.val - 1)" ng-bind="pgn.name ? pgn.name : pgn.val" ng-disabled="pgn.val === pageNumber" ng-if="pgn.val != \'...\'"> </button> <span ng-bind="pgn.val" ng-if="pgn.val == \'...\'"></span> </li> <li ng-class="{disabled:pageNumber >= totalPages}"> <button type="button" class="btn-reset" ng-disabled="pageNumber >= totalPages" ng-click="next()"> <localize key="general_next">Next</localize> </button> </li> </ul> </div> </div> ',scope:{pageNumber:"=",totalPages:"=",onNext:"=",onPrev:"=",onGoToPage:"=",onChange:"&"},link:function link(scope,el,attr,ctrl){function activate(){scope.pageNumber&&(scope.pageNumber=parseInt(scope.pageNumber));var tempPagination=[],i=0;if(scope.totalPages<=10)for(i=0;i<scope.totalPages;i++)tempPagination.push({val:i+1,isActive:scope.pageNumber===i+1});else{var maxIndex=scope.totalPages-10,start=Math.max(scope.pageNumber-5,0);for(i=start=Math.min(maxIndex,start);i<10+start;i++)tempPagination.push({val:i+1,isActive:scope.pageNumber===i+1});start>0&&localizationService.localize("general_first").then(function(value){var firstLabel=value;tempPagination.unshift({name:firstLabel,val:1,isActive:!1},{val:"...",isActive:!1})}),start<maxIndex&&localizationService.localize("general_last").then(function(value){var lastLabel=value;tempPagination.push({val:"...",isActive:!1},{name:lastLabel,val:scope.totalPages,isActive:!1})})}scope.pagination=tempPagination}scope.next=function(){scope.pageNumber<scope.totalPages&&(scope.pageNumber++,scope.onNext&&scope.onNext(scope.pageNumber),scope.onChange&&scope.onChange({pageNumber:scope.pageNumber}))},scope.prev=function(pageNumber){scope.pageNumber>1&&(scope.pageNumber--,scope.onPrev&&scope.onPrev(scope.pageNumber),scope.onChange&&scope.onChange({pageNumber:scope.pageNumber}))},scope.goToPage=function(pageNumber){scope.pageNumber=pageNumber+1,scope.onGoToPage&&scope.onGoToPage(scope.pageNumber),scope.onChange&&scope.onChange({pageNumber:scope.pageNumber})};var unbindPageNumberWatcher=scope.$watchCollection("[pageNumber, totalPages]",function(newValues,oldValues){activate()});scope.$on("$destroy",function(){unbindPageNumberWatcher()}),activate()}}})}(),function(){angular.module("umbraco.directives").directive("umbProgressBar",function ProgressBarDirective(){return{restrict:"E",replace:!0,template:'<span class="umb-progress-bar umb-progress-bar--{{size}}"> <span class="umb-progress-bar__progress umb-progress-bar__progress--{{color}}" ng-style="{\'width\': percentage + \'%\'}"></span> </span> ',scope:{percentage:"@",size:"@?",color:"@?"}}})}(),function(){angular.module("umbraco.directives").directive("umbProgressCircle",function ProgressCircleDirective($http,$timeout){return{restrict:"E",replace:!0,template:'<div class="umb-progress-circle" ng-style="{\'width\': size, \'height\': size, \'line-height\': size + \'px\' }"> <svg class="umb-progress-circle__view-box" viewBox="0 0 100 100"> <circle class="umb-progress-circle__bg" cx="50" cy="50" r="47" fill="none" stroke-width="6"></circle> <circle class="umb-progress-circle__highlight umb-progress-circle__highlight--{{ color }}" cx="50" cy="50" r="47" fill="none" stroke-width="6" stroke-dasharray="{{ strokeDashArray }}" stroke-dashoffset="{{ strokeDashOffset }}"></circle> </svg> <div ng-style="{\'font-size\': percentageSize}" class="umb-progress-circle__percentage">{{ percentage }}%</div> </div>',scope:{percentage:"@",size:"@?",color:"@?"},link:function link(scope,element,$filter){!function onInit(){var percent=scope.percentage;percent>100?percent=100:percent<0&&(percent=0);var strokeDashArray=element.find(".umb-progress-circle__highlight").attr("r")*Math.PI*2;scope.strokeDashArray=strokeDashArray;var strokeDashOffset=strokeDashArray-percent/100*strokeDashArray;scope.strokeDashOffset=strokeDashOffset,scope.percentageSize=.3*scope.size+"px"}()}}})}(),function(){var umbRangeSlider={template:'<div class="umb-range-slider"></div>',controller:function UmbRangeSliderController($element,$timeout,$scope,assetsService){var ctrl=this,sliderInstance=null;function grabElementAndRun(){$timeout(function(){var element=$element.find(".umb-range-slider")[0];!function setSlider(element){sliderInstance=element;var options=ctrl.options?ctrl.options:{start:[0],step:1,range:{min:[0],max:[100]}};noUiSlider.create(sliderInstance,options),function mergeTooltips(slider,threshold,separator){var textIsRtl="rtl"===getComputedStyle(slider).direction,isRtl="rtl"===slider.noUiSlider.options.direction,isVertical="vertical"===slider.noUiSlider.options.orientation,tooltips=slider.noUiSlider.getTooltips(),origins=slider.noUiSlider.getOrigins();tooltips.forEach(function(tooltip,index){tooltip&&origins[index].appendChild(tooltip)}),slider.noUiSlider.on("update",function(values,handle,unencoded,tap,positions){var pools=[[]],poolPositions=[[]],poolValues=[[]],atPool=0;tooltips[0]&&(pools[0][0]=0,poolPositions[0][0]=positions[0],poolValues[0][0]=values[0]);for(var i=1;i<positions.length;i++)(!tooltips[i]||positions[i]-positions[i-1]>threshold)&&(pools[++atPool]=[],poolValues[atPool]=[],poolPositions[atPool]=[]),tooltips[i]&&(pools[atPool].push(i),poolValues[atPool].push(values[i]),poolPositions[atPool].push(positions[i]));pools.forEach(function(pool,poolIndex){for(var handlesInPool=pool.length,j=0;j<handlesInPool;j++){var handleNumber=pool[j];if(j===handlesInPool-1){var offset=0;poolPositions[poolIndex].forEach(function(value){offset+=1e3-10*value});var direction=isVertical?"bottom":"right",last=isRtl?0:handlesInPool-1,lastOffset=1e3-10*poolPositions[poolIndex][last];offset=(textIsRtl&&!isVertical?100:0)+offset/handlesInPool-lastOffset;var tooltipValues=poolValues[poolIndex].filter(function(v,i,a){return a.indexOf(v)===i});tooltips[handleNumber].innerHTML=tooltipValues.join(separator),tooltips[handleNumber].style.display="block",tooltips[handleNumber].style[direction]=offset+"%"}else tooltips[handleNumber].style.display="none"}})})}(sliderInstance,15," - "),ctrl.onSetup&&ctrl.onSetup({slider:sliderInstance});ctrl.ngModel&&sliderInstance.noUiSlider.set(ctrl.ngModel);$(element).on("$destroy",function(){sliderInstance.noUiSlider.off()}),function setUpCallbacks(){sliderInstance&&(ctrl.onUpdate&&sliderInstance.noUiSlider.on("update",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onUpdate({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onSlide&&sliderInstance.noUiSlider.on("slide",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onSlide({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onSet&&sliderInstance.noUiSlider.on("set",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onSet({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onChange&&sliderInstance.noUiSlider.on("change",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onChange({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onDrag&&sliderInstance.noUiSlider.on("drag",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onDrag({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onStart&&sliderInstance.noUiSlider.on("start",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onStart({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}),ctrl.onEnd&&sliderInstance.noUiSlider.on("end",function(values,handle,unencoded,tap,positions){$timeout(function(){ctrl.onEnd({values:values,handle:handle,unencoded:unencoded,tap:tap,positions:positions})})}))}(),$scope.$applyAsync()}(element)},0,!0)}ctrl.$onInit=function(){assetsService.loadCss("lib/nouislider/nouislider.min.css",$scope),assetsService.loadJs("lib/nouislider/nouislider.min.js",$scope).then(function(){grabElementAndRun()})}},bindings:{ngModel:"<",options:"<",onSetup:"&?",onUpdate:"&?",onSlide:"&?",onSet:"&?",onChange:"&?",onDrag:"&?",onStart:"&?",onEnd:"&?"}};angular.module("umbraco.directives").component("umbRangeSlider",umbRangeSlider)}(),function(){angular.module("umbraco.directives").directive("umbStickyBar",function StickyBarDirective(){var headerObserver,setClass=function setClass(addClass,current){return current.classList.toggle("umb-sticky-bar--active",addClass)},addSentinel=function addSentinel(current){var sentinel=document.createElement("div");sentinel.classList.add("umb-sticky-sentinel","-top"),current.parentElement.prepend(sentinel)},observeHeader=function observeHeader(current,container){(headerObserver=new IntersectionObserver(function(records,observer){var _ref=[records[0].boundingClientRect,records[0].rootBounds],target=_ref[0],rootBounds=_ref[1];rootBounds&&target&&(target.bottom<rootBounds.top&&setClass(!0,current),target.bottom>=rootBounds.top&&target.bottom<rootBounds.bottom&&setClass(!1,current))},{threshold:[0],root:container})).observe(current.parentElement.querySelector(".umb-sticky-sentinel.-top"))};return{restrict:"A",link:function link(scope,el,attr,ctrl){var current=el[0],container=current.closest(".umb-editor-container")||current.closest(".umb-dashboard");container&&(addSentinel(current),observeHeader(current,container)),scope.$on("$destroy",function(){headerObserver.disconnect()})}}})}(),function(){angular.module("umbraco.directives").component("umbTable",{template:'<div> <div class="umb-table" ng-if="vm.items">  <div class="umb-table-head"> <div class="umb-table-row"> <div class="umb-table-cell"> <button type="button" class="umb-table__action" ng-show="vm.allowSelectAll" ng-click="vm.selectAll()"> <umb-checkmark checked="vm.isSelectedAll()" size="xs"></umb-checkmark> </button> </div> <div class="umb-table-cell umb-table__name"> <button type="button" class="umb-table-head__link sortable" ng-click="vm.sort(\'Name\', true, true)"> <localize key="general_name">Name</localize> <i class="umb-table-head__icon icon" aria-hidden="true" ng-class="{\'icon-navigation-up\': vm.isSortDirection(\'Name\', \'asc\'), \'icon-navigation-down\': vm.isSortDirection(\'Name\', \'desc\')}"></i> </button> </div> <div class="umb-table-cell" ng-show="vm.items[0].state"> <localize key="general_status">Status</localize> </div> <div class="umb-table-cell" ng-repeat="column in vm.itemProperties track by column.alias"> <button type="button" class="umb-table-head__link" ng-click="vm.sort(column.alias, column.allowSorting, column.isSystem)" ng-class="{\'sortable\':column.allowSorting}"> <span ng-bind="column.header"></span> <i class="umb-table-head__icon icon" aria-hidden="true" ng-class="{\'icon-navigation-up\': vm.isSortDirection(column.alias, \'asc\'), \'icon-navigation-down\': vm.isSortDirection(column.alias, \'desc\')}"></i> </button> </div> </div> </div>  <div class="umb-table-body"> <div class="umb-table-row -selectable umb-outline" ng-repeat="item in vm.items track by $index" ng-init="item.icon = vm.getIcon(item)" ng-class="{\'-selected\':item.selected, \'-light\':!item.published && item.updater != null}" ng-click="vm.selectItem(item, $index, $event)"> <div class="umb-table-cell"> <umb-icon icon="{{item.icon}}" class="umb-table-body__icon umb-table-body__fileicon" ng-if="!item.selected"></umb-icon> <umb-icon icon="icon-check" class="umb-table-body__icon umb-table-body__checkicon" ng-if="item.selected"></umb-icon> </div> <div class="umb-table-cell umb-table__name"> <a title="{{item.name}}" class="umb-table-body__link" ng-href="{{\'#\' + item.editPath}}" ng-click="vm.clickItem(item, $event)" ng-bind="item.name"> </a> </div> <div class="umb-table-cell" ng-show="item.state"> <umb-variant-state variant="item"> </umb-variant-state> </div> <div class="umb-table-cell" ng-repeat="column in vm.itemProperties track by column.alias"> <span title="{{column.header}}: {{item[column.alias]}}"> <div ng-if="!column.isSensitive"> {{item[column.alias]}} </div> <em ng-show="column.isSensitive" class="muted"> <localize key="content_isSensitiveValue_short"></localize> </em> </span> </div> </div> </div> </div>  <umb-empty-state ng-hide="vm.items" position="center"> <localize key="content_listViewNoItems">There are no items show in the list.</localize> </umb-empty-state> </div> ',controller:function TableController(iconHelper){var vm=this;vm.clickItem=function(item,$event){!vm.onClick||$event.metaKey||$event.ctrlKey||(vm.onClick({item:item}),$event.preventDefault()),$event.stopPropagation()},vm.selectItem=function(item,$index,$event){vm.onSelect&&(vm.onSelect({item:item,$index:$index,$event:$event}),$event.stopPropagation())},vm.selectAll=function($event){vm.onSelectAll&&vm.onSelectAll({$event:$event})},vm.isSelectedAll=function(){if(vm.onSelectedAll&&vm.items&&vm.items.length>0)return vm.onSelectedAll()},vm.isSortDirection=function(col,direction){if(vm.onSortingDirection)return vm.onSortingDirection({col:col,direction:direction})},vm.sort=function(field,allow,isSystem){vm.onSort&&vm.onSort({field:field,allow:allow,isSystem:isSystem})},vm.getIcon=function(entry){return iconHelper.convertFromLegacyIcon(entry.icon)}},controllerAs:"vm",bindings:{items:"<",itemProperties:"<",allowSelectAll:"<",onSelect:"&",onClick:"&",onSelectAll:"&",onSelectedAll:"&",onSortingDirection:"&",onSort:"&"}})}(),function(){angular.module("umbraco.directives").directive("textarea",function umbTextarea($document){return{restrict:"E",link:function autogrow(scope,element,attributes){function trigger(){setTimeout(element.triggerHandler.bind(element,"input"),1)}element.hasClass("autogrow")&&(parseInt(window.getComputedStyle(element[0]).getPropertyValue("min-height")),element.on("keydown",function(evt){evt.which}),element.on("input",function(evt){element.css({height:"auto",minHeight:0});var contentHeight=this.scrollHeight;element.css({minHeight:null,height:contentHeight+1+4+"px"})}),scope.$watch(attributes.ngModel,trigger),trigger())}}})}(),function(){angular.module("umbraco.directives").directive("umbTooltip",function TooltipDirective(){return{restrict:"E",transclude:!0,replace:!0,template:'<div class="umb-tooltip shadow-depth-2" ng-style="tooltipStyles" ng-transclude></div> ',scope:{event:"="},link:function link(scope,el,attr,ctrl){scope.tooltipStyles={},scope.tooltipStyles.left=0,scope.tooltipStyles.top=0,function setTooltipPosition(event){var elementHeight,elementWidth,overlay=$(event.target).closest(".umb-overlay"),rect=(overlay.length>0?overlay:$("#contentwrapper"))[0].getBoundingClientRect(),containerLeft=rect.left,containerRight=containerLeft+rect.width,containerTop=rect.top,containerBottom=containerTop+rect.height,position={right:"inherit",left:"inherit",top:"inherit",bottom:"inherit"};elementHeight=el[0].clientHeight,elementWidth=el[0].clientWidth,position.left=event.pageX-elementWidth/2,position.top=event.pageY,overlay.length>0?(position.left=event.pageX-rect.left-elementWidth/2,position.top=event.pageY-rect.top):(position.left+elementWidth>containerRight&&(position.right=10,position.left="inherit"),position.top+elementHeight>containerBottom&&(position.bottom=10,position.top="inherit"),position.left<containerLeft&&(position.left=containerLeft+10,position.right="inherit"),position.top<containerTop&&(position.top=10,position.bottom="inherit")),scope.tooltipStyles=position,el.css(position)}(scope.event)}}})}(),angular.module("umbraco.directives").directive("umbFileDropzone",function($timeout,Upload,localizationService,umbRequestHelper,overlayService,mediaHelper,mediaTypeHelper){return{restrict:"E",replace:!0,template:'<div data-element="dropzone" class="umb-file-dropzone"> <ng-form name="uploadForm" umb-isolate-form>  <div ngf-drop ng-hide="hideDropzone === \'true\'" ng-model="filesHolder" ngf-change="handleFiles($files, $event, $invalidFiles)" class="dropzone" ngf-drag-over-class="\'drag-over\'" ngf-multiple="true" ngf-allow-dir="true" ngf-pattern="{{ accept }}" ngf-max-size="{{ maxFileSize }}" ng-class="{\'is-small\': compact !==\'false\' || (done.length + queue.length) > 0 }"> <div class="content"> <p> <localize key="media_dragAndDropYourFilesIntoTheArea">Drag and drop your file(s) into the area</localize> </p>  <img class="illustration" src="assets/img/uploader/upload-illustration.svg" draggable="false">  <button type="button" data-element="button-uploadMedia" class="file-select" ngf-select ng-model="filesHolder" ngf-change="handleFiles($files, $event, $invalidFiles)" ngf-multiple="true" ngf-pattern="{{ accept }}" ngf-max-size="{{ maxFileSize }}"> -&nbsp;<localize key="media_orClickHereToUpload">or click here to choose files</localize> </button> </div> </div>  <ul class="file-list" ng-show="done.length > 0 || queue.length > 0 || rejected.length > 0 || filesHolder.length > 0">  <li class="file" ng-repeat="file in done track by file.key">  <div class="file-description">{{ file.name }}</div>  <div class="file-icon" ng-if="file.uploadStatus == \'done\'"> <umb-icon icon="icon-check" class="icon color-green"></umb-icon> </div> </li> <li class="file" ng-if="currentFile">  <div class="file-name">{{currentFile.name}}</div>  <div class="file-progress"> <span class="file-progress-indicator" ng-style="{\'width\': currentFile.uploadProgress + \'%\'}"></span> </div> </li>  <li class="file" ng-repeat="queued in queue track by queued.key">  <div class="file-name">{{queued.name}}</div> </li> <li class="file" ng-repeat="file in rejected track by file.key">  <div class="file-description"> <strong>{{file.name}}</strong> <span class="file-error" ng-if="file.$error"> <span ng-if="file.$error === \'pattern\'" class="errorMessage color-red"><localize key="media_disallowedFileType"></localize></span> <span ng-if="file.$error === \'maxSize\'" class="errorMessage color-red"><localize key="media_maxFileSize"></localize> "{{maxFileSize}}"</span> </span> <span class="file-error" ng-if="file.serverErrorMessage"> <span class="errorMessage color-red">{{file.serverErrorMessage}}</span> </span> </div>  <div class="file-icon"> <umb-icon icon="icon-delete" class="icon color-red"></umb-icon> </div> </li> </ul> </ng-form> </div> ',scope:{parentId:"@",contentTypeAlias:"@",propertyAlias:"@",accept:"@",maxFileSize:"@",compact:"@",hideDropzone:"@",acceptedMediatypes:"=",filesQueued:"=",handleFile:"=",filesUploaded:"="},link:function link(scope,element,attrs){function _filesQueued(files,event){Utilities.forEach(files,function(file){!0===function _filterFile(file){return-1===["Thumbs.db"].indexOf(file.name)&&-1===["directory"].indexOf(file.type)&&0!==file.name.indexOf(".")}(file)&&(file.$error?scope.rejected.push(file):scope.queue.push(file))}),scope.working||(scope.acceptedMediatypes&&scope.acceptedMediatypes.length||(files.map(function(file){file.uploadStatus="error",file.serverErrorMessage="File type is not allowed here",scope.rejected.push(file)}),scope.queue=[]),scope.acceptedMediatypes&&!1===function _requestChooseMediaTypeDialog(){if(0===scope.queue.length)return!1;if(1===scope.acceptedMediatypes.length)return!1;var uploadFileExtensions=scope.queue.map(function(file){return mediaHelper.getFileExtension(file.name)}),filteredMediaTypes=mediaTypeHelper.getTypeAcceptingFileExtensions(scope.acceptedMediatypes,uploadFileExtensions);if(filteredMediaTypes.filter(function(mediaType){return"File"!==mediaType.alias}).length<=1)return!1;return localizationService.localizeMany(["defaultdialogs_selectMediaType","mediaType_autoPickMediaType"]).then(function(translations){filteredMediaTypes.push({alias:"umbracoAutoSelect",name:translations[1],icon:"icon-wand"});var dialog={view:"itempicker",filter:filteredMediaTypes.length>8,availableItems:filteredMediaTypes,submit:function submit(model){scope.contentTypeAlias=model.selectedItem.alias,_processQueueItem(),overlayService.close()},close:function close(){scope.queue.map(function(file){file.uploadStatus="error",file.serverErrorMessage="No files uploaded, no mediatype selected",scope.rejected.push(file)}),scope.queue=[],overlayService.close()}};dialog.title=translations[0],overlayService.open(dialog)}),!0}()&&(scope.contentTypeAlias="umbracoAutoSelect",_processQueueItem()))}function _processQueueItem(){if(scope.queue.length>0)scope.currentFile=scope.queue.shift(),function _upload(file){scope.propertyAlias=scope.propertyAlias?scope.propertyAlias:"umbracoFile",scope.contentTypeAlias=scope.contentTypeAlias?scope.contentTypeAlias:"Image",Upload.upload({url:umbRequestHelper.getApiUrl("mediaApiBaseUrl","PostAddFile"),fields:{currentFolder:scope.parentId,contentTypeAlias:scope.contentTypeAlias,propertyAlias:scope.propertyAlias,path:file.path},file:file}).progress(function(evt){if("done"!==file.uploadStat&&"error"!==file.uploadStat){var progressPercentage=parseInt(100*evt.loaded/evt.total,10);file.uploadProgress=progressPercentage,file.uploadStatus="uploading"}}).success(function(data,status,headers,config){data.notifications&&data.notifications.length>0?(file.uploadStatus="error",file.serverErrorMessage=data.notifications[0].message,scope.rejected.push(file)):(file.uploadStatus="done",file.uploadProgress=100,file.doneDate=new Date,scope.done.push(file)),scope.currentFile=void 0,_processQueueItem()}).error(function(evt,status,headers,config){file.uploadStatus="error",evt.InnerException?(file.serverErrorMessage=evt.InnerException.ExceptionMessage,evt.InnerException.StackTrace&&evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength")>0&&(file.serverErrorMessage="File too large to upload")):evt.Message?file.serverErrorMessage=evt.Message:evt&&"string"==typeof evt&&(file.serverErrorMessage=evt),404===status&&(file.serverErrorMessage="File not found"),scope.rejected.push(file),scope.currentFile=void 0,_processQueueItem()})}(scope.currentFile);else if(scope.done.length>0){scope.filesUploaded&&scope.filesUploaded(scope.done);var currentLength=scope.done.length;$timeout(function(){scope.done.splice(0,currentLength)},3e3)}}scope.queue=[],scope.done=[],scope.rejected=[],scope.currentFile=void 0,scope.handleFiles=function(files,event,invalidFiles){var allFiles=[].concat(_toConsumableArray(files),_toConsumableArray(invalidFiles));allFiles.forEach(function(file){file.key=String.CreateGuid()}),scope.filesQueued&&scope.filesQueued(allFiles,event),_filesQueued(allFiles)}}}}),angular.module("umbraco.directives").directive("umbFileUpload",function umbFileUpload(){return{restrict:"A",scope:!0,link:function link(scope,el,attrs){el.on("change",function(event){var files=event.target.files;scope.$emit("filesSelected",{files:files}),el.val("")}),el.on("dragover dragenter",function(){scope.$emit("isDragover",{value:!0})}).on("dragleave dragend drop",function(){scope.$emit("isDragover",{value:!1})})}}}),function(){var umbPropertyFileUploadComponent={template:' <div class="umb-property-file-upload"> <ng-form name="vm.fileUploadForm" ng-class="{ \'drag-over\': vm.dragover }"> <input type="hidden" ng-model="mandatoryValidator" ng-required="vm.required && !vm.files.length"> <div class="fileinput-button umb-upload-button-big" ng-hide="vm.files.length > 0"> <umb-icon icon="icon-page-up" class="icon"></umb-icon> <p><localize key="media_clickToUpload">Click to upload</localize></p> <umb-single-file-upload accept-file-ext="vm.acceptFileExt"></umb-single-file-upload> </div> <div ng-if="vm.files.length > 0"> <div ng-if="!vm.hideSelection"> <div class="umb-fileupload clearfix" ng-repeat="file in vm.files"> <div ng-if="file.isImage || file.extension === \'svg\'"> <div class="gravity-container"> <div class="viewport"> <img ng-if="file.isClientSide" ng-src="{{file.fileSrc}}" style="max-width: 100%; max-height: 100%" alt="{{file.fileName}}"> <a ng-if="!file.isClientSide" href="#" ng-href="{{file.fileSrc}}" target="_blank" rel="noopener"> <img ng-src="{{file.fileSrc}}" style="max-width: 100%; max-height: 100%" alt="{{file.fileName}}"> </a> </div> </div> </div> <div ng-if="!file.isImage && file.extension !== \'svg\'"> <a class="span6 thumbnail tc" ng-show="!file.isClientSide" href="#" ng-href="{{file.fileName}}" target="_blank" rel="noopener"> <umb-file-icon extension="{{file.extension}}" size="m"> </umb-file-icon> <div class="mt2">{{file.fileName}}</div> </a> <div class="span6 thumbnail tc" ng-show="file.isClientSide"> <umb-file-icon extension="{{file.extension}}" size="m"> </umb-file-icon> <div class="mt2">{{file.fileName}}</div> </div> </div> </div> <div> <button type="button" class="btn btn-link btn-crop-delete" ng-click="vm.clear()"><umb-icon icon="icon-delete" class="red"></umb-icon> <localize key="content_uploadClear">Remove file</localize></button> <button type="button" class="sr-only" ng-if="file.isImage" ng-click="vm.clear()"><localize key="content_uploadClearImageContext">Click here to remove the image from the media item</localize></button> <button type="button" class="sr-only" ng-if="!file.isImage" ng-click="vm.clear()"><localize key="content_uploadClearFileContext">Click here to remove the file from the media item</localize></button> </div> </div> <div ng-if="vm.hideSelection"> <div ng-transclude></div> </div> </div> </ng-form> </div> ',bindings:{culture:"@?",segment:"@?",propertyAlias:"@",value:"<",hideSelection:"<",dragover:"<",onFilesSelected:"&",onFilesChanged:"&",onInit:"&",required:"=",acceptFileExt:"<?"},transclude:!0,controllerAs:"vm",controller:function umbPropertyFileUploadController($scope,$q,fileManager,mediaHelper,angularHelper){var vm=this;function notifyFilesSelected(val,files){val||(val=null),files||(files=null),vm.onFilesSelected({value:val,files:files}),vm.fileUploadForm.$setDirty()}function notifyFilesChanged(files){files||(files=null),vm.onFilesChanged({files:files})}function notifyInit(val,files){val||(val=null),files||(files=null),vm.onInit&&vm.onInit({value:val,files:files})}function checkPendingClientFiles(){return vm.culture||(vm.culture=null),vm.segment||(vm.segment=null),_.map(_.filter(fileManager.getFiles(),function(f){return f.alias===vm.propertyAlias&&f.culture===vm.culture&&f.segment===vm.segment}),function(f){return f.file})}function getExtension(fileName){return fileName.substring(fileName.lastIndexOf(".")+1,fileName.length).toLowerCase()}function updateModelFromSelectedFiles(files){var promises=[];vm.files=[];for(var newVal="",reader=new FileReader,fileCount=files.length,i=0;i<fileCount;i++){var index=i,isImage=mediaHelper.detectIfImageByExtension(files[i].name),extension=getExtension(files[i].name),f={isImage:isImage,extension:extension,fileName:files[i].name,isClientSide:!0};if(vm.files.push(f),newVal+=files[i].name.split(",").join("-")+",",isImage||"svg"===extension){var deferred=$q.defer();reader.onload=function(e){vm.files[index].fileSrc=e.target.result,deferred.resolve(newVal)},promises.push(deferred.promise),reader.readAsDataURL(files[i])}else promises.push($q.when(newVal))}return $q.all(promises).then(function(p){return $q.when(p[p.length-1])})}function onFilesSelected(event,args){args.files&&args.files.length>0?(fileManager.setFiles({propertyAlias:vm.propertyAlias,files:args.files,culture:vm.culture,segment:vm.segment}),updateModelFromSelectedFiles(args.files).then(function(newVal){angularHelper.safeApply($scope,function(){notifyFilesSelected(newVal,vm.files),notifyFilesChanged(vm.files)})})):angularHelper.safeApply($scope)}function isDragover(e,args){vm.dragover=args.value,angularHelper.safeApply($scope)}vm.$onInit=function onInit(){$scope.$on("filesSelected",onFilesSelected),$scope.$on("isDragover",isDragover),function initialize(){vm.culture||(vm.culture=null),vm.segment||(vm.segment=null);var existingClientFiles=checkPendingClientFiles();if(existingClientFiles.length>0)updateModelFromSelectedFiles(existingClientFiles).then(function(newVal){notifyInit(newVal,vm.files)});else if(vm.value){var files=vm.value.split(",");vm.files=_.map(files,function(file){var f={fileName:file,isImage:mediaHelper.detectIfImageByExtension(file),extension:getExtension(file)};return f.fileSrc=function getThumbnail(file){return"svg"===file.extension?file.fileName:file.isImage?mediaHelper.getThumbnailFromPath(file.fileName):null}(f),f}),notifyInit()}else vm.files=[],notifyInit()}()},vm.$onChanges=function onChanges(changes){if(changes.value&&!changes.value.isFirstChange()&&changes.value.currentValue!==changes.value.previousValue)if(!changes.value.currentValue&&changes.value.previousValue)vm.files=[];else if(changes.value.currentValue&&!changes.value.previousValue&&0===vm.files.length){var existingClientFiles=checkPendingClientFiles();existingClientFiles.length>0&&updateModelFromSelectedFiles(existingClientFiles).then(function(){notifyFilesChanged(vm.files)})}},vm.$postLink=function postLink(){},vm.clear=function clearFiles(){fileManager.setFiles({propertyAlias:vm.propertyAlias,culture:vm.culture,segment:vm.segment,files:[]}),vm.files=[],notifyFilesSelected(null),notifyFilesChanged(null)}}};angular.module("umbraco.directives").component("umbPropertyFileUpload",umbPropertyFileUploadComponent)}(),angular.module("umbraco.directives").directive("umbSingleFileUpload",function umbSingleFileUpload($compile){var innerTemplate="<input type='file' umb-file-upload accept='{{acceptFileExt}}'/>";return{restrict:"E",scope:{rebuild:"=",acceptFileExt:"<?"},replace:!0,template:"<div>"+innerTemplate+"</div>",link:function link(scope,el){scope.$watch("rebuild",function(newVal,oldVal){newVal&&newVal!==oldVal&&(el.html(innerTemplate),$compile(el.contents())(scope))})}}}),function(){var component={template:'<div> <div class="alert alert-success text-center" ng-hide="!vm.passwordValues.generatedPassword"> <small>Password has been reset to:</small> <br> <strong>{{vm.passwordValues.generatedPassword}}</strong> </div> <div ng-switch="vm.changing"> <div ng-switch-when="false"> <button type="button" ng-click="vm.doChange()" class="btn umb-button__button btn-action umb-outline umb-outline--thin"> <localize key="general_changePassword">Change password</localize> </button> </div> <div ng-switch-when="true"> <ng-form name="changePasswordForm">  <umb-control-group alias="oldPassword" label="@user_oldPassword" ng-if="vm.showOldPass()" required="true"> <input type="password" name="oldPassword" id="oldPassword" ng-model="vm.passwordValues.oldPassword" class="input-block-level umb-textstring textstring" required val-server-field="oldPassword" no-dirty-check> <span ng-messages="changePasswordForm.oldPassword.$error" show-validation-on-submit> <span class="help-inline" ng-message="required">Required</span> <span class="help-inline" ng-message="valServerField">{{changePasswordForm.oldPassword.errorMsg}}</span> </span> </umb-control-group> <umb-control-group alias="password" label="@user_newPassword" required="true"> <input type="password" name="password" id="password" class="input-block-level umb-textstring textstring" required val-server-field="password" ng-model="vm.passwordValues.newPassword" ng-minlength="{{vm.config.minPasswordLength}}" no-dirty-check ng-keyup="vm.newPasswordKeyUp($event)"> <span ng-messages="changePasswordForm.password.$error" show-validation-on-submit> <span class="help-inline" ng-message="required">Required</span> <span class="help-inline" ng-message="minlength">Minimum {{vm.config.minPasswordLength}} characters</span> <span class="help-inline" ng-message="valServerField">{{changePasswordForm.password.errorMsg}}</span> </span> <umb-password-tip password-val="vm.passwordVal" min-pwd-length="vm.config.minPasswordLength" min-pwd-non-alpha-num="vm.config.minNonAlphaNumericChars"></umb-password-tip> </umb-control-group> <umb-control-group alias="confirmPassword" label="@user_confirmNewPassword" required="true"> <input type="password" name="confirmPassword" id="confirmPassword" ng-model="vm.passwordValues.confirm" class="input-block-level umb-textstring textstring" val-compare="password" no-dirty-check> <span ng-messages="changePasswordForm.confirmPassword.$error" show-validation-on-submit> <span class="help-inline" ng-message="valCompare"><localize key="user_passwordMismatch">The confirmed password doesn\'t match the new password!</localize></span> </span> </umb-control-group> <button ng-click="vm.cancelChange()" ng-show="vm.showCancelBtn()" class="btn umb-button__button btn-cancel umb-button-- umb-outline umb-outline--thin"> <localize key="general_cancel">Cancel</localize> </button> </ng-form> </div> </div> </div> ',controller:function ChangePasswordController($scope){var vm=this;vm.$onInit=function onInit(){unsubscribe.push($scope.$on("formSubmitted",function(){!1===vm.config.disableToggle&&(vm.changing=!1)})),unsubscribe.push($scope.$on("formSubmitting",function(){vm.changing||(vm.passwordValues=null)})),resetModel(vm.isNew),vm.changing=!0===vm.config.disableToggle||!vm.config.hasPassword,vm.changing||(vm.passwordValues=null)},vm.$onDestroy=function onDestroy(){for(var u in unsubscribe)unsubscribe[u]()},vm.doChange=function doChange(){resetModel(),vm.changing=!0,vm.passwordValues.confirm=null},vm.cancelChange=function cancelChange(){vm.changing=!1,vm.passwordValues=null},vm.showOldPass=function showOldPass(){return vm.config.hasPassword&&!vm.config.allowManuallyChangingPassword},vm.showCancelBtn=function showCancelBtn(){return!0!==vm.config.disableToggle&&vm.config.hasPassword},vm.newPasswordKeyUp=function newPasswordKeyUp(event){vm.passwordVal=event.target.value};var unsubscribe=[];function resetModel(isNew){void 0===vm.config.disableToggle&&(vm.config.disableToggle=!1),void 0===vm.config.hasPassword&&(vm.config.hasPassword=!1),void 0===vm.config.minPasswordLength&&(vm.config.minPasswordLength=0),void 0===vm.config.minNonAlphaNumericChars&&(vm.config.minNonAlphaNumericChars=0),Utilities.isObject(vm.passwordValues)?isNew||(vm.passwordValues.newPassword=null,vm.passwordValues.oldPassword=null):vm.passwordValues={newPassword:null,oldPassword:null},vm.passwordVal=vm.passwordValues.newPassword,isNew?vm.passwordValues.newPassword&&vm.passwordValues.newPassword.length>0&&(vm.passwordValues.confirm=vm.passwordValues.newPassword):vm.passwordValues.confirm=""}},controllerAs:"vm",bindings:{isNew:"<",passwordValues:"=",config:"="}};angular.module("umbraco.directives").component("changePassword",component)}(),function(){angular.module("umbraco.directives").directive("umbUserGroupPreview",function UserGroupPreviewDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-user-group-preview"> <umb-icon icon="{{icon}}" class="umb-user-group-preview__icon"></umb-icon> <div class="umb-user-group-preview__content"> <div class="umb-user-group-preview__name">{{ name }}</div> <div class="umb-user-group-preview__permissions" ng-if="sections"> <span> <span class="bold"><localize key="main_sections">Sections</localize>:</span> <span ng-repeat="section in sections" class="umb-user-group-preview__permission">{{ section.name }}</span> <span ng-if="sections.length === 0">All sections</span> </span> </div> <div class="umb-user-group-preview__permissions" ng-if="!hideContentStartNode"> <span> <span class="bold"><localize key="user_startnode">Content start node</localize>:</span> <span ng-if="!contentStartNode"><localize key="user_noStartNode">No start node selected</localize></span> <span ng-if="contentStartNode">{{ contentStartNode.name }}</span> </span> </div> <div class="umb-user-group-preview__permissions" ng-if="!hideMediaStartNode"> <span> <span class="bold"><localize key="user_mediastartnode">Media start node</localize>:</span> <span ng-if="!mediaStartNode"><localize key="user_noStartNode">No start node selected</localize></span> <span ng-if="mediaStartNode">{{ mediaStartNode.name }}</span> </span> </div> <div class="umb-user-group-preview__permissions" ng-if="permissions"> <span> <span class="bold"><localize key="general_rights">Permissions</localize>:</span> <span ng-repeat="permission in permissions" class="umb-user-group-preview__permission">{{ permission.name }}</span> </span> </div> </div> <div class="umb-user-group-preview__actions"> <button class="btn-link umb-user-group-preview__action" title="Edit" ng-if="allowEdit" ng-click="onEdit()"><localize key="general_edit">Edit</localize></button> <button class="btn-link umb-user-group-preview__action umb-user-group-preview__action--red" title="Remove" ng-if="allowRemove" ng-click="onRemove()"><localize key="general_remove">Remove</localize></button> </div> </div> ',scope:{icon:"=?",name:"=",sections:"=?",contentStartNode:"=?",hideContentStartNode:"@?",mediaStartNode:"=?",hideMediaStartNode:"@?",permissions:"=?",allowRemove:"=?",allowEdit:"=?",onRemove:"&?",onEdit:"&?"},link:function link(scope,el,attr,ctrl){}}})}(),function(){angular.module("umbraco.directives").directive("umbUserPreview",function UserPreviewDirective(){return{restrict:"E",replace:!0,template:'<div class="umb-user-preview"> <div class="umb-user-preview__avatar"> <umb-avatar size="xxs" color="secondary" name="{{name}}" img-src="{{avatars[0]}}" img-srcset="{{avatars[1]}} 2x, {{avatars[2]}} 3x"> </umb-avatar> </div> <div class="umb-user-preview__content"> <div class="umb-user-preview__name">{{ name }}</div> </div> <div class="umb-user-preview__actions"> <button type="button" class="umb-user-preview__action umb-user-preview__action--red btn-link" title="Remove {{name}}" ng-if="allowRemove" ng-click="onRemove()"> <localize key="general_remove">Remove</localize> <span class="sr-only">{{name}}</span> </button> <div> </div> </div></div>',scope:{avatars:"=?",name:"=",allowRemove:"=?",onRemove:"&?"},link:function link(scope,el,attr,ctrl){}}})}(),angular.module("umbraco.directives").directive("autoScale",function($window,$timeout,windowResizeListener){return function(scope,el,attrs){var totalOffset=0,offsety=parseInt(attrs.autoScale,10),window=$($window);function setElementSize(){el.height(window.height()-(el.offset().top+totalOffset))}void 0!==offsety&&(totalOffset+=offsety),$timeout(function(){setElementSize()});var resizeCallback=function resizeCallback(){setElementSize()};windowResizeListener.register(resizeCallback),scope.$on("$destroy",function(){windowResizeListener.unregister(resizeCallback)})}}),angular.module("umbraco.directives").directive("disableTabindex",function(tabbableService){return{restrict:"A",scope:{disableTabindex:"<"},link:function link(scope,element,attrs){if(scope.disableTabindex){var targetNode=element[0];new MutationObserver(function domChange(mutationsList,observer){var _iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=mutationsList[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var mutation=_step.value;if("childList"==mutation.type){var childInputs=tabbableService.tabbable(mutation.target);Utilities.forEach(childInputs,function(element){$(element).attr("tabindex","-1")})}}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{_iteratorNormalCompletion||null==_iterator.return||_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}}).observe(targetNode,{attributes:!0,childList:!0,subtree:!0})}}}}),angular.module("umbraco.directives").directive("retriveDomElement",function(){return{restrict:"A",selector:"[retriveDomElement]",scope:{retriveDomElement:"&"},link:{post:function post(scope,iElement,iAttrs,controller){scope.retriveDomElement({element:iElement,attributes:iAttrs})}}}}),angular.module("umbraco.directives").directive("noPasswordManager",function(){return{restrict:"A",link:function link(scope,element,attrs){element.attr("data-lpignore","true")}}}),angular.module("umbraco.directives").directive("umbDroppable",function($timeout){return{restrict:"A",link:function link(scope,element,attrs){$timeout(function(){var options=scope.$eval(attrs.umbDroppable);element.droppable(options)})}}}),angular.module("umbraco.directives").directive("umbIsolateForm",function(){return{restrict:"A",require:["form","^form"],link:function link(scope,element,attrs,forms){forms[1].$removeControl(forms[0])}}}),angular.module("umbraco.directives").directive("umbKeyboardList",["$document","$timeout",function($document,$timeout){return{restrict:"A",link:function link(scope,element){var listItems=[],currentIndex=0,focusSet=!1;function keydown(event){$timeout(function(){!function checkFocus(){var found=!1;Utilities.forEach(listItems,function(item,index){$(item).is(":focus")&&(currentIndex=index,focusSet=!0,found=!0)}),found||(currentIndex=0,focusSet=!1)}(),40===event.keyCode&&function arrowDown(){currentIndex<listItems.length-1&&(focusSet&&currentIndex++,listItems[currentIndex].trigger("focus"),focusSet=!0)}(),38===event.keyCode&&function arrowUp(){currentIndex>0&&listItems[--currentIndex].trigger("focus")}()})}$timeout(function(){listItems=element.find("li :tabbable")}),$document.on("keydown",keydown),scope.$on("$destroy",function stopListening(){$document.off("keydown",keydown)})}}}]),angular.module("umbraco.directives").directive("umbOverflowChecker",function($parse,$timeout,windowResizeListener){return{restrict:"A",link:function link(scope,element,attrs){var overflow=$parse(attrs.onOverflow),scrollElement=element[0],container=element[0].parentElement;function checkOverflow(){$timeout(function(){var scrollElementScrollWidth=scrollElement.scrollWidth,containerScrollWidth=container.scrollWidth,overflowLeft=scrollElement.scrollLeft,overflowRight=containerScrollWidth-scrollElementScrollWidth+overflowLeft;scope.$evalAsync(function(){return overflow(scope,{overflowLeft:overflowLeft,overflowRight:overflowRight})})},50)}scrollElement.addEventListener("scroll",checkOverflow),windowResizeListener.register(checkOverflow),scope.$on("$destroy",function(){scrollElement.removeEventListener("scroll",checkOverflow),windowResizeListener.unregister(checkOverflow)}),scope.$on("umbOverflowChecker.checkOverflow",checkOverflow),scope.$on("umbOverflowChecker.scrollTo",function scrollTo(event,options){$timeout(function(){"end"===options.position&&(scrollElement.scrollLeft=scrollElement.scrollWidth-scrollElement.clientWidth),"start"===options.position&&(scrollElement.scrollLeft=0)},50)}),checkOverflow()}}}),angular.module("umbraco.directives.validation").directive("noDirtyCheck",function noDirtyCheck(){return{restrict:"A",require:"ngModel",link:function link(scope,elm,attrs,ctrl){if("0"!==attrs.noDirtyCheck&&0!==attrs.noDirtyCheck&&"false"!==attrs.noDirtyCheck.toString().toLowerCase()){var alwaysFalse={get:function get(){return!1},set:function set(){}};Object.defineProperty(ctrl,"$pristine",alwaysFalse),Object.defineProperty(ctrl,"$dirty",alwaysFalse)}}}}),function(){angular.module("umbraco.directives.validation").directive("showValidationOnSubmit",function showValidationOnSubmit(serverValidationManager){return{require:["ngMessages","^^?valFormManager"],restrict:"A",scope:{form:"=?"},link:function link(scope,element,attr,ctrl){var formMgr=ctrl.length>1?ctrl[1]:null;element.closest(".show-validation").length>0||formMgr&&formMgr.showValidation||element[0].classList.add("ng-hide");var unsubscribe=[];unsubscribe.push(scope.$on("formSubmitting",function(ev,args){element[0].classList.remove("ng-hide")})),unsubscribe.push(scope.$on("formSubmitted",function(ev,args){element[0].classList.add("ng-hide")})),element.on("$destroy",function(){for(var u in unsubscribe)unsubscribe[u]()})}}})}(),function(){angular.module("umbraco.directives").directive("umbSetDirtyOnChange",function SetDirtyOnChange(){return{require:["^^form","?ngModel"],restrict:"A",link:function link(scope,el,attr,ctrls){var formCtrl=ctrls[0];if(ctrls.length>1&&ctrls[1]){var modelCtrl=ctrls[1],oldRender=modelCtrl.$render;modelCtrl.$render=function(){formCtrl.$setDirty(),oldRender&&oldRender()}}else{var initValue=attr.umbSetDirtyOnChange;attr.$observe("umbSetDirtyOnChange",function(newValue){newValue!==initValue&&formCtrl.$setDirty()})}}}})}(),angular.module("umbraco.directives.validation").directive("valCompare",function(){return{require:["ngModel","^^form"],link:function link(scope,elem,attrs,ctrls){var ctrl=ctrls[0],otherInput=ctrls[1][attrs.valCompare];ctrl.$validators.valCompare=function(modelValue,viewValue){return viewValue===otherInput.$viewValue},otherInput.$parsers.push(function(value){return ctrl.$setValidity("valCompare",value===ctrl.$viewValue),value})}}}),angular.module("umbraco.directives.validation").directive("valEmail",function valEmail(valEmailExpression){return{require:"ngModel",restrict:"A",link:function link(scope,elm,attrs,ctrl){"email"===attrs.type&&(ctrl.$validators={}),ctrl.$validators.valEmail=function(modelValue,viewValue){return function patternValidator(viewValue){return!viewValue||valEmailExpression.EMAIL_REGEXP.test(viewValue)?(ctrl.errorMsg="",!0):(ctrl.errorMsg="Invalid email",!1)}(viewValue)}}}}).factory("valEmailExpression",function(){return{EMAIL_REGEXP:/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i}}),angular.module("umbraco.directives.validation").directive("valFormManager",function valFormManager(serverValidationManager,$rootScope,$timeout,$location,overlayService,eventsService,$routeParams,navigationService,editorService,localizationService,angularHelper){var SHOW_VALIDATION_Type_CLASS_NAME="show-validation-type-";function notify(scope){scope.$broadcast("valStatusChanged",{form:scope.formCtrl})}return{require:["form","^^?valFormManager","^^?valSubView"],restrict:"A",controller:function ValFormManagerController($scope){$scope.valFormManager=this;var unsubscribe=[],self=this;this.onValidationStatusChanged=function(cb){unsubscribe.push($scope.$on("valStatusChanged",function(evt,args){cb.apply(self,[evt,args])}))},this.isShowingValidation=function(){return!0===$scope.showValidation},this.getValidationMessageType=function(){return $scope.valMsgType},this.notify=notify,this.isValid=function(){return!$scope.formCtrl.$invalid},$scope.$on("$destroy",function(){for(var u in unsubscribe)unsubscribe[u]()})},link:function link(scope,element,attr,ctrls){function notifySubView(){subView&&subView.valStatusChanged({form:formCtrl,showValidation:scope.showValidation})}var formCtrl=scope.formCtrl=ctrls[0],parentFormMgr=scope.parentFormMgr=function getAncestorValFormManager(scope,ctrls,index){var found;return(found=ctrls[index])?found:(found=angularHelper.traverseScopeChain(scope,function(s){return s&&s.valFormManager&&"ValFormManagerController"===s.valFormManager.constructor.name}))?found.valFormManager:null}(scope,ctrls,1),subView=ctrls.length>1?ctrls[2]:null,labels={};localizationService.localizeMany(["prompt_unsavedChanges","prompt_unsavedChangesWarning","prompt_discardChanges","prompt_stay"]).then(function(values){labels.unsavedChangesTitle=values[0],labels.unsavedChangesContent=values[1],labels.discardChangesButton=values[2],labels.stayButton=values[3]});var lastValidationMessageType=null;function setValidationMessageType(type){removeValidationMessageType(),scope.valMsgType=type;var postfix="";switch(type){case 0:break;case 1:postfix="info";break;case 2:postfix="error";break;case 3:postfix="success";break;case 4:postfix="warning"}var cssClass=SHOW_VALIDATION_Type_CLASS_NAME+postfix;element.addClass(cssClass),lastValidationMessageType=cssClass}function removeValidationMessageType(){lastValidationMessageType&&(element.removeClass(lastValidationMessageType),lastValidationMessageType=null)}scope.$watch(function(){return formCtrl.$invalid},function(e){notify(scope),notifySubView();var inError=element.find(".control-group .ng-invalid").closest(".control-group");inError.addClass("error"),element.find(".control-group .ng-valid").closest(".control-group").not(inError).removeClass("error")});var isSavingNewItem=!1;(serverValidationManager.items.length>0||parentFormMgr&&parentFormMgr.isShowingValidation())&&(element.addClass("show-validation"),scope.showValidation=!0,setValidationMessageType((parentFormMgr?parentFormMgr.getValidationMessageType():2)||2),notifySubView());var unsubscribe=[];unsubscribe.push(scope.$on("formSubmitting",function(ev,args){var messageType=2;switch(args.action){case"save":messageType=4}element.addClass("show-validation"),scope.showValidation=!0,setValidationMessageType(messageType),notifySubView(),isSavingNewItem=$routeParams.create})),unsubscribe.push(scope.$on("formSubmitted",function(ev,args){element.removeClass("show-validation"),removeValidationMessageType(),scope.showValidation=!1,notifySubView()}));var confirmed=!1,locationEvent=$rootScope.$on("$locationChangeStart",function(event,nextLocation,currentLocation){var infiniteEditors=editorService.getEditors();if(!(!formCtrl.$dirty&&0===infiniteEditors.length||isSavingNewItem&&0===infiniteEditors.length)){var nextPath=nextLocation.split("#")[1];if(nextPath&&!confirmed&&navigationService.isRouteChangingNavigation(currentLocation,nextLocation)){(nextPath.indexOf("%253")||nextPath.indexOf("%252"))&&(nextPath=decodeURIComponent(nextPath));var overlay={view:"default",title:labels.unsavedChangesTitle,content:labels.unsavedChangesContent,disableBackdropClick:!0,disableEscKey:!0,submitButtonLabel:labels.stayButton,closeButtonLabel:labels.discardChangesButton,submit:function submit(){overlayService.close()},close:function close(){editorService.closeAll(),navigationService.clearSearch();var parts=nextPath.split("?"),query={};parts.length>1&&parts[1].split("&").forEach(function(q){var keyVal=q.split("=");query[keyVal[0]]=keyVal[1]}),$location.path(parts[0]).search(query),overlayService.close(),confirmed=!0}};overlayService.open(overlay),event.preventDefault(),eventsService.emit("valFormManager.pendingChanges",!0)}}});unsubscribe.push(locationEvent),scope.$on("$destroy",function(){for(var u in unsubscribe)unsubscribe[u]()}),$timeout(function(){formCtrl.$setPristine()},1e3)}}}),angular.module("umbraco.directives.validation").directive("valHighlight",function valHighlight($timeout){return{restrict:"A",link:function link(scope,element,attrs,ctrl){attrs.$observe("valHighlight",function(newVal){"true"===newVal?(element.addClass("highlight-error"),$timeout(function(){scope[attrs.valHighlight]=!1},1e3)):element.removeClass("highlight-error")})}}}),function(){angular.module("umbraco.directives.validation").directive("multi",["$parse","$rootScope",function multi($parse,$rootScope){return{restrict:"A",require:"ngModel",link:function link(scope,elem,attrs,ngModelCtrl){var validate=$parse(attrs.multi)(scope);ngModelCtrl.$viewChangeListeners.push(function(){$rootScope.$broadcast("multi:valueChanged")});var deregisterListener=scope.$on("multi:valueChanged",function(event){ngModelCtrl.$setValidity("multi",validate())});scope.$on("$destroy",deregisterListener)}}}])}(),angular.module("umbraco.directives.validation").directive("valPropertyMsg",function valPropertyMsg(serverValidationManager,localizationService,angularHelper){return{require:["^^form","^^valFormManager","^^umbProperty","?^^umbVariantContent","?^^valPropertyMsg"],replace:!0,restrict:"E",template:"<div ng-show=\"errorMsg != ''\" class='alert alert-error property-error' >{{errorMsg}}</div>",scope:{},link:function link(scope,element,attrs,ctrl){var unsubscribe=[],watcher=null,hasError=!1;scope.errorMsg="";var formCtrl=ctrl[0],valFormManager=ctrl[1],umbPropCtrl=ctrl[2],umbVariantCtrl=ctrl[3],currentProperty=umbPropCtrl.property;scope.currentProperty=currentProperty;var currentCulture=currentProperty.culture,currentSegment=currentProperty.segment,isMandatory=currentProperty.validation?currentProperty.validation.mandatory:void 0,labels={},showValidation=!1;if(umbVariantCtrl){var currentVariant=umbVariantCtrl.editor.content;if(!(!(umbVariantCtrl.content.variants.length>1)||currentVariant.language&&currentVariant.language.isDefault||currentCulture||currentSegment||currentProperty.unlockInvariantValue))return}function getErrorMsg(){if(scope.currentProperty){var err=serverValidationManager.getPropertyError(umbPropCtrl.getValidationPath(),null,"",null);return err&&err.errorMsg?err.errorMsg:scope.currentProperty.propertyErrorMessage?scope.currentProperty.propertyErrorMessage:labels.propertyHasErrors}return labels.propertyHasErrors}function checkAndClearError(){var errCount=angularHelper.countAllFormErrors(formCtrl);if(0===errCount)return!0;if(errCount>2)return!1;var hasValServer=Utilities.isArray(formCtrl.$error.valServer);if(1===errCount&&hasValServer)return!0;var hasOwnErr=function hasExplicitError(){return Utilities.isArray(formCtrl.$error.valPropertyMsg)}();if(1===errCount&&hasOwnErr||2===errCount&&hasOwnErr&&hasValServer){var propertyValidationPath=umbPropCtrl.getValidationPath();return!!function isLastServerError(propertyValidationPath){var nestedErrs=serverValidationManager.getPropertyErrorsByValidationPath(propertyValidationPath,currentCulture,currentSegment,{matchType:"prefix"});return 0===nestedErrs.length||1===nestedErrs.length&&nestedErrs[0].propertyAlias===propertyValidationPath}(propertyValidationPath)&&(serverValidationManager.removePropertyError(propertyValidationPath,currentCulture,"",currentSegment),!0)}return!1}function startWatch(){watcher||(watcher=scope.$watchCollection(function(){return formCtrl},function(updatedFormController){var ngModels=[];!function collectAllNgModelControllersRecursively(controls,ngModels){controls.forEach(function(ctrl){angularHelper.isForm(ctrl)?ctrl.$name!==formCtrl.$name&&collectAllNgModelControllersRecursively(ctrl.$getControls(),ngModels):ctrl.hasOwnProperty("$modelValue")&&Utilities.isObject(ctrl.$validators)&&ngModels.push(ctrl)})}(updatedFormController.$getControls(),ngModels),ngModels.forEach(function(x){x.$validators.serverValidityResetter||(x.$validators.serverValidityResetter=function resetServerValidityValidator(fieldController){var storedFieldController=fieldController;return function(modelValue,viewValue){return storedFieldController.$dirty&&checkAndClearError()&&resetError(),!0}}(x))})}))}function stopWatch(){watcher&&(watcher(),watcher=null)}function resetError(){stopWatch(),hasError=!1,formCtrl.$setValidity("valPropertyMsg",!0),scope.errorMsg=""}currentCulture=currentCulture||"invariant",scope.$on("$destroy",function(){stopWatch(),unsubscribe.forEach(function(u){return u()})}),function onInit(){localizationService.localize("errors_propertyHasErrors").then(function(data){labels.propertyHasErrors=data,(showValidation=serverValidationManager.items.length>0)||(showValidation=element.closest(".show-validation").length>0),valFormManager.onValidationStatusChanged(function(evt,args){!function checkValidationStatus(){if(formCtrl.$invalid){if(formCtrl.$error.valPropertyMsg&&formCtrl.$error.valPropertyMsg.length>0)return;if(_.without(_.keys(formCtrl.$error),"valPropertyMsg").length>0){if(void 0!==isMandatory&&!1===isMandatory&&!currentProperty.value){resetError();var _iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=formCtrl.$getControls()[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0)_step.value.$setValidity()}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{_iteratorNormalCompletion||null==_iterator.return||_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}return}hasError=!0,showValidation&&""===scope.errorMsg&&(scope.errorMsg=getErrorMsg())}else resetError()}else resetError()}()}),unsubscribe.push(scope.$on("formSubmitting",function(ev,args){showValidation=!0,hasError&&""===scope.errorMsg?(scope.errorMsg=getErrorMsg(),startWatch()):hasError||resetError()})),unsubscribe.push(scope.$on("formSubmitted",function(ev,args){showValidation=!1,resetError()})),scope.currentProperty&&unsubscribe.push(serverValidationManager.subscribe(umbPropCtrl.getValidationPath(),currentCulture,"",function serverValidationManagerCallback(isValid,propertyErrors,allErrors){var hadError=hasError;if(hasError=!isValid){if(scope.errorMsg=propertyErrors.length>1?labels.propertyHasErrors:propertyErrors[0].errorMsg||labels.propertyHasErrors,formCtrl.$setValidity("valPropertyMsg",!1),startWatch(),1===propertyErrors.length&&hadError&&!formCtrl.$pristine){var propertyValidationPath=umbPropCtrl.getValidationPath();serverValidationManager.removePropertyError(propertyValidationPath,currentCulture,"",currentSegment),resetError()}}else resetError()},currentSegment,{matchType:"prefix"}))})}()}}}),angular.module("umbraco.directives.validation").directive("valPropertyValidator",function valPropertyValidator(serverValidationManager){return{scope:{valPropertyValidator:"="},require:["ngModel","?^umbProperty"],restrict:"A",link:function link(scope,element,attrs,ctrls){var modelCtrl=ctrls[0],propCtrl=ctrls.length>1?ctrls[1]:null;if(!scope.valPropertyValidator||!Utilities.isFunction(scope.valPropertyValidator))throw new Error("val-property-validator directive must specify a function to call");function validate(viewValue){var result=scope.valPropertyValidator();if(!result.errorKey||void 0===result.isValid||!result.errorMsg)throw"The result object from valPropertyValidator does not contain required properties: isValid, errorKey, errorMsg";return!0===result.isValid?(modelCtrl.$setValidity(result.errorKey,!0),propCtrl&&propCtrl.setPropertyError(null)):(modelCtrl.$setValidity(result.errorKey,!1),propCtrl&&propCtrl.setPropertyError(result.errorMsg)),result.isValid?viewValue:void 0}modelCtrl.$parsers.push(validate),validate()}}}),angular.module("umbraco.directives.validation").directive("valRegex",function valRegex(){return{require:"ngModel",restrict:"A",link:function link(scope,elm,attrs,ctrl){var regex,flags="";attrs.$observe("valRegexFlags",function(newVal){newVal&&(flags=newVal)}),attrs.$observe("valRegex",function(newVal){if(newVal)try{regex=newVal?new RegExp(newVal,flags):new RegExp(attrs.valRegex,flags)}catch(e){regex=new RegExp(attrs.valRegex,flags)}});var oldRender=ctrl.$render;ctrl.$render=function(){patternValidator(ctrl.$viewValue),oldRender&&oldRender()};var patternValidator=function patternValidator(viewValue){if(regex)return!viewValue||regex.test(viewValue.toString())?(ctrl.$setValidity("valRegex",!0),ctrl.errorMsg="",viewValue):(ctrl.$setValidity("valRegex",!1),void(ctrl.errorMsg="Value is invalid, it does not match the correct pattern"))}}}}),function(){angular.module("umbraco.directives").directive("valRequireComponent",function valRequireComponentDirective(){return{require:"ngModel",restrict:"A",link:function link(scope,el,attr,ngModel){var unbindModelWatcher=scope.$watch(function(){return ngModel.$modelValue},function(newValue){null==newValue||""===newValue?ngModel.$setValidity("valRequiredComponent",!1):ngModel.$setValidity("valRequiredComponent",!0)});scope.$on("$destroy",function(){unbindModelWatcher()})}}})}(),angular.module("umbraco.directives.validation").directive("valServer",function valServer(serverValidationManager){return{require:["ngModel","?^^umbProperty","?^^umbVariantContent"],restrict:"A",scope:{},link:function link(scope,element,attr,ctrls){var modelCtrl=ctrls[0],umbPropCtrl=ctrls[1];if(umbPropCtrl){var umbVariantCtrl=ctrls[2],currentProperty=umbPropCtrl.property,currentCulture=currentProperty.culture,currentSegment=currentProperty.segment;if(umbVariantCtrl){var currentVariant=umbVariantCtrl.editor.content;if(!(!(umbVariantCtrl.content.variants.length>1)||currentVariant.language&&currentVariant.language.isDefault||currentCulture||currentSegment||currentProperty.unlockInvariantValue))return}currentCulture=currentCulture||"invariant";var watcher=null,unsubscribe=[],fieldName="value";attr.valServer&&((fieldName=scope.$eval(attr.valServer))||(fieldName=attr.valServer));var propertyValidationPath=umbPropCtrl?umbPropCtrl.getValidationPath():currentProperty.alias;unsubscribe.push(serverValidationManager.subscribe(propertyValidationPath,currentCulture,fieldName,function serverValidationManagerCallback(isValid,propertyErrors,allErrors){isValid?(modelCtrl.$setValidity("valServer",!0),modelCtrl.errorMsg="",stopWatch()):(modelCtrl.$setValidity("valServer",!1),modelCtrl.errorMsg=propertyErrors[0].errorMsg,function startWatch(){watcher||(watcher=scope.$watch(function(){return modelCtrl.$modelValue},function(newValue,oldValue){newValue&&!Utilities.equals(newValue,oldValue)&&modelCtrl.$invalid&&(modelCtrl.$setValidity("valServer",!0),serverValidationManager.removePropertyError(propertyValidationPath,currentCulture,fieldName,currentSegment),stopWatch())},!0))}())},currentSegment)),scope.$on("$destroy",function(){stopWatch(),unsubscribe.forEach(function(u){return u()})})}function stopWatch(){watcher&&(watcher(),watcher=null)}}}}),angular.module("umbraco.directives.validation").directive("valServerField",function valServerField(serverValidationManager){return{require:"ngModel",restrict:"A",scope:{},link:function link(scope,element,attr,ngModel){var fieldName=null,unsubscribe=[];attr.$observe("valServerField",function(newVal){newVal&&null===fieldName&&(fieldName=newVal,unsubscribe.push(scope.$watch(function(){return ngModel.$modelValue},function(newValue){ngModel.$invalid&&ngModel.$setValidity("valServerField",!0)})),unsubscribe.push(serverValidationManager.subscribe(null,null,fieldName,function(isValid,fieldErrors,allErrors){isValid?(ngModel.$setValidity("valServerField",!0),ngModel.errorMsg=""):(ngModel.$setValidity("valServerField",!1),ngModel.errorMsg=fieldErrors[0].errorMsg)})))}),scope.$on("$destroy",function(){for(var e in unsubscribe)unsubscribe[e]()})}}}),angular.module("umbraco.directives.validation").directive("valServerMatch",function valServerMatch(serverValidationManager){return{require:["form","^^umbProperty","?^^umbVariantContent"],restrict:"A",scope:{valServerMatch:"="},link:function link(scope,element,attr,ctrls){var formCtrl=ctrls[0],umbPropCtrl=ctrls[1];if(umbPropCtrl){var umbVariantCtrl=ctrls[2],currentProperty=umbPropCtrl.property,currentCulture=currentProperty.culture,currentSegment=currentProperty.segment;if(umbVariantCtrl){var currentVariant=umbVariantCtrl.editor.content;if(!(!(umbVariantCtrl.content.variants.length>1)||currentVariant.language&&currentVariant.language.isDefault||currentCulture||currentSegment||currentProperty.unlockInvariantValue))return}currentCulture=currentCulture||"invariant";var unsubscribe=[];if(Utilities.isObject(scope.valServerMatch)){var allowedKeys=["contains","prefix","suffix"];Object.keys(scope.valServerMatch).forEach(function(matchType){if(-1===allowedKeys.indexOf(matchType))throw"valServerMatch dictionary keys must be one of "+allowedKeys.join();var matchVal=scope.valServerMatch[matchType];Utilities.isObject(matchVal)?Object.keys(matchVal).forEach(function(valKey){bindCallback(valKey,matchVal[valKey],matchType)}):bindCallback("valServerMatch",matchVal,matchType)})}else{if(!Utilities.isString(scope.valServerMatch))throw"valServerMatch value must be a string or a dictionary";bindCallback("valServerMatch",scope.valServerMatch,null)}scope.$on("$destroy",function(){unsubscribe.forEach(function(u){return u()})})}function bindCallback(validationKey,matchVal,matchType){matchVal&&(Utilities.isString(matchVal)&&(matchVal=[matchVal]),matchVal.forEach(function(m){unsubscribe.push(serverValidationManager.subscribe(m,currentCulture,"",function(isValid,propertyErrors,allErrors){isValid?formCtrl.$setValidity(validationKey,!0):formCtrl.$setValidity(validationKey,!1)},currentSegment,matchType?{matchType:matchType}:null))}))}}}}),function(){angular.module("umbraco.directives").directive("valSubView",function valSubViewDirective(){return{require:["?^^form","?^^valFormManager"],restrict:"A",link:function link(scope,el,attr,ctrl){if(ctrl[1]){var model=scope.model;attr&&attr.valSubView&&(model=scope[attr.valSubView]);var valFormManager=ctrl[1];model.hasError=!1,valFormManager.onValidationStatusChanged(function(evt,args){args.form.$valid?model.hasError=!1:el.find(".ng-invalid").length>0?model.hasError=!0:model.hasError=!1})}},controller:function controller($scope,$element,$attrs){var model=$scope.model;return $attrs&&$attrs.valSubView&&(model=$scope[$attrs.valSubView]),{valStatusChanged:function valStatusChanged(args){model&&(args.form.$valid?(model.hasError=!1,model.errorClass=null):$element.find(".ng-invalid").length>0?(model.hasError=!0,model.errorClass=args.showValidation?"show-validation":null):(model.hasError=!1,model.errorClass=null))}}}}})}(),angular.module("umbraco.directives.validation").directive("valTab",function valTab($timeout){return{require:["^^form","^^valFormManager"],restrict:"A",link:function link(scope,element,attr,ctrs){var evts=[],form=ctrs[0],tab=scope.$eval(attr.valTab)||scope.tab;if(tab){var closestEditor=element.closest(".blockelement-inlineblock-editor");closestEditor=0===(closestEditor=0===closestEditor.length?element.closest(".umb-editor-sub-view"):closestEditor).length?element.closest(".umb-editor"):closestEditor,setSuccess(),$timeout(function(){scope.$watchCollection(function(){return form.$$controls},function(newValue){unsubscribe(),function subscribe(){var _iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_loop=function _loop(){var control=_step.value;unbind=scope.$watch(function(){return control.$invalid},function(){setValidity(form)}),evts.push(unbind)},_iterator=form.$$controls[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var unbind;_loop()}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{_iteratorNormalCompletion||null==_iterator.return||_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}}()})}),scope.$on("$destroy",function(){unsubscribe()})}function setValidity(form){var tabAlias=tab.alias||"";form.$valid?setSuccess():closestEditor.find("[data-element='tab-content-"+tabAlias+"']").find(".ng-invalid").length>0?function setError(){scope.valTab_tabHasError=!0,tab.hasError=!0}():setSuccess()}function setSuccess(){scope.valTab_tabHasError=!1,tab.hasError=!1}function unsubscribe(){evts.forEach(function(event){return event()})}}}}),angular.module("umbraco.directives.validation").directive("valTriggerChange",function($sniffer){return{link:function link(scope,elem,attrs){elem.on("click",function(){$(attrs.valTriggerChange).trigger($sniffer.hasEvent("input")?"input":"change")})},priority:1}}),function(){angular.module("umbraco").component("umbBlockCard",{template:'<div> <div class="__showcase" ng-class="{\'--error\':vm.elementTypeModel === null}" ng-style="{\'background-color\': vm.blockConfigModel ? vm.blockConfigModel.backgroundColor : \'\', \'background-image\': vm.styleBackgroundImage}"> <div class="__icon"> <umb-icon icon="{{vm.icon}}" ng-attr-style="{{\'color:\' + vm.blockConfigModel.iconColor}}" ng-if="vm.blockConfigModel == null || vm.blockConfigModel.thumbnail == null"> </umb-icon> </div> </div> <div class="__info" ng-if="vm.elementTypeModel !== null"> <div class="__name" ng-bind="vm.elementTypeModel.name"></div> <div class="__subname" ng-if="vm.elementTypeModel.description" ng-bind="vm.elementTypeModel.description"></div> </div> <div class="__info --error" ng-if="vm.elementTypeModel === null"> <div class="__name"><localize key="blockEditor_elementTypeDoesNotExistHeadline">Other</localize></div> <div class="__subname"><localize key="blockEditor_elementTypeDoesNotExistDescription">Other</localize></div> </div> <ng-transclude></ng-transclude> </div> ',controller:function BlockCardController($scope,umbRequestHelper){var vm=this;vm.styleBackgroundImage="none";var unwatch=$scope.$watch("vm.blockConfigModel.thumbnail",function(newValue,oldValue){newValue!==oldValue&&vm.updateThumbnail()});vm.$onInit=function(){vm.updateThumbnail()},vm.$onChanges=function(){vm.icon=vm.elementTypeModel?vm.elementTypeModel.icon.split(" ")[0]:"icon-block"},vm.$onDestroy=function(){unwatch()},vm.updateThumbnail=function(){if(null!=vm.blockConfigModel&&null!=vm.blockConfigModel.thumbnail&&""!==vm.blockConfigModel.thumbnail){var path=umbRequestHelper.convertVirtualToAbsolutePath(vm.blockConfigModel.thumbnail);!1===path.toLowerCase().endsWith(".svg")&&(path+="?width=400"),vm.styleBackgroundImage="url('".concat(path,"')")}else vm.styleBackgroundImage="none"}},controllerAs:"vm",transclude:!0,bindings:{blockConfigModel:"<?",elementTypeModel:"<"}})}(),function(){angular.module("umbraco.directives").component("umbElementEditorContent",{template:'<div class="form-horizontal"> <ng-form name="elementTypeContentForm"> <umb-editor-tab-bar ng-if="vm.tabs.length > 0"> <umb-tabs-nav tabs="vm.tabs" on-tab-change="vm.setActiveTab(tab)"></umb-tabs-nav> </umb-editor-tab-bar> <umb-box ng-repeat="tab in vm.tabs" ng-show="tab.alias === vm.activeTabAlias && tab.properties.length > 0"> <umb-box-content data-element="tab-content-{{tab.alias}}"> <umb-property data-element="property-{{property.alias}}" ng-repeat="property in tab.properties track by property.alias" property="property" element-key="{{vm.model.key}}" show-inherit="vm.model.variants.length > 1 && !property.culture && !activeVariant.language.isDefault" inherits-from="defaultVariant.language.name"> <div ng-class="{\'o-40 cursor-not-allowed\': vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue}"> <umb-property-editor model="property" preview="vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue"> </umb-property-editor> </div> </umb-property> </umb-box-content> </umb-box> <div class="umb-group-panel" data-element="group-{{group.alias}}" ng-repeat="group in vm.model.variants[0].tabs track by group.key" ng-if="group.type === \'Group\'" ng-show="group.parentAlias === vm.activeTabAlias || vm.tabs.length === 0"> <div class="umb-group-panel__header"> <div id="group-{{group.id}}">{{ group.label }}</div> </div> <div class="umb-group-panel__content" data-element="tab-content-{{group.type === \'Group\' ? group.parentAlias : group.alias}}"> <umb-property data-element="property-{{property.alias}}" ng-repeat="property in group.properties track by property.alias" property="property" element-key="{{vm.model.key}}" show-inherit="vm.model.variants.length > 1 && !property.culture && !activeVariant.language.isDefault" inherits-from="defaultVariant.language.name"> <div ng-class="{\'o-40 cursor-not-allowed\': vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue}"> <umb-property-editor model="property" preview="vm.model.variants.length > 1 && !activeVariant.language.isDefault && !property.culture && !property.unlockInvariantValue"> </umb-property-editor> </div> </umb-property> </div> </div> <umb-empty-state ng-if="vm.model.tabs.length === 0" position="center"> <localize key="content_noProperties"></localize> </umb-empty-state> </ng-form> </div> ',controller:function ElementEditorContentComponentController($scope,$filter,contentEditingHelper,contentTypeHelper){var vm=this;function setActiveTab(tab){vm.activeTabAlias=tab.alias,vm.tabs.forEach(function(tab){return tab.active=!1}),tab.active=!0}vm.tabs=[],vm.activeTabAlias=null,vm.getScope=function getScope(){return $scope},vm.setActiveTab=setActiveTab,$scope.$watchCollection("vm.model.variants[0].tabs",function(newValue){contentTypeHelper.defineParentAliasOnGroups(newValue),contentTypeHelper.relocateDisorientedGroups(newValue),vm.tabs=$filter("filter")(newValue,function(tab){return tab.type===contentTypeHelper.TYPE_TAB}),vm.tabs.length>0&&(contentEditingHelper.registerGenericTab(newValue),setActiveTab(vm.tabs[0]))})},controllerAs:"vm",bindings:{model:"="}})}(),function(){angular.module("umbraco").component("umbMediaCard",{template:'<ng-form name="vm.mediaCardForm"> <div class="__showcase"> <div ng-if="vm.loading" class="umb-button__progress"></div> <p ng-if="vm.media.trashed" class="__status --error"> <umb-icon icon="icon-trash"></umb-icon> <localize key="mediaPicker_trashed"></localize> </p> <p ng-if="vm.notAllowed" class="__status --error"> <umb-icon icon="icon-block"></umb-icon> <localize key="mediaPicker_notAllowed"></localize> </p>  <img ng-if="vm.loading === false && vm.thumbnail" ng-class="{\'trashed\': vm.media.trashed}" ng-src="{{vm.thumbnail}}" title="{{vm.media.name}}" alt="{{vm.media.name}}"> <umb-file-icon ng-if="vm.loading === false && vm.icon" icon="{{vm.icon}}" size="s" text="{{vm.name}}"> </umb-file-icon>  <umb-file-icon ng-if="vm.loading === false && !vm.thumbnail" ng-class="{\'trashed\': vm.media.trashed}" title="{{vm.media.name}}" extension="{{vm.media.extension}}" icon="{{vm.media.icon}}" size="s" text="{{vm.media.name}}"> </umb-file-icon> </div> <button type="button" ng-click="vm.onNameClicked($event)" class="btn-reset __info" ng-if="vm.media !== null || vm.name"> <div class="__name" ng-bind="vm.media.name || vm.name"></div> <div class="__subname" ng-if="vm.media.description" ng-bind="vm.media.description"></div> </button> <ng-transclude></ng-transclude> </ng-form> ',controller:function MediaCardController($scope,$element,entityResource,mediaHelper,eventsService,localizationService){var unsubscribe=[],vm=this;function checkErrorState(){vm.notAllowed=vm.media&&vm.allowedTypes&&vm.allowedTypes.length>0&&-1===vm.allowedTypes.indexOf(vm.media.metaData.ContentTypeAlias),!0===vm.hasError||!0===vm.notAllowed||vm.media&&!0===vm.media.trashed?($element.addClass("--hasError"),vm.mediaCardForm.$setValidity("error",!1)):($element.removeClass("--hasError"),vm.mediaCardForm.$setValidity("error",!0))}vm.paddingBottom=100,vm.loading=!1,unsubscribe.push($scope.$watch("vm.mediaKey",function(newValue,oldValue){newValue!==oldValue&&vm.updateThumbnail()})),vm.$onInit=function(){unsubscribe.push($scope.$watchGroup(["vm.media.trashed","vm.hasError"],checkErrorState)),vm.updateThumbnail(),unsubscribe.push(eventsService.on("editors.media.saved",function(name,args){args&&args.media&&args.media.key===vm.mediaKey&&vm.updateThumbnail()}))},vm.$onDestroy=function(){unsubscribe.forEach(function(x){return x()})},vm.updateThumbnail=function(){vm.mediaKey&&""!==vm.mediaKey&&(vm.loading=!0,entityResource.getById(vm.mediaKey,"Media").then(function(mediaEntity){vm.media=mediaEntity,checkErrorState(),vm.thumbnail=mediaHelper.resolveFileFromEntity(mediaEntity,!0),vm.loading=!1},function(){localizationService.localize("mediaPicker_deletedItem").then(function(localized){vm.media={name:localized,icon:"icon-picture",trashed:!0},vm.loading=!1,$element.addClass("--hasError"),vm.mediaCardForm.$setValidity("error",!1)})}))}},controllerAs:"vm",transclude:!0,bindings:{mediaKey:"<?",icon:"<?",name:"<?",hasError:"<",allowedTypes:"<?",onNameClicked:"&?"}})}(),function(){angular.module("umbraco").component("umbPropertyInfoButton",{template:'<button type="button" title="{{ vm.show ? \'\' : vm.buttonTitle}}" class="btn-reset umb-outline umb-outline--surrounding __button" ng-click="vm.onMouseClick($event)" ng-bind="vm.symbol"> </button> <div class="__tooltip" ng-if="vm.show" on-outside-click="vm.onMouseClickOutside($event)"> <ng-transclude></ng-transclude> </div> ',controller:function UmbPropertyInfoButtonController(localizationService){var vm=this;vm.show=!1,vm.onMouseClick=function($event){vm.show=!vm.show},vm.onMouseClickOutside=function($event){vm.show=!1},vm.$onInit=function(){vm.symbol=vm.symbol||"i",vm.buttonTitleKey&&localizationService.localize(vm.buttonTitleKey).then(function(value){vm.buttonTitle=value})}},controllerAs:"vm",transclude:!0,bindings:{buttonTitle:"@?",buttonTitleKey:"@?",symbol:"@?"}})}(),function(){angular.module("umbraco").component("umbBlockListBlock",{controller:function BlockListBlockController($scope,$compile,$element){var model=this;model.$onInit=function(){if(model.block.setParentForm(model.parentForm),model.block.index=model.index,$scope.block=model.block,$scope.api=model.api,$scope.index=model.index,$scope.parentForm=model.parentForm,$scope.valFormManager=model.valFormManager,model.stylesheet){var shadowRoot=$element[0].attachShadow({mode:"open"});shadowRoot.innerHTML='\n                    <style>\n                    @import "'.concat(model.stylesheet,'"\n                    </style>\n                    <div class="umb-block-list__block--view" ng-include="\'').concat(model.view,"'\"></div>\n                "),$compile(shadowRoot)($scope)}else $element.append($compile('<div class="umb-block-list__block--view" ng-include="model.view"></div>')($scope))},model.$onChanges=function(changes){if(changes.index){var index=changes.index.currentValue;$scope.index=index,model.block.index=index,model.block.updateLabel()}}},controllerAs:"model",bindings:{stylesheet:"@",view:"@",block:"=",api:"<",index:"<",parentForm:"<"},require:{valFormManager:"^^valFormManager"}})}(),function(){angular.module("umbraco").component("umbBlockListPropertyEditor",{template:'<div class="umb-block-list"> <umb-load-indicator ng-if="vm.loading"></umb-load-indicator> <div class="umb-block-list__wrapper" ng-style="vm.listWrapperStyles"> <div ui-sortable="vm.sortableOptions" ng-model="vm.layout" ng-if="vm.loading !== true"> <div ng-repeat="layout in vm.layout track by layout.$block.key"> <button type="button" class="btn-reset umb-block-list__block--create-button" ng-click="vm.requestShowCreate($index, $event)" ng-controller="Umbraco.PropertyEditors.BlockListPropertyEditor.CreateButtonController as inlineCreateButtonCtrl" ng-mousemove="inlineCreateButtonCtrl.onMouseMove($event)"> <div class="__plus" ng-style="{\'left\':inlineCreateButtonCtrl.plusPosX}"> <umb-icon icon="icon-add" class="icon"></umb-icon> </div> </button> <umb-block-list-row block-editor-api="vm.blockEditorApi" layout="layout" index="$index"> </umb-block-list-row> </div> </div> <div class="umb-block-list__actions" ng-if="vm.loading !== true"> <button id="{{vm.model.alias}}" type="button" class="btn-reset umb-block-list__create-button umb-outline" ng-disabled="vm.availableBlockTypes.length === 0" ng-click="vm.requestShowCreate(vm.layout.length, $event)"> <localize ng-if="vm.availableBlockTypes.length !== 1" key="blockEditor_addBlock">Add content</localize> <localize ng-if="vm.availableBlockTypes.length === 1" key="blockEditor_addThis" tokens="[vm.availableBlockTypes[0].elementTypeModel.name]">Add content</localize> </button> <button type="button" class="btn-reset umb-block-list__clipboard-button umb-outline" ng-class="{\'--jump\': vm.jumpClipboardButton}" ng-disabled="vm.clipboardItems.length === 0" ng-click="vm.requestShowClipboard(vm.layout.length, $event)" localize="title" title="@blockEditor_tabClipboard"> <umb-icon icon="icon-paste-in" class="icon"></umb-icon> <span class="sr-only"> <localize key="blockEditor_tabClipboard">Clipboard</localize> </span> </button> </div> <input type="hidden" name="minCount" ng-model="vm.layout" val-server="minCount"> <input type="hidden" name="maxCount" ng-model="vm.layout" val-server="maxCount"> <div ng-messages="vm.propertyForm.minCount.$error"> <div class="help text-error" ng-message="minCount"> <localize key="validation_entriesShort" tokens="[vm.validationLimit.min, vm.validationLimit.min - vm.layout.length]" watch-tokens="true">Minimum %0% entries, needs <strong>%1%</strong> more.</localize> </div> <span class="help-inline" ng-message="valServer" ng-bind-html="vm.propertyForm.minCount.errorMsg">></span> </div> <div ng-messages="vm.propertyForm.maxCount.$error"> <div class="help text-error" ng-message="maxCount"> <localize key="validation_entriesExceed" tokens="[vm.validationLimit.max, vm.layout.length - vm.validationLimit.max]" watch-tokens="true">Maximum %0% entries, <strong>%1%</strong> too many.</localize> </div> <span class="help-inline" ng-message="valServer" ng-bind-html="vm.propertyForm.maxCount.errorMsg"></span> </div> </div> <umb-overlay ng-if="vm.blockTypePicker.show" position="target" size="vm.blockTypePicker.size" view="vm.blockTypePicker.view" model="vm.blockTypePicker"> </umb-overlay> </div> ',controller:function BlockListController($scope,$timeout,editorService,clipboardService,localizationService,overlayService,blockEditorService,udiService,serverValidationManager,angularHelper,eventsService){var modelObject,jumpClipboardTimeout,unsubscribe=[],copyAllBlocksAction=null,deleteAllBlocksAction=null,inlineEditing=!1,liveEditing=!0,vm=this;function onServerValueChanged(newVal,oldVal){"object"===_typeof(newVal)&&null!==newVal||(vm.model.value=newVal={}),modelObject.update(vm.model.value,$scope),onLoaded()}function setDirty(){vm.propertyForm&&vm.propertyForm.$setDirty()}function onLoaded(){vm.layout=modelObject.getLayout([]);var invalidLayoutItems=[];vm.layout.forEach(function(entry){if(void 0===entry.$block||null===entry.$block||void 0===entry.$block.data){var block=getBlockObject(entry);null!==block?entry.$block=block:invalidLayoutItems.push(entry)}else updateBlockObject(entry.$block)}),invalidLayoutItems.forEach(function(entry){var index=vm.layout.findIndex(function(x){return x===entry});index>=0&&vm.layout.splice(index,1)}),vm.availableContentTypesAliases=modelObject.getAvailableAliasesForBlockContent(),vm.availableBlockTypes=modelObject.getAvailableBlocksForBlockPicker(),updateClipboard(!0),vm.loading=!1,$scope.$evalAsync()}function ensureCultureData(content){content&&(vm.umbVariantContent.editor.content.language&&(content.language=vm.umbVariantContent.editor.content.language),content.variants[0].tabs.forEach(function(tab){tab.properties.forEach(function(prop){prop.culture=vm.umbProperty.property.culture})}))}function getBlockObject(entry){var block=modelObject.getBlockObject(entry);return null===block?null:(block.view=block.config.view?block.config.view:function getDefaultViewForBlock(block){var defaultViewFolderPath="views/propertyeditors/blocklist/blocklistentryeditors/";return!0===block.config.unsupported?defaultViewFolderPath+"unsupportedblock/unsupportedblock.editor.html":!0===inlineEditing?defaultViewFolderPath+"inlineblock/inlineblock.editor.html":defaultViewFolderPath+"labelblock/labelblock.editor.html"}(block),block.showValidation=!!block.config.view,block.hideContentInOverlay=!0===block.config.forceHideContentEditorInOverlay||!0===inlineEditing,block.showSettings=null!=block.config.settingsElementTypeKey,block.showCopy=vm.supportCopy&&null!=block.config.contentElementTypeKey,block.index=0,block.setParentForm=function(parentForm){this._parentForm=parentForm},block.activate=function(){this._activate()},block.edit=function(){this._edit()},block.editSettings=function(){this._editSettings()},block.requestDelete=function(){this._requestDelete()},block.delete=function(){this._delete()},block.copy=function(){this._copy()},updateBlockObject(block),block)}function updateBlockObject(block){ensureCultureData(block.content),ensureCultureData(block.settings),block._activate=activateBlock.bind(null,block),block._edit=function(){var blockIndex=vm.layout.indexOf(this.layout);editBlock(this,!1,blockIndex,this._parentForm)},block._editSettings=function(){var blockIndex=vm.layout.indexOf(this.layout);editBlock(this,!0,blockIndex,this._parentForm)},block._requestDelete=requestDeleteBlock.bind(null,block),block._delete=deleteBlock.bind(null,block),block._copy=copyBlock.bind(null,block)}function addNewBlock(index,contentElementTypeKey){var layoutEntry=modelObject.create(contentElementTypeKey);if(null===layoutEntry)return!1;var blockObject=getBlockObject(layoutEntry);return null!==blockObject&&(layoutEntry.$block=blockObject,vm.layout.splice(index,0,layoutEntry),vm.setBlockFocus(blockObject),!0)}function deleteBlock(block){var layoutIndex=vm.layout.findIndex(function(entry){return entry.contentUdi===block.layout.contentUdi});if(-1===layoutIndex)throw new Error("Could not find layout entry of block with udi: "+block.layout.contentUdi);setDirty();var removed=vm.layout.splice(layoutIndex,1);removed.forEach(function(x){var guids=[udiService.getKey(x.contentUdi),x.settingsUdi?udiService.getKey(x.settingsUdi):null];guids.forEach(function(guid){guid&&serverValidationManager.removePropertyError(guid,vm.umbProperty.property.culture,vm.umbProperty.property.segment,"",{matchType:"contains"})})}),modelObject.removeDataAndDestroyModel(block)}function activateBlock(blockObject){blockObject.active=!0}function editBlock(blockObject,openSettings,blockIndex,parentForm,options){if(options=options||{},void 0===blockIndex)throw"blockIndex was not specified on call to editBlock";var wasNotActiveBefore=!0!==blockObject.active;if((!0===openSettings||!0!==blockObject.hideContentInOverlay)&&(!0!==openSettings||blockObject.config.settingsElementTypeKey)){activateBlock(blockObject);var blockContentClone=Utilities.copy(blockObject.content),blockSettingsClone=null;blockObject.config.settingsElementTypeKey&&(blockSettingsClone=Utilities.copy(blockObject.settings));var blockEditorModel={$parentScope:$scope,$parentForm:parentForm||vm.propertyForm,hideContent:blockObject.hideContentInOverlay,openSettings:!0===openSettings,createFlow:!0===options.createFlow,liveEditing:liveEditing,title:blockObject.label,view:"views/common/infiniteeditors/blockeditor/blockeditor.html",size:blockObject.config.editorSize||"medium",submit:function submit(blockEditorModel){!1===liveEditing&&blockObject.retrieveValuesFrom(blockEditorModel.content,blockEditorModel.settings),blockObject.active=!1,editorService.close()},close:function close(blockEditorModel){blockEditorModel.createFlow?deleteBlock(blockObject):(!0===liveEditing&&blockObject.retrieveValuesFrom(blockContentClone,blockSettingsClone),!0===wasNotActiveBefore&&(blockObject.active=!1)),editorService.close()}};!0===liveEditing?(blockEditorModel.content=blockObject.content,blockEditorModel.settings=blockObject.settings):(blockEditorModel.content=blockContentClone,blockEditorModel.settings=blockSettingsClone),editorService.open(blockEditorModel)}}function showCreateDialog(createIndex,openClipboard){if(!vm.blockTypePicker&&0!==vm.availableBlockTypes.length){var amountOfAvailableTypes=vm.availableBlockTypes.length,blockPickerModel={$parentScope:$scope,$parentForm:vm.propertyForm,availableItems:vm.availableBlockTypes,title:vm.labels.grid_addElement,openClipboard:openClipboard,orderBy:"$index",view:"views/common/infiniteeditors/blockpicker/blockpicker.html",size:amountOfAvailableTypes>8?"medium":"small",filter:amountOfAvailableTypes>8,clickPasteItem:function clickPasteItem(item,mouseEvent){if(Array.isArray(item.pasteData)){var indexIncrementor=0;item.pasteData.forEach(function(entry){requestPasteFromClipboard(createIndex+indexIncrementor,entry,item.type)&&indexIncrementor++})}else requestPasteFromClipboard(createIndex,item.pasteData,item.type);mouseEvent.ctrlKey||mouseEvent.metaKey||blockPickerModel.close()},submit:function submit(blockPickerModel,mouseEvent){var wasAdded=!1;blockPickerModel&&blockPickerModel.selectedItem&&(wasAdded=addNewBlock(createIndex,blockPickerModel.selectedItem.blockConfigModel.contentElementTypeKey)),mouseEvent.ctrlKey||mouseEvent.metaKey||(editorService.close(),wasAdded&&userFlowWhenBlockWasCreated(createIndex))},close:function close(){createIndex<vm.layout.length&&vm.setBlockFocus(vm.layout[Math.max(createIndex-1,0)].$block),editorService.close()},clickClearClipboard:function($event){clipboardService.clearEntriesOfType(clipboardService.TYPES.ELEMENT_TYPE,vm.availableContentTypesAliases),clipboardService.clearEntriesOfType(clipboardService.TYPES.BLOCK,vm.availableContentTypesAliases)}};blockPickerModel.clipboardItems=vm.clipboardItems,editorService.open(blockPickerModel)}}function userFlowWhenBlockWasCreated(createIndex){if(vm.layout.length>createIndex){var blockObject=vm.layout[createIndex].$block;!0===inlineEditing?blockObject.activate():!1===inlineEditing&&!0!==blockObject.hideContentInOverlay&&blockObject.edit()}}function updateClipboard(firstTime){var oldAmount=vm.clipboardItems.length;vm.clipboardItems=[];var entriesForPaste=clipboardService.retriveEntriesOfType(clipboardService.TYPES.ELEMENT_TYPE,vm.availableContentTypesAliases);entriesForPaste.forEach(function(entry){var pasteEntry={type:clipboardService.TYPES.ELEMENT_TYPE,date:entry.date,pasteData:entry.data,elementTypeModel:{name:entry.label,icon:entry.icon}};if(!1===Array.isArray(entry.data)){var scaffold=modelObject.getScaffoldFromAlias(entry.alias);scaffold&&(pasteEntry.blockConfigModel=modelObject.getBlockConfiguration(scaffold.contentTypeKey))}blockPickerModel.clipboardItems.push(pasteEntry)});var entriesForPaste=clipboardService.retriveEntriesOfType(clipboardService.TYPES.BLOCK,vm.availableContentTypesAliases);entriesForPaste.forEach(function(entry){var pasteEntry={type:clipboardService.TYPES.BLOCK,date:entry.date,pasteData:entry.data,elementTypeModel:{name:entry.label,icon:entry.icon}};!1===Array.isArray(entry.data)&&(pasteEntry.blockConfigModel=modelObject.getBlockConfiguration(entry.data.data.contentTypeKey)),vm.clipboardItems.push(pasteEntry)}),vm.clipboardItems.sort(function(a,b){return b.date-a.date}),!0!==firstTime&&vm.clipboardItems.length>oldAmount&&function jumpClipboard(){if(jumpClipboardTimeout)return;vm.jumpClipboardButton=!0,jumpClipboardTimeout=$timeout(function(){vm.jumpClipboardButton=!1,jumpClipboardTimeout=null},2e3)}()}function requestCopyAllBlocks(){var aliases=[],elementTypesToCopy=vm.layout.filter(function(entry){return!0!==entry.$block.config.unsupported}).map(function(entry){return aliases.push(entry.$block.content.contentTypeAlias),{layout:entry.$block.layout,data:entry.$block.data,settingsData:entry.$block.settingsData}});aliases=aliases.filter(function(item,index){return aliases.indexOf(item)===index});var contentNodeName="?",contentNodeIcon=null;vm.umbVariantContent?(contentNodeName=vm.umbVariantContent.editor.content.name,vm.umbVariantContentEditors?contentNodeIcon=vm.umbVariantContentEditors.content.icon.split(" ")[0]:vm.umbElementEditorContent&&(contentNodeIcon=vm.umbElementEditorContent.model.documentType.icon.split(" ")[0])):vm.umbElementEditorContent&&(contentNodeName=vm.umbElementEditorContent.model.documentType.name,contentNodeIcon=vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]),localizationService.localize("clipboard_labelForArrayOfItemsFrom",[vm.model.label,contentNodeName]).then(function(localizedLabel){clipboardService.copyArray(clipboardService.TYPES.BLOCK,aliases,elementTypesToCopy,localizedLabel,contentNodeIcon||"icon-thumbnail-list",vm.model.id)})}function copyBlock(block){clipboardService.copy(clipboardService.TYPES.BLOCK,block.content.contentTypeAlias,{layout:block.layout,data:block.data,settingsData:block.settingsData},block.label,block.content.icon,block.content.udi)}function requestPasteFromClipboard(index,pasteEntry,pasteType){if(void 0===pasteEntry)return!1;var layoutEntry;if(pasteType===clipboardService.TYPES.ELEMENT_TYPE)layoutEntry=modelObject.createFromElementType(pasteEntry);else{if(pasteType!==clipboardService.TYPES.BLOCK)return!1;layoutEntry=modelObject.createFromBlockData(pasteEntry)}if(null===layoutEntry)return!1;var blockObject=getBlockObject(layoutEntry);return null!==blockObject&&(layoutEntry.$block=blockObject,vm.layout.splice(index,0,layoutEntry),vm.currentBlockInFocus=blockObject,!0)}function requestDeleteBlock(block){localizationService.localizeMany(["general_delete","blockEditor_confirmDeleteBlockMessage","contentTypeEditor_yesDelete"]).then(function(data){var overlay={title:data[0],content:localizationService.tokenReplace(data[1],[block.label]),submitButtonLabel:data[2],close:function close(){overlayService.close()},submit:function submit(){deleteBlock(block),overlayService.close()}};overlayService.confirmDelete(overlay)})}function requestDeleteAllBlocks(){localizationService.localizeMany(["content_nestedContentDeleteAllItems","general_delete"]).then(function(data){overlayService.confirmDelete({title:data[1],content:data[0],close:function close(){overlayService.close()},submit:function submit(){!function deleteAllBlocks(){for(;vm.layout.length;)deleteBlock(vm.layout[0].$block)}(),overlayService.close()}})})}vm.loading=!0,vm.currentBlockInFocus=null,vm.setBlockFocus=function(block){null!==vm.currentBlockInFocus&&(vm.currentBlockInFocus.focus=!1),vm.currentBlockInFocus=block,block.focus=!0},vm.supportCopy=clipboardService.isSupported(),vm.clipboardItems=[],unsubscribe.push(eventsService.on("clipboardService.storageUpdate",updateClipboard)),unsubscribe.push($scope.$on("editors.content.splitViewChanged",function(event,eventData){var compositeId=vm.umbVariantContent.editor.compositeId;eventData.editors.some(function(x){return x.compositeId===compositeId})&&function updateAllBlockObjects(){vm.layout.forEach(function(entry){entry.$block&&updateBlockObject(entry.$block)})}()})),vm.layout=[],vm.availableBlockTypes=[],vm.labels={},localizationService.localizeMany(["grid_addElement","content_createEmpty"]).then(function(data){vm.labels.grid_addElement=data[0],vm.labels.content_createEmpty=data[1]}),vm.$onInit=function(){if(vm.umbProperty&&!vm.umbVariantContent){var found=angularHelper.traverseScopeChain($scope,function(s){return s&&s.vm&&"umbVariantContentController"===s.vm.constructor.name});if(vm.umbVariantContent=found?found.vm:null,!vm.umbVariantContent)throw"Could not find umbVariantContent in the $scope chain"}vm.model.onValueChanged=onServerValueChanged,inlineEditing=vm.model.config.useInlineEditingAsDefault,liveEditing=vm.model.config.useLiveEditing,vm.validationLimit=vm.model.config.validationLimit,vm.listWrapperStyles={},vm.model.config.maxPropertyWidth&&(vm.listWrapperStyles["max-width"]=vm.model.config.maxPropertyWidth),"object"===_typeof(vm.model.value)&&null!==vm.model.value||(vm.model.value={});var scopeOfExistence=$scope;vm.umbVariantContentEditors&&vm.umbVariantContentEditors.getScope?scopeOfExistence=vm.umbVariantContentEditors.getScope():vm.umbElementEditorContent&&vm.umbElementEditorContent.getScope&&(scopeOfExistence=vm.umbElementEditorContent.getScope());var propertyActions=[copyAllBlocksAction={labelKey:"clipboard_labelForCopyAllEntries",labelTokens:[vm.model.label],icon:"documents",method:requestCopyAllBlocks,isDisabled:!0},deleteAllBlocksAction={labelKey:"clipboard_labelForRemoveAllEntries",labelTokens:[],icon:"trash",method:requestDeleteAllBlocks,isDisabled:!0}];vm.umbProperty&&vm.umbProperty.setPropertyActions(propertyActions),(modelObject=blockEditorService.createModelObject(vm.model.value,vm.model.editor,vm.model.config.blocks,scopeOfExistence,$scope)).load().then(onLoaded)},vm.requestShowCreate=function requestShowCreate(createIndex,mouseEvent){if(vm.blockTypePicker)return;if(1===vm.availableBlockTypes.length){var blockType=vm.availableBlockTypes[0];!addNewBlock(createIndex,blockType.blockConfigModel.contentElementTypeKey)||mouseEvent.ctrlKey||mouseEvent.metaKey||userFlowWhenBlockWasCreated(createIndex)}else showCreateDialog(createIndex)},vm.requestShowClipboard=function requestShowClipboard(createIndex,mouseEvent){showCreateDialog(createIndex,!0)},vm.showCreateDialog=showCreateDialog,vm.blockEditorApi={activateBlock:activateBlock,editBlock:editBlock,copyBlock:copyBlock,requestDeleteBlock:requestDeleteBlock,deleteBlock:deleteBlock,openSettingsForBlock:function openSettingsForBlock(block,blockIndex,parentForm){editBlock(block,!0,blockIndex,parentForm)}},vm.sortableOptions={axis:"y",containment:"parent",cursor:"grabbing",handle:".blockelement__draggable-element",cancel:"input,textarea,select,option",classes:".blockelement--dragging",distance:5,tolerance:"pointer",scroll:!0,update:function update(ev,ui){setDirty()}},unsubscribe.push($scope.$watch(function(){return vm.layout.length},function onAmountOfBlocksChanged(){copyAllBlocksAction&&(copyAllBlocksAction.isDisabled=0===vm.layout.length);deleteAllBlocksAction&&(deleteAllBlocksAction.isDisabled=0===vm.layout.length);if(vm.propertyForm&&vm.validationLimit){var isMinRequirementGood=null===vm.validationLimit.min||vm.layout.length>=vm.validationLimit.min;vm.propertyForm.minCount.$setValidity("minCount",isMinRequirementGood);var isMaxRequirementGood=null===vm.validationLimit.max||vm.layout.length<=vm.validationLimit.max;vm.propertyForm.maxCount.$setValidity("maxCount",isMaxRequirementGood)}})),$scope.$on("$destroy",function(){var _iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=unsubscribe[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var subscription=_step.value;subscription()}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{_iteratorNormalCompletion||null==_iterator.return||_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}})},controllerAs:"vm",bindings:{model:"="},require:{propertyForm:"^form",umbProperty:"?^umbProperty",umbVariantContent:"?^^umbVariantContent",umbVariantContentEditors:"?^^umbVariantContentEditors",umbElementEditorContent:"?^^umbElementEditorContent"}})}(),function(){angular.module("umbraco").component("umbBlockListRow",{template:'<ng-form name="vm.blockRowForm" val-server-match="{ \'contains\' : { \'valServerMatchContent\': vm.layout.$block.content.key, \'valServerMatchSettings\': vm.layout.$block.settings.key } }"> <div class="umb-block-list__block" ng-class="{\'--active\':vm.layout.$block.active, \'--show-validation\': vm.layout.$block.showValidation === true}"> <umb-block-list-block stylesheet="{{::vm.layout.$block.config.stylesheet}}" class="umb-block-list__block--content" ng-class="{\'blockelement__draggable-element\': vm.layout.$block.config.stylesheet}" view="{{vm.layout.$block.view}}" api="vm.blockEditorApi" block="vm.layout.$block" index="vm.index" parent-form="vm.blockRowForm"> </umb-block-list-block> <div class="umb-block-list__block--actions"> <button type="button" class="btn-reset umb-outline action --settings" localize="title" title="actions_editSettings" ng-click="vm.blockEditorApi.openSettingsForBlock(vm.layout.$block, vm.index, vm.blockRowForm);" ng-class="{ \'--error\': vm.blockRowForm.$error.valServerMatchSettings && vm.valFormManager.isShowingValidation() }" ng-if="vm.layout.$block.showSettings === true"> <umb-icon icon="icon-settings" class="icon"></umb-icon> <span class="sr-only"> <localize key="general_settings">Settings</localize> </span> <div class="__error-badge">!</div> </button> <button type="button" class="btn-reset umb-outline action --copy" localize="title" title="actions_copy" ng-click="vm.blockEditorApi.copyBlock(vm.layout.$block);" ng-if="vm.layout.$block.showCopy === true"> <umb-icon icon="icon-documents" class="icon"></umb-icon> <span class="sr-only"> <localize key="general_copy">Copy</localize> </span> </button> <button type="button" class="btn-reset umb-outline action --delete" localize="title" title="actions_delete" ng-click="vm.blockEditorApi.requestDeleteBlock(vm.layout.$block);"> <umb-icon icon="icon-trash" class="icon"></umb-icon> <span class="sr-only"> <localize key="general_delete">Delete</localize> </span> </button> </div> </div> </ng-form> ',controller:function BlockListRowController($scope){this.$onInit=function(){}},controllerAs:"vm",bindings:{blockEditorApi:"<",layout:"<",index:"<"},require:{valFormManager:"^^valFormManager"}})}(),function(){angular.module("umbraco").component("umbMediaPicker3PropertyEditor",{template:'<div class="umb-mediapicker3"> <umb-load-indicator ng-if="vm.loading"></umb-load-indicator> <div class="umb-media-card-grid" ng-class="{\'--singleMode\':(vm.validationLimit.max === 1 && vm.model.value.length <= 1)}"> <div style="display:contents;" ui-sortable="vm.sortableOptions" ng-model="vm.model.value" ng-if="vm.loading !== true"> <div ng-repeat="media in vm.model.value track by media.key" class="umb-media-card-grid__cell"> <button type="button" ng-if="vm.loading !== true && vm.allowAdd && ((vm.singleMode === true && vm.model.value.length === 0) || vm.singleMode === false)" class="btn-reset umb-media-card-grid--inline-create-button" ng-click="vm.addMediaAt($index, $event)" ng-controller="Umbraco.PropertyEditors.MediaPicker3PropertyEditor.CreateButtonController as inlineCreateButtonCtrl" ng-mousemove="inlineCreateButtonCtrl.onMouseMove($event)"> <div class="__plus" ng-style="{\'top\':inlineCreateButtonCtrl.plusPosY}"> <umb-icon icon="icon-add" class="icon"></umb-icon> </div> </button> <umb-media-card media-key="media.mediaKey" on-name-clicked="vm.editMedia(media, $index, $event)" ng-class="{\'--active\': vm.activeMediaEntry === media}" has-error="vm.propertyForm.maxCount.$valid === false && $index >= vm.validationLimit.max" allowed-types="vm.allowedTypes"> <div class="__actions"> <button ng-if="vm.supportCopy" type="button" class="btn-reset __action umb-outline" localize="title" title="actions_copy" ng-click="vm.copyMedia(media); $event.stopPropagation();"> <umb-icon icon="icon-documents" class="icon"></umb-icon> </button> <button type="button" class="btn-reset __action umb-outline" localize="title" title="general_remove" ng-click="vm.removeMedia(media); $event.stopPropagation();"> <umb-icon icon="icon-trash" class="icon"></umb-icon> </button> </div> </umb-media-card> </div> </div> <button ng-if="vm.loading !== true && ((vm.singleMode === true && vm.model.value.length === 0) || vm.singleMode !== true)" id="{{vm.model.alias}}" type="button" class="btn-reset umb-media-card-grid__create-button umb-outline" ng-disabled="!vm.allowAdd" ng-click="vm.addMediaAt(vm.model.value.length, $event)"> <div> <umb-icon icon="icon-add" class="icon large"></umb-icon> <localize key="general_add">Add</localize> </div> </button> </div> <input type="hidden" name="modelValue" ng-model="vm.model.value" val-server="value"> <input type="hidden" name="minCount" ng-model="vm.model.value" val-server="minCount"> <input type="hidden" name="maxCount" ng-model="vm.model.value" val-server="maxCount"> <div ng-messages="vm.propertyForm.minCount.$error"> <div class="help text-error" ng-message="minCount"> <localize key="validation_entriesShort" tokens="[vm.validationLimit.min, vm.validationLimit.min - vm.model.value.length]" watch-tokens="true">Minimum %0% entries, needs <strong>%1%</strong> more.</localize> </div> <span class="help-inline" ng-message="valServer" ng-bind-html="vm.propertyForm.minCount.errorMsg">></span> </div> <div ng-messages="vm.propertyForm.maxCount.$error"> <div class="help text-error" ng-message="maxCount"> <localize key="validation_entriesExceed" tokens="[vm.validationLimit.max, vm.model.value.length - vm.validationLimit.max]" watch-tokens="true">Maximum %0% entries, <strong>%1%</strong> too many.</localize> </div> <span class="help-inline" ng-message="valServer" ng-bind-html="vm.propertyForm.maxCount.errorMsg"></span> </div> </div> ',controller:function MediaPicker3Controller($scope,editorService,clipboardService,localizationService,overlayService,userService,entityResource){var unsubscribe=[],copyAllMediasAction=null,removeAllMediasAction=null,vm=this;function onServerValueChanged(newVal,oldVal){null!==newVal&&Array.isArray(newVal)||(newVal=[],vm.model.value=newVal),vm.model.value.forEach(function(mediaEntry){return updateMediaEntryData(mediaEntry)})}function setDirty(){vm.propertyForm&&vm.propertyForm.$setDirty()}function changeMediaFor(mediaEntry,onSuccess){var mediaPicker={startNodeId:vm.model.config.startNodeId,startNodeIsVirtual:vm.model.config.startNodeIsVirtual,dataTypeKey:vm.model.dataTypeKey,multiPicker:!1,submit:function submit(model){editorService.close(),model.selection.forEach(function(entry){mediaEntry.mediaKey=entry.key}),mediaEntry.crops=null,mediaEntry.focalPoint=null,updateMediaEntryData(mediaEntry),onSuccess&&onSuccess()},close:function close(){editorService.close()}};vm.model.config.filter&&(mediaPicker.filter=vm.model.config.filter),editorService.mediaPicker(mediaPicker)}function resetCrop(cropEntry){Object.assign(cropEntry,vm.model.config.crops.find(function(c){return c.alias===cropEntry.alias})),cropEntry.coordinates=null,setDirty()}function updateMediaEntryData(mediaEntry){mediaEntry.crops=mediaEntry.crops||[],mediaEntry.focalPoint=mediaEntry.focalPoint||{left:.5,top:.5};var newCrops=Utilities.copy(vm.model.config.crops);newCrops.forEach(function(crop){var oldCrop=mediaEntry.crops.filter(function(x){return x.alias===crop.alias}).shift();oldCrop&&oldCrop.height===crop.height&&oldCrop.width===crop.width&&(crop.coordinates=oldCrop.coordinates)}),mediaEntry.crops=newCrops}function setActiveMedia(mediaEntryOrNull){vm.activeMediaEntry=mediaEntryOrNull}vm.loading=!0,vm.activeMediaEntry=null,vm.supportCopy=clipboardService.isSupported(),vm.addMediaAt=function addMediaAt(createIndex,$event){var mediaPicker={startNodeId:vm.model.config.startNodeId,startNodeIsVirtual:vm.model.config.startNodeIsVirtual,dataTypeKey:vm.model.dataTypeKey,multiPicker:!0!==vm.singleMode,clickPasteItem:function clickPasteItem(item,mouseEvent){if(Array.isArray(item.data)){var indexIncrementor=0;item.data.forEach(function(entry){requestPasteFromClipboard(createIndex+indexIncrementor,entry,item.type)&&indexIncrementor++})}else requestPasteFromClipboard(createIndex,item.data,item.type);mouseEvent.ctrlKey||mouseEvent.metaKey||mediaPicker.close()},submit:function submit(model){editorService.close();var indexIncrementor=0;model.selection.forEach(function(entry){var mediaEntry={};mediaEntry.key=String.CreateGuid(),mediaEntry.mediaKey=entry.key,updateMediaEntryData(mediaEntry),vm.model.value.splice(createIndex+indexIncrementor,0,mediaEntry),indexIncrementor++}),setDirty()},close:function close(){editorService.close()}};vm.model.config.filter&&(mediaPicker.filter=vm.model.config.filter);mediaPicker.clickClearClipboard=function($event){clipboardService.clearEntriesOfType(clipboardService.TYPES.Media,vm.allowedTypes||null)},mediaPicker.clipboardItems=clipboardService.retriveEntriesOfType(clipboardService.TYPES.MEDIA,vm.allowedTypes||null),mediaPicker.clipboardItems.sort(function(a,b){return b.date-a.date}),editorService.mediaPicker(mediaPicker)},vm.editMedia=function editMedia(mediaEntry,options,$event){$event&&$event.stopPropagation();options=options||{},setActiveMedia(mediaEntry);var documentInfo=getDocumentNameAndIcon(),mediaEntryClone=Utilities.copy(mediaEntry),mediaEditorModel={$parentScope:$scope,$parentForm:vm.propertyForm,createFlow:!0===options.createFlow,documentName:documentInfo.name,mediaEntry:mediaEntryClone,propertyEditor:{changeMediaFor:changeMediaFor,resetCrop:resetCrop},enableFocalPointSetter:vm.model.config.enableLocalFocalPoint||!1,view:"views/common/infiniteeditors/mediaentryeditor/mediaentryeditor.html",size:"large",submit:function submit(model){vm.model.value[vm.model.value.indexOf(mediaEntry)]=mediaEntryClone,setActiveMedia(null),editorService.close()},close:function close(model){model.createFlow,setActiveMedia(null),editorService.close()}};editorService.open(mediaEditorModel)},vm.removeMedia=function removeMedia(media){var index=vm.model.value.indexOf(media);-1!==index&&vm.model.value.splice(index,1)},vm.copyMedia=function copyMedia(mediaEntry){entityResource.getById(mediaEntry.mediaKey,"Media").then(function(mediaEntity){clipboardService.copy(clipboardService.TYPES.MEDIA,mediaEntity.metaData.ContentTypeAlias,mediaEntry,mediaEntity.name,mediaEntity.icon,mediaEntry.key)})},vm.labels={},localizationService.localizeMany(["grid_addElement","content_createEmpty"]).then(function(data){vm.labels.grid_addElement=data[0],vm.labels.content_createEmpty=data[1]}),vm.$onInit=function(){vm.validationLimit=vm.model.config.validationLimit||{},!1===vm.model.config.multiple&&(vm.validationLimit.max=1),vm.model.config.crops=vm.model.config.crops||[],vm.singleMode=1===vm.validationLimit.max,vm.allowedTypes=vm.model.config.filter?vm.model.config.filter.split(","):null,copyAllMediasAction={labelKey:"clipboard_labelForCopyAllEntries",labelTokens:[vm.model.label],icon:"documents",method:requestCopyAllMedias,isDisabled:!0},removeAllMediasAction={labelKey:"clipboard_labelForRemoveAllEntries",labelTokens:[],icon:"trash",method:requestRemoveAllMedia,isDisabled:!0};var propertyActions=[];vm.supportCopy&&propertyActions.push(copyAllMediasAction),propertyActions.push(removeAllMediasAction),vm.umbProperty&&vm.umbProperty.setPropertyActions(propertyActions),null!==vm.model.value&&Array.isArray(vm.model.value)||(vm.model.value=[]),vm.model.value.forEach(function(mediaEntry){return updateMediaEntryData(mediaEntry)}),vm.model.onValueChanged=onServerValueChanged,userService.getCurrentUser().then(function(userData){vm.model.config.startNodeId||(!0===vm.model.config.ignoreUserStartNodes?(vm.model.config.startNodeId=-1,vm.model.config.startNodeIsVirtual=!0):(vm.model.config.startNodeId=1!==userData.startMediaIds.length?-1:userData.startMediaIds[0],vm.model.config.startNodeIsVirtual=1!==userData.startMediaIds.length));var hasAccessToMedia=-1!==userData.allowedSections.indexOf("media");vm.allowEdit=hasAccessToMedia,vm.allowAdd=hasAccessToMedia,vm.loading=!1})};var getDocumentNameAndIcon=function getDocumentNameAndIcon(){var contentNodeName="?",contentNodeIcon=null;return vm.umbVariantContent?(contentNodeName=vm.umbVariantContent.editor.content.name,vm.umbVariantContentEditors?contentNodeIcon=vm.umbVariantContentEditors.content.icon.split(" ")[0]:vm.umbElementEditorContent&&(contentNodeIcon=vm.umbElementEditorContent.model.documentType.icon.split(" ")[0])):vm.umbElementEditorContent&&(contentNodeName=vm.umbElementEditorContent.model.documentType.name,contentNodeIcon=vm.umbElementEditorContent.model.documentType.icon.split(" ")[0]),{name:contentNodeName,icon:contentNodeIcon}},requestCopyAllMedias=function requestCopyAllMedias(){var mediaKeys=vm.model.value.map(function(x){return x.mediaKey});entityResource.getByIds(mediaKeys,"Media").then(function(entities){var aliases=entities.map(function(mediaEntity){return mediaEntity.metaData.ContentTypeAlias});aliases=aliases.filter(function(item,index){return aliases.indexOf(item)===index});var documentInfo=getDocumentNameAndIcon();localizationService.localize("clipboard_labelForArrayOfItemsFrom",[vm.model.label,documentInfo.name]).then(function(localizedLabel){clipboardService.copyArray(clipboardService.TYPES.MEDIA,aliases,vm.model.value,localizedLabel,documentInfo.icon||"icon-thumbnail-list",vm.model.id)})})};function requestPasteFromClipboard(createIndex,pasteEntry,pasteType){return void 0!==pasteEntry&&((pasteEntry=clipboardService.parseContentForPaste(pasteEntry,pasteType)).key=String.CreateGuid(),updateMediaEntryData(pasteEntry),vm.model.value.splice(createIndex,0,pasteEntry),!0)}function requestRemoveAllMedia(){localizationService.localizeMany(["mediaPicker_confirmRemoveAllMediaEntryMessage","general_remove"]).then(function(data){overlayService.confirmDelete({title:data[1],content:data[0],close:function close(){overlayService.close()},submit:function submit(){!function deleteAllMedias(){vm.model.value=[]}(),overlayService.close()}})})}vm.sortableOptions={cursor:"grabbing",handle:"umb-media-card",cancel:"input,textarea,select,option",classes:".umb-media-card--dragging",distance:5,tolerance:"pointer",scroll:!0,update:function update(ev,ui){setDirty()}},unsubscribe.push($scope.$watch(function(){return vm.model.value.length},function onAmountOfMediaChanged(){copyAllMediasAction&&(copyAllMediasAction.isDisabled=0===vm.model.value.length);removeAllMediasAction&&(removeAllMediasAction.isDisabled=0===vm.model.value.length);if(vm.propertyForm&&vm.validationLimit){var isMinRequirementGood=null===vm.validationLimit.min||vm.model.value.length>=vm.validationLimit.min;vm.propertyForm.minCount.$setValidity("minCount",isMinRequirementGood);var isMaxRequirementGood=null===vm.validationLimit.max||vm.model.value.length<=vm.validationLimit.max;vm.propertyForm.maxCount.$setValidity("maxCount",isMaxRequirementGood)}})),$scope.$on("$destroy",function(){var _iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=unsubscribe[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var subscription=_step.value;subscription()}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{_iteratorNormalCompletion||null==_iterator.return||_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}})},controllerAs:"vm",bindings:{model:"="},require:{propertyForm:"^form",umbProperty:"?^umbProperty",umbVariantContent:"?^^umbVariantContent",umbVariantContentEditors:"?^^umbVariantContentEditors",umbElementEditorContent:"?^^umbElementEditorContent"}})}()}();