@spinnaker/amazon 0.8.7 → 0.8.11

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/domain/IAmazonServerGroup.d.ts +5 -3
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetMetricFields.d.ts +1 -1
  6. package/dist/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingAdditionalSettings.d.ts +1 -0
  7. package/dist/serverGroup/details/scalingPolicy/targetTracking/UpsertTargetTrackingModal.d.ts +8 -0
  8. package/dist/serverGroup/details/scalingPolicy/upsert/ScalingPolicyAdditionalSettings.d.ts +1 -0
  9. package/dist/serverGroup/details/scalingPolicy/upsert/UpsertScalingPolicyModal.d.ts +8 -0
  10. package/dist/serverGroup/details/scalingPolicy/upsert/step/StepPolicyAction.d.ts +2 -3
  11. package/dist/serverGroup/details/sections/InstancesDistributionDetailsSection.d.ts +2 -0
  12. package/dist/serverGroup/details/sections/index.d.ts +1 -1
  13. package/package.json +3 -3
  14. package/src/aws.module.ts +2 -2
  15. package/src/domain/IAmazonServerGroup.ts +5 -3
  16. package/src/serverGroup/details/scalingPolicy/CreateScalingPolicyButton.tsx +17 -28
  17. package/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.js +45 -49
  18. package/src/serverGroup/details/scalingPolicy/chart/MetricAlarmChart.tsx +3 -2
  19. package/src/serverGroup/details/scalingPolicy/targetTracking/TargetMetricFields.tsx +2 -2
  20. package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingAdditionalSettings.less +11 -0
  21. package/src/serverGroup/details/scalingPolicy/targetTracking/TargetTrackingAdditionalSettings.tsx +18 -16
  22. package/src/serverGroup/details/scalingPolicy/targetTracking/UpsertTargetTrackingModal.tsx +75 -0
  23. package/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.component.ts +10 -16
  24. package/src/serverGroup/details/scalingPolicy/upsert/ScalingPolicyAdditionalSettings.less +11 -0
  25. package/src/serverGroup/details/scalingPolicy/upsert/ScalingPolicyAdditionalSettings.tsx +9 -8
  26. package/src/serverGroup/details/scalingPolicy/upsert/UpsertScalingPolicyModal.tsx +211 -0
  27. package/src/serverGroup/details/scalingPolicy/upsert/alarm/AlarmConfigurer.tsx +17 -23
  28. package/src/serverGroup/details/scalingPolicy/upsert/alarm/DimensionsEditor.tsx +2 -2
  29. package/src/serverGroup/details/scalingPolicy/upsert/alarm/MetricSelector.tsx +2 -1
  30. package/src/serverGroup/details/scalingPolicy/upsert/step/StepPolicyAction.tsx +4 -4
  31. package/src/serverGroup/details/sections/{InstancesDiversificationDetailsSection.spec.tsx → InstancesDistributionDetailsSection.spec.tsx} +8 -8
  32. package/src/serverGroup/details/sections/{InstancesDiversificationDetailsSection.tsx → InstancesDistributionDetailsSection.tsx} +10 -10
  33. package/src/serverGroup/details/sections/LaunchTemplateDetailsSection.spec.tsx +1 -1
  34. package/src/serverGroup/details/sections/LaunchTemplateDetailsSection.tsx +1 -1
  35. package/src/serverGroup/details/sections/MultipleInstanceTypesSubSection.tsx +1 -1
  36. package/src/serverGroup/details/sections/index.ts +1 -1
  37. package/dist/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.controller.d.ts +0 -41
  38. package/dist/serverGroup/details/scalingPolicy/upsert/alarm/alarmConfigurer.component.d.ts +0 -2
  39. package/dist/serverGroup/details/scalingPolicy/upsert/alarm/dimensionsEditor.component.d.ts +0 -2
  40. package/dist/serverGroup/details/scalingPolicy/upsert/simple/simplePolicyAction.component.d.ts +0 -2
  41. package/dist/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.controller.d.ts +0 -2
  42. package/dist/serverGroup/details/sections/InstancesDiversificationDetailsSection.d.ts +0 -2
  43. package/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.controller.ts +0 -129
  44. package/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html +0 -94
  45. package/src/serverGroup/details/scalingPolicy/upsert/simple/simplePolicyAction.component.js +0 -20
  46. package/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.controller.js +0 -248
  47. package/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html +0 -74
  48. package/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.less +0 -32
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import*as e from"angular";import{module as t}from"angular";import{SETTINGS as a,HelpField as n,DeploymentStrategyRegistry as r,FormValidator as i,FormikFormField as s,TextInput as l,AccountService as o,ReactSelectInput as c,CheckboxInput as d,MapEditorInput as p,NumberInput as u,NetworkReader as m,SubnetReader as g,ReactInjector as h,TetheredSelect as f,TaskMonitor as v,FunctionWriter as y,ReactModal as b,WizardModal as w,WizardPage as E,noop as C,ConfirmationModalService as k,ApplicationReader as S,AddEntityTagLinks as G,ReactInject as N,Details as T,AccountTag as I,Overrides as x,CollapsibleSection as A,HelpContentsRegistry as P,REST as z,LabeledValue as B,timestamp as D,useData as $,SubnetTag as M,withErrorBoundary as F,InstanceWriter as L,TaskExecutor as R,CloudProviderRegistry as O,FirewallLabels as U,RecentHistoryService as V,InstanceReader as j,LabeledValueList as q,LinkWithClipboard as H,robotToHuman as W,Tooltip as Z,InstanceLoadBalancerHealth as _,LoadBalancerServerGroup as K,HealthCounts as Y,LoadBalancerInstances as X,LoadBalancerClusterContainer as Q,logger as J,LoadBalancerDataUtils as ee,Spinner as te,HoverablePopover as ae,SpinFormik as ne,ModalClose as re,SubmitButton as ie,SelectInput as se,CertificateReader as le,relativeTime as oe,Overridable as ce,ValidationMessage as de,CustomLabels as pe,Validators as ue,spelNumberCheck as me,SpInput as ge,SpelNumberInput as he,ChecklistInput as fe,useDeepObjectDiff as ve,useMountStatusRef as ye,createFakeReactSyntheticEvent as be,Markdown as we,NameUtils as Ee,AccountSelectInput as Ce,RegionSelectField as ke,InfrastructureCaches as Se,LoadBalancerWriter as Ge,ManagedMenuItem as Ne,SECURITY_GROUP_READER as Te,LOAD_BALANCER_READ_SERVICE as Ie,MANAGED_RESOURCE_DETAILS_INDICATOR as xe,APPLICATION_STATE_PROVIDER as Ae,Registry as Pe,BakeExecutionLabel as ze,AuthenticationService as Be,PipelineTemplates as De,BakeryReader as $e,StageConstants as Me,AppListExtractor as Fe,StageConfigField as Le,yamlDocumentsToString as Re,ExecutionDetailsSection as Oe,ExecutionStepDetails as Ue,StageFailureMessage as Ve,NgGenericArtifactDelegate as je,ExpectedArtifactSelectorViewController as qe,ExecutionBarLabel as He,ExpectedArtifactService as We,ArtifactReferenceService as Ze,EXECUTION_SERVICE as _e,PipelineConfigService as Ke,ModalWizard as Ye,SecurityGroupWriter as Xe,filterObjectValues as Qe,CACHE_INITIALIZER_SERVICE as Je,confirmNotManaged as et,DeployInitializer as tt,DeployingIntoManagedClusterWarning as at,ServerGroupDetailsField as nt,DeploymentStrategySelector as rt,ServerGroupNamePreview as it,TaskReason as st,ToggleButtonGroup as lt,ToggleSize as ot,NgReact as ct,PlatformHealthOverride as dt,MapEditor as pt,UserVerification as ut,TaskMonitorWrapper as mt,MinMaxDesiredChanges as gt,ServerGroupWarningMessageService as ht,ModalInjector as ft,ClusterTargetBuilder as vt,ServerGroupReader as yt,EntitySource as bt,ViewChangesLink as wt,CapacityDetailsSection as Et,ViewScalingActivitiesLink as Ct,ShowUserData as kt,setMatchingResourceSummary as St,SERVER_GROUP_COMMAND_REGISTRY_PROVIDER as Gt,INSTANCE_TYPE_SERVICE as Nt,SERVER_GROUP_WRITER as Tt,CloudMetricsReader as It,useForceUpdate as xt,useObservable as At,ApplicationNameValidator as Pt}from"@spinnaker/core";import*as zt from"react";import Bt,{useState as Dt}from"react";import $t,{isEmpty as Mt,forOwn as Ft,uniqBy as Lt,cloneDeep as Rt,flatten as Ot,isNil as Ut,orderBy as Vt,isEqual as jt,sortBy as qt,pickBy as Ht,groupBy as Wt,get as Zt,uniq as _t,difference as Kt,some as Yt,isNumber as Xt,filter as Qt,set as Jt,chain as ea,partition as ta,map as aa,every as na,values as ra,head as ia,extend as sa,intersection as la,find as oa,has as ca,clone as da,keys as pa,xor as ua,flatMap as ma,defaults as ga}from"lodash";import ha from"classnames";import{Subject as fa,from as va,combineLatest as ya,BehaviorSubject as ba,of as wa,Observable as Ea}from"rxjs";import{map as Ca,distinctUntilChanged as ka,shareReplay as Sa,switchMap as Ga,withLatestFrom as Na,takeUntil as Ta,tap as Ia,mergeMap as xa,catchError as Aa,debounceTime as Pa,take as za}from"rxjs/operators";import{Dropdown as Ba,Modal as Da,Button as $a,Tooltip as Ma,OverlayTrigger as Fa,ModalFooter as La,MenuItem as Ra}from"react-bootstrap";import{angular2react as Oa}from"angular2react";import{$q as Ua}from"ngimport";import{react2angular as Va}from"react2angular";import{UISref as ja,UISrefActive as qa}from"@uirouter/react";import{UIRouterContextComponent as Ha}from"@uirouter/react-hybrid";import Wa from"@uirouter/angularjs";import Za from"angular-ui-bootstrap";import{SortableHandle as _a,arrayMove as Ka,SortableElement as Ya,SortableContainer as Xa}from"react-sortable-hoc";import{Form as Qa,Field as Ja}from"formik";import en from"react-select";import tn from"react-virtualized-select";import{Chart as an,LineController as nn,LineElement as rn,PointElement as sn,LinearScale as ln,Title as on,TimeScale as cn,Tooltip as dn,Legend as pn,Filler as un}from"chart.js";import"chartjs-adapter-luxon";const mn={bindings:{action:"&",isValid:"&",cancel:"&",account:"=?",verification:"=?"},template:'\n <div class="modal-footer">\n <user-verification account="$ctrl.account" verification="$ctrl.verification"></user-verification>\n <button type="submit" ng-click="$ctrl.action()" style="display:none"></button> \x3c!-- Allows form submission via enter keypress--\x3e\n <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>\n <button type="submit"\n class="btn btn-primary"\n ng-click="$ctrl.action()"\n ng-disabled="!$ctrl.isValid()">\n Submit\n </button>\n </div>\n ',controller:()=>{}};t("spinnaker.amazon.footer",[]).component("awsFooter",mn);t("spinnaker.amazon.common",["spinnaker.amazon.footer"]);const gn=a.providers.aws||{defaults:{}};gn&&(gn.resetToOriginal=a.resetProvider("aws"));class hn extends Bt.Component{constructor(){super(...arguments),this.handleChange=(e,t)=>{this.props.command.termination[e]=t,this.forceUpdate()}}render(){var e;const{command:t}=this.props;return Bt.createElement("div",{className:"form-group",style:{marginTop:"20px"}},Bt.createElement("div",{className:"well-compact alert alert-warning"},Bt.createElement("strong",null,"Note:")," a rolling push only updates the"," ",Bt.createElement("em",null,"launch ",Boolean(null==(e=gn.serverGroups)?void 0:e.enableLaunchTemplates)?"template":"configuration")," ","for the auto scaling group.",Bt.createElement("br",null)," Changes to the following fields will be ignored:",Bt.createElement("ul",null,Bt.createElement("li",null,"Account, Region, Subnet Type"),Bt.createElement("li",null,"Capacity"),Bt.createElement("li",null,"Load Balancers"),Bt.createElement("li",null,"Health Check Configuration"),Bt.createElement("li",null,"Termination Policies, Enable Traffic flag"))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",checked:t.termination.relaunchAllInstances,onChange:e=>this.handleChange("relaunchAllInstances",e.target.checked)}),Bt.createElement("b",null,"Relaunch all instances"),Bt.createElement(n,{id:"strategy.rollingPush.relaunchAll"})))),!t.termination.relaunchAllInstances&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},"Total relaunches",Bt.createElement(n,{id:"strategy.rollingPush.totalRelaunches"})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement("input",{className:"form-control input-sm",type:"number",value:t.termination.totalRelaunches,onChange:e=>this.handleChange("totalRelaunches",e.target.value),min:"0"}))),(t.termination.totalRelaunches>0||t.termination.relaunchAllInstances)&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},"Concurrent relaunches",Bt.createElement(n,{id:"strategy.rollingPush.concurrentRelaunches"})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement("input",{className:"form-control input-sm",type:"number",value:t.termination.concurrentRelaunches,onChange:e=>this.handleChange("concurrentRelaunches",e.target.value),min:"1"}))),(t.termination.totalRelaunches>0||t.termination.relaunchAllInstances)&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},"Order",Bt.createElement(n,{id:"strategy.rollingPush.order"})),Bt.createElement("div",{className:"col-md-3"},Bt.createElement("select",{className:"input input-sm",style:{width:"100px"},value:t.termination.order,onChange:e=>this.handleChange("order",e.target.value)},Bt.createElement("option",{value:"oldest"},"oldest first"),Bt.createElement("option",{value:"newest"},"newest first")))))}}var fn;r.registerStrategy({label:"Rolling Push (not recommended)",description:`Updates the launch ${(null==(fn=gn.serverGroups)?void 0:fn.enableLaunchTemplates)?"template":"configuration"} for this server group, then terminates instances incrementally,\n replacing them with instances launched with the updated configuration. This is not a best practice - it goes against\n the principles of immutable infrastructure - but may be necessary in some cases.`,key:"rollingpush",providerRestricted:!0,additionalFields:["termination.totalRelaunches","termination.concurrentRelaunches","termination.order","termination.relaunchAllInstances"],AdditionalFieldsComponent:hn,initializationMethod:e=>{var t,a;e.termination=e.termination||{order:"oldest",relaunchAllInstances:!0,concurrentRelaunches:1,totalRelaunches:null!=(a=Number(null==(t=null==e?void 0:e.capacity)?void 0:t.max))?a:1}}});class vn{constructor(){this.convertFunctionForEditing=e=>({...e,envVariables:e.environment?e.environment.variables:{},credentials:e.account,tracingConfig:{mode:e.tracingConfig?e.tracingConfig.mode:""},deadLetterConfig:{targetArn:e.deadLetterConfig?e.deadLetterConfig.targetArn:""},KMSKeyArn:e.kmskeyArn?e.kmskeyArn:"",subnetIds:e.vpcConfig?e.vpcConfig.subnetIds:[],securityGroupIds:e.vpcConfig?e.vpcConfig.securityGroupIds:[],vpcId:e.vpcConfig?e.vpcConfig.vpcId:"",operation:"",cloudProvider:e.cloudProvider,region:e.region,targetGroups:Mt(e.targetGroups)?"":e.targetGroups})}normalizeFunction(e){const t=e;return t.credentials=e.account,t}constructNewAwsFunctionTemplate(e){return{role:"",runtime:"",s3bucket:"",s3key:"",handler:"",functionName:"",publish:!1,tags:{},memorySize:128,description:"",credentials:e.defaultCredentials.aws||gn.defaults.account,cloudProvider:"aws",detail:"",region:e.defaultRegions.aws||gn.defaults.region,envVariables:{},tracingConfig:{mode:"PassThrough"},kmskeyArn:"",vpcId:"",subnetIds:[],securityGroupIds:[],timeout:3,deadLetterConfig:{targetArn:""},operation:"",targetGroups:""}}}const yn=(e,t)=>e.match(/^arn:aws:iam::\d{12}:role\/?\/[a-zA-Z_0-9+=,.@\-_/]+/)?void 0:`Invalid role. ${t} must match regular expression: arn:aws:iam::d{12}:role/?[a-zA-Z_0-9+=,.@-_/]+`,bn=(e,t)=>e.match(/^[0-9A-Za-z.-]*[^.]$/)?void 0:`Invalid S3 Bucket name. ${t} must match regular expression: [0-9A-Za-z.-]*[^.]$`,wn=(e,t)=>e.match(/arn:aws[a-zA-Z-]?:[a-zA-Z_0-9.-]+:./)?void 0:`Invalid ARN. ${t} must match regular expression: /arn:aws[a-zA-Z-]?:[a-zA-Z_0-9.-]+:./`,En=(e,t)=>Mt(e)?`At least one ${t} is required`:void 0;class Cn extends Bt.Component{constructor(e){super(e)}validate(e){const t=new i(e);return t.field("role","Role ARN").required().withValidators(yn),t.validateForm()}render(){return Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-11"},Bt.createElement("div",{className:"sp-margin-m-bottom"},Bt.createElement(s,{name:"role",label:"Role ARN",input:e=>Bt.createElement(l,{...e,placeholder:"Enter role ARN",name:"role"}),required:!0}))))}}const kn=["nodejs10.x","nodejs12.x","java8","java11","python2.7","python3.6","python3.7","python3.8","dotnetcore2.1","dotnetcore3.1","go1.x","ruby2.5","ruby2.7","provided"];class Sn extends Bt.Component{constructor(){super(...arguments),this.state={accounts:[],existingFunctionNames:[],regions:[]},this.props$=new fa,this.destroy$=new fa}validate(e){const t=new i(e);t.field("s3bucket","S3 Bucket Name").optional().withValidators(bn);const a=t.validateForm();return this.props.isNew&&this.state.existingFunctionNames.includes(this.props.app.name.concat("-").concat(e.functionName))&&(a.functionName=`There is already a function in ${e.credentials}:${e.region} with that name.`),a}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}componentDidMount(){const e=this.props$.pipe(Ca((e=>e.formik.values))),t={account$:e.pipe(Ca((e=>e.credentials)),ka()),region$:e.pipe(Ca((e=>e.region)),ka()),functionName$:e.pipe(Ca((e=>e.functionName)),ka()),runtime$:e.pipe(Ca((e=>e.runtime)),ka()),s3bucket$:e.pipe(Ca((e=>e.s3bucket)),ka()),s3key$:e.pipe(Ca((e=>e.s3key)),ka()),handler$:e.pipe(Ca((e=>e.handler)),ka())},a=va(o.listAccounts("aws")).pipe(Sa(1)),n=ya([t.account$,a]).pipe(Ga((([e,t])=>o.getRegionsForAccount(e))),Sa(1)),r=this.props.app.getDataSource("functions").data$,i=ya([r,t.account$,t.region$]).pipe(Ca((([e,t,a])=>e.filter((e=>e.account===t&&e.region===a)).map((e=>e.functionName)))),Sa(1));n.pipe(Na(t.region$),Ta(this.destroy$)).subscribe((([e,t])=>{e.some((e=>e.name===t))||this.props.formik.setFieldValue("region",e[0]&&e[0].name)})),ya([a,n,i]).pipe(Ta(this.destroy$)).subscribe((([e,t,a])=>this.setState({accounts:e,regions:t,existingFunctionNames:a})))}render(){const{isNew:e}=this.props,{errors:t,values:a}=this.props.formik,{accounts:r,regions:i}=this.state,o=ha({well:!0,"alert-danger":!!t.functionName,"alert-info":!t.functionName});return Bt.createElement("div",{className:"container-fluid form-horizontal "},e&&Bt.createElement("div",{className:o},Bt.createElement("strong",null,"Your function will be named: "),Bt.createElement(n,{id:"aws.function.name"}),Bt.createElement("span",null,this.props.app.name,"-",a.functionName),Bt.createElement(s,{name:"functionName",input:()=>null})),Bt.createElement(s,{name:"credentials",label:"Account",input:e=>Bt.createElement(c,{...e,stringOptions:r.map((e=>e.name)),clearable:!0})}),Bt.createElement(s,{name:"region",label:"Region",input:e=>Bt.createElement(c,{...e,stringOptions:i.map((e=>e.name)),clearable:!0})}),Bt.createElement(s,{name:"functionName",label:"Function Name",help:Bt.createElement(n,{id:"aws.function.name"}),input:e=>Bt.createElement(l,{...e})}),Bt.createElement(s,{name:"runtime",label:"Runtime",help:Bt.createElement(n,{id:"aws.function.runtime"}),input:e=>Bt.createElement(c,{...e,stringOptions:kn,clearable:!0})}),Bt.createElement(s,{name:"s3bucket",label:"S3 Bucket",help:Bt.createElement(n,{id:"aws.function.s3bucket"}),input:e=>Bt.createElement(l,{...e,placeholder:"S3 bucket name"})}),Bt.createElement(s,{name:"s3key",label:"S3 Key",help:Bt.createElement(n,{id:"aws.function.s3key"}),input:e=>Bt.createElement(l,{...e,placeholder:"object.zip"})}),Bt.createElement(s,{name:"handler",label:"Handler",help:Bt.createElement(n,{id:"aws.function.handler"}),input:e=>Bt.createElement(l,{...e,placeholder:"filename.method"})}),Bt.createElement(s,{name:"publish",label:"Publish",input:e=>Bt.createElement(d,{...e})}))}}class Gn extends Bt.Component{constructor(e){super(e),this.validate=e=>{const t=new i(e);return t.field("deadLetterConfig.targetArn","Target ARN").optional().withValidators(wn),t.validateForm()}}render(){return Bt.createElement("div",{className:"container-fluid form-horizontal "},"Dead Letter Config",Bt.createElement(s,{name:"deadLetterConfig.targetArn",label:"Target ARN",help:Bt.createElement(n,{id:"aws.function.deadletterqueue"}),input:e=>Bt.createElement(l,{...e})}),"X-Ray Tracing",Bt.createElement(s,{name:"tracingConfig.mode",label:"Mode",help:Bt.createElement(n,{id:"aws.function.tracingConfig.mode"}),input:e=>Bt.createElement(c,{...e,stringOptions:["Active","PassThrough"],clearable:!0})}))}}class Nn extends Bt.Component{constructor(){super(...arguments),this.validate=e=>{const t=new i(e);return t.field("kmskeyArn","KMS Key ARN").optional().withValidators(wn),t.validateForm()}}render(){return Bt.createElement("div",{className:"container-fluid form-horizontal "},Bt.createElement(s,{name:"envVariables",label:"Env Variables",input:e=>Bt.createElement(p,{...e,allowEmptyValues:!0,addButtonLabel:"Add"})}),Bt.createElement(s,{name:"kmskeyArn",label:"Key ARN",help:Bt.createElement(n,{id:"aws.function.kmsKeyArn"}),input:e=>Bt.createElement(l,{...e})}))}}class Tn extends Bt.Component{constructor(){super(...arguments),this.validate=()=>({})}render(){return Bt.createElement("div",{className:"container-fluid form-horizontal "},Bt.createElement(s,{name:"description",label:"Description",input:e=>Bt.createElement(l,{...e})}),Bt.createElement(s,{name:"memorySize",label:"Memory (MB)",help:Bt.createElement(n,{id:"aws.functionBasicSettings.memorySize"}),input:e=>Bt.createElement(u,{...e,min:128,max:3008})}),Bt.createElement(s,{name:"timeout",label:"Timeout (seconds)",help:Bt.createElement(n,{id:"aws.functionBasicSettings.timeout"}),input:e=>Bt.createElement(u,{...e,min:1,max:900})}),Bt.createElement(s,{name:"targetGroups",label:"Target Group Name",input:e=>Bt.createElement(l,{...e})}))}}class In extends Bt.Component{constructor(){super(...arguments),this.validate=e=>{const t=new i(e);return t.field("tags","Tag").required().withValidators(En),t.validateForm()}}render(){return Bt.createElement("div",{className:"container-fluid form-horizontal "},Bt.createElement(s,{name:"tags",input:e=>Bt.createElement(p,{...e,allowEmptyValues:!1,addButtonLabel:"Add"})}))}}class xn{static listVpcs(){return this.cache||(this.cache=m.listNetworksByProvider("aws").then((e=>e.map((e=>(e.label=e.name,e.deprecated=!!e.deprecated,e.deprecated&&(e.label+=" (deprecated)"),e)))))),this.cache}static resetCache(){this.cache=null}static getVpcName(e){return this.listVpcs().then((t=>{const a=t.find((t=>t.id===e));return a?a.name:null}))}}class An extends Bt.Component{constructor(e){super(e),this.state={vpcOptions:[],accounts:null,regions:[],subnets:[],availableSubnets:[],securityGroups:null},this.props$=new fa,this.destroy$=new fa,this.handleSubnetUpdate=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("subnetIds",t)},this.handleSecurityGroupsUpdate=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("securityGroupIds",t)},this.setVpc=e=>{this.props.formik.setFieldValue("vpcId",e),this.props.formik.setFieldValue("subnetIds",[]);const{availableSubnets:t}=this.state,a=t.filter((function(t){return t.vpcId.includes(e)}));this.setState({subnets:a})},this.toSubnetOption=e=>({value:e.subnetId,label:e.subnetId}),this.getSecurityGroupsByVpc=e=>{const{values:t}=this.props.formik,a=[];return Ft(e,(function(e,n){n===t.credentials&&Ft(e,(function(e,n){"aws"===n&&Ft(e,(function(e,n){n===t.region&&e.forEach((function(e){e.vpcId===t.vpcId&&a.push({value:e.id,label:e.name})}))}))}))})),a},this.getSubnetOptions=()=>{const{subnets:e,availableSubnets:t}=this.state,{values:a}=this.props.formik;return!this.props.isNew&&a.vpcId?t.filter((function(e){return e.vpcId.includes(a.vpcId)})).map(this.toSubnetOption):e.map(this.toSubnetOption)},this.getAllVpcs()}getAllVpcs(){va(xn.listVpcs()).pipe(Ta(this.destroy$)).subscribe((e=>{this.setState({vpcOptions:e})}))}validate(){return{}}getAvailableSubnets(){return g.listSubnetsByProvider("aws")}getAvailableSecurityGroups(){return h.securityGroupReader.getAllSecurityGroups()}makeSubnetOptions(e){const t=e.map((e=>({subnetId:e.id,vpcId:e.vpcId})));return Lt(t,"subnetId")}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}componentDidMount(){const e=Promise.resolve(this.getAvailableSubnets()).then((e=>(e.forEach((e=>{e.label=e.id,e.deprecated=!!e.deprecated,e.deprecated&&(e.label+=" (deprecated)")})),e.filter((e=>e.label))))).then((e=>this.makeSubnetOptions(e))),t=Promise.resolve(this.getAvailableSecurityGroups());ya([e,t]).pipe(Ta(this.destroy$)).subscribe((([e,t])=>this.setState({availableSubnets:e,securityGroups:t})))}render(){const{vpcOptions:e,securityGroups:t}=this.state,{values:a}=this.props.formik,r=this.getSubnetOptions(),i=t?this.getSecurityGroupsByVpc(t):[];return Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-11"},Bt.createElement("div",{className:"sp-margin-m-bottom"},a.credentials&&Bt.createElement(s,{name:"vpcId",label:"VPC Id",help:Bt.createElement(n,{id:"aws.function.vpc.id"}),input:t=>Bt.createElement(c,{...t,stringOptions:e.filter((e=>e.account===a.credentials)).map((e=>e.id)),clearable:!0}),onChange:this.setVpc,required:!1})),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-4 sm-label-right"},Bt.createElement("b",null,"Subnets "),Bt.createElement(n,{id:"aws.function.subnet"})),Bt.createElement("div",{className:"col-md-7"},0===r.length&&Bt.createElement("div",{className:"form-control-static"},"No subnets found in the selected account/region/VPC"),a.vpcId?Bt.createElement(f,{multi:!0,options:r,value:a.subnetIds,onChange:this.handleSubnetUpdate}):null)),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-4 sm-label-right"},Bt.createElement("b",null,"Security Groups "),Bt.createElement(n,{id:"aws.function.subnet"})),Bt.createElement("div",{className:"col-md-7"},0===i.length&&Bt.createElement("div",{className:"form-control-static"},"No security groups found in the selected account/region/VPC"),a.credentials&&a.vpcId?Bt.createElement(f,{multi:!0,options:i,value:a.securityGroupIds,onChange:this.handleSecurityGroupsUpdate}):null))))}}const Pn=class extends Bt.Component{constructor(e){super(e),this._isUnmounted=!1,this.submit=e=>{const{app:t}=this.props,{isNew:a}=this.state,n=Rt(e),r=a?"Create":"Update",i=new v({application:t,title:(a?"Creating":"Updating")+" your function",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>{this.checkForS3Update(n,r)}});i.submit((()=>(n.type="lambdaFunction",n.operation=a?"createLambdaFunction":"updateLambdaFunctionConfiguration",y.upsertFunction(n,t,r)))),this.setState({taskMonitor:i})};const t=new vn,a=e.functionDef?t.convertFunctionForEditing(e.functionDef):t.constructNewAwsFunctionTemplate(e.app);this.state={isNew:!e.functionDef,functionCommand:a,taskMonitor:null}}static show(e){return b.show(Pn,e,{dialogClassName:"wizard-modal modal-lg"})}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.functionDetails")?h.$state.go("^.functionDetails",t):h.$state.go(".functionDetails",t)}onTaskComplete(e){this.props.app.functions.refresh(),this.refreshUnsubscribe=this.props.app.functions.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}checkForS3Update(e,t){const{isNew:a}=this.state;if(!a&&(e.s3bucket||e.s3key)){e.operation="updateLambdaFunctionCode";const{app:a}=this.props;y.upsertFunction(e,a,t)}this.onTaskComplete(e)}render(){const{app:e,dismissModal:t,forPipelineConfig:a,functionDef:n}=this.props,{isNew:r,functionCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Existing Function":"Create New Function";return r||(l=`Edit ${i.functionName}: ${i.region}: ${i.credentials}`),Bt.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",render:({formik:t,nextIdx:a,wizard:i})=>Bt.createElement(Bt.Fragment,null,Bt.createElement(E,{label:"Basic information",wizard:i,order:a(),render:({innerRef:a})=>Bt.createElement(Sn,{ref:a,app:e,formik:t,isNew:r,functionDef:n})}),Bt.createElement(E,{label:"Execution Role",wizard:i,order:a(),render:({innerRef:e})=>Bt.createElement(Cn,{ref:e,formik:t,isNew:r,functionDef:n})}),Bt.createElement(E,{label:"Environment",wizard:i,order:a(),render:({innerRef:e})=>Bt.createElement(Nn,{ref:e,formik:t,isNew:r,functionDef:n})}),Bt.createElement(E,{label:"Tags",wizard:i,order:a(),render:({innerRef:e})=>Bt.createElement(In,{ref:e,formik:t,isNew:r,functionDef:n})}),Bt.createElement(E,{label:"Settings",wizard:i,order:a(),render:({innerRef:e})=>Bt.createElement(Tn,{ref:e,formik:t,isNew:r,functionDef:n})}),Bt.createElement(E,{label:"Network",wizard:i,order:a(),render:({innerRef:a})=>Bt.createElement(An,{ref:a,app:e,formik:t,isNew:r})}),Bt.createElement(E,{label:"Debugging and Error Handling",wizard:i,order:a(),render:({innerRef:e})=>Bt.createElement(Gn,{ref:e,formik:t,isNew:r,functionDef:n})}))})}};let zn=Pn;zn.defaultProps={closeModal:C,dismissModal:C};class Bn extends Bt.Component{constructor(e){super(e),this.editFunction=()=>{const{functionDef:e}=this.props,{application:t}=this.state;zn.show({app:t,functionDef:e})},this.deleteFunction=()=>{const{app:e,functionDef:t,functionFromParams:a}=this.props,n={application:e,title:"Deleting "+a.functionName},r={cloudProvider:t.cloudProvider,functionName:t.functionName,region:t.region,credentials:t.credentials};k.confirm({header:`Really delete ${a.functionName} in ${a.region}: ${a.account}?`,buttonText:`Delete ${a.functionName}`,account:a.account,taskMonitorConfig:n,submitMethod:()=>y.deleteFunction(r,e)})},this.entityTagUpdate=()=>{this.props.app.functions.refresh()},this.state={application:e.app}}componentDidMount(){const{app:e,functionDef:t}=this.props;let a;const n=t.functionName.split("-")[0];n===e.name?a=e:S.getApplication(n).then((e=>{this.setState({application:e})})).catch((()=>{this.setState({application:this.props.app})})),this.setState({application:a})}render(){const{app:e,functionDef:t}=this.props,{application:n}=this.state;return Bt.createElement("div",{style:{display:"inline-block"}},Bt.createElement(Ba,{className:"dropdown",id:"function-actions-dropdown"},Bt.createElement(Ba.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},Bt.createElement("span",null,"Function Actions")),Bt.createElement(Ba.Menu,{className:"dropdown-menu"},Bt.createElement("li",{className:n?"":"disabled"},Bt.createElement("a",{className:"clickable",onClick:this.editFunction},"Edit Function")),t.functionName&&Bt.createElement("li",null,Bt.createElement("a",{className:"clickable",onClick:this.deleteFunction},"Delete Function")),a&&a.feature.entityTags&&Bt.createElement(G,{component:t,application:e,entityType:"function",onUpdate:this.entityTagUpdate}))))}}class Dn{constructor(){this.policyTypes=[]}registerPolicyType(e){this.policyTypes.push(e)}getPolicyConfig(e){return this.policyTypes.find((t=>t.type===e))}}const $n=new Dn;const Mn={bindings:{policy:"<",serverGroup:"<",application:"<"},controller:class{$onInit(){const e=$n.getPolicyConfig(this.policy.policyType);this.templateUrl=e?e.summaryTemplateUrl:"amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html"}},template:'<div ng-include src="$ctrl.templateUrl"></div>'},Fn="spinnaker.amazon.scalingPolicy.details.summary.component";t(Fn,[]).component("scalingPolicySummary",Mn),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html",'<alarm-based-summary\n policy="$ctrl.policy"\n server-group="$ctrl.serverGroup"\n application="$ctrl.application"\n></alarm-based-summary>\n')}]);class Ln extends N{constructor(){super(...arguments),this.$injectorProxy={},this.ScalingPolicySummary=Oa("scalingPolicySummary",Mn,this.$injectorProxy)}initialize(e){const t=e,a=this.$injectorProxy;Object.keys(e).filter((e=>"function"==typeof t[e])).forEach((e=>a[e]=t[e].bind(t)))}}const Rn=new Ln;class On extends N{get awsInstanceTypeService(){return this.$injector.get("awsInstanceTypeService")}get awsServerGroupCommandBuilder(){return this.$injector.get("awsServerGroupCommandBuilder")}get awsServerGroupConfigurationService(){return this.$injector.get("awsServerGroupConfigurationService")}get awsServerGroupTransformer(){return this.$injector.get("awsServerGroupTransformer")}get functionReader(){return this.$injector.get("functionReader")}get evaluateCloudFormationChangeSetExecutionService(){return this.$injector.get("evaluateCloudFormationChangeSetExecutionService")}initialize(e){this.$injector=e}}const Un=new On;var Vn=Object.defineProperty,jn=Object.getOwnPropertyDescriptor;let qn=class extends Bt.Component{constructor(e){super(e),this.destroy$=new fa,this.state={loading:!0}}extractFunction(){const{app:e,functionObj:t}=this.props;e.functions.data.find((e=>e.functionName===t.functionName&&e.region===t.region&&e.account===t.account))?va(Un.functionReader.getFunctionDetails("aws",t.account,t.region,t.functionName)).pipe(Ta(this.destroy$)).subscribe((e=>{e.length&&this.setState({functionDef:e[0],loading:!1})})):this.setState({functionDef:{},loading:!1})}componentDidMount(){const{app:e}=this.props,t=e.functions;va(t.ready()).pipe(Ta(this.destroy$)).subscribe((()=>{const e=t.onRefresh(null,(()=>this.extractFunction()));this.setState({dataSourceUnsubscribe:e}),this.extractFunction()}))}componentWillUnmount(){this.state.dataSourceUnsubscribe&&this.state.dataSourceUnsubscribe(),this.destroy$.next()}render(){const{app:e}=this.props,{loading:t,functionDef:a}=this.state;if(t)return Bt.createElement(T,{loading:t});const n=Bt.createElement("dl",{className:"horizontal-when-filters-collapsed dl-horizontal dl-narrow"},Bt.createElement("dt",null,"Last Modified "),Bt.createElement("dd",null,a.lastModified),Bt.createElement("dt",null,"In"),Bt.createElement("dd",null,Bt.createElement(I,{account:a.account})," ",a.region),Bt.createElement("dt",null,"VPC"),Bt.createElement("dd",null,a.vpcConfig?a.vpcConfig.vpcId:"Default"),Bt.createElement("dt",null,"Function ARN"),Bt.createElement("dd",null,a.functionArn),Bt.createElement("dt",null,"Revision ID"),Bt.createElement("dd",null,a.revisionId),Bt.createElement("dt",null,"Version"),Bt.createElement("dd",null,a.version),Bt.createElement("dt",null,"Event Source"),Bt.createElement("dd",null,a.eventSourceMappings&&0!==a.eventSourceMappings.length?a.eventSourceMappings:"None")),r=Bt.createElement(A,{heading:"Function Details"},n);return Bt.createElement(T,{loading:this.state.loading},Mt(this.state.functionDef)?"Function not found.":Bt.createElement(T.Header,{icon:Bt.createElement("i",{className:"fa fa-xs fa-fw fa-asterisk"}),name:this.state.functionDef.functionName},Bt.createElement("div",{className:"actions"},Bt.createElement(Bn,{app:e,functionDef:a,functionFromParams:{account:this.state.functionDef.account,region:this.state.functionDef.region,functionName:this.state.functionDef.functionName}}))),Mt(this.state.functionDef)?"":r)}};qn=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?jn(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Vn(t,a,i),i})([x("function.details","aws")],qn);t("spinnaker.amazon.function",[]);const Hn={"aws.associateElasticIp.elasticIp":"<p>(Optional) <b>Elastic IP</b> is an IP address that Spinnaker will associate with this cluster.</p>\n <p>If specified, this elastic IP must exist and not already be attached to an instance or cluster.</p>\n <p>If left blank, Spinnaker will make a selection from the list of available elastic IPs in the provided account and region.</p>","aws.associateElasticIp.type":"<p><b>Type</b> of elastic IP to associate:'\n <ul>\n <li><b>standard</b> is usable in EC2 Classic</li>\n <li><b>vpc</b> is usable in VPC</li>\n </ul>","aws.serverGroup.subnet":"The subnet selection determines the VPC in which your server group will run. Options vary by account and region; the most common ones are:\n <ul>\n <li><b>None (EC2 Classic)</b>: instances will not run in a VPC</li>\n <li><b>internal</b> instances will be restricted to internal clients (i.e. require VPN access)</li>\n <li><b>external</b> instances will be publicly accessible and running in VPC</li>\n </ul>","aws.loadBalancer.subnet":"The subnet selection determines the VPC in which your load balancer will run.<br/>\n This also restricts the server groups which can be serviced by the load balancer.\n Options vary by account and region; the most common ones are:\n <ul>\n <li><b>None (EC2 Classic)</b>: the load balancer will not run in a VPC</li>\n <li><b>internal</b> access to the load balancer will be restricted to internal clients (i.e. require VPN access)</li>\n <li><b>external</b> the load balancer will be publicly accessible and running in VPC</li>\n </ul>","aws.loadBalancer.detail":'<p>(Optional) <b>Detail</b> is a string of free-form alphanumeric characters; by convention, we recommend using "frontend".</p>\n <p>However, if your stack name needs to be longer (load balancer names are limited to 32 characters), consider changing it to "elb", or omit it altogether.</p>',"aws.loadBalancer.internal":"Controls the load balancer scheme, <strong>not</strong> the subnet. By default, load balancers are created with a DNS name that resolves to public IP addresses. Specify internal to create a load balancer with a DNS name that resolves to private IP addresses.","aws.loadBalancer.stack":"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","aws.loadBalancer.name":"<p>The load balancer name is formed by combining the application name, the <b>Stack</b> field, and the <b>Detail</b> field.</p>","aws.loadBalancer.targetGroups":"Add a target group if you want to associate this with an Application Load Balancer (ALB) or Network Load Balancer (NLB)","aws.loadBalancer.loadBalancers":"Add a load balancer directly if you created a Classic Load Balancer (a classic load balancer does not have target groups)","aws.loadBalancer.ruleCondition.host":"<p>You can specify a single host name (for example, <em>my.example.com</em>). A host name is case insensitive, can be up to 128 characters in length, and can contain any of the following characters. Note that you can include up to three wildcard characters.</p>\n <ul>\n <li>A-Z, a-z, 0-9</li>\n <li>- .</li>\n <li>* (matches 0 or more characters)</li>\n <li>? (matches exactly 1 character)</li>\n </ul>\n <p>Note that <strong>*.example.com</strong> will match <strong>test.example.com</strong> but won't match <strong>example.com</strong>.</p>","aws.loadBalancer.ruleCondition.path":"<p>You can specify a single path pattern (for example, <em>/img/*</em>). A path pattern is case sensitive, can be up to 128 characters in length, and can contain any of the following characters. Note that you can include up to three wildcard characters.</p>\n <ul>\n <li>A-Z, a-z, 0-9</li>\n <li>_ - . $ / ~ \" ' @ : +</li>\n <li>& (using &amp;amp;)</li>\n <li>* (matches 0 or more characters)</li>\n <li>? (matches exactly 1 character)</li>\n </ul>\n <p>Note that the path pattern is used to route requests but does not alter them. For example, if a rule has a path pattern of <em>/img/*</em>, the rule would forward a request for <em>/img/picture.jpg</em> to the specified target group as a request for <em>/img/picture.jpg</em>.</p>","aws.loadBalancer.oidcAuthentication":"Authentication requires a configured OIDC client.","aws.serverGroup.stack":"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","aws.serverGroup.detail":"(Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables.","aws.serverGroup.imageName":"(Required) <b>Image</b> is the deployable Amazon Machine Image. Images are restricted to the account and region selected.","aws.serverGroup.spotMaxPrice":"The maximum price per unit hour to pay for a Spot instance. By default (empty), Amazon EC2 Auto Scaling uses the On-Demand price as the maximum Spot price","aws.serverGroup.spotAllocationStrategy":"<p>Indicates how to allocate instances across Spot Instance pools.</p>\n <ul>\n <li><b>capacity-optimized (recommended)</b>: Instances launched using Spot pools that are optimally chosen based on the available Spot capacity.</li>\n <li><b>capacity-optimized-prioritized</b>: Instances launched using the priority on a best-effort basis to determine which launch template override to use first, but AWS optimizes for capacity first.</li>\n <li><b>lowest-price</b>: Instances launched using Spot pools with the lowest price, and evenly allocated across the number of Spot pools specified</li>\n </ul>","aws.serverGroup.spotInstancePoolCount":"Number of lowest priced Spot Instance pools to diversify across. Only applicable for strategy 'lowest-price'.","aws.serverGroup.odAllocationStrategy":"The only strategy / default is 'prioritized'. The order of instance types in the list of launch template overrides is used to determine which instance type to use first when fulfilling On-Demand capacity.","aws.serverGroup.odBase":"Minimum amount of the Auto Scaling Group's capacity that must be fulfilled by On-Demand Instances. This base portion is provisioned first as the group scales.","aws.serverGroup.odPercentAboveBase":"Percentages of On-Demand and Spot instances for additional capacity beyond OnDemandBaseCapacity.","aws.serverGroup.instanceTypeWeight":"The number of capacity units gives the instance type a proportional weight to other instance types. When specified, weights count towards desired capacity.","aws.serverGroup.instanceTypes":"Specify up to 20 instance types.","aws.serverGroup.multipleInstanceTypes":"Instance types a server group can launch, first (highest priority) to last (lowest priority).","aws.serverGroup.unlimitedCpuCredits":"<p>CPU credits can be configured with 2 modes:</p><br/>\n <ul>\n <li><b>Unlimited (i.e. Unlimited On)</b>: Can sustain high CPU utilization for any period of time whenever required.<br/>\n If the average CPU usage over a rolling 24-hour period exceeds the baseline, charges for surplus credits will apply.</li>\n <li><b>Standard (i.e. Unlimited Off)</b>: <b>Default mode in Spinnaker.</b> Suited to workloads with an average CPU utilization that is consistently below the baseline CPU utilization of the instance.<br/>\n To burst above the baseline, the instance spends credits that it has accrued in its CPU credit balance.</li>\n </ul>","aws.serverGroup.capacityRebalance":"Enabling <b>Capacity Rebalance</b> allows EC2 Auto Scaling to proactively replace Spot Instances that have received a rebalance recommendation, <b>before</b> it is interrupted by AWS EC2.","aws.serverGroup.legacyUdf":"<p>(Optional) <b>User Data Format</b> allows overriding of the format used when generating user data during deployment. The default format used is configured\n in the application's attributes, editable via the 'Config' tab.</p>\n <p><b>Default</b> will use the value from the application's configuration.</p>\n <p><b>Modern</b> will use the modern template.</p>\n <p><b>Legacy</b> will use the legacy (<b>deprecated</b>) template.</p>\n <p>This option is intended to allow testing migration from legacy to modern before configuring it for the entire application. If unsure, pick <b>Default</b>.</p>","aws.serverGroup.base64UserData":"(Optional) <b>UserData</b> is a base64 encoded string.","aws.serverGroup.enabledMetrics":"(Optional) <b>Enabled Metrics</b> are the Auto Scaling Group metrics to enable on this group. Existing metrics are not modified.","aws.serverGroup.imdsv2":"(Recommended) <b>IMDSv2</b> helps mitigate AWS credential theft from the exploitation of SSRF vulnerabilities in web applications. All modern AWS SDKs support IMDSv2 and it should not be disabled unless you're using a legacy SDK.","aws.serverGroup.instanceMonitoring":"(Optional) <b>Instance Monitoring</b> whether to enable detailed monitoring of instances. Group metrics must be disabled to update an ASG with Instance Monitoring set to false.","aws.serverGroup.tags":"(Optional) <b>Tags</b> are propagated to the instances in this cluster.","aws.serverGroup.allImages":"Search for an image that does not match the name of your application.","aws.serverGroup.filterImages":"Select from a pre-filtered list of images matching the name of your application.","aws.serverGroup.traffic":'<p>Enables the "AddToLoadBalancer" scaling process, which is used by Spinnaker and discovery services to determine if the server group is enabled.</p>\n <p>Will be automatically enabled when any non "custom" deployment strategy is selected.</p>',"aws.securityGroup.vpc":'\n <p>The VPC to which this {{firewall}} will apply.</p>\n <p>If you wish to use VPC but are unsure which VPC to use, the most common one is "Main".</p>\n <p>If you do not wish to use VPC, select "None".</p>',"aws.securityGroup.name":"<p>The {{firewall}} name is formed by combining the application name, the <b>Stack</b> field, and the <b>Detail</b> field.</p>","aws.securityGroup.cross.account.ingress.help":"<p>Accounts that are excluded will not show up in this list</p>","aws.scalingPolicy.search.restricted":'<p>Resets dimensions to "AutoScalingGroupName: {name of the ASG}" and provides\n a simpler, combined input for the namespace and metric name fields.</p>',"aws.scalingPolicy.search.all":"\n <p>Allows you to edit the dimensions and namespace to find a specific metric for this alarm.</p>","aws.blockDeviceMappings.useSource":'\n <p>Spinnaker will use the block device mappings of the existing server group when deploying a new server group.</p>\n <p>In the event that there is no existing server group, the\n <a target="_blank" href="https://github.com/spinnaker/clouddriver/blob/master/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/InstanceTypeUtils.java">defaults</a>\n for the selected instance type will be used.</p>',"aws.blockDeviceMappings.useAMI":"<p>Spinnaker will use the block device mappings from the selected AMI when deploying a new server group.</p>","aws.blockDeviceMappings.useDefaults":'<p>Spinnaker will use the <a target="_blank" href="https://github.com/spinnaker/clouddriver/blob/master/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/InstanceTypeUtils.java">default block device mappings</a> for the selected instance type when deploying a new server group.</p>',"aws.targetGroup.protocol":"The protocol to use for routing traffic to the targets. Cannot be edited after being saved; if you want to use a different protocol, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.targetType":"Determines how targets are specified. Only set to ip if you need to attach individual ips. Cannot be edited after being saved; if you want to use a different target type, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.port":"The port on which the targets receive traffic. Cannot be edited after being saved; if you want to use a different port, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.attributes.deregistrationDelay":"The amount of time for the load balancer to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds.","aws.targetGroup.attributes.stickinessEnabled":" Indicates whether sticky sessions are enabled.","aws.targetGroup.attributes.deregistrationDelayConnectionTermination":"If enabled, your Network Load Balancer will terminate active connections when deregistration delay is reached.","aws.targetGroup.attributes.preserveClientIp":"If enabled, your Network Load Balancer will preserve client IP addresses to the target.","aws.targetGroup.attributes.stickinessType":"The type of sticky sessions. The only current possible value is <code>lb_cookie</code>.","aws.targetGroup.attributes.stickinessDuration":"The time period, in seconds, during which requests from a client should be routed to the same target. After this time period expires, the load balancer-generated cookie is considered stale. The range is 1 second to 1 week (604800 seconds). The default value is 1 day (86400 seconds).","aws.targetGroup.attributes.healthCheckPort.trafficPort":"The port the load balancer uses when performing health checks on targets. The default is <b>traffic-port</b>, which is the port on which each target receives traffic from the load balancer.","aws.targetGroup.healthCheckProtocol":"TCP health checks only support 10s and 30s intervals","aws.targetGroup.healthCheckTimeout":"Target groups with TCP or TLS protocol must have a 6s timeout for HTTP health checks or a 10s timeout for HTTPS/TLS health checks.","aws.targetGroup.nlbHealthcheckThreshold":"The healthy and unhealthy threshold for NLBs must be equal. This represents the number of successful and failed healthchecks required for healthy and unhealthy targets, respectively.","aws.serverGroup.capacityConstraint":"\n <p>Ensures that the capacity of this server group has not changed in the background (i.e. due to autoscaling activity).</p>\n <p>If the capacity has changed, this resize operation will be rejected.</p>","aws.tagImage.consideredStages":"Limit which previous stages will be considered when locating AMI's to tag. If left unchecked, AMI's generated by any upstream stage will be tagged.","aws.loadBalancer.redirect.host":"The hostname. This component is not percent-encoded. The hostname can contain <code>#{host}</code>.","aws.loadBalancer.redirect.path":'The absolute path, starting with the leading "/". This component is not percent-encoded. The path can contain <code>#{host}</code>, <code>#{path}</code>, and <code>#{port}</code>.',"aws.loadBalancer.redirect.port":"The port. You can specify a value from 1 to 65535 or <code>#{port}</code>.","aws.loadBalancer.redirect.protocol":"The protocol. You can specify HTTP, HTTPS, or <code>#{protocol}</code>. You can redirect HTTP to HTTP, HTTP to HTTPS, and HTTPS to HTTPS. You cannot redirect HTTPS to HTTP.","aws.loadBalancer.redirect.query":'The query parameters, URL-encoded when necessary, but not percent-encoded. Do not include the leading "?", as it is automatically added. You can specify any of the reserved keywords.',"aws.loadBalancer.redirect.statusCode":"The HTTP redirect code. The redirect is either permanent (HTTP 301) or temporary (HTTP 302).","aws.loadBalancer.redirect":'<p>A URI consists of the following components: protocol://hostname:port/path?query. You must modify at least one of the following components to avoid a redirect loop: protocol, hostname, port, or path. Any components that you do not modify retain their original values.\n\n <p>You can reuse URI components using the following reserved keywords:\n\n <ul><li>#{protocol}\n <li>#{host}\n <li>#{port}\n <li>#{path} (the leading "/" is removed)\n <li>#{query}\n </ul>\n <p>For example, you can change the path to "/new/#{path}", the hostname to "example.#{host}", or the query to "#{query}&value=xyz".',"aws.cloudformation.source":"\n <p>Where the template file content is read from.</p>\n <p>\n <b>text:</b> The template is supplied statically to the pipeline from the below text-box.\n </p>\n <p>\n <b>artifact:</b> The template is read from an artifact supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>\n ","aws.cloudformation.expectedArtifact":"The artifact that is to be applied to this stage. The artifact should represent a valid cloudformation template.","aws.function.name":"Enter a name that describes the purpose of your function. Function name will be prefixed with the application name.","aws.function.runtime":"Choose the language to use to write your function","aws.function.s3key":"The Amazon S3 key of the deployment package","aws.function.handler":"The name of the method within your code that Lambda calls to execute your function. The format includes the file name. It can also include namespaces and other qualifiers, depending on the runtime.","aws.function.s3bucket":"An Amazon S3 bucket in the same AWS Region as your function. The bucket can be in a different AWS account.","aws.function.execution.role":"Lambda will create an execution role with permission to upload logs to Amazon CloudWatch Logs. You can also choose an existing role that defines the permissions of your function.","aws.function.env.vars":"You can define environment variables as key-value pairs that are accessible from your function code. These are useful to store configuration settings without the need to change function code","aws.function.tags":"You can use tags to group and filter your functions. A tag consists of a case-sensitive key-value pair","aws.functionBasicSettings.memorySize":"Your function is allocated CPU proportional to the memory configured.","aws.functionBasicSettings.timeout":"The amount of time that Lambda allows a function to run before stopping it. The default is 3 seconds. The maximum allowed value is 900 seconds.","aws.function.publish":"Set to true to publish the first version of the function during creation.","aws.function.deadletterqueue":"A dead letter queue configuration that specifies the queue or topic where Lambda sends asynchronous events when they fail processing. (SNS or SQS)","aws.function.tracingConfig.mode":"The function's AWS X-Ray tracing configuration.","aws.function.kmsKeyArn":"The ARN of the AWS Key Management Service (AWS KMS) key that's used to encrypt your function's environment variables. If it's not provided, AWS Lambda uses a default service key.","aws.cloudformation.changeSet.options":"<p>Action to take when the created ChangeSet contains a replacement.</p>\n <p>\n <b>ask:</b> Execution will be put on hold asking for user feedback.\n </p>\n <p>\n <b>skip it:</b> ChangeSet will not be executed and stage will continue.\n </p>\n <p>\n <b>execute it</b> ChangeSet will be executed.\n </p>\n <p>\n <b>fail stage</b> ChangeSet will not be executed and the stage will fail.\n </p>"};Object.keys(Hn).forEach((e=>P.register(e,Hn[e])));class Wn{findImages(e){return!e.q||e.q.length<3?Ua.when([{message:"Please enter at least 3 characters...",disabled:!0}]):z("/images/find").query(e).get().catch((()=>[]))}getImage(e,t,a){return z("/images").path(a,t,e).query({provider:"aws"}).get().then((e=>e&&e.length?e[0]:null)).catch((()=>null))}}t("spinnaker.amazon.instanceType.service",[]).factory("awsInstanceTypeService",["$q",function(e){const t=[{type:"general",label:"General Purpose",families:[{type:"m5",description:"m5 instances provide a balance of compute, memory, and network resources. They are a good choice for most applications.",instanceTypes:[{name:"m5.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"m5.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"m5.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]},{type:"t2",description:"t2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t2.small",label:"Small",cpu:1,memory:2,storage:{type:"EBS"},costFactor:1},{name:"t2.medium",label:"Medium",cpu:2,memory:4,storage:{type:"EBS"},costFactor:1},{name:"t2.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"t2.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"t2.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]},{type:"t3",description:"t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t3.small",label:"Small",cpu:2,memory:2,storage:{type:"EBS"},costFactor:1},{name:"t3.medium",label:"Medium",cpu:2,memory:4,storage:{type:"EBS"},costFactor:1},{name:"t3.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"t3.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"t3.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]}],icon:"hdd"},{type:"memory",label:"High Memory",families:[{type:"r5",description:"r5 instances are optimized for memory-intensive applications and have the lowest cost per GiB of RAM among Amazon EC2 instance types.",instanceTypes:[{name:"r5.large",label:"Large",cpu:2,memory:16,storage:{type:"EBS"},costFactor:1},{name:"r5.xlarge",label:"XLarge",cpu:4,memory:32,storage:{type:"EBS"},costFactor:2},{name:"r5.2xlarge",label:"2XLarge",cpu:8,memory:64,storage:{type:"EBS"},costFactor:2},{name:"r5.4xlarge",label:"4XLarge",cpu:16,memory:128,storage:{type:"EBS"},costFactor:3}]}],icon:"hdd"},{type:"micro",label:"Micro Utility",families:[{type:"t2",description:"t2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t2.nano",label:"Nano",cpu:1,memory:.5,storage:{type:"EBS"},costFactor:1},{name:"t2.micro",label:"Micro",cpu:1,memory:1,storage:{type:"EBS"},costFactor:1},{name:"t2.small",label:"Small",cpu:1,memory:2,storage:{type:"EBS"},costFactor:1}]},{type:"t3",description:"t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t3.nano",label:"Nano",cpu:2,memory:.5,storage:{type:"EBS"},costFactor:1},{name:"t3.micro",label:"Micro",cpu:2,memory:1,storage:{type:"EBS"},costFactor:1},{name:"t3.small",label:"Small",cpu:2,memory:2,storage:{type:"EBS"},costFactor:1}]}],icon:"hdd"},{type:"custom",label:"Custom Type",families:[],icon:"asterisk"}],a=t.filter((({type:e})=>!$t.get(gn,"instanceTypes.exclude.categories",[]).includes(e))).map((e=>Object.assign({},e,{families:e.families.filter((({type:e})=>!$t.get(gn,"instanceTypes.exclude.families",[]).includes(e)))})));const n=["xlarge","large","medium","small","micro","nano"];function r(e,t){const a=e.split("."),r=t.split("."),[i,s=""]=a,[l,o=""]=r;if(i!==l)return i>l?1:i<l?-1:0;const c=n.findIndex((e=>s.endsWith(e))),d=n.findIndex((e=>o.endsWith(e)));if(-1===c||-1===d)return 0;if(0===c&&0===d){const e=parseInt(s.replace("xlarge",""))||0,t=parseInt(o.replace("xlarge",""))||0;return t<e?1:t>e?-1:0}return c>d?-1:c<d?1:0}const i={paravirtual:["c1","c3","hi1","hs1","m1","m2","m3","t1"],hvm:["c3","c4","d2","i2","g2","m3","m4","m5","p2","r3","r4","r5","t2","x1"],vpcOnly:["c4","m4","m5","r4","r5","t2","x1"],ebsOptimized:["c4","d2","f1","g3","i3","m4","m5","p2","r4","r5","x1"],burstablePerf:["t2","t3","t3a","t4g"]};return{getCategories:function(){return e.when(a)},getAvailableTypesForRegions:function(e,t){let a=[];return(t=t||[])&&t.length&&(a=$t.map(e[t[0]],"name")),t.forEach((function(t){e[t]&&(a=$t.intersection(a,$t.map(e[t],"name")))})),a.sort(r)},getAllTypesByRegion:function(){return z("/instanceTypes").get().then((function(e){return $t.chain(e).map((function(e){return{region:e.region,account:e.account,name:e.name,key:[e.region,e.account,e.name].join(":")}})).uniqBy("key").groupBy("region").value()}))},filterInstanceTypes:function(e,t,a){return e.filter((e=>{if("*"===t)return!0;const[n]=e.split(".");return!(!a&&i.vpcOnly.includes(n))&&(!i.paravirtual.includes(n)&&"hvm"===t||i[t].includes(n))}))},isEbsOptimized:function(e){if(!e)return!1;const[t]=e.split(".");return i.ebsOptimized.includes(t)},isBurstingSupported:function(e){if(!e)return!1;const[t]=e.split(".");return i.burstablePerf.includes(t)},isInstanceTypeInCategory:function(e,a){if(!e||!a)return!1;if("custom"===a)return!0;const[n]=e.split("."),r=$t.find(t,{type:a}),i=r&&$t.find(r.families,{type:n});return i&&i.instanceTypes.map((e=>e.name)).includes(e)}}}]);const Zn=({account:e,availabilityZone:t,instanceType:a,capacityType:n,launchTime:r,provider:i,region:s,serverGroup:l,showInstanceType:o})=>Bt.createElement(Bt.Fragment,null,Bt.createElement(B,{label:"Launched",value:r?D(r):"Unknown"}),Bt.createElement(B,{label:"In",value:Bt.createElement("div",null,Bt.createElement(I,{account:e}),t||"Unknown")}),o&&Bt.createElement(B,{label:"Type",value:a||"Unknown"}),o&&n&&Bt.createElement(B,{label:"Capacity Type",value:n||"Unknown"}),l&&Bt.createElement(B,{label:"Server Group",value:Bt.createElement("div",null,Bt.createElement(Ha,null,Bt.createElement(ja,{to:"^.serverGroup",params:{region:s,accountId:e,serverGroup:l,provider:i}},Bt.createElement("a",null,l))))}));function _n(e){const{vpcId:t}=e,a=$((async()=>{const t=await xn.getVpcName(e.vpcId);return t?`${t} (${e.vpcId})`:`(${e.vpcId})`}),"None (EC2 Classic)",[t]),n=t?a.result:"None (EC2 Classic)";return Bt.createElement("span",{className:"vpc-tag"},n)}t("spinnaker.application.amazonInstanceInformation.component",[]).component("amazonInstanceInformation",Va(F((({instance:e})=>{const{imageId:t,serverGroup:a,subnetId:n,vpcId:r}=e;return Bt.createElement(A,{heading:"Instance Information",defaultExpanded:!0},Bt.createElement("dl",{className:"dl-horizontal dl-narrow"},Bt.createElement(Zn,{account:e.account,availabilityZone:e.availabilityZone,instanceType:e.instanceType,capacityType:e.capacityType,launchTime:e.launchTime,provider:e.provider,region:e.region,serverGroup:e.serverGroup,showInstanceType:!0}),a&&Bt.createElement(B,{label:"VPC",value:Bt.createElement(_n,{vpcId:r})}),n&&Bt.createElement(B,{label:"Subnet",value:Bt.createElement(M,{subnetId:n})}),t&&Bt.createElement(B,{label:"Image ID",value:t})))}),"amazonInstanceInformation"),["instance"]));class Kn extends L{static deregisterInstancesFromTargetGroup(e,t,a){const n=super.buildMultiInstanceJob(e,"deregisterInstancesFromLoadBalancer");n.forEach((e=>e.targetGroupNames=a));const r=super.buildMultiInstanceDescriptor(n,"Deregister",`from ${a.join(" and ")}`);return R.executeTask({job:n,application:t,description:r})}static deregisterInstanceFromTargetGroup(e,t,a={}){return a.type="deregisterInstancesFromLoadBalancer",a.instanceIds=[e.id],a.targetGroupNames=e.targetGroups,a.region=e.region,a.credentials=e.account,a.cloudProvider=e.cloudProvider,R.executeTask({job:[a],application:t,description:`Deregister instance: ${e.id}`})}static registerInstancesWithTargetGroup(e,t,a){const n=super.buildMultiInstanceJob(e,"registerInstancesWithLoadBalancer");n.forEach((e=>e.targetGroupNames=a));const r=super.buildMultiInstanceDescriptor(n,"Register",`with ${a.join(" and ")}`);return R.executeTask({job:n,application:t,description:r})}static registerInstanceWithTargetGroup(e,t,a={}){return a.type="registerInstancesWithLoadBalancer",a.instanceIds=[e.id],a.targetGroupNames=e.targetGroups,a.region=e.region,a.credentials=e.account,a.cloudProvider=e.cloudProvider,R.executeTask({job:[a],application:t,description:`Register instance: ${e.id}`})}}const Yn=e=>{const t=e.map((e=>e.targetGroups));return Ot(t)},Xn=(e,t,a)=>{e.forEach((e=>{"TargetGroup"===e.type&&e.targetGroups.forEach((e=>{var n,r,i;const s=null!=(n=t.find((t=>t.name===e.name&&t.account===a)))?n:{},l="traffic-port"===s.healthCheckPort||Ut(s.healthCheckPort)?s.port:s.healthCheckPort;e.healthCheckProtocol=null==(r=s.healthCheckProtocol)?void 0:r.toLowerCase(),e.healthCheckPath=`:${l}${null!=(i=s.healthCheckPath)?i:""}`}))}))};t("spinnaker.amazon.vpc.tag.directive",[]).directive("vpcTag",(function(){return{restrict:"E",scope:{vpcId:"="},template:'<span class="vpc-tag">{{vpcLabel}}</span>',link:function(e){e.$watch("vpcId",(function(){e.vpcId?xn.getVpcName(e.vpcId).then((function(t){e.vpcLabel="("+e.vpcId+")",t&&(e.vpcLabel=t+" "+e.vpcLabel)})):e.vpcLabel="None (EC2 Classic)"}),!0)}}}));t("spinnaker.amazon.instance.details.controller",[Wa,Za,"spinnaker.amazon.vpc.tag.directive"]).controller("awsInstanceDetailsCtrl",["$scope","$state","instance","app","moniker","environment","$q","overrides",function(e,t,n,r,i,s,l,o){function c(){const t={};let a,i,s,c,p,u,m;return r.serverGroups?(r.serverGroups.data.some((function(e){return e.instances.some((function(r){if(r.id===n.instanceId)return a=r,i=e.loadBalancers,s=e.targetGroups,c=e.account,p=e.region,u=e.vpcId,m=e.isDisabled,t.serverGroup=e.name,t.vpcId=e.vpcId,!0}))})),a||(r.loadBalancers.data.some((function(e){return e.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))||e.targetGroups.some((function(t){return t.instances.some((function(r){if(r.id===n.instanceId)return a=r,s=[t.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))})),a||r.loadBalancers.data.some((function(e){return e.serverGroups.some((function(t){return!!t.isDisabled&&t.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))||e.targetGroups.some((function(t){t.serverGroups.some((function(t){return!!t.isDisabled&&t.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))}))})))):(a={id:n.instanceId},i=[],s=[],c=n.account,p=n.region),a&&c&&p?(a.account=c,t.account=c,t.region=p,V.addExtraDataToLatest("instances",t),j.getInstanceDetails(c,p,n.instanceId).then((t=>{if(!e.$$destroyed){if(e.state.loading=!1,function(t,a){r.isStandalone&&(t.health=a.health),t.health=t.health||[];const n=t.health.filter((function(e){return"Amazon"!==e.type||"Unknown"!==e.state}));if(!r.isStandalone){const e=Yn(r.loadBalancers.data.filter((function(e){return"aws"===e.cloudProvider})));Xn(n,e,t.account)}a.health&&n.forEach((function(e){const t=a.health.filter((function(t){return t.type===e.type}));t.length&&$t.defaults(e,t[0])})),e.healthMetrics=n}(a,t),e.instance=$t.defaults(t,a),e.instance.account=c,e.instance.region=p,e.instance.vpcId=u,e.instance.serverGroupDisabled=m,e.instance.loadBalancers=i,e.instance.targetGroups=s,e.instance.networkInterfaces){e.instance.ipv6Addresses=$t.flatMap(e.instance.networkInterfaces,(t=>t.ipv6Addresses.map((t=>({ip:t.ipv6Address,url:`http://${t.ipv6Address}:${e.state.instancePort}`})))));const t=e.instance.networkInterfaces.filter((e=>!1===e.attachment.deleteOnTermination));t.length&&(e.instance.permanentIps=t.map((e=>e.privateIpAddress)))}e.baseIpAddress=t.publicDnsName||t.privateIpAddress,o.instanceDetailsLoaded&&o.instanceDetailsLoaded()}}),d)):(a||(e.instanceIdNotFound=n.instanceId,e.state.loading=!1),l.when(null))}function d(){e.$$destroyed||(r.isStandalone?(e.state.loading=!1,e.instanceIdNotFound=n.instanceId,e.state.notFoundStandalone=!0,V.removeLastItem("instances")):t.go("^",{allowModalToStayOpen:!0},{location:"replace"}))}e.detailsTemplateUrl=O.getValue("aws","instance.detailsTemplateUrl"),e.state={loading:!0,standalone:r.isStandalone,instancePort:$t.get(r,"attributes.instancePort")||a.defaultInstancePort||80},e.application=r,e.moniker=i,e.environment=s,e.securityGroupsLabel=U.get("Firewalls"),this.canDeregisterFromLoadBalancer=function(){return(e.instance.health||[]).some((function(e){return"LoadBalancer"===e.type}))},this.canRegisterWithLoadBalancer=function(){const t=e.instance,a=t.health||[];if(!t.loadBalancers||!t.loadBalancers.length)return!1;const n=a.some((function(e){return"LoadBalancer"===e.type&&"OutOfService"===e.state})),r=a.some((function(e){return"LoadBalancer"===e.type}));return n||!r},this.canDeregisterFromTargetGroup=function(){return(e.instance.health||[]).some((function(e){return"TargetGroup"===e.type&&"OutOfService"!==e.state}))},this.canRegisterWithTargetGroup=function(){const t=e.instance,a=t.health||[];if(!t.targetGroups||!t.targetGroups.length)return!1;const n=a.some((function(e){return"TargetGroup"===e.type&&"OutOfService"===e.state})),r=a.some((function(e){return"TargetGroup"===e.type}));return n||!r},this.canRegisterWithDiscovery=function(){const t=(e.instance.health||[]).filter((function(e){return"Discovery"===e.type}));return!!t.length&&"OutOfService"===t[0].state},this.terminateInstance=function(){const a=e.instance,n={application:r,title:"Terminating "+a.instanceId,onTaskComplete:function(){t.includes("**.instanceDetails",{instanceId:a.instanceId})&&t.go("^")}};k.confirm({header:"Really terminate "+a.instanceId+"?",buttonText:"Terminate "+a.instanceId,account:a.account,taskMonitorConfig:n,submitMethod:function(){return Kn.terminateInstance(a,r)}})},this.terminateInstanceAndShrinkServerGroup=function(){const a=e.instance,n={application:r,title:"Terminating "+a.instanceId+" and shrinking server group",onTaskComplete:function(){t.includes("**.instanceDetails",{instanceId:a.instanceId})&&t.go("^")}};k.confirm({header:"Really terminate "+a.instanceId+" and shrink "+a.serverGroup+"?",buttonText:"Terminate "+a.instanceId+" and shrink "+a.serverGroup,account:a.account,taskMonitorConfig:n,submitMethod:function(){return Kn.terminateInstanceAndShrinkServerGroup(a,r)}})},this.rebootInstance=function(){const t=e.instance,a={application:r,title:"Rebooting "+t.instanceId};k.confirm({header:"Really reboot "+t.instanceId+"?",buttonText:"Reboot "+t.instanceId,account:t.account,platformHealthOnlyShowOverride:r.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",taskMonitorConfig:a,submitMethod:(e={})=>(r.attributes&&r.attributes.platformHealthOnlyShowOverride&&r.attributes.platformHealthOnly&&(e.interestingHealthProviderNames=["Amazon"]),Kn.rebootInstance(t,r,e))})},this.registerInstanceWithLoadBalancer=function(){const t=e.instance,a=t.loadBalancers.join(" and "),n={application:r,title:"Registering "+t.instanceId+" with "+a};k.confirm({header:"Really register "+t.instanceId+" with "+a+"?",buttonText:"Register "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Kn.registerInstanceWithLoadBalancer(t,r)}})},this.deregisterInstanceFromLoadBalancer=function(){const t=e.instance,a=t.loadBalancers.join(" and "),n={application:r,title:"Deregistering "+t.instanceId+" from "+a};k.confirm({header:"Really deregister "+t.instanceId+" from "+a+"?",buttonText:"Deregister "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Kn.deregisterInstanceFromLoadBalancer(t,r)}})},this.registerInstanceWithTargetGroup=function(){const t=e.instance,a=t.targetGroups.join(" and "),n={application:r,title:"Registering "+t.instanceId+" with "+a};k.confirm({header:"Really register "+t.instanceId+" with "+a+"?",buttonText:"Register "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Kn.registerInstanceWithTargetGroup(t,r)}})},this.deregisterInstanceFromTargetGroup=function(){const t=e.instance,a=t.targetGroups.join(" and "),n={application:r,title:"Deregistering "+t.instanceId+" from "+a};k.confirm({header:"Really deregister "+t.instanceId+" from "+a+"?",buttonText:"Deregister "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Kn.deregisterInstanceFromTargetGroup(t,r)}})},this.enableInstanceInDiscovery=function(){const t=e.instance,a={application:r,title:"Enabling "+t.instanceId+" in discovery"};k.confirm({header:"Really enable "+t.instanceId+" in discovery?",buttonText:"Enable "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return Kn.enableInstanceInDiscovery(t,r)}})},this.disableInstanceInDiscovery=function(){const t=e.instance,a={application:r,title:"Disabling "+t.instanceId+" in discovery"};k.confirm({header:"Really disable "+t.instanceId+" in discovery?",buttonText:"Disable "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return Kn.disableInstanceInDiscovery(t,r)}})},this.hasHealthState=function(t,a){return(e.instance.health||[]).some((function(e){return e.type===t&&e.state===a}))};const p=e=>{const t=[{label:"Reboot",triggerAction:this.rebootInstance},{label:"Terminate",triggerAction:this.terminateInstance},{label:"Terminate and Shrink Server Group",triggerAction:this.terminateInstanceAndShrinkServerGroup}],a=[];return this.canRegisterWithDiscovery()&&!e.serverGroupDisabled&&a.push({label:"Enable In Discovery",triggerAction:this.enableInstanceInDiscovery}),(this.hasHealthState("Discovery","Up")||this.hasHealthState("Discovery","Down"))&&a.push({label:"Disable in Discovery",triggerAction:this.disableInstanceInDiscovery}),this.canRegisterWithLoadBalancer()&&a.push({label:"Register with Load Balancer",triggerAction:this.registerInstanceWithLoadBalancer}),this.canDeregisterFromLoadBalancer()&&a.push({label:"Deregister from Load Balancer",triggerAction:this.deregisterInstanceFromLoadBalancer}),this.canRegisterWithTargetGroup()&&a.push({label:"Register with Target Group",triggerAction:this.registerInstanceWithTargetGroup}),this.canDeregisterFromTargetGroup()&&a.push({label:"Deregister from Target Group",triggerAction:this.deregisterInstanceFromTargetGroup}),a.concat(t)};(r.isStandalone?c():l.all([r.serverGroups.ready(),r.loadBalancers.ready()]).then(c)).then((()=>{e.instanceActions=p(e.instance),e.$$destroyed||r.isStandalone||r.serverGroups.onRefresh(e,c)})),e.account=n.account}]);const Qn=({instancePort:e,ipv6Addresses:t,permanentIps:a,privateDnsName:n,privateIpAddress:r,publicDnsName:i,publicIpAddress:s})=>{const l=e?`:${e}`:"";return zt.createElement(q,{className:"horizontal-when-filters-collapsed"},n&&zt.createElement(B,{label:"Private DNS Name",value:zt.createElement(H,{text:n,url:`http://${n}${l}`})}),i&&zt.createElement(B,{label:"Public DNS Name",value:zt.createElement(H,{text:i,url:`http://${i}${l}`})}),r&&zt.createElement(B,{label:"Private IP Address",value:zt.createElement(H,{text:r,url:`http://${r}${l}`})}),Boolean(null==a?void 0:a.length)&&zt.createElement(B,{label:"Permanent IP Address",value:a.map((e=>zt.createElement(H,{key:e,text:e,url:`http://${e}${l}`})))}),s&&zt.createElement(B,{label:"Public IP Address",value:zt.createElement(H,{text:s,url:`http://${s}${l}`})}),Boolean(null==t?void 0:t.length)&&zt.createElement(B,{label:"IPv6 Address"+(t.length>1?"es":""),value:t.map((e=>zt.createElement(H,{key:e.ip,text:e.ip,url:e.url})))}))};t("spinnaker.application.instanceDns.component",[]).component("instanceDns",Va(F(Qn,"instanceDns"),["instancePort","ipv6Addresses","permanentIps","privateDnsName","privateIpAddress","publicDnsName","publicIpAddress"]));t("spinnaker.application.instanceSecurityGroups.component",[]).component("instanceSecurityGroups",Va(F((({instance:e})=>{const{account:t,region:a,provider:n,securityGroups:r,vpcId:i}=e,s=Vt(r,["groupName"],["asc"]),l=U.get("Firewalls");return Bt.createElement(A,{heading:l,defaultExpanded:!0},Bt.createElement(Ha,null,Bt.createElement("ul",null,(s||[]).map((e=>Bt.createElement("li",{key:e.groupId},Bt.createElement(ja,{to:"^.firewallDetails",params:{name:e.groupName,accountId:t,region:a,vpcId:i,provider:n}},Bt.createElement("a",null,e.groupName," (",e.groupId,")"))))))))}),"instanceSecurityGroups"),["instance"]));const Jn=({healthMetrics:e,healthState:t,metricTypes:a,customHealthUrl:n,privateIpAddress:r})=>{const i=a.includes("LoadBalancer"),s=a.includes("TargetGroup");return Bt.createElement(A,{heading:"Status",defaultExpanded:!0},!e.length&&Bt.createElement("p",null,"Starting"===t?"Starting":"No health metrics found for this instance"),Bt.createElement("dl",{className:"horizontal-when-filters-collapsed"},e.sort(((e,t)=>e.type<t.type?-1:e.type>t.type?1:0)).map((e=>Bt.createElement(Bt.Fragment,{key:`${e.type}-${e.description}`},Bt.createElement("dt",null,W(e.type)),Bt.createElement("dd",null,!a.includes(e.type)&&Bt.createElement("div",null,Bt.createElement(Z,{value:"down"===e.state.toLowerCase()?e.description:"",placement:"left"},Bt.createElement("span",null,Bt.createElement("span",{className:`glyphicon glyphicon-${e.state}-triangle`}),Bt.createElement("span",null,W(e.state)))),Bt.createElement("span",{className:"pad-left small"},e.healthCheckUrl&&Bt.createElement("a",{target:"_blank",href:e.healthCheckUrl},"Health Check"),e.healthCheckUrl&&e.statusPageUrl&&Bt.createElement("span",null," | "),e.statusPageUrl&&Bt.createElement("a",{target:"_blank",href:e.statusPageUrl},"Status"),n&&e.type===n.type&&Bt.createElement("span",null," ","|"," ",Bt.createElement("a",{target:"_blank",href:n.href},n.text)))),i&&"LoadBalancer"===e.type&&(e.loadBalancers||[]).map((e=>Bt.createElement(_,{key:`lb-${e.name}`,loadBalancer:e}))),s&&"TargetGroup"===e.type&&(e.targetGroups||[]).map((e=>Bt.createElement(_,{key:`tg-${e.name}`,loadBalancer:e,ipAddress:r})))))))))};t("spinnaker.application.instanceStatus.component",[]).component("instanceStatus",Va(F(Jn,"instanceStatus"),["healthMetrics","healthState","metricTypes","customHealthUrl","privateIpAddress"]));function er(e,t){void 0===t&&(t={});var a=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===a&&n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}t("spinnaker.application.instanceTags.component",[]).component("instanceTags",Va(F((({tags:e})=>{const t=Vt(e,["key"],["asc"]);return Bt.createElement(A,{heading:"Tags",defaultExpanded:!0},!e.length&&Bt.createElement("div",null,"No tags associated with this server"),e.length&&t.map((e=>Bt.createElement(B,{key:e.key,label:e.key,value:e.value}))))}),"instanceTags"),["tags"]));er(".target-group-title {\n color: var(--color-mineshaft);\n font-weight: 600;\n font-size: 14px;\n padding-right: 15px;\n text-transform: uppercase;\n padding-left: 10px;\n}\n.cluster-container .target-group-container {\n margin-top: 3px;\n}\n.cluster-container .target-group-container:not(:first-child) {\n padding-top: 5px;\n}\n.target-group-container .target-group-header {\n padding: 4px 0;\n}\n.target-group-container .server-group-title {\n padding-top: 0;\n}\n.target-group-container .server-group-title .clickable-row {\n margin-top: -1px;\n}\n.target-group-container .no-margin-y {\n margin-top: -1px !important;\n margin-bottom: 0 !important;\n}\n.target-group-container > div > .text-right {\n padding-right: 10px;\n font-weight: 600;\n}\n.listener-targets {\n display: inline-block;\n vertical-align: top;\n}\n");class tr extends Bt.Component{render(){const{targetGroup:e,showInstances:t,showServerGroups:a,loadBalancer:n}=this.props,r=Vt(e.serverGroups,["isDisabled","name"],["asc","desc"]).map((e=>Bt.createElement(K,{key:e.name,account:e.account,region:e.region,serverGroup:e,showInstances:t}))),i={loadBalancerName:n.name,region:e.region,accountId:e.account,name:e.name,vpcId:e.vpcId,provider:e.cloudProvider};return Bt.createElement("div",{className:"target-group-container container-fluid no-padding"},Bt.createElement(qa,{class:"active"},Bt.createElement(ja,{to:".targetGroupDetails",params:i},Bt.createElement("div",{className:"clickable clickable-row row no-margin-y target-group-header"},Bt.createElement("div",{className:"col-md-8 target-group-title"},e.name),Bt.createElement("div",{className:"col-md-4 text-right"},Bt.createElement(Y,{container:e.instanceCounts}))))),a&&r,!a&&t&&Bt.createElement(X,{serverGroups:e.serverGroups,instances:e.instances}))}}class ar extends Bt.Component{shouldComponentUpdate(e){return e.showInstances!==this.props.showInstances||e.showServerGroups!==this.props.showServerGroups||e.loadBalancer!==this.props.loadBalancer||(()=>!jt((e.serverGroups||[]).map((e=>e.name)),(this.props.serverGroups||[]).map((e=>e.name))))()||(()=>!jt((e.loadBalancer.targetGroups||[]).map((e=>e.name)),(this.props.loadBalancer.targetGroups||[]).map((e=>e.name))))()}render(){const{loadBalancer:e,showInstances:t,showServerGroups:a}=this.props;if("classic"!==e.loadBalancerType){const n=e.targetGroups.map((n=>Bt.createElement(tr,{key:n.name,loadBalancer:e,targetGroup:n,showInstances:t,showServerGroups:a})));return Bt.createElement("div",{className:"cluster-container"},n)}return Bt.createElement(Q,{...this.props})}}class nr{static buildTargetGroup(e,t){if(!e)return null;const a={name:e.name,vpcId:e.vpcId,cloudProvider:e.cloudProvider,account:e.account,region:e.region,loadBalancerNames:e.loadBalancerNames,instanceCounts:{up:0,down:0,succeeded:0,failed:0,outOfService:0,unknown:0,starting:0}};return t.instances.forEach((t=>{const n=t.health.find((e=>"TargetGroup"===e.type));if(n){const t=n.targetGroups.find((t=>t.name===e.name));if(void 0!==t&&void 0!==t.healthState){const e=t.healthState.toLowerCase();void 0!==a.instanceCounts[e]&&a.instanceCounts[e]++}}})),a}static populateTargetGroups(e,t){return Ua.all([o.getAccountDetails(t.account),e.getDataSource("loadBalancers").ready()]).then((a=>{const n=a[0]&&a[0].awsAccount||t.account,r=e.loadBalancers.data.filter((e=>"application"===e.loadBalancerType||"network"===e.loadBalancerType));return t.targetGroups.map((e=>{const a=Ot(r.map((e=>e.targetGroups||[]))).find((a=>a.name===e&&a.region===t.region&&a.account===n));return this.buildTargetGroup(a,t)})).filter((e=>e))}))}}class rr extends Bt.Component{constructor(){super(...arguments),this.onClick=e=>{this.props.onItemClick(this.props.loadBalancer),e.nativeEvent.preventDefault()}}render(){return Bt.createElement("a",{onClick:this.onClick},Bt.createElement("span",{className:"name"},this.props.loadBalancer.name),Bt.createElement(Y,{container:this.props.loadBalancer.instanceCounts}))}}class ir extends Bt.Component{constructor(){super(...arguments),this.onClick=e=>{this.props.onItemClick(this.props.loadBalancer),e.nativeEvent.preventDefault()}}render(){return Bt.createElement(Z,{value:`${this.props.label||"Load Balancer"}: ${this.props.loadBalancer.name}`},Bt.createElement("button",{className:"btn btn-link no-padding",onClick:this.onClick},Bt.createElement("span",{className:"badge badge-counter"},Bt.createElement("span",{className:"icon"},Bt.createElement("i",{className:"fa icon-sitemap"})))))}}class sr extends Bt.Component{constructor(e){super(e),this.mounted=!1,this.showLoadBalancerDetails=e=>{const{$state:t}=h,a=this.props.serverGroup;J.log({category:"Cluster Pod",action:"Load Load Balancer Details (multiple menu)"});const n=t.current.name.endsWith(".clusters")?".loadBalancerDetails":"^.loadBalancerDetails";t.go(n,{region:a.region,accountId:a.account,name:e.name,provider:a.type})},this.showTargetGroupDetails=e=>{const{$state:t}=h;J.log({category:"Cluster Pod",action:"Load Target Group Details (multiple menu)"});const a=t.current.name.endsWith(".clusters")?".targetGroupDetails":"^.targetGroupDetails";t.go(a,{region:e.region,accountId:e.account,name:e.name,provider:"aws",loadBalancerName:e.loadBalancerNames[0]})},this.handleShowPopover=()=>{J.log({category:"Cluster Pod",action:"Show Load Balancers Menu"})},this.handleClick=e=>{e.preventDefault(),e.stopPropagation()},this.state={loadBalancers:[],targetGroups:[],isLoading:!0}}componentDidMount(){this.mounted=!0,this.loadBalancersRefreshUnsubscribe=this.props.application.getDataSource("loadBalancers").onRefresh(null,(()=>{this.forceUpdate()})),ee.populateLoadBalancers(this.props.application,this.props.serverGroup).then((e=>{this.mounted&&this.setState({loadBalancers:e,isLoading:!1})})),nr.populateTargetGroups(this.props.application,this.props.serverGroup).then((e=>{this.mounted&&this.setState({targetGroups:e})}))}componentWillUnmount(){this.mounted=!1,this.loadBalancersRefreshUnsubscribe()}render(){const{loadBalancers:e,targetGroups:t,isLoading:a}=this.state,n=t&&t.length||0,r=e&&e.length||0,i=n+r;if(!i)return a?Bt.createElement(te,{size:"nano"}):null;const s="load-balancers-tag "+(i>1?"overflowing":""),l=Bt.createElement("div",{className:"menu-load-balancers"},r>0&&Bt.createElement("div",{className:"menu-load-balancers-header"},"Load Balancers"),qt(e,"name").map((e=>Bt.createElement(rr,{key:e.name,loadBalancer:e,onItemClick:this.showLoadBalancerDetails}))),n>0&&Bt.createElement("div",{className:"menu-load-balancers-header"},"Target Groups"),qt(t,"name").map((e=>Bt.createElement(rr,{key:e.name,loadBalancer:e,onItemClick:this.showTargetGroupDetails}))));return Bt.createElement("span",{className:s},i>1&&Bt.createElement(ae,{delayShow:100,delayHide:150,onShow:this.handleShowPopover,placement:"bottom",template:l,hOffsetPercent:"80%",container:this.props.container,className:"no-padding menu-load-balancers"},Bt.createElement("button",{onClick:this.handleClick,className:"btn btn-link btn-multiple-load-balancers clearfix no-padding"},Bt.createElement("span",{className:"badge badge-counter"},Bt.createElement("span",{className:"icon"},Bt.createElement("i",{className:"fa icon-sitemap"}))," ",i))),1===e.length&&0===t.length&&Bt.createElement("span",{className:"btn-load-balancer"},Bt.createElement(ir,{key:e[0].name,label:"Load Balancer",loadBalancer:e[0],onItemClick:this.showLoadBalancerDetails})),1===t.length&&0===e.length&&Bt.createElement("span",{className:"btn-load-balancer"},Bt.createElement(ir,{key:t[0].name,label:"Target Group",loadBalancer:t[0],onItemClick:this.showTargetGroupDetails})))}}const lr=Bt.forwardRef(((e,t)=>Bt.createElement("div",{ref:t},Bt.createElement(s,{name:"idleTimeout",label:"Idle Timeout",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.idleTimeout"}),input:e=>Bt.createElement(u,{...e,min:0})}),Bt.createElement(s,{name:"deletionProtection",label:"Protection",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.deletionProtection"}),input:e=>Bt.createElement(d,{...e,text:"Enable delete protection"})}),Bt.createElement(s,{name:"dualstack",label:"Dualstack",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.albIpAddressType"}),input:e=>Bt.createElement(d,{...e,text:"Assign Ipv4 and IPv6"})}))));er(".configure-config-modal .StandardFieldLayout .sm-label-right {\n min-width: 160px;\n}\n");const or=class extends Bt.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal(e)},this.submit=e=>{this.props.closeModal(e)},this.validate=()=>({});const t=e.config||{};this.state={initialValues:{authorizationEndpoint:t.authorizationEndpoint||"",clientId:t.clientId||"",clientSecret:t.clientSecret||"",issuer:t.issuer||"",scope:t.scope||"openid",sessionCookieName:t.sessionCookieName||"AWSELBAuthSessionCookie",tokenEndpoint:t.tokenEndpoint||"",userInfoEndpoint:t.userInfoEndpoint||""}}}static show(e){return b.show(or,e)}render(){const{initialValues:e}=this.state;return Bt.createElement("div",{className:"configure-config-modal"},Bt.createElement(ne,{initialValues:e,onSubmit:this.submit,validate:this.validate,render:({isValid:e})=>Bt.createElement(Qa,{className:"form-horizontal"},Bt.createElement(re,{dismiss:this.close}),Bt.createElement(Da.Header,null,Bt.createElement(Da.Title,null,"Configure OIDC Client")),Bt.createElement(Da.Body,null,Bt.createElement(s,{name:"issuer",label:"Issuer",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter the OpenId Provider"})}),Bt.createElement(s,{name:"authorizationEndpoint",label:"Authorization Endpoint",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter OpenID provider server endpoint"})}),Bt.createElement(s,{name:"tokenEndpoint",label:"Token Endpoint",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter a URI for your token endpoint"})}),Bt.createElement(s,{name:"userInfoEndpoint",label:"User info Endpoint",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter a URI for your user info endpoint"})}),Bt.createElement(s,{name:"clientId",label:"Client ID",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter the client ID"})}),Bt.createElement(s,{name:"clientSecret",label:"Client secret",required:!0,input:e=>Bt.createElement(l,{...e,placeholder:"Enter the client secret"})})),Bt.createElement(Da.Footer,null,Bt.createElement("button",{className:"btn btn-default",onClick:this.close,type:"button"},"Cancel"),Bt.createElement(ie,{isDisabled:!e,submitting:!1,isFormSubmit:!0,label:"Save Client"})))}))}};let cr=or;cr.defaultProps={closeModal:C,dismissModal:C};const dr=class extends Bt.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal(e)},this.submit=e=>{const t=Ht(e,(e=>e&&""!==e));this.props.closeModal(t)};const t=e.config||{};this.initialValues={host:t.host||"",path:t.path||"",port:t.port||"",protocol:t.protocol||void 0,query:t.query||"",statusCode:t.statusCode||"HTTP_301"}}static show(e){return b.show(dr,e)}render(){return Bt.createElement("div",{className:"configure-config-modal"},Bt.createElement(ne,{initialValues:this.initialValues,onSubmit:this.submit,render:({isValid:e})=>Bt.createElement(Qa,{className:"form-horizontal"},Bt.createElement(re,{dismiss:this.close}),Bt.createElement(Da.Header,null,Bt.createElement(Da.Title,null,"Configure Redirect ",Bt.createElement(n,{id:"aws.loadBalancer.redirect"}))),Bt.createElement(Da.Body,null,Bt.createElement(s,{name:"host",label:"Host",required:!1,input:e=>Bt.createElement(l,{...e}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.host"})}),Bt.createElement(s,{name:"path",label:"Path",required:!1,input:e=>Bt.createElement(l,{...e}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.path"})}),Bt.createElement(s,{name:"port",label:"Port",required:!1,input:e=>Bt.createElement(l,{...e}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.port"})}),Bt.createElement(s,{name:"protocol",label:"Protocol",required:!1,input:e=>Bt.createElement(c,{...e,stringOptions:["HTTP","HTTPS","#{protocol}"],placeholder:"Select Protocol",clearable:!1,style:{width:"130px"}}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.protocol"})}),Bt.createElement(s,{name:"query",label:"Query",required:!1,input:e=>Bt.createElement(l,{...e}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.query"})}),Bt.createElement(s,{name:"statusCode",label:"Status Code",required:!0,input:e=>Bt.createElement(se,{...e,options:["HTTP_301","HTTP_302"]}),help:Bt.createElement(n,{id:"aws.loadBalancer.redirect.statusCode"})})),Bt.createElement(Da.Footer,null,Bt.createElement("button",{className:"btn btn-default",onClick:this.close,type:"button"},"Cancel"),Bt.createElement(ie,{isDisabled:!e,submitting:!1,isFormSubmit:!0,label:"Save Config"})))}))}};let pr=dr;pr.defaultProps={closeModal:C,dismissModal:C};class ur{static listCertificates(){return le.listCertificatesByProvider("aws").then((e=>o.listAllAccounts("aws").then((t=>{const a=t.reduce(((e,t)=>(e[t.accountId]=t.name,e)),{}),n=qt(e,"serverCertificateName");return Wt(n,(e=>{const[,,,,t]=e.arn.split(":");return a[t]||"unknown"}))}))))}}var mr=Object.defineProperty,gr=Object.getOwnPropertyDescriptor;let hr=class extends Bt.Component{render(){const{certificates:e,accountName:t,onCertificateSelect:a,currentValue:n}=this.props,r=e[t]||[],i=r.map((e=>({label:e.serverCertificateName,value:e.serverCertificateName}))),s=r.find((e=>e.serverCertificateName===n));return Bt.createElement("div",{style:{width:"100%"}},Bt.createElement(en,{className:"input-sm",wrapperStyle:{width:"100%"},clearable:!0,required:!0,options:i,onChange:e=>a(e.value),value:n}),s&&Bt.createElement("div",{className:"small sp-margin-xs-top sp-margin-m-bottom sp-margin-m-left"},Bt.createElement("div",null,"Uploaded ",oe(s.uploadDate)," (",D(s.uploadDate),")"),Bt.createElement("b",null,"Expires ",oe(s.expiration))," (",D(s.expiration),")"))}};hr=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?gr(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&mr(t,a,i),i})([ce("amazon.certificateSelectField")],hr);const fr=_a((()=>Bt.createElement("span",{className:"pipeline-drag-handle clickable glyphicon glyphicon-resize-vertical"}))),vr={authenticateOidcConfig:{authorizationEndpoint:"",clientId:"",issuer:"",scope:"openid",sessionCookieName:"AWSELBAuthSessionCookie",tokenEndpoint:"",userInfoEndpoint:""},type:"authenticate-oidc"};class yr extends Bt.Component{constructor(e){super(e),this.protocols=["HTTP","HTTPS"],this.initialActionsWithAuth=new Set,this.initialListenersWithDefaultAuth=new Set,this.removedAuthActions=new Map,this.attachClientSecret=(e,t)=>{if("authenticate-oidc"===e.type){const a=t.find((t=>t.clientId===e.authenticateOidcConfig.clientId));a&&(e.authenticateOidcConfig.clientSecret=a.clientSecret)}},this.addListener=()=>{this.props.formik.values.listeners.push({certificates:[],protocol:"HTTP",port:80,defaultActions:[{type:"forward",targetGroupName:""}],rules:[]}),this.updateListeners()},this.addRule=e=>{e.rules.push({priority:null,actions:[{type:"forward",targetGroupName:""}],conditions:[{field:"path-pattern",values:[""]}]}),this.updateListeners()},this.removeRule=(e,t)=>{e.rules.splice(t,1),this.updateListeners()},this.handleConditionFieldChanged=(e,t)=>{e.field=t,"http-request-method"===t&&(e.values=[]),this.updateListeners()},this.handleConditionValueChanged=(e,t)=>{e.values[0]=t,this.updateListeners()},this.handleHttpRequestMethodChanged=(e,t,a)=>{let n=e.values||[];a?n.push(t):n=n.filter((e=>e!==t)),e.values=n,e.httpRequestMethodConfig={values:n},this.updateListeners()},this.addCondition=e=>{if(1===e.conditions.length){const t="path-pattern"===e.conditions[0].field?"host-header":"path-pattern";e.conditions.push({field:t,values:[""]})}this.updateListeners()},this.removeCondition=(e,t)=>{e.conditions.splice(t,1),this.updateListeners()},this.handleRuleActionTargetChanged=(e,t)=>{e.targetGroupName=t,this.updateListeners()},this.handleRuleActionTypeChanged=(e,t)=>{e.type=t,"forward"===e.type?delete e.redirectActionConfig:"redirect"===e.type&&(e.redirectActionConfig={statusCode:"HTTP_301"},delete e.targetGroupName),this.updateListeners()},this.handleSortEnd=(e,t)=>{t.rules=Ka(t.rules,e.oldIndex,e.newIndex),this.updateListeners()},this.configureOidcClient=e=>{cr.show({config:e.authenticateOidcConfig}).then((t=>{e.authenticateOidcConfig=t,this.updateListeners()})).catch((()=>{}))},this.configureRedirect=e=>{pr.show({config:e.redirectActionConfig}).then((t=>{e.redirectActionConfig=t,this.updateListeners()})).catch((()=>{}))},this.authenticateRuleToggle=(e,t)=>{const a=e.rules[t],n=a&&a.actions||e.defaultActions;if(n){const a=n.findIndex((e=>"authenticate-oidc"===e.type));if(-1!==a)this.removeAuthAction(e,n,a,t);else{const a=(this.removedAuthActions.has(e)?this.removedAuthActions.get(e)[t||-1]:void 0)||{...vr};n.unshift({...a})}this.updateListeners()}},this.oidcConfigChanged=(e,t)=>{e.authenticateOidcConfig={...t},this.updateListeners()},this.redirectConfigChanged=(e,t)=>{e.redirectActionConfig={...t},this.updateListeners()},this.state={certificates:[],certificateTypes:Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),oidcConfigs:void 0},this.props.formik.initialValues.listeners.forEach((e=>{"authenticate-oidc"===e.defaultActions[0].type&&this.initialListenersWithDefaultAuth.add(e),e.rules.forEach((e=>{"authenticate-oidc"===e.actions[0].type&&this.initialActionsWithAuth.add(e.actions)}))}))}getAllTargetGroupsFromListeners(e){const t=Ot(e.map((e=>e.defaultActions))),a=Ot(e.map((e=>e.rules)));return t.push(...Ot(a.map((e=>e.actions)))),_t(t.map((e=>e.targetGroupName)))}validate(e){const t={},a=e.targetGroups.map((e=>e.name)),n=this.getAllTargetGroupsFromListeners(e.listeners),r=Kt(a,n);1===r.length?t.listeners=`Target group ${r[0]} is unused.`:r.length>1&&(t.listeners=`Target groups ${r.join(", ")} are unused.`);const{listeners:i}=e;Lt(i,"port").length<i.length&&(t.listenerPorts="Multiple listeners cannot use the same port.");return e.listeners.find((e=>{const t=!!e.defaultActions.find((e=>"forward"===e.type&&!e.targetGroupName||"authenticate-oidc"===e.type&&!e.authenticateOidcConfig.clientId||"redirect"===e.type&&(!e.redirectActionConfig||!Yt(e.redirectActionConfig,(e=>e&&""!==e))))),a=!!e.rules.find((e=>{const t=!!e.actions.find((e=>"forward"===e.type&&!e.targetGroupName)),a=!!e.actions.find((e=>"authenticate-oidc"===e.type&&!e.authenticateOidcConfig.clientId)),n=!!e.conditions.find((e=>"http-request-method"===e.field?!e.values.length:e.values.includes("")));return t||a||n}));return t||a}))&&(t.listeners="Missing fields in rule configuration."),t}componentDidMount(){this.loadCertificates(),this.loadOidcClients()}loadCertificates(){ur.listCertificates().then((e=>{this.setState({certificates:e})}))}loadOidcClients(){(class{static getOidcConfigsByApp(e){return z("/oidcConfigs").query({app:e}).get()}}).getOidcConfigsByApp(this.props.app.name).then((e=>{e&&e.length&&this.props.formik.values.listeners.forEach((t=>{t.defaultActions.forEach((t=>this.attachClientSecret(t,e))),t.rules.forEach((t=>t.actions.forEach((t=>this.attachClientSecret(t,e)))))})),this.setState({oidcConfigs:e}),this.updateListeners()})).catch((()=>{}))}updateListeners(){this.props.formik.setFieldValue("listeners",this.props.formik.values.listeners)}needsCert(e){return"HTTPS"===e.protocol}showCertificateSelect(e){return"iam"===e.type&&this.state.certificates&&Object.keys(this.state.certificates).length>0}addListenerCertificate(e){e.certificates=e.certificates||[],e.certificates.push({certificateArn:void 0,type:"iam",name:void 0})}removeAuthActions(e){const t=e.defaultActions.findIndex((e=>"authenticate-oidc"===e.type));-1!==t&&this.removeAuthAction(e,e.defaultActions,t,-1),e.rules.forEach(((t,a)=>{const n=t.actions.findIndex((e=>"authenticate-oidc"===e.type));-1!==n&&this.removeAuthAction(e,t.actions,n,a)})),this.updateListeners()}reenableAuthActions(e){const t=this.removedAuthActions.has(e)?this.removedAuthActions.get(e):[],a=t[-1];a&&(t[-1]=void 0,e.defaultActions.unshift({...a})),e.rules.forEach(((e,a)=>{const n=t[a];t[a]=void 0,n&&e.actions.unshift({...n})}))}listenerProtocolChanged(e,t){e.protocol=t,"HTTPS"===e.protocol&&(e.port=443,e.certificates&&0!==e.certificates.length||this.addListenerCertificate(e),this.reenableAuthActions(e)),"HTTP"===e.protocol&&(e.port=80,e.certificates.length=0,this.removeAuthActions(e)),this.updateListeners()}listenerPortChanged(e,t){e.port=Number.parseInt(t,10),this.updateListeners()}certificateTypeChanged(e,t){e.type=t,this.updateListeners()}handleCertificateChanged(e,t){e.name=t,this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}removeAuthActionInternal(e,t,a,n=-1){const r=t.splice(a,1)[0];this.removedAuthActions.has(e)||this.removedAuthActions.set(e,[]),this.removedAuthActions.get(e)[n||-1]=r,this.updateListeners()}removeAuthAction(e,t,a,n=-1){const r=-1===n&&this.initialListenersWithDefaultAuth.has(e),i=n>-1&&this.initialActionsWithAuth.has(t);r||i?k.confirm({header:"Really remove authentication?",buttonText:"Remove Auth",submitMethod:()=>(this.removeAuthActionInternal(e,t,a,n),r&&this.initialListenersWithDefaultAuth.delete(e),i&&this.initialActionsWithAuth.delete(t),Ua.resolve())}):this.removeAuthActionInternal(e,t,a,n)}render(){const{errors:e,values:t}=this.props.formik,{certificates:a,certificateTypes:n,oidcConfigs:r}=this.state;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},t.listeners.map(((e,i)=>Bt.createElement("div",{key:i,className:"wizard-pod"},Bt.createElement("div",null,Bt.createElement("div",{className:"wizard-pod-row header"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Listen On"),Bt.createElement("div",{className:"wizard-pod-row-contents spread"},Bt.createElement("div",null,Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol"),Bt.createElement("select",{className:"form-control input-sm inline-number",style:{width:"80px"},value:e.protocol,onChange:t=>this.listenerProtocolChanged(e,t.target.value)},this.protocols.map((e=>Bt.createElement("option",{key:e},e))))),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port"),Bt.createElement("input",{className:"form-control input-sm inline-number",type:"text",min:0,value:e.port||"",onChange:t=>this.listenerPortChanged(e,t.target.value),style:{width:"80px"},required:!0}))),Bt.createElement("div",null,Bt.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(i)},Bt.createElement("span",{className:"glyphicon glyphicon-trash"}))))),this.needsCert(e)&&Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Certificate"),Bt.createElement("div",{className:"wizard-pod-row-contents"},e.certificates.map(((e,r)=>Bt.createElement("div",{key:r,style:{width:"100%",display:"flex",flexDirection:"row"}},Bt.createElement("select",{className:"form-control input-sm inline-number",style:{width:"45px"},value:e.type,onChange:t=>this.certificateTypeChanged(e,t.target.value)},n.map((e=>Bt.createElement("option",{key:e},e)))),this.showCertificateSelect(e)&&Bt.createElement(hr,{certificates:a,accountName:t.credentials,currentValue:e.name,app:this.props.app,onCertificateSelect:t=>this.handleCertificateChanged(e,t)}),!this.showCertificateSelect(e)&&Bt.createElement("input",{className:"form-control input-sm no-spel",style:{display:"inline-block"},type:"text",value:e.name,onChange:t=>this.handleCertificateChanged(e,t.target.value),required:!0})))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-contents",style:{padding:"0"}},Bt.createElement("table",{className:"table table-condensed packed rules-table"},Bt.createElement("thead",null,Bt.createElement("tr",null,Bt.createElement("th",{style:{width:"15px",padding:"0"}}),Bt.createElement("th",null,"If"),Bt.createElement("th",{style:{width:"315px"}},"Then"),Bt.createElement("th",{style:{width:"45px"}}))),Bt.createElement(Cr,{addCondition:this.addCondition,addRule:this.addRule,authenticateRuleToggle:this.authenticateRuleToggle,distance:10,handleConditionFieldChanged:this.handleConditionFieldChanged,handleConditionValueChanged:this.handleConditionValueChanged,handleHttpRequestMethodChanged:this.handleHttpRequestMethodChanged,handleRuleActionTargetChanged:this.handleRuleActionTargetChanged,handleRuleActionTypeChanged:this.handleRuleActionTypeChanged,listener:e,helperClass:"rule-sortable-helper",removeRule:this.removeRule,removeCondition:this.removeCondition,targetGroups:t.targetGroups,oidcConfigs:r,oidcConfigChanged:this.oidcConfigChanged,redirectConfigChanged:this.redirectConfigChanged,onSortEnd:t=>this.handleSortEnd(t,e),configureOidcClient:this.configureOidcClient,configureRedirect:this.configureRedirect})))))))),e.listenerPorts&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:e.listenerPorts})),e.listeners&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:e.listeners})),Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("tbody",null,Bt.createElement("tr",null,Bt.createElement("td",null,Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addListener},Bt.createElement("span",null,Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new listener")))))))))}}const br=Ya((e=>Bt.createElement("tr",{className:"listener-rule"},Bt.createElement("td",{className:"handle"},Bt.createElement(fr,null)),Bt.createElement("td",null,e.rule.conditions.map(((t,a)=>Bt.createElement("div",{key:a,className:"listener-rule-condition"},Bt.createElement("select",{className:"form-control input-sm inline-number",value:t.field,onChange:a=>e.handleConditionFieldChanged(t,a.target.value),style:{width:"40%"},required:!0},(1===e.rule.conditions.length||"host-header"===t.field)&&Bt.createElement("option",{value:"host-header"},"Host"),(1===e.rule.conditions.length||"path-pattern"===t.field)&&Bt.createElement("option",{value:"path-pattern"},"Path"),(1===e.rule.conditions.length||"http-request-method"===t.field)&&Bt.createElement("option",{value:"http-request-method"},"Method(s)")),"path-pattern"===t.field&&Bt.createElement(n,{id:"aws.loadBalancer.ruleCondition.path"}),"host-header"===t.field&&Bt.createElement(n,{id:"aws.loadBalancer.ruleCondition.host"}),"http-request-method"!==t.field&&Bt.createElement("input",{className:"form-control input-sm",type:"text",value:t.values[0],onChange:a=>e.handleConditionValueChanged(t,a.target.value),maxLength:128,required:!0,style:{width:"63%"}}),"http-request-method"===t.field&&Bt.createElement("div",{className:"col-md-6 checkbox"},["DELETE","GET","PATCH","POST","PUT"].map((a=>Bt.createElement("label",{key:`${a}-checkbox`},Bt.createElement("input",{type:"checkbox",checked:t.values.includes(a),onChange:n=>e.handleHttpRequestMethodChanged(t,a,n.target.checked)}),a)))),Bt.createElement("span",{className:"remove-condition"},1===a&&Bt.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.removeCondition(e.rule,a),style:{padding:"0"}},Bt.createElement(Z,{value:"Remove Condition"},Bt.createElement("span",{className:"glyphicon glyphicon-trash"}))))))),1===e.rule.conditions.length&&Bt.createElement("div",{className:"add-new-container"},Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:()=>e.addCondition(e.rule)},Bt.createElement("span",null,Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new condition")),Bt.createElement("span",{style:{minWidth:"15px"}}))),Bt.createElement("td",null,e.rule.actions.map(((t,a)=>Bt.createElement(wr,{key:a,action:t,actionTypeChanged:a=>e.handleRuleActionTypeChanged(t,a),oidcConfigChanged:a=>e.oidcConfigChanged(t,a),redirectConfigChanged:a=>e.redirectConfigChanged(t,a),targetChanged:a=>e.handleRuleActionTargetChanged(t,a),targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect})))),Bt.createElement("td",null,Bt.createElement(Er,{ruleIndex:e.ruleIndex,listener:e.listener,authenticateRuleToggle:e.authenticateRuleToggle,removeRule:e.removeRule,actions:e.rule.actions}))))),wr=e=>{var t;if("authenticate-oidc"!==e.action.type){const t=e.action.redirectActionConfig||e.action.redirectConfig;return Bt.createElement("div",{className:"horizontal top"},Bt.createElement("select",{className:"form-control input-sm",style:{width:"80px"},value:e.action.type,onChange:t=>e.actionTypeChanged(t.target.value)},Bt.createElement("option",{value:"forward"},"forward to"),Bt.createElement("option",{value:"redirect"},"redirect to")),"forward"===e.action.type&&Bt.createElement("select",{className:"form-control input-sm",value:e.action.targetGroupName,onChange:t=>e.targetChanged(t.target.value),required:!0},Bt.createElement("option",{value:""}),_t(e.targetGroups.map((e=>e.name))).map((e=>Bt.createElement("option",{key:e},e)))),"redirect"===e.action.type&&Bt.createElement("dl",{className:"dl-horizontal dl-narrow"},Bt.createElement("dt",null,"Host"),Bt.createElement("dd",null,t.host),Bt.createElement("dt",null,"Path"),Bt.createElement("dd",null,t.path),Bt.createElement("dt",null,"Port"),Bt.createElement("dd",null,t.port),Bt.createElement("dt",null,"Protocol"),Bt.createElement("dd",null,t.protocol),Bt.createElement("dt",null,"Query"),Bt.createElement("dd",null,t.query),Bt.createElement("dt",null,"Status Code"),Bt.createElement("dd",null,t.statusCode),Bt.createElement("dt",null,Bt.createElement("button",{className:"btn btn-link no-padding",type:"button",onClick:()=>e.configureRedirect(e.action)},"Configure..."))))}if("authenticate-oidc"===e.action.type){const a=e.action.authenticateOidcConfig.clientId,n=Zt(gn,"loadBalancers.disableManualOidcDialog",!1)||e.oidcConfigs&&e.oidcConfigs.length>0&&(!a||e.oidcConfigs.find((e=>e.clientId===a))),r=(null==(t=e.oidcConfigs)?void 0:t.length)?e.oidcConfigs.map((e=>Bt.createElement("option",{key:e.clientId},e.clientId))):Bt.createElement("option",{disabled:!0},"No ",pe.get("OIDC client")," config found");return Bt.createElement("div",{className:"horizontal middle",style:{height:"30px"}},Bt.createElement("span",{style:{whiteSpace:"pre"}},"auth with ",pe.get("OIDC client")," "),n&&Bt.createElement("select",{className:"form-control input-sm",value:a,onChange:t=>e.oidcConfigChanged(e.oidcConfigs.find((e=>e.clientId===t.target.value))),required:!0},Bt.createElement("option",{value:""}),r),!n&&Bt.createElement("a",{onClick:()=>e.configureOidcClient(e.action),className:"clickable"},a||"Configure..."),Bt.createElement("span",{style:{whiteSpace:"pre"}},Bt.createElement("em",null," and then")))}return null},Er=e=>{const t=Boolean(e.actions.find((e=>"authenticate-oidc"===e.type))),a="HTTPS"===e.listener.protocol,r=t?"Remove authentication from rule":"Authenticate rule",i=t?"fas fa-fw fa-lock-open":"fas fa-fw fa-user-lock";return Bt.createElement("span",null,a&&Bt.createElement(Bt.Fragment,null,Bt.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.authenticateRuleToggle(e.listener,e.ruleIndex),style:{padding:"0"}},Bt.createElement(Z,{value:r},Bt.createElement("i",{className:i}))),Bt.createElement(n,{id:"aws.loadBalancer.oidcAuthentication"})),void 0!==e.ruleIndex&&e.ruleIndex>=0&&e.removeRule&&Bt.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.removeRule(e.listener,e.ruleIndex),style:{padding:"0"}},Bt.createElement(Z,{value:"Remove Rule"},Bt.createElement("i",{className:"far fa-fw fa-trash-alt"}))))},Cr=Xa((e=>Bt.createElement("tbody",null,Bt.createElement("tr",{className:"not-sortable"},Bt.createElement("td",null),Bt.createElement("td",null,"Default"),Bt.createElement("td",null,e.listener.defaultActions.map(((t,a)=>Bt.createElement(wr,{key:a,action:t,actionTypeChanged:a=>e.handleRuleActionTypeChanged(t,a),targetChanged:a=>e.handleRuleActionTargetChanged(t,a),targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,oidcConfigChanged:a=>e.oidcConfigChanged(t,a),redirectConfigChanged:a=>e.redirectConfigChanged(t,a),configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect})))),Bt.createElement("td",null,Bt.createElement(Er,{listener:e.listener,actions:e.listener.defaultActions,authenticateRuleToggle:e.authenticateRuleToggle}))),e.listener.rules.sort(((e,t)=>e.priority-t.priority)).map(((t,a)=>Bt.createElement(br,{key:a,rule:t,addCondition:e.addCondition,handleConditionFieldChanged:e.handleConditionFieldChanged,handleConditionValueChanged:e.handleConditionValueChanged,handleHttpRequestMethodChanged:e.handleHttpRequestMethodChanged,handleRuleActionTargetChanged:e.handleRuleActionTargetChanged,handleRuleActionTypeChanged:e.handleRuleActionTypeChanged,oidcConfigChanged:e.oidcConfigChanged,redirectConfigChanged:e.redirectConfigChanged,removeCondition:e.removeCondition,authenticateRuleToggle:e.authenticateRuleToggle,removeRule:e.removeRule,targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,listener:e.listener,index:a,ruleIndex:a,configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect}))),Bt.createElement("tr",{className:"not-sortable"},Bt.createElement("td",{colSpan:5},Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:()=>e.addRule(e.listener)},Bt.createElement("span",null,Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new rule"))))))),kr=(e,t,a)=>n=>Zt(e,[t,a],[]).includes(n.toLowerCase())?`There is already a target group in ${t}:${a} with that name.`:null,Sr=e=>t=>t.length<32-e?null:"Target group names are automatically prefixed with their application name and cannot exceed 32 characters in length.";class Gr extends Bt.Component{constructor(e){super(e),this.protocols=["HTTP","HTTPS"],this.targetTypes=["instance","ip","lambda"],this.destroy$=new fa,this.addTargetGroup=()=>{const{setFieldValue:e,values:t}=this.props.formik,a=t.targetGroups.length;t.targetGroups.push({name:"targetgroup"+(a?`${a}`:""),protocol:"HTTP",port:7001,targetType:"instance",healthCheckProtocol:"HTTP",healthCheckPort:"7001",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:2,attributes:{deregistrationDelay:300,stickinessEnabled:!1,stickinessType:"lb_cookie",stickinessDuration:8400}}),e("targetGroups",t.targetGroups)};const t=e.isNew?0:e.formik.initialValues.targetGroups.length;this.state={existingTargetGroupNames:{},oldTargetGroupCount:t}}validate(e){const t=_t(Ot(Qt(Wt(e.targetGroups,"name"),(e=>e.length>1))).map((e=>e.name))),a=new i(e),{arrayForEach:n}=a;return a.field("targetGroups").withValidators(n(((a,n)=>{var r;a.field("name","Name").withValidators(kr(this.state.existingTargetGroupNames,e.credentials,e.region),Sr(this.props.app.name.length),ue.valueUnique(t,"There is already a target group in this load balancer with the same name.")),a.field("healthCheckInterval","Health Check Interval").withValidators((r=n,e=>"TCP"!==r.healthCheckProtocol||"TCP"===r.healthCheckProtocol&&(10===Number.parseInt(e,10)||30===Number.parseInt(e,10))?null:"TCP health checks only support 10s and 30s intervals"),ue.checkBetween("healthCheckInterval",5,300)),a.field("healthyThreshold","Healthy Threshold").withValidators(ue.checkBetween("healthyThreshold",2,10)),a.field("unhealthyThreshold","Unhealthy Threshold").spelAware().withValidators(ue.checkBetween("unhealthyThreshold",2,10)),a.field("healthCheckTimeout","Timeout").withValidators((e=>t=>{const a=Xt(t)?t:Number.parseInt(t,10),{protocol:n,healthCheckProtocol:r}=e;if("TCP"===n||"TLS"===n){if("HTTP"===r&&6!==a)return"HTTP health check timeouts for TCP/TLS target groups must be 6s";if(("HTTPS"===r||"TLS"===r)&&10!==a)return"HTTPS/TLS health check timeouts for TCP/TLS target groups must be 10s"}return null})(n),ue.checkBetween("healthCheckTimeout",2,120)),"lambda"!==n.targetType&&(a.field("protocol","Protocol").required(),a.field("healthCheckPath","Health Check Path").required(),a.field("healthCheckProtocol","Health Check Protocol").required(),a.field("name","Name").required(),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckInterval","Health Check Interval").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckPort","Health Check Port").required().spelAware().withValidators((e=>"traffic-port"===e?null:me(e))),a.field("port","Port").required().spelAware().withValidators((e=>me(e))),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e)),ue.checkBetween("healthyThreshold",2,10)),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e)),ue.checkBetween("unhealthyThreshold",2,10)))}))),a.validateForm()}removeAppName(e){return e.replace(`${this.props.app.name}-`,"")}updateLoadBalancerNames(e){const{app:t,loadBalancer:a}=e,n={};va(t.getDataSource("loadBalancers").refresh(!0)).pipe(Ta(this.destroy$)).subscribe((()=>{t.getDataSource("loadBalancers").data.forEach((e=>{"classic"!==e.loadBalancerType&&(a&&e.name===a.name||e.targetGroups.forEach((t=>{n[e.account]=n[e.account]||{},n[e.account][e.region]=n[e.account][e.region]||[],n[e.account][e.region].push(this.removeAppName(t.name))})))})),this.setState({existingTargetGroupNames:n},(()=>this.props.formik.validateForm()))}))}targetGroupFieldChanged(e,t,a){const{setFieldValue:n,values:r}=this.props.formik,i=r.targetGroups[e];"targetType"===t&&"lambda"===a&&delete i.port,Jt(i,t,a),n("targetGroups",r.targetGroups)}removeTargetGroup(e){const{setFieldValue:t,values:a}=this.props.formik,{oldTargetGroupCount:n}=this.state;a.targetGroups.splice(e,1),e<n&&this.setState({oldTargetGroupCount:n-1}),t("targetGroups",a.targetGroups)}componentDidMount(){this.updateLoadBalancerNames(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{oldTargetGroupCount:r}=this.state,i=this.protocols.map((e=>Bt.createElement("option",{key:e},e))),s=this.targetTypes.map((e=>Bt.createElement("option",{key:e},e)));return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},a.targetGroups.map(((a,l)=>{const o=t.targetGroups&&t.targetGroups[l]||{},c=("TCP"===a.protocol||"TLS"===a.protocol)&&"HTTP"===a.healthCheckProtocol,d=("TCP"===a.protocol||"TLS"===a.protocol)&&"HTTPS"===a.healthCheckProtocol;return Bt.createElement("div",{key:l,className:"wizard-pod"},Bt.createElement("div",null,Bt.createElement("div",{className:"wizard-pod-row header"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Group Name"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"group-name-prefix"},e.name,"-"),Bt.createElement("input",{className:"form-control input-sm target-group-name",type:"text",value:a.name,onChange:e=>this.targetGroupFieldChanged(l,"name",e.target.value),required:!0,disabled:l<r}),Bt.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeTargetGroup(l)},Bt.createElement("span",{className:"glyphicon glyphicon-trash"}))),o.name&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:o.name})))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},Bt.createElement(n,{id:"aws.targetGroup.targetType"})," ",Bt.createElement("span",null,"Target Type ")),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("select",{className:"form-control input-sm",value:a.targetType,onChange:e=>this.targetGroupFieldChanged(l,"targetType",e.target.value),disabled:l<r},s))))),"lambda"!==a.targetType&&Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Backend Connection"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol "),Bt.createElement(n,{id:"aws.targetGroup.protocol"})," ",Bt.createElement("select",{className:"form-control input-sm inline-number",value:a.protocol,onChange:e=>this.targetGroupFieldChanged(l,"protocol",e.target.value),disabled:l<r},i)),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port "),Bt.createElement(n,{id:"aws.targetGroup.port"})," ",Bt.createElement("input",{className:"form-control input-sm inline-number",value:a.port,onChange:e=>this.targetGroupFieldChanged(l,"port",e.target.value),type:"text",required:!0,disabled:l<r}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},"lambda"!==a.targetType&&Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol "),"TCP"===a.healthCheckProtocol&&Bt.createElement(n,{id:"aws.targetGroup.healthCheckProtocol"})," ",Bt.createElement("select",{className:"form-control input-sm inline-number",value:a.healthCheckProtocol,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckProtocol",e.target.value)},i)),"lambda"!==a.targetType&&Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port "),Bt.createElement(n,{id:"aws.targetGroup.attributes.healthCheckPort.trafficPort"})," ",Bt.createElement("select",{className:"form-control input-sm inline-number",style:{width:"90px"},value:"traffic-port"===a.healthCheckPort?"traffic-port":"manual",onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPort","traffic-port"===e.target.value?"traffic-port":"")},Bt.createElement("option",{value:"traffic-port"},"Traffic Port"),Bt.createElement("option",{value:"manual"},"Manual"))," ",Bt.createElement(ge,{className:"form-control input-sm inline-number",error:o.healthCheckPort,style:{visibility:"traffic-port"===a.healthCheckPort?"hidden":"inherit"},name:"healthCheckPort",required:!0,value:a.healthCheckPort,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPort",e.target.value)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Path "),Bt.createElement(ge,{error:o.healthCheckPath,name:"healthCheckPath",required:!0,value:a.healthCheckPath,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPath",e.target.value)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Timeout "),(c||d)&&Bt.createElement(n,{id:"aws.targetGroup.healthCheckTimeout"}),Bt.createElement(he,{error:o.healthCheckTimeout,disabled:c||d,required:!0,value:c?6:d?10:a.healthCheckTimeout,min:2,max:120,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckTimeout",e)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Interval "),Bt.createElement(he,{error:o.healthCheckInterval,required:!0,value:a.healthCheckInterval,min:5,max:300,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckInterval",e)}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck Threshold"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Healthy "),Bt.createElement(he,{error:o.healthyThreshold,value:a.healthyThreshold,min:2,max:10,onChange:e=>this.targetGroupFieldChanged(l,"healthyThreshold",e)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Unhealthy "),Bt.createElement(he,{error:o.unhealthyThreshold,required:!0,value:a.unhealthyThreshold,min:2,max:10,onChange:e=>this.targetGroupFieldChanged(l,"unhealthyThreshold",e)}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Attributes"),"lambda"!==a.targetType?Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Dereg. Delay"),Bt.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelay"})," ",Bt.createElement("input",{className:"form-control input-sm inline-number",type:"text",value:a.attributes.deregistrationDelay,onChange:e=>this.targetGroupFieldChanged(l,"attributes.deregistrationDelay",e.target.value)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",{className:"checkbox-inline",style:{paddingTop:"2px"}},Bt.createElement("input",{type:"checkbox",checked:a.attributes.stickinessEnabled,onChange:e=>this.targetGroupFieldChanged(l,"attributes.stickinessEnabled",e.target.checked)})," ",Bt.createElement("label",null,"Sticky"),Bt.createElement(n,{id:"aws.targetGroup.attributes.stickinessEnabled"}))),a.attributes.stickinessEnabled&&Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Duration "),Bt.createElement(n,{id:"aws.targetGroup.attributes.stickinessDuration"})," ",Bt.createElement("input",{className:"form-control input-sm inline-number",value:a.attributes.stickinessDuration,onChange:e=>this.targetGroupFieldChanged(l,"attributes.stickinessDuration",e.target.value),type:"text"})))):Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",{className:"checkbox-inline",style:{paddingTop:"2px"}},Bt.createElement("input",{type:"checkbox",checked:a.attributes.multiValueHeadersEnabled,onChange:e=>this.targetGroupFieldChanged(l,"attributes.multiValueHeadersEnabled",e.target.checked)})," ",Bt.createElement("label",null,"Enable Multi Value Headers"))))))})),Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("tbody",null,Bt.createElement("tr",null,Bt.createElement("td",null,Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addTargetGroup},Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new target group"))))))))}}class Nr extends Bt.Component{constructor(e){super(e),this.handleUsePreferredZonesChanged=e=>{const t="true"===e.target.value;this.setState({usePreferredZones:t}),t&&this.setDefaultZones(this.props)},this.handleSelectedZonesChanged=e=>{this.props.onChange([...e])},this.state={defaultZones:[],usePreferredZones:e.usePreferredZones||!e.selectedZones||0===e.selectedZones.length},this.setDefaultZones(e)}componentWillReceiveProps(e){e.region===this.props.region&&e.credentials===this.props.credentials||this.setDefaultZones(e)}setDefaultZones(e){const{credentials:t,onChange:a,region:n}=e,{usePreferredZones:r}=this.state;o.getAvailabilityZonesForAccountAndRegion("aws",t,n).then((e=>{this.setState({defaultZones:e}),r&&e&&a(e.slice())}))}render(){const{region:e,allZones:t,selectedZones:a}=this.props,{defaultZones:n,usePreferredZones:r}=this.state;return Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Availability Zones"),e&&Bt.createElement("div",{className:"col-md-7"},Bt.createElement("p",{className:"form-control-static"},"Automatic Availability Zone Balancing:"),Bt.createElement("select",{className:"form-control input-sm",value:r?"true":"false",onChange:this.handleUsePreferredZonesChanged},Bt.createElement("option",{value:"true"},"Enabled"),Bt.createElement("option",{value:"false"},"Manual")),Bt.createElement("br",null),r&&Bt.createElement("div",null,Bt.createElement("p",{className:"form-control-static"},"Server group will be available in:"),Bt.createElement("ul",null,n.map((e=>Bt.createElement("li",{key:e},e))))),!r&&Bt.createElement("div",null,"Restrict server group instances to:",Bt.createElement(fe,{stringOptions:t,value:a,onChange:e=>this.handleSelectedZonesChanged(e.target.value)}))))}}function Tr(e){const{application:t,credentials:a,defaultSubnetTypes:n,hideClassic:r,name:i,onChange:s,readOnly:l,region:o,subnets:c,value:d,...p}=e,u=ve(c),m=Bt.useMemo((()=>{const e=r||function(e,t,a){const{classicLaunchLockout:n,classicLaunchAllowlist:r}=gn,i=Number(Zt(a,"attributes.createTs",0))>(n||0),s=!!r&&r.some((a=>a.region===e&&a.credentials===t));return i||!s}(o,a,t);return function(e,t){const a=(e,t)=>e.label.localeCompare(t.label),n=e=>({value:e.purpose,label:e.label}),r=t?[]:[{label:"None (EC2 Classic)",value:""}],i=e.filter((e=>!e.deprecated)).sort(a).map(n),s=e.filter((e=>e.deprecated)).sort(a).map(n);return s.length&&s.unshift({label:"-----------",value:"",disabled:!0}),r.concat(i).concat(s)}(c,e)}),[r,o,a,t,u]),g=function(e,t=[]){for(const a of t){const t=e.find((e=>a===e.purpose));if(t)return t}}(c,n)||c[0],h=ye().current;return Bt.useEffect((()=>{const e=m.some((e=>e.value===d));g&&(!e||"FIRST_RENDER"!==h)&&s(be({name:i,value:g.purpose}))}),[m]),l?Bt.createElement("p",{className:"form-control-static"},e.value||"None (EC2 Classic)"):Bt.createElement(se,{options:m,value:d,onChange:s,...p})}class Ir extends zt.Component{constructor(){super(...arguments),this.handleChange=e=>{const{component:t,onChange:a,field:n}=this.props;t[n]=e.target.value,a()}}render(){var e,t,a;const{component:r,defaultSubnetTypes:i,field:s,helpKey:l,labelColumns:o,recommendedSubnetTypes:c,region:d,showSubnetWarning:p,...u}=this.props,m=r[s],g=null!=(t=null!=c?c:null==(e=gn.serverGroups)?void 0:e.recommendedSubnets)?t:[],h=null!=i?i:[gn.defaults.subnetType],f=g.some((e=>m&&m.includes(e))),v=null==(a=gn.serverGroups)?void 0:a.subnetWarning;return zt.createElement("div",{className:"form-group"},zt.createElement("div",{className:`col-md-${o} sm-label-right`},"VPC Subnet ",zt.createElement(n,{id:l})),zt.createElement("div",{className:"col-md-7"},d?zt.createElement(Tr,{...u,inputClassName:"form-control input-sm",credentials:r.credentials,defaultSubnetTypes:h,region:d,value:m,onChange:this.handleChange}):"(Select an account)",p&&!f&&Boolean(v)&&zt.createElement("div",{className:"alert alert-warning sp-margin-s-top horizontal center"},zt.createElement("i",{className:"fa fa-exclamation-triangle sp-margin-s-top"}),zt.createElement("div",{className:"sp-margin-s-left"},zt.createElement(we,{message:v,style:{display:"inline-block",marginLeft:"2px"}})))))}}class xr extends Bt.Component{constructor(){super(...arguments),this.state={accounts:void 0,availabilityZones:[],existingLoadBalancerNames:[],hideInternalFlag:!1,internalFlagToggled:!1,regions:[],subnets:[]},this.props$=new fa,this.destroy$=new fa,this.internalFlagChanged=e=>{this.setState({internalFlagToggled:!0}),this.props.formik.handleChange(e)},this.handleSubnetUpdated=e=>{this.props.formik.setFieldValue("subnetType",e)},this.accountUpdated=e=>{this.props.formik.setFieldValue("credentials",e)},this.regionUpdated=e=>{this.props.formik.setFieldValue("region",e)},this.stackChanged=e=>{this.props.formik.setFieldValue("stack",e.target.value)},this.detailChanged=e=>{this.props.formik.setFieldValue("detail",e.target.value)},this.handleAvailabilityZonesChanged=e=>{this.props.formik.setFieldValue("regionZones",e)}}validate(e){const t={};return this.state.existingLoadBalancerNames.includes(e.name)&&(t.name=`There is already a load balancer in ${e.credentials}:${e.region} with that name.`),e.name&&e.name.length>32&&(t.name="Load balancer names cannot exceed 32 characters in length"),e.stack&&!e.stack.match(/^[a-zA-Z0-9]*$/)&&(t.stack="Stack can only contain letters and numbers."),e.detail&&!e.detail.match(/^[a-zA-Z0-9-]*$/)&&(t.detail="Detail can only contain letters, numbers, and dashes."),t}buildName(){const{values:e}=this.props.formik;if(Ut(e.moniker)){const t=Ee.parseLoadBalancerName(e.name);e.stack=t.stack,e.detail=t.freeFormDetails}else e.stack=e.moniker.stack,e.detail=e.moniker.detail;delete e.name}shouldHideInternalFlag(){return!!(gn&&gn.loadBalancers&&gn.loadBalancers.inferInternalFlagFromSubnet)&&(delete this.props.formik.values.isInternal,!0)}componentDidMount(){this.setState({hideInternalFlag:this.shouldHideInternalFlag()}),this.props.loadBalancer&&this.props.isNew&&this.buildName();const e=this.props$.pipe(Ca((e=>e.formik.values))),t=this.props$.pipe(Ca((e=>e.app.name)),ka()),a={account$:e.pipe(Ca((e=>e.credentials)),ka()),region$:e.pipe(Ca((e=>e.region)),ka()),subnetPurpose$:e.pipe(Ca((e=>e.subnetType)),ka()),stack$:e.pipe(Ca((e=>e.stack)),ka()),detail$:e.pipe(Ca((e=>e.detail)),ka())},n=va(o.listAccounts("aws")).pipe(Sa(1)),r=ya([a.account$,n]).pipe(Ga((([e,t])=>o.getRegionsForAccount(e))),Sa(1)),i=this.props.app.getDataSource("loadBalancers").data$,s=ya([i,a.account$,a.region$]).pipe(Ca((([e,t,a])=>e.filter((e=>e.account===t&&e.region===a)).map((e=>e.name)))),Sa(1)),l=ya([a.account$,a.region$]).pipe(Ga((([e,t])=>this.getAvailableSubnets(e,t))),Ca((e=>this.makeSubnetOptions(e))),Sa(1)),c=ya([l,a.subnetPurpose$]).pipe(Ca((([e,t])=>e&&e.find((e=>e.purpose===t))))),d=c.pipe(Ca((e=>e?_t(e.availabilityZones).sort():[]))),p=a.region$.pipe(Na(r),Ca((([e,t])=>t.find((t=>t.name===e)))),Ca((e=>e?e.availabilityZones:[]))),u=ya([t,a.stack$,a.detail$]).pipe(Ca((([e,t,a])=>({app:e,stack:t,detail:a,cluster:Ee.getClusterName(e,t,a)}))));r.pipe(Na(a.region$),Ta(this.destroy$)).subscribe((([e,t])=>{e.some((e=>e.name===t))||this.props.formik.setFieldValue("region",e[0]&&e[0].name)})),p.pipe(Ta(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("regionZones",e)})),c.pipe(Ta(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("vpcId",e&&e.vpcIds[0]),this.props.formik.setFieldValue("subnetType",e&&e.purpose),!this.state.hideInternalFlag&&!this.state.internalFlagToggled&&e&&e.purpose&&this.props.formik.setFieldValue("isInternal",e.purpose.includes("internal"))})),u.pipe(Ta(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("moniker",e),this.props.formik.setFieldValue("name",e.cluster)})),ya([n,r,d,s,l]).pipe(Ta(this.destroy$)).subscribe((([e,t,a,n,r])=>this.setState({accounts:e,regions:t,availabilityZones:a,existingLoadBalancerNames:n,subnets:r})))}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}getAvailableSubnets(e,t){return g.listSubnets().then((a=>ea(a).filter({account:e,region:t}).reject({target:"ec2"}).reject({purpose:null}).value()))}makeSubnetOptions(e){const t=Wt(e,(e=>e.purpose));return Object.keys(t).map((e=>t[e])).map((e=>(e=>{const{purpose:t,label:a,deprecated:n}=e[0];return{purpose:t,label:a,deprecated:n,vpcIds:_t(e.map((e=>e.vpcId))),availabilityZones:_t(e.map((e=>e.availabilityZone)))}})(e)))}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{accounts:r,availabilityZones:i,hideInternalFlag:s,regions:l,subnets:o}=this.state,c=ha({"col-md-12":!0,well:!0,"alert-danger":!!t.name,"alert-info":!t.name});return Bt.createElement("div",{className:"container-fluid form-horizontal"},!r&&Bt.createElement("div",{style:{height:"200px"}},Bt.createElement(te,{size:"medium"})),r&&Bt.createElement("div",{className:"modal-body"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:c},Bt.createElement("strong",null,"Your load balancer will be named: "),Bt.createElement("span",null,a.name),Bt.createElement(n,{id:"aws.loadBalancer.name"}),Bt.createElement(Ja,{type:"text",style:{display:"none"},className:"form-control input-sm no-spel",name:"name"}),t.name&&Bt.createElement(de,{type:"error",message:t.name}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),Bt.createElement("div",{className:"col-md-7"},Bt.createElement(Ce,{value:a.credentials,onChange:e=>this.accountUpdated(e.target.value),accounts:r,provider:"aws"}))),Bt.createElement(ke,{labelColumns:3,component:a,field:"region",account:a.credentials,onChange:this.regionUpdated,regions:l}),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",Bt.createElement(n,{id:"aws.loadBalancer.stack"})),Bt.createElement("div",{className:"col-md-3"},Bt.createElement("input",{type:"text",className:"form-control input-sm no-spel "+(t.stack?"invalid":""),value:a.stack,name:"stack",onChange:this.stackChanged})),Bt.createElement("div",{className:"col-md-6 form-inline"},Bt.createElement("label",{className:"sm-label-right"},Bt.createElement("span",null,"Detail ",Bt.createElement(n,{id:"aws.loadBalancer.detail"})," ")),Bt.createElement("input",{type:"text",className:"form-control input-sm no-spel "+(t.detail?"invalid":""),value:a.detail,name:"detail",onChange:this.detailChanged})),t.stack&&Bt.createElement("div",{className:"col-md-7 col-md-offset-3"},Bt.createElement(de,{type:"error",message:t.stack})),t.detail&&Bt.createElement("div",{className:"col-md-7 col-md-offset-3"},Bt.createElement(de,{type:"error",message:t.detail}))),Bt.createElement(Nr,{credentials:a.credentials,region:a.region,onChange:this.handleAvailabilityZonesChanged,selectedZones:a.regionZones,allZones:i}),Bt.createElement(Ir,{labelColumns:3,helpKey:"aws.loadBalancer.subnet",component:a,field:"subnetType",region:a.region,subnets:o,application:e,onChange:()=>this.handleSubnetUpdated(a.subnetType)}),a.vpcId&&!s&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},Bt.createElement("b",null,"Internal")," ",Bt.createElement(n,{id:"aws.loadBalancer.internal"})),Bt.createElement("div",{className:"col-md-7 checkbox"},Bt.createElement("label",null,Bt.createElement(Ja,{name:"isInternal",onChange:this.internalFlagChanged,render:({field:{value:e,...t}})=>Bt.createElement("input",{type:"checkbox",...t,checked:!!e})}),"Create an internal load balancer")))))}}class Ar extends Bt.Component{constructor(e){super(e),this.destroy$=new fa,this.props$=new fa,this.refresh$=new fa,this.clearRemoved=()=>{this.setState({removed:[]},(()=>this.props.formik.validateForm()))},this.handleSecurityGroupsChanged=e=>{this.props.formik.setFieldValue("securityGroups",e.map((e=>e.value)))};const t=Zt(gn,"defaultSecurityGroups",[]);this.state={availableSecurityGroups:[],defaultSecurityGroups:t,loaded:!1,refreshing:!1,removed:[],refreshTime:Se.get("securityGroups").getStats().ageMax}}validate(){const{removed:e}=this.state;if(e&&e.length){return{securityGroupsRemoved:`${U.get("Firewalls")} removed: ${e.join(", ")}`}}return{}}updateRemovedSecurityGroups(e,t){const{isNew:a}=this.props,{defaultSecurityGroups:n,removed:r}=this.state,i=e=>t.find((t=>t.name===e||t.id===e)),[s,l]=ta((()=>{const t=e.concat(r).sort();return _t((a?n:[]).concat(t))})(),(e=>!!i(e))),o=s.map((e=>i(e).name));jt(e,o)||this.props.formik.setFieldValue("securityGroups",o),this.setState({removed:l},(()=>this.props.formik.validateForm()))}onRefreshStart(){this.props.onLoadingChanged(!0),this.setState({refreshing:!0})}onRefreshComplete(){this.props.onLoadingChanged(!1);const e=Se.get("securityGroups").getStats().ageMax;this.setState({refreshing:!1,loaded:!0,refreshTime:e})}componentDidMount(){const e=this.refresh$.pipe(Ia((()=>this.onRefreshStart())),Ga((()=>h.cacheInitializer.refreshCache("securityGroups"))),xa((()=>h.securityGroupReader.getAllSecurityGroups())),Ia((()=>this.onRefreshComplete()))),t=this.props$.pipe(Ca((e=>e.formik.values))),a=t.pipe(Ca((e=>e.vpcId)),ka());ya([a,e]).pipe(Na(t),Ca((([[e,t],a])=>{const n=t[a.credentials]||{};return(n.aws&&n.aws[a.region]||[]).filter((t=>e===t.vpcId)).sort()}))).pipe(Na(t),Ta(this.destroy$)).subscribe((([e,t])=>{this.setState({availableSecurityGroups:e.map((e=>({label:`${e.name} (${e.id})`,value:e.name})))}),this.updateRemovedSecurityGroups(t.securityGroups,e)})),this.refresh$.next()}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{securityGroups:e}=this.props.formik.values,{availableSecurityGroups:t,loaded:a,refreshing:n,removed:r,refreshTime:i}=this.state;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",null,r.length>0&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following ",U.get("firewalls")," could not be found in the selected account/region/VPC and were removed:"),Bt.createElement("ul",null,r.map((e=>Bt.createElement("li",{key:e},e)))),Bt.createElement("p",{className:"text-right"},Bt.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:this.clearRemoved},"Okay"))))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},U.get("Firewalls")),Bt.createElement("div",{className:"col-md-9"},!a&&Bt.createElement("div",{style:{paddingTop:"13px"}},Bt.createElement(te,{size:"small"})),a&&Bt.createElement(tn,{multi:!0,value:e,options:t,onChange:this.handleSecurityGroupsChanged,clearable:!1}))),Bt.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},Bt.createElement("div",{className:"col-md-9 col-md-offset-3"},Bt.createElement("p",null,n&&Bt.createElement("span",null,Bt.createElement("span",{className:"fa fa-sync-alt fa-spin"})," "),U.get("Firewalls"),!n&&Bt.createElement("span",null," last refreshed ",D(i)),n&&Bt.createElement("span",null," refreshing...")),Bt.createElement("p",null,"If you're not finding a ",U.get("firewall")," that was recently added,"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.refresh$.next()},"click here")," ","to refresh the list.")))))}}class Pr{updateHealthCounts(e){const t=e.instances;if(e.instanceCounts={up:t.filter((e=>"InService"===e.health[0].state)).length,down:t.filter((e=>"Down"===e.healthState)).length,outOfService:t.filter((e=>"OutOfService"===e.healthState)).length,starting:void 0,succeeded:void 0,failed:void 0,unknown:void 0},e.serverGroups){const t=Ot(e.serverGroups.map((e=>e.instances)));e.instanceCounts.up=t.filter((e=>"InService"===e.health[0].state)).length,e.instanceCounts.down=t.filter((e=>"Down"===e.healthState)).length,e.instanceCounts.outOfService=t.filter((e=>"OutOfService"===e.healthState)).length}}transformInstance(e,t,a,n){const r=e.health||{};"healthy"===r.state&&(r.state="InService"),e.provider=t,e.account=a,e.region=n,e.healthState=r.state?"InService"===r.state?"Up":"Down":"OutOfService",e.health=[r]}addVpcNameToContainer(e){return t=>{const a=t.find((t=>t.id===e.vpcId));return e.vpcName=a?a.name:"",e}}normalizeServerGroups(e,t,a,n){e.forEach((e=>{e.account=e.account||t.account,e.region=e.region||t.region,e.cloudProvider=e.cloudProvider||t.cloudProvider,e.detachedInstances?(e.detachedInstances=e.detachedInstances.map((e=>({id:e}))),e.instances=e.instances.concat(e.detachedInstances)):e.detachedInstances=[],e.instances.forEach((e=>{this.transformInstance(e,t.type,t.account,t.region),e[a]=[t.name],e.health.type=n})),this.updateHealthCounts(e)}))}normalizeTargetGroup(e){this.normalizeServerGroups(e.serverGroups,e,"targetGroups","TargetGroup");const t=Qt(e.serverGroups,{isDisabled:!1});return e.provider=e.type,e.instances=ea(t).map("instances").flatten().value(),e.detachedInstances=ea(t).map("detachedInstances").flatten().value(),this.updateHealthCounts(e),Ua.all([xn.listVpcs(),o.listAllAccounts()]).then((([t,a])=>{const n=this.addVpcNameToContainer(e)(t);return n.serverGroups=n.serverGroups.map((e=>{const t=a.find((t=>t.name===e.account)),n=t&&t.cloudProvider||e.cloudProvider;return e.cloudProvider=n,e.instances.forEach((e=>{e.cloudProvider=n,e.provider=n})),{...e,cloudProvider:n}})),n}))}normalizeActions(e){if("application"===e.loadBalancerType){e.listeners.forEach((e=>{e.defaultActions.sort(((e,t)=>e.order-t.order)),e.rules.forEach((e=>e.actions.sort(((e,t)=>e.order-t.order))))}))}}normalizeLoadBalancer(e){this.normalizeServerGroups(e.serverGroups,e,"loadBalancers","LoadBalancer");let t=e.serverGroups;if(e.targetGroups){const a=e;a.targetGroups.forEach((e=>this.normalizeTargetGroup(e))),t=Ot(aa(a.targetGroups,"serverGroups"))}e.loadBalancerType=e.loadBalancerType||"classic",e.provider=e.type,this.normalizeActions(e);const a=Qt(t,{isDisabled:!1});return e.instances=ea(a).map("instances").flatten().value(),e.detachedInstances=ea(a).map("detachedInstances").flatten().value(),this.updateHealthCounts(e),xn.listVpcs().then((t=>this.addVpcNameToContainer(e)(t)))}static convertClassicLoadBalancerForEditing(e){const t={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,cloudProvider:e.cloudProvider,credentials:e.credentials||e.account,listeners:e.listeners,loadBalancerType:"classic",name:e.name,regionZones:e.availabilityZones,securityGroups:e.securityGroups,vpcId:e.vpcId,healthCheck:void 0,healthTimeout:e.healthTimeout,healthInterval:e.healthInterval,healthyThreshold:e.healthyThreshold,unhealthyThreshold:e.unhealthyThreshold,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckPath:e.healthCheckPath,idleTimeout:e.idleTimeout||60,subnetType:e.subnetType};if(e.elb){const a=e.elb;if(t.securityGroups=a.securityGroups,t.vpcId=a.vpcid||a.vpcId,a.listenerDescriptions&&(t.listeners=a.listenerDescriptions.map((e=>{const t=e.listener;if(t.sslcertificateId){const e=t.sslcertificateId.split("/");t.sslcertificateId=e[1],t.sslCertificateType=e[0].split(":")[2]}return{internalProtocol:t.instanceProtocol,internalPort:t.instancePort,externalProtocol:t.protocol,externalPort:t.loadBalancerPort,sslCertificateId:t.sslcertificateId,sslCertificateName:t.sslcertificateId,sslCertificateType:t.sslCertificateType,policyNames:e.policyNames}}))),a.healthCheck&&a.healthCheck.target){t.healthTimeout=a.healthCheck.timeout,t.healthInterval=a.healthCheck.interval,t.healthyThreshold=a.healthCheck.healthyThreshold,t.unhealthyThreshold=a.healthCheck.unhealthyThreshold;const e=a.healthCheck.target,n=e.indexOf(":");let r=e.indexOf("/");if(-1===r&&(r=e.length),-1!==n){t.healthCheckProtocol=e.substring(0,n);const a=Number(e.substring(n+1,r));t.healthCheckPath=e.substring(r),isNaN(a)||(t.healthCheckPort=a)}}}return t}static convertApplicationLoadBalancerForEditing(e){const t=Ee.parseLoadBalancerName(e.name).application,a={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,loadBalancerType:"application",cloudProvider:e.cloudProvider,credentials:e.account||e.credentials,listeners:[],targetGroups:[],name:e.name,regionZones:e.availabilityZones,securityGroups:[],subnetType:e.subnetType,vpcId:void 0,idleTimeout:e.idleTimeout||60,deletionProtection:e.deletionProtection||!1,ipAddressType:e.ipAddressType||"ipv4",dualstack:"dualstack"===e.ipAddressType};if(e.elb){const n=e.elb;a.securityGroups=n.securityGroups,a.vpcId=n.vpcid||n.vpcId,n.listeners&&(a.listeners=n.listeners.map((e=>{const a=[];return e.certificates&&e.certificates.forEach((e=>{const t=e.certificateArn.split(":"),n=t[5].split("/");a.push({certificateArn:e.certificateArn,type:t[2],name:n[1]})})),(e.defaultActions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,"")),e.redirectActionConfig=e.redirectConfig})),e.rules=(e.rules||[]).filter((e=>!e.default)),e.rules.forEach((e=>{(e.actions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,"")),e.redirectActionConfig=e.redirectConfig})),(e.conditions||[]).forEach((e=>{"http-request-method"===e.field&&(e.values=e.httpRequestMethodConfig.values)})),e.conditions=e.conditions||[]})),e.rules.sort(((e,t)=>e.priority-t.priority)),{protocol:e.protocol,port:e.port,defaultActions:e.defaultActions,certificates:a,rules:e.rules||[],sslPolicy:e.sslPolicy}}))),n.targetGroups&&(a.targetGroups=n.targetGroups.map((e=>({name:e.targetGroupName.replace(`${t}-`,""),protocol:e.protocol,port:e.port,targetType:e.targetType,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckPath:e.healthCheckPath,healthCheckTimeout:e.healthCheckTimeoutSeconds,healthCheckInterval:e.healthCheckIntervalSeconds,healthyThreshold:e.healthyThresholdCount,unhealthyThreshold:e.unhealthyThresholdCount,attributes:{deregistrationDelay:Number(e.attributes["deregistration_delay.timeout_seconds"]),stickinessEnabled:"true"===e.attributes["stickiness.enabled"],stickinessType:e.attributes["stickiness.type"],stickinessDuration:Number(e.attributes["stickiness.lb_cookie.duration_seconds"]),multiValueHeadersEnabled:"true"===e.attributes["lambda.multi_value_headers.enabled"]}}))))}return a}static convertNetworkLoadBalancerForEditing(e){const t=Ee.parseLoadBalancerName(e.name).application,a={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,loadBalancerType:"network",cloudProvider:e.cloudProvider,credentials:e.account||e.credentials,listeners:[],targetGroups:[],name:e.name,regionZones:e.availabilityZones,securityGroups:[],subnetType:e.subnetType,vpcId:void 0,deletionProtection:e.deletionProtection,loadBalancingCrossZone:e.loadBalancingCrossZone,ipAddressType:e.ipAddressType||"ipv4",dualstack:"dualstack"===e.ipAddressType};if(e.elb){const n=e.elb;a.securityGroups=n.securityGroups,a.vpcId=n.vpcid||n.vpcId,n.listeners&&(a.listeners=n.listeners.map((e=>{const a=[];return e.certificates&&e.certificates.forEach((e=>{const t=e.certificateArn.split(":"),n=t[5].split("/");a.push({certificateArn:e.certificateArn,type:t[2],name:n[1]})})),(e.defaultActions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,""))})),e.rules=(e.rules||[]).filter((e=>!e.default)),e.rules.forEach((e=>{(e.actions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,""))})),e.conditions=e.conditions||[]})),e.rules.sort(((e,t)=>e.priority-t.priority)),{protocol:e.protocol,port:e.port,defaultActions:e.defaultActions,certificates:a,rules:e.rules||[],sslPolicy:e.sslPolicy}}))),n.targetGroups&&(a.targetGroups=n.targetGroups.map((e=>({name:e.targetGroupName.replace(`${t}-`,""),protocol:e.protocol,port:e.port,targetType:e.targetType,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckTimeout:e.healthCheckTimeoutSeconds,healthCheckInterval:e.healthCheckIntervalSeconds,healthyThreshold:e.healthyThresholdCount,unhealthyThreshold:e.unhealthyThresholdCount,healthCheckPath:e.healthCheckPath,attributes:{deregistrationDelay:Number(e.attributes["deregistration_delay.timeout_seconds"]),deregistrationDelayConnectionTermination:Boolean("true"===e.attributes["deregistration_delay.connection_termination.enabled"]),preserveClientIp:Boolean("true"===e.attributes["preserve_client_ip.enabled"])}}))))}return a}static constructNewClassicLoadBalancerTemplate(e){return{availabilityZones:void 0,name:"",stack:"",detail:"",loadBalancerType:"classic",isInternal:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||gn.defaults.account,region:e.defaultRegions.aws||gn.defaults.region,vpcId:null,subnetType:gn.defaults.subnetType,healthCheck:void 0,healthCheckProtocol:"HTTP",healthCheckPort:7001,healthCheckPath:"/healthcheck",healthTimeout:5,healthInterval:10,healthyThreshold:10,unhealthyThreshold:2,idleTimeout:60,regionZones:[],securityGroups:[],listeners:[{externalPort:80,externalProtocol:"HTTP",internalPort:7001,internalProtocol:"HTTP"}]}}static constructNewApplicationLoadBalancerTemplate(e){const t="targetgroup";return{name:"",availabilityZones:void 0,stack:"",detail:"",loadBalancerType:"application",ipAddressType:"ipv4",dualstack:!1,isInternal:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||gn.defaults.account,region:e.defaultRegions.aws||gn.defaults.region,vpcId:null,subnetType:gn.defaults.subnetType,idleTimeout:60,deletionProtection:!1,targetGroups:[{name:t,protocol:"HTTP",port:e.attributes.instancePort||a.defaultInstancePort,targetType:"instance",healthCheckProtocol:"HTTP",healthCheckPort:"traffic-port",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:2,attributes:{deregistrationDelay:300,stickinessEnabled:!1,stickinessType:"lb_cookie",stickinessDuration:8400,multiValueHeadersEnabled:!1}}],regionZones:[],securityGroups:[],listeners:[{certificates:[],protocol:"HTTP",port:80,defaultActions:[{type:"forward",targetGroupName:t}],rules:[]}]}}static constructNewNetworkLoadBalancerTemplate(e){const t="targetgroup";return{name:"",availabilityZones:void 0,stack:"",detail:"",loadBalancerType:"network",isInternal:!1,ipAddressType:"ipv4",dualstack:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||gn.defaults.account,region:e.defaultRegions.aws||gn.defaults.region,vpcId:null,subnetType:gn.defaults.subnetType,deletionProtection:!1,loadBalancingCrossZone:!0,securityGroups:[],targetGroups:[{name:t,protocol:"TCP",port:7001,targetType:"instance",healthCheckProtocol:"TCP",healthCheckPath:"/healthcheck",healthCheckPort:"traffic-port",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:10,attributes:{deregistrationDelay:300}}],regionZones:[],listeners:[{certificates:[],protocol:"TCP",port:80,defaultActions:[{type:"forward",targetGroupName:t}],rules:[]}]}}}er(".wizard-pod {\n padding-bottom: 15px;\n}\n.wizard-pod > div {\n border: 1px solid var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n padding: 5px;\n border-bottom: 1px solid var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row label {\n font-weight: 400;\n padding-right: 5px;\n}\n.wizard-pod .wizard-pod-row.header {\n background-color: var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row.header .glyphicon-trash {\n padding: 0 8px;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-title {\n font-weight: 800;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n padding: 0;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data label {\n font-weight: 600;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data .wizard-pod-content {\n padding: 0 10px 0 0;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-title {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n max-height: 37px;\n -ms-flex-preferred-size: 120px;\n flex-basis: 120px;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: reverse;\n -ms-flex-direction: row-reverse;\n flex-direction: row-reverse;\n font-weight: 600;\n text-align: right;\n margin-right: 10px;\n width: 100px;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n -webkit-box-align: baseline;\n -ms-flex-align: baseline;\n align-items: baseline;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n -webkit-box-align: baseline;\n -ms-flex-align: baseline;\n align-items: baseline;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 5px 0;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data.spread {\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .wizard-pod-content {\n padding: 0 10px 5px 0;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .group-name-prefix {\n -webkit-box-flex: 2;\n -ms-flex-positive: 2;\n flex-grow: 2;\n white-space: nowrap;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table thead th {\n font-weight: 600;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table td {\n vertical-align: middle;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table > tbody > tr:first-child > td {\n border-top: none;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-errors {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n}\n.wizard-pod .listener-rule .handle {\n cursor: move;\n width: 10px;\n padding: 0;\n}\n.wizard-pod .listener-rule .listener-rule-condition {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n.wizard-pod .listener-rule .listener-rule-condition label {\n white-space: nowrap;\n}\n.wizard-pod .listener-rule .listener-rule-condition .help-field > span {\n top: 4px;\n padding: 0 2px;\n}\n.wizard-pod .listener-rule .listener-rule-condition .remove-condition {\n min-width: 15px;\n padding-top: 4px;\n}\n.wizard-pod .listener-rule .add-new-container {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n.wizard-pod .listener-rule .add-new-container .add-new {\n padding: 2px;\n margin-bottom: 0;\n}\n.rule-sortable-helper {\n z-index: 99999;\n width: 500px;\n}\n");const zr=class extends Bt.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Rt(e);if(s.listeners.forEach((e=>{e.defaultActions.forEach((e=>{e.authenticateOidcConfig&&(e.authenticateOidcActionConfig=e.authenticateOidcConfig,delete e.authenticateOidcConfig)})),e.rules.forEach((e=>e.actions.forEach((e=>{e.authenticateOidcConfig&&(e.authenticateOidcActionConfig=e.authenticateOidcConfig,delete e.authenticateOidcConfig)}))))})),a)this.formatListeners(s).then((()=>{this.setIpAddressType(s),n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ge.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}};const t=e.command?e.command:e.loadBalancer?Pr.convertApplicationLoadBalancerForEditing(e.loadBalancer):Pr.constructNewApplicationLoadBalancerTemplate(e.app);this.state={includeSecurityGroups:!!t.vpcId,isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(zr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{"HTTP"===a.protocol&&(delete a.sslPolicy,a.certificates=[]),a.certificates.forEach((a=>{a.certificateArn=this.certificateIdAsARN(t.accountId,a.name,e.region,a.type||this.certificateTypes[0])}))}))}))}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}addAppName(e){return`${this.props.app.name}-${e}`}manageTargetGroupNames(e){(e.targetGroups||[]).forEach((e=>{e.name=this.addAppName(e.name)})),(e.listeners||[]).forEach((e=>{e.defaultActions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))})),(e.rules||[]).forEach((e=>{e.actions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))}))}))}))}manageRules(e){e.listeners.forEach((e=>{e.rules.forEach(((e,t)=>{e.priority=t+1,e.conditions=e.conditions.filter((e=>"http-request-method"!==e.field?e.values[0].length>0:e.values.length>0))}))}))}setIpAddressType(e){e.ipAddressType=e.dualstack?"dualstack":"ipv4",delete e.dualstack}formatCommand(e){this.setAvailabilityZones(e),this.manageTargetGroupNames(e),this.manageRules(e),this.setIpAddressType(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Application Load Balancer":"Create New Application Load Balancer";return r||(l=`Edit ${i.name}: ${i.region}: ${i.credentials}`),Bt.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",render:({formik:t,nextIdx:i,wizard:s})=>{const l=r||a,o=!!t.values.vpcId;return Bt.createElement(Bt.Fragment,null,l&&Bt.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>Bt.createElement(xr,{app:e,forPipelineConfig:a,formik:t,isNew:r,loadBalancer:n,ref:i})}),o&&Bt.createElement(E,{label:U.get("Firewalls"),wizard:s,order:i(),render:({innerRef:e,onLoadingChanged:a})=>Bt.createElement(Ar,{formik:t,isNew:r,onLoadingChanged:a,ref:e})}),Bt.createElement(E,{label:"Target Groups",wizard:s,order:i(),render:({innerRef:a})=>Bt.createElement(Gr,{ref:a,app:e,formik:t,isNew:r,loadBalancer:n})}),Bt.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:a})=>Bt.createElement(yr,{ref:a,app:e,formik:t})}),Bt.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>Bt.createElement(lr,{ref:e})}))}})}};let Br=zr;Br.defaultProps={closeModal:C,dismissModal:C};er(".AmazonLoadBalancer-AdvancedSettings .StandardFieldLayout .sm-label-right {\n width: 180px;\n}\n");class Dr extends Bt.Component{render(){const{values:e}=this.props.formik,{maxValue:t}=ue;return Bt.createElement("div",{className:"form-group AmazonLoadBalancer-AdvancedSettings"},Bt.createElement(s,{name:"healthTimeout",label:"Timeout",required:!0,help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.healthTimeout"}),input:t=>Bt.createElement(u,{...t,min:0,max:e.healthInterval}),validate:t(e.healthInterval,"Timeout must be less than the health interval.")}),Bt.createElement(s,{name:"healthInterval",label:"Interval",required:!0,help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.healthInterval"}),input:e=>Bt.createElement(u,{...e,min:0})}),Bt.createElement(s,{name:"healthyThreshold",label:"Healthy Threshold",required:!0,help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.healthyThreshold"}),input:e=>Bt.createElement(u,{...e,min:0})}),Bt.createElement(s,{name:"unhealthyThreshold",label:"Unhealthy Threshold",required:!0,help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.unhealthyThreshold"}),input:e=>Bt.createElement(u,{...e,min:0})}),Bt.createElement(s,{name:"idleTimeout",label:"Idle Timeout",required:!0,help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.idleTimeout"}),input:e=>Bt.createElement(u,{...e,min:0})}),Bt.createElement("div",{className:"col-md-12"},Bt.createElement("p",null,"Additional configuration options (cross-zone load balancing, session stickiness, access logs) are available via the AWS console.")))}}class $r extends Bt.Component{constructor(){super(...arguments),this.healthCheckPathChanged=e=>{e&&0!==e.indexOf("/")&&this.props.formik.setFieldValue("healthCheckPath",`/${e}`)}}requiresHealthCheckPath(){const{values:e}=this.props.formik;return e.healthCheckProtocol&&0===e.healthCheckProtocol.indexOf("HTTP")}render(){return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"col-md-4 sm-label-right"},"Ping"),Bt.createElement("div",{className:"col-md-8"},Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("thead",null,Bt.createElement("tr",null,Bt.createElement("th",{style:{width:"35%"}},"Protocol"),Bt.createElement("th",{style:{width:"30%"}},"Port"),Bt.createElement("th",null,this.requiresHealthCheckPath()&&Bt.createElement("span",null,"Path")))),Bt.createElement("tbody",null,Bt.createElement("tr",null,Bt.createElement("td",null,Bt.createElement(s,{name:"healthCheckProtocol",required:!0,input:e=>Bt.createElement(se,{...e,options:["HTTP","HTTPS","SSL","TCP"]})})),Bt.createElement("td",null,Bt.createElement(s,{name:"healthCheckPort",required:!0,input:e=>Bt.createElement(u,{...e,min:1,max:65534})})),Bt.createElement("td",null,this.requiresHealthCheckPath()&&Bt.createElement(s,{name:"healthCheckPath",input:e=>Bt.createElement(l,{...e}),required:!0,onChange:this.healthCheckPathChanged})))))))}}er(".create-classic-load-balancer-wizard-listeners .Select-control {\n height: 30px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-placeholder {\n line-height: 26px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-value {\n line-height: 26px !important;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-value .Select-value-label {\n line-height: 26px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-input {\n height: 26px;\n}\n");class Mr extends Bt.Component{constructor(){super(...arguments),this.protocols=["HTTP","HTTPS","TCP","SSL"],this.secureProtocols=["HTTPS","SSL"],this.certificateTypes=Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),this.state={certificates:[]},this.addListener=()=>{this.props.formik.values.listeners.push({internalProtocol:"HTTP",externalProtocol:"HTTP",externalPort:80,internalPort:80}),this.updateListeners()}}componentDidMount(){this.loadCertificates()}loadCertificates(){ur.listCertificates().then((e=>{this.setState({certificates:e})}))}updateListeners(){const{values:e,setFieldValue:t}=this.props.formik;t("listeners",e.listeners)}showCertificateSelect(e){return"iam"===e.sslCertificateType&&this.state.certificates&&Object.keys(this.state.certificates).length>0}listenerExternalProtocolChanged(e,t){e.externalProtocol=t,this.secureProtocols.includes(t)&&(e.externalPort=443,this.certificateTypes.length>=1&&(e.sslCertificateType=this.certificateTypes[0])),"HTTP"===t&&(e.externalPort=80),this.updateListeners()}listenerInternalProtocolChanged(e,t){e.internalProtocol=t,this.updateListeners()}listenerExternalPortChanged(e,t){e.externalPort=Number.parseInt(t,10),this.updateListeners()}listenerInternalPortChanged(e,t){e.internalPort=Number.parseInt(t,10),this.updateListeners()}listenerCertificateTypeChanged(e,t){e.sslCertificateType=t,this.updateListeners()}handleListenerCertificateChanged(e,t){e.sslCertificateName=t,this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}renderCertificateSelector(e){if(this.secureProtocols.includes(e.externalProtocol)){if(this.showCertificateSelect(e)){const{values:t}=this.props.formik,{certificates:a}=this.state;return Bt.createElement(hr,{certificates:a,accountName:t.credentials,currentValue:e.sslCertificateName,app:this.props.app,onCertificateSelect:t=>this.handleListenerCertificateChanged(e,t)})}return Bt.createElement("input",{className:"input-sm",style:{width:"100%",marginLeft:"10px"},required:!0,onChange:t=>this.handleListenerCertificateChanged(e,t.target.value),value:e.sslCertificateName})}return null}render(){const{values:e}=this.props.formik;return Bt.createElement("div",{className:"container-fluid form-horizontal create-classic-load-balancer-wizard-listeners"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("thead",null,Bt.createElement("tr",null,Bt.createElement("th",null,"External Protocol"),Bt.createElement("th",null,"External Port"),Bt.createElement("th",null),Bt.createElement("th",null,"Internal Protocol"),Bt.createElement("th",null,"Internal Port"),Bt.createElement("th",null))),Bt.createElement("tbody",null,e.listeners.map(((e,t)=>Bt.createElement(Bt.Fragment,{key:t},Bt.createElement("tr",{key:t+"-main"},Bt.createElement("td",null,Bt.createElement("select",{className:"form-control input-sm",value:e.externalProtocol,onChange:t=>this.listenerExternalProtocolChanged(e,t.target.value)},this.protocols.map((e=>Bt.createElement("option",{key:e},e))))),Bt.createElement("td",null,Bt.createElement("input",{className:"form-control input-sm",type:"number",min:"0",value:e.externalPort,onChange:t=>this.listenerExternalPortChanged(e,t.target.value),required:!0})),Bt.createElement("td",{className:"small",style:{paddingTop:"10px"}},"→"),Bt.createElement("td",null,Bt.createElement("select",{className:"form-control input-sm",value:e.internalProtocol,onChange:t=>this.listenerInternalProtocolChanged(e,t.target.value)},this.protocols.map((e=>Bt.createElement("option",{key:e},e))))),Bt.createElement("td",null,Bt.createElement("input",{className:"form-control input-sm",type:"number",min:"0",value:e.internalPort,onChange:t=>this.listenerInternalPortChanged(e,t.target.value),required:!0})),Bt.createElement("td",null,Bt.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(t)},Bt.createElement("span",{className:"glyphicon glyphicon-trash"})))),this.secureProtocols.includes(e.externalProtocol)&&Bt.createElement("tr",{key:t+"-ssl"},Bt.createElement("td",{colSpan:5,style:{borderTopWidth:0}},Bt.createElement("div",{className:"horizontal space-between"},Bt.createElement("div",{className:"sm-label-right"},"Certificate"),this.certificateTypes.length>1&&Bt.createElement("select",{style:{width:"45px",marginLeft:"10px"},className:"form-control input-sm",value:e.sslCertificateType,onChange:t=>this.listenerCertificateTypeChanged(e,t.target.value)},this.certificateTypes.map((e=>Bt.createElement("option",{key:e},e)))),this.renderCertificateSelector(e)))))))),Bt.createElement("tfoot",null,Bt.createElement("tr",null,Bt.createElement("td",{colSpan:5},Bt.createElement("button",{className:"add-new col-md-12",onClick:this.addListener,type:"button"},Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"}),Bt.createElement("span",null," Add new port mapping")))))))))}}const Fr=class extends Bt.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Rt(e);if(a)this.formatListeners(s).then((()=>{n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ge.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}},this.validate=e=>({});const t=e.command?e.command:e.loadBalancer?Pr.convertClassicLoadBalancerForEditing(e.loadBalancer):Pr.constructNewClassicLoadBalancerTemplate(e.app);this.state={isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(Fr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{a.sslCertificateId=this.certificateIdAsARN(t.accountId,a.sslCertificateName,e.region,a.sslCertificateType||this.certificateTypes[0])}))}))}clearSecurityGroupsIfNotInVpc(e){e.vpcId||e.subnetType||(e.securityGroups=null)}addHealthCheckToCommand(e){let t=null;const a=e.healthCheckProtocol||"";t=a.startsWith("HTTP")?`${a}:${e.healthCheckPort}${e.healthCheckPath}`:`${a}:${e.healthCheckPort}`,e.healthCheck=t}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}formatCommand(e){this.setAvailabilityZones(e),this.clearSecurityGroupsIfNotInVpc(e),this.addHealthCheckToCommand(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state,l=r||a;let o=a?"Configure Classic Load Balancer":"Create New Classic Load Balancer";return r||(o=`Edit ${i.name}: ${i.region}: ${i.credentials}`),Bt.createElement(w,{heading:o,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",validate:this.validate,render:({formik:t,nextIdx:i,wizard:s})=>Bt.createElement(Bt.Fragment,null,l&&Bt.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>Bt.createElement(xr,{app:e,formik:t,isNew:r,forPipelineConfig:a,loadBalancer:n,ref:i})}),!!t.values.vpcId&&Bt.createElement(E,{label:U.get("Firewall"),wizard:s,order:i(),render:({innerRef:e,onLoadingChanged:a})=>Bt.createElement(Ar,{formik:t,isNew:r,onLoadingChanged:a,ref:e})}),Bt.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:a})=>Bt.createElement(Mr,{ref:a,formik:t,app:e})}),Bt.createElement(E,{label:"Health Check",wizard:s,order:i(),render:({innerRef:e})=>Bt.createElement($r,{ref:e,formik:t})}),Bt.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>Bt.createElement(Dr,{ref:e,formik:t})}))})}};let Lr=Fr;Lr.defaultProps={closeModal:C,dismissModal:C};const Rr=Bt.forwardRef(((e,t)=>Bt.createElement("div",{ref:t},Bt.createElement(s,{name:"deletionProtection",label:"Protection",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.deletionProtection"}),input:e=>Bt.createElement(d,{...e,text:"Enable deletion protection"})}),Bt.createElement(s,{name:"loadBalancingCrossZone",label:"Cross-Zone Load Balancing",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.loadBalancingCrossZone"}),input:e=>Bt.createElement(d,{...e,text:"Distribute traffic across zones"})}),e.showDualstack&&Bt.createElement(s,{name:"dualstack",label:"Dualstack",help:Bt.createElement(n,{id:"loadBalancer.advancedSettings.nlbIpAddressType"}),input:e=>Bt.createElement(d,{...e,text:"Assign Ipv4 and IPv6"})}))));function Or({availableCertificates:e,certificates:t,formik:a,app:n,certificateTypes:r}){function i(){a.setFieldValue("listeners",a.values.listeners)}function s(e,t){e.name=t,i()}function l(e){return"iam"===e.type&&t&&Object.keys(t).length>0}const{values:o}=a;return Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Certificate"),Bt.createElement("div",{className:"wizard-pod-row-contents"},e.map(((e,a)=>Bt.createElement("div",{key:a,style:{width:"100%",display:"flex",flexDirection:"row"}},Bt.createElement("select",{className:"form-control input-sm inline-number",style:{width:"45px"},value:e.type,onChange:t=>function(e,t){e.type=t,i()}(e,t.target.value)},r.map((e=>Bt.createElement("option",{key:e},e)))),l(e)&&Bt.createElement(hr,{certificates:t,accountName:o.credentials,currentValue:e.name,app:n,onCertificateSelect:t=>s(e,t)}),!l(e)&&Bt.createElement("input",{className:"form-control input-sm no-spel",style:{display:"inline-block"},type:"text",value:e.name,onChange:t=>s(e,t.target.value),required:!0}))))))}class Ur extends Bt.Component{constructor(e){super(e),this.protocols=["TCP","UDP","TLS"],this.removedAuthActions=new Map,this.addListener=()=>{this.props.formik.values.listeners.push({certificates:[],protocol:"TCP",port:80,defaultActions:[{type:"forward",targetGroupName:""}],rules:[]}),this.updateListeners()},this.handleDefaultTargetChanged=(e,t)=>{e.defaultActions[0].targetGroupName=t,this.updateListeners()},this.state={certificates:[],certificateTypes:Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),oidcConfigs:void 0}}getAllTargetGroupsFromListeners(e){const t=Ot(e.map((e=>e.defaultActions))),a=Ot(e.map((e=>e.rules)));return t.push(...Ot(a.map((e=>e.actions)))),_t(t.map((e=>e.targetGroupName)))}validate(e){const t={},a=e.targetGroups.map((e=>e.name)),n=this.getAllTargetGroupsFromListeners(e.listeners),r=Kt(a,n);1===r.length?t.listeners=`Target group ${r[0]} is unused.`:r.length>1&&(t.listeners=`Target groups ${r.join(", ")} are unused.`);const{listeners:i}=e;return Lt(i,"port").length<i.length&&(t.listenerPorts="Multiple listeners cannot use the same port."),t}updateListeners(){this.props.formik.setFieldValue("listeners",this.props.formik.values.listeners)}componentDidMount(){this.loadCertificates()}addListenerCertificate(e){e.certificates=e.certificates||[],e.certificates.push({certificateArn:void 0,type:"iam",name:void 0})}loadCertificates(){ur.listCertificates().then((e=>{this.setState({certificates:e})}))}listenerProtocolChanged(e,t){e.protocol=t,"TCP"===e.protocol?e.port=80:"UDP"===e.protocol?e.port=53:"TLS"===e.protocol&&(e.port=443,e.certificates&&0!==e.certificates.length||this.addListenerCertificate(e),this.reenableAuthActions(e)),this.updateListeners()}reenableAuthActions(e){const t=this.removedAuthActions.has(e)?this.removedAuthActions.get(e):[],a=t[-1];a&&(t[-1]=void 0,e.defaultActions.unshift({...a})),e.rules.forEach(((e,a)=>{const n=t[a];t[a]=void 0,n&&e.actions.unshift({...n})}))}listenerPortChanged(e,t){e.port=Number.parseInt(t,10),this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}render(){const{errors:e,values:t}=this.props.formik,{certificates:a,certificateTypes:n}=this.state;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},t.listeners.map(((e,r)=>Bt.createElement("div",{key:r,className:"wizard-pod"},Bt.createElement("div",null,Bt.createElement("div",{className:"wizard-pod-row header"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Listen On"),Bt.createElement("div",{className:"wizard-pod-row-contents spread"},Bt.createElement("div",null,Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol"),Bt.createElement("select",{className:"form-control input-sm inline-number",style:{width:"80px"},value:e.protocol,onChange:t=>this.listenerProtocolChanged(e,t.target.value)},this.protocols.map((e=>Bt.createElement("option",{key:e},e))))),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port"),Bt.createElement("input",{className:"form-control input-sm inline-number",type:"text",min:0,value:e.port||"",onChange:t=>this.listenerPortChanged(e,t.target.value),style:{width:"80px"},required:!0}))),Bt.createElement("div",null,Bt.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(r)},Bt.createElement("span",{className:"glyphicon glyphicon-trash"}))))),Bt.createElement("div",null,"TLS"===e.protocol&&Bt.createElement(Or,{availableCertificates:e.certificates,formik:this.props.formik,app:this.props.app,certificateTypes:n,certificates:a})),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title",style:{height:"30px"}},"Rules"),Bt.createElement("div",{className:"wizard-pod-row-contents",style:{padding:"0"}},Bt.createElement("table",{className:"table table-condensed packed rules-table"},Bt.createElement("thead",null,Bt.createElement("tr",null,Bt.createElement("th",{style:{width:"10px",padding:"0"}}),Bt.createElement("th",{style:{width:"226px"}},"If"),Bt.createElement("th",{style:{width:"75px"}},"Then"),Bt.createElement("th",null,"Target"),Bt.createElement("th",{style:{width:"30px"}}))),Bt.createElement("tbody",null,Bt.createElement("tr",{className:"not-sortable"},Bt.createElement("td",null),Bt.createElement("td",null,"Default"),Bt.createElement("td",null,"forward to"),Bt.createElement("td",null,Bt.createElement("select",{className:"form-control input-sm",value:e.defaultActions[0].targetGroupName,onChange:t=>this.handleDefaultTargetChanged(e,t.target.value),required:!0},Bt.createElement("option",{value:""}),_t(t.targetGroups.map((e=>e.name))).map((e=>Bt.createElement("option",{key:e},e))))),Bt.createElement("td",null)))))))))),e.listenerPorts&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:e.listenerPorts})),e.listeners&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:e.listeners})),Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("tbody",null,Bt.createElement("tr",null,Bt.createElement("td",null,Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addListener},Bt.createElement("span",null,Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new listener")))))))))}}class Vr extends Bt.Component{constructor(e){super(e),this.protocols=["TCP","UDP"],this.healthProtocols=["TCP","HTTP","HTTPS"],this.targetTypes=["instance","ip"],this.destroy$=new fa,this.addTargetGroup=()=>{const{setFieldValue:e,values:t}=this.props.formik,a=t.targetGroups.length;t.targetGroups.push({name:"targetgroup"+(a?`${a}`:""),protocol:"TCP",port:7001,targetType:"instance",healthCheckProtocol:"TCP",healthCheckPort:"traffic-port",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:10,attributes:{deregistrationDelay:300,preserveClientIp:!0}}),e("targetGroups",t.targetGroups)};const t=e.isNew?0:e.formik.initialValues.targetGroups.length;this.state={existingTargetGroupNames:{},oldTargetGroupCount:t}}validate(e){const t=_t(Ot(Qt(Wt(e.targetGroups,"name"),(e=>e.length>1))).map((e=>e.name))),a=new i(e),{arrayForEach:n}=a;return a.field("targetGroups").withValidators(n((a=>{a.field("name","Name").required().withValidators(kr(this.state.existingTargetGroupNames,e.credentials,e.region),Sr(this.props.app.name.length),ue.valueUnique(t,"There is already a target group in this load balancer with the same name.")),a.field("port","Port").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckInterval","Health Check Interval").required().spelAware().withValidators((e=>me(e))),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckPort","Health Check Port").required().spelAware().withValidators((e=>"traffic-port"===e?null:me(e))),a.field("protocol","Protocol").required(),a.field("healthCheckProtocol","Health Check Protocol").required()}))),a.validateForm()}removeAppName(e){return e.replace(`${this.props.app.name}-`,"")}updateLoadBalancerNames(e){const{app:t,loadBalancer:a}=e,n={};va(t.getDataSource("loadBalancers").refresh(!0)).pipe(Ta(this.destroy$)).subscribe((()=>{t.getDataSource("loadBalancers").data.forEach((e=>{"classic"!==e.loadBalancerType&&(a&&e.name===a.name||e.targetGroups.forEach((t=>{n[e.account]=n[e.account]||{},n[e.account][e.region]=n[e.account][e.region]||[],n[e.account][e.region].push(this.removeAppName(t.name))})))})),this.setState({existingTargetGroupNames:n},(()=>this.props.formik.validateForm()))}))}targetGroupFieldChanged(e,t,a){const{setFieldValue:n,values:r}=this.props.formik,i=r.targetGroups[e];Jt(i,t,a),"healthyThreshold"===t&&Jt(i,"unhealthyThreshold",a),n("targetGroups",r.targetGroups)}removeTargetGroup(e){const{setFieldValue:t,values:a}=this.props.formik,{oldTargetGroupCount:n}=this.state;a.targetGroups.splice(e,1),e<n&&this.setState({oldTargetGroupCount:n-1}),t("targetGroups",a.targetGroups)}componentDidMount(){this.updateLoadBalancerNames(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{oldTargetGroupCount:r}=this.state,i=this.protocols.map((e=>Bt.createElement("option",{key:e},e))),s=this.healthProtocols.map((e=>Bt.createElement("option",{key:e},e))),l=this.targetTypes.map((e=>Bt.createElement("option",{key:e},e)));return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},a.targetGroups.map(((a,o)=>{const c=t.targetGroups&&t.targetGroups[o]||{};return Bt.createElement("div",{key:o,className:"wizard-pod"},Bt.createElement("div",null,Bt.createElement("div",{className:"wizard-pod-row header"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Group Name"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"group-name-prefix"},e.name,"-"),Bt.createElement("input",{className:"form-control input-sm target-group-name",type:"text",value:a.name,onChange:e=>this.targetGroupFieldChanged(o,"name",e.target.value),required:!0,disabled:o<r}),Bt.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeTargetGroup(o)},Bt.createElement("span",{className:"glyphicon glyphicon-trash"}))),c.name&&Bt.createElement("div",{className:"wizard-pod-row-errors"},Bt.createElement(de,{type:"error",message:c.name})))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},Bt.createElement(n,{id:"aws.targetGroup.targetType"})," ",Bt.createElement("span",null,"Target Type ")),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("select",{className:"form-control input-sm",value:a.targetType,onChange:e=>this.targetGroupFieldChanged(o,"targetType",e.target.value),disabled:o<r},l))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Backend Connection"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol "),Bt.createElement(n,{id:"aws.targetGroup.protocol"})," ",Bt.createElement("select",{className:"form-control input-sm inline-number",value:a.protocol,onChange:e=>this.targetGroupFieldChanged(o,"protocol",e.target.value),disabled:o<r},i)),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port "),Bt.createElement(n,{id:"aws.targetGroup.port"})," ",Bt.createElement("input",{className:"form-control input-sm inline-number",value:a.port,onChange:e=>this.targetGroupFieldChanged(o,"port",e.target.value),type:"text",required:!0,disabled:o<r}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Protocol "),Bt.createElement("select",{disabled:o<r,className:"form-control input-sm inline-number",value:a.healthCheckProtocol,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckProtocol",e.target.value)},s)),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Port "),Bt.createElement(ge,{className:"form-control input-sm inline-number",error:c.healthCheckPort,name:"healthCheckPort",required:!0,value:a.healthCheckPort,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckPort",e.target.value)})),"TCP"!==a.healthCheckProtocol&&Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Path "),Bt.createElement(ge,{className:"form-control input-sm inline-text",error:c.healthCheckPath,name:"healthCheckPath",required:!0,value:a.healthCheckPath,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckPath",e.target.value)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Timeout "),Bt.createElement(he,{error:c.healthCheckTimeout,required:!0,value:a.healthCheckTimeout,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckTimeout",e)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Interval "),Bt.createElement(he,{error:c.healthCheckInterval,required:!0,value:a.healthCheckInterval,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckInterval",e)}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},Bt.createElement(n,{id:"aws.targetGroup.nlbHealthcheckThreshold"})," ",Bt.createElement("span",null,"Healthcheck Threshold ")),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement(he,{error:c.healthyThreshold,value:a.healthyThreshold,onChange:e=>this.targetGroupFieldChanged(o,"healthyThreshold",e)}))))),Bt.createElement("div",{className:"wizard-pod-row"},Bt.createElement("div",{className:"wizard-pod-row-title"},"Attributes"),Bt.createElement("div",{className:"wizard-pod-row-contents"},Bt.createElement("div",{className:"wizard-pod-row-data"},Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement("label",null,"Dereg. Delay"),Bt.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelay"})," ",Bt.createElement("input",{className:"form-control input-sm inline-number",type:"text",value:a.attributes.deregistrationDelay,onChange:e=>this.targetGroupFieldChanged(o,"attributes.deregistrationDelay",e.target.value)})),Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement(d,{name:"deregistrationDelayConnectionTermination",text:"Connection Termination",checked:a.attributes.deregistrationDelayConnectionTermination,onChange:e=>{this.targetGroupFieldChanged(o,"attributes.deregistrationDelayConnectionTermination",e.target.checked)}}),Bt.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelayConnectionTermination"})),"instance"!==a.targetType&&Bt.createElement("span",{className:"wizard-pod-content"},Bt.createElement(d,{name:"preserveClientIp",text:"Preserve Client IP",checked:a.attributes.preserveClientIp,onChange:e=>{this.targetGroupFieldChanged(o,"attributes.preserveClientIp",e.target.checked)}}),Bt.createElement(n,{id:"aws.targetGroup.attributes.preserveClientIp"})))))))})),Bt.createElement("table",{className:"table table-condensed packed"},Bt.createElement("tbody",null,Bt.createElement("tr",null,Bt.createElement("td",null,Bt.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addTargetGroup},Bt.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new target group"))))))))}}const jr=class extends Bt.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Zt(gn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Rt(e);if(s.ipAddressType=s.dualstack?"dualstack":"ipv4",delete s.dualstack,a)this.formatListeners(s).then((()=>{n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ge.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}},this.validate=()=>({});const t=e.loadBalancer?Pr.convertNetworkLoadBalancerForEditing(e.loadBalancer):Pr.constructNewNetworkLoadBalancerTemplate(e.app);this.state={isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(jr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{"TCP"===a.protocol&&(delete a.sslPolicy,a.certificates=[]),a.certificates.forEach((a=>{a.certificateArn=this.certificateIdAsARN(t.accountId,a.name,e.region,a.type||this.certificateTypes[0])}))}))}))}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}addAppName(e){return`${this.props.app.name}-${e}`}manageTargetGroupNames(e){(e.targetGroups||[]).forEach((e=>{e.name=this.addAppName(e.name)})),(e.listeners||[]).forEach((e=>{e.defaultActions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))})),(e.rules||[]).forEach((e=>{e.actions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))}))}))}))}manageRules(e){e.listeners.forEach((e=>{e.rules.forEach(((e,t)=>{e.priority=t+1,e.conditions=e.conditions.filter((e=>e.values[0].length>0))}))}))}formatCommand(e){this.setAvailabilityZones(e),this.manageTargetGroupNames(e),this.manageRules(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Network Load Balancer":"Create New Network Load Balancer";r||(l=`Edit ${i.name}: ${i.region}: ${i.credentials}`);const o=r||a;return Bt.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",validate:this.validate,render:({formik:t,nextIdx:i,wizard:s})=>Bt.createElement(Bt.Fragment,null,o&&Bt.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>Bt.createElement(xr,{app:e,forPipelineConfig:a,formik:t,isNew:r,loadBalancer:n,ref:i})}),Bt.createElement(E,{label:"Target Groups",wizard:s,order:i(),render:({innerRef:a})=>Bt.createElement(Vr,{ref:a,formik:t,app:e,isNew:r,loadBalancer:n})}),Bt.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:e})=>Bt.createElement(Ur,{ref:e,formik:t})}),Bt.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>Bt.createElement(Rr,{ref:e,showDualstack:!t.values.isInternal&&na(t.values.targetGroups,{targetType:"instance"})})}))})}};let qr=jr;qr.defaultProps={closeModal:C,dismissModal:C};const Hr=[{type:"application",label:"Application",sublabel:"ALB",description:"Highly configurable, application-focused balancer. HTTP and HTTPS only.",component:Br},{type:"network",label:"Network",sublabel:"NLB",description:"Basic, high-performance balancer with fixed IP.",component:qr},{type:"classic",label:"Classic",sublabel:"Legacy",description:"Previous generation balancer (ELB).",component:Lr}],Wr=class extends Bt.Component{constructor(e){super(e),this.choose=()=>{const{children:e,...t}=this.props;this.close(),this.state.selectedChoice.component.show(t).then((e=>{this.props.closeModal(e)})).catch((()=>{}))},this.close=e=>{this.props.dismissModal(e)},this.state={choices:Hr,selectedChoice:Hr[0]}}static show(e){return b.show(Wr,{...e,className:"create-pipeline-modal-overflow-visible modal-lg"},{bsSize:"lg"})}choiceSelected(e){this.setState({selectedChoice:e})}getIncompatibility(e,t){const{loadBalancer:a={}}=O.getProvider(t),{incompatibleLoadBalancerTypes:n=[]}=a;return n.find((t=>t.type===e.type))}isIncompatibleWithAllProviders(e){const{app:{attributes:t}}=this.props,{cloudProviders:a=[]}=t;return a.length>0&&a.every((t=>!!this.getIncompatibility(e,t)))}render(){const{app:{attributes:e}}=this.props,{cloudProviders:t=[]}=e,{choices:a,selectedChoice:n}=this.state,r=a.filter((e=>!this.isIncompatibleWithAllProviders(e))),i=t.map((e=>this.getIncompatibility(n,e))).filter((e=>e)),s=gn.createLoadBalancerWarnings&&gn.createLoadBalancerWarnings[n.type];return Bt.createElement(Bt.Fragment,null,Bt.createElement(re,{dismiss:this.close}),Bt.createElement(Da.Header,null,Bt.createElement(Da.Title,null,"Select Type of Load Balancer")),Bt.createElement(Da.Body,null,Bt.createElement("div",{className:"modal-body"},Bt.createElement("div",{className:"card-choices"},r.map((e=>Bt.createElement("div",{key:e.type,className:"card "+(n===e?"active":""),onClick:()=>this.choiceSelected(e)},Bt.createElement("h3",{className:"load-balancer-label"},e.label),Bt.createElement("h3",null,"(",e.sublabel,")"),Bt.createElement("div",null,e.description))))),Bt.createElement(Bt.Fragment,null,i.length>0&&i.map((e=>Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"})," ",e.reason))))),!!s&&Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"}),Bt.createElement(we,{message:s,style:{display:"inline-block",marginLeft:"2px"}}))),Bt.createElement("div",{className:"load-balancer-description"}))),Bt.createElement(Da.Footer,null,Bt.createElement($a,{onClick:this.choose},"Configure Load Balancer ",Bt.createElement("span",{className:"glyphicon glyphicon-chevron-right"}))))}};let Zr=Wr;Zr.defaultProps={closeModal:C,dismissModal:C};class _r extends Bt.Component{constructor(e){super(e),this.editLoadBalancer=()=>{const{loadBalancer:e}=this.props,{application:t}=this.state;Hr.find((t=>t.type===e.loadBalancerType)).component.show({app:t,loadBalancer:e})},this.deleteLoadBalancer=()=>{const{app:e,loadBalancer:t,loadBalancerFromParams:a}=this.props;if(t.instances&&t.instances.length)return;const n={application:e,title:"Deleting "+a.name},r={cloudProvider:t.cloudProvider,loadBalancerName:t.name,loadBalancerType:t.loadBalancerType||"classic",regions:[t.region],credentials:t.account,vpcId:Zt(t,"elb.vpcId",null)};k.confirm({header:`Really delete ${a.name} in ${a.region}: ${a.accountId}?`,buttonText:`Delete ${a.name}`,account:a.accountId,taskMonitorConfig:n,submitMethod:()=>Ge.deleteLoadBalancer(r,e)})},this.entityTagUpdate=()=>{this.props.app.loadBalancers.refresh()};const{app:t,loadBalancer:a}=this.props;let n;const r=a.name.split("-")[0];r===t.name?n=t:S.getApplication(r).then((e=>{this.setState({application:e})})).catch((()=>{})),this.state={application:n}}render(){const{app:e,loadBalancer:t}=this.props,{application:r}=this.state,{loadBalancerType:i,instances:s,instanceCounts:l}=t,o=t.name.split("-")[0],c=!("classic"===i&&ra(l).filter((e=>e)).length)&&!s.length;return Bt.createElement("div",{style:{display:"inline-block"}},Bt.createElement(Ba,{className:"dropdown",id:"load-balancer-actions-dropdown"},Bt.createElement(Ba.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},Bt.createElement("span",null,"Load Balancer Actions")),Bt.createElement(Ba.Menu,{className:"dropdown-menu"},r&&Bt.createElement(Ne,{resource:t,application:e,onClick:this.editLoadBalancer},"Edit Load Balancer"),!r&&Bt.createElement("li",{className:"disabled"},Bt.createElement("a",null,"Edit Load Balancer"," ",Bt.createElement(n,{content:`The application <b>${o}</b> must be configured before this load balancer can be edited.`}))),c&&Bt.createElement(Ne,{resource:t,application:e,onClick:this.deleteLoadBalancer},"Delete Load Balancer"),!c&&Bt.createElement("li",{className:"disabled"},Bt.createElement("a",null,"Delete Load Balancer"," ",Bt.createElement(n,{content:"You must detach all instances before you can delete this load balancer."}))),a&&a.feature.entityTags&&Bt.createElement(G,{component:t,application:e,entityType:"loadBalancer",onUpdate:this.entityTagUpdate}))))}}const Kr="spinnaker.amazon.loadBalancer.details.loadBalancerActions.component";t(Kr,[]).component("loadBalancerActions",Va(F(_r,"loadBalancerActions"),["app","loadBalancer","loadBalancerFromParams"]));class Yr{constructor(e,t,n,r,i,s,l){this.$scope=e,this.$state=t,this.$q=n,this.app=i,this.securityGroupReader=s,this.loadBalancerReader=l,this.state={loading:!0},this.firewallsLabel=U.get("Firewalls"),this.oidcConfigPath=a.oidcConfigPath,this.application=i,this.loadBalancerFromParams=r,this.app.ready().then((()=>this.extractLoadBalancer())).then((()=>{e.$$destroyed||i.getDataSource("loadBalancers").onRefresh(e,(()=>this.extractLoadBalancer()))}))}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}extractLoadBalancer(){const e=this.app.loadBalancers.data.find((e=>e.name===this.loadBalancerFromParams.name&&e.region===this.loadBalancerFromParams.region&&e.account===this.loadBalancerFromParams.accountId));if(e){return this.loadBalancerReader.getLoadBalancerDetails("aws",this.loadBalancerFromParams.accountId,this.loadBalancerFromParams.region,this.loadBalancerFromParams.name).then((t=>{this.loadBalancer=e,this.state.loading=!1;const a=[];if(t.length){this.loadBalancer.elb=t[0],this.loadBalancer.elb.vpcId=this.loadBalancer.elb.vpcId||this.loadBalancer.elb.vpcid,this.loadBalancer.account=this.loadBalancerFromParams.accountId;const e=t[0];if("application"===e.loadBalancerType||"network"===e.loadBalancerType){const e=t[0];e.listeners&&e.listeners.length&&(this.elbProtocol="http:",e.listeners.some((e=>"HTTPS"===e.protocol))&&(this.elbProtocol="https:"),this.listeners=[],e.listeners.forEach((e=>{e.defaultActions.sort(((e,t)=>e.order-t.order)),e.rules.forEach((e=>e.actions.sort(((e,t)=>e.order-t.order))))})),e.listeners.forEach((e=>{e.rules.map((t=>{let a=[e.protocol,(t.conditions.find((e=>"host-header"===e.field))||{values:[""]}).values[0],e.port].filter((e=>e)).join(":");const n=(t.conditions.find((e=>"path-pattern"===e.field))||{values:[]}).values[0];n&&(a=`${a}${n}`);const r=t.actions.map((e=>{const t={...e};return"forward"===t.type&&(t.targetGroup=this.loadBalancer.targetGroups.find((e=>e.name===t.targetGroupName))),t}));this.listeners.push({in:a,actions:r})}))}))),"dualstack"===e.ipAddressType&&(this.ipAddressTypeDescription="IPv4 and IPv6"),"ipv4"===e.ipAddressType&&(this.ipAddressTypeDescription="IPv4")}else{const e=t[0];e.listenerDescriptions&&(this.elbProtocol="http:",e.listenerDescriptions.some((e=>"HTTPS"===e.listener.protocol))&&(this.elbProtocol="https:"))}(this.loadBalancer.elb.securityGroups||[]).forEach((e=>{const t=this.securityGroupReader.getApplicationSecurityGroup(this.app,this.loadBalancerFromParams.accountId,this.loadBalancerFromParams.region,e);t&&a.push(t)})),this.securityGroups=qt(a,"name"),this.loadBalancer.subnets&&(this.loadBalancer.subnetDetails=this.loadBalancer.subnets.reduce(((e,t)=>(g.getSubnetByIdAndProvider(t,this.loadBalancer.provider).then((t=>{e.push(t)})),e)),[]))}}),(()=>this.autoClose()))}return this.autoClose(),this.loadBalancer||this.autoClose(),this.$q.when(null)}getFirstSubnetPurpose(e=[]){return ia(e.map((e=>e.purpose)))||""}}Yr.$inject=["$scope","$state","$q","loadBalancer","app","securityGroupReader","loadBalancerReader"];t("spinnaker.amazon.loadBalancer.details.controller",[Wa,Te,Kr,Ie,xe]).controller("awsLoadBalancerDetailsCtrl",Yr);class Xr{constructor(e,t,a,n,r){this.$scope=e,this.$q=t,this.$state=a,this.app=r,this.state={loading:!0},this.application=r,this.targetGroupFromParams=n,this.app.ready().then((()=>this.extractTargetGroup())).then((()=>{e.$$destroyed||r.getDataSource("loadBalancers").onRefresh(e,(()=>this.extractTargetGroup()))}))}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}extractTargetGroup(){const{loadBalancerName:e,region:t,accountId:a,name:n}=this.targetGroupFromParams,r=this.app.loadBalancers.data.find((n=>n.name===e&&n.region===t&&n.account===a));if(!r)return this.autoClose(),this.$q.when(null);const i=r.targetGroups.find((e=>e.name===n));return i?(this.targetGroup=i,this.loadBalancer=r,this.state.loading=!1,this.elbProtocol="http:",this.loadBalancer.listeners&&this.loadBalancer.listeners.some((e=>"HTTPS"===e.protocol))&&(this.elbProtocol="https:"),this.$q.when(null)):(this.autoClose(),this.$q.when(null))}}Xr.$inject=["$scope","$q","$state","targetGroup","app"];t("spinnaker.amazon.loadBalancer.details.targetGroupDetails.controller",[Wa,xe]).controller("awsTargetGroupDetailsCtrl",Xr);var Qr=Object.defineProperty,Jr=Object.getOwnPropertyDescriptor;let ei=class extends Bt.Component{render(){return Bt.createElement("h3",null,"Target Group Details")}};ei=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?Jr(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Qr(t,a,i),i})([ce("loadBalancer.targetGroupDetails")],ei);t("spinnaker.amazon.loadBalancer.targetGroup.states",[Ae]).config(["applicationStateProvider",e=>{const t={name:"targetGroupDetails",url:"/targetGroupDetails/:provider/:accountId/:region/:vpcId/:loadBalancerName/:name",params:{vpcId:{value:null,squash:!0}},views:{"detail@../insight":{component:ei,$type:"react"}},resolve:{accountId:["$stateParams",e=>e.accountId],targetGroup:["$stateParams",e=>({loadBalancerName:e.loadBalancerName,name:e.name,accountId:e.accountId,region:e.region,vpcId:e.vpcId})]},data:{pageTitleDetails:{title:"Target Group Details",nameParam:"name",accountParam:"accountId",regionParam:"region"}}};e.addInsightDetailState(t)}]);t("spinnaker.amazon.loadBalancer",["spinnaker.amazon.loadBalancer.details.controller","spinnaker.amazon.loadBalancer.details.targetGroupDetails.controller",Kr,"spinnaker.amazon.loadBalancer.targetGroup.states"]);t("spinnaker.amazon.pipeline.stage.bake.executionDetails.controller",[Wa]).controller("awsBakeExecutionDetailsCtrl",["$scope","$stateParams","executionDetailsSectionService","$interpolate",function(e,t,n,r){e.configSections=["bakeConfig","taskStatus"];const i=()=>{e.detailsSection=t.details,e.provider=e.stage.context.cloudProviderType||"aws",e.roscoMode=a.feature.roscoMode||"function"==typeof a.feature.roscoSelector&&a.feature.roscoSelector(e.stage.context),e.bakeryDetailUrl=r(e.roscoMode&&a.roscoDetailUrl?a.roscoDetailUrl:a.bakeryDetailUrl),e.bakeFailedNoError="FAILURE"===Zt(e.stage,"context.status.result")&&!e.stage.failureMessage},s=()=>n.synchronizeSection(e.configSections,i);s(),e.$on("$stateChangeSuccess",s)}]);t("spinnaker.amazon.pipeline.stage.bakeStage",["spinnaker.amazon.pipeline.stage.bake.executionDetails.controller"]).config((function(){Pe.pipeline.registerStage({provides:"bake",cloudProvider:"aws",label:"Bake",description:"Bakes an image",templateUrl:"amazon/src/pipeline/stages/bake/bakeStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/bake/bakeExecutionDetails.html",executionLabelComponent:ze,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("awsBakeStageCtrl",["$scope","$q","$uibModal",function(e,t,n){function r(){if(e.baseOsOptions.length&&e.baseOsOptions.every((({vmTypes:e})=>e))){const t=e.baseOsOptions.length&&new Set(e.baseOsOptions.reduce(((e,{vmTypes:t})=>e.concat(t)),[])),a=e.baseOsOptions.find((({id:t})=>t===e.stage.baseOs));e.viewState.showVmTypeSelector=t.size>1,e.vmTypes=a.vmTypes}else e.viewState.showVmTypeSelector=!0,e.vmTypes=["hvm","pv"]}e.stage.extendedAttributes=e.stage.extendedAttributes||{},e.stage.regions=e.stage.regions&&e.stage.regions.sort()||[],e.stage.user||(e.stage.user=Be.getAuthenticatedUser().name),e.viewState={loading:!0,roscoMode:a.feature.roscoMode||"function"==typeof a.feature.roscoSelector&&a.feature.roscoSelector(e.stage),minRootVolumeSize:gn.minRootVolumeSize,showVmTypeSelector:!0,bakeWarning:gn.bakeWarning,dockerBakeWarning:gn.dockerBakeWarning,showDockerPreview:gn.dockerBakeryDeprecated&&"docker"===e.stage.storeType,showMigrationFields:"Started"!==e.pipeline.migrationStatus,showStoreType:!gn.dockerBakeryDeprecated},this.addExtendedAttribute=function(){e.stage.extendedAttributes||(e.stage.extendedAttributes={}),n.open({templateUrl:De.addExtendedAttributes,controller:"bakeStageAddExtendedAttributeController",controllerAs:"addExtendedAttribute",resolve:{extendedAttribute:function(){return{key:"",value:""}}}}).result.then((function(t){e.stage.extendedAttributes[t.key]=t.value})).catch((()=>{}))},this.removeExtendedAttribute=function(t){delete e.stage.extendedAttributes[t]},this.showTemplateFileName=function(){return e.viewState.roscoMode||e.stage.templateFileName},this.showExtendedAttributes=function(){return e.viewState.roscoMode||e.stage.extendedAttributes&&$t.size(e.stage.extendedAttributes)>0},this.showVarFileName=function(){return e.viewState.roscoMode||e.stage.varFileName},this.handleBaseOsChange=function(){r(),e.vmTypes&&e.vmTypes.length&&!e.vmTypes.includes(e.stage.vmType)&&(e.stage.vmType=e.vmTypes[0])},e.$watch("stage",(function(){$t.forOwn(e.stage,(function(t,a){""===t&&delete e.stage[a]})),"ebs"===e.stage.storeType&&"aws"!==e.stage.cloudProviderType&&(e.stage.cloudProviderType="aws"),"function"==typeof a.feature.roscoSelector&&(e.viewState.roscoMode=a.feature.roscoSelector(e.stage))}),!0),t.all([$e.getRegions("aws"),$e.getBaseOsOptions("aws"),$e.getBaseLabelOptions(),["ebs","docker"]]).then((function([t,a,n,i]){e.regions=[...t].sort(),e.storeTypes=i,!e.stage.storeType&&e.storeTypes&&e.storeTypes.length&&(e.stage.storeType=e.storeTypes[0]),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.aws&&e.stage.regions.push(...Object.keys(e.application.defaultRegions.aws).sort()),e.baseOsOptions=a.baseImages,e.baseLabelOptions=n,!e.stage.baseOs&&e.baseOsOptions&&e.baseOsOptions.length?e.stage.baseOs=e.baseOsOptions[0].id:e.stage.baseOs&&!(e.baseOsOptions||[]).find((t=>t.id===e.stage.baseOs))&&e.baseOsOptions.push({id:e.stage.baseOs,detailedDescription:"Custom",vmTypes:["hvm","pv"]}),!e.stage.baseLabel&&e.baseLabelOptions&&e.baseLabelOptions.length&&(e.stage.baseLabel=e.baseLabelOptions[0]),r(),!e.stage.vmType&&e.vmTypes&&e.vmTypes.length&&(e.stage.vmType=e.vmTypes[0]),e.showAdvancedOptions=function(){const t=e.stage;return!!(t.templateFileName||t.extendedAttributes&&$t.size(t.extendedAttributes)>0||t.varFileName||t.baseName||t.baseAmi||t.amiName||t.amiSuffix||t.rootVolumeSize)}(),e.viewState.loading=!1}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/bake/bakeStage.html",'<div ng-controller="awsBakeStageCtrl 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 && viewState.showDockerPreview">\n <div ng-if="viewState.dockerBakeWarning" class="alert alert-warning sp-margin-s-top horizontal middle">\n <i class="fa fa-exclamation-triangle"></i>\n <div class="sp-margin-s-left">\n <markdown message="viewState.dockerBakeWarning"></markdown>\n </div>\n </div>\n <div>\n <div class="alert alert-info horizontal middle">\n <i class="fa fa-info-circle"></i>\n <div class="sp-margin-s-left">\n <markdown\n message="\'To edit bake configuration or view advanced options, migrate to EBS store type.\'"\n ></markdown>\n </div>\n </div>\n <stage-config-field label="Store Type" ng-if="!viewState.roscoMode && viewState.showMigrationFields">\n <label class="radio-inline" ng-repeat="storeType in storeTypes">\n <input type="radio" ng-model="stage.storeType" ng-value="storeType" />\n {{storeType | uppercase}}\n </label>\n </stage-config-field>\n <stage-config-field label="Regions">\n <span class="sp-margin-xs-right" ng-repeat="region in stage.regions">{{region}}</span>\n </stage-config-field>\n <stage-config-field label="Skip Region Detection">{{!!stage.skipRegionDetection}}</stage-config-field>\n <stage-config-field label="Repo Path">{{stage.package}}</stage-config-field>\n <stage-config-field label="Base OS">{{stage.baseOs}}</stage-config-field>\n <stage-config-field label="VM Type">{{stage.vmType}}</stage-config-field>\n <stage-config-field label="Store Type">{{stage.storeType}}</stage-config-field>\n <stage-config-field label="Base Label">{{stage.baseLabel}}</stage-config-field>\n </div>\n </div>\n <div ng-if="!viewState.loading && !viewState.showDockerPreview">\n <div\n ng-if="pipeline.migrationStatus === \'Started\' && viewState.bakeWarning"\n class="alert alert-warning sp-margin-s-top horizontal middle"\n >\n <i class="fa fa-exclamation-triangle"></i>\n <div class="sp-margin-s-left">\n <markdown message="viewState.bakeWarning"></markdown>\n </div>\n </div>\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="Skip Region Detection" help-key="pipeline.config.bake.skipRegionDetection">\n <div class="checkbox" style="margin-bottom: 0">\n <label>\n <input type="checkbox" ng-model="stage.skipRegionDetection" />\n Only bake explicitly selected regions\n </label>\n </div>\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Repo Path\' : \'Package\'}}"\n help-key="pipeline.config.bake.package"\n >\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\n model="stage.baseOs"\n base-os-options="baseOsOptions"\n on-change="bakeStageCtrl.handleBaseOsChange()"\n ></bake-stage-choose-os>\n </stage-config-field>\n <stage-config-field label="VM Type" ng-if="viewState.showVmTypeSelector && viewState.showMigrationFields">\n <label class="radio-inline" ng-repeat="vmType in vmTypes">\n <input type="radio" ng-model="stage.vmType" ng-value="vmType" />\n {{vmType | uppercase}}\n </label>\n </stage-config-field>\n <stage-config-field\n label="Store Type"\n ng-if="!viewState.roscoMode && viewState.showMigrationFields && viewState.showStoreType"\n >\n <label class="radio-inline" ng-repeat="storeType in storeTypes">\n <input type="radio" ng-model="stage.storeType" ng-value="storeType" />\n {{storeType | uppercase}}\n </label>\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 <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() && viewState.showMigrationFields"\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() && viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.varFileName" />\n </stage-config-field>\n <stage-config-field label="Root Volume Size" ng-if="viewState.minRootVolumeSize && viewState.showMigrationFields">\n <input\n type="number"\n class="form-control input-sm"\n style="width: 80px; display: inline-block"\n ng-min="viewState.minRootVolumeSize"\n ng-model="stage.rootVolumeSize"\n />\n GB <span class="small">(minimum: {{viewState.minRootVolumeSize}})</span>\n </stage-config-field>\n <stage-config-field label="Base Name" ng-if="stage.storeType !== \'docker\' && viewState.showMigrationFields">\n <input type="text" class="form-control input-sm" ng-model="stage.baseName" />\n </stage-config-field>\n <stage-config-field\n label="Base AMI"\n help-key="pipeline.config.bake.baseAmi"\n ng-if="stage.storeType !== \'docker\' && viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.baseAmi" />\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Docker Image Name\' : \'AMI Name\'}}"\n help-key="pipeline.config.bake.amiName"\n ng-if="viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.amiName" />\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Docker Image Prefix\' : \'AMI Suffix\'}}"\n help-key="pipeline.config.bake.amiSuffix"\n ng-if="viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.amiSuffix" />\n </stage-config-field>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/bake/bakeExecutionDetails.html",'<div ng-controller="awsBakeExecutionDetailsCtrl">\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>Amazon</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>VM Type</dt>\n <dd>{{stage.context.vmType | uppercase}}</dd>\n <dt ng-if="!roscoMode">Store Type</dt>\n <dd ng-if="!roscoMode">{{stage.context.storeType | uppercase}}</dd>\n <dt ng-if="!roscoMode">Label</dt>\n <dd ng-if="!roscoMode">{{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\n stage="stage"\n message="stage.failureMessage"\n ng-if="stage.failureMessage"\n ></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 <div ng-if="stage.context.imageName">\n <strong>Image:</strong>\n <div select-on-dbl-click>{{stage.context.imageName}}</div>\n <div>({{stage.context.ami}})</div>\n </div>\n <span ng-if="bakeFailedNoError">Bake failed. </span>\n <a target="_blank" href="{{ bakeryDetailUrl(stage) }}">View Bakery Details</a>\n <span ng-if="bakeFailedNoError"> for more info.</span>\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')}]);t("spinnaker.amazon.pipeline.stage.cloneServerGroupStage",[]).config((function(){Pe.pipeline.registerStage({provides:"cloneServerGroup",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html",executionStepLabelUrl:"amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html",accountExtractor:e=>[e.context.credentials],validators:[{type:"requiredField",fieldName:"targetCluster",fieldLabel:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"region"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsCloneServerGroupStageCtrl",["$scope",function(e){const t=e.stage;e.viewState={accountsLoaded:!1},o.listAccounts("aws").then((t=>{e.accounts=t,e.viewState.accountsLoaded=!0})),this.cloneTargets=Me.TARGET_LIST,t.target=t.target||this.cloneTargets[0].val,t.application=e.application.name,t.cloudProvider="aws",t.cloudProviderType="aws",t.viewState={mode:"editPipeline"},t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),t.isNew&&(t.useAmiBlockDeviceMappings=$t.get(e,"application.attributes.providerSettings.aws.useAmiBlockDeviceMappings",!1),t.copySourceCustomBlockDeviceMappings=!1),this.targetClusterUpdated=()=>{if(t.targetCluster){const a=Fe.monikerClusterNameFilter(t.targetCluster),n=$t.first(Fe.getMonikers([e.application],a));if(n)t.stack=n.stack,t.freeFormDetails=n.detail;else{const e=Ee.parseClusterName(t.targetCluster);t.stack=e.stack,t.freeFormDetails=e.freeFormDetails}}else t.stack="",t.freeFormDetails=""},e.$watch("stage.targetCluster",this.targetClusterUpdated),this.removeCapacity=()=>{delete t.capacity},$t.has(t,"useSourceCapacity")||(t.useSourceCapacity=!0),this.toggleSuspendedProcess=e=>{t.suspendedProcesses=t.suspendedProcesses||[];const a=t.suspendedProcesses.indexOf(e);-1===a?t.suspendedProcesses.push(e):t.suspendedProcesses.splice(a,1)},this.processIsSuspended=e=>t.suspendedProcesses&&t.suspendedProcesses.includes(e),this.getBlockDeviceMappingsSource=()=>t.copySourceCustomBlockDeviceMappings?"source":t.useAmiBlockDeviceMappings?"ami":"default",this.selectBlockDeviceMappingsSource=e=>{"source"===e?(t.copySourceCustomBlockDeviceMappings=!0,t.useAmiBlockDeviceMappings=!1):"ami"===e?(t.copySourceCustomBlockDeviceMappings=!1,t.useAmiBlockDeviceMappings=!0):(t.copySourceCustomBlockDeviceMappings=!1,t.useAmiBlockDeviceMappings=!1)},this.onRedBlackFieldChange=(e,a)=>{$t.set(t,e,a)}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html",'<div ng-controller="awsCloneServerGroupStageCtrl as cloneServerGroupStageCtrl">\n <div ng-if="!pipeline.strategy">\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 <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="accounts"\n single-region="true"\n cluster-field="targetCluster"\n >\n </account-region-cluster-selector>\n </div>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="cloneServerGroupStageCtrl.cloneTargets"></target-select>\n </stage-config-field>\n <div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Capacity</div>\n <div class="col-md-9 radio">\n <label>\n <input\n type="radio"\n ng-model="stage.useSourceCapacity"\n ng-value="true"\n ng-click="cloneServerGroupStageCtrl.removeCapacity()"\n id="useSourceCapacityTrue"\n />\n Copy the capacity from the current server group\n <help-field key="serverGroupCapacity.useSourceCapacityTrue"></help-field>\n </label>\n </div>\n <div class="col-md-9 col-md-offset-3 radio">\n <label>\n <input type="radio" ng-model="stage.useSourceCapacity" ng-value="false" id="useSourceCapacityFalse" />\n Let me specify the capacity\n <help-field key="serverGroupCapacity.useSourceCapacityFalse"></help-field>\n </label>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-2 col-md-offset-3">Min</div>\n <div class="col-md-2">Max</div>\n <div class="col-md-2">Desired</div>\n </div>\n <div class="form-group">\n <div class="col-md-2 col-md-offset-3">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.min"\n min="0"\n max="{{stage.capacity.max}}"\n required\n />\n </div>\n <div class="col-md-2">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.max"\n min="{{stage.capacity.min}}"\n required\n />\n </div>\n <div class="col-md-2">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.desired"\n min="{{stage.capacity.min}}"\n max="{{stage.capacity.max}}"\n required\n />\n </div>\n </div>\n </div>\n <stage-config-field label="Traffic" help-key="aws.serverGroup.traffic">\n <div class="checkbox">\n <label>\n <input\n type="checkbox"\n ng-click="cloneServerGroupStageCtrl.toggleSuspendedProcess(\'AddToLoadBalancer\')"\n ng-checked="!cloneServerGroupStageCtrl.processIsSuspended(\'AddToLoadBalancer\')"\n />\n Send client requests to new instances\n </label>\n </div>\n </stage-config-field>\n <stage-config-field label="AMI Block Device Mappings">\n <div class="radio">\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'source\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'source\'"\n name="blockDeviceMappingsSource"\n />\n Copy from current server group\n <help-field key="aws.blockDeviceMappings.useSource"></help-field>\n </label>\n </div>\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'ami\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'ami\'"\n name="blockDeviceMappingsSource"\n />\n Prefer AMI block device mappings\n <help-field key="aws.blockDeviceMappings.useAMI"></help-field>\n </label>\n </div>\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'default\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'default\'"\n name="blockDeviceMappingsSource"\n />\n Defaults for selected instance type\n <help-field key="aws.blockDeviceMappings.useDefaults"></help-field>\n </label>\n </div>\n </div>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n <deployment-strategy-selector\n field-columns="6"\n command="stage"\n on-field-change="cloneServerGroupStageCtrl.onRedBlackFieldChange"\n ></deployment-strategy-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html",'<span class="task-label"> Clone Server Group: {{step.context.source.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.cloudformation.changetset.info.component",[]).component("cloudFormationChangeSetInfo",Va(F((e=>{const{stage:t,stageconfig:a}=e,[n,r]=Dt(t.changeSetName?t.changeSetName:"ChangeSet-${ execution['id']}"),[i,s]=Dt(t.executeChangeSet),[o,p]=Dt(t.actionOnReplacement);return Bt.createElement("div",null,Bt.createElement("hr",null),Bt.createElement("h4",null,"ChangeSet Configuration"),Bt.createElement(Le,{label:"ChangeSet Name"},Bt.createElement(l,{className:"form-control",type:"text",value:n,onChange:e=>{return t=e.target.value,r(t),void a.updateStageField({changeSetName:t});var t}})),Bt.createElement(Le,{label:"Execute ChangeSet"},Bt.createElement(d,{checked:i,onChange:e=>{return t=e.target.checked,s(t),void a.updateStageField({executeChangeSet:t});var t}})),i&&Bt.createElement(Le,{label:"If ChangeSet contains a replacement","help-key":"aws.cloudformation.changeSet.options"},Bt.createElement(c,{clearable:!1,value:o,options:[{value:"ask",label:"ask"},{value:"skip",label:"skip it"},{value:"execute",label:"execute it"},{value:"fail",label:"fail stage"}],onChange:e=>{return t=e.target.value,p(t),void a.updateStageField({actionOnReplacement:t});var t}})))}),"cloudFormationChangeSetInfo"),["stage","stageconfig"]));class ti{constructor(e){this.$scope=e,this.$onInit=()=>{"string"==typeof this.command.templateBody?this.rawTemplateBody=this.command.templateBody:this.rawTemplateBody=Re(this.command.templateBody)},this.handleChange=(e,t)=>{this.command.templateBody=t||e,this.templateBody=t||e,this.rawTemplateBody=e,this.$scope.$applyAsync()}}}ti.$inject=["$scope"];const ai={bindings:{command:"<",templateBody:"<"},controller:ti,controllerAs:"ctrl",template:'\n <yaml-editor\n value="ctrl.rawTemplateBody"\n on-change="ctrl.handleChange"\n ></yaml-editor>'};t("spinnaker.amazon.cloudformation.entry.component",[]).component("cloudFormationTemplateEntry",ai);class ni extends zt.Component{constructor(e){super(e)}render(){const{stage:e,current:t,name:a}=this.props;return zt.createElement(Oe,{name:a,current:t},zt.createElement(Ue,{item:e}),zt.createElement(Ve,{stage:e,message:e.failureMessage}))}}ni.title="Task Status";class ri{constructor(e){this.$scope=e,this.state={loaded:!1},this.textSource="text",this.artifactSource="artifact",this.sources=[this.textSource,this.artifactSource],this.showClusterSelect=!1,this.onStackArtifactEdited=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactId=null,this.$scope.stage.stackArtifact=e}))},this.onStackArtifactSelected=e=>{this.onChangeStackArtifactId(e.id)},this.onChangeStackArtifactId=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactId=e,this.$scope.stage.stackArtifact=null}))},this.onStackArtifactAccountSelected=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactAccount=e}))},this.updatePipeline=e=>{this.$scope.$applyAsync((()=>{sa(this.$scope.pipeline,e)}))};const t={accounts:o.getAllAccountDetailsForProvider("aws"),artifactAccounts:o.getArtifactAccounts()};Ua.all(t).then((e=>{const{accounts:t,artifactAccounts:a}=e;this.accounts=t,this.state.loaded=!0,this.cloudFormationStackArtifactDelegate.setAccounts(a),this.cloudFormationStackArtifactController.updateAccounts(this.cloudFormationStackArtifactDelegate.getSelectedExpectedArtifact())})),this.cloudFormationStackArtifactDelegate=new je(e,"stack"),this.cloudFormationStackArtifactController=new qe(this.cloudFormationStackArtifactDelegate)}canShowAccountSelect(){return this.$scope.stage.source===this.artifactSource&&!this.$scope.showCreateArtifactForm&&this.cloudFormationStackArtifactController.accountsForArtifact.length>1}toggleChangeSet(){this.$scope.stage.isChangeSet=!this.$scope.stage.isChangeSet}}ri.$inject=["$scope"];const ii=e=>{const{execution:t,stage:a,application:n}=e,[r,i]=Dt(!1),[s,l]=Dt(""),[o,c]=Dt(!1),d=e=>{i(!0),l(e),c(!1),Un.evaluateCloudFormationChangeSetExecutionService.evaluateExecution(n,t,a,e)},p=e=>a.judgmentStatus===e||r&&s===e;return Bt.createElement("div",null,Bt.createElement("div",null,Bt.createElement("p",null,"This ChangeSet contains a replacement, which means there will be ",Bt.createElement("b",null,"potential data loss")," when executed."),Bt.createElement("p",null,"How do you want to proceed?"),Bt.createElement("div",{className:"action-buttons"},Bt.createElement("button",{className:"btn btn-danger",onClick:()=>{d("execute")},disabled:r},p("Execute")&&Bt.createElement(te,{mode:"circular"}),a.context.stopButtonLabel||"Execute"),Bt.createElement("button",{className:"btn btn-primary",disabled:r,onClick:()=>{d("skip")}},p("Skip")&&Bt.createElement(te,{mode:"circular"}),a.context.skipButtonLabel||"Skip"),Bt.createElement("button",{className:"btn btn-primary",disabled:r,onClick:()=>{d("fail")}},p("Fail")&&Bt.createElement(te,{mode:"circular"}),a.context.FailButtonLabel||"Fail"))),o&&Bt.createElement("div",{className:"error-message"},"There was an error recording your decision. Please try again."))};class si extends zt.Component{constructor(e){super(e)}render(){const{application:e,execution:t,stage:a,current:n,name:r}=this.props,i=a.context.changeSetContainsReplacement,s=i&&a.isRunning&&"ask"===a.context.actionOnReplacement,l=a.context.isChangeSet;return zt.createElement(Oe,{name:r,current:n},s?zt.createElement(ii,{key:a.refId,application:e,execution:t,stage:a}):zt.createElement("div",null,l?zt.createElement("div",null,zt.createElement("dl",{className:"no-margin"},zt.createElement("dt",null,"ChangeSet Name"),zt.createElement("dd",null,a.context.changeSetName),zt.createElement("dt",null,"Replacement"),zt.createElement("dd",null,String(i)),a.context.changeSetExecutionChoice&&zt.createElement("div",null,zt.createElement("dt",null,"Judgment"),zt.createElement("dd",null,a.context.changeSetExecutionChoice),zt.createElement("dt",null,"Judged By"),zt.createElement("dd",null,a.context.lastModifiedBy)))):zt.createElement("div",null,"No changeSets found")))}}si.title="Change Set Execution";class li extends zt.Component{render(){if(!this.props.executionMarker)return zt.createElement(He,{...this.props});const{stage:e}=this.props;if(e.isRunning&&e.stages[0].context.changeSetContainsReplacement&&"ask"===e.stages[0].context.actionOnReplacement){const t=zt.createElement("div",null,zt.createElement("div",null,zt.createElement("b",null,e.name)),zt.createElement(ii,{stage:e.masterStage,application:this.props.application,execution:this.props.execution}));return zt.createElement(ae,{template:t},this.props.children)}const t=zt.createElement(Ma,{id:e.id},e.name);return zt.createElement(Fa,{placement:"top",overlay:t},zt.createElement("span",null,this.props.children))}}class oi extends zt.Component{constructor(e){super(e)}render(){return this.props.stage.isRunning&&this.props.stage.stages[0].context.changeSetContainsReplacement&&"ask"===this.props.stage.stages[0].context.actionOnReplacement?(this.props.stage.requiresAttention=!0,zt.createElement("span",{className:"fa fa-child"})):null}}t("spinnaker.amazon.pipeline.stages.deployCloudFormationStage",[]).config((()=>{Pe.pipeline.registerStage({label:"Deploy (CloudFormation Stack)",description:"Deploy a CloudFormation Stack",key:"deployCloudFormation",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/deployCloudFormation/deployCloudFormationStackConfig.html",controller:"DeployCloudFormationStackConfigController",controllerAs:"ctrl",useCustomTooltip:!0,executionDetailsSections:[ni,si],executionLabelComponent:li,producesArtifacts:!0,supportsCustomTimeout:!0,validators:[],markerIcon:oi,accountExtractor:e=>e.account?[e.account]:[],configAccountExtractor:e=>e.account?[e.account]:[],artifactExtractor:We.accumulateArtifacts(["stackArtifactId","requiredArtifactIds"]),artifactRemover:Ze.removeArtifactFromFields(["stackArtifactId","requiredArtifactIds"])})})).controller("DeployCloudFormationStackConfigController",ri),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/deployCloudFormation/deployCloudFormationStackConfig.html",'<div ng-if="ctrl.state.loaded" class="clearfix">\n <div class="container-fluid form-horizontal">\n <h4>Basic Settings</h4>\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="ctrl.accounts"\n show-cluster-select="ctrl.showClusterSelect"\n >\n </account-region-cluster-selector>\n </div>\n <h4>Template Configuration</h4>\n <ng-form name="amazonCloudFormationTemplateSource">\n <stage-config-field label="Stack name">\n <label class="sm-label-right">\n <input type="text" class="form-control input-sm" required ng-model="stage.stackName" />\n </label>\n <br />\n <label>\n <input type="checkbox" ng-checked="stage.isChangeSet" ng-click="ctrl.toggleChangeSet()" />\n <strong>Create CloudFormation ChangeSet</strong>\n </label>\n </stage-config-field>\n\n <stage-config-field label="IAM role ARN">\n <label class="sm-label-right">\n <input type="text" class="form-control input-sm" ng-model="stage.roleARN" />\n </label>\n </stage-config-field>\n <stage-config-field label="Source" help-key="aws.cloudformation.source">\n <label class="sm-label-right">\n <input type="radio" ng-model="ctrl.$scope.stage.source" value="{{ctrl.textSource}}" />\n {{ ctrl.textSource | robotToHuman }}\n <span ng-if="stage.source === ctrl.textSource"> </span> </label\n ><br />\n <label class="sm-label-right">\n <input type="radio" ng-model="ctrl.$scope.stage.source" value="{{ctrl.artifactSource}}" />\n {{ ctrl.artifactSource | robotToHuman }}\n </label>\n </stage-config-field>\n </ng-form>\n <cloud-formation-template-entry\n ng-if="stage.source === ctrl.textSource"\n templateBody="stage.templateBody"\n command="stage"\n >\n </cloud-formation-template-entry>\n <stage-artifact-selector-delegate\n ng-if="ctrl.$scope.stage.source === ctrl.artifactSource"\n artifact="stage.stackArtifact"\n excluded-artifact-type-patterns="[]"\n expected-artifact-id="stage.stackArtifactId"\n field-columns="8"\n help-key="\'aws.cloudformation.expectedArtifact\'"\n label="\'Expected Artifact\'"\n on-artifact-edited="ctrl.onStackArtifactEdited"\n on-expected-artifact-selected="ctrl.onStackArtifactSelected"\n pipeline="pipeline"\n stage="stage"\n >\n </stage-artifact-selector-delegate>\n <div ng-if="stage.isChangeSet">\n <cloud-formation-change-set-info stage="stage" stageconfig="stageConfigCtrl"> </cloud-formation-change-set-info>\n </div>\n <hr />\n <stage-config-field label="Parameters" field-columns="6">\n <map-editor model="ctrl.$scope.stage.parameters" add-button-label="Add parameter"></map-editor>\n </stage-config-field>\n <hr />\n <stage-config-field label="Tags" field-columns="6">\n <map-editor model="ctrl.$scope.stage.tags" add-button-label="Add tag"></map-editor>\n </stage-config-field>\n <hr />\n <stage-config-field label="Capabilities" field-columns="6">\n <ui-select multiple ng-model="stage.capabilities" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices repeat="capability in [\'CAPABILITY_IAM\', \'CAPABILITY_NAMED_IAM\', \'CAPABILITY_AUTO_EXPAND\']">\n <span>{{ capability }}</span>\n </ui-select-choices>\n </ui-select>\n </stage-config-field>\n </div>\n</div>\n')}]);class ci{constructor(e){this.executionService=e}evaluateExecution(e,t,a,n){const r=e=>{const t=e.stages.find((e=>e.id===a.id));return t&&"RUNNING"!==t.status};return this.executionService.patchExecution(t.id,a.id,{changeSetExecutionChoice:n}).then((()=>this.executionService.waitUntilExecutionMatches(t.id,r))).then((t=>this.executionService.updateExecution(e,t)))}}ci.$inject=["executionService"];t("spinnaker.amazon.deployCloudFormation.service",[_e]).service("evaluateCloudFormationChangeSetExecutionService",ci);t("spinnaker.amazon.pipeline.stage.aws.destroyAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"destroyServerGroup",alias:"destroyAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/destroyAsg/destroyAsgStage.html",executionStepLabelUrl:"amazon/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("awsDestroyAsgStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.regions=["us-east-1","us-west-1","eu-west-1","us-west-2"],e.targets=Me.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/destroyAsg/destroyAsgStage.html",'<div ng-controller="awsDestroyAsgStageCtrl 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("amazon/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",'<span class="task-label"> Destroy Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.pipeline.stage.disableAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"disableServerGroup",alias:"disableAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/disableAsg/disableAsgStage.html",executionStepLabelUrl:"amazon/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("awsDisableAsgStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.targets=Me.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="aws",t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableAsg/disableAsgStage.html",'<div ng-controller="awsDisableAsgStageCtrl 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="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",'<span class="task-label"> Disable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.pipeline.stage.disableClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"disableCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/disableCluster/disableClusterStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"remainingEnabledServerGroups",fieldLabel:"Keep [X] enabled Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsDisableClusterStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},a.regions=a.regions||[],a.cloudProvider="aws",a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws),void 0===a.remainingEnabledServerGroups&&(a.remainingEnabledServerGroups=1),t.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===a.preferLargerOverNewer&&(a.preferLargerOverNewer="false"),a.preferLargerOverNewer=a.preferLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableCluster/disableClusterStage.html",'<div ng-controller="awsDisableClusterStageCtrl as disableClusterStageCtrl" 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="Disable Options">\n <div class="form-inline">\n Keep the\n <input\n type="number"\n min="0"\n required\n ng-model="stage.remainingEnabledServerGroups"\n class="form-control input-sm"\n style="width: 50px"\n />\n <select class="form-control input-sm" ng-model="stage.preferLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n {{disableClusterStageCtrl.pluralize(\'server group\', stage.remainingEnabledServerGroups)}} enabled.\n </div>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.enableAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"enableServerGroup",alias:"enableAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/enableAsg/enableAsgStage.html",executionStepLabelUrl:"amazon/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("awsEnableAsgStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},e.targets=Me.TARGET_LIST,a.regions=a.regions||[],a.cloudProvider="aws",a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws),a.target||(a.target=e.targets[0].val),e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/enableAsg/enableAsgStage.html",'<div ng-controller="awsEnableAsgStageCtrl 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="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",'<span class="task-label"> Enable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);e.module("spinnaker.amazon.pipeline.stage.findAmiStage",[]).config((function(){Pe.pipeline.registerStage({provides:"findImage",alias:"findAmi",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/findAmi/findAmiStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"selectionStrategy",fieldLabel:"Server Group Selection"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials"}]})})).controller("awsFindAmiStageCtrl",["$scope",function(t){const a=t.stage;t.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(e){t.accounts=e,t.state.accounts=!0})),t.selectionStrategies=[{label:"Largest",val:"LARGEST",description:"When multiple server groups exist, prefer the server group with the most instances"},{label:"Newest",val:"NEWEST",description:"When multiple server groups exist, prefer the newest"},{label:"Oldest",val:"OLDEST",description:"When multiple server groups exist, prefer the oldest"},{label:"Fail",val:"FAIL",description:"When multiple server groups exist, fail"}],a.regions=a.regions||[],a.cloudProvider="aws",a.selectionStrategy=a.selectionStrategy||t.selectionStrategies[0].val,e.isUndefined(a.onlyEnabled)&&(a.onlyEnabled=!0),!a.credentials&&t.application.defaultCredentials.aws&&(a.credentials=t.application.defaultCredentials.aws),!a.regions.length&&t.application.defaultRegions.aws&&a.regions.push(t.application.defaultRegions.aws),t.$watch("stage.credentials",t.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findAmi/findAmiStage.html",'<div ng-controller="awsFindAmiStageCtrl as findAmiCtrl" class="form-horizontal">\n <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="accounts"\n show-all-regions="true"\n >\n </account-region-cluster-selector>\n <stage-config-field label="Server Group Selection">\n <ui-select ng-model="stage.selectionStrategy" class="form-control input-sm">\n <ui-select-match placeholder="None">{{$select.selected.label}}</ui-select-match>\n <ui-select-choices repeat="strategy.val as strategy in selectionStrategies | filter: $select.search">\n <strong ng-bind-html="strategy.label | highlight: $select.search"></strong>\n <div ng-bind-html="strategy.description"></div>\n </ui-select-choices>\n </ui-select>\n </stage-config-field>\n <stage-config-field label="Server Group Filters">\n <label class="checkbox-inline">\n <input type="checkbox" ng-model="stage.onlyEnabled" />\n Only consider enabled Server Groups\n </label>\n </stage-config-field>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.findImageFromTagsStage",[]).config((function(){Pe.pipeline.registerStage({provides:"findImageFromTags",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html",executionConfigSections:["findImageConfig","taskStatus"],validators:[{type:"requiredField",fieldName:"packageName"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"tags"}]})})).controller("awsFindImageFromTagsStageCtrl",["$scope",function(e){e.stage.tags=e.stage.tags||{},e.stage.regions=e.stage.regions||[],e.stage.cloudProvider=e.stage.cloudProvider||"aws",$e.getRegions("aws").then((function(t){e.regions=t}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html",'<div ng-controller="awsFindImageFromTagsStageCtrl as findImageFromTagsCtrl" class="form-horizontal">\n <stage-config-field label="Package">\n <input type="text" class="form-control input-sm" ng-model="stage.packageName" />\n </stage-config-field>\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="Tags">\n <map-editor model="stage.tags" allow-empty="true"></map-editor>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'findImageConfig\'">\n <div class="row">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Amazon</dd>\n <dt>Package</dt>\n <dd>{{stage.context.packageName}}</dd>\n <dt>Regions</dt>\n <dd>{{stage.context.regions.join(\', \')}}</dd>\n <dt>Tags</dt>\n <dd>\n <span ng-repeat="(key, val) in stage.context.tags"> {{key}}:{{val}}{{$last ? \'\' : \', \'}} </span>\n </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.amiDetails">\n <div class="col-md-12">\n <div class="well alert alert-info">\n <h4>Results</h4>\n <dl ng-repeat="image in stage.context.amiDetails" class="dl-narrow dl-horizontal">\n <dt>Region</dt>\n <dd>{{image.region}}</dd>\n <dt>Image ID</dt>\n <dd>{{image.imageId}}</dd>\n <dt>Name</dt>\n <dd>{{image.imageName}}</dd>\n </dl>\n </div>\n </div>\n </div>\n </div>\n\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')}]);t("spinnaker.amazon.pipeline.stage.modifyScalingProcessStage",[]).config((function(){Pe.pipeline.registerStage({label:"Modify Scaling Process",description:"Suspend/Resume Scaling Processes",key:"modifyAwsScalingProcess",alias:"modifyScalingProcess",controller:"ModifyScalingProcessStageCtrl",templateUrl:"amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessExecutionDetails.html",executionConfigSections:["modifyScalingProcessesConfig","taskStatus"],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"action"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"processes"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}],cloudProvider:"aws",strategy:!0})})).controller("ModifyScalingProcessStageCtrl",["$scope","stage",function(e,t){e.stage=t,e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.targets=Me.TARGET_LIST,e.actions=[{label:"Suspend",val:"suspend"},{label:"Resume",val:"resume"}],e.processes=["Launch","Terminate","AddToLoadBalancer","AlarmNotification","AZRebalance","HealthCheck","ReplaceUnhealthy","ScheduledActions"],t.processes=t.processes||[],t.regions=t.regions||[],t.action=t.action||e.actions[0].val,t.target=t.target||e.targets[0].val,t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),e.toggleProcess=function(e){t.processes||(t.processes=[]);const a=t.processes.indexOf(e);a>-1?t.processes.splice(a,1):t.processes.push(e)},e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessStage.html",'<div 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-config-field label="Action">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.action"\n ng-options="a.val as a.label for a in actions"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <stage-config-field label="Processes" field-columns="8">\n <div class="checkbox" style="padding-left: 0">\n <checklist model="stage.processes" items="processes"></checklist>\n </div>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'modifyScalingProcessesConfig\'">\n <div class="row">\n <div class="col-md-9">\n <dl class="dl-narrow dl-horizontal">\n <dt>Account</dt>\n <dd><account-tag account="stage.context.credentials"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{stage.context.region}}</dd>\n <dt>ASG Name</dt>\n <dd>{{stage.context.asgName}}</dd>\n <dt>Action</dt>\n <dd>{{stage.context.action}}</dd>\n <dt>Processes</dt>\n <dd>{{stage.context.processes.join(\', \')}}</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.execution.logs">\n <div class="col-md-12">\n <div class="well alert alert-info">\n <a target="_blank" href="{{stage.context.execution.logs}}"> View Execution Logs </a>\n </div>\n </div>\n </div>\n </div>\n\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')}]);t("spinnaker.amazon.pipeline.stage.aws.resizeAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"resizeServerGroup",alias:"resizeAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/resizeAsg/resizeAsgStage.html",executionStepLabelUrl:"amazon/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"targetImpedance",message:"This pipeline will attempt to resize a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"action"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsResizeAsgStageCtrl",["$scope",function(e){const t=e.stage;e.viewState={accountsLoaded:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.viewState.accountsLoaded=!0})),e.resizeTargets=Me.TARGET_LIST,e.scaleActions=[{label:"Scale Up",val:"scale_up"},{label:"Scale Down",val:"scale_down"},{label:"Scale to Cluster Size",val:"scale_to_cluster"},{label:"Scale to Exact Size",val:"scale_exact"}],e.resizeTypes=[{label:"Percentage",val:"pct"},{label:"Incremental",val:"incr"}],t.capacity=t.capacity||{},t.regions=t.regions||[],t.target=t.target||e.resizeTargets[0].val,t.action=t.action||e.scaleActions[0].val,t.resizeType=t.resizeType||e.resizeTypes[0].val,void 0===t.targetHealthyDeployPercentage&&(t.targetHealthyDeployPercentage=100),t.action||"exact"!==t.resizeType||(t.action="scale_exact"),t.cloudProvider="aws",t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),this.updateResizeType=function(){"scale_exact"===t.action?(t.resizeType="exact",delete t.scalePct,delete t.scaleNum):(t.capacity={},"pct"===t.resizeType?delete t.scaleNum:(t.resizeType="incr",delete t.scalePct,t.scaleNum=t.scaleNum||0))}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/resizeAsg/resizeAsgStage.html",'<div ng-controller="awsResizeAsgStageCtrl as resizeAsgStageCtrl">\n <div ng-if="!pipeline.strategy">\n <div ng-if="!viewState.accountsLoaded" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div ng-if="viewState.accountsLoaded">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="resizeTargets"></target-select>\n </stage-config-field>\n <stage-config-field label="Action" help-key="pipeline.config.resizeAsg.action">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.action"\n ng-change="resizeAsgStageCtrl.updateResizeType()"\n ng-options="a.val as a.label for a in scaleActions"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <div ng-if="stage.action !== \'scale_exact\'">\n <stage-config-field label="{{stage.action === \'scale_to_cluster\' ? \'Additional Capacity\' : \'Type\'}}">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.resizeType"\n ng-change="resizeAsgStageCtrl.updateResizeType()"\n ng-options="t.val as t.label for t in resizeTypes"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <div ng-if="stage.resizeType === \'pct\'">\n <stage-config-field label="Resize Percentage">\n <input type="number" min="0" ng-model="stage.scalePct" class="form-control input-sm" style="width: 80px" />\n <div>\n <em class="subinput-note"\n >This is the percentage by which the target server group\'s capacity will be increased</em\n >\n </div>\n </stage-config-field>\n </div>\n <div ng-if="stage.resizeType === \'incr\'">\n <stage-config-field label="Resize-by Amount">\n <input type="number" min="0" ng-model="stage.scaleNum" class="form-control input-sm" style="width: 80px" />\n <div>\n <em class="subinput-note"\n >This is the exact amount by which the target server group\'s capacity will be increased</em\n >\n </div>\n </stage-config-field>\n </div>\n <div ng-if="stage.action === \'scale_up\' || stage.action === \'scale_to_cluster\'">\n <stage-config-field>\n <target-healthy-percentage-selector command="stage"></target-healthy-percentage-selector>\n </stage-config-field>\n </div>\n </div>\n <div ng-if="stage.action === \'scale_exact\'">\n <stage-config-field class="small">\n <div class="row">\n <div class="col-md-3">Min</div>\n <div class="col-md-3">Max</div>\n <div class="col-md-3">Desired</div>\n </div>\n </stage-config-field>\n <stage-config-field label="Match Capacity">\n <div class="row">\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.min" class="form-control input-sm" />\n </div>\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.max" class="form-control input-sm" />\n </div>\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.desired" class="form-control input-sm" />\n </div>\n </div>\n </stage-config-field>\n <stage-config-field>\n <em class="subinput-note">This is the exact amount to which the target server group will be scaled</em>\n </stage-config-field>\n </div>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html",'<span class="task-label" ng-if="!step.context.useNameAsLabel">\n Resize Server Group: {{step.context.serverGroupName}} ({{step.context.region}})\n</span>\n<span class="task-label" ng-if="step.context.useNameAsLabel"> {{step.name}} </span>\n')}]);t("spinnaker.amazon.pipeline.stage.rollbackClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"rollbackCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/rollbackCluster/rollbackClusterStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsRollbackClusterStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},a.regions=a.regions||[],a.cloudProvider="aws",a.targetHealthyRollbackPercentage=a.targetHealthyRollbackPercentage||100,a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/rollbackCluster/rollbackClusterStage.html",'<div ng-controller="awsRollbackClusterStageCtrl as rollbackClusterStageCtrl" 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-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n\n <div class="row">\n <div class="col-sm-10 col-sm-offset-2" ng-if="stage.regions.length > 1">\n Wait\n <input\n type="number"\n min="0"\n ng-model="stage.waitTimeBetweenRegions"\n class="form-control input-sm inline-number"\n />\n seconds between regional rollbacks.\n </div>\n <div class="col-sm-10 col-sm-offset-2">\n Consider rollback successful when\n <input\n type="number"\n min="0"\n max="100"\n ng-model="stage.targetHealthyRollbackPercentage"\n class="form-control input-sm inline-number"\n />\n percent of instances are healthy.\n </div>\n </div>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.scaleDownClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"scaleDownCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"remainingFullSizeServerGroups",fieldLabel:"Keep [X] full size Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}],strategy:!0})})).controller("awsScaleDownClusterStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),void 0===t.remainingFullSizeServerGroups&&(t.remainingFullSizeServerGroups=1),void 0===t.allowScaleDownActive&&(t.allowScaleDownActive=!1),this.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===t.preferLargerOverNewer&&(t.preferLargerOverNewer="false"),t.preferLargerOverNewer=t.preferLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html",'<div ng-controller="awsScaleDownClusterStageCtrl as scaleDownClusterStageCtrl" 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="Scale Down Options">\n <div class="form-inline">\n <p>\n Keep the\n <input\n type="number"\n min="0"\n required\n ng-model="stage.remainingFullSizeServerGroups"\n class="form-control input-sm"\n style="width: 50px"\n />\n <select class="form-control input-sm" ng-model="stage.preferLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n {{scaleDownClusterStageCtrl.pluralize(\'server group\', stage.remainingFullSizeServerGroups)}} at current size.\n </p>\n <p>The remaining server groups will be scaled down to zero instances.</p>\n </div>\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-offset-3 col-md-6 checkbox">\n <label>\n <input type="checkbox" ng-model="stage.allowScaleDownActive" />\n Allow scale down of active server groups\n </label>\n </div>\n </div>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.aws.shrinkClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"shrinkCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"shrinkToSize",fieldLabel:"shrink to [X] Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsShrinkClusterStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),void 0===t.shrinkToSize&&(t.shrinkToSize=1),void 0===t.allowDeleteActive&&(t.allowDeleteActive=!1),this.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===t.retainLargerOverNewer&&(t.retainLargerOverNewer="false"),t.retainLargerOverNewer=t.retainLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html",'<div ng-controller="awsShrinkClusterStageCtrl as shrinkClusterStageCtrl" 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="Shrink Options">\n <div class="form-inline">\n Shrink to\n <input\n type="number"\n min="0"\n required\n ng-model="stage.shrinkToSize"\n class="form-control input-sm"\n style="width: 50px"\n />\n {{shrinkClusterStageCtrl.pluralize(\'server group\', stage.shrinkToSize)}}, keeping the\n <select class="form-control input-sm" ng-model="stage.retainLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n </div>\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-offset-3 col-md-6 checkbox">\n <label>\n <input type="checkbox" ng-model="stage.allowDeleteActive" />\n Allow deletion of active server groups\n </label>\n </div>\n </div>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.tagImageStage",[]).config((function(){Pe.pipeline.registerStage({provides:"upsertImageTags",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/tagImage/tagImageStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/tagImage/tagImageExecutionDetails.html",executionConfigSections:["tagImageConfig","taskStatus"]})})).controller("awsTagImageStageCtrl",["$scope",e=>{e.stage.tags=e.stage.tags||{},e.stage.cloudProvider=e.stage.cloudProvider||"aws";e.$watch("stage.requisiteStageRefIds",(()=>{const t=Ke.getAllUpstreamDependencies(e.pipeline,e.stage).filter((e=>Me.IMAGE_PRODUCING_STAGES.includes(e.type)));e.consideredStages=new Map(t.map((e=>[e.refId,e.name])))}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/tagImage/tagImageStage.html",'<div ng-controller="awsTagImageStageCtrl as tagImageStageCtrl" class="form-horizontal">\n <stage-config-field label="Tags">\n <map-editor model="stage.tags" allow-empty="true"></map-editor>\n </stage-config-field>\n <stage-config-field label="Stages (optional)" help-key="aws.tagImage.consideredStages" help-key-expand="true">\n <div class="checkbox">\n <checklist model="stage.consideredStages" items="consideredStages"></checklist>\n </div>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/tagImage/tagImageExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'tagImageConfig\'">\n <div class="row" ng-if="stage.context.targets">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Amazon</dd>\n <dt>Images</dt>\n <dd ng-repeat="target in stage.context.targets">\n {{target.imageName}}<br />\n <em>{{target.regions.join(\', \')}}</em>\n </dd>\n </dl>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt>Tags</dt>\n <dd ng-repeat="(key, val) in stage.context.tags" ng-if="val !== null">{{key}} = {{val}}</dd>\n <dt ng-if="stage.context.consideredStages">Stages</dt>\n <dd ng-repeat="consideredStage in stage.context.consideredStages">\n <stage-name stages="execution.stages" ref-id="consideredStage"></stage-name>\n </dd>\n </dl>\n </div>\n </div>\n\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n </div>\n\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')}]);t("spinnaker.amazon.react",[]).run(["$injector",function(e){Un.initialize(e),Rn.initialize(e)}]);t("spinnaker.amazon.search.searchResultFormatter",[]).factory("awsSearchResultFormatter",(function(){return{securityGroups:function(e){return xn.getVpcName(e.vpcId).then((function(t){const a=t?e.region+" - "+t.toLowerCase():e.region;return e.name+" ("+a+")"}))}}}));t("spinnaker.amazon.securityGroup.baseConfig.controller",[Wa,Te]).controller("awsConfigSecurityGroupMixin",["$scope","$state","$uibModalInstance","application","securityGroup","securityGroupReader","cacheInitializer",function(e,t,a,n,r,i,s){let l;const c=this;e.self=e,e.application=n,e.customComponentIsvalid=!0,e.state={submitting:!1,regionError:void 0,refreshingSecurityGroups:!1,removedRules:[],infiniteScroll:{numToAdd:20,currentItems:20}},e.allVpcs=[],e.wizard=Ye,e.hideClassic=!1,c.addMoreItems=function(){e.state.infiniteScroll.currentItems+=e.state.infiniteScroll.numToAdd};const d=()=>e.securityGroup.accountName||e.securityGroup.credentials;function p(){if(e.$$destroyed)return;a.close();const n={name:e.securityGroup.name,accountId:d(),region:e.securityGroup.regions[0],vpcId:e.securityGroup.vpcId,provider:"aws"};t.includes("**.firewallDetails")?t.go("^.firewallDetails",n):t.go(".firewallDetails",n)}function u(){e.availableSecurityGroups=[],e.existingSecurityGroupNames=[]}function m(){e.state.refreshTime=Se.get("securityGroups").getStats().ageMax}e.taskMonitor=new v({application:n,title:`Creating your ${U.get("firewall")}`,modalInstance:a,onTaskComplete:function(){n.securityGroups.refresh(),n.securityGroups.onNextRefresh(e,p)}}),e.securityGroup=r,c.initializeAccounts=()=>o.listAllAccounts("aws").then((function(t){e.accounts=t.filter((e=>!1!==e.authorized)),e.allAccounts=t,c.accountUpdated()})),c.upsert=function(){e.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(e.securityGroup,n,"Create")}))},c.accountUpdated=function(){const t=e.securityGroup;t.account=t.accountId=t.accountName=t.credentials,o.getRegionsForAccount(d()).then((t=>{e.regions=t.map((e=>e.name)),u(),c.regionUpdated(),e.state.isNew&&c.updateName()}))},c.regionUpdated=function(){const t=d(),a=e.securityGroup.regions||[];xn.listVpcs().then((function(n){const r=$t.groupBy(n.filter((e=>e.account===t)),"label");e.allVpcs=n;const i=[];$t.forOwn(r,(function(e,n){a.every((a=>e.some((e=>e.region===a&&e.account===t))))&&i.push({ids:e.filter((e=>a.includes(e.region))).map((e=>e.id)),label:n,deprecated:e[0].deprecated})})),e.activeVpcs=i.filter((function(e){return!e.deprecated})),e.deprecatedVpcs=i.filter((function(e){return e.deprecated})),e.vpcs=i,e.state.regionError=e.state.isClone&&(e.securityGroup.regions||[]).includes(e.state.originRegion),c.updateVpcId(i)}))},this.updateVpcId=t=>{const a=gn.classicLaunchLockout;if(!r.id&&a){if(Number($t.get(n,"attributes.createTs",0))>=a&&(e.hideClassic=!0,!r.vpcId&&t.length)){let a;if(gn.defaults.vpc){const e=t.find((e=>e.label===gn.defaults.vpc));e&&(a=e.ids[0])}r.vpcId=a||(e.activeVpcs.length?e.activeVpcs[0].ids[0]:t[0].ids[0])}}const i=e.allVpcs.find((t=>t.id===e.securityGroup.vpcId)),s=(t||[]).find((e=>i&&i.label===e.label)),l=(t||[]).find((e=>gn.defaults.vpc===e.label))||(e.activeVpcs||[])[0];e.securityGroup.vpcId=s&&s.ids[0]||l&&l.ids[0],this.vpcUpdated()},this.vpcUpdated=function(){const t=d(),a=e.securityGroup.regions;t&&a.length?function(){const t=e.securityGroup.vpcId||null,a=d(),n=e.securityGroup.regions||[];let r=[],i=[];n.forEach((function(n){let s=null;if(t){const r=$t.find(e.allVpcs,{id:t});s=$t.find(e.allVpcs,{account:a,region:n,name:r.name}).id}const o=$t.get(l,[a,"aws",n].join("."),[]).filter((e=>e.vpcId===s)).map((e=>e.name));r=$t.uniq(r.concat(o)),i=i.length?$t.intersection(i,o):r})),e.availableSecurityGroups=i,e.existingSecurityGroupNames=r,e.state.securityGroupsLoaded=!0,function(){const t=e.state.removedRules,a=e.securityGroup;e.securityGroup.securityGroupIngress=(a.securityGroupIngress||[]).filter((n=>!(!n.accountName||!n.vpcId||n.accountName===a.accountName&&n.vpcId===a.vpcId)||(!(n.name&&!e.availableSecurityGroups.includes(n.name)&&!t.includes(n.name))||(t.push(n.name),!1)))),t.length&&Ye.markDirty("Ingress")}()}():u(),e.coordinatesChanged.next()},c.mixinUpsert=function(t){e.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(e.securityGroup,n,t)}))},c.refreshSecurityGroups=function(){return e.state.refreshingSecurityGroups=!0,s.refreshCache("securityGroups").then((function(){return c.initializeSecurityGroups().then((function(){c.vpcUpdated(),e.state.refreshingSecurityGroups=!1,m()}))}))},l={},e.allSecurityGroupsUpdated=new fa,e.coordinatesChanged=new fa,c.initializeSecurityGroups=function(){return i.getAllSecurityGroups().then((function(t){m(),l=t;const a=e.securityGroup.credentials||e.securityGroup.accountName,n=e.securityGroup.regions[0],r=e.securityGroup.vpcId||null;let i;i=a&&n?$t.filter(t[a].aws[n],{vpcId:r}):t,e.availableSecurityGroups=$t.map(i,"name");const s=gn.securityGroupExclusions;e.allSecurityGroups=s?Qe(t,(e=>!s.includes(e))):t,e.allSecurityGroupsUpdated.next(),e.state.regionError=e.state.isClone&&(e.securityGroup.regions||[]).includes(e.state.originRegion)}))},c.cancel=function(){a.dismiss()};const g=/^[\x20-\x7F]+$/,h=/^[a-zA-Z0-9\s._\-:/()#,@[\]+=&;{}!$*]+$/;c.getCurrentNamePattern=function(){return e.securityGroup.vpcId?h:g},c.updateName=function(){const{securityGroup:t}=e,a=n.isStandalone?n.name.split("-")[0]:n.name,r=Ee.getClusterName(a,t.stack,t.detail);t.name=r,e.namePreview=r},c.namePattern={test:function(e){return c.getCurrentNamePattern().test(e)}},c.addRule=function(e){e.push({type:"tcp",startPort:7001,endPort:7001})},c.removeRule=function(e,t){e.splice(t,1)},c.updateRuleType=function(e,t,a){const n=t[a];"icmp"!==e&&"icmpv6"!==e||(n.startPort=0,n.endPort=0)},c.dismissRemovedRules=function(){e.state.removedRules=[],Ye.markClean("Ingress"),Ye.markComplete("Ingress")}}]);e.module("spinnaker.amazon.securityGroup.clone.controller",["spinnaker.amazon.securityGroup.baseConfig.controller"]).controller("awsCloneSecurityGroupController",["$scope","$uibModalInstance","$controller","securityGroup","application",function(t,a,n,r,i){const s=this;s.firewallLabel=U.get("Firewall"),t.pages={location:"amazon/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"},r.credentials=r.accountName,t.namePreview=r.name,e.extend(this,n("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:i,securityGroup:r})),t.state.isNew=!0,t.allowDuplicateNames=!0,t.state.isClone=!0,t.state.originRegion=r.regions&&r.regions[0],o.listAccounts("aws").then((function(e){t.accounts=e,s.accountUpdated()})),r.securityGroupIngress=$t.chain(r.inboundRules).filter((function(e){return e.securityGroup})).map((function(e){return e.portRanges.map((function(t){return{name:e.securityGroup.name,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),r.ipIngress=$t.chain(r.inboundRules).filter((function(e){return e.range})).map((function(e){return e.portRanges.map((function(t){return{cidr:e.range.ip+e.range.cidr,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),s.upsert=function(){const{credentials:e}=t.securityGroup;Object.assign(t.securityGroup,{account:e,accountName:e,accountId:e}),s.mixinUpsert("Clone")},s.initializeSecurityGroups().then(s.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="container-fluid form-horizontal">\n <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 <help-field key="aws.securityGroup.name"></help-field>\n <input\n type="hidden"\n class="form-control input-sm"\n ng-model="securityGroup.name"\n ng-model-options="{allowInvalid: true}"\n validate-unique="{{allowDuplicateNames ? \'\' : \'existingSecurityGroupNames\'}}"\n validate-ignore-case="true"\n name="securityGroupName"\n ng-pattern="ctrl.namePattern"\n trigger-validation="securityGroup.subnet"\n required\n />\n <validation-error\n ng-if="form.securityGroupName.$error.validateUnique && securityGroup.credentials"\n message="A {{ctrl.translate(\'firewall\')}} named \'{{namePreview}}\' already exists in one or more of the selected regions. Use a unique stack and detail to create a new {{ctrl.translate(\'firewall\')}}."\n ></validation-error>\n <validation-error\n ng-if="form.securityGroupName.$error.pattern"\n message="Name must match {{ctrl.getCurrentNamePattern().toString()}}"\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-8">\n <account-select-field\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'aws\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Regions</div>\n <div class="col-md-8">\n <input type="hidden" ng-model="securityGroup.regions[0]" required />\n <checklist\n ng-if="securityGroup.credentials"\n items="regions"\n model="securityGroup.regions"\n inline="true"\n on-change="ctrl.regionUpdated()"\n ></checklist>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <validation-error\n ng-if="state.regionError"\n message="A security group cannot be cloned into a region it already exists in. Please deselect \'{{state.originRegion}}\' to clear this error."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\n ng-model="securityGroup.stack"\n ng-change="ctrl.updateName()"\n />\n </div>\n <div class="col-md-2 sm-label-right">Detail</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\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-3 sm-label-right">Description (required)</div>\n <div class="col-md-8">\n <textarea required cols="2" class="form-control input-sm no-spel" ng-model="securityGroup.description">\n </textarea>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">VPC <help-field key="aws.securityGroup.vpc"></help-field></div>\n <div class="col-md-8">\n <select\n class="form-control input-sm"\n ng-model="securityGroup.vpcId"\n ng-change="ctrl.vpcUpdated()"\n ng-if="securityGroup.regions.length"\n >\n <option value="" ng-if="!hideClassic">None (EC2 Classic)</option>\n <option\n ng-repeat="vpc in activeVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n <option ng-if="activeVpcs.length && deprecatedVpcs.length" disabled>---------------</option>\n <option\n ng-repeat="vpc in deprecatedVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n </select>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <p class="form-control-static" ng-if="securityGroup.credentials && !securityGroup.regions.length">\n (Select at least one region)\n </p>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);e.module("spinnaker.amazon.securityGroup.create.controller",[Wa,Je]).controller("awsCreateSecurityGroupCtrl",["$scope","$uibModalInstance","$state","$controller","cacheInitializer","application","securityGroup",function(t,a,n,r,i,s,l){t.pages={location:"amazon/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"};const o=this;o.translate=e=>U.get(e),e.extend(this,r("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:s,securityGroup:l})),t.state.isNew=!0,o.upsert=()=>o.mixinUpsert("Create"),o.initializeSecurityGroups().then(o.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="container-fluid form-horizontal">\n <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 <help-field key="aws.securityGroup.name"></help-field>\n <input\n type="hidden"\n class="form-control input-sm"\n ng-model="securityGroup.name"\n ng-model-options="{allowInvalid: true}"\n validate-unique="{{allowDuplicateNames ? \'\' : \'existingSecurityGroupNames\'}}"\n validate-ignore-case="true"\n name="securityGroupName"\n ng-pattern="ctrl.namePattern"\n trigger-validation="securityGroup.subnet"\n required\n />\n <validation-error\n ng-if="form.securityGroupName.$error.validateUnique && securityGroup.credentials"\n message="A {{ctrl.translate(\'firewall\')}} named \'{{namePreview}}\' already exists in one or more of the selected regions. Use a unique stack and detail to create a new {{ctrl.translate(\'firewall\')}}."\n ></validation-error>\n <validation-error\n ng-if="form.securityGroupName.$error.pattern"\n message="Name must match {{ctrl.getCurrentNamePattern().toString()}}"\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-8">\n <account-select-field\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'aws\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Regions</div>\n <div class="col-md-8">\n <input type="hidden" ng-model="securityGroup.regions[0]" required />\n <checklist\n ng-if="securityGroup.credentials"\n items="regions"\n model="securityGroup.regions"\n inline="true"\n on-change="ctrl.regionUpdated()"\n ></checklist>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <validation-error\n ng-if="state.regionError"\n message="A security group cannot be cloned into a region it already exists in. Please deselect \'{{state.originRegion}}\' to clear this error."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\n ng-model="securityGroup.stack"\n ng-change="ctrl.updateName()"\n />\n </div>\n <div class="col-md-2 sm-label-right">Detail</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\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-3 sm-label-right">Description (required)</div>\n <div class="col-md-8">\n <textarea required cols="2" class="form-control input-sm no-spel" ng-model="securityGroup.description">\n </textarea>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">VPC <help-field key="aws.securityGroup.vpc"></help-field></div>\n <div class="col-md-8">\n <select\n class="form-control input-sm"\n ng-model="securityGroup.vpcId"\n ng-change="ctrl.vpcUpdated()"\n ng-if="securityGroup.regions.length"\n >\n <option value="" ng-if="!hideClassic">None (EC2 Classic)</option>\n <option\n ng-repeat="vpc in activeVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n <option ng-if="activeVpcs.length && deprecatedVpcs.length" disabled>---------------</option>\n <option\n ng-repeat="vpc in deprecatedVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n </select>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <p class="form-control-static" ng-if="securityGroup.credentials && !securityGroup.regions.length">\n (Select at least one region)\n </p>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);e.module("spinnaker.amazon.securityGroup.edit.controller",[Wa]).controller("awsEditSecurityGroupCtrl",["$scope","$uibModalInstance","$state","application","securityGroup","$controller",function(t,a,n,r,i,s){t.self=t,t.pages={ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"},t.securityGroup=i,t.state={refreshingSecurityGroups:!1},t.securityGroup.regions=[t.securityGroup.region],t.securityGroup.credentials=t.securityGroup.accountName,e.extend(this,s("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:r,securityGroup:i})),t.state.isNew=!1,t.taskMonitor=new v({application:r,title:`Updating your ${U.get("firewall")}`,modalInstance:a,onTaskComplete:()=>r.securityGroups.refresh()}),i.securityGroupIngress=$t.chain(i.inboundRules).filter((e=>e.securityGroup)).map((e=>e.portRanges.map((t=>{const a=e.securityGroup.vpcId===i.vpcId?null:e.securityGroup.vpcId;return{accountName:e.securityGroup.accountName||e.securityGroup.accountId,accountId:e.securityGroup.accountId,vpcId:a,id:e.securityGroup.id,name:e.securityGroup.inferredName?null:e.securityGroup.name,type:e.protocol,startPort:t.startPort,endPort:t.endPort,existing:!0}})))).flatten().value(),i.ipIngress=$t.chain(i.inboundRules).filter((function(e){return e.range})).map((function(e){return e.portRanges.map((function(t){return{cidr:e.range.ip+e.range.cidr,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),this.upsert=function(){const e=t.securityGroup,a={credentials:e.accountName,name:e.name,description:e.description,vpcId:e.vpcId,region:e.region,securityGroupIngress:e.securityGroupIngress,ipIngress:e.ipIngress};t.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(a,r,"Update")}))},this.cancel=function(){a.dismiss()},this.initializeSecurityGroups().then(this.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);const di={bindings:{rule:"=",securityGroup:"=",accounts:"=",vpcs:"=",allSecurityGroups:"=",coordinatesChanged:"=",allSecurityGroupsUpdated:"="},templateUrl:"amazon/src/securityGroup/configure/ingressRuleGroupSelector.component.html",controller:class{constructor(){this.infiniteScroll={currentItems:20}}addMoreItems(){this.infiniteScroll.currentItems+=20}resetCurrentItems(){this.infiniteScroll.currentItems=20}addRegionalVpc(e){const t=e.account;this.regionalVpcs[t]||(this.regionalVpcs[t]=[]),this.regionalVpcs[t].push({name:e.name,region:e.region,account:t,id:e.id,label:e.label,deprecated:e.deprecated,cloudProvider:e.cloudProvider})}enableCrossAccount(){var e;this.rule.crossAccountEnabled=!0,this.crossAccountAccounts=this.accounts;const t=null==(e=gn)?void 0:e.crossAccountIngressExclusions[this.securityGroup.credentials];t&&Array.isArray(t)&&(this.crossAccountAccounts=this.accounts.filter((e=>!t.includes(e.name)))),this.rule.accountName=this.securityGroup.credentials,this.rule.vpcId=this.securityGroup.vpcId}disableCrossAccount(){this.rule.crossAccountEnabled=!1,this.rule.accountName=void 0,this.rule.vpcId=void 0}$onInit(){this.setAvailableSecurityGroups(),this.coordinatesChangedListener=this.coordinatesChanged.subscribe((()=>this.setAvailableSecurityGroups())),this.securityGroupsUpdatedListener=this.allSecurityGroupsUpdated.subscribe((()=>this.setAvailableSecurityGroups()))}$onDestroy(){this.coordinatesChangedListener.unsubscribe(),this.securityGroupsUpdatedListener.unsubscribe()}setAvailableSecurityGroups(){const e=this.rule.accountName||this.securityGroup.credentials,t=this.securityGroup.regions,a=this.rule.vpcId||this.securityGroup.vpcId||null;let n=[],r=[];t.length>1&&this.disableCrossAccount(),t.forEach((t=>{var i,s,l,o;let c=null;if(a){const n=this.vpcs.find((e=>e.id===a)),r=this.vpcs.find((a=>a.account===e&&a.region===t&&a.name===n.name));c=r?r.id:void 0}const d=(null!=(o=null==(l=null==(s=null==(i=this.allSecurityGroups)?void 0:i[e])?void 0:s.aws)?void 0:l[t])?o:[]).filter((e=>e.vpcId===c)).map((e=>e.name));n=_t(n.concat(d)),r=r.length?la(r,d):n})),1===t.length&&this.configureAvailableVpcs(),this.availableSecurityGroups=r,r.includes(this.rule.name)||this.rule.existing||(this.rule.name=null)}configureAvailableVpcs(){const e=this.securityGroup.regions[0],t=this.vpcs.filter((t=>t.region===e));this.regionalVpcs={},t.forEach((e=>this.addRegionalVpc(e))),this.reconcileRuleVpc(t)}reconcileRuleVpc(e){if(this.rule.vpcId&&!this.rule.existing){if(!this.securityGroup.vpcId)return this.rule.vpcId=null,void(this.rule.name=null);const t=e.find((e=>e.id===this.rule.vpcId)),a=e.find((e=>e.account===this.rule.accountName&&e.name===t.name));a?this.rule.vpcId=a.id:(this.rule.vpcId=null,this.rule.name=null)}}}};t("spinnaker.amazon.securityGroup.configure.ingressRuleGroupSelector",[]).component("ingressRuleGroupSelector",di),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/ingressRuleGroupSelector.component.html",'<span class="form-control-static" ng-if="$ctrl.rule.existing">\n <account-tag\n account="$ctrl.rule.accountName"\n ng-if="$ctrl.rule.accountName !== $ctrl.securityGroup.accountName"\n ></account-tag>\n {{ $ctrl.rule.name || $ctrl.rule.id }}\n</span>\n\n<div ng-if="$ctrl.rule.crossAccountEnabled && $ctrl.securityGroup.regions.length === 1" class="cross-account-select">\n <div class="row">\n <div class="col-md-3"><span class="small">Account</span></div>\n <div class="col-md-9">\n <account-select-field\n component="$ctrl.rule"\n field="accountName"\n accounts="$ctrl.crossAccountAccounts"\n provider="\'aws\'"\n on-change="$ctrl.setAvailableSecurityGroups()"\n ></account-select-field>\n </div>\n </div>\n <div class="row" ng-if="$ctrl.securityGroup.vpcId">\n <div class="col-md-3"><span class="small">VPC</span></div>\n <div class="col-md-9">\n <select class="form-control input-sm" ng-model="$ctrl.rule.vpcId" ng-change="$ctrl.setAvailableSecurityGroups()">\n <option\n ng-repeat="vpc in $ctrl.regionalVpcs[$ctrl.rule.accountName]"\n value="{{ vpc.id }}"\n ng-selected="$ctrl.rule.vpcId === vpc.id"\n >\n {{ vpc.label }}\n </option>\n </select>\n </div>\n </div>\n</div>\n\n<div class="row">\n <div class="col-md-3">\n <span class="small" ng-if="$ctrl.rule.crossAccountEnabled">Group</span>\n </div>\n <div class="col-md-{{ $ctrl.rule.crossAccountEnabled ? 9 : 12 }}">\n <ui-select\n ng-if="!$ctrl.rule.existing"\n ng-model="$ctrl.rule.name"\n uis-open-close="$ctrl.resetCurrentItems()"\n class="form-control input-sm"\n required\n style="width: 100%"\n >\n <ui-select-match>{{ $select.selected }}</ui-select-match>\n <ui-select-choices\n repeat="securityGroup as securityGroup in $ctrl.availableSecurityGroups | filter: $select.search | limitTo: $ctrl.infiniteScroll.currentItems"\n infinite-scroll="$ctrl.addMoreItems()"\n infinite-scroll-distance="4"\n >\n <span ng-bind-html="securityGroup | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n</div>\n\n<a\n href\n class="small"\n ng-if="!$ctrl.rule.existing && $ctrl.securityGroup.regions.length === 1 && !$ctrl.rule.crossAccountEnabled"\n ng-click="$ctrl.enableCrossAccount($index)"\n>\n Select from a different account <span ng-if="$ctrl.securityGroup.vpcId">or VPC</span>\n</a>\n\n<div ng-if="$ctrl.crossAccountAccounts && $ctrl.crossAccountAccounts.length !== $ctrl.accounts.length">\n <help-field key="aws.securityGroup.cross.account.ingress.help" expand="true"></help-field>\n</div>\n<span ng-if="$ctrl.securityGroup.regions.length > 1" class="small">\n Cross-account rules disabled when 2+ regions selected\n</span>\n')}]);var pi=Object.defineProperty,ui=Object.getOwnPropertyDescriptor;let mi=class extends Bt.Component{render(){return null}};mi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?ui(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&pi(t,a,i),i})([ce("aws.securityGroup.details.custom")],mi);t("spinnaker.amazon.securityGroups.details.custom.component",[]).component("securityGroupDetailsCustom",Va(F(mi,"securityGroupDetailsCustom"),["securityGroupDetails","ctrl","scope"]));e.module("spinnaker.amazon.securityGroup.details.controller",[Wa,Te,"spinnaker.amazon.securityGroup.clone.controller",xe]).controller("awsSecurityGroupDetailsCtrl",["$scope","$state","resolvedSecurityGroup","app","securityGroupReader","$uibModal",function(t,a,n,r,i,s){this.application=r;const l=r,o=n;function c(){return i.getSecurityGroupDetails(l,o.accountId,o.provider,o.region,o.vpcId,o.name).then((function(e){return xn.getVpcName(e.vpcId).then((t=>(e.vpcName=t,e)))})).then((function(a){if(t.state.loading=!1,!a||$t.isEmpty(a))p();else{const n=i.getApplicationSecurityGroup(l,o.accountId,o.region,o.name);e.extend(o,n,a),t.securityGroup=o,t.ipRules=function(e){const t=$t.groupBy(e.ipRangeRules,(e=>e.range.ip+e.range.cidr));return Object.keys(t).map((e=>({address:e,rules:d(t,e)}))).filter((e=>e.rules.length))}(o),t.securityGroupRules=function(e){const t=$t.groupBy(e.securityGroupRules,(e=>e.securityGroup.id));return Object.keys(t).map((e=>({securityGroup:t[e][0].securityGroup,rules:d(t,e)}))).filter((e=>e.rules.length))}(o)}}),p)}function d(e,t){const a=[];return e[t].forEach((e=>{(e.portRanges||[]).forEach((t=>{("-1"===e.protocol||void 0!==t.startPort&&void 0!==t.endPort)&&a.push({startPort:t.startPort,endPort:t.endPort,protocol:e.protocol,description:e.description})}))})),a}function p(){t.$$destroyed||(r.isStandalone?(t.group=o.name,t.state.notFound=!0,t.state.loading=!1,V.removeLastItem("securityGroups")):a.go("^",{allowModalToStayOpen:!0},{location:"replace"}))}this.firewallLabel=U.get("Firewall"),t.detailsTemplateUrl=O.getValue("aws","securityGroup.detailsTemplateUrl"),t.state={loading:!0,standalone:r.isStandalone},c().then((()=>{t.$$destroyed||r.isStandalone||r.securityGroups.onRefresh(t,c)})),this.editInboundRules=function(){et(t.securityGroup,l).then((a=>new Promise((e=>setTimeout(e,500))).then((()=>{a&&s.open({templateUrl:"amazon/src/securityGroup/configure/editSecurityGroup.html",controller:"awsEditSecurityGroupCtrl as ctrl",size:"lg",resolve:{securityGroup:function(){return e.copy(t.securityGroup)},application:function(){return l}}})}))))},this.cloneSecurityGroup=function(){s.open({templateUrl:"amazon/src/securityGroup/clone/cloneSecurityGroup.html",controller:"awsCloneSecurityGroupController as ctrl",size:"lg",resolve:{securityGroup:function(){const a=e.copy(t.securityGroup);return a.region&&(a.regions=[a.region]),a},application:function(){return l}}})},this.deleteSecurityGroup=function(){let e=!1;const a={removeDependencies:!0},n={application:l,title:"Deleting "+o.name,onTaskRetry:()=>{e=!0}},r=()=>{const t={cloudProvider:o.provider,vpcId:o.vpcId};return e&&Object.assign(t,a),Xe.deleteSecurityGroup(o,l,t)};et(t.securityGroup,l).then((e=>{e&&k.confirm({header:"Really delete "+o.name+"?",buttonText:"Delete "+o.name,account:o.accountId,taskMonitorConfig:n,submitMethod:r,retryBody:`<div><p>Retry deleting the ${U.get("firewall")} and revoke any dependent ingress rules?</p><p>Any instance or load balancer associations will have to removed manually.</p></div>`})}))},r.isStandalone&&(r.securityGroups={refresh:c})}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/editSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard\n heading="Edit {{securityGroup.name}}: {{securityGroup.region}}: {{securityGroup.accountName}}"\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 class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="form.$invalid || !wizard.isComplete() || state.submitting || !customComponentIsvalid"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="state.isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/clone/cloneSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard heading="Clone {{ctrl.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" mark-clean-on-view="false">\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="form.$invalid || !wizard.isComplete() || state.submitting || state.removedRules.length > 0 || !customComponentIsvalid || state.regionError"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]);var gi=Object.defineProperty,hi=Object.getOwnPropertyDescriptor;let fi=class extends Bt.Component{render(){const e=this.props.ipRules||[],t=`IP Range Rules (${e.length})`;return Bt.createElement(A,{heading:t},e.map((e=>Bt.createElement(q,{className:"horizontal-when-filters-collapsed"},Bt.createElement(B,{label:"IP Range",value:e.address}),Bt.createElement(B,{label:"Port Ranges",value:e.rules.map((t=>"-1"===t.protocol?Bt.createElement("span",null,"All ports and protocols",e.rules.length>1?Bt.createElement("div",null,Bt.createElement("em",null,"Additional port ranges are specified, but redundant:")):null):Bt.createElement("div",null,Bt.createElement("span",null,t.protocol,":",t.startPort," → ",t.endPort))))})))))}};fi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?hi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&gi(t,a,i),i})([ce("aws.securityGroup.ip.rules")],fi);t("spinnaker.amazon.securityGroups.details.securityGroups.component",[]).component("ipRangeRules",Va(F(fi,"ipRangeRules"),["ipRules"]));class vi{resolveIndexedSecurityGroup(e,t,a){return vi.resolveIndexedSecurityGroup(e,t,a)}static resolveIndexedSecurityGroup(e,t,a){return e[t.account][t.region][a]}}t("spinnaker.amazon.securityGroup.reader",[]).service("awsSecurityGroupReader",vi);t("spinnaker.amazon.securityGroup.transformer",[]).factory("awsSecurityGroupTransformer",(function(){return{normalizeSecurityGroup:function(e){return xn.listVpcs().then(function(e){return function(t){const a=t.filter((function(t){return t.id===e.vpcId}));e.vpcName=a.length?a[0].name:""}}(e))},compress:function(e){const t=Wt(e,"vpcId");return Object.keys(t).forEach((e=>{t[e]=t[e].map((e=>[e.name,e.id]))})),t},decompress:function(e){const t=[];return Object.keys(e).forEach((a=>{e[a].forEach((e=>{t.push({name:e[0],id:e[1],vpcId:a})}))})),t},supportsCompression:!0}}));t("spinnaker.amazon.securityGroup",["spinnaker.amazon.securityGroup.reader","spinnaker.amazon.securityGroup.clone.controller","spinnaker.amazon.securityGroup.configure.ingressRuleGroupSelector","spinnaker.amazon.securityGroup.baseConfig.controller","spinnaker.amazon.securityGroup.create.controller","spinnaker.amazon.securityGroup.edit.controller","spinnaker.amazon.securityGroup.details.controller","spinnaker.amazon.securityGroup.transformer","spinnaker.amazon.securityGroups.details.securityGroups.component","spinnaker.amazon.securityGroups.details.custom.component"]);class yi extends Bt.Component{constructor(e){super(e),this.state={templateSelectionText:{copied:["account, region, subnet, cluster name (stack, details)","load balancers",U.get("firewalls"),"instance type","all fields on the Advanced Settings page"],notCopied:["the following suspended scaling processes: Launch, Terminate, AddToLoadBalancer"],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.state.templateSelectionText.notCopied.push("the deployment strategy (if any) used to deploy the most recent server group")}render(){const{app:e,command:t,onDismiss:a,onTemplateSelected:n}=this.props,{templateSelectionText:r}=this.state;return Bt.createElement(tt,{cloudProvider:"aws",application:e,command:t,onDismiss:a,onTemplateSelected:n,templateSelectionText:r})}}class bi extends Bt.Component{constructor(){super(...arguments),this.state={errorMessage:null,selectionMode:"packageImages",searchString:"",searchResults:null,isSearching:!1,packageImages:null,isLoadingPackageImages:!0},this.awsImageReader=new Wn,this.props$=new fa,this.searchInput$=new fa,this.destroy$=new fa,this.sortImagesBy$=new ba("ts"),this.buildImageMenu=e=>{const{ImageMenuHeading:t,ImageLabel:a}=this,{options:n}=e;return Bt.createElement("div",{className:"Select-menu-outer"},Bt.createElement("div",{className:"Select-menu",role:"listbox"},n.length>0&&Bt.createElement(t,null),n.map((t=>Bt.createElement(a,{key:t.imageName,option:t,params:e})))))},this.ImageMenuHeading=()=>{const e=this.sortImagesBy$.value;return Bt.createElement("div",{className:"sp-padding-s-xaxis sp-padding-xs-yaxis small",style:{borderBottom:"1px solid var(--color-silver)",position:"sticky",top:0,backgroundColor:"var(--color-white)"}},Bt.createElement("b",null,"Sort by: "),Bt.createElement("a",{className:"clickable sp-padding-xs-xaxis",onClick:()=>this.setSortImagesBy("ts")},"ts"===e?Bt.createElement("b",null,"timestamp (newest first)"):"timestamp (newest first)"),Bt.createElement("span",null," | "),Bt.createElement("a",{className:"clickable sp-padding-xs-xaxis",onClick:()=>this.setSortImagesBy("name")},"name"===e?Bt.createElement("b",null,"name (A-Z)"):"name (A-Z)"))},this.ImageLabel=e=>{const{credentials:t,region:a}=this.props,{option:n,params:r}=e,i=n.amis[a]&&n.amis[a][0]?n.amis[a][0]:` - not found in ${t}/${a}`;return Bt.createElement("div",{key:n.imageName,onClick:()=>r.selectValue(n),onMouseOver:()=>r.focusOption(n),className:"Select-option "+(r.focusedOption&&r.focusedOption.imageName===n.imageName?"is-focused":""),role:"option"},Bt.createElement("div",null,n.imageName),Bt.createElement("div",{className:"small"},Bt.createElement("b",null,"Created: "),n.attributes.creationDate,Bt.createElement("b",{className:"sp-padding-s-left"},"AMI: "),i))}}static makeFakeImage(e,t,a){if(!e&&!t)return null;return{imageName:e,amis:{[a]:[t]},attributes:{virtualizationType:"*",creationDate:(new Date).toISOString()}}}loadImagesFromApplicationName(e){const t=e.name.replace(/_/g,"[_\\-]")+"*";return this.awsImageReader.findImages({q:t})}buildQueryForSimilarImages(e){let t=!1,a=e.split("_")[0];const n=a.split("-");n.length>3&&(a=n.slice(0,-3).join("-"),t=!0);return!a||a.length<3?null:a+(t?"-*":"*")}loadImageById(e,t,a){return e?this.awsImageReader.getImage(e,t,a).catch((()=>null)):Ua.when(null)}searchForImages(e){return e&&e.length>=3?this.awsImageReader.findImages({q:e}):Ua.when([])}fetchPackageImages(e,t,a,n){const r=e&&e.amis&&e.amis[t]&&e.amis[t][0];return this.loadImageById(r,t,a).then((e=>e?this.searchForImages(this.buildQueryForSimilarImages(e.imageName)).then((t=>t.find((t=>t.imageName===e.imageName))?t:t.concat(e))):this.loadImagesFromApplicationName(n)))}selectImage(e){this.props.value!==e&&this.props.onChange(e)}findMatchingImage(e,t){return e.find((e=>t&&t.imageName===e.imageName))}componentDidMount(){const e=this.props$.pipe(Ca((e=>e.region)),ka()),{value:t,region:a,credentials:n,application:r}=this.props;this.setState({isLoadingPackageImages:!0});const i=this.fetchPackageImages(t,a,n,r),s=va(i).pipe(Aa((e=>(console.error(e),this.setState({errorMessage:"Unable to load package images"}),wa([])))),Ia((()=>this.setState({isLoadingPackageImages:!1})))),l=ya([s,e,this.sortImagesBy$]).pipe(Ca((([e,t,a])=>{const n=e.filter((e=>!!e.amis[t]));return this.sortImages(n,a)}))),o=this.searchInput$.pipe(Ia((e=>this.setState({searchString:e}))),ka(),Pa(250)).pipe(Ia((()=>this.setState({isSearching:!0}))),Ga((e=>this.searchForImages(e))),Aa((e=>(console.error(e),this.setState({errorMessage:"Unable to search for images"}),wa([])))),Ia((()=>this.setState({isSearching:!1}))));ya([o,e,this.sortImagesBy$]).pipe(Ca((([e,t,a])=>{const{searchString:n}=this.state;if(0===e.length&&/ami-[0-9a-f]{8,17}/.exec(n)){return[bi.makeFakeImage(n,n,t)].filter((e=>!!e))}const r=e.filter((e=>!!e.amis[t]));return this.sortImages(r,a)}))).pipe(Ta(this.destroy$)).subscribe((e=>this.setState({searchResults:e}))),l.pipe(Ta(this.destroy$)).subscribe((e=>{this.setState({packageImages:e}),this.selectImage(this.findMatchingImage(e,this.props.value))})),e.pipe(Ga((e=>{const t=this.props.value;if("packageImages"===this.state.selectionMode)return l.pipe(Ca((e=>this.findMatchingImage(e,t))));{const a=!!(t&&t.amis&&t.amis[e]);return wa(a?t:void 0)}})),Ta(this.destroy$)).subscribe((e=>this.selectImage(e)))}setSortImagesBy(e){this.sortImagesBy$.next(e)}sortImages(e,t){return e.slice().sort(((e,a)=>"ts"===t?a.attributes.creationDate.localeCompare(e.attributes.creationDate):e.imageName.localeCompare(a.imageName)))}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}render(){const{value:e,credentials:t,region:a,onChange:r}=this.props,{isLoadingPackageImages:i,isSearching:s,selectionMode:l,packageImages:o,searchResults:c,searchString:d}=this.state,p=!!o,u=e=>{const n=e.amis||{},r=n[a]&&n[a][0],i=r?`(${r})`:` - not found in ${t}/${a}`;return Bt.createElement(Bt.Fragment,null,Bt.createElement("span",null,e.imageName),Bt.createElement("span",null,i))},m={clearable:!1,required:!0,valueKey:"imageName",optionRenderer:u,valueRenderer:u,onSelectResetsInput:!1,onBlurResetsInput:!1,onCloseResetsInput:!1,value:e},g=this.state.errorMessage?Bt.createElement(de,{message:this.state.errorMessage,type:"error"}):null,h=`No results found in ${t}/${a}`;if("searchAllImages"===l){const e=!d||d.length<3?"Please enter at least 3 characters":s?"Searching...":h;return Bt.createElement("div",{className:"col-md-9"},Bt.createElement(f,{...m,menuRenderer:this.buildImageMenu,isLoading:s,placeholder:"Search for an image...",filterOptions:!1,noResultsText:e,options:c,onInputChange:e=>(this.searchInput$.next(e),e),onChange:r}),g)}return p?Bt.createElement("div",{className:"col-md-9"},Bt.createElement(f,{...m,menuRenderer:this.buildImageMenu,isLoading:i,placeholder:"Pick an image",noResultsText:h,options:o,onChange:r}),g,Bt.createElement("button",{type:"button",className:"link",onClick:()=>this.setState({selectionMode:"searchAllImages"})},"Search All Images")," ",Bt.createElement(n,{id:"aws.serverGroup.allImages"})):Bt.createElement("div",{className:"col-md-9"},Bt.createElement(f,{...m,isLoading:i,disabled:!0,options:[e].filter((e=>!!e))}),g,Bt.createElement("button",{type:"button",className:"link",onClick:()=>this.setState({selectionMode:"searchAllImages"})},"Search All Images")," ",Bt.createElement(n,{id:"aws.serverGroup.allImages"}))}}const wi=e=>e&&e.includes("${");class Ei extends Bt.Component{constructor(e){super(e),this.imageChanged=e=>{var t,n;const{setFieldValue:r,values:i}=this.props.formik;this.setState({selectedImage:e});const s=e&&e.attributes.virtualizationType,l=e&&e.imageName;if(i.virtualizationType=s,i.amiName=l,r("virtualizationType",s),r("amiName",l),i.imageChanged(i),e&&(null==(t=a.disabledImages)?void 0:t.length)&&(null==(n=gn.serverGroups)?void 0:n.enableIPv6)){a.disabledImages.some((t=>e.imageName.includes(t)))&&r("associateIPv6Address",!1)}},this.accountUpdated=e=>{var t,a,n,r,i,s,l,o,c,d,p;const{setFieldValue:u,values:m}=this.props.formik;m.credentials=e,m.credentialsChanged(m),m.subnetChanged(m),u("credentials",e);const g=m.backingData.credentialsKeyedByAccount[e];if(u("associateIPv6Address",(null==(a=null==(t=gn)?void 0:t.serverGroups)?void 0:a.enableIPv6)&&(null==(r=null==(n=gn)?void 0:n.serverGroups)?void 0:r.setIPv6InTest)&&"test"===g.environment),null==(i=gn.serverGroups)?void 0:i.enableIMDSv2){const t=!(null==(o=null==(l=null==(s=gn)?void 0:s.serverGroups)?void 0:l.accountDenyListIMDSv2)?void 0:o.includes(e)),a=null==(c=gn.serverGroups)?void 0:c.defaultIMDSv2AppAgeLimit,n=null==(p=null==(d=this.props.app)?void 0:d.attributes)?void 0:p.createTs;u("requireIMDSv2",t&&a&&n&&Number(n)>a)}},this.regionUpdated=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.region=e,t.regionChanged(t),a("region",e)},this.subnetUpdated=()=>{const{setFieldValue:e,values:t}=this.props.formik;t.subnetChanged(t),e("subnetType",t.subnetType)},this.clientRequestsChanged=()=>{const{values:e,setFieldValue:t}=this.props.formik;e.toggleSuspendedProcess(e,"AddToLoadBalancer"),t("suspendedProcesses",e.suspendedProcesses),this.setState({})},this.navigateToLatestServerGroup=()=>{const{values:e}=this.props.formik,{latestServerGroup:t}=this.state,a={provider:e.selectedProvider,accountId:t.account,region:t.region,serverGroup:t.name},{$state:n}=h;n.is("home.applications.application.insight.clusters")?n.go(".serverGroup",a):n.go("^.serverGroup",a)},this.stackChanged=e=>{const{setFieldValue:t,values:a}=this.props.formik;a.stack=e,t("stack",e),a.clusterChanged(a)},this.handleReasonChanged=e=>{this.props.formik.setFieldValue("reason",e)},this.strategyChanged=(e,t)=>{e.onStrategyChange(e,t),this.props.formik.setFieldValue("strategy",t.key)},this.onStrategyFieldChange=(e,t)=>{this.props.formik.setFieldValue(e,t)};const{amiName:t,region:n,viewState:{imageId:r}}=e.formik.values,i=bi.makeFakeImage(t,r,n);this.state={...this.getStateFromProps(e),selectedImage:i}}getStateFromProps(e){const{app:t}=e,{values:a}=e.formik,n=Ee.getClusterName(t.name,a.stack,a.freeFormDetails),r=!t.clusters.find((e=>e.name===n)),i=t.serverGroups.data.filter((e=>e.cluster===n&&e.account===a.credentials&&e.region===a.region)).sort(((e,t)=>e.createdTime-t.createdTime)),s=i.length?i.pop():null;return{namePreview:n,createsNewCluster:r,latestServerGroup:s}}validate(e){const t={};var a,n;return a=e.stack,wi(a)||/^([a-zA-Z_0-9._${}]*(\${.+})*)*$/.test(a)||(t.stack="Only dot(.) and underscore(_) special characters are allowed in the Stack field."),n=e.freeFormDetails,wi(n)||/^([a-zA-Z_0-9._${}-]*(\${.+})*)*$/.test(n)||(t.freeFormDetails="Only dot(.), underscore(_), and dash(-) special characters are allowed in the Detail field."),e.viewState.disableImageSelection||e.amiName||(t.amiName="Image required."),e.resourceSummary&&(t.resourceSummary={id:"Cluster is managed"}),t}componentWillReceiveProps(e){this.setState(this.getStateFromProps(e))}render(){const{app:e,formik:t}=this.props,{errors:a,values:r}=t,{createsNewCluster:i,latestServerGroup:s,namePreview:l}=this.state,o=r.backingData.accounts,c=r.viewState.readOnlyFields||{};return Bt.createElement("div",{className:"container-fluid form-horizontal"},r.regionIsDeprecated(r)&&Bt.createElement("div",{className:"form-group row"},Bt.createElement("div",{className:"col-md-12 error-message"},Bt.createElement("div",{className:"alert alert-danger"},"You are deploying into a deprecated region within the ",r.credentials," account!"))),Bt.createElement(at,{app:e,formik:t}),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),Bt.createElement("div",{className:"col-md-7"},Bt.createElement(Ce,{value:r.credentials,onChange:e=>this.accountUpdated(e.target.value),readOnly:c.credentials,accounts:o,provider:"aws"}))),Bt.createElement(ke,{readOnly:c.region,labelColumns:3,component:r,field:"region",account:r.credentials,regions:r.backingData.filtered.regions,onChange:this.regionUpdated}),Bt.createElement(Ir,{readOnly:c.subnet,labelColumns:3,helpKey:"aws.serverGroup.subnet",component:r,field:"subnetType",region:r.region,application:e,subnets:r.backingData.filtered.subnetPurposes,onChange:this.subnetUpdated,showSubnetWarning:!0}),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",Bt.createElement(n,{id:"aws.serverGroup.stack"})),Bt.createElement("div",{className:"col-md-7"},Bt.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:r.stack,onChange:e=>this.stackChanged(e.target.value)}))),a.stack&&Bt.createElement("div",{className:"form-group row slide-in"},Bt.createElement("div",{className:"col-sm-9 col-sm-offset-2 error-message"},Bt.createElement("span",null,a.stack))),Bt.createElement(nt,{app:e,formik:t}),r.viewState.imageSourceText&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Image Source"),Bt.createElement("div",{className:"col-md-7",style:{marginTop:"5px"}},Bt.createElement(we,{tag:"span",message:r.viewState.imageSourceText}))),!r.viewState.disableImageSelection&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Image ",Bt.createElement(n,{id:"aws.serverGroup.imageName"})),wi(r.amiName)?Bt.createElement(Ja,{name:"amiName"}):Bt.createElement(bi,{onChange:e=>this.imageChanged(e),value:this.state.selectedImage,application:e,credentials:r.credentials,region:r.region})),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Traffic ",Bt.createElement(n,{id:"aws.serverGroup.traffic"})),Bt.createElement("div",{className:"col-md-9 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",onChange:this.clientRequestsChanged,checked:!r.processIsSuspended(r,"AddToLoadBalancer"),disabled:""!==r.strategy&&"custom"!==r.strategy}),"Send client requests to new instances"))),!r.viewState.disableStrategySelection&&r.selectedProvider&&Bt.createElement(rt,{command:r,onFieldChange:this.onStrategyFieldChange,onStrategyChange:this.strategyChanged}),!r.viewState.hideClusterNamePreview&&Bt.createElement(it,{createsNewCluster:i,latestServerGroupName:null==s?void 0:s.name,mode:r.viewState.mode,namePreview:l,navigateToLatestServerGroup:this.navigateToLatestServerGroup}),Bt.createElement(st,{reason:r.reason,onChange:this.handleReasonChanged}))}}class Ci extends Bt.Component{constructor(){super(...arguments),this.preferSourceCapacityOptions=[{label:"fail the stage",value:!1},{label:"use fallback values",value:!0}],this.useSourceCapacityUpdated=e=>{const t="true"===e.target.value,{command:a}=this.props;this.props.setFieldValue("useSourceCapacity",t),t||(delete a.preferSourceCapacity,this.props.setFieldValue("preferSourceCapacity",void 0)),this.setState({})},this.simpleInstancesChanged=e=>{this.setMinMax(e)},this.preferSourceCapacityChanged=e=>{this.props.setFieldValue("preferSourceCapacity",!(!e||!e.value)||void 0),this.setState({})},this.capacityFieldChanged=(e,t)=>{const{command:a,setFieldValue:n}=this.props;a.capacity={...a.capacity},a.capacity[e]=t,n("capacity",a.capacity)}}setSimpleCapacity(e){const{command:t}=this.props,a={...t.viewState,useSimpleCapacity:e};this.props.setFieldValue("useSourceCapacity",!1),this.props.setFieldValue("viewState",a),this.setMinMax(t.capacity.desired),this.setState({})}setMinMax(e){const{command:t}=this.props;t.viewState.useSimpleCapacity&&(t.capacity={min:e,max:e,desired:e},this.props.setFieldValue("useSourceCapacity",!1),this.props.setFieldValue("capacity",t.capacity)),this.setState({})}render(){const{command:e,MinMaxDesired:t}=this.props,a=e.viewState.readOnlyFields||{};return!e.viewState.useSimpleCapacity||e.useSourceCapacity?Bt.createElement("div",null,Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement("p",null,"Sets up auto-scaling constraints for this server group."),Bt.createElement("p",null,"To set min, max, and desired instance counts to the same value use the"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.setSimpleCapacity(!0)},"Simple Mode"),"."))),!a.useSourceCapacity&&"editPipeline"===e.viewState.mode&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Capacity"),Bt.createElement("div",{className:"col-md-9 radio"},Bt.createElement("label",null,Bt.createElement("input",{type:"radio",checked:e.useSourceCapacity,value:"true",id:"useSourceCapacityTrue",onChange:this.useSourceCapacityUpdated}),"Copy the capacity from the current server group",Bt.createElement(n,{id:"serverGroupCapacity.useSourceCapacityTrue"}))),e.useSourceCapacity&&Bt.createElement("div",{className:"col-md-9 col-md-offset-3 radio",style:{paddingLeft:"35px"}},Bt.createElement("div",null,"If no current server group is found,",Bt.createElement(en,{clearable:!1,value:!!e.preferSourceCapacity,options:this.preferSourceCapacityOptions,onChange:this.preferSourceCapacityChanged})),e.preferSourceCapacity&&Bt.createElement("div",null,Bt.createElement("b",null,"Fallback values"),Bt.createElement(t,{command:e,fieldChanged:this.capacityFieldChanged}))),Bt.createElement("div",{className:"col-md-9 col-md-offset-3 radio"},Bt.createElement("label",null,Bt.createElement("input",{type:"radio",checked:!e.useSourceCapacity,value:"false",id:"useSourceCapacityFalse",onChange:this.useSourceCapacityUpdated}),"Let me specify the capacity",Bt.createElement(n,{id:"serverGroupCapacity.useSourceCapacityFalse"})))),(!e.useSourceCapacity||"editPipeline"!==e.viewState.mode)&&Bt.createElement("div",null,Bt.createElement("div",{className:"col-md-9 col-md-offset-3"},Bt.createElement(t,{command:e,fieldChanged:this.capacityFieldChanged})))):Bt.createElement("div",null,Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement("p",null,"Sets the min, max, and desired instance counts to the same value."),Bt.createElement("p",null," ","To set capacity for auto-scaling, use the"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.setSimpleCapacity(!1)},"Advanced Mode"),"."))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Number of Instances"),Bt.createElement("div",{className:"col-md-8"},Bt.createElement(he,{value:e.capacity.desired,min:0,onChange:this.simpleInstancesChanged}))))}}class ki extends Bt.Component{render(){const{command:{capacity:{min:e,max:t,desired:a}},fieldChanged:n}=this.props;return Bt.createElement("div",null,Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-2"},"Min"),Bt.createElement("div",{className:"col-md-8"},Bt.createElement(he,{value:e,min:0,max:"number"==typeof t?t:void 0,onChange:e=>n("min",e),required:!0}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-2"},"Max"),Bt.createElement("div",{className:"col-md-8"},Bt.createElement(he,{value:t,min:"number"==typeof e?e:void 0,onChange:e=>n("max",e),required:!0}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-2"},"Desired"),Bt.createElement("div",{className:"col-md-8"},Bt.createElement(he,{value:a,min:"number"==typeof e?e:void 0,max:"number"==typeof t?t:void 0,onChange:e=>n("desired",e),required:!0}))))}}class Si extends Bt.Component{validate(e){const t={};(e.capacity.min<0||e.capacity.max<0||e.capacity.desired<0)&&(t.capacity="Capacity min, max, and desired all have to be non-negative values.");const a=e;return void 0!==a.targetHealthyDeployPercentage&&null!==a.targetHealthyDeployPercentage||(t.targetHealthyDeployPercentage="Target Healthy Deploy Percentage required."),t}render(){const{setFieldValue:e,values:t}=this.props.formik;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"row"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement(Ci,{command:t,setFieldValue:e,MinMaxDesired:ki}))),Bt.createElement("div",{className:"row"},Bt.createElement("div",{className:"col-md-12"},Bt.createElement("div",{className:"form-group form-inline",style:{marginTop:"20px"}},Bt.createElement("div",{className:"col-md-12"},"Consider deployment successful when"," ",Bt.createElement(Ja,{type:"number",name:"targetHealthyDeployPercentage",min:"0",max:"100",className:"form-control input-sm inline-number",required:!0})," ","percent of instances are healthy.")))))}}function Gi(e){const[t,a]=Bt.useState(!1);Bt.useEffect((()=>{if(e.newInstanceType){const t=Un.awsInstanceTypeService.isBurstingSupported(e.newInstanceType);t||e.setUnlimitedCpuCredits(void 0),a(t)}if(e.newProfileType){const{instanceType:t}=e.command,n=Un.awsInstanceTypeService.isInstanceTypeInCategory(t,e.newProfileType),r=Un.awsInstanceTypeService.isBurstingSupported(t);a(t&&n&&r)}}),[e.newProfileType,e.newInstanceType]);return Bt.createElement("div",null,t&&Bt.createElement("div",{className:"row"},Bt.createElement(lt,{toggleSize:ot.XSMALL,propLabel:"Unlimited CPU credits ",propHelpFieldId:"aws.serverGroup.unlimitedCpuCredits",tooltipPropOffBtn:"Toggle to turn OFF unlimited CPU credits",displayTextPropOffBtn:"Off",tooltipPropOnBtn:"Toggle to turn ON unlimited CPU credits",displayTextPropOnBtn:"On",onClick:t=>{e.setUnlimitedCpuCredits(t)},isPropertyActive:e.command.unlimitedCpuCredits})))}class Ni extends Bt.Component{constructor(e){super(e),this.instanceProfileChanged=e=>{this.setState({newProfileType:e,newInstanceType:void 0})},this.instanceTypeChanged=e=>{const{values:t}=this.props.formik;t.instanceTypeChanged(t),this.props.formik.setFieldValue("instanceType",e),this.setState({newInstanceType:e,newProfileType:void 0})},this.setUnlimitedCpuCredits=e=>{this.props.formik.values.unlimitedCpuCredits!==e&&(this.props.formik.setFieldValue("unlimitedCpuCredits",e),this.setState({}))},this.state={newInstanceType:void 0,newProfileType:void 0}}validate(e){const t={};return e.instanceType||(t.instanceType="Instance Type required."),t}render(){var e,t;const{values:a}=this.props.formik,{InstanceArchetypeSelector:n,InstanceTypeSelector:r}=ct,i=!(!a.viewState.disableImageSelection&&!a.amiName),s=null==(e=gn.serverGroups)?void 0:e.enableLaunchTemplates,l=null==(t=gn.serverGroups)?void 0:t.enableCpuCredits;return i&&a?Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"row"},Bt.createElement(n,{command:a,onTypeChanged:this.instanceTypeChanged,onProfileChanged:this.instanceProfileChanged}),Bt.createElement("div",{style:{padding:"0 15px"}},a.viewState.instanceProfile&&"custom"!==a.viewState.instanceProfile&&Bt.createElement(r,{command:a,onTypeChanged:this.instanceTypeChanged}))),s&&l&&Bt.createElement("div",{className:"row"},Bt.createElement(Gi,{command:a,newInstanceType:this.state.newInstanceType,newProfileType:this.state.newProfileType,setUnlimitedCpuCredits:this.setUnlimitedCpuCredits}))):Bt.createElement("h5",{className:"text-center"},"Please select an image.")}}class Ti extends Bt.Component{constructor(){super(...arguments),this.handleAvailabilityZonesChanged=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.usePreferredZonesChanged(t),a("availabilityZones",e)},this.rebalanceToggled=()=>{const{values:e,setFieldValue:t}=this.props.formik;e.toggleSuspendedProcess(e,"AZRebalance"),t("suspendedProcesses",e.suspendedProcesses),this.setState({})}}validate(e){const t={};return e.availabilityZones&&0!==e.availabilityZones.length||(t.availabilityZones="You must select at least one availability zone."),t}render(){const{values:e}=this.props.formik;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement(Nr,{credentials:e.credentials,region:e.region,onChange:this.handleAvailabilityZonesChanged,selectedZones:e.availabilityZones,allZones:e.backingData.filtered.availabilityZones,usePreferredZones:e.viewState.usePreferredZones}),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},Bt.createElement("b",null,"AZ Rebalance")),Bt.createElement("div",{className:"col-md-7 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",onChange:this.rebalanceToggled,checked:!e.processIsSuspended(e,"AZRebalance")}),"Keep instances evenly distributed across zones"))))}}const Ii=e=>({value:e,label:e});class xi extends Bt.Component{constructor(){super(...arguments),this.state={refreshing:!1,refreshed:!1,showVpcLoadBalancers:!1},this.refreshLoadBalancers=()=>{const{values:e}=this.props.formik;this.setState({refreshing:!0});h.providerServiceDelegate.getDelegate(e.cloudProvider||e.selectedProvider,"serverGroup.configurationService").refreshLoadBalancers(e).then((()=>{this.setState({refreshing:!1,refreshed:!0})}))},this.targetGroupsChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("targetGroups",t)},this.loadBalancersChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("loadBalancers",t)},this.vpcLoadBalancersChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("vpcLoadBalancers",t)}}validate(e){const t={};return e.viewState.dirty.targetGroups&&(t.targetGroups="You must confirm the removed target groups."),e.viewState.dirty.loadBalancers&&(t.loadBalancers="You must confirm the removed load balancers."),t}clearWarnings(e){this.props.formik.values.viewState.dirty[e]=null,this.props.formik.validateForm()}render(){var e;const{hideLoadBalancers:t,hideTargetGroups:a}=this.props,{values:r}=this.props.formik,{dirty:i}=r.viewState,{refreshed:s,refreshing:l,showVpcLoadBalancers:o}=this.state;let c=null;if(!a){const t=(r.backingData.filtered.targetGroups||[]).concat(r.viewState.spelTargetGroups||[]).map(Ii);c=Bt.createElement(Bt.Fragment,null,i.targetGroups&&Bt.createElement("div",{className:"col-md-12"},Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following target groups could not be found in the selected account/region/VPC and were removed:"),Bt.createElement("ul",null,i.targetGroups.map((e=>Bt.createElement("li",{key:e},e)))),Bt.createElement("p",{className:"text-right"},Bt.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:()=>this.clearWarnings("targetGroups")},"Okay")))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-4 sm-label-right"},Bt.createElement("b",null,"Target Groups "),Bt.createElement(n,{id:"aws.loadBalancer.targetGroups"})),Bt.createElement("div",{className:"col-md-7"},0===t.length&&Bt.createElement("div",{className:"form-control-static"},"No ",Bt.createElement("b",null,null!=(e=this.props.targetGroupTypeHelpText)?e:"instance")," target groups found in the selected account/region/VPC"),t.length>0&&Bt.createElement(f,{multi:!0,options:t,value:r.targetGroups,onChange:this.targetGroupsChanged}))))}let d=null;if(!t){const e=(r.backingData.filtered.loadBalancers||[]).concat(r.viewState.spelLoadBalancers||[]).map(Ii),t=(r.backingData.filtered.vpcLoadBalancers||[]).map(Ii),a=r.vpcLoadBalancers&&r.vpcLoadBalancers.length>0;d=Bt.createElement(Bt.Fragment,null,i.loadBalancers&&Bt.createElement("div",{className:"col-md-12"},Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following load balancers could not be found in the selected account/region/VPC and were removed:"),Bt.createElement("ul",null,i.loadBalancers.map((e=>Bt.createElement("li",{key:e},e)))),Bt.createElement("p",{className:"text-right"},Bt.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:()=>this.clearWarnings("loadBalancers")},"Okay")))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-4 sm-label-right"},Bt.createElement("b",null,"Classic Load Balancers "),Bt.createElement(n,{id:"aws.loadBalancer.loadBalancers"})),Bt.createElement("div",{className:"col-md-7"},0===e.length&&Bt.createElement("div",{className:"form-control-static"},"No load balancers found in the selected account/region/VPC"),e.length>0&&Bt.createElement(f,{multi:!0,options:e,value:r.loadBalancers,onChange:this.loadBalancersChanged}))),!r.vpcId&&Bt.createElement("div",{className:"form-group"},!a&&!o&&Bt.createElement("div",null,Bt.createElement("div",{className:"col-md-8 col-md-offset-3"},Bt.createElement("a",{className:"clickable",onClick:()=>this.setState({showVpcLoadBalancers:!0})},"Add VPC Load Balancers"))),a&&Bt.createElement("div",null,Bt.createElement("div",{className:"col-md-4 sm-label-right"},Bt.createElement("b",null,"VPC Load Balancers")),Bt.createElement("div",{className:"col-md-8"},t.length>0&&Bt.createElement(f,{multi:!0,options:t,value:r.vpcLoadBalancers,onChange:this.vpcLoadBalancersChanged})))),!s&&Bt.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},Bt.createElement("div",{className:"col-md-8 col-md-offset-4"},l&&Bt.createElement("p",null,Bt.createElement("span",{className:"fa fa-sync-alt fa-spin"}),Bt.createElement("span",null," refreshing...")),!l&&Bt.createElement("p",null,"If you are looking for a load balancer or target group from a different application, ",Bt.createElement("br",null),Bt.createElement("a",{className:"clickable",onClick:this.refreshLoadBalancers},"click here")," ","to load all load balancers."))))}return Bt.createElement("div",{className:"container-fluid form-horizontal"},c,d)}}class Ai extends Bt.Component{constructor(e){super(e),this.refreshSecurityGroups=()=>{this.setState({refreshing:!0}),this.props.refresh?this.props.refresh().then((()=>this.setState({refreshing:!1}))):h.providerServiceDelegate.getDelegate(this.props.command.selectedProvider,"serverGroup.configurationService").refreshSecurityGroups(this.props.command).then((()=>{this.setState({refreshing:!1,refreshTime:Se.get("securityGroups").getStats().ageMax})}))},this.onChange=e=>{const t=e.map((e=>e.value));this.props.onChange(t)},this.state={refreshing:!1,refreshTime:Se.get("securityGroups").getStats().ageMax}}render(){const{availableGroups:e,groupsToEdit:t,helpKey:a,hideLabel:r}=this.props,{refreshing:i,refreshTime:s}=this.state,l=e.map((e=>({label:`${e.name} (${e.id})`,value:e.id})));return Bt.createElement(Bt.Fragment,null,Bt.createElement("div",{className:"form-group"},!r&&Bt.createElement("div",{className:"col-md-3 sm-label-right"},Bt.createElement("b",null,U.get("Firewalls")),a&&Bt.createElement(n,{key:a})),Bt.createElement("div",{className:"col-md-8"},Bt.createElement(tn,{ignoreAccents:!0,options:l,onChange:this.onChange,value:t,multi:!0}))),Bt.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},Bt.createElement("div",{className:`col-md-${r?12:9} col-md-offset-${r?0:3}`},Bt.createElement("p",null,i&&Bt.createElement("span",null,Bt.createElement("span",{className:"fa fa-sync-alt fa-spin"})),U.get("Firewalls"),!i&&Bt.createElement("span",null," last refreshed ",D(s)),i&&Bt.createElement("span",null," refreshing...")),Bt.createElement("p",null,"If you're not finding a ",U.get("firewall")," that was recently added,"," ",Bt.createElement("a",{className:"clickable",onClick:this.refreshSecurityGroups},"click here")," ","to refresh the list."))))}}class Pi extends Bt.Component{render(){const{command:e,onClear:t,removed:a}=this.props,n=(e&&e.viewState.dirty.securityGroups||[]).concat(a||[]);return 0===n.length?null:Bt.createElement("div",{className:"col-md-12"},Bt.createElement("div",{className:"alert alert-warning"},Bt.createElement("p",null,Bt.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following ",U.get("firewalls")," could not be found in the selected account/region/VPC and were removed:"),Bt.createElement("ul",null,n.map((e=>Bt.createElement("li",{key:e},e)))),Bt.createElement("p",{className:"text-right"},Bt.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:t},"Okay"))))}}Pi.defaultProps={onClear:C};class zi extends Bt.Component{constructor(){super(...arguments),this.onChange=e=>{this.props.formik.setFieldValue("securityGroups",e)},this.acknowledgeRemovedGroups=()=>{const{viewState:e}=this.props.formik.values;e.dirty.securityGroups=null,this.props.formik.setFieldValue("viewState",e)}}validate(e){const t={};return e.viewState.dirty.securityGroups&&(t.securityGroups="You must acknowledge removed security groups."),t}render(){const{values:e}=this.props.formik;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement(Pi,{command:e,onClear:this.acknowledgeRemovedGroups}),Bt.createElement(Ai,{command:e,availableGroups:e.backingData.filtered.securityGroups,groupsToEdit:e.securityGroups,onChange:this.onChange}))}}class Bi extends Bt.Component{constructor(){super(...arguments),this.duplicateKeys=!1,this.validate=e=>{const t={};return e.keyPair||(t.keyPair="Key Name is required"),this.duplicateKeys&&(t.tags="Tags have duplicate keys."),t},this.selectBlockDeviceMappingsSource=e=>{const{values:t}=this.props.formik;t.selectBlockDeviceMappingsSource(t,e),this.setState({})},this.toggleSuspendedProcess=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.toggleSuspendedProcess(t,e),a("suspendedProcesses",t.suspendedProcesses),this.setState({})},this.platformHealthOverrideChanged=e=>{this.props.formik.setFieldValue("interestingHealthProviderNames",e)},this.tagsChanged=(e,t)=>{this.duplicateKeys=t,this.props.formik.setFieldValue("tags",e)}}render(){const{app:e}=this.props,{setFieldValue:t,values:a}=this.props.formik,r=a.getBlockDeviceMappingsSource(a),i=a.backingData.filtered.keyPairs||[],s=gn.serverGroups;return Bt.createElement("div",{className:"container-fluid form-horizontal"},Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Cooldown")),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(Ja,{type:"text",required:!0,name:"cooldown",className:"form-control input-sm no-spel"}))," ","seconds"),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Enabled Metrics "),Bt.createElement(n,{id:"aws.serverGroup.enabledMetrics"})),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(en,{multi:!0,value:a.enabledMetrics,options:a.backingData.enabledMetrics.map((e=>({label:e,value:e}))),onChange:e=>t("enabledMetrics",e.map((e=>e.value)))}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Health Check Type")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(en,{value:a.healthCheckType,clearable:!1,placeholder:"Select...",options:a.backingData.healthCheckTypes.map((e=>({label:e,value:e}))),onChange:e=>t("healthCheckType",e.value)}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Health Check Grace Period")),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(Ja,{type:"text",required:!0,className:"form-control input-sm no-spel",name:"healthCheckGracePeriod"}))," ","seconds"),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Termination Policies")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(en,{multi:!0,value:a.terminationPolicies,options:a.backingData.terminationPolicies.map((e=>({label:e,value:e}))),onChange:e=>t("terminationPolicies",e.map((e=>e.value)))}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Key Name")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(en,{value:a.keyPair,required:!0,clearable:!1,options:i.map((e=>({label:e,value:e}))),onChange:e=>t("keyPair",e.value)}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Ramdisk Id (optional)")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(Ja,{type:"text",name:"ramdiskId",className:"form-control input-sm no-spel"}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"IAM Instance Profile (optional)")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(Ja,{type:"text",className:"form-control input-sm no-spel",name:"iamRole"}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"UserData (optional) "),Bt.createElement(n,{id:"aws.serverGroup.base64UserData"})),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(Ja,{type:"text",className:"form-control input-sm no-spel",name:"base64UserData"}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Instance Monitoring "),Bt.createElement(n,{id:"aws.serverGroup.instanceMonitoring"})),Bt.createElement("div",{className:"col-md-6 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",checked:a.instanceMonitoring,onChange:e=>t("instanceMonitoring",e.target.checked)})," ","Enforce Instance Monitoring"," "))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"EBS Optimized")),Bt.createElement("div",{className:"col-md-6 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",checked:a.ebsOptimized,onChange:e=>t("ebsOptimized",e.target.checked)})," ","Optimize Instances for EBS"))),(null==s?void 0:s.enableIMDSv2)&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"IMDSv2 "),Bt.createElement(n,{id:"aws.serverGroup.imdsv2"})),Bt.createElement("div",{className:"col-md-6 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",checked:!0===a.requireIMDSv2,onChange:e=>t("requireIMDSv2",e.target.checked)})," ","Require IMDSv2"," "))),!gn.disableSpotPricing&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Spot Instances Price (optional)")," ",Bt.createElement(n,{id:"aws.serverGroup.spotMaxPrice"})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(Ja,{type:"text",className:"form-control input-sm",name:"spotPrice"}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"AMI Block Device Mappings")),Bt.createElement("div",{className:"col-md-6 radio"},Bt.createElement("div",null,Bt.createElement("label",null,Bt.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("source"),checked:"source"===r,name:"blockDeviceMappingsSource"}),"Copy from current server group ",Bt.createElement(n,{id:"aws.blockDeviceMappings.useSource"}))),Bt.createElement("div",null,Bt.createElement("label",null,Bt.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("ami"),checked:"ami"===r,name:"blockDeviceMappingsSource"}),"Prefer AMI block device mappings ",Bt.createElement(n,{id:"aws.blockDeviceMappings.useAMI"}))),Bt.createElement("div",null,Bt.createElement("label",null,Bt.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("default"),checked:"default"===r,name:"blockDeviceMappingsSource"}),"Defaults for selected instance type ",Bt.createElement(n,{id:"aws.blockDeviceMappings.useDefaults"}))))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,`Associate ${(null==s?void 0:s.enableIPv6)?"IPv6 (Recommended)":"Public IPv4"} Address`),Bt.createElement(n,{id:"serverGroup.ipv6"})),(null==s?void 0:s.enableIPv6)&&Bt.createElement("div",{className:"col-md-6 checkbox"},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",checked:!0===a.associateIPv6Address,onChange:e=>t("associateIPv6Address",e.target.checked),id:"associateIPv6AddressToggle"})," ","Assign an IPv6 address to instances"," ")),!(null==s?void 0:s.enableIPv6)&&Bt.createElement("div",null,Bt.createElement("div",{className:"col-md-2 radio"},Bt.createElement("label",null,Bt.createElement("input",{type:"radio",checked:!0===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",!0),id:"associatePublicIpAddressTrue"}),"Yes")),Bt.createElement("div",{className:"col-md-2 radio"},Bt.createElement("label",null,Bt.createElement("input",{type:"radio",checked:!1===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",!1),id:"associatePublicIpAddressFalse"}),"No")),Bt.createElement("div",{className:"col-md-2 radio"},Bt.createElement("label",null,Bt.createElement("input",{type:"radio",checked:null===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",null),id:"associatePublicIpAddressDefault"}),"Default")))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Scaling Processes")),Bt.createElement("div",{className:"col-md-6 checkbox"},a.backingData.scalingProcesses.map((e=>Bt.createElement("div",{key:e.name},Bt.createElement("label",null,Bt.createElement("input",{type:"checkbox",onChange:()=>this.toggleSuspendedProcess(e.name),checked:!a.suspendedProcesses.includes(e.name)})," ",e.name," ",Bt.createElement(n,{content:e.description}))))))),e.attributes.platformHealthOnlyShowOverride&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-5 sm-label-right"},Bt.createElement("b",null,"Task Completion")),Bt.createElement("div",{className:"col-md-6"},Bt.createElement(dt,{interestingHealthProviderNames:a.interestingHealthProviderNames,platformHealthType:"Amazon",onChange:this.platformHealthOverrideChanged}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"sm-label-left"},Bt.createElement("b",null,"Tags (optional)"),Bt.createElement(n,{id:"aws.serverGroup.tags"})),Bt.createElement(pt,{model:a.tags,allowEmpty:!0,onChange:this.tagsChanged})))}}var Di=Object.defineProperty,$i=Object.getOwnPropertyDescriptor;let Mi=class extends Bt.Component{constructor(){super(...arguments),this.validators=new Map,this.validate=e=>{const t={};return this.validators.forEach((a=>{const n=a(e);Object.assign(t,{...n})})),t},this.handleRef=e=>{e?this.validators.set("common",e.validate):this.validators.delete("common")}}render(){const{formik:e,app:t}=this.props;return Bt.createElement(Bi,{formik:e,app:t,ref:this.handleRef})}};Mi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?$i(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Di(t,a,i),i})([ce("aws.serverGroup.advancedSettings")],Mi);class Fi extends Bt.Component{constructor(){super(...arguments),this.ref=Bt.createRef()}validate(e){return this.ref&&this.ref.current?this.ref.current.validate(e):{}}render(){const{app:e,formik:t}=this.props;return Bt.createElement(Mi,{formik:t,app:e,ref:this.ref})}}const Li=class extends Bt.Component{constructor(e){super(e),this._isUnmounted=!1,this.templateSelected=()=>{this.setState({requiresTemplateSelection:!1}),this.configureCommand()},this.onTaskComplete=()=>{this.props.application.serverGroups.refresh(),this.props.application.serverGroups.onNextRefresh(null,this.onApplicationRefresh)},this.onApplicationRefresh=()=>{if(this._isUnmounted)return;const{command:e}=this.props,{taskMonitor:t}=this.state,a=t.task.execution.stages.find((e=>"cloneServerGroup"===e.type));if(a&&a.context["deploy.server.groups"]){const t=a.context["deploy.server.groups"][e.region];if(t){const a={serverGroup:t,accountId:e.credentials,region:e.region,provider:"aws"};let n="^.^.^.clusters.serverGroup";h.$state.includes("**.clusters.serverGroup")&&(n="^.serverGroup"),h.$state.includes("**.clusters.cluster.serverGroup")&&(n="^.^.serverGroup"),h.$state.includes("**.clusters")&&(n=".serverGroup"),h.$state.go(n,a)}}},this.initializeCommand=()=>{const{command:e}=this.props;e.credentialsChanged(e),e.regionChanged(e),Un.awsServerGroupConfigurationService.configureSubnetPurposes(e)},this.configureCommand=()=>{const{application:e,command:t}=this.props;Un.awsServerGroupConfigurationService.configureCommand(e,t).then((()=>{this.initializeCommand(),this.setState({loaded:!0,requiresTemplateSelection:!1})}))},this.normalizeCommand=({tags:e})=>{e&&Object.keys(e).forEach((t=>{t.length||e[t].length||delete e[t]}))},this.submit=e=>{this.normalizeCommand(e);"editPipeline"===e.viewState.mode||"createPipeline"===e.viewState.mode?this.props.closeModal&&this.props.closeModal(e):this.state.taskMonitor.submit((()=>h.serverGroupWriter.cloneServerGroup(e,this.props.application)))};const t=Zt(e,"command.viewState.requiresTemplateSelection",!1);t||this.configureCommand(),this.state={firewallsLabel:U.get("Firewalls"),loaded:!1,requiresTemplateSelection:t,taskMonitor:new v({application:e.application,title:"Creating your server group",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:this.onTaskComplete})}}static show(e){return b.show(Li,e,{dialogClassName:"wizard-modal modal-lg"})}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}render(){const{application:e,command:t,dismissModal:a,title:n}=this.props,{loaded:r,taskMonitor:i,requiresTemplateSelection:s}=this.state;return s?Bt.createElement(yi,{app:e,command:t,onDismiss:a,onTemplateSelected:this.templateSelected}):Bt.createElement(w,{heading:n,initialValues:t,loading:!r,taskMonitor:i,dismissModal:a,closeModal:this.submit,submitButtonLabel:t.viewState.submitButtonLabel,render:({formik:t,nextIdx:a,wizard:n})=>Bt.createElement(Bt.Fragment,null,Bt.createElement(E,{label:"Basic Settings",wizard:n,order:a(),render:({innerRef:a})=>Bt.createElement(Ei,{ref:a,formik:t,app:e})}),Bt.createElement(E,{label:"Load Balancers",wizard:n,order:a(),render:({innerRef:e})=>Bt.createElement(xi,{ref:e,formik:t})}),Bt.createElement(E,{label:U.get("Firewalls"),wizard:n,order:a(),render:({innerRef:e})=>Bt.createElement(zi,{ref:e,formik:t})}),Bt.createElement(E,{label:"Instance Type",wizard:n,order:a(),render:({innerRef:e})=>Bt.createElement(Ni,{ref:e,formik:t})}),Bt.createElement(E,{label:"Capacity",wizard:n,order:a(),render:({innerRef:e})=>Bt.createElement(Si,{ref:e,formik:t})}),Bt.createElement(E,{label:"Availability Zones",wizard:n,order:a(),render:({innerRef:e})=>Bt.createElement(Ti,{ref:e,formik:t})}),Bt.createElement(E,{label:"Advanced Settings",wizard:n,order:a(),render:({innerRef:a})=>Bt.createElement(Fi,{ref:a,formik:t,app:e})}))})}};let Ri=Li;Ri.defaultProps={closeModal:C,dismissModal:C};class Oi extends Bt.Component{constructor(){super(...arguments),this.state={verified:!1,requireVerification:!1},this.handleVerification=e=>{this.setState({verified:e})}}componentDidMount(){o.accounts$.pipe(za(1),Ca((e=>e.find((e=>e.name===this.props.account))))).subscribe((e=>{this.setState({requireVerification:!!e&&e.challengeDestructiveActions})}))}render(){const{account:e,onCancel:t,onSubmit:a,isValid:n}=this.props,{verified:r,requireVerification:i}=this.state;return Bt.createElement(La,null,Bt.createElement("form",{onSubmit:()=>(this.props.onSubmit(),!1)},i&&Bt.createElement(ut,{expectedValue:e,onValidChange:this.handleVerification})),Bt.createElement("button",{className:"btn btn-default",onClick:t},"Cancel"),Bt.createElement("button",{type:"submit",className:"btn btn-primary",onClick:a,disabled:!n||i&&!r},"Submit"))}}Oi.defaultProps={isValid:!0};const Ui=class extends Bt.Component{constructor(e){super(e),this.formikRef=Bt.createRef(),this.validate=e=>{const{min:t,max:a,desired:n}=e,r={};return this.state.advancedMode?(t>a&&t>n?r.min="Min cannot be larger than Max/Desired":a<t&&a<n?r.max="Max cannot be smaller than Min/Desired":(t>a&&(r.min="Min cannot be larger than Max"),this.isDesiredControlledByAutoscaling()||(n<t&&(r.desired="Desired cannot be smaller than Min"),n>a&&(r.desired="Desired cannot be larger than Max"))),r):r},this.toggleAdvancedMode=()=>{const{desired:e}=this.formikRef.current.getFormikContext().values;this.formikRef.current.setFieldValue("min",e),this.formikRef.current.setFieldValue("max",e),this.setState({advancedMode:!this.state.advancedMode})},this.close=e=>{this.props.dismissModal.apply(null,e)},this.platformHealthOverrideChanged=e=>{this.setState({interestingHealthProviderNames:e})},this.isDesiredControlledByAutoscaling=()=>{const{serverGroup:e}=this.props,{suspendedProcesses:t}=e.asg,{advancedMode:a}=this.state;return(e.scalingPolicies||[]).length&&a&&t.every((e=>"AlarmNotification"!==e.processName))},this.submit=e=>{const{min:t,max:a,desired:n,enforceCapacityConstraints:r,reason:i}=e,{interestingHealthProviderNames:s}=this.state,{serverGroup:l,application:o}=this.props,{asg:c}=l,d={capacity:Ht({min:t!==c.minSize?t:void 0,max:a!==c.maxSize?a:void 0,desired:n!==c.desiredCapacity?n:void 0},(e=>void 0!==e)),reason:i,interestingHealthProviderNames:s};r&&(d.constraints={capacity:{min:c.minSize,max:c.maxSize,desired:c.desiredCapacity}}),this.state.taskMonitor.submit((()=>h.serverGroupWriter.resizeServerGroup(l,o,d)))};const{minSize:t,maxSize:a,desiredCapacity:n}=e.serverGroup.asg,{attributes:r}=e.application;this.state={advancedMode:t!==a,initialValues:{min:t,max:a,desired:n,enforceCapacityConstraints:!1},taskMonitor:new v({application:e.application,title:"Resizing your server group",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.props.application.serverGroups.refresh()}),platformHealthOnlyShowOverride:r.platformHealthOnlyShowOverride,interestingHealthProviderNames:r.platformHealthOnlyShowOverride&&r.platformHealthOnly?["Amazon"]:null}}static show(e){const t={},{serverGroup:a,application:n}=e;return et(a,n).then((a=>{a&&b.show(Ui,e,t)}))}autoIncrementDesiredIfNeeded(){if(!this.isDesiredControlledByAutoscaling())return;const e=this.formikRef.current.getFormikContext(),{asg:t}=this.props.serverGroup,{min:a,max:n,desired:r}=e.values,i=Math.min(n,Math.max(a,t.desiredCapacity));r!==i&&e.setFieldValue("desired",i)}renderSimpleMode(e){const{serverGroup:t}=this.props,{asg:a}=t;return Bt.createElement("div",null,Bt.createElement("p",null,"Sets min, max, and desired instance counts to the same value."),Bt.createElement("p",null,"To allow autoscaling, use the"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Advanced Mode"),"."),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Current size"),Bt.createElement("div",{className:"col-md-4"},Bt.createElement("div",{className:"horizontal middle"},Bt.createElement("input",{type:"number",className:"NumberInput form-control",value:a.desiredCapacity,disabled:!0}),Bt.createElement("div",{className:"sp-padding-xs-xaxis"},"instances")))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Resize to"),Bt.createElement("div",{className:"col-md-4"},Bt.createElement("div",{className:"horizontal middle"},Bt.createElement(s,{name:"desired",input:e=>Bt.createElement(u,{...e,min:0}),touched:!0,onChange:t=>{e.setFieldValue("min",t),e.setFieldValue("max",t)}}),Bt.createElement("div",{className:"sp-padding-xs-xaxis"},"instances")))))}renderAdvancedMode(e){const{serverGroup:t}=this.props,{errors:a}=e,{asg:n}=t,r=a.min||a.max||a.desired;return Bt.createElement("div",null,Bt.createElement("p",null,"Sets up autoscaling for this server group."),Bt.createElement("p",null,"To disable autoscaling, use the"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Simple Mode"),"."),Bt.createElement("div",{className:"form-group bold"},Bt.createElement("div",{className:"col-md-2 col-md-offset-3"},"Min"),Bt.createElement("div",{className:"col-md-2"},"Max"),Bt.createElement("div",{className:"col-md-2"},"Desired")),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Current"),Bt.createElement("div",{className:"col-md-2"},Bt.createElement("input",{type:"number",className:"NumberInput form-control",value:n.minSize,disabled:!0})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement("input",{type:"number",className:"NumberInput form-control",value:n.maxSize,disabled:!0})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement("input",{type:"number",className:"NumberInput form-control",value:n.desiredCapacity,disabled:!0}))),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Resize to"),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(s,{name:"min",input:e=>Bt.createElement(u,{...e,min:0}),onChange:()=>this.autoIncrementDesiredIfNeeded(),layout:({input:e})=>Bt.createElement(Bt.Fragment,null,e),touched:!0})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(s,{name:"max",input:e=>Bt.createElement(u,{...e,min:0}),onChange:()=>this.autoIncrementDesiredIfNeeded(),layout:({input:e})=>Bt.createElement(Bt.Fragment,null,e),touched:!0})),Bt.createElement("div",{className:"col-md-2"},Bt.createElement(s,{name:"desired",input:e=>Bt.createElement(u,{...e,min:0,disabled:this.isDesiredControlledByAutoscaling()}),layout:({input:e})=>Bt.createElement(Bt.Fragment,null,e),touched:!0}))),!!r&&Bt.createElement("div",{className:"col-md-offset-3 col-md-9"},Bt.createElement(de,{message:r,type:"error"})))}renderCapacityConstraintSelector(){return Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-7 col-md-offset-3"},Bt.createElement(s,{name:"enforceCapacityConstraints",input:e=>Bt.createElement(Bt.Fragment,null,Bt.createElement(d,{...e,text:"Enforce Capacity Constraints"}),Bt.createElement(n,{id:"aws.serverGroup.capacityConstraint"}))})))}renderScalingPolicyWarning(e){const{serverGroup:t}=this.props,{min:a,max:n}=e.values,{advancedMode:r}=this.state,i=t.scalingPolicies||[];return i.length&&a===n?Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-7 col-md-offset-3"},Bt.createElement("div",{className:"well-compact alert alert-warning"},Bt.createElement("b",null,"Warning"),": this server group has",1===i.length&&Bt.createElement("span",null," a scaling policy. "),i.length>1&&Bt.createElement("span",null," scaling policies. "),!r&&Bt.createElement("span",null,"Scaling policies will not take effect in Simple Mode. Switch to"," ",Bt.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Advanced Mode"),"."),r&&Bt.createElement("span",null,"Scaling policies will not take effect when ",Bt.createElement("b",null,"Min")," is the same as ",Bt.createElement("b",null,"Max"),".")))):this.isDesiredControlledByAutoscaling()?Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-8 col-md-offset-1"},Bt.createElement("div",{className:"well-compact alert alert-warning"},Bt.createElement("p",null,Bt.createElement("b",null,"Desired")," capacity is managed by Autoscaling Policies."),Bt.createElement("p",null,"If you need to scale ",Bt.createElement("b",null,"down")," this server group, set ",Bt.createElement("b",null,"Max")," to the new desired size."),Bt.createElement("p",null,"If you need to scale ",Bt.createElement("b",null,"up")," this server group, set ",Bt.createElement("b",null,"Min")," to the new desired size.")))):null}render(){const{serverGroup:e}=this.props,{advancedMode:t,initialValues:a,platformHealthOnlyShowOverride:n}=this.state;return Bt.createElement(Bt.Fragment,null,Bt.createElement(mt,{monitor:this.state.taskMonitor}),Bt.createElement(ne,{ref:this.formikRef,initialValues:a,validate:this.validate,onSubmit:this.submit,render:a=>{const{asg:r}=e,i={min:r.minSize,max:r.maxSize,desired:r.desiredCapacity},s=a.values;return Bt.createElement(Bt.Fragment,null,Bt.createElement(re,{dismiss:this.close}),Bt.createElement(Da.Header,null,Bt.createElement(Da.Title,null,"Resize ",e.name)),Bt.createElement(Da.Body,null,Bt.createElement(Qa,{className:"form-horizontal"},t&&this.renderAdvancedMode(a),!t&&this.renderSimpleMode(a),this.renderScalingPolicyWarning(a),this.renderCapacityConstraintSelector(),n&&Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-8 col-md-offset-3"},Bt.createElement(dt,{interestingHealthProviderNames:this.state.interestingHealthProviderNames,platformHealthType:"Amazon",onChange:this.platformHealthOverrideChanged,showHelpDetails:!0}))),Bt.createElement(st,{reason:a.values.reason,onChange:e=>a.setFieldValue("reason",e)}),Bt.createElement("div",{className:"form-group"},Bt.createElement("div",{className:"col-md-3 sm-label-right"},"Changes"),Bt.createElement("div",{className:"col-md-9 sm-control-field"},Bt.createElement(gt,{current:i,next:s}))))),Bt.createElement(Oi,{onSubmit:()=>this.submit(a.values),onCancel:this.close,isValid:a.isValid,account:e.account}))}}))}};let Vi=Ui;Vi.defaultProps={closeModal:C,dismissModal:C};var ji=Object.defineProperty,qi=Object.getOwnPropertyDescriptor;let Hi=class extends Bt.Component{constructor(){super(...arguments),this.resizeServerGroup=()=>{Vi.show(this.props)}}render(){return Bt.createElement(Ra,{onClick:this.resizeServerGroup},"Resize")}};Hi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?qi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&ji(t,a,i),i})([ce("AmazonServerGroupActions.resize")],Hi);class Wi extends Bt.Component{constructor(){super(...arguments),this.destroyServerGroup=()=>{const{app:e,serverGroup:t}=this.props,a={application:e,title:"Destroying "+t.name,onTaskComplete:()=>{h.$state.includes("**.serverGroup",n)&&h.$state.go("^")}},n={name:t.name,accountId:t.account,region:t.region},r={header:"Really destroy "+t.name+"?",buttonText:"Destroy "+t.name,account:t.account,taskMonitorConfig:a,interestingHealthProviderNames:void 0,submitMethod:a=>h.serverGroupWriter.destroyServerGroup(t,e,a),askForReason:!0,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon"};ht.addDestroyWarningMessage(e,t,r),e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(r.interestingHealthProviderNames=["Amazon"]),k.confirm(r)},this.disableServerGroup=()=>{const{app:e,serverGroup:t}=this.props,a={application:e,title:"Disabling "+t.name},n={header:"Really disable "+t.name+"?",buttonText:"Disable "+t.name,account:t.account,interestingHealthProviderNames:void 0,taskMonitorConfig:a,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",submitMethod:a=>h.serverGroupWriter.disableServerGroup(t,e.name,a),askForReason:!0};ht.addDisableWarningMessage(e,t,n),e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=["Amazon"]),k.confirm(n)},this.enableServerGroup=()=>{if(!this.isRollbackEnabled())return void this.showEnableServerGroupModal();const e={header:"Rolling back?",body:"Spinnaker provides an orchestrated rollback feature to carefully restore a different version of this\n server group. Do you want to use the orchestrated rollback?",buttonText:"Yes, take me to the rollback settings modal",cancelButtonText:"No, I just want to enable the server group"};k.confirm(e).then((()=>new Promise((e=>setTimeout(e,500))))).then((()=>this.rollbackServerGroup())).catch((e=>{"footer"===(null==e?void 0:e.source)&&this.showEnableServerGroupModal()}))},this.rollbackServerGroup=()=>{const{app:e}=this.props;let t,a=this.props.serverGroup,n=e.getDataSource("serverGroups").data.filter((e=>e.cluster===a.cluster&&e.region===a.region&&e.account===a.account));a.isDisabled&&(t=a,a=Vt(n.filter((e=>e.name!==t.name&&!e.isDisabled)),["instanceCounts.total","createdTime"],["desc","desc"])[0]),n=n.filter((e=>e.name!==a.name)),1!==n.length||t||(t=n[0]),ft.modalService.open({templateUrl:h.overrideRegistry.getTemplate("aws.rollback.modal","amazon/src/serverGroup/details/rollback/rollbackServerGroup.html"),controller:"awsRollbackServerGroupCtrl as ctrl",resolve:{serverGroup:()=>a,previousServerGroup:()=>t,disabledServerGroups:()=>{const t=oa(e.clusters,{name:a.cluster,account:a.account,serverGroups:[]});return Qt(t.serverGroups,{isDisabled:!0,region:a.region})},allServerGroups:()=>n,application:()=>e}})},this.cloneServerGroup=()=>{const{app:e,serverGroup:t}=this.props;Un.awsServerGroupCommandBuilder.buildServerGroupCommandFromExisting(e,t).then((a=>{const n=`Clone ${t.name}`;Ri.show({title:n,application:e,command:a})}))}}isEnableLocked(){if(this.props.serverGroup.isDisabled){if((this.props.serverGroup.runningTasks||[]).filter((e=>Zt(e,"execution.stages",[]).some((e=>"resizeServerGroup"===e.type)))).length)return!0}return!1}isRollbackEnabled(){const{app:e,serverGroup:t}=this.props;return!t.isDisabled||e.getDataSource("serverGroups").data.some((e=>e.cluster===t.cluster&&e.region===t.region&&e.account===t.account&&!e.isDisabled))}hasDisabledInstances(){return this.props.serverGroup.isDisabled||Zt(this.props.serverGroup,"instanceCounts.outOfService",0)>0}showEnableServerGroupModal(){const{app:e,serverGroup:t}=this.props,a={application:e,title:"Enabling "+t.name},n={header:"Really enable "+t.name+"?",buttonText:"Enable "+t.name,account:t.account,interestingHealthProviderNames:void 0,taskMonitorConfig:a,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",submitMethod:a=>h.serverGroupWriter.enableServerGroup(t,e,a),askForReason:!0};e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=["Amazon"]),k.confirm(n)}render(){const{app:e,serverGroup:t}=this.props,n=a.feature&&a.feature.entityTags,r=vt.buildClusterTargets(t);return Bt.createElement(Ba,{className:"dropdown",id:"server-group-actions-dropdown"},Bt.createElement(Ba.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},"Server Group Actions"),Bt.createElement(Ba.Menu,{className:"dropdown-menu"},this.isRollbackEnabled()&&Bt.createElement(Ne,{resource:t,application:e,onClick:this.rollbackServerGroup},"Rollback"),this.isRollbackEnabled()&&Bt.createElement("li",{role:"presentation",className:"divider"}),Bt.createElement(Hi,{application:e,serverGroup:t}),!t.isDisabled&&Bt.createElement(Ne,{resource:t,application:e,onClick:this.disableServerGroup},"Disable"),this.hasDisabledInstances()&&!this.isEnableLocked()&&Bt.createElement(Ne,{resource:t,application:e,onClick:this.enableServerGroup},"Enable"),this.isEnableLocked()&&Bt.createElement("li",{className:"disabled"},Bt.createElement(Ma,{value:"Cannot enable this server group until resize operation completes",placement:"left"},Bt.createElement("a",null,Bt.createElement("span",{className:"small glyphicon glyphicon-lock"})," Enable"))),Bt.createElement(Ne,{resource:t,application:e,onClick:this.destroyServerGroup},"Destroy"),Bt.createElement("li",null,Bt.createElement("a",{className:"clickable",onClick:this.cloneServerGroup},"Clone")),n&&Bt.createElement(G,{component:t,application:e,entityType:"serverGroup",ownerOptions:r,onUpdate:()=>e.serverGroups.refresh()})))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/rollback/rollbackServerGroup.html",'<div modal-page class="confirmation-modal">\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Rollback {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body confirmation-modal">\n <div class="row">\n <div class="col-sm-3 sm-label-right">Restore to</div>\n <div class="col-md-7">\n <ui-select\n ng-model="command.rollbackContext.restoreServerGroupName"\n class="form-control input-sm"\n ng-if="command.rollbackType === \'EXPLICIT\'"\n >\n <ui-select-match placeholder="Select...">{{ctrl.label($select.selected)}}</ui-select-match>\n <ui-select-choices group-by="ctrl.group" repeat="serverGroup.name as serverGroup in allServerGroups">\n <span ng-bind-html="ctrl.label(serverGroup)"></span>\n </ui-select-choices>\n </ui-select>\n <div ng-if="command.rollbackType === \'PREVIOUS_IMAGE\'" style="margin-top: 5px">\n {{ previousServerGroup.name }} <span class="small">(no longer deployed)</span><br />\n <span class="small">\n <strong>Image</strong>: {{ previousServerGroup.imageName}}\n <span ng-if="previousServerGroup.imageId">({{ previousServerGroup.imageId }})</span><br />\n </span>\n <span class="small" ng-if="previousServerGroup.buildNumber">\n <strong>Build</strong> #{{ previousServerGroup.buildNumber }}\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="command.platformHealthOnlyShowOverride">\n <div class="col-sm-10 col-sm-offset-1">\n <platform-health-override\n command="command"\n platform-health-type="\'Amazon\'"\n show-help-details="true"\n field-columns="12"\n >\n </platform-health-override>\n </div>\n </div>\n\n <task-reason command="command"></task-reason>\n\n <div class="row">\n <div class="col-sm-11 col-sm-offset-1">\n Wait\n <input\n placeholder="0"\n min="0"\n type="number"\n ng-model="command.rollbackContext.delayBeforeDisableSeconds"\n class="form-control input-sm inline-number"\n />\n seconds before disabling <em>{{ ctrl.label(serverGroup) }}</em>.\n </div>\n </div>\n\n <div class="row">\n <div class="col-sm-11 col-sm-offset-1">\n Consider rollback successful when\n <input\n type="number"\n min="0"\n max="100"\n ng-model="command.rollbackContext.targetHealthyRollbackPercentage"\n class="form-control input-sm inline-number"\n />\n percent of instances are healthy.\n </div>\n </div>\n\n <div class="row">\n <div class="col-sm-4 sm-label-right">Rollback Operations</div>\n </div>\n <div class="row" ng-if="command.rollbackType === \'EXPLICIT\'">\n <div class="col-sm-11 col-sm-offset-1">\n <ol>\n <li>Enable <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em></li>\n <li>\n Resize <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em> to [\n <strong>min</strong>: {{serverGroup.capacity.desired}}, <strong>max</strong>: {{ serverGroup.capacity.max\n }}, <strong>desired</strong>: {{ serverGroup.capacity.desired }} ] <br />(minimum capacity pinned at\n {{serverGroup.capacity.desired}} to prevent autoscaling down during rollback)\n </li>\n\n <li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100">\n Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} instances to\n report as healthy\n </li>\n <li ng-if="command.rollbackContext.delayBeforeDisableSeconds > 0">\n Wait {{ command.rollbackContext.delayBeforeDisableSeconds }} seconds\n </li>\n <li>Disable <em>{{ serverGroup.name }}</em></li>\n <li>\n Restore minimum capacity of\n <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em> [\n <strong>min</strong>: {{ serverGroup.capacity.min }} ]\n </li>\n </ol>\n <p>This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}).</p>\n </div>\n </div>\n <div class="row" ng-if="command.rollbackType === \'PREVIOUS_IMAGE\'">\n <div class="col-sm-11 col-sm-offset-1">\n <ol>\n <li>\n Deploy <em>{{ previousServerGroup.imageId }}</em> [ <strong>min</strong>:\n {{serverGroup.capacity.desired}}, <strong>max</strong>: {{ serverGroup.capacity.max }},\n <strong>desired</strong>: {{ serverGroup.capacity.desired }} ] <br />(minimum capacity pinned at\n {{serverGroup.capacity.desired}} to prevent autoscaling down during deploy)\n </li>\n <li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100">\n Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} instances to\n report as healthy\n </li>\n <li>Disable {{ serverGroup.name }}</li>\n <li>\n Restore minimum capacity of <em>new server group</em> [ <strong>min</strong>: {{ serverGroup.capacity.min\n }} ]\n </li>\n </ol>\n <p>This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}).</p>\n </div>\n </div>\n </div>\n <aws-footer\n action="ctrl.rollback()"\n cancel="ctrl.cancel()"\n is-valid="ctrl.isValid()"\n account="serverGroup.account"\n verification="verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class Zi{static getDisabledDate(e){if(e.isDisabled){const t=this.normalizeScalingProcesses(e).find((e=>"AddToLoadBalancer"===e.name&&!e.enabled));if(t)return t.suspensionDate}return null}static normalizeScalingProcesses(e){if(!e.asg||!e.asg.suspendedProcesses)return[];const t=e.asg.suspendedProcesses;return this.listProcesses().map((e=>{const a=t.find((t=>t.processName===e.name)),n={name:e.name,enabled:!a,description:e.description};if(a){const e=a.suspensionReason.replace("User suspended at ","");n.suspensionDate=new Date(e).getTime()}return n}))}static listProcesses(){return[{name:"Launch",description:"Controls if new instances should be launched into the ASG. If this is disabled, scale-up events will not produce new instances."},{name:"Terminate",description:"Controls if instances should be terminated during a scale-down event."},{name:"AddToLoadBalancer",description:"Controls if new instances should be added to the ASG’s ELB."},{name:"AlarmNotification",description:"This disables autoscaling."},{name:"AZRebalance",description:"Controls whether AWS should attempt to maintain an even distribution of instances across all healthy Availability Zones configured for the ASG."},{name:"HealthCheck",description:"If disabled, the instance’s health will no longer be reported to the autoscaling processor."},{name:"ReplaceUnhealthy",description:"Controls whether instances should be replaced if they failed the health check."},{name:"ScheduledActions",description:"Controls whether scheduled actions should be executed."}]}}function _i(e,t){const{app:a,serverGroup:n}=e;return new Ea((r=>{(function(e){const{app:t,serverGroup:a}=e;return t.ready().then((()=>{let e=t.serverGroups.data.find((e=>e.name===a.name&&e.account===a.accountId&&e.region===a.region));return e||t.loadBalancers.data.some((t=>t.account===a.accountId&&t.region===a.region&&t.serverGroups.some((t=>t.name===a.name&&(e=t,!0))))),e}))})(e).then((e=>{yt.getServerGroup(a.name,n.accountId,n.region,n.name).then((a=>{Object.assign(a,e,{account:n.accountId});const i=Un.awsServerGroupTransformer.normalizeServerGroupDetails(a);if(o.getAccountDetails(i.account).then((e=>{i.accountDetails=e,r.next(i)})),Mt(i))t();else{const e=i.asg?i.asg.vpczoneIdentifier:"";if(""!==e){const t=e.split(",")[0];g.listSubnets().then((e=>{const a=e.find((e=>e.id===t));i.subnetType=a.purpose,r.next(i)}))}i.disabledDate=Zi.getDisabledDate(i),r.next(i)}}),t)}),t)}))}class Ki extends Bt.Component{constructor(){super(...arguments),this.editAdvancedSettings=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/advancedSettings/editAsgAdvancedSettings.modal.html",controller:"EditAsgAdvancedSettingsCtrl as ctrl",resolve:{application:()=>e,serverGroup:()=>t}})))}}render(){const{serverGroup:e}=this.props,t=e.asg;return Bt.createElement(A,{heading:"Advanced Settings"},Bt.createElement("dl",{className:"horizontal-when-filters-collapsed"},Bt.createElement("dt",null,"Cooldown"),Bt.createElement("dd",null,t.defaultCooldown," seconds"),t.enabledMetrics.length>0&&[Bt.createElement("dt",{key:"t-metrics"},"Enabled Metrics"),Bt.createElement("dd",{key:"d-metrics"},t.enabledMetrics.map((e=>e.metric)).join(", "))],Bt.createElement("dt",null,"Health Check Type"),Bt.createElement("dd",null,t.healthCheckType),Bt.createElement("dt",null,"Grace Period"),Bt.createElement("dd",null,t.healthCheckGracePeriod," seconds"),Bt.createElement("dt",null,"Termination Policies"),Bt.createElement("dd",null,t.terminationPolicies.join(", ")),t.capacityRebalance&&[Bt.createElement("dt",null,"Capacity Rebalance ",Bt.createElement(n,{id:"aws.serverGroup.capacityRebalance"})),Bt.createElement("dd",null,`${t.capacityRebalance}`)]),Bt.createElement("a",{className:"clickable",onClick:this.editAdvancedSettings},"Edit Advanced Settings"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/advancedSettings/editAsgAdvancedSettings.modal.html",'<div modal-page>\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Edit Advanced Settings for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Cooldown</b></div>\n <div class="col-md-2">\n <input type="number" required class="form-control input-sm" ng-model="command.cooldown" />\n </div>\n &nbsp;seconds\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right">\n <b>Enabled Metrics</b>\n <help-field key="aws.serverGroup.enabledMetrics"></help-field>\n </div>\n <div class="col-md-6">\n <ui-select multiple ng-model="command.enabledMetrics" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices\n repeat="enabledMetric in command.backingData.enabledMetrics | filter: $select.search | orderBy: \'toString()\'"\n >\n <span ng-bind-html="enabledMetric | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Health Check Type</b></div>\n <div class="col-md-6">\n <ui-select ng-model="command.healthCheckType" class="form-control input-sm">\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="healthCheckType in command.backingData.healthCheckTypes | filter: $select.search"\n >\n <span ng-bind-html="healthCheckType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Health Check Grace Period</b></div>\n <div class="col-md-2">\n <input type="text" required class="form-control input-sm" ng-model="command.healthCheckGracePeriod" />\n </div>\n &nbsp;seconds\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Termination Policies</b></div>\n <div class="col-md-6">\n <ui-select multiple ng-model="command.terminationPolicies" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices\n repeat="terminationPolicy in command.backingData.terminationPolicies | filter: $select.search | orderBy: \'toString()\'"\n >\n <span ng-bind-html="terminationPolicy | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right">\n <b>Capacity Rebalance</b><help-field key="aws.serverGroup.capacityRebalance" />\n </div>\n <div class="col-md-6">\n <input type="checkbox" ng-model="command.capacityRebalance" /> Enable capacity rebalance\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <button type="submit" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="ctrl.submit()">Submit</button>\n </div>\n </form>\n</div>\n')}]);class Yi extends Bt.Component{constructor(e){super(e),this.state={changeConfig:this.getChangeConfig(e.serverGroup)}}getChangeConfig(e){const t={metadata:Zt(e.entityTags,"creationMetadata")};return ca(e,"buildInfo.jenkins")&&(t.buildInfo={ancestor:void 0,jenkins:e.buildInfo.jenkins,target:void 0}),t}componentWillReceiveProps(e){this.setState({changeConfig:this.getChangeConfig(e.serverGroup)})}render(){const{serverGroup:e}=this.props,{changeConfig:t}=this.state,n=a.feature&&a.feature.entityTags,r=e.entityTags||{};return Bt.createElement(A,{heading:"Server Group Information",defaultExpanded:!0},Bt.createElement("dl",{className:"dl-horizontal dl-narrow"},Bt.createElement("dt",null,"Created"),Bt.createElement("dd",null,D(e.createdTime)),n&&Bt.createElement(bt,{metadata:r.creationMetadata}),n&&Bt.createElement(wt,{changeConfig:t,linkText:"view changes",nameItem:e,viewType:"description"}),Bt.createElement("dt",null,"In"),Bt.createElement("dd",null,Bt.createElement(I,{account:e.account}),e.region),Bt.createElement("dt",null,"VPC"),Bt.createElement("dd",null,Bt.createElement(_n,{vpcId:e.vpcId})),e.vpcId&&e.subnetType&&Bt.createElement("dt",null,"Subnet"),e.vpcId&&e.subnetType&&Bt.createElement("dd",null,e.subnetType),e.asg&&Bt.createElement("dt",null,"Zones"),e.asg&&Bt.createElement("dd",null,Bt.createElement("ul",null,e.asg.availabilityZones.map((e=>Bt.createElement("li",{key:e},e)))))))}}var Xi=Object.defineProperty,Qi=Object.getOwnPropertyDescriptor;let Ji=class extends Bt.Component{render(){const{serverGroup:e,app:t}=this.props,a={min:e.asg.minSize,max:e.asg.maxSize,desired:e.asg.desiredCapacity};return Bt.createElement(A,{heading:"Capacity",defaultExpanded:!0},Bt.createElement(Et,{current:e.instances.length,capacity:a}),Bt.createElement("div",null,Bt.createElement("a",{className:"clickable",onClick:()=>Vi.show({application:t,serverGroup:e})},"Resize Server Group")),Bt.createElement("div",null,Bt.createElement(Ct,{serverGroup:e})))}};Ji=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?Qi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Xi(t,a,i),i})([ce("amazon.serverGroup.CapacityDetailsSection")],Ji);class es extends Bt.Component{render(){const{serverGroup:e}=this.props;return e.instanceCounts.total>0?Bt.createElement(A,{heading:"Health",defaultExpanded:!0},Bt.createElement("dl",{className:"dl-horizontal dl-narrow"},Bt.createElement("dt",null,"Instances"),Bt.createElement("dd",null,Bt.createElement(Y,{container:e.instanceCounts,className:"pull-left"})))):null}}const ts=({serverGroup:e})=>{if(!e.mixedInstancesPolicy)return null;const t=e.mixedInstancesPolicy.instancesDiversification;return Bt.createElement(A,{heading:"Instance Diversification"},Bt.createElement(q,{className:"horizontal-when-filters-collapsed"},Bt.createElement(B,{label:"On-Demand Allocation Strategy",helpFieldId:"aws.serverGroup.odAllocationStrategy",value:t.onDemandAllocationStrategy}),Bt.createElement(B,{label:"On-Demand Base Capacity",helpFieldId:"aws.serverGroup.odBase",value:t.onDemandBaseCapacity}),Bt.createElement(B,{label:"On-Demand Percentage Above Base Capacity",helpFieldId:"aws.serverGroup.odPercentAboveBase",value:t.onDemandPercentageAboveBaseCapacity}),Bt.createElement(B,{label:"Spot Allocation Strategy",helpFieldId:"aws.serverGroup.spotAllocationStrategy",value:t.spotAllocationStrategy}),t.spotInstancePools&&Bt.createElement(B,{label:"Spot Instance Pools",helpFieldId:"aws.serverGroup.spotInstancePoolCount",value:t.spotInstancePools}),Bt.createElement(B,{label:"Max Spot Price",helpFieldId:"aws.serverGroup.spotMaxPrice",value:t.spotMaxPrice||"on-demand price, default"})))},as=e=>{let t;return(e||"").split(", ").forEach((e=>{const a=e.split("=");2===a.length&&"ancestor_name"===a[0]&&(t=a[1])})),t};class ns extends Bt.Component{constructor(e){super(e),this.state={image:this.getImage(e.serverGroup)}}getImage(e){const t=e.image?e.image:void 0;return e.image&&e.image.description&&(t.baseImage=as(e.image.description)),t}componentWillReceiveProps(e){this.setState({image:this.getImage(e.serverGroup)})}render(){const{name:e,launchConfig:t}=this.props.serverGroup,{image:a}=this.state;return t?Bt.createElement(A,{heading:"Launch Configuration"},Bt.createElement("dl",{className:"horizontal-when-filters-collapsed"},Bt.createElement("dt",null,"Name"),Bt.createElement("dd",null,t.launchConfigurationName),Bt.createElement("dt",null,"Image ID"),Bt.createElement("dd",null,t.imageId),a&&a.imageLocation&&Bt.createElement("dt",null,"Image Name"),a&&a.imageLocation&&Bt.createElement("dd",null,a.imageLocation),a&&a.baseImage&&Bt.createElement("dt",null,"Base Image Name"),a&&a.baseImage&&Bt.createElement("dd",null,a.baseImage),Bt.createElement("dt",null,"Instance Type"),Bt.createElement("dd",null,t.instanceType),Bt.createElement("dt",null,"IAM Profile"),Bt.createElement("dd",null,t.iamInstanceProfile),Bt.createElement("dt",null,"Instance Monitoring"),Bt.createElement("dd",null,t.instanceMonitoring.enabled?"enabled":"disabled"),t.spotPrice&&Bt.createElement("dt",null,"Spot Price"),t.spotPrice&&Bt.createElement("dd",null,t.spotPrice),t.keyName&&Bt.createElement("dt",null,"Key Name"),t.keyName&&Bt.createElement("dd",null,t.keyName),t.kernelId&&Bt.createElement("dt",null,"Kernel ID"),t.kernelId&&Bt.createElement("dd",null,t.kernelId),t.ramdiskId&&Bt.createElement("dt",null,"Ramdisk ID"),t.ramdiskId&&Bt.createElement("dd",null,t.ramdiskId),Bt.createElement("dt",null,"User Data"),t.userData&&Bt.createElement("dd",null,Bt.createElement(kt,{serverGroupName:e,userData:t.userData})),!t.userData&&Bt.createElement("dd",null,"[none]"))):null}}function rs(e){return e.instanceTypeOverrides?Bt.createElement(A,{heading:"Instance Types",defaultExpanded:!0,outerDivClassName:"multiple-instance-types-subsection",toggleClassName:"clickable subsection-heading",headingClassName:"collapsible-subheading"},Bt.createElement("table",{className:"table table-condensed packed",id:"MultipleInstanceTypes"},Bt.createElement("thead",null,Bt.createElement("tr",null,Bt.createElement("th",{id:"instanceType"},"Type ",Bt.createElement(n,{id:"aws.serverGroup.multipleInstanceTypes"})),Bt.createElement("th",{id:"weight"},"Weighted Capacity ",Bt.createElement(n,{id:"aws.serverGroup.instanceTypeWeight"})))),Bt.createElement("tbody",null,e.instanceTypeOverrides.map((e=>[Bt.createElement("tr",null,Bt.createElement("td",{headers:"instanceType"},e.instanceType),Bt.createElement("td",{headers:"weight"},e.weightedCapacity))]))))):null}er('.multiple-instance-types-subsection {\n padding: 0;\n}\n.multiple-instance-types-subsection a.subsection-heading {\n color: var(--color-black);\n}\n.multiple-instance-types-subsection h4.collapsible-subheading {\n padding: 10px 0px;\n background-color: var(--color-alabaster);\n margin: 0;\n font-size: 103%;\n font-weight: 600;\n text-transform: none;\n}\n.multiple-instance-types-subsection h4.collapsible-subheading .glyphicon {\n font-size: 10px;\n opacity: 0.5;\n margin-right: 4px;\n}\n.multiple-instance-types-subsection .content-body {\n -webkit-animation: 0.15 ease-in 0 fadeIn;\n animation: 0.15 ease-in 0 fadeIn;\n -webkit-animation-iteration-count: 1;\n animation-iteration-count: 1;\n padding-left: 17px;\n margin: 10px 0 20px 0;\n}\n.multiple-instance-types-subsection .content-body:before,\n.multiple-instance-types-subsection .content-body:after {\n display: table;\n content: " ";\n}\n.multiple-instance-types-subsection .content-body:after {\n clear: both;\n}\n.multiple-instance-types-subsection .content-body ul {\n list-style-type: none;\n padding-left: 0;\n}\n.multiple-instance-types-subsection:last-child {\n border-bottom-width: 0;\n}\n.multiple-instance-types-subsection:first-child {\n padding-top: 0;\n}\n');const is=({serverGroup:e})=>{var t,a,n;const{image:r}=e,i=as(null==r?void 0:r.description);if(!e.launchTemplate&&!e.mixedInstancesPolicy)return null;const s=!!e.mixedInstancesPolicy,l=s?e.mixedInstancesPolicy.launchTemplates[0]:e.launchTemplate,{launchTemplateData:o}=l,c=s?e.mixedInstancesPolicy.instancesDiversification.spotMaxPrice:null==(a=null==(t=null==o?void 0:o.instanceMarketOptions)?void 0:t.spotOptions)?void 0:a.maxPrice,d=null==(n=null==o?void 0:o.creditSpecification)?void 0:n.cpuCredits,p=s?e.mixedInstancesPolicy.launchTemplateOverridesForInstanceType:null;return Bt.createElement(A,{heading:"Launch Template"},Bt.createElement(q,{className:"horizontal-when-filters-collapsed"},Bt.createElement(B,{label:"Name",value:l.launchTemplateName}),Bt.createElement(B,{label:"Image ID",value:o.imageId}),(null==r?void 0:r.imageLocation)&&Bt.createElement(B,{label:"Image Name",value:null==r?void 0:r.imageLocation}),i&&Bt.createElement(B,{label:"Base Image Name",value:i}),p&&p.length>0?Bt.createElement(rs,{instanceTypeOverrides:p}):Bt.createElement(B,{label:"Instance Type",value:o.instanceType}),d&&Bt.createElement(B,{label:"CPU Credit Specification",value:d}),Bt.createElement(B,{label:"IAM Profile",value:o.iamInstanceProfile.name}),o.monitoring&&Bt.createElement(B,{label:"Instance Monitoring",value:o.monitoring.enabled?"enabled":"disabled"}),c&&Bt.createElement(B,{label:"Max Spot Price",value:c}),o.keyName&&Bt.createElement(B,{label:"Key Name",value:o.keyName}),o.kernelId&&Bt.createElement(B,{label:"Kernel ID",value:o.kernelId}),o.ramDiskId&&Bt.createElement(B,{label:"Ramdisk ID",value:o.ramDiskId}),o.userData&&Bt.createElement(B,{label:"User Data",value:Bt.createElement(kt,{serverGroupName:e.name,userData:o.userData})})))};class ss extends Bt.Component{render(){return Bt.createElement(A,{heading:"Logs"},Bt.createElement("ul",null,Bt.createElement("li",null,Bt.createElement(Ct,{serverGroup:this.props.serverGroup}))))}}class ls extends Bt.Component{constructor(e){super(e),this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=t.buildInfo||{};let n=null;a.commit&&(n=t.buildInfo.commit.substring(0,8));let r=null;if(a.buildInfoUrl)r=t.buildInfo.buildInfoUrl;else if(a.jenkins){const e=t.buildInfo.jenkins;r=`${e.host}job/${e.name}/${e.number}`}return{commitHash:n,jenkinsLink:r}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{serverGroup:e}=this.props,{commitHash:t,jenkinsLink:a}=this.state;return e.buildInfo&&e.buildInfo.jenkins?Bt.createElement(A,{heading:"Package"},Bt.createElement("dl",{className:"horizontal-when-filters-collapsed"},Bt.createElement("dt",null,"Job"),Bt.createElement("dd",null,e.buildInfo.jenkins.name),Bt.createElement("dt",null,"Package"),Bt.createElement("dd",null,e.buildInfo.package_name),Bt.createElement("dt",null,"Build"),Bt.createElement("dd",null,e.buildInfo.jenkins.number),Bt.createElement("dt",null,"Commit"),Bt.createElement("dd",null,t),Bt.createElement("dt",null,"Version"),Bt.createElement("dd",null,e.buildInfo.version),Bt.createElement("dt",null,"Build Link"),Bt.createElement("dd",null,Bt.createElement("a",{target:"_blank",href:a},a)))):null}}class os{static upsertScalingPolicy(e,t){return t.type=t.type||"upsertScalingPolicy",R.executeTask({application:e,description:"Upsert scaling policy "+(t.name||t.serverGroupName),job:[t]})}static deleteScalingPolicy(e,t,a){return R.executeTask({application:e,description:"Delete scaling policy "+a.policyName,job:[{type:"deleteScalingPolicy",cloudProvider:"aws",credentials:t.account,region:t.region,policyName:a.policyName,serverGroupName:t.name}]})}}class cs{constructor(e,t,a,n,r){this.$uibModalInstance=e,this.policy=t,this.serverGroup=a,this.application=n,this.$scope=r,this.predefinedMetrics=["ASGAverageCPUUtilization","ASGAverageNetworkOut","ASGAverageNetworkIn"],this.statistics=["Average","Maximum","Minimum","SampleCount","Sum"],this.alarmUpdated=new fa,this.metricTypeChanged=e=>{this.state.metricType=e},this.toggleMetricType=()=>{const e=this.command.targetTrackingConfiguration;"predefined"===this.state.metricType?(e.predefinedMetricSpecification=null,e.customizedMetricSpecification={metricName:"CPUUtilization",namespace:"AWS/EC2",dimensions:[{name:"AutoScalingGroupName",value:this.serverGroup.name}],statistic:"Average"},this.state.metricType="custom"):(e.customizedMetricSpecification=null,e.predefinedMetricSpecification={predefinedMetricType:"ASGAverageCPUUtilization"},this.state.metricType="predefined")},this.updateUnit=e=>{this.state.unit=e},this.alarmChanged=e=>{this.command.targetTrackingConfiguration.customizedMetricSpecification=e,this.alarmUpdated.next()},this.commandChanged=e=>{this.$scope.$applyAsync((()=>{this.command=e}))}}$onInit(){const e=this.policy.targetTrackingConfiguration.customizedMetricSpecification?"custom":"predefined";this.command=this.buildCommand(),this.state={metricType:e,unit:null,scaleInChanged:!1}}scaleInChanged(){this.state.scaleInChanged=!0}cancel(){this.$uibModalInstance.dismiss()}save(){const e=this.policy.policyName?"Update":"Create",t=Rt(this.command);this.taskMonitor=new v({application:this.application,title:`${e} scaling policy for ${this.serverGroup.name}`,modalInstance:this.$uibModalInstance,submitMethod:()=>os.upsertScalingPolicy(this.application,t)}),this.taskMonitor.submit()}buildCommand(){return{type:"upsertScalingPolicy",cloudProvider:"aws",credentials:this.serverGroup.account,region:this.serverGroup.region,serverGroupName:this.serverGroup.name,adjustmentType:null,name:this.policy.policyName,estimatedInstanceWarmup:this.policy.estimatedInstanceWarmup||600,targetTrackingConfiguration:{...this.policy.targetTrackingConfiguration}}}}function ds(e){const[t,a]=Bt.useState(null),r=e=>{a(e.currentTarget.id)},i="step"===t?"card active":"card",s="targetTracking"===t?"card active":"card",l="aws.scalingPolicy.additionalHelp",o=!!P.getHelpField(l);return Bt.createElement(Da,{show:!0,onHide:e.showCallback},Bt.createElement(Da.Header,{closeButton:!0},Bt.createElement("h3",null,"Select a policy type")),Bt.createElement(Da.Body,null,Bt.createElement("div",{className:"card-choices"},Bt.createElement("div",{className:s,onClick:r,id:"targetTracking"},Bt.createElement("h3",null,"Target Tracking"),Bt.createElement("div",null,"Continuously adjusts the size of the ASG to keep a specified metric at the target value")),Bt.createElement("div",{className:i,onClick:r,id:"step"},Bt.createElement("h3",null,"Step"),Bt.createElement("div",null,"Rule-based scaling, with the ability to define different scaling amounts depending on the magnitude of the alarm breach"))),o&&Bt.createElement(de,{type:"info",message:Bt.createElement(n,{id:l,expand:!0})}),e.warnOnMinMaxCapacity&&Bt.createElement(de,{type:"warning",message:Bt.createElement(Bt.Fragment,null,Bt.createElement("p",null,"This server group's ",Bt.createElement("em",null,"min")," and ",Bt.createElement("em",null,"max")," capacity are identical, so scaling policies will have ",Bt.createElement("b",null,"no effect.")),Bt.createElement("p",null,"Scaling policies work by adjusting the server group's ",Bt.createElement("em",null,"desired")," capacity to a value between the min and max."))})),Bt.createElement(Da.Footer,null,Bt.createElement("button",{className:"btn btn-default",onClick:e.showCallback},"Cancel"),Bt.createElement("button",{className:"btn btn-primary",disabled:!t,onClick:()=>{e.typeSelectedCallback(t)}},"Next")))}cs.$inject=["$uibModalInstance","policy","serverGroup","application","$scope"];class ps extends Bt.Component{constructor(e){super(e),this.handleClick=()=>{this.setState({showSelection:!0})},this.typeSelected=e=>{this.setState({typeSelection:e,showSelection:!1,showModal:!0}),"step"===e&&this.createStepPolicy(),"targetTracking"===e&&this.createTargetTrackingPolicy()},this.showModalCallback=()=>{this.setState({showSelection:!1,showModal:!1,typeSelection:null})},this.state={showSelection:!1,showModal:!1,typeSelection:null}}createStepPolicy(){const{serverGroup:e,application:t}=this.props;ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html",controller:"awsUpsertScalingPolicyCtrl",controllerAs:"ctrl",size:"lg",resolve:{policy:()=>Un.awsServerGroupTransformer.constructNewStepScalingPolicyTemplate(e),serverGroup:()=>e,application:()=>t}}).result.catch((()=>{}))}createTargetTrackingPolicy(){const{serverGroup:e,application:t}=this.props;ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html",controller:cs,controllerAs:"$ctrl",size:"lg",resolve:{policy:()=>Un.awsServerGroupTransformer.constructNewTargetTrackingPolicyTemplate(),serverGroup:()=>e,application:()=>t}}).result.catch((()=>{}))}render(){const{min:e,max:t}=this.props.serverGroup.capacity;return Bt.createElement("div",null,Bt.createElement("a",{className:"clickable",onClick:this.handleClick},"Create new scaling policy"),this.state.showSelection&&Bt.createElement(ds,{warnOnMinMaxCapacity:e===t,typeSelectedCallback:this.typeSelected,showCallback:this.showModalCallback}))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html",'<div modal-page class="scaling-policy-modal form-inline">\n <task-monitor monitor="ctrl.taskMonitor"></task-monitor>\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">{{ctrl.action}} scaling policy</h4>\n </div>\n <div class="modal-body">\n <form name="form" novalidate>\n <h4 class="section-heading">Conditions</h4>\n <div class="section-body">\n <alarm-configurer\n alarm="ctrl.command.alarm"\n multiple-alarms="ctrl.viewState.multipleAlarms"\n server-group="ctrl.serverGroup"\n step-adjustments="ctrl.command.step.stepAdjustments"\n steps-changed="ctrl.stepsChanged"\n update-alarm="ctrl.alarmChanged"\n ></alarm-configurer>\n </div>\n <h4 class="section-heading">Actions</h4>\n <div class="section-body" ng-if="!ctrl.command.alarm.metricName">\n <h4 class="text-center">Select a metric</h4>\n </div>\n <div class="section-body" ng-if="ctrl.command.alarm.metricName">\n <div ng-if="ctrl.command.simple">\n <div class="row">\n <div class="col-md-10 col-md-offset-1">\n <p>\n This is a simple scaling policy. To declare different actions based on the magnitude of the alarm,\n <strong>switch to a <a href ng-click="ctrl.switchMode()">step policy</a>.</strong>\n </p>\n </div>\n </div>\n <aws-simple-policy-action\n adjustment-type="ctrl.viewState.adjustmentType"\n adjustment-type-changed="ctrl.adjustmentTypeChanged"\n operator="ctrl.viewState.operator"\n scaling-adjustment="ctrl.command.simple.scalingAdjustment"\n update-scaling-adjustment="ctrl.scalingAdjustmentChanged"\n ></aws-simple-policy-action>\n </div>\n <div ng-if="ctrl.command.step">\n <step-policy-action\n adjustment-type="ctrl.viewState.adjustmentType"\n adjustment-type-changed="ctrl.adjustmentTypeChanged"\n alarm="ctrl.command.alarm"\n is-min="ctrl.viewState.comparatorBound === \'min\'"\n operator="ctrl.viewState.operator"\n step="ctrl.command.step"\n steps-changed="ctrl.stepsChanged"\n >\n </step-policy-action>\n </div>\n </div>\n <scaling-policy-additional-settings\n command="ctrl.command"\n is-instance-type="ctrl.viewState.adjustmentType === \'instances\'"\n is-new="ctrl.viewState.isNew"\n operator="ctrl.viewState.operator"\n update-command="ctrl.commandChanged"\n ></scaling-policy-additional-settings>\n </form>\n </div>\n\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!form.$valid"\n submitting="taskMonitor.submitting"\n on-click="ctrl.save()"\n is-new="ctrl.viewState.isNew"\n ></submit-button>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html",'<div modal-page class="scaling-policy-modal form-inline">\n <task-monitor monitor="$ctrl.taskMonitor"></task-monitor>\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">{{$ctrl.policy.policyName ? "Update" : "Create"}} scaling policy</h4>\n </div>\n <div class="modal-body">\n <form name="form" novalidate>\n <h4 class="section-heading">Target Metric</h4>\n <target-metric-fields\n allow-dual-mode="true"\n cloudwatch="false"\n command="$ctrl.command"\n is-custom-metric="$ctrl.state.metricType === \'custom\'"\n server-group="$ctrl.serverGroup"\n toggle-metric-type="$ctrl.metricTypeChanged"\n unit="$ctrl.state.unit"\n update-command="$ctrl.commandChanged"\n update-unit="$ctrl.updateUnit"\n ></target-metric-fields>\n <h4 class="section-heading">Additional Settings</h4>\n <div class="section-body section-additional-settings">\n <div class="row" ng-if="$ctrl.policy.policyName">\n <div class="col-md-2 sm-label-right">Policy Name</div>\n <div class="col-md-10 content-fields">\n <span class="form-control-static select-placeholder" ng-bind="$ctrl.policy.policyName"></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-md-2 sm-label-right">Warmup</div>\n <div class="col-md-10 content-fields">\n <span class="form-control-static select-placeholder">Instances need</span>\n <input\n type="number"\n style="width: 60px"\n class="form-control input-sm"\n required\n ng-model="$ctrl.command.estimatedInstanceWarmup"\n />\n <span class="input-label"> seconds to warm up </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-md-2 sm-label-right">Scale In</div>\n <div class="col-md-9">\n <div class="checkbox" style="margin-top: 5px">\n <label>\n <input\n type="checkbox"\n ng-model="$ctrl.command.targetTrackingConfiguration.disableScaleIn"\n ng-change="$ctrl.scaleInChanged()"\n />\n Disable Scale-downs\n </label>\n <div class="small" style="margin-top: 5px">\n <p>\n This option disables scale-downs for the target tracking policy, while keeping the scale-ups. This\n means that ASG will not scale down unless you explicitly set up a separate step policy to scale it\n down.\n </p>\n <p>This is useful when you have special requirements, such as gradual or delayed scale-down.</p>\n </div>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="$ctrl.state.scaleInChanged">\n <div class="col-md-10 col-md-offset-1 well">\n <div ng-if="$ctrl.command.targetTrackingConfiguration.disableScaleIn">\n This policy will not scale down. Make sure you have another policy (either TT or Step) that will scale\n down this ASG.\n </div>\n <div ng-if="!$ctrl.command.targetTrackingConfiguration.disableScaleIn">\n This policy will scale both up and down. Make sure you don\'t have other scaling policies, as they will\n likely interfere with each other.\n </div>\n </div>\n </div>\n </div>\n </form>\n </div>\n\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!form.$valid || $ctrl.taskMonitor.submitting"\n submitting="$ctrl.taskMonitor.submitting"\n on-click="$ctrl.save()"\n is-new="!$ctrl.policy.policyName"\n ></submit-button>\n </div>\n</div>\n')}]);var us=Object.defineProperty,ms=Object.getOwnPropertyDescriptor;let gs=class extends Bt.Component{constructor(e){super(e)}static arePoliciesDisabled(e){const t=Zi.normalizeScalingProcesses(e);return e.scalingPolicies.length>0&&t.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","AlarmNotification"].includes(e.name)))}render(){const{app:e,serverGroup:t}=this.props,a=gs.arePoliciesDisabled(t),{ScalingPolicySummary:n}=Rn;return Bt.createElement(A,{cacheKey:"Scaling Policies",heading:({chevron:e})=>Bt.createElement("h4",{className:"collapsible-heading"},e,Bt.createElement("span",null,a&&Bt.createElement(Z,{value:"Some scaling processes are disabled that may prevent scaling policies from working"},Bt.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scaling Policies"))},a&&Bt.createElement("div",{className:"band band-warning"},"Some scaling processes are disabled that may prevent scaling policies from working."),t.scalingPolicies.map((a=>Bt.createElement(n,{key:a.policyARN,policy:a,serverGroup:t,application:e}))),Bt.createElement(ps,{serverGroup:t,application:e}))}};gs=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?ms(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&us(t,a,i),i})([ce("aws.serverGroup.ScalingPoliciesDetailsSection")],gs);class hs extends Bt.Component{constructor(e){super(e),this.toggleScalingProcesses=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scalingProcesses/modifyScalingProcesses.html",controller:"ModifyScalingProcessesCtrl as ctrl",resolve:{serverGroup:()=>t,application:()=>e,processes:()=>this.state.autoScalingProcesses}})))},this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=Zi.normalizeScalingProcesses(t),n=t.scalingPolicies.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","AlarmNotification"].includes(e.name))),r=t.scheduledActions.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","ScheduledAction"].includes(e.name)));return{autoScalingProcesses:a,scalingPoliciesDisabled:n,scheduledActionsDisabled:r}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{autoScalingProcesses:e,scalingPoliciesDisabled:t,scheduledActionsDisabled:a}=this.state;return Bt.createElement(A,{cacheKey:"Scaling Processes",heading:({chevron:e})=>Bt.createElement("h4",{className:"collapsible-heading"},e,Bt.createElement("span",null,t&&Bt.createElement(Z,{value:"Some scaling processes are disabled that may prevent scaling policies from working"},Bt.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),a&&Bt.createElement(Z,{value:"Some scaling processes are disabled that may prevent scheduled actions from working"},Bt.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scaling Processes"))},Bt.createElement("ul",{className:"scaling-processes"},e.map((e=>Bt.createElement("li",{key:e.name},Bt.createElement("span",{style:{visibility:e.enabled?"visible":"hidden"},className:"fa fa-check small"}),Bt.createElement("span",{className:e.enabled?"":"text-disabled"},e.name," "),Bt.createElement(n,{content:e.description,placement:"bottom"}),e.suspensionDate&&Bt.createElement("div",{className:"text-disabled small",style:{marginLeft:"35px"}},"Suspended ",D(e.suspensionDate)))))),Bt.createElement("a",{className:"clickable",onClick:this.toggleScalingProcesses},"Edit Scaling Processes"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingProcesses/modifyScalingProcesses.html",'<div modal-page class="confirmation-modal">\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Modify Scaling Processes for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-sm-offset-2 col-sm-10">\n <div class="checkbox" ng-repeat="process in command">\n <label>\n <input type="checkbox" ng-model="process.enabled" />\n {{process.name}}\n </label>\n <help-field content="{{process.description}}" placement="right"></help-field>\n </div>\n </div>\n </div>\n </div>\n <task-reason command="command"></task-reason>\n <aws-footer\n action="ctrl.submit()"\n cancel="ctrl.cancel()"\n is-valid="ctrl.isValid()"\n account="serverGroup.account"\n verification="verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class fs extends Bt.Component{render(){const{action:e}=this.props;return Bt.createElement("dl",{className:"horizontal-when-filters-collapsed",style:{marginBottom:"20px"}},Bt.createElement("dt",null,"Schedule"),Bt.createElement("dd",null,e.recurrence),void 0!==e.minSize&&Bt.createElement("dt",null,"Min Size"),void 0!==e.minSize&&Bt.createElement("dd",null,e.minSize),void 0!==e.maxSize&&Bt.createElement("dt",null,"Max Size"),void 0!==e.maxSize&&Bt.createElement("dd",null,e.maxSize),void 0!==e.desiredCapacity&&Bt.createElement("dt",null,"Desired Size"),void 0!==e.desiredCapacity&&Bt.createElement("dd",null,e.desiredCapacity))}}class vs extends Bt.Component{constructor(e){super(e),this.editScheduledActions=()=>{ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scheduledAction/editScheduledActions.modal.html",controller:"EditScheduledActionsCtrl as ctrl",resolve:{application:()=>this.props.app,serverGroup:()=>this.props.serverGroup}})},this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=Zi.normalizeScalingProcesses(t);return{scheduledActionsDisabled:t.scheduledActions.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","ScheduledAction"].includes(e.name)))}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{serverGroup:e}=this.props,{scheduledActionsDisabled:t}=this.state;return Bt.createElement(A,{cacheKey:"Scheduled Actions",heading:({chevron:e})=>Bt.createElement("h4",{className:"collapsible-heading"},e,Bt.createElement("span",null,t&&Bt.createElement(Z,{value:"Some scaling processes are disabled that may prevent scheduled actions from working"},Bt.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scheduled Actions"))},e.scheduledActions.map(((e,t)=>Bt.createElement(fs,{key:t,action:e}))),e.scheduledActions.length>0&&Bt.createElement("p",null,Bt.createElement("strong",null,"Note:")," Schedules are evaluated in UTC."),0===e.scheduledActions.length&&Bt.createElement("p",null,"No Scheduled Actions are configured for this server group."),Bt.createElement("a",{className:"clickable",onClick:this.editScheduledActions},"Edit Scheduled Actions"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scheduledAction/editScheduledActions.modal.html",'<div modal-page>\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Edit Scheduled Actions for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <p>You must specify at least one of: Min Size, Max Size, Desired Capacity</p>\n <p><strong>Note:</strong> CRON expressions are evaluated in UTC.</p>\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th>Recurrence (CRON)</th>\n <th>Min Size</th>\n <th>Max Size</th>\n <th>Desired Capacity</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="action in command.scheduledActions">\n <td>\n <input\n class="form-control input-sm no-spel"\n type="text"\n ng-model="action.recurrence"\n name="recurrence-{{$index}}"\n required\n />\n \x3c!-- TODO: Add cron-validator when endpoint is fixed --\x3e\n <div class="form-group row slide-in" ng-if="form[\'recurrence-\' + $index].$error.cronExpression">\n <div class="error-message">{{cronErrors[\'action.recurrence.cronExpression\']}}</div>\n </div>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n max="{{action.maxSize || Infinity}}"\n ng-model="action.minSize"\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n min="{{action.minSize || 0}}"\n ng-model="action.maxSize"\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n ng-model="action.desiredCapacity"\n min="{{command.minSize || 0}}"\n max="{{command.maxSize || Infinity}}"\n />\n </td>\n <td>\n <a href class="sm-label" ng-click="ctrl.removeScheduledAction($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.addScheduledAction()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new Scheduled Action\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <button type="submit" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="ctrl.submit()">Submit</button>\n </div>\n </form>\n</div>\n')}]);class ys extends Bt.Component{constructor(e){super(e),this.updateSecurityGroups=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/securityGroup/editSecurityGroups.modal.html",controller:"EditSecurityGroupsCtrl as $ctrl",resolve:{application:()=>e,serverGroup:()=>t,securityGroups:()=>this.state.securityGroups}})))},this.state={securityGroups:this.getSecurityGroups(e)}}tryFindingSecurityGroupInIndex(e,t,a,n){try{return vi.resolveIndexedSecurityGroup(e,{account:t,region:a},n)}catch(e){return}}getSecurityGroups(e){let t;const{app:a,serverGroup:n}=e;return n.securityGroups&&n.securityGroups.length&&(t=ea(n.securityGroups).map((e=>oa(a.securityGroups.data,{accountName:n.account,region:n.region,id:e})||oa(a.securityGroups.data,{accountName:n.account,region:n.region,name:e})||this.tryFindingSecurityGroupInIndex(a.securityGroupsIndex,n.account,n.region,e)||{id:e,name:e})).compact().value()),t}componentWillReceiveProps(e){this.setState({securityGroups:this.getSecurityGroups(e)})}render(){const{serverGroup:e}=this.props,{securityGroups:t}=this.state;return Bt.createElement(A,{heading:U.get("Firewalls")},Bt.createElement("ul",null,qt(t,"name").map((t=>Bt.createElement("li",{key:t.name},Bt.createElement(ja,{to:"^.firewallDetails",params:{name:t.name,accountId:t.accountName,region:e.region,vpcId:e.vpcId,provider:e.type}},Bt.createElement("a",null,t.name," (",t.id,")")))))),e.vpcId&&Bt.createElement("a",{className:"clickable",onClick:this.updateSecurityGroups},"Edit ",U.get("Firewalls")))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/securityGroup/editSecurityGroups.modal.html",'<div modal-page>\n <task-monitor monitor="$ctrl.taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">\n Edit <firewall-label label="Firewalls"></firewall-label> for {{$ctrl.serverGroup.name}}\n </h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-10 col-md-offset-1">\n <ui-select\n multiple\n ng-model="$ctrl.command.securityGroups"\n uis-open-close="$ctrl.resetCurrentItems()"\n class="form-control input-sm"\n >\n <ui-select-match>{{$item.name}} ({{$item.id}})</ui-select-match>\n <ui-select-choices\n repeat="securityGroup as securityGroup in $ctrl.availableSecurityGroups | filter: $select.search | limitTo: $ctrl.infiniteScroll.currentItems"\n infinite-scroll="$ctrl.addMoreItems()"\n infinite-scroll-distance="4"\n >\n <span ng-bind-html="securityGroup.name | highlight: $select.search"></span>\n (<span ng-bind-html="securityGroup.id | highlight: $select.search"></span>)\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n </div>\n <aws-footer\n action="$ctrl.submit()"\n cancel="$ctrl.cancel()"\n is-valid="$ctrl.isValid()"\n account="$ctrl.serverGroup.account"\n verification="$ctrl.state.verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class bs extends Bt.Component{render(){const{serverGroup:e}=this.props;return Bt.createElement(A,{heading:"Tags"},0===e.asg.tags.length&&Bt.createElement("div",null,"No tags associated with this server group"),e.asg.tags.length>0&&Bt.createElement("dl",null,qt(e.asg.tags,"key").map((e=>[Bt.createElement("dt",{key:e.key},e.key),Bt.createElement("dd",{key:e.value},e.value)]))))}}class ws{static listKeyPairs(){return z("/keyPairs").useCache().get().then((e=>e.sort(((e,t)=>e.keyName.localeCompare(t.keyName)))))}}class Es{constructor(e,t,a,n,r){this.securityGroupReader=e,this.awsInstanceTypeService=t,this.cacheInitializer=a,this.loadBalancerReader=n,this.serverGroupCommandRegistry=r,this.enabledMetrics=["GroupMinSize","GroupMaxSize","GroupDesiredCapacity","GroupInServiceInstances","GroupPendingInstances","GroupStandbyInstances","GroupTerminatingInstances","GroupTotalInstances"],this.healthCheckTypes=["EC2","ELB"],this.terminationPolicies=["OldestInstance","NewestInstance","OldestLaunchConfiguration","ClosestToNextInstanceHour","Default"]}configureUpdateCommand(e){e.backingData={enabledMetrics:da(this.enabledMetrics),healthCheckTypes:da(this.healthCheckTypes),terminationPolicies:da(this.terminationPolicies)}}configureCommand(e,t){return this.applyOverrides("beforeConfiguration",t),t.toggleSuspendedProcess=(e,t)=>{e.suspendedProcesses=e.suspendedProcesses||[];const a=e.suspendedProcesses.indexOf(t);e.suspendedProcesses=-1===a?e.suspendedProcesses.concat(t):e.suspendedProcesses.filter((e=>e!==t))},t.processIsSuspended=(e,t)=>e.suspendedProcesses.includes(t),t.onStrategyChange=(e,t)=>{var a;(null==(a=gn.serverGroups)?void 0:a.enableLaunchTemplates)&&(e.setLaunchTemplate="rollingpush"===t.key||void 0),""!==t.key&&"custom"!==t.key&&(e.suspendedProcesses=(e.suspendedProcesses||[]).filter((e=>"AddToLoadBalancer"!==e)))},t.getBlockDeviceMappingsSource=e=>e.copySourceCustomBlockDeviceMappings?"source":e.useAmiBlockDeviceMappings?"ami":"default",t.selectBlockDeviceMappingsSource=(e,t)=>{"source"===t?(e.copySourceCustomBlockDeviceMappings=!0,e.useAmiBlockDeviceMappings=!1):"ami"===t?(e.copySourceCustomBlockDeviceMappings=!1,e.useAmiBlockDeviceMappings=!0):(e.copySourceCustomBlockDeviceMappings=!1,e.useAmiBlockDeviceMappings=!1)},t.regionIsDeprecated=e=>ca(e,"backingData.filtered.regions")&&e.backingData.filtered.regions.some((t=>t.name===e.region&&t.deprecated)),Ua.all([o.getCredentialsKeyedByAccount("aws"),this.securityGroupReader.getAllSecurityGroups(),g.listSubnets(),o.getPreferredZonesByAccount("aws"),ws.listKeyPairs(),this.awsInstanceTypeService.getAllTypesByRegion(),Ua.when(da(this.enabledMetrics)),Ua.when(da(this.healthCheckTypes)),Ua.when(da(this.terminationPolicies))]).then((([a,n,r,i,s,l,o,c,d])=>{var p,u;const m={credentialsKeyedByAccount:a,securityGroups:n,subnets:r,preferredZones:i,keyPairs:s,instanceTypes:l,enabledMetrics:o,healthCheckTypes:c,terminationPolicies:d};let g=Ua.when();if(m.accounts=pa(m.credentialsKeyedByAccount),m.filtered={},m.scalingProcesses=Zi.listProcesses(),m.appLoadBalancers=e.getDataSource("loadBalancers").data,m.managedResources=null==(u=null==(p=e.getDataSource("managedResources"))?void 0:p.data)?void 0:u.resources,t.backingData=m,this.configureVpcId(t),m.filtered.securityGroups=this.getRegionalSecurityGroups(t),t.viewState.disableImageSelection&&this.configureInstanceTypes(t),t.securityGroups&&t.securityGroups.length){const e=aa(this.getRegionalSecurityGroups(t),"id");la(t.securityGroups,e).length<t.securityGroups.length&&(g=this.refreshSecurityGroups(t,!0))}return g.then((()=>{this.applyOverrides("afterConfiguration",t),this.attachEventHandlers(t)}))}))}applyOverrides(e,t){this.serverGroupCommandRegistry.getCommandOverrides("aws").forEach((a=>{a[e]&&a[e](t)}))}configureKeyPairs(e){const t={dirty:{}};if(e.credentials&&e.region){const a=Yt(e.backingData.credentialsKeyedByAccount,(t=>t.defaultKeyPair&&e.keyPair&&0===e.keyPair.indexOf(t.defaultKeyPair.replace("{{region}}","")))),n=ea(e.backingData.keyPairs).filter({account:e.credentials,region:e.region}).map("keyName").value();if(e.keyPair&&n.length&&!n.includes(e.keyPair)){const r=e.backingData.credentialsKeyedByAccount[e.credentials]||{regions:[],defaultKeyPair:null};if(r.defaultKeyPair){const i=r.defaultKeyPair.replace("{{region}}",e.region);a&&n.includes(i)?e.keyPair=i:(e.keyPair=null,t.dirty.keyPair=!0)}else e.keyPair=null,t.dirty.keyPair=!0}e.backingData.filtered.keyPairs=n}else e.backingData.filtered.keyPairs=[];return t}configureInstanceTypes(e){const t={dirty:{}};if(e.region&&(e.virtualizationType||e.viewState.disableImageSelection)){let a=this.awsInstanceTypeService.getAvailableTypesForRegions(e.backingData.instanceTypes,[e.region]);e.virtualizationType&&(a=this.awsInstanceTypeService.filterInstanceTypes(a,e.virtualizationType,!!e.vpcId)),e.instanceType&&!a.includes(e.instanceType)&&(t.dirty.instanceType=e.instanceType,e.instanceType=null),e.backingData.filtered.instanceTypes=a}else e.backingData.filtered.instanceTypes=[];return sa(e.viewState.dirty,t.dirty),t}configureImages(e){const t={dirty:{}};return e.amiName||(e.virtualizationType=null),e.viewState.disableImageSelection||e.amiName&&!e.region&&(t.dirty.amiName=!0,e.amiName=null),t}configureAvailabilityZones(e){e.backingData.filtered.availabilityZones=oa(e.backingData.credentialsKeyedByAccount[e.credentials].regions,{name:e.region}).availabilityZones}configureSubnetPurposes(e){const t={dirty:{}},a=e.backingData.filtered;return null===e.region||(a.subnetPurposes=ea(e.backingData.subnets).filter({account:e.credentials,region:e.region}).reject({target:"elb"}).reject({purpose:null}).uniqBy("purpose").value(),ea(a.subnetPurposes).some({purpose:e.subnetType}).value()||(e.subnetType=null,t.dirty.subnetType=!0)),t}getRegionalSecurityGroups(e){const t=e.backingData.securityGroups[e.credentials]||{aws:{}};return ea(t.aws[e.region]).filter({vpcId:e.vpcId||null}).sortBy("name").value()}configureSecurityGroupOptions(e){const t={dirty:{}},a=e.backingData.filtered.securityGroups,n=this.getRegionalSecurityGroups(e),r="string"==typeof e.securityGroups&&e.securityGroups.includes("${");if(a&&e.securityGroups&&!r){const r=e.securityGroups.map((e=>{const t=oa(a,{id:e});return t?t.name:e})),i=e.securityGroups.map((e=>{const t=oa(a,{id:e})||oa(a,{name:e});return t?t.name:null})).map((e=>oa(n,{name:e}))).filter((e=>e)),s=aa(i,"name"),l=ua(r,s);e.securityGroups=aa(i,"id"),l.length&&(t.dirty.securityGroups=l)}return e.backingData.filtered.securityGroups=n.sort(((e,t)=>e.name.localeCompare(t.name))),t}refreshSecurityGroups(e,t){return this.cacheInitializer.refreshCache("securityGroups").then((()=>this.securityGroupReader.getAllSecurityGroups().then((a=>{e.backingData.securityGroups=a,t||this.configureSecurityGroupOptions(e)}))))}getLoadBalancerMap(e){if(e.backingData.loadBalancers)return ea(e.backingData.loadBalancers).map("accounts").flattenDeep().filter({name:e.credentials}).map("regions").flattenDeep().filter({name:e.region}).map("loadBalancers").flattenDeep().value();return(e.backingData.appLoadBalancers||[]).filter((t=>t.region===e.region&&t.account===e.credentials))}getLoadBalancerNames(e){return this.getLoadBalancerMap(e).filter((t=>(!t.loadBalancerType||"classic"===t.loadBalancerType)&&t.vpcId===e.vpcId)).map((e=>e.name)).sort()}getVpcLoadBalancerNames(e){return this.getLoadBalancerMap(e).filter((e=>(!e.loadBalancerType||"classic"===e.loadBalancerType)&&e.vpcId)).map((e=>e.name)).sort()}getTargetGroupNames(e){const t=this.getLoadBalancerMap(e).filter((e=>"classic"!==e.loadBalancerType));return Ot(t.map((e=>e.targetGroups.filter((e=>"instance"===e.targetType))))).map((e=>e.name)).sort()}getValidMatches(e,t){const a=t.filter((e=>e.includes("${"))),n=la(e,t),[r,i]=ta(t,(e=>n.includes(e)||a.includes(e)));return{valid:r,invalid:i,spel:a}}configureLoadBalancerOptions(e){const t={dirty:{}},a=(e.loadBalancers||[]).concat(e.vpcLoadBalancers||[]),n=e.targetGroups||[],r=this.getLoadBalancerNames(e),i=this.getVpcLoadBalancerNames(e),s=this.getTargetGroupNames(e);if(a&&e.loadBalancers){const n=e.vpcId?r:r.concat(i),{valid:s,invalid:l,spel:o}=this.getValidMatches(n,a);e.loadBalancers=la(r.concat(o),s),e.vpcId?delete e.vpcLoadBalancers:e.vpcLoadBalancers=la(i,s),l.length&&(t.dirty.loadBalancers=l),e.viewState.spelLoadBalancers=o||[]}if(n&&e.targetGroups&&!n.includes("${")){const{valid:a,invalid:r,spel:i}=this.getValidMatches(s,n);e.targetGroups=a,r.length&&(t.dirty.targetGroups=r),e.viewState.spelTargetGroups=i||[]}return e.backingData.filtered.loadBalancers=r,e.backingData.filtered.vpcLoadBalancers=i,e.backingData.filtered.targetGroups=s,t}refreshLoadBalancers(e,t){return this.loadBalancerReader.listLoadBalancers("aws").then((a=>{e.backingData.loadBalancers=a,t||this.configureLoadBalancerOptions(e)}))}configureVpcId(e){const t={dirty:{}};if(e.subnetType){const t=oa(e.backingData.subnets,{purpose:e.subnetType,account:e.credentials,region:e.region});e.vpcId=t?t.vpcId:null}else e.vpcId=null,t.dirty.vpcId=!0;return sa(t.dirty,this.configureInstanceTypes(e).dirty),t}attachEventHandlers(e){e.usePreferredZonesChanged=e=>{const t=e.availabilityZones?e.availabilityZones.length:0,a={dirty:{}},n=e.backingData.preferredZones[e.credentials];if(n&&n[e.region]&&e.viewState.usePreferredZones)e.availabilityZones=Rt(n[e.region].sort());else{e.availabilityZones=la(e.availabilityZones,e.backingData.filtered.availabilityZones);t!==(e.availabilityZones?e.availabilityZones.length:0)&&(a.dirty.availabilityZones=!0)}return a},e.subnetChanged=e=>{const t=this.configureVpcId(e);return sa(t.dirty,this.configureSecurityGroupOptions(e).dirty),sa(t.dirty,this.configureLoadBalancerOptions(e).dirty),e.viewState.dirty=e.viewState.dirty||{},sa(e.viewState.dirty,t.dirty),t},e.regionChanged=e=>{const t={dirty:{}},a=e.backingData.filtered;return sa(t.dirty,this.configureSubnetPurposes(e).dirty),e.region?(sa(t.dirty,e.subnetChanged(e).dirty),sa(t.dirty,this.configureInstanceTypes(e).dirty),this.configureAvailabilityZones(e),sa(t.dirty,e.usePreferredZonesChanged(e).dirty),sa(t.dirty,this.configureImages(e).dirty),sa(t.dirty,this.configureKeyPairs(e).dirty)):a.regionalAvailabilityZones=null,St(e),t},e.clusterChanged=e=>{e.moniker=Ee.getMoniker(e.application,e.stack,e.freeFormDetails),St(e)},e.credentialsChanged=e=>{const t={dirty:{}},a=e.backingData;if(e.credentials){const n=a.credentialsKeyedByAccount[e.credentials]||{regions:[],defaultKeyPair:null};a.filtered.regions=n.regions,Yt(a.filtered.regions,{name:e.region})?sa(t.dirty,e.regionChanged(e).dirty):(e.region=null,t.dirty.region=!0)}else e.region=null;return St(e),t},e.imageChanged=e=>this.configureInstanceTypes(e),e.instanceTypeChanged=e=>{e.ebsOptimized=this.awsInstanceTypeService.isEbsOptimized(e.instanceType)},this.applyOverrides("attachEventHandlers",e)}}Es.$inject=["securityGroupReader","awsInstanceTypeService","cacheInitializer","loadBalancerReader","serverGroupCommandRegistry"];const Cs="spinnaker.amazon.serverGroup.configure.service";t("spinnaker.amazon.serverGroup.configure.service",[Te,"spinnaker.amazon.instanceType.service",Ie,Je,Gt]).service("awsServerGroupConfigurationService",Es);e.module("spinnaker.amazon.serverGroupCommandBuilder.service",[Nt,"spinnaker.amazon.serverGroup.configure.service"]).factory("awsServerGroupCommandBuilder",["$q","instanceTypeService","awsServerGroupConfigurationService",function(t,a,n){function i(e,a){a=a||{};const n=o.getCredentialsKeyedByAccount("aws"),r=a.account||e.defaultCredentials.aws||gn.defaults.account,i=a.region||e.defaultRegions.aws||gn.defaults.region,l=a.subnet||gn.defaults.subnetType||"",c=o.getAvailabilityZonesForAccountAndRegion("aws",r,i);return t.all([c,n]).then((function([t,n]){const o=n[r],c=o?o.defaultKeyPair:null,d=$t.get(e,"attributes.providerSettings.aws",{});let p=gn.defaults.iamRole||"BaseIAMRole";p=p.replace("{{application}}",e.name);const u=d.useAmiBlockDeviceMappings||!1,m={application:e.name,credentials:r,region:i,strategy:"",capacity:{min:1,max:1,desired:1},targetHealthyDeployPercentage:100,cooldown:10,enabledMetrics:[],healthCheckType:"EC2",healthCheckGracePeriod:600,instanceMonitoring:!1,ebsOptimized:!1,selectedProvider:"aws",iamRole:p,terminationPolicies:["Default"],vpcId:null,subnetType:l,availabilityZones:t,keyPair:c,suspendedProcesses:[],securityGroups:[],stack:"",freeFormDetails:"",spotPrice:"",tags:{},useAmiBlockDeviceMappings:u,copySourceCustomBlockDeviceMappings:!1,viewState:{instanceProfile:"custom",useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!0,mode:a.mode||"create",disableStrategySelection:!0,dirty:{},submitButtonLabel:s(a.mode||"create")}};if(e.attributes&&e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(m.interestingHealthProviderNames=["Amazon"]),"test"===r&&gn.serverGroups&&gn.serverGroups.enableIPv6&&(m.associateIPv6Address=!0),gn.serverGroups&&gn.serverGroups.enableIMDSv2){const t=gn.serverGroups.defaultIMDSv2AppAgeLimit,a=e.attributes&&e.attributes.createTs;m.requireIMDSv2=!!(t&&a&&Number(a)>t)}return m}))}function s(e){switch(e){case"createPipeline":return"Add";case"editPipeline":return"Done";case"clone":return"Clone";default:return"Create"}}return{buildNewServerGroupCommand:i,buildServerGroupCommandFromExisting:function(n,i,l="clone"){const c=o.getPreferredZonesByAccount("aws"),d=g.listSubnets(),p=Ee.parseServerGroupName(i.asg.autoScalingGroupName),u=i.launchConfig?i.launchConfig.instanceType:i.launchTemplate?i.launchTemplate.launchTemplateData.instanceType:null,m=a.getCategoryForInstanceType("aws",u);return t.all([c,d,m]).then((function([t,a,o]){const c=i.asg.availabilityZones.sort();let d=!1;const u=t[i.account];if(u){const e=u[i.region].sort();d=c.join(",")===e.join(",")}const m=["Launch","Terminate","AddToLoadBalancer"],g=$t.get(n,"attributes.providerSettings.aws",{}).useAmiBlockDeviceMappings||!1,h={},f=["spinnaker:application","spinnaker:stack","spinnaker:details"];i.asg.tags&&i.asg.tags.filter((e=>!f.includes(e.key))).forEach((e=>{h[e.key]=e.value}));const v={application:n.name,strategy:"",stack:p.stack,freeFormDetails:p.freeFormDetails,credentials:i.account,cooldown:i.asg.defaultCooldown,enabledMetrics:$t.get(i,"asg.enabledMetrics",[]).map((e=>e.metric)),healthCheckGracePeriod:i.asg.healthCheckGracePeriod,healthCheckType:i.asg.healthCheckType,terminationPolicies:i.asg.terminationPolicies,loadBalancers:i.asg.loadBalancerNames,region:i.region,useSourceCapacity:!1,capacity:{min:i.asg.minSize,max:i.asg.maxSize,desired:i.asg.desiredCapacity},targetHealthyDeployPercentage:100,availabilityZones:c,selectedProvider:"aws",source:{account:i.account,region:i.region,asgName:i.asg.autoScalingGroupName},suspendedProcesses:(i.asg.suspendedProcesses||[]).map((e=>e.processName)).filter((e=>!m.includes(e))),tags:Object.assign({},i.tags,h),targetGroups:i.targetGroups,useAmiBlockDeviceMappings:g,copySourceCustomBlockDeviceMappings:"clone"===l,viewState:{instanceProfile:o,useAllImageSelection:!1,useSimpleCapacity:i.asg.minSize===i.asg.maxSize,usePreferredZones:d,mode:l,submitButtonLabel:s(l),isNew:!1,dirty:{}}};if(n.attributes&&n.attributes.platformHealthOnlyShowOverride&&n.attributes.platformHealthOnly&&(v.interestingHealthProviderNames=["Amazon"]),"editPipeline"===l){v.useSourceCapacity=!0,v.viewState.useSimpleCapacity=!1,v.strategy="redblack";const e=r.getStrategy("redblack");e.initializationMethod&&e.initializationMethod(v),v.suspendedProcesses=[]}const y=i.asg.vpczoneIdentifier;if(""!==y){const e=y.split(",")[0],t=$t.chain(a).find({id:e}).value();v.subnetType=t.purpose,v.vpcId=t.vpcId}else v.subnetType="",v.vpcId=null;if(i.launchConfig&&(e.extend(v,{instanceType:i.launchConfig.instanceType,iamRole:i.launchConfig.iamInstanceProfile,keyPair:i.launchConfig.keyName,associatePublicIpAddress:i.launchConfig.associatePublicIpAddress,ramdiskId:i.launchConfig.ramdiskId,instanceMonitoring:i.launchConfig.instanceMonitoring.enabled,ebsOptimized:i.launchConfig.ebsOptimized,spotPrice:i.launchConfig.spotPrice}),i.launchConfig.userData&&(v.base64UserData=i.launchConfig.userData),v.viewState.imageId=i.launchConfig.imageId),i.launchTemplate){const{launchTemplateData:t}=i.launchTemplate,a=t.instanceMarketOptions&&t.instanceMarketOptions.spotOptions&&t.instanceMarketOptions.spotOptions.maxPrice,{ipv6AddressCount:n}=t.networkInterfaces&&t.networkInterfaces.length&&t.networkInterfaces[0],r=gn.serverGroups,s=i.accountDetails&&"test"===i.accountDetails.environment,l=r&&r.enableIPv6&&r.setIPv6InTest&&s;e.extend(v,{instanceType:t.instanceType,iamRole:t.iamInstanceProfile.name,keyPair:t.keyName,associateIPv6Address:l||Boolean(n),ramdiskId:t.ramdiskId,instanceMonitoring:t.monitoring.enabled,ebsOptimized:t.ebsOptimized,spotPrice:a||void 0,requireIMDSv2:Boolean(t.metadataOptions&&"required"===t.metadataOptions.httpsTokens),unlimitedCpuCredits:t.creditSpecification?"unlimited"===t.creditSpecification.cpuCredits:void 0}),v.viewState.imageId=t.imageId}if("clone"===l&&i.image&&i.image.name&&(v.amiName=i.image.name),i.launchConfig&&i.launchConfig.securityGroups.length&&(v.securityGroups=i.launchConfig.securityGroups),i.launchTemplate&&i.launchTemplate.launchTemplateData.securityGroups.length&&(v.securityGroups=i.launchTemplate.launchTemplateData.securityGroups),i.launchTemplate&&i.launchTemplate.launchTemplateData.networkInterfaces){const e=i.launchTemplate.launchTemplateData.networkInterfaces.find((e=>0===e.deviceIndex))||{};v.securityGroups=e.groups}return v}))},buildNewServerGroupCommandForPipeline:function(){return t.when({viewState:{requiresTemplateSelection:!0}})},buildServerGroupCommandFromPipeline:function(n,r){const s=$t.cloneDeep(r),l=Object.keys(s.availabilityZones)[0],o=a.getCategoryForInstanceType("aws",s.instanceType),c={account:s.account,region:l};return t.all([i(n,c),o]).then((function([t,a]){const n=s.availabilityZones[l].join(",")===t.availabilityZones.join(","),r={instanceProfile:a,disableImageSelection:!0,useSimpleCapacity:s.capacity.min===s.capacity.max&&!0!==s.useSourceCapacity,usePreferredZones:n,mode:"editPipeline",submitButtonLabel:"Done",templatingEnabled:!0,existingPipelineCluster:!0,dirty:{}},i={region:l,credentials:s.account,availabilityZones:s.availabilityZones[l],iamRole:s.iamRole,viewState:r};return s.strategy=s.strategy||"",e.extend({},t,s,i)}))},buildUpdateServerGroupCommand:function(t){const a={type:"modifyAsg",asgs:[{asgName:t.name,region:t.region}],cooldown:t.asg.defaultCooldown,enabledMetrics:$t.get(t,"asg.enabledMetrics",[]).map((e=>e.metric)),healthCheckGracePeriod:t.asg.healthCheckGracePeriod,healthCheckType:t.asg.healthCheckType,terminationPolicies:e.copy(t.asg.terminationPolicies),credentials:t.account,capacityRebalance:t.asg.capacityRebalance};return n.configureUpdateCommand(a),a}}}]);t("spinnaker.amazon.serverGroup.editAsgAdvancedSettings.modal.controller",["spinnaker.amazon.serverGroupCommandBuilder.service"]).controller("EditAsgAdvancedSettingsCtrl",["$scope","$uibModalInstance","application","serverGroup","awsServerGroupCommandBuilder",function(e,t,a,n,r){e.command=r.buildUpdateServerGroupCommand(n),e.serverGroup=n,e.taskMonitor=new v({application:a,title:"Update Advanced Settings for "+n.name,modalInstance:t,onTaskComplete:()=>a.serverGroups.refresh()}),this.submit=()=>{const t=[e.command];e.taskMonitor.submit((function(){return R.executeTask({job:t,application:a,description:"Update Advanced Settings for "+n.name})}))},this.cancel=t.dismiss}]);function ks(e){const t=zt.useRef(),a=zt.useRef(),{lines:n,className:r="",style:i={}}=e;return zt.useEffect((()=>{return t?(a.current=(e=t.current,new an(e,{type:"line",data:{labels:[],datasets:[{data:[]}]},options:{plugins:{tooltip:{mode:"index",itemSort:(e,t)=>{var a,n;const r=e.chart.data.datasets.map((e=>e.label)),i=null!=(a=e.dataset.label)?a:r[0],s=null!=(n=t.dataset.label)?n:r[0];return r.indexOf(s)-r.indexOf(i)}}},hover:{mode:"index"},elements:{point:{hitRadius:12,radius:1,hoverRadius:5}},scales:{x:{type:"time",display:!0,scaleLabel:{labelString:"Date"},ticks:{major:{enabled:!0}}},y:{min:0,stacked:!0}}}})),()=>{var e;return null==(e=a.current)?void 0:e.destroy()}):null;var e}),[t.current]),zt.useEffect((()=>{const e=a.current;e&&n&&(e.options.animation=!1,e.data.datasets=n,e.update())}),[a.current,n]),zt.createElement("canvas",{ref:t,...i,className:r})}function Ss(e){return e.serverGroup&&e.alarm?zt.createElement(Gs,{...e}):null}function Gs(e){var t,a;const n=null!=(t=e.alarm)?t:{},r=null!=(a=e.serverGroup)?a:{},{type:i,account:s,region:l}=r,{metricName:o,namespace:c,statistic:d,period:p}=n,{status:u,result:m}=$((async()=>{var t;const a={namespace:c,statistics:d,period:p};n.dimensions.forEach((e=>a[e.name]=e.value));const r=await It.getMetricStatistics(i,s,l,o,a);return r.datapoints=r.datapoints||[],null==(t=e.onChartLoaded)||t.call(e,r),r}),{datapoints:[],unit:""},[c,d,p,i,s,l,o]),g=xt();if(At(e.alarmUpdated,(()=>g())),"PENDING"===u)return zt.createElement("div",{className:"flex-container-v middle center sp-margin-xl"},zt.createElement(te,null));if("REJECTED"===u)return zt.createElement(zt.Fragment,null,zt.createElement("div",null,"no data"),zt.createElement("div",null,"something went wrong fetching stats"));if(0===m.datapoints.length)return zt.createElement(zt.Fragment,null,"no data");const h=new Date,f=new Date(Date.now()-864e5),v={label:o,fill:"stack",borderColor:"green",borderWidth:2,data:m.datapoints.map((e=>({x:new Date(e.timestamp),y:e.average})))},y={label:"threshold",borderWidth:1,borderColor:"red",data:[{x:f,y:n.threshold},{x:h,y:n.threshold}]};return zt.createElement(ks,{lines:[v,y]})}t("spinnaker.amazon.serverGroup.details.rollback.controller",[Tt]).controller("awsRollbackServerGroupCtrl",["$scope","$uibModalInstance","serverGroupWriter","application","serverGroup","previousServerGroup","disabledServerGroups","allServerGroups",function(e,t,a,n,r,i,s,l){e.serverGroup=r,e.disabledServerGroups=s.sort(((e,t)=>t.name.localeCompare(e.name))),e.allServerGroups=l.sort(((e,t)=>t.name.localeCompare(e.name))),e.verification={};const o=r.capacity.desired;let c,d="EXPLICIT";if(0===l.length&&r.entityTags){const t=Zt(r,"entityTags.creationMetadata.value.previousServerGroup");if(t){d="PREVIOUS_IMAGE",e.previousServerGroup={name:t.name,imageName:t.imageName},t.imageId&&t.imageId!==t.imageName&&(e.previousServerGroup.imageId=t.imageId);const a=Zt(t,"buildInfo.jenkins.number");a&&(e.previousServerGroup.buildNumber=a)}}c=o<10?100:o<20?90:95,e.command={rollbackType:d,rollbackContext:{rollbackServerGroupName:r.name,restoreServerGroupName:i?i.name:void 0,targetHealthyRollbackPercentage:c,delayBeforeDisableSeconds:0}},e.minHealthy=function(e){return Math.ceil(o*e/100)},n&&n.attributes&&(n.attributes.platformHealthOnlyShowOverride&&n.attributes.platformHealthOnly&&(e.command.interestingHealthProviderNames=["Amazon"]),e.command.platformHealthOnlyShowOverride=n.attributes.platformHealthOnlyShowOverride),this.isValid=function(){const t=e.command;return!!e.verification.verified&&("PREVIOUS_IMAGE"===d||void 0!==t.rollbackContext.restoreServerGroupName)},e.taskMonitor=new v({application:n,title:"Rollback "+r.name,modalInstance:t}),this.rollback=function(){if(!this.isValid())return;e.taskMonitor.submit((function(){return a.rollbackServerGroup(r,n,e.command)}))},this.cancel=function(){t.dismiss()},this.label=function(e){return e?e.buildInfo&&e.buildInfo.jenkins&&e.buildInfo.jenkins.number?e.name+" (build #"+e.buildInfo.jenkins.number+")":e.name:""},this.group=function(e){return e.isDisabled?"Disabled Server Groups":"Enabled Server Groups"}}]),an.register(nn,rn,sn,ln,on,cn,dn,pn,un);t("spinnaker.amazon.serverGroup.details.scalingPolicy.metricAlarmChart.component",[]).component("metricAlarmChart",Va(F(Ss,"metricAlarmChart"),["alarm","serverGroup","alarmUpdated","onChartLoaded"]));const Ns={bindings:{policy:"=",serverGroup:"="},templateUrl:"amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html",controller(){this.$onInit=()=>{this.alarm=this.policy.alarms[0];let e=!1;this.policy.cooldown&&(e=!0),this.policy.stepAdjustments&&this.policy.stepAdjustments.length&&(e="decrease"!==this.policy.stepAdjustments[0].operator),this.showWait=e}}},Ts="spinnaker.amazon.serverGroup.details.scalingPolicy.popover.component";t(Ts,["spinnaker.amazon.serverGroup.details.scalingPolicy.metricAlarmChart.component"]).component("awsScalingPolicyPopover",Ns),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html",'<div>\n <dl class="dl-horizontal dl-narrow">\n <dt>Whenever</dt>\n <dd>\n {{ $ctrl.alarm.statistic }} of {{ $ctrl.alarm.metricName }} is\n <span ng-bind-html="$ctrl.alarm.comparator"></span> {{ $ctrl.alarm.threshold }}\n </dd>\n <dt>for at least</dt>\n <dd>{{ $ctrl.alarm.evaluationPeriods }} consecutive periods of {{ $ctrl.alarm.period }} seconds</dd>\n <dt>then</dt>\n <dd ng-if="$ctrl.policy.stepAdjustments.length">\n <div ng-repeat="stepAdjustment in $ctrl.policy.stepAdjustments">\n <span ng-if="$ctrl.policy.stepAdjustments.length > 1">\n if {{ $ctrl.alarm.metricName }}\n <span ng-if="$ctrl.alarm.comparisonOperator.indexOf(\'Greater\') === 0">\n <span\n ng-if="\n stepAdjustment.metricIntervalUpperBound !== undefined &&\n stepAdjustment.metricIntervalLowerBound !== undefined\n "\n >\n is between\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n and\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span>\n <span ng-if="stepAdjustment.metricIntervalUpperBound === undefined">\n is greater than {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n </span>\n </span>\n\n <span ng-if="$ctrl.alarm.comparisonOperator.indexOf(\'Less\') === 0">\n <span\n ng-if="\n stepAdjustment.metricIntervalUpperBound !== undefined &&\n stepAdjustment.metricIntervalLowerBound !== undefined\n "\n >\n is between\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n and\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span>\n <span ng-if="stepAdjustment.metricIntervalLowerBound === undefined">\n is less than {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span> </span\n >,\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ExactCapacity\'">\n set capacity to {{ stepAdjustment.scalingAdjustment }} instance<span\n ng-if="stepAdjustment.scalingAdjustment > 1"\n >s</span\n >\n </span>\n <span\n ng-if="\n $ctrl.policy.adjustmentType === \'ChangeInCapacity\' ||\n $ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'\n "\n >\n {{ stepAdjustment.operator }} capacity\n <span ng-if="$ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'">\n by {{ stepAdjustment.absAdjustment }}%\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ChangeInCapacity\'">\n by {{ stepAdjustment.absAdjustment }} instance<span ng-if="stepAdjustment.absAdjustment > 1">s</span>\n </span>\n </span>\n </div>\n </dd>\n <dd ng-if="!$ctrl.policy.stepAdjustments.length">\n <span ng-if="$ctrl.policy.adjustmentType === \'ExactCapacity\'">\n set capacity to {{ $ctrl.policy.scalingAdjustment }} instance<span ng-if="$ctrl.policy.scalingAdjustment > 1"\n >s</span\n >\n </span>\n <span\n ng-if="\n $ctrl.policy.adjustmentType === \'ChangeInCapacity\' ||\n $ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'\n "\n >\n {{ $ctrl.policy.operator }} capacity\n <span ng-if="$ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'">\n by {{ $ctrl.policy.absAdjustment }}%\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ChangeInCapacity\'">\n by {{ $ctrl.policy.absAdjustment }} instance<span ng-if="$ctrl.policy.absAdjustment > 1">s</span>\n </span>\n </span>\n </dd>\n <dt ng-if="$ctrl.policy.minAdjustmentMagnitude">in</dt>\n <dd ng-if="$ctrl.policy.minAdjustmentMagnitude">\n increments of at least {{ $ctrl.policy.minAdjustmentMagnitude }} instance<span\n ng-if="$ctrl.policy.minAdjustmentMagnitude > 1"\n >s</span\n >\n </dd>\n <dt ng-if="$ctrl.showWait">wait</dt>\n <dd ng-if="$ctrl.policy.cooldown">{{ $ctrl.policy.cooldown }} seconds before allowing another scaling activity.</dd>\n <dd ng-if="$ctrl.showWait && $ctrl.policy.estimatedInstanceWarmup">\n {{ $ctrl.policy.estimatedInstanceWarmup }} seconds to warm up after each step.\n </dd>\n </dl>\n\n <metric-alarm-chart alarm="$ctrl.policy.alarms[0]" server-group="$ctrl.serverGroup"></metric-alarm-chart>\n</div>\n')}]);const Is=({command:e,isInstanceType:t,isNew:a,operator:r,updateCommand:i})=>{var s,l,o,c;const[d,p]=zt.useState(e),m=(t,a)=>{const n={...e};Jt(n,t,a),p(n),i(n)};return zt.createElement("div",null,zt.createElement("h4",{className:"section-heading"},"Additional Settings"),zt.createElement("div",{className:"section-body section-additional-settings"},!a&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Policy Name"),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement("span",{className:"form-control-static select-placeholder"},d.name))),!t&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Adjustment Step"),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement("span",{className:"form-control-static select-placeholder"},`${r} instannces in increments of at least `),zt.createElement(u,{value:d.minAdjustmentMagnitude,onChange:e=>m("minAdjustmentMagnitude",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-right input-sm number-input-sm"}),zt.createElement("span",{className:"input-label"}," instance(s) "))),Boolean(d.simple)&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Cooldown"),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement("span",{className:"form-control-static select-placeholder"}," Wait at least "),zt.createElement(u,{value:null==(s=d.simple)?void 0:s.cooldown,onChange:e=>m("simple.cooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),zt.createElement("span",{className:"input-label"}," seconds before another scaling event "))),Boolean(null==(l=d.step)?void 0:l.estimatedInstanceWarmup)&&"Remove"!==r&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Warmup"),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement("span",{className:"form-control-static select-placeholder"},"Instances need"),zt.createElement(u,{value:d.step.estimatedInstanceWarmup,onChange:e=>m("step.estimatedInstanceWarmup",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),zt.createElement("span",{className:"input-label"}," seconds to warm up after each step "))),Boolean(null==(o=d.step)?void 0:o.cooldown)&&"Remove"!==r&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},zt.createElement("span",{className:"sp-margin-xs-right"},"Cooldown"),zt.createElement(n,{id:`${d.cloudProvider||d.provider}.autoscaling.cooldown`})),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement(u,{value:null==(c=d.step)?void 0:c.cooldown,onChange:e=>m("step.cooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),zt.createElement("span",{className:"input-label"}," seconds ")))))},xs="spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component",As="spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component";t("spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component",[]).component("scalingPolicyAdditionalSettings",Va(F(Is,"scalingPolicyAdditionalSettings"),["command","isInstanceType","isNew","operator","updateCommand"]));er("dimensions-editor {\n display: block;\n padding-left: 5px;\n}\ndimensions-editor h5 {\n margin-bottom: 0;\n}\ndimensions-editor .dimensions-row {\n margin-top: 5px;\n margin-left: -20px;\n}\ndimensions-editor .add-new {\n margin-left: 0;\n padding: 4px;\n width: 100%;\n}\n");const Ps=({alarm:e,serverGroup:t,updateAvailableMetrics:a})=>{const[n,r]=zt.useState(e.dimensions||[]),{result:i}=$((()=>It.listMetrics("aws",t.account,t.region,{namespace:e.namespace}).then((e=>{const t=ma(e,(e=>e.dimensions));return _t(t.map((e=>e.name))).sort()}))),[],[e.namespace,t.name]),s=(e,t,i)=>{const s=[...n];s[i][e]=t,r(s),a(s)};return zt.createElement("div",null,zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-12 small"},zt.createElement("h5",null,"Dimensions"))),n.map(((t,n)=>zt.createElement("div",{key:`dimension-${n}`,className:"row dimensions-row horizontal middle"},zt.createElement("div",{className:"col-md-6"},zt.createElement(c,{onChange:e=>s("name",e.target.value,n),value:t.name,stringOptions:i})),zt.createElement(l,{onChange:e=>s("value",e.target.value,n),value:t.value}),!e.disableEditingDimensions&&zt.createElement("div",{className:"col-md-1",onClick:()=>(t=>{const n=e.dimensions.filter(((e,a)=>a!==t));r(n),a(n)})(n)},zt.createElement("a",null,zt.createElement("i",{className:"glyphicon glyphicon-trash clickable"})))))),!e.disableEditingDimensions&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-10"},zt.createElement("button",{className:"btn btn-block btn-xs add-new",onClick:()=>{const e=[...n,{}];r(e),a(e)}},zt.createElement("span",{className:"glyphicon glyphicon-plus-sign sp-margin-xs-left"}),"Add dimension"))))},zs=["AWS/ApplicationELB","AWS/AutoScaling","AWS/AmazonMQ","AWS/Billing","AWS/CloudFront","AWS/CloudSearch","AWS/Events","AWS/DynamoDB","AWS/ECS","AWS/ElastiCache","AWS/EBS","AWS/EC2","AWS/ELB","AWS/ElasticMapReduce","AWS/ES","AWS/Kinesis","AWS/Lambda","AWS/ML","AWS/OpsWorks","AWS/Redshift","AWS/RDS","AWS/Route53","AWS/SNS","AWS/SQS","AWS/S3","AWS/SWF","AWS/StorageGateway","AWS/WAF","AWS/WorkSpaces"];er(".MetricSelector {\n font-size: 12px;\n}\n.MetricSelector .simple-input {\n width: 216px;\n}\n.MetricSelector .advanced-input-namespace {\n width: 138px;\n}\n.MetricSelector .advanced-input-metric {\n width: 300px;\n}\n");const Bs=({alarm:e,updateAlarm:t,serverGroup:a})=>{var r,i;const s=((null==(i=null==(r=gn)?void 0:r.metrics)?void 0:i.customNamespaces)||[]).concat(zs),[l,o]=zt.useState(!1),[d,p]=zt.useState({}),[u,m]=zt.useState(null==e?void 0:e.metricName),[g,h]=zt.useState(null==e?void 0:e.namespace),f=((null==e?void 0:e.dimensions)||[]).reduce(((e,t)=>(e[t.name]=t.value,e)),{}),v=e=>e.sort(((e,t)=>{var a;return null==(a=e.name)?void 0:a.localeCompare(t.name)})).map((e=>e.value)).join(", "),y=v((null==e?void 0:e.dimensions)||[]),{result:b}=$((()=>It.listMetrics("aws",a.account,a.region,f).then((a=>{const n=a.map((e=>({label:`(${e.namespace}) ${e.name}`,dimensions:[],dimensionValues:v(e.dimensions),value:e,...e}))).sort(((e,t)=>{var a;return null==(a=e.label)?void 0:a.localeCompare(t.label)})),r=n.find((t=>t.name===(null==e?void 0:e.metricName)&&t.namespace===(null==e?void 0:e.namespace)&&t.dimensionValues===y))||n.find((e=>e.name.match("CPUUtilization")))||n[0];p(r),m(r.name),h(r.namespace);const i={...e,metricName:r.name,namespace:r.namespace,dimensions:r.dimensions};return t(i),n}))),[],[a,null==e?void 0:e.namespace]),w=()=>{const n=!l;if(n)f.namespace=null==e?void 0:e.namespace;else{const n={...e,dimension:[{name:"AutoScalingGroupName",value:a.name}]};t(n)}o(n)},E=(a,n)=>{const r={...e,metricName:n,namespace:a};m(n),h(a),t(r)};return l?zt.createElement("div",{className:"MetricSelector"},zt.createElement("div",{className:"horizontal middle"},zt.createElement(c,{value:g,onChange:t=>E(t.target.value,null==e?void 0:e.metricName),stringOptions:s,inputClassName:"advanced-input-namespace sp-margin-m-right"}),zt.createElement(c,{value:u,onChange:t=>E(null==e?void 0:e.namespace,t.target.value),stringOptions:b.map((e=>e.name)),placeholder:"name",searchable:!0,inputClassName:"advanced-input-metric"})),zt.createElement("div",{className:"vertical"},!Boolean(b.length)&&zt.createElement("span",{className:"input-label"},zt.createElement("b",null,"Note:")," no metrics found for selected namespace + dimensions"),zt.createElement("a",{className:"clickable",onClick:w},zt.createElement("span",{className:"sp-margin-s-yaxis sp-margin-xs-right"},"Only show metrics for this auto scaling group"),zt.createElement(n,{id:"aws.scalingPolicy.search.restricted"}))),zt.createElement(Ps,{alarm:e,serverGroup:a,updateAvailableMetrics:a=>{const n={...e,dimensions:a};t(n)}})):zt.createElement("div",{className:"MetricSelector horizontal middle"},zt.createElement(c,{value:d,onChange:a=>(a=>{const n={...e,metricName:a.name,namespace:a.namespace,dimensions:a.dimensions},r=b.find((e=>e.namespace===a.namespace&&e.name===a.name));p(r),m(r.name),h(r.namespace),t(n)})(a.target.value),options:b,clearable:!1,inputClassName:"sp-margin-s-right simple-input"}),zt.createElement("a",{className:"clickable",onClick:w},zt.createElement("span",{className:"sp-margin-xs-right"},"Search all metrics"),zt.createElement(n,{id:"aws.scalingPolicy.search.all"})))};t("spinnaker.amazon.scalingPolicy.alarm.metric.selector.component",[]).component("metricSelector",Va(F(Bs,"metricSelector"),["alarm","serverGroup","updateAlarm"]));var Ds,$s,Ms;t("spinnaker.amazon.serverGroup.details.scalingPolicy.dimensionEditor",[]).component("dimensionsEditor",Va(F(Ps,"dimensionsEditor"),["alarm","namespaceUpdated","serverGroup","updateAvailableMetrics"]));const Fs=(e,t)=>e.name.localeCompare(t.name);const Ls={bindings:{alarm:"<",serverGroup:"<",alarmUpdated:"<"},controller:class{constructor(){this.namespaceUpdated=new fa,this.namespaces=(null!=(Ms=null==($s=null==(Ds=gn)?void 0:Ds.metrics)?void 0:$s.customNamespaces)?Ms:[]).concat(zs),this.updateAvailableMetrics=()=>{const{alarm:e}=this,t=this.convertDimensionsToObject();this.state.advancedMode&&(t.namespace=e.namespace),It.listMetrics("aws",this.serverGroup.account,this.serverGroup.region,t).then((t=>{t=t||[],this.state.metricsLoaded=!0,this.state.metrics=t.map((e=>this.buildMetricOption(e))).sort(((e,t)=>e.label.localeCompare(t.label)));const a=e.dimensions.sort(Fs).map((e=>e.value)).join(", "),n=this.state.metrics.find((t=>t.name===e.metricName&&t.namespace===e.namespace&&t.dimensionValues===a));t.length||this.state.advancedMode||(this.state.noDefaultMetrics=!0,e.namespace=e.namespace||this.namespaces[0],this.advancedMode()),n?this.state.selectedMetric=n:!e.metricName&&this.state.metrics.length&&(this.state.selectedMetric=this.state.metrics.find((e=>e.name.match("CPUUtilization")))||this.state.metrics[0]),this.metricChanged()})).catch((()=>{this.state.metricsLoaded=!0,this.advancedMode()}))}}$onInit(){this.state={advancedMode:!1,metricsLoaded:!1,metrics:[],selectedMetric:null};const e=this.alarm.dimensions;(!e||!e.length||e.length>1||"AutoScalingGroupName"!==e[0].name||e[0].value!==this.serverGroup.name)&&(this.state.advancedMode=!0),this.updateAvailableMetrics(),this.alarmUpdated.next()}simpleMode(){this.alarm.dimensions=[{name:"AutoScalingGroupName",value:this.serverGroup.name}],this.state.advancedMode=!1,this.updateAvailableMetrics()}advancedMode(){this.state.advancedMode=!0}buildMetricOption(e){return{label:`(${e.namespace}) ${e.name}`,dimensions:[],dimensionValues:e.dimensions.sort(Fs).map((e=>e.value)).join(", "),...e}}convertDimensionsToObject(){return this.alarm.dimensions.reduce(((e,t)=>(e[t.name]=t.value,e)),{})}dimensionsToString(e=[]){return e.map((e=>[e.name,e.value].join(":"))).join(",")}metricChanged(e=!1){const{alarm:t}=this;if(this.state.metricsLoaded)if(this.state.advancedMode)this.alarmUpdated.next();else if(this.state.selectedMetric){const a=this.state.selectedMetric,n=a&&this.dimensionsToString(t.dimensions)!==this.dimensionsToString(a.dimensions),r=t.metricName!==a.name||t.namespace!==a.namespace||n;t.metricName=a.name,t.namespace=a.namespace,n&&(t.dimensions=a.dimensions,this.updateAvailableMetrics()),(r||e)&&this.alarmUpdated.next()}else t.namespace=null,t.metricName=null,this.alarmUpdated.next()}},template:'\n <div class="text-center" style="display: inline-block; width: 100px; margin-top: 7px" ng-if="!$ctrl.state.metricsLoaded">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div style="display: inline-block; width: 500px" ng-if="$ctrl.state.metricsLoaded">\n <select class="form-control input-sm"\n required\n ng-model="$ctrl.state.selectedMetric"\n ng-change="$ctrl.metricChanged()"\n ng-if="!$ctrl.state.advancedMode"\n ng-options="metric as metric.label for metric in $ctrl.state.metrics">\n </select>\n <select class="form-control input-sm"\n required\n ng-model="$ctrl.alarm.namespace"\n ng-change="$ctrl.namespaceChanged()"\n ng-if="$ctrl.state.advancedMode"\n ng-options="namespace for namespace in $ctrl.namespaces">\n </select>\n <div style="display: inline-block; width: 300px; position: relative; top: -3px"\n ng-if="$ctrl.state.advancedMode">\n <input type="text" class="form-control input-sm no-spel" style="width: 100%"\n required\n uib-typeahead="option.name as option.name for option in $ctrl.state.metrics | filter: $viewValue"\n typeahead-show-hint="true"\n typeahead-min-length="0"\n typeahead-editable="true"\n typeahead-on-select="$ctrl.metricChanged()"\n ng-change="$ctrl.metricChanged()"\n ng-model-options="{ updateOn: \'default blur\', debounce: { \'default\': 300, \'blur\': 0 } }"\n ng-model="$ctrl.alarm.metricName"\n placeholder="name"/>\n </div>\n <a href class="small"\n ng-if="!$ctrl.state.advancedMode"\n ng-click="$ctrl.advancedMode()">\n Search all metrics <help-field key="aws.scalingPolicy.search.all"></help-field>\n </a>\n <span class="input-label" style="margin-left: 5px"\n ng-if="$ctrl.state.advancedMode && $ctrl.state.metrics.length === 0">\n <strong>Note:</strong> no metrics found for selected namespace + dimensions\n </span>\n <div style="padding-left: 5px;">\n <a href class="small"\n ng-if="$ctrl.state.advancedMode && !$ctrl.state.noDefaultMetrics"\n ng-click="$ctrl.simpleMode()">\n Only show metrics for this auto scaling group <help-field key="aws.scalingPolicy.search.restricted"></help-field>\n </a>\n </div>\n <div ng-if="$ctrl.state.advancedMode">\n <dimensions-editor alarm="$ctrl.alarm"\n server-group="$ctrl.serverGroup"\n namespace-updated="$ctrl.namespaceUpdated"\n update-available-metrics="$ctrl.updateAvailableMetrics"></dimensions-editor>\n </div>\n '};t("spinnaker.amazon.scalingPolicy.alarm.metric.editor",[]).component("awsMetricSelector",Ls);t("spinnaker.amazon.serverGroup.details.scalingPolicy.alarm.configurer",["spinnaker.amazon.serverGroup.details.scalingPolicy.dimensionEditor","spinnaker.amazon.scalingPolicy.alarm.metric.editor","spinnaker.amazon.scalingPolicy.alarm.metric.selector.component"]).component("awsAlarmConfigurer",{bindings:{command:"=",modalViewState:"=",serverGroup:"<",boundsChanged:"&"},templateUrl:"amazon/src/serverGroup/details/scalingPolicy/upsert/alarm/alarmConfigurer.component.html",controller:["$rootScope",function(e){this.statistics=["Average","Maximum","Minimum","SampleCount","Sum"],this.state={units:null},this.comparators=[{label:">=",value:"GreaterThanOrEqualToThreshold"},{label:">",value:"GreaterThanThreshold"},{label:"<=",value:"LessThanOrEqualToThreshold"},{label:"<",value:"LessThanThreshold"}],this.periods=[{label:"1 minute",value:60},{label:"5 minutes",value:300},{label:"15 minutes",value:900},{label:"1 hour",value:3600},{label:"4 hours",value:14400},{label:"1 day",value:86400}],this.alarmUpdated=new fa,this.onChartLoaded=t=>{this.state.unit=t.unit,this.updateChart(),e.$digest()},this.thresholdChanged=()=>{const e="max"===this.modalViewState.comparatorBound?"metricIntervalLowerBound":"metricIntervalUpperBound";this.command.step&&(this.command.step.stepAdjustments[0][e]=this.command.alarm.threshold),this.boundsChanged(),this.alarmUpdated.next()},this.alarmChanged=e=>{this.command.alarm=e,this.updateChart()},this.updateChart=()=>this.alarmUpdated.next(),this.alarmComparatorChanged=()=>{const e=this.modalViewState.comparatorBound;this.modalViewState.comparatorBound=0===this.command.alarm.comparisonOperator.indexOf("Greater")?"max":"min",e&&this.modalViewState.comparatorBound!==e&&this.command.step&&(this.command.step.stepAdjustments=[{scalingAdjustment:1}],this.thresholdChanged()),this.alarmUpdated.next()},this.$onInit=()=>{this.alarm=this.command.alarm,this.alarmComparatorChanged()}}]}),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/upsert/alarm/alarmConfigurer.component.html",'<div class="row" ng-if="$ctrl.modalViewState.multipleAlarms">\n <div class="col-md-12">\n <div class="alert alert-warning">\n <p>\n <i class="fa fa-exclamation-triangle"></i> This scaling policy is configured with multiple alarms. You are only\n editing the first alarm.\n </p>\n <p>To edit or remove the additional alarms, you will need to use the AWS console.</p>\n </div>\n </div>\n</div>\n<div class="row" ng-if="$ctrl.alarm.alarmActionArns.length > 1">\n <div class="col-md-12">\n <div class="alert alert-warning">\n <p>\n <i class="fa fa-exclamation-triangle"></i> This alarm is used in multiple scaling policies. Any changes here\n will affect those other scaling policies.\n </p>\n </div>\n </div>\n</div>\n\n<div class="row">\n <div class="col-md-2 sm-label-right">Whenever</div>\n <div class="col-md-10 content-fields horizontal">\n <select\n class="form-control input-sm"\n style="vertical-align: top"\n required\n ng-model="$ctrl.alarm.statistic"\n ng-change="$ctrl.updateChart()"\n ng-options="stat for stat in $ctrl.statistics"\n ></select>\n <span class="input-label sp-margin-xs-right" style="vertical-align: top; margin-top: 7px"> of </span>\n <metric-selector\n update-alarm="$ctrl.alarmChanged"\n alarm="$ctrl.command.alarm"\n server-group="$ctrl.serverGroup"\n ></metric-selector>\n </div>\n</div>\n\n<div class="row">\n <div class="col-md-2 sm-label-right">is</div>\n <div class="col-md-10 content-fields">\n <select\n class="form-control input-sm"\n style="width: 50px"\n ng-model="$ctrl.alarm.comparisonOperator"\n ng-change="$ctrl.alarmComparatorChanged()"\n ng-options="comparator.value as comparator.label for comparator in $ctrl.comparators"\n ></select>\n <input\n type="number"\n class="form-control input-sm"\n style="width: 100px"\n ng-change="$ctrl.thresholdChanged()"\n ng-model="$ctrl.alarm.threshold"\n />\n <span class="input-label" ng-bind="$ctrl.state.unit"></span>\n </div>\n</div>\n\n<div class="row">\n <div class="col-md-2 sm-label-right">for at least</div>\n <div class="col-md-10 content-fields">\n <input type="number" class="form-control input-sm" style="width: 50px" ng-model="$ctrl.alarm.evaluationPeriods" />\n <span class="input-label"> consecutive period(s) of </span>\n <select\n class="form-control input-sm"\n ng-change="$ctrl.updateChart()"\n ng-model="$ctrl.alarm.period"\n ng-options="period.value as period.label for period in $ctrl.periods"\n ></select>\n </div>\n</div>\n\n<div class="row" ng-if="$ctrl.alarm.metricName">\n <div class="col-md-10 col-md-offset-1">\n <div>\n <metric-alarm-chart\n ng-if="$ctrl.alarm"\n alarm="$ctrl.alarm"\n server-group="$ctrl.serverGroup"\n alarm-updated="$ctrl.alarmUpdated"\n on-chart-loaded="($ctrl.onChartLoaded)"\n ></metric-alarm-chart>\n </div>\n </div>\n</div>\n')}]);er(".AlarmConfigurer {\n font-size: 12px;\n margin: 0px;\n}\n.AlarmConfigurer .configurer-field-lg {\n width: 90px;\n}\n.AlarmConfigurer .configurer-field-small {\n width: 32px;\n}\n.AlarmConfigurer .configurer-field-med {\n width: 48px;\n}\n.AlarmConfigurer .number-input-field {\n margin: 0px;\n}\n");const Rs=["Average","Maximum","Minimum","SampleCount","Sum"],Os=[{label:">=",value:"GreaterThanOrEqualToThreshold"},{label:">",value:"GreaterThanThreshold"},{label:"<=",value:"LessThanOrEqualToThreshold"},{label:"<",value:"LessThanThreshold"}],Us=[{label:"1 minute",value:60},{label:"5 minutes",value:300},{label:"15 minutes",value:900},{label:"1 hour",value:3600},{label:"4 hours",value:14400},{label:"1 day",value:86400}],Vs=({alarm:e,multipleAlarms:t,serverGroup:a,stepAdjustments:n,stepsChanged:r,updateAlarm:i})=>{var s,l;const o=0===(null==(s=e.comparisonOperator)?void 0:s.indexOf("Greater"))?"max":"min",[d,p]=zt.useState(e),[m,g]=zt.useState(null==d?void 0:d.unit);zt.useEffect((()=>{if(n){const t={scalingAdjustment:1,["max"===o?"metricIntervalLowerBound":"metricIntervalUpperBound"]:e.threshold};r([t])}}),[o]);const h=(e,t)=>{const a={...d,[e]:t};p(a),i(a)};return zt.createElement("div",{className:"AlarmConfigurer"},t&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-12"},zt.createElement("div",{className:"alert alert-warning"},zt.createElement("p",null,zt.createElement("i",{className:"fa fa-exclamation-triangle"})," This scaling policy is configured with multiple alarms. You are only editing the first alarm."),zt.createElement("p",null,"To edit or remove the additional alarms, you will need to use the AWS console.")))),(null==(l=d.alarmActionArns)?void 0:l.length)>1&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-12"},zt.createElement("div",{className:"alert alert-warning"},zt.createElement("p",null,zt.createElement("i",{className:"fa fa-exclamation-triangle"})," This alarm is used in multiple scaling policies. Any changes here will affect those other scaling policies.")))),zt.createElement("div",{className:"row sp-margin-s-yaxis"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Whenever"),zt.createElement("div",{className:"col-md-10 horizontal middle"},zt.createElement(c,{value:d.statistic,onChange:e=>h("statistic",e.target.value),stringOptions:Rs,clearable:!1,inputClassName:"sp-margin-xs-right configurer-field-lg"}),zt.createElement("span",{className:"input-label sp-margin-xs-right"}," of "),zt.createElement(Bs,{alarm:d,serverGroup:a,updateAlarm:e=>{p(e),i(e)}}))),zt.createElement("div",{className:"row sp-margin-s-yaxis"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"is"),zt.createElement("div",{className:"col-md-10 horizontal middle"},zt.createElement(c,{value:d.comparisonOperator,onChange:e=>h("comparisonOperator",e.target.value),options:Os,clearable:!1,inputClassName:"sp-margin-s-right configurer-field-small"}),zt.createElement("div",{className:"sp-margin-xl-left"},zt.createElement(u,{value:d.threshold,onChange:e=>(e=>{const t={...d,threshold:e};p(t),i(t);const a="max"===o?"metricIntervalLowerBound":"metricIntervalUpperBound";if(null==n?void 0:n.length){const t=[...n];t[0][a]=e,r(t)}})(Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-right configurer-field-lg"})),zt.createElement("span",{className:"input-label"},m))),zt.createElement("div",{className:"row sp-margin-s-yaxis"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"for at least"),zt.createElement("div",{className:"col-md-10 horizontal middle"},zt.createElement(u,{value:d.evaluationPeriods,onChange:e=>h("evaluationPeriods",Number.parseInt(e.target.value)),inputClassName:"configurer-field-med number-input-field"}),zt.createElement("span",{className:"input-label sp-margin-s-xaxis"}," consecutive period(s) of "),zt.createElement(c,{value:d.period,onChange:e=>h("period",e.target.value),options:Us,clearable:!1,inputClassName:"sp-margin-xs-right configurer-field-lg"}))),zt.createElement("div",{className:"row sp-margin-s-yaxis","ng-if":"$ctrl.alarm.metricName"},zt.createElement("div",{className:"col-md-10 col-md-offset-1"},e&&zt.createElement("div",null,zt.createElement(Ss,{alarm:d,serverGroup:a,onChartLoaded:e=>g(e.unit)})))))};t("spinnaker.amazon.serverGroup.details.scalingPolicy.alarm.configurer.component",[]).component("alarmConfigurer",Va(F(Vs,"alarmConfigurer"),["alarm","multipleAlarms","serverGroup","stepAdjustments","stepsChanged","updateAlarm"]));er(".SimplePolicyAction .action-input {\n width: 65px;\n}\n.SimplePolicyAction .adjustment-type-input {\n width: 110px;\n}\n");t("spinnaker.amazon.serverGroup.details.scalingPolicy.upsert.actions.simplePolicy",[]).component("awsSimplePolicyAction",Va(F((({adjustmentType:e,adjustmentTypeChanged:t,operator:a,scalingAdjustment:n,updateScalingAdjustment:r})=>{const[i,s]=zt.useState(a),l="Set to"===i?["instances"]:["instances","percent of group"],[o,d]=zt.useState(e),[p,m]=zt.useState(n);return zt.createElement("div",{className:"SimplePolicyAction row"},zt.createElement("div",{className:"col-md-10 col-md-offset-1 horizontal middle"},zt.createElement(c,{value:i,stringOptions:["Add","Remove","Set to"],onChange:a=>{return n=a.target.value,s(n),void t(n,e);var n},clearable:!1,inputClassName:"action-input"}),zt.createElement(u,{value:p,min:1,onChange:e=>{return t=Number.parseInt(e.target.value),m(t),void r(t);var t},inputClassName:"action-input"}),zt.createElement(c,{value:o,stringOptions:l,onChange:e=>{return a=e.target.value,d(a),void t(i,a);var a},clearable:!1,inputClassName:"adjustment-type-input"})))}),"awsSimplePolicyAction"),["adjustmentType","adjustmentTypeChanged","operator","scalingAdjustment","updateScalingAdjustment"]));er(".StepPolicyAction .step-policy-row {\n padding: 5px 0;\n border-bottom: 1px solid var(--color-seashell);\n}\n.StepPolicyAction .step-policy-row .action-input {\n width: 65px !important;\n}\n.StepPolicyAction .step-policy-row .adjustment-type-input {\n width: 110px;\n}\n.StepPolicyAction .step-policy-row .remove-step-action-icon {\n margin-left: auto;\n}\n");const js=({adjustmentType:e,adjustmentTypeChanged:t,alarm:a,isMin:n,operator:r,step:i,stepAdjustments:s,stepsChanged:l})=>{const o=null==a?void 0:a.comparisonOperator.includes("Equal"),d=["Add","Remove","Set to"],[p,m]=zt.useState(r),g="Set to"===p?["instances"]:["instances","percent of group"],[h,f]=zt.useState(e),[v,y]=zt.useState((null==i?void 0:i.stepAdjustments)||s),b=(e,t)=>{const a=[...v];a[t]=e,y(a),l(a)};return zt.useEffect((()=>{y(i.stepAdjustments)}),[null==i?void 0:i.stepAdjustments]),zt.createElement("div",{className:"StepPolicyAction row"},null==v?void 0:v.map(((r,i)=>zt.createElement("div",{key:`step-adjustment-${i}`,className:"step-policy-row col-md-10 col-md-offset-1 horizontal middle"},Boolean(i)?zt.createElement("span",{className:"action-input sp-margin-xs-left"},p):zt.createElement(c,{value:p,stringOptions:d,onChange:a=>{return n=a.target.value,m(n),void t(n,e);var n},clearable:!1,inputClassName:"action-input sp-margin-xs-right"}),zt.createElement(u,{value:r.scalingAdjustment,min:1,onChange:e=>b({...r,scalingAdjustment:Number.parseInt(e.target.value)},i),inputClassName:"action-input"}),Boolean(i)?zt.createElement("span",{className:"sp-margin-xs-left"},h):zt.createElement(c,{value:h,stringOptions:g,onChange:e=>{return a=e.target.value,f(a),void t(p,a);var a},clearable:!1,inputClassName:"adjustment-type-input"}),zt.createElement("span",{className:"sp-margin-xs-xaxis"}," ","when ",zt.createElement("b",null,null==a?void 0:a.metricName)," is"," "),i===v.length-1&&zt.createElement("span",null,` ${n?"less":"greater"} than${!Boolean(i)||o?" or equal to":""} ${n?r.metricIntervalUpperBound||"":r.metricIntervalLowerBound||""} `),i<v.length-1&&zt.createElement(zt.Fragment,null,zt.createElement("span",{className:"sp-margin-xs-xaxis"},"between"),n?zt.createElement(u,{value:r.metricIntervalLowerBound,max:r.metricIntervalUpperBound,onChange:e=>b({...r,metricIntervalLowerBound:Number.parseInt(e.target.value)},i),inputClassName:"action-input"}):zt.createElement("span",null,r.metricIntervalLowerBound),zt.createElement("span",{className:"sp-margin-xs-xaxis"},"and"),n?zt.createElement("span",null,r.metricIntervalUpperBound):zt.createElement(u,{value:r.metricIntervalUpperBound,min:r.metricIntervalLowerBound,onChange:e=>b({...r,metricIntervalUpperBound:Number.parseInt(e.target.value)},i),inputClassName:"action-input"})),Boolean(i)&&zt.createElement("a",{className:"glyphicon glyphicon-trash clickable sp-margin-xs-xaxis remove-step-action-icon",onClick:()=>(e=>{const t=v.filter(((t,a)=>a!==e));y(t),l(t)})(i)})))),zt.createElement("div",{className:"row sp-margin-s"},zt.createElement("div",{className:"col-md-10 col-md-offset-1"},zt.createElement("button",{className:"btn btn-block btn-sm add-new",onClick:()=>{const e=[...v,{scalingAdjustment:1}];y(e),l(e)}},zt.createElement("span",{className:"glyphicon glyphicon-plus-sign"}),"Add step"))),zt.createElement("div",{className:"row sp-margin-s-xaxis"},zt.createElement("div",{className:"col-md-10 col-md-offset-1"},zt.createElement("a",{href:"http://docs.aws.amazon.com/autoscaling/latest/userguide/as-scale-based-on-demand.html#as-scaling-steps",target:"_blank"},zt.createElement("i",{className:"far fa-file-alt sp-margin-xs-right"}),"Documentation"))))};t("spinnaker.amazon.scalingPolicy.stepPolicyAction.component",[]).component("stepPolicyAction",Va(F(js,"stepPolicyAction"),["adjustmentType","adjustmentTypeChanged","alarm","isMin","operator","step","stepAdjustments","stepsChanged"]));er(".scaling-policy-modal input,\n.scaling-policy-modal select {\n margin: 0 5px;\n}\n.scaling-policy-modal span.input-label,\n.scaling-policy-modal .select-placeholder {\n display: inline-block;\n font-size: 12px;\n}\n.scaling-policy-modal .section-additional-settings .row {\n margin-bottom: 10px;\n}\n.scaling-policy-modal .section-additional-settings .number-input-sm {\n width: 60px;\n}\n.scaling-policy-modal aws-alarm-configurer > .row {\n margin-bottom: 10px;\n}\n.scaling-policy-modal .sm-label-right {\n padding-right: 5px;\n}\n.scaling-policy-modal .content-fields {\n padding-left: 0;\n}\n");t("spinnaker.amazon.serverGroup.details.scalingPolicy.upsertScalingPolicy.controller",["spinnaker.amazon.serverGroup.details.scalingPolicy.upsert.actions.simplePolicy","spinnaker.amazon.scalingPolicy.stepPolicyAction.component","spinnaker.amazon.serverGroup.details.scalingPolicy.alarm.configurer","spinnaker.amazon.serverGroup.details.scalingPolicy.alarm.configurer.component","spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component"]).controller("awsUpsertScalingPolicyCtrl",["$uibModalInstance","serverGroup","application","policy","$scope",function(e,t,a,n,r){function i(e,t){const a=e.alarm.threshold;e.step={estimatedInstanceWarmup:t.estimatedInstanceWarmup||e.cooldown||600,metricAggregationType:"Average"},e.step.stepAdjustments=t.stepAdjustments.map((e=>{const t={scalingAdjustment:Math.abs(e.scalingAdjustment)};return void 0!==e.metricIntervalUpperBound&&(t.metricIntervalUpperBound=e.metricIntervalUpperBound+a),void 0!==e.metricIntervalLowerBound&&(t.metricIntervalLowerBound=e.metricIntervalLowerBound+a),t}))}function s(e,t){e.simple={cooldown:t.cooldown||600,scalingAdjustment:Math.abs(t.scalingAdjustment)||1}}this.serverGroup=t,this.viewState={isNew:!n.policyARN,multipleAlarms:n.alarms.length>1,metricsLoaded:!1,namespacesLoaded:!1},this.initialize=()=>{const e={name:n.policyName,serverGroupName:t.name,credentials:t.account,region:t.region,provider:t.type,adjustmentType:n.adjustmentType,minAdjustmentMagnitude:n.minAdjustmentMagnitude||1};if(function(e,a){const n=a.alarms[0];e.alarm={name:n.alarmName,region:t.region,actionsEnabled:!0,alarmDescription:n.alarmDescription,comparisonOperator:n.comparisonOperator,dimensions:n.dimensions,evaluationPeriods:n.evaluationPeriods,period:n.period,threshold:n.threshold,namespace:n.namespace,metricName:n.metricName,statistic:n.statistic,unit:n.unit,alarmActionArns:n.alarmActions,insufficientDataActionArns:n.insufficientDataActions,okActionArns:n.okActions}}(e,n),"ExactCapacity"===e.adjustmentType)this.viewState.operator="Set to",this.viewState.adjustmentType="instances";else{let e=n.scalingAdjustment;n.stepAdjustments&&n.stepAdjustments.length&&(e=n.stepAdjustments[0].scalingAdjustment),this.viewState.operator=e>0?"Add":"Remove",this.viewState.adjustmentType="ChangeInCapacity"===n.adjustmentType?"instances":"percent of group"}n.stepAdjustments&&n.stepAdjustments.length?i(e,n):s(e,n),this.command=e},this.commandChanged=e=>{this.$scope.$applyAsync((()=>{this.command=e}))},this.scalingAdjustmentChanged=e=>{this.command.simple.scalingAdjustment=e},this.stepsChanged=e=>{this.command.step.stepAdjustments=e,this.boundsChanged()},this.alarmChanged=e=>{this.command.alarm=e},this.adjustmentTypeChanged=(e,t)=>{this.viewState.operator=e,this.viewState.adjustmentType=t;const a="instances"!==t?"PercentChangeInCapacity":"Set to"===e?"ExactCapacity":"ChangeInCapacity";this.command.adjustmentType=a},this.boundsChanged=()=>{const e="min"===this.viewState.comparatorBound?"metricIntervalLowerBound":"metricIntervalUpperBound",t="metricIntervalLowerBound"===e?"metricIntervalUpperBound":"metricIntervalLowerBound";if(this.command.step){const a=this.command.step.stepAdjustments;a.forEach(((n,r)=>{a.length>r+1&&(a[r+1][t]=n[e])})),delete a[a.length-1][e]}},this.switchMode=()=>{const e=this.command,t=e.step?e.step.estimatedInstanceWarmup:e.simple.cooldown;if(e.step){const a={cooldown:t};delete e.step,s(e,a)}else{const a=[{scalingAdjustment:e.simple.scalingAdjustment}];"min"===this.viewState.comparatorBound?a[0].metricIntervalUpperBound=0:a[0].metricIntervalLowerBound=0,delete e.simple,i(e,{estimatedInstanceWarmup:t,stepAdjustments:a}),this.boundsChanged()}},this.action=this.viewState.isNew?"Create":"Edit";const l=()=>{const e=Rt(this.command);return"PercentChangeInCapacity"!==e.adjustmentType&&delete e.minAdjustmentMagnitude,e.step?e.step.stepAdjustments.forEach((t=>{"Remove"===this.viewState.operator&&(t.scalingAdjustment=0-t.scalingAdjustment,delete e.step.estimatedInstanceWarmup),void 0!==t.metricIntervalLowerBound&&(t.metricIntervalLowerBound-=e.alarm.threshold),void 0!==t.metricIntervalUpperBound&&(t.metricIntervalUpperBound-=e.alarm.threshold)})):"Remove"===this.viewState.operator&&(e.simple.scalingAdjustment=0-e.simple.scalingAdjustment),e};this.taskMonitor=new v({application:a,title:this.action+" scaling policy for "+t.name,modalInstance:e}),this.save=()=>{const e=l();this.taskMonitor.submit((()=>os.upsertScalingPolicy(a,e)))},this.cancel=e.dismiss,this.initialize()}]);er("scaling-policy-summary .alarm-name {\n word-break: break-all;\n}\nscaling-policy-summary .actions {\n font-size: 85%;\n margin: 0 0 15px 0;\n border-bottom: 1px solid var(--color-alto);\n}\nscaling-policy-summary .actions .btn-left {\n padding-left: 0;\n border-left-width: 0;\n}\n");t("spinnaker.amazon.serverGroup.details.scalingPolicy.alarmBasedSummary.component",["spinnaker.amazon.serverGroup.details.scalingPolicy.upsertScalingPolicy.controller",Ts]).component("alarmBasedSummary",{bindings:{policy:"=",serverGroup:"=",application:"="},templateUrl:"amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html",controller:["$uibModal",function(e){this.popoverTemplate="amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html",this.editPolicy=()=>{e.open({templateUrl:"amazon/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html",controller:"awsUpsertScalingPolicyCtrl",controllerAs:"ctrl",size:"lg",resolve:{policy:()=>this.policy,serverGroup:()=>this.serverGroup,application:()=>this.application}})},this.deletePolicy=()=>{const e={application:this.application,title:"Deleting scaling policy "+this.policy.policyName};k.confirm({header:"Really delete "+this.policy.policyName+"?",buttonText:"Delete scaling policy",account:this.policy.alarms.length?this.serverGroup.account:null,taskMonitorConfig:e,submitMethod:()=>os.deleteScalingPolicy(this.application,this.serverGroup,this.policy)})}}]}),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html",'<span class="label label-default">{{ $ctrl.policy.policyType | robotToHuman | uppercase }}</span>\n\n<div ng-repeat="alarm in $ctrl.policy.alarms track by $index">\n <div\n uib-popover-template="$ctrl.popoverTemplate"\n popover-placement="left"\n popover-title="{{ $ctrl.policy.policyName }}"\n popover-trigger="\'mouseenter\'"\n >\n <div>\n <strong>Whenever</strong>\n {{ alarm.statistic }} of <span class="alarm-name">{{ alarm.metricName }}</span> is\n <span ng-bind-html="alarm.comparator"></span> {{ alarm.threshold }}\n </div>\n <div>\n <strong>for at least</strong>\n {{ alarm.evaluationPeriods }} consecutive periods of {{ alarm.period }} seconds\n </div>\n </div>\n</div>\n\n<div ng-if="!$ctrl.policy.alarms.length">\n <em>No alarms configured for this policy &mdash; it\'s safe to delete.</em>\n</div>\n\n<div class="actions text-right">\n <button class="btn btn-xs btn-link" ng-click="$ctrl.editPolicy()" ng-if="$ctrl.policy.alarms.length">\n <span class="glyphicon glyphicon-cog" uib-tooltip="Edit policy"></span>\n <span class="sr-only">Edit policy</span>\n </button>\n <button class="btn btn-xs btn-link" ng-click="$ctrl.deletePolicy()">\n <span class="glyphicon glyphicon-trash" uib-tooltip="Delete policy"></span>\n <span class="sr-only">Delete policy</span>\n </button>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html",'<aws-scaling-policy-popover policy="$ctrl.policy" server-group="$ctrl.serverGroup"></aws-scaling-policy-popover>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/upsert/upsertScalingPolicy.modal.html",'<div modal-page class="scaling-policy-modal form-inline">\n <task-monitor monitor="ctrl.taskMonitor"></task-monitor>\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">{{ctrl.action}} scaling policy</h4>\n </div>\n <div class="modal-body">\n <form name="form" novalidate>\n <h4 class="section-heading">Conditions</h4>\n <div class="section-body">\n <alarm-configurer\n alarm="ctrl.command.alarm"\n multiple-alarms="ctrl.viewState.multipleAlarms"\n server-group="ctrl.serverGroup"\n step-adjustments="ctrl.command.step.stepAdjustments"\n steps-changed="ctrl.stepsChanged"\n update-alarm="ctrl.alarmChanged"\n ></alarm-configurer>\n </div>\n <h4 class="section-heading">Actions</h4>\n <div class="section-body" ng-if="!ctrl.command.alarm.metricName">\n <h4 class="text-center">Select a metric</h4>\n </div>\n <div class="section-body" ng-if="ctrl.command.alarm.metricName">\n <div ng-if="ctrl.command.simple">\n <div class="row">\n <div class="col-md-10 col-md-offset-1">\n <p>\n This is a simple scaling policy. To declare different actions based on the magnitude of the alarm,\n <strong>switch to a <a href ng-click="ctrl.switchMode()">step policy</a>.</strong>\n </p>\n </div>\n </div>\n <aws-simple-policy-action\n adjustment-type="ctrl.viewState.adjustmentType"\n adjustment-type-changed="ctrl.adjustmentTypeChanged"\n operator="ctrl.viewState.operator"\n scaling-adjustment="ctrl.command.simple.scalingAdjustment"\n update-scaling-adjustment="ctrl.scalingAdjustmentChanged"\n ></aws-simple-policy-action>\n </div>\n <div ng-if="ctrl.command.step">\n <step-policy-action\n adjustment-type="ctrl.viewState.adjustmentType"\n adjustment-type-changed="ctrl.adjustmentTypeChanged"\n alarm="ctrl.command.alarm"\n is-min="ctrl.viewState.comparatorBound === \'min\'"\n operator="ctrl.viewState.operator"\n step="ctrl.command.step"\n steps-changed="ctrl.stepsChanged"\n >\n </step-policy-action>\n </div>\n </div>\n <scaling-policy-additional-settings\n command="ctrl.command"\n is-instance-type="ctrl.viewState.adjustmentType === \'instances\'"\n is-new="ctrl.viewState.isNew"\n operator="ctrl.viewState.operator"\n update-command="ctrl.commandChanged"\n ></scaling-policy-additional-settings>\n </form>\n </div>\n\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!form.$valid"\n submitting="taskMonitor.submitting"\n on-click="ctrl.save()"\n is-new="ctrl.viewState.isNew"\n ></submit-button>\n </div>\n</div>\n')}]),$n.registerPolicyType({type:"TargetTrackingScaling",summaryTemplateUrl:"amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html"}),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html",'<target-tracking-summary\n policy="$ctrl.policy"\n server-group="$ctrl.serverGroup"\n application="$ctrl.application"\n></target-tracking-summary>\n')}]);const qs={ASGAverageCPUUtilization:"CPUUtilization",ASGAverageNetworkIn:"NetworkIn",ASGAverageNetworkOut:"NetworkOut"},Hs=({alarmUpdated:e=new fa,config:t,serverGroup:a,updateUnit:n})=>{const[r,i]=zt.useState({alarmName:null,alarmArn:null,metricName:null,namespace:null,statistic:"Average",dimensions:[],period:60,threshold:t.targetValue,comparisonOperator:"GreaterThanThreshold",okactions:[],insufficientDataActions:[],alarmActions:[],evaluationPeriods:null,alarmDescription:null,unit:null});zt.useEffect((()=>{(()=>{var e;const n=null==t?void 0:t.customizedMetricSpecification,s={...r,dimensions:(null==n?void 0:n.dimensions)||[{name:"AutoScalingGroupName",value:a.name}],metricName:(null==n?void 0:n.metricName)||qs[null==(e=null==t?void 0:t.predefinedMetricSpecification)?void 0:e.predefinedMetricType],namespace:(null==n?void 0:n.namespace)||"AWS/EC2",threshold:null==t?void 0:t.targetValue};n&&(s.statistic=null==n?void 0:n.statistic),i(s)})()}),[t]);return zt.createElement(Ss,{alarm:r,alarmUpdated:e,onChartLoaded:t=>{n&&n(t.unit),null==e||e.next()},serverGroup:a})};er(".TargetMetricFields .metric-select-input {\n font-size: 12px;\n width: 180px;\n}\n.TargetMetricFields .target-input {\n width: 120px;\n}\n");const Ws=({allowDualMode:e,cloudwatch:t,command:a,isCustomMetric:n,serverGroup:r,toggleMetricType:i,unit:s,updateCommand:l})=>{var o,d;const[p,m]=zt.useState(a),[g,h]=zt.useState(n),[f,v]=zt.useState(s),y=(e,t)=>{const a=Rt(p);Jt(a,e,t),m(a),l(a)};return zt.createElement("div",{className:"TargetMetricFields sp-margin-l-xaxis"},zt.createElement("p",null,"With target tracking policies, Amazon will automatically adjust the size of your ASG to keep the selected metric as close as possible to the selected value."),t&&zt.createElement("p",null,zt.createElement("b",null,"Note:"),' metrics must be sent to Amazon CloudWatch before they can be used in auto scaling. If you do not see a metric below, click "Configure available metrics" in the server group details to set up forwarding from Atlas to CloudWatch.'),zt.createElement("div",{className:"row sp-margin-s-yaxis"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Metric"),zt.createElement("div",{className:"col-md-10 content-fields"},!g&&zt.createElement(c,{value:null==(o=p.targetTrackingConfiguration.predefinedMetricSpecification)?void 0:o.predefinedMetricType,stringOptions:["ASGAverageCPUUtilization","ASGAverageNetworkOut","ASGAverageNetworkIn"],onChange:e=>y("targetTrackingConfiguration.predefinedMetricSpecification.predefinedMetricType",e.target.value),inputClassName:"metric-select-input"}),g&&zt.createElement(Bs,{alarm:p.targetTrackingConfiguration.customizedMetricSpecification,serverGroup:r,updateAlarm:e=>{y("targetTrackingConfiguration.customizedMetricSpecification",e)}}),e&&zt.createElement("a",{className:"clickable",onClick:()=>{const e=Rt(p);g?(Jt(e,"targetTrackingConfiguration.predefinedMetricSpecification",{predefinedMetricType:"ASGAverageCPUUtilization"}),Jt(e,"targetTrackingConfiguration.customizedMetricSpecification",null)):(Jt(e,"targetTrackingConfiguration.predefinedMetricSpecification",null),Jt(e,"targetTrackingConfiguration.customizedMetricSpecification",{metricName:"CPUUtilization",namespace:"AWS/EC2",dimensions:[{name:"AutoScalingGroupName",value:r.name}],statistic:"Average"})),m(e),l(e),h(!g),i(g?"predefined":"custom")}},g?"Use a predefined metric":"Select a custom metric"))),zt.createElement("div",{className:"row sp-margin-s-yaxis"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Target"),zt.createElement("div",{className:"col-md-10 content-fields horizontal"},g&&zt.createElement("div",{className:"horizontal middle"},zt.createElement(c,{value:null==(d=p.targetTrackingConfiguration.customizedMetricSpecification)?void 0:d.statistic,stringOptions:["Average","Maximum","Minimum","SampleCount","Sum"],onChange:e=>y("targetTrackingConfiguration.customizedMetricSpecification.statistic",e.target.value),inputClassName:"form-control input-sm target-input"}),zt.createElement("span",{className:"sp-margin-xs-xaxis"},"of")),zt.createElement("div",null,zt.createElement(u,{value:p.targetTrackingConfiguration.targetValue,onChange:e=>y("targetTrackingConfiguration.targetValue",Number.parseInt(e.target.value)),inputClassName:"form-control input-sm sp-margin-xs-right"}),zt.createElement("span",null,f)))),zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-10 col-md-offset-1"},zt.createElement(Hs,{config:p.targetTrackingConfiguration,serverGroup:r,unit:f,updateUnit:e=>v(e)}))))};t("spinnaker.amazon.scalingPolicy.targetTracking.metricFields.component",[]).component("targetMetricFields",Va(F(Ws,"targetMetricFields"),["allowDualMode","cloudwatch","command","isCustomMetric","serverGroup","toggleMetricType","unit","updateCommand"]));t("spinnaker.amazon.scalingPolicy.targetTracking.chart.component",[]).component("targetTrackingChart",Va(F(Hs,"targetTrackingChart"),["alarmUpdated","config","serverGroup","unit","updateUnit"]));class Zs{constructor(e){this.$uibModal=e,this.popoverTemplate="amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingPopover.html"}$onInit(){this.config=this.policy.targetTrackingConfiguration}editPolicy(){this.$uibModal.open({templateUrl:"amazon/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html",controller:cs,controllerAs:"$ctrl",size:"lg",resolve:{policy:()=>this.policy,serverGroup:()=>this.serverGroup,application:()=>this.application}})}deletePolicy(){const e={application:this.application,title:"Deleting scaling policy "+this.policy.policyName};k.confirm({header:`Really delete ${this.policy.policyName}?`,buttonText:"Delete scaling policy",account:this.serverGroup.account,taskMonitorConfig:e,submitMethod:()=>os.deleteScalingPolicy(this.application,this.serverGroup,this.policy)})}}Zs.$inject=["$uibModal"];const _s={bindings:{policy:"<",serverGroup:"<",application:"<"},controller:Zs,template:'\n <div uib-popover-template="$ctrl.popoverTemplate"\n popover-placement="left"\n popover-title="{{$ctrl.policy.policyName}}"\n popover-trigger="\'mouseenter\'">\n <p>\n <span class="label label-default">{{$ctrl.policy.policyType | robotToHuman | uppercase }}</span>\n <div>\n <strong>Target</strong>\n {{$ctrl.config.predefinedMetricSpecification.predefinedMetricType}}\n {{$ctrl.config.customizedMetricSpecification.metricName}}\n <span ng-if="$ctrl.config.customizedMetricSpecification">({{$ctrl.config.customizedMetricSpecification.statistic}})</span>\n @ {{$ctrl.config.targetValue}}\n </div>\n </p>\n <div class="actions text-right">\n <button class="btn btn-xs btn-link" ng-click="$ctrl.editPolicy()">\n <span class="glyphicon glyphicon-cog" uib-tooltip="Edit policy"></span>\n <span class="sr-only">Edit policy</span>\n </button>\n <button class="btn btn-xs btn-link" ng-click="$ctrl.deletePolicy()">\n <span class="glyphicon glyphicon-trash" uib-tooltip="Delete policy"></span>\n <span class="sr-only">Delete policy</span>\n </button>\n </div>\n </div>\n '};t("spinnaker.amazon.scalingPolicy.targetTracking.summary.component",[]).component("targetTrackingSummary",_s),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingPopover.html",'<target-tracking-chart\n config="$ctrl.policy.targetTrackingConfiguration"\n server-group="$ctrl.serverGroup"\n update-unit="$ctrl.updateUnit"\n></target-tracking-chart>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/upsertTargetTracking.modal.html",'<div modal-page class="scaling-policy-modal form-inline">\n <task-monitor monitor="$ctrl.taskMonitor"></task-monitor>\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">{{$ctrl.policy.policyName ? "Update" : "Create"}} scaling policy</h4>\n </div>\n <div class="modal-body">\n <form name="form" novalidate>\n <h4 class="section-heading">Target Metric</h4>\n <target-metric-fields\n allow-dual-mode="true"\n cloudwatch="false"\n command="$ctrl.command"\n is-custom-metric="$ctrl.state.metricType === \'custom\'"\n server-group="$ctrl.serverGroup"\n toggle-metric-type="$ctrl.metricTypeChanged"\n unit="$ctrl.state.unit"\n update-command="$ctrl.commandChanged"\n update-unit="$ctrl.updateUnit"\n ></target-metric-fields>\n <h4 class="section-heading">Additional Settings</h4>\n <div class="section-body section-additional-settings">\n <div class="row" ng-if="$ctrl.policy.policyName">\n <div class="col-md-2 sm-label-right">Policy Name</div>\n <div class="col-md-10 content-fields">\n <span class="form-control-static select-placeholder" ng-bind="$ctrl.policy.policyName"></span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-md-2 sm-label-right">Warmup</div>\n <div class="col-md-10 content-fields">\n <span class="form-control-static select-placeholder">Instances need</span>\n <input\n type="number"\n style="width: 60px"\n class="form-control input-sm"\n required\n ng-model="$ctrl.command.estimatedInstanceWarmup"\n />\n <span class="input-label"> seconds to warm up </span>\n </div>\n </div>\n\n <div class="row">\n <div class="col-md-2 sm-label-right">Scale In</div>\n <div class="col-md-9">\n <div class="checkbox" style="margin-top: 5px">\n <label>\n <input\n type="checkbox"\n ng-model="$ctrl.command.targetTrackingConfiguration.disableScaleIn"\n ng-change="$ctrl.scaleInChanged()"\n />\n Disable Scale-downs\n </label>\n <div class="small" style="margin-top: 5px">\n <p>\n This option disables scale-downs for the target tracking policy, while keeping the scale-ups. This\n means that ASG will not scale down unless you explicitly set up a separate step policy to scale it\n down.\n </p>\n <p>This is useful when you have special requirements, such as gradual or delayed scale-down.</p>\n </div>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="$ctrl.state.scaleInChanged">\n <div class="col-md-10 col-md-offset-1 well">\n <div ng-if="$ctrl.command.targetTrackingConfiguration.disableScaleIn">\n This policy will not scale down. Make sure you have another policy (either TT or Step) that will scale\n down this ASG.\n </div>\n <div ng-if="!$ctrl.command.targetTrackingConfiguration.disableScaleIn">\n This policy will scale both up and down. Make sure you don\'t have other scaling policies, as they will\n likely interfere with each other.\n </div>\n </div>\n </div>\n </div>\n </form>\n </div>\n\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="!form.$valid || $ctrl.taskMonitor.submitting"\n submitting="$ctrl.taskMonitor.submitting"\n on-click="$ctrl.save()"\n is-new="!$ctrl.policy.policyName"\n ></submit-button>\n </div>\n</div>\n')}]);t("spinnaker.amazon.scalingPolicy.targetTracking",["spinnaker.amazon.scalingPolicy.targetTracking.chart.component","spinnaker.amazon.scalingPolicy.targetTracking.summary.component","spinnaker.amazon.scalingPolicy.targetTracking.metricFields.component"]);t("spinnaker.amazon.scalingPolicy.module",[Fn,"spinnaker.amazon.scalingPolicy.targetTracking","spinnaker.amazon.serverGroup.details.scalingPolicy.alarmBasedSummary.component"]);e.module("spinnaker.amazon.serverGroup.details.autoscaling.process.controller",[]).controller("ModifyScalingProcessesCtrl",["$scope","$uibModalInstance","application","serverGroup","processes",function(t,a,n,r,i){t.command=e.copy(i),t.serverGroup=r,t.verification={},this.isValid=function(){return!!t.verification.verified&&this.isDirty()};const s=$t.chain(t.command).filter({enabled:!0}).map("name").value(),l=$t.chain(t.command).filter({enabled:!1}).map("name").value();this.isDirty=function(){const e=$t.chain(t.command).filter({enabled:!0}).map("name").value(),a=$t.chain(t.command).filter({enabled:!1}).map("name").value(),n=$t.intersection(l,e),r=$t.intersection(s,a);return!(!n.length&&!r.length)},t.taskMonitor=new v({application:n,title:"Update Auto Scaling Processes for "+r.name,modalInstance:a,onTaskComplete:()=>n.serverGroups.refresh()}),this.submit=function(){const e=$t.chain(t.command).filter({enabled:!0}).map("name").value(),a=$t.chain(t.command).filter({enabled:!1}).map("name").value(),i=$t.intersection(l,e),o=$t.intersection(s,a),c=[];i.length&&c.push({type:"modifyScalingProcess",action:"resume",processes:i,asgName:r.name,regions:[r.region],credentials:r.account,cloudProvider:"aws",reason:t.command.reason}),o.length&&c.push({type:"modifyScalingProcess",action:"suspend",processes:o,asgName:r.name,regions:[r.region],credentials:r.account,cloudProvider:"aws",reason:t.command.reason});t.taskMonitor.submit((function(){return R.executeTask({job:c,application:n,description:"Update Auto Scaling Processes for "+r.name})}))},this.cancel=a.dismiss}]);t("spinnaker.amazon.serverGroup.details.scheduledActions.editScheduledActions.modal.controller",[]).controller("EditScheduledActionsCtrl",["$scope","$uibModalInstance","application","serverGroup",function(e,t,a,n){e.command={scheduledActions:n.scheduledActions.map((e=>({recurrence:e.recurrence,minSize:e.minSize,maxSize:e.maxSize,desiredCapacity:e.desiredCapacity})))},e.serverGroup=n,this.addScheduledAction=()=>{e.command.scheduledActions.push({})},this.removeScheduledAction=t=>{e.command.scheduledActions.splice(t,1)},e.taskMonitor=new v({application:a,title:"Update Scheduled Actions for "+n.name,modalInstance:t,onTaskComplete:()=>a.serverGroups.refresh()}),this.submit=()=>{const t=[{type:"upsertAsgScheduledActions",asgs:[{asgName:n.name,region:n.region}],scheduledActions:e.command.scheduledActions,credentials:n.account}];e.taskMonitor.submit((function(){return R.executeTask({job:t,application:a,description:"Update Scheduled Actions for "+n.name})}))},this.cancel=t.dismiss}]);t("spinnaker.amazon.serverGroup.details.securityGroup.editSecurityGroups.modal.controller",[Tt,Te]).controller("EditSecurityGroupsCtrl",["$scope","$uibModalInstance","serverGroupWriter","securityGroupReader","application","serverGroup","securityGroups",function(e,t,a,n,r,i,s){this.command={securityGroups:(s||[]).slice(0).sort(((e,t)=>e.name.localeCompare(t.name)))},this.state={securityGroupsLoaded:!1,submitting:!1,verification:{}},this.infiniteScroll={currentItems:20},this.addMoreItems=()=>this.infiniteScroll.currentItems+=20,this.resetCurrentItems=()=>this.infiniteScroll.currentItems=20,this.isValid=()=>this.state.verification.verified,n.getAllSecurityGroups().then((e=>{const t=i.account,a=i.region,n=i.vpcId;this.availableSecurityGroups=$t.get(e,[t,"aws",a].join("."),[]).filter((e=>e.vpcId===n)).sort(((e,t)=>this.command.securityGroups.some((t=>t.id===e.id))?-1:this.command.securityGroups.some((e=>e.id===t.id))?1:e.name.localeCompare(t.name))),this.state.securityGroupsLoaded=!0})),this.serverGroup=i,this.taskMonitor=new v({application:r,title:`Update ${U.get("Firewalls")} for ${i.name}`,modalInstance:t,onTaskComplete:()=>r.serverGroups.refresh()}),this.submit=()=>{this.taskMonitor.submit((()=>{this.state.submitting=!0;const e=Boolean(i.launchTemplate);return a.updateSecurityGroups(i,this.command.securityGroups,r,e)}))},this.cancel=t.dismiss}]);t("spinnaker.amazon.serverGroup.details",["spinnaker.amazon.scalingPolicy.module","spinnaker.amazon.serverGroup.details.securityGroup.editSecurityGroups.modal.controller","spinnaker.amazon.serverGroup.details.autoscaling.process.controller","spinnaker.amazon.serverGroup.details.scheduledActions.editScheduledActions.modal.controller","spinnaker.amazon.serverGroup.editAsgAdvancedSettings.modal.controller","spinnaker.amazon.serverGroup.details.rollback.controller"]);t("spinnaker.amazon.serverGroup.transformer",[]).service("awsServerGroupTransformer",class{addComparator(e){if(e.comparisonOperator)switch(e.comparisonOperator){case"LessThanThreshold":e.comparator="&lt;";break;case"GreaterThanThreshold":e.comparator="&gt;";break;case"LessThanOrEqualToThreshold":e.comparator="&le;";break;case"GreaterThanOrEqualToThreshold":e.comparator="&ge;"}}addAdjustmentAttributes(e){e.operator=e.scalingAdjustment<0?"decrease":"increase",e.absAdjustment=Math.abs(e.scalingAdjustment)}transformScalingPolicy(e){const t={...e},a=(e,t)=>t.metricIntervalUpperBound-e.metricIntervalUpperBound,n=(e,t)=>e.metricIntervalLowerBound-t.metricIntervalLowerBound;if(t.alarms=e.alarms||[],t.alarms.forEach((e=>this.addComparator(e))),this.addAdjustmentAttributes(t),t.stepAdjustments&&t.stepAdjustments.length){t.stepAdjustments.forEach((e=>this.addAdjustmentAttributes(e)));const r=e.stepAdjustments.every((e=>void 0!==e.metricIntervalUpperBound))?a:n;t.stepAdjustments.sort(((e,t)=>r(e,t)))}return t}normalizeServerGroupDetails(e){const t={...e};return e.scalingPolicies&&(t.scalingPolicies=e.scalingPolicies.map((e=>this.transformScalingPolicy(e)))),t}normalizeServerGroup(e){return e.instances.forEach((t=>{t.vpcId=e.vpcId})),xn.listVpcs().then((t=>this.addVpcNameToServerGroup(e)(t)))}addVpcNameToServerGroup(e){return t=>{const a=t.find((t=>t.id===e.vpcId));return e.vpcName=a?a.name:"",e}}convertServerGroupCommandToDeployConfiguration(e){const t=ga({backingData:[],viewState:[]},e);return t.cloudProvider="aws",t.availabilityZones={},t.availabilityZones[t.region]=e.availabilityZones,t.loadBalancers=(e.loadBalancers||[]).concat(e.vpcLoadBalancers||[]),t.targetGroups=e.targetGroups||[],t.account=t.credentials,t.subnetType=t.subnetType||"","clone"!==e.viewState.mode&&delete t.source,t.ramdiskId||delete t.ramdiskId,delete t.region,delete t.viewState,delete t.backingData,delete t.selectedProvider,delete t.instanceProfile,delete t.vpcId,t}constructNewStepScalingPolicyTemplate(e){return{alarms:[{namespace:"AWS/EC2",metricName:"CPUUtilization",threshold:50,statistic:"Average",comparisonOperator:"GreaterThanThreshold",evaluationPeriods:1,dimensions:[{name:"AutoScalingGroupName",value:e.name}],period:60}],adjustmentType:"ChangeInCapacity",stepAdjustments:[{scalingAdjustment:1,metricIntervalLowerBound:0}],estimatedInstanceWarmup:600}}constructNewTargetTrackingPolicyTemplate(){return{alarms:[],estimatedInstanceWarmup:300,targetTrackingConfiguration:{targetValue:null,predefinedMetricSpecification:{predefinedMetricType:"ASGAverageCPUUtilization"}}}}});t("spinnaker.amazon.subnet.renderer",[]).service("awsSubnetRenderer",class{render(e){return e.subnetType}});Pt.registerValidator("aws",new class{validateSpecialCharacters(e,t){/^[a-zA-Z_0-9.]*$/g.test(e)||t.push("Only dot(.) and underscore(_) special characters are allowed.")}validateClassicLock(e){const t=gn.classicLaunchLockout;t&&t<(new Date).getTime()&&e.push(`New applications deployed to AWS are restricted to VPC; you cannot create server groups,\n load balancers, or ${U.get("firewalls")} in EC2 Classic.`)}validateLoadBalancerCharacters(e,t){(e.includes(".")||e.includes("_"))&&t.push("If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.\n Any hostname constructed with this application name may have issues.")}validateLength(e,t,a){if(e.length>250)a.push("The maximum length for an application in Amazon is 250 characters.");else{if(e.length>240)if(e.length>=248)t.push(`You will not be able to include a stack or detail field for clusters or ${U.get("firewalls")}.`);else{const a=248-e.length;t.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${a} characters to do so.`)}if(e.length>20)if(e.length>32)t.push(`You will not be able to create an Amazon load balancer for this application if the\n application's name is longer than 32 characters (currently: ${e.length} characters)`);else if(e.length>=30)t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${e.length} characters). With separators ("-"), you will not\n be able to add a stack and detail field to any load balancer.`);else{const a=30-e.length;t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${a} characters to add a stack or detail\n field to any load balancer.`)}}}validate(e=""){const t=[],a=[];return e.length&&(this.validateClassicLock(t),this.validateSpecialCharacters(e,a),this.validateLoadBalancerCharacters(e,t),this.validateLength(e,t,a)),{warnings:t,errors:a}}});t("spinnaker.amazon.vpc",["spinnaker.amazon.vpc.tag.directive"]);er('.cloud-provider-logo .icon-aws {\n -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!DOCTYPE svg PUBLIC %22-%2F%2FW3C%2F%2FDTD SVG 1.1%2F%2FEN%22 %22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg version%3D%221.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 width%3D%22130px%22 height%3D%22130px%22 viewBox%3D%220 0 27 27%22%3E%3Cg%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2213.2%2C27 2.4%2C23.1 2.4%2C8.5 13.2%2C12.5 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2226.5%2C23.1 15.2%2C27 15.2%2C12.5 26.5%2C8 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2214.2%2C3.4 25.5%2C7 14.2%2C11.0 2.9%2C7 %22%2F%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!DOCTYPE svg PUBLIC %22-%2F%2FW3C%2F%2FDTD SVG 1.1%2F%2FEN%22 %22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg version%3D%221.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 width%3D%22130px%22 height%3D%22130px%22 viewBox%3D%220 0 27 27%22%3E%3Cg%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2213.2%2C27 2.4%2C23.1 2.4%2C8.5 13.2%2C12.5 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2226.5%2C23.1 15.2%2C27 15.2%2C12.5 26.5%2C8 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2214.2%2C3.4 25.5%2C7 14.2%2C11.0 2.9%2C7 %22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n}\n');const Ks="spinnaker.amazon";t("spinnaker.amazon",["spinnaker.amazon.react","spinnaker.amazon.pipeline.stage.bakeStage","spinnaker.amazon.pipeline.stage.cloneServerGroupStage","spinnaker.amazon.pipeline.stage.aws.destroyAsgStage","spinnaker.amazon.pipeline.stage.disableAsgStage","spinnaker.amazon.pipeline.stage.disableClusterStage","spinnaker.amazon.pipeline.stage.rollbackClusterStage","spinnaker.amazon.pipeline.stage.enableAsgStage","spinnaker.amazon.pipeline.stage.findAmiStage","spinnaker.amazon.pipeline.stage.findImageFromTagsStage","spinnaker.amazon.pipeline.stage.modifyScalingProcessStage","spinnaker.amazon.pipeline.stage.aws.resizeAsgStage","spinnaker.amazon.pipeline.stage.scaleDownClusterStage","spinnaker.amazon.pipeline.stage.aws.shrinkClusterStage","spinnaker.amazon.pipeline.stage.tagImageStage","spinnaker.amazon.serverGroup.details","spinnaker.amazon.common","spinnaker.amazon.serverGroup.transformer","spinnaker.amazon.instanceType.service","spinnaker.amazon.loadBalancer","spinnaker.amazon.function","spinnaker.amazon.instance.details.controller","spinnaker.amazon.securityGroup","spinnaker.amazon.subnet.renderer","spinnaker.amazon.vpc","spinnaker.amazon.search.searchResultFormatter","spinnaker.amazon.pipeline.stages.deployCloudFormationStage","spinnaker.amazon.cloudformation.entry.component","spinnaker.amazon.cloudformation.changetset.info.component","spinnaker.amazon.deployCloudFormation.service","spinnaker.application.instanceStatus.component","spinnaker.application.instanceTags.component","spinnaker.application.instanceSecurityGroups.component","spinnaker.application.instanceDns.component","spinnaker.application.amazonInstanceInformation.component"]).config((()=>{O.registerProvider("aws",{name:"Amazon",logo:{path:"amazon.logo352d4e042476837f.svg"},image:{reader:Wn},serverGroup:{transformer:"awsServerGroupTransformer",detailsActions:Wi,detailsGetter:_i,detailsSections:[Yi,Ji,es,ts,ns,is,ys,hs,gs,vs,bs,ls,Ki,ss],CloneServerGroupModal:Ri,commandBuilder:"awsServerGroupCommandBuilder",configurationService:"awsServerGroupConfigurationService",scalingActivitiesEnabled:!0},instance:{instanceTypeService:"awsInstanceTypeService",detailsTemplateUrl:"amazon/src/instance/details/instanceDetails.html",detailsController:"awsInstanceDetailsCtrl"},loadBalancer:{transformer:Pr,detailsTemplateUrl:"amazon/src/loadBalancer/details/loadBalancerDetails.html",detailsController:"awsLoadBalancerDetailsCtrl",CreateLoadBalancerModal:Zr,targetGroupDetailsTemplateUrl:"amazon/src/loadBalancer/details/targetGroupDetails.html",targetGroupDetailsController:"awsTargetGroupDetailsCtrl",ClusterContainer:ar,LoadBalancersTag:sr},function:{details:qn,CreateFunctionModal:zn,transformer:vn},securityGroup:{transformer:"awsSecurityGroupTransformer",reader:"awsSecurityGroupReader",detailsTemplateUrl:"amazon/src/securityGroup/details/securityGroupDetail.html",detailsController:"awsSecurityGroupDetailsCtrl",createSecurityGroupTemplateUrl:"amazon/src/securityGroup/configure/createSecurityGroup.html",createSecurityGroupController:"awsCreateSecurityGroupCtrl"},subnet:{renderer:"awsSubnetRenderer"},search:{resultFormatter:"awsSearchResultFormatter"},applicationProviderFields:{templateUrl:"amazon/src/applicationProviderFields/awsFields.html"}})})),r.registerProvider("aws",["custom","redblack","rollingpush","rollingredblack","monitored"]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/instance/details/instanceDetails.html",'<div class="text-center" ng-if="state.notFoundStandalone">\n <h3>Could not find instance {{instanceIdNotFound}}.</h3>\n <a ui-sref="home.infrastructure">Back to search results</a>\n</div>\n<div class="details-panel" ng-if="!state.notFoundStandalone">\n <div class="header">\n <instance-details-header\n health-state="instance.healthState"\n instance-id="instance.instanceId || instanceIdNotFound"\n loading="state.loading"\n standalone="state.standalone"\n ></instance-details-header>\n <div ng-if="!state.loading">\n <div class="actions" ng-class="{ insights: instance.insightActions.length > 0 }" ng-if="instance.placement">\n <instance-actions actions="instanceActions"></instance-actions>\n <instance-insights insights="instance.insightActions" instance="instance"></instance-insights>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading && instance">\n <amazon-instance-information instance="instance"></amazon-instance-information>\n <instance-status\n health-metrics="healthMetrics"\n health-state="instance.healthState"\n metric-types="[\'LoadBalancer\', \'TargetGroup\']"\n private-ip-address="instance.privateIpAddress"\n >\n </instance-status>\n <collapsible-section heading="DNS">\n <instance-dns\n instance-port="state.instancePort"\n ipv6-addresses="instance.ipv6Addresses"\n permanent-ips="instance.permanentIps"\n private-dns-name="instance.privateDnsName"\n private-ip-address="instance.privateIpAddress"\n public-dns-name="instance.publicDnsName"\n public-ip-address="instance.publicIpAddress"\n >\n </instance-dns>\n </collapsible-section>\n <instance-security-groups instance="instance"></instance-security-groups>\n <instance-tags tags="instance.tags"></instance-tags>\n <collapsible-section heading="Console Output" ng-if="baseIpAddress">\n <ul>\n <li>\n <console-output-link instance="instance"></console-output-link>\n </li>\n </ul>\n </collapsible-section>\n <instance-links\n address="baseIpAddress"\n application="application"\n instance="instance"\n moniker="moniker"\n environment="environment"\n ></instance-links>\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("amazon/src/loadBalancer/details/loadBalancerDetails.html",'<div class="details-panel">\n <div ng-if="ctrl.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 spinner-container">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div ng-if="!ctrl.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>\n {{ctrl.loadBalancer.name}}\n <render-if-feature feature="entityTags">\n <entity-notifications\n entity="ctrl.loadBalancer"\n application="ctrl.application"\n placement="bottom"\n h-offset-percent="90%"\n entity-type="loadBalancer"\n page-location="details"\n on-update="ctrl.application.loadBalancers.refresh()"\n ></entity-notifications>\n </render-if-feature>\n </h3>\n </div>\n <div>\n <div class="actions">\n <load-balancer-actions\n app="ctrl.application"\n load-balancer="ctrl.loadBalancer"\n load-balancer-from-params="ctrl.loadBalancerFromParams"\n ></load-balancer-actions>\n <div\n class="dropdown"\n ng-if="ctrl.loadBalancer.elb.insightActions.length > 0"\n uib-dropdown\n dropdown-append-to-body\n >\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 ctrl.loadBalancer.elb.insightActions">\n <a target="_blank" href="{{action.url}}">{{action.label}}</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!ctrl.state.loading && ctrl.loadBalancer.isManaged"\n resource-summary="ctrl.loadBalancer.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div ng-if="!ctrl.state.loading" class="content">\n <collapsible-section heading="Load Balancer Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Created</dt>\n <dd>{{ctrl.loadBalancer.elb.createdTime | timestamp}}</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="ctrl.loadBalancer.account" pad="right"></account-tag> {{ctrl.loadBalancer.region}}\n </dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="ctrl.loadBalancer.elb.vpcId"></vpc-tag>\n </dd>\n <dt>Subnet</dt>\n <dd>{{ctrl.getFirstSubnetPurpose(ctrl.loadBalancer.subnetDetails)}}</dd>\n <dt>Scheme</dt>\n <dd>{{ ctrl.loadBalancer.scheme }}</dd>\n <dt ng-if="ctrl.loadBalancer.loadBalancerType">Type</dt>\n <dd ng-if="ctrl.loadBalancer.loadBalancerType">{{ctrl.loadBalancer.loadBalancerType}}</dd>\n <dt ng-if="ctrl.ipAddressTypeDescription">IP Type</dt>\n <dd ng-if="ctrl.ipAddressTypeDescription">{{ctrl.ipAddressTypeDescription}}</dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt>Availability Zones</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="availabilityZone in ctrl.loadBalancer.elb.availabilityZones">{{availabilityZone}}</li>\n </ul>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.loadBalancer.serverGroups && ctrl.loadBalancer.serverGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Server Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in ctrl.loadBalancer.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: \'aws\'})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.loadBalancer.targetGroups && ctrl.loadBalancer.targetGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Target Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="targetGroup in ctrl.loadBalancer.targetGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.targetGroupDetails({region: targetGroup.region,\n loadBalancerName: ctrl.loadBalancer.name,\n accountId: targetGroup.account,\n name: targetGroup.name,\n vpcId: targetGroup.vpcId,\n provider: \'aws\'})"\n >\n {{targetGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="ctrl.loadBalancer.elb.dnsname">DNS Name</dt>\n <dd>\n <a target="_blank" href="{{ctrl.elbProtocol}}//{{ctrl.loadBalancer.elb.dnsname}}"\n >{{ctrl.loadBalancer.elb.dnsname}}</a\n >\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="ctrl.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" ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'">\n <health-counts class="pull-left" container="ctrl.loadBalancer.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="false" ng-if="ctrl.loadBalancer.loadBalancerType !== \'classic\'">\n Select a target group to check the instance health status from the view of the target group.\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'" heading="Listeners">\n <dl>\n <dt>Load Balancer &rarr; Instance</dt>\n <dd ng-repeat="listener in ctrl.loadBalancer.elb.listenerDescriptions">\n {{listener.listener.protocol}}:{{listener.listener.loadBalancerPort}} &rarr;\n {{listener.listener.instanceProtocol}}:{{listener.listener.instancePort}}\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType !== \'classic\'" heading="Listeners">\n <div ng-repeat="listener in ctrl.listeners">\n <div class="listener-targets">{{listener.in}} &rarr;</div>\n <div class="listener-targets">\n <div ng-repeat="action in listener.actions">\n \x3c!-- redirect --\x3e\n <span ng-if="action.type === \'redirect\'">\n <span ng-if="action.redirectConfig.protocol !== listener.protocol">\n {{action.redirectConfig.protocol}}:\n </span>\n <span ng-if="action.redirectConfig.host !== \'#{host}\'"> {{action.redirectConfig.host}} </span>\n <span ng-if="action.redirectConfig.port !== \'#{port}\'"> {{action.redirectConfig.port}} </span>\n <span ng-if="action.redirectConfig.path !== \'/#{path}\'"> {{action.redirectConfig.path}} </span>\n <span ng-if="action.redirectConfig.query !== \'#{query}\'"> ?{{action.redirectConfig.query}} </span>\n ({{action.redirectConfig.statusCode}})\n </span>\n \x3c!-- authenticate-oidc --\x3e\n <span ng-if="action.type === \'authenticate-oidc\'">\n <i class="fas fa-fw fa-user-lock"></i>\n <a\n ng-if="ctrl.oidcConfigPath"\n href="{{ctrl.oidcConfigPath}}{{action.authenticateOidcConfig.clientId}}"\n target="_blank"\n >\n {{action.authenticateOidcConfig.clientId}}\n </a>\n <span ng-if="!ctrl.oidcConfigPath"> {{action.authenticateOidcConfig.clientId}} </span>\n </span>\n \x3c!-- forward --\x3e\n <span ng-if="action.targetGroupName && action.targetGroup">\n <i class="fa fa-fw fa-crosshairs icon" aria-hidden="true"></i>\n <a\n ui-sref="^.targetGroupDetails({region: action.targetGroup.region,\n loadBalancerName: ctrl.loadBalancer.name,\n accountId: action.targetGroup.account,\n name: action.targetGroup.name,\n vpcId: action.targetGroup.vpcId,\n provider: \'aws\'})"\n >\n {{action.targetGroupName}}\n </a>\n </span>\n <span ng-if="action.targetGroupName && !action.targetGroup">\n <i class="fa fa-fw fa-crosshairs icon" aria-hidden="true"></i>\n {{action.targetGroupName}}\n </span>\n </div>\n </div>\n </div>\n </collapsible-section>\n <collapsible-section\n heading="{{ctrl.firewallsLabel}}"\n ng-if="ctrl.loadBalancer.loadBalancerType !== \'network\' || (ctrl.loadBalancer.loadBalancerType === \'network\' && ctrl.securityGroups && ctrl.securityGroups.length > 0)"\n >\n <ul>\n <li ng-repeat="securityGroup in ctrl.securityGroups | orderBy:\'name\'">\n <a\n ui-sref="^.firewallDetails({name:securityGroup.name, accountId: ctrl.loadBalancer.account, region: ctrl.loadBalancer.region, vpcId: ctrl.loadBalancer.vpcId, provider: ctrl.loadBalancer.provider})"\n >\n {{securityGroup.name}} ({{securityGroup.id}})\n </a>\n </li>\n </ul>\n </collapsible-section>\n <collapsible-section heading="Subnets">\n <div ng-if="ctrl.loadBalancer.subnetDetails.length === 0">\n <h5>No subnets</h5>\n </div>\n <div ng-repeat="subnet in ctrl.loadBalancer.subnetDetails" ng-class="{\'bottom-border\': !$last}">\n <h5><strong>{{subnet.id}}</strong></h5>\n <dl class="dl-horizontal dl-narrow">\n <dt>Purpose</dt>\n <dd>{{subnet.purpose}}</dd>\n\n <dt>State</dt>\n <dd>{{subnet.state}}</dd>\n\n <dt>Cidr Block</dt>\n <dd>{{subnet.cidrBlock}}</dd>\n </dl>\n </div>\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'" heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.target}}</dd>\n <dt>Timeout</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.timeout}} seconds</dd>\n <dt>Interval</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.interval}} seconds</dd>\n <dt>Healthy Threshold</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.healthyThreshold}}</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.unhealthyThreshold}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/loadBalancer/details/targetGroupDetails.html",'<div class="details-panel">\n <div ng-if="ctrl.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="!ctrl.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 fa-crosshairs icon" aria-hidden="true"></i>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{ctrl.targetGroup.name}}</h3>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!ctrl.state.loading && ctrl.loadBalancer.isManaged"\n resource-summary="ctrl.loadBalancer.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div ng-if="!ctrl.state.loading" class="content">\n <collapsible-section heading="Target Group Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>In</dt>\n <dd><account-tag account="ctrl.targetGroup.account" pad="right"></account-tag> {{ctrl.targetGroup.region}}</dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="ctrl.targetGroup.vpcId"></vpc-tag>\n </dd>\n <dt>Protocol</dt>\n <dd>{{ctrl.targetGroup.protocol}}</dd>\n <dt>Port</dt>\n <dd>{{ctrl.targetGroup.port}}</dd>\n <dt>Target Type</dt>\n <dd>{{ctrl.targetGroup.targetType}}</dd>\n </dl>\n <dl ng-if="ctrl.loadBalancer" class="horizontal-when-filters-collapsed">\n <dt>Load Balancer</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li>\n <a\n ui-sref="^.loadBalancerDetails({ name: ctrl.loadBalancer.name,\n region: ctrl.loadBalancer.region,\n accountId: ctrl.loadBalancer.account,\n vpcId: ctrl.loadBalancer.vpcId,\n provider: \'aws\'})"\n >\n {{ctrl.loadBalancer.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="ctrl.loadBalancer.dnsname">Load Balancer DNS Name</dt>\n <dd ng-if="ctrl.loadBalancer.dnsname">\n <a target="_blank" href="{{ctrl.elbProtocol}}//{{ctrl.loadBalancer.dnsname}}"\n >{{ctrl.loadBalancer.dnsname}}</a\n >\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="ctrl.loadBalancer.dnsname"\n tool-tip="\'Copy DNS Name to clipboard\'"\n >\n </copy-to-clipboard>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.targetGroup.serverGroups && ctrl.targetGroup.serverGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Server Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in ctrl.targetGroup.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: serverGroup.cloudProvider})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <health-counts class="pull-left" container="ctrl.targetGroup.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>\n {{ctrl.targetGroup.healthCheckProtocol}}:{{ctrl.targetGroup.healthCheckPort}}\n {{ctrl.targetGroup.healthCheckPath}}\n </dd>\n <dt>Timeout</dt>\n <dd>{{ctrl.targetGroup.healthCheckTimeoutSeconds}} seconds</dd>\n <dt>Interval</dt>\n <dd>{{ctrl.targetGroup.healthCheckIntervalSeconds}} seconds</dd>\n <dt>Healthy Threshold</dt>\n <dd>{{ctrl.targetGroup.healthyThresholdCount}}</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{ctrl.targetGroup.unhealthyThresholdCount}}</dd>\n <dt>Matcher</dt>\n <dd>HTTP Code(s): {{ctrl.targetGroup.matcher.httpCode}}</dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Attributes" expanded="true">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Deregistration Delay Timeout</dt>\n <dd>{{ctrl.targetGroup.attributes[\'deregistration_delay.timeout_seconds\']}} seconds</dd>\n <dt>Stickiness Enabled</dt>\n <dd>{{ctrl.targetGroup.attributes[\'stickiness.enabled\']}}</dd>\n <dt ng-if-start="ctrl.targetGroup.attributes[\'stickiness.enabled\'] === \'true\'">\n Stickiness Load Balancer Cookie Duration\n </dt>\n <dd>{{ctrl.targetGroup.attributes[\'stickiness.lb_cookie.duration_seconds\']}} seconds</dd>\n <dt>Stickiness Type</dt>\n <dd ng-if-end>{{ctrl.targetGroup.attributes[\'stickiness.type\']}}</dd>\n <dt ng-if-start="ctrl.loadBalancer.loadBalancerType === \'network\'">Preserve Client IP</dt>\n <dd ng-if-end>{{ctrl.targetGroup.attributes[\'preserve_client_ip.enabled\']}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/details/securityGroupDetail.html",'<div class="text-center" ng-if="state.notFound">\n <h3>Could not find <firewall-label label="firewall"></firewall-label> {{group}}.</h3>\n <a ui-sref="home.infrastructure">Back to search results</a>\n</div>\n<div class="details-panel" ng-if="!state.notFound">\n <div class="header">\n <div class="close-button" ng-if="!state.standalone">\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 <render-if-feature feature="entityTags">\n <entity-notifications\n entity="securityGroup"\n application="ctrl.application"\n placement="bottom"\n h-offset-percent="90%"\n entity-type="securityGroup"\n page-location="details"\n on-update="ctrl.application.securityGroups.refresh()"\n ></entity-notifications>\n </render-if-feature>\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><a href ng-click="ctrl.editInboundRules()">Edit Inbound Rules</a></li>\n <li>\n <a href ng-click="ctrl.deleteSecurityGroup()">Delete <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <li>\n <a href ng-click="ctrl.cloneSecurityGroup()">Clone <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <render-if-feature feature="entityTags">\n <add-entity-tag-links\n component="securityGroup"\n application="ctrl.application"\n entity-type="securityGroup"\n on-update="ctrl.application.securityGroups.refresh"\n ></add-entity-tag-links>\n </render-if-feature>\n </ul>\n </div>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!state.loading && securityGroup.isManaged"\n resource-summary="securityGroup.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div class="content" ng-if="!state.loading">\n <collapsible-section heading="{{ctrl.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>\n <account-tag account="securityGroup.accountName"></account-tag>\n </dd>\n <dt>Region</dt>\n <dd>{{securityGroup.region}}</dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="securityGroup.vpcId"></vpc-tag>\n </dd>\n <dt>Description</dt>\n <dd>{{securityGroup.description}}</dd>\n </dl>\n </collapsible-section>\n <ip-range-rules ip-rules="ipRules"></ip-range-rules>\n <collapsible-section\n heading="{{ctrl.firewallLabel}} Rules ({{securityGroupRules.length || 0}})"\n expanded="{{securityGroupRules.length > 0}}"\n >\n <div ng-if="!securityGroupRules.length">None</div>\n\n <dl\n ng-class="insightCtrl.vm.filtersExpanded ? \'\' : \'dl-horizontal dl-medium\'"\n ng-repeat="rule in securityGroupRules | orderBy: \'securityGroup.name\' "\n >\n <dt>\n <firewall-label label="Firewall"></firewall-label>\n </dt>\n <dd ng-if="rule.securityGroup.name">\n <a\n ui-sref="^.firewallDetails({name: rule.securityGroup.name, accountId: rule.securityGroup.accountName, region: rule.securityGroup.region, vpcId: rule.securityGroup.vpcId, provider: \'aws\'})"\n >\n <account-tag\n account="rule.securityGroup.accountName || rule.securityGroup.accountId"\n ng-if="rule.securityGroup.accountName !== securityGroup.accountName"\n ></account-tag>\n {{rule.securityGroup.name}} ({{rule.securityGroup.id}})\n </a>\n </dd>\n <dt>Port Ranges</dt>\n <dd ng-repeat="portRange in rule.rules">\n {{portRange.protocol}}: {{portRange.startPort}} &rarr; {{portRange.endPort}}\n </dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard heading="Create New {{ctrl.translate(\'Firewall\')}}" 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="form.$invalid || !wizard.isComplete() || state.submitting || !customComponentIsvalid"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="state.isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/applicationProviderFields/awsFields.html",'<div class="form-group row">\n <div class="col-sm-3 sm-label-right">AWS Settings</div>\n <div class="col-sm-9 checkbox" style="margin-bottom: 0; margin-top: 5px">\n <label>\n <input\n type="checkbox"\n ng-init="$ctrl.initializeApplicationField(\'aws.useAmiBlockDeviceMappings\')"\n ng-model="$ctrl.application.providerSettings.aws.useAmiBlockDeviceMappings"\n />\n Prefer AMI Block Device Mappings\n </label>\n </div>\n</div>\n')}]);const Ys=({command:e,cooldowns:t,policyName:a,updateCommand:r})=>{var i;const s=(t,a)=>{const n={...e};Jt(n,t,a),r(n)},l=Boolean(null==(i=e.targetTracking)?void 0:i.disableScaleIn);return zt.createElement("div",{className:"section-body section-additional-settings"},a&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Policy Name"),zt.createElement("div",{className:"col-md-10 content-fields"},a)),Boolean(e.esitmatedInstanceWarmup)&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Warmup"),zt.createElement("div",{className:"col-md-10 content-fields"},zt.createElement("span",{className:"form-control-static select-placeholder"},"Instances need"),zt.createElement(u,{value:e.estimatedInstanceWarmup,onChange:e=>s("estimatedInstanceWarmup",Number.parseInt(e.target.value)),inputClassName:"form-control input-sm sp-margin-xs-xaxis"}),zt.createElement("span",{className:"input-label"}," seconds to warm up "))),zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-2 sm-label-right"},"Scale In"),zt.createElement("div",{className:"col-md-9"},zt.createElement("div",{className:"checkbox"},zt.createElement(d,{text:"Disable Scale-downs",checked:l,onChange:e=>s("targetTrackingConfiguration.disableScaleIn",e.target.checked)}),zt.createElement("div",{className:"small"},zt.createElement("p",null,"This option disables scale-downs for the target tracking policy, while keeping the scale-ups. This means that ASG will not scale down unless you explicitly set up a separate step policy to scale it down."),zt.createElement("p",null,"This is useful when you have special requirements, such as gradual or delayed scale-down."))))),zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-10 col-md-offset-1 well"},l&&zt.createElement("div",null,"This policy will not scale down. Make sure you have another policy (either TT or Step) that will scale down this ASG."),!l&&zt.createElement("div",null,"This policy will scale both up and down. Make sure you don't have other scaling policies, as they will likely interfere with each other."))),t&&!l&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-3 sm-label-right"},zt.createElement("span",{className:"sp-margin-xs-right"},"Scale In Cooldown"),zt.createElement(n,{id:"titus.autoscaling.scaleIn.cooldown"})),zt.createElement("div",{className:"col-md-9 content-fields"},zt.createElement(u,{value:e.targetTrackingConfiguration.scaleInCooldown,onChange:e=>s("targetTrackingConfiguration.scaleInCooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis"}),zt.createElement("span",{className:"input-label"}," seconds "))),t&&zt.createElement("div",{className:"row"},zt.createElement("div",{className:"col-md-3 sm-label-right"},zt.createElement("span",{className:"sp-margin-xs-right"},"Scale Out Cooldown"),zt.createElement(n,{id:"titus.autoscaling.scaleOut.cooldown"})),zt.createElement("div",{className:"col-md-9 content-fields"},zt.createElement(u,{value:e.targetTrackingConfiguration.scaleInCooldown,onChange:e=>s("targetTrackingConfiguration.scaleOutCooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis"}),zt.createElement("span",{className:"input-label"}," seconds "))))};export{Ks as AMAZON_MODULE,xs as AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_ADDITIONAL_SETTINGS_COMPONENT,gn as AWSProviderSettings,Cs as AWS_SERVER_GROUP_CONFIGURATION_SERVICE,Ki as AdvancedSettingsDetailsSection,Vs as AlarmConfigurer,Ji as AmazonCapacityDetailsSection,ur as AmazonCertificateReader,hr as AmazonCertificateSelectField,qn as AmazonFunctionDetails,bi as AmazonImageSelectInput,Yi as AmazonInfoDetailsSection,Kn as AmazonInstanceWriter,Zr as AmazonLoadBalancerChoiceModal,ar as AmazonLoadBalancerClusterContainer,nr as AmazonLoadBalancerDataUtils,sr as AmazonLoadBalancersTag,Vi as AmazonResizeServerGroupModal,vn as AwsFunctionTransformer,Pr as AwsLoadBalancerTransformer,Oi as AwsModalFooter,Rn as AwsNgReact,Ln as AwsNgReactInjector,On as AwsReactInject,Un as AwsReactInjector,Es as AwsServerGroupConfigurationService,zn as CreateLambdaFunction,ps as CreateScalingPolicyButton,ks as DateLineChart,Ps as DimensionsEditor,Bn as FunctionActions,Sn as FunctionBasicInformation,es as HealthDetailsSection,fi as IPRangeRules,Qn as InstanceDns,Zn as InstanceInformation,Jn as InstanceStatus,ts as InstancesDiversificationDetailsSection,ws as KeyPairsReader,ns as LaunchConfigDetailsSection,is as LaunchTemplateDetailsSection,Hr as LoadBalancerTypes,ss as LogsDetailsSection,Ss as MetricAlarmChart,Bs as MetricSelector,ls as PackageDetailsSection,ds as PolicyTypeSelectionModal,gs as ScalingPoliciesDetailsSection,Is as ScalingPolicyAdditionalSettings,Dn as ScalingPolicyTypeRegistrar,$n as ScalingPolicyTypeRegistry,os as ScalingPolicyWriter,hs as ScalingProcessesDetailsSection,vs as ScheduledActionsDetailsSection,Ai as SecurityGroupSelector,ys as SecurityGroupsDetailsSection,Fi as ServerGroupAdvancedSettings,Bi as ServerGroupAdvancedSettingsCommon,Ei as ServerGroupBasicSettings,Si as ServerGroupCapacity,Ni as ServerGroupInstanceType,xi as ServerGroupLoadBalancers,zi as ServerGroupSecurityGroups,Pi as ServerGroupSecurityGroupsRemoved,Ti as ServerGroupZones,js as StepPolicyAction,Ir as SubnetSelectField,Tr as SubnetSelectInput,bs as TagsDetailsSection,tr as TargetGroup,ei as TargetGroupDetails,Ws as TargetMetricFields,Ys as TargetTrackingAdditionalSettings,Hs as TargetTrackingChart,xn as VpcReader,Xn as applyHealthCheckInfoToTargetGroups,Yn as getAllTargetGroups,as as getBaseImageName,As as name};
1
+ import*as e from"angular";import{module as t}from"angular";import{SETTINGS as a,HelpField as n,DeploymentStrategyRegistry as r,FormValidator as i,FormikFormField as s,TextInput as l,AccountService as o,ReactSelectInput as c,CheckboxInput as d,MapEditorInput as p,NumberInput as u,NetworkReader as m,SubnetReader as g,ReactInjector as h,TetheredSelect as f,TaskMonitor as v,FunctionWriter as y,ReactModal as b,WizardModal as w,WizardPage as E,noop as C,ConfirmationModalService as k,ApplicationReader as S,AddEntityTagLinks as N,ReactInject as G,Details as T,AccountTag as I,Overrides as x,CollapsibleSection as A,HelpContentsRegistry as P,REST as z,LabeledValue as B,timestamp as D,useData as $,SubnetTag as F,withErrorBoundary as M,InstanceWriter as R,TaskExecutor as L,CloudProviderRegistry as O,FirewallLabels as U,RecentHistoryService as V,InstanceReader as q,LabeledValueList as j,LinkWithClipboard as H,robotToHuman as W,Tooltip as Z,InstanceLoadBalancerHealth as _,LoadBalancerServerGroup as K,HealthCounts as Y,LoadBalancerInstances as X,LoadBalancerClusterContainer as Q,logger as J,LoadBalancerDataUtils as ee,Spinner as te,HoverablePopover as ae,SpinFormik as ne,ModalClose as re,SubmitButton as ie,SelectInput as se,CertificateReader as le,relativeTime as oe,Overridable as ce,ValidationMessage as de,CustomLabels as pe,Validators as ue,spelNumberCheck as me,SpInput as ge,SpelNumberInput as he,ChecklistInput as fe,useDeepObjectDiff as ve,useMountStatusRef as ye,createFakeReactSyntheticEvent as be,Markdown as we,NameUtils as Ee,AccountSelectInput as Ce,RegionSelectField as ke,InfrastructureCaches as Se,LoadBalancerWriter as Ne,ManagedMenuItem as Ge,SECURITY_GROUP_READER as Te,LOAD_BALANCER_READ_SERVICE as Ie,MANAGED_RESOURCE_DETAILS_INDICATOR as xe,APPLICATION_STATE_PROVIDER as Ae,Registry as Pe,BakeExecutionLabel as ze,AuthenticationService as Be,PipelineTemplates as De,BakeryReader as $e,StageConstants as Fe,AppListExtractor as Me,StageConfigField as Re,yamlDocumentsToString as Le,ExecutionDetailsSection as Oe,ExecutionStepDetails as Ue,StageFailureMessage as Ve,NgGenericArtifactDelegate as qe,ExpectedArtifactSelectorViewController as je,ExecutionBarLabel as He,ExpectedArtifactService as We,ArtifactReferenceService as Ze,EXECUTION_SERVICE as _e,PipelineConfigService as Ke,ModalWizard as Ye,SecurityGroupWriter as Xe,filterObjectValues as Qe,CACHE_INITIALIZER_SERVICE as Je,confirmNotManaged as et,DeployInitializer as tt,DeployingIntoManagedClusterWarning as at,ServerGroupDetailsField as nt,DeploymentStrategySelector as rt,ServerGroupNamePreview as it,TaskReason as st,ToggleButtonGroup as lt,ToggleSize as ot,NgReact as ct,PlatformHealthOverride as dt,MapEditor as pt,UserVerification as ut,TaskMonitorWrapper as mt,MinMaxDesiredChanges as gt,ServerGroupWarningMessageService as ht,ModalInjector as ft,ClusterTargetBuilder as vt,ServerGroupReader as yt,EntitySource as bt,ViewChangesLink as wt,CapacityDetailsSection as Et,ViewScalingActivitiesLink as Ct,ShowUserData as kt,CloudMetricsReader as St,useForceUpdate as Nt,useObservable as Gt,TaskMonitorModal as Tt,usePrevious as It,setMatchingResourceSummary as xt,SERVER_GROUP_COMMAND_REGISTRY_PROVIDER as At,INSTANCE_TYPE_SERVICE as Pt,SERVER_GROUP_WRITER as zt,ApplicationNameValidator as Bt}from"@spinnaker/core";import*as Dt from"react";import $t,{useState as Ft}from"react";import Mt,{isEmpty as Rt,forOwn as Lt,uniqBy as Ot,cloneDeep as Ut,flatten as Vt,isNil as qt,orderBy as jt,isEqual as Ht,sortBy as Wt,pickBy as Zt,groupBy as _t,get as Kt,uniq as Yt,difference as Xt,some as Qt,isNumber as Jt,filter as ea,set as ta,chain as aa,partition as na,map as ra,every as ia,values as sa,head as la,extend as oa,intersection as ca,find as da,has as pa,flatMap as ua,clone as ma,keys as ga,xor as ha,defaults as fa}from"lodash";import va from"classnames";import{Subject as ya,from as ba,combineLatest as wa,BehaviorSubject as Ea,of as Ca,Observable as ka}from"rxjs";import{map as Sa,distinctUntilChanged as Na,shareReplay as Ga,switchMap as Ta,withLatestFrom as Ia,takeUntil as xa,tap as Aa,mergeMap as Pa,catchError as za,debounceTime as Ba,take as Da}from"rxjs/operators";import{Dropdown as $a,Modal as Fa,Button as Ma,Tooltip as Ra,OverlayTrigger as La,ModalFooter as Oa,MenuItem as Ua}from"react-bootstrap";import{angular2react as Va}from"angular2react";import{$q as qa}from"ngimport";import{react2angular as ja}from"react2angular";import{UISref as Ha,UISrefActive as Wa}from"@uirouter/react";import{UIRouterContextComponent as Za}from"@uirouter/react-hybrid";import _a from"@uirouter/angularjs";import Ka from"angular-ui-bootstrap";import{SortableHandle as Ya,arrayMove as Xa,SortableElement as Qa,SortableContainer as Ja}from"react-sortable-hoc";import{Form as en,Field as tn}from"formik";import an from"react-select";import nn from"react-virtualized-select";import{Chart as rn,LineController as sn,LineElement as ln,PointElement as on,LinearScale as cn,Title as dn,TimeScale as pn,Tooltip as un,Legend as mn,Filler as gn}from"chart.js";import"chartjs-adapter-luxon";const hn={bindings:{action:"&",isValid:"&",cancel:"&",account:"=?",verification:"=?"},template:'\n <div class="modal-footer">\n <user-verification account="$ctrl.account" verification="$ctrl.verification"></user-verification>\n <button type="submit" ng-click="$ctrl.action()" style="display:none"></button> \x3c!-- Allows form submission via enter keypress--\x3e\n <button class="btn btn-default" ng-click="$ctrl.cancel()">Cancel</button>\n <button type="submit"\n class="btn btn-primary"\n ng-click="$ctrl.action()"\n ng-disabled="!$ctrl.isValid()">\n Submit\n </button>\n </div>\n ',controller:()=>{}};t("spinnaker.amazon.footer",[]).component("awsFooter",hn);t("spinnaker.amazon.common",["spinnaker.amazon.footer"]);const fn=a.providers.aws||{defaults:{}};fn&&(fn.resetToOriginal=a.resetProvider("aws"));class vn extends $t.Component{constructor(){super(...arguments),this.handleChange=(e,t)=>{this.props.command.termination[e]=t,this.forceUpdate()}}render(){var e;const{command:t}=this.props;return $t.createElement("div",{className:"form-group",style:{marginTop:"20px"}},$t.createElement("div",{className:"well-compact alert alert-warning"},$t.createElement("strong",null,"Note:")," a rolling push only updates the"," ",$t.createElement("em",null,"launch ",Boolean(null==(e=fn.serverGroups)?void 0:e.enableLaunchTemplates)?"template":"configuration")," ","for the auto scaling group.",$t.createElement("br",null)," Changes to the following fields will be ignored:",$t.createElement("ul",null,$t.createElement("li",null,"Account, Region, Subnet Type"),$t.createElement("li",null,"Capacity"),$t.createElement("li",null,"Load Balancers"),$t.createElement("li",null,"Health Check Configuration"),$t.createElement("li",null,"Termination Policies, Enable Traffic flag"))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",checked:t.termination.relaunchAllInstances,onChange:e=>this.handleChange("relaunchAllInstances",e.target.checked)}),$t.createElement("b",null,"Relaunch all instances"),$t.createElement(n,{id:"strategy.rollingPush.relaunchAll"})))),!t.termination.relaunchAllInstances&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},"Total relaunches",$t.createElement(n,{id:"strategy.rollingPush.totalRelaunches"})),$t.createElement("div",{className:"col-md-2"},$t.createElement("input",{className:"form-control input-sm",type:"number",value:t.termination.totalRelaunches,onChange:e=>this.handleChange("totalRelaunches",e.target.value),min:"0"}))),(t.termination.totalRelaunches>0||t.termination.relaunchAllInstances)&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},"Concurrent relaunches",$t.createElement(n,{id:"strategy.rollingPush.concurrentRelaunches"})),$t.createElement("div",{className:"col-md-2"},$t.createElement("input",{className:"form-control input-sm",type:"number",value:t.termination.concurrentRelaunches,onChange:e=>this.handleChange("concurrentRelaunches",e.target.value),min:"1"}))),(t.termination.totalRelaunches>0||t.termination.relaunchAllInstances)&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},"Order",$t.createElement(n,{id:"strategy.rollingPush.order"})),$t.createElement("div",{className:"col-md-3"},$t.createElement("select",{className:"input input-sm",style:{width:"100px"},value:t.termination.order,onChange:e=>this.handleChange("order",e.target.value)},$t.createElement("option",{value:"oldest"},"oldest first"),$t.createElement("option",{value:"newest"},"newest first")))))}}var yn;r.registerStrategy({label:"Rolling Push (not recommended)",description:`Updates the launch ${(null==(yn=fn.serverGroups)?void 0:yn.enableLaunchTemplates)?"template":"configuration"} for this server group, then terminates instances incrementally,\n replacing them with instances launched with the updated configuration. This is not a best practice - it goes against\n the principles of immutable infrastructure - but may be necessary in some cases.`,key:"rollingpush",providerRestricted:!0,additionalFields:["termination.totalRelaunches","termination.concurrentRelaunches","termination.order","termination.relaunchAllInstances"],AdditionalFieldsComponent:vn,initializationMethod:e=>{var t,a;e.termination=e.termination||{order:"oldest",relaunchAllInstances:!0,concurrentRelaunches:1,totalRelaunches:null!=(a=Number(null==(t=null==e?void 0:e.capacity)?void 0:t.max))?a:1}}});class bn{constructor(){this.convertFunctionForEditing=e=>({...e,envVariables:e.environment?e.environment.variables:{},credentials:e.account,tracingConfig:{mode:e.tracingConfig?e.tracingConfig.mode:""},deadLetterConfig:{targetArn:e.deadLetterConfig?e.deadLetterConfig.targetArn:""},KMSKeyArn:e.kmskeyArn?e.kmskeyArn:"",subnetIds:e.vpcConfig?e.vpcConfig.subnetIds:[],securityGroupIds:e.vpcConfig?e.vpcConfig.securityGroupIds:[],vpcId:e.vpcConfig?e.vpcConfig.vpcId:"",operation:"",cloudProvider:e.cloudProvider,region:e.region,targetGroups:Rt(e.targetGroups)?"":e.targetGroups})}normalizeFunction(e){const t=e;return t.credentials=e.account,t}constructNewAwsFunctionTemplate(e){return{role:"",runtime:"",s3bucket:"",s3key:"",handler:"",functionName:"",publish:!1,tags:{},memorySize:128,description:"",credentials:e.defaultCredentials.aws||fn.defaults.account,cloudProvider:"aws",detail:"",region:e.defaultRegions.aws||fn.defaults.region,envVariables:{},tracingConfig:{mode:"PassThrough"},kmskeyArn:"",vpcId:"",subnetIds:[],securityGroupIds:[],timeout:3,deadLetterConfig:{targetArn:""},operation:"",targetGroups:""}}}const wn=(e,t)=>e.match(/^arn:aws:iam::\d{12}:role\/?\/[a-zA-Z_0-9+=,.@\-_/]+/)?void 0:`Invalid role. ${t} must match regular expression: arn:aws:iam::d{12}:role/?[a-zA-Z_0-9+=,.@-_/]+`,En=(e,t)=>e.match(/^[0-9A-Za-z.-]*[^.]$/)?void 0:`Invalid S3 Bucket name. ${t} must match regular expression: [0-9A-Za-z.-]*[^.]$`,Cn=(e,t)=>e.match(/arn:aws[a-zA-Z-]?:[a-zA-Z_0-9.-]+:./)?void 0:`Invalid ARN. ${t} must match regular expression: /arn:aws[a-zA-Z-]?:[a-zA-Z_0-9.-]+:./`,kn=(e,t)=>Rt(e)?`At least one ${t} is required`:void 0;class Sn extends $t.Component{constructor(e){super(e)}validate(e){const t=new i(e);return t.field("role","Role ARN").required().withValidators(wn),t.validateForm()}render(){return $t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-11"},$t.createElement("div",{className:"sp-margin-m-bottom"},$t.createElement(s,{name:"role",label:"Role ARN",input:e=>$t.createElement(l,{...e,placeholder:"Enter role ARN",name:"role"}),required:!0}))))}}const Nn=["nodejs10.x","nodejs12.x","java8","java11","python2.7","python3.6","python3.7","python3.8","dotnetcore2.1","dotnetcore3.1","go1.x","ruby2.5","ruby2.7","provided"];class Gn extends $t.Component{constructor(){super(...arguments),this.state={accounts:[],existingFunctionNames:[],regions:[]},this.props$=new ya,this.destroy$=new ya}validate(e){const t=new i(e);t.field("s3bucket","S3 Bucket Name").optional().withValidators(En);const a=t.validateForm();return this.props.isNew&&this.state.existingFunctionNames.includes(this.props.app.name.concat("-").concat(e.functionName))&&(a.functionName=`There is already a function in ${e.credentials}:${e.region} with that name.`),a}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}componentDidMount(){const e=this.props$.pipe(Sa((e=>e.formik.values))),t={account$:e.pipe(Sa((e=>e.credentials)),Na()),region$:e.pipe(Sa((e=>e.region)),Na()),functionName$:e.pipe(Sa((e=>e.functionName)),Na()),runtime$:e.pipe(Sa((e=>e.runtime)),Na()),s3bucket$:e.pipe(Sa((e=>e.s3bucket)),Na()),s3key$:e.pipe(Sa((e=>e.s3key)),Na()),handler$:e.pipe(Sa((e=>e.handler)),Na())},a=ba(o.listAccounts("aws")).pipe(Ga(1)),n=wa([t.account$,a]).pipe(Ta((([e,t])=>o.getRegionsForAccount(e))),Ga(1)),r=this.props.app.getDataSource("functions").data$,i=wa([r,t.account$,t.region$]).pipe(Sa((([e,t,a])=>e.filter((e=>e.account===t&&e.region===a)).map((e=>e.functionName)))),Ga(1));n.pipe(Ia(t.region$),xa(this.destroy$)).subscribe((([e,t])=>{e.some((e=>e.name===t))||this.props.formik.setFieldValue("region",e[0]&&e[0].name)})),wa([a,n,i]).pipe(xa(this.destroy$)).subscribe((([e,t,a])=>this.setState({accounts:e,regions:t,existingFunctionNames:a})))}render(){const{isNew:e}=this.props,{errors:t,values:a}=this.props.formik,{accounts:r,regions:i}=this.state,o=va({well:!0,"alert-danger":!!t.functionName,"alert-info":!t.functionName});return $t.createElement("div",{className:"container-fluid form-horizontal "},e&&$t.createElement("div",{className:o},$t.createElement("strong",null,"Your function will be named: "),$t.createElement(n,{id:"aws.function.name"}),$t.createElement("span",null,this.props.app.name,"-",a.functionName),$t.createElement(s,{name:"functionName",input:()=>null})),$t.createElement(s,{name:"credentials",label:"Account",input:e=>$t.createElement(c,{...e,stringOptions:r.map((e=>e.name)),clearable:!0})}),$t.createElement(s,{name:"region",label:"Region",input:e=>$t.createElement(c,{...e,stringOptions:i.map((e=>e.name)),clearable:!0})}),$t.createElement(s,{name:"functionName",label:"Function Name",help:$t.createElement(n,{id:"aws.function.name"}),input:e=>$t.createElement(l,{...e})}),$t.createElement(s,{name:"runtime",label:"Runtime",help:$t.createElement(n,{id:"aws.function.runtime"}),input:e=>$t.createElement(c,{...e,stringOptions:Nn,clearable:!0})}),$t.createElement(s,{name:"s3bucket",label:"S3 Bucket",help:$t.createElement(n,{id:"aws.function.s3bucket"}),input:e=>$t.createElement(l,{...e,placeholder:"S3 bucket name"})}),$t.createElement(s,{name:"s3key",label:"S3 Key",help:$t.createElement(n,{id:"aws.function.s3key"}),input:e=>$t.createElement(l,{...e,placeholder:"object.zip"})}),$t.createElement(s,{name:"handler",label:"Handler",help:$t.createElement(n,{id:"aws.function.handler"}),input:e=>$t.createElement(l,{...e,placeholder:"filename.method"})}),$t.createElement(s,{name:"publish",label:"Publish",input:e=>$t.createElement(d,{...e})}))}}class Tn extends $t.Component{constructor(e){super(e),this.validate=e=>{const t=new i(e);return t.field("deadLetterConfig.targetArn","Target ARN").optional().withValidators(Cn),t.validateForm()}}render(){return $t.createElement("div",{className:"container-fluid form-horizontal "},"Dead Letter Config",$t.createElement(s,{name:"deadLetterConfig.targetArn",label:"Target ARN",help:$t.createElement(n,{id:"aws.function.deadletterqueue"}),input:e=>$t.createElement(l,{...e})}),"X-Ray Tracing",$t.createElement(s,{name:"tracingConfig.mode",label:"Mode",help:$t.createElement(n,{id:"aws.function.tracingConfig.mode"}),input:e=>$t.createElement(c,{...e,stringOptions:["Active","PassThrough"],clearable:!0})}))}}class In extends $t.Component{constructor(){super(...arguments),this.validate=e=>{const t=new i(e);return t.field("kmskeyArn","KMS Key ARN").optional().withValidators(Cn),t.validateForm()}}render(){return $t.createElement("div",{className:"container-fluid form-horizontal "},$t.createElement(s,{name:"envVariables",label:"Env Variables",input:e=>$t.createElement(p,{...e,allowEmptyValues:!0,addButtonLabel:"Add"})}),$t.createElement(s,{name:"kmskeyArn",label:"Key ARN",help:$t.createElement(n,{id:"aws.function.kmsKeyArn"}),input:e=>$t.createElement(l,{...e})}))}}class xn extends $t.Component{constructor(){super(...arguments),this.validate=()=>({})}render(){return $t.createElement("div",{className:"container-fluid form-horizontal "},$t.createElement(s,{name:"description",label:"Description",input:e=>$t.createElement(l,{...e})}),$t.createElement(s,{name:"memorySize",label:"Memory (MB)",help:$t.createElement(n,{id:"aws.functionBasicSettings.memorySize"}),input:e=>$t.createElement(u,{...e,min:128,max:3008})}),$t.createElement(s,{name:"timeout",label:"Timeout (seconds)",help:$t.createElement(n,{id:"aws.functionBasicSettings.timeout"}),input:e=>$t.createElement(u,{...e,min:1,max:900})}),$t.createElement(s,{name:"targetGroups",label:"Target Group Name",input:e=>$t.createElement(l,{...e})}))}}class An extends $t.Component{constructor(){super(...arguments),this.validate=e=>{const t=new i(e);return t.field("tags","Tag").required().withValidators(kn),t.validateForm()}}render(){return $t.createElement("div",{className:"container-fluid form-horizontal "},$t.createElement(s,{name:"tags",input:e=>$t.createElement(p,{...e,allowEmptyValues:!1,addButtonLabel:"Add"})}))}}class Pn{static listVpcs(){return this.cache||(this.cache=m.listNetworksByProvider("aws").then((e=>e.map((e=>(e.label=e.name,e.deprecated=!!e.deprecated,e.deprecated&&(e.label+=" (deprecated)"),e)))))),this.cache}static resetCache(){this.cache=null}static getVpcName(e){return this.listVpcs().then((t=>{const a=t.find((t=>t.id===e));return a?a.name:null}))}}class zn extends $t.Component{constructor(e){super(e),this.state={vpcOptions:[],accounts:null,regions:[],subnets:[],availableSubnets:[],securityGroups:null},this.props$=new ya,this.destroy$=new ya,this.handleSubnetUpdate=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("subnetIds",t)},this.handleSecurityGroupsUpdate=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("securityGroupIds",t)},this.setVpc=e=>{this.props.formik.setFieldValue("vpcId",e),this.props.formik.setFieldValue("subnetIds",[]);const{availableSubnets:t}=this.state,a=t.filter((function(t){return t.vpcId.includes(e)}));this.setState({subnets:a})},this.toSubnetOption=e=>({value:e.subnetId,label:e.subnetId}),this.getSecurityGroupsByVpc=e=>{const{values:t}=this.props.formik,a=[];return Lt(e,(function(e,n){n===t.credentials&&Lt(e,(function(e,n){"aws"===n&&Lt(e,(function(e,n){n===t.region&&e.forEach((function(e){e.vpcId===t.vpcId&&a.push({value:e.id,label:e.name})}))}))}))})),a},this.getSubnetOptions=()=>{const{subnets:e,availableSubnets:t}=this.state,{values:a}=this.props.formik;return!this.props.isNew&&a.vpcId?t.filter((function(e){return e.vpcId.includes(a.vpcId)})).map(this.toSubnetOption):e.map(this.toSubnetOption)},this.getAllVpcs()}getAllVpcs(){ba(Pn.listVpcs()).pipe(xa(this.destroy$)).subscribe((e=>{this.setState({vpcOptions:e})}))}validate(){return{}}getAvailableSubnets(){return g.listSubnetsByProvider("aws")}getAvailableSecurityGroups(){return h.securityGroupReader.getAllSecurityGroups()}makeSubnetOptions(e){const t=e.map((e=>({subnetId:e.id,vpcId:e.vpcId})));return Ot(t,"subnetId")}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}componentDidMount(){const e=Promise.resolve(this.getAvailableSubnets()).then((e=>(e.forEach((e=>{e.label=e.id,e.deprecated=!!e.deprecated,e.deprecated&&(e.label+=" (deprecated)")})),e.filter((e=>e.label))))).then((e=>this.makeSubnetOptions(e))),t=Promise.resolve(this.getAvailableSecurityGroups());wa([e,t]).pipe(xa(this.destroy$)).subscribe((([e,t])=>this.setState({availableSubnets:e,securityGroups:t})))}render(){const{vpcOptions:e,securityGroups:t}=this.state,{values:a}=this.props.formik,r=this.getSubnetOptions(),i=t?this.getSecurityGroupsByVpc(t):[];return $t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-11"},$t.createElement("div",{className:"sp-margin-m-bottom"},a.credentials&&$t.createElement(s,{name:"vpcId",label:"VPC Id",help:$t.createElement(n,{id:"aws.function.vpc.id"}),input:t=>$t.createElement(c,{...t,stringOptions:e.filter((e=>e.account===a.credentials)).map((e=>e.id)),clearable:!0}),onChange:this.setVpc,required:!1})),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-4 sm-label-right"},$t.createElement("b",null,"Subnets "),$t.createElement(n,{id:"aws.function.subnet"})),$t.createElement("div",{className:"col-md-7"},0===r.length&&$t.createElement("div",{className:"form-control-static"},"No subnets found in the selected account/region/VPC"),a.vpcId?$t.createElement(f,{multi:!0,options:r,value:a.subnetIds,onChange:this.handleSubnetUpdate}):null)),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-4 sm-label-right"},$t.createElement("b",null,"Security Groups "),$t.createElement(n,{id:"aws.function.subnet"})),$t.createElement("div",{className:"col-md-7"},0===i.length&&$t.createElement("div",{className:"form-control-static"},"No security groups found in the selected account/region/VPC"),a.credentials&&a.vpcId?$t.createElement(f,{multi:!0,options:i,value:a.securityGroupIds,onChange:this.handleSecurityGroupsUpdate}):null))))}}const Bn=class extends $t.Component{constructor(e){super(e),this._isUnmounted=!1,this.submit=e=>{const{app:t}=this.props,{isNew:a}=this.state,n=Ut(e),r=a?"Create":"Update",i=new v({application:t,title:(a?"Creating":"Updating")+" your function",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>{this.checkForS3Update(n,r)}});i.submit((()=>(n.type="lambdaFunction",n.operation=a?"createLambdaFunction":"updateLambdaFunctionConfiguration",y.upsertFunction(n,t,r)))),this.setState({taskMonitor:i})};const t=new bn,a=e.functionDef?t.convertFunctionForEditing(e.functionDef):t.constructNewAwsFunctionTemplate(e.app);this.state={isNew:!e.functionDef,functionCommand:a,taskMonitor:null}}static show(e){return b.show(Bn,e,{dialogClassName:"wizard-modal modal-lg"})}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.functionDetails")?h.$state.go("^.functionDetails",t):h.$state.go(".functionDetails",t)}onTaskComplete(e){this.props.app.functions.refresh(),this.refreshUnsubscribe=this.props.app.functions.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}checkForS3Update(e,t){const{isNew:a}=this.state;if(!a&&(e.s3bucket||e.s3key)){e.operation="updateLambdaFunctionCode";const{app:a}=this.props;y.upsertFunction(e,a,t)}this.onTaskComplete(e)}render(){const{app:e,dismissModal:t,forPipelineConfig:a,functionDef:n}=this.props,{isNew:r,functionCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Existing Function":"Create New Function";return r||(l=`Edit ${i.functionName}: ${i.region}: ${i.credentials}`),$t.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",render:({formik:t,nextIdx:a,wizard:i})=>$t.createElement($t.Fragment,null,$t.createElement(E,{label:"Basic information",wizard:i,order:a(),render:({innerRef:a})=>$t.createElement(Gn,{ref:a,app:e,formik:t,isNew:r,functionDef:n})}),$t.createElement(E,{label:"Execution Role",wizard:i,order:a(),render:({innerRef:e})=>$t.createElement(Sn,{ref:e,formik:t,isNew:r,functionDef:n})}),$t.createElement(E,{label:"Environment",wizard:i,order:a(),render:({innerRef:e})=>$t.createElement(In,{ref:e,formik:t,isNew:r,functionDef:n})}),$t.createElement(E,{label:"Tags",wizard:i,order:a(),render:({innerRef:e})=>$t.createElement(An,{ref:e,formik:t,isNew:r,functionDef:n})}),$t.createElement(E,{label:"Settings",wizard:i,order:a(),render:({innerRef:e})=>$t.createElement(xn,{ref:e,formik:t,isNew:r,functionDef:n})}),$t.createElement(E,{label:"Network",wizard:i,order:a(),render:({innerRef:a})=>$t.createElement(zn,{ref:a,app:e,formik:t,isNew:r})}),$t.createElement(E,{label:"Debugging and Error Handling",wizard:i,order:a(),render:({innerRef:e})=>$t.createElement(Tn,{ref:e,formik:t,isNew:r,functionDef:n})}))})}};let Dn=Bn;Dn.defaultProps={closeModal:C,dismissModal:C};class $n extends $t.Component{constructor(e){super(e),this.editFunction=()=>{const{functionDef:e}=this.props,{application:t}=this.state;Dn.show({app:t,functionDef:e})},this.deleteFunction=()=>{const{app:e,functionDef:t,functionFromParams:a}=this.props,n={application:e,title:"Deleting "+a.functionName},r={cloudProvider:t.cloudProvider,functionName:t.functionName,region:t.region,credentials:t.credentials};k.confirm({header:`Really delete ${a.functionName} in ${a.region}: ${a.account}?`,buttonText:`Delete ${a.functionName}`,account:a.account,taskMonitorConfig:n,submitMethod:()=>y.deleteFunction(r,e)})},this.entityTagUpdate=()=>{this.props.app.functions.refresh()},this.state={application:e.app}}componentDidMount(){const{app:e,functionDef:t}=this.props;let a;const n=t.functionName.split("-")[0];n===e.name?a=e:S.getApplication(n).then((e=>{this.setState({application:e})})).catch((()=>{this.setState({application:this.props.app})})),this.setState({application:a})}render(){const{app:e,functionDef:t}=this.props,{application:n}=this.state;return $t.createElement("div",{style:{display:"inline-block"}},$t.createElement($a,{className:"dropdown",id:"function-actions-dropdown"},$t.createElement($a.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},$t.createElement("span",null,"Function Actions")),$t.createElement($a.Menu,{className:"dropdown-menu"},$t.createElement("li",{className:n?"":"disabled"},$t.createElement("a",{className:"clickable",onClick:this.editFunction},"Edit Function")),t.functionName&&$t.createElement("li",null,$t.createElement("a",{className:"clickable",onClick:this.deleteFunction},"Delete Function")),a&&a.feature.entityTags&&$t.createElement(N,{component:t,application:e,entityType:"function",onUpdate:this.entityTagUpdate}))))}}class Fn{constructor(){this.policyTypes=[]}registerPolicyType(e){this.policyTypes.push(e)}getPolicyConfig(e){return this.policyTypes.find((t=>t.type===e))}}const Mn=new Fn;const Rn={bindings:{policy:"<",serverGroup:"<",application:"<"},controller:class{$onInit(){const e=Mn.getPolicyConfig(this.policy.policyType);this.templateUrl=e?e.summaryTemplateUrl:"amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html"}},template:'<div ng-include src="$ctrl.templateUrl"></div>'},Ln="spinnaker.amazon.scalingPolicy.details.summary.component";t(Ln,[]).component("scalingPolicySummary",Rn),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.template.html",'<alarm-based-summary\n policy="$ctrl.policy"\n server-group="$ctrl.serverGroup"\n application="$ctrl.application"\n></alarm-based-summary>\n')}]);class On extends G{constructor(){super(...arguments),this.$injectorProxy={},this.ScalingPolicySummary=Va("scalingPolicySummary",Rn,this.$injectorProxy)}initialize(e){const t=e,a=this.$injectorProxy;Object.keys(e).filter((e=>"function"==typeof t[e])).forEach((e=>a[e]=t[e].bind(t)))}}const Un=new On;class Vn extends G{get awsInstanceTypeService(){return this.$injector.get("awsInstanceTypeService")}get awsServerGroupCommandBuilder(){return this.$injector.get("awsServerGroupCommandBuilder")}get awsServerGroupConfigurationService(){return this.$injector.get("awsServerGroupConfigurationService")}get awsServerGroupTransformer(){return this.$injector.get("awsServerGroupTransformer")}get functionReader(){return this.$injector.get("functionReader")}get evaluateCloudFormationChangeSetExecutionService(){return this.$injector.get("evaluateCloudFormationChangeSetExecutionService")}initialize(e){this.$injector=e}}const qn=new Vn;var jn=Object.defineProperty,Hn=Object.getOwnPropertyDescriptor;let Wn=class extends $t.Component{constructor(e){super(e),this.destroy$=new ya,this.state={loading:!0}}extractFunction(){const{app:e,functionObj:t}=this.props;e.functions.data.find((e=>e.functionName===t.functionName&&e.region===t.region&&e.account===t.account))?ba(qn.functionReader.getFunctionDetails("aws",t.account,t.region,t.functionName)).pipe(xa(this.destroy$)).subscribe((e=>{e.length&&this.setState({functionDef:e[0],loading:!1})})):this.setState({functionDef:{},loading:!1})}componentDidMount(){const{app:e}=this.props,t=e.functions;ba(t.ready()).pipe(xa(this.destroy$)).subscribe((()=>{const e=t.onRefresh(null,(()=>this.extractFunction()));this.setState({dataSourceUnsubscribe:e}),this.extractFunction()}))}componentWillUnmount(){this.state.dataSourceUnsubscribe&&this.state.dataSourceUnsubscribe(),this.destroy$.next()}render(){const{app:e}=this.props,{loading:t,functionDef:a}=this.state;if(t)return $t.createElement(T,{loading:t});const n=$t.createElement("dl",{className:"horizontal-when-filters-collapsed dl-horizontal dl-narrow"},$t.createElement("dt",null,"Last Modified "),$t.createElement("dd",null,a.lastModified),$t.createElement("dt",null,"In"),$t.createElement("dd",null,$t.createElement(I,{account:a.account})," ",a.region),$t.createElement("dt",null,"VPC"),$t.createElement("dd",null,a.vpcConfig?a.vpcConfig.vpcId:"Default"),$t.createElement("dt",null,"Function ARN"),$t.createElement("dd",null,a.functionArn),$t.createElement("dt",null,"Revision ID"),$t.createElement("dd",null,a.revisionId),$t.createElement("dt",null,"Version"),$t.createElement("dd",null,a.version),$t.createElement("dt",null,"Event Source"),$t.createElement("dd",null,a.eventSourceMappings&&0!==a.eventSourceMappings.length?a.eventSourceMappings:"None")),r=$t.createElement(A,{heading:"Function Details"},n);return $t.createElement(T,{loading:this.state.loading},Rt(this.state.functionDef)?"Function not found.":$t.createElement(T.Header,{icon:$t.createElement("i",{className:"fa fa-xs fa-fw fa-asterisk"}),name:this.state.functionDef.functionName},$t.createElement("div",{className:"actions"},$t.createElement($n,{app:e,functionDef:a,functionFromParams:{account:this.state.functionDef.account,region:this.state.functionDef.region,functionName:this.state.functionDef.functionName}}))),Rt(this.state.functionDef)?"":r)}};Wn=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?Hn(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&jn(t,a,i),i})([x("function.details","aws")],Wn);t("spinnaker.amazon.function",[]);const Zn={"aws.associateElasticIp.elasticIp":"<p>(Optional) <b>Elastic IP</b> is an IP address that Spinnaker will associate with this cluster.</p>\n <p>If specified, this elastic IP must exist and not already be attached to an instance or cluster.</p>\n <p>If left blank, Spinnaker will make a selection from the list of available elastic IPs in the provided account and region.</p>","aws.associateElasticIp.type":"<p><b>Type</b> of elastic IP to associate:'\n <ul>\n <li><b>standard</b> is usable in EC2 Classic</li>\n <li><b>vpc</b> is usable in VPC</li>\n </ul>","aws.serverGroup.subnet":"The subnet selection determines the VPC in which your server group will run. Options vary by account and region; the most common ones are:\n <ul>\n <li><b>None (EC2 Classic)</b>: instances will not run in a VPC</li>\n <li><b>internal</b> instances will be restricted to internal clients (i.e. require VPN access)</li>\n <li><b>external</b> instances will be publicly accessible and running in VPC</li>\n </ul>","aws.loadBalancer.subnet":"The subnet selection determines the VPC in which your load balancer will run.<br/>\n This also restricts the server groups which can be serviced by the load balancer.\n Options vary by account and region; the most common ones are:\n <ul>\n <li><b>None (EC2 Classic)</b>: the load balancer will not run in a VPC</li>\n <li><b>internal</b> access to the load balancer will be restricted to internal clients (i.e. require VPN access)</li>\n <li><b>external</b> the load balancer will be publicly accessible and running in VPC</li>\n </ul>","aws.loadBalancer.detail":'<p>(Optional) <b>Detail</b> is a string of free-form alphanumeric characters; by convention, we recommend using "frontend".</p>\n <p>However, if your stack name needs to be longer (load balancer names are limited to 32 characters), consider changing it to "elb", or omit it altogether.</p>',"aws.loadBalancer.internal":"Controls the load balancer scheme, <strong>not</strong> the subnet. By default, load balancers are created with a DNS name that resolves to public IP addresses. Specify internal to create a load balancer with a DNS name that resolves to private IP addresses.","aws.loadBalancer.stack":"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","aws.loadBalancer.name":"<p>The load balancer name is formed by combining the application name, the <b>Stack</b> field, and the <b>Detail</b> field.</p>","aws.loadBalancer.targetGroups":"Add a target group if you want to associate this with an Application Load Balancer (ALB) or Network Load Balancer (NLB)","aws.loadBalancer.loadBalancers":"Add a load balancer directly if you created a Classic Load Balancer (a classic load balancer does not have target groups)","aws.loadBalancer.ruleCondition.host":"<p>You can specify a single host name (for example, <em>my.example.com</em>). A host name is case insensitive, can be up to 128 characters in length, and can contain any of the following characters. Note that you can include up to three wildcard characters.</p>\n <ul>\n <li>A-Z, a-z, 0-9</li>\n <li>- .</li>\n <li>* (matches 0 or more characters)</li>\n <li>? (matches exactly 1 character)</li>\n </ul>\n <p>Note that <strong>*.example.com</strong> will match <strong>test.example.com</strong> but won't match <strong>example.com</strong>.</p>","aws.loadBalancer.ruleCondition.path":"<p>You can specify a single path pattern (for example, <em>/img/*</em>). A path pattern is case sensitive, can be up to 128 characters in length, and can contain any of the following characters. Note that you can include up to three wildcard characters.</p>\n <ul>\n <li>A-Z, a-z, 0-9</li>\n <li>_ - . $ / ~ \" ' @ : +</li>\n <li>& (using &amp;amp;)</li>\n <li>* (matches 0 or more characters)</li>\n <li>? (matches exactly 1 character)</li>\n </ul>\n <p>Note that the path pattern is used to route requests but does not alter them. For example, if a rule has a path pattern of <em>/img/*</em>, the rule would forward a request for <em>/img/picture.jpg</em> to the specified target group as a request for <em>/img/picture.jpg</em>.</p>","aws.loadBalancer.oidcAuthentication":"Authentication requires a configured OIDC client.","aws.serverGroup.stack":"(Optional) <b>Stack</b> is one of the core naming components of a cluster, used to create vertical stacks of dependent services for integration testing.","aws.serverGroup.detail":"(Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables.","aws.serverGroup.imageName":"(Required) <b>Image</b> is the deployable Amazon Machine Image. Images are restricted to the account and region selected.","aws.serverGroup.spotMaxPrice":"The maximum price per unit hour to pay for a Spot instance. By default (empty), Amazon EC2 Auto Scaling uses the On-Demand price as the maximum Spot price","aws.serverGroup.spotAllocationStrategy":"<p>Indicates how to allocate instances across Spot Instance pools.</p>\n <ul>\n <li><b>capacity-optimized (recommended)</b>: Instances launched using Spot pools that are optimally chosen based on the available Spot capacity.</li>\n <li><b>capacity-optimized-prioritized</b>: Instances launched using the priority on a best-effort basis to determine which launch template override to use first, but AWS optimizes for capacity first.</li>\n <li><b>lowest-price</b>: Instances launched using Spot pools with the lowest price, and evenly allocated across the number of Spot pools specified</li>\n </ul>","aws.serverGroup.spotInstancePoolCount":"Number of lowest priced Spot Instance pools to diversify across. Only applicable for strategy 'lowest-price'.","aws.serverGroup.odAllocationStrategy":"The only strategy / default is 'prioritized'. The order of instance types in the list of launch template overrides is used to determine which instance type to use first when fulfilling On-Demand capacity.","aws.serverGroup.odBase":"Minimum amount of the Auto Scaling Group's capacity that must be fulfilled by On-Demand Instances. This base portion is provisioned first as the group scales.","aws.serverGroup.odPercentAboveBase":"Percentages of On-Demand and Spot instances for additional capacity beyond OnDemandBaseCapacity.","aws.serverGroup.instanceTypeWeight":"The number of capacity units gives the instance type a proportional weight to other instance types. When specified, weights count towards desired capacity.","aws.serverGroup.instanceTypes":"Specify up to 20 instance types.","aws.serverGroup.multipleInstanceTypes":"Instance types a server group can launch, first (highest priority) to last (lowest priority).","aws.serverGroup.unlimitedCpuCredits":"<p>CPU credits can be configured with 2 modes:</p><br/>\n <ul>\n <li><b>Unlimited (i.e. Unlimited On)</b>: Can sustain high CPU utilization for any period of time whenever required.<br/>\n If the average CPU usage over a rolling 24-hour period exceeds the baseline, charges for surplus credits will apply.</li>\n <li><b>Standard (i.e. Unlimited Off)</b>: <b>Default mode in Spinnaker.</b> Suited to workloads with an average CPU utilization that is consistently below the baseline CPU utilization of the instance.<br/>\n To burst above the baseline, the instance spends credits that it has accrued in its CPU credit balance.</li>\n </ul>","aws.serverGroup.capacityRebalance":"Enabling <b>Capacity Rebalance</b> allows EC2 Auto Scaling to proactively replace Spot Instances that have received a rebalance recommendation, <b>before</b> it is interrupted by AWS EC2.","aws.serverGroup.legacyUdf":"<p>(Optional) <b>User Data Format</b> allows overriding of the format used when generating user data during deployment. The default format used is configured\n in the application's attributes, editable via the 'Config' tab.</p>\n <p><b>Default</b> will use the value from the application's configuration.</p>\n <p><b>Modern</b> will use the modern template.</p>\n <p><b>Legacy</b> will use the legacy (<b>deprecated</b>) template.</p>\n <p>This option is intended to allow testing migration from legacy to modern before configuring it for the entire application. If unsure, pick <b>Default</b>.</p>","aws.serverGroup.base64UserData":"(Optional) <b>UserData</b> is a base64 encoded string.","aws.serverGroup.enabledMetrics":"(Optional) <b>Enabled Metrics</b> are the Auto Scaling Group metrics to enable on this group. Existing metrics are not modified.","aws.serverGroup.imdsv2":"(Recommended) <b>IMDSv2</b> helps mitigate AWS credential theft from the exploitation of SSRF vulnerabilities in web applications. All modern AWS SDKs support IMDSv2 and it should not be disabled unless you're using a legacy SDK.","aws.serverGroup.instanceMonitoring":"(Optional) <b>Instance Monitoring</b> whether to enable detailed monitoring of instances. Group metrics must be disabled to update an ASG with Instance Monitoring set to false.","aws.serverGroup.tags":"(Optional) <b>Tags</b> are propagated to the instances in this cluster.","aws.serverGroup.allImages":"Search for an image that does not match the name of your application.","aws.serverGroup.filterImages":"Select from a pre-filtered list of images matching the name of your application.","aws.serverGroup.traffic":'<p>Enables the "AddToLoadBalancer" scaling process, which is used by Spinnaker and discovery services to determine if the server group is enabled.</p>\n <p>Will be automatically enabled when any non "custom" deployment strategy is selected.</p>',"aws.securityGroup.vpc":'\n <p>The VPC to which this {{firewall}} will apply.</p>\n <p>If you wish to use VPC but are unsure which VPC to use, the most common one is "Main".</p>\n <p>If you do not wish to use VPC, select "None".</p>',"aws.securityGroup.name":"<p>The {{firewall}} name is formed by combining the application name, the <b>Stack</b> field, and the <b>Detail</b> field.</p>","aws.securityGroup.cross.account.ingress.help":"<p>Accounts that are excluded will not show up in this list</p>","aws.scalingPolicy.search.restricted":'<p>Resets dimensions to "AutoScalingGroupName: {name of the ASG}" and provides\n a simpler, combined input for the namespace and metric name fields.</p>',"aws.scalingPolicy.search.all":"\n <p>Allows you to edit the dimensions and namespace to find a specific metric for this alarm.</p>","aws.blockDeviceMappings.useSource":'\n <p>Spinnaker will use the block device mappings of the existing server group when deploying a new server group.</p>\n <p>In the event that there is no existing server group, the\n <a target="_blank" href="https://github.com/spinnaker/clouddriver/blob/master/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/InstanceTypeUtils.java">defaults</a>\n for the selected instance type will be used.</p>',"aws.blockDeviceMappings.useAMI":"<p>Spinnaker will use the block device mappings from the selected AMI when deploying a new server group.</p>","aws.blockDeviceMappings.useDefaults":'<p>Spinnaker will use the <a target="_blank" href="https://github.com/spinnaker/clouddriver/blob/master/clouddriver-aws/src/main/groovy/com/netflix/spinnaker/clouddriver/aws/deploy/InstanceTypeUtils.java">default block device mappings</a> for the selected instance type when deploying a new server group.</p>',"aws.targetGroup.protocol":"The protocol to use for routing traffic to the targets. Cannot be edited after being saved; if you want to use a different protocol, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.targetType":"Determines how targets are specified. Only set to ip if you need to attach individual ips. Cannot be edited after being saved; if you want to use a different target type, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.port":"The port on which the targets receive traffic. Cannot be edited after being saved; if you want to use a different port, create a new target group, save the load balancer, move your targets, and then delete this target group.","aws.targetGroup.attributes.deregistrationDelay":"The amount of time for the load balancer to wait before changing the state of a deregistering target from draining to unused. The range is 0-3600 seconds. The default value is 300 seconds.","aws.targetGroup.attributes.stickinessEnabled":" Indicates whether sticky sessions are enabled.","aws.targetGroup.attributes.deregistrationDelayConnectionTermination":"If enabled, your Network Load Balancer will terminate active connections when deregistration delay is reached.","aws.targetGroup.attributes.preserveClientIp":"If enabled, your Network Load Balancer will preserve client IP addresses to the target.","aws.targetGroup.attributes.stickinessType":"The type of sticky sessions. The only current possible value is <code>lb_cookie</code>.","aws.targetGroup.attributes.stickinessDuration":"The time period, in seconds, during which requests from a client should be routed to the same target. After this time period expires, the load balancer-generated cookie is considered stale. The range is 1 second to 1 week (604800 seconds). The default value is 1 day (86400 seconds).","aws.targetGroup.attributes.healthCheckPort.trafficPort":"The port the load balancer uses when performing health checks on targets. The default is <b>traffic-port</b>, which is the port on which each target receives traffic from the load balancer.","aws.targetGroup.healthCheckProtocol":"TCP health checks only support 10s and 30s intervals","aws.targetGroup.healthCheckTimeout":"Target groups with TCP or TLS protocol must have a 6s timeout for HTTP health checks or a 10s timeout for HTTPS/TLS health checks.","aws.targetGroup.nlbHealthcheckThreshold":"The healthy and unhealthy threshold for NLBs must be equal. This represents the number of successful and failed healthchecks required for healthy and unhealthy targets, respectively.","aws.serverGroup.capacityConstraint":"\n <p>Ensures that the capacity of this server group has not changed in the background (i.e. due to autoscaling activity).</p>\n <p>If the capacity has changed, this resize operation will be rejected.</p>","aws.tagImage.consideredStages":"Limit which previous stages will be considered when locating AMI's to tag. If left unchecked, AMI's generated by any upstream stage will be tagged.","aws.loadBalancer.redirect.host":"The hostname. This component is not percent-encoded. The hostname can contain <code>#{host}</code>.","aws.loadBalancer.redirect.path":'The absolute path, starting with the leading "/". This component is not percent-encoded. The path can contain <code>#{host}</code>, <code>#{path}</code>, and <code>#{port}</code>.',"aws.loadBalancer.redirect.port":"The port. You can specify a value from 1 to 65535 or <code>#{port}</code>.","aws.loadBalancer.redirect.protocol":"The protocol. You can specify HTTP, HTTPS, or <code>#{protocol}</code>. You can redirect HTTP to HTTP, HTTP to HTTPS, and HTTPS to HTTPS. You cannot redirect HTTPS to HTTP.","aws.loadBalancer.redirect.query":'The query parameters, URL-encoded when necessary, but not percent-encoded. Do not include the leading "?", as it is automatically added. You can specify any of the reserved keywords.',"aws.loadBalancer.redirect.statusCode":"The HTTP redirect code. The redirect is either permanent (HTTP 301) or temporary (HTTP 302).","aws.loadBalancer.redirect":'<p>A URI consists of the following components: protocol://hostname:port/path?query. You must modify at least one of the following components to avoid a redirect loop: protocol, hostname, port, or path. Any components that you do not modify retain their original values.\n\n <p>You can reuse URI components using the following reserved keywords:\n\n <ul><li>#{protocol}\n <li>#{host}\n <li>#{port}\n <li>#{path} (the leading "/" is removed)\n <li>#{query}\n </ul>\n <p>For example, you can change the path to "/new/#{path}", the hostname to "example.#{host}", or the query to "#{query}&value=xyz".',"aws.cloudformation.source":"\n <p>Where the template file content is read from.</p>\n <p>\n <b>text:</b> The template is supplied statically to the pipeline from the below text-box.\n </p>\n <p>\n <b>artifact:</b> The template is read from an artifact supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>\n ","aws.cloudformation.expectedArtifact":"The artifact that is to be applied to this stage. The artifact should represent a valid cloudformation template.","aws.function.name":"Enter a name that describes the purpose of your function. Function name will be prefixed with the application name.","aws.function.runtime":"Choose the language to use to write your function","aws.function.s3key":"The Amazon S3 key of the deployment package","aws.function.handler":"The name of the method within your code that Lambda calls to execute your function. The format includes the file name. It can also include namespaces and other qualifiers, depending on the runtime.","aws.function.s3bucket":"An Amazon S3 bucket in the same AWS Region as your function. The bucket can be in a different AWS account.","aws.function.execution.role":"Lambda will create an execution role with permission to upload logs to Amazon CloudWatch Logs. You can also choose an existing role that defines the permissions of your function.","aws.function.env.vars":"You can define environment variables as key-value pairs that are accessible from your function code. These are useful to store configuration settings without the need to change function code","aws.function.tags":"You can use tags to group and filter your functions. A tag consists of a case-sensitive key-value pair","aws.functionBasicSettings.memorySize":"Your function is allocated CPU proportional to the memory configured.","aws.functionBasicSettings.timeout":"The amount of time that Lambda allows a function to run before stopping it. The default is 3 seconds. The maximum allowed value is 900 seconds.","aws.function.publish":"Set to true to publish the first version of the function during creation.","aws.function.deadletterqueue":"A dead letter queue configuration that specifies the queue or topic where Lambda sends asynchronous events when they fail processing. (SNS or SQS)","aws.function.tracingConfig.mode":"The function's AWS X-Ray tracing configuration.","aws.function.kmsKeyArn":"The ARN of the AWS Key Management Service (AWS KMS) key that's used to encrypt your function's environment variables. If it's not provided, AWS Lambda uses a default service key.","aws.cloudformation.changeSet.options":"<p>Action to take when the created ChangeSet contains a replacement.</p>\n <p>\n <b>ask:</b> Execution will be put on hold asking for user feedback.\n </p>\n <p>\n <b>skip it:</b> ChangeSet will not be executed and stage will continue.\n </p>\n <p>\n <b>execute it</b> ChangeSet will be executed.\n </p>\n <p>\n <b>fail stage</b> ChangeSet will not be executed and the stage will fail.\n </p>"};Object.keys(Zn).forEach((e=>P.register(e,Zn[e])));class _n{findImages(e){return!e.q||e.q.length<3?qa.when([{message:"Please enter at least 3 characters...",disabled:!0}]):z("/images/find").query(e).get().catch((()=>[]))}getImage(e,t,a){return z("/images").path(a,t,e).query({provider:"aws"}).get().then((e=>e&&e.length?e[0]:null)).catch((()=>null))}}t("spinnaker.amazon.instanceType.service",[]).factory("awsInstanceTypeService",["$q",function(e){const t=[{type:"general",label:"General Purpose",families:[{type:"m5",description:"m5 instances provide a balance of compute, memory, and network resources. They are a good choice for most applications.",instanceTypes:[{name:"m5.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"m5.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"m5.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]},{type:"t2",description:"t2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t2.small",label:"Small",cpu:1,memory:2,storage:{type:"EBS"},costFactor:1},{name:"t2.medium",label:"Medium",cpu:2,memory:4,storage:{type:"EBS"},costFactor:1},{name:"t2.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"t2.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"t2.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]},{type:"t3",description:"t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t3.small",label:"Small",cpu:2,memory:2,storage:{type:"EBS"},costFactor:1},{name:"t3.medium",label:"Medium",cpu:2,memory:4,storage:{type:"EBS"},costFactor:1},{name:"t3.large",label:"Large",cpu:2,memory:8,storage:{type:"EBS"},costFactor:2},{name:"t3.xlarge",label:"XLarge",cpu:4,memory:16,storage:{type:"EBS"},costFactor:3},{name:"t3.2xlarge",label:"2XLarge",cpu:8,memory:32,storage:{type:"EBS"},costFactor:4}]}],icon:"hdd"},{type:"memory",label:"High Memory",families:[{type:"r5",description:"r5 instances are optimized for memory-intensive applications and have the lowest cost per GiB of RAM among Amazon EC2 instance types.",instanceTypes:[{name:"r5.large",label:"Large",cpu:2,memory:16,storage:{type:"EBS"},costFactor:1},{name:"r5.xlarge",label:"XLarge",cpu:4,memory:32,storage:{type:"EBS"},costFactor:2},{name:"r5.2xlarge",label:"2XLarge",cpu:8,memory:64,storage:{type:"EBS"},costFactor:2},{name:"r5.4xlarge",label:"4XLarge",cpu:16,memory:128,storage:{type:"EBS"},costFactor:3}]}],icon:"hdd"},{type:"micro",label:"Micro Utility",families:[{type:"t2",description:"t2 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t2.nano",label:"Nano",cpu:1,memory:.5,storage:{type:"EBS"},costFactor:1},{name:"t2.micro",label:"Micro",cpu:1,memory:1,storage:{type:"EBS"},costFactor:1},{name:"t2.small",label:"Small",cpu:1,memory:2,storage:{type:"EBS"},costFactor:1}]},{type:"t3",description:"t3 instances are a good choice for workloads that don’t use the full CPU often or consistently, but occasionally need to burst (e.g. web servers, developer environments and small databases).",instanceTypes:[{name:"t3.nano",label:"Nano",cpu:2,memory:.5,storage:{type:"EBS"},costFactor:1},{name:"t3.micro",label:"Micro",cpu:2,memory:1,storage:{type:"EBS"},costFactor:1},{name:"t3.small",label:"Small",cpu:2,memory:2,storage:{type:"EBS"},costFactor:1}]}],icon:"hdd"},{type:"custom",label:"Custom Type",families:[],icon:"asterisk"}],a=t.filter((({type:e})=>!Mt.get(fn,"instanceTypes.exclude.categories",[]).includes(e))).map((e=>Object.assign({},e,{families:e.families.filter((({type:e})=>!Mt.get(fn,"instanceTypes.exclude.families",[]).includes(e)))})));const n=["xlarge","large","medium","small","micro","nano"];function r(e,t){const a=e.split("."),r=t.split("."),[i,s=""]=a,[l,o=""]=r;if(i!==l)return i>l?1:i<l?-1:0;const c=n.findIndex((e=>s.endsWith(e))),d=n.findIndex((e=>o.endsWith(e)));if(-1===c||-1===d)return 0;if(0===c&&0===d){const e=parseInt(s.replace("xlarge",""))||0,t=parseInt(o.replace("xlarge",""))||0;return t<e?1:t>e?-1:0}return c>d?-1:c<d?1:0}const i={paravirtual:["c1","c3","hi1","hs1","m1","m2","m3","t1"],hvm:["c3","c4","d2","i2","g2","m3","m4","m5","p2","r3","r4","r5","t2","x1"],vpcOnly:["c4","m4","m5","r4","r5","t2","x1"],ebsOptimized:["c4","d2","f1","g3","i3","m4","m5","p2","r4","r5","x1"],burstablePerf:["t2","t3","t3a","t4g"]};return{getCategories:function(){return e.when(a)},getAvailableTypesForRegions:function(e,t){let a=[];return(t=t||[])&&t.length&&(a=Mt.map(e[t[0]],"name")),t.forEach((function(t){e[t]&&(a=Mt.intersection(a,Mt.map(e[t],"name")))})),a.sort(r)},getAllTypesByRegion:function(){return z("/instanceTypes").get().then((function(e){return Mt.chain(e).map((function(e){return{region:e.region,account:e.account,name:e.name,key:[e.region,e.account,e.name].join(":")}})).uniqBy("key").groupBy("region").value()}))},filterInstanceTypes:function(e,t,a){return e.filter((e=>{if("*"===t)return!0;const[n]=e.split(".");return!(!a&&i.vpcOnly.includes(n))&&(!i.paravirtual.includes(n)&&"hvm"===t||i[t].includes(n))}))},isEbsOptimized:function(e){if(!e)return!1;const[t]=e.split(".");return i.ebsOptimized.includes(t)},isBurstingSupported:function(e){if(!e)return!1;const[t]=e.split(".");return i.burstablePerf.includes(t)},isInstanceTypeInCategory:function(e,a){if(!e||!a)return!1;if("custom"===a)return!0;const[n]=e.split("."),r=Mt.find(t,{type:a}),i=r&&Mt.find(r.families,{type:n});return i&&i.instanceTypes.map((e=>e.name)).includes(e)}}}]);const Kn=({account:e,availabilityZone:t,instanceType:a,capacityType:n,launchTime:r,provider:i,region:s,serverGroup:l,showInstanceType:o})=>$t.createElement($t.Fragment,null,$t.createElement(B,{label:"Launched",value:r?D(r):"Unknown"}),$t.createElement(B,{label:"In",value:$t.createElement("div",null,$t.createElement(I,{account:e}),t||"Unknown")}),o&&$t.createElement(B,{label:"Type",value:a||"Unknown"}),o&&n&&$t.createElement(B,{label:"Capacity Type",value:n||"Unknown"}),l&&$t.createElement(B,{label:"Server Group",value:$t.createElement("div",null,$t.createElement(Za,null,$t.createElement(Ha,{to:"^.serverGroup",params:{region:s,accountId:e,serverGroup:l,provider:i}},$t.createElement("a",null,l))))}));function Yn(e){const{vpcId:t}=e,a=$((async()=>{const t=await Pn.getVpcName(e.vpcId);return t?`${t} (${e.vpcId})`:`(${e.vpcId})`}),"None (EC2 Classic)",[t]),n=t?a.result:"None (EC2 Classic)";return $t.createElement("span",{className:"vpc-tag"},n)}t("spinnaker.application.amazonInstanceInformation.component",[]).component("amazonInstanceInformation",ja(M((({instance:e})=>{const{imageId:t,serverGroup:a,subnetId:n,vpcId:r}=e;return $t.createElement(A,{heading:"Instance Information",defaultExpanded:!0},$t.createElement("dl",{className:"dl-horizontal dl-narrow"},$t.createElement(Kn,{account:e.account,availabilityZone:e.availabilityZone,instanceType:e.instanceType,capacityType:e.capacityType,launchTime:e.launchTime,provider:e.provider,region:e.region,serverGroup:e.serverGroup,showInstanceType:!0}),a&&$t.createElement(B,{label:"VPC",value:$t.createElement(Yn,{vpcId:r})}),n&&$t.createElement(B,{label:"Subnet",value:$t.createElement(F,{subnetId:n})}),t&&$t.createElement(B,{label:"Image ID",value:t})))}),"amazonInstanceInformation"),["instance"]));class Xn extends R{static deregisterInstancesFromTargetGroup(e,t,a){const n=super.buildMultiInstanceJob(e,"deregisterInstancesFromLoadBalancer");n.forEach((e=>e.targetGroupNames=a));const r=super.buildMultiInstanceDescriptor(n,"Deregister",`from ${a.join(" and ")}`);return L.executeTask({job:n,application:t,description:r})}static deregisterInstanceFromTargetGroup(e,t,a={}){return a.type="deregisterInstancesFromLoadBalancer",a.instanceIds=[e.id],a.targetGroupNames=e.targetGroups,a.region=e.region,a.credentials=e.account,a.cloudProvider=e.cloudProvider,L.executeTask({job:[a],application:t,description:`Deregister instance: ${e.id}`})}static registerInstancesWithTargetGroup(e,t,a){const n=super.buildMultiInstanceJob(e,"registerInstancesWithLoadBalancer");n.forEach((e=>e.targetGroupNames=a));const r=super.buildMultiInstanceDescriptor(n,"Register",`with ${a.join(" and ")}`);return L.executeTask({job:n,application:t,description:r})}static registerInstanceWithTargetGroup(e,t,a={}){return a.type="registerInstancesWithLoadBalancer",a.instanceIds=[e.id],a.targetGroupNames=e.targetGroups,a.region=e.region,a.credentials=e.account,a.cloudProvider=e.cloudProvider,L.executeTask({job:[a],application:t,description:`Register instance: ${e.id}`})}}const Qn=e=>{const t=e.map((e=>e.targetGroups));return Vt(t)},Jn=(e,t,a)=>{e.forEach((e=>{"TargetGroup"===e.type&&e.targetGroups.forEach((e=>{var n,r,i;const s=null!=(n=t.find((t=>t.name===e.name&&t.account===a)))?n:{},l="traffic-port"===s.healthCheckPort||qt(s.healthCheckPort)?s.port:s.healthCheckPort;e.healthCheckProtocol=null==(r=s.healthCheckProtocol)?void 0:r.toLowerCase(),e.healthCheckPath=`:${l}${null!=(i=s.healthCheckPath)?i:""}`}))}))};t("spinnaker.amazon.vpc.tag.directive",[]).directive("vpcTag",(function(){return{restrict:"E",scope:{vpcId:"="},template:'<span class="vpc-tag">{{vpcLabel}}</span>',link:function(e){e.$watch("vpcId",(function(){e.vpcId?Pn.getVpcName(e.vpcId).then((function(t){e.vpcLabel="("+e.vpcId+")",t&&(e.vpcLabel=t+" "+e.vpcLabel)})):e.vpcLabel="None (EC2 Classic)"}),!0)}}}));t("spinnaker.amazon.instance.details.controller",[_a,Ka,"spinnaker.amazon.vpc.tag.directive"]).controller("awsInstanceDetailsCtrl",["$scope","$state","instance","app","moniker","environment","$q","overrides",function(e,t,n,r,i,s,l,o){function c(){const t={};let a,i,s,c,p,u,m;return r.serverGroups?(r.serverGroups.data.some((function(e){return e.instances.some((function(r){if(r.id===n.instanceId)return a=r,i=e.loadBalancers,s=e.targetGroups,c=e.account,p=e.region,u=e.vpcId,m=e.isDisabled,t.serverGroup=e.name,t.vpcId=e.vpcId,!0}))})),a||(r.loadBalancers.data.some((function(e){return e.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))||e.targetGroups.some((function(t){return t.instances.some((function(r){if(r.id===n.instanceId)return a=r,s=[t.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))})),a||r.loadBalancers.data.some((function(e){return e.serverGroups.some((function(t){return!!t.isDisabled&&t.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))||e.targetGroups.some((function(t){t.serverGroups.some((function(t){return!!t.isDisabled&&t.instances.some((function(t){if(t.id===n.instanceId)return a=t,i=[e.name],c=e.account,p=e.region,u=e.vpcId,!0}))}))}))})))):(a={id:n.instanceId},i=[],s=[],c=n.account,p=n.region),a&&c&&p?(a.account=c,t.account=c,t.region=p,V.addExtraDataToLatest("instances",t),q.getInstanceDetails(c,p,n.instanceId).then((t=>{if(!e.$$destroyed){if(e.state.loading=!1,function(t,a){r.isStandalone&&(t.health=a.health),t.health=t.health||[];const n=t.health.filter((function(e){return"Amazon"!==e.type||"Unknown"!==e.state}));if(!r.isStandalone){const e=Qn(r.loadBalancers.data.filter((function(e){return"aws"===e.cloudProvider})));Jn(n,e,t.account)}a.health&&n.forEach((function(e){const t=a.health.filter((function(t){return t.type===e.type}));t.length&&Mt.defaults(e,t[0])})),e.healthMetrics=n}(a,t),e.instance=Mt.defaults(t,a),e.instance.account=c,e.instance.region=p,e.instance.vpcId=u,e.instance.serverGroupDisabled=m,e.instance.loadBalancers=i,e.instance.targetGroups=s,e.instance.networkInterfaces){e.instance.ipv6Addresses=Mt.flatMap(e.instance.networkInterfaces,(t=>t.ipv6Addresses.map((t=>({ip:t.ipv6Address,url:`http://${t.ipv6Address}:${e.state.instancePort}`})))));const t=e.instance.networkInterfaces.filter((e=>!1===e.attachment.deleteOnTermination));t.length&&(e.instance.permanentIps=t.map((e=>e.privateIpAddress)))}e.baseIpAddress=t.publicDnsName||t.privateIpAddress,o.instanceDetailsLoaded&&o.instanceDetailsLoaded()}}),d)):(a||(e.instanceIdNotFound=n.instanceId,e.state.loading=!1),l.when(null))}function d(){e.$$destroyed||(r.isStandalone?(e.state.loading=!1,e.instanceIdNotFound=n.instanceId,e.state.notFoundStandalone=!0,V.removeLastItem("instances")):t.go("^",{allowModalToStayOpen:!0},{location:"replace"}))}e.detailsTemplateUrl=O.getValue("aws","instance.detailsTemplateUrl"),e.state={loading:!0,standalone:r.isStandalone,instancePort:Mt.get(r,"attributes.instancePort")||a.defaultInstancePort||80},e.application=r,e.moniker=i,e.environment=s,e.securityGroupsLabel=U.get("Firewalls"),this.canDeregisterFromLoadBalancer=function(){return(e.instance.health||[]).some((function(e){return"LoadBalancer"===e.type}))},this.canRegisterWithLoadBalancer=function(){const t=e.instance,a=t.health||[];if(!t.loadBalancers||!t.loadBalancers.length)return!1;const n=a.some((function(e){return"LoadBalancer"===e.type&&"OutOfService"===e.state})),r=a.some((function(e){return"LoadBalancer"===e.type}));return n||!r},this.canDeregisterFromTargetGroup=function(){return(e.instance.health||[]).some((function(e){return"TargetGroup"===e.type&&"OutOfService"!==e.state}))},this.canRegisterWithTargetGroup=function(){const t=e.instance,a=t.health||[];if(!t.targetGroups||!t.targetGroups.length)return!1;const n=a.some((function(e){return"TargetGroup"===e.type&&"OutOfService"===e.state})),r=a.some((function(e){return"TargetGroup"===e.type}));return n||!r},this.canRegisterWithDiscovery=function(){const t=(e.instance.health||[]).filter((function(e){return"Discovery"===e.type}));return!!t.length&&"OutOfService"===t[0].state},this.terminateInstance=function(){const a=e.instance,n={application:r,title:"Terminating "+a.instanceId,onTaskComplete:function(){t.includes("**.instanceDetails",{instanceId:a.instanceId})&&t.go("^")}};k.confirm({header:"Really terminate "+a.instanceId+"?",buttonText:"Terminate "+a.instanceId,account:a.account,taskMonitorConfig:n,submitMethod:function(){return Xn.terminateInstance(a,r)}})},this.terminateInstanceAndShrinkServerGroup=function(){const a=e.instance,n={application:r,title:"Terminating "+a.instanceId+" and shrinking server group",onTaskComplete:function(){t.includes("**.instanceDetails",{instanceId:a.instanceId})&&t.go("^")}};k.confirm({header:"Really terminate "+a.instanceId+" and shrink "+a.serverGroup+"?",buttonText:"Terminate "+a.instanceId+" and shrink "+a.serverGroup,account:a.account,taskMonitorConfig:n,submitMethod:function(){return Xn.terminateInstanceAndShrinkServerGroup(a,r)}})},this.rebootInstance=function(){const t=e.instance,a={application:r,title:"Rebooting "+t.instanceId};k.confirm({header:"Really reboot "+t.instanceId+"?",buttonText:"Reboot "+t.instanceId,account:t.account,platformHealthOnlyShowOverride:r.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",taskMonitorConfig:a,submitMethod:(e={})=>(r.attributes&&r.attributes.platformHealthOnlyShowOverride&&r.attributes.platformHealthOnly&&(e.interestingHealthProviderNames=["Amazon"]),Xn.rebootInstance(t,r,e))})},this.registerInstanceWithLoadBalancer=function(){const t=e.instance,a=t.loadBalancers.join(" and "),n={application:r,title:"Registering "+t.instanceId+" with "+a};k.confirm({header:"Really register "+t.instanceId+" with "+a+"?",buttonText:"Register "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Xn.registerInstanceWithLoadBalancer(t,r)}})},this.deregisterInstanceFromLoadBalancer=function(){const t=e.instance,a=t.loadBalancers.join(" and "),n={application:r,title:"Deregistering "+t.instanceId+" from "+a};k.confirm({header:"Really deregister "+t.instanceId+" from "+a+"?",buttonText:"Deregister "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Xn.deregisterInstanceFromLoadBalancer(t,r)}})},this.registerInstanceWithTargetGroup=function(){const t=e.instance,a=t.targetGroups.join(" and "),n={application:r,title:"Registering "+t.instanceId+" with "+a};k.confirm({header:"Really register "+t.instanceId+" with "+a+"?",buttonText:"Register "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Xn.registerInstanceWithTargetGroup(t,r)}})},this.deregisterInstanceFromTargetGroup=function(){const t=e.instance,a=t.targetGroups.join(" and "),n={application:r,title:"Deregistering "+t.instanceId+" from "+a};k.confirm({header:"Really deregister "+t.instanceId+" from "+a+"?",buttonText:"Deregister "+t.instanceId,account:t.account,taskMonitorConfig:n,submitMethod:function(){return Xn.deregisterInstanceFromTargetGroup(t,r)}})},this.enableInstanceInDiscovery=function(){const t=e.instance,a={application:r,title:"Enabling "+t.instanceId+" in discovery"};k.confirm({header:"Really enable "+t.instanceId+" in discovery?",buttonText:"Enable "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return Xn.enableInstanceInDiscovery(t,r)}})},this.disableInstanceInDiscovery=function(){const t=e.instance,a={application:r,title:"Disabling "+t.instanceId+" in discovery"};k.confirm({header:"Really disable "+t.instanceId+" in discovery?",buttonText:"Disable "+t.instanceId,account:t.account,taskMonitorConfig:a,submitMethod:function(){return Xn.disableInstanceInDiscovery(t,r)}})},this.hasHealthState=function(t,a){return(e.instance.health||[]).some((function(e){return e.type===t&&e.state===a}))};const p=e=>{const t=[{label:"Reboot",triggerAction:this.rebootInstance},{label:"Terminate",triggerAction:this.terminateInstance},{label:"Terminate and Shrink Server Group",triggerAction:this.terminateInstanceAndShrinkServerGroup}],a=[];return this.canRegisterWithDiscovery()&&!e.serverGroupDisabled&&a.push({label:"Enable In Discovery",triggerAction:this.enableInstanceInDiscovery}),(this.hasHealthState("Discovery","Up")||this.hasHealthState("Discovery","Down"))&&a.push({label:"Disable in Discovery",triggerAction:this.disableInstanceInDiscovery}),this.canRegisterWithLoadBalancer()&&a.push({label:"Register with Load Balancer",triggerAction:this.registerInstanceWithLoadBalancer}),this.canDeregisterFromLoadBalancer()&&a.push({label:"Deregister from Load Balancer",triggerAction:this.deregisterInstanceFromLoadBalancer}),this.canRegisterWithTargetGroup()&&a.push({label:"Register with Target Group",triggerAction:this.registerInstanceWithTargetGroup}),this.canDeregisterFromTargetGroup()&&a.push({label:"Deregister from Target Group",triggerAction:this.deregisterInstanceFromTargetGroup}),a.concat(t)};(r.isStandalone?c():l.all([r.serverGroups.ready(),r.loadBalancers.ready()]).then(c)).then((()=>{e.instanceActions=p(e.instance),e.$$destroyed||r.isStandalone||r.serverGroups.onRefresh(e,c)})),e.account=n.account}]);const er=({instancePort:e,ipv6Addresses:t,permanentIps:a,privateDnsName:n,privateIpAddress:r,publicDnsName:i,publicIpAddress:s})=>{const l=e?`:${e}`:"";return Dt.createElement(j,{className:"horizontal-when-filters-collapsed"},n&&Dt.createElement(B,{label:"Private DNS Name",value:Dt.createElement(H,{text:n,url:`http://${n}${l}`})}),i&&Dt.createElement(B,{label:"Public DNS Name",value:Dt.createElement(H,{text:i,url:`http://${i}${l}`})}),r&&Dt.createElement(B,{label:"Private IP Address",value:Dt.createElement(H,{text:r,url:`http://${r}${l}`})}),Boolean(null==a?void 0:a.length)&&Dt.createElement(B,{label:"Permanent IP Address",value:a.map((e=>Dt.createElement(H,{key:e,text:e,url:`http://${e}${l}`})))}),s&&Dt.createElement(B,{label:"Public IP Address",value:Dt.createElement(H,{text:s,url:`http://${s}${l}`})}),Boolean(null==t?void 0:t.length)&&Dt.createElement(B,{label:"IPv6 Address"+(t.length>1?"es":""),value:t.map((e=>Dt.createElement(H,{key:e.ip,text:e.ip,url:e.url})))}))};t("spinnaker.application.instanceDns.component",[]).component("instanceDns",ja(M(er,"instanceDns"),["instancePort","ipv6Addresses","permanentIps","privateDnsName","privateIpAddress","publicDnsName","publicIpAddress"]));t("spinnaker.application.instanceSecurityGroups.component",[]).component("instanceSecurityGroups",ja(M((({instance:e})=>{const{account:t,region:a,provider:n,securityGroups:r,vpcId:i}=e,s=jt(r,["groupName"],["asc"]),l=U.get("Firewalls");return $t.createElement(A,{heading:l,defaultExpanded:!0},$t.createElement(Za,null,$t.createElement("ul",null,(s||[]).map((e=>$t.createElement("li",{key:e.groupId},$t.createElement(Ha,{to:"^.firewallDetails",params:{name:e.groupName,accountId:t,region:a,vpcId:i,provider:n}},$t.createElement("a",null,e.groupName," (",e.groupId,")"))))))))}),"instanceSecurityGroups"),["instance"]));const tr=({healthMetrics:e,healthState:t,metricTypes:a,customHealthUrl:n,privateIpAddress:r})=>{const i=a.includes("LoadBalancer"),s=a.includes("TargetGroup");return $t.createElement(A,{heading:"Status",defaultExpanded:!0},!e.length&&$t.createElement("p",null,"Starting"===t?"Starting":"No health metrics found for this instance"),$t.createElement("dl",{className:"horizontal-when-filters-collapsed"},e.sort(((e,t)=>e.type<t.type?-1:e.type>t.type?1:0)).map((e=>$t.createElement($t.Fragment,{key:`${e.type}-${e.description}`},$t.createElement("dt",null,W(e.type)),$t.createElement("dd",null,!a.includes(e.type)&&$t.createElement("div",null,$t.createElement(Z,{value:"down"===e.state.toLowerCase()?e.description:"",placement:"left"},$t.createElement("span",null,$t.createElement("span",{className:`glyphicon glyphicon-${e.state}-triangle`}),$t.createElement("span",null,W(e.state)))),$t.createElement("span",{className:"pad-left small"},e.healthCheckUrl&&$t.createElement("a",{target:"_blank",href:e.healthCheckUrl},"Health Check"),e.healthCheckUrl&&e.statusPageUrl&&$t.createElement("span",null," | "),e.statusPageUrl&&$t.createElement("a",{target:"_blank",href:e.statusPageUrl},"Status"),n&&e.type===n.type&&$t.createElement("span",null," ","|"," ",$t.createElement("a",{target:"_blank",href:n.href},n.text)))),i&&"LoadBalancer"===e.type&&(e.loadBalancers||[]).map((e=>$t.createElement(_,{key:`lb-${e.name}`,loadBalancer:e}))),s&&"TargetGroup"===e.type&&(e.targetGroups||[]).map((e=>$t.createElement(_,{key:`tg-${e.name}`,loadBalancer:e,ipAddress:r})))))))))};t("spinnaker.application.instanceStatus.component",[]).component("instanceStatus",ja(M(tr,"instanceStatus"),["healthMetrics","healthState","metricTypes","customHealthUrl","privateIpAddress"]));function ar(e,t){void 0===t&&(t={});var a=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],r=document.createElement("style");r.type="text/css","top"===a&&n.firstChild?n.insertBefore(r,n.firstChild):n.appendChild(r),r.styleSheet?r.styleSheet.cssText=e:r.appendChild(document.createTextNode(e))}}t("spinnaker.application.instanceTags.component",[]).component("instanceTags",ja(M((({tags:e})=>{const t=jt(e,["key"],["asc"]);return $t.createElement(A,{heading:"Tags",defaultExpanded:!0},!e.length&&$t.createElement("div",null,"No tags associated with this server"),e.length&&t.map((e=>$t.createElement(B,{key:e.key,label:e.key,value:e.value}))))}),"instanceTags"),["tags"]));ar(".target-group-title {\n color: var(--color-mineshaft);\n font-weight: 600;\n font-size: 14px;\n padding-right: 15px;\n text-transform: uppercase;\n padding-left: 10px;\n}\n.cluster-container .target-group-container {\n margin-top: 3px;\n}\n.cluster-container .target-group-container:not(:first-child) {\n padding-top: 5px;\n}\n.target-group-container .target-group-header {\n padding: 4px 0;\n}\n.target-group-container .server-group-title {\n padding-top: 0;\n}\n.target-group-container .server-group-title .clickable-row {\n margin-top: -1px;\n}\n.target-group-container .no-margin-y {\n margin-top: -1px !important;\n margin-bottom: 0 !important;\n}\n.target-group-container > div > .text-right {\n padding-right: 10px;\n font-weight: 600;\n}\n.listener-targets {\n display: inline-block;\n vertical-align: top;\n}\n");class nr extends $t.Component{render(){const{targetGroup:e,showInstances:t,showServerGroups:a,loadBalancer:n}=this.props,r=jt(e.serverGroups,["isDisabled","name"],["asc","desc"]).map((e=>$t.createElement(K,{key:e.name,account:e.account,region:e.region,serverGroup:e,showInstances:t}))),i={loadBalancerName:n.name,region:e.region,accountId:e.account,name:e.name,vpcId:e.vpcId,provider:e.cloudProvider};return $t.createElement("div",{className:"target-group-container container-fluid no-padding"},$t.createElement(Wa,{class:"active"},$t.createElement(Ha,{to:".targetGroupDetails",params:i},$t.createElement("div",{className:"clickable clickable-row row no-margin-y target-group-header"},$t.createElement("div",{className:"col-md-8 target-group-title"},e.name),$t.createElement("div",{className:"col-md-4 text-right"},$t.createElement(Y,{container:e.instanceCounts}))))),a&&r,!a&&t&&$t.createElement(X,{serverGroups:e.serverGroups,instances:e.instances}))}}class rr extends $t.Component{shouldComponentUpdate(e){return e.showInstances!==this.props.showInstances||e.showServerGroups!==this.props.showServerGroups||e.loadBalancer!==this.props.loadBalancer||(()=>!Ht((e.serverGroups||[]).map((e=>e.name)),(this.props.serverGroups||[]).map((e=>e.name))))()||(()=>!Ht((e.loadBalancer.targetGroups||[]).map((e=>e.name)),(this.props.loadBalancer.targetGroups||[]).map((e=>e.name))))()}render(){const{loadBalancer:e,showInstances:t,showServerGroups:a}=this.props;if("classic"!==e.loadBalancerType){const n=e.targetGroups.map((n=>$t.createElement(nr,{key:n.name,loadBalancer:e,targetGroup:n,showInstances:t,showServerGroups:a})));return $t.createElement("div",{className:"cluster-container"},n)}return $t.createElement(Q,{...this.props})}}class ir{static buildTargetGroup(e,t){if(!e)return null;const a={name:e.name,vpcId:e.vpcId,cloudProvider:e.cloudProvider,account:e.account,region:e.region,loadBalancerNames:e.loadBalancerNames,instanceCounts:{up:0,down:0,succeeded:0,failed:0,outOfService:0,unknown:0,starting:0}};return t.instances.forEach((t=>{const n=t.health.find((e=>"TargetGroup"===e.type));if(n){const t=n.targetGroups.find((t=>t.name===e.name));if(void 0!==t&&void 0!==t.healthState){const e=t.healthState.toLowerCase();void 0!==a.instanceCounts[e]&&a.instanceCounts[e]++}}})),a}static populateTargetGroups(e,t){return qa.all([o.getAccountDetails(t.account),e.getDataSource("loadBalancers").ready()]).then((a=>{const n=a[0]&&a[0].awsAccount||t.account,r=e.loadBalancers.data.filter((e=>"application"===e.loadBalancerType||"network"===e.loadBalancerType));return t.targetGroups.map((e=>{const a=Vt(r.map((e=>e.targetGroups||[]))).find((a=>a.name===e&&a.region===t.region&&a.account===n));return this.buildTargetGroup(a,t)})).filter((e=>e))}))}}class sr extends $t.Component{constructor(){super(...arguments),this.onClick=e=>{this.props.onItemClick(this.props.loadBalancer),e.nativeEvent.preventDefault()}}render(){return $t.createElement("a",{onClick:this.onClick},$t.createElement("span",{className:"name"},this.props.loadBalancer.name),$t.createElement(Y,{container:this.props.loadBalancer.instanceCounts}))}}class lr extends $t.Component{constructor(){super(...arguments),this.onClick=e=>{this.props.onItemClick(this.props.loadBalancer),e.nativeEvent.preventDefault()}}render(){return $t.createElement(Z,{value:`${this.props.label||"Load Balancer"}: ${this.props.loadBalancer.name}`},$t.createElement("button",{className:"btn btn-link no-padding",onClick:this.onClick},$t.createElement("span",{className:"badge badge-counter"},$t.createElement("span",{className:"icon"},$t.createElement("i",{className:"fa icon-sitemap"})))))}}class or extends $t.Component{constructor(e){super(e),this.mounted=!1,this.showLoadBalancerDetails=e=>{const{$state:t}=h,a=this.props.serverGroup;J.log({category:"Cluster Pod",action:"Load Load Balancer Details (multiple menu)"});const n=t.current.name.endsWith(".clusters")?".loadBalancerDetails":"^.loadBalancerDetails";t.go(n,{region:a.region,accountId:a.account,name:e.name,provider:a.type})},this.showTargetGroupDetails=e=>{const{$state:t}=h;J.log({category:"Cluster Pod",action:"Load Target Group Details (multiple menu)"});const a=t.current.name.endsWith(".clusters")?".targetGroupDetails":"^.targetGroupDetails";t.go(a,{region:e.region,accountId:e.account,name:e.name,provider:"aws",loadBalancerName:e.loadBalancerNames[0]})},this.handleShowPopover=()=>{J.log({category:"Cluster Pod",action:"Show Load Balancers Menu"})},this.handleClick=e=>{e.preventDefault(),e.stopPropagation()},this.state={loadBalancers:[],targetGroups:[],isLoading:!0}}componentDidMount(){this.mounted=!0,this.loadBalancersRefreshUnsubscribe=this.props.application.getDataSource("loadBalancers").onRefresh(null,(()=>{this.forceUpdate()})),ee.populateLoadBalancers(this.props.application,this.props.serverGroup).then((e=>{this.mounted&&this.setState({loadBalancers:e,isLoading:!1})})),ir.populateTargetGroups(this.props.application,this.props.serverGroup).then((e=>{this.mounted&&this.setState({targetGroups:e})}))}componentWillUnmount(){this.mounted=!1,this.loadBalancersRefreshUnsubscribe()}render(){const{loadBalancers:e,targetGroups:t,isLoading:a}=this.state,n=t&&t.length||0,r=e&&e.length||0,i=n+r;if(!i)return a?$t.createElement(te,{size:"nano"}):null;const s="load-balancers-tag "+(i>1?"overflowing":""),l=$t.createElement("div",{className:"menu-load-balancers"},r>0&&$t.createElement("div",{className:"menu-load-balancers-header"},"Load Balancers"),Wt(e,"name").map((e=>$t.createElement(sr,{key:e.name,loadBalancer:e,onItemClick:this.showLoadBalancerDetails}))),n>0&&$t.createElement("div",{className:"menu-load-balancers-header"},"Target Groups"),Wt(t,"name").map((e=>$t.createElement(sr,{key:e.name,loadBalancer:e,onItemClick:this.showTargetGroupDetails}))));return $t.createElement("span",{className:s},i>1&&$t.createElement(ae,{delayShow:100,delayHide:150,onShow:this.handleShowPopover,placement:"bottom",template:l,hOffsetPercent:"80%",container:this.props.container,className:"no-padding menu-load-balancers"},$t.createElement("button",{onClick:this.handleClick,className:"btn btn-link btn-multiple-load-balancers clearfix no-padding"},$t.createElement("span",{className:"badge badge-counter"},$t.createElement("span",{className:"icon"},$t.createElement("i",{className:"fa icon-sitemap"}))," ",i))),1===e.length&&0===t.length&&$t.createElement("span",{className:"btn-load-balancer"},$t.createElement(lr,{key:e[0].name,label:"Load Balancer",loadBalancer:e[0],onItemClick:this.showLoadBalancerDetails})),1===t.length&&0===e.length&&$t.createElement("span",{className:"btn-load-balancer"},$t.createElement(lr,{key:t[0].name,label:"Target Group",loadBalancer:t[0],onItemClick:this.showTargetGroupDetails})))}}const cr=$t.forwardRef(((e,t)=>$t.createElement("div",{ref:t},$t.createElement(s,{name:"idleTimeout",label:"Idle Timeout",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.idleTimeout"}),input:e=>$t.createElement(u,{...e,min:0})}),$t.createElement(s,{name:"deletionProtection",label:"Protection",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.deletionProtection"}),input:e=>$t.createElement(d,{...e,text:"Enable delete protection"})}),$t.createElement(s,{name:"dualstack",label:"Dualstack",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.albIpAddressType"}),input:e=>$t.createElement(d,{...e,text:"Assign Ipv4 and IPv6"})}))));ar(".configure-config-modal .StandardFieldLayout .sm-label-right {\n min-width: 160px;\n}\n");const dr=class extends $t.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal(e)},this.submit=e=>{this.props.closeModal(e)},this.validate=()=>({});const t=e.config||{};this.state={initialValues:{authorizationEndpoint:t.authorizationEndpoint||"",clientId:t.clientId||"",clientSecret:t.clientSecret||"",issuer:t.issuer||"",scope:t.scope||"openid",sessionCookieName:t.sessionCookieName||"AWSELBAuthSessionCookie",tokenEndpoint:t.tokenEndpoint||"",userInfoEndpoint:t.userInfoEndpoint||""}}}static show(e){return b.show(dr,e)}render(){const{initialValues:e}=this.state;return $t.createElement("div",{className:"configure-config-modal"},$t.createElement(ne,{initialValues:e,onSubmit:this.submit,validate:this.validate,render:({isValid:e})=>$t.createElement(en,{className:"form-horizontal"},$t.createElement(re,{dismiss:this.close}),$t.createElement(Fa.Header,null,$t.createElement(Fa.Title,null,"Configure OIDC Client")),$t.createElement(Fa.Body,null,$t.createElement(s,{name:"issuer",label:"Issuer",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter the OpenId Provider"})}),$t.createElement(s,{name:"authorizationEndpoint",label:"Authorization Endpoint",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter OpenID provider server endpoint"})}),$t.createElement(s,{name:"tokenEndpoint",label:"Token Endpoint",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter a URI for your token endpoint"})}),$t.createElement(s,{name:"userInfoEndpoint",label:"User info Endpoint",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter a URI for your user info endpoint"})}),$t.createElement(s,{name:"clientId",label:"Client ID",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter the client ID"})}),$t.createElement(s,{name:"clientSecret",label:"Client secret",required:!0,input:e=>$t.createElement(l,{...e,placeholder:"Enter the client secret"})})),$t.createElement(Fa.Footer,null,$t.createElement("button",{className:"btn btn-default",onClick:this.close,type:"button"},"Cancel"),$t.createElement(ie,{isDisabled:!e,submitting:!1,isFormSubmit:!0,label:"Save Client"})))}))}};let pr=dr;pr.defaultProps={closeModal:C,dismissModal:C};const ur=class extends $t.Component{constructor(e){super(e),this.close=e=>{this.props.dismissModal(e)},this.submit=e=>{const t=Zt(e,(e=>e&&""!==e));this.props.closeModal(t)};const t=e.config||{};this.initialValues={host:t.host||"",path:t.path||"",port:t.port||"",protocol:t.protocol||void 0,query:t.query||"",statusCode:t.statusCode||"HTTP_301"}}static show(e){return b.show(ur,e)}render(){return $t.createElement("div",{className:"configure-config-modal"},$t.createElement(ne,{initialValues:this.initialValues,onSubmit:this.submit,render:({isValid:e})=>$t.createElement(en,{className:"form-horizontal"},$t.createElement(re,{dismiss:this.close}),$t.createElement(Fa.Header,null,$t.createElement(Fa.Title,null,"Configure Redirect ",$t.createElement(n,{id:"aws.loadBalancer.redirect"}))),$t.createElement(Fa.Body,null,$t.createElement(s,{name:"host",label:"Host",required:!1,input:e=>$t.createElement(l,{...e}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.host"})}),$t.createElement(s,{name:"path",label:"Path",required:!1,input:e=>$t.createElement(l,{...e}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.path"})}),$t.createElement(s,{name:"port",label:"Port",required:!1,input:e=>$t.createElement(l,{...e}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.port"})}),$t.createElement(s,{name:"protocol",label:"Protocol",required:!1,input:e=>$t.createElement(c,{...e,stringOptions:["HTTP","HTTPS","#{protocol}"],placeholder:"Select Protocol",clearable:!1,style:{width:"130px"}}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.protocol"})}),$t.createElement(s,{name:"query",label:"Query",required:!1,input:e=>$t.createElement(l,{...e}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.query"})}),$t.createElement(s,{name:"statusCode",label:"Status Code",required:!0,input:e=>$t.createElement(se,{...e,options:["HTTP_301","HTTP_302"]}),help:$t.createElement(n,{id:"aws.loadBalancer.redirect.statusCode"})})),$t.createElement(Fa.Footer,null,$t.createElement("button",{className:"btn btn-default",onClick:this.close,type:"button"},"Cancel"),$t.createElement(ie,{isDisabled:!e,submitting:!1,isFormSubmit:!0,label:"Save Config"})))}))}};let mr=ur;mr.defaultProps={closeModal:C,dismissModal:C};class gr{static listCertificates(){return le.listCertificatesByProvider("aws").then((e=>o.listAllAccounts("aws").then((t=>{const a=t.reduce(((e,t)=>(e[t.accountId]=t.name,e)),{}),n=Wt(e,"serverCertificateName");return _t(n,(e=>{const[,,,,t]=e.arn.split(":");return a[t]||"unknown"}))}))))}}var hr=Object.defineProperty,fr=Object.getOwnPropertyDescriptor;let vr=class extends $t.Component{render(){const{certificates:e,accountName:t,onCertificateSelect:a,currentValue:n}=this.props,r=e[t]||[],i=r.map((e=>({label:e.serverCertificateName,value:e.serverCertificateName}))),s=r.find((e=>e.serverCertificateName===n));return $t.createElement("div",{style:{width:"100%"}},$t.createElement(an,{className:"input-sm",wrapperStyle:{width:"100%"},clearable:!0,required:!0,options:i,onChange:e=>a(e.value),value:n}),s&&$t.createElement("div",{className:"small sp-margin-xs-top sp-margin-m-bottom sp-margin-m-left"},$t.createElement("div",null,"Uploaded ",oe(s.uploadDate)," (",D(s.uploadDate),")"),$t.createElement("b",null,"Expires ",oe(s.expiration))," (",D(s.expiration),")"))}};vr=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?fr(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&hr(t,a,i),i})([ce("amazon.certificateSelectField")],vr);const yr=Ya((()=>$t.createElement("span",{className:"pipeline-drag-handle clickable glyphicon glyphicon-resize-vertical"}))),br={authenticateOidcConfig:{authorizationEndpoint:"",clientId:"",issuer:"",scope:"openid",sessionCookieName:"AWSELBAuthSessionCookie",tokenEndpoint:"",userInfoEndpoint:""},type:"authenticate-oidc"};class wr extends $t.Component{constructor(e){super(e),this.protocols=["HTTP","HTTPS"],this.initialActionsWithAuth=new Set,this.initialListenersWithDefaultAuth=new Set,this.removedAuthActions=new Map,this.attachClientSecret=(e,t)=>{if("authenticate-oidc"===e.type){const a=t.find((t=>t.clientId===e.authenticateOidcConfig.clientId));a&&(e.authenticateOidcConfig.clientSecret=a.clientSecret)}},this.addListener=()=>{this.props.formik.values.listeners.push({certificates:[],protocol:"HTTP",port:80,defaultActions:[{type:"forward",targetGroupName:""}],rules:[]}),this.updateListeners()},this.addRule=e=>{e.rules.push({priority:null,actions:[{type:"forward",targetGroupName:""}],conditions:[{field:"path-pattern",values:[""]}]}),this.updateListeners()},this.removeRule=(e,t)=>{e.rules.splice(t,1),this.updateListeners()},this.handleConditionFieldChanged=(e,t)=>{e.field=t,"http-request-method"===t&&(e.values=[]),this.updateListeners()},this.handleConditionValueChanged=(e,t)=>{e.values[0]=t,this.updateListeners()},this.handleHttpRequestMethodChanged=(e,t,a)=>{let n=e.values||[];a?n.push(t):n=n.filter((e=>e!==t)),e.values=n,e.httpRequestMethodConfig={values:n},this.updateListeners()},this.addCondition=e=>{if(1===e.conditions.length){const t="path-pattern"===e.conditions[0].field?"host-header":"path-pattern";e.conditions.push({field:t,values:[""]})}this.updateListeners()},this.removeCondition=(e,t)=>{e.conditions.splice(t,1),this.updateListeners()},this.handleRuleActionTargetChanged=(e,t)=>{e.targetGroupName=t,this.updateListeners()},this.handleRuleActionTypeChanged=(e,t)=>{e.type=t,"forward"===e.type?delete e.redirectActionConfig:"redirect"===e.type&&(e.redirectActionConfig={statusCode:"HTTP_301"},delete e.targetGroupName),this.updateListeners()},this.handleSortEnd=(e,t)=>{t.rules=Xa(t.rules,e.oldIndex,e.newIndex),this.updateListeners()},this.configureOidcClient=e=>{pr.show({config:e.authenticateOidcConfig}).then((t=>{e.authenticateOidcConfig=t,this.updateListeners()})).catch((()=>{}))},this.configureRedirect=e=>{mr.show({config:e.redirectActionConfig}).then((t=>{e.redirectActionConfig=t,this.updateListeners()})).catch((()=>{}))},this.authenticateRuleToggle=(e,t)=>{const a=e.rules[t],n=a&&a.actions||e.defaultActions;if(n){const a=n.findIndex((e=>"authenticate-oidc"===e.type));if(-1!==a)this.removeAuthAction(e,n,a,t);else{const a=(this.removedAuthActions.has(e)?this.removedAuthActions.get(e)[t||-1]:void 0)||{...br};n.unshift({...a})}this.updateListeners()}},this.oidcConfigChanged=(e,t)=>{e.authenticateOidcConfig={...t},this.updateListeners()},this.redirectConfigChanged=(e,t)=>{e.redirectActionConfig={...t},this.updateListeners()},this.state={certificates:[],certificateTypes:Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),oidcConfigs:void 0},this.props.formik.initialValues.listeners.forEach((e=>{"authenticate-oidc"===e.defaultActions[0].type&&this.initialListenersWithDefaultAuth.add(e),e.rules.forEach((e=>{"authenticate-oidc"===e.actions[0].type&&this.initialActionsWithAuth.add(e.actions)}))}))}getAllTargetGroupsFromListeners(e){const t=Vt(e.map((e=>e.defaultActions))),a=Vt(e.map((e=>e.rules)));return t.push(...Vt(a.map((e=>e.actions)))),Yt(t.map((e=>e.targetGroupName)))}validate(e){const t={},a=e.targetGroups.map((e=>e.name)),n=this.getAllTargetGroupsFromListeners(e.listeners),r=Xt(a,n);1===r.length?t.listeners=`Target group ${r[0]} is unused.`:r.length>1&&(t.listeners=`Target groups ${r.join(", ")} are unused.`);const{listeners:i}=e;Ot(i,"port").length<i.length&&(t.listenerPorts="Multiple listeners cannot use the same port.");return e.listeners.find((e=>{const t=!!e.defaultActions.find((e=>"forward"===e.type&&!e.targetGroupName||"authenticate-oidc"===e.type&&!e.authenticateOidcConfig.clientId||"redirect"===e.type&&(!e.redirectActionConfig||!Qt(e.redirectActionConfig,(e=>e&&""!==e))))),a=!!e.rules.find((e=>{const t=!!e.actions.find((e=>"forward"===e.type&&!e.targetGroupName)),a=!!e.actions.find((e=>"authenticate-oidc"===e.type&&!e.authenticateOidcConfig.clientId)),n=!!e.conditions.find((e=>"http-request-method"===e.field?!e.values.length:e.values.includes("")));return t||a||n}));return t||a}))&&(t.listeners="Missing fields in rule configuration."),t}componentDidMount(){this.loadCertificates(),this.loadOidcClients()}loadCertificates(){gr.listCertificates().then((e=>{this.setState({certificates:e})}))}loadOidcClients(){(class{static getOidcConfigsByApp(e){return z("/oidcConfigs").query({app:e}).get()}}).getOidcConfigsByApp(this.props.app.name).then((e=>{e&&e.length&&this.props.formik.values.listeners.forEach((t=>{t.defaultActions.forEach((t=>this.attachClientSecret(t,e))),t.rules.forEach((t=>t.actions.forEach((t=>this.attachClientSecret(t,e)))))})),this.setState({oidcConfigs:e}),this.updateListeners()})).catch((()=>{}))}updateListeners(){this.props.formik.setFieldValue("listeners",this.props.formik.values.listeners)}needsCert(e){return"HTTPS"===e.protocol}showCertificateSelect(e){return"iam"===e.type&&this.state.certificates&&Object.keys(this.state.certificates).length>0}addListenerCertificate(e){e.certificates=e.certificates||[],e.certificates.push({certificateArn:void 0,type:"iam",name:void 0})}removeAuthActions(e){const t=e.defaultActions.findIndex((e=>"authenticate-oidc"===e.type));-1!==t&&this.removeAuthAction(e,e.defaultActions,t,-1),e.rules.forEach(((t,a)=>{const n=t.actions.findIndex((e=>"authenticate-oidc"===e.type));-1!==n&&this.removeAuthAction(e,t.actions,n,a)})),this.updateListeners()}reenableAuthActions(e){const t=this.removedAuthActions.has(e)?this.removedAuthActions.get(e):[],a=t[-1];a&&(t[-1]=void 0,e.defaultActions.unshift({...a})),e.rules.forEach(((e,a)=>{const n=t[a];t[a]=void 0,n&&e.actions.unshift({...n})}))}listenerProtocolChanged(e,t){e.protocol=t,"HTTPS"===e.protocol&&(e.port=443,e.certificates&&0!==e.certificates.length||this.addListenerCertificate(e),this.reenableAuthActions(e)),"HTTP"===e.protocol&&(e.port=80,e.certificates.length=0,this.removeAuthActions(e)),this.updateListeners()}listenerPortChanged(e,t){e.port=Number.parseInt(t,10),this.updateListeners()}certificateTypeChanged(e,t){e.type=t,this.updateListeners()}handleCertificateChanged(e,t){e.name=t,this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}removeAuthActionInternal(e,t,a,n=-1){const r=t.splice(a,1)[0];this.removedAuthActions.has(e)||this.removedAuthActions.set(e,[]),this.removedAuthActions.get(e)[n||-1]=r,this.updateListeners()}removeAuthAction(e,t,a,n=-1){const r=-1===n&&this.initialListenersWithDefaultAuth.has(e),i=n>-1&&this.initialActionsWithAuth.has(t);r||i?k.confirm({header:"Really remove authentication?",buttonText:"Remove Auth",submitMethod:()=>(this.removeAuthActionInternal(e,t,a,n),r&&this.initialListenersWithDefaultAuth.delete(e),i&&this.initialActionsWithAuth.delete(t),qa.resolve())}):this.removeAuthActionInternal(e,t,a,n)}render(){const{errors:e,values:t}=this.props.formik,{certificates:a,certificateTypes:n,oidcConfigs:r}=this.state;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},t.listeners.map(((e,i)=>$t.createElement("div",{key:i,className:"wizard-pod"},$t.createElement("div",null,$t.createElement("div",{className:"wizard-pod-row header"},$t.createElement("div",{className:"wizard-pod-row-title"},"Listen On"),$t.createElement("div",{className:"wizard-pod-row-contents spread"},$t.createElement("div",null,$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol"),$t.createElement("select",{className:"form-control input-sm inline-number",style:{width:"80px"},value:e.protocol,onChange:t=>this.listenerProtocolChanged(e,t.target.value)},this.protocols.map((e=>$t.createElement("option",{key:e},e))))),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port"),$t.createElement("input",{className:"form-control input-sm inline-number",type:"text",min:0,value:e.port||"",onChange:t=>this.listenerPortChanged(e,t.target.value),style:{width:"80px"},required:!0}))),$t.createElement("div",null,$t.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(i)},$t.createElement("span",{className:"glyphicon glyphicon-trash"}))))),this.needsCert(e)&&$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Certificate"),$t.createElement("div",{className:"wizard-pod-row-contents"},e.certificates.map(((e,r)=>$t.createElement("div",{key:r,style:{width:"100%",display:"flex",flexDirection:"row"}},$t.createElement("select",{className:"form-control input-sm inline-number",style:{width:"45px"},value:e.type,onChange:t=>this.certificateTypeChanged(e,t.target.value)},n.map((e=>$t.createElement("option",{key:e},e)))),this.showCertificateSelect(e)&&$t.createElement(vr,{certificates:a,accountName:t.credentials,currentValue:e.name,app:this.props.app,onCertificateSelect:t=>this.handleCertificateChanged(e,t)}),!this.showCertificateSelect(e)&&$t.createElement("input",{className:"form-control input-sm no-spel",style:{display:"inline-block"},type:"text",value:e.name,onChange:t=>this.handleCertificateChanged(e,t.target.value),required:!0})))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-contents",style:{padding:"0"}},$t.createElement("table",{className:"table table-condensed packed rules-table"},$t.createElement("thead",null,$t.createElement("tr",null,$t.createElement("th",{style:{width:"15px",padding:"0"}}),$t.createElement("th",null,"If"),$t.createElement("th",{style:{width:"315px"}},"Then"),$t.createElement("th",{style:{width:"45px"}}))),$t.createElement(Sr,{addCondition:this.addCondition,addRule:this.addRule,authenticateRuleToggle:this.authenticateRuleToggle,distance:10,handleConditionFieldChanged:this.handleConditionFieldChanged,handleConditionValueChanged:this.handleConditionValueChanged,handleHttpRequestMethodChanged:this.handleHttpRequestMethodChanged,handleRuleActionTargetChanged:this.handleRuleActionTargetChanged,handleRuleActionTypeChanged:this.handleRuleActionTypeChanged,listener:e,helperClass:"rule-sortable-helper",removeRule:this.removeRule,removeCondition:this.removeCondition,targetGroups:t.targetGroups,oidcConfigs:r,oidcConfigChanged:this.oidcConfigChanged,redirectConfigChanged:this.redirectConfigChanged,onSortEnd:t=>this.handleSortEnd(t,e),configureOidcClient:this.configureOidcClient,configureRedirect:this.configureRedirect})))))))),e.listenerPorts&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:e.listenerPorts})),e.listeners&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:e.listeners})),$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("tbody",null,$t.createElement("tr",null,$t.createElement("td",null,$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addListener},$t.createElement("span",null,$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new listener")))))))))}}const Er=Qa((e=>$t.createElement("tr",{className:"listener-rule"},$t.createElement("td",{className:"handle"},$t.createElement(yr,null)),$t.createElement("td",null,e.rule.conditions.map(((t,a)=>$t.createElement("div",{key:a,className:"listener-rule-condition"},$t.createElement("select",{className:"form-control input-sm inline-number",value:t.field,onChange:a=>e.handleConditionFieldChanged(t,a.target.value),style:{width:"40%"},required:!0},(1===e.rule.conditions.length||"host-header"===t.field)&&$t.createElement("option",{value:"host-header"},"Host"),(1===e.rule.conditions.length||"path-pattern"===t.field)&&$t.createElement("option",{value:"path-pattern"},"Path"),(1===e.rule.conditions.length||"http-request-method"===t.field)&&$t.createElement("option",{value:"http-request-method"},"Method(s)")),"path-pattern"===t.field&&$t.createElement(n,{id:"aws.loadBalancer.ruleCondition.path"}),"host-header"===t.field&&$t.createElement(n,{id:"aws.loadBalancer.ruleCondition.host"}),"http-request-method"!==t.field&&$t.createElement("input",{className:"form-control input-sm",type:"text",value:t.values[0],onChange:a=>e.handleConditionValueChanged(t,a.target.value),maxLength:128,required:!0,style:{width:"63%"}}),"http-request-method"===t.field&&$t.createElement("div",{className:"col-md-6 checkbox"},["DELETE","GET","PATCH","POST","PUT"].map((a=>$t.createElement("label",{key:`${a}-checkbox`},$t.createElement("input",{type:"checkbox",checked:t.values.includes(a),onChange:n=>e.handleHttpRequestMethodChanged(t,a,n.target.checked)}),a)))),$t.createElement("span",{className:"remove-condition"},1===a&&$t.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.removeCondition(e.rule,a),style:{padding:"0"}},$t.createElement(Z,{value:"Remove Condition"},$t.createElement("span",{className:"glyphicon glyphicon-trash"}))))))),1===e.rule.conditions.length&&$t.createElement("div",{className:"add-new-container"},$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:()=>e.addCondition(e.rule)},$t.createElement("span",null,$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new condition")),$t.createElement("span",{style:{minWidth:"15px"}}))),$t.createElement("td",null,e.rule.actions.map(((t,a)=>$t.createElement(Cr,{key:a,action:t,actionTypeChanged:a=>e.handleRuleActionTypeChanged(t,a),oidcConfigChanged:a=>e.oidcConfigChanged(t,a),redirectConfigChanged:a=>e.redirectConfigChanged(t,a),targetChanged:a=>e.handleRuleActionTargetChanged(t,a),targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect})))),$t.createElement("td",null,$t.createElement(kr,{ruleIndex:e.ruleIndex,listener:e.listener,authenticateRuleToggle:e.authenticateRuleToggle,removeRule:e.removeRule,actions:e.rule.actions}))))),Cr=e=>{var t;if("authenticate-oidc"!==e.action.type){const t=e.action.redirectActionConfig||e.action.redirectConfig;return $t.createElement("div",{className:"horizontal top"},$t.createElement("select",{className:"form-control input-sm",style:{width:"80px"},value:e.action.type,onChange:t=>e.actionTypeChanged(t.target.value)},$t.createElement("option",{value:"forward"},"forward to"),$t.createElement("option",{value:"redirect"},"redirect to")),"forward"===e.action.type&&$t.createElement("select",{className:"form-control input-sm",value:e.action.targetGroupName,onChange:t=>e.targetChanged(t.target.value),required:!0},$t.createElement("option",{value:""}),Yt(e.targetGroups.map((e=>e.name))).map((e=>$t.createElement("option",{key:e},e)))),"redirect"===e.action.type&&$t.createElement("dl",{className:"dl-horizontal dl-narrow"},$t.createElement("dt",null,"Host"),$t.createElement("dd",null,t.host),$t.createElement("dt",null,"Path"),$t.createElement("dd",null,t.path),$t.createElement("dt",null,"Port"),$t.createElement("dd",null,t.port),$t.createElement("dt",null,"Protocol"),$t.createElement("dd",null,t.protocol),$t.createElement("dt",null,"Query"),$t.createElement("dd",null,t.query),$t.createElement("dt",null,"Status Code"),$t.createElement("dd",null,t.statusCode),$t.createElement("dt",null,$t.createElement("button",{className:"btn btn-link no-padding",type:"button",onClick:()=>e.configureRedirect(e.action)},"Configure..."))))}if("authenticate-oidc"===e.action.type){const a=e.action.authenticateOidcConfig.clientId,n=Kt(fn,"loadBalancers.disableManualOidcDialog",!1)||e.oidcConfigs&&e.oidcConfigs.length>0&&(!a||e.oidcConfigs.find((e=>e.clientId===a))),r=(null==(t=e.oidcConfigs)?void 0:t.length)?e.oidcConfigs.map((e=>$t.createElement("option",{key:e.clientId},e.clientId))):$t.createElement("option",{disabled:!0},"No ",pe.get("OIDC client")," config found");return $t.createElement("div",{className:"horizontal middle",style:{height:"30px"}},$t.createElement("span",{style:{whiteSpace:"pre"}},"auth with ",pe.get("OIDC client")," "),n&&$t.createElement("select",{className:"form-control input-sm",value:a,onChange:t=>e.oidcConfigChanged(e.oidcConfigs.find((e=>e.clientId===t.target.value))),required:!0},$t.createElement("option",{value:""}),r),!n&&$t.createElement("a",{onClick:()=>e.configureOidcClient(e.action),className:"clickable"},a||"Configure..."),$t.createElement("span",{style:{whiteSpace:"pre"}},$t.createElement("em",null," and then")))}return null},kr=e=>{const t=Boolean(e.actions.find((e=>"authenticate-oidc"===e.type))),a="HTTPS"===e.listener.protocol,r=t?"Remove authentication from rule":"Authenticate rule",i=t?"fas fa-fw fa-lock-open":"fas fa-fw fa-user-lock";return $t.createElement("span",null,a&&$t.createElement($t.Fragment,null,$t.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.authenticateRuleToggle(e.listener,e.ruleIndex),style:{padding:"0"}},$t.createElement(Z,{value:r},$t.createElement("i",{className:i}))),$t.createElement(n,{id:"aws.loadBalancer.oidcAuthentication"})),void 0!==e.ruleIndex&&e.ruleIndex>=0&&e.removeRule&&$t.createElement("a",{className:"btn btn-sm btn-link clickable",onClick:()=>e.removeRule(e.listener,e.ruleIndex),style:{padding:"0"}},$t.createElement(Z,{value:"Remove Rule"},$t.createElement("i",{className:"far fa-fw fa-trash-alt"}))))},Sr=Ja((e=>$t.createElement("tbody",null,$t.createElement("tr",{className:"not-sortable"},$t.createElement("td",null),$t.createElement("td",null,"Default"),$t.createElement("td",null,e.listener.defaultActions.map(((t,a)=>$t.createElement(Cr,{key:a,action:t,actionTypeChanged:a=>e.handleRuleActionTypeChanged(t,a),targetChanged:a=>e.handleRuleActionTargetChanged(t,a),targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,oidcConfigChanged:a=>e.oidcConfigChanged(t,a),redirectConfigChanged:a=>e.redirectConfigChanged(t,a),configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect})))),$t.createElement("td",null,$t.createElement(kr,{listener:e.listener,actions:e.listener.defaultActions,authenticateRuleToggle:e.authenticateRuleToggle}))),e.listener.rules.sort(((e,t)=>e.priority-t.priority)).map(((t,a)=>$t.createElement(Er,{key:a,rule:t,addCondition:e.addCondition,handleConditionFieldChanged:e.handleConditionFieldChanged,handleConditionValueChanged:e.handleConditionValueChanged,handleHttpRequestMethodChanged:e.handleHttpRequestMethodChanged,handleRuleActionTargetChanged:e.handleRuleActionTargetChanged,handleRuleActionTypeChanged:e.handleRuleActionTypeChanged,oidcConfigChanged:e.oidcConfigChanged,redirectConfigChanged:e.redirectConfigChanged,removeCondition:e.removeCondition,authenticateRuleToggle:e.authenticateRuleToggle,removeRule:e.removeRule,targetGroups:e.targetGroups,oidcConfigs:e.oidcConfigs,listener:e.listener,index:a,ruleIndex:a,configureOidcClient:e.configureOidcClient,configureRedirect:e.configureRedirect}))),$t.createElement("tr",{className:"not-sortable"},$t.createElement("td",{colSpan:5},$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:()=>e.addRule(e.listener)},$t.createElement("span",null,$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new rule"))))))),Nr=(e,t,a)=>n=>Kt(e,[t,a],[]).includes(n.toLowerCase())?`There is already a target group in ${t}:${a} with that name.`:null,Gr=e=>t=>t.length<32-e?null:"Target group names are automatically prefixed with their application name and cannot exceed 32 characters in length.";class Tr extends $t.Component{constructor(e){super(e),this.protocols=["HTTP","HTTPS"],this.targetTypes=["instance","ip","lambda"],this.destroy$=new ya,this.addTargetGroup=()=>{const{setFieldValue:e,values:t}=this.props.formik,a=t.targetGroups.length;t.targetGroups.push({name:"targetgroup"+(a?`${a}`:""),protocol:"HTTP",port:7001,targetType:"instance",healthCheckProtocol:"HTTP",healthCheckPort:"7001",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:2,attributes:{deregistrationDelay:300,stickinessEnabled:!1,stickinessType:"lb_cookie",stickinessDuration:8400}}),e("targetGroups",t.targetGroups)};const t=e.isNew?0:e.formik.initialValues.targetGroups.length;this.state={existingTargetGroupNames:{},oldTargetGroupCount:t}}validate(e){const t=Yt(Vt(ea(_t(e.targetGroups,"name"),(e=>e.length>1))).map((e=>e.name))),a=new i(e),{arrayForEach:n}=a;return a.field("targetGroups").withValidators(n(((a,n)=>{var r;a.field("name","Name").withValidators(Nr(this.state.existingTargetGroupNames,e.credentials,e.region),Gr(this.props.app.name.length),ue.valueUnique(t,"There is already a target group in this load balancer with the same name.")),a.field("healthCheckInterval","Health Check Interval").withValidators((r=n,e=>"TCP"!==r.healthCheckProtocol||"TCP"===r.healthCheckProtocol&&(10===Number.parseInt(e,10)||30===Number.parseInt(e,10))?null:"TCP health checks only support 10s and 30s intervals"),ue.checkBetween("healthCheckInterval",5,300)),a.field("healthyThreshold","Healthy Threshold").withValidators(ue.checkBetween("healthyThreshold",2,10)),a.field("unhealthyThreshold","Unhealthy Threshold").spelAware().withValidators(ue.checkBetween("unhealthyThreshold",2,10)),a.field("healthCheckTimeout","Timeout").withValidators((e=>t=>{const a=Jt(t)?t:Number.parseInt(t,10),{protocol:n,healthCheckProtocol:r}=e;if("TCP"===n||"TLS"===n){if("HTTP"===r&&6!==a)return"HTTP health check timeouts for TCP/TLS target groups must be 6s";if(("HTTPS"===r||"TLS"===r)&&10!==a)return"HTTPS/TLS health check timeouts for TCP/TLS target groups must be 10s"}return null})(n),ue.checkBetween("healthCheckTimeout",2,120)),"lambda"!==n.targetType&&(a.field("protocol","Protocol").required(),a.field("healthCheckPath","Health Check Path").required(),a.field("healthCheckProtocol","Health Check Protocol").required(),a.field("name","Name").required(),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckInterval","Health Check Interval").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckPort","Health Check Port").required().spelAware().withValidators((e=>"traffic-port"===e?null:me(e))),a.field("port","Port").required().spelAware().withValidators((e=>me(e))),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e)),ue.checkBetween("healthyThreshold",2,10)),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e)),ue.checkBetween("unhealthyThreshold",2,10)))}))),a.validateForm()}removeAppName(e){return e.replace(`${this.props.app.name}-`,"")}updateLoadBalancerNames(e){const{app:t,loadBalancer:a}=e,n={};ba(t.getDataSource("loadBalancers").refresh(!0)).pipe(xa(this.destroy$)).subscribe((()=>{t.getDataSource("loadBalancers").data.forEach((e=>{"classic"!==e.loadBalancerType&&(a&&e.name===a.name||e.targetGroups.forEach((t=>{n[e.account]=n[e.account]||{},n[e.account][e.region]=n[e.account][e.region]||[],n[e.account][e.region].push(this.removeAppName(t.name))})))})),this.setState({existingTargetGroupNames:n},(()=>this.props.formik.validateForm()))}))}targetGroupFieldChanged(e,t,a){const{setFieldValue:n,values:r}=this.props.formik,i=r.targetGroups[e];"targetType"===t&&"lambda"===a&&delete i.port,ta(i,t,a),n("targetGroups",r.targetGroups)}removeTargetGroup(e){const{setFieldValue:t,values:a}=this.props.formik,{oldTargetGroupCount:n}=this.state;a.targetGroups.splice(e,1),e<n&&this.setState({oldTargetGroupCount:n-1}),t("targetGroups",a.targetGroups)}componentDidMount(){this.updateLoadBalancerNames(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{oldTargetGroupCount:r}=this.state,i=this.protocols.map((e=>$t.createElement("option",{key:e},e))),s=this.targetTypes.map((e=>$t.createElement("option",{key:e},e)));return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},a.targetGroups.map(((a,l)=>{const o=t.targetGroups&&t.targetGroups[l]||{},c=("TCP"===a.protocol||"TLS"===a.protocol)&&"HTTP"===a.healthCheckProtocol,d=("TCP"===a.protocol||"TLS"===a.protocol)&&"HTTPS"===a.healthCheckProtocol;return $t.createElement("div",{key:l,className:"wizard-pod"},$t.createElement("div",null,$t.createElement("div",{className:"wizard-pod-row header"},$t.createElement("div",{className:"wizard-pod-row-title"},"Group Name"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"group-name-prefix"},e.name,"-"),$t.createElement("input",{className:"form-control input-sm target-group-name",type:"text",value:a.name,onChange:e=>this.targetGroupFieldChanged(l,"name",e.target.value),required:!0,disabled:l<r}),$t.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeTargetGroup(l)},$t.createElement("span",{className:"glyphicon glyphicon-trash"}))),o.name&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:o.name})))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},$t.createElement(n,{id:"aws.targetGroup.targetType"})," ",$t.createElement("span",null,"Target Type ")),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("select",{className:"form-control input-sm",value:a.targetType,onChange:e=>this.targetGroupFieldChanged(l,"targetType",e.target.value),disabled:l<r},s))))),"lambda"!==a.targetType&&$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Backend Connection"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol "),$t.createElement(n,{id:"aws.targetGroup.protocol"})," ",$t.createElement("select",{className:"form-control input-sm inline-number",value:a.protocol,onChange:e=>this.targetGroupFieldChanged(l,"protocol",e.target.value),disabled:l<r},i)),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port "),$t.createElement(n,{id:"aws.targetGroup.port"})," ",$t.createElement("input",{className:"form-control input-sm inline-number",value:a.port,onChange:e=>this.targetGroupFieldChanged(l,"port",e.target.value),type:"text",required:!0,disabled:l<r}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},"lambda"!==a.targetType&&$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol "),"TCP"===a.healthCheckProtocol&&$t.createElement(n,{id:"aws.targetGroup.healthCheckProtocol"})," ",$t.createElement("select",{className:"form-control input-sm inline-number",value:a.healthCheckProtocol,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckProtocol",e.target.value)},i)),"lambda"!==a.targetType&&$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port "),$t.createElement(n,{id:"aws.targetGroup.attributes.healthCheckPort.trafficPort"})," ",$t.createElement("select",{className:"form-control input-sm inline-number",style:{width:"90px"},value:"traffic-port"===a.healthCheckPort?"traffic-port":"manual",onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPort","traffic-port"===e.target.value?"traffic-port":"")},$t.createElement("option",{value:"traffic-port"},"Traffic Port"),$t.createElement("option",{value:"manual"},"Manual"))," ",$t.createElement(ge,{className:"form-control input-sm inline-number",error:o.healthCheckPort,style:{visibility:"traffic-port"===a.healthCheckPort?"hidden":"inherit"},name:"healthCheckPort",required:!0,value:a.healthCheckPort,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPort",e.target.value)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Path "),$t.createElement(ge,{error:o.healthCheckPath,name:"healthCheckPath",required:!0,value:a.healthCheckPath,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckPath",e.target.value)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Timeout "),(c||d)&&$t.createElement(n,{id:"aws.targetGroup.healthCheckTimeout"}),$t.createElement(he,{error:o.healthCheckTimeout,disabled:c||d,required:!0,value:c?6:d?10:a.healthCheckTimeout,min:2,max:120,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckTimeout",e)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Interval "),$t.createElement(he,{error:o.healthCheckInterval,required:!0,value:a.healthCheckInterval,min:5,max:300,onChange:e=>this.targetGroupFieldChanged(l,"healthCheckInterval",e)}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck Threshold"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Healthy "),$t.createElement(he,{error:o.healthyThreshold,value:a.healthyThreshold,min:2,max:10,onChange:e=>this.targetGroupFieldChanged(l,"healthyThreshold",e)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Unhealthy "),$t.createElement(he,{error:o.unhealthyThreshold,required:!0,value:a.unhealthyThreshold,min:2,max:10,onChange:e=>this.targetGroupFieldChanged(l,"unhealthyThreshold",e)}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Attributes"),"lambda"!==a.targetType?$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Dereg. Delay"),$t.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelay"})," ",$t.createElement("input",{className:"form-control input-sm inline-number",type:"text",value:a.attributes.deregistrationDelay,onChange:e=>this.targetGroupFieldChanged(l,"attributes.deregistrationDelay",e.target.value)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",{className:"checkbox-inline",style:{paddingTop:"2px"}},$t.createElement("input",{type:"checkbox",checked:a.attributes.stickinessEnabled,onChange:e=>this.targetGroupFieldChanged(l,"attributes.stickinessEnabled",e.target.checked)})," ",$t.createElement("label",null,"Sticky"),$t.createElement(n,{id:"aws.targetGroup.attributes.stickinessEnabled"}))),a.attributes.stickinessEnabled&&$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Duration "),$t.createElement(n,{id:"aws.targetGroup.attributes.stickinessDuration"})," ",$t.createElement("input",{className:"form-control input-sm inline-number",value:a.attributes.stickinessDuration,onChange:e=>this.targetGroupFieldChanged(l,"attributes.stickinessDuration",e.target.value),type:"text"})))):$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",{className:"checkbox-inline",style:{paddingTop:"2px"}},$t.createElement("input",{type:"checkbox",checked:a.attributes.multiValueHeadersEnabled,onChange:e=>this.targetGroupFieldChanged(l,"attributes.multiValueHeadersEnabled",e.target.checked)})," ",$t.createElement("label",null,"Enable Multi Value Headers"))))))})),$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("tbody",null,$t.createElement("tr",null,$t.createElement("td",null,$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addTargetGroup},$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new target group"))))))))}}class Ir extends $t.Component{constructor(e){super(e),this.handleUsePreferredZonesChanged=e=>{const t="true"===e.target.value;this.setState({usePreferredZones:t}),t&&this.setDefaultZones(this.props)},this.handleSelectedZonesChanged=e=>{this.props.onChange([...e])},this.state={defaultZones:[],usePreferredZones:e.usePreferredZones||!e.selectedZones||0===e.selectedZones.length},this.setDefaultZones(e)}componentWillReceiveProps(e){e.region===this.props.region&&e.credentials===this.props.credentials||this.setDefaultZones(e)}setDefaultZones(e){const{credentials:t,onChange:a,region:n}=e,{usePreferredZones:r}=this.state;o.getAvailabilityZonesForAccountAndRegion("aws",t,n).then((e=>{this.setState({defaultZones:e}),r&&e&&a(e.slice())}))}render(){const{region:e,allZones:t,selectedZones:a}=this.props,{defaultZones:n,usePreferredZones:r}=this.state;return $t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Availability Zones"),e&&$t.createElement("div",{className:"col-md-7"},$t.createElement("p",{className:"form-control-static"},"Automatic Availability Zone Balancing:"),$t.createElement("select",{className:"form-control input-sm",value:r?"true":"false",onChange:this.handleUsePreferredZonesChanged},$t.createElement("option",{value:"true"},"Enabled"),$t.createElement("option",{value:"false"},"Manual")),$t.createElement("br",null),r&&$t.createElement("div",null,$t.createElement("p",{className:"form-control-static"},"Server group will be available in:"),$t.createElement("ul",null,n.map((e=>$t.createElement("li",{key:e},e))))),!r&&$t.createElement("div",null,"Restrict server group instances to:",$t.createElement(fe,{stringOptions:t,value:a,onChange:e=>this.handleSelectedZonesChanged(e.target.value)}))))}}function xr(e){const{application:t,credentials:a,defaultSubnetTypes:n,hideClassic:r,name:i,onChange:s,readOnly:l,region:o,subnets:c,value:d,...p}=e,u=ve(c),m=$t.useMemo((()=>{const e=r||function(e,t,a){const{classicLaunchLockout:n,classicLaunchAllowlist:r}=fn,i=Number(Kt(a,"attributes.createTs",0))>(n||0),s=!!r&&r.some((a=>a.region===e&&a.credentials===t));return i||!s}(o,a,t);return function(e,t){const a=(e,t)=>e.label.localeCompare(t.label),n=e=>({value:e.purpose,label:e.label}),r=t?[]:[{label:"None (EC2 Classic)",value:""}],i=e.filter((e=>!e.deprecated)).sort(a).map(n),s=e.filter((e=>e.deprecated)).sort(a).map(n);return s.length&&s.unshift({label:"-----------",value:"",disabled:!0}),r.concat(i).concat(s)}(c,e)}),[r,o,a,t,u]),g=function(e,t=[]){for(const a of t){const t=e.find((e=>a===e.purpose));if(t)return t}}(c,n)||c[0],h=ye().current;return $t.useEffect((()=>{const e=m.some((e=>e.value===d));g&&(!e||"FIRST_RENDER"!==h)&&s(be({name:i,value:g.purpose}))}),[m]),l?$t.createElement("p",{className:"form-control-static"},e.value||"None (EC2 Classic)"):$t.createElement(se,{options:m,value:d,onChange:s,...p})}class Ar extends Dt.Component{constructor(){super(...arguments),this.handleChange=e=>{const{component:t,onChange:a,field:n}=this.props;t[n]=e.target.value,a()}}render(){var e,t,a;const{component:r,defaultSubnetTypes:i,field:s,helpKey:l,labelColumns:o,recommendedSubnetTypes:c,region:d,showSubnetWarning:p,...u}=this.props,m=r[s],g=null!=(t=null!=c?c:null==(e=fn.serverGroups)?void 0:e.recommendedSubnets)?t:[],h=null!=i?i:[fn.defaults.subnetType],f=g.some((e=>m&&m.includes(e))),v=null==(a=fn.serverGroups)?void 0:a.subnetWarning;return Dt.createElement("div",{className:"form-group"},Dt.createElement("div",{className:`col-md-${o} sm-label-right`},"VPC Subnet ",Dt.createElement(n,{id:l})),Dt.createElement("div",{className:"col-md-7"},d?Dt.createElement(xr,{...u,inputClassName:"form-control input-sm",credentials:r.credentials,defaultSubnetTypes:h,region:d,value:m,onChange:this.handleChange}):"(Select an account)",p&&!f&&Boolean(v)&&Dt.createElement("div",{className:"alert alert-warning sp-margin-s-top horizontal center"},Dt.createElement("i",{className:"fa fa-exclamation-triangle sp-margin-s-top"}),Dt.createElement("div",{className:"sp-margin-s-left"},Dt.createElement(we,{message:v,style:{display:"inline-block",marginLeft:"2px"}})))))}}class Pr extends $t.Component{constructor(){super(...arguments),this.state={accounts:void 0,availabilityZones:[],existingLoadBalancerNames:[],hideInternalFlag:!1,internalFlagToggled:!1,regions:[],subnets:[]},this.props$=new ya,this.destroy$=new ya,this.internalFlagChanged=e=>{this.setState({internalFlagToggled:!0}),this.props.formik.handleChange(e)},this.handleSubnetUpdated=e=>{this.props.formik.setFieldValue("subnetType",e)},this.accountUpdated=e=>{this.props.formik.setFieldValue("credentials",e)},this.regionUpdated=e=>{this.props.formik.setFieldValue("region",e)},this.stackChanged=e=>{this.props.formik.setFieldValue("stack",e.target.value)},this.detailChanged=e=>{this.props.formik.setFieldValue("detail",e.target.value)},this.handleAvailabilityZonesChanged=e=>{this.props.formik.setFieldValue("regionZones",e)}}validate(e){const t={};return this.state.existingLoadBalancerNames.includes(e.name)&&(t.name=`There is already a load balancer in ${e.credentials}:${e.region} with that name.`),e.name&&e.name.length>32&&(t.name="Load balancer names cannot exceed 32 characters in length"),e.stack&&!e.stack.match(/^[a-zA-Z0-9]*$/)&&(t.stack="Stack can only contain letters and numbers."),e.detail&&!e.detail.match(/^[a-zA-Z0-9-]*$/)&&(t.detail="Detail can only contain letters, numbers, and dashes."),t}buildName(){const{values:e}=this.props.formik;if(qt(e.moniker)){const t=Ee.parseLoadBalancerName(e.name);e.stack=t.stack,e.detail=t.freeFormDetails}else e.stack=e.moniker.stack,e.detail=e.moniker.detail;delete e.name}shouldHideInternalFlag(){return!!(fn&&fn.loadBalancers&&fn.loadBalancers.inferInternalFlagFromSubnet)&&(delete this.props.formik.values.isInternal,!0)}componentDidMount(){this.setState({hideInternalFlag:this.shouldHideInternalFlag()}),this.props.loadBalancer&&this.props.isNew&&this.buildName();const e=this.props$.pipe(Sa((e=>e.formik.values))),t=this.props$.pipe(Sa((e=>e.app.name)),Na()),a={account$:e.pipe(Sa((e=>e.credentials)),Na()),region$:e.pipe(Sa((e=>e.region)),Na()),subnetPurpose$:e.pipe(Sa((e=>e.subnetType)),Na()),stack$:e.pipe(Sa((e=>e.stack)),Na()),detail$:e.pipe(Sa((e=>e.detail)),Na())},n=ba(o.listAccounts("aws")).pipe(Ga(1)),r=wa([a.account$,n]).pipe(Ta((([e,t])=>o.getRegionsForAccount(e))),Ga(1)),i=this.props.app.getDataSource("loadBalancers").data$,s=wa([i,a.account$,a.region$]).pipe(Sa((([e,t,a])=>e.filter((e=>e.account===t&&e.region===a)).map((e=>e.name)))),Ga(1)),l=wa([a.account$,a.region$]).pipe(Ta((([e,t])=>this.getAvailableSubnets(e,t))),Sa((e=>this.makeSubnetOptions(e))),Ga(1)),c=wa([l,a.subnetPurpose$]).pipe(Sa((([e,t])=>e&&e.find((e=>e.purpose===t))))),d=c.pipe(Sa((e=>e?Yt(e.availabilityZones).sort():[]))),p=a.region$.pipe(Ia(r),Sa((([e,t])=>t.find((t=>t.name===e)))),Sa((e=>e?e.availabilityZones:[]))),u=wa([t,a.stack$,a.detail$]).pipe(Sa((([e,t,a])=>({app:e,stack:t,detail:a,cluster:Ee.getClusterName(e,t,a)}))));r.pipe(Ia(a.region$),xa(this.destroy$)).subscribe((([e,t])=>{e.some((e=>e.name===t))||this.props.formik.setFieldValue("region",e[0]&&e[0].name)})),p.pipe(xa(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("regionZones",e)})),c.pipe(xa(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("vpcId",e&&e.vpcIds[0]),this.props.formik.setFieldValue("subnetType",e&&e.purpose),!this.state.hideInternalFlag&&!this.state.internalFlagToggled&&e&&e.purpose&&this.props.formik.setFieldValue("isInternal",e.purpose.includes("internal"))})),u.pipe(xa(this.destroy$)).subscribe((e=>{this.props.formik.setFieldValue("moniker",e),this.props.formik.setFieldValue("name",e.cluster)})),wa([n,r,d,s,l]).pipe(xa(this.destroy$)).subscribe((([e,t,a,n,r])=>this.setState({accounts:e,regions:t,availabilityZones:a,existingLoadBalancerNames:n,subnets:r})))}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}getAvailableSubnets(e,t){return g.listSubnets().then((a=>aa(a).filter({account:e,region:t}).reject({target:"ec2"}).reject({purpose:null}).value()))}makeSubnetOptions(e){const t=_t(e,(e=>e.purpose));return Object.keys(t).map((e=>t[e])).map((e=>(e=>{const{purpose:t,label:a,deprecated:n}=e[0];return{purpose:t,label:a,deprecated:n,vpcIds:Yt(e.map((e=>e.vpcId))),availabilityZones:Yt(e.map((e=>e.availabilityZone)))}})(e)))}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{accounts:r,availabilityZones:i,hideInternalFlag:s,regions:l,subnets:o}=this.state,c=va({"col-md-12":!0,well:!0,"alert-danger":!!t.name,"alert-info":!t.name});return $t.createElement("div",{className:"container-fluid form-horizontal"},!r&&$t.createElement("div",{style:{height:"200px"}},$t.createElement(te,{size:"medium"})),r&&$t.createElement("div",{className:"modal-body"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:c},$t.createElement("strong",null,"Your load balancer will be named: "),$t.createElement("span",null,a.name),$t.createElement(n,{id:"aws.loadBalancer.name"}),$t.createElement(tn,{type:"text",style:{display:"none"},className:"form-control input-sm no-spel",name:"name"}),t.name&&$t.createElement(de,{type:"error",message:t.name}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),$t.createElement("div",{className:"col-md-7"},$t.createElement(Ce,{value:a.credentials,onChange:e=>this.accountUpdated(e.target.value),accounts:r,provider:"aws"}))),$t.createElement(ke,{labelColumns:3,component:a,field:"region",account:a.credentials,onChange:this.regionUpdated,regions:l}),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",$t.createElement(n,{id:"aws.loadBalancer.stack"})),$t.createElement("div",{className:"col-md-3"},$t.createElement("input",{type:"text",className:"form-control input-sm no-spel "+(t.stack?"invalid":""),value:a.stack,name:"stack",onChange:this.stackChanged})),$t.createElement("div",{className:"col-md-6 form-inline"},$t.createElement("label",{className:"sm-label-right"},$t.createElement("span",null,"Detail ",$t.createElement(n,{id:"aws.loadBalancer.detail"})," ")),$t.createElement("input",{type:"text",className:"form-control input-sm no-spel "+(t.detail?"invalid":""),value:a.detail,name:"detail",onChange:this.detailChanged})),t.stack&&$t.createElement("div",{className:"col-md-7 col-md-offset-3"},$t.createElement(de,{type:"error",message:t.stack})),t.detail&&$t.createElement("div",{className:"col-md-7 col-md-offset-3"},$t.createElement(de,{type:"error",message:t.detail}))),$t.createElement(Ir,{credentials:a.credentials,region:a.region,onChange:this.handleAvailabilityZonesChanged,selectedZones:a.regionZones,allZones:i}),$t.createElement(Ar,{labelColumns:3,helpKey:"aws.loadBalancer.subnet",component:a,field:"subnetType",region:a.region,subnets:o,application:e,onChange:()=>this.handleSubnetUpdated(a.subnetType)}),a.vpcId&&!s&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},$t.createElement("b",null,"Internal")," ",$t.createElement(n,{id:"aws.loadBalancer.internal"})),$t.createElement("div",{className:"col-md-7 checkbox"},$t.createElement("label",null,$t.createElement(tn,{name:"isInternal",onChange:this.internalFlagChanged,render:({field:{value:e,...t}})=>$t.createElement("input",{type:"checkbox",...t,checked:!!e})}),"Create an internal load balancer")))))}}class zr extends $t.Component{constructor(e){super(e),this.destroy$=new ya,this.props$=new ya,this.refresh$=new ya,this.clearRemoved=()=>{this.setState({removed:[]},(()=>this.props.formik.validateForm()))},this.handleSecurityGroupsChanged=e=>{this.props.formik.setFieldValue("securityGroups",e.map((e=>e.value)))};const t=Kt(fn,"defaultSecurityGroups",[]);this.state={availableSecurityGroups:[],defaultSecurityGroups:t,loaded:!1,refreshing:!1,removed:[],refreshTime:Se.get("securityGroups").getStats().ageMax}}validate(){const{removed:e}=this.state;if(e&&e.length){return{securityGroupsRemoved:`${U.get("Firewalls")} removed: ${e.join(", ")}`}}return{}}updateRemovedSecurityGroups(e,t){const{isNew:a}=this.props,{defaultSecurityGroups:n,removed:r}=this.state,i=e=>t.find((t=>t.name===e||t.id===e)),[s,l]=na((()=>{const t=e.concat(r).sort();return Yt((a?n:[]).concat(t))})(),(e=>!!i(e))),o=s.map((e=>i(e).name));Ht(e,o)||this.props.formik.setFieldValue("securityGroups",o),this.setState({removed:l},(()=>this.props.formik.validateForm()))}onRefreshStart(){this.props.onLoadingChanged(!0),this.setState({refreshing:!0})}onRefreshComplete(){this.props.onLoadingChanged(!1);const e=Se.get("securityGroups").getStats().ageMax;this.setState({refreshing:!1,loaded:!0,refreshTime:e})}componentDidMount(){const e=this.refresh$.pipe(Aa((()=>this.onRefreshStart())),Ta((()=>h.cacheInitializer.refreshCache("securityGroups"))),Pa((()=>h.securityGroupReader.getAllSecurityGroups())),Aa((()=>this.onRefreshComplete()))),t=this.props$.pipe(Sa((e=>e.formik.values))),a=t.pipe(Sa((e=>e.vpcId)),Na());wa([a,e]).pipe(Ia(t),Sa((([[e,t],a])=>{const n=t[a.credentials]||{};return(n.aws&&n.aws[a.region]||[]).filter((t=>e===t.vpcId)).sort()}))).pipe(Ia(t),xa(this.destroy$)).subscribe((([e,t])=>{this.setState({availableSecurityGroups:e.map((e=>({label:`${e.name} (${e.id})`,value:e.name})))}),this.updateRemovedSecurityGroups(t.securityGroups,e)})),this.refresh$.next()}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{securityGroups:e}=this.props.formik.values,{availableSecurityGroups:t,loaded:a,refreshing:n,removed:r,refreshTime:i}=this.state;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",null,r.length>0&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following ",U.get("firewalls")," could not be found in the selected account/region/VPC and were removed:"),$t.createElement("ul",null,r.map((e=>$t.createElement("li",{key:e},e)))),$t.createElement("p",{className:"text-right"},$t.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:this.clearRemoved},"Okay"))))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},U.get("Firewalls")),$t.createElement("div",{className:"col-md-9"},!a&&$t.createElement("div",{style:{paddingTop:"13px"}},$t.createElement(te,{size:"small"})),a&&$t.createElement(nn,{multi:!0,value:e,options:t,onChange:this.handleSecurityGroupsChanged,clearable:!1}))),$t.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},$t.createElement("div",{className:"col-md-9 col-md-offset-3"},$t.createElement("p",null,n&&$t.createElement("span",null,$t.createElement("span",{className:"fa fa-sync-alt fa-spin"})," "),U.get("Firewalls"),!n&&$t.createElement("span",null," last refreshed ",D(i)),n&&$t.createElement("span",null," refreshing...")),$t.createElement("p",null,"If you're not finding a ",U.get("firewall")," that was recently added,"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.refresh$.next()},"click here")," ","to refresh the list.")))))}}class Br{updateHealthCounts(e){const t=e.instances;if(e.instanceCounts={up:t.filter((e=>"InService"===e.health[0].state)).length,down:t.filter((e=>"Down"===e.healthState)).length,outOfService:t.filter((e=>"OutOfService"===e.healthState)).length,starting:void 0,succeeded:void 0,failed:void 0,unknown:void 0},e.serverGroups){const t=Vt(e.serverGroups.map((e=>e.instances)));e.instanceCounts.up=t.filter((e=>"InService"===e.health[0].state)).length,e.instanceCounts.down=t.filter((e=>"Down"===e.healthState)).length,e.instanceCounts.outOfService=t.filter((e=>"OutOfService"===e.healthState)).length}}transformInstance(e,t,a,n){const r=e.health||{};"healthy"===r.state&&(r.state="InService"),e.provider=t,e.account=a,e.region=n,e.healthState=r.state?"InService"===r.state?"Up":"Down":"OutOfService",e.health=[r]}addVpcNameToContainer(e){return t=>{const a=t.find((t=>t.id===e.vpcId));return e.vpcName=a?a.name:"",e}}normalizeServerGroups(e,t,a,n){e.forEach((e=>{e.account=e.account||t.account,e.region=e.region||t.region,e.cloudProvider=e.cloudProvider||t.cloudProvider,e.detachedInstances?(e.detachedInstances=e.detachedInstances.map((e=>({id:e}))),e.instances=e.instances.concat(e.detachedInstances)):e.detachedInstances=[],e.instances.forEach((e=>{this.transformInstance(e,t.type,t.account,t.region),e[a]=[t.name],e.health.type=n})),this.updateHealthCounts(e)}))}normalizeTargetGroup(e){this.normalizeServerGroups(e.serverGroups,e,"targetGroups","TargetGroup");const t=ea(e.serverGroups,{isDisabled:!1});return e.provider=e.type,e.instances=aa(t).map("instances").flatten().value(),e.detachedInstances=aa(t).map("detachedInstances").flatten().value(),this.updateHealthCounts(e),qa.all([Pn.listVpcs(),o.listAllAccounts()]).then((([t,a])=>{const n=this.addVpcNameToContainer(e)(t);return n.serverGroups=n.serverGroups.map((e=>{const t=a.find((t=>t.name===e.account)),n=t&&t.cloudProvider||e.cloudProvider;return e.cloudProvider=n,e.instances.forEach((e=>{e.cloudProvider=n,e.provider=n})),{...e,cloudProvider:n}})),n}))}normalizeActions(e){if("application"===e.loadBalancerType){e.listeners.forEach((e=>{e.defaultActions.sort(((e,t)=>e.order-t.order)),e.rules.forEach((e=>e.actions.sort(((e,t)=>e.order-t.order))))}))}}normalizeLoadBalancer(e){this.normalizeServerGroups(e.serverGroups,e,"loadBalancers","LoadBalancer");let t=e.serverGroups;if(e.targetGroups){const a=e;a.targetGroups.forEach((e=>this.normalizeTargetGroup(e))),t=Vt(ra(a.targetGroups,"serverGroups"))}e.loadBalancerType=e.loadBalancerType||"classic",e.provider=e.type,this.normalizeActions(e);const a=ea(t,{isDisabled:!1});return e.instances=aa(a).map("instances").flatten().value(),e.detachedInstances=aa(a).map("detachedInstances").flatten().value(),this.updateHealthCounts(e),Pn.listVpcs().then((t=>this.addVpcNameToContainer(e)(t)))}static convertClassicLoadBalancerForEditing(e){const t={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,cloudProvider:e.cloudProvider,credentials:e.credentials||e.account,listeners:e.listeners,loadBalancerType:"classic",name:e.name,regionZones:e.availabilityZones,securityGroups:e.securityGroups,vpcId:e.vpcId,healthCheck:void 0,healthTimeout:e.healthTimeout,healthInterval:e.healthInterval,healthyThreshold:e.healthyThreshold,unhealthyThreshold:e.unhealthyThreshold,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckPath:e.healthCheckPath,idleTimeout:e.idleTimeout||60,subnetType:e.subnetType};if(e.elb){const a=e.elb;if(t.securityGroups=a.securityGroups,t.vpcId=a.vpcid||a.vpcId,a.listenerDescriptions&&(t.listeners=a.listenerDescriptions.map((e=>{const t=e.listener;if(t.sslcertificateId){const e=t.sslcertificateId.split("/");t.sslcertificateId=e[1],t.sslCertificateType=e[0].split(":")[2]}return{internalProtocol:t.instanceProtocol,internalPort:t.instancePort,externalProtocol:t.protocol,externalPort:t.loadBalancerPort,sslCertificateId:t.sslcertificateId,sslCertificateName:t.sslcertificateId,sslCertificateType:t.sslCertificateType,policyNames:e.policyNames}}))),a.healthCheck&&a.healthCheck.target){t.healthTimeout=a.healthCheck.timeout,t.healthInterval=a.healthCheck.interval,t.healthyThreshold=a.healthCheck.healthyThreshold,t.unhealthyThreshold=a.healthCheck.unhealthyThreshold;const e=a.healthCheck.target,n=e.indexOf(":");let r=e.indexOf("/");if(-1===r&&(r=e.length),-1!==n){t.healthCheckProtocol=e.substring(0,n);const a=Number(e.substring(n+1,r));t.healthCheckPath=e.substring(r),isNaN(a)||(t.healthCheckPort=a)}}}return t}static convertApplicationLoadBalancerForEditing(e){const t=Ee.parseLoadBalancerName(e.name).application,a={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,loadBalancerType:"application",cloudProvider:e.cloudProvider,credentials:e.account||e.credentials,listeners:[],targetGroups:[],name:e.name,regionZones:e.availabilityZones,securityGroups:[],subnetType:e.subnetType,vpcId:void 0,idleTimeout:e.idleTimeout||60,deletionProtection:e.deletionProtection||!1,ipAddressType:e.ipAddressType||"ipv4",dualstack:"dualstack"===e.ipAddressType};if(e.elb){const n=e.elb;a.securityGroups=n.securityGroups,a.vpcId=n.vpcid||n.vpcId,n.listeners&&(a.listeners=n.listeners.map((e=>{const a=[];return e.certificates&&e.certificates.forEach((e=>{const t=e.certificateArn.split(":"),n=t[5].split("/");a.push({certificateArn:e.certificateArn,type:t[2],name:n[1]})})),(e.defaultActions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,"")),e.redirectActionConfig=e.redirectConfig})),e.rules=(e.rules||[]).filter((e=>!e.default)),e.rules.forEach((e=>{(e.actions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,"")),e.redirectActionConfig=e.redirectConfig})),(e.conditions||[]).forEach((e=>{"http-request-method"===e.field&&(e.values=e.httpRequestMethodConfig.values)})),e.conditions=e.conditions||[]})),e.rules.sort(((e,t)=>e.priority-t.priority)),{protocol:e.protocol,port:e.port,defaultActions:e.defaultActions,certificates:a,rules:e.rules||[],sslPolicy:e.sslPolicy}}))),n.targetGroups&&(a.targetGroups=n.targetGroups.map((e=>({name:e.targetGroupName.replace(`${t}-`,""),protocol:e.protocol,port:e.port,targetType:e.targetType,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckPath:e.healthCheckPath,healthCheckTimeout:e.healthCheckTimeoutSeconds,healthCheckInterval:e.healthCheckIntervalSeconds,healthyThreshold:e.healthyThresholdCount,unhealthyThreshold:e.unhealthyThresholdCount,attributes:{deregistrationDelay:Number(e.attributes["deregistration_delay.timeout_seconds"]),stickinessEnabled:"true"===e.attributes["stickiness.enabled"],stickinessType:e.attributes["stickiness.type"],stickinessDuration:Number(e.attributes["stickiness.lb_cookie.duration_seconds"]),multiValueHeadersEnabled:"true"===e.attributes["lambda.multi_value_headers.enabled"]}}))))}return a}static convertNetworkLoadBalancerForEditing(e){const t=Ee.parseLoadBalancerName(e.name).application,a={availabilityZones:void 0,isInternal:e.isInternal,region:e.region,loadBalancerType:"network",cloudProvider:e.cloudProvider,credentials:e.account||e.credentials,listeners:[],targetGroups:[],name:e.name,regionZones:e.availabilityZones,securityGroups:[],subnetType:e.subnetType,vpcId:void 0,deletionProtection:e.deletionProtection,loadBalancingCrossZone:e.loadBalancingCrossZone,ipAddressType:e.ipAddressType||"ipv4",dualstack:"dualstack"===e.ipAddressType};if(e.elb){const n=e.elb;a.securityGroups=n.securityGroups,a.vpcId=n.vpcid||n.vpcId,n.listeners&&(a.listeners=n.listeners.map((e=>{const a=[];return e.certificates&&e.certificates.forEach((e=>{const t=e.certificateArn.split(":"),n=t[5].split("/");a.push({certificateArn:e.certificateArn,type:t[2],name:n[1]})})),(e.defaultActions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,""))})),e.rules=(e.rules||[]).filter((e=>!e.default)),e.rules.forEach((e=>{(e.actions||[]).forEach((e=>{e.targetGroupName&&(e.targetGroupName=e.targetGroupName.replace(`${t}-`,""))})),e.conditions=e.conditions||[]})),e.rules.sort(((e,t)=>e.priority-t.priority)),{protocol:e.protocol,port:e.port,defaultActions:e.defaultActions,certificates:a,rules:e.rules||[],sslPolicy:e.sslPolicy}}))),n.targetGroups&&(a.targetGroups=n.targetGroups.map((e=>({name:e.targetGroupName.replace(`${t}-`,""),protocol:e.protocol,port:e.port,targetType:e.targetType,healthCheckProtocol:e.healthCheckProtocol,healthCheckPort:e.healthCheckPort,healthCheckTimeout:e.healthCheckTimeoutSeconds,healthCheckInterval:e.healthCheckIntervalSeconds,healthyThreshold:e.healthyThresholdCount,unhealthyThreshold:e.unhealthyThresholdCount,healthCheckPath:e.healthCheckPath,attributes:{deregistrationDelay:Number(e.attributes["deregistration_delay.timeout_seconds"]),deregistrationDelayConnectionTermination:Boolean("true"===e.attributes["deregistration_delay.connection_termination.enabled"]),preserveClientIp:Boolean("true"===e.attributes["preserve_client_ip.enabled"])}}))))}return a}static constructNewClassicLoadBalancerTemplate(e){return{availabilityZones:void 0,name:"",stack:"",detail:"",loadBalancerType:"classic",isInternal:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||fn.defaults.account,region:e.defaultRegions.aws||fn.defaults.region,vpcId:null,subnetType:fn.defaults.subnetType,healthCheck:void 0,healthCheckProtocol:"HTTP",healthCheckPort:7001,healthCheckPath:"/healthcheck",healthTimeout:5,healthInterval:10,healthyThreshold:10,unhealthyThreshold:2,idleTimeout:60,regionZones:[],securityGroups:[],listeners:[{externalPort:80,externalProtocol:"HTTP",internalPort:7001,internalProtocol:"HTTP"}]}}static constructNewApplicationLoadBalancerTemplate(e){const t="targetgroup";return{name:"",availabilityZones:void 0,stack:"",detail:"",loadBalancerType:"application",ipAddressType:"ipv4",dualstack:!1,isInternal:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||fn.defaults.account,region:e.defaultRegions.aws||fn.defaults.region,vpcId:null,subnetType:fn.defaults.subnetType,idleTimeout:60,deletionProtection:!1,targetGroups:[{name:t,protocol:"HTTP",port:e.attributes.instancePort||a.defaultInstancePort,targetType:"instance",healthCheckProtocol:"HTTP",healthCheckPort:"traffic-port",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:2,attributes:{deregistrationDelay:300,stickinessEnabled:!1,stickinessType:"lb_cookie",stickinessDuration:8400,multiValueHeadersEnabled:!1}}],regionZones:[],securityGroups:[],listeners:[{certificates:[],protocol:"HTTP",port:80,defaultActions:[{type:"forward",targetGroupName:t}],rules:[]}]}}static constructNewNetworkLoadBalancerTemplate(e){const t="targetgroup";return{name:"",availabilityZones:void 0,stack:"",detail:"",loadBalancerType:"network",isInternal:!1,ipAddressType:"ipv4",dualstack:!1,cloudProvider:"aws",credentials:e.defaultCredentials.aws||fn.defaults.account,region:e.defaultRegions.aws||fn.defaults.region,vpcId:null,subnetType:fn.defaults.subnetType,deletionProtection:!1,loadBalancingCrossZone:!0,securityGroups:[],targetGroups:[{name:t,protocol:"TCP",port:7001,targetType:"instance",healthCheckProtocol:"TCP",healthCheckPath:"/healthcheck",healthCheckPort:"traffic-port",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:10,attributes:{deregistrationDelay:300}}],regionZones:[],listeners:[{certificates:[],protocol:"TCP",port:80,defaultActions:[{type:"forward",targetGroupName:t}],rules:[]}]}}}ar(".wizard-pod {\n padding-bottom: 15px;\n}\n.wizard-pod > div {\n border: 1px solid var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n padding: 5px;\n border-bottom: 1px solid var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row label {\n font-weight: 400;\n padding-right: 5px;\n}\n.wizard-pod .wizard-pod-row.header {\n background-color: var(--color-cirrus);\n}\n.wizard-pod .wizard-pod-row.header .glyphicon-trash {\n padding: 0 8px;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-title {\n font-weight: 800;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data {\n -ms-flex-wrap: nowrap;\n flex-wrap: nowrap;\n padding: 0;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data label {\n font-weight: 600;\n}\n.wizard-pod .wizard-pod-row.header .wizard-pod-row-contents .wizard-pod-row-data .wizard-pod-content {\n padding: 0 10px 0 0;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-title {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n max-height: 37px;\n -ms-flex-preferred-size: 120px;\n flex-basis: 120px;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: reverse;\n -ms-flex-direction: row-reverse;\n flex-direction: row-reverse;\n font-weight: 600;\n text-align: right;\n margin-right: 10px;\n width: 100px;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n -webkit-box-align: baseline;\n -ms-flex-align: baseline;\n align-items: baseline;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n -webkit-box-align: baseline;\n -ms-flex-align: baseline;\n align-items: baseline;\n -ms-flex-wrap: wrap;\n flex-wrap: wrap;\n padding: 5px 0;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data.spread {\n -webkit-box-pack: justify;\n -ms-flex-pack: justify;\n justify-content: space-between;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .wizard-pod-content {\n padding: 0 10px 5px 0;\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .group-name-prefix {\n -webkit-box-flex: 2;\n -ms-flex-positive: 2;\n flex-grow: 2;\n white-space: nowrap;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table thead th {\n font-weight: 600;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table td {\n vertical-align: middle;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-data .rules-table > tbody > tr:first-child > td {\n border-top: none;\n}\n.wizard-pod .wizard-pod-row .wizard-pod-row-contents .wizard-pod-row-errors {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n width: 100%;\n}\n.wizard-pod .listener-rule .handle {\n cursor: move;\n width: 10px;\n padding: 0;\n}\n.wizard-pod .listener-rule .listener-rule-condition {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n.wizard-pod .listener-rule .listener-rule-condition label {\n white-space: nowrap;\n}\n.wizard-pod .listener-rule .listener-rule-condition .help-field > span {\n top: 4px;\n padding: 0 2px;\n}\n.wizard-pod .listener-rule .listener-rule-condition .remove-condition {\n min-width: 15px;\n padding-top: 4px;\n}\n.wizard-pod .listener-rule .add-new-container {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n}\n.wizard-pod .listener-rule .add-new-container .add-new {\n padding: 2px;\n margin-bottom: 0;\n}\n.rule-sortable-helper {\n z-index: 99999;\n width: 500px;\n}\n");const Dr=class extends $t.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Ut(e);if(s.listeners.forEach((e=>{e.defaultActions.forEach((e=>{e.authenticateOidcConfig&&(e.authenticateOidcActionConfig=e.authenticateOidcConfig,delete e.authenticateOidcConfig)})),e.rules.forEach((e=>e.actions.forEach((e=>{e.authenticateOidcConfig&&(e.authenticateOidcActionConfig=e.authenticateOidcConfig,delete e.authenticateOidcConfig)}))))})),a)this.formatListeners(s).then((()=>{this.setIpAddressType(s),n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ne.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}};const t=e.command?e.command:e.loadBalancer?Br.convertApplicationLoadBalancerForEditing(e.loadBalancer):Br.constructNewApplicationLoadBalancerTemplate(e.app);this.state={includeSecurityGroups:!!t.vpcId,isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(Dr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{"HTTP"===a.protocol&&(delete a.sslPolicy,a.certificates=[]),a.certificates.forEach((a=>{a.certificateArn=this.certificateIdAsARN(t.accountId,a.name,e.region,a.type||this.certificateTypes[0])}))}))}))}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}addAppName(e){return`${this.props.app.name}-${e}`}manageTargetGroupNames(e){(e.targetGroups||[]).forEach((e=>{e.name=this.addAppName(e.name)})),(e.listeners||[]).forEach((e=>{e.defaultActions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))})),(e.rules||[]).forEach((e=>{e.actions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))}))}))}))}manageRules(e){e.listeners.forEach((e=>{e.rules.forEach(((e,t)=>{e.priority=t+1,e.conditions=e.conditions.filter((e=>"http-request-method"!==e.field?e.values[0].length>0:e.values.length>0))}))}))}setIpAddressType(e){e.ipAddressType=e.dualstack?"dualstack":"ipv4",delete e.dualstack}formatCommand(e){this.setAvailabilityZones(e),this.manageTargetGroupNames(e),this.manageRules(e),this.setIpAddressType(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Application Load Balancer":"Create New Application Load Balancer";return r||(l=`Edit ${i.name}: ${i.region}: ${i.credentials}`),$t.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",render:({formik:t,nextIdx:i,wizard:s})=>{const l=r||a,o=!!t.values.vpcId;return $t.createElement($t.Fragment,null,l&&$t.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>$t.createElement(Pr,{app:e,forPipelineConfig:a,formik:t,isNew:r,loadBalancer:n,ref:i})}),o&&$t.createElement(E,{label:U.get("Firewalls"),wizard:s,order:i(),render:({innerRef:e,onLoadingChanged:a})=>$t.createElement(zr,{formik:t,isNew:r,onLoadingChanged:a,ref:e})}),$t.createElement(E,{label:"Target Groups",wizard:s,order:i(),render:({innerRef:a})=>$t.createElement(Tr,{ref:a,app:e,formik:t,isNew:r,loadBalancer:n})}),$t.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:a})=>$t.createElement(wr,{ref:a,app:e,formik:t})}),$t.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>$t.createElement(cr,{ref:e})}))}})}};let $r=Dr;$r.defaultProps={closeModal:C,dismissModal:C};ar(".AmazonLoadBalancer-AdvancedSettings .StandardFieldLayout .sm-label-right {\n width: 180px;\n}\n");class Fr extends $t.Component{render(){const{values:e}=this.props.formik,{maxValue:t}=ue;return $t.createElement("div",{className:"form-group AmazonLoadBalancer-AdvancedSettings"},$t.createElement(s,{name:"healthTimeout",label:"Timeout",required:!0,help:$t.createElement(n,{id:"loadBalancer.advancedSettings.healthTimeout"}),input:t=>$t.createElement(u,{...t,min:0,max:e.healthInterval}),validate:t(e.healthInterval,"Timeout must be less than the health interval.")}),$t.createElement(s,{name:"healthInterval",label:"Interval",required:!0,help:$t.createElement(n,{id:"loadBalancer.advancedSettings.healthInterval"}),input:e=>$t.createElement(u,{...e,min:0})}),$t.createElement(s,{name:"healthyThreshold",label:"Healthy Threshold",required:!0,help:$t.createElement(n,{id:"loadBalancer.advancedSettings.healthyThreshold"}),input:e=>$t.createElement(u,{...e,min:0})}),$t.createElement(s,{name:"unhealthyThreshold",label:"Unhealthy Threshold",required:!0,help:$t.createElement(n,{id:"loadBalancer.advancedSettings.unhealthyThreshold"}),input:e=>$t.createElement(u,{...e,min:0})}),$t.createElement(s,{name:"idleTimeout",label:"Idle Timeout",required:!0,help:$t.createElement(n,{id:"loadBalancer.advancedSettings.idleTimeout"}),input:e=>$t.createElement(u,{...e,min:0})}),$t.createElement("div",{className:"col-md-12"},$t.createElement("p",null,"Additional configuration options (cross-zone load balancing, session stickiness, access logs) are available via the AWS console.")))}}class Mr extends $t.Component{constructor(){super(...arguments),this.healthCheckPathChanged=e=>{e&&0!==e.indexOf("/")&&this.props.formik.setFieldValue("healthCheckPath",`/${e}`)}}requiresHealthCheckPath(){const{values:e}=this.props.formik;return e.healthCheckProtocol&&0===e.healthCheckProtocol.indexOf("HTTP")}render(){return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"col-md-4 sm-label-right"},"Ping"),$t.createElement("div",{className:"col-md-8"},$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("thead",null,$t.createElement("tr",null,$t.createElement("th",{style:{width:"35%"}},"Protocol"),$t.createElement("th",{style:{width:"30%"}},"Port"),$t.createElement("th",null,this.requiresHealthCheckPath()&&$t.createElement("span",null,"Path")))),$t.createElement("tbody",null,$t.createElement("tr",null,$t.createElement("td",null,$t.createElement(s,{name:"healthCheckProtocol",required:!0,input:e=>$t.createElement(se,{...e,options:["HTTP","HTTPS","SSL","TCP"]})})),$t.createElement("td",null,$t.createElement(s,{name:"healthCheckPort",required:!0,input:e=>$t.createElement(u,{...e,min:1,max:65534})})),$t.createElement("td",null,this.requiresHealthCheckPath()&&$t.createElement(s,{name:"healthCheckPath",input:e=>$t.createElement(l,{...e}),required:!0,onChange:this.healthCheckPathChanged})))))))}}ar(".create-classic-load-balancer-wizard-listeners .Select-control {\n height: 30px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-placeholder {\n line-height: 26px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-value {\n line-height: 26px !important;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-value .Select-value-label {\n line-height: 26px;\n}\n.create-classic-load-balancer-wizard-listeners .Select-control .Select-input {\n height: 26px;\n}\n");class Rr extends $t.Component{constructor(){super(...arguments),this.protocols=["HTTP","HTTPS","TCP","SSL"],this.secureProtocols=["HTTPS","SSL"],this.certificateTypes=Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),this.state={certificates:[]},this.addListener=()=>{this.props.formik.values.listeners.push({internalProtocol:"HTTP",externalProtocol:"HTTP",externalPort:80,internalPort:80}),this.updateListeners()}}componentDidMount(){this.loadCertificates()}loadCertificates(){gr.listCertificates().then((e=>{this.setState({certificates:e})}))}updateListeners(){const{values:e,setFieldValue:t}=this.props.formik;t("listeners",e.listeners)}showCertificateSelect(e){return"iam"===e.sslCertificateType&&this.state.certificates&&Object.keys(this.state.certificates).length>0}listenerExternalProtocolChanged(e,t){e.externalProtocol=t,this.secureProtocols.includes(t)&&(e.externalPort=443,this.certificateTypes.length>=1&&(e.sslCertificateType=this.certificateTypes[0])),"HTTP"===t&&(e.externalPort=80),this.updateListeners()}listenerInternalProtocolChanged(e,t){e.internalProtocol=t,this.updateListeners()}listenerExternalPortChanged(e,t){e.externalPort=Number.parseInt(t,10),this.updateListeners()}listenerInternalPortChanged(e,t){e.internalPort=Number.parseInt(t,10),this.updateListeners()}listenerCertificateTypeChanged(e,t){e.sslCertificateType=t,this.updateListeners()}handleListenerCertificateChanged(e,t){e.sslCertificateName=t,this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}renderCertificateSelector(e){if(this.secureProtocols.includes(e.externalProtocol)){if(this.showCertificateSelect(e)){const{values:t}=this.props.formik,{certificates:a}=this.state;return $t.createElement(vr,{certificates:a,accountName:t.credentials,currentValue:e.sslCertificateName,app:this.props.app,onCertificateSelect:t=>this.handleListenerCertificateChanged(e,t)})}return $t.createElement("input",{className:"input-sm",style:{width:"100%",marginLeft:"10px"},required:!0,onChange:t=>this.handleListenerCertificateChanged(e,t.target.value),value:e.sslCertificateName})}return null}render(){const{values:e}=this.props.formik;return $t.createElement("div",{className:"container-fluid form-horizontal create-classic-load-balancer-wizard-listeners"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("thead",null,$t.createElement("tr",null,$t.createElement("th",null,"External Protocol"),$t.createElement("th",null,"External Port"),$t.createElement("th",null),$t.createElement("th",null,"Internal Protocol"),$t.createElement("th",null,"Internal Port"),$t.createElement("th",null))),$t.createElement("tbody",null,e.listeners.map(((e,t)=>$t.createElement($t.Fragment,{key:t},$t.createElement("tr",{key:t+"-main"},$t.createElement("td",null,$t.createElement("select",{className:"form-control input-sm",value:e.externalProtocol,onChange:t=>this.listenerExternalProtocolChanged(e,t.target.value)},this.protocols.map((e=>$t.createElement("option",{key:e},e))))),$t.createElement("td",null,$t.createElement("input",{className:"form-control input-sm",type:"number",min:"0",value:e.externalPort,onChange:t=>this.listenerExternalPortChanged(e,t.target.value),required:!0})),$t.createElement("td",{className:"small",style:{paddingTop:"10px"}},"→"),$t.createElement("td",null,$t.createElement("select",{className:"form-control input-sm",value:e.internalProtocol,onChange:t=>this.listenerInternalProtocolChanged(e,t.target.value)},this.protocols.map((e=>$t.createElement("option",{key:e},e))))),$t.createElement("td",null,$t.createElement("input",{className:"form-control input-sm",type:"number",min:"0",value:e.internalPort,onChange:t=>this.listenerInternalPortChanged(e,t.target.value),required:!0})),$t.createElement("td",null,$t.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(t)},$t.createElement("span",{className:"glyphicon glyphicon-trash"})))),this.secureProtocols.includes(e.externalProtocol)&&$t.createElement("tr",{key:t+"-ssl"},$t.createElement("td",{colSpan:5,style:{borderTopWidth:0}},$t.createElement("div",{className:"horizontal space-between"},$t.createElement("div",{className:"sm-label-right"},"Certificate"),this.certificateTypes.length>1&&$t.createElement("select",{style:{width:"45px",marginLeft:"10px"},className:"form-control input-sm",value:e.sslCertificateType,onChange:t=>this.listenerCertificateTypeChanged(e,t.target.value)},this.certificateTypes.map((e=>$t.createElement("option",{key:e},e)))),this.renderCertificateSelector(e)))))))),$t.createElement("tfoot",null,$t.createElement("tr",null,$t.createElement("td",{colSpan:5},$t.createElement("button",{className:"add-new col-md-12",onClick:this.addListener,type:"button"},$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"}),$t.createElement("span",null," Add new port mapping")))))))))}}const Lr=class extends $t.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Ut(e);if(a)this.formatListeners(s).then((()=>{n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ne.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}},this.validate=e=>({});const t=e.command?e.command:e.loadBalancer?Br.convertClassicLoadBalancerForEditing(e.loadBalancer):Br.constructNewClassicLoadBalancerTemplate(e.app);this.state={isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(Lr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{a.sslCertificateId=this.certificateIdAsARN(t.accountId,a.sslCertificateName,e.region,a.sslCertificateType||this.certificateTypes[0])}))}))}clearSecurityGroupsIfNotInVpc(e){e.vpcId||e.subnetType||(e.securityGroups=null)}addHealthCheckToCommand(e){let t=null;const a=e.healthCheckProtocol||"";t=a.startsWith("HTTP")?`${a}:${e.healthCheckPort}${e.healthCheckPath}`:`${a}:${e.healthCheckPort}`,e.healthCheck=t}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}formatCommand(e){this.setAvailabilityZones(e),this.clearSecurityGroupsIfNotInVpc(e),this.addHealthCheckToCommand(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state,l=r||a;let o=a?"Configure Classic Load Balancer":"Create New Classic Load Balancer";return r||(o=`Edit ${i.name}: ${i.region}: ${i.credentials}`),$t.createElement(w,{heading:o,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",validate:this.validate,render:({formik:t,nextIdx:i,wizard:s})=>$t.createElement($t.Fragment,null,l&&$t.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>$t.createElement(Pr,{app:e,formik:t,isNew:r,forPipelineConfig:a,loadBalancer:n,ref:i})}),!!t.values.vpcId&&$t.createElement(E,{label:U.get("Firewall"),wizard:s,order:i(),render:({innerRef:e,onLoadingChanged:a})=>$t.createElement(zr,{formik:t,isNew:r,onLoadingChanged:a,ref:e})}),$t.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:a})=>$t.createElement(Rr,{ref:a,formik:t,app:e})}),$t.createElement(E,{label:"Health Check",wizard:s,order:i(),render:({innerRef:e})=>$t.createElement(Mr,{ref:e,formik:t})}),$t.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>$t.createElement(Fr,{ref:e,formik:t})}))})}};let Or=Lr;Or.defaultProps={closeModal:C,dismissModal:C};const Ur=$t.forwardRef(((e,t)=>$t.createElement("div",{ref:t},$t.createElement(s,{name:"deletionProtection",label:"Protection",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.deletionProtection"}),input:e=>$t.createElement(d,{...e,text:"Enable deletion protection"})}),$t.createElement(s,{name:"loadBalancingCrossZone",label:"Cross-Zone Load Balancing",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.loadBalancingCrossZone"}),input:e=>$t.createElement(d,{...e,text:"Distribute traffic across zones"})}),e.showDualstack&&$t.createElement(s,{name:"dualstack",label:"Dualstack",help:$t.createElement(n,{id:"loadBalancer.advancedSettings.nlbIpAddressType"}),input:e=>$t.createElement(d,{...e,text:"Assign Ipv4 and IPv6"})}))));function Vr({availableCertificates:e,certificates:t,formik:a,app:n,certificateTypes:r}){function i(){a.setFieldValue("listeners",a.values.listeners)}function s(e,t){e.name=t,i()}function l(e){return"iam"===e.type&&t&&Object.keys(t).length>0}const{values:o}=a;return $t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Certificate"),$t.createElement("div",{className:"wizard-pod-row-contents"},e.map(((e,a)=>$t.createElement("div",{key:a,style:{width:"100%",display:"flex",flexDirection:"row"}},$t.createElement("select",{className:"form-control input-sm inline-number",style:{width:"45px"},value:e.type,onChange:t=>function(e,t){e.type=t,i()}(e,t.target.value)},r.map((e=>$t.createElement("option",{key:e},e)))),l(e)&&$t.createElement(vr,{certificates:t,accountName:o.credentials,currentValue:e.name,app:n,onCertificateSelect:t=>s(e,t)}),!l(e)&&$t.createElement("input",{className:"form-control input-sm no-spel",style:{display:"inline-block"},type:"text",value:e.name,onChange:t=>s(e,t.target.value),required:!0}))))))}class qr extends $t.Component{constructor(e){super(e),this.protocols=["TCP","UDP","TLS"],this.removedAuthActions=new Map,this.addListener=()=>{this.props.formik.values.listeners.push({certificates:[],protocol:"TCP",port:80,defaultActions:[{type:"forward",targetGroupName:""}],rules:[]}),this.updateListeners()},this.handleDefaultTargetChanged=(e,t)=>{e.defaultActions[0].targetGroupName=t,this.updateListeners()},this.state={certificates:[],certificateTypes:Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),oidcConfigs:void 0}}getAllTargetGroupsFromListeners(e){const t=Vt(e.map((e=>e.defaultActions))),a=Vt(e.map((e=>e.rules)));return t.push(...Vt(a.map((e=>e.actions)))),Yt(t.map((e=>e.targetGroupName)))}validate(e){const t={},a=e.targetGroups.map((e=>e.name)),n=this.getAllTargetGroupsFromListeners(e.listeners),r=Xt(a,n);1===r.length?t.listeners=`Target group ${r[0]} is unused.`:r.length>1&&(t.listeners=`Target groups ${r.join(", ")} are unused.`);const{listeners:i}=e;return Ot(i,"port").length<i.length&&(t.listenerPorts="Multiple listeners cannot use the same port."),t}updateListeners(){this.props.formik.setFieldValue("listeners",this.props.formik.values.listeners)}componentDidMount(){this.loadCertificates()}addListenerCertificate(e){e.certificates=e.certificates||[],e.certificates.push({certificateArn:void 0,type:"iam",name:void 0})}loadCertificates(){gr.listCertificates().then((e=>{this.setState({certificates:e})}))}listenerProtocolChanged(e,t){e.protocol=t,"TCP"===e.protocol?e.port=80:"UDP"===e.protocol?e.port=53:"TLS"===e.protocol&&(e.port=443,e.certificates&&0!==e.certificates.length||this.addListenerCertificate(e),this.reenableAuthActions(e)),this.updateListeners()}reenableAuthActions(e){const t=this.removedAuthActions.has(e)?this.removedAuthActions.get(e):[],a=t[-1];a&&(t[-1]=void 0,e.defaultActions.unshift({...a})),e.rules.forEach(((e,a)=>{const n=t[a];t[a]=void 0,n&&e.actions.unshift({...n})}))}listenerPortChanged(e,t){e.port=Number.parseInt(t,10),this.updateListeners()}removeListener(e){this.props.formik.values.listeners.splice(e,1),this.updateListeners()}render(){const{errors:e,values:t}=this.props.formik,{certificates:a,certificateTypes:n}=this.state;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},t.listeners.map(((e,r)=>$t.createElement("div",{key:r,className:"wizard-pod"},$t.createElement("div",null,$t.createElement("div",{className:"wizard-pod-row header"},$t.createElement("div",{className:"wizard-pod-row-title"},"Listen On"),$t.createElement("div",{className:"wizard-pod-row-contents spread"},$t.createElement("div",null,$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol"),$t.createElement("select",{className:"form-control input-sm inline-number",style:{width:"80px"},value:e.protocol,onChange:t=>this.listenerProtocolChanged(e,t.target.value)},this.protocols.map((e=>$t.createElement("option",{key:e},e))))),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port"),$t.createElement("input",{className:"form-control input-sm inline-number",type:"text",min:0,value:e.port||"",onChange:t=>this.listenerPortChanged(e,t.target.value),style:{width:"80px"},required:!0}))),$t.createElement("div",null,$t.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeListener(r)},$t.createElement("span",{className:"glyphicon glyphicon-trash"}))))),$t.createElement("div",null,"TLS"===e.protocol&&$t.createElement(Vr,{availableCertificates:e.certificates,formik:this.props.formik,app:this.props.app,certificateTypes:n,certificates:a})),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title",style:{height:"30px"}},"Rules"),$t.createElement("div",{className:"wizard-pod-row-contents",style:{padding:"0"}},$t.createElement("table",{className:"table table-condensed packed rules-table"},$t.createElement("thead",null,$t.createElement("tr",null,$t.createElement("th",{style:{width:"10px",padding:"0"}}),$t.createElement("th",{style:{width:"226px"}},"If"),$t.createElement("th",{style:{width:"75px"}},"Then"),$t.createElement("th",null,"Target"),$t.createElement("th",{style:{width:"30px"}}))),$t.createElement("tbody",null,$t.createElement("tr",{className:"not-sortable"},$t.createElement("td",null),$t.createElement("td",null,"Default"),$t.createElement("td",null,"forward to"),$t.createElement("td",null,$t.createElement("select",{className:"form-control input-sm",value:e.defaultActions[0].targetGroupName,onChange:t=>this.handleDefaultTargetChanged(e,t.target.value),required:!0},$t.createElement("option",{value:""}),Yt(t.targetGroups.map((e=>e.name))).map((e=>$t.createElement("option",{key:e},e))))),$t.createElement("td",null)))))))))),e.listenerPorts&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:e.listenerPorts})),e.listeners&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:e.listeners})),$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("tbody",null,$t.createElement("tr",null,$t.createElement("td",null,$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addListener},$t.createElement("span",null,$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new listener")))))))))}}class jr extends $t.Component{constructor(e){super(e),this.protocols=["TCP","UDP"],this.healthProtocols=["TCP","HTTP","HTTPS"],this.targetTypes=["instance","ip"],this.destroy$=new ya,this.addTargetGroup=()=>{const{setFieldValue:e,values:t}=this.props.formik,a=t.targetGroups.length;t.targetGroups.push({name:"targetgroup"+(a?`${a}`:""),protocol:"TCP",port:7001,targetType:"instance",healthCheckProtocol:"TCP",healthCheckPort:"traffic-port",healthCheckPath:"/healthcheck",healthCheckTimeout:5,healthCheckInterval:10,healthyThreshold:10,unhealthyThreshold:10,attributes:{deregistrationDelay:300,preserveClientIp:!0}}),e("targetGroups",t.targetGroups)};const t=e.isNew?0:e.formik.initialValues.targetGroups.length;this.state={existingTargetGroupNames:{},oldTargetGroupCount:t}}validate(e){const t=Yt(Vt(ea(_t(e.targetGroups,"name"),(e=>e.length>1))).map((e=>e.name))),a=new i(e),{arrayForEach:n}=a;return a.field("targetGroups").withValidators(n((a=>{a.field("name","Name").required().withValidators(Nr(this.state.existingTargetGroupNames,e.credentials,e.region),Gr(this.props.app.name.length),ue.valueUnique(t,"There is already a target group in this load balancer with the same name.")),a.field("port","Port").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckInterval","Health Check Interval").required().spelAware().withValidators((e=>me(e))),a.field("healthyThreshold","Healthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("unhealthyThreshold","Unhealthy Threshold").required().spelAware().withValidators((e=>me(e))),a.field("healthCheckPort","Health Check Port").required().spelAware().withValidators((e=>"traffic-port"===e?null:me(e))),a.field("protocol","Protocol").required(),a.field("healthCheckProtocol","Health Check Protocol").required()}))),a.validateForm()}removeAppName(e){return e.replace(`${this.props.app.name}-`,"")}updateLoadBalancerNames(e){const{app:t,loadBalancer:a}=e,n={};ba(t.getDataSource("loadBalancers").refresh(!0)).pipe(xa(this.destroy$)).subscribe((()=>{t.getDataSource("loadBalancers").data.forEach((e=>{"classic"!==e.loadBalancerType&&(a&&e.name===a.name||e.targetGroups.forEach((t=>{n[e.account]=n[e.account]||{},n[e.account][e.region]=n[e.account][e.region]||[],n[e.account][e.region].push(this.removeAppName(t.name))})))})),this.setState({existingTargetGroupNames:n},(()=>this.props.formik.validateForm()))}))}targetGroupFieldChanged(e,t,a){const{setFieldValue:n,values:r}=this.props.formik,i=r.targetGroups[e];ta(i,t,a),"healthyThreshold"===t&&ta(i,"unhealthyThreshold",a),n("targetGroups",r.targetGroups)}removeTargetGroup(e){const{setFieldValue:t,values:a}=this.props.formik,{oldTargetGroupCount:n}=this.state;a.targetGroups.splice(e,1),e<n&&this.setState({oldTargetGroupCount:n-1}),t("targetGroups",a.targetGroups)}componentDidMount(){this.updateLoadBalancerNames(this.props)}componentWillUnmount(){this.destroy$.next(),this.destroy$.complete()}render(){const{app:e}=this.props,{errors:t,values:a}=this.props.formik,{oldTargetGroupCount:r}=this.state,i=this.protocols.map((e=>$t.createElement("option",{key:e},e))),s=this.healthProtocols.map((e=>$t.createElement("option",{key:e},e))),l=this.targetTypes.map((e=>$t.createElement("option",{key:e},e)));return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},a.targetGroups.map(((a,o)=>{const c=t.targetGroups&&t.targetGroups[o]||{};return $t.createElement("div",{key:o,className:"wizard-pod"},$t.createElement("div",null,$t.createElement("div",{className:"wizard-pod-row header"},$t.createElement("div",{className:"wizard-pod-row-title"},"Group Name"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"group-name-prefix"},e.name,"-"),$t.createElement("input",{className:"form-control input-sm target-group-name",type:"text",value:a.name,onChange:e=>this.targetGroupFieldChanged(o,"name",e.target.value),required:!0,disabled:o<r}),$t.createElement("a",{className:"sm-label clickable",onClick:()=>this.removeTargetGroup(o)},$t.createElement("span",{className:"glyphicon glyphicon-trash"}))),c.name&&$t.createElement("div",{className:"wizard-pod-row-errors"},$t.createElement(de,{type:"error",message:c.name})))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},$t.createElement(n,{id:"aws.targetGroup.targetType"})," ",$t.createElement("span",null,"Target Type ")),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("select",{className:"form-control input-sm",value:a.targetType,onChange:e=>this.targetGroupFieldChanged(o,"targetType",e.target.value),disabled:o<r},l))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Backend Connection"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol "),$t.createElement(n,{id:"aws.targetGroup.protocol"})," ",$t.createElement("select",{className:"form-control input-sm inline-number",value:a.protocol,onChange:e=>this.targetGroupFieldChanged(o,"protocol",e.target.value),disabled:o<r},i)),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port "),$t.createElement(n,{id:"aws.targetGroup.port"})," ",$t.createElement("input",{className:"form-control input-sm inline-number",value:a.port,onChange:e=>this.targetGroupFieldChanged(o,"port",e.target.value),type:"text",required:!0,disabled:o<r}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Healthcheck"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Protocol "),$t.createElement("select",{disabled:o<r,className:"form-control input-sm inline-number",value:a.healthCheckProtocol,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckProtocol",e.target.value)},s)),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Port "),$t.createElement(ge,{className:"form-control input-sm inline-number",error:c.healthCheckPort,name:"healthCheckPort",required:!0,value:a.healthCheckPort,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckPort",e.target.value)})),"TCP"!==a.healthCheckProtocol&&$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Path "),$t.createElement(ge,{className:"form-control input-sm inline-text",error:c.healthCheckPath,name:"healthCheckPath",required:!0,value:a.healthCheckPath,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckPath",e.target.value)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Timeout "),$t.createElement(he,{error:c.healthCheckTimeout,required:!0,value:a.healthCheckTimeout,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckTimeout",e)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Interval "),$t.createElement(he,{error:c.healthCheckInterval,required:!0,value:a.healthCheckInterval,onChange:e=>this.targetGroupFieldChanged(o,"healthCheckInterval",e)}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},$t.createElement(n,{id:"aws.targetGroup.nlbHealthcheckThreshold"})," ",$t.createElement("span",null,"Healthcheck Threshold ")),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement(he,{error:c.healthyThreshold,value:a.healthyThreshold,onChange:e=>this.targetGroupFieldChanged(o,"healthyThreshold",e)}))))),$t.createElement("div",{className:"wizard-pod-row"},$t.createElement("div",{className:"wizard-pod-row-title"},"Attributes"),$t.createElement("div",{className:"wizard-pod-row-contents"},$t.createElement("div",{className:"wizard-pod-row-data"},$t.createElement("span",{className:"wizard-pod-content"},$t.createElement("label",null,"Dereg. Delay"),$t.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelay"})," ",$t.createElement("input",{className:"form-control input-sm inline-number",type:"text",value:a.attributes.deregistrationDelay,onChange:e=>this.targetGroupFieldChanged(o,"attributes.deregistrationDelay",e.target.value)})),$t.createElement("span",{className:"wizard-pod-content"},$t.createElement(d,{name:"deregistrationDelayConnectionTermination",text:"Connection Termination",checked:a.attributes.deregistrationDelayConnectionTermination,onChange:e=>{this.targetGroupFieldChanged(o,"attributes.deregistrationDelayConnectionTermination",e.target.checked)}}),$t.createElement(n,{id:"aws.targetGroup.attributes.deregistrationDelayConnectionTermination"})),"instance"!==a.targetType&&$t.createElement("span",{className:"wizard-pod-content"},$t.createElement(d,{name:"preserveClientIp",text:"Preserve Client IP",checked:a.attributes.preserveClientIp,onChange:e=>{this.targetGroupFieldChanged(o,"attributes.preserveClientIp",e.target.checked)}}),$t.createElement(n,{id:"aws.targetGroup.attributes.preserveClientIp"})))))))})),$t.createElement("table",{className:"table table-condensed packed"},$t.createElement("tbody",null,$t.createElement("tr",null,$t.createElement("td",null,$t.createElement("button",{type:"button",className:"add-new col-md-12",onClick:this.addTargetGroup},$t.createElement("span",{className:"glyphicon glyphicon-plus-sign"})," Add new target group"))))))))}}const Hr=class extends $t.Component{constructor(e){super(e),this._isUnmounted=!1,this.certificateTypes=Kt(fn,"loadBalancers.certificateTypes",["iam","acm"]),this.submit=e=>{const{app:t,forPipelineConfig:a,closeModal:n}=this.props,{isNew:r}=this.state,i=r?"Create":"Update",s=Ut(e);if(s.ipAddressType=s.dualstack?"dualstack":"ipv4",delete s.dualstack,a)this.formatListeners(s).then((()=>{n&&n(s)}));else{const e=new v({application:t,title:(r?"Creating":"Updating")+" your load balancer",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.onTaskComplete(s)});e.submit((()=>this.formatListeners(s).then((()=>(this.formatCommand(s),Ne.upsertLoadBalancer(s,t,i)))))),this.setState({taskMonitor:e})}},this.validate=()=>({});const t=e.loadBalancer?Br.convertNetworkLoadBalancerForEditing(e.loadBalancer):Br.constructNewNetworkLoadBalancerTemplate(e.app);this.state={isNew:!e.loadBalancer,loadBalancerCommand:t,taskMonitor:null}}static show(e){return b.show(Hr,e,{dialogClassName:"wizard-modal modal-lg"})}certificateIdAsARN(e,t,a,n){if(t&&(0!==t.indexOf("arn:aws:iam::")||0!==t.indexOf("arn:aws:acm:"))){if("iam"===n)return`arn:aws:iam::${e}:server-certificate/${t}`;if("acm"===n)return`arn:aws:acm:${a}:${e}:certificate/${t}`}return t}formatListeners(e){return o.getAccountDetails(e.credentials).then((t=>{e.listeners.forEach((a=>{"TCP"===a.protocol&&(delete a.sslPolicy,a.certificates=[]),a.certificates.forEach((a=>{a.certificateArn=this.certificateIdAsARN(t.accountId,a.name,e.region,a.type||this.certificateTypes[0])}))}))}))}setAvailabilityZones(e){const t={};t[e.region]=e.regionZones||[],e.availabilityZones=t}addAppName(e){return`${this.props.app.name}-${e}`}manageTargetGroupNames(e){(e.targetGroups||[]).forEach((e=>{e.name=this.addAppName(e.name)})),(e.listeners||[]).forEach((e=>{e.defaultActions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))})),(e.rules||[]).forEach((e=>{e.actions.forEach((e=>{e.targetGroupName&&(e.targetGroupName=this.addAppName(e.targetGroupName))}))}))}))}manageRules(e){e.listeners.forEach((e=>{e.rules.forEach(((e,t)=>{e.priority=t+1,e.conditions=e.conditions.filter((e=>e.values[0].length>0))}))}))}formatCommand(e){this.setAvailabilityZones(e),this.manageTargetGroupNames(e),this.manageRules(e)}onApplicationRefresh(e){if(this._isUnmounted)return;this.refreshUnsubscribe=void 0,this.props.dismissModal(),this.setState({taskMonitor:void 0});const t={name:e.name,accountId:e.credentials,region:e.region,vpcId:e.vpcId,provider:"aws"};h.$state.includes("**.loadBalancerDetails")?h.$state.go("^.loadBalancerDetails",t):h.$state.go(".loadBalancerDetails",t)}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}onTaskComplete(e){this.props.app.loadBalancers.refresh(),this.refreshUnsubscribe=this.props.app.loadBalancers.onNextRefresh(null,(()=>this.onApplicationRefresh(e)))}render(){const{app:e,dismissModal:t,forPipelineConfig:a,loadBalancer:n}=this.props,{isNew:r,loadBalancerCommand:i,taskMonitor:s}=this.state;let l=a?"Configure Network Load Balancer":"Create New Network Load Balancer";r||(l=`Edit ${i.name}: ${i.region}: ${i.credentials}`);const o=r||a;return $t.createElement(w,{heading:l,initialValues:i,taskMonitor:s,dismissModal:t,closeModal:this.submit,submitButtonLabel:a?r?"Add":"Done":r?"Create":"Update",validate:this.validate,render:({formik:t,nextIdx:i,wizard:s})=>$t.createElement($t.Fragment,null,o&&$t.createElement(E,{label:"Location",wizard:s,order:i(),render:({innerRef:i})=>$t.createElement(Pr,{app:e,forPipelineConfig:a,formik:t,isNew:r,loadBalancer:n,ref:i})}),$t.createElement(E,{label:"Target Groups",wizard:s,order:i(),render:({innerRef:a})=>$t.createElement(jr,{ref:a,formik:t,app:e,isNew:r,loadBalancer:n})}),$t.createElement(E,{label:"Listeners",wizard:s,order:i(),render:({innerRef:e})=>$t.createElement(qr,{ref:e,formik:t})}),$t.createElement(E,{label:"Advanced Settings",wizard:s,order:i(),render:({innerRef:e})=>$t.createElement(Ur,{ref:e,showDualstack:!t.values.isInternal&&ia(t.values.targetGroups,{targetType:"instance"})})}))})}};let Wr=Hr;Wr.defaultProps={closeModal:C,dismissModal:C};const Zr=[{type:"application",label:"Application",sublabel:"ALB",description:"Highly configurable, application-focused balancer. HTTP and HTTPS only.",component:$r},{type:"network",label:"Network",sublabel:"NLB",description:"Basic, high-performance balancer with fixed IP.",component:Wr},{type:"classic",label:"Classic",sublabel:"Legacy",description:"Previous generation balancer (ELB).",component:Or}],_r=class extends $t.Component{constructor(e){super(e),this.choose=()=>{const{children:e,...t}=this.props;this.close(),this.state.selectedChoice.component.show(t).then((e=>{this.props.closeModal(e)})).catch((()=>{}))},this.close=e=>{this.props.dismissModal(e)},this.state={choices:Zr,selectedChoice:Zr[0]}}static show(e){return b.show(_r,{...e,className:"create-pipeline-modal-overflow-visible modal-lg"},{bsSize:"lg"})}choiceSelected(e){this.setState({selectedChoice:e})}getIncompatibility(e,t){const{loadBalancer:a={}}=O.getProvider(t),{incompatibleLoadBalancerTypes:n=[]}=a;return n.find((t=>t.type===e.type))}isIncompatibleWithAllProviders(e){const{app:{attributes:t}}=this.props,{cloudProviders:a=[]}=t;return a.length>0&&a.every((t=>!!this.getIncompatibility(e,t)))}render(){const{app:{attributes:e}}=this.props,{cloudProviders:t=[]}=e,{choices:a,selectedChoice:n}=this.state,r=a.filter((e=>!this.isIncompatibleWithAllProviders(e))),i=t.map((e=>this.getIncompatibility(n,e))).filter((e=>e)),s=fn.createLoadBalancerWarnings&&fn.createLoadBalancerWarnings[n.type];return $t.createElement($t.Fragment,null,$t.createElement(re,{dismiss:this.close}),$t.createElement(Fa.Header,null,$t.createElement(Fa.Title,null,"Select Type of Load Balancer")),$t.createElement(Fa.Body,null,$t.createElement("div",{className:"modal-body"},$t.createElement("div",{className:"card-choices"},r.map((e=>$t.createElement("div",{key:e.type,className:"card "+(n===e?"active":""),onClick:()=>this.choiceSelected(e)},$t.createElement("h3",{className:"load-balancer-label"},e.label),$t.createElement("h3",null,"(",e.sublabel,")"),$t.createElement("div",null,e.description))))),$t.createElement($t.Fragment,null,i.length>0&&i.map((e=>$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"})," ",e.reason))))),!!s&&$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"}),$t.createElement(we,{message:s,style:{display:"inline-block",marginLeft:"2px"}}))),$t.createElement("div",{className:"load-balancer-description"}))),$t.createElement(Fa.Footer,null,$t.createElement(Ma,{onClick:this.choose},"Configure Load Balancer ",$t.createElement("span",{className:"glyphicon glyphicon-chevron-right"}))))}};let Kr=_r;Kr.defaultProps={closeModal:C,dismissModal:C};class Yr extends $t.Component{constructor(e){super(e),this.editLoadBalancer=()=>{const{loadBalancer:e}=this.props,{application:t}=this.state;Zr.find((t=>t.type===e.loadBalancerType)).component.show({app:t,loadBalancer:e})},this.deleteLoadBalancer=()=>{const{app:e,loadBalancer:t,loadBalancerFromParams:a}=this.props;if(t.instances&&t.instances.length)return;const n={application:e,title:"Deleting "+a.name},r={cloudProvider:t.cloudProvider,loadBalancerName:t.name,loadBalancerType:t.loadBalancerType||"classic",regions:[t.region],credentials:t.account,vpcId:Kt(t,"elb.vpcId",null)};k.confirm({header:`Really delete ${a.name} in ${a.region}: ${a.accountId}?`,buttonText:`Delete ${a.name}`,account:a.accountId,taskMonitorConfig:n,submitMethod:()=>Ne.deleteLoadBalancer(r,e)})},this.entityTagUpdate=()=>{this.props.app.loadBalancers.refresh()};const{app:t,loadBalancer:a}=this.props;let n;const r=a.name.split("-")[0];r===t.name?n=t:S.getApplication(r).then((e=>{this.setState({application:e})})).catch((()=>{})),this.state={application:n}}render(){const{app:e,loadBalancer:t}=this.props,{application:r}=this.state,{loadBalancerType:i,instances:s,instanceCounts:l}=t,o=t.name.split("-")[0],c=!("classic"===i&&sa(l).filter((e=>e)).length)&&!s.length;return $t.createElement("div",{style:{display:"inline-block"}},$t.createElement($a,{className:"dropdown",id:"load-balancer-actions-dropdown"},$t.createElement($a.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},$t.createElement("span",null,"Load Balancer Actions")),$t.createElement($a.Menu,{className:"dropdown-menu"},r&&$t.createElement(Ge,{resource:t,application:e,onClick:this.editLoadBalancer},"Edit Load Balancer"),!r&&$t.createElement("li",{className:"disabled"},$t.createElement("a",null,"Edit Load Balancer"," ",$t.createElement(n,{content:`The application <b>${o}</b> must be configured before this load balancer can be edited.`}))),c&&$t.createElement(Ge,{resource:t,application:e,onClick:this.deleteLoadBalancer},"Delete Load Balancer"),!c&&$t.createElement("li",{className:"disabled"},$t.createElement("a",null,"Delete Load Balancer"," ",$t.createElement(n,{content:"You must detach all instances before you can delete this load balancer."}))),a&&a.feature.entityTags&&$t.createElement(N,{component:t,application:e,entityType:"loadBalancer",onUpdate:this.entityTagUpdate}))))}}const Xr="spinnaker.amazon.loadBalancer.details.loadBalancerActions.component";t(Xr,[]).component("loadBalancerActions",ja(M(Yr,"loadBalancerActions"),["app","loadBalancer","loadBalancerFromParams"]));class Qr{constructor(e,t,n,r,i,s,l){this.$scope=e,this.$state=t,this.$q=n,this.app=i,this.securityGroupReader=s,this.loadBalancerReader=l,this.state={loading:!0},this.firewallsLabel=U.get("Firewalls"),this.oidcConfigPath=a.oidcConfigPath,this.application=i,this.loadBalancerFromParams=r,this.app.ready().then((()=>this.extractLoadBalancer())).then((()=>{e.$$destroyed||i.getDataSource("loadBalancers").onRefresh(e,(()=>this.extractLoadBalancer()))}))}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}extractLoadBalancer(){const e=this.app.loadBalancers.data.find((e=>e.name===this.loadBalancerFromParams.name&&e.region===this.loadBalancerFromParams.region&&e.account===this.loadBalancerFromParams.accountId));if(e){return this.loadBalancerReader.getLoadBalancerDetails("aws",this.loadBalancerFromParams.accountId,this.loadBalancerFromParams.region,this.loadBalancerFromParams.name).then((t=>{this.loadBalancer=e,this.state.loading=!1;const a=[];if(t.length){this.loadBalancer.elb=t[0],this.loadBalancer.elb.vpcId=this.loadBalancer.elb.vpcId||this.loadBalancer.elb.vpcid,this.loadBalancer.account=this.loadBalancerFromParams.accountId;const e=t[0];if("application"===e.loadBalancerType||"network"===e.loadBalancerType){const e=t[0];e.listeners&&e.listeners.length&&(this.elbProtocol="http:",e.listeners.some((e=>"HTTPS"===e.protocol))&&(this.elbProtocol="https:"),this.listeners=[],e.listeners.forEach((e=>{e.defaultActions.sort(((e,t)=>e.order-t.order)),e.rules.forEach((e=>e.actions.sort(((e,t)=>e.order-t.order))))})),e.listeners.forEach((e=>{e.rules.map((t=>{let a=[e.protocol,(t.conditions.find((e=>"host-header"===e.field))||{values:[""]}).values[0],e.port].filter((e=>e)).join(":");const n=(t.conditions.find((e=>"path-pattern"===e.field))||{values:[]}).values[0];n&&(a=`${a}${n}`);const r=t.actions.map((e=>{const t={...e};return"forward"===t.type&&(t.targetGroup=this.loadBalancer.targetGroups.find((e=>e.name===t.targetGroupName))),t}));this.listeners.push({in:a,actions:r})}))}))),"dualstack"===e.ipAddressType&&(this.ipAddressTypeDescription="IPv4 and IPv6"),"ipv4"===e.ipAddressType&&(this.ipAddressTypeDescription="IPv4")}else{const e=t[0];e.listenerDescriptions&&(this.elbProtocol="http:",e.listenerDescriptions.some((e=>"HTTPS"===e.listener.protocol))&&(this.elbProtocol="https:"))}(this.loadBalancer.elb.securityGroups||[]).forEach((e=>{const t=this.securityGroupReader.getApplicationSecurityGroup(this.app,this.loadBalancerFromParams.accountId,this.loadBalancerFromParams.region,e);t&&a.push(t)})),this.securityGroups=Wt(a,"name"),this.loadBalancer.subnets&&(this.loadBalancer.subnetDetails=this.loadBalancer.subnets.reduce(((e,t)=>(g.getSubnetByIdAndProvider(t,this.loadBalancer.provider).then((t=>{e.push(t)})),e)),[]))}}),(()=>this.autoClose()))}return this.autoClose(),this.loadBalancer||this.autoClose(),this.$q.when(null)}getFirstSubnetPurpose(e=[]){return la(e.map((e=>e.purpose)))||""}}Qr.$inject=["$scope","$state","$q","loadBalancer","app","securityGroupReader","loadBalancerReader"];t("spinnaker.amazon.loadBalancer.details.controller",[_a,Te,Xr,Ie,xe]).controller("awsLoadBalancerDetailsCtrl",Qr);class Jr{constructor(e,t,a,n,r){this.$scope=e,this.$q=t,this.$state=a,this.app=r,this.state={loading:!0},this.application=r,this.targetGroupFromParams=n,this.app.ready().then((()=>this.extractTargetGroup())).then((()=>{e.$$destroyed||r.getDataSource("loadBalancers").onRefresh(e,(()=>this.extractTargetGroup()))}))}autoClose(){this.$scope.$$destroyed||(this.$state.params.allowModalToStayOpen=!0,this.$state.go("^",null,{location:"replace"}))}extractTargetGroup(){const{loadBalancerName:e,region:t,accountId:a,name:n}=this.targetGroupFromParams,r=this.app.loadBalancers.data.find((n=>n.name===e&&n.region===t&&n.account===a));if(!r)return this.autoClose(),this.$q.when(null);const i=r.targetGroups.find((e=>e.name===n));return i?(this.targetGroup=i,this.loadBalancer=r,this.state.loading=!1,this.elbProtocol="http:",this.loadBalancer.listeners&&this.loadBalancer.listeners.some((e=>"HTTPS"===e.protocol))&&(this.elbProtocol="https:"),this.$q.when(null)):(this.autoClose(),this.$q.when(null))}}Jr.$inject=["$scope","$q","$state","targetGroup","app"];t("spinnaker.amazon.loadBalancer.details.targetGroupDetails.controller",[_a,xe]).controller("awsTargetGroupDetailsCtrl",Jr);var ei=Object.defineProperty,ti=Object.getOwnPropertyDescriptor;let ai=class extends $t.Component{render(){return $t.createElement("h3",null,"Target Group Details")}};ai=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?ti(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&ei(t,a,i),i})([ce("loadBalancer.targetGroupDetails")],ai);t("spinnaker.amazon.loadBalancer.targetGroup.states",[Ae]).config(["applicationStateProvider",e=>{const t={name:"targetGroupDetails",url:"/targetGroupDetails/:provider/:accountId/:region/:vpcId/:loadBalancerName/:name",params:{vpcId:{value:null,squash:!0}},views:{"detail@../insight":{component:ai,$type:"react"}},resolve:{accountId:["$stateParams",e=>e.accountId],targetGroup:["$stateParams",e=>({loadBalancerName:e.loadBalancerName,name:e.name,accountId:e.accountId,region:e.region,vpcId:e.vpcId})]},data:{pageTitleDetails:{title:"Target Group Details",nameParam:"name",accountParam:"accountId",regionParam:"region"}}};e.addInsightDetailState(t)}]);t("spinnaker.amazon.loadBalancer",["spinnaker.amazon.loadBalancer.details.controller","spinnaker.amazon.loadBalancer.details.targetGroupDetails.controller",Xr,"spinnaker.amazon.loadBalancer.targetGroup.states"]);t("spinnaker.amazon.pipeline.stage.bake.executionDetails.controller",[_a]).controller("awsBakeExecutionDetailsCtrl",["$scope","$stateParams","executionDetailsSectionService","$interpolate",function(e,t,n,r){e.configSections=["bakeConfig","taskStatus"];const i=()=>{e.detailsSection=t.details,e.provider=e.stage.context.cloudProviderType||"aws",e.roscoMode=a.feature.roscoMode||"function"==typeof a.feature.roscoSelector&&a.feature.roscoSelector(e.stage.context),e.bakeryDetailUrl=r(e.roscoMode&&a.roscoDetailUrl?a.roscoDetailUrl:a.bakeryDetailUrl),e.bakeFailedNoError="FAILURE"===Kt(e.stage,"context.status.result")&&!e.stage.failureMessage},s=()=>n.synchronizeSection(e.configSections,i);s(),e.$on("$stateChangeSuccess",s)}]);t("spinnaker.amazon.pipeline.stage.bakeStage",["spinnaker.amazon.pipeline.stage.bake.executionDetails.controller"]).config((function(){Pe.pipeline.registerStage({provides:"bake",cloudProvider:"aws",label:"Bake",description:"Bakes an image",templateUrl:"amazon/src/pipeline/stages/bake/bakeStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/bake/bakeExecutionDetails.html",executionLabelComponent:ze,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("awsBakeStageCtrl",["$scope","$q","$uibModal",function(e,t,n){function r(){if(e.baseOsOptions.length&&e.baseOsOptions.every((({vmTypes:e})=>e))){const t=e.baseOsOptions.length&&new Set(e.baseOsOptions.reduce(((e,{vmTypes:t})=>e.concat(t)),[])),a=e.baseOsOptions.find((({id:t})=>t===e.stage.baseOs));e.viewState.showVmTypeSelector=t.size>1,e.vmTypes=a.vmTypes}else e.viewState.showVmTypeSelector=!0,e.vmTypes=["hvm","pv"]}e.stage.extendedAttributes=e.stage.extendedAttributes||{},e.stage.regions=e.stage.regions&&e.stage.regions.sort()||[],e.stage.user||(e.stage.user=Be.getAuthenticatedUser().name),e.viewState={loading:!0,roscoMode:a.feature.roscoMode||"function"==typeof a.feature.roscoSelector&&a.feature.roscoSelector(e.stage),minRootVolumeSize:fn.minRootVolumeSize,showVmTypeSelector:!0,bakeWarning:fn.bakeWarning,dockerBakeWarning:fn.dockerBakeWarning,showDockerPreview:fn.dockerBakeryDeprecated&&"docker"===e.stage.storeType,showMigrationFields:"Started"!==e.pipeline.migrationStatus,showStoreType:!fn.dockerBakeryDeprecated},this.addExtendedAttribute=function(){e.stage.extendedAttributes||(e.stage.extendedAttributes={}),n.open({templateUrl:De.addExtendedAttributes,controller:"bakeStageAddExtendedAttributeController",controllerAs:"addExtendedAttribute",resolve:{extendedAttribute:function(){return{key:"",value:""}}}}).result.then((function(t){e.stage.extendedAttributes[t.key]=t.value})).catch((()=>{}))},this.removeExtendedAttribute=function(t){delete e.stage.extendedAttributes[t]},this.showTemplateFileName=function(){return e.viewState.roscoMode||e.stage.templateFileName},this.showExtendedAttributes=function(){return e.viewState.roscoMode||e.stage.extendedAttributes&&Mt.size(e.stage.extendedAttributes)>0},this.showVarFileName=function(){return e.viewState.roscoMode||e.stage.varFileName},this.handleBaseOsChange=function(){r(),e.vmTypes&&e.vmTypes.length&&!e.vmTypes.includes(e.stage.vmType)&&(e.stage.vmType=e.vmTypes[0])},e.$watch("stage",(function(){Mt.forOwn(e.stage,(function(t,a){""===t&&delete e.stage[a]})),"ebs"===e.stage.storeType&&"aws"!==e.stage.cloudProviderType&&(e.stage.cloudProviderType="aws"),"function"==typeof a.feature.roscoSelector&&(e.viewState.roscoMode=a.feature.roscoSelector(e.stage))}),!0),t.all([$e.getRegions("aws"),$e.getBaseOsOptions("aws"),$e.getBaseLabelOptions(),["ebs","docker"]]).then((function([t,a,n,i]){e.regions=[...t].sort(),e.storeTypes=i,!e.stage.storeType&&e.storeTypes&&e.storeTypes.length&&(e.stage.storeType=e.storeTypes[0]),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.aws&&e.stage.regions.push(...Object.keys(e.application.defaultRegions.aws).sort()),e.baseOsOptions=a.baseImages,e.baseLabelOptions=n,!e.stage.baseOs&&e.baseOsOptions&&e.baseOsOptions.length?e.stage.baseOs=e.baseOsOptions[0].id:e.stage.baseOs&&!(e.baseOsOptions||[]).find((t=>t.id===e.stage.baseOs))&&e.baseOsOptions.push({id:e.stage.baseOs,detailedDescription:"Custom",vmTypes:["hvm","pv"]}),!e.stage.baseLabel&&e.baseLabelOptions&&e.baseLabelOptions.length&&(e.stage.baseLabel=e.baseLabelOptions[0]),r(),!e.stage.vmType&&e.vmTypes&&e.vmTypes.length&&(e.stage.vmType=e.vmTypes[0]),e.showAdvancedOptions=function(){const t=e.stage;return!!(t.templateFileName||t.extendedAttributes&&Mt.size(t.extendedAttributes)>0||t.varFileName||t.baseName||t.baseAmi||t.amiName||t.amiSuffix||t.rootVolumeSize)}(),e.viewState.loading=!1}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/bake/bakeStage.html",'<div ng-controller="awsBakeStageCtrl 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 && viewState.showDockerPreview">\n <div ng-if="viewState.dockerBakeWarning" class="alert alert-warning sp-margin-s-top horizontal middle">\n <i class="fa fa-exclamation-triangle"></i>\n <div class="sp-margin-s-left">\n <markdown message="viewState.dockerBakeWarning"></markdown>\n </div>\n </div>\n <div>\n <div class="alert alert-info horizontal middle">\n <i class="fa fa-info-circle"></i>\n <div class="sp-margin-s-left">\n <markdown\n message="\'To edit bake configuration or view advanced options, migrate to EBS store type.\'"\n ></markdown>\n </div>\n </div>\n <stage-config-field label="Store Type" ng-if="!viewState.roscoMode && viewState.showMigrationFields">\n <label class="radio-inline" ng-repeat="storeType in storeTypes">\n <input type="radio" ng-model="stage.storeType" ng-value="storeType" />\n {{storeType | uppercase}}\n </label>\n </stage-config-field>\n <stage-config-field label="Regions">\n <span class="sp-margin-xs-right" ng-repeat="region in stage.regions">{{region}}</span>\n </stage-config-field>\n <stage-config-field label="Skip Region Detection">{{!!stage.skipRegionDetection}}</stage-config-field>\n <stage-config-field label="Repo Path">{{stage.package}}</stage-config-field>\n <stage-config-field label="Base OS">{{stage.baseOs}}</stage-config-field>\n <stage-config-field label="VM Type">{{stage.vmType}}</stage-config-field>\n <stage-config-field label="Store Type">{{stage.storeType}}</stage-config-field>\n <stage-config-field label="Base Label">{{stage.baseLabel}}</stage-config-field>\n </div>\n </div>\n <div ng-if="!viewState.loading && !viewState.showDockerPreview">\n <div\n ng-if="pipeline.migrationStatus === \'Started\' && viewState.bakeWarning"\n class="alert alert-warning sp-margin-s-top horizontal middle"\n >\n <i class="fa fa-exclamation-triangle"></i>\n <div class="sp-margin-s-left">\n <markdown message="viewState.bakeWarning"></markdown>\n </div>\n </div>\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="Skip Region Detection" help-key="pipeline.config.bake.skipRegionDetection">\n <div class="checkbox" style="margin-bottom: 0">\n <label>\n <input type="checkbox" ng-model="stage.skipRegionDetection" />\n Only bake explicitly selected regions\n </label>\n </div>\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Repo Path\' : \'Package\'}}"\n help-key="pipeline.config.bake.package"\n >\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\n model="stage.baseOs"\n base-os-options="baseOsOptions"\n on-change="bakeStageCtrl.handleBaseOsChange()"\n ></bake-stage-choose-os>\n </stage-config-field>\n <stage-config-field label="VM Type" ng-if="viewState.showVmTypeSelector && viewState.showMigrationFields">\n <label class="radio-inline" ng-repeat="vmType in vmTypes">\n <input type="radio" ng-model="stage.vmType" ng-value="vmType" />\n {{vmType | uppercase}}\n </label>\n </stage-config-field>\n <stage-config-field\n label="Store Type"\n ng-if="!viewState.roscoMode && viewState.showMigrationFields && viewState.showStoreType"\n >\n <label class="radio-inline" ng-repeat="storeType in storeTypes">\n <input type="radio" ng-model="stage.storeType" ng-value="storeType" />\n {{storeType | uppercase}}\n </label>\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 <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() && viewState.showMigrationFields"\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() && viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.varFileName" />\n </stage-config-field>\n <stage-config-field label="Root Volume Size" ng-if="viewState.minRootVolumeSize && viewState.showMigrationFields">\n <input\n type="number"\n class="form-control input-sm"\n style="width: 80px; display: inline-block"\n ng-min="viewState.minRootVolumeSize"\n ng-model="stage.rootVolumeSize"\n />\n GB <span class="small">(minimum: {{viewState.minRootVolumeSize}})</span>\n </stage-config-field>\n <stage-config-field label="Base Name" ng-if="stage.storeType !== \'docker\' && viewState.showMigrationFields">\n <input type="text" class="form-control input-sm" ng-model="stage.baseName" />\n </stage-config-field>\n <stage-config-field\n label="Base AMI"\n help-key="pipeline.config.bake.baseAmi"\n ng-if="stage.storeType !== \'docker\' && viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.baseAmi" />\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Docker Image Name\' : \'AMI Name\'}}"\n help-key="pipeline.config.bake.amiName"\n ng-if="viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.amiName" />\n </stage-config-field>\n <stage-config-field\n label="{{stage.storeType === \'docker\' ? \'Docker Image Prefix\' : \'AMI Suffix\'}}"\n help-key="pipeline.config.bake.amiSuffix"\n ng-if="viewState.showMigrationFields"\n >\n <input type="text" class="form-control input-sm" ng-model="stage.amiSuffix" />\n </stage-config-field>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/bake/bakeExecutionDetails.html",'<div ng-controller="awsBakeExecutionDetailsCtrl">\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>Amazon</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>VM Type</dt>\n <dd>{{stage.context.vmType | uppercase}}</dd>\n <dt ng-if="!roscoMode">Store Type</dt>\n <dd ng-if="!roscoMode">{{stage.context.storeType | uppercase}}</dd>\n <dt ng-if="!roscoMode">Label</dt>\n <dd ng-if="!roscoMode">{{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\n stage="stage"\n message="stage.failureMessage"\n ng-if="stage.failureMessage"\n ></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 <div ng-if="stage.context.imageName">\n <strong>Image:</strong>\n <div select-on-dbl-click>{{stage.context.imageName}}</div>\n <div>({{stage.context.ami}})</div>\n </div>\n <span ng-if="bakeFailedNoError">Bake failed. </span>\n <a target="_blank" href="{{ bakeryDetailUrl(stage) }}">View Bakery Details</a>\n <span ng-if="bakeFailedNoError"> for more info.</span>\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')}]);t("spinnaker.amazon.pipeline.stage.cloneServerGroupStage",[]).config((function(){Pe.pipeline.registerStage({provides:"cloneServerGroup",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html",executionStepLabelUrl:"amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html",accountExtractor:e=>[e.context.credentials],validators:[{type:"requiredField",fieldName:"targetCluster",fieldLabel:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"region"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsCloneServerGroupStageCtrl",["$scope",function(e){const t=e.stage;e.viewState={accountsLoaded:!1},o.listAccounts("aws").then((t=>{e.accounts=t,e.viewState.accountsLoaded=!0})),this.cloneTargets=Fe.TARGET_LIST,t.target=t.target||this.cloneTargets[0].val,t.application=e.application.name,t.cloudProvider="aws",t.cloudProviderType="aws",t.viewState={mode:"editPipeline"},t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),t.isNew&&(t.useAmiBlockDeviceMappings=Mt.get(e,"application.attributes.providerSettings.aws.useAmiBlockDeviceMappings",!1),t.copySourceCustomBlockDeviceMappings=!1),this.targetClusterUpdated=()=>{if(t.targetCluster){const a=Me.monikerClusterNameFilter(t.targetCluster),n=Mt.first(Me.getMonikers([e.application],a));if(n)t.stack=n.stack,t.freeFormDetails=n.detail;else{const e=Ee.parseClusterName(t.targetCluster);t.stack=e.stack,t.freeFormDetails=e.freeFormDetails}}else t.stack="",t.freeFormDetails=""},e.$watch("stage.targetCluster",this.targetClusterUpdated),this.removeCapacity=()=>{delete t.capacity},Mt.has(t,"useSourceCapacity")||(t.useSourceCapacity=!0),this.toggleSuspendedProcess=e=>{t.suspendedProcesses=t.suspendedProcesses||[];const a=t.suspendedProcesses.indexOf(e);-1===a?t.suspendedProcesses.push(e):t.suspendedProcesses.splice(a,1)},this.processIsSuspended=e=>t.suspendedProcesses&&t.suspendedProcesses.includes(e),this.getBlockDeviceMappingsSource=()=>t.copySourceCustomBlockDeviceMappings?"source":t.useAmiBlockDeviceMappings?"ami":"default",this.selectBlockDeviceMappingsSource=e=>{"source"===e?(t.copySourceCustomBlockDeviceMappings=!0,t.useAmiBlockDeviceMappings=!1):"ami"===e?(t.copySourceCustomBlockDeviceMappings=!1,t.useAmiBlockDeviceMappings=!0):(t.copySourceCustomBlockDeviceMappings=!1,t.useAmiBlockDeviceMappings=!1)},this.onRedBlackFieldChange=(e,a)=>{Mt.set(t,e,a)}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html",'<div ng-controller="awsCloneServerGroupStageCtrl as cloneServerGroupStageCtrl">\n <div ng-if="!pipeline.strategy">\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 <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="accounts"\n single-region="true"\n cluster-field="targetCluster"\n >\n </account-region-cluster-selector>\n </div>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="cloneServerGroupStageCtrl.cloneTargets"></target-select>\n </stage-config-field>\n <div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Capacity</div>\n <div class="col-md-9 radio">\n <label>\n <input\n type="radio"\n ng-model="stage.useSourceCapacity"\n ng-value="true"\n ng-click="cloneServerGroupStageCtrl.removeCapacity()"\n id="useSourceCapacityTrue"\n />\n Copy the capacity from the current server group\n <help-field key="serverGroupCapacity.useSourceCapacityTrue"></help-field>\n </label>\n </div>\n <div class="col-md-9 col-md-offset-3 radio">\n <label>\n <input type="radio" ng-model="stage.useSourceCapacity" ng-value="false" id="useSourceCapacityFalse" />\n Let me specify the capacity\n <help-field key="serverGroupCapacity.useSourceCapacityFalse"></help-field>\n </label>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-2 col-md-offset-3">Min</div>\n <div class="col-md-2">Max</div>\n <div class="col-md-2">Desired</div>\n </div>\n <div class="form-group">\n <div class="col-md-2 col-md-offset-3">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.min"\n min="0"\n max="{{stage.capacity.max}}"\n required\n />\n </div>\n <div class="col-md-2">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.max"\n min="{{stage.capacity.min}}"\n required\n />\n </div>\n <div class="col-md-2">\n <input\n type="number"\n ng-disabled="stage.useSourceCapacity"\n class="form-control input-sm"\n ng-model="stage.capacity.desired"\n min="{{stage.capacity.min}}"\n max="{{stage.capacity.max}}"\n required\n />\n </div>\n </div>\n </div>\n <stage-config-field label="Traffic" help-key="aws.serverGroup.traffic">\n <div class="checkbox">\n <label>\n <input\n type="checkbox"\n ng-click="cloneServerGroupStageCtrl.toggleSuspendedProcess(\'AddToLoadBalancer\')"\n ng-checked="!cloneServerGroupStageCtrl.processIsSuspended(\'AddToLoadBalancer\')"\n />\n Send client requests to new instances\n </label>\n </div>\n </stage-config-field>\n <stage-config-field label="AMI Block Device Mappings">\n <div class="radio">\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'source\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'source\'"\n name="blockDeviceMappingsSource"\n />\n Copy from current server group\n <help-field key="aws.blockDeviceMappings.useSource"></help-field>\n </label>\n </div>\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'ami\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'ami\'"\n name="blockDeviceMappingsSource"\n />\n Prefer AMI block device mappings\n <help-field key="aws.blockDeviceMappings.useAMI"></help-field>\n </label>\n </div>\n <div>\n <label>\n <input\n type="radio"\n ng-click="cloneServerGroupStageCtrl.selectBlockDeviceMappingsSource(\'default\')"\n ng-checked="cloneServerGroupStageCtrl.getBlockDeviceMappingsSource() === \'default\'"\n name="blockDeviceMappingsSource"\n />\n Defaults for selected instance type\n <help-field key="aws.blockDeviceMappings.useDefaults"></help-field>\n </label>\n </div>\n </div>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n <deployment-strategy-selector\n field-columns="6"\n command="stage"\n on-field-change="cloneServerGroupStageCtrl.onRedBlackFieldChange"\n ></deployment-strategy-selector>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html",'<span class="task-label"> Clone Server Group: {{step.context.source.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.cloudformation.changetset.info.component",[]).component("cloudFormationChangeSetInfo",ja(M((e=>{const{stage:t,stageconfig:a}=e,[n,r]=Ft(t.changeSetName?t.changeSetName:"ChangeSet-${ execution['id']}"),[i,s]=Ft(t.executeChangeSet),[o,p]=Ft(t.actionOnReplacement);return $t.createElement("div",null,$t.createElement("hr",null),$t.createElement("h4",null,"ChangeSet Configuration"),$t.createElement(Re,{label:"ChangeSet Name"},$t.createElement(l,{className:"form-control",type:"text",value:n,onChange:e=>{return t=e.target.value,r(t),void a.updateStageField({changeSetName:t});var t}})),$t.createElement(Re,{label:"Execute ChangeSet"},$t.createElement(d,{checked:i,onChange:e=>{return t=e.target.checked,s(t),void a.updateStageField({executeChangeSet:t});var t}})),i&&$t.createElement(Re,{label:"If ChangeSet contains a replacement","help-key":"aws.cloudformation.changeSet.options"},$t.createElement(c,{clearable:!1,value:o,options:[{value:"ask",label:"ask"},{value:"skip",label:"skip it"},{value:"execute",label:"execute it"},{value:"fail",label:"fail stage"}],onChange:e=>{return t=e.target.value,p(t),void a.updateStageField({actionOnReplacement:t});var t}})))}),"cloudFormationChangeSetInfo"),["stage","stageconfig"]));class ni{constructor(e){this.$scope=e,this.$onInit=()=>{"string"==typeof this.command.templateBody?this.rawTemplateBody=this.command.templateBody:this.rawTemplateBody=Le(this.command.templateBody)},this.handleChange=(e,t)=>{this.command.templateBody=t||e,this.templateBody=t||e,this.rawTemplateBody=e,this.$scope.$applyAsync()}}}ni.$inject=["$scope"];const ri={bindings:{command:"<",templateBody:"<"},controller:ni,controllerAs:"ctrl",template:'\n <yaml-editor\n value="ctrl.rawTemplateBody"\n on-change="ctrl.handleChange"\n ></yaml-editor>'};t("spinnaker.amazon.cloudformation.entry.component",[]).component("cloudFormationTemplateEntry",ri);class ii extends Dt.Component{constructor(e){super(e)}render(){const{stage:e,current:t,name:a}=this.props;return Dt.createElement(Oe,{name:a,current:t},Dt.createElement(Ue,{item:e}),Dt.createElement(Ve,{stage:e,message:e.failureMessage}))}}ii.title="Task Status";class si{constructor(e){this.$scope=e,this.state={loaded:!1},this.textSource="text",this.artifactSource="artifact",this.sources=[this.textSource,this.artifactSource],this.showClusterSelect=!1,this.onStackArtifactEdited=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactId=null,this.$scope.stage.stackArtifact=e}))},this.onStackArtifactSelected=e=>{this.onChangeStackArtifactId(e.id)},this.onChangeStackArtifactId=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactId=e,this.$scope.stage.stackArtifact=null}))},this.onStackArtifactAccountSelected=e=>{this.$scope.$applyAsync((()=>{this.$scope.stage.stackArtifactAccount=e}))},this.updatePipeline=e=>{this.$scope.$applyAsync((()=>{oa(this.$scope.pipeline,e)}))};const t={accounts:o.getAllAccountDetailsForProvider("aws"),artifactAccounts:o.getArtifactAccounts()};qa.all(t).then((e=>{const{accounts:t,artifactAccounts:a}=e;this.accounts=t,this.state.loaded=!0,this.cloudFormationStackArtifactDelegate.setAccounts(a),this.cloudFormationStackArtifactController.updateAccounts(this.cloudFormationStackArtifactDelegate.getSelectedExpectedArtifact())})),this.cloudFormationStackArtifactDelegate=new qe(e,"stack"),this.cloudFormationStackArtifactController=new je(this.cloudFormationStackArtifactDelegate)}canShowAccountSelect(){return this.$scope.stage.source===this.artifactSource&&!this.$scope.showCreateArtifactForm&&this.cloudFormationStackArtifactController.accountsForArtifact.length>1}toggleChangeSet(){this.$scope.stage.isChangeSet=!this.$scope.stage.isChangeSet}}si.$inject=["$scope"];const li=e=>{const{execution:t,stage:a,application:n}=e,[r,i]=Ft(!1),[s,l]=Ft(""),[o,c]=Ft(!1),d=e=>{i(!0),l(e),c(!1),qn.evaluateCloudFormationChangeSetExecutionService.evaluateExecution(n,t,a,e)},p=e=>a.judgmentStatus===e||r&&s===e;return $t.createElement("div",null,$t.createElement("div",null,$t.createElement("p",null,"This ChangeSet contains a replacement, which means there will be ",$t.createElement("b",null,"potential data loss")," when executed."),$t.createElement("p",null,"How do you want to proceed?"),$t.createElement("div",{className:"action-buttons"},$t.createElement("button",{className:"btn btn-danger",onClick:()=>{d("execute")},disabled:r},p("Execute")&&$t.createElement(te,{mode:"circular"}),a.context.stopButtonLabel||"Execute"),$t.createElement("button",{className:"btn btn-primary",disabled:r,onClick:()=>{d("skip")}},p("Skip")&&$t.createElement(te,{mode:"circular"}),a.context.skipButtonLabel||"Skip"),$t.createElement("button",{className:"btn btn-primary",disabled:r,onClick:()=>{d("fail")}},p("Fail")&&$t.createElement(te,{mode:"circular"}),a.context.FailButtonLabel||"Fail"))),o&&$t.createElement("div",{className:"error-message"},"There was an error recording your decision. Please try again."))};class oi extends Dt.Component{constructor(e){super(e)}render(){const{application:e,execution:t,stage:a,current:n,name:r}=this.props,i=a.context.changeSetContainsReplacement,s=i&&a.isRunning&&"ask"===a.context.actionOnReplacement,l=a.context.isChangeSet;return Dt.createElement(Oe,{name:r,current:n},s?Dt.createElement(li,{key:a.refId,application:e,execution:t,stage:a}):Dt.createElement("div",null,l?Dt.createElement("div",null,Dt.createElement("dl",{className:"no-margin"},Dt.createElement("dt",null,"ChangeSet Name"),Dt.createElement("dd",null,a.context.changeSetName),Dt.createElement("dt",null,"Replacement"),Dt.createElement("dd",null,String(i)),a.context.changeSetExecutionChoice&&Dt.createElement("div",null,Dt.createElement("dt",null,"Judgment"),Dt.createElement("dd",null,a.context.changeSetExecutionChoice),Dt.createElement("dt",null,"Judged By"),Dt.createElement("dd",null,a.context.lastModifiedBy)))):Dt.createElement("div",null,"No changeSets found")))}}oi.title="Change Set Execution";class ci extends Dt.Component{render(){if(!this.props.executionMarker)return Dt.createElement(He,{...this.props});const{stage:e}=this.props;if(e.isRunning&&e.stages[0].context.changeSetContainsReplacement&&"ask"===e.stages[0].context.actionOnReplacement){const t=Dt.createElement("div",null,Dt.createElement("div",null,Dt.createElement("b",null,e.name)),Dt.createElement(li,{stage:e.masterStage,application:this.props.application,execution:this.props.execution}));return Dt.createElement(ae,{template:t},this.props.children)}const t=Dt.createElement(Ra,{id:e.id},e.name);return Dt.createElement(La,{placement:"top",overlay:t},Dt.createElement("span",null,this.props.children))}}class di extends Dt.Component{constructor(e){super(e)}render(){return this.props.stage.isRunning&&this.props.stage.stages[0].context.changeSetContainsReplacement&&"ask"===this.props.stage.stages[0].context.actionOnReplacement?(this.props.stage.requiresAttention=!0,Dt.createElement("span",{className:"fa fa-child"})):null}}t("spinnaker.amazon.pipeline.stages.deployCloudFormationStage",[]).config((()=>{Pe.pipeline.registerStage({label:"Deploy (CloudFormation Stack)",description:"Deploy a CloudFormation Stack",key:"deployCloudFormation",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/deployCloudFormation/deployCloudFormationStackConfig.html",controller:"DeployCloudFormationStackConfigController",controllerAs:"ctrl",useCustomTooltip:!0,executionDetailsSections:[ii,oi],executionLabelComponent:ci,producesArtifacts:!0,supportsCustomTimeout:!0,validators:[],markerIcon:di,accountExtractor:e=>e.account?[e.account]:[],configAccountExtractor:e=>e.account?[e.account]:[],artifactExtractor:We.accumulateArtifacts(["stackArtifactId","requiredArtifactIds"]),artifactRemover:Ze.removeArtifactFromFields(["stackArtifactId","requiredArtifactIds"])})})).controller("DeployCloudFormationStackConfigController",si),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/deployCloudFormation/deployCloudFormationStackConfig.html",'<div ng-if="ctrl.state.loaded" class="clearfix">\n <div class="container-fluid form-horizontal">\n <h4>Basic Settings</h4>\n <div ng-if="!pipeline.strategy">\n <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="ctrl.accounts"\n show-cluster-select="ctrl.showClusterSelect"\n >\n </account-region-cluster-selector>\n </div>\n <h4>Template Configuration</h4>\n <ng-form name="amazonCloudFormationTemplateSource">\n <stage-config-field label="Stack name">\n <label class="sm-label-right">\n <input type="text" class="form-control input-sm" required ng-model="stage.stackName" />\n </label>\n <br />\n <label>\n <input type="checkbox" ng-checked="stage.isChangeSet" ng-click="ctrl.toggleChangeSet()" />\n <strong>Create CloudFormation ChangeSet</strong>\n </label>\n </stage-config-field>\n\n <stage-config-field label="IAM role ARN">\n <label class="sm-label-right">\n <input type="text" class="form-control input-sm" ng-model="stage.roleARN" />\n </label>\n </stage-config-field>\n <stage-config-field label="Source" help-key="aws.cloudformation.source">\n <label class="sm-label-right">\n <input type="radio" ng-model="ctrl.$scope.stage.source" value="{{ctrl.textSource}}" />\n {{ ctrl.textSource | robotToHuman }}\n <span ng-if="stage.source === ctrl.textSource"> </span> </label\n ><br />\n <label class="sm-label-right">\n <input type="radio" ng-model="ctrl.$scope.stage.source" value="{{ctrl.artifactSource}}" />\n {{ ctrl.artifactSource | robotToHuman }}\n </label>\n </stage-config-field>\n </ng-form>\n <cloud-formation-template-entry\n ng-if="stage.source === ctrl.textSource"\n templateBody="stage.templateBody"\n command="stage"\n >\n </cloud-formation-template-entry>\n <stage-artifact-selector-delegate\n ng-if="ctrl.$scope.stage.source === ctrl.artifactSource"\n artifact="stage.stackArtifact"\n excluded-artifact-type-patterns="[]"\n expected-artifact-id="stage.stackArtifactId"\n field-columns="8"\n help-key="\'aws.cloudformation.expectedArtifact\'"\n label="\'Expected Artifact\'"\n on-artifact-edited="ctrl.onStackArtifactEdited"\n on-expected-artifact-selected="ctrl.onStackArtifactSelected"\n pipeline="pipeline"\n stage="stage"\n >\n </stage-artifact-selector-delegate>\n <div ng-if="stage.isChangeSet">\n <cloud-formation-change-set-info stage="stage" stageconfig="stageConfigCtrl"> </cloud-formation-change-set-info>\n </div>\n <hr />\n <stage-config-field label="Parameters" field-columns="6">\n <map-editor model="ctrl.$scope.stage.parameters" add-button-label="Add parameter"></map-editor>\n </stage-config-field>\n <hr />\n <stage-config-field label="Tags" field-columns="6">\n <map-editor model="ctrl.$scope.stage.tags" add-button-label="Add tag"></map-editor>\n </stage-config-field>\n <hr />\n <stage-config-field label="Capabilities" field-columns="6">\n <ui-select multiple ng-model="stage.capabilities" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices repeat="capability in [\'CAPABILITY_IAM\', \'CAPABILITY_NAMED_IAM\', \'CAPABILITY_AUTO_EXPAND\']">\n <span>{{ capability }}</span>\n </ui-select-choices>\n </ui-select>\n </stage-config-field>\n </div>\n</div>\n')}]);class pi{constructor(e){this.executionService=e}evaluateExecution(e,t,a,n){const r=e=>{const t=e.stages.find((e=>e.id===a.id));return t&&"RUNNING"!==t.status};return this.executionService.patchExecution(t.id,a.id,{changeSetExecutionChoice:n}).then((()=>this.executionService.waitUntilExecutionMatches(t.id,r))).then((t=>this.executionService.updateExecution(e,t)))}}pi.$inject=["executionService"];t("spinnaker.amazon.deployCloudFormation.service",[_e]).service("evaluateCloudFormationChangeSetExecutionService",pi);t("spinnaker.amazon.pipeline.stage.aws.destroyAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"destroyServerGroup",alias:"destroyAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/destroyAsg/destroyAsgStage.html",executionStepLabelUrl:"amazon/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("awsDestroyAsgStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.regions=["us-east-1","us-west-1","eu-west-1","us-west-2"],e.targets=Fe.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/destroyAsg/destroyAsgStage.html",'<div ng-controller="awsDestroyAsgStageCtrl 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("amazon/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html",'<span class="task-label"> Destroy Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.pipeline.stage.disableAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"disableServerGroup",alias:"disableAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/disableAsg/disableAsgStage.html",executionStepLabelUrl:"amazon/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("awsDisableAsgStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.targets=Fe.TARGET_LIST,t.regions=t.regions||[],t.cloudProvider="aws",t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),t.target||(t.target=e.targets[0].val)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableAsg/disableAsgStage.html",'<div ng-controller="awsDisableAsgStageCtrl 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="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableAsg/disableAsgStepLabel.html",'<span class="task-label"> Disable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);t("spinnaker.amazon.pipeline.stage.disableClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"disableCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/disableCluster/disableClusterStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"remainingEnabledServerGroups",fieldLabel:"Keep [X] enabled Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsDisableClusterStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},a.regions=a.regions||[],a.cloudProvider="aws",a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws),void 0===a.remainingEnabledServerGroups&&(a.remainingEnabledServerGroups=1),t.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===a.preferLargerOverNewer&&(a.preferLargerOverNewer="false"),a.preferLargerOverNewer=a.preferLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/disableCluster/disableClusterStage.html",'<div ng-controller="awsDisableClusterStageCtrl as disableClusterStageCtrl" 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="Disable Options">\n <div class="form-inline">\n Keep the\n <input\n type="number"\n min="0"\n required\n ng-model="stage.remainingEnabledServerGroups"\n class="form-control input-sm"\n style="width: 50px"\n />\n <select class="form-control input-sm" ng-model="stage.preferLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n {{disableClusterStageCtrl.pluralize(\'server group\', stage.remainingEnabledServerGroups)}} enabled.\n </div>\n </stage-config-field>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.enableAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"enableServerGroup",alias:"enableAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/enableAsg/enableAsgStage.html",executionStepLabelUrl:"amazon/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("awsEnableAsgStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},e.targets=Fe.TARGET_LIST,a.regions=a.regions||[],a.cloudProvider="aws",a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws),a.target||(a.target=e.targets[0].val),e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/enableAsg/enableAsgStage.html",'<div ng-controller="awsEnableAsgStageCtrl 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="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/enableAsg/enableAsgStepLabel.html",'<span class="task-label"> Enable Server Group: {{step.context.serverGroupName}} ({{step.context.region}}) </span>\n')}]);e.module("spinnaker.amazon.pipeline.stage.findAmiStage",[]).config((function(){Pe.pipeline.registerStage({provides:"findImage",alias:"findAmi",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/findAmi/findAmiStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"selectionStrategy",fieldLabel:"Server Group Selection"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials"}]})})).controller("awsFindAmiStageCtrl",["$scope",function(t){const a=t.stage;t.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(e){t.accounts=e,t.state.accounts=!0})),t.selectionStrategies=[{label:"Largest",val:"LARGEST",description:"When multiple server groups exist, prefer the server group with the most instances"},{label:"Newest",val:"NEWEST",description:"When multiple server groups exist, prefer the newest"},{label:"Oldest",val:"OLDEST",description:"When multiple server groups exist, prefer the oldest"},{label:"Fail",val:"FAIL",description:"When multiple server groups exist, fail"}],a.regions=a.regions||[],a.cloudProvider="aws",a.selectionStrategy=a.selectionStrategy||t.selectionStrategies[0].val,e.isUndefined(a.onlyEnabled)&&(a.onlyEnabled=!0),!a.credentials&&t.application.defaultCredentials.aws&&(a.credentials=t.application.defaultCredentials.aws),!a.regions.length&&t.application.defaultRegions.aws&&a.regions.push(t.application.defaultRegions.aws),t.$watch("stage.credentials",t.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findAmi/findAmiStage.html",'<div ng-controller="awsFindAmiStageCtrl as findAmiCtrl" class="form-horizontal">\n <account-region-cluster-selector\n application="application"\n component="stage"\n accounts="accounts"\n show-all-regions="true"\n >\n </account-region-cluster-selector>\n <stage-config-field label="Server Group Selection">\n <ui-select ng-model="stage.selectionStrategy" class="form-control input-sm">\n <ui-select-match placeholder="None">{{$select.selected.label}}</ui-select-match>\n <ui-select-choices repeat="strategy.val as strategy in selectionStrategies | filter: $select.search">\n <strong ng-bind-html="strategy.label | highlight: $select.search"></strong>\n <div ng-bind-html="strategy.description"></div>\n </ui-select-choices>\n </ui-select>\n </stage-config-field>\n <stage-config-field label="Server Group Filters">\n <label class="checkbox-inline">\n <input type="checkbox" ng-model="stage.onlyEnabled" />\n Only consider enabled Server Groups\n </label>\n </stage-config-field>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.findImageFromTagsStage",[]).config((function(){Pe.pipeline.registerStage({provides:"findImageFromTags",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html",executionConfigSections:["findImageConfig","taskStatus"],validators:[{type:"requiredField",fieldName:"packageName"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"tags"}]})})).controller("awsFindImageFromTagsStageCtrl",["$scope",function(e){e.stage.tags=e.stage.tags||{},e.stage.regions=e.stage.regions||[],e.stage.cloudProvider=e.stage.cloudProvider||"aws",$e.getRegions("aws").then((function(t){e.regions=t}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html",'<div ng-controller="awsFindImageFromTagsStageCtrl as findImageFromTagsCtrl" class="form-horizontal">\n <stage-config-field label="Package">\n <input type="text" class="form-control input-sm" ng-model="stage.packageName" />\n </stage-config-field>\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="Tags">\n <map-editor model="stage.tags" allow-empty="true"></map-editor>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'findImageConfig\'">\n <div class="row">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Amazon</dd>\n <dt>Package</dt>\n <dd>{{stage.context.packageName}}</dd>\n <dt>Regions</dt>\n <dd>{{stage.context.regions.join(\', \')}}</dd>\n <dt>Tags</dt>\n <dd>\n <span ng-repeat="(key, val) in stage.context.tags"> {{key}}:{{val}}{{$last ? \'\' : \', \'}} </span>\n </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.amiDetails">\n <div class="col-md-12">\n <div class="well alert alert-info">\n <h4>Results</h4>\n <dl ng-repeat="image in stage.context.amiDetails" class="dl-narrow dl-horizontal">\n <dt>Region</dt>\n <dd>{{image.region}}</dd>\n <dt>Image ID</dt>\n <dd>{{image.imageId}}</dd>\n <dt>Name</dt>\n <dd>{{image.imageName}}</dd>\n </dl>\n </div>\n </div>\n </div>\n </div>\n\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')}]);t("spinnaker.amazon.pipeline.stage.modifyScalingProcessStage",[]).config((function(){Pe.pipeline.registerStage({label:"Modify Scaling Process",description:"Suspend/Resume Scaling Processes",key:"modifyAwsScalingProcess",alias:"modifyScalingProcess",controller:"ModifyScalingProcessStageCtrl",templateUrl:"amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessExecutionDetails.html",executionConfigSections:["modifyScalingProcessesConfig","taskStatus"],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"action"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"processes"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}],cloudProvider:"aws",strategy:!0})})).controller("ModifyScalingProcessStageCtrl",["$scope","stage",function(e,t){e.stage=t,e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),e.targets=Fe.TARGET_LIST,e.actions=[{label:"Suspend",val:"suspend"},{label:"Resume",val:"resume"}],e.processes=["Launch","Terminate","AddToLoadBalancer","AlarmNotification","AZRebalance","HealthCheck","ReplaceUnhealthy","ScheduledActions"],t.processes=t.processes||[],t.regions=t.regions||[],t.action=t.action||e.actions[0].val,t.target=t.target||e.targets[0].val,t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),e.toggleProcess=function(e){t.processes||(t.processes=[]);const a=t.processes.indexOf(e);a>-1?t.processes.splice(a,1):t.processes.push(e)},e.$watch("stage.credentials",e.accountUpdated)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessStage.html",'<div 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-config-field label="Action">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.action"\n ng-options="a.val as a.label for a in actions"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <stage-config-field label="Processes" field-columns="8">\n <div class="checkbox" style="padding-left: 0">\n <checklist model="stage.processes" items="processes"></checklist>\n </div>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/modifyScalingProcess/modifyScalingProcessExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'modifyScalingProcessesConfig\'">\n <div class="row">\n <div class="col-md-9">\n <dl class="dl-narrow dl-horizontal">\n <dt>Account</dt>\n <dd><account-tag account="stage.context.credentials"></account-tag></dd>\n <dt>Region</dt>\n <dd>{{stage.context.region}}</dd>\n <dt>ASG Name</dt>\n <dd>{{stage.context.asgName}}</dd>\n <dt>Action</dt>\n <dd>{{stage.context.action}}</dd>\n <dt>Processes</dt>\n <dd>{{stage.context.processes.join(\', \')}}</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.execution.logs">\n <div class="col-md-12">\n <div class="well alert alert-info">\n <a target="_blank" href="{{stage.context.execution.logs}}"> View Execution Logs </a>\n </div>\n </div>\n </div>\n </div>\n\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')}]);t("spinnaker.amazon.pipeline.stage.aws.resizeAsgStage",[]).config((function(){Pe.pipeline.registerStage({provides:"resizeServerGroup",alias:"resizeAsg",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/resizeAsg/resizeAsgStage.html",executionStepLabelUrl:"amazon/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"targetImpedance",message:"This pipeline will attempt to resize a server group without deploying a new version into the same cluster."},{type:"requiredField",fieldName:"target"},{type:"requiredField",fieldName:"action"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsResizeAsgStageCtrl",["$scope",function(e){const t=e.stage;e.viewState={accountsLoaded:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.viewState.accountsLoaded=!0})),e.resizeTargets=Fe.TARGET_LIST,e.scaleActions=[{label:"Scale Up",val:"scale_up"},{label:"Scale Down",val:"scale_down"},{label:"Scale to Cluster Size",val:"scale_to_cluster"},{label:"Scale to Exact Size",val:"scale_exact"}],e.resizeTypes=[{label:"Percentage",val:"pct"},{label:"Incremental",val:"incr"}],t.capacity=t.capacity||{},t.regions=t.regions||[],t.target=t.target||e.resizeTargets[0].val,t.action=t.action||e.scaleActions[0].val,t.resizeType=t.resizeType||e.resizeTypes[0].val,void 0===t.targetHealthyDeployPercentage&&(t.targetHealthyDeployPercentage=100),t.action||"exact"!==t.resizeType||(t.action="scale_exact"),t.cloudProvider="aws",t.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(t.interestingHealthProviderNames=["Amazon"]),!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),this.updateResizeType=function(){"scale_exact"===t.action?(t.resizeType="exact",delete t.scalePct,delete t.scaleNum):(t.capacity={},"pct"===t.resizeType?delete t.scaleNum:(t.resizeType="incr",delete t.scalePct,t.scaleNum=t.scaleNum||0))}}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/resizeAsg/resizeAsgStage.html",'<div ng-controller="awsResizeAsgStageCtrl as resizeAsgStageCtrl">\n <div ng-if="!pipeline.strategy">\n <div ng-if="!viewState.accountsLoaded" class="horizontal center middle">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n <div ng-if="viewState.accountsLoaded">\n <account-region-cluster-selector application="application" component="stage" accounts="accounts">\n </account-region-cluster-selector>\n </div>\n </div>\n <stage-config-field label="Target">\n <target-select model="stage" options="resizeTargets"></target-select>\n </stage-config-field>\n <stage-config-field label="Action" help-key="pipeline.config.resizeAsg.action">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.action"\n ng-change="resizeAsgStageCtrl.updateResizeType()"\n ng-options="a.val as a.label for a in scaleActions"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <div ng-if="stage.action !== \'scale_exact\'">\n <stage-config-field label="{{stage.action === \'scale_to_cluster\' ? \'Additional Capacity\' : \'Type\'}}">\n <select\n class="form-control input-sm"\n required\n ng-model="stage.resizeType"\n ng-change="resizeAsgStageCtrl.updateResizeType()"\n ng-options="t.val as t.label for t in resizeTypes"\n >\n <option>Select an action...</option>\n </select>\n </stage-config-field>\n <div ng-if="stage.resizeType === \'pct\'">\n <stage-config-field label="Resize Percentage">\n <input type="number" min="0" ng-model="stage.scalePct" class="form-control input-sm" style="width: 80px" />\n <div>\n <em class="subinput-note"\n >This is the percentage by which the target server group\'s capacity will be increased</em\n >\n </div>\n </stage-config-field>\n </div>\n <div ng-if="stage.resizeType === \'incr\'">\n <stage-config-field label="Resize-by Amount">\n <input type="number" min="0" ng-model="stage.scaleNum" class="form-control input-sm" style="width: 80px" />\n <div>\n <em class="subinput-note"\n >This is the exact amount by which the target server group\'s capacity will be increased</em\n >\n </div>\n </stage-config-field>\n </div>\n <div ng-if="stage.action === \'scale_up\' || stage.action === \'scale_to_cluster\'">\n <stage-config-field>\n <target-healthy-percentage-selector command="stage"></target-healthy-percentage-selector>\n </stage-config-field>\n </div>\n </div>\n <div ng-if="stage.action === \'scale_exact\'">\n <stage-config-field class="small">\n <div class="row">\n <div class="col-md-3">Min</div>\n <div class="col-md-3">Max</div>\n <div class="col-md-3">Desired</div>\n </div>\n </stage-config-field>\n <stage-config-field label="Match Capacity">\n <div class="row">\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.min" class="form-control input-sm" />\n </div>\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.max" class="form-control input-sm" />\n </div>\n <div class="col-md-3">\n <input type="number" ng-model="stage.capacity.desired" class="form-control input-sm" />\n </div>\n </div>\n </stage-config-field>\n <stage-config-field>\n <em class="subinput-note">This is the exact amount to which the target server group will be scaled</em>\n </stage-config-field>\n </div>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html",'<span class="task-label" ng-if="!step.context.useNameAsLabel">\n Resize Server Group: {{step.context.serverGroupName}} ({{step.context.region}})\n</span>\n<span class="task-label" ng-if="step.context.useNameAsLabel"> {{step.name}} </span>\n')}]);t("spinnaker.amazon.pipeline.stage.rollbackClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"rollbackCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/rollbackCluster/rollbackClusterStage.html",validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsRollbackClusterStageCtrl",["$scope",function(e){const t=this,a=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.reset=()=>{t.accountUpdated(),t.resetSelectedCluster()},a.regions=a.regions||[],a.cloudProvider="aws",a.targetHealthyRollbackPercentage=a.targetHealthyRollbackPercentage||100,a.isNew&&e.application.attributes.platformHealthOnlyShowOverride&&e.application.attributes.platformHealthOnly&&(a.interestingHealthProviderNames=["Amazon"]),!a.credentials&&e.application.defaultCredentials.aws&&(a.credentials=e.application.defaultCredentials.aws),!a.regions.length&&e.application.defaultRegions.aws&&a.regions.push(e.application.defaultRegions.aws)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/rollbackCluster/rollbackClusterStage.html",'<div ng-controller="awsRollbackClusterStageCtrl as rollbackClusterStageCtrl" 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-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n\n <div class="row">\n <div class="col-sm-10 col-sm-offset-2" ng-if="stage.regions.length > 1">\n Wait\n <input\n type="number"\n min="0"\n ng-model="stage.waitTimeBetweenRegions"\n class="form-control input-sm inline-number"\n />\n seconds between regional rollbacks.\n </div>\n <div class="col-sm-10 col-sm-offset-2">\n Consider rollback successful when\n <input\n type="number"\n min="0"\n max="100"\n ng-model="stage.targetHealthyRollbackPercentage"\n class="form-control input-sm inline-number"\n />\n percent of instances are healthy.\n </div>\n </div>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.scaleDownClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"scaleDownCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"remainingFullSizeServerGroups",fieldLabel:"Keep [X] full size Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}],strategy:!0})})).controller("awsScaleDownClusterStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),void 0===t.remainingFullSizeServerGroups&&(t.remainingFullSizeServerGroups=1),void 0===t.allowScaleDownActive&&(t.allowScaleDownActive=!1),this.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===t.preferLargerOverNewer&&(t.preferLargerOverNewer="false"),t.preferLargerOverNewer=t.preferLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html",'<div ng-controller="awsScaleDownClusterStageCtrl as scaleDownClusterStageCtrl" 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="Scale Down Options">\n <div class="form-inline">\n <p>\n Keep the\n <input\n type="number"\n min="0"\n required\n ng-model="stage.remainingFullSizeServerGroups"\n class="form-control input-sm"\n style="width: 50px"\n />\n <select class="form-control input-sm" ng-model="stage.preferLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n {{scaleDownClusterStageCtrl.pluralize(\'server group\', stage.remainingFullSizeServerGroups)}} at current size.\n </p>\n <p>The remaining server groups will be scaled down to zero instances.</p>\n </div>\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-offset-3 col-md-6 checkbox">\n <label>\n <input type="checkbox" ng-model="stage.allowScaleDownActive" />\n Allow scale down of active server groups\n </label>\n </div>\n </div>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.aws.shrinkClusterStage",[]).config((function(){Pe.pipeline.registerStage({provides:"shrinkCluster",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html",accountExtractor:e=>[e.context.credentials],configAccountExtractor:e=>[e.credentials],validators:[{type:"requiredField",fieldName:"cluster"},{type:"requiredField",fieldName:"shrinkToSize",fieldLabel:"shrink to [X] Server Groups"},{type:"requiredField",fieldName:"regions"},{type:"requiredField",fieldName:"credentials",fieldLabel:"account"}]})})).controller("awsShrinkClusterStageCtrl",["$scope",function(e){const t=e.stage;e.state={accounts:!1,regionsLoaded:!1},o.listAccounts("aws").then((function(t){e.accounts=t,e.state.accounts=!0})),t.regions=t.regions||[],t.cloudProvider="aws",!t.credentials&&e.application.defaultCredentials.aws&&(t.credentials=e.application.defaultCredentials.aws),!t.regions.length&&e.application.defaultRegions.aws&&t.regions.push(e.application.defaultRegions.aws),void 0===t.shrinkToSize&&(t.shrinkToSize=1),void 0===t.allowDeleteActive&&(t.allowDeleteActive=!1),this.pluralize=function(e,t){return 1===t?e:e+"s"},void 0===t.retainLargerOverNewer&&(t.retainLargerOverNewer="false"),t.retainLargerOverNewer=t.retainLargerOverNewer.toString()}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html",'<div ng-controller="awsShrinkClusterStageCtrl as shrinkClusterStageCtrl" 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="Shrink Options">\n <div class="form-inline">\n Shrink to\n <input\n type="number"\n min="0"\n required\n ng-model="stage.shrinkToSize"\n class="form-control input-sm"\n style="width: 50px"\n />\n {{shrinkClusterStageCtrl.pluralize(\'server group\', stage.shrinkToSize)}}, keeping the\n <select class="form-control input-sm" ng-model="stage.retainLargerOverNewer" style="width: 100px">\n <option value="true">largest</option>\n <option value="false">newest</option>\n </select>\n </div>\n </stage-config-field>\n <div class="form-group">\n <div class="col-md-offset-3 col-md-6 checkbox">\n <label>\n <input type="checkbox" ng-model="stage.allowDeleteActive" />\n Allow deletion of active server groups\n </label>\n </div>\n </div>\n <stage-platform-health-override application="application" stage="stage" platform-health-type="\'Amazon\'">\n </stage-platform-health-override>\n</div>\n')}]);t("spinnaker.amazon.pipeline.stage.tagImageStage",[]).config((function(){Pe.pipeline.registerStage({provides:"upsertImageTags",cloudProvider:"aws",templateUrl:"amazon/src/pipeline/stages/tagImage/tagImageStage.html",executionDetailsUrl:"amazon/src/pipeline/stages/tagImage/tagImageExecutionDetails.html",executionConfigSections:["tagImageConfig","taskStatus"]})})).controller("awsTagImageStageCtrl",["$scope",e=>{e.stage.tags=e.stage.tags||{},e.stage.cloudProvider=e.stage.cloudProvider||"aws";e.$watch("stage.requisiteStageRefIds",(()=>{const t=Ke.getAllUpstreamDependencies(e.pipeline,e.stage).filter((e=>Fe.IMAGE_PRODUCING_STAGES.includes(e.type)));e.consideredStages=new Map(t.map((e=>[e.refId,e.name])))}))}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/tagImage/tagImageStage.html",'<div ng-controller="awsTagImageStageCtrl as tagImageStageCtrl" class="form-horizontal">\n <stage-config-field label="Tags">\n <map-editor model="stage.tags" allow-empty="true"></map-editor>\n </stage-config-field>\n <stage-config-field label="Stages (optional)" help-key="aws.tagImage.consideredStages" help-key-expand="true">\n <div class="checkbox">\n <checklist model="stage.consideredStages" items="consideredStages"></checklist>\n </div>\n </stage-config-field>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/pipeline/stages/tagImage/tagImageExecutionDetails.html",'<div ng-controller="BaseExecutionDetailsCtrl">\n <execution-details-section-nav sections="configSections"></execution-details-section-nav>\n <div class="step-section-details" ng-if="detailsSection === \'tagImageConfig\'">\n <div class="row" ng-if="stage.context.targets">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt if-multiple-providers>Provider</dt>\n <dd if-multiple-providers>Amazon</dd>\n <dt>Images</dt>\n <dd ng-repeat="target in stage.context.targets">\n {{target.imageName}}<br />\n <em>{{target.regions.join(\', \')}}</em>\n </dd>\n </dl>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <dl class="dl-narrow dl-horizontal">\n <dt>Tags</dt>\n <dd ng-repeat="(key, val) in stage.context.tags" ng-if="val !== null">{{key}} = {{val}}</dd>\n <dt ng-if="stage.context.consideredStages">Stages</dt>\n <dd ng-repeat="consideredStage in stage.context.consideredStages">\n <stage-name stages="execution.stages" ref-id="consideredStage"></stage-name>\n </dd>\n </dl>\n </div>\n </div>\n\n <stage-failure-message stage="stage" message="stage.failureMessage"></stage-failure-message>\n </div>\n\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')}]);t("spinnaker.amazon.react",[]).run(["$injector",function(e){qn.initialize(e),Un.initialize(e)}]);t("spinnaker.amazon.search.searchResultFormatter",[]).factory("awsSearchResultFormatter",(function(){return{securityGroups:function(e){return Pn.getVpcName(e.vpcId).then((function(t){const a=t?e.region+" - "+t.toLowerCase():e.region;return e.name+" ("+a+")"}))}}}));t("spinnaker.amazon.securityGroup.baseConfig.controller",[_a,Te]).controller("awsConfigSecurityGroupMixin",["$scope","$state","$uibModalInstance","application","securityGroup","securityGroupReader","cacheInitializer",function(e,t,a,n,r,i,s){let l;const c=this;e.self=e,e.application=n,e.customComponentIsvalid=!0,e.state={submitting:!1,regionError:void 0,refreshingSecurityGroups:!1,removedRules:[],infiniteScroll:{numToAdd:20,currentItems:20}},e.allVpcs=[],e.wizard=Ye,e.hideClassic=!1,c.addMoreItems=function(){e.state.infiniteScroll.currentItems+=e.state.infiniteScroll.numToAdd};const d=()=>e.securityGroup.accountName||e.securityGroup.credentials;function p(){if(e.$$destroyed)return;a.close();const n={name:e.securityGroup.name,accountId:d(),region:e.securityGroup.regions[0],vpcId:e.securityGroup.vpcId,provider:"aws"};t.includes("**.firewallDetails")?t.go("^.firewallDetails",n):t.go(".firewallDetails",n)}function u(){e.availableSecurityGroups=[],e.existingSecurityGroupNames=[]}function m(){e.state.refreshTime=Se.get("securityGroups").getStats().ageMax}e.taskMonitor=new v({application:n,title:`Creating your ${U.get("firewall")}`,modalInstance:a,onTaskComplete:function(){n.securityGroups.refresh(),n.securityGroups.onNextRefresh(e,p)}}),e.securityGroup=r,c.initializeAccounts=()=>o.listAllAccounts("aws").then((function(t){e.accounts=t.filter((e=>!1!==e.authorized)),e.allAccounts=t,c.accountUpdated()})),c.upsert=function(){e.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(e.securityGroup,n,"Create")}))},c.accountUpdated=function(){const t=e.securityGroup;t.account=t.accountId=t.accountName=t.credentials,o.getRegionsForAccount(d()).then((t=>{e.regions=t.map((e=>e.name)),u(),c.regionUpdated(),e.state.isNew&&c.updateName()}))},c.regionUpdated=function(){const t=d(),a=e.securityGroup.regions||[];Pn.listVpcs().then((function(n){const r=Mt.groupBy(n.filter((e=>e.account===t)),"label");e.allVpcs=n;const i=[];Mt.forOwn(r,(function(e,n){a.every((a=>e.some((e=>e.region===a&&e.account===t))))&&i.push({ids:e.filter((e=>a.includes(e.region))).map((e=>e.id)),label:n,deprecated:e[0].deprecated})})),e.activeVpcs=i.filter((function(e){return!e.deprecated})),e.deprecatedVpcs=i.filter((function(e){return e.deprecated})),e.vpcs=i,e.state.regionError=e.state.isClone&&(e.securityGroup.regions||[]).includes(e.state.originRegion),c.updateVpcId(i)}))},this.updateVpcId=t=>{const a=fn.classicLaunchLockout;if(!r.id&&a){if(Number(Mt.get(n,"attributes.createTs",0))>=a&&(e.hideClassic=!0,!r.vpcId&&t.length)){let a;if(fn.defaults.vpc){const e=t.find((e=>e.label===fn.defaults.vpc));e&&(a=e.ids[0])}r.vpcId=a||(e.activeVpcs.length?e.activeVpcs[0].ids[0]:t[0].ids[0])}}const i=e.allVpcs.find((t=>t.id===e.securityGroup.vpcId)),s=(t||[]).find((e=>i&&i.label===e.label)),l=(t||[]).find((e=>fn.defaults.vpc===e.label))||(e.activeVpcs||[])[0];e.securityGroup.vpcId=s&&s.ids[0]||l&&l.ids[0],this.vpcUpdated()},this.vpcUpdated=function(){const t=d(),a=e.securityGroup.regions;t&&a.length?function(){const t=e.securityGroup.vpcId||null,a=d(),n=e.securityGroup.regions||[];let r=[],i=[];n.forEach((function(n){let s=null;if(t){const r=Mt.find(e.allVpcs,{id:t});s=Mt.find(e.allVpcs,{account:a,region:n,name:r.name}).id}const o=Mt.get(l,[a,"aws",n].join("."),[]).filter((e=>e.vpcId===s)).map((e=>e.name));r=Mt.uniq(r.concat(o)),i=i.length?Mt.intersection(i,o):r})),e.availableSecurityGroups=i,e.existingSecurityGroupNames=r,e.state.securityGroupsLoaded=!0,function(){const t=e.state.removedRules,a=e.securityGroup;e.securityGroup.securityGroupIngress=(a.securityGroupIngress||[]).filter((n=>!(!n.accountName||!n.vpcId||n.accountName===a.accountName&&n.vpcId===a.vpcId)||(!(n.name&&!e.availableSecurityGroups.includes(n.name)&&!t.includes(n.name))||(t.push(n.name),!1)))),t.length&&Ye.markDirty("Ingress")}()}():u(),e.coordinatesChanged.next()},c.mixinUpsert=function(t){e.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(e.securityGroup,n,t)}))},c.refreshSecurityGroups=function(){return e.state.refreshingSecurityGroups=!0,s.refreshCache("securityGroups").then((function(){return c.initializeSecurityGroups().then((function(){c.vpcUpdated(),e.state.refreshingSecurityGroups=!1,m()}))}))},l={},e.allSecurityGroupsUpdated=new ya,e.coordinatesChanged=new ya,c.initializeSecurityGroups=function(){return i.getAllSecurityGroups().then((function(t){m(),l=t;const a=e.securityGroup.credentials||e.securityGroup.accountName,n=e.securityGroup.regions[0],r=e.securityGroup.vpcId||null;let i;i=a&&n?Mt.filter(t[a].aws[n],{vpcId:r}):t,e.availableSecurityGroups=Mt.map(i,"name");const s=fn.securityGroupExclusions;e.allSecurityGroups=s?Qe(t,(e=>!s.includes(e))):t,e.allSecurityGroupsUpdated.next(),e.state.regionError=e.state.isClone&&(e.securityGroup.regions||[]).includes(e.state.originRegion)}))},c.cancel=function(){a.dismiss()};const g=/^[\x20-\x7F]+$/,h=/^[a-zA-Z0-9\s._\-:/()#,@[\]+=&;{}!$*]+$/;c.getCurrentNamePattern=function(){return e.securityGroup.vpcId?h:g},c.updateName=function(){const{securityGroup:t}=e,a=n.isStandalone?n.name.split("-")[0]:n.name,r=Ee.getClusterName(a,t.stack,t.detail);t.name=r,e.namePreview=r},c.namePattern={test:function(e){return c.getCurrentNamePattern().test(e)}},c.addRule=function(e){e.push({type:"tcp",startPort:7001,endPort:7001})},c.removeRule=function(e,t){e.splice(t,1)},c.updateRuleType=function(e,t,a){const n=t[a];"icmp"!==e&&"icmpv6"!==e||(n.startPort=0,n.endPort=0)},c.dismissRemovedRules=function(){e.state.removedRules=[],Ye.markClean("Ingress"),Ye.markComplete("Ingress")}}]);e.module("spinnaker.amazon.securityGroup.clone.controller",["spinnaker.amazon.securityGroup.baseConfig.controller"]).controller("awsCloneSecurityGroupController",["$scope","$uibModalInstance","$controller","securityGroup","application",function(t,a,n,r,i){const s=this;s.firewallLabel=U.get("Firewall"),t.pages={location:"amazon/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"},r.credentials=r.accountName,t.namePreview=r.name,e.extend(this,n("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:i,securityGroup:r})),t.state.isNew=!0,t.allowDuplicateNames=!0,t.state.isClone=!0,t.state.originRegion=r.regions&&r.regions[0],o.listAccounts("aws").then((function(e){t.accounts=e,s.accountUpdated()})),r.securityGroupIngress=Mt.chain(r.inboundRules).filter((function(e){return e.securityGroup})).map((function(e){return e.portRanges.map((function(t){return{name:e.securityGroup.name,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),r.ipIngress=Mt.chain(r.inboundRules).filter((function(e){return e.range})).map((function(e){return e.portRanges.map((function(t){return{cidr:e.range.ip+e.range.cidr,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),s.upsert=function(){const{credentials:e}=t.securityGroup;Object.assign(t.securityGroup,{account:e,accountName:e,accountId:e}),s.mixinUpsert("Clone")},s.initializeSecurityGroups().then(s.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="container-fluid form-horizontal">\n <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 <help-field key="aws.securityGroup.name"></help-field>\n <input\n type="hidden"\n class="form-control input-sm"\n ng-model="securityGroup.name"\n ng-model-options="{allowInvalid: true}"\n validate-unique="{{allowDuplicateNames ? \'\' : \'existingSecurityGroupNames\'}}"\n validate-ignore-case="true"\n name="securityGroupName"\n ng-pattern="ctrl.namePattern"\n trigger-validation="securityGroup.subnet"\n required\n />\n <validation-error\n ng-if="form.securityGroupName.$error.validateUnique && securityGroup.credentials"\n message="A {{ctrl.translate(\'firewall\')}} named \'{{namePreview}}\' already exists in one or more of the selected regions. Use a unique stack and detail to create a new {{ctrl.translate(\'firewall\')}}."\n ></validation-error>\n <validation-error\n ng-if="form.securityGroupName.$error.pattern"\n message="Name must match {{ctrl.getCurrentNamePattern().toString()}}"\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-8">\n <account-select-field\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'aws\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Regions</div>\n <div class="col-md-8">\n <input type="hidden" ng-model="securityGroup.regions[0]" required />\n <checklist\n ng-if="securityGroup.credentials"\n items="regions"\n model="securityGroup.regions"\n inline="true"\n on-change="ctrl.regionUpdated()"\n ></checklist>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <validation-error\n ng-if="state.regionError"\n message="A security group cannot be cloned into a region it already exists in. Please deselect \'{{state.originRegion}}\' to clear this error."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\n ng-model="securityGroup.stack"\n ng-change="ctrl.updateName()"\n />\n </div>\n <div class="col-md-2 sm-label-right">Detail</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\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-3 sm-label-right">Description (required)</div>\n <div class="col-md-8">\n <textarea required cols="2" class="form-control input-sm no-spel" ng-model="securityGroup.description">\n </textarea>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">VPC <help-field key="aws.securityGroup.vpc"></help-field></div>\n <div class="col-md-8">\n <select\n class="form-control input-sm"\n ng-model="securityGroup.vpcId"\n ng-change="ctrl.vpcUpdated()"\n ng-if="securityGroup.regions.length"\n >\n <option value="" ng-if="!hideClassic">None (EC2 Classic)</option>\n <option\n ng-repeat="vpc in activeVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n <option ng-if="activeVpcs.length && deprecatedVpcs.length" disabled>---------------</option>\n <option\n ng-repeat="vpc in deprecatedVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n </select>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <p class="form-control-static" ng-if="securityGroup.credentials && !securityGroup.regions.length">\n (Select at least one region)\n </p>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);e.module("spinnaker.amazon.securityGroup.create.controller",[_a,Je]).controller("awsCreateSecurityGroupCtrl",["$scope","$uibModalInstance","$state","$controller","cacheInitializer","application","securityGroup",function(t,a,n,r,i,s,l){t.pages={location:"amazon/src/securityGroup/configure/createSecurityGroupProperties.html",ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"};const o=this;o.translate=e=>U.get(e),e.extend(this,r("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:s,securityGroup:l})),t.state.isNew=!0,o.upsert=()=>o.mixinUpsert("Create"),o.initializeSecurityGroups().then(o.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupProperties.html",'<div class="container-fluid form-horizontal">\n <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 <help-field key="aws.securityGroup.name"></help-field>\n <input\n type="hidden"\n class="form-control input-sm"\n ng-model="securityGroup.name"\n ng-model-options="{allowInvalid: true}"\n validate-unique="{{allowDuplicateNames ? \'\' : \'existingSecurityGroupNames\'}}"\n validate-ignore-case="true"\n name="securityGroupName"\n ng-pattern="ctrl.namePattern"\n trigger-validation="securityGroup.subnet"\n required\n />\n <validation-error\n ng-if="form.securityGroupName.$error.validateUnique && securityGroup.credentials"\n message="A {{ctrl.translate(\'firewall\')}} named \'{{namePreview}}\' already exists in one or more of the selected regions. Use a unique stack and detail to create a new {{ctrl.translate(\'firewall\')}}."\n ></validation-error>\n <validation-error\n ng-if="form.securityGroupName.$error.pattern"\n message="Name must match {{ctrl.getCurrentNamePattern().toString()}}"\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-8">\n <account-select-field\n component="securityGroup"\n field="credentials"\n accounts="accounts"\n provider="\'aws\'"\n on-change="ctrl.accountUpdated()"\n ></account-select-field>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Regions</div>\n <div class="col-md-8">\n <input type="hidden" ng-model="securityGroup.regions[0]" required />\n <checklist\n ng-if="securityGroup.credentials"\n items="regions"\n model="securityGroup.regions"\n inline="true"\n on-change="ctrl.regionUpdated()"\n ></checklist>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <validation-error\n ng-if="state.regionError"\n message="A security group cannot be cloned into a region it already exists in. Please deselect \'{{state.originRegion}}\' to clear this error."\n ></validation-error>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">Stack</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\n ng-model="securityGroup.stack"\n ng-change="ctrl.updateName()"\n />\n </div>\n <div class="col-md-2 sm-label-right">Detail</div>\n <div class="col-md-3">\n <input\n type="text"\n class="form-control input-sm no-spel"\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-3 sm-label-right">Description (required)</div>\n <div class="col-md-8">\n <textarea required cols="2" class="form-control input-sm no-spel" ng-model="securityGroup.description">\n </textarea>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-3 sm-label-right">VPC <help-field key="aws.securityGroup.vpc"></help-field></div>\n <div class="col-md-8">\n <select\n class="form-control input-sm"\n ng-model="securityGroup.vpcId"\n ng-change="ctrl.vpcUpdated()"\n ng-if="securityGroup.regions.length"\n >\n <option value="" ng-if="!hideClassic">None (EC2 Classic)</option>\n <option\n ng-repeat="vpc in activeVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n <option ng-if="activeVpcs.length && deprecatedVpcs.length" disabled>---------------</option>\n <option\n ng-repeat="vpc in deprecatedVpcs | orderBy: \'label\'"\n value="{{vpc.ids[0]}}"\n ng-selected="securityGroup.vpcId === vpc.ids[0]"\n >\n {{vpc.label}}\n </option>\n </select>\n <p class="form-control-static" ng-if="!securityGroup.credentials">(Select an account)</p>\n <p class="form-control-static" ng-if="securityGroup.credentials && !securityGroup.regions.length">\n (Select at least one region)\n </p>\n </div>\n </div>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);e.module("spinnaker.amazon.securityGroup.edit.controller",[_a]).controller("awsEditSecurityGroupCtrl",["$scope","$uibModalInstance","$state","application","securityGroup","$controller",function(t,a,n,r,i,s){t.self=t,t.pages={ingress:"amazon/src/securityGroup/configure/createSecurityGroupIngress.html"},t.securityGroup=i,t.state={refreshingSecurityGroups:!1},t.securityGroup.regions=[t.securityGroup.region],t.securityGroup.credentials=t.securityGroup.accountName,e.extend(this,s("awsConfigSecurityGroupMixin",{$scope:t,$uibModalInstance:a,application:r,securityGroup:i})),t.state.isNew=!1,t.taskMonitor=new v({application:r,title:`Updating your ${U.get("firewall")}`,modalInstance:a,onTaskComplete:()=>r.securityGroups.refresh()}),i.securityGroupIngress=Mt.chain(i.inboundRules).filter((e=>e.securityGroup)).map((e=>e.portRanges.map((t=>{const a=e.securityGroup.vpcId===i.vpcId?null:e.securityGroup.vpcId;return{accountName:e.securityGroup.accountName||e.securityGroup.accountId,accountId:e.securityGroup.accountId,vpcId:a,id:e.securityGroup.id,name:e.securityGroup.inferredName?null:e.securityGroup.name,type:e.protocol,startPort:t.startPort,endPort:t.endPort,existing:!0}})))).flatten().value(),i.ipIngress=Mt.chain(i.inboundRules).filter((function(e){return e.range})).map((function(e){return e.portRanges.map((function(t){return{cidr:e.range.ip+e.range.cidr,type:e.protocol,startPort:t.startPort,endPort:t.endPort}}))})).flatten().value(),this.upsert=function(){const e=t.securityGroup,a={credentials:e.accountName,name:e.name,description:e.description,vpcId:e.vpcId,region:e.region,securityGroupIngress:e.securityGroupIngress,ipIngress:e.ipIngress};t.taskMonitor.submit((function(){return Xe.upsertSecurityGroup(a,r,"Update")}))},this.cancel=function(){a.dismiss()},this.initializeSecurityGroups().then(this.initializeAccounts)}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroupIngress.html",'<div class="container-fluid form-horizontal">\n <div class="modal-body">\n <div class="row">\n <div class="col-md-12" ng-if="state.removedRules.length">\n <div class="alert alert-danger">\n <p>\n <i class="fa fa-exclamation-triangle"></i> The following\n <firewall-label label="firewalls"></firewall-label> could not be found in the selected account/region/VPC\n and were removed:\n </p>\n <ul>\n <li ng-repeat="securityGroup in state.removedRules">{{securityGroup}}</li>\n </ul>\n <p class="text-right">\n <a class="btn btn-sm btn-primary dirty-flag-dismiss" href ng-click="ctrl.dismissRemovedRules()">Okay</a>\n </p>\n </div>\n </div>\n </div>\n <div class="row">\n <div class="col-md-12">\n <p class="info">\n <span class="glyphicon glyphicon-info-sign"></span> IP range rules can only be edited through the AWS Console.\n </p>\n </div>\n </div>\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: 50%"><firewall-label label="Firewall"></firewall-label></th>\n <th style="width: 15%">Protocol</th>\n <th style="width: 15%">Start Port</th>\n <th style="width: 15%">End Port</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="rule in securityGroup.securityGroupIngress">\n <td>\n <ingress-rule-group-selector\n rule="rule"\n ng-if="state.securityGroupsLoaded"\n security-group="securityGroup"\n vpcs="allVpcs"\n accounts="allAccounts"\n all-security-groups="allSecurityGroups"\n coordinates-changed="coordinatesChanged"\n all-security-groups-updated="allSecurityGroupsUpdated"\n ></ingress-rule-group-selector>\n </td>\n <td>\n <select\n class="form-control input-sm"\n ng-model="rule.type"\n ng-options="protocol as protocol.toUpperCase() for protocol in [\'tcp\', \'udp\', \'icmp\', \'icmpv6\']"\n ng-change="ctrl.updateRuleType(rule.type, securityGroup.securityGroupIngress, $index)"\n required\n ></select>\n </td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.startPort" required /></td>\n <td><input class="form-control input-sm" type="number" min="0" ng-model="rule.endPort" required /></td>\n <td>\n <a class="sm-label" ng-click="ctrl.removeRule(securityGroup.securityGroupIngress, $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.addRule(securityGroup.securityGroupIngress)">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new\n <firewall-label label="Firewall"></firewall-label> Rule\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n <div class="form-group small" style="margin-top: 20px">\n <div class="col-md-12">\n <p>\n <span ng-if="state.refreshingSecurityGroups"><span class="fa fa-sync-alt fa-spin"></span></span>\n <firewall-label label="Firewalls"></firewall-label>\n <span ng-if="!state.refreshingSecurityGroups">last refreshed {{ state.refreshTime | timestamp }}</span>\n <span ng-if="state.refreshingSecurityGroups"> 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="ctrl.refreshSecurityGroups()">click here</a> to refresh the list.\n </p>\n </div>\n </div>\n <security-group-details-custom security-group-details="securityGroup" ctrl="ctrl" scope="self" />\n </div>\n</div>\n')}]);const ui={bindings:{rule:"=",securityGroup:"=",accounts:"=",vpcs:"=",allSecurityGroups:"=",coordinatesChanged:"=",allSecurityGroupsUpdated:"="},templateUrl:"amazon/src/securityGroup/configure/ingressRuleGroupSelector.component.html",controller:class{constructor(){this.infiniteScroll={currentItems:20}}addMoreItems(){this.infiniteScroll.currentItems+=20}resetCurrentItems(){this.infiniteScroll.currentItems=20}addRegionalVpc(e){const t=e.account;this.regionalVpcs[t]||(this.regionalVpcs[t]=[]),this.regionalVpcs[t].push({name:e.name,region:e.region,account:t,id:e.id,label:e.label,deprecated:e.deprecated,cloudProvider:e.cloudProvider})}enableCrossAccount(){var e;this.rule.crossAccountEnabled=!0,this.crossAccountAccounts=this.accounts;const t=null==(e=fn)?void 0:e.crossAccountIngressExclusions[this.securityGroup.credentials];t&&Array.isArray(t)&&(this.crossAccountAccounts=this.accounts.filter((e=>!t.includes(e.name)))),this.rule.accountName=this.securityGroup.credentials,this.rule.vpcId=this.securityGroup.vpcId}disableCrossAccount(){this.rule.crossAccountEnabled=!1,this.rule.accountName=void 0,this.rule.vpcId=void 0}$onInit(){this.setAvailableSecurityGroups(),this.coordinatesChangedListener=this.coordinatesChanged.subscribe((()=>this.setAvailableSecurityGroups())),this.securityGroupsUpdatedListener=this.allSecurityGroupsUpdated.subscribe((()=>this.setAvailableSecurityGroups()))}$onDestroy(){this.coordinatesChangedListener.unsubscribe(),this.securityGroupsUpdatedListener.unsubscribe()}setAvailableSecurityGroups(){const e=this.rule.accountName||this.securityGroup.credentials,t=this.securityGroup.regions,a=this.rule.vpcId||this.securityGroup.vpcId||null;let n=[],r=[];t.length>1&&this.disableCrossAccount(),t.forEach((t=>{var i,s,l,o;let c=null;if(a){const n=this.vpcs.find((e=>e.id===a)),r=this.vpcs.find((a=>a.account===e&&a.region===t&&a.name===n.name));c=r?r.id:void 0}const d=(null!=(o=null==(l=null==(s=null==(i=this.allSecurityGroups)?void 0:i[e])?void 0:s.aws)?void 0:l[t])?o:[]).filter((e=>e.vpcId===c)).map((e=>e.name));n=Yt(n.concat(d)),r=r.length?ca(r,d):n})),1===t.length&&this.configureAvailableVpcs(),this.availableSecurityGroups=r,r.includes(this.rule.name)||this.rule.existing||(this.rule.name=null)}configureAvailableVpcs(){const e=this.securityGroup.regions[0],t=this.vpcs.filter((t=>t.region===e));this.regionalVpcs={},t.forEach((e=>this.addRegionalVpc(e))),this.reconcileRuleVpc(t)}reconcileRuleVpc(e){if(this.rule.vpcId&&!this.rule.existing){if(!this.securityGroup.vpcId)return this.rule.vpcId=null,void(this.rule.name=null);const t=e.find((e=>e.id===this.rule.vpcId)),a=e.find((e=>e.account===this.rule.accountName&&e.name===t.name));a?this.rule.vpcId=a.id:(this.rule.vpcId=null,this.rule.name=null)}}}};t("spinnaker.amazon.securityGroup.configure.ingressRuleGroupSelector",[]).component("ingressRuleGroupSelector",ui),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/ingressRuleGroupSelector.component.html",'<span class="form-control-static" ng-if="$ctrl.rule.existing">\n <account-tag\n account="$ctrl.rule.accountName"\n ng-if="$ctrl.rule.accountName !== $ctrl.securityGroup.accountName"\n ></account-tag>\n {{ $ctrl.rule.name || $ctrl.rule.id }}\n</span>\n\n<div ng-if="$ctrl.rule.crossAccountEnabled && $ctrl.securityGroup.regions.length === 1" class="cross-account-select">\n <div class="row">\n <div class="col-md-3"><span class="small">Account</span></div>\n <div class="col-md-9">\n <account-select-field\n component="$ctrl.rule"\n field="accountName"\n accounts="$ctrl.crossAccountAccounts"\n provider="\'aws\'"\n on-change="$ctrl.setAvailableSecurityGroups()"\n ></account-select-field>\n </div>\n </div>\n <div class="row" ng-if="$ctrl.securityGroup.vpcId">\n <div class="col-md-3"><span class="small">VPC</span></div>\n <div class="col-md-9">\n <select class="form-control input-sm" ng-model="$ctrl.rule.vpcId" ng-change="$ctrl.setAvailableSecurityGroups()">\n <option\n ng-repeat="vpc in $ctrl.regionalVpcs[$ctrl.rule.accountName]"\n value="{{ vpc.id }}"\n ng-selected="$ctrl.rule.vpcId === vpc.id"\n >\n {{ vpc.label }}\n </option>\n </select>\n </div>\n </div>\n</div>\n\n<div class="row">\n <div class="col-md-3">\n <span class="small" ng-if="$ctrl.rule.crossAccountEnabled">Group</span>\n </div>\n <div class="col-md-{{ $ctrl.rule.crossAccountEnabled ? 9 : 12 }}">\n <ui-select\n ng-if="!$ctrl.rule.existing"\n ng-model="$ctrl.rule.name"\n uis-open-close="$ctrl.resetCurrentItems()"\n class="form-control input-sm"\n required\n style="width: 100%"\n >\n <ui-select-match>{{ $select.selected }}</ui-select-match>\n <ui-select-choices\n repeat="securityGroup as securityGroup in $ctrl.availableSecurityGroups | filter: $select.search | limitTo: $ctrl.infiniteScroll.currentItems"\n infinite-scroll="$ctrl.addMoreItems()"\n infinite-scroll-distance="4"\n >\n <span ng-bind-html="securityGroup | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n</div>\n\n<a\n href\n class="small"\n ng-if="!$ctrl.rule.existing && $ctrl.securityGroup.regions.length === 1 && !$ctrl.rule.crossAccountEnabled"\n ng-click="$ctrl.enableCrossAccount($index)"\n>\n Select from a different account <span ng-if="$ctrl.securityGroup.vpcId">or VPC</span>\n</a>\n\n<div ng-if="$ctrl.crossAccountAccounts && $ctrl.crossAccountAccounts.length !== $ctrl.accounts.length">\n <help-field key="aws.securityGroup.cross.account.ingress.help" expand="true"></help-field>\n</div>\n<span ng-if="$ctrl.securityGroup.regions.length > 1" class="small">\n Cross-account rules disabled when 2+ regions selected\n</span>\n')}]);var mi=Object.defineProperty,gi=Object.getOwnPropertyDescriptor;let hi=class extends $t.Component{render(){return null}};hi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?gi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&mi(t,a,i),i})([ce("aws.securityGroup.details.custom")],hi);t("spinnaker.amazon.securityGroups.details.custom.component",[]).component("securityGroupDetailsCustom",ja(M(hi,"securityGroupDetailsCustom"),["securityGroupDetails","ctrl","scope"]));e.module("spinnaker.amazon.securityGroup.details.controller",[_a,Te,"spinnaker.amazon.securityGroup.clone.controller",xe]).controller("awsSecurityGroupDetailsCtrl",["$scope","$state","resolvedSecurityGroup","app","securityGroupReader","$uibModal",function(t,a,n,r,i,s){this.application=r;const l=r,o=n;function c(){return i.getSecurityGroupDetails(l,o.accountId,o.provider,o.region,o.vpcId,o.name).then((function(e){return Pn.getVpcName(e.vpcId).then((t=>(e.vpcName=t,e)))})).then((function(a){if(t.state.loading=!1,!a||Mt.isEmpty(a))p();else{const n=i.getApplicationSecurityGroup(l,o.accountId,o.region,o.name);e.extend(o,n,a),t.securityGroup=o,t.ipRules=function(e){const t=Mt.groupBy(e.ipRangeRules,(e=>e.range.ip+e.range.cidr));return Object.keys(t).map((e=>({address:e,rules:d(t,e)}))).filter((e=>e.rules.length))}(o),t.securityGroupRules=function(e){const t=Mt.groupBy(e.securityGroupRules,(e=>e.securityGroup.id));return Object.keys(t).map((e=>({securityGroup:t[e][0].securityGroup,rules:d(t,e)}))).filter((e=>e.rules.length))}(o)}}),p)}function d(e,t){const a=[];return e[t].forEach((e=>{(e.portRanges||[]).forEach((t=>{("-1"===e.protocol||void 0!==t.startPort&&void 0!==t.endPort)&&a.push({startPort:t.startPort,endPort:t.endPort,protocol:e.protocol,description:e.description})}))})),a}function p(){t.$$destroyed||(r.isStandalone?(t.group=o.name,t.state.notFound=!0,t.state.loading=!1,V.removeLastItem("securityGroups")):a.go("^",{allowModalToStayOpen:!0},{location:"replace"}))}this.firewallLabel=U.get("Firewall"),t.detailsTemplateUrl=O.getValue("aws","securityGroup.detailsTemplateUrl"),t.state={loading:!0,standalone:r.isStandalone},c().then((()=>{t.$$destroyed||r.isStandalone||r.securityGroups.onRefresh(t,c)})),this.editInboundRules=function(){et(t.securityGroup,l).then((a=>new Promise((e=>setTimeout(e,500))).then((()=>{a&&s.open({templateUrl:"amazon/src/securityGroup/configure/editSecurityGroup.html",controller:"awsEditSecurityGroupCtrl as ctrl",size:"lg",resolve:{securityGroup:function(){return e.copy(t.securityGroup)},application:function(){return l}}})}))))},this.cloneSecurityGroup=function(){s.open({templateUrl:"amazon/src/securityGroup/clone/cloneSecurityGroup.html",controller:"awsCloneSecurityGroupController as ctrl",size:"lg",resolve:{securityGroup:function(){const a=e.copy(t.securityGroup);return a.region&&(a.regions=[a.region]),a},application:function(){return l}}})},this.deleteSecurityGroup=function(){let e=!1;const a={removeDependencies:!0},n={application:l,title:"Deleting "+o.name,onTaskRetry:()=>{e=!0}},r=()=>{const t={cloudProvider:o.provider,vpcId:o.vpcId};return e&&Object.assign(t,a),Xe.deleteSecurityGroup(o,l,t)};et(t.securityGroup,l).then((e=>{e&&k.confirm({header:"Really delete "+o.name+"?",buttonText:"Delete "+o.name,account:o.accountId,taskMonitorConfig:n,submitMethod:r,retryBody:`<div><p>Retry deleting the ${U.get("firewall")} and revoke any dependent ingress rules?</p><p>Any instance or load balancer associations will have to removed manually.</p></div>`})}))},r.isStandalone&&(r.securityGroups={refresh:c})}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/editSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard\n heading="Edit {{securityGroup.name}}: {{securityGroup.region}}: {{securityGroup.accountName}}"\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 class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <submit-button\n is-disabled="form.$invalid || !wizard.isComplete() || state.submitting || !customComponentIsvalid"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="state.isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/clone/cloneSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard heading="Clone {{ctrl.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" mark-clean-on-view="false">\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="form.$invalid || !wizard.isComplete() || state.submitting || state.removedRules.length > 0 || !customComponentIsvalid || state.regionError"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]);var fi=Object.defineProperty,vi=Object.getOwnPropertyDescriptor;let yi=class extends $t.Component{render(){const e=this.props.ipRules||[],t=`IP Range Rules (${e.length})`;return $t.createElement(A,{heading:t},e.map((e=>$t.createElement(j,{className:"horizontal-when-filters-collapsed"},$t.createElement(B,{label:"IP Range",value:e.address}),$t.createElement(B,{label:"Port Ranges",value:e.rules.map((t=>"-1"===t.protocol?$t.createElement("span",null,"All ports and protocols",e.rules.length>1?$t.createElement("div",null,$t.createElement("em",null,"Additional port ranges are specified, but redundant:")):null):$t.createElement("div",null,$t.createElement("span",null,t.protocol,":",t.startPort," → ",t.endPort))))})))))}};yi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?vi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&fi(t,a,i),i})([ce("aws.securityGroup.ip.rules")],yi);t("spinnaker.amazon.securityGroups.details.securityGroups.component",[]).component("ipRangeRules",ja(M(yi,"ipRangeRules"),["ipRules"]));class bi{resolveIndexedSecurityGroup(e,t,a){return bi.resolveIndexedSecurityGroup(e,t,a)}static resolveIndexedSecurityGroup(e,t,a){return e[t.account][t.region][a]}}t("spinnaker.amazon.securityGroup.reader",[]).service("awsSecurityGroupReader",bi);t("spinnaker.amazon.securityGroup.transformer",[]).factory("awsSecurityGroupTransformer",(function(){return{normalizeSecurityGroup:function(e){return Pn.listVpcs().then(function(e){return function(t){const a=t.filter((function(t){return t.id===e.vpcId}));e.vpcName=a.length?a[0].name:""}}(e))},compress:function(e){const t=_t(e,"vpcId");return Object.keys(t).forEach((e=>{t[e]=t[e].map((e=>[e.name,e.id]))})),t},decompress:function(e){const t=[];return Object.keys(e).forEach((a=>{e[a].forEach((e=>{t.push({name:e[0],id:e[1],vpcId:a})}))})),t},supportsCompression:!0}}));t("spinnaker.amazon.securityGroup",["spinnaker.amazon.securityGroup.reader","spinnaker.amazon.securityGroup.clone.controller","spinnaker.amazon.securityGroup.configure.ingressRuleGroupSelector","spinnaker.amazon.securityGroup.baseConfig.controller","spinnaker.amazon.securityGroup.create.controller","spinnaker.amazon.securityGroup.edit.controller","spinnaker.amazon.securityGroup.details.controller","spinnaker.amazon.securityGroup.transformer","spinnaker.amazon.securityGroups.details.securityGroups.component","spinnaker.amazon.securityGroups.details.custom.component"]);class wi extends $t.Component{constructor(e){super(e),this.state={templateSelectionText:{copied:["account, region, subnet, cluster name (stack, details)","load balancers",U.get("firewalls"),"instance type","all fields on the Advanced Settings page"],notCopied:["the following suspended scaling processes: Launch, Terminate, AddToLoadBalancer"],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.state.templateSelectionText.notCopied.push("the deployment strategy (if any) used to deploy the most recent server group")}render(){const{app:e,command:t,onDismiss:a,onTemplateSelected:n}=this.props,{templateSelectionText:r}=this.state;return $t.createElement(tt,{cloudProvider:"aws",application:e,command:t,onDismiss:a,onTemplateSelected:n,templateSelectionText:r})}}class Ei extends $t.Component{constructor(){super(...arguments),this.state={errorMessage:null,selectionMode:"packageImages",searchString:"",searchResults:null,isSearching:!1,packageImages:null,isLoadingPackageImages:!0},this.awsImageReader=new _n,this.props$=new ya,this.searchInput$=new ya,this.destroy$=new ya,this.sortImagesBy$=new Ea("ts"),this.buildImageMenu=e=>{const{ImageMenuHeading:t,ImageLabel:a}=this,{options:n}=e;return $t.createElement("div",{className:"Select-menu-outer"},$t.createElement("div",{className:"Select-menu",role:"listbox"},n.length>0&&$t.createElement(t,null),n.map((t=>$t.createElement(a,{key:t.imageName,option:t,params:e})))))},this.ImageMenuHeading=()=>{const e=this.sortImagesBy$.value;return $t.createElement("div",{className:"sp-padding-s-xaxis sp-padding-xs-yaxis small",style:{borderBottom:"1px solid var(--color-silver)",position:"sticky",top:0,backgroundColor:"var(--color-white)"}},$t.createElement("b",null,"Sort by: "),$t.createElement("a",{className:"clickable sp-padding-xs-xaxis",onClick:()=>this.setSortImagesBy("ts")},"ts"===e?$t.createElement("b",null,"timestamp (newest first)"):"timestamp (newest first)"),$t.createElement("span",null," | "),$t.createElement("a",{className:"clickable sp-padding-xs-xaxis",onClick:()=>this.setSortImagesBy("name")},"name"===e?$t.createElement("b",null,"name (A-Z)"):"name (A-Z)"))},this.ImageLabel=e=>{const{credentials:t,region:a}=this.props,{option:n,params:r}=e,i=n.amis[a]&&n.amis[a][0]?n.amis[a][0]:` - not found in ${t}/${a}`;return $t.createElement("div",{key:n.imageName,onClick:()=>r.selectValue(n),onMouseOver:()=>r.focusOption(n),className:"Select-option "+(r.focusedOption&&r.focusedOption.imageName===n.imageName?"is-focused":""),role:"option"},$t.createElement("div",null,n.imageName),$t.createElement("div",{className:"small"},$t.createElement("b",null,"Created: "),n.attributes.creationDate,$t.createElement("b",{className:"sp-padding-s-left"},"AMI: "),i))}}static makeFakeImage(e,t,a){if(!e&&!t)return null;return{imageName:e,amis:{[a]:[t]},attributes:{virtualizationType:"*",creationDate:(new Date).toISOString()}}}loadImagesFromApplicationName(e){const t=e.name.replace(/_/g,"[_\\-]")+"*";return this.awsImageReader.findImages({q:t})}buildQueryForSimilarImages(e){let t=!1,a=e.split("_")[0];const n=a.split("-");n.length>3&&(a=n.slice(0,-3).join("-"),t=!0);return!a||a.length<3?null:a+(t?"-*":"*")}loadImageById(e,t,a){return e?this.awsImageReader.getImage(e,t,a).catch((()=>null)):qa.when(null)}searchForImages(e){return e&&e.length>=3?this.awsImageReader.findImages({q:e}):qa.when([])}fetchPackageImages(e,t,a,n){const r=e&&e.amis&&e.amis[t]&&e.amis[t][0];return this.loadImageById(r,t,a).then((e=>e?this.searchForImages(this.buildQueryForSimilarImages(e.imageName)).then((t=>t.find((t=>t.imageName===e.imageName))?t:t.concat(e))):this.loadImagesFromApplicationName(n)))}selectImage(e){this.props.value!==e&&this.props.onChange(e)}findMatchingImage(e,t){return e.find((e=>t&&t.imageName===e.imageName))}componentDidMount(){const e=this.props$.pipe(Sa((e=>e.region)),Na()),{value:t,region:a,credentials:n,application:r}=this.props;this.setState({isLoadingPackageImages:!0});const i=this.fetchPackageImages(t,a,n,r),s=ba(i).pipe(za((e=>(console.error(e),this.setState({errorMessage:"Unable to load package images"}),Ca([])))),Aa((()=>this.setState({isLoadingPackageImages:!1})))),l=wa([s,e,this.sortImagesBy$]).pipe(Sa((([e,t,a])=>{const n=e.filter((e=>!!e.amis[t]));return this.sortImages(n,a)}))),o=this.searchInput$.pipe(Aa((e=>this.setState({searchString:e}))),Na(),Ba(250)).pipe(Aa((()=>this.setState({isSearching:!0}))),Ta((e=>this.searchForImages(e))),za((e=>(console.error(e),this.setState({errorMessage:"Unable to search for images"}),Ca([])))),Aa((()=>this.setState({isSearching:!1}))));wa([o,e,this.sortImagesBy$]).pipe(Sa((([e,t,a])=>{const{searchString:n}=this.state;if(0===e.length&&/ami-[0-9a-f]{8,17}/.exec(n)){return[Ei.makeFakeImage(n,n,t)].filter((e=>!!e))}const r=e.filter((e=>!!e.amis[t]));return this.sortImages(r,a)}))).pipe(xa(this.destroy$)).subscribe((e=>this.setState({searchResults:e}))),l.pipe(xa(this.destroy$)).subscribe((e=>{this.setState({packageImages:e}),this.selectImage(this.findMatchingImage(e,this.props.value))})),e.pipe(Ta((e=>{const t=this.props.value;if("packageImages"===this.state.selectionMode)return l.pipe(Sa((e=>this.findMatchingImage(e,t))));{const a=!!(t&&t.amis&&t.amis[e]);return Ca(a?t:void 0)}})),xa(this.destroy$)).subscribe((e=>this.selectImage(e)))}setSortImagesBy(e){this.sortImagesBy$.next(e)}sortImages(e,t){return e.slice().sort(((e,a)=>"ts"===t?a.attributes.creationDate.localeCompare(e.attributes.creationDate):e.imageName.localeCompare(a.imageName)))}componentDidUpdate(){this.props$.next(this.props)}componentWillUnmount(){this.destroy$.next()}render(){const{value:e,credentials:t,region:a,onChange:r}=this.props,{isLoadingPackageImages:i,isSearching:s,selectionMode:l,packageImages:o,searchResults:c,searchString:d}=this.state,p=!!o,u=e=>{const n=e.amis||{},r=n[a]&&n[a][0],i=r?`(${r})`:` - not found in ${t}/${a}`;return $t.createElement($t.Fragment,null,$t.createElement("span",null,e.imageName),$t.createElement("span",null,i))},m={clearable:!1,required:!0,valueKey:"imageName",optionRenderer:u,valueRenderer:u,onSelectResetsInput:!1,onBlurResetsInput:!1,onCloseResetsInput:!1,value:e},g=this.state.errorMessage?$t.createElement(de,{message:this.state.errorMessage,type:"error"}):null,h=`No results found in ${t}/${a}`;if("searchAllImages"===l){const e=!d||d.length<3?"Please enter at least 3 characters":s?"Searching...":h;return $t.createElement("div",{className:"col-md-9"},$t.createElement(f,{...m,menuRenderer:this.buildImageMenu,isLoading:s,placeholder:"Search for an image...",filterOptions:!1,noResultsText:e,options:c,onInputChange:e=>(this.searchInput$.next(e),e),onChange:r}),g)}return p?$t.createElement("div",{className:"col-md-9"},$t.createElement(f,{...m,menuRenderer:this.buildImageMenu,isLoading:i,placeholder:"Pick an image",noResultsText:h,options:o,onChange:r}),g,$t.createElement("button",{type:"button",className:"link",onClick:()=>this.setState({selectionMode:"searchAllImages"})},"Search All Images")," ",$t.createElement(n,{id:"aws.serverGroup.allImages"})):$t.createElement("div",{className:"col-md-9"},$t.createElement(f,{...m,isLoading:i,disabled:!0,options:[e].filter((e=>!!e))}),g,$t.createElement("button",{type:"button",className:"link",onClick:()=>this.setState({selectionMode:"searchAllImages"})},"Search All Images")," ",$t.createElement(n,{id:"aws.serverGroup.allImages"}))}}const Ci=e=>e&&e.includes("${");class ki extends $t.Component{constructor(e){super(e),this.imageChanged=e=>{var t,n;const{setFieldValue:r,values:i}=this.props.formik;this.setState({selectedImage:e});const s=e&&e.attributes.virtualizationType,l=e&&e.imageName;if(i.virtualizationType=s,i.amiName=l,r("virtualizationType",s),r("amiName",l),i.imageChanged(i),e&&(null==(t=a.disabledImages)?void 0:t.length)&&(null==(n=fn.serverGroups)?void 0:n.enableIPv6)){a.disabledImages.some((t=>e.imageName.includes(t)))&&r("associateIPv6Address",!1)}},this.accountUpdated=e=>{var t,a,n,r,i,s,l,o,c,d,p;const{setFieldValue:u,values:m}=this.props.formik;m.credentials=e,m.credentialsChanged(m),m.subnetChanged(m),u("credentials",e);const g=m.backingData.credentialsKeyedByAccount[e];if(u("associateIPv6Address",(null==(a=null==(t=fn)?void 0:t.serverGroups)?void 0:a.enableIPv6)&&(null==(r=null==(n=fn)?void 0:n.serverGroups)?void 0:r.setIPv6InTest)&&"test"===g.environment),null==(i=fn.serverGroups)?void 0:i.enableIMDSv2){const t=!(null==(o=null==(l=null==(s=fn)?void 0:s.serverGroups)?void 0:l.accountDenyListIMDSv2)?void 0:o.includes(e)),a=null==(c=fn.serverGroups)?void 0:c.defaultIMDSv2AppAgeLimit,n=null==(p=null==(d=this.props.app)?void 0:d.attributes)?void 0:p.createTs;u("requireIMDSv2",t&&a&&n&&Number(n)>a)}},this.regionUpdated=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.region=e,t.regionChanged(t),a("region",e)},this.subnetUpdated=()=>{const{setFieldValue:e,values:t}=this.props.formik;t.subnetChanged(t),e("subnetType",t.subnetType)},this.clientRequestsChanged=()=>{const{values:e,setFieldValue:t}=this.props.formik;e.toggleSuspendedProcess(e,"AddToLoadBalancer"),t("suspendedProcesses",e.suspendedProcesses),this.setState({})},this.navigateToLatestServerGroup=()=>{const{values:e}=this.props.formik,{latestServerGroup:t}=this.state,a={provider:e.selectedProvider,accountId:t.account,region:t.region,serverGroup:t.name},{$state:n}=h;n.is("home.applications.application.insight.clusters")?n.go(".serverGroup",a):n.go("^.serverGroup",a)},this.stackChanged=e=>{const{setFieldValue:t,values:a}=this.props.formik;a.stack=e,t("stack",e),a.clusterChanged(a)},this.handleReasonChanged=e=>{this.props.formik.setFieldValue("reason",e)},this.strategyChanged=(e,t)=>{e.onStrategyChange(e,t),this.props.formik.setFieldValue("strategy",t.key)},this.onStrategyFieldChange=(e,t)=>{this.props.formik.setFieldValue(e,t)};const{amiName:t,region:n,viewState:{imageId:r}}=e.formik.values,i=Ei.makeFakeImage(t,r,n);this.state={...this.getStateFromProps(e),selectedImage:i}}getStateFromProps(e){const{app:t}=e,{values:a}=e.formik,n=Ee.getClusterName(t.name,a.stack,a.freeFormDetails),r=!t.clusters.find((e=>e.name===n)),i=t.serverGroups.data.filter((e=>e.cluster===n&&e.account===a.credentials&&e.region===a.region)).sort(((e,t)=>e.createdTime-t.createdTime)),s=i.length?i.pop():null;return{namePreview:n,createsNewCluster:r,latestServerGroup:s}}validate(e){const t={};var a,n;return a=e.stack,Ci(a)||/^([a-zA-Z_0-9._${}]*(\${.+})*)*$/.test(a)||(t.stack="Only dot(.) and underscore(_) special characters are allowed in the Stack field."),n=e.freeFormDetails,Ci(n)||/^([a-zA-Z_0-9._${}-]*(\${.+})*)*$/.test(n)||(t.freeFormDetails="Only dot(.), underscore(_), and dash(-) special characters are allowed in the Detail field."),e.viewState.disableImageSelection||e.amiName||(t.amiName="Image required."),e.resourceSummary&&(t.resourceSummary={id:"Cluster is managed"}),t}componentWillReceiveProps(e){this.setState(this.getStateFromProps(e))}render(){const{app:e,formik:t}=this.props,{errors:a,values:r}=t,{createsNewCluster:i,latestServerGroup:s,namePreview:l}=this.state,o=r.backingData.accounts,c=r.viewState.readOnlyFields||{};return $t.createElement("div",{className:"container-fluid form-horizontal"},r.regionIsDeprecated(r)&&$t.createElement("div",{className:"form-group row"},$t.createElement("div",{className:"col-md-12 error-message"},$t.createElement("div",{className:"alert alert-danger"},"You are deploying into a deprecated region within the ",r.credentials," account!"))),$t.createElement(at,{app:e,formik:t}),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Account"),$t.createElement("div",{className:"col-md-7"},$t.createElement(Ce,{value:r.credentials,onChange:e=>this.accountUpdated(e.target.value),readOnly:c.credentials,accounts:o,provider:"aws"}))),$t.createElement(ke,{readOnly:c.region,labelColumns:3,component:r,field:"region",account:r.credentials,regions:r.backingData.filtered.regions,onChange:this.regionUpdated}),$t.createElement(Ar,{readOnly:c.subnet,labelColumns:3,helpKey:"aws.serverGroup.subnet",component:r,field:"subnetType",region:r.region,application:e,subnets:r.backingData.filtered.subnetPurposes,onChange:this.subnetUpdated,showSubnetWarning:!0}),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Stack ",$t.createElement(n,{id:"aws.serverGroup.stack"})),$t.createElement("div",{className:"col-md-7"},$t.createElement("input",{type:"text",className:"form-control input-sm no-spel",value:r.stack,onChange:e=>this.stackChanged(e.target.value)}))),a.stack&&$t.createElement("div",{className:"form-group row slide-in"},$t.createElement("div",{className:"col-sm-9 col-sm-offset-2 error-message"},$t.createElement("span",null,a.stack))),$t.createElement(nt,{app:e,formik:t}),r.viewState.imageSourceText&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Image Source"),$t.createElement("div",{className:"col-md-7",style:{marginTop:"5px"}},$t.createElement(we,{tag:"span",message:r.viewState.imageSourceText}))),!r.viewState.disableImageSelection&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Image ",$t.createElement(n,{id:"aws.serverGroup.imageName"})),Ci(r.amiName)?$t.createElement(tn,{name:"amiName"}):$t.createElement(Ei,{onChange:e=>this.imageChanged(e),value:this.state.selectedImage,application:e,credentials:r.credentials,region:r.region})),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Traffic ",$t.createElement(n,{id:"aws.serverGroup.traffic"})),$t.createElement("div",{className:"col-md-9 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",onChange:this.clientRequestsChanged,checked:!r.processIsSuspended(r,"AddToLoadBalancer"),disabled:""!==r.strategy&&"custom"!==r.strategy}),"Send client requests to new instances"))),!r.viewState.disableStrategySelection&&r.selectedProvider&&$t.createElement(rt,{command:r,onFieldChange:this.onStrategyFieldChange,onStrategyChange:this.strategyChanged}),!r.viewState.hideClusterNamePreview&&$t.createElement(it,{createsNewCluster:i,latestServerGroupName:null==s?void 0:s.name,mode:r.viewState.mode,namePreview:l,navigateToLatestServerGroup:this.navigateToLatestServerGroup}),$t.createElement(st,{reason:r.reason,onChange:this.handleReasonChanged}))}}class Si extends $t.Component{constructor(){super(...arguments),this.preferSourceCapacityOptions=[{label:"fail the stage",value:!1},{label:"use fallback values",value:!0}],this.useSourceCapacityUpdated=e=>{const t="true"===e.target.value,{command:a}=this.props;this.props.setFieldValue("useSourceCapacity",t),t||(delete a.preferSourceCapacity,this.props.setFieldValue("preferSourceCapacity",void 0)),this.setState({})},this.simpleInstancesChanged=e=>{this.setMinMax(e)},this.preferSourceCapacityChanged=e=>{this.props.setFieldValue("preferSourceCapacity",!(!e||!e.value)||void 0),this.setState({})},this.capacityFieldChanged=(e,t)=>{const{command:a,setFieldValue:n}=this.props;a.capacity={...a.capacity},a.capacity[e]=t,n("capacity",a.capacity)}}setSimpleCapacity(e){const{command:t}=this.props,a={...t.viewState,useSimpleCapacity:e};this.props.setFieldValue("useSourceCapacity",!1),this.props.setFieldValue("viewState",a),this.setMinMax(t.capacity.desired),this.setState({})}setMinMax(e){const{command:t}=this.props;t.viewState.useSimpleCapacity&&(t.capacity={min:e,max:e,desired:e},this.props.setFieldValue("useSourceCapacity",!1),this.props.setFieldValue("capacity",t.capacity)),this.setState({})}render(){const{command:e,MinMaxDesired:t}=this.props,a=e.viewState.readOnlyFields||{};return!e.viewState.useSimpleCapacity||e.useSourceCapacity?$t.createElement("div",null,$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},$t.createElement("p",null,"Sets up auto-scaling constraints for this server group."),$t.createElement("p",null,"To set min, max, and desired instance counts to the same value use the"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.setSimpleCapacity(!0)},"Simple Mode"),"."))),!a.useSourceCapacity&&"editPipeline"===e.viewState.mode&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Capacity"),$t.createElement("div",{className:"col-md-9 radio"},$t.createElement("label",null,$t.createElement("input",{type:"radio",checked:e.useSourceCapacity,value:"true",id:"useSourceCapacityTrue",onChange:this.useSourceCapacityUpdated}),"Copy the capacity from the current server group",$t.createElement(n,{id:"serverGroupCapacity.useSourceCapacityTrue"}))),e.useSourceCapacity&&$t.createElement("div",{className:"col-md-9 col-md-offset-3 radio",style:{paddingLeft:"35px"}},$t.createElement("div",null,"If no current server group is found,",$t.createElement(an,{clearable:!1,value:!!e.preferSourceCapacity,options:this.preferSourceCapacityOptions,onChange:this.preferSourceCapacityChanged})),e.preferSourceCapacity&&$t.createElement("div",null,$t.createElement("b",null,"Fallback values"),$t.createElement(t,{command:e,fieldChanged:this.capacityFieldChanged}))),$t.createElement("div",{className:"col-md-9 col-md-offset-3 radio"},$t.createElement("label",null,$t.createElement("input",{type:"radio",checked:!e.useSourceCapacity,value:"false",id:"useSourceCapacityFalse",onChange:this.useSourceCapacityUpdated}),"Let me specify the capacity",$t.createElement(n,{id:"serverGroupCapacity.useSourceCapacityFalse"})))),(!e.useSourceCapacity||"editPipeline"!==e.viewState.mode)&&$t.createElement("div",null,$t.createElement("div",{className:"col-md-9 col-md-offset-3"},$t.createElement(t,{command:e,fieldChanged:this.capacityFieldChanged})))):$t.createElement("div",null,$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-12"},$t.createElement("p",null,"Sets the min, max, and desired instance counts to the same value."),$t.createElement("p",null," ","To set capacity for auto-scaling, use the"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.setSimpleCapacity(!1)},"Advanced Mode"),"."))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Number of Instances"),$t.createElement("div",{className:"col-md-8"},$t.createElement(he,{value:e.capacity.desired,min:0,onChange:this.simpleInstancesChanged}))))}}class Ni extends $t.Component{render(){const{command:{capacity:{min:e,max:t,desired:a}},fieldChanged:n}=this.props;return $t.createElement("div",null,$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-2"},"Min"),$t.createElement("div",{className:"col-md-8"},$t.createElement(he,{value:e,min:0,max:"number"==typeof t?t:void 0,onChange:e=>n("min",e),required:!0}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-2"},"Max"),$t.createElement("div",{className:"col-md-8"},$t.createElement(he,{value:t,min:"number"==typeof e?e:void 0,onChange:e=>n("max",e),required:!0}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-2"},"Desired"),$t.createElement("div",{className:"col-md-8"},$t.createElement(he,{value:a,min:"number"==typeof e?e:void 0,max:"number"==typeof t?t:void 0,onChange:e=>n("desired",e),required:!0}))))}}class Gi extends $t.Component{validate(e){const t={};(e.capacity.min<0||e.capacity.max<0||e.capacity.desired<0)&&(t.capacity="Capacity min, max, and desired all have to be non-negative values.");const a=e;return void 0!==a.targetHealthyDeployPercentage&&null!==a.targetHealthyDeployPercentage||(t.targetHealthyDeployPercentage="Target Healthy Deploy Percentage required."),t}render(){const{setFieldValue:e,values:t}=this.props.formik;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"row"},$t.createElement("div",{className:"col-md-12"},$t.createElement(Si,{command:t,setFieldValue:e,MinMaxDesired:Ni}))),$t.createElement("div",{className:"row"},$t.createElement("div",{className:"col-md-12"},$t.createElement("div",{className:"form-group form-inline",style:{marginTop:"20px"}},$t.createElement("div",{className:"col-md-12"},"Consider deployment successful when"," ",$t.createElement(tn,{type:"number",name:"targetHealthyDeployPercentage",min:"0",max:"100",className:"form-control input-sm inline-number",required:!0})," ","percent of instances are healthy.")))))}}function Ti(e){const[t,a]=$t.useState(!1);$t.useEffect((()=>{if(e.newInstanceType){const t=qn.awsInstanceTypeService.isBurstingSupported(e.newInstanceType);t||e.setUnlimitedCpuCredits(void 0),a(t)}if(e.newProfileType){const{instanceType:t}=e.command,n=qn.awsInstanceTypeService.isInstanceTypeInCategory(t,e.newProfileType),r=qn.awsInstanceTypeService.isBurstingSupported(t);a(t&&n&&r)}}),[e.newProfileType,e.newInstanceType]);return $t.createElement("div",null,t&&$t.createElement("div",{className:"row"},$t.createElement(lt,{toggleSize:ot.XSMALL,propLabel:"Unlimited CPU credits ",propHelpFieldId:"aws.serverGroup.unlimitedCpuCredits",tooltipPropOffBtn:"Toggle to turn OFF unlimited CPU credits",displayTextPropOffBtn:"Off",tooltipPropOnBtn:"Toggle to turn ON unlimited CPU credits",displayTextPropOnBtn:"On",onClick:t=>{e.setUnlimitedCpuCredits(t)},isPropertyActive:e.command.unlimitedCpuCredits})))}class Ii extends $t.Component{constructor(e){super(e),this.instanceProfileChanged=e=>{this.setState({newProfileType:e,newInstanceType:void 0})},this.instanceTypeChanged=e=>{const{values:t}=this.props.formik;t.instanceTypeChanged(t),this.props.formik.setFieldValue("instanceType",e),this.setState({newInstanceType:e,newProfileType:void 0})},this.setUnlimitedCpuCredits=e=>{this.props.formik.values.unlimitedCpuCredits!==e&&(this.props.formik.setFieldValue("unlimitedCpuCredits",e),this.setState({}))},this.state={newInstanceType:void 0,newProfileType:void 0}}validate(e){const t={};return e.instanceType||(t.instanceType="Instance Type required."),t}render(){var e,t;const{values:a}=this.props.formik,{InstanceArchetypeSelector:n,InstanceTypeSelector:r}=ct,i=!(!a.viewState.disableImageSelection&&!a.amiName),s=null==(e=fn.serverGroups)?void 0:e.enableLaunchTemplates,l=null==(t=fn.serverGroups)?void 0:t.enableCpuCredits;return i&&a?$t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"row"},$t.createElement(n,{command:a,onTypeChanged:this.instanceTypeChanged,onProfileChanged:this.instanceProfileChanged}),$t.createElement("div",{style:{padding:"0 15px"}},a.viewState.instanceProfile&&"custom"!==a.viewState.instanceProfile&&$t.createElement(r,{command:a,onTypeChanged:this.instanceTypeChanged}))),s&&l&&$t.createElement("div",{className:"row"},$t.createElement(Ti,{command:a,newInstanceType:this.state.newInstanceType,newProfileType:this.state.newProfileType,setUnlimitedCpuCredits:this.setUnlimitedCpuCredits}))):$t.createElement("h5",{className:"text-center"},"Please select an image.")}}class xi extends $t.Component{constructor(){super(...arguments),this.handleAvailabilityZonesChanged=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.usePreferredZonesChanged(t),a("availabilityZones",e)},this.rebalanceToggled=()=>{const{values:e,setFieldValue:t}=this.props.formik;e.toggleSuspendedProcess(e,"AZRebalance"),t("suspendedProcesses",e.suspendedProcesses),this.setState({})}}validate(e){const t={};return e.availabilityZones&&0!==e.availabilityZones.length||(t.availabilityZones="You must select at least one availability zone."),t}render(){const{values:e}=this.props.formik;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement(Ir,{credentials:e.credentials,region:e.region,onChange:this.handleAvailabilityZonesChanged,selectedZones:e.availabilityZones,allZones:e.backingData.filtered.availabilityZones,usePreferredZones:e.viewState.usePreferredZones}),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},$t.createElement("b",null,"AZ Rebalance")),$t.createElement("div",{className:"col-md-7 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",onChange:this.rebalanceToggled,checked:!e.processIsSuspended(e,"AZRebalance")}),"Keep instances evenly distributed across zones"))))}}const Ai=e=>({value:e,label:e});class Pi extends $t.Component{constructor(){super(...arguments),this.state={refreshing:!1,refreshed:!1,showVpcLoadBalancers:!1},this.refreshLoadBalancers=()=>{const{values:e}=this.props.formik;this.setState({refreshing:!0});h.providerServiceDelegate.getDelegate(e.cloudProvider||e.selectedProvider,"serverGroup.configurationService").refreshLoadBalancers(e).then((()=>{this.setState({refreshing:!1,refreshed:!0})}))},this.targetGroupsChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("targetGroups",t)},this.loadBalancersChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("loadBalancers",t)},this.vpcLoadBalancersChanged=e=>{const t=e.map((e=>e.value));this.props.formik.setFieldValue("vpcLoadBalancers",t)}}validate(e){const t={};return e.viewState.dirty.targetGroups&&(t.targetGroups="You must confirm the removed target groups."),e.viewState.dirty.loadBalancers&&(t.loadBalancers="You must confirm the removed load balancers."),t}clearWarnings(e){this.props.formik.values.viewState.dirty[e]=null,this.props.formik.validateForm()}render(){var e;const{hideLoadBalancers:t,hideTargetGroups:a}=this.props,{values:r}=this.props.formik,{dirty:i}=r.viewState,{refreshed:s,refreshing:l,showVpcLoadBalancers:o}=this.state;let c=null;if(!a){const t=(r.backingData.filtered.targetGroups||[]).concat(r.viewState.spelTargetGroups||[]).map(Ai);c=$t.createElement($t.Fragment,null,i.targetGroups&&$t.createElement("div",{className:"col-md-12"},$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following target groups could not be found in the selected account/region/VPC and were removed:"),$t.createElement("ul",null,i.targetGroups.map((e=>$t.createElement("li",{key:e},e)))),$t.createElement("p",{className:"text-right"},$t.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:()=>this.clearWarnings("targetGroups")},"Okay")))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-4 sm-label-right"},$t.createElement("b",null,"Target Groups "),$t.createElement(n,{id:"aws.loadBalancer.targetGroups"})),$t.createElement("div",{className:"col-md-7"},0===t.length&&$t.createElement("div",{className:"form-control-static"},"No ",$t.createElement("b",null,null!=(e=this.props.targetGroupTypeHelpText)?e:"instance")," target groups found in the selected account/region/VPC"),t.length>0&&$t.createElement(f,{multi:!0,options:t,value:r.targetGroups,onChange:this.targetGroupsChanged}))))}let d=null;if(!t){const e=(r.backingData.filtered.loadBalancers||[]).concat(r.viewState.spelLoadBalancers||[]).map(Ai),t=(r.backingData.filtered.vpcLoadBalancers||[]).map(Ai),a=r.vpcLoadBalancers&&r.vpcLoadBalancers.length>0;d=$t.createElement($t.Fragment,null,i.loadBalancers&&$t.createElement("div",{className:"col-md-12"},$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following load balancers could not be found in the selected account/region/VPC and were removed:"),$t.createElement("ul",null,i.loadBalancers.map((e=>$t.createElement("li",{key:e},e)))),$t.createElement("p",{className:"text-right"},$t.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:()=>this.clearWarnings("loadBalancers")},"Okay")))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-4 sm-label-right"},$t.createElement("b",null,"Classic Load Balancers "),$t.createElement(n,{id:"aws.loadBalancer.loadBalancers"})),$t.createElement("div",{className:"col-md-7"},0===e.length&&$t.createElement("div",{className:"form-control-static"},"No load balancers found in the selected account/region/VPC"),e.length>0&&$t.createElement(f,{multi:!0,options:e,value:r.loadBalancers,onChange:this.loadBalancersChanged}))),!r.vpcId&&$t.createElement("div",{className:"form-group"},!a&&!o&&$t.createElement("div",null,$t.createElement("div",{className:"col-md-8 col-md-offset-3"},$t.createElement("a",{className:"clickable",onClick:()=>this.setState({showVpcLoadBalancers:!0})},"Add VPC Load Balancers"))),a&&$t.createElement("div",null,$t.createElement("div",{className:"col-md-4 sm-label-right"},$t.createElement("b",null,"VPC Load Balancers")),$t.createElement("div",{className:"col-md-8"},t.length>0&&$t.createElement(f,{multi:!0,options:t,value:r.vpcLoadBalancers,onChange:this.vpcLoadBalancersChanged})))),!s&&$t.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},$t.createElement("div",{className:"col-md-8 col-md-offset-4"},l&&$t.createElement("p",null,$t.createElement("span",{className:"fa fa-sync-alt fa-spin"}),$t.createElement("span",null," refreshing...")),!l&&$t.createElement("p",null,"If you are looking for a load balancer or target group from a different application, ",$t.createElement("br",null),$t.createElement("a",{className:"clickable",onClick:this.refreshLoadBalancers},"click here")," ","to load all load balancers."))))}return $t.createElement("div",{className:"container-fluid form-horizontal"},c,d)}}class zi extends $t.Component{constructor(e){super(e),this.refreshSecurityGroups=()=>{this.setState({refreshing:!0}),this.props.refresh?this.props.refresh().then((()=>this.setState({refreshing:!1}))):h.providerServiceDelegate.getDelegate(this.props.command.selectedProvider,"serverGroup.configurationService").refreshSecurityGroups(this.props.command).then((()=>{this.setState({refreshing:!1,refreshTime:Se.get("securityGroups").getStats().ageMax})}))},this.onChange=e=>{const t=e.map((e=>e.value));this.props.onChange(t)},this.state={refreshing:!1,refreshTime:Se.get("securityGroups").getStats().ageMax}}render(){const{availableGroups:e,groupsToEdit:t,helpKey:a,hideLabel:r}=this.props,{refreshing:i,refreshTime:s}=this.state,l=e.map((e=>({label:`${e.name} (${e.id})`,value:e.id})));return $t.createElement($t.Fragment,null,$t.createElement("div",{className:"form-group"},!r&&$t.createElement("div",{className:"col-md-3 sm-label-right"},$t.createElement("b",null,U.get("Firewalls")),a&&$t.createElement(n,{key:a})),$t.createElement("div",{className:"col-md-8"},$t.createElement(nn,{ignoreAccents:!0,options:l,onChange:this.onChange,value:t,multi:!0}))),$t.createElement("div",{className:"form-group small",style:{marginTop:"20px"}},$t.createElement("div",{className:`col-md-${r?12:9} col-md-offset-${r?0:3}`},$t.createElement("p",null,i&&$t.createElement("span",null,$t.createElement("span",{className:"fa fa-sync-alt fa-spin"})),U.get("Firewalls"),!i&&$t.createElement("span",null," last refreshed ",D(s)),i&&$t.createElement("span",null," refreshing...")),$t.createElement("p",null,"If you're not finding a ",U.get("firewall")," that was recently added,"," ",$t.createElement("a",{className:"clickable",onClick:this.refreshSecurityGroups},"click here")," ","to refresh the list."))))}}class Bi extends $t.Component{render(){const{command:e,onClear:t,removed:a}=this.props,n=(e&&e.viewState.dirty.securityGroups||[]).concat(a||[]);return 0===n.length?null:$t.createElement("div",{className:"col-md-12"},$t.createElement("div",{className:"alert alert-warning"},$t.createElement("p",null,$t.createElement("i",{className:"fa fa-exclamation-triangle"}),"The following ",U.get("firewalls")," could not be found in the selected account/region/VPC and were removed:"),$t.createElement("ul",null,n.map((e=>$t.createElement("li",{key:e},e)))),$t.createElement("p",{className:"text-right"},$t.createElement("a",{className:"btn btn-sm btn-default dirty-flag-dismiss clickable",onClick:t},"Okay"))))}}Bi.defaultProps={onClear:C};class Di extends $t.Component{constructor(){super(...arguments),this.onChange=e=>{this.props.formik.setFieldValue("securityGroups",e)},this.acknowledgeRemovedGroups=()=>{const{viewState:e}=this.props.formik.values;e.dirty.securityGroups=null,this.props.formik.setFieldValue("viewState",e)}}validate(e){const t={};return e.viewState.dirty.securityGroups&&(t.securityGroups="You must acknowledge removed security groups."),t}render(){const{values:e}=this.props.formik;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement(Bi,{command:e,onClear:this.acknowledgeRemovedGroups}),$t.createElement(zi,{command:e,availableGroups:e.backingData.filtered.securityGroups,groupsToEdit:e.securityGroups,onChange:this.onChange}))}}class $i extends $t.Component{constructor(){super(...arguments),this.duplicateKeys=!1,this.validate=e=>{const t={};return e.keyPair||(t.keyPair="Key Name is required"),this.duplicateKeys&&(t.tags="Tags have duplicate keys."),t},this.selectBlockDeviceMappingsSource=e=>{const{values:t}=this.props.formik;t.selectBlockDeviceMappingsSource(t,e),this.setState({})},this.toggleSuspendedProcess=e=>{const{values:t,setFieldValue:a}=this.props.formik;t.toggleSuspendedProcess(t,e),a("suspendedProcesses",t.suspendedProcesses),this.setState({})},this.platformHealthOverrideChanged=e=>{this.props.formik.setFieldValue("interestingHealthProviderNames",e)},this.tagsChanged=(e,t)=>{this.duplicateKeys=t,this.props.formik.setFieldValue("tags",e)}}render(){const{app:e}=this.props,{setFieldValue:t,values:a}=this.props.formik,r=a.getBlockDeviceMappingsSource(a),i=a.backingData.filtered.keyPairs||[],s=fn.serverGroups;return $t.createElement("div",{className:"container-fluid form-horizontal"},$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Cooldown")),$t.createElement("div",{className:"col-md-2"},$t.createElement(tn,{type:"text",required:!0,name:"cooldown",className:"form-control input-sm no-spel"}))," ","seconds"),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Enabled Metrics "),$t.createElement(n,{id:"aws.serverGroup.enabledMetrics"})),$t.createElement("div",{className:"col-md-6"},$t.createElement(an,{multi:!0,value:a.enabledMetrics,options:a.backingData.enabledMetrics.map((e=>({label:e,value:e}))),onChange:e=>t("enabledMetrics",e.map((e=>e.value)))}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Health Check Type")),$t.createElement("div",{className:"col-md-6"},$t.createElement(an,{value:a.healthCheckType,clearable:!1,placeholder:"Select...",options:a.backingData.healthCheckTypes.map((e=>({label:e,value:e}))),onChange:e=>t("healthCheckType",e.value)}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Health Check Grace Period")),$t.createElement("div",{className:"col-md-2"},$t.createElement(tn,{type:"text",required:!0,className:"form-control input-sm no-spel",name:"healthCheckGracePeriod"}))," ","seconds"),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Termination Policies")),$t.createElement("div",{className:"col-md-6"},$t.createElement(an,{multi:!0,value:a.terminationPolicies,options:a.backingData.terminationPolicies.map((e=>({label:e,value:e}))),onChange:e=>t("terminationPolicies",e.map((e=>e.value)))}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Key Name")),$t.createElement("div",{className:"col-md-6"},$t.createElement(an,{value:a.keyPair,required:!0,clearable:!1,options:i.map((e=>({label:e,value:e}))),onChange:e=>t("keyPair",e.value)}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Ramdisk Id (optional)")),$t.createElement("div",{className:"col-md-6"},$t.createElement(tn,{type:"text",name:"ramdiskId",className:"form-control input-sm no-spel"}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"IAM Instance Profile (optional)")),$t.createElement("div",{className:"col-md-6"},$t.createElement(tn,{type:"text",className:"form-control input-sm no-spel",name:"iamRole"}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"UserData (optional) "),$t.createElement(n,{id:"aws.serverGroup.base64UserData"})),$t.createElement("div",{className:"col-md-6"},$t.createElement(tn,{type:"text",className:"form-control input-sm no-spel",name:"base64UserData"}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Instance Monitoring "),$t.createElement(n,{id:"aws.serverGroup.instanceMonitoring"})),$t.createElement("div",{className:"col-md-6 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",checked:a.instanceMonitoring,onChange:e=>t("instanceMonitoring",e.target.checked)})," ","Enforce Instance Monitoring"," "))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"EBS Optimized")),$t.createElement("div",{className:"col-md-6 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",checked:a.ebsOptimized,onChange:e=>t("ebsOptimized",e.target.checked)})," ","Optimize Instances for EBS"))),(null==s?void 0:s.enableIMDSv2)&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"IMDSv2 "),$t.createElement(n,{id:"aws.serverGroup.imdsv2"})),$t.createElement("div",{className:"col-md-6 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",checked:!0===a.requireIMDSv2,onChange:e=>t("requireIMDSv2",e.target.checked)})," ","Require IMDSv2"," "))),!fn.disableSpotPricing&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Spot Instances Price (optional)")," ",$t.createElement(n,{id:"aws.serverGroup.spotMaxPrice"})),$t.createElement("div",{className:"col-md-2"},$t.createElement(tn,{type:"text",className:"form-control input-sm",name:"spotPrice"}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"AMI Block Device Mappings")),$t.createElement("div",{className:"col-md-6 radio"},$t.createElement("div",null,$t.createElement("label",null,$t.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("source"),checked:"source"===r,name:"blockDeviceMappingsSource"}),"Copy from current server group ",$t.createElement(n,{id:"aws.blockDeviceMappings.useSource"}))),$t.createElement("div",null,$t.createElement("label",null,$t.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("ami"),checked:"ami"===r,name:"blockDeviceMappingsSource"}),"Prefer AMI block device mappings ",$t.createElement(n,{id:"aws.blockDeviceMappings.useAMI"}))),$t.createElement("div",null,$t.createElement("label",null,$t.createElement("input",{type:"radio",onChange:()=>this.selectBlockDeviceMappingsSource("default"),checked:"default"===r,name:"blockDeviceMappingsSource"}),"Defaults for selected instance type ",$t.createElement(n,{id:"aws.blockDeviceMappings.useDefaults"}))))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,`Associate ${(null==s?void 0:s.enableIPv6)?"IPv6 (Recommended)":"Public IPv4"} Address`),$t.createElement(n,{id:"serverGroup.ipv6"})),(null==s?void 0:s.enableIPv6)&&$t.createElement("div",{className:"col-md-6 checkbox"},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",checked:!0===a.associateIPv6Address,onChange:e=>t("associateIPv6Address",e.target.checked),id:"associateIPv6AddressToggle"})," ","Assign an IPv6 address to instances"," ")),!(null==s?void 0:s.enableIPv6)&&$t.createElement("div",null,$t.createElement("div",{className:"col-md-2 radio"},$t.createElement("label",null,$t.createElement("input",{type:"radio",checked:!0===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",!0),id:"associatePublicIpAddressTrue"}),"Yes")),$t.createElement("div",{className:"col-md-2 radio"},$t.createElement("label",null,$t.createElement("input",{type:"radio",checked:!1===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",!1),id:"associatePublicIpAddressFalse"}),"No")),$t.createElement("div",{className:"col-md-2 radio"},$t.createElement("label",null,$t.createElement("input",{type:"radio",checked:null===a.associatePublicIpAddress,onChange:()=>t("associatePublicIpAddress",null),id:"associatePublicIpAddressDefault"}),"Default")))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Scaling Processes")),$t.createElement("div",{className:"col-md-6 checkbox"},a.backingData.scalingProcesses.map((e=>$t.createElement("div",{key:e.name},$t.createElement("label",null,$t.createElement("input",{type:"checkbox",onChange:()=>this.toggleSuspendedProcess(e.name),checked:!a.suspendedProcesses.includes(e.name)})," ",e.name," ",$t.createElement(n,{content:e.description}))))))),e.attributes.platformHealthOnlyShowOverride&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-5 sm-label-right"},$t.createElement("b",null,"Task Completion")),$t.createElement("div",{className:"col-md-6"},$t.createElement(dt,{interestingHealthProviderNames:a.interestingHealthProviderNames,platformHealthType:"Amazon",onChange:this.platformHealthOverrideChanged}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"sm-label-left"},$t.createElement("b",null,"Tags (optional)"),$t.createElement(n,{id:"aws.serverGroup.tags"})),$t.createElement(pt,{model:a.tags,allowEmpty:!0,onChange:this.tagsChanged})))}}var Fi=Object.defineProperty,Mi=Object.getOwnPropertyDescriptor;let Ri=class extends $t.Component{constructor(){super(...arguments),this.validators=new Map,this.validate=e=>{const t={};return this.validators.forEach((a=>{const n=a(e);Object.assign(t,{...n})})),t},this.handleRef=e=>{e?this.validators.set("common",e.validate):this.validators.delete("common")}}render(){const{formik:e,app:t}=this.props;return $t.createElement($i,{formik:e,app:t,ref:this.handleRef})}};Ri=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?Mi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Fi(t,a,i),i})([ce("aws.serverGroup.advancedSettings")],Ri);class Li extends $t.Component{constructor(){super(...arguments),this.ref=$t.createRef()}validate(e){return this.ref&&this.ref.current?this.ref.current.validate(e):{}}render(){const{app:e,formik:t}=this.props;return $t.createElement(Ri,{formik:t,app:e,ref:this.ref})}}const Oi=class extends $t.Component{constructor(e){super(e),this._isUnmounted=!1,this.templateSelected=()=>{this.setState({requiresTemplateSelection:!1}),this.configureCommand()},this.onTaskComplete=()=>{this.props.application.serverGroups.refresh(),this.props.application.serverGroups.onNextRefresh(null,this.onApplicationRefresh)},this.onApplicationRefresh=()=>{if(this._isUnmounted)return;const{command:e}=this.props,{taskMonitor:t}=this.state,a=t.task.execution.stages.find((e=>"cloneServerGroup"===e.type));if(a&&a.context["deploy.server.groups"]){const t=a.context["deploy.server.groups"][e.region];if(t){const a={serverGroup:t,accountId:e.credentials,region:e.region,provider:"aws"};let n="^.^.^.clusters.serverGroup";h.$state.includes("**.clusters.serverGroup")&&(n="^.serverGroup"),h.$state.includes("**.clusters.cluster.serverGroup")&&(n="^.^.serverGroup"),h.$state.includes("**.clusters")&&(n=".serverGroup"),h.$state.go(n,a)}}},this.initializeCommand=()=>{const{command:e}=this.props;e.credentialsChanged(e),e.regionChanged(e),qn.awsServerGroupConfigurationService.configureSubnetPurposes(e)},this.configureCommand=()=>{const{application:e,command:t}=this.props;qn.awsServerGroupConfigurationService.configureCommand(e,t).then((()=>{this.initializeCommand(),this.setState({loaded:!0,requiresTemplateSelection:!1})}))},this.normalizeCommand=({tags:e})=>{e&&Object.keys(e).forEach((t=>{t.length||e[t].length||delete e[t]}))},this.submit=e=>{this.normalizeCommand(e);"editPipeline"===e.viewState.mode||"createPipeline"===e.viewState.mode?this.props.closeModal&&this.props.closeModal(e):this.state.taskMonitor.submit((()=>h.serverGroupWriter.cloneServerGroup(e,this.props.application)))};const t=Kt(e,"command.viewState.requiresTemplateSelection",!1);t||this.configureCommand(),this.state={firewallsLabel:U.get("Firewalls"),loaded:!1,requiresTemplateSelection:t,taskMonitor:new v({application:e.application,title:"Creating your server group",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:this.onTaskComplete})}}static show(e){return b.show(Oi,e,{dialogClassName:"wizard-modal modal-lg"})}componentWillUnmount(){this._isUnmounted=!0,this.refreshUnsubscribe&&this.refreshUnsubscribe()}render(){const{application:e,command:t,dismissModal:a,title:n}=this.props,{loaded:r,taskMonitor:i,requiresTemplateSelection:s}=this.state;return s?$t.createElement(wi,{app:e,command:t,onDismiss:a,onTemplateSelected:this.templateSelected}):$t.createElement(w,{heading:n,initialValues:t,loading:!r,taskMonitor:i,dismissModal:a,closeModal:this.submit,submitButtonLabel:t.viewState.submitButtonLabel,render:({formik:t,nextIdx:a,wizard:n})=>$t.createElement($t.Fragment,null,$t.createElement(E,{label:"Basic Settings",wizard:n,order:a(),render:({innerRef:a})=>$t.createElement(ki,{ref:a,formik:t,app:e})}),$t.createElement(E,{label:"Load Balancers",wizard:n,order:a(),render:({innerRef:e})=>$t.createElement(Pi,{ref:e,formik:t})}),$t.createElement(E,{label:U.get("Firewalls"),wizard:n,order:a(),render:({innerRef:e})=>$t.createElement(Di,{ref:e,formik:t})}),$t.createElement(E,{label:"Instance Type",wizard:n,order:a(),render:({innerRef:e})=>$t.createElement(Ii,{ref:e,formik:t})}),$t.createElement(E,{label:"Capacity",wizard:n,order:a(),render:({innerRef:e})=>$t.createElement(Gi,{ref:e,formik:t})}),$t.createElement(E,{label:"Availability Zones",wizard:n,order:a(),render:({innerRef:e})=>$t.createElement(xi,{ref:e,formik:t})}),$t.createElement(E,{label:"Advanced Settings",wizard:n,order:a(),render:({innerRef:a})=>$t.createElement(Li,{ref:a,formik:t,app:e})}))})}};let Ui=Oi;Ui.defaultProps={closeModal:C,dismissModal:C};class Vi extends $t.Component{constructor(){super(...arguments),this.state={verified:!1,requireVerification:!1},this.handleVerification=e=>{this.setState({verified:e})}}componentDidMount(){o.accounts$.pipe(Da(1),Sa((e=>e.find((e=>e.name===this.props.account))))).subscribe((e=>{this.setState({requireVerification:!!e&&e.challengeDestructiveActions})}))}render(){const{account:e,onCancel:t,onSubmit:a,isValid:n}=this.props,{verified:r,requireVerification:i}=this.state;return $t.createElement(Oa,null,$t.createElement("form",{onSubmit:()=>(this.props.onSubmit(),!1)},i&&$t.createElement(ut,{expectedValue:e,onValidChange:this.handleVerification})),$t.createElement("button",{className:"btn btn-default",onClick:t},"Cancel"),$t.createElement("button",{type:"submit",className:"btn btn-primary",onClick:a,disabled:!n||i&&!r},"Submit"))}}Vi.defaultProps={isValid:!0};const qi=class extends $t.Component{constructor(e){super(e),this.formikRef=$t.createRef(),this.validate=e=>{const{min:t,max:a,desired:n}=e,r={};return this.state.advancedMode?(t>a&&t>n?r.min="Min cannot be larger than Max/Desired":a<t&&a<n?r.max="Max cannot be smaller than Min/Desired":(t>a&&(r.min="Min cannot be larger than Max"),this.isDesiredControlledByAutoscaling()||(n<t&&(r.desired="Desired cannot be smaller than Min"),n>a&&(r.desired="Desired cannot be larger than Max"))),r):r},this.toggleAdvancedMode=()=>{const{desired:e}=this.formikRef.current.getFormikContext().values;this.formikRef.current.setFieldValue("min",e),this.formikRef.current.setFieldValue("max",e),this.setState({advancedMode:!this.state.advancedMode})},this.close=e=>{this.props.dismissModal.apply(null,e)},this.platformHealthOverrideChanged=e=>{this.setState({interestingHealthProviderNames:e})},this.isDesiredControlledByAutoscaling=()=>{const{serverGroup:e}=this.props,{suspendedProcesses:t}=e.asg,{advancedMode:a}=this.state;return(e.scalingPolicies||[]).length&&a&&t.every((e=>"AlarmNotification"!==e.processName))},this.submit=e=>{const{min:t,max:a,desired:n,enforceCapacityConstraints:r,reason:i}=e,{interestingHealthProviderNames:s}=this.state,{serverGroup:l,application:o}=this.props,{asg:c}=l,d={capacity:Zt({min:t!==c.minSize?t:void 0,max:a!==c.maxSize?a:void 0,desired:n!==c.desiredCapacity?n:void 0},(e=>void 0!==e)),reason:i,interestingHealthProviderNames:s};r&&(d.constraints={capacity:{min:c.minSize,max:c.maxSize,desired:c.desiredCapacity}}),this.state.taskMonitor.submit((()=>h.serverGroupWriter.resizeServerGroup(l,o,d)))};const{minSize:t,maxSize:a,desiredCapacity:n}=e.serverGroup.asg,{attributes:r}=e.application;this.state={advancedMode:t!==a,initialValues:{min:t,max:a,desired:n,enforceCapacityConstraints:!1},taskMonitor:new v({application:e.application,title:"Resizing your server group",modalInstance:v.modalInstanceEmulation((()=>this.props.dismissModal())),onTaskComplete:()=>this.props.application.serverGroups.refresh()}),platformHealthOnlyShowOverride:r.platformHealthOnlyShowOverride,interestingHealthProviderNames:r.platformHealthOnlyShowOverride&&r.platformHealthOnly?["Amazon"]:null}}static show(e){const t={},{serverGroup:a,application:n}=e;return et(a,n).then((a=>{a&&b.show(qi,e,t)}))}autoIncrementDesiredIfNeeded(){if(!this.isDesiredControlledByAutoscaling())return;const e=this.formikRef.current.getFormikContext(),{asg:t}=this.props.serverGroup,{min:a,max:n,desired:r}=e.values,i=Math.min(n,Math.max(a,t.desiredCapacity));r!==i&&e.setFieldValue("desired",i)}renderSimpleMode(e){const{serverGroup:t}=this.props,{asg:a}=t;return $t.createElement("div",null,$t.createElement("p",null,"Sets min, max, and desired instance counts to the same value."),$t.createElement("p",null,"To allow autoscaling, use the"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Advanced Mode"),"."),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Current size"),$t.createElement("div",{className:"col-md-4"},$t.createElement("div",{className:"horizontal middle"},$t.createElement("input",{type:"number",className:"NumberInput form-control",value:a.desiredCapacity,disabled:!0}),$t.createElement("div",{className:"sp-padding-xs-xaxis"},"instances")))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Resize to"),$t.createElement("div",{className:"col-md-4"},$t.createElement("div",{className:"horizontal middle"},$t.createElement(s,{name:"desired",input:e=>$t.createElement(u,{...e,min:0}),touched:!0,onChange:t=>{e.setFieldValue("min",t),e.setFieldValue("max",t)}}),$t.createElement("div",{className:"sp-padding-xs-xaxis"},"instances")))))}renderAdvancedMode(e){const{serverGroup:t}=this.props,{errors:a}=e,{asg:n}=t,r=a.min||a.max||a.desired;return $t.createElement("div",null,$t.createElement("p",null,"Sets up autoscaling for this server group."),$t.createElement("p",null,"To disable autoscaling, use the"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Simple Mode"),"."),$t.createElement("div",{className:"form-group bold"},$t.createElement("div",{className:"col-md-2 col-md-offset-3"},"Min"),$t.createElement("div",{className:"col-md-2"},"Max"),$t.createElement("div",{className:"col-md-2"},"Desired")),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Current"),$t.createElement("div",{className:"col-md-2"},$t.createElement("input",{type:"number",className:"NumberInput form-control",value:n.minSize,disabled:!0})),$t.createElement("div",{className:"col-md-2"},$t.createElement("input",{type:"number",className:"NumberInput form-control",value:n.maxSize,disabled:!0})),$t.createElement("div",{className:"col-md-2"},$t.createElement("input",{type:"number",className:"NumberInput form-control",value:n.desiredCapacity,disabled:!0}))),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Resize to"),$t.createElement("div",{className:"col-md-2"},$t.createElement(s,{name:"min",input:e=>$t.createElement(u,{...e,min:0}),onChange:()=>this.autoIncrementDesiredIfNeeded(),layout:({input:e})=>$t.createElement($t.Fragment,null,e),touched:!0})),$t.createElement("div",{className:"col-md-2"},$t.createElement(s,{name:"max",input:e=>$t.createElement(u,{...e,min:0}),onChange:()=>this.autoIncrementDesiredIfNeeded(),layout:({input:e})=>$t.createElement($t.Fragment,null,e),touched:!0})),$t.createElement("div",{className:"col-md-2"},$t.createElement(s,{name:"desired",input:e=>$t.createElement(u,{...e,min:0,disabled:this.isDesiredControlledByAutoscaling()}),layout:({input:e})=>$t.createElement($t.Fragment,null,e),touched:!0}))),!!r&&$t.createElement("div",{className:"col-md-offset-3 col-md-9"},$t.createElement(de,{message:r,type:"error"})))}renderCapacityConstraintSelector(){return $t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-7 col-md-offset-3"},$t.createElement(s,{name:"enforceCapacityConstraints",input:e=>$t.createElement($t.Fragment,null,$t.createElement(d,{...e,text:"Enforce Capacity Constraints"}),$t.createElement(n,{id:"aws.serverGroup.capacityConstraint"}))})))}renderScalingPolicyWarning(e){const{serverGroup:t}=this.props,{min:a,max:n}=e.values,{advancedMode:r}=this.state,i=t.scalingPolicies||[];return i.length&&a===n?$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-7 col-md-offset-3"},$t.createElement("div",{className:"well-compact alert alert-warning"},$t.createElement("b",null,"Warning"),": this server group has",1===i.length&&$t.createElement("span",null," a scaling policy. "),i.length>1&&$t.createElement("span",null," scaling policies. "),!r&&$t.createElement("span",null,"Scaling policies will not take effect in Simple Mode. Switch to"," ",$t.createElement("a",{className:"clickable",onClick:()=>this.toggleAdvancedMode()},"Advanced Mode"),"."),r&&$t.createElement("span",null,"Scaling policies will not take effect when ",$t.createElement("b",null,"Min")," is the same as ",$t.createElement("b",null,"Max"),".")))):this.isDesiredControlledByAutoscaling()?$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-8 col-md-offset-1"},$t.createElement("div",{className:"well-compact alert alert-warning"},$t.createElement("p",null,$t.createElement("b",null,"Desired")," capacity is managed by Autoscaling Policies."),$t.createElement("p",null,"If you need to scale ",$t.createElement("b",null,"down")," this server group, set ",$t.createElement("b",null,"Max")," to the new desired size."),$t.createElement("p",null,"If you need to scale ",$t.createElement("b",null,"up")," this server group, set ",$t.createElement("b",null,"Min")," to the new desired size.")))):null}render(){const{serverGroup:e}=this.props,{advancedMode:t,initialValues:a,platformHealthOnlyShowOverride:n}=this.state;return $t.createElement($t.Fragment,null,$t.createElement(mt,{monitor:this.state.taskMonitor}),$t.createElement(ne,{ref:this.formikRef,initialValues:a,validate:this.validate,onSubmit:this.submit,render:a=>{const{asg:r}=e,i={min:r.minSize,max:r.maxSize,desired:r.desiredCapacity},s=a.values;return $t.createElement($t.Fragment,null,$t.createElement(re,{dismiss:this.close}),$t.createElement(Fa.Header,null,$t.createElement(Fa.Title,null,"Resize ",e.name)),$t.createElement(Fa.Body,null,$t.createElement(en,{className:"form-horizontal"},t&&this.renderAdvancedMode(a),!t&&this.renderSimpleMode(a),this.renderScalingPolicyWarning(a),this.renderCapacityConstraintSelector(),n&&$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-8 col-md-offset-3"},$t.createElement(dt,{interestingHealthProviderNames:this.state.interestingHealthProviderNames,platformHealthType:"Amazon",onChange:this.platformHealthOverrideChanged,showHelpDetails:!0}))),$t.createElement(st,{reason:a.values.reason,onChange:e=>a.setFieldValue("reason",e)}),$t.createElement("div",{className:"form-group"},$t.createElement("div",{className:"col-md-3 sm-label-right"},"Changes"),$t.createElement("div",{className:"col-md-9 sm-control-field"},$t.createElement(gt,{current:i,next:s}))))),$t.createElement(Vi,{onSubmit:()=>this.submit(a.values),onCancel:this.close,isValid:a.isValid,account:e.account}))}}))}};let ji=qi;ji.defaultProps={closeModal:C,dismissModal:C};var Hi=Object.defineProperty,Wi=Object.getOwnPropertyDescriptor;let Zi=class extends $t.Component{constructor(){super(...arguments),this.resizeServerGroup=()=>{ji.show(this.props)}}render(){return $t.createElement(Ua,{onClick:this.resizeServerGroup},"Resize")}};Zi=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?Wi(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Hi(t,a,i),i})([ce("AmazonServerGroupActions.resize")],Zi);class _i extends $t.Component{constructor(){super(...arguments),this.destroyServerGroup=()=>{const{app:e,serverGroup:t}=this.props,a={application:e,title:"Destroying "+t.name,onTaskComplete:()=>{h.$state.includes("**.serverGroup",n)&&h.$state.go("^")}},n={name:t.name,accountId:t.account,region:t.region},r={header:"Really destroy "+t.name+"?",buttonText:"Destroy "+t.name,account:t.account,taskMonitorConfig:a,interestingHealthProviderNames:void 0,submitMethod:a=>h.serverGroupWriter.destroyServerGroup(t,e,a),askForReason:!0,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon"};ht.addDestroyWarningMessage(e,t,r),e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(r.interestingHealthProviderNames=["Amazon"]),k.confirm(r)},this.disableServerGroup=()=>{const{app:e,serverGroup:t}=this.props,a={application:e,title:"Disabling "+t.name},n={header:"Really disable "+t.name+"?",buttonText:"Disable "+t.name,account:t.account,interestingHealthProviderNames:void 0,taskMonitorConfig:a,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",submitMethod:a=>h.serverGroupWriter.disableServerGroup(t,e.name,a),askForReason:!0};ht.addDisableWarningMessage(e,t,n),e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=["Amazon"]),k.confirm(n)},this.enableServerGroup=()=>{if(!this.isRollbackEnabled())return void this.showEnableServerGroupModal();const e={header:"Rolling back?",body:"Spinnaker provides an orchestrated rollback feature to carefully restore a different version of this\n server group. Do you want to use the orchestrated rollback?",buttonText:"Yes, take me to the rollback settings modal",cancelButtonText:"No, I just want to enable the server group"};k.confirm(e).then((()=>new Promise((e=>setTimeout(e,500))))).then((()=>this.rollbackServerGroup())).catch((e=>{"footer"===(null==e?void 0:e.source)&&this.showEnableServerGroupModal()}))},this.rollbackServerGroup=()=>{const{app:e}=this.props;let t,a=this.props.serverGroup,n=e.getDataSource("serverGroups").data.filter((e=>e.cluster===a.cluster&&e.region===a.region&&e.account===a.account));a.isDisabled&&(t=a,a=jt(n.filter((e=>e.name!==t.name&&!e.isDisabled)),["instanceCounts.total","createdTime"],["desc","desc"])[0]),n=n.filter((e=>e.name!==a.name)),1!==n.length||t||(t=n[0]),ft.modalService.open({templateUrl:h.overrideRegistry.getTemplate("aws.rollback.modal","amazon/src/serverGroup/details/rollback/rollbackServerGroup.html"),controller:"awsRollbackServerGroupCtrl as ctrl",resolve:{serverGroup:()=>a,previousServerGroup:()=>t,disabledServerGroups:()=>{const t=da(e.clusters,{name:a.cluster,account:a.account,serverGroups:[]});return ea(t.serverGroups,{isDisabled:!0,region:a.region})},allServerGroups:()=>n,application:()=>e}})},this.cloneServerGroup=()=>{const{app:e,serverGroup:t}=this.props;qn.awsServerGroupCommandBuilder.buildServerGroupCommandFromExisting(e,t).then((a=>{const n=`Clone ${t.name}`;Ui.show({title:n,application:e,command:a})}))}}isEnableLocked(){if(this.props.serverGroup.isDisabled){if((this.props.serverGroup.runningTasks||[]).filter((e=>Kt(e,"execution.stages",[]).some((e=>"resizeServerGroup"===e.type)))).length)return!0}return!1}isRollbackEnabled(){const{app:e,serverGroup:t}=this.props;return!t.isDisabled||e.getDataSource("serverGroups").data.some((e=>e.cluster===t.cluster&&e.region===t.region&&e.account===t.account&&!e.isDisabled))}hasDisabledInstances(){return this.props.serverGroup.isDisabled||Kt(this.props.serverGroup,"instanceCounts.outOfService",0)>0}showEnableServerGroupModal(){const{app:e,serverGroup:t}=this.props,a={application:e,title:"Enabling "+t.name},n={header:"Really enable "+t.name+"?",buttonText:"Enable "+t.name,account:t.account,interestingHealthProviderNames:void 0,taskMonitorConfig:a,platformHealthOnlyShowOverride:e.attributes.platformHealthOnlyShowOverride,platformHealthType:"Amazon",submitMethod:a=>h.serverGroupWriter.enableServerGroup(t,e,a),askForReason:!0};e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(n.interestingHealthProviderNames=["Amazon"]),k.confirm(n)}render(){const{app:e,serverGroup:t}=this.props,n=a.feature&&a.feature.entityTags,r=vt.buildClusterTargets(t);return $t.createElement($a,{className:"dropdown",id:"server-group-actions-dropdown"},$t.createElement($a.Toggle,{className:"btn btn-sm btn-primary dropdown-toggle"},"Server Group Actions"),$t.createElement($a.Menu,{className:"dropdown-menu"},this.isRollbackEnabled()&&$t.createElement(Ge,{resource:t,application:e,onClick:this.rollbackServerGroup},"Rollback"),this.isRollbackEnabled()&&$t.createElement("li",{role:"presentation",className:"divider"}),$t.createElement(Zi,{application:e,serverGroup:t}),!t.isDisabled&&$t.createElement(Ge,{resource:t,application:e,onClick:this.disableServerGroup},"Disable"),this.hasDisabledInstances()&&!this.isEnableLocked()&&$t.createElement(Ge,{resource:t,application:e,onClick:this.enableServerGroup},"Enable"),this.isEnableLocked()&&$t.createElement("li",{className:"disabled"},$t.createElement(Ra,{value:"Cannot enable this server group until resize operation completes",placement:"left"},$t.createElement("a",null,$t.createElement("span",{className:"small glyphicon glyphicon-lock"})," Enable"))),$t.createElement(Ge,{resource:t,application:e,onClick:this.destroyServerGroup},"Destroy"),$t.createElement("li",null,$t.createElement("a",{className:"clickable",onClick:this.cloneServerGroup},"Clone")),n&&$t.createElement(N,{component:t,application:e,entityType:"serverGroup",ownerOptions:r,onUpdate:()=>e.serverGroups.refresh()})))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/rollback/rollbackServerGroup.html",'<div modal-page class="confirmation-modal">\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Rollback {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body confirmation-modal">\n <div class="row">\n <div class="col-sm-3 sm-label-right">Restore to</div>\n <div class="col-md-7">\n <ui-select\n ng-model="command.rollbackContext.restoreServerGroupName"\n class="form-control input-sm"\n ng-if="command.rollbackType === \'EXPLICIT\'"\n >\n <ui-select-match placeholder="Select...">{{ctrl.label($select.selected)}}</ui-select-match>\n <ui-select-choices group-by="ctrl.group" repeat="serverGroup.name as serverGroup in allServerGroups">\n <span ng-bind-html="ctrl.label(serverGroup)"></span>\n </ui-select-choices>\n </ui-select>\n <div ng-if="command.rollbackType === \'PREVIOUS_IMAGE\'" style="margin-top: 5px">\n {{ previousServerGroup.name }} <span class="small">(no longer deployed)</span><br />\n <span class="small">\n <strong>Image</strong>: {{ previousServerGroup.imageName}}\n <span ng-if="previousServerGroup.imageId">({{ previousServerGroup.imageId }})</span><br />\n </span>\n <span class="small" ng-if="previousServerGroup.buildNumber">\n <strong>Build</strong> #{{ previousServerGroup.buildNumber }}\n </span>\n </div>\n </div>\n </div>\n\n <div class="row" ng-if="command.platformHealthOnlyShowOverride">\n <div class="col-sm-10 col-sm-offset-1">\n <platform-health-override\n command="command"\n platform-health-type="\'Amazon\'"\n show-help-details="true"\n field-columns="12"\n >\n </platform-health-override>\n </div>\n </div>\n\n <task-reason command="command"></task-reason>\n\n <div class="row">\n <div class="col-sm-11 col-sm-offset-1">\n Wait\n <input\n placeholder="0"\n min="0"\n type="number"\n ng-model="command.rollbackContext.delayBeforeDisableSeconds"\n class="form-control input-sm inline-number"\n />\n seconds before disabling <em>{{ ctrl.label(serverGroup) }}</em>.\n </div>\n </div>\n\n <div class="row">\n <div class="col-sm-11 col-sm-offset-1">\n Consider rollback successful when\n <input\n type="number"\n min="0"\n max="100"\n ng-model="command.rollbackContext.targetHealthyRollbackPercentage"\n class="form-control input-sm inline-number"\n />\n percent of instances are healthy.\n </div>\n </div>\n\n <div class="row">\n <div class="col-sm-4 sm-label-right">Rollback Operations</div>\n </div>\n <div class="row" ng-if="command.rollbackType === \'EXPLICIT\'">\n <div class="col-sm-11 col-sm-offset-1">\n <ol>\n <li>Enable <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em></li>\n <li>\n Resize <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em> to [\n <strong>min</strong>: {{serverGroup.capacity.desired}}, <strong>max</strong>: {{ serverGroup.capacity.max\n }}, <strong>desired</strong>: {{ serverGroup.capacity.desired }} ] <br />(minimum capacity pinned at\n {{serverGroup.capacity.desired}} to prevent autoscaling down during rollback)\n </li>\n\n <li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100">\n Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} instances to\n report as healthy\n </li>\n <li ng-if="command.rollbackContext.delayBeforeDisableSeconds > 0">\n Wait {{ command.rollbackContext.delayBeforeDisableSeconds }} seconds\n </li>\n <li>Disable <em>{{ serverGroup.name }}</em></li>\n <li>\n Restore minimum capacity of\n <em>{{ command.rollbackContext.restoreServerGroupName || \'previous server group\' }}</em> [\n <strong>min</strong>: {{ serverGroup.capacity.min }} ]\n </li>\n </ol>\n <p>This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}).</p>\n </div>\n </div>\n <div class="row" ng-if="command.rollbackType === \'PREVIOUS_IMAGE\'">\n <div class="col-sm-11 col-sm-offset-1">\n <ol>\n <li>\n Deploy <em>{{ previousServerGroup.imageId }}</em> [ <strong>min</strong>:\n {{serverGroup.capacity.desired}}, <strong>max</strong>: {{ serverGroup.capacity.max }},\n <strong>desired</strong>: {{ serverGroup.capacity.desired }} ] <br />(minimum capacity pinned at\n {{serverGroup.capacity.desired}} to prevent autoscaling down during deploy)\n </li>\n <li ng-if="command.rollbackContext.targetHealthyRollbackPercentage < 100">\n Wait for at least {{minHealthy(command.rollbackContext.targetHealthyRollbackPercentage)}} instances to\n report as healthy\n </li>\n <li>Disable {{ serverGroup.name }}</li>\n <li>\n Restore minimum capacity of <em>new server group</em> [ <strong>min</strong>: {{ serverGroup.capacity.min\n }} ]\n </li>\n </ol>\n <p>This rollback will affect server groups in {{ serverGroup.account }} ({{ serverGroup.region }}).</p>\n </div>\n </div>\n </div>\n <aws-footer\n action="ctrl.rollback()"\n cancel="ctrl.cancel()"\n is-valid="ctrl.isValid()"\n account="serverGroup.account"\n verification="verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class Ki{static getDisabledDate(e){if(e.isDisabled){const t=this.normalizeScalingProcesses(e).find((e=>"AddToLoadBalancer"===e.name&&!e.enabled));if(t)return t.suspensionDate}return null}static normalizeScalingProcesses(e){if(!e.asg||!e.asg.suspendedProcesses)return[];const t=e.asg.suspendedProcesses;return this.listProcesses().map((e=>{const a=t.find((t=>t.processName===e.name)),n={name:e.name,enabled:!a,description:e.description};if(a){const e=a.suspensionReason.replace("User suspended at ","");n.suspensionDate=new Date(e).getTime()}return n}))}static listProcesses(){return[{name:"Launch",description:"Controls if new instances should be launched into the ASG. If this is disabled, scale-up events will not produce new instances."},{name:"Terminate",description:"Controls if instances should be terminated during a scale-down event."},{name:"AddToLoadBalancer",description:"Controls if new instances should be added to the ASG’s ELB."},{name:"AlarmNotification",description:"This disables autoscaling."},{name:"AZRebalance",description:"Controls whether AWS should attempt to maintain an even distribution of instances across all healthy Availability Zones configured for the ASG."},{name:"HealthCheck",description:"If disabled, the instance’s health will no longer be reported to the autoscaling processor."},{name:"ReplaceUnhealthy",description:"Controls whether instances should be replaced if they failed the health check."},{name:"ScheduledActions",description:"Controls whether scheduled actions should be executed."}]}}function Yi(e,t){const{app:a,serverGroup:n}=e;return new ka((r=>{(function(e){const{app:t,serverGroup:a}=e;return t.ready().then((()=>{let e=t.serverGroups.data.find((e=>e.name===a.name&&e.account===a.accountId&&e.region===a.region));return e||t.loadBalancers.data.some((t=>t.account===a.accountId&&t.region===a.region&&t.serverGroups.some((t=>t.name===a.name&&(e=t,!0))))),e}))})(e).then((e=>{yt.getServerGroup(a.name,n.accountId,n.region,n.name).then((a=>{Object.assign(a,e,{account:n.accountId});const i=qn.awsServerGroupTransformer.normalizeServerGroupDetails(a);if(o.getAccountDetails(i.account).then((e=>{i.accountDetails=e,r.next(i)})),Rt(i))t();else{const e=i.asg?i.asg.vpczoneIdentifier:"";if(""!==e){const t=e.split(",")[0];g.listSubnets().then((e=>{const a=e.find((e=>e.id===t));i.subnetType=a.purpose,r.next(i)}))}i.disabledDate=Ki.getDisabledDate(i),r.next(i)}}),t)}),t)}))}class Xi extends $t.Component{constructor(){super(...arguments),this.editAdvancedSettings=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/advancedSettings/editAsgAdvancedSettings.modal.html",controller:"EditAsgAdvancedSettingsCtrl as ctrl",resolve:{application:()=>e,serverGroup:()=>t}})))}}render(){const{serverGroup:e}=this.props,t=e.asg;return $t.createElement(A,{heading:"Advanced Settings"},$t.createElement("dl",{className:"horizontal-when-filters-collapsed"},$t.createElement("dt",null,"Cooldown"),$t.createElement("dd",null,t.defaultCooldown," seconds"),t.enabledMetrics.length>0&&[$t.createElement("dt",{key:"t-metrics"},"Enabled Metrics"),$t.createElement("dd",{key:"d-metrics"},t.enabledMetrics.map((e=>e.metric)).join(", "))],$t.createElement("dt",null,"Health Check Type"),$t.createElement("dd",null,t.healthCheckType),$t.createElement("dt",null,"Grace Period"),$t.createElement("dd",null,t.healthCheckGracePeriod," seconds"),$t.createElement("dt",null,"Termination Policies"),$t.createElement("dd",null,t.terminationPolicies.join(", ")),t.capacityRebalance&&[$t.createElement("dt",null,"Capacity Rebalance ",$t.createElement(n,{id:"aws.serverGroup.capacityRebalance"})),$t.createElement("dd",null,`${t.capacityRebalance}`)]),$t.createElement("a",{className:"clickable",onClick:this.editAdvancedSettings},"Edit Advanced Settings"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/advancedSettings/editAsgAdvancedSettings.modal.html",'<div modal-page>\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Edit Advanced Settings for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Cooldown</b></div>\n <div class="col-md-2">\n <input type="number" required class="form-control input-sm" ng-model="command.cooldown" />\n </div>\n &nbsp;seconds\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right">\n <b>Enabled Metrics</b>\n <help-field key="aws.serverGroup.enabledMetrics"></help-field>\n </div>\n <div class="col-md-6">\n <ui-select multiple ng-model="command.enabledMetrics" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices\n repeat="enabledMetric in command.backingData.enabledMetrics | filter: $select.search | orderBy: \'toString()\'"\n >\n <span ng-bind-html="enabledMetric | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Health Check Type</b></div>\n <div class="col-md-6">\n <ui-select ng-model="command.healthCheckType" class="form-control input-sm">\n <ui-select-match placeholder="Select...">{{$select.selected}}</ui-select-match>\n <ui-select-choices\n repeat="healthCheckType in command.backingData.healthCheckTypes | filter: $select.search"\n >\n <span ng-bind-html="healthCheckType | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Health Check Grace Period</b></div>\n <div class="col-md-2">\n <input type="text" required class="form-control input-sm" ng-model="command.healthCheckGracePeriod" />\n </div>\n &nbsp;seconds\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right"><b>Termination Policies</b></div>\n <div class="col-md-6">\n <ui-select multiple ng-model="command.terminationPolicies" class="form-control input-sm">\n <ui-select-match>{{$item}}</ui-select-match>\n <ui-select-choices\n repeat="terminationPolicy in command.backingData.terminationPolicies | filter: $select.search | orderBy: \'toString()\'"\n >\n <span ng-bind-html="terminationPolicy | highlight: $select.search"></span>\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n <div class="form-group">\n <div class="col-md-5 sm-label-right">\n <b>Capacity Rebalance</b><help-field key="aws.serverGroup.capacityRebalance" />\n </div>\n <div class="col-md-6">\n <input type="checkbox" ng-model="command.capacityRebalance" /> Enable capacity rebalance\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <button type="submit" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="ctrl.submit()">Submit</button>\n </div>\n </form>\n</div>\n')}]);class Qi extends $t.Component{constructor(e){super(e),this.state={changeConfig:this.getChangeConfig(e.serverGroup)}}getChangeConfig(e){const t={metadata:Kt(e.entityTags,"creationMetadata")};return pa(e,"buildInfo.jenkins")&&(t.buildInfo={ancestor:void 0,jenkins:e.buildInfo.jenkins,target:void 0}),t}componentWillReceiveProps(e){this.setState({changeConfig:this.getChangeConfig(e.serverGroup)})}render(){const{serverGroup:e}=this.props,{changeConfig:t}=this.state,n=a.feature&&a.feature.entityTags,r=e.entityTags||{};return $t.createElement(A,{heading:"Server Group Information",defaultExpanded:!0},$t.createElement("dl",{className:"dl-horizontal dl-narrow"},$t.createElement("dt",null,"Created"),$t.createElement("dd",null,D(e.createdTime)),n&&$t.createElement(bt,{metadata:r.creationMetadata}),n&&$t.createElement(wt,{changeConfig:t,linkText:"view changes",nameItem:e,viewType:"description"}),$t.createElement("dt",null,"In"),$t.createElement("dd",null,$t.createElement(I,{account:e.account}),e.region),$t.createElement("dt",null,"VPC"),$t.createElement("dd",null,$t.createElement(Yn,{vpcId:e.vpcId})),e.vpcId&&e.subnetType&&$t.createElement("dt",null,"Subnet"),e.vpcId&&e.subnetType&&$t.createElement("dd",null,e.subnetType),e.asg&&$t.createElement("dt",null,"Zones"),e.asg&&$t.createElement("dd",null,$t.createElement("ul",null,e.asg.availabilityZones.map((e=>$t.createElement("li",{key:e},e)))))))}}var Ji=Object.defineProperty,es=Object.getOwnPropertyDescriptor;let ts=class extends $t.Component{render(){const{serverGroup:e,app:t}=this.props,a={min:e.asg.minSize,max:e.asg.maxSize,desired:e.asg.desiredCapacity};return $t.createElement(A,{heading:"Capacity",defaultExpanded:!0},$t.createElement(Et,{current:e.instances.length,capacity:a}),$t.createElement("div",null,$t.createElement("a",{className:"clickable",onClick:()=>ji.show({application:t,serverGroup:e})},"Resize Server Group")),$t.createElement("div",null,$t.createElement(Ct,{serverGroup:e})))}};ts=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?es(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Ji(t,a,i),i})([ce("amazon.serverGroup.CapacityDetailsSection")],ts);class as extends $t.Component{render(){const{serverGroup:e}=this.props;return e.instanceCounts.total>0?$t.createElement(A,{heading:"Health",defaultExpanded:!0},$t.createElement("dl",{className:"dl-horizontal dl-narrow"},$t.createElement("dt",null,"Instances"),$t.createElement("dd",null,$t.createElement(Y,{container:e.instanceCounts,className:"pull-left"})))):null}}const ns=({serverGroup:e})=>{if(!e.mixedInstancesPolicy)return null;const t=e.mixedInstancesPolicy.instancesDistribution;return $t.createElement(A,{heading:"Instances Distribution"},$t.createElement(j,{className:"horizontal-when-filters-collapsed"},$t.createElement(B,{label:"On-Demand Allocation Strategy",helpFieldId:"aws.serverGroup.odAllocationStrategy",value:t.onDemandAllocationStrategy}),$t.createElement(B,{label:"On-Demand Base Capacity",helpFieldId:"aws.serverGroup.odBase",value:t.onDemandBaseCapacity}),$t.createElement(B,{label:"On-Demand Percentage Above Base Capacity",helpFieldId:"aws.serverGroup.odPercentAboveBase",value:t.onDemandPercentageAboveBaseCapacity}),$t.createElement(B,{label:"Spot Allocation Strategy",helpFieldId:"aws.serverGroup.spotAllocationStrategy",value:t.spotAllocationStrategy}),t.spotInstancePools&&$t.createElement(B,{label:"Spot Instance Pools",helpFieldId:"aws.serverGroup.spotInstancePoolCount",value:t.spotInstancePools}),$t.createElement(B,{label:"Max Spot Price",helpFieldId:"aws.serverGroup.spotMaxPrice",value:t.spotMaxPrice||"on-demand price, default"})))},rs=e=>{let t;return(e||"").split(", ").forEach((e=>{const a=e.split("=");2===a.length&&"ancestor_name"===a[0]&&(t=a[1])})),t};class is extends $t.Component{constructor(e){super(e),this.state={image:this.getImage(e.serverGroup)}}getImage(e){const t=e.image?e.image:void 0;return e.image&&e.image.description&&(t.baseImage=rs(e.image.description)),t}componentWillReceiveProps(e){this.setState({image:this.getImage(e.serverGroup)})}render(){const{name:e,launchConfig:t}=this.props.serverGroup,{image:a}=this.state;return t?$t.createElement(A,{heading:"Launch Configuration"},$t.createElement("dl",{className:"horizontal-when-filters-collapsed"},$t.createElement("dt",null,"Name"),$t.createElement("dd",null,t.launchConfigurationName),$t.createElement("dt",null,"Image ID"),$t.createElement("dd",null,t.imageId),a&&a.imageLocation&&$t.createElement("dt",null,"Image Name"),a&&a.imageLocation&&$t.createElement("dd",null,a.imageLocation),a&&a.baseImage&&$t.createElement("dt",null,"Base Image Name"),a&&a.baseImage&&$t.createElement("dd",null,a.baseImage),$t.createElement("dt",null,"Instance Type"),$t.createElement("dd",null,t.instanceType),$t.createElement("dt",null,"IAM Profile"),$t.createElement("dd",null,t.iamInstanceProfile),$t.createElement("dt",null,"Instance Monitoring"),$t.createElement("dd",null,t.instanceMonitoring.enabled?"enabled":"disabled"),t.spotPrice&&$t.createElement("dt",null,"Spot Price"),t.spotPrice&&$t.createElement("dd",null,t.spotPrice),t.keyName&&$t.createElement("dt",null,"Key Name"),t.keyName&&$t.createElement("dd",null,t.keyName),t.kernelId&&$t.createElement("dt",null,"Kernel ID"),t.kernelId&&$t.createElement("dd",null,t.kernelId),t.ramdiskId&&$t.createElement("dt",null,"Ramdisk ID"),t.ramdiskId&&$t.createElement("dd",null,t.ramdiskId),$t.createElement("dt",null,"User Data"),t.userData&&$t.createElement("dd",null,$t.createElement(kt,{serverGroupName:e,userData:t.userData})),!t.userData&&$t.createElement("dd",null,"[none]"))):null}}function ss(e){return e.instanceTypeOverrides?$t.createElement(A,{heading:"Instance Types",defaultExpanded:!0,outerDivClassName:"multiple-instance-types-subsection",toggleClassName:"clickable subsection-heading",headingClassName:"collapsible-subheading"},$t.createElement("table",{className:"table table-condensed packed",id:"MultipleInstanceTypes"},$t.createElement("thead",null,$t.createElement("tr",null,$t.createElement("th",{id:"instanceType"},"Type ",$t.createElement(n,{id:"aws.serverGroup.multipleInstanceTypes"})),$t.createElement("th",{id:"weight"},"Weighted Capacity ",$t.createElement(n,{id:"aws.serverGroup.instanceTypeWeight"})))),$t.createElement("tbody",null,e.instanceTypeOverrides.map((e=>[$t.createElement("tr",{key:e.instanceType},$t.createElement("td",{headers:"instanceType"},e.instanceType),$t.createElement("td",{headers:"weight"},e.weightedCapacity))]))))):null}ar('.multiple-instance-types-subsection {\n padding: 0;\n}\n.multiple-instance-types-subsection a.subsection-heading {\n color: var(--color-black);\n}\n.multiple-instance-types-subsection h4.collapsible-subheading {\n padding: 10px 0px;\n background-color: var(--color-alabaster);\n margin: 0;\n font-size: 103%;\n font-weight: 600;\n text-transform: none;\n}\n.multiple-instance-types-subsection h4.collapsible-subheading .glyphicon {\n font-size: 10px;\n opacity: 0.5;\n margin-right: 4px;\n}\n.multiple-instance-types-subsection .content-body {\n -webkit-animation: 0.15 ease-in 0 fadeIn;\n animation: 0.15 ease-in 0 fadeIn;\n -webkit-animation-iteration-count: 1;\n animation-iteration-count: 1;\n padding-left: 17px;\n margin: 10px 0 20px 0;\n}\n.multiple-instance-types-subsection .content-body:before,\n.multiple-instance-types-subsection .content-body:after {\n display: table;\n content: " ";\n}\n.multiple-instance-types-subsection .content-body:after {\n clear: both;\n}\n.multiple-instance-types-subsection .content-body ul {\n list-style-type: none;\n padding-left: 0;\n}\n.multiple-instance-types-subsection:last-child {\n border-bottom-width: 0;\n}\n.multiple-instance-types-subsection:first-child {\n padding-top: 0;\n}\n');const ls=({serverGroup:e})=>{var t,a,n;const{image:r}=e,i=rs(null==r?void 0:r.description);if(!e.launchTemplate&&!e.mixedInstancesPolicy)return null;const s=!!e.mixedInstancesPolicy,l=s?e.mixedInstancesPolicy.launchTemplates[0]:e.launchTemplate,{launchTemplateData:o}=l,c=s?e.mixedInstancesPolicy.instancesDistribution.spotMaxPrice:null==(a=null==(t=null==o?void 0:o.instanceMarketOptions)?void 0:t.spotOptions)?void 0:a.maxPrice,d=null==(n=null==o?void 0:o.creditSpecification)?void 0:n.cpuCredits,p=s?e.mixedInstancesPolicy.launchTemplateOverridesForInstanceType:null;return $t.createElement(A,{heading:"Launch Template"},$t.createElement(j,{className:"horizontal-when-filters-collapsed"},$t.createElement(B,{label:"Name",value:l.launchTemplateName}),$t.createElement(B,{label:"Image ID",value:o.imageId}),(null==r?void 0:r.imageLocation)&&$t.createElement(B,{label:"Image Name",value:null==r?void 0:r.imageLocation}),i&&$t.createElement(B,{label:"Base Image Name",value:i}),p&&p.length>0?$t.createElement(ss,{instanceTypeOverrides:p}):$t.createElement(B,{label:"Instance Type",value:o.instanceType}),d&&$t.createElement(B,{label:"CPU Credit Specification",value:d}),$t.createElement(B,{label:"IAM Profile",value:o.iamInstanceProfile.name}),o.monitoring&&$t.createElement(B,{label:"Instance Monitoring",value:o.monitoring.enabled?"enabled":"disabled"}),c&&$t.createElement(B,{label:"Max Spot Price",value:c}),o.keyName&&$t.createElement(B,{label:"Key Name",value:o.keyName}),o.kernelId&&$t.createElement(B,{label:"Kernel ID",value:o.kernelId}),o.ramDiskId&&$t.createElement(B,{label:"Ramdisk ID",value:o.ramDiskId}),o.userData&&$t.createElement(B,{label:"User Data",value:$t.createElement(kt,{serverGroupName:e.name,userData:o.userData})})))};class os extends $t.Component{render(){return $t.createElement(A,{heading:"Logs"},$t.createElement("ul",null,$t.createElement("li",null,$t.createElement(Ct,{serverGroup:this.props.serverGroup}))))}}class cs extends $t.Component{constructor(e){super(e),this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=t.buildInfo||{};let n=null;a.commit&&(n=t.buildInfo.commit.substring(0,8));let r=null;if(a.buildInfoUrl)r=t.buildInfo.buildInfoUrl;else if(a.jenkins){const e=t.buildInfo.jenkins;r=`${e.host}job/${e.name}/${e.number}`}return{commitHash:n,jenkinsLink:r}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{serverGroup:e}=this.props,{commitHash:t,jenkinsLink:a}=this.state;return e.buildInfo&&e.buildInfo.jenkins?$t.createElement(A,{heading:"Package"},$t.createElement("dl",{className:"horizontal-when-filters-collapsed"},$t.createElement("dt",null,"Job"),$t.createElement("dd",null,e.buildInfo.jenkins.name),$t.createElement("dt",null,"Package"),$t.createElement("dd",null,e.buildInfo.package_name),$t.createElement("dt",null,"Build"),$t.createElement("dd",null,e.buildInfo.jenkins.number),$t.createElement("dt",null,"Commit"),$t.createElement("dd",null,t),$t.createElement("dt",null,"Version"),$t.createElement("dd",null,e.buildInfo.version),$t.createElement("dt",null,"Build Link"),$t.createElement("dd",null,$t.createElement("a",{target:"_blank",href:a},a)))):null}}function ds(e){const t=Dt.useRef(),a=Dt.useRef(),{lines:n,className:r="",style:i={}}=e;return Dt.useEffect((()=>{return t?(a.current=(e=t.current,new rn(e,{type:"line",data:{labels:[],datasets:[{data:[]}]},options:{plugins:{tooltip:{mode:"index",itemSort:(e,t)=>{var a,n;const r=e.chart.data.datasets.map((e=>e.label)),i=null!=(a=e.dataset.label)?a:r[0],s=null!=(n=t.dataset.label)?n:r[0];return r.indexOf(s)-r.indexOf(i)}}},hover:{mode:"index"},elements:{point:{hitRadius:12,radius:1,hoverRadius:5}},scales:{x:{type:"time",display:!0,scaleLabel:{labelString:"Date"},ticks:{major:{enabled:!0}}},y:{min:0,stacked:!0}}}})),()=>{var e;return null==(e=a.current)?void 0:e.destroy()}):null;var e}),[t.current]),Dt.useEffect((()=>{const e=a.current;e&&n&&(e.options.animation=!1,e.data.datasets=n,e.update())}),[a.current,n]),Dt.createElement("canvas",{ref:t,...i,className:r})}function ps(e){return e.serverGroup&&e.alarm?Dt.createElement(us,{...e}):null}function us(e){var t,a;const n=null!=(t=e.alarm)?t:{},r=null!=(a=e.serverGroup)?a:{},{account:i,awsAccount:s,cloudProvider:l,region:o,type:c}=r,{metricName:d,namespace:p,statistic:u,period:m}=n,{status:g,result:h}=$((async()=>{var t;const a={namespace:p,statistics:u,period:m};n.dimensions.forEach((e=>a[e.name]=e.value));const r="aws"===l?i:s,c=await St.getMetricStatistics("aws",r,o,d,a);return c.datapoints=c.datapoints||[],null==(t=e.onChartLoaded)||t.call(e,c),c}),{datapoints:[],unit:""},[p,u,m,c,i,o,d]),f=Nt();if(Gt(e.alarmUpdated,(()=>f())),"PENDING"===g)return Dt.createElement("div",{className:"flex-container-v middle center sp-margin-xl"},Dt.createElement(te,null));if("REJECTED"===g)return Dt.createElement(Dt.Fragment,null,Dt.createElement("div",null,"no data"),Dt.createElement("div",null,"something went wrong fetching stats"));if(0===h.datapoints.length)return Dt.createElement(Dt.Fragment,null,"no data");const v=new Date,y=new Date(Date.now()-864e5),b={label:d,fill:"stack",borderColor:"green",borderWidth:2,data:h.datapoints.map((e=>({x:new Date(e.timestamp),y:e.average})))},w={label:"threshold",borderWidth:1,borderColor:"red",data:[{x:y,y:n.threshold},{x:v,y:n.threshold}]};return Dt.createElement(ds,{lines:[b,w]})}rn.register(sn,ln,on,cn,dn,pn,un,mn,gn);t("spinnaker.amazon.serverGroup.details.scalingPolicy.metricAlarmChart.component",[]).component("metricAlarmChart",ja(M(ps,"metricAlarmChart"),["alarm","serverGroup","alarmUpdated","onChartLoaded"]));const ms={ASGAverageCPUUtilization:"CPUUtilization",ASGAverageNetworkIn:"NetworkIn",ASGAverageNetworkOut:"NetworkOut"},gs=({alarmUpdated:e=new ya,config:t,serverGroup:a,updateUnit:n})=>{const[r,i]=Dt.useState({alarmName:null,alarmArn:null,metricName:null,namespace:null,statistic:"Average",dimensions:[],period:60,threshold:t.targetValue,comparisonOperator:"GreaterThanThreshold",okactions:[],insufficientDataActions:[],alarmActions:[],evaluationPeriods:null,alarmDescription:null,unit:null});Dt.useEffect((()=>{(()=>{var e;const n=null==t?void 0:t.customizedMetricSpecification,s={...r,dimensions:(null==n?void 0:n.dimensions)||[{name:"AutoScalingGroupName",value:a.name}],metricName:(null==n?void 0:n.metricName)||ms[null==(e=null==t?void 0:t.predefinedMetricSpecification)?void 0:e.predefinedMetricType],namespace:(null==n?void 0:n.namespace)||"AWS/EC2",threshold:null==t?void 0:t.targetValue};n&&(s.statistic=null==n?void 0:n.statistic),i(s)})()}),[t]);return Dt.createElement(ps,{alarm:r,alarmUpdated:e,onChartLoaded:t=>{n&&n(t.unit),null==e||e.next()},serverGroup:a})};ar("dimensions-editor {\n display: block;\n padding-left: 5px;\n}\ndimensions-editor h5 {\n margin-bottom: 0;\n}\ndimensions-editor .dimensions-row {\n margin-top: 5px;\n margin-left: -20px;\n}\ndimensions-editor .add-new {\n margin-left: 0;\n padding: 4px;\n width: 100%;\n}\n");const hs=({alarm:e,serverGroup:t,updateAvailableMetrics:a})=>{const[n,r]=Dt.useState(e.dimensions||[]),{result:i}=$((()=>St.listMetrics("aws",t.account,t.region,{namespace:e.namespace}).then((e=>{const t=ua(e,(e=>e.dimensions));return Yt(t.map((e=>e.name))).sort()}))),[],[e.namespace,t.name]),s=(e,t,i)=>{const s=[...n];s[i][e]=t,r(s),a(s)};return Dt.createElement("div",null,Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-12 small"},Dt.createElement("h5",null,"Dimensions"))),n.map(((t,n)=>Dt.createElement("div",{key:`dimension-${n}`,className:"row dimensions-row horizontal middle"},Dt.createElement("div",{className:"col-md-6"},Dt.createElement(c,{onChange:e=>s("name",e.target.value,n),value:t.name,stringOptions:i})),Dt.createElement(l,{onChange:e=>s("value",e.target.value,n),value:t.value}),!e.disableEditingDimensions&&Dt.createElement("div",{className:"col-md-1",onClick:()=>(t=>{const n=e.dimensions.filter(((e,a)=>a!==t));r(n),a(n)})(n)},Dt.createElement("a",null,Dt.createElement("i",{className:"glyphicon glyphicon-trash clickable"})))))),!e.disableEditingDimensions&&Dt.createElement("div",{className:"row"},Dt.createElement("div",null,Dt.createElement("button",{type:"button",className:"btn btn-block btn-xs add-new",onClick:()=>{const e=[...n,{}];r(e),a(e)}},Dt.createElement("span",{className:"glyphicon glyphicon-plus-sign sp-margin-xs-left"}),"Add dimension"))))},fs=["AWS/ApplicationELB","AWS/AutoScaling","AWS/AmazonMQ","AWS/Billing","AWS/CloudFront","AWS/CloudSearch","AWS/Events","AWS/DynamoDB","AWS/ECS","AWS/ElastiCache","AWS/EBS","AWS/EC2","AWS/ELB","AWS/ElasticMapReduce","AWS/ES","AWS/Kinesis","AWS/Lambda","AWS/ML","AWS/OpsWorks","AWS/Redshift","AWS/RDS","AWS/Route53","AWS/SNS","AWS/SQS","AWS/S3","AWS/SWF","AWS/StorageGateway","AWS/WAF","AWS/WorkSpaces"];ar(".MetricSelector {\n font-size: 12px;\n}\n.MetricSelector .simple-input {\n width: 216px;\n}\n.MetricSelector .advanced-input-namespace {\n width: 138px;\n}\n.MetricSelector .advanced-input-metric {\n width: 300px;\n}\n");const vs=({alarm:e,updateAlarm:t,serverGroup:a})=>{var r,i;const s=((null==(i=null==(r=fn)?void 0:r.metrics)?void 0:i.customNamespaces)||[]).concat(fs),[l,o]=Dt.useState(!1),[d,p]=Dt.useState({}),[u,m]=Dt.useState(null==e?void 0:e.metricName),[g,h]=Dt.useState(null==e?void 0:e.namespace),f=((null==e?void 0:e.dimensions)||[]).reduce(((e,t)=>(e[t.name]=t.value,e)),{}),v=e=>e.sort(((e,t)=>{var a;return null==(a=e.name)?void 0:a.localeCompare(t.name)})).map((e=>e.value)).join(", "),y=v((null==e?void 0:e.dimensions)||[]),{result:b}=$((()=>{const n="aws"===a.cloudProvider?a.account:null==a?void 0:a.awsAccount;return St.listMetrics("aws",n,a.region,f).then((a=>{const n=a.map((e=>({label:`(${e.namespace}) ${e.name}`,dimensions:[],dimensionValues:v(e.dimensions),value:e,...e}))).sort(((e,t)=>{var a;return null==(a=e.label)?void 0:a.localeCompare(t.label)})),r=n.find((t=>t.name===(null==e?void 0:e.metricName)&&t.namespace===(null==e?void 0:e.namespace)&&t.dimensionValues===y))||n.find((e=>e.name.match("CPUUtilization")))||n[0];p(r),m(r.name),h(r.namespace);const i={...e,metricName:r.name,namespace:r.namespace,dimensions:r.dimensions};return t(i),n}))}),[],[a,null==e?void 0:e.namespace]),w=()=>{const n=!l;if(n)f.namespace=null==e?void 0:e.namespace;else{const n={...e,dimension:[{name:"AutoScalingGroupName",value:a.name}]};t(n)}o(n)},E=(a,n)=>{const r={...e,metricName:n,namespace:a};m(n),h(a),t(r)};return l?Dt.createElement("div",{className:"MetricSelector"},Dt.createElement("div",{className:"horizontal middle"},Dt.createElement(c,{value:g,onChange:t=>E(t.target.value,null==e?void 0:e.metricName),stringOptions:s,inputClassName:"advanced-input-namespace sp-margin-m-right"}),Dt.createElement(c,{value:u,onChange:t=>E(null==e?void 0:e.namespace,t.target.value),stringOptions:b.map((e=>e.name)),placeholder:"name",searchable:!0,inputClassName:"advanced-input-metric"})),Dt.createElement("div",{className:"vertical"},!Boolean(b.length)&&Dt.createElement("span",{className:"input-label"},Dt.createElement("b",null,"Note:")," no metrics found for selected namespace + dimensions"),Dt.createElement("a",{className:"clickable",onClick:w},Dt.createElement("span",{className:"sp-margin-s-yaxis sp-margin-xs-right"},"Only show metrics for this auto scaling group"),Dt.createElement(n,{id:"aws.scalingPolicy.search.restricted"}))),Dt.createElement(hs,{alarm:e,serverGroup:a,updateAvailableMetrics:a=>{const n={...e,dimensions:a};t(n)}})):Dt.createElement("div",{className:"MetricSelector horizontal middle"},Dt.createElement(c,{value:d,onChange:a=>(a=>{const n={...e,metricName:a.name,namespace:a.namespace,dimensions:a.dimensions},r=b.find((e=>e.namespace===a.namespace&&e.name===a.name));p(r),m(r.name),h(r.namespace),t(n)})(a.target.value),options:b,clearable:!1,inputClassName:"sp-margin-s-right simple-input"}),Dt.createElement("a",{className:"clickable",onClick:w},Dt.createElement("span",{className:"sp-margin-xs-right"},"Search all metrics"),Dt.createElement(n,{id:"aws.scalingPolicy.search.all"})))};ar(".TargetMetricFields .metric-select-input {\n font-size: 12px;\n width: 180px;\n}\n.TargetMetricFields .target-input {\n width: 120px;\n}\n");const ys=({allowDualMode:e,cloudwatch:t,command:a,isCustomMetric:n,serverGroup:r,toggleMetricType:i,unit:s,updateCommand:l})=>{var o,d;const[p,m]=Dt.useState(a),[g,h]=Dt.useState(n),[f,v]=Dt.useState(s),y=(e,t)=>{const a=Ut(p);ta(a,e,t),m(a),l(a)};return Dt.createElement("div",{className:"TargetMetricFields sp-margin-l-xaxis"},Dt.createElement("p",null,"With target tracking policies, Amazon will automatically adjust the size of your ASG to keep the selected metric as close as possible to the selected value."),t&&Dt.createElement("p",null,Dt.createElement("b",null,"Note:"),' metrics must be sent to Amazon CloudWatch before they can be used in auto scaling. If you do not see a metric below, click "Configure available metrics" in the server group details to set up forwarding from Atlas to CloudWatch.'),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Metric"),Dt.createElement("div",{className:"col-md-10 content-fields"},!g&&Dt.createElement(c,{value:null==(o=p.targetTrackingConfiguration.predefinedMetricSpecification)?void 0:o.predefinedMetricType,stringOptions:["ASGAverageCPUUtilization","ASGAverageNetworkOut","ASGAverageNetworkIn"],onChange:e=>y("targetTrackingConfiguration.predefinedMetricSpecification.predefinedMetricType",e.target.value),inputClassName:"metric-select-input"}),g&&Dt.createElement(vs,{alarm:p.targetTrackingConfiguration.customizedMetricSpecification,serverGroup:r,updateAlarm:e=>{y("targetTrackingConfiguration.customizedMetricSpecification",e)}}),e&&Dt.createElement("a",{className:"clickable",onClick:()=>{const e=Ut(p);g?(ta(e,"targetTrackingConfiguration.predefinedMetricSpecification",{predefinedMetricType:"ASGAverageCPUUtilization"}),ta(e,"targetTrackingConfiguration.customizedMetricSpecification",null)):(ta(e,"targetTrackingConfiguration.predefinedMetricSpecification",null),ta(e,"targetTrackingConfiguration.customizedMetricSpecification",{metricName:"CPUUtilization",namespace:"AWS/EC2",dimensions:[{name:"AutoScalingGroupName",value:r.name}],statistic:"Average"})),m(e),l(e),h(!g),i(g?"predefined":"custom")}},g?"Use a predefined metric":"Select a custom metric"))),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Target"),Dt.createElement("div",{className:"col-md-10 content-fields horizontal"},g&&Dt.createElement("div",{className:"horizontal middle"},Dt.createElement(c,{value:null==(d=p.targetTrackingConfiguration.customizedMetricSpecification)?void 0:d.statistic,stringOptions:["Average","Maximum","Minimum","SampleCount","Sum"],onChange:e=>y("targetTrackingConfiguration.customizedMetricSpecification.statistic",e.target.value),inputClassName:"form-control input-sm target-input"}),Dt.createElement("span",{className:"sp-margin-xs-xaxis"},"of")),Dt.createElement("div",{className:"horizontal middle"},Dt.createElement(u,{value:p.targetTrackingConfiguration.targetValue,onChange:e=>y("targetTrackingConfiguration.targetValue",Number.parseInt(e.target.value)),inputClassName:"form-control input-sm sp-margin-xs-right"}),Dt.createElement("span",null,f)))),Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},Dt.createElement(gs,{config:p.targetTrackingConfiguration,serverGroup:r,unit:f,updateUnit:e=>v(e)}))))};ar(".TargetTrackingAdditionalSettings {\n font-size: 14px;\n}\n.TargetTrackingAdditionalSettings .row {\n margin-bottom: 10px;\n}\n.TargetTrackingAdditionalSettings .number-input-sm {\n width: 120px;\n}\n");const bs=({command:e,cooldowns:t,policyName:a,updateCommand:r})=>{var i;const s=(t,a)=>{const n={...e};ta(n,t,a),r(n)},l=null==(i=e.targetTrackingConfiguration)?void 0:i.disableScaleIn;return Dt.createElement("div",{className:"section-body TargetTrackingAdditionalSettings"},a&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Policy Name"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},a)),Boolean(e.estimatedInstanceWarmup)&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Warmup"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement("span",{className:"form-control-static"},"Instances need"),Dt.createElement(u,{value:e.estimatedInstanceWarmup,onChange:e=>s("estimatedInstanceWarmup",Number.parseInt(e.target.value)),inputClassName:"form-control number-input-sm sp-margin-xs-xaxis"}),Dt.createElement("span",{className:"input-label"}," seconds to warm up "))),Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Scale In"),Dt.createElement("div",{className:"col-md-9"},Dt.createElement("div",{className:"checkbox"},Dt.createElement(d,{text:"Disable Scale-downs",checked:l,onChange:e=>s("targetTrackingConfiguration.disableScaleIn",e.target.checked)}),Dt.createElement("div",{className:"small"},Dt.createElement("p",null,"This option disables scale-downs for the target tracking policy, while keeping the scale-ups. This means that ASG will not scale down unless you explicitly set up a separate step policy to scale it down."),Dt.createElement("p",null,"This is useful when you have special requirements, such as gradual or delayed scale-down."))))),Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},l&&Dt.createElement("div",{className:"well"},"This policy will not scale down. Make sure you have another policy (either TT or Step) that will scale down this ASG."),!1===l&&Dt.createElement("div",{className:"well"},"This policy will scale both up and down. Make sure you don't have other scaling policies, as they will likely interfere with each other."))),t&&!l&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-3 sm-label-right"},Dt.createElement("span",{className:"sp-margin-xs-right"},"Scale In Cooldown"),Dt.createElement(n,{id:"titus.autoscaling.scaleIn.cooldown"})),Dt.createElement("div",{className:"col-md-9 horizontal middle"},Dt.createElement(u,{value:e.targetTrackingConfiguration.scaleInCooldown,onChange:e=>s("targetTrackingConfiguration.scaleInCooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis number-input-sm"}),Dt.createElement("span",{className:"input-label"}," seconds "))),t&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-3 sm-label-right"},Dt.createElement("span",{className:"sp-margin-xs-right"},"Scale Out Cooldown"),Dt.createElement(n,{id:"titus.autoscaling.scaleOut.cooldown"})),Dt.createElement("div",{className:"col-md-9 horizontal middle"},Dt.createElement(u,{value:e.targetTrackingConfiguration.scaleOutCooldown,onChange:e=>s("targetTrackingConfiguration.scaleOutCooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis number-input-sm"}),Dt.createElement("span",{className:"input-label"}," seconds "))))},ws={buildAlarm:(e,t,a)=>{const n=(null==e?void 0:e.alarms)?e.alarms[0]:{};return{name:n.alarmName,actionsEnabled:!0,alarmActionArns:n.alarmActions,alarmDescription:n.alarmDescription,asgName:a,comparisonOperator:n.comparisonOperator,dimensions:n.dimensions,evaluationPeriods:n.evaluationPeriods,insufficientDataActionArns:n.insufficientDataActions,metricName:n.metricName,namespace:n.namespace,okActionArns:n.okactions,period:n.period,region:t,statistic:n.statistic,threshold:n.threshold,unit:n.unit}},buildStepPolicy:(e,t,a)=>{var n,r;const i=e.stepAdjustments.map((e=>{const a={scalingAdjustment:Math.abs(e.scalingAdjustment)};return void 0!==e.metricIntervalUpperBound&&(a.metricIntervalUpperBound=e.metricIntervalUpperBound+t),void 0!==e.metricIntervalLowerBound&&(a.metricIntervalLowerBound=e.metricIntervalLowerBound+t),a}));return{estimatedInstanceWarmup:null!=(r=null!=(n=e.estimatedInstanceWarmup)?n:a)?r:600,metricAggregationType:"Average",stepAdjustments:i}},buildSimplePolicy:e=>{var t,a;return{cooldown:null!=(t=e.cooldown)?t:600,scalingAdjustment:null!=(a=Math.abs(e.scalingAdjustment))?a:1}},buildNewCommand:(e,t,a)=>{var n,r,i;const s={name:a.policyName,adjustmentType:"Step"===e?a.adjustmentType:null,cloudProvider:t.cloudProvider,credentials:t.account,provider:t.type,region:t.region,serverGroupName:t.name};return"Step"===e&&(s.alarm=ws.buildAlarm(a,t.region,t.name),s.minAdjustmentMagnitude=null!=(n=a.minAdjustmentMagnitude)?n:1,(null==(r=a.stepAdjustments)?void 0:r.length)?s.step=ws.buildStepPolicy(a,s.alarm.threshold,s.cooldown):s.simple=ws.buildSimplePolicy(a)),"TargetTracking"===e&&(s.estimatedInstanceWarmup=null!=(i=a.estimatedInstanceWarmup)?i:600,s.targetTrackingConfiguration={...a.targetTrackingConfiguration}),s},prepareCommandForUpsert:(e,t)=>{const a=Ut(e);return"PercentChangeInCapacity"!==a.adjustmentType&&delete a.minAdjustmentMagnitude,a.step?a.step.stepAdjustments.forEach((e=>{t&&(e.scalingAdjustment=0-e.scalingAdjustment,delete a.step.estimatedInstanceWarmup),void 0!==e.metricIntervalLowerBound&&(e.metricIntervalLowerBound-=a.alarm.threshold),void 0!==e.metricIntervalUpperBound&&(e.metricIntervalUpperBound-=a.alarm.threshold)})):t&&(e.simple.scalingAdjustment=0-e.simple.scalingAdjustment),a}},Es=({app:e,closeModal:t,dismissModal:a,policy:n,serverGroup:r})=>{var i;const[s,l]=Dt.useState(Boolean(null==(i=n.targetTrackingConfiguration)?void 0:i.customizedMetricSpecification)),[o,c]=Dt.useState({});Dt.useEffect((()=>{const e=ws.buildNewCommand("TargetTracking",r,n);c(e)}),[]);const d=n.policyName?"Update":"Create";return Dt.createElement(Tt,{closeModal:t,dismissModal:a,title:`${d} scaling policy`,application:e,description:`${d} scaling policy for ${r.name}`,initialValues:o,mapValuesToTask:()=>({application:e,job:[{type:"upsertScalingPolicy",...o}]}),render:()=>Dt.createElement("div",{className:"modal-body"},Dt.createElement("h4",{className:"section-heading"},"Target Metric"),Dt.createElement(ys,{allowDualMode:!0,cloudwatch:!1,command:o,isCustomMetric:s,serverGroup:r,toggleMetricType:e=>l("custom"===e),updateCommand:c}),Dt.createElement("h4",{className:"section-heading"},"Additional Settings"),Dt.createElement(bs,{command:o,cooldowns:!1,policyName:n.policyName,updateCommand:c}))})};function Cs(e){const[t,a]=$t.useState(null),r=e=>{a(e.currentTarget.id)},i="step"===t?"card active":"card",s="targetTracking"===t?"card active":"card",l="aws.scalingPolicy.additionalHelp",o=!!P.getHelpField(l);return $t.createElement(Fa,{show:!0,onHide:e.showCallback},$t.createElement(Fa.Header,{closeButton:!0},$t.createElement("h3",null,"Select a policy type")),$t.createElement(Fa.Body,null,$t.createElement("div",{className:"card-choices"},$t.createElement("div",{className:s,onClick:r,id:"targetTracking"},$t.createElement("h3",null,"Target Tracking"),$t.createElement("div",null,"Continuously adjusts the size of the ASG to keep a specified metric at the target value")),$t.createElement("div",{className:i,onClick:r,id:"step"},$t.createElement("h3",null,"Step"),$t.createElement("div",null,"Rule-based scaling, with the ability to define different scaling amounts depending on the magnitude of the alarm breach"))),o&&$t.createElement(de,{type:"info",message:$t.createElement(n,{id:l,expand:!0})}),e.warnOnMinMaxCapacity&&$t.createElement(de,{type:"warning",message:$t.createElement($t.Fragment,null,$t.createElement("p",null,"This server group's ",$t.createElement("em",null,"min")," and ",$t.createElement("em",null,"max")," capacity are identical, so scaling policies will have ",$t.createElement("b",null,"no effect.")),$t.createElement("p",null,"Scaling policies work by adjusting the server group's ",$t.createElement("em",null,"desired")," capacity to a value between the min and max."))})),$t.createElement(Fa.Footer,null,$t.createElement("button",{className:"btn btn-default",onClick:e.showCallback},"Cancel"),$t.createElement("button",{className:"btn btn-primary",disabled:!t,onClick:()=>{e.typeSelectedCallback(t)}},"Next")))}ar(".ScalingPolicyAdditionalSettings .section-additional-settings .row {\n margin-bottom: 10px;\n}\n.ScalingPolicyAdditionalSettings .section-additional-settings .number-input-sm {\n width: 60px;\n}\n");const ks=({command:e,isInstanceType:t,isNew:a,operator:r,updateCommand:i})=>{var s,l,o,c;const[d,p]=Dt.useState(e),m=(t,a)=>{const n={...e};ta(n,t,a),p(n),i(n)};return Dt.createElement("div",{className:"ScalingPolicyAdditionalSettings"},Dt.createElement("h4",{className:"section-heading"},"Additional Settings"),Dt.createElement("div",{className:"section-body section-additional-settings"},!a&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Policy Name"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement("span",{className:"form-control-static select-placeholder"},d.name))),!t&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Adjustment Step"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement("span",{className:"form-control-static select-placeholder"},`${r} instances in increments of at least `),Dt.createElement(u,{value:d.minAdjustmentMagnitude,onChange:e=>m("minAdjustmentMagnitude",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),Dt.createElement("span",{className:"input-label"}," instance(s) "))),Boolean(d.simple)&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Cooldown"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement("span",{className:"form-control-static select-placeholder"}," Wait at least "),Dt.createElement(u,{value:null==(s=d.simple)?void 0:s.cooldown,onChange:e=>m("simple.cooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),Dt.createElement("span",{className:"input-label"}," seconds before another scaling event "))),Boolean(null==(l=d.step)?void 0:l.estimatedInstanceWarmup)&&"Remove"!==r&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Warmup"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement("span",{className:"form-control-static select-placeholder"},"Instances need"),Dt.createElement(u,{value:d.step.estimatedInstanceWarmup,onChange:e=>m("step.estimatedInstanceWarmup",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),Dt.createElement("span",{className:"input-label"}," seconds to warm up after each step "))),Boolean(null==(o=d.step)?void 0:o.cooldown)&&"Remove"!==r&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},Dt.createElement("span",{className:"sp-margin-xs-right"},"Cooldown"),Dt.createElement(n,{id:`${d.cloudProvider||d.provider}.autoscaling.cooldown`})),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement(u,{value:null==(c=d.step)?void 0:c.cooldown,onChange:e=>m("step.cooldown",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-xaxis input-sm number-input-sm"}),Dt.createElement("span",{className:"input-label"}," seconds ")))))},Ss="spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component",Ns="spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component";t("spinnaker.amazon.serverGroup.details.scalingPolicy.additionalSettings.component",[]).component("scalingPolicyAdditionalSettings",ja(M(ks,"scalingPolicyAdditionalSettings"),["command","isInstanceType","isNew","operator","updateCommand"]));ar(".AlarmConfigurer {\n font-size: 12px;\n margin: 0px;\n}\n.AlarmConfigurer .configurer-field-lg {\n width: 90px;\n}\n.AlarmConfigurer .configurer-field-small {\n width: 32px;\n}\n.AlarmConfigurer .configurer-field-med {\n width: 48px;\n}\n.AlarmConfigurer .number-input-field {\n margin: 0px;\n}\n");const Gs=["Average","Maximum","Minimum","SampleCount","Sum"],Ts=[{label:">=",value:"GreaterThanOrEqualToThreshold"},{label:">",value:"GreaterThanThreshold"},{label:"<=",value:"LessThanOrEqualToThreshold"},{label:"<",value:"LessThanThreshold"}],Is=[{label:"1 minute",value:60},{label:"5 minutes",value:300},{label:"15 minutes",value:900},{label:"1 hour",value:3600},{label:"4 hours",value:14400},{label:"1 day",value:86400}],xs=({alarm:e,multipleAlarms:t,serverGroup:a,stepAdjustments:n,stepsChanged:r,updateAlarm:i})=>{var s,l;const o=0===(null==(s=e.comparisonOperator)?void 0:s.indexOf("Greater"))?"max":"min",[d,p]=Dt.useState(e),[m,g]=Dt.useState(null==d?void 0:d.unit),h=It(o);Dt.useEffect((()=>{if(n&&void 0!==h){const t={scalingAdjustment:1,["max"===o?"metricIntervalLowerBound":"metricIntervalUpperBound"]:e.threshold};r([t])}}),[o]),Dt.useEffect((()=>{const e="max"===o?"metricIntervalLowerBound":"metricIntervalUpperBound";if(null==n?void 0:n.length){const t=[...n];t[0][e]=d.threshold,r(t)}}),[d.threshold]);const f=(e,t)=>{const a={...d,[e]:t};p(a),i(a)};return Dt.createElement("div",{className:"AlarmConfigurer"},t&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-12"},Dt.createElement("div",{className:"alert alert-warning"},Dt.createElement("p",null,Dt.createElement("i",{className:"fa fa-exclamation-triangle"})," This scaling policy is configured with multiple alarms. You are only editing the first alarm."),Dt.createElement("p",null,"To edit or remove the additional alarms, you will need to use the AWS console.")))),(null==(l=d.alarmActionArns)?void 0:l.length)>1&&Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-12"},Dt.createElement("div",{className:"alert alert-warning"},Dt.createElement("p",null,Dt.createElement("i",{className:"fa fa-exclamation-triangle"})," This alarm is used in multiple scaling policies. Any changes here will affect those other scaling policies.")))),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"Whenever"),Dt.createElement("div",{className:"col-md-10 horizontal"},Dt.createElement(c,{value:d.statistic,onChange:e=>f("statistic",e.target.value),stringOptions:Gs,clearable:!1,inputClassName:"sp-margin-xs-right configurer-field-lg"}),Dt.createElement("span",{className:"input-label sp-margin-xs-right sp-margin-s-top"}," of "),Dt.createElement(vs,{alarm:d,serverGroup:a,updateAlarm:e=>{p(e),i(e)}}))),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"is"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement(c,{value:d.comparisonOperator,onChange:e=>f("comparisonOperator",e.target.value),options:Ts,clearable:!1,inputClassName:"sp-margin-s-right configurer-field-small"}),Dt.createElement("div",{className:"sp-margin-xl-left"},Dt.createElement(u,{value:d.threshold,onChange:e=>f("threshold",Number.parseInt(e.target.value)),inputClassName:"sp-margin-xs-right configurer-field-lg"})),Dt.createElement("span",{className:"input-label"},m))),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-2 sm-label-right"},"for at least"),Dt.createElement("div",{className:"col-md-10 horizontal middle"},Dt.createElement(u,{value:d.evaluationPeriods,onChange:e=>f("evaluationPeriods",Number.parseInt(e.target.value)),inputClassName:"configurer-field-med number-input-field"}),Dt.createElement("span",{className:"input-label sp-margin-s-xaxis"}," consecutive period(s) of "),Dt.createElement(c,{value:d.period,onChange:e=>f("period",e.target.value),options:Is,clearable:!1,inputClassName:"sp-margin-xs-right configurer-field-lg"}))),Dt.createElement("div",{className:"row sp-margin-s-yaxis"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},e&&Dt.createElement("div",null,Dt.createElement(ps,{alarm:d,serverGroup:a,onChartLoaded:e=>g(e.unit)})))))};ar(".SimplePolicyAction .action-input {\n width: 65px;\n}\n.SimplePolicyAction .adjustment-type-input {\n width: 110px;\n}\n");const As=({adjustmentType:e,adjustmentTypeChanged:t,operator:a,scalingAdjustment:n,updateScalingAdjustment:r})=>{const[i,s]=Dt.useState(a),l="Set to"===i?["instances"]:["instances","percent of group"],[o,d]=Dt.useState(e),[p,m]=Dt.useState(n);return Dt.createElement("div",{className:"SimplePolicyAction row"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1 horizontal middle"},Dt.createElement(c,{value:i,stringOptions:["Add","Remove","Set to"],onChange:a=>{return n=a.target.value,s(n),void t(n,e);var n},clearable:!1,inputClassName:"action-input"}),Dt.createElement(u,{value:p,min:1,onChange:e=>{return t=Number.parseInt(e.target.value),m(t),void r(t);var t},inputClassName:"action-input"}),Dt.createElement(c,{value:o,stringOptions:l,onChange:e=>{return a=e.target.value,d(a),void t(i,a);var a},clearable:!1,inputClassName:"adjustment-type-input"})))};ar(".StepPolicyAction .step-policy-row {\n padding: 5px 0;\n border-bottom: 1px solid var(--color-seashell);\n}\n.StepPolicyAction .step-policy-row .action-input {\n width: 65px !important;\n}\n.StepPolicyAction .step-policy-row .adjustment-type-input {\n width: 110px;\n}\n.StepPolicyAction .step-policy-row .remove-step-action-icon {\n margin-left: auto;\n}\n");const Ps=({adjustmentType:e,adjustmentTypeChanged:t,alarm:a,isMin:n,operator:r,step:i,stepAdjustments:s,stepsChanged:l})=>{const o=null==a?void 0:a.comparisonOperator.includes("Equal"),d=["Add","Remove","Set to"],[p,m]=Dt.useState(r),g="Set to"===p?["instances"]:["instances","percent of group"],[h,f]=Dt.useState(e),[v,y]=Dt.useState((null==i?void 0:i.stepAdjustments)||s),b=(e,t)=>{const a=[...v];a[t]=e,y(a),l(a)};return Dt.useEffect((()=>{y(i.stepAdjustments)}),[null==i?void 0:i.stepAdjustments]),Dt.createElement("div",{className:"StepPolicyAction row"},null==v?void 0:v.map(((r,i)=>Dt.createElement("div",{key:`step-adjustment-${i}`,className:"step-policy-row col-md-10 col-md-offset-1 horizontal middle"},Boolean(i)?Dt.createElement("span",{className:"action-input sp-margin-xs-left"},p):Dt.createElement(c,{value:p,stringOptions:d,onChange:a=>{return n=a.target.value,m(n),void t(n,e);var n},clearable:!1,inputClassName:"action-input sp-margin-xs-right"}),Dt.createElement(u,{value:r.scalingAdjustment,min:1,onChange:e=>b({...r,scalingAdjustment:Number.parseInt(e.target.value)},i),inputClassName:"action-input"}),Boolean(i)?Dt.createElement("span",{className:"sp-margin-xs-left"},h):Dt.createElement(c,{value:h,stringOptions:g,onChange:e=>{return a=e.target.value,f(a),void t(p,a);var a},clearable:!1,inputClassName:"adjustment-type-input sp-margin-xs-left"}),Dt.createElement("span",{className:"sp-margin-xs-xaxis"}," ","when ",Dt.createElement("b",null,null==a?void 0:a.metricName)," is"," "),i===v.length-1&&Dt.createElement("span",null,` ${n?"less":"greater"} than${!Boolean(i)||o?" or equal to":""} ${n?r.metricIntervalUpperBound||"":r.metricIntervalLowerBound||""} `),i<v.length-1&&Dt.createElement(Dt.Fragment,null,Dt.createElement("span",{className:"sp-margin-xs-xaxis"},"between"),n?Dt.createElement(u,{value:r.metricIntervalLowerBound,max:r.metricIntervalUpperBound,onChange:e=>b({...r,metricIntervalLowerBound:Number.parseInt(e.target.value)},i),inputClassName:"action-input"}):Dt.createElement("span",null,r.metricIntervalLowerBound),Dt.createElement("span",{className:"sp-margin-xs-xaxis"},"and"),n?Dt.createElement("span",null,r.metricIntervalUpperBound):Dt.createElement(u,{value:r.metricIntervalUpperBound,min:r.metricIntervalLowerBound,onChange:e=>b({...r,metricIntervalUpperBound:Number.parseInt(e.target.value)},i),inputClassName:"action-input"})),Boolean(i)&&Dt.createElement("a",{className:"glyphicon glyphicon-trash clickable sp-margin-xs-xaxis remove-step-action-icon",onClick:()=>(e=>{const t=v.filter(((t,a)=>a!==e));y(t),l(t)})(i)})))),Dt.createElement("div",{className:"row sp-margin-s"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},Dt.createElement("button",{type:"button",className:"btn btn-block btn-sm add-new",onClick:()=>{const e=[...v,{scalingAdjustment:1}];y(e),l(e)}},Dt.createElement("span",{className:"glyphicon glyphicon-plus-sign"}),"Add step"))),Dt.createElement("div",{className:"row sp-margin-s-xaxis"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},Dt.createElement("a",{href:"http://docs.aws.amazon.com/autoscaling/latest/userguide/as-scale-based-on-demand.html#as-scaling-steps",target:"_blank"},Dt.createElement("i",{className:"far fa-file-alt sp-margin-xs-right"}),"Documentation"))))},zs=({app:e,closeModal:t,dismissModal:a,policy:n,serverGroup:r})=>{var i,s,l;const o={closeModal:t,dismissModal:a},[c,d]=Dt.useState({});Dt.useEffect((()=>{const e=ws.buildNewCommand("Step",r,n);d(e)}),[]);const p=(null==(i=n.stepAdjustments)?void 0:i.length)?n.stepAdjustments[0].scalingAdjustment:n.scalingAdjustment,[u,m]=Dt.useState("ExactCapacity"===c.adjustmentType?"Set to":p>0?"Add":"Remove"),g="ExactCapacity"===c.adjustmentType||"ChangeInCapacity"===c.adjustmentType?"instances":"percent of group",h=c.step,f=n.policyARN?"Edit":"Create",v=0===(null==(l=null==(s=null==c?void 0:c.alarm)?void 0:s.comparisonOperator)?void 0:l.indexOf("Greater"))?"max":"min",y=e=>{const t="min"===v?"metricIntervalLowerBound":"metricIntervalUpperBound",a="metricIntervalLowerBound"===t?"metricIntervalUpperBound":"metricIntervalLowerBound",n=e.stepAdjustments;(n||[]).forEach(((e,r)=>{n.length>r+1&&(n[r+1][a]=e[t])})),delete n[n.length-1][t]},b=e=>{const t=Ut(c);t.simplescalingAdjustment=e,d(t)},w=e=>{const t=Ut(c);t.step.stepAdjustments=e,y(t.step),d(t)},E=(e,t)=>{m(e);const a="instances"!==t?"PercentChangeInCapacity":"Set to"===e?"ExactCapacity":"ChangeInCapacity";d({...c,adjustmentType:a})},C=()=>{const e=Ut(c),t=c.step?c.step.estimatedInstanceWarmup:c.simple.cooldown;if(c.step)delete e.step,e.simple=ws.buildSimplePolicy({cooldown:t});else{const a=[{scalingAdjustment:c.simple.scalingAdjustment}];"min"===v?a[0].metricIntervalUpperBound=0:a[0].metricIntervalLowerBound=0;const n={estimatedInstanceWarmup:t,stepAdjustments:a};delete e.simple,e.step=ws.buildStepPolicy(n,e.alarm.threshold,t),y(e.step)}d(e)};return Dt.createElement(Tt,{...o,title:`${f} scaling policy`,application:e,description:`${f} scaling policy for ${r.name}`,initialValues:c,mapValuesToTask:()=>{const t=ws.prepareCommandForUpsert(c,"Remove"===u);return{application:e,job:[{type:t.type||"upsertScalingPolicy",...t}]}},render:()=>{var e,t,a,i,s;return Dt.createElement("div",null,Dt.createElement("h4",{className:"section-heading"},"Conditions"),Dt.createElement("div",{className:"section-body"},Dt.createElement(xs,{alarm:c.alarm,multipleAlarms:Boolean((null==(e=null==n?void 0:n.alarms)?void 0:e.length)>1),serverGroup:r,stepAdjustments:c.step.stepAdjustments,stepsChanged:w,updateAlarm:e=>d({...c,alarm:e})})),Dt.createElement("h4",{className:"section-heading"},"Actions"),Dt.createElement("div",{className:"section-body"},!(null==(t=c.alarm)?void 0:t.metricName)&&Dt.createElement("h4",{className:"text-center"},"Select a metric"),(null==(a=c.alarm)?void 0:a.metricName)&&!h&&Dt.createElement("div",null,Dt.createElement("div",{className:"row"},Dt.createElement("div",{className:"col-md-10 col-md-offset-1"},Dt.createElement("p",null,"This is a simple scaling policy. To declare different actions based on the magnitude of the alarm,",Dt.createElement("b",null,"switch to a",Dt.createElement("a",{className:"clickable sp-margin-xs-l",onClick:C},"step policy"),".")))),Dt.createElement(As,{adjustmentType:g,adjustmentTypeChanged:E,operator:u,scalingAdjustment:null==(i=c.simple)?void 0:i.scalingAdjustment,updateScalingAdjustment:b})),(null==(s=c.alarm)?void 0:s.metricName)&&h&&Dt.createElement(Ps,{adjustmentType:g,adjustmentTypeChanged:E,alarm:c.alarm,isMin:"min"===v,operator:u,step:c.step,stepsChanged:w})),Dt.createElement(ks,{command:c,isInstanceType:"instances"===g,isNew:Boolean(!n.policyARN),operator:u,updateCommand:d}))}})};class Bs extends $t.Component{constructor(e){super(e),this.handleClick=()=>{this.setState({showSelection:!0})},this.typeSelected=e=>{this.setState({typeSelection:e,showSelection:!1,showModal:!0}),"step"===e&&this.createStepPolicy(),"targetTracking"===e&&this.createTargetTrackingPolicy()},this.showModalCallback=()=>{this.setState({showSelection:!1,showModal:!1,typeSelection:null})},this.state={showSelection:!1,showModal:!1,typeSelection:null}}createStepPolicy(){const{serverGroup:e,application:t}=this.props,a={app:t,policy:qn.awsServerGroupTransformer.constructNewStepScalingPolicyTemplate(e),serverGroup:e};b.show(zs,a,{dialogClassName:"wizard-modal modal-lg"})}createTargetTrackingPolicy(){const{serverGroup:e,application:t}=this.props,a={app:t,policy:qn.awsServerGroupTransformer.constructNewTargetTrackingPolicyTemplate(),serverGroup:e};b.show(Es,a,{dialogClassName:"wizard-modal modal-lg"})}render(){const{min:e,max:t}=this.props.serverGroup.capacity;return $t.createElement("div",null,$t.createElement("a",{className:"clickable",onClick:this.handleClick},"Create new scaling policy"),this.state.showSelection&&$t.createElement(Cs,{warnOnMinMaxCapacity:e===t,typeSelectedCallback:this.typeSelected,showCallback:this.showModalCallback}))}}var Ds=Object.defineProperty,$s=Object.getOwnPropertyDescriptor;let Fs=class extends $t.Component{constructor(e){super(e)}static arePoliciesDisabled(e){const t=Ki.normalizeScalingProcesses(e);return e.scalingPolicies.length>0&&t.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","AlarmNotification"].includes(e.name)))}render(){const{app:e,serverGroup:t}=this.props,a=Fs.arePoliciesDisabled(t),{ScalingPolicySummary:n}=Un;return $t.createElement(A,{cacheKey:"Scaling Policies",heading:({chevron:e})=>$t.createElement("h4",{className:"collapsible-heading"},e,$t.createElement("span",null,a&&$t.createElement(Z,{value:"Some scaling processes are disabled that may prevent scaling policies from working"},$t.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scaling Policies"))},a&&$t.createElement("div",{className:"band band-warning"},"Some scaling processes are disabled that may prevent scaling policies from working."),t.scalingPolicies.map((a=>$t.createElement(n,{key:a.policyARN,policy:a,serverGroup:t,application:e}))),$t.createElement(Bs,{serverGroup:t,application:e}))}};Fs=((e,t,a,n)=>{for(var r,i=n>1?void 0:n?$s(t,a):t,s=e.length-1;s>=0;s--)(r=e[s])&&(i=(n?r(t,a,i):r(i))||i);return n&&i&&Ds(t,a,i),i})([ce("aws.serverGroup.ScalingPoliciesDetailsSection")],Fs);class Ms extends $t.Component{constructor(e){super(e),this.toggleScalingProcesses=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scalingProcesses/modifyScalingProcesses.html",controller:"ModifyScalingProcessesCtrl as ctrl",resolve:{serverGroup:()=>t,application:()=>e,processes:()=>this.state.autoScalingProcesses}})))},this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=Ki.normalizeScalingProcesses(t),n=t.scalingPolicies.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","AlarmNotification"].includes(e.name))),r=t.scheduledActions.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","ScheduledAction"].includes(e.name)));return{autoScalingProcesses:a,scalingPoliciesDisabled:n,scheduledActionsDisabled:r}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{autoScalingProcesses:e,scalingPoliciesDisabled:t,scheduledActionsDisabled:a}=this.state;return $t.createElement(A,{cacheKey:"Scaling Processes",heading:({chevron:e})=>$t.createElement("h4",{className:"collapsible-heading"},e,$t.createElement("span",null,t&&$t.createElement(Z,{value:"Some scaling processes are disabled that may prevent scaling policies from working"},$t.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),a&&$t.createElement(Z,{value:"Some scaling processes are disabled that may prevent scheduled actions from working"},$t.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scaling Processes"))},$t.createElement("ul",{className:"scaling-processes"},e.map((e=>$t.createElement("li",{key:e.name},$t.createElement("span",{style:{visibility:e.enabled?"visible":"hidden"},className:"fa fa-check small"}),$t.createElement("span",{className:e.enabled?"":"text-disabled"},e.name," "),$t.createElement(n,{content:e.description,placement:"bottom"}),e.suspensionDate&&$t.createElement("div",{className:"text-disabled small",style:{marginLeft:"35px"}},"Suspended ",D(e.suspensionDate)))))),$t.createElement("a",{className:"clickable",onClick:this.toggleScalingProcesses},"Edit Scaling Processes"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingProcesses/modifyScalingProcesses.html",'<div modal-page class="confirmation-modal">\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Modify Scaling Processes for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-sm-offset-2 col-sm-10">\n <div class="checkbox" ng-repeat="process in command">\n <label>\n <input type="checkbox" ng-model="process.enabled" />\n {{process.name}}\n </label>\n <help-field content="{{process.description}}" placement="right"></help-field>\n </div>\n </div>\n </div>\n </div>\n <task-reason command="command"></task-reason>\n <aws-footer\n action="ctrl.submit()"\n cancel="ctrl.cancel()"\n is-valid="ctrl.isValid()"\n account="serverGroup.account"\n verification="verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class Rs extends $t.Component{render(){const{action:e}=this.props;return $t.createElement("dl",{className:"horizontal-when-filters-collapsed",style:{marginBottom:"20px"}},$t.createElement("dt",null,"Schedule"),$t.createElement("dd",null,e.recurrence),void 0!==e.minSize&&$t.createElement("dt",null,"Min Size"),void 0!==e.minSize&&$t.createElement("dd",null,e.minSize),void 0!==e.maxSize&&$t.createElement("dt",null,"Max Size"),void 0!==e.maxSize&&$t.createElement("dd",null,e.maxSize),void 0!==e.desiredCapacity&&$t.createElement("dt",null,"Desired Size"),void 0!==e.desiredCapacity&&$t.createElement("dd",null,e.desiredCapacity))}}class Ls extends $t.Component{constructor(e){super(e),this.editScheduledActions=()=>{ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/scheduledAction/editScheduledActions.modal.html",controller:"EditScheduledActionsCtrl as ctrl",resolve:{application:()=>this.props.app,serverGroup:()=>this.props.serverGroup}})},this.state=this.getState(e)}getState(e){const{serverGroup:t}=e,a=Ki.normalizeScalingProcesses(t);return{scheduledActionsDisabled:t.scheduledActions.length>0&&a.filter((e=>!e.enabled)).some((e=>["Launch","Terminate","ScheduledAction"].includes(e.name)))}}componentWillReceiveProps(e){this.setState(this.getState(e))}render(){const{serverGroup:e}=this.props,{scheduledActionsDisabled:t}=this.state;return $t.createElement(A,{cacheKey:"Scheduled Actions",heading:({chevron:e})=>$t.createElement("h4",{className:"collapsible-heading"},e,$t.createElement("span",null,t&&$t.createElement(Z,{value:"Some scaling processes are disabled that may prevent scheduled actions from working"},$t.createElement("span",{className:"fa fa-exclamation-circle warning-text"})),"Scheduled Actions"))},e.scheduledActions.map(((e,t)=>$t.createElement(Rs,{key:t,action:e}))),e.scheduledActions.length>0&&$t.createElement("p",null,$t.createElement("strong",null,"Note:")," Schedules are evaluated in UTC."),0===e.scheduledActions.length&&$t.createElement("p",null,"No Scheduled Actions are configured for this server group."),$t.createElement("a",{className:"clickable",onClick:this.editScheduledActions},"Edit Scheduled Actions"))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scheduledAction/editScheduledActions.modal.html",'<div modal-page>\n <task-monitor monitor="taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">Edit Scheduled Actions for {{serverGroup.name}}</h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-12">\n <p>You must specify at least one of: Min Size, Max Size, Desired Capacity</p>\n <p><strong>Note:</strong> CRON expressions are evaluated in UTC.</p>\n <table class="table table-condensed packed">\n <thead>\n <tr>\n <th>Recurrence (CRON)</th>\n <th>Min Size</th>\n <th>Max Size</th>\n <th>Desired Capacity</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="action in command.scheduledActions">\n <td>\n <input\n class="form-control input-sm no-spel"\n type="text"\n ng-model="action.recurrence"\n name="recurrence-{{$index}}"\n required\n />\n \x3c!-- TODO: Add cron-validator when endpoint is fixed --\x3e\n <div class="form-group row slide-in" ng-if="form[\'recurrence-\' + $index].$error.cronExpression">\n <div class="error-message">{{cronErrors[\'action.recurrence.cronExpression\']}}</div>\n </div>\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n min="0"\n max="{{action.maxSize || Infinity}}"\n ng-model="action.minSize"\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n min="{{action.minSize || 0}}"\n ng-model="action.maxSize"\n />\n </td>\n <td>\n <input\n class="form-control input-sm"\n type="number"\n ng-model="action.desiredCapacity"\n min="{{command.minSize || 0}}"\n max="{{command.maxSize || Infinity}}"\n />\n </td>\n <td>\n <a href class="sm-label" ng-click="ctrl.removeScheduledAction($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.addScheduledAction()">\n <span class="glyphicon glyphicon-plus-sign"></span> Add new Scheduled Action\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>\n <button type="submit" class="btn btn-primary" ng-disabled="form.$invalid" ng-click="ctrl.submit()">Submit</button>\n </div>\n </form>\n</div>\n')}]);class Os extends $t.Component{constructor(e){super(e),this.updateSecurityGroups=()=>{const{app:e,serverGroup:t}=this.props;et(t,e).then((a=>a&&ft.modalService.open({templateUrl:"amazon/src/serverGroup/details/securityGroup/editSecurityGroups.modal.html",controller:"EditSecurityGroupsCtrl as $ctrl",resolve:{application:()=>e,serverGroup:()=>t,securityGroups:()=>this.state.securityGroups}})))},this.state={securityGroups:this.getSecurityGroups(e)}}tryFindingSecurityGroupInIndex(e,t,a,n){try{return bi.resolveIndexedSecurityGroup(e,{account:t,region:a},n)}catch(e){return}}getSecurityGroups(e){let t;const{app:a,serverGroup:n}=e;return n.securityGroups&&n.securityGroups.length&&(t=aa(n.securityGroups).map((e=>da(a.securityGroups.data,{accountName:n.account,region:n.region,id:e})||da(a.securityGroups.data,{accountName:n.account,region:n.region,name:e})||this.tryFindingSecurityGroupInIndex(a.securityGroupsIndex,n.account,n.region,e)||{id:e,name:e})).compact().value()),t}componentWillReceiveProps(e){this.setState({securityGroups:this.getSecurityGroups(e)})}render(){const{serverGroup:e}=this.props,{securityGroups:t}=this.state;return $t.createElement(A,{heading:U.get("Firewalls")},$t.createElement("ul",null,Wt(t,"name").map((t=>$t.createElement("li",{key:t.name},$t.createElement(Ha,{to:"^.firewallDetails",params:{name:t.name,accountId:t.accountName,region:e.region,vpcId:e.vpcId,provider:e.type}},$t.createElement("a",null,t.name," (",t.id,")")))))),e.vpcId&&$t.createElement("a",{className:"clickable",onClick:this.updateSecurityGroups},"Edit ",U.get("Firewalls")))}}window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/securityGroup/editSecurityGroups.modal.html",'<div modal-page>\n <task-monitor monitor="$ctrl.taskMonitor"></task-monitor>\n <form role="form" name="form">\n <modal-close dismiss="$dismiss()"></modal-close>\n <div class="modal-header">\n <h4 class="modal-title">\n Edit <firewall-label label="Firewalls"></firewall-label> for {{$ctrl.serverGroup.name}}\n </h4>\n </div>\n <div class="modal-body container-fluid form-horizontal">\n <div class="form-group">\n <div class="col-md-10 col-md-offset-1">\n <ui-select\n multiple\n ng-model="$ctrl.command.securityGroups"\n uis-open-close="$ctrl.resetCurrentItems()"\n class="form-control input-sm"\n >\n <ui-select-match>{{$item.name}} ({{$item.id}})</ui-select-match>\n <ui-select-choices\n repeat="securityGroup as securityGroup in $ctrl.availableSecurityGroups | filter: $select.search | limitTo: $ctrl.infiniteScroll.currentItems"\n infinite-scroll="$ctrl.addMoreItems()"\n infinite-scroll-distance="4"\n >\n <span ng-bind-html="securityGroup.name | highlight: $select.search"></span>\n (<span ng-bind-html="securityGroup.id | highlight: $select.search"></span>)\n </ui-select-choices>\n </ui-select>\n </div>\n </div>\n </div>\n <aws-footer\n action="$ctrl.submit()"\n cancel="$ctrl.cancel()"\n is-valid="$ctrl.isValid()"\n account="$ctrl.serverGroup.account"\n verification="$ctrl.state.verification"\n ></aws-footer>\n </form>\n</div>\n')}]);class Us extends $t.Component{render(){const{serverGroup:e}=this.props;return $t.createElement(A,{heading:"Tags"},0===e.asg.tags.length&&$t.createElement("div",null,"No tags associated with this server group"),e.asg.tags.length>0&&$t.createElement("dl",null,Wt(e.asg.tags,"key").map((e=>[$t.createElement("dt",{key:e.key},e.key),$t.createElement("dd",{key:e.value},e.value)]))))}}class Vs{static listKeyPairs(){return z("/keyPairs").useCache().get().then((e=>e.sort(((e,t)=>e.keyName.localeCompare(t.keyName)))))}}class qs{constructor(e,t,a,n,r){this.securityGroupReader=e,this.awsInstanceTypeService=t,this.cacheInitializer=a,this.loadBalancerReader=n,this.serverGroupCommandRegistry=r,this.enabledMetrics=["GroupMinSize","GroupMaxSize","GroupDesiredCapacity","GroupInServiceInstances","GroupPendingInstances","GroupStandbyInstances","GroupTerminatingInstances","GroupTotalInstances"],this.healthCheckTypes=["EC2","ELB"],this.terminationPolicies=["OldestInstance","NewestInstance","OldestLaunchConfiguration","ClosestToNextInstanceHour","Default"]}configureUpdateCommand(e){e.backingData={enabledMetrics:ma(this.enabledMetrics),healthCheckTypes:ma(this.healthCheckTypes),terminationPolicies:ma(this.terminationPolicies)}}configureCommand(e,t){return this.applyOverrides("beforeConfiguration",t),t.toggleSuspendedProcess=(e,t)=>{e.suspendedProcesses=e.suspendedProcesses||[];const a=e.suspendedProcesses.indexOf(t);e.suspendedProcesses=-1===a?e.suspendedProcesses.concat(t):e.suspendedProcesses.filter((e=>e!==t))},t.processIsSuspended=(e,t)=>e.suspendedProcesses.includes(t),t.onStrategyChange=(e,t)=>{var a;(null==(a=fn.serverGroups)?void 0:a.enableLaunchTemplates)&&(e.setLaunchTemplate="rollingpush"===t.key||void 0),""!==t.key&&"custom"!==t.key&&(e.suspendedProcesses=(e.suspendedProcesses||[]).filter((e=>"AddToLoadBalancer"!==e)))},t.getBlockDeviceMappingsSource=e=>e.copySourceCustomBlockDeviceMappings?"source":e.useAmiBlockDeviceMappings?"ami":"default",t.selectBlockDeviceMappingsSource=(e,t)=>{"source"===t?(e.copySourceCustomBlockDeviceMappings=!0,e.useAmiBlockDeviceMappings=!1):"ami"===t?(e.copySourceCustomBlockDeviceMappings=!1,e.useAmiBlockDeviceMappings=!0):(e.copySourceCustomBlockDeviceMappings=!1,e.useAmiBlockDeviceMappings=!1)},t.regionIsDeprecated=e=>pa(e,"backingData.filtered.regions")&&e.backingData.filtered.regions.some((t=>t.name===e.region&&t.deprecated)),qa.all([o.getCredentialsKeyedByAccount("aws"),this.securityGroupReader.getAllSecurityGroups(),g.listSubnets(),o.getPreferredZonesByAccount("aws"),Vs.listKeyPairs(),this.awsInstanceTypeService.getAllTypesByRegion(),qa.when(ma(this.enabledMetrics)),qa.when(ma(this.healthCheckTypes)),qa.when(ma(this.terminationPolicies))]).then((([a,n,r,i,s,l,o,c,d])=>{var p,u;const m={credentialsKeyedByAccount:a,securityGroups:n,subnets:r,preferredZones:i,keyPairs:s,instanceTypes:l,enabledMetrics:o,healthCheckTypes:c,terminationPolicies:d};let g=qa.when();if(m.accounts=ga(m.credentialsKeyedByAccount),m.filtered={},m.scalingProcesses=Ki.listProcesses(),m.appLoadBalancers=e.getDataSource("loadBalancers").data,m.managedResources=null==(u=null==(p=e.getDataSource("managedResources"))?void 0:p.data)?void 0:u.resources,t.backingData=m,this.configureVpcId(t),m.filtered.securityGroups=this.getRegionalSecurityGroups(t),t.viewState.disableImageSelection&&this.configureInstanceTypes(t),t.securityGroups&&t.securityGroups.length){const e=ra(this.getRegionalSecurityGroups(t),"id");ca(t.securityGroups,e).length<t.securityGroups.length&&(g=this.refreshSecurityGroups(t,!0))}return g.then((()=>{this.applyOverrides("afterConfiguration",t),this.attachEventHandlers(t)}))}))}applyOverrides(e,t){this.serverGroupCommandRegistry.getCommandOverrides("aws").forEach((a=>{a[e]&&a[e](t)}))}configureKeyPairs(e){const t={dirty:{}};if(e.credentials&&e.region){const a=Qt(e.backingData.credentialsKeyedByAccount,(t=>t.defaultKeyPair&&e.keyPair&&0===e.keyPair.indexOf(t.defaultKeyPair.replace("{{region}}","")))),n=aa(e.backingData.keyPairs).filter({account:e.credentials,region:e.region}).map("keyName").value();if(e.keyPair&&n.length&&!n.includes(e.keyPair)){const r=e.backingData.credentialsKeyedByAccount[e.credentials]||{regions:[],defaultKeyPair:null};if(r.defaultKeyPair){const i=r.defaultKeyPair.replace("{{region}}",e.region);a&&n.includes(i)?e.keyPair=i:(e.keyPair=null,t.dirty.keyPair=!0)}else e.keyPair=null,t.dirty.keyPair=!0}e.backingData.filtered.keyPairs=n}else e.backingData.filtered.keyPairs=[];return t}configureInstanceTypes(e){const t={dirty:{}};if(e.region&&(e.virtualizationType||e.viewState.disableImageSelection)){let a=this.awsInstanceTypeService.getAvailableTypesForRegions(e.backingData.instanceTypes,[e.region]);e.virtualizationType&&(a=this.awsInstanceTypeService.filterInstanceTypes(a,e.virtualizationType,!!e.vpcId)),e.instanceType&&!a.includes(e.instanceType)&&(t.dirty.instanceType=e.instanceType,e.instanceType=null),e.backingData.filtered.instanceTypes=a}else e.backingData.filtered.instanceTypes=[];return oa(e.viewState.dirty,t.dirty),t}configureImages(e){const t={dirty:{}};return e.amiName||(e.virtualizationType=null),e.viewState.disableImageSelection||e.amiName&&!e.region&&(t.dirty.amiName=!0,e.amiName=null),t}configureAvailabilityZones(e){e.backingData.filtered.availabilityZones=da(e.backingData.credentialsKeyedByAccount[e.credentials].regions,{name:e.region}).availabilityZones}configureSubnetPurposes(e){const t={dirty:{}},a=e.backingData.filtered;return null===e.region||(a.subnetPurposes=aa(e.backingData.subnets).filter({account:e.credentials,region:e.region}).reject({target:"elb"}).reject({purpose:null}).uniqBy("purpose").value(),aa(a.subnetPurposes).some({purpose:e.subnetType}).value()||(e.subnetType=null,t.dirty.subnetType=!0)),t}getRegionalSecurityGroups(e){const t=e.backingData.securityGroups[e.credentials]||{aws:{}};return aa(t.aws[e.region]).filter({vpcId:e.vpcId||null}).sortBy("name").value()}configureSecurityGroupOptions(e){const t={dirty:{}},a=e.backingData.filtered.securityGroups,n=this.getRegionalSecurityGroups(e),r="string"==typeof e.securityGroups&&e.securityGroups.includes("${");if(a&&e.securityGroups&&!r){const r=e.securityGroups.map((e=>{const t=da(a,{id:e});return t?t.name:e})),i=e.securityGroups.map((e=>{const t=da(a,{id:e})||da(a,{name:e});return t?t.name:null})).map((e=>da(n,{name:e}))).filter((e=>e)),s=ra(i,"name"),l=ha(r,s);e.securityGroups=ra(i,"id"),l.length&&(t.dirty.securityGroups=l)}return e.backingData.filtered.securityGroups=n.sort(((e,t)=>e.name.localeCompare(t.name))),t}refreshSecurityGroups(e,t){return this.cacheInitializer.refreshCache("securityGroups").then((()=>this.securityGroupReader.getAllSecurityGroups().then((a=>{e.backingData.securityGroups=a,t||this.configureSecurityGroupOptions(e)}))))}getLoadBalancerMap(e){if(e.backingData.loadBalancers)return aa(e.backingData.loadBalancers).map("accounts").flattenDeep().filter({name:e.credentials}).map("regions").flattenDeep().filter({name:e.region}).map("loadBalancers").flattenDeep().value();return(e.backingData.appLoadBalancers||[]).filter((t=>t.region===e.region&&t.account===e.credentials))}getLoadBalancerNames(e){return this.getLoadBalancerMap(e).filter((t=>(!t.loadBalancerType||"classic"===t.loadBalancerType)&&t.vpcId===e.vpcId)).map((e=>e.name)).sort()}getVpcLoadBalancerNames(e){return this.getLoadBalancerMap(e).filter((e=>(!e.loadBalancerType||"classic"===e.loadBalancerType)&&e.vpcId)).map((e=>e.name)).sort()}getTargetGroupNames(e){const t=this.getLoadBalancerMap(e).filter((e=>"classic"!==e.loadBalancerType));return Vt(t.map((e=>e.targetGroups.filter((e=>"instance"===e.targetType))))).map((e=>e.name)).sort()}getValidMatches(e,t){const a=t.filter((e=>e.includes("${"))),n=ca(e,t),[r,i]=na(t,(e=>n.includes(e)||a.includes(e)));return{valid:r,invalid:i,spel:a}}configureLoadBalancerOptions(e){const t={dirty:{}},a=(e.loadBalancers||[]).concat(e.vpcLoadBalancers||[]),n=e.targetGroups||[],r=this.getLoadBalancerNames(e),i=this.getVpcLoadBalancerNames(e),s=this.getTargetGroupNames(e);if(a&&e.loadBalancers){const n=e.vpcId?r:r.concat(i),{valid:s,invalid:l,spel:o}=this.getValidMatches(n,a);e.loadBalancers=ca(r.concat(o),s),e.vpcId?delete e.vpcLoadBalancers:e.vpcLoadBalancers=ca(i,s),l.length&&(t.dirty.loadBalancers=l),e.viewState.spelLoadBalancers=o||[]}if(n&&e.targetGroups&&!n.includes("${")){const{valid:a,invalid:r,spel:i}=this.getValidMatches(s,n);e.targetGroups=a,r.length&&(t.dirty.targetGroups=r),e.viewState.spelTargetGroups=i||[]}return e.backingData.filtered.loadBalancers=r,e.backingData.filtered.vpcLoadBalancers=i,e.backingData.filtered.targetGroups=s,t}refreshLoadBalancers(e,t){return this.loadBalancerReader.listLoadBalancers("aws").then((a=>{e.backingData.loadBalancers=a,t||this.configureLoadBalancerOptions(e)}))}configureVpcId(e){const t={dirty:{}};if(e.subnetType){const t=da(e.backingData.subnets,{purpose:e.subnetType,account:e.credentials,region:e.region});e.vpcId=t?t.vpcId:null}else e.vpcId=null,t.dirty.vpcId=!0;return oa(t.dirty,this.configureInstanceTypes(e).dirty),t}attachEventHandlers(e){e.usePreferredZonesChanged=e=>{const t=e.availabilityZones?e.availabilityZones.length:0,a={dirty:{}},n=e.backingData.preferredZones[e.credentials];if(n&&n[e.region]&&e.viewState.usePreferredZones)e.availabilityZones=Ut(n[e.region].sort());else{e.availabilityZones=ca(e.availabilityZones,e.backingData.filtered.availabilityZones);t!==(e.availabilityZones?e.availabilityZones.length:0)&&(a.dirty.availabilityZones=!0)}return a},e.subnetChanged=e=>{const t=this.configureVpcId(e);return oa(t.dirty,this.configureSecurityGroupOptions(e).dirty),oa(t.dirty,this.configureLoadBalancerOptions(e).dirty),e.viewState.dirty=e.viewState.dirty||{},oa(e.viewState.dirty,t.dirty),t},e.regionChanged=e=>{const t={dirty:{}},a=e.backingData.filtered;return oa(t.dirty,this.configureSubnetPurposes(e).dirty),e.region?(oa(t.dirty,e.subnetChanged(e).dirty),oa(t.dirty,this.configureInstanceTypes(e).dirty),this.configureAvailabilityZones(e),oa(t.dirty,e.usePreferredZonesChanged(e).dirty),oa(t.dirty,this.configureImages(e).dirty),oa(t.dirty,this.configureKeyPairs(e).dirty)):a.regionalAvailabilityZones=null,xt(e),t},e.clusterChanged=e=>{e.moniker=Ee.getMoniker(e.application,e.stack,e.freeFormDetails),xt(e)},e.credentialsChanged=e=>{const t={dirty:{}},a=e.backingData;if(e.credentials){const n=a.credentialsKeyedByAccount[e.credentials]||{regions:[],defaultKeyPair:null};a.filtered.regions=n.regions,Qt(a.filtered.regions,{name:e.region})?oa(t.dirty,e.regionChanged(e).dirty):(e.region=null,t.dirty.region=!0)}else e.region=null;return xt(e),t},e.imageChanged=e=>this.configureInstanceTypes(e),e.instanceTypeChanged=e=>{e.ebsOptimized=this.awsInstanceTypeService.isEbsOptimized(e.instanceType)},this.applyOverrides("attachEventHandlers",e)}}qs.$inject=["securityGroupReader","awsInstanceTypeService","cacheInitializer","loadBalancerReader","serverGroupCommandRegistry"];const js="spinnaker.amazon.serverGroup.configure.service";t("spinnaker.amazon.serverGroup.configure.service",[Te,"spinnaker.amazon.instanceType.service",Ie,Je,At]).service("awsServerGroupConfigurationService",qs);e.module("spinnaker.amazon.serverGroupCommandBuilder.service",[Pt,"spinnaker.amazon.serverGroup.configure.service"]).factory("awsServerGroupCommandBuilder",["$q","instanceTypeService","awsServerGroupConfigurationService",function(t,a,n){function i(e,a){a=a||{};const n=o.getCredentialsKeyedByAccount("aws"),r=a.account||e.defaultCredentials.aws||fn.defaults.account,i=a.region||e.defaultRegions.aws||fn.defaults.region,l=a.subnet||fn.defaults.subnetType||"",c=o.getAvailabilityZonesForAccountAndRegion("aws",r,i);return t.all([c,n]).then((function([t,n]){const o=n[r],c=o?o.defaultKeyPair:null,d=Mt.get(e,"attributes.providerSettings.aws",{});let p=fn.defaults.iamRole||"BaseIAMRole";p=p.replace("{{application}}",e.name);const u=d.useAmiBlockDeviceMappings||!1,m={application:e.name,credentials:r,region:i,strategy:"",capacity:{min:1,max:1,desired:1},targetHealthyDeployPercentage:100,cooldown:10,enabledMetrics:[],healthCheckType:"EC2",healthCheckGracePeriod:600,instanceMonitoring:!1,ebsOptimized:!1,selectedProvider:"aws",iamRole:p,terminationPolicies:["Default"],vpcId:null,subnetType:l,availabilityZones:t,keyPair:c,suspendedProcesses:[],securityGroups:[],stack:"",freeFormDetails:"",spotPrice:"",tags:{},useAmiBlockDeviceMappings:u,copySourceCustomBlockDeviceMappings:!1,viewState:{instanceProfile:"custom",useAllImageSelection:!1,useSimpleCapacity:!0,usePreferredZones:!0,mode:a.mode||"create",disableStrategySelection:!0,dirty:{},submitButtonLabel:s(a.mode||"create")}};if(e.attributes&&e.attributes.platformHealthOnlyShowOverride&&e.attributes.platformHealthOnly&&(m.interestingHealthProviderNames=["Amazon"]),"test"===r&&fn.serverGroups&&fn.serverGroups.enableIPv6&&(m.associateIPv6Address=!0),fn.serverGroups&&fn.serverGroups.enableIMDSv2){const t=fn.serverGroups.defaultIMDSv2AppAgeLimit,a=e.attributes&&e.attributes.createTs;m.requireIMDSv2=!!(t&&a&&Number(a)>t)}return m}))}function s(e){switch(e){case"createPipeline":return"Add";case"editPipeline":return"Done";case"clone":return"Clone";default:return"Create"}}return{buildNewServerGroupCommand:i,buildServerGroupCommandFromExisting:function(n,i,l="clone"){const c=o.getPreferredZonesByAccount("aws"),d=g.listSubnets(),p=Ee.parseServerGroupName(i.asg.autoScalingGroupName),u=i.launchConfig?i.launchConfig.instanceType:i.launchTemplate?i.launchTemplate.launchTemplateData.instanceType:null,m=a.getCategoryForInstanceType("aws",u);return t.all([c,d,m]).then((function([t,a,o]){const c=i.asg.availabilityZones.sort();let d=!1;const u=t[i.account];if(u){const e=u[i.region].sort();d=c.join(",")===e.join(",")}const m=["Launch","Terminate","AddToLoadBalancer"],g=Mt.get(n,"attributes.providerSettings.aws",{}).useAmiBlockDeviceMappings||!1,h={},f=["spinnaker:application","spinnaker:stack","spinnaker:details"];i.asg.tags&&i.asg.tags.filter((e=>!f.includes(e.key))).forEach((e=>{h[e.key]=e.value}));const v={application:n.name,strategy:"",stack:p.stack,freeFormDetails:p.freeFormDetails,credentials:i.account,cooldown:i.asg.defaultCooldown,enabledMetrics:Mt.get(i,"asg.enabledMetrics",[]).map((e=>e.metric)),healthCheckGracePeriod:i.asg.healthCheckGracePeriod,healthCheckType:i.asg.healthCheckType,terminationPolicies:i.asg.terminationPolicies,loadBalancers:i.asg.loadBalancerNames,region:i.region,useSourceCapacity:!1,capacity:{min:i.asg.minSize,max:i.asg.maxSize,desired:i.asg.desiredCapacity},targetHealthyDeployPercentage:100,availabilityZones:c,selectedProvider:"aws",source:{account:i.account,region:i.region,asgName:i.asg.autoScalingGroupName},suspendedProcesses:(i.asg.suspendedProcesses||[]).map((e=>e.processName)).filter((e=>!m.includes(e))),tags:Object.assign({},i.tags,h),targetGroups:i.targetGroups,useAmiBlockDeviceMappings:g,copySourceCustomBlockDeviceMappings:"clone"===l,viewState:{instanceProfile:o,useAllImageSelection:!1,useSimpleCapacity:i.asg.minSize===i.asg.maxSize,usePreferredZones:d,mode:l,submitButtonLabel:s(l),isNew:!1,dirty:{}}};if(n.attributes&&n.attributes.platformHealthOnlyShowOverride&&n.attributes.platformHealthOnly&&(v.interestingHealthProviderNames=["Amazon"]),"editPipeline"===l){v.useSourceCapacity=!0,v.viewState.useSimpleCapacity=!1,v.strategy="redblack";const e=r.getStrategy("redblack");e.initializationMethod&&e.initializationMethod(v),v.suspendedProcesses=[]}const y=i.asg.vpczoneIdentifier;if(""!==y){const e=y.split(",")[0],t=Mt.chain(a).find({id:e}).value();v.subnetType=t.purpose,v.vpcId=t.vpcId}else v.subnetType="",v.vpcId=null;if(i.launchConfig&&(e.extend(v,{instanceType:i.launchConfig.instanceType,iamRole:i.launchConfig.iamInstanceProfile,keyPair:i.launchConfig.keyName,associatePublicIpAddress:i.launchConfig.associatePublicIpAddress,ramdiskId:i.launchConfig.ramdiskId,instanceMonitoring:i.launchConfig.instanceMonitoring.enabled,ebsOptimized:i.launchConfig.ebsOptimized,spotPrice:i.launchConfig.spotPrice}),i.launchConfig.userData&&(v.base64UserData=i.launchConfig.userData),v.viewState.imageId=i.launchConfig.imageId),i.launchTemplate){const{launchTemplateData:t}=i.launchTemplate,a=t.instanceMarketOptions&&t.instanceMarketOptions.spotOptions&&t.instanceMarketOptions.spotOptions.maxPrice,{ipv6AddressCount:n}=t.networkInterfaces&&t.networkInterfaces.length&&t.networkInterfaces[0],r=fn.serverGroups,s=i.accountDetails&&"test"===i.accountDetails.environment,l=r&&r.enableIPv6&&r.setIPv6InTest&&s;e.extend(v,{instanceType:t.instanceType,iamRole:t.iamInstanceProfile.name,keyPair:t.keyName,associateIPv6Address:l||Boolean(n),ramdiskId:t.ramdiskId,instanceMonitoring:t.monitoring.enabled,ebsOptimized:t.ebsOptimized,spotPrice:a||void 0,requireIMDSv2:Boolean(t.metadataOptions&&"required"===t.metadataOptions.httpsTokens),unlimitedCpuCredits:t.creditSpecification?"unlimited"===t.creditSpecification.cpuCredits:void 0}),v.viewState.imageId=t.imageId}if("clone"===l&&i.image&&i.image.name&&(v.amiName=i.image.name),i.launchConfig&&i.launchConfig.securityGroups.length&&(v.securityGroups=i.launchConfig.securityGroups),i.launchTemplate&&i.launchTemplate.launchTemplateData.securityGroups.length&&(v.securityGroups=i.launchTemplate.launchTemplateData.securityGroups),i.launchTemplate&&i.launchTemplate.launchTemplateData.networkInterfaces){const e=i.launchTemplate.launchTemplateData.networkInterfaces.find((e=>0===e.deviceIndex))||{};v.securityGroups=e.groups}return v}))},buildNewServerGroupCommandForPipeline:function(){return t.when({viewState:{requiresTemplateSelection:!0}})},buildServerGroupCommandFromPipeline:function(n,r){const s=Mt.cloneDeep(r),l=Object.keys(s.availabilityZones)[0],o=a.getCategoryForInstanceType("aws",s.instanceType),c={account:s.account,region:l};return t.all([i(n,c),o]).then((function([t,a]){const n=s.availabilityZones[l].join(",")===t.availabilityZones.join(","),r={instanceProfile:a,disableImageSelection:!0,useSimpleCapacity:s.capacity.min===s.capacity.max&&!0!==s.useSourceCapacity,usePreferredZones:n,mode:"editPipeline",submitButtonLabel:"Done",templatingEnabled:!0,existingPipelineCluster:!0,dirty:{}},i={region:l,credentials:s.account,availabilityZones:s.availabilityZones[l],iamRole:s.iamRole,viewState:r};return s.strategy=s.strategy||"",e.extend({},t,s,i)}))},buildUpdateServerGroupCommand:function(t){const a={type:"modifyAsg",asgs:[{asgName:t.name,region:t.region}],cooldown:t.asg.defaultCooldown,enabledMetrics:Mt.get(t,"asg.enabledMetrics",[]).map((e=>e.metric)),healthCheckGracePeriod:t.asg.healthCheckGracePeriod,healthCheckType:t.asg.healthCheckType,terminationPolicies:e.copy(t.asg.terminationPolicies),credentials:t.account,capacityRebalance:t.asg.capacityRebalance};return n.configureUpdateCommand(a),a}}}]);t("spinnaker.amazon.serverGroup.editAsgAdvancedSettings.modal.controller",["spinnaker.amazon.serverGroupCommandBuilder.service"]).controller("EditAsgAdvancedSettingsCtrl",["$scope","$uibModalInstance","application","serverGroup","awsServerGroupCommandBuilder",function(e,t,a,n,r){e.command=r.buildUpdateServerGroupCommand(n),e.serverGroup=n,e.taskMonitor=new v({application:a,title:"Update Advanced Settings for "+n.name,modalInstance:t,onTaskComplete:()=>a.serverGroups.refresh()}),this.submit=()=>{const t=[e.command];e.taskMonitor.submit((function(){return L.executeTask({job:t,application:a,description:"Update Advanced Settings for "+n.name})}))},this.cancel=t.dismiss}]);t("spinnaker.amazon.serverGroup.details.rollback.controller",[zt]).controller("awsRollbackServerGroupCtrl",["$scope","$uibModalInstance","serverGroupWriter","application","serverGroup","previousServerGroup","disabledServerGroups","allServerGroups",function(e,t,a,n,r,i,s,l){e.serverGroup=r,e.disabledServerGroups=s.sort(((e,t)=>t.name.localeCompare(e.name))),e.allServerGroups=l.sort(((e,t)=>t.name.localeCompare(e.name))),e.verification={};const o=r.capacity.desired;let c,d="EXPLICIT";if(0===l.length&&r.entityTags){const t=Kt(r,"entityTags.creationMetadata.value.previousServerGroup");if(t){d="PREVIOUS_IMAGE",e.previousServerGroup={name:t.name,imageName:t.imageName},t.imageId&&t.imageId!==t.imageName&&(e.previousServerGroup.imageId=t.imageId);const a=Kt(t,"buildInfo.jenkins.number");a&&(e.previousServerGroup.buildNumber=a)}}c=o<10?100:o<20?90:95,e.command={rollbackType:d,rollbackContext:{rollbackServerGroupName:r.name,restoreServerGroupName:i?i.name:void 0,targetHealthyRollbackPercentage:c,delayBeforeDisableSeconds:0}},e.minHealthy=function(e){return Math.ceil(o*e/100)},n&&n.attributes&&(n.attributes.platformHealthOnlyShowOverride&&n.attributes.platformHealthOnly&&(e.command.interestingHealthProviderNames=["Amazon"]),e.command.platformHealthOnlyShowOverride=n.attributes.platformHealthOnlyShowOverride),this.isValid=function(){const t=e.command;return!!e.verification.verified&&("PREVIOUS_IMAGE"===d||void 0!==t.rollbackContext.restoreServerGroupName)},e.taskMonitor=new v({application:n,title:"Rollback "+r.name,modalInstance:t}),this.rollback=function(){if(!this.isValid())return;e.taskMonitor.submit((function(){return a.rollbackServerGroup(r,n,e.command)}))},this.cancel=function(){t.dismiss()},this.label=function(e){return e?e.buildInfo&&e.buildInfo.jenkins&&e.buildInfo.jenkins.number?e.name+" (build #"+e.buildInfo.jenkins.number+")":e.name:""},this.group=function(e){return e.isDisabled?"Disabled Server Groups":"Enabled Server Groups"}}]);class Hs{static upsertScalingPolicy(e,t){return t.type=t.type||"upsertScalingPolicy",L.executeTask({application:e,description:"Upsert scaling policy "+(t.name||t.serverGroupName),job:[t]})}static deleteScalingPolicy(e,t,a){return L.executeTask({application:e,description:"Delete scaling policy "+a.policyName,job:[{type:"deleteScalingPolicy",cloudProvider:"aws",credentials:t.account,region:t.region,policyName:a.policyName,serverGroupName:t.name}]})}}const Ws={bindings:{policy:"=",serverGroup:"="},templateUrl:"amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html",controller(){this.$onInit=()=>{this.alarm=this.policy.alarms[0];let e=!1;this.policy.cooldown&&(e=!0),this.policy.stepAdjustments&&this.policy.stepAdjustments.length&&(e="decrease"!==this.policy.stepAdjustments[0].operator),this.showWait=e}}},Zs="spinnaker.amazon.serverGroup.details.scalingPolicy.popover.component";t(Zs,["spinnaker.amazon.serverGroup.details.scalingPolicy.metricAlarmChart.component"]).component("awsScalingPolicyPopover",Ws),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyPopover.component.html",'<div>\n <dl class="dl-horizontal dl-narrow">\n <dt>Whenever</dt>\n <dd>\n {{ $ctrl.alarm.statistic }} of {{ $ctrl.alarm.metricName }} is\n <span ng-bind-html="$ctrl.alarm.comparator"></span> {{ $ctrl.alarm.threshold }}\n </dd>\n <dt>for at least</dt>\n <dd>{{ $ctrl.alarm.evaluationPeriods }} consecutive periods of {{ $ctrl.alarm.period }} seconds</dd>\n <dt>then</dt>\n <dd ng-if="$ctrl.policy.stepAdjustments.length">\n <div ng-repeat="stepAdjustment in $ctrl.policy.stepAdjustments">\n <span ng-if="$ctrl.policy.stepAdjustments.length > 1">\n if {{ $ctrl.alarm.metricName }}\n <span ng-if="$ctrl.alarm.comparisonOperator.indexOf(\'Greater\') === 0">\n <span\n ng-if="\n stepAdjustment.metricIntervalUpperBound !== undefined &&\n stepAdjustment.metricIntervalLowerBound !== undefined\n "\n >\n is between\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n and\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span>\n <span ng-if="stepAdjustment.metricIntervalUpperBound === undefined">\n is greater than {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n </span>\n </span>\n\n <span ng-if="$ctrl.alarm.comparisonOperator.indexOf(\'Less\') === 0">\n <span\n ng-if="\n stepAdjustment.metricIntervalUpperBound !== undefined &&\n stepAdjustment.metricIntervalLowerBound !== undefined\n "\n >\n is between\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalLowerBound }}\n and\n {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span>\n <span ng-if="stepAdjustment.metricIntervalLowerBound === undefined">\n is less than {{ $ctrl.alarm.threshold + stepAdjustment.metricIntervalUpperBound }}\n </span> </span\n >,\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ExactCapacity\'">\n set capacity to {{ stepAdjustment.scalingAdjustment }} instance<span\n ng-if="stepAdjustment.scalingAdjustment > 1"\n >s</span\n >\n </span>\n <span\n ng-if="\n $ctrl.policy.adjustmentType === \'ChangeInCapacity\' ||\n $ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'\n "\n >\n {{ stepAdjustment.operator }} capacity\n <span ng-if="$ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'">\n by {{ stepAdjustment.absAdjustment }}%\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ChangeInCapacity\'">\n by {{ stepAdjustment.absAdjustment }} instance<span ng-if="stepAdjustment.absAdjustment > 1">s</span>\n </span>\n </span>\n </div>\n </dd>\n <dd ng-if="!$ctrl.policy.stepAdjustments.length">\n <span ng-if="$ctrl.policy.adjustmentType === \'ExactCapacity\'">\n set capacity to {{ $ctrl.policy.scalingAdjustment }} instance<span ng-if="$ctrl.policy.scalingAdjustment > 1"\n >s</span\n >\n </span>\n <span\n ng-if="\n $ctrl.policy.adjustmentType === \'ChangeInCapacity\' ||\n $ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'\n "\n >\n {{ $ctrl.policy.operator }} capacity\n <span ng-if="$ctrl.policy.adjustmentType === \'PercentChangeInCapacity\'">\n by {{ $ctrl.policy.absAdjustment }}%\n </span>\n <span ng-if="$ctrl.policy.adjustmentType === \'ChangeInCapacity\'">\n by {{ $ctrl.policy.absAdjustment }} instance<span ng-if="$ctrl.policy.absAdjustment > 1">s</span>\n </span>\n </span>\n </dd>\n <dt ng-if="$ctrl.policy.minAdjustmentMagnitude">in</dt>\n <dd ng-if="$ctrl.policy.minAdjustmentMagnitude">\n increments of at least {{ $ctrl.policy.minAdjustmentMagnitude }} instance<span\n ng-if="$ctrl.policy.minAdjustmentMagnitude > 1"\n >s</span\n >\n </dd>\n <dt ng-if="$ctrl.showWait">wait</dt>\n <dd ng-if="$ctrl.policy.cooldown">{{ $ctrl.policy.cooldown }} seconds before allowing another scaling activity.</dd>\n <dd ng-if="$ctrl.showWait && $ctrl.policy.estimatedInstanceWarmup">\n {{ $ctrl.policy.estimatedInstanceWarmup }} seconds to warm up after each step.\n </dd>\n </dl>\n\n <metric-alarm-chart alarm="$ctrl.policy.alarms[0]" server-group="$ctrl.serverGroup"></metric-alarm-chart>\n</div>\n')}]);ar("scaling-policy-summary .alarm-name {\n word-break: break-all;\n}\nscaling-policy-summary .actions {\n font-size: 85%;\n margin: 0 0 15px 0;\n border-bottom: 1px solid var(--color-alto);\n}\nscaling-policy-summary .actions .btn-left {\n padding-left: 0;\n border-left-width: 0;\n}\n");t("spinnaker.amazon.serverGroup.details.scalingPolicy.alarmBasedSummary.component",[Zs]).component("alarmBasedSummary",{bindings:{policy:"=",serverGroup:"=",application:"="},templateUrl:"amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html",controller:["$uibModal",function(e){this.popoverTemplate="amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html",this.editPolicy=()=>{const e={app:this.application,policy:this.policy,serverGroup:this.serverGroup};b.show(zs,e,{dialogClassName:"wizard-modal modal-lg"})},this.deletePolicy=()=>{const e={application:this.application,title:"Deleting scaling policy "+this.policy.policyName};k.confirm({header:"Really delete "+this.policy.policyName+"?",buttonText:"Delete scaling policy",account:this.policy.alarms.length?this.serverGroup.account:null,taskMonitorConfig:e,submitMethod:()=>Hs.deleteScalingPolicy(this.application,this.serverGroup,this.policy)})}}]}),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/alarmBasedSummary.component.html",'<span class="label label-default">{{ $ctrl.policy.policyType | robotToHuman | uppercase }}</span>\n\n<div ng-repeat="alarm in $ctrl.policy.alarms track by $index">\n <div\n uib-popover-template="$ctrl.popoverTemplate"\n popover-placement="left"\n popover-title="{{ $ctrl.policy.policyName }}"\n popover-trigger="\'mouseenter\'"\n >\n <div>\n <strong>Whenever</strong>\n {{ alarm.statistic }} of <span class="alarm-name">{{ alarm.metricName }}</span> is\n <span ng-bind-html="alarm.comparator"></span> {{ alarm.threshold }}\n </div>\n <div>\n <strong>for at least</strong>\n {{ alarm.evaluationPeriods }} consecutive periods of {{ alarm.period }} seconds\n </div>\n </div>\n</div>\n\n<div ng-if="!$ctrl.policy.alarms.length">\n <em>No alarms configured for this policy &mdash; it\'s safe to delete.</em>\n</div>\n\n<div class="actions text-right">\n <button class="btn btn-xs btn-link" ng-click="$ctrl.editPolicy()" ng-if="$ctrl.policy.alarms.length">\n <span class="glyphicon glyphicon-cog" uib-tooltip="Edit policy"></span>\n <span class="sr-only">Edit policy</span>\n </button>\n <button class="btn btn-xs btn-link" ng-click="$ctrl.deletePolicy()">\n <span class="glyphicon glyphicon-trash" uib-tooltip="Delete policy"></span>\n <span class="sr-only">Delete policy</span>\n </button>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/popover/scalingPolicyDetails.popover.html",'<aws-scaling-policy-popover policy="$ctrl.policy" server-group="$ctrl.serverGroup"></aws-scaling-policy-popover>\n')}]),Mn.registerPolicyType({type:"TargetTrackingScaling",summaryTemplateUrl:"amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html"}),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingSummary.html",'<target-tracking-summary\n policy="$ctrl.policy"\n server-group="$ctrl.serverGroup"\n application="$ctrl.application"\n></target-tracking-summary>\n')}]);t("spinnaker.amazon.scalingPolicy.targetTracking.metricFields.component",[]).component("targetMetricFields",ja(M(ys,"targetMetricFields"),["allowDualMode","cloudwatch","command","isCustomMetric","serverGroup","toggleMetricType","unit","updateCommand"]));t("spinnaker.amazon.scalingPolicy.targetTracking.chart.component",[]).component("targetTrackingChart",ja(M(gs,"targetTrackingChart"),["alarmUpdated","config","serverGroup","unit","updateUnit"]));const _s={bindings:{policy:"<",serverGroup:"<",application:"<"},controller:class{constructor(){this.popoverTemplate="amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingPopover.html"}$onInit(){this.config=this.policy.targetTrackingConfiguration}editPolicy(){const e={app:this.application,policy:this.policy,serverGroup:this.serverGroup};b.show(Es,e,{dialogClassName:"wizard-modal modal-lg"})}deletePolicy(){const e={application:this.application,title:"Deleting scaling policy "+this.policy.policyName};k.confirm({header:`Really delete ${this.policy.policyName}?`,buttonText:"Delete scaling policy",account:this.serverGroup.account,taskMonitorConfig:e,submitMethod:()=>Hs.deleteScalingPolicy(this.application,this.serverGroup,this.policy)})}},template:'\n <div uib-popover-template="$ctrl.popoverTemplate"\n popover-placement="left"\n popover-title="{{$ctrl.policy.policyName}}"\n popover-trigger="\'mouseenter\'">\n <p>\n <span class="label label-default">{{$ctrl.policy.policyType | robotToHuman | uppercase }}</span>\n <div>\n <strong>Target</strong>\n {{$ctrl.config.predefinedMetricSpecification.predefinedMetricType}}\n {{$ctrl.config.customizedMetricSpecification.metricName}}\n <span ng-if="$ctrl.config.customizedMetricSpecification">({{$ctrl.config.customizedMetricSpecification.statistic}})</span>\n @ {{$ctrl.config.targetValue}}\n </div>\n </p>\n <div class="actions text-right">\n <button class="btn btn-xs btn-link" ng-click="$ctrl.editPolicy()">\n <span class="glyphicon glyphicon-cog" uib-tooltip="Edit policy"></span>\n <span class="sr-only">Edit policy</span>\n </button>\n <button class="btn btn-xs btn-link" ng-click="$ctrl.deletePolicy()">\n <span class="glyphicon glyphicon-trash" uib-tooltip="Delete policy"></span>\n <span class="sr-only">Delete policy</span>\n </button>\n </div>\n </div>\n '};t("spinnaker.amazon.scalingPolicy.targetTracking.summary.component",[]).component("targetTrackingSummary",_s),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/serverGroup/details/scalingPolicy/targetTracking/targetTrackingPopover.html",'<target-tracking-chart\n config="$ctrl.policy.targetTrackingConfiguration"\n server-group="$ctrl.serverGroup"\n update-unit="$ctrl.updateUnit"\n></target-tracking-chart>\n')}]);t("spinnaker.amazon.scalingPolicy.targetTracking",["spinnaker.amazon.scalingPolicy.targetTracking.chart.component","spinnaker.amazon.scalingPolicy.targetTracking.summary.component","spinnaker.amazon.scalingPolicy.targetTracking.metricFields.component"]);t("spinnaker.amazon.scalingPolicy.module",[Ln,"spinnaker.amazon.scalingPolicy.targetTracking","spinnaker.amazon.serverGroup.details.scalingPolicy.alarmBasedSummary.component"]);e.module("spinnaker.amazon.serverGroup.details.autoscaling.process.controller",[]).controller("ModifyScalingProcessesCtrl",["$scope","$uibModalInstance","application","serverGroup","processes",function(t,a,n,r,i){t.command=e.copy(i),t.serverGroup=r,t.verification={},this.isValid=function(){return!!t.verification.verified&&this.isDirty()};const s=Mt.chain(t.command).filter({enabled:!0}).map("name").value(),l=Mt.chain(t.command).filter({enabled:!1}).map("name").value();this.isDirty=function(){const e=Mt.chain(t.command).filter({enabled:!0}).map("name").value(),a=Mt.chain(t.command).filter({enabled:!1}).map("name").value(),n=Mt.intersection(l,e),r=Mt.intersection(s,a);return!(!n.length&&!r.length)},t.taskMonitor=new v({application:n,title:"Update Auto Scaling Processes for "+r.name,modalInstance:a,onTaskComplete:()=>n.serverGroups.refresh()}),this.submit=function(){const e=Mt.chain(t.command).filter({enabled:!0}).map("name").value(),a=Mt.chain(t.command).filter({enabled:!1}).map("name").value(),i=Mt.intersection(l,e),o=Mt.intersection(s,a),c=[];i.length&&c.push({type:"modifyScalingProcess",action:"resume",processes:i,asgName:r.name,regions:[r.region],credentials:r.account,cloudProvider:"aws",reason:t.command.reason}),o.length&&c.push({type:"modifyScalingProcess",action:"suspend",processes:o,asgName:r.name,regions:[r.region],credentials:r.account,cloudProvider:"aws",reason:t.command.reason});t.taskMonitor.submit((function(){return L.executeTask({job:c,application:n,description:"Update Auto Scaling Processes for "+r.name})}))},this.cancel=a.dismiss}]);t("spinnaker.amazon.serverGroup.details.scheduledActions.editScheduledActions.modal.controller",[]).controller("EditScheduledActionsCtrl",["$scope","$uibModalInstance","application","serverGroup",function(e,t,a,n){e.command={scheduledActions:n.scheduledActions.map((e=>({recurrence:e.recurrence,minSize:e.minSize,maxSize:e.maxSize,desiredCapacity:e.desiredCapacity})))},e.serverGroup=n,this.addScheduledAction=()=>{e.command.scheduledActions.push({})},this.removeScheduledAction=t=>{e.command.scheduledActions.splice(t,1)},e.taskMonitor=new v({application:a,title:"Update Scheduled Actions for "+n.name,modalInstance:t,onTaskComplete:()=>a.serverGroups.refresh()}),this.submit=()=>{const t=[{type:"upsertAsgScheduledActions",asgs:[{asgName:n.name,region:n.region}],scheduledActions:e.command.scheduledActions,credentials:n.account}];e.taskMonitor.submit((function(){return L.executeTask({job:t,application:a,description:"Update Scheduled Actions for "+n.name})}))},this.cancel=t.dismiss}]);t("spinnaker.amazon.serverGroup.details.securityGroup.editSecurityGroups.modal.controller",[zt,Te]).controller("EditSecurityGroupsCtrl",["$scope","$uibModalInstance","serverGroupWriter","securityGroupReader","application","serverGroup","securityGroups",function(e,t,a,n,r,i,s){this.command={securityGroups:(s||[]).slice(0).sort(((e,t)=>e.name.localeCompare(t.name)))},this.state={securityGroupsLoaded:!1,submitting:!1,verification:{}},this.infiniteScroll={currentItems:20},this.addMoreItems=()=>this.infiniteScroll.currentItems+=20,this.resetCurrentItems=()=>this.infiniteScroll.currentItems=20,this.isValid=()=>this.state.verification.verified,n.getAllSecurityGroups().then((e=>{const t=i.account,a=i.region,n=i.vpcId;this.availableSecurityGroups=Mt.get(e,[t,"aws",a].join("."),[]).filter((e=>e.vpcId===n)).sort(((e,t)=>this.command.securityGroups.some((t=>t.id===e.id))?-1:this.command.securityGroups.some((e=>e.id===t.id))?1:e.name.localeCompare(t.name))),this.state.securityGroupsLoaded=!0})),this.serverGroup=i,this.taskMonitor=new v({application:r,title:`Update ${U.get("Firewalls")} for ${i.name}`,modalInstance:t,onTaskComplete:()=>r.serverGroups.refresh()}),this.submit=()=>{this.taskMonitor.submit((()=>{this.state.submitting=!0;const e=Boolean(i.launchTemplate);return a.updateSecurityGroups(i,this.command.securityGroups,r,e)}))},this.cancel=t.dismiss}]);t("spinnaker.amazon.serverGroup.details",["spinnaker.amazon.scalingPolicy.module","spinnaker.amazon.serverGroup.details.securityGroup.editSecurityGroups.modal.controller","spinnaker.amazon.serverGroup.details.autoscaling.process.controller","spinnaker.amazon.serverGroup.details.scheduledActions.editScheduledActions.modal.controller","spinnaker.amazon.serverGroup.editAsgAdvancedSettings.modal.controller","spinnaker.amazon.serverGroup.details.rollback.controller"]);t("spinnaker.amazon.serverGroup.transformer",[]).service("awsServerGroupTransformer",class{addComparator(e){if(e.comparisonOperator)switch(e.comparisonOperator){case"LessThanThreshold":e.comparator="&lt;";break;case"GreaterThanThreshold":e.comparator="&gt;";break;case"LessThanOrEqualToThreshold":e.comparator="&le;";break;case"GreaterThanOrEqualToThreshold":e.comparator="&ge;"}}addAdjustmentAttributes(e){e.operator=e.scalingAdjustment<0?"decrease":"increase",e.absAdjustment=Math.abs(e.scalingAdjustment)}transformScalingPolicy(e){const t={...e},a=(e,t)=>t.metricIntervalUpperBound-e.metricIntervalUpperBound,n=(e,t)=>e.metricIntervalLowerBound-t.metricIntervalLowerBound;if(t.alarms=e.alarms||[],t.alarms.forEach((e=>this.addComparator(e))),this.addAdjustmentAttributes(t),t.stepAdjustments&&t.stepAdjustments.length){t.stepAdjustments.forEach((e=>this.addAdjustmentAttributes(e)));const r=e.stepAdjustments.every((e=>void 0!==e.metricIntervalUpperBound))?a:n;t.stepAdjustments.sort(((e,t)=>r(e,t)))}return t}normalizeServerGroupDetails(e){const t={...e};return e.scalingPolicies&&(t.scalingPolicies=e.scalingPolicies.map((e=>this.transformScalingPolicy(e)))),t}normalizeServerGroup(e){return e.instances.forEach((t=>{t.vpcId=e.vpcId})),Pn.listVpcs().then((t=>this.addVpcNameToServerGroup(e)(t)))}addVpcNameToServerGroup(e){return t=>{const a=t.find((t=>t.id===e.vpcId));return e.vpcName=a?a.name:"",e}}convertServerGroupCommandToDeployConfiguration(e){const t=fa({backingData:[],viewState:[]},e);return t.cloudProvider="aws",t.availabilityZones={},t.availabilityZones[t.region]=e.availabilityZones,t.loadBalancers=(e.loadBalancers||[]).concat(e.vpcLoadBalancers||[]),t.targetGroups=e.targetGroups||[],t.account=t.credentials,t.subnetType=t.subnetType||"","clone"!==e.viewState.mode&&delete t.source,t.ramdiskId||delete t.ramdiskId,delete t.region,delete t.viewState,delete t.backingData,delete t.selectedProvider,delete t.instanceProfile,delete t.vpcId,t}constructNewStepScalingPolicyTemplate(e){return{alarms:[{namespace:"AWS/EC2",metricName:"CPUUtilization",threshold:50,statistic:"Average",comparisonOperator:"GreaterThanThreshold",evaluationPeriods:1,dimensions:[{name:"AutoScalingGroupName",value:e.name}],period:60}],adjustmentType:"ChangeInCapacity",stepAdjustments:[{scalingAdjustment:1,metricIntervalLowerBound:0}],estimatedInstanceWarmup:600}}constructNewTargetTrackingPolicyTemplate(){return{alarms:[],estimatedInstanceWarmup:300,targetTrackingConfiguration:{targetValue:null,predefinedMetricSpecification:{predefinedMetricType:"ASGAverageCPUUtilization"}}}}});t("spinnaker.amazon.subnet.renderer",[]).service("awsSubnetRenderer",class{render(e){return e.subnetType}});Bt.registerValidator("aws",new class{validateSpecialCharacters(e,t){/^[a-zA-Z_0-9.]*$/g.test(e)||t.push("Only dot(.) and underscore(_) special characters are allowed.")}validateClassicLock(e){const t=fn.classicLaunchLockout;t&&t<(new Date).getTime()&&e.push(`New applications deployed to AWS are restricted to VPC; you cannot create server groups,\n load balancers, or ${U.get("firewalls")} in EC2 Classic.`)}validateLoadBalancerCharacters(e,t){(e.includes(".")||e.includes("_"))&&t.push("If the application's name contains an underscore(_) or dot(.),\n you will not be able to create a load balancer,\n preventing it from being used as a front end service.\n Any hostname constructed with this application name may have issues.")}validateLength(e,t,a){if(e.length>250)a.push("The maximum length for an application in Amazon is 250 characters.");else{if(e.length>240)if(e.length>=248)t.push(`You will not be able to include a stack or detail field for clusters or ${U.get("firewalls")}.`);else{const a=248-e.length;t.push(`If you plan to include a stack or detail field for clusters, you will only\n have ~${a} characters to do so.`)}if(e.length>20)if(e.length>32)t.push(`You will not be able to create an Amazon load balancer for this application if the\n application's name is longer than 32 characters (currently: ${e.length} characters)`);else if(e.length>=30)t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32 (currently: ${e.length} characters). With separators ("-"), you will not\n be able to add a stack and detail field to any load balancer.`);else{const a=30-e.length;t.push(`If you plan to create load balancers for this application, be aware that the character limit\n for load balancer names is 32. You will only have ~${a} characters to add a stack or detail\n field to any load balancer.`)}}}validate(e=""){const t=[],a=[];return e.length&&(this.validateClassicLock(t),this.validateSpecialCharacters(e,a),this.validateLoadBalancerCharacters(e,t),this.validateLength(e,t,a)),{warnings:t,errors:a}}});t("spinnaker.amazon.vpc",["spinnaker.amazon.vpc.tag.directive"]);ar('.cloud-provider-logo .icon-aws {\n -webkit-mask-image: url("data:image/svg+xml,%3C%3Fxml version%3D%221.0%22 encoding%3D%22utf-8%22%3F%3E%3C!DOCTYPE svg PUBLIC %22-%2F%2FW3C%2F%2FDTD SVG 1.1%2F%2FEN%22 %22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg version%3D%221.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 width%3D%22130px%22 height%3D%22130px%22 viewBox%3D%220 0 27 27%22%3E%3Cg%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2213.2%2C27 2.4%2C23.1 2.4%2C8.5 13.2%2C12.5 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2226.5%2C23.1 15.2%2C27 15.2%2C12.5 26.5%2C8 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2214.2%2C3.4 25.5%2C7 14.2%2C11.0 2.9%2C7 %22%2F%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!DOCTYPE svg PUBLIC %22-%2F%2FW3C%2F%2FDTD SVG 1.1%2F%2FEN%22 %22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg version%3D%221.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 width%3D%22130px%22 height%3D%22130px%22 viewBox%3D%220 0 27 27%22%3E%3Cg%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2213.2%2C27 2.4%2C23.1 2.4%2C8.5 13.2%2C12.5 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2226.5%2C23.1 15.2%2C27 15.2%2C12.5 26.5%2C8 %22%2F%3E%09%3Cpolygon fill%3D%22%23000000%22 stroke%3D%22%23FFFFFF%22 stroke-width%3D%220%22 points%3D%2214.2%2C3.4 25.5%2C7 14.2%2C11.0 2.9%2C7 %22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");\n}\n');const Ks="spinnaker.amazon";t("spinnaker.amazon",["spinnaker.amazon.react","spinnaker.amazon.pipeline.stage.bakeStage","spinnaker.amazon.pipeline.stage.cloneServerGroupStage","spinnaker.amazon.pipeline.stage.aws.destroyAsgStage","spinnaker.amazon.pipeline.stage.disableAsgStage","spinnaker.amazon.pipeline.stage.disableClusterStage","spinnaker.amazon.pipeline.stage.rollbackClusterStage","spinnaker.amazon.pipeline.stage.enableAsgStage","spinnaker.amazon.pipeline.stage.findAmiStage","spinnaker.amazon.pipeline.stage.findImageFromTagsStage","spinnaker.amazon.pipeline.stage.modifyScalingProcessStage","spinnaker.amazon.pipeline.stage.aws.resizeAsgStage","spinnaker.amazon.pipeline.stage.scaleDownClusterStage","spinnaker.amazon.pipeline.stage.aws.shrinkClusterStage","spinnaker.amazon.pipeline.stage.tagImageStage","spinnaker.amazon.serverGroup.details","spinnaker.amazon.common","spinnaker.amazon.serverGroup.transformer","spinnaker.amazon.instanceType.service","spinnaker.amazon.loadBalancer","spinnaker.amazon.function","spinnaker.amazon.instance.details.controller","spinnaker.amazon.securityGroup","spinnaker.amazon.subnet.renderer","spinnaker.amazon.vpc","spinnaker.amazon.search.searchResultFormatter","spinnaker.amazon.pipeline.stages.deployCloudFormationStage","spinnaker.amazon.cloudformation.entry.component","spinnaker.amazon.cloudformation.changetset.info.component","spinnaker.amazon.deployCloudFormation.service","spinnaker.application.instanceStatus.component","spinnaker.application.instanceTags.component","spinnaker.application.instanceSecurityGroups.component","spinnaker.application.instanceDns.component","spinnaker.application.amazonInstanceInformation.component"]).config((()=>{O.registerProvider("aws",{name:"Amazon",logo:{path:"amazon.logo352d4e042476837f.svg"},image:{reader:_n},serverGroup:{transformer:"awsServerGroupTransformer",detailsActions:_i,detailsGetter:Yi,detailsSections:[Qi,ts,as,ns,is,ls,Os,Ms,Fs,Ls,Us,cs,Xi,os],CloneServerGroupModal:Ui,commandBuilder:"awsServerGroupCommandBuilder",configurationService:"awsServerGroupConfigurationService",scalingActivitiesEnabled:!0},instance:{instanceTypeService:"awsInstanceTypeService",detailsTemplateUrl:"amazon/src/instance/details/instanceDetails.html",detailsController:"awsInstanceDetailsCtrl"},loadBalancer:{transformer:Br,detailsTemplateUrl:"amazon/src/loadBalancer/details/loadBalancerDetails.html",detailsController:"awsLoadBalancerDetailsCtrl",CreateLoadBalancerModal:Kr,targetGroupDetailsTemplateUrl:"amazon/src/loadBalancer/details/targetGroupDetails.html",targetGroupDetailsController:"awsTargetGroupDetailsCtrl",ClusterContainer:rr,LoadBalancersTag:or},function:{details:Wn,CreateFunctionModal:Dn,transformer:bn},securityGroup:{transformer:"awsSecurityGroupTransformer",reader:"awsSecurityGroupReader",detailsTemplateUrl:"amazon/src/securityGroup/details/securityGroupDetail.html",detailsController:"awsSecurityGroupDetailsCtrl",createSecurityGroupTemplateUrl:"amazon/src/securityGroup/configure/createSecurityGroup.html",createSecurityGroupController:"awsCreateSecurityGroupCtrl"},subnet:{renderer:"awsSubnetRenderer"},search:{resultFormatter:"awsSearchResultFormatter"},applicationProviderFields:{templateUrl:"amazon/src/applicationProviderFields/awsFields.html"}})})),r.registerProvider("aws",["custom","redblack","rollingpush","rollingredblack","monitored"]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/instance/details/instanceDetails.html",'<div class="text-center" ng-if="state.notFoundStandalone">\n <h3>Could not find instance {{instanceIdNotFound}}.</h3>\n <a ui-sref="home.infrastructure">Back to search results</a>\n</div>\n<div class="details-panel" ng-if="!state.notFoundStandalone">\n <div class="header">\n <instance-details-header\n health-state="instance.healthState"\n instance-id="instance.instanceId || instanceIdNotFound"\n loading="state.loading"\n standalone="state.standalone"\n ></instance-details-header>\n <div ng-if="!state.loading">\n <div class="actions" ng-class="{ insights: instance.insightActions.length > 0 }" ng-if="instance.placement">\n <instance-actions actions="instanceActions"></instance-actions>\n <instance-insights insights="instance.insightActions" instance="instance"></instance-insights>\n </div>\n </div>\n </div>\n <div class="content" ng-if="!state.loading && instance">\n <amazon-instance-information instance="instance"></amazon-instance-information>\n <instance-status\n health-metrics="healthMetrics"\n health-state="instance.healthState"\n metric-types="[\'LoadBalancer\', \'TargetGroup\']"\n private-ip-address="instance.privateIpAddress"\n >\n </instance-status>\n <collapsible-section heading="DNS">\n <instance-dns\n instance-port="state.instancePort"\n ipv6-addresses="instance.ipv6Addresses"\n permanent-ips="instance.permanentIps"\n private-dns-name="instance.privateDnsName"\n private-ip-address="instance.privateIpAddress"\n public-dns-name="instance.publicDnsName"\n public-ip-address="instance.publicIpAddress"\n >\n </instance-dns>\n </collapsible-section>\n <instance-security-groups instance="instance"></instance-security-groups>\n <instance-tags tags="instance.tags"></instance-tags>\n <collapsible-section heading="Console Output" ng-if="baseIpAddress">\n <ul>\n <li>\n <console-output-link instance="instance"></console-output-link>\n </li>\n </ul>\n </collapsible-section>\n <instance-links\n address="baseIpAddress"\n application="application"\n instance="instance"\n moniker="moniker"\n environment="environment"\n ></instance-links>\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("amazon/src/loadBalancer/details/loadBalancerDetails.html",'<div class="details-panel">\n <div ng-if="ctrl.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 spinner-container">\n <loading-spinner size="\'small\'"></loading-spinner>\n </div>\n </div>\n\n <div ng-if="!ctrl.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>\n {{ctrl.loadBalancer.name}}\n <render-if-feature feature="entityTags">\n <entity-notifications\n entity="ctrl.loadBalancer"\n application="ctrl.application"\n placement="bottom"\n h-offset-percent="90%"\n entity-type="loadBalancer"\n page-location="details"\n on-update="ctrl.application.loadBalancers.refresh()"\n ></entity-notifications>\n </render-if-feature>\n </h3>\n </div>\n <div>\n <div class="actions">\n <load-balancer-actions\n app="ctrl.application"\n load-balancer="ctrl.loadBalancer"\n load-balancer-from-params="ctrl.loadBalancerFromParams"\n ></load-balancer-actions>\n <div\n class="dropdown"\n ng-if="ctrl.loadBalancer.elb.insightActions.length > 0"\n uib-dropdown\n dropdown-append-to-body\n >\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 ctrl.loadBalancer.elb.insightActions">\n <a target="_blank" href="{{action.url}}">{{action.label}}</a>\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!ctrl.state.loading && ctrl.loadBalancer.isManaged"\n resource-summary="ctrl.loadBalancer.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div ng-if="!ctrl.state.loading" class="content">\n <collapsible-section heading="Load Balancer Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>Created</dt>\n <dd>{{ctrl.loadBalancer.elb.createdTime | timestamp}}</dd>\n <dt>In</dt>\n <dd>\n <account-tag account="ctrl.loadBalancer.account" pad="right"></account-tag> {{ctrl.loadBalancer.region}}\n </dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="ctrl.loadBalancer.elb.vpcId"></vpc-tag>\n </dd>\n <dt>Subnet</dt>\n <dd>{{ctrl.getFirstSubnetPurpose(ctrl.loadBalancer.subnetDetails)}}</dd>\n <dt>Scheme</dt>\n <dd>{{ ctrl.loadBalancer.scheme }}</dd>\n <dt ng-if="ctrl.loadBalancer.loadBalancerType">Type</dt>\n <dd ng-if="ctrl.loadBalancer.loadBalancerType">{{ctrl.loadBalancer.loadBalancerType}}</dd>\n <dt ng-if="ctrl.ipAddressTypeDescription">IP Type</dt>\n <dd ng-if="ctrl.ipAddressTypeDescription">{{ctrl.ipAddressTypeDescription}}</dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt>Availability Zones</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="availabilityZone in ctrl.loadBalancer.elb.availabilityZones">{{availabilityZone}}</li>\n </ul>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.loadBalancer.serverGroups && ctrl.loadBalancer.serverGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Server Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in ctrl.loadBalancer.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: \'aws\'})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.loadBalancer.targetGroups && ctrl.loadBalancer.targetGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Target Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="targetGroup in ctrl.loadBalancer.targetGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.targetGroupDetails({region: targetGroup.region,\n loadBalancerName: ctrl.loadBalancer.name,\n accountId: targetGroup.account,\n name: targetGroup.name,\n vpcId: targetGroup.vpcId,\n provider: \'aws\'})"\n >\n {{targetGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="ctrl.loadBalancer.elb.dnsname">DNS Name</dt>\n <dd>\n <a target="_blank" href="{{ctrl.elbProtocol}}//{{ctrl.loadBalancer.elb.dnsname}}"\n >{{ctrl.loadBalancer.elb.dnsname}}</a\n >\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="ctrl.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" ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'">\n <health-counts class="pull-left" container="ctrl.loadBalancer.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="false" ng-if="ctrl.loadBalancer.loadBalancerType !== \'classic\'">\n Select a target group to check the instance health status from the view of the target group.\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'" heading="Listeners">\n <dl>\n <dt>Load Balancer &rarr; Instance</dt>\n <dd ng-repeat="listener in ctrl.loadBalancer.elb.listenerDescriptions">\n {{listener.listener.protocol}}:{{listener.listener.loadBalancerPort}} &rarr;\n {{listener.listener.instanceProtocol}}:{{listener.listener.instancePort}}\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType !== \'classic\'" heading="Listeners">\n <div ng-repeat="listener in ctrl.listeners">\n <div class="listener-targets">{{listener.in}} &rarr;</div>\n <div class="listener-targets">\n <div ng-repeat="action in listener.actions">\n \x3c!-- redirect --\x3e\n <span ng-if="action.type === \'redirect\'">\n <span ng-if="action.redirectConfig.protocol !== listener.protocol">\n {{action.redirectConfig.protocol}}:\n </span>\n <span ng-if="action.redirectConfig.host !== \'#{host}\'"> {{action.redirectConfig.host}} </span>\n <span ng-if="action.redirectConfig.port !== \'#{port}\'"> {{action.redirectConfig.port}} </span>\n <span ng-if="action.redirectConfig.path !== \'/#{path}\'"> {{action.redirectConfig.path}} </span>\n <span ng-if="action.redirectConfig.query !== \'#{query}\'"> ?{{action.redirectConfig.query}} </span>\n ({{action.redirectConfig.statusCode}})\n </span>\n \x3c!-- authenticate-oidc --\x3e\n <span ng-if="action.type === \'authenticate-oidc\'">\n <i class="fas fa-fw fa-user-lock"></i>\n <a\n ng-if="ctrl.oidcConfigPath"\n href="{{ctrl.oidcConfigPath}}{{action.authenticateOidcConfig.clientId}}"\n target="_blank"\n >\n {{action.authenticateOidcConfig.clientId}}\n </a>\n <span ng-if="!ctrl.oidcConfigPath"> {{action.authenticateOidcConfig.clientId}} </span>\n </span>\n \x3c!-- forward --\x3e\n <span ng-if="action.targetGroupName && action.targetGroup">\n <i class="fa fa-fw fa-crosshairs icon" aria-hidden="true"></i>\n <a\n ui-sref="^.targetGroupDetails({region: action.targetGroup.region,\n loadBalancerName: ctrl.loadBalancer.name,\n accountId: action.targetGroup.account,\n name: action.targetGroup.name,\n vpcId: action.targetGroup.vpcId,\n provider: \'aws\'})"\n >\n {{action.targetGroupName}}\n </a>\n </span>\n <span ng-if="action.targetGroupName && !action.targetGroup">\n <i class="fa fa-fw fa-crosshairs icon" aria-hidden="true"></i>\n {{action.targetGroupName}}\n </span>\n </div>\n </div>\n </div>\n </collapsible-section>\n <collapsible-section\n heading="{{ctrl.firewallsLabel}}"\n ng-if="ctrl.loadBalancer.loadBalancerType !== \'network\' || (ctrl.loadBalancer.loadBalancerType === \'network\' && ctrl.securityGroups && ctrl.securityGroups.length > 0)"\n >\n <ul>\n <li ng-repeat="securityGroup in ctrl.securityGroups | orderBy:\'name\'">\n <a\n ui-sref="^.firewallDetails({name:securityGroup.name, accountId: ctrl.loadBalancer.account, region: ctrl.loadBalancer.region, vpcId: ctrl.loadBalancer.vpcId, provider: ctrl.loadBalancer.provider})"\n >\n {{securityGroup.name}} ({{securityGroup.id}})\n </a>\n </li>\n </ul>\n </collapsible-section>\n <collapsible-section heading="Subnets">\n <div ng-if="ctrl.loadBalancer.subnetDetails.length === 0">\n <h5>No subnets</h5>\n </div>\n <div ng-repeat="subnet in ctrl.loadBalancer.subnetDetails" ng-class="{\'bottom-border\': !$last}">\n <h5><strong>{{subnet.id}}</strong></h5>\n <dl class="dl-horizontal dl-narrow">\n <dt>Purpose</dt>\n <dd>{{subnet.purpose}}</dd>\n\n <dt>State</dt>\n <dd>{{subnet.state}}</dd>\n\n <dt>Cidr Block</dt>\n <dd>{{subnet.cidrBlock}}</dd>\n </dl>\n </div>\n </collapsible-section>\n <collapsible-section ng-if="ctrl.loadBalancer.loadBalancerType === \'classic\'" heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.target}}</dd>\n <dt>Timeout</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.timeout}} seconds</dd>\n <dt>Interval</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.interval}} seconds</dd>\n <dt>Healthy Threshold</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.healthyThreshold}}</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{ctrl.loadBalancer.elb.healthCheck.unhealthyThreshold}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/loadBalancer/details/targetGroupDetails.html",'<div class="details-panel">\n <div ng-if="ctrl.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="!ctrl.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 fa-crosshairs icon" aria-hidden="true"></i>\n <h3 class="horizontal middle space-between flex-1" select-on-dbl-click>{{ctrl.targetGroup.name}}</h3>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!ctrl.state.loading && ctrl.loadBalancer.isManaged"\n resource-summary="ctrl.loadBalancer.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div ng-if="!ctrl.state.loading" class="content">\n <collapsible-section heading="Target Group Details" expanded="true">\n <dl class="dl-horizontal dl-narrow">\n <dt>In</dt>\n <dd><account-tag account="ctrl.targetGroup.account" pad="right"></account-tag> {{ctrl.targetGroup.region}}</dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="ctrl.targetGroup.vpcId"></vpc-tag>\n </dd>\n <dt>Protocol</dt>\n <dd>{{ctrl.targetGroup.protocol}}</dd>\n <dt>Port</dt>\n <dd>{{ctrl.targetGroup.port}}</dd>\n <dt>Target Type</dt>\n <dd>{{ctrl.targetGroup.targetType}}</dd>\n </dl>\n <dl ng-if="ctrl.loadBalancer" class="horizontal-when-filters-collapsed">\n <dt>Load Balancer</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li>\n <a\n ui-sref="^.loadBalancerDetails({ name: ctrl.loadBalancer.name,\n region: ctrl.loadBalancer.region,\n accountId: ctrl.loadBalancer.account,\n vpcId: ctrl.loadBalancer.vpcId,\n provider: \'aws\'})"\n >\n {{ctrl.loadBalancer.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n <dl class="horizontal-when-filters-collapsed">\n <dt ng-if="ctrl.loadBalancer.dnsname">Load Balancer DNS Name</dt>\n <dd ng-if="ctrl.loadBalancer.dnsname">\n <a target="_blank" href="{{ctrl.elbProtocol}}//{{ctrl.loadBalancer.dnsname}}"\n >{{ctrl.loadBalancer.dnsname}}</a\n >\n <copy-to-clipboard\n class="copy-to-clipboard copy-to-clipboard-sm"\n text="ctrl.loadBalancer.dnsname"\n tool-tip="\'Copy DNS Name to clipboard\'"\n >\n </copy-to-clipboard>\n </dd>\n </dl>\n <dl\n ng-if="ctrl.targetGroup.serverGroups && ctrl.targetGroup.serverGroups.length"\n class="horizontal-when-filters-collapsed"\n >\n <dt>Server Groups</dt>\n <dd>\n <ul class="collapse-margin-on-filter-collapse">\n <li ng-repeat="serverGroup in ctrl.targetGroup.serverGroups | orderBy: [\'isDisabled\', \'-name\']">\n <a\n ui-sref="^.serverGroup({region: serverGroup.region,\n accountId: serverGroup.account,\n serverGroup: serverGroup.name,\n provider: serverGroup.cloudProvider})"\n >\n {{serverGroup.name}}\n </a>\n </li>\n </ul>\n </dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Status" expanded="true">\n <health-counts class="pull-left" container="ctrl.targetGroup.instanceCounts"></health-counts>\n </collapsible-section>\n <collapsible-section heading="Health Checks">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Target</dt>\n <dd>\n {{ctrl.targetGroup.healthCheckProtocol}}:{{ctrl.targetGroup.healthCheckPort}}\n {{ctrl.targetGroup.healthCheckPath}}\n </dd>\n <dt>Timeout</dt>\n <dd>{{ctrl.targetGroup.healthCheckTimeoutSeconds}} seconds</dd>\n <dt>Interval</dt>\n <dd>{{ctrl.targetGroup.healthCheckIntervalSeconds}} seconds</dd>\n <dt>Healthy Threshold</dt>\n <dd>{{ctrl.targetGroup.healthyThresholdCount}}</dd>\n <dt>Unhealthy Threshold</dt>\n <dd>{{ctrl.targetGroup.unhealthyThresholdCount}}</dd>\n <dt>Matcher</dt>\n <dd>HTTP Code(s): {{ctrl.targetGroup.matcher.httpCode}}</dd>\n </dl>\n </collapsible-section>\n <collapsible-section heading="Attributes" expanded="true">\n <dl class="horizontal-when-filters-collapsed">\n <dt>Deregistration Delay Timeout</dt>\n <dd>{{ctrl.targetGroup.attributes[\'deregistration_delay.timeout_seconds\']}} seconds</dd>\n <dt>Stickiness Enabled</dt>\n <dd>{{ctrl.targetGroup.attributes[\'stickiness.enabled\']}}</dd>\n <dt ng-if-start="ctrl.targetGroup.attributes[\'stickiness.enabled\'] === \'true\'">\n Stickiness Load Balancer Cookie Duration\n </dt>\n <dd>{{ctrl.targetGroup.attributes[\'stickiness.lb_cookie.duration_seconds\']}} seconds</dd>\n <dt>Stickiness Type</dt>\n <dd ng-if-end>{{ctrl.targetGroup.attributes[\'stickiness.type\']}}</dd>\n <dt ng-if-start="ctrl.loadBalancer.loadBalancerType === \'network\'">Preserve Client IP</dt>\n <dd ng-if-end>{{ctrl.targetGroup.attributes[\'preserve_client_ip.enabled\']}}</dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/details/securityGroupDetail.html",'<div class="text-center" ng-if="state.notFound">\n <h3>Could not find <firewall-label label="firewall"></firewall-label> {{group}}.</h3>\n <a ui-sref="home.infrastructure">Back to search results</a>\n</div>\n<div class="details-panel" ng-if="!state.notFound">\n <div class="header">\n <div class="close-button" ng-if="!state.standalone">\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 <render-if-feature feature="entityTags">\n <entity-notifications\n entity="securityGroup"\n application="ctrl.application"\n placement="bottom"\n h-offset-percent="90%"\n entity-type="securityGroup"\n page-location="details"\n on-update="ctrl.application.securityGroups.refresh()"\n ></entity-notifications>\n </render-if-feature>\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><a href ng-click="ctrl.editInboundRules()">Edit Inbound Rules</a></li>\n <li>\n <a href ng-click="ctrl.deleteSecurityGroup()">Delete <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <li>\n <a href ng-click="ctrl.cloneSecurityGroup()">Clone <firewall-label label="Firewall"></firewall-label></a>\n </li>\n <render-if-feature feature="entityTags">\n <add-entity-tag-links\n component="securityGroup"\n application="ctrl.application"\n entity-type="securityGroup"\n on-update="ctrl.application.securityGroups.refresh"\n ></add-entity-tag-links>\n </render-if-feature>\n </ul>\n </div>\n </div>\n </div>\n <managed-resource-details-indicator\n ng-if="!state.loading && securityGroup.isManaged"\n resource-summary="securityGroup.managedResourceSummary"\n application="ctrl.application"\n >\n </managed-resource-details-indicator>\n <div class="content" ng-if="!state.loading">\n <collapsible-section heading="{{ctrl.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>\n <account-tag account="securityGroup.accountName"></account-tag>\n </dd>\n <dt>Region</dt>\n <dd>{{securityGroup.region}}</dd>\n <dt>VPC</dt>\n <dd>\n <vpc-tag vpc-id="securityGroup.vpcId"></vpc-tag>\n </dd>\n <dt>Description</dt>\n <dd>{{securityGroup.description}}</dd>\n </dl>\n </collapsible-section>\n <ip-range-rules ip-rules="ipRules"></ip-range-rules>\n <collapsible-section\n heading="{{ctrl.firewallLabel}} Rules ({{securityGroupRules.length || 0}})"\n expanded="{{securityGroupRules.length > 0}}"\n >\n <div ng-if="!securityGroupRules.length">None</div>\n\n <dl\n ng-class="insightCtrl.vm.filtersExpanded ? \'\' : \'dl-horizontal dl-medium\'"\n ng-repeat="rule in securityGroupRules | orderBy: \'securityGroup.name\' "\n >\n <dt>\n <firewall-label label="Firewall"></firewall-label>\n </dt>\n <dd ng-if="rule.securityGroup.name">\n <a\n ui-sref="^.firewallDetails({name: rule.securityGroup.name, accountId: rule.securityGroup.accountName, region: rule.securityGroup.region, vpcId: rule.securityGroup.vpcId, provider: \'aws\'})"\n >\n <account-tag\n account="rule.securityGroup.accountName || rule.securityGroup.accountId"\n ng-if="rule.securityGroup.accountName !== securityGroup.accountName"\n ></account-tag>\n {{rule.securityGroup.name}} ({{rule.securityGroup.id}})\n </a>\n </dd>\n <dt>Port Ranges</dt>\n <dd ng-repeat="portRange in rule.rules">\n {{portRange.protocol}}: {{portRange.startPort}} &rarr; {{portRange.endPort}}\n </dd>\n </dl>\n </collapsible-section>\n </div>\n</div>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/securityGroup/configure/createSecurityGroup.html",'<ng-form role="form" name="form" novalidate>\n <v2-modal-wizard heading="Create New {{ctrl.translate(\'Firewall\')}}" 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="form.$invalid || !wizard.isComplete() || state.submitting || !customComponentIsvalid"\n submitting="state.submitting"\n on-click="ctrl.upsert()"\n is-new="state.isNew"\n ></submit-button>\n </div>\n</ng-form>\n')}]),window.angular.module("ng").run(["$templateCache",function(e){e.put("amazon/src/applicationProviderFields/awsFields.html",'<div class="form-group row">\n <div class="col-sm-3 sm-label-right">AWS Settings</div>\n <div class="col-sm-9 checkbox" style="margin-bottom: 0; margin-top: 5px">\n <label>\n <input\n type="checkbox"\n ng-init="$ctrl.initializeApplicationField(\'aws.useAmiBlockDeviceMappings\')"\n ng-model="$ctrl.application.providerSettings.aws.useAmiBlockDeviceMappings"\n />\n Prefer AMI Block Device Mappings\n </label>\n </div>\n</div>\n')}]);export{Ks as AMAZON_MODULE,Ss as AMAZON_SERVERGROUP_DETAILS_SCALINGPOLICY_ADDITIONAL_SETTINGS_COMPONENT,fn as AWSProviderSettings,js as AWS_SERVER_GROUP_CONFIGURATION_SERVICE,Xi as AdvancedSettingsDetailsSection,xs as AlarmConfigurer,ts as AmazonCapacityDetailsSection,gr as AmazonCertificateReader,vr as AmazonCertificateSelectField,Wn as AmazonFunctionDetails,Ei as AmazonImageSelectInput,Qi as AmazonInfoDetailsSection,Xn as AmazonInstanceWriter,Kr as AmazonLoadBalancerChoiceModal,rr as AmazonLoadBalancerClusterContainer,ir as AmazonLoadBalancerDataUtils,or as AmazonLoadBalancersTag,ji as AmazonResizeServerGroupModal,bn as AwsFunctionTransformer,Br as AwsLoadBalancerTransformer,Vi as AwsModalFooter,Un as AwsNgReact,On as AwsNgReactInjector,Vn as AwsReactInject,qn as AwsReactInjector,qs as AwsServerGroupConfigurationService,Dn as CreateLambdaFunction,Bs as CreateScalingPolicyButton,ds as DateLineChart,hs as DimensionsEditor,$n as FunctionActions,Gn as FunctionBasicInformation,as as HealthDetailsSection,yi as IPRangeRules,er as InstanceDns,Kn as InstanceInformation,tr as InstanceStatus,ns as InstancesDistributionDetailsSection,Vs as KeyPairsReader,is as LaunchConfigDetailsSection,ls as LaunchTemplateDetailsSection,Zr as LoadBalancerTypes,os as LogsDetailsSection,ps as MetricAlarmChart,vs as MetricSelector,cs as PackageDetailsSection,Cs as PolicyTypeSelectionModal,Fs as ScalingPoliciesDetailsSection,ks as ScalingPolicyAdditionalSettings,Fn as ScalingPolicyTypeRegistrar,Mn as ScalingPolicyTypeRegistry,Hs as ScalingPolicyWriter,Ms as ScalingProcessesDetailsSection,Ls as ScheduledActionsDetailsSection,zi as SecurityGroupSelector,Os as SecurityGroupsDetailsSection,Li as ServerGroupAdvancedSettings,$i as ServerGroupAdvancedSettingsCommon,ki as ServerGroupBasicSettings,Gi as ServerGroupCapacity,Ii as ServerGroupInstanceType,Pi as ServerGroupLoadBalancers,Di as ServerGroupSecurityGroups,Bi as ServerGroupSecurityGroupsRemoved,xi as ServerGroupZones,Ps as StepPolicyAction,Ar as SubnetSelectField,xr as SubnetSelectInput,Us as TagsDetailsSection,nr as TargetGroup,ai as TargetGroupDetails,ys as TargetMetricFields,bs as TargetTrackingAdditionalSettings,gs as TargetTrackingChart,Pn as VpcReader,Jn as applyHealthCheckInfoToTargetGroups,Qn as getAllTargetGroups,rs as getBaseImageName,Ns as name};
2
2
  //# sourceMappingURL=index.js.map