@spinnaker/azure 0.2.0 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/loadBalancer/configure/advancedSettings.html +13 -0
- package/src/loadBalancer/configure/createLoadBalancer.controller.js +2 -0
- package/src/loadBalancer/loadBalancer.transformer.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,41 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.3.3](https://github.com/spinnaker/deck/compare/@spinnaker/azure@0.3.2...@spinnaker/azure@0.3.3) (2021-09-16)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @spinnaker/azure
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [0.3.2](https://github.com/spinnaker/deck/compare/@spinnaker/azure@0.3.1...@spinnaker/azure@0.3.2) (2021-09-15)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @spinnaker/azure
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [0.3.1](https://github.com/spinnaker/deck/compare/@spinnaker/azure@0.3.0...@spinnaker/azure@0.3.1) (2021-09-14)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @spinnaker/azure
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# [0.3.0](https://github.com/spinnaker/deck/compare/@spinnaker/azure@0.2.0...@spinnaker/azure@0.3.0) (2021-09-06)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Features
|
|
34
|
+
|
|
35
|
+
* **provider/azure:** Allow specifying App Gateway sku ([#9635](https://github.com/spinnaker/deck/issues/9635)) ([7e02b80](https://github.com/spinnaker/deck/commit/7e02b80deec2030178011c710c7a1c3e094cf876))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
6
41
|
# [0.2.0](https://github.com/spinnaker/deck/compare/@spinnaker/azure@0.1.0...@spinnaker/azure@0.2.0) (2021-09-02)
|
|
7
42
|
|
|
8
43
|
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as e from"angular";import{module as n}from"angular";import{HelpContentsRegistry as t,REST as a,CloudProviderRegistry as r,ConfirmationModalService as i,RecentHistoryService as l,InstanceReader as s,InstanceWriter as o,ModalInjector as c,ReactModal as d,ModalClose as u,noop as p,SETTINGS as m,TaskMonitor as g,AccountService as f,NetworkReader as v,LoadBalancerWriter as h,NameUtils as B,SECURITY_GROUP_READER as A,LOAD_BALANCER_READ_SERVICE as y,FirewallLabels as b,Registry as S,BakeExecutionLabel as D,AuthenticationService as z,PipelineTemplates as w,BakeryReader as G,StageConstants as C,TaskExecutor as k,InfrastructureCaches as F,CACHE_INITIALIZER_SERVICE as I,IMAGE_READER as E,ModalWizard as T,SERVER_GROUP_WRITER as x,UserVerification as N,ReactInjector as P,TaskMonitorWrapper as L,TaskReason as R,ServerGroupReader as M,ServerGroupWarningMessageService as U,ApplicationNameValidator as V,DeploymentStrategyRegistry as _}from"@spinnaker/core";import H from"lodash";import O from"@uirouter/angularjs";import Q from"angular-ui-bootstrap";import X from"react";import{Modal as q,Button as j}from"react-bootstrap";import W from"react-select";var Y,Z;(Z=Y||(Y={}))[Z.TAG_NUMBER_EXCEED=0]="TAG_NUMBER_EXCEED",Z[Z.TAG_KEY_LENGTH_EXCEED=1]="TAG_KEY_LENGTH_EXCEED",Z[Z.TAG_VALUE_LENGTH_EXCEED=2]="TAG_VALUE_LENGTH_EXCEED",Z[Z.TAG_KEY_INVALID_CHARACTER=3]="TAG_KEY_INVALID_CHARACTER",Z[Z.TAG_VALUE_INVALID_CHARACTER=4]="TAG_VALUE_INVALID_CHARACTER",Z[Z.TAG_OBJECT_UNDEFINED=5]="TAG_OBJECT_UNDEFINED";const $=[{type:"Azure Load Balancer",description:""},{type:"Azure Application Gateway",description:""}],J=class{static checkTags(e){if(!e)return{isValid:!1,error:5,errorMessage:"instanceTags is not defined"};const n=Object.keys(e).length;if(!(n>=0&&n<=J.TAG_LIMITATION))return{isValid:!1,error:0,errorMessage:`Number of tags exceeds the limit: ${J.TAG_LIMITATION}`};for(const[n,t]of Object.entries(e)){if(n.length>J.TAG_KEY_LENGTH_LIMITATION)return{isValid:!1,error:1,errorMessage:`Length of Tag key: ${n} exceeds the limit: ${J.TAG_KEY_LENGTH_LIMITATION}`};if(t.length>J.TAG_VALUE_LENGTH_LIMITATION)return{isValid:!1,error:2,errorMessage:`Length of Tag value: ${t} exceeds the limit: ${J.TAG_VALUE_LENGTH_LIMITATION}`};if(J.TAG_INVALID_CHAR_REG_EXR.test(n))return{isValid:!1,error:3,errorMessage:`Invalid characters in Tag key: ${n}`};if(J.TAG_INVALID_CHAR_REG_EXR.test(t))return{isValid:!1,error:4,errorMessage:`Invalid characters in Tag value: ${t}`}}return{isValid:!0,error:null}}static getLoadBalancerType(e){return e=e.toLowerCase().split("_").join(" "),$.find((n=>n.type.toLowerCase()===e))||null}};let K=J;K.TAG_LIMITATION=8,K.TAG_KEY_LENGTH_LIMITATION=512,K.TAG_VALUE_LENGTH_LIMITATION=256,K.TAG_INVALID_CHAR_REG_EXR=/[<>%&\\?/]/;const ee={"azure.securityGroup.ingress.description":"Friendly description of the rule you want to enable (limit 80 chars.)","azure.securityGroup.ingress.priority":"Rules are processed in priority order; the lower the number, the higher the priority. We recommend leaving gaps between rules - 100, 200, 300, etc. - so that it's easier to add new rules without having to edit existing rules. There are several default rules that can be overridden with priority (65000, 65001 and 65500). For more information visit http://portal.azure.com.","azure.securityGroup.ingress.source":"The source filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the incoming traffic from a specific source IP address range (CIDR format) that will be allowed or denied by this rule.","azure.securityGroup.ingress.sourcePortRange":"The source port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which ports incoming traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.","azure.securityGroup.ingress.destination":"The destination filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the outgoing traffic from a specific destination IP address range (CIDR format) that will be allowed or denied by this rule.","azure.securityGroup.ingress.destinationPortRange":"The destination port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which destination ports traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.","azure.securityGroup.ingress.direction":"Specifies whether the rule is for inbound or outbound traffic.","azure.securityGroup.ingress.actions":"To adjust the priority of a rule, move it up or down in the list of rules. Rules at the top of the list have the highest priority.","azure.securityGroup.ingress.destPortRanges":"Provide a single port, such as 80; a port range, such as 1024-65535; or a comma-separated list of single ports and/or port ranges, such as 80,1024-65535. Provide an asterisk (*) to allow traffic on any port.","azure.securityGroup.ingress.sourceIPCIDRRanges":"Provide an address range using CIDR notation, such as 192.168.99.0/24; an IP address, such as 192.168.99.0; or a comma-separated list of address ranges or IP addresses, such as 10.0.0.0/24,44.66.0.0/24","azure.serverGroup.imageName":"(Required) <b>Image</b> is the deployable Azure Machine Image.","azure.serverGroup.stack":"(Required) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","azure.serverGroup.detail":"(Required) <b>Detail</b> is a naming component to help distinguish specifics of the server group.","azure.serverGroup.scriptLocation":"The location of custom scripts separated by comma or semicolon to be downloaded on to each instance. A single script should be like: fileUri. Multiple scripts should be like fileUri1,fileUri2 or fileUri1;fileUri2","azure.serverGroup.commandToExecute":"Command(s) to execute custom scripts provided during provisioning of an instance.","azure.serverGroup.customData":"Script or metadata to be injected into each instances.","azure.serverGroup.customTags":`Custom tags on Virtual Machine Scale Set. Allow ${K.TAG_LIMITATION} tags at most.`,"azure.serverGroup.enableInboundNAT":"An Azure load balancer of the basic sku will be created with adding inbound NAT port-forwarding rules to facilitate loggin on VM instances. There is no charge for creating an Azure load balancer of the basic sku. This option is disabled if Availability Zones are set which require Standard Azure Load Balancer and an extra Network Security Group with correct inbound and outbound rules configured.","azure.serverGroup.lun":"Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM.","azure.serverGroup.diskSizeGB":"Specifies the size of an empty data disk in gigabytes. This value cannot be larger than 1023 GB","azure.serverGroup.managedDisk.storageAccountType":"You can choose between Azure managed disks types to support your workload or scenario.","azure.serverGroup.caching":"Changing the default host caching policy can adversely impact the performance of your application. You should run performance tests to measure its impact. To improve the total IOPS/throughput, we recommend striping across multiple disks and using premium (SSD) disks.","azure.serverGroup.userAssignedIdentities":"Allows your server to access Azure resources. Learn more here: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview","azure.loadBalancer.dnsName":'If there is no custom DNS label specified, a default DNS name will be created. The default value will be "GeneratedText.cloudapp.net" for Azure Application Gateway or "GeneratedText.[region].cloudapp.azure.com" for Azure Load Balancer.',"azure.loadBalancer.probes.probeInterval":"Probe interval in seconds. This value is the time interval between two consecutive probes.","azure.loadBalancer.probes.timeout":"Probe time-out in seconds. If a valid response is not received within this time-out period, the probe is marked as failed. Note that the time-out value should not be more than the Interval value.","azure.loadBalancer.probes.unhealthyThreshold":"Probe retry count. The back-end server is marked down after the consecutive probe failure count reaches the unhealthy threshold.","azure.loadBalancer.loadBalancingRules.idleTimeout":"Keep a TCP or HTTP connection open without relying on clients to send keep-alive messages.","azure.loadBalancer.loadBalancingRules.sessionPersistence":'Session persistence specifies that traffic from a client should be handled by the same virtual machine in the backend pool for the duration of a session. "None" specifies that successive requests from the same client may be handled by any virtual machine. "Client IP" specifies that successive requests from the same client IP address will be handled by the same virtual machine. "Client IP and protocol" specifies that successive requests from the same client IP address and protocol combination will be handled by the same virtual machine.'};Object.keys(ee).forEach((e=>t.register(e,ee[e])));n("spinnaker.azure.image.reader",[]).factory("azureImageReader",(function(){return{findImages:function(e){return a("/images/find").query(e).get().then((function(e){return e}),(function(){return[]}))},getImage:function(e,n,t){return a("/images").path(t,n,e).query({provider:"azure"}).get().then((function(e){return e&&e.length?e[0]:null}),(function(){return null}))}}}));n("spinnaker.azure.instanceType.service",[]).factory("azureInstanceTypeService",["$q",function(e){const n=[{type:"general",label:"General Purpose",description:"Balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers.",families:[{type:"B-series",description:"The B-series burstable VMs are ideal for workloads that do not need the full performance of the CPU continuously, like web servers, small databases and development and test environments.",instanceTypes:[{name:"Standard_B1ms",label:"Standard_B1ms",cpu:1,memory:2,storage:{type:"SSD",count:2,size:4}},{name:"Standard_B1s",label:"Standard_B1s",cpu:1,memory:1,storage:{type:"SSD",count:2,size:2}},{name:"Standard_B2ms",label:"Standard_B2ms",cpu:2,memory:8,storage:{type:"SSD",count:4,size:16}},{name:"Standard_B2s",label:"Standard_B2s",cpu:2,memory:4,storage:{type:"SSD",count:4,size:8}},{name:"Standard_B4ms",label:"Standard_B4ms",cpu:4,memory:16,storage:{type:"SSD",count:8,size:32}},{name:"Standard_B8ms",label:"Standard_B8ms",cpu:8,memory:32,storage:{type:"SSD",count:16,size:64}},{name:"Standard_B1ls",label:"Standard_B1ls",cpu:1,memory:.5,storage:{type:"SSD",count:2,size:1}}]},{type:"Dsv3-series",description:"The Dsv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.",instanceTypes:[{name:"Standard_D2s_v3",label:"Standard_D2s_v3",cpu:2,memory:8,storage:{type:"SSD",count:4,size:16}},{name:"Standard_D4s_v3",label:"Standard_D4s_v3",cpu:4,memory:16,storage:{type:"SSD",count:8,size:32}},{name:"Standard_D8s_v3",label:"Standard_D8s_v3",cpu:8,memory:32,storage:{type:"SSD",count:16,size:64}},{name:"Standard_D16s_v3",label:"Standard_D16s_v3",cpu:16,memory:64,storage:{type:"SSD",count:32,size:128}},{name:"Standard_D32s_v3",label:"Standard_D32s_v3",cpu:32,memory:128,storage:{type:"SSD",count:32,size:256}},{name:"Standard_D64s_v3",label:"Standard_D64s_v3",cpu:64,memory:256,storage:{type:"SSD",count:32,size:512}}]},{type:"Dv3-series",description:"The Dv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.",instanceTypes:[{name:"Standard_D2_v3",label:"Standard_D2_v3",cpu:2,memory:8,storage:{type:"SSD",count:4,size:50}},{name:"Standard_D4_v3",label:"Standard_D4_v3",cpu:4,memory:16,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D8_v3",label:"Standard_D8_v3",cpu:8,memory:32,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D16_v3",label:"Standard_D16_v3",cpu:16,memory:64,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D32_v3",label:"Standard_D32_v3",cpu:32,memory:128,storage:{type:"SSD",count:32,size:800}},{name:"Standard_D64_v3",label:"Standard_D64_v3",cpu:64,memory:256,storage:{type:"SSD",count:32,size:1600}}]},{type:"DSv2-series",description:"",instanceTypes:[{name:"Standard_DS1_v2",label:"Standard_DS1_v2",cpu:1,memory:3.5,storage:{type:"SSD",count:4,size:7}},{name:"Standard_DS2_v2",label:"Standard_DS2_v2",cpu:2,memory:7,storage:{type:"SSD",count:8,size:14}},{name:"Standard_DS3_v2",label:"Standard_DS3_v2",cpu:4,memory:14,storage:{type:"SSD",count:16,size:28}},{name:"Standard_DS4_v2",label:"Standard_DS4_v2",cpu:8,memory:28,storage:{type:"SSD",count:32,size:56}},{name:"Standard_DS5_v2",label:"Standard_DS5_v2",cpu:16,memory:56,storage:{type:"SSD",count:64,size:112}},{name:"Standard_DS11_v2",label:"Standard_DS11_v2",cpu:2,memory:14,storage:{type:"SSD",count:8,size:28}},{name:"Standard_DS12_v2",label:"Standard_DS12_v2",cpu:4,memory:28,storage:{type:"SSD",count:16,size:56}},{name:"Standard_DS13_v2",label:"Standard_DS13_v2",cpu:8,memory:56,storage:{type:"SSD",count:32,size:112}},{name:"Standard_DS14_v2",label:"Standard_DS14_v2",cpu:16,memory:112,storage:{type:"SSD",count:64,size:224}},{name:"Standard_DS15_v2",label:"Standard_DS15_v2",cpu:20,memory:140,storage:{type:"SSD",count:64,size:280}}]},{type:"Dv2-series",description:"",instanceTypes:[{name:"Standard_D1_v2",label:"Standard_D1_v2",cpu:1,memory:3.5,storage:{type:"SSD",count:4,size:50}},{name:"Standard_D2_v2",label:"Standard_D2_v2",cpu:2,memory:7,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D3_v2",label:"Standard_D3_v2",cpu:4,memory:14,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D4_v2",label:"Standard_D4_v2",cpu:8,memory:28,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D5_v2",label:"Standard_D5_v2",cpu:16,memory:56,storage:{type:"SSD",count:64,size:800}},{name:"Standard_D11_v2",label:"Standard_D11_v2",cpu:2,memory:14,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D12_v2",label:"Standard_D12_v2",cpu:4,memory:28,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D13_v2",label:"Standard_D13_v2",cpu:8,memory:56,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D14_v2",label:"Standard_D14_v2",cpu:16,memory:112,storage:{type:"SSD",count:64,size:800}},{name:"Standard_D15_v2",label:"Standard_D15_v2",cpu:20,memory:140,storage:{type:"SSD",count:64,size:280}}]},{type:"Av2-series",description:"",instanceTypes:[{name:"Standard_A1_v2",label:"Standard_A1_v2",cpu:1,memory:2,storage:{type:"SSD",count:2,size:10}},{name:"Standard_A2m_v2",label:"Standard_A2m_v2",cpu:2,memory:16,storage:{type:"SSD",count:4,size:20}},{name:"Standard_A2_v2",label:"Standard_A2_v2",cpu:2,memory:4,storage:{type:"SSD",count:4,size:20}},{name:"Standard_A4m_v2",label:"Standard_A4m_v2",cpu:4,memory:32,storage:{type:"SSD",count:8,size:40}},{name:"Standard_A4_v2",label:"Standard_A4_v2",cpu:4,memory:8,storage:{type:"SSD",count:8,size:40}},{name:"Standard_A8m_v2",label:"Standard_A8m_v2",cpu:8,memory:64,storage:{type:"SSD",count:16,size:80}},{name:"Standard_A8_v2",label:"Standard_A8_v2",cpu:8,memory:16,storage:{type:"SSD",count:16,size:80}}]},{type:"DC-series",description:"",instanceTypes:[{name:"Standard_DC2s",label:"Standard_DC2s",cpu:2,memory:8,storage:{type:"SSD",count:2,size:100}},{name:"Standard_DC4s",label:"Standard_DC4s",cpu:4,memory:16,storage:{type:"SSD",count:4,size:200}}]}],icon:"hdd"},{type:"compute",label:"Compute Optimized",description:"High CPU-to-memory ratio. Good for medium traffic web servers, network appliances, batch processes, and application servers.",families:[{type:"Fsv2-series",description:"",instanceTypes:[{name:"Standard_F2s_v2",label:"Standard_F2s_v2",cpu:2,memory:4,storage:{type:"SSD",count:4,size:16}},{name:"Standard_F4s_v2",label:"Standard_F4s_v2",cpu:4,memory:8,storage:{type:"SSD",count:8,size:32}},{name:"Standard_F8s_v2",label:"Standard_F8s_v2",cpu:8,memory:16,storage:{type:"SSD",count:16,size:64}},{name:"Standard_F16s_v2",label:"Standard_F16s_v2",cpu:16,memory:32,storage:{type:"SSD",count:32,size:128}},{name:"Standard_F32s_v2",label:"Standard_F32s_v2",cpu:32,memory:64,storage:{type:"SSD",count:32,size:256}},{name:"Standard_F64s_v2",label:"Standard_F64s_v2",cpu:64,memory:128,storage:{type:"SSD",count:32,size:512}},{name:"Standard_F72s_v2",label:"Standard_F72s_v2",cpu:72,memory:144,storage:{type:"SSD",count:32,size:576}}]},{type:"Fs-series",description:"",instanceTypes:[{name:"Standard_F1s",label:"Standard_F1s",cpu:1,memory:2,storage:{type:"SSD",count:4,size:4}},{name:"Standard_F2s",label:"Standard_F2s",cpu:2,memory:4,storage:{type:"SSD",count:8,size:8}},{name:"Standard_F4s",label:"Standard_F4s",cpu:4,memory:8,storage:{type:"SSD",count:16,size:16}},{name:"Standard_F8s",label:"Standard_F8s",cpu:8,memory:16,storage:{type:"SSD",count:32,size:32}},{name:"Standard_F16s",label:"Standard_F16s",cpu:16,memory:32,storage:{type:"SSD",count:64,size:64}}]},{type:"F-series",description:"",instanceTypes:[{name:"Standard_F1",label:"Standard_F1",cpu:1,memory:2,storage:{type:"SSD",count:4,size:16}},{name:"Standard_F2",label:"Standard_F2",cpu:2,memory:4,storage:{type:"SSD",count:8,size:32}},{name:"Standard_F4",label:"Standard_F4",cpu:4,memory:8,storage:{type:"SSD",count:16,size:64}},{name:"Standard_F8",label:"Standard_F8",cpu:8,memory:16,storage:{type:"SSD",count:32,size:128}},{name:"Standard_F16",label:"Standard_F16",cpu:16,memory:32,storage:{type:"SSD",count:64,size:256}}]}],icon:"hdd"},{type:"custom",label:"Custom Type",description:"Select the instance type below.",families:[],icon:"asterisk"}];function t(e){return e&&e.storage?e.storage.count*e.storage.size:0}function a(){return n.map((function(e){for(const n of e.families)for(const e of n.instanceTypes)null==e.costFactor&&(e.costFactor=0);e.stats=function(e){const n={cpu:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},memory:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},storage:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},families:[]};return e.families&&e.families.length&&e.families.forEach((function(e){n.families.push(e.type);const a=H.minBy(e.instanceTypes,"cpu").cpu||Number.MAX_VALUE,r=H.maxBy(e.instanceTypes,"cpu").cpu||-Number.MAX_VALUE,i=H.minBy(e.instanceTypes,"memory").memory||Number.MAX_VALUE,l=H.maxBy(e.instanceTypes,"memory").memory||-Number.MAX_VALUE,s=t(H.minBy(e.instanceTypes,t))||Number.MAX_VALUE,o=t(H.maxBy(e.instanceTypes,t))||-Number.MAX_VALUE;n.cpu.min=Math.min(n.cpu.min,a),n.cpu.max=Math.max(n.cpu.max,r),n.memory.min=Math.min(n.memory.min,i),n.memory.max=Math.max(n.memory.max,l),n.storage.min=Math.min(n.storage.min,s),n.storage.max=Math.max(n.storage.max,o)})),n}(e)})),e.when(n)}return{getCategories:a,getAvailableTypesForRegions:function(e,n){const[t]=n;return e[t]},getAllTypesByRegion:function(){return a()}}}]);n("spinnaker.azure.instance.detail.controller",[O,Q]).controller("azureInstanceDetailsCtrl",["$scope","$state","$uibModal","instance","app","$q",function(e,n,t,a,c,d){function u(){const t={};let r,i,o,u,p;return c.serverGroups?(c.serverGroups.data.some((function(e){return e.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=e.loadBalancers,o=e.account,u=e.region,p=e.vpcId,t.serverGroup=e.name,t.vpcId=e.vpcId,!0}))})),r||(c.loadBalancers.data.some((function(e){return e.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=[e.name],o=e.account,u=e.region,p=e.vpcId,!0}))})),r||c.loadBalancers.data.some((function(e){return e.serverGroups.some((function(n){return!!n.isDisabled&&n.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=[e.name],o=e.account,u=e.region,p=e.vpcId,!0}))}))})))):(r={},i=[],o=a.account,u=a.region),r&&o&&u?(t.account=o,t.region=u,l.addExtraDataToLatest("instances",t),s.getInstanceDetails(o,u,a.instanceId).then((function(n){e.state.loading=!1,function(n,t){c.isStandalone&&(n.health=t.health),n.health=n.health||[];const a=n.health.filter((function(e){return"Azure"!==e.type||"Unknown"!==e.state}));t.health&&a.forEach((function(e){const n=t.health.filter((function(n){return n.type===e.type}));n.length&&H.defaults(e,n[0])})),e.healthMetrics=a}(r,n),e.instance=H.defaults(n,r),e.instance.account=o,e.instance.region=u,e.instance.vpcId=p,e.instance.loadBalancers=i;const t=H.find(e.healthMetrics,(function(e){return"Discovery"===e.type}));if(t&&t.vipAddress){const n=t.vipAddress;e.instance.vipAddress=n.includes(",")?n.split(","):[n]}e.baseIpAddress=n.publicDnsName||n.privateIpAddress}),(function(){e.state.loading=!1,n.go("^")}))):(r||(e.instanceIdNotFound=a.instanceId,e.state.loading=!1),d.when(null))}e.detailsTemplateUrl=r.getValue("azure","instance.detailsTemplateUrl"),e.state={loading:!0,standalone:c.isStandalone},this.canDeregisterFromLoadBalancer=function(){return e.instance.health.some((function(e){return"LoadBalancer"===e.type}))},this.canRegisterWithLoadBalancer=function(){const n=e.instance;if(!n.loadBalancers||!n.loadBalancers.length)return!1;const t=n.health.some((function(e){return"LoadBalancer"===e.type&&"OutOfService"===e.state})),a=n.health.some((function(e){return"LoadBalancer"===e.type}));return t||!a},this.canRegisterWithDiscovery=function(){const n=e.instance.health.filter((function(e){return"Discovery"===e.type}));return!!n.length&&"OutOfService"===n[0].state},this.terminateInstance=function(){const t=e.instance,a={application:c,title:"Terminating "+t.instanceId,onTaskComplete:function(){n.includes("**.instanceDetails",{instanceId:t.instanceId})&&n.go("^")}};i.confirm({header:"Really terminate "+t.instanceId+"?",buttonText:"Terminate "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return o.terminateInstance(t,c)}})},this.terminateInstanceAndShrinkServerGroup=function(){const t=e.instance,a={application:c,title:"Terminating "+t.instanceId+" and shrinking server group",onTaskComplete:function(){n.includes("**.instanceDetails",{instanceId:t.instanceId})&&n.go("^")}};i.confirm({header:"Really terminate "+t.instanceId+" and shrink "+t.serverGroup+"?",buttonText:"Terminate "+t.instanceId+" and shrink "+t.serverGroup,account:t.account,taskMonitorConfig:a,submitMethod:function(){return o.terminateInstanceAndShrinkServerGroup(t,c)}})},this.rebootInstance=function(){const n=e.instance,t={application:c,title:"Rebooting "+n.instanceId};i.confirm({header:"Really reboot "+n.instanceId+"?",buttonText:"Reboot "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.rebootInstance(n,c)}})},this.registerInstanceWithLoadBalancer=function(){const n=e.instance,t=n.loadBalancers.join(" and "),a={application:c,title:"Registering "+n.instanceId+" with "+t};i.confirm({header:"Really register "+n.instanceId+" with "+t+"?",buttonText:"Register "+n.instanceId,account:n.account,taskMonitorConfig:a,submitMethod:function(){return o.registerInstanceWithLoadBalancer(n,c)}})},this.deregisterInstanceFromLoadBalancer=function(){const n=e.instance,t=n.loadBalancers.join(" and "),a={application:c,title:"Deregistering "+n.instanceId+" from "+t};i.confirm({header:"Really deregister "+n.instanceId+" from "+t+"?",buttonText:"Deregister "+n.instanceId,account:n.account,taskMonitorConfig:a,submitMethod:function(){return o.deregisterInstanceFromLoadBalancer(n,c)}})},this.enableInstanceInDiscovery=function(){const n=e.instance,t={application:c,title:"Enabling "+n.instanceId+" in discovery"};i.confirm({header:"Really enable "+n.instanceId+" in discovery?",buttonText:"Enable "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.enableInstanceInDiscovery(n,c)}})},this.disableInstanceInDiscovery=function(){const n=e.instance,t={application:c,title:"Disabling "+n.instanceId+" in discovery"};i.confirm({header:"Really disable "+n.instanceId+" in discovery?",buttonText:"Disable "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.disableInstanceInDiscovery(n,c)}})},this.hasHealthState=function(n,t){return e.instance.health.some((function(e){return e.type===n&&e.state===t}))};(c.isStandalone?u():d.all([c.serverGroups.ready(),c.loadBalancers.ready()]).then(u)).then((()=>{e.$$destroyed||c.isStandalone||c.serverGroups.onRefresh(e,u)})),e.account=a.account}]);const ne=class extends X.Component{constructor(e){super(e),this.choose=()=>{this.close();const e=r.getValue("azure","loadBalancer");c.modalService.open({templateUrl:e.createLoadBalancerTemplateUrl,windowClass:"modal-z-index",controller:`${e.createLoadBalancerController} as ctrl`,size:"lg",resolve:{application:()=>this.props.app,loadBalancer:()=>null,isNew:()=>!0,forPipelineConfig:()=>!1,loadBalancerType:()=>this.state.selectedChoice}}).result.catch((()=>{}))},this.close=e=>{this.props.dismissModal(e)},this.state={choices:$,selectedChoice:$[0]}}static show(e){return d.show(ne,{...e,className:"create-pipeline-modal-overflow-visible"})}choiceSelected(e){this.setState({selectedChoice:e})}render(){const{choices:e,selectedChoice:n}=this.state;return X.createElement(X.Fragment,null,X.createElement(u,{dismiss:this.close}),X.createElement(q.Header,null,X.createElement(q.Title,null,"Select Type of Load Balancer")),X.createElement(q.Body,null,X.createElement("div",{className:"modal-body"},X.createElement("div",{className:"card-choices"},e.map((e=>X.createElement("div",{key:e.type,className:"card "+(n===e?"active":""),onClick:()=>this.choiceSelected(e)},X.createElement("h3",{className:"load-balancer-label"},e.type),X.createElement("div",null,e.description))))),X.createElement("div",{className:"load-balancer-description"}))),X.createElement(q.Footer,null,X.createElement(j,{onClick:this.choose},"Configure Load Balancer ",X.createElement("span",{className:"glyphicon glyphicon-chevron-right"}))))}};let te=ne;te.defaultProps={closeModal:p,dismissModal:p};const ae=m.providers.azure||{defaults:{}};ae&&(ae.resetToOriginal=m.resetProvider("azure"));n("spinnaker.azure.loadBalancer.transformer",[]).factory("azureLoadBalancerTransformer",["$q",function(e){return{normalizeLoadBalancer:function(n){n.serverGroups.forEach((function(e){e.account=n.account,e.region=n.region,e.detachedInstances?(e.detachedInstances=e.detachedInstances.map((function(e){return{id:e}})),e.instances=e.instances.concat(e.detachedInstances)):e.detachedInstances=[]}));const t=H.filter(n.serverGroups,{isDisabled:!1});return n.provider=n.type,n.instances=H.chain(t).map("instances").flatten().value(),n.detachedInstances=H.chain(t).map("detachedInstances").flatten().value(),e.resolve(n)},convertLoadBalancerForEditing:function(e){const n={region:e.region,credentials:e.account,name:e.name,stack:e.stack,detail:e.detail,vnet:e.vnet,subnet:e.subnet,probes:[],loadBalancingRules:[]};if(e.elb){const t=e.elb;n.securityGroups=t.securityGroups,n.vnet=t.vnet,t.loadBalancingRules&&(n.loadBalancingRules=t.loadBalancingRules),n.probes=t.probes,t.dnsName&&"dns-not-found"!==t.dnsName&&(n.dnsName=t.dnsName.split(".")[0])}return n},constructNewLoadBalancerTemplate:function(e){return{stack:"",detail:"frontend",credentials:e.defaultCredentials.azure||ae.defaults.account,region:e.defaultRegions.azure||ae.defaults.region,cloudProvider:"azure",vnet:null,subnet:null,probes:[{probeName:"",probeProtocol:"HTTP",probePort:"80",probePath:"/",probeInterval:30,unhealthyThreshold:8,timeout:120}],securityGroups:[],loadBalancingRules:[{ruleName:"",protocol:"HTTP",externalPort:80,backendPort:80,probeName:"",persistence:"None",idleTimeout:4}]}}}}]);n("spinnaker.azure.loadBalancer.create.controller",[O,"spinnaker.azure.loadBalancer.transformer"]).controller("azureCreateLoadBalancerCtrl",["$scope","$uibModalInstance","$state","azureLoadBalancerTransformer","application","loadBalancer","isNew","loadBalancerType",function(e,n,t,a,r,i,l,s){const o=this;function c(){if(e.$$destroyed)return;n.close();const a={name:e.loadBalancer.name,accountId:e.loadBalancer.credentials,region:e.loadBalancer.region,provider:"azure"};t.includes("**.loadBalancerDetails")?t.go("^.loadBalancerDetails",a):t.go(".loadBalancerDetails",a)}function d(){const n=e.loadBalancer.credentials,t=e.loadBalancer.region,a={};r.getDataSource("loadBalancers").refresh(!0).then((()=>{r.getDataSource("loadBalancers").data.forEach((e=>{e.account===n&&(a[e.region]=a[e.region]||[],a[e.region].push(e.name))})),e.existingLoadBalancerNames=a[t]||[]}))}e.regions=[],e.pages={location:"azure/src/loadBalancer/configure/createLoadBalancerProperties.html",listeners:"azure/src/loadBalancer/configure/listeners.html",healthCheck:"azure/src/loadBalancer/configure/healthCheck.html",advancedSettings:"azure/src/loadBalancer/configure/advancedSettings.html"},e.isNew=l,e.loadBalancerType=s.type,e.isALB="Azure Load Balancer"===s.type,e.state={accountsLoaded:!1,submitting:!1},e.taskMonitor=new g({application:r,title:(l?"Creating ":"Updating ")+"your load balancer",modalInstance:n,onTaskComplete:function(){r.loadBalancers.refresh(),r.loadBalancers.onNextRefresh(e,c)}}),function(){if(i){if(e.loadBalancer=a.convertLoadBalancerForEditing(i),l){const n=B.parseLoadBalancerName(e.loadBalancer.name);e.loadBalancer.stack=n.stack,e.loadBalancer.detail=n.freeFormDetails,delete e.loadBalancer.name}}else e.loadBalancer=a.constructNewLoadBalancerTemplate(r);l&&(d(),f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accountsLoaded=!0,o.accountUpdated()})))}(),this.requiresHealthCheckPath=function(){return e.loadBalancer.probes[0].probeProtocol&&0===e.loadBalancer.probes[0].probeProtocol.indexOf("HTTP")},this.updateName=function(){e.loadBalancer.name=this.getName()},this.getName=function(){const n=e.loadBalancer,t=[r.name,n.stack||"",n.detail||""].join("-");return H.trimEnd(t,"-")},this.accountUpdated=function(){f.getRegionsForAccount(e.loadBalancer.credentials).then((function(n){e.regions=n,o.regionUpdated()}))},this.regionUpdated=function(){d(),o.updateName(),o.vnetUpdated()},this.vnetUpdated=function(){const n=e.loadBalancer.credentials,t=e.loadBalancer.region;e.loadBalancer.selectedVnet=null,e.loadBalancer.vnet=null,e.loadBalancer.vnetResourceGroup=null,o.selectedVnets=[],v.listNetworks().then((function(e){e.azure&&e.azure.forEach((e=>{e.account===n&&e.region===t&&o.selectedVnets.push(e)}))})),o.subnetUpdated()},this.subnetUpdated=function(){e.loadBalancer.selectedSubnet=null,e.loadBalancer.subnet=null,o.selectedSubnets=[]},this.selectedVnetChanged=function(n){e.loadBalancer.vnet=n.name,e.loadBalancer.vnetResourceGroup=n.resourceGroup,e.loadBalancer.selectedSubnet=null,e.loadBalancer.subnet=null,o.selectedSubnets=[],n.subnets&&n.subnets.map((function(e){let n=!0;e.devices&&e.devices.map((function(e){e&&"applicationGateways"!==e.type&&(n=!1)})),n&&o.selectedSubnets.push(e)}))},this.removeListener=function(n){e.loadBalancer.loadBalancingRules.splice(n,1)},this.addListener=function(){e.loadBalancer.loadBalancingRules.push({protocol:"HTTP"})},this.submit=function(){const n=l?"Create":"Update";e.taskMonitor.submit((function(){const t={cloudProvider:"azure",appName:r.name,clusterName:e.loadBalancer.clusterName,resourceGroupName:e.loadBalancer.clusterName,loadBalancerName:e.loadBalancer.name};e.loadBalancer.selectedVnet&&(e.loadBalancer.vnet=e.loadBalancer.selectedVnet.name,e.loadBalancer.vnetResourceGroup=e.loadBalancer.selectedVnet.resourceGroup),e.loadBalancer.selectedSubnet&&(e.loadBalancer.subnet=e.loadBalancer.selectedSubnet.name);const a=e.loadBalancer.clusterName||e.loadBalancer.name,i=a+"-probe",l=a+"-rule";return e.loadBalancer.type="upsertLoadBalancer",e.loadBalancer.loadBalancerType=e.loadBalancerType,e.loadBalancer.vnet||e.loadBalancer.subnetType||(e.loadBalancer.securityGroups=null),e.loadBalancer.probes[0].probeName=i,e.loadBalancer.loadBalancingRules.forEach(((e,n)=>{e.ruleName=l+n,e.probeName=i})),"TCP"===e.loadBalancer.probes[0].probeProtocol&&(e.loadBalancer.probes[0].probePath=void 0),h.upsertLoadBalancer(e.loadBalancer,r,n,t)}))},this.cancel=function(){n.dismiss()}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/createLoadBalancerProperties.html",'<div>\n <div ng-if="!state.accountsLoaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div class="modal-body" ng-if="state.accountsLoaded">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.loadBalancerName.$error.validateUnique, \'alert-info\': !form.loadBalancerName.$error.validateUnique}"\n >\n <strong>Your {{loadBalancerType}} will be named:</strong>\n <span>{{ctrl.getName()}}</span>\n \x3c!-- Angular does not seem to run length validation on hidden inputs, hence the text + display:none --\x3e\n <input\n type="text"\n style="display: none"\n ng-maxlength="32"\n class="form-control input-sm"\n ng-model="loadBalancer.name"\n validate-unique="existingLoadBalancerNames"\n validate-ignore-case="true"\n name="loadBalancerName"\n />\n <validation-error\n ng-if="form.loadBalancerName.$error.validateUnique"\n message="There is already a load balancer in {{loadBalancer.credentials}}:{{loadBalancer.region}} with that name."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Account</div>\n <div class="col-md-7">\n <account-select-field\n required\n component="loadBalancer"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <region-select-field\n required\n label-columns="3"\n component="loadBalancer"\n field="region"\n account="loadBalancer.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-3 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="loadBalancer.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks"\n >{{$select.selected.name}}</ui-select-match\n >\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-3 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="loadBalancer.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack <help-field key="azure.loadBalancer.stack"></help-field></div>\n <div class="col-md-3">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-model="loadBalancer.stack"\n name="stackName"\n ng-change="ctrl.updateName()"\n ng-pattern="/^[a-zA-Z0-9]*$/"\n />\n </div>\n <div class="col-md-6 form-inline">\n <label class="sm-label-right"> Detail <help-field key="azure.loadBalancer.detail"></help-field> </label>\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-model="loadBalancer.detail"\n name="detailName"\n ng-change="ctrl.updateName()"\n ng-pattern="/^[a-zA-Z0-9-]*$/"\n />\n </div>\n <div class="col-md-7 col-md-offset-3" ng-if="form.stackName.$error.pattern">\n <validation-error message="Stack can only contain letters and numbers."></validation-error>\n </div>\n <div class="col-md-7 col-md-offset-3" ng-if="form.detailName.$error.pattern">\n <validation-error message="Detail can only contain letters, numbers, and dashes."></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-9 col-md-offset-3" ng-if="form.loadBalancerName.$error.maxlength">\n <validation-error message="Load Balancer name can only be 32 characters."></validation-error>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/listeners.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th>Protocol</th>\n <th>External Port</th>\n <th></th>\n <th>Internal Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in loadBalancer.loadBalancingRules">\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.protocol"\n ng-init="rule.protocol = (isALB ? \'TCP\' : \'HTTP\')"\n ng-options="protocol for protocol in (isALB ? [\'TCP\', \'UDP\'] : [\'HTTP\'])"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="number" min="0" ng-model="rule.externalPort" required />\n </td>\n <td class="small" style="padding-top: 10px">→</td>\n <td>\n <input class="form-control input-sm" type="number" min="0" ng-model="rule.backendPort" required />\n </td>\n <td>\n <a href class="sm-label" ng-click="ctrl.removeListener($index)"\n ><span class="glyphicon glyphicon-trash"></span\n ></a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="5">\n <button class="add-new col-md-12" ng-click="ctrl.addListener()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new port mapping\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/healthCheck.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed" ng-if="!isALB">\n <thead>\n <tr>\n <th width="35%">Protocol</th>\n <th width="30%">Host</th>\n <th><span ng-if="ctrl.requiresHealthCheckPath()">Path</span></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.probes[0].probeProtocol"\n required\n ng-options="protocol for protocol in [\'HTTP\']"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.probes[0].probePort" />\n </td>\n <td>\n <input\n ng-if="ctrl.requiresHealthCheckPath()"\n class="form-control input-sm"\n type="text"\n ng-model="loadBalancer.probes[0].probePath"\n required\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <table class="table table-condensed packed" ng-if="isALB">\n <thead>\n <tr>\n <th width="35%">Protocol</th>\n <th width="30%">Port</th>\n <th><span ng-if="ctrl.requiresHealthCheckPath()">Path</span></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.probes[0].probeProtocol"\n ng-init="loadBalancer.probes[0].probeProtocol = \'TCP\'"\n required\n ng-options="protocol for protocol in [\'TCP\', \'HTTP\']"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.probes[0].probePort" />\n </td>\n <td>\n <input\n ng-if="ctrl.requiresHealthCheckPath()"\n class="form-control input-sm"\n type="text"\n ng-model="loadBalancer.probes[0].probePath"\n required\n />\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/advancedSettings.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <div class="form-group">\n <div class="col-md-3">\n <b>Custom DNS Label</b>\n <help-field key="azure.loadBalancer.dnsName"></help-field>\n </div>\n <div class="col-md-6">\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.dnsName" />\n <span>.{{loadBalancer.region}}.cloudapp.azure.com</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3">\n <b>Health Check</b>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Interval</b>\n <help-field key="azure.loadBalancer.probes.probeInterval"></help-field>\n </div>\n <div class="col-md-4">\n <input class="form-control input-sm" type="number" min="0" ng-model="loadBalancer.probes[0].probeInterval" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Unhealthy Threshold</b>\n <help-field key="azure.loadBalancer.probes.unhealthyThreshold"></help-field>\n </div>\n <div class="col-md-4">\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n ng-model="loadBalancer.probes[0].unhealthyThreshold"\n />\n </div>\n </div>\n <div class="form-group" ng-if="isALB">\n <div class="col-md-4 sm-label-right">\n <b>Idle Timeout</b>\n <help-field key="azure.loadBalancer.loadBalancingRules.idleTimeout"></help-field>\n </div>\n <div class="col-md-4">\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n ng-model="loadBalancer.loadBalancingRules[0].idleTimeout"\n />\n </div>\n </div>\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-4 sm-label-right">\n <b>Timeout</b>\n <help-field key="azure.loadBalancer.probes.timeout"></help-field>\n </div>\n <div class="col-md-4">\n <input class="form-control input-sm" type="number" min="0" ng-model="loadBalancer.probes[0].timeout" />\n </div>\n </div>\n <div class="form-group" ng-if="isALB">\n <div class="col-md-4 sm-label-right">\n <b>Session persistence</b>\n <help-field key="azure.loadBalancer.loadBalancingRules.sessionPersistence"></help-field>\n </div>\n <div class="col-md-4">\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.sessionPersistence"\n ng-init="loadBalancer.sessionPersistence = \'None\'"\n required\n ng-options="p for p in [\'None\', \'Client IP\', \'Client IP and protocol\']"\n ></select>\n </div>\n </div>\n </div>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.loadBalancer.details.controller",[Q,O,A,y]).controller("azureLoadBalancerDetailsCtrl",["$scope","$state","$exceptionHandler","$uibModal","loadBalancer","app","securityGroupReader","loadBalancerReader","$q",function(n,t,a,r,l,s,o,c,d){function u(){if(n.loadBalancer=s.loadBalancers.data.filter((function(e){return e.name===l.name&&e.region===l.region&&e.account===l.accountId}))[0],n.loadBalancer){return c.getLoadBalancerDetails(n.loadBalancer.provider,l.accountId,l.region,l.name).then((function(e){n.state.loading=!1;const t=[],a=e.filter((function(e){return e.name===l.name}));if(a.length&&(n.loadBalancer.elb=a[0],n.loadBalancer.account=l.accountId,n.loadBalancer.elb.securityGroups&&(n.loadBalancer.elb.securityGroups.forEach((function(e){const n=o.getApplicationSecurityGroup(s,l.accountId,l.region,e);n&&t.push(n)})),n.securityGroups=H.sortBy(t,"name")),n.loadBalancer.loadBalancerType&&n.loadBalancer.loadBalancerType.includes("_"))){const e=n.loadBalancer.loadBalancerType;n.loadBalancer.loadBalancerType=e.split("_").map((e=>{const n=e.toLowerCase();return n.substring(0,1).toUpperCase()+n.substring(1)})).join(" ")}}))}return n.loadBalancer||t.go("^"),d.when(null)}n.state={loading:!0},n.firewallsLabel=b.get("Firewalls"),s.ready().then(u).then((()=>{n.$$destroyed||s.onRefresh(n,u)})),this.editLoadBalancer=function(){r.open({templateUrl:"azure/src/loadBalancer/configure/editLoadBalancer.html",controller:"azureCreateLoadBalancerCtrl as ctrl",size:"lg",resolve:{application:function(){return s},loadBalancer:function(){return e.copy(n.loadBalancer)},isNew:function(){return!1},loadBalancerType:function(){return{type:n.loadBalancer.loadBalancerType}}}})},this.deleteLoadBalancer=function(){if(n.loadBalancer.instances&&n.loadBalancer.instances.length)return;const e={application:s,title:"Deleting "+l.name},t={cloudProvider:"azure",loadBalancerName:n.loadBalancer.name,loadBalancerType:n.loadBalancer.loadBalancerType,credentials:n.loadBalancer.account,region:l.region,appName:s.name};i.confirm({header:"Really delete "+l.name+"?",buttonText:"Delete "+l.name,account:l.accountId,taskMonitorConfig:e,submitMethod:()=>h.deleteLoadBalancer(t,s)})}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/editLoadBalancer.html",'<form name="form" novalidate validate-on-submit>\n <v2-modal-wizard\n heading="Edit {{loadBalancerType}} {{loadBalancer.name}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="Listeners" label="Listeners" done="true">\n <ng-include src="pages.listeners"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Health Check" label="Health Check" done="true" hide-subheading="true">\n <ng-include src="pages.healthCheck"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Advanced Settings" label="Advanced Settings" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.submit()"\n is-new="isNew"\n ></submit-button>\n </div>\n</form>\n')}]);n("spinnaker.azure.pipeline.stage.bake.executionDetails.controller",[O]).controller("azureBakeExecutionDetailsCtrl",["$scope","$stateParams","executionDetailsSectionService","$interpolate",function(e,n,t,a){e.configSections=["bakeConfig","taskStatus"];const r=()=>{e.detailsSection=n.details,e.provider=e.stage.context.cloudProviderType||"azure",e.roscoMode=m.feature.roscoMode||"function"==typeof m.feature.roscoSelector&&m.feature.roscoSelector(e.stage.context),e.bakeryDetailUrl=a(e.roscoMode&&m.roscoDetailUrl?m.roscoDetailUrl:m.bakeryDetailUrl)},i=()=>t.synchronizeSection(e.configSections,r);i(),e.$on("$stateChangeSuccess",i)}]);n("spinnaker.azure.pipeline.stage.bakeStage",["spinnaker.azure.pipeline.stage.bake.executionDetails.controller"]).config((function(){S.pipeline.registerStage({provides:"bake",cloudProvider:"azure",label:"Bake",description:"Bakes an image",templateUrl:"azure/src/pipeline/stages/bake/bakeStage.html",executionDetailsUrl:"azure/src/pipeline/stages/bake/bakeExecutionDetails.html",executionLabelComponent:D,extraLabelLines:e=>e.masterStage.context.allPreviouslyBaked||e.masterStage.context.somePreviouslyBaked?1:0,supportsCustomTimeout:!0,validators:[{type:"requiredField",fieldName:"package"},{type:"requiredField",fieldName:"regions"},{type:"upstreamVersionProvided",checkParentTriggers:!0,getMessage:e=>"Bake stages should always have a stage or trigger preceding them that provides version information: <ul>"+e.map((e=>`<li>${e}</li>`)).join("")+"</ul>Otherwise, Spinnaker will bake and deploy the most-recently built package."}],restartable:!0})})).controller("azureBakeStageCtrl",["$scope","$q","$uibModal",function(e,n,t){e.stage.extendedAttributes=e.stage.extendedAttributes||{},e.stage.regions=e.stage.regions||[],e.stage.user||(e.stage.user=z.getAuthenticatedUser().name),e.viewState={loading:!0},this.baseOsChanged=()=>{const n=H.find(e.baseOsOptions,{id:e.stage.baseOs});e.stage.osType=n.osType},this.addExtendedAttribute=function(){e.stage.extendedAttributes||(e.stage.extendedAttributes={}),t.open({templateUrl:w.addExtendedAttributes,controller:"bakeStageAddExtendedAttributeController",controllerAs:"addExtendedAttribute",resolve:{extendedAttribute:function(){return{key:"",value:""}}}}).result.then((function(n){e.stage.extendedAttributes[n.key]=n.value})).catch((()=>{}))},this.removeExtendedAttribute=function(n){delete e.stage.extendedAttributes[n]},this.showTemplateFileName=function(){return e.viewState.roscoMode||e.stage.templateFileName},this.showExtendedAttributes=function(){return e.viewState.roscoMode||e.stage.extendedAttributes&&H.size(e.stage.extendedAttributes)>0},this.showVarFileName=function(){return e.viewState.roscoMode||e.stage.varFileName},e.$watch("stage",(function(){H.forOwn(e.stage,(function(n,t){""===n&&delete e.stage[t]})),"function"==typeof m.feature.roscoSelector&&(e.viewState.roscoMode=m.feature.roscoSelector(e.stage))}),!0),n.all([G.getRegions("azure"),G.getBaseOsOptions("azure"),G.getBaseLabelOptions()]).then((function([n,t,a]){e.regions=n,1===e.regions.length?e.stage.region=e.regions[0]:e.regions.includes(e.stage.region)||delete e.stage.region,!e.stage.regions.length&&e.application.defaultRegions.azure&&e.stage.regions.push(e.application.defaultRegions.azure),!e.stage.regions.length&&e.application.defaultRegions.azure&&e.stage.regions.push(e.application.defaultRegions.azure),e.baseOsOptions=t.baseImages,e.baseOsOptions.length&&(e.stage.osType=t.baseImages[0].osType),e.baseLabelOptions=a,!e.stage.baseOs&&e.baseOsOptions&&e.baseOsOptions.length&&(e.stage.baseOs=e.baseOsOptions[0].id),!e.stage.baseLabel&&e.baseLabelOptions&&e.baseLabelOptions.length&&(e.stage.baseLabel=e.baseLabelOptions[0]),e.viewState.roscoMode=m.feature.roscoMode||"function"==typeof m.feature.roscoSelector&&m.feature.roscoSelector(e.stage),e.showAdvancedOptions=function(){const n=e.stage;return!!(n.templateFileName||n.extendedAttributes&&H.size(n.extendedAttributes)>0||n.varFileName)}(),e.viewState.loading=!1}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/bake/bakeStage.html",'<div ng-controller="azureBakeStageCtrl as bakeStageCtrl">\n <div ng-if="viewState.loading" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div ng-if="!viewState.loading">\n <stage-config-field label="Regions">\n <checklist items="regions" model="stage.regions" inline="true" include-select-all-button="true"></checklist>\n </stage-config-field>\n <stage-config-field label="Package" help-key="pipeline.config.bake.package">\n <input type="text" class="form-control input-sm" ng-model="stage.package" />\n </stage-config-field>\n <stage-config-field label="Base OS">\n <bake-stage-choose-os model="stage.baseOs" base-os-options="baseOsOptions"></bake-stage-choose-os>\n </stage-config-field>\n <stage-config-field label="Base Label">\n <label class="radio-inline" ng-repeat="baseLabel in baseLabelOptions">\n <input type="radio" ng-model="stage.baseLabel" ng-value="baseLabel" />\n {{baseLabel}}\n </label>\n </stage-config-field>\n \x3c!-- Even if the roscoMode flag is false, we should show the control if rebake is set. --\x3e\n <stage-config-field label="Rebake" ng-if="viewState.roscoMode || stage.rebake">\n <div class="checkbox" style="margin-bottom: 0">\n <label>\n <input type="checkbox" ng-model="stage.rebake" />\n Rebake image without regard to the status of any existing bake\n </label>\n </div>\n </stage-config-field>\n <stage-config-field label="Base Name">\n <input type="text" class="form-control input-sm" ng-model="stage.baseName" />\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-9 col-md-offset-1">\n <div class="checkbox">\n <label>\n <input type="checkbox" ng-model="showAdvancedOptions" />\n <strong>Show Advanced Options</strong>\n </label>\n </div>\n </div>\n </div>\n <div ng-class="{collapse: showAdvancedOptions !== true, \'collapse.in\': showAdvancedOptions === true}">\n <stage-config-field\n label="Template File Name"\n help-key="pipeline.config.bake.templateFileName"\n ng-if="bakeStageCtrl.showTemplateFileName()"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.templateFileName" />\n </stage-config-field>\n <stage-config-field\n label="Extended Attributes"\n help-key="pipeline.config.bake.extendedAttributes"\n ng-if="bakeStageCtrl.showExtendedAttributes()"\n >\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 40%">Key</th>\n <th style="width: 60%">Value</th>\n <th class="text-right">Actions</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="(key,value) in stage.extendedAttributes">\n <td>\n <strong class="small">{{key}}</strong>\n </td>\n <td>\n <input\n type="text"\n ng-model="stage.extendedAttributes[key]"\n value="{{value}}"\n class="form-control input-sm"\n />\n </td>\n <td class="text-right">\n <a class="small" href ng-click="bakeStageCtrl.removeExtendedAttribute(key)">Remove</a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="7">\n <button class="btn btn-block btn-sm add-new" ng-click="bakeStageCtrl.addExtendedAttribute()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add Extended Attribute\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </stage-config-field>\n <stage-config-field\n label="Var File Name"\n help-key="pipeline.config.bake.varFileName"\n ng-if="bakeStageCtrl.showVarFileName()"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.varFileName" />\n </stage-config-field>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/bake/bakeExecutionDetails.html",'<div ng-controller="azureBakeExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'bakeConfig\'">\n <div class="row">\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Azure</dd>\n <dt>Image</dt>\n <dd>{{stage.context.ami}}</dd>\n <dt>Region</dt>\n <dd>{{stage.context.region}}</dd>\n <dt>Package</dt>\n <dd>{{stage.context.package}}</dd>\n </dl>\n </div>\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt>Base OS</dt>\n <dd>{{stage.context.baseOs}}</dd>\n <dt>Label</dt>\n <dd>{{stage.context.baseLabel}}</dd>\n <dt ng-if="roscoMode || execution.trigger.rebake || stage.context.rebake">Rebake</dt>\n <dd ng-if="roscoMode || execution.trigger.rebake || stage.context.rebake">\n {{execution.trigger.rebake || stage.context.rebake || false}}\n </dd>\n <dt ng-if="stage.context.templateFileName">Template</dt>\n <dd ng-if="stage.context.templateFileName">{{stage.context.templateFileName}}</dd>\n <dt ng-if="stage.context.varFileName">Var File</dt>\n <dd ng-if="stage.context.varFileName">{{stage.context.varFileName}}</dd>\n </dl>\n </div>\n </div>\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n\n <div class="row" ng-if="stage.context.region && stage.context.status.resourceId">\n <div class="col-md-12">\n <div class="alert alert-{{stage.isFailed ? \'danger\' : \'info\'}}">\n <div ng-if="stage.context.previouslyBaked">No changes detected; reused existing bake</div>\n <a target="_blank" href="{{ bakeryDetailUrl(stage) }}"> View Bakery Details </a>\n </div>\n </div>\n </div>\n </div>\n <div class="step-section-details" ng-if="detailsSection === \'taskStatus\'">\n <div class="row">\n <execution-step-details item="stage"></execution-step-details>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.pipeline.stage.destroyAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"destroyServerGroup",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/destroyAsg/destroyAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"targetImpedance",message:"This pipeline will attempt to destroy a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureDestroyAsgStageCtrl",["$scope",function(e){const n=this,t=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),n.accountUpdated=function(){f.getAccountDetails(t.credentials).then((function(e){t.regions=[e.org]}))},e.targets=C.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="azure",t.interestingHealthProviderNames=[],!t.credentials&&e.application.defaultCredentials.azure&&(t.credentials=e.application.defaultCredentials.azure),t.credentials&&n.accountUpdated(),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/destroyAsg/destroyAsgStage.html",'<div ng-controller="azureDestroyAsgStageCtrl as destroyAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",'<span class="task-label"> Destroy Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.pipeline.stage.disableAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"disableServerGroup",alias:"disableAsg",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/disableAsg/disableAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",validators:[{type:"targetImpedance",message:"This pipeline will attempt to disable a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureDisableAsgStageCtrl",["$scope",function(e){const n=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),e.targets=C.TARGET_LIST,n.regions=n.regions||[],n.cloudProvider="azure",n.isNew&&e.application.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=[]),!n.credentials&&e.application.defaultCredentials.azure&&(n.credentials=e.application.defaultCredentials.azure),!n.regions.length&&e.application.defaultRegions.azure&&n.regions.push(e.application.defaultRegions.azure),n.target||(n.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/disableAsg/disableAsgStage.html",'<div ng-controller="azureDisableAsgStageCtrl as disableAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'azureService\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",'<span class="task-label"> Disable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.pipeline.stage.enableAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"enableServerGroup",alias:"enableAsg",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/enableAsg/enableAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureEnableAsgStageCtrl",["$scope",function(e){const n=this,t=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),n.reset=()=>{n.accountUpdated(),n.resetSelectedCluster()},e.targets=C.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="azure",t.isNew&&(t.interestingHealthProviderNames=[]),!t.credentials&&e.application.defaultCredentials.azure&&(t.credentials=e.application.defaultCredentials.azure),!t.regions.length&&e.application.defaultRegions.azure&&t.regions.push(e.application.defaultRegions.azure),t.target||(t.target=e.targets[0].val),e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/enableAsg/enableAsgStage.html",'<div ng-controller="azureEnableAsgStageCtrl as enableAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'azureService\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",'<span class="task-label"> Enable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.securityGroup.write.service",[O]).factory("azureSecurityGroupWriter",(function(){return{deleteSecurityGroup:function(e,n,t={}){t.type="deleteSecurityGroup",t.securityGroupName=e.name,t.regions=[e.region],t.credentials=e.accountId,t.appName=n.name;const a=k.executeTask({job:[t],application:n,description:`Delete ${b.get("Firewalls")}: ${e.name}`});return F.clearCache("securityGroup"),a},upsertSecurityGroup:function(e,n,t,a={}){a.securityGroupName=e.name,H.assignWith(a,e,(function(e,n){return H.isUndefined(e)?n:e}));const r=k.executeTask({job:[a],application:n,description:`${t} ${b.get("Firewall")}: spinnaker.azure.securityGroup.write.service`});return F.clearCache("securityGroup"),r}}}));n("spinnaker.azure.securityGroup.create.controller",[O,"spinnaker.azure.securityGroup.write.service"]).controller("azureCreateSecurityGroupCtrl",["$scope","$uibModalInstance","$state","$controller","application","securityGroup","azureSecurityGroupWriter",function(e,n,t,a,r,i,l){e.pages={location:"azure/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},e.regions=[],e.firewallLabel=b.get("Firewall");const s=this;function o(){if(e.$$destroyed)return;n.close();const a={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.regions[0],provider:"azure"};t.includes("**.firewallDetails")?t.go("^.firewallDetails",a):t.go(".firewallDetails",a)}function c(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.isNew=!0,e.state={submitting:!1,infiniteScroll:{numToAdd:20,currentItems:20}},f.listAccounts("azure").then((function(n){e.accounts=n,s.accountUpdated()})),s.addMoreItems=function(){e.state.infiniteScroll.currentItems+=e.state.infiniteScroll.numToAdd},e.taskMonitor=new g({application:r,title:`Creating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){r.securityGroups.refresh(),r.securityGroups.onNextRefresh(e,o)}}),e.securityGroup=i,s.accountUpdated=function(){f.getRegionsForAccount(e.securityGroup.credentials).then((function(n){e.regions=n,e.securityGroup.regions=n,s.updateName(),s.regionUpdated()}))},this.regionUpdated=function(){s.vnetUpdated()},this.vnetUpdated=function(){const n=e.securityGroup.credentials,t=e.securityGroup.region;e.securityGroup.selectedVnet=null,e.securityGroup.vnet=null,e.securityGroup.vnetResourceGroup=null,s.selectedVnets=[],v.listNetworks().then((function(e){e.azure&&e.azure.forEach((e=>{e.account===n&&e.region===t&&s.selectedVnets.push(e)}))})),s.subnetUpdated()},this.subnetUpdated=function(){e.securityGroup.selectedSubnet=null,e.securityGroup.subnet=null,s.selectedSubnets=[]},this.selectedVnetChanged=function(n){e.securityGroup.vnet=n.name,e.securityGroup.vnetResourceGroup=n.resourceGroup,e.securityGroup.selectedSubnet=null,e.securityGroup.subnet=null,s.selectedSubnets=[],n.subnets&&n.subnets.map((function(e){s.selectedSubnets.push(e)}))},s.cancel=function(){n.dismiss()},s.updateName=function(){const n=e.securityGroup;let t=r.name;n.detail&&(t+="-"+n.detail),n.name=t,e.namePreview=t},s.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:r.name,region:e.securityGroup.region,vpcId:"null"};return e.securityGroup.selectedVnet&&(e.securityGroup.vnet=e.securityGroup.selectedVnet.name,e.securityGroup.vnetResourceGroup=e.securityGroup.selectedVnet.resourceGroup),e.securityGroup.selectedSubnet&&(e.securityGroup.subnet=e.securityGroup.selectedSubnet.name),e.securityGroup.type="upsertSecurityGroup",l.upsertSecurityGroup(e.securityGroup,r,"Create",n)}))},s.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0==n.length?100:100*(n.length+1),protocolUI:"tcp",protocol:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourceAddressPrefixes:[],sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"*",destinationPortRanges:[],destPortRanges:"*",sourceIPCIDRRanges:"*"})},s.portUpdated=function(e,n){if(!H.isEmpty(e[n].destPortRanges)){const t=e[n].destPortRanges.split(",");t.length>1?(e[n].destinationPortRanges=[],t.forEach((t=>e[n].destinationPortRanges.push(t))),e[n].destinationPortRange=null):(e[n].destinationPortRange=e[n].destPortRanges,e[n].destinationPortRanges=[])}},s.sourceIPCIDRUpdated=function(e,n){if(!H.isEmpty(e[n].destPortRanges)){const t=e[n].sourceIPCIDRRanges.split(",");t.length>1?(e[n].sourceAddressPrefixes=[],t.forEach((t=>e[n].sourceAddressPrefixes.push(t))),e[n].sourceAddressPrefix=null):(e[n].sourceAddressPrefix=e[n].sourceIPCIDRRanges,e[n].sourceAddressPrefixes=[])}},s.protocolUpdated=function(e,n){e[n].protocol=e[n].protocolUI},s.removeRule=function(e,n){e.splice(n,1)},s.moveUp=function(e,n){0!==n&&c(e,n,n-1)},s.moveDown=function(e,n){n!==e.length-1&&c(e,n,n+1)},e.securityGroup.securityRules=[]}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="modal-body">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.securityGroupName.$error.validateUnique, \'alert-info\': !form.securityGroupName.$error.validateUnique}"\n >\n <strong>Your <firewall-label label="firewall"></firewall-label> will be named:</strong>\n <span ng-bind="namePreview"></span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Detail</div>\n <div class="col-md-4">\n <input\n type="text"\n class="form-control input-sm"\n required\n ng-model="securityGroup.detail"\n ng-change="ctrl.updateName()"\n />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Description</div>\n <div class="col-md-8">\n <input type="text" class="form-control input-sm" ng-model="securityGroup.description" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Account</div>\n <div class="col-md-8">\n <account-select-field\n required\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-12">\n <region-select-field\n label-columns="4"\n component="securityGroup"\n field="region"\n field-columns="8"\n account="securityGroup.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.securityGroup.azure.edit.controller",[O,I,A,"spinnaker.azure.securityGroup.write.service"]).controller("azureEditSecurityGroupCtrl",["$scope","$uibModalInstance","$exceptionHandler","$state","securityGroupReader","cacheInitializer","application","securityGroup","azureSecurityGroupWriter",function(e,n,t,a,r,i,l,s,o){function c(){if(e.$$destroyed)return;n.close();const t={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.region,provider:"azure"};a.includes("**.firewallDetails")?a.go("^.firewallDetails",t):a.go(".firewallDetails",t)}function d(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.pages={ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},s.securityRules=H.map(s.securityRules,(function(e){return H.isEmpty(e.protocol)||(e.protocolUI=e.protocol.toLowerCase()),e.destPortRanges=e.destinationPortRangeModel,e.sourceIPCIDRRanges=e.sourceAddressPrefixModel,e})),e.securityGroup=s,e.state={refreshingSecurityGroups:!1},e.taskMonitor=new g({application:l,title:`Updating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){l.securityGroups.refresh(),l.securityGroups.onNextRefresh(e,c)}}),this.getSecurityGroupRefreshTime=function(){return F.get("securityGroups").getStats().ageMax},this.refreshSecurityGroups=function(){return e.state.refreshingSecurityGroups=!0,i.refreshCache("securityGroups").then((function(){r.getAllSecurityGroups().then((function(n){const t=s.accountName,a=s.region,r=H.filter(n[t].azure[a],{});e.availableSecurityGroups=H.map(r,"name")})).then((function(){e.state.refreshingSecurityGroups=!1}))}))},this.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0===n.length?100:100*(n.length+1),protocolUI:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourceAddressPrefixes:[],sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"*",destinationPortRanges:[],destPortRanges:"*",sourceIPCIDRRanges:"*"})},this.portUpdated=function(e,n){if(!H.isEmpty(e[n].sourceIPCIDRRanges)){const t=e[n].destPortRanges.split(",");t.length>1?(e[n].destinationPortRanges=[],t.forEach((t=>e[n].destinationPortRanges.push(t))),e[n].destinationPortRange=null):(e[n].destinationPortRange=e[n].destPortRanges,e[n].destinationPortRanges=[])}},this.sourceIPCIDRUpdated=function(e,n){if(!H.isEmpty(e[n].sourceIPCIDRRanges)){const t=e[n].sourceIPCIDRRanges.split(",");t.length>1?(e[n].sourceAddressPrefixes=[],t.forEach((t=>e[n].sourceAddressPrefixes.push(t))),e[n].sourceAddressPrefix=null):(e[n].sourceAddressPrefix=e[n].sourceIPCIDRRanges,e[n].sourceAddressPrefixes=[])}},this.removeRule=function(e,n){e.splice(n,1)},this.moveUp=function(e,n){0!==n&&d(e,n,n-1)},this.moveDown=function(e,n){n!==e.length-1&&d(e,n,n+1)},e.taskMonitor.onTaskComplete=n.dismiss,this.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:l.name,region:e.securityGroup.region,subnet:null,vpcId:"null"};return e.securityGroup.type="upsertSecurityGroup",o.upsertSecurityGroup(e.securityGroup,l,"Update",n)}))},this.cancel=function(){n.dismiss()}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.securityGroup.clone.controller",["spinnaker.azure.securityGroup.write.service","spinnaker.azure.securityGroup.create.controller"]).controller("azureCloneSecurityGroupController",["$scope","$uibModalInstance","$controller","$state","azureSecurityGroupWriter","securityGroup","application",function(e,n,t,a,r,i,l){const s=this;function o(){if(e.$$destroyed)return;n.close();const t={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.region,provider:"azure"};a.includes("**.firewallDetails")?a.go("^.firewallDetails",t):a.go(".firewallDetails",t)}function c(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.firewallLabel=b.get("Firewall"),e.pages={location:"azure/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},i.securityRules=H.map(i.securityRules,(function(e){const n=e.destinationPortRange.split("-");return e.startPort=Number(n[0]),e.endPort=Number(n[1]),e})),s.accountUpdated=function(){f.getRegionsForAccount(e.securityGroup.credentials).then((function(n){e.regions=n,e.securityGroup.regions=n,s.updateName()}))},s.cancel=function(){n.dismiss()},s.updateName=function(){const n=e.securityGroup;let t=l.name;n.detail&&(t+="-"+n.detail),n.name=t,e.namePreview=t},e.securityGroup=i,e.state={refreshingSecurityGroups:!1},e.taskMonitor=new g({application:l,title:`Updating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){l.securityGroups.refresh(),l.securityGroups.onNextRefresh(e,o)}}),f.listAccounts("azure").then((function(n){e.accounts=n,s.accountUpdated()})),s.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0===n.length?100:100*(n.length+1),protocol:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"7001-7001",startPort:7001,endPort:7001})},s.portUpdated=function(e,n){e[n].destinationPortRange=e[n].startPort+"-"+e[n].endPort},s.removeRule=function(e,n){e.splice(n,1)},s.moveUp=function(e,n){0!==n&&c(e,n,n-1)},s.moveDown=function(e,n){n!==e.length-1&&c(e,n,n+1)},s.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:l.name,region:e.securityGroup.region,subnet:"none",vpcId:"null"};return e.securityGroup.type="upsertSecurityGroup",r.upsertSecurityGroup(e.securityGroup,l,"Clone",n)}))}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="modal-body">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.securityGroupName.$error.validateUnique, \'alert-info\': !form.securityGroupName.$error.validateUnique}"\n >\n <strong>Your <firewall-label label="firewall"></firewall-label> will be named:</strong>\n <span ng-bind="namePreview"></span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Detail</div>\n <div class="col-md-4">\n <input\n type="text"\n class="form-control input-sm"\n required\n ng-model="securityGroup.detail"\n ng-change="ctrl.updateName()"\n />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Description</div>\n <div class="col-md-8">\n <input type="text" class="form-control input-sm" ng-model="securityGroup.description" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Account</div>\n <div class="col-md-8">\n <account-select-field\n required\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-12">\n <region-select-field\n label-columns="4"\n component="securityGroup"\n field="region"\n field-columns="8"\n account="securityGroup.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.securityGroup.azure.details.controller",[O,A,"spinnaker.azure.securityGroup.write.service","spinnaker.azure.securityGroup.clone.controller"]).controller("azureSecurityGroupDetailsCtrl",["$scope","$state","resolvedSecurityGroup","app","azureSecurityGroupWriter","securityGroupReader","$uibModal",function(n,t,a,r,l,s,o){const c=r,d=a;function u(){return s.getSecurityGroupDetails(c,d.accountId,d.provider,d.region,d.vpcId,d.name).then((function(e){n.state.loading=!1,!e||H.isEmpty(e)?p():n.securityGroup=e}),(function(){p()}))}function p(){t.go("^")}n.state={loading:!0},n.firewallLabel=b.get("Firewall"),u().then((()=>{n.$$destroyed||r.securityGroups.onRefresh(n,u)})),this.editInboundRules=function(){o.open({templateUrl:"azure/src/securityGroup/configure/editSecurityGroup.html",controller:"azureEditSecurityGroupCtrl as ctrl",resolve:{securityGroup:function(){return e.copy(n.securityGroup)},application:function(){return c}}})},this.cloneSecurityGroup=function(){o.open({templateUrl:"azure/src/securityGroup/clone/cloneSecurityGroup.html",controller:"azureCloneSecurityGroupController as ctrl",resolve:{securityGroup:function(){const t=e.copy(n.securityGroup);return t.region&&(t.regions=[t.region]),t},application:function(){return c}}})},this.deleteSecurityGroup=function(){const e={application:c,title:"Deleting "+d.name};i.confirm({header:"Really delete "+d.name+"?",buttonText:"Delete "+d.name,account:d.accountId,taskMonitorConfig:e,submitMethod:function(){return n.securityGroup.type="deleteSecurityGroup",l.deleteSecurityGroup(d,c,{cloudProvider:"azure",vpcId:n.securityGroup.vpcId})}})},r.isStandalone&&(r.securityGroups={refresh:u})}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/editSecurityGroup.html",'<form name="form" novalidate validate-on-submit>\n <v2-modal-wizard\n heading="Edit {{securityGroup.name}}: {{securityGroup.region}}: {{securityGroup.credentials}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.upsert()"\n ></submit-button>\n </div>\n</form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/clone/cloneSecurityGroup.html",'<v2-modal-wizard heading="Clone {{firewallLabel}}">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n</v2-modal-wizard>\n')}]);n("spinnaker.azure.securityGroup.reader",[]).factory("azureSecurityGroupReader",(function(){return{resolveIndexedSecurityGroup:function(e,n,t){const a=t.split("/");return e[n.account][n.region][a[a.length-1]]}}}));n("spinnaker.azure.securityGroup.transformer",[]).factory("azureSecurityGroupTransformer",(function(){return{normalizeSecurityGroup:function(){}}}));n("spinnaker.azure.serverGroup.transformer",[]).factory("azureServerGroupTransformer",(function(){function e(e,n){if(Array.isArray(e.customScriptsSettings.fileUris))n.customScriptsSettings.fileUris=e.customScriptsSettings.fileUris;else{const t=e.customScriptsSettings.fileUris;t.includes(",")?n.customScriptsSettings.fileUris=t.split(","):t.includes(";")?n.customScriptsSettings.fileUris=t.split(";"):n.customScriptsSettings.fileUris=[t],n.customScriptsSettings.fileUris.forEach((function(e,t){n.customScriptsSettings.fileUris[t]=e.trim()}))}}return{convertServerGroupCommandToDeployConfiguration:function(n){let t;t="editPipeline"===n.viewState.mode||"createPipeline"===n.viewState.mode?{imageName:"",isCustom:"true",publisher:"",offer:"",sku:"",version:"",region:n.region,uri:"",ostype:""}:n.selectedImage;const a={name:n.application,cloudProvider:n.selectedProvider,application:n.application,stack:n.stack,strategy:n.strategy,rollback:{onFailure:n.rollback?n.rollback.onFailure:null},scaleDown:n.scaleDown,maxRemainingAsgs:n.maxRemainingAsgs,delayBeforeDisableSec:n.delayBeforeDisableSec,delayBeforeScaleDownSec:n.delayBeforeScaleDownSec,allowDeleteActive:"redblack"===n.strategy||null,allowScaleDownActive:"redblack"===n.strategy||null,detail:n.freeFormDetails,freeFormDetails:n.freeFormDetails,healthSettings:n.healthSettings,image:n.image,account:n.credentials,selectedProvider:"azure",vnet:n.vnet,vnetResourceGroup:n.selectedVnet.resourceGroup,subnet:n.subnet,useSourceCapacity:!1,capacity:{min:n.sku.capacity,max:n.sku.capacity},credentials:n.credentials,region:n.region,securityGroupName:n.securityGroupName,loadBalancerName:n.loadBalancerName,loadBalancerType:n.loadBalancerType,user:"[anonymous]",upgradePolicy:"Manual",type:"createServerGroup",sku:{name:"Standard_DS1_v2",tier:"Standard",capacity:n.sku.capacity},instanceTags:n.instanceTags,dataDisks:n.dataDisks,userAssignedIdentities:n.userAssignedIdentities,viewState:n.viewState,osConfig:{customData:n.osConfig?n.osConfig.customData:null},customScriptsSettings:{fileUris:null,commandToExecute:""},zonesEnabled:n.zonesEnabled,zones:n.zonesEnabled?n.zones:[],enableInboundNAT:n.enableInboundNAT};if(null!=n.image&&0!=n.image.isCustom||(a.image=t),void 0!==n.stack&&(a.name=a.name+"-"+n.stack),void 0!==n.freeFormDetails&&(a.name=a.name+"-"+n.freeFormDetails),void 0!==n.customScriptsSettings&&(a.customScriptsSettings.commandToExecute=n.customScriptsSettings.commandToExecute,H.isEmpty(n.customScriptsSettings.fileUris)||e(n,a)),n.instanceType){const e=n.instanceType;a.instanceType=n.instanceType,a.sku.name=e,a.sku.tier=e.substring(0,e.indexOf("_"))}return a.interestingHealthProviderNames=[],a},normalizeServerGroup:function(e){return e},parseCustomScriptsSettings:e}}));n("spinnaker.azure.serverGroup.configure.instanceArchetype.controller",[]).controller("azureInstanceArchetypeCtrl",["$scope","instanceTypeService","modalWizardService",function(e,n,t){const a=t.getWizard();e.$watch("command.viewState.instanceProfile",(function(){e.command.viewState.instanceProfile&&"custom"!==e.command.viewState.instanceProfile?(a.includePage("instance-type"),a.markClean("instance-profile"),a.markComplete("instance-profile")):a.excludePage("instance-type")})),e.$watch("command.viewState.instanceType",(function(e){e&&(a.markClean("instance-profile"),a.markComplete("instance-profile"))}))}]);n("spinnaker.azure.serverGroup.configure.instanceType.controller",[]).controller("azureInstanceTypeCtrl",["$scope","modalWizardService",function(e,n){n.getWizard().markComplete("instance-type"),n.getWizard().markClean("instance-type")}]);n("spinnaker.azure.serverGroup.configure.advancedSetting.controller",[]).controller("azureServerGroupAdvancedSettingsCtrl",["$scope","modalWizardService",function(e,n){n.getWizard().markComplete("advanced"),e.$watch("form.$valid",(function(e){e?n.getWizard().markClean("advanced"):n.getWizard().markDirty("advanced")}))}]);e.module("spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive",[]).directive("azureServerGroupAdvancedSettingsSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"adv",controller:"azureServerGroupAdvancedSettingsSelectorCtrl"}})).controller("azureServerGroupAdvancedSettingsSelectorCtrl",(function(){this.addDataDisk=()=>{const n=e.copy(this.command.dataDisks);this.command.dataDisks=n.concat([{lun:0,managedDisk:{storageAccountType:"Standard_LRS"},diskSizeGB:1,caching:"None",createOption:"Empty"}])},this.removeDataDisk=n=>{const t=e.copy(this.command.dataDisks);t.splice(n,1),this.command.dataDisks=t}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Number of Instances</div>\n <div class="col-md-2">\n <input\n type="number"\n class="form-control input-sm"\n ng-model="adv.command.sku.capacity"\n min="0"\n max="100"\n required\n />\n </div>\n </div>\n <div></div>\n <div class="form-group">\n <div class="col-xs-4 sm-label-right">\n <b>Custom Data</b>\n <help-field key="azure.serverGroup.customData"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.osConfig.customData" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Custom Script</b>\n <help-field key="azure.serverGroup.scriptLocation"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.customScriptsSettings.fileUris" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Command To Execute</b>\n <help-field key="azure.serverGroup.commandToExecute"></help-field>\n </div>\n <div class="col-md-7">\n <input\n type="text"\n class="form-control input-sm"\n ng-model="adv.command.customScriptsSettings.commandToExecute"\n />\n </div>\n </div>\n <div class="form-group" ng-if="adv.command.loadBalancerType === \'Azure Application Gateway\'">\n <div class="col-md-4 sm-label-right">\n <input type="checkbox" ng-model="adv.command.enableInboundNAT" ng-disabled="adv.command.zonesEnabled" />\n </div>\n <div class="col-md-7">\n <b>Enable inbound NAT port-forwarding rules to connect to VM instances</b>\n <help-field key="azure.serverGroup.enableInboundNAT"></help-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>User-Assigned Identities</b>\n <help-field key="azure.serverGroup.userAssignedIdentities"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.userAssignedIdentities" />\n </div>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-left">Data Disks</div>\n <div class="col-md-11">\n <table class="table table-condensed packed tags">\n <thead>\n <tr>\n <th>\n LUN\n <help-field key="azure.serverGroup.lun"></help-field>\n </th>\n <th>\n Size (GB)\n <help-field key="azure.serverGroup.diskSizeGB"></help-field>\n </th>\n <th>\n Type\n <help-field key="azure.serverGroup.managedDisk.storageAccountType"></help-field>\n </th>\n <th>\n Caching\n <help-field key="azure.serverGroup.caching"></help-field>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="disk in adv.command.dataDisks">\n <td>\n <input type="number" class="form-control input-sm" ng-model="disk.lun" required min="0" />\n </td>\n <td>\n <input type="number" class="form-control input-sm" ng-model="disk.diskSizeGB" required min="1" />\n </td>\n <td>\n <ui-select ng-model="disk.managedDisk.storageAccountType" class="form-control input-sm" required>\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="dataDiskType in adv.command.backingData.dataDiskTypes | filter: $select.search"\n >\n <span ng-bind-html="dataDiskType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </td>\n <td>\n <ui-select ng-model="disk.caching" class="form-control input-sm" required>\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="dataDiskCachingType in adv.command.backingData.dataDiskCachingTypes | filter: $select.search"\n >\n <span ng-bind-html="dataDiskCachingType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </td>\n <td>\n <a class="btn btn-link sm-label" style="margin-top: 0" ng-click="adv.removeDataDisk($index)">\n <span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="4">\n <button class="btn btn-block btn-sm add-new" ng-click="adv.addDataDisk()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add New Data Disk\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.basicSettings.image.filter",[]).filter("regional",(function(){return function(e,n){return H.filter(e,(function(e){return e.region===n||null===e.region}))}}));e.module("spinnaker.azure.serverGroup.configure.basicSettings",[O,Q,"spinnaker.azure.serverGroup.configure.basicSettings.image.filter",E]).controller("azureServerGroupBasicSettingsCtrl",["$scope","$controller","$uibModalStack","$state","imageReader",function(n,t,a,r,i){n.$watch("form.$valid",(function(e){e?(T.markClean("basic-settings"),T.markComplete("basic-settings")):T.markIncomplete("basic-settings")})),this.imageChanged=e=>{n.command.imageName=e.imageName,n.command.selectedImage=e,T.markClean("basic-settings")},e.extend(this,t("BasicSettingsMixin",{$scope:n,imageReader:i,$uibModalStack:a,$state:r})),this.stackPattern={test:function(e){return(n.command.viewState.templatingEnabled?/^([a-zA-Z0-9]*(\${.+})*)*$/:/^[a-zA-Z0-9]*$/).test(e)}},this.detailPattern={test:function(e){return(n.command.viewState.templatingEnabled?/^([a-zA-Z0-9-]*(\${.+})*)*$/:/^[a-zA-Z0-9-]*$/).test(e)}}}]);n("spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive",[]).directive("azureServerGroupCapacitySelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"cap",controller:"azureServerGroupCapacitySelectorCtrl"}})).controller("azureServerGroupCapacitySelectorCtrl",(function(){})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.html",'<div>\n <div class="form-group">\n <div class="col-md-12">\n <p>Sets desired instance count.</p>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Number of Instances</div>\n <div class="col-md-2">\n <input\n type="number"\n class="form-control input-sm"\n ng-model="cap.command.sku.capacity"\n min="0"\n max="100"\n required\n />\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.healthSetting.controller",[]).controller("azureServerGroupHealthSettingsCtrl",["$scope",function(e){void 0===e.command.healthSettings&&(e.command.healthSettings={}),this.healthCheckProtocols=[{displayName:"N/A",name:null},{displayName:"HTTP",name:"http"},{displayName:"TCP",name:"tcp"}],this.requiresHealthCheckPath=function(){return"http"===e.command.healthSettings.protocol},this.changeHealthCheckProtocol=function(n){null==n?(e.command.healthSettings.protocol=null,e.command.healthSettings.port=null,e.command.healthSettings.requestPath=null):this.requiresHealthCheckPath()||(e.command.healthSettings.requestPath=null)}}]);n("spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive",[]).directive("azureServerGroupHealthSettingsSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.html",scope:{command:"="}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupHealthSettingsCtrl as healthCtrl">\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Protocol</div>\n <div class="col-md-7">\n <select\n class="form-control input-sm"\n ng-model="command.healthSettings.protocol"\n ng-options="protocol.name as protocol.displayName for protocol in healthCtrl.healthCheckProtocols"\n ng-change="healthCtrl.changeHealthCheckProtocol(command.healthSettings.protocol)"\n ></select>\n </div>\n </div>\n <div class="form-group" ng-if="command.healthSettings.protocol">\n <div class="col-md-3 sm-label-right">Port</div>\n <div class="col-md-7">\n <input class="form-control input-sm" type="text" ng-model="command.healthSettings.port" required />\n </div>\n </div>\n <div class="form-group" ng-if="healthCtrl.requiresHealthCheckPath()">\n <div class="col-md-3 sm-label-right">Path</div>\n <div class="col-md-7">\n <input class="form-control input-sm" type="text" ng-model="command.healthSettings.requestPath" required />\n </div>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-9 col-md-offset-3">\n <p>Health settings here will be applied directly to the VM Scale Set.</p>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.imageSettings.controller",[]).controller("azureServerGroupImageSettingsCtrl",["$scope",function(e){this.clearImage=function(){0==e.command.image.isCustom?e.command.image={isCustom:!1}:e.command.image.region=e.command.region},T.markComplete("image-settings"),e.$watch("form.$valid",(function(e){e?T.markClean("image-settings"):T.markDirty("image-settings")}))}]);n("spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive",[]).directive("azureServerGroupImageSettingsSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.html",scope:{command:"="}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupImageSettingsCtrl as imageCtrl">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Use custom image?</div>\n <input type="checkbox" ng-model="command.image.isCustom" ng-change="imageCtrl.clearImage()" />\n </div>\n\n <div class="form-group" ng-if="command.image.isCustom === true">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Region</div>\n <div class="col-md-6">\n <span>{{command.image.region}}</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Image Name</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.imageName" required />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">OS Type</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.ostype" required />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">URI</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.uri" required />\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.loadBalancer.controller",[y]).controller("azureServerGroupLoadBalancersCtrl",["$scope","loadBalancerReader",function(e,n){function t(t,a){n.getLoadBalancerDetails("azure",e.command.credentials,e.command.region,t).then((function(n){if(n&&0!==n.length){if(n&&1===n.length){const t=n[0],r=e.command.selectedVnet;e.command.selectedVnet=null,e.command.selectedVnetSubnets=[],e.command.allVnets=[],v.listNetworks().then((function(n){n.azure&&n.azure.forEach((n=>{n.account===e.command.credentials&&n.region===e.command.region&&e.command.allVnets.push(n),n.account===e.command.credentials&&n.region===e.command.region&&("Azure Application Gateway"===a&&n.name==t.vnet||"Azure Load Balancer"===a&&n.name===r.name)&&(e.command.selectedVnet=n,n.subnets.map((function(n){let t=!0;n.devices&&n.devices.map((function(e){e&&"applicationGateways"===e.type&&(t=!1)})),t&&e.command.selectedVnetSubnets.push(n.name)})))}))}))}}else{e.command.selectedVnet;const n=e.command.selectedSubnet;e.command.selectedVnetSubnets=[],e.command.allVnets=[],v.listNetworks().then((function(t){t.azure&&t.azure.forEach((t=>{t.account===e.command.credentials&&t.region===e.command.region&&(e.command.allVnets.push(t),t.subnets.map((function(t){let a=!0;t.devices&&t.devices.map((function(e){e&&"applicationGateways"===e.type&&(a=!1)})),a&&(e.command.selectedVnetSubnets.push(t.name),t.name===n&&(e.command.selectedSubnet=n))})))}))}))}}))}T.markClean("load-balancers"),e.command.credentials&&e.command.region&&(e.command.viewState.networkSettingsConfigured=!0,e.command.selectedVnetSubnets=[],null!==e.command.loadBalancerName&&void 0!==e.command.loadBalancerName&&(e.useLoadBalancer=!0),t(e.command.loadBalancerName,e.command.loadBalancerType)),this.loadBalancerChanged=function(n){e.command.viewState.networkSettingsConfigured=!0,T.markComplete("load-balancers");const a=e.command.backingData.loadBalancers;let r=null;if(a){const e=a.find((e=>e.name===n));e&&(r=K.getLoadBalancerType(e.loadBalancerType).type)}null===n&&(e.command.loadBalancerName=null),e.command.selectedVnetSubnets=[],e.command.loadBalancerType=r,F.clearCache("networks"),t(n,r)}}]);n("spinnaker.azure.serverGroup.configure.loadBalancer.directive",[]).directive("azureServerGroupLoadBalancersSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.html"}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.loadBalancersConfigured">Please select an account and region.</h5>\n<div\n ng-if="command.viewState.loadBalancersConfigured"\n ng-controller="azureServerGroupLoadBalancersCtrl as loadBalancerCtrl"\n>\n <div class="form-group">\n <div class="col-md-3 sm-label-right"><b>Load Balancers</b></div>\n <div class="col-md-7">\n <label for="useLoadBalancerCheckbox">\n <input\n type="checkbox"\n ng-model="useLoadBalancer"\n id="useLoadBalancerCheckbox"\n ng-change="loadBalancerCtrl.loadBalancerChanged(null)"\n />\n Use load balancer\n </label>\n <ui-select\n ng-model="command.loadBalancerName"\n class="form-control input-sm"\n ng-change="loadBalancerCtrl.loadBalancerChanged($select.selected)"\n ng-show="useLoadBalancer"\n >\n <ui-select-match placeholder="select a loadBalancer">{{$select.selected}}</ui-select-match>\n <ui-select-choices repeat="loadBalancer in command.loadBalancers | filter: $select.search">\n <span ng-bind-html="loadBalancer | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-show="command.loadBalancerName">\n <div class="col-md-12">\n <div class="well-compact" ng-class="well">\n <h5 class="text-center">\n <p>The load balancer {{command.loadBalancerName}} is an {{command.loadBalancerType}}</p>\n </h5>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.networkSettings.controller",[]).controller("azureServerGroupNetworkSettingsCtrl",["$scope",function(e){T.markClean("network-settings"),e.command.selectedVnet={name:e.command.vnet},e.command.selectedSubnet=e.command.subnet,this.vnetChanged=function(n){e.command.vnet=n,e.command.subnet=e.command.selectedSubnet=null,e.command.selectedVnetSubnets=n.subnets.map((e=>e.name))},this.networkSettingsChanged=function(n){e.command.vnet=e.command.selectedVnet.name,e.command.subnet=n,T.markComplete("network-settings")},this.getVnetName=function(){return e.command.selectedVnet?e.command.selectedVnet.name:"Virtual network was not selected"}}]);n("spinnaker.azure.serverGroup.configure.networkSettings.directive",[]).directive("azureServerGroupNetworkSettingsSelector",(function(){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.html"}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.networkSettingsConfigured">\n Please select an account, a region and a load balancer first.\n</h5>\n<div\n ng-if="command.viewState.networkSettingsConfigured"\n ng-controller="azureServerGroupNetworkSettingsCtrl as networkSettingCtrl"\n>\n <div class="form-group" ng-if="command.loadBalancerType === \'Azure Load Balancer\' || !command.loadBalancerType">\n <div class="col-md-3 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n required\n class="form-control input-sm"\n ng-model="command.selectedVnet"\n on-select="networkSettingCtrl.vnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in command.allVnets">\n <span ng-bind-html="selectVnet.name"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-3 sm-label-right"><b>Subnets</b></div>\n <div class="col-md-7">\n <ui-select\n required\n ng-model="command.selectedSubnet"\n class="form-control input-sm"\n on-select="networkSettingCtrl.networkSettingsChanged($item)"\n >\n <ui-select-match placeholder="Select from an existing subnet">{{$select.selected}}</ui-select-match>\n <ui-select-choices repeat="subnet in command.selectedVnetSubnets | filter: $select.search">\n <span ng-bind-html="subnet | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-if="!command.viewState.hideClusterNamePreview">\n <div class="col-md-12">\n <div class="well-compact" ng-class="well">\n <h5 class="text-center">\n <p>Your server group will be using a subnet in virtual network:</p>\n <p>\n <strong> {{networkSettingCtrl.getVnetName()}} </strong>\n </p>\n </h5>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.securityGroups.controller",[]).controller("azureServerGroupSecurityGroupsCtrl",["$scope",function(e){T.markClean("security-groups"),T.markComplete("security-groups"),e.command.selectedSecurityGroup={id:e.command.securityGroupName},this.securityGroupChanged=function(n){e.command.securityGroupName=n.id,T.markComplete("security-groups")}}]);n("spinnaker.azure.serverGroup.configure.securityGroupSelector.directive",[]).directive("azureServerGroupSecurityGroupsSelector",["azureServerGroupConfigurationService",function(e){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.html",link:function(n){n.firewallLabel=b.get("firewall"),n.getSecurityGroupRefreshTime=function(){return F.get("securityGroups").getStats().ageMax},n.refreshSecurityGroups=function(){n.refreshing=!0,e.refreshSecurityGroups(n.command).then((function(){n.refreshing=!1}))}}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.securityGroupsConfigured">Please select an account and region.</h5>\n<div\n ng-if="command.viewState.securityGroupsConfigured"\n ng-controller="azureServerGroupSecurityGroupsCtrl as securityGroupCtrl"\n>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n <b><firewall-label label="Firewalls"></firewall-label></b>\n </div>\n <div class="col-md-7">\n <ui-select\n ng-model="command.selectedSecurityGroup"\n class="form-control input-sm"\n on-select="securityGroupCtrl.securityGroupChanged($item)"\n >\n <ui-select-match placeholder="select a {{firewallLabel}}">{{$select.selected.id}}</ui-select-match>\n <ui-select-choices\n repeat="securityGroup in command.backingData.filtered.securityGroups | anyFieldFilter: {name: $select.search, id: $select.search}"\n >\n <span ng-bind-html="securityGroup.id | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-9 col-md-offset-3">\n <p>\n <span ng-if="refreshing"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!refreshing">last refreshed {{ getSecurityGroupRefreshTime() | timestamp }}</span>\n <span ng-if="refreshing"> refreshing...</span>\n </p>\n <p>\n If you\'re not finding a <firewall-label label="firewall"></firewall-label> that was recently added,\n <a href ng-click="refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.wizard.tags.directive",[]).directive("azureTagsSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/tags/tagsSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"tagsSelectorCtrl",controller:"TagsSelectorCtrl"}})).controller("TagsSelectorCtrl",["$scope",function(){this.getTagResult=function(){return K.checkTags(this.command.instanceTags)}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/tags/tagsSelector.directive.html",'<div class="form-group">\n <div class="col-md-12" style="color: red" ng-if="!tagsSelectorCtrl.getTagResult().isValid">\n {{ tagsSelectorCtrl.getTagResult().errorMessage }}\n </div>\n <div class="col-md-4 sm-label-left">\n <b>Custom Tags</b>\n <help-field key="azure.serverGroup.customTags"></help-field>\n </div>\n <div class="col-md-12">\n <map-editor\n model="tagsSelectorCtrl.command.instanceTags"\n add-button-label="Add New Tags"\n allow-empty="true"\n ></map-editor>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive",[]).directive("azureZoneSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"vm",controller:["$scope",function(e){this.updateEnableInboundNAT=()=>{e.vm.command.zonesEnabled&&(e.vm.command.enableInboundNAT=!1)}}]}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html",'<div class="form-group" ng-if="vm.command.region">\n <div class="col-md-10">\n <label ng-if="vm.command.backingData.filtered.zones && vm.command.backingData.filtered.zones.length !== 0">\n <input type="checkbox" ng-model="vm.command.zonesEnabled" ng-change="vm.updateEnableInboundNAT()" />\n Set availability zones\n </label>\n <ui-select multiple ng-if="vm.command.zonesEnabled" ng-model="vm.command.zones" class="form-control input-sm">\n <ui-select-match>{{ $item }}</ui-select-match>\n <ui-select-choices repeat="zone as zone in vm.command.backingData.filtered.zones">\n <span>{{ zone }}</span>\n </ui-select-choices>\n </ui-select>\n </div>\n</div>\n<h5 class="text-center" ng-if="!vm.command.region">Please select a region.</h5>\n<h5\n class="text-center"\n ng-if="vm.command.region && !(vm.command.backingData.filtered.zones && vm.command.backingData.filtered.zones.length !== 0)"\n>\n Current region does not support availability zones\n</h5>\n')}]);n("spinnaker.azure.serverGroup.configure",["spinnaker.azure.serverGroup.configure.basicSettings","spinnaker.azure.serverGroup.configure.loadBalancer.controller","spinnaker.azure.serverGroup.configure.instanceArchetype.controller","spinnaker.azure.serverGroup.configure.instanceType.controller","spinnaker.azure.serverGroup.configure.securityGroups.controller","spinnaker.azure.serverGroup.configure.advancedSetting.controller","spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive","spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive","spinnaker.azure.serverGroup.configure.imageSettings.controller","spinnaker.azure.serverGroup.configure.healthSetting.controller","spinnaker.azure.serverGroup.configure.loadBalancer.directive","spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive","spinnaker.azure.serverGroup.configure.securityGroupSelector.directive","spinnaker.azure.serverGroup.transformer","spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive","spinnaker.azure.serverGroup.configure.networkSettings.controller","spinnaker.azure.serverGroup.configure.networkSettings.directive","spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive","spinnaker.azure.serverGroup.configure.wizard.tags.directive"]);e.module("spinnaker.azure.serverGroup.configure.service",["spinnaker.azure.image.reader",y,A,I,"spinnaker.azure.instanceType.service"]).factory("azureServerGroupConfigurationService",["$q","azureImageReader","securityGroupReader","cacheInitializer","loadBalancerReader","azureInstanceTypeService",function(n,t,a,r,i,l){const s=["Standard_LRS","StandardSSD_LRS","Premium_LRS"],o=["None","ReadOnly","ReadWrite"],c=["EC2","ELB"],d=["OldestInstance","NewestInstance","OldestLaunchConfiguration","ClosestToNextInstanceHour","Default"];function u(n){const t={dirty:{}};if(n.region){const a=[t.dirty];a.push(function(e){const n=e,t={dirty:{}},a=[n.region],{credentialsKeyedByAccount:r}=n.backingData,{locationToInstanceTypesMap:i}=r[n.credentials];if(a.every((e=>!e)))return t;const s=l.getAvailableTypesForRegions(i,a).map((e=>e.name)),o=n.instanceType;H.every([o,!H.startsWith(o,"custom"),!H.includes(s,o)])&&(t.dirty.instanceType=n.instanceType,n.instanceType=null);return n.backingData.filtered.instanceTypes=s,t}(n).dirty),e.extend(...a)}else n.backingData.filtered.instanceTypes=[];return t}function p(e){const n={dirty:{}},t=e.backingData.filtered;if(!e.region)return n;let{regionsSupportZones:a,availabilityZones:r}=e.backingData.credentialsKeyedByAccount[e.credentials];return a=a||[],r=r||[],t.zones=a.includes(e.region)?r:[],n}function m(e){const n=e.backingData.securityGroups[e.credentials]||{azure:{}};return H.chain(n[e.region]).sortBy("name").value()}function g(e){const n={dirty:{}};let t;e.backingData.filtered.securityGroups&&(t=e.backingData.filtered.securityGroups);const a=m(e);return e.selectedSecurityGroup&&(e.selectedSecurityGroup=null,n.dirty.securityGroups=!0),t!=a&&(e.backingData.filtered.securityGroups=a,n.dirty.securityGroups=!0),e.backingData.filtered.securityGroups===[]?e.viewState.securityGroupsConfigured=!1:e.viewState.securityGroupsConfigured=!0,n}function v(e){return H.chain(e).map("name").uniq().value().sort()}function h(e){const n={dirty:{}},t=e.loadBalancers,a=v(e.backingData.loadBalancers);if(t&&e.loadBalancers){const r=H.intersection(a,e.loadBalancers),i=H.xor(r,t);e.loadBalancers=r,i.length&&(n.dirty.loadBalancers=i)}return e.backingData.filtered.loadBalancers=a,n}function B(e){const n=e.backingData.loadBalancers,t=H.filter(n,(function(n){return n.account===e.credentials&&n.region===e.region}));return e.loadBalancers=v(t),e.viewState.loadBalancersConfigured=!0,{dirty:{}}}return{configureUpdateCommand:function(n){n.backingData={healthCheckTypes:e.copy(c),terminationPolicies:e.copy(d)}},configureCommand:function(t,r){return n.all([f.getCredentialsKeyedByAccount("azure"),a.loadSecurityGroups(),i.loadLoadBalancers(t.name)]).then((function([n,t,a]){var i;r.backingData={credentialsKeyedByAccount:n,securityGroups:t,loadBalancers:a,dataDiskTypes:e.copy(s),dataDiskCachingTypes:e.copy(o),accounts:H.keys(n),filtered:{}},(i=r).regionChanged=function(n,t=!1){const a={dirty:{}};return n.region&&n.credentials&&(e.extend(a.dirty,B(n).dirty),e.extend(a.dirty,g(n).dirty),e.extend(a.dirty,u(n).dirty),e.extend(a.dirty,p(n).dirty)),t||(n.loadBalancerName=null,n.loadBalancerType=null,n.vnet=null,n.vnetResourceGroup=null,n.subnet=null,n.selectedSubnet=null,n.selectedVnet=null,n.selectedVnetSubnets=[],n.viewState.networkSettingsConfigured=!1,n.selectedSecurityGroup=null,n.securityGroupName=null,n.zonesEnabled=!1,n.zones=[]),a},i.credentialsChanged=function(n,t){const a={dirty:{}},r=n.backingData;if(n.credentials){const i=r.credentialsKeyedByAccount[n.credentials]||{regions:[],defaultKeyPair:null};r.filtered.regions=i.regions,H.chain(r.filtered.regions).some({name:n.region}).value()?e.extend(a.dirty,n.regionChanged(n,t).dirty):(n.region=null,a.dirty.region=!0),n.region&&e.extend(a.dirty,B(n).dirty),e.extend(a.dirty,u(n).dirty)}else n.region=null;return a}}))},configureImages:function(e){const n={dirty:{}};let t=null;return e.viewState.disableImageSelection||(e.region?(t=e.backingData.packageImages.filter((function(n){return n.amis&&n.amis[e.region]})).map((function(n){return{imageName:n.imageName,ami:n.amis?n.amis[e.region][0]:null}})),e.amiName&&!t.some((function(n){return n.imageName===e.amiName}))&&(n.dirty.amiName=!0,e.amiName=null)):e.amiName=null,e.backingData.filtered.images=t),n},configureSecurityGroupOptions:g,configureLoadBalancerOptions:h,refreshLoadBalancers:function(e,n){return i.listLoadBalancers("azure").then((function(t){e.backingData.loadBalancers=t,n||h(e)}))},refreshSecurityGroups:function(e,n){return r.refreshCache("securityGroups").then((function(){return a.getAllSecurityGroups().then((function(t){e.backingData.securityGroups=t,n||g(e)}))}))},getRegionalSecurityGroups:m,refreshInstanceTypes:function(e){return r.refreshCache("instanceTypes").then((function(){return l.getAllTypesByRegion().then((function(n){e.backingData.instanceTypes=n,u(e)}))}))},configureZones:p}}]);n("spinnaker.azure.cloneServerGroup.controller",[O,"spinnaker.azure.serverGroup.configure.service","spinnaker.azure.serverGroup.transformer",x]).controller("azureCloneServerGroupCtrl",["$scope","$uibModalInstance","$q","$state","serverGroupWriter","azureServerGroupConfigurationService","serverGroupCommand","application","title",function(e,n,t,a,r,i,l,s,o){function c(){if(e.$$destroyed)return;const n=e.taskMonitor.task.execution.stages.find((e=>"cloneServerGroup"===e.type));if(n&&n.context["deploy.server.groups"]){const t=n.context["deploy.server.groups"][e.command.region];if(t){const n={serverGroup:t,accountId:e.command.credentials,region:e.command.region,provider:"azure"};let r="^.^.^.clusters.serverGroup";a.includes("**.clusters.serverGroup")&&(r="^.serverGroup"),a.includes("**.clusters.cluster.serverGroup")&&(r="^.^.serverGroup"),a.includes("**.clusters")&&(r=".serverGroup"),a.go(r,n)}}}function d(){i.configureCommand(s,l).then((function(){const n=l.viewState.mode;"clone"!==n&&"create"!==n||(l.viewState.useAllImageSelection=!0),e.state.loaded=!0,function(){const e=l.viewState.mode;"clone"!==e&&"editPipeline"!==e||(T.markComplete("basic-settings"),T.markComplete("load-balancers"),T.markComplete("network-settings"),T.markComplete("security-groups"),T.markComplete("instance-type"),T.markComplete("zones"))}(),p(e.command.credentialsChanged(e.command,!0)),p(e.command.regionChanged(e.command,!0)),e.$watch("command.credentials",u(e.command.credentialsChanged)),e.$watch("command.region",u(e.command.regionChanged))}))}function u(n){return function(t,a){t!==a&&p(n(e.command))}}function p(e){e.dirty.loadBalancers&&(T.markDirty("load-balancers"),T.markDirty("network-settings")),e.dirty.securityGroups&&T.markDirty("security-groups"),e.dirty.instanceType&&T.markDirty("instance-type"),(e.dirty.zoneEnabled||e.dirty.zones)&&T.markDirty("zones")}e.pages={templateSelection:"azure/src/serverGroup/configure/wizard/templateSelection.html",basicSettings:"azure/src/serverGroup/configure/wizard/basicSettings/basicSettings.html",imageSettings:"azure/src/serverGroup/configure/wizard/image/imageSettings.html",healthSettings:"azure/src/serverGroup/configure/wizard/healthSettings/healthSettings.html",loadBalancers:"azure/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html",networkSettings:"azure/src/serverGroup/configure/wizard/networkSettings/networkSettings.html",securityGroups:"azure/src/serverGroup/configure/wizard/securityGroup/securityGroups.html",instanceType:"azure/src/serverGroup/configure/wizard/instanceType/instanceType.html",zones:"azure/src/serverGroup/configure/wizard/capacity/zones.html",tags:"azure/src/serverGroup/configure/wizard/tags/tags.html",advancedSettings:"azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html"},e.firewallsLabel=b.get("Firewalls"),e.title=o,e.applicationName=s.name,e.application=s,e.command=l,e.command.backingData=e.command.backingData||{},e.command.backingData.filtered=e.command.backingData.filtered||{},e.command.backingData.filtered.regions=e.command.backingData.filtered.regions||[],e.state={loaded:!1,requiresTemplateSelection:!!l.viewState.requiresTemplateSelection},this.templateSelectionText={copied:["account, region, subnet, cluster name (stack, details)","load balancers",b.get("firewalls"),"instance type","all fields on the Advanced Settings page"],notCopied:[],additionalCopyText:"If a server group exists in this cluster at the time of deployment, its scaling policies will be copied over to the new server group."},e.command.viewState.disableStrategySelection||this.templateSelectionText.notCopied.push("the deployment strategy (if any) used to deploy the most recent server group"),e.taskMonitor=new g({application:s,title:"Creating your server group",modalInstance:n,onTaskComplete:function(){s.serverGroups.refresh(),s.serverGroups.onNextRefresh(e,c)}}),this.submit=function(){if("editPipeline"===e.command.viewState.mode||"createPipeline"===e.command.viewState.mode)return n.close(e.command);e.taskMonitor.submit((function(){return r.cloneServerGroup(e.command,s)}))},this.cancel=function(){n.dismiss()},this.toggleSuspendedProcess=function(n){e.command.suspendedProcesses=e.command.suspendedProcesses||[];const t=e.command.suspendedProcesses.indexOf(n);-1===t?e.command.suspendedProcesses.push(n):e.command.suspendedProcesses.splice(t,1)},this.processIsSuspended=function(n){return e.command.suspendedProcesses.includes(n)},e.state.requiresTemplateSelection?e.state.loaded=!0:d(),this.templateSelected=()=>{e.state.requiresTemplateSelection=!1,d()},this.isValid=function(){return e.command&&e.command.application&&e.command.credentials&&e.command.instanceType&&e.command.region&&(!e.command.zonesEnabled||0!==e.command.zones.length)&&K.checkTags(e.command.instanceTags).isValid}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/templateSelection.html",'<deploy-initializer\n cloud-provider="azure"\n command="command"\n application="application"\n parent-state="state"\n dismiss="ctrl.cancel()"\n template-selection-text="ctrl.templateSelectionText"\n on-template-selected="ctrl.templateSelected()"\n></deploy-initializer>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/basicSettings/basicSettings.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupBasicSettingsCtrl as basicSettingsCtrl">\n <div class="modal-body">\n <ng-form name="basicSettings">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Account</div>\n <div class="col-md-7">\n <account-select-field\n required\n read-only="command.viewState.readOnlyFields.credentials"\n component="command"\n field="credentials"\n accounts="command.backingData.accounts"\n provider="\'azure\'"\n ></account-select-field>\n </div>\n </div>\n <region-select-field\n required\n read-only="command.viewState.readOnlyFields.region"\n label-columns="3"\n component="command"\n field="region"\n account="command.credentials"\n provider="\'azure\'"\n regions="command.backingData.filtered.regions"\n ></region-select-field>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n Stack\n <help-field key="azure.serverGroup.stack"></help-field>\n </div>\n <div class="col-md-7">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-pattern="basicSettingsCtrl.stackPattern"\n name="stack"\n ng-model="command.stack"\n />\n </div>\n </div>\n <div class="form-group row slide-in" ng-if="basicSettings.stack.$error.pattern">\n <div class="col-sm-9 col-sm-offset-2 error-message">\n <span>Stack can only contain letters and numbers.</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n Detail\n <help-field key="azure.serverGroup.detail"></help-field>\n </div>\n <div class="col-md-7">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-pattern="basicSettingsCtrl.detailPattern"\n name="details"\n ng-model="command.freeFormDetails"\n />\n </div>\n </div>\n <div class="form-group row slide-in" ng-if="basicSettings.details.$error.pattern">\n <div class="col-sm-9 col-sm-offset-2 error-message">\n <span>Detail can only contain letters, numbers, and dashes(-).</span>\n </div>\n </div>\n <div class="form-group" ng-if="!command.viewState.disableImageSelection">\n <div class="col-md-3 sm-label-right">\n Image\n <help-field key="azure.serverGroup.imageName"></help-field>\n </div>\n <div class="col-md-9">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="command.selectedImage"\n on-select="basicSettingsCtrl.imageChanged($item)"\n >\n <ui-select-match placeholder="Pick an image">{{$select.selected.imageName}}</ui-select-match>\n <ui-select-choices repeat="image in command.images | regional:command.region | filter:$select.search">\n <span ng-bind-html="image.imageName"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <deployment-strategy-selector\n ng-if="!command.viewState.disableStrategySelection && command.selectedProvider"\n command="command"\n ></deployment-strategy-selector>\n <div class="form-group" ng-if="!command.viewState.hideClusterNamePreview">\n <div class="col-md-12">\n <div\n class="well-compact"\n ng-class="basicSettingsCtrl.showPreviewAsWarning() ? \'alert alert-warning\' : \'well\'"\n >\n <h5 class="text-center">\n <p>Your server group will be in the cluster:</p>\n <p>\n <strong>\n {{basicSettingsCtrl.getNamePreview()}}\n <span ng-if="basicSettingsCtrl.createsNewCluster()"> (new cluster)</span>\n </strong>\n </p>\n <div\n class="text-left"\n ng-if="!basicSettingsCtrl.createsNewCluster() && command.viewState.mode === \'create\' && latestServerGroup"\n >\n <p>There is already a server group in this cluster. Do you want to clone it?</p>\n <p>\n Cloning copies the entire configuration from the selected server group, allowing you to modify\n whichever fields (e.g. image) you need to change in the new server group.\n </p>\n <p>\n To clone a server group, select "Clone" from the "Server Group Actions" menu in the details view of\n the server group.\n </p>\n <p>\n <a href ng-click="basicSettingsCtrl.navigateToLatestServerGroup()">\n Go to details for {{latestServerGroup.name}}\n </a>\n </p>\n </div>\n </h5>\n </div>\n </div>\n </div>\n </ng-form>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/image/imageSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-image-settings-selector command="command"></azure-server-group-image-settings-selector>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/healthSettings/healthSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-health-settings-selector command="command"></azure-server-group-health-settings-selector>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html",'<div class="row">\n <azure-server-group-load-balancers-selector command="command"></azure-server-group-load-balancers-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/networkSettings/networkSettings.html",'<div class="row">\n <azure-server-group-network-settings-selector command="command"></azure-server-group-network-settings-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/securityGroup/securityGroups.html",'<div class="row">\n <azure-server-group-security-groups-selector command="command"></azure-server-group-security-groups-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/instanceType/instanceType.html",'<div ng-show="!!(command.region)">\n <v2-instance-archetype-selector ng-if="command.region" command="command"></v2-instance-archetype-selector>\n <div style="padding: 0 15px">\n <v2-instance-type-selector\n ng-if="command.viewState.instanceProfile && !(command.viewState.instanceProfile === \'custom\' || command.viewState.instanceProfile === \'buildCustom\' )"\n command="command"\n ></v2-instance-type-selector>\n </div>\n</div>\n<h5 class="text-center" ng-if="!command.region">Please select a region.</h5>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/capacity/zones.html",'<ng-form name="zonesSubForm">\n <div class="container-fluid form-horizontal">\n <azure-zone-selector command="command"></azure-zone-selector>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/tags/tags.html",'<ng-form name="zonesSubForm">\n <div class="container-fluid form-horizontal">\n <azure-tags-selector command="command"></azure-tags-selector>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-advanced-settings-selector command="command"></azure-server-group-advanced-settings-selector>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.serverGroupCommandBuilder.service",["spinnaker.azure.image.reader","spinnaker.azure.serverGroup.transformer"]).factory("azureServerGroupCommandBuilder",["$q","azureImageReader","azureServerGroupTransformer",function(n,t,a){function r(e,n){const a=(n=n||{}).account||e.defaultCredentials.azure,r=n.region||e.defaultRegions.azure;return t.findImages({provider:"azure"}).then((function(t){return{application:e.name,credentials:a,region:r,images:t,loadBalancers:[],selectedVnetSubnets:[],strategy:"",sku:{capacity:1},zonesEnabled:!1,zones:[],instanceTags:{},dataDisks:[],selectedProvider:"azure",viewState:{instanceProfile:"custom",allImageSelection:null,useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!0,mode:n.mode||"create",disableStrategySelection:!0,loadBalancersConfigured:!1,networkSettingsConfigured:!1,securityGroupsConfigured:!1},enableInboundNAT:!1}}))}return{buildNewServerGroupCommand:r,buildNewServerGroupCommandForPipeline:function(){return n.when({viewState:{requiresTemplateSelection:!0}})},buildServerGroupCommandFromExisting:function(e,t,r){r=r||"clone";const i=B.parseServerGroupName(t.name),l={application:e.name,strategy:"",stack:i.stack,freeFormDetails:i.freeFormDetails,credentials:t.account,loadBalancers:t.loadBalancers,selectedSubnets:t.selectedVnetSubnets,selectedVnet:t.selectedVnet,securityGroups:t.securityGroups,loadBalancerName:t.loadBalancerName,loadBalancerType:t.loadBalancerType,securityGroupName:t.securityGroupName,region:t.region,vnet:t.vnet,vnetResourceGroup:t.vnetResourceGroup,subnet:t.subnet,zones:t.zones,zonesEnabled:t.zones&&t.zones.length>0,instanceTags:{},dataDisks:t.dataDisks,sku:t.sku,capacity:{min:t.capacity.min,max:t.capacity.max,desired:t.capacity.desired},tags:[],instanceType:t.sku.name,selectedProvider:"azure",source:{account:t.account,region:t.region,serverGroupName:t.name,asgName:t.name},viewState:{allImageSelection:null,useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!1,listImplicitSecurityGroups:!1,mode:r,disableStrategySelection:!0},enableInboundNAT:t.enableInboundNAT};return void 0!==t.customScriptsSettings&&(l.customScriptsSettings={},l.customScriptsSettings.commandToExecute=t.customScriptsSettings.commandToExecute,H.isEmpty(t.customScriptsSettings.fileUris)||a.parseCustomScriptsSettings(t,l)),n.when(l)},buildServerGroupCommandFromPipeline:function(n,t){const a=H.cloneDeep(t),i=a.region;return r(n,{account:a.account,region:i}).then((function(n){const r={disableImageSelection:!0,useSimpleCapacity:!0,mode:"editPipeline",submitButtonLabel:"Done",instanceProfile:t.viewState.instanceProfile,instanceTypeDetails:t.viewState.instanceTypeDetails},l={region:i,credentials:a.account,viewState:r};t.viewState.instanceTypeDetails&&(l.instanceType=t.viewState.instanceTypeDetails.name),a.strategy=a.strategy||"";return e.extend({},n,a,l)}))}}}]);class re extends X.Component{constructor(e){super(e),this.state={verified:!1},this.handleVerification=e=>{this.setState({verified:e})}}render(){const{onSubmit:e,onCancel:n,isValid:t,account:a}=this.props,{verified:r}=this.state;return X.createElement("div",{className:"modal-footer"},X.createElement(N,{expectedValue:a,onValidChange:this.handleVerification}),X.createElement("button",{className:"btn btn-default",onClick:n},"Cancel"),X.createElement("button",{type:"submit",className:"btn btn-primary",onClick:e,disabled:!t||!r},"Submit"))}}const ie=class extends X.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal.apply(null,e)},this.submit=()=>{const{command:e,taskMonitor:n}=this.state,{serverGroup:t,application:a}=this.props;n.submit((()=>P.serverGroupWriter.rollbackServerGroup(t,a,e)))},this.filterServerGroups=e=>e.filter((e=>0!==e.instanceCounts.total)).sort(((e,n)=>n.name.localeCompare(e.name))),this.isValid=()=>void 0!==this.state.command.rollbackContext.restoreServerGroupName,this.handleServerGroupChange=e=>{const{disabledServerGroups:n}=this.props,t={...this.state.command};t.rollbackContext.restoreServerGroupName=e.value;const a=this.filterServerGroups(n).find((function(n){return n.name===e.value}));t.targetSize=a.capacity.max,this.setState({command:t})},this.handleTaskReasonChange=e=>{const n={...this.state.command};n.reason=e,this.setState({command:n})};const{application:n,serverGroup:t}=e;this.state={taskMonitor:new g({application:n,title:"Rolling back your server group",modalInstance:g.modalInstanceEmulation((()=>this.props.dismissModal()))}),submitting:!0,command:{interestingHealthProviderNames:[],rollbackType:"EXPLICIT",rollbackContext:{rollbackServerGroupName:t.name,enableAndDisableOnly:!0}}}}static show(e){return d.show(ie,e,{})}render(){const{command:e,taskMonitor:n,submitting:t}=this.state,{serverGroup:a,disabledServerGroups:r}=this.props,i=this.isValid(),l=this.filterServerGroups(r).map((e=>({label:e.name,value:e.name})));return X.createElement(q,{onHide:this.close},X.createElement(L,{monitor:n}),t&&X.createElement("form",{role:"form"},X.createElement(u,{dismiss:this.close}),X.createElement(q.Header,null,X.createElement(q.Title,null,"Rollback ",a.name)),X.createElement(q.Body,null,X.createElement("div",{className:"row"},X.createElement("div",{className:"col-sm-3 sm-label-right"},"Restore to"),X.createElement("div",{className:"col-sm-6"},X.createElement(W,{value:e.rollbackContext.restoreServerGroupName,onChange:this.handleServerGroupChange,options:l}))),X.createElement(R,{reason:e.taskReason,onChange:this.handleTaskReasonChange})),X.createElement(re,{onSubmit:this.submit,onCancel:this.close,isValid:i,account:a.account})))}};let le=ie;le.defaultProps={closeModal:p,dismissModal:p};e.module("spinnaker.azure.serverGroup.details.controller",[O,"spinnaker.azure.serverGroupCommandBuilder.service",x]).controller("azureServerGroupDetailsCtrl",["$scope","$state","$templateCache","app","serverGroup","azureServerGroupCommandBuilder","$uibModal","serverGroupWriter",function(n,t,a,r,l,s,o,c){function d(){const a=function(){let e=H.find(r.serverGroups.data,(function(e){return e.name===l.name&&e.account===l.accountId&&e.region===l.region}));return e||r.loadBalancers.data.some((function(n){if(n.account===l.accountId&&n.region===l.region)return n.serverGroups.some((function(n){if(n.name===l.name)return e=n,!0}))})),e||t.go("^"),e}();return M.getServerGroup(r.name,l.accountId,l.region,l.name).then((function(i){if(n.state.loading=!1,e.extend(i,a),i.account=l.accountId,n.serverGroup=i,H.isEmpty(n.serverGroup))t.go("^");else{if(n.image=i.image?i.image:void 0,i.image&&i.image.description){i.image.description.split(", ").forEach((function(e){const n=e.split("=");2===n.length&&"ancestor_name"===n[0]&&(i.image.baseImage=n[1])}))}i.launchConfig&&i.launchConfig.securityGroups&&(n.securityGroups=H.chain(i.launchConfig.securityGroups).map((function(e){return H.find(r.securityGroups.data,{accountName:l.accountId,region:l.region,id:e})||H.find(r.securityGroups.data,{accountName:l.accountId,region:l.region,name:e})})).compact().value())}}))}n.state={loading:!0},n.firewallsLabel=b.get("Firewalls"),this.application=r,d().then((()=>{n.$$destroyed||r.serverGroups.onRefresh(n,d)})),this.destroyServerGroup=function(){const e=n.serverGroup,a={name:e.name,accountId:e.account,region:e.region},l={application:r,title:"Destroying "+e.name,onTaskComplete:function(){t.includes("**.serverGroup",a)&&t.go("^")}},s={header:"Really destroy "+e.name+"?",buttonText:"Destroy "+e.name,account:e.account,taskMonitorConfig:l,submitMethod:function(){return c.destroyServerGroup(e,r)}};U.addDestroyWarningMessage(r,e,s),i.confirm(s)},this.disableServerGroup=function(){const e=n.serverGroup,t={application:r,title:"Disabling "+e.name},a={header:"Really disable "+e.name+"?",buttonText:"Disable "+e.name,account:e.account,taskMonitorConfig:t,submitMethod:()=>c.disableServerGroup(e,r)};U.addDisableWarningMessage(r,e,a),i.confirm(a)},this.enableServerGroup=function(){const t=n.serverGroup,a={application:r,title:"Enabling "+t.name};i.confirm({header:"Really enable "+t.name+"?",buttonText:"Enable "+t.name,account:t.account,taskMonitorConfig:a,submitMethod:n=>c.enableServerGroup(t,r,e.extend(n,{interestingHealthProviderNames:[]}))})},this.rollbackServerGroup=()=>{const e=n.serverGroup,t=H.find(r.clusters,{name:e.cluster,account:e.account}),a=H.filter(t.serverGroups,{isDisabled:!0,region:e.region});le.show({application:r,serverGroup:e,disabledServerGroups:a})},this.cloneServerGroup=e=>{o.open({templateUrl:"azure/src/serverGroup/configure/wizard/serverGroupWizard.html",controller:"azureCloneServerGroupCtrl as ctrl",size:"lg",resolve:{title:()=>"Clone "+e.name,application:()=>r,serverGroupCommand:()=>s.buildServerGroupCommandFromExisting(r,e)}})},this.truncateCommitHash=function(){return n.serverGroup&&n.serverGroup.buildInfo&&n.serverGroup.buildInfo.commit?n.serverGroup.buildInfo.commit.substring(0,8):null}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/serverGroupWizard.html",'<div>\n <div ng-if="state.requiresTemplateSelection">\n <ng-include src="pages.templateSelection"></ng-include>\n </div>\n <div ng-if="!state.loaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div>\n <form name="serverGroupWizardForm" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard\n ng-show="state.loaded && !state.requiresTemplateSelection"\n heading="{{title}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="basic-settings" label="Basic Settings" hide-subheading="true">\n <ng-include src="pages.basicSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="image-settings" label="Image">\n <ng-include src="pages.imageSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="load-balancers" label="Load Balancers" mark-complete-on-view="false">\n <ng-include src="pages.loadBalancers"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="network-settings" label="Network Settings" mark-complete-on-view="false">\n <ng-include src="pages.networkSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="health-settings" label="Health" mark-complete-on-view="false">\n <ng-include src="pages.healthSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="security-groups" label="{{firewallsLabel}}" mark-complete-on-view="false" done="true">\n <ng-include src="pages.securityGroups"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="instance-type" label="Instance Type" mark-complete-on-view="false" done="false">\n <ng-include src="pages.instanceType"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="zones" label="Zones" mark-complete-on-view="false" done="false">\n <ng-include src="pages.zones"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="tags" label="Tags" mark-complete-on-view="false" done="true">\n <ng-include src="pages.tags"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="advanced-settings" label="Advanced Settings" mark-complete-on-view="false" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer" ng-if="state.loaded">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default btn-cancel" ng-click="ctrl.cancel()">\n Cancel\n </button>\n <submit-button\n is-disabled="taskMonitor.submitting || !ctrl.isValid()"\n label="command.viewState.submitButtonLabel"\n submitting="taskMonitor.submitting"\n on-click="serverGroupWizardForm.$valid && ctrl.submit()"\n is-new="true"\n ></submit-button>\n </div>\n </form>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.details.azure",["spinnaker.azure.serverGroup.details.controller"]);n("spinnaker.azure.validation.applicationName",[]).factory("azureApplicationNameValidator",(function(){return{validate:function(e){const n=[];return e&&e.length&&function(e,n){/^([a-zA-Z][a-zA-Z0-9]*)?$/.test(e)||n.push("The application name must begin with a letter and must contain only letters or digits. No special characters are allowed.")}(e,n),{warnings:[],errors:n}}}})).run(["azureApplicationNameValidator",function(e){V.registerValidator("azure",e)}]);!function(e,n){void 0===n&&(n={});var t=n.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===t&&a.firstChild?a.insertBefore(r,a.firstChild):a.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}('.cloud-provider-logo .icon-azure {\n -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!-- Generator%3A Adobe Illustrator 22.1.0%2C SVG Export Plug-In . SVG Version%3A 6.00 Build 0) --%3E%3Csvg version%3D%221.1%22 id%3D%22Layer_1%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22 x%3D%220px%22 y%3D%220px%22%09 viewBox%3D%220 0 48 48%22 style%3D%22enable-background%3Anew 0 0 48 48%3B%22 xml%3Aspace%3D%22preserve%22%3E%3Cstyle type%3D%22text%2Fcss%22%3E%09.st0%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2300A2D8%3B%7D%09.st1%7Bfill%3A%23F79E1C%3B%7D%09.st2%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232ABAEC%3B%7D%09.st3%7Bfill%3A%23F7B218%3B%7D%09.st4%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3Anone%3B%7D%09.st5%7Bfill%3A%2300A2D8%3B%7D%09.st6%7Bfill%3A%232ABAEC%3B%7D%09.st7%7Bfill%3A%23323A45%3B%7D%09.st8%7Bfill%3A%2388909B%3B%7D%09.st9%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st10%7Bfill%3A%23A3BF3A%3B%7D%09.st11%7Bfill%3A%2380A23E%3B%7D%09.st12%7Bfill%3A%237B4D87%3B%7D%09.st13%7Bfill%3A%232F75BB%3B%7D%09.st14%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2385C9D5%3B%7D%09.st15%7Bopacity%3A0.15%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st16%7Bfill%3A%23A5D9E2%3B%7D%09.st17%7Bfill%3A%2385C9D5%3B%7D%09.st18%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23323A45%3B%7D%09.st19%7Bfill%3A%23FFFFFF%3B%7D%09.st20%7Bfill%3A%23DAEFF3%3B%7D%09.st21%7Bfill%3A%232A65AF%3B%7D%09.st22%7Bfill%3A%23F6ECF4%3B%7D%09.st23%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232F75BB%3B%7D%09.st24%7Bfill%3Anone%3B%7D%09.st25%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9BA19%3B%7D%09.st26%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23A3BF3A%3B%7D%09.st27%7Bfill%3A%23F6931D%3B%7D%09.st28%7Bfill%3A%235E6D80%3B%7D%09.st29%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3B%7D%09.st30%7Bfill%3A%2300B8E2%3B%7D%09.st31%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%235E6D80%3B%7D%09.st32%7Bfill%3Anone%3Bstroke%3A%2385C9D5%3Bstroke-width%3A0%3Bstroke-linecap%3Around%3Bstroke-linejoin%3Around%3B%7D%09.st33%7Bfill%3A%232A89CA%3B%7D%09.st34%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237B4D87%3B%7D%09.st35%7Bopacity%3A0.3%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st36%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3B%7D%09.st37%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2378B843%3B%7D%09.st38%7Bfill%3A%2378B843%3B%7D%09.st39%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23EDF0F4%3B%7D%09.st40%7Bfill%3A%23005BA3%3B%7D%09.st41%7Bfill%3A%230F80B0%3B%7D%09.st42%7Bfill%3A%23005F87%3B%7D%09.st43%7Bfill%3A%23B7D332%3B%7D%09.st44%7Bfill%3A%237FB900%3B%7D%09.st45%7Bopacity%3A0.6%3Bfill%3A%23FFFFFF%3B%7D%09.st46%7Bopacity%3A0.4%3Bfill%3A%23FFFFFF%3B%7D%09.st47%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_13_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st48%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_64_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st49%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_65_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st50%7Bfill%3A%2373BDCD%3B%7D%09.st51%7Bopacity%3A0.6%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st52%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3Bstroke%3A%23FFFFFF%3Bstroke-width%3A4%3Bstroke-miterlimit%3A10%3B%7D%09.st53%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3B%7D%09.st54%7Bclip-path%3Aurl(%23XMLID_67_)%3Bfill%3Anone%3B%7D%09.st55%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F7B218%3B%7D%09.st56%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_69_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st57%7Bopacity%3A0.8%3Bfill%3A%23FFFFFF%3B%7D%09.st58%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_79_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st59%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23DB5B26%3B%7D%09.st60%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F58B1F%3B%7D%09.st61%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_84_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st62%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23404B59%3B%7D%09.st63%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_118_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st64%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23D1B0D3%3B%7D%09.st65%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_119_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st66%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2315B2E7%3B%7D%09.st67%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23E1F3F8%3B%7D%09.st68%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_120_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st69%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_124_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st70%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_125_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st71%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_126_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st72%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237C8737%3B%7D%09.st73%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_127_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st74%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_130_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st75%7Bfill%3A%23CCCBCB%3B%7D%09.st76%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2388909B%3B%7D%09.st77%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st78%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_131_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st79%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_133_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st80%7Bdisplay%3Anone%3B%7D%09.st81%7Bfill%3A%2345B6F4%3B%7D%09.st82%7Bfill%3A%2389919C%3B%7D%09.st83%7Bfill%3A%2361ADD1%3B%7D%09.st84%7Bfill%3A%233899C6%3B%7D%09.st85%7Bfill%3A%23F78F08%3B%7D%09.st86%7Bfill%3A%23C1BFBC%3B%7D%09.st87%7Bfill%3A%237A7A7A%3B%7D%09.st88%7Bfill%3A%23B3B4B5%3B%7D%09.st89%7Bopacity%3A0.48%3B%7D%09.st90%7Bfill%3A%23A0A1A2%3B%7D%09.st91%7Bfill%3A%23A1DEF0%3B%7D%09.st92%7Bfill%3A%23804998%3B%7D%09.st93%7Bfill%3A%230072C6%3B%7D%09.st94%7Bfill%3A%2359B4D9%3B%7D%09.st95%7Bfill%3A%233999C6%3B%7D%09.st96%7Bfill%3A%230078D7%3B%7D%09.st97%7Bfill%3A%23D1B972%3B%7D%09.st98%7Bfill%3A%23FEE087%3B%7D%09.st99%7Bfill%3A%23B1CE2D%3B%7D%09.st100%7Bfill%3A%237FBA00%3B%7D%09.st101%7Bfill%3A%23FCD116%3B%7D%09.st102%7Bfill%3A%23719904%3B%7D%09.st103%7Bfill%3A%23B8D432%3B%7D%09.st104%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23804898%3B%7D%09.st105%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%236B2980%3B%7D%09.st106%7Bfill%3A%236B2980%3B%7D%09.st107%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st108%7Bopacity%3A0.2%3Bfill%3A%231E1E1E%3Benable-background%3Anew %3B%7D%09.st109%7Bfill%3A%2333BCF0%3B%7D%09.st110%7Bopacity%3A0.2%3Bfill%3A%23636363%3B%7D%09.st111%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_134_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st112%7Bfill%3A%238B77B6%3B%7D%09.st113%7Bfill%3A%239B6CAC%3B%7D%09.st114%7Bfill%3A%23874B94%3B%7D%09.st115%7Bopacity%3A0.4%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st116%7Bopacity%3A0.8%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st117%7Bopacity%3A0.6%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st118%7Bopacity%3A0.25%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st119%7Bfill%3A%23DD5900%3B%7D%09.st120%7Bfill%3A%23FF8C00%3B%7D%09.st121%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%233E3E3E%3B%7D%09.st122%7Bfill%3Aurl(%23path3060_1_)%3B%7D%09.st123%7Bfill%3A%231870C5%3B%7D%09.st124%7Bfill%3A%2372BFDF%3B%7D%09.st125%7Bfill%3A%233C3938%3B%7D%09.st126%7Bfill%3A%230072AC%3B%7D%09.st127%7Bfill%3A%230079B6%3B%7D%09.st128%7Bfill%3A%2300A2D9%3B%7D%09.st129%7Bfill%3A%23BFDC34%3B%7D%09.st130%7Bfill%3A%23898989%3B%7D%09.st131%7Bfill%3A%23EDF0F5%3B%7D%09.st132%7Bfill%3A%23A3A4A7%3B%7D%09.st133%7Bfill%3A%23353535%3B%7D%09.st134%7Bfill%3A%23FF8C02%3B%7D%09.st135%7Bfill%3A%2300AC8C%3B%7D%09.st136%7Bfill%3A%236EC2E9%3B%7D%09.st137%7Bfill%3A%23442359%3B%7D%09.st138%7Bfill%3A%236DC0E6%3B%7D%09.st139%7Bfill%3A%23432056%3B%7D%09.st140%7Bfill%3A%2386CAD7%3B%7D%09.st141%7Bfill%3A%23009E48%3B%7D%09.st142%7Bopacity%3A0.2%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st143%7Bfill%3A%2368217A%3B%7D%09.st144%7Bfill%3A%23E5E5E5%3B%7D%09.st145%7Bopacity%3A0.15%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st146%7Bfill%3A%233898C6%3B%7D%09.st147%7Bfill%3A%2380BA42%3B%7D%09.st148%7Bfill%3A%23B3D234%3B%7D%09.st149%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9F9F9%3B%7D%09.st150%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23008EBE%3B%7D%09.st151%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F1F1F2%3B%7D%09.st152%7Bfill%3A%23BAD80A%3B%7D%09.st153%7Bclip-path%3Aurl(%23SVGID_2_)%3B%7D%09.st154%7Bfill%3A%2300BCF2%3B%7D%09.st155%7Bfill%3A%235AB4DA%3B%7D%09.st156%7Bfill%3Anone%3Bstroke%3A%235AB4DA%3Bstroke-width%3A0.75%3Bstroke-miterlimit%3A10%3B%7D%09.st157%7Bfill%3A%233898C5%3B%7D%09.st158%7Bfill%3A%237A7B7B%3B%7D%09.st159%7Bfill%3A%23545555%3B%7D%09.st160%7Bfill%3A%23D6EAF3%3B%7D%09.st161%7Bfill%3A%23009580%3B%7D%09.st162%7Bfill%3A%23BA141A%3B%7D%09.st163%7Bfill%3A%237AC3E1%3B%7D%09.st164%7Bfill%3A%23E27226%3B%7D%09.st165%7Bfill%3A%23FF9D26%3B%7D%09.st166%7Bopacity%3A0.12%3Bfill%3A%23BA141A%3B%7D%09.st167%7Bfill%3A%233C98C5%3B%7D%09.st168%7Bfill%3A%235AB3D8%3B%7D%09.st169%7Bfill%3A%23AAD8EB%3B%7D%09.st170%7Bfill%3A%23797979%3B%7D%09.st171%7Bfill%3A%23959595%3B%7D%09.st172%7Bfill%3A%23D1D1D1%3B%7D%09.st173%7Bclip-path%3Aurl(%23SVGID_4_)%3B%7D%09.st174%7Bfill%3A%2333A2E5%3B%7D%09.st175%7Bfill%3A%2371C2EA%3B%7D%09.st176%7Bfill%3A%23005091%3B%7D%09.st177%7Bclip-path%3Aurl(%23SVGID_6_)%3B%7D%09.st178%7Bfill%3A%23ACD64D%3B%7D%3C%2Fstyle%3E%3Cg%3E%09%3Cg%3E%09%09%3Cg%3E%09%09%09%3Cg%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2226.5%2C4.5 12.5%2C15.5 1.5%2C35.5 11.5%2C35.5 %09%09%09%09%22%2F%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2227.5%2C7.5 21.5%2C22.5 32.5%2C35.5 11.5%2C40.5 46.5%2C40.5 %09%09%09%09%22%2F%3E%09%09%09%3C%2Fg%3E%09%09%3C%2Fg%3E%09%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!-- Generator%3A Adobe Illustrator 22.1.0%2C SVG Export Plug-In . SVG Version%3A 6.00 Build 0) --%3E%3Csvg version%3D%221.1%22 id%3D%22Layer_1%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22 x%3D%220px%22 y%3D%220px%22%09 viewBox%3D%220 0 48 48%22 style%3D%22enable-background%3Anew 0 0 48 48%3B%22 xml%3Aspace%3D%22preserve%22%3E%3Cstyle type%3D%22text%2Fcss%22%3E%09.st0%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2300A2D8%3B%7D%09.st1%7Bfill%3A%23F79E1C%3B%7D%09.st2%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232ABAEC%3B%7D%09.st3%7Bfill%3A%23F7B218%3B%7D%09.st4%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3Anone%3B%7D%09.st5%7Bfill%3A%2300A2D8%3B%7D%09.st6%7Bfill%3A%232ABAEC%3B%7D%09.st7%7Bfill%3A%23323A45%3B%7D%09.st8%7Bfill%3A%2388909B%3B%7D%09.st9%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st10%7Bfill%3A%23A3BF3A%3B%7D%09.st11%7Bfill%3A%2380A23E%3B%7D%09.st12%7Bfill%3A%237B4D87%3B%7D%09.st13%7Bfill%3A%232F75BB%3B%7D%09.st14%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2385C9D5%3B%7D%09.st15%7Bopacity%3A0.15%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st16%7Bfill%3A%23A5D9E2%3B%7D%09.st17%7Bfill%3A%2385C9D5%3B%7D%09.st18%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23323A45%3B%7D%09.st19%7Bfill%3A%23FFFFFF%3B%7D%09.st20%7Bfill%3A%23DAEFF3%3B%7D%09.st21%7Bfill%3A%232A65AF%3B%7D%09.st22%7Bfill%3A%23F6ECF4%3B%7D%09.st23%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232F75BB%3B%7D%09.st24%7Bfill%3Anone%3B%7D%09.st25%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9BA19%3B%7D%09.st26%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23A3BF3A%3B%7D%09.st27%7Bfill%3A%23F6931D%3B%7D%09.st28%7Bfill%3A%235E6D80%3B%7D%09.st29%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3B%7D%09.st30%7Bfill%3A%2300B8E2%3B%7D%09.st31%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%235E6D80%3B%7D%09.st32%7Bfill%3Anone%3Bstroke%3A%2385C9D5%3Bstroke-width%3A0%3Bstroke-linecap%3Around%3Bstroke-linejoin%3Around%3B%7D%09.st33%7Bfill%3A%232A89CA%3B%7D%09.st34%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237B4D87%3B%7D%09.st35%7Bopacity%3A0.3%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st36%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3B%7D%09.st37%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2378B843%3B%7D%09.st38%7Bfill%3A%2378B843%3B%7D%09.st39%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23EDF0F4%3B%7D%09.st40%7Bfill%3A%23005BA3%3B%7D%09.st41%7Bfill%3A%230F80B0%3B%7D%09.st42%7Bfill%3A%23005F87%3B%7D%09.st43%7Bfill%3A%23B7D332%3B%7D%09.st44%7Bfill%3A%237FB900%3B%7D%09.st45%7Bopacity%3A0.6%3Bfill%3A%23FFFFFF%3B%7D%09.st46%7Bopacity%3A0.4%3Bfill%3A%23FFFFFF%3B%7D%09.st47%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_13_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st48%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_64_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st49%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_65_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st50%7Bfill%3A%2373BDCD%3B%7D%09.st51%7Bopacity%3A0.6%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st52%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3Bstroke%3A%23FFFFFF%3Bstroke-width%3A4%3Bstroke-miterlimit%3A10%3B%7D%09.st53%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3B%7D%09.st54%7Bclip-path%3Aurl(%23XMLID_67_)%3Bfill%3Anone%3B%7D%09.st55%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F7B218%3B%7D%09.st56%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_69_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st57%7Bopacity%3A0.8%3Bfill%3A%23FFFFFF%3B%7D%09.st58%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_79_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st59%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23DB5B26%3B%7D%09.st60%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F58B1F%3B%7D%09.st61%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_84_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st62%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23404B59%3B%7D%09.st63%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_118_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st64%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23D1B0D3%3B%7D%09.st65%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_119_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st66%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2315B2E7%3B%7D%09.st67%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23E1F3F8%3B%7D%09.st68%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_120_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st69%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_124_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st70%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_125_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st71%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_126_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st72%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237C8737%3B%7D%09.st73%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_127_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st74%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_130_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st75%7Bfill%3A%23CCCBCB%3B%7D%09.st76%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2388909B%3B%7D%09.st77%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st78%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_131_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st79%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_133_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st80%7Bdisplay%3Anone%3B%7D%09.st81%7Bfill%3A%2345B6F4%3B%7D%09.st82%7Bfill%3A%2389919C%3B%7D%09.st83%7Bfill%3A%2361ADD1%3B%7D%09.st84%7Bfill%3A%233899C6%3B%7D%09.st85%7Bfill%3A%23F78F08%3B%7D%09.st86%7Bfill%3A%23C1BFBC%3B%7D%09.st87%7Bfill%3A%237A7A7A%3B%7D%09.st88%7Bfill%3A%23B3B4B5%3B%7D%09.st89%7Bopacity%3A0.48%3B%7D%09.st90%7Bfill%3A%23A0A1A2%3B%7D%09.st91%7Bfill%3A%23A1DEF0%3B%7D%09.st92%7Bfill%3A%23804998%3B%7D%09.st93%7Bfill%3A%230072C6%3B%7D%09.st94%7Bfill%3A%2359B4D9%3B%7D%09.st95%7Bfill%3A%233999C6%3B%7D%09.st96%7Bfill%3A%230078D7%3B%7D%09.st97%7Bfill%3A%23D1B972%3B%7D%09.st98%7Bfill%3A%23FEE087%3B%7D%09.st99%7Bfill%3A%23B1CE2D%3B%7D%09.st100%7Bfill%3A%237FBA00%3B%7D%09.st101%7Bfill%3A%23FCD116%3B%7D%09.st102%7Bfill%3A%23719904%3B%7D%09.st103%7Bfill%3A%23B8D432%3B%7D%09.st104%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23804898%3B%7D%09.st105%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%236B2980%3B%7D%09.st106%7Bfill%3A%236B2980%3B%7D%09.st107%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st108%7Bopacity%3A0.2%3Bfill%3A%231E1E1E%3Benable-background%3Anew %3B%7D%09.st109%7Bfill%3A%2333BCF0%3B%7D%09.st110%7Bopacity%3A0.2%3Bfill%3A%23636363%3B%7D%09.st111%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_134_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st112%7Bfill%3A%238B77B6%3B%7D%09.st113%7Bfill%3A%239B6CAC%3B%7D%09.st114%7Bfill%3A%23874B94%3B%7D%09.st115%7Bopacity%3A0.4%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st116%7Bopacity%3A0.8%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st117%7Bopacity%3A0.6%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st118%7Bopacity%3A0.25%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st119%7Bfill%3A%23DD5900%3B%7D%09.st120%7Bfill%3A%23FF8C00%3B%7D%09.st121%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%233E3E3E%3B%7D%09.st122%7Bfill%3Aurl(%23path3060_1_)%3B%7D%09.st123%7Bfill%3A%231870C5%3B%7D%09.st124%7Bfill%3A%2372BFDF%3B%7D%09.st125%7Bfill%3A%233C3938%3B%7D%09.st126%7Bfill%3A%230072AC%3B%7D%09.st127%7Bfill%3A%230079B6%3B%7D%09.st128%7Bfill%3A%2300A2D9%3B%7D%09.st129%7Bfill%3A%23BFDC34%3B%7D%09.st130%7Bfill%3A%23898989%3B%7D%09.st131%7Bfill%3A%23EDF0F5%3B%7D%09.st132%7Bfill%3A%23A3A4A7%3B%7D%09.st133%7Bfill%3A%23353535%3B%7D%09.st134%7Bfill%3A%23FF8C02%3B%7D%09.st135%7Bfill%3A%2300AC8C%3B%7D%09.st136%7Bfill%3A%236EC2E9%3B%7D%09.st137%7Bfill%3A%23442359%3B%7D%09.st138%7Bfill%3A%236DC0E6%3B%7D%09.st139%7Bfill%3A%23432056%3B%7D%09.st140%7Bfill%3A%2386CAD7%3B%7D%09.st141%7Bfill%3A%23009E48%3B%7D%09.st142%7Bopacity%3A0.2%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st143%7Bfill%3A%2368217A%3B%7D%09.st144%7Bfill%3A%23E5E5E5%3B%7D%09.st145%7Bopacity%3A0.15%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st146%7Bfill%3A%233898C6%3B%7D%09.st147%7Bfill%3A%2380BA42%3B%7D%09.st148%7Bfill%3A%23B3D234%3B%7D%09.st149%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9F9F9%3B%7D%09.st150%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23008EBE%3B%7D%09.st151%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F1F1F2%3B%7D%09.st152%7Bfill%3A%23BAD80A%3B%7D%09.st153%7Bclip-path%3Aurl(%23SVGID_2_)%3B%7D%09.st154%7Bfill%3A%2300BCF2%3B%7D%09.st155%7Bfill%3A%235AB4DA%3B%7D%09.st156%7Bfill%3Anone%3Bstroke%3A%235AB4DA%3Bstroke-width%3A0.75%3Bstroke-miterlimit%3A10%3B%7D%09.st157%7Bfill%3A%233898C5%3B%7D%09.st158%7Bfill%3A%237A7B7B%3B%7D%09.st159%7Bfill%3A%23545555%3B%7D%09.st160%7Bfill%3A%23D6EAF3%3B%7D%09.st161%7Bfill%3A%23009580%3B%7D%09.st162%7Bfill%3A%23BA141A%3B%7D%09.st163%7Bfill%3A%237AC3E1%3B%7D%09.st164%7Bfill%3A%23E27226%3B%7D%09.st165%7Bfill%3A%23FF9D26%3B%7D%09.st166%7Bopacity%3A0.12%3Bfill%3A%23BA141A%3B%7D%09.st167%7Bfill%3A%233C98C5%3B%7D%09.st168%7Bfill%3A%235AB3D8%3B%7D%09.st169%7Bfill%3A%23AAD8EB%3B%7D%09.st170%7Bfill%3A%23797979%3B%7D%09.st171%7Bfill%3A%23959595%3B%7D%09.st172%7Bfill%3A%23D1D1D1%3B%7D%09.st173%7Bclip-path%3Aurl(%23SVGID_4_)%3B%7D%09.st174%7Bfill%3A%2333A2E5%3B%7D%09.st175%7Bfill%3A%2371C2EA%3B%7D%09.st176%7Bfill%3A%23005091%3B%7D%09.st177%7Bclip-path%3Aurl(%23SVGID_6_)%3B%7D%09.st178%7Bfill%3A%23ACD64D%3B%7D%3C%2Fstyle%3E%3Cg%3E%09%3Cg%3E%09%09%3Cg%3E%09%09%09%3Cg%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2226.5%2C4.5 12.5%2C15.5 1.5%2C35.5 11.5%2C35.5 %09%09%09%09%22%2F%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2227.5%2C7.5 21.5%2C22.5 32.5%2C35.5 11.5%2C40.5 46.5%2C40.5 %09%09%09%09%22%2F%3E%09%09%09%3C%2Fg%3E%09%09%3C%2Fg%3E%09%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n background-color: #0078d4;\n}\n');const se="spinnaker.azure";n("spinnaker.azure",["spinnaker.azure.pipeline.stage.destroyAsgStage","spinnaker.azure.pipeline.stage.enableAsgStage","spinnaker.azure.pipeline.stage.disableAsgStage","spinnaker.azure.pipeline.stage.bakeStage","spinnaker.azure.serverGroup.details.azure","spinnaker.azure.serverGroup.transformer","spinnaker.azure.cloneServerGroup.controller","spinnaker.azure.serverGroup.configure","spinnaker.azure.instanceType.service","spinnaker.azure.loadBalancer.transformer","spinnaker.azure.loadBalancer.details.controller","spinnaker.azure.loadBalancer.create.controller","spinnaker.azure.instance.detail.controller","spinnaker.azure.securityGroup.azure.details.controller","spinnaker.azure.securityGroup.create.controller","spinnaker.azure.securityGroup.azure.edit.controller","spinnaker.azure.securityGroup.transformer","spinnaker.azure.securityGroup.reader","spinnaker.azure.image.reader","spinnaker.azure.validation.applicationName"]).config((function(){r.registerProvider("azure",{name:"Azure",logo:{path:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAACrCAYAAACEwDK4AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI2MjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTcxPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOS0wNS0wNlQxMjowNTozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjguMzwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K8Qjg7wAAM9JJREFUeAHtnQeAFdX1/8/MvLa9L1tgF5Zl6UUUggoIggVLrCQYY42a/jPlb4rxr9EkvxhNIz9bEjUmllhRRFCxIKII0hVY2jaWLbC9vf5mft9z571lwd1lWfWXRM+FeW/ezJ07937uveeee+6ZWbIsazG2EpIgBITA554AywKWCSRC4XPfFgSAEDiCgMiEI3DIDyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh8B9DQPuPyWk0o+2WlRnyhYorW8O5++pb0irq2pIqu6y46uaAtau6tv6+L89Yf9akzF3/aeWS/AqBfycCjk8jM5ZljUa6FrZyTdPCvd0DcZJwvAhbLrZkbN158RMZXaGIsbcx4Cira3ej8ydWtoeza1u9haf8atXItkBkeER3pkYiRDpEm6FppBkaBci9zxHv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"},image:{reader:"azureImageReader"},serverGroup:{transformer:"azureServerGroupTransformer",detailsTemplateUrl:"azure/src/serverGroup/details/serverGroupDetails.html",detailsController:"azureServerGroupDetailsCtrl",cloneServerGroupTemplateUrl:"azure/src/serverGroup/configure/wizard/serverGroupWizard.html",cloneServerGroupController:"azureCloneServerGroupCtrl",commandBuilder:"azureServerGroupCommandBuilder",configurationService:"azureServerGroupConfigurationService"},instance:{instanceTypeService:"azureInstanceTypeService",detailsTemplateUrl:"azure/src/instance/details/instanceDetails.html",detailsController:"azureInstanceDetailsCtrl"},loadBalancer:{transformer:"azureLoadBalancerTransformer",detailsTemplateUrl:"azure/src/loadBalancer/details/loadBalancerDetail.html",detailsController:"azureLoadBalancerDetailsCtrl",createLoadBalancerTemplateUrl:"azure/src/loadBalancer/configure/createLoadBalancer.html",createLoadBalancerController:"azureCreateLoadBalancerCtrl",CreateLoadBalancerModal:te},securityGroup:{transformer:"azureSecurityGroupTransformer",reader:"azureSecurityGroupReader",detailsTemplateUrl:"azure/src/securityGroup/details/securityGroupDetail.html",detailsController:"azureSecurityGroupDetailsCtrl",createSecurityGroupTemplateUrl:"azure/src/securityGroup/configure/createSecurityGroup.html",createSecurityGroupController:"azureCreateSecurityGroupCtrl"}})})),_.registerProvider("azure",["redblack"]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/details/serverGroupDetails.html",'<div class="details-panel" ng-class="{ disabled: serverGroup.isDisabled }">\n <div class="header" ng-if="state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div class="header" ng-if="!state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <span class="glyphicon glyphicon-th"></span>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{serverGroup.name}}</h3>\n </div>\n <div class="actions" ng-class="{ insights: serverGroup.insightActions.length > 0 }">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Server Group Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li><a href ng-if="!serverGroup.isDisabled" ng-click="ctrl.rollbackServerGroup()">Rollback</a></li>\n <div ng-if="false">\n <li><a href ng-click="ctrl.resizeServerGroup()">Resize</a></li>\n </div>\n <li><a href ng-click="ctrl.disableServerGroup()">Disable</a></li>\n <li><a href ng-click="ctrl.enableServerGroup()">Enable</a></li>\n <li><a href ng-click="ctrl.destroyServerGroup()">Destroy</a></li>\n <li><a href ng-click="ctrl.cloneServerGroup(serverGroup)">Clone</a></li>\n </ul>\n </div>\n <div class="dropdown" ng-if="serverGroup.insightActions.length > 0" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-default dropdown-toggle" uib-dropdown-toggle>\n Insight <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li ng-repeat="action in serverGroup.insightActions">\n <a target="_blank" href="{{action.url}}">{{action.label}}</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading">\n <h4 class="text-center" ng-if="serverGroup.isDisabled">[SERVER GROUP IS DISABLED]</h4>\n\n <server-group-running-tasks-details\n server-group="serverGroup"\n application="ctrl.application"\n ></server-group-running-tasks-details>\n\n <collapsible-section heading="Server Group Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Created</dt>\n <dd>{{serverGroup.createdTime | timestamp}}</dd>\n <dt>Region</dt>\n <dd>\n <account-tag account="serverGroup.account" provider="serverGroup.type" pad="right"></account-tag>\n {{serverGroup.region}}\n </dd>\n <dt>Image</dt>\n <dd>{{serverGroup.image.imageName}}</dd>\n <dt>SKU</dt>\n <dd>{{serverGroup.sku.name}}</dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="Size" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Current</dt>\n <dd>{{serverGroup.instances.length}}</dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="Health" expanded="true">\n <dl class="dl-horizontal dl-narrow" ng-if="serverGroup">\n <dt>Instances</dt>\n <dd>\n <health-counts container="serverGroup.instanceCounts" class="pull-left"></health-counts>\n </dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="{{firewallsLabel}}">\n <dl class="dl-horizontal dl-narrow">\n <dt>Name</dt>\n <dd>{{serverGroup.securityGroupName}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/serverGroupWizard.html",'<div>\n <div ng-if="state.requiresTemplateSelection">\n <ng-include src="pages.templateSelection"></ng-include>\n </div>\n <div ng-if="!state.loaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div>\n <form name="serverGroupWizardForm" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard\n ng-show="state.loaded && !state.requiresTemplateSelection"\n heading="{{title}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="basic-settings" label="Basic Settings" hide-subheading="true">\n <ng-include src="pages.basicSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="image-settings" label="Image">\n <ng-include src="pages.imageSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="load-balancers" label="Load Balancers" mark-complete-on-view="false">\n <ng-include src="pages.loadBalancers"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="network-settings" label="Network Settings" mark-complete-on-view="false">\n <ng-include src="pages.networkSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="health-settings" label="Health" mark-complete-on-view="false">\n <ng-include src="pages.healthSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="security-groups" label="{{firewallsLabel}}" mark-complete-on-view="false" done="true">\n <ng-include src="pages.securityGroups"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="instance-type" label="Instance Type" mark-complete-on-view="false" done="false">\n <ng-include src="pages.instanceType"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="zones" label="Zones" mark-complete-on-view="false" done="false">\n <ng-include src="pages.zones"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="tags" label="Tags" mark-complete-on-view="false" done="true">\n <ng-include src="pages.tags"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="advanced-settings" label="Advanced Settings" mark-complete-on-view="false" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer" ng-if="state.loaded">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default btn-cancel" ng-click="ctrl.cancel()">\n Cancel\n </button>\n <submit-button\n is-disabled="taskMonitor.submitting || !ctrl.isValid()"\n label="command.viewState.submitButtonLabel"\n submitting="taskMonitor.submitting"\n on-click="serverGroupWizardForm.$valid && ctrl.submit()"\n is-new="true"\n ></submit-button>\n </div>\n </form>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/instance/details/instanceDetails.html",'<div class="details-panel">\n <div class="header">\n <instance-details-header\n health-state="instance.healthState"\n instance-id="instance ? instance.instanceId : instanceIdNotFound"\n loading="state.loading"\n standalone="state.standalone"\n ></instance-details-header>\n </div>\n <div class="content" ng-if="!state.loading && instance">\n <collapsible-section heading="Instance Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Launched</dt>\n <dd ng-if="instance.launchTime">{{instance.launchTime | timestamp}}</dd>\n <dd ng-if="!instance.launchTime">(Unknown)</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="instance.account" provider="instance.provider" pad="right"></account-tag>\n {{instance.region || \'(Unknown)\'}}\n </dd>\n <dt>Type</dt>\n <dd>{{instance.instanceType || \'(Unknown)\'}}</dd>\n <dt ng-if="instance.serverGroup">Server Group</dt>\n <dd ng-if="instance.serverGroup">\n <a\n ui-sref="^.serverGroup({region: instance.region,\n accountId: instance.account,\n serverGroup: instance.serverGroup,\n provider: instance.provider})"\n >{{instance.serverGroup}}</a\n >\n </dd>\n </dl>\n </collapsible-section>\n </div>\n <div class="content" ng-if="!state.loading && !instance">\n <div class="content-section">\n <div class="content-body text-center">\n <h3>Instance not found.</h3>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/details/loadBalancerDetail.html",'<div class="details-panel">\n <div ng-if="state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div ng-if="!state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <i class="fa icon-sitemap"></i>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{loadBalancer.name}}</h3>\n </div>\n <div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Load Balancer Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li><a href ng-click="ctrl.editLoadBalancer()">Edit Load Balancer</a></li>\n <li ng-if="!loadBalancer.serverGroups.length">\n <a href ng-click="ctrl.deleteLoadBalancer()">Delete Load Balancer</a>\n </li>\n <li\n ng-if="loadBalancer.serverGroups.length"\n class="disabled"\n tooltip="You must detach all server groups before you can delete this load balancer."\n >\n <a href>Delete Load Balancer</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!state.loading" class="content">\n <collapsible-section heading="Load Balancer Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Type</dt>\n <dd>{{loadBalancer.loadBalancerType}}</dd>\n <dt>Created</dt>\n <dd>{{loadBalancer.elb.createdTime | timestamp}}</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="loadBalancer.account" pad="right" provider="loadBalancer.type"></account-tag>\n {{loadBalancer.region}}\n </dd>\n <dt ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">VNet</dt>\n <dd ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">{{loadBalancer.elb.vnet}}</dd>\n <dt ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">Subnet</dt>\n <dd ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">{{loadBalancer.elb.subnet}}</dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="loadBalancer.serverGroups">Server Groups</dt>\n <dd ng-if="loadBalancer.serverGroups">\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in loadBalancer.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: \'azure\'})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="loadBalancer.elb.dnsName">DNS Name:</dt>\n <dd>\n <a target="_blank" href="//{{loadBalancer.elb.dnsName}}">{{loadBalancer.elb.dnsName}}</a>\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="loadBalancer.elb.dnsName"\n tool-tip="\'Copy DNS Name to clipboard\'"\n >\n </copy-to-clipboard>\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <health-counts class="pull-left" container="loadBalancer.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Listeners">\n <dl>\n <dt>Load Balancer → Instance</dt>\n <dd ng-repeat="loadBalancingRule in loadBalancer.elb.loadBalancingRules">\n {{loadBalancingRule.protocol}}:{{loadBalancingRule.externalPort}} → {{loadBalancingRule.backendPort}}\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="{{firewallsLabel}}">\n <ul>\n <li ng-repeat="securityGroup in securityGroups | orderBy:\'name\'">\n <a\n ui-sref="^.firewallDetails({name:securityGroup.name, accountId: loadBalancer.account, region: loadBalancer.region, vpcId: loadBalancer.vpcId, provider: loadBalancer.provider})"\n >\n {{securityGroup.name}} ({{securityGroup.id}})\n </a>\n </li>\n </ul>\n </collapsible-section>\n <collapsible-section heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>{{loadBalancer.elb.probes[0].probeProtocol}}</dd>\n <dt>Interval</dt>\n <dd>{{loadBalancer.elb.probes[0].probeInterval}} seconds</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{loadBalancer.elb.probes[0].unhealthyThreshold}}</dd>\n <dt>Timeout</dt>\n <dd>{{loadBalancer.elb.probes[0].timeout}} seconds</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/createLoadBalancer.html",'<form name="form" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard heading="Create New {{loadBalancerType}}" task-monitor="taskMonitor" dismiss="$dismiss()">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Listeners" label="Listeners" done="true">\n <ng-include src="pages.listeners"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Health Check" label="Health Check" done="true" hide-subheading="true">\n <ng-include src="pages.healthCheck"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Advanced Settings" label="Advanced Settings" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!state.accountsLoaded || taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.submit()"\n is-new="isNew"\n ></submit-button>\n </div>\n</form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/details/securityGroupDetail.html",'<div class="details-panel">\n <div class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div ng-if="state.loading" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div class="header-text horizontal middle" ng-if="!state.loading">\n <span class="glyphicon glyphicon-transfer"></span>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>\n {{securityGroup.name || \'(not found)\'}}\n </h3>\n </div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" ng-disabled="disabled" uib-dropdown-toggle>\n <firewall-label label="Firewall"></firewall-label> Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li>\n <a href ng-click="ctrl.deleteSecurityGroup()">Delete <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <li><a href ng-click="ctrl.editInboundRules()">Edit Inbound Rules</a></li>\n <li>\n <a href ng-click="ctrl.cloneSecurityGroup()">Clone <firewall-label label="Firewall"></firewall-label></a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading">\n <collapsible-section heading="{{firewallLabel}} Details" expanded="true">\n <dl class="dl-horizontal dl-medium">\n <dt>ID</dt>\n <dd>{{securityGroup.id}}</dd>\n <dt>Account</dt>\n <dd><account-tag account="securityGroup.accountName"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{securityGroup.region}}</dd>\n <dt>Description:</dt>\n <dd>{{securityGroup.description}}</dd>\n </dl>\n </collapsible-section>\n <collapsible-section\n heading="Security Rules ({{securityGroup.securityRules.length || 0}})"\n expanded="{{!!(securityGroup.securityRules && securityGroup.securityRules.length)}}"\n >\n <div ng-if="!securityGroup.securityRules.length">None</div>\n <dl\n ng-class="insightCtrl.vm.filtersExpanded ? \'\' : \'dl-horizontal dl-medium\'"\n ng-repeat="rule in securityGroup.securityRules | orderBy: \'rule.priority\'"\n >\n <dt>Name</dt>\n <dd>{{rule.name}}</dd>\n <dt>Priority</dt>\n <dd>{{rule.priority}}</dd>\n <dt>Direction</dt>\n <dd>{{rule.direction}}</dd>\n <dt>Access</dt>\n <dd>{{rule.access}}</dd>\n <dt>Protocol</dt>\n <dd>{{rule.protocol}}</dd>\n <dt>Src Addr Prefix</dt>\n <dd>{{rule.sourceAddressPrefixModel}}</dd>\n <dt>Src Port Range</dt>\n <dd>{{rule.sourcePortRange}}</dd>\n <dt>Dest Addr Prefix</dt>\n <dd>{{rule.destinationAddressPrefix}}</dd>\n <dt>Dest Port Range</dt>\n <dd>{{rule.destinationPortRangeModel}}</dd>\n <hr />\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroup.html",'<form name="form" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard heading="Create New {{firewallLabel}}" task-monitor="taskMonitor" dismiss="$dismiss()">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="state.submitting"\n submitting="state.submitting"\n on-click="form.$valid && ctrl.upsert()"\n is-new="isNew"\n >\n </submit-button>\n </div>\n</form>\n')}]);export{se as AZURE_MODULE};
|
|
1
|
+
import*as e from"angular";import{module as n}from"angular";import{HelpContentsRegistry as t,REST as a,CloudProviderRegistry as r,ConfirmationModalService as i,RecentHistoryService as l,InstanceReader as s,InstanceWriter as o,ModalInjector as c,ReactModal as d,ModalClose as u,noop as p,SETTINGS as m,TaskMonitor as g,AccountService as f,NetworkReader as v,LoadBalancerWriter as h,NameUtils as B,SECURITY_GROUP_READER as A,LOAD_BALANCER_READ_SERVICE as y,FirewallLabels as b,Registry as S,BakeExecutionLabel as D,AuthenticationService as z,PipelineTemplates as w,BakeryReader as G,StageConstants as k,TaskExecutor as C,InfrastructureCaches as F,CACHE_INITIALIZER_SERVICE as I,IMAGE_READER as E,ModalWizard as T,SERVER_GROUP_WRITER as x,UserVerification as N,ReactInjector as P,TaskMonitorWrapper as L,TaskReason as R,ServerGroupReader as M,ServerGroupWarningMessageService as U,ApplicationNameValidator as V,DeploymentStrategyRegistry as _}from"@spinnaker/core";import H from"lodash";import O from"@uirouter/angularjs";import Q from"angular-ui-bootstrap";import X from"react";import{Modal as q,Button as j}from"react-bootstrap";import W from"react-select";var Y,Z;(Z=Y||(Y={}))[Z.TAG_NUMBER_EXCEED=0]="TAG_NUMBER_EXCEED",Z[Z.TAG_KEY_LENGTH_EXCEED=1]="TAG_KEY_LENGTH_EXCEED",Z[Z.TAG_VALUE_LENGTH_EXCEED=2]="TAG_VALUE_LENGTH_EXCEED",Z[Z.TAG_KEY_INVALID_CHARACTER=3]="TAG_KEY_INVALID_CHARACTER",Z[Z.TAG_VALUE_INVALID_CHARACTER=4]="TAG_VALUE_INVALID_CHARACTER",Z[Z.TAG_OBJECT_UNDEFINED=5]="TAG_OBJECT_UNDEFINED";const $=[{type:"Azure Load Balancer",description:""},{type:"Azure Application Gateway",description:""}],J=class{static checkTags(e){if(!e)return{isValid:!1,error:5,errorMessage:"instanceTags is not defined"};const n=Object.keys(e).length;if(!(n>=0&&n<=J.TAG_LIMITATION))return{isValid:!1,error:0,errorMessage:`Number of tags exceeds the limit: ${J.TAG_LIMITATION}`};for(const[n,t]of Object.entries(e)){if(n.length>J.TAG_KEY_LENGTH_LIMITATION)return{isValid:!1,error:1,errorMessage:`Length of Tag key: ${n} exceeds the limit: ${J.TAG_KEY_LENGTH_LIMITATION}`};if(t.length>J.TAG_VALUE_LENGTH_LIMITATION)return{isValid:!1,error:2,errorMessage:`Length of Tag value: ${t} exceeds the limit: ${J.TAG_VALUE_LENGTH_LIMITATION}`};if(J.TAG_INVALID_CHAR_REG_EXR.test(n))return{isValid:!1,error:3,errorMessage:`Invalid characters in Tag key: ${n}`};if(J.TAG_INVALID_CHAR_REG_EXR.test(t))return{isValid:!1,error:4,errorMessage:`Invalid characters in Tag value: ${t}`}}return{isValid:!0,error:null}}static getLoadBalancerType(e){return e=e.toLowerCase().split("_").join(" "),$.find((n=>n.type.toLowerCase()===e))||null}};let K=J;K.TAG_LIMITATION=8,K.TAG_KEY_LENGTH_LIMITATION=512,K.TAG_VALUE_LENGTH_LIMITATION=256,K.TAG_INVALID_CHAR_REG_EXR=/[<>%&\\?/]/;const ee={"azure.securityGroup.ingress.description":"Friendly description of the rule you want to enable (limit 80 chars.)","azure.securityGroup.ingress.priority":"Rules are processed in priority order; the lower the number, the higher the priority. We recommend leaving gaps between rules - 100, 200, 300, etc. - so that it's easier to add new rules without having to edit existing rules. There are several default rules that can be overridden with priority (65000, 65001 and 65500). For more information visit http://portal.azure.com.","azure.securityGroup.ingress.source":"The source filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the incoming traffic from a specific source IP address range (CIDR format) that will be allowed or denied by this rule.","azure.securityGroup.ingress.sourcePortRange":"The source port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which ports incoming traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.","azure.securityGroup.ingress.destination":"The destination filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the outgoing traffic from a specific destination IP address range (CIDR format) that will be allowed or denied by this rule.","azure.securityGroup.ingress.destinationPortRange":"The destination port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which destination ports traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.","azure.securityGroup.ingress.direction":"Specifies whether the rule is for inbound or outbound traffic.","azure.securityGroup.ingress.actions":"To adjust the priority of a rule, move it up or down in the list of rules. Rules at the top of the list have the highest priority.","azure.securityGroup.ingress.destPortRanges":"Provide a single port, such as 80; a port range, such as 1024-65535; or a comma-separated list of single ports and/or port ranges, such as 80,1024-65535. Provide an asterisk (*) to allow traffic on any port.","azure.securityGroup.ingress.sourceIPCIDRRanges":"Provide an address range using CIDR notation, such as 192.168.99.0/24; an IP address, such as 192.168.99.0; or a comma-separated list of address ranges or IP addresses, such as 10.0.0.0/24,44.66.0.0/24","azure.serverGroup.imageName":"(Required) <b>Image</b> is the deployable Azure Machine Image.","azure.serverGroup.stack":"(Required) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","azure.serverGroup.detail":"(Required) <b>Detail</b> is a naming component to help distinguish specifics of the server group.","azure.serverGroup.scriptLocation":"The location of custom scripts separated by comma or semicolon to be downloaded on to each instance. A single script should be like: fileUri. Multiple scripts should be like fileUri1,fileUri2 or fileUri1;fileUri2","azure.serverGroup.commandToExecute":"Command(s) to execute custom scripts provided during provisioning of an instance.","azure.serverGroup.customData":"Script or metadata to be injected into each instances.","azure.serverGroup.customTags":`Custom tags on Virtual Machine Scale Set. Allow ${K.TAG_LIMITATION} tags at most.`,"azure.serverGroup.enableInboundNAT":"An Azure load balancer of the basic sku will be created with adding inbound NAT port-forwarding rules to facilitate loggin on VM instances. There is no charge for creating an Azure load balancer of the basic sku. This option is disabled if Availability Zones are set which require Standard Azure Load Balancer and an extra Network Security Group with correct inbound and outbound rules configured.","azure.serverGroup.lun":"Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM.","azure.serverGroup.diskSizeGB":"Specifies the size of an empty data disk in gigabytes. This value cannot be larger than 1023 GB","azure.serverGroup.managedDisk.storageAccountType":"You can choose between Azure managed disks types to support your workload or scenario.","azure.serverGroup.caching":"Changing the default host caching policy can adversely impact the performance of your application. You should run performance tests to measure its impact. To improve the total IOPS/throughput, we recommend striping across multiple disks and using premium (SSD) disks.","azure.serverGroup.userAssignedIdentities":"Allows your server to access Azure resources. Learn more here: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview","azure.loadBalancer.dnsName":'If there is no custom DNS label specified, a default DNS name will be created. The default value will be "GeneratedText.cloudapp.net" for Azure Application Gateway or "GeneratedText.[region].cloudapp.azure.com" for Azure Load Balancer.',"azure.loadBalancer.probes.probeInterval":"Probe interval in seconds. This value is the time interval between two consecutive probes.","azure.loadBalancer.probes.timeout":"Probe time-out in seconds. If a valid response is not received within this time-out period, the probe is marked as failed. Note that the time-out value should not be more than the Interval value.","azure.loadBalancer.probes.unhealthyThreshold":"Probe retry count. The back-end server is marked down after the consecutive probe failure count reaches the unhealthy threshold.","azure.loadBalancer.loadBalancingRules.idleTimeout":"Keep a TCP or HTTP connection open without relying on clients to send keep-alive messages.","azure.loadBalancer.loadBalancingRules.sessionPersistence":'Session persistence specifies that traffic from a client should be handled by the same virtual machine in the backend pool for the duration of a session. "None" specifies that successive requests from the same client may be handled by any virtual machine. "Client IP" specifies that successive requests from the same client IP address will be handled by the same virtual machine. "Client IP and protocol" specifies that successive requests from the same client IP address and protocol combination will be handled by the same virtual machine.'};Object.keys(ee).forEach((e=>t.register(e,ee[e])));n("spinnaker.azure.image.reader",[]).factory("azureImageReader",(function(){return{findImages:function(e){return a("/images/find").query(e).get().then((function(e){return e}),(function(){return[]}))},getImage:function(e,n,t){return a("/images").path(t,n,e).query({provider:"azure"}).get().then((function(e){return e&&e.length?e[0]:null}),(function(){return null}))}}}));n("spinnaker.azure.instanceType.service",[]).factory("azureInstanceTypeService",["$q",function(e){const n=[{type:"general",label:"General Purpose",description:"Balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers.",families:[{type:"B-series",description:"The B-series burstable VMs are ideal for workloads that do not need the full performance of the CPU continuously, like web servers, small databases and development and test environments.",instanceTypes:[{name:"Standard_B1ms",label:"Standard_B1ms",cpu:1,memory:2,storage:{type:"SSD",count:2,size:4}},{name:"Standard_B1s",label:"Standard_B1s",cpu:1,memory:1,storage:{type:"SSD",count:2,size:2}},{name:"Standard_B2ms",label:"Standard_B2ms",cpu:2,memory:8,storage:{type:"SSD",count:4,size:16}},{name:"Standard_B2s",label:"Standard_B2s",cpu:2,memory:4,storage:{type:"SSD",count:4,size:8}},{name:"Standard_B4ms",label:"Standard_B4ms",cpu:4,memory:16,storage:{type:"SSD",count:8,size:32}},{name:"Standard_B8ms",label:"Standard_B8ms",cpu:8,memory:32,storage:{type:"SSD",count:16,size:64}},{name:"Standard_B1ls",label:"Standard_B1ls",cpu:1,memory:.5,storage:{type:"SSD",count:2,size:1}}]},{type:"Dsv3-series",description:"The Dsv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.",instanceTypes:[{name:"Standard_D2s_v3",label:"Standard_D2s_v3",cpu:2,memory:8,storage:{type:"SSD",count:4,size:16}},{name:"Standard_D4s_v3",label:"Standard_D4s_v3",cpu:4,memory:16,storage:{type:"SSD",count:8,size:32}},{name:"Standard_D8s_v3",label:"Standard_D8s_v3",cpu:8,memory:32,storage:{type:"SSD",count:16,size:64}},{name:"Standard_D16s_v3",label:"Standard_D16s_v3",cpu:16,memory:64,storage:{type:"SSD",count:32,size:128}},{name:"Standard_D32s_v3",label:"Standard_D32s_v3",cpu:32,memory:128,storage:{type:"SSD",count:32,size:256}},{name:"Standard_D64s_v3",label:"Standard_D64s_v3",cpu:64,memory:256,storage:{type:"SSD",count:32,size:512}}]},{type:"Dv3-series",description:"The Dv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.",instanceTypes:[{name:"Standard_D2_v3",label:"Standard_D2_v3",cpu:2,memory:8,storage:{type:"SSD",count:4,size:50}},{name:"Standard_D4_v3",label:"Standard_D4_v3",cpu:4,memory:16,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D8_v3",label:"Standard_D8_v3",cpu:8,memory:32,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D16_v3",label:"Standard_D16_v3",cpu:16,memory:64,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D32_v3",label:"Standard_D32_v3",cpu:32,memory:128,storage:{type:"SSD",count:32,size:800}},{name:"Standard_D64_v3",label:"Standard_D64_v3",cpu:64,memory:256,storage:{type:"SSD",count:32,size:1600}}]},{type:"DSv2-series",description:"",instanceTypes:[{name:"Standard_DS1_v2",label:"Standard_DS1_v2",cpu:1,memory:3.5,storage:{type:"SSD",count:4,size:7}},{name:"Standard_DS2_v2",label:"Standard_DS2_v2",cpu:2,memory:7,storage:{type:"SSD",count:8,size:14}},{name:"Standard_DS3_v2",label:"Standard_DS3_v2",cpu:4,memory:14,storage:{type:"SSD",count:16,size:28}},{name:"Standard_DS4_v2",label:"Standard_DS4_v2",cpu:8,memory:28,storage:{type:"SSD",count:32,size:56}},{name:"Standard_DS5_v2",label:"Standard_DS5_v2",cpu:16,memory:56,storage:{type:"SSD",count:64,size:112}},{name:"Standard_DS11_v2",label:"Standard_DS11_v2",cpu:2,memory:14,storage:{type:"SSD",count:8,size:28}},{name:"Standard_DS12_v2",label:"Standard_DS12_v2",cpu:4,memory:28,storage:{type:"SSD",count:16,size:56}},{name:"Standard_DS13_v2",label:"Standard_DS13_v2",cpu:8,memory:56,storage:{type:"SSD",count:32,size:112}},{name:"Standard_DS14_v2",label:"Standard_DS14_v2",cpu:16,memory:112,storage:{type:"SSD",count:64,size:224}},{name:"Standard_DS15_v2",label:"Standard_DS15_v2",cpu:20,memory:140,storage:{type:"SSD",count:64,size:280}}]},{type:"Dv2-series",description:"",instanceTypes:[{name:"Standard_D1_v2",label:"Standard_D1_v2",cpu:1,memory:3.5,storage:{type:"SSD",count:4,size:50}},{name:"Standard_D2_v2",label:"Standard_D2_v2",cpu:2,memory:7,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D3_v2",label:"Standard_D3_v2",cpu:4,memory:14,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D4_v2",label:"Standard_D4_v2",cpu:8,memory:28,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D5_v2",label:"Standard_D5_v2",cpu:16,memory:56,storage:{type:"SSD",count:64,size:800}},{name:"Standard_D11_v2",label:"Standard_D11_v2",cpu:2,memory:14,storage:{type:"SSD",count:8,size:100}},{name:"Standard_D12_v2",label:"Standard_D12_v2",cpu:4,memory:28,storage:{type:"SSD",count:16,size:200}},{name:"Standard_D13_v2",label:"Standard_D13_v2",cpu:8,memory:56,storage:{type:"SSD",count:32,size:400}},{name:"Standard_D14_v2",label:"Standard_D14_v2",cpu:16,memory:112,storage:{type:"SSD",count:64,size:800}},{name:"Standard_D15_v2",label:"Standard_D15_v2",cpu:20,memory:140,storage:{type:"SSD",count:64,size:280}}]},{type:"Av2-series",description:"",instanceTypes:[{name:"Standard_A1_v2",label:"Standard_A1_v2",cpu:1,memory:2,storage:{type:"SSD",count:2,size:10}},{name:"Standard_A2m_v2",label:"Standard_A2m_v2",cpu:2,memory:16,storage:{type:"SSD",count:4,size:20}},{name:"Standard_A2_v2",label:"Standard_A2_v2",cpu:2,memory:4,storage:{type:"SSD",count:4,size:20}},{name:"Standard_A4m_v2",label:"Standard_A4m_v2",cpu:4,memory:32,storage:{type:"SSD",count:8,size:40}},{name:"Standard_A4_v2",label:"Standard_A4_v2",cpu:4,memory:8,storage:{type:"SSD",count:8,size:40}},{name:"Standard_A8m_v2",label:"Standard_A8m_v2",cpu:8,memory:64,storage:{type:"SSD",count:16,size:80}},{name:"Standard_A8_v2",label:"Standard_A8_v2",cpu:8,memory:16,storage:{type:"SSD",count:16,size:80}}]},{type:"DC-series",description:"",instanceTypes:[{name:"Standard_DC2s",label:"Standard_DC2s",cpu:2,memory:8,storage:{type:"SSD",count:2,size:100}},{name:"Standard_DC4s",label:"Standard_DC4s",cpu:4,memory:16,storage:{type:"SSD",count:4,size:200}}]}],icon:"hdd"},{type:"compute",label:"Compute Optimized",description:"High CPU-to-memory ratio. Good for medium traffic web servers, network appliances, batch processes, and application servers.",families:[{type:"Fsv2-series",description:"",instanceTypes:[{name:"Standard_F2s_v2",label:"Standard_F2s_v2",cpu:2,memory:4,storage:{type:"SSD",count:4,size:16}},{name:"Standard_F4s_v2",label:"Standard_F4s_v2",cpu:4,memory:8,storage:{type:"SSD",count:8,size:32}},{name:"Standard_F8s_v2",label:"Standard_F8s_v2",cpu:8,memory:16,storage:{type:"SSD",count:16,size:64}},{name:"Standard_F16s_v2",label:"Standard_F16s_v2",cpu:16,memory:32,storage:{type:"SSD",count:32,size:128}},{name:"Standard_F32s_v2",label:"Standard_F32s_v2",cpu:32,memory:64,storage:{type:"SSD",count:32,size:256}},{name:"Standard_F64s_v2",label:"Standard_F64s_v2",cpu:64,memory:128,storage:{type:"SSD",count:32,size:512}},{name:"Standard_F72s_v2",label:"Standard_F72s_v2",cpu:72,memory:144,storage:{type:"SSD",count:32,size:576}}]},{type:"Fs-series",description:"",instanceTypes:[{name:"Standard_F1s",label:"Standard_F1s",cpu:1,memory:2,storage:{type:"SSD",count:4,size:4}},{name:"Standard_F2s",label:"Standard_F2s",cpu:2,memory:4,storage:{type:"SSD",count:8,size:8}},{name:"Standard_F4s",label:"Standard_F4s",cpu:4,memory:8,storage:{type:"SSD",count:16,size:16}},{name:"Standard_F8s",label:"Standard_F8s",cpu:8,memory:16,storage:{type:"SSD",count:32,size:32}},{name:"Standard_F16s",label:"Standard_F16s",cpu:16,memory:32,storage:{type:"SSD",count:64,size:64}}]},{type:"F-series",description:"",instanceTypes:[{name:"Standard_F1",label:"Standard_F1",cpu:1,memory:2,storage:{type:"SSD",count:4,size:16}},{name:"Standard_F2",label:"Standard_F2",cpu:2,memory:4,storage:{type:"SSD",count:8,size:32}},{name:"Standard_F4",label:"Standard_F4",cpu:4,memory:8,storage:{type:"SSD",count:16,size:64}},{name:"Standard_F8",label:"Standard_F8",cpu:8,memory:16,storage:{type:"SSD",count:32,size:128}},{name:"Standard_F16",label:"Standard_F16",cpu:16,memory:32,storage:{type:"SSD",count:64,size:256}}]}],icon:"hdd"},{type:"custom",label:"Custom Type",description:"Select the instance type below.",families:[],icon:"asterisk"}];function t(e){return e&&e.storage?e.storage.count*e.storage.size:0}function a(){return n.map((function(e){for(const n of e.families)for(const e of n.instanceTypes)null==e.costFactor&&(e.costFactor=0);e.stats=function(e){const n={cpu:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},memory:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},storage:{min:Number.MAX_VALUE,max:-Number.MAX_VALUE},families:[]};return e.families&&e.families.length&&e.families.forEach((function(e){n.families.push(e.type);const a=H.minBy(e.instanceTypes,"cpu").cpu||Number.MAX_VALUE,r=H.maxBy(e.instanceTypes,"cpu").cpu||-Number.MAX_VALUE,i=H.minBy(e.instanceTypes,"memory").memory||Number.MAX_VALUE,l=H.maxBy(e.instanceTypes,"memory").memory||-Number.MAX_VALUE,s=t(H.minBy(e.instanceTypes,t))||Number.MAX_VALUE,o=t(H.maxBy(e.instanceTypes,t))||-Number.MAX_VALUE;n.cpu.min=Math.min(n.cpu.min,a),n.cpu.max=Math.max(n.cpu.max,r),n.memory.min=Math.min(n.memory.min,i),n.memory.max=Math.max(n.memory.max,l),n.storage.min=Math.min(n.storage.min,s),n.storage.max=Math.max(n.storage.max,o)})),n}(e)})),e.when(n)}return{getCategories:a,getAvailableTypesForRegions:function(e,n){const[t]=n;return e[t]},getAllTypesByRegion:function(){return a()}}}]);n("spinnaker.azure.instance.detail.controller",[O,Q]).controller("azureInstanceDetailsCtrl",["$scope","$state","$uibModal","instance","app","$q",function(e,n,t,a,c,d){function u(){const t={};let r,i,o,u,p;return c.serverGroups?(c.serverGroups.data.some((function(e){return e.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=e.loadBalancers,o=e.account,u=e.region,p=e.vpcId,t.serverGroup=e.name,t.vpcId=e.vpcId,!0}))})),r||(c.loadBalancers.data.some((function(e){return e.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=[e.name],o=e.account,u=e.region,p=e.vpcId,!0}))})),r||c.loadBalancers.data.some((function(e){return e.serverGroups.some((function(n){return!!n.isDisabled&&n.instances.some((function(n){if(n.id===a.instanceId)return r=n,i=[e.name],o=e.account,u=e.region,p=e.vpcId,!0}))}))})))):(r={},i=[],o=a.account,u=a.region),r&&o&&u?(t.account=o,t.region=u,l.addExtraDataToLatest("instances",t),s.getInstanceDetails(o,u,a.instanceId).then((function(n){e.state.loading=!1,function(n,t){c.isStandalone&&(n.health=t.health),n.health=n.health||[];const a=n.health.filter((function(e){return"Azure"!==e.type||"Unknown"!==e.state}));t.health&&a.forEach((function(e){const n=t.health.filter((function(n){return n.type===e.type}));n.length&&H.defaults(e,n[0])})),e.healthMetrics=a}(r,n),e.instance=H.defaults(n,r),e.instance.account=o,e.instance.region=u,e.instance.vpcId=p,e.instance.loadBalancers=i;const t=H.find(e.healthMetrics,(function(e){return"Discovery"===e.type}));if(t&&t.vipAddress){const n=t.vipAddress;e.instance.vipAddress=n.includes(",")?n.split(","):[n]}e.baseIpAddress=n.publicDnsName||n.privateIpAddress}),(function(){e.state.loading=!1,n.go("^")}))):(r||(e.instanceIdNotFound=a.instanceId,e.state.loading=!1),d.when(null))}e.detailsTemplateUrl=r.getValue("azure","instance.detailsTemplateUrl"),e.state={loading:!0,standalone:c.isStandalone},this.canDeregisterFromLoadBalancer=function(){return e.instance.health.some((function(e){return"LoadBalancer"===e.type}))},this.canRegisterWithLoadBalancer=function(){const n=e.instance;if(!n.loadBalancers||!n.loadBalancers.length)return!1;const t=n.health.some((function(e){return"LoadBalancer"===e.type&&"OutOfService"===e.state})),a=n.health.some((function(e){return"LoadBalancer"===e.type}));return t||!a},this.canRegisterWithDiscovery=function(){const n=e.instance.health.filter((function(e){return"Discovery"===e.type}));return!!n.length&&"OutOfService"===n[0].state},this.terminateInstance=function(){const t=e.instance,a={application:c,title:"Terminating "+t.instanceId,onTaskComplete:function(){n.includes("**.instanceDetails",{instanceId:t.instanceId})&&n.go("^")}};i.confirm({header:"Really terminate "+t.instanceId+"?",buttonText:"Terminate "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return o.terminateInstance(t,c)}})},this.terminateInstanceAndShrinkServerGroup=function(){const t=e.instance,a={application:c,title:"Terminating "+t.instanceId+" and shrinking server group",onTaskComplete:function(){n.includes("**.instanceDetails",{instanceId:t.instanceId})&&n.go("^")}};i.confirm({header:"Really terminate "+t.instanceId+" and shrink "+t.serverGroup+"?",buttonText:"Terminate "+t.instanceId+" and shrink "+t.serverGroup,account:t.account,taskMonitorConfig:a,submitMethod:function(){return o.terminateInstanceAndShrinkServerGroup(t,c)}})},this.rebootInstance=function(){const n=e.instance,t={application:c,title:"Rebooting "+n.instanceId};i.confirm({header:"Really reboot "+n.instanceId+"?",buttonText:"Reboot "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.rebootInstance(n,c)}})},this.registerInstanceWithLoadBalancer=function(){const n=e.instance,t=n.loadBalancers.join(" and "),a={application:c,title:"Registering "+n.instanceId+" with "+t};i.confirm({header:"Really register "+n.instanceId+" with "+t+"?",buttonText:"Register "+n.instanceId,account:n.account,taskMonitorConfig:a,submitMethod:function(){return o.registerInstanceWithLoadBalancer(n,c)}})},this.deregisterInstanceFromLoadBalancer=function(){const n=e.instance,t=n.loadBalancers.join(" and "),a={application:c,title:"Deregistering "+n.instanceId+" from "+t};i.confirm({header:"Really deregister "+n.instanceId+" from "+t+"?",buttonText:"Deregister "+n.instanceId,account:n.account,taskMonitorConfig:a,submitMethod:function(){return o.deregisterInstanceFromLoadBalancer(n,c)}})},this.enableInstanceInDiscovery=function(){const n=e.instance,t={application:c,title:"Enabling "+n.instanceId+" in discovery"};i.confirm({header:"Really enable "+n.instanceId+" in discovery?",buttonText:"Enable "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.enableInstanceInDiscovery(n,c)}})},this.disableInstanceInDiscovery=function(){const n=e.instance,t={application:c,title:"Disabling "+n.instanceId+" in discovery"};i.confirm({header:"Really disable "+n.instanceId+" in discovery?",buttonText:"Disable "+n.instanceId,account:n.account,taskMonitorConfig:t,submitMethod:function(){return o.disableInstanceInDiscovery(n,c)}})},this.hasHealthState=function(n,t){return e.instance.health.some((function(e){return e.type===n&&e.state===t}))};(c.isStandalone?u():d.all([c.serverGroups.ready(),c.loadBalancers.ready()]).then(u)).then((()=>{e.$$destroyed||c.isStandalone||c.serverGroups.onRefresh(e,u)})),e.account=a.account}]);const ne=class extends X.Component{constructor(e){super(e),this.choose=()=>{this.close();const e=r.getValue("azure","loadBalancer");c.modalService.open({templateUrl:e.createLoadBalancerTemplateUrl,windowClass:"modal-z-index",controller:`${e.createLoadBalancerController} as ctrl`,size:"lg",resolve:{application:()=>this.props.app,loadBalancer:()=>null,isNew:()=>!0,forPipelineConfig:()=>!1,loadBalancerType:()=>this.state.selectedChoice}}).result.catch((()=>{}))},this.close=e=>{this.props.dismissModal(e)},this.state={choices:$,selectedChoice:$[0]}}static show(e){return d.show(ne,{...e,className:"create-pipeline-modal-overflow-visible"})}choiceSelected(e){this.setState({selectedChoice:e})}render(){const{choices:e,selectedChoice:n}=this.state;return X.createElement(X.Fragment,null,X.createElement(u,{dismiss:this.close}),X.createElement(q.Header,null,X.createElement(q.Title,null,"Select Type of Load Balancer")),X.createElement(q.Body,null,X.createElement("div",{className:"modal-body"},X.createElement("div",{className:"card-choices"},e.map((e=>X.createElement("div",{key:e.type,className:"card "+(n===e?"active":""),onClick:()=>this.choiceSelected(e)},X.createElement("h3",{className:"load-balancer-label"},e.type),X.createElement("div",null,e.description))))),X.createElement("div",{className:"load-balancer-description"}))),X.createElement(q.Footer,null,X.createElement(j,{onClick:this.choose},"Configure Load Balancer ",X.createElement("span",{className:"glyphicon glyphicon-chevron-right"}))))}};let te=ne;te.defaultProps={closeModal:p,dismissModal:p};const ae=m.providers.azure||{defaults:{}};ae&&(ae.resetToOriginal=m.resetProvider("azure"));n("spinnaker.azure.loadBalancer.transformer",[]).factory("azureLoadBalancerTransformer",["$q",function(e){return{normalizeLoadBalancer:function(n){n.serverGroups.forEach((function(e){e.account=n.account,e.region=n.region,e.detachedInstances?(e.detachedInstances=e.detachedInstances.map((function(e){return{id:e}})),e.instances=e.instances.concat(e.detachedInstances)):e.detachedInstances=[]}));const t=H.filter(n.serverGroups,{isDisabled:!1});return n.provider=n.type,n.instances=H.chain(t).map("instances").flatten().value(),n.detachedInstances=H.chain(t).map("detachedInstances").flatten().value(),e.resolve(n)},convertLoadBalancerForEditing:function(e){const n={region:e.region,credentials:e.account,name:e.name,stack:e.stack,detail:e.detail,vnet:e.vnet,subnet:e.subnet,probes:[],loadBalancingRules:[]};if(e.elb){const t=e.elb;n.securityGroups=t.securityGroups,n.vnet=t.vnet,t.loadBalancingRules&&(n.loadBalancingRules=t.loadBalancingRules),n.probes=t.probes,t.dnsName&&"dns-not-found"!==t.dnsName&&(n.dnsName=t.dnsName.split(".")[0])}return n},constructNewLoadBalancerTemplate:function(e){return{stack:"",detail:"frontend",credentials:e.defaultCredentials.azure||ae.defaults.account,region:e.defaultRegions.azure||ae.defaults.region,cloudProvider:"azure",vnet:null,subnet:null,probes:[{probeName:"",probeProtocol:"HTTP",probePort:"80",probePath:"/",probeInterval:30,unhealthyThreshold:8,timeout:120}],securityGroups:[],loadBalancingRules:[{ruleName:"",protocol:"HTTP",externalPort:80,backendPort:80,probeName:"",persistence:"None",idleTimeout:4}],sku:"Standard_v2"}}}}]);n("spinnaker.azure.loadBalancer.create.controller",[O,"spinnaker.azure.loadBalancer.transformer"]).controller("azureCreateLoadBalancerCtrl",["$scope","$uibModalInstance","$state","azureLoadBalancerTransformer","application","loadBalancer","isNew","loadBalancerType",function(e,n,t,a,r,i,l,s){const o=this;function c(){if(e.$$destroyed)return;n.close();const a={name:e.loadBalancer.name,accountId:e.loadBalancer.credentials,region:e.loadBalancer.region,provider:"azure"};t.includes("**.loadBalancerDetails")?t.go("^.loadBalancerDetails",a):t.go(".loadBalancerDetails",a)}function d(){const n=e.loadBalancer.credentials,t=e.loadBalancer.region,a={};r.getDataSource("loadBalancers").refresh(!0).then((()=>{r.getDataSource("loadBalancers").data.forEach((e=>{e.account===n&&(a[e.region]=a[e.region]||[],a[e.region].push(e.name))})),e.existingLoadBalancerNames=a[t]||[]}))}e.regions=[],e.pages={location:"azure/src/loadBalancer/configure/createLoadBalancerProperties.html",listeners:"azure/src/loadBalancer/configure/listeners.html",healthCheck:"azure/src/loadBalancer/configure/healthCheck.html",advancedSettings:"azure/src/loadBalancer/configure/advancedSettings.html"},e.isNew=l,e.loadBalancerType=s.type,e.isALB="Azure Load Balancer"===s.type,e.state={accountsLoaded:!1,submitting:!1},e.validSkus=["Standard_v2","Standard_Small"],e.taskMonitor=new g({application:r,title:(l?"Creating ":"Updating ")+"your load balancer",modalInstance:n,onTaskComplete:function(){r.loadBalancers.refresh(),r.loadBalancers.onNextRefresh(e,c)}}),function(){if(i){if(e.loadBalancer=a.convertLoadBalancerForEditing(i),l){const n=B.parseLoadBalancerName(e.loadBalancer.name);e.loadBalancer.stack=n.stack,e.loadBalancer.detail=n.freeFormDetails,delete e.loadBalancer.name}}else e.loadBalancer=a.constructNewLoadBalancerTemplate(r);l&&(d(),f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accountsLoaded=!0,o.accountUpdated()})))}(),this.requiresHealthCheckPath=function(){return e.loadBalancer.probes[0].probeProtocol&&0===e.loadBalancer.probes[0].probeProtocol.indexOf("HTTP")},this.updateName=function(){e.loadBalancer.name=this.getName()},this.getName=function(){const n=e.loadBalancer,t=[r.name,n.stack||"",n.detail||""].join("-");return H.trimEnd(t,"-")},this.accountUpdated=function(){f.getRegionsForAccount(e.loadBalancer.credentials).then((function(n){e.regions=n,o.regionUpdated()}))},this.regionUpdated=function(){d(),o.updateName(),o.vnetUpdated()},this.vnetUpdated=function(){const n=e.loadBalancer.credentials,t=e.loadBalancer.region;e.loadBalancer.selectedVnet=null,e.loadBalancer.vnet=null,e.loadBalancer.vnetResourceGroup=null,o.selectedVnets=[],v.listNetworks().then((function(e){e.azure&&e.azure.forEach((e=>{e.account===n&&e.region===t&&o.selectedVnets.push(e)}))})),o.subnetUpdated()},this.subnetUpdated=function(){e.loadBalancer.selectedSubnet=null,e.loadBalancer.subnet=null,o.selectedSubnets=[]},this.selectedVnetChanged=function(n){e.loadBalancer.vnet=n.name,e.loadBalancer.vnetResourceGroup=n.resourceGroup,e.loadBalancer.selectedSubnet=null,e.loadBalancer.subnet=null,o.selectedSubnets=[],n.subnets&&n.subnets.map((function(e){let n=!0;e.devices&&e.devices.map((function(e){e&&"applicationGateways"!==e.type&&(n=!1)})),n&&o.selectedSubnets.push(e)}))},this.removeListener=function(n){e.loadBalancer.loadBalancingRules.splice(n,1)},this.addListener=function(){e.loadBalancer.loadBalancingRules.push({protocol:"HTTP"})},this.submit=function(){const n=l?"Create":"Update";e.taskMonitor.submit((function(){const t={cloudProvider:"azure",appName:r.name,clusterName:e.loadBalancer.clusterName,resourceGroupName:e.loadBalancer.clusterName,loadBalancerName:e.loadBalancer.name};e.loadBalancer.selectedVnet&&(e.loadBalancer.vnet=e.loadBalancer.selectedVnet.name,e.loadBalancer.vnetResourceGroup=e.loadBalancer.selectedVnet.resourceGroup),e.loadBalancer.selectedSubnet&&(e.loadBalancer.subnet=e.loadBalancer.selectedSubnet.name);const a=e.loadBalancer.clusterName||e.loadBalancer.name,i=a+"-probe",l=a+"-rule";return e.loadBalancer.type="upsertLoadBalancer",e.loadBalancer.loadBalancerType=e.loadBalancerType,e.loadBalancer.vnet||e.loadBalancer.subnetType||(e.loadBalancer.securityGroups=null),e.loadBalancer.probes[0].probeName=i,e.loadBalancer.loadBalancingRules.forEach(((e,n)=>{e.ruleName=l+n,e.probeName=i})),"TCP"===e.loadBalancer.probes[0].probeProtocol&&(e.loadBalancer.probes[0].probePath=void 0),h.upsertLoadBalancer(e.loadBalancer,r,n,t)}))},this.cancel=function(){n.dismiss()}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/createLoadBalancerProperties.html",'<div>\n <div ng-if="!state.accountsLoaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div class="modal-body" ng-if="state.accountsLoaded">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.loadBalancerName.$error.validateUnique, \'alert-info\': !form.loadBalancerName.$error.validateUnique}"\n >\n <strong>Your {{loadBalancerType}} will be named:</strong>\n <span>{{ctrl.getName()}}</span>\n \x3c!-- Angular does not seem to run length validation on hidden inputs, hence the text + display:none --\x3e\n <input\n type="text"\n style="display: none"\n ng-maxlength="32"\n class="form-control input-sm"\n ng-model="loadBalancer.name"\n validate-unique="existingLoadBalancerNames"\n validate-ignore-case="true"\n name="loadBalancerName"\n />\n <validation-error\n ng-if="form.loadBalancerName.$error.validateUnique"\n message="There is already a load balancer in {{loadBalancer.credentials}}:{{loadBalancer.region}} with that name."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Account</div>\n <div class="col-md-7">\n <account-select-field\n required\n component="loadBalancer"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <region-select-field\n required\n label-columns="3"\n component="loadBalancer"\n field="region"\n account="loadBalancer.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-3 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="loadBalancer.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks"\n >{{$select.selected.name}}</ui-select-match\n >\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-3 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="loadBalancer.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack <help-field key="azure.loadBalancer.stack"></help-field></div>\n <div class="col-md-3">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-model="loadBalancer.stack"\n name="stackName"\n ng-change="ctrl.updateName()"\n ng-pattern="/^[a-zA-Z0-9]*$/"\n />\n </div>\n <div class="col-md-6 form-inline">\n <label class="sm-label-right"> Detail <help-field key="azure.loadBalancer.detail"></help-field> </label>\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-model="loadBalancer.detail"\n name="detailName"\n ng-change="ctrl.updateName()"\n ng-pattern="/^[a-zA-Z0-9-]*$/"\n />\n </div>\n <div class="col-md-7 col-md-offset-3" ng-if="form.stackName.$error.pattern">\n <validation-error message="Stack can only contain letters and numbers."></validation-error>\n </div>\n <div class="col-md-7 col-md-offset-3" ng-if="form.detailName.$error.pattern">\n <validation-error message="Detail can only contain letters, numbers, and dashes."></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-9 col-md-offset-3" ng-if="form.loadBalancerName.$error.maxlength">\n <validation-error message="Load Balancer name can only be 32 characters."></validation-error>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/listeners.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th>Protocol</th>\n <th>External Port</th>\n <th></th>\n <th>Internal Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in loadBalancer.loadBalancingRules">\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.protocol"\n ng-init="rule.protocol = (isALB ? \'TCP\' : \'HTTP\')"\n ng-options="protocol for protocol in (isALB ? [\'TCP\', \'UDP\'] : [\'HTTP\'])"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="number" min="0" ng-model="rule.externalPort" required />\n </td>\n <td class="small" style="padding-top: 10px">→</td>\n <td>\n <input class="form-control input-sm" type="number" min="0" ng-model="rule.backendPort" required />\n </td>\n <td>\n <a href class="sm-label" ng-click="ctrl.removeListener($index)"\n ><span class="glyphicon glyphicon-trash"></span\n ></a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="5">\n <button class="add-new col-md-12" ng-click="ctrl.addListener()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new port mapping\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/healthCheck.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed" ng-if="!isALB">\n <thead>\n <tr>\n <th width="35%">Protocol</th>\n <th width="30%">Host</th>\n <th><span ng-if="ctrl.requiresHealthCheckPath()">Path</span></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.probes[0].probeProtocol"\n required\n ng-options="protocol for protocol in [\'HTTP\']"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.probes[0].probePort" />\n </td>\n <td>\n <input\n ng-if="ctrl.requiresHealthCheckPath()"\n class="form-control input-sm"\n type="text"\n ng-model="loadBalancer.probes[0].probePath"\n required\n />\n </td>\n </tr>\n </tbody>\n </table>\n\n <table class="table table-condensed packed" ng-if="isALB">\n <thead>\n <tr>\n <th width="35%">Protocol</th>\n <th width="30%">Port</th>\n <th><span ng-if="ctrl.requiresHealthCheckPath()">Path</span></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td>\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.probes[0].probeProtocol"\n ng-init="loadBalancer.probes[0].probeProtocol = \'TCP\'"\n required\n ng-options="protocol for protocol in [\'TCP\', \'HTTP\']"\n ></select>\n </td>\n <td>\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.probes[0].probePort" />\n </td>\n <td>\n <input\n ng-if="ctrl.requiresHealthCheckPath()"\n class="form-control input-sm"\n type="text"\n ng-model="loadBalancer.probes[0].probePath"\n required\n />\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/advancedSettings.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <div class="form-group">\n <div class="col-md-3">\n <b>Custom DNS Label</b>\n <help-field key="azure.loadBalancer.dnsName"></help-field>\n </div>\n <div class="col-md-6">\n <input class="form-control input-sm" type="text" ng-model="loadBalancer.dnsName" />\n <span>.{{loadBalancer.region}}.cloudapp.azure.com</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3">\n <b>Health Check</b>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Interval</b>\n <help-field key="azure.loadBalancer.probes.probeInterval"></help-field>\n </div>\n <div class="col-md-4">\n <input class="form-control input-sm" type="number" min="0" ng-model="loadBalancer.probes[0].probeInterval" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Unhealthy Threshold</b>\n <help-field key="azure.loadBalancer.probes.unhealthyThreshold"></help-field>\n </div>\n <div class="col-md-4">\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n ng-model="loadBalancer.probes[0].unhealthyThreshold"\n />\n </div>\n </div>\n <div class="form-group" ng-if="isALB">\n <div class="col-md-4 sm-label-right">\n <b>Idle Timeout</b>\n <help-field key="azure.loadBalancer.loadBalancingRules.idleTimeout"></help-field>\n </div>\n <div class="col-md-4">\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n ng-model="loadBalancer.loadBalancingRules[0].idleTimeout"\n />\n </div>\n </div>\n <div class="form-group" ng-if="!isALB">\n <div class="col-md-4 sm-label-right">\n <b>Timeout</b>\n <help-field key="azure.loadBalancer.probes.timeout"></help-field>\n </div>\n <div class="col-md-4">\n <input class="form-control input-sm" type="number" min="0" ng-model="loadBalancer.probes[0].timeout" />\n </div>\n </div>\n <div class="form-group" ng-if="isNew && !isALB">\n <div class="col-md-4 sm-label-right">\n <b>SKU</b>\n <help-field key="azure.loadBalancer.sku"></help-field>\n </div>\n <div class="col-md-4">\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.sku"\n ng-options="sku for sku in validSkus"\n ></select>\n </div>\n </div>\n <div class="form-group" ng-if="isALB">\n <div class="col-md-4 sm-label-right">\n <b>Session persistence</b>\n <help-field key="azure.loadBalancer.loadBalancingRules.sessionPersistence"></help-field>\n </div>\n <div class="col-md-4">\n <select\n class="form-control input-sm"\n ng-model="loadBalancer.sessionPersistence"\n ng-init="loadBalancer.sessionPersistence = \'None\'"\n required\n ng-options="p for p in [\'None\', \'Client IP\', \'Client IP and protocol\']"\n ></select>\n </div>\n </div>\n </div>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.loadBalancer.details.controller",[Q,O,A,y]).controller("azureLoadBalancerDetailsCtrl",["$scope","$state","$exceptionHandler","$uibModal","loadBalancer","app","securityGroupReader","loadBalancerReader","$q",function(n,t,a,r,l,s,o,c,d){function u(){if(n.loadBalancer=s.loadBalancers.data.filter((function(e){return e.name===l.name&&e.region===l.region&&e.account===l.accountId}))[0],n.loadBalancer){return c.getLoadBalancerDetails(n.loadBalancer.provider,l.accountId,l.region,l.name).then((function(e){n.state.loading=!1;const t=[],a=e.filter((function(e){return e.name===l.name}));if(a.length&&(n.loadBalancer.elb=a[0],n.loadBalancer.account=l.accountId,n.loadBalancer.elb.securityGroups&&(n.loadBalancer.elb.securityGroups.forEach((function(e){const n=o.getApplicationSecurityGroup(s,l.accountId,l.region,e);n&&t.push(n)})),n.securityGroups=H.sortBy(t,"name")),n.loadBalancer.loadBalancerType&&n.loadBalancer.loadBalancerType.includes("_"))){const e=n.loadBalancer.loadBalancerType;n.loadBalancer.loadBalancerType=e.split("_").map((e=>{const n=e.toLowerCase();return n.substring(0,1).toUpperCase()+n.substring(1)})).join(" ")}}))}return n.loadBalancer||t.go("^"),d.when(null)}n.state={loading:!0},n.firewallsLabel=b.get("Firewalls"),s.ready().then(u).then((()=>{n.$$destroyed||s.onRefresh(n,u)})),this.editLoadBalancer=function(){r.open({templateUrl:"azure/src/loadBalancer/configure/editLoadBalancer.html",controller:"azureCreateLoadBalancerCtrl as ctrl",size:"lg",resolve:{application:function(){return s},loadBalancer:function(){return e.copy(n.loadBalancer)},isNew:function(){return!1},loadBalancerType:function(){return{type:n.loadBalancer.loadBalancerType}}}})},this.deleteLoadBalancer=function(){if(n.loadBalancer.instances&&n.loadBalancer.instances.length)return;const e={application:s,title:"Deleting "+l.name},t={cloudProvider:"azure",loadBalancerName:n.loadBalancer.name,loadBalancerType:n.loadBalancer.loadBalancerType,credentials:n.loadBalancer.account,region:l.region,appName:s.name};i.confirm({header:"Really delete "+l.name+"?",buttonText:"Delete "+l.name,account:l.accountId,taskMonitorConfig:e,submitMethod:()=>h.deleteLoadBalancer(t,s)})}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/editLoadBalancer.html",'<form name="form" novalidate validate-on-submit>\n <v2-modal-wizard\n heading="Edit {{loadBalancerType}} {{loadBalancer.name}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="Listeners" label="Listeners" done="true">\n <ng-include src="pages.listeners"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Health Check" label="Health Check" done="true" hide-subheading="true">\n <ng-include src="pages.healthCheck"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Advanced Settings" label="Advanced Settings" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.submit()"\n is-new="isNew"\n ></submit-button>\n </div>\n</form>\n')}]);n("spinnaker.azure.pipeline.stage.bake.executionDetails.controller",[O]).controller("azureBakeExecutionDetailsCtrl",["$scope","$stateParams","executionDetailsSectionService","$interpolate",function(e,n,t,a){e.configSections=["bakeConfig","taskStatus"];const r=()=>{e.detailsSection=n.details,e.provider=e.stage.context.cloudProviderType||"azure",e.roscoMode=m.feature.roscoMode||"function"==typeof m.feature.roscoSelector&&m.feature.roscoSelector(e.stage.context),e.bakeryDetailUrl=a(e.roscoMode&&m.roscoDetailUrl?m.roscoDetailUrl:m.bakeryDetailUrl)},i=()=>t.synchronizeSection(e.configSections,r);i(),e.$on("$stateChangeSuccess",i)}]);n("spinnaker.azure.pipeline.stage.bakeStage",["spinnaker.azure.pipeline.stage.bake.executionDetails.controller"]).config((function(){S.pipeline.registerStage({provides:"bake",cloudProvider:"azure",label:"Bake",description:"Bakes an image",templateUrl:"azure/src/pipeline/stages/bake/bakeStage.html",executionDetailsUrl:"azure/src/pipeline/stages/bake/bakeExecutionDetails.html",executionLabelComponent:D,extraLabelLines:e=>e.masterStage.context.allPreviouslyBaked||e.masterStage.context.somePreviouslyBaked?1:0,supportsCustomTimeout:!0,validators:[{type:"requiredField",fieldName:"package"},{type:"requiredField",fieldName:"regions"},{type:"upstreamVersionProvided",checkParentTriggers:!0,getMessage:e=>"Bake stages should always have a stage or trigger preceding them that provides version information: <ul>"+e.map((e=>`<li>${e}</li>`)).join("")+"</ul>Otherwise, Spinnaker will bake and deploy the most-recently built package."}],restartable:!0})})).controller("azureBakeStageCtrl",["$scope","$q","$uibModal",function(e,n,t){e.stage.extendedAttributes=e.stage.extendedAttributes||{},e.stage.regions=e.stage.regions||[],e.stage.user||(e.stage.user=z.getAuthenticatedUser().name),e.viewState={loading:!0},this.baseOsChanged=()=>{const n=H.find(e.baseOsOptions,{id:e.stage.baseOs});e.stage.osType=n.osType},this.addExtendedAttribute=function(){e.stage.extendedAttributes||(e.stage.extendedAttributes={}),t.open({templateUrl:w.addExtendedAttributes,controller:"bakeStageAddExtendedAttributeController",controllerAs:"addExtendedAttribute",resolve:{extendedAttribute:function(){return{key:"",value:""}}}}).result.then((function(n){e.stage.extendedAttributes[n.key]=n.value})).catch((()=>{}))},this.removeExtendedAttribute=function(n){delete e.stage.extendedAttributes[n]},this.showTemplateFileName=function(){return e.viewState.roscoMode||e.stage.templateFileName},this.showExtendedAttributes=function(){return e.viewState.roscoMode||e.stage.extendedAttributes&&H.size(e.stage.extendedAttributes)>0},this.showVarFileName=function(){return e.viewState.roscoMode||e.stage.varFileName},e.$watch("stage",(function(){H.forOwn(e.stage,(function(n,t){""===n&&delete e.stage[t]})),"function"==typeof m.feature.roscoSelector&&(e.viewState.roscoMode=m.feature.roscoSelector(e.stage))}),!0),n.all([G.getRegions("azure"),G.getBaseOsOptions("azure"),G.getBaseLabelOptions()]).then((function([n,t,a]){e.regions=n,1===e.regions.length?e.stage.region=e.regions[0]:e.regions.includes(e.stage.region)||delete e.stage.region,!e.stage.regions.length&&e.application.defaultRegions.azure&&e.stage.regions.push(e.application.defaultRegions.azure),!e.stage.regions.length&&e.application.defaultRegions.azure&&e.stage.regions.push(e.application.defaultRegions.azure),e.baseOsOptions=t.baseImages,e.baseOsOptions.length&&(e.stage.osType=t.baseImages[0].osType),e.baseLabelOptions=a,!e.stage.baseOs&&e.baseOsOptions&&e.baseOsOptions.length&&(e.stage.baseOs=e.baseOsOptions[0].id),!e.stage.baseLabel&&e.baseLabelOptions&&e.baseLabelOptions.length&&(e.stage.baseLabel=e.baseLabelOptions[0]),e.viewState.roscoMode=m.feature.roscoMode||"function"==typeof m.feature.roscoSelector&&m.feature.roscoSelector(e.stage),e.showAdvancedOptions=function(){const n=e.stage;return!!(n.templateFileName||n.extendedAttributes&&H.size(n.extendedAttributes)>0||n.varFileName)}(),e.viewState.loading=!1}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/bake/bakeStage.html",'<div ng-controller="azureBakeStageCtrl as bakeStageCtrl">\n <div ng-if="viewState.loading" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div ng-if="!viewState.loading">\n <stage-config-field label="Regions">\n <checklist items="regions" model="stage.regions" inline="true" include-select-all-button="true"></checklist>\n </stage-config-field>\n <stage-config-field label="Package" help-key="pipeline.config.bake.package">\n <input type="text" class="form-control input-sm" ng-model="stage.package" />\n </stage-config-field>\n <stage-config-field label="Base OS">\n <bake-stage-choose-os model="stage.baseOs" base-os-options="baseOsOptions"></bake-stage-choose-os>\n </stage-config-field>\n <stage-config-field label="Base Label">\n <label class="radio-inline" ng-repeat="baseLabel in baseLabelOptions">\n <input type="radio" ng-model="stage.baseLabel" ng-value="baseLabel" />\n {{baseLabel}}\n </label>\n </stage-config-field>\n \x3c!-- Even if the roscoMode flag is false, we should show the control if rebake is set. --\x3e\n <stage-config-field label="Rebake" ng-if="viewState.roscoMode || stage.rebake">\n <div class="checkbox" style="margin-bottom: 0">\n <label>\n <input type="checkbox" ng-model="stage.rebake" />\n Rebake image without regard to the status of any existing bake\n </label>\n </div>\n </stage-config-field>\n <stage-config-field label="Base Name">\n <input type="text" class="form-control input-sm" ng-model="stage.baseName" />\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-9 col-md-offset-1">\n <div class="checkbox">\n <label>\n <input type="checkbox" ng-model="showAdvancedOptions" />\n <strong>Show Advanced Options</strong>\n </label>\n </div>\n </div>\n </div>\n <div ng-class="{collapse: showAdvancedOptions !== true, \'collapse.in\': showAdvancedOptions === true}">\n <stage-config-field\n label="Template File Name"\n help-key="pipeline.config.bake.templateFileName"\n ng-if="bakeStageCtrl.showTemplateFileName()"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.templateFileName" />\n </stage-config-field>\n <stage-config-field\n label="Extended Attributes"\n help-key="pipeline.config.bake.extendedAttributes"\n ng-if="bakeStageCtrl.showExtendedAttributes()"\n >\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 40%">Key</th>\n <th style="width: 60%">Value</th>\n <th class="text-right">Actions</th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="(key,value) in stage.extendedAttributes">\n <td>\n <strong class="small">{{key}}</strong>\n </td>\n <td>\n <input\n type="text"\n ng-model="stage.extendedAttributes[key]"\n value="{{value}}"\n class="form-control input-sm"\n />\n </td>\n <td class="text-right">\n <a class="small" href ng-click="bakeStageCtrl.removeExtendedAttribute(key)">Remove</a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="7">\n <button class="btn btn-block btn-sm add-new" ng-click="bakeStageCtrl.addExtendedAttribute()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add Extended Attribute\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </stage-config-field>\n <stage-config-field\n label="Var File Name"\n help-key="pipeline.config.bake.varFileName"\n ng-if="bakeStageCtrl.showVarFileName()"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.varFileName" />\n </stage-config-field>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/bake/bakeExecutionDetails.html",'<div ng-controller="azureBakeExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'bakeConfig\'">\n <div class="row">\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Azure</dd>\n <dt>Image</dt>\n <dd>{{stage.context.ami}}</dd>\n <dt>Region</dt>\n <dd>{{stage.context.region}}</dd>\n <dt>Package</dt>\n <dd>{{stage.context.package}}</dd>\n </dl>\n </div>\n <div class="col-md-6">\n <dl class="dl-narrow dl-horizontal">\n <dt>Base OS</dt>\n <dd>{{stage.context.baseOs}}</dd>\n <dt>Label</dt>\n <dd>{{stage.context.baseLabel}}</dd>\n <dt ng-if="roscoMode || execution.trigger.rebake || stage.context.rebake">Rebake</dt>\n <dd ng-if="roscoMode || execution.trigger.rebake || stage.context.rebake">\n {{execution.trigger.rebake || stage.context.rebake || false}}\n </dd>\n <dt ng-if="stage.context.templateFileName">Template</dt>\n <dd ng-if="stage.context.templateFileName">{{stage.context.templateFileName}}</dd>\n <dt ng-if="stage.context.varFileName">Var File</dt>\n <dd ng-if="stage.context.varFileName">{{stage.context.varFileName}}</dd>\n </dl>\n </div>\n </div>\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n\n <div class="row" ng-if="stage.context.region && stage.context.status.resourceId">\n <div class="col-md-12">\n <div class="alert alert-{{stage.isFailed ? \'danger\' : \'info\'}}">\n <div ng-if="stage.context.previouslyBaked">No changes detected; reused existing bake</div>\n <a target="_blank" href="{{ bakeryDetailUrl(stage) }}"> View Bakery Details </a>\n </div>\n </div>\n </div>\n </div>\n <div class="step-section-details" ng-if="detailsSection === \'taskStatus\'">\n <div class="row">\n <execution-step-details item="stage"></execution-step-details>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.pipeline.stage.destroyAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"destroyServerGroup",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/destroyAsg/destroyAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"targetImpedance",message:"This pipeline will attempt to destroy a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureDestroyAsgStageCtrl",["$scope",function(e){const n=this,t=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),n.accountUpdated=function(){f.getAccountDetails(t.credentials).then((function(e){t.regions=[e.org]}))},e.targets=k.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="azure",t.interestingHealthProviderNames=[],!t.credentials&&e.application.defaultCredentials.azure&&(t.credentials=e.application.defaultCredentials.azure),t.credentials&&n.accountUpdated(),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/destroyAsg/destroyAsgStage.html",'<div ng-controller="azureDestroyAsgStageCtrl as destroyAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",'<span class="task-label"> Destroy Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.pipeline.stage.disableAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"disableServerGroup",alias:"disableAsg",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/disableAsg/disableAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",validators:[{type:"targetImpedance",message:"This pipeline will attempt to disable a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureDisableAsgStageCtrl",["$scope",function(e){const n=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),e.targets=k.TARGET_LIST,n.regions=n.regions||[],n.cloudProvider="azure",n.isNew&&e.application.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=[]),!n.credentials&&e.application.defaultCredentials.azure&&(n.credentials=e.application.defaultCredentials.azure),!n.regions.length&&e.application.defaultRegions.azure&&n.regions.push(e.application.defaultRegions.azure),n.target||(n.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/disableAsg/disableAsgStage.html",'<div ng-controller="azureDisableAsgStageCtrl as disableAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'azureService\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",'<span class="task-label"> Disable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.pipeline.stage.enableAsgStage",[]).config((function(){S.pipeline.registerStage({provides:"enableServerGroup",alias:"enableAsg",cloudProvider:"azure",templateUrl:"azure/src/pipeline/stages/enableAsg/enableAsgStage.html",executionStepLabelUrl:"azure/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("azureEnableAsgStageCtrl",["$scope",function(e){const n=this,t=e.stage;e.state={accounts:!1,regionsLoaded:!1},f.listAccounts("azure").then((function(n){e.accounts=n,e.state.accounts=!0})),n.reset=()=>{n.accountUpdated(),n.resetSelectedCluster()},e.targets=k.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="azure",t.isNew&&(t.interestingHealthProviderNames=[]),!t.credentials&&e.application.defaultCredentials.azure&&(t.credentials=e.application.defaultCredentials.azure),!t.regions.length&&e.application.defaultRegions.azure&&t.regions.push(e.application.defaultRegions.azure),t.target||(t.target=e.targets[0].val),e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/enableAsg/enableAsgStage.html",'<div ng-controller="azureEnableAsgStageCtrl as enableAsgStageCtrl" class="form-horizontal">\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="targets"></target-select>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'azureService\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",'<span class="task-label"> Enable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);n("spinnaker.azure.securityGroup.write.service",[O]).factory("azureSecurityGroupWriter",(function(){return{deleteSecurityGroup:function(e,n,t={}){t.type="deleteSecurityGroup",t.securityGroupName=e.name,t.regions=[e.region],t.credentials=e.accountId,t.appName=n.name;const a=C.executeTask({job:[t],application:n,description:`Delete ${b.get("Firewalls")}: ${e.name}`});return F.clearCache("securityGroup"),a},upsertSecurityGroup:function(e,n,t,a={}){a.securityGroupName=e.name,H.assignWith(a,e,(function(e,n){return H.isUndefined(e)?n:e}));const r=C.executeTask({job:[a],application:n,description:`${t} ${b.get("Firewall")}: spinnaker.azure.securityGroup.write.service`});return F.clearCache("securityGroup"),r}}}));n("spinnaker.azure.securityGroup.create.controller",[O,"spinnaker.azure.securityGroup.write.service"]).controller("azureCreateSecurityGroupCtrl",["$scope","$uibModalInstance","$state","$controller","application","securityGroup","azureSecurityGroupWriter",function(e,n,t,a,r,i,l){e.pages={location:"azure/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},e.regions=[],e.firewallLabel=b.get("Firewall");const s=this;function o(){if(e.$$destroyed)return;n.close();const a={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.regions[0],provider:"azure"};t.includes("**.firewallDetails")?t.go("^.firewallDetails",a):t.go(".firewallDetails",a)}function c(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.isNew=!0,e.state={submitting:!1,infiniteScroll:{numToAdd:20,currentItems:20}},f.listAccounts("azure").then((function(n){e.accounts=n,s.accountUpdated()})),s.addMoreItems=function(){e.state.infiniteScroll.currentItems+=e.state.infiniteScroll.numToAdd},e.taskMonitor=new g({application:r,title:`Creating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){r.securityGroups.refresh(),r.securityGroups.onNextRefresh(e,o)}}),e.securityGroup=i,s.accountUpdated=function(){f.getRegionsForAccount(e.securityGroup.credentials).then((function(n){e.regions=n,e.securityGroup.regions=n,s.updateName(),s.regionUpdated()}))},this.regionUpdated=function(){s.vnetUpdated()},this.vnetUpdated=function(){const n=e.securityGroup.credentials,t=e.securityGroup.region;e.securityGroup.selectedVnet=null,e.securityGroup.vnet=null,e.securityGroup.vnetResourceGroup=null,s.selectedVnets=[],v.listNetworks().then((function(e){e.azure&&e.azure.forEach((e=>{e.account===n&&e.region===t&&s.selectedVnets.push(e)}))})),s.subnetUpdated()},this.subnetUpdated=function(){e.securityGroup.selectedSubnet=null,e.securityGroup.subnet=null,s.selectedSubnets=[]},this.selectedVnetChanged=function(n){e.securityGroup.vnet=n.name,e.securityGroup.vnetResourceGroup=n.resourceGroup,e.securityGroup.selectedSubnet=null,e.securityGroup.subnet=null,s.selectedSubnets=[],n.subnets&&n.subnets.map((function(e){s.selectedSubnets.push(e)}))},s.cancel=function(){n.dismiss()},s.updateName=function(){const n=e.securityGroup;let t=r.name;n.detail&&(t+="-"+n.detail),n.name=t,e.namePreview=t},s.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:r.name,region:e.securityGroup.region,vpcId:"null"};return e.securityGroup.selectedVnet&&(e.securityGroup.vnet=e.securityGroup.selectedVnet.name,e.securityGroup.vnetResourceGroup=e.securityGroup.selectedVnet.resourceGroup),e.securityGroup.selectedSubnet&&(e.securityGroup.subnet=e.securityGroup.selectedSubnet.name),e.securityGroup.type="upsertSecurityGroup",l.upsertSecurityGroup(e.securityGroup,r,"Create",n)}))},s.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0==n.length?100:100*(n.length+1),protocolUI:"tcp",protocol:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourceAddressPrefixes:[],sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"*",destinationPortRanges:[],destPortRanges:"*",sourceIPCIDRRanges:"*"})},s.portUpdated=function(e,n){if(!H.isEmpty(e[n].destPortRanges)){const t=e[n].destPortRanges.split(",");t.length>1?(e[n].destinationPortRanges=[],t.forEach((t=>e[n].destinationPortRanges.push(t))),e[n].destinationPortRange=null):(e[n].destinationPortRange=e[n].destPortRanges,e[n].destinationPortRanges=[])}},s.sourceIPCIDRUpdated=function(e,n){if(!H.isEmpty(e[n].destPortRanges)){const t=e[n].sourceIPCIDRRanges.split(",");t.length>1?(e[n].sourceAddressPrefixes=[],t.forEach((t=>e[n].sourceAddressPrefixes.push(t))),e[n].sourceAddressPrefix=null):(e[n].sourceAddressPrefix=e[n].sourceIPCIDRRanges,e[n].sourceAddressPrefixes=[])}},s.protocolUpdated=function(e,n){e[n].protocol=e[n].protocolUI},s.removeRule=function(e,n){e.splice(n,1)},s.moveUp=function(e,n){0!==n&&c(e,n,n-1)},s.moveDown=function(e,n){n!==e.length-1&&c(e,n,n+1)},e.securityGroup.securityRules=[]}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="modal-body">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.securityGroupName.$error.validateUnique, \'alert-info\': !form.securityGroupName.$error.validateUnique}"\n >\n <strong>Your <firewall-label label="firewall"></firewall-label> will be named:</strong>\n <span ng-bind="namePreview"></span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Detail</div>\n <div class="col-md-4">\n <input\n type="text"\n class="form-control input-sm"\n required\n ng-model="securityGroup.detail"\n ng-change="ctrl.updateName()"\n />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Description</div>\n <div class="col-md-8">\n <input type="text" class="form-control input-sm" ng-model="securityGroup.description" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Account</div>\n <div class="col-md-8">\n <account-select-field\n required\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-12">\n <region-select-field\n label-columns="4"\n component="securityGroup"\n field="region"\n field-columns="8"\n account="securityGroup.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.securityGroup.azure.edit.controller",[O,I,A,"spinnaker.azure.securityGroup.write.service"]).controller("azureEditSecurityGroupCtrl",["$scope","$uibModalInstance","$exceptionHandler","$state","securityGroupReader","cacheInitializer","application","securityGroup","azureSecurityGroupWriter",function(e,n,t,a,r,i,l,s,o){function c(){if(e.$$destroyed)return;n.close();const t={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.region,provider:"azure"};a.includes("**.firewallDetails")?a.go("^.firewallDetails",t):a.go(".firewallDetails",t)}function d(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.pages={ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},s.securityRules=H.map(s.securityRules,(function(e){return H.isEmpty(e.protocol)||(e.protocolUI=e.protocol.toLowerCase()),e.destPortRanges=e.destinationPortRangeModel,e.sourceIPCIDRRanges=e.sourceAddressPrefixModel,e})),e.securityGroup=s,e.state={refreshingSecurityGroups:!1},e.taskMonitor=new g({application:l,title:`Updating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){l.securityGroups.refresh(),l.securityGroups.onNextRefresh(e,c)}}),this.getSecurityGroupRefreshTime=function(){return F.get("securityGroups").getStats().ageMax},this.refreshSecurityGroups=function(){return e.state.refreshingSecurityGroups=!0,i.refreshCache("securityGroups").then((function(){r.getAllSecurityGroups().then((function(n){const t=s.accountName,a=s.region,r=H.filter(n[t].azure[a],{});e.availableSecurityGroups=H.map(r,"name")})).then((function(){e.state.refreshingSecurityGroups=!1}))}))},this.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0===n.length?100:100*(n.length+1),protocolUI:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourceAddressPrefixes:[],sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"*",destinationPortRanges:[],destPortRanges:"*",sourceIPCIDRRanges:"*"})},this.portUpdated=function(e,n){if(!H.isEmpty(e[n].sourceIPCIDRRanges)){const t=e[n].destPortRanges.split(",");t.length>1?(e[n].destinationPortRanges=[],t.forEach((t=>e[n].destinationPortRanges.push(t))),e[n].destinationPortRange=null):(e[n].destinationPortRange=e[n].destPortRanges,e[n].destinationPortRanges=[])}},this.sourceIPCIDRUpdated=function(e,n){if(!H.isEmpty(e[n].sourceIPCIDRRanges)){const t=e[n].sourceIPCIDRRanges.split(",");t.length>1?(e[n].sourceAddressPrefixes=[],t.forEach((t=>e[n].sourceAddressPrefixes.push(t))),e[n].sourceAddressPrefix=null):(e[n].sourceAddressPrefix=e[n].sourceIPCIDRRanges,e[n].sourceAddressPrefixes=[])}},this.removeRule=function(e,n){e.splice(n,1)},this.moveUp=function(e,n){0!==n&&d(e,n,n-1)},this.moveDown=function(e,n){n!==e.length-1&&d(e,n,n+1)},e.taskMonitor.onTaskComplete=n.dismiss,this.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:l.name,region:e.securityGroup.region,subnet:null,vpcId:"null"};return e.securityGroup.type="upsertSecurityGroup",o.upsertSecurityGroup(e.securityGroup,l,"Update",n)}))},this.cancel=function(){n.dismiss()}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.securityGroup.clone.controller",["spinnaker.azure.securityGroup.write.service","spinnaker.azure.securityGroup.create.controller"]).controller("azureCloneSecurityGroupController",["$scope","$uibModalInstance","$controller","$state","azureSecurityGroupWriter","securityGroup","application",function(e,n,t,a,r,i,l){const s=this;function o(){if(e.$$destroyed)return;n.close();const t={name:e.securityGroup.name,accountId:e.securityGroup.credentials||e.securityGroup.accountName,region:e.securityGroup.region,provider:"azure"};a.includes("**.firewallDetails")?a.go("^.firewallDetails",t):a.go(".firewallDetails",t)}function c(e,n,t){const a=e[t],r=e[n].priority,i=e[t].priority;e[t]=e[n],e[n]=a,e[n].priority=r,e[t].priority=i}e.firewallLabel=b.get("Firewall"),e.pages={location:"azure/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"azure/src/securityGroup/configure/createSecurityGroupIngress.html"},i.securityRules=H.map(i.securityRules,(function(e){const n=e.destinationPortRange.split("-");return e.startPort=Number(n[0]),e.endPort=Number(n[1]),e})),s.accountUpdated=function(){f.getRegionsForAccount(e.securityGroup.credentials).then((function(n){e.regions=n,e.securityGroup.regions=n,s.updateName()}))},s.cancel=function(){n.dismiss()},s.updateName=function(){const n=e.securityGroup;let t=l.name;n.detail&&(t+="-"+n.detail),n.name=t,e.namePreview=t},e.securityGroup=i,e.state={refreshingSecurityGroups:!1},e.taskMonitor=new g({application:l,title:`Updating your ${b.get("firewall")}`,modalInstance:n,onTaskComplete:function(){l.securityGroups.refresh(),l.securityGroups.onNextRefresh(e,o)}}),f.listAccounts("azure").then((function(n){e.accounts=n,s.accountUpdated()})),s.addRule=function(n){n.push({name:e.securityGroup.name+"-Rule"+n.length,priority:0===n.length?100:100*(n.length+1),protocol:"tcp",access:"Allow",direction:"InBound",sourceAddressPrefix:"*",sourcePortRange:"*",destinationAddressPrefix:"*",destinationPortRange:"7001-7001",startPort:7001,endPort:7001})},s.portUpdated=function(e,n){e[n].destinationPortRange=e[n].startPort+"-"+e[n].endPort},s.removeRule=function(e,n){e.splice(n,1)},s.moveUp=function(e,n){0!==n&&c(e,n,n-1)},s.moveDown=function(e,n){n!==e.length-1&&c(e,n,n+1)},s.upsert=function(){e.taskMonitor.submit((function(){const n={cloudProvider:"azure",appName:l.name,region:e.securityGroup.region,subnet:"none",vpcId:"null"};return e.securityGroup.type="upsertSecurityGroup",r.upsertSecurityGroup(e.securityGroup,l,"Clone",n)}))}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="modal-body">\n <div class="form-group">\n <div\n class="col-md-12 well"\n ng-class="{\'alert-danger\': form.securityGroupName.$error.validateUnique, \'alert-info\': !form.securityGroupName.$error.validateUnique}"\n >\n <strong>Your <firewall-label label="firewall"></firewall-label> will be named:</strong>\n <span ng-bind="namePreview"></span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Detail</div>\n <div class="col-md-4">\n <input\n type="text"\n class="form-control input-sm"\n required\n ng-model="securityGroup.detail"\n ng-change="ctrl.updateName()"\n />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Description</div>\n <div class="col-md-8">\n <input type="text" class="form-control input-sm" ng-model="securityGroup.description" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Account</div>\n <div class="col-md-8">\n <account-select-field\n required\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'azure\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-12">\n <region-select-field\n label-columns="4"\n component="securityGroup"\n field="region"\n field-columns="8"\n account="securityGroup.credentials"\n provider="\'azure\'"\n on-change="ctrl.regionUpdated()"\n regions="regions"\n ></region-select-field>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedVnet"\n on-select="ctrl.selectedVnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in ctrl.selectedVnets | filter: $select.search">\n <span ng-bind-html="selectVnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Subnet</div>\n <div class="col-md-7">\n <ui-select\n class="form-control input-sm"\n ng-model="securityGroup.selectedSubnet"\n on-select="ctrl.selectedSubnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing subnets">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectSubnet in ctrl.selectedSubnets | filter: $select.search">\n <span ng-bind-html="selectSubnet.name | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="modal-body">\n <div class="row"></div>\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-12">\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th style="width: 21%">Protocol</th>\n <th style="width: 32%">\n Source IP/CIDR ranges<help-field key="azure.securityGroup.ingress.sourceIPCIDRRanges"></help-field>\n </th>\n <th style="width: 32%">\n Destination port ranges<help-field key="azure.securityGroup.ingress.destPortRanges"></help-field>\n </th>\n <th style width="15%">Actions<help-field key="azure.securityGroup.ingress.actions"></help-field></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityRules">\n <td>\n <select class="form-control input-sm" ng-model="rule.protocolUI">\n <option value="tcp">TCP</option>\n <option value="udp">UDP</option>\n <option value="*">ANY</option>\n </select>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="*"\n pattern="^*$|^((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?(,((25[0-5]|2[0-4]d|[01]?dd?)[.]){3}(25[0-5]|2[0-4]d|[01]?dd?)(/([1-9]|[1-2]d|3[0-2]))?)*$"\n ng-model="rule.sourceIPCIDRRanges"\n ng-change="ctrl.sourceIPCIDRUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="text"\n value="80"\n pattern="^*$|^((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5]))(,((d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])|(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])-(d|[1-9]d{1,3}|[1-5]d{4}|6[0-4]d{3}|65[0-4]d{2}|655[0-2]d|6553[0-5])))*$"\n ng-model="rule.destPortRanges"\n ng-change="ctrl.portUpdated(securityGroup.securityRules, $index)"\n required\n />\n </td>\n <td>\n <a class="btn-link sm-label" ng-click="ctrl.moveUp(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-up"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.moveDown(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-arrow-down"></span>\n </a>\n <a class="btn-link sm-label" ng-click="ctrl.removeRule(securityGroup.securityRules, $index)"\n ><span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <button class="add-new col-md-12" ng-click="ctrl.addRule(securityGroup.securityRules)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </div>\n </div>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.securityGroup.azure.details.controller",[O,A,"spinnaker.azure.securityGroup.write.service","spinnaker.azure.securityGroup.clone.controller"]).controller("azureSecurityGroupDetailsCtrl",["$scope","$state","resolvedSecurityGroup","app","azureSecurityGroupWriter","securityGroupReader","$uibModal",function(n,t,a,r,l,s,o){const c=r,d=a;function u(){return s.getSecurityGroupDetails(c,d.accountId,d.provider,d.region,d.vpcId,d.name).then((function(e){n.state.loading=!1,!e||H.isEmpty(e)?p():n.securityGroup=e}),(function(){p()}))}function p(){t.go("^")}n.state={loading:!0},n.firewallLabel=b.get("Firewall"),u().then((()=>{n.$$destroyed||r.securityGroups.onRefresh(n,u)})),this.editInboundRules=function(){o.open({templateUrl:"azure/src/securityGroup/configure/editSecurityGroup.html",controller:"azureEditSecurityGroupCtrl as ctrl",resolve:{securityGroup:function(){return e.copy(n.securityGroup)},application:function(){return c}}})},this.cloneSecurityGroup=function(){o.open({templateUrl:"azure/src/securityGroup/clone/cloneSecurityGroup.html",controller:"azureCloneSecurityGroupController as ctrl",resolve:{securityGroup:function(){const t=e.copy(n.securityGroup);return t.region&&(t.regions=[t.region]),t},application:function(){return c}}})},this.deleteSecurityGroup=function(){const e={application:c,title:"Deleting "+d.name};i.confirm({header:"Really delete "+d.name+"?",buttonText:"Delete "+d.name,account:d.accountId,taskMonitorConfig:e,submitMethod:function(){return n.securityGroup.type="deleteSecurityGroup",l.deleteSecurityGroup(d,c,{cloudProvider:"azure",vpcId:n.securityGroup.vpcId})}})},r.isStandalone&&(r.securityGroups={refresh:u})}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/editSecurityGroup.html",'<form name="form" novalidate validate-on-submit>\n <v2-modal-wizard\n heading="Edit {{securityGroup.name}}: {{securityGroup.region}}: {{securityGroup.credentials}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.upsert()"\n ></submit-button>\n </div>\n</form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/clone/cloneSecurityGroup.html",'<v2-modal-wizard heading="Clone {{firewallLabel}}">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n</v2-modal-wizard>\n')}]);n("spinnaker.azure.securityGroup.reader",[]).factory("azureSecurityGroupReader",(function(){return{resolveIndexedSecurityGroup:function(e,n,t){const a=t.split("/");return e[n.account][n.region][a[a.length-1]]}}}));n("spinnaker.azure.securityGroup.transformer",[]).factory("azureSecurityGroupTransformer",(function(){return{normalizeSecurityGroup:function(){}}}));n("spinnaker.azure.serverGroup.transformer",[]).factory("azureServerGroupTransformer",(function(){function e(e,n){if(Array.isArray(e.customScriptsSettings.fileUris))n.customScriptsSettings.fileUris=e.customScriptsSettings.fileUris;else{const t=e.customScriptsSettings.fileUris;t.includes(",")?n.customScriptsSettings.fileUris=t.split(","):t.includes(";")?n.customScriptsSettings.fileUris=t.split(";"):n.customScriptsSettings.fileUris=[t],n.customScriptsSettings.fileUris.forEach((function(e,t){n.customScriptsSettings.fileUris[t]=e.trim()}))}}return{convertServerGroupCommandToDeployConfiguration:function(n){let t;t="editPipeline"===n.viewState.mode||"createPipeline"===n.viewState.mode?{imageName:"",isCustom:"true",publisher:"",offer:"",sku:"",version:"",region:n.region,uri:"",ostype:""}:n.selectedImage;const a={name:n.application,cloudProvider:n.selectedProvider,application:n.application,stack:n.stack,strategy:n.strategy,rollback:{onFailure:n.rollback?n.rollback.onFailure:null},scaleDown:n.scaleDown,maxRemainingAsgs:n.maxRemainingAsgs,delayBeforeDisableSec:n.delayBeforeDisableSec,delayBeforeScaleDownSec:n.delayBeforeScaleDownSec,allowDeleteActive:"redblack"===n.strategy||null,allowScaleDownActive:"redblack"===n.strategy||null,detail:n.freeFormDetails,freeFormDetails:n.freeFormDetails,healthSettings:n.healthSettings,image:n.image,account:n.credentials,selectedProvider:"azure",vnet:n.vnet,vnetResourceGroup:n.selectedVnet.resourceGroup,subnet:n.subnet,useSourceCapacity:!1,capacity:{min:n.sku.capacity,max:n.sku.capacity},credentials:n.credentials,region:n.region,securityGroupName:n.securityGroupName,loadBalancerName:n.loadBalancerName,loadBalancerType:n.loadBalancerType,user:"[anonymous]",upgradePolicy:"Manual",type:"createServerGroup",sku:{name:"Standard_DS1_v2",tier:"Standard",capacity:n.sku.capacity},instanceTags:n.instanceTags,dataDisks:n.dataDisks,userAssignedIdentities:n.userAssignedIdentities,viewState:n.viewState,osConfig:{customData:n.osConfig?n.osConfig.customData:null},customScriptsSettings:{fileUris:null,commandToExecute:""},zonesEnabled:n.zonesEnabled,zones:n.zonesEnabled?n.zones:[],enableInboundNAT:n.enableInboundNAT};if(null!=n.image&&0!=n.image.isCustom||(a.image=t),void 0!==n.stack&&(a.name=a.name+"-"+n.stack),void 0!==n.freeFormDetails&&(a.name=a.name+"-"+n.freeFormDetails),void 0!==n.customScriptsSettings&&(a.customScriptsSettings.commandToExecute=n.customScriptsSettings.commandToExecute,H.isEmpty(n.customScriptsSettings.fileUris)||e(n,a)),n.instanceType){const e=n.instanceType;a.instanceType=n.instanceType,a.sku.name=e,a.sku.tier=e.substring(0,e.indexOf("_"))}return a.interestingHealthProviderNames=[],a},normalizeServerGroup:function(e){return e},parseCustomScriptsSettings:e}}));n("spinnaker.azure.serverGroup.configure.instanceArchetype.controller",[]).controller("azureInstanceArchetypeCtrl",["$scope","instanceTypeService","modalWizardService",function(e,n,t){const a=t.getWizard();e.$watch("command.viewState.instanceProfile",(function(){e.command.viewState.instanceProfile&&"custom"!==e.command.viewState.instanceProfile?(a.includePage("instance-type"),a.markClean("instance-profile"),a.markComplete("instance-profile")):a.excludePage("instance-type")})),e.$watch("command.viewState.instanceType",(function(e){e&&(a.markClean("instance-profile"),a.markComplete("instance-profile"))}))}]);n("spinnaker.azure.serverGroup.configure.instanceType.controller",[]).controller("azureInstanceTypeCtrl",["$scope","modalWizardService",function(e,n){n.getWizard().markComplete("instance-type"),n.getWizard().markClean("instance-type")}]);n("spinnaker.azure.serverGroup.configure.advancedSetting.controller",[]).controller("azureServerGroupAdvancedSettingsCtrl",["$scope","modalWizardService",function(e,n){n.getWizard().markComplete("advanced"),e.$watch("form.$valid",(function(e){e?n.getWizard().markClean("advanced"):n.getWizard().markDirty("advanced")}))}]);e.module("spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive",[]).directive("azureServerGroupAdvancedSettingsSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"adv",controller:"azureServerGroupAdvancedSettingsSelectorCtrl"}})).controller("azureServerGroupAdvancedSettingsSelectorCtrl",(function(){this.addDataDisk=()=>{const n=e.copy(this.command.dataDisks);this.command.dataDisks=n.concat([{lun:0,managedDisk:{storageAccountType:"Standard_LRS"},diskSizeGB:1,caching:"None",createOption:"Empty"}])},this.removeDataDisk=n=>{const t=e.copy(this.command.dataDisks);t.splice(n,1),this.command.dataDisks=t}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.html",'<div class="container-fluid form-horizontal">\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-4 sm-label-right">Number of Instances</div>\n <div class="col-md-2">\n <input\n type="number"\n class="form-control input-sm"\n ng-model="adv.command.sku.capacity"\n min="0"\n max="100"\n required\n />\n </div>\n </div>\n <div></div>\n <div class="form-group">\n <div class="col-xs-4 sm-label-right">\n <b>Custom Data</b>\n <help-field key="azure.serverGroup.customData"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.osConfig.customData" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Custom Script</b>\n <help-field key="azure.serverGroup.scriptLocation"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.customScriptsSettings.fileUris" />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>Command To Execute</b>\n <help-field key="azure.serverGroup.commandToExecute"></help-field>\n </div>\n <div class="col-md-7">\n <input\n type="text"\n class="form-control input-sm"\n ng-model="adv.command.customScriptsSettings.commandToExecute"\n />\n </div>\n </div>\n <div class="form-group" ng-if="adv.command.loadBalancerType === \'Azure Application Gateway\'">\n <div class="col-md-4 sm-label-right">\n <input type="checkbox" ng-model="adv.command.enableInboundNAT" ng-disabled="adv.command.zonesEnabled" />\n </div>\n <div class="col-md-7">\n <b>Enable inbound NAT port-forwarding rules to connect to VM instances</b>\n <help-field key="azure.serverGroup.enableInboundNAT"></help-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-right">\n <b>User-Assigned Identities</b>\n <help-field key="azure.serverGroup.userAssignedIdentities"></help-field>\n </div>\n <div class="col-md-7">\n <input type="text" class="form-control input-sm" ng-model="adv.command.userAssignedIdentities" />\n </div>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-4 sm-label-left">Data Disks</div>\n <div class="col-md-11">\n <table class="table table-condensed packed tags">\n <thead>\n <tr>\n <th>\n LUN\n <help-field key="azure.serverGroup.lun"></help-field>\n </th>\n <th>\n Size (GB)\n <help-field key="azure.serverGroup.diskSizeGB"></help-field>\n </th>\n <th>\n Type\n <help-field key="azure.serverGroup.managedDisk.storageAccountType"></help-field>\n </th>\n <th>\n Caching\n <help-field key="azure.serverGroup.caching"></help-field>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="disk in adv.command.dataDisks">\n <td>\n <input type="number" class="form-control input-sm" ng-model="disk.lun" required min="0" />\n </td>\n <td>\n <input type="number" class="form-control input-sm" ng-model="disk.diskSizeGB" required min="1" />\n </td>\n <td>\n <ui-select ng-model="disk.managedDisk.storageAccountType" class="form-control input-sm" required>\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="dataDiskType in adv.command.backingData.dataDiskTypes | filter: $select.search"\n >\n <span ng-bind-html="dataDiskType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </td>\n <td>\n <ui-select ng-model="disk.caching" class="form-control input-sm" required>\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="dataDiskCachingType in adv.command.backingData.dataDiskCachingTypes | filter: $select.search"\n >\n <span ng-bind-html="dataDiskCachingType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </td>\n <td>\n <a class="btn btn-link sm-label" style="margin-top: 0" ng-click="adv.removeDataDisk($index)">\n <span class="glyphicon glyphicon-trash"></span>\n </a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan="4">\n <button class="btn btn-block btn-sm add-new" ng-click="adv.addDataDisk()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add New Data Disk\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.basicSettings.image.filter",[]).filter("regional",(function(){return function(e,n){return H.filter(e,(function(e){return e.region===n||null===e.region}))}}));e.module("spinnaker.azure.serverGroup.configure.basicSettings",[O,Q,"spinnaker.azure.serverGroup.configure.basicSettings.image.filter",E]).controller("azureServerGroupBasicSettingsCtrl",["$scope","$controller","$uibModalStack","$state","imageReader",function(n,t,a,r,i){n.$watch("form.$valid",(function(e){e?(T.markClean("basic-settings"),T.markComplete("basic-settings")):T.markIncomplete("basic-settings")})),this.imageChanged=e=>{n.command.imageName=e.imageName,n.command.selectedImage=e,T.markClean("basic-settings")},e.extend(this,t("BasicSettingsMixin",{$scope:n,imageReader:i,$uibModalStack:a,$state:r})),this.stackPattern={test:function(e){return(n.command.viewState.templatingEnabled?/^([a-zA-Z0-9]*(\${.+})*)*$/:/^[a-zA-Z0-9]*$/).test(e)}},this.detailPattern={test:function(e){return(n.command.viewState.templatingEnabled?/^([a-zA-Z0-9-]*(\${.+})*)*$/:/^[a-zA-Z0-9-]*$/).test(e)}}}]);n("spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive",[]).directive("azureServerGroupCapacitySelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"cap",controller:"azureServerGroupCapacitySelectorCtrl"}})).controller("azureServerGroupCapacitySelectorCtrl",(function(){})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/capacity/capacitySelector.directive.html",'<div>\n <div class="form-group">\n <div class="col-md-12">\n <p>Sets desired instance count.</p>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Number of Instances</div>\n <div class="col-md-2">\n <input\n type="number"\n class="form-control input-sm"\n ng-model="cap.command.sku.capacity"\n min="0"\n max="100"\n required\n />\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.healthSetting.controller",[]).controller("azureServerGroupHealthSettingsCtrl",["$scope",function(e){void 0===e.command.healthSettings&&(e.command.healthSettings={}),this.healthCheckProtocols=[{displayName:"N/A",name:null},{displayName:"HTTP",name:"http"},{displayName:"TCP",name:"tcp"}],this.requiresHealthCheckPath=function(){return"http"===e.command.healthSettings.protocol},this.changeHealthCheckProtocol=function(n){null==n?(e.command.healthSettings.protocol=null,e.command.healthSettings.port=null,e.command.healthSettings.requestPath=null):this.requiresHealthCheckPath()||(e.command.healthSettings.requestPath=null)}}]);n("spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive",[]).directive("azureServerGroupHealthSettingsSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.html",scope:{command:"="}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupHealthSettingsCtrl as healthCtrl">\n <div class="form-group">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Protocol</div>\n <div class="col-md-7">\n <select\n class="form-control input-sm"\n ng-model="command.healthSettings.protocol"\n ng-options="protocol.name as protocol.displayName for protocol in healthCtrl.healthCheckProtocols"\n ng-change="healthCtrl.changeHealthCheckProtocol(command.healthSettings.protocol)"\n ></select>\n </div>\n </div>\n <div class="form-group" ng-if="command.healthSettings.protocol">\n <div class="col-md-3 sm-label-right">Port</div>\n <div class="col-md-7">\n <input class="form-control input-sm" type="text" ng-model="command.healthSettings.port" required />\n </div>\n </div>\n <div class="form-group" ng-if="healthCtrl.requiresHealthCheckPath()">\n <div class="col-md-3 sm-label-right">Path</div>\n <div class="col-md-7">\n <input class="form-control input-sm" type="text" ng-model="command.healthSettings.requestPath" required />\n </div>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-9 col-md-offset-3">\n <p>Health settings here will be applied directly to the VM Scale Set.</p>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.imageSettings.controller",[]).controller("azureServerGroupImageSettingsCtrl",["$scope",function(e){this.clearImage=function(){0==e.command.image.isCustom?e.command.image={isCustom:!1}:e.command.image.region=e.command.region},T.markComplete("image-settings"),e.$watch("form.$valid",(function(e){e?T.markClean("image-settings"):T.markDirty("image-settings")}))}]);n("spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive",[]).directive("azureServerGroupImageSettingsSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.html",scope:{command:"="}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupImageSettingsCtrl as imageCtrl">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Use custom image?</div>\n <input type="checkbox" ng-model="command.image.isCustom" ng-change="imageCtrl.clearImage()" />\n </div>\n\n <div class="form-group" ng-if="command.image.isCustom === true">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Region</div>\n <div class="col-md-6">\n <span>{{command.image.region}}</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Image Name</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.imageName" required />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">OS Type</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.ostype" required />\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">URI</div>\n <div class="col-md-6">\n <input type="text" class="input-sm" ng-model="command.image.uri" required />\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.loadBalancer.controller",[y]).controller("azureServerGroupLoadBalancersCtrl",["$scope","loadBalancerReader",function(e,n){function t(t,a){n.getLoadBalancerDetails("azure",e.command.credentials,e.command.region,t).then((function(n){if(n&&0!==n.length){if(n&&1===n.length){const t=n[0],r=e.command.selectedVnet;e.command.selectedVnet=null,e.command.selectedVnetSubnets=[],e.command.allVnets=[],v.listNetworks().then((function(n){n.azure&&n.azure.forEach((n=>{n.account===e.command.credentials&&n.region===e.command.region&&e.command.allVnets.push(n),n.account===e.command.credentials&&n.region===e.command.region&&("Azure Application Gateway"===a&&n.name==t.vnet||"Azure Load Balancer"===a&&n.name===r.name)&&(e.command.selectedVnet=n,n.subnets.map((function(n){let t=!0;n.devices&&n.devices.map((function(e){e&&"applicationGateways"===e.type&&(t=!1)})),t&&e.command.selectedVnetSubnets.push(n.name)})))}))}))}}else{e.command.selectedVnet;const n=e.command.selectedSubnet;e.command.selectedVnetSubnets=[],e.command.allVnets=[],v.listNetworks().then((function(t){t.azure&&t.azure.forEach((t=>{t.account===e.command.credentials&&t.region===e.command.region&&(e.command.allVnets.push(t),t.subnets.map((function(t){let a=!0;t.devices&&t.devices.map((function(e){e&&"applicationGateways"===e.type&&(a=!1)})),a&&(e.command.selectedVnetSubnets.push(t.name),t.name===n&&(e.command.selectedSubnet=n))})))}))}))}}))}T.markClean("load-balancers"),e.command.credentials&&e.command.region&&(e.command.viewState.networkSettingsConfigured=!0,e.command.selectedVnetSubnets=[],null!==e.command.loadBalancerName&&void 0!==e.command.loadBalancerName&&(e.useLoadBalancer=!0),t(e.command.loadBalancerName,e.command.loadBalancerType)),this.loadBalancerChanged=function(n){e.command.viewState.networkSettingsConfigured=!0,T.markComplete("load-balancers");const a=e.command.backingData.loadBalancers;let r=null;if(a){const e=a.find((e=>e.name===n));e&&(r=K.getLoadBalancerType(e.loadBalancerType).type)}null===n&&(e.command.loadBalancerName=null),e.command.selectedVnetSubnets=[],e.command.loadBalancerType=r,F.clearCache("networks"),t(n,r)}}]);n("spinnaker.azure.serverGroup.configure.loadBalancer.directive",[]).directive("azureServerGroupLoadBalancersSelector",["azureServerGroupConfigurationService",function(){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.html"}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.loadBalancersConfigured">Please select an account and region.</h5>\n<div\n ng-if="command.viewState.loadBalancersConfigured"\n ng-controller="azureServerGroupLoadBalancersCtrl as loadBalancerCtrl"\n>\n <div class="form-group">\n <div class="col-md-3 sm-label-right"><b>Load Balancers</b></div>\n <div class="col-md-7">\n <label for="useLoadBalancerCheckbox">\n <input\n type="checkbox"\n ng-model="useLoadBalancer"\n id="useLoadBalancerCheckbox"\n ng-change="loadBalancerCtrl.loadBalancerChanged(null)"\n />\n Use load balancer\n </label>\n <ui-select\n ng-model="command.loadBalancerName"\n class="form-control input-sm"\n ng-change="loadBalancerCtrl.loadBalancerChanged($select.selected)"\n ng-show="useLoadBalancer"\n >\n <ui-select-match placeholder="select a loadBalancer">{{$select.selected}}</ui-select-match>\n <ui-select-choices repeat="loadBalancer in command.loadBalancers | filter: $select.search">\n <span ng-bind-html="loadBalancer | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-show="command.loadBalancerName">\n <div class="col-md-12">\n <div class="well-compact" ng-class="well">\n <h5 class="text-center">\n <p>The load balancer {{command.loadBalancerName}} is an {{command.loadBalancerType}}</p>\n </h5>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.networkSettings.controller",[]).controller("azureServerGroupNetworkSettingsCtrl",["$scope",function(e){T.markClean("network-settings"),e.command.selectedVnet={name:e.command.vnet},e.command.selectedSubnet=e.command.subnet,this.vnetChanged=function(n){e.command.vnet=n,e.command.subnet=e.command.selectedSubnet=null,e.command.selectedVnetSubnets=n.subnets.map((e=>e.name))},this.networkSettingsChanged=function(n){e.command.vnet=e.command.selectedVnet.name,e.command.subnet=n,T.markComplete("network-settings")},this.getVnetName=function(){return e.command.selectedVnet?e.command.selectedVnet.name:"Virtual network was not selected"}}]);n("spinnaker.azure.serverGroup.configure.networkSettings.directive",[]).directive("azureServerGroupNetworkSettingsSelector",(function(){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.html"}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.networkSettingsConfigured">\n Please select an account, a region and a load balancer first.\n</h5>\n<div\n ng-if="command.viewState.networkSettingsConfigured"\n ng-controller="azureServerGroupNetworkSettingsCtrl as networkSettingCtrl"\n>\n <div class="form-group" ng-if="command.loadBalancerType === \'Azure Load Balancer\' || !command.loadBalancerType">\n <div class="col-md-3 sm-label-right">Virtual Network</div>\n <div class="col-md-7">\n <ui-select\n required\n class="form-control input-sm"\n ng-model="command.selectedVnet"\n on-select="networkSettingCtrl.vnetChanged($item)"\n >\n <ui-select-match placeholder="Select from existing virtual networks">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat="selectVnet in command.allVnets">\n <span ng-bind-html="selectVnet.name"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group">\n <div class="col-md-3 sm-label-right"><b>Subnets</b></div>\n <div class="col-md-7">\n <ui-select\n required\n ng-model="command.selectedSubnet"\n class="form-control input-sm"\n on-select="networkSettingCtrl.networkSettingsChanged($item)"\n >\n <ui-select-match placeholder="Select from an existing subnet">{{$select.selected}}</ui-select-match>\n <ui-select-choices repeat="subnet in command.selectedVnetSubnets | filter: $select.search">\n <span ng-bind-html="subnet | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group" ng-if="!command.viewState.hideClusterNamePreview">\n <div class="col-md-12">\n <div class="well-compact" ng-class="well">\n <h5 class="text-center">\n <p>Your server group will be using a subnet in virtual network:</p>\n <p>\n <strong> {{networkSettingCtrl.getVnetName()}} </strong>\n </p>\n </h5>\n </div>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.securityGroups.controller",[]).controller("azureServerGroupSecurityGroupsCtrl",["$scope",function(e){T.markClean("security-groups"),T.markComplete("security-groups"),e.command.selectedSecurityGroup={id:e.command.securityGroupName},this.securityGroupChanged=function(n){e.command.securityGroupName=n.id,T.markComplete("security-groups")}}]);n("spinnaker.azure.serverGroup.configure.securityGroupSelector.directive",[]).directive("azureServerGroupSecurityGroupsSelector",["azureServerGroupConfigurationService",function(e){return{restrict:"E",scope:{command:"="},templateUrl:"azure/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.html",link:function(n){n.firewallLabel=b.get("firewall"),n.getSecurityGroupRefreshTime=function(){return F.get("securityGroups").getStats().ageMax},n.refreshSecurityGroups=function(){n.refreshing=!0,e.refreshSecurityGroups(n.command).then((function(){n.refreshing=!1}))}}}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.html",'<h5 class="text-center" ng-if="!command.viewState.securityGroupsConfigured">Please select an account and region.</h5>\n<div\n ng-if="command.viewState.securityGroupsConfigured"\n ng-controller="azureServerGroupSecurityGroupsCtrl as securityGroupCtrl"\n>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n <b><firewall-label label="Firewalls"></firewall-label></b>\n </div>\n <div class="col-md-7">\n <ui-select\n ng-model="command.selectedSecurityGroup"\n class="form-control input-sm"\n on-select="securityGroupCtrl.securityGroupChanged($item)"\n >\n <ui-select-match placeholder="select a {{firewallLabel}}">{{$select.selected.id}}</ui-select-match>\n <ui-select-choices\n repeat="securityGroup in command.backingData.filtered.securityGroups | anyFieldFilter: {name: $select.search, id: $select.search}"\n >\n <span ng-bind-html="securityGroup.id | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-9 col-md-offset-3">\n <p>\n <span ng-if="refreshing"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!refreshing">last refreshed {{ getSecurityGroupRefreshTime() | timestamp }}</span>\n <span ng-if="refreshing"> refreshing...</span>\n </p>\n <p>\n If you\'re not finding a <firewall-label label="firewall"></firewall-label> that was recently added,\n <a href ng-click="refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.wizard.tags.directive",[]).directive("azureTagsSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/tags/tagsSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"tagsSelectorCtrl",controller:"TagsSelectorCtrl"}})).controller("TagsSelectorCtrl",["$scope",function(){this.getTagResult=function(){return K.checkTags(this.command.instanceTags)}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/tags/tagsSelector.directive.html",'<div class="form-group">\n <div class="col-md-12" style="color: red" ng-if="!tagsSelectorCtrl.getTagResult().isValid">\n {{ tagsSelectorCtrl.getTagResult().errorMessage }}\n </div>\n <div class="col-md-4 sm-label-left">\n <b>Custom Tags</b>\n <help-field key="azure.serverGroup.customTags"></help-field>\n </div>\n <div class="col-md-12">\n <map-editor\n model="tagsSelectorCtrl.command.instanceTags"\n add-button-label="Add New Tags"\n allow-empty="true"\n ></map-editor>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive",[]).directive("azureZoneSelector",(function(){return{restrict:"E",templateUrl:"azure/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html",scope:{},bindToController:{command:"="},controllerAs:"vm",controller:["$scope",function(e){this.updateEnableInboundNAT=()=>{e.vm.command.zonesEnabled&&(e.vm.command.enableInboundNAT=!1)}}]}})),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html",'<div class="form-group" ng-if="vm.command.region">\n <div class="col-md-10">\n <label ng-if="vm.command.backingData.filtered.zones && vm.command.backingData.filtered.zones.length !== 0">\n <input type="checkbox" ng-model="vm.command.zonesEnabled" ng-change="vm.updateEnableInboundNAT()" />\n Set availability zones\n </label>\n <ui-select multiple ng-if="vm.command.zonesEnabled" ng-model="vm.command.zones" class="form-control input-sm">\n <ui-select-match>{{ $item }}</ui-select-match>\n <ui-select-choices repeat="zone as zone in vm.command.backingData.filtered.zones">\n <span>{{ zone }}</span>\n </ui-select-choices>\n </ui-select>\n </div>\n</div>\n<h5 class="text-center" ng-if="!vm.command.region">Please select a region.</h5>\n<h5\n class="text-center"\n ng-if="vm.command.region && !(vm.command.backingData.filtered.zones && vm.command.backingData.filtered.zones.length !== 0)"\n>\n Current region does not support availability zones\n</h5>\n')}]);n("spinnaker.azure.serverGroup.configure",["spinnaker.azure.serverGroup.configure.basicSettings","spinnaker.azure.serverGroup.configure.loadBalancer.controller","spinnaker.azure.serverGroup.configure.instanceArchetype.controller","spinnaker.azure.serverGroup.configure.instanceType.controller","spinnaker.azure.serverGroup.configure.securityGroups.controller","spinnaker.azure.serverGroup.configure.advancedSetting.controller","spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive","spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive","spinnaker.azure.serverGroup.configure.imageSettings.controller","spinnaker.azure.serverGroup.configure.healthSetting.controller","spinnaker.azure.serverGroup.configure.loadBalancer.directive","spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive","spinnaker.azure.serverGroup.configure.securityGroupSelector.directive","spinnaker.azure.serverGroup.transformer","spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive","spinnaker.azure.serverGroup.configure.networkSettings.controller","spinnaker.azure.serverGroup.configure.networkSettings.directive","spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive","spinnaker.azure.serverGroup.configure.wizard.tags.directive"]);e.module("spinnaker.azure.serverGroup.configure.service",["spinnaker.azure.image.reader",y,A,I,"spinnaker.azure.instanceType.service"]).factory("azureServerGroupConfigurationService",["$q","azureImageReader","securityGroupReader","cacheInitializer","loadBalancerReader","azureInstanceTypeService",function(n,t,a,r,i,l){const s=["Standard_LRS","StandardSSD_LRS","Premium_LRS"],o=["None","ReadOnly","ReadWrite"],c=["EC2","ELB"],d=["OldestInstance","NewestInstance","OldestLaunchConfiguration","ClosestToNextInstanceHour","Default"];function u(n){const t={dirty:{}};if(n.region){const a=[t.dirty];a.push(function(e){const n=e,t={dirty:{}},a=[n.region],{credentialsKeyedByAccount:r}=n.backingData,{locationToInstanceTypesMap:i}=r[n.credentials];if(a.every((e=>!e)))return t;const s=l.getAvailableTypesForRegions(i,a).map((e=>e.name)),o=n.instanceType;H.every([o,!H.startsWith(o,"custom"),!H.includes(s,o)])&&(t.dirty.instanceType=n.instanceType,n.instanceType=null);return n.backingData.filtered.instanceTypes=s,t}(n).dirty),e.extend(...a)}else n.backingData.filtered.instanceTypes=[];return t}function p(e){const n={dirty:{}},t=e.backingData.filtered;if(!e.region)return n;let{regionsSupportZones:a,availabilityZones:r}=e.backingData.credentialsKeyedByAccount[e.credentials];return a=a||[],r=r||[],t.zones=a.includes(e.region)?r:[],n}function m(e){const n=e.backingData.securityGroups[e.credentials]||{azure:{}};return H.chain(n[e.region]).sortBy("name").value()}function g(e){const n={dirty:{}};let t;e.backingData.filtered.securityGroups&&(t=e.backingData.filtered.securityGroups);const a=m(e);return e.selectedSecurityGroup&&(e.selectedSecurityGroup=null,n.dirty.securityGroups=!0),t!=a&&(e.backingData.filtered.securityGroups=a,n.dirty.securityGroups=!0),e.backingData.filtered.securityGroups===[]?e.viewState.securityGroupsConfigured=!1:e.viewState.securityGroupsConfigured=!0,n}function v(e){return H.chain(e).map("name").uniq().value().sort()}function h(e){const n={dirty:{}},t=e.loadBalancers,a=v(e.backingData.loadBalancers);if(t&&e.loadBalancers){const r=H.intersection(a,e.loadBalancers),i=H.xor(r,t);e.loadBalancers=r,i.length&&(n.dirty.loadBalancers=i)}return e.backingData.filtered.loadBalancers=a,n}function B(e){const n=e.backingData.loadBalancers,t=H.filter(n,(function(n){return n.account===e.credentials&&n.region===e.region}));return e.loadBalancers=v(t),e.viewState.loadBalancersConfigured=!0,{dirty:{}}}return{configureUpdateCommand:function(n){n.backingData={healthCheckTypes:e.copy(c),terminationPolicies:e.copy(d)}},configureCommand:function(t,r){return n.all([f.getCredentialsKeyedByAccount("azure"),a.loadSecurityGroups(),i.loadLoadBalancers(t.name)]).then((function([n,t,a]){var i;r.backingData={credentialsKeyedByAccount:n,securityGroups:t,loadBalancers:a,dataDiskTypes:e.copy(s),dataDiskCachingTypes:e.copy(o),accounts:H.keys(n),filtered:{}},(i=r).regionChanged=function(n,t=!1){const a={dirty:{}};return n.region&&n.credentials&&(e.extend(a.dirty,B(n).dirty),e.extend(a.dirty,g(n).dirty),e.extend(a.dirty,u(n).dirty),e.extend(a.dirty,p(n).dirty)),t||(n.loadBalancerName=null,n.loadBalancerType=null,n.vnet=null,n.vnetResourceGroup=null,n.subnet=null,n.selectedSubnet=null,n.selectedVnet=null,n.selectedVnetSubnets=[],n.viewState.networkSettingsConfigured=!1,n.selectedSecurityGroup=null,n.securityGroupName=null,n.zonesEnabled=!1,n.zones=[]),a},i.credentialsChanged=function(n,t){const a={dirty:{}},r=n.backingData;if(n.credentials){const i=r.credentialsKeyedByAccount[n.credentials]||{regions:[],defaultKeyPair:null};r.filtered.regions=i.regions,H.chain(r.filtered.regions).some({name:n.region}).value()?e.extend(a.dirty,n.regionChanged(n,t).dirty):(n.region=null,a.dirty.region=!0),n.region&&e.extend(a.dirty,B(n).dirty),e.extend(a.dirty,u(n).dirty)}else n.region=null;return a}}))},configureImages:function(e){const n={dirty:{}};let t=null;return e.viewState.disableImageSelection||(e.region?(t=e.backingData.packageImages.filter((function(n){return n.amis&&n.amis[e.region]})).map((function(n){return{imageName:n.imageName,ami:n.amis?n.amis[e.region][0]:null}})),e.amiName&&!t.some((function(n){return n.imageName===e.amiName}))&&(n.dirty.amiName=!0,e.amiName=null)):e.amiName=null,e.backingData.filtered.images=t),n},configureSecurityGroupOptions:g,configureLoadBalancerOptions:h,refreshLoadBalancers:function(e,n){return i.listLoadBalancers("azure").then((function(t){e.backingData.loadBalancers=t,n||h(e)}))},refreshSecurityGroups:function(e,n){return r.refreshCache("securityGroups").then((function(){return a.getAllSecurityGroups().then((function(t){e.backingData.securityGroups=t,n||g(e)}))}))},getRegionalSecurityGroups:m,refreshInstanceTypes:function(e){return r.refreshCache("instanceTypes").then((function(){return l.getAllTypesByRegion().then((function(n){e.backingData.instanceTypes=n,u(e)}))}))},configureZones:p}}]);n("spinnaker.azure.cloneServerGroup.controller",[O,"spinnaker.azure.serverGroup.configure.service","spinnaker.azure.serverGroup.transformer",x]).controller("azureCloneServerGroupCtrl",["$scope","$uibModalInstance","$q","$state","serverGroupWriter","azureServerGroupConfigurationService","serverGroupCommand","application","title",function(e,n,t,a,r,i,l,s,o){function c(){if(e.$$destroyed)return;const n=e.taskMonitor.task.execution.stages.find((e=>"cloneServerGroup"===e.type));if(n&&n.context["deploy.server.groups"]){const t=n.context["deploy.server.groups"][e.command.region];if(t){const n={serverGroup:t,accountId:e.command.credentials,region:e.command.region,provider:"azure"};let r="^.^.^.clusters.serverGroup";a.includes("**.clusters.serverGroup")&&(r="^.serverGroup"),a.includes("**.clusters.cluster.serverGroup")&&(r="^.^.serverGroup"),a.includes("**.clusters")&&(r=".serverGroup"),a.go(r,n)}}}function d(){i.configureCommand(s,l).then((function(){const n=l.viewState.mode;"clone"!==n&&"create"!==n||(l.viewState.useAllImageSelection=!0),e.state.loaded=!0,function(){const e=l.viewState.mode;"clone"!==e&&"editPipeline"!==e||(T.markComplete("basic-settings"),T.markComplete("load-balancers"),T.markComplete("network-settings"),T.markComplete("security-groups"),T.markComplete("instance-type"),T.markComplete("zones"))}(),p(e.command.credentialsChanged(e.command,!0)),p(e.command.regionChanged(e.command,!0)),e.$watch("command.credentials",u(e.command.credentialsChanged)),e.$watch("command.region",u(e.command.regionChanged))}))}function u(n){return function(t,a){t!==a&&p(n(e.command))}}function p(e){e.dirty.loadBalancers&&(T.markDirty("load-balancers"),T.markDirty("network-settings")),e.dirty.securityGroups&&T.markDirty("security-groups"),e.dirty.instanceType&&T.markDirty("instance-type"),(e.dirty.zoneEnabled||e.dirty.zones)&&T.markDirty("zones")}e.pages={templateSelection:"azure/src/serverGroup/configure/wizard/templateSelection.html",basicSettings:"azure/src/serverGroup/configure/wizard/basicSettings/basicSettings.html",imageSettings:"azure/src/serverGroup/configure/wizard/image/imageSettings.html",healthSettings:"azure/src/serverGroup/configure/wizard/healthSettings/healthSettings.html",loadBalancers:"azure/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html",networkSettings:"azure/src/serverGroup/configure/wizard/networkSettings/networkSettings.html",securityGroups:"azure/src/serverGroup/configure/wizard/securityGroup/securityGroups.html",instanceType:"azure/src/serverGroup/configure/wizard/instanceType/instanceType.html",zones:"azure/src/serverGroup/configure/wizard/capacity/zones.html",tags:"azure/src/serverGroup/configure/wizard/tags/tags.html",advancedSettings:"azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html"},e.firewallsLabel=b.get("Firewalls"),e.title=o,e.applicationName=s.name,e.application=s,e.command=l,e.command.backingData=e.command.backingData||{},e.command.backingData.filtered=e.command.backingData.filtered||{},e.command.backingData.filtered.regions=e.command.backingData.filtered.regions||[],e.state={loaded:!1,requiresTemplateSelection:!!l.viewState.requiresTemplateSelection},this.templateSelectionText={copied:["account, region, subnet, cluster name (stack, details)","load balancers",b.get("firewalls"),"instance type","all fields on the Advanced Settings page"],notCopied:[],additionalCopyText:"If a server group exists in this cluster at the time of deployment, its scaling policies will be copied over to the new server group."},e.command.viewState.disableStrategySelection||this.templateSelectionText.notCopied.push("the deployment strategy (if any) used to deploy the most recent server group"),e.taskMonitor=new g({application:s,title:"Creating your server group",modalInstance:n,onTaskComplete:function(){s.serverGroups.refresh(),s.serverGroups.onNextRefresh(e,c)}}),this.submit=function(){if("editPipeline"===e.command.viewState.mode||"createPipeline"===e.command.viewState.mode)return n.close(e.command);e.taskMonitor.submit((function(){return r.cloneServerGroup(e.command,s)}))},this.cancel=function(){n.dismiss()},this.toggleSuspendedProcess=function(n){e.command.suspendedProcesses=e.command.suspendedProcesses||[];const t=e.command.suspendedProcesses.indexOf(n);-1===t?e.command.suspendedProcesses.push(n):e.command.suspendedProcesses.splice(t,1)},this.processIsSuspended=function(n){return e.command.suspendedProcesses.includes(n)},e.state.requiresTemplateSelection?e.state.loaded=!0:d(),this.templateSelected=()=>{e.state.requiresTemplateSelection=!1,d()},this.isValid=function(){return e.command&&e.command.application&&e.command.credentials&&e.command.instanceType&&e.command.region&&(!e.command.zonesEnabled||0!==e.command.zones.length)&&K.checkTags(e.command.instanceTags).isValid}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/templateSelection.html",'<deploy-initializer\n cloud-provider="azure"\n command="command"\n application="application"\n parent-state="state"\n dismiss="ctrl.cancel()"\n template-selection-text="ctrl.templateSelectionText"\n on-template-selected="ctrl.templateSelected()"\n></deploy-initializer>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/basicSettings/basicSettings.html",'<div class="container-fluid form-horizontal" ng-controller="azureServerGroupBasicSettingsCtrl as basicSettingsCtrl">\n <div class="modal-body">\n <ng-form name="basicSettings">\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Account</div>\n <div class="col-md-7">\n <account-select-field\n required\n read-only="command.viewState.readOnlyFields.credentials"\n component="command"\n field="credentials"\n accounts="command.backingData.accounts"\n provider="\'azure\'"\n ></account-select-field>\n </div>\n </div>\n <region-select-field\n required\n read-only="command.viewState.readOnlyFields.region"\n label-columns="3"\n component="command"\n field="region"\n account="command.credentials"\n provider="\'azure\'"\n regions="command.backingData.filtered.regions"\n ></region-select-field>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n Stack\n <help-field key="azure.serverGroup.stack"></help-field>\n </div>\n <div class="col-md-7">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-pattern="basicSettingsCtrl.stackPattern"\n name="stack"\n ng-model="command.stack"\n />\n </div>\n </div>\n <div class="form-group row slide-in" ng-if="basicSettings.stack.$error.pattern">\n <div class="col-sm-9 col-sm-offset-2 error-message">\n <span>Stack can only contain letters and numbers.</span>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">\n Detail\n <help-field key="azure.serverGroup.detail"></help-field>\n </div>\n <div class="col-md-7">\n <input\n required\n type="text"\n class="form-control input-sm"\n ng-pattern="basicSettingsCtrl.detailPattern"\n name="details"\n ng-model="command.freeFormDetails"\n />\n </div>\n </div>\n <div class="form-group row slide-in" ng-if="basicSettings.details.$error.pattern">\n <div class="col-sm-9 col-sm-offset-2 error-message">\n <span>Detail can only contain letters, numbers, and dashes(-).</span>\n </div>\n </div>\n <div class="form-group" ng-if="!command.viewState.disableImageSelection">\n <div class="col-md-3 sm-label-right">\n Image\n <help-field key="azure.serverGroup.imageName"></help-field>\n </div>\n <div class="col-md-9">\n <ui-select\n class="form-control input-sm"\n required\n ng-model="command.selectedImage"\n on-select="basicSettingsCtrl.imageChanged($item)"\n >\n <ui-select-match placeholder="Pick an image">{{$select.selected.imageName}}</ui-select-match>\n <ui-select-choices repeat="image in command.images | regional:command.region | filter:$select.search">\n <span ng-bind-html="image.imageName"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <deployment-strategy-selector\n ng-if="!command.viewState.disableStrategySelection && command.selectedProvider"\n command="command"\n ></deployment-strategy-selector>\n <div class="form-group" ng-if="!command.viewState.hideClusterNamePreview">\n <div class="col-md-12">\n <div\n class="well-compact"\n ng-class="basicSettingsCtrl.showPreviewAsWarning() ? \'alert alert-warning\' : \'well\'"\n >\n <h5 class="text-center">\n <p>Your server group will be in the cluster:</p>\n <p>\n <strong>\n {{basicSettingsCtrl.getNamePreview()}}\n <span ng-if="basicSettingsCtrl.createsNewCluster()"> (new cluster)</span>\n </strong>\n </p>\n <div\n class="text-left"\n ng-if="!basicSettingsCtrl.createsNewCluster() && command.viewState.mode === \'create\' && latestServerGroup"\n >\n <p>There is already a server group in this cluster. Do you want to clone it?</p>\n <p>\n Cloning copies the entire configuration from the selected server group, allowing you to modify\n whichever fields (e.g. image) you need to change in the new server group.\n </p>\n <p>\n To clone a server group, select "Clone" from the "Server Group Actions" menu in the details view of\n the server group.\n </p>\n <p>\n <a href ng-click="basicSettingsCtrl.navigateToLatestServerGroup()">\n Go to details for {{latestServerGroup.name}}\n </a>\n </p>\n </div>\n </h5>\n </div>\n </div>\n </div>\n </ng-form>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/image/imageSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-image-settings-selector command="command"></azure-server-group-image-settings-selector>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/healthSettings/healthSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-health-settings-selector command="command"></azure-server-group-health-settings-selector>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html",'<div class="row">\n <azure-server-group-load-balancers-selector command="command"></azure-server-group-load-balancers-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/networkSettings/networkSettings.html",'<div class="row">\n <azure-server-group-network-settings-selector command="command"></azure-server-group-network-settings-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/securityGroup/securityGroups.html",'<div class="row">\n <azure-server-group-security-groups-selector command="command"></azure-server-group-security-groups-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/instanceType/instanceType.html",'<div ng-show="!!(command.region)">\n <v2-instance-archetype-selector ng-if="command.region" command="command"></v2-instance-archetype-selector>\n <div style="padding: 0 15px">\n <v2-instance-type-selector\n ng-if="command.viewState.instanceProfile && !(command.viewState.instanceProfile === \'custom\' || command.viewState.instanceProfile === \'buildCustom\' )"\n command="command"\n ></v2-instance-type-selector>\n </div>\n</div>\n<h5 class="text-center" ng-if="!command.region">Please select a region.</h5>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/capacity/zones.html",'<ng-form name="zonesSubForm">\n <div class="container-fluid form-horizontal">\n <azure-zone-selector command="command"></azure-zone-selector>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/tags/tags.html",'<ng-form name="zonesSubForm">\n <div class="container-fluid form-horizontal">\n <azure-tags-selector command="command"></azure-tags-selector>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html",'<div class="row">\n <div class="col-md-12">\n <azure-server-group-advanced-settings-selector command="command"></azure-server-group-advanced-settings-selector>\n </div>\n</div>\n')}]);e.module("spinnaker.azure.serverGroupCommandBuilder.service",["spinnaker.azure.image.reader","spinnaker.azure.serverGroup.transformer"]).factory("azureServerGroupCommandBuilder",["$q","azureImageReader","azureServerGroupTransformer",function(n,t,a){function r(e,n){const a=(n=n||{}).account||e.defaultCredentials.azure,r=n.region||e.defaultRegions.azure;return t.findImages({provider:"azure"}).then((function(t){return{application:e.name,credentials:a,region:r,images:t,loadBalancers:[],selectedVnetSubnets:[],strategy:"",sku:{capacity:1},zonesEnabled:!1,zones:[],instanceTags:{},dataDisks:[],selectedProvider:"azure",viewState:{instanceProfile:"custom",allImageSelection:null,useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!0,mode:n.mode||"create",disableStrategySelection:!0,loadBalancersConfigured:!1,networkSettingsConfigured:!1,securityGroupsConfigured:!1},enableInboundNAT:!1}}))}return{buildNewServerGroupCommand:r,buildNewServerGroupCommandForPipeline:function(){return n.when({viewState:{requiresTemplateSelection:!0}})},buildServerGroupCommandFromExisting:function(e,t,r){r=r||"clone";const i=B.parseServerGroupName(t.name),l={application:e.name,strategy:"",stack:i.stack,freeFormDetails:i.freeFormDetails,credentials:t.account,loadBalancers:t.loadBalancers,selectedSubnets:t.selectedVnetSubnets,selectedVnet:t.selectedVnet,securityGroups:t.securityGroups,loadBalancerName:t.loadBalancerName,loadBalancerType:t.loadBalancerType,securityGroupName:t.securityGroupName,region:t.region,vnet:t.vnet,vnetResourceGroup:t.vnetResourceGroup,subnet:t.subnet,zones:t.zones,zonesEnabled:t.zones&&t.zones.length>0,instanceTags:{},dataDisks:t.dataDisks,sku:t.sku,capacity:{min:t.capacity.min,max:t.capacity.max,desired:t.capacity.desired},tags:[],instanceType:t.sku.name,selectedProvider:"azure",source:{account:t.account,region:t.region,serverGroupName:t.name,asgName:t.name},viewState:{allImageSelection:null,useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!1,listImplicitSecurityGroups:!1,mode:r,disableStrategySelection:!0},enableInboundNAT:t.enableInboundNAT};return void 0!==t.customScriptsSettings&&(l.customScriptsSettings={},l.customScriptsSettings.commandToExecute=t.customScriptsSettings.commandToExecute,H.isEmpty(t.customScriptsSettings.fileUris)||a.parseCustomScriptsSettings(t,l)),n.when(l)},buildServerGroupCommandFromPipeline:function(n,t){const a=H.cloneDeep(t),i=a.region;return r(n,{account:a.account,region:i}).then((function(n){const r={disableImageSelection:!0,useSimpleCapacity:!0,mode:"editPipeline",submitButtonLabel:"Done",instanceProfile:t.viewState.instanceProfile,instanceTypeDetails:t.viewState.instanceTypeDetails},l={region:i,credentials:a.account,viewState:r};t.viewState.instanceTypeDetails&&(l.instanceType=t.viewState.instanceTypeDetails.name),a.strategy=a.strategy||"";return e.extend({},n,a,l)}))}}}]);class re extends X.Component{constructor(e){super(e),this.state={verified:!1},this.handleVerification=e=>{this.setState({verified:e})}}render(){const{onSubmit:e,onCancel:n,isValid:t,account:a}=this.props,{verified:r}=this.state;return X.createElement("div",{className:"modal-footer"},X.createElement(N,{expectedValue:a,onValidChange:this.handleVerification}),X.createElement("button",{className:"btn btn-default",onClick:n},"Cancel"),X.createElement("button",{type:"submit",className:"btn btn-primary",onClick:e,disabled:!t||!r},"Submit"))}}const ie=class extends X.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal.apply(null,e)},this.submit=()=>{const{command:e,taskMonitor:n}=this.state,{serverGroup:t,application:a}=this.props;n.submit((()=>P.serverGroupWriter.rollbackServerGroup(t,a,e)))},this.filterServerGroups=e=>e.filter((e=>0!==e.instanceCounts.total)).sort(((e,n)=>n.name.localeCompare(e.name))),this.isValid=()=>void 0!==this.state.command.rollbackContext.restoreServerGroupName,this.handleServerGroupChange=e=>{const{disabledServerGroups:n}=this.props,t={...this.state.command};t.rollbackContext.restoreServerGroupName=e.value;const a=this.filterServerGroups(n).find((function(n){return n.name===e.value}));t.targetSize=a.capacity.max,this.setState({command:t})},this.handleTaskReasonChange=e=>{const n={...this.state.command};n.reason=e,this.setState({command:n})};const{application:n,serverGroup:t}=e;this.state={taskMonitor:new g({application:n,title:"Rolling back your server group",modalInstance:g.modalInstanceEmulation((()=>this.props.dismissModal()))}),submitting:!0,command:{interestingHealthProviderNames:[],rollbackType:"EXPLICIT",rollbackContext:{rollbackServerGroupName:t.name,enableAndDisableOnly:!0}}}}static show(e){return d.show(ie,e,{})}render(){const{command:e,taskMonitor:n,submitting:t}=this.state,{serverGroup:a,disabledServerGroups:r}=this.props,i=this.isValid(),l=this.filterServerGroups(r).map((e=>({label:e.name,value:e.name})));return X.createElement(q,{onHide:this.close},X.createElement(L,{monitor:n}),t&&X.createElement("form",{role:"form"},X.createElement(u,{dismiss:this.close}),X.createElement(q.Header,null,X.createElement(q.Title,null,"Rollback ",a.name)),X.createElement(q.Body,null,X.createElement("div",{className:"row"},X.createElement("div",{className:"col-sm-3 sm-label-right"},"Restore to"),X.createElement("div",{className:"col-sm-6"},X.createElement(W,{value:e.rollbackContext.restoreServerGroupName,onChange:this.handleServerGroupChange,options:l}))),X.createElement(R,{reason:e.taskReason,onChange:this.handleTaskReasonChange})),X.createElement(re,{onSubmit:this.submit,onCancel:this.close,isValid:i,account:a.account})))}};let le=ie;le.defaultProps={closeModal:p,dismissModal:p};e.module("spinnaker.azure.serverGroup.details.controller",[O,"spinnaker.azure.serverGroupCommandBuilder.service",x]).controller("azureServerGroupDetailsCtrl",["$scope","$state","$templateCache","app","serverGroup","azureServerGroupCommandBuilder","$uibModal","serverGroupWriter",function(n,t,a,r,l,s,o,c){function d(){const a=function(){let e=H.find(r.serverGroups.data,(function(e){return e.name===l.name&&e.account===l.accountId&&e.region===l.region}));return e||r.loadBalancers.data.some((function(n){if(n.account===l.accountId&&n.region===l.region)return n.serverGroups.some((function(n){if(n.name===l.name)return e=n,!0}))})),e||t.go("^"),e}();return M.getServerGroup(r.name,l.accountId,l.region,l.name).then((function(i){if(n.state.loading=!1,e.extend(i,a),i.account=l.accountId,n.serverGroup=i,H.isEmpty(n.serverGroup))t.go("^");else{if(n.image=i.image?i.image:void 0,i.image&&i.image.description){i.image.description.split(", ").forEach((function(e){const n=e.split("=");2===n.length&&"ancestor_name"===n[0]&&(i.image.baseImage=n[1])}))}i.launchConfig&&i.launchConfig.securityGroups&&(n.securityGroups=H.chain(i.launchConfig.securityGroups).map((function(e){return H.find(r.securityGroups.data,{accountName:l.accountId,region:l.region,id:e})||H.find(r.securityGroups.data,{accountName:l.accountId,region:l.region,name:e})})).compact().value())}}))}n.state={loading:!0},n.firewallsLabel=b.get("Firewalls"),this.application=r,d().then((()=>{n.$$destroyed||r.serverGroups.onRefresh(n,d)})),this.destroyServerGroup=function(){const e=n.serverGroup,a={name:e.name,accountId:e.account,region:e.region},l={application:r,title:"Destroying "+e.name,onTaskComplete:function(){t.includes("**.serverGroup",a)&&t.go("^")}},s={header:"Really destroy "+e.name+"?",buttonText:"Destroy "+e.name,account:e.account,taskMonitorConfig:l,submitMethod:function(){return c.destroyServerGroup(e,r)}};U.addDestroyWarningMessage(r,e,s),i.confirm(s)},this.disableServerGroup=function(){const e=n.serverGroup,t={application:r,title:"Disabling "+e.name},a={header:"Really disable "+e.name+"?",buttonText:"Disable "+e.name,account:e.account,taskMonitorConfig:t,submitMethod:()=>c.disableServerGroup(e,r)};U.addDisableWarningMessage(r,e,a),i.confirm(a)},this.enableServerGroup=function(){const t=n.serverGroup,a={application:r,title:"Enabling "+t.name};i.confirm({header:"Really enable "+t.name+"?",buttonText:"Enable "+t.name,account:t.account,taskMonitorConfig:a,submitMethod:n=>c.enableServerGroup(t,r,e.extend(n,{interestingHealthProviderNames:[]}))})},this.rollbackServerGroup=()=>{const e=n.serverGroup,t=H.find(r.clusters,{name:e.cluster,account:e.account}),a=H.filter(t.serverGroups,{isDisabled:!0,region:e.region});le.show({application:r,serverGroup:e,disabledServerGroups:a})},this.cloneServerGroup=e=>{o.open({templateUrl:"azure/src/serverGroup/configure/wizard/serverGroupWizard.html",controller:"azureCloneServerGroupCtrl as ctrl",size:"lg",resolve:{title:()=>"Clone "+e.name,application:()=>r,serverGroupCommand:()=>s.buildServerGroupCommandFromExisting(r,e)}})},this.truncateCommitHash=function(){return n.serverGroup&&n.serverGroup.buildInfo&&n.serverGroup.buildInfo.commit?n.serverGroup.buildInfo.commit.substring(0,8):null}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/serverGroupWizard.html",'<div>\n <div ng-if="state.requiresTemplateSelection">\n <ng-include src="pages.templateSelection"></ng-include>\n </div>\n <div ng-if="!state.loaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div>\n <form name="serverGroupWizardForm" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard\n ng-show="state.loaded && !state.requiresTemplateSelection"\n heading="{{title}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="basic-settings" label="Basic Settings" hide-subheading="true">\n <ng-include src="pages.basicSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="image-settings" label="Image">\n <ng-include src="pages.imageSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="load-balancers" label="Load Balancers" mark-complete-on-view="false">\n <ng-include src="pages.loadBalancers"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="network-settings" label="Network Settings" mark-complete-on-view="false">\n <ng-include src="pages.networkSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="health-settings" label="Health" mark-complete-on-view="false">\n <ng-include src="pages.healthSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="security-groups" label="{{firewallsLabel}}" mark-complete-on-view="false" done="true">\n <ng-include src="pages.securityGroups"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="instance-type" label="Instance Type" mark-complete-on-view="false" done="false">\n <ng-include src="pages.instanceType"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="zones" label="Zones" mark-complete-on-view="false" done="false">\n <ng-include src="pages.zones"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="tags" label="Tags" mark-complete-on-view="false" done="true">\n <ng-include src="pages.tags"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="advanced-settings" label="Advanced Settings" mark-complete-on-view="false" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer" ng-if="state.loaded">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default btn-cancel" ng-click="ctrl.cancel()">\n Cancel\n </button>\n <submit-button\n is-disabled="taskMonitor.submitting || !ctrl.isValid()"\n label="command.viewState.submitButtonLabel"\n submitting="taskMonitor.submitting"\n on-click="serverGroupWizardForm.$valid && ctrl.submit()"\n is-new="true"\n ></submit-button>\n </div>\n </form>\n </div>\n</div>\n')}]);n("spinnaker.azure.serverGroup.details.azure",["spinnaker.azure.serverGroup.details.controller"]);n("spinnaker.azure.validation.applicationName",[]).factory("azureApplicationNameValidator",(function(){return{validate:function(e){const n=[];return e&&e.length&&function(e,n){/^([a-zA-Z][a-zA-Z0-9]*)?$/.test(e)||n.push("The application name must begin with a letter and must contain only letters or digits. No special characters are allowed.")}(e,n),{warnings:[],errors:n}}}})).run(["azureApplicationNameValidator",function(e){V.registerValidator("azure",e)}]);!function(e,n){void 0===n&&(n={});var t=n.insertAt;if(e&&"undefined"!=typeof document){var a=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===t&&a.firstChild?a.insertBefore(r,a.firstChild):a.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}('.cloud-provider-logo .icon-azure {\n -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!-- Generator%3A Adobe Illustrator 22.1.0%2C SVG Export Plug-In . SVG Version%3A 6.00 Build 0) --%3E%3Csvg version%3D%221.1%22 id%3D%22Layer_1%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22 x%3D%220px%22 y%3D%220px%22%09 viewBox%3D%220 0 48 48%22 style%3D%22enable-background%3Anew 0 0 48 48%3B%22 xml%3Aspace%3D%22preserve%22%3E%3Cstyle type%3D%22text%2Fcss%22%3E%09.st0%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2300A2D8%3B%7D%09.st1%7Bfill%3A%23F79E1C%3B%7D%09.st2%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232ABAEC%3B%7D%09.st3%7Bfill%3A%23F7B218%3B%7D%09.st4%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3Anone%3B%7D%09.st5%7Bfill%3A%2300A2D8%3B%7D%09.st6%7Bfill%3A%232ABAEC%3B%7D%09.st7%7Bfill%3A%23323A45%3B%7D%09.st8%7Bfill%3A%2388909B%3B%7D%09.st9%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st10%7Bfill%3A%23A3BF3A%3B%7D%09.st11%7Bfill%3A%2380A23E%3B%7D%09.st12%7Bfill%3A%237B4D87%3B%7D%09.st13%7Bfill%3A%232F75BB%3B%7D%09.st14%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2385C9D5%3B%7D%09.st15%7Bopacity%3A0.15%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st16%7Bfill%3A%23A5D9E2%3B%7D%09.st17%7Bfill%3A%2385C9D5%3B%7D%09.st18%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23323A45%3B%7D%09.st19%7Bfill%3A%23FFFFFF%3B%7D%09.st20%7Bfill%3A%23DAEFF3%3B%7D%09.st21%7Bfill%3A%232A65AF%3B%7D%09.st22%7Bfill%3A%23F6ECF4%3B%7D%09.st23%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232F75BB%3B%7D%09.st24%7Bfill%3Anone%3B%7D%09.st25%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9BA19%3B%7D%09.st26%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23A3BF3A%3B%7D%09.st27%7Bfill%3A%23F6931D%3B%7D%09.st28%7Bfill%3A%235E6D80%3B%7D%09.st29%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3B%7D%09.st30%7Bfill%3A%2300B8E2%3B%7D%09.st31%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%235E6D80%3B%7D%09.st32%7Bfill%3Anone%3Bstroke%3A%2385C9D5%3Bstroke-width%3A0%3Bstroke-linecap%3Around%3Bstroke-linejoin%3Around%3B%7D%09.st33%7Bfill%3A%232A89CA%3B%7D%09.st34%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237B4D87%3B%7D%09.st35%7Bopacity%3A0.3%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st36%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3B%7D%09.st37%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2378B843%3B%7D%09.st38%7Bfill%3A%2378B843%3B%7D%09.st39%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23EDF0F4%3B%7D%09.st40%7Bfill%3A%23005BA3%3B%7D%09.st41%7Bfill%3A%230F80B0%3B%7D%09.st42%7Bfill%3A%23005F87%3B%7D%09.st43%7Bfill%3A%23B7D332%3B%7D%09.st44%7Bfill%3A%237FB900%3B%7D%09.st45%7Bopacity%3A0.6%3Bfill%3A%23FFFFFF%3B%7D%09.st46%7Bopacity%3A0.4%3Bfill%3A%23FFFFFF%3B%7D%09.st47%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_13_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st48%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_64_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st49%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_65_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st50%7Bfill%3A%2373BDCD%3B%7D%09.st51%7Bopacity%3A0.6%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st52%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3Bstroke%3A%23FFFFFF%3Bstroke-width%3A4%3Bstroke-miterlimit%3A10%3B%7D%09.st53%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3B%7D%09.st54%7Bclip-path%3Aurl(%23XMLID_67_)%3Bfill%3Anone%3B%7D%09.st55%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F7B218%3B%7D%09.st56%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_69_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st57%7Bopacity%3A0.8%3Bfill%3A%23FFFFFF%3B%7D%09.st58%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_79_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st59%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23DB5B26%3B%7D%09.st60%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F58B1F%3B%7D%09.st61%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_84_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st62%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23404B59%3B%7D%09.st63%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_118_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st64%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23D1B0D3%3B%7D%09.st65%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_119_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st66%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2315B2E7%3B%7D%09.st67%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23E1F3F8%3B%7D%09.st68%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_120_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st69%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_124_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st70%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_125_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st71%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_126_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st72%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237C8737%3B%7D%09.st73%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_127_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st74%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_130_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st75%7Bfill%3A%23CCCBCB%3B%7D%09.st76%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2388909B%3B%7D%09.st77%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st78%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_131_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st79%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_133_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st80%7Bdisplay%3Anone%3B%7D%09.st81%7Bfill%3A%2345B6F4%3B%7D%09.st82%7Bfill%3A%2389919C%3B%7D%09.st83%7Bfill%3A%2361ADD1%3B%7D%09.st84%7Bfill%3A%233899C6%3B%7D%09.st85%7Bfill%3A%23F78F08%3B%7D%09.st86%7Bfill%3A%23C1BFBC%3B%7D%09.st87%7Bfill%3A%237A7A7A%3B%7D%09.st88%7Bfill%3A%23B3B4B5%3B%7D%09.st89%7Bopacity%3A0.48%3B%7D%09.st90%7Bfill%3A%23A0A1A2%3B%7D%09.st91%7Bfill%3A%23A1DEF0%3B%7D%09.st92%7Bfill%3A%23804998%3B%7D%09.st93%7Bfill%3A%230072C6%3B%7D%09.st94%7Bfill%3A%2359B4D9%3B%7D%09.st95%7Bfill%3A%233999C6%3B%7D%09.st96%7Bfill%3A%230078D7%3B%7D%09.st97%7Bfill%3A%23D1B972%3B%7D%09.st98%7Bfill%3A%23FEE087%3B%7D%09.st99%7Bfill%3A%23B1CE2D%3B%7D%09.st100%7Bfill%3A%237FBA00%3B%7D%09.st101%7Bfill%3A%23FCD116%3B%7D%09.st102%7Bfill%3A%23719904%3B%7D%09.st103%7Bfill%3A%23B8D432%3B%7D%09.st104%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23804898%3B%7D%09.st105%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%236B2980%3B%7D%09.st106%7Bfill%3A%236B2980%3B%7D%09.st107%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st108%7Bopacity%3A0.2%3Bfill%3A%231E1E1E%3Benable-background%3Anew %3B%7D%09.st109%7Bfill%3A%2333BCF0%3B%7D%09.st110%7Bopacity%3A0.2%3Bfill%3A%23636363%3B%7D%09.st111%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_134_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st112%7Bfill%3A%238B77B6%3B%7D%09.st113%7Bfill%3A%239B6CAC%3B%7D%09.st114%7Bfill%3A%23874B94%3B%7D%09.st115%7Bopacity%3A0.4%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st116%7Bopacity%3A0.8%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st117%7Bopacity%3A0.6%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st118%7Bopacity%3A0.25%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st119%7Bfill%3A%23DD5900%3B%7D%09.st120%7Bfill%3A%23FF8C00%3B%7D%09.st121%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%233E3E3E%3B%7D%09.st122%7Bfill%3Aurl(%23path3060_1_)%3B%7D%09.st123%7Bfill%3A%231870C5%3B%7D%09.st124%7Bfill%3A%2372BFDF%3B%7D%09.st125%7Bfill%3A%233C3938%3B%7D%09.st126%7Bfill%3A%230072AC%3B%7D%09.st127%7Bfill%3A%230079B6%3B%7D%09.st128%7Bfill%3A%2300A2D9%3B%7D%09.st129%7Bfill%3A%23BFDC34%3B%7D%09.st130%7Bfill%3A%23898989%3B%7D%09.st131%7Bfill%3A%23EDF0F5%3B%7D%09.st132%7Bfill%3A%23A3A4A7%3B%7D%09.st133%7Bfill%3A%23353535%3B%7D%09.st134%7Bfill%3A%23FF8C02%3B%7D%09.st135%7Bfill%3A%2300AC8C%3B%7D%09.st136%7Bfill%3A%236EC2E9%3B%7D%09.st137%7Bfill%3A%23442359%3B%7D%09.st138%7Bfill%3A%236DC0E6%3B%7D%09.st139%7Bfill%3A%23432056%3B%7D%09.st140%7Bfill%3A%2386CAD7%3B%7D%09.st141%7Bfill%3A%23009E48%3B%7D%09.st142%7Bopacity%3A0.2%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st143%7Bfill%3A%2368217A%3B%7D%09.st144%7Bfill%3A%23E5E5E5%3B%7D%09.st145%7Bopacity%3A0.15%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st146%7Bfill%3A%233898C6%3B%7D%09.st147%7Bfill%3A%2380BA42%3B%7D%09.st148%7Bfill%3A%23B3D234%3B%7D%09.st149%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9F9F9%3B%7D%09.st150%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23008EBE%3B%7D%09.st151%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F1F1F2%3B%7D%09.st152%7Bfill%3A%23BAD80A%3B%7D%09.st153%7Bclip-path%3Aurl(%23SVGID_2_)%3B%7D%09.st154%7Bfill%3A%2300BCF2%3B%7D%09.st155%7Bfill%3A%235AB4DA%3B%7D%09.st156%7Bfill%3Anone%3Bstroke%3A%235AB4DA%3Bstroke-width%3A0.75%3Bstroke-miterlimit%3A10%3B%7D%09.st157%7Bfill%3A%233898C5%3B%7D%09.st158%7Bfill%3A%237A7B7B%3B%7D%09.st159%7Bfill%3A%23545555%3B%7D%09.st160%7Bfill%3A%23D6EAF3%3B%7D%09.st161%7Bfill%3A%23009580%3B%7D%09.st162%7Bfill%3A%23BA141A%3B%7D%09.st163%7Bfill%3A%237AC3E1%3B%7D%09.st164%7Bfill%3A%23E27226%3B%7D%09.st165%7Bfill%3A%23FF9D26%3B%7D%09.st166%7Bopacity%3A0.12%3Bfill%3A%23BA141A%3B%7D%09.st167%7Bfill%3A%233C98C5%3B%7D%09.st168%7Bfill%3A%235AB3D8%3B%7D%09.st169%7Bfill%3A%23AAD8EB%3B%7D%09.st170%7Bfill%3A%23797979%3B%7D%09.st171%7Bfill%3A%23959595%3B%7D%09.st172%7Bfill%3A%23D1D1D1%3B%7D%09.st173%7Bclip-path%3Aurl(%23SVGID_4_)%3B%7D%09.st174%7Bfill%3A%2333A2E5%3B%7D%09.st175%7Bfill%3A%2371C2EA%3B%7D%09.st176%7Bfill%3A%23005091%3B%7D%09.st177%7Bclip-path%3Aurl(%23SVGID_6_)%3B%7D%09.st178%7Bfill%3A%23ACD64D%3B%7D%3C%2Fstyle%3E%3Cg%3E%09%3Cg%3E%09%09%3Cg%3E%09%09%09%3Cg%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2226.5%2C4.5 12.5%2C15.5 1.5%2C35.5 11.5%2C35.5 %09%09%09%09%22%2F%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2227.5%2C7.5 21.5%2C22.5 32.5%2C35.5 11.5%2C40.5 46.5%2C40.5 %09%09%09%09%22%2F%3E%09%09%09%3C%2Fg%3E%09%09%3C%2Fg%3E%09%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!-- Generator%3A Adobe Illustrator 22.1.0%2C SVG Export Plug-In . SVG Version%3A 6.00 Build 0) --%3E%3Csvg version%3D%221.1%22 id%3D%22Layer_1%22 xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22 xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22 x%3D%220px%22 y%3D%220px%22%09 viewBox%3D%220 0 48 48%22 style%3D%22enable-background%3Anew 0 0 48 48%3B%22 xml%3Aspace%3D%22preserve%22%3E%3Cstyle type%3D%22text%2Fcss%22%3E%09.st0%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2300A2D8%3B%7D%09.st1%7Bfill%3A%23F79E1C%3B%7D%09.st2%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232ABAEC%3B%7D%09.st3%7Bfill%3A%23F7B218%3B%7D%09.st4%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3Anone%3B%7D%09.st5%7Bfill%3A%2300A2D8%3B%7D%09.st6%7Bfill%3A%232ABAEC%3B%7D%09.st7%7Bfill%3A%23323A45%3B%7D%09.st8%7Bfill%3A%2388909B%3B%7D%09.st9%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st10%7Bfill%3A%23A3BF3A%3B%7D%09.st11%7Bfill%3A%2380A23E%3B%7D%09.st12%7Bfill%3A%237B4D87%3B%7D%09.st13%7Bfill%3A%232F75BB%3B%7D%09.st14%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2385C9D5%3B%7D%09.st15%7Bopacity%3A0.15%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st16%7Bfill%3A%23A5D9E2%3B%7D%09.st17%7Bfill%3A%2385C9D5%3B%7D%09.st18%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23323A45%3B%7D%09.st19%7Bfill%3A%23FFFFFF%3B%7D%09.st20%7Bfill%3A%23DAEFF3%3B%7D%09.st21%7Bfill%3A%232A65AF%3B%7D%09.st22%7Bfill%3A%23F6ECF4%3B%7D%09.st23%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%232F75BB%3B%7D%09.st24%7Bfill%3Anone%3B%7D%09.st25%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9BA19%3B%7D%09.st26%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23A3BF3A%3B%7D%09.st27%7Bfill%3A%23F6931D%3B%7D%09.st28%7Bfill%3A%235E6D80%3B%7D%09.st29%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3B%7D%09.st30%7Bfill%3A%2300B8E2%3B%7D%09.st31%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%235E6D80%3B%7D%09.st32%7Bfill%3Anone%3Bstroke%3A%2385C9D5%3Bstroke-width%3A0%3Bstroke-linecap%3Around%3Bstroke-linejoin%3Around%3B%7D%09.st33%7Bfill%3A%232A89CA%3B%7D%09.st34%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237B4D87%3B%7D%09.st35%7Bopacity%3A0.3%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st36%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3B%7D%09.st37%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2378B843%3B%7D%09.st38%7Bfill%3A%2378B843%3B%7D%09.st39%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23EDF0F4%3B%7D%09.st40%7Bfill%3A%23005BA3%3B%7D%09.st41%7Bfill%3A%230F80B0%3B%7D%09.st42%7Bfill%3A%23005F87%3B%7D%09.st43%7Bfill%3A%23B7D332%3B%7D%09.st44%7Bfill%3A%237FB900%3B%7D%09.st45%7Bopacity%3A0.6%3Bfill%3A%23FFFFFF%3B%7D%09.st46%7Bopacity%3A0.4%3Bfill%3A%23FFFFFF%3B%7D%09.st47%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_13_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st48%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_64_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st49%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_65_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st50%7Bfill%3A%2373BDCD%3B%7D%09.st51%7Bopacity%3A0.6%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st52%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3Bstroke%3A%23FFFFFF%3Bstroke-width%3A4%3Bstroke-miterlimit%3A10%3B%7D%09.st53%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2380A23E%3B%7D%09.st54%7Bclip-path%3Aurl(%23XMLID_67_)%3Bfill%3Anone%3B%7D%09.st55%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F7B218%3B%7D%09.st56%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_69_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st57%7Bopacity%3A0.8%3Bfill%3A%23FFFFFF%3B%7D%09.st58%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_79_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st59%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23DB5B26%3B%7D%09.st60%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F58B1F%3B%7D%09.st61%7Bopacity%3A0.35%3Bclip-path%3Aurl(%23XMLID_84_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st62%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23404B59%3B%7D%09.st63%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_118_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st64%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23D1B0D3%3B%7D%09.st65%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_119_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st66%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2315B2E7%3B%7D%09.st67%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23E1F3F8%3B%7D%09.st68%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_120_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st69%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_124_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st70%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_125_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st71%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_126_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st72%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%237C8737%3B%7D%09.st73%7Bopacity%3A0.3%3Bclip-path%3Aurl(%23XMLID_127_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st74%7Bopacity%3A0.15%3Bclip-path%3Aurl(%23XMLID_130_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st75%7Bfill%3A%23CCCBCB%3B%7D%09.st76%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%2388909B%3B%7D%09.st77%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st78%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_131_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st79%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_133_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st80%7Bdisplay%3Anone%3B%7D%09.st81%7Bfill%3A%2345B6F4%3B%7D%09.st82%7Bfill%3A%2389919C%3B%7D%09.st83%7Bfill%3A%2361ADD1%3B%7D%09.st84%7Bfill%3A%233899C6%3B%7D%09.st85%7Bfill%3A%23F78F08%3B%7D%09.st86%7Bfill%3A%23C1BFBC%3B%7D%09.st87%7Bfill%3A%237A7A7A%3B%7D%09.st88%7Bfill%3A%23B3B4B5%3B%7D%09.st89%7Bopacity%3A0.48%3B%7D%09.st90%7Bfill%3A%23A0A1A2%3B%7D%09.st91%7Bfill%3A%23A1DEF0%3B%7D%09.st92%7Bfill%3A%23804998%3B%7D%09.st93%7Bfill%3A%230072C6%3B%7D%09.st94%7Bfill%3A%2359B4D9%3B%7D%09.st95%7Bfill%3A%233999C6%3B%7D%09.st96%7Bfill%3A%230078D7%3B%7D%09.st97%7Bfill%3A%23D1B972%3B%7D%09.st98%7Bfill%3A%23FEE087%3B%7D%09.st99%7Bfill%3A%23B1CE2D%3B%7D%09.st100%7Bfill%3A%237FBA00%3B%7D%09.st101%7Bfill%3A%23FCD116%3B%7D%09.st102%7Bfill%3A%23719904%3B%7D%09.st103%7Bfill%3A%23B8D432%3B%7D%09.st104%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23804898%3B%7D%09.st105%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%236B2980%3B%7D%09.st106%7Bfill%3A%236B2980%3B%7D%09.st107%7Bopacity%3A0.3%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st108%7Bopacity%3A0.2%3Bfill%3A%231E1E1E%3Benable-background%3Anew %3B%7D%09.st109%7Bfill%3A%2333BCF0%3B%7D%09.st110%7Bopacity%3A0.2%3Bfill%3A%23636363%3B%7D%09.st111%7Bopacity%3A0.1%3Bclip-path%3Aurl(%23XMLID_134_)%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23FFFFFF%3B%7D%09.st112%7Bfill%3A%238B77B6%3B%7D%09.st113%7Bfill%3A%239B6CAC%3B%7D%09.st114%7Bfill%3A%23874B94%3B%7D%09.st115%7Bopacity%3A0.4%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st116%7Bopacity%3A0.8%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st117%7Bopacity%3A0.6%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st118%7Bopacity%3A0.25%3Bfill%3A%237FBA00%3Benable-background%3Anew %3B%7D%09.st119%7Bfill%3A%23DD5900%3B%7D%09.st120%7Bfill%3A%23FF8C00%3B%7D%09.st121%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%233E3E3E%3B%7D%09.st122%7Bfill%3Aurl(%23path3060_1_)%3B%7D%09.st123%7Bfill%3A%231870C5%3B%7D%09.st124%7Bfill%3A%2372BFDF%3B%7D%09.st125%7Bfill%3A%233C3938%3B%7D%09.st126%7Bfill%3A%230072AC%3B%7D%09.st127%7Bfill%3A%230079B6%3B%7D%09.st128%7Bfill%3A%2300A2D9%3B%7D%09.st129%7Bfill%3A%23BFDC34%3B%7D%09.st130%7Bfill%3A%23898989%3B%7D%09.st131%7Bfill%3A%23EDF0F5%3B%7D%09.st132%7Bfill%3A%23A3A4A7%3B%7D%09.st133%7Bfill%3A%23353535%3B%7D%09.st134%7Bfill%3A%23FF8C02%3B%7D%09.st135%7Bfill%3A%2300AC8C%3B%7D%09.st136%7Bfill%3A%236EC2E9%3B%7D%09.st137%7Bfill%3A%23442359%3B%7D%09.st138%7Bfill%3A%236DC0E6%3B%7D%09.st139%7Bfill%3A%23432056%3B%7D%09.st140%7Bfill%3A%2386CAD7%3B%7D%09.st141%7Bfill%3A%23009E48%3B%7D%09.st142%7Bopacity%3A0.2%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st143%7Bfill%3A%2368217A%3B%7D%09.st144%7Bfill%3A%23E5E5E5%3B%7D%09.st145%7Bopacity%3A0.15%3Bfill%3A%23FFFFFF%3Benable-background%3Anew %3B%7D%09.st146%7Bfill%3A%233898C6%3B%7D%09.st147%7Bfill%3A%2380BA42%3B%7D%09.st148%7Bfill%3A%23B3D234%3B%7D%09.st149%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F9F9F9%3B%7D%09.st150%7Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23008EBE%3B%7D%09.st151%7Bopacity%3A0.1%3Bfill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bfill%3A%23F1F1F2%3B%7D%09.st152%7Bfill%3A%23BAD80A%3B%7D%09.st153%7Bclip-path%3Aurl(%23SVGID_2_)%3B%7D%09.st154%7Bfill%3A%2300BCF2%3B%7D%09.st155%7Bfill%3A%235AB4DA%3B%7D%09.st156%7Bfill%3Anone%3Bstroke%3A%235AB4DA%3Bstroke-width%3A0.75%3Bstroke-miterlimit%3A10%3B%7D%09.st157%7Bfill%3A%233898C5%3B%7D%09.st158%7Bfill%3A%237A7B7B%3B%7D%09.st159%7Bfill%3A%23545555%3B%7D%09.st160%7Bfill%3A%23D6EAF3%3B%7D%09.st161%7Bfill%3A%23009580%3B%7D%09.st162%7Bfill%3A%23BA141A%3B%7D%09.st163%7Bfill%3A%237AC3E1%3B%7D%09.st164%7Bfill%3A%23E27226%3B%7D%09.st165%7Bfill%3A%23FF9D26%3B%7D%09.st166%7Bopacity%3A0.12%3Bfill%3A%23BA141A%3B%7D%09.st167%7Bfill%3A%233C98C5%3B%7D%09.st168%7Bfill%3A%235AB3D8%3B%7D%09.st169%7Bfill%3A%23AAD8EB%3B%7D%09.st170%7Bfill%3A%23797979%3B%7D%09.st171%7Bfill%3A%23959595%3B%7D%09.st172%7Bfill%3A%23D1D1D1%3B%7D%09.st173%7Bclip-path%3Aurl(%23SVGID_4_)%3B%7D%09.st174%7Bfill%3A%2333A2E5%3B%7D%09.st175%7Bfill%3A%2371C2EA%3B%7D%09.st176%7Bfill%3A%23005091%3B%7D%09.st177%7Bclip-path%3Aurl(%23SVGID_6_)%3B%7D%09.st178%7Bfill%3A%23ACD64D%3B%7D%3C%2Fstyle%3E%3Cg%3E%09%3Cg%3E%09%09%3Cg%3E%09%09%09%3Cg%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2226.5%2C4.5 12.5%2C15.5 1.5%2C35.5 11.5%2C35.5 %09%09%09%09%22%2F%3E%09%09%09%09%3Cpolygon class%3D%22st93%22 points%3D%2227.5%2C7.5 21.5%2C22.5 32.5%2C35.5 11.5%2C40.5 46.5%2C40.5 %09%09%09%09%22%2F%3E%09%09%09%3C%2Fg%3E%09%09%3C%2Fg%3E%09%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n background-color: #0078d4;\n}\n');const se="spinnaker.azure";n("spinnaker.azure",["spinnaker.azure.pipeline.stage.destroyAsgStage","spinnaker.azure.pipeline.stage.enableAsgStage","spinnaker.azure.pipeline.stage.disableAsgStage","spinnaker.azure.pipeline.stage.bakeStage","spinnaker.azure.serverGroup.details.azure","spinnaker.azure.serverGroup.transformer","spinnaker.azure.cloneServerGroup.controller","spinnaker.azure.serverGroup.configure","spinnaker.azure.instanceType.service","spinnaker.azure.loadBalancer.transformer","spinnaker.azure.loadBalancer.details.controller","spinnaker.azure.loadBalancer.create.controller","spinnaker.azure.instance.detail.controller","spinnaker.azure.securityGroup.azure.details.controller","spinnaker.azure.securityGroup.create.controller","spinnaker.azure.securityGroup.azure.edit.controller","spinnaker.azure.securityGroup.transformer","spinnaker.azure.securityGroup.reader","spinnaker.azure.image.reader","spinnaker.azure.validation.applicationName"]).config((function(){r.registerProvider("azure",{name:"Azure",logo:{path:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAACrCAYAAACEwDK4AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI2MjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTcxPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOS0wNS0wNlQxMjowNTozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjguMzwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K8Qjg7wAAM9JJREFUeAHtnQeAFdX1/8/MvLa9L1tgF5Zl6UUUggoIggVLrCQYY42a/jPlb4rxr9EkvxhNIz9bEjUmllhRRFCxIKII0hVY2jaWLbC9vf5mft9z571lwd1lWfWXRM+FeW/ezJ07937uveeee+6ZWbIsazG2EpIgBITA554AywKWCSRC4XPfFgSAEDiCgMiEI3DIDyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh8B9DQPuPyWk0o+2WlRnyhYorW8O5++pb0irq2pIqu6y46uaAtau6tv6+L89Yf9akzF3/aeWS/AqBfycCjk8jM5ZljUa6FrZyTdPCvd0DcZJwvAhbLrZkbN158RMZXaGIsbcx4Cira3ej8ydWtoeza1u9haf8atXItkBkeER3pkYiRDpEm6FppBkaBci9zxHv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"},image:{reader:"azureImageReader"},serverGroup:{transformer:"azureServerGroupTransformer",detailsTemplateUrl:"azure/src/serverGroup/details/serverGroupDetails.html",detailsController:"azureServerGroupDetailsCtrl",cloneServerGroupTemplateUrl:"azure/src/serverGroup/configure/wizard/serverGroupWizard.html",cloneServerGroupController:"azureCloneServerGroupCtrl",commandBuilder:"azureServerGroupCommandBuilder",configurationService:"azureServerGroupConfigurationService"},instance:{instanceTypeService:"azureInstanceTypeService",detailsTemplateUrl:"azure/src/instance/details/instanceDetails.html",detailsController:"azureInstanceDetailsCtrl"},loadBalancer:{transformer:"azureLoadBalancerTransformer",detailsTemplateUrl:"azure/src/loadBalancer/details/loadBalancerDetail.html",detailsController:"azureLoadBalancerDetailsCtrl",createLoadBalancerTemplateUrl:"azure/src/loadBalancer/configure/createLoadBalancer.html",createLoadBalancerController:"azureCreateLoadBalancerCtrl",CreateLoadBalancerModal:te},securityGroup:{transformer:"azureSecurityGroupTransformer",reader:"azureSecurityGroupReader",detailsTemplateUrl:"azure/src/securityGroup/details/securityGroupDetail.html",detailsController:"azureSecurityGroupDetailsCtrl",createSecurityGroupTemplateUrl:"azure/src/securityGroup/configure/createSecurityGroup.html",createSecurityGroupController:"azureCreateSecurityGroupCtrl"}})})),_.registerProvider("azure",["redblack"]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/details/serverGroupDetails.html",'<div class="details-panel" ng-class="{ disabled: serverGroup.isDisabled }">\n <div class="header" ng-if="state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div class="header" ng-if="!state.loading">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <span class="glyphicon glyphicon-th"></span>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{serverGroup.name}}</h3>\n </div>\n <div class="actions" ng-class="{ insights: serverGroup.insightActions.length > 0 }">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Server Group Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li><a href ng-if="!serverGroup.isDisabled" ng-click="ctrl.rollbackServerGroup()">Rollback</a></li>\n <div ng-if="false">\n <li><a href ng-click="ctrl.resizeServerGroup()">Resize</a></li>\n </div>\n <li><a href ng-click="ctrl.disableServerGroup()">Disable</a></li>\n <li><a href ng-click="ctrl.enableServerGroup()">Enable</a></li>\n <li><a href ng-click="ctrl.destroyServerGroup()">Destroy</a></li>\n <li><a href ng-click="ctrl.cloneServerGroup(serverGroup)">Clone</a></li>\n </ul>\n </div>\n <div class="dropdown" ng-if="serverGroup.insightActions.length > 0" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-default dropdown-toggle" uib-dropdown-toggle>\n Insight <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li ng-repeat="action in serverGroup.insightActions">\n <a target="_blank" href="{{action.url}}">{{action.label}}</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading">\n <h4 class="text-center" ng-if="serverGroup.isDisabled">[SERVER GROUP IS DISABLED]</h4>\n\n <server-group-running-tasks-details\n server-group="serverGroup"\n application="ctrl.application"\n ></server-group-running-tasks-details>\n\n <collapsible-section heading="Server Group Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Created</dt>\n <dd>{{serverGroup.createdTime | timestamp}}</dd>\n <dt>Region</dt>\n <dd>\n <account-tag account="serverGroup.account" provider="serverGroup.type" pad="right"></account-tag>\n {{serverGroup.region}}\n </dd>\n <dt>Image</dt>\n <dd>{{serverGroup.image.imageName}}</dd>\n <dt>SKU</dt>\n <dd>{{serverGroup.sku.name}}</dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="Size" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Current</dt>\n <dd>{{serverGroup.instances.length}}</dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="Health" expanded="true">\n <dl class="dl-horizontal dl-narrow" ng-if="serverGroup">\n <dt>Instances</dt>\n <dd>\n <health-counts container="serverGroup.instanceCounts" class="pull-left"></health-counts>\n </dd>\n </dl>\n </collapsible-section>\n\n <collapsible-section heading="{{firewallsLabel}}">\n <dl class="dl-horizontal dl-narrow">\n <dt>Name</dt>\n <dd>{{serverGroup.securityGroupName}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/serverGroup/configure/wizard/serverGroupWizard.html",'<div>\n <div ng-if="state.requiresTemplateSelection">\n <ng-include src="pages.templateSelection"></ng-include>\n </div>\n <div ng-if="!state.loaded" style="height: 200px" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div>\n <form name="serverGroupWizardForm" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard\n ng-show="state.loaded && !state.requiresTemplateSelection"\n heading="{{title}}"\n task-monitor="taskMonitor"\n dismiss="$dismiss()"\n >\n <v2-wizard-page key="basic-settings" label="Basic Settings" hide-subheading="true">\n <ng-include src="pages.basicSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="image-settings" label="Image">\n <ng-include src="pages.imageSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="load-balancers" label="Load Balancers" mark-complete-on-view="false">\n <ng-include src="pages.loadBalancers"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="network-settings" label="Network Settings" mark-complete-on-view="false">\n <ng-include src="pages.networkSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="health-settings" label="Health" mark-complete-on-view="false">\n <ng-include src="pages.healthSettings"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="security-groups" label="{{firewallsLabel}}" mark-complete-on-view="false" done="true">\n <ng-include src="pages.securityGroups"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="instance-type" label="Instance Type" mark-complete-on-view="false" done="false">\n <ng-include src="pages.instanceType"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="zones" label="Zones" mark-complete-on-view="false" done="false">\n <ng-include src="pages.zones"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="tags" label="Tags" mark-complete-on-view="false" done="true">\n <ng-include src="pages.tags"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="advanced-settings" label="Advanced Settings" mark-complete-on-view="false" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer" ng-if="state.loaded">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default btn-cancel" ng-click="ctrl.cancel()">\n Cancel\n </button>\n <submit-button\n is-disabled="taskMonitor.submitting || !ctrl.isValid()"\n label="command.viewState.submitButtonLabel"\n submitting="taskMonitor.submitting"\n on-click="serverGroupWizardForm.$valid && ctrl.submit()"\n is-new="true"\n ></submit-button>\n </div>\n </form>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/instance/details/instanceDetails.html",'<div class="details-panel">\n <div class="header">\n <instance-details-header\n health-state="instance.healthState"\n instance-id="instance ? instance.instanceId : instanceIdNotFound"\n loading="state.loading"\n standalone="state.standalone"\n ></instance-details-header>\n </div>\n <div class="content" ng-if="!state.loading && instance">\n <collapsible-section heading="Instance Information" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Launched</dt>\n <dd ng-if="instance.launchTime">{{instance.launchTime | timestamp}}</dd>\n <dd ng-if="!instance.launchTime">(Unknown)</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="instance.account" provider="instance.provider" pad="right"></account-tag>\n {{instance.region || \'(Unknown)\'}}\n </dd>\n <dt>Type</dt>\n <dd>{{instance.instanceType || \'(Unknown)\'}}</dd>\n <dt ng-if="instance.serverGroup">Server Group</dt>\n <dd ng-if="instance.serverGroup">\n <a\n ui-sref="^.serverGroup({region: instance.region,\n accountId: instance.account,\n serverGroup: instance.serverGroup,\n provider: instance.provider})"\n >{{instance.serverGroup}}</a\n >\n </dd>\n </dl>\n </collapsible-section>\n </div>\n <div class="content" ng-if="!state.loading && !instance">\n <div class="content-section">\n <div class="content-body text-center">\n <h3>Instance not found.</h3>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/details/loadBalancerDetail.html",'<div class="details-panel">\n <div ng-if="state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div ng-if="!state.loading" class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div class="header-text horizontal middle">\n <i class="fa icon-sitemap"></i>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{loadBalancer.name}}</h3>\n </div>\n <div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" uib-dropdown-toggle>\n Load Balancer Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li><a href ng-click="ctrl.editLoadBalancer()">Edit Load Balancer</a></li>\n <li ng-if="!loadBalancer.serverGroups.length">\n <a href ng-click="ctrl.deleteLoadBalancer()">Delete Load Balancer</a>\n </li>\n <li\n ng-if="loadBalancer.serverGroups.length"\n class="disabled"\n tooltip="You must detach all server groups before you can delete this load balancer."\n >\n <a href>Delete Load Balancer</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <div ng-if="!state.loading" class="content">\n <collapsible-section heading="Load Balancer Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Type</dt>\n <dd>{{loadBalancer.loadBalancerType}}</dd>\n <dt>Created</dt>\n <dd>{{loadBalancer.elb.createdTime | timestamp}}</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="loadBalancer.account" pad="right" provider="loadBalancer.type"></account-tag>\n {{loadBalancer.region}}\n </dd>\n <dt ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">VNet</dt>\n <dd ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">{{loadBalancer.elb.vnet}}</dd>\n <dt ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">Subnet</dt>\n <dd ng-if="loadBalancer.loadBalancerType === \'Azure Application Gateway\'">{{loadBalancer.elb.subnet}}</dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="loadBalancer.serverGroups">Server Groups</dt>\n <dd ng-if="loadBalancer.serverGroups">\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in loadBalancer.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: \'azure\'})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="loadBalancer.elb.dnsName">DNS Name:</dt>\n <dd>\n <a target="_blank" href="//{{loadBalancer.elb.dnsName}}">{{loadBalancer.elb.dnsName}}</a>\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="loadBalancer.elb.dnsName"\n tool-tip="\'Copy DNS Name to clipboard\'"\n >\n </copy-to-clipboard>\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <health-counts class="pull-left" container="loadBalancer.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Listeners">\n <dl>\n <dt>Load Balancer → Instance</dt>\n <dd ng-repeat="loadBalancingRule in loadBalancer.elb.loadBalancingRules">\n {{loadBalancingRule.protocol}}:{{loadBalancingRule.externalPort}} → {{loadBalancingRule.backendPort}}\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="{{firewallsLabel}}">\n <ul>\n <li ng-repeat="securityGroup in securityGroups | orderBy:\'name\'">\n <a\n ui-sref="^.firewallDetails({name:securityGroup.name, accountId: loadBalancer.account, region: loadBalancer.region, vpcId: loadBalancer.vpcId, provider: loadBalancer.provider})"\n >\n {{securityGroup.name}} ({{securityGroup.id}})\n </a>\n </li>\n </ul>\n </collapsible-section>\n <collapsible-section heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>{{loadBalancer.elb.probes[0].probeProtocol}}</dd>\n <dt>Interval</dt>\n <dd>{{loadBalancer.elb.probes[0].probeInterval}} seconds</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{loadBalancer.elb.probes[0].unhealthyThreshold}}</dd>\n <dt>Timeout</dt>\n <dd>{{loadBalancer.elb.probes[0].timeout}} seconds</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/loadBalancer/configure/createLoadBalancer.html",'<form name="form" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard heading="Create New {{loadBalancerType}}" task-monitor="taskMonitor" dismiss="$dismiss()">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Listeners" label="Listeners" done="true">\n <ng-include src="pages.listeners"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Health Check" label="Health Check" done="true" hide-subheading="true">\n <ng-include src="pages.healthCheck"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Advanced Settings" label="Advanced Settings" done="true">\n <ng-include src="pages.advancedSettings"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button ng-disabled="taskMonitor.submitting" class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!state.accountsLoaded || taskMonitor.submitting"\n submitting="taskMonitor.submitting"\n on-click="form.$valid && ctrl.submit()"\n is-new="isNew"\n ></submit-button>\n </div>\n</form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/details/securityGroupDetail.html",'<div class="details-panel">\n <div class="header">\n <div class="close-button">\n <a class="btn btn-link" ui-sref="^">\n <span class="glyphicon glyphicon-remove"></span>\n </a>\n </div>\n <div ng-if="state.loading" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div class="header-text horizontal middle" ng-if="!state.loading">\n <span class="glyphicon glyphicon-transfer"></span>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>\n {{securityGroup.name || \'(not found)\'}}\n </h3>\n </div>\n <div class="actions">\n <div class="dropdown" uib-dropdown dropdown-append-to-body>\n <button type="button" class="btn btn-sm btn-primary dropdown-toggle" ng-disabled="disabled" uib-dropdown-toggle>\n <firewall-label label="Firewall"></firewall-label> Actions <span class="caret"></span>\n </button>\n <ul class="dropdown-menu" uib-dropdown-menu role="menu">\n <li>\n <a href ng-click="ctrl.deleteSecurityGroup()">Delete <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <li><a href ng-click="ctrl.editInboundRules()">Edit Inbound Rules</a></li>\n <li>\n <a href ng-click="ctrl.cloneSecurityGroup()">Clone <firewall-label label="Firewall"></firewall-label></a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading">\n <collapsible-section heading="{{firewallLabel}} Details" expanded="true">\n <dl class="dl-horizontal dl-medium">\n <dt>ID</dt>\n <dd>{{securityGroup.id}}</dd>\n <dt>Account</dt>\n <dd><account-tag account="securityGroup.accountName"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{securityGroup.region}}</dd>\n <dt>Description:</dt>\n <dd>{{securityGroup.description}}</dd>\n </dl>\n </collapsible-section>\n <collapsible-section\n heading="Security Rules ({{securityGroup.securityRules.length || 0}})"\n expanded="{{!!(securityGroup.securityRules && securityGroup.securityRules.length)}}"\n >\n <div ng-if="!securityGroup.securityRules.length">None</div>\n <dl\n ng-class="insightCtrl.vm.filtersExpanded ? \'\' : \'dl-horizontal dl-medium\'"\n ng-repeat="rule in securityGroup.securityRules | orderBy: \'rule.priority\'"\n >\n <dt>Name</dt>\n <dd>{{rule.name}}</dd>\n <dt>Priority</dt>\n <dd>{{rule.priority}}</dd>\n <dt>Direction</dt>\n <dd>{{rule.direction}}</dd>\n <dt>Access</dt>\n <dd>{{rule.access}}</dd>\n <dt>Protocol</dt>\n <dd>{{rule.protocol}}</dd>\n <dt>Src Addr Prefix</dt>\n <dd>{{rule.sourceAddressPrefixModel}}</dd>\n <dt>Src Port Range</dt>\n <dd>{{rule.sourcePortRange}}</dd>\n <dt>Dest Addr Prefix</dt>\n <dd>{{rule.destinationAddressPrefix}}</dd>\n <dt>Dest Port Range</dt>\n <dd>{{rule.destinationPortRangeModel}}</dd>\n <hr />\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("azure/src/securityGroup/configure/createSecurityGroup.html",'<form name="form" class="form-horizontal" novalidate validate-on-submit>\n <v2-modal-wizard heading="Create New {{firewallLabel}}" task-monitor="taskMonitor" dismiss="$dismiss()">\n <v2-wizard-page key="Location" label="Location">\n <ng-include src="pages.location"></ng-include>\n </v2-wizard-page>\n <v2-wizard-page key="Ingress" label="Ingress" done="true">\n <ng-include src="pages.ingress"></ng-include>\n </v2-wizard-page>\n </v2-modal-wizard>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="state.submitting"\n submitting="state.submitting"\n on-click="form.$valid && ctrl.upsert()"\n is-new="isNew"\n >\n </submit-button>\n </div>\n</form>\n')}]);export{se as AZURE_MODULE};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utility.ts","../src/help/azure.help.ts","../src/image/image.reader.js","../src/instance/azureInstanceType.service.js","../src/instance/details/instance.details.controller.js","../src/loadBalancer/configure/AzureLoadBalancerChoiceModal.tsx","../src/azure.settings.ts","../src/loadBalancer/loadBalancer.transformer.js","../src/loadBalancer/configure/createLoadBalancer.controller.js","../src/loadBalancer/details/loadBalancerDetail.controller.js","../src/pipeline/stages/bake/bakeExecutionDetails.controller.js","../src/pipeline/stages/bake/azureBakeStage.js","../src/pipeline/stages/destroyAsg/azureDestroyAsgStage.js","../src/pipeline/stages/disableAsg/azureDisableAsgStage.js","../src/pipeline/stages/enableAsg/azureEnableAsgStage.js","../src/securityGroup/securityGroup.write.service.js","../src/securityGroup/configure/CreateSecurityGroupCtrl.js","../src/securityGroup/configure/EditSecurityGroupCtrl.js","../src/securityGroup/clone/cloneSecurityGroup.controller.js","../src/securityGroup/details/securityGroupDetail.controller.js","../src/securityGroup/securityGroup.reader.js","../src/securityGroup/securityGroup.transformer.js","../src/serverGroup/serverGroup.transformer.js","../src/serverGroup/configure/wizard/ServerGroupInstanceArchetype.controller.js","../src/serverGroup/configure/wizard/ServerGroupInstanceType.controller.js","../src/serverGroup/configure/wizard/advancedSettings/ServerGroupAdvancedSettings.controller.js","../src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.js","../src/serverGroup/configure/wizard/basicSettings/image.regional.filter.js","../src/serverGroup/configure/wizard/basicSettings/ServerGroupBasicSettings.controller.js","../src/serverGroup/configure/wizard/capacity/capacitySelector.directive.js","../src/serverGroup/configure/wizard/healthSettings/ServerGroupHealthSettings.controller.js","../src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.js","../src/serverGroup/configure/wizard/image/ServerGroupImageSettings.controller.js","../src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.js","../src/serverGroup/configure/wizard/loadBalancers/ServerGroupLoadBalancers.controller.js","../src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.js","../src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettings.controller.js","../src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.js","../src/serverGroup/configure/wizard/securityGroup/ServerGroupSecurityGroups.controller.js","../src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.js","../src/serverGroup/configure/wizard/tags/tagsSelector.directive.js","../src/serverGroup/configure/wizard/zones/zoneSelector.directive.js","../src/serverGroup/configure/serverGroup.configure.azure.module.js","../src/serverGroup/configure/serverGroupConfiguration.service.js","../src/serverGroup/configure/wizard/CloneServerGroup.azure.controller.js","../src/serverGroup/configure/serverGroupCommandBuilder.service.js","../src/common/AzureModalFooter.tsx","../src/serverGroup/details/rollback/RollbackServerGroupModal.tsx","../src/serverGroup/details/serverGroupDetails.azure.controller.js","../src/serverGroup/details/serverGroup.details.module.js","../src/validation/applicationName.validator.js","../../../node_modules/style-inject/dist/style-inject.es.js","../src/azure.module.ts","../src/logo/logo_azure.png"],"sourcesContent":["export interface ITagResult {\n isValid: boolean;\n error: TagError | null;\n errorMessage?: string;\n}\n\nexport enum TagError {\n TAG_NUMBER_EXCEED,\n TAG_KEY_LENGTH_EXCEED,\n TAG_VALUE_LENGTH_EXCEED,\n TAG_KEY_INVALID_CHARACTER,\n TAG_VALUE_INVALID_CHARACTER,\n TAG_OBJECT_UNDEFINED,\n}\n\nexport interface IAzureLoadBalancer {\n type: string;\n description: string;\n}\n\nexport const AzureLoadBalancerTypes: IAzureLoadBalancer[] = [\n {\n type: 'Azure Load Balancer',\n description: '',\n },\n {\n type: 'Azure Application Gateway',\n description: '',\n },\n];\n\nexport default class Utility {\n public static readonly TAG_LIMITATION: number = 8;\n public static readonly TAG_KEY_LENGTH_LIMITATION: number = 512;\n public static readonly TAG_VALUE_LENGTH_LIMITATION: number = 256;\n public static readonly TAG_INVALID_CHAR_REG_EXR: RegExp = /[<>%&\\\\?/]/;\n\n public static checkTags(tagsObject: { [s: string]: string }): ITagResult {\n if (!tagsObject) {\n return {\n isValid: false,\n error: TagError.TAG_OBJECT_UNDEFINED,\n errorMessage: 'instanceTags is not defined',\n };\n }\n const length: number = Object.keys(tagsObject).length;\n if (!(length >= 0 && length <= Utility.TAG_LIMITATION)) {\n return {\n isValid: false,\n error: TagError.TAG_NUMBER_EXCEED,\n errorMessage: `Number of tags exceeds the limit: ${Utility.TAG_LIMITATION}`,\n };\n }\n\n for (const [k, v] of Object.entries(tagsObject)) {\n if (k.length > Utility.TAG_KEY_LENGTH_LIMITATION) {\n return {\n isValid: false,\n error: TagError.TAG_KEY_LENGTH_EXCEED,\n errorMessage: `Length of Tag key: ${k} exceeds the limit: ${Utility.TAG_KEY_LENGTH_LIMITATION}`,\n };\n }\n if (v.length > Utility.TAG_VALUE_LENGTH_LIMITATION) {\n return {\n isValid: false,\n error: TagError.TAG_VALUE_LENGTH_EXCEED,\n errorMessage: `Length of Tag value: ${v} exceeds the limit: ${Utility.TAG_VALUE_LENGTH_LIMITATION}`,\n };\n }\n if (Utility.TAG_INVALID_CHAR_REG_EXR.test(k)) {\n return {\n isValid: false,\n error: TagError.TAG_KEY_INVALID_CHARACTER,\n errorMessage: `Invalid characters in Tag key: ${k}`,\n };\n }\n if (Utility.TAG_INVALID_CHAR_REG_EXR.test(v)) {\n return {\n isValid: false,\n error: TagError.TAG_VALUE_INVALID_CHARACTER,\n errorMessage: `Invalid characters in Tag value: ${v}`,\n };\n }\n }\n return {\n isValid: true,\n error: null,\n };\n }\n\n public static getLoadBalancerType(typeString: string): IAzureLoadBalancer | null {\n typeString = typeString.toLowerCase().split('_').join(' ');\n return AzureLoadBalancerTypes.find((lb: IAzureLoadBalancer) => lb.type.toLowerCase() === typeString) || null;\n }\n}\n","import { HelpContentsRegistry } from '@spinnaker/core';\nimport Utility from '../utility';\n\nconst helpContents: { [key: string]: string } = {\n 'azure.securityGroup.ingress.description': 'Friendly description of the rule you want to enable (limit 80 chars.)',\n 'azure.securityGroup.ingress.priority':\n \"Rules are processed in priority order; the lower the number, the higher the priority. We recommend leaving gaps between rules - 100, 200, 300, etc. - so that it's easier to add new rules without having to edit existing rules. There are several default rules that can be overridden with priority (65000, 65001 and 65500). For more information visit http://portal.azure.com.\",\n 'azure.securityGroup.ingress.source':\n \"The source filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the incoming traffic from a specific source IP address range (CIDR format) that will be allowed or denied by this rule.\",\n 'azure.securityGroup.ingress.sourcePortRange':\n 'The source port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which ports incoming traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.',\n 'azure.securityGroup.ingress.destination':\n \"The destination filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the outgoing traffic from a specific destination IP address range (CIDR format) that will be allowed or denied by this rule.\",\n 'azure.securityGroup.ingress.destinationPortRange':\n 'The destination port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which destination ports traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.',\n 'azure.securityGroup.ingress.direction': 'Specifies whether the rule is for inbound or outbound traffic.',\n 'azure.securityGroup.ingress.actions':\n 'To adjust the priority of a rule, move it up or down in the list of rules. Rules at the top of the list have the highest priority.',\n 'azure.securityGroup.ingress.destPortRanges':\n 'Provide a single port, such as 80; a port range, such as 1024-65535; or a comma-separated list of single ports and/or port ranges, such as 80,1024-65535. Provide an asterisk (*) to allow traffic on any port.',\n 'azure.securityGroup.ingress.sourceIPCIDRRanges':\n 'Provide an address range using CIDR notation, such as 192.168.99.0/24; an IP address, such as 192.168.99.0; or a comma-separated list of address ranges or IP addresses, such as 10.0.0.0/24,44.66.0.0/24',\n 'azure.serverGroup.imageName': '(Required) <b>Image</b> is the deployable Azure Machine Image.',\n 'azure.serverGroup.stack':\n '(Required) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.',\n 'azure.serverGroup.detail':\n '(Required) <b>Detail</b> is a naming component to help distinguish specifics of the server group.',\n 'azure.serverGroup.scriptLocation':\n 'The location of custom scripts separated by comma or semicolon to be downloaded on to each instance. A single script should be like: fileUri. Multiple scripts should be like fileUri1,fileUri2 or fileUri1;fileUri2',\n 'azure.serverGroup.commandToExecute':\n 'Command(s) to execute custom scripts provided during provisioning of an instance.',\n 'azure.serverGroup.customData': 'Script or metadata to be injected into each instances.',\n 'azure.serverGroup.customTags': `Custom tags on Virtual Machine Scale Set. Allow ${Utility.TAG_LIMITATION} tags at most.`,\n 'azure.serverGroup.enableInboundNAT':\n 'An Azure load balancer of the basic sku will be created with adding inbound NAT port-forwarding rules to facilitate loggin on VM instances. There is no charge for creating an Azure load balancer of the basic sku. This option is disabled if Availability Zones are set which require Standard Azure Load Balancer and an extra Network Security Group with correct inbound and outbound rules configured.',\n 'azure.serverGroup.lun':\n 'Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM.',\n 'azure.serverGroup.diskSizeGB':\n 'Specifies the size of an empty data disk in gigabytes. This value cannot be larger than 1023 GB',\n 'azure.serverGroup.managedDisk.storageAccountType':\n 'You can choose between Azure managed disks types to support your workload or scenario.',\n 'azure.serverGroup.caching':\n 'Changing the default host caching policy can adversely impact the performance of your application. You should run performance tests to measure its impact. To improve the total IOPS/throughput, we recommend striping across multiple disks and using premium (SSD) disks.',\n 'azure.serverGroup.userAssignedIdentities':\n 'Allows your server to access Azure resources. Learn more here: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview',\n 'azure.loadBalancer.dnsName':\n 'If there is no custom DNS label specified, a default DNS name will be created. The default value will be \"GeneratedText.cloudapp.net\" for Azure Application Gateway or \"GeneratedText.[region].cloudapp.azure.com\" for Azure Load Balancer.',\n 'azure.loadBalancer.probes.probeInterval':\n 'Probe interval in seconds. This value is the time interval between two consecutive probes.',\n 'azure.loadBalancer.probes.timeout':\n 'Probe time-out in seconds. If a valid response is not received within this time-out period, the probe is marked as failed. Note that the time-out value should not be more than the Interval value.',\n 'azure.loadBalancer.probes.unhealthyThreshold':\n 'Probe retry count. The back-end server is marked down after the consecutive probe failure count reaches the unhealthy threshold.',\n 'azure.loadBalancer.loadBalancingRules.idleTimeout':\n 'Keep a TCP or HTTP connection open without relying on clients to send keep-alive messages.',\n 'azure.loadBalancer.loadBalancingRules.sessionPersistence':\n 'Session persistence specifies that traffic from a client should be handled by the same virtual machine in the backend pool for the duration of a session. \"None\" specifies that successive requests from the same client may be handled by any virtual machine. \"Client IP\" specifies that successive requests from the same client IP address will be handled by the same virtual machine. \"Client IP and protocol\" specifies that successive requests from the same client IP address and protocol combination will be handled by the same virtual machine.',\n};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { REST } from '@spinnaker/core';\n\nexport const AZURE_IMAGE_IMAGE_READER = 'spinnaker.azure.image.reader';\nexport const name = AZURE_IMAGE_IMAGE_READER; // for backwards compatibility\nmodule(AZURE_IMAGE_IMAGE_READER, []).factory('azureImageReader', function () {\n function findImages(params) {\n return REST('/images/find')\n .query(params)\n .get()\n .then(\n function (results) {\n return results;\n },\n function () {\n return [];\n },\n );\n }\n\n function getImage(amiName, region, credentials) {\n return REST('/images')\n .path(credentials, region, amiName)\n .query({ provider: 'azure' })\n .get()\n .then(\n function (results) {\n return results && results.length ? results[0] : null;\n },\n function () {\n return null;\n },\n );\n }\n\n return {\n findImages: findImages,\n getImage: getImage,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE = 'spinnaker.azure.instanceType.service';\nexport const name = AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE; // for backwards compatibility\nmodule(AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE, []).factory('azureInstanceTypeService', [\n '$q',\n function ($q) {\n const B = {\n type: 'B-series',\n description:\n 'The B-series burstable VMs are ideal for workloads that do not need the full performance of the CPU continuously, like web servers, small databases and development and test environments.',\n instanceTypes: [\n {\n name: 'Standard_B1ms',\n label: 'Standard_B1ms',\n cpu: 1,\n memory: 2,\n storage: {\n type: 'SSD',\n count: 2,\n size: 4,\n },\n },\n {\n name: 'Standard_B1s',\n label: 'Standard_B1s',\n cpu: 1,\n memory: 1,\n storage: {\n type: 'SSD',\n count: 2,\n size: 2,\n },\n },\n {\n name: 'Standard_B2ms',\n label: 'Standard_B2ms',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 16,\n },\n },\n {\n name: 'Standard_B2s',\n label: 'Standard_B2s',\n cpu: 2,\n memory: 4,\n storage: {\n type: 'SSD',\n count: 4,\n size: 8,\n },\n },\n {\n name: 'Standard_B4ms',\n label: 'Standard_B4ms',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 32,\n },\n },\n {\n name: 'Standard_B8ms',\n label: 'Standard_B8ms',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 64,\n },\n },\n {\n name: 'Standard_B1ls',\n label: 'Standard_B1ls',\n cpu: 1,\n memory: 0.5,\n storage: {\n type: 'SSD',\n count: 2,\n size: 1,\n },\n },\n ],\n };\n\n const DSV3 = {\n type: 'Dsv3-series',\n description:\n 'The Dsv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.',\n instanceTypes: [\n {\n name: 'Standard_D2s_v3',\n label: 'Standard_D2s_v3',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 16,\n },\n },\n {\n name: 'Standard_D4s_v3',\n label: 'Standard_D4s_v3',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 32,\n },\n },\n {\n name: 'Standard_D8s_v3',\n label: 'Standard_D8s_v3',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 64,\n },\n },\n {\n name: 'Standard_D16s_v3',\n label: 'Standard_D16s_v3',\n cpu: 16,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 32,\n size: 128,\n },\n },\n {\n name: 'Standard_D32s_v3',\n label: 'Standard_D32s_v3',\n cpu: 32,\n memory: 128,\n storage: {\n type: 'SSD',\n count: 32,\n size: 256,\n },\n },\n {\n name: 'Standard_D64s_v3',\n label: 'Standard_D64s_v3',\n cpu: 64,\n memory: 256,\n storage: {\n type: 'SSD',\n count: 32,\n size: 512,\n },\n },\n ],\n };\n\n const DV3 = {\n type: 'Dv3-series',\n description:\n 'The Dv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.',\n instanceTypes: [\n {\n name: 'Standard_D2_v3',\n label: 'Standard_D2_v3',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 50,\n },\n },\n {\n name: 'Standard_D4_v3',\n label: 'Standard_D4_v3',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D8_v3',\n label: 'Standard_D8_v3',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D16_v3',\n label: 'Standard_D16_v3',\n cpu: 16,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D32_v3',\n label: 'Standard_D32_v3',\n cpu: 32,\n memory: 128,\n storage: {\n type: 'SSD',\n count: 32,\n size: 800,\n },\n },\n {\n name: 'Standard_D64_v3',\n label: 'Standard_D64_v3',\n cpu: 64,\n memory: 256,\n storage: {\n type: 'SSD',\n count: 32,\n size: 1600,\n },\n },\n ],\n };\n\n const DSV2 = {\n type: 'DSv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_DS1_v2',\n label: 'Standard_DS1_v2',\n cpu: 1,\n memory: 3.5,\n storage: {\n type: 'SSD',\n count: 4,\n size: 7,\n },\n },\n {\n name: 'Standard_DS2_v2',\n label: 'Standard_DS2_v2',\n cpu: 2,\n memory: 7,\n storage: {\n type: 'SSD',\n count: 8,\n size: 14,\n },\n },\n {\n name: 'Standard_DS3_v2',\n label: 'Standard_DS3_v2',\n cpu: 4,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 16,\n size: 28,\n },\n },\n {\n name: 'Standard_DS4_v2',\n label: 'Standard_DS4_v2',\n cpu: 8,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 32,\n size: 56,\n },\n },\n {\n name: 'Standard_DS5_v2',\n label: 'Standard_DS5_v2',\n cpu: 16,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 64,\n size: 112,\n },\n },\n {\n name: 'Standard_DS11_v2',\n label: 'Standard_DS11_v2',\n cpu: 2,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 8,\n size: 28,\n },\n },\n {\n name: 'Standard_DS12_v2',\n label: 'Standard_DS12_v2',\n cpu: 4,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 16,\n size: 56,\n },\n },\n {\n name: 'Standard_DS13_v2',\n label: 'Standard_DS13_v2',\n cpu: 8,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 32,\n size: 112,\n },\n },\n {\n name: 'Standard_DS14_v2',\n label: 'Standard_DS14_v2',\n cpu: 16,\n memory: 112,\n storage: {\n type: 'SSD',\n count: 64,\n size: 224,\n },\n },\n {\n name: 'Standard_DS15_v2',\n label: 'Standard_DS15_v2',\n cpu: 20,\n memory: 140,\n storage: {\n type: 'SSD',\n count: 64,\n size: 280,\n },\n },\n ],\n };\n\n const DV2 = {\n type: 'Dv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_D1_v2',\n label: 'Standard_D1_v2',\n cpu: 1,\n memory: 3.5,\n storage: {\n type: 'SSD',\n count: 4,\n size: 50,\n },\n },\n {\n name: 'Standard_D2_v2',\n label: 'Standard_D2_v2',\n cpu: 2,\n memory: 7,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D3_v2',\n label: 'Standard_D3_v2',\n cpu: 4,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D4_v2',\n label: 'Standard_D4_v2',\n cpu: 8,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D5_v2',\n label: 'Standard_D5_v2',\n cpu: 16,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 64,\n size: 800,\n },\n },\n {\n name: 'Standard_D11_v2',\n label: 'Standard_D11_v2',\n cpu: 2,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D12_v2',\n label: 'Standard_D12_v2',\n cpu: 4,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D13_v2',\n label: 'Standard_D13_v2',\n cpu: 8,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D14_v2',\n label: 'Standard_D14_v2',\n cpu: 16,\n memory: 112,\n storage: {\n type: 'SSD',\n count: 64,\n size: 800,\n },\n },\n {\n name: 'Standard_D15_v2',\n label: 'Standard_D15_v2',\n cpu: 20,\n memory: 140,\n storage: {\n type: 'SSD',\n count: 64,\n size: 280,\n },\n },\n ],\n };\n\n const AV2 = {\n type: 'Av2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_A1_v2',\n label: 'Standard_A1_v2',\n cpu: 1,\n memory: 2,\n storage: {\n type: 'SSD',\n count: 2,\n size: 10,\n },\n },\n {\n name: 'Standard_A2m_v2',\n label: 'Standard_A2m_v2',\n cpu: 2,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 4,\n size: 20,\n },\n },\n {\n name: 'Standard_A2_v2',\n label: 'Standard_A2_v2',\n cpu: 2,\n memory: 4,\n storage: {\n type: 'SSD',\n count: 4,\n size: 20,\n },\n },\n {\n name: 'Standard_A4m_v2',\n label: 'Standard_A4m_v2',\n cpu: 4,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 8,\n size: 40,\n },\n },\n {\n name: 'Standard_A4_v2',\n label: 'Standard_A4_v2',\n cpu: 4,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 8,\n size: 40,\n },\n },\n {\n name: 'Standard_A8m_v2',\n label: 'Standard_A8m_v2',\n cpu: 8,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 16,\n size: 80,\n },\n },\n {\n name: 'Standard_A8_v2',\n label: 'Standard_A8_v2',\n cpu: 8,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 16,\n size: 80,\n },\n },\n ],\n };\n\n const DC = {\n type: 'DC-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_DC2s',\n label: 'Standard_DC2s',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 2,\n size: 100,\n },\n },\n {\n name: 'Standard_DC4s',\n label: 'Standard_DC4s',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 4,\n size: 200,\n },\n },\n ],\n };\n\n const FSV2 = {\n type: 'Fsv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F2s_v2',\n label: 'Standard_F2s_v2',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 4, size: 16 },\n },\n {\n name: 'Standard_F4s_v2',\n label: 'Standard_F4s_v2',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 8, size: 32 },\n },\n {\n name: 'Standard_F8s_v2',\n label: 'Standard_F8s_v2',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 16, size: 64 },\n },\n {\n name: 'Standard_F16s_v2',\n label: 'Standard_F16s_v2',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 32, size: 128 },\n },\n {\n name: 'Standard_F32s_v2',\n label: 'Standard_F32s_v2',\n cpu: 32,\n memory: 64,\n storage: { type: 'SSD', count: 32, size: 256 },\n },\n {\n name: 'Standard_F64s_v2',\n label: 'Standard_F64s_v2',\n cpu: 64,\n memory: 128,\n storage: { type: 'SSD', count: 32, size: 512 },\n },\n {\n name: 'Standard_F72s_v2',\n label: 'Standard_F72s_v2',\n cpu: 72,\n memory: 144,\n storage: { type: 'SSD', count: 32, size: 576 },\n },\n ],\n };\n\n const FS = {\n type: 'Fs-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F1s',\n label: 'Standard_F1s',\n cpu: 1,\n memory: 2,\n storage: { type: 'SSD', count: 4, size: 4 },\n },\n {\n name: 'Standard_F2s',\n label: 'Standard_F2s',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 8, size: 8 },\n },\n {\n name: 'Standard_F4s',\n label: 'Standard_F4s',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 16, size: 16 },\n },\n {\n name: 'Standard_F8s',\n label: 'Standard_F8s',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 32, size: 32 },\n },\n {\n name: 'Standard_F16s',\n label: 'Standard_F16s',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 64, size: 64 },\n },\n ],\n };\n\n const F = {\n type: 'F-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F1',\n label: 'Standard_F1',\n cpu: 1,\n memory: 2,\n storage: { type: 'SSD', count: 4, size: 16 },\n },\n {\n name: 'Standard_F2',\n label: 'Standard_F2',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 8, size: 32 },\n },\n {\n name: 'Standard_F4',\n label: 'Standard_F4',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 16, size: 64 },\n },\n {\n name: 'Standard_F8',\n label: 'Standard_F8',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 32, size: 128 },\n },\n {\n name: 'Standard_F16',\n label: 'Standard_F16',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 64, size: 256 },\n },\n ],\n };\n\n const categories = [\n {\n type: 'general',\n label: 'General Purpose',\n description:\n 'Balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers.',\n families: [B, DSV3, DV3, DSV2, DV2, AV2, DC],\n icon: 'hdd',\n },\n {\n type: 'compute',\n label: 'Compute Optimized',\n description:\n 'High CPU-to-memory ratio. Good for medium traffic web servers, network appliances, batch processes, and application servers.',\n families: [FSV2, FS, F],\n icon: 'hdd',\n },\n {\n type: 'custom',\n label: 'Custom Type',\n description: 'Select the instance type below.',\n families: [],\n icon: 'asterisk',\n },\n ];\n\n function calculateStorage(type) {\n if (!type || !type.storage) {\n return 0;\n }\n return type.storage.count * type.storage.size;\n }\n\n function buildStats(category) {\n const stats = {\n cpu: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n memory: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n storage: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n families: [],\n };\n\n if (category.families && category.families.length) {\n category.families.forEach(function (family) {\n stats.families.push(family.type);\n const cpuMin = _.minBy(family.instanceTypes, 'cpu').cpu || Number.MAX_VALUE;\n const cpuMax = _.maxBy(family.instanceTypes, 'cpu').cpu || -Number.MAX_VALUE;\n const memoryMin = _.minBy(family.instanceTypes, 'memory').memory || Number.MAX_VALUE;\n const memoryMax = _.maxBy(family.instanceTypes, 'memory').memory || -Number.MAX_VALUE;\n const storageMin = calculateStorage(_.minBy(family.instanceTypes, calculateStorage)) || Number.MAX_VALUE;\n const storageMax = calculateStorage(_.maxBy(family.instanceTypes, calculateStorage)) || -Number.MAX_VALUE;\n\n stats.cpu.min = Math.min(stats.cpu.min, cpuMin);\n stats.cpu.max = Math.max(stats.cpu.max, cpuMax);\n stats.memory.min = Math.min(stats.memory.min, memoryMin);\n stats.memory.max = Math.max(stats.memory.max, memoryMax);\n stats.storage.min = Math.min(stats.storage.min, storageMin);\n stats.storage.max = Math.max(stats.storage.max, storageMax);\n });\n }\n\n return stats;\n }\n\n function getCategories() {\n categories.map(function (category) {\n for (const family of category.families) {\n for (const inst of family.instanceTypes) {\n if (inst.costFactor == undefined) inst.costFactor = 0;\n }\n }\n category.stats = buildStats(category);\n });\n return $q.when(categories);\n }\n\n const getAllTypesByRegion = function getAllTypesByRegion() {\n return getCategories();\n };\n\n function getAvailableTypesForRegions(locationToInstanceTypesMap, selectedLocations) {\n // This function is only ever called with one location.\n const [location] = selectedLocations;\n return locationToInstanceTypesMap[location];\n }\n\n return {\n getCategories: getCategories,\n getAvailableTypesForRegions: getAvailableTypesForRegions,\n getAllTypesByRegion: getAllTypesByRegion,\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport {\n CloudProviderRegistry,\n ConfirmationModalService,\n InstanceReader,\n InstanceWriter,\n RecentHistoryService,\n} from '@spinnaker/core';\n\nexport const AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER = 'spinnaker.azure.instance.detail.controller';\nexport const name = AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER, [UIROUTER_ANGULARJS, ANGULAR_UI_BOOTSTRAP]).controller(\n 'azureInstanceDetailsCtrl',\n [\n '$scope',\n '$state',\n '$uibModal',\n 'instance',\n 'app',\n '$q',\n function ($scope, $state, $uibModal, instance, app, $q) {\n // needed for standalone instances\n $scope.detailsTemplateUrl = CloudProviderRegistry.getValue('azure', 'instance.detailsTemplateUrl');\n\n $scope.state = {\n loading: true,\n standalone: app.isStandalone,\n };\n\n function extractHealthMetrics(instance, latest) {\n // do not backfill on standalone instances\n if (app.isStandalone) {\n instance.health = latest.health;\n }\n\n instance.health = instance.health || [];\n const displayableMetrics = instance.health.filter(function (metric) {\n return metric.type !== 'Azure' || metric.state !== 'Unknown';\n });\n // backfill details where applicable\n if (latest.health) {\n displayableMetrics.forEach(function (metric) {\n const detailsMatch = latest.health.filter(function (latestHealth) {\n return latestHealth.type === metric.type;\n });\n if (detailsMatch.length) {\n _.defaults(metric, detailsMatch[0]);\n }\n });\n }\n $scope.healthMetrics = displayableMetrics;\n }\n\n function retrieveInstance() {\n const extraData = {};\n let instanceSummary, loadBalancers, account, region, vpcId;\n if (!app.serverGroups) {\n // standalone instance\n instanceSummary = {};\n loadBalancers = [];\n account = instance.account;\n region = instance.region;\n } else {\n app.serverGroups.data.some(function (serverGroup) {\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = serverGroup.loadBalancers;\n account = serverGroup.account;\n region = serverGroup.region;\n vpcId = serverGroup.vpcId;\n extraData.serverGroup = serverGroup.name;\n extraData.vpcId = serverGroup.vpcId;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a server group that is part of another app\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a disabled server group via a load balancer\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.serverGroups.some(function (serverGroup) {\n if (!serverGroup.isDisabled) {\n return false;\n }\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n });\n }\n }\n }\n\n if (instanceSummary && account && region) {\n extraData.account = account;\n extraData.region = region;\n RecentHistoryService.addExtraDataToLatest('instances', extraData);\n return InstanceReader.getInstanceDetails(account, region, instance.instanceId).then(\n function (details) {\n $scope.state.loading = false;\n extractHealthMetrics(instanceSummary, details);\n $scope.instance = _.defaults(details, instanceSummary);\n $scope.instance.account = account;\n $scope.instance.region = region;\n $scope.instance.vpcId = vpcId;\n $scope.instance.loadBalancers = loadBalancers;\n const discoveryMetric = _.find($scope.healthMetrics, function (metric) {\n return metric.type === 'Discovery';\n });\n if (discoveryMetric && discoveryMetric.vipAddress) {\n const vipList = discoveryMetric.vipAddress;\n $scope.instance.vipAddress = vipList.includes(',') ? vipList.split(',') : [vipList];\n }\n $scope.baseIpAddress = details.publicDnsName || details.privateIpAddress;\n },\n function () {\n // When an instance is first starting up, we may not have the details cached in oort yet, but we still\n // want to let the user see what details we have\n $scope.state.loading = false;\n $state.go('^');\n },\n );\n }\n\n if (!instanceSummary) {\n $scope.instanceIdNotFound = instance.instanceId;\n $scope.state.loading = false;\n }\n\n return $q.when(null);\n }\n\n this.canDeregisterFromLoadBalancer = function () {\n return $scope.instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n };\n\n this.canRegisterWithLoadBalancer = function () {\n const instance = $scope.instance;\n if (!instance.loadBalancers || !instance.loadBalancers.length) {\n return false;\n }\n const outOfService = instance.health.some(function (health) {\n return health.type === 'LoadBalancer' && health.state === 'OutOfService';\n });\n const hasLoadBalancerHealth = instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n return outOfService || !hasLoadBalancerHealth;\n };\n\n this.canRegisterWithDiscovery = function () {\n const instance = $scope.instance;\n const discoveryHealth = instance.health.filter(function (health) {\n return health.type === 'Discovery';\n });\n return discoveryHealth.length ? discoveryHealth[0].state === 'OutOfService' : false;\n };\n\n this.terminateInstance = function terminateInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId,\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return InstanceWriter.terminateInstance(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + '?',\n buttonText: 'Terminate ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.terminateInstanceAndShrinkServerGroup = function terminateInstanceAndShrinkServerGroup() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId + ' and shrinking server group',\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return InstanceWriter.terminateInstanceAndShrinkServerGroup(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup + '?',\n buttonText: 'Terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.rebootInstance = function rebootInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Rebooting ' + instance.instanceId,\n };\n\n const submitMethod = function () {\n return InstanceWriter.rebootInstance(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really reboot ' + instance.instanceId + '?',\n buttonText: 'Reboot ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.registerInstanceWithLoadBalancer = function registerInstanceWithLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Registering ' + instance.instanceId + ' with ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.registerInstanceWithLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really register ' + instance.instanceId + ' with ' + loadBalancerNames + '?',\n buttonText: 'Register ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.deregisterInstanceFromLoadBalancer = function deregisterInstanceFromLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Deregistering ' + instance.instanceId + ' from ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.deregisterInstanceFromLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really deregister ' + instance.instanceId + ' from ' + loadBalancerNames + '?',\n buttonText: 'Deregister ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.enableInstanceInDiscovery = function enableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.enableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really enable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Enable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.disableInstanceInDiscovery = function disableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.disableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really disable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Disable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.hasHealthState = function hasHealthState(healthProviderType, state) {\n const instance = $scope.instance;\n return instance.health.some(function (health) {\n return health.type === healthProviderType && health.state === state;\n });\n };\n\n const initialize = app.isStandalone\n ? retrieveInstance()\n : $q.all([app.serverGroups.ready(), app.loadBalancers.ready()]).then(retrieveInstance);\n\n initialize.then(() => {\n // Two things to look out for here:\n // 1. If the retrieveInstance call completes *after* the user has navigated away from the view, there\n // is no point in subscribing to the refresh\n // 2. If this is a standalone instance, there is no application that will refresh\n if (!$scope.$$destroyed && !app.isStandalone) {\n app.serverGroups.onRefresh($scope, retrieveInstance);\n }\n });\n\n $scope.account = instance.account;\n },\n ],\n);\n","import React from 'react';\nimport { Button, Modal } from 'react-bootstrap';\n\nimport {\n CloudProviderRegistry,\n ILoadBalancerModalProps,\n ModalClose,\n ModalInjector,\n noop,\n ReactModal,\n} from '@spinnaker/core';\n\nimport { AzureLoadBalancerTypes, IAzureLoadBalancer } from '../../utility';\n\nexport interface IAzureLoadBalancerChoiceModalState {\n choices: IAzureLoadBalancer[];\n selectedChoice: IAzureLoadBalancer;\n}\n\nexport class AzureLoadBalancerChoiceModal extends React.Component<\n ILoadBalancerModalProps,\n IAzureLoadBalancerChoiceModalState\n> {\n public static defaultProps: Partial<ILoadBalancerModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static show(props: ILoadBalancerModalProps): Promise<void> {\n return ReactModal.show(AzureLoadBalancerChoiceModal, {\n ...props,\n className: 'create-pipeline-modal-overflow-visible',\n });\n }\n\n constructor(props: ILoadBalancerModalProps) {\n super(props);\n this.state = {\n choices: AzureLoadBalancerTypes,\n selectedChoice: AzureLoadBalancerTypes[0],\n };\n }\n\n public choiceSelected(choice: IAzureLoadBalancer): void {\n this.setState({ selectedChoice: choice });\n }\n\n private choose = (): void => {\n this.close();\n const provider: any = CloudProviderRegistry.getValue('azure', 'loadBalancer');\n ModalInjector.modalService\n .open({\n templateUrl: provider.createLoadBalancerTemplateUrl,\n windowClass: 'modal-z-index',\n controller: `${provider.createLoadBalancerController} as ctrl`,\n size: 'lg',\n resolve: {\n application: () => this.props.app,\n loadBalancer: (): any => null,\n isNew: () => true,\n forPipelineConfig: () => false,\n loadBalancerType: () => this.state.selectedChoice,\n },\n })\n .result.catch(() => {});\n };\n\n public close = (reason?: any): void => {\n this.props.dismissModal(reason);\n };\n\n public render() {\n const { choices, selectedChoice } = this.state;\n\n return (\n <>\n <ModalClose dismiss={this.close} />\n <Modal.Header>\n <Modal.Title>Select Type of Load Balancer</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <div className=\"modal-body\">\n <div className=\"card-choices\">\n {choices.map((choice) => (\n <div\n key={choice.type}\n className={`card ${selectedChoice === choice ? 'active' : ''}`}\n onClick={() => this.choiceSelected(choice)}\n >\n <h3 className=\"load-balancer-label\">{choice.type}</h3>\n <div>{choice.description}</div>\n </div>\n ))}\n </div>\n <div className=\"load-balancer-description\" />\n </div>\n </Modal.Body>\n <Modal.Footer>\n <Button onClick={this.choose}>\n Configure Load Balancer <span className=\"glyphicon glyphicon-chevron-right\" />\n </Button>\n </Modal.Footer>\n </>\n );\n }\n}\n","import { IProviderSettings, SETTINGS } from '@spinnaker/core';\n\nexport interface IAzureProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n };\n}\n\nexport const AzureProviderSettings: IAzureProviderSettings = (SETTINGS.providers.azure as IAzureProviderSettings) || {\n defaults: {},\n};\nif (AzureProviderSettings) {\n AzureProviderSettings.resetToOriginal = SETTINGS.resetProvider('azure');\n}\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AzureProviderSettings } from '../azure.settings';\n\nexport const AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER = 'spinnaker.azure.loadBalancer.transformer';\nexport const name = AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER, []).factory('azureLoadBalancerTransformer', [\n '$q',\n function ($q) {\n function normalizeLoadBalancer(loadBalancer) {\n loadBalancer.serverGroups.forEach(function (serverGroup) {\n serverGroup.account = loadBalancer.account;\n serverGroup.region = loadBalancer.region;\n\n if (serverGroup.detachedInstances) {\n serverGroup.detachedInstances = serverGroup.detachedInstances.map(function (instanceId) {\n return { id: instanceId };\n });\n serverGroup.instances = serverGroup.instances.concat(serverGroup.detachedInstances);\n } else {\n serverGroup.detachedInstances = [];\n }\n });\n const activeServerGroups = _.filter(loadBalancer.serverGroups, { isDisabled: false });\n loadBalancer.provider = loadBalancer.type;\n loadBalancer.instances = _.chain(activeServerGroups).map('instances').flatten().value();\n loadBalancer.detachedInstances = _.chain(activeServerGroups).map('detachedInstances').flatten().value();\n return $q.resolve(loadBalancer);\n }\n\n function convertLoadBalancerForEditing(loadBalancer) {\n const toEdit = {\n region: loadBalancer.region,\n credentials: loadBalancer.account,\n name: loadBalancer.name,\n stack: loadBalancer.stack,\n detail: loadBalancer.detail,\n vnet: loadBalancer.vnet,\n subnet: loadBalancer.subnet,\n probes: [],\n loadBalancingRules: [],\n };\n\n if (loadBalancer.elb) {\n const elb = loadBalancer.elb;\n\n toEdit.securityGroups = elb.securityGroups;\n toEdit.vnet = elb.vnet;\n\n if (elb.loadBalancingRules) {\n toEdit.loadBalancingRules = elb.loadBalancingRules;\n }\n\n toEdit.probes = elb.probes;\n if (elb.dnsName && elb.dnsName !== 'dns-not-found') {\n toEdit.dnsName = elb.dnsName.split('.')[0];\n }\n }\n return toEdit;\n }\n\n function constructNewLoadBalancerTemplate(application) {\n const defaultCredentials = application.defaultCredentials.azure || AzureProviderSettings.defaults.account;\n const defaultRegion = application.defaultRegions.azure || AzureProviderSettings.defaults.region;\n return {\n stack: '',\n detail: 'frontend',\n credentials: defaultCredentials,\n region: defaultRegion,\n cloudProvider: 'azure',\n vnet: null,\n subnet: null,\n probes: [\n {\n probeName: '',\n probeProtocol: 'HTTP',\n probePort: '80',\n probePath: '/',\n probeInterval: 30,\n unhealthyThreshold: 8,\n timeout: 120,\n },\n ],\n securityGroups: [],\n loadBalancingRules: [\n {\n ruleName: '',\n protocol: 'HTTP',\n externalPort: 80,\n backendPort: 80,\n probeName: '',\n persistence: 'None',\n idleTimeout: 4,\n },\n ],\n };\n }\n\n return {\n normalizeLoadBalancer: normalizeLoadBalancer,\n convertLoadBalancerForEditing: convertLoadBalancerForEditing,\n constructNewLoadBalancerTemplate: constructNewLoadBalancerTemplate,\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, LoadBalancerWriter, NameUtils, NetworkReader, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from '../loadBalancer.transformer';\n\nexport const AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER =\n 'spinnaker.azure.loadBalancer.create.controller';\nexport const name = AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER; // for backwards compatibility\nmodule(AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n]).controller('azureCreateLoadBalancerCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n 'azureLoadBalancerTransformer',\n 'application',\n 'loadBalancer',\n 'isNew',\n 'loadBalancerType',\n function (\n $scope,\n $uibModalInstance,\n $state,\n azureLoadBalancerTransformer,\n application,\n loadBalancer,\n isNew,\n loadBalancerType,\n ) {\n const ctrl = this;\n\n $scope.regions = [];\n\n $scope.pages = {\n location: require('./createLoadBalancerProperties.html'),\n listeners: require('./listeners.html'),\n healthCheck: require('./healthCheck.html'),\n advancedSettings: require('./advancedSettings.html'),\n };\n\n $scope.isNew = isNew;\n $scope.loadBalancerType = loadBalancerType.type;\n $scope.isALB = loadBalancerType.type === 'Azure Load Balancer';\n\n $scope.state = {\n accountsLoaded: false,\n submitting: false,\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.loadBalancer.name,\n accountId: $scope.loadBalancer.credentials,\n region: $scope.loadBalancer.region,\n provider: 'azure',\n };\n\n if (!$state.includes('**.loadBalancerDetails')) {\n $state.go('.loadBalancerDetails', newStateParams);\n } else {\n $state.go('^.loadBalancerDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.loadBalancers.refresh();\n application.loadBalancers.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: (isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function initializeCreateMode() {\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accountsLoaded = true;\n ctrl.accountUpdated();\n });\n }\n\n function initializeController() {\n if (loadBalancer) {\n $scope.loadBalancer = azureLoadBalancerTransformer.convertLoadBalancerForEditing(loadBalancer);\n if (isNew) {\n const nameParts = NameUtils.parseLoadBalancerName($scope.loadBalancer.name);\n $scope.loadBalancer.stack = nameParts.stack;\n $scope.loadBalancer.detail = nameParts.freeFormDetails;\n delete $scope.loadBalancer.name;\n }\n } else {\n $scope.loadBalancer = azureLoadBalancerTransformer.constructNewLoadBalancerTemplate(application);\n }\n if (isNew) {\n updateLoadBalancerNames();\n initializeCreateMode();\n }\n }\n\n function updateLoadBalancerNames() {\n const account = $scope.loadBalancer.credentials;\n const region = $scope.loadBalancer.region;\n\n const accountLoadBalancersByRegion = {};\n application\n .getDataSource('loadBalancers')\n .refresh(true)\n .then(() => {\n application.getDataSource('loadBalancers').data.forEach((loadBalancer) => {\n if (loadBalancer.account === account) {\n accountLoadBalancersByRegion[loadBalancer.region] =\n accountLoadBalancersByRegion[loadBalancer.region] || [];\n accountLoadBalancersByRegion[loadBalancer.region].push(loadBalancer.name);\n }\n });\n\n $scope.existingLoadBalancerNames = accountLoadBalancersByRegion[region] || [];\n });\n }\n\n initializeController();\n\n this.requiresHealthCheckPath = function () {\n return (\n $scope.loadBalancer.probes[0].probeProtocol && $scope.loadBalancer.probes[0].probeProtocol.indexOf('HTTP') === 0\n );\n };\n\n this.updateName = function () {\n $scope.loadBalancer.name = this.getName();\n };\n\n this.getName = function () {\n const elb = $scope.loadBalancer;\n const elbName = [application.name, elb.stack || '', elb.detail || ''].join('-');\n return _.trimEnd(elbName, '-');\n };\n\n this.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.loadBalancer.credentials).then(function (regions) {\n $scope.regions = regions;\n ctrl.regionUpdated();\n });\n };\n\n this.regionUpdated = function () {\n updateLoadBalancerNames();\n ctrl.updateName();\n ctrl.vnetUpdated();\n };\n\n this.vnetUpdated = function () {\n const account = $scope.loadBalancer.credentials;\n const region = $scope.loadBalancer.region;\n $scope.loadBalancer.selectedVnet = null;\n $scope.loadBalancer.vnet = null;\n $scope.loadBalancer.vnetResourceGroup = null;\n ctrl.selectedVnets = [];\n\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((vnet) => {\n if (vnet.account === account && vnet.region === region) {\n ctrl.selectedVnets.push(vnet);\n }\n });\n }\n });\n\n ctrl.subnetUpdated();\n };\n\n this.subnetUpdated = function () {\n $scope.loadBalancer.selectedSubnet = null;\n $scope.loadBalancer.subnet = null;\n ctrl.selectedSubnets = [];\n };\n\n this.selectedVnetChanged = function (item) {\n $scope.loadBalancer.vnet = item.name;\n $scope.loadBalancer.vnetResourceGroup = item.resourceGroup;\n $scope.loadBalancer.selectedSubnet = null;\n $scope.loadBalancer.subnet = null;\n ctrl.selectedSubnets = [];\n if (item.subnets) {\n item.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n if (device && device.type !== 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n ctrl.selectedSubnets.push(subnet);\n }\n });\n }\n };\n\n this.removeListener = function (index) {\n $scope.loadBalancer.loadBalancingRules.splice(index, 1);\n };\n\n this.addListener = function () {\n $scope.loadBalancer.loadBalancingRules.push({ protocol: 'HTTP' });\n };\n\n this.submit = function () {\n const descriptor = isNew ? 'Create' : 'Update';\n\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n clusterName: $scope.loadBalancer.clusterName,\n resourceGroupName: $scope.loadBalancer.clusterName,\n loadBalancerName: $scope.loadBalancer.name,\n };\n\n if ($scope.loadBalancer.selectedVnet) {\n $scope.loadBalancer.vnet = $scope.loadBalancer.selectedVnet.name;\n $scope.loadBalancer.vnetResourceGroup = $scope.loadBalancer.selectedVnet.resourceGroup;\n }\n\n if ($scope.loadBalancer.selectedSubnet) {\n $scope.loadBalancer.subnet = $scope.loadBalancer.selectedSubnet.name;\n }\n\n const name = $scope.loadBalancer.clusterName || $scope.loadBalancer.name;\n const probeName = name + '-probe';\n const ruleNameBase = name + '-rule';\n $scope.loadBalancer.type = 'upsertLoadBalancer';\n $scope.loadBalancer.loadBalancerType = $scope.loadBalancerType;\n if (!$scope.loadBalancer.vnet && !$scope.loadBalancer.subnetType) {\n $scope.loadBalancer.securityGroups = null;\n }\n\n $scope.loadBalancer.probes[0].probeName = probeName;\n\n $scope.loadBalancer.loadBalancingRules.forEach((rule, index) => {\n rule.ruleName = ruleNameBase + index;\n rule.probeName = probeName;\n });\n\n if ($scope.loadBalancer.probes[0].probeProtocol === 'TCP') {\n $scope.loadBalancer.probes[0].probePath = undefined;\n }\n\n return LoadBalancerWriter.upsertLoadBalancer($scope.loadBalancer, application, descriptor, params);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport {\n ConfirmationModalService,\n FirewallLabels,\n LOAD_BALANCER_READ_SERVICE,\n LoadBalancerWriter,\n SECURITY_GROUP_READER,\n} from '@spinnaker/core';\n\nexport const AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER =\n 'spinnaker.azure.loadBalancer.details.controller';\nexport const name = AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER, [\n ANGULAR_UI_BOOTSTRAP,\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n LOAD_BALANCER_READ_SERVICE,\n ])\n .controller('azureLoadBalancerDetailsCtrl', [\n '$scope',\n '$state',\n '$exceptionHandler',\n '$uibModal',\n 'loadBalancer',\n 'app',\n 'securityGroupReader',\n 'loadBalancerReader',\n '$q',\n function (\n $scope,\n $state,\n $exceptionHandler,\n $uibModal,\n loadBalancer,\n app,\n securityGroupReader,\n loadBalancerReader,\n $q,\n ) {\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n function extractLoadBalancer() {\n $scope.loadBalancer = app.loadBalancers.data.filter(function (test) {\n return (\n test.name === loadBalancer.name &&\n test.region === loadBalancer.region &&\n test.account === loadBalancer.accountId\n );\n })[0];\n\n if ($scope.loadBalancer) {\n const detailsLoader = loadBalancerReader.getLoadBalancerDetails(\n $scope.loadBalancer.provider,\n loadBalancer.accountId,\n loadBalancer.region,\n loadBalancer.name,\n );\n\n return detailsLoader.then(function (details) {\n $scope.state.loading = false;\n const securityGroups = [];\n\n const filtered = details.filter(function (test) {\n return test.name === loadBalancer.name;\n });\n\n if (filtered.length) {\n $scope.loadBalancer.elb = filtered[0];\n\n $scope.loadBalancer.account = loadBalancer.accountId;\n\n if ($scope.loadBalancer.elb.securityGroups) {\n $scope.loadBalancer.elb.securityGroups.forEach(function (securityGroupId) {\n const match = securityGroupReader.getApplicationSecurityGroup(\n app,\n loadBalancer.accountId,\n loadBalancer.region,\n securityGroupId,\n );\n if (match) {\n securityGroups.push(match);\n }\n });\n $scope.securityGroups = _.sortBy(securityGroups, 'name');\n }\n\n if ($scope.loadBalancer.loadBalancerType && $scope.loadBalancer.loadBalancerType.includes('_')) {\n const type = $scope.loadBalancer.loadBalancerType;\n $scope.loadBalancer.loadBalancerType = type\n .split('_')\n .map((s) => {\n const ss = s.toLowerCase();\n return ss.substring(0, 1).toUpperCase() + ss.substring(1);\n })\n .join(' ');\n }\n }\n });\n }\n if (!$scope.loadBalancer) {\n $state.go('^');\n }\n\n return $q.when(null);\n }\n\n app\n .ready()\n .then(extractLoadBalancer)\n .then(() => {\n // If the user navigates away from the view before the initial extractLoadBalancer call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.onRefresh($scope, extractLoadBalancer);\n }\n });\n\n this.editLoadBalancer = function editLoadBalancer() {\n $uibModal.open({\n templateUrl: require('../configure/editLoadBalancer.html'),\n controller: 'azureCreateLoadBalancerCtrl as ctrl',\n size: 'lg',\n resolve: {\n application: function () {\n return app;\n },\n loadBalancer: function () {\n return angular.copy($scope.loadBalancer);\n },\n isNew: function () {\n return false;\n },\n loadBalancerType: function () {\n return { type: $scope.loadBalancer.loadBalancerType };\n },\n },\n });\n };\n\n this.deleteLoadBalancer = function deleteLoadBalancer() {\n if ($scope.loadBalancer.instances && $scope.loadBalancer.instances.length) {\n return;\n }\n\n const taskMonitor = {\n application: app,\n title: 'Deleting ' + loadBalancer.name,\n };\n\n const command = {\n cloudProvider: 'azure',\n loadBalancerName: $scope.loadBalancer.name,\n loadBalancerType: $scope.loadBalancer.loadBalancerType,\n credentials: $scope.loadBalancer.account,\n region: loadBalancer.region,\n appName: app.name,\n };\n\n const submitMethod = () => LoadBalancerWriter.deleteLoadBalancer(command, app);\n\n ConfirmationModalService.confirm({\n header: 'Really delete ' + loadBalancer.name + '?',\n buttonText: 'Delete ' + loadBalancer.name,\n account: loadBalancer.accountId,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { SETTINGS } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER =\n 'spinnaker.azure.pipeline.stage.bake.executionDetails.controller';\nexport const name = AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER, [UIROUTER_ANGULARJS]).controller(\n 'azureBakeExecutionDetailsCtrl',\n [\n '$scope',\n '$stateParams',\n 'executionDetailsSectionService',\n '$interpolate',\n function ($scope, $stateParams, executionDetailsSectionService, $interpolate) {\n $scope.configSections = ['bakeConfig', 'taskStatus'];\n\n const initialized = () => {\n $scope.detailsSection = $stateParams.details;\n $scope.provider = $scope.stage.context.cloudProviderType || 'azure';\n $scope.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' &&\n SETTINGS.feature.roscoSelector($scope.stage.context));\n $scope.bakeryDetailUrl = $interpolate(\n $scope.roscoMode && SETTINGS.roscoDetailUrl ? SETTINGS.roscoDetailUrl : SETTINGS.bakeryDetailUrl,\n );\n };\n\n const initialize = () => executionDetailsSectionService.synchronizeSection($scope.configSections, initialized);\n\n initialize();\n\n $scope.$on('$stateChangeSuccess', initialize);\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n AuthenticationService,\n BakeExecutionLabel,\n BakeryReader,\n PipelineTemplates,\n Registry,\n SETTINGS,\n} from '@spinnaker/core';\n\nimport { AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER } from './bakeExecutionDetails.controller';\n\nexport const AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE = 'spinnaker.azure.pipeline.stage.bakeStage';\nexport const name = AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE, [AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'bake',\n cloudProvider: 'azure',\n label: 'Bake',\n description: 'Bakes an image',\n templateUrl: require('./bakeStage.html'),\n executionDetailsUrl: require('./bakeExecutionDetails.html'),\n executionLabelComponent: BakeExecutionLabel,\n extraLabelLines: (stage) => {\n return stage.masterStage.context.allPreviouslyBaked || stage.masterStage.context.somePreviouslyBaked ? 1 : 0;\n },\n supportsCustomTimeout: true,\n validators: [\n { type: 'requiredField', fieldName: 'package' },\n { type: 'requiredField', fieldName: 'regions' },\n {\n type: 'upstreamVersionProvided',\n checkParentTriggers: true,\n getMessage: (labels) =>\n 'Bake stages should always have a stage or trigger preceding them that provides version information: ' +\n '<ul>' +\n labels.map((label) => `<li>${label}</li>`).join('') +\n '</ul>' +\n 'Otherwise, Spinnaker will bake and deploy the most-recently built package.',\n },\n ],\n restartable: true,\n });\n })\n .controller('azureBakeStageCtrl', [\n '$scope',\n '$q',\n '$uibModal',\n function ($scope, $q, $uibModal) {\n $scope.stage.extendedAttributes = $scope.stage.extendedAttributes || {};\n $scope.stage.regions = $scope.stage.regions || [];\n\n if (!$scope.stage.user) {\n $scope.stage.user = AuthenticationService.getAuthenticatedUser().name;\n }\n\n $scope.viewState = {\n loading: true,\n };\n\n function initialize() {\n $q.all([\n BakeryReader.getRegions('azure'),\n BakeryReader.getBaseOsOptions('azure'),\n BakeryReader.getBaseLabelOptions(),\n ]).then(function ([regions, baseOsOptions, baseLabelOptions]) {\n $scope.regions = regions;\n if ($scope.regions.length === 1) {\n $scope.stage.region = $scope.regions[0];\n } else if (!$scope.regions.includes($scope.stage.region)) {\n delete $scope.stage.region;\n }\n if (!$scope.stage.regions.length && $scope.application.defaultRegions.azure) {\n $scope.stage.regions.push($scope.application.defaultRegions.azure);\n }\n if (!$scope.stage.regions.length && $scope.application.defaultRegions.azure) {\n $scope.stage.regions.push($scope.application.defaultRegions.azure);\n }\n $scope.baseOsOptions = baseOsOptions.baseImages;\n if ($scope.baseOsOptions.length) {\n $scope.stage.osType = baseOsOptions.baseImages[0].osType;\n }\n\n $scope.baseLabelOptions = baseLabelOptions;\n\n if (!$scope.stage.baseOs && $scope.baseOsOptions && $scope.baseOsOptions.length) {\n $scope.stage.baseOs = $scope.baseOsOptions[0].id;\n }\n\n if (!$scope.stage.baseLabel && $scope.baseLabelOptions && $scope.baseLabelOptions.length) {\n $scope.stage.baseLabel = $scope.baseLabelOptions[0];\n }\n $scope.viewState.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector($scope.stage));\n $scope.showAdvancedOptions = showAdvanced();\n $scope.viewState.loading = false;\n });\n }\n\n this.baseOsChanged = () => {\n const selectedOption = _.find($scope.baseOsOptions, { id: $scope.stage.baseOs });\n $scope.stage.osType = selectedOption.osType;\n };\n\n function stageUpdated() {\n deleteEmptyProperties();\n // Since the selector computes using stage as an input, it needs to be able to recompute roscoMode on updates\n if (typeof SETTINGS.feature.roscoSelector === 'function') {\n $scope.viewState.roscoMode = SETTINGS.feature.roscoSelector($scope.stage);\n }\n }\n\n function showAdvanced() {\n const stg = $scope.stage;\n return !!(\n stg.templateFileName ||\n (stg.extendedAttributes && _.size(stg.extendedAttributes) > 0) ||\n stg.varFileName\n );\n }\n\n function deleteEmptyProperties() {\n _.forOwn($scope.stage, function (val, key) {\n if (val === '') {\n delete $scope.stage[key];\n }\n });\n }\n\n this.addExtendedAttribute = function () {\n if (!$scope.stage.extendedAttributes) {\n $scope.stage.extendedAttributes = {};\n }\n $uibModal\n .open({\n templateUrl: PipelineTemplates.addExtendedAttributes,\n controller: 'bakeStageAddExtendedAttributeController',\n controllerAs: 'addExtendedAttribute',\n resolve: {\n extendedAttribute: function () {\n return {\n key: '',\n value: '',\n };\n },\n },\n })\n .result.then(function (extendedAttribute) {\n $scope.stage.extendedAttributes[extendedAttribute.key] = extendedAttribute.value;\n })\n .catch(() => {});\n };\n\n this.removeExtendedAttribute = function (key) {\n delete $scope.stage.extendedAttributes[key];\n };\n\n this.showTemplateFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.templateFileName;\n };\n\n this.showExtendedAttributes = function () {\n return (\n $scope.viewState.roscoMode || ($scope.stage.extendedAttributes && _.size($scope.stage.extendedAttributes) > 0)\n );\n };\n\n this.showVarFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.varFileName;\n };\n\n $scope.$watch('stage', stageUpdated, true);\n\n initialize();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE = 'spinnaker.azure.pipeline.stage.destroyAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'destroyServerGroup',\n cloudProvider: 'azure',\n templateUrl: require('./destroyAsgStage.html'),\n executionStepLabelUrl: require('./destroyAsgStepLabel.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureDestroyAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n ctrl.accountUpdated = function () {\n AccountService.getAccountDetails(stage.credentials).then(function (details) {\n stage.regions = [details.org];\n // stage.regions = ['eastus', 'westus'];\n });\n };\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n stage.interestingHealthProviderNames = []; // bypass the check for now; will change this later to ['azureService']\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n\n if (stage.credentials) {\n ctrl.accountUpdated();\n }\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE = 'spinnaker.azure.pipeline.stage.disableAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'disableServerGroup',\n alias: 'disableAsg',\n cloudProvider: 'azure',\n templateUrl: require('./disableAsgStage.html'),\n executionStepLabelUrl: require('./disableAsgStepLabel.html'),\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureDisableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n if (stage.isNew && $scope.application.attributes.platformHealthOnly) {\n stage.interestingHealthProviderNames = []; // bypass the check for now; will change this later to ['azureService']\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.azure) {\n stage.regions.push($scope.application.defaultRegions.azure);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE = 'spinnaker.azure.pipeline.stage.enableAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'enableServerGroup',\n alias: 'enableAsg',\n cloudProvider: 'azure',\n templateUrl: require('./enableAsgStage.html'),\n executionStepLabelUrl: require('./enableAsgStepLabel.html'),\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureEnableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n ctrl.reset = () => {\n ctrl.accountUpdated();\n ctrl.resetSelectedCluster();\n };\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n if (stage.isNew) {\n // bypass the health check for now; will change this later to ['azureService'] and we will also add back the check for $scope.application.attributes.platformHealthOnly\n stage.interestingHealthProviderNames = [];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.azure) {\n stage.regions.push($scope.application.defaultRegions.azure);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n\n $scope.$watch('stage.credentials', $scope.accountUpdated);\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { FirewallLabels, InfrastructureCaches, TaskExecutor } from '@spinnaker/core';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE = 'spinnaker.azure.securityGroup.write.service';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE, [UIROUTER_ANGULARJS]).factory(\n 'azureSecurityGroupWriter',\n function () {\n function upsertSecurityGroup(securityGroup, application, descriptor, params = {}) {\n params.securityGroupName = securityGroup.name;\n\n // We want to extend params with all attributes from securityGroup, but only if they don't already exist.\n _.assignWith(params, securityGroup, function (value, other) {\n return _.isUndefined(value) ? other : value;\n });\n\n const operation = TaskExecutor.executeTask({\n job: [params],\n application: application,\n description: `${descriptor} ${FirewallLabels.get('Firewall')}: ${name}`,\n });\n\n InfrastructureCaches.clearCache('securityGroup');\n\n return operation;\n }\n\n function deleteSecurityGroup(securityGroup, application, params = {}) {\n params.type = 'deleteSecurityGroup';\n params.securityGroupName = securityGroup.name;\n params.regions = [securityGroup.region];\n params.credentials = securityGroup.accountId;\n //params.cloudProvider = securityGroup.providerType;\n params.appName = application.name;\n\n const operation = TaskExecutor.executeTask({\n job: [params],\n application: application,\n description: `Delete ${FirewallLabels.get('Firewalls')}: ${securityGroup.name}`,\n });\n\n InfrastructureCaches.clearCache('securityGroup');\n\n return operation;\n }\n\n return {\n deleteSecurityGroup: deleteSecurityGroup,\n upsertSecurityGroup: upsertSecurityGroup,\n };\n },\n);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, FirewallLabels, NetworkReader, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL = 'spinnaker.azure.securityGroup.create.controller';\nexport const name = AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL, [\n UIROUTER_ANGULARJS,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n]).controller('azureCreateSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n '$controller',\n 'application',\n 'securityGroup',\n 'azureSecurityGroupWriter',\n function ($scope, $uibModalInstance, $state, $controller, application, securityGroup, azureSecurityGroupWriter) {\n $scope.pages = {\n location: require('./createSecurityGroupProperties.html'),\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n $scope.regions = [];\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n const ctrl = this;\n $scope.isNew = true;\n $scope.state = {\n submitting: false,\n infiniteScroll: {\n numToAdd: 20,\n currentItems: 20,\n },\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n ctrl.accountUpdated();\n });\n\n ctrl.addMoreItems = function () {\n $scope.state.infiniteScroll.currentItems += $scope.state.infiniteScroll.numToAdd;\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.regions[0],\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Creating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n $scope.securityGroup = securityGroup;\n\n ctrl.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.securityGroup.credentials).then(function (regions) {\n $scope.regions = regions;\n $scope.securityGroup.regions = regions;\n ctrl.updateName();\n ctrl.regionUpdated();\n });\n };\n\n this.regionUpdated = function () {\n ctrl.vnetUpdated();\n };\n\n this.vnetUpdated = function () {\n const account = $scope.securityGroup.credentials;\n const region = $scope.securityGroup.region;\n $scope.securityGroup.selectedVnet = null;\n $scope.securityGroup.vnet = null;\n $scope.securityGroup.vnetResourceGroup = null;\n\n ctrl.selectedVnets = [];\n\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((vnet) => {\n if (vnet.account === account && vnet.region === region) {\n ctrl.selectedVnets.push(vnet);\n }\n });\n }\n });\n\n ctrl.subnetUpdated();\n };\n\n this.subnetUpdated = function () {\n $scope.securityGroup.selectedSubnet = null;\n $scope.securityGroup.subnet = null;\n ctrl.selectedSubnets = [];\n };\n\n this.selectedVnetChanged = function (item) {\n $scope.securityGroup.vnet = item.name;\n $scope.securityGroup.vnetResourceGroup = item.resourceGroup;\n $scope.securityGroup.selectedSubnet = null;\n $scope.securityGroup.subnet = null;\n ctrl.selectedSubnets = [];\n if (item.subnets) {\n item.subnets.map(function (subnet) {\n ctrl.selectedSubnets.push(subnet);\n });\n }\n };\n\n ctrl.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n ctrl.updateName = function () {\n const securityGroup = $scope.securityGroup;\n let name = application.name;\n if (securityGroup.detail) {\n name += '-' + securityGroup.detail;\n }\n securityGroup.name = name;\n $scope.namePreview = name;\n };\n\n ctrl.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n vpcId: 'null',\n };\n\n if ($scope.securityGroup.selectedVnet) {\n $scope.securityGroup.vnet = $scope.securityGroup.selectedVnet.name;\n $scope.securityGroup.vnetResourceGroup = $scope.securityGroup.selectedVnet.resourceGroup;\n }\n\n if ($scope.securityGroup.selectedSubnet) {\n $scope.securityGroup.subnet = $scope.securityGroup.selectedSubnet.name;\n }\n\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Create', params);\n });\n };\n\n ctrl.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length == 0 ? 100 : 100 * (ruleset.length + 1),\n protocolUI: 'tcp',\n protocol: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourceAddressPrefixes: [],\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '*',\n destinationPortRanges: [],\n destPortRanges: '*',\n sourceIPCIDRRanges: '*',\n });\n };\n\n ctrl.portUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].destPortRanges)) {\n const ruleRanges = ruleset[index].destPortRanges.split(',');\n\n if (ruleRanges.length > 1) {\n ruleset[index].destinationPortRanges = [];\n ruleRanges.forEach((v) => ruleset[index].destinationPortRanges.push(v));\n\n // If there are multiple port ranges then set null to the single port parameter otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRange = null;\n } else {\n ruleset[index].destinationPortRange = ruleset[index].destPortRanges;\n\n // If there is a single port range then set null to the port array otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRanges = [];\n }\n }\n };\n\n ctrl.sourceIPCIDRUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].destPortRanges)) {\n const ruleRanges = ruleset[index].sourceIPCIDRRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].sourceAddressPrefixes = [];\n ruleRanges.forEach((v) => ruleset[index].sourceAddressPrefixes.push(v));\n\n // If there are multiple IP/CIDR ranges then set null to the single sourceAddressPrefix parameter otherwise ARM template will fail in validation\n ruleset[index].sourceAddressPrefix = null;\n } else {\n ruleset[index].sourceAddressPrefix = ruleset[index].sourceIPCIDRRanges;\n\n // If there is a single IP/CIDR then set null to the IP/CIDR array otherwise ARM template will fail in validation.\n ruleset[index].sourceAddressPrefixes = [];\n }\n }\n };\n\n ctrl.protocolUpdated = function (ruleset, index) {\n ruleset[index].protocol = ruleset[index].protocolUI;\n };\n\n ctrl.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n ctrl.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n ctrl.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n $scope.securityGroup.securityRules = [];\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n CACHE_INITIALIZER_SERVICE,\n FirewallLabels,\n InfrastructureCaches,\n SECURITY_GROUP_READER,\n TaskMonitor,\n} from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL =\n 'spinnaker.azure.securityGroup.azure.edit.controller';\nexport const name = AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL, [\n UIROUTER_ANGULARJS,\n CACHE_INITIALIZER_SERVICE,\n SECURITY_GROUP_READER,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n]).controller('azureEditSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$exceptionHandler',\n '$state',\n 'securityGroupReader',\n 'cacheInitializer',\n 'application',\n 'securityGroup',\n 'azureSecurityGroupWriter',\n function (\n $scope,\n $uibModalInstance,\n $exceptionHandler,\n $state,\n securityGroupReader,\n cacheInitializer,\n application,\n securityGroup,\n azureSecurityGroupWriter,\n ) {\n $scope.pages = {\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n securityGroup.securityRules = _.map(securityGroup.securityRules, function (rule) {\n if (!_.isEmpty(rule.protocol)) {\n rule.protocolUI = rule.protocol.toLowerCase();\n }\n\n rule.destPortRanges = rule.destinationPortRangeModel;\n rule.sourceIPCIDRRanges = rule.sourceAddressPrefixModel;\n\n return rule;\n });\n\n $scope.securityGroup = securityGroup;\n\n $scope.state = {\n refreshingSecurityGroups: false,\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Updating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n this.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n this.refreshSecurityGroups = function () {\n $scope.state.refreshingSecurityGroups = true;\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n initializeSecurityGroups().then(function () {\n $scope.state.refreshingSecurityGroups = false;\n });\n });\n };\n\n function initializeSecurityGroups() {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n const account = securityGroup.accountName;\n const region = securityGroup.region;\n const availableGroups = _.filter(securityGroups[account].azure[region], {\n /*vpcId: vpcId*/\n });\n $scope.availableSecurityGroups = _.map(availableGroups, 'name');\n });\n }\n\n this.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length === 0 ? 100 : 100 * (ruleset.length + 1),\n protocolUI: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourceAddressPrefixes: [],\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '*',\n destinationPortRanges: [],\n destPortRanges: '*',\n sourceIPCIDRRanges: '*',\n });\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.region,\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n this.portUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].sourceIPCIDRRanges)) {\n const ruleRanges = ruleset[index].destPortRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].destinationPortRanges = [];\n ruleRanges.forEach((v) => ruleset[index].destinationPortRanges.push(v));\n\n // If there are multiple port ranges then set null to the single port parameter otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRange = null;\n } else {\n ruleset[index].destinationPortRange = ruleset[index].destPortRanges;\n\n // If there is a single port range then set null to the port array otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRanges = [];\n }\n }\n };\n\n this.sourceIPCIDRUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].sourceIPCIDRRanges)) {\n const ruleRanges = ruleset[index].sourceIPCIDRRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].sourceAddressPrefixes = [];\n ruleRanges.forEach((v) => ruleset[index].sourceAddressPrefixes.push(v));\n\n // If there are multiple IP/CIDR ranges then set null to the single sourceAddressPrefix parameter otherwise ARM template will fail in validation\n ruleset[index].sourceAddressPrefix = null;\n } else {\n ruleset[index].sourceAddressPrefix = ruleset[index].sourceIPCIDRRanges;\n\n // If there is a single IP/CIDR then set null to the IP/CIDR array otherwise ARM template will fail in validation.\n ruleset[index].sourceAddressPrefixes = [];\n }\n }\n };\n\n this.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n this.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n this.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n $scope.taskMonitor.onTaskComplete = $uibModalInstance.dismiss;\n\n this.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n subnet: null,\n vpcId: 'null',\n };\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Update', params);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, FirewallLabels, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL } from '../configure/CreateSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER = 'spinnaker.azure.securityGroup.clone.controller';\nexport const name = AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER, [\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL,\n]).controller('azureCloneSecurityGroupController', [\n '$scope',\n '$uibModalInstance',\n '$controller',\n '$state',\n 'azureSecurityGroupWriter',\n 'securityGroup',\n 'application',\n function ($scope, $uibModalInstance, $controller, $state, azureSecurityGroupWriter, securityGroup, application) {\n const ctrl = this;\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n $scope.pages = {\n location: require('../configure/createSecurityGroupProperties.html'),\n ingress: require('../configure/createSecurityGroupIngress.html'),\n };\n\n securityGroup.securityRules = _.map(securityGroup.securityRules, function (rule) {\n const temp = rule.destinationPortRange.split('-');\n rule.startPort = Number(temp[0]);\n rule.endPort = Number(temp[1]);\n return rule;\n });\n\n ctrl.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.securityGroup.credentials).then(function (regions) {\n $scope.regions = regions;\n $scope.securityGroup.regions = regions;\n ctrl.updateName();\n });\n };\n\n ctrl.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n ctrl.updateName = function () {\n const securityGroup = $scope.securityGroup;\n let name = application.name;\n if (securityGroup.detail) {\n name += '-' + securityGroup.detail;\n }\n securityGroup.name = name;\n $scope.namePreview = name;\n };\n\n $scope.securityGroup = securityGroup;\n\n $scope.state = {\n refreshingSecurityGroups: false,\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Updating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n ctrl.accountUpdated();\n });\n\n ctrl.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length === 0 ? 100 : 100 * (ruleset.length + 1),\n protocol: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '7001-7001',\n startPort: 7001,\n endPort: 7001,\n });\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.region,\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n ctrl.portUpdated = function (ruleset, index) {\n ruleset[index].destinationPortRange = ruleset[index].startPort + '-' + ruleset[index].endPort;\n };\n ctrl.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n ctrl.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n ctrl.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n ctrl.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n subnet: 'none',\n vpcId: 'null',\n };\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Clone', params);\n });\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { ConfirmationModalService, FirewallLabels, SECURITY_GROUP_READER } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER } from '../clone/cloneSecurityGroup.controller';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER =\n 'spinnaker.azure.securityGroup.azure.details.controller';\nexport const name = AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER, [\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER,\n ])\n .controller('azureSecurityGroupDetailsCtrl', [\n '$scope',\n '$state',\n 'resolvedSecurityGroup',\n 'app',\n 'azureSecurityGroupWriter',\n 'securityGroupReader',\n '$uibModal',\n function ($scope, $state, resolvedSecurityGroup, app, azureSecurityGroupWriter, securityGroupReader, $uibModal) {\n const application = app;\n const securityGroup = resolvedSecurityGroup;\n\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n function extractSecurityGroup() {\n return securityGroupReader\n .getSecurityGroupDetails(\n application,\n securityGroup.accountId,\n securityGroup.provider,\n securityGroup.region,\n securityGroup.vpcId,\n securityGroup.name,\n )\n .then(\n function (details) {\n $scope.state.loading = false;\n\n if (!details || _.isEmpty(details)) {\n fourOhFour();\n } else {\n $scope.securityGroup = details;\n }\n },\n function () {\n fourOhFour();\n },\n );\n }\n\n function fourOhFour() {\n $state.go('^');\n }\n\n extractSecurityGroup().then(() => {\n // If the user navigates away from the view before the initial extractSecurityGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.securityGroups.onRefresh($scope, extractSecurityGroup);\n }\n });\n\n this.editInboundRules = function editInboundRules() {\n $uibModal.open({\n templateUrl: require('../configure/editSecurityGroup.html'),\n controller: 'azureEditSecurityGroupCtrl as ctrl',\n resolve: {\n securityGroup: function () {\n return angular.copy($scope.securityGroup);\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.cloneSecurityGroup = function cloneSecurityGroup() {\n $uibModal.open({\n templateUrl: require('../clone/cloneSecurityGroup.html'),\n controller: 'azureCloneSecurityGroupController as ctrl',\n resolve: {\n securityGroup: function () {\n const securityGroup = angular.copy($scope.securityGroup);\n if (securityGroup.region) {\n securityGroup.regions = [securityGroup.region];\n }\n return securityGroup;\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.deleteSecurityGroup = function deleteSecurityGroup() {\n const taskMonitor = {\n application: application,\n title: 'Deleting ' + securityGroup.name,\n };\n\n const submitMethod = function () {\n $scope.securityGroup.type = 'deleteSecurityGroup';\n return azureSecurityGroupWriter.deleteSecurityGroup(securityGroup, application, {\n cloudProvider: 'azure',\n vpcId: $scope.securityGroup.vpcId,\n });\n };\n\n ConfirmationModalService.confirm({\n header: 'Really delete ' + securityGroup.name + '?',\n buttonText: 'Delete ' + securityGroup.name,\n account: securityGroup.accountId,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n if (app.isStandalone) {\n // we still want the edit to refresh the firewall details when the modal closes\n app.securityGroups = {\n refresh: extractSecurityGroup,\n };\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_READER = 'spinnaker.azure.securityGroup.reader';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_READER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_READER, []).factory('azureSecurityGroupReader', function () {\n function resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {\n //hack to get around securityGroupId not matching id in indexedSecurityGroups.\n const temp = securityGroupId.split('/');\n return indexedSecurityGroups[container.account][container.region][temp[temp.length - 1]];\n }\n\n return {\n resolveIndexedSecurityGroup: resolveIndexedSecurityGroup,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER = 'spinnaker.azure.securityGroup.transformer';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER, []).factory('azureSecurityGroupTransformer', function () {\n function normalizeSecurityGroup() {}\n\n return {\n normalizeSecurityGroup: normalizeSecurityGroup,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER = 'spinnaker.azure.serverGroup.transformer';\nexport const name = AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER, []).factory('azureServerGroupTransformer', function () {\n function normalizeServerGroup(serverGroup) {\n return serverGroup;\n }\n\n function parseCustomScriptsSettings(command, configuration) {\n /*\n At the first time this wizard pops up, the type of command.customScriptsSettings.fileUris is String. As for the following\n occurrences of its pop up with this field unchanged, its type becomes an array. So here differentiate the two scenarios\n to assign the correct value to model.\n */\n if (Array.isArray(command.customScriptsSettings.fileUris)) {\n configuration.customScriptsSettings.fileUris = command.customScriptsSettings.fileUris;\n } else {\n const fileUrisTemp = command.customScriptsSettings.fileUris;\n if (fileUrisTemp.includes(',')) {\n configuration.customScriptsSettings.fileUris = fileUrisTemp.split(',');\n } else if (fileUrisTemp.includes(';')) {\n configuration.customScriptsSettings.fileUris = fileUrisTemp.split(';');\n } else {\n configuration.customScriptsSettings.fileUris = [fileUrisTemp];\n }\n\n configuration.customScriptsSettings.fileUris.forEach(function (v, index) {\n configuration.customScriptsSettings.fileUris[index] = v.trim();\n });\n }\n }\n\n function convertServerGroupCommandToDeployConfiguration(command) {\n let tempImage;\n\n if (command.viewState.mode === 'editPipeline' || command.viewState.mode === 'createPipeline') {\n tempImage = {\n imageName: '',\n isCustom: 'true',\n publisher: '',\n offer: '',\n sku: '',\n version: '',\n region: command.region,\n uri: '',\n ostype: '',\n };\n } else {\n tempImage = command.selectedImage;\n }\n\n const configuration = {\n name: command.application,\n cloudProvider: command.selectedProvider,\n application: command.application,\n stack: command.stack,\n strategy: command.strategy,\n rollback: {\n onFailure: command.rollback ? command.rollback.onFailure : null,\n },\n scaleDown: command.scaleDown,\n maxRemainingAsgs: command.maxRemainingAsgs,\n delayBeforeDisableSec: command.delayBeforeDisableSec,\n delayBeforeScaleDownSec: command.delayBeforeScaleDownSec,\n allowDeleteActive: command.strategy === 'redblack' ? true : null,\n allowScaleDownActive: command.strategy === 'redblack' ? true : null,\n detail: command.freeFormDetails,\n freeFormDetails: command.freeFormDetails,\n healthSettings: command.healthSettings,\n image: command.image,\n account: command.credentials,\n selectedProvider: 'azure',\n vnet: command.vnet,\n vnetResourceGroup: command.selectedVnet.resourceGroup,\n subnet: command.subnet,\n useSourceCapacity: false,\n capacity: {\n min: command.sku.capacity,\n max: command.sku.capacity,\n },\n credentials: command.credentials,\n region: command.region,\n securityGroupName: command.securityGroupName,\n loadBalancerName: command.loadBalancerName,\n loadBalancerType: command.loadBalancerType,\n user: '[anonymous]',\n upgradePolicy: 'Manual',\n type: 'createServerGroup',\n sku: {\n name: 'Standard_DS1_v2',\n tier: 'Standard',\n capacity: command.sku.capacity,\n },\n instanceTags: command.instanceTags,\n dataDisks: command.dataDisks,\n userAssignedIdentities: command.userAssignedIdentities,\n viewState: command.viewState,\n osConfig: {\n customData: command.osConfig ? command.osConfig.customData : null,\n },\n customScriptsSettings: {\n fileUris: null,\n commandToExecute: '',\n },\n zonesEnabled: command.zonesEnabled,\n zones: command.zonesEnabled ? command.zones : [],\n enableInboundNAT: command.enableInboundNAT,\n };\n\n if (command.image == null || command.image.isCustom == false) {\n configuration.image = tempImage;\n }\n\n if (typeof command.stack !== 'undefined') {\n configuration.name = configuration.name + '-' + command.stack;\n }\n if (typeof command.freeFormDetails !== 'undefined') {\n configuration.name = configuration.name + '-' + command.freeFormDetails;\n }\n\n if (typeof command.customScriptsSettings !== 'undefined') {\n configuration.customScriptsSettings.commandToExecute = command.customScriptsSettings.commandToExecute;\n if (!_.isEmpty(command.customScriptsSettings.fileUris)) {\n parseCustomScriptsSettings(command, configuration);\n }\n }\n\n if (command.instanceType) {\n const vmsku = command.instanceType;\n configuration.instanceType = command.instanceType;\n configuration.sku.name = vmsku;\n configuration.sku.tier = vmsku.substring(0, vmsku.indexOf('_'));\n }\n\n // Default to an empty list of health provider names for now.\n configuration.interestingHealthProviderNames = [];\n\n return configuration;\n }\n\n return {\n convertServerGroupCommandToDeployConfiguration: convertServerGroupCommandToDeployConfiguration,\n normalizeServerGroup: normalizeServerGroup,\n parseCustomScriptsSettings: parseCustomScriptsSettings,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.instanceArchetype.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER, []).controller(\n 'azureInstanceArchetypeCtrl',\n [\n '$scope',\n 'instanceTypeService',\n 'modalWizardService',\n function ($scope, instanceTypeService, modalWizardService) {\n const wizard = modalWizardService.getWizard();\n\n $scope.$watch('command.viewState.instanceProfile', function () {\n if (!$scope.command.viewState.instanceProfile || $scope.command.viewState.instanceProfile === 'custom') {\n wizard.excludePage('instance-type');\n } else {\n wizard.includePage('instance-type');\n wizard.markClean('instance-profile');\n wizard.markComplete('instance-profile');\n }\n });\n\n $scope.$watch('command.viewState.instanceType', function (newVal) {\n if (newVal) {\n wizard.markClean('instance-profile');\n wizard.markComplete('instance-profile');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.instanceType.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER, []).controller('azureInstanceTypeCtrl', [\n '$scope',\n 'modalWizardService',\n function ($scope, modalWizardService) {\n modalWizardService.getWizard().markComplete('instance-type');\n modalWizardService.getWizard().markClean('instance-type');\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.advancedSetting.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupAdvancedSettingsCtrl',\n [\n '$scope',\n 'modalWizardService',\n function ($scope, modalWizardService) {\n modalWizardService.getWizard().markComplete('advanced');\n\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n modalWizardService.getWizard().markClean('advanced');\n } else {\n modalWizardService.getWizard().markDirty('advanced');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport * as angular from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE, [])\n .directive('azureServerGroupAdvancedSettingsSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./advancedSettingsSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'adv',\n controller: 'azureServerGroupAdvancedSettingsSelectorCtrl',\n };\n })\n .controller('azureServerGroupAdvancedSettingsSelectorCtrl', function () {\n this.addDataDisk = () => {\n const newDataDisks = angular.copy(this.command.dataDisks);\n this.command.dataDisks = newDataDisks.concat([\n {\n lun: 0,\n managedDisk: {\n storageAccountType: 'Standard_LRS',\n },\n diskSizeGB: 1,\n caching: 'None',\n createOption: 'Empty',\n },\n ]);\n };\n\n this.removeDataDisk = (index) => {\n const newDataDisks = angular.copy(this.command.dataDisks);\n newDataDisks.splice(index, 1);\n this.command.dataDisks = newDataDisks;\n };\n });\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER =\n 'spinnaker.azure.serverGroup.configure.basicSettings.image.filter';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER, []).filter('regional', function () {\n return function (input, selectedRegion) {\n return _.filter(input, function (image) {\n return image.region === selectedRegion || image.region === null;\n });\n };\n});\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { IMAGE_READER, ModalWizard } from '@spinnaker/core';\n\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER } from './image.regional.filter';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.basicSettings';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER, [\n UIROUTER_ANGULARJS,\n ANGULAR_UI_BOOTSTRAP,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER,\n IMAGE_READER,\n ])\n .controller('azureServerGroupBasicSettingsCtrl', [\n '$scope',\n '$controller',\n '$uibModalStack',\n '$state',\n 'imageReader',\n function ($scope, $controller, $uibModalStack, $state, imageReader) {\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n ModalWizard.markClean('basic-settings');\n ModalWizard.markComplete('basic-settings');\n } else {\n ModalWizard.markIncomplete('basic-settings');\n }\n });\n\n this.imageChanged = (image) => {\n $scope.command.imageName = image.imageName;\n $scope.command.selectedImage = image;\n ModalWizard.markClean('basic-settings');\n };\n\n angular.extend(\n this,\n $controller('BasicSettingsMixin', {\n $scope: $scope,\n imageReader: imageReader,\n $uibModalStack: $uibModalStack,\n $state: $state,\n }),\n );\n\n this.stackPattern = {\n test: function (stack) {\n const pattern = $scope.command.viewState.templatingEnabled ? /^([a-zA-Z0-9]*(\\${.+})*)*$/ : /^[a-zA-Z0-9]*$/;\n\n return pattern.test(stack);\n },\n };\n\n this.detailPattern = {\n test: function (detail) {\n const pattern = $scope.command.viewState.templatingEnabled\n ? /^([a-zA-Z0-9-]*(\\${.+})*)*$/\n : /^[a-zA-Z0-9-]*$/;\n\n return pattern.test(detail);\n },\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE, [])\n .directive('azureServerGroupCapacitySelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./capacitySelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'cap',\n controller: 'azureServerGroupCapacitySelectorCtrl',\n };\n })\n .controller('azureServerGroupCapacitySelectorCtrl', function () {});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.healthSetting.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupHealthSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n if (typeof $scope.command.healthSettings === 'undefined') {\n $scope.command.healthSettings = {};\n }\n\n this.healthCheckProtocols = [\n { displayName: 'N/A', name: null },\n { displayName: 'HTTP', name: 'http' },\n { displayName: 'TCP', name: 'tcp' },\n ];\n\n this.requiresHealthCheckPath = function () {\n return $scope.command.healthSettings.protocol === 'http';\n };\n\n this.changeHealthCheckProtocol = function (newProtocol) {\n if (newProtocol == null) {\n $scope.command.healthSettings.protocol = null;\n $scope.command.healthSettings.port = null;\n $scope.command.healthSettings.requestPath = null;\n } else if (!this.requiresHealthCheckPath()) {\n $scope.command.healthSettings.requestPath = null;\n }\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupHealthSettingsSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n templateUrl: require('./healthSettingsSelector.directive.html'),\n scope: {\n command: '=',\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.imageSettings.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupImageSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n this.clearImage = function () {\n if ($scope.command.image.isCustom == false) {\n $scope.command.image = { isCustom: false };\n } else {\n $scope.command.image.region = $scope.command.region;\n }\n };\n\n ModalWizard.markComplete('image-settings');\n\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n ModalWizard.markClean('image-settings');\n } else {\n ModalWizard.markDirty('image-settings');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE, []).directive(\n 'azureServerGroupImageSettingsSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n templateUrl: require('./imageSettingsSelector.directive.html'),\n scope: {\n command: '=',\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { InfrastructureCaches, LOAD_BALANCER_READ_SERVICE, ModalWizard, NetworkReader } from '@spinnaker/core';\n\nimport Utility from '../../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.loadBalancer.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER, [\n LOAD_BALANCER_READ_SERVICE,\n]).controller('azureServerGroupLoadBalancersCtrl', [\n '$scope',\n 'loadBalancerReader',\n function ($scope, loadBalancerReader) {\n ModalWizard.markClean('load-balancers');\n\n function loadVnetSubnets(item, type) {\n loadBalancerReader\n .getLoadBalancerDetails('azure', $scope.command.credentials, $scope.command.region, item)\n .then(function (LBs) {\n if (!LBs || LBs.length === 0) {\n // load the subnet and vnets without a load balancer\n const attachedVnet = $scope.command.selectedVnet;\n const attachedSubnet = $scope.command.selectedSubnet;\n $scope.command.selectedVnetSubnets = [];\n $scope.command.allVnets = [];\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((selectedVnet) => {\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region\n ) {\n $scope.command.allVnets.push(selectedVnet);\n\n selectedVnet.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n // only add subnets that are not assigned to an ApplicationGateway\n if (device && device.type === 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n $scope.command.selectedVnetSubnets.push(subnet.name);\n if (subnet.name === attachedSubnet) {\n $scope.command.selectedSubnet = attachedSubnet;\n }\n }\n });\n }\n });\n }\n });\n } else if (LBs && LBs.length === 1) {\n const selectedLoadBalancer = LBs[0];\n const attachedVnet = $scope.command.selectedVnet;\n $scope.command.selectedVnet = null;\n $scope.command.selectedVnetSubnets = [];\n $scope.command.allVnets = [];\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((selectedVnet) => {\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region\n ) {\n $scope.command.allVnets.push(selectedVnet);\n }\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region &&\n ((type === 'Azure Application Gateway' && selectedVnet.name == selectedLoadBalancer.vnet) ||\n (type === 'Azure Load Balancer' && selectedVnet.name === attachedVnet.name))\n ) {\n $scope.command.selectedVnet = selectedVnet;\n selectedVnet.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n // only add subnets that are not assigned to an ApplicationGateway\n if (device && device.type === 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n $scope.command.selectedVnetSubnets.push(subnet.name);\n }\n });\n }\n });\n }\n });\n }\n });\n }\n\n if ($scope.command.credentials && $scope.command.region) {\n $scope.command.viewState.networkSettingsConfigured = true;\n $scope.command.selectedVnetSubnets = [];\n if ($scope.command.loadBalancerName !== null && typeof $scope.command.loadBalancerName !== 'undefined') {\n $scope.useLoadBalancer = true;\n }\n loadVnetSubnets($scope.command.loadBalancerName, $scope.command.loadBalancerType);\n }\n\n this.loadBalancerChanged = function (item) {\n $scope.command.viewState.networkSettingsConfigured = true;\n ModalWizard.markComplete('load-balancers');\n\n const loadBalancers = $scope.command.backingData.loadBalancers;\n let loadBalancerType = null;\n\n if (loadBalancers) {\n const loadBalancerToFind = loadBalancers.find((lb) => lb.name === item);\n if (loadBalancerToFind) {\n loadBalancerType = Utility.getLoadBalancerType(loadBalancerToFind.loadBalancerType).type;\n }\n }\n\n if (item === null) {\n $scope.command.loadBalancerName = null;\n }\n\n $scope.command.selectedVnetSubnets = [];\n $scope.command.loadBalancerType = loadBalancerType;\n InfrastructureCaches.clearCache('networks');\n loadVnetSubnets(item, loadBalancerType);\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.loadBalancer.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupLoadBalancersSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./serverGroupLoadBalancersSelector.directive.html'),\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.networkSettings.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupNetworkSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n ModalWizard.markClean('network-settings');\n\n $scope.command.selectedVnet = {\n name: $scope.command.vnet,\n };\n\n $scope.command.selectedSubnet = $scope.command.subnet;\n\n this.vnetChanged = function (item) {\n $scope.command.vnet = item;\n $scope.command.subnet = $scope.command.selectedSubnet = null;\n $scope.command.selectedVnetSubnets = item.subnets.map((s) => s.name);\n };\n\n this.networkSettingsChanged = function (item) {\n $scope.command.vnet = $scope.command.selectedVnet.name;\n $scope.command.subnet = item;\n ModalWizard.markComplete('network-settings');\n };\n\n this.getVnetName = function () {\n if ($scope.command.selectedVnet) {\n return $scope.command.selectedVnet.name;\n } else {\n return 'Virtual network was not selected';\n }\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.networkSettings.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupNetworkSettingsSelector',\n function () {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./ServerGroupNetworkSettingsSelector.directive.html'),\n };\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.securityGroups.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER, []).controller(\n 'azureServerGroupSecurityGroupsCtrl',\n [\n '$scope',\n function ($scope) {\n ModalWizard.markClean('security-groups');\n ModalWizard.markComplete('security-groups');\n\n $scope.command.selectedSecurityGroup = {\n id: $scope.command.securityGroupName,\n };\n\n this.securityGroupChanged = function (securityGroup) {\n $scope.command.securityGroupName = securityGroup.id;\n ModalWizard.markComplete('security-groups');\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { FirewallLabels, InfrastructureCaches } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.securityGroupSelector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupSecurityGroupsSelector',\n [\n 'azureServerGroupConfigurationService',\n function (azureServerGroupConfigurationService) {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./serverGroupSecurityGroupsSelector.directive.html'),\n link: function (scope) {\n scope.firewallLabel = FirewallLabels.get('firewall');\n\n scope.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n scope.refreshSecurityGroups = function () {\n scope.refreshing = true;\n azureServerGroupConfigurationService.refreshSecurityGroups(scope.command).then(function () {\n scope.refreshing = false;\n });\n };\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport Utility from '../../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.tags.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE, [])\n .directive('azureTagsSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./tagsSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'tagsSelectorCtrl',\n controller: 'TagsSelectorCtrl',\n };\n })\n .controller('TagsSelectorCtrl', [\n '$scope',\n function () {\n this.getTagResult = function () {\n return Utility.checkTags(this.command.instanceTags);\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE, []).directive('azureZoneSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./zoneSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: [\n '$scope',\n function ($scope) {\n this.updateEnableInboundNAT = () => {\n if ($scope.vm.command.zonesEnabled) {\n $scope.vm.command.enableInboundNAT = false;\n }\n };\n },\n ],\n };\n});\n","import { module } from 'angular';\n\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../serverGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER } from './wizard/ServerGroupInstanceArchetype.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER } from './wizard/ServerGroupInstanceType.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER } from './wizard/advancedSettings/ServerGroupAdvancedSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE } from './wizard/advancedSettings/advancedSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER } from './wizard/basicSettings/ServerGroupBasicSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE } from './wizard/capacity/capacitySelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER } from './wizard/healthSettings/ServerGroupHealthSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE } from './wizard/healthSettings/healthSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER } from './wizard/image/ServerGroupImageSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE } from './wizard/image/imageSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER } from './wizard/loadBalancers/ServerGroupLoadBalancers.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE } from './wizard/loadBalancers/serverGroupLoadBalancersSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER } from './wizard/networkSettings/ServerGroupNetworkSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE } from './wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER } from './wizard/securityGroup/ServerGroupSecurityGroups.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE } from './wizard/securityGroup/serverGroupSecurityGroupsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE } from './wizard/tags/tagsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE } from './wizard/zones/zoneSelector.directive';\n\n('use strict');\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE = 'spinnaker.azure.serverGroup.configure';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE, [\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE,\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n AccountService,\n CACHE_INITIALIZER_SERVICE,\n LOAD_BALANCER_READ_SERVICE,\n SECURITY_GROUP_READER,\n} from '@spinnaker/core';\nimport { AZURE_IMAGE_IMAGE_READER } from '../../image/image.reader';\nimport { AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE } from '../../instance/azureInstanceType.service';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE =\n 'spinnaker.azure.serverGroup.configure.service';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE, [\n AZURE_IMAGE_IMAGE_READER,\n LOAD_BALANCER_READ_SERVICE,\n SECURITY_GROUP_READER,\n CACHE_INITIALIZER_SERVICE,\n AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE,\n ])\n .factory('azureServerGroupConfigurationService', [\n '$q',\n 'azureImageReader',\n 'securityGroupReader',\n 'cacheInitializer',\n 'loadBalancerReader',\n 'azureInstanceTypeService',\n function (\n $q,\n azureImageReader,\n securityGroupReader,\n cacheInitializer,\n loadBalancerReader,\n azureInstanceTypeService,\n ) {\n const dataDiskTypes = ['Standard_LRS', 'StandardSSD_LRS', 'Premium_LRS'];\n const dataDiskCachingTypes = ['None', 'ReadOnly', 'ReadWrite'];\n\n const healthCheckTypes = ['EC2', 'ELB'];\n const terminationPolicies = [\n 'OldestInstance',\n 'NewestInstance',\n 'OldestLaunchConfiguration',\n 'ClosestToNextInstanceHour',\n 'Default',\n ];\n\n function configureUpdateCommand(command) {\n command.backingData = {\n healthCheckTypes: angular.copy(healthCheckTypes),\n terminationPolicies: angular.copy(terminationPolicies),\n };\n }\n\n function configureCommand(application, command) {\n return $q\n .all([\n AccountService.getCredentialsKeyedByAccount('azure'),\n securityGroupReader.loadSecurityGroups(),\n loadBalancerReader.loadLoadBalancers(application.name),\n ])\n .then(function ([credentialsKeyedByAccount, securityGroups, loadBalancers]) {\n command.backingData = {\n credentialsKeyedByAccount,\n securityGroups,\n loadBalancers,\n dataDiskTypes: angular.copy(dataDiskTypes),\n dataDiskCachingTypes: angular.copy(dataDiskCachingTypes),\n accounts: _.keys(credentialsKeyedByAccount),\n filtered: {},\n };\n attachEventHandlers(command);\n });\n }\n\n function configureInstanceTypes(command) {\n const result = {\n dirty: {},\n };\n if (command.region) {\n const results = [result.dirty];\n\n // results.push(configureCustomInstanceTypes(command).dirty);\n results.push(configureStandardInstanceTypes(command).dirty);\n\n angular.extend(...results);\n } else {\n command.backingData.filtered.instanceTypes = [];\n }\n return result;\n }\n\n function configureStandardInstanceTypes(command) {\n const c = command;\n const result = {\n dirty: {},\n };\n\n const locations = [c.region];\n const { credentialsKeyedByAccount } = c.backingData;\n const { locationToInstanceTypesMap } = credentialsKeyedByAccount[c.credentials];\n\n if (locations.every((l) => !l)) {\n return result;\n }\n\n const filtered = azureInstanceTypeService\n .getAvailableTypesForRegions(locationToInstanceTypesMap, locations)\n .map((type) => type.name);\n\n const instanceType = c.instanceType;\n if (_.every([instanceType, !_.startsWith(instanceType, 'custom'), !_.includes(filtered, instanceType)])) {\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n c.backingData.filtered.instanceTypes = filtered;\n return result;\n }\n\n function configureImages(command) {\n const result = {\n dirty: {},\n };\n let regionalImages = null;\n if (command.viewState.disableImageSelection) {\n return result;\n }\n if (command.region) {\n regionalImages = command.backingData.packageImages\n .filter(function (image) {\n return image.amis && image.amis[command.region];\n })\n .map(function (image) {\n return {\n imageName: image.imageName,\n ami: image.amis ? image.amis[command.region][0] : null,\n };\n });\n if (\n command.amiName &&\n !regionalImages.some(function (image) {\n return image.imageName === command.amiName;\n })\n ) {\n result.dirty.amiName = true;\n command.amiName = null;\n }\n } else {\n command.amiName = null;\n }\n command.backingData.filtered.images = regionalImages;\n return result;\n }\n\n function configureZones(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (!command.region) {\n return result;\n }\n let { regionsSupportZones, availabilityZones } = command.backingData.credentialsKeyedByAccount[\n command.credentials\n ];\n regionsSupportZones = regionsSupportZones || [];\n availabilityZones = availabilityZones || [];\n filteredData.zones = regionsSupportZones.includes(command.region) ? availabilityZones : [];\n\n return result;\n }\n\n function getRegionalSecurityGroups(command) {\n const newSecurityGroups = command.backingData.securityGroups[command.credentials] || {\n azure: {},\n };\n return _.chain(newSecurityGroups[command.region]).sortBy('name').value();\n }\n\n function configureSecurityGroupOptions(command) {\n const result = {\n dirty: {},\n };\n let currentOptions;\n if (command.backingData.filtered.securityGroups) {\n currentOptions = command.backingData.filtered.securityGroups;\n }\n const newRegionalSecurityGroups = getRegionalSecurityGroups(command);\n if (command.selectedSecurityGroup) {\n // one has not been previously selected. We are either configuring for the\n //first time or they changed regions or account\n command.selectedSecurityGroup = null;\n result.dirty.securityGroups = true;\n }\n if (currentOptions != newRegionalSecurityGroups) {\n command.backingData.filtered.securityGroups = newRegionalSecurityGroups;\n result.dirty.securityGroups = true;\n }\n\n if (command.backingData.filtered.securityGroups === []) {\n command.viewState.securityGroupsConfigured = false;\n } else {\n command.viewState.securityGroupsConfigured = true;\n }\n\n return result;\n }\n\n function refreshSecurityGroups(command, skipCommandReconfiguration) {\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n command.backingData.securityGroups = securityGroups;\n if (!skipCommandReconfiguration) {\n configureSecurityGroupOptions(command);\n }\n });\n });\n }\n\n function getLoadBalancerNames(loadBalancers) {\n return _.chain(loadBalancers).map('name').uniq().value().sort();\n }\n\n function configureLoadBalancerOptions(command) {\n const result = {\n dirty: {},\n };\n const current = command.loadBalancers;\n const newLoadBalancers = getLoadBalancerNames(command.backingData.loadBalancers);\n\n if (current && command.loadBalancers) {\n const matched = _.intersection(newLoadBalancers, command.loadBalancers);\n const removed = _.xor(matched, current);\n command.loadBalancers = matched;\n if (removed.length) {\n result.dirty.loadBalancers = removed;\n }\n }\n command.backingData.filtered.loadBalancers = newLoadBalancers;\n return result;\n }\n\n function refreshLoadBalancers(command, skipCommandReconfiguration) {\n return loadBalancerReader.listLoadBalancers('azure').then(function (loadBalancers) {\n command.backingData.loadBalancers = loadBalancers;\n if (!skipCommandReconfiguration) {\n configureLoadBalancerOptions(command);\n }\n });\n }\n\n function configureLoadBalancers(command) {\n const result = {\n dirty: {},\n };\n const temp = command.backingData.loadBalancers;\n const filterlist = _.filter(temp, function (lb) {\n return lb.account === command.credentials && lb.region === command.region;\n });\n\n command.loadBalancers = getLoadBalancerNames(filterlist);\n command.viewState.loadBalancersConfigured = true;\n\n return result;\n }\n\n function attachEventHandlers(cmd) {\n cmd.regionChanged = function regionChanged(command, isInit = false) {\n const result = {\n dirty: {},\n };\n if (command.region && command.credentials) {\n angular.extend(result.dirty, configureLoadBalancers(command).dirty);\n angular.extend(result.dirty, configureSecurityGroupOptions(command).dirty);\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n angular.extend(result.dirty, configureZones(command).dirty);\n }\n // reset previous set values\n if (!isInit) {\n command.loadBalancerName = null;\n command.loadBalancerType = null;\n command.vnet = null;\n command.vnetResourceGroup = null;\n command.subnet = null;\n command.selectedSubnet = null;\n command.selectedVnet = null;\n command.selectedVnetSubnets = [];\n command.viewState.networkSettingsConfigured = false;\n command.selectedSecurityGroup = null;\n command.securityGroupName = null;\n command.zonesEnabled = false;\n command.zones = [];\n }\n\n return result;\n };\n\n cmd.credentialsChanged = function credentialsChanged(command, isInit) {\n const result = {\n dirty: {},\n };\n const backingData = command.backingData;\n if (command.credentials) {\n const regionsForAccount = backingData.credentialsKeyedByAccount[command.credentials] || {\n regions: [],\n defaultKeyPair: null,\n };\n backingData.filtered.regions = regionsForAccount.regions;\n if (\n !_.chain(backingData.filtered.regions)\n .some({\n name: command.region,\n })\n .value()\n ) {\n command.region = null;\n result.dirty.region = true;\n } else {\n angular.extend(result.dirty, command.regionChanged(command, isInit).dirty);\n }\n if (command.region) {\n angular.extend(result.dirty, configureLoadBalancers(command).dirty);\n }\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n } else {\n command.region = null;\n }\n return result;\n };\n }\n\n function refreshInstanceTypes(command) {\n return cacheInitializer.refreshCache('instanceTypes').then(function () {\n return azureInstanceTypeService.getAllTypesByRegion().then(function (instanceTypes) {\n command.backingData.instanceTypes = instanceTypes;\n configureInstanceTypes(command);\n });\n });\n }\n\n return {\n configureUpdateCommand: configureUpdateCommand,\n configureCommand: configureCommand,\n configureImages: configureImages,\n configureSecurityGroupOptions: configureSecurityGroupOptions,\n configureLoadBalancerOptions: configureLoadBalancerOptions,\n refreshLoadBalancers: refreshLoadBalancers,\n refreshSecurityGroups: refreshSecurityGroups,\n getRegionalSecurityGroups: getRegionalSecurityGroups,\n refreshInstanceTypes: refreshInstanceTypes,\n configureZones: configureZones,\n };\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { FirewallLabels, ModalWizard, SERVER_GROUP_WRITER, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../../serverGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE } from '../serverGroupConfiguration.service';\nimport Utility from '../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER =\n 'spinnaker.azure.cloneServerGroup.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n SERVER_GROUP_WRITER,\n]).controller('azureCloneServerGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$q',\n '$state',\n 'serverGroupWriter',\n 'azureServerGroupConfigurationService',\n 'serverGroupCommand',\n 'application',\n 'title',\n function (\n $scope,\n $uibModalInstance,\n $q,\n $state,\n serverGroupWriter,\n azureServerGroupConfigurationService,\n serverGroupCommand,\n application,\n title,\n ) {\n $scope.pages = {\n templateSelection: require('./templateSelection.html'),\n basicSettings: require('./basicSettings/basicSettings.html'),\n imageSettings: require('./image/imageSettings.html'),\n healthSettings: require('./healthSettings/healthSettings.html'),\n loadBalancers: require('./loadBalancers/loadBalancers.html'),\n networkSettings: require('./networkSettings/networkSettings.html'),\n securityGroups: require('./securityGroup/securityGroups.html'),\n instanceType: require('./instanceType/instanceType.html'),\n zones: require('./capacity/zones.html'),\n tags: require('./tags/tags.html'),\n advancedSettings: require('./advancedSettings/advancedSettings.html'),\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n $scope.title = title;\n\n $scope.applicationName = application.name;\n $scope.application = application;\n $scope.command = serverGroupCommand;\n\n // Give regions an init value to prevent it being undefined. If so, the React component RegionSelectField would get \"undefined\" for property regions\n // and then be unmounted so that the region selector would be hidden.\n $scope.command.backingData = $scope.command.backingData || {};\n $scope.command.backingData.filtered = $scope.command.backingData.filtered || {};\n $scope.command.backingData.filtered.regions = $scope.command.backingData.filtered.regions || [];\n\n $scope.state = {\n loaded: false,\n requiresTemplateSelection: !!serverGroupCommand.viewState.requiresTemplateSelection,\n };\n\n this.templateSelectionText = {\n copied: [\n 'account, region, subnet, cluster name (stack, details)',\n 'load balancers',\n FirewallLabels.get('firewalls'),\n 'instance type',\n 'all fields on the Advanced Settings page',\n ],\n notCopied: [],\n additionalCopyText:\n 'If a server group exists in this cluster at the time of deployment, its scaling policies will be copied over to the new server group.',\n };\n\n if (!$scope.command.viewState.disableStrategySelection) {\n this.templateSelectionText.notCopied.push(\n 'the deployment strategy (if any) used to deploy the most recent server group',\n );\n }\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n const cloneStage = $scope.taskMonitor.task.execution.stages.find((stage) => stage.type === 'cloneServerGroup');\n if (cloneStage && cloneStage.context['deploy.server.groups']) {\n const newServerGroupName = cloneStage.context['deploy.server.groups'][$scope.command.region];\n if (newServerGroupName) {\n const newStateParams = {\n serverGroup: newServerGroupName,\n accountId: $scope.command.credentials,\n region: $scope.command.region,\n provider: 'azure',\n };\n let transitionTo = '^.^.^.clusters.serverGroup';\n if ($state.includes('**.clusters.serverGroup')) {\n // clone via details, all view\n transitionTo = '^.serverGroup';\n }\n if ($state.includes('**.clusters.cluster.serverGroup')) {\n // clone or create with details open\n transitionTo = '^.^.serverGroup';\n }\n if ($state.includes('**.clusters')) {\n // create new, no details open\n transitionTo = '.serverGroup';\n }\n $state.go(transitionTo, newStateParams);\n }\n }\n }\n\n function onTaskComplete() {\n application.serverGroups.refresh();\n application.serverGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: 'Creating your server group',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function configureCommand() {\n azureServerGroupConfigurationService.configureCommand(application, serverGroupCommand).then(function () {\n const mode = serverGroupCommand.viewState.mode;\n if (mode === 'clone' || mode === 'create') {\n serverGroupCommand.viewState.useAllImageSelection = true;\n }\n $scope.state.loaded = true;\n initializeWizardState();\n initializeSelectOptions();\n initializeWatches();\n });\n }\n\n function initializeWizardState() {\n const mode = serverGroupCommand.viewState.mode;\n if (mode === 'clone' || mode === 'editPipeline') {\n ModalWizard.markComplete('basic-settings');\n ModalWizard.markComplete('load-balancers');\n ModalWizard.markComplete('network-settings');\n ModalWizard.markComplete('security-groups');\n ModalWizard.markComplete('instance-type');\n ModalWizard.markComplete('zones');\n }\n }\n\n function initializeWatches() {\n $scope.$watch('command.credentials', createResultProcessor($scope.command.credentialsChanged));\n $scope.$watch('command.region', createResultProcessor($scope.command.regionChanged));\n }\n\n function initializeSelectOptions() {\n processCommandUpdateResult($scope.command.credentialsChanged($scope.command, true));\n processCommandUpdateResult($scope.command.regionChanged($scope.command, true));\n }\n\n function createResultProcessor(method) {\n return function (newValue, oldValue) {\n if (newValue !== oldValue) {\n processCommandUpdateResult(method($scope.command));\n }\n };\n }\n\n function processCommandUpdateResult(result) {\n if (result.dirty.loadBalancers) {\n ModalWizard.markDirty('load-balancers');\n ModalWizard.markDirty('network-settings');\n }\n if (result.dirty.securityGroups) {\n ModalWizard.markDirty('security-groups');\n }\n if (result.dirty.instanceType) {\n ModalWizard.markDirty('instance-type');\n }\n if (result.dirty.zoneEnabled || result.dirty.zones) {\n ModalWizard.markDirty('zones');\n }\n }\n\n this.submit = function () {\n if ($scope.command.viewState.mode === 'editPipeline' || $scope.command.viewState.mode === 'createPipeline') {\n return $uibModalInstance.close($scope.command);\n }\n $scope.taskMonitor.submit(function () {\n return serverGroupWriter.cloneServerGroup($scope.command, application);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n this.toggleSuspendedProcess = function (process) {\n $scope.command.suspendedProcesses = $scope.command.suspendedProcesses || [];\n const processIndex = $scope.command.suspendedProcesses.indexOf(process);\n if (processIndex === -1) {\n $scope.command.suspendedProcesses.push(process);\n } else {\n $scope.command.suspendedProcesses.splice(processIndex, 1);\n }\n };\n\n this.processIsSuspended = function (process) {\n return $scope.command.suspendedProcesses.includes(process);\n };\n\n if (!$scope.state.requiresTemplateSelection) {\n configureCommand();\n } else {\n $scope.state.loaded = true;\n }\n\n this.templateSelected = () => {\n $scope.state.requiresTemplateSelection = false;\n configureCommand();\n };\n\n this.isValid = function () {\n return (\n $scope.command &&\n $scope.command.application &&\n $scope.command.credentials &&\n $scope.command.instanceType &&\n $scope.command.region &&\n (!$scope.command.zonesEnabled || $scope.command.zones.length !== 0) &&\n Utility.checkTags($scope.command.instanceTags).isValid\n );\n };\n },\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { NameUtils } from '@spinnaker/core';\nimport { AZURE_IMAGE_IMAGE_READER } from '../../image/image.reader';\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../serverGroup.transformer';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE =\n 'spinnaker.azure.serverGroupCommandBuilder.service';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE, [\n AZURE_IMAGE_IMAGE_READER,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n ])\n .factory('azureServerGroupCommandBuilder', [\n '$q',\n 'azureImageReader',\n 'azureServerGroupTransformer',\n function ($q, azureImageReader, azureServerGroupTransformer) {\n function buildNewServerGroupCommand(application, defaults) {\n defaults = defaults || {};\n\n const defaultCredentials = defaults.account || application.defaultCredentials.azure;\n const defaultRegion = defaults.region || application.defaultRegions.azure;\n\n return azureImageReader.findImages({ provider: 'azure' }).then(function (images) {\n return {\n application: application.name,\n credentials: defaultCredentials,\n region: defaultRegion,\n images,\n loadBalancers: [],\n selectedVnetSubnets: [],\n strategy: '',\n sku: {\n capacity: 1,\n },\n zonesEnabled: false,\n zones: [],\n instanceTags: {},\n dataDisks: [],\n selectedProvider: 'azure',\n viewState: {\n instanceProfile: 'custom',\n allImageSelection: null,\n useAllImageSelection: false,\n useSimpleCapacity: true,\n usePreferredZones: true,\n mode: defaults.mode || 'create',\n disableStrategySelection: true,\n loadBalancersConfigured: false,\n networkSettingsConfigured: false,\n securityGroupsConfigured: false,\n },\n enableInboundNAT: false,\n };\n });\n }\n\n // Only used to prepare view requiring template selecting\n function buildNewServerGroupCommandForPipeline() {\n return $q.when({\n viewState: {\n requiresTemplateSelection: true,\n },\n });\n }\n\n function buildServerGroupCommandFromExisting(application, serverGroup, mode) {\n mode = mode || 'clone';\n\n const serverGroupName = NameUtils.parseServerGroupName(serverGroup.name);\n\n const command = {\n application: application.name,\n strategy: '',\n stack: serverGroupName.stack,\n freeFormDetails: serverGroupName.freeFormDetails,\n credentials: serverGroup.account,\n loadBalancers: serverGroup.loadBalancers,\n selectedSubnets: serverGroup.selectedVnetSubnets,\n selectedVnet: serverGroup.selectedVnet,\n securityGroups: serverGroup.securityGroups,\n loadBalancerName: serverGroup.loadBalancerName,\n loadBalancerType: serverGroup.loadBalancerType,\n securityGroupName: serverGroup.securityGroupName,\n region: serverGroup.region,\n vnet: serverGroup.vnet,\n vnetResourceGroup: serverGroup.vnetResourceGroup,\n subnet: serverGroup.subnet,\n zones: serverGroup.zones,\n zonesEnabled: serverGroup.zones && serverGroup.zones.length > 0,\n instanceTags: {},\n dataDisks: serverGroup.dataDisks,\n sku: serverGroup.sku,\n capacity: {\n min: serverGroup.capacity.min,\n max: serverGroup.capacity.max,\n desired: serverGroup.capacity.desired,\n },\n tags: [],\n instanceType: serverGroup.sku.name,\n selectedProvider: 'azure',\n source: {\n account: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n asgName: serverGroup.name,\n },\n viewState: {\n allImageSelection: null,\n useAllImageSelection: false,\n useSimpleCapacity: true,\n usePreferredZones: false,\n listImplicitSecurityGroups: false,\n mode: mode,\n disableStrategySelection: true,\n },\n enableInboundNAT: serverGroup.enableInboundNAT,\n };\n\n if (typeof serverGroup.customScriptsSettings !== 'undefined') {\n command.customScriptsSettings = {};\n command.customScriptsSettings.commandToExecute = serverGroup.customScriptsSettings.commandToExecute;\n if (!_.isEmpty(serverGroup.customScriptsSettings.fileUris)) {\n azureServerGroupTransformer.parseCustomScriptsSettings(serverGroup, command);\n }\n }\n\n return $q.when(command);\n }\n\n function buildServerGroupCommandFromPipeline(application, originalCluster) {\n const pipelineCluster = _.cloneDeep(originalCluster);\n const region = pipelineCluster.region;\n\n const commandOptions = { account: pipelineCluster.account, region: region };\n return buildNewServerGroupCommand(application, commandOptions).then(function (command) {\n const viewState = {\n disableImageSelection: true,\n useSimpleCapacity: true,\n mode: 'editPipeline',\n submitButtonLabel: 'Done',\n instanceProfile: originalCluster.viewState.instanceProfile,\n instanceTypeDetails: originalCluster.viewState.instanceTypeDetails,\n };\n\n const viewOverrides = {\n region: region,\n credentials: pipelineCluster.account,\n viewState: viewState,\n };\n if (originalCluster.viewState.instanceTypeDetails) {\n viewOverrides.instanceType = originalCluster.viewState.instanceTypeDetails.name;\n }\n\n pipelineCluster.strategy = pipelineCluster.strategy || '';\n\n const extendedCommand = angular.extend({}, command, pipelineCluster, viewOverrides);\n\n return extendedCommand;\n });\n }\n\n return {\n buildNewServerGroupCommand: buildNewServerGroupCommand,\n buildNewServerGroupCommandForPipeline: buildNewServerGroupCommandForPipeline,\n buildServerGroupCommandFromExisting: buildServerGroupCommandFromExisting,\n buildServerGroupCommandFromPipeline: buildServerGroupCommandFromPipeline,\n };\n },\n ]);\n","import React from 'react';\n\nimport { UserVerification } from '@spinnaker/core';\n\nexport interface IAzureModalFooterProps {\n onSubmit: () => void;\n onCancel: () => void;\n isValid: boolean;\n account: string;\n}\n\nexport interface IAzureModalFooterState {\n verified: boolean;\n}\n\nexport class AzureModalFooter extends React.Component<IAzureModalFooterProps, IAzureModalFooterState> {\n constructor(props: any) {\n super(props);\n }\n\n public state = { verified: false };\n\n private handleVerification = (verified: boolean) => {\n this.setState({ verified });\n };\n\n public render() {\n const { onSubmit, onCancel, isValid, account } = this.props;\n const { verified } = this.state;\n\n return (\n <div className=\"modal-footer\">\n {<UserVerification expectedValue={account} onValidChange={this.handleVerification} />}\n <button className=\"btn btn-default\" onClick={onCancel}>\n Cancel\n </button>\n <button type=\"submit\" className=\"btn btn-primary\" onClick={onSubmit} disabled={!isValid || !verified}>\n Submit\n </button>\n </div>\n );\n }\n}\n","import React from 'react';\nimport { Modal } from 'react-bootstrap';\nimport Select from 'react-select';\n\nimport {\n IModalComponentProps,\n ModalClose,\n noop,\n ReactInjector,\n ReactModal,\n TaskMonitor,\n TaskMonitorWrapper,\n TaskReason,\n} from '@spinnaker/core';\n\nimport { AzureModalFooter } from '../../../common/AzureModalFooter';\n\nexport interface IAzureRollbackServerGroupModalProps extends IModalComponentProps {\n application: any;\n serverGroup: any;\n disabledServerGroups: any;\n}\n\nexport interface IAzureRollbackServerGroupModalState {\n taskMonitor: TaskMonitor;\n submitting: boolean;\n command: any;\n}\n\nexport class AzureRollbackServerGroupModal extends React.Component<\n IAzureRollbackServerGroupModalProps,\n IAzureRollbackServerGroupModalState\n> {\n public static defaultProps: Partial<IAzureRollbackServerGroupModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static show(props: IAzureRollbackServerGroupModalProps) {\n const modalProps = {};\n return ReactModal.show(AzureRollbackServerGroupModal, props, modalProps);\n }\n\n constructor(props: IAzureRollbackServerGroupModalProps) {\n super(props);\n\n const { application, serverGroup } = props;\n\n this.state = {\n taskMonitor: new TaskMonitor({\n application: application,\n title: 'Rolling back your server group',\n modalInstance: TaskMonitor.modalInstanceEmulation(() => this.props.dismissModal()),\n }),\n submitting: true,\n command: {\n interestingHealthProviderNames: [],\n rollbackType: 'EXPLICIT',\n rollbackContext: {\n rollbackServerGroupName: serverGroup.name,\n enableAndDisableOnly: true,\n },\n },\n };\n }\n\n private close = (args?: any) => {\n this.props.dismissModal.apply(null, args);\n };\n\n private submit = () => {\n const { command, taskMonitor } = this.state;\n const { serverGroup, application } = this.props;\n\n taskMonitor.submit(() => {\n return ReactInjector.serverGroupWriter.rollbackServerGroup(serverGroup, application, command);\n });\n };\n\n private filterServerGroups = (disabledServerGroups: any) => {\n const filteredDisabledServerGroups = disabledServerGroups\n .filter((disabledServerGroup: any) => disabledServerGroup.instanceCounts.total !== 0)\n .sort((a: any, b: any) => b.name.localeCompare(a.name));\n\n return filteredDisabledServerGroups;\n };\n\n private isValid = () => {\n const restoreServerGroupName = this.state.command.rollbackContext.restoreServerGroupName;\n return restoreServerGroupName !== undefined;\n };\n\n private handleServerGroupChange = (restoreServerGroupOption: any) => {\n const { disabledServerGroups } = this.props;\n const newCommand = { ...this.state.command };\n newCommand.rollbackContext.restoreServerGroupName = restoreServerGroupOption.value;\n const restoreServerGroup = this.filterServerGroups(disabledServerGroups).find(function (disabledServerGroup: any) {\n return disabledServerGroup.name === restoreServerGroupOption.value;\n });\n newCommand.targetSize = restoreServerGroup.capacity.max;\n this.setState({\n command: newCommand,\n });\n };\n\n private handleTaskReasonChange = (taskReason?: any) => {\n const newCommand = { ...this.state.command };\n newCommand.reason = taskReason;\n this.setState({\n command: newCommand,\n });\n };\n\n public render() {\n const { command, taskMonitor, submitting } = this.state;\n const { serverGroup, disabledServerGroups } = this.props;\n const isValidSG = this.isValid();\n const disabledServerGroupOptions = this.filterServerGroups(disabledServerGroups).map(\n (disabledServerGroup: any) => ({\n label: disabledServerGroup.name,\n value: disabledServerGroup.name,\n }),\n );\n\n return (\n <Modal onHide={this.close}>\n <TaskMonitorWrapper monitor={taskMonitor} />\n {submitting && (\n <form role=\"form\">\n <ModalClose dismiss={this.close} />\n <Modal.Header>\n <Modal.Title>Rollback {serverGroup.name}</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <div className=\"row\">\n <div className=\"col-sm-3 sm-label-right\">Restore to</div>\n <div className=\"col-sm-6\">\n <Select\n value={command.rollbackContext.restoreServerGroupName}\n onChange={this.handleServerGroupChange}\n options={disabledServerGroupOptions}\n />\n </div>\n </div>\n <TaskReason reason={command.taskReason} onChange={this.handleTaskReasonChange} />\n </Modal.Body>\n <AzureModalFooter\n onSubmit={this.submit}\n onCancel={this.close}\n isValid={isValidSG}\n account={serverGroup.account}\n />\n </form>\n )}\n </Modal>\n );\n }\n}\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n ConfirmationModalService,\n FirewallLabels,\n SERVER_GROUP_WRITER,\n ServerGroupReader,\n ServerGroupWarningMessageService,\n} from '@spinnaker/core';\n\nimport '../configure/serverGroup.configure.azure.module';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE } from '../configure/serverGroupCommandBuilder.service';\nimport { AzureRollbackServerGroupModal } from './rollback/RollbackServerGroupModal';\n\nexport const AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER =\n 'spinnaker.azure.serverGroup.details.controller';\nexport const name = AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE,\n SERVER_GROUP_WRITER,\n ])\n .controller('azureServerGroupDetailsCtrl', [\n '$scope',\n '$state',\n '$templateCache',\n 'app',\n 'serverGroup',\n 'azureServerGroupCommandBuilder',\n '$uibModal',\n 'serverGroupWriter',\n function (\n $scope,\n $state,\n $templateCache,\n app,\n serverGroup,\n azureServerGroupCommandBuilder,\n $uibModal,\n serverGroupWriter,\n ) {\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n this.application = app;\n\n function extractServerGroupSummary() {\n let summary = _.find(app.serverGroups.data, function (toCheck) {\n return (\n toCheck.name === serverGroup.name &&\n toCheck.account === serverGroup.accountId &&\n toCheck.region === serverGroup.region\n );\n });\n if (!summary) {\n app.loadBalancers.data.some(function (loadBalancer) {\n if (loadBalancer.account === serverGroup.accountId && loadBalancer.region === serverGroup.region) {\n return loadBalancer.serverGroups.some(function (possibleServerGroup) {\n if (possibleServerGroup.name === serverGroup.name) {\n summary = possibleServerGroup;\n return true;\n }\n });\n }\n });\n }\n if (!summary) {\n $state.go('^');\n }\n return summary;\n }\n\n function retrieveServerGroup() {\n const summary = extractServerGroupSummary();\n return ServerGroupReader.getServerGroup(\n app.name,\n serverGroup.accountId,\n serverGroup.region,\n serverGroup.name,\n ).then(function (details) {\n cancelLoader();\n\n angular.extend(details, summary);\n details.account = serverGroup.accountId; // it's possible the summary was not found because the clusters are still loading\n\n $scope.serverGroup = details;\n\n if (!_.isEmpty($scope.serverGroup)) {\n $scope.image = details.image ? details.image : undefined;\n\n if (details.image && details.image.description) {\n const tags = details.image.description.split(', ');\n tags.forEach(function (tag) {\n const keyVal = tag.split('=');\n if (keyVal.length === 2 && keyVal[0] === 'ancestor_name') {\n details.image.baseImage = keyVal[1];\n }\n });\n }\n\n if (details.launchConfig && details.launchConfig.securityGroups) {\n $scope.securityGroups = _.chain(details.launchConfig.securityGroups)\n .map(function (id) {\n return (\n _.find(app.securityGroups.data, {\n accountName: serverGroup.accountId,\n region: serverGroup.region,\n id: id,\n }) ||\n _.find(app.securityGroups.data, {\n accountName: serverGroup.accountId,\n region: serverGroup.region,\n name: id,\n })\n );\n })\n .compact()\n .value();\n }\n } else {\n $state.go('^');\n }\n });\n }\n\n function cancelLoader() {\n $scope.state.loading = false;\n }\n\n retrieveServerGroup().then(() => {\n // If the user navigates away from the view before the initial retrieveServerGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.serverGroups.onRefresh($scope, retrieveServerGroup);\n }\n });\n\n this.destroyServerGroup = function destroyServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const stateParams = {\n name: serverGroup.name,\n accountId: serverGroup.account,\n region: serverGroup.region,\n };\n\n const taskMonitor = {\n application: app,\n title: 'Destroying ' + serverGroup.name,\n onTaskComplete: function () {\n if ($state.includes('**.serverGroup', stateParams)) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return serverGroupWriter.destroyServerGroup(serverGroup, app);\n };\n\n const confirmationModalParams = {\n header: 'Really destroy ' + serverGroup.name + '?',\n buttonText: 'Destroy ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n };\n\n ServerGroupWarningMessageService.addDestroyWarningMessage(app, serverGroup, confirmationModalParams);\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.disableServerGroup = function disableServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + serverGroup.name,\n };\n\n const submitMethod = () => serverGroupWriter.disableServerGroup(serverGroup, app);\n\n const confirmationModalParams = {\n header: 'Really disable ' + serverGroup.name + '?',\n buttonText: 'Disable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n };\n\n ServerGroupWarningMessageService.addDisableWarningMessage(app, serverGroup, confirmationModalParams);\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.enableServerGroup = function enableServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + serverGroup.name,\n };\n\n const submitMethod = (params) => {\n return serverGroupWriter.enableServerGroup(\n serverGroup,\n app,\n angular.extend(params, {\n interestingHealthProviderNames: [], // bypass the check for now; will change this later to ['azureService']\n }),\n );\n };\n\n ConfirmationModalService.confirm({\n header: 'Really enable ' + serverGroup.name + '?',\n buttonText: 'Enable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.rollbackServerGroup = () => {\n const serverGroup = $scope.serverGroup;\n const cluster = _.find(app.clusters, { name: serverGroup.cluster, account: serverGroup.account });\n const disabledServerGroups = _.filter(cluster.serverGroups, { isDisabled: true, region: serverGroup.region });\n AzureRollbackServerGroupModal.show({ application: app, serverGroup, disabledServerGroups });\n };\n\n this.cloneServerGroup = (serverGroup) => {\n $uibModal.open({\n templateUrl: require('../configure/wizard/serverGroupWizard.html'),\n controller: 'azureCloneServerGroupCtrl as ctrl',\n size: 'lg',\n resolve: {\n title: () => 'Clone ' + serverGroup.name,\n application: () => app,\n serverGroupCommand: () =>\n azureServerGroupCommandBuilder.buildServerGroupCommandFromExisting(app, serverGroup),\n },\n });\n };\n\n this.truncateCommitHash = function () {\n if ($scope.serverGroup && $scope.serverGroup.buildInfo && $scope.serverGroup.buildInfo.commit) {\n return $scope.serverGroup.buildInfo.commit.substring(0, 8);\n }\n return null;\n };\n },\n ]);\n","import { module } from 'angular';\n\nimport { AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER } from './serverGroupDetails.azure.controller';\n\n('use strict');\n\nexport const AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE = 'spinnaker.azure.serverGroup.details.azure';\nexport const name = AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE, [\n AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER,\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ApplicationNameValidator } from '@spinnaker/core';\n\nexport const AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR = 'spinnaker.azure.validation.applicationName';\nexport const name = AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR; // for backwards compatibility\nmodule(AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR, [])\n .factory('azureApplicationNameValidator', function () {\n function validateSpecialCharacters(name, errors) {\n const pattern = /^([a-zA-Z][a-zA-Z0-9]*)?$/;\n if (!pattern.test(name)) {\n errors.push(\n 'The application name must begin with a letter and must contain only letters or digits. No ' +\n 'special characters are allowed.',\n );\n }\n }\n\n function validate(name) {\n const warnings = [];\n const errors = [];\n\n if (name && name.length) {\n validateSpecialCharacters(name, errors);\n }\n\n return {\n warnings: warnings,\n errors: errors,\n };\n }\n\n return {\n validate: validate,\n };\n })\n .run([\n 'azureApplicationNameValidator',\n function (azureApplicationNameValidator) {\n ApplicationNameValidator.registerValidator('azure', azureApplicationNameValidator);\n },\n ]);\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import { module } from 'angular';\n\nimport { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';\n\nimport './help/azure.help';\nimport { AZURE_IMAGE_IMAGE_READER } from './image/image.reader';\nimport { AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE } from './instance/azureInstanceType.service';\nimport { AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER } from './instance/details/instance.details.controller';\nimport { AzureLoadBalancerChoiceModal } from './loadBalancer/configure/AzureLoadBalancerChoiceModal';\nimport { AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER } from './loadBalancer/configure/createLoadBalancer.controller';\nimport { AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER } from './loadBalancer/details/loadBalancerDetail.controller';\nimport { AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from './loadBalancer/loadBalancer.transformer';\nimport logo from './logo/logo_azure.png';\nimport { AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE } from './pipeline/stages/bake/azureBakeStage';\nimport { AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE } from './pipeline/stages/destroyAsg/azureDestroyAsgStage';\nimport { AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE } from './pipeline/stages/disableAsg/azureDisableAsgStage';\nimport { AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE } from './pipeline/stages/enableAsg/azureEnableAsgStage';\nimport { AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL } from './securityGroup/configure/CreateSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL } from './securityGroup/configure/EditSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER } from './securityGroup/details/securityGroupDetail.controller';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_READER } from './securityGroup/securityGroup.reader';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER } from './securityGroup/securityGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE } from './serverGroup/configure/serverGroup.configure.azure.module';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER } from './serverGroup/configure/wizard/CloneServerGroup.azure.controller';\nimport { AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE } from './serverGroup/details/serverGroup.details.module';\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from './serverGroup/serverGroup.transformer';\nimport { AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR } from './validation/applicationName.validator';\n\nimport './logo/azure.logo.less';\n\nexport const AZURE_MODULE = 'spinnaker.azure';\nmodule(AZURE_MODULE, [\n AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE,\n AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE,\n AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE,\n AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE,\n AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE,\n AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE,\n AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER,\n AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER,\n AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER,\n AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER,\n AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL,\n AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL,\n AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER,\n AZURE_SECURITYGROUP_SECURITYGROUP_READER,\n AZURE_IMAGE_IMAGE_READER,\n AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR,\n]).config(function () {\n CloudProviderRegistry.registerProvider('azure', {\n name: 'Azure',\n logo: {\n path: logo,\n },\n image: {\n reader: 'azureImageReader',\n },\n serverGroup: {\n transformer: 'azureServerGroupTransformer',\n detailsTemplateUrl: require('./serverGroup/details/serverGroupDetails.html'),\n detailsController: 'azureServerGroupDetailsCtrl',\n cloneServerGroupTemplateUrl: require('./serverGroup/configure/wizard/serverGroupWizard.html'),\n cloneServerGroupController: 'azureCloneServerGroupCtrl',\n commandBuilder: 'azureServerGroupCommandBuilder',\n configurationService: 'azureServerGroupConfigurationService',\n },\n instance: {\n instanceTypeService: 'azureInstanceTypeService',\n detailsTemplateUrl: require('./instance/details/instanceDetails.html'),\n detailsController: 'azureInstanceDetailsCtrl',\n },\n loadBalancer: {\n transformer: 'azureLoadBalancerTransformer',\n detailsTemplateUrl: require('./loadBalancer/details/loadBalancerDetail.html'),\n detailsController: 'azureLoadBalancerDetailsCtrl',\n createLoadBalancerTemplateUrl: require('./loadBalancer/configure/createLoadBalancer.html'),\n createLoadBalancerController: 'azureCreateLoadBalancerCtrl',\n CreateLoadBalancerModal: AzureLoadBalancerChoiceModal,\n },\n securityGroup: {\n transformer: 'azureSecurityGroupTransformer',\n reader: 'azureSecurityGroupReader',\n detailsTemplateUrl: require('./securityGroup/details/securityGroupDetail.html'),\n detailsController: 'azureSecurityGroupDetailsCtrl',\n createSecurityGroupTemplateUrl: require('./securityGroup/configure/createSecurityGroup.html'),\n createSecurityGroupController: 'azureCreateSecurityGroupCtrl',\n },\n });\n});\n\nDeploymentStrategyRegistry.registerProvider('azure', ['redblack']);\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAACrCAYAAACEwDK4AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI2MjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTcxPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOS0wNS0wNlQxMjowNTozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjguMzwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K8Qjg7wAAM9JJREFUeAHtnQeAFdX1/8/MvLa9L1tgF5Zl6UUUggoIggVLrCQYY42a/jPlb4rxr9EkvxhNIz9bEjUmllhRRFCxIKII0hVY2jaWLbC9vf5mft9z571lwd1lWfWXRM+FeW/ezJ07937uveeee+6ZWbIsazG2EpIgBITA554AywKWCSRC4XPfFgSAEDiCgMiEI3DIDyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh8B9DQPuPyWk0o+2WlRnyhYorW8O5++pb0irq2pIqu6y46uaAtau6tv6+L89Yf9akzF3/aeWS/AqBfycCjk8jM5ZljUa6FrZyTdPCvd0DcZJwvAhbLrZkbN158RMZXaGIsbcx4Cira3ej8ydWtoeza1u9haf8atXItkBkeER3pkYiRDpEm6FppBkaBci9zxHv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\""],"names":["TagError","TagError2","AzureLoadBalancerTypes","type","description","tagsObject","isValid","error","errorMessage","length","Object","keys","_Utility","TAG_LIMITATION","k","v","entries","TAG_KEY_LENGTH_LIMITATION","TAG_VALUE_LENGTH_LIMITATION","TAG_INVALID_CHAR_REG_EXR","test","typeString","toLowerCase","split","join","find","lb","Utility","helpContents","azure.securityGroup.ingress.description","azure.securityGroup.ingress.priority","azure.securityGroup.ingress.source","azure.securityGroup.ingress.sourcePortRange","azure.securityGroup.ingress.destination","azure.securityGroup.ingress.destinationPortRange","azure.securityGroup.ingress.direction","azure.securityGroup.ingress.actions","azure.securityGroup.ingress.destPortRanges","azure.securityGroup.ingress.sourceIPCIDRRanges","azure.serverGroup.imageName","azure.serverGroup.stack","azure.serverGroup.detail","azure.serverGroup.scriptLocation","azure.serverGroup.commandToExecute","azure.serverGroup.customData","azure.serverGroup.customTags","azure.serverGroup.enableInboundNAT","azure.serverGroup.lun","azure.serverGroup.diskSizeGB","azure.serverGroup.managedDisk.storageAccountType","azure.serverGroup.caching","azure.serverGroup.userAssignedIdentities","azure.loadBalancer.dnsName","azure.loadBalancer.probes.probeInterval","azure.loadBalancer.probes.timeout","azure.loadBalancer.probes.unhealthyThreshold","azure.loadBalancer.loadBalancingRules.idleTimeout","azure.loadBalancer.loadBalancingRules.sessionPersistence","forEach","key","HelpContentsRegistry","register","module","factory","findImages","params","REST","query","get","then","results","getImage","amiName","region","credentials","path","provider","$q","categories","label","families","instanceTypes","name","cpu","memory","storage","count","size","icon","map","category","family","inst","costFactor","stats","min","Number","MAX_VALUE","max","push","cpuMin","_","minBy","cpuMax","maxBy","memoryMin","memoryMax","storageMin","calculateStorage","storageMax","Math","buildStats","when","getCategories","getAvailableTypesForRegions","locationToInstanceTypesMap","selectedLocations","location","getAllTypesByRegion","UIROUTER_ANGULARJS","ANGULAR_UI_BOOTSTRAP","controller","$scope","$state","$uibModal","instance","app","extraData","instanceSummary","loadBalancers","account","vpcId","serverGroups","data","some","serverGroup","instances","possibleInstance","id","instanceId","loadBalancer","isDisabled","addExtraDataToLatest","InstanceReader","getInstanceDetails","details","state","loading","instance2","latest","isStandalone","health","displayableMetrics","filter","metric","detailsMatch","latestHealth","defaults","healthMetrics","discoveryMetric","vipAddress","vipList","includes","baseIpAddress","publicDnsName","privateIpAddress","go","instanceIdNotFound","detailsTemplateUrl","CloudProviderRegistry","getValue","standalone","canDeregisterFromLoadBalancer","canRegisterWithLoadBalancer","outOfService","hasLoadBalancerHealth","canRegisterWithDiscovery","discoveryHealth","terminateInstance","taskMonitor","application","title","onTaskComplete","confirm","header","buttonText","taskMonitorConfig","submitMethod","InstanceWriter","terminateInstanceAndShrinkServerGroup","rebootInstance","registerInstanceWithLoadBalancer","loadBalancerNames","deregisterInstanceFromLoadBalancer","enableInstanceInDiscovery","disableInstanceInDiscovery","hasHealthState","healthProviderType","retrieveInstance","all","ready","$$destroyed","onRefresh","React","Component","[object Object]","props","close","modalService","open","templateUrl","createLoadBalancerTemplateUrl","windowClass","createLoadBalancerController","resolve","this","isNew","forPipelineConfig","loadBalancerType","selectedChoice","result","catch","reason","dismissModal","choices","ReactModal","show","_AzureLoadBalancerChoiceModal","className","choice","setState","ModalClose","dismiss","Modal","Header","Title","Body","onClick","choiceSelected","Footer","Button","choose","AzureLoadBalancerChoiceModal","defaultProps","closeModal","noop","AzureProviderSettings","SETTINGS","providers","azure","resetToOriginal","resetProvider","normalizeLoadBalancer","detachedInstances","concat","activeServerGroups","chain","flatten","value","convertLoadBalancerForEditing","toEdit","stack","detail","vnet","subnet","probes","loadBalancingRules","elb","securityGroups","dnsName","constructNewLoadBalancerTemplate","defaultCredentials","defaultRegions","cloudProvider","probeName","probeProtocol","probePort","probePath","probeInterval","unhealthyThreshold","timeout","ruleName","protocol","externalPort","backendPort","persistence","idleTimeout","$uibModalInstance","azureLoadBalancerTransformer","ctrl","newStateParams","accountId","accountLoadBalancersByRegion","getDataSource","refresh","loadBalancer2","existingLoadBalancerNames","regions","pages","listeners","healthCheck","advancedSettings","isALB","accountsLoaded","submitting","TaskMonitor","modalInstance","onNextRefresh","onApplicationRefresh","nameParts","NameUtils","parseLoadBalancerName","freeFormDetails","listAccounts","accounts","accountUpdated","requiresHealthCheckPath","indexOf","updateName","getName","elbName","trimEnd","getRegionsForAccount","regionUpdated","vnetUpdated","selectedVnet","vnetResourceGroup","selectedVnets","listNetworks","vnets","subnetUpdated","selectedSubnet","selectedSubnets","selectedVnetChanged","item","resourceGroup","subnets","addSubnet","devices","device","removeListener","index","splice","addListener","submit","descriptor","appName","clusterName","resourceGroupName","loadBalancerName","name2","ruleNameBase","subnetType","rule","LoadBalancerWriter","upsertLoadBalancer","cancel","angular","SECURITY_GROUP_READER","LOAD_BALANCER_READ_SERVICE","$exceptionHandler","securityGroupReader","loadBalancerReader","getLoadBalancerDetails","filtered","securityGroupId","match","getApplicationSecurityGroup","sortBy","s","ss","substring","toUpperCase","firewallsLabel","FirewallLabels","extractLoadBalancer","editLoadBalancer","copy","deleteLoadBalancer","command","$stateParams","executionDetailsSectionService","$interpolate","configSections","initialized","detailsSection","stage","context","cloudProviderType","roscoMode","feature","roscoSelector","bakeryDetailUrl","roscoDetailUrl","initialize","synchronizeSection","$on","config","pipeline","registerStage","provides","executionDetailsUrl","executionLabelComponent","BakeExecutionLabel","extraLabelLines","masterStage","allPreviouslyBaked","somePreviouslyBaked","supportsCustomTimeout","validators","fieldName","checkParentTriggers","getMessage","labels","restartable","extendedAttributes","user","AuthenticationService","getAuthenticatedUser","viewState","baseOsChanged","selectedOption","baseOsOptions","baseOs","osType","addExtendedAttribute","PipelineTemplates","addExtendedAttributes","controllerAs","extendedAttribute","removeExtendedAttribute","showTemplateFileName","templateFileName","showExtendedAttributes","showVarFileName","varFileName","$watch","forOwn","val","BakeryReader","getRegions","getBaseOsOptions","getBaseLabelOptions","baseLabelOptions","baseImages","baseLabel","showAdvancedOptions","stg","showAdvanced","executionStepLabelUrl","accountExtractor","configAccountExtractor","message","fieldLabel","regionsLoaded","getAccountDetails","org","targets","StageConstants","TARGET_LIST","interestingHealthProviderNames","target","alias","attributes","platformHealthOnly","reset","resetSelectedCluster","deleteSecurityGroup","securityGroup","securityGroupName","operation","TaskExecutor","executeTask","job","clearCache","upsertSecurityGroup","assignWith","other","isUndefined","$controller","azureSecurityGroupWriter","ingress","firewallLabel","accountName","ruleset","a","b","temp","priorityA","priority","priorityB","infiniteScroll","numToAdd","currentItems","addMoreItems","securityGroup2","namePreview","upsert","addRule","protocolUI","access","direction","sourceAddressPrefix","sourceAddressPrefixes","sourcePortRange","destinationAddressPrefix","destinationPortRange","destinationPortRanges","destPortRanges","sourceIPCIDRRanges","portUpdated","isEmpty","ruleRanges","sourceIPCIDRUpdated","protocolUpdated","removeRule","moveUp","moveDown","securityRules","CACHE_INITIALIZER_SERVICE","cacheInitializer","destinationPortRangeModel","sourceAddressPrefixModel","refreshingSecurityGroups","getSecurityGroupRefreshTime","InfrastructureCaches","getStats","ageMax","refreshSecurityGroups","refreshCache","getAllSecurityGroups","availableGroups","availableSecurityGroups","startPort","endPort","resolvedSecurityGroup","getSecurityGroupDetails","extractSecurityGroup","editInboundRules","cloneSecurityGroup","resolveIndexedSecurityGroup","indexedSecurityGroups","container","normalizeSecurityGroup","configuration","Array","isArray","customScriptsSettings","fileUris","fileUrisTemp","trim","convertServerGroupCommandToDeployConfiguration","tempImage","mode","imageName","isCustom","publisher","offer","sku","version","uri","ostype","selectedImage","selectedProvider","strategy","rollback","onFailure","scaleDown","maxRemainingAsgs","delayBeforeDisableSec","delayBeforeScaleDownSec","allowDeleteActive","allowScaleDownActive","healthSettings","image","useSourceCapacity","capacity","upgradePolicy","tier","instanceTags","dataDisks","userAssignedIdentities","osConfig","customData","commandToExecute","zonesEnabled","zones","enableInboundNAT","instanceType","vmsku","normalizeServerGroup","parseCustomScriptsSettings","instanceTypeService","modalWizardService","wizard","getWizard","instanceProfile","includePage","markClean","markComplete","excludePage","newVal","markDirty","directive","restrict","scope","bindToController","addDataDisk","newDataDisks","lun","managedDisk","storageAccountType","diskSizeGB","caching","createOption","removeDataDisk","input","selectedRegion","IMAGE_READER","$uibModalStack","imageReader","markIncomplete","imageChanged","extend","stackPattern","templatingEnabled","detailPattern","healthCheckProtocols","displayName","changeHealthCheckProtocol","newProtocol","port","requestPath","clearImage","LBs","selectedLoadBalancer","attachedVnet","selectedVnetSubnets","allVnets","attachedSubnet","networkSettingsConfigured","useLoadBalancer","loadBalancerChanged","backingData","loadBalancerToFind","getLoadBalancerType","vnetChanged","networkSettingsChanged","getVnetName","selectedSecurityGroup","securityGroupChanged","azureServerGroupConfigurationService","link","refreshing","getTagResult","checkTags","updateEnableInboundNAT","vm","azureImageReader","azureInstanceTypeService","dataDiskTypes","dataDiskCachingTypes","healthCheckTypes","terminationPolicies","dirty","c","locations","credentialsKeyedByAccount","every","l","startsWith","configureStandardInstanceTypes","filteredData","regionsSupportZones","availabilityZones","newSecurityGroups","currentOptions","newRegionalSecurityGroups","getRegionalSecurityGroups","securityGroupsConfigured","uniq","sort","current","newLoadBalancers","getLoadBalancerNames","matched","intersection","removed","xor","filterlist","loadBalancersConfigured","configureUpdateCommand","configureCommand","AccountService","getCredentialsKeyedByAccount","loadSecurityGroups","loadLoadBalancers","cmd","regionChanged","isInit","configureLoadBalancers","configureSecurityGroupOptions","configureInstanceTypes","configureZones","credentialsChanged","regionsForAccount","defaultKeyPair","configureImages","regionalImages","disableImageSelection","packageImages","amis","ami","images","configureLoadBalancerOptions","refreshLoadBalancers","skipCommandReconfiguration","listLoadBalancers","refreshInstanceTypes","SERVER_GROUP_WRITER","serverGroupWriter","serverGroupCommand","cloneStage","task","execution","stages","newServerGroupName","transitionTo","useAllImageSelection","loaded","createResultProcessor","method","newValue","oldValue","zoneEnabled","templateSelection","basicSettings","imageSettings","networkSettings","tags","applicationName","requiresTemplateSelection","templateSelectionText","copied","notCopied","additionalCopyText","disableStrategySelection","cloneServerGroup","toggleSuspendedProcess","process","suspendedProcesses","processIndex","processIsSuspended","templateSelected","azureServerGroupTransformer","defaultRegion","allImageSelection","useSimpleCapacity","usePreferredZones","buildNewServerGroupCommand","buildNewServerGroupCommandForPipeline","buildServerGroupCommandFromExisting","serverGroupName","parseServerGroupName","desired","source","asgName","listImplicitSecurityGroups","buildServerGroupCommandFromPipeline","originalCluster","pipelineCluster","cloneDeep","submitButtonLabel","instanceTypeDetails","viewOverrides","verified","onSubmit","onCancel","UserVerification","expectedValue","onValidChange","handleVerification","disabled","args","apply","ReactInjector","rollbackServerGroup","disabledServerGroups","disabledServerGroup","instanceCounts","total","localeCompare","rollbackContext","restoreServerGroupName","restoreServerGroupOption","newCommand","restoreServerGroup","filterServerGroups","targetSize","taskReason","modalInstanceEmulation","rollbackType","rollbackServerGroupName","enableAndDisableOnly","_AzureRollbackServerGroupModal","isValidSG","disabledServerGroupOptions","onHide","TaskMonitorWrapper","monitor","role","Select","onChange","handleServerGroupChange","options","TaskReason","handleTaskReasonChange","AzureModalFooter","AzureRollbackServerGroupModal","$templateCache","azureServerGroupCommandBuilder","summary","toCheck","possibleServerGroup","extractServerGroupSummary","ServerGroupReader","getServerGroup","tag","keyVal","baseImage","launchConfig","compact","retrieveServerGroup","destroyServerGroup","serverGroup2","stateParams","confirmationModalParams","addDestroyWarningMessage","disableServerGroup","addDisableWarningMessage","enableServerGroup","cluster","clusters","truncateCommitHash","buildInfo","commit","validate","errors","warnings","run","azureApplicationNameValidator","registerValidator","css","ref","insertAt","document","head","getElementsByTagName","style","createElement","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","AZURE_MODULE","registerProvider","logo","reader","transformer","detailsController","cloneServerGroupTemplateUrl","cloneServerGroupController","commandBuilder","configurationService","CreateLoadBalancerModal","createSecurityGroupTemplateUrl","createSecurityGroupController","DeploymentStrategyRegistry"],"mappings":"uoCAMYA,EAAAC,GAAAA,EAAAD,2VAcCE,EAA+C,CAC1D,CACEC,KAAM,sBACNC,YAAa,IAEf,CACED,KAAM,4BACNC,YAAa,8BAUSC,OACjBA,QACI,CACLC,SAAS,EACTC,MAAO,EACPC,aAAc,qCAGZC,EAAiBC,OAAOC,KAAKN,GAAYI,eAC/B,GAAKA,GAAUG,EAAQC,sBAC9B,CACLP,SAAS,EACTC,MAAO,EACPC,aAAc,qCAAqCI,EAAQC,4BAInDC,EAAGC,KAAML,OAAOM,QAAQX,GAAa,IAC3CS,EAAEL,OAASG,EAAQK,gCACd,CACLX,SAAS,EACTC,MAAO,EACPC,aAAc,sBAAsBM,wBAAwBF,EAAQK,gCAGpEF,EAAEN,OAASG,EAAQM,kCACd,CACLZ,SAAS,EACTC,MAAO,EACPC,aAAc,wBAAwBO,wBAAwBH,EAAQM,kCAGtEN,EAAQO,yBAAyBC,KAAKN,SACjC,CACLR,SAAS,EACTC,MAAO,EACPC,aAAc,kCAAkCM,QAGhDF,EAAQO,yBAAyBC,KAAKL,SACjC,CACLT,SAAS,EACTC,MAAO,EACPC,aAAc,oCAAoCO,WAIjD,CACLT,SAAS,EACTC,MAAO,iCAIuBc,YACnBA,EAAWC,cAAcC,MAAM,KAAKC,KAAK,KAC/CtB,EAAuBuB,MAAMC,GAA2BA,EAAGvB,KAAKmB,gBAAkBD,KAAe,OA7D5G,QAAAM,EACyBd,eAAyB,EADlDc,EAEyBV,0BAAoC,IAF7DU,EAGyBT,4BAAsC,IAH/DS,EAIyBR,yBAAmC,aChC5D,MAAMS,GAA0C,CAC9CC,0CAA2C,wEAC3CC,uCACE,0XACFC,qCACE,8PACFC,8CACE,0QACFC,0CACE,wQACFC,mDACE,kRACFC,wCAAyC,iEACzCC,sCACE,sIACFC,6CACE,kNACFC,iDACE,4MACFC,8BAA+B,iEAC/BC,0BACE,2JACFC,2BACE,oGACFC,mCACE,uNACFC,qCACE,oFACFC,+BAAgC,yDAChCC,+BAAgC,mDAAmDlB,EAAQd,+BAC3FiC,qCACE,gZACFC,wBACE,gLACFC,+BACE,kGACFC,mDACE,yFACFC,4BACE,8QACFC,2CACE,qKACFC,6BACE,8OACFC,0CACE,6FACFC,oCACE,sMACFC,+CACE,mIACFC,oDACE,6FACFC,2DACE,iiBAGJ/C,OAAOC,KAAKiB,IAAc8B,SAASC,GAAQC,EAAqBC,SAASF,EAAK/B,GAAa+B,MCnD3FG,EAFwC,+BAEP,IAAIC,QAAQ,oBAAoB,iBA8BxD,CACLC,oBA9BkBC,UACXC,EAAK,gBACTC,MAAMF,GACNG,MACAC,MACC,SAAUC,UACDA,KAET,iBACS,OAsBbC,kBAjBgBC,EAASC,EAAQC,UAC1BR,EAAK,WACTS,KAAKD,EAAaD,EAAQD,GAC1BL,MAAM,CAAES,SAAU,UAClBR,MACAC,MACC,SAAUC,UACDA,GAAWA,EAAQ7D,OAAS6D,EAAQ,GAAK,QAElD,kBACS,aC1BjBR,EAFwD,uCAEP,IAAIC,QAAQ,2BAA4B,CACvF,KACA,SAAUc,SAitBFC,EAAa,CACjB,CACE3E,KAAM,UACN4E,MAAO,kBACP3E,YACE,qIACF4E,SAAU,CAttBJ,CACR7E,KAAM,WACNC,YACE,6LACF6E,cAAe,CACb,CACEC,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,IAGV,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,IAGV,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,IAGV,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,MAMD,CACXpF,KAAM,cACNC,YACE,kHACF6E,cAAe,CACb,CACEC,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,QAMF,CACVpF,KAAM,aACNC,YACE,iHACF6E,cAAe,CACb,CACEC,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,MAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,SAMD,CACXpF,KAAM,cACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,IAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,QAMF,CACVpF,KAAM,aACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,MAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,MAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,QAMF,CACVpF,KAAM,aACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,KAGV,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,KAGV,CACEL,KAAM,iBACNH,MAAO,iBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,GACPC,KAAM,OAMH,CACTpF,KAAM,YACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,MAGV,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CACPlF,KAAM,MACNmF,MAAO,EACPC,KAAM,SAyJVC,KAAM,OAER,CACErF,KAAM,UACN4E,MAAO,oBACP3E,YACE,+HACF4E,SAAU,CA1JD,CACX7E,KAAM,cACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,KAE1C,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,KAE1C,CACEL,KAAM,kBACNH,MAAO,kBACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,KAE3C,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,MAE3C,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,MAE3C,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,MAE3C,CACEL,KAAM,mBACNH,MAAO,mBACPI,IAAK,GACLC,OAAQ,IACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,QAKpC,CACTpF,KAAM,YACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,IAE1C,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,IAE1C,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,KAE3C,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,KAE3C,CACEL,KAAM,gBACNH,MAAO,gBACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,OAKrC,CACRpF,KAAM,WACNC,YAAa,GACb6E,cAAe,CACb,CACEC,KAAM,cACNH,MAAO,cACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,KAE1C,CACEL,KAAM,cACNH,MAAO,cACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,EAAGC,KAAM,KAE1C,CACEL,KAAM,cACNH,MAAO,cACPI,IAAK,EACLC,OAAQ,EACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,KAE3C,CACEL,KAAM,cACNH,MAAO,cACPI,IAAK,EACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,MAE3C,CACEL,KAAM,eACNH,MAAO,eACPI,IAAK,GACLC,OAAQ,GACRC,QAAS,CAAElF,KAAM,MAAOmF,MAAO,GAAIC,KAAM,SAoB3CC,KAAM,OAER,CACErF,KAAM,SACN4E,MAAO,cACP3E,YAAa,kCACb4E,SAAU,GACVQ,KAAM,wBAIgBrF,UACnBA,GAASA,EAAKkF,QAGZlF,EAAKkF,QAAQC,MAAQnF,EAAKkF,QAAQE,KAFhC,wBA6CEE,KAAI,SAAUC,aACZC,KAAUD,EAASV,mBACjBY,KAAQD,EAAOV,cACD,MAAnBW,EAAKC,eAA8BA,WAAa,KAG/CC,eA9COJ,SACZI,EAAQ,CACZX,IAAK,CACHY,IAAKC,OAAOC,UACZC,KAAMF,OAAOC,WAEfb,OAAQ,CACNW,IAAKC,OAAOC,UACZC,KAAMF,OAAOC,WAEfZ,QAAS,CACPU,IAAKC,OAAOC,UACZC,KAAMF,OAAOC,WAEfjB,SAAU,WAGRU,EAASV,UAAYU,EAASV,SAASvE,UAChCuE,SAAStB,SAAQ,SAAUiC,KAC5BX,SAASmB,KAAKR,EAAOxF,YACrBiG,EAASC,EAAEC,MAAMX,EAAOV,cAAe,OAAOE,KAAOa,OAAOC,UAC5DM,EAASF,EAAEG,MAAMb,EAAOV,cAAe,OAAOE,MAAQa,OAAOC,UAC7DQ,EAAYJ,EAAEC,MAAMX,EAAOV,cAAe,UAAUG,QAAUY,OAAOC,UACrES,EAAYL,EAAEG,MAAMb,EAAOV,cAAe,UAAUG,SAAWY,OAAOC,UACtEU,EAAaC,EAAiBP,EAAEC,MAAMX,EAAOV,cAAe2B,KAAsBZ,OAAOC,UACzFY,EAAaD,EAAiBP,EAAEG,MAAMb,EAAOV,cAAe2B,MAAuBZ,OAAOC,YAE1Fd,IAAIY,IAAMe,KAAKf,IAAID,EAAMX,IAAIY,IAAKK,KAClCjB,IAAIe,IAAMY,KAAKZ,IAAIJ,EAAMX,IAAIe,IAAKK,KAClCnB,OAAOW,IAAMe,KAAKf,IAAID,EAAMV,OAAOW,IAAKU,KACxCrB,OAAOc,IAAMY,KAAKZ,IAAIJ,EAAMV,OAAOc,IAAKQ,KACxCrB,QAAQU,IAAMe,KAAKf,IAAID,EAAMT,QAAQU,IAAKY,KAC1CtB,QAAQa,IAAMY,KAAKZ,IAAIJ,EAAMT,QAAQa,IAAKW,MAI7Cf,EAUYiB,CAAWrB,MAEvBb,EAAGmC,KAAKlC,SAaV,CACLmC,cAAAA,EACAC,qCARmCC,EAA4BC,SAExDC,GAAYD,SACZD,EAA2BE,IAMlCC,oBAb0B,kBACnBL,SC9xBbnD,EAFkE,6CAEP,CAACyD,EAAoBC,IAAuBC,WACrG,2BACA,CACE,SACA,SACA,YACA,WACA,MACA,KACA,SAAUC,EAAQC,EAAQC,EAAWC,EAAUC,EAAKjD,sBAkC1CkD,EAAY,OACdC,EAAiBC,EAAeC,EAASzD,EAAQ0D,SAChDL,EAAIM,gBAOHA,aAAaC,KAAKC,MAAK,SAAUC,UAC5BA,EAAYC,UAAUF,MAAK,SAAUG,MACtCA,EAAiBC,KAAOb,EAASc,oBACjBF,IACFF,EAAYN,gBAClBM,EAAYL,UACbK,EAAY9D,SACb8D,EAAYJ,QACVI,YAAcA,EAAYrD,OAC1BiD,MAAQI,EAAYJ,OACvB,QAIRH,MAECC,cAAcI,KAAKC,MAAK,SAAUM,UAC7BA,EAAaJ,UAAUF,MAAK,SAAUG,MACvCA,EAAiBC,KAAOb,EAASc,oBACjBF,IACF,CAACG,EAAa1D,QACpB0D,EAAaV,UACdU,EAAanE,SACdmE,EAAaT,OACd,QAIRH,KAECC,cAAcI,KAAKC,MAAK,SAAUM,UAC7BA,EAAaR,aAAaE,MAAK,SAAUC,WACzCA,EAAYM,YAGVN,EAAYC,UAAUF,MAAK,SAAUG,MACtCA,EAAiBC,KAAOb,EAASc,oBACjBF,IACF,CAACG,EAAa1D,QACpB0D,EAAaV,UACdU,EAAanE,SACdmE,EAAaT,OACd,gBA/CD,KACF,KACNN,EAASK,UACVL,EAASpD,QAqDhBuD,GAAmBE,GAAWzD,KACtByD,QAAUA,IACVzD,OAASA,IACEqE,qBAAqB,YAAaf,GAChDgB,EAAeC,mBAAmBd,EAASzD,EAAQoD,EAASc,YAAYtE,MAC7E,SAAU4E,KACDC,MAAMC,SAAU,WA3FDC,EAAUC,GAElCvB,EAAIwB,iBACGC,OAASF,EAAOE,UAGlBA,OAASH,EAASG,QAAU,SAC/BC,EAAqBJ,EAASG,OAAOE,QAAO,SAAUC,SACnC,UAAhBA,EAAOvJ,MAAqC,YAAjBuJ,EAAOR,SAGvCG,EAAOE,UACU7F,SAAQ,SAAUgG,SAC7BC,EAAeN,EAAOE,OAAOE,QAAO,SAAUG,UAC3CA,EAAazJ,OAASuJ,EAAOvJ,QAElCwJ,EAAalJ,UACboJ,SAASH,EAAQC,EAAa,SAI/BG,cAAgBN,GAuEIxB,EAAiBiB,KAC/BpB,SAAWxB,EAAEwD,SAASZ,EAASjB,KAC/BH,SAASK,QAAUA,IACnBL,SAASpD,OAASA,IAClBoD,SAASM,MAAQA,IACjBN,SAASI,cAAgBA,QAC1B8B,EAAkB1D,EAAE5E,KAAKiG,EAAOoC,eAAe,SAAUJ,SACtC,cAAhBA,EAAOvJ,WAEZ4J,GAAmBA,EAAgBC,WAAY,OAC3CC,EAAUF,EAAgBC,aACzBnC,SAASmC,WAAaC,EAAQC,SAAS,KAAOD,EAAQ1I,MAAM,KAAO,CAAC0I,KAEtEE,cAAgBlB,EAAQmB,eAAiBnB,EAAQoB,oBAE1D,aAGSnB,MAAMC,SAAU,IAChBmB,GAAG,UAKXtC,MACIuC,mBAAqB1C,EAASc,aAC9BO,MAAMC,SAAU,GAGlBtE,EAAGmC,KAAK,SAhIVwD,mBAAqBC,EAAsBC,SAAS,QAAS,iCAE7DxB,MAAQ,CACbC,SAAS,EACTwB,WAAY7C,EAAIwB,mBA+HbsB,8BAAgC,kBAC5BlD,EAAOG,SAAS0B,OAAOjB,MAAK,SAAUiB,SACpB,iBAAhBA,EAAOpJ,cAIb0K,4BAA8B,iBAC3BzB,EAAW1B,EAAOG,aACnBuB,EAASnB,gBAAkBmB,EAASnB,cAAcxH,cAC9C,QAEHqK,EAAe1B,EAASG,OAAOjB,MAAK,SAAUiB,SAC3B,iBAAhBA,EAAOpJ,MAA4C,iBAAjBoJ,EAAOL,SAE5C6B,EAAwB3B,EAASG,OAAOjB,MAAK,SAAUiB,SACpC,iBAAhBA,EAAOpJ,eAET2K,IAAiBC,QAGrBC,yBAA2B,iBAExBC,EADWvD,EAAOG,SACS0B,OAAOE,QAAO,SAAUF,SAChC,cAAhBA,EAAOpJ,gBAET8K,EAAgBxK,QAAsC,iBAA7BwK,EAAgB,GAAG/B,YAGhDgC,kBAAoB,iBACjB9B,EAAW1B,EAAOG,SAElBsD,EAAc,CAClBC,YAAatD,EACbuD,MAAO,eAAiBjC,EAAST,WACjC2C,eAAgB,WACV3D,EAAOuC,SAAS,qBAAsB,CAAEvB,WAAYS,EAAST,gBACxD2B,GAAG,SASSiB,QAAQ,CAC/BC,OAAQ,oBAAsBpC,EAAST,WAAa,IACpD8C,WAAY,aAAerC,EAAST,WACpCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeV,kBAAkB9B,EAAUtB,YAYjD+D,sCAAwC,iBACrCzC,EAAW1B,EAAOG,SAElBsD,EAAc,CAClBC,YAAatD,EACbuD,MAAO,eAAiBjC,EAAST,WAAa,8BAC9C2C,eAAgB,WACV3D,EAAOuC,SAAS,qBAAsB,CAAEvB,WAAYS,EAAST,gBACxD2B,GAAG,SASSiB,QAAQ,CAC/BC,OAAQ,oBAAsBpC,EAAST,WAAa,eAAiBS,EAASb,YAAc,IAC5FkD,WAAY,aAAerC,EAAST,WAAa,eAAiBS,EAASb,YAC3EL,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeC,sCAAsCzC,EAAUtB,YAYrEgE,eAAiB,iBACd1C,EAAW1B,EAAOG,SAElBsD,EAAc,CAClBC,YAAatD,EACbuD,MAAO,aAAejC,EAAST,cAOR4C,QAAQ,CAC/BC,OAAQ,iBAAmBpC,EAAST,WAAa,IACjD8C,WAAY,UAAYrC,EAAST,WACjCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeE,eAAe1C,EAAUtB,YAY9CiE,iCAAmC,iBAChC3C,EAAW1B,EAAOG,SAClBmE,EAAoB5C,EAASnB,cAAczG,KAAK,SAEhD2J,EAAc,CAClBC,YAAatD,EACbuD,MAAO,eAAiBjC,EAAST,WAAa,SAAWqD,KAOlCT,QAAQ,CAC/BC,OAAQ,mBAAqBpC,EAAST,WAAa,SAAWqD,EAAoB,IAClFP,WAAY,YAAcrC,EAAST,WACnCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeG,iCAAiC3C,EAAUtB,YAYhEmE,mCAAqC,iBAClC7C,EAAW1B,EAAOG,SAClBmE,EAAoB5C,EAASnB,cAAczG,KAAK,SAEhD2J,EAAc,CAClBC,YAAatD,EACbuD,MAAO,iBAAmBjC,EAAST,WAAa,SAAWqD,KAOpCT,QAAQ,CAC/BC,OAAQ,qBAAuBpC,EAAST,WAAa,SAAWqD,EAAoB,IACpFP,WAAY,cAAgBrC,EAAST,WACrCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeK,mCAAmC7C,EAAUtB,YAYlEoE,0BAA4B,iBACzB9C,EAAW1B,EAAOG,SAElBsD,EAAc,CAClBC,YAAatD,EACbuD,MAAO,YAAcjC,EAAST,WAAa,mBAOpB4C,QAAQ,CAC/BC,OAAQ,iBAAmBpC,EAAST,WAAa,iBACjD8C,WAAY,UAAYrC,EAAST,WACjCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeM,0BAA0B9C,EAAUtB,YAYzDqE,2BAA6B,iBAC1B/C,EAAW1B,EAAOG,SAElBsD,EAAc,CAClBC,YAAatD,EACbuD,MAAO,aAAejC,EAAST,WAAa,mBAOrB4C,QAAQ,CAC/BC,OAAQ,kBAAoBpC,EAAST,WAAa,iBAClD8C,WAAY,WAAarC,EAAST,WAClCT,QAASkB,EAASlB,QAClBwD,kBAAmBP,EACnBQ,aATmB,kBACZC,EAAeO,2BAA2B/C,EAAUtB,YAY1DsE,eAAiB,SAAwBC,EAAoBnD,UAC/CxB,EAAOG,SACR0B,OAAOjB,MAAK,SAAUiB,UAC7BA,EAAOpJ,OAASkM,GAAsB9C,EAAOL,QAAUA,OAI/CpB,EAAIwB,aACnBgD,IACAzH,EAAG0H,IAAI,CAACzE,EAAIM,aAAaoE,QAAS1E,EAAIG,cAAcuE,UAAUnI,KAAKiI,IAE5DjI,MAAK,KAKTqD,EAAO+E,aAAgB3E,EAAIwB,gBAC1BlB,aAAasE,UAAUhF,EAAQ4E,QAIhCpE,QAAUL,EAASK,WC5VzB,uBAA2CyE,EAAMC,UAgBtDC,YAAYC,SACJA,eAWS,UACVC,cACCnI,EAAgB6F,EAAsBC,SAAS,QAAS,kBAChDsC,aACXC,KAAK,CACJC,YAAatI,EAASuI,8BACtBC,YAAa,gBACb3F,WAAY,GAAG7C,EAASyI,uCACxB9H,KAAM,KACN+H,QAAS,CACPlC,YAAa,IAAMmC,KAAKT,MAAMhF,IAC9Bc,aAAc,IAAW,KACzB4E,MAAO,KAAM,EACbC,kBAAmB,KAAM,EACzBC,iBAAkB,IAAMH,KAAKrE,MAAMyE,kBAGtCC,OAAOC,OAAM,qBAGFC,SACThB,MAAMiB,aAAaD,SA/BnB5E,MAAQ,CACX8E,QAAS9N,EACTyN,eAAgBzN,EAAuB,gBAXxB4M,UACVmB,EAAWC,KAAKC,GAA8B,IAChDrB,EACHsB,UAAW,2CAYRvB,eAAewB,QACfC,SAAS,CAAEX,eAAgBU,IA2B3BxB,eACCmB,QAAEA,iBAASL,GAAmBJ,KAAKrE,6DAIpCqF,EAAD,CAAYC,QAASjB,KAAKR,wBACzB0B,EAAMC,OAAP,qBACGD,EAAME,MAAP,KAAa,iDAEdF,EAAMG,KAAP,qBACG,MAAD,CAAKR,UAAU,8BACZ,MAAD,CAAKA,UAAU,gBACZJ,EAAQvI,KAAK4I,mBACX,MAAD,CACE1K,IAAK0K,EAAOlO,KACZiO,UAAW,SAAQT,IAAmBU,EAAS,SAAW,IAC1DQ,QAAS,IAAMtB,KAAKuB,eAAeT,oBAElC,KAAD,CAAID,UAAU,uBAAuBC,EAAOlO,sBAC3C,MAAD,KAAMkO,EAAOjO,iCAIlB,MAAD,CAAKgO,UAAU,gDAGlBK,EAAMM,OAAP,qBACGC,EAAD,CAAQH,QAAStB,KAAK0B,QAAQ,2CACH,OAAD,CAAMb,UAAU,qDAhF7Cc,GAISC,aAAiD,CAC7DC,WAAYC,EACZtB,aAAcsB,SChBLC,GAAiDC,EAASC,UAAUC,OAAoC,CACnH5F,SAAU,IAERyF,QACoBI,gBAAkBH,EAASI,cAAc,UCJjE7L,EAF2D,2CAEP,IAAIC,QAAQ,+BAAgC,CAC9F,KACA,SAAUc,SA0FD,CACL+K,+BA1F6BhH,KAChBR,aAAa1E,SAAQ,SAAU6E,KAC9BL,QAAUU,EAAaV,UACvBzD,OAASmE,EAAanE,OAE9B8D,EAAYsH,qBACFA,kBAAoBtH,EAAYsH,kBAAkBpK,KAAI,SAAUkD,SACnE,CAAED,GAAIC,QAEHH,UAAYD,EAAYC,UAAUsH,OAAOvH,EAAYsH,sBAErDA,kBAAoB,YAG9BE,EAAqB1J,EAAEoD,OAAOb,EAAaR,aAAc,CAAES,YAAY,aAChEjE,SAAWgE,EAAazI,OACxBqI,UAAYnC,EAAE2J,MAAMD,GAAoBtK,IAAI,aAAawK,UAAUC,UACnEL,kBAAoBxJ,EAAE2J,MAAMD,GAAoBtK,IAAI,qBAAqBwK,UAAUC,QACzFrL,EAAGyI,QAAQ1E,IAyElBuH,uCAtEqCvH,SAC/BwH,EAAS,CACb3L,OAAQmE,EAAanE,OACrBC,YAAakE,EAAaV,QAC1BhD,KAAM0D,EAAa1D,KACnBmL,MAAOzH,EAAayH,MACpBC,OAAQ1H,EAAa0H,OACrBC,KAAM3H,EAAa2H,KACnBC,OAAQ5H,EAAa4H,OACrBC,OAAQ,GACRC,mBAAoB,OAGlB9H,EAAa+H,IAAK,OACdA,EAAM/H,EAAa+H,MAElBC,eAAiBD,EAAIC,iBACrBL,KAAOI,EAAIJ,KAEdI,EAAID,uBACCA,mBAAqBC,EAAID,sBAG3BD,OAASE,EAAIF,OAChBE,EAAIE,SAA2B,kBAAhBF,EAAIE,YACdA,QAAUF,EAAIE,QAAQtP,MAAM,KAAK,WAGrC6O,GA2CPU,0CAxCwC1F,SAGjC,CACLiF,MAAO,GACPC,OAAQ,WACR5L,YALyB0G,EAAY2F,mBAAmBtB,OAASH,GAAsBzF,SAAS3B,QAMhGzD,OALoB2G,EAAY4F,eAAevB,OAASH,GAAsBzF,SAASpF,OAMvFwM,cAAe,QACfV,KAAM,KACNC,OAAQ,KACRC,OAAQ,CACN,CACES,UAAW,GACXC,cAAe,OACfC,UAAW,KACXC,UAAW,IACXC,cAAe,GACfC,mBAAoB,EACpBC,QAAS,MAGbZ,eAAgB,GAChBF,mBAAoB,CAClB,CACEe,SAAU,GACVC,SAAU,OACVC,aAAc,GACdC,YAAa,GACbV,UAAW,GACXW,YAAa,OACbC,YAAa,UClFzBhO,EAFE,iDAEiE,CACjEyD,EDPyD,6CCSxDE,WAAW,8BAA+B,CAC3C,SACA,oBACA,SACA,+BACA,cACA,eACA,QACA,mBACA,SACEC,EACAqK,EACApK,EACAqK,EACA5G,EACAxC,EACA4E,EACAE,SAEMuE,EAAO1E,qBAsBP7F,EAAO+E,qBAGOM,cACZmF,EAAiB,CACrBhN,KAAMwC,EAAOkB,aAAa1D,KAC1BiN,UAAWzK,EAAOkB,aAAalE,YAC/BD,OAAQiD,EAAOkB,aAAanE,OAC5BG,SAAU,SAGP+C,EAAOuC,SAAS,4BAGZI,GAAG,wBAAyB4H,KAF5B5H,GAAG,uBAAwB4H,sBA6C9BhK,EAAUR,EAAOkB,aAAalE,YAC9BD,EAASiD,EAAOkB,aAAanE,OAE7B2N,EAA+B,KAElCC,cAAc,iBACdC,SAAQ,GACRjO,MAAK,OACQgO,cAAc,iBAAiBhK,KAAK3E,SAAS6O,IACnDA,EAAarK,UAAYA,MACEqK,EAAa9N,QACxC2N,EAA6BG,EAAa9N,SAAW,KAC1B8N,EAAa9N,QAAQ0B,KAAKoM,EAAarN,YAIjEsN,0BAA4BJ,EAA6B3N,IAAW,QA7F1EgO,QAAU,KAEVC,MAAQ,CACbrL,SAAU,qEACVsL,UAAW,kDACXC,YAAa,oDACbC,iBAAkB,4DAGbrF,MAAQA,IACRE,iBAAmBA,EAAiBvN,OACpC2S,MAAkC,wBAA1BpF,EAAiBvN,OAEzB+I,MAAQ,CACb6J,gBAAgB,EAChBC,YAAY,KA4BP7H,YAAc,IAAI8H,EAAY,CACnC7H,YAAAA,EACAC,SAAgB,YAAc,aAAe,qBAC7C6H,cAAenB,EACfzG,4BARYrD,cAAcqK,YACdrK,cAAckL,cAAczL,EAAQ0L,oBAmB5CxK,QACKA,aAAeoJ,EAA6B7B,8BAA8BvH,GAC7E4E,EAAO,OACH6F,EAAYC,EAAUC,sBAAsB7L,EAAOkB,aAAa1D,QAC/D0D,aAAayH,MAAQgD,EAAUhD,QAC/BzH,aAAa0H,OAAS+C,EAAUG,uBAChC9L,EAAOkB,aAAa1D,aAGtB0D,aAAeoJ,EAA6BlB,iCAAiC1F,GAElFoC,UAnBWiG,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACXxK,MAAM6J,gBAAiB,IACzBY,6BA6CJC,wBAA0B,kBAE3BlM,EAAOkB,aAAa6H,OAAO,GAAGU,eAAiF,IAAhEzJ,EAAOkB,aAAa6H,OAAO,GAAGU,cAAc0C,QAAQ,cAIlGC,WAAa,aACTlL,aAAa1D,KAAOqI,KAAKwG,gBAG7BA,QAAU,iBACPpD,EAAMjJ,EAAOkB,aACboL,EAAU,CAAC5I,EAAYlG,KAAMyL,EAAIN,OAAS,GAAIM,EAAIL,QAAU,IAAI9O,KAAK,YACpE6E,EAAE4N,QAAQD,EAAS,WAGvBL,eAAiB,aACLO,qBAAqBxM,EAAOkB,aAAalE,aAAaL,MAAK,SAAUoO,KAC3EA,QAAUA,IACZ0B,yBAIJA,cAAgB,iBAEdL,eACAM,oBAGFA,YAAc,iBACXlM,EAAUR,EAAOkB,aAAalE,YAC9BD,EAASiD,EAAOkB,aAAanE,SAC5BmE,aAAayL,aAAe,OAC5BzL,aAAa2H,KAAO,OACpB3H,aAAa0L,kBAAoB,OACnCC,cAAgB,KAEPC,eAAenQ,MAAK,SAAUoQ,GACtCA,EAAMhF,SACFA,MAAM/L,SAAS6M,IACfA,EAAKrI,UAAYA,GAAWqI,EAAK9L,SAAWA,KACzC8P,cAAcpO,KAAKoK,WAM3BmE,sBAGFA,cAAgB,aACZ9L,aAAa+L,eAAiB,OAC9B/L,aAAa4H,OAAS,OACxBoE,gBAAkB,SAGpBC,oBAAsB,SAAUC,KAC5BlM,aAAa2H,KAAOuE,EAAK5P,OACzB0D,aAAa0L,kBAAoBQ,EAAKC,gBACtCnM,aAAa+L,eAAiB,OAC9B/L,aAAa4H,OAAS,OACxBoE,gBAAkB,GACnBE,EAAKE,WACFA,QAAQvP,KAAI,SAAU+K,OACrByE,GAAY,EACZzE,EAAO0E,WACFA,QAAQzP,KAAI,SAAU0P,GACvBA,GAA0B,wBAAhBA,EAAOhV,UACP,MAId8U,KACGL,gBAAgBzO,KAAKqK,YAM7B4E,eAAiB,SAAUC,KACvBzM,aAAa8H,mBAAmB4E,OAAOD,EAAO,SAGlDE,YAAc,aACV3M,aAAa8H,mBAAmBvK,KAAK,CAAEuL,SAAU,eAGrD8D,OAAS,iBACNC,EAAajI,EAAQ,SAAW,WAE/BrC,YAAYqK,QAAO,iBAClBvR,EAAS,CACbgN,cAAe,QACfyE,QAAStK,EAAYlG,KACrByQ,YAAajO,EAAOkB,aAAa+M,YACjCC,kBAAmBlO,EAAOkB,aAAa+M,YACvCE,iBAAkBnO,EAAOkB,aAAa1D,MAGpCwC,EAAOkB,aAAayL,iBACfzL,aAAa2H,KAAO7I,EAAOkB,aAAayL,aAAanP,OACrD0D,aAAa0L,kBAAoB5M,EAAOkB,aAAayL,aAAaU,eAGvErN,EAAOkB,aAAa+L,mBACf/L,aAAa4H,OAAS9I,EAAOkB,aAAa+L,eAAezP,YAG5D4Q,EAAOpO,EAAOkB,aAAa+M,aAAejO,EAAOkB,aAAa1D,KAC9DgM,EAAY4E,EAAO,SACnBC,EAAeD,EAAO,iBACrBlN,aAAazI,KAAO,uBACpByI,aAAa8E,iBAAmBhG,EAAOgG,iBACzChG,EAAOkB,aAAa2H,MAAS7I,EAAOkB,aAAaoN,eAC7CpN,aAAagI,eAAiB,QAGhChI,aAAa6H,OAAO,GAAGS,UAAYA,IAEnCtI,aAAa8H,mBAAmBhN,SAAQ,CAACuS,EAAMZ,OAC/C5D,SAAWsE,EAAeV,IAC1BnE,UAAYA,KAGiC,QAAhDxJ,EAAOkB,aAAa6H,OAAO,GAAGU,kBACzBvI,aAAa6H,OAAO,GAAGY,eAAY,GAGrC6E,EAAmBC,mBAAmBzO,EAAOkB,aAAcwC,EAAaqK,EAAYxR,YAI1FmS,OAAS,aACM5H,wgZC3PxB6H,EACGvS,OAHD,kDAGkE,CAChE0D,EACAD,EACA+O,EACAC,IAED9O,WAAW,+BAAgC,CAC1C,SACA,SACA,oBACA,YACA,eACA,MACA,sBACA,qBACA,KACA,SACEC,EACAC,EACA6O,EACA5O,EACAgB,EACAd,EACA2O,EACAC,EACA7R,qBASS+D,aAAed,EAAIG,cAAcI,KAAKoB,QAAO,SAAUrI,UAE1DA,EAAK8D,OAAS0D,EAAa1D,MAC3B9D,EAAKqD,SAAWmE,EAAanE,QAC7BrD,EAAK8G,UAAYU,EAAauJ,aAE/B,GAECzK,EAAOkB,aAAc,QACD8N,EAAmBC,uBACvCjP,EAAOkB,aAAahE,SACpBgE,EAAauJ,UACbvJ,EAAanE,OACbmE,EAAa1D,MAGMb,MAAK,SAAU4E,KAC3BC,MAAMC,SAAU,QACjByH,EAAiB,GAEjBgG,EAAW3N,EAAQQ,QAAO,SAAUrI,UACjCA,EAAK8D,OAAS0D,EAAa1D,WAGhC0R,EAASnW,WACJmI,aAAa+H,IAAMiG,EAAS,KAE5BhO,aAAaV,QAAUU,EAAauJ,UAEvCzK,EAAOkB,aAAa+H,IAAIC,mBACnBhI,aAAa+H,IAAIC,eAAelN,SAAQ,SAAUmT,SACjDC,EAAQL,EAAoBM,4BAChCjP,EACAc,EAAauJ,UACbvJ,EAAanE,OACboS,GAEEC,KACa3Q,KAAK2Q,QAGjBlG,eAAiBvK,EAAE2Q,OAAOpG,EAAgB,SAG/ClJ,EAAOkB,aAAa8E,kBAAoBhG,EAAOkB,aAAa8E,iBAAiBxD,SAAS,MAAM,OACxF/J,EAAOuH,EAAOkB,aAAa8E,mBAC1B9E,aAAa8E,iBAAmBvN,EACpCoB,MAAM,KACNkE,KAAKwR,UACEC,EAAKD,EAAE3V,qBACN4V,EAAGC,UAAU,EAAG,GAAGC,cAAgBF,EAAGC,UAAU,MAExD3V,KAAK,gBAKXkG,EAAOkB,gBACH0B,GAAG,KAGLzF,EAAGmC,KAAK,QApEVkC,MAAQ,CACbC,SAAS,KAGJkO,eAAiBC,EAAelT,IAAI,eAoExCoI,QACAnI,KAAKkT,GACLlT,MAAK,KAGCqD,EAAO+E,eACNC,UAAUhF,EAAQ6P,WAIvBC,iBAAmB,aACZvK,KAAK,CACbC,YAAa,yDACbzF,WAAY,sCACZlC,KAAM,KACN+H,QAAS,CACPlC,YAAa,kBACJtD,GAETc,aAAc,kBACLyN,EAAQoB,KAAK/P,EAAOkB,eAE7B4E,MAAO,kBACE,GAETE,iBAAkB,iBACT,CAAEvN,KAAMuH,EAAOkB,aAAa8E,4BAMtCgK,mBAAqB,cACpBhQ,EAAOkB,aAAaJ,WAAad,EAAOkB,aAAaJ,UAAU/H,oBAI7D0K,EAAc,CAClBC,YAAatD,EACbuD,MAAO,YAAczC,EAAa1D,MAG9ByS,EAAU,CACd1G,cAAe,QACf4E,iBAAkBnO,EAAOkB,aAAa1D,KACtCwI,iBAAkBhG,EAAOkB,aAAa8E,iBACtChJ,YAAagD,EAAOkB,aAAaV,QACjCzD,OAAQmE,EAAanE,OACrBiR,QAAS5N,EAAI5C,QAKUqG,QAAQ,CAC/BC,OAAQ,iBAAmB5C,EAAa1D,KAAO,IAC/CuG,WAAY,UAAY7C,EAAa1D,KACrCgD,QAASU,EAAauJ,UACtBzG,kBAAmBP,EACnBQ,aAPmB,IAAMuK,EAAmBwB,mBAAmBC,EAAS7P,8rCC/JlFhE,EAFE,kEAEiE,CAACyD,IAAqBE,WACvF,gCACA,CACE,SACA,eACA,iCACA,eACA,SAAUC,EAAQkQ,EAAcC,EAAgCC,KACvDC,eAAiB,CAAC,aAAc,oBAEjCC,EAAc,OACXC,eAAiBL,EAAa3O,UAC9BrE,SAAW8C,EAAOwQ,MAAMC,QAAQC,mBAAqB,UACrDC,UACL9I,EAAS+I,QAAQD,WAC0B,mBAAnC9I,EAAS+I,QAAQC,eACvBhJ,EAAS+I,QAAQC,cAAc7Q,EAAOwQ,MAAMC,WACzCK,gBAAkBV,EACvBpQ,EAAO2Q,WAAa9I,EAASkJ,eAAiBlJ,EAASkJ,eAAiBlJ,EAASiJ,kBAI/EE,EAAa,IAAMb,EAA+Bc,mBAAmBjR,EAAOqQ,eAAgBC,SAI3FY,IAAI,sBAAuBF,MClBxC5U,EAFyD,2CAEP,CDVhD,oECWC+U,QAAO,aACGC,SAASC,cAAc,CAC9BC,SAAU,OACV/H,cAAe,QACflM,MAAO,OACP3E,YAAa,iBACb8M,YAAa,gDACb+L,oBAAqB,2DACrBC,wBAAyBC,EACzBC,gBAAkBlB,GACTA,EAAMmB,YAAYlB,QAAQmB,oBAAsBpB,EAAMmB,YAAYlB,QAAQoB,oBAAsB,EAAI,EAE7GC,uBAAuB,EACvBC,WAAY,CACV,CAAEtZ,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,WACpC,CACEvZ,KAAM,0BACNwZ,qBAAqB,EACrBC,WAAaC,GACX,2GAEAA,EAAOpU,KAAKV,GAAU,OAAOA,WAAcvD,KAAK,IAChD,oFAINsY,aAAa,OAGhBrS,WAAW,qBAAsB,CAChC,SACA,KACA,YACA,SAAUC,EAAQ7C,EAAI+C,KACbsQ,MAAM6B,mBAAqBrS,EAAOwQ,MAAM6B,oBAAsB,KAC9D7B,MAAMzF,QAAU/K,EAAOwQ,MAAMzF,SAAW,GAE1C/K,EAAOwQ,MAAM8B,SACT9B,MAAM8B,KAAOC,EAAsBC,uBAAuBhV,QAG5DiV,UAAY,CACjBhR,SAAS,QA2CNiR,cAAgB,WACbC,EAAiBhU,EAAE5E,KAAKiG,EAAO4S,cAAe,CAAE5R,GAAIhB,EAAOwQ,MAAMqC,WAChErC,MAAMsC,OAASH,EAAeG,aA4BlCC,qBAAuB,WACrB/S,EAAOwQ,MAAM6B,uBACT7B,MAAM6B,mBAAqB,MAGjC9M,KAAK,CACJC,YAAawN,EAAkBC,sBAC/BlT,WAAY,0CACZmT,aAAc,uBACdtN,QAAS,CACPuN,kBAAmB,iBACV,CACLlX,IAAK,GACLuM,MAAO,QAKdtC,OAAOvJ,MAAK,SAAUwW,KACd3C,MAAM6B,mBAAmBc,EAAkBlX,KAAOkX,EAAkB3K,SAE5ErC,OAAM,eAGNiN,wBAA0B,SAAUnX,UAChC+D,EAAOwQ,MAAM6B,mBAAmBpW,SAGpCoX,qBAAuB,kBACnBrT,EAAOyS,UAAU9B,WAAa3Q,EAAOwQ,MAAM8C,uBAG/CC,uBAAyB,kBAE1BvT,EAAOyS,UAAU9B,WAAc3Q,EAAOwQ,MAAM6B,oBAAsB1T,EAAEd,KAAKmC,EAAOwQ,MAAM6B,oBAAsB,QAI3GmB,gBAAkB,kBACdxT,EAAOyS,UAAU9B,WAAa3Q,EAAOwQ,MAAMiD,eAG7CC,OAAO,sBAjDVC,OAAO3T,EAAOwQ,OAAO,SAAUoD,EAAK3X,GACxB,KAAR2X,UACK5T,EAAOwQ,MAAMvU,MAjBsB,mBAAnC4L,EAAS+I,QAAQC,kBACnB4B,UAAU9B,UAAY9I,EAAS+I,QAAQC,cAAc7Q,EAAOwQ,WA+DlC,KA/GhC3L,IAAI,CACLgP,EAAaC,WAAW,SACxBD,EAAaE,iBAAiB,SAC9BF,EAAaG,wBACZrX,MAAK,UAAWoO,EAAS6H,EAAeqB,MAClClJ,QAAUA,EACa,IAA1B/K,EAAO+K,QAAQhS,SACVyX,MAAMzT,OAASiD,EAAO+K,QAAQ,GAC3B/K,EAAO+K,QAAQvI,SAASxC,EAAOwQ,MAAMzT,gBACxCiD,EAAOwQ,MAAMzT,QAEjBiD,EAAOwQ,MAAMzF,QAAQhS,QAAUiH,EAAO0D,YAAY4F,eAAevB,SAC7DyI,MAAMzF,QAAQtM,KAAKuB,EAAO0D,YAAY4F,eAAevB,QAEzD/H,EAAOwQ,MAAMzF,QAAQhS,QAAUiH,EAAO0D,YAAY4F,eAAevB,SAC7DyI,MAAMzF,QAAQtM,KAAKuB,EAAO0D,YAAY4F,eAAevB,SAEvD6K,cAAgBA,EAAcsB,WACjClU,EAAO4S,cAAc7Z,WAChByX,MAAMsC,OAASF,EAAcsB,WAAW,GAAGpB,UAG7CmB,iBAAmBA,GAErBjU,EAAOwQ,MAAMqC,QAAU7S,EAAO4S,eAAiB5S,EAAO4S,cAAc7Z,WAChEyX,MAAMqC,OAAS7S,EAAO4S,cAAc,GAAG5R,KAG3ChB,EAAOwQ,MAAM2D,WAAanU,EAAOiU,kBAAoBjU,EAAOiU,iBAAiBlb,WACzEyX,MAAM2D,UAAYnU,EAAOiU,iBAAiB,MAE5CxB,UAAU9B,UACf9I,EAAS+I,QAAQD,WAC0B,mBAAnC9I,EAAS+I,QAAQC,eAAgChJ,EAAS+I,QAAQC,cAAc7Q,EAAOwQ,SAC1F4D,qCAmBHC,EAAMrU,EAAOwQ,iBAEb8C,kBACHe,EAAIhC,oBAAsB1T,EAAEd,KAAKwW,EAAIhC,oBAAsB,GAC5DgC,EAAIZ,aAvByBa,KACtB7B,UAAUhR,SAAU,umNC7FrCrF,EAFqE,iDAEP,IAC3D+U,QAAO,aACGC,SAASC,cAAc,CAC9BC,SAAU,qBACV/H,cAAe,QACf/D,YAAa,4DACb+O,sBAAuB,gEACvBC,iBAAmBhE,GAAU,CAACA,EAAMC,QAAQzT,aAC5CyX,uBAAyBjE,GAAU,CAACA,EAAMxT,aAC1C+U,WAAY,CACV,CACEtZ,KAAM,kBACNic,QACE,+GAEJ,CAAEjc,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,UACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,cAAe2C,WAAY,iBAIpE5U,WAAW,2BAA4B,CACtC,SACA,SAAUC,SACFuK,EAAO1E,KAEP2K,EAAQxQ,EAAOwQ,QAEdhP,MAAQ,CACbwK,UAAU,EACV4I,eAAe,KAGF7I,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACXxK,MAAMwK,UAAW,OAGrBC,eAAiB,aACL4I,kBAAkBrE,EAAMxT,aAAaL,MAAK,SAAU4E,KAC3DwJ,QAAU,CAACxJ,EAAQuT,WAKtBC,QAAUC,EAAeC,cAE1BlK,QAAUyF,EAAMzF,SAAW,KAC3BxB,cAAgB,UAEhB2L,+BAAiC,IAElC1E,EAAMxT,aAAegD,EAAO0D,YAAY2F,mBAAmBtB,UACxD/K,YAAcgD,EAAO0D,YAAY2F,mBAAmBtB,OAGxDyI,EAAMxT,eACHiP,iBAEFuE,EAAM2E,WACHA,OAASnV,EAAO+U,QAAQ,GAAGnB,uzBC7DzCxX,EAFqE,iDAEP,IAC3D+U,QAAO,aACGC,SAASC,cAAc,CAC9BC,SAAU,qBACV8D,MAAO,aACP7L,cAAe,QACf/D,YAAa,4DACb+O,sBAAuB,gEACvBxC,WAAY,CACV,CACEtZ,KAAM,kBACNic,QACE,+GAEJ,CAAEjc,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,UACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,cAAe2C,WAAY,iBAIpE5U,WAAW,2BAA4B,CACtC,SACA,SAAUC,SACFwQ,EAAQxQ,EAAOwQ,QAEdhP,MAAQ,CACbwK,UAAU,EACV4I,eAAe,KAGF7I,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACXxK,MAAMwK,UAAW,OAGnB+I,QAAUC,EAAeC,cAE1BlK,QAAUyF,EAAMzF,SAAW,KAC3BxB,cAAgB,QAElBiH,EAAM1K,OAAS9F,EAAO0D,YAAY2R,WAAWC,uBACzCJ,+BAAiC,KAGpC1E,EAAMxT,aAAegD,EAAO0D,YAAY2F,mBAAmBtB,UACxD/K,YAAcgD,EAAO0D,YAAY2F,mBAAmBtB,QAEvDyI,EAAMzF,QAAQhS,QAAUiH,EAAO0D,YAAY4F,eAAevB,SACvDgD,QAAQtM,KAAKuB,EAAO0D,YAAY4F,eAAevB,OAGlDyI,EAAM2E,WACHA,OAASnV,EAAO+U,QAAQ,GAAGnB,g9BCrDzCxX,EAFmE,gDAEP,IACzD+U,QAAO,aACGC,SAASC,cAAc,CAC9BC,SAAU,oBACV8D,MAAO,YACP7L,cAAe,QACf/D,YAAa,0DACb+O,sBAAuB,8DACvBxC,WAAY,CACV,CAAEtZ,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,UACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,WACpC,CAAEvZ,KAAM,gBAAiBuZ,UAAW,cAAe2C,WAAY,iBAIpE5U,WAAW,0BAA2B,CACrC,SACA,SAAUC,SACFuK,EAAO1E,KAEP2K,EAAQxQ,EAAOwQ,QAEdhP,MAAQ,CACbwK,UAAU,EACV4I,eAAe,KAGF7I,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACXxK,MAAMwK,UAAW,OAGrBuJ,MAAQ,OACNtJ,mBACAuJ,0BAGAT,QAAUC,EAAeC,cAE1BlK,QAAUyF,EAAMzF,SAAW,KAC3BxB,cAAgB,QAElBiH,EAAM1K,UAEFoP,+BAAiC,KAGpC1E,EAAMxT,aAAegD,EAAO0D,YAAY2F,mBAAmBtB,UACxD/K,YAAcgD,EAAO0D,YAAY2F,mBAAmBtB,QAEvDyI,EAAMzF,QAAQhS,QAAUiH,EAAO0D,YAAY4F,eAAevB,SACvDgD,QAAQtM,KAAKuB,EAAO0D,YAAY4F,eAAevB,OAGlDyI,EAAM2E,WACHA,OAASnV,EAAO+U,QAAQ,GAAGnB,OAG5BF,OAAO,oBAAqB1T,EAAOiM,o9BCzDhD7P,EAF+D,8CAEP,CAACyD,IAAqBxD,QAC5E,4BACA,iBAuCS,CACLoZ,6BApB2BC,EAAehS,EAAanH,EAAS,MACzD9D,KAAO,wBACPkd,kBAAoBD,EAAclY,OAClCuN,QAAU,CAAC2K,EAAc3Y,UACzBC,YAAc0Y,EAAcjL,YAE5BuD,QAAUtK,EAAYlG,WAEvBoY,EAAYC,EAAaC,YAAY,CACzCC,IAAK,CAACxZ,GACNmH,YAAAA,EACAhL,YAAa,UAAUkX,EAAelT,IAAI,iBAAiBgZ,EAAclY,kBAGtDwY,WAAW,iBAEzBJ,GAKPK,6BAxC2BP,EAAehS,EAAaqK,EAAYxR,EAAS,MACrEoZ,kBAAoBD,EAAclY,OAGvC0Y,WAAW3Z,EAAQmZ,GAAe,SAAUlN,EAAO2N,UAC5CxX,EAAEyX,YAAY5N,GAAS2N,EAAQ3N,WAGlCoN,EAAYC,EAAaC,YAAY,CACzCC,IAAK,CAACxZ,GACNmH,YAAAA,EACAhL,YAAa,GAAGqV,KAAc6B,EAAelT,IAAI,sEAG9BsZ,WAAW,iBAEzBJ,OCjBbxZ,EAFqE,kDAEP,CAC5DyD,EDL6D,gDCO5DE,WAAW,+BAAgC,CAC5C,SACA,oBACA,SACA,cACA,cACA,gBACA,2BACA,SAAUC,EAAQqK,EAAmBpK,EAAQoW,EAAa3S,EAAagS,EAAeY,KAC7EtL,MAAQ,CACbrL,SAAU,uEACV4W,QAAS,uEAGJxL,QAAU,KAEVyL,cAAgB5G,EAAelT,IAAI,kBAEpC6N,EAAO1E,qBAqBP7F,EAAO+E,qBAGOM,cACZmF,EAAiB,CACrBhN,KAAMwC,EAAO0V,cAAclY,KAC3BiN,UAAWzK,EAAO0V,cAAc1Y,aAAegD,EAAO0V,cAAce,YACpE1Z,OAAQiD,EAAO0V,cAAc3K,QAAQ,GACrC7N,SAAU,SAEP+C,EAAOuC,SAAS,wBAGZI,GAAG,oBAAqB4H,KAFxB5H,GAAG,mBAAoB4H,cAyLfkM,EAASC,EAAGC,SACvBC,EAAOH,EAAQE,GACfE,EAAYJ,EAAQC,GAAGI,SACvBC,EAAYN,EAAQE,GAAGG,WAErBH,GAAKF,EAAQC,KACbA,GAAKE,IAELF,GAAGI,SAAWD,IACdF,GAAGG,SAAWC,IAjOjBlR,OAAQ,IACRtE,MAAQ,CACb8J,YAAY,EACZ2L,eAAgB,CACdC,SAAU,GACVC,aAAc,OAIHpL,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACbC,sBAGFmL,aAAe,aACX5V,MAAMyV,eAAeE,cAAgBnX,EAAOwB,MAAMyV,eAAeC,YA2BnEzT,YAAc,IAAI8H,EAAY,CACnC7H,YAAAA,EACAC,MAAO,iBAAiBiM,EAAelT,IAAI,cAC3C8O,cAAenB,EACfzG,4BARYsF,eAAe0B,YACf1B,eAAeuC,cAAczL,EAAQ0L,QAU5CgK,cAAgBA,IAElBzJ,eAAiB,aACLO,qBAAqBxM,EAAO0V,cAAc1Y,aAAaL,MAAK,SAAUoO,KAC5EA,QAAUA,IACV2K,cAAc3K,QAAUA,IAC1BqB,eACAK,yBAIJA,cAAgB,aACdC,oBAGFA,YAAc,iBACXlM,EAAUR,EAAO0V,cAAc1Y,YAC/BD,EAASiD,EAAO0V,cAAc3Y,SAC7B2Y,cAAc/I,aAAe,OAC7B+I,cAAc7M,KAAO,OACrB6M,cAAc9I,kBAAoB,OAEpCC,cAAgB,KAEPC,eAAenQ,MAAK,SAAUoQ,GACtCA,EAAMhF,SACFA,MAAM/L,SAAS6M,IACfA,EAAKrI,UAAYA,GAAWqI,EAAK9L,SAAWA,KACzC8P,cAAcpO,KAAKoK,WAM3BmE,sBAGFA,cAAgB,aACZ0I,cAAczI,eAAiB,OAC/ByI,cAAc5M,OAAS,OACzBoE,gBAAkB,SAGpBC,oBAAsB,SAAUC,KAC5BsI,cAAc7M,KAAOuE,EAAK5P,OAC1BkY,cAAc9I,kBAAoBQ,EAAKC,gBACvCqI,cAAczI,eAAiB,OAC/ByI,cAAc5M,OAAS,OACzBoE,gBAAkB,GACnBE,EAAKE,WACFA,QAAQvP,KAAI,SAAU+K,KACpBoE,gBAAgBzO,KAAKqK,SAK3B4F,OAAS,aACM5H,aAGfsF,WAAa,iBACViL,EAAgBrX,EAAO0V,kBACzBtH,EAAO1K,EAAYlG,KACnB6Z,EAAczO,YACR,IAAMyO,EAAczO,UAEhBpL,KAAO4Q,IACdkJ,YAAclJ,KAGlBmJ,OAAS,aACL9T,YAAYqK,QAAO,iBAClBvR,EAAS,CACbgN,cAAe,QACfyE,QAAStK,EAAYlG,KACrBT,OAAQiD,EAAO0V,cAAc3Y,OAC7B0D,MAAO,eAGLT,EAAO0V,cAAc/I,iBAChB+I,cAAc7M,KAAO7I,EAAO0V,cAAc/I,aAAanP,OACvDkY,cAAc9I,kBAAoB5M,EAAO0V,cAAc/I,aAAaU,eAGzErN,EAAO0V,cAAczI,mBAChByI,cAAc5M,OAAS9I,EAAO0V,cAAczI,eAAezP,QAG7DkY,cAAcjd,KAAO,sBAErB6d,EAAyBL,oBAAoBjW,EAAO0V,cAAehS,EAAa,SAAUnH,SAIhGib,QAAU,SAAUd,KACfjY,KAAK,CACXjB,KAAMwC,EAAO0V,cAAclY,KAAO,QAAUkZ,EAAQ3d,OACpDge,SAA4B,GAAlBL,EAAQ3d,OAAc,IAAM,OAAeA,OAAS,GAC9D0e,WAAY,MACZzN,SAAU,MACV0N,OAAQ,QACRC,UAAW,UACXC,oBAAqB,IACrBC,sBAAuB,GACvBC,gBAAiB,IACjBC,yBAA0B,IAC1BC,qBAAsB,IACtBC,sBAAuB,GACvBC,eAAgB,IAChBC,mBAAoB,SAInBC,YAAc,SAAU1B,EAAS/I,OAC/BhP,EAAE0Z,QAAQ3B,EAAQ/I,GAAOuK,gBAAiB,OACvCI,EAAa5B,EAAQ/I,GAAOuK,eAAere,MAAM,KAEnDye,EAAWvf,OAAS,KACd4U,GAAOsK,sBAAwB,KAC5Bjc,SAAS3C,GAAMqd,EAAQ/I,GAAOsK,sBAAsBxZ,KAAKpF,OAG5DsU,GAAOqK,qBAAuB,SAE9BrK,GAAOqK,qBAAuBtB,EAAQ/I,GAAOuK,iBAG7CvK,GAAOsK,sBAAwB,QAKxCM,oBAAsB,SAAU7B,EAAS/I,OACvChP,EAAE0Z,QAAQ3B,EAAQ/I,GAAOuK,gBAAiB,OACvCI,EAAa5B,EAAQ/I,GAAOwK,mBAAmBte,MAAM,KACvDye,EAAWvf,OAAS,KACd4U,GAAOkK,sBAAwB,KAC5B7b,SAAS3C,GAAMqd,EAAQ/I,GAAOkK,sBAAsBpZ,KAAKpF,OAG5DsU,GAAOiK,oBAAsB,SAE7BjK,GAAOiK,oBAAsBlB,EAAQ/I,GAAOwK,qBAG5CxK,GAAOkK,sBAAwB,QAKxCW,gBAAkB,SAAU9B,EAAS/I,KAChCA,GAAO3D,SAAW0M,EAAQ/I,GAAO8J,cAGtCgB,WAAa,SAAU/B,EAAS/I,KAC3BC,OAAOD,EAAO,MAGnB+K,OAAS,SAAUhC,EAAS/I,GACjB,IAAVA,KACM+I,EAAS/I,EAAOA,EAAQ,MAE/BgL,SAAW,SAAUjC,EAAS/I,GAC7BA,IAAU+I,EAAQ3d,OAAS,KACrB2d,EAAS/I,EAAOA,EAAQ,MAe7B+H,cAAckD,cAAgB,i4NCnPzCxc,EAFE,sDAE0D,CAC1DyD,EACAgZ,EACAjK,EFd6D,gDEgB5D7O,WAAW,6BAA8B,CAC1C,SACA,oBACA,oBACA,SACA,sBACA,mBACA,cACA,gBACA,2BACA,SACEC,EACAqK,EACAyE,EACA7O,EACA8O,EACA+J,EACApV,EACAgS,EACAY,mBA0EMtW,EAAO+E,qBAGOM,cACZmF,EAAiB,CACrBhN,KAAMwC,EAAO0V,cAAclY,KAC3BiN,UAAWzK,EAAO0V,cAAc1Y,aAAegD,EAAO0V,cAAce,YACpE1Z,OAAQiD,EAAO0V,cAAc3Y,OAC7BG,SAAU,SAEP+C,EAAOuC,SAAS,wBAGZI,GAAG,oBAAqB4H,KAFxB5H,GAAG,mBAAoB4H,cA4DfkM,EAASC,EAAGC,SACvBC,EAAOH,EAAQE,GACfE,EAAYJ,EAAQC,GAAGI,SACvBC,EAAYN,EAAQE,GAAGG,WAErBH,GAAKF,EAAQC,KACbA,GAAKE,IAELF,GAAGI,SAAWD,IACdF,GAAGG,SAAWC,IAxJjBhM,MAAQ,CACbuL,QAAS,uEAGGqC,cAAgBja,EAAEZ,IAAI2X,EAAckD,eAAe,SAAUrK,UACpE5P,EAAE0Z,QAAQ9J,EAAKvE,cACbyN,WAAalJ,EAAKvE,SAASpQ,iBAG7Bse,eAAiB3J,EAAKwK,4BACtBZ,mBAAqB5J,EAAKyK,yBAExBzK,OAGFmH,cAAgBA,IAEhBlU,MAAQ,CACbyX,0BAA0B,KAGrBxV,YAAc,IAAI8H,EAAY,CACnC7H,YAAAA,EACAC,MAAO,iBAAiBiM,EAAelT,IAAI,cAC3C8O,cAAenB,EACfzG,4BAiEYsF,eAAe0B,YACf1B,eAAeuC,cAAczL,EAAQ0L,WA/D9CwN,4BAA8B,kBAC1BC,EAAqBzc,IAAI,kBAAkB0c,WAAWC,aAG1DC,sBAAwB,oBACpB9X,MAAMyX,0BAA2B,EACjCH,EAAiBS,aAAa,kBAAkB5c,MAAK,WAQrDoS,EAAoByK,uBAAuB7c,MAAK,SAAUuM,SACzD1I,EAAUkV,EAAce,YACxB1Z,EAAS2Y,EAAc3Y,OACvB0c,EAAkB9a,EAAEoD,OAAOmH,EAAe1I,GAASuH,MAAMhL,GAAS,MAGjE2c,wBAA0B/a,EAAEZ,IAAI0b,EAAiB,WAb7B9c,MAAK,aACvB6E,MAAMyX,0BAA2B,cAgBzCzB,QAAU,SAAUd,KACfjY,KAAK,CACXjB,KAAMwC,EAAO0V,cAAclY,KAAO,QAAUkZ,EAAQ3d,OACpDge,SAA6B,IAAnBL,EAAQ3d,OAAe,IAAM,OAAeA,OAAS,GAC/D0e,WAAY,MACZC,OAAQ,QACRC,UAAW,UACXC,oBAAqB,IACrBC,sBAAuB,GACvBC,gBAAiB,IACjBC,yBAA0B,IAC1BC,qBAAsB,IACtBC,sBAAuB,GACvBC,eAAgB,IAChBC,mBAAoB,YA4BnBC,YAAc,SAAU1B,EAAS/I,OAC/BhP,EAAE0Z,QAAQ3B,EAAQ/I,GAAOwK,oBAAqB,OAC3CG,EAAa5B,EAAQ/I,GAAOuK,eAAere,MAAM,KACnDye,EAAWvf,OAAS,KACd4U,GAAOsK,sBAAwB,KAC5Bjc,SAAS3C,GAAMqd,EAAQ/I,GAAOsK,sBAAsBxZ,KAAKpF,OAG5DsU,GAAOqK,qBAAuB,SAE9BrK,GAAOqK,qBAAuBtB,EAAQ/I,GAAOuK,iBAG7CvK,GAAOsK,sBAAwB,WAKxCM,oBAAsB,SAAU7B,EAAS/I,OACvChP,EAAE0Z,QAAQ3B,EAAQ/I,GAAOwK,oBAAqB,OAC3CG,EAAa5B,EAAQ/I,GAAOwK,mBAAmBte,MAAM,KACvDye,EAAWvf,OAAS,KACd4U,GAAOkK,sBAAwB,KAC5B7b,SAAS3C,GAAMqd,EAAQ/I,GAAOkK,sBAAsBpZ,KAAKpF,OAG5DsU,GAAOiK,oBAAsB,SAE7BjK,GAAOiK,oBAAsBlB,EAAQ/I,GAAOwK,qBAG5CxK,GAAOkK,sBAAwB,WAKxCY,WAAa,SAAU/B,EAAS/I,KAC3BC,OAAOD,EAAO,SAGnB+K,OAAS,SAAUhC,EAAS/I,GACjB,IAAVA,KACM+I,EAAS/I,EAAOA,EAAQ,SAE/BgL,SAAW,SAAUjC,EAAS/I,GAC7BA,IAAU+I,EAAQ3d,OAAS,KACrB2d,EAAS/I,EAAOA,EAAQ,MAe7BlK,YAAYG,eAAiByG,EAAkBvD,aAEjDyQ,OAAS,aACL9T,YAAYqK,QAAO,iBAClBvR,EAAS,CACbgN,cAAe,QACfyE,QAAStK,EAAYlG,KACrBT,OAAQiD,EAAO0V,cAAc3Y,OAC7B+L,OAAQ,KACRrI,MAAO,iBAEFiV,cAAcjd,KAAO,sBAErB6d,EAAyBL,oBAAoBjW,EAAO0V,cAAehS,EAAa,SAAUnH,YAIhGmS,OAAS,aACM5H,ywHC9MxB1K,EAFuE,iDAEP,CHJD,8CCEM,oDEKlE2D,WAAW,oCAAqC,CACjD,SACA,oBACA,cACA,SACA,2BACA,gBACA,cACA,SAAUC,EAAQqK,EAAmBgM,EAAapW,EAAQqW,EAA0BZ,EAAehS,SAC3F6G,EAAO1E,qBA0EP7F,EAAO+E,qBAGOM,cACZmF,EAAiB,CACrBhN,KAAMwC,EAAO0V,cAAclY,KAC3BiN,UAAWzK,EAAO0V,cAAc1Y,aAAegD,EAAO0V,cAAce,YACpE1Z,OAAQiD,EAAO0V,cAAc3Y,OAC7BG,SAAU,SAEP+C,EAAOuC,SAAS,wBAGZI,GAAG,oBAAqB4H,KAFxB5H,GAAG,mBAAoB4H,cAyBfkM,EAASC,EAAGC,SACvBC,EAAOH,EAAQE,GACfE,EAAYJ,EAAQC,GAAGI,SACvBC,EAAYN,EAAQE,GAAGG,WAErBH,GAAKF,EAAQC,KACbA,GAAKE,IAELF,GAAGI,SAAWD,IACdF,GAAGG,SAAWC,IArHjBR,cAAgB5G,EAAelT,IAAI,cAEnCsO,MAAQ,CACbrL,SAAU,uEACV4W,QAAS,uEAGGqC,cAAgBja,EAAEZ,IAAI2X,EAAckD,eAAe,SAAUrK,SACnEsI,EAAOtI,EAAKyJ,qBAAqBne,MAAM,cACxC8f,UAAYrb,OAAOuY,EAAK,MACxB+C,QAAUtb,OAAOuY,EAAK,IACpBtI,OAGJtC,eAAiB,aACLO,qBAAqBxM,EAAO0V,cAAc1Y,aAAaL,MAAK,SAAUoO,KAC5EA,QAAUA,IACV2K,cAAc3K,QAAUA,IAC1BqB,mBAIJsC,OAAS,aACM5H,aAGfsF,WAAa,iBACViL,EAAgBrX,EAAO0V,kBACzBtH,EAAO1K,EAAYlG,KACnB6Z,EAAczO,YACR,IAAMyO,EAAczO,UAEhBpL,KAAO4Q,IACdkJ,YAAclJ,KAGhBsH,cAAgBA,IAEhBlU,MAAQ,CACbyX,0BAA0B,KAGrBxV,YAAc,IAAI8H,EAAY,CACnC7H,YAAAA,EACAC,MAAO,iBAAiBiM,EAAelT,IAAI,cAC3C8O,cAAenB,EACfzG,4BA4CYsF,eAAe0B,YACf1B,eAAeuC,cAAczL,EAAQ0L,QA1CpCK,aAAa,SAASpP,MAAK,SAAUqP,KAC3CA,SAAWA,IACbC,sBAGFuL,QAAU,SAAUd,KACfjY,KAAK,CACXjB,KAAMwC,EAAO0V,cAAclY,KAAO,QAAUkZ,EAAQ3d,OACpDge,SAA6B,IAAnBL,EAAQ3d,OAAe,IAAM,OAAeA,OAAS,GAC/DiR,SAAU,MACV0N,OAAQ,QACRC,UAAW,UACXC,oBAAqB,IACrBE,gBAAiB,IACjBC,yBAA0B,IAC1BC,qBAAsB,YACtB2B,UAAW,KACXC,QAAS,UA4BRxB,YAAc,SAAU1B,EAAS/I,KAC5BA,GAAOqK,qBAAuBtB,EAAQ/I,GAAOgM,UAAY,IAAMjD,EAAQ/I,GAAOiM,WAEnFnB,WAAa,SAAU/B,EAAS/I,KAC3BC,OAAOD,EAAO,MAEnB+K,OAAS,SAAUhC,EAAS/I,GACjB,IAAVA,KACM+I,EAAS/I,EAAOA,EAAQ,MAE/BgL,SAAW,SAAUjC,EAAS/I,GAC7BA,IAAU+I,EAAQ3d,OAAS,KACrB2d,EAAS/I,EAAOA,EAAQ,MAc/B4J,OAAS,aACL9T,YAAYqK,QAAO,iBAClBvR,EAAS,CACbgN,cAAe,QACfyE,QAAStK,EAAYlG,KACrBT,OAAQiD,EAAO0V,cAAc3Y,OAC7B+L,OAAQ,OACRrI,MAAO,iBAEFiV,cAAcjd,KAAO,sBAErB6d,EAAyBL,oBAAoBjW,EAAO0V,cAAehS,EAAa,QAASnH,q4NC/IxGoS,EACGvS,OAHD,yDAGoE,CAClEyD,EACA+O,EJT2D,8CGEQ,mDCWpE7O,WAAW,gCAAiC,CAC3C,SACA,SACA,wBACA,MACA,2BACA,sBACA,YACA,SAAUC,EAAQC,EAAQ4Z,EAAuBzZ,EAAKkW,EAA0BvH,EAAqB7O,SAC7FwD,EAActD,EACdsV,EAAgBmE,sBASb9K,EACJ+K,wBACCpW,EACAgS,EAAcjL,UACdiL,EAAcxY,SACdwY,EAAc3Y,OACd2Y,EAAcjV,MACdiV,EAAclY,MAEfb,MACC,SAAU4E,KACDC,MAAMC,SAAU,GAElBF,GAAW5C,EAAE0Z,QAAQ9W,SAGjBmU,cAAgBnU,KAG3B,iCAOGqB,GAAG,OAjCLpB,MAAQ,CACbC,SAAS,KAGJ+U,cAAgB5G,EAAelT,IAAI,gBAgCnBC,MAAK,KAGrBqD,EAAO+E,eACNmE,eAAelE,UAAUhF,EAAQ+Z,WAIpCC,iBAAmB,aACZzU,KAAK,CACbC,YAAa,2DACbzF,WAAY,qCACZ6F,QAAS,CACP8P,cAAe,kBACN/G,EAAQoB,KAAK/P,EAAO0V,gBAE7BhS,YAAa,kBACJA,YAMVuW,mBAAqB,aACd1U,KAAK,CACbC,YAAa,wDACbzF,WAAY,4CACZ6F,QAAS,CACP8P,cAAe,iBACP2B,EAAgB1I,EAAQoB,KAAK/P,EAAO0V,sBACtC2B,EAActa,WACFgO,QAAU,CAACsM,EAActa,SAElCsa,GAET3T,YAAa,kBACJA,YAMV+R,oBAAsB,iBACnBhS,EAAc,CAClBC,YAAAA,EACAC,MAAO,YAAc+R,EAAclY,QAWZqG,QAAQ,CAC/BC,OAAQ,iBAAmB4R,EAAclY,KAAO,IAChDuG,WAAY,UAAY2R,EAAclY,KACtCgD,QAASkV,EAAcjL,UACvBzG,kBAAmBP,EACnBQ,aAbmB,oBACZyR,cAAcjd,KAAO,sBACrB6d,EAAyBb,oBAAoBC,EAAehS,EAAa,CAC9E6F,cAAe,QACf9I,MAAOT,EAAO0V,cAAcjV,YAa9BL,EAAIwB,iBAEFsH,eAAiB,CACnB0B,QAASmP,4zCCnInB3d,EAFwD,uCAEP,IAAIC,QAAQ,4BAA4B,iBAOhF,CACL6d,qCAPmCC,EAAuBC,EAAWjL,SAE/D0H,EAAO1H,EAAgBtV,MAAM,YAC5BsgB,EAAsBC,EAAU5Z,SAAS4Z,EAAUrd,QAAQ8Z,EAAKA,EAAK9d,OAAS,SCJzFqD,EAF6D,4CAEP,IAAIC,QAAQ,iCAAiC,iBAG1F,CACLge,wCCHJje,EAFyD,0CAEP,IAAIC,QAAQ,+BAA+B,sBAKvD4T,EAASqK,MAMvCC,MAAMC,QAAQvK,EAAQwK,sBAAsBC,YAChCD,sBAAsBC,SAAWzK,EAAQwK,sBAAsBC,aACxE,OACCC,EAAe1K,EAAQwK,sBAAsBC,SAC/CC,EAAanY,SAAS,OACViY,sBAAsBC,SAAWC,EAAa9gB,MAAM,KACzD8gB,EAAanY,SAAS,OACjBiY,sBAAsBC,SAAWC,EAAa9gB,MAAM,OAEpD4gB,sBAAsBC,SAAW,CAACC,KAGpCF,sBAAsBC,SAAS1e,SAAQ,SAAU3C,EAAGsU,KAClD8M,sBAAsBC,SAAS/M,GAAStU,EAAEuhB,iBAiHvD,CACLC,wDA7GsD5K,OAClD6K,IAE2B,iBAA3B7K,EAAQwC,UAAUsI,MAAsD,mBAA3B9K,EAAQwC,UAAUsI,KACrD,CACVC,UAAW,GACXC,SAAU,OACVC,UAAW,GACXC,MAAO,GACPC,IAAK,GACLC,QAAS,GACTte,OAAQkT,EAAQlT,OAChBue,IAAK,GACLC,OAAQ,IAGEtL,EAAQuL,oBAGhBlB,EAAgB,CACpB9c,KAAMyS,EAAQvM,YACd6F,cAAe0G,EAAQwL,iBACvB/X,YAAauM,EAAQvM,YACrBiF,MAAOsH,EAAQtH,MACf+S,SAAUzL,EAAQyL,SAClBC,SAAU,CACRC,UAAW3L,EAAQ0L,SAAW1L,EAAQ0L,SAASC,UAAY,MAE7DC,UAAW5L,EAAQ4L,UACnBC,iBAAkB7L,EAAQ6L,iBAC1BC,sBAAuB9L,EAAQ8L,sBAC/BC,wBAAyB/L,EAAQ+L,wBACjCC,kBAAwC,aAArBhM,EAAQyL,UAAiC,KAC5DQ,qBAA2C,aAArBjM,EAAQyL,UAAiC,KAC/D9S,OAAQqH,EAAQnE,gBAChBA,gBAAiBmE,EAAQnE,gBACzBqQ,eAAgBlM,EAAQkM,eACxBC,MAAOnM,EAAQmM,MACf5b,QAASyP,EAAQjT,YACjBye,iBAAkB,QAClB5S,KAAMoH,EAAQpH,KACd+D,kBAAmBqD,EAAQtD,aAAaU,cACxCvE,OAAQmH,EAAQnH,OAChBuT,mBAAmB,EACnBC,SAAU,CACRje,IAAK4R,EAAQmL,IAAIkB,SACjB9d,IAAKyR,EAAQmL,IAAIkB,UAEnBtf,YAAaiT,EAAQjT,YACrBD,OAAQkT,EAAQlT,OAChB4Y,kBAAmB1F,EAAQ0F,kBAC3BxH,iBAAkB8B,EAAQ9B,iBAC1BnI,iBAAkBiK,EAAQjK,iBAC1BsM,KAAM,cACNiK,cAAe,SACf9jB,KAAM,oBACN2iB,IAAK,CACH5d,KAAM,kBACNgf,KAAM,WACNF,SAAUrM,EAAQmL,IAAIkB,UAExBG,aAAcxM,EAAQwM,aACtBC,UAAWzM,EAAQyM,UACnBC,uBAAwB1M,EAAQ0M,uBAChClK,UAAWxC,EAAQwC,UACnBmK,SAAU,CACRC,WAAY5M,EAAQ2M,SAAW3M,EAAQ2M,SAASC,WAAa,MAE/DpC,sBAAuB,CACrBC,SAAU,KACVoC,iBAAkB,IAEpBC,aAAc9M,EAAQ8M,aACtBC,MAAO/M,EAAQ8M,aAAe9M,EAAQ+M,MAAQ,GAC9CC,iBAAkBhN,EAAQgN,qBAGP,MAAjBhN,EAAQmM,OAA2C,GAA1BnM,EAAQmM,MAAMnB,aAC3BmB,MAAQtB,QAGK,IAAlB7K,EAAQtH,UACHnL,KAAO8c,EAAc9c,KAAO,IAAMyS,EAAQtH,YAEnB,IAA5BsH,EAAQnE,oBACHtO,KAAO8c,EAAc9c,KAAO,IAAMyS,EAAQnE,sBAGb,IAAlCmE,EAAQwK,0BACHA,sBAAsBqC,iBAAmB7M,EAAQwK,sBAAsBqC,iBAChFne,EAAE0Z,QAAQpI,EAAQwK,sBAAsBC,aAChBzK,EAASqK,IAIpCrK,EAAQiN,aAAc,OAClBC,EAAQlN,EAAQiN,eACRA,aAAejN,EAAQiN,eACvB9B,IAAI5d,KAAO2f,IACX/B,IAAIoB,KAAOW,EAAM1N,UAAU,EAAG0N,EAAMhR,QAAQ,eAI9C+I,+BAAiC,GAExCoF,GAKP8C,8BA1I4Bvc,UACrBA,GA0IPwc,2BAAAA,MC5IJjhB,EAFE,qEAEiF,IAAI2D,WACrF,6BACA,CACE,SACA,sBACA,qBACA,SAAUC,EAAQsd,EAAqBC,SAC/BC,EAASD,EAAmBE,cAE3B/J,OAAO,qCAAqC,WAC5C1T,EAAOiQ,QAAQwC,UAAUiL,iBAAgE,WAA7C1d,EAAOiQ,QAAQwC,UAAUiL,mBAGjEC,YAAY,mBACZC,UAAU,sBACVC,aAAa,uBAJbC,YAAY,sBAQhBpK,OAAO,kCAAkC,SAAUqK,GACpDA,MACKH,UAAU,sBACVC,aAAa,2BCtB9BzhB,EAFE,gEAE4E,IAAI2D,WAAW,wBAAyB,CACpH,SACA,qBACA,SAAUC,EAAQud,KACGE,YAAYI,aAAa,mBACzBJ,YAAYG,UAAU,oBCL7CxhB,EAFE,mEAEiG,IAAI2D,WACrG,uCACA,CACE,SACA,qBACA,SAAUC,EAAQud,KACGE,YAAYI,aAAa,cAErCnK,OAAO,eAAe,SAAUqK,GACjCA,IACiBN,YAAYG,UAAU,cAEtBH,YAAYO,UAAU,kBCZnDrP,EACGvS,OAHD,mFAGgG,IAC/F6hB,UAAU,4CAA4C,iBAC9C,CACLC,SAAU,IACV1Y,YAAa,kGACb2Y,MAAO,GACPC,iBAAkB,CAChBnO,QAAS,KAEXiD,aAAc,MACdnT,WAAY,mDAGfA,WAAW,gDAAgD,gBACrDse,YAAc,WACXC,EAAe3P,EAAQoB,KAAKlK,KAAKoK,QAAQyM,gBAC1CzM,QAAQyM,UAAY4B,EAAalW,OAAO,CAC3C,CACEmW,IAAK,EACLC,YAAa,CACXC,mBAAoB,gBAEtBC,WAAY,EACZC,QAAS,OACTC,aAAc,iBAKfC,eAAkBlR,UACf2Q,EAAe3P,EAAQoB,KAAKlK,KAAKoK,QAAQyM,aAClC9O,OAAOD,EAAO,QACtBsC,QAAQyM,UAAY4B,66KChC/BliB,EAFE,mEAE6E,IAAI2F,OAAO,YAAY,kBAC7F,SAAU+c,EAAOC,UACfpgB,EAAEoD,OAAO+c,GAAO,SAAU1C,UACxBA,EAAMrf,SAAWgiB,GAAmC,OAAjB3C,EAAMrf,cCEtD4R,EACGvS,OAHD,sDAG8F,CAC5FyD,EACAC,EDVF,mECYEkf,IAEDjf,WAAW,oCAAqC,CAC/C,SACA,cACA,iBACA,SACA,cACA,SAAUC,EAAQqW,EAAa4I,EAAgBhf,EAAQif,KAC9CxL,OAAO,eAAe,SAAUqK,GACjCA,KACUH,UAAU,oBACVC,aAAa,qBAEbsB,eAAe,0BAI1BC,aAAgBhD,MACZnM,QAAQ+K,UAAYoB,EAAMpB,YAC1B/K,QAAQuL,cAAgBY,IACnBwB,UAAU,qBAGhByB,OACNxZ,KACAwQ,EAAY,qBAAsB,CAChCrW,OAAAA,EACAkf,YAAAA,EACAD,eAAAA,EACAhf,OAAAA,UAICqf,aAAe,CAClB5lB,KAAM,SAAUiP,UACE3I,EAAOiQ,QAAQwC,UAAU8M,kBAAoB,6BAA+B,kBAE7E7lB,KAAKiP,UAInB6W,cAAgB,CACnB9lB,KAAM,SAAUkP,UACE5I,EAAOiQ,QAAQwC,UAAU8M,kBACrC,8BACA,mBAEW7lB,KAAKkP,QC3D9BxM,EAFE,2EAE6E,IAC5E6hB,UAAU,oCAAoC,iBACtC,CACLC,SAAU,IACV1Y,YAAa,kFACb2Y,MAAO,GACPC,iBAAkB,CAChBnO,QAAS,KAEXiD,aAAc,MACdnT,WAAY,2CAGfA,WAAW,wCAAwC,goBCbtD3D,EAFE,iEAE6F,IAAI2D,WACjG,qCACA,CACE,SACA,SAAUC,QACqC,IAAlCA,EAAOiQ,QAAQkM,mBACjBlM,QAAQkM,eAAiB,SAG7BsD,qBAAuB,CAC1B,CAAEC,YAAa,MAAOliB,KAAM,MAC5B,CAAEkiB,YAAa,OAAQliB,KAAM,QAC7B,CAAEkiB,YAAa,MAAOliB,KAAM,aAGzB0O,wBAA0B,iBACqB,SAA3ClM,EAAOiQ,QAAQkM,eAAenS,eAGlC2V,0BAA4B,SAAUC,GACtB,MAAfA,KACK3P,QAAQkM,eAAenS,SAAW,OAClCiG,QAAQkM,eAAe0D,KAAO,OAC9B5P,QAAQkM,eAAe2D,YAAc,MAClCja,KAAKqG,8BACR+D,QAAQkM,eAAe2D,YAAc,UCzBtD1jB,EAFE,iFAEyF,IAAI6hB,UAC7F,yCACA,CACE,uCACA,iBACS,CACLC,SAAU,IACV1Y,YAAa,8FACb2Y,MAAO,CACLlO,QAAS,8kDCPnB7T,EAFE,iEAE2F,IAAI2D,WAC/F,oCACA,CACE,SACA,SAAUC,QACH+f,WAAa,WACqB,GAAjC/f,EAAOiQ,QAAQmM,MAAMnB,WAChBhL,QAAQmM,MAAQ,CAAEnB,UAAU,KAE5BhL,QAAQmM,MAAMrf,OAASiD,EAAOiQ,QAAQlT,UAIrC8gB,aAAa,oBAElBnK,OAAO,eAAe,SAAUqK,GACjCA,IACUH,UAAU,oBAEVI,UAAU,wBCrBhC5hB,EAFE,+EAE+E,IAAI6hB,UACnF,wCACA,CACE,uCACA,iBACS,CACLC,SAAU,IACV1Y,YAAa,oFACb2Y,MAAO,CACLlO,QAAS,k7CCLnB7T,EAFE,gEAE2F,CAC3FyS,IACC9O,WAAW,oCAAqC,CACjD,SACA,qBACA,SAAUC,EAAQgP,cAGS5B,EAAM3U,KAE1BwW,uBAAuB,QAASjP,EAAOiQ,QAAQjT,YAAagD,EAAOiQ,QAAQlT,OAAQqQ,GACnFzQ,MAAK,SAAUqjB,MACTA,GAAsB,IAAfA,EAAIjnB,WAoCLinB,GAAsB,IAAfA,EAAIjnB,OAAc,OAC5BknB,EAAuBD,EAAI,GAC3BE,EAAelgB,EAAOiQ,QAAQtD,eAC7BsD,QAAQtD,aAAe,OACvBsD,QAAQkQ,oBAAsB,KAC9BlQ,QAAQmQ,SAAW,KACZtT,eAAenQ,MAAK,SAAUoQ,GACtCA,EAAMhF,SACFA,MAAM/L,SAAS2Q,IAEjBA,EAAanM,UAAYR,EAAOiQ,QAAQjT,aACxC2P,EAAa5P,SAAWiD,EAAOiQ,QAAQlT,UAEhCkT,QAAQmQ,SAAS3hB,KAAKkO,GAG7BA,EAAanM,UAAYR,EAAOiQ,QAAQjT,aACxC2P,EAAa5P,SAAWiD,EAAOiQ,QAAQlT,SAC5B,iCAA+B4P,EAAanP,MAAQyiB,EAAqBpX,MACxE,wBAATpQ,GAAkCkU,EAAanP,OAAS0iB,EAAa1iB,UAEjEyS,QAAQtD,aAAeA,IACjBW,QAAQvP,KAAI,SAAU+K,OAC7ByE,GAAY,EACZzE,EAAO0E,WACFA,QAAQzP,KAAI,SAAU0P,GAEvBA,GAA0B,wBAAhBA,EAAOhV,UACP,MAId8U,KACK0C,QAAQkQ,oBAAoB1hB,KAAKqK,EAAOtL,qBArE/B,CAEPwC,EAAOiQ,QAAQtD,mBAC9B0T,EAAiBrgB,EAAOiQ,QAAQhD,iBAC/BgD,QAAQkQ,oBAAsB,KAC9BlQ,QAAQmQ,SAAW,KACZtT,eAAenQ,MAAK,SAAUoQ,GACtCA,EAAMhF,SACFA,MAAM/L,SAAS2Q,IAEjBA,EAAanM,UAAYR,EAAOiQ,QAAQjT,aACxC2P,EAAa5P,SAAWiD,EAAOiQ,QAAQlT,WAEhCkT,QAAQmQ,SAAS3hB,KAAKkO,KAEhBW,QAAQvP,KAAI,SAAU+K,OAC7ByE,GAAY,EACZzE,EAAO0E,WACFA,QAAQzP,KAAI,SAAU0P,GAEvBA,GAA0B,wBAAhBA,EAAOhV,UACP,MAId8U,MACK0C,QAAQkQ,oBAAoB1hB,KAAKqK,EAAOtL,MAC3CsL,EAAOtL,OAAS6iB,MACXpQ,QAAQhD,eAAiBoT,oBAlC1CzC,UAAU,kBAsFlB5d,EAAOiQ,QAAQjT,aAAegD,EAAOiQ,QAAQlT,WACxCkT,QAAQwC,UAAU6N,2BAA4B,IAC9CrQ,QAAQkQ,oBAAsB,GACG,OAApCngB,EAAOiQ,QAAQ9B,uBAAwE,IAApCnO,EAAOiQ,QAAQ9B,qBAC7DoS,iBAAkB,KAEXvgB,EAAOiQ,QAAQ9B,iBAAkBnO,EAAOiQ,QAAQjK,wBAG7Dwa,oBAAsB,SAAUpT,KAC5B6C,QAAQwC,UAAU6N,2BAA4B,IACzCzC,aAAa,wBAEnBtd,EAAgBP,EAAOiQ,QAAQwQ,YAAYlgB,kBAC7CyF,EAAmB,QAEnBzF,EAAe,OACXmgB,EAAqBngB,EAAcxG,MAAMC,GAAOA,EAAGwD,OAAS4P,IAC9DsT,MACiBzmB,EAAQ0mB,oBAAoBD,EAAmB1a,kBAAkBvN,MAI3E,OAAT2U,MACK6C,QAAQ9B,iBAAmB,QAG7B8B,QAAQkQ,oBAAsB,KAC9BlQ,QAAQjK,iBAAmBA,IACbgQ,WAAW,cAChB5I,EAAMpH,OC9H5B5J,EAFE,+DAEkG,IAAI6hB,UACtG,wCACA,CACE,uCACA,iBACS,CACLC,SAAU,IACVC,MAAO,CACLlO,QAAS,KAEXzK,YAAa,y0DCRrBpJ,EAFE,mEAE+F,IAAI2D,WACnG,sCACA,CACE,SACA,SAAUC,KACI4d,UAAU,sBAEf3N,QAAQtD,aAAe,CAC5BnP,KAAMwC,EAAOiQ,QAAQpH,QAGhBoH,QAAQhD,eAAiBjN,EAAOiQ,QAAQnH,YAE1C8X,YAAc,SAAUxT,KACpB6C,QAAQpH,KAAOuE,IACf6C,QAAQnH,OAAS9I,EAAOiQ,QAAQhD,eAAiB,OACjDgD,QAAQkQ,oBAAsB/S,EAAKE,QAAQvP,KAAKwR,GAAMA,EAAE/R,aAG5DqjB,uBAAyB,SAAUzT,KAC/B6C,QAAQpH,KAAO7I,EAAOiQ,QAAQtD,aAAanP,OAC3CyS,QAAQnH,OAASsE,IACZyQ,aAAa,0BAGtBiD,YAAc,kBACb9gB,EAAOiQ,QAAQtD,aACV3M,EAAOiQ,QAAQtD,aAAanP,KAE5B,uCC/BjBpB,EAFE,kEAEsG,IAAI6hB,UAC1G,2CACA,iBACS,CACLC,SAAU,IACVC,MAAO,CACLlO,QAAS,KAEXzK,YAAa,q2ECNnBpJ,EAFE,kEAE4F,IAAI2D,WAChG,qCACA,CACE,SACA,SAAUC,KACI4d,UAAU,qBACVC,aAAa,qBAElB5N,QAAQ8Q,sBAAwB,CACrC/f,GAAIhB,EAAOiQ,QAAQ0F,wBAGhBqL,qBAAuB,SAAUtL,KAC7BzF,QAAQ0F,kBAAoBD,EAAc1U,KACrC6c,aAAa,uBCdjCzhB,EAFE,wEAEmG,IAAI6hB,UACvG,yCACA,CACE,uCACA,SAAUgD,SACD,CACL/C,SAAU,IACVC,MAAO,CACLlO,QAAS,KAEXzK,YAAa,wGACb0b,KAAM,SAAU/C,KACR3H,cAAgB5G,EAAelT,IAAI,cAEnCwc,4BAA8B,kBAC3BC,EAAqBzc,IAAI,kBAAkB0c,WAAWC,UAGzDC,sBAAwB,aACtB6H,YAAa,IACkB7H,sBAAsB6E,EAAMlO,SAAStT,MAAK,aACvEwkB,YAAa,q5DCrBjC/kB,EAFE,8DAEqE,IACpE6hB,UAAU,qBAAqB,iBACvB,CACLC,SAAU,IACV1Y,YAAa,0EACb2Y,MAAO,GACPC,iBAAkB,CAChBnO,QAAS,KAEXiD,aAAc,mBACdnT,WAAY,uBAGfA,WAAW,mBAAoB,CAC9B,SACA,gBACOqhB,aAAe,kBACXnnB,EAAQonB,UAAUxb,KAAKoK,QAAQwM,srBCnB9CrgB,EAFE,uEAEsE,IAAI6hB,UAAU,qBAAqB,iBAClG,CACLC,SAAU,IACV1Y,YAAa,2EACb2Y,MAAO,GACPC,iBAAkB,CAChBnO,QAAS,KAEXiD,aAAc,KACdnT,WAAY,CACV,SACA,SAAUC,QACHshB,uBAAyB,KACxBthB,EAAOuhB,GAAGtR,QAAQ8M,iBACbwE,GAAGtR,QAAQgN,kBAAmB,yoCCKjD7gB,EAF8E,wCAEP,CdfrE,sDMFA,gEXJA,qECAA,gEcEA,kEbFA,mEMAA,iFEAA,+EDEA,iEFFA,iEKAA,+DNAA,2EUEA,wEjBFuD,0CIAvD,mFUEA,mECFA,kEIAA,uEDEA,gEGUFuS,EACGvS,OAHD,gDAGsE,CzCZhC,+ByCcpCyS,EACAD,EACAiK,ExCjBoD,yCwCoBrDxc,QAAQ,uCAAwC,CAC/C,KACA,mBACA,sBACA,mBACA,qBACA,2BACA,SACEc,EACAqkB,EACAzS,EACA+J,EACA9J,EACAyS,SAEMC,EAAgB,CAAC,eAAgB,kBAAmB,eACpDC,EAAuB,CAAC,OAAQ,WAAY,aAE5CC,EAAmB,CAAC,MAAO,OAC3BC,EAAsB,CAC1B,iBACA,iBACA,4BACA,4BACA,sBA+B8B5R,SACxB/J,EAAS,CACb4b,MAAO,OAEL7R,EAAQlT,OAAQ,OACZH,EAAU,CAACsJ,EAAO4b,SAGhBrjB,cAS4BwR,SAChC8R,EAAI9R,EACJ/J,EAAS,CACb4b,MAAO,IAGHE,EAAY,CAACD,EAAEhlB,SACfklB,0BAAEA,GAA8BF,EAAEtB,aAClChhB,2BAAEA,GAA+BwiB,EAA0BF,EAAE/kB,gBAE/DglB,EAAUE,OAAOC,IAAOA,WACnBjc,QAGHgJ,EAAWuS,EACdjiB,4BAA4BC,EAA4BuiB,GACxDjkB,KAAKtF,GAASA,EAAK+E,OAEhB0f,EAAe6E,EAAE7E,aACnBve,EAAEujB,MAAM,CAAChF,GAAeve,EAAEyjB,WAAWlF,EAAc,WAAYve,EAAE6D,SAAS0M,EAAUgO,SAC/E4E,MAAM5E,aAAe6E,EAAE7E,eAC5BA,aAAe,eAEjBuD,YAAYvR,SAAS3R,cAAgB2R,EAChChJ,EAjCQmc,CAA+BpS,GAAS6R,SAE7CzC,UAAUziB,UAEV6jB,YAAYvR,SAAS3R,cAAgB,UAExC2I,aAiEe+J,SAChB/J,EAAS,CAAE4b,MAAO,IAClBQ,EAAerS,EAAQwQ,YAAYvR,aACpCe,EAAQlT,cACJmJ,MAELqc,oBAAEA,oBAAqBC,GAAsBvS,EAAQwQ,YAAYwB,0BACnEhS,EAAQjT,sBAEYulB,GAAuB,KACzBC,GAAqB,KAC5BxF,MAAQuF,EAAoB/f,SAASyN,EAAQlT,QAAUylB,EAAoB,GAEjFtc,aAG0B+J,SAC3BwS,EAAoBxS,EAAQwQ,YAAYvX,eAAe+G,EAAQjT,cAAgB,CACnF+K,MAAO,WAEFpJ,EAAE2J,MAAMma,EAAkBxS,EAAQlT,SAASuS,OAAO,QAAQ9G,mBAG5ByH,SAC/B/J,EAAS,CACb4b,MAAO,QAELY,EACAzS,EAAQwQ,YAAYvR,SAAShG,mBACd+G,EAAQwQ,YAAYvR,SAAShG,sBAE1CyZ,EAA4BC,EAA0B3S,UACxDA,EAAQ8Q,0BAGFA,sBAAwB,OACzBe,MAAM5Y,gBAAiB,GAE5BwZ,GAAkBC,MACZlC,YAAYvR,SAAShG,eAAiByZ,IACvCb,MAAM5Y,gBAAiB,GAG5B+G,EAAQwQ,YAAYvR,SAAShG,iBAAmB,KAC1CuJ,UAAUoQ,0BAA2B,IAErCpQ,UAAUoQ,0BAA2B,EAGxC3c,aAcqB3F,UACrB5B,EAAE2J,MAAM/H,GAAexC,IAAI,QAAQ+kB,OAAOta,QAAQua,kBAGrB9S,SAC9B/J,EAAS,CACb4b,MAAO,IAEHkB,EAAU/S,EAAQ1P,cAClB0iB,EAAmBC,EAAqBjT,EAAQwQ,YAAYlgB,kBAE9DyiB,GAAW/S,EAAQ1P,cAAe,OAC9B4iB,EAAUxkB,EAAEykB,aAAaH,EAAkBhT,EAAQ1P,eACnD8iB,EAAU1kB,EAAE2kB,IAAIH,EAASH,KACvBziB,cAAgB4iB,EACpBE,EAAQtqB,WACH+oB,MAAMvhB,cAAgB8iB,YAGzB5C,YAAYvR,SAAS3O,cAAgB0iB,EACtC/c,aAYuB+J,SAIxB4G,EAAO5G,EAAQwQ,YAAYlgB,cAC3BgjB,EAAa5kB,EAAEoD,OAAO8U,GAAM,SAAU7c,UACnCA,EAAGwG,UAAYyP,EAAQjT,aAAehD,EAAG+C,SAAWkT,EAAQlT,mBAG7DwD,cAAgB2iB,EAAqBK,KACrC9Q,UAAU+Q,yBAA0B,EAT7B,CACb1B,MAAO,UAuFJ,CACL2B,gCApS8BxT,KACtBwQ,YAAc,CACpBmB,iBAAkBjT,EAAQoB,KAAK6R,GAC/BC,oBAAqBlT,EAAQoB,KAAK8R,KAkSpC6B,0BA9RwBhgB,EAAauM,UAC9B9S,EACJ0H,IAAI,CACH8e,EAAeC,6BAA6B,SAC5C7U,EAAoB8U,qBACpB7U,EAAmB8U,kBAAkBpgB,EAAYlG,QAElDb,MAAK,UAAWslB,EAA2B/Y,EAAgB3I,QA2MnCwjB,IA1MftD,YAAc,CACpBwB,0BAAAA,EACA/Y,eAAAA,EACA3I,cAAAA,EACAmhB,cAAe/S,EAAQoB,KAAK2R,GAC5BC,qBAAsBhT,EAAQoB,KAAK4R,GACnC3V,SAAUrN,EAAE1F,KAAKgpB,GACjB/S,SAAU,KAmMW6U,EAjMH9T,GAkMpB+T,cAAgB,SAAuB/T,EAASgU,GAAS,SACrD/d,EAAS,CACb4b,MAAO,WAEL7R,EAAQlT,QAAUkT,EAAQjT,gBACpBqiB,OAAOnZ,EAAO4b,MAAOoC,EAAuBjU,GAAS6R,SACrDzC,OAAOnZ,EAAO4b,MAAOqC,EAA8BlU,GAAS6R,SAC5DzC,OAAOnZ,EAAO4b,MAAOsC,EAAuBnU,GAAS6R,SACrDzC,OAAOnZ,EAAO4b,MAAOuC,EAAepU,GAAS6R,QAGlDmC,MACK9V,iBAAmB,OACnBnI,iBAAmB,OACnB6C,KAAO,OACP+D,kBAAoB,OACpB9D,OAAS,OACTmE,eAAiB,OACjBN,aAAe,OACfwT,oBAAsB,KACtB1N,UAAU6N,2BAA4B,IACtCS,sBAAwB,OACxBpL,kBAAoB,OACpBoH,cAAe,IACfC,MAAQ,IAGX9W,KAGLoe,mBAAqB,SAA4BrU,EAASgU,SACtD/d,EAAS,CACb4b,MAAO,IAEHrB,EAAcxQ,EAAQwQ,eACxBxQ,EAAQjT,YAAa,OACjBunB,EAAoB9D,EAAYwB,0BAA0BhS,EAAQjT,cAAgB,CACtF+N,QAAS,GACTyZ,eAAgB,QAENtV,SAASnE,QAAUwZ,EAAkBxZ,QAE9CpM,EAAE2J,MAAMmY,EAAYvR,SAASnE,SAC3BnK,KAAK,CACJpD,KAAMyS,EAAQlT,SAEfyL,UAKK6W,OAAOnZ,EAAO4b,MAAO7R,EAAQ+T,cAAc/T,EAASgU,GAAQnC,UAH5D/kB,OAAS,OACV+kB,MAAM/kB,QAAS,GAIpBkT,EAAQlT,UACFsiB,OAAOnZ,EAAO4b,MAAOoC,EAAuBjU,GAAS6R,SAEvDzC,OAAOnZ,EAAO4b,MAAOsC,EAAuBnU,GAAS6R,cAErD/kB,OAAS,YAEZmJ,OAgBTue,yBA9NuBxU,SACjB/J,EAAS,CACb4b,MAAO,QAEL4C,EAAiB,YACjBzU,EAAQwC,UAAUkS,wBAGlB1U,EAAQlT,UACOkT,EAAQwQ,YAAYmE,cAClC7iB,QAAO,SAAUqa,UACTA,EAAMyI,MAAQzI,EAAMyI,KAAK5U,EAAQlT,WAEzCgB,KAAI,SAAUqe,SACN,CACLpB,UAAWoB,EAAMpB,UACjB8J,IAAK1I,EAAMyI,KAAOzI,EAAMyI,KAAK5U,EAAQlT,QAAQ,GAAK,SAItDkT,EAAQnT,UACP4nB,EAAe9jB,MAAK,SAAUwb,UACtBA,EAAMpB,YAAc/K,EAAQnT,eAG9BglB,MAAMhlB,SAAU,IACfA,QAAU,SAGZA,QAAU,OAEZ2jB,YAAYvR,SAAS6V,OAASL,GAzB7Bxe,GAyNTie,8BAAAA,EACAa,6BAAAA,EACAC,8BAxG4BhV,EAASiV,UAC9BlW,EAAmBmW,kBAAkB,SAASxoB,MAAK,SAAU4D,KAC1DkgB,YAAYlgB,cAAgBA,EAC/B2kB,KAC0BjV,OAqGjCqJ,+BA3I6BrJ,EAASiV,UAC/BpM,EAAiBS,aAAa,kBAAkB5c,MAAK,kBACnDoS,EAAoByK,uBAAuB7c,MAAK,SAAUuM,KACvDuX,YAAYvX,eAAiBA,EAChCgc,KAC2BjV,UAuIpC2S,0BAAAA,EACAwC,8BAlB4BnV,UACrB6I,EAAiBS,aAAa,iBAAiB5c,MAAK,kBAClD8kB,EAAyB7hB,sBAAsBjD,MAAK,SAAUY,KAC3DkjB,YAAYljB,cAAgBA,IACb0S,UAe3BoU,eAAAA,MCnVRjoB,EAFE,8CAE2E,CAC3EyD,EDAA,gDrBVuD,0CsBavDwlB,IACCtlB,WAAW,4BAA6B,CACzC,SACA,oBACA,KACA,SACA,oBACA,uCACA,qBACA,cACA,QACA,SACEC,EACAqK,EACAlN,EACA8C,EACAqlB,EACArE,EACAsE,EACA7hB,EACAC,mBAwDM3D,EAAO+E,yBAGLygB,EAAaxlB,EAAOyD,YAAYgiB,KAAKC,UAAUC,OAAO5rB,MAAMyW,GAAyB,qBAAfA,EAAM/X,UAC9E+sB,GAAcA,EAAW/U,QAAQ,wBAAyB,OACtDmV,EAAqBJ,EAAW/U,QAAQ,wBAAwBzQ,EAAOiQ,QAAQlT,WACjF6oB,EAAoB,OAChBpb,EAAiB,CACrB3J,YAAa+kB,EACbnb,UAAWzK,EAAOiQ,QAAQjT,YAC1BD,OAAQiD,EAAOiQ,QAAQlT,OACvBG,SAAU,aAER2oB,EAAe,6BACf5lB,EAAOuC,SAAS,+BAEH,iBAEbvC,EAAOuC,SAAS,uCAEH,mBAEbvC,EAAOuC,SAAS,mBAEH,kBAEVI,GAAGijB,EAAcrb,oBAkBSkZ,iBAAiBhgB,EAAa6hB,GAAoB5oB,MAAK,iBACpFoe,EAAOwK,EAAmB9S,UAAUsI,KAC7B,UAATA,GAA6B,WAATA,MACHtI,UAAUqT,sBAAuB,KAE/CtkB,MAAMukB,QAAS,mBAQlBhL,EAAOwK,EAAmB9S,UAAUsI,KAC7B,UAATA,GAA6B,iBAATA,MACV8C,aAAa,oBACbA,aAAa,oBACbA,aAAa,sBACbA,aAAa,qBACbA,aAAa,mBACbA,aAAa,eAUA7d,EAAOiQ,QAAQqU,mBAAmBtkB,EAAOiQ,SAAS,MAClDjQ,EAAOiQ,QAAQ+T,cAAchkB,EAAOiQ,SAAS,MANjEyD,OAAO,sBAAuBsS,EAAsBhmB,EAAOiQ,QAAQqU,uBACnE5Q,OAAO,iBAAkBsS,EAAsBhmB,EAAOiQ,QAAQ+T,8BAQxCiC,UACtB,SAAUC,EAAUC,GACrBD,IAAaC,KACYF,EAAOjmB,EAAOiQ,sBAKX/J,GAC9BA,EAAO4b,MAAMvhB,kBACHyd,UAAU,oBACVA,UAAU,qBAEpB9X,EAAO4b,MAAM5Y,kBACH8U,UAAU,mBAEpB9X,EAAO4b,MAAM5E,gBACHc,UAAU,kBAEpB9X,EAAO4b,MAAMsE,aAAelgB,EAAO4b,MAAM9E,UAC/BgB,UAAU,WAxJnBhT,MAAQ,CACbqb,kBAAmB,gEACnBC,cAAe,0EACfC,cAAe,kEACfpK,eAAgB,4EAChB5b,cAAe,0EACfimB,gBAAiB,8EACjBtd,eAAgB,2EAChBgU,aAAc,wEACdF,MAAO,6DACPyJ,KAAM,wDACNtb,iBAAkB,mFAGbwE,eAAiBC,EAAelT,IAAI,eAEpCiH,MAAQA,IAER+iB,gBAAkBhjB,EAAYlG,OAC9BkG,YAAcA,IACduM,QAAUsV,IAIVtV,QAAQwQ,YAAczgB,EAAOiQ,QAAQwQ,aAAe,KACpDxQ,QAAQwQ,YAAYvR,SAAWlP,EAAOiQ,QAAQwQ,YAAYvR,UAAY,KACtEe,QAAQwQ,YAAYvR,SAASnE,QAAU/K,EAAOiQ,QAAQwQ,YAAYvR,SAASnE,SAAW,KAEtFvJ,MAAQ,CACbukB,QAAQ,EACRY,4BAA6BpB,EAAmB9S,UAAUkU,gCAGvDC,sBAAwB,CAC3BC,OAAQ,CACN,yDACA,iBACAjX,EAAelT,IAAI,aACnB,gBACA,4CAEFoqB,UAAW,GACXC,mBACE,yIAGC/mB,EAAOiQ,QAAQwC,UAAUuU,+BACvBJ,sBAAsBE,UAAUroB,KACnC,kFA0CGgF,YAAc,IAAI8H,EAAY,CACnC7H,YAAAA,EACAC,MAAO,6BACP6H,cAAenB,EACfzG,4BARYlD,aAAakK,YACblK,aAAa+K,cAAczL,EAAQ0L,WAqE5CoC,OAAS,cAC0B,iBAAlC9N,EAAOiQ,QAAQwC,UAAUsI,MAA6D,mBAAlC/a,EAAOiQ,QAAQwC,UAAUsI,YACxE1Q,EAAkBhF,MAAMrF,EAAOiQ,WAEjCxM,YAAYqK,QAAO,kBACjBwX,EAAkB2B,iBAAiBjnB,EAAOiQ,QAASvM,YAIzDgL,OAAS,aACM5H,gBAGfogB,uBAAyB,SAAUC,KAC/BlX,QAAQmX,mBAAqBpnB,EAAOiQ,QAAQmX,oBAAsB,SACnEC,EAAernB,EAAOiQ,QAAQmX,mBAAmBjb,QAAQgb,QAC3DE,IACKpX,QAAQmX,mBAAmB3oB,KAAK0oB,KAEhClX,QAAQmX,mBAAmBxZ,OAAOyZ,EAAc,SAItDC,mBAAqB,SAAUH,UAC3BnnB,EAAOiQ,QAAQmX,mBAAmB5kB,SAAS2kB,IAG/CnnB,EAAOwB,MAAMmlB,4BAGTnlB,MAAMukB,QAAS,WAGnBwB,iBAAmB,OACf/lB,MAAMmlB,2BAA4B,YAItC/tB,QAAU,kBAEXoH,EAAOiQ,SACPjQ,EAAOiQ,QAAQvM,aACf1D,EAAOiQ,QAAQjT,aACfgD,EAAOiQ,QAAQiN,cACfld,EAAOiQ,QAAQlT,UACbiD,EAAOiQ,QAAQ8M,cAAgD,IAAhC/c,EAAOiQ,QAAQ+M,MAAMjkB,SACtDkB,EAAQonB,UAAUrhB,EAAOiQ,QAAQwM,cAAc7jB,0vRCtOvD+V,EACGvS,OAHD,oDAGuE,C3CPjC,+BoBDiB,4CuBYtDC,QAAQ,iCAAkC,CACzC,KACA,mBACA,8BACA,SAAUc,EAAIqkB,EAAkBgG,cACM9jB,EAAavB,SAGzCkH,KAFKlH,GAAY,IAEa3B,SAAWkD,EAAY2F,mBAAmBtB,MACxE0f,EAAgBtlB,EAASpF,QAAU2G,EAAY4F,eAAevB,aAE7DyZ,EAAiBllB,WAAW,CAAEY,SAAU,UAAWP,MAAK,SAAUooB,SAChE,CACLrhB,YAAaA,EAAYlG,KACzBR,YAAaqM,EACbtM,OAAQ0qB,EACR1C,OAAAA,EACAxkB,cAAe,GACf4f,oBAAqB,GACrBzE,SAAU,GACVN,IAAK,CACHkB,SAAU,GAEZS,cAAc,EACdC,MAAO,GACPP,aAAc,GACdC,UAAW,GACXjB,iBAAkB,QAClBhJ,UAAW,CACTiL,gBAAiB,SACjBgK,kBAAmB,KACnB5B,sBAAsB,EACtB6B,mBAAmB,EACnBC,mBAAmB,EACnB7M,KAAM5Y,EAAS4Y,MAAQ,SACvBiM,0BAA0B,EAC1BxD,yBAAyB,EACzBlD,2BAA2B,EAC3BuC,0BAA0B,GAE5B5F,kBAAkB,YA8GjB,CACL4K,2BAAAA,EACAC,wDAzGO3qB,EAAGmC,KAAK,CACbmT,UAAW,CACTkU,2BAA2B,MAwG/BoB,6CAnG2CrkB,EAAa7C,EAAaka,KAC9DA,GAAQ,cAETiN,EAAkBpc,EAAUqc,qBAAqBpnB,EAAYrD,MAE7DyS,EAAU,CACdvM,YAAaA,EAAYlG,KACzBke,SAAU,GACV/S,MAAOqf,EAAgBrf,MACvBmD,gBAAiBkc,EAAgBlc,gBACjC9O,YAAa6D,EAAYL,QACzBD,cAAeM,EAAYN,cAC3B2M,gBAAiBrM,EAAYsf,oBAC7BxT,aAAc9L,EAAY8L,aAC1BzD,eAAgBrI,EAAYqI,eAC5BiF,iBAAkBtN,EAAYsN,iBAC9BnI,iBAAkBnF,EAAYmF,iBAC9B2P,kBAAmB9U,EAAY8U,kBAC/B5Y,OAAQ8D,EAAY9D,OACpB8L,KAAMhI,EAAYgI,KAClB+D,kBAAmB/L,EAAY+L,kBAC/B9D,OAAQjI,EAAYiI,OACpBkU,MAAOnc,EAAYmc,MACnBD,aAAclc,EAAYmc,OAASnc,EAAYmc,MAAMjkB,OAAS,EAC9D0jB,aAAc,GACdC,UAAW7b,EAAY6b,UACvBtB,IAAKva,EAAYua,IACjBkB,SAAU,CACRje,IAAKwC,EAAYyb,SAASje,IAC1BG,IAAKqC,EAAYyb,SAAS9d,IAC1B0pB,QAASrnB,EAAYyb,SAAS4L,SAEhCzB,KAAM,GACNvJ,aAAcrc,EAAYua,IAAI5d,KAC9Bie,iBAAkB,QAClB0M,OAAQ,CACN3nB,QAASK,EAAYL,QACrBzD,OAAQ8D,EAAY9D,OACpBirB,gBAAiBnnB,EAAYrD,KAC7B4qB,QAASvnB,EAAYrD,MAEvBiV,UAAW,CACTiV,kBAAmB,KACnB5B,sBAAsB,EACtB6B,mBAAmB,EACnBC,mBAAmB,EACnBS,4BAA4B,EAC5BtN,KAAAA,EACAiM,0BAA0B,GAE5B/J,iBAAkBpc,EAAYoc,8BAGiB,IAAtCpc,EAAY4Z,0BACbA,sBAAwB,KACxBA,sBAAsBqC,iBAAmBjc,EAAY4Z,sBAAsBqC,iBAC9Ene,EAAE0Z,QAAQxX,EAAY4Z,sBAAsBC,aACnB2C,2BAA2Bxc,EAAaoP,IAIjE9S,EAAGmC,KAAK2Q,IAuCfqY,6CApC2C5kB,EAAa6kB,SAClDC,EAAkB7pB,EAAE8pB,UAAUF,GAC9BxrB,EAASyrB,EAAgBzrB,cAGxB8qB,EAA2BnkB,EADX,CAAElD,QAASgoB,EAAgBhoB,QAASzD,OAAAA,IACIJ,MAAK,SAAUsT,SACtEwC,EAAY,CAChBkS,uBAAuB,EACvBgD,mBAAmB,EACnB5M,KAAM,eACN2N,kBAAmB,OACnBhL,gBAAiB6K,EAAgB9V,UAAUiL,gBAC3CiL,oBAAqBJ,EAAgB9V,UAAUkW,qBAG3CC,EAAgB,CACpB7rB,OAAAA,EACAC,YAAawrB,EAAgBhoB,QAC7BiS,UAAAA,GAEE8V,EAAgB9V,UAAUkW,wBACdzL,aAAeqL,EAAgB9V,UAAUkW,oBAAoBnrB,QAG7Dke,SAAW8M,EAAgB9M,UAAY,UAE/B/M,EAAQ0Q,OAAO,GAAIpP,EAASuY,EAAiBI,4BClJzC3jB,EAAMC,UAC1CC,YAAYC,SACJA,cAGO,CAAEyjB,UAAU,2BAEGA,SACvBjiB,SAAS,CAAEiiB,SAAAA,KAGX1jB,eACC2jB,SAAEA,WAAUC,UAAUnwB,UAAS4H,GAAYqF,KAAKT,OAChDyjB,SAAEA,GAAahjB,KAAKrE,6BAGvB,MAAD,CAAKkF,UAAU,gCACXsiB,EAAD,CAAkBC,cAAezoB,EAAS0oB,cAAerjB,KAAKsjB,qCAC9D,SAAD,CAAQziB,UAAU,kBAAkBS,QAAS4hB,GAAU,0BAGtD,SAAD,CAAQtwB,KAAK,SAASiO,UAAU,kBAAkBS,QAAS2hB,EAAUM,UAAWxwB,IAAYiwB,GAAU,YCPvG,uBAA4C5jB,EAAMC,UAcvDC,YAAYC,SACJA,cAsBSikB,SACVjkB,MAAMiB,aAAaijB,MAAM,KAAMD,gBAGrB,WACTpZ,QAAEA,cAASxM,GAAgBoC,KAAKrE,OAChCX,YAAEA,cAAa6C,GAAgBmC,KAAKT,QAE9B0I,QAAO,IACVyb,EAAcjE,kBAAkBkE,oBAAoB3oB,EAAa6C,EAAauM,8BAI3DwZ,GACSA,EAClC1nB,QAAQ2nB,GAA0E,IAA7CA,EAAoBC,eAAeC,QACxE7G,MAAK,CAACpM,EAAQC,IAAWA,EAAEpZ,KAAKqsB,cAAclT,EAAEnZ,qBAKnC,SAEkB,IADHqI,KAAKrE,MAAMyO,QAAQ6Z,gBAAgBC,oDAIjCC,UAC3BP,qBAAEA,GAAyB5jB,KAAKT,MAChC6kB,EAAa,IAAKpkB,KAAKrE,MAAMyO,WACxB6Z,gBAAgBC,uBAAyBC,EAAyBxhB,YACvE0hB,EAAqBrkB,KAAKskB,mBAAmBV,GAAsB1vB,MAAK,SAAU2vB,UAC/EA,EAAoBlsB,OAASwsB,EAAyBxhB,WAEpD4hB,WAAaF,EAAmB5N,SAAS9d,SAC/CoI,SAAS,CACZqJ,QAASga,iCAIqBI,UAC1BJ,EAAa,IAAKpkB,KAAKrE,MAAMyO,WACxB7J,OAASikB,OACfzjB,SAAS,CACZqJ,QAASga,WA/DLvmB,YAAEA,cAAa7C,GAAgBuE,OAEhC5D,MAAQ,CACXiC,YAAa,IAAI8H,EAAY,CAC3B7H,YAAAA,EACAC,MAAO,iCACP6H,cAAeD,EAAY+e,wBAAuB,IAAMzkB,KAAKT,MAAMiB,mBAErEiF,YAAY,EACZ2E,QAAS,CACPiF,+BAAgC,GAChCqV,aAAc,WACdT,gBAAiB,CACfU,wBAAyB3pB,EAAYrD,KACrCitB,sBAAsB,iBAtBXrlB,UAEVmB,EAAWC,KAAKkkB,GAA+BtlB,EADnC,IA0EdD,eACC8K,QAAEA,cAASxM,aAAa6H,GAAezF,KAAKrE,OAC5CX,YAAEA,uBAAa4oB,GAAyB5jB,KAAKT,MAC7CulB,EAAY9kB,KAAKjN,UACjBgyB,EAA6B/kB,KAAKskB,mBAAmBV,GAAsB1rB,KAC9E2rB,KACCrsB,MAAOqsB,EAAoBlsB,KAC3BgL,MAAOkhB,EAAoBlsB,gCAK5BuJ,EAAD,CAAO8jB,OAAQhlB,KAAKR,uBACjBylB,EAAD,CAAoBC,QAAStnB,IAC5B6H,mBACE,OAAD,CAAM0f,KAAK,wBACRnkB,EAAD,CAAYC,QAASjB,KAAKR,wBACzB0B,EAAMC,OAAP,qBACGD,EAAME,MAAP,KAAa,YAAUpG,EAAYrD,uBAEpCuJ,EAAMG,KAAP,qBACG,MAAD,CAAKR,UAAU,uBACZ,MAAD,CAAKA,UAAU,2BAA0B,8BACxC,MAAD,CAAKA,UAAU,4BACZukB,EAAD,CACEziB,MAAOyH,EAAQ6Z,gBAAgBC,uBAC/BmB,SAAUrlB,KAAKslB,wBACfC,QAASR,sBAIdS,EAAD,CAAYjlB,OAAQ6J,EAAQoa,WAAYa,SAAUrlB,KAAKylB,0CAExDC,GAAD,CACEzC,SAAUjjB,KAAKiI,OACfib,SAAUljB,KAAKR,MACfzM,QAAS+xB,EACTnqB,QAASK,EAAYL,wBAzH5BgrB,GAIS/jB,aAA6D,CACzEC,WAAYC,EACZtB,aAAcsB,GCdlBgH,EACGvS,OAHD,iDAGuE,CACrEyD,EHbF,oDGeEwlB,IAEDtlB,WAAW,8BAA+B,CACzC,SACA,SACA,iBACA,MACA,cACA,iCACA,YACA,oBACA,SACEC,EACAC,EACAwrB,EACArrB,EACAS,EACA6qB,EACAxrB,EACAolB,sBAqCQqG,iBA1BFA,EAAUhtB,EAAE5E,KAAKqG,EAAIM,aAAaC,MAAM,SAAUirB,UAElDA,EAAQpuB,OAASqD,EAAYrD,MAC7BouB,EAAQprB,UAAYK,EAAY4J,WAChCmhB,EAAQ7uB,SAAW8D,EAAY9D,iBAG9B4uB,KACCprB,cAAcI,KAAKC,MAAK,SAAUM,MAChCA,EAAaV,UAAYK,EAAY4J,WAAavJ,EAAanE,SAAW8D,EAAY9D,cACjFmE,EAAaR,aAAaE,MAAK,SAAUirB,MAC1CA,EAAoBruB,OAASqD,EAAYrD,cACjCquB,GACH,QAMZF,KACI/oB,GAAG,KAEL+oB,EAISG,UACTC,EAAkBC,eACvB5rB,EAAI5C,KACJqD,EAAY4J,UACZ5J,EAAY9D,OACZ8D,EAAYrD,MACZb,MAAK,SAAU4E,QA+CVC,MAAMC,SAAU,IA5Cb4d,OAAO9d,EAASoqB,KAChBnrB,QAAUK,EAAY4J,YAEvB5J,YAAcU,EAEhB5C,EAAE0Z,QAAQrY,EAAOa,eAiCb+B,GAAG,SAjCwB,MAC3BwZ,MAAQ7a,EAAQ6a,MAAQ7a,EAAQ6a,WAAQ,EAE3C7a,EAAQ6a,OAAS7a,EAAQ6a,MAAM1jB,YAAa,CACjC6I,EAAQ6a,MAAM1jB,YAAYmB,MAAM,MACxCmC,SAAQ,SAAUiwB,SACfC,EAASD,EAAIpyB,MAAM,KACH,IAAlBqyB,EAAOnzB,QAA8B,kBAAdmzB,EAAO,OACxB9P,MAAM+P,UAAYD,EAAO,OAKnC3qB,EAAQ6qB,cAAgB7qB,EAAQ6qB,aAAaljB,mBACxCA,eAAiBvK,EAAE2J,MAAM/G,EAAQ6qB,aAAaljB,gBAClDnL,KAAI,SAAUiD,UAEXrC,EAAE5E,KAAKqG,EAAI8I,eAAevI,KAAM,CAC9B8V,YAAa5V,EAAY4J,UACzB1N,OAAQ8D,EAAY9D,OACpBiE,GAAAA,KAEFrC,EAAE5E,KAAKqG,EAAI8I,eAAevI,KAAM,CAC9B8V,YAAa5V,EAAY4J,UACzB1N,OAAQ8D,EAAY9D,OACpBS,KAAMwD,OAIXqrB,UACA7jB,eA/EJhH,MAAQ,CACbC,SAAS,KAGJkO,eAAiBC,EAAelT,IAAI,kBAEtCgH,YAActD,MAqFGzD,MAAK,KAGpBqD,EAAO+E,eACNrE,aAAasE,UAAUhF,EAAQssB,WAIlCC,mBAAqB,iBAClBC,EAAcxsB,EAAOa,YAErB4rB,EAAc,CAClBjvB,KAAMgvB,EAAYhvB,KAClBiN,UAAW+hB,EAAYhsB,QACvBzD,OAAQyvB,EAAYzvB,QAGhB0G,EAAc,CAClBC,YAAatD,EACbuD,MAAO,cAAgB6oB,EAAYhvB,KACnCoG,eAAgB,WACV3D,EAAOuC,SAAS,iBAAkBiqB,MAC7B7pB,GAAG,OASV8pB,EAA0B,CAC9B5oB,OAAQ,kBAAoB0oB,EAAYhvB,KAAO,IAC/CuG,WAAY,WAAayoB,EAAYhvB,KACrCgD,QAASgsB,EAAYhsB,QACrBwD,kBAAmBP,EACnBQ,aATmB,kBACZqhB,EAAkBiH,mBAAmBC,EAAapsB,OAW1BusB,yBAAyBvsB,EAAKosB,EAAaE,KAEnD7oB,QAAQ6oB,SAG9BE,mBAAqB,iBAClBJ,EAAcxsB,EAAOa,YAErB4C,EAAc,CAClBC,YAAatD,EACbuD,MAAO,aAAe6oB,EAAYhvB,MAK9BkvB,EAA0B,CAC9B5oB,OAAQ,kBAAoB0oB,EAAYhvB,KAAO,IAC/CuG,WAAY,WAAayoB,EAAYhvB,KACrCgD,QAASgsB,EAAYhsB,QACrBwD,kBAAmBP,EACnBQ,aAPmB,IAAMqhB,EAAkBsH,mBAAmBJ,EAAapsB,MAU5CysB,yBAAyBzsB,EAAKosB,EAAaE,KAEnD7oB,QAAQ6oB,SAG9BI,kBAAoB,iBACjBN,EAAcxsB,EAAOa,YAErB4C,EAAc,CAClBC,YAAatD,EACbuD,MAAO,YAAc6oB,EAAYhvB,QAaVqG,QAAQ,CAC/BC,OAAQ,iBAAmB0oB,EAAYhvB,KAAO,IAC9CuG,WAAY,UAAYyoB,EAAYhvB,KACpCgD,QAASgsB,EAAYhsB,QACrBwD,kBAAmBP,EACnBQ,aAfoB1H,GACb+oB,EAAkBwH,kBACvBN,EACApsB,EACAuO,EAAQ0Q,OAAO9iB,EAAQ,CACrB2Y,+BAAgC,cAcnCsU,oBAAsB,WACnBgD,EAAcxsB,EAAOa,YACrBksB,EAAUpuB,EAAE5E,KAAKqG,EAAI4sB,SAAU,CAAExvB,KAAMgvB,EAAYO,QAASvsB,QAASgsB,EAAYhsB,UACjFipB,EAAuB9qB,EAAEoD,OAAOgrB,EAAQrsB,aAAc,CAAES,YAAY,EAAMpE,OAAQyvB,EAAYzvB,YACtEyJ,KAAK,CAAE9C,YAAatD,EAAKS,cAAa4oB,qBAAAA,UAGjExC,iBAAoBuF,MACbjnB,KAAK,CACbC,YAAa,gEACbzF,WAAY,oCACZlC,KAAM,KACN+H,QAAS,CACPjC,MAAO,IAAM,SAAW6oB,EAAYhvB,KACpCkG,YAAa,IAAMtD,EACnBmlB,mBAAoB,IAClBmG,EAA+B3D,oCAAoC3nB,EAAKosB,YAK3ES,mBAAqB,kBACpBjtB,EAAOa,aAAeb,EAAOa,YAAYqsB,WAAaltB,EAAOa,YAAYqsB,UAAUC,OAC9EntB,EAAOa,YAAYqsB,UAAUC,OAAO1d,UAAU,EAAG,GAEnD,ynGCxPfrT,EAFoE,4CAEP,CDW3D,mDEXFA,EAF0D,6CAEP,IAChDC,QAAQ,iCAAiC,iBAyBjC,CACL+wB,kBAfgBhf,SAEVif,EAAS,UAEXjf,GAAQA,EAAKrV,iBAdgBqV,EAAMif,GACvB,4BACH3zB,KAAK0U,MACT3P,KACL,8HAWwB2P,EAAMif,GAG3B,CACLC,SARe,GASfD,OAAAA,QAQLE,IAAI,CACH,gCACA,SAAUC,KACiBC,kBAAkB,QAASD,OCzC1D,SAAqBE,EAAKC,QACX,IAARA,IAAiBA,EAAM,IAC5B,IAAIC,EAAWD,EAAIC,SAEnB,GAAKF,GAA2B,oBAAbG,SAAnB,CAEA,IAAIC,EAAOD,SAASC,MAAQD,SAASE,qBAAqB,QAAQ,GAC9DC,EAAQH,SAASI,cAAc,SACnCD,EAAMv1B,KAAO,WAEI,QAAbm1B,GACEE,EAAKI,WACPJ,EAAKK,aAAaH,EAAOF,EAAKI,YAKhCJ,EAAKM,YAAYJ,GAGfA,EAAMK,WACRL,EAAMK,WAAWC,QAAUZ,EAE3BM,EAAMI,YAAYP,SAASU,eAAeb,mvqBCOjCc,GAAe,kBAC5BpyB,EAD4B,kBACP,CxCzBgD,iDEAF,gDDAE,iDFUZ,2CsCVW,4C3BDX,0CsBOvD,8CFY4E,wCvCnBtB,uCIEG,2CESzD,kDDLA,iDJIgE,6CeHhE,yDHFmE,kDCOnE,sDIb2D,4CDAL,uClBEhB,+BgDAkB,+CE8CvD+U,QAAO,aACcsd,iBAAiB,QAAS,CAC9CjxB,KAAM,QACNkxB,KAAM,CACJzxB,KCxDS,s0lBD0DXmf,MAAO,CACLuS,OAAQ,oBAEV9tB,YAAa,CACX+tB,YAAa,8BACb9rB,mBAAoB,wDACpB+rB,kBAAmB,8BACnBC,4BAA6B,gEAC7BC,2BAA4B,4BAC5BC,eAAgB,iCAChBC,qBAAsB,wCAExB9uB,SAAU,CACRmd,oBAAqB,2BACrBxa,mBAAoB,kDACpB+rB,kBAAmB,4BAErB3tB,aAAc,CACZ0tB,YAAa,+BACb9rB,mBAAoB,yDACpB+rB,kBAAmB,+BACnBppB,8BAA+B,2DAC/BE,6BAA8B,8BAC9BupB,wBAAyB1nB,IAE3BkO,cAAe,CACbkZ,YAAa,gCACbD,OAAQ,2BACR7rB,mBAAoB,2DACpB+rB,kBAAmB,gCACnBM,+BAAgC,6DAChCC,8BAA+B,qCAKrCC,EAA2BZ,iBAAiB,QAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utility.ts","../src/help/azure.help.ts","../src/image/image.reader.js","../src/instance/azureInstanceType.service.js","../src/instance/details/instance.details.controller.js","../src/loadBalancer/configure/AzureLoadBalancerChoiceModal.tsx","../src/azure.settings.ts","../src/loadBalancer/loadBalancer.transformer.js","../src/loadBalancer/configure/createLoadBalancer.controller.js","../src/loadBalancer/details/loadBalancerDetail.controller.js","../src/pipeline/stages/bake/bakeExecutionDetails.controller.js","../src/pipeline/stages/bake/azureBakeStage.js","../src/pipeline/stages/destroyAsg/azureDestroyAsgStage.js","../src/pipeline/stages/disableAsg/azureDisableAsgStage.js","../src/pipeline/stages/enableAsg/azureEnableAsgStage.js","../src/securityGroup/securityGroup.write.service.js","../src/securityGroup/configure/CreateSecurityGroupCtrl.js","../src/securityGroup/configure/EditSecurityGroupCtrl.js","../src/securityGroup/clone/cloneSecurityGroup.controller.js","../src/securityGroup/details/securityGroupDetail.controller.js","../src/securityGroup/securityGroup.reader.js","../src/securityGroup/securityGroup.transformer.js","../src/serverGroup/serverGroup.transformer.js","../src/serverGroup/configure/wizard/ServerGroupInstanceArchetype.controller.js","../src/serverGroup/configure/wizard/ServerGroupInstanceType.controller.js","../src/serverGroup/configure/wizard/advancedSettings/ServerGroupAdvancedSettings.controller.js","../src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.js","../src/serverGroup/configure/wizard/basicSettings/image.regional.filter.js","../src/serverGroup/configure/wizard/basicSettings/ServerGroupBasicSettings.controller.js","../src/serverGroup/configure/wizard/capacity/capacitySelector.directive.js","../src/serverGroup/configure/wizard/healthSettings/ServerGroupHealthSettings.controller.js","../src/serverGroup/configure/wizard/healthSettings/healthSettingsSelector.directive.js","../src/serverGroup/configure/wizard/image/ServerGroupImageSettings.controller.js","../src/serverGroup/configure/wizard/image/imageSettingsSelector.directive.js","../src/serverGroup/configure/wizard/loadBalancers/ServerGroupLoadBalancers.controller.js","../src/serverGroup/configure/wizard/loadBalancers/serverGroupLoadBalancersSelector.directive.js","../src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettings.controller.js","../src/serverGroup/configure/wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive.js","../src/serverGroup/configure/wizard/securityGroup/ServerGroupSecurityGroups.controller.js","../src/serverGroup/configure/wizard/securityGroup/serverGroupSecurityGroupsSelector.directive.js","../src/serverGroup/configure/wizard/tags/tagsSelector.directive.js","../src/serverGroup/configure/wizard/zones/zoneSelector.directive.js","../src/serverGroup/configure/serverGroup.configure.azure.module.js","../src/serverGroup/configure/serverGroupConfiguration.service.js","../src/serverGroup/configure/wizard/CloneServerGroup.azure.controller.js","../src/serverGroup/configure/serverGroupCommandBuilder.service.js","../src/common/AzureModalFooter.tsx","../src/serverGroup/details/rollback/RollbackServerGroupModal.tsx","../src/serverGroup/details/serverGroupDetails.azure.controller.js","../src/serverGroup/details/serverGroup.details.module.js","../src/validation/applicationName.validator.js","../../../node_modules/style-inject/dist/style-inject.es.js","../src/azure.module.ts","../src/logo/logo_azure.png"],"sourcesContent":["export interface ITagResult {\n isValid: boolean;\n error: TagError | null;\n errorMessage?: string;\n}\n\nexport enum TagError {\n TAG_NUMBER_EXCEED,\n TAG_KEY_LENGTH_EXCEED,\n TAG_VALUE_LENGTH_EXCEED,\n TAG_KEY_INVALID_CHARACTER,\n TAG_VALUE_INVALID_CHARACTER,\n TAG_OBJECT_UNDEFINED,\n}\n\nexport interface IAzureLoadBalancer {\n type: string;\n description: string;\n}\n\nexport const AzureLoadBalancerTypes: IAzureLoadBalancer[] = [\n {\n type: 'Azure Load Balancer',\n description: '',\n },\n {\n type: 'Azure Application Gateway',\n description: '',\n },\n];\n\nexport default class Utility {\n public static readonly TAG_LIMITATION: number = 8;\n public static readonly TAG_KEY_LENGTH_LIMITATION: number = 512;\n public static readonly TAG_VALUE_LENGTH_LIMITATION: number = 256;\n public static readonly TAG_INVALID_CHAR_REG_EXR: RegExp = /[<>%&\\\\?/]/;\n\n public static checkTags(tagsObject: { [s: string]: string }): ITagResult {\n if (!tagsObject) {\n return {\n isValid: false,\n error: TagError.TAG_OBJECT_UNDEFINED,\n errorMessage: 'instanceTags is not defined',\n };\n }\n const length: number = Object.keys(tagsObject).length;\n if (!(length >= 0 && length <= Utility.TAG_LIMITATION)) {\n return {\n isValid: false,\n error: TagError.TAG_NUMBER_EXCEED,\n errorMessage: `Number of tags exceeds the limit: ${Utility.TAG_LIMITATION}`,\n };\n }\n\n for (const [k, v] of Object.entries(tagsObject)) {\n if (k.length > Utility.TAG_KEY_LENGTH_LIMITATION) {\n return {\n isValid: false,\n error: TagError.TAG_KEY_LENGTH_EXCEED,\n errorMessage: `Length of Tag key: ${k} exceeds the limit: ${Utility.TAG_KEY_LENGTH_LIMITATION}`,\n };\n }\n if (v.length > Utility.TAG_VALUE_LENGTH_LIMITATION) {\n return {\n isValid: false,\n error: TagError.TAG_VALUE_LENGTH_EXCEED,\n errorMessage: `Length of Tag value: ${v} exceeds the limit: ${Utility.TAG_VALUE_LENGTH_LIMITATION}`,\n };\n }\n if (Utility.TAG_INVALID_CHAR_REG_EXR.test(k)) {\n return {\n isValid: false,\n error: TagError.TAG_KEY_INVALID_CHARACTER,\n errorMessage: `Invalid characters in Tag key: ${k}`,\n };\n }\n if (Utility.TAG_INVALID_CHAR_REG_EXR.test(v)) {\n return {\n isValid: false,\n error: TagError.TAG_VALUE_INVALID_CHARACTER,\n errorMessage: `Invalid characters in Tag value: ${v}`,\n };\n }\n }\n return {\n isValid: true,\n error: null,\n };\n }\n\n public static getLoadBalancerType(typeString: string): IAzureLoadBalancer | null {\n typeString = typeString.toLowerCase().split('_').join(' ');\n return AzureLoadBalancerTypes.find((lb: IAzureLoadBalancer) => lb.type.toLowerCase() === typeString) || null;\n }\n}\n","import { HelpContentsRegistry } from '@spinnaker/core';\nimport Utility from '../utility';\n\nconst helpContents: { [key: string]: string } = {\n 'azure.securityGroup.ingress.description': 'Friendly description of the rule you want to enable (limit 80 chars.)',\n 'azure.securityGroup.ingress.priority':\n \"Rules are processed in priority order; the lower the number, the higher the priority. We recommend leaving gaps between rules - 100, 200, 300, etc. - so that it's easier to add new rules without having to edit existing rules. There are several default rules that can be overridden with priority (65000, 65001 and 65500). For more information visit http://portal.azure.com.\",\n 'azure.securityGroup.ingress.source':\n \"The source filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the incoming traffic from a specific source IP address range (CIDR format) that will be allowed or denied by this rule.\",\n 'azure.securityGroup.ingress.sourcePortRange':\n 'The source port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which ports incoming traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.',\n 'azure.securityGroup.ingress.destination':\n \"The destination filter can be Any, an IP address range or a default tag('Internet', 'VirtualNetwork', AzureLoadBalancer'). It specifies the outgoing traffic from a specific destination IP address range (CIDR format) that will be allowed or denied by this rule.\",\n 'azure.securityGroup.ingress.destinationPortRange':\n 'The destination port range can be a single port, such as 80, or a port range, such as 1024-65535. This specifies from which destination ports traffic will be allowed or denied by this rule. Provide an asterisk (*) to allow traffic from clients connecting from any port.',\n 'azure.securityGroup.ingress.direction': 'Specifies whether the rule is for inbound or outbound traffic.',\n 'azure.securityGroup.ingress.actions':\n 'To adjust the priority of a rule, move it up or down in the list of rules. Rules at the top of the list have the highest priority.',\n 'azure.securityGroup.ingress.destPortRanges':\n 'Provide a single port, such as 80; a port range, such as 1024-65535; or a comma-separated list of single ports and/or port ranges, such as 80,1024-65535. Provide an asterisk (*) to allow traffic on any port.',\n 'azure.securityGroup.ingress.sourceIPCIDRRanges':\n 'Provide an address range using CIDR notation, such as 192.168.99.0/24; an IP address, such as 192.168.99.0; or a comma-separated list of address ranges or IP addresses, such as 10.0.0.0/24,44.66.0.0/24',\n 'azure.serverGroup.imageName': '(Required) <b>Image</b> is the deployable Azure Machine Image.',\n 'azure.serverGroup.stack':\n '(Required) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.',\n 'azure.serverGroup.detail':\n '(Required) <b>Detail</b> is a naming component to help distinguish specifics of the server group.',\n 'azure.serverGroup.scriptLocation':\n 'The location of custom scripts separated by comma or semicolon to be downloaded on to each instance. A single script should be like: fileUri. Multiple scripts should be like fileUri1,fileUri2 or fileUri1;fileUri2',\n 'azure.serverGroup.commandToExecute':\n 'Command(s) to execute custom scripts provided during provisioning of an instance.',\n 'azure.serverGroup.customData': 'Script or metadata to be injected into each instances.',\n 'azure.serverGroup.customTags': `Custom tags on Virtual Machine Scale Set. Allow ${Utility.TAG_LIMITATION} tags at most.`,\n 'azure.serverGroup.enableInboundNAT':\n 'An Azure load balancer of the basic sku will be created with adding inbound NAT port-forwarding rules to facilitate loggin on VM instances. There is no charge for creating an Azure load balancer of the basic sku. This option is disabled if Availability Zones are set which require Standard Azure Load Balancer and an extra Network Security Group with correct inbound and outbound rules configured.',\n 'azure.serverGroup.lun':\n 'Specifies the logical unit number of the data disk. This value is used to identify data disks within the VM and therefore must be unique for each data disk attached to a VM.',\n 'azure.serverGroup.diskSizeGB':\n 'Specifies the size of an empty data disk in gigabytes. This value cannot be larger than 1023 GB',\n 'azure.serverGroup.managedDisk.storageAccountType':\n 'You can choose between Azure managed disks types to support your workload or scenario.',\n 'azure.serverGroup.caching':\n 'Changing the default host caching policy can adversely impact the performance of your application. You should run performance tests to measure its impact. To improve the total IOPS/throughput, we recommend striping across multiple disks and using premium (SSD) disks.',\n 'azure.serverGroup.userAssignedIdentities':\n 'Allows your server to access Azure resources. Learn more here: https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview',\n 'azure.loadBalancer.dnsName':\n 'If there is no custom DNS label specified, a default DNS name will be created. The default value will be \"GeneratedText.cloudapp.net\" for Azure Application Gateway or \"GeneratedText.[region].cloudapp.azure.com\" for Azure Load Balancer.',\n 'azure.loadBalancer.probes.probeInterval':\n 'Probe interval in seconds. This value is the time interval between two consecutive probes.',\n 'azure.loadBalancer.probes.timeout':\n 'Probe time-out in seconds. If a valid response is not received within this time-out period, the probe is marked as failed. Note that the time-out value should not be more than the Interval value.',\n 'azure.loadBalancer.probes.unhealthyThreshold':\n 'Probe retry count. The back-end server is marked down after the consecutive probe failure count reaches the unhealthy threshold.',\n 'azure.loadBalancer.loadBalancingRules.idleTimeout':\n 'Keep a TCP or HTTP connection open without relying on clients to send keep-alive messages.',\n 'azure.loadBalancer.loadBalancingRules.sessionPersistence':\n 'Session persistence specifies that traffic from a client should be handled by the same virtual machine in the backend pool for the duration of a session. \"None\" specifies that successive requests from the same client may be handled by any virtual machine. \"Client IP\" specifies that successive requests from the same client IP address will be handled by the same virtual machine. \"Client IP and protocol\" specifies that successive requests from the same client IP address and protocol combination will be handled by the same virtual machine.',\n};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { REST } from '@spinnaker/core';\n\nexport const AZURE_IMAGE_IMAGE_READER = 'spinnaker.azure.image.reader';\nexport const name = AZURE_IMAGE_IMAGE_READER; // for backwards compatibility\nmodule(AZURE_IMAGE_IMAGE_READER, []).factory('azureImageReader', function () {\n function findImages(params) {\n return REST('/images/find')\n .query(params)\n .get()\n .then(\n function (results) {\n return results;\n },\n function () {\n return [];\n },\n );\n }\n\n function getImage(amiName, region, credentials) {\n return REST('/images')\n .path(credentials, region, amiName)\n .query({ provider: 'azure' })\n .get()\n .then(\n function (results) {\n return results && results.length ? results[0] : null;\n },\n function () {\n return null;\n },\n );\n }\n\n return {\n findImages: findImages,\n getImage: getImage,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE = 'spinnaker.azure.instanceType.service';\nexport const name = AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE; // for backwards compatibility\nmodule(AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE, []).factory('azureInstanceTypeService', [\n '$q',\n function ($q) {\n const B = {\n type: 'B-series',\n description:\n 'The B-series burstable VMs are ideal for workloads that do not need the full performance of the CPU continuously, like web servers, small databases and development and test environments.',\n instanceTypes: [\n {\n name: 'Standard_B1ms',\n label: 'Standard_B1ms',\n cpu: 1,\n memory: 2,\n storage: {\n type: 'SSD',\n count: 2,\n size: 4,\n },\n },\n {\n name: 'Standard_B1s',\n label: 'Standard_B1s',\n cpu: 1,\n memory: 1,\n storage: {\n type: 'SSD',\n count: 2,\n size: 2,\n },\n },\n {\n name: 'Standard_B2ms',\n label: 'Standard_B2ms',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 16,\n },\n },\n {\n name: 'Standard_B2s',\n label: 'Standard_B2s',\n cpu: 2,\n memory: 4,\n storage: {\n type: 'SSD',\n count: 4,\n size: 8,\n },\n },\n {\n name: 'Standard_B4ms',\n label: 'Standard_B4ms',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 32,\n },\n },\n {\n name: 'Standard_B8ms',\n label: 'Standard_B8ms',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 64,\n },\n },\n {\n name: 'Standard_B1ls',\n label: 'Standard_B1ls',\n cpu: 1,\n memory: 0.5,\n storage: {\n type: 'SSD',\n count: 2,\n size: 1,\n },\n },\n ],\n };\n\n const DSV3 = {\n type: 'Dsv3-series',\n description:\n 'The Dsv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.',\n instanceTypes: [\n {\n name: 'Standard_D2s_v3',\n label: 'Standard_D2s_v3',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 16,\n },\n },\n {\n name: 'Standard_D4s_v3',\n label: 'Standard_D4s_v3',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 32,\n },\n },\n {\n name: 'Standard_D8s_v3',\n label: 'Standard_D8s_v3',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 64,\n },\n },\n {\n name: 'Standard_D16s_v3',\n label: 'Standard_D16s_v3',\n cpu: 16,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 32,\n size: 128,\n },\n },\n {\n name: 'Standard_D32s_v3',\n label: 'Standard_D32s_v3',\n cpu: 32,\n memory: 128,\n storage: {\n type: 'SSD',\n count: 32,\n size: 256,\n },\n },\n {\n name: 'Standard_D64s_v3',\n label: 'Standard_D64s_v3',\n cpu: 64,\n memory: 256,\n storage: {\n type: 'SSD',\n count: 32,\n size: 512,\n },\n },\n ],\n };\n\n const DV3 = {\n type: 'Dv3-series',\n description:\n 'The Dv3-series sizes offer a combination of vCPU, memory, and temporary storage for most production workloads.',\n instanceTypes: [\n {\n name: 'Standard_D2_v3',\n label: 'Standard_D2_v3',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 4,\n size: 50,\n },\n },\n {\n name: 'Standard_D4_v3',\n label: 'Standard_D4_v3',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D8_v3',\n label: 'Standard_D8_v3',\n cpu: 8,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D16_v3',\n label: 'Standard_D16_v3',\n cpu: 16,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D32_v3',\n label: 'Standard_D32_v3',\n cpu: 32,\n memory: 128,\n storage: {\n type: 'SSD',\n count: 32,\n size: 800,\n },\n },\n {\n name: 'Standard_D64_v3',\n label: 'Standard_D64_v3',\n cpu: 64,\n memory: 256,\n storage: {\n type: 'SSD',\n count: 32,\n size: 1600,\n },\n },\n ],\n };\n\n const DSV2 = {\n type: 'DSv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_DS1_v2',\n label: 'Standard_DS1_v2',\n cpu: 1,\n memory: 3.5,\n storage: {\n type: 'SSD',\n count: 4,\n size: 7,\n },\n },\n {\n name: 'Standard_DS2_v2',\n label: 'Standard_DS2_v2',\n cpu: 2,\n memory: 7,\n storage: {\n type: 'SSD',\n count: 8,\n size: 14,\n },\n },\n {\n name: 'Standard_DS3_v2',\n label: 'Standard_DS3_v2',\n cpu: 4,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 16,\n size: 28,\n },\n },\n {\n name: 'Standard_DS4_v2',\n label: 'Standard_DS4_v2',\n cpu: 8,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 32,\n size: 56,\n },\n },\n {\n name: 'Standard_DS5_v2',\n label: 'Standard_DS5_v2',\n cpu: 16,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 64,\n size: 112,\n },\n },\n {\n name: 'Standard_DS11_v2',\n label: 'Standard_DS11_v2',\n cpu: 2,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 8,\n size: 28,\n },\n },\n {\n name: 'Standard_DS12_v2',\n label: 'Standard_DS12_v2',\n cpu: 4,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 16,\n size: 56,\n },\n },\n {\n name: 'Standard_DS13_v2',\n label: 'Standard_DS13_v2',\n cpu: 8,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 32,\n size: 112,\n },\n },\n {\n name: 'Standard_DS14_v2',\n label: 'Standard_DS14_v2',\n cpu: 16,\n memory: 112,\n storage: {\n type: 'SSD',\n count: 64,\n size: 224,\n },\n },\n {\n name: 'Standard_DS15_v2',\n label: 'Standard_DS15_v2',\n cpu: 20,\n memory: 140,\n storage: {\n type: 'SSD',\n count: 64,\n size: 280,\n },\n },\n ],\n };\n\n const DV2 = {\n type: 'Dv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_D1_v2',\n label: 'Standard_D1_v2',\n cpu: 1,\n memory: 3.5,\n storage: {\n type: 'SSD',\n count: 4,\n size: 50,\n },\n },\n {\n name: 'Standard_D2_v2',\n label: 'Standard_D2_v2',\n cpu: 2,\n memory: 7,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D3_v2',\n label: 'Standard_D3_v2',\n cpu: 4,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D4_v2',\n label: 'Standard_D4_v2',\n cpu: 8,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D5_v2',\n label: 'Standard_D5_v2',\n cpu: 16,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 64,\n size: 800,\n },\n },\n {\n name: 'Standard_D11_v2',\n label: 'Standard_D11_v2',\n cpu: 2,\n memory: 14,\n storage: {\n type: 'SSD',\n count: 8,\n size: 100,\n },\n },\n {\n name: 'Standard_D12_v2',\n label: 'Standard_D12_v2',\n cpu: 4,\n memory: 28,\n storage: {\n type: 'SSD',\n count: 16,\n size: 200,\n },\n },\n {\n name: 'Standard_D13_v2',\n label: 'Standard_D13_v2',\n cpu: 8,\n memory: 56,\n storage: {\n type: 'SSD',\n count: 32,\n size: 400,\n },\n },\n {\n name: 'Standard_D14_v2',\n label: 'Standard_D14_v2',\n cpu: 16,\n memory: 112,\n storage: {\n type: 'SSD',\n count: 64,\n size: 800,\n },\n },\n {\n name: 'Standard_D15_v2',\n label: 'Standard_D15_v2',\n cpu: 20,\n memory: 140,\n storage: {\n type: 'SSD',\n count: 64,\n size: 280,\n },\n },\n ],\n };\n\n const AV2 = {\n type: 'Av2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_A1_v2',\n label: 'Standard_A1_v2',\n cpu: 1,\n memory: 2,\n storage: {\n type: 'SSD',\n count: 2,\n size: 10,\n },\n },\n {\n name: 'Standard_A2m_v2',\n label: 'Standard_A2m_v2',\n cpu: 2,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 4,\n size: 20,\n },\n },\n {\n name: 'Standard_A2_v2',\n label: 'Standard_A2_v2',\n cpu: 2,\n memory: 4,\n storage: {\n type: 'SSD',\n count: 4,\n size: 20,\n },\n },\n {\n name: 'Standard_A4m_v2',\n label: 'Standard_A4m_v2',\n cpu: 4,\n memory: 32,\n storage: {\n type: 'SSD',\n count: 8,\n size: 40,\n },\n },\n {\n name: 'Standard_A4_v2',\n label: 'Standard_A4_v2',\n cpu: 4,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 8,\n size: 40,\n },\n },\n {\n name: 'Standard_A8m_v2',\n label: 'Standard_A8m_v2',\n cpu: 8,\n memory: 64,\n storage: {\n type: 'SSD',\n count: 16,\n size: 80,\n },\n },\n {\n name: 'Standard_A8_v2',\n label: 'Standard_A8_v2',\n cpu: 8,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 16,\n size: 80,\n },\n },\n ],\n };\n\n const DC = {\n type: 'DC-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_DC2s',\n label: 'Standard_DC2s',\n cpu: 2,\n memory: 8,\n storage: {\n type: 'SSD',\n count: 2,\n size: 100,\n },\n },\n {\n name: 'Standard_DC4s',\n label: 'Standard_DC4s',\n cpu: 4,\n memory: 16,\n storage: {\n type: 'SSD',\n count: 4,\n size: 200,\n },\n },\n ],\n };\n\n const FSV2 = {\n type: 'Fsv2-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F2s_v2',\n label: 'Standard_F2s_v2',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 4, size: 16 },\n },\n {\n name: 'Standard_F4s_v2',\n label: 'Standard_F4s_v2',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 8, size: 32 },\n },\n {\n name: 'Standard_F8s_v2',\n label: 'Standard_F8s_v2',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 16, size: 64 },\n },\n {\n name: 'Standard_F16s_v2',\n label: 'Standard_F16s_v2',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 32, size: 128 },\n },\n {\n name: 'Standard_F32s_v2',\n label: 'Standard_F32s_v2',\n cpu: 32,\n memory: 64,\n storage: { type: 'SSD', count: 32, size: 256 },\n },\n {\n name: 'Standard_F64s_v2',\n label: 'Standard_F64s_v2',\n cpu: 64,\n memory: 128,\n storage: { type: 'SSD', count: 32, size: 512 },\n },\n {\n name: 'Standard_F72s_v2',\n label: 'Standard_F72s_v2',\n cpu: 72,\n memory: 144,\n storage: { type: 'SSD', count: 32, size: 576 },\n },\n ],\n };\n\n const FS = {\n type: 'Fs-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F1s',\n label: 'Standard_F1s',\n cpu: 1,\n memory: 2,\n storage: { type: 'SSD', count: 4, size: 4 },\n },\n {\n name: 'Standard_F2s',\n label: 'Standard_F2s',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 8, size: 8 },\n },\n {\n name: 'Standard_F4s',\n label: 'Standard_F4s',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 16, size: 16 },\n },\n {\n name: 'Standard_F8s',\n label: 'Standard_F8s',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 32, size: 32 },\n },\n {\n name: 'Standard_F16s',\n label: 'Standard_F16s',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 64, size: 64 },\n },\n ],\n };\n\n const F = {\n type: 'F-series',\n description: '',\n instanceTypes: [\n {\n name: 'Standard_F1',\n label: 'Standard_F1',\n cpu: 1,\n memory: 2,\n storage: { type: 'SSD', count: 4, size: 16 },\n },\n {\n name: 'Standard_F2',\n label: 'Standard_F2',\n cpu: 2,\n memory: 4,\n storage: { type: 'SSD', count: 8, size: 32 },\n },\n {\n name: 'Standard_F4',\n label: 'Standard_F4',\n cpu: 4,\n memory: 8,\n storage: { type: 'SSD', count: 16, size: 64 },\n },\n {\n name: 'Standard_F8',\n label: 'Standard_F8',\n cpu: 8,\n memory: 16,\n storage: { type: 'SSD', count: 32, size: 128 },\n },\n {\n name: 'Standard_F16',\n label: 'Standard_F16',\n cpu: 16,\n memory: 32,\n storage: { type: 'SSD', count: 64, size: 256 },\n },\n ],\n };\n\n const categories = [\n {\n type: 'general',\n label: 'General Purpose',\n description:\n 'Balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers.',\n families: [B, DSV3, DV3, DSV2, DV2, AV2, DC],\n icon: 'hdd',\n },\n {\n type: 'compute',\n label: 'Compute Optimized',\n description:\n 'High CPU-to-memory ratio. Good for medium traffic web servers, network appliances, batch processes, and application servers.',\n families: [FSV2, FS, F],\n icon: 'hdd',\n },\n {\n type: 'custom',\n label: 'Custom Type',\n description: 'Select the instance type below.',\n families: [],\n icon: 'asterisk',\n },\n ];\n\n function calculateStorage(type) {\n if (!type || !type.storage) {\n return 0;\n }\n return type.storage.count * type.storage.size;\n }\n\n function buildStats(category) {\n const stats = {\n cpu: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n memory: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n storage: {\n min: Number.MAX_VALUE,\n max: -Number.MAX_VALUE,\n },\n families: [],\n };\n\n if (category.families && category.families.length) {\n category.families.forEach(function (family) {\n stats.families.push(family.type);\n const cpuMin = _.minBy(family.instanceTypes, 'cpu').cpu || Number.MAX_VALUE;\n const cpuMax = _.maxBy(family.instanceTypes, 'cpu').cpu || -Number.MAX_VALUE;\n const memoryMin = _.minBy(family.instanceTypes, 'memory').memory || Number.MAX_VALUE;\n const memoryMax = _.maxBy(family.instanceTypes, 'memory').memory || -Number.MAX_VALUE;\n const storageMin = calculateStorage(_.minBy(family.instanceTypes, calculateStorage)) || Number.MAX_VALUE;\n const storageMax = calculateStorage(_.maxBy(family.instanceTypes, calculateStorage)) || -Number.MAX_VALUE;\n\n stats.cpu.min = Math.min(stats.cpu.min, cpuMin);\n stats.cpu.max = Math.max(stats.cpu.max, cpuMax);\n stats.memory.min = Math.min(stats.memory.min, memoryMin);\n stats.memory.max = Math.max(stats.memory.max, memoryMax);\n stats.storage.min = Math.min(stats.storage.min, storageMin);\n stats.storage.max = Math.max(stats.storage.max, storageMax);\n });\n }\n\n return stats;\n }\n\n function getCategories() {\n categories.map(function (category) {\n for (const family of category.families) {\n for (const inst of family.instanceTypes) {\n if (inst.costFactor == undefined) inst.costFactor = 0;\n }\n }\n category.stats = buildStats(category);\n });\n return $q.when(categories);\n }\n\n const getAllTypesByRegion = function getAllTypesByRegion() {\n return getCategories();\n };\n\n function getAvailableTypesForRegions(locationToInstanceTypesMap, selectedLocations) {\n // This function is only ever called with one location.\n const [location] = selectedLocations;\n return locationToInstanceTypesMap[location];\n }\n\n return {\n getCategories: getCategories,\n getAvailableTypesForRegions: getAvailableTypesForRegions,\n getAllTypesByRegion: getAllTypesByRegion,\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport {\n CloudProviderRegistry,\n ConfirmationModalService,\n InstanceReader,\n InstanceWriter,\n RecentHistoryService,\n} from '@spinnaker/core';\n\nexport const AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER = 'spinnaker.azure.instance.detail.controller';\nexport const name = AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER, [UIROUTER_ANGULARJS, ANGULAR_UI_BOOTSTRAP]).controller(\n 'azureInstanceDetailsCtrl',\n [\n '$scope',\n '$state',\n '$uibModal',\n 'instance',\n 'app',\n '$q',\n function ($scope, $state, $uibModal, instance, app, $q) {\n // needed for standalone instances\n $scope.detailsTemplateUrl = CloudProviderRegistry.getValue('azure', 'instance.detailsTemplateUrl');\n\n $scope.state = {\n loading: true,\n standalone: app.isStandalone,\n };\n\n function extractHealthMetrics(instance, latest) {\n // do not backfill on standalone instances\n if (app.isStandalone) {\n instance.health = latest.health;\n }\n\n instance.health = instance.health || [];\n const displayableMetrics = instance.health.filter(function (metric) {\n return metric.type !== 'Azure' || metric.state !== 'Unknown';\n });\n // backfill details where applicable\n if (latest.health) {\n displayableMetrics.forEach(function (metric) {\n const detailsMatch = latest.health.filter(function (latestHealth) {\n return latestHealth.type === metric.type;\n });\n if (detailsMatch.length) {\n _.defaults(metric, detailsMatch[0]);\n }\n });\n }\n $scope.healthMetrics = displayableMetrics;\n }\n\n function retrieveInstance() {\n const extraData = {};\n let instanceSummary, loadBalancers, account, region, vpcId;\n if (!app.serverGroups) {\n // standalone instance\n instanceSummary = {};\n loadBalancers = [];\n account = instance.account;\n region = instance.region;\n } else {\n app.serverGroups.data.some(function (serverGroup) {\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = serverGroup.loadBalancers;\n account = serverGroup.account;\n region = serverGroup.region;\n vpcId = serverGroup.vpcId;\n extraData.serverGroup = serverGroup.name;\n extraData.vpcId = serverGroup.vpcId;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a server group that is part of another app\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a disabled server group via a load balancer\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.serverGroups.some(function (serverGroup) {\n if (!serverGroup.isDisabled) {\n return false;\n }\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n });\n }\n }\n }\n\n if (instanceSummary && account && region) {\n extraData.account = account;\n extraData.region = region;\n RecentHistoryService.addExtraDataToLatest('instances', extraData);\n return InstanceReader.getInstanceDetails(account, region, instance.instanceId).then(\n function (details) {\n $scope.state.loading = false;\n extractHealthMetrics(instanceSummary, details);\n $scope.instance = _.defaults(details, instanceSummary);\n $scope.instance.account = account;\n $scope.instance.region = region;\n $scope.instance.vpcId = vpcId;\n $scope.instance.loadBalancers = loadBalancers;\n const discoveryMetric = _.find($scope.healthMetrics, function (metric) {\n return metric.type === 'Discovery';\n });\n if (discoveryMetric && discoveryMetric.vipAddress) {\n const vipList = discoveryMetric.vipAddress;\n $scope.instance.vipAddress = vipList.includes(',') ? vipList.split(',') : [vipList];\n }\n $scope.baseIpAddress = details.publicDnsName || details.privateIpAddress;\n },\n function () {\n // When an instance is first starting up, we may not have the details cached in oort yet, but we still\n // want to let the user see what details we have\n $scope.state.loading = false;\n $state.go('^');\n },\n );\n }\n\n if (!instanceSummary) {\n $scope.instanceIdNotFound = instance.instanceId;\n $scope.state.loading = false;\n }\n\n return $q.when(null);\n }\n\n this.canDeregisterFromLoadBalancer = function () {\n return $scope.instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n };\n\n this.canRegisterWithLoadBalancer = function () {\n const instance = $scope.instance;\n if (!instance.loadBalancers || !instance.loadBalancers.length) {\n return false;\n }\n const outOfService = instance.health.some(function (health) {\n return health.type === 'LoadBalancer' && health.state === 'OutOfService';\n });\n const hasLoadBalancerHealth = instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n return outOfService || !hasLoadBalancerHealth;\n };\n\n this.canRegisterWithDiscovery = function () {\n const instance = $scope.instance;\n const discoveryHealth = instance.health.filter(function (health) {\n return health.type === 'Discovery';\n });\n return discoveryHealth.length ? discoveryHealth[0].state === 'OutOfService' : false;\n };\n\n this.terminateInstance = function terminateInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId,\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return InstanceWriter.terminateInstance(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + '?',\n buttonText: 'Terminate ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.terminateInstanceAndShrinkServerGroup = function terminateInstanceAndShrinkServerGroup() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId + ' and shrinking server group',\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return InstanceWriter.terminateInstanceAndShrinkServerGroup(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup + '?',\n buttonText: 'Terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.rebootInstance = function rebootInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Rebooting ' + instance.instanceId,\n };\n\n const submitMethod = function () {\n return InstanceWriter.rebootInstance(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really reboot ' + instance.instanceId + '?',\n buttonText: 'Reboot ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.registerInstanceWithLoadBalancer = function registerInstanceWithLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Registering ' + instance.instanceId + ' with ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.registerInstanceWithLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really register ' + instance.instanceId + ' with ' + loadBalancerNames + '?',\n buttonText: 'Register ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.deregisterInstanceFromLoadBalancer = function deregisterInstanceFromLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Deregistering ' + instance.instanceId + ' from ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.deregisterInstanceFromLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really deregister ' + instance.instanceId + ' from ' + loadBalancerNames + '?',\n buttonText: 'Deregister ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.enableInstanceInDiscovery = function enableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.enableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really enable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Enable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.disableInstanceInDiscovery = function disableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.disableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really disable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Disable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.hasHealthState = function hasHealthState(healthProviderType, state) {\n const instance = $scope.instance;\n return instance.health.some(function (health) {\n return health.type === healthProviderType && health.state === state;\n });\n };\n\n const initialize = app.isStandalone\n ? retrieveInstance()\n : $q.all([app.serverGroups.ready(), app.loadBalancers.ready()]).then(retrieveInstance);\n\n initialize.then(() => {\n // Two things to look out for here:\n // 1. If the retrieveInstance call completes *after* the user has navigated away from the view, there\n // is no point in subscribing to the refresh\n // 2. If this is a standalone instance, there is no application that will refresh\n if (!$scope.$$destroyed && !app.isStandalone) {\n app.serverGroups.onRefresh($scope, retrieveInstance);\n }\n });\n\n $scope.account = instance.account;\n },\n ],\n);\n","import React from 'react';\nimport { Button, Modal } from 'react-bootstrap';\n\nimport {\n CloudProviderRegistry,\n ILoadBalancerModalProps,\n ModalClose,\n ModalInjector,\n noop,\n ReactModal,\n} from '@spinnaker/core';\n\nimport { AzureLoadBalancerTypes, IAzureLoadBalancer } from '../../utility';\n\nexport interface IAzureLoadBalancerChoiceModalState {\n choices: IAzureLoadBalancer[];\n selectedChoice: IAzureLoadBalancer;\n}\n\nexport class AzureLoadBalancerChoiceModal extends React.Component<\n ILoadBalancerModalProps,\n IAzureLoadBalancerChoiceModalState\n> {\n public static defaultProps: Partial<ILoadBalancerModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static show(props: ILoadBalancerModalProps): Promise<void> {\n return ReactModal.show(AzureLoadBalancerChoiceModal, {\n ...props,\n className: 'create-pipeline-modal-overflow-visible',\n });\n }\n\n constructor(props: ILoadBalancerModalProps) {\n super(props);\n this.state = {\n choices: AzureLoadBalancerTypes,\n selectedChoice: AzureLoadBalancerTypes[0],\n };\n }\n\n public choiceSelected(choice: IAzureLoadBalancer): void {\n this.setState({ selectedChoice: choice });\n }\n\n private choose = (): void => {\n this.close();\n const provider: any = CloudProviderRegistry.getValue('azure', 'loadBalancer');\n ModalInjector.modalService\n .open({\n templateUrl: provider.createLoadBalancerTemplateUrl,\n windowClass: 'modal-z-index',\n controller: `${provider.createLoadBalancerController} as ctrl`,\n size: 'lg',\n resolve: {\n application: () => this.props.app,\n loadBalancer: (): any => null,\n isNew: () => true,\n forPipelineConfig: () => false,\n loadBalancerType: () => this.state.selectedChoice,\n },\n })\n .result.catch(() => {});\n };\n\n public close = (reason?: any): void => {\n this.props.dismissModal(reason);\n };\n\n public render() {\n const { choices, selectedChoice } = this.state;\n\n return (\n <>\n <ModalClose dismiss={this.close} />\n <Modal.Header>\n <Modal.Title>Select Type of Load Balancer</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <div className=\"modal-body\">\n <div className=\"card-choices\">\n {choices.map((choice) => (\n <div\n key={choice.type}\n className={`card ${selectedChoice === choice ? 'active' : ''}`}\n onClick={() => this.choiceSelected(choice)}\n >\n <h3 className=\"load-balancer-label\">{choice.type}</h3>\n <div>{choice.description}</div>\n </div>\n ))}\n </div>\n <div className=\"load-balancer-description\" />\n </div>\n </Modal.Body>\n <Modal.Footer>\n <Button onClick={this.choose}>\n Configure Load Balancer <span className=\"glyphicon glyphicon-chevron-right\" />\n </Button>\n </Modal.Footer>\n </>\n );\n }\n}\n","import { IProviderSettings, SETTINGS } from '@spinnaker/core';\n\nexport interface IAzureProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n };\n}\n\nexport const AzureProviderSettings: IAzureProviderSettings = (SETTINGS.providers.azure as IAzureProviderSettings) || {\n defaults: {},\n};\nif (AzureProviderSettings) {\n AzureProviderSettings.resetToOriginal = SETTINGS.resetProvider('azure');\n}\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AzureProviderSettings } from '../azure.settings';\n\nexport const AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER = 'spinnaker.azure.loadBalancer.transformer';\nexport const name = AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER, []).factory('azureLoadBalancerTransformer', [\n '$q',\n function ($q) {\n function normalizeLoadBalancer(loadBalancer) {\n loadBalancer.serverGroups.forEach(function (serverGroup) {\n serverGroup.account = loadBalancer.account;\n serverGroup.region = loadBalancer.region;\n\n if (serverGroup.detachedInstances) {\n serverGroup.detachedInstances = serverGroup.detachedInstances.map(function (instanceId) {\n return { id: instanceId };\n });\n serverGroup.instances = serverGroup.instances.concat(serverGroup.detachedInstances);\n } else {\n serverGroup.detachedInstances = [];\n }\n });\n const activeServerGroups = _.filter(loadBalancer.serverGroups, { isDisabled: false });\n loadBalancer.provider = loadBalancer.type;\n loadBalancer.instances = _.chain(activeServerGroups).map('instances').flatten().value();\n loadBalancer.detachedInstances = _.chain(activeServerGroups).map('detachedInstances').flatten().value();\n return $q.resolve(loadBalancer);\n }\n\n function convertLoadBalancerForEditing(loadBalancer) {\n const toEdit = {\n region: loadBalancer.region,\n credentials: loadBalancer.account,\n name: loadBalancer.name,\n stack: loadBalancer.stack,\n detail: loadBalancer.detail,\n vnet: loadBalancer.vnet,\n subnet: loadBalancer.subnet,\n probes: [],\n loadBalancingRules: [],\n };\n\n if (loadBalancer.elb) {\n const elb = loadBalancer.elb;\n\n toEdit.securityGroups = elb.securityGroups;\n toEdit.vnet = elb.vnet;\n\n if (elb.loadBalancingRules) {\n toEdit.loadBalancingRules = elb.loadBalancingRules;\n }\n\n toEdit.probes = elb.probes;\n if (elb.dnsName && elb.dnsName !== 'dns-not-found') {\n toEdit.dnsName = elb.dnsName.split('.')[0];\n }\n }\n return toEdit;\n }\n\n function constructNewLoadBalancerTemplate(application) {\n const defaultCredentials = application.defaultCredentials.azure || AzureProviderSettings.defaults.account;\n const defaultRegion = application.defaultRegions.azure || AzureProviderSettings.defaults.region;\n return {\n stack: '',\n detail: 'frontend',\n credentials: defaultCredentials,\n region: defaultRegion,\n cloudProvider: 'azure',\n vnet: null,\n subnet: null,\n probes: [\n {\n probeName: '',\n probeProtocol: 'HTTP',\n probePort: '80',\n probePath: '/',\n probeInterval: 30,\n unhealthyThreshold: 8,\n timeout: 120,\n },\n ],\n securityGroups: [],\n loadBalancingRules: [\n {\n ruleName: '',\n protocol: 'HTTP',\n externalPort: 80,\n backendPort: 80,\n probeName: '',\n persistence: 'None',\n idleTimeout: 4,\n },\n ],\n sku: 'Standard_v2',\n };\n }\n\n return {\n normalizeLoadBalancer: normalizeLoadBalancer,\n convertLoadBalancerForEditing: convertLoadBalancerForEditing,\n constructNewLoadBalancerTemplate: constructNewLoadBalancerTemplate,\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, LoadBalancerWriter, NameUtils, NetworkReader, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from '../loadBalancer.transformer';\n\nexport const AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER =\n 'spinnaker.azure.loadBalancer.create.controller';\nexport const name = AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER; // for backwards compatibility\nmodule(AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n]).controller('azureCreateLoadBalancerCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n 'azureLoadBalancerTransformer',\n 'application',\n 'loadBalancer',\n 'isNew',\n 'loadBalancerType',\n function (\n $scope,\n $uibModalInstance,\n $state,\n azureLoadBalancerTransformer,\n application,\n loadBalancer,\n isNew,\n loadBalancerType,\n ) {\n const ctrl = this;\n\n $scope.regions = [];\n\n $scope.pages = {\n location: require('./createLoadBalancerProperties.html'),\n listeners: require('./listeners.html'),\n healthCheck: require('./healthCheck.html'),\n advancedSettings: require('./advancedSettings.html'),\n };\n\n $scope.isNew = isNew;\n $scope.loadBalancerType = loadBalancerType.type;\n $scope.isALB = loadBalancerType.type === 'Azure Load Balancer';\n\n $scope.state = {\n accountsLoaded: false,\n submitting: false,\n };\n\n $scope.validSkus = ['Standard_v2', 'Standard_Small'];\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.loadBalancer.name,\n accountId: $scope.loadBalancer.credentials,\n region: $scope.loadBalancer.region,\n provider: 'azure',\n };\n\n if (!$state.includes('**.loadBalancerDetails')) {\n $state.go('.loadBalancerDetails', newStateParams);\n } else {\n $state.go('^.loadBalancerDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.loadBalancers.refresh();\n application.loadBalancers.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: (isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function initializeCreateMode() {\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accountsLoaded = true;\n ctrl.accountUpdated();\n });\n }\n\n function initializeController() {\n if (loadBalancer) {\n $scope.loadBalancer = azureLoadBalancerTransformer.convertLoadBalancerForEditing(loadBalancer);\n if (isNew) {\n const nameParts = NameUtils.parseLoadBalancerName($scope.loadBalancer.name);\n $scope.loadBalancer.stack = nameParts.stack;\n $scope.loadBalancer.detail = nameParts.freeFormDetails;\n delete $scope.loadBalancer.name;\n }\n } else {\n $scope.loadBalancer = azureLoadBalancerTransformer.constructNewLoadBalancerTemplate(application);\n }\n if (isNew) {\n updateLoadBalancerNames();\n initializeCreateMode();\n }\n }\n\n function updateLoadBalancerNames() {\n const account = $scope.loadBalancer.credentials;\n const region = $scope.loadBalancer.region;\n\n const accountLoadBalancersByRegion = {};\n application\n .getDataSource('loadBalancers')\n .refresh(true)\n .then(() => {\n application.getDataSource('loadBalancers').data.forEach((loadBalancer) => {\n if (loadBalancer.account === account) {\n accountLoadBalancersByRegion[loadBalancer.region] =\n accountLoadBalancersByRegion[loadBalancer.region] || [];\n accountLoadBalancersByRegion[loadBalancer.region].push(loadBalancer.name);\n }\n });\n\n $scope.existingLoadBalancerNames = accountLoadBalancersByRegion[region] || [];\n });\n }\n\n initializeController();\n\n this.requiresHealthCheckPath = function () {\n return (\n $scope.loadBalancer.probes[0].probeProtocol && $scope.loadBalancer.probes[0].probeProtocol.indexOf('HTTP') === 0\n );\n };\n\n this.updateName = function () {\n $scope.loadBalancer.name = this.getName();\n };\n\n this.getName = function () {\n const elb = $scope.loadBalancer;\n const elbName = [application.name, elb.stack || '', elb.detail || ''].join('-');\n return _.trimEnd(elbName, '-');\n };\n\n this.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.loadBalancer.credentials).then(function (regions) {\n $scope.regions = regions;\n ctrl.regionUpdated();\n });\n };\n\n this.regionUpdated = function () {\n updateLoadBalancerNames();\n ctrl.updateName();\n ctrl.vnetUpdated();\n };\n\n this.vnetUpdated = function () {\n const account = $scope.loadBalancer.credentials;\n const region = $scope.loadBalancer.region;\n $scope.loadBalancer.selectedVnet = null;\n $scope.loadBalancer.vnet = null;\n $scope.loadBalancer.vnetResourceGroup = null;\n ctrl.selectedVnets = [];\n\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((vnet) => {\n if (vnet.account === account && vnet.region === region) {\n ctrl.selectedVnets.push(vnet);\n }\n });\n }\n });\n\n ctrl.subnetUpdated();\n };\n\n this.subnetUpdated = function () {\n $scope.loadBalancer.selectedSubnet = null;\n $scope.loadBalancer.subnet = null;\n ctrl.selectedSubnets = [];\n };\n\n this.selectedVnetChanged = function (item) {\n $scope.loadBalancer.vnet = item.name;\n $scope.loadBalancer.vnetResourceGroup = item.resourceGroup;\n $scope.loadBalancer.selectedSubnet = null;\n $scope.loadBalancer.subnet = null;\n ctrl.selectedSubnets = [];\n if (item.subnets) {\n item.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n if (device && device.type !== 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n ctrl.selectedSubnets.push(subnet);\n }\n });\n }\n };\n\n this.removeListener = function (index) {\n $scope.loadBalancer.loadBalancingRules.splice(index, 1);\n };\n\n this.addListener = function () {\n $scope.loadBalancer.loadBalancingRules.push({ protocol: 'HTTP' });\n };\n\n this.submit = function () {\n const descriptor = isNew ? 'Create' : 'Update';\n\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n clusterName: $scope.loadBalancer.clusterName,\n resourceGroupName: $scope.loadBalancer.clusterName,\n loadBalancerName: $scope.loadBalancer.name,\n };\n\n if ($scope.loadBalancer.selectedVnet) {\n $scope.loadBalancer.vnet = $scope.loadBalancer.selectedVnet.name;\n $scope.loadBalancer.vnetResourceGroup = $scope.loadBalancer.selectedVnet.resourceGroup;\n }\n\n if ($scope.loadBalancer.selectedSubnet) {\n $scope.loadBalancer.subnet = $scope.loadBalancer.selectedSubnet.name;\n }\n\n const name = $scope.loadBalancer.clusterName || $scope.loadBalancer.name;\n const probeName = name + '-probe';\n const ruleNameBase = name + '-rule';\n $scope.loadBalancer.type = 'upsertLoadBalancer';\n $scope.loadBalancer.loadBalancerType = $scope.loadBalancerType;\n if (!$scope.loadBalancer.vnet && !$scope.loadBalancer.subnetType) {\n $scope.loadBalancer.securityGroups = null;\n }\n\n $scope.loadBalancer.probes[0].probeName = probeName;\n\n $scope.loadBalancer.loadBalancingRules.forEach((rule, index) => {\n rule.ruleName = ruleNameBase + index;\n rule.probeName = probeName;\n });\n\n if ($scope.loadBalancer.probes[0].probeProtocol === 'TCP') {\n $scope.loadBalancer.probes[0].probePath = undefined;\n }\n\n return LoadBalancerWriter.upsertLoadBalancer($scope.loadBalancer, application, descriptor, params);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport {\n ConfirmationModalService,\n FirewallLabels,\n LOAD_BALANCER_READ_SERVICE,\n LoadBalancerWriter,\n SECURITY_GROUP_READER,\n} from '@spinnaker/core';\n\nexport const AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER =\n 'spinnaker.azure.loadBalancer.details.controller';\nexport const name = AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER, [\n ANGULAR_UI_BOOTSTRAP,\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n LOAD_BALANCER_READ_SERVICE,\n ])\n .controller('azureLoadBalancerDetailsCtrl', [\n '$scope',\n '$state',\n '$exceptionHandler',\n '$uibModal',\n 'loadBalancer',\n 'app',\n 'securityGroupReader',\n 'loadBalancerReader',\n '$q',\n function (\n $scope,\n $state,\n $exceptionHandler,\n $uibModal,\n loadBalancer,\n app,\n securityGroupReader,\n loadBalancerReader,\n $q,\n ) {\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n function extractLoadBalancer() {\n $scope.loadBalancer = app.loadBalancers.data.filter(function (test) {\n return (\n test.name === loadBalancer.name &&\n test.region === loadBalancer.region &&\n test.account === loadBalancer.accountId\n );\n })[0];\n\n if ($scope.loadBalancer) {\n const detailsLoader = loadBalancerReader.getLoadBalancerDetails(\n $scope.loadBalancer.provider,\n loadBalancer.accountId,\n loadBalancer.region,\n loadBalancer.name,\n );\n\n return detailsLoader.then(function (details) {\n $scope.state.loading = false;\n const securityGroups = [];\n\n const filtered = details.filter(function (test) {\n return test.name === loadBalancer.name;\n });\n\n if (filtered.length) {\n $scope.loadBalancer.elb = filtered[0];\n\n $scope.loadBalancer.account = loadBalancer.accountId;\n\n if ($scope.loadBalancer.elb.securityGroups) {\n $scope.loadBalancer.elb.securityGroups.forEach(function (securityGroupId) {\n const match = securityGroupReader.getApplicationSecurityGroup(\n app,\n loadBalancer.accountId,\n loadBalancer.region,\n securityGroupId,\n );\n if (match) {\n securityGroups.push(match);\n }\n });\n $scope.securityGroups = _.sortBy(securityGroups, 'name');\n }\n\n if ($scope.loadBalancer.loadBalancerType && $scope.loadBalancer.loadBalancerType.includes('_')) {\n const type = $scope.loadBalancer.loadBalancerType;\n $scope.loadBalancer.loadBalancerType = type\n .split('_')\n .map((s) => {\n const ss = s.toLowerCase();\n return ss.substring(0, 1).toUpperCase() + ss.substring(1);\n })\n .join(' ');\n }\n }\n });\n }\n if (!$scope.loadBalancer) {\n $state.go('^');\n }\n\n return $q.when(null);\n }\n\n app\n .ready()\n .then(extractLoadBalancer)\n .then(() => {\n // If the user navigates away from the view before the initial extractLoadBalancer call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.onRefresh($scope, extractLoadBalancer);\n }\n });\n\n this.editLoadBalancer = function editLoadBalancer() {\n $uibModal.open({\n templateUrl: require('../configure/editLoadBalancer.html'),\n controller: 'azureCreateLoadBalancerCtrl as ctrl',\n size: 'lg',\n resolve: {\n application: function () {\n return app;\n },\n loadBalancer: function () {\n return angular.copy($scope.loadBalancer);\n },\n isNew: function () {\n return false;\n },\n loadBalancerType: function () {\n return { type: $scope.loadBalancer.loadBalancerType };\n },\n },\n });\n };\n\n this.deleteLoadBalancer = function deleteLoadBalancer() {\n if ($scope.loadBalancer.instances && $scope.loadBalancer.instances.length) {\n return;\n }\n\n const taskMonitor = {\n application: app,\n title: 'Deleting ' + loadBalancer.name,\n };\n\n const command = {\n cloudProvider: 'azure',\n loadBalancerName: $scope.loadBalancer.name,\n loadBalancerType: $scope.loadBalancer.loadBalancerType,\n credentials: $scope.loadBalancer.account,\n region: loadBalancer.region,\n appName: app.name,\n };\n\n const submitMethod = () => LoadBalancerWriter.deleteLoadBalancer(command, app);\n\n ConfirmationModalService.confirm({\n header: 'Really delete ' + loadBalancer.name + '?',\n buttonText: 'Delete ' + loadBalancer.name,\n account: loadBalancer.accountId,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { SETTINGS } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER =\n 'spinnaker.azure.pipeline.stage.bake.executionDetails.controller';\nexport const name = AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER, [UIROUTER_ANGULARJS]).controller(\n 'azureBakeExecutionDetailsCtrl',\n [\n '$scope',\n '$stateParams',\n 'executionDetailsSectionService',\n '$interpolate',\n function ($scope, $stateParams, executionDetailsSectionService, $interpolate) {\n $scope.configSections = ['bakeConfig', 'taskStatus'];\n\n const initialized = () => {\n $scope.detailsSection = $stateParams.details;\n $scope.provider = $scope.stage.context.cloudProviderType || 'azure';\n $scope.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' &&\n SETTINGS.feature.roscoSelector($scope.stage.context));\n $scope.bakeryDetailUrl = $interpolate(\n $scope.roscoMode && SETTINGS.roscoDetailUrl ? SETTINGS.roscoDetailUrl : SETTINGS.bakeryDetailUrl,\n );\n };\n\n const initialize = () => executionDetailsSectionService.synchronizeSection($scope.configSections, initialized);\n\n initialize();\n\n $scope.$on('$stateChangeSuccess', initialize);\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n AuthenticationService,\n BakeExecutionLabel,\n BakeryReader,\n PipelineTemplates,\n Registry,\n SETTINGS,\n} from '@spinnaker/core';\n\nimport { AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER } from './bakeExecutionDetails.controller';\n\nexport const AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE = 'spinnaker.azure.pipeline.stage.bakeStage';\nexport const name = AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE, [AZURE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'bake',\n cloudProvider: 'azure',\n label: 'Bake',\n description: 'Bakes an image',\n templateUrl: require('./bakeStage.html'),\n executionDetailsUrl: require('./bakeExecutionDetails.html'),\n executionLabelComponent: BakeExecutionLabel,\n extraLabelLines: (stage) => {\n return stage.masterStage.context.allPreviouslyBaked || stage.masterStage.context.somePreviouslyBaked ? 1 : 0;\n },\n supportsCustomTimeout: true,\n validators: [\n { type: 'requiredField', fieldName: 'package' },\n { type: 'requiredField', fieldName: 'regions' },\n {\n type: 'upstreamVersionProvided',\n checkParentTriggers: true,\n getMessage: (labels) =>\n 'Bake stages should always have a stage or trigger preceding them that provides version information: ' +\n '<ul>' +\n labels.map((label) => `<li>${label}</li>`).join('') +\n '</ul>' +\n 'Otherwise, Spinnaker will bake and deploy the most-recently built package.',\n },\n ],\n restartable: true,\n });\n })\n .controller('azureBakeStageCtrl', [\n '$scope',\n '$q',\n '$uibModal',\n function ($scope, $q, $uibModal) {\n $scope.stage.extendedAttributes = $scope.stage.extendedAttributes || {};\n $scope.stage.regions = $scope.stage.regions || [];\n\n if (!$scope.stage.user) {\n $scope.stage.user = AuthenticationService.getAuthenticatedUser().name;\n }\n\n $scope.viewState = {\n loading: true,\n };\n\n function initialize() {\n $q.all([\n BakeryReader.getRegions('azure'),\n BakeryReader.getBaseOsOptions('azure'),\n BakeryReader.getBaseLabelOptions(),\n ]).then(function ([regions, baseOsOptions, baseLabelOptions]) {\n $scope.regions = regions;\n if ($scope.regions.length === 1) {\n $scope.stage.region = $scope.regions[0];\n } else if (!$scope.regions.includes($scope.stage.region)) {\n delete $scope.stage.region;\n }\n if (!$scope.stage.regions.length && $scope.application.defaultRegions.azure) {\n $scope.stage.regions.push($scope.application.defaultRegions.azure);\n }\n if (!$scope.stage.regions.length && $scope.application.defaultRegions.azure) {\n $scope.stage.regions.push($scope.application.defaultRegions.azure);\n }\n $scope.baseOsOptions = baseOsOptions.baseImages;\n if ($scope.baseOsOptions.length) {\n $scope.stage.osType = baseOsOptions.baseImages[0].osType;\n }\n\n $scope.baseLabelOptions = baseLabelOptions;\n\n if (!$scope.stage.baseOs && $scope.baseOsOptions && $scope.baseOsOptions.length) {\n $scope.stage.baseOs = $scope.baseOsOptions[0].id;\n }\n\n if (!$scope.stage.baseLabel && $scope.baseLabelOptions && $scope.baseLabelOptions.length) {\n $scope.stage.baseLabel = $scope.baseLabelOptions[0];\n }\n $scope.viewState.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector($scope.stage));\n $scope.showAdvancedOptions = showAdvanced();\n $scope.viewState.loading = false;\n });\n }\n\n this.baseOsChanged = () => {\n const selectedOption = _.find($scope.baseOsOptions, { id: $scope.stage.baseOs });\n $scope.stage.osType = selectedOption.osType;\n };\n\n function stageUpdated() {\n deleteEmptyProperties();\n // Since the selector computes using stage as an input, it needs to be able to recompute roscoMode on updates\n if (typeof SETTINGS.feature.roscoSelector === 'function') {\n $scope.viewState.roscoMode = SETTINGS.feature.roscoSelector($scope.stage);\n }\n }\n\n function showAdvanced() {\n const stg = $scope.stage;\n return !!(\n stg.templateFileName ||\n (stg.extendedAttributes && _.size(stg.extendedAttributes) > 0) ||\n stg.varFileName\n );\n }\n\n function deleteEmptyProperties() {\n _.forOwn($scope.stage, function (val, key) {\n if (val === '') {\n delete $scope.stage[key];\n }\n });\n }\n\n this.addExtendedAttribute = function () {\n if (!$scope.stage.extendedAttributes) {\n $scope.stage.extendedAttributes = {};\n }\n $uibModal\n .open({\n templateUrl: PipelineTemplates.addExtendedAttributes,\n controller: 'bakeStageAddExtendedAttributeController',\n controllerAs: 'addExtendedAttribute',\n resolve: {\n extendedAttribute: function () {\n return {\n key: '',\n value: '',\n };\n },\n },\n })\n .result.then(function (extendedAttribute) {\n $scope.stage.extendedAttributes[extendedAttribute.key] = extendedAttribute.value;\n })\n .catch(() => {});\n };\n\n this.removeExtendedAttribute = function (key) {\n delete $scope.stage.extendedAttributes[key];\n };\n\n this.showTemplateFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.templateFileName;\n };\n\n this.showExtendedAttributes = function () {\n return (\n $scope.viewState.roscoMode || ($scope.stage.extendedAttributes && _.size($scope.stage.extendedAttributes) > 0)\n );\n };\n\n this.showVarFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.varFileName;\n };\n\n $scope.$watch('stage', stageUpdated, true);\n\n initialize();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE = 'spinnaker.azure.pipeline.stage.destroyAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'destroyServerGroup',\n cloudProvider: 'azure',\n templateUrl: require('./destroyAsgStage.html'),\n executionStepLabelUrl: require('./destroyAsgStepLabel.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureDestroyAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n ctrl.accountUpdated = function () {\n AccountService.getAccountDetails(stage.credentials).then(function (details) {\n stage.regions = [details.org];\n // stage.regions = ['eastus', 'westus'];\n });\n };\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n stage.interestingHealthProviderNames = []; // bypass the check for now; will change this later to ['azureService']\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n\n if (stage.credentials) {\n ctrl.accountUpdated();\n }\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE = 'spinnaker.azure.pipeline.stage.disableAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'disableServerGroup',\n alias: 'disableAsg',\n cloudProvider: 'azure',\n templateUrl: require('./disableAsgStage.html'),\n executionStepLabelUrl: require('./disableAsgStepLabel.html'),\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureDisableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n if (stage.isNew && $scope.application.attributes.platformHealthOnly) {\n stage.interestingHealthProviderNames = []; // bypass the check for now; will change this later to ['azureService']\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.azure) {\n stage.regions.push($scope.application.defaultRegions.azure);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE = 'spinnaker.azure.pipeline.stage.enableAsgStage';\nexport const name = AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE; // for backwards compatibility\nmodule(AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'enableServerGroup',\n alias: 'enableAsg',\n cloudProvider: 'azure',\n templateUrl: require('./enableAsgStage.html'),\n executionStepLabelUrl: require('./enableAsgStepLabel.html'),\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('azureEnableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n ctrl.reset = () => {\n ctrl.accountUpdated();\n ctrl.resetSelectedCluster();\n };\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'azure';\n\n if (stage.isNew) {\n // bypass the health check for now; will change this later to ['azureService'] and we will also add back the check for $scope.application.attributes.platformHealthOnly\n stage.interestingHealthProviderNames = [];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.azure) {\n stage.credentials = $scope.application.defaultCredentials.azure;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.azure) {\n stage.regions.push($scope.application.defaultRegions.azure);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n\n $scope.$watch('stage.credentials', $scope.accountUpdated);\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { FirewallLabels, InfrastructureCaches, TaskExecutor } from '@spinnaker/core';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE = 'spinnaker.azure.securityGroup.write.service';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE, [UIROUTER_ANGULARJS]).factory(\n 'azureSecurityGroupWriter',\n function () {\n function upsertSecurityGroup(securityGroup, application, descriptor, params = {}) {\n params.securityGroupName = securityGroup.name;\n\n // We want to extend params with all attributes from securityGroup, but only if they don't already exist.\n _.assignWith(params, securityGroup, function (value, other) {\n return _.isUndefined(value) ? other : value;\n });\n\n const operation = TaskExecutor.executeTask({\n job: [params],\n application: application,\n description: `${descriptor} ${FirewallLabels.get('Firewall')}: ${name}`,\n });\n\n InfrastructureCaches.clearCache('securityGroup');\n\n return operation;\n }\n\n function deleteSecurityGroup(securityGroup, application, params = {}) {\n params.type = 'deleteSecurityGroup';\n params.securityGroupName = securityGroup.name;\n params.regions = [securityGroup.region];\n params.credentials = securityGroup.accountId;\n //params.cloudProvider = securityGroup.providerType;\n params.appName = application.name;\n\n const operation = TaskExecutor.executeTask({\n job: [params],\n application: application,\n description: `Delete ${FirewallLabels.get('Firewalls')}: ${securityGroup.name}`,\n });\n\n InfrastructureCaches.clearCache('securityGroup');\n\n return operation;\n }\n\n return {\n deleteSecurityGroup: deleteSecurityGroup,\n upsertSecurityGroup: upsertSecurityGroup,\n };\n },\n);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, FirewallLabels, NetworkReader, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL = 'spinnaker.azure.securityGroup.create.controller';\nexport const name = AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL, [\n UIROUTER_ANGULARJS,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n]).controller('azureCreateSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n '$controller',\n 'application',\n 'securityGroup',\n 'azureSecurityGroupWriter',\n function ($scope, $uibModalInstance, $state, $controller, application, securityGroup, azureSecurityGroupWriter) {\n $scope.pages = {\n location: require('./createSecurityGroupProperties.html'),\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n $scope.regions = [];\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n const ctrl = this;\n $scope.isNew = true;\n $scope.state = {\n submitting: false,\n infiniteScroll: {\n numToAdd: 20,\n currentItems: 20,\n },\n };\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n ctrl.accountUpdated();\n });\n\n ctrl.addMoreItems = function () {\n $scope.state.infiniteScroll.currentItems += $scope.state.infiniteScroll.numToAdd;\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.regions[0],\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Creating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n $scope.securityGroup = securityGroup;\n\n ctrl.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.securityGroup.credentials).then(function (regions) {\n $scope.regions = regions;\n $scope.securityGroup.regions = regions;\n ctrl.updateName();\n ctrl.regionUpdated();\n });\n };\n\n this.regionUpdated = function () {\n ctrl.vnetUpdated();\n };\n\n this.vnetUpdated = function () {\n const account = $scope.securityGroup.credentials;\n const region = $scope.securityGroup.region;\n $scope.securityGroup.selectedVnet = null;\n $scope.securityGroup.vnet = null;\n $scope.securityGroup.vnetResourceGroup = null;\n\n ctrl.selectedVnets = [];\n\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((vnet) => {\n if (vnet.account === account && vnet.region === region) {\n ctrl.selectedVnets.push(vnet);\n }\n });\n }\n });\n\n ctrl.subnetUpdated();\n };\n\n this.subnetUpdated = function () {\n $scope.securityGroup.selectedSubnet = null;\n $scope.securityGroup.subnet = null;\n ctrl.selectedSubnets = [];\n };\n\n this.selectedVnetChanged = function (item) {\n $scope.securityGroup.vnet = item.name;\n $scope.securityGroup.vnetResourceGroup = item.resourceGroup;\n $scope.securityGroup.selectedSubnet = null;\n $scope.securityGroup.subnet = null;\n ctrl.selectedSubnets = [];\n if (item.subnets) {\n item.subnets.map(function (subnet) {\n ctrl.selectedSubnets.push(subnet);\n });\n }\n };\n\n ctrl.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n ctrl.updateName = function () {\n const securityGroup = $scope.securityGroup;\n let name = application.name;\n if (securityGroup.detail) {\n name += '-' + securityGroup.detail;\n }\n securityGroup.name = name;\n $scope.namePreview = name;\n };\n\n ctrl.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n vpcId: 'null',\n };\n\n if ($scope.securityGroup.selectedVnet) {\n $scope.securityGroup.vnet = $scope.securityGroup.selectedVnet.name;\n $scope.securityGroup.vnetResourceGroup = $scope.securityGroup.selectedVnet.resourceGroup;\n }\n\n if ($scope.securityGroup.selectedSubnet) {\n $scope.securityGroup.subnet = $scope.securityGroup.selectedSubnet.name;\n }\n\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Create', params);\n });\n };\n\n ctrl.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length == 0 ? 100 : 100 * (ruleset.length + 1),\n protocolUI: 'tcp',\n protocol: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourceAddressPrefixes: [],\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '*',\n destinationPortRanges: [],\n destPortRanges: '*',\n sourceIPCIDRRanges: '*',\n });\n };\n\n ctrl.portUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].destPortRanges)) {\n const ruleRanges = ruleset[index].destPortRanges.split(',');\n\n if (ruleRanges.length > 1) {\n ruleset[index].destinationPortRanges = [];\n ruleRanges.forEach((v) => ruleset[index].destinationPortRanges.push(v));\n\n // If there are multiple port ranges then set null to the single port parameter otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRange = null;\n } else {\n ruleset[index].destinationPortRange = ruleset[index].destPortRanges;\n\n // If there is a single port range then set null to the port array otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRanges = [];\n }\n }\n };\n\n ctrl.sourceIPCIDRUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].destPortRanges)) {\n const ruleRanges = ruleset[index].sourceIPCIDRRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].sourceAddressPrefixes = [];\n ruleRanges.forEach((v) => ruleset[index].sourceAddressPrefixes.push(v));\n\n // If there are multiple IP/CIDR ranges then set null to the single sourceAddressPrefix parameter otherwise ARM template will fail in validation\n ruleset[index].sourceAddressPrefix = null;\n } else {\n ruleset[index].sourceAddressPrefix = ruleset[index].sourceIPCIDRRanges;\n\n // If there is a single IP/CIDR then set null to the IP/CIDR array otherwise ARM template will fail in validation.\n ruleset[index].sourceAddressPrefixes = [];\n }\n }\n };\n\n ctrl.protocolUpdated = function (ruleset, index) {\n ruleset[index].protocol = ruleset[index].protocolUI;\n };\n\n ctrl.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n ctrl.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n ctrl.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n $scope.securityGroup.securityRules = [];\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n CACHE_INITIALIZER_SERVICE,\n FirewallLabels,\n InfrastructureCaches,\n SECURITY_GROUP_READER,\n TaskMonitor,\n} from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL =\n 'spinnaker.azure.securityGroup.azure.edit.controller';\nexport const name = AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL, [\n UIROUTER_ANGULARJS,\n CACHE_INITIALIZER_SERVICE,\n SECURITY_GROUP_READER,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n]).controller('azureEditSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$exceptionHandler',\n '$state',\n 'securityGroupReader',\n 'cacheInitializer',\n 'application',\n 'securityGroup',\n 'azureSecurityGroupWriter',\n function (\n $scope,\n $uibModalInstance,\n $exceptionHandler,\n $state,\n securityGroupReader,\n cacheInitializer,\n application,\n securityGroup,\n azureSecurityGroupWriter,\n ) {\n $scope.pages = {\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n securityGroup.securityRules = _.map(securityGroup.securityRules, function (rule) {\n if (!_.isEmpty(rule.protocol)) {\n rule.protocolUI = rule.protocol.toLowerCase();\n }\n\n rule.destPortRanges = rule.destinationPortRangeModel;\n rule.sourceIPCIDRRanges = rule.sourceAddressPrefixModel;\n\n return rule;\n });\n\n $scope.securityGroup = securityGroup;\n\n $scope.state = {\n refreshingSecurityGroups: false,\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Updating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n this.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n this.refreshSecurityGroups = function () {\n $scope.state.refreshingSecurityGroups = true;\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n initializeSecurityGroups().then(function () {\n $scope.state.refreshingSecurityGroups = false;\n });\n });\n };\n\n function initializeSecurityGroups() {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n const account = securityGroup.accountName;\n const region = securityGroup.region;\n const availableGroups = _.filter(securityGroups[account].azure[region], {\n /*vpcId: vpcId*/\n });\n $scope.availableSecurityGroups = _.map(availableGroups, 'name');\n });\n }\n\n this.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length === 0 ? 100 : 100 * (ruleset.length + 1),\n protocolUI: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourceAddressPrefixes: [],\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '*',\n destinationPortRanges: [],\n destPortRanges: '*',\n sourceIPCIDRRanges: '*',\n });\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.region,\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n this.portUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].sourceIPCIDRRanges)) {\n const ruleRanges = ruleset[index].destPortRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].destinationPortRanges = [];\n ruleRanges.forEach((v) => ruleset[index].destinationPortRanges.push(v));\n\n // If there are multiple port ranges then set null to the single port parameter otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRange = null;\n } else {\n ruleset[index].destinationPortRange = ruleset[index].destPortRanges;\n\n // If there is a single port range then set null to the port array otherwise ARM template will fail in validation.\n ruleset[index].destinationPortRanges = [];\n }\n }\n };\n\n this.sourceIPCIDRUpdated = function (ruleset, index) {\n if (!_.isEmpty(ruleset[index].sourceIPCIDRRanges)) {\n const ruleRanges = ruleset[index].sourceIPCIDRRanges.split(',');\n if (ruleRanges.length > 1) {\n ruleset[index].sourceAddressPrefixes = [];\n ruleRanges.forEach((v) => ruleset[index].sourceAddressPrefixes.push(v));\n\n // If there are multiple IP/CIDR ranges then set null to the single sourceAddressPrefix parameter otherwise ARM template will fail in validation\n ruleset[index].sourceAddressPrefix = null;\n } else {\n ruleset[index].sourceAddressPrefix = ruleset[index].sourceIPCIDRRanges;\n\n // If there is a single IP/CIDR then set null to the IP/CIDR array otherwise ARM template will fail in validation.\n ruleset[index].sourceAddressPrefixes = [];\n }\n }\n };\n\n this.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n this.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n this.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n $scope.taskMonitor.onTaskComplete = $uibModalInstance.dismiss;\n\n this.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n subnet: null,\n vpcId: 'null',\n };\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Update', params);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, FirewallLabels, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL } from '../configure/CreateSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER = 'spinnaker.azure.securityGroup.clone.controller';\nexport const name = AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER, [\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL,\n]).controller('azureCloneSecurityGroupController', [\n '$scope',\n '$uibModalInstance',\n '$controller',\n '$state',\n 'azureSecurityGroupWriter',\n 'securityGroup',\n 'application',\n function ($scope, $uibModalInstance, $controller, $state, azureSecurityGroupWriter, securityGroup, application) {\n const ctrl = this;\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n $scope.pages = {\n location: require('../configure/createSecurityGroupProperties.html'),\n ingress: require('../configure/createSecurityGroupIngress.html'),\n };\n\n securityGroup.securityRules = _.map(securityGroup.securityRules, function (rule) {\n const temp = rule.destinationPortRange.split('-');\n rule.startPort = Number(temp[0]);\n rule.endPort = Number(temp[1]);\n return rule;\n });\n\n ctrl.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.securityGroup.credentials).then(function (regions) {\n $scope.regions = regions;\n $scope.securityGroup.regions = regions;\n ctrl.updateName();\n });\n };\n\n ctrl.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n ctrl.updateName = function () {\n const securityGroup = $scope.securityGroup;\n let name = application.name;\n if (securityGroup.detail) {\n name += '-' + securityGroup.detail;\n }\n securityGroup.name = name;\n $scope.namePreview = name;\n };\n\n $scope.securityGroup = securityGroup;\n\n $scope.state = {\n refreshingSecurityGroups: false,\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Updating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n AccountService.listAccounts('azure').then(function (accounts) {\n $scope.accounts = accounts;\n ctrl.accountUpdated();\n });\n\n ctrl.addRule = function (ruleset) {\n ruleset.push({\n name: $scope.securityGroup.name + '-Rule' + ruleset.length,\n priority: ruleset.length === 0 ? 100 : 100 * (ruleset.length + 1),\n protocol: 'tcp',\n access: 'Allow',\n direction: 'InBound',\n sourceAddressPrefix: '*',\n sourcePortRange: '*',\n destinationAddressPrefix: '*',\n destinationPortRange: '7001-7001',\n startPort: 7001,\n endPort: 7001,\n });\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: $scope.securityGroup.region,\n provider: 'azure',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n ctrl.portUpdated = function (ruleset, index) {\n ruleset[index].destinationPortRange = ruleset[index].startPort + '-' + ruleset[index].endPort;\n };\n ctrl.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n ctrl.moveUp = function (ruleset, index) {\n if (index === 0) return;\n swapRules(ruleset, index, index - 1);\n };\n ctrl.moveDown = function (ruleset, index) {\n if (index === ruleset.length - 1) return;\n swapRules(ruleset, index, index + 1);\n };\n function swapRules(ruleset, a, b) {\n const temp = ruleset[b];\n const priorityA = ruleset[a].priority;\n const priorityB = ruleset[b].priority;\n //swap elements\n ruleset[b] = ruleset[a];\n ruleset[a] = temp;\n //swap priorities\n ruleset[a].priority = priorityA;\n ruleset[b].priority = priorityB;\n }\n\n ctrl.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const params = {\n cloudProvider: 'azure',\n appName: application.name,\n region: $scope.securityGroup.region,\n subnet: 'none',\n vpcId: 'null',\n };\n $scope.securityGroup.type = 'upsertSecurityGroup';\n\n return azureSecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Clone', params);\n });\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { ConfirmationModalService, FirewallLabels, SECURITY_GROUP_READER } from '@spinnaker/core';\n\nimport { AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER } from '../clone/cloneSecurityGroup.controller';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE } from '../securityGroup.write.service';\n\nexport const AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER =\n 'spinnaker.azure.securityGroup.azure.details.controller';\nexport const name = AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER, [\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n AZURE_SECURITYGROUP_SECURITYGROUP_WRITE_SERVICE,\n AZURE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER,\n ])\n .controller('azureSecurityGroupDetailsCtrl', [\n '$scope',\n '$state',\n 'resolvedSecurityGroup',\n 'app',\n 'azureSecurityGroupWriter',\n 'securityGroupReader',\n '$uibModal',\n function ($scope, $state, resolvedSecurityGroup, app, azureSecurityGroupWriter, securityGroupReader, $uibModal) {\n const application = app;\n const securityGroup = resolvedSecurityGroup;\n\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n function extractSecurityGroup() {\n return securityGroupReader\n .getSecurityGroupDetails(\n application,\n securityGroup.accountId,\n securityGroup.provider,\n securityGroup.region,\n securityGroup.vpcId,\n securityGroup.name,\n )\n .then(\n function (details) {\n $scope.state.loading = false;\n\n if (!details || _.isEmpty(details)) {\n fourOhFour();\n } else {\n $scope.securityGroup = details;\n }\n },\n function () {\n fourOhFour();\n },\n );\n }\n\n function fourOhFour() {\n $state.go('^');\n }\n\n extractSecurityGroup().then(() => {\n // If the user navigates away from the view before the initial extractSecurityGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.securityGroups.onRefresh($scope, extractSecurityGroup);\n }\n });\n\n this.editInboundRules = function editInboundRules() {\n $uibModal.open({\n templateUrl: require('../configure/editSecurityGroup.html'),\n controller: 'azureEditSecurityGroupCtrl as ctrl',\n resolve: {\n securityGroup: function () {\n return angular.copy($scope.securityGroup);\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.cloneSecurityGroup = function cloneSecurityGroup() {\n $uibModal.open({\n templateUrl: require('../clone/cloneSecurityGroup.html'),\n controller: 'azureCloneSecurityGroupController as ctrl',\n resolve: {\n securityGroup: function () {\n const securityGroup = angular.copy($scope.securityGroup);\n if (securityGroup.region) {\n securityGroup.regions = [securityGroup.region];\n }\n return securityGroup;\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.deleteSecurityGroup = function deleteSecurityGroup() {\n const taskMonitor = {\n application: application,\n title: 'Deleting ' + securityGroup.name,\n };\n\n const submitMethod = function () {\n $scope.securityGroup.type = 'deleteSecurityGroup';\n return azureSecurityGroupWriter.deleteSecurityGroup(securityGroup, application, {\n cloudProvider: 'azure',\n vpcId: $scope.securityGroup.vpcId,\n });\n };\n\n ConfirmationModalService.confirm({\n header: 'Really delete ' + securityGroup.name + '?',\n buttonText: 'Delete ' + securityGroup.name,\n account: securityGroup.accountId,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n if (app.isStandalone) {\n // we still want the edit to refresh the firewall details when the modal closes\n app.securityGroups = {\n refresh: extractSecurityGroup,\n };\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_READER = 'spinnaker.azure.securityGroup.reader';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_READER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_READER, []).factory('azureSecurityGroupReader', function () {\n function resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {\n //hack to get around securityGroupId not matching id in indexedSecurityGroups.\n const temp = securityGroupId.split('/');\n return indexedSecurityGroups[container.account][container.region][temp[temp.length - 1]];\n }\n\n return {\n resolveIndexedSecurityGroup: resolveIndexedSecurityGroup,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER = 'spinnaker.azure.securityGroup.transformer';\nexport const name = AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER, []).factory('azureSecurityGroupTransformer', function () {\n function normalizeSecurityGroup() {}\n\n return {\n normalizeSecurityGroup: normalizeSecurityGroup,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER = 'spinnaker.azure.serverGroup.transformer';\nexport const name = AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER, []).factory('azureServerGroupTransformer', function () {\n function normalizeServerGroup(serverGroup) {\n return serverGroup;\n }\n\n function parseCustomScriptsSettings(command, configuration) {\n /*\n At the first time this wizard pops up, the type of command.customScriptsSettings.fileUris is String. As for the following\n occurrences of its pop up with this field unchanged, its type becomes an array. So here differentiate the two scenarios\n to assign the correct value to model.\n */\n if (Array.isArray(command.customScriptsSettings.fileUris)) {\n configuration.customScriptsSettings.fileUris = command.customScriptsSettings.fileUris;\n } else {\n const fileUrisTemp = command.customScriptsSettings.fileUris;\n if (fileUrisTemp.includes(',')) {\n configuration.customScriptsSettings.fileUris = fileUrisTemp.split(',');\n } else if (fileUrisTemp.includes(';')) {\n configuration.customScriptsSettings.fileUris = fileUrisTemp.split(';');\n } else {\n configuration.customScriptsSettings.fileUris = [fileUrisTemp];\n }\n\n configuration.customScriptsSettings.fileUris.forEach(function (v, index) {\n configuration.customScriptsSettings.fileUris[index] = v.trim();\n });\n }\n }\n\n function convertServerGroupCommandToDeployConfiguration(command) {\n let tempImage;\n\n if (command.viewState.mode === 'editPipeline' || command.viewState.mode === 'createPipeline') {\n tempImage = {\n imageName: '',\n isCustom: 'true',\n publisher: '',\n offer: '',\n sku: '',\n version: '',\n region: command.region,\n uri: '',\n ostype: '',\n };\n } else {\n tempImage = command.selectedImage;\n }\n\n const configuration = {\n name: command.application,\n cloudProvider: command.selectedProvider,\n application: command.application,\n stack: command.stack,\n strategy: command.strategy,\n rollback: {\n onFailure: command.rollback ? command.rollback.onFailure : null,\n },\n scaleDown: command.scaleDown,\n maxRemainingAsgs: command.maxRemainingAsgs,\n delayBeforeDisableSec: command.delayBeforeDisableSec,\n delayBeforeScaleDownSec: command.delayBeforeScaleDownSec,\n allowDeleteActive: command.strategy === 'redblack' ? true : null,\n allowScaleDownActive: command.strategy === 'redblack' ? true : null,\n detail: command.freeFormDetails,\n freeFormDetails: command.freeFormDetails,\n healthSettings: command.healthSettings,\n image: command.image,\n account: command.credentials,\n selectedProvider: 'azure',\n vnet: command.vnet,\n vnetResourceGroup: command.selectedVnet.resourceGroup,\n subnet: command.subnet,\n useSourceCapacity: false,\n capacity: {\n min: command.sku.capacity,\n max: command.sku.capacity,\n },\n credentials: command.credentials,\n region: command.region,\n securityGroupName: command.securityGroupName,\n loadBalancerName: command.loadBalancerName,\n loadBalancerType: command.loadBalancerType,\n user: '[anonymous]',\n upgradePolicy: 'Manual',\n type: 'createServerGroup',\n sku: {\n name: 'Standard_DS1_v2',\n tier: 'Standard',\n capacity: command.sku.capacity,\n },\n instanceTags: command.instanceTags,\n dataDisks: command.dataDisks,\n userAssignedIdentities: command.userAssignedIdentities,\n viewState: command.viewState,\n osConfig: {\n customData: command.osConfig ? command.osConfig.customData : null,\n },\n customScriptsSettings: {\n fileUris: null,\n commandToExecute: '',\n },\n zonesEnabled: command.zonesEnabled,\n zones: command.zonesEnabled ? command.zones : [],\n enableInboundNAT: command.enableInboundNAT,\n };\n\n if (command.image == null || command.image.isCustom == false) {\n configuration.image = tempImage;\n }\n\n if (typeof command.stack !== 'undefined') {\n configuration.name = configuration.name + '-' + command.stack;\n }\n if (typeof command.freeFormDetails !== 'undefined') {\n configuration.name = configuration.name + '-' + command.freeFormDetails;\n }\n\n if (typeof command.customScriptsSettings !== 'undefined') {\n configuration.customScriptsSettings.commandToExecute = command.customScriptsSettings.commandToExecute;\n if (!_.isEmpty(command.customScriptsSettings.fileUris)) {\n parseCustomScriptsSettings(command, configuration);\n }\n }\n\n if (command.instanceType) {\n const vmsku = command.instanceType;\n configuration.instanceType = command.instanceType;\n configuration.sku.name = vmsku;\n configuration.sku.tier = vmsku.substring(0, vmsku.indexOf('_'));\n }\n\n // Default to an empty list of health provider names for now.\n configuration.interestingHealthProviderNames = [];\n\n return configuration;\n }\n\n return {\n convertServerGroupCommandToDeployConfiguration: convertServerGroupCommandToDeployConfiguration,\n normalizeServerGroup: normalizeServerGroup,\n parseCustomScriptsSettings: parseCustomScriptsSettings,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.instanceArchetype.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER, []).controller(\n 'azureInstanceArchetypeCtrl',\n [\n '$scope',\n 'instanceTypeService',\n 'modalWizardService',\n function ($scope, instanceTypeService, modalWizardService) {\n const wizard = modalWizardService.getWizard();\n\n $scope.$watch('command.viewState.instanceProfile', function () {\n if (!$scope.command.viewState.instanceProfile || $scope.command.viewState.instanceProfile === 'custom') {\n wizard.excludePage('instance-type');\n } else {\n wizard.includePage('instance-type');\n wizard.markClean('instance-profile');\n wizard.markComplete('instance-profile');\n }\n });\n\n $scope.$watch('command.viewState.instanceType', function (newVal) {\n if (newVal) {\n wizard.markClean('instance-profile');\n wizard.markComplete('instance-profile');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.instanceType.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER, []).controller('azureInstanceTypeCtrl', [\n '$scope',\n 'modalWizardService',\n function ($scope, modalWizardService) {\n modalWizardService.getWizard().markComplete('instance-type');\n modalWizardService.getWizard().markClean('instance-type');\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.advancedSetting.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupAdvancedSettingsCtrl',\n [\n '$scope',\n 'modalWizardService',\n function ($scope, modalWizardService) {\n modalWizardService.getWizard().markComplete('advanced');\n\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n modalWizardService.getWizard().markClean('advanced');\n } else {\n modalWizardService.getWizard().markDirty('advanced');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport * as angular from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.advancedSettings.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE, [])\n .directive('azureServerGroupAdvancedSettingsSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./advancedSettingsSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'adv',\n controller: 'azureServerGroupAdvancedSettingsSelectorCtrl',\n };\n })\n .controller('azureServerGroupAdvancedSettingsSelectorCtrl', function () {\n this.addDataDisk = () => {\n const newDataDisks = angular.copy(this.command.dataDisks);\n this.command.dataDisks = newDataDisks.concat([\n {\n lun: 0,\n managedDisk: {\n storageAccountType: 'Standard_LRS',\n },\n diskSizeGB: 1,\n caching: 'None',\n createOption: 'Empty',\n },\n ]);\n };\n\n this.removeDataDisk = (index) => {\n const newDataDisks = angular.copy(this.command.dataDisks);\n newDataDisks.splice(index, 1);\n this.command.dataDisks = newDataDisks;\n };\n });\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER =\n 'spinnaker.azure.serverGroup.configure.basicSettings.image.filter';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER, []).filter('regional', function () {\n return function (input, selectedRegion) {\n return _.filter(input, function (image) {\n return image.region === selectedRegion || image.region === null;\n });\n };\n});\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { IMAGE_READER, ModalWizard } from '@spinnaker/core';\n\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER } from './image.regional.filter';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.basicSettings';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER, [\n UIROUTER_ANGULARJS,\n ANGULAR_UI_BOOTSTRAP,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_IMAGE_REGIONAL_FILTER,\n IMAGE_READER,\n ])\n .controller('azureServerGroupBasicSettingsCtrl', [\n '$scope',\n '$controller',\n '$uibModalStack',\n '$state',\n 'imageReader',\n function ($scope, $controller, $uibModalStack, $state, imageReader) {\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n ModalWizard.markClean('basic-settings');\n ModalWizard.markComplete('basic-settings');\n } else {\n ModalWizard.markIncomplete('basic-settings');\n }\n });\n\n this.imageChanged = (image) => {\n $scope.command.imageName = image.imageName;\n $scope.command.selectedImage = image;\n ModalWizard.markClean('basic-settings');\n };\n\n angular.extend(\n this,\n $controller('BasicSettingsMixin', {\n $scope: $scope,\n imageReader: imageReader,\n $uibModalStack: $uibModalStack,\n $state: $state,\n }),\n );\n\n this.stackPattern = {\n test: function (stack) {\n const pattern = $scope.command.viewState.templatingEnabled ? /^([a-zA-Z0-9]*(\\${.+})*)*$/ : /^[a-zA-Z0-9]*$/;\n\n return pattern.test(stack);\n },\n };\n\n this.detailPattern = {\n test: function (detail) {\n const pattern = $scope.command.viewState.templatingEnabled\n ? /^([a-zA-Z0-9-]*(\\${.+})*)*$/\n : /^[a-zA-Z0-9-]*$/;\n\n return pattern.test(detail);\n },\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.capacity.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE, [])\n .directive('azureServerGroupCapacitySelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./capacitySelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'cap',\n controller: 'azureServerGroupCapacitySelectorCtrl',\n };\n })\n .controller('azureServerGroupCapacitySelectorCtrl', function () {});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.healthSetting.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupHealthSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n if (typeof $scope.command.healthSettings === 'undefined') {\n $scope.command.healthSettings = {};\n }\n\n this.healthCheckProtocols = [\n { displayName: 'N/A', name: null },\n { displayName: 'HTTP', name: 'http' },\n { displayName: 'TCP', name: 'tcp' },\n ];\n\n this.requiresHealthCheckPath = function () {\n return $scope.command.healthSettings.protocol === 'http';\n };\n\n this.changeHealthCheckProtocol = function (newProtocol) {\n if (newProtocol == null) {\n $scope.command.healthSettings.protocol = null;\n $scope.command.healthSettings.port = null;\n $scope.command.healthSettings.requestPath = null;\n } else if (!this.requiresHealthCheckPath()) {\n $scope.command.healthSettings.requestPath = null;\n }\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.healthSettings.selector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupHealthSettingsSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n templateUrl: require('./healthSettingsSelector.directive.html'),\n scope: {\n command: '=',\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.imageSettings.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupImageSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n this.clearImage = function () {\n if ($scope.command.image.isCustom == false) {\n $scope.command.image = { isCustom: false };\n } else {\n $scope.command.image.region = $scope.command.region;\n }\n };\n\n ModalWizard.markComplete('image-settings');\n\n $scope.$watch('form.$valid', function (newVal) {\n if (newVal) {\n ModalWizard.markClean('image-settings');\n } else {\n ModalWizard.markDirty('image-settings');\n }\n });\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.imageSettingsSelector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE, []).directive(\n 'azureServerGroupImageSettingsSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n templateUrl: require('./imageSettingsSelector.directive.html'),\n scope: {\n command: '=',\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { InfrastructureCaches, LOAD_BALANCER_READ_SERVICE, ModalWizard, NetworkReader } from '@spinnaker/core';\n\nimport Utility from '../../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.loadBalancer.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER, [\n LOAD_BALANCER_READ_SERVICE,\n]).controller('azureServerGroupLoadBalancersCtrl', [\n '$scope',\n 'loadBalancerReader',\n function ($scope, loadBalancerReader) {\n ModalWizard.markClean('load-balancers');\n\n function loadVnetSubnets(item, type) {\n loadBalancerReader\n .getLoadBalancerDetails('azure', $scope.command.credentials, $scope.command.region, item)\n .then(function (LBs) {\n if (!LBs || LBs.length === 0) {\n // load the subnet and vnets without a load balancer\n const attachedVnet = $scope.command.selectedVnet;\n const attachedSubnet = $scope.command.selectedSubnet;\n $scope.command.selectedVnetSubnets = [];\n $scope.command.allVnets = [];\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((selectedVnet) => {\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region\n ) {\n $scope.command.allVnets.push(selectedVnet);\n\n selectedVnet.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n // only add subnets that are not assigned to an ApplicationGateway\n if (device && device.type === 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n $scope.command.selectedVnetSubnets.push(subnet.name);\n if (subnet.name === attachedSubnet) {\n $scope.command.selectedSubnet = attachedSubnet;\n }\n }\n });\n }\n });\n }\n });\n } else if (LBs && LBs.length === 1) {\n const selectedLoadBalancer = LBs[0];\n const attachedVnet = $scope.command.selectedVnet;\n $scope.command.selectedVnet = null;\n $scope.command.selectedVnetSubnets = [];\n $scope.command.allVnets = [];\n NetworkReader.listNetworks().then(function (vnets) {\n if (vnets.azure) {\n vnets.azure.forEach((selectedVnet) => {\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region\n ) {\n $scope.command.allVnets.push(selectedVnet);\n }\n if (\n selectedVnet.account === $scope.command.credentials &&\n selectedVnet.region === $scope.command.region &&\n ((type === 'Azure Application Gateway' && selectedVnet.name == selectedLoadBalancer.vnet) ||\n (type === 'Azure Load Balancer' && selectedVnet.name === attachedVnet.name))\n ) {\n $scope.command.selectedVnet = selectedVnet;\n selectedVnet.subnets.map(function (subnet) {\n let addSubnet = true;\n if (subnet.devices) {\n subnet.devices.map(function (device) {\n // only add subnets that are not assigned to an ApplicationGateway\n if (device && device.type === 'applicationGateways') {\n addSubnet = false;\n }\n });\n }\n if (addSubnet) {\n $scope.command.selectedVnetSubnets.push(subnet.name);\n }\n });\n }\n });\n }\n });\n }\n });\n }\n\n if ($scope.command.credentials && $scope.command.region) {\n $scope.command.viewState.networkSettingsConfigured = true;\n $scope.command.selectedVnetSubnets = [];\n if ($scope.command.loadBalancerName !== null && typeof $scope.command.loadBalancerName !== 'undefined') {\n $scope.useLoadBalancer = true;\n }\n loadVnetSubnets($scope.command.loadBalancerName, $scope.command.loadBalancerType);\n }\n\n this.loadBalancerChanged = function (item) {\n $scope.command.viewState.networkSettingsConfigured = true;\n ModalWizard.markComplete('load-balancers');\n\n const loadBalancers = $scope.command.backingData.loadBalancers;\n let loadBalancerType = null;\n\n if (loadBalancers) {\n const loadBalancerToFind = loadBalancers.find((lb) => lb.name === item);\n if (loadBalancerToFind) {\n loadBalancerType = Utility.getLoadBalancerType(loadBalancerToFind.loadBalancerType).type;\n }\n }\n\n if (item === null) {\n $scope.command.loadBalancerName = null;\n }\n\n $scope.command.selectedVnetSubnets = [];\n $scope.command.loadBalancerType = loadBalancerType;\n InfrastructureCaches.clearCache('networks');\n loadVnetSubnets(item, loadBalancerType);\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.loadBalancer.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupLoadBalancersSelector',\n [\n 'azureServerGroupConfigurationService',\n function () {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./serverGroupLoadBalancersSelector.directive.html'),\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.networkSettings.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER, []).controller(\n 'azureServerGroupNetworkSettingsCtrl',\n [\n '$scope',\n function ($scope) {\n ModalWizard.markClean('network-settings');\n\n $scope.command.selectedVnet = {\n name: $scope.command.vnet,\n };\n\n $scope.command.selectedSubnet = $scope.command.subnet;\n\n this.vnetChanged = function (item) {\n $scope.command.vnet = item;\n $scope.command.subnet = $scope.command.selectedSubnet = null;\n $scope.command.selectedVnetSubnets = item.subnets.map((s) => s.name);\n };\n\n this.networkSettingsChanged = function (item) {\n $scope.command.vnet = $scope.command.selectedVnet.name;\n $scope.command.subnet = item;\n ModalWizard.markComplete('network-settings');\n };\n\n this.getVnetName = function () {\n if ($scope.command.selectedVnet) {\n return $scope.command.selectedVnet.name;\n } else {\n return 'Virtual network was not selected';\n }\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.networkSettings.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupNetworkSettingsSelector',\n function () {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./ServerGroupNetworkSettingsSelector.directive.html'),\n };\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ModalWizard } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER =\n 'spinnaker.azure.serverGroup.configure.securityGroups.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER, []).controller(\n 'azureServerGroupSecurityGroupsCtrl',\n [\n '$scope',\n function ($scope) {\n ModalWizard.markClean('security-groups');\n ModalWizard.markComplete('security-groups');\n\n $scope.command.selectedSecurityGroup = {\n id: $scope.command.securityGroupName,\n };\n\n this.securityGroupChanged = function (securityGroup) {\n $scope.command.securityGroupName = securityGroup.id;\n ModalWizard.markComplete('security-groups');\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { FirewallLabels, InfrastructureCaches } from '@spinnaker/core';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.securityGroupSelector.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE, []).directive(\n 'azureServerGroupSecurityGroupsSelector',\n [\n 'azureServerGroupConfigurationService',\n function (azureServerGroupConfigurationService) {\n return {\n restrict: 'E',\n scope: {\n command: '=',\n },\n templateUrl: require('./serverGroupSecurityGroupsSelector.directive.html'),\n link: function (scope) {\n scope.firewallLabel = FirewallLabels.get('firewall');\n\n scope.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n scope.refreshSecurityGroups = function () {\n scope.refreshing = true;\n azureServerGroupConfigurationService.refreshSecurityGroups(scope.command).then(function () {\n scope.refreshing = false;\n });\n };\n },\n };\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport Utility from '../../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.tags.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE, [])\n .directive('azureTagsSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./tagsSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'tagsSelectorCtrl',\n controller: 'TagsSelectorCtrl',\n };\n })\n .controller('TagsSelectorCtrl', [\n '$scope',\n function () {\n this.getTagResult = function () {\n return Utility.checkTags(this.command.instanceTags);\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE =\n 'spinnaker.azure.serverGroup.configure.wizard.capacity.zone.directive';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE, []).directive('azureZoneSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./zoneSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: [\n '$scope',\n function ($scope) {\n this.updateEnableInboundNAT = () => {\n if ($scope.vm.command.zonesEnabled) {\n $scope.vm.command.enableInboundNAT = false;\n }\n };\n },\n ],\n };\n});\n","import { module } from 'angular';\n\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../serverGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER } from './wizard/ServerGroupInstanceArchetype.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER } from './wizard/ServerGroupInstanceType.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER } from './wizard/advancedSettings/ServerGroupAdvancedSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE } from './wizard/advancedSettings/advancedSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER } from './wizard/basicSettings/ServerGroupBasicSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE } from './wizard/capacity/capacitySelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER } from './wizard/healthSettings/ServerGroupHealthSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE } from './wizard/healthSettings/healthSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER } from './wizard/image/ServerGroupImageSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE } from './wizard/image/imageSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER } from './wizard/loadBalancers/ServerGroupLoadBalancers.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE } from './wizard/loadBalancers/serverGroupLoadBalancersSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER } from './wizard/networkSettings/ServerGroupNetworkSettings.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE } from './wizard/networkSettings/ServerGroupNetworkSettingsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER } from './wizard/securityGroup/ServerGroupSecurityGroups.controller';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE } from './wizard/securityGroup/serverGroupSecurityGroupsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE } from './wizard/tags/tagsSelector.directive';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE } from './wizard/zones/zoneSelector.directive';\n\n('use strict');\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE = 'spinnaker.azure.serverGroup.configure';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE, [\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_BASICSETTINGS_SERVERGROUPBASICSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCEARCHETYPE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SERVERGROUPINSTANCETYPE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_SERVERGROUPADVANCEDSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_HEALTHSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_IMAGESETTINGS_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_IMAGESETTINGS_SERVERGROUPIMAGESETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_HEALTHSETTINGS_SERVERGROUPHEALTHSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_SERVERGROUPLOADBALANCERSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_CAPACITYSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUP_SERVERGROUPSECURITYGROUPSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGS_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_NETWORKSETTINGS_SERVERGROUPNETWORKSETTINGSSELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_TAGS_TAGSSELECTOR_DIRECTIVE,\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n AccountService,\n CACHE_INITIALIZER_SERVICE,\n LOAD_BALANCER_READ_SERVICE,\n SECURITY_GROUP_READER,\n} from '@spinnaker/core';\nimport { AZURE_IMAGE_IMAGE_READER } from '../../image/image.reader';\nimport { AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE } from '../../instance/azureInstanceType.service';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE =\n 'spinnaker.azure.serverGroup.configure.service';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE, [\n AZURE_IMAGE_IMAGE_READER,\n LOAD_BALANCER_READ_SERVICE,\n SECURITY_GROUP_READER,\n CACHE_INITIALIZER_SERVICE,\n AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE,\n ])\n .factory('azureServerGroupConfigurationService', [\n '$q',\n 'azureImageReader',\n 'securityGroupReader',\n 'cacheInitializer',\n 'loadBalancerReader',\n 'azureInstanceTypeService',\n function (\n $q,\n azureImageReader,\n securityGroupReader,\n cacheInitializer,\n loadBalancerReader,\n azureInstanceTypeService,\n ) {\n const dataDiskTypes = ['Standard_LRS', 'StandardSSD_LRS', 'Premium_LRS'];\n const dataDiskCachingTypes = ['None', 'ReadOnly', 'ReadWrite'];\n\n const healthCheckTypes = ['EC2', 'ELB'];\n const terminationPolicies = [\n 'OldestInstance',\n 'NewestInstance',\n 'OldestLaunchConfiguration',\n 'ClosestToNextInstanceHour',\n 'Default',\n ];\n\n function configureUpdateCommand(command) {\n command.backingData = {\n healthCheckTypes: angular.copy(healthCheckTypes),\n terminationPolicies: angular.copy(terminationPolicies),\n };\n }\n\n function configureCommand(application, command) {\n return $q\n .all([\n AccountService.getCredentialsKeyedByAccount('azure'),\n securityGroupReader.loadSecurityGroups(),\n loadBalancerReader.loadLoadBalancers(application.name),\n ])\n .then(function ([credentialsKeyedByAccount, securityGroups, loadBalancers]) {\n command.backingData = {\n credentialsKeyedByAccount,\n securityGroups,\n loadBalancers,\n dataDiskTypes: angular.copy(dataDiskTypes),\n dataDiskCachingTypes: angular.copy(dataDiskCachingTypes),\n accounts: _.keys(credentialsKeyedByAccount),\n filtered: {},\n };\n attachEventHandlers(command);\n });\n }\n\n function configureInstanceTypes(command) {\n const result = {\n dirty: {},\n };\n if (command.region) {\n const results = [result.dirty];\n\n // results.push(configureCustomInstanceTypes(command).dirty);\n results.push(configureStandardInstanceTypes(command).dirty);\n\n angular.extend(...results);\n } else {\n command.backingData.filtered.instanceTypes = [];\n }\n return result;\n }\n\n function configureStandardInstanceTypes(command) {\n const c = command;\n const result = {\n dirty: {},\n };\n\n const locations = [c.region];\n const { credentialsKeyedByAccount } = c.backingData;\n const { locationToInstanceTypesMap } = credentialsKeyedByAccount[c.credentials];\n\n if (locations.every((l) => !l)) {\n return result;\n }\n\n const filtered = azureInstanceTypeService\n .getAvailableTypesForRegions(locationToInstanceTypesMap, locations)\n .map((type) => type.name);\n\n const instanceType = c.instanceType;\n if (_.every([instanceType, !_.startsWith(instanceType, 'custom'), !_.includes(filtered, instanceType)])) {\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n c.backingData.filtered.instanceTypes = filtered;\n return result;\n }\n\n function configureImages(command) {\n const result = {\n dirty: {},\n };\n let regionalImages = null;\n if (command.viewState.disableImageSelection) {\n return result;\n }\n if (command.region) {\n regionalImages = command.backingData.packageImages\n .filter(function (image) {\n return image.amis && image.amis[command.region];\n })\n .map(function (image) {\n return {\n imageName: image.imageName,\n ami: image.amis ? image.amis[command.region][0] : null,\n };\n });\n if (\n command.amiName &&\n !regionalImages.some(function (image) {\n return image.imageName === command.amiName;\n })\n ) {\n result.dirty.amiName = true;\n command.amiName = null;\n }\n } else {\n command.amiName = null;\n }\n command.backingData.filtered.images = regionalImages;\n return result;\n }\n\n function configureZones(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (!command.region) {\n return result;\n }\n let { regionsSupportZones, availabilityZones } = command.backingData.credentialsKeyedByAccount[\n command.credentials\n ];\n regionsSupportZones = regionsSupportZones || [];\n availabilityZones = availabilityZones || [];\n filteredData.zones = regionsSupportZones.includes(command.region) ? availabilityZones : [];\n\n return result;\n }\n\n function getRegionalSecurityGroups(command) {\n const newSecurityGroups = command.backingData.securityGroups[command.credentials] || {\n azure: {},\n };\n return _.chain(newSecurityGroups[command.region]).sortBy('name').value();\n }\n\n function configureSecurityGroupOptions(command) {\n const result = {\n dirty: {},\n };\n let currentOptions;\n if (command.backingData.filtered.securityGroups) {\n currentOptions = command.backingData.filtered.securityGroups;\n }\n const newRegionalSecurityGroups = getRegionalSecurityGroups(command);\n if (command.selectedSecurityGroup) {\n // one has not been previously selected. We are either configuring for the\n //first time or they changed regions or account\n command.selectedSecurityGroup = null;\n result.dirty.securityGroups = true;\n }\n if (currentOptions != newRegionalSecurityGroups) {\n command.backingData.filtered.securityGroups = newRegionalSecurityGroups;\n result.dirty.securityGroups = true;\n }\n\n if (command.backingData.filtered.securityGroups === []) {\n command.viewState.securityGroupsConfigured = false;\n } else {\n command.viewState.securityGroupsConfigured = true;\n }\n\n return result;\n }\n\n function refreshSecurityGroups(command, skipCommandReconfiguration) {\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n command.backingData.securityGroups = securityGroups;\n if (!skipCommandReconfiguration) {\n configureSecurityGroupOptions(command);\n }\n });\n });\n }\n\n function getLoadBalancerNames(loadBalancers) {\n return _.chain(loadBalancers).map('name').uniq().value().sort();\n }\n\n function configureLoadBalancerOptions(command) {\n const result = {\n dirty: {},\n };\n const current = command.loadBalancers;\n const newLoadBalancers = getLoadBalancerNames(command.backingData.loadBalancers);\n\n if (current && command.loadBalancers) {\n const matched = _.intersection(newLoadBalancers, command.loadBalancers);\n const removed = _.xor(matched, current);\n command.loadBalancers = matched;\n if (removed.length) {\n result.dirty.loadBalancers = removed;\n }\n }\n command.backingData.filtered.loadBalancers = newLoadBalancers;\n return result;\n }\n\n function refreshLoadBalancers(command, skipCommandReconfiguration) {\n return loadBalancerReader.listLoadBalancers('azure').then(function (loadBalancers) {\n command.backingData.loadBalancers = loadBalancers;\n if (!skipCommandReconfiguration) {\n configureLoadBalancerOptions(command);\n }\n });\n }\n\n function configureLoadBalancers(command) {\n const result = {\n dirty: {},\n };\n const temp = command.backingData.loadBalancers;\n const filterlist = _.filter(temp, function (lb) {\n return lb.account === command.credentials && lb.region === command.region;\n });\n\n command.loadBalancers = getLoadBalancerNames(filterlist);\n command.viewState.loadBalancersConfigured = true;\n\n return result;\n }\n\n function attachEventHandlers(cmd) {\n cmd.regionChanged = function regionChanged(command, isInit = false) {\n const result = {\n dirty: {},\n };\n if (command.region && command.credentials) {\n angular.extend(result.dirty, configureLoadBalancers(command).dirty);\n angular.extend(result.dirty, configureSecurityGroupOptions(command).dirty);\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n angular.extend(result.dirty, configureZones(command).dirty);\n }\n // reset previous set values\n if (!isInit) {\n command.loadBalancerName = null;\n command.loadBalancerType = null;\n command.vnet = null;\n command.vnetResourceGroup = null;\n command.subnet = null;\n command.selectedSubnet = null;\n command.selectedVnet = null;\n command.selectedVnetSubnets = [];\n command.viewState.networkSettingsConfigured = false;\n command.selectedSecurityGroup = null;\n command.securityGroupName = null;\n command.zonesEnabled = false;\n command.zones = [];\n }\n\n return result;\n };\n\n cmd.credentialsChanged = function credentialsChanged(command, isInit) {\n const result = {\n dirty: {},\n };\n const backingData = command.backingData;\n if (command.credentials) {\n const regionsForAccount = backingData.credentialsKeyedByAccount[command.credentials] || {\n regions: [],\n defaultKeyPair: null,\n };\n backingData.filtered.regions = regionsForAccount.regions;\n if (\n !_.chain(backingData.filtered.regions)\n .some({\n name: command.region,\n })\n .value()\n ) {\n command.region = null;\n result.dirty.region = true;\n } else {\n angular.extend(result.dirty, command.regionChanged(command, isInit).dirty);\n }\n if (command.region) {\n angular.extend(result.dirty, configureLoadBalancers(command).dirty);\n }\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n } else {\n command.region = null;\n }\n return result;\n };\n }\n\n function refreshInstanceTypes(command) {\n return cacheInitializer.refreshCache('instanceTypes').then(function () {\n return azureInstanceTypeService.getAllTypesByRegion().then(function (instanceTypes) {\n command.backingData.instanceTypes = instanceTypes;\n configureInstanceTypes(command);\n });\n });\n }\n\n return {\n configureUpdateCommand: configureUpdateCommand,\n configureCommand: configureCommand,\n configureImages: configureImages,\n configureSecurityGroupOptions: configureSecurityGroupOptions,\n configureLoadBalancerOptions: configureLoadBalancerOptions,\n refreshLoadBalancers: refreshLoadBalancers,\n refreshSecurityGroups: refreshSecurityGroups,\n getRegionalSecurityGroups: getRegionalSecurityGroups,\n refreshInstanceTypes: refreshInstanceTypes,\n configureZones: configureZones,\n };\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { FirewallLabels, ModalWizard, SERVER_GROUP_WRITER, TaskMonitor } from '@spinnaker/core';\n\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../../serverGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE } from '../serverGroupConfiguration.service';\nimport Utility from '../../../utility';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER =\n 'spinnaker.azure.cloneServerGroup.controller';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n SERVER_GROUP_WRITER,\n]).controller('azureCloneServerGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$q',\n '$state',\n 'serverGroupWriter',\n 'azureServerGroupConfigurationService',\n 'serverGroupCommand',\n 'application',\n 'title',\n function (\n $scope,\n $uibModalInstance,\n $q,\n $state,\n serverGroupWriter,\n azureServerGroupConfigurationService,\n serverGroupCommand,\n application,\n title,\n ) {\n $scope.pages = {\n templateSelection: require('./templateSelection.html'),\n basicSettings: require('./basicSettings/basicSettings.html'),\n imageSettings: require('./image/imageSettings.html'),\n healthSettings: require('./healthSettings/healthSettings.html'),\n loadBalancers: require('./loadBalancers/loadBalancers.html'),\n networkSettings: require('./networkSettings/networkSettings.html'),\n securityGroups: require('./securityGroup/securityGroups.html'),\n instanceType: require('./instanceType/instanceType.html'),\n zones: require('./capacity/zones.html'),\n tags: require('./tags/tags.html'),\n advancedSettings: require('./advancedSettings/advancedSettings.html'),\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n $scope.title = title;\n\n $scope.applicationName = application.name;\n $scope.application = application;\n $scope.command = serverGroupCommand;\n\n // Give regions an init value to prevent it being undefined. If so, the React component RegionSelectField would get \"undefined\" for property regions\n // and then be unmounted so that the region selector would be hidden.\n $scope.command.backingData = $scope.command.backingData || {};\n $scope.command.backingData.filtered = $scope.command.backingData.filtered || {};\n $scope.command.backingData.filtered.regions = $scope.command.backingData.filtered.regions || [];\n\n $scope.state = {\n loaded: false,\n requiresTemplateSelection: !!serverGroupCommand.viewState.requiresTemplateSelection,\n };\n\n this.templateSelectionText = {\n copied: [\n 'account, region, subnet, cluster name (stack, details)',\n 'load balancers',\n FirewallLabels.get('firewalls'),\n 'instance type',\n 'all fields on the Advanced Settings page',\n ],\n notCopied: [],\n additionalCopyText:\n 'If a server group exists in this cluster at the time of deployment, its scaling policies will be copied over to the new server group.',\n };\n\n if (!$scope.command.viewState.disableStrategySelection) {\n this.templateSelectionText.notCopied.push(\n 'the deployment strategy (if any) used to deploy the most recent server group',\n );\n }\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n const cloneStage = $scope.taskMonitor.task.execution.stages.find((stage) => stage.type === 'cloneServerGroup');\n if (cloneStage && cloneStage.context['deploy.server.groups']) {\n const newServerGroupName = cloneStage.context['deploy.server.groups'][$scope.command.region];\n if (newServerGroupName) {\n const newStateParams = {\n serverGroup: newServerGroupName,\n accountId: $scope.command.credentials,\n region: $scope.command.region,\n provider: 'azure',\n };\n let transitionTo = '^.^.^.clusters.serverGroup';\n if ($state.includes('**.clusters.serverGroup')) {\n // clone via details, all view\n transitionTo = '^.serverGroup';\n }\n if ($state.includes('**.clusters.cluster.serverGroup')) {\n // clone or create with details open\n transitionTo = '^.^.serverGroup';\n }\n if ($state.includes('**.clusters')) {\n // create new, no details open\n transitionTo = '.serverGroup';\n }\n $state.go(transitionTo, newStateParams);\n }\n }\n }\n\n function onTaskComplete() {\n application.serverGroups.refresh();\n application.serverGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: 'Creating your server group',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function configureCommand() {\n azureServerGroupConfigurationService.configureCommand(application, serverGroupCommand).then(function () {\n const mode = serverGroupCommand.viewState.mode;\n if (mode === 'clone' || mode === 'create') {\n serverGroupCommand.viewState.useAllImageSelection = true;\n }\n $scope.state.loaded = true;\n initializeWizardState();\n initializeSelectOptions();\n initializeWatches();\n });\n }\n\n function initializeWizardState() {\n const mode = serverGroupCommand.viewState.mode;\n if (mode === 'clone' || mode === 'editPipeline') {\n ModalWizard.markComplete('basic-settings');\n ModalWizard.markComplete('load-balancers');\n ModalWizard.markComplete('network-settings');\n ModalWizard.markComplete('security-groups');\n ModalWizard.markComplete('instance-type');\n ModalWizard.markComplete('zones');\n }\n }\n\n function initializeWatches() {\n $scope.$watch('command.credentials', createResultProcessor($scope.command.credentialsChanged));\n $scope.$watch('command.region', createResultProcessor($scope.command.regionChanged));\n }\n\n function initializeSelectOptions() {\n processCommandUpdateResult($scope.command.credentialsChanged($scope.command, true));\n processCommandUpdateResult($scope.command.regionChanged($scope.command, true));\n }\n\n function createResultProcessor(method) {\n return function (newValue, oldValue) {\n if (newValue !== oldValue) {\n processCommandUpdateResult(method($scope.command));\n }\n };\n }\n\n function processCommandUpdateResult(result) {\n if (result.dirty.loadBalancers) {\n ModalWizard.markDirty('load-balancers');\n ModalWizard.markDirty('network-settings');\n }\n if (result.dirty.securityGroups) {\n ModalWizard.markDirty('security-groups');\n }\n if (result.dirty.instanceType) {\n ModalWizard.markDirty('instance-type');\n }\n if (result.dirty.zoneEnabled || result.dirty.zones) {\n ModalWizard.markDirty('zones');\n }\n }\n\n this.submit = function () {\n if ($scope.command.viewState.mode === 'editPipeline' || $scope.command.viewState.mode === 'createPipeline') {\n return $uibModalInstance.close($scope.command);\n }\n $scope.taskMonitor.submit(function () {\n return serverGroupWriter.cloneServerGroup($scope.command, application);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n this.toggleSuspendedProcess = function (process) {\n $scope.command.suspendedProcesses = $scope.command.suspendedProcesses || [];\n const processIndex = $scope.command.suspendedProcesses.indexOf(process);\n if (processIndex === -1) {\n $scope.command.suspendedProcesses.push(process);\n } else {\n $scope.command.suspendedProcesses.splice(processIndex, 1);\n }\n };\n\n this.processIsSuspended = function (process) {\n return $scope.command.suspendedProcesses.includes(process);\n };\n\n if (!$scope.state.requiresTemplateSelection) {\n configureCommand();\n } else {\n $scope.state.loaded = true;\n }\n\n this.templateSelected = () => {\n $scope.state.requiresTemplateSelection = false;\n configureCommand();\n };\n\n this.isValid = function () {\n return (\n $scope.command &&\n $scope.command.application &&\n $scope.command.credentials &&\n $scope.command.instanceType &&\n $scope.command.region &&\n (!$scope.command.zonesEnabled || $scope.command.zones.length !== 0) &&\n Utility.checkTags($scope.command.instanceTags).isValid\n );\n };\n },\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { NameUtils } from '@spinnaker/core';\nimport { AZURE_IMAGE_IMAGE_READER } from '../../image/image.reader';\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../serverGroup.transformer';\n\nexport const AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE =\n 'spinnaker.azure.serverGroupCommandBuilder.service';\nexport const name = AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE, [\n AZURE_IMAGE_IMAGE_READER,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n ])\n .factory('azureServerGroupCommandBuilder', [\n '$q',\n 'azureImageReader',\n 'azureServerGroupTransformer',\n function ($q, azureImageReader, azureServerGroupTransformer) {\n function buildNewServerGroupCommand(application, defaults) {\n defaults = defaults || {};\n\n const defaultCredentials = defaults.account || application.defaultCredentials.azure;\n const defaultRegion = defaults.region || application.defaultRegions.azure;\n\n return azureImageReader.findImages({ provider: 'azure' }).then(function (images) {\n return {\n application: application.name,\n credentials: defaultCredentials,\n region: defaultRegion,\n images,\n loadBalancers: [],\n selectedVnetSubnets: [],\n strategy: '',\n sku: {\n capacity: 1,\n },\n zonesEnabled: false,\n zones: [],\n instanceTags: {},\n dataDisks: [],\n selectedProvider: 'azure',\n viewState: {\n instanceProfile: 'custom',\n allImageSelection: null,\n useAllImageSelection: false,\n useSimpleCapacity: true,\n usePreferredZones: true,\n mode: defaults.mode || 'create',\n disableStrategySelection: true,\n loadBalancersConfigured: false,\n networkSettingsConfigured: false,\n securityGroupsConfigured: false,\n },\n enableInboundNAT: false,\n };\n });\n }\n\n // Only used to prepare view requiring template selecting\n function buildNewServerGroupCommandForPipeline() {\n return $q.when({\n viewState: {\n requiresTemplateSelection: true,\n },\n });\n }\n\n function buildServerGroupCommandFromExisting(application, serverGroup, mode) {\n mode = mode || 'clone';\n\n const serverGroupName = NameUtils.parseServerGroupName(serverGroup.name);\n\n const command = {\n application: application.name,\n strategy: '',\n stack: serverGroupName.stack,\n freeFormDetails: serverGroupName.freeFormDetails,\n credentials: serverGroup.account,\n loadBalancers: serverGroup.loadBalancers,\n selectedSubnets: serverGroup.selectedVnetSubnets,\n selectedVnet: serverGroup.selectedVnet,\n securityGroups: serverGroup.securityGroups,\n loadBalancerName: serverGroup.loadBalancerName,\n loadBalancerType: serverGroup.loadBalancerType,\n securityGroupName: serverGroup.securityGroupName,\n region: serverGroup.region,\n vnet: serverGroup.vnet,\n vnetResourceGroup: serverGroup.vnetResourceGroup,\n subnet: serverGroup.subnet,\n zones: serverGroup.zones,\n zonesEnabled: serverGroup.zones && serverGroup.zones.length > 0,\n instanceTags: {},\n dataDisks: serverGroup.dataDisks,\n sku: serverGroup.sku,\n capacity: {\n min: serverGroup.capacity.min,\n max: serverGroup.capacity.max,\n desired: serverGroup.capacity.desired,\n },\n tags: [],\n instanceType: serverGroup.sku.name,\n selectedProvider: 'azure',\n source: {\n account: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n asgName: serverGroup.name,\n },\n viewState: {\n allImageSelection: null,\n useAllImageSelection: false,\n useSimpleCapacity: true,\n usePreferredZones: false,\n listImplicitSecurityGroups: false,\n mode: mode,\n disableStrategySelection: true,\n },\n enableInboundNAT: serverGroup.enableInboundNAT,\n };\n\n if (typeof serverGroup.customScriptsSettings !== 'undefined') {\n command.customScriptsSettings = {};\n command.customScriptsSettings.commandToExecute = serverGroup.customScriptsSettings.commandToExecute;\n if (!_.isEmpty(serverGroup.customScriptsSettings.fileUris)) {\n azureServerGroupTransformer.parseCustomScriptsSettings(serverGroup, command);\n }\n }\n\n return $q.when(command);\n }\n\n function buildServerGroupCommandFromPipeline(application, originalCluster) {\n const pipelineCluster = _.cloneDeep(originalCluster);\n const region = pipelineCluster.region;\n\n const commandOptions = { account: pipelineCluster.account, region: region };\n return buildNewServerGroupCommand(application, commandOptions).then(function (command) {\n const viewState = {\n disableImageSelection: true,\n useSimpleCapacity: true,\n mode: 'editPipeline',\n submitButtonLabel: 'Done',\n instanceProfile: originalCluster.viewState.instanceProfile,\n instanceTypeDetails: originalCluster.viewState.instanceTypeDetails,\n };\n\n const viewOverrides = {\n region: region,\n credentials: pipelineCluster.account,\n viewState: viewState,\n };\n if (originalCluster.viewState.instanceTypeDetails) {\n viewOverrides.instanceType = originalCluster.viewState.instanceTypeDetails.name;\n }\n\n pipelineCluster.strategy = pipelineCluster.strategy || '';\n\n const extendedCommand = angular.extend({}, command, pipelineCluster, viewOverrides);\n\n return extendedCommand;\n });\n }\n\n return {\n buildNewServerGroupCommand: buildNewServerGroupCommand,\n buildNewServerGroupCommandForPipeline: buildNewServerGroupCommandForPipeline,\n buildServerGroupCommandFromExisting: buildServerGroupCommandFromExisting,\n buildServerGroupCommandFromPipeline: buildServerGroupCommandFromPipeline,\n };\n },\n ]);\n","import React from 'react';\n\nimport { UserVerification } from '@spinnaker/core';\n\nexport interface IAzureModalFooterProps {\n onSubmit: () => void;\n onCancel: () => void;\n isValid: boolean;\n account: string;\n}\n\nexport interface IAzureModalFooterState {\n verified: boolean;\n}\n\nexport class AzureModalFooter extends React.Component<IAzureModalFooterProps, IAzureModalFooterState> {\n constructor(props: any) {\n super(props);\n }\n\n public state = { verified: false };\n\n private handleVerification = (verified: boolean) => {\n this.setState({ verified });\n };\n\n public render() {\n const { onSubmit, onCancel, isValid, account } = this.props;\n const { verified } = this.state;\n\n return (\n <div className=\"modal-footer\">\n {<UserVerification expectedValue={account} onValidChange={this.handleVerification} />}\n <button className=\"btn btn-default\" onClick={onCancel}>\n Cancel\n </button>\n <button type=\"submit\" className=\"btn btn-primary\" onClick={onSubmit} disabled={!isValid || !verified}>\n Submit\n </button>\n </div>\n );\n }\n}\n","import React from 'react';\nimport { Modal } from 'react-bootstrap';\nimport Select from 'react-select';\n\nimport {\n IModalComponentProps,\n ModalClose,\n noop,\n ReactInjector,\n ReactModal,\n TaskMonitor,\n TaskMonitorWrapper,\n TaskReason,\n} from '@spinnaker/core';\n\nimport { AzureModalFooter } from '../../../common/AzureModalFooter';\n\nexport interface IAzureRollbackServerGroupModalProps extends IModalComponentProps {\n application: any;\n serverGroup: any;\n disabledServerGroups: any;\n}\n\nexport interface IAzureRollbackServerGroupModalState {\n taskMonitor: TaskMonitor;\n submitting: boolean;\n command: any;\n}\n\nexport class AzureRollbackServerGroupModal extends React.Component<\n IAzureRollbackServerGroupModalProps,\n IAzureRollbackServerGroupModalState\n> {\n public static defaultProps: Partial<IAzureRollbackServerGroupModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static show(props: IAzureRollbackServerGroupModalProps) {\n const modalProps = {};\n return ReactModal.show(AzureRollbackServerGroupModal, props, modalProps);\n }\n\n constructor(props: IAzureRollbackServerGroupModalProps) {\n super(props);\n\n const { application, serverGroup } = props;\n\n this.state = {\n taskMonitor: new TaskMonitor({\n application: application,\n title: 'Rolling back your server group',\n modalInstance: TaskMonitor.modalInstanceEmulation(() => this.props.dismissModal()),\n }),\n submitting: true,\n command: {\n interestingHealthProviderNames: [],\n rollbackType: 'EXPLICIT',\n rollbackContext: {\n rollbackServerGroupName: serverGroup.name,\n enableAndDisableOnly: true,\n },\n },\n };\n }\n\n private close = (args?: any) => {\n this.props.dismissModal.apply(null, args);\n };\n\n private submit = () => {\n const { command, taskMonitor } = this.state;\n const { serverGroup, application } = this.props;\n\n taskMonitor.submit(() => {\n return ReactInjector.serverGroupWriter.rollbackServerGroup(serverGroup, application, command);\n });\n };\n\n private filterServerGroups = (disabledServerGroups: any) => {\n const filteredDisabledServerGroups = disabledServerGroups\n .filter((disabledServerGroup: any) => disabledServerGroup.instanceCounts.total !== 0)\n .sort((a: any, b: any) => b.name.localeCompare(a.name));\n\n return filteredDisabledServerGroups;\n };\n\n private isValid = () => {\n const restoreServerGroupName = this.state.command.rollbackContext.restoreServerGroupName;\n return restoreServerGroupName !== undefined;\n };\n\n private handleServerGroupChange = (restoreServerGroupOption: any) => {\n const { disabledServerGroups } = this.props;\n const newCommand = { ...this.state.command };\n newCommand.rollbackContext.restoreServerGroupName = restoreServerGroupOption.value;\n const restoreServerGroup = this.filterServerGroups(disabledServerGroups).find(function (disabledServerGroup: any) {\n return disabledServerGroup.name === restoreServerGroupOption.value;\n });\n newCommand.targetSize = restoreServerGroup.capacity.max;\n this.setState({\n command: newCommand,\n });\n };\n\n private handleTaskReasonChange = (taskReason?: any) => {\n const newCommand = { ...this.state.command };\n newCommand.reason = taskReason;\n this.setState({\n command: newCommand,\n });\n };\n\n public render() {\n const { command, taskMonitor, submitting } = this.state;\n const { serverGroup, disabledServerGroups } = this.props;\n const isValidSG = this.isValid();\n const disabledServerGroupOptions = this.filterServerGroups(disabledServerGroups).map(\n (disabledServerGroup: any) => ({\n label: disabledServerGroup.name,\n value: disabledServerGroup.name,\n }),\n );\n\n return (\n <Modal onHide={this.close}>\n <TaskMonitorWrapper monitor={taskMonitor} />\n {submitting && (\n <form role=\"form\">\n <ModalClose dismiss={this.close} />\n <Modal.Header>\n <Modal.Title>Rollback {serverGroup.name}</Modal.Title>\n </Modal.Header>\n <Modal.Body>\n <div className=\"row\">\n <div className=\"col-sm-3 sm-label-right\">Restore to</div>\n <div className=\"col-sm-6\">\n <Select\n value={command.rollbackContext.restoreServerGroupName}\n onChange={this.handleServerGroupChange}\n options={disabledServerGroupOptions}\n />\n </div>\n </div>\n <TaskReason reason={command.taskReason} onChange={this.handleTaskReasonChange} />\n </Modal.Body>\n <AzureModalFooter\n onSubmit={this.submit}\n onCancel={this.close}\n isValid={isValidSG}\n account={serverGroup.account}\n />\n </form>\n )}\n </Modal>\n );\n }\n}\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n ConfirmationModalService,\n FirewallLabels,\n SERVER_GROUP_WRITER,\n ServerGroupReader,\n ServerGroupWarningMessageService,\n} from '@spinnaker/core';\n\nimport '../configure/serverGroup.configure.azure.module';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE } from '../configure/serverGroupCommandBuilder.service';\nimport { AzureRollbackServerGroupModal } from './rollback/RollbackServerGroupModal';\n\nexport const AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER =\n 'spinnaker.azure.serverGroup.details.controller';\nexport const name = AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER; // for backwards compatibility\nangular\n .module(AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE,\n SERVER_GROUP_WRITER,\n ])\n .controller('azureServerGroupDetailsCtrl', [\n '$scope',\n '$state',\n '$templateCache',\n 'app',\n 'serverGroup',\n 'azureServerGroupCommandBuilder',\n '$uibModal',\n 'serverGroupWriter',\n function (\n $scope,\n $state,\n $templateCache,\n app,\n serverGroup,\n azureServerGroupCommandBuilder,\n $uibModal,\n serverGroupWriter,\n ) {\n $scope.state = {\n loading: true,\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n this.application = app;\n\n function extractServerGroupSummary() {\n let summary = _.find(app.serverGroups.data, function (toCheck) {\n return (\n toCheck.name === serverGroup.name &&\n toCheck.account === serverGroup.accountId &&\n toCheck.region === serverGroup.region\n );\n });\n if (!summary) {\n app.loadBalancers.data.some(function (loadBalancer) {\n if (loadBalancer.account === serverGroup.accountId && loadBalancer.region === serverGroup.region) {\n return loadBalancer.serverGroups.some(function (possibleServerGroup) {\n if (possibleServerGroup.name === serverGroup.name) {\n summary = possibleServerGroup;\n return true;\n }\n });\n }\n });\n }\n if (!summary) {\n $state.go('^');\n }\n return summary;\n }\n\n function retrieveServerGroup() {\n const summary = extractServerGroupSummary();\n return ServerGroupReader.getServerGroup(\n app.name,\n serverGroup.accountId,\n serverGroup.region,\n serverGroup.name,\n ).then(function (details) {\n cancelLoader();\n\n angular.extend(details, summary);\n details.account = serverGroup.accountId; // it's possible the summary was not found because the clusters are still loading\n\n $scope.serverGroup = details;\n\n if (!_.isEmpty($scope.serverGroup)) {\n $scope.image = details.image ? details.image : undefined;\n\n if (details.image && details.image.description) {\n const tags = details.image.description.split(', ');\n tags.forEach(function (tag) {\n const keyVal = tag.split('=');\n if (keyVal.length === 2 && keyVal[0] === 'ancestor_name') {\n details.image.baseImage = keyVal[1];\n }\n });\n }\n\n if (details.launchConfig && details.launchConfig.securityGroups) {\n $scope.securityGroups = _.chain(details.launchConfig.securityGroups)\n .map(function (id) {\n return (\n _.find(app.securityGroups.data, {\n accountName: serverGroup.accountId,\n region: serverGroup.region,\n id: id,\n }) ||\n _.find(app.securityGroups.data, {\n accountName: serverGroup.accountId,\n region: serverGroup.region,\n name: id,\n })\n );\n })\n .compact()\n .value();\n }\n } else {\n $state.go('^');\n }\n });\n }\n\n function cancelLoader() {\n $scope.state.loading = false;\n }\n\n retrieveServerGroup().then(() => {\n // If the user navigates away from the view before the initial retrieveServerGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.serverGroups.onRefresh($scope, retrieveServerGroup);\n }\n });\n\n this.destroyServerGroup = function destroyServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const stateParams = {\n name: serverGroup.name,\n accountId: serverGroup.account,\n region: serverGroup.region,\n };\n\n const taskMonitor = {\n application: app,\n title: 'Destroying ' + serverGroup.name,\n onTaskComplete: function () {\n if ($state.includes('**.serverGroup', stateParams)) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return serverGroupWriter.destroyServerGroup(serverGroup, app);\n };\n\n const confirmationModalParams = {\n header: 'Really destroy ' + serverGroup.name + '?',\n buttonText: 'Destroy ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n };\n\n ServerGroupWarningMessageService.addDestroyWarningMessage(app, serverGroup, confirmationModalParams);\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.disableServerGroup = function disableServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + serverGroup.name,\n };\n\n const submitMethod = () => serverGroupWriter.disableServerGroup(serverGroup, app);\n\n const confirmationModalParams = {\n header: 'Really disable ' + serverGroup.name + '?',\n buttonText: 'Disable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n };\n\n ServerGroupWarningMessageService.addDisableWarningMessage(app, serverGroup, confirmationModalParams);\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.enableServerGroup = function enableServerGroup() {\n const serverGroup = $scope.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + serverGroup.name,\n };\n\n const submitMethod = (params) => {\n return serverGroupWriter.enableServerGroup(\n serverGroup,\n app,\n angular.extend(params, {\n interestingHealthProviderNames: [], // bypass the check for now; will change this later to ['azureService']\n }),\n );\n };\n\n ConfirmationModalService.confirm({\n header: 'Really enable ' + serverGroup.name + '?',\n buttonText: 'Enable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.rollbackServerGroup = () => {\n const serverGroup = $scope.serverGroup;\n const cluster = _.find(app.clusters, { name: serverGroup.cluster, account: serverGroup.account });\n const disabledServerGroups = _.filter(cluster.serverGroups, { isDisabled: true, region: serverGroup.region });\n AzureRollbackServerGroupModal.show({ application: app, serverGroup, disabledServerGroups });\n };\n\n this.cloneServerGroup = (serverGroup) => {\n $uibModal.open({\n templateUrl: require('../configure/wizard/serverGroupWizard.html'),\n controller: 'azureCloneServerGroupCtrl as ctrl',\n size: 'lg',\n resolve: {\n title: () => 'Clone ' + serverGroup.name,\n application: () => app,\n serverGroupCommand: () =>\n azureServerGroupCommandBuilder.buildServerGroupCommandFromExisting(app, serverGroup),\n },\n });\n };\n\n this.truncateCommitHash = function () {\n if ($scope.serverGroup && $scope.serverGroup.buildInfo && $scope.serverGroup.buildInfo.commit) {\n return $scope.serverGroup.buildInfo.commit.substring(0, 8);\n }\n return null;\n };\n },\n ]);\n","import { module } from 'angular';\n\nimport { AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER } from './serverGroupDetails.azure.controller';\n\n('use strict');\n\nexport const AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE = 'spinnaker.azure.serverGroup.details.azure';\nexport const name = AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE; // for backwards compatibility\nmodule(AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE, [\n AZURE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_AZURE_CONTROLLER,\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ApplicationNameValidator } from '@spinnaker/core';\n\nexport const AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR = 'spinnaker.azure.validation.applicationName';\nexport const name = AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR; // for backwards compatibility\nmodule(AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR, [])\n .factory('azureApplicationNameValidator', function () {\n function validateSpecialCharacters(name, errors) {\n const pattern = /^([a-zA-Z][a-zA-Z0-9]*)?$/;\n if (!pattern.test(name)) {\n errors.push(\n 'The application name must begin with a letter and must contain only letters or digits. No ' +\n 'special characters are allowed.',\n );\n }\n }\n\n function validate(name) {\n const warnings = [];\n const errors = [];\n\n if (name && name.length) {\n validateSpecialCharacters(name, errors);\n }\n\n return {\n warnings: warnings,\n errors: errors,\n };\n }\n\n return {\n validate: validate,\n };\n })\n .run([\n 'azureApplicationNameValidator',\n function (azureApplicationNameValidator) {\n ApplicationNameValidator.registerValidator('azure', azureApplicationNameValidator);\n },\n ]);\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import { module } from 'angular';\n\nimport { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';\n\nimport './help/azure.help';\nimport { AZURE_IMAGE_IMAGE_READER } from './image/image.reader';\nimport { AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE } from './instance/azureInstanceType.service';\nimport { AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER } from './instance/details/instance.details.controller';\nimport { AzureLoadBalancerChoiceModal } from './loadBalancer/configure/AzureLoadBalancerChoiceModal';\nimport { AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER } from './loadBalancer/configure/createLoadBalancer.controller';\nimport { AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER } from './loadBalancer/details/loadBalancerDetail.controller';\nimport { AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from './loadBalancer/loadBalancer.transformer';\nimport logo from './logo/logo_azure.png';\nimport { AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE } from './pipeline/stages/bake/azureBakeStage';\nimport { AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE } from './pipeline/stages/destroyAsg/azureDestroyAsgStage';\nimport { AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE } from './pipeline/stages/disableAsg/azureDisableAsgStage';\nimport { AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE } from './pipeline/stages/enableAsg/azureEnableAsgStage';\nimport { AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL } from './securityGroup/configure/CreateSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL } from './securityGroup/configure/EditSecurityGroupCtrl';\nimport { AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER } from './securityGroup/details/securityGroupDetail.controller';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_READER } from './securityGroup/securityGroup.reader';\nimport { AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER } from './securityGroup/securityGroup.transformer';\nimport { AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE } from './serverGroup/configure/serverGroup.configure.azure.module';\nimport { AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER } from './serverGroup/configure/wizard/CloneServerGroup.azure.controller';\nimport { AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE } from './serverGroup/details/serverGroup.details.module';\nimport { AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from './serverGroup/serverGroup.transformer';\nimport { AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR } from './validation/applicationName.validator';\n\nimport './logo/azure.logo.less';\n\nexport const AZURE_MODULE = 'spinnaker.azure';\nmodule(AZURE_MODULE, [\n AZURE_PIPELINE_STAGES_DESTROYASG_AZUREDESTROYASGSTAGE,\n AZURE_PIPELINE_STAGES_ENABLEASG_AZUREENABLEASGSTAGE,\n AZURE_PIPELINE_STAGES_DISABLEASG_AZUREDISABLEASGSTAGE,\n AZURE_PIPELINE_STAGES_BAKE_AZUREBAKESTAGE,\n AZURE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_MODULE,\n AZURE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n AZURE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_AZURE_CONTROLLER,\n AZURE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_AZURE_MODULE,\n AZURE_INSTANCE_AZUREINSTANCETYPE_SERVICE,\n AZURE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n AZURE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER,\n AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER,\n AZURE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER,\n AZURE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER,\n AZURE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUPCTRL,\n AZURE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUPCTRL,\n AZURE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER,\n AZURE_SECURITYGROUP_SECURITYGROUP_READER,\n AZURE_IMAGE_IMAGE_READER,\n AZURE_VALIDATION_APPLICATIONNAME_VALIDATOR,\n]).config(function () {\n CloudProviderRegistry.registerProvider('azure', {\n name: 'Azure',\n logo: {\n path: logo,\n },\n image: {\n reader: 'azureImageReader',\n },\n serverGroup: {\n transformer: 'azureServerGroupTransformer',\n detailsTemplateUrl: require('./serverGroup/details/serverGroupDetails.html'),\n detailsController: 'azureServerGroupDetailsCtrl',\n cloneServerGroupTemplateUrl: require('./serverGroup/configure/wizard/serverGroupWizard.html'),\n cloneServerGroupController: 'azureCloneServerGroupCtrl',\n commandBuilder: 'azureServerGroupCommandBuilder',\n configurationService: 'azureServerGroupConfigurationService',\n },\n instance: {\n instanceTypeService: 'azureInstanceTypeService',\n detailsTemplateUrl: require('./instance/details/instanceDetails.html'),\n detailsController: 'azureInstanceDetailsCtrl',\n },\n loadBalancer: {\n transformer: 'azureLoadBalancerTransformer',\n detailsTemplateUrl: require('./loadBalancer/details/loadBalancerDetail.html'),\n detailsController: 'azureLoadBalancerDetailsCtrl',\n createLoadBalancerTemplateUrl: require('./loadBalancer/configure/createLoadBalancer.html'),\n createLoadBalancerController: 'azureCreateLoadBalancerCtrl',\n CreateLoadBalancerModal: AzureLoadBalancerChoiceModal,\n },\n securityGroup: {\n transformer: 'azureSecurityGroupTransformer',\n reader: 'azureSecurityGroupReader',\n detailsTemplateUrl: require('./securityGroup/details/securityGroupDetail.html'),\n detailsController: 'azureSecurityGroupDetailsCtrl',\n createSecurityGroupTemplateUrl: require('./securityGroup/configure/createSecurityGroup.html'),\n createSecurityGroupController: 'azureCreateSecurityGroupCtrl',\n },\n });\n});\n\nDeploymentStrategyRegistry.registerProvider('azure', ['redblack']);\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQYAAACrCAYAAACEwDK4AAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAABCZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICAgICAgICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI+CiAgICAgICAgIDx0aWZmOlJlc29sdXRpb25Vbml0PjI8L3RpZmY6UmVzb2x1dGlvblVuaXQ+CiAgICAgICAgIDx0aWZmOkNvbXByZXNzaW9uPjU8L3RpZmY6Q29tcHJlc3Npb24+CiAgICAgICAgIDx0aWZmOlhSZXNvbHV0aW9uPjcyPC90aWZmOlhSZXNvbHV0aW9uPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICAgICA8dGlmZjpZUmVzb2x1dGlvbj43MjwvdGlmZjpZUmVzb2x1dGlvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxYRGltZW5zaW9uPjI2MjwvZXhpZjpQaXhlbFhEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOkNvbG9yU3BhY2U+MTwvZXhpZjpDb2xvclNwYWNlPgogICAgICAgICA8ZXhpZjpQaXhlbFlEaW1lbnNpb24+MTcxPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxOS0wNS0wNlQxMjowNTozMTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjguMzwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4K8Qjg7wAAM9JJREFUeAHtnQeAFdX1/8/MvLa9L1tgF5Zl6UUUggoIggVLrCQYY42a/jPlb4rxr9EkvxhNIz9bEjUmllhRRFCxIKII0hVY2jaWLbC9vf5mft9z571lwd1lWfWXRM+FeW/ezJ07937uveeee+6ZWbIsazG2EpIgBITA554AywKWCSRC4XPfFgSAEDiCgMiEI3DIDyEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEhIASEgBAQAkJACAgBISAEhIAQEAJCQAgIASEgBISAEBACQkAICAEh8B9DQPuPyWk0o+2WlRnyhYorW8O5++pb0irq2pIqu6y46uaAtau6tv6+L89Yf9akzF3/aeWS/AqBfycCjk8jM5ZljUa6FrZyTdPCvd0DcZJwvAhbLrZkbN158RMZXaGIsbcx4Cira3ej8ydWtoeza1u9haf8atXItkBkeER3pkYiRDpEm6FppBkaBci9zxHv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\""],"names":["TagError","TagError2","AzureLoadBalancerTypes","type","description","tagsObject","isValid","error","errorMessage","length","Object","keys","_Utility","TAG_LIMITATION","k","v","entries","TAG_KEY_LENGTH_LIMITATION","TAG_VALUE_LENGTH_LIMITATION","TAG_INVALID_CHAR_REG_EXR","test","typeString","toLowerCase","split","join","find","lb","Utility","helpContents","azure.securityGroup.ingress.description","azure.securityGroup.ingress.priority","azure.securityGroup.ingress.source","azure.securityGroup.ingress.sourcePortRange","azure.securityGroup.ingress.destination","azure.securityGroup.ingress.destinationPortRange","azure.securityGroup.ingress.direction","azure.securityGroup.ingress.actions","azure.securityGroup.ingress.destPortRanges","azure.securityGroup.ingress.sourceIPCIDRRanges","azure.serverGroup.imageName","azure.serverGroup.stack","azure.serverGroup.detail","azure.serverGroup.scriptLocation","azure.serverGroup.commandToExecute","azure.serverGroup.customData","azure.serverGroup.customTags","azure.serverGroup.enableInboundNAT","azure.serverGroup.lun","azure.serverGroup.diskSizeGB","azure.serverGroup.managedDisk.storageAccountType","azure.serverGroup.caching","azure.serverGroup.userAssignedIdentities","azure.loadBalancer.dnsName","azure.loadBalancer.probes.probeInterval","azure.loadBalancer.probes.timeout","azure.loadBalancer.probes.unhealthyThreshold","azure.loadBalancer.loadBalancingRules.idleTimeout","azure.loadBalancer.loadBalancingRules.sessionPersistence","forEach","key","HelpContentsRegistry","register","module","factory","findImages","params","REST","query","get","then","results","getImage","amiName","region","credentials","path","provider","$q","categories","label","families","instanceTypes","name","cpu","memory","storage","count","size","icon","map","category","family","inst","costFactor","stats","min","Number","MAX_VALUE","max","push","cpuMin","_","minBy","cpuMax","maxBy","memoryMin","memoryMax","storageMin","calculateStorage","storageMax","Math","buildStats","when","getCategories","getAvailableTypesForRegions","locationToInstanceTypesMap","selectedLocations","location","getAllTypesByRegion","UIROUTER_ANGULARJS","ANGULAR_UI_BOOTSTRAP","controller","$scope","$state","$uibModal","instance","app","extraData","instanceSummary","loadBalancers","account","vpcId","serverGroups","data","some","serverGroup","instances","possibleInstance","id","instanceId","loadBalancer","isDisabled","addExtraDataToLatest","InstanceReader","getInstanceDetails","details","state","loading","instance2","latest","isStandalone","health","displayableMetrics","filter","metric","detailsMatch","latestHealth","defaults","healthMetrics","discoveryMetric","vipAddress","vipList","includes","baseIpAddress","publicDnsName","privateIpAddress","go","instanceIdNotFound","detailsTemplateUrl","CloudProviderRegistry","getValue","standalone","canDeregisterFromLoadBalancer","canRegisterWithLoadBalancer","outOfService","hasLoadBalancerHealth","canRegisterWithDiscovery","discoveryHealth","terminateInstance","taskMonitor","application","title","onTaskComplete","confirm","header","buttonText","taskMonitorConfig","submitMethod","InstanceWriter","terminateInstanceAndShrinkServerGroup","rebootInstance","registerInstanceWithLoadBalancer","loadBalancerNames","deregisterInstanceFromLoadBalancer","enableInstanceInDiscovery","disableInstanceInDiscovery","hasHealthState","healthProviderType","retrieveInstance","all","ready","$$destroyed","onRefresh","React","Component","[object Object]","props","close","modalService","open","templateUrl","createLoadBalancerTemplateUrl","windowClass","createLoadBalancerController","resolve","this","isNew","forPipelineConfig","loadBalancerType","selectedChoice","result","catch","reason","dismissModal","choices","ReactModal","show","_AzureLoadBalancerChoiceModal","className","choice","setState","ModalClose","dismiss","Modal","Header","Title","Body","onClick","choiceSelected","Footer","Button","choose","AzureLoadBalancerChoiceModal","defaultProps","closeModal","noop","AzureProviderSettings","SETTINGS","providers","azure","resetToOriginal","resetProvider","normalizeLoadBalancer","detachedInstances","concat","activeServerGroups","chain","flatten","value","convertLoadBalancerForEditing","toEdit","stack","detail","vnet","subnet","probes","loadBalancingRules","elb","securityGroups","dnsName","constructNewLoadBalancerTemplate","defaultCredentials","defaultRegions","cloudProvider","probeName","probeProtocol","probePort","probePath","probeInterval","unhealthyThreshold","timeout","ruleName","protocol","externalPort","backendPort","persistence","idleTimeout","sku","$uibModalInstance","azureLoadBalancerTransformer","ctrl","newStateParams","accountId","accountLoadBalancersByRegion","getDataSource","refresh","loadBalancer2","existingLoadBalancerNames","regions","pages","listeners","healthCheck","advancedSettings","isALB","accountsLoaded","submitting","validSkus","TaskMonitor","modalInstance","onNextRefresh","onApplicationRefresh","nameParts","NameUtils","parseLoadBalancerName","freeFormDetails","listAccounts","accounts","accountUpdated","requiresHealthCheckPath","indexOf","updateName","getName","elbName","trimEnd","getRegionsForAccount","regionUpdated","vnetUpdated","selectedVnet","vnetResourceGroup","selectedVnets","listNetworks","vnets","subnetUpdated","selectedSubnet","selectedSubnets","selectedVnetChanged","item","resourceGroup","subnets","addSubnet","devices","device","removeListener","index","splice","addListener","submit","descriptor","appName","clusterName","resourceGroupName","loadBalancerName","name2","ruleNameBase","subnetType","rule","LoadBalancerWriter","upsertLoadBalancer","cancel","angular","SECURITY_GROUP_READER","LOAD_BALANCER_READ_SERVICE","$exceptionHandler","securityGroupReader","loadBalancerReader","getLoadBalancerDetails","filtered","securityGroupId","match","getApplicationSecurityGroup","sortBy","s","ss","substring","toUpperCase","firewallsLabel","FirewallLabels","extractLoadBalancer","editLoadBalancer","copy","deleteLoadBalancer","command","$stateParams","executionDetailsSectionService","$interpolate","configSections","initialized","detailsSection","stage","context","cloudProviderType","roscoMode","feature","roscoSelector","bakeryDetailUrl","roscoDetailUrl","initialize","synchronizeSection","$on","config","pipeline","registerStage","provides","executionDetailsUrl","executionLabelComponent","BakeExecutionLabel","extraLabelLines","masterStage","allPreviouslyBaked","somePreviouslyBaked","supportsCustomTimeout","validators","fieldName","checkParentTriggers","getMessage","labels","restartable","extendedAttributes","user","AuthenticationService","getAuthenticatedUser","viewState","baseOsChanged","selectedOption","baseOsOptions","baseOs","osType","addExtendedAttribute","PipelineTemplates","addExtendedAttributes","controllerAs","extendedAttribute","removeExtendedAttribute","showTemplateFileName","templateFileName","showExtendedAttributes","showVarFileName","varFileName","$watch","forOwn","val","BakeryReader","getRegions","getBaseOsOptions","getBaseLabelOptions","baseLabelOptions","baseImages","baseLabel","showAdvancedOptions","stg","showAdvanced","executionStepLabelUrl","accountExtractor","configAccountExtractor","message","fieldLabel","regionsLoaded","getAccountDetails","org","targets","StageConstants","TARGET_LIST","interestingHealthProviderNames","target","alias","attributes","platformHealthOnly","reset","resetSelectedCluster","deleteSecurityGroup","securityGroup","securityGroupName","operation","TaskExecutor","executeTask","job","clearCache","upsertSecurityGroup","assignWith","other","isUndefined","$controller","azureSecurityGroupWriter","ingress","firewallLabel","accountName","ruleset","a","b","temp","priorityA","priority","priorityB","infiniteScroll","numToAdd","currentItems","addMoreItems","securityGroup2","namePreview","upsert","addRule","protocolUI","access","direction","sourceAddressPrefix","sourceAddressPrefixes","sourcePortRange","destinationAddressPrefix","destinationPortRange","destinationPortRanges","destPortRanges","sourceIPCIDRRanges","portUpdated","isEmpty","ruleRanges","sourceIPCIDRUpdated","protocolUpdated","removeRule","moveUp","moveDown","securityRules","CACHE_INITIALIZER_SERVICE","cacheInitializer","destinationPortRangeModel","sourceAddressPrefixModel","refreshingSecurityGroups","getSecurityGroupRefreshTime","InfrastructureCaches","getStats","ageMax","refreshSecurityGroups","refreshCache","getAllSecurityGroups","availableGroups","availableSecurityGroups","startPort","endPort","resolvedSecurityGroup","getSecurityGroupDetails","extractSecurityGroup","editInboundRules","cloneSecurityGroup","resolveIndexedSecurityGroup","indexedSecurityGroups","container","normalizeSecurityGroup","configuration","Array","isArray","customScriptsSettings","fileUris","fileUrisTemp","trim","convertServerGroupCommandToDeployConfiguration","tempImage","mode","imageName","isCustom","publisher","offer","version","uri","ostype","selectedImage","selectedProvider","strategy","rollback","onFailure","scaleDown","maxRemainingAsgs","delayBeforeDisableSec","delayBeforeScaleDownSec","allowDeleteActive","allowScaleDownActive","healthSettings","image","useSourceCapacity","capacity","upgradePolicy","tier","instanceTags","dataDisks","userAssignedIdentities","osConfig","customData","commandToExecute","zonesEnabled","zones","enableInboundNAT","instanceType","vmsku","normalizeServerGroup","parseCustomScriptsSettings","instanceTypeService","modalWizardService","wizard","getWizard","instanceProfile","includePage","markClean","markComplete","excludePage","newVal","markDirty","directive","restrict","scope","bindToController","addDataDisk","newDataDisks","lun","managedDisk","storageAccountType","diskSizeGB","caching","createOption","removeDataDisk","input","selectedRegion","IMAGE_READER","$uibModalStack","imageReader","markIncomplete","imageChanged","extend","stackPattern","templatingEnabled","detailPattern","healthCheckProtocols","displayName","changeHealthCheckProtocol","newProtocol","port","requestPath","clearImage","LBs","selectedLoadBalancer","attachedVnet","selectedVnetSubnets","allVnets","attachedSubnet","networkSettingsConfigured","useLoadBalancer","loadBalancerChanged","backingData","loadBalancerToFind","getLoadBalancerType","vnetChanged","networkSettingsChanged","getVnetName","selectedSecurityGroup","securityGroupChanged","azureServerGroupConfigurationService","link","refreshing","getTagResult","checkTags","updateEnableInboundNAT","vm","azureImageReader","azureInstanceTypeService","dataDiskTypes","dataDiskCachingTypes","healthCheckTypes","terminationPolicies","dirty","c","locations","credentialsKeyedByAccount","every","l","startsWith","configureStandardInstanceTypes","filteredData","regionsSupportZones","availabilityZones","newSecurityGroups","currentOptions","newRegionalSecurityGroups","getRegionalSecurityGroups","securityGroupsConfigured","uniq","sort","current","newLoadBalancers","getLoadBalancerNames","matched","intersection","removed","xor","filterlist","loadBalancersConfigured","configureUpdateCommand","configureCommand","AccountService","getCredentialsKeyedByAccount","loadSecurityGroups","loadLoadBalancers","cmd","regionChanged","isInit","configureLoadBalancers","configureSecurityGroupOptions","configureInstanceTypes","configureZones","credentialsChanged","regionsForAccount","defaultKeyPair","configureImages","regionalImages","disableImageSelection","packageImages","amis","ami","images","configureLoadBalancerOptions","refreshLoadBalancers","skipCommandReconfiguration","listLoadBalancers","refreshInstanceTypes","SERVER_GROUP_WRITER","serverGroupWriter","serverGroupCommand","cloneStage","task","execution","stages","newServerGroupName","transitionTo","useAllImageSelection","loaded","createResultProcessor","method","newValue","oldValue","zoneEnabled","templateSelection","basicSettings","imageSettings","networkSettings","tags","applicationName","requiresTemplateSelection","templateSelectionText","copied","notCopied","additionalCopyText","disableStrategySelection","cloneServerGroup","toggleSuspendedProcess","process","suspendedProcesses","processIndex","processIsSuspended","templateSelected","azureServerGroupTransformer","defaultRegion","allImageSelection","useSimpleCapacity","usePreferredZones","buildNewServerGroupCommand","buildNewServerGroupCommandForPipeline","buildServerGroupCommandFromExisting","serverGroupName","parseServerGroupName","desired","source","asgName","listImplicitSecurityGroups","buildServerGroupCommandFromPipeline","originalCluster","pipelineCluster","cloneDeep","submitButtonLabel","instanceTypeDetails","viewOverrides","verified","onSubmit","onCancel","UserVerification","expectedValue","onValidChange","handleVerification","disabled","args","apply","ReactInjector","rollbackServerGroup","disabledServerGroups","disabledServerGroup","instanceCounts","total","localeCompare","rollbackContext","restoreServerGroupName","restoreServerGroupOption","newCommand","restoreServerGroup","filterServerGroups","targetSize","taskReason","modalInstanceEmulation","rollbackType","rollbackServerGroupName","enableAndDisableOnly","_AzureRollbackServerGroupModal","isValidSG","disabledServerGroupOptions","onHide","TaskMonitorWrapper","monitor","role","Select","onChange","handleServerGroupChange","options","TaskReason","handleTaskReasonChange","AzureModalFooter","AzureRollbackServerGroupModal","$templateCache","azureServerGroupCommandBuilder","summary","toCheck","possibleServerGroup","extractServerGroupSummary","ServerGroupReader","getServerGroup","tag","keyVal","baseImage","launchConfig","compact","retrieveServerGroup","destroyServerGroup","serverGroup2","stateParams","confirmationModalParams","addDestroyWarningMessage","disableServerGroup","addDisableWarningMessage","enableServerGroup","cluster","clusters","truncateCommitHash","buildInfo","commit","validate","errors","warnings","run","azureApplicationNameValidator","registerValidator","css","ref","insertAt","document","head","getElementsByTagName","style","createElement","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","AZURE_MODULE","registerProvider","logo","reader","transformer","detailsController","cloneServerGroupTemplateUrl","cloneServerGroupController","commandBuilder","configurationService","CreateLoadBalancerModal","createSecurityGroupTemplateUrl","createSecurityGroupController","DeploymentStrategyRegistry"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spinnaker/azure",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"lib": "npm run build"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@spinnaker/core": "^0.
|
|
16
|
+
"@spinnaker/core": "^0.11.1",
|
|
17
17
|
"@uirouter/angularjs": "1.0.26",
|
|
18
18
|
"angular": "1.6.10",
|
|
19
19
|
"angular-ui-bootstrap": "2.5.0",
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"shx": "0.3.3",
|
|
36
36
|
"typescript": "4.3.5"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "70b1ded668f557a8304fd2d4b9cc43ea93dd5c5d"
|
|
39
39
|
}
|
|
@@ -62,6 +62,19 @@
|
|
|
62
62
|
<input class="form-control input-sm" type="number" min="0" ng-model="loadBalancer.probes[0].timeout" />
|
|
63
63
|
</div>
|
|
64
64
|
</div>
|
|
65
|
+
<div class="form-group" ng-if="isNew && !isALB">
|
|
66
|
+
<div class="col-md-4 sm-label-right">
|
|
67
|
+
<b>SKU</b>
|
|
68
|
+
<help-field key="azure.loadBalancer.sku"></help-field>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="col-md-4">
|
|
71
|
+
<select
|
|
72
|
+
class="form-control input-sm"
|
|
73
|
+
ng-model="loadBalancer.sku"
|
|
74
|
+
ng-options="sku for sku in validSkus"
|
|
75
|
+
></select>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
65
78
|
<div class="form-group" ng-if="isALB">
|
|
66
79
|
<div class="col-md-4 sm-label-right">
|
|
67
80
|
<b>Session persistence</b>
|
|
@@ -53,6 +53,8 @@ module(AZURE_LOADBALANCER_CONFIGURE_CREATELOADBALANCER_CONTROLLER, [
|
|
|
53
53
|
submitting: false,
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
+
$scope.validSkus = ['Standard_v2', 'Standard_Small'];
|
|
57
|
+
|
|
56
58
|
function onApplicationRefresh() {
|
|
57
59
|
// If the user has already closed the modal, do not navigate to the new details view
|
|
58
60
|
if ($scope.$$destroyed) {
|