@spinnaker/google 2026.2.3 → 2026.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autoHealingPolicy/GceAutoHealingPolicyEditor.d.ts +24 -0
- package/dist/autoHealingPolicy/index.d.ts +1 -0
- package/dist/autoscalingPolicy/GceAutoscalingPolicyEditor.d.ts +8 -0
- package/dist/autoscalingPolicy/GceAutoscalingPolicyWriter.d.ts +25 -0
- package/dist/autoscalingPolicy/IGceAutoscalingPolicy.d.ts +33 -2
- package/dist/autoscalingPolicy/index.d.ts +2 -0
- package/dist/cache/cacheConfigurer.service.d.ts +2 -2
- package/dist/certificate/certificate.reader.d.ts +1 -2
- package/dist/common/xpnNaming.gce.service.d.ts +4 -2
- package/dist/domain/autoHealingPolicy.d.ts +0 -5
- package/dist/domain/serverGroup.d.ts +24 -0
- package/dist/gce.module.d.ts +3 -1
- package/dist/healthCheck/healthCheck.read.service.d.ts +1 -2
- package/dist/image/ImageSelect.d.ts +0 -1
- package/dist/image/image.reader.d.ts +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/custom/customInstanceBuilder.gce.service.d.ts +17 -2
- package/dist/instance/details/GceInstanceDetails.d.ts +24 -0
- package/dist/instance/gceInstanceType.service.d.ts +3 -2
- package/dist/instance/gceMultiInstanceTask.transformer.d.ts +3 -2
- package/dist/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.d.ts +34 -0
- package/dist/loadBalancer/configure/common/GceProxyLoadBalancerEditor.d.ts +36 -0
- package/dist/loadBalancer/configure/common/GceProxyLoadBalancerModal.d.ts +36 -0
- package/dist/loadBalancer/configure/common/gceLoadBalancerData.d.ts +47 -0
- package/dist/loadBalancer/configure/common/gceLoadBalancerModels.d.ts +106 -0
- package/dist/loadBalancer/configure/common/gceLoadBalancerSubmission.d.ts +10 -0
- package/dist/loadBalancer/configure/common/index.d.ts +4 -0
- package/dist/loadBalancer/configure/common/useGceLoadBalancerData.d.ts +5 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerEditor.d.ts +33 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.d.ts +12 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerModal.d.ts +37 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.d.ts +18 -0
- package/dist/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.d.ts +16 -0
- package/dist/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.d.ts +30 -0
- package/dist/loadBalancer/configure/network/GceNetworkLoadBalancerModal.d.ts +58 -0
- package/dist/loadBalancer/details/gceLoadBalancerDetails.d.ts +36 -0
- package/dist/loadBalancer/httpLoadBalancerUtils.service.d.ts +0 -1
- package/dist/loadBalancer/loadBalancer.setTransformer.d.ts +1 -5
- package/dist/loadBalancer/loadBalancer.transformer.d.ts +3 -2
- package/dist/pipeline/stages/bake/gceBakeStage.d.ts +2 -2
- package/dist/pipeline/stages/cloneServerGroup/gceCloneServerGroupStage.d.ts +1 -2
- package/dist/pipeline/stages/destroyAsg/gceDestroyAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableAsg/gceDisableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/disableCluster/gceDisableClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/enableAsg/gceEnableAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/findAmi/gceFindAmiStage.d.ts +1 -2
- package/dist/pipeline/stages/findImageFromTags/gceFindImageFromTagsStage.d.ts +1 -2
- package/dist/pipeline/stages/googleStageConfig.d.ts +40 -0
- package/dist/pipeline/stages/resizeAsg/gceResizeAsgStage.d.ts +1 -2
- package/dist/pipeline/stages/scaleDownCluster/gceScaleDownClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/shrinkCluster/gceShrinkClusterStage.d.ts +1 -2
- package/dist/pipeline/stages/tagImage/gceTagImageStage.d.ts +1 -2
- package/dist/securityGroup/configure/GceSecurityGroupModal.d.ts +50 -0
- package/dist/securityGroup/details/GceSecurityGroupDetails.d.ts +12 -0
- package/dist/securityGroup/securityGroup.reader.d.ts +3 -2
- package/dist/securityGroup/securityGroup.transformer.d.ts +5 -2
- package/dist/serverGroup/configure/serverGroupCommandBuilder.service.d.ts +6 -2
- package/dist/serverGroup/configure/serverGroupConfiguration.service.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/GceCloneServerGroupModal.d.ts +49 -0
- package/dist/serverGroup/configure/wizard/GceServerGroupWizard.helpers.d.ts +4 -0
- package/dist/serverGroup/configure/wizard/GceServerGroupWizard.types.d.ts +113 -0
- package/dist/serverGroup/configure/wizard/GceServerGroupWizardAdapter.d.ts +16 -0
- package/dist/serverGroup/configure/wizard/GceServerGroupWizardPage.d.ts +20 -0
- package/dist/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.d.ts +3 -0
- package/dist/serverGroup/configure/wizard/hiddenMetadataKeys.value.d.ts +1 -2
- package/dist/serverGroup/configure/wizard/index.d.ts +5 -0
- package/dist/serverGroup/configure/wizard/pages/AdvancedSettings.d.ts +20 -0
- package/dist/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.d.ts +10 -0
- package/dist/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.d.ts +21 -0
- package/dist/serverGroup/configure/wizard/pages/Policies.d.ts +14 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.d.ts +13 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupCapacity.d.ts +35 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupImageSettings.d.ts +11 -0
- package/dist/serverGroup/configure/wizard/pages/ServerGroupInstanceType.d.ts +29 -0
- package/dist/serverGroup/configure/wizard/pages/index.d.ts +8 -0
- package/dist/serverGroup/configure/wizard/securityGroups/tagManager.service.d.ts +17 -2
- package/dist/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.d.ts +19 -0
- package/dist/serverGroup/details/GceInstanceFlexibilityPolicyDetails.d.ts +6 -0
- package/dist/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.d.ts +11 -0
- package/dist/serverGroup/details/autoHealingPolicy/index.d.ts +2 -0
- package/dist/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.d.ts +21 -0
- package/dist/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.d.ts +12 -0
- package/dist/serverGroup/details/autoscalingPolicy/index.d.ts +2 -0
- package/dist/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.d.ts +26 -0
- package/dist/serverGroup/details/gceServerGroupDetails.d.ts +32 -0
- package/dist/serverGroup/details/resize/GceResizeServerGroupModal.d.ts +60 -0
- package/dist/serverGroup/details/rollback/GceRollbackServerGroupModal.d.ts +44 -0
- package/dist/serverGroup/details/stateful/StatefulMIGService.d.ts +2 -2
- package/dist/serverGroup/serverGroup.transformer.d.ts +2 -2
- package/dist/subnet/subnet.renderer.d.ts +4 -2
- package/dist/validation/ApplicationNameValidator.d.ts +6 -0
- package/package.json +3 -12
- package/src/autoHealingPolicy/GceAutoHealingPolicyEditor.spec.tsx +133 -0
- package/src/autoHealingPolicy/GceAutoHealingPolicyEditor.tsx +143 -0
- package/src/autoHealingPolicy/index.ts +1 -0
- package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.spec.tsx +241 -0
- package/src/autoscalingPolicy/GceAutoscalingPolicyEditor.tsx +479 -0
- package/src/autoscalingPolicy/GceAutoscalingPolicyWriter.spec.ts +135 -0
- package/src/autoscalingPolicy/GceAutoscalingPolicyWriter.ts +101 -0
- package/src/autoscalingPolicy/IGceAutoscalingPolicy.ts +37 -2
- package/src/autoscalingPolicy/index.ts +2 -0
- package/src/cache/cacheConfigurer.service.js +30 -22
- package/src/certificate/certificate.reader.ts +1 -6
- package/src/common/xpnNaming.gce.service.js +4 -12
- package/src/domain/autoHealingPolicy.ts +0 -6
- package/src/domain/serverGroup.ts +25 -0
- package/src/gce.module.spec.ts +638 -0
- package/src/gce.module.ts +106 -126
- package/src/healthCheck/healthCheck.read.service.ts +1 -5
- package/src/help/gce.help.ts +3 -7
- package/src/image/ImageSelect.tsx +0 -15
- package/src/image/image.reader.spec.ts +10 -0
- package/src/image/image.reader.ts +3 -3
- package/src/index.ts +1 -1
- package/src/instance/custom/customInstanceBuilder.gce.service.js +123 -141
- package/src/instance/details/GceInstanceDetails.spec.tsx +354 -0
- package/src/instance/details/GceInstanceDetails.tsx +419 -0
- package/src/instance/gceInstanceType.service.js +6 -11
- package/src/instance/gceMultiInstanceTask.transformer.js +11 -23
- package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.less +17 -0
- package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.spec.tsx +279 -0
- package/src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.tsx +169 -0
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.spec.tsx +353 -0
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.tsx +503 -0
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerModal.spec.tsx +313 -0
- package/src/loadBalancer/configure/common/GceProxyLoadBalancerModal.tsx +241 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerData.spec.ts +117 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerData.ts +191 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerModels.spec.ts +409 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerModels.ts +534 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.spec.ts +297 -0
- package/src/loadBalancer/configure/common/gceLoadBalancerSubmission.ts +127 -0
- package/src/loadBalancer/configure/common/index.spec.ts +17 -0
- package/src/loadBalancer/configure/common/index.ts +4 -0
- package/src/loadBalancer/configure/common/useGceLoadBalancerData.spec.tsx +78 -0
- package/src/loadBalancer/configure/common/useGceLoadBalancerData.ts +34 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.spec.tsx +472 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.tsx +586 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.spec.tsx +94 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.tsx +153 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.spec.tsx +326 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerModal.tsx +217 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.spec.tsx +86 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.tsx +284 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.spec.tsx +82 -0
- package/src/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.tsx +174 -0
- package/src/loadBalancer/configure/http/httpLoadBalancerWizard.component.less +31 -12
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.spec.tsx +175 -0
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.tsx +315 -0
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerModal.spec.tsx +303 -0
- package/src/loadBalancer/configure/network/GceNetworkLoadBalancerModal.tsx +368 -0
- package/src/loadBalancer/details/gceLoadBalancerDetails.spec.tsx +65 -0
- package/src/loadBalancer/details/gceLoadBalancerDetails.tsx +456 -0
- package/src/loadBalancer/httpLoadBalancerUtils.service.ts +3 -6
- package/src/loadBalancer/loadBalancer.setTransformer.ts +3 -12
- package/src/loadBalancer/loadBalancer.transformer.js +5 -9
- package/src/pipeline/stages/bake/gceBakeStage.js +362 -155
- package/src/pipeline/stages/cloneServerGroup/gceCloneServerGroupStage.js +17 -83
- package/src/pipeline/stages/destroyAsg/gceDestroyAsgStage.js +24 -62
- package/src/pipeline/stages/disableAsg/gceDisableAsgStage.js +22 -68
- package/src/pipeline/stages/disableCluster/gceDisableClusterStage.js +21 -79
- package/src/pipeline/stages/enableAsg/gceEnableAsgStage.js +17 -65
- package/src/pipeline/stages/findAmi/gceFindAmiStage.js +17 -79
- package/src/pipeline/stages/findImageFromTags/gceFindImageFromTagsStage.js +121 -35
- package/src/pipeline/stages/googleStageConfig.js +580 -0
- package/src/pipeline/stages/googleStageConfig.spec.js +44 -0
- package/src/pipeline/stages/resizeAsg/gceResizeAsgStage.js +26 -125
- package/src/pipeline/stages/scaleDownCluster/gceScaleDownClusterStage.js +24 -78
- package/src/pipeline/stages/shrinkCluster/gceShrinkClusterStage.js +19 -73
- package/src/pipeline/stages/tagImage/gceTagImageStage.js +165 -36
- package/src/securityGroup/configure/GceSecurityGroupModal.spec.tsx +381 -0
- package/src/securityGroup/configure/GceSecurityGroupModal.tsx +543 -0
- package/src/securityGroup/details/GceSecurityGroupDetails.spec.tsx +232 -0
- package/src/securityGroup/details/GceSecurityGroupDetails.tsx +261 -0
- package/src/securityGroup/securityGroup.reader.js +3 -11
- package/src/securityGroup/securityGroup.transformer.js +8 -15
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.js +563 -556
- package/src/serverGroup/configure/serverGroupCommandBuilder.service.spec.js +238 -0
- package/src/serverGroup/configure/serverGroupConfiguration.service.js +621 -653
- package/src/serverGroup/configure/serverGroupConfiguration.service.spec.js +9 -0
- package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.spec.tsx +1228 -0
- package/src/serverGroup/configure/wizard/GceCloneServerGroupModal.tsx +824 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizard.helpers.ts +51 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizard.types.ts +176 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizardAdapter.ts +115 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizardPage.spec.tsx +460 -0
- package/src/serverGroup/configure/wizard/GceServerGroupWizardPage.tsx +285 -0
- package/src/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.spec.tsx +125 -0
- package/src/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.tsx +127 -0
- package/src/serverGroup/configure/wizard/hiddenMetadataKeys.value.js +2 -7
- package/src/serverGroup/configure/wizard/index.ts +5 -0
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.spec.tsx +339 -0
- package/src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx +871 -0
- package/src/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.spec.tsx +196 -0
- package/src/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.tsx +278 -0
- package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.spec.tsx +643 -0
- package/src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.tsx +851 -0
- package/src/serverGroup/configure/wizard/pages/Policies.spec.tsx +317 -0
- package/src/serverGroup/configure/wizard/pages/Policies.tsx +293 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.spec.tsx +418 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx +247 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.spec.tsx +659 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupCapacity.tsx +470 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.spec.tsx +146 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.tsx +163 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.spec.tsx +536 -0
- package/src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx +728 -0
- package/src/serverGroup/configure/wizard/pages/index.ts +8 -0
- package/src/serverGroup/configure/wizard/securityGroups/tagManager.service.js +186 -182
- package/src/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.spec.tsx +390 -0
- package/src/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.tsx +310 -0
- package/src/serverGroup/details/GceInstanceFlexibilityPolicyDetails.spec.tsx +32 -0
- package/src/serverGroup/details/GceInstanceFlexibilityPolicyDetails.tsx +36 -0
- package/src/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.spec.tsx +192 -0
- package/src/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.tsx +83 -0
- package/src/serverGroup/details/autoHealingPolicy/index.ts +2 -0
- package/src/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.spec.tsx +94 -0
- package/src/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.tsx +102 -0
- package/src/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.spec.tsx +200 -0
- package/src/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.tsx +153 -0
- package/src/serverGroup/details/autoscalingPolicy/index.ts +2 -0
- package/src/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.spec.tsx +227 -0
- package/src/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.tsx +196 -0
- package/src/serverGroup/details/gceServerGroupDetails.spec.tsx +290 -0
- package/src/serverGroup/details/gceServerGroupDetails.tsx +372 -0
- package/src/serverGroup/details/resize/GceResizeServerGroupModal.spec.tsx +390 -0
- package/src/serverGroup/details/resize/GceResizeServerGroupModal.tsx +346 -0
- package/src/serverGroup/details/rollback/GceRollbackServerGroupModal.spec.tsx +168 -0
- package/src/serverGroup/details/rollback/GceRollbackServerGroupModal.tsx +196 -0
- package/src/serverGroup/details/stateful/UpdateBootImageButton.tsx +1 -1
- package/src/serverGroup/serverGroup.transformer.js +73 -54
- package/src/serverGroup/serverGroup.transformer.spec.js +90 -15
- package/src/subnet/subnet.renderer.js +10 -15
- package/src/validation/ApplicationNameValidator.spec.ts +47 -0
- package/src/validation/ApplicationNameValidator.ts +89 -0
- package/dist/address/address.reader.d.ts +0 -15
- package/dist/autoscalingPolicy/autoscalingPolicy.write.service.d.ts +0 -2
- package/dist/autoscalingPolicy/components/basicSettings/basicSettings.component.d.ts +0 -2
- package/dist/autoscalingPolicy/components/metricSettings/GcePredictiveAutoscaling.d.ts +0 -1
- package/dist/autoscalingPolicy/components/metricSettings/metricSettings.component.d.ts +0 -2
- package/dist/autoscalingPolicy/components/scalingSchedules/scalingSchedules.component.d.ts +0 -2
- package/dist/autoscalingPolicy/components/scalingSchedules/timeZoneSelect.d.ts +0 -13
- package/dist/backendService/backendService.reader.d.ts +0 -2
- package/dist/cache/cacheRefresh.component.d.ts +0 -1
- package/dist/common/footer.directive.d.ts +0 -2
- package/dist/gceNetworkSelectField.directive.d.ts +0 -2
- package/dist/gceRegionSelectField.directive.d.ts +0 -2
- package/dist/instance/custom/customInstance.filter.d.ts +0 -2
- package/dist/instance/details/instance.details.controller.d.ts +0 -2
- package/dist/interceptors/iap.interceptor.d.ts +0 -8
- package/dist/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.d.ts +0 -1
- package/dist/loadBalancer/configure/choice/gceLoadBalancerPipelineModal.d.ts +0 -9
- package/dist/loadBalancer/configure/choice/loadBalancerTypeToWizardMap.constant.d.ts +0 -10
- package/dist/loadBalancer/configure/common/addressSelector.component.d.ts +0 -1
- package/dist/loadBalancer/configure/common/commonLoadBalancer.controller.d.ts +0 -17
- package/dist/loadBalancer/configure/common/commonLoadBalancerCommandBuilder.service.d.ts +0 -23
- package/dist/loadBalancer/configure/common/healthCheck.component.d.ts +0 -1
- package/dist/loadBalancer/configure/http/backendService/backendService.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/basicSettings/basicSettings.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/commandBuilder.service.d.ts +0 -2
- package/dist/loadBalancer/configure/http/createHttpLoadBalancer.controller.d.ts +0 -2
- package/dist/loadBalancer/configure/http/healthCheck/healthCheck.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/hostRule/hostRule.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/httpLoadBalancer.write.service.d.ts +0 -2
- package/dist/loadBalancer/configure/http/listeners/listener.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/pathRule/pathRule.component.d.ts +0 -2
- package/dist/loadBalancer/configure/http/transformer.service.d.ts +0 -2
- package/dist/loadBalancer/configure/internal/gceCreateInternalLoadBalancer.controller.d.ts +0 -1
- package/dist/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.d.ts +0 -3
- package/dist/loadBalancer/configure/network/createLoadBalancer.controller.d.ts +0 -2
- package/dist/loadBalancer/configure/ssl/gceCreateSslLoadBalancer.controller.d.ts +0 -1
- package/dist/loadBalancer/configure/tcp/gceCreateTcpLoadBalancer.controller.d.ts +0 -1
- package/dist/loadBalancer/details/backendService/backendService.component.d.ts +0 -1
- package/dist/loadBalancer/details/backendService/sessionAffinity.filter.d.ts +0 -1
- package/dist/loadBalancer/details/deleteModal/deleteModal.controller.d.ts +0 -1
- package/dist/loadBalancer/details/healthCheck/healthCheck.component.d.ts +0 -2
- package/dist/loadBalancer/details/hostAndPathRules/hostAndPathRules.controller.d.ts +0 -2
- package/dist/loadBalancer/details/hostAndPathRules/hostAndPathRules.service.d.ts +0 -2
- package/dist/loadBalancer/details/hostAndPathRules/hostAndPathRulesButton.component.d.ts +0 -2
- package/dist/loadBalancer/details/loadBalancerDetail.controller.d.ts +0 -2
- package/dist/loadBalancer/details/loadBalancerType/loadBalancerType.component.d.ts +0 -2
- package/dist/pipeline/stages/bake/bakeExecutionDetails.controller.d.ts +0 -2
- package/dist/securityGroup/clone/cloneSecurityGroup.controller.d.ts +0 -2
- package/dist/securityGroup/configure/ConfigSecurityGroupMixin.controller.d.ts +0 -2
- package/dist/securityGroup/configure/createSecurityGroup.controller.d.ts +0 -2
- package/dist/securityGroup/configure/editSecurityGroup.controller.d.ts +0 -2
- package/dist/securityGroup/details/securityGroupDetail.controller.d.ts +0 -2
- package/dist/securityGroup/securityGroupHelpText.service.d.ts +0 -13
- package/dist/serverGroup/configure/serverGroup.configure.gce.module.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/GceAcceleratorConfigurer.d.ts +0 -16
- package/dist/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/advancedSettings/diskConfigurer.component.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/autoHealingPolicy/autoHealingPolicySelector.component.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/capacity/advancedCapacitySelector.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/capacity/simpleCapacitySelector.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/cloneServerGroup.gce.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/customInstance/customInstanceConfigurer.component.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/loadBalancers/elSevenOptions/backendServiceSelector.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/loadBalancers/elSevenOptions/elSevenOptionsGenerator.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/loadBalancers/loadBalancerSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/loadBalancingPolicy/loadBalancingPolicySelector.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/location/basicSettings.controller.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroups/securityGroupSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroups/securityGroupsRemoved.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroups/tagSelector.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/securityGroups/tagSelectorGenerator.component.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/zones/regionalSelector.directive.d.ts +0 -2
- package/dist/serverGroup/configure/wizard/zones/targetShapeSelector.directive.d.ts +0 -1
- package/dist/serverGroup/configure/wizard/zones/zoneSelector.directive.d.ts +0 -2
- package/dist/serverGroup/details/ServerGroupDiskDescriptions.d.ts +0 -1
- package/dist/serverGroup/details/autoHealingPolicy/addAutoHealingPolicyButton.component.d.ts +0 -1
- package/dist/serverGroup/details/autoHealingPolicy/autoHealingPolicy.component.d.ts +0 -1
- package/dist/serverGroup/details/autoHealingPolicy/modal/upsertAutoHealingPolicy.modal.controller.d.ts +0 -2
- package/dist/serverGroup/details/autoscalingPolicy/addAutoscalingPolicyButton.component.d.ts +0 -2
- package/dist/serverGroup/details/autoscalingPolicy/autoscalingPolicy.directive.d.ts +0 -2
- package/dist/serverGroup/details/autoscalingPolicy/modal/GceScaleInControls.d.ts +0 -1
- package/dist/serverGroup/details/autoscalingPolicy/modal/upsertAutoscalingPolicy.modal.controller.d.ts +0 -2
- package/dist/serverGroup/details/resize/resizeAutoscalingPolicy.component.d.ts +0 -2
- package/dist/serverGroup/details/resize/resizeCapacity.component.d.ts +0 -2
- package/dist/serverGroup/details/resize/resizeServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/rollback/rollbackServerGroup.controller.d.ts +0 -2
- package/dist/serverGroup/details/serverGroup.details.gce.module.d.ts +0 -2
- package/dist/serverGroup/details/serverGroupDetails.gce.controller.d.ts +0 -2
- package/dist/subnet/subnetSelectField.directive.d.ts +0 -2
- package/dist/validation/applicationName.validator.d.ts +0 -2
- package/src/address/address.reader.ts +0 -61
- package/src/applicationProviderFields/gceFields.html +0 -13
- package/src/autoscalingPolicy/autoscalingPolicy.write.service.js +0 -83
- package/src/autoscalingPolicy/components/basicSettings/basicSettings.component.html +0 -71
- package/src/autoscalingPolicy/components/basicSettings/basicSettings.component.js +0 -20
- package/src/autoscalingPolicy/components/metricSettings/GcePredictiveAutoscaling.tsx +0 -54
- package/src/autoscalingPolicy/components/metricSettings/metricSettings.component.html +0 -208
- package/src/autoscalingPolicy/components/metricSettings/metricSettings.component.js +0 -108
- package/src/autoscalingPolicy/components/scalingSchedules/scalingSchedules.component.html +0 -84
- package/src/autoscalingPolicy/components/scalingSchedules/scalingSchedules.component.js +0 -61
- package/src/autoscalingPolicy/components/scalingSchedules/timeZoneSelect.tsx +0 -63
- package/src/backendService/backendService.reader.js +0 -28
- package/src/cache/cacheRefresh.component.html +0 -17
- package/src/cache/cacheRefresh.component.ts +0 -53
- package/src/cache/cacheRefreshTooltip.html +0 -3
- package/src/common/footer.directive.html +0 -7
- package/src/common/footer.directive.js +0 -22
- package/src/gceNetworkSelectField.directive.js +0 -22
- package/src/gceRegionSelectField.directive.js +0 -22
- package/src/instance/custom/customInstance.filter.js +0 -26
- package/src/instance/details/instance.details.controller.js +0 -518
- package/src/instance/details/instance.details.controller.spec.js +0 -27
- package/src/instance/details/instanceDetails.html +0 -248
- package/src/instance/gceInstanceType.service.spec.js +0 -19
- package/src/interceptors/iap.interceptor.ts +0 -36
- package/src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.html +0 -33
- package/src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.spec.js +0 -66
- package/src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.ts +0 -64
- package/src/loadBalancer/configure/choice/gceLoadBalancerPipelineModal.ts +0 -47
- package/src/loadBalancer/configure/choice/loadBalancerTypeToWizardMap.constant.ts +0 -58
- package/src/loadBalancer/configure/common/addressSelector.component.ts +0 -47
- package/src/loadBalancer/configure/common/commonAdvancedSettingsPage.html +0 -32
- package/src/loadBalancer/configure/common/commonCreateLoadBalancer.html +0 -41
- package/src/loadBalancer/configure/common/commonEditLoadBalancer.html +0 -38
- package/src/loadBalancer/configure/common/commonHealthCheckPage.html +0 -16
- package/src/loadBalancer/configure/common/commonLoadBalancer.controller.ts +0 -56
- package/src/loadBalancer/configure/common/commonLoadBalancerCommandBuilder.service.ts +0 -87
- package/src/loadBalancer/configure/common/healthCheck.component.html +0 -179
- package/src/loadBalancer/configure/common/healthCheck.component.ts +0 -82
- package/src/loadBalancer/configure/gceL4LoadBalancerPipeline.spec.js +0 -143
- package/src/loadBalancer/configure/http/backendService/backendService.component.html +0 -157
- package/src/loadBalancer/configure/http/backendService/backendService.component.js +0 -80
- package/src/loadBalancer/configure/http/backendService/backendServices.html +0 -57
- package/src/loadBalancer/configure/http/basicSettings/basicSettings.component.html +0 -105
- package/src/loadBalancer/configure/http/basicSettings/basicSettings.component.js +0 -46
- package/src/loadBalancer/configure/http/basicSettings/basicSettings.html +0 -6
- package/src/loadBalancer/configure/http/commandBuilder.service.js +0 -404
- package/src/loadBalancer/configure/http/createHttpLoadBalancer.controller.js +0 -184
- package/src/loadBalancer/configure/http/createHttpLoadBalancer.controller.spec.js +0 -96
- package/src/loadBalancer/configure/http/createHttpLoadBalancer.html +0 -39
- package/src/loadBalancer/configure/http/defaultService/defaultService.html +0 -24
- package/src/loadBalancer/configure/http/editHttpLoadBalancer.html +0 -36
- package/src/loadBalancer/configure/http/healthCheck/healthCheck.component.html +0 -180
- package/src/loadBalancer/configure/http/healthCheck/healthCheck.component.js +0 -69
- package/src/loadBalancer/configure/http/healthCheck/healthChecks.html +0 -55
- package/src/loadBalancer/configure/http/hostRule/hostRule.component.html +0 -60
- package/src/loadBalancer/configure/http/hostRule/hostRule.component.js +0 -35
- package/src/loadBalancer/configure/http/hostRule/hostRules.html +0 -16
- package/src/loadBalancer/configure/http/httpLoadBalancer.write.service.js +0 -56
- package/src/loadBalancer/configure/http/listeners/listener.component.html +0 -245
- package/src/loadBalancer/configure/http/listeners/listener.component.js +0 -164
- package/src/loadBalancer/configure/http/listeners/listener.component.spec.js +0 -125
- package/src/loadBalancer/configure/http/listeners/listeners.html +0 -17
- package/src/loadBalancer/configure/http/pathRule/pathRule.component.html +0 -51
- package/src/loadBalancer/configure/http/pathRule/pathRule.component.js +0 -16
- package/src/loadBalancer/configure/http/transformer.service.js +0 -191
- package/src/loadBalancer/configure/http/transformer.service.spec.js +0 -182
- package/src/loadBalancer/configure/internal/createLoadBalancerProperties.html +0 -98
- package/src/loadBalancer/configure/internal/gceCreateInternalLoadBalancer.controller.ts +0 -284
- package/src/loadBalancer/configure/internal/listener.html +0 -41
- package/src/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.spec.js +0 -89
- package/src/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.ts +0 -196
- package/src/loadBalancer/configure/network/advancedSettings.html +0 -54
- package/src/loadBalancer/configure/network/createLoadBalancer.controller.js +0 -240
- package/src/loadBalancer/configure/network/createLoadBalancer.controller.spec.js +0 -118
- package/src/loadBalancer/configure/network/createLoadBalancer.html +0 -25
- package/src/loadBalancer/configure/network/createLoadBalancerProperties.html +0 -86
- package/src/loadBalancer/configure/network/editLoadBalancer.html +0 -29
- package/src/loadBalancer/configure/network/healthCheck.html +0 -36
- package/src/loadBalancer/configure/network/listeners.html +0 -55
- package/src/loadBalancer/configure/ssl/backendService.html +0 -31
- package/src/loadBalancer/configure/ssl/createLoadBalancerProperties.html +0 -86
- package/src/loadBalancer/configure/ssl/gceCreateSslLoadBalancer.controller.ts +0 -244
- package/src/loadBalancer/configure/ssl/listener.html +0 -43
- package/src/loadBalancer/configure/tcp/backendService.html +0 -31
- package/src/loadBalancer/configure/tcp/createLoadBalancerProperties.html +0 -86
- package/src/loadBalancer/configure/tcp/gceCreateTcpLoadBalancer.controller.ts +0 -234
- package/src/loadBalancer/configure/tcp/listener.html +0 -15
- package/src/loadBalancer/details/backendService/backendService.component.ts +0 -23
- package/src/loadBalancer/details/backendService/sessionAffinity.filter.ts +0 -11
- package/src/loadBalancer/details/deleteModal/deleteModal.controller.ts +0 -105
- package/src/loadBalancer/details/deleteModal/deleteModal.html +0 -31
- package/src/loadBalancer/details/healthCheck/healthCheck.component.html +0 -14
- package/src/loadBalancer/details/healthCheck/healthCheck.component.js +0 -13
- package/src/loadBalancer/details/hostAndPathRules/hostAndPathRules.controller.js +0 -23
- package/src/loadBalancer/details/hostAndPathRules/hostAndPathRules.modal.html +0 -40
- package/src/loadBalancer/details/hostAndPathRules/hostAndPathRules.service.js +0 -41
- package/src/loadBalancer/details/hostAndPathRules/hostAndPathRulesButton.component.js +0 -39
- package/src/loadBalancer/details/loadBalancerDetail.controller.js +0 -260
- package/src/loadBalancer/details/loadBalancerDetail.controller.spec.js +0 -41
- package/src/loadBalancer/details/loadBalancerDetails.html +0 -202
- package/src/loadBalancer/details/loadBalancerType/loadBalancerType.component.js +0 -31
- package/src/loadBalancer/details/loadBalancerType/loadBalancerType.component.spec.js +0 -85
- package/src/networkSelectField.directive.html +0 -14
- package/src/pipeline/stages/bake/bakeExecutionDetails.controller.js +0 -40
- package/src/pipeline/stages/bake/bakeExecutionDetails.html +0 -60
- package/src/pipeline/stages/bake/bakeStage.html +0 -117
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStage.html +0 -99
- package/src/pipeline/stages/cloneServerGroup/cloneServerGroupStepLabel.html +0 -1
- package/src/pipeline/stages/destroyAsg/destroyAsgStage.html +0 -9
- package/src/pipeline/stages/destroyAsg/destroyAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableAsg/disableAsgStage.html +0 -11
- package/src/pipeline/stages/disableAsg/disableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/disableCluster/disableClusterStage.html +0 -26
- package/src/pipeline/stages/enableAsg/enableAsgStage.html +0 -11
- package/src/pipeline/stages/enableAsg/enableAsgStepLabel.html +0 -1
- package/src/pipeline/stages/findAmi/findAmiStage.html +0 -20
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsExecutionDetails.html +0 -40
- package/src/pipeline/stages/findImageFromTags/findImageFromTagsStage.html +0 -8
- package/src/pipeline/stages/resizeAsg/resizeAsgStage.html +0 -97
- package/src/pipeline/stages/resizeAsg/resizeAsgStepLabel.html +0 -1
- package/src/pipeline/stages/scaleDownCluster/scaleDownClusterStage.html +0 -35
- package/src/pipeline/stages/shrinkCluster/shrinkClusterStage.html +0 -34
- package/src/pipeline/stages/tagImage/tagImageExecutionDetails.html +0 -39
- package/src/pipeline/stages/tagImage/tagImageStage.html +0 -14
- package/src/regionSelectField.directive.html +0 -18
- package/src/securityGroup/clone/cloneSecurityGroup.controller.js +0 -85
- package/src/securityGroup/clone/cloneSecurityGroup.html +0 -25
- package/src/securityGroup/configure/ConfigSecurityGroupMixin.controller.js +0 -318
- package/src/securityGroup/configure/createSecurityGroup.controller.js +0 -62
- package/src/securityGroup/configure/createSecurityGroup.html +0 -25
- package/src/securityGroup/configure/createSecurityGroupIngress.html +0 -81
- package/src/securityGroup/configure/createSecurityGroupProperties.html +0 -70
- package/src/securityGroup/configure/createSecurityGroupSourceFilters.html +0 -56
- package/src/securityGroup/configure/createSecurityGroupTargets.html +0 -43
- package/src/securityGroup/configure/editSecurityGroup.controller.js +0 -132
- package/src/securityGroup/configure/editSecurityGroup.html +0 -26
- package/src/securityGroup/details/securityGroupDetail.controller.js +0 -258
- package/src/securityGroup/details/securityGroupDetail.html +0 -171
- package/src/securityGroup/securityGroupHelpText.service.spec.ts +0 -102
- package/src/securityGroup/securityGroupHelpText.service.ts +0 -83
- package/src/serverGroup/configure/serverGroup.configure.gce.module.js +0 -59
- package/src/serverGroup/configure/wizard/advancedSettings/GceAcceleratorConfigurer.tsx +0 -222
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.directive.html +0 -277
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettings.html +0 -9
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.js +0 -71
- package/src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.spec.js +0 -58
- package/src/serverGroup/configure/wizard/advancedSettings/diskConfigurer.component.ts +0 -199
- package/src/serverGroup/configure/wizard/autoHealingPolicy/autoHealingPolicy.html +0 -20
- package/src/serverGroup/configure/wizard/autoHealingPolicy/autoHealingPolicySelector.component.html +0 -90
- package/src/serverGroup/configure/wizard/autoHealingPolicy/autoHealingPolicySelector.component.ts +0 -70
- package/src/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicy.html +0 -20
- package/src/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component.html +0 -21
- package/src/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component.js +0 -44
- package/src/serverGroup/configure/wizard/capacity/advancedCapacitySelector.component.html +0 -42
- package/src/serverGroup/configure/wizard/capacity/advancedCapacitySelector.component.js +0 -16
- package/src/serverGroup/configure/wizard/capacity/capacity.html +0 -16
- package/src/serverGroup/configure/wizard/capacity/simpleCapacitySelector.component.html +0 -14
- package/src/serverGroup/configure/wizard/capacity/simpleCapacitySelector.component.js +0 -22
- package/src/serverGroup/configure/wizard/capacity/simpleCapacitySelector.component.spec.js +0 -31
- package/src/serverGroup/configure/wizard/capacity/zones.html +0 -7
- package/src/serverGroup/configure/wizard/cloneServerGroup.gce.controller.js +0 -476
- package/src/serverGroup/configure/wizard/customInstance/customInstanceBuilder.html +0 -13
- package/src/serverGroup/configure/wizard/customInstance/customInstanceConfigurer.component.ts +0 -21
- package/src/serverGroup/configure/wizard/instanceType/instanceType.html +0 -11
- package/src/serverGroup/configure/wizard/loadBalancers/elSevenOptions/backendServiceSelector.component.html +0 -21
- package/src/serverGroup/configure/wizard/loadBalancers/elSevenOptions/backendServiceSelector.component.js +0 -33
- package/src/serverGroup/configure/wizard/loadBalancers/elSevenOptions/elSevenOptionsGenerator.component.js +0 -42
- package/src/serverGroup/configure/wizard/loadBalancers/loadBalancerSelector.directive.html +0 -53
- package/src/serverGroup/configure/wizard/loadBalancers/loadBalancerSelector.directive.js +0 -55
- package/src/serverGroup/configure/wizard/loadBalancers/loadBalancers.html +0 -5
- package/src/serverGroup/configure/wizard/loadBalancingPolicy/loadBalancingPolicySelector.component.html +0 -182
- package/src/serverGroup/configure/wizard/loadBalancingPolicy/loadBalancingPolicySelector.component.less +0 -11
- package/src/serverGroup/configure/wizard/loadBalancingPolicy/loadBalancingPolicySelector.component.ts +0 -153
- package/src/serverGroup/configure/wizard/location/basicSettings.controller.js +0 -139
- package/src/serverGroup/configure/wizard/location/basicSettings.html +0 -167
- package/src/serverGroup/configure/wizard/securityGroups/securityGroupSelector.directive.html +0 -66
- package/src/serverGroup/configure/wizard/securityGroups/securityGroupSelector.directive.js +0 -48
- package/src/serverGroup/configure/wizard/securityGroups/securityGroups.html +0 -4
- package/src/serverGroup/configure/wizard/securityGroups/securityGroupsRemoved.directive.html +0 -14
- package/src/serverGroup/configure/wizard/securityGroups/securityGroupsRemoved.directive.js +0 -25
- package/src/serverGroup/configure/wizard/securityGroups/tagSelector.component.html +0 -26
- package/src/serverGroup/configure/wizard/securityGroups/tagSelector.component.js +0 -31
- package/src/serverGroup/configure/wizard/securityGroups/tagSelectorGenerator.component.js +0 -44
- package/src/serverGroup/configure/wizard/serverGroupWizard.html +0 -52
- package/src/serverGroup/configure/wizard/templateSelection/templateSelection.html +0 -9
- package/src/serverGroup/configure/wizard/zones/regionalSelector.directive.html +0 -13
- package/src/serverGroup/configure/wizard/zones/regionalSelector.directive.js +0 -21
- package/src/serverGroup/configure/wizard/zones/targetShapeSelector.directive.html +0 -13
- package/src/serverGroup/configure/wizard/zones/targetShapeSelector.directive.ts +0 -20
- package/src/serverGroup/configure/wizard/zones/zoneSelector.directive.html +0 -24
- package/src/serverGroup/configure/wizard/zones/zoneSelector.directive.js +0 -21
- package/src/serverGroup/details/ServerGroupDiskDescriptions.tsx +0 -97
- package/src/serverGroup/details/autoHealingPolicy/addAutoHealingPolicyButton.component.ts +0 -38
- package/src/serverGroup/details/autoHealingPolicy/autoHealingPolicy.component.ts +0 -73
- package/src/serverGroup/details/autoHealingPolicy/modal/upsertAutoHealingPolicy.modal.controller.ts +0 -88
- package/src/serverGroup/details/autoHealingPolicy/modal/upsertAutoHealingPolicy.modal.html +0 -29
- package/src/serverGroup/details/autoscalingPolicy/addAutoscalingPolicyButton.component.js +0 -38
- package/src/serverGroup/details/autoscalingPolicy/autoscalingPolicy.directive.html +0 -49
- package/src/serverGroup/details/autoscalingPolicy/autoscalingPolicy.directive.js +0 -138
- package/src/serverGroup/details/autoscalingPolicy/modal/GceScaleInControls.tsx +0 -137
- package/src/serverGroup/details/autoscalingPolicy/modal/upsertAutoscalingPolicy.modal.controller.js +0 -56
- package/src/serverGroup/details/autoscalingPolicy/modal/upsertAutoscalingPolicy.modal.html +0 -38
- package/src/serverGroup/details/resize/resizeAutoscalingPolicy.component.html +0 -55
- package/src/serverGroup/details/resize/resizeAutoscalingPolicy.component.js +0 -60
- package/src/serverGroup/details/resize/resizeCapacity.component.html +0 -36
- package/src/serverGroup/details/resize/resizeCapacity.component.js +0 -46
- package/src/serverGroup/details/resize/resizeServerGroup.controller.js +0 -64
- package/src/serverGroup/details/resize/resizeServerGroup.controller.spec.js +0 -119
- package/src/serverGroup/details/resize/resizeServerGroup.html +0 -41
- package/src/serverGroup/details/rollback/rollbackServerGroup.controller.js +0 -73
- package/src/serverGroup/details/rollback/rollbackServerGroup.html +0 -43
- package/src/serverGroup/details/serverGroup.details.gce.module.js +0 -17
- package/src/serverGroup/details/serverGroupDetails.gce.controller.js +0 -511
- package/src/serverGroup/details/serverGroupDetails.gce.controller.spec.js +0 -26
- package/src/serverGroup/details/serverGroupDetails.html +0 -359
- package/src/serverGroup/details/serverGroupDetails.less +0 -3
- package/src/subnet/subnetSelectField.directive.html +0 -21
- package/src/subnet/subnetSelectField.directive.js +0 -24
- package/src/validation/applicationName.validator.js +0 -114
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js","../src/autoscalingPolicy/GceAutoScalingFieldLayout.tsx","../src/autoscalingPolicy/IGceAutoscalingPolicy.ts","../src/gce.settings.ts","../src/autoscalingPolicy/components/metricSettings/GcePredictiveAutoscaling.tsx","../src/address/address.reader.ts","../src/backendService/backendService.reader.js","../src/healthCheck/healthCheck.read.service.ts","../src/cache/cacheConfigurer.service.js","../src/common/xpnNaming.gce.service.js","../src/help/gce.help.ts","../src/image/image.reader.ts","../src/image/ImageSelect.tsx","../src/instance/custom/customInstanceBuilder.gce.service.js","../src/instance/custom/customInstance.filter.js","../src/loadBalancer/httpLoadBalancerUtils.service.ts","../src/instance/details/instance.details.controller.js","../src/instance/gceInstanceTypeDisks.ts","../src/instance/gceInstanceType.service.js","../src/instance/gceMultiInstanceTask.transformer.js","../src/interceptors/iap.interceptor.ts","../src/loadBalancer/configure/choice/loadBalancerTypeToWizardMap.constant.ts","../src/loadBalancer/configure/choice/gceLoadBalancerChoice.modal.ts","../src/loadBalancer/configure/choice/gceLoadBalancerPipelineModal.ts","../src/loadBalancer/configure/http/templates.ts","../src/loadBalancer/configure/http/backendService/backendService.component.js","../src/loadBalancer/configure/http/basicSettings/basicSettings.component.js","../src/cache/cacheRefresh.component.ts","../src/certificate/certificate.reader.ts","../src/loadBalancer/configure/common/sessionAffinityNameMaps.ts","../src/loadBalancer/configure/http/transformer.service.js","../src/loadBalancer/configure/http/commandBuilder.service.js","../src/loadBalancer/details/hostAndPathRules/hostAndPathRules.service.js","../src/loadBalancer/details/hostAndPathRules/hostAndPathRules.controller.js","../src/loadBalancer/details/hostAndPathRules/hostAndPathRulesButton.component.js","../src/loadBalancer/configure/http/healthCheck/healthCheck.component.js","../src/loadBalancer/configure/http/pathRule/pathRule.component.js","../src/loadBalancer/configure/http/hostRule/hostRule.component.js","../src/loadBalancer/configure/http/httpLoadBalancer.write.service.js","../src/loadBalancer/configure/common/addressSelector.component.ts","../src/loadBalancer/configure/http/listeners/listener.component.js","../src/loadBalancer/configure/http/createHttpLoadBalancer.controller.js","../src/loadBalancer/configure/common/commonLoadBalancer.controller.ts","../src/loadBalancer/configure/common/commonLoadBalancerCommandBuilder.service.ts","../src/loadBalancer/configure/common/healthCheck.component.ts","../src/loadBalancer/configure/internal/gceCreateInternalLoadBalancer.controller.ts","../src/loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller.ts","../src/gceRegionSelectField.directive.js","../src/loadBalancer/loadBalancer.transformer.js","../src/loadBalancer/configure/network/createLoadBalancer.controller.js","../src/loadBalancer/configure/ssl/gceCreateSslLoadBalancer.controller.ts","../src/loadBalancer/configure/tcp/gceCreateTcpLoadBalancer.controller.ts","../src/loadBalancer/details/backendService/backendService.component.ts","../src/loadBalancer/details/backendService/sessionAffinity.filter.ts","../src/loadBalancer/details/deleteModal/deleteModal.controller.ts","../src/loadBalancer/details/healthCheck/healthCheck.component.js","../src/loadBalancer/details/loadBalancerType/loadBalancerType.component.js","../src/loadBalancer/details/loadBalancerDetail.controller.js","../src/loadBalancer/loadBalancer.setTransformer.ts","../src/pipeline/stages/bake/bakeExecutionDetails.controller.js","../src/pipeline/stages/bake/gceBakeStage.js","../src/pipeline/stages/cloneServerGroup/gceCloneServerGroupStage.js","../src/pipeline/stages/destroyAsg/gceDestroyAsgStage.js","../src/pipeline/stages/disableAsg/gceDisableAsgStage.js","../src/pipeline/stages/disableCluster/gceDisableClusterStage.js","../src/pipeline/stages/enableAsg/gceEnableAsgStage.js","../src/pipeline/stages/findAmi/gceFindAmiStage.js","../src/pipeline/stages/findImageFromTags/gceFindImageFromTagsStage.js","../src/pipeline/stages/resizeAsg/gceResizeAsgStage.js","../src/pipeline/stages/scaleDownCluster/gceScaleDownClusterStage.js","../src/pipeline/stages/shrinkCluster/gceShrinkClusterStage.js","../src/pipeline/stages/tagImage/gceTagImageStage.js","../src/securityGroup/configure/createSecurityGroup.controller.js","../src/securityGroup/configure/editSecurityGroup.controller.js","../src/securityGroup/securityGroupHelpText.service.ts","../src/securityGroup/configure/ConfigSecurityGroupMixin.controller.js","../src/securityGroup/clone/cloneSecurityGroup.controller.js","../src/securityGroup/details/securityGroupDetail.controller.js","../src/securityGroup/securityGroup.reader.js","../src/securityGroup/securityGroup.transformer.js","../src/autoscalingPolicy/components/basicSettings/basicSettings.component.js","../src/autoscalingPolicy/components/metricSettings/metricSettings.component.js","../src/autoscalingPolicy/components/scalingSchedules/scalingSchedules.component.js","../src/autoscalingPolicy/components/scalingSchedules/timeZoneSelect.tsx","../src/serverGroup/serverGroup.transformer.js","../src/healthCheck/healthCheckUtils.ts","../src/serverGroup/configure/wizard/advancedSettings/gceAccelerator.service.ts","../src/serverGroup/configure/wizard/securityGroups/tagManager.service.js","../src/serverGroup/configure/serverGroupConfiguration.service.js","../src/serverGroup/configure/wizard/advancedSettings/GceAcceleratorConfigurer.tsx","../src/serverGroup/configure/wizard/advancedSettings/advancedSettingsSelector.directive.js","../src/serverGroup/configure/wizard/advancedSettings/diskConfigurer.component.ts","../src/serverGroup/configure/wizard/autoHealingPolicy/autoHealingPolicySelector.component.ts","../src/serverGroup/configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component.js","../src/serverGroup/configure/wizard/capacity/advancedCapacitySelector.component.js","../src/serverGroup/configure/wizard/capacity/simpleCapacitySelector.component.js","../src/serverGroup/configure/wizard/customInstance/CustomInstanceConfigurer.tsx","../src/serverGroup/configure/wizard/customInstance/customInstanceConfigurer.component.ts","../src/serverGroup/configure/wizard/loadBalancers/elSevenOptions/backendServiceSelector.component.js","../src/serverGroup/configure/wizard/loadBalancers/elSevenOptions/elSevenOptionsGenerator.component.js","../src/serverGroup/configure/wizard/loadBalancers/loadBalancerSelector.directive.js","../src/serverGroup/configure/wizard/loadBalancingPolicy/loadBalancingPolicySelector.component.ts","../src/gceNetworkSelectField.directive.js","../src/subnet/subnetSelectField.directive.js","../src/serverGroup/configure/wizard/location/basicSettings.controller.js","../src/serverGroup/configure/wizard/securityGroups/tagSelector.component.js","../src/serverGroup/configure/wizard/securityGroups/tagSelectorGenerator.component.js","../src/serverGroup/configure/wizard/securityGroups/securityGroupSelector.directive.js","../src/serverGroup/configure/wizard/securityGroups/securityGroupsRemoved.directive.js","../src/serverGroup/configure/wizard/zones/regionalSelector.directive.js","../src/serverGroup/configure/wizard/zones/targetShapeSelector.directive.ts","../src/serverGroup/configure/wizard/zones/zoneSelector.directive.js","../src/serverGroup/configure/serverGroup.configure.gce.module.js","../src/serverGroup/configure/wizard/hiddenMetadataKeys.value.js","../src/serverGroup/configure/serverGroupCommandBuilder.service.js","../src/serverGroup/configure/wizard/cloneServerGroup.gce.controller.js","../src/serverGroup/details/stateful/StatefulMIGService.ts","../src/serverGroup/details/stateful/MarkDiskStatefulButton.tsx","../src/serverGroup/details/stateful/UpdateBootImageButton.tsx","../src/serverGroup/details/ServerGroupDiskDescriptions.tsx","../src/serverGroup/details/autoscalingPolicy/modal/GceScaleInControls.tsx","../src/serverGroup/details/autoHealingPolicy/addAutoHealingPolicyButton.component.ts","../src/serverGroup/details/autoHealingPolicy/autoHealingPolicy.component.ts","../src/autoscalingPolicy/autoscalingPolicy.write.service.js","../src/serverGroup/details/autoHealingPolicy/modal/upsertAutoHealingPolicy.modal.controller.ts","../src/serverGroup/details/autoscalingPolicy/modal/upsertAutoscalingPolicy.modal.controller.js","../src/serverGroup/details/autoscalingPolicy/addAutoscalingPolicyButton.component.js","../src/serverGroup/details/autoscalingPolicy/autoscalingPolicy.directive.js","../src/common/footer.directive.js","../src/serverGroup/details/resize/resizeAutoscalingPolicy.component.js","../src/serverGroup/details/resize/resizeCapacity.component.js","../src/serverGroup/details/resize/resizeServerGroup.controller.js","../src/serverGroup/details/rollback/rollbackServerGroup.controller.js","../src/serverGroup/details/serverGroupDetails.gce.controller.js","../src/serverGroup/details/serverGroup.details.gce.module.js","../src/subnet/subnet.renderer.js","../src/validation/applicationName.validator.js","../src/gce.module.ts","../src/logo/gce.logo.png"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import { isEmpty } from 'lodash';\nimport React from 'react';\n\nimport type { ILayoutProps } from '@spinnaker/core';\n\nimport './gceAutoscalingFieldLayout.less';\n\n// todo(mneterval): remove when GCE Autoscaling Controls are entirely converted to React & Formik\nexport function GceAutoScalingFieldLayout(props: ILayoutProps) {\n const { label, help, input, actions, validation, required } = props;\n\n const showLabel = !isEmpty(label) || !isEmpty(help);\n const { hidden, messageNode } = validation;\n\n return (\n <div className=\"gce-autoscaling-layout\">\n {showLabel && (\n <label className=\"col-md-3 sm-label-right\">\n {label}\n {required && <span>*</span>} {help}\n </label>\n )}\n <div className=\"col-md-2 content-fields\">\n <div>\n {input} {actions}\n </div>\n {!hidden && <div className=\"message\">{messageNode}</div>}\n </div>\n </div>\n );\n}\n","export interface IGceAutoscalingPolicy {\n cpuUtilization: IGceAutoscalingCpuUtilization;\n scaleInControl: IGceScaleInControl;\n}\n\nexport interface IGceScaleInControl {\n maxScaledInReplicas?: {\n fixed?: number;\n percent?: number;\n };\n timeWindowSec?: number;\n}\n\nexport interface IGceAutoscalingCpuUtilization {\n predictiveMethod?: GcePredictiveMethod;\n utilizationTarget?: number;\n}\n\nexport enum GcePredictiveMethod {\n NONE = 'NONE',\n STANDARD = 'OPTIMIZE_AVAILABILITY',\n}\n","import { defaults } from 'lodash';\n\nimport type { IInstanceStorage, IProviderSettings } from '@spinnaker/core';\nimport { SETTINGS } from '@spinnaker/core';\n\nexport interface IGCEProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n zone?: string;\n instanceTypeStorage?: IInstanceStorage;\n };\n feature: {\n predictiveAutoscaling?: boolean;\n statefulMigsEnabled?: boolean;\n };\n}\n\nexport const GCEProviderSettings: IGCEProviderSettings = defaults(SETTINGS.providers.gce || {}, {\n defaults: {},\n feature: {},\n resetToOriginal: SETTINGS.resetProvider('gce'),\n});\n","import { module } from 'angular';\nimport React from 'react';\nimport { react2angular } from 'react2angular';\n\nimport type { IFormInputProps } from '@spinnaker/core';\nimport { CheckboxInput, FormField, HelpField, LayoutProvider, withErrorBoundary } from '@spinnaker/core';\n\nimport { GceAutoScalingFieldLayout } from '../../GceAutoScalingFieldLayout';\nimport type { IGceAutoscalingPolicy } from '../../IGceAutoscalingPolicy';\nimport { GcePredictiveMethod } from '../../IGceAutoscalingPolicy';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\ninterface IGcePredictiveAutoscalingProps {\n policy: IGceAutoscalingPolicy;\n updatePolicy: (policy: IGceAutoscalingPolicy) => void;\n}\n\nfunction GcePredictiveAutoscaling({ policy, updatePolicy }: IGcePredictiveAutoscalingProps) {\n if (!GCEProviderSettings.feature.predictiveAutoscaling) {\n return null;\n }\n\n function togglePredictiveAutoscaling(predictiveMethod: GcePredictiveMethod) {\n updatePolicy({\n ...policy,\n cpuUtilization: {\n ...policy.cpuUtilization,\n predictiveMethod,\n },\n });\n }\n\n return (\n <LayoutProvider value={GceAutoScalingFieldLayout}>\n <div className=\"row\">\n <FormField\n help={<HelpField id=\"gce.serverGroup.scalingPolicy.predictiveAutoscaling\" />}\n input={(inputProps: IFormInputProps) => <CheckboxInput {...inputProps} />}\n label=\"Enable predictive autoscaling\"\n onChange={(e: React.ChangeEvent<any>) => {\n togglePredictiveAutoscaling(e.target.checked ? GcePredictiveMethod.STANDARD : GcePredictiveMethod.NONE);\n }}\n value={policy?.cpuUtilization?.predictiveMethod === GcePredictiveMethod.STANDARD}\n />\n </div>\n </LayoutProvider>\n );\n}\n\nexport const GCE_PREDICTIVE_AUTOSCALING = 'spinnaker.gce.predictiveAutoscaling';\nmodule(GCE_PREDICTIVE_AUTOSCALING, []).component(\n 'gcePredictiveAutoscaling',\n react2angular(withErrorBoundary(GcePredictiveAutoscaling, 'gcePredictiveAutoscaling'), ['policy', 'updatePolicy']),\n);\n","import { module } from 'angular';\n\nimport type { ISearchResults } from '@spinnaker/core';\nimport { InfrastructureCaches, SearchService } from '@spinnaker/core';\n\ninterface IAddressSearchResults {\n account: string;\n address: string; // JSON encoded string containing the address. It is missing the account.\n name: string;\n provider: string;\n region: string;\n type: string;\n}\n\nexport interface IGceAddress {\n account?: string;\n address: string;\n creationTimestamp?: string;\n description?: string;\n id?: number;\n kind?: string;\n labelFingerprint?: string;\n name?: string;\n networkTier?: string;\n region?: string;\n selfLink?: string;\n status?: string;\n}\n\nclass GceAddressReader {\n public listAddresses(region?: string): PromiseLike<IGceAddress[]> {\n if (region) {\n return this.listAddresses(null /* region */).then((addresses) =>\n addresses.filter((address) => address.region === region),\n );\n } else {\n return SearchService.search<IAddressSearchResults>(\n { q: '', type: 'addresses', allowShortQuery: 'true' },\n InfrastructureCaches.get('addresses'),\n )\n .then((searchResults: ISearchResults<IAddressSearchResults>) => {\n if (searchResults && searchResults.results) {\n return searchResults.results\n .filter((result) => result.provider === 'gce')\n .map((result) => {\n const address = JSON.parse(result.address) as IGceAddress;\n address.account = result.account;\n address.region = result.region;\n return address;\n });\n } else {\n return [];\n }\n })\n .catch(() => [] as IGceAddress[]);\n }\n }\n}\n\nexport const GCE_ADDRESS_READER = 'spinnaker.gce.addressReader.service';\nmodule(GCE_ADDRESS_READER, []).service('gceAddressReader', GceAddressReader);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { InfrastructureCaches, REST } from '@spinnaker/core';\n\nexport const GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER = 'spinnaker.deck.gce.backendService.reader.service';\nexport const name = GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER; // for backwards compatibility\nmodule(GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER, []).factory('gceBackendServiceReader', function () {\n function listBackendServices(kind) {\n if (kind) {\n return listBackendServices().then(([services]) => {\n if (services) {\n const results = services.results || [];\n return results.filter((service) => service.kind === kind);\n }\n return [];\n });\n } else {\n return REST('/search')\n .useCache(InfrastructureCaches.get('backendServices'))\n .query({ q: '', type: 'backendServices', allowShortQuery: 'true' })\n .get();\n }\n }\n\n return { listBackendServices };\n});\n","import { module } from 'angular';\nimport { uniqWith } from 'lodash';\n\nimport type { ISearchResults } from '@spinnaker/core';\nimport { InfrastructureCaches, SearchService } from '@spinnaker/core';\nimport type { IGceHealthCheck } from '../domain';\n\ninterface IHealthCheckSearchResults {\n name: string;\n account: string;\n healthCheck: string; // JSON encoded string containing the real health check (it is missing the account).\n region?: string;\n kind: string;\n provider: string;\n type: string;\n}\n\nexport class GceHealthCheckReader {\n public listHealthChecks(type?: string): PromiseLike<IGceHealthCheck[]> {\n if (type) {\n return this.listHealthChecks().then((healthChecks) =>\n healthChecks.filter((healthCheck) => healthCheck.healthCheckType === type),\n );\n } else {\n return SearchService.search(\n { q: '', type: 'healthChecks', allowShortQuery: 'true' },\n InfrastructureCaches.get('healthChecks'),\n )\n .then((searchResults: ISearchResults<IHealthCheckSearchResults>) => {\n if (searchResults && searchResults.results) {\n const healthChecks = searchResults.results\n .filter((result) => result.provider === 'gce')\n .map((result) => {\n const healthCheck = JSON.parse(result.healthCheck) as IGceHealthCheck;\n healthCheck.account = result.account;\n return healthCheck;\n });\n return uniqWith(healthChecks, (checkA: IGceHealthCheck, checkB: IGceHealthCheck) => {\n return (\n checkA.name === checkB.name &&\n checkA.healthCheckType === checkB.healthCheckType &&\n checkA.account === checkB.account\n );\n });\n } else {\n return [];\n }\n })\n .catch(() => []);\n }\n }\n}\n\nexport const GCE_HEALTH_CHECK_READER = 'spinnaker.gce.healthCheck.reader';\nmodule(GCE_HEALTH_CHECK_READER, []).service('gceHealthCheckReader', GceHealthCheckReader);\n","'use strict';\n\nimport { module } from 'angular';\nimport { GCE_ADDRESS_READER } from '../address/address.reader';\n\nimport { GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER } from '../backendService/backendService.reader';\nimport { GCE_HEALTH_CHECK_READER } from '../healthCheck/healthCheck.read.service';\n\nexport const GOOGLE_CACHE_CACHECONFIGURER_SERVICE = 'spinnaker.gce.cache.initializer';\nexport const name = GOOGLE_CACHE_CACHECONFIGURER_SERVICE; // for backwards compatibility\nmodule(GOOGLE_CACHE_CACHECONFIGURER_SERVICE, [\n GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER,\n GCE_ADDRESS_READER,\n GCE_HEALTH_CHECK_READER,\n]).factory('gceCacheConfigurer', [\n 'gceAddressReader',\n 'gceBackendServiceReader',\n 'gceCertificateReader',\n 'gceHealthCheckReader',\n function (gceAddressReader, gceBackendServiceReader, gceCertificateReader, gceHealthCheckReader) {\n const config = Object.create(null);\n\n config.addresses = {\n initializers: [() => gceAddressReader.listAddresses()],\n };\n\n config.backendServices = {\n initializers: [() => gceBackendServiceReader.listBackendServices()],\n };\n\n config.certificates = {\n initializers: [() => gceCertificateReader.listCertificates()],\n };\n\n config.healthChecks = {\n initializers: [() => gceHealthCheckReader.listHealthChecks()],\n };\n\n return config;\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const GOOGLE_COMMON_XPNNAMING_GCE_SERVICE = 'spinnaker.gce.common.xpnNaming.service';\nexport const name = GOOGLE_COMMON_XPNNAMING_GCE_SERVICE; // for backwards compatibility\nmodule(GOOGLE_COMMON_XPNNAMING_GCE_SERVICE, []).factory('gceXpnNamingService', function () {\n const deriveProjectId = (resourceWithSelfLink) => {\n const pathSegments = resourceWithSelfLink.selfLink.split('/');\n return pathSegments[pathSegments.indexOf('projects') + 1];\n };\n\n const decorateXpnResourceIfNecessary = (projectId, xpnResource) => {\n if (!xpnResource) {\n return null;\n }\n\n // A network selfLink looks like: https://compute.googleapis.com/compute/beta/projects/test-host-project/global/networks/default\n // A subnet selfLink looks like: https://compute.googleapis.com/compute/beta/projects/my-test-service-project/regions/us-west1/subnetworks/default\n const xpnResourcePathSegments = xpnResource.split('/');\n const xpnResourceProjectId = xpnResourcePathSegments[xpnResourcePathSegments.indexOf('projects') + 1];\n const xpnResourceName = _.last(xpnResourcePathSegments);\n if (xpnResourceProjectId !== projectId) {\n return xpnResourceProjectId + '/' + xpnResourceName;\n } else {\n return xpnResourceName;\n }\n };\n\n return {\n deriveProjectId,\n decorateXpnResourceIfNecessary,\n };\n});\n","import { HelpContentsRegistry } from '@spinnaker/core';\n\nconst helpContents: { [key: string]: string } = {\n 'gce.httpLoadBalancer.certificate':\n 'The name of an SSL certificate. If specified, Spinnaker will create an HTTPS load balancer.',\n 'gce.httpLoadBalancer.certificateMap':\n 'A Certificate Manager certificate map name. Certificate maps let GCP manage and auto-rotate TLS certificates, replacing individual certificate selection.',\n 'gce.httpLoadBalancer.defaultService':\n 'A default service handles any requests that do not match a specified host rule or path matching rule.',\n 'gce.httpLoadBalancer.externalIP':\n 'The IP address for this listener. If you do not specify an IP, your listener will be assigned an ephemeral IP.',\n 'gce.httpLoadBalancer.hostRule.hostPattern': 'For example, <b>example.com</b>.',\n 'gce.httpLoadBalancer.namedPort': `\n For HTTP(S) and SSL/TCP load balancers,\n incoming traffic is directed through a named port (for Spinnaker, the named port is <b>http</b>).\n The mapping from named port to port number is specified per server group\n and can be configured within the server group creation dialogue under <b>Port Name Mapping</b>.`,\n 'gce.httpLoadBalancer.pathRule.paths': 'For example, <b>/path</b> in <b>example.com/path</b>',\n 'gce.httpLoadBalancer.port':\n 'HTTP requests can be load balanced based on port 80 or port 8080. HTTPS requests can be load balanced on port 443.',\n 'gce.image.artifact':\n 'The artifact that is to be deployed to this cluster. The artifact should represent a deployable image.',\n 'gce.image.source': `\n <p>Where the image to deploy is read from.</p>\n <p>\n <b>Artifact:</b> Deploy an artifact that was supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>\n <p>\n <b>Prior Stage:</b> Deploy the result of the most recent Bake or Find Image stage.\n </p>\n `,\n 'gce.instance.customInstance.cores':\n '<ul><li>Above 1, vCPU count must be even.</li><li>Zones that support Haswell and Ivy Bridge processors can support custom machine types up to 32 vCPUs.</li><li>Zones that support Sandy Bridge processors can support up to 16 vCPUs.</li></ul>',\n 'gce.instance.customInstance.memory':\n '<ul><li>Memory per vCPU must be between .9 GB and 6.5 GB.</li><li>Total memory must be a multiple of 256 MB.</li><li>Memory per vCPU must be between .9 GB and 800 GB if selected extended memory feature.</li></ul>',\n 'gce.instance.customInstance.extendedmemory':\n 'Add more memory per vCPU to your VM instance. <a href=\"https://cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#extendedmemory\">Click here </a>for more information regarding extended memory',\n 'gce.instance.customMetadata.instance-template': 'The instance template used to configure this instance.',\n 'gce.instance.customMetadata.load-balancer-names':\n 'This field is used to \"remember\" what load balancers this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.global-load-balancer-names':\n 'This field is used to \"remember\" what global load balancers this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.backend-service-names':\n 'This field is used to \"remember\" what backend services this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.load-balancing-policy':\n 'This field is used to \"remember\" the load balancing policy this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.startup-script': 'This script will run automatically on every boot.',\n 'gce.instance.labels.spinnaker-region': 'This label can be used to group instances when querying for metrics.',\n 'gce.instance.labels.spinnaker-server-group': 'This label can be used to group instances when querying for metrics.',\n 'gce.instance.storage':\n '<p>Storage options can be fully-configured on the <b>Advanced Settings</b> tab. These are just default settings. Please be aware of your Local SSD quotas as you provision VMs.</p>',\n 'gce.instance.storage.localSSD':\n '<p>Local SSD disks are always 375GB. All non shared-core instance types support attaching up to 8 Local SSD disks. Please be aware of your Local SSD quotas as you provision VMs.</p>',\n 'gce.instance.serviceAccount':\n '<p>Service accounts authenticate applications running on your virtual machine instances to other Google Cloud Platform services. Valid values are either \"default\" or the full email address of a custom service account.</p>',\n 'gce.instance.authScopes':\n '<p>Service account scopes specify which Google Cloud Platform APIs your instances can authenticate with, and define the level of access that your instances have with those services. You can enter custom auth scopes by typing into the blank field.</p>',\n 'gce.instance.authScopes.cloud-platform':\n '<p>The instances in this server group have full API access to all Google Cloud services.</p>',\n 'gce.instanceType.32core':\n '<p>32-core machine types are in Beta and are available only in Ivy Bridge and Haswell zones.</p>',\n 'gce.internalLoadBalancer.ports': 'Use a comma to separate up to five TCP ports.',\n 'gce.internalHttpLoadBalancer.network':\n \"Network must have a subnet whose 'purpose' is 'INTERNAL_HTTPS_LOAD_BALANCER'\",\n 'gce.loadBalancer.connectionDraining':\n '(Optional) If set, enables connection draining for this backend service. This field defines the number of seconds to wait before instances that belong to this backend service are terminated in order to drain in-flight connections.',\n 'gce.loadBalancer.detail':\n '<p>(Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables.</p>',\n 'gce.loadBalancer.advancedSettings.healthInterval':\n '<p>Configures the interval, in seconds, between load balancer health checks.</p><p>Default: <b>10</b></p>',\n 'gce.loadBalancer.advancedSettings.healthyThreshold':\n '<p>Configures the number of healthy observations before reinstituting an instance into the load balancer’s traffic rotation.</p><p>Default: <b>10</b></p>',\n 'gce.loadBalancer.advancedSettings.unhealthyThreshold':\n '<p>Configures the number of unhealthy observations before deservicing an instance from the load balancer.</p><p>Default: <b>2</b></p>',\n 'gce.loadBalancer.healthCheck':\n '(Optional) <b>Health Checks</b> use HTTP requests to determine if a VM instance is healthy.',\n 'gce.loadBalancer.portName':\n '(Required) The <b>Port Name</b> this backend service will forward traffic to. Load balancers in GCP specify a <b>Port Name</b>, and each server group added to a load balancer needs to specify a mapping from that <b>Port Name</b> to a port to actually receive traffic.',\n 'gce.loadBalancer.portRange':\n '(Optional) Only packets addressed to ports in the specified <b>Port Range</b> will be forwarded. If left empty, all ports are forwarded. Must be a single port number or two port numbers separated by a dash. Each port number must be between 1 and 65535, inclusive. For example: 5000-5999.',\n 'gce.securityGroup.sourceCIDRs':\n 'Traffic is only allowed from sources that match one of these CIDR ranges, or one of the source tags above.',\n 'gce.securityGroup.sourceTags':\n 'Traffic is only allowed from sources that match one of these tags, or one of the source CIDR ranges below.',\n 'gce.securityGroup.targetTags': 'Traffic is only allowed if the target instance has one of these tags.',\n 'gce.securityGroup.targetServiceAccounts':\n 'Traffic is allowed if the target instance has one of these service accounts.',\n 'gce.securityGroup.sourceServiceAccounts':\n 'Traffic is allowed if the source instance has one of these service accounts.',\n 'gce.serverGroup.associatePublicIpAddress.providerField':\n 'Check if new GCE server groups in this application should be assigned a public IP address by default.',\n 'gce.serverGroup.resizeWithAutoscalingPolicy': `\n Setting the desired instance count for a server group with an autoscaler is not supported by Spinnaker;\n if the desired instance count differs from the instance count that the autoscaler wants to maintain for its configured metrics,\n it will quickly override the desired instance count.`,\n 'gce.serverGroup.scalingPolicy.coolDownPeriodSec':\n 'How long to wait before collecting information from a new instance. This should be at least the time it takes to initialize the instance.',\n 'gce.serverGroup.scalingPolicy.cpuUtilization':\n 'Autoscaler adds or removes instances to maintain this CPU usage on each instance.',\n 'gce.serverGroup.scalingPolicy.predictiveAutoscaling':\n 'Autoscaler adds or removes instances based on forecasted load. You must set a CPU utilization target to enable predictive autoscaling.',\n 'gce.serverGroup.scalingPolicy.loadBalancingUtilization':\n 'Autoscaler adds or removes instances to maintain this usage of load-balancing capacity.',\n 'gce.serverGroup.scalingPolicy.customMetricUtilizations':\n 'Autoscaler adds or removes instances to maintain this usage for custom metric.',\n 'gce.serverGroup.scalingPolicy.cronExpression': `\n Start time and recurrence using a cron expression. Examples: <br/>\n Every day at 3 PM:<br/>\n 0 15 * * *<br/>\n Every week Monday to Friday at 8:30 AM: <br/>\n 30 8 * * Mon-Fri<br/>\n Once on 30 January 2030 at midnight: <br/>\n 0 0 30 1 * 2030`,\n 'gce.serverGroup.imageName':\n '(Required) <b>Image</b> is the Google Compute Engine image. Images are restricted to the account selected.',\n 'gce.serverGroup.capacity':\n 'The number of instances that the instance group manager will attempt to maintain. Deleting or abandoning instances will affect this number, as will resizing the group.',\n 'gce.serverGroup.minCpuPlatform':\n 'The baseline minimum CPU platform to use for your instances, whenever available. Select \"Automatic\" unless you have a specific need.',\n 'gce.serverGroup.customMetadata':\n '<b>Custom Metadata</b> will be propagated to the instances in this server group. This is useful for passing in arbitrary values that can be queried by your code on the instance.',\n 'gce.serverGroup.userData':\n '<p>Custom user data will be propagated to the instances in this server group. Key/value pairs can either be newline or comma delimited.</p><strong>Example:</strong><br/> <pre>key=value<br>key2=value2</pre>',\n 'gce.serverGroup.customMetadata.load-balancer-names':\n 'This field is used to \"remember\" what load balancers this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.global-load-balancer-names':\n 'This field is used to \"remember\" what global load balancers this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.backend-service-names':\n 'This field is used to \"remember\" what backend services this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.load-balancing-policy':\n 'This field is used to \"remember\" the load balancing policy this server group is configured with, even if the server group is deregistered from the load balancer. This allows us to re-enable the server group with the same load balancing policy specified on creation.',\n 'gce.serverGroup.customMetadata.select-zones':\n 'This regional server group will be deployed only to specific zones within the region.',\n 'gce.serverGroup.customMetadata.startup-script': 'This script will run automatically on every boot.',\n 'gce.serverGroup.labels.spinnaker-region': 'This label can be used to group instances when querying for metrics.',\n 'gce.serverGroup.labels.spinnaker-server-group':\n 'This label can be used to group instances when querying for metrics.',\n 'gce.serverGroup.shieldedVmConfig':\n 'Shielded VM features include trusted UEFI firmware and come with options for Secure Boot, Virtual Trusted Platform Module (vTPM), and Integrity Monitoring.',\n 'gce.serverGroup.shieldedVmSecureBoot':\n 'Secure boot helps protect your VM instances against boot-level and kernel-level malware and rootkits.',\n 'gce.serverGroup.shieldedVmVtpm':\n 'Virtual Trusted Platform Module (vTPM) validates your guest VM pre-boot and boot integrity, and offers key generation and protection.',\n 'gce.serverGroup.shieldedVmIntegrityMonitoring':\n 'Integrity monitoring lets you monitor and verify the runtime boot integrity of your shielded VM instances using Stackdriver reports. Note: requires vTPM to be enabled.',\n 'gce.serverGroup.preemptibility':\n 'A preemptible VM costs much less, but lasts only 24 hours. It can be terminated sooner due to system demands.',\n 'gce.serverGroup.automaticRestart':\n 'Compute Engine can automatically restart VM instances if they are terminated for non-user-initiated reasons (maintenance event, hardware failure, software failure, etc.).',\n 'gce.serverGroup.onHostMaintenance':\n 'When Compute Engine performs periodic infrastructure maintenance it can migrate your VM instances to other hardware without downtime.',\n 'gce.serverGroup.canIpForward':\n 'Forwarding allows the instance to help route packets. See <a target=\"_blank\" href=\"https://cloud.google.com/compute/docs/networking?hl=en_US#canipforward\">here</a> for more information.',\n 'gce.serverGroup.securityGroups.implicit':\n 'Firewall rules with no target tags defined will permit incoming connections that match the ingress rules to all instances in the network.',\n 'gce.serverGroup.securityGroups.targetTags':\n 'This {{firewall}} rule will be associated with this server group only if a target tag is selected.',\n 'gce.serverGroup.autoscaling.targetCPUUsage':\n 'Autoscaling adds or removes VMs in the group to maintain this level of CPU usage on each VM.',\n 'gce.serverGroup.autoscaling.targetHTTPLoadBalancingUsage':\n \"Autoscaling adds or removes VMs in the group to maintain this usage of load-balancing capacity. This value is a percentage of the 'Maximum rate' setting of the load balancer this group is used by.\",\n 'gce.serverGroup.autoscaling.targetMetric':\n 'Autoscaling adds or removes VMs in the group to maintain these target levels.',\n 'gce.serverGroup.autoscaling.minVMs':\n 'The least number of VM instances the group will contain, even if the target is not met.',\n 'gce.serverGroup.autoscaling.maxVMs': 'The largest number of VM instances allowed, even if the target is exceeded.',\n 'gce.serverGroup.autoscaling.cooldown':\n 'How long to wait before collecting information from a new instance. This should be at least the time it takes to initialize the instance. To find the minimum, create an instance from the same image and note how long it takes to start.',\n 'gce.serverGroup.autoscaling.mode':\n 'Mode of operation of the autoscaling policy. This guides the autoscaler by defining the types of scaling operations it can perform. Options are ON, ONLY_SCALE_OUT, and OFF.',\n 'gce.serverGroup.autoHealing':\n 'VMs in the group are recreated as needed. You can use a health check to recreate a VM if the health check finds the VM unresponsive. If you do not select a health check, VMs are recreated only when stopped.',\n 'gce.serverGroup.initialDelaySec':\n 'The time to allow an instance to boot and applications to fully start before the first health check.',\n 'gce.serverGroup.maxUnavailable': `\n Maximum number of instances that can be unavailable when auto-healing. The instance is considered available if all of the following conditions are satisfied:\n <ul>\n <li>1. Instance's status is RUNNING.</li>\n <li>2. Instance's liveness health check result was observed to be HEALTHY at least once.</li>\n </ul>`,\n 'gce.serverGroup.subnet': `\n Subnetworks allow you to regionally segment the network IP space into prefixes (subnets) and control which prefix a VM instance's internal IP address is allocated from. There are several types of GCE networks:\n <ul>\n <li><b>Legacy (non-subnet) Network</b>: IP address allocation occurs at the global network level. This means the network address space spans across all regions.</li>\n <li><b>Auto Subnet Network</b>: Server groups will be automatically assigned to the specified region's subnet.</li>\n <li><b>Custom Subnet Network</b>: A subnet must be selected for the server group. If no subnets have been created for the specified region, you will not be able to provision the server group.</li>\n </ul>`,\n 'gce.serverGroup.loadBalancingPolicy.balancingMode':\n 'Tells the load balancer when the backend is at capacity. If a backend is at capacity, new requests are routed to the nearest region that can handle requests. The balancing mode can be based on CPU utilization or requests per second (RPS).',\n 'gce.serverGroup.loadBalancingPolicy.maxRatePerInstance':\n 'The maximum number of requests per second that can be sent to the backend instance group. Input must be a number greater than zero.',\n 'gce.serverGroup.loadBalancingPolicy.maxUtilization':\n 'The maximum CPU utilization allowed for the backend. CPU utilization is calculated by averaging CPU use across all instances in the backend instance group. Input must be a number between 0 and 100.',\n 'gce.serverGroup.loadBalancingPolicy.maxConnectionsPerInstance':\n 'The target connections per second for individual instances. When this number is exceeded, requests are directed to another backend.',\n 'gce.serverGroup.loadBalancingPolicy.capacityScaler': `\n An additional control to manage your maximum CPU utilization or RPS.\n If you want your instances to operate at a max 80% CPU utilization, set your balancing mode to 80% max CPU utilization and your capacity to 100%.\n If you want to cut instance utilization by half, set your balancing mode to 80% max CPU utilization and your capacity to 50%. Input must be a number between 0 and 100.`,\n 'gce.serverGroup.loadBalancingPolicy.portName':\n 'A load balancer sends traffic to an instance group through a named port. Input must be a port name.',\n 'gce.serverGroup.loadBalancingPolicy.listeningPort':\n 'A load balancer sends traffic to an instance group through a named port. Input must be a port number (i.e., between 1 and 65535).',\n 'gce.serverGroup.traffic':\n 'Registers the server group with any associated load balancers. These registrations are used by Spinnaker to determine if the server group is enabled.',\n 'gce.serverGroup.accelerator':\n 'Attaches GPUs to instances in this server group. The set of available GPUs is dictated by the selected zone. You cannot attach GPUs to instances with shared-core machine types.',\n 'gce.tagImage.consideredStages':\n 'Limit which previous stages will be considered when locating images to tag. If left unchecked, images generated by any upstream stage will be tagged.',\n 'pipeline.config.gce.bake.accountName':\n '<p>(Optional) The name of a Google account configured within Rosco. If left blank, the first configured account will be used.</p>',\n 'pipeline.config.gce.bake.baseImage':\n '<p>(Optional) A GCE image name. For example: ubuntu-1204-precise-v20150910.</p>',\n 'gce.loadBalancerType.Network': `\n <p>Use Network Load Balancing to balance the load on your systems based on incoming IP protocol data, such as address, port, and protocol type.</p>\n <p>Network Load Balancing is a regional, non-proxied load balancer. You can use it to load balance UDP traffic, and TCP and SSL traffic on ports that are not supported by the SSL proxy and TCP proxy load balancers.</p>`,\n 'gce.loadBalancerType.HTTP(S)':\n '<p>Google Cloud Platform (GCP) HTTP(S) Load Balancing provides global load balancing for HTTP(S) requests destined for your instances.</p>',\n 'gce.loadBalancerType.Internal':\n '<p>Internal TCP/UDP Load Balancing is a regional load balancer that enables you to run and scale your services behind a private load balancing IP address that is accessible only to your internal virtual machine instances.</p>',\n 'gce.loadBalancerType.SSL':\n '<p>Google Cloud SSL Proxy Load Balancing terminates user SSL (TLS) connections at the load balancing layer, then balances the connections across your instances using the SSL or TCP protocols. This supports both IPv4 and IPv6 addresses for client traffic.</p>',\n 'gce.loadBalancerType.TCP':\n '<p>Google Cloud Platform (GCP) TCP Proxy Load Balancing allows you to use a single IP address for all users around the world. GCP TCP proxy load balancing automatically routes traffic to the instances that are closest to the user.</p>',\n};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","import { REST } from '@spinnaker/core';\n\nexport interface IGceImage {\n imageName: string;\n}\n\nexport class GceImageReader {\n public static findImages(params: { account?: string; provider?: string; q?: string }): PromiseLike<IGceImage[]> {\n return REST('/images/find')\n .query(params)\n .get()\n .catch(() => [] as IGceImage[]);\n }\n\n public static getImage(/*amiName: string, region: string, credentials: string*/): PromiseLike<IGceImage> {\n // GCE images are not regional so we don't need to retrieve ids scoped to regions.\n return null;\n }\n}\n","import { module } from 'angular';\nimport { chain } from 'lodash';\nimport React from 'react';\nimport type { AutocompleteResult, Option } from 'react-select';\nimport { Async } from 'react-select';\nimport { react2angular } from 'react2angular';\n\nimport { withErrorBoundary } from '@spinnaker/core';\n\nimport type { IGceImage } from '../image';\n\ninterface IImageSelectProps {\n availableImages: IGceImage[];\n selectedImage: string;\n selectImage: (image: string, target?: any) => void;\n target?: any;\n}\n\nexport class ImageSelect extends React.Component<IImageSelectProps> {\n private loadOptions = (inputValue: string): Promise<AutocompleteResult<string>> => {\n return new Promise((resolve) => {\n if (!inputValue || inputValue.length < 3) {\n resolve({\n options: [],\n complete: false,\n });\n } else {\n const filteredOptions = chain(this.props.availableImages)\n .filter((i) => i.imageName.toLowerCase().includes(inputValue))\n .take(20)\n .map((i) => ({ value: i.imageName, label: i.imageName }))\n .value();\n resolve({\n options: filteredOptions,\n complete: false,\n });\n }\n });\n };\n\n public render() {\n return (\n <Async\n cache={null}\n clearable={false}\n ignoreAccents={false}\n loadOptions={this.loadOptions}\n onChange={(selected: Option<string>) => this.props.selectImage(selected.value, this.props.target)}\n placeholder=\"Type at least 3 characters to search for an image...\"\n searchPromptText=\"Type at least 3 characters to search for an image...\"\n value={{ value: this.props.selectedImage, label: this.props.selectedImage }}\n />\n );\n }\n}\n\nexport const GCE_IMAGE_SELECT = 'spinnaker.gce.imageSelect';\nmodule(GCE_IMAGE_SELECT, []).component(\n 'gceImageSelect',\n react2angular(withErrorBoundary(ImageSelect, 'gceImageSelect'), [\n 'availableImages',\n 'selectedImage',\n 'selectImage',\n 'target',\n ]),\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE =\n 'spinnaker.serverGroup.customInstanceBuilder.gce.service';\nexport const name = GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE; // for backwards compatibility\nmodule(GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE, []).factory(\n 'gceCustomInstanceBuilderService',\n function () {\n function vCpuCountForLocationIsValid(instanceFamily, vCpuCount, location, locationToInstanceTypesMap) {\n let max = 0;\n switch (instanceFamily) {\n case 'E2':\n // E2 support up to 32 cores\n // https://cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#e2_custom_machine_types\n max = 32;\n break;\n case 'N2':\n case 'N2D':\n case 'N1':\n default:\n max = locationToInstanceTypesMap[location].vCpuMax;\n }\n return vCpuCount <= max;\n }\n\n /*\n * Above 1, vCPU count must be even.\n * */\n function numberOfVCpusIsValid(instanceFamily, vCpuCount) {\n if (vCpuCount === 1) {\n return true;\n }\n switch (instanceFamily) {\n case 'N2':\n case 'N2D':\n return vCpuCount % 4 === 0;\n case 'E2':\n case 'N1':\n default:\n return vCpuCount % 2 === 0;\n }\n }\n\n function generateValidVCpuListForLocation(location, locationToInstanceTypesMap) {\n const max = locationToInstanceTypesMap[location].vCpuMax;\n return [1, ..._.range(2, max, 2), max];\n }\n\n function generateValidInstanceFamilyList() {\n return ['n1', 'e2', 'n2', 'n2d'].map((x) => x.toUpperCase());\n }\n\n /*\n * Memory per vCPU must be between .9 GB and 6.5 GB\n * Total memory must be a multiple of 256 MB.\n * */\n function minMemoryForVCpuCount(instanceFamily, vCpuCount) {\n switch (instanceFamily) {\n case 'E2':\n case 'N2':\n case 'N2D':\n return Math.ceil(0.5 * vCpuCount * 4) / 4;\n case 'N1':\n default:\n return Math.ceil(0.9 * vCpuCount * 4) / 4;\n }\n }\n\n function maxMemoryForVCpuCount(instanceFamily, vCpuCount) {\n switch (instanceFamily) {\n case 'E2':\n return 8 * vCpuCount > 128 ? 128 : 8 * vCpuCount;\n case 'N2':\n case 'N2D':\n return 8 * vCpuCount;\n case 'N1':\n default:\n return 6.5 * vCpuCount;\n }\n }\n\n function generateValidMemoryListForVCpuCount(instanceFamily, vCpuCount) {\n const min = minMemoryForVCpuCount(instanceFamily, vCpuCount);\n const max = maxMemoryForVCpuCount(instanceFamily, vCpuCount);\n return [..._.range(min, max, 0.25), max];\n }\n\n function memoryIsValid(instanceFamily, totalMemory, vCpuCount, extendedMemory) {\n const min = minMemoryForVCpuCount(instanceFamily, vCpuCount);\n const max = extendedMemory ? 800 : maxMemoryForVCpuCount(instanceFamily, vCpuCount);\n return _.inRange(totalMemory, min, max) || totalMemory === max;\n }\n\n /*\n * In the API, you must always provide memory in MB units.\n * Format: custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY\n * */\n function generateInstanceTypeString(instanceFamily, vCpuCount, totalMemory, extendedMemory) {\n const extendedFlag = extendedMemory ? '-ext' : '';\n const memoryInMbs = Number(totalMemory) * 1024;\n instanceFamily = instanceFamily.toLowerCase();\n if (instanceFamily === 'n1') {\n return `custom-${vCpuCount}-${memoryInMbs}${extendedFlag}`;\n }\n return `${instanceFamily}-custom-${vCpuCount}-${memoryInMbs}${extendedFlag}`;\n }\n\n function parseInstanceTypeString(instanceTypeString) {\n const [vCpuCount, memoryInMbs] = _.chain(instanceTypeString.split('-'))\n .takeRight(2)\n .map((value) => Number(value))\n .value();\n\n let instanceFamily = instanceTypeString.split('-')[0].toUpperCase();\n if (instanceFamily === 'CUSTOM') {\n instanceFamily = 'N1';\n }\n\n const memory = memoryInMbs / 1024;\n\n return { instanceFamily, vCpuCount, memory };\n }\n\n function customInstanceChoicesAreValid(\n instanceFamily,\n vCpuCount,\n totalMemory,\n location,\n locationToInstanceTypesMap,\n extendedMemory,\n ) {\n return _.every([\n numberOfVCpusIsValid(instanceFamily, vCpuCount),\n memoryIsValid(instanceFamily, totalMemory, vCpuCount, extendedMemory),\n vCpuCountForLocationIsValid(instanceFamily, vCpuCount, location, locationToInstanceTypesMap),\n ]);\n }\n\n return {\n generateValidVCpuListForLocation,\n generateValidMemoryListForVCpuCount,\n generateValidInstanceFamilyList,\n generateInstanceTypeString,\n customInstanceChoicesAreValid,\n memoryIsValid,\n vCpuCountForLocationIsValid,\n parseInstanceTypeString,\n };\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE } from './customInstanceBuilder.gce.service';\n\nexport const GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER = 'spinnaker.gce.customInstance.filter';\nexport const name = GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER; // for backwards compatibility\nmodule(GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER, [GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE]).filter(\n 'customInstanceFilter',\n [\n 'gceCustomInstanceBuilderService',\n function (gceCustomInstanceBuilderService) {\n return function (instanceTypeString) {\n if (_.includes(instanceTypeString, 'custom-')) {\n const { instanceFamily, vCpuCount, memory } = gceCustomInstanceBuilderService.parseInstanceTypeString(\n instanceTypeString,\n );\n return `${instanceFamily} ${vCpuCount} vCPU / ${memory} GB RAM`;\n }\n return instanceTypeString;\n };\n },\n ],\n);\n","import { module } from 'angular';\nimport { uniq } from 'lodash';\n\nimport type { IGceHttpLoadBalancer, IGceLoadBalancer } from '../domain/loadBalancer';\n\nexport class GceHttpLoadBalancerUtils {\n public static REGION = 'global';\n\n public isHttpLoadBalancer(lb: IGceLoadBalancer): lb is IGceHttpLoadBalancer {\n return (\n (lb.provider === 'gce' || lb.type === 'gce') &&\n (lb.loadBalancerType === 'HTTP' || lb.loadBalancerType === 'INTERNAL_MANAGED')\n );\n }\n\n public normalizeLoadBalancerNamesForAccount(\n loadBalancerNames: string[],\n account: string,\n loadBalancers: IGceLoadBalancer[],\n ): string[] {\n // Assume that loadBalancers is a list of all GCE load balancers in an application\n // (but possibly from several accounts), and has already been normalized (listener names mapped to URL map names).\n const normalizedLoadBalancerNames: string[] = [];\n loadBalancerNames.forEach((loadBalancerName) => {\n const matchingUrlMap = loadBalancers.find((loadBalancer) => {\n return (\n account === loadBalancer.account &&\n this.isHttpLoadBalancer(loadBalancer) &&\n loadBalancer.listeners.map((listener) => listener.name).includes(loadBalancerName)\n );\n });\n\n matchingUrlMap\n ? normalizedLoadBalancerNames.push(matchingUrlMap.name)\n : normalizedLoadBalancerNames.push(loadBalancerName);\n });\n return uniq(normalizedLoadBalancerNames);\n }\n}\n\nexport const GCE_HTTP_LOAD_BALANCER_UTILS = 'spinnaker.gce.httpLoadBalancerUtils.service';\nmodule(GCE_HTTP_LOAD_BALANCER_UTILS, []).service('gceHttpLoadBalancerUtils', GceHttpLoadBalancerUtils);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport {\n CloudProviderRegistry,\n ConfirmationModalService,\n FirewallLabels,\n InstanceReader,\n InstanceWriter,\n RecentHistoryService,\n} from '@spinnaker/core';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../common/xpnNaming.gce.service';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../../loadBalancer/httpLoadBalancerUtils.service';\n\nexport const GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER = 'spinnaker.instance.detail.gce.controller';\nexport const name = GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER, [\n UIROUTER_ANGULARJS,\n ANGULAR_UI_BOOTSTRAP,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n GCE_HTTP_LOAD_BALANCER_UTILS,\n]).controller('gceInstanceDetailsCtrl', [\n '$scope',\n '$state',\n '$uibModal',\n 'instance',\n 'app',\n 'moniker',\n 'environment',\n '$q',\n 'gceHttpLoadBalancerUtils',\n 'gceXpnNamingService',\n function (\n $scope,\n $state,\n $uibModal,\n instance,\n app,\n moniker,\n environment,\n $q,\n gceHttpLoadBalancerUtils,\n gceXpnNamingService,\n ) {\n // needed for standalone instances\n $scope.detailsTemplateUrl = CloudProviderRegistry.getValue('gce', 'instance.detailsTemplateUrl');\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n $scope.state = {\n loading: true,\n standalone: app.isStandalone,\n };\n\n $scope.application = app;\n $scope.moniker = moniker;\n $scope.environment = environment;\n\n function extractHealthMetrics(instance, latest) {\n // do not backfill on standalone instances\n if (app.isStandalone) {\n instance.health = latest.health;\n }\n\n instance.health = instance.health || [];\n const displayableMetrics = instance.health.filter(function (metric) {\n return metric.type !== 'Google' || metric.state !== 'Unknown';\n });\n\n // backfill details where applicable\n if (latest.health) {\n displayableMetrics.forEach(function (metric) {\n const detailsMatch = latest.health.filter(function (latestHealth) {\n return latestHealth.type === metric.type;\n });\n if (detailsMatch.length) {\n _.defaults(metric, detailsMatch[0]);\n }\n });\n }\n $scope.healthMetrics = displayableMetrics;\n }\n\n function retrieveInstance() {\n const extraData = {};\n let instanceSummary, loadBalancers, account, region, vpcId;\n if (!app.serverGroups) {\n // standalone instance\n instanceSummary = {};\n loadBalancers = [];\n account = instance.account;\n region = instance.region;\n } else {\n app.serverGroups.data.some(function (serverGroup) {\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = serverGroup.loadBalancers;\n account = serverGroup.account;\n region = serverGroup.region;\n extraData.serverGroup = serverGroup.name;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a server group that is part of another application\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n if (!instanceSummary) {\n // perhaps it is in a disabled server group via a load balancer\n app.loadBalancers.data.some(function (loadBalancer) {\n return loadBalancer.serverGroups.some(function (serverGroup) {\n if (!serverGroup.isDisabled) {\n return false;\n }\n return serverGroup.instances.some(function (possibleInstance) {\n if (possibleInstance.id === instance.instanceId) {\n instanceSummary = possibleInstance;\n loadBalancers = [loadBalancer.name];\n account = loadBalancer.account;\n region = loadBalancer.region;\n vpcId = loadBalancer.vpcId;\n return true;\n }\n });\n });\n });\n }\n }\n }\n\n if (instanceSummary && account && region) {\n extraData.account = account;\n extraData.region = region;\n RecentHistoryService.addExtraDataToLatest('instances', extraData);\n return InstanceReader.getInstanceDetails(account, region, instance.instanceId).then(function (details) {\n $scope.state.loading = false;\n extractHealthMetrics(instanceSummary, details);\n $scope.instance = _.defaults(details, instanceSummary);\n $scope.instance.account = account;\n $scope.instance.region = region;\n $scope.instance.vpcId = vpcId;\n if (app.getDataSource('loadBalancers')) {\n $scope.instance.loadBalancers = gceHttpLoadBalancerUtils.normalizeLoadBalancerNamesForAccount(\n loadBalancers,\n account,\n app.getDataSource('loadBalancers').data,\n );\n }\n\n $scope.instance.internalDnsName = $scope.instance.instanceId;\n $scope.instance.internalIpAddress = $scope.instance.networkInterfaces[0].networkIP;\n\n if ($scope.instance.networkInterfaces[0].accessConfigs) {\n $scope.instance.externalIpAddress = $scope.instance.networkInterfaces[0].accessConfigs[0].natIP;\n }\n\n $scope.baseIpAddress = $scope.instance.externalIpAddress || $scope.instance.internalIpAddress;\n\n const projectId = gceXpnNamingService.deriveProjectId($scope.instance);\n $scope.instance.logsLink =\n 'https://console.developers.google.com/project/' +\n projectId +\n '/logs?service=gce_instance&minLogLevel=0&filters=text:' +\n $scope.instance.instanceId;\n\n $scope.instance.network = getNetwork(projectId);\n $scope.instance.subnet = getSubnet(projectId);\n\n $scope.instance.sshLink =\n $scope.instance.selfLink.replace(\n /www.googleapis.com\\/compute\\/(alpha|beta|v1)/,\n 'cloudssh.developers.google.com',\n ) + '?authuser=0&hl=en_US';\n\n $scope.instance.gcloudSSHCommand =\n 'gcloud compute ssh --project ' +\n projectId +\n ' --zone ' +\n $scope.instance.placement.availabilityZone +\n ' ' +\n instance.instanceId;\n\n augmentTagsWithHelp();\n }, autoClose);\n }\n\n if (!instanceSummary) {\n $scope.instanceIdNotFound = instance.instanceId;\n $scope.state.loading = false;\n }\n\n return $q.when(null);\n }\n\n function autoClose() {\n if ($scope.$$destroyed) {\n return;\n }\n $state.go('^', { allowModalToStayOpen: true }, { location: 'replace' });\n }\n\n function augmentTagsWithHelp() {\n if (_.has($scope, 'instance.tags.items') && _.has($scope, 'instance.securityGroups')) {\n const securityGroups = _.chain($scope.instance.securityGroups)\n .map((securityGroup) => {\n return _.find(app.securityGroups.data, {\n accountName: $scope.instance.account,\n region: 'global',\n id: securityGroup.groupId,\n });\n })\n .compact()\n .value();\n\n const helpMap = {};\n\n $scope.instance.tags.items.forEach((tag) => {\n const securityGroupsMatches = _.filter(securityGroups, (securityGroup) =>\n _.includes(securityGroup.targetTags, tag),\n );\n const securityGroupMatchNames = _.map(securityGroupsMatches, 'name');\n\n if (!_.isEmpty(securityGroupMatchNames)) {\n const groupOrGroups = securityGroupMatchNames.length > 1 ? 'groups' : 'group';\n\n helpMap[tag] =\n 'This tag associates this instance with security ' +\n groupOrGroups +\n ' <em>' +\n securityGroupMatchNames.join(', ') +\n '</em>.';\n }\n });\n\n $scope.instance.tags.helpMap = helpMap;\n }\n }\n\n function getNetwork(projectId) {\n const networkUrl = _.get($scope.instance, 'networkInterfaces[0].network');\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, networkUrl);\n }\n\n function getSubnet(projectId) {\n const subnetUrl = _.get($scope.instance, 'networkInterfaces[0].subnetwork');\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, subnetUrl);\n }\n\n this.canRegisterWithLoadBalancer = function () {\n const instance = $scope.instance;\n const instanceLoadBalancerDoesNotSupportRegister =\n !app.loadBalancers ||\n _.chain(app.loadBalancers.data)\n .filter((lb) => lb.loadBalancerType !== 'NETWORK' && lb.account === instance.account)\n .map('name')\n .intersection(instance.loadBalancers || [])\n .value().length;\n\n if (!instance.loadBalancers || !instance.loadBalancers.length || instanceLoadBalancerDoesNotSupportRegister) {\n return false;\n }\n const outOfService = instance.health.some(function (health) {\n return health.type === 'LoadBalancer' && health.state === 'OutOfService';\n });\n const hasLoadBalancerHealth = instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n return outOfService || !hasLoadBalancerHealth;\n };\n\n this.canDeregisterFromLoadBalancer = function () {\n const instance = $scope.instance;\n const instanceLoadBalancerDoesNotSupportDeregister =\n !app.loadBalancers ||\n _.chain(app.loadBalancers.data)\n .filter((lb) => lb.loadBalancerType !== 'NETWORK' && lb.account === instance.account)\n .map('name')\n .intersection(instance.loadBalancers || [])\n .value().length;\n\n if (!instance.loadBalancers || !instance.loadBalancers.length || instanceLoadBalancerDoesNotSupportDeregister) {\n return false;\n }\n const hasLoadBalancerHealth = instance.health.some(function (health) {\n return health.type === 'LoadBalancer';\n });\n return hasLoadBalancerHealth;\n };\n\n this.canRegisterWithDiscovery = function () {\n const instance = $scope.instance;\n const discoveryHealth = instance.health.filter(function (health) {\n return health.type === 'Discovery';\n });\n return discoveryHealth.length ? discoveryHealth[0].state === 'OutOfService' : false;\n };\n\n this.showInstanceActionsDivider = function () {\n return (\n this.canRegisterWithDiscovery() ||\n this.hasHealthState('Discovery', 'Up') ||\n this.canRegisterWithLoadBalancer() ||\n this.canDeregisterFromLoadBalancer()\n );\n };\n\n this.terminateInstance = function terminateInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId,\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n const params = { cloudProvider: 'gce' };\n\n if (instance.serverGroup) {\n params.managedInstanceGroupName = instance.serverGroup;\n }\n\n return InstanceWriter.terminateInstance(instance, app, params);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + '?',\n buttonText: 'Terminate ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.terminateInstanceAndShrinkServerGroup = function terminateInstanceAndShrinkServerGroup() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Terminating ' + instance.instanceId + ' and shrinking server group',\n onTaskComplete: function () {\n if ($state.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = function () {\n return InstanceWriter.terminateInstanceAndShrinkServerGroup(instance, app, {\n serverGroupName: instance.serverGroup,\n instanceIds: [instance.instanceId],\n zone: instance.placement.availabilityZone,\n });\n };\n\n ConfirmationModalService.confirm({\n header: 'Really terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup + '?',\n buttonText: 'Terminate ' + instance.instanceId + ' and shrink ' + instance.serverGroup,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.rebootInstance = function rebootInstance() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Rebooting ' + instance.instanceId,\n };\n\n const submitMethod = function () {\n return InstanceWriter.rebootInstance(instance, app, {\n // We can't really reliably do anything other than ignore health here.\n interestingHealthProviderNames: [],\n });\n };\n\n ConfirmationModalService.confirm({\n header: 'Really reboot ' + instance.instanceId + '?',\n buttonText: 'Reboot ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.registerInstanceWithLoadBalancer = function registerInstanceWithLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Registering ' + instance.instanceId + ' with ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.registerInstanceWithLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really register ' + instance.instanceId + ' with ' + loadBalancerNames + '?',\n buttonText: 'Register ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.deregisterInstanceFromLoadBalancer = function deregisterInstanceFromLoadBalancer() {\n const instance = $scope.instance;\n const loadBalancerNames = instance.loadBalancers.join(' and ');\n\n const taskMonitor = {\n application: app,\n title: 'Deregistering ' + instance.instanceId + ' from ' + loadBalancerNames,\n };\n\n const submitMethod = function () {\n return InstanceWriter.deregisterInstanceFromLoadBalancer(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really deregister ' + instance.instanceId + ' from ' + loadBalancerNames + '?',\n buttonText: 'Deregister ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.enableInstanceInDiscovery = function enableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.enableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really enable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Enable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.disableInstanceInDiscovery = function disableInstanceInDiscovery() {\n const instance = $scope.instance;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + instance.instanceId + ' in discovery',\n };\n\n const submitMethod = function () {\n return InstanceWriter.disableInstanceInDiscovery(instance, app);\n };\n\n ConfirmationModalService.confirm({\n header: 'Really disable ' + instance.instanceId + ' in discovery?',\n buttonText: 'Disable ' + instance.instanceId,\n account: instance.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n this.hasHealthState = function hasHealthState(healthProviderType, state) {\n const instance = $scope.instance;\n return instance.health.some(function (health) {\n return health.type === healthProviderType && health.state === state;\n });\n };\n\n const initialize = app.isStandalone\n ? retrieveInstance()\n : $q.all([app.serverGroups.ready(), app.loadBalancers.ready()]).then(retrieveInstance);\n\n initialize.then(() => {\n // Two things to look out for here:\n // 1. If the retrieveInstance call completes *after* the user has navigated away from the view, there\n // is no point in subscribing to the refresh\n // 2. If this is a standalone instance, there is no application that will refresh\n if (!$scope.$$destroyed && !app.isStandalone) {\n app.serverGroups.onRefresh($scope, retrieveInstance);\n }\n });\n\n $scope.account = instance.account;\n },\n]);\n","// Duplicated from https://github.com/spinnaker/clouddriver/blob/master/clouddriver-web/config/clouddriver.yml\n// TODO(mneterval): remove after resolution of https://github.com/spinnaker/spinnaker/issues/4859\nexport const GCE_INSTANCE_TYPE_DISK_DEFAULTS = Object.freeze([\n {\n instanceType: 'n1-standard-1',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'f1-micro',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'g1-small',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-small',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-micro',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-medium',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'default',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, SETTINGS } from '@spinnaker/core';\n\nimport { GCE_INSTANCE_TYPE_DISK_DEFAULTS } from './gceInstanceTypeDisks';\n\nexport const GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE = 'spinnaker.gce.instanceType.service';\nexport const name = GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE; // for backwards compatibility\nmodule(GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE, []).factory('gceInstanceTypeService', [\n '$q',\n '$log',\n function ($q, $log) {\n const cachedResult = null;\n\n const n1standard = {\n type: 'n1-standard',\n description:\n 'This family provides a balance of compute, memory, and network resources, and it is a good choice for general purpose applications.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-standard-1',\n label: 'Small',\n cpu: 1,\n memory: 3.75,\n costFactor: 1,\n },\n {\n name: 'n1-standard-2',\n label: 'Medium',\n cpu: 2,\n memory: 7.5,\n costFactor: 2,\n },\n {\n name: 'n1-standard-4',\n label: 'Large',\n cpu: 4,\n memory: 15,\n costFactor: 2,\n },\n {\n name: 'n1-standard-8',\n label: 'XLarge',\n cpu: 8,\n memory: 30,\n costFactor: 3,\n },\n {\n name: 'n1-standard-16',\n label: '2XLarge',\n cpu: 16,\n memory: 60,\n costFactor: 3,\n },\n {\n name: 'n1-standard-32',\n label: '4XLarge',\n cpu: 32,\n memory: 120,\n costFactor: 4,\n },\n {\n name: 'n1-standard-64',\n label: '8XLarge',\n cpu: 64,\n memory: 240,\n costFactor: 4,\n },\n {\n name: 'n1-standard-96',\n label: '12XLarge',\n cpu: 96,\n memory: 360,\n costFactor: 4,\n },\n ],\n };\n\n const f1micro = {\n type: 'f1-micro bursting',\n description:\n 'This family of machine types is a good choice for small, non-resource intensive 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).',\n storageType: 'Std',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'f1-micro',\n label: 'Micro',\n cpu: 1,\n memory: 0.6,\n costFactor: 1,\n },\n {\n name: 'g1-small',\n label: 'Small',\n cpu: 1,\n memory: 1.7,\n costFactor: 1,\n },\n {\n name: 'e2-micro',\n label: 'E2 Micro',\n cpu: 2,\n memory: 1,\n costFactor: 1,\n },\n {\n name: 'e2-small',\n label: 'E2 Small',\n cpu: 2,\n memory: 2,\n costFactor: 2,\n },\n {\n name: 'e2-medium',\n label: 'E2 Medium',\n cpu: 2,\n memory: 4,\n costFactor: 2,\n },\n ],\n };\n\n const n1highmem = {\n type: 'n1-highmem',\n description:\n 'High memory machine types are ideal for tasks that require more memory relative to virtual cores. High memory machine types have 6.50GB of RAM per virtual core.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-highmem-2',\n label: 'Medium',\n cpu: 2,\n memory: 13,\n costFactor: 2,\n },\n {\n name: 'n1-highmem-4',\n label: 'Large',\n cpu: 4,\n memory: 26,\n costFactor: 2,\n },\n {\n name: 'n1-highmem-8',\n label: 'XLarge',\n cpu: 8,\n memory: 52,\n costFactor: 3,\n },\n {\n name: 'n1-highmem-16',\n label: '2XLarge',\n cpu: 16,\n memory: 104,\n costFactor: 3,\n },\n {\n name: 'n1-highmem-32',\n label: '4XLarge',\n cpu: 32,\n memory: 208,\n costFactor: 4,\n },\n {\n name: 'n1-highmem-64',\n label: '8XLarge',\n cpu: 64,\n memory: 416,\n costFactor: 4,\n },\n {\n name: 'n1-highmem-96',\n label: '12XLarge',\n cpu: 96,\n memory: 624,\n costFactor: 4,\n },\n ],\n };\n\n const n1highcpu = {\n type: 'n1-highcpu',\n description:\n 'High CPU machine types are ideal for tasks that require more virtual cores relative to memory. High CPU machine types have one virtual core for every 0.90GB of RAM.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-highcpu-2',\n label: 'Medium',\n cpu: 2,\n memory: 1.8,\n costFactor: 1,\n },\n {\n name: 'n1-highcpu-4',\n label: 'Large',\n cpu: 4,\n memory: 3.6,\n costFactor: 2,\n },\n {\n name: 'n1-highcpu-8',\n label: 'XLarge',\n cpu: 8,\n memory: 7.2,\n costFactor: 2,\n },\n {\n name: 'n1-highcpu-16',\n label: '2XLarge',\n cpu: 16,\n memory: 14.4,\n costFactor: 3,\n },\n {\n name: 'n1-highcpu-32',\n label: '4XLarge',\n cpu: 32,\n memory: 28.8,\n costFactor: 4,\n },\n {\n name: 'n1-highcpu-64',\n label: '8XLarge',\n cpu: 64,\n memory: 57.6,\n costFactor: 4,\n },\n {\n name: 'n1-highcpu-96',\n label: '12XLarge',\n cpu: 96,\n memory: 86.4,\n costFactor: 4,\n },\n ],\n };\n\n const customMachine = {\n type: 'buildCustom',\n instanceTypes: [\n {\n name: 'n1buildCustom',\n nameRegex: /custom-\\d{1,2}-\\d{4,6}/,\n storage: {\n localSSDSupported: true,\n },\n },\n {\n name: 'e2buildCustom',\n nameRegex: /e2-custom-(\\d{1,2})-(\\d{3,6})/,\n storage: {\n localSSDSupported: false,\n },\n },\n {\n name: 'otherbuildCustom',\n nameRegex: /(.*)-?custom-(\\d{1,2})-(\\d{3,6})/,\n storage: {\n localSSDSupported: true,\n },\n },\n ],\n };\n\n const categories = [\n {\n type: 'general',\n label: 'General Purpose',\n families: [n1standard],\n icon: 'hdd',\n },\n {\n type: 'memory',\n label: 'High Memory',\n families: [n1highmem],\n icon: 'hdd',\n },\n {\n type: 'cpu',\n label: 'High CPU',\n families: [n1highcpu],\n icon: 'hdd',\n },\n {\n type: 'micro',\n label: 'Micro Utility',\n families: [f1micro],\n icon: 'hdd',\n },\n {\n type: 'custom',\n label: 'Custom Type',\n families: [],\n icon: 'asterisk',\n },\n {\n type: 'buildCustom',\n label: 'Build Custom',\n families: [customMachine],\n icon: 'wrench',\n },\n ];\n\n const getCategories = _.memoize(() => {\n const initializedCategories = _.cloneDeep(categories);\n return AccountService.getAllAccountDetailsForProvider('gce').then((accountDetails) => {\n // All GCE accounts have the same instance type disk defaults, so we can pick the first one.\n let instanceTypeDisks = _.get(accountDetails, '[0].instanceTypeDisks');\n if (_.isEmpty(instanceTypeDisks)) {\n instanceTypeDisks = GCE_INSTANCE_TYPE_DISK_DEFAULTS;\n }\n if (instanceTypeDisks) {\n const families = _.flatten(initializedCategories.map((category) => category.families));\n families.forEach((family) => {\n family.instanceTypes.forEach((instanceType) => {\n const diskDefaults = instanceTypeDisks.find(\n (instanceTypeDisk) => instanceTypeDisk.instanceType === instanceType.name,\n );\n if (diskDefaults) {\n const disks = diskDefaults.disks\n .map((disk) => {\n switch (disk.type) {\n case 'PD_SSD':\n return {\n type: 'pd-ssd',\n sizeGb: disk.sizeGb,\n };\n case 'PD_STANDARD':\n return {\n type: 'pd-standard',\n sizeGb: disk.sizeGb,\n };\n case 'LOCAL_SSD':\n return {\n type: 'local-ssd',\n sizeGb: 375,\n };\n default:\n $log.warn(`Disk type '${disk.type}' not supported.`);\n return null;\n }\n })\n .filter((disk) => !!disk);\n\n let size = 0;\n let count = 0;\n if (diskDefaults.supportsLocalSSD) {\n count = disks.filter((disk) => disk.type === 'local-ssd').length;\n size = 375;\n } else {\n // TODO(dpeach): This will render the disk defaults incorrectly for f1-micro and g1-small instance types\n // if the disk defaults set in Clouddriver have different sizes. Fixing it will require updating\n // the core instance type selector.\n // This logic will render the count of the largest disk.\n const persistentDisks = disks.filter((disk) => disk.type.startsWith('pd-'));\n if (persistentDisks.length) {\n size = persistentDisks.reduce((maxSizeGb, disk) => Math.max(maxSizeGb, disk.sizeGb), 0);\n count = persistentDisks.filter((disk) => disk.sizeGb === size).length;\n }\n }\n\n instanceType.storage = {\n localSSDSupported: diskDefaults.supportsLocalSSD,\n size: size,\n count: count,\n defaultSettings: { disks },\n };\n }\n });\n });\n }\n return initializedCategories;\n });\n });\n\n function getAllTypesByRegion() {\n if (cachedResult) {\n return $q.when(cachedResult);\n }\n\n return getCategories().then((categories) => {\n return _.chain(categories)\n .map('families')\n .flatten()\n .map('instanceTypes')\n .flatten()\n .map('name')\n .filter((name) => name !== 'n1buildCustom' && name !== 'e2buildCustom' && name !== 'otherbuildCustom')\n .value();\n });\n }\n\n function getAvailableTypesForLocations(locationToInstanceTypesMap, selectedLocations) {\n if (!locationToInstanceTypesMap || !selectedLocations || selectedLocations.length === 0) {\n console.error('Invalid input parameters');\n return [];\n }\n\n const availableTypes = selectedLocations\n .filter((location) => locationToInstanceTypesMap[location])\n .flatMap((location) => locationToInstanceTypesMap[location].instanceTypes || []);\n\n return availableTypes;\n }\n\n const getAvailableTypesForRegions = getAvailableTypesForLocations;\n\n const resolveInstanceTypeDetails = (instanceType) => {\n return {\n name: instanceType,\n storage: Object.assign({ isDefault: true }, SETTINGS.providers.gce.defaults.instanceTypeStorage),\n };\n };\n\n return {\n getCategories: getCategories,\n getAvailableTypesForRegions: getAvailableTypesForRegions,\n getAllTypesByRegion: getAllTypesByRegion,\n getAvailableTypesForLocations: getAvailableTypesForLocations,\n resolveInstanceTypeDetails: resolveInstanceTypeDetails,\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER =\n 'spinnaker.google.instance.multiInstance.task.transformer';\nexport const name = GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER; // for backwards compatibility\nmodule(GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER, []).factory('gceMultiInstanceTaskTransformer', function () {\n // custom transformers for specific tasks,\n // e.g. \"rebootInstances\" needs an empty \"interestingHealthProviderNames\" array\n const transformers = {\n rebootInstances: (job) => {\n job.interestingHealthProviderNames = [];\n },\n };\n\n // adds the \"zone\" field to all jobs\n const transformAll = (instanceGroup, job) => {\n job.zone = instanceGroup.instances[0].availabilityZone;\n };\n\n const transformJob = (instanceGroup, job) => {\n transformAll(instanceGroup, job);\n if (transformers[job.type]) {\n transformers[job.type](job);\n }\n };\n\n return {\n transform: transformJob,\n };\n});\n","import type { IHttpInterceptor, IHttpPromiseCallbackArg, IHttpProvider } from 'angular';\nimport { module } from 'angular';\nimport { $http, $q } from 'ngimport';\nimport { SETTINGS } from '@spinnaker/core';\n\n/**\n * When a Cloud IAP (if enabled) session expires, refreshes session.\n */\n\nexport class IapInterceptor implements IHttpInterceptor {\n public responseError = <T>(response: IHttpPromiseCallbackArg<T>): PromiseLike<T> => {\n const { config, status } = response;\n\n if (status === 401 && SETTINGS.feature.iapRefresherEnabled) {\n return $http.get('/_gcp_iap/do_session_refresh').then(\n () => {\n return $http.get(config.url, config).then((result: T) => result);\n },\n // Reject with original response\n () => $q.reject(response),\n );\n }\n\n return $q.reject(response);\n };\n}\n\nexport const IAP_INTERCEPTOR = 'spinnaker.gce.iap.interceptor';\nmodule(IAP_INTERCEPTOR, [])\n .service('iapInterceptor', IapInterceptor)\n .config([\n '$httpProvider',\n ($httpProvider: IHttpProvider) => {\n $httpProvider.interceptors.push('iapInterceptor');\n },\n ]);\n","import { module } from 'angular';\n\nexport interface IGceLoadBalancerWizardConfig {\n label: string;\n createTemplateUrl: string;\n editTemplateUrl: string;\n controller: string;\n}\n\nexport interface IGceLoadBalancerToWizardMap {\n [loadBalancerType: string]: IGceLoadBalancerWizardConfig;\n}\n\nconst loadBalancerTypeToWizardMap: IGceLoadBalancerToWizardMap = {\n NETWORK: {\n label: 'Network',\n createTemplateUrl: require('../network/createLoadBalancer.html'),\n editTemplateUrl: require('../network/editLoadBalancer.html'),\n controller: 'gceCreateLoadBalancerCtrl',\n },\n HTTP: {\n label: 'HTTP(S)',\n createTemplateUrl: require('../http/createHttpLoadBalancer.html'),\n editTemplateUrl: require('../http/editHttpLoadBalancer.html'),\n controller: 'gceCreateHttpLoadBalancerCtrl',\n },\n INTERNAL_MANAGED: {\n label: 'Internal HTTP(S)',\n createTemplateUrl: require('../http/createHttpLoadBalancer.html'),\n editTemplateUrl: require('../http/editHttpLoadBalancer.html'),\n controller: 'gceCreateInternalHttpLoadBalancerCtrl',\n },\n INTERNAL: {\n label: 'Internal',\n createTemplateUrl: require('../common/commonCreateLoadBalancer.html'),\n editTemplateUrl: require('../common/commonEditLoadBalancer.html'),\n controller: 'gceInternalLoadBalancerCtrl',\n },\n SSL: {\n label: 'SSL',\n createTemplateUrl: require('../common/commonCreateLoadBalancer.html'),\n editTemplateUrl: require('../common/commonEditLoadBalancer.html'),\n controller: 'gceSslLoadBalancerCtrl',\n },\n TCP: {\n label: 'TCP',\n createTemplateUrl: require('../common/commonCreateLoadBalancer.html'),\n editTemplateUrl: require('../common/commonEditLoadBalancer.html'),\n controller: 'gceTcpLoadBalancerCtrl',\n },\n};\n\nexport const GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT = 'spinnaker.gce.loadBalancerTypeToWizard.constant';\n\nmodule(GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT, []).constant(\n 'loadBalancerTypeToWizardMap',\n loadBalancerTypeToWizardMap,\n);\n","import type { IController } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService, IModalService } from 'angular-ui-bootstrap';\nimport { find, map } from 'lodash';\n\nimport type { Application } from '@spinnaker/core';\n\nimport type { IGceLoadBalancerToWizardMap } from './loadBalancerTypeToWizardMap.constant';\nimport { GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT } from './loadBalancerTypeToWizardMap.constant';\n\nclass GceLoadBalancerChoiceCtrl implements IController {\n public choices: string[];\n public choice = 'Network';\n\n public static $inject = [\n '$uibModal',\n '$uibModalInstance',\n 'application',\n 'loadBalancerTypeToWizardMap',\n 'forPipelineConfig',\n ];\n constructor(\n public $uibModal: IModalService,\n public $uibModalInstance: IModalInstanceService,\n private application: Application,\n private loadBalancerTypeToWizardMap: IGceLoadBalancerToWizardMap,\n private forPipelineConfig: boolean,\n ) {}\n\n public $onInit(): void {\n this.choices = map(this.loadBalancerTypeToWizardMap, (wizardConfig) => wizardConfig.label);\n }\n\n public choose(choice: string): void {\n const wizard = find(this.loadBalancerTypeToWizardMap, (wizardConfig) => wizardConfig.label === choice);\n if (!wizard) {\n this.$uibModalInstance.dismiss('No wizard config for choice');\n return;\n }\n if (this.forPipelineConfig) {\n this.$uibModalInstance.close(wizard);\n return;\n }\n const wizardResult = this.$uibModal.open({\n templateUrl: wizard.createTemplateUrl,\n controller: `${wizard.controller} as ctrl`,\n size: 'lg',\n resolve: {\n application: () => this.application,\n loadBalancer: (): null => null,\n isNew: () => true,\n forPipelineConfig: () => this.forPipelineConfig,\n },\n }).result;\n this.$uibModalInstance.close(wizardResult);\n }\n}\n\nexport const GCE_LOAD_BALANCER_CHOICE_MODAL = 'spinnaker.gce.loadBalancerChoice.modal.controller';\n\nmodule(GCE_LOAD_BALANCER_CHOICE_MODAL, [GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT]).controller(\n 'gceLoadBalancerChoiceCtrl',\n GceLoadBalancerChoiceCtrl,\n);\n","import type { IModalService } from 'angular-ui-bootstrap';\n\nimport type { Application } from '@spinnaker/core';\n\nimport type { IGceLoadBalancerWizardConfig } from './loadBalancerTypeToWizardMap.constant';\n\nexport interface IGCEPipelineLoadBalancerModalOptions {\n application: Application;\n loadBalancer: any;\n isNew: boolean;\n $uibModal: IModalService;\n}\n\nexport const openGCEPipelineLoadBalancerModal = ({\n application,\n loadBalancer,\n isNew,\n $uibModal,\n}: IGCEPipelineLoadBalancerModalOptions): PromiseLike<any> => {\n return $uibModal\n .open({\n templateUrl: require('./gceLoadBalancerChoice.modal.html'),\n controller: 'gceLoadBalancerChoiceCtrl as ctrl',\n size: 'lg',\n resolve: {\n application: () => application,\n forPipelineConfig: () => true,\n },\n })\n .result.then((wizardConfig: IGceLoadBalancerWizardConfig) => {\n if (!wizardConfig) {\n return null;\n }\n const templateUrl = isNew ? wizardConfig.createTemplateUrl : wizardConfig.editTemplateUrl;\n return $uibModal.open({\n templateUrl,\n controller: `${wizardConfig.controller} as ctrl`,\n size: 'lg',\n resolve: {\n application: () => application,\n loadBalancer: () => loadBalancer,\n isNew: () => isNew,\n forPipelineConfig: () => true,\n },\n }).result;\n });\n};\n","export class HttpLoadBalancerTemplate {\n public provider = 'gce';\n public stack = '';\n public detail = '';\n public region = 'global';\n public loadBalancerType = 'HTTP';\n public certificate = '';\n public certificateMap = '';\n public defaultService: BackendServiceTemplate;\n public hostRules: HostRuleTemplate[] = [];\n public listeners: ListenerTemplate[] = [];\n\n constructor(public credentials: string | null) {}\n}\n\nexport class BackendServiceTemplate {\n public backends: any[] = [];\n public healthCheck: HealthCheckTemplate;\n public sessionAffinity = 'NONE';\n public affinityCookieTtlSec: number | null = null;\n}\n\nexport class HealthCheckTemplate {\n public requestPath = '/';\n public port = 80;\n public checkIntervalSec = 10;\n public timeoutSec = 5;\n public healthyThreshold = 10;\n public unhealthyThreshold = 2;\n}\n\nexport class PathMatcherTemplate {\n public pathRules: PathRuleTemplate[] = [];\n}\n\nexport class HostRuleTemplate {\n public hostPatterns: string[];\n public pathMatcher: PathMatcherTemplate = new PathMatcherTemplate();\n}\n\nexport class PathRuleTemplate {\n public paths: string[];\n}\n\nexport class ListenerTemplate {\n public name: string;\n public port: number;\n public certificate: string | null = null;\n public certificateMap: string | null = null;\n public certificateSource: 'certificate' | 'certificateMap' = 'certificate';\n}\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\nimport { BackendServiceTemplate } from '../templates';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT =\n 'spinnaker.deck.gce.httpLoadBalancer.backendService.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT, []).component(\n 'gceHttpLoadBalancerBackendServiceSelector',\n {\n bindings: {\n deleteService: '&',\n backendService: '=',\n command: '=',\n index: '=',\n },\n templateUrl: require('./backendService.component.html'),\n controller: function () {\n this.$onInit = () => {\n this.backingData = this.command.backingData;\n this.loadBalancer = this.command.loadBalancer;\n const servicesByName = this.backingData.backendServicesKeyedByName;\n\n this.onBackendServiceSelect = (selectedBackendService) => {\n assign(selectedBackendService);\n this.command.onHealthCheckSelected(selectedBackendService.healthCheck, this.command);\n };\n\n this.toggleEditExisting = () => {\n this.editExisting = !this.editExisting;\n if (!this.editExisting) {\n const template = new BackendServiceTemplate();\n assign(template);\n } else {\n delete this.backendService.name;\n }\n };\n\n this.getAllHealthChecks = () => {\n const allHealthChecks = this.loadBalancer.healthChecks.concat(this.backingData.healthChecks);\n return _.chain(allHealthChecks)\n .filter((hc) => hc.account === this.loadBalancer.credentials || !hc.account)\n .map((hc) => hc.name)\n .uniq()\n .value();\n };\n\n this.getSessionAffinitySuggestions = () => {\n if (this.loadBalancer.loadBalancerType === 'HTTP') {\n return ['None', 'Client IP', 'Generated Cookie'];\n } else {\n return ['None', 'Client IP', 'Generated Cookie', 'Header Field', 'HTTP Cookie'];\n }\n };\n\n this.getAllServiceNames = () => {\n return this.command.backingData.backendServices\n .filter((service) => service.account === this.loadBalancer.credentials)\n .map((service) => service.name);\n };\n\n this.maxCookieTtl = 60 * 60 * 24; // One day.\n\n const getBackendServiceName = () => {\n return _.get(this, 'backendService.name');\n };\n\n if (servicesByName[getBackendServiceName()]) {\n this.editExisting = true;\n }\n\n const assign = (toAssign) => {\n this.loadBalancer.backendServices[this.index] = this.backendService = toAssign;\n };\n };\n },\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT =\n 'spinnaker.deck.gce.httpLoadBalancer.basicSettings.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT, []).component(\n 'gceHttpLoadBalancerBasicSettings',\n {\n bindings: {\n command: '=',\n application: '=',\n },\n templateUrl: require('./basicSettings.component.html'),\n controller: function () {\n this.$onInit = () => {\n const c = this.command;\n this.loadBalancer = c.loadBalancer;\n this.accounts = c.backingData.accounts;\n const loadBalancerMap = c.backingData.loadBalancerMap;\n\n this.getName = (loadBalancer, applicationName) => {\n const loadBalancerName = [applicationName, loadBalancer.stack || '', loadBalancer.detail || ''].join('-');\n return _.trimEnd(loadBalancerName, '-');\n };\n\n this.updateName = (lb, appName) => {\n lb.urlMapName = this.getName(lb, appName);\n };\n\n this.accountChanged = (account) => {\n this.existingLoadBalancerNames = _.get(loadBalancerMap, [account, 'urlMapNames']) || [];\n c.onAccountChange(c);\n };\n\n if (!this.loadBalancer.name) {\n this.updateName(this.loadBalancer, this.application.name);\n }\n\n this.existingLoadBalancerNames = _.get(loadBalancerMap, [this.loadBalancer.credentials, 'urlMapNames']) || [];\n };\n },\n },\n);\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\n\nimport type { CacheInitializerService } from '@spinnaker/core';\nimport { CACHE_INITIALIZER_SERVICE, InfrastructureCaches } from '@spinnaker/core';\n\nclass GceCacheRefreshCtrl implements IController {\n public capitalizedKey: string;\n public depluralizedKey: string;\n public renderCompact: boolean;\n public refreshing = false;\n public tooltipTemplate = require('./cacheRefreshTooltip.html');\n private onRefresh: Function;\n private cacheKey: string;\n private cacheKeyAlias: string;\n\n public static $inject = ['cacheInitializer'];\n constructor(private cacheInitializer: CacheInitializerService) {}\n\n public $onInit(): void {\n const cacheKeyAlias = this.cacheKeyAlias || this.cacheKey;\n this.capitalizedKey = cacheKeyAlias[0].toUpperCase() + cacheKeyAlias.substring(1);\n this.depluralizedKey = cacheKeyAlias.substring(0, cacheKeyAlias.length - 1);\n }\n\n public getRefreshTime(): number {\n return InfrastructureCaches.get(this.cacheKey).getStats().ageMax;\n }\n\n public refresh(): void {\n this.refreshing = true;\n this.cacheInitializer\n .refreshCache(this.cacheKey)\n .then(() => this.onRefresh())\n .then(() => {\n this.refreshing = false;\n });\n }\n}\n\nconst gceCacheRefresh: IComponentOptions = {\n bindings: {\n onRefresh: '&',\n cacheKey: '@',\n cacheKeyAlias: '@',\n renderCompact: '<',\n },\n controller: GceCacheRefreshCtrl,\n templateUrl: require('./cacheRefresh.component.html'),\n};\n\nexport const GCE_CACHE_REFRESH = 'spinnaker.gce.cacheRefresh.component';\nmodule(GCE_CACHE_REFRESH, [CACHE_INITIALIZER_SERVICE]).component('gceCacheRefresh', gceCacheRefresh);\n","import { module } from 'angular';\n\nimport type { ISearchResults } from '@spinnaker/core';\nimport { InfrastructureCaches, SearchService } from '@spinnaker/core';\n\nexport interface IGceCertificate {\n account: string;\n name: string;\n provider: string;\n type: string;\n}\n\nexport class GceCertificateReader {\n public listCertificates(): PromiseLike<IGceCertificate[]> {\n return SearchService.search<IGceCertificate>(\n { q: '', type: 'sslCertificates', allowShortQuery: 'true' },\n InfrastructureCaches.get('certificates'),\n )\n .then((searchResults: ISearchResults<IGceCertificate>) => {\n if (searchResults && searchResults.results) {\n return searchResults.results.filter((certificate) => certificate.provider === 'gce');\n } else {\n return [];\n }\n })\n .catch(() => []);\n }\n}\n\nexport const GCE_CERTIFICATE_READER = 'spinnaker.gce.certificateReader.service';\nmodule(GCE_CERTIFICATE_READER, []).service('gceCertificateReader', GceCertificateReader);\n","import _ from 'lodash';\n\nexport interface IStringMap {\n [key: string]: string;\n}\n\nexport const sessionAffinityViewToModelMap: IStringMap = {\n None: 'NONE',\n 'Client IP': 'CLIENT_IP',\n 'Generated Cookie': 'GENERATED_COOKIE',\n 'Client IP and protocol': 'CLIENT_IP_PROTO',\n 'Client IP, port and protocol': 'CLIENT_IP_PORT_PROTO',\n 'Header Field': 'HEADER_FIELD',\n 'HTTP Cookie': 'HTTP_COOKIE',\n 'Strong Cookie': 'STRONG_COOKIE_AFFINITY',\n};\n\nexport const sessionAffinityModelToViewMap = _.invert<IStringMap, IStringMap>(sessionAffinityViewToModelMap);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { NameUtils } from '@spinnaker/core';\n\nimport { sessionAffinityModelToViewMap, sessionAffinityViewToModelMap } from '../common/sessionAffinityNameMaps';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE = 'spinnaker.gce.deck.httpLoadBalancer.transformer';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE, []).factory(\n 'gceHttpLoadBalancerTransformer',\n function () {\n // SERIALIZE\n\n const keysToOmit = ['backendServices', 'healthChecks', 'listeners', 'stack', 'detail'];\n\n function serialize(originalCommand, originalLoadBalancer) {\n const command = _.cloneDeep(originalCommand);\n const { loadBalancer, backingData } = command;\n\n mapComponentNamesToObjects(loadBalancer, backingData);\n\n loadBalancer.hostRules = loadBalancer.hostRules.reduce((hostRules, hostRule) => {\n return hostRules.concat(\n hostRule.hostPatterns.map((hostPattern) => {\n return {\n hostPatterns: [hostPattern],\n pathMatcher: _.cloneDeep(hostRule.pathMatcher),\n };\n }),\n );\n }, []);\n\n const commands = buildCommandForEachListener(loadBalancer);\n\n if (originalLoadBalancer) {\n commands[0].listenersToDelete = _.chain(originalLoadBalancer.listeners)\n .map('name')\n .difference(_.map(originalCommand.loadBalancer.listeners, 'name'))\n .value();\n }\n\n return commands;\n }\n\n function mapComponentNamesToObjects(loadBalancer, backingData) {\n const unifiedHealthChecksKeyedByName = _.assign(\n backingData.healthChecksKeyedByName,\n _.keyBy(loadBalancer.healthChecks, 'name'),\n );\n const unifiedBackendServicesKeyedByName = _.assign(\n backingData.backendServicesKeyedByName,\n _.keyBy(loadBalancer.backendServices, 'name'),\n );\n\n _.forEach(unifiedBackendServicesKeyedByName, (service) => {\n service.healthCheck = unifiedHealthChecksKeyedByName[service.healthCheck];\n // Map human readable text back to session affinity code.\n service.sessionAffinity = sessionAffinityViewToModelMap[service.sessionAffinity] || service.sessionAffinity;\n });\n\n loadBalancer.defaultService = unifiedBackendServicesKeyedByName[loadBalancer.defaultService];\n mapBackendServiceNamesToObjects(loadBalancer.hostRules, unifiedBackendServicesKeyedByName);\n }\n\n function mapBackendServiceNamesToObjects(hostRules, servicesByName) {\n hostRules.forEach((hostRule) => {\n const p = hostRule.pathMatcher;\n\n p.defaultService = servicesByName[p.defaultService];\n\n p.pathRules.forEach((pathRule) => {\n pathRule.backendService = servicesByName[pathRule.backendService];\n });\n });\n }\n\n function buildCommandForEachListener(loadBalancer) {\n return loadBalancer.listeners.map((listener) => {\n let command = _.cloneDeep(loadBalancer);\n command = _.omit(command, keysToOmit);\n // Determine the authoritative cert source. The certificateSource field is explicit when\n // present, but listeners deserialized from LBs created before this field existed may only\n // have certificate/certificateMap values without a source. The fallback condition handles\n // that: no certificate + truthy certificateMap implies certificateMap mode.\n const useCertificateMap =\n listener.certificateSource === 'certificateMap' || (!listener.certificate && !!listener.certificateMap);\n command.name = listener.name;\n command.portRange = listener.port;\n command.certificate = useCertificateMap ? null : listener.certificate || null;\n command.certificateMap = useCertificateMap ? listener.certificateMap || null : null;\n command.ipAddress = listener.ipAddress;\n command.subnet = listener.subnet;\n\n return command;\n });\n }\n\n // DESERIALIZE\n\n function deserialize(loadBalancer) {\n const { backendServices, healthChecks, defaultService } = getHealthChecksAndBackendServices(loadBalancer);\n const hostRules = getHostRules(loadBalancer);\n const listeners = getListeners(loadBalancer);\n\n return {\n defaultService: defaultService.name,\n backendServices,\n healthChecks,\n hostRules,\n listeners,\n network: loadBalancer.network,\n region: loadBalancer.region,\n urlMapName: loadBalancer.urlMapName,\n credentials: loadBalancer.credentials || loadBalancer.account,\n };\n }\n\n function getHealthChecksAndBackendServices(loadBalancer) {\n const defaultService = loadBalancer.defaultService;\n let backendServices = [loadBalancer.defaultService];\n\n if (loadBalancer.hostRules) {\n backendServices = loadBalancer.hostRules.reduce((services, hostRule) => {\n services = services.concat(hostRule.pathMatcher.defaultService);\n return hostRule.pathMatcher.pathRules.reduce(\n (services, pathRule) => services.concat(pathRule.backendService),\n services,\n );\n }, backendServices);\n }\n\n const healthChecks = _.chain(backendServices).map('healthCheck').uniqBy('name').cloneDeep().value();\n healthChecks.forEach((hc) => {\n hc.account = loadBalancer.account || loadBalancer.credentials;\n });\n backendServices = _.uniqBy(backendServices, 'name');\n\n backendServices.forEach((service) => {\n // Map health check to health check name so we don't have to deal with object references\n service.healthCheck = service.healthCheck.name;\n // Map session affinity code to more human readable text.\n service.sessionAffinity = sessionAffinityModelToViewMap[service.sessionAffinity] || service.sessionAffinity;\n });\n\n return { backendServices, healthChecks, defaultService };\n }\n\n function getHostRules(loadBalancer) {\n return mapBackendServicesToNames(_.cloneDeep(loadBalancer.hostRules));\n }\n\n function getListeners(loadBalancer) {\n loadBalancer.listeners.forEach((listener) => {\n const { stack, freeFormDetails } = NameUtils.parseLoadBalancerName(listener.name);\n listener.stack = stack;\n listener.detail = freeFormDetails;\n listener.created = true;\n listener.certificate = listener.certificate || null;\n // Normalize certificateMap from the full Certificate Manager URL returned by the server\n // (e.g. //certificatemanager.googleapis.com/projects/p/locations/global/certificateMaps/cm)\n // to its short resource name. This mirrors getCertificateMapName in listener.component.js.\n listener.certificateMap = listener.certificateMap ? _.last(listener.certificateMap.split('/')) : null;\n // Infer certificateSource for listeners deserialized from LBs created before this field\n // existed. The presence of certificateMap implies certificateMap mode.\n listener.certificateSource = listener.certificateMap ? 'certificateMap' : 'certificate';\n });\n\n return loadBalancer.listeners;\n }\n\n function mapBackendServicesToNames(hostRules) {\n // Map backend service to backend service name so we don't have to deal with object references\n hostRules.forEach((hostRule) => {\n const p = hostRule.pathMatcher;\n\n p.defaultService = p.defaultService.name;\n\n p.pathRules.forEach((pathRule) => {\n pathRule.backendService = pathRule.backendService.name;\n });\n });\n\n return hostRules;\n }\n\n return { serialize, deserialize };\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, LOAD_BALANCER_READ_SERVICE, NetworkReader, SubnetReader } from '@spinnaker/core';\n\nimport { GCE_ADDRESS_READER } from '../../../address/address.reader';\nimport { GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER } from '../../../backendService/backendService.reader';\nimport { GCE_CERTIFICATE_READER } from '../../../certificate/certificate.reader';\nimport { sessionAffinityModelToViewMap } from '../common/sessionAffinityNameMaps';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../../common/xpnNaming.gce.service';\nimport { GCEProviderSettings } from '../../../gce.settings';\nimport { GCE_HEALTH_CHECK_READER } from '../../../healthCheck/healthCheck.read.service';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../../httpLoadBalancerUtils.service';\nimport { HttpLoadBalancerTemplate, ListenerTemplate } from './templates';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE } from './transformer.service';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE =\n 'spinnaker.deck.gce.httpLoadBalancer.backing.service';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE, [\n GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER,\n GCE_CERTIFICATE_READER,\n LOAD_BALANCER_READ_SERVICE,\n GCE_HTTP_LOAD_BALANCER_UTILS,\n GCE_ADDRESS_READER,\n GCE_HEALTH_CHECK_READER,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n]).factory('gceHttpLoadBalancerCommandBuilder', [\n '$q',\n 'gceHttpLoadBalancerUtils',\n 'gceBackendServiceReader',\n 'gceCertificateReader',\n 'gceHealthCheckReader',\n 'gceHttpLoadBalancerTransformer',\n 'loadBalancerReader',\n 'gceAddressReader',\n 'gceXpnNamingService',\n function (\n $q,\n gceHttpLoadBalancerUtils,\n gceBackendServiceReader,\n gceCertificateReader,\n gceHealthCheckReader,\n gceHttpLoadBalancerTransformer,\n loadBalancerReader,\n gceAddressReader,\n gceXpnNamingService,\n ) {\n function buildCommand({ originalLoadBalancer, isNew, isInternal }) {\n originalLoadBalancer = _.cloneDeep(originalLoadBalancer);\n\n return buildBackingDataAndLoadBalancer(originalLoadBalancer, isNew, isInternal).then(\n ({ backingData, loadBalancer }) => {\n return {\n backingData,\n getAllBackendServices,\n isNew,\n loadBalancer,\n onAccountChange,\n onBackendServiceRefresh,\n onBackendServiceSelected,\n onRegionSelected,\n onCertificateRefresh,\n onHealthCheckRefresh,\n onHealthCheckSelected,\n getUnusedBackendServices,\n removeUnusedBackendServices,\n getUnusedHealthChecks,\n removeUnusedHealthChecks,\n onAddressRefresh,\n };\n },\n );\n }\n\n function buildBackingDataAndLoadBalancer(originalLoadBalancer, isNew, isInternal) {\n let region = null;\n if (isInternal) {\n region = originalLoadBalancer ? originalLoadBalancer.region : GCEProviderSettings.defaults.region;\n }\n return buildBackingData(region).then((backingData) => {\n const loadBalancer = buildLoadBalancer(isNew, originalLoadBalancer, isInternal);\n\n unifyDataSources(backingData, loadBalancer);\n\n return { backingData, loadBalancer };\n });\n }\n\n function buildBackingData(region) {\n const promises = {\n backendServices: getBackendServices(region),\n healthChecks: getHealthChecks(region),\n certificates: getCertificates(),\n loadBalancerMap: getLoadBalancerMap(region),\n networks: getNetworks(),\n subnets: SubnetReader.listSubnetsByProvider('gce'),\n addresses: gceAddressReader.listAddresses(region),\n accounts: getAccounts(),\n };\n return $q.all(promises);\n }\n\n function buildLoadBalancer(isNew, loadBalancer, isInternal) {\n const loadBalancerTemplate = new HttpLoadBalancerTemplate(GCEProviderSettings.defaults.account || null);\n if (isInternal) {\n loadBalancerTemplate.loadBalancerType = 'INTERNAL_MANAGED';\n loadBalancerTemplate.isInternal = true;\n if (loadBalancer) {\n loadBalancer.network = gceXpnNamingService.decorateXpnResourceIfNecessary(\n loadBalancer.project,\n loadBalancer.network,\n );\n loadBalancer.listeners.forEach((listener) => {\n listener.subnet = gceXpnNamingService.decorateXpnResourceIfNecessary(loadBalancer.project, listener.subnet);\n });\n }\n loadBalancerTemplate.region = GCEProviderSettings.defaults.region;\n loadBalancerTemplate.network = 'default';\n } else {\n loadBalancerTemplate.loadBalancerType = 'HTTP';\n loadBalancerTemplate.isInternal = false;\n }\n\n let mixinData;\n if (isNew) {\n mixinData = {\n backendServices: [],\n listeners: [new ListenerTemplate()],\n healthChecks: [],\n };\n } else {\n mixinData = gceHttpLoadBalancerTransformer.deserialize(loadBalancer);\n }\n\n const loadBalancerData = _.assign(loadBalancerTemplate, mixinData);\n return loadBalancerData;\n }\n\n function unifyDataSources(backingData, loadBalancer) {\n setAccount(backingData.accounts, loadBalancer);\n removeExistingListenersFromBackingData(backingData, loadBalancer.listeners);\n\n // update backing data with any values coming from load balancer -- they are more up to date.\n const lbHealthCheckMap = _.keyBy(loadBalancer.healthChecks, 'name');\n const backingDataHealthCheckMap = _.keyBy(backingData.healthChecks, 'name');\n\n backingData.healthChecksKeyedByName = _.assign(backingDataHealthCheckMap, _.cloneDeep(lbHealthCheckMap));\n backingData.healthChecksKeyedByNameCopy = _.cloneDeep(backingDataHealthCheckMap);\n backingData.healthChecks = _.map(backingDataHealthCheckMap, _.identity);\n\n const lbBackendServicesMap = _.keyBy(loadBalancer.backendServices, 'name');\n const backingDataBackendServiceMap = _.keyBy(backingData.backendServices, 'name');\n\n backingData.backendServicesKeyedByName = _.assign(\n backingDataBackendServiceMap,\n _.cloneDeep(lbBackendServicesMap),\n );\n backingData.backendServicesKeyedByNameCopy = _.cloneDeep(backingDataBackendServiceMap);\n backingData.backendServices = _.map(backingDataBackendServiceMap, _.identity);\n\n backingData.regions = backingData.accounts\n .find((account) => account.name === loadBalancer.credentials)\n .regions.map((region) => region.name);\n\n backingData.subnetMap = _.groupBy(backingData.subnets, 'network');\n backingData.internalHttpLbNetworks = backingData.networks.filter((network) =>\n backingData.subnetMap[network].find((subnet) => subnet.purpose === 'INTERNAL_HTTPS_LOAD_BALANCER'),\n );\n }\n\n function removeExistingListenersFromBackingData(backingData, existingListeners) {\n const accountNames = backingData.accounts.map((account) => account.name);\n\n accountNames.forEach((accountName) => {\n if (_.has(backingData, ['loadBalancerMap', accountName, 'listeners'])) {\n backingData.loadBalancerMap[accountName].listeners = _.without(\n backingData.loadBalancerMap[accountName].listeners,\n ...existingListeners.map((listener) => listener.name),\n );\n }\n });\n }\n\n function setAccount(accounts, loadBalancerData) {\n const accountNames = _.map(accounts, 'name');\n const credentials = _.get(loadBalancerData, 'credentials.name') || loadBalancerData.credentials;\n\n if (!accountNames.includes(credentials)) {\n loadBalancerData.credentials = _.first(accountNames);\n }\n }\n\n function getHealthChecks(region) {\n return gceHealthCheckReader.listHealthChecks().then((healthChecks) => {\n return healthChecks.filter((healthCheck) => !region || healthCheck.region === region);\n });\n }\n\n function getNetworks() {\n return NetworkReader.listNetworksByProvider('gce').then((networks) => {\n return _.chain(networks).map('name').compact().uniq().value();\n });\n }\n\n function getBackendServices(region) {\n const kind = region ? 'regionBackendService' : 'globalBackendService';\n return gceBackendServiceReader.listBackendServices(kind).then((backendServices) => {\n backendServices = backendServices.filter((backendService) => !region || backendService.region === region);\n backendServices.forEach((service) => {\n service.healthCheck = service.healthCheckLink.split('/').pop();\n\n const ttlIsDefined = typeof service.affinityCookieTtlSec === 'string';\n service.affinityCookieTtlSec = ttlIsDefined ? Number(service.affinityCookieTtlSec) : null;\n\n service.sessionAffinity = sessionAffinityModelToViewMap[service.sessionAffinity] || service.sessionAffinity;\n });\n\n return backendServices;\n });\n }\n\n function getCertificates() {\n return gceCertificateReader.listCertificates();\n }\n\n function getAccounts() {\n return AccountService.listAccounts('gce');\n }\n\n function getLoadBalancerMap(region) {\n return loadBalancerReader.listLoadBalancers('gce').then((lbs) => {\n return _.chain(lbs)\n .map((lb) => lb.accounts)\n .flatten()\n .groupBy('name')\n .mapValues((accounts) => {\n const loadBalancers = _.chain(accounts)\n .map((a) => a.regions)\n .flatten()\n .filter((region) => region.name === (region || gceHttpLoadBalancerUtils.REGION))\n .map((region) => region.loadBalancers)\n .flatten()\n .value();\n\n const urlMapNames = _.chain(loadBalancers).map('urlMapName').uniq().value();\n const listeners = _.chain(loadBalancers).map('name').uniq().value();\n\n return { urlMapNames, listeners };\n })\n .valueOf();\n });\n }\n\n function onHealthCheckRefresh(command) {\n getHealthChecks(command.loadBalancer.region).then((healthChecks) => {\n command.backingData.healthChecks = healthChecks;\n command.backingData.healthChecksKeyedByName = _.keyBy(healthChecks, 'name');\n command.backingData.healthChecksKeyedByNameCopy = _.cloneDeep(command.backingData.healthChecksKeyedByName);\n\n command.loadBalancer.healthChecks = command.loadBalancer.healthChecks.map((hc) => {\n const updated = command.backingData.healthChecksKeyedByName[_.get(hc, 'name')];\n if (updated) {\n return _.cloneDeep(updated);\n } else {\n return hc;\n }\n });\n });\n }\n\n function onCertificateRefresh(command) {\n getCertificates().then((certificates) => {\n command.backingData.certificates = certificates;\n });\n }\n\n function onBackendServiceRefresh(command) {\n getBackendServices(command.loadBalancer.region).then((backendServices) => {\n command.backingData.backendServices = backendServices;\n command.backingData.backendServicesKeyedByName = _.keyBy(backendServices, 'name');\n command.backingData.backendServicesKeyedByNameCopy = _.cloneDeep(\n command.backingData.backendServicesKeyedByName,\n );\n\n command.loadBalancer.backendServices = command.loadBalancer.backendServices.map((service) => {\n const updated = command.backingData.backendServicesKeyedByName[_.get(service, 'name')];\n if (updated) {\n return _.cloneDeep(updated);\n } else {\n return service;\n }\n });\n });\n }\n\n function onRegionSelected(command) {\n buildBackingData(command.loadBalancer.region).then((backingData) => {\n Object.assign(command.backingData, backingData);\n unifyDataSources(command.backingData, command.loadBalancer);\n });\n }\n\n function onHealthCheckSelected(selectedName, command) {\n if (!command.loadBalancer.healthChecks.find((hc) => _.get(hc, 'name') === selectedName)) {\n const selectedObject = command.backingData.healthChecksKeyedByName[selectedName];\n if (selectedObject) {\n command.loadBalancer.healthChecks.push(selectedObject);\n }\n }\n }\n\n function onBackendServiceSelected(selectedName, command) {\n if (!command.loadBalancer.backendServices.find((service) => service.name === selectedName)) {\n const selectedObject = command.backingData.backendServicesKeyedByName[selectedName];\n command.loadBalancer.backendServices.push(selectedObject);\n if (selectedObject.healthCheck) {\n onHealthCheckSelected(selectedObject.healthCheck, command);\n }\n }\n }\n\n function getAllBackendServices(command) {\n const allBackendServices = command.loadBalancer.backendServices.concat(command.backingData.backendServices);\n return _.chain(allBackendServices)\n .filter((service) => {\n return (\n service.account === command.loadBalancer.credentials || service.account === command.loadBalancer.account\n );\n })\n .map('name')\n .compact()\n .uniq()\n .value();\n }\n\n function getUnusedHealthChecks(command) {\n return _.chain(command.loadBalancer.healthChecks)\n .map('name')\n .difference(_.map(command.loadBalancer.backendServices, 'healthCheck'))\n .compact()\n .uniq()\n .value();\n }\n\n function getUnusedBackendServices(command) {\n const defaultService = command.loadBalancer.defaultService;\n const hostRuleServices = _.map(command.loadBalancer.hostRules, 'pathMatcher.defaultService');\n const pathRuleServices = _.chain(command.loadBalancer.hostRules)\n .map('pathMatcher.pathRules')\n .flatten()\n .map('backendService')\n .value();\n\n const usedServices = _.chain([defaultService, ...hostRuleServices, ...pathRuleServices])\n .compact()\n .uniq()\n .value();\n\n return _.chain(command.loadBalancer.backendServices)\n .map('name')\n .difference(usedServices)\n .compact()\n .uniq()\n .value();\n }\n\n function removeUnusedBackendServices(command) {\n const unusedBackendServices = getUnusedBackendServices(command);\n command.loadBalancer.backendServices = command.loadBalancer.backendServices.filter(\n (service) => !unusedBackendServices.includes(service.name),\n );\n }\n\n function removeUnusedHealthChecks(command) {\n const unusedHealthChecks = getUnusedHealthChecks(command);\n command.loadBalancer.healthChecks = command.loadBalancer.healthChecks.filter(\n (healthCheck) => !unusedHealthChecks.includes(healthCheck.name),\n );\n }\n\n function onAccountChange(command) {\n command.loadBalancer.backendServices = [];\n command.loadBalancer.healthChecks = [];\n command.loadBalancer.hostRules = [];\n command.loadBalancer.listeners = [new ListenerTemplate()];\n command.loadBalancer.defaultService = null;\n command.backingData.regions = command.backingData.accounts\n .find((account) => account.name === command.loadBalancer.credentials)\n .regions.map((region) => region.name);\n }\n\n function onAddressRefresh(command) {\n gceAddressReader.listAddresses('global').then((addresses) => {\n command.backingData.addresses = addresses;\n });\n }\n\n return { buildCommand };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE =\n 'spinnaker.deck.gce.loadBalancer.hostAndPathRules.service';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE, []).factory(\n 'hostAndPathRulesService',\n function () {\n function buildTable(hostRules, defaultService) {\n const defaultRow = buildRow('Any unmatched (default)', 'Any unmatched (default)', defaultService.name);\n if (hostRules.length === 0) {\n return [defaultRow];\n }\n\n return hostRules.reduce(\n (rows, hostRule) => {\n const [hostPattern] = hostRule.hostPatterns;\n const { defaultService, pathRules } = hostRule.pathMatcher;\n\n rows.push(buildRow(hostPattern, '/*', defaultService.name));\n\n return rows.concat(\n pathRules.reduce((rows, pathRule) => {\n const { backendService, paths } = pathRule;\n return rows.concat(paths.map((path) => buildRow(hostPattern, path, backendService.name)));\n }, []),\n );\n },\n [defaultRow],\n );\n }\n\n function buildRow(hostPattern, path, backend) {\n return { hostPattern, path, backend };\n }\n\n return { buildTable };\n },\n);\n","import { module } from 'angular';\n\nimport { GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE } from './hostAndPathRules.service';\n\n('use strict');\n\nexport const GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER =\n 'spinnaker.deck.gce.loadBalancer.hostAndPathRules.controller';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER, [\n GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE,\n]).controller('gceHostAndPathRulesCtrl', [\n 'hostRules',\n 'defaultService',\n 'loadBalancerName',\n '$uibModalInstance',\n 'hostAndPathRulesService',\n function (hostRules, defaultService, loadBalancerName, $uibModalInstance, hostAndPathRulesService) {\n this.table = hostAndPathRulesService.buildTable(hostRules, defaultService);\n this.loadBalancerName = loadBalancerName;\n this.close = $uibModalInstance.dismiss;\n },\n]);\n","import { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER } from './hostAndPathRules.controller';\n\n('use strict');\n\nexport const GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT =\n 'spinnaker.deck.gce.loadBalancer.hostAndPathRulesButton.component';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT, [\n ANGULAR_UI_BOOTSTRAP,\n GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER,\n]).component('gceHostAndPathRulesButton', {\n bindings: {\n hostRules: '=',\n defaultService: '=',\n loadBalancerName: '=',\n },\n template: '<a href ng-click=\"$ctrl.viewHostAndPathRules()\">View Host and Path Rules</a>',\n controller: [\n '$uibModal',\n function ($uibModal) {\n this.viewHostAndPathRules = () => {\n $uibModal.open({\n templateUrl: require('./hostAndPathRules.modal.html'),\n controller: 'gceHostAndPathRulesCtrl',\n controllerAs: 'ctrl',\n size: 'lg',\n resolve: {\n hostRules: () => this.hostRules,\n defaultService: () => this.defaultService,\n loadBalancerName: () => this.loadBalancerName,\n },\n });\n };\n },\n ],\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { HealthCheckTemplate } from '../templates';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT =\n 'spinnaker.deck.httpLoadBalancer.healthCheck.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT, []).component(\n 'gceHttpLoadBalancerHealthCheck',\n {\n bindings: {\n command: '=',\n deleteHealthCheck: '&',\n healthCheck: '=',\n index: '=',\n },\n templateUrl: require('./healthCheck.component.html'),\n controller: function () {\n this.$onInit = () => {\n this.max = Number.MAX_SAFE_INTEGER;\n this.backingData = this.command.backingData;\n this.loadBalancer = this.command.loadBalancer;\n const healthChecksByName = this.backingData.healthChecksKeyedByName;\n\n this.onHealthCheckSelect = (selectedHealthCheck) => {\n assign(selectedHealthCheck);\n };\n\n this.getAllHealthCheckNames = () => {\n return this.command.backingData.healthChecks\n .filter((hc) => hc.account === this.loadBalancer.credentials)\n .map((hc) => hc.name);\n };\n\n this.toggleEditExisting = () => {\n this.editExisting = !this.editExisting;\n if (!this.editExisting) {\n assign(new HealthCheckTemplate());\n } else {\n delete this.healthCheck.name;\n }\n };\n\n const assign = (toAssign) => {\n this.loadBalancer.healthChecks[this.index] = this.healthCheck = toAssign;\n };\n\n const getHealthCheckName = () => {\n return _.get(this, 'healthCheck.name');\n };\n\n this.onProtocolChange = () => {\n if (this.healthCheck.healthCheckType !== this.healthCheckType) {\n assign(Object.assign({}, new HealthCheckTemplate(), { healthCheckType: this.healthCheckType }));\n }\n };\n\n if (healthChecksByName[getHealthCheckName()]) {\n this.editExisting = true;\n }\n\n this.healthCheckType = this.healthCheck.healthCheckType;\n };\n },\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT =\n 'spinnaker.deck.gce.httpLoadBalancer.pathRule.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT, []).component('gcePathRule', {\n bindings: {\n pathRule: '=',\n command: '=',\n index: '=',\n deletePathRule: '&',\n },\n templateUrl: require('./pathRule.component.html'),\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT } from '../pathRule/pathRule.component';\nimport { PathRuleTemplate } from '../templates';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT =\n 'spinnaker.deck.gce.httpLoadBalancer.hostRule.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT, [\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT,\n]).component('gceHostRule', {\n bindings: {\n hostRule: '=',\n index: '=',\n command: '=',\n deleteHostRule: '&',\n },\n templateUrl: require('./hostRule.component.html'),\n controller: function () {\n this.$onInit = () => {\n this.loadBalancer = this.command.loadBalancer;\n const pathRules = this.hostRule.pathMatcher.pathRules;\n\n this.addPathRule = () => {\n pathRules.push(new PathRuleTemplate());\n };\n\n this.deletePathRule = (index) => {\n pathRules.splice(index, 1);\n };\n };\n },\n});\n","'use strict';\n\nimport * as angular from 'angular';\n\nimport { InfrastructureCaches, TaskExecutor } from '@spinnaker/core';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE =\n 'spinnaker.deck.gce.httpLoadBalancer.write.service';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE; // for backwards compatibility\nangular\n .module(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE, [])\n .factory('gceHttpLoadBalancerWriter', function () {\n function upsertLoadBalancers(loadBalancers, application, descriptor) {\n loadBalancers.forEach((lb) => {\n angular.extend(lb, {\n type: 'upsertLoadBalancer',\n cloudProvider: 'gce',\n loadBalancerName: lb.name,\n });\n });\n\n InfrastructureCaches.clearCache('backendServices');\n InfrastructureCaches.clearCache('healthChecks');\n\n return TaskExecutor.executeTask({\n job: loadBalancers,\n application: application,\n description: `${descriptor} Load Balancer: ${loadBalancers[0].urlMapName}`,\n });\n }\n\n function deleteLoadBalancers(loadBalancer, application, params = {}) {\n const job = {\n type: 'deleteLoadBalancer',\n loadBalancerName: loadBalancer.listeners[0].name,\n regions: [loadBalancer.region || 'global'],\n region: loadBalancer.region || 'global',\n loadBalancerType: loadBalancer.loadBalancerType,\n cloudProvider: loadBalancer.provider,\n credentials: loadBalancer.account,\n };\n\n angular.extend(job, params);\n\n InfrastructureCaches.clearCache('backendServices');\n InfrastructureCaches.clearCache('healthChecks');\n\n return TaskExecutor.executeTask({\n job: [job],\n application: application,\n description: `Delete load balancer: ${loadBalancer.urlMapName} in ${loadBalancer.account}:global`,\n });\n }\n\n return { upsertLoadBalancers, deleteLoadBalancers };\n });\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\nimport type { IGceAddress } from '../../../address/address.reader';\n\nclass GceAddressSelectorCtrl implements IController {\n public selectedAddress: IGceAddress;\n public addressList: IGceAddress[];\n public account: string;\n // The IP address string is the only piece that we can expect a parent resource to keep track of.\n // We'll try to match this IP to a full address map.\n private initialIpAddress: string;\n\n public $onInit(): void {\n this.selectedAddress = this.addressList.find((address) => address.address === this.initialIpAddress);\n if (!this.selectedAddress) {\n this.selectedAddress = { address: this.initialIpAddress, account: this.account };\n }\n }\n}\n\nconst gceAddressSelector: IComponentOptions = {\n bindings: {\n initialIpAddress: '<',\n addressList: '<',\n readOnly: '<',\n onAddressSelect: '&',\n account: '<',\n },\n template: `\n <ui-select on-select=\"$ctrl.onAddressSelect({address: $ctrl.selectedAddress})\"\n ng-disabled=\"$ctrl.readOnly\"\n ng-model=\"$ctrl.selectedAddress\"\n class=\"form-control input-sm\">\n <ui-select-match allow-clear>\n {{$ctrl.selectedAddress.address}} <span ng-if=\"$ctrl.selectedAddress.name\">({{$ctrl.selectedAddress.name}})</span>\n </ui-select-match>\n <ui-select-choices repeat=\"address in $ctrl.addressList | filter: {name: $select.search, account: $ctrl.account}\">\n <span>\n {{address.address}} <span ng-if=\"address.name\">({{address.name}})</span> <br>\n </span>\n </ui-select-choices>\n </ui-select>`,\n controller: GceAddressSelectorCtrl,\n};\n\nexport const GCE_ADDRESS_SELECTOR = 'spinnaker.gce.addressSelector.component';\nmodule(GCE_ADDRESS_SELECTOR, []).component('gceAddressSelector', gceAddressSelector);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { GCE_ADDRESS_SELECTOR } from '../../common/addressSelector.component';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT =\n 'spinnaker.deck.gce.httpLoadBalancer.listener.component';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT, [GCE_ADDRESS_SELECTOR]).component(\n 'gceListener',\n {\n bindings: {\n command: '=',\n listener: '=',\n deleteListener: '&',\n index: '=',\n application: '=',\n },\n templateUrl: require('./listener.component.html'),\n controller: function () {\n this.$onInit = () => {\n this.certificates = this.command.backingData.certificates;\n const loadBalancerMap = this.command.backingData.loadBalancerMap;\n\n this.getName = (listener, applicationName) => {\n const listenerName = [applicationName, listener.stack || '', listener.detail || ''].join('-');\n return _.trimEnd(listenerName, '-');\n };\n\n this.getCertificates = () => {\n return this.command.backingData.certificates\n .filter((certificate) => certificate.account === this.command.loadBalancer.credentials)\n .map((certificate) => certificate.name);\n };\n\n this.getSubnets = () => {\n const ret = this.command.backingData.subnetMap[this.command.loadBalancer.network]\n .filter((subnet) => subnet.region === this.command.loadBalancer.region)\n .map((subnet) => subnet.name);\n return _.uniq(ret);\n };\n\n this.getInternalAddresses = () => {\n return this.command.backingData.addresses.filter(\n (address) =>\n address.addressType === 'INTERNAL' && address.subnetwork.split('/').pop() === this.listener.subnet,\n );\n };\n\n this.updateName = (listener, appName) => {\n listener.name = this.getName(listener, appName);\n };\n\n this.localListenerHasSameName = () => {\n return (\n this.command.loadBalancer.listeners.filter((listener) => listener.name === this.listener.name).length > 1\n );\n };\n\n this.existingListenerNames = () => {\n return _.get(loadBalancerMap, [this.command.loadBalancer.credentials, 'listeners']);\n };\n\n this.isHttps = (port) => port === 443 || port === '443';\n // certificateMap writes are only supported on global external/classic HTTPS proxies (HTTP\n // type). INTERNAL_MANAGED regional proxies do not support certificateMap per GCP docs.\n this.supportsCertificateMap = () => this.command.loadBalancer.loadBalancerType === 'HTTP';\n this.certificateMapPattern = /^[a-z]([-a-z0-9]*[a-z0-9])?$/;\n // Extracts the short resource name from a certificateMap value. Users may paste a full\n // Certificate Manager URL (e.g. //certificatemanager.googleapis.com/projects/p/locations/\n // global/certificateMaps/my-map); only the last path segment (the map name) is stored.\n // The server reconstructs the full URL using GCEUtil.buildCertificateMapUrl.\n this.getCertificateMapName = (certificateMap) => {\n if (!_.isString(certificateMap)) {\n return certificateMap;\n }\n const normalized = certificateMap.trim();\n return normalized ? _.last(normalized.split('/')) : normalized;\n };\n\n // Reconcile the XOR between certificate and certificateMap on a listener. Ensures only\n // one is active at a time. Also infers certificateSource for existing listeners that were\n // created before the certificateSource field existed (backward compat).\n this.syncCertificateState = (listener) => {\n if (!this.supportsCertificateMap()) {\n listener.certificateSource = 'certificate';\n listener.certificateMap = null;\n return;\n }\n\n if (!listener.certificateSource) {\n listener.certificateSource = listener.certificateMap ? 'certificateMap' : 'certificate';\n }\n\n if (listener.certificateSource === 'certificateMap') {\n listener.certificate = null;\n if (_.isString(listener.certificateMap)) {\n listener.certificateMap = this.getCertificateMapName(listener.certificateMap);\n }\n } else {\n listener.certificateMap = null;\n }\n };\n\n this.onCertificateSourceChanged = (listener) => {\n if (!this.supportsCertificateMap()) {\n listener.certificateSource = 'certificate';\n listener.certificateMap = null;\n return;\n }\n\n if (listener.certificateSource === 'certificateMap') {\n listener.certificate = null;\n } else {\n listener.certificateMap = null;\n }\n };\n\n this.onCertificateSelected = (listener) => {\n if (listener.certificate) {\n listener.certificateSource = 'certificate';\n listener.certificateMap = null;\n }\n };\n\n this.onCertificateMapChanged = (listener) => {\n if (_.isString(listener.certificateMap)) {\n listener.certificateMap = this.getCertificateMapName(listener.certificateMap);\n }\n if (listener.certificateMap) {\n listener.certificateSource = 'certificateMap';\n listener.certificate = null;\n }\n };\n\n this.onPortChanged = (listener) => {\n if (!this.isHttps(listener.port)) {\n listener.certificate = null;\n listener.certificateMap = null;\n listener.certificateSource = 'certificate';\n } else {\n this.syncCertificateState(listener);\n }\n };\n\n if (!this.listener.name) {\n this.updateName(this.listener, this.application.name);\n }\n\n this.onPortChanged(this.listener);\n\n this.onAddressSelect = (address) => {\n if (address) {\n this.listener.ipAddress = address.address;\n } else {\n this.listener.ipAddress = null;\n }\n };\n };\n },\n },\n);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT } from './backendService/backendService.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT } from './basicSettings/basicSettings.component';\nimport { GCE_CACHE_REFRESH } from '../../../cache/cacheRefresh.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE } from './commandBuilder.service';\nimport { GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT } from '../../details/hostAndPathRules/hostAndPathRulesButton.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT } from './healthCheck/healthCheck.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT } from './hostRule/hostRule.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE } from './httpLoadBalancer.write.service';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT } from './listeners/listener.component';\nimport { BackendServiceTemplate, HealthCheckTemplate, HostRuleTemplate, ListenerTemplate } from './templates';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE } from './transformer.service';\n\nimport './httpLoadBalancerWizard.component.less';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER =\n 'spinnaker.deck.gce.loadBalancer.createHttp.controller';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER, [\n ANGULAR_UI_BOOTSTRAP,\n UIROUTER_ANGULARJS,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT,\n GCE_CACHE_REFRESH,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE,\n GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE,\n]).controller('gceCreateHttpLoadBalancerCtrl', [\n '$scope',\n '$uibModal',\n '$uibModalInstance',\n 'application',\n 'loadBalancer',\n 'isNew',\n 'forPipelineConfig',\n 'gceHttpLoadBalancerWriter',\n '$state',\n 'wizardSubFormValidation',\n 'gceHttpLoadBalancerCommandBuilder',\n 'gceHttpLoadBalancerTransformer',\n function (\n $scope,\n $uibModal,\n $uibModalInstance,\n application,\n loadBalancer,\n isNew,\n forPipelineConfig,\n gceHttpLoadBalancerWriter,\n $state,\n wizardSubFormValidation,\n gceHttpLoadBalancerCommandBuilder,\n gceHttpLoadBalancerTransformer,\n ) {\n this.application = application;\n this.isNew = isNew;\n this.modalDescriptor = this.isNew\n ? 'Create HTTP(S) load balancer'\n : `Edit ${loadBalancer.name}:global:${loadBalancer.account}`;\n\n this.pages = {\n location: require('./basicSettings/basicSettings.html'),\n listeners: require('./listeners/listeners.html'),\n defaultService: require('./defaultService/defaultService.html'),\n backendServices: require('./backendService/backendServices.html'),\n healthChecks: require('./healthCheck/healthChecks.html'),\n hostRules: require('./hostRule/hostRules.html'),\n };\n\n const keyToTemplateMap = {\n backendServices: BackendServiceTemplate,\n healthChecks: HealthCheckTemplate,\n hostRules: HostRuleTemplate,\n listeners: ListenerTemplate,\n };\n\n this.add = (key) => {\n this.command.loadBalancer[key].push(new keyToTemplateMap[key]());\n };\n\n this.remove = (key, index) => {\n this.command.loadBalancer[key].splice(index, 1);\n };\n\n const onApplicationRefresh = () => {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n\n const lb = this.command.loadBalancer;\n const newStateParams = {\n name: lb.urlMapName,\n accountId: lb.credentials,\n region: lb.region,\n provider: 'gce',\n };\n\n if (!$state.includes('**.loadBalancerDetails')) {\n $state.go('.loadBalancerDetails', newStateParams);\n } else {\n $state.go('^.loadBalancerDetails', newStateParams);\n }\n };\n\n const onTaskComplete = () => {\n application.loadBalancers.refresh();\n application.loadBalancers.onNextRefresh($scope, onApplicationRefresh);\n };\n\n $scope.taskMonitor = this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: (this.isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n this.submit = () => {\n const serializedCommands = gceHttpLoadBalancerTransformer.serialize(this.command, loadBalancer);\n const descriptor = this.isNew ? 'Create' : 'Update';\n\n if (forPipelineConfig) {\n const pipelineCommands = serializedCommands.map((command) => ({\n ...command,\n cloudProvider: 'gce',\n loadBalancerName: command.name,\n listeners: [\n {\n name: command.name,\n port: command.portRange,\n certificate: command.certificate || null,\n certificateMap: command.certificateMap || null,\n ipAddress: command.ipAddress,\n subnet: command.subnet,\n },\n ],\n }));\n $uibModalInstance.close(pipelineCommands);\n return;\n }\n\n this.taskMonitor.submit(() =>\n gceHttpLoadBalancerWriter.upsertLoadBalancers(serializedCommands, application, descriptor),\n );\n };\n\n gceHttpLoadBalancerCommandBuilder.buildCommand({ isNew, originalLoadBalancer: loadBalancer }).then((command) => {\n this.command = command;\n\n wizardSubFormValidation\n .config({ scope: $scope, form: 'form' })\n .register({ page: 'location', subForm: 'location' })\n .register({\n page: 'listeners',\n subForm: 'listeners',\n validators: [\n {\n watchString: 'ctrl.command.loadBalancer.listeners',\n validator: (listeners) => listeners.length > 0,\n collection: true,\n },\n ],\n })\n .register({ page: 'default-service', subForm: 'defaultService' })\n .register({ page: 'health-checks', subForm: 'healthChecks' })\n .register({ page: 'backend-services', subForm: 'backendServices' })\n .register({ page: 'host-rules', subForm: 'hostRules' });\n });\n\n this.cancel = $uibModalInstance.dismiss;\n },\n]);\n","import type { StateService } from '@uirouter/angularjs';\nimport type { IScope } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\nimport { trimEnd } from 'lodash';\n\nimport type { Application } from '@spinnaker/core';\nimport { InfrastructureCaches } from '@spinnaker/core';\nimport type { IGceLoadBalancer } from '../../../domain/loadBalancer';\n\nexport class CommonGceLoadBalancerCtrl {\n public static $inject = ['$scope', 'application', '$uibModalInstance', '$state'];\n constructor(\n public $scope: IScope,\n public application: Application,\n public $uibModalInstance: IModalInstanceService,\n private $state: StateService,\n ) {}\n\n public onTaskComplete(loadBalancer: IGceLoadBalancer): void {\n InfrastructureCaches.clearCache('healthChecks');\n this.application.getDataSource('loadBalancers').refresh();\n this.application\n .getDataSource('loadBalancers')\n .onNextRefresh(this.$scope, () => this.onApplicationRefresh(loadBalancer));\n }\n\n public cancel(): void {\n this.$uibModalInstance.dismiss();\n }\n\n public getName(lb: IGceLoadBalancer, application: Application): string {\n const loadBalancerName = [application.name, lb.stack || '', lb.detail || ''].join('-');\n return trimEnd(loadBalancerName, '-');\n }\n\n private onApplicationRefresh(loadBalancer: IGceLoadBalancer): void {\n // If the user has already closed the modal, do not navigate to the new details view\n if (this.$scope.$$destroyed) {\n return;\n }\n this.$uibModalInstance.close();\n\n const newStateParams = {\n name: loadBalancer.loadBalancerName,\n accountId: loadBalancer.credentials,\n region: loadBalancer.region,\n provider: 'gce',\n };\n\n if (!this.$state.includes('**.loadBalancerDetails')) {\n this.$state.go('.loadBalancerDetails', newStateParams);\n } else {\n this.$state.go('^.loadBalancerDetails', newStateParams);\n }\n }\n}\n","import { module } from 'angular';\nimport _ from 'lodash';\n\nimport type { IAccount, ILoadBalancersByAccount, INetwork, ISubnet, LoadBalancerReader } from '@spinnaker/core';\nimport { AccountService, LOAD_BALANCER_READ_SERVICE, NetworkReader, SubnetReader } from '@spinnaker/core';\nimport type { GceCertificateReader, IGceCertificate } from '../../../certificate/certificate.reader';\nimport { GCE_CERTIFICATE_READER } from '../../../certificate/certificate.reader';\nimport type { IGceHealthCheck } from '../../../domain/healthCheck';\nimport type { GceHealthCheckReader } from '../../../healthCheck/healthCheck.read.service';\nimport { GCE_HEALTH_CHECK_READER } from '../../../healthCheck/healthCheck.read.service';\n\nexport class GceCommonLoadBalancerCommandBuilder {\n private dataFetchers: { [key: string]: Function } = {\n existingLoadBalancerNamesByAccount: (): PromiseLike<_.Dictionary<any>> => {\n return this.loadBalancerReader.listLoadBalancers('gce').then((loadBalancerList: ILoadBalancersByAccount[]) => {\n return _.chain(loadBalancerList)\n .map('accounts')\n .flatten()\n .groupBy('name') // account name\n .mapValues((regionWrappers) =>\n _.chain(regionWrappers)\n .map('regions')\n .flatten()\n .map('loadBalancers')\n .flatten()\n .map('name') // load balancer name\n .value(),\n )\n .value();\n });\n },\n accounts: (): PromiseLike<IAccount[]> => AccountService.listAccounts('gce'),\n networks: (): PromiseLike<INetwork[]> => NetworkReader.listNetworksByProvider('gce'),\n subnets: (): PromiseLike<ISubnet[]> => SubnetReader.listSubnetsByProvider('gce'),\n healthChecks: (): PromiseLike<IGceHealthCheck[]> => this.gceHealthCheckReader.listHealthChecks(),\n certificates: (): PromiseLike<IGceCertificate[]> => this.gceCertificateReader.listCertificates(),\n };\n\n public static $inject = ['$q', 'loadBalancerReader', 'gceHealthCheckReader', 'gceCertificateReader'];\n constructor(\n private $q: ng.IQService,\n private loadBalancerReader: LoadBalancerReader,\n private gceHealthCheckReader: GceHealthCheckReader,\n private gceCertificateReader: GceCertificateReader,\n ) {}\n\n public getBackingData(dataTypes: string[]): PromiseLike<any> {\n const promises = dataTypes.reduce(\n (promisesByDataType: { [dataType: string]: PromiseLike<any> }, dataType: string) => {\n if (this.dataFetchers[dataType]) {\n promisesByDataType[dataType] = this.dataFetchers[dataType]();\n }\n return promisesByDataType;\n },\n {},\n );\n\n return this.$q.all(promises);\n }\n\n public groupHealthChecksByAccountAndType(\n healthChecks: IGceHealthCheck[],\n ): { [account: string]: { [healthCheckType: string]: IGceHealthCheck[] } } {\n return _.chain(healthChecks)\n .groupBy('account')\n .mapValues((grouped: IGceHealthCheck[]) => _.groupBy(grouped, 'healthCheckType'))\n .value();\n }\n\n public groupHealthCheckNamesByAccount(\n healthChecks: IGceHealthCheck[],\n namesToOmit: string[],\n ): { [account: string]: string[] } {\n return _.chain(healthChecks)\n .groupBy('account')\n .mapValues((grouped: IGceHealthCheck[]) => _.chain(grouped).map('name').difference(namesToOmit).value())\n .value() as { [account: string]: string[] };\n }\n}\n\nexport const GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER = 'spinnaker.gce.commonLoadBalancerCommandBuilder.service';\n\nmodule(GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER, [\n LOAD_BALANCER_READ_SERVICE,\n GCE_CERTIFICATE_READER,\n GCE_HEALTH_CHECK_READER,\n]).service('gceCommonLoadBalancerCommandBuilder', GceCommonLoadBalancerCommandBuilder);\n","import type { IController } from 'angular';\nimport { module } from 'angular';\nimport { get } from 'lodash';\n\nimport type { IGceHealthCheck } from '../../../domain/index';\n\nclass HealthCheckCreateCtrl implements IController {\n public healthCheck: IGceHealthCheck;\n public healthCheckPlaceholder: IGceHealthCheck;\n public healthChecksByAccountAndType: { [account: string]: { [healthCheckType: string]: IGceHealthCheck[] } };\n public editExisting = false;\n public existingHealthChecksForProtocol: IGceHealthCheck[];\n public existingHealthCheckNames: string[];\n public credentials: string;\n public max = Number.MAX_SAFE_INTEGER;\n\n public static $inject = ['$scope'];\n constructor(private $scope: ng.IScope) {}\n\n public $onInit(): void {\n if (this.healthCheck.name) {\n this.healthCheckPlaceholder = this.healthCheck;\n this.existingHealthChecksForProtocol = this.healthChecksByAccountAndType[this.credentials][\n this.healthCheck.healthCheckType\n ];\n this.editExisting = true;\n } else {\n this.existingHealthChecksForProtocol = this.healthChecksByAccountAndType[this.credentials]['TCP'];\n }\n\n this.$scope.$watch('$ctrl.credentials', () => this.setExistingHealthChecksForProtocol());\n }\n\n public onProtocolChange(): void {\n delete this.healthCheck.name;\n delete this.healthCheckPlaceholder;\n this.setExistingHealthChecksForProtocol();\n }\n\n public setExistingHealthChecksForProtocol() {\n this.existingHealthChecksForProtocol =\n get<{}, IGceHealthCheck[]>(this, [\n 'healthChecksByAccountAndType',\n this.credentials,\n this.healthCheck.healthCheckType,\n ]) || [];\n\n if (!this.existingHealthChecksForProtocol.find((healthCheck) => healthCheck.name === this.healthCheck.name)) {\n delete this.healthCheck.name;\n delete this.healthCheckPlaceholder;\n }\n }\n\n public toggleEditExisting(): void {\n this.editExisting = !this.editExisting;\n delete this.healthCheck.name;\n delete this.healthCheckPlaceholder;\n }\n\n public onHealthCheckSelect(selectedHealthCheck: IGceHealthCheck): void {\n Object.assign(this.healthCheck, selectedHealthCheck);\n }\n\n public onHealthCheckNameChange(typedName: string): void {\n this.healthCheck.name = typedName;\n }\n}\n\nconst healthCheckCreateComponent: ng.IComponentOptions = {\n bindings: {\n healthCheck: '=',\n credentials: '<',\n healthChecksByAccountAndType: '<',\n existingHealthCheckNames: '<',\n },\n templateUrl: require('./healthCheck.component.html'),\n controller: HealthCheckCreateCtrl,\n};\n\nexport const GCE_HEALTH_CHECK_SELECTOR_COMPONENT = 'spinnaker.gce.healthCheckSelector.component';\n\nmodule(GCE_HEALTH_CHECK_SELECTOR_COMPONENT, []).component('gceHealthCheckSelector', healthCheckCreateComponent);\n","import type { StateService } from '@uirouter/angularjs';\nimport type { IController, IScope } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport type { Application, IAccount, ICredentials, IRegion } from '@spinnaker/core';\nimport { AccountService, LoadBalancerWriter, TaskMonitor } from '@spinnaker/core';\n\nimport { CommonGceLoadBalancerCtrl } from '../common/commonLoadBalancer.controller';\nimport type { GceCommonLoadBalancerCommandBuilder } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_HEALTH_CHECK_SELECTOR_COMPONENT } from '../common/healthCheck.component';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../../common/xpnNaming.gce.service';\nimport type {\n IGceBackendService,\n IGceHealthCheck,\n IGceLoadBalancer,\n IGceNetwork,\n IGceSubnet,\n} from '../../../domain/index';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\nclass ViewState {\n constructor(public sessionAffinity: string) {}\n}\n\ninterface IListKeyedByAccount {\n [account: string]: string[];\n}\n\ninterface IPrivateScope extends IScope {\n $$destroyed: boolean;\n}\n\nclass InternalLoadBalancer implements IGceLoadBalancer {\n public name: string;\n public stack: string;\n public detail: string;\n public loadBalancerName: string;\n public ports: any;\n public ipProtocol = 'TCP';\n public loadBalancerType = 'INTERNAL';\n public credentials: string;\n public account: string;\n public project: string;\n public network = 'default';\n public subnet: string;\n public cloudProvider = 'gce';\n public backendService: IGceBackendService = { healthCheck: { healthCheckType: 'TCP' } } as IGceBackendService;\n\n constructor(public region: string) {}\n}\n\nclass InternalLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements IController {\n public pages: any = {\n location: require('./createLoadBalancerProperties.html'),\n listener: require('./listener.html'),\n healthCheck: require('../common/commonHealthCheckPage.html'),\n advancedSettings: require('../common/commonAdvancedSettingsPage.html'),\n };\n public sessionAffinityViewToModelMap: any = {\n None: 'NONE',\n 'Client IP': 'CLIENT_IP',\n 'Client IP and protocol': 'CLIENT_IP_PROTO',\n 'Client IP, port and protocol': 'CLIENT_IP_PORT_PROTO',\n };\n public accounts: ICredentials[];\n public regions: string[];\n public networks: IGceNetwork[];\n public networkOptions: string[];\n public subnets: IGceSubnet[];\n public subnetOptions: string[];\n public healthChecksByAccountAndType: { [account: string]: { [healthCheckType: string]: IGceHealthCheck[] } };\n\n // The 'by account' maps populate the corresponding 'existing names' lists below.\n public existingLoadBalancerNamesByAccount: IListKeyedByAccount;\n public existingHealthCheckNamesByAccount: IListKeyedByAccount;\n public existingLoadBalancerNames: string[];\n public existingHealthCheckNames: string[];\n\n public viewState: ViewState = new ViewState('None');\n public taskMonitor: any;\n\n private sessionAffinityModelToViewMap: any = _.invert(this.sessionAffinityViewToModelMap);\n\n public static $inject = [\n '$scope',\n 'application',\n '$uibModalInstance',\n 'loadBalancer',\n 'gceCommonLoadBalancerCommandBuilder',\n 'isNew',\n 'forPipelineConfig',\n 'wizardSubFormValidation',\n 'gceXpnNamingService',\n '$state',\n ];\n constructor(\n public $scope: IPrivateScope,\n public application: Application,\n public $uibModalInstance: IModalInstanceService,\n private loadBalancer: InternalLoadBalancer,\n private gceCommonLoadBalancerCommandBuilder: GceCommonLoadBalancerCommandBuilder,\n private isNew: boolean,\n private forPipelineConfig: boolean,\n private wizardSubFormValidation: any,\n private gceXpnNamingService: any,\n $state: StateService,\n ) {\n super($scope, application, $uibModalInstance, $state);\n }\n\n public $onInit(): void {\n this.gceCommonLoadBalancerCommandBuilder\n .getBackingData(['existingLoadBalancerNamesByAccount', 'accounts', 'networks', 'subnets', 'healthChecks'])\n .then((backingData) => {\n if (!this.isNew) {\n this.initializeEditMode();\n } else {\n this.loadBalancer = new InternalLoadBalancer(\n GCEProviderSettings ? GCEProviderSettings.defaults.region : null,\n );\n }\n\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n\n const accountNames: string[] = backingData.accounts.map((account: IAccount) => account.name);\n if (accountNames.length && !accountNames.includes(this.loadBalancer.account)) {\n this.loadBalancer.credentials = accountNames[0];\n } else {\n this.loadBalancer.credentials = this.loadBalancer.account;\n }\n\n this.accounts = backingData.accounts;\n this.networks = backingData.networks;\n this.subnets = backingData.subnets;\n this.existingLoadBalancerNamesByAccount = backingData.existingLoadBalancerNamesByAccount;\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n backingData.healthChecks as IGceHealthCheck[],\n );\n\n // We don't count the load balancer's health check in the existing health checks list.\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n backingData.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n\n this.accountUpdated();\n\n this.wizardSubFormValidation\n .config({ scope: this.$scope, form: 'form' })\n .register({ page: 'location', subForm: 'locationForm' })\n .register({ page: 'listener', subForm: 'listenerForm' })\n .register({ page: 'healthCheck', subForm: 'healthCheckForm' })\n .register({ page: 'advancedSettings', subForm: 'advancedSettingsForm' });\n\n this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: (this.isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: this.$uibModalInstance,\n onTaskComplete: () => this.onTaskComplete(this.loadBalancer),\n });\n });\n }\n\n public onHealthCheckRefresh(): void {\n this.gceCommonLoadBalancerCommandBuilder.getBackingData(['healthChecks']).then((data) => {\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n data.healthChecks as IGceHealthCheck[],\n );\n\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n data.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n });\n }\n\n public networkUpdated(): void {\n this.subnetOptions = this.subnets\n .filter((subnet) => {\n return (\n subnet.region === this.loadBalancer.region &&\n (subnet.account === this.loadBalancer.credentials || subnet.account === this.loadBalancer.account) &&\n subnet.network === this.loadBalancer.network\n );\n })\n .map((subnet) => subnet.id);\n\n if (!this.subnetOptions.includes(this.loadBalancer.subnet)) {\n this.loadBalancer.subnet = this.subnetOptions[0];\n }\n }\n\n public protocolUpdated(): void {\n if (this.loadBalancer.ipProtocol === 'UDP') {\n this.viewState = new ViewState('None');\n this.loadBalancer.backendService.sessionAffinity = 'NONE';\n }\n }\n\n public accountUpdated(): void {\n const existingHealthCheckNames = _.get<any, string[]>(this, [\n 'existingHealthCheckNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingHealthCheckNames = existingHealthCheckNames || [];\n\n const existingLoadBalancerNames = _.get<any, string[]>(this, [\n 'existingLoadBalancerNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingLoadBalancerNames = existingLoadBalancerNames || [];\n\n this.networkOptions = this.networks\n .filter((network: IGceNetwork) => network.account === this.loadBalancer.credentials)\n .map((network) => network.id);\n\n AccountService.getRegionsForAccount(this.loadBalancer.credentials).then((regions: IRegion[]) => {\n this.regions = regions.map((region: IRegion) => region.name);\n this.networkUpdated();\n });\n }\n\n public regionUpdated(): void {\n this.networkUpdated();\n }\n\n public updateName(): void {\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n }\n\n public setSessionAffinity(viewState: ViewState): void {\n this.loadBalancer.backendService.sessionAffinity = this.sessionAffinityViewToModelMap[viewState.sessionAffinity];\n }\n\n public submit(): void {\n const descriptor = this.isNew ? 'Create' : 'Update';\n const toSubmitLoadBalancer = _.cloneDeep(this.loadBalancer) as any;\n toSubmitLoadBalancer.ports = toSubmitLoadBalancer.ports.split(',').map((port: string) => port.trim());\n toSubmitLoadBalancer.cloudProvider = 'gce';\n toSubmitLoadBalancer.name = toSubmitLoadBalancer.loadBalancerName;\n toSubmitLoadBalancer.backendService.name = toSubmitLoadBalancer.loadBalancerName;\n delete toSubmitLoadBalancer.instances;\n\n if (this.forPipelineConfig) {\n Object.assign(toSubmitLoadBalancer, { healthCheck: {} });\n this.$uibModalInstance.close(toSubmitLoadBalancer);\n return;\n }\n\n this.taskMonitor.submit(() =>\n LoadBalancerWriter.upsertLoadBalancer(toSubmitLoadBalancer, this.application, descriptor, {\n healthCheck: {},\n }),\n );\n }\n\n private initializeEditMode(): void {\n this.loadBalancer.ports = this.loadBalancer.ports.join(', ');\n this.loadBalancer.subnet = this.gceXpnNamingService.decorateXpnResourceIfNecessary(\n this.loadBalancer.project,\n this.loadBalancer.subnet,\n );\n this.loadBalancer.network = this.gceXpnNamingService.decorateXpnResourceIfNecessary(\n this.loadBalancer.project,\n this.loadBalancer.network,\n );\n this.viewState = new ViewState(\n this.sessionAffinityModelToViewMap[this.loadBalancer.backendService.sessionAffinity],\n );\n }\n}\n\nexport const GCE_INTERNAL_LOAD_BALANCER_CTRL = 'spinnaker.gce.internalLoadBalancer.controller';\n\nmodule(GCE_INTERNAL_LOAD_BALANCER_CTRL, [\n GCE_HEALTH_CHECK_SELECTOR_COMPONENT,\n GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n]).controller('gceInternalLoadBalancerCtrl', InternalLoadBalancerCtrl);\n","import type { StateService } from '@uirouter/angularjs';\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport type { IScope } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\n\nimport type { Application } from '@spinnaker/core';\nimport { TaskMonitor } from '@spinnaker/core';\n\nimport { GCE_CACHE_REFRESH } from '../../../cache/cacheRefresh.component';\nimport { GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT } from '../../details/hostAndPathRules/hostAndPathRulesButton.component';\nimport type { IGceHttpLoadBalancer } from '../../../domain';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT } from '../http/backendService/backendService.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT } from '../http/basicSettings/basicSettings.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE } from '../http/commandBuilder.service';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT } from '../http/healthCheck/healthCheck.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT } from '../http/hostRule/hostRule.component';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE } from '../http/httpLoadBalancer.write.service';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT } from '../http/listeners/listener.component';\nimport { BackendServiceTemplate, HealthCheckTemplate, HostRuleTemplate, ListenerTemplate } from '../http/templates';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE } from '../http/transformer.service';\n\nimport '../http/httpLoadBalancerWizard.component.less';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER =\n 'spinnaker.deck.gce.loadBalancer.createInternalHttp.controller';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER; // for backwards compatibility\n\nclass CreateInternalHttpLoadBalancerController implements ng.IComponentController {\n public taskMonitor: any;\n public command: any;\n public modalDescriptor: string;\n\n public pages = {\n location: require('../http/basicSettings/basicSettings.html'),\n listeners: require('../http/listeners/listeners.html'),\n defaultService: require('../http/defaultService/defaultService.html'),\n backendServices: require('../http/backendService/backendServices.html'),\n healthChecks: require('../http/healthCheck/healthChecks.html'),\n hostRules: require('../http/hostRule/hostRules.html'),\n };\n\n private keyToTemplateMap: { [key: string]: any } = {\n backendServices: BackendServiceTemplate,\n healthChecks: HealthCheckTemplate,\n hostRules: HostRuleTemplate,\n listeners: ListenerTemplate,\n };\n\n public static $inject = [\n '$scope',\n 'application',\n '$uibModalInstance',\n 'loadBalancer',\n 'gceHttpLoadBalancerCommandBuilder',\n 'isNew',\n 'forPipelineConfig',\n 'wizardSubFormValidation',\n 'gceHttpLoadBalancerTransformer',\n 'gceHttpLoadBalancerWriter',\n '$state',\n ];\n\n constructor(\n public $scope: IScope,\n public application: Application,\n public $uibModalInstance: IModalInstanceService,\n private loadBalancer: IGceHttpLoadBalancer,\n private gceHttpLoadBalancerCommandBuilder: any,\n private isNew: boolean,\n private forPipelineConfig: boolean,\n private wizardSubFormValidation: any,\n private gceHttpLoadBalancerTransformer: any,\n private gceHttpLoadBalancerWriter: any,\n private $state: StateService,\n ) {\n this.modalDescriptor = this.isNew\n ? 'Create Internal HTTP(S) load balancer'\n : `Edit ${this.loadBalancer.name}:${this.loadBalancer.region}:${this.loadBalancer.account}`;\n\n const onTaskComplete = () => {\n application.loadBalancers.refresh();\n application.loadBalancers.onNextRefresh($scope, this.onApplicationRefresh.bind(this));\n };\n\n $scope.taskMonitor = this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: (this.isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: this.$uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n }\n\n public $onInit(): void {\n this.gceHttpLoadBalancerCommandBuilder\n .buildCommand({ isNew: this.isNew, originalLoadBalancer: this.loadBalancer, isInternal: true })\n .then((command: any) => {\n this.command = command;\n this.wizardSubFormValidation\n .config({ scope: this.$scope, form: 'form' })\n .register({ page: 'location', subForm: 'location' })\n .register({\n page: 'listeners',\n subForm: 'listeners',\n validators: [\n {\n watchString: 'ctrl.command.loadBalancer.listeners',\n validator: (listeners: any[]) => listeners.length > 0,\n collection: true,\n },\n ],\n })\n .register({ page: 'default-service', subForm: 'defaultService' })\n .register({ page: 'health-checks', subForm: 'healthChecks' })\n .register({ page: 'backend-services', subForm: 'backendServices' })\n .register({ page: 'host-rules', subForm: 'hostRules' });\n });\n }\n\n public add(key: string): void {\n this.command.loadBalancer[key].push(new this.keyToTemplateMap[key]());\n }\n\n public remove(key: string, index: number): void {\n this.command.loadBalancer[key].splice(index, 1);\n }\n\n public cancel(): void {\n this.$uibModalInstance.dismiss();\n }\n\n public submit(): void {\n const serializedCommands = this.gceHttpLoadBalancerTransformer.serialize(this.command, this.loadBalancer);\n const descriptor = this.isNew ? 'Create' : 'Update';\n\n if (this.forPipelineConfig) {\n const pipelineCommands = serializedCommands.map((command: any) => ({\n ...command,\n cloudProvider: 'gce',\n loadBalancerName: command.name,\n listeners: [\n {\n name: command.name,\n port: command.portRange,\n certificate: command.certificate || null,\n certificateMap: command.certificateMap || null,\n ipAddress: command.ipAddress,\n subnet: command.subnet,\n },\n ],\n }));\n this.$uibModalInstance.close(pipelineCommands);\n return;\n }\n\n this.taskMonitor.submit(() =>\n this.gceHttpLoadBalancerWriter.upsertLoadBalancers(serializedCommands, this.application, descriptor),\n );\n }\n\n private onApplicationRefresh(): void {\n // If the user has already closed the modal, do not navigate to the new details view\n if (this.$scope.$$destroyed) {\n return;\n }\n this.$uibModalInstance.close();\n const lb = this.command.loadBalancer;\n const newStateParams = {\n name: lb.urlMapName,\n accountId: lb.credentials,\n region: lb.region,\n provider: 'gce',\n };\n\n if (!this.$state.includes('**.loadBalancerDetails')) {\n this.$state.go('.loadBalancerDetails', newStateParams);\n } else {\n this.$state.go('^.loadBalancerDetails', newStateParams);\n }\n }\n}\n\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER, [\n 'ui.bootstrap',\n UIROUTER_ANGULARJS,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT,\n GCE_CACHE_REFRESH,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE,\n GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE,\n]).controller('gceCreateInternalHttpLoadBalancerCtrl', CreateInternalHttpLoadBalancerController);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE = 'spinnaker.google.regionSelectField.directive';\nexport const name = GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE, []).directive('gceRegionSelectField', function () {\n return {\n restrict: 'E',\n templateUrl: require('./regionSelectField.directive.html'),\n scope: {\n regions: '=',\n component: '=',\n field: '@',\n account: '=',\n onChange: '&',\n labelColumns: '@',\n readOnly: '=',\n fieldColumns: '@',\n },\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { GCEProviderSettings } from '../gce.settings';\n\nexport const GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER = 'spinnaker.gce.loadBalancer.transformer';\nexport const name = GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER, []).factory('gceLoadBalancerTransformer', [\n '$q',\n function ($q) {\n function updateHealthCounts(container) {\n const instances = container.instances;\n const serverGroups = container.serverGroups || [container];\n container.instanceCounts = {\n up: instances.filter((instance) => {\n return instance.health[0].state === 'InService';\n }).length,\n down: instances.filter((instance) => {\n return instance.health[0].state === 'OutOfService';\n }).length,\n outOfService: serverGroups.reduce((acc, serverGroup) => {\n return (\n serverGroup.instances.filter((instance) => {\n return instance.healthState === 'OutOfService';\n }).length + acc\n );\n }, 0),\n };\n }\n\n function transformInstance(instance, loadBalancer) {\n instance.health = instance.health || {};\n instance.provider = loadBalancer.type;\n instance.account = loadBalancer.account;\n instance.region = loadBalancer.region;\n instance.health.type = 'LoadBalancer';\n instance.healthState = instance.health.state\n ? instance.health.state === 'InService'\n ? 'Up'\n : 'Down'\n : 'OutOfService';\n instance.health = [instance.health];\n instance.loadBalancers = [loadBalancer.name];\n }\n\n function normalizeLoadBalancer(loadBalancer) {\n loadBalancer.serverGroups.forEach(function (serverGroup) {\n serverGroup.account = loadBalancer.account;\n if (serverGroup.detachedInstances) {\n serverGroup.detachedInstances = serverGroup.detachedInstances.map(function (instanceId) {\n return { id: instanceId };\n });\n serverGroup.instances = serverGroup.instances.concat(serverGroup.detachedInstances);\n } else {\n serverGroup.detachedInstances = [];\n }\n\n serverGroup.instances.forEach(function (instance) {\n transformInstance(instance, loadBalancer);\n });\n updateHealthCounts(serverGroup);\n });\n const activeServerGroups = _.filter(loadBalancer.serverGroups, { isDisabled: false });\n loadBalancer.provider = loadBalancer.type;\n loadBalancer.instances = _.chain(activeServerGroups).map('instances').flatten().value();\n loadBalancer.detachedInstances = _.chain(activeServerGroups).map('detachedInstances').flatten().value();\n if (_.get(loadBalancer, 'backendService.healthCheck')) {\n loadBalancer.backendService.healthCheck.timeout = loadBalancer.backendService.healthCheck.timeoutSec;\n loadBalancer.backendService.healthCheck.interval = loadBalancer.backendService.healthCheck.checkIntervalSec;\n }\n updateHealthCounts(loadBalancer);\n return $q.when(loadBalancer);\n }\n\n function convertLoadBalancerForEditing(loadBalancer) {\n const toEdit = {\n provider: 'gce',\n region: loadBalancer.region,\n credentials: loadBalancer.account,\n listeners: [],\n name: loadBalancer.name,\n regionZones: loadBalancer.availabilityZones,\n };\n\n if (loadBalancer.elb) {\n const elb = loadBalancer.elb;\n\n toEdit.vpcId = elb.vpcid;\n\n if (elb.listenerDescriptions) {\n toEdit.listeners = elb.listenerDescriptions.map(function (description) {\n const listener = description.listener;\n return {\n protocol: listener.protocol,\n portRange: listener.loadBalancerPort,\n healthCheck: elb.healthCheck !== undefined,\n };\n });\n }\n\n if (elb.healthCheck && elb.healthCheck.target) {\n toEdit.healthTimeout = elb.healthCheck.timeout;\n toEdit.healthInterval = elb.healthCheck.interval;\n toEdit.healthyThreshold = elb.healthCheck.healthyThreshold;\n toEdit.unhealthyThreshold = elb.healthCheck.unhealthyThreshold;\n\n const healthCheck = loadBalancer.elb.healthCheck.target;\n const protocolIndex = healthCheck.indexOf(':');\n const pathIndex = healthCheck.indexOf('/');\n\n if (protocolIndex !== -1 && pathIndex !== -1) {\n toEdit.healthCheckProtocol = healthCheck.substring(0, protocolIndex);\n toEdit.healthCheckPort = healthCheck.substring(protocolIndex + 1, pathIndex);\n toEdit.healthCheckPath = healthCheck.substring(pathIndex);\n if (!isNaN(toEdit.healthCheckPort)) {\n toEdit.healthCheckPort = Number(toEdit.healthCheckPort);\n }\n }\n } else {\n toEdit.healthCheckProtocol = 'HTTP';\n toEdit.healthCheckPort = 80;\n toEdit.healthCheckPath = '/';\n toEdit.healthTimeout = 5;\n toEdit.healthInterval = 10;\n toEdit.healthyThreshold = 10;\n toEdit.unhealthyThreshold = 2;\n }\n\n toEdit.sessionAffinity = loadBalancer.sessionAffinity || 'None';\n }\n return toEdit;\n }\n\n function constructNewLoadBalancerTemplate() {\n return {\n provider: 'gce',\n stack: '',\n detail: '',\n credentials: GCEProviderSettings.defaults.account,\n region: GCEProviderSettings.defaults.region,\n healthCheckProtocol: 'HTTP',\n healthCheckPort: 80,\n healthCheckPath: '/',\n healthTimeout: 5,\n healthInterval: 10,\n healthyThreshold: 10,\n unhealthyThreshold: 2,\n sessionAffinity: 'NONE',\n regionZones: [],\n listeners: [\n {\n protocol: 'TCP',\n portRange: '8080',\n healthCheck: true,\n },\n ],\n };\n }\n\n return {\n normalizeLoadBalancer: normalizeLoadBalancer,\n convertLoadBalancerForEditing: convertLoadBalancerForEditing,\n constructNewLoadBalancerTemplate: constructNewLoadBalancerTemplate,\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { AccountService, LoadBalancerWriter, ModalWizard, TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE } from '../../../gceRegionSelectField.directive';\nimport { GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from '../../loadBalancer.transformer';\n\nexport const GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER =\n 'spinnaker.loadBalancer.gce.create.controller';\nexport const name = GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER, [\n UIROUTER_ANGULARJS,\n GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE,\n]).controller('gceCreateLoadBalancerCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n 'gceLoadBalancerTransformer',\n 'application',\n 'loadBalancer',\n 'isNew',\n 'forPipelineConfig',\n function (\n $scope,\n $uibModalInstance,\n $state,\n gceLoadBalancerTransformer,\n application,\n loadBalancer,\n isNew,\n forPipelineConfig,\n ) {\n const ctrl = this;\n\n $scope.isNew = isNew;\n\n $scope.pages = {\n location: require('./createLoadBalancerProperties.html'),\n listeners: require('./listeners.html'),\n healthCheck: require('./healthCheck.html'),\n advancedSettings: require('./advancedSettings.html'),\n };\n\n $scope.state = {\n accountsLoaded: false,\n submitting: false,\n };\n\n $scope.sessionAffinityOptions = [\n { value: 'NONE', name: 'None' },\n { value: 'CLIENT_IP', name: 'Client IP' },\n { value: 'CLIENT_IP_PROTO', name: 'Client IP and protocol' },\n ];\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.loadBalancer.name,\n accountId: $scope.loadBalancer.credentials,\n region: $scope.loadBalancer.region,\n provider: 'gce',\n };\n if (!$state.includes('**.loadBalancerDetails')) {\n $state.go('.loadBalancerDetails', newStateParams);\n } else {\n $state.go('^.loadBalancerDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.loadBalancers.refresh();\n application.loadBalancers.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: (isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function initializeEditMode() {}\n\n function initializeCreateMode() {\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accountsLoaded = true;\n\n const accountNames = _.map($scope.accounts, 'name');\n if (accountNames.length && !accountNames.includes($scope.loadBalancer.credentials)) {\n $scope.loadBalancer.credentials = accountNames[0];\n }\n\n ctrl.accountUpdated();\n });\n }\n\n function updateLoadBalancerNames() {\n const account = $scope.loadBalancer.credentials;\n\n const accountLoadBalancersByRegion = {};\n application\n .getDataSource('loadBalancers')\n .refresh(true)\n .then(() => {\n application.getDataSource('loadBalancers').data.forEach((loadBalancer) => {\n if (loadBalancer.account === account) {\n accountLoadBalancersByRegion[loadBalancer.region] =\n accountLoadBalancersByRegion[loadBalancer.region] || [];\n accountLoadBalancersByRegion[loadBalancer.region].push(loadBalancer.name);\n }\n });\n\n $scope.existingLoadBalancerNames = _.flatten(_.map(accountLoadBalancersByRegion));\n });\n }\n\n // initialize controller\n if (loadBalancer) {\n $scope.loadBalancer = gceLoadBalancerTransformer.convertLoadBalancerForEditing(loadBalancer);\n initializeEditMode();\n } else {\n $scope.loadBalancer = gceLoadBalancerTransformer.constructNewLoadBalancerTemplate();\n updateLoadBalancerNames();\n initializeCreateMode();\n }\n\n // Controller API\n\n this.requiresHealthCheckPath = function () {\n return $scope.loadBalancer.healthCheckProtocol && $scope.loadBalancer.healthCheckProtocol.indexOf('HTTP') === 0;\n };\n\n this.prependForwardSlash = (text) => {\n return text && text.indexOf('/') !== 0 ? `/${text}` : text;\n };\n\n this.updateName = function () {\n $scope.loadBalancer.name = this.getName();\n };\n\n this.getName = function () {\n const loadBalancer = $scope.loadBalancer;\n const loadBalancerName = [application.name, loadBalancer.stack || '', loadBalancer.detail || ''].join('-');\n return _.trimEnd(loadBalancerName, '-');\n };\n\n this.accountUpdated = function () {\n AccountService.getRegionsForAccount($scope.loadBalancer.credentials).then(function (regions) {\n if (_.isArray(regions)) {\n $scope.regions = _.map(regions, 'name');\n } else {\n // TODO(duftler): Remove this once we finish deprecating the old style regions/zones in clouddriver GCE credentials.\n $scope.regions = _.keys(regions);\n }\n ctrl.regionUpdated();\n });\n };\n\n this.regionUpdated = function () {\n updateLoadBalancerNames();\n ctrl.updateName();\n };\n\n this.setVisibilityHealthCheckTab = function () {\n const wizard = ModalWizard;\n\n if ($scope.loadBalancer.listeners[0].healthCheck) {\n wizard.includePage('Health Check');\n wizard.markIncomplete('Health Check');\n wizard.includePage('Advanced Settings');\n wizard.markIncomplete('Advanced Settings');\n } else {\n wizard.excludePage('Health Check');\n wizard.markComplete('Health Check');\n wizard.excludePage('Advanced Settings');\n wizard.markComplete('Advanced Settings');\n wizard.markComplete('Listener');\n }\n };\n\n this.submit = function () {\n const descriptor = isNew ? 'Create' : 'Update';\n\n const params = {\n cloudProvider: 'gce',\n loadBalancerName: $scope.loadBalancer.name,\n };\n\n if ($scope.loadBalancer.listeners && $scope.loadBalancer.listeners.length > 0) {\n const listener = $scope.loadBalancer.listeners[0];\n\n if (listener.protocol) {\n params.ipProtocol = listener.protocol;\n }\n\n if (listener.portRange) {\n params.portRange = listener.portRange;\n }\n\n if (listener.healthCheck) {\n params.healthCheck = {\n port: $scope.loadBalancer.healthCheckPort,\n requestPath: $scope.loadBalancer.healthCheckPath,\n timeoutSec: $scope.loadBalancer.healthTimeout,\n checkIntervalSec: $scope.loadBalancer.healthInterval,\n healthyThreshold: $scope.loadBalancer.healthyThreshold,\n unhealthyThreshold: $scope.loadBalancer.unhealthyThreshold,\n };\n } else {\n params.healthCheck = null;\n }\n\n params.sessionAffinity = $scope.loadBalancer.sessionAffinity;\n }\n\n if (forPipelineConfig) {\n const command = Object.assign({}, $scope.loadBalancer, params);\n $uibModalInstance.close(command);\n return;\n }\n\n $scope.taskMonitor.submit(function () {\n return LoadBalancerWriter.upsertLoadBalancer($scope.loadBalancer, application, descriptor, params);\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","import type { StateService } from '@uirouter/angularjs';\nimport type { IController, IScope } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport type {\n Application,\n IAccount,\n ICredentials,\n IInstance,\n ILoadBalancerUpsertCommand,\n IRegion,\n} from '@spinnaker/core';\nimport { AccountService, LoadBalancerWriter, TaskMonitor } from '@spinnaker/core';\n\nimport { CommonGceLoadBalancerCtrl } from '../common/commonLoadBalancer.controller';\nimport type { GceCommonLoadBalancerCommandBuilder } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_HEALTH_CHECK_SELECTOR_COMPONENT } from '../common/healthCheck.component';\nimport type { IGceBackendService, IGceHealthCheck, IGceLoadBalancer } from '../../../domain/index';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\nclass ViewState {\n constructor(public sessionAffinity: string) {}\n}\n\ninterface IListKeyedByAccount {\n [account: string]: string[];\n}\n\ninterface ISslLoadBalancerUpsertDescription extends ILoadBalancerUpsertCommand {\n backendService: IGceBackendService;\n loadBalancerName: string;\n instances: IInstance[];\n}\n\nclass SslLoadBalancer implements IGceLoadBalancer {\n public stack: string;\n public detail: string;\n public loadBalancerName: string;\n public portRange = '443';\n public ipProtocol = 'TCP';\n public instances: IInstance[];\n public loadBalancerType = 'SSL';\n public credentials: string;\n public account: string;\n public certificate: string;\n public backendService: IGceBackendService = { healthCheck: { healthCheckType: 'TCP' } } as IGceBackendService;\n public cloudProvider: string;\n public name: string;\n constructor(public region = 'global') {}\n}\n\nclass SslLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements IController {\n public pages: any = {\n location: require('./createLoadBalancerProperties.html'),\n listener: require('./listener.html'),\n healthCheck: require('../common/commonHealthCheckPage.html'),\n advancedSettings: require('../common/commonAdvancedSettingsPage.html'),\n backendService: require('./backendService.html'),\n };\n public sessionAffinityViewToModelMap: any = {\n None: 'NONE',\n 'Client IP': 'CLIENT_IP',\n 'Generated Cookie': 'GENERATED_COOKIE',\n };\n public accounts: ICredentials[];\n public regions: string[];\n public certificateWrappers: any[];\n public healthChecksByAccountAndType: { [account: string]: { [healthCheckType: string]: IGceHealthCheck[] } };\n public portOptions: string[] = ['25', '43', '110', '143', '195', '443', '465', '587', '700', '993', '995'];\n\n // The 'by account' maps populate the corresponding 'existing names' lists below.\n public existingLoadBalancerNamesByAccount: IListKeyedByAccount;\n public existingHealthCheckNamesByAccount: IListKeyedByAccount;\n public existingLoadBalancerNames: string[];\n public existingHealthCheckNames: string[];\n\n public viewState: ViewState = new ViewState('None');\n public maxCookieTtl = 60 * 60 * 24; // One day.\n public taskMonitor: any;\n public hasBackendService = true;\n\n private sessionAffinityModelToViewMap: any = _.invert(this.sessionAffinityViewToModelMap);\n\n public static $inject = [\n '$scope',\n 'application',\n '$uibModalInstance',\n 'loadBalancer',\n 'gceCommonLoadBalancerCommandBuilder',\n 'isNew',\n 'forPipelineConfig',\n 'wizardSubFormValidation',\n '$state',\n ];\n constructor(\n public $scope: IScope,\n public application: Application,\n public $uibModalInstance: IModalInstanceService,\n private loadBalancer: SslLoadBalancer,\n private gceCommonLoadBalancerCommandBuilder: GceCommonLoadBalancerCommandBuilder,\n private isNew: boolean,\n private forPipelineConfig: boolean,\n private wizardSubFormValidation: any,\n $state: StateService,\n ) {\n super($scope, application, $uibModalInstance, $state);\n }\n\n public $onInit(): void {\n this.gceCommonLoadBalancerCommandBuilder\n .getBackingData(['existingLoadBalancerNamesByAccount', 'accounts', 'healthChecks', 'certificates'])\n .then((backingData) => {\n if (!this.isNew) {\n this.initializeEditMode();\n } else {\n this.loadBalancer = new SslLoadBalancer(GCEProviderSettings ? GCEProviderSettings.defaults.region : null);\n }\n\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n\n const accountNames: string[] = backingData.accounts.map((account: IAccount) => account.name);\n if (accountNames.length && !accountNames.includes(this.loadBalancer.account)) {\n this.loadBalancer.credentials = accountNames[0];\n } else {\n this.loadBalancer.credentials = this.loadBalancer.account;\n }\n\n this.accounts = backingData.accounts;\n this.certificateWrappers = backingData.certificates as any[];\n this.existingLoadBalancerNamesByAccount = backingData.existingLoadBalancerNamesByAccount;\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n backingData.healthChecks as IGceHealthCheck[],\n );\n\n // We don't count the load balancer's health check in the existing health checks list.\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n backingData.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n\n this.accountUpdated();\n\n this.wizardSubFormValidation\n .config({ scope: this.$scope, form: 'form' })\n .register({ page: 'location', subForm: 'locationForm' })\n .register({ page: 'listener', subForm: 'listenerForm' })\n .register({ page: 'healthCheck', subForm: 'healthCheckForm' })\n .register({ page: 'advancedSettings', subForm: 'advancedSettingsForm' });\n\n this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: (this.isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: this.$uibModalInstance,\n onTaskComplete: () => this.onTaskComplete(this.loadBalancer),\n });\n });\n }\n\n public onHealthCheckRefresh(): void {\n this.gceCommonLoadBalancerCommandBuilder.getBackingData(['healthChecks']).then((data) => {\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n data.healthChecks as IGceHealthCheck[],\n );\n\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n data.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n });\n }\n\n public onCertificateRefresh(): void {\n this.gceCommonLoadBalancerCommandBuilder.getBackingData(['certificates']).then((data) => {\n this.certificateWrappers = data.certificates as any[];\n });\n }\n\n public accountUpdated(): void {\n const existingHealthCheckNames = _.get<any, string[]>(this, [\n 'existingHealthCheckNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingHealthCheckNames = existingHealthCheckNames || [];\n\n const existingLoadBalancerNames = _.get<any, string[]>(this, [\n 'existingLoadBalancerNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingLoadBalancerNames = existingLoadBalancerNames || [];\n\n AccountService.getRegionsForAccount(this.loadBalancer.credentials).then((regions: IRegion[]) => {\n this.regions = regions.map((region: IRegion) => region.name);\n });\n }\n\n public updateName(): void {\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n }\n\n public setSessionAffinity(viewState: ViewState): void {\n this.loadBalancer.backendService.sessionAffinity = this.sessionAffinityViewToModelMap[viewState.sessionAffinity];\n }\n\n public submit(): void {\n const descriptor = this.isNew ? 'Create' : 'Update';\n const toSubmitLoadBalancer = _.cloneDeep(this.loadBalancer) as ISslLoadBalancerUpsertDescription;\n toSubmitLoadBalancer.name = toSubmitLoadBalancer.loadBalancerName;\n toSubmitLoadBalancer.backendService.name = toSubmitLoadBalancer.loadBalancerName;\n toSubmitLoadBalancer.cloudProvider = 'gce';\n delete toSubmitLoadBalancer.instances;\n\n if (this.forPipelineConfig) {\n Object.assign(toSubmitLoadBalancer, { healthCheck: {} });\n this.$uibModalInstance.close(toSubmitLoadBalancer);\n return;\n }\n\n this.taskMonitor.submit(() =>\n LoadBalancerWriter.upsertLoadBalancer(toSubmitLoadBalancer, this.application, descriptor, {\n healthCheck: {},\n }),\n );\n }\n\n private initializeEditMode(): void {\n this.loadBalancer.portRange = this.loadBalancer.portRange.split('-')[0];\n this.loadBalancer.certificate = this.loadBalancer.certificate.split('/').pop();\n this.viewState = new ViewState(\n this.sessionAffinityModelToViewMap[this.loadBalancer.backendService.sessionAffinity],\n );\n }\n}\n\nexport const GCE_SSL_LOAD_BALANCER_CTRL = 'spinnaker.gce.sslLoadBalancer.controller';\n\nmodule(GCE_SSL_LOAD_BALANCER_CTRL, [\n GCE_HEALTH_CHECK_SELECTOR_COMPONENT,\n GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER,\n]).controller('gceSslLoadBalancerCtrl', SslLoadBalancerCtrl);\n","import type { StateService } from '@uirouter/angularjs';\nimport type { IScope } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\nimport _ from 'lodash';\n\nimport type {\n Application,\n IAccount,\n ICredentials,\n IInstance,\n ILoadBalancerUpsertCommand,\n IRegion,\n} from '@spinnaker/core';\nimport { AccountService, LoadBalancerWriter, TaskMonitor } from '@spinnaker/core';\n\nimport { CommonGceLoadBalancerCtrl } from '../common/commonLoadBalancer.controller';\nimport type { GceCommonLoadBalancerCommandBuilder } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER } from '../common/commonLoadBalancerCommandBuilder.service';\nimport { GCE_HEALTH_CHECK_SELECTOR_COMPONENT } from '../common/healthCheck.component';\nimport type { IGceBackendService, IGceHealthCheck, IGceLoadBalancer } from '../../../domain/index';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\nclass ViewState {\n constructor(public sessionAffinity: string) {}\n}\n\ninterface IListKeyedByAccount {\n [account: string]: string[];\n}\n\ninterface ITcpLoadBalancerUpsertDescription extends ILoadBalancerUpsertCommand {\n backendService: IGceBackendService;\n loadBalancerName: string;\n instances: IInstance[];\n}\n\nclass TcpLoadBalancer implements IGceLoadBalancer {\n public stack: string;\n public detail: string;\n public loadBalancerName: string;\n public portRange = '443';\n public ipProtocol = 'TCP';\n public instances: IInstance[];\n public loadBalancerType = 'TCP';\n public credentials: string;\n public account: string;\n public backendService: IGceBackendService = { healthCheck: { healthCheckType: 'TCP' } } as IGceBackendService;\n public cloudProvider: string;\n public name: string;\n constructor(public region = 'global') {}\n}\n\nclass TcpLoadBalancerCtrl extends CommonGceLoadBalancerCtrl implements ng.IComponentController {\n public pages: any = {\n location: require('./createLoadBalancerProperties.html'),\n listener: require('./listener.html'),\n healthCheck: require('../common/commonHealthCheckPage.html'),\n advancedSettings: require('../common/commonAdvancedSettingsPage.html'),\n backendService: require('./backendService.html'),\n };\n public sessionAffinityViewToModelMap: any = {\n None: 'NONE',\n 'Client IP': 'CLIENT_IP',\n 'Generated Cookie': 'GENERATED_COOKIE',\n };\n public accounts: ICredentials[];\n public regions: string[];\n public healthChecksByAccountAndType: { [account: string]: { [healthCheckType: string]: IGceHealthCheck[] } };\n public portOptions: string[] = ['25', '43', '110', '143', '195', '443', '465', '587', '700', '993', '995'];\n\n // The 'by account' maps populate the corresponding 'existing names' lists below.\n public existingLoadBalancerNamesByAccount: IListKeyedByAccount;\n public existingHealthCheckNamesByAccount: IListKeyedByAccount;\n public existingLoadBalancerNames: string[];\n public existingHealthCheckNames: string[];\n\n public viewState: ViewState = new ViewState('None');\n public maxCookieTtl = 60 * 60 * 24; // One day.\n public taskMonitor: any;\n public hasBackendService = true;\n\n private sessionAffinityModelToViewMap: any = _.invert(this.sessionAffinityViewToModelMap);\n\n public static $inject = [\n '$scope',\n 'application',\n '$uibModalInstance',\n 'loadBalancer',\n 'gceCommonLoadBalancerCommandBuilder',\n 'isNew',\n 'forPipelineConfig',\n 'wizardSubFormValidation',\n '$state',\n ];\n constructor(\n public $scope: IScope,\n public application: Application,\n public $uibModalInstance: IModalInstanceService,\n private loadBalancer: TcpLoadBalancer,\n private gceCommonLoadBalancerCommandBuilder: GceCommonLoadBalancerCommandBuilder,\n private isNew: boolean,\n private forPipelineConfig: boolean,\n private wizardSubFormValidation: any,\n $state: StateService,\n ) {\n super($scope, application, $uibModalInstance, $state);\n }\n\n public $onInit(): void {\n this.gceCommonLoadBalancerCommandBuilder\n .getBackingData(['existingLoadBalancerNamesByAccount', 'accounts', 'healthChecks'])\n .then((backingData) => {\n if (!this.isNew) {\n this.initializeEditMode();\n } else {\n this.loadBalancer = new TcpLoadBalancer(GCEProviderSettings ? GCEProviderSettings.defaults.region : null);\n }\n\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n\n const accountNames: string[] = backingData.accounts.map((account: IAccount) => account.name);\n if (accountNames.length && !accountNames.includes(this.loadBalancer.account)) {\n this.loadBalancer.credentials = accountNames[0];\n } else {\n this.loadBalancer.credentials = this.loadBalancer.account;\n }\n\n this.accounts = backingData.accounts;\n this.existingLoadBalancerNamesByAccount = backingData.existingLoadBalancerNamesByAccount;\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n backingData.healthChecks as IGceHealthCheck[],\n );\n\n // We don't count the load balancer's health check in the existing health checks list.\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n backingData.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n\n this.accountUpdated();\n\n this.wizardSubFormValidation\n .config({ scope: this.$scope, form: 'form' })\n .register({ page: 'location', subForm: 'locationForm' })\n .register({ page: 'listener', subForm: 'listenerForm' })\n .register({ page: 'healthCheck', subForm: 'healthCheckForm' })\n .register({ page: 'advancedSettings', subForm: 'advancedSettingsForm' });\n\n this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: (this.isNew ? 'Creating ' : 'Updating ') + 'your load balancer',\n modalInstance: this.$uibModalInstance,\n onTaskComplete: () => this.onTaskComplete(this.loadBalancer),\n });\n });\n }\n\n public onHealthCheckRefresh(): void {\n this.gceCommonLoadBalancerCommandBuilder.getBackingData(['healthChecks']).then((data) => {\n this.healthChecksByAccountAndType = this.gceCommonLoadBalancerCommandBuilder.groupHealthChecksByAccountAndType(\n data.healthChecks as IGceHealthCheck[],\n );\n\n const healthCheckNamesToOmit = this.isNew ? [] : [this.loadBalancer.backendService.healthCheck.name];\n this.existingHealthCheckNamesByAccount = this.gceCommonLoadBalancerCommandBuilder.groupHealthCheckNamesByAccount(\n data.healthChecks as IGceHealthCheck[],\n healthCheckNamesToOmit,\n );\n });\n }\n\n public accountUpdated(): void {\n const existingHealthCheckNames = _.get<any, string[]>(this, [\n 'existingHealthCheckNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingHealthCheckNames = existingHealthCheckNames || [];\n\n const existingLoadBalancerNames = _.get<any, string[]>(this, [\n 'existingLoadBalancerNamesByAccount',\n this.loadBalancer.credentials,\n ]);\n this.existingLoadBalancerNames = existingLoadBalancerNames || [];\n\n AccountService.getRegionsForAccount(this.loadBalancer.credentials).then((regions: IRegion[]) => {\n this.regions = regions.map((region: IRegion) => region.name);\n });\n }\n\n public updateName(): void {\n this.loadBalancer.loadBalancerName = this.getName(this.loadBalancer, this.application);\n }\n\n public setSessionAffinity(viewState: ViewState): void {\n this.loadBalancer.backendService.sessionAffinity = this.sessionAffinityViewToModelMap[viewState.sessionAffinity];\n }\n\n public submit(): void {\n const descriptor = this.isNew ? 'Create' : 'Update';\n const toSubmitLoadBalancer = _.cloneDeep(this.loadBalancer) as ITcpLoadBalancerUpsertDescription;\n toSubmitLoadBalancer.name = toSubmitLoadBalancer.loadBalancerName;\n toSubmitLoadBalancer.backendService.name = toSubmitLoadBalancer.loadBalancerName;\n toSubmitLoadBalancer.cloudProvider = 'gce';\n delete toSubmitLoadBalancer.instances;\n\n if (this.forPipelineConfig) {\n Object.assign(toSubmitLoadBalancer, { healthCheck: {} });\n this.$uibModalInstance.close(toSubmitLoadBalancer);\n return;\n }\n\n this.taskMonitor.submit(() =>\n LoadBalancerWriter.upsertLoadBalancer(toSubmitLoadBalancer, this.application, descriptor, {\n healthCheck: {},\n }),\n );\n }\n\n private initializeEditMode(): void {\n this.loadBalancer.portRange = this.loadBalancer.portRange.split('-')[0];\n this.viewState = new ViewState(\n this.sessionAffinityModelToViewMap[this.loadBalancer.backendService.sessionAffinity],\n );\n }\n}\n\nexport const GCE_TCP_LOAD_BALANCER_CTRL = 'spinnaker.gce.tcpLoadBalancer.controller';\n\nmodule(GCE_TCP_LOAD_BALANCER_CTRL, [\n GCE_HEALTH_CHECK_SELECTOR_COMPONENT,\n GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER,\n]).controller('gceTcpLoadBalancerCtrl', TcpLoadBalancerCtrl);\n","import { module } from 'angular';\n\nconst gceBackendServiceDetailsComponent: ng.IComponentOptions = {\n bindings: {\n backendService: '<',\n },\n template: `\n <dt>Name</dt>\n <dd>{{$ctrl.backendService.name}}</dd>\n <dt>Health Check</dt>\n <dd>{{$ctrl.backendService.healthCheck.name}}</dd>\n <dt ng-if=\"$ctrl.backendService.sessionAffinity\">Session Affinity</dt>\n <dd ng-if=\"$ctrl.backendService.sessionAffinity\">{{$ctrl.backendService.sessionAffinity | gceSessionAffinityFilter}}</dd>\n <dt ng-if=\"$ctrl.backendService.sessionAffinity === 'GENERATED_COOKIE'\">Affinity Cookie TTL</dt>\n <dd ng-if=\"$ctrl.backendService.sessionAffinity === 'GENERATED_COOKIE'\">{{$ctrl.backendService.affinityCookieTtlSec}}</dd>`,\n};\n\nexport const GCE_BACKEND_SERVICE_DETAILS_COMPONENT =\n 'spinnaker.gce.loadBalancer.details.backendServiceDetails.component';\nmodule(GCE_BACKEND_SERVICE_DETAILS_COMPONENT, []).component(\n 'gceBackendServiceDetails',\n gceBackendServiceDetailsComponent,\n);\n","import { module } from 'angular';\nimport { sessionAffinityModelToViewMap } from '../../configure/common/sessionAffinityNameMaps';\n\nfunction gceSessionAffinityFilter() {\n return function (modelValue: string): string {\n return sessionAffinityModelToViewMap[modelValue] || modelValue;\n };\n}\n\nexport const SESSION_AFFINITY_FILTER = 'spinnaker.gce.loadBalancer.details.sessionAffinity.filter';\nmodule(SESSION_AFFINITY_FILTER, []).filter('gceSessionAffinityFilter', gceSessionAffinityFilter);\n","import type { IController } from 'angular';\nimport { module } from 'angular';\nimport type { IModalInstanceService } from 'angular-ui-bootstrap';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport type { Application, ILoadBalancerDeleteCommand } from '@spinnaker/core';\nimport { LoadBalancerWriter, TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE } from '../../configure/http/httpLoadBalancer.write.service';\nimport type { GceHttpLoadBalancerUtils } from '../../httpLoadBalancerUtils.service';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../../httpLoadBalancerUtils.service';\n\nclass Verification {\n public verified = false;\n}\n\nclass Params {\n public deleteHealthChecks = false;\n}\n\ninterface IGoogleLoadBalancerDeleteOperation extends ILoadBalancerDeleteCommand {\n region: string;\n accountName: string;\n deleteHealthChecks: boolean;\n loadBalancerType: string;\n}\n\nclass DeleteLoadBalancerModalController implements IController {\n public verification: Verification = new Verification();\n public params: Params = new Params();\n public taskMonitor: any;\n\n public static $inject = [\n 'application',\n 'gceHttpLoadBalancerUtils',\n 'gceHttpLoadBalancerWriter',\n 'loadBalancer',\n '$uibModalInstance',\n ];\n constructor(\n private application: Application,\n private gceHttpLoadBalancerUtils: GceHttpLoadBalancerUtils,\n private gceHttpLoadBalancerWriter: any,\n private loadBalancer: any,\n private $uibModalInstance: IModalInstanceService,\n ) {}\n\n public $onInit(): void {\n const taskMonitorConfig = {\n application: this.application,\n title: 'Deleting ' + this.loadBalancer.name,\n modalInstance: this.$uibModalInstance,\n };\n\n this.taskMonitor = new TaskMonitor(taskMonitorConfig);\n }\n\n public isValid(): boolean {\n return this.verification.verified;\n }\n\n public submit(): void {\n this.taskMonitor.submit(this.getSubmitMethod());\n }\n\n public cancel(): void {\n this.$uibModalInstance.dismiss();\n }\n\n public hasHealthChecks(): boolean {\n if (this.gceHttpLoadBalancerUtils.isHttpLoadBalancer(this.loadBalancer)) {\n return true;\n } else {\n return !!this.loadBalancer.healthCheck;\n }\n }\n\n private getSubmitMethod(): () => PromiseLike<any> {\n if (this.gceHttpLoadBalancerUtils.isHttpLoadBalancer(this.loadBalancer)) {\n return () => {\n return this.gceHttpLoadBalancerWriter.deleteLoadBalancers(this.loadBalancer, this.application, this.params);\n };\n } else {\n return () => {\n const command: IGoogleLoadBalancerDeleteOperation = {\n cloudProvider: 'gce',\n loadBalancerName: this.loadBalancer.name,\n accountName: this.loadBalancer.account,\n credentials: this.loadBalancer.account,\n region: this.loadBalancer.region,\n loadBalancerType: this.loadBalancer.loadBalancerType || 'NETWORK',\n deleteHealthChecks: this.params.deleteHealthChecks,\n };\n return LoadBalancerWriter.deleteLoadBalancer(command, this.application);\n };\n }\n }\n}\n\nexport const DELETE_MODAL_CONTROLLER = 'spinnaker.gce.loadBalancer.deleteModal.controller';\nmodule(DELETE_MODAL_CONTROLLER, [\n ANGULAR_UI_BOOTSTRAP as any,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE,\n GCE_HTTP_LOAD_BALANCER_UTILS,\n]).controller('gceLoadBalancerDeleteModalCtrl', DeleteLoadBalancerModalController);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT =\n 'spinnaker.deck.gce.loadBalancer.details.healthCheck.component';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT, []).component('gceHealthCheck', {\n bindings: {\n healthCheck: '=',\n },\n templateUrl: require('./healthCheck.component.html'),\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT =\n 'spinnaker.deck.gce.loadBalancer.loadBalancerType';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT, []).component('gceLoadBalancerType', {\n template: '<span>{{ $ctrl.type }}</span>',\n bindings: {\n loadBalancer: '=',\n },\n controller: function () {\n this.$onInit = () => {\n this.type = (function (lb) {\n if (lb.loadBalancerType === 'HTTP') {\n const hasCertificate = _.isString(lb.certificate) && !_.isEmpty(lb.certificate);\n const hasCertificateMap = _.isString(lb.certificateMap) && !_.isEmpty(lb.certificateMap);\n if (hasCertificate || hasCertificateMap) {\n return 'HTTPS';\n } else {\n return 'HTTP';\n }\n } else {\n return lb.loadBalancerType;\n }\n })(this.loadBalancer);\n };\n },\n});\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, LOAD_BALANCER_READ_SERVICE } from '@spinnaker/core';\n\nimport { GCE_BACKEND_SERVICE_DETAILS_COMPONENT } from './backendService/backendService.component';\nimport { SESSION_AFFINITY_FILTER } from './backendService/sessionAffinity.filter';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../common/xpnNaming.gce.service';\nimport { GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT } from '../configure/choice/loadBalancerTypeToWizardMap.constant';\nimport { DELETE_MODAL_CONTROLLER } from './deleteModal/deleteModal.controller';\nimport { GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT } from './healthCheck/healthCheck.component';\nimport { GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT } from './hostAndPathRules/hostAndPathRulesButton.component';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../httpLoadBalancerUtils.service';\nimport { GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT } from './loadBalancerType/loadBalancerType.component';\n\nexport const GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER =\n 'spinnaker.loadBalancer.gce.details.controller';\nexport const name = GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER, [\n UIROUTER_ANGULARJS,\n LOAD_BALANCER_READ_SERVICE,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT,\n GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT,\n GCE_HTTP_LOAD_BALANCER_UTILS,\n GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT,\n GCE_BACKEND_SERVICE_DETAILS_COMPONENT,\n DELETE_MODAL_CONTROLLER,\n SESSION_AFFINITY_FILTER,\n GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT,\n ])\n .controller('gceLoadBalancerDetailsCtrl', [\n '$scope',\n '$state',\n '$uibModal',\n 'loadBalancer',\n 'app',\n 'gceHttpLoadBalancerUtils',\n 'loadBalancerReader',\n '$q',\n 'loadBalancerTypeToWizardMap',\n 'gceXpnNamingService',\n function (\n $scope,\n $state,\n $uibModal,\n loadBalancer,\n app,\n gceHttpLoadBalancerUtils,\n loadBalancerReader,\n $q,\n loadBalancerTypeToWizardMap,\n gceXpnNamingService,\n ) {\n const application = (this.application = app);\n\n $scope.state = {\n loading: true,\n };\n\n function extractLoadBalancer() {\n $scope.loadBalancer = application.loadBalancers.data.filter(function (test) {\n const testVpc = test.vpcId || null;\n return (\n test.name === loadBalancer.name &&\n (test.region === loadBalancer.region || test.region === 'global') &&\n test.account === loadBalancer.accountId &&\n testVpc === loadBalancer.vpcId\n );\n })[0];\n\n if ($scope.loadBalancer) {\n return createDetailsLoader().then(function (details) {\n $scope.state.loading = false;\n const filtered = details.filter(function (test) {\n return test.vpcid === loadBalancer.vpcId || (!test.vpcid && !loadBalancer.vpcId);\n });\n if (filtered.length) {\n $scope.loadBalancer.elb = filtered[0];\n $scope.loadBalancer.account = loadBalancer.accountId;\n\n AccountService.getCredentialsKeyedByAccount('gce').then(function () {\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer($scope.loadBalancer)) {\n $scope.loadBalancer.elb.backendServices = getBackendServices($scope.loadBalancer);\n $scope.loadBalancer.elb.healthChecks = _.chain($scope.loadBalancer.elb.backendServices)\n .map('healthCheck')\n .uniqBy('name')\n .value();\n }\n });\n }\n AccountService.getAccountDetails(loadBalancer.accountId).then(function (accountDetails) {\n let resourceTypes;\n\n if ($scope.loadBalancer.loadBalancerType === 'INTERNAL') {\n resourceTypes = ['gce_forwarding_rule', 'gce_backend_service'];\n } else if ($scope.loadBalancer.loadBalancerType === 'NETWORK') {\n resourceTypes = ['gce_forwarding_rule', 'gce_target_pool', 'gce_health_check'];\n } else if ($scope.loadBalancer.loadBalancerType === 'SSL') {\n resourceTypes = ['gce_forwarding_rule', 'gce_backend_service'];\n } else if ($scope.loadBalancer.loadBalancerType === 'TCP') {\n resourceTypes = ['gce_forwarding_rule', 'gce_backend_service'];\n } else if ($scope.loadBalancer.loadBalancerType === 'INTERNAL_MANAGED') {\n resourceTypes = ['http_load_balancer', 'gce_target_http_proxy', 'gce_url_map', 'gce_backend_service'];\n } else {\n // $scope.loadBalancer.loadBalancerType === 'HTTP'\n resourceTypes = ['http_load_balancer', 'gce_target_http_proxy', 'gce_url_map', 'gce_backend_service'];\n }\n\n resourceTypes = _.join(resourceTypes, ' OR ');\n\n $scope.loadBalancer.project = accountDetails.project;\n $scope.loadBalancer.logsLink =\n 'https://console.developers.google.com/project/' +\n accountDetails.project +\n '/logs?advancedFilter=resource.type=(' +\n resourceTypes +\n ')%0A\"' +\n $scope.loadBalancer.name +\n '\"';\n });\n }, autoClose);\n }\n if (!$scope.loadBalancer) {\n autoClose();\n }\n return $q.when(null);\n }\n\n function createDetailsLoader() {\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer($scope.loadBalancer)) {\n const detailsPromises = $scope.loadBalancer.listeners.map((listener) => {\n return loadBalancerReader.getLoadBalancerDetails(\n $scope.loadBalancer.provider,\n loadBalancer.accountId,\n $scope.loadBalancer.region,\n listener.name,\n );\n });\n\n return $q.all(detailsPromises).then((loadBalancers) => {\n loadBalancers = _.flatten(loadBalancers);\n const representativeLb = loadBalancers[0];\n representativeLb.dns = loadBalancers.map((loadBalancer) => {\n let protocol;\n if (loadBalancer.listenerDescriptions[0].listener.loadBalancerPort === '443') {\n protocol = 'https:';\n } else {\n protocol = 'http:';\n }\n return { dnsname: loadBalancer.dnsname, protocol: protocol };\n });\n representativeLb.dns = _.uniqBy(representativeLb.dns, 'dnsname');\n representativeLb.listenerDescriptions = _.flatten(loadBalancers.map((lb) => lb.listenerDescriptions));\n return [representativeLb];\n });\n } else {\n return loadBalancerReader\n .getLoadBalancerDetails(\n $scope.loadBalancer.provider,\n loadBalancer.accountId,\n $scope.loadBalancer.region,\n $scope.loadBalancer.name,\n )\n .then((loadBalancerDetails) => {\n const loadBalancer = loadBalancerDetails[0];\n let protocol;\n if (loadBalancer.listenerDescriptions[0].listener.loadBalancerPort === '443') {\n protocol = 'https:';\n } else {\n protocol = 'http:';\n }\n loadBalancer.dns = { dnsname: loadBalancer.dnsname, protocol: protocol };\n return loadBalancerDetails;\n });\n }\n }\n\n function getBackendServices(loadBalancer) {\n let backendServices = [loadBalancer.defaultService];\n\n if (loadBalancer.hostRules.length) {\n backendServices = _.chain(loadBalancer.hostRules)\n .reduce((services, hostRule) => {\n services.push(hostRule.pathMatcher.defaultService);\n return services.concat(_.map(hostRule.pathMatcher.pathRules, 'backendService'));\n }, backendServices)\n .uniqBy('name')\n .value();\n }\n return backendServices;\n }\n\n function autoClose() {\n if ($scope.$$destroyed) {\n return;\n }\n $state.go('^', { allowModalToStayOpen: true }, { location: 'replace' });\n }\n\n app.loadBalancers\n .ready()\n .then(extractLoadBalancer)\n .then(() => {\n // If the user navigates away from the view before the initial extractLoadBalancer call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.loadBalancers.onRefresh($scope, extractLoadBalancer);\n }\n });\n\n this.editLoadBalancer = function editLoadBalancer() {\n const wizard = loadBalancerTypeToWizardMap[$scope.loadBalancer.loadBalancerType];\n\n $uibModal.open({\n templateUrl: wizard.editTemplateUrl,\n controller: `${wizard.controller} as ctrl`,\n size: 'lg',\n resolve: {\n application: function () {\n return application;\n },\n loadBalancer: function () {\n return angular.copy($scope.loadBalancer);\n },\n isNew: function () {\n return false;\n },\n },\n });\n };\n\n this.deleteLoadBalancer = function deleteLoadBalancer() {\n if (!($scope.loadBalancer.instances && $scope.loadBalancer.instances.length)) {\n $uibModal.open({\n controller: 'gceLoadBalancerDeleteModalCtrl as ctrl',\n templateUrl: require('./deleteModal/deleteModal.html'),\n resolve: {\n application: () => application,\n loadBalancer: () => $scope.loadBalancer,\n },\n });\n }\n };\n\n this.isHttpLoadBalancer = (lb) => gceHttpLoadBalancerUtils.isHttpLoadBalancer(lb);\n\n this.getNetworkId = function getNetworkId(loadBalancer) {\n return gceXpnNamingService.decorateXpnResourceIfNecessary(loadBalancer.project, loadBalancer.network);\n };\n\n this.getSubnetId = function getSubnetId(loadBalancer) {\n return gceXpnNamingService.decorateXpnResourceIfNecessary(loadBalancer.project, loadBalancer.subnet);\n };\n },\n ]);\n","import { module } from 'angular';\nimport { cloneDeep, groupBy, map, partition } from 'lodash';\n\nimport type { IGceHttpLoadBalancer, IGceLoadBalancer } from '../domain/loadBalancer';\n\nimport type { GceHttpLoadBalancerUtils } from './httpLoadBalancerUtils.service';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from './httpLoadBalancerUtils.service';\n\nexport class GceLoadBalancerSetTransformer {\n private static normalizeHttpLoadBalancerGroup(group: IGceHttpLoadBalancer[]): IGceHttpLoadBalancer {\n const normalized = cloneDeep(group[0]);\n\n normalized.listeners = group.map((loadBalancer) => {\n const port = loadBalancer.portRange ? GceLoadBalancerSetTransformer.parsePortRange(loadBalancer.portRange) : null;\n return {\n port,\n name: loadBalancer.name,\n certificate: loadBalancer.certificate,\n certificateMap: loadBalancer.certificateMap,\n ipAddress: loadBalancer.ipAddress,\n subnet: loadBalancer.subnet,\n };\n });\n\n normalized.name = normalized.urlMapName;\n delete normalized.subnet;\n return normalized;\n }\n\n private static parsePortRange(portRange: string): string {\n return portRange.split('-')[0];\n }\n\n public static $inject = ['gceHttpLoadBalancerUtils'];\n constructor(private gceHttpLoadBalancerUtils: GceHttpLoadBalancerUtils) {}\n\n public normalizeLoadBalancerSet = (loadBalancers: IGceLoadBalancer[]): IGceLoadBalancer[] => {\n const [httpLoadBalancers, otherLoadBalancers] = partition(loadBalancers, (lb) =>\n this.gceHttpLoadBalancerUtils.isHttpLoadBalancer(lb),\n );\n\n const groupedByUrlMap = groupBy(httpLoadBalancers, 'urlMapName');\n const normalizedElSevenLoadBalancers = map(\n groupedByUrlMap,\n GceLoadBalancerSetTransformer.normalizeHttpLoadBalancerGroup,\n );\n\n return (normalizedElSevenLoadBalancers as IGceLoadBalancer[]).concat(otherLoadBalancers);\n };\n}\n\nexport const LOAD_BALANCER_SET_TRANSFORMER = 'spinnaker.gce.loadBalancer.setTransformer.service';\nmodule(LOAD_BALANCER_SET_TRANSFORMER, [GCE_HTTP_LOAD_BALANCER_UTILS]).service(\n 'gceLoadBalancerSetTransformer',\n GceLoadBalancerSetTransformer,\n);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\n\nimport { SETTINGS } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER =\n 'spinnaker.gce.pipeline.stage.bake.executionDetails.controller';\nexport const name = GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER, [UIROUTER_ANGULARJS]).controller(\n 'gceBakeExecutionDetailsCtrl',\n [\n '$scope',\n '$stateParams',\n 'executionDetailsSectionService',\n '$interpolate',\n function ($scope, $stateParams, executionDetailsSectionService, $interpolate) {\n $scope.configSections = ['bakeConfig', 'taskStatus', 'artifactStatus'];\n\n const initialized = () => {\n $scope.detailsSection = $stateParams.details;\n $scope.provider = $scope.stage.context.cloudProviderType || 'gce';\n $scope.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' &&\n SETTINGS.feature.roscoSelector($scope.stage.context));\n $scope.bakeryDetailUrl = $interpolate(\n $scope.roscoMode && SETTINGS.roscoDetailUrl ? SETTINGS.roscoDetailUrl : SETTINGS.bakeryDetailUrl,\n );\n };\n\n const initialize = () => executionDetailsSectionService.synchronizeSection($scope.configSections, initialized);\n\n initialize();\n\n $scope.$on('$stateChangeSuccess', initialize);\n },\n ],\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n ArtifactReferenceService,\n AuthenticationService,\n BakeExecutionLabel,\n BakeryReader,\n ExpectedArtifactService,\n PipelineTemplates,\n Registry,\n SETTINGS,\n} from '@spinnaker/core';\nimport { GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER } from './bakeExecutionDetails.controller';\n\nexport const GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE = 'spinnaker.gce.pipeline.stage..bakeStage';\nexport const name = GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE, [GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'bake',\n cloudProvider: 'gce',\n label: 'Bake',\n description: 'Bakes an image',\n templateUrl: require('./bakeStage.html'),\n executionDetailsUrl: require('./bakeExecutionDetails.html'),\n executionLabelComponent: BakeExecutionLabel,\n extraLabelLines: (stage) => {\n return stage.masterStage.context.allPreviouslyBaked || stage.masterStage.context.somePreviouslyBaked ? 1 : 0;\n },\n producesArtifacts: true,\n supportsCustomTimeout: true,\n validators: [\n {\n type: 'anyFieldRequired',\n fields: [\n { fieldName: 'package', fieldLabel: 'Package' },\n { fieldName: 'packageArtifactIds', fieldLabel: 'Package Artifacts' },\n ],\n },\n ],\n restartable: true,\n artifactExtractor: ExpectedArtifactService.accumulateArtifacts(['packageArtifactIds']),\n artifactRemover: ArtifactReferenceService.removeArtifactFromFields(['packageArtifactIds']),\n });\n })\n .controller('gceBakeStageCtrl', [\n '$scope',\n '$q',\n '$uibModal',\n function ($scope, $q, $uibModal) {\n $scope.stage.extendedAttributes = $scope.stage.extendedAttributes || {};\n $scope.stage.region = 'global';\n\n if (!$scope.stage.cloudProvider) {\n $scope.stage.cloudProvider = 'gce';\n }\n\n if (!$scope.stage.user) {\n $scope.stage.user = AuthenticationService.getAuthenticatedUser().name;\n }\n\n $scope.viewState = {\n loading: true,\n };\n\n function initialize() {\n $scope.viewState.providerSelected = true;\n $q.all([\n BakeryReader.getBaseOsOptions('gce'),\n BakeryReader.getBaseLabelOptions(),\n ExpectedArtifactService.getExpectedArtifactsAvailableToStage($scope.stage, $scope.pipeline),\n ]).then(function ([baseOsOptions, baseLabelOptions, expectedArtifacts]) {\n $scope.baseOsOptions = baseOsOptions.baseImages;\n $scope.baseLabelOptions = baseLabelOptions;\n $scope.viewState.expectedArtifacts = expectedArtifacts;\n\n if (!$scope.stage.baseOs && $scope.baseOsOptions && $scope.baseOsOptions.length) {\n $scope.stage.baseOs = $scope.baseOsOptions[0].id;\n }\n if (!$scope.stage.baseLabel && $scope.baseLabelOptions && $scope.baseLabelOptions.length) {\n $scope.stage.baseLabel = $scope.baseLabelOptions[0];\n }\n $scope.viewState.roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector($scope.stage));\n $scope.showAdvancedOptions = showAdvanced();\n $scope.viewState.loading = false;\n });\n }\n\n function showAdvanced() {\n const stage = $scope.stage;\n return !!(\n stage.templateFileName ||\n (stage.extendedAttributes && _.size(stage.extendedAttributes) > 0) ||\n stage.varFileName ||\n stage.baseAmi ||\n stage.accountName\n );\n }\n\n function stageUpdated() {\n deleteEmptyProperties();\n // Since the selector computes using stage as an input, it needs to be able to recompute roscoMode on updates\n if (typeof SETTINGS.feature.roscoSelector === 'function') {\n $scope.viewState.roscoMode = SETTINGS.feature.roscoSelector($scope.stage);\n }\n }\n\n function deleteEmptyProperties() {\n _.forOwn($scope.stage, function (val, key) {\n if (val === '') {\n delete $scope.stage[key];\n }\n });\n }\n\n this.addExtendedAttribute = function () {\n if (!$scope.stage.extendedAttributes) {\n $scope.stage.extendedAttributes = {};\n }\n $uibModal\n .open({\n templateUrl: PipelineTemplates.addExtendedAttributes,\n controller: 'bakeStageAddExtendedAttributeController',\n controllerAs: 'addExtendedAttribute',\n resolve: {\n extendedAttribute: function () {\n return {\n key: '',\n value: '',\n };\n },\n },\n })\n .result.then(function (extendedAttribute) {\n $scope.stage.extendedAttributes[extendedAttribute.key] = extendedAttribute.value;\n })\n .catch(() => {});\n };\n\n this.removeExtendedAttribute = function (key) {\n delete $scope.stage.extendedAttributes[key];\n };\n\n this.showTemplateFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.templateFileName;\n };\n\n this.showAccountName = function () {\n return $scope.viewState.roscoMode || $scope.stage.accountName;\n };\n\n this.showExtendedAttributes = function () {\n return (\n $scope.viewState.roscoMode || ($scope.stage.extendedAttributes && _.size($scope.stage.extendedAttributes) > 0)\n );\n };\n\n this.showVarFileName = function () {\n return $scope.viewState.roscoMode || $scope.stage.varFileName;\n };\n\n $scope.$watch('stage', stageUpdated, true);\n\n initialize();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, NameUtils, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE =\n 'spinnaker.gce.pipeline.stage..cloneServerGroupStage';\nexport const name = GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'cloneServerGroup',\n cloudProvider: 'gce',\n templateUrl: require('./cloneServerGroupStage.html'),\n executionStepLabelUrl: require('./cloneServerGroupStepLabel.html'),\n validators: [\n { type: 'requiredField', fieldName: 'targetCluster', fieldLabel: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'region' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceCloneServerGroupStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.viewState = {\n accountsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then((accounts) => {\n $scope.accounts = accounts;\n $scope.viewState.accountsLoaded = true;\n });\n\n this.cloneTargets = StageConstants.TARGET_LIST;\n stage.target = stage.target || this.cloneTargets[0].val;\n stage.application = $scope.application.name;\n stage.cloudProvider = 'gce';\n stage.cloudProviderType = 'gce';\n\n if (\n stage.isNew &&\n $scope.application.attributes.platformHealthOnlyShowOverride &&\n $scope.application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n\n this.targetClusterUpdated = () => {\n if (stage.targetCluster) {\n const clusterName = NameUtils.parseServerGroupName(stage.targetCluster);\n stage.stack = clusterName.stack;\n stage.freeFormDetails = clusterName.freeFormDetails;\n } else {\n stage.stack = '';\n stage.freeFormDetails = '';\n }\n };\n\n $scope.$watch('stage.targetCluster', this.targetClusterUpdated);\n\n this.removeCapacity = () => {\n delete stage.capacity;\n };\n\n if (!_.has(stage, 'useSourceCapacity')) {\n stage.useSourceCapacity = true;\n }\n\n this.toggleDisableTraffic = () => {\n stage.disableTraffic = !stage.disableTraffic;\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE = 'spinnaker.gce.pipeline.stage..destroyAsgStage';\nexport const name = GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'destroyServerGroup',\n cloudProvider: 'gce',\n templateUrl: require('./destroyAsgStage.html'),\n executionStepLabelUrl: require('./destroyAsgStepLabel.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceDestroyAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE = 'spinnaker.gce.pipeline.stage..disableAsgStage';\nexport const name = GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'disableServerGroup',\n cloudProvider: 'gce',\n templateUrl: require('./disableAsgStage.html'),\n executionStepLabelUrl: require('./disableAsgStepLabel.html'),\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceDisableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (\n stage.isNew &&\n $scope.application.attributes.platformHealthOnlyShowOverride &&\n $scope.application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE =\n 'spinnaker.gce.pipeline.stage..disableClusterStage';\nexport const name = GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'disableCluster',\n cloudProvider: 'gce',\n templateUrl: require('./disableClusterStage.html'),\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n {\n type: 'requiredField',\n fieldName: 'remainingEnabledServerGroups',\n fieldLabel: 'Keep [X] enabled Server Groups',\n },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceDisableClusterStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (\n stage.isNew &&\n $scope.application.attributes.platformHealthOnlyShowOverride &&\n $scope.application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (stage.remainingEnabledServerGroups === undefined) {\n stage.remainingEnabledServerGroups = 1;\n }\n\n ctrl.pluralize = function (str, val) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n if (stage.preferLargerOverNewer === undefined) {\n stage.preferLargerOverNewer = 'false';\n }\n stage.preferLargerOverNewer = stage.preferLargerOverNewer.toString();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE = 'spinnaker.gce.pipeline.stage..enableAsgStage';\nexport const name = GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'enableServerGroup',\n cloudProvider: 'gce',\n templateUrl: require('./enableAsgStage.html'),\n executionStepLabelUrl: require('./enableAsgStepLabel.html'),\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceEnableAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.targets = StageConstants.TARGET_LIST;\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (\n stage.isNew &&\n $scope.application.attributes.platformHealthOnlyShowOverride &&\n $scope.application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (!stage.target) {\n stage.target = $scope.targets[0].val;\n }\n\n $scope.$watch('stage.credentials', $scope.accountUpdated);\n },\n ]);\n","'use strict';\n\nimport * as angular from 'angular';\n\nimport { AccountService, Registry } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE = 'spinnaker.gce.pipeline.stage..findAmiStage';\nexport const name = GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE; // for backwards compatibility\nangular\n .module(GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'findImage',\n cloudProvider: 'gce',\n templateUrl: require('./findAmiStage.html'),\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'selectionStrategy', fieldLabel: 'Server Group Selection' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials' },\n ],\n });\n })\n .controller('gceFindAmiStageCtrl', [\n '$scope',\n function ($scope) {\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n $scope.selectionStrategies = [\n {\n label: 'Largest',\n val: 'LARGEST',\n description: 'When multiple server groups exist, prefer the server group with the most instances',\n },\n {\n label: 'Newest',\n val: 'NEWEST',\n description: 'When multiple server groups exist, prefer the newest',\n },\n {\n label: 'Oldest',\n val: 'OLDEST',\n description: 'When multiple server groups exist, prefer the oldest',\n },\n {\n label: 'Fail',\n val: 'FAIL',\n description: 'When multiple server groups exist, fail',\n },\n ];\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n stage.selectionStrategy = stage.selectionStrategy || $scope.selectionStrategies[0].val;\n\n if (angular.isUndefined(stage.onlyEnabled)) {\n stage.onlyEnabled = true;\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n $scope.$watch('stage.credentials', $scope.accountUpdated);\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { BakeryReader, Registry } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE =\n 'spinnaker.gce.pipeline.stage..findImageFromTagsStage';\nexport const name = GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'findImageFromTags',\n cloudProvider: 'gce',\n templateUrl: require('./findImageFromTagsStage.html'),\n executionDetailsUrl: require('./findImageFromTagsExecutionDetails.html'),\n executionConfigSections: ['findImageConfig', 'taskStatus'],\n validators: [\n { type: 'requiredField', fieldName: 'packageName' },\n { type: 'requiredField', fieldName: 'tags' },\n ],\n });\n })\n .controller('gceFindImageFromTagsStageCtrl', [\n '$scope',\n function ($scope) {\n $scope.stage.tags = $scope.stage.tags || {};\n $scope.stage.regions = $scope.stage.regions || [];\n $scope.stage.cloudProvider = $scope.stage.cloudProvider || 'gce';\n\n BakeryReader.getRegions('gce').then(function (regions) {\n $scope.regions = regions;\n });\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE = 'spinnaker.gce.pipeline.stage..resizeAsgStage';\nexport const name = GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'resizeServerGroup',\n cloudProvider: 'gce',\n templateUrl: require('./resizeAsgStage.html'),\n executionStepLabelUrl: require('./resizeAsgStepLabel.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n supportsCustomTimeout: true,\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to resize a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'action' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceResizeAsgStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.viewState = {\n accountsLoaded: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.viewState.accountsLoaded = true;\n });\n\n $scope.resizeTargets = StageConstants.TARGET_LIST;\n\n $scope.scaleActions = [\n {\n label: 'Scale Up',\n val: 'scale_up',\n },\n {\n label: 'Scale Down',\n val: 'scale_down',\n },\n {\n label: 'Scale to Cluster Size',\n val: 'scale_to_cluster',\n },\n {\n label: 'Scale to Exact Size',\n val: 'scale_exact',\n },\n ];\n\n $scope.resizeTypes = [\n {\n label: 'Percentage',\n val: 'pct',\n },\n {\n label: 'Incremental',\n val: 'incr',\n },\n ];\n\n stage.capacity = stage.capacity || {};\n stage.regions = stage.regions || [];\n stage.target = stage.target || $scope.resizeTargets[0].val;\n stage.action = stage.action || $scope.scaleActions[0].val;\n stage.resizeType = stage.resizeType || $scope.resizeTypes[0].val;\n if (!stage.action && stage.resizeType === 'exact') {\n stage.action = 'scale_exact';\n }\n stage.cloudProvider = 'gce';\n stage.cloudProviderType = 'gce';\n\n if (\n stage.isNew &&\n $scope.application.attributes.platformHealthOnlyShowOverride &&\n $scope.application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n ctrl.updateResizeType = function () {\n if (stage.action === 'scale_exact') {\n stage.resizeType = 'exact';\n delete stage.scalePct;\n delete stage.scaleNum;\n } else {\n stage.capacity = {};\n if (stage.resizeType === 'pct') {\n delete stage.scaleNum;\n } else {\n stage.resizeType = 'incr';\n delete stage.scalePct;\n stage.scaleNum = stage.scaleNum || 0;\n }\n }\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE =\n 'spinnaker.gce.pipeline.stage..scaleDownClusterStage';\nexport const name = GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'scaleDownCluster',\n cloudProvider: 'gce',\n templateUrl: require('./scaleDownClusterStage.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n {\n type: 'requiredField',\n fieldName: 'remainingFullSizeServerGroups',\n fieldLabel: 'Keep [X] full size Server Groups',\n },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n strategy: true,\n });\n })\n .controller('gceScaleDownClusterStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (stage.remainingFullSizeServerGroups === undefined) {\n stage.remainingFullSizeServerGroups = 1;\n }\n\n if (stage.allowScaleDownActive === undefined) {\n stage.allowScaleDownActive = false;\n }\n\n ctrl.pluralize = function (str, val) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n if (stage.preferLargerOverNewer === undefined) {\n stage.preferLargerOverNewer = 'false';\n }\n stage.preferLargerOverNewer = stage.preferLargerOverNewer.toString();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, Registry } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE =\n 'spinnaker.gce.pipeline.stage..shrinkClusterStage';\nexport const name = GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'shrinkCluster',\n cloudProvider: 'gce',\n templateUrl: require('./shrinkClusterStage.html'),\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'shrinkToSize', fieldLabel: 'shrink to [X] Server Groups' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n })\n .controller('gceShrinkClusterStageCtrl', [\n '$scope',\n function ($scope) {\n const ctrl = this;\n\n const stage = $scope.stage;\n\n $scope.state = {\n accounts: false,\n regionsLoaded: false,\n };\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n $scope.state.accounts = true;\n });\n\n stage.regions = stage.regions || [];\n stage.cloudProvider = 'gce';\n\n if (!stage.credentials && $scope.application.defaultCredentials.gce) {\n stage.credentials = $scope.application.defaultCredentials.gce;\n }\n if (!stage.regions.length && $scope.application.defaultRegions.gce) {\n stage.regions.push($scope.application.defaultRegions.gce);\n }\n\n if (stage.shrinkToSize === undefined) {\n stage.shrinkToSize = 1;\n }\n\n if (stage.allowDeleteActive === undefined) {\n stage.allowDeleteActive = false;\n }\n\n ctrl.pluralize = function (str, val) {\n if (val === 1) {\n return str;\n }\n return str + 's';\n };\n\n if (stage.retainLargerOverNewer === undefined) {\n stage.retainLargerOverNewer = 'false';\n }\n stage.retainLargerOverNewer = stage.retainLargerOverNewer.toString();\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { AccountService, PipelineConfigService, Registry, StageConstants } from '@spinnaker/core';\n\nexport const GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE = 'spinnaker.gce.pipeline.stage..tagImageStage';\nexport const name = GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE; // for backwards compatibility\nmodule(GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE, [])\n .config(function () {\n Registry.pipeline.registerStage({\n provides: 'upsertImageTags',\n cloudProvider: 'gce',\n templateUrl: require('./tagImageStage.html'),\n executionDetailsUrl: require('./tagImageExecutionDetails.html'),\n executionConfigSections: ['tagImageConfig', 'taskStatus'],\n });\n })\n .controller('gceTagImageStageCtrl', [\n '$scope',\n ($scope) => {\n AccountService.listAccounts('gce').then((accounts) => ($scope.accounts = accounts));\n\n $scope.stage.tags = $scope.stage.tags || {};\n $scope.stage.cloudProvider = $scope.stage.cloudProvider || 'gce';\n\n const initUpstreamStages = () => {\n const upstreamDependencies = PipelineConfigService.getAllUpstreamDependencies(\n $scope.pipeline,\n $scope.stage,\n ).filter((stage) => StageConstants.IMAGE_PRODUCING_STAGES.includes(stage.type));\n $scope.consideredStages = new Map(upstreamDependencies.map((stage) => [stage.refId, stage.name]));\n };\n $scope.$watch('pipeline.stages', initUpstreamStages);\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\n\nimport { AccountService, InfrastructureCaches } from '@spinnaker/core';\n\nexport const GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER =\n 'spinnaker.gce.securityGroup.create.controller';\nexport const name = GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER, [UIROUTER_ANGULARJS])\n .controller('gceCreateSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n '$controller',\n 'application',\n 'securityGroup',\n function ($scope, $uibModalInstance, $state, $controller, application, securityGroup) {\n $scope.pages = {\n location: require('./createSecurityGroupProperties.html'),\n targets: require('./createSecurityGroupTargets.html'),\n sourceFilters: require('./createSecurityGroupSourceFilters.html'),\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n const ctrl = this;\n\n securityGroup.backingData = {};\n securityGroup.network = 'default';\n securityGroup.sourceRanges = [];\n securityGroup.sourceTags = [];\n securityGroup.ipIngress = [];\n\n angular.extend(\n this,\n $controller('gceConfigSecurityGroupMixin', {\n $scope: $scope,\n $uibModalInstance: $uibModalInstance,\n application: application,\n securityGroup: securityGroup,\n mode: 'create',\n }),\n );\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n ctrl.accountUpdated();\n });\n\n this.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n ctrl.upsert = function () {\n ctrl.mixinUpsert('Create');\n };\n\n ctrl.initializeSecurityGroups();\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\n\nimport { FirewallLabels, InfrastructureCaches, SecurityGroupWriter, TaskMonitor } from '@spinnaker/core';\n\nexport const GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER =\n 'spinnaker.google.securityGroup.edit.controller';\nexport const name = GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER, [UIROUTER_ANGULARJS])\n .controller('gceEditSecurityGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$state',\n 'application',\n 'securityGroup',\n '$controller',\n function ($scope, $uibModalInstance, $state, application, securityGroup, $controller) {\n $scope.pages = {\n targets: require('./createSecurityGroupTargets.html'),\n sourceFilters: require('./createSecurityGroupSourceFilters.html'),\n ingress: require('./createSecurityGroupIngress.html'),\n };\n\n $scope.securityGroup = securityGroup;\n\n $scope.state = {\n refreshingSecurityGroups: false,\n };\n\n angular.extend(\n this,\n $controller('gceConfigSecurityGroupMixin', {\n $scope: $scope,\n $uibModalInstance: $uibModalInstance,\n application: application,\n securityGroup: securityGroup,\n mode: 'edit',\n }),\n );\n\n $scope.isNew = false;\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Updating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: () => application.securityGroups.refresh(),\n });\n\n securityGroup.sourceRanges = _.map(securityGroup.sourceRanges, function (sourceRange) {\n return { value: sourceRange };\n });\n\n securityGroup.ipIngress = _.chain(securityGroup.ipIngressRules)\n .map(function (rule) {\n if (rule.portRanges && rule.portRanges.length > 0) {\n return rule.portRanges.map(function (portRange) {\n return {\n type: rule.protocol,\n startPort: portRange.startPort,\n endPort: portRange.endPort,\n };\n });\n } else {\n return [\n {\n type: rule.protocol,\n },\n ];\n }\n })\n .flatten()\n .value();\n\n securityGroup.sourceTags = securityGroup.sourceTags || [];\n\n this.getSecurityGroupRefreshTime = function () {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n this.addSourceCIDR = function (sourceRanges) {\n sourceRanges.push({ value: '0.0.0.0/0' });\n };\n\n this.removeSourceCIDR = function (sourceRanges, index) {\n sourceRanges.splice(index, 1);\n };\n\n this.addRule = function (ruleset) {\n ruleset.push({\n type: 'tcp',\n startPort: 7001,\n endPort: 7001,\n });\n };\n\n this.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n this.upsert = function () {\n $scope.taskMonitor.submit(function () {\n const allowed = _.map($scope.securityGroup.ipIngress, function (ipIngressRule) {\n const rule = {\n ipProtocol: ipIngressRule.type,\n };\n\n if (ipIngressRule.startPort && ipIngressRule.endPort) {\n rule.portRanges = [ipIngressRule.startPort + '-' + ipIngressRule.endPort];\n }\n\n return rule;\n });\n\n return SecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Update', {\n cloudProvider: 'gce',\n sourceRanges: _.uniq(_.map($scope.securityGroup.sourceRanges, 'value')),\n allowed: allowed,\n targetTags: $scope.securityGroup.targetTags || [],\n region: 'global',\n });\n });\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n ]);\n","import { module } from 'angular';\nimport { has } from 'lodash';\n\nimport type { Application, IServerGroup } from '@spinnaker/core';\nimport { FirewallLabels } from '@spinnaker/core';\n\nexport class GceSecurityGroupHelpTextService {\n private serverGroupsIndexedByTag: Map<string, Set<string>>;\n private application: Application;\n private account: string;\n private network: string;\n\n public register(application: Application, account: string, network: string): PromiseLike<void> {\n this.reset();\n this.application = application;\n this.account = account;\n this.network = network;\n return this.indexServerGroupsByTag();\n }\n\n public getHelpTextForTag(tag: string, tagType: 'source' | 'target'): string {\n const serverGroups = this.getServerGroupsWithTag(tag);\n let text: string;\n switch (serverGroups.length) {\n case 0:\n text = null;\n break;\n case 1:\n text = `This ${tagType} tag associates this ${FirewallLabels.get('firewall')} with the server group <em>${\n serverGroups[0]\n }</em>.`;\n break;\n default:\n text = `This ${tagType} tag associates this ${FirewallLabels.get('firewall')} with the server groups\n ${serverGroups.map((serverGroup) => `<em>${serverGroup}</em>`).join(', ')}.`;\n break;\n }\n return text;\n }\n\n public getServerGroupsWithTag(tag: string): string[] {\n if (this.serverGroupsIndexedByTag.get(tag)) {\n return Array.from(this.serverGroupsIndexedByTag.get(tag)).sort();\n } else {\n return [];\n }\n }\n\n public reset(): void {\n this.application = null;\n this.account = null;\n this.serverGroupsIndexedByTag = new Map<string, Set<string>>();\n }\n\n private indexServerGroupsByTag(): PromiseLike<void> {\n return this.application.ready().then(() => {\n this.application.getDataSource('serverGroups').data.forEach((serverGroup: IServerGroup) => {\n if (\n has(serverGroup, 'providerMetadata.tags.length') &&\n serverGroup.account === this.account &&\n serverGroup.providerMetadata?.networkName === this.network\n ) {\n serverGroup.providerMetadata.tags.forEach((tag: string) => {\n if (!this.serverGroupsIndexedByTag.get(tag)) {\n this.serverGroupsIndexedByTag.set(\n tag,\n new Set<string>([serverGroup.name]),\n );\n } else {\n this.serverGroupsIndexedByTag.get(tag).add(serverGroup.name);\n }\n });\n }\n });\n });\n }\n}\n\nexport const GCE_SECURITY_GROUP_HELP_TEXT_SERVICE = 'spinnaker.gce.securityGroupHelpText.service';\nmodule(GCE_SECURITY_GROUP_HELP_TEXT_SERVICE, []).service(\n 'gceSecurityGroupHelpTextService',\n GceSecurityGroupHelpTextService,\n);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport {\n FirewallLabels,\n ModalWizard,\n NetworkReader,\n SECURITY_GROUP_READER,\n SecurityGroupWriter,\n TaskMonitor,\n} from '@spinnaker/core';\n\nimport { GCE_SECURITY_GROUP_HELP_TEXT_SERVICE } from '../securityGroupHelpText.service';\n\nimport './securityGroup.configure.less';\n\nexport const GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER =\n 'spinnaker.google.securityGroup.baseConfig.controller';\nexport const name = GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER, [\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n GCE_SECURITY_GROUP_HELP_TEXT_SERVICE,\n]).controller('gceConfigSecurityGroupMixin', [\n '$scope',\n '$state',\n '$uibModalInstance',\n 'application',\n 'securityGroup',\n 'securityGroupReader',\n 'cacheInitializer',\n 'gceSecurityGroupHelpTextService',\n 'mode',\n function (\n $scope,\n $state,\n $uibModalInstance,\n application,\n securityGroup,\n securityGroupReader,\n cacheInitializer,\n gceSecurityGroupHelpTextService,\n mode,\n ) {\n const ctrl = this;\n\n $scope.isNew = true;\n\n $scope.state = {\n submitting: false,\n refreshingSecurityGroups: false,\n removedRules: [],\n infiniteScroll: {\n numToAdd: 20,\n currentItems: 20,\n },\n mode: mode,\n target: null,\n targetOptions: null,\n };\n\n $scope.wizard = ModalWizard;\n\n ctrl.getTagHelpText = function (tag, tagType) {\n return gceSecurityGroupHelpTextService.getHelpTextForTag(tag, tagType);\n };\n\n ctrl.addMoreItems = function () {\n $scope.state.infiniteScroll.currentItems += $scope.state.infiniteScroll.numToAdd;\n };\n\n ctrl.registerHelpTextService = function () {\n gceSecurityGroupHelpTextService.register(\n application,\n $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n securityGroup.network,\n );\n };\n\n ctrl.initializeTargetOptions = function () {\n const options = ['allowAllTraffic', 'specifyTags'];\n if ($scope.state.mode === 'edit') {\n $scope.state.targetOptions = options;\n } else {\n $scope.state.targetOptions = ['autoGenerate'].concat(options);\n }\n };\n\n ctrl.initializeTarget = function () {\n if ($scope.state.mode === 'create') {\n $scope.state.target = 'autoGenerate';\n } else {\n if ($scope.securityGroup.targetTags && $scope.securityGroup.targetTags.length > 0) {\n $scope.state.target = 'specifyTags';\n } else {\n $scope.state.target = 'allowAllTraffic';\n }\n }\n };\n\n ctrl.getTargetLabel = function (target) {\n switch (target) {\n case 'autoGenerate':\n return 'Auto-generate target tag';\n case 'allowAllTraffic':\n return 'Allow traffic to all server groups';\n case 'specifyTags':\n return 'Specify target tags';\n default:\n return null;\n }\n };\n\n ctrl.onTargetChange = function () {\n switch ($scope.state.target) {\n case 'autoGenerate':\n $scope.securityGroup.targetTags = null;\n break;\n case 'allowAllTraffic':\n $scope.securityGroup.targetTags = [];\n break;\n case 'specifyTags':\n $scope.securityGroup.targetTags = $scope.securityGroup.targetTags || [];\n break;\n default:\n break;\n }\n };\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n $uibModalInstance.close();\n const newStateParams = {\n name: $scope.securityGroup.name,\n accountId: $scope.securityGroup.credentials || $scope.securityGroup.accountName,\n region: 'global',\n vpcId: $scope.securityGroup.vpcId,\n provider: 'gce',\n };\n if (!$state.includes('**.firewallDetails')) {\n $state.go('.firewallDetails', newStateParams);\n } else {\n $state.go('^.firewallDetails', newStateParams);\n }\n }\n\n function onTaskComplete() {\n application.securityGroups.refresh();\n application.securityGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: `Creating your ${FirewallLabels.get('firewall')}`,\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n $scope.securityGroup = securityGroup;\n ctrl.initializeTargetOptions();\n ctrl.initializeTarget();\n ctrl.onTargetChange();\n ctrl.registerHelpTextService();\n\n ctrl.upsert = function () {\n $scope.taskMonitor.submit(function () {\n return SecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, 'Create');\n });\n };\n\n ctrl.mixinUpsert = function (descriptor) {\n $scope.taskMonitor.submit(function () {\n const allowed = _.map($scope.securityGroup.ipIngress, function (ipIngressRule) {\n const rule = {\n ipProtocol: ipIngressRule.type,\n };\n\n if (ipIngressRule.startPort && ipIngressRule.endPort) {\n rule.portRanges = [ipIngressRule.startPort + '-' + ipIngressRule.endPort];\n }\n\n return rule;\n });\n\n return SecurityGroupWriter.upsertSecurityGroup($scope.securityGroup, application, descriptor, {\n cloudProvider: 'gce',\n sourceRanges: _.uniq(_.map($scope.securityGroup.sourceRanges, 'value')),\n targetTags: $scope.securityGroup.targetTags,\n sourceTags: $scope.securityGroup.sourceTags,\n allowed: allowed,\n region: 'global',\n network: $scope.securityGroup.network,\n });\n });\n };\n\n ctrl.accountUpdated = function () {\n ctrl.initializeSecurityGroups();\n ctrl.updateNetworks();\n ctrl.updateName();\n };\n\n ctrl.refreshSecurityGroups = function () {\n $scope.state.refreshingSecurityGroups = true;\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n return ctrl.initializeSecurityGroups().then(function () {\n $scope.state.refreshingSecurityGroups = false;\n });\n });\n };\n\n ctrl.initializeSecurityGroups = function () {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n const account = $scope.securityGroup.credentials || $scope.securityGroup.accountName;\n\n let existingGroups;\n if (account) {\n existingGroups = securityGroups[account].gce.global;\n } else {\n existingGroups = securityGroups;\n }\n\n $scope.existingSecurityGroupNames = _.map(existingGroups, 'name');\n });\n };\n\n ctrl.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n ctrl.updateNetworks = function () {\n NetworkReader.listNetworksByProvider('gce').then(function (gceNetworks) {\n const account = $scope.securityGroup.credentials || $scope.securityGroup.accountName;\n $scope.securityGroup.backingData.networks = _(gceNetworks)\n .filter((n) => n.account === account && !n.id.includes('/'))\n .map((n) => n.id)\n .value();\n });\n };\n\n ctrl.getCurrentNamePattern = function () {\n return /^[a-zA-Z0-9-]*$/;\n };\n\n ctrl.updateName = function () {\n const securityGroup = $scope.securityGroup;\n let name = application.name;\n if (securityGroup.detail) {\n name += '-' + securityGroup.detail;\n name = _.trimEnd(name, '-');\n }\n securityGroup.name = name;\n $scope.namePreview = name;\n };\n\n ctrl.namePattern = {\n test: function (name) {\n return ctrl.getCurrentNamePattern().test(name);\n },\n };\n\n ctrl.addSourceCIDR = function (sourceRanges) {\n sourceRanges.push({ value: '0.0.0.0/0' });\n };\n\n ctrl.removeSourceCIDR = function (sourceRanges, index) {\n sourceRanges.splice(index, 1);\n };\n\n ctrl.addRule = function (ruleset) {\n ruleset.push({\n type: 'tcp',\n startPort: 7001,\n endPort: 7001,\n });\n };\n\n ctrl.removeRule = function (ruleset, index) {\n ruleset.splice(index, 1);\n };\n\n ctrl.dismissRemovedRules = function () {\n $scope.state.removedRules = [];\n ModalWizard.markClean('Ingress');\n ModalWizard.markComplete('Ingress');\n };\n\n ctrl.isValid = function () {\n return (\n ($scope.state.target === 'specifyTags' ? $scope.securityGroup.targetTags.length > 0 : true) &&\n $scope.securityGroup.ipIngress.length > 0 &&\n ($scope.securityGroup.sourceTags.length > 0 || $scope.securityGroup.sourceRanges.length > 0)\n );\n };\n\n ctrl.addTargetTag = function () {\n $scope.securityGroup.targetTags.push('');\n };\n\n ctrl.removeTargetTag = function (index) {\n $scope.securityGroup.targetTags.splice(index, 1);\n };\n\n ctrl.addSourceTag = function () {\n $scope.securityGroup.sourceTags.push('');\n };\n\n ctrl.removeSourceTag = function (index) {\n $scope.securityGroup.sourceTags.splice(index, 1);\n };\n },\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, FirewallLabels } from '@spinnaker/core';\nimport { GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER } from '../configure/ConfigSecurityGroupMixin.controller';\n\nexport const GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER =\n 'spinnaker.google.securityGroup.clone.controller';\nexport const name = GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER, [\n GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER,\n ])\n .controller('gceCloneSecurityGroupController', [\n '$scope',\n '$uibModalInstance',\n '$controller',\n 'securityGroup',\n 'application',\n function ($scope, $uibModalInstance, $controller, securityGroup, application) {\n const vm = this;\n\n $scope.pages = {\n location: require('../configure/createSecurityGroupProperties.html'),\n targets: require('../configure/createSecurityGroupTargets.html'),\n sourceFilters: require('../configure/createSecurityGroupSourceFilters.html'),\n ingress: require('../configure/createSecurityGroupIngress.html'),\n };\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n angular.extend(\n this,\n $controller('gceConfigSecurityGroupMixin', {\n $scope: $scope,\n $uibModalInstance: $uibModalInstance,\n application: application,\n securityGroup: securityGroup,\n mode: 'clone',\n }),\n );\n\n AccountService.listAccounts('gce').then(function (accounts) {\n $scope.accounts = accounts;\n vm.accountUpdated();\n });\n\n securityGroup.sourceRanges = _.map(securityGroup.sourceRanges, function (sourceRange) {\n return { value: sourceRange };\n });\n\n securityGroup.ipIngress = _.chain(securityGroup.ipIngressRules)\n .map(function (rule) {\n if (rule.portRanges && rule.portRanges.length > 0) {\n return rule.portRanges.map(function (portRange) {\n return {\n type: rule.protocol,\n startPort: portRange.startPort,\n endPort: portRange.endPort,\n };\n });\n } else {\n return [\n {\n type: rule.protocol,\n },\n ];\n }\n })\n .flatten()\n .value();\n\n securityGroup.backingData = {};\n\n securityGroup.sourceTags = securityGroup.sourceTags || [];\n\n vm.upsert = function () {\n vm.mixinUpsert('Clone');\n };\n\n vm.initializeSecurityGroups();\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n AccountService,\n CloudProviderRegistry,\n ConfirmationModalService,\n FirewallLabels,\n SECURITY_GROUP_READER,\n SecurityGroupWriter,\n} from '@spinnaker/core';\n\nimport { GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER } from '../clone/cloneSecurityGroup.controller';\nimport { GCE_SECURITY_GROUP_HELP_TEXT_SERVICE } from '../securityGroupHelpText.service';\n\nexport const GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER =\n 'spinnaker.securityGroup.gce.details.controller';\nexport const name = GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER, [\n UIROUTER_ANGULARJS,\n SECURITY_GROUP_READER,\n GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER,\n GCE_SECURITY_GROUP_HELP_TEXT_SERVICE,\n ])\n .controller('gceSecurityGroupDetailsCtrl', [\n '$scope',\n '$state',\n 'resolvedSecurityGroup',\n 'app',\n 'securityGroupReader',\n '$uibModal',\n 'gceSecurityGroupHelpTextService',\n function (\n $scope,\n $state,\n resolvedSecurityGroup,\n app,\n securityGroupReader,\n $uibModal,\n gceSecurityGroupHelpTextService,\n ) {\n const application = (this.application = app);\n const securityGroup = resolvedSecurityGroup;\n\n // needed for standalone instances\n $scope.detailsTemplateUrl = CloudProviderRegistry.getValue('gce', 'securityGroup.detailsTemplateUrl');\n\n $scope.state = {\n loading: true,\n standalone: app.isStandalone,\n };\n\n $scope.firewallLabel = FirewallLabels.get('Firewall');\n\n function extractSecurityGroup() {\n return securityGroupReader\n .getSecurityGroupDetails(\n application,\n securityGroup.accountId,\n securityGroup.provider,\n securityGroup.region,\n securityGroup.vpcId,\n securityGroup.name,\n )\n .then(function (details) {\n $scope.state.loading = false;\n\n if (!details || _.isEmpty(details)) {\n fourOhFour();\n } else {\n $scope.securityGroup = details;\n const applicationSecurityGroup = securityGroupReader.getApplicationSecurityGroup(\n application,\n securityGroup.accountId,\n securityGroup.region,\n securityGroup.name,\n );\n $scope.securityGroup = angular.extend(_.cloneDeep(applicationSecurityGroup), $scope.securityGroup);\n\n // These come back from the global firewall endpoint as '[tag-a, tag-b]'\n if (typeof $scope.securityGroup.targetTags === 'string') {\n const targetTags = $scope.securityGroup.targetTags;\n $scope.securityGroup.targetTags = targetTags.substring(1, targetTags.length - 1).split(', ');\n }\n if (typeof $scope.securityGroup.sourceTags === 'string') {\n const sourceTags = $scope.securityGroup.sourceTags;\n $scope.securityGroup.sourceTags = sourceTags.substring(1, sourceTags.length - 1).split(', ');\n }\n\n // These come back from the global firewall endpoint as '[account-a@project.iam.gserviceaccount.com, account-b@project.iam.gserviceaccount.com]'\n if (typeof $scope.securityGroup.targetServiceAccounts === 'string') {\n const targetServiceAccounts = $scope.securityGroup.targetServiceAccounts;\n $scope.securityGroup.targetServiceAccounts = targetServiceAccounts\n .substring(1, targetServiceAccounts.length - 1)\n .split(', ');\n }\n if (typeof $scope.securityGroup.sourceServiceAccounts === 'string') {\n const sourceServiceAccounts = $scope.securityGroup.sourceServiceAccounts;\n $scope.securityGroup.sourceServiceAccounts = sourceServiceAccounts\n .substring(1, sourceServiceAccounts.length - 1)\n .split(', ');\n }\n\n $scope.securityGroup.sourceRanges = _.chain($scope.securityGroup.ipRangeRules)\n .map((rule) => {\n return rule.range.ip && rule.range.cidr ? rule.range.ip + rule.range.cidr : null;\n })\n .compact()\n .uniq()\n .value();\n\n const ipIngress = _.map($scope.securityGroup.ipRangeRules, function (ipRangeRule) {\n return {\n protocol: ipRangeRule.protocol,\n portRanges: ipRangeRule.portRanges,\n };\n });\n\n let ipIngressRules = {};\n\n ipIngress.forEach(function (ipIngressRule) {\n if (_.has(ipIngressRules, ipIngressRule.protocol)) {\n ipIngressRules[ipIngressRule.protocol] = ipIngressRules[ipIngressRule.protocol].concat(\n ipIngressRule.portRanges,\n );\n\n ipIngressRules[ipIngressRule.protocol] = _.uniqBy(ipIngressRules[ipIngressRule.protocol], function (\n portRange,\n ) {\n return portRange.startPort + '->' + portRange.endPort;\n });\n } else {\n ipIngressRules[ipIngressRule.protocol] = ipIngressRule.portRanges;\n }\n });\n\n ipIngressRules = _.map(ipIngressRules, function (portRanges, protocol) {\n return {\n protocol: protocol,\n portRanges: portRanges,\n };\n });\n\n $scope.securityGroup.ipIngressRules = ipIngressRules;\n\n $scope.securityGroup.protocolPortRangeCount = _.sumBy(ipIngressRules, function (ipIngressRule) {\n return ipIngressRule.portRanges.length > 1 ? ipIngressRule.portRanges.length : 1;\n });\n\n AccountService.getAccountDetails(securityGroup.accountId).then(function (accountDetails) {\n $scope.securityGroup.logsLink =\n 'https://console.developers.google.com/project/' +\n accountDetails.project +\n '/logs?service=gce_firewall_rule&minLogLevel=0&filters=text:' +\n securityGroup.name;\n });\n\n gceSecurityGroupHelpTextService.register(\n application,\n $scope.securityGroup.accountName,\n $scope.securityGroup.network,\n );\n }\n }, fourOhFour);\n }\n\n function fourOhFour() {\n if ($scope.$$destroyed) {\n return;\n }\n $state.go('^', { allowModalToStayOpen: true }, { location: 'replace' });\n }\n\n application.securityGroups\n .ready()\n .then(() => extractSecurityGroup())\n .then(() => {\n // If the user navigates away from the view before the initial extractSecurityGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed && !app.isStandalone) {\n app.securityGroups.onRefresh($scope, extractSecurityGroup);\n }\n });\n\n this.getTagHelpText = function (tag, tagType) {\n return gceSecurityGroupHelpTextService.getHelpTextForTag(tag, tagType);\n };\n\n this.editInboundRules = function editInboundRules() {\n $uibModal.open({\n templateUrl: require('../configure/editSecurityGroup.html'),\n controller: 'gceEditSecurityGroupCtrl as ctrl',\n size: 'lg',\n resolve: {\n securityGroup: function () {\n return angular.copy($scope.securityGroup);\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.cloneSecurityGroup = function cloneSecurityGroup() {\n $uibModal.open({\n templateUrl: require('../clone/cloneSecurityGroup.html'),\n controller: 'gceCloneSecurityGroupController as ctrl',\n size: 'lg',\n resolve: {\n securityGroup: function () {\n const securityGroup = angular.copy($scope.securityGroup);\n if (securityGroup.region) {\n securityGroup.regions = [securityGroup.region];\n }\n return securityGroup;\n },\n application: function () {\n return application;\n },\n },\n });\n };\n\n this.deleteSecurityGroup = function deleteSecurityGroup() {\n const taskMonitor = {\n application: application,\n title: 'Deleting ' + securityGroup.name,\n };\n\n const submitMethod = function () {\n return SecurityGroupWriter.deleteSecurityGroup(securityGroup, application, {\n cloudProvider: $scope.securityGroup.type,\n securityGroupName: securityGroup.name,\n });\n };\n\n ConfirmationModalService.confirm({\n header: 'Really delete ' + securityGroup.name + '?',\n buttonText: 'Delete ' + securityGroup.name,\n account: securityGroup.accountId,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n });\n };\n\n if (app.isStandalone) {\n // we still want the edit to refresh the firewall details when the modal closes\n app.securityGroups = {\n refresh: extractSecurityGroup,\n };\n }\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SECURITYGROUP_SECURITYGROUP_READER = 'spinnaker.gce.securityGroup.reader';\nexport const name = GOOGLE_SECURITYGROUP_SECURITYGROUP_READER; // for backwards compatibility\nmodule(GOOGLE_SECURITYGROUP_SECURITYGROUP_READER, []).factory('gceSecurityGroupReader', function () {\n function resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {\n return indexedSecurityGroups[container.account].global[securityGroupId];\n }\n\n return {\n resolveIndexedSecurityGroup: resolveIndexedSecurityGroup,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER = 'spinnaker.gce.securityGroup.transformer';\nexport const name = GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER; // for backwards compatibility\nmodule(GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER, []).factory('gceSecurityGroupTransformer', [\n '$q',\n function ($q) {\n function normalizeSecurityGroup(securityGroup) {\n return $q.when(securityGroup); // no-op\n }\n\n return {\n normalizeSecurityGroup: normalizeSecurityGroup,\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT =\n 'spinnaker.deck.gce.autoscalingPolicy.basicSettings.component';\nexport const name = GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT, []).component(\n 'gceAutoscalingPolicyBasicSettings',\n {\n bindings: {\n policy: '=',\n updatePolicy: '<',\n },\n templateUrl: require('./basicSettings.component.html'),\n controller: function controller() {\n this.modes = ['ON', 'OFF', 'ONLY_SCALE_OUT'];\n },\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nexport const GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT =\n 'spinnaker.deck.gce.autoscalingPolicy.metricSettings.component';\nexport const name = GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT, []).component(\n 'gceAutoscalingPolicyMetricSettings',\n {\n bindings: {\n policy: '=',\n showNoMetricsWarning: '=',\n updatePolicy: '<',\n },\n templateUrl: require('./metricSettings.component.html'),\n controller: function () {\n this.$onInit = () => {\n const multipleAllowedFor = {\n cpuUtilization: false,\n loadBalancingUtilization: false,\n customMetricUtilizations: true,\n };\n\n const metricTypes = Object.keys(multipleAllowedFor);\n\n this.targetTypesToDisplayMap = {\n GAUGE: 'Gauge',\n DELTA_PER_SECOND: 'Delta / second',\n DELTA_PER_MINUTE: 'Delta / minute',\n };\n\n this.metricScopeTypesToDisplayMap = {\n TIME_SERIES_PER_INSTANCE: 'Time series per instance',\n SINGLE_TIME_SERIES_PER_GROUP: 'Single time series per group',\n };\n\n this.scalingpolicyTypesToDisplayMap = {\n UTILIZATION_TARGET: 'Utilization target',\n SINGLE_INSTANCE_ASSIGNMENT: 'singleInstanceAssignment',\n };\n\n this.addMetric = (metricType) => {\n if (multipleAllowedFor[metricType]) {\n this.policy[metricType] = this.policy[metricType] || [];\n this.policy[metricType].push({});\n } else if (emptyOrUndefined(this.policy[metricType])) {\n this.policy[metricType] = { utilizationTarget: null };\n }\n };\n\n this.deleteMetric = (metricType, index) => {\n if (multipleAllowedFor[metricType]) {\n this.policy[metricType].splice(index, 1);\n } else {\n // sending an empty object to the API deletes the policy.\n this.policy[metricType] = {};\n }\n };\n\n this.showMetric = (metricType) => {\n const metric = this.policy[metricType];\n // should not show policy form if the policy is undefined or an empty object.\n return !emptyOrUndefined(metric);\n };\n\n this.isSingleTimeSeriesPerGroup = (scopeType, index) => {\n if (this.policy.customMetricUtilizations[index].metricExportScope === scopeType) return true;\n };\n\n this.isScalingPolicySingleInstanceAssignment = (policyType, index) => {\n if (this.policy.customMetricUtilizations[index].scalingpolicy === policyType) return true;\n };\n\n this.showNoMetricsWarning = () => {\n return _.every(\n metricTypes.map((type) => {\n return _.some([\n multipleAllowedFor[type] && !_.get(this.policy, [type, 'length']),\n emptyOrUndefined(this.policy[type]),\n ]);\n }),\n );\n };\n\n this.setUtilizationTargetFromDisplay = (metricType, value) => {\n this.policy[metricType].utilizationTarget = value / 100;\n };\n\n this.initializeTargetDisplay = (metricType) => {\n this[`${metricType}TargetDisplay`] = safeDecimalToPercent(this.policy[metricType].utilizationTarget);\n };\n\n function safeDecimalToPercent(value) {\n if (value === 0) {\n return 0;\n }\n return value ? Math.round(value * 100) : undefined;\n }\n\n function emptyOrUndefined(value) {\n return _.isEqual(value, {}) || _.isUndefined(value);\n }\n };\n },\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\nimport timezones from './standardTimezone.json';\n\nexport const GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT =\n 'spinnaker.deck.gce.autoscalingPolicy.scalingSchedules.component';\nexport const name = GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT, []).component(\n 'gceAutoscalingPolicyScalingSchedules',\n {\n bindings: {\n policy: '=',\n updatePolicy: '<',\n },\n templateUrl: require('./scalingSchedules.component.html'),\n controller: function () {\n this.$onInit = () => {\n const multipleAllowedFor = {\n scalingSchedules: true,\n };\n\n this.timezones = timezones;\n\n this.addSchedule = (scheduleType) => {\n if (multipleAllowedFor[scheduleType]) {\n this.policy[scheduleType] = this.policy[scheduleType] || [];\n this.policy[scheduleType].push({});\n } else if (emptyOrUndefined(this.policy[scheduleType])) {\n this.policy[scheduleType] = {};\n }\n };\n\n this.deleteSchedule = (scheduleType, index) => {\n if (multipleAllowedFor[scheduleType]) {\n this.policy[scheduleType].splice(index, 1);\n } else {\n // sending an empty object to the API deletes the policy.\n this.policy[scheduleType] = {};\n }\n };\n\n this.selectTimezone = (timezone, index) => {\n const { scalingSchedules } = this.policy;\n const schedule = scalingSchedules[index];\n scalingSchedules[index] = { ...schedule, timezone };\n\n this.updatePolicy({\n ...this.policy,\n scalingSchedules: [...scalingSchedules],\n });\n };\n\n function emptyOrUndefined(value) {\n return _.isEqual(value, {}) || _.isUndefined(value);\n }\n };\n },\n },\n);\n","import { module } from 'angular';\nimport { chain } from 'lodash';\nimport React from 'react';\nimport type { AutocompleteResult, Option } from 'react-select';\nimport { Async } from 'react-select';\nimport { react2angular } from 'react2angular';\nimport { withErrorBoundary } from '@spinnaker/core';\n\ninterface ITimezoneSelectProps {\n availableTimezones: string[];\n selectedTimezone: string;\n selectTimezone: (timezone: string, target?: any) => void;\n target?: any;\n}\n\nexport class TimezoneSelect extends React.Component<ITimezoneSelectProps> {\n private loadOptions = (inputValue: string): Promise<AutocompleteResult<string>> => {\n return new Promise((resolve) => {\n if (!inputValue || inputValue.length < 3) {\n resolve({\n options: [],\n complete: false,\n });\n } else {\n const filteredOptions = chain(this.props.availableTimezones)\n .filter((i) => i.toLowerCase().includes(inputValue))\n .map((i) => ({ value: i, label: i }))\n .value();\n resolve({\n options: filteredOptions,\n complete: false,\n });\n }\n });\n };\n\n public render() {\n return (\n <Async\n cache={null}\n clearable={false}\n ignoreAccents={false}\n loadOptions={this.loadOptions}\n onChange={(selected: Option<string>) => this.props.selectTimezone(selected.value, this.props.target)}\n placeholder=\"Type at least 3 characters to search for an timezone...\"\n searchPromptText=\"Type at least 3 characters to search for an timezone...\"\n value={{ value: this.props.selectedTimezone, label: this.props.selectedTimezone }}\n required={true}\n />\n );\n }\n}\n\nexport const GCE_TIMEZONE_SELECT = 'spinnaker.gce.timezoneSelect';\nmodule(GCE_TIMEZONE_SELECT, []).component(\n 'gceTimezoneSelect',\n react2angular(withErrorBoundary(TimezoneSelect, 'gceTimezoneSelect'), [\n 'availableTimezones',\n 'selectedTimezone',\n 'selectTimezone',\n 'target',\n ]),\n);\n","'use strict';\n\nimport { module } from 'angular';\nimport { defaults } from 'lodash';\n\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../loadBalancer/httpLoadBalancerUtils.service';\n\nexport const GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER = 'spinnaker.gce.serverGroup.transformer';\nexport const name = GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER, [GCE_HTTP_LOAD_BALANCER_UTILS]).factory(\n 'gceServerGroupTransformer',\n [\n 'gceHttpLoadBalancerUtils',\n function (gceHttpLoadBalancerUtils) {\n function normalizeServerGroup(serverGroup, application) {\n return application\n .getDataSource('loadBalancers')\n .ready()\n .then(() => {\n if (serverGroup.loadBalancers) {\n // At this point, the HTTP(S) load balancers have been normalized (listener names mapped to URL map names).\n // Our server groups' lists of load balancer names still need to make this mapping.\n serverGroup.loadBalancers = gceHttpLoadBalancerUtils.normalizeLoadBalancerNamesForAccount(\n serverGroup.loadBalancers,\n serverGroup.account,\n application.getDataSource('loadBalancers').data,\n );\n }\n return serverGroup;\n });\n }\n\n function convertServerGroupCommandToDeployConfiguration(base) {\n const truncatedZones = base.backingData.filtered.truncatedZones;\n\n // use defaults to avoid copying the backingData, which is huge and expensive to copy over\n const command = defaults({ backingData: [], viewState: [] }, base);\n if (base.viewState.mode !== 'clone') {\n delete command.source;\n }\n // We took this approach to avoid a breaking change to existing pipelines.\n command.disableTraffic = !command.enableTraffic;\n command.cloudProvider = 'gce';\n command.availabilityZones = {};\n command.availabilityZones[command.region] = base.zone ? [base.zone] : truncatedZones;\n command.account = command.credentials;\n delete command.viewState;\n delete command.backingData;\n delete command.selectedProvider;\n delete command.implicitSecurityGroups;\n delete command.enableTraffic;\n delete command.providerType;\n delete command.enableAutoHealing;\n\n return command;\n }\n\n return {\n convertServerGroupCommandToDeployConfiguration: convertServerGroupCommandToDeployConfiguration,\n normalizeServerGroup: normalizeServerGroup,\n };\n },\n ],\n);\n","import type { IGceHealthCheck, IGceHealthCheckKind } from '../domain';\n\nexport interface IGceHealthCheckOption {\n displayName: string;\n kind: IGceHealthCheckKind;\n name: string;\n selfLink: string;\n}\n\nexport function parseHealthCheckUrl(url: string): { healthCheckName: string; healthCheckKind: IGceHealthCheckKind } {\n const healthCheckPathParts = url.split('/');\n if (healthCheckPathParts.length < 2) {\n throw new Error(`Health check url ${url} missing expected segments.`);\n }\n const healthCheckName = healthCheckPathParts[healthCheckPathParts.length - 1];\n const healthCheckKind = healthCheckPathParts[healthCheckPathParts.length - 2].slice(0, -1);\n return {\n healthCheckName,\n healthCheckKind: healthCheckKind as IGceHealthCheckKind,\n };\n}\n\nexport function getHealthCheckOptions(healthChecks: IGceHealthCheck[]): IGceHealthCheckOption[] {\n const duplicateNames = getDuplicateHealthCheckNames(healthChecks);\n return healthChecks.map((hc) => {\n const isNameDupe = duplicateNames.has(hc.name);\n return {\n displayName: isNameDupe ? `${hc.name} (${hc.kind})` : hc.name,\n kind: hc.kind,\n name: hc.name,\n selfLink: hc.selfLink,\n };\n });\n}\n\nexport function getDuplicateHealthCheckNames(healthChecks: IGceHealthCheck[]): Set<string> {\n const allNames = new Set<string>();\n const duplicateNames = new Set<string>();\n healthChecks.forEach((hc) => {\n if (allNames.has(hc.name)) {\n duplicateNames.add(hc.name);\n } else {\n allNames.add(hc.name);\n }\n });\n return duplicateNames;\n}\n","import { get, intersectionBy, isFinite } from 'lodash';\n\nexport interface IGceAcceleratorTypeRaw {\n name: string;\n description: string;\n maximumCardsPerInstance: number;\n}\n\nexport interface IGceAcceleratorType extends IGceAcceleratorTypeRaw {\n availableCardCounts: number[];\n}\n\ninterface IZoneToAcceleratorTypesMap {\n [zone: string]: IGceAcceleratorTypeRaw[];\n}\n\nexport interface IGceAcceleratorCommand {\n backingData: any;\n credentials: string;\n distributionPolicy: { zones: string[]; targetShape?: string };\n regional: boolean;\n selectZones: boolean;\n zone: string;\n}\n\nexport class GceAcceleratorService {\n public static getAvailableAccelerators({\n backingData,\n credentials,\n distributionPolicy,\n regional,\n selectZones,\n zone,\n }: IGceAcceleratorCommand): IGceAcceleratorType[] {\n const acceleratorMap = this.getZoneToAcceleratorTypesMap(backingData, credentials);\n\n if (zone && !regional) {\n return this.getAcceleratorTypesForZone(acceleratorMap, zone);\n }\n\n if (regional && selectZones) {\n const zones = get(distributionPolicy, 'zones', []);\n const allZonesAcceleratorTypes = zones.map((z) => this.getAcceleratorTypesForZone(acceleratorMap, z));\n return intersectionBy.apply(null, [...allZonesAcceleratorTypes, 'name']);\n }\n\n return [];\n }\n\n private static getZoneToAcceleratorTypesMap(backingData: any, credentials: string): IZoneToAcceleratorTypesMap {\n return get(backingData, ['credentialsKeyedByAccount', credentials, 'zoneToAcceleratorTypesMap'], {});\n }\n\n private static getAcceleratorTypesForZone(\n acceleratorMap: IZoneToAcceleratorTypesMap,\n zone: string,\n ): IGceAcceleratorType[] {\n return get(acceleratorMap, [zone, 'acceleratorTypes', 'acceleratorTypes'], []).map((a) => {\n return {\n ...a,\n availableCardCounts: this.getAvailableCardCounts(a),\n };\n });\n }\n\n private static getAvailableCardCounts(accelerator: IGceAcceleratorTypeRaw): number[] {\n const maxCards = isFinite(accelerator.maximumCardsPerInstance) ? accelerator.maximumCardsPerInstance : 4;\n const availableCardCounts = [];\n for (let i = 1; i <= maxCards; i *= 2) {\n availableCardCounts.push(i);\n }\n return availableCardCounts;\n }\n}\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { FirewallLabels } from '@spinnaker/core';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE =\n 'spinnaker.deck.gce.tagManager.service';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE, []).factory('gceTagManager', function () {\n const resetKeys = ['command', 'securityGroups', 'securityGroupObjectsKeyedByTag', 'securityGroupObjectsKeyedById'];\n\n this.reset = () => {\n resetKeys.forEach((key) => delete this[key]);\n };\n\n this.register = (command) => {\n this.command = command;\n const { credentials, backingData } = command;\n if (backingData.securityGroups[credentials] !== undefined) {\n this.securityGroupObjects = _.cloneDeep(backingData.securityGroups[credentials].gce.global);\n\n initializeSecurityGroupObjects(this.securityGroupObjects, command.tags);\n\n const { byTag, bySecurityGroupId } = groupSecurityGroupObjects(this.securityGroupObjects);\n this.securityGroupObjectsKeyedByTag = byTag;\n this.securityGroupObjectsKeyedById = bySecurityGroupId;\n }\n\n if (!command.securityGroups) {\n command.securityGroups = this.inferSecurityGroupIdsFromTags(command.tags);\n }\n };\n\n this.inferSecurityGroupIdsFromTags = (commandTags = []) => {\n return _.chain(commandTags)\n .map((t) => this.securityGroupObjectsKeyedByTag[t.value])\n .flatten()\n .compact()\n .filter((sg) => sg.network === this.command.network)\n .map('id')\n .uniq()\n .value();\n };\n\n const initializeSecurityGroupObjects = (securityGroupObjects, commandTags = []) => {\n securityGroupObjects.forEach((sg) => {\n // Raw target tags look like '[tag-a, tag-b]'.\n const rawTags = sg.targetTags;\n sg.tagsArray = rawTags ? rawTags.substring(1, rawTags.length - 1).split(', ') : [];\n\n sg.selectedTags = commandTags\n ? _.intersection(\n commandTags.map((t) => t.value),\n sg.tagsArray,\n )\n : [];\n });\n };\n\n const groupSecurityGroupObjects = (securityGroupObjects) => {\n return securityGroupObjects.reduce(\n (groupings, sg) => {\n const { bySecurityGroupId } = groupings;\n bySecurityGroupId[sg.id] = sg;\n\n return sg.tagsArray.reduce((groupings, tag) => {\n const { byTag } = groupings;\n if (!byTag[tag]) {\n byTag[tag] = [];\n }\n byTag[tag].push(sg);\n\n return groupings;\n }, groupings);\n },\n { byTag: {}, bySecurityGroupId: {} },\n );\n };\n\n this.inferSelectedSecurityGroupFromTag = _.debounce((tagName) => {\n let securityGroupObjectsWithTag = this.securityGroupObjectsKeyedByTag[tagName];\n const c = this.command;\n\n if (securityGroupObjectsWithTag) {\n securityGroupObjectsWithTag = _.filter(securityGroupObjectsWithTag, (sg) => sg.network === this.command.network);\n }\n\n if (securityGroupObjectsWithTag) {\n updateSelectedTagsOnSecurityGroupObjects(securityGroupObjectsWithTag, tagName);\n c.securityGroups = _.map(\n updateSelectedSecurityGroups(getSecurityGroupObjectsFromIds(c.securityGroups), securityGroupObjectsWithTag),\n 'id',\n );\n }\n\n // If you pause while typing \"tag-a,\" but you really want to add \"tag-abc,\"\n // make sure you remove \"tag-a\".\n this.updateSelectedTags();\n }, 100);\n\n this.updateSelectedTags = () => {\n const c = this.command;\n const tags = c.tags.map((t) => t.value);\n\n getSecurityGroupObjectsFromIds(c.securityGroups).forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = _.intersection(sg.selectedTags, tags);\n }\n\n if (!_.get(sg, 'selectedTags.length')) {\n c.securityGroups = _.without(c.securityGroups, sg.id);\n }\n });\n };\n\n this.addTag = (tagName) => {\n const c = this.command;\n const tags = c.tags;\n let securityGroupObjectsWithTag = this.securityGroupObjectsKeyedByTag[tagName];\n\n if (securityGroupObjectsWithTag) {\n securityGroupObjectsWithTag = _.filter(securityGroupObjectsWithTag, (sg) => sg.network === this.command.network);\n }\n\n if (\n !_.includes(\n tags.map((t) => t.value),\n tagName,\n )\n ) {\n tags.push({ value: tagName });\n }\n\n if (securityGroupObjectsWithTag) {\n updateSelectedTagsOnSecurityGroupObjects(securityGroupObjectsWithTag, tagName);\n c.securityGroups = _.map(\n updateSelectedSecurityGroups(getSecurityGroupObjectsFromIds(c.securityGroups), securityGroupObjectsWithTag),\n 'id',\n );\n }\n };\n\n const getSecurityGroupObjectsFromIds = (ids) => ids.map((id) => this.securityGroupObjectsKeyedById[id]);\n\n const updateSelectedTagsOnSecurityGroupObjects = (securityGroupObjects, newTag) => {\n securityGroupObjects.forEach((sg) => {\n sg.selectedTags = _.chain(sg.selectedTags || [])\n .concat([newTag])\n .uniq()\n .value();\n });\n };\n\n const updateSelectedSecurityGroups = (oldGroups, newGroups) => {\n return _.chain(oldGroups).concat(newGroups).uniq().value();\n };\n\n this.removeTag = (tagName) => {\n const c = this.command;\n const securityGroupIds = c.securityGroups || [];\n const securityGroupObjects = getSecurityGroupObjectsFromIds(securityGroupIds);\n\n securityGroupObjects.forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = sg.selectedTags.filter((tag) => tag !== tagName);\n }\n });\n\n c.tags = c.tags.filter((tag) => tag.value !== tagName);\n };\n\n this.removeSecurityGroup = (securityGroupId) => {\n const securityGroupObject = this.securityGroupObjectsKeyedById[securityGroupId];\n const tagsToRemove = securityGroupObject.selectedTags;\n const c = this.command;\n\n getSecurityGroupObjectsFromIds(c.securityGroups).forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = _.difference(sg.selectedTags, tagsToRemove);\n }\n });\n\n securityGroupObject.selectedTags = [];\n c.tags = _.chain(c.tags)\n .map((t) => t.value)\n .difference(tagsToRemove)\n .map((t) => ({ value: t }))\n .value();\n };\n\n this.getToolTipContent = (tagName) => {\n const groups = _.get(this, ['securityGroupObjectsKeyedByTag', tagName]);\n const groupIds = groups ? groups.filter((sg) => sg.network === this.command.network).map((sg) => sg.id) : [];\n\n return `This tag associates this server group with ${\n groupIds.length > 1 ? FirewallLabels.get('firewalls') : FirewallLabels.get('firewall')\n }\n <em>${groupIds.join(', ')}</em>.`;\n };\n\n this.showToolTip = (tagName) => {\n return !!_.get(this, ['securityGroupObjectsKeyedByTag', tagName]);\n };\n\n return this;\n});\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n AccountService,\n CACHE_INITIALIZER_SERVICE,\n LOAD_BALANCER_READ_SERVICE,\n NetworkReader,\n SECURITY_GROUP_READER,\n SubnetReader,\n} from '@spinnaker/core';\n\nimport { GCEProviderSettings } from '../../gce.settings';\nimport { GCE_HEALTH_CHECK_READER } from '../../healthCheck/healthCheck.read.service';\nimport { getHealthCheckOptions } from '../../healthCheck/healthCheckUtils';\nimport { GceImageReader } from '../../image';\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE } from './../../instance/custom/customInstanceBuilder.gce.service';\nimport { GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE } from '../../instance/gceInstanceType.service';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../../loadBalancer/httpLoadBalancerUtils.service';\nimport { LOAD_BALANCER_SET_TRANSFORMER } from '../../loadBalancer/loadBalancer.setTransformer';\nimport { GceAcceleratorService } from './wizard/advancedSettings/gceAccelerator.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from './wizard/securityGroups/tagManager.service';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE =\n 'spinnaker.serverGroup.configure.gce.configuration.service';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE, [\n LOAD_BALANCER_SET_TRANSFORMER,\n SECURITY_GROUP_READER,\n CACHE_INITIALIZER_SERVICE,\n LOAD_BALANCER_READ_SERVICE,\n GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE,\n GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE,\n GCE_HTTP_LOAD_BALANCER_UTILS,\n GCE_HEALTH_CHECK_READER,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n ])\n .factory('gceServerGroupConfigurationService', [\n 'securityGroupReader',\n 'gceInstanceTypeService',\n 'cacheInitializer',\n '$q',\n 'loadBalancerReader',\n 'gceCustomInstanceBuilderService',\n 'gceHttpLoadBalancerUtils',\n 'gceHealthCheckReader',\n 'gceTagManager',\n 'gceLoadBalancerSetTransformer',\n function (\n securityGroupReader,\n gceInstanceTypeService,\n cacheInitializer,\n $q,\n loadBalancerReader,\n gceCustomInstanceBuilderService,\n gceHttpLoadBalancerUtils,\n gceHealthCheckReader,\n gceTagManager,\n gceLoadBalancerSetTransformer,\n ) {\n const persistentDiskTypes = ['pd-standard', 'pd-ssd', 'hyperdisk-balanced'];\n const authScopes = [\n 'cloud-platform',\n 'userinfo.email',\n 'compute.readonly',\n 'compute',\n 'cloud.useraccounts.readonly',\n 'cloud.useraccounts',\n 'devstorage.read_only',\n 'devstorage.write_only',\n 'devstorage.full_control',\n 'taskqueue',\n 'bigquery',\n 'sqlservice.admin',\n 'datastore',\n 'logging.write',\n 'logging.read',\n 'logging.admin',\n 'monitoring.write',\n 'monitoring.read',\n 'monitoring',\n 'bigtable.data.readonly',\n 'bigtable.data',\n 'bigtable.admin',\n 'bigtable.admin.table',\n ];\n\n function configureCommand(application, command) {\n return $q\n .all([\n AccountService.getCredentialsKeyedByAccount('gce'),\n securityGroupReader.getAllSecurityGroups(),\n NetworkReader.listNetworksByProvider('gce'),\n SubnetReader.listSubnetsByProvider('gce'),\n loadBalancerReader.listLoadBalancers('gce'),\n loadAllImages(command.credentials),\n gceInstanceTypeService.getAllTypesByRegion(),\n $q.when(angular.copy(persistentDiskTypes)),\n $q.when(angular.copy(authScopes)),\n gceHealthCheckReader.listHealthChecks(),\n AccountService.listAccounts('gce'),\n ])\n .then(function ([\n credentialsKeyedByAccount,\n securityGroups,\n networks,\n subnets,\n loadBalancers,\n allImages,\n instanceTypes,\n persistentDiskTypes,\n authScopes,\n healthChecks,\n accounts,\n ]) {\n const backingData = {\n credentialsKeyedByAccount,\n securityGroups,\n networks,\n subnets,\n loadBalancers,\n allImages,\n instanceTypes,\n persistentDiskTypes,\n authScopes,\n healthChecks,\n accounts,\n };\n let securityGroupReloader = $q.when(null);\n let networkReloader = $q.when(null);\n let healthCheckReloader = $q.when(null);\n backingData.filtered = {};\n backingData.distributionPolicyTargetShapes = getDistributionPolicyTargetShapes();\n command.backingData = backingData;\n configureImages(command);\n\n if (command.securityGroups && command.securityGroups.length) {\n // Verify all firewalls are accounted for; otherwise, try refreshing firewalls cache.\n const securityGroupIds = _.map(getSecurityGroups(command), 'id');\n if (_.intersection(command.securityGroups, securityGroupIds).length < command.securityGroups.length) {\n securityGroupReloader = refreshSecurityGroups(command, true);\n }\n }\n if (command.network) {\n // Verify network is accounted for; otherwise, try refreshing networks cache.\n const networkNames = getNetworkNames(command);\n if (!networkNames.includes(command.network)) {\n networkReloader = refreshNetworks(command);\n }\n }\n\n if (command.autoScalingPolicy) {\n command.enableAutoScaling = true;\n }\n\n if (command.autoHealingPolicy) {\n command.enableAutoHealing = true;\n }\n if (_.has(command, 'autoHealingPolicy.healthCheck')) {\n // Verify health check is accounted for; otherwise, try refreshing health checks cache.\n const healthChecks = getHealthChecks(command);\n if (!_.chain(healthChecks).map('selfLink').includes(command.autoHealingPolicy.healthCheckUrl).value()) {\n healthCheckReloader = refreshHealthChecks(command, true);\n }\n }\n\n return $q.all([securityGroupReloader, networkReloader, healthCheckReloader]).then(() => {\n gceTagManager.register(command);\n attachEventHandlers(command);\n });\n });\n }\n\n function getDistributionPolicyTargetShapes() {\n return ['ANY', 'EVEN'];\n }\n\n function configureDistributionPolicyTargetShape(command) {\n const accountDetails = command.backingData.credentialsKeyedByAccount[command.credentials];\n if (!command.distributionPolicy.targetShape) {\n command.distributionPolicy.targetShape = 'EVEN';\n }\n }\n\n function loadAllImages(account) {\n return GceImageReader.findImages({\n account: account,\n provider: 'gce',\n q: '*',\n });\n }\n\n function configureInstanceTypes(command) {\n const result = { dirty: {} };\n if (command.region) {\n const results = [result.dirty];\n\n results.push(configureCustomInstanceTypes(command).dirty);\n results.push(configureStandardInstanceTypes(command).dirty);\n\n angular.extend(...results);\n } else {\n command.backingData.filtered.instanceTypes = [];\n }\n return result;\n }\n\n function configureCpuPlatforms(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n const locationToCpuPlatformsMap =\n command.backingData.credentialsKeyedByAccount[command.credentials].locationToCpuPlatformsMap;\n\n filteredData.cpuPlatforms = ['(Automatic)'];\n\n const location = command.regional ? command.region : command.zone;\n\n if (_.has(locationToCpuPlatformsMap, location)) {\n filteredData.cpuPlatforms = _.concat(filteredData.cpuPlatforms, locationToCpuPlatformsMap[location]);\n }\n\n if (!_.includes(filteredData.cpuPlatforms, command.minCpuPlatform)) {\n delete command.minCpuPlatform;\n result.dirty.minCpuPlatform = true;\n }\n return result;\n }\n\n function configureStandardInstanceTypes(command) {\n const c = command;\n const result = { dirty: {} };\n\n const locations = c.regional ? c.distributionPolicy.zones : [c.zone];\n const { credentialsKeyedByAccount } = c.backingData;\n const { locationToInstanceTypesMap } = credentialsKeyedByAccount[c.credentials];\n\n if (locations.every((l) => !l)) {\n return result;\n }\n\n let filtered = gceInstanceTypeService.getAvailableTypesForLocations(locationToInstanceTypesMap, locations);\n\n filtered = sortInstanceTypes(filtered);\n const instanceType = c.instanceType;\n if (_.every([instanceType, !_.includes(instanceType, 'custom-'), !_.includes(filtered, instanceType)])) {\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n c.backingData.filtered.instanceTypes = filtered;\n return result;\n }\n\n function configureCustomInstanceTypes(command) {\n const c = command;\n const result = { dirty: {} };\n let vCpuCount = _.get(c, 'viewState.customInstance.vCpuCount');\n const instanceFamily = _.get(c, 'viewState.customInstance.instanceFamily');\n const memory = _.get(c, 'viewState.customInstance.memory');\n const extendedMemory = _.get(c, 'viewState.customInstance.extendedMemory');\n const { zone, regional, region } = c;\n const { locationToInstanceTypesMap } = c.backingData.credentialsKeyedByAccount[c.credentials];\n const location = regional ? region : zone;\n\n if (!location) {\n return result;\n }\n\n if (zone || regional) {\n _.set(\n c,\n 'backingData.customInstanceTypes.vCpuList',\n gceCustomInstanceBuilderService.generateValidVCpuListForLocation(location, locationToInstanceTypesMap),\n );\n }\n\n // initializes vCpuCount so that memory selector will be populated.\n if (\n !vCpuCount ||\n !gceCustomInstanceBuilderService.vCpuCountForLocationIsValid(\n instanceFamily,\n vCpuCount,\n location,\n locationToInstanceTypesMap,\n )\n ) {\n vCpuCount = _.get(c, 'backingData.customInstanceTypes.vCpuList[0]');\n _.set(c, 'viewState.customInstance.vCpuCount', vCpuCount);\n }\n\n _.set(\n c,\n 'backingData.customInstanceTypes.memoryList',\n gceCustomInstanceBuilderService.generateValidMemoryListForVCpuCount(instanceFamily, vCpuCount),\n );\n\n if (\n _.every([\n memory,\n vCpuCount,\n !gceCustomInstanceBuilderService.memoryIsValid(instanceFamily, memory, vCpuCount, extendedMemory),\n ])\n ) {\n _.set(c, 'viewState.customInstance.memory', undefined);\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n\n _.set(\n c,\n 'backingData.customInstanceTypes.instanceFamilyList',\n gceCustomInstanceBuilderService.generateValidInstanceFamilyList(),\n );\n\n return result;\n }\n\n function configureAccelerators(command) {\n const result = { dirty: {} };\n const acceleratorTypes = GceAcceleratorService.getAvailableAccelerators(command);\n _.set(command, ['viewState', 'acceleratorTypes'], acceleratorTypes);\n result.dirty.acceleratorTypes = true;\n const chosenAccelerators = _.get(command, 'acceleratorConfigs', []);\n if (chosenAccelerators.length > 0) {\n command.acceleratorConfigs = chosenAccelerators.filter(\n (chosen) => !!acceleratorTypes.find((a) => a.name === chosen.acceleratorType),\n );\n if (command.acceleratorConfigs.length === 0) {\n delete command.acceleratorConfigs;\n }\n }\n return result;\n }\n\n // n1-standard-8 should come before n1-standard-16, so we must sort by the individual segments of the names.\n function sortInstanceTypes(instanceTypes) {\n const tokenizedInstanceTypes = _.map(instanceTypes, (instanceType) => {\n const tokens = instanceType.split('-');\n\n return {\n class: tokens[0],\n group: tokens[1],\n index: Number(tokens[2]) || 0,\n };\n });\n\n const sortedTokenizedInstanceTypes = _.sortBy(tokenizedInstanceTypes, ['class', 'group', 'index']);\n\n return _.map(sortedTokenizedInstanceTypes, (sortedTokenizedInstanceType) => {\n return (\n sortedTokenizedInstanceType.class +\n '-' +\n sortedTokenizedInstanceType.group +\n (sortedTokenizedInstanceType.index ? '-' + sortedTokenizedInstanceType.index : '')\n );\n });\n }\n\n function configureImages(command) {\n command.image = command.viewState.imageId;\n const result = { dirty: {} };\n if (command.credentials !== command.viewState.lastImageAccount) {\n command.viewState.lastImageAccount = command.credentials;\n if (!_.chain(command.backingData.allImages).find({ imageName: command.image }).value()) {\n command.image = null;\n result.dirty.imageName = true;\n }\n }\n return result;\n }\n\n function configureZones(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (command.region === null) {\n return result;\n }\n const regions = command.backingData.credentialsKeyedByAccount[command.credentials].regions;\n if (_.isArray(regions)) {\n filteredData.zones = _.find(regions, { name: command.region }).zones;\n filteredData.truncatedZones = _.takeRight(filteredData.zones.sort(), 3);\n } else {\n // TODO(duftler): Remove this once we finish deprecating the old style regions/zones in clouddriver GCE credentials.\n filteredData.zones = regions[command.region];\n }\n if (!_.chain(filteredData.zones).includes(command.zone).value()) {\n delete command.zone;\n if (!command.regional) {\n result.dirty.zone = true;\n }\n }\n return result;\n }\n\n function getHealthChecks(command) {\n const matchingHealthChecks = _.filter(command.backingData.healthChecks, { account: command.credentials });\n return getHealthCheckOptions(matchingHealthChecks);\n }\n\n function configureHealthChecks(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n\n if (command.credentials === null) {\n return result;\n }\n\n filteredData.healthChecks = getHealthChecks(command);\n\n if (\n _.has(command, 'autoHealingPolicy.healthCheck') &&\n !_.chain(filteredData.healthChecks).map('selfLink').includes(command.autoHealingPolicy.healthCheckUrl).value()\n ) {\n delete command.autoHealingPolicy.healthCheck;\n result.dirty.autoHealingPolicy = true;\n } else {\n result.dirty.autoHealingPolicy = null;\n }\n\n return result;\n }\n\n function getLoadBalancers(command) {\n return _.chain(command.backingData.loadBalancers)\n .map('accounts')\n .flattenDeep()\n .filter({ name: command.credentials })\n .map('regions')\n .flattenDeep()\n .map('loadBalancers')\n .flattenDeep()\n .filter(_.curry(isRelevantLoadBalancer)(command))\n .uniq()\n .value();\n }\n\n function isRelevantLoadBalancer(command, loadBalancer) {\n return loadBalancer.region === command.region || loadBalancer.region === 'global';\n }\n\n function configureLoadBalancerOptions(command) {\n const results = { dirty: {} };\n const current = command.loadBalancers;\n const newLoadBalancerObjects = gceLoadBalancerSetTransformer.normalizeLoadBalancerSet(\n getLoadBalancers(command),\n );\n command.backingData.filtered.loadBalancerIndex = _.keyBy(newLoadBalancerObjects, 'name');\n command.backingData.filtered.loadBalancers = _.map(newLoadBalancerObjects, 'name');\n\n if (current && command.loadBalancers) {\n command.loadBalancers = gceHttpLoadBalancerUtils.normalizeLoadBalancerNamesForAccount(\n command.loadBalancers,\n command.credentials,\n newLoadBalancerObjects,\n );\n const matched = _.intersection(command.backingData.filtered.loadBalancers, command.loadBalancers);\n const removed = _.xor(matched, command.loadBalancers);\n command.loadBalancers = matched;\n configureBackendServiceOptions(command);\n\n if (removed.length) {\n results.dirty.loadBalancers = removed;\n }\n }\n return results;\n }\n\n function configureBackendServiceOptions(command) {\n /*\n a server group has a list of backend services, but there's no mapping from l7 -> backend service\n for the server group. this will not populate the wizard perfectly,\n but it is the best we can do with the given data.\n */\n\n const backendsFromMetadata = command.backendServiceMetadata;\n const lbIndex = command.backingData.filtered.loadBalancerIndex;\n\n const backendServices = command.loadBalancers.reduce((backendServices, lbName) => {\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer(lbIndex[lbName])) {\n backendServices[lbName] = _.intersection(lbIndex[lbName].backendServices, backendsFromMetadata);\n }\n return backendServices;\n }, {});\n\n if (Object.keys(backendServices).length > 0) {\n command.backendServices = backendServices;\n }\n }\n\n function refreshLoadBalancers(command, skipCommandReconfiguration) {\n return loadBalancerReader.listLoadBalancers('gce').then(function (loadBalancers) {\n command.backingData.loadBalancers = loadBalancers;\n if (!skipCommandReconfiguration) {\n configureLoadBalancerOptions(command);\n }\n });\n }\n\n function refreshHealthChecks(command, skipCommandReconfiguration) {\n return cacheInitializer\n .refreshCache('healthChecks')\n .then(function () {\n return gceHealthCheckReader.listHealthChecks();\n })\n .then(function (healthChecks) {\n command.backingData.healthChecks = healthChecks;\n if (!skipCommandReconfiguration) {\n configureHealthChecks(command);\n }\n });\n }\n\n function configureSubnets(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (command.region === null) {\n return result;\n }\n filteredData.subnets = _.chain(command.backingData.subnets)\n .filter({ account: command.credentials, network: command.network, region: command.region })\n .map('id')\n .value();\n\n if (!_.chain(filteredData.subnets).includes(command.subnet).value()) {\n command.subnet = '';\n result.dirty.subnet = true;\n }\n return result;\n }\n\n function getSecurityGroups(command) {\n let newSecurityGroups = command.backingData.securityGroups[command.credentials] || { gce: {} };\n newSecurityGroups = _.filter(newSecurityGroups.gce.global, function (securityGroup) {\n return securityGroup.network === command.network;\n });\n return _.chain(newSecurityGroups).sortBy('name').value();\n }\n\n function getXpnHostProjectIfAny(network) {\n if (network && network.includes('/')) {\n return network.split('/')[0] + '/';\n } else {\n return '';\n }\n }\n\n function configureSecurityGroupOptions(command) {\n const results = { dirty: {} };\n const currentOptions = command.backingData.filtered.securityGroups;\n const newSecurityGroups = getSecurityGroups(command);\n if (currentOptions && command.securityGroups) {\n // not initializing - we are actually changing groups\n const currentGroupNames = command.securityGroups.map(function (groupId) {\n const match = _.chain(currentOptions).find({ id: groupId }).value();\n return match ? match.id : groupId;\n });\n const matchedGroups = command.securityGroups\n .map(function (groupId) {\n const securityGroup = _.chain(currentOptions).find({ id: groupId }).value();\n return securityGroup ? securityGroup.id : null;\n })\n .map(function (groupName) {\n return _.chain(newSecurityGroups).find({ id: groupName }).value();\n })\n .filter(function (group) {\n return group;\n });\n command.securityGroups = _.map(matchedGroups, 'id');\n const removed = _.xor(currentGroupNames, command.securityGroups);\n if (removed.length) {\n results.dirty.securityGroups = removed;\n }\n }\n\n // Only include explicit firewall options in the pulldown list.\n command.backingData.filtered.securityGroups = _.filter(newSecurityGroups, function (securityGroup) {\n return !_.isEmpty(securityGroup.targetTags);\n });\n\n // Identify implicit firewalls so they can be optionally listed in a read-only state.\n command.implicitSecurityGroups = _.filter(newSecurityGroups, function (securityGroup) {\n return _.isEmpty(securityGroup.targetTags);\n });\n\n // Only include explicitly-selected firewalls in the body of the command.\n const xpnHostProject = getXpnHostProjectIfAny(command.network);\n const decoratedSecurityGroups = _.map(command.securityGroups, (sg) =>\n !sg.startsWith(xpnHostProject) ? xpnHostProject + sg : sg,\n );\n command.securityGroups = _.difference(decoratedSecurityGroups, _.map(command.implicitSecurityGroups, 'id'));\n\n return results;\n }\n\n function refreshSecurityGroups(command, skipCommandReconfiguration) {\n return cacheInitializer.refreshCache('securityGroups').then(function () {\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n command.backingData.securityGroups = securityGroups;\n if (!skipCommandReconfiguration) {\n configureSecurityGroupOptions(command);\n }\n });\n });\n }\n\n function getNetworkNames(command) {\n return _.map(_.filter(command.backingData.networks, { account: command.credentials }), 'id');\n }\n\n function refreshNetworks(command) {\n NetworkReader.listNetworksByProvider('gce').then(function (gceNetworks) {\n command.backingData.networks = gceNetworks;\n });\n }\n\n function refreshInstanceTypes(command) {\n return cacheInitializer.refreshCache('instanceTypes').then(function () {\n return gceInstanceTypeService.getAllTypesByRegion().then(function (instanceTypes) {\n command.backingData.instanceTypes = instanceTypes;\n configureInstanceTypes(command);\n });\n });\n }\n\n function attachEventHandlers(cmd) {\n cmd.regionalChanged = function regionalChanged(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n const defaults = GCEProviderSettings.defaults;\n if (command.regional) {\n command.zone = null;\n configureDistributionPolicyTargetShape(command);\n } else if (!command.zone) {\n if (command.region === defaults.region) {\n command.zone = defaults.zone;\n } else {\n command.zone = filteredData.zones[0];\n }\n\n angular.extend(result.dirty, configureZones(command).dirty);\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n return result;\n };\n\n cmd.regionChanged = function regionChanged(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n angular.extend(result.dirty, configureSubnets(command).dirty);\n if (command.region) {\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n angular.extend(result.dirty, configureZones(command).dirty);\n angular.extend(result.dirty, configureCpuPlatforms(command).dirty);\n // TODO: Internal Load Balancers also need to be filtered by network.\n angular.extend(result.dirty, configureLoadBalancerOptions(command).dirty);\n angular.extend(result.dirty, configureImages(command).dirty);\n } else {\n filteredData.zones = null;\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n return result;\n };\n\n cmd.credentialsChanged = function credentialsChanged(command) {\n const result = { dirty: {} };\n const backingData = command.backingData;\n if (command.credentials) {\n const regions = backingData.credentialsKeyedByAccount[command.credentials].regions;\n if (_.isArray(regions)) {\n backingData.filtered.regions = _.map(regions, 'name');\n } else {\n // TODO(duftler): Remove this once we finish deprecating the old style regions/zones in clouddriver GCE credentials.\n backingData.filtered.regions = _.keys(regions);\n }\n if (!backingData.filtered.regions.includes(command.region)) {\n command.region = null;\n result.dirty.region = true;\n } else {\n angular.extend(result.dirty, command.regionChanged(command).dirty);\n }\n\n backingData.filtered.networks = getNetworkNames(command);\n if (!backingData.filtered.networks.includes(command.network)) {\n command.network = null;\n result.dirty.network = true;\n } else {\n angular.extend(result.dirty, command.networkChanged(command).dirty);\n }\n\n angular.extend(result.dirty, configureHealthChecks(command).dirty);\n angular.extend(result.dirty, configureInstanceTypes(command).dirty);\n\n configureDistributionPolicyTargetShape(command);\n } else {\n command.region = null;\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n\n return result;\n };\n\n cmd.networkChanged = function networkChanged(command) {\n const result = { dirty: {} };\n\n command.viewState.autoCreateSubnets = _.chain(command.backingData.networks)\n .filter({ account: command.credentials, id: command.network })\n .map('autoCreateSubnets')\n .head()\n .value();\n\n command.viewState.subnets = _.chain(command.backingData.networks)\n .filter({ account: command.credentials, id: command.network })\n .map('subnets')\n .head()\n .value();\n\n angular.extend(result.dirty, configureSubnets(command).dirty);\n angular.extend(result.dirty, configureSecurityGroupOptions(command).dirty);\n\n // TODO: Internal Load Balancers also need to be filtered by network.\n\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n\n return result;\n };\n\n cmd.zoneChanged = function zoneChanged(command) {\n const result = { dirty: {} };\n if (command.zone === undefined && !command.regional) {\n result.dirty.zone = true;\n }\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n angular.extend(command.viewState.dirty, configureInstanceTypes(command).dirty);\n angular.extend(command.viewState.dirty, configureCpuPlatforms(command).dirty);\n angular.extend(command.viewState.dirty, configureAccelerators(command).dirty);\n return result;\n };\n\n cmd.selectZonesChanged = function selectZonesChanged(command) {\n const result = { dirty: {} };\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(command.viewState.dirty, result.dirty);\n angular.extend(command.viewState.dirty, configureAccelerators(command).dirty);\n return result;\n };\n\n cmd.customInstanceChanged = function customInstanceChanged(command) {\n const result = { dirty: {} };\n\n command.viewState.dirty = command.viewState.dirty || {};\n angular.extend(result, command.viewState.dirty, configureCustomInstanceTypes(command).dirty);\n\n return result;\n };\n }\n\n return {\n configureCommand,\n configureInstanceTypes,\n configureImages,\n configureZones,\n configureSubnets,\n configureLoadBalancerOptions,\n refreshLoadBalancers,\n refreshSecurityGroups,\n refreshInstanceTypes,\n refreshHealthChecks,\n };\n },\n ]);\n","import { module } from 'angular';\n\nimport { get, isEmpty } from 'lodash';\nimport React from 'react';\nimport type { Option } from 'react-select';\nimport Select from 'react-select';\nimport { react2angular } from 'react2angular';\n\nimport { HelpField, withErrorBoundary } from '@spinnaker/core';\n\nimport type { IGceAcceleratorType } from './gceAccelerator.service';\n\ninterface IGceAcceleratorConfig {\n acceleratorType: string;\n acceleratorCount: number;\n}\n\nexport interface IGceAcceleratorConfigurerProps {\n acceleratorConfigs: IGceAcceleratorConfig[];\n availableAccelerators: IGceAcceleratorType[];\n regional: boolean;\n setAcceleratorConfigs: (configs: IGceAcceleratorConfig[]) => void;\n zone: string;\n}\n\nexport function GceAcceleratorConfigurer({\n acceleratorConfigs = [],\n availableAccelerators = [],\n regional,\n setAcceleratorConfigs,\n zone,\n}: IGceAcceleratorConfigurerProps) {\n const addAccelerator = (): void => {\n if (isEmpty(availableAccelerators)) {\n return;\n }\n setAcceleratorConfigs(\n acceleratorConfigs.concat([\n {\n acceleratorType: availableAccelerators[0].name,\n acceleratorCount: 1,\n },\n ]),\n );\n };\n\n const removeAccelerator = (indexToRemove: number): void => {\n setAcceleratorConfigs(\n acceleratorConfigs.filter((_config, index) => {\n return indexToRemove !== index;\n }),\n );\n };\n\n const getTypeOptions = (): Array<Option<string>> => {\n return availableAccelerators.map(({ description, name }) => {\n return {\n label: description,\n value: name,\n };\n });\n };\n\n const getAvailableCardCounts = (acceleratorType: string): number[] => {\n const acceleratorConfig = availableAccelerators.find(({ name }) => name === acceleratorType);\n return get(acceleratorConfig, 'availableCardCounts', []);\n };\n\n const getCountOptions = (acceleratorType: string): Array<Option<number>> => {\n return getAvailableCardCounts(acceleratorType).map((count) => ({\n label: count.toString(),\n value: count,\n }));\n };\n\n const getNearestCount = (type: string, currentCount: number): number => {\n const availableCounts = getAvailableCardCounts(type);\n if (availableCounts.includes(currentCount)) {\n return currentCount;\n }\n return availableCounts.reduce((nearest, count) => {\n if (count > currentCount) {\n return nearest;\n }\n return count;\n }, 1);\n };\n\n const onTypeChange = (indexToUpdate: number, type: string): void => {\n setAcceleratorConfigs(\n acceleratorConfigs.map((config, index) => {\n if (indexToUpdate !== index) {\n return config;\n }\n return {\n acceleratorType: type,\n acceleratorCount: getNearestCount(type, config.acceleratorCount),\n };\n }),\n );\n };\n\n const onCountChange = (indexToUpdate: number, count: number) => {\n setAcceleratorConfigs(\n acceleratorConfigs.map((config, index) => {\n if (indexToUpdate !== index) {\n return config;\n }\n return {\n ...config,\n acceleratorCount: count,\n };\n }),\n );\n };\n\n return (\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n Accelerators <HelpField id=\"gce.serverGroup.accelerator\" />\n </div>\n <table className=\"table table-condensed packed tags\">\n <thead>\n <tr>\n <th style={{ width: '75%' }}>Type</th>\n <th style={{ width: '15%' }}>Count</th>\n <th />\n </tr>\n </thead>\n <tbody>\n {acceleratorConfigs.map(({ acceleratorType, acceleratorCount }, i) => (\n <tr key={i}>\n <td>\n <Select\n clearable={false}\n onChange={(option: Option<string>) => onTypeChange(i, option.value)}\n options={getTypeOptions()}\n value={acceleratorType}\n />\n </td>\n <td>\n <Select\n clearable={false}\n onChange={(option: Option<number>) => onCountChange(i, option.value)}\n options={getCountOptions(acceleratorType)}\n value={acceleratorCount}\n />\n </td>\n <td>\n <button className=\"btn btn-link\" onClick={() => removeAccelerator(i)}>\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n ))}\n {!isEmpty(acceleratorConfigs) && (\n <tr>\n <td colSpan={3}>\n Adding Accelerators places constraints on the instances that you can deploy. See\n <a href=\"https://cloud.google.com/compute/docs/gpus/#restrictions\" target=\"_blank\">\n {' '}\n the complete list of these restrictions\n </a>{' '}\n for more information.\n </td>\n </tr>\n )}\n {!isEmpty(availableAccelerators) && (\n <tr>\n <td colSpan={3}>\n <button className=\"btn btn-block btn-sm add-new\" onClick={addAccelerator}>\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add Accelerator\n </button>\n </td>\n </tr>\n )}\n {isEmpty(availableAccelerators) && !regional && !zone && (\n <tr>\n <td colSpan={3}>\n A zone must be selected to configure accelerators. Please note: the set of available accelerator types\n are limited by zone. See{' '}\n <a href=\"https://cloud.google.com/compute/docs/gpus/#gpus-list\" target=\"_blank\">\n the complete list of types in each zone\n </a>{' '}\n for more information.\n </td>\n </tr>\n )}\n {isEmpty(availableAccelerators) && !regional && zone && (\n <tr>\n <td colSpan={3}>There are no accelerators available in the currently selected zone.</td>\n </tr>\n )}\n {isEmpty(availableAccelerators) && regional && (\n <tr>\n <td colSpan={3}>\n There are no accelerators available in all of the currently selected zone(s). Please explicitly select\n only zones that each support the accelerators you would like to configure. See{' '}\n <a href=\"https://cloud.google.com/compute/docs/gpus/#gpus-list\" target=\"_blank\">\n the complete list of types in each zone\n </a>{' '}\n for more information.\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n );\n}\n\nexport const GCE_ACCELERATOR_CONFIGURER = 'spinnaker.gce.accelerator.component';\nmodule(GCE_ACCELERATOR_CONFIGURER, []).component(\n 'gceAcceleratorConfigurer',\n react2angular(withErrorBoundary(GceAcceleratorConfigurer, 'gceAcceleratorConfigurer'), [\n 'acceleratorConfigs',\n 'availableAccelerators',\n 'regional',\n 'setAcceleratorConfigs',\n 'zone',\n ]),\n);\n","import { module } from 'angular';\nimport UI_SELECT from 'ui-select';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from '../securityGroups/tagManager.service';\n\n('use strict');\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.advancedSettings.selector.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE, [\n UI_SELECT,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n])\n .directive('gceServerGroupAdvancedSettingsSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./advancedSettings.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: 'gceServerGroupAdvancedSettingsSelectorCtrl',\n };\n })\n .controller('gceServerGroupAdvancedSettingsSelectorCtrl', [\n '$scope',\n 'gceTagManager',\n function ($scope, gceTagManager) {\n this.addTag = () => {\n this.command.tags.push({});\n };\n\n this.removeTag = (index) => {\n this.command.tags.splice(index, 1);\n gceTagManager.updateSelectedTags();\n };\n\n this.setDisks = (disks) => {\n this.command.disks = disks;\n };\n\n this.inferSelectedSecurityGroupFromTag = gceTagManager.inferSelectedSecurityGroupFromTag;\n this.showToolTip = gceTagManager.showToolTip;\n this.getToolTipContent = gceTagManager.getToolTipContent;\n\n this.setPreemptible = () => {\n if (this.command.preemptible) {\n this.command.automaticRestart = false;\n this.command.onHostMaintenance = 'TERMINATE';\n } else {\n this.command.automaticRestart = true;\n this.command.onHostMaintenance = 'MIGRATE';\n }\n };\n\n this.setEnableVtpm = () => {\n if (!this.command.enableVtpm) {\n // Integrity monitoring requires vTPM to be enabled.\n this.command.enableIntegrityMonitoring = false;\n }\n };\n\n this.setAcceleratorConfigs = (configs) => {\n $scope.$apply(() => {\n this.command.acceleratorConfigs = configs;\n });\n };\n },\n ]);\n","import type { IComponentController, IComponentOptions, IScope } from 'angular';\nimport { module } from 'angular';\nimport { without } from 'lodash';\n\ninterface IGceDisk {\n type: string;\n sizeGb: number;\n sourceImage?: string;\n}\n\nclass GceDiskConfigurerController implements IComponentController {\n public localSSDCount: number;\n public persistentDisks: IGceDisk[];\n public isDefault: boolean;\n\n // From component bindings.\n public command: any;\n public disks: IGceDisk[];\n private updateDisks: (arg: { disks: IGceDisk[] }) => void;\n\n public static $inject = ['$scope'];\n constructor(public $scope: IScope) {}\n\n public $onInit(): void {\n this.setLocalSSDCount();\n this.setPersistentDisks();\n\n if (this.getLocalSSDDisks().length && !this.command?.viewState?.instanceTypeDetails?.storage?.localSSDSupported) {\n this.updateDisks({ disks: this.sortDisks(this.getPersistentDisks()) });\n }\n\n this.isDefault = !!this.command?.viewState?.instanceTypeDetails?.storage?.isDefault;\n }\n\n public $onChanges(): void {\n this.$onInit();\n }\n\n public handleLocalSSDCountChange(): void {\n // Handles invalid input.\n if (this.localSSDCount === undefined) {\n return;\n }\n\n let disks = this.getPersistentDisks();\n for (let i = 0; i < this.localSSDCount; i++) {\n disks = disks.concat([{ type: 'local-ssd', sizeGb: 375 }]);\n }\n\n disks = this.sortDisks(disks);\n this.updateDisks({ disks });\n }\n\n public handlePersistentDiskChange(): void {\n let disks = this.persistentDisks.concat(this.getLocalSSDDisks());\n disks = this.sortDisks(disks);\n this.updateDisks({ disks });\n }\n\n public handleImageChange = (imageName: string, target: IGceDisk) => {\n // called from a React component\n this.$scope.$apply(() => {\n target.sourceImage = imageName;\n this.handlePersistentDiskChange();\n });\n };\n\n public addPersistentDisk(): void {\n this.persistentDisks = this.persistentDisks.concat([{ type: 'pd-ssd', sizeGb: 10, sourceImage: null }]);\n this.handlePersistentDiskChange();\n }\n\n public removePersistentDisk(index: number): void {\n this.persistentDisks.splice(index, 1);\n this.handlePersistentDiskChange();\n }\n\n private setPersistentDisks(): void {\n this.persistentDisks = this.getPersistentDisks();\n }\n\n private setLocalSSDCount(): void {\n this.localSSDCount = this.getLocalSSDDisks().length;\n }\n\n private sortDisks(disks: IGceDisk[]): IGceDisk[] {\n const diskWithoutImage = disks.find(\n (disk) => (disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-')) && disk.sourceImage === undefined,\n );\n return [diskWithoutImage].concat(without(disks, diskWithoutImage));\n }\n\n private getLocalSSDDisks(): IGceDisk[] {\n return (this.command.disks || []).filter((disk: IGceDisk) => disk.type === 'local-ssd');\n }\n\n private getPersistentDisks(): IGceDisk[] {\n return (this.command.disks || []).filter(\n (disk: IGceDisk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'),\n );\n }\n}\n\nconst gceDiskConfigurer: IComponentOptions = {\n controller: GceDiskConfigurerController,\n bindings: { command: '<', disks: '<', updateDisks: '&' },\n template: `\n <ng-form name=\"diskConfigurer\">\n <div class=\"form-group\">\n <div class=\"col-md-5 sm-label-right\">\n <b>Number of Local SSD Disks</b>\n <help-field key=\"gce.instance.storage.localSSD\"></help-field>\n </div>\n <div class=\"col-md-2\">\n <input type=\"number\"\n class=\"form-control input-sm\"\n ng-model=\"$ctrl.localSSDCount\"\n ng-change=\"$ctrl.handleLocalSSDCountChange()\"\n required\n min=\"0\"\n max=\"{{$ctrl.command.viewState.instanceTypeDetails.storage.localSSDSupported ? 8 : 0}}\"\n ng-disabled=\"!$ctrl.command.viewState.instanceTypeDetails.storage.localSSDSupported\"/>\n </div>\n </div>\n <div class=\"form-group\">\n <div class=\"sm-label-left\" style=\"margin-bottom: 5px;\">Persistent Disks\n <span class=\"glyphicon glyphicon-warning-sign\"\n style=\"color: #EEBB3C;\"\n ng-if=\"$ctrl.isDefault && !diskConfigurer.$dirty\"\n uib-tooltip=\"This instance type does not have an explicitly configured persistent disk option and is using the\n default disk storage specified in settings.js.\"></span>\n </div>\n <table class=\"table table-condensed packed tags\">\n <thead>\n <tr>\n <th style=\"width: 25%;\">Type</th>\n <th>Size (GB)</th>\n <th style=\"width: 50%;\">Image</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat=\"disk in $ctrl.persistentDisks\">\n <td>\n <ui-select ng-model=\"disk.type\" class=\"form-control input-sm\" on-select=\"$ctrl.handlePersistentDiskChange()\" required>\n <ui-select-match placeholder=\"Select...\">{{$select.selected}}</ui-select-match>\n <ui-select-choices repeat=\"persistentDiskType in $ctrl.command.backingData.persistentDiskTypes | filter: $select.search\">\n <span ng-bind-html=\"persistentDiskType | highlight: $select.search\"></span>\n </ui-select-choices>\n </ui-select>\n </td>\n <td>\n <input type=\"number\"\n class=\"form-control input-sm\"\n ng-model=\"disk.sizeGb\"\n ng-change=\"$ctrl.handlePersistentDiskChange()\"\n required\n min=\"10\"/>\n </td>\n <td>\n <div ng-if=\"$index === 0\">\n <p class=\"small\" style=\"margin: 0;\" ng-if=\"$ctrl.command.viewState.mode === 'create' || $ctrl.command.viewState.mode === 'clone'\">\n This disk will use the image selected at the top of this dialogue.\n </p>\n <p class=\"small\" style=\"margin: 0;\" ng-if=\"$ctrl.command.viewState.mode === 'createPipeline' || $ctrl.command.viewState.mode === 'editPipeline'\">\n This disk will use the image inferred from this pipeline's execution context.\n </p>\n </div>\n <gce-image-select\n ng-if=\"$index > 0\"\n available-images=\"$ctrl.command.backingData.allImages\"\n selected-image=\"disk.sourceImage\"\n select-image=\"$ctrl.handleImageChange\"\n target=\"disk\"\n ></gce-image-select>\n </td>\n <td ng-if=\"$index > 0\">\n <a class=\"btn btn-link sm-label\" style=\"margin-top: 0;\" ng-click=\"$ctrl.removePersistentDisk($index)\">\n <span class=\"glyphicon glyphicon-trash\"></span>\n </a>\n </td>\n </tr>\n </tbody>\n <tfoot>\n <tr>\n <td colspan=\"4\">\n <button class=\"btn btn-block btn-sm add-new\" ng-click=\"$ctrl.addPersistentDisk()\">\n <span class=\"glyphicon glyphicon-plus-sign\"></span> Add New Persistent Disk\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n </ng-form>`,\n};\n\nexport const GCE_DISK_CONFIGURER = 'spinnaker.gce.diskConfigurer.component';\nmodule(GCE_DISK_CONFIGURER, []).component('gceDiskConfigurer', gceDiskConfigurer);\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\nimport { set } from 'lodash';\n\nimport type { IGceAutoHealingPolicy } from '../../../../domain/autoHealingPolicy';\nimport type { IGceHealthCheckOption } from '../../../../healthCheck/healthCheckUtils';\nimport { parseHealthCheckUrl } from '../../../../healthCheck/healthCheckUtils';\n\nclass GceAutoHealingPolicySelector implements IController {\n public healthChecks: string[];\n public autoHealingPolicy: IGceAutoHealingPolicy;\n public enabled: boolean;\n public viewState: { maxUnavailableMetric: 'percent' | 'fixed' };\n private setAutoHealingPolicy: Function;\n\n public $onInit(): void {\n if (this.autoHealingPolicy && this.autoHealingPolicy.maxUnavailable) {\n if (typeof this.autoHealingPolicy.maxUnavailable.fixed === 'number') {\n this.viewState = { maxUnavailableMetric: 'fixed' };\n } else if (typeof this.autoHealingPolicy.maxUnavailable.percent === 'number') {\n this.viewState = { maxUnavailableMetric: 'percent' };\n }\n }\n\n if (!this.autoHealingPolicy) {\n this.setAutoHealingPolicy({ autoHealingPolicy: { initialDelaySec: 300 } });\n }\n }\n\n public $onDestroy(): void {\n this.setAutoHealingPolicy({ autoHealingPolicy: null });\n }\n\n public manageMaxUnavailableMetric(selectedMetric: string): void {\n if (!selectedMetric) {\n // Clouddriver deletes maxUnavailable if maxUnavailable is an empty object.\n this.autoHealingPolicy.maxUnavailable = {};\n } else {\n const toDeleteKey = selectedMetric === 'percent' ? 'fixed' : 'percent';\n set(this.autoHealingPolicy, ['maxUnavailable', toDeleteKey], undefined);\n }\n }\n\n public onHealthCheckChange(_healthCheck: IGceHealthCheckOption, healthCheckUrl: string) {\n if (healthCheckUrl) {\n const { healthCheckName, healthCheckKind } = parseHealthCheckUrl(healthCheckUrl);\n this.autoHealingPolicy.healthCheck = healthCheckName;\n this.autoHealingPolicy.healthCheckKind = healthCheckKind;\n }\n }\n}\n\nconst gceAutoHealingPolicySelectorComponent: IComponentOptions = {\n bindings: {\n onHealthCheckRefresh: '&',\n setAutoHealingPolicy: '&',\n healthChecks: '<',\n autoHealingPolicy: '<',\n enabled: '<',\n labelColumns: '@?',\n },\n templateUrl: require('./autoHealingPolicySelector.component.html'),\n controller: GceAutoHealingPolicySelector,\n};\n\nexport const GCE_AUTOHEALING_POLICY_SELECTOR = 'spinnaker.gce.autoHealingPolicy.selector.component';\nmodule(GCE_AUTOHEALING_POLICY_SELECTOR, []).component(\n 'gceAutoHealingPolicySelector',\n gceAutoHealingPolicySelectorComponent,\n);\n","import { module } from 'angular';\nimport { cloneDeep } from 'lodash';\n\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/basicSettings/basicSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/metricSettings/metricSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT } from '../../../../autoscalingPolicy/components/scalingSchedules/scalingSchedules.component';\n\nimport './autoScalingPolicySelector.less';\n\nconst gceAutoScalingPolicySelectorComponent = {\n bindings: {\n policy: '<',\n enabled: '<',\n setAutoScalingPolicy: '&',\n autoscalingPolicy: '<',\n },\n templateUrl: require('./autoScalingPolicySelector.component.html'),\n controller: 'gceUpsertAutoscalingPolicyCtrl',\n};\n\nexport const GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT = 'spinnaker.gce.autoScalingPolicy.selector.component';\nmodule(GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT, [\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT,\n])\n .controller('gceUpsertAutoscalingPolicyCtrl', [\n '$scope',\n function ($scope) {\n var vm = this;\n this.$onInit = function () {\n this.policy = cloneDeep({});\n this.setAutoScalingPolicy({ autoscalingPolicy: this.policy });\n\n this.updatePolicy = (updatedPolicy) => {\n $scope.$applyAsync(() => {\n this.policy = updatedPolicy;\n this.setAutoScalingPolicy({ autoscalingPolicy: this.policy });\n });\n };\n };\n },\n ])\n .component('gceAutoScalingPolicySelectorComponent', gceAutoScalingPolicySelectorComponent);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT =\n 'spinnaker.deck.gce.serverGroup.configure.advancedCapacitySelector.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT, []).component(\n 'gceServerGroupAdvancedCapacitySelector',\n {\n bindings: {\n command: '=',\n },\n templateUrl: require('./advancedCapacitySelector.component.html'),\n },\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT =\n 'spinnaker.google.serverGroup.configure.wizard.simpleCapacity.selector.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT, [])\n .component('gceServerGroupSimpleCapacitySelector', {\n templateUrl: require('./simpleCapacitySelector.component.html'),\n bindings: {\n command: '=',\n setSimpleCapacity: '=',\n },\n controller: 'gceServerGroupSimpleCapacitySelectorCtrl',\n })\n .controller('gceServerGroupSimpleCapacitySelectorCtrl', function () {\n this.setMinMax = (newVal) => {\n this.command.capacity.min = newVal;\n this.command.capacity.max = newVal;\n };\n });\n","import React from 'react';\nimport type { Option } from 'react-select';\nimport Select from 'react-select';\n\nimport { CheckboxInput, HelpField } from '@spinnaker/core';\nimport './customInstanceConfigurer.component.less';\n\nexport interface ICustomInstanceConfig {\n vCpuCount: number;\n memory: number;\n instanceFamily: string;\n extendedMemory: boolean;\n}\n\nexport interface ICustomInstanceConfigurerProps {\n vCpuList: number[];\n memoryList: number[];\n instanceFamilyList: string[];\n selectedVCpuCount: number;\n selectedMemory: number;\n selectedInstanceFamily: string;\n selectedExtendedMemory: boolean;\n onChange: (config: ICustomInstanceConfig) => void;\n}\n\nexport class CustomInstanceConfigurer extends React.Component<ICustomInstanceConfigurerProps> {\n public render() {\n const instanceFamilyOptions: Option[] = (this.props.instanceFamilyList || []).map((instanceFamily) => ({\n label: instanceFamily,\n value: instanceFamily,\n }));\n const vCpuOptions: Option[] = (this.props.vCpuList || []).map((vCpu) => ({ label: vCpu + '', value: vCpu }));\n const memoryOptions: Option[] = (this.props.memoryList || []).map((memory) => ({\n label: memory + '',\n value: memory,\n }));\n const selectedVCpuCountLabel = this.props.selectedVCpuCount ? this.props.selectedVCpuCount + '' : null;\n const selectedMemoryLabel = this.props.selectedMemory ? this.props.selectedMemory + '' : null;\n const selectedInstanceFamilyLabel = this.props.selectedInstanceFamily ? this.props.selectedInstanceFamily : null;\n\n return (\n <div>\n <div className=\"row\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Family </b>\n </div>\n <div className=\"col-md-3\">\n <Select\n options={instanceFamilyOptions}\n clearable={false}\n value={{ label: selectedInstanceFamilyLabel, value: this.props.selectedInstanceFamily }}\n onChange={this.handleInstanceFamilyChange}\n />\n </div>\n </div>\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Cores </b>\n <HelpField id=\"gce.instance.customInstance.cores\" />\n </div>\n <div className=\"col-md-3\">\n <Select\n options={vCpuOptions}\n clearable={false}\n value={{ label: selectedVCpuCountLabel, value: this.props.selectedVCpuCount }}\n onChange={this.handleVCpuChange}\n />\n </div>\n </div>\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Memory (Gb) </b>\n <HelpField id=\"gce.instance.customInstance.memory\" />\n </div>\n <div className=\"col-md-3\">\n {this.props.selectedExtendedMemory ? (\n <input\n type=\"number\"\n name=\"memory\"\n className=\"form-control\"\n value={this.props.selectedMemory}\n onChange={(event) => this.handleMemoryChangeCustom(event.target.value)}\n />\n ) : (\n <Select\n options={memoryOptions}\n clearable={false}\n value={{ label: selectedMemoryLabel, value: this.props.selectedMemory }}\n onChange={this.handleMemoryChange}\n />\n )}\n </div>\n </div>\n {this.props.selectedInstanceFamily !== 'E2' ? (\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\"></div>\n <div className=\"col-md-3\">\n <span className=\"gce-instance-build-custom-extended-memory-checkbox\">\n <CheckboxInput\n name=\"extendedMemory\"\n text=\"Extended Memory\"\n checked={this.props.selectedExtendedMemory}\n onChange={(event: { target: { checked: boolean } }) => {\n this.handleExtendedMemory(event.target.checked);\n }}\n />\n <div className=\"gce-instance-build-custom-extended-memory-checkbox-helptext\">\n <HelpField id=\"gce.instance.customInstance.extendedmemory\" />\n </div>\n </span>\n </div>\n </div>\n ) : null}\n </div>\n );\n }\n\n private handleVCpuChange = (option: Option) => {\n const value = (option ? option.value : null) as number;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: value,\n memory: this.props.selectedMemory,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleMemoryChange = (option: Option) => {\n const value = (option ? option.value : null) as number;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: value,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleInstanceFamilyChange = (option: Option) => {\n const value = (option ? option.value : null) as string;\n this.props.onChange({\n instanceFamily: value,\n vCpuCount: this.props.selectedVCpuCount,\n memory: this.props.selectedMemory,\n extendedMemory: value === 'E2' ? false : this.props.selectedExtendedMemory,\n });\n };\n\n private handleMemoryChangeCustom = (val: string) => {\n const value = +val;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: value,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleExtendedMemory = (checked: boolean) => {\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: this.props.selectedMemory,\n extendedMemory: checked,\n });\n };\n}\n","import { module } from 'angular';\nimport { react2angular } from 'react2angular';\n\nimport { withErrorBoundary } from '@spinnaker/core';\n\nimport { CustomInstanceConfigurer } from './CustomInstanceConfigurer';\n\nexport const GCE_CUSTOM_INSTANCE_CONFIGURER = 'spinnaker.gce.customInstanceConfigurer';\nmodule(GCE_CUSTOM_INSTANCE_CONFIGURER, []).component(\n 'gceCustomInstanceConfigurer',\n react2angular(withErrorBoundary(CustomInstanceConfigurer, 'gceCustomInstanceConfigurer'), [\n 'vCpuList',\n 'instanceFamilyList',\n 'memoryList',\n 'selectedVCpuCount',\n 'selectedMemory',\n 'selectedInstanceFamily',\n 'selectedExtendedMemory',\n 'onChange',\n ]),\n);\n","'use strict';\n\nimport { module } from 'angular';\n\n// TODO(dpeach): this approach is unmaintainable because we\n// have to intercept ui-select event emitters to make it work.\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT =\n 'spinnaker.deck.gce.backendServiceSelector.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT, []).component(\n 'gceBackendServiceSelector',\n {\n bindings: {\n command: '=',\n loadBalancerName: '=',\n },\n templateUrl: require('./backendServiceSelector.component.html'),\n controller: [\n '$scope',\n function ($scope) {\n $scope.$on('$destroy', () => {\n if (this.command.backendServices) {\n delete this.command.backendServices[this.loadBalancerName];\n }\n });\n\n $scope.$on('uis:select', function (event) {\n event.preventDefault();\n });\n },\n ],\n },\n);\n","import * as angular from 'angular';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT } from './backendServiceSelector.component';\n\n('use strict');\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT =\n 'spinnaker.deck.gce.elSevenOptionsGenerator.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT, [\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT,\n ])\n .directive('gceElSevenOptionsGenerator', [\n '$compile',\n function ($compile) {\n const template = `<gce-backend-service-selector load-balancer-name=\"loadBalancerName\" command=\"command\">\n </gce-backend-service-selector>`;\n\n return {\n restrict: 'E',\n scope: {\n command: '=',\n loadBalancerName: '@',\n },\n link: function (scope, element) {\n const compiledTemplate = $compile(template)(scope);\n\n // Look up DOM to find container for selected load balancer.\n const listItem = angular.element(element).closest('.ui-select-match-item');\n\n // Drop service selector in between load balancers.\n listItem.after(compiledTemplate);\n\n scope.$on('$destroy', () => {\n // Remove selector if load balancer is removed.\n listItem.next().remove();\n });\n },\n };\n },\n ]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT } from './elSevenOptions/elSevenOptionsGenerator.component';\nimport { GCE_HTTP_LOAD_BALANCER_UTILS } from '../../../../loadBalancer/httpLoadBalancerUtils.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE } from '../../serverGroupConfiguration.service';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.loadBalancers.selector.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE, [\n GCE_HTTP_LOAD_BALANCER_UTILS,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT,\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE,\n ])\n .directive('gceServerGroupLoadBalancerSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./loadBalancerSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: 'gceServerGroupLoadBalancerSelectorCtrl',\n };\n })\n .controller('gceServerGroupLoadBalancerSelectorCtrl', [\n 'gceHttpLoadBalancerUtils',\n function (gceHttpLoadBalancerUtils) {\n this.showLoadBalancingPolicy = () => {\n if (_.has(this, 'command.backingData.filtered.loadBalancerIndex')) {\n const index = this.command.backingData.filtered.loadBalancerIndex;\n const selected = this.command.loadBalancers;\n\n return (\n angular.isDefined(selected) &&\n _.some(selected, (s) => {\n return (\n index[s].loadBalancerType === 'HTTP' ||\n index[s].loadBalancerType === 'INTERNAL_MANAGED' ||\n index[s].loadBalancerType === 'SSL' ||\n index[s].loadBalancerType === 'TCP'\n );\n })\n );\n }\n };\n\n this.isHttpLoadBalancer = (lb) => gceHttpLoadBalancerUtils.isHttpLoadBalancer(lb);\n },\n ]);\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\nimport { chain, get, has, intersection, set, without } from 'lodash';\n\nimport type { IGceBackendService, INamedPort } from '../../../../domain';\n\nimport './loadBalancingPolicySelector.component.less';\n\nclass GceLoadBalancingPolicySelectorController implements IController {\n public maxPort = 65535;\n public command: any;\n [key: string]: any;\n public globalBackendServices: IGceBackendService[];\n\n public static $inject = ['gceBackendServiceReader'];\n constructor(private gceBackendServiceReader: any) {}\n\n public setModel(propertyName: string, viewValue: number): void {\n set(this, propertyName, viewValue / 100);\n }\n\n public setView(propertyName: string, modelValue: number): void {\n this[propertyName] = this.decimalToPercent(modelValue);\n }\n\n public onBalancingModeChange(mode: string): void {\n const keys: string[] = ['maxUtilization', 'maxRatePerInstance', 'maxConnectionsPerInstance'];\n let toDelete: string[] = [];\n switch (mode) {\n case 'RATE':\n toDelete = without(keys, 'maxRatePerInstance');\n break;\n case 'UTILIZATION':\n toDelete = without(keys, 'maxUtilization');\n break;\n case 'CONNECTION':\n toDelete = without(keys, 'maxConnectionsPerInstance');\n break;\n default:\n break;\n }\n\n toDelete.forEach((key) => delete this.command.loadBalancingPolicy[key]);\n }\n\n public getBalancingModes(): string[] {\n let balancingModes: string[] = [];\n /*\n * Three cases:\n * - If we have only HTTP(S) load balancers, our balancing mode can be RATE or UTILIZATION.\n * - If we have only SSL/TCP load balancers, our balancing mode can be CONNECTION or UTILIZATION.\n * - If we have both, only UTILIZATION.\n * */\n if (has(this, 'command.backingData.filtered.loadBalancerIndex')) {\n const index = this.command.backingData.filtered.loadBalancerIndex;\n const selected = this.command.loadBalancers;\n\n const hasSsl = selected.find((loadBalancer: any) => get(index[loadBalancer], 'loadBalancerType') === 'SSL');\n const hasTcp = selected.find((loadBalancer: any) => get(index[loadBalancer], 'loadBalancerType') === 'TCP');\n const hasHttp =\n selected.find((loadBalancer: any) => get(index[loadBalancer], 'loadBalancerType') === 'HTTP') ||\n selected.find((loadBalancer: any) => get(index[loadBalancer], 'loadBalancerType') === 'HTTP2') ||\n selected.find((loadBalancer: any) => get(index[loadBalancer], 'loadBalancerType') === 'GRPC');\n if ((hasSsl || hasTcp) && hasHttp) {\n balancingModes = ['UTILIZATION'];\n } else if (hasSsl || hasTcp) {\n balancingModes = ['CONNECTION', 'UTILIZATION'];\n } else {\n balancingModes = ['RATE', 'UTILIZATION'];\n }\n }\n\n if (!balancingModes.includes(get(this.command, 'loadBalancingPolicy.balancingMode') as string)) {\n set(this.command, 'loadBalancingPolicy.balancingMode', balancingModes[0]);\n }\n return balancingModes;\n }\n\n public $onInit(): void {\n this.gceBackendServiceReader.listBackendServices('globalBackendService').then((services: IGceBackendService[]) => {\n this.globalBackendServices = services;\n });\n }\n\n public $onDestroy(): void {\n delete this.command.loadBalancingPolicy;\n }\n\n public addNamedPort() {\n if (!get(this.command, 'loadBalancingPolicy.namedPorts')) {\n set(this.command, 'loadBalancingPolicy.namedPorts', []);\n }\n\n this.command.loadBalancingPolicy.namedPorts.push({ name: '', port: 80 });\n }\n\n public removeNamedPort(index: number) {\n this.command.loadBalancingPolicy.namedPorts.splice(index, 1);\n }\n\n public getPortNames(): string[] {\n const index = this.command.backingData.filtered.loadBalancerIndex;\n const selected = this.command.loadBalancers;\n const inUsePortNames = this.command.loadBalancingPolicy.namedPorts.map((namedPort: INamedPort) => namedPort.name);\n\n const getThem = (globalBackendServices: IGceBackendService[], loadBalancer: string): string[] => {\n switch (get(index[loadBalancer], 'loadBalancerType')) {\n case 'SSL':\n case 'TCP':\n case 'GRPC':\n case 'HTTP2':\n case 'HTTP': {\n const lbBackendServices: string[] = get(index[loadBalancer], 'backendServices');\n const filteredBackendServices = globalBackendServices.filter((service: IGceBackendService) =>\n lbBackendServices.includes(service.name),\n );\n const portNames = filteredBackendServices.map((service: IGceBackendService) => service.portName);\n const portNameIntersection = intersection(portNames, inUsePortNames);\n return portNames.filter((portName) => !portNameIntersection.includes(portName));\n }\n default:\n return [];\n }\n };\n\n return chain(selected)\n .flatMap((lbName: string) => getThem(this.globalBackendServices, lbName))\n .uniq()\n .value();\n }\n\n private decimalToPercent(value: number): number {\n if (value === 0) {\n return 0;\n }\n return value ? Math.round(value * 100) : undefined;\n }\n}\n\nconst gceLoadBalancingPolicySelectorComponent: IComponentOptions = {\n bindings: {\n command: '=',\n },\n controller: GceLoadBalancingPolicySelectorController,\n templateUrl: require('./loadBalancingPolicySelector.component.html'),\n};\n\nexport const GCE_LOAD_BALANCING_POLICY_SELECTOR = 'spinnaker.gce.loadBalancingPolicy.selector.component';\n\nmodule(GCE_LOAD_BALANCING_POLICY_SELECTOR, []).component(\n 'gceLoadBalancingPolicySelector',\n gceLoadBalancingPolicySelectorComponent,\n);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE = 'spinnaker.google.networkSelectField.directive';\nexport const name = GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE, []).directive('gceNetworkSelectField', function () {\n return {\n restrict: 'E',\n templateUrl: require('./networkSelectField.directive.html'),\n scope: {\n networks: '=',\n component: '=',\n field: '@',\n account: '=',\n helpKey: '@',\n onChange: '&',\n labelColumns: '@',\n fieldColumns: '@',\n },\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE = 'spinnaker.google.subnet.subnetSelectField.directive';\nexport const name = GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE, []).directive('gceSubnetSelectField', function () {\n return {\n restrict: 'E',\n templateUrl: require('./subnetSelectField.directive.html'),\n scope: {\n subnets: '=',\n subnetPlaceholder: '=',\n autoCreateSubnets: '=',\n component: '=',\n field: '@',\n account: '=',\n region: '=',\n onChange: '&',\n labelColumns: '@',\n helpKey: '@',\n },\n };\n});\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\nimport { from as observableFrom, Subject } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\n\nimport {\n ArtifactTypePatterns,\n excludeAllTypesExcept,\n ExpectedArtifactSelectorViewController,\n IMAGE_READER,\n NgGCEImageArtifactDelegate,\n} from '@spinnaker/core';\n\nimport { GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE } from '../../../../gceNetworkSelectField.directive';\nimport { GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE } from '../../../../gceRegionSelectField.directive';\nimport { GceImageReader } from '../../../../image';\nimport { GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE } from '../../../../subnet/subnetSelectField.directive';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER =\n 'spinnaker.google.serverGroup.configure.wizard.basicSettings.controller';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER, [\n UIROUTER_ANGULARJS,\n ANGULAR_UI_BOOTSTRAP,\n IMAGE_READER,\n GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE,\n GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE,\n GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE,\n ])\n .controller('gceServerGroupBasicSettingsCtrl', [\n '$scope',\n '$controller',\n '$uibModalStack',\n '$state',\n function ($scope, $controller, $uibModalStack, $state) {\n function fetchImagesForAccount() {\n return observableFrom(\n GceImageReader.findImages({\n account: $scope.command.credentials,\n provider: $scope.command.selectedProvider,\n q: '*',\n }),\n );\n }\n\n const imageSearchResultsStream = new Subject();\n imageSearchResultsStream.pipe(switchMap(fetchImagesForAccount)).subscribe((images) => {\n $scope.command.backingData.allImages = images;\n });\n\n this.accountUpdated = () => {\n imageSearchResultsStream.next();\n };\n\n this.selectImage = (image) => {\n // called from a React component\n $scope.$apply(() => {\n $scope.command.image = image;\n });\n };\n\n angular.extend(\n this,\n $controller('BasicSettingsMixin', {\n $scope: $scope,\n imageReader: GceImageReader,\n $uibModalStack: $uibModalStack,\n $state: $state,\n }),\n );\n\n this.stackPattern = {\n test: function (stack) {\n const pattern = $scope.command.viewState.templatingEnabled ? /^([a-zA-Z0-9]*(\\${.+})*)*$/ : /^[a-zA-Z0-9]*$/;\n return pattern.test(stack);\n },\n };\n\n this.detailPattern = {\n test: function (detail) {\n const pattern = $scope.command.viewState.templatingEnabled\n ? /^([a-zA-Z0-9-]*(\\${.+})*)*$/\n : /^[a-zA-Z0-9-]*$/;\n return pattern.test(detail);\n },\n };\n\n this.getSubnetPlaceholder = () => {\n if (!$scope.command.region) {\n return '(Select an account)';\n } else if ($scope.command.viewState.autoCreateSubnets) {\n return '(Subnet will be automatically selected)';\n } else if ($scope.command.viewState.autoCreateSubnets === null) {\n return '(Subnets not supported)';\n } else {\n return null;\n }\n };\n\n this.imageSources = ['artifact', 'priorStage'];\n\n this.excludedImageArtifactTypes = excludeAllTypesExcept(ArtifactTypePatterns.CUSTOM_OBJECT);\n\n this.onImageArtifactEdited = (artifact) => {\n $scope.$applyAsync(() => {\n $scope.command.imageArtifactId = null;\n $scope.command.imageArtifact = artifact;\n });\n };\n\n this.onImageArtifactSelected = (expectedArtifact) => {\n this.onChangeImageArtifactId(expectedArtifact.id);\n };\n\n this.onChangeImageArtifactId = (artifactId) => {\n $scope.$applyAsync(() => {\n $scope.command.imageArtifactId = artifactId;\n $scope.command.imageArtifact = null;\n });\n };\n\n this.onImageArtifactAccountSelected = (accountName) => {\n $scope.$applyAsync(() => {\n $scope.command.imageAccountName = accountName;\n });\n };\n\n const gceImageDelegate = new NgGCEImageArtifactDelegate($scope);\n $scope.gceImageArtifact = {\n showCreateArtifactForm: false,\n delegate: gceImageDelegate,\n controller: new ExpectedArtifactSelectorViewController(gceImageDelegate),\n };\n },\n ]);\n","import { module } from 'angular';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from './tagManager.service';\n\n('use strict');\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT =\n 'spinnaker.deck.gce.tagSelector.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT, [\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n]).component('gceTagSelector', {\n bindings: {\n command: '=',\n securityGroupId: '=',\n },\n templateUrl: require('./tagSelector.component.html'),\n controller: [\n '$scope',\n 'gceTagManager',\n function ($scope, gceTagManager) {\n this.securityGroup = gceTagManager.securityGroupObjectsKeyedById[this.securityGroupId];\n this.onSelect = gceTagManager.addTag;\n this.onRemove = gceTagManager.removeTag;\n\n $scope.$on('uis:select', function (event) {\n event.preventDefault();\n });\n },\n ],\n});\n","import * as angular from 'angular';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from './tagManager.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT } from './tagSelector.component';\n\n('use strict');\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT =\n 'spinnaker.deck.gce.tagSelectorGenerator.component';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT, [\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n ])\n .directive('gceTagSelectorGenerator', [\n '$compile',\n 'gceTagManager',\n function ($compile, gceTagManager) {\n const template = `<gce-tag-selector security-group-id=\"securityGroupId\" command=\"command\">\n </gce-tag-selector>`;\n\n return {\n restrict: 'E',\n scope: {\n command: '=',\n securityGroupId: '=',\n },\n link: function (scope, element) {\n const { securityGroupId } = scope;\n const securityGroupObject = gceTagManager.securityGroupObjectsKeyedById[securityGroupId];\n\n if (securityGroupObject && securityGroupObject.tagsArray.length < 2) {\n securityGroupObject.tagsArray.forEach((tagName) => gceTagManager.addTag(tagName));\n return;\n }\n\n const compiledTemplate = $compile(template)(scope);\n\n angular.element(element).closest('.ui-select-match-item').after(compiledTemplate);\n },\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { InfrastructureCaches } from '@spinnaker/core';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE } from '../../serverGroupConfiguration.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from './tagManager.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT } from './tagSelectorGenerator.component';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.securityGroups.selector.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE, [\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n])\n .directive('gceServerGroupSecurityGroupSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./securityGroupSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: 'gceServerGroupSecurityGroupsSelectorCtrl',\n };\n })\n .controller('gceServerGroupSecurityGroupsSelectorCtrl', [\n 'gceServerGroupConfigurationService',\n 'gceTagManager',\n function (gceServerGroupConfigurationService, gceTagManager) {\n this.getSecurityGroupRefreshTime = () => {\n return InfrastructureCaches.get('securityGroups').getStats().ageMax;\n };\n\n this.refreshSecurityGroups = () => {\n this.refreshing = true;\n gceServerGroupConfigurationService.refreshSecurityGroups(this.command).then(() => {\n this.refreshing = false;\n });\n };\n\n this.onRemove = gceTagManager.removeSecurityGroup;\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.securityGroups.removed.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE, [])\n .directive('gceServerGroupSecurityGroupsRemoved', function () {\n return {\n restrict: 'E',\n templateUrl: require('./securityGroupsRemoved.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: 'gceServerGroupSecurityGroupsRemovedCtrl',\n };\n })\n .controller('gceServerGroupSecurityGroupsRemovedCtrl', function () {\n this.acknowledgeSecurityGroupRemoval = () => {\n this.command.viewState.dirty.securityGroups = null;\n };\n });\n","'use strict';\n\nimport * as angular from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.capacity.regional.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE, [])\n .directive('gceRegionalSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./regionalSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: angular.noop,\n };\n });\n","import { module, noop } from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_TARGETSHAPESELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.capacity.targetShape.directive';\n\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_TARGETSHAPESELECTOR_DIRECTIVE, []).directive(\n 'gceTargetShapeSelector',\n function () {\n return {\n restrict: 'E',\n templateUrl: require('./targetShapeSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: noop,\n };\n },\n);\n","'use strict';\n\nimport * as angular from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE =\n 'spinnaker.google.serverGroup.configure.wizard.capacity.zone.directive';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE, [])\n .directive('gceZoneSelector', function () {\n return {\n restrict: 'E',\n templateUrl: require('./zoneSelector.directive.html'),\n scope: {},\n bindToController: {\n command: '=',\n },\n controllerAs: 'vm',\n controller: angular.noop,\n };\n });\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT } from '../../autoscalingPolicy/components/basicSettings/basicSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT } from '../../autoscalingPolicy/components/metricSettings/metricSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT } from '../../autoscalingPolicy/components/scalingSchedules/scalingSchedules.component';\nimport { GCE_TIMEZONE_SELECT } from '../../autoscalingPolicy/components/scalingSchedules/timeZoneSelect';\nimport { GCE_CACHE_REFRESH } from '../../cache/cacheRefresh.component';\nimport { GCE_IMAGE_SELECT } from '../../image/ImageSelect';\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE } from './../../instance/custom/customInstanceBuilder.gce.service';\nimport { GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from '../serverGroup.transformer';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE } from './serverGroupConfiguration.service';\nimport { GCE_ACCELERATOR_CONFIGURER } from './wizard/advancedSettings/GceAcceleratorConfigurer';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE } from './wizard/advancedSettings/advancedSettingsSelector.directive';\nimport { GCE_DISK_CONFIGURER } from './wizard/advancedSettings/diskConfigurer.component';\nimport { GCE_AUTOHEALING_POLICY_SELECTOR } from './wizard/autoHealingPolicy/autoHealingPolicySelector.component';\nimport { GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT } from './wizard/autoScalingPolicy/autoScalingPolicySelector.component';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT } from './wizard/capacity/advancedCapacitySelector.component';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT } from './wizard/capacity/simpleCapacitySelector.component';\nimport { GCE_CUSTOM_INSTANCE_CONFIGURER } from './wizard/customInstance/customInstanceConfigurer.component';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE } from './wizard/loadBalancers/loadBalancerSelector.directive';\nimport { GCE_LOAD_BALANCING_POLICY_SELECTOR } from './wizard/loadBalancingPolicy/loadBalancingPolicySelector.component';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER } from './wizard/location/basicSettings.controller';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE } from './wizard/securityGroups/securityGroupSelector.directive';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE } from './wizard/securityGroups/securityGroupsRemoved.directive';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE } from './wizard/zones/regionalSelector.directive';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_TARGETSHAPESELECTOR_DIRECTIVE } from './wizard/zones/targetShapeSelector.directive';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE } from './wizard/zones/zoneSelector.directive';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE = 'spinnaker.serverGroup.configure.gce';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE, [\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT,\n GCE_LOAD_BALANCING_POLICY_SELECTOR,\n GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT,\n GCE_AUTOHEALING_POLICY_SELECTOR,\n GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE,\n GCE_CACHE_REFRESH,\n GCE_CUSTOM_INSTANCE_CONFIGURER,\n GCE_DISK_CONFIGURER,\n GCE_ACCELERATOR_CONFIGURER,\n GCE_IMAGE_SELECT,\n GCE_TIMEZONE_SELECT,\n GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_TARGETSHAPESELECTOR_DIRECTIVE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE,\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE =\n 'spinnaker.deck.gce.serverGroup.hiddenMetadataKeys.value';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE, []).value('gceServerGroupHiddenMetadataKeys', [\n 'load-balancer-names',\n 'global-load-balancer-names',\n 'backend-service-names',\n 'load-balancing-policy',\n 'select-zones',\n 'customUserData',\n]);\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { AccountService, ExpectedArtifactService, INSTANCE_TYPE_SERVICE } from '@spinnaker/core';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../common/xpnNaming.gce.service';\nimport { GCEProviderSettings } from '../../gce.settings';\nimport { parseHealthCheckUrl } from '../../healthCheck/healthCheckUtils';\n\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE } from './../../instance/custom/customInstanceBuilder.gce.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE } from './wizard/hiddenMetadataKeys.value';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE =\n 'spinnaker.gce.serverGroupCommandBuilder.service';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE, [\n INSTANCE_TYPE_SERVICE,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE,\n ])\n .factory('gceServerGroupCommandBuilder', [\n '$q',\n 'instanceTypeService',\n 'gceCustomInstanceBuilderService',\n 'gceServerGroupHiddenMetadataKeys',\n 'gceXpnNamingService',\n function (\n $q,\n instanceTypeService,\n gceCustomInstanceBuilderService,\n gceServerGroupHiddenMetadataKeys,\n gceXpnNamingService,\n ) {\n // Two assumptions here:\n // 1) All GCE machine types are represented in the tree of choices.\n // 2) Each machine type appears in exactly one category.\n function determineInstanceCategoryFromInstanceType(command) {\n return instanceTypeService.getCategories('gce').then(function (categories) {\n categories.forEach(function (category) {\n category.families.forEach(function (family) {\n family.instanceTypes.forEach(function (instanceType) {\n if (instanceType.name === command.instanceType) {\n command.viewState.instanceProfile = category.type;\n }\n });\n });\n });\n });\n }\n\n function extractNetworkName(serverGroup) {\n const projectId = gceXpnNamingService.deriveProjectId(serverGroup.launchConfig.instanceTemplate);\n const networkUrl = _.get(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].network');\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, networkUrl);\n }\n\n function extractSubnetName(serverGroup) {\n const projectId = gceXpnNamingService.deriveProjectId(serverGroup.launchConfig.instanceTemplate);\n const subnetworkUrl = _.get(\n serverGroup,\n 'launchConfig.instanceTemplate.properties.networkInterfaces[0].subnetwork',\n );\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, subnetworkUrl);\n }\n\n function determineAssociatePublicIPAddress(serverGroup) {\n return _.has(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].accessConfigs');\n }\n\n function extractLoadBalancers(asg) {\n return ['load-balancer-names', 'global-load-balancer-names'].reduce((loadBalancers, property) => {\n if (asg[property]) {\n loadBalancers = loadBalancers.concat(asg[property]);\n }\n return loadBalancers;\n }, []);\n }\n\n function extractLoadBalancersFromMetadata(metadata) {\n return ['load-balancer-names', 'global-load-balancer-names'].reduce((loadBalancers, property) => {\n if (metadata[property]) {\n loadBalancers = loadBalancers.concat(metadata[property].split(','));\n }\n return loadBalancers;\n }, []);\n }\n\n function populateDisksFromExisting(disks, command) {\n disks = disks.map((disk, index) => {\n if (index === 0) {\n return {\n type: disk.initializeParams.diskType,\n sizeGb: disk.initializeParams.diskSizeGb,\n };\n } else {\n return {\n type: disk.initializeParams.diskType,\n sizeGb: disk.initializeParams.diskSizeGb,\n sourceImage: _.last(_.get(disk, 'initializeParams.sourceImage', '').split('/')) || null,\n };\n }\n });\n const localSSDDisks = disks.filter((disk) => disk.type === 'local-ssd');\n const persistentDisks = disks.filter(\n (disk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'),\n );\n\n if (persistentDisks.length) {\n command.disks = persistentDisks.concat(localSSDDisks);\n return instanceTypeService\n .getInstanceTypeDetails(\n command.selectedProvider,\n _.includes(command.instanceType, 'custom-') ? 'buildCustom' : command.instanceType,\n )\n .then((instanceTypeDetails) => {\n command.viewState.instanceTypeDetails = instanceTypeDetails;\n calculateOverriddenStorageDescription(instanceTypeDetails, command);\n });\n } else {\n command.disks = [{ type: 'pd-ssd', sizeGb: 10 }].concat(localSSDDisks);\n return $q.when(null);\n }\n }\n\n function populateDisksFromPipeline(command) {\n const persistentDisks = getPersistentDisks(command);\n const localSSDDisks = getLocalSSDDisks(command);\n\n if (persistentDisks.length) {\n command.disks = persistentDisks.concat(localSSDDisks);\n return instanceTypeService\n .getInstanceTypeDetails(\n command.selectedProvider,\n _.includes(command.instanceType, 'custom-') ? 'buildCustom' : command.instanceType,\n )\n .then((instanceTypeDetails) => {\n command.viewState.instanceTypeDetails = instanceTypeDetails;\n calculateOverriddenStorageDescription(instanceTypeDetails, command);\n });\n } else {\n command.disks = [{ type: 'pd-ssd', sizeGb: 10 }].concat(localSSDDisks);\n return $q.when(null);\n }\n }\n\n function getLocalSSDDisks(command) {\n return (command.disks || []).filter((disk) => disk.type === 'local-ssd');\n }\n\n function getPersistentDisks(command) {\n return (command.disks || []).filter(\n (disk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'),\n );\n }\n\n function calculatePersistentDiskOverriddenStorageDescription(command) {\n const persistentDisks = getPersistentDisks(command);\n\n const diskCountBySizeGb = new Map();\n persistentDisks.forEach((disk) => {\n if (diskCountBySizeGb.has(disk.sizeGb)) {\n diskCountBySizeGb.set(disk.sizeGb, diskCountBySizeGb.get(disk.sizeGb) + 1);\n } else {\n diskCountBySizeGb.set(disk.sizeGb, 1);\n }\n });\n\n return Array.from(diskCountBySizeGb)\n .sort(([sizeA], [sizeB]) => sizeB - sizeA)\n .map(([sizeGb, count]) => count + '×' + sizeGb)\n .join(', ');\n }\n\n function calculateOverriddenStorageDescription(instanceTypeDetails, command) {\n if (instanceTypeDetails.storage.localSSDSupported) {\n if (getLocalSSDDisks(command).length !== instanceTypeDetails.storage.count) {\n command.viewState.overriddenStorageDescription = getLocalSSDDisks(command).length + '×375';\n }\n } else {\n const persistentDisks = getPersistentDisks(command);\n const overrideStorageDescription =\n persistentDisks.some((disk) => disk.sizeGb !== instanceTypeDetails.storage.size) ||\n persistentDisks.length !== instanceTypeDetails.storage.count;\n\n if (overrideStorageDescription) {\n command.viewState.overriddenStorageDescription = calculatePersistentDiskOverriddenStorageDescription(\n command,\n );\n }\n }\n }\n\n function populateAvailabilityPolicies(scheduling, command) {\n if (scheduling) {\n command.preemptible = scheduling.preemptible;\n command.automaticRestart = scheduling.automaticRestart;\n command.onHostMaintenance = scheduling.onHostMaintenance;\n } else {\n command.preemptible = false;\n command.automaticRestart = true;\n command.onHostMaintenance = 'MIGRATE';\n }\n }\n\n function populateAutoHealingPolicy(serverGroup, command) {\n const autoHealingPolicy = serverGroup.autoHealingPolicy;\n if (autoHealingPolicy) {\n const healthCheckUrl = autoHealingPolicy.healthCheckUrl\n ? autoHealingPolicy.healthCheckUrl\n : autoHealingPolicy.healthCheck;\n\n if (healthCheckUrl) {\n const { healthCheckName, healthCheckKind } = parseHealthCheckUrl(healthCheckUrl);\n command.autoHealingPolicy = {\n healthCheck: healthCheckName,\n healthCheckKind: healthCheckKind,\n healthCheckUrl: healthCheckUrl,\n initialDelaySec: autoHealingPolicy.initialDelaySec,\n };\n }\n\n const maxUnavailable = autoHealingPolicy.maxUnavailable;\n if (maxUnavailable) {\n command.autoHealingPolicy.maxUnavailable = maxUnavailable;\n command.viewState.maxUnavailableMetric = typeof maxUnavailable.percent === 'number' ? 'percent' : 'fixed';\n }\n }\n }\n\n function populateShieldedVmConfig(serverGroup, command) {\n command.enableSecureBoot = serverGroup.enableSecureBoot;\n command.enableVtpm = serverGroup.enableVtpm;\n command.enableIntegrityMonitoring = serverGroup.enableIntegrityMonitoring;\n }\n\n function populateCustomMetadata(metadataItems, command) {\n // Hide metadata items in the wizard.\n if (metadataItems) {\n let customUserData = '';\n let customUserDataKeys = [];\n if (angular.isArray(metadataItems)) {\n const customUserDataItem = metadataItems.find((metadataItem) => metadataItem.key === 'customUserData');\n if (customUserDataItem) {\n customUserData = customUserDataItem.value;\n customUserDataKeys = getCustomUserDataKeys(customUserData);\n command.userData = customUserData;\n }\n metadataItems.forEach(function (metadataItem) {\n if (\n !_.includes(customUserDataKeys, metadataItem.key) &&\n !_.includes(gceServerGroupHiddenMetadataKeys, metadataItem.key)\n ) {\n command.instanceMetadata[metadataItem.key] = metadataItem.value;\n }\n });\n } else {\n if (metadataItems.customUserData) {\n customUserData = metadataItems.customUserData;\n customUserDataKeys = getCustomUserDataKeys(customUserData);\n command.userData = customUserData;\n metadataItems = _.omit(metadataItems, customUserDataKeys);\n }\n angular.extend(command.instanceMetadata, _.omit(metadataItems, gceServerGroupHiddenMetadataKeys));\n }\n }\n\n if (command.labels['spinnaker-moniker-sequence']) {\n delete command.labels['spinnaker-moniker-sequence'];\n }\n }\n\n function getCustomUserDataKeys(customUserData) {\n const customUserDataKeys = [];\n customUserData.split(/\\n|,/).forEach(function (userDataItem) {\n const customUserDataKey = userDataItem.split('=')[0];\n customUserDataKeys.push(customUserDataKey);\n });\n return customUserDataKeys;\n }\n\n function populateTags(instanceTemplateTags, command) {\n if (instanceTemplateTags && instanceTemplateTags.items) {\n _.map(instanceTemplateTags.items, function (tag) {\n command.tags.push({ value: tag });\n });\n }\n }\n\n function populateResourceManagerTags(instanceTemplateResourceManagerTags, command) {\n if (instanceTemplateResourceManagerTags) {\n Object.assign(command.resourceManagerTags, instanceTemplateResourceManagerTags);\n }\n }\n\n function populatePartnerMetadata(instanceTemplatePartnerMetadata, command) {\n if (instanceTemplatePartnerMetadata) {\n Object.assign(command.partnerMetadata, instanceTemplatePartnerMetadata);\n }\n }\n\n function populateLabels(instanceTemplateLabels, command) {\n if (instanceTemplateLabels) {\n Object.assign(command.labels, instanceTemplateLabels);\n\n if (command.labels['spinnaker-region']) {\n delete command.labels['spinnaker-region'];\n }\n\n if (command.labels['spinnaker-server-group']) {\n delete command.labels['spinnaker-server-group'];\n }\n\n // Need to delete the sequence, otherwise it won't increment\n if (command.labels['spinnaker-moniker-sequence']) {\n delete command.labels['spinnaker-moniker-sequence'];\n }\n }\n }\n\n function populateAuthScopes(serviceAccounts, command) {\n if (serviceAccounts && serviceAccounts.length) {\n command.serviceAccountEmail = serviceAccounts[0].email;\n command.authScopes = _.map(serviceAccounts[0].scopes, (authScope) => {\n return authScope.replace('https://www.googleapis.com/auth/', '');\n });\n } else {\n command.authScopes = [];\n }\n }\n\n function attemptToSetValidCredentials(application, defaultCredentials, command) {\n return AccountService.listAccounts('gce').then(function (gceAccounts) {\n const gceAccountNames = _.map(gceAccounts, 'name');\n const firstGCEAccount = gceAccountNames[0];\n\n const defaultCredentialsAreValid = defaultCredentials && gceAccountNames.includes(defaultCredentials);\n\n command.credentials = defaultCredentialsAreValid ? defaultCredentials : firstGCEAccount || 'my-account-name';\n });\n }\n\n function buildNewServerGroupCommand(application, defaults) {\n defaults = defaults || {};\n\n const defaultCredentials = defaults.account || GCEProviderSettings.defaults.account;\n const defaultRegion = defaults.region || GCEProviderSettings.defaults.region;\n const defaultZone = defaults.zone || GCEProviderSettings.defaults.zone;\n const associatePublicIpAddress = _.has(application, 'attributes.providerSettings.gce.associatePublicIpAddress')\n ? application.attributes.providerSettings.gce.associatePublicIpAddress\n : true;\n\n const command = {\n application: application.name,\n credentials: defaultCredentials,\n region: defaultRegion,\n zone: defaultZone,\n regional: false, // TODO(duftler): Externalize this default alongside defaultRegion and defaultZone.\n selectZones: false, // Explicitly select zones for regional server groups.\n distributionPolicy: { zones: [] },\n network: 'default',\n associatePublicIpAddress: associatePublicIpAddress,\n canIpForward: false,\n strategy: '',\n capacity: {\n min: 0,\n max: 0,\n desired: 1,\n },\n backendServiceMetadata: [],\n minCpuPlatform: '(Automatic)',\n disks: [\n { type: 'pd-ssd', sizeGb: 10 },\n { type: 'local-ssd', sizeGb: 375 },\n ],\n imageSource: 'priorStage',\n instanceMetadata: {},\n tags: [],\n labels: {},\n resourceManagerTags: {},\n partnerMetadata: {},\n enableSecureBoot: false,\n enableVtpm: false,\n enableIntegrityMonitoring: false,\n preemptible: false,\n automaticRestart: true,\n onHostMaintenance: 'MIGRATE',\n serviceAccountEmail: 'default',\n authScopes: ['cloud.useraccounts.readonly', 'devstorage.read_only', 'logging.write', 'monitoring.write'],\n enableTraffic: true,\n cloudProvider: 'gce',\n selectedProvider: 'gce',\n availabilityZones: [],\n viewState: {\n instanceProfile: 'custom',\n allImageSelection: null,\n useSimpleCapacity: true,\n usePreferredZones: true,\n listImplicitSecurityGroups: false,\n mode: defaults.mode || 'create',\n disableStrategySelection: true,\n expectedArtifacts: [],\n },\n };\n\n if (\n application.attributes &&\n application.attributes.platformHealthOnlyShowOverride &&\n application.attributes.platformHealthOnly\n ) {\n command.interestingHealthProviderNames = ['Google'];\n }\n\n return attemptToSetValidCredentials(application, defaultCredentials, command).then(() => command);\n }\n\n // Only used to prepare view requiring template selecting\n function buildNewServerGroupCommandForPipeline(currentStage, pipeline) {\n const expectedArtifacts = ExpectedArtifactService.getExpectedArtifactsAvailableToStage(currentStage, pipeline);\n return $q.when({\n viewState: {\n pipeline,\n expectedArtifacts: expectedArtifacts,\n requiresTemplateSelection: true,\n stage: currentStage,\n },\n });\n }\n\n function buildServerGroupCommandFromExisting(application, serverGroup, mode) {\n mode = mode || 'clone';\n const moniker = serverGroup.moniker;\n\n const command = {\n application: application.name,\n autoscalingPolicy: _.cloneDeep(serverGroup.autoscalingPolicy),\n strategy: '',\n stack: moniker.stack,\n freeFormDetails: moniker.detail,\n credentials: serverGroup.account,\n loadBalancers: extractLoadBalancers(serverGroup.asg),\n loadBalancingPolicy: _.cloneDeep(serverGroup.loadBalancingPolicy),\n backendServiceMetadata: serverGroup.asg['backend-service-names'],\n securityGroups: serverGroup.securityGroups,\n region: serverGroup.region,\n capacity: {\n min: serverGroup.asg.minSize,\n max: serverGroup.asg.maxSize,\n desired: serverGroup.asg.desiredCapacity,\n },\n regional: serverGroup.regional,\n network: extractNetworkName(serverGroup),\n subnet: extractSubnetName(serverGroup),\n associatePublicIpAddress: determineAssociatePublicIPAddress(serverGroup),\n canIpForward: serverGroup.canIpForward,\n minCpuPlatform: serverGroup.launchConfig.minCpuPlatform || '(Automatic)',\n instanceMetadata: {},\n tags: [],\n labels: {},\n resourceManagerTags: {},\n partnerMetadata: {},\n availabilityZones: [],\n enableSecureBoot: serverGroup.enableSecureBoot,\n enableVtpm: serverGroup.enableVtpm,\n enableIntegrityMonitoring: serverGroup.enableIntegrityMonitoring,\n enableTraffic: true,\n cloudProvider: 'gce',\n selectedProvider: 'gce',\n distributionPolicy: {\n zones: serverGroup.distributionPolicy ? serverGroup.distributionPolicy.zones : [],\n targetShape: serverGroup.distributionPolicy ? serverGroup.distributionPolicy.targetShape : null,\n },\n selectZones: serverGroup.selectZones,\n source: {\n account: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n asgName: serverGroup.name,\n },\n viewState: {\n allImageSelection: null,\n useSimpleCapacity: !serverGroup.autoscalingPolicy,\n usePreferredZones: false,\n listImplicitSecurityGroups: false,\n mode: mode,\n },\n };\n\n if (!command.regional) {\n command.zone = serverGroup.zones[0];\n command.source.zone = serverGroup.zones[0];\n }\n\n if (\n application.attributes &&\n application.attributes.platformHealthOnlyShowOverride &&\n application.attributes.platformHealthOnly\n ) {\n command.interestingHealthProviderNames = ['Google'];\n }\n\n populateAutoHealingPolicy(serverGroup, command);\n\n if (serverGroup.launchConfig) {\n const instanceType = serverGroup.launchConfig.instanceType;\n angular.extend(command, {\n instanceType: instanceType,\n });\n\n if (_.includes(instanceType, 'custom-')) {\n command.viewState.customInstance = gceCustomInstanceBuilderService.parseInstanceTypeString(instanceType);\n command.viewState.instanceProfile = 'buildCustom';\n }\n\n command.viewState.imageId = serverGroup.launchConfig.imageId;\n return determineInstanceCategoryFromInstanceType(command).then(function () {\n populateAvailabilityPolicies(serverGroup.launchConfig.instanceTemplate.properties.scheduling, command);\n populateCustomMetadata(serverGroup.launchConfig.instanceTemplate.properties.metadata.items, command);\n populateTags(serverGroup.launchConfig.instanceTemplate.properties.tags, command);\n populateLabels(serverGroup.instanceTemplateLabels, command);\n populateAuthScopes(serverGroup.launchConfig.instanceTemplate.properties.serviceAccounts, command);\n populateResourceManagerTags(\n serverGroup.launchConfig.instanceTemplate.properties.resourceManagerTags,\n command,\n );\n populatePartnerMetadata(serverGroup.launchConfig.instanceTemplate.properties.partnerMetadata, command);\n\n return populateDisksFromExisting(serverGroup.launchConfig.instanceTemplate.properties.disks, command).then(\n function () {\n return command;\n },\n );\n });\n }\n\n return $q.when(command);\n }\n\n function buildServerGroupCommandFromPipeline(application, originalCluster, currentStage, pipeline) {\n const pipelineCluster = _.cloneDeep(originalCluster);\n const region = Object.keys(pipelineCluster.availabilityZones)[0];\n const zone = pipelineCluster.zone;\n const instanceTypeCategoryLoader = instanceTypeService.getCategoryForInstanceType(\n 'gce',\n pipelineCluster.instanceType,\n );\n\n const commandOptions = { account: pipelineCluster.account, region: region, zone: zone };\n return $q\n .all([buildNewServerGroupCommand(application, commandOptions), instanceTypeCategoryLoader])\n .then(function ([command, instanceProfile]) {\n const expectedArtifacts = ExpectedArtifactService.getExpectedArtifactsAvailableToStage(\n currentStage,\n pipeline,\n );\n const viewState = {\n pipeline,\n stage: currentStage,\n instanceProfile,\n disableImageSelection: true,\n expectedArtifacts: expectedArtifacts,\n showImageSourceSelector: true,\n useSimpleCapacity: !pipelineCluster.autoscalingPolicy,\n mode: 'editPipeline',\n submitButtonLabel: 'Done',\n customInstance:\n instanceProfile === 'buildCustom'\n ? gceCustomInstanceBuilderService.parseInstanceTypeString(pipelineCluster.instanceType)\n : null,\n templatingEnabled: true,\n };\n\n const viewOverrides = {\n region: region,\n credentials: pipelineCluster.account,\n enableTraffic: !pipelineCluster.disableTraffic,\n viewState: viewState,\n };\n\n pipelineCluster.strategy = pipelineCluster.strategy || '';\n\n const extendedCommand = angular.extend({}, command, pipelineCluster, viewOverrides);\n\n return populateDisksFromPipeline(extendedCommand).then(function () {\n const instanceMetadata = extendedCommand.instanceMetadata;\n extendedCommand.loadBalancers = extractLoadBalancersFromMetadata(instanceMetadata);\n extendedCommand.backendServiceMetadata = instanceMetadata['backend-service-names']\n ? instanceMetadata['backend-service-names'].split(',')\n : [];\n extendedCommand.minCpuPlatform = pipelineCluster.minCpuPlatform || '(Automatic)';\n extendedCommand.instanceMetadata = {};\n populateCustomMetadata(instanceMetadata, extendedCommand);\n populateAutoHealingPolicy(pipelineCluster, extendedCommand);\n populateShieldedVmConfig(pipelineCluster, extendedCommand);\n\n const instanceTemplateTags = { items: extendedCommand.tags };\n extendedCommand.tags = [];\n populateTags(instanceTemplateTags, extendedCommand);\n\n const resourceManagerTags = extendedCommand.resourceManagerTags;\n populateResourceManagerTags(resourceManagerTags, extendedCommand);\n\n const partnerMetadata = extendedCommand.partnerMetadata;\n populatePartnerMetadata(partnerMetadata, extendedCommand);\n\n return extendedCommand;\n });\n });\n }\n\n return {\n buildNewServerGroupCommand: buildNewServerGroupCommand,\n buildNewServerGroupCommandForPipeline: buildNewServerGroupCommandForPipeline,\n buildServerGroupCommandFromExisting: buildServerGroupCommandFromExisting,\n buildServerGroupCommandFromPipeline: buildServerGroupCommandFromPipeline,\n };\n },\n ]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _, { isEmpty } from 'lodash';\n\nimport { FirewallLabels, INSTANCE_TYPE_SERVICE, ModalWizard, TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE } from './hiddenMetadataKeys.value';\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE } from '../../../instance/custom/customInstanceBuilder.gce.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE } from './securityGroups/tagManager.service';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER =\n 'spinnaker.serverGroup.configure.gce.cloneServerGroup';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE,\n INSTANCE_TYPE_SERVICE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE,\n ])\n .controller('gceCloneServerGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n '$q',\n '$state',\n '$log',\n 'serverGroupWriter',\n 'gceServerGroupConfigurationService',\n 'serverGroupCommand',\n 'application',\n 'title',\n 'gceCustomInstanceBuilderService',\n 'instanceTypeService',\n 'wizardSubFormValidation',\n 'gceServerGroupHiddenMetadataKeys',\n 'gceTagManager',\n function (\n $scope,\n $uibModalInstance,\n $q,\n $state,\n $log,\n serverGroupWriter,\n gceServerGroupConfigurationService,\n serverGroupCommand,\n application,\n title,\n gceCustomInstanceBuilderService,\n instanceTypeService,\n wizardSubFormValidation,\n gceServerGroupHiddenMetadataKeys,\n gceTagManager,\n ) {\n $scope.pages = {\n templateSelection: require('./templateSelection/templateSelection.html'),\n basicSettings: require('./location/basicSettings.html'),\n loadBalancers: require('./loadBalancers/loadBalancers.html'),\n securityGroups: require('./securityGroups/securityGroups.html'),\n instanceType: require('./instanceType/instanceType.html'),\n capacity: require('./capacity/capacity.html'),\n autoHealingPolicy: require('./autoHealingPolicy/autoHealingPolicy.html'),\n autoScalingPolicy: require('./autoScalingPolicy/autoScalingPolicy.html'),\n zones: require('./capacity/zones.html'),\n advancedSettings: require('./advancedSettings/advancedSettings.html'),\n };\n\n $scope.firewallsLabel = FirewallLabels.get('Firewalls');\n\n $scope.title = title;\n\n $scope.applicationName = application.name;\n $scope.application = application;\n\n $scope.command = serverGroupCommand;\n\n $scope.state = {\n loaded: false,\n requiresTemplateSelection: !!serverGroupCommand.viewState.requiresTemplateSelection,\n };\n\n this.templateSelectionText = {\n copied: [\n 'account, region, subnet, cluster name (stack, details)',\n 'load balancers',\n FirewallLabels.get('firewalls'),\n 'instance type',\n 'all fields on the Advanced Settings page',\n ],\n notCopied: [],\n };\n\n if (!$scope.command.viewState.disableStrategySelection) {\n this.templateSelectionText.notCopied.push(\n 'the deployment strategy (if any) used to deploy the most recent server group',\n );\n }\n\n function onApplicationRefresh() {\n // If the user has already closed the modal, do not navigate to the new details view\n if ($scope.$$destroyed) {\n return;\n }\n const cloneStage = $scope.taskMonitor.task.execution.stages.find((stage) => stage.type === 'cloneServerGroup');\n if (cloneStage && cloneStage.context['deploy.server.groups']) {\n const newServerGroupName = cloneStage.context['deploy.server.groups'][$scope.command.region];\n if (newServerGroupName) {\n const newStateParams = {\n serverGroup: newServerGroupName,\n accountId: $scope.command.credentials,\n region: $scope.command.region,\n provider: 'gce',\n };\n let transitionTo = '^.^.^.clusters.serverGroup';\n if ($state.includes('**.clusters.serverGroup')) {\n // clone via details, all view\n transitionTo = '^.serverGroup';\n }\n if ($state.includes('**.clusters.cluster.serverGroup')) {\n // clone or create with details open\n transitionTo = '^.^.serverGroup';\n }\n if ($state.includes('**.clusters')) {\n // create new, no details open\n transitionTo = '.serverGroup';\n }\n $state.go(transitionTo, newStateParams);\n }\n }\n }\n\n function onTaskComplete() {\n application.serverGroups.refresh();\n application.serverGroups.onNextRefresh($scope, onApplicationRefresh);\n }\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: 'Creating your server group',\n modalInstance: $uibModalInstance,\n onTaskComplete: onTaskComplete,\n });\n\n function configureCommand() {\n gceServerGroupConfigurationService\n .configureCommand(application, serverGroupCommand)\n .then(function () {\n $scope.state.loaded = true;\n initializeSelectOptions();\n initializeWatches();\n wizardSubFormValidation\n .config({ scope: $scope, form: 'form' })\n .register({ page: 'location', subForm: 'basicSettings' })\n .register({ page: 'capacity', subForm: 'capacitySubForm' })\n .register({ page: 'zones', subForm: 'zonesSubForm' })\n .register({ page: 'load-balancers', subForm: 'loadBalancerSubForm' })\n .register({ page: 'autohealing-policy', subForm: 'autoHealingPolicySubForm' })\n .register({ page: 'autoscaling-policy', subForm: 'autoScalingPolicySubForm' });\n })\n .catch((e) => {\n $log.error('Error generating server group command: ', e);\n });\n }\n\n function initializeWatches() {\n $scope.$watch('command.credentials', createResultProcessor($scope.command.credentialsChanged));\n $scope.$watch('command.regional', createResultProcessor($scope.command.regionalChanged));\n $scope.$watch('command.region', createResultProcessor($scope.command.regionChanged));\n $scope.$watch('command.network', createResultProcessor($scope.command.networkChanged));\n $scope.$watch('command.zone', createResultProcessor($scope.command.zoneChanged));\n $scope.$watch('command.viewState.instanceTypeDetails', updateStorageSettingsFromInstanceType());\n $scope.$watch('command.selectZones', createResultProcessor($scope.command.selectZonesChanged));\n $scope.$watch('command.distributionPolicy.zones', createResultProcessor($scope.command.selectZonesChanged));\n $scope.$watch(\n 'command.viewState.customInstance',\n () => {\n $scope.command.customInstanceChanged($scope.command);\n setInstanceTypeFromCustomChoices();\n },\n true,\n );\n }\n\n function initializeSelectOptions() {\n processCommandUpdateResult($scope.command.credentialsChanged($scope.command));\n processCommandUpdateResult($scope.command.regionalChanged($scope.command));\n processCommandUpdateResult($scope.command.regionChanged($scope.command));\n processCommandUpdateResult($scope.command.networkChanged($scope.command));\n processCommandUpdateResult($scope.command.zoneChanged($scope.command));\n processCommandUpdateResult($scope.command.customInstanceChanged($scope.command));\n gceServerGroupConfigurationService.configureSubnets($scope.command);\n }\n\n function createResultProcessor(method) {\n return function () {\n processCommandUpdateResult(method($scope.command));\n };\n }\n\n function processCommandUpdateResult(result) {\n if (result.dirty.loadBalancers) {\n ModalWizard.markDirty('load-balancers');\n }\n if (result.dirty.securityGroups) {\n ModalWizard.markDirty('security-groups');\n }\n if (result.dirty.availabilityZones) {\n ModalWizard.markDirty('capacity');\n }\n if (result.dirty.instanceType) {\n ModalWizard.markDirty('instance-type');\n }\n }\n\n function setInstanceTypeFromCustomChoices() {\n const c = $scope.command;\n const location = c.regional ? c.region : c.zone;\n const { locationToInstanceTypesMap } = c.backingData.credentialsKeyedByAccount[c.credentials];\n const extendedMemory = _.get(c, 'viewState.customInstance.extendedMemory');\n const customInstanceChoices = [\n _.get(c, 'viewState.customInstance.instanceFamily'),\n _.get(c, 'viewState.customInstance.vCpuCount'),\n _.get(c, 'viewState.customInstance.memory'),\n ];\n\n if (\n _.every([\n ...customInstanceChoices,\n gceCustomInstanceBuilderService.customInstanceChoicesAreValid(\n ...customInstanceChoices,\n location,\n locationToInstanceTypesMap,\n extendedMemory,\n ),\n ])\n ) {\n c.instanceType = gceCustomInstanceBuilderService.generateInstanceTypeString(\n ...customInstanceChoices,\n extendedMemory,\n );\n\n instanceTypeService.getInstanceTypeDetails(c.selectedProvider, 'buildCustom').then((instanceTypeDetails) => {\n c.viewState.instanceTypeDetails = instanceTypeDetails;\n });\n }\n }\n\n function updateStorageSettingsFromInstanceType() {\n return function (instanceTypeDetails) {\n if ($scope.command.viewState.initialized) {\n if (instanceTypeDetails && instanceTypeDetails.storage && instanceTypeDetails.storage.defaultSettings) {\n $scope.command.disks = instanceTypeDetails.storage.defaultSettings.disks;\n delete $scope.command.viewState.overriddenStorageDescription;\n }\n } else {\n $scope.command.viewState.initialized = true;\n }\n };\n }\n\n this.isValid = function () {\n const selectedZones =\n $scope.command.selectZones && _.get($scope, 'command.distributionPolicy.zones.length') >= 1;\n const autoScalingPolicy = $scope.command.autoscalingPolicy;\n return (\n $scope.command &&\n ($scope.command.viewState.disableImageSelection || $scope.command.image) &&\n $scope.command.application &&\n $scope.command.credentials &&\n $scope.command.instanceType &&\n $scope.command.region &&\n ($scope.command.regional || $scope.command.zone) &&\n $scope.command.capacity.desired !== null &&\n (!$scope.command.selectZones || selectedZones) &&\n $scope.form.$valid &&\n (!autoScalingPolicy ||\n (autoScalingPolicy &&\n (!isEmpty(autoScalingPolicy.cpuUtilization) ||\n !isEmpty(autoScalingPolicy.customMetricUtilizations) ||\n !isEmpty(autoScalingPolicy.loadBalancingUtilization)))) &&\n ModalWizard.isComplete()\n );\n };\n\n this.showSubmitButton = function () {\n return ModalWizard.allPagesVisited();\n };\n\n function buildLoadBalancerMetadata(loadBalancerNames, loadBalancerIndex, backendServices) {\n let metadata = {};\n\n if (_.get(loadBalancerNames, 'length') > 0) {\n metadata = loadBalancerNames.reduce(\n (metadata, name) => {\n const loadBalancerDetails = loadBalancerIndex[name];\n\n if (loadBalancerDetails.loadBalancerType === 'HTTP') {\n metadata['global-load-balancer-names'] = metadata['global-load-balancer-names'].concat(\n loadBalancerDetails.listeners.map((listener) => listener.name),\n );\n } else if (loadBalancerDetails.loadBalancerType === 'INTERNAL_MANAGED') {\n metadata['load-balancer-names'] = metadata['load-balancer-names'].concat(\n loadBalancerDetails.listeners.map((listener) => listener.name),\n );\n } else if (loadBalancerDetails.loadBalancerType === 'SSL') {\n metadata['global-load-balancer-names'].push(name);\n } else if (loadBalancerDetails.loadBalancerType === 'TCP') {\n metadata['global-load-balancer-names'].push(name);\n } else {\n metadata['load-balancer-names'].push(name);\n }\n return metadata;\n },\n { 'load-balancer-names': [], 'global-load-balancer-names': [] },\n );\n }\n\n if (_.isObject(backendServices) && Object.keys(backendServices).length > 0) {\n metadata['backend-service-names'] = _.reduce(\n backendServices,\n (accumulatedBackends, backends) => accumulatedBackends.concat(backends),\n [],\n );\n }\n\n for (const key in metadata) {\n if (metadata[key].length === 0) {\n delete metadata[key];\n } else {\n metadata[key] = _.uniq(metadata[key]).toString();\n }\n }\n\n return metadata;\n }\n\n function collectLoadBalancerNamesForCommand(loadBalancerIndex, loadBalancerMetadata) {\n let loadBalancerNames = [];\n if (loadBalancerMetadata['load-balancer-names']) {\n loadBalancerNames = loadBalancerNames.concat(loadBalancerMetadata['load-balancer-names'].split(','));\n }\n\n const selectedSslLoadBalancerNames = _.chain(loadBalancerIndex)\n .filter({ loadBalancerType: 'SSL' })\n .map('name')\n .intersection(\n loadBalancerMetadata['global-load-balancer-names']\n ? loadBalancerMetadata['global-load-balancer-names'].split(',')\n : [],\n )\n .value();\n\n const selectedTcpLoadBalancerNames = _.chain(loadBalancerIndex)\n .filter({ loadBalancerType: 'TCP' })\n .map('name')\n .intersection(\n loadBalancerMetadata['global-load-balancer-names']\n ? loadBalancerMetadata['global-load-balancer-names'].split(',')\n : [],\n )\n .value();\n\n return loadBalancerNames.concat(selectedSslLoadBalancerNames).concat(selectedTcpLoadBalancerNames);\n }\n\n this.submit = function () {\n // We use this list of load balancer names when 'Enabling' a server group.\n const loadBalancerMetadata = buildLoadBalancerMetadata(\n $scope.command.loadBalancers,\n $scope.command.backingData.filtered.loadBalancerIndex,\n $scope.command.backendServices,\n );\n\n const origLoadBalancers = $scope.command.loadBalancers;\n $scope.command.loadBalancers = collectLoadBalancerNamesForCommand(\n $scope.command.backingData.filtered.loadBalancerIndex,\n loadBalancerMetadata,\n );\n\n if ($scope.command.minCpuPlatform === '(Automatic)') {\n $scope.command.minCpuPlatform = '';\n }\n\n angular.extend($scope.command.instanceMetadata, loadBalancerMetadata);\n\n const origTags = $scope.command.tags;\n const transformedTags = [];\n // The tags are stored using a 'value' attribute to enable the Add/Remove behavior in the wizard.\n $scope.command.tags.forEach(function (tag) {\n transformedTags.push(tag.value);\n });\n $scope.command.tags = transformedTags;\n\n $scope.command.targetSize = $scope.command.capacity.desired;\n\n if ($scope.command.autoscalingPolicy) {\n $scope.command.capacity.min = $scope.command.autoscalingPolicy.minNumReplicas;\n $scope.command.capacity.max = $scope.command.autoscalingPolicy.maxNumReplicas;\n } else {\n $scope.command.capacity.min = $scope.command.capacity.desired;\n $scope.command.capacity.max = $scope.command.capacity.desired;\n }\n\n delete $scope.command.securityGroups;\n\n if ($scope.command.viewState.mode === 'editPipeline' || $scope.command.viewState.mode === 'createPipeline') {\n return $uibModalInstance.close($scope.command);\n }\n\n $scope.taskMonitor.submit(function () {\n const promise = serverGroupWriter.cloneServerGroup(angular.copy($scope.command), application);\n\n // Copy back the original objects so the wizard can still be used if the command needs to be resubmitted.\n $scope.command.instanceMetadata = _.omit($scope.command.instanceMetadata, gceServerGroupHiddenMetadataKeys);\n\n $scope.command.tags = origTags;\n $scope.command.loadBalancers = origLoadBalancers;\n $scope.command.securityGroups = gceTagManager.inferSecurityGroupIdsFromTags($scope.command.tags);\n\n return promise;\n });\n };\n\n this.onHealthCheckRefresh = function () {\n gceServerGroupConfigurationService.refreshHealthChecks($scope.command);\n };\n\n this.onEnableAutoHealingChange = function () {\n // Prevent empty auto-healing policies from being overwritten by those of their ancestors\n $scope.command.overwriteAncestorAutoHealingPolicy =\n $scope.command.viewState.mode === 'clone' &&\n $scope.command.autoHealingPolicy != null &&\n $scope.command.enableAutoHealing === false;\n };\n\n this.setAutoHealingPolicy = function (autoHealingPolicy) {\n $scope.command.autoHealingPolicy = autoHealingPolicy;\n };\n\n this.onEnableAutoScalingChange = function () {\n // Prevent empty auto-scaling policies from being overwritten by those of their ancestors\n $scope.command.overwriteAncestorAutoScalingPolicy =\n $scope.command.autoscalingPolicy != null && $scope.command.enableAutoScaling === false;\n };\n\n this.setAutoScalingPolicy = function (autoScalingPolicy) {\n $scope.command.autoscalingPolicy = autoScalingPolicy;\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n\n this.specialInstanceProfiles = new Set(['custom', 'buildCustom']);\n\n // This function is called from within React, and without $apply, Angular does not know when it has been called.\n $scope.command.setCustomInstanceViewState = (customInstanceChoices) => {\n $scope.$apply(() => ($scope.command.viewState.customInstance = customInstanceChoices));\n };\n\n if (!$scope.state.requiresTemplateSelection) {\n configureCommand();\n } else {\n $scope.state.loaded = true;\n }\n\n this.templateSelected = () => {\n $scope.state.requiresTemplateSelection = false;\n configureCommand();\n };\n\n $scope.$on('$destroy', gceTagManager.reset);\n },\n ]);\n","import { has } from 'lodash';\n\nimport { TaskExecutor } from '@spinnaker/core';\nimport type { IGceServerGroup } from '../../../domain';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\nexport class StatefulMIGService {\n public static markDiskStateful(applicationName: string, deviceName: string, serverGroup: IGceServerGroup) {\n return TaskExecutor.executeTask({\n application: applicationName,\n description: 'Mark disk as stateful',\n job: [\n {\n cloudProvider: 'gce',\n credentials: serverGroup.account,\n deviceName,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n type: 'setStatefulDisk',\n },\n ],\n });\n }\n\n public static statefullyUpdateBootDisk(applicationName: string, bootImage: string, serverGroup: IGceServerGroup) {\n return TaskExecutor.executeTask({\n application: applicationName,\n description: 'Statefully update boot disk image',\n job: [\n {\n bootImage,\n cloudProvider: 'gce',\n credentials: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n type: 'statefullyUpdateBootImage',\n },\n ],\n });\n }\n\n public static isDiskStateful(deviceName: string, serverGroup: IGceServerGroup): boolean {\n return has(serverGroup, ['statefulPolicy', 'preservedState', 'disks', deviceName]);\n }\n\n public static statefulMigsEnabled(): boolean {\n return GCEProviderSettings.feature.statefulMigsEnabled;\n }\n}\n","import React from 'react';\n\nimport type { Application } from '@spinnaker/core';\nimport { ConfirmationModalService } from '@spinnaker/core';\n\nimport { StatefulMIGService } from './StatefulMIGService';\nimport type { IGceServerGroup } from '../../../domain';\n\ninterface IMarkDiskStatefulButtonProps {\n application: Application;\n deviceName: string;\n serverGroup: IGceServerGroup;\n}\n\nexport function MarkDiskStatefulButton({ application, deviceName, serverGroup }: IMarkDiskStatefulButtonProps) {\n function openConfirmationModal(): void {\n ConfirmationModalService.confirm({\n account: serverGroup.account,\n askForReason: true,\n buttonText: 'Mark as stateful',\n header: `Really mark disk ${deviceName} as stateful?`,\n submitMethod: () => {\n return StatefulMIGService.markDiskStateful(application.name, deviceName, serverGroup);\n },\n taskMonitorConfig: {\n application,\n title: 'Marking disk as stateful',\n },\n });\n }\n\n if (StatefulMIGService.isDiskStateful(deviceName, serverGroup)) {\n return <span> (Marked as Stateful)</span>;\n }\n\n return (\n <button className=\"btn-link\" onClick={() => openConfirmationModal()}>\n Mark as Stateful\n </button>\n );\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps } from '@spinnaker/core';\nimport { FormikFormField, ReactModal, TaskMonitor, WizardModal, WizardPage } from '@spinnaker/core';\n\nimport { StatefulMIGService } from './StatefulMIGService';\nimport type { IGceServerGroup } from '../../../domain';\nimport type { IGceImage } from '../../../image';\nimport { GceImageReader, ImageSelect } from '../../../image';\n\ninterface IUpdateBootImageButtonProps {\n application: Application;\n bootImage: string;\n serverGroup: IGceServerGroup;\n}\n\nexport function UpdateBootImageButton(props: IUpdateBootImageButtonProps) {\n function openUpdateImageModal() {\n const componentProps = { ...props } as IUpdateBootImageModalProps;\n ReactModal.show(UpdateBootImageModal, componentProps, { dialogClassName: 'wizard-modal modal-lg' });\n }\n\n return (\n <button className=\"btn-link\" onClick={openUpdateImageModal}>\n Statefully Update\n </button>\n );\n}\n\ninterface IUpdateBootImageModalProps extends IModalComponentProps, IUpdateBootImageButtonProps {\n application: Application;\n serverGroup: IGceServerGroup;\n}\n\ninterface IUpdateBootImageModalState {\n availableImages: IGceImage[];\n taskMonitor: TaskMonitor;\n}\n\ninterface IUpdateBootImageModalFormValues {\n image: string;\n}\n\nclass UpdateBootImageModal extends React.Component<IUpdateBootImageModalProps, IUpdateBootImageModalState> {\n public constructor(props: IUpdateBootImageModalProps) {\n super(props);\n this.state = {\n availableImages: [],\n taskMonitor: new TaskMonitor({\n application: props.application,\n title: 'Updating Boot Image',\n modalInstance: TaskMonitor.modalInstanceEmulation(() => this.props.dismissModal()),\n }),\n };\n }\n\n public componentDidMount() {\n GceImageReader.findImages({\n account: this.props.serverGroup.account,\n provider: 'gce',\n q: '*',\n }).then((images) => {\n this.setState({ availableImages: images });\n });\n }\n\n private submit = (values: IUpdateBootImageModalFormValues): void => {\n this.state.taskMonitor.submit(() =>\n StatefulMIGService.statefullyUpdateBootDisk(this.props.application.name, values.image, this.props.serverGroup),\n );\n };\n\n public render() {\n return (\n <WizardModal<IUpdateBootImageModalFormValues>\n closeModal={this.submit}\n dismissModal={this.props.dismissModal}\n heading=\"Update Boot Disk Image\"\n initialValues={{ image: this.props.bootImage }}\n submitButtonLabel=\"Update Image\"\n taskMonitor={this.state.taskMonitor}\n render={({ formik, nextIdx, wizard }) => (\n <WizardPage\n label=\"Boot Image\"\n wizard={wizard}\n order={nextIdx()}\n render={() => (\n <FormikFormField\n input={(props) => (\n <div className=\"full-width\" style={{ height: '225px' }}>\n <ImageSelect\n availableImages={this.state.availableImages}\n selectedImage={props.value}\n selectImage={(imageName: string) => formik.setFieldValue('image', imageName)}\n />\n </div>\n )}\n label=\"Boot image name:\"\n name=\"image\"\n required={true}\n />\n )}\n />\n )}\n />\n );\n }\n}\n","import { module } from 'angular';\nimport { get, last } from 'lodash';\nimport React from 'react';\nimport { react2angular } from 'react2angular';\n\nimport type { Application } from '@spinnaker/core';\nimport { withErrorBoundary } from '@spinnaker/core';\n\nimport type { IGceDisk, IGceServerGroup } from '../../domain';\nimport { MarkDiskStatefulButton } from './stateful/MarkDiskStatefulButton';\nimport { StatefulMIGService } from './stateful/StatefulMIGService';\nimport { UpdateBootImageButton } from './stateful/UpdateBootImageButton';\n\ninterface IServerGroupDiskDescriptionProps {\n application: Application;\n serverGroup: IGceServerGroup;\n}\n\nclass ServerGroupDiskDescriptions extends React.Component<IServerGroupDiskDescriptionProps> {\n public render() {\n const { application, serverGroup } = this.props;\n const disks: IGceDisk[] = get(serverGroup, 'launchConfig.instanceTemplate.properties.disks', []);\n const statefulOperationsEnabled: boolean = StatefulMIGService.statefulMigsEnabled();\n const canUpdateBootImage =\n statefulOperationsEnabled &&\n disks.some((disk) => StatefulMIGService.isDiskStateful(disk.deviceName, serverGroup));\n\n return disks.map((disk) => {\n if (disk.boot) {\n return (\n <React.Fragment key={disk.deviceName}>\n <dt>\n Boot Disk\n {canUpdateBootImage && (\n <UpdateBootImageButton\n application={application}\n bootImage={ServerGroupDiskDescriptions.getDiskImageName(disk)}\n serverGroup={serverGroup}\n />\n )}\n </dt>\n <dd>{ServerGroupDiskDescriptions.getDiskTypeLabel(disk)}</dd>\n <dd>{ServerGroupDiskDescriptions.getDiskImageLabel(disk)}</dd>\n </React.Fragment>\n );\n }\n return (\n <React.Fragment key={disk.deviceName}>\n <dt>\n Disk\n {statefulOperationsEnabled && (\n <MarkDiskStatefulButton\n application={application}\n deviceName={disk.deviceName}\n serverGroup={serverGroup}\n />\n )}\n </dt>\n <dd>{ServerGroupDiskDescriptions.getDiskTypeLabel(disk)}</dd>\n <dd>{ServerGroupDiskDescriptions.getDiskImageLabel(disk)}</dd>\n </React.Fragment>\n );\n });\n }\n\n private static translateDiskType = (disk: IGceDisk): string => {\n const diskType = disk.initializeParams.diskType;\n if (diskType === 'pd-ssd') {\n return 'Persistent SSD';\n } else if (diskType === 'local-ssd') {\n return 'Local SSD';\n } else {\n return 'Persistent Std';\n }\n };\n\n private static getDiskTypeLabel = (disk: IGceDisk): string => {\n return `${ServerGroupDiskDescriptions.translateDiskType(disk)}: ${disk.initializeParams.diskSizeGb}GB`;\n };\n\n private static getDiskImageLabel = (disk: IGceDisk): string => {\n return `Image: ${ServerGroupDiskDescriptions.getDiskImageName(disk)}`;\n };\n\n private static getDiskImageName = (disk: IGceDisk): string => {\n return last(get(disk, 'initializeParams.sourceImage', '').split('/'));\n };\n}\n\nexport const GCE_SERVER_GROUP_DISK_DESCRIPTIONS = 'spinnaker.gce.serverGroupDiskDescriptions';\nmodule(GCE_SERVER_GROUP_DISK_DESCRIPTIONS, []).component(\n 'gceServerGroupDiskDescriptions',\n react2angular(withErrorBoundary(ServerGroupDiskDescriptions, 'gceServerGroupDiskDescriptions'), [\n 'application',\n 'serverGroup',\n ]),\n);\n","import { module } from 'angular';\nimport { isEmpty } from 'lodash';\nimport React from 'react';\nimport { react2angular } from 'react2angular';\n\nimport {\n CheckboxInput,\n FormField,\n LayoutProvider,\n NumberInput,\n ReactSelectInput,\n withErrorBoundary,\n} from '@spinnaker/core';\n\nimport type { IGceAutoscalingPolicy, IGceScaleInControl } from '../../../../autoscalingPolicy';\nimport { GceAutoScalingFieldLayout } from '../../../../autoscalingPolicy';\n\nenum maxReplicasUnit {\n fixed = 'fixed',\n percent = 'percent',\n}\n\ninterface IGceScaleInControlsProps {\n policy: IGceAutoscalingPolicy;\n updatePolicy: (policy: IGceAutoscalingPolicy) => void;\n}\n\nconst defaultScaleInControl: IGceScaleInControl = {\n maxScaledInReplicas: {\n fixed: null,\n percent: 0,\n },\n timeWindowSec: 60,\n};\n\nfunction GceScaleInControls({ policy, updatePolicy }: IGceScaleInControlsProps) {\n function updateScaleInControl(scaleInControl: IGceScaleInControl) {\n const scaleInControlExist = Object.keys(scaleInControl).length;\n if (scaleInControlExist) {\n updatePolicy({\n ...policy,\n scaleInControl,\n });\n } else {\n const updatedPolicy: any = policy;\n delete updatedPolicy['scaleInControl'];\n updatePolicy({\n ...updatedPolicy,\n });\n }\n }\n\n function getMaxReplicasUnit(): maxReplicasUnit {\n if (Number.isInteger(policy.scaleInControl.maxScaledInReplicas.percent)) {\n return maxReplicasUnit.percent;\n }\n return maxReplicasUnit.fixed;\n }\n\n return (\n <LayoutProvider value={GceAutoScalingFieldLayout}>\n <div className=\"row\">\n <FormField\n input={(inputProps) => <CheckboxInput {...inputProps} />}\n label=\"Enable scale-in controls\"\n onChange={(e: React.ChangeEvent<any>) => {\n updateScaleInControl(e.target.checked ? defaultScaleInControl : {});\n }}\n value={!isEmpty(policy.scaleInControl)}\n />\n </div>\n {!isEmpty(policy.scaleInControl) && (\n <>\n <div className=\"row\">\n <FormField\n input={(inputProps) => (\n <NumberInput\n {...inputProps}\n min={0}\n max={getMaxReplicasUnit() === maxReplicasUnit.percent ? 100 : null}\n />\n )}\n label=\"Max scaled-in replicas\"\n onChange={(e: React.ChangeEvent<any>) => {\n updateScaleInControl({\n ...policy.scaleInControl,\n maxScaledInReplicas: {\n [getMaxReplicasUnit()]: parseInt(e.target.value, 10),\n },\n });\n }}\n value={policy.scaleInControl.maxScaledInReplicas[getMaxReplicasUnit()]}\n />\n <FormField\n input={(inputProps) => (\n <ReactSelectInput\n {...inputProps}\n clearable={false}\n stringOptions={[maxReplicasUnit.percent, maxReplicasUnit.fixed]}\n />\n )}\n label=\"\"\n onChange={(e: React.ChangeEvent<any>) => {\n updateScaleInControl({\n ...policy.scaleInControl,\n maxScaledInReplicas: {\n [e.target.value]: policy.scaleInControl.maxScaledInReplicas[getMaxReplicasUnit()],\n },\n });\n }}\n value={getMaxReplicasUnit()}\n />\n </div>\n <div className=\"row\">\n <FormField\n input={(inputProps) => <NumberInput {...inputProps} min={60} max={3600} />}\n label=\"Time window (seconds)\"\n onChange={(e: React.ChangeEvent<any>) => {\n updateScaleInControl({\n ...policy.scaleInControl,\n timeWindowSec: parseInt(e.target.value, 10),\n });\n }}\n value={policy.scaleInControl.timeWindowSec}\n />\n </div>\n </>\n )}\n </LayoutProvider>\n );\n}\n\nexport const GCE_SCALE_IN_CONTROLS = 'spinnaker.gce.scaleInControls';\nmodule(GCE_SCALE_IN_CONTROLS, []).component(\n 'gceScaleInControls',\n react2angular(withErrorBoundary(GceScaleInControls, 'gceScaleInControls'), ['policy', 'updatePolicy']),\n);\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\nimport type { IModalService } from 'angular-ui-bootstrap';\n\nimport type { Application, IServerGroup } from '@spinnaker/core';\n\nclass GceAddAutoHealingPolicyButtonCtrl implements IController {\n public application: Application;\n public serverGroup: IServerGroup;\n\n public static $inject = ['$uibModal'];\n constructor(private $uibModal: IModalService) {}\n\n public addAutoHealingPolicy(): void {\n this.$uibModal.open({\n templateUrl: require('./modal/upsertAutoHealingPolicy.modal.html'),\n controller: 'gceUpsertAutoHealingPolicyModalCtrl',\n controllerAs: 'ctrl',\n size: 'md',\n resolve: {\n serverGroup: () => this.serverGroup,\n application: () => this.application,\n },\n });\n }\n}\n\nconst gceAddAutoHealingPolicyButton: IComponentOptions = {\n bindings: {\n application: '<',\n serverGroup: '<',\n },\n template: '<a href ng-click=\"$ctrl.addAutoHealingPolicy()\">Create new autohealing policy</a>',\n controller: GceAddAutoHealingPolicyButtonCtrl,\n};\n\nexport const GCE_ADD_AUTOHEALING_POLICY_BUTTON = 'spinnaker.gce.addAutoHealingPolicyButton.component';\nmodule(GCE_ADD_AUTOHEALING_POLICY_BUTTON, []).component('gceAddAutoHealingPolicyButton', gceAddAutoHealingPolicyButton);\n","import type { IComponentOptions, IController } from 'angular';\nimport { module } from 'angular';\nimport type { IModalService } from 'angular-ui-bootstrap';\n\nimport type { Application } from '@spinnaker/core';\nimport { ConfirmationModalService } from '@spinnaker/core';\nimport type { IGceServerGroup } from '../../../domain/index';\n\nclass GceAutoHealingPolicyDetailsCtrl implements IController {\n public serverGroup: IGceServerGroup;\n public application: Application;\n\n public static $inject = ['$uibModal', 'gceAutoscalingPolicyWriter'];\n constructor(private $uibModal: IModalService, private gceAutoscalingPolicyWriter: any) {}\n\n public editPolicy(): void {\n this.$uibModal.open({\n templateUrl: require('./modal/upsertAutoHealingPolicy.modal.html'),\n controller: 'gceUpsertAutoHealingPolicyModalCtrl',\n controllerAs: 'ctrl',\n size: 'md',\n resolve: {\n application: () => this.application,\n serverGroup: () => this.serverGroup,\n },\n });\n }\n\n public deletePolicy(): void {\n const taskMonitor = {\n application: this.application,\n title: `Deleting autohealing policy for ${this.serverGroup.name}`,\n };\n\n ConfirmationModalService.confirm({\n header: `Really delete autohealer for ${this.serverGroup.name}?`,\n buttonText: 'Delete autohealer',\n account: this.serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: () => this.gceAutoscalingPolicyWriter.deleteAutoHealingPolicy(this.application, this.serverGroup),\n });\n }\n}\n\nconst gceAutoHealingPolicyDetails: IComponentOptions = {\n bindings: { serverGroup: '<', application: '<' },\n template: `\n <dt>\n Health Check\n <help-field key=\"gce.serverGroup.autoHealing\"></help-field>\n </dt>\n <dd>{{$ctrl.serverGroup.autoHealingPolicyHealthCheck}}</dd>\n <dt>\n Initial Delay\n <help-field key=\"gce.serverGroup.initialDelaySec\"></help-field>\n </dt>\n <dd>{{$ctrl.serverGroup.initialDelaySec}} seconds</dd>\n <dt ng-if=\"$ctrl.serverGroup.maxUnavailable\">\n Max Unavailable\n <help-field key=\"gce.serverGroup.maxUnavailable\"></help-field>\n </dt>\n <dd ng-if=\"$ctrl.serverGroup.maxUnavailable\">{{$ctrl.serverGroup.maxUnavailable}}</dd>\n <action-icons class=\"text-right\"\n edit=\"$ctrl.editPolicy()\"\n edit-info=\"Edit Policy\"\n destroy=\"$ctrl.deletePolicy()\"\n destroy-info=\"Delete Policy\">\n </action-icons>`,\n controller: GceAutoHealingPolicyDetailsCtrl,\n};\n\nexport const GCE_AUTOHEALING_POLICY_DETAILS = 'spinnaker.gce.autoHealingPolicyDetails.component';\nmodule(GCE_AUTOHEALING_POLICY_DETAILS, []).component('gceAutoHealingPolicyDetails', gceAutoHealingPolicyDetails);\n","'use strict';\n\nimport * as angular from 'angular';\n\nimport { TaskExecutor } from '@spinnaker/core';\n\nexport const GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE =\n 'spinnaker.gce.serverGroup.details.scalingPolicy.write.service';\nexport const name = GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE; // for backwards compatibility\nangular\n .module(GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE, [])\n .factory('gceAutoscalingPolicyWriter', function () {\n function upsertAutoscalingPolicy(application, serverGroup, policy, params = {}) {\n const job = {\n type: 'upsertScalingPolicy',\n cloudProvider: serverGroup.type,\n credentials: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n autoscalingPolicy: policy,\n };\n angular.extend(job, params);\n\n return TaskExecutor.executeTask({\n application,\n description: 'Upsert scaling policy ' + serverGroup.name,\n job: [job],\n });\n }\n\n function deleteAutoscalingPolicy(application, serverGroup) {\n return TaskExecutor.executeTask({\n application,\n description: 'Delete scaling policy ' + serverGroup.name,\n job: [\n {\n type: 'deleteScalingPolicy',\n cloudProvider: serverGroup.type,\n credentials: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n },\n ],\n });\n }\n\n function upsertAutoHealingPolicy(application, serverGroup, policy, params = {}) {\n const job = {\n type: 'upsertScalingPolicy',\n cloudProvider: serverGroup.type,\n credentials: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n autoHealingPolicy: policy,\n };\n angular.extend(job, params);\n\n return TaskExecutor.executeTask({\n application,\n description: 'Upsert autohealing policy ' + serverGroup.name,\n job: [job],\n });\n }\n\n function deleteAutoHealingPolicy(application, serverGroup) {\n return TaskExecutor.executeTask({\n application,\n description: 'Delete autohealing policy ' + serverGroup.name,\n job: [\n {\n type: 'deleteScalingPolicy',\n cloudProvider: serverGroup.type,\n credentials: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n deleteAutoHealingPolicy: true,\n },\n ],\n });\n }\n\n return { upsertAutoscalingPolicy, deleteAutoscalingPolicy, upsertAutoHealingPolicy, deleteAutoHealingPolicy };\n });\n","import type { IController } from 'angular';\nimport { module } from 'angular';\nimport type { IModalServiceInstance } from 'angular-ui-bootstrap';\nimport { cloneDeep } from 'lodash';\n\nimport type { Application } from '@spinnaker/core';\nimport { TaskMonitor } from '@spinnaker/core';\nimport { GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE } from '../../../../autoscalingPolicy/autoscalingPolicy.write.service';\nimport type { IGceAutoHealingPolicy, IGceServerGroup } from '../../../../domain/index';\nimport type { GceHealthCheckReader } from '../../../../healthCheck/healthCheck.read.service';\nimport { GCE_HEALTH_CHECK_READER } from '../../../../healthCheck/healthCheck.read.service';\nimport type { IGceHealthCheckOption } from '../../../../healthCheck/healthCheckUtils';\nimport { getHealthCheckOptions } from '../../../../healthCheck/healthCheckUtils';\n\nimport './upsertAutoHealingPolicy.modal.less';\n\nclass GceUpsertAutoHealingPolicyModalCtrl implements IController {\n public autoHealingPolicy: IGceAutoHealingPolicy;\n public taskMonitor: TaskMonitor;\n public healthChecks: IGceHealthCheckOption[];\n public action: 'Edit' | 'New';\n public isNew: boolean;\n public submitButtonLabel: string;\n\n public static $inject = [\n '$uibModalInstance',\n 'application',\n 'serverGroup',\n 'gceHealthCheckReader',\n 'gceAutoscalingPolicyWriter',\n ];\n constructor(\n private $uibModalInstance: IModalServiceInstance,\n private application: Application,\n public serverGroup: IGceServerGroup,\n private gceHealthCheckReader: GceHealthCheckReader,\n private gceAutoscalingPolicyWriter: any,\n ) {\n this.initialize();\n }\n\n public submit(): void {\n const submitMethod = () => {\n return this.gceAutoscalingPolicyWriter.upsertAutoHealingPolicy(\n this.application,\n this.serverGroup,\n this.autoHealingPolicy,\n );\n };\n this.taskMonitor.submit(submitMethod);\n }\n\n public cancel(): void {\n this.$uibModalInstance.dismiss();\n }\n\n public setAutoHealingPolicy(autoHealingPolicy: IGceAutoHealingPolicy): void {\n this.autoHealingPolicy = autoHealingPolicy;\n }\n\n public onHealthCheckRefresh(): void {\n this.gceHealthCheckReader.listHealthChecks().then((healthChecks) => {\n const matchingHealthChecks = healthChecks.filter((hc) => hc.account === this.serverGroup.account);\n this.healthChecks = getHealthCheckOptions(matchingHealthChecks);\n });\n }\n\n private initialize(): void {\n this.onHealthCheckRefresh();\n this.action = this.serverGroup.autoHealingPolicy ? 'Edit' : 'New';\n this.isNew = !this.serverGroup.autoHealingPolicy;\n this.submitButtonLabel = this.isNew ? 'Create' : 'Update';\n if (!this.isNew) {\n this.autoHealingPolicy = cloneDeep(this.serverGroup.autoHealingPolicy);\n }\n this.taskMonitor = new TaskMonitor({\n application: this.application,\n title: `${this.action} autohealing policy for ${this.serverGroup.name}`,\n modalInstance: this.$uibModalInstance,\n });\n }\n}\n\nexport const GCE_UPSERT_AUTOHEALING_POLICY_MODAL_CTRL = 'spinnaker.gce.upsertAutoHealingPolicy.modal.controller';\nmodule(GCE_UPSERT_AUTOHEALING_POLICY_MODAL_CTRL, [\n GCE_HEALTH_CHECK_READER,\n GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE,\n]).controller('gceUpsertAutoHealingPolicyModalCtrl', GceUpsertAutoHealingPolicyModalCtrl);\n","'use strict';\n\nimport { module } from 'angular';\nimport { cloneDeep } from 'lodash';\n\nimport { TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE } from '../../../../autoscalingPolicy/autoscalingPolicy.write.service';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/basicSettings/basicSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT } from '../../../../autoscalingPolicy/components/metricSettings/metricSettings.component';\nimport { GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT } from '../../../../autoscalingPolicy/components/scalingSchedules/scalingSchedules.component';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE } from '../../../configure/serverGroup.configure.gce.module';\n\nimport './upsertAutoscalingPolicy.modal.less';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER =\n 'spinnaker.deck.gce.upsertAutoscalingPolicy.modal.controller';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER, [\n GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT,\n GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT,\n]).controller('gceUpsertAutoscalingPolicyModalCtrl', [\n 'policy',\n 'application',\n 'serverGroup',\n '$uibModalInstance',\n 'gceAutoscalingPolicyWriter',\n '$scope',\n function (policy, application, serverGroup, $uibModalInstance, gceAutoscalingPolicyWriter, $scope) {\n [this.action, this.isNew] = policy ? ['Edit', false] : ['New', true];\n this.policy = cloneDeep(policy || {});\n\n this.cancel = $uibModalInstance.dismiss;\n\n this.taskMonitor = new TaskMonitor({\n application: application,\n title: `${this.action} scaling policy for ${serverGroup.name}`,\n modalInstance: $uibModalInstance,\n });\n\n this.save = () => {\n const submitMethod = () =>\n gceAutoscalingPolicyWriter.upsertAutoscalingPolicy(application, serverGroup, this.policy);\n\n this.taskMonitor.submit(submitMethod);\n };\n\n this.updatePolicy = (updatedPolicy) => {\n $scope.$applyAsync(() => {\n this.policy = updatedPolicy;\n });\n };\n },\n]);\n","import { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER } from './modal/upsertAutoscalingPolicy.modal.controller';\n\n('use strict');\n\nexport const GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT =\n 'spinnaker.gce.serverGroup.details.scalingPolicy.addButton';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT, [\n ANGULAR_UI_BOOTSTRAP,\n GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER,\n]).component('gceAddAutoscalingPolicyButton', {\n bindings: {\n serverGroup: '=',\n application: '=',\n },\n template: '<a href ng-click=\"$ctrl.addAutoscalingPolicy()\">Create new scaling policy</a>',\n controller: [\n '$uibModal',\n function ($uibModal) {\n this.addAutoscalingPolicy = () => {\n $uibModal.open({\n templateUrl: require('./modal/upsertAutoscalingPolicy.modal.html'),\n controller: 'gceUpsertAutoscalingPolicyModalCtrl',\n controllerAs: 'ctrl',\n size: 'lg',\n resolve: {\n policy: () => undefined,\n serverGroup: () => this.serverGroup,\n application: () => this.application,\n },\n });\n };\n },\n ],\n});\n","'use strict';\n\nimport { module } from 'angular';\nimport ANGULAR_UI_BOOTSTRAP from 'angular-ui-bootstrap';\n\nimport { ConfirmationModalService, SETTINGS } from '@spinnaker/core';\n\nimport { GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE } from './../../../autoscalingPolicy/autoscalingPolicy.write.service';\nimport { GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT } from '../../configure/wizard/autoScalingPolicy/autoScalingPolicySelector.component';\nimport { GCEProviderSettings } from '../../../gce.settings';\nimport { GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER } from './modal/upsertAutoscalingPolicy.modal.controller';\nexport const GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE =\n 'spinnaker.gce.instance.details.scalingPolicy.directive';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE, [\n ANGULAR_UI_BOOTSTRAP,\n GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE,\n GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER,\n GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT,\n]).component('gceAutoscalingPolicy', {\n bindings: {\n policy: '=',\n application: '=',\n serverGroup: '=',\n },\n templateUrl: require('./autoscalingPolicy.directive.html'),\n controller: [\n '$uibModal',\n 'gceAutoscalingPolicyWriter',\n function ($uibModal, gceAutoscalingPolicyWriter) {\n var scope = this;\n scope.$onInit = function () {\n const policy = scope.policy;\n\n policy.bases = [];\n\n if (policy.cpuUtilization) {\n const basis = {\n description: 'CPU Usage',\n helpKey: 'gce.serverGroup.autoscaling.targetCPUUsage',\n };\n\n if (policy.cpuUtilization.utilizationTarget) {\n basis.targets = [Math.round(policy.cpuUtilization.utilizationTarget * 100) + '%'];\n }\n\n policy.bases.push(basis);\n }\n\n if (policy.loadBalancingUtilization) {\n const basis = {\n description: 'HTTP Load Balancing Usage',\n helpKey: 'gce.serverGroup.autoscaling.targetHTTPLoadBalancingUsage',\n };\n\n if (policy.loadBalancingUtilization.utilizationTarget) {\n basis.targets = [Math.round(policy.loadBalancingUtilization.utilizationTarget * 100) + '%'];\n }\n\n policy.bases.push(basis);\n }\n\n if (policy.customMetricUtilizations) {\n const basis = {\n description: policy.customMetricUtilizations.length > 1 ? 'Monitoring Metrics' : 'Monitoring Metric',\n helpKey: 'gce.serverGroup.autoscaling.targetMetric',\n };\n\n if (policy.customMetricUtilizations.length > 0) {\n basis.targets = [];\n policy.customMetricUtilizations.forEach((metric) => {\n let target = metric.metric + ': ' + metric.utilizationTarget;\n\n if (metric.utilizationTargetType === 'DELTA_PER_SECOND') {\n target += '/sec';\n } else if (metric.utilizationTargetType === 'DELTA_PER_MINUTE') {\n target += '/min';\n }\n\n basis.targets.push(target);\n });\n }\n\n policy.bases.push(basis);\n }\n\n scope.scaleInControlsConfigured =\n policy.scaleInControl &&\n policy.scaleInControl.timeWindowSec &&\n policy.scaleInControl.maxScaledInReplicas &&\n (policy.scaleInControl.maxScaledInReplicas.percent || policy.scaleInControl.maxScaledInReplicas.fixed);\n\n if (scope.scaleInControlsConfigured) {\n scope.maxScaledInReplicasMessage = policy.scaleInControl.maxScaledInReplicas.percent\n ? `${policy.scaleInControl.maxScaledInReplicas.percent}%`\n : `${policy.scaleInControl.maxScaledInReplicas.fixed}`;\n\n scope.timeWindowSecMessage = `${policy.scaleInControl.timeWindowSec} seconds`;\n }\n\n scope.predictiveAutoscalingEnabled =\n GCEProviderSettings.feature.predictiveAutoscaling &&\n policy.cpuUtilization &&\n policy.cpuUtilization.predictiveMethod;\n\n scope.editPolicy = () => {\n $uibModal.open({\n templateUrl: require('./modal/upsertAutoscalingPolicy.modal.html'),\n controller: 'gceUpsertAutoscalingPolicyModalCtrl',\n controllerAs: 'ctrl',\n size: 'lg',\n resolve: {\n policy: () => scope.policy,\n application: () => scope.application,\n serverGroup: () => scope.serverGroup,\n },\n });\n };\n\n scope.deletePolicy = () => {\n const taskMonitor = {\n application: scope.application,\n title: `Deleting autoscaler for ${scope.serverGroup.name}`,\n };\n\n ConfirmationModalService.confirm({\n header: `Really delete autoscaler for ${scope.serverGroup.name}?`,\n buttonText: 'Delete autoscaler',\n account: scope.serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: () =>\n gceAutoscalingPolicyWriter.deleteAutoscalingPolicy(scope.application, scope.serverGroup),\n });\n };\n };\n },\n ],\n});\n","'use strict';\n\nimport * as angular from 'angular';\n\nexport const GOOGLE_COMMON_FOOTER_DIRECTIVE = 'spinnaker.google.footer.directive';\nexport const name = GOOGLE_COMMON_FOOTER_DIRECTIVE; // for backwards compatibility\nangular.module(GOOGLE_COMMON_FOOTER_DIRECTIVE, []).directive('gceFooter', function () {\n return {\n restrict: 'E',\n templateUrl: require('./footer.directive.html'),\n scope: {},\n bindToController: {\n action: '&',\n isValid: '&',\n cancel: '&',\n account: '=?',\n verification: '=?',\n },\n controllerAs: 'vm',\n controller: angular.noop,\n };\n});\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE } from '../../../autoscalingPolicy/autoscalingPolicy.write.service';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT =\n 'spinnaker.deck.gce.serverGroup.details.resizeAutoscalingPolicy.component';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT, [\n GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE,\n ])\n .component('gceResizeAutoscalingPolicy', {\n bindings: {\n serverGroup: '=',\n command: '=',\n formMethods: '=',\n application: '=',\n },\n templateUrl: require('./resizeAutoscalingPolicy.component.html'),\n controller: [\n '$scope',\n 'gceAutoscalingPolicyWriter',\n function ($scope, gceAutoscalingPolicyWriter) {\n // In Angular 1.7 Directive bindings were removed in the constructor, default values now must be instantiated within $onInit\n // See https://docs.angularjs.org/guide/migration#-compile- and https://docs.angularjs.org/guide/migration#migrate1.5to1.6-ng-services-$compile\n this.$onInit = () => {\n const newPolicyBounds = ['newMinNumReplicas', 'newMaxNumReplicas'];\n newPolicyBounds.forEach((prop) => (this.command[prop] = null));\n\n angular.extend(this.formMethods, {\n formIsValid: () =>\n _.every([\n _.chain(newPolicyBounds)\n .map((bound) => this.command[bound] !== null)\n .every()\n .value(),\n $scope.resizeAutoscalingPolicyForm.$valid,\n ]),\n submitMethod: () => {\n return gceAutoscalingPolicyWriter.upsertAutoscalingPolicy(\n this.application,\n this.serverGroup,\n {\n minNumReplicas: this.command.newMinNumReplicas,\n maxNumReplicas: this.command.newMaxNumReplicas,\n },\n {\n reason: this.command.reason,\n interestingHealthProviderNames: this.command.interestingHealthProviderNames,\n },\n );\n },\n });\n };\n },\n ],\n });\n","'use strict';\n\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport { SERVER_GROUP_WRITER } from '@spinnaker/core';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT =\n 'spinnaker.google.serverGroup.details.resize.capacity.component';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT, [SERVER_GROUP_WRITER])\n .component('gceResizeCapacity', {\n bindings: {\n command: '=',\n application: '=',\n serverGroup: '=',\n formMethods: '=',\n },\n templateUrl: require('./resizeCapacity.component.html'),\n controller: [\n '$scope',\n 'serverGroupWriter',\n function ($scope, serverGroupWriter) {\n // In Angular 1.7 Directive bindings were removed in the constructor, default values now must be instantiated within $onInit\n // See https://docs.angularjs.org/guide/migration#-compile- and https://docs.angularjs.org/guide/migration#migrate1.5to1.6-ng-services-$compile\n this.$onInit = () => {\n this.command.newSize = null;\n\n angular.extend(this.formMethods, {\n formIsValid: () => _.every([this.command.newSize !== null, $scope.resizeCapacityForm.$valid]),\n submitMethod: () => {\n return serverGroupWriter.resizeServerGroup(this.serverGroup, this.application, {\n capacity: { min: this.command.newSize, max: this.command.newSize, desired: this.command.newSize },\n serverGroupName: this.serverGroup.name,\n targetSize: this.command.newSize,\n region: this.serverGroup.region,\n interestingHealthProviderNames: this.command.interestingHealthProviderNames,\n reason: this.command.reason,\n });\n },\n });\n };\n },\n ],\n });\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { TaskMonitor } from '@spinnaker/core';\n\nimport { GOOGLE_COMMON_FOOTER_DIRECTIVE } from '../../../common/footer.directive';\nimport { GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT } from './resizeAutoscalingPolicy.component';\nimport { GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT } from './resizeCapacity.component';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER =\n 'spinnaker.google.serverGroup.details.resize.controller';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER, [\n GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT,\n GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT,\n GOOGLE_COMMON_FOOTER_DIRECTIVE,\n]).controller('gceResizeServerGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n 'application',\n 'serverGroup',\n function ($scope, $uibModalInstance, application, serverGroup) {\n $scope.serverGroup = serverGroup;\n $scope.application = application;\n $scope.verification = {};\n $scope.command = {};\n $scope.formMethods = {};\n\n if (application && application.attributes) {\n if (application.attributes.platformHealthOnlyShowOverride && application.attributes.platformHealthOnly) {\n $scope.command.interestingHealthProviderNames = ['Google'];\n }\n\n $scope.command.platformHealthOnlyShowOverride = application.attributes.platformHealthOnlyShowOverride;\n }\n\n this.isValid = function () {\n if (!$scope.verification.verified) {\n return false;\n }\n return $scope.formMethods.formIsValid();\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: 'Resizing ' + serverGroup.name,\n modalInstance: $uibModalInstance,\n });\n\n this.resize = function () {\n this.submitting = true;\n if (!this.isValid()) {\n return;\n }\n\n $scope.taskMonitor.submit($scope.formMethods.submitMethod);\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { SERVER_GROUP_WRITER, TaskMonitor } from '@spinnaker/core';\nimport { GOOGLE_COMMON_FOOTER_DIRECTIVE } from '../../../common/footer.directive';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER =\n 'spinnaker.google.serverGroup.details.rollback.controller';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER, [\n SERVER_GROUP_WRITER,\n GOOGLE_COMMON_FOOTER_DIRECTIVE,\n]).controller('gceRollbackServerGroupCtrl', [\n '$scope',\n '$uibModalInstance',\n 'serverGroupWriter',\n 'application',\n 'serverGroup',\n 'disabledServerGroups',\n function ($scope, $uibModalInstance, serverGroupWriter, application, serverGroup, disabledServerGroups) {\n $scope.serverGroup = serverGroup;\n $scope.disabledServerGroups = disabledServerGroups.sort((a, b) => b.name.localeCompare(a.name));\n $scope.verification = {};\n\n $scope.command = {\n rollbackType: 'EXPLICIT',\n rollbackContext: {\n rollbackServerGroupName: serverGroup.name,\n },\n };\n\n if (application && application.attributes) {\n if (application.attributes.platformHealthOnlyShowOverride && application.attributes.platformHealthOnly) {\n $scope.command.interestingHealthProviderNames = ['Google'];\n }\n\n $scope.command.platformHealthOnlyShowOverride = application.attributes.platformHealthOnlyShowOverride;\n }\n\n this.isValid = function () {\n const command = $scope.command;\n if (!$scope.verification.verified) {\n return false;\n }\n\n return command.rollbackContext.restoreServerGroupName !== undefined;\n };\n\n $scope.taskMonitor = new TaskMonitor({\n application: application,\n title: 'Rollback ' + serverGroup.name,\n modalInstance: $uibModalInstance,\n });\n\n this.rollback = function () {\n this.submitting = true;\n if (!this.isValid()) {\n return;\n }\n\n const submitMethod = function () {\n return serverGroupWriter.rollbackServerGroup(serverGroup, application, $scope.command);\n };\n\n $scope.taskMonitor.submit(submitMethod);\n };\n\n this.cancel = function () {\n $uibModalInstance.dismiss();\n };\n },\n]);\n","'use strict';\n\nimport UIROUTER_ANGULARJS from '@uirouter/angularjs';\nimport * as angular from 'angular';\nimport _ from 'lodash';\n\nimport {\n AccountService,\n ClusterTargetBuilder,\n ConfirmationModalService,\n FirewallLabels,\n NetworkReader,\n SERVER_GROUP_WRITER,\n ServerGroupReader,\n ServerGroupTemplates,\n ServerGroupWarningMessageService,\n} from '@spinnaker/core';\n\nimport { GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT } from './autoscalingPolicy/addAutoscalingPolicyButton.component';\nimport { GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE } from './autoscalingPolicy/autoscalingPolicy.directive';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from '../../common/xpnNaming.gce.service';\nimport '../configure/serverGroup.configure.gce.module';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE } from '../configure/serverGroupCommandBuilder.service';\nimport { GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER } from './resize/resizeServerGroup.controller';\nimport { GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER } from './rollback/rollbackServerGroup.controller';\n\nimport './serverGroupDetails.less';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER =\n 'spinnaker.serverGroup.details.gce.controller';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER; // for backwards compatibility\nangular\n .module(GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER, [\n UIROUTER_ANGULARJS,\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE,\n SERVER_GROUP_WRITER,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER,\n GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER,\n GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE,\n GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT,\n ])\n .controller('gceServerGroupDetailsCtrl', [\n '$scope',\n '$state',\n '$templateCache',\n '$interpolate',\n 'app',\n 'serverGroup',\n 'gceServerGroupCommandBuilder',\n '$uibModal',\n 'serverGroupWriter',\n 'gceXpnNamingService',\n function (\n $scope,\n $state,\n $templateCache,\n $interpolate,\n app,\n serverGroup,\n gceServerGroupCommandBuilder,\n $uibModal,\n serverGroupWriter,\n gceXpnNamingService,\n ) {\n this.state = {\n loading: true,\n };\n\n this.firewallsLabel = FirewallLabels.get('Firewalls');\n\n this.application = app;\n\n const extractServerGroupSummary = () => {\n let summary = _.find(app.serverGroups.data, (toCheck) => {\n return (\n toCheck.name === serverGroup.name &&\n toCheck.account === serverGroup.accountId &&\n toCheck.region === serverGroup.region\n );\n });\n if (!summary) {\n app.loadBalancers.data.some((loadBalancer) => {\n if (loadBalancer.account === serverGroup.accountId && loadBalancer.region === serverGroup.region) {\n return loadBalancer.serverGroups.some((possibleServerGroup) => {\n if (possibleServerGroup.name === serverGroup.name) {\n summary = possibleServerGroup;\n return true;\n }\n });\n }\n });\n }\n return summary;\n };\n\n const autoClose = () => {\n if ($scope.$$destroyed) {\n return;\n }\n $state.go('^', { allowModalToStayOpen: true }, { location: 'replace' });\n };\n\n const cancelLoader = () => {\n this.state.loading = false;\n };\n\n const retrieveServerGroup = () => {\n const summary = extractServerGroupSummary();\n return ServerGroupReader.getServerGroup(\n app.name,\n serverGroup.accountId,\n serverGroup.region,\n serverGroup.name,\n ).then((details) => {\n cancelLoader();\n\n angular.extend(details, summary);\n // it's possible the summary was not found because the clusters are still loading\n details.account = serverGroup.accountId;\n\n this.serverGroup = details;\n\n if (!_.isEmpty(this.serverGroup)) {\n if (details.securityGroups) {\n this.securityGroups = _.chain(details.securityGroups)\n .map((id) => {\n return (\n _.find(app.securityGroups.data, { accountName: serverGroup.accountId, region: 'global', id: id }) ||\n _.find(app.securityGroups.data, { accountName: serverGroup.accountId, region: 'global', name: id })\n );\n })\n .compact()\n .value();\n }\n\n this.serverGroup.zones.sort();\n\n const projectId = gceXpnNamingService.deriveProjectId(this.serverGroup.launchConfig.instanceTemplate);\n this.serverGroup.logsLink =\n 'https://console.developers.google.com/project/' +\n projectId +\n '/logs?advancedFilter=resource.type=(gce_instance_group_manager OR gce_instance OR gce_autoscaler)%0A\"' +\n this.serverGroup.name +\n '\"';\n\n this.serverGroup.network = getNetwork(projectId);\n retrieveSubnet(projectId);\n determineAssociatePublicIPAddress();\n\n findStartupScript();\n prepareAvailabilityPolicies();\n prepareShieldedVmConfig();\n prepareAutoHealingPolicy();\n prepareAuthScopes();\n prepareCurrentActions();\n augmentTagsWithHelp();\n configureEntityTagTargets();\n processLabels();\n } else {\n autoClose();\n }\n }, autoClose);\n };\n\n const findStartupScript = () => {\n if (_.has(this.serverGroup, 'launchConfig.instanceTemplate.properties.metadata.items')) {\n const metadataItems = this.serverGroup.launchConfig.instanceTemplate.properties.metadata.items;\n const startupScriptItem = _.find(metadataItems, (metadataItem) => {\n return metadataItem.key === 'startup-script';\n });\n\n if (startupScriptItem) {\n this.serverGroup.startupScript = startupScriptItem.value;\n }\n }\n };\n\n const prepareAvailabilityPolicies = () => {\n if (_.has(this.serverGroup, 'launchConfig.instanceTemplate.properties.scheduling')) {\n const scheduling = this.serverGroup.launchConfig.instanceTemplate.properties.scheduling;\n\n this.serverGroup.availabilityPolicies = {\n preemptibility: scheduling.preemptible ? 'On' : 'Off',\n automaticRestart: scheduling.automaticRestart ? 'On' : 'Off',\n onHostMaintenance: scheduling.onHostMaintenance === 'MIGRATE' ? 'Migrate' : 'Terminate',\n };\n }\n };\n\n const prepareShieldedVmConfig = () => {\n if (_.has(this.serverGroup, 'launchConfig.instanceTemplate.properties.shieldedVmConfig')) {\n const shieldedVmConfig = this.serverGroup.launchConfig.instanceTemplate.properties.shieldedVmConfig;\n\n this.serverGroup.shieldedVmConfig = {\n enableSecureBoot: shieldedVmConfig.enableSecureBoot ? 'On' : 'Off',\n enableVtpm: shieldedVmConfig.enableVtpm ? 'On' : 'Off',\n enableIntegrityMonitoring: shieldedVmConfig.enableIntegrityMonitoring ? 'On' : 'Off',\n };\n }\n };\n\n const prepareAutoHealingPolicy = () => {\n if (this.serverGroup.autoHealingPolicy) {\n const autoHealingPolicy = this.serverGroup.autoHealingPolicy;\n const healthCheckUrl = autoHealingPolicy.healthCheck;\n\n this.serverGroup.autoHealingPolicyHealthCheck = healthCheckUrl ? _.last(healthCheckUrl.split('/')) : null;\n this.serverGroup.initialDelaySec = autoHealingPolicy.initialDelaySec;\n\n if (autoHealingPolicy.maxUnavailable) {\n if (typeof autoHealingPolicy.maxUnavailable.percent === 'number') {\n this.serverGroup.maxUnavailable = autoHealingPolicy.maxUnavailable.percent + '%';\n } else {\n this.serverGroup.maxUnavailable = autoHealingPolicy.maxUnavailable.fixed + ' instances';\n }\n }\n }\n };\n\n const prepareAuthScopes = () => {\n if (_.has(this.serverGroup, 'launchConfig.instanceTemplate.properties.serviceAccounts')) {\n const serviceAccounts = this.serverGroup.launchConfig.instanceTemplate.properties.serviceAccounts;\n if (serviceAccounts.length) {\n const serviceAccount = this.serverGroup.launchConfig.instanceTemplate.properties.serviceAccounts[0];\n\n this.serverGroup.serviceAccountEmail = serviceAccount.email;\n this.serverGroup.authScopes = _.map(serviceAccount.scopes, (authScope) => {\n return authScope.replace('https://www.googleapis.com/auth/', '');\n });\n }\n }\n };\n\n const prepareCurrentActions = () => {\n if (this.serverGroup.currentActions) {\n this.serverGroup.currentActionsSummary = [];\n\n _.forOwn(this.serverGroup.currentActions, (value, key) => {\n if (key !== 'none' && value) {\n this.serverGroup.currentActionsSummary.push({ action: _.startCase(key), count: value });\n }\n });\n\n if (!this.serverGroup.currentActionsSummary.length) {\n delete this.serverGroup.currentActionsSummary;\n }\n }\n };\n\n const augmentTagsWithHelp = () => {\n if (_.has(this.serverGroup, 'launchConfig.instanceTemplate.properties.tags.items') && this.securityGroups) {\n const helpMap = {};\n\n this.serverGroup.launchConfig.instanceTemplate.properties.tags.items.forEach((tag) => {\n const securityGroupsMatches = _.filter(this.securityGroups, (securityGroup) =>\n _.includes(securityGroup.targetTags, tag),\n );\n const securityGroupMatchNames = _.map(securityGroupsMatches, 'name');\n\n if (!_.isEmpty(securityGroupMatchNames)) {\n const groupOrGroups = securityGroupMatchNames.length > 1 ? 'groups' : 'group';\n\n helpMap[tag] =\n 'This tag associates this server group with security ' +\n groupOrGroups +\n ' <em>' +\n securityGroupMatchNames.join(', ') +\n '</em>.';\n }\n });\n\n this.serverGroup.launchConfig.instanceTemplate.properties.tags.helpMap = helpMap;\n }\n };\n\n const processLabels = () => {\n if (!_.size(this.serverGroup.instanceTemplateLabels)) {\n delete this.serverGroup.instanceTemplateLabels;\n }\n };\n\n const getNetwork = (projectId) => {\n const networkUrl = _.get(\n this.serverGroup,\n 'launchConfig.instanceTemplate.properties.networkInterfaces[0].network',\n );\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, networkUrl);\n };\n\n const retrieveSubnet = (projectId) => {\n NetworkReader.listNetworksByProvider('gce').then((networks) => {\n const autoCreateSubnets = _.chain(networks)\n .filter({ account: this.serverGroup.account, id: this.serverGroup.network })\n .map('autoCreateSubnets')\n .head()\n .value();\n\n if (autoCreateSubnets) {\n this.serverGroup.subnet = '(Auto-select)';\n } else {\n const subnetUrl = _.get(\n this.serverGroup,\n 'launchConfig.instanceTemplate.properties.networkInterfaces[0].subnetwork',\n );\n this.serverGroup.subnet = gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, subnetUrl);\n }\n });\n };\n\n const determineAssociatePublicIPAddress = () => {\n this.serverGroup.associatePublicIPAddress = _.has(\n this.serverGroup,\n 'launchConfig.instanceTemplate.properties.networkInterfaces[0].accessConfigs',\n );\n };\n\n retrieveServerGroup().then(() => {\n // If the user navigates away from the view before the initial retrieveServerGroup call completes,\n // do not bother subscribing to the refresh\n if (!$scope.$$destroyed) {\n app.serverGroups.onRefresh($scope, retrieveServerGroup);\n }\n });\n\n this.destroyServerGroup = () => {\n const serverGroup = this.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Destroying ' + serverGroup.name,\n onTaskComplete: () => {\n if ($state.includes('**.serverGroup', stateParams)) {\n $state.go('^');\n }\n },\n };\n\n const submitMethod = (params) => serverGroupWriter.destroyServerGroup(serverGroup, app, params);\n\n const stateParams = {\n name: serverGroup.name,\n accountId: serverGroup.account,\n region: serverGroup.region,\n };\n\n const confirmationModalParams = {\n header: 'Really destroy ' + serverGroup.name + '?',\n buttonText: 'Destroy ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n submitMethod: submitMethod,\n askForReason: true,\n platformHealthOnlyShowOverride: app.attributes.platformHealthOnlyShowOverride,\n platformHealthType: 'Google',\n };\n\n ServerGroupWarningMessageService.addDestroyWarningMessage(app, serverGroup, confirmationModalParams);\n\n if (app.attributes.platformHealthOnlyShowOverride && app.attributes.platformHealthOnly) {\n confirmationModalParams.interestingHealthProviderNames = ['Google'];\n }\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.disableServerGroup = () => {\n const serverGroup = this.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Disabling ' + serverGroup.name,\n };\n\n const submitMethod = (params) => serverGroupWriter.disableServerGroup(serverGroup, app, params);\n\n const confirmationModalParams = {\n header: 'Really disable ' + serverGroup.name + '?',\n buttonText: 'Disable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n platformHealthOnlyShowOverride: app.attributes.platformHealthOnlyShowOverride,\n platformHealthType: 'Google',\n submitMethod: submitMethod,\n askForReason: true,\n };\n\n ServerGroupWarningMessageService.addDisableWarningMessage(app, serverGroup, confirmationModalParams);\n\n if (app.attributes.platformHealthOnlyShowOverride && app.attributes.platformHealthOnly) {\n confirmationModalParams.interestingHealthProviderNames = ['Google'];\n }\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.enableServerGroup = () => {\n const serverGroup = this.serverGroup;\n\n const taskMonitor = {\n application: app,\n title: 'Enabling ' + serverGroup.name,\n };\n\n const submitMethod = (params) => serverGroupWriter.enableServerGroup(serverGroup, app, params);\n\n const confirmationModalParams = {\n header: 'Really enable ' + serverGroup.name + '?',\n buttonText: 'Enable ' + serverGroup.name,\n account: serverGroup.account,\n taskMonitorConfig: taskMonitor,\n platformHealthOnlyShowOverride: app.attributes.platformHealthOnlyShowOverride,\n platformHealthType: 'Google',\n submitMethod: submitMethod,\n askForReason: true,\n };\n\n if (app.attributes.platformHealthOnlyShowOverride && app.attributes.platformHealthOnly) {\n confirmationModalParams.interestingHealthProviderNames = ['Google'];\n }\n\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n this.rollbackServerGroup = () => {\n $uibModal.open({\n templateUrl: require('./rollback/rollbackServerGroup.html'),\n controller: 'gceRollbackServerGroupCtrl as ctrl',\n resolve: {\n serverGroup: () => this.serverGroup,\n disabledServerGroups: () => {\n const cluster = _.find(app.clusters, {\n name: this.serverGroup.cluster,\n account: this.serverGroup.account,\n });\n return _.filter(cluster.serverGroups, { isDisabled: true, region: this.serverGroup.region });\n },\n application: () => app,\n },\n });\n };\n\n this.resizeServerGroup = () => {\n $uibModal.open({\n templateUrl: require('./resize/resizeServerGroup.html'),\n controller: 'gceResizeServerGroupCtrl as ctrl',\n resolve: {\n serverGroup: () => {\n return this.serverGroup;\n },\n application: () => {\n return app;\n },\n },\n });\n };\n\n this.cloneServerGroup = (serverGroup) => {\n $uibModal.open({\n templateUrl: require('../configure/wizard/serverGroupWizard.html'),\n controller: 'gceCloneServerGroupCtrl as ctrl',\n size: 'lg',\n resolve: {\n title: () => {\n return 'Clone ' + serverGroup.name;\n },\n application: () => {\n return app;\n },\n serverGroup: () => {\n return serverGroup;\n },\n serverGroupCommand: () => {\n return gceServerGroupCommandBuilder.buildServerGroupCommandFromExisting(app, serverGroup);\n },\n },\n });\n };\n\n this.showStartupScript = () => {\n $scope.userDataModalTitle = 'Startup Script';\n $scope.serverGroup = { name: this.serverGroup.name };\n $scope.userData = this.serverGroup.startupScript;\n $uibModal.open({\n templateUrl: ServerGroupTemplates.userData,\n scope: $scope,\n });\n };\n\n this.buildJenkinsLink = () => {\n if (this.serverGroup && this.serverGroup.buildInfo && this.serverGroup.buildInfo.buildInfoUrl) {\n return this.serverGroup.buildInfo.buildInfoUrl;\n } else if (this.serverGroup && this.serverGroup.buildInfo && this.serverGroup.buildInfo.jenkins) {\n const jenkins = this.serverGroup.buildInfo.jenkins;\n return jenkins.host + 'job/' + jenkins.name + '/' + jenkins.number;\n }\n return null;\n };\n\n this.truncateCommitHash = () => {\n if (this.serverGroup && this.serverGroup.buildInfo && this.serverGroup.buildInfo.commit) {\n return this.serverGroup.buildInfo.commit.substring(0, 8);\n }\n return null;\n };\n\n const configureEntityTagTargets = () => {\n this.entityTagTargets = ClusterTargetBuilder.buildClusterTargets(this.serverGroup);\n };\n },\n ]);\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { GCE_ADD_AUTOHEALING_POLICY_BUTTON } from './autoHealingPolicy/addAutoHealingPolicyButton.component';\nimport { GCE_AUTOHEALING_POLICY_DETAILS } from './autoHealingPolicy/autoHealingPolicy.component';\nimport { GCE_UPSERT_AUTOHEALING_POLICY_MODAL_CTRL } from './autoHealingPolicy/modal/upsertAutoHealingPolicy.modal.controller';\nimport { GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER } from './serverGroupDetails.gce.controller';\n\nexport const GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE = 'spinnaker.serverGroup.details.gce';\nexport const name = GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE; // for backwards compatibility\nmodule(GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE, [\n GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER,\n GCE_ADD_AUTOHEALING_POLICY_BUTTON,\n GCE_UPSERT_AUTOHEALING_POLICY_MODAL_CTRL,\n GCE_AUTOHEALING_POLICY_DETAILS,\n]);\n","'use strict';\n\nimport { module } from 'angular';\nimport _ from 'lodash';\n\nimport { NetworkReader } from '@spinnaker/core';\n\nexport const GOOGLE_SUBNET_SUBNET_RENDERER = 'spinnaker.gce.subnet.renderer';\nexport const name = GOOGLE_SUBNET_SUBNET_RENDERER; // for backwards compatibility\nmodule(GOOGLE_SUBNET_SUBNET_RENDERER, []).factory('gceSubnetRenderer', function () {\n let gceNetworks;\n\n NetworkReader.listNetworksByProvider('gce').then(function (networks) {\n gceNetworks = networks;\n });\n\n function render(serverGroup) {\n if (serverGroup.subnet) {\n return serverGroup.subnet;\n } else {\n const autoCreateSubnets = _.chain(gceNetworks)\n .filter({ account: serverGroup.account, name: serverGroup.network })\n .map('autoCreateSubnets')\n .head()\n .value();\n\n return autoCreateSubnets ? '(Auto-select)' : '[none]';\n }\n }\n\n return {\n render: render,\n };\n});\n","'use strict';\n\nimport { module } from 'angular';\n\nimport { ApplicationNameValidator, FirewallLabels } from '@spinnaker/core';\n\nexport const GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR = 'spinnaker.gce.validation.applicationName';\nexport const name = GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR; // for backwards compatibility\nmodule(GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR, [])\n .factory('gceApplicationNameValidator', function () {\n function validateSpecialCharacters(name, errors) {\n const pattern = /^([a-zA-Z][a-zA-Z0-9]*)?$/;\n if (!pattern.test(name)) {\n errors.push(\n 'The application name must begin with a letter and must contain only letters or digits. No ' +\n 'special characters are allowed.',\n );\n }\n }\n\n function validateLength(name, warnings, errors) {\n // GCE resource names must comply with https://www.ietf.org/rfc/rfc1035.txt\n // [a-z]([-a-z0-9]*[a-z0-9])?\n const maxResourceNameLength = 63;\n\n // e.g. $appName-$stack-$detail-tp-1451531076528 and $appName-$stack-$detail-hc-1451531076528\n const loadBalancerNameSuffixLength = 17;\n const maxLengthForLoadBalancers = maxResourceNameLength - loadBalancerNameSuffixLength;\n\n // e.g. $appName-$stack-$detail-v000-abcd\n const instanceNameSuffixLength = 10;\n const maxLengthForServerGroups = maxResourceNameLength - instanceNameSuffixLength;\n\n if (name.length > maxResourceNameLength) {\n errors.push('The maximum length for an application in Google is 63 characters.');\n return;\n }\n\n if (name.length > maxLengthForLoadBalancers - 12) {\n if (name.length > maxLengthForLoadBalancers) {\n warnings.push(`You will not be able to create a Google load balancer for this application if the\n application's name is longer than ${maxLengthForLoadBalancers} characters (currently: ${name.length}\n characters).`);\n } else if (name.length >= maxLengthForLoadBalancers - 2) {\n warnings.push(\n 'With separators (\"-\"), you will not be able to include a stack and detail field for ' +\n 'Google load balancers.',\n );\n } else {\n const remaining = maxLengthForLoadBalancers - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google load balancers, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n\n if (name.length > maxLengthForServerGroups - 12) {\n if (name.length > maxLengthForServerGroups) {\n warnings.push(`You will not be able to create a Google server group for this application if the\n application's name is longer than ${maxLengthForServerGroups} characters (currently: ${name.length}\n characters).`);\n } else if (name.length >= maxLengthForServerGroups - 2) {\n warnings.push(\n 'With separators (\"-\"), you will not be able to include a stack and detail field for ' +\n 'Google server groups.',\n );\n } else {\n const remaining = maxLengthForServerGroups - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google server groups, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n\n if (name.length > maxResourceNameLength - 12) {\n if (name.length >= maxResourceNameLength - 2) {\n warnings.push(\n `With separators (\"-\"), you will not be able to include a stack and detail field for Google ${FirewallLabels.get(\n 'firewalls',\n )}.`,\n );\n } else {\n const remaining = maxResourceNameLength - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google ${FirewallLabels.get(\n 'firewalls',\n )}, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n }\n\n function validate(name) {\n const warnings = [];\n const errors = [];\n\n if (name && name.length) {\n validateSpecialCharacters(name, errors);\n validateLength(name, warnings, errors);\n }\n\n return {\n warnings: warnings,\n errors: errors,\n };\n }\n\n return {\n validate: validate,\n };\n })\n .run([\n 'gceApplicationNameValidator',\n function (gceApplicationNameValidator) {\n ApplicationNameValidator.registerValidator('gce', gceApplicationNameValidator);\n },\n ]);\n","import { module } from 'angular';\n\nimport { CloudProviderRegistry, DeploymentStrategyRegistry } from '@spinnaker/core';\n\nimport { GCE_PREDICTIVE_AUTOSCALING } from './autoscalingPolicy/components/metricSettings/GcePredictiveAutoscaling';\nimport { GOOGLE_CACHE_CACHECONFIGURER_SERVICE } from './cache/cacheConfigurer.service';\nimport { GOOGLE_COMMON_XPNNAMING_GCE_SERVICE } from './common/xpnNaming.gce.service';\nimport './help/gce.help';\nimport { GceImageReader } from './image';\nimport { GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER } from './instance/custom/customInstance.filter';\nimport { GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER } from './instance/details/instance.details.controller';\nimport { GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE } from './instance/gceInstanceType.service';\nimport { GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER } from './instance/gceMultiInstanceTask.transformer';\nimport { IAP_INTERCEPTOR } from './interceptors/iap.interceptor';\nimport { GCE_LOAD_BALANCER_CHOICE_MODAL } from './loadBalancer/configure/choice/gceLoadBalancerChoice.modal';\nimport { openGCEPipelineLoadBalancerModal } from './loadBalancer/configure/choice/gceLoadBalancerPipelineModal';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER } from './loadBalancer/configure/http/createHttpLoadBalancer.controller';\nimport { GCE_INTERNAL_LOAD_BALANCER_CTRL } from './loadBalancer/configure/internal/gceCreateInternalLoadBalancer.controller';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER } from './loadBalancer/configure/internalhttp/createInternalHttpLoadBalancer.controller';\nimport { GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER } from './loadBalancer/configure/network/createLoadBalancer.controller';\nimport { GCE_SSL_LOAD_BALANCER_CTRL } from './loadBalancer/configure/ssl/gceCreateSslLoadBalancer.controller';\nimport { GCE_TCP_LOAD_BALANCER_CTRL } from './loadBalancer/configure/tcp/gceCreateTcpLoadBalancer.controller';\nimport { GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER } from './loadBalancer/details/loadBalancerDetail.controller';\nimport { LOAD_BALANCER_SET_TRANSFORMER } from './loadBalancer/loadBalancer.setTransformer';\nimport { GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER } from './loadBalancer/loadBalancer.transformer';\nimport logo from './logo/gce.logo.png';\nimport { GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE } from './pipeline/stages/bake/gceBakeStage';\nimport { GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE } from './pipeline/stages/cloneServerGroup/gceCloneServerGroupStage';\nimport { GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE } from './pipeline/stages/destroyAsg/gceDestroyAsgStage';\nimport { GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE } from './pipeline/stages/disableAsg/gceDisableAsgStage';\nimport { GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE } from './pipeline/stages/disableCluster/gceDisableClusterStage';\nimport { GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE } from './pipeline/stages/enableAsg/gceEnableAsgStage';\nimport { GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE } from './pipeline/stages/findAmi/gceFindAmiStage';\nimport { GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE } from './pipeline/stages/findImageFromTags/gceFindImageFromTagsStage';\nimport { GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE } from './pipeline/stages/resizeAsg/gceResizeAsgStage';\nimport { GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE } from './pipeline/stages/scaleDownCluster/gceScaleDownClusterStage';\nimport { GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE } from './pipeline/stages/shrinkCluster/gceShrinkClusterStage';\nimport { GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE } from './pipeline/stages/tagImage/gceTagImageStage';\nimport { GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER } from './securityGroup/configure/createSecurityGroup.controller';\nimport { GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER } from './securityGroup/configure/editSecurityGroup.controller';\nimport { GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER } from './securityGroup/details/securityGroupDetail.controller';\nimport { GOOGLE_SECURITYGROUP_SECURITYGROUP_READER } from './securityGroup/securityGroup.reader';\nimport { GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER } from './securityGroup/securityGroup.transformer';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE } from './serverGroup/configure/serverGroup.configure.gce.module';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE } from './serverGroup/configure/serverGroupCommandBuilder.service';\nimport { GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER } from './serverGroup/configure/wizard/cloneServerGroup.gce.controller';\nimport { GCE_SERVER_GROUP_DISK_DESCRIPTIONS } from './serverGroup/details/ServerGroupDiskDescriptions';\nimport { GCE_SCALE_IN_CONTROLS } from './serverGroup/details/autoscalingPolicy/modal/GceScaleInControls';\nimport { GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE } from './serverGroup/details/serverGroup.details.gce.module';\nimport { GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER } from './serverGroup/serverGroup.transformer';\nimport { GOOGLE_SUBNET_SUBNET_RENDERER } from './subnet/subnet.renderer';\nimport { GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR } from './validation/applicationName.validator';\n\nimport './logo/gce.logo.less';\n\nexport const GOOGLE_MODULE = 'spinnaker.gce';\nmodule(GOOGLE_MODULE, [\n LOAD_BALANCER_SET_TRANSFORMER,\n GCE_INTERNAL_LOAD_BALANCER_CTRL,\n GCE_LOAD_BALANCER_CHOICE_MODAL,\n GCE_SSL_LOAD_BALANCER_CTRL,\n GCE_TCP_LOAD_BALANCER_CTRL,\n IAP_INTERCEPTOR,\n GCE_SERVER_GROUP_DISK_DESCRIPTIONS,\n GCE_SCALE_IN_CONTROLS,\n GCE_PREDICTIVE_AUTOSCALING,\n GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE,\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE,\n GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER,\n GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE,\n GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER,\n GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE,\n GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE,\n GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE,\n GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE,\n GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE,\n GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE,\n GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE,\n GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE,\n GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE,\n GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE,\n GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE,\n GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE,\n GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE,\n GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER,\n GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER,\n GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER,\n GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER,\n GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER,\n GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER,\n GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER,\n GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER,\n GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER,\n GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER,\n GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER,\n GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER,\n GOOGLE_SECURITYGROUP_SECURITYGROUP_READER,\n GOOGLE_SUBNET_SUBNET_RENDERER,\n GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR,\n GOOGLE_CACHE_CACHECONFIGURER_SERVICE,\n GOOGLE_COMMON_XPNNAMING_GCE_SERVICE,\n]).config(() => {\n CloudProviderRegistry.registerProvider('gce', {\n name: 'Google',\n logo: {\n path: logo,\n },\n cache: {\n configurer: 'gceCacheConfigurer',\n },\n image: {\n reader: GceImageReader,\n },\n serverGroup: {\n transformer: 'gceServerGroupTransformer',\n detailsTemplateUrl: require('./serverGroup/details/serverGroupDetails.html'),\n detailsController: 'gceServerGroupDetailsCtrl',\n cloneServerGroupTemplateUrl: require('./serverGroup/configure/wizard/serverGroupWizard.html'),\n cloneServerGroupController: 'gceCloneServerGroupCtrl',\n commandBuilder: 'gceServerGroupCommandBuilder',\n configurationService: 'gceServerGroupConfigurationService',\n },\n instance: {\n instanceTypeService: 'gceInstanceTypeService',\n detailsTemplateUrl: require('./instance/details/instanceDetails.html'),\n detailsController: 'gceInstanceDetailsCtrl',\n multiInstanceTaskTransformer: 'gceMultiInstanceTaskTransformer',\n customInstanceBuilderTemplateUrl: require('./serverGroup/configure/wizard/customInstance/customInstanceBuilder.html'),\n },\n loadBalancer: {\n transformer: 'gceLoadBalancerTransformer',\n setTransformer: 'gceLoadBalancerSetTransformer',\n detailsTemplateUrl: require('./loadBalancer/details/loadBalancerDetails.html'),\n detailsController: 'gceLoadBalancerDetailsCtrl',\n createLoadBalancerTemplateUrl: require('./loadBalancer/configure/choice/gceLoadBalancerChoice.modal.html'),\n createLoadBalancerController: 'gceLoadBalancerChoiceCtrl',\n pipelineCreateLoadBalancerModal: openGCEPipelineLoadBalancerModal,\n },\n securityGroup: {\n transformer: 'gceSecurityGroupTransformer',\n reader: 'gceSecurityGroupReader',\n detailsTemplateUrl: require('./securityGroup/details/securityGroupDetail.html'),\n detailsController: 'gceSecurityGroupDetailsCtrl',\n createSecurityGroupTemplateUrl: require('./securityGroup/configure/createSecurityGroup.html'),\n createSecurityGroupController: 'gceCreateSecurityGroupCtrl',\n },\n subnet: {\n renderer: 'gceSubnetRenderer',\n },\n snapshotsEnabled: true,\n applicationProviderFields: {\n templateUrl: require('./applicationProviderFields/gceFields.html'),\n },\n });\n});\n\nDeploymentStrategyRegistry.registerProvider('gce', ['custom', 'redblack']);\n","export default \"gce.logo2ae85d8704b1d6b8.png\""],"names":["styleInject","css","ref","insertAt","document","head","getElementsByTagName","style","createElement","type","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","GceAutoScalingFieldLayout","props","label","help","input","actions","validation","required","showLabel","isEmpty","hidden","messageNode","className","React","GcePredictiveMethod","GCEProviderSettings","defaults","SETTINGS","providers","gce","feature","resetToOriginal","resetProvider","GCE_PREDICTIVE_AUTOSCALING","module","component","react2angular","withErrorBoundary","policy","updatePolicy","_a","predictiveAutoscaling","LayoutProvider","value","FormField","HelpField","id","inputProps","CheckboxInput","onChange","e","predictiveMethod","target","checked","STANDARD","NONE","cpuUtilization","GCE_ADDRESS_READER","service","listAddresses","region","this","then","addresses","filter","address","SearchService","search","q","allowShortQuery","InfrastructureCaches","get","searchResults","results","result","provider","map","JSON","parse","account","catch","GOOGLE_BACKENDSERVICE_BACKENDSERVICE_READER","factory","listBackendServices","kind","services","REST","useCache","query","GCE_HEALTH_CHECK_READER","listHealthChecks","healthChecks","healthCheck","healthCheckType","uniqWith","checkA","checkB","name","GOOGLE_CACHE_CACHECONFIGURER_SERVICE","gceAddressReader","gceBackendServiceReader","gceCertificateReader","gceHealthCheckReader","config","Object","create","initializers","backendServices","certificates","listCertificates","GOOGLE_COMMON_XPNNAMING_GCE_SERVICE","deriveProjectId","resourceWithSelfLink","pathSegments","selfLink","split","indexOf","decorateXpnResourceIfNecessary","projectId","xpnResource","xpnResourcePathSegments","xpnResourceProjectId","xpnResourceName","_","last","helpContents","keys","forEach","key","HelpContentsRegistry","register","GceImageReader","findImages","params","getImage","ImageSelect","Component","constructor","super","arguments","loadOptions","inputValue","Promise","resolve","length","options","complete","chain","availableImages","i","imageName","toLowerCase","includes","take","render","Async","cache","clearable","ignoreAccents","selected","selectImage","placeholder","searchPromptText","selectedImage","GCE_IMAGE_SELECT","GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCEBUILDER_GCE_SERVICE","vCpuCountForLocationIsValid","instanceFamily","vCpuCount","location","locationToInstanceTypesMap","max","vCpuMax","numberOfVCpusIsValid","minMemoryForVCpuCount","Math","ceil","maxMemoryForVCpuCount","memoryIsValid","totalMemory","extendedMemory","min","inRange","generateValidVCpuListForLocation","range","generateValidMemoryListForVCpuCount","generateValidInstanceFamilyList","x","toUpperCase","generateInstanceTypeString","extendedFlag","memoryInMbs","Number","customInstanceChoicesAreValid","every","parseInstanceTypeString","instanceTypeString","takeRight","memory","GOOGLE_INSTANCE_CUSTOM_CUSTOMINSTANCE_FILTER","gceCustomInstanceBuilderService","GceHttpLoadBalancerUtils","isHttpLoadBalancer","lb","loadBalancerType","normalizeLoadBalancerNamesForAccount","loadBalancerNames","loadBalancers","normalizedLoadBalancerNames","loadBalancerName","matchingUrlMap","find","loadBalancer","listeners","listener","push","uniq","REGION","GCE_HTTP_LOAD_BALANCER_UTILS","GOOGLE_INSTANCE_DETAILS_INSTANCE_DETAILS_CONTROLLER","UIROUTER_ANGULARJS","ANGULAR_UI_BOOTSTRAP","controller","$scope","$state","$uibModal","instance","app","moniker","environment","$q","gceHttpLoadBalancerUtils","gceXpnNamingService","retrieveInstance","extraData","instanceSummary","vpcId","serverGroups","data","some","serverGroup","instances","possibleInstance","instanceId","isDisabled","RecentHistoryService","addExtraDataToLatest","InstanceReader","getInstanceDetails","details","state","loading","latest","isStandalone","health","displayableMetrics","metric","detailsMatch","latestHealth","healthMetrics","extractHealthMetrics","getDataSource","internalDnsName","internalIpAddress","networkInterfaces","networkIP","accessConfigs","externalIpAddress","natIP","baseIpAddress","logsLink","network","networkUrl","getNetwork","subnet","subnetUrl","getSubnet","sshLink","replace","gcloudSSHCommand","placement","availabilityZone","has","securityGroups","securityGroup","accountName","groupId","compact","helpMap","tags","items","tag","securityGroupsMatches","targetTags","securityGroupMatchNames","groupOrGroups","join","augmentTagsWithHelp","autoClose","instanceIdNotFound","when","$$destroyed","go","allowModalToStayOpen","detailsTemplateUrl","CloudProviderRegistry","getValue","firewallsLabel","FirewallLabels","standalone","application","canRegisterWithLoadBalancer","instanceLoadBalancerDoesNotSupportRegister","intersection","outOfService","hasLoadBalancerHealth","canDeregisterFromLoadBalancer","instanceLoadBalancerDoesNotSupportDeregister","canRegisterWithDiscovery","discoveryHealth","showInstanceActionsDivider","hasHealthState","terminateInstance","taskMonitor","title","onTaskComplete","ConfirmationModalService","confirm","header","buttonText","taskMonitorConfig","submitMethod","cloudProvider","managedInstanceGroupName","InstanceWriter","terminateInstanceAndShrinkServerGroup","serverGroupName","instanceIds","zone","rebootInstance","interestingHealthProviderNames","registerInstanceWithLoadBalancer","deregisterInstanceFromLoadBalancer","enableInstanceInDiscovery","disableInstanceInDiscovery","healthProviderType","all","ready","onRefresh","GCE_INSTANCE_TYPE_DISK_DEFAULTS","freeze","instanceType","disks","sizeGb","supportsLocalSSD","GOOGLE_INSTANCE_GCEINSTANCETYPE_SERVICE","$log","categories","families","description","storageType","storageHelpFieldKey","instanceTypes","cpu","costFactor","icon","nameRegex","storage","localSSDSupported","getCategories","memoize","initializedCategories","cloneDeep","AccountService","getAllAccountDetailsForProvider","accountDetails","instanceTypeDisks","flatten","category","family","diskDefaults","instanceTypeDisk","disk","warn","size","count","persistentDisks","startsWith","reduce","maxSizeGb","defaultSettings","getAvailableTypesForLocations","selectedLocations","console","error","flatMap","getAvailableTypesForRegions","getAllTypesByRegion","resolveInstanceTypeDetails","assign","isDefault","instanceTypeStorage","GOOGLE_INSTANCE_GCEMULTIINSTANCETASK_TRANSFORMER","transformers","rebootInstances","job","transform","instanceGroup","transformAll","IAP_INTERCEPTOR","responseError","response","status","iapRefresherEnabled","$http","url","reject","$httpProvider","interceptors","GCE_LOAD_BALANCER_TYPE_TO_WIZARD_CONSTANT","constant","NETWORK","createTemplateUrl","editTemplateUrl","HTTP","INTERNAL_MANAGED","INTERNAL","SSL","TCP","GceLoadBalancerChoiceCtrl","$uibModalInstance","loadBalancerTypeToWizardMap","forPipelineConfig","choice","$onInit","choices","wizardConfig","choose","wizard","dismiss","close","wizardResult","open","templateUrl","isNew","$inject","GCE_LOAD_BALANCER_CHOICE_MODAL","openGCEPipelineLoadBalancerModal","HttpLoadBalancerTemplate","credentials","stack","detail","certificate","certificateMap","hostRules","BackendServiceTemplate","backends","sessionAffinity","affinityCookieTtlSec","HealthCheckTemplate","requestPath","port","checkIntervalSec","timeoutSec","healthyThreshold","unhealthyThreshold","PathMatcherTemplate","pathRules","HostRuleTemplate","pathMatcher","PathRuleTemplate","ListenerTemplate","certificateSource","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BACKENDSERVICE_BACKENDSERVICE_COMPONENT","bindings","deleteService","backendService","command","index","backingData","servicesByName","backendServicesKeyedByName","onBackendServiceSelect","selectedBackendService","onHealthCheckSelected","toggleEditExisting","editExisting","template","getAllHealthChecks","allHealthChecks","concat","hc","getSessionAffinitySuggestions","getAllServiceNames","maxCookieTtl","getBackendServiceName","toAssign","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_BASICSETTINGS_BASICSETTINGS_COMPONENT","c","accounts","loadBalancerMap","getName","applicationName","trimEnd","updateName","appName","urlMapName","accountChanged","existingLoadBalancerNames","onAccountChange","GceCacheRefreshCtrl","cacheInitializer","refreshing","tooltipTemplate","cacheKeyAlias","cacheKey","capitalizedKey","substring","depluralizedKey","getRefreshTime","getStats","ageMax","refresh","refreshCache","gceCacheRefresh","renderCompact","GCE_CACHE_REFRESH","CACHE_INITIALIZER_SERVICE","GCE_CERTIFICATE_READER","sessionAffinityViewToModelMap","None","sessionAffinityModelToViewMap","invert","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_TRANSFORMER_SERVICE","keysToOmit","serialize","originalCommand","originalLoadBalancer","unifiedHealthChecksKeyedByName","healthChecksKeyedByName","keyBy","unifiedBackendServicesKeyedByName","defaultService","hostRule","p","pathRule","mapComponentNamesToObjects","hostPatterns","hostPattern","commands","omit","useCertificateMap","portRange","ipAddress","buildCommandForEachListener","listenersToDelete","difference","deserialize","uniqBy","getHealthChecksAndBackendServices","mapBackendServicesToNames","getHostRules","freeFormDetails","NameUtils","parseLoadBalancerName","created","getListeners","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_COMMANDBUILDER_SERVICE","LOAD_BALANCER_READ_SERVICE","gceHttpLoadBalancerTransformer","loadBalancerReader","buildBackingData","promises","getBackendServices","getHealthChecks","getCertificates","getLoadBalancerMap","networks","NetworkReader","listNetworksByProvider","subnets","SubnetReader","listSubnetsByProvider","listAccounts","unifyDataSources","loadBalancerData","accountNames","first","setAccount","existingListeners","without","removeExistingListenersFromBackingData","lbHealthCheckMap","backingDataHealthCheckMap","healthChecksKeyedByNameCopy","identity","lbBackendServicesMap","backingDataBackendServiceMap","backendServicesKeyedByNameCopy","regions","subnetMap","groupBy","internalHttpLbNetworks","purpose","healthCheckLink","pop","ttlIsDefined","listLoadBalancers","lbs","mapValues","a","urlMapNames","valueOf","onHealthCheckRefresh","updated","onCertificateRefresh","onBackendServiceRefresh","onRegionSelected","selectedName","selectedObject","onBackendServiceSelected","getAllBackendServices","allBackendServices","getUnusedHealthChecks","getUnusedBackendServices","hostRuleServices","pathRuleServices","usedServices","removeUnusedBackendServices","unusedBackendServices","removeUnusedHealthChecks","unusedHealthChecks","onAddressRefresh","buildCommand","isInternal","loadBalancerTemplate","project","mixinData","buildLoadBalancer","buildBackingDataAndLoadBalancer","GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_SERVICE","buildRow","path","backend","buildTable","defaultRow","rows","paths","GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULES_CONTROLLER","hostAndPathRulesService","table","GOOGLE_LOADBALANCER_DETAILS_HOSTANDPATHRULES_HOSTANDPATHRULESBUTTON_COMPONENT","viewHostAndPathRules","controllerAs","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HEALTHCHECK_HEALTHCHECK_COMPONENT","deleteHealthCheck","MAX_SAFE_INTEGER","healthChecksByName","onHealthCheckSelect","selectedHealthCheck","getAllHealthCheckNames","onProtocolChange","getHealthCheckName","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_PATHRULE_PATHRULE_COMPONENT","deletePathRule","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HOSTRULE_HOSTRULE_COMPONENT","deleteHostRule","addPathRule","splice","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_HTTPLOADBALANCER_WRITE_SERVICE","angular","upsertLoadBalancers","descriptor","extend","clearCache","TaskExecutor","executeTask","deleteLoadBalancers","gceAddressSelector","initialIpAddress","addressList","readOnly","onAddressSelect","selectedAddress","GCE_ADDRESS_SELECTOR","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_LISTENERS_LISTENER_COMPONENT","deleteListener","listenerName","getSubnets","ret","getInternalAddresses","addressType","subnetwork","localListenerHasSameName","existingListenerNames","isHttps","supportsCertificateMap","certificateMapPattern","getCertificateMapName","isString","normalized","trim","syncCertificateState","onCertificateSourceChanged","onCertificateSelected","onCertificateMapChanged","onPortChanged","GOOGLE_LOADBALANCER_CONFIGURE_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER","gceHttpLoadBalancerWriter","wizardSubFormValidation","gceHttpLoadBalancerCommandBuilder","modalDescriptor","pages","keyToTemplateMap","add","remove","onApplicationRefresh","newStateParams","accountId","TaskMonitor","modalInstance","onNextRefresh","submit","serializedCommands","pipelineCommands","scope","form","page","subForm","validators","watchString","validator","collection","cancel","CommonGceLoadBalancerCtrl","GceCommonLoadBalancerCommandBuilder","dataFetchers","existingLoadBalancerNamesByAccount","loadBalancerList","regionWrappers","getBackingData","dataTypes","promisesByDataType","dataType","groupHealthChecksByAccountAndType","grouped","groupHealthCheckNamesByAccount","namesToOmit","GCE_COMMON_LOAD_BALANCER_COMMAND_BUILDER","HealthCheckCreateCtrl","healthCheckPlaceholder","existingHealthChecksForProtocol","healthChecksByAccountAndType","$watch","setExistingHealthChecksForProtocol","onHealthCheckNameChange","typedName","healthCheckCreateComponent","existingHealthCheckNames","GCE_HEALTH_CHECK_SELECTOR_COMPONENT","ViewState$2","InternalLoadBalancer","ipProtocol","InternalLoadBalancerCtrl","gceCommonLoadBalancerCommandBuilder","advancedSettings","viewState","ViewState","initializeEditMode","healthCheckNamesToOmit","existingHealthCheckNamesByAccount","accountUpdated","networkUpdated","subnetOptions","protocolUpdated","networkOptions","getRegionsForAccount","regionUpdated","setSessionAffinity","toSubmitLoadBalancer","ports","LoadBalancerWriter","upsertLoadBalancer","GCE_INTERNAL_LOAD_BALANCER_CTRL","GOOGLE_LOADBALANCER_CONFIGURE_INTERNAL_HTTP_CREATEHTTPLOADBALANCER_CONTROLLER","CreateInternalHttpLoadBalancerController","bind","GOOGLE_GCEREGIONSELECTFIELD_DIRECTIVE","directive","restrict","field","labelColumns","fieldColumns","GOOGLE_LOADBALANCER_LOADBALANCER_TRANSFORMER","updateHealthCounts","container","instanceCounts","up","down","acc","healthState","normalizeLoadBalancer","detachedInstances","transformInstance","activeServerGroups","timeout","interval","convertLoadBalancerForEditing","toEdit","regionZones","availabilityZones","elb","vpcid","listenerDescriptions","protocol","loadBalancerPort","healthTimeout","healthInterval","protocolIndex","pathIndex","healthCheckProtocol","healthCheckPort","healthCheckPath","isNaN","constructNewLoadBalancerTemplate","GOOGLE_LOADBALANCER_CONFIGURE_NETWORK_CREATELOADBALANCER_CONTROLLER","gceLoadBalancerTransformer","ctrl","updateLoadBalancerNames","accountLoadBalancersByRegion","accountsLoaded","submitting","sessionAffinityOptions","requiresHealthCheckPath","prependForwardSlash","text","isArray","setVisibilityHealthCheckTab","ModalWizard","includePage","markIncomplete","excludePage","markComplete","ViewState$1","SslLoadBalancer","SslLoadBalancerCtrl","portOptions","hasBackendService","certificateWrappers","GCE_SSL_LOAD_BALANCER_CTRL","TcpLoadBalancer","TcpLoadBalancerCtrl","GCE_TCP_LOAD_BALANCER_CTRL","gceBackendServiceDetailsComponent","GCE_BACKEND_SERVICE_DETAILS_COMPONENT","SESSION_AFFINITY_FILTER","modelValue","Verification","verified","Params","deleteHealthChecks","DeleteLoadBalancerModalController","verification","isValid","getSubmitMethod","hasHealthChecks","deleteLoadBalancer","DELETE_MODAL_CONTROLLER","GOOGLE_LOADBALANCER_DETAILS_HEALTHCHECK_HEALTHCHECK_COMPONENT","GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERTYPE_LOADBALANCERTYPE_COMPONENT","hasCertificate","hasCertificateMap","GOOGLE_LOADBALANCER_DETAILS_LOADBALANCERDETAIL_CONTROLLER","extractLoadBalancer","test","testVpc","detailsPromises","getLoadBalancerDetails","representativeLb","dns","dnsname","loadBalancerDetails","createDetailsLoader","filtered","getCredentialsKeyedByAccount","getAccountDetails","resourceTypes","editLoadBalancer","copy","getNetworkId","getSubnetId","_GceLoadBalancerSetTransformer","normalizeLoadBalancerSet","httpLoadBalancers","otherLoadBalancers","partition","groupedByUrlMap","normalizeHttpLoadBalancerGroup","group","parsePortRange","GceLoadBalancerSetTransformer","LOAD_BALANCER_SET_TRANSFORMER","GOOGLE_PIPELINE_STAGES_BAKE_BAKEEXECUTIONDETAILS_CONTROLLER","$stateParams","executionDetailsSectionService","$interpolate","configSections","initialized","detailsSection","stage","context","cloudProviderType","roscoMode","roscoSelector","bakeryDetailUrl","roscoDetailUrl","initialize","synchronizeSection","$on","GOOGLE_PIPELINE_STAGES_BAKE_GCEBAKESTAGE","Registry","pipeline","registerStage","provides","executionDetailsUrl","executionLabelComponent","BakeExecutionLabel","extraLabelLines","masterStage","allPreviouslyBaked","somePreviouslyBaked","producesArtifacts","supportsCustomTimeout","fields","fieldName","fieldLabel","restartable","artifactExtractor","ExpectedArtifactService","accumulateArtifacts","artifactRemover","ArtifactReferenceService","removeArtifactFromFields","extendedAttributes","user","AuthenticationService","getAuthenticatedUser","addExtendedAttribute","PipelineTemplates","addExtendedAttributes","extendedAttribute","removeExtendedAttribute","showTemplateFileName","templateFileName","showAccountName","showExtendedAttributes","showVarFileName","varFileName","forOwn","val","providerSelected","BakeryReader","getBaseOsOptions","getBaseLabelOptions","getExpectedArtifactsAvailableToStage","baseOsOptions","baseLabelOptions","expectedArtifacts","baseImages","baseOs","baseLabel","showAdvancedOptions","baseAmi","showAdvanced","GOOGLE_PIPELINE_STAGES_CLONESERVERGROUP_GCECLONESERVERGROUPSTAGE","executionStepLabelUrl","cloneTargets","StageConstants","TARGET_LIST","attributes","platformHealthOnlyShowOverride","platformHealthOnly","defaultCredentials","targetClusterUpdated","targetCluster","clusterName","parseServerGroupName","removeCapacity","capacity","useSourceCapacity","toggleDisableTraffic","disableTraffic","GOOGLE_PIPELINE_STAGES_DESTROYASG_GCEDESTROYASGSTAGE","accountExtractor","configAccountExtractor","message","regionsLoaded","targets","defaultRegions","GOOGLE_PIPELINE_STAGES_DISABLEASG_GCEDISABLEASGSTAGE","GOOGLE_PIPELINE_STAGES_DISABLECLUSTER_GCEDISABLECLUSTERSTAGE","remainingEnabledServerGroups","pluralize","str","preferLargerOverNewer","toString","GOOGLE_PIPELINE_STAGES_ENABLEASG_GCEENABLEASGSTAGE","GOOGLE_PIPELINE_STAGES_FINDAMI_GCEFINDAMISTAGE","selectionStrategies","selectionStrategy","isUndefined","onlyEnabled","GOOGLE_PIPELINE_STAGES_FINDIMAGEFROMTAGS_GCEFINDIMAGEFROMTAGSSTAGE","executionConfigSections","getRegions","GOOGLE_PIPELINE_STAGES_RESIZEASG_GCERESIZEASGSTAGE","resizeTargets","scaleActions","resizeTypes","action","resizeType","updateResizeType","scalePct","scaleNum","GOOGLE_PIPELINE_STAGES_SCALEDOWNCLUSTER_GCESCALEDOWNCLUSTERSTAGE","strategy","remainingFullSizeServerGroups","allowScaleDownActive","GOOGLE_PIPELINE_STAGES_SHRINKCLUSTER_GCESHRINKCLUSTERSTAGE","shrinkToSize","allowDeleteActive","retainLargerOverNewer","GOOGLE_PIPELINE_STAGES_TAGIMAGE_GCETAGIMAGESTAGE","upstreamDependencies","PipelineConfigService","getAllUpstreamDependencies","IMAGE_PRODUCING_STAGES","consideredStages","Map","refId","GOOGLE_SECURITYGROUP_CONFIGURE_CREATESECURITYGROUP_CONTROLLER","$controller","sourceFilters","ingress","sourceRanges","sourceTags","ipIngress","mode","getSecurityGroupRefreshTime","upsert","mixinUpsert","initializeSecurityGroups","GOOGLE_SECURITYGROUP_CONFIGURE_EDITSECURITYGROUP_CONTROLLER","refreshingSecurityGroups","sourceRange","ipIngressRules","rule","portRanges","startPort","endPort","addSourceCIDR","removeSourceCIDR","addRule","ruleset","removeRule","allowed","ipIngressRule","SecurityGroupWriter","upsertSecurityGroup","GCE_SECURITY_GROUP_HELP_TEXT_SERVICE","reset","indexServerGroupsByTag","getHelpTextForTag","tagType","getServerGroupsWithTag","serverGroupsIndexedByTag","Array","from","sort","providerMetadata","networkName","set","Set","GOOGLE_SECURITYGROUP_CONFIGURE_CONFIGSECURITYGROUPMIXIN_CONTROLLER","SECURITY_GROUP_READER","securityGroupReader","gceSecurityGroupHelpTextService","removedRules","infiniteScroll","numToAdd","currentItems","targetOptions","getTagHelpText","addMoreItems","registerHelpTextService","initializeTargetOptions","initializeTarget","getTargetLabel","onTargetChange","updateNetworks","refreshSecurityGroups","getAllSecurityGroups","existingGroups","global","existingSecurityGroupNames","gceNetworks","n","getCurrentNamePattern","namePreview","namePattern","dismissRemovedRules","markClean","addTargetTag","removeTargetTag","addSourceTag","removeSourceTag","GOOGLE_SECURITYGROUP_CLONE_CLONESECURITYGROUP_CONTROLLER","vm","firewallLabel","GOOGLE_SECURITYGROUP_DETAILS_SECURITYGROUPDETAIL_CONTROLLER","resolvedSecurityGroup","extractSecurityGroup","getSecurityGroupDetails","fourOhFour","applicationSecurityGroup","getApplicationSecurityGroup","targetServiceAccounts","sourceServiceAccounts","ipRangeRules","ip","cidr","ipRangeRule","protocolPortRangeCount","sumBy","editInboundRules","cloneSecurityGroup","deleteSecurityGroup","securityGroupName","GOOGLE_SECURITYGROUP_SECURITYGROUP_READER","resolveIndexedSecurityGroup","indexedSecurityGroups","securityGroupId","GOOGLE_SECURITYGROUP_SECURITYGROUP_TRANSFORMER","normalizeSecurityGroup","GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_BASICSETTINGS_BASICSETTINGS_COMPONENT","modes","GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_METRICSETTINGS_METRICSETTINGS_COMPONENT","showNoMetricsWarning","multipleAllowedFor","loadBalancingUtilization","customMetricUtilizations","metricTypes","emptyOrUndefined","isEqual","targetTypesToDisplayMap","GAUGE","DELTA_PER_SECOND","DELTA_PER_MINUTE","metricScopeTypesToDisplayMap","TIME_SERIES_PER_INSTANCE","SINGLE_TIME_SERIES_PER_GROUP","scalingpolicyTypesToDisplayMap","UTILIZATION_TARGET","SINGLE_INSTANCE_ASSIGNMENT","addMetric","metricType","utilizationTarget","deleteMetric","showMetric","isSingleTimeSeriesPerGroup","scopeType","metricExportScope","isScalingPolicySingleInstanceAssignment","policyType","scalingpolicy","setUtilizationTargetFromDisplay","initializeTargetDisplay","round","safeDecimalToPercent","GOOGLE_AUTOSCALINGPOLICY_COMPONENTS_SCALINGSCHEDULES_SCALINGSCHEDULES_COMPONENT","scalingSchedules","timezones","addSchedule","scheduleType","deleteSchedule","selectTimezone","timezone","schedule","TimezoneSelect","availableTimezones","selectedTimezone","GCE_TIMEZONE_SELECT","GOOGLE_SERVERGROUP_SERVERGROUP_TRANSFORMER","parseHealthCheckUrl","healthCheckPathParts","Error","healthCheckName","healthCheckKind","slice","getHealthCheckOptions","duplicateNames","allNames","getDuplicateHealthCheckNames","displayName","convertServerGroupCommandToDeployConfiguration","base","truncatedZones","source","enableTraffic","selectedProvider","implicitSecurityGroups","providerType","enableAutoHealing","normalizeServerGroup","GceAcceleratorService","getAvailableAccelerators","distributionPolicy","regional","selectZones","acceleratorMap","getZoneToAcceleratorTypesMap","getAcceleratorTypesForZone","allZonesAcceleratorTypes","z","intersectionBy","apply","availableCardCounts","getAvailableCardCounts","accelerator","maxCards","isFinite","maximumCardsPerInstance","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGMANAGER_SERVICE","resetKeys","securityGroupObjects","initializeSecurityGroupObjects","byTag","bySecurityGroupId","groupSecurityGroupObjects","securityGroupObjectsKeyedByTag","securityGroupObjectsKeyedById","inferSecurityGroupIdsFromTags","commandTags","t","sg","rawTags","tagsArray","selectedTags","groupings","inferSelectedSecurityGroupFromTag","debounce","tagName","securityGroupObjectsWithTag","updateSelectedTagsOnSecurityGroupObjects","updateSelectedSecurityGroups","getSecurityGroupObjectsFromIds","updateSelectedTags","addTag","ids","newTag","oldGroups","newGroups","removeTag","securityGroupIds","removeSecurityGroup","securityGroupObject","tagsToRemove","getToolTipContent","groups","groupIds","showToolTip","GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE","gceInstanceTypeService","gceTagManager","gceLoadBalancerSetTransformer","persistentDiskTypes","authScopes","configureDistributionPolicyTargetShape","credentialsKeyedByAccount","targetShape","configureInstanceTypes","dirty","configureCustomInstanceTypes","locations","zones","l","tokenizedInstanceTypes","tokens","class","sortedTokenizedInstanceTypes","sortBy","sortedTokenizedInstanceType","sortInstanceTypes","configureStandardInstanceTypes","configureCpuPlatforms","filteredData","locationToCpuPlatformsMap","cpuPlatforms","minCpuPlatform","configureAccelerators","acceleratorTypes","chosenAccelerators","acceleratorConfigs","chosen","acceleratorType","configureImages","image","imageId","lastImageAccount","allImages","configureZones","configureHealthChecks","autoHealingPolicy","healthCheckUrl","isRelevantLoadBalancer","configureLoadBalancerOptions","current","newLoadBalancerObjects","flattenDeep","curry","getLoadBalancers","loadBalancerIndex","matched","removed","xor","backendsFromMetadata","backendServiceMetadata","lbIndex","lbName","configureBackendServiceOptions","refreshHealthChecks","skipCommandReconfiguration","configureSubnets","getSecurityGroups","newSecurityGroups","configureSecurityGroupOptions","currentOptions","currentGroupNames","match","matchedGroups","groupName","xpnHostProject","decoratedSecurityGroups","getNetworkNames","configureCommand","securityGroupReloader","networkReloader","healthCheckReloader","distributionPolicyTargetShapes","refreshNetworks","autoScalingPolicy","enableAutoScaling","cmd","regionalChanged","regionChanged","credentialsChanged","networkChanged","autoCreateSubnets","zoneChanged","selectZonesChanged","customInstanceChanged","refreshLoadBalancers","refreshInstanceTypes","GCE_ACCELERATOR_CONFIGURER","availableAccelerators","setAcceleratorConfigs","acceleratorConfig","getCountOptions","getNearestCount","currentCount","availableCounts","nearest","width","acceleratorCount","Select","option","onTypeChange","indexToUpdate","onCountChange","onClick","removeAccelerator","indexToRemove","_config","colSpan","href","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ADVANCEDSETTINGS_ADVANCEDSETTINGSSELECTOR_DIRECTIVE","UI_SELECT","bindToController","setDisks","setPreemptible","preemptible","automaticRestart","onHostMaintenance","setEnableVtpm","enableVtpm","enableIntegrityMonitoring","configs","$apply","GceDiskConfigurerController","handleImageChange","sourceImage","handlePersistentDiskChange","_b","_c","_d","_e","_f","_g","_h","setLocalSSDCount","setPersistentDisks","getLocalSSDDisks","instanceTypeDetails","updateDisks","sortDisks","getPersistentDisks","$onChanges","handleLocalSSDCountChange","localSSDCount","addPersistentDisk","removePersistentDisk","diskWithoutImage","gceDiskConfigurer","GCE_DISK_CONFIGURER","gceAutoHealingPolicySelectorComponent","setAutoHealingPolicy","enabled","maxUnavailable","fixed","maxUnavailableMetric","percent","initialDelaySec","$onDestroy","manageMaxUnavailableMetric","selectedMetric","toDeleteKey","onHealthCheckChange","_healthCheck","GCE_AUTOHEALING_POLICY_SELECTOR","GCE_AUTOSCALING_POLICY_SELECTOR_COMPONENT","setAutoScalingPolicy","autoscalingPolicy","updatedPolicy","$applyAsync","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_ADVANCEDCAPACITYSELECTOR_COMPONENT","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CAPACITY_SIMPLECAPACITYSELECTOR_COMPONENT","setSimpleCapacity","setMinMax","newVal","CustomInstanceConfigurer","handleVCpuChange","selectedInstanceFamily","selectedMemory","selectedExtendedMemory","handleMemoryChange","selectedVCpuCount","handleInstanceFamilyChange","handleMemoryChangeCustom","handleExtendedMemory","instanceFamilyOptions","instanceFamilyList","vCpuOptions","vCpuList","vCpu","memoryOptions","memoryList","selectedVCpuCountLabel","selectedMemoryLabel","selectedInstanceFamilyLabel","event","GCE_CUSTOM_INSTANCE_CONFIGURER","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_BACKENDSERVICESELECTOR_COMPONENT","preventDefault","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_ELSEVENOPTIONS_ELSEVENOPTIONSGENERATOR_COMPONENT","$compile","link","element","compiledTemplate","listItem","closest","after","next","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOADBALANCERS_LOADBALANCERSELECTOR_DIRECTIVE","showLoadBalancingPolicy","isDefined","s","GceLoadBalancingPolicySelectorController","maxPort","setModel","propertyName","viewValue","setView","decimalToPercent","onBalancingModeChange","toDelete","loadBalancingPolicy","getBalancingModes","balancingModes","hasSsl","hasTcp","hasHttp","globalBackendServices","addNamedPort","namedPorts","removeNamedPort","getPortNames","inUsePortNames","namedPort","lbBackendServices","portNames","portName","portNameIntersection","getThem","gceLoadBalancingPolicySelectorComponent","GCE_LOAD_BALANCING_POLICY_SELECTOR","GOOGLE_GCENETWORKSELECTFIELD_DIRECTIVE","helpKey","GOOGLE_SUBNET_SUBNETSELECTFIELD_DIRECTIVE","subnetPlaceholder","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_LOCATION_BASICSETTINGS_CONTROLLER","IMAGE_READER","$uibModalStack","imageSearchResultsStream","Subject","pipe","switchMap","observableFrom","subscribe","images","imageReader","stackPattern","templatingEnabled","detailPattern","getSubnetPlaceholder","imageSources","excludedImageArtifactTypes","excludeAllTypesExcept","ArtifactTypePatterns","CUSTOM_OBJECT","onImageArtifactEdited","artifact","imageArtifactId","imageArtifact","onImageArtifactSelected","expectedArtifact","onChangeImageArtifactId","artifactId","onImageArtifactAccountSelected","imageAccountName","gceImageDelegate","NgGCEImageArtifactDelegate","gceImageArtifact","showCreateArtifactForm","delegate","ExpectedArtifactSelectorViewController","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTOR_COMPONENT","onSelect","onRemove","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_TAGSELECTORGENERATOR_COMPONENT","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSELECTOR_DIRECTIVE","gceServerGroupConfigurationService","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_SECURITYGROUPS_SECURITYGROUPSREMOVED_DIRECTIVE","acknowledgeSecurityGroupRemoval","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_REGIONALSELECTOR_DIRECTIVE","noop","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_TARGETSHAPESELECTOR_DIRECTIVE","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_ZONES_ZONESELECTOR_DIRECTIVE","GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUP_CONFIGURE_GCE_MODULE","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_HIDDENMETADATAKEYS_VALUE","GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCOMMANDBUILDER_SERVICE","INSTANCE_TYPE_SERVICE","instanceTypeService","gceServerGroupHiddenMetadataKeys","extractNetworkName","launchConfig","instanceTemplate","extractSubnetName","subnetworkUrl","determineAssociatePublicIPAddress","calculateOverriddenStorageDescription","overriddenStorageDescription","diskCountBySizeGb","sizeA","sizeB","calculatePersistentDiskOverriddenStorageDescription","populateAutoHealingPolicy","populateCustomMetadata","metadataItems","customUserData","customUserDataKeys","customUserDataItem","metadataItem","getCustomUserDataKeys","userData","instanceMetadata","labels","userDataItem","customUserDataKey","populateTags","instanceTemplateTags","populateResourceManagerTags","instanceTemplateResourceManagerTags","resourceManagerTags","populatePartnerMetadata","instanceTemplatePartnerMetadata","partnerMetadata","buildNewServerGroupCommand","defaultRegion","defaultZone","associatePublicIpAddress","providerSettings","canIpForward","desired","imageSource","enableSecureBoot","serviceAccountEmail","instanceProfile","allImageSelection","useSimpleCapacity","usePreferredZones","listImplicitSecurityGroups","disableStrategySelection","gceAccounts","gceAccountNames","firstGCEAccount","defaultCredentialsAreValid","attemptToSetValidCredentials","buildNewServerGroupCommandForPipeline","currentStage","requiresTemplateSelection","buildServerGroupCommandFromExisting","asg","property","minSize","maxSize","desiredCapacity","asgName","customInstance","determineInstanceCategoryFromInstanceType","scheduling","populateAvailabilityPolicies","properties","metadata","instanceTemplateLabels","populateLabels","serviceAccounts","email","scopes","authScope","populateAuthScopes","localSSDDisks","initializeParams","diskType","diskSizeGb","getInstanceTypeDetails","populateDisksFromExisting","buildServerGroupCommandFromPipeline","originalCluster","pipelineCluster","instanceTypeCategoryLoader","getCategoryForInstanceType","commandOptions","disableImageSelection","showImageSourceSelector","submitButtonLabel","viewOverrides","extendedCommand","populateDisksFromPipeline","populateShieldedVmConfig","GOOGLE_SERVERGROUP_CONFIGURE_WIZARD_CLONESERVERGROUP_GCE_CONTROLLER","serverGroupWriter","serverGroupCommand","cloneStage","task","execution","stages","newServerGroupName","transitionTo","loaded","processCommandUpdateResult","createResultProcessor","customInstanceChoices","setInstanceTypeFromCustomChoices","method","markDirty","templateSelection","basicSettings","templateSelectionText","copied","notCopied","selectedZones","$valid","isComplete","showSubmitButton","allPagesVisited","loadBalancerMetadata","isObject","accumulatedBackends","buildLoadBalancerMetadata","origLoadBalancers","selectedSslLoadBalancerNames","selectedTcpLoadBalancerNames","collectLoadBalancerNamesForCommand","origTags","transformedTags","targetSize","minNumReplicas","maxNumReplicas","promise","cloneServerGroup","onEnableAutoHealingChange","overwriteAncestorAutoHealingPolicy","onEnableAutoScalingChange","overwriteAncestorAutoScalingPolicy","specialInstanceProfiles","setCustomInstanceViewState","templateSelected","StatefulMIGService","markDiskStateful","deviceName","statefullyUpdateBootDisk","bootImage","isDiskStateful","statefulMigsEnabled","MarkDiskStatefulButton","askForReason","UpdateBootImageButton","componentProps","ReactModal","show","UpdateBootImageModal","dialogClassName","values","modalInstanceEmulation","dismissModal","componentDidMount","setState","WizardModal","closeModal","heading","initialValues","formik","nextIdx","WizardPage","order","FormikFormField","height","setFieldValue","_ServerGroupDiskDescriptions","statefulOperationsEnabled","canUpdateBootImage","boot","Fragment","getDiskImageName","getDiskTypeLabel","getDiskImageLabel","translateDiskType","ServerGroupDiskDescriptions","GCE_SERVER_GROUP_DISK_DESCRIPTIONS","defaultScaleInControl","maxScaledInReplicas","timeWindowSec","GCE_SCALE_IN_CONTROLS","updateScaleInControl","scaleInControl","getMaxReplicasUnit","isInteger","NumberInput","parseInt","ReactSelectInput","stringOptions","GceAddAutoHealingPolicyButtonCtrl","addAutoHealingPolicy","gceAddAutoHealingPolicyButton","GCE_ADD_AUTOHEALING_POLICY_BUTTON","GceAutoHealingPolicyDetailsCtrl","gceAutoscalingPolicyWriter","editPolicy","deletePolicy","deleteAutoHealingPolicy","gceAutoHealingPolicyDetails","GCE_AUTOHEALING_POLICY_DETAILS","GOOGLE_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_WRITE_SERVICE","upsertAutoscalingPolicy","deleteAutoscalingPolicy","upsertAutoHealingPolicy","GceUpsertAutoHealingPolicyModalCtrl","matchingHealthChecks","GCE_UPSERT_AUTOHEALING_POLICY_MODAL_CTRL","GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_MODAL_UPSERTAUTOSCALINGPOLICY_MODAL_CONTROLLER","save","GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_ADDAUTOSCALINGPOLICYBUTTON_COMPONENT","addAutoscalingPolicy","GOOGLE_SERVERGROUP_DETAILS_AUTOSCALINGPOLICY_AUTOSCALINGPOLICY_DIRECTIVE","bases","basis","utilizationTargetType","scaleInControlsConfigured","maxScaledInReplicasMessage","timeWindowSecMessage","predictiveAutoscalingEnabled","GOOGLE_COMMON_FOOTER_DIRECTIVE","GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZEAUTOSCALINGPOLICY_COMPONENT","formMethods","newPolicyBounds","prop","formIsValid","bound","resizeAutoscalingPolicyForm","newMinNumReplicas","newMaxNumReplicas","reason","GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZECAPACITY_COMPONENT","SERVER_GROUP_WRITER","newSize","resizeCapacityForm","resizeServerGroup","GOOGLE_SERVERGROUP_DETAILS_RESIZE_RESIZESERVERGROUP_CONTROLLER","resize","GOOGLE_SERVERGROUP_DETAILS_ROLLBACK_ROLLBACKSERVERGROUP_CONTROLLER","disabledServerGroups","b","localeCompare","rollbackType","rollbackContext","rollbackServerGroupName","restoreServerGroupName","rollback","rollbackServerGroup","GOOGLE_SERVERGROUP_DETAILS_SERVERGROUPDETAILS_GCE_CONTROLLER","$templateCache","gceServerGroupCommandBuilder","cancelLoader","retrieveServerGroup","summary","toCheck","possibleServerGroup","extractServerGroupSummary","ServerGroupReader","getServerGroup","retrieveSubnet","findStartupScript","prepareAvailabilityPolicies","prepareShieldedVmConfig","prepareAutoHealingPolicy","prepareAuthScopes","prepareCurrentActions","configureEntityTagTargets","processLabels","startupScriptItem","startupScript","availabilityPolicies","preemptibility","shieldedVmConfig","autoHealingPolicyHealthCheck","serviceAccount","currentActions","currentActionsSummary","startCase","associatePublicIPAddress","destroyServerGroup","stateParams","confirmationModalParams","platformHealthType","ServerGroupWarningMessageService","addDestroyWarningMessage","disableServerGroup","addDisableWarningMessage","enableServerGroup","cluster","clusters","showStartupScript","userDataModalTitle","ServerGroupTemplates","buildJenkinsLink","buildInfo","buildInfoUrl","jenkins","host","number","truncateCommitHash","commit","entityTagTargets","ClusterTargetBuilder","buildClusterTargets","GOOGLE_SERVERGROUP_DETAILS_SERVERGROUP_DETAILS_GCE_MODULE","GOOGLE_SUBNET_SUBNET_RENDERER","GOOGLE_VALIDATION_APPLICATIONNAME_VALIDATOR","validate","warnings","errors","validateSpecialCharacters","maxResourceNameLength","maxLengthForLoadBalancers","remaining","maxLengthForServerGroups","validateLength","run","gceApplicationNameValidator","ApplicationNameValidator","registerValidator","GOOGLE_MODULE","registerProvider","logo","configurer","reader","transformer","detailsController","cloneServerGroupTemplateUrl","cloneServerGroupController","commandBuilder","configurationService","multiInstanceTaskTransformer","customInstanceBuilderTemplateUrl","setTransformer","createLoadBalancerTemplateUrl","createLoadBalancerController","pipelineCreateLoadBalancerModal","createSecurityGroupTemplateUrl","createSecurityGroupController","renderer","snapshotsEnabled","applicationProviderFields","DeploymentStrategyRegistry"],"mappings":"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MG,GAA0C,CAC9C,mCACE,8FACF,sCACE,4JACF,sCACE,wGACF,kCACE,iHACF,4CAA6C,mCAC7C,iCAAkC,kVAKlC,sCAAuC,uDACvC,4BACE,qHACF,qBACE,0GACF,mBAAoB,qWASpB,oCACE,mPACF,qCACE,uNACF,6CACE,kOACF,gDAAiD,yDACjD,kDACE,qHACF,yDACE,4HACF,oDACE,uHACF,oDACE,2HACF,6CAA8C,oDAC9C,uCAAwC,uEACxC,6CAA8C,uEAC9C,uBACE,sLACF,gCACE,wLACF,8BACE,gOACF,0BACE,6PACF,yCACE,+FACF,0BACE,mGACF,iCAAkC,gDAClC,uCACE,+EACF,sCACE,yOACF,0BACE,gIACF,mDACE,4GACF,qDACE,4JACF,uDACE,wIACF,+BACE,8FACF,4BACE,8QACF,6BACE,kSACF,gCACE,6GACF,+BACE,6GACF,+BAAgC,wEAChC,0CACE,+EACF,0CACE,+EACF,yDACE,wGACF,8CAA+C,qTAI/C,kDACE,4IACF,+CACE,oFACF,sDACE,yIACF,yDACE,0FACF,yDACE,iFACF,+CAAgD,mQAQhD,4BACE,6GACF,2BACE,0KACF,iCACE,uIACF,iCACE,oLACF,2BACE,gNACF,qDACE,qIACF,4DACE,4IACF,uDACE,uIACF,uDACE,4QACF,8CACE,wFACF,gDAAiD,oDACjD,0CAA2C,uEAC3C,gDACE,uEACF,mCACE,8JACF,uCACE,wGACF,iCACE,wIACF,gDACE,0KACF,iCACE,gHACF,mCACE,6KACF,oCACE,wIACF,+BACE,4LACF,0CACE,4IACF,4CACE,qGACF,6CACE,+FACF,2DACE,uMACF,2CACE,gFACF,qCACE,0FACF,qCAAsC,8EACtC,uCACE,6OACF,mCACE,+KACF,8BACE,iNACF,kCACE,uGACF,iCAAkC,2VAMlC,yBAA0B,+uBAO1B,oDACE,iPACF,yDACE,sIACF,qDACE,wMACF,gEACE,sIACF,qDAAsD,uZAItD,+CACE,sGACF,oDACE,oIACF,0BACE,wJACF,8BACE,mLACF,gCACE,wJACF,uCACE,oIACF,qCACE,kF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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/certificate/certificate.reader.ts","../src/healthCheck/healthCheck.read.service.ts","../src/cache/cacheConfigurer.service.js","../src/help/gce.help.ts","../src/image/image.reader.ts","../src/image/ImageSelect.tsx","../src/common/xpnNaming.gce.service.js","../src/instance/details/GceInstanceDetails.tsx","../src/instance/gceInstanceTypeDisks.ts","../src/instance/gceInstanceType.service.js","../src/instance/gceMultiInstanceTask.transformer.js","../src/loadBalancer/configure/common/gceLoadBalancerData.ts","../src/loadBalancer/configure/common/gceLoadBalancerModels.ts","../src/loadBalancer/configure/common/GceProxyLoadBalancerEditor.tsx","../src/loadBalancer/configure/common/GceProxyLoadBalancerModal.tsx","../src/loadBalancer/configure/common/useGceLoadBalancerData.ts","../src/loadBalancer/configure/http/GceHttpLoadBalancerListenerEditor.tsx","../src/loadBalancer/configure/http/GceHttpLoadBalancerResourceEditors.tsx","../src/loadBalancer/configure/http/GceHttpLoadBalancerRoutingEditor.tsx","../src/loadBalancer/configure/common/gceLoadBalancerSubmission.ts","../../../node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js","../src/loadBalancer/configure/http/GceHttpLoadBalancerEditor.tsx","../src/loadBalancer/configure/http/GceHttpLoadBalancerModal.tsx","../src/loadBalancer/configure/network/GceNetworkLoadBalancerEditor.tsx","../src/gce.settings.ts","../src/loadBalancer/configure/network/GceNetworkLoadBalancerModal.tsx","../src/loadBalancer/configure/choice/GceLoadBalancerChoiceModal.tsx","../src/loadBalancer/httpLoadBalancerUtils.service.ts","../src/loadBalancer/details/gceLoadBalancerDetails.tsx","../src/loadBalancer/loadBalancer.setTransformer.ts","../src/loadBalancer/loadBalancer.transformer.js","../src/logo/gce.logo.png","../src/pipeline/stages/bake/gceBakeStage.js","../src/pipeline/stages/googleStageConfig.js","../src/pipeline/stages/cloneServerGroup/gceCloneServerGroupStage.js","../src/pipeline/stages/destroyAsg/gceDestroyAsgStage.js","../src/pipeline/stages/disableAsg/gceDisableAsgStage.js","../src/pipeline/stages/disableCluster/gceDisableClusterStage.js","../src/pipeline/stages/enableAsg/gceEnableAsgStage.js","../src/pipeline/stages/findAmi/gceFindAmiStage.js","../src/pipeline/stages/findImageFromTags/gceFindImageFromTagsStage.js","../src/pipeline/stages/resizeAsg/gceResizeAsgStage.js","../src/pipeline/stages/scaleDownCluster/gceScaleDownClusterStage.js","../src/pipeline/stages/shrinkCluster/gceShrinkClusterStage.js","../src/pipeline/stages/tagImage/gceTagImageStage.js","../src/securityGroup/configure/GceSecurityGroupModal.tsx","../src/securityGroup/details/GceSecurityGroupDetails.tsx","../src/securityGroup/securityGroup.reader.js","../src/securityGroup/securityGroup.transformer.js","../src/healthCheck/healthCheckUtils.ts","../src/instance/custom/customInstanceBuilder.gce.service.js","../src/serverGroup/configure/wizard/hiddenMetadataKeys.value.js","../src/serverGroup/configure/serverGroupCommandBuilder.service.js","../src/serverGroup/configure/wizard/advancedSettings/gceAccelerator.service.ts","../src/serverGroup/configure/wizard/securityGroups/tagManager.service.js","../src/serverGroup/configure/serverGroupConfiguration.service.js","../src/serverGroup/configure/wizard/GceServerGroupWizard.helpers.ts","../src/serverGroup/configure/wizard/GceServerGroupWizardAdapter.ts","../src/serverGroup/configure/wizard/GceServerGroupWizardPage.tsx","../src/serverGroup/configure/wizard/pages/AdvancedSettings.tsx","../src/serverGroup/configure/wizard/pages/GceServerGroupFirewalls.tsx","../src/serverGroup/configure/wizard/pages/GceServerGroupLoadBalancers.tsx","../src/autoHealingPolicy/GceAutoHealingPolicyEditor.tsx","../src/autoscalingPolicy/IGceAutoscalingPolicy.ts","../src/autoscalingPolicy/GceAutoscalingPolicyWriter.ts","../src/autoscalingPolicy/GceAutoscalingPolicyEditor.tsx","../src/serverGroup/configure/wizard/pages/Policies.tsx","../src/serverGroup/configure/wizard/pages/ServerGroupBasicSettings.tsx","../src/serverGroup/configure/wizard/zones/GceInstanceFlexibilityConfigurer.tsx","../src/serverGroup/configure/wizard/pages/ServerGroupCapacity.tsx","../src/serverGroup/configure/wizard/pages/ServerGroupImageSettings.tsx","../src/serverGroup/configure/wizard/pages/ServerGroupInstanceType.tsx","../src/serverGroup/configure/wizard/GceCloneServerGroupModal.tsx","../src/serverGroup/configure/wizard/customInstance/CustomInstanceConfigurer.tsx","../src/serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder.tsx","../src/serverGroup/details/GceInstanceFlexibilityPolicyDetails.tsx","../src/serverGroup/details/autoHealingPolicy/modal/GceUpsertAutoHealingPolicyModal.tsx","../src/serverGroup/details/autoHealingPolicy/GceAutoHealingPolicyDetails.tsx","../src/serverGroup/details/autoscalingPolicy/modal/GceUpsertAutoscalingPolicyModal.tsx","../src/serverGroup/details/autoscalingPolicy/GceAutoscalingPolicyDetails.tsx","../src/serverGroup/details/resize/GceResizeServerGroupModal.tsx","../src/serverGroup/details/rollback/GceRollbackServerGroupModal.tsx","../src/serverGroup/details/gceServerGroupDetails.tsx","../src/serverGroup/serverGroup.transformer.js","../src/subnet/subnet.renderer.js","../src/validation/ApplicationNameValidator.ts","../src/gce.module.ts"],"sourcesContent":["import type { ISearchResults } from '@spinnaker/core';\nimport { InfrastructureCaches, SearchService } from '@spinnaker/core';\n\nexport interface IGceCertificate {\n account: string;\n name: string;\n provider: string;\n type: string;\n}\n\nexport class GceCertificateReader {\n public listCertificates(): Promise<IGceCertificate[]> {\n return SearchService.search<IGceCertificate>(\n { q: '', type: 'sslCertificates', allowShortQuery: 'true' },\n InfrastructureCaches.get('certificates'),\n )\n .then((searchResults: ISearchResults<IGceCertificate>) => {\n if (searchResults && searchResults.results) {\n return searchResults.results.filter((certificate) => certificate.provider === 'gce');\n } else {\n return [];\n }\n })\n .catch(() => []);\n }\n}\n","import { uniqWith } from 'lodash';\n\nimport type { ISearchResults } from '@spinnaker/core';\nimport { InfrastructureCaches, SearchService } from '@spinnaker/core';\nimport type { IGceHealthCheck } from '../domain';\n\ninterface IHealthCheckSearchResults {\n name: string;\n account: string;\n healthCheck: string; // JSON encoded string containing the real health check (it is missing the account).\n region?: string;\n kind: string;\n provider: string;\n type: string;\n}\n\nexport class GceHealthCheckReader {\n public listHealthChecks(type?: string): Promise<IGceHealthCheck[]> {\n if (type) {\n return this.listHealthChecks().then((healthChecks) =>\n healthChecks.filter((healthCheck) => healthCheck.healthCheckType === type),\n );\n } else {\n return SearchService.search(\n { q: '', type: 'healthChecks', allowShortQuery: 'true' },\n InfrastructureCaches.get('healthChecks'),\n )\n .then((searchResults: ISearchResults<IHealthCheckSearchResults>) => {\n if (searchResults && searchResults.results) {\n const healthChecks = searchResults.results\n .filter((result) => result.provider === 'gce')\n .map((result) => {\n const healthCheck = JSON.parse(result.healthCheck) as IGceHealthCheck;\n healthCheck.account = result.account;\n return healthCheck;\n });\n return uniqWith(healthChecks, (checkA: IGceHealthCheck, checkB: IGceHealthCheck) => {\n return (\n checkA.name === checkB.name &&\n checkA.healthCheckType === checkB.healthCheckType &&\n checkA.account === checkB.account\n );\n });\n } else {\n return [];\n }\n })\n .catch(() => []);\n }\n }\n}\n","'use strict';\n\nimport { InfrastructureCaches, REST, SearchService } from '@spinnaker/core';\n\nimport { GceCertificateReader } from '../certificate/certificate.reader';\nimport { GceHealthCheckReader } from '../healthCheck/healthCheck.read.service';\n\nexport class GceCacheConfigurer {\n constructor() {\n const gceCertificateReader = new GceCertificateReader();\n const gceHealthCheckReader = new GceHealthCheckReader();\n const listAddresses = () =>\n SearchService.search({ q: '', type: 'addresses', allowShortQuery: 'true' }, InfrastructureCaches.get('addresses'))\n .then((searchResults) => {\n if (searchResults && searchResults.results) {\n return searchResults.results\n .filter((result) => result.provider === 'gce')\n .map((result) => ({ ...JSON.parse(result.address), account: result.account, region: result.region }));\n }\n return [];\n })\n .catch(() => []);\n const listBackendServices = () =>\n REST('/search')\n .useCache(InfrastructureCaches.get('backendServices'))\n .query({ q: '', type: 'backendServices', allowShortQuery: 'true' })\n .get();\n\n const config = Object.create(null);\n\n config.addresses = {\n initializers: [listAddresses],\n };\n\n config.backendServices = {\n initializers: [listBackendServices],\n };\n\n config.certificates = {\n initializers: [() => gceCertificateReader.listCertificates()],\n };\n\n config.healthChecks = {\n initializers: [() => gceHealthCheckReader.listHealthChecks()],\n };\n\n return config;\n }\n}\n","import { HelpContentsRegistry } from '@spinnaker/core';\n\nconst helpContents: { [key: string]: string } = {\n 'gce.httpLoadBalancer.certificate':\n 'The name of an SSL certificate. If specified, Spinnaker will create an HTTPS load balancer.',\n 'gce.httpLoadBalancer.certificateMap':\n 'A Certificate Manager certificate map name. Certificate maps let GCP manage and auto-rotate TLS certificates, replacing individual certificate selection.',\n 'gce.httpLoadBalancer.defaultService':\n 'A default service handles any requests that do not match a specified host rule or path matching rule.',\n 'gce.httpLoadBalancer.externalIP':\n 'The IP address for this listener. If you do not specify an IP, your listener will be assigned an ephemeral IP.',\n 'gce.httpLoadBalancer.hostRule.hostPattern': 'For example, <b>example.com</b>.',\n 'gce.httpLoadBalancer.namedPort': `\n For HTTP(S) and SSL/TCP load balancers,\n incoming traffic is directed through a named port (for Spinnaker, the named port is <b>http</b>).\n The mapping from named port to port number is specified per server group\n and can be configured within the server group creation dialogue under <b>Port Name Mapping</b>.`,\n 'gce.httpLoadBalancer.pathRule.paths': 'For example, <b>/path</b> in <b>example.com/path</b>',\n 'gce.httpLoadBalancer.port':\n 'HTTP requests can be load balanced based on port 80 or port 8080. HTTPS requests can be load balanced on port 443.',\n 'gce.image.artifact':\n 'The artifact that is to be deployed to this cluster. The artifact should represent a deployable image.',\n 'gce.image.source': `\n <p>Where the image to deploy is read from.</p>\n <p>\n <b>Artifact:</b> Deploy an artifact that was supplied/created upstream. The expected artifact must be referenced here, and will be bound at runtime.\n </p>\n <p>\n <b>Prior Stage:</b> Deploy the result of the most recent Bake or Find Image stage.\n </p>\n `,\n 'gce.instance.customInstance.cores':\n '<ul><li>Above 1, vCPU count must be even.</li><li>Zones that support Haswell and Ivy Bridge processors can support custom machine types up to 32 vCPUs.</li><li>Zones that support Sandy Bridge processors can support up to 16 vCPUs.</li></ul>',\n 'gce.instance.customInstance.memory':\n '<ul><li>Memory per vCPU must be between .9 GB and 6.5 GB.</li><li>Total memory must be a multiple of 256 MB.</li><li>Memory per vCPU must be between .9 GB and 800 GB if selected extended memory feature.</li></ul>',\n 'gce.instance.customInstance.extendedmemory':\n 'Add more memory per vCPU to your VM instance. <a href=\"https://cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#extendedmemory\">Click here </a>for more information regarding extended memory',\n 'gce.instance.customMetadata.instance-template': 'The instance template used to configure this instance.',\n 'gce.instance.customMetadata.load-balancer-names':\n 'This field is used to \"remember\" what load balancers this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.global-load-balancer-names':\n 'This field is used to \"remember\" what global load balancers this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.backend-service-names':\n 'This field is used to \"remember\" what backend services this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.load-balancing-policy':\n 'This field is used to \"remember\" the load balancing policy this instance is associated with, even if it is deregistered.',\n 'gce.instance.customMetadata.startup-script': 'This script will run automatically on every boot.',\n 'gce.instance.labels.spinnaker-region': 'This label can be used to group instances when querying for metrics.',\n 'gce.instance.labels.spinnaker-server-group': 'This label can be used to group instances when querying for metrics.',\n 'gce.instance.storage':\n '<p>Storage options can be fully-configured on the <b>Advanced Settings</b> tab. These are just default settings. Please be aware of your Local SSD quotas as you provision VMs.</p>',\n 'gce.instance.storage.localSSD':\n '<p>Local SSD disks are always 375GB. All non shared-core instance types support attaching up to 8 Local SSD disks. Please be aware of your Local SSD quotas as you provision VMs.</p>',\n 'gce.instance.serviceAccount':\n '<p>Service accounts authenticate applications running on your virtual machine instances to other Google Cloud Platform services. Valid values are either \"default\" or the full email address of a custom service account.</p>',\n 'gce.instance.authScopes':\n '<p>Service account scopes specify which Google Cloud Platform APIs your instances can authenticate with, and define the level of access that your instances have with those services. You can enter custom auth scopes by typing into the blank field.</p>',\n 'gce.instance.authScopes.cloud-platform':\n '<p>The instances in this server group have full API access to all Google Cloud services.</p>',\n 'gce.instanceType.32core':\n '<p>32-core machine types are in Beta and are available only in Ivy Bridge and Haswell zones.</p>',\n 'gce.internalLoadBalancer.ports': 'Use a comma to separate up to five TCP ports.',\n 'gce.internalHttpLoadBalancer.network':\n \"Network must have a subnet whose 'purpose' is 'INTERNAL_HTTPS_LOAD_BALANCER'\",\n 'gce.loadBalancer.connectionDraining':\n '(Optional) If set, enables connection draining for this backend service. This field defines the number of seconds to wait before instances that belong to this backend service are terminated in order to drain in-flight connections.',\n 'gce.loadBalancer.detail':\n '<p>(Optional) <b>Detail</b> is a string of free-form alphanumeric characters and hyphens to describe any other variables.</p>',\n 'gce.loadBalancer.advancedSettings.healthInterval':\n '<p>Configures the interval, in seconds, between load balancer health checks.</p><p>Default: <b>10</b></p>',\n 'gce.loadBalancer.advancedSettings.healthyThreshold':\n '<p>Configures the number of healthy observations before reinstituting an instance into the load balancer’s traffic rotation.</p><p>Default: <b>10</b></p>',\n 'gce.loadBalancer.advancedSettings.unhealthyThreshold':\n '<p>Configures the number of unhealthy observations before deservicing an instance from the load balancer.</p><p>Default: <b>2</b></p>',\n 'gce.loadBalancer.healthCheck':\n '(Optional) <b>Health Checks</b> use HTTP requests to determine if a VM instance is healthy.',\n 'gce.loadBalancer.portName':\n '(Required) The <b>Port Name</b> this backend service will forward traffic to. Load balancers in GCP specify a <b>Port Name</b>, and each server group added to a load balancer needs to specify a mapping from that <b>Port Name</b> to a port to actually receive traffic.',\n 'gce.loadBalancer.portRange':\n '(Optional) Only packets addressed to ports in the specified <b>Port Range</b> will be forwarded. If left empty, all ports are forwarded. Must be a single port number or two port numbers separated by a dash. Each port number must be between 1 and 65535, inclusive. For example: 5000-5999.',\n 'gce.securityGroup.sourceCIDRs':\n 'Traffic is only allowed from sources that match one of these CIDR ranges, or one of the source tags above.',\n 'gce.securityGroup.sourceTags':\n 'Traffic is only allowed from sources that match one of these tags, or one of the source CIDR ranges below.',\n 'gce.securityGroup.targetTags': 'Traffic is only allowed if the target instance has one of these tags.',\n 'gce.securityGroup.targetServiceAccounts':\n 'Traffic is allowed if the target instance has one of these service accounts.',\n 'gce.securityGroup.sourceServiceAccounts':\n 'Traffic is allowed if the source instance has one of these service accounts.',\n 'gce.serverGroup.associatePublicIpAddress.providerField':\n 'Check if new GCE server groups in this application should be assigned a public IP address by default.',\n 'gce.serverGroup.resizeWithAutoscalingPolicy': `\n Setting the desired instance count for a server group with an autoscaler is not supported by Spinnaker;\n if the desired instance count differs from the instance count that the autoscaler wants to maintain for its configured metrics,\n it will quickly override the desired instance count.`,\n 'gce.serverGroup.scalingPolicy.coolDownPeriodSec':\n 'How long to wait before collecting information from a new instance. This should be at least the time it takes to initialize the instance.',\n 'gce.serverGroup.scalingPolicy.cpuUtilization':\n 'Autoscaler adds or removes instances to maintain this CPU usage on each instance.',\n 'gce.serverGroup.scalingPolicy.predictiveAutoscaling':\n 'Autoscaler adds or removes instances based on forecasted load. You must set a CPU utilization target to enable predictive autoscaling.',\n 'gce.serverGroup.scalingPolicy.loadBalancingUtilization':\n 'Autoscaler adds or removes instances to maintain this usage of load-balancing capacity.',\n 'gce.serverGroup.scalingPolicy.customMetricUtilizations':\n 'Autoscaler adds or removes instances to maintain this usage for custom metric.',\n 'gce.serverGroup.scalingPolicy.cronExpression': `\n Start time and recurrence using a cron expression. Examples: <br/>\n Every day at 3 PM:<br/>\n 0 15 * * *<br/>\n Every week Monday to Friday at 8:30 AM: <br/>\n 30 8 * * Mon-Fri<br/>\n Once on 30 January 2030 at midnight: <br/>\n 0 0 30 1 * 2030`,\n 'gce.serverGroup.imageName':\n '(Required) <b>Image</b> is the Google Compute Engine image. Images are restricted to the account selected.',\n 'gce.serverGroup.capacity':\n 'The number of instances that the instance group manager will attempt to maintain. Deleting or abandoning instances will affect this number, as will resizing the group.',\n 'gce.serverGroup.minCpuPlatform':\n 'The baseline minimum CPU platform to use for your instances, whenever available. Select \"Automatic\" unless you have a specific need.',\n 'gce.serverGroup.customMetadata':\n '<b>Custom Metadata</b> will be propagated to the instances in this server group. This is useful for passing in arbitrary values that can be queried by your code on the instance.',\n 'gce.serverGroup.userData':\n '<p>Custom user data will be propagated to the instances in this server group. Key/value pairs can either be newline or comma delimited.</p><strong>Example:</strong><br/> <pre>key=value<br>key2=value2</pre>',\n 'gce.serverGroup.customMetadata.load-balancer-names':\n 'This field is used to \"remember\" what load balancers this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.global-load-balancer-names':\n 'This field is used to \"remember\" what global load balancers this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.backend-service-names':\n 'This field is used to \"remember\" what backend services this server group is associated with, even if the instances are deregistered.',\n 'gce.serverGroup.customMetadata.load-balancing-policy':\n 'This field is used to \"remember\" the load balancing policy this server group is configured with, even if the server group is deregistered from the load balancer. This allows us to re-enable the server group with the same load balancing policy specified on creation.',\n 'gce.serverGroup.customMetadata.select-zones':\n 'This regional server group will be deployed only to specific zones within the region.',\n 'gce.serverGroup.customMetadata.startup-script': 'This script will run automatically on every boot.',\n 'gce.serverGroup.labels.spinnaker-region': 'This label can be used to group instances when querying for metrics.',\n 'gce.serverGroup.labels.spinnaker-server-group':\n 'This label can be used to group instances when querying for metrics.',\n 'gce.serverGroup.instanceFlexibilityPolicy':\n 'Defines named sets of acceptable machine types for a regional managed instance group. Lower ranks are preferred; Google Compute Engine selects an available type when creating each VM.',\n 'gce.serverGroup.shieldedInstanceConfig':\n 'Shielded VM features include trusted UEFI firmware and come with options for Secure Boot, Virtual Trusted Platform Module (vTPM), and Integrity Monitoring.',\n 'gce.serverGroup.shieldedVmSecureBoot':\n 'Secure boot helps protect your VM instances against boot-level and kernel-level malware and rootkits.',\n 'gce.serverGroup.shieldedVmVtpm':\n 'Virtual Trusted Platform Module (vTPM) validates your guest VM pre-boot and boot integrity, and offers key generation and protection.',\n 'gce.serverGroup.shieldedVmIntegrityMonitoring':\n 'Integrity monitoring lets you monitor and verify the runtime boot integrity of your shielded VM instances using Stackdriver reports. Note: requires vTPM to be enabled.',\n 'gce.serverGroup.preemptibility':\n 'A preemptible VM costs much less, but lasts only 24 hours. It can be terminated sooner due to system demands.',\n 'gce.serverGroup.automaticRestart':\n 'Compute Engine can automatically restart VM instances if they are terminated for non-user-initiated reasons (maintenance event, hardware failure, software failure, etc.).',\n 'gce.serverGroup.onHostMaintenance':\n 'When Compute Engine performs periodic infrastructure maintenance it can migrate your VM instances to other hardware without downtime.',\n 'gce.serverGroup.canIpForward':\n 'Forwarding allows the instance to help route packets. See <a target=\"_blank\" href=\"https://cloud.google.com/compute/docs/networking?hl=en_US#canipforward\">here</a> for more information.',\n 'gce.serverGroup.securityGroups.implicit':\n 'Firewall rules with no target tags defined will permit incoming connections that match the ingress rules to all instances in the network.',\n 'gce.serverGroup.securityGroups.targetTags':\n 'This {{firewall}} rule will be associated with this server group only if a target tag is selected.',\n 'gce.serverGroup.autoscaling.targetCPUUsage':\n 'Autoscaling adds or removes VMs in the group to maintain this level of CPU usage on each VM.',\n 'gce.serverGroup.autoscaling.targetHTTPLoadBalancingUsage':\n \"Autoscaling adds or removes VMs in the group to maintain this usage of load-balancing capacity. This value is a percentage of the 'Maximum rate' setting of the load balancer this group is used by.\",\n 'gce.serverGroup.autoscaling.targetMetric':\n 'Autoscaling adds or removes VMs in the group to maintain these target levels.',\n 'gce.serverGroup.autoscaling.minVMs':\n 'The least number of VM instances the group will contain, even if the target is not met.',\n 'gce.serverGroup.autoscaling.maxVMs': 'The largest number of VM instances allowed, even if the target is exceeded.',\n 'gce.serverGroup.autoscaling.cooldown':\n 'How long to wait before collecting information from a new instance. This should be at least the time it takes to initialize the instance. To find the minimum, create an instance from the same image and note how long it takes to start.',\n 'gce.serverGroup.autoscaling.mode':\n 'Mode of operation of the autoscaling policy. This guides the autoscaler by defining the types of scaling operations it can perform. Options are ON, ONLY_SCALE_OUT, and OFF.',\n 'gce.serverGroup.autoHealing':\n 'VMs in the group are recreated as needed. You can use a health check to recreate a VM if the health check finds the VM unresponsive. If you do not select a health check, VMs are recreated only when stopped.',\n 'gce.serverGroup.initialDelaySec':\n 'The time to allow an instance to boot and applications to fully start before the first health check.',\n 'gce.serverGroup.subnet': `\n Subnetworks allow you to regionally segment the network IP space into prefixes (subnets) and control which prefix a VM instance's internal IP address is allocated from. There are several types of GCE networks:\n <ul>\n <li><b>Legacy (non-subnet) Network</b>: IP address allocation occurs at the global network level. This means the network address space spans across all regions.</li>\n <li><b>Auto Subnet Network</b>: Server groups will be automatically assigned to the specified region's subnet.</li>\n <li><b>Custom Subnet Network</b>: A subnet must be selected for the server group. If no subnets have been created for the specified region, you will not be able to provision the server group.</li>\n </ul>`,\n 'gce.serverGroup.loadBalancingPolicy.balancingMode':\n 'Tells the load balancer when the backend is at capacity. If a backend is at capacity, new requests are routed to the nearest region that can handle requests. The balancing mode can be based on CPU utilization or requests per second (RPS).',\n 'gce.serverGroup.loadBalancingPolicy.maxRatePerInstance':\n 'The maximum number of requests per second that can be sent to the backend instance group. Input must be a number greater than zero.',\n 'gce.serverGroup.loadBalancingPolicy.maxUtilization':\n 'The maximum CPU utilization allowed for the backend. CPU utilization is calculated by averaging CPU use across all instances in the backend instance group. Input must be a number between 0 and 100.',\n 'gce.serverGroup.loadBalancingPolicy.maxConnectionsPerInstance':\n 'The target connections per second for individual instances. When this number is exceeded, requests are directed to another backend.',\n 'gce.serverGroup.loadBalancingPolicy.capacityScaler': `\n An additional control to manage your maximum CPU utilization or RPS.\n If you want your instances to operate at a max 80% CPU utilization, set your balancing mode to 80% max CPU utilization and your capacity to 100%.\n If you want to cut instance utilization by half, set your balancing mode to 80% max CPU utilization and your capacity to 50%. Input must be a number between 0 and 100.`,\n 'gce.serverGroup.loadBalancingPolicy.portName':\n 'A load balancer sends traffic to an instance group through a named port. Input must be a port name.',\n 'gce.serverGroup.loadBalancingPolicy.listeningPort':\n 'A load balancer sends traffic to an instance group through a named port. Input must be a port number (i.e., between 1 and 65535).',\n 'gce.serverGroup.traffic':\n 'Registers the server group with any associated load balancers. These registrations are used by Spinnaker to determine if the server group is enabled.',\n 'gce.serverGroup.accelerator':\n 'Attaches GPUs to instances in this server group. The set of available GPUs is dictated by the selected zone. You cannot attach GPUs to instances with shared-core machine types.',\n 'gce.tagImage.consideredStages':\n 'Limit which previous stages will be considered when locating images to tag. If left unchecked, images generated by any upstream stage will be tagged.',\n 'pipeline.config.gce.bake.accountName':\n '<p>(Optional) The name of a Google account configured within Rosco. If left blank, the first configured account will be used.</p>',\n 'pipeline.config.gce.bake.baseImage':\n '<p>(Optional) A GCE image name. For example: ubuntu-1204-precise-v20150910.</p>',\n 'gce.loadBalancerType.Network': `\n <p>Use Network Load Balancing to balance the load on your systems based on incoming IP protocol data, such as address, port, and protocol type.</p>\n <p>Network Load Balancing is a regional, non-proxied load balancer. You can use it to load balance UDP traffic, and TCP and SSL traffic on ports that are not supported by the SSL proxy and TCP proxy load balancers.</p>`,\n 'gce.loadBalancerType.HTTP(S)':\n '<p>Google Cloud Platform (GCP) HTTP(S) Load Balancing provides global load balancing for HTTP(S) requests destined for your instances.</p>',\n 'gce.loadBalancerType.Internal':\n '<p>Internal TCP/UDP Load Balancing is a regional load balancer that enables you to run and scale your services behind a private load balancing IP address that is accessible only to your internal virtual machine instances.</p>',\n 'gce.loadBalancerType.SSL':\n '<p>Google Cloud SSL Proxy Load Balancing terminates user SSL (TLS) connections at the load balancing layer, then balances the connections across your instances using the SSL or TCP protocols. This supports both IPv4 and IPv6 addresses for client traffic.</p>',\n 'gce.loadBalancerType.TCP':\n '<p>Google Cloud Platform (GCP) TCP Proxy Load Balancing allows you to use a single IP address for all users around the world. GCP TCP proxy load balancing automatically routes traffic to the instances that are closest to the user.</p>',\n};\n\nObject.keys(helpContents).forEach((key) => HelpContentsRegistry.register(key, helpContents[key]));\n","import { REST } from '@spinnaker/core';\n\nexport interface IGceImage {\n imageName: string;\n}\n\nexport class GceImageReader {\n public static findImages(params: { account?: string; provider?: string; q?: string }): Promise<IGceImage[]> {\n return REST('/images/find')\n .query(params)\n .get()\n .catch(() => [] as IGceImage[]);\n }\n\n public static getImage(/*amiName: string, region: string, credentials: string*/): Promise<IGceImage | null> {\n // GCE images are not regional so we don't need to retrieve ids scoped to regions.\n return Promise.resolve(null);\n }\n}\n","import { chain } from 'lodash';\nimport React from 'react';\nimport type { AutocompleteResult, Option } from 'react-select';\nimport { Async } from 'react-select';\n\nimport type { IGceImage } from '../image';\n\ninterface IImageSelectProps {\n availableImages: IGceImage[];\n selectedImage: string;\n selectImage: (image: string, target?: any) => void;\n target?: any;\n}\n\nexport class ImageSelect extends React.Component<IImageSelectProps> {\n private loadOptions = (inputValue: string): Promise<AutocompleteResult<string>> => {\n return new Promise((resolve) => {\n if (!inputValue || inputValue.length < 3) {\n resolve({\n options: [],\n complete: false,\n });\n } else {\n const filteredOptions = chain(this.props.availableImages)\n .filter((i) => i.imageName.toLowerCase().includes(inputValue))\n .take(20)\n .map((i) => ({ value: i.imageName, label: i.imageName }))\n .value();\n resolve({\n options: filteredOptions,\n complete: false,\n });\n }\n });\n };\n\n public render() {\n return (\n <Async\n cache={null}\n clearable={false}\n ignoreAccents={false}\n loadOptions={this.loadOptions}\n onChange={(selected: Option<string>) => this.props.selectImage(selected.value, this.props.target)}\n placeholder=\"Type at least 3 characters to search for an image...\"\n searchPromptText=\"Type at least 3 characters to search for an image...\"\n value={{ value: this.props.selectedImage, label: this.props.selectedImage }}\n />\n );\n }\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nexport class GceXpnNamingService {\n deriveProjectId = (resourceWithSelfLink) => {\n const pathSegments = resourceWithSelfLink.selfLink.split('/');\n return pathSegments[pathSegments.indexOf('projects') + 1];\n };\n\n decorateXpnResourceIfNecessary = (projectId, xpnResource) => {\n if (!xpnResource) {\n return null;\n }\n\n // A network selfLink looks like: https://compute.googleapis.com/compute/beta/projects/test-host-project/global/networks/default\n // A subnet selfLink looks like: https://compute.googleapis.com/compute/beta/projects/my-test-service-project/regions/us-west1/subnetworks/default\n const xpnResourcePathSegments = xpnResource.split('/');\n const xpnResourceProjectId = xpnResourcePathSegments[xpnResourcePathSegments.indexOf('projects') + 1];\n const xpnResourceName = _.last(xpnResourcePathSegments);\n if (xpnResourceProjectId !== projectId) {\n return xpnResourceProjectId + '/' + xpnResourceName;\n } else {\n return xpnResourceName;\n }\n };\n}\n","import React, { useLayoutEffect, useState } from 'react';\n\nimport type { IRouterInjectedProps } from '@spinnaker/core';\nimport {\n AccountTag,\n CollapsibleSection,\n ConfirmationModalService,\n Details,\n InstanceActions,\n InstanceReader,\n InstanceWriter,\n RecentHistoryService,\n withRouter,\n} from '@spinnaker/core';\n\nimport { GceXpnNamingService } from '../../common/xpnNaming.gce.service';\n\ninterface IGceInstanceDetailsProps extends IRouterInjectedProps {\n app: any;\n instance?: any;\n initialInstance?: any;\n $stateParams?: any;\n}\n\nfunction getInstanceParams(props: IGceInstanceDetailsProps): any {\n const stateParams = props.$stateParams || props.stateParams || {};\n const instance = props.instance || props.initialInstance || {};\n return {\n account: instance.account || stateParams.account || stateParams.accountId,\n instanceId: instance.instanceId || stateParams.instanceId || stateParams.id,\n region: instance.region || stateParams.region,\n };\n}\n\nfunction findInstanceSummary(app: any, instanceId: string): any {\n const serverGroups = app?.serverGroups?.data || [];\n for (const serverGroup of serverGroups) {\n const summary = (serverGroup.instances || []).find((candidate: any) => candidate.id === instanceId);\n if (summary) {\n return {\n ...summary,\n account: serverGroup.account,\n loadBalancers: serverGroup.loadBalancers || [],\n region: serverGroup.region,\n serverGroup: serverGroup.name,\n vpcId: serverGroup.vpcId,\n };\n }\n }\n\n const loadBalancers = app?.loadBalancers?.data || [];\n for (const loadBalancer of loadBalancers) {\n const summary = (loadBalancer.instances || []).find((candidate: any) => candidate.id === instanceId);\n if (summary) {\n return {\n ...summary,\n account: loadBalancer.account,\n loadBalancers: [loadBalancer.name],\n region: loadBalancer.region,\n vpcId: loadBalancer.vpcId,\n };\n }\n\n for (const serverGroup of (loadBalancer.serverGroups || []).filter((candidate: any) => candidate.isDisabled)) {\n const disabledSummary = (serverGroup.instances || []).find((candidate: any) => candidate.id === instanceId);\n if (disabledSummary) {\n return {\n ...disabledSummary,\n account: loadBalancer.account,\n loadBalancers: [loadBalancer.name],\n region: loadBalancer.region,\n serverGroup: disabledSummary.serverGroup || serverGroup.name,\n serverGroupDisabled: true,\n vpcId: loadBalancer.vpcId,\n };\n }\n }\n }\n\n return null;\n}\n\nfunction projectFromSelfLink(selfLink: string): string | undefined {\n const match = /\\/projects\\/([^/]+)/.exec(selfLink || '');\n return match?.[1];\n}\n\nexport function decorateInstance(instance: any): any {\n const xpnNaming = new GceXpnNamingService();\n const networkInterface = instance.networkInterfaces?.[0] || {};\n const project = projectFromSelfLink(instance.selfLink) || instance.account;\n const zone = instance.zone || instance.placement?.availabilityZone || instance.region;\n const network = xpnNaming.decorateXpnResourceIfNecessary(project, networkInterface.network);\n const subnet = xpnNaming.decorateXpnResourceIfNecessary(project, networkInterface.subnetwork);\n const externalIpAddress = networkInterface.accessConfigs?.[0]?.natIP;\n const internalIpAddress = networkInterface.networkIP;\n const sshLink = instance.selfLink\n ? instance.selfLink.replace('www.googleapis.com/compute/v1', 'cloudssh.developers.google.com')\n : null;\n\n return {\n ...instance,\n baseIpAddress: externalIpAddress || internalIpAddress,\n externalIpAddress,\n gcloudSSHCommand: zone ? `gcloud compute ssh ${instance.name || instance.instanceId} --zone ${zone}` : undefined,\n health: (instance.health || []).filter((health: any) => health.type !== 'Google' || health.state !== 'Unknown'),\n internalDnsName: instance.instanceId,\n internalIpAddress,\n logsLink: project\n ? `https://console.cloud.google.com/logs/query?project=${encodeURIComponent(project)}&resource=gce_instance`\n : undefined,\n network,\n region: instance.region || zone,\n sshLink,\n subnet,\n };\n}\n\nfunction hasHealthState(instance: any, type: string, state: string): boolean {\n return (instance.health || []).some((health: any) => health.type === type && health.state === state);\n}\n\nfunction getNetworkLoadBalancerNames(app: any, instance: any): string[] {\n if (!instance.loadBalancers?.length || !app.loadBalancers) {\n return [];\n }\n\n return (app.loadBalancers.data || [])\n .filter(\n (loadBalancer: any) =>\n loadBalancer.account === instance.account &&\n loadBalancer.loadBalancerType === 'NETWORK' &&\n instance.loadBalancers.includes(loadBalancer.name),\n )\n .map((loadBalancer: any) => loadBalancer.name);\n}\n\nfunction canRegisterWithLoadBalancer(app: any, instance: any): boolean {\n if (!getNetworkLoadBalancerNames(app, instance).length) {\n return false;\n }\n\n return (\n hasHealthState(instance, 'LoadBalancer', 'OutOfService') ||\n !(instance.health || []).some((health: any) => health.type === 'LoadBalancer')\n );\n}\n\nfunction canRegisterWithDiscovery(instance: any): boolean {\n const discoveryHealth = (instance.health || []).filter((health: any) => health.type === 'Discovery');\n return discoveryHealth[0]?.state === 'OutOfService';\n}\n\nexport function GceInstanceActionsComponent({\n app,\n instance,\n stateService,\n}: {\n app: any;\n instance: any;\n} & IRouterInjectedProps): JSX.Element {\n const closeIfCurrentInstance = () => {\n if (stateService.includes('**.instanceDetails', { instanceId: instance.instanceId })) {\n stateService.go('^');\n }\n };\n const confirm = (\n header: string,\n buttonText: string,\n title: string,\n submitMethod: (params?: any) => PromiseLike<any>,\n closeOnComplete = false,\n ) => {\n ConfirmationModalService.confirm({\n account: instance.account,\n askForReason: true,\n buttonText,\n header,\n submitMethod,\n taskMonitorConfig: {\n application: app,\n onTaskComplete: closeOnComplete ? closeIfCurrentInstance : undefined,\n title,\n },\n });\n };\n const networkLoadBalancerNames = getNetworkLoadBalancerNames(app, instance);\n const loadBalancerInstance = { ...instance, loadBalancers: networkLoadBalancerNames };\n const loadBalancerNames = networkLoadBalancerNames.join(' and ');\n const actions = [];\n\n if (canRegisterWithDiscovery(instance)) {\n actions.push({\n label: 'Enable in Discovery',\n triggerAction: () =>\n confirm(\n `Really enable ${instance.instanceId} in discovery?`,\n `Enable ${instance.instanceId}`,\n `Enabling ${instance.instanceId} in discovery`,\n (params = {}) => InstanceWriter.enableInstanceInDiscovery(instance, app, params),\n ),\n });\n }\n\n if (hasHealthState(instance, 'Discovery', 'Up')) {\n actions.push({\n label: 'Disable in Discovery',\n triggerAction: () =>\n confirm(\n `Really disable ${instance.instanceId} in discovery?`,\n `Disable ${instance.instanceId}`,\n `Disabling ${instance.instanceId} in discovery`,\n (params = {}) => InstanceWriter.disableInstanceInDiscovery(instance, app, params),\n ),\n });\n }\n\n if (canRegisterWithLoadBalancer(app, instance)) {\n actions.push({\n label: 'Register with Load Balancer',\n triggerAction: () =>\n confirm(\n `Really register ${instance.instanceId} with ${loadBalancerNames}?`,\n `Register ${instance.instanceId}`,\n `Registering ${instance.instanceId} with ${loadBalancerNames}`,\n (params = {}) => InstanceWriter.registerInstanceWithLoadBalancer(loadBalancerInstance, app, params),\n ),\n });\n }\n\n if (\n networkLoadBalancerNames.length > 0 &&\n (instance.health || []).some((health: any) => health.type === 'LoadBalancer')\n ) {\n actions.push({\n label: 'Deregister from Load Balancer',\n triggerAction: () =>\n confirm(\n `Really deregister ${instance.instanceId} from ${loadBalancerNames}?`,\n `Deregister ${instance.instanceId}`,\n `Deregistering ${instance.instanceId} from ${loadBalancerNames}`,\n (params = {}) => InstanceWriter.deregisterInstanceFromLoadBalancer(loadBalancerInstance, app, params),\n ),\n });\n }\n\n actions.push({\n label: 'Reboot',\n triggerAction: () =>\n confirm(\n `Really reboot ${instance.instanceId}?`,\n `Reboot ${instance.instanceId}`,\n `Rebooting ${instance.instanceId}`,\n (params = {}) =>\n InstanceWriter.rebootInstance(instance, app, { ...params, interestingHealthProviderNames: [] }),\n ),\n });\n actions.push({\n label: 'Terminate',\n triggerAction: () =>\n confirm(\n `Really terminate ${instance.instanceId}?`,\n `Terminate ${instance.instanceId}`,\n `Terminating ${instance.instanceId}`,\n (params = {}) =>\n InstanceWriter.terminateInstance(instance, app, {\n ...params,\n cloudProvider: 'gce',\n ...(instance.serverGroup ? { managedInstanceGroupName: instance.serverGroup } : {}),\n }),\n true,\n ),\n });\n\n if (instance.serverGroup) {\n actions.push({\n label: 'Terminate and Shrink Server Group',\n triggerAction: () =>\n confirm(\n `Really terminate ${instance.instanceId} and shrink ${instance.serverGroup}?`,\n `Terminate ${instance.instanceId} and shrink ${instance.serverGroup}`,\n `Terminating ${instance.instanceId} and shrinking server group`,\n (params = {}) =>\n InstanceWriter.terminateInstanceAndShrinkServerGroup(instance, app, {\n ...params,\n instanceIds: [instance.instanceId],\n serverGroupName: instance.serverGroup,\n zone: instance.placement.availabilityZone,\n }),\n true,\n ),\n });\n }\n\n return <InstanceActions actions={actions} />;\n}\n\nexport function GceInstanceDetailsComponent(props: IGceInstanceDetailsProps): JSX.Element {\n const [instance, setInstance] = useState<any>(props.initialInstance || null);\n const [loading, setLoading] = useState<boolean>(true);\n const [notFound, setNotFound] = useState<boolean>(false);\n\n useLayoutEffect(() => {\n let cancelled = false;\n const params = getInstanceParams(props);\n const summary = params.instanceId ? findInstanceSummary(props.app, params.instanceId) : null;\n const account = summary?.account || params.account;\n const region = summary?.region || params.region;\n\n setInstance(null);\n setLoading(true);\n setNotFound(false);\n\n if (!params.instanceId || !account || !region) {\n setNotFound(true);\n setLoading(false);\n return undefined;\n }\n\n RecentHistoryService.addExtraDataToLatest('instances', { account, region, serverGroup: summary?.serverGroup });\n\n InstanceReader.getInstanceDetails(account, region, params.instanceId).then(\n (details: any) => {\n if (cancelled) {\n return;\n }\n setInstance(decorateInstance({ ...summary, ...details, account, instanceId: params.instanceId, region }));\n setLoading(false);\n },\n () => {\n if (cancelled) {\n return;\n }\n setNotFound(true);\n setLoading(false);\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [props.app, props.instance, props.initialInstance, props.$stateParams, props.stateParams]);\n\n if (notFound) {\n return <div className=\"alert alert-warning\">Instance not found.</div>;\n }\n\n return (\n <Details loading={loading}>\n {instance && (\n <>\n <Details.Header\n icon={<span className=\"icon-gce\" />}\n name={instance.name || instance.instanceId}\n actions={\n <GceInstanceActionsComponent\n app={props.app}\n instance={instance}\n router={props.router}\n stateParams={props.stateParams}\n stateService={props.stateService}\n />\n }\n />\n <Details.Content loading={loading}>\n <CollapsibleSection heading=\"Instance Information\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Account</dt>\n <dd>\n <AccountTag account={instance.account} />\n </dd>\n <dt>Region</dt>\n <dd>{instance.region}</dd>\n <dt>Type</dt>\n <dd>{instance.machineType || instance.instanceType || instance.type}</dd>\n <dt>Network</dt>\n <dd>{instance.network || '-'}</dd>\n <dt>Subnet</dt>\n <dd>{instance.subnet || '-'}</dd>\n </dl>\n </CollapsibleSection>\n <CollapsibleSection heading=\"DNS\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Internal DNS Name</dt>\n <dd>{instance.internalDnsName || '-'}</dd>\n <dt>Internal IP</dt>\n <dd>{instance.internalIpAddress || '-'}</dd>\n <dt>External IP</dt>\n <dd>{instance.externalIpAddress || '-'}</dd>\n </dl>\n </CollapsibleSection>\n <CollapsibleSection heading=\"SSH\" defaultExpanded={false}>\n {instance.sshLink && (\n <p>\n <a href={instance.sshLink} target=\"_blank\" rel=\"noopener noreferrer\">\n SSH in Google Cloud Console\n </a>\n </p>\n )}\n {instance.gcloudSSHCommand && <pre>{instance.gcloudSSHCommand}</pre>}\n </CollapsibleSection>\n <CollapsibleSection heading=\"Logs\" defaultExpanded={false}>\n {instance.logsLink ? (\n <a href={instance.logsLink} target=\"_blank\" rel=\"noopener noreferrer\">\n View Google Cloud logs\n </a>\n ) : (\n <span>No log link available</span>\n )}\n </CollapsibleSection>\n </Details.Content>\n </>\n )}\n </Details>\n );\n}\n\nexport const GceInstanceActions = withRouter(GceInstanceActionsComponent);\nexport const GceInstanceDetails = withRouter(GceInstanceDetailsComponent);\n","// Duplicated from https://github.com/spinnaker/clouddriver/blob/master/clouddriver-web/config/clouddriver.yml\n// TODO(mneterval): remove after resolution of https://github.com/spinnaker/spinnaker/issues/4859\nexport const GCE_INSTANCE_TYPE_DISK_DEFAULTS = Object.freeze([\n {\n instanceType: 'n1-standard-1',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-standard-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'f1-micro',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'g1-small',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-small',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-micro',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'e2-medium',\n supportsLocalSSD: false,\n disks: [\n {\n type: 'pd-standard',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highmem-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-2',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-4',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-8',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-16',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-32',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-64',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'n1-highcpu-96',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n {\n instanceType: 'default',\n disks: [\n {\n type: 'pd-ssd',\n sizeGb: 10,\n },\n ],\n },\n]);\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { AccountService, SETTINGS } from '@spinnaker/core';\n\nimport { GCE_INSTANCE_TYPE_DISK_DEFAULTS } from './gceInstanceTypeDisks';\n\nexport class GceInstanceTypeService {\n constructor(promiseService, logger = console) {\n const cachedResult = null;\n\n const n1standard = {\n type: 'n1-standard',\n description:\n 'This family provides a balance of compute, memory, and network resources, and it is a good choice for general purpose applications.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-standard-1',\n label: 'Small',\n cpu: 1,\n memory: 3.75,\n costFactor: 1,\n },\n {\n name: 'n1-standard-2',\n label: 'Medium',\n cpu: 2,\n memory: 7.5,\n costFactor: 2,\n },\n {\n name: 'n1-standard-4',\n label: 'Large',\n cpu: 4,\n memory: 15,\n costFactor: 2,\n },\n {\n name: 'n1-standard-8',\n label: 'XLarge',\n cpu: 8,\n memory: 30,\n costFactor: 3,\n },\n {\n name: 'n1-standard-16',\n label: '2XLarge',\n cpu: 16,\n memory: 60,\n costFactor: 3,\n },\n {\n name: 'n1-standard-32',\n label: '4XLarge',\n cpu: 32,\n memory: 120,\n costFactor: 4,\n },\n {\n name: 'n1-standard-64',\n label: '8XLarge',\n cpu: 64,\n memory: 240,\n costFactor: 4,\n },\n {\n name: 'n1-standard-96',\n label: '12XLarge',\n cpu: 96,\n memory: 360,\n costFactor: 4,\n },\n ],\n };\n\n const f1micro = {\n type: 'f1-micro bursting',\n description:\n 'This family of machine types is a good choice for small, non-resource intensive 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).',\n storageType: 'Std',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'f1-micro',\n label: 'Micro',\n cpu: 1,\n memory: 0.6,\n costFactor: 1,\n },\n {\n name: 'g1-small',\n label: 'Small',\n cpu: 1,\n memory: 1.7,\n costFactor: 1,\n },\n {\n name: 'e2-micro',\n label: 'E2 Micro',\n cpu: 2,\n memory: 1,\n costFactor: 1,\n },\n {\n name: 'e2-small',\n label: 'E2 Small',\n cpu: 2,\n memory: 2,\n costFactor: 2,\n },\n {\n name: 'e2-medium',\n label: 'E2 Medium',\n cpu: 2,\n memory: 4,\n costFactor: 2,\n },\n ],\n };\n\n const n1highmem = {\n type: 'n1-highmem',\n description:\n 'High memory machine types are ideal for tasks that require more memory relative to virtual cores. High memory machine types have 6.50GB of RAM per virtual core.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-highmem-2',\n label: 'Medium',\n cpu: 2,\n memory: 13,\n costFactor: 2,\n },\n {\n name: 'n1-highmem-4',\n label: 'Large',\n cpu: 4,\n memory: 26,\n costFactor: 2,\n },\n {\n name: 'n1-highmem-8',\n label: 'XLarge',\n cpu: 8,\n memory: 52,\n costFactor: 3,\n },\n {\n name: 'n1-highmem-16',\n label: '2XLarge',\n cpu: 16,\n memory: 104,\n costFactor: 3,\n },\n {\n name: 'n1-highmem-32',\n label: '4XLarge',\n cpu: 32,\n memory: 208,\n costFactor: 4,\n },\n {\n name: 'n1-highmem-64',\n label: '8XLarge',\n cpu: 64,\n memory: 416,\n costFactor: 4,\n },\n {\n name: 'n1-highmem-96',\n label: '12XLarge',\n cpu: 96,\n memory: 624,\n costFactor: 4,\n },\n ],\n };\n\n const n1highcpu = {\n type: 'n1-highcpu',\n description:\n 'High CPU machine types are ideal for tasks that require more virtual cores relative to memory. High CPU machine types have one virtual core for every 0.90GB of RAM.',\n storageType: 'SSD',\n storageHelpFieldKey: 'gce.instance.storage',\n instanceTypes: [\n {\n name: 'n1-highcpu-2',\n label: 'Medium',\n cpu: 2,\n memory: 1.8,\n costFactor: 1,\n },\n {\n name: 'n1-highcpu-4',\n label: 'Large',\n cpu: 4,\n memory: 3.6,\n costFactor: 2,\n },\n {\n name: 'n1-highcpu-8',\n label: 'XLarge',\n cpu: 8,\n memory: 7.2,\n costFactor: 2,\n },\n {\n name: 'n1-highcpu-16',\n label: '2XLarge',\n cpu: 16,\n memory: 14.4,\n costFactor: 3,\n },\n {\n name: 'n1-highcpu-32',\n label: '4XLarge',\n cpu: 32,\n memory: 28.8,\n costFactor: 4,\n },\n {\n name: 'n1-highcpu-64',\n label: '8XLarge',\n cpu: 64,\n memory: 57.6,\n costFactor: 4,\n },\n {\n name: 'n1-highcpu-96',\n label: '12XLarge',\n cpu: 96,\n memory: 86.4,\n costFactor: 4,\n },\n ],\n };\n\n const customMachine = {\n type: 'buildCustom',\n instanceTypes: [\n {\n name: 'n1buildCustom',\n nameRegex: /custom-\\d{1,2}-\\d{4,6}/,\n storage: {\n localSSDSupported: true,\n },\n },\n {\n name: 'e2buildCustom',\n nameRegex: /e2-custom-(\\d{1,2})-(\\d{3,6})/,\n storage: {\n localSSDSupported: false,\n },\n },\n {\n name: 'otherbuildCustom',\n nameRegex: /(.*)-?custom-(\\d{1,2})-(\\d{3,6})/,\n storage: {\n localSSDSupported: true,\n },\n },\n ],\n };\n\n const categories = [\n {\n type: 'general',\n label: 'General Purpose',\n families: [n1standard],\n icon: 'hdd',\n },\n {\n type: 'memory',\n label: 'High Memory',\n families: [n1highmem],\n icon: 'hdd',\n },\n {\n type: 'cpu',\n label: 'High CPU',\n families: [n1highcpu],\n icon: 'hdd',\n },\n {\n type: 'micro',\n label: 'Micro Utility',\n families: [f1micro],\n icon: 'hdd',\n },\n {\n type: 'custom',\n label: 'Custom Type',\n families: [],\n icon: 'asterisk',\n },\n {\n type: 'buildCustom',\n label: 'Build Custom',\n families: [customMachine],\n icon: 'wrench',\n },\n ];\n\n const getCategories = _.memoize(() => {\n const initializedCategories = _.cloneDeep(categories);\n return AccountService.getAllAccountDetailsForProvider('gce').then((accountDetails) => {\n // All GCE accounts have the same instance type disk defaults, so we can pick the first one.\n let instanceTypeDisks = _.get(accountDetails, '[0].instanceTypeDisks');\n if (_.isEmpty(instanceTypeDisks)) {\n instanceTypeDisks = GCE_INSTANCE_TYPE_DISK_DEFAULTS;\n }\n if (instanceTypeDisks) {\n const families = _.flatten(initializedCategories.map((category) => category.families));\n families.forEach((family) => {\n family.instanceTypes.forEach((instanceType) => {\n const diskDefaults = instanceTypeDisks.find(\n (instanceTypeDisk) => instanceTypeDisk.instanceType === instanceType.name,\n );\n if (diskDefaults) {\n const disks = diskDefaults.disks\n .map((disk) => {\n switch (disk.type) {\n case 'PD_SSD':\n return {\n type: 'pd-ssd',\n sizeGb: disk.sizeGb,\n };\n case 'PD_STANDARD':\n return {\n type: 'pd-standard',\n sizeGb: disk.sizeGb,\n };\n case 'LOCAL_SSD':\n return {\n type: 'local-ssd',\n sizeGb: 375,\n };\n default:\n logger.warn(`Disk type '${disk.type}' not supported.`);\n return null;\n }\n })\n .filter((disk) => !!disk);\n\n let size = 0;\n let count = 0;\n if (diskDefaults.supportsLocalSSD) {\n count = disks.filter((disk) => disk.type === 'local-ssd').length;\n size = 375;\n } else {\n // TODO(dpeach): This will render the disk defaults incorrectly for f1-micro and g1-small instance types\n // if the disk defaults set in Clouddriver have different sizes. Fixing it will require updating\n // the core instance type selector.\n // This logic will render the count of the largest disk.\n const persistentDisks = disks.filter((disk) => disk.type.startsWith('pd-'));\n if (persistentDisks.length) {\n size = persistentDisks.reduce((maxSizeGb, disk) => Math.max(maxSizeGb, disk.sizeGb), 0);\n count = persistentDisks.filter((disk) => disk.sizeGb === size).length;\n }\n }\n\n instanceType.storage = {\n localSSDSupported: diskDefaults.supportsLocalSSD,\n size: size,\n count: count,\n defaultSettings: { disks },\n };\n }\n });\n });\n }\n return initializedCategories;\n });\n });\n\n function getAllTypesByRegion() {\n if (cachedResult) {\n return promiseService.resolve(cachedResult);\n }\n\n return getCategories().then((categories) => {\n return _.chain(categories)\n .map('families')\n .flatten()\n .map('instanceTypes')\n .flatten()\n .map('name')\n .filter((name) => name !== 'n1buildCustom' && name !== 'e2buildCustom' && name !== 'otherbuildCustom')\n .value();\n });\n }\n\n function getAvailableTypesForLocations(locationToInstanceTypesMap, selectedLocations) {\n if (!locationToInstanceTypesMap || !selectedLocations || selectedLocations.length === 0) {\n console.error('Invalid input parameters');\n return [];\n }\n\n const availableTypes = selectedLocations\n .filter((location) => locationToInstanceTypesMap[location])\n .flatMap((location) => locationToInstanceTypesMap[location].instanceTypes || []);\n\n return availableTypes;\n }\n\n const getAvailableTypesForRegions = getAvailableTypesForLocations;\n\n const resolveInstanceTypeDetails = (instanceType) => {\n return {\n name: instanceType,\n storage: Object.assign({ isDefault: true }, SETTINGS.providers.gce.defaults.instanceTypeStorage),\n };\n };\n\n return {\n getCategories: getCategories,\n getAvailableTypesForRegions: getAvailableTypesForRegions,\n getAllTypesByRegion: getAllTypesByRegion,\n getAvailableTypesForLocations: getAvailableTypesForLocations,\n resolveInstanceTypeDetails: resolveInstanceTypeDetails,\n };\n }\n}\n","'use strict';\n\nconst transformers = {\n rebootInstances: (job) => {\n job.interestingHealthProviderNames = [];\n },\n};\n\nconst transformAll = (instanceGroup, job) => {\n job.zone = instanceGroup.instances[0].availabilityZone;\n};\n\nexport class GceMultiInstanceTaskTransformer {\n transform = (instanceGroup, job) => {\n transformAll(instanceGroup, job);\n if (transformers[job.type]) {\n transformers[job.type](job);\n }\n };\n}\n","import type { ISearchResults } from '@spinnaker/core';\nimport {\n AccountService,\n InfrastructureCaches,\n NetworkReader,\n REST,\n SearchService,\n SubnetReader,\n} from '@spinnaker/core';\n\nimport { GceCertificateReader } from '../../../certificate/certificate.reader';\nimport { GceHealthCheckReader } from '../../../healthCheck/healthCheck.read.service';\n\nexport interface IGceLoadBalancerDataItem {\n name: string;\n}\n\nexport interface IGceLoadBalancerData {\n accounts: IGceLoadBalancerDataItem[];\n addresses: IGceLoadBalancerDataItem[];\n backendServices: IGceLoadBalancerDataItem[];\n certificates: IGceLoadBalancerDataItem[];\n healthChecks: IGceLoadBalancerDataItem[];\n networks: IGceLoadBalancerDataItem[];\n regions: IGceLoadBalancerDataItem[];\n subnets: IGceLoadBalancerDataItem[];\n}\n\nexport interface IGceLoadBalancerDataReaders {\n accounts: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n addresses: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n backendServices: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n certificates: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n healthChecks: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n networks: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n regions: (account: string) => PromiseLike<IGceLoadBalancerDataItem[]>;\n subnets: () => PromiseLike<IGceLoadBalancerDataItem[]>;\n}\n\nexport type GceLoadBalancerDataStatus = 'idle' | 'loading' | 'ready' | 'error';\n\nexport interface IGceLoadBalancerDataState {\n data: IGceLoadBalancerData;\n error?: unknown;\n status: GceLoadBalancerDataStatus;\n}\n\ntype GceLoadBalancerDataListener = (state: IGceLoadBalancerDataState) => void;\n\nconst EMPTY_DATA: IGceLoadBalancerData = {\n accounts: [],\n addresses: [],\n backendServices: [],\n certificates: [],\n healthChecks: [],\n networks: [],\n regions: [],\n subnets: [],\n};\n\nexport class GceLoadBalancerDataController {\n private disposed = false;\n private listeners = new Set<GceLoadBalancerDataListener>();\n private requestId = 0;\n private state: IGceLoadBalancerDataState = { data: EMPTY_DATA, status: 'idle' };\n\n constructor(private readers: IGceLoadBalancerDataReaders = gceLoadBalancerDataReaders) {}\n\n public getState(): IGceLoadBalancerDataState {\n return this.state;\n }\n\n public subscribe(listener: GceLoadBalancerDataListener): () => void {\n if (!this.disposed) {\n this.listeners.add(listener);\n }\n return () => this.listeners.delete(listener);\n }\n\n public async load(account: string): Promise<void> {\n const requestId = ++this.requestId;\n this.publish({ data: this.state.data, error: undefined, status: 'loading' });\n\n try {\n const [\n accounts,\n addresses,\n backendServices,\n certificates,\n healthChecks,\n networks,\n regions,\n subnets,\n ] = await Promise.all([\n this.readers.accounts(),\n this.readers.addresses(),\n this.readers.backendServices(),\n this.readers.certificates(),\n this.readers.healthChecks(),\n this.readers.networks(),\n this.readers.regions(account),\n this.readers.subnets(),\n ]);\n if (this.isCurrent(requestId)) {\n this.publish({\n data: { accounts, addresses, backendServices, certificates, healthChecks, networks, regions, subnets },\n error: undefined,\n status: 'ready',\n });\n }\n } catch (error) {\n if (this.isCurrent(requestId)) {\n this.publish({ data: this.state.data, error, status: 'error' });\n }\n }\n }\n\n public dispose(): void {\n this.disposed = true;\n this.requestId += 1;\n this.listeners.clear();\n }\n\n private isCurrent(requestId: number): boolean {\n return !this.disposed && requestId === this.requestId;\n }\n\n private publish(state: IGceLoadBalancerDataState): void {\n if (this.disposed) {\n return;\n }\n this.state = state;\n this.listeners.forEach((listener) => listener(state));\n }\n}\n\nexport function mergeGceResourceOptions<T extends IGceLoadBalancerDataItem>(\n available: readonly T[],\n persisted: readonly T[],\n): T[] {\n const availableNames = new Set(available.map(({ name }) => name));\n return [...available, ...persisted.filter(({ name }) => name && !availableNames.has(name))];\n}\n\ninterface IAddressSearchResult {\n account: string;\n address: string;\n name: string;\n provider: string;\n region: string;\n type: string;\n}\n\nconst certificateReader = new GceCertificateReader();\nconst healthCheckReader = new GceHealthCheckReader();\n\nexport const gceLoadBalancerDataReaders: IGceLoadBalancerDataReaders = {\n accounts: () => AccountService.listAccounts('gce') as PromiseLike<IGceLoadBalancerDataItem[]>,\n regions: (account) =>\n AccountService.getRegionsForAccount(account).then((regions) => {\n if (Array.isArray(regions)) {\n return regions as IGceLoadBalancerDataItem[];\n }\n return Object.keys(regions || {}).map((name) => ({ name }));\n }),\n networks: () => NetworkReader.listNetworksByProvider('gce') as PromiseLike<IGceLoadBalancerDataItem[]>,\n subnets: () => SubnetReader.listSubnetsByProvider('gce') as PromiseLike<IGceLoadBalancerDataItem[]>,\n certificates: () => certificateReader.listCertificates() as PromiseLike<IGceLoadBalancerDataItem[]>,\n healthChecks: () => healthCheckReader.listHealthChecks() as PromiseLike<IGceLoadBalancerDataItem[]>,\n addresses: () =>\n SearchService.search<IAddressSearchResult>(\n { q: '', type: 'addresses', allowShortQuery: 'true' },\n InfrastructureCaches.get('addresses'),\n ).then((searchResults: ISearchResults<IAddressSearchResult>) =>\n (searchResults?.results || [])\n .filter(({ provider }) => provider === 'gce')\n .map((result) => ({ ...JSON.parse(result.address), account: result.account, region: result.region })),\n ),\n backendServices: () =>\n REST('/search')\n .useCache(true)\n .query({ q: '', type: 'backendServices', allowShortQuery: 'true' })\n .get()\n .then(normalizeBackendServiceResults),\n};\n\nfunction normalizeBackendServiceResults(response: unknown): IGceLoadBalancerDataItem[] {\n const first = Array.isArray(response) && response.length === 1 ? response[0] : response;\n const results = first && typeof first === 'object' && 'results' in first ? first.results : first;\n return Array.isArray(results) ? (results as IGceLoadBalancerDataItem[]) : [];\n}\n","export const GCE_LOAD_BALANCER_TYPES = ['NETWORK', 'INTERNAL', 'TCP', 'SSL', 'HTTP', 'INTERNAL_MANAGED'] as const;\n\nexport type GceLoadBalancerType = typeof GCE_LOAD_BALANCER_TYPES[number];\nexport type GceLoadBalancerEditorMode = 'create' | 'edit' | 'pipeline';\nexport type GceLoadBalancerProtocol = 'TCP' | 'UDP' | 'HTTP' | 'HTTPS' | 'HTTP2' | 'GRPC' | 'SSL';\n\nexport interface IGceLoadBalancerCapabilities {\n address: boolean;\n backendServices: boolean;\n certificates: boolean;\n healthChecks: boolean;\n hostRules: boolean;\n network: boolean;\n subnet: boolean;\n}\n\nexport const GCE_LOAD_BALANCER_CAPABILITIES: Record<GceLoadBalancerType, IGceLoadBalancerCapabilities> = {\n NETWORK: capabilities({ address: true, healthChecks: true }),\n INTERNAL: capabilities({\n address: true,\n backendServices: true,\n healthChecks: true,\n network: true,\n subnet: true,\n }),\n TCP: capabilities({ address: true, backendServices: true, healthChecks: true }),\n SSL: capabilities({ address: true, backendServices: true, certificates: true, healthChecks: true }),\n HTTP: capabilities({\n address: true,\n backendServices: true,\n certificates: true,\n healthChecks: true,\n hostRules: true,\n }),\n INTERNAL_MANAGED: capabilities({\n address: true,\n backendServices: true,\n certificates: true,\n healthChecks: true,\n hostRules: true,\n network: true,\n subnet: true,\n }),\n};\n\nexport interface IGceResourceReference {\n name: string;\n selfLink?: string;\n [key: string]: unknown;\n}\n\nexport interface IGceLoadBalancerListener {\n name: string;\n protocol: GceLoadBalancerProtocol;\n portRange: string;\n address?: IGceResourceReference;\n certificate?: IGceResourceReference;\n certificateMap?: string;\n subnet?: IGceResourceReference;\n}\n\nexport interface IGceLoadBalancerHealthCheck {\n checkIntervalSec?: number;\n grpcServiceName?: string;\n healthCheckType?: GceLoadBalancerProtocol;\n healthyThreshold?: number;\n host?: string;\n name?: string;\n port?: number;\n proxyHeader?: string;\n requestPath?: string;\n timeoutSec?: number;\n unhealthyThreshold?: number;\n useServingPort?: boolean;\n [key: string]: unknown;\n}\n\nexport interface IGceLoadBalancerBackendService {\n name: string;\n healthCheck?: IGceResourceReference;\n [key: string]: unknown;\n}\n\nexport interface IGceLoadBalancerPathRule {\n backendService?: IGceResourceReference;\n paths: string[];\n}\n\nexport interface IGceLoadBalancerPathMatcher {\n defaultService?: IGceResourceReference;\n pathRules: IGceLoadBalancerPathRule[];\n}\n\nexport interface IGceLoadBalancerHostRule {\n hostPatterns: string[];\n pathMatcher: IGceLoadBalancerPathMatcher;\n}\n\nexport interface IGceLoadBalancerOriginalState {\n backendServices: IGceLoadBalancerBackendService[];\n healthChecks: IGceLoadBalancerHealthCheck[];\n listeners: IGceLoadBalancerListener[];\n}\n\ninterface IGceLoadBalancerCommandBase {\n mode: GceLoadBalancerEditorMode;\n name: string;\n credentials: string;\n region: string;\n loadBalancerType: GceLoadBalancerType;\n listeners: IGceLoadBalancerListener[];\n healthChecks: IGceLoadBalancerHealthCheck[];\n backendServices: IGceLoadBalancerBackendService[];\n hostRules: IGceLoadBalancerHostRule[];\n defaultService?: IGceResourceReference;\n network?: IGceResourceReference;\n original?: IGceLoadBalancerOriginalState;\n subnet?: IGceResourceReference;\n}\n\nexport interface IGceCreateLoadBalancerCommand extends IGceLoadBalancerCommandBase {\n mode: 'create';\n}\n\nexport interface IGceEditLoadBalancerCommand extends IGceLoadBalancerCommandBase {\n mode: 'edit';\n}\n\nexport interface IGcePipelineLoadBalancerCommand extends IGceLoadBalancerCommandBase {\n mode: 'pipeline';\n}\n\nexport type IGceLoadBalancerCommand =\n | IGceCreateLoadBalancerCommand\n | IGceEditLoadBalancerCommand\n | IGcePipelineLoadBalancerCommand;\n\nexport interface IGceSerializedLoadBalancerCommand {\n [key: string]: unknown;\n cloudProvider: 'gce';\n credentials: string;\n loadBalancerName: string;\n loadBalancerType: GceLoadBalancerType;\n name: string;\n provider: 'gce';\n region: string;\n type: 'upsertLoadBalancer';\n}\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport function normalizeGceLoadBalancerCommand(\n persisted: UnknownRecord,\n mode: GceLoadBalancerEditorMode,\n): IGceLoadBalancerCommand {\n const loadBalancerType = normalizeLoadBalancerType(persisted.loadBalancerType);\n const name = asString(\n isHttpType(loadBalancerType)\n ? persisted.urlMapName || persisted.name || persisted.loadBalancerName\n : persisted.name || persisted.loadBalancerName,\n );\n const topLevelListener = {\n address: persisted.ipAddress || persisted.address,\n certificate: persisted.certificate,\n name: isHttpType(loadBalancerType) ? persisted.loadBalancerName || persisted.name || name : name,\n portRange: persisted.portRange || persisted.ports,\n protocol:\n persisted.protocol ||\n (isHttpType(loadBalancerType) ? (persisted.certificate ? 'HTTPS' : 'HTTP') : persisted.ipProtocol),\n subnet: persisted.subnet,\n };\n const listeners = asArray(persisted.listeners).length ? asArray(persisted.listeners) : [topLevelListener];\n const backendServices = collectBackendServices(persisted);\n const healthChecks = collectHealthChecks(persisted, backendServices);\n\n const command = {\n mode,\n name,\n credentials: asString(persisted.credentials || persisted.account),\n region: asString(persisted.region) || defaultRegion(loadBalancerType),\n loadBalancerType,\n listeners: listeners.map((listener) => normalizeListener(asRecord(listener), loadBalancerType, name)),\n healthChecks,\n backendServices,\n hostRules: asArray(persisted.hostRules).map((hostRule) => normalizeHostRule(asRecord(hostRule))),\n defaultService: normalizeReference(persisted.defaultService),\n network: normalizeReference(persisted.network),\n subnet: normalizeReference(persisted.subnet),\n } as IGceLoadBalancerCommand;\n\n if (mode === 'edit') {\n command.original = cloneValue({ backendServices, healthChecks, listeners: command.listeners });\n }\n return command;\n}\n\nexport function serializeGceLoadBalancerCommand(command: IGceLoadBalancerCommand): IGceSerializedLoadBalancerCommand {\n const capabilitiesForType = GCE_LOAD_BALANCER_CAPABILITIES[command.loadBalancerType];\n const listener = command.listeners[0];\n const serialized: IGceSerializedLoadBalancerCommand = {\n cloudProvider: 'gce',\n credentials: command.credentials,\n loadBalancerName: command.name,\n loadBalancerType: command.loadBalancerType,\n name: command.name,\n provider: 'gce',\n region: command.region,\n type: 'upsertLoadBalancer',\n };\n\n if (isHttpType(command.loadBalancerType)) {\n serialized.listeners = command.listeners.map((currentListener) =>\n serializeListener(currentListener, capabilitiesForType),\n );\n } else if (listener) {\n serialized.ipProtocol = listener.protocol;\n serialized.portRange = listener.portRange;\n }\n if (capabilitiesForType.address && listener?.address) {\n serialized.ipAddress = serializeReservedAddress(listener.address);\n }\n if (capabilitiesForType.certificates && listener?.certificate) {\n serialized.certificate = serializeCertificateName(listener.certificate);\n }\n if (capabilitiesForType.healthChecks && command.healthChecks.length) {\n serialized.healthChecks = command.healthChecks.map((healthCheck) => ({ ...healthCheck }));\n }\n if (capabilitiesForType.backendServices && command.backendServices.length) {\n serialized.backendServices = command.backendServices.map(serializeBackendService);\n }\n if (capabilitiesForType.hostRules && command.hostRules.length) {\n serialized.hostRules = command.hostRules.map(serializeHostRule);\n }\n if (capabilitiesForType.backendServices && command.defaultService) {\n serialized.defaultService = serializeBackendServiceName(command.defaultService);\n }\n if (capabilitiesForType.network && command.network) {\n serialized.network = serializeNetworkName(command.network);\n }\n if (capabilitiesForType.subnet && command.subnet) {\n serialized.subnet = serializeSubnetName(command.subnet);\n }\n\n return serialized;\n}\n\nfunction capabilities(overrides: Partial<IGceLoadBalancerCapabilities>): IGceLoadBalancerCapabilities {\n return {\n address: false,\n backendServices: false,\n certificates: false,\n healthChecks: false,\n hostRules: false,\n network: false,\n subnet: false,\n ...overrides,\n };\n}\n\nfunction normalizeLoadBalancerType(value: unknown): GceLoadBalancerType {\n const normalized = asString(value).toUpperCase() as GceLoadBalancerType;\n return GCE_LOAD_BALANCER_TYPES.includes(normalized) ? normalized : 'NETWORK';\n}\n\nfunction normalizeProtocol(value: unknown, type: GceLoadBalancerType): GceLoadBalancerProtocol {\n const normalized = asString(value).toUpperCase();\n if (['TCP', 'UDP', 'HTTP', 'HTTPS', 'HTTP2', 'GRPC', 'SSL'].includes(normalized)) {\n return normalized as GceLoadBalancerProtocol;\n }\n if (type === 'SSL') {\n return 'SSL';\n }\n return isHttpType(type) ? 'HTTP' : 'TCP';\n}\n\nfunction normalizeListener(\n listener: UnknownRecord,\n type: GceLoadBalancerType,\n fallbackName: string,\n): IGceLoadBalancerListener {\n const normalized: IGceLoadBalancerListener = {\n name: asString(listener.name) || fallbackName,\n protocol: normalizeProtocol(\n listener.protocol ||\n (isHttpType(type)\n ? listener.certificate || listener.certificateMap || Number(listener.port || listener.portRange) === 443\n ? 'HTTPS'\n : 'HTTP'\n : listener.ipProtocol),\n type,\n ),\n portRange: normalizePortRange(listener.portRange || listener.port || listener.ports),\n };\n const address = normalizeReference(listener.address || listener.ipAddress);\n const certificate = normalizeReference(listener.certificate);\n const certificateMap = asString(listener.certificateMap);\n const subnet = normalizeReference(listener.subnet);\n if (address) {\n normalized.address = address;\n }\n if (certificate) {\n normalized.certificate = certificate;\n }\n if (certificateMap) {\n normalized.certificateMap = certificateMap;\n }\n if (subnet) {\n normalized.subnet = subnet;\n }\n return normalized;\n}\n\nexport function normalizeGceHealthCheck(value: unknown): IGceLoadBalancerHealthCheck {\n const healthCheck = asRecord(value);\n const normalized: IGceLoadBalancerHealthCheck = { ...healthCheck };\n const healthCheckType = asString(healthCheck.healthCheckType || healthCheck.protocol);\n if (healthCheckType) {\n normalized.healthCheckType = normalizeProtocol(healthCheckType, 'NETWORK');\n }\n (['port', 'checkIntervalSec', 'timeoutSec', 'healthyThreshold', 'unhealthyThreshold'] as const).forEach((field) => {\n if (healthCheck[field] !== undefined && healthCheck[field] !== null && healthCheck[field] !== '') {\n normalized[field] = Number(healthCheck[field]);\n }\n });\n if (healthCheck.requestPath) {\n const requestPath = asString(healthCheck.requestPath);\n normalized.requestPath = requestPath.startsWith('/') ? requestPath : `/${requestPath}`;\n }\n return normalized;\n}\n\nfunction normalizeBackendService(service: UnknownRecord): IGceLoadBalancerBackendService {\n const normalized: IGceLoadBalancerBackendService = { ...service, name: asString(service.name) };\n const healthCheck = normalizeReference(service.healthCheck || service.healthCheckLink);\n if (healthCheck) {\n normalized.healthCheck = healthCheck;\n }\n delete normalized.healthCheckLink;\n return normalized;\n}\n\nfunction collectBackendServices(persisted: UnknownRecord): IGceLoadBalancerBackendService[] {\n const candidates = [...asArray(persisted.backendServices), ...asArray(persisted.backendService)];\n if (persisted.defaultService && typeof persisted.defaultService === 'object') {\n candidates.push(persisted.defaultService);\n }\n asArray(persisted.hostRules).forEach((hostRuleValue) => {\n const pathMatcher = asRecord(asRecord(hostRuleValue).pathMatcher);\n if (pathMatcher.defaultService && typeof pathMatcher.defaultService === 'object') {\n candidates.push(pathMatcher.defaultService);\n }\n asArray(pathMatcher.pathRules).forEach((pathRuleValue) => {\n const backendService = asRecord(pathRuleValue).backendService;\n if (backendService && typeof backendService === 'object') {\n candidates.push(backendService);\n }\n });\n });\n\n const services = new Map<string, IGceLoadBalancerBackendService>();\n candidates.forEach((candidate) => {\n const service = normalizeBackendService(\n typeof candidate === 'object' ? asRecord(candidate) : { name: asString(candidate) },\n );\n if (service.name && !services.has(service.name)) {\n services.set(service.name, service);\n }\n });\n return Array.from(services.values());\n}\n\nfunction collectHealthChecks(\n persisted: UnknownRecord,\n backendServices: IGceLoadBalancerBackendService[],\n): IGceLoadBalancerHealthCheck[] {\n const candidates = [...asArray(persisted.healthChecks), ...asArray(persisted.healthCheck)];\n backendServices.forEach((service) => {\n if (service.healthCheck && Object.keys(service.healthCheck).some((key) => key !== 'name' && key !== 'selfLink')) {\n candidates.push(service.healthCheck);\n }\n });\n const healthChecks = new Map<string, IGceLoadBalancerHealthCheck>();\n candidates.forEach((candidate, index) => {\n const healthCheck = normalizeGceHealthCheck(asRecord(candidate));\n const key = healthCheck.name || (Object.keys(healthCheck).length ? `unnamed-${index}` : '');\n if (key && !healthChecks.has(key)) {\n healthChecks.set(key, healthCheck);\n }\n });\n return Array.from(healthChecks.values());\n}\n\nfunction normalizeHostRule(hostRule: UnknownRecord): IGceLoadBalancerHostRule {\n const pathMatcher = asRecord(hostRule.pathMatcher);\n return {\n hostPatterns: asStringArray(hostRule.hostPatterns),\n pathMatcher: {\n defaultService: normalizeReference(pathMatcher.defaultService),\n pathRules: asArray(pathMatcher.pathRules).map((pathRule) => {\n const rule = asRecord(pathRule);\n return {\n backendService: normalizeReference(rule.backendService),\n paths: asStringArray(rule.paths),\n };\n }),\n },\n };\n}\n\nfunction normalizeReference(value: unknown): IGceResourceReference | undefined {\n if (!value) {\n return undefined;\n }\n if (typeof value === 'object') {\n const reference = asRecord(value);\n const name = asString(reference.name || reference.id || reference.address || reference.selfLink);\n return name ? ({ ...reference, name } as IGceResourceReference) : undefined;\n }\n const reference = asString(value);\n const name = reference.split('/').filter(Boolean).pop() || reference;\n return reference.includes('/') ? { name, selfLink: reference } : { name };\n}\n\nfunction serializeReservedAddress(reference: IGceResourceReference): string {\n return asString(reference.address) || reference.name;\n}\n\nfunction serializeCertificateName(reference: IGceResourceReference): string {\n return reference.name;\n}\n\nfunction serializeNetworkName(reference: IGceResourceReference): string {\n return reference.name;\n}\n\nfunction serializeSubnetName(reference: IGceResourceReference): string {\n return reference.name;\n}\n\nfunction serializeBackendServiceName(reference: IGceResourceReference): string {\n return reference.name;\n}\n\nfunction serializeHealthCheckName(reference: IGceResourceReference): string {\n return reference.name;\n}\n\nfunction serializeListener(\n listener: IGceLoadBalancerListener,\n capabilitiesForType: IGceLoadBalancerCapabilities,\n): UnknownRecord {\n const serialized: UnknownRecord = {\n name: listener.name,\n portRange: listener.protocol === 'HTTPS' ? '443' : listener.portRange,\n protocol: listener.protocol,\n };\n if (capabilitiesForType.address && listener.address) {\n serialized.ipAddress = serializeReservedAddress(listener.address);\n }\n if (capabilitiesForType.certificates && listener.certificate) {\n serialized.certificate = serializeCertificateName(listener.certificate);\n }\n if (capabilitiesForType.certificates && listener.certificateMap) {\n serialized.certificateMap = listener.certificateMap;\n }\n if (capabilitiesForType.subnet && listener.subnet) {\n serialized.subnet = serializeSubnetName(listener.subnet);\n }\n return serialized;\n}\n\nfunction serializeBackendService(service: IGceLoadBalancerBackendService): UnknownRecord {\n const serialized: UnknownRecord = { ...service };\n if (service.healthCheck) {\n serialized.healthCheck = serializeHealthCheckName(service.healthCheck);\n }\n return serialized;\n}\n\nfunction serializeHostRule(hostRule: IGceLoadBalancerHostRule): UnknownRecord {\n return {\n hostPatterns: [...hostRule.hostPatterns],\n pathMatcher: {\n defaultService: hostRule.pathMatcher.defaultService\n ? serializeBackendServiceName(hostRule.pathMatcher.defaultService)\n : undefined,\n pathRules: hostRule.pathMatcher.pathRules.map((pathRule) => ({\n backendService: pathRule.backendService ? serializeBackendServiceName(pathRule.backendService) : undefined,\n paths: [...pathRule.paths],\n })),\n },\n };\n}\n\nfunction normalizePortRange(value: unknown): string {\n return Array.isArray(value) ? value.map(String).join(',') : asString(value);\n}\n\nfunction defaultRegion(type: GceLoadBalancerType): string {\n return ['TCP', 'SSL', 'HTTP'].includes(type) ? 'global' : '';\n}\n\nfunction isHttpType(type: GceLoadBalancerType): boolean {\n return type === 'HTTP' || type === 'INTERNAL_MANAGED';\n}\n\nfunction asRecord(value: unknown): UnknownRecord {\n return value && typeof value === 'object' ? (value as UnknownRecord) : {};\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (value === undefined || value === null) {\n return [];\n }\n return Array.isArray(value) ? value : [value];\n}\n\nfunction asString(value: unknown): string {\n return value === undefined || value === null ? '' : String(value);\n}\n\nfunction asStringArray(value: unknown): string[] {\n return asArray(value).map(asString).filter(Boolean);\n}\n\nfunction cloneValue<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(cloneValue) as T;\n }\n if (value && typeof value === 'object') {\n return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, cloneValue(item)])) as T;\n }\n return value;\n}\n","import React from 'react';\n\nimport { mergeGceResourceOptions } from './gceLoadBalancerData';\nimport type { IGceLoadBalancerData, IGceLoadBalancerDataItem } from './gceLoadBalancerData';\nimport type {\n GceLoadBalancerProtocol,\n IGceLoadBalancerBackendService,\n IGceLoadBalancerCommand,\n IGceLoadBalancerHealthCheck,\n IGceResourceReference,\n} from './gceLoadBalancerModels';\nimport { normalizeGceHealthCheck } from './gceLoadBalancerModels';\n\nexport type GceProxyLoadBalancerType = 'INTERNAL' | 'TCP' | 'SSL';\n\nexport interface IGceProxyTypeConfig {\n backendProtocols: readonly GceLoadBalancerProtocol[];\n frontendProtocols: readonly GceLoadBalancerProtocol[];\n}\n\nexport const GCE_PROXY_TYPE_CONFIG: Record<GceProxyLoadBalancerType, IGceProxyTypeConfig> = {\n INTERNAL: { frontendProtocols: ['TCP', 'UDP'], backendProtocols: ['TCP', 'UDP'] },\n TCP: { frontendProtocols: ['TCP'], backendProtocols: ['TCP'] },\n SSL: { frontendProtocols: ['SSL'], backendProtocols: ['TCP'] },\n};\n\nconst PROXY_PORTS = ['25', '43', '110', '143', '195', '443', '465', '587', '700', '993', '995'];\nconst HEALTH_CHECK_PROTOCOLS: GceLoadBalancerProtocol[] = ['HTTP', 'HTTPS', 'TCP', 'SSL'];\nconst PROXY_SESSION_AFFINITIES = ['NONE', 'CLIENT_IP', 'GENERATED_COOKIE'];\nconst INTERNAL_SESSION_AFFINITIES = ['NONE', 'CLIENT_IP', 'CLIENT_IP_PROTO', 'CLIENT_IP_PORT_PROTO'];\n\ninterface IGceProxyDataItem extends IGceLoadBalancerDataItem {\n account?: string;\n credentials?: string;\n network?: string | IGceResourceReference;\n region?: string;\n}\n\nexport interface IGceProxyResourceOptions extends IGceLoadBalancerData {\n accounts: IGceProxyDataItem[];\n addresses: IGceProxyDataItem[];\n backendServices: IGceProxyDataItem[];\n certificates: IGceProxyDataItem[];\n healthChecks: IGceProxyDataItem[];\n networks: IGceProxyDataItem[];\n regions: IGceProxyDataItem[];\n subnets: IGceProxyDataItem[];\n}\n\nexport interface IGceProxyLoadBalancerEditorProps {\n command: IGceLoadBalancerCommand;\n data: IGceLoadBalancerData;\n disabled?: boolean;\n onChange: (command: IGceLoadBalancerCommand) => void;\n}\n\nexport function applyGceProxyTypeConstraints(command: IGceLoadBalancerCommand): IGceLoadBalancerCommand {\n const type = command.loadBalancerType as GceProxyLoadBalancerType;\n const config = GCE_PROXY_TYPE_CONFIG[type];\n if (!config) {\n return command;\n }\n\n const originalListener = command.listeners[0] || {\n name: command.name,\n portRange: '',\n protocol: config.frontendProtocols[0],\n };\n const frontendProtocol = config.frontendProtocols.includes(originalListener.protocol)\n ? originalListener.protocol\n : config.frontendProtocols[0];\n const originalBackend = command.backendServices[0];\n const backendProtocol =\n type === 'INTERNAL'\n ? config.backendProtocols.includes(frontendProtocol)\n ? frontendProtocol\n : config.backendProtocols[0]\n : config.backendProtocols[0];\n const backendService: IGceLoadBalancerBackendService = {\n ...(originalBackend || {\n name: command.name,\n portName: type === 'INTERNAL' ? undefined : 'http',\n sessionAffinity: 'NONE',\n }),\n protocol: backendProtocol,\n };\n if (frontendProtocol === 'UDP') {\n backendService.sessionAffinity = 'NONE';\n delete backendService.affinityCookieTtlSec;\n }\n\n return {\n ...command,\n region: type === 'INTERNAL' ? command.region : 'global',\n listeners: [\n {\n ...originalListener,\n name: originalListener.name || command.name,\n portRange: originalListener.portRange || (type === 'INTERNAL' ? '' : '443'),\n protocol: frontendProtocol,\n },\n ],\n backendServices: [backendService],\n } as IGceLoadBalancerCommand;\n}\n\nexport function getGceProxyResourceOptions(\n command: IGceLoadBalancerCommand,\n data: IGceLoadBalancerData,\n): IGceProxyResourceOptions {\n const listener = command.listeners[0];\n const backend = command.backendServices[0];\n const accountScoped = (items: IGceProxyDataItem[]) =>\n items.filter((item) =>\n !item.account && !item.credentials ? true : (item.account || item.credentials) === command.credentials,\n );\n const locationScoped = (items: IGceProxyDataItem[]) =>\n accountScoped(items).filter((item) => !item.region || item.region === command.region);\n const networkName = command.network?.name;\n const subnetScoped = accountScoped(data.subnets as IGceProxyDataItem[]).filter((item) => {\n const itemNetwork = typeof item.network === 'string' ? item.network : item.network?.name;\n return (!item.region || item.region === command.region) && (!itemNetwork || itemNetwork === networkName);\n });\n\n return {\n accounts: data.accounts,\n addresses: mergeGceResourceOptions(\n locationScoped(data.addresses as IGceProxyDataItem[]),\n references(listener?.address),\n ),\n backendServices: mergeGceResourceOptions(\n locationScoped(data.backendServices as IGceProxyDataItem[]),\n references(backend),\n ),\n certificates: mergeGceResourceOptions(\n accountScoped(data.certificates as IGceProxyDataItem[]),\n references(listener?.certificate),\n ),\n healthChecks: mergeGceResourceOptions(\n accountScoped(data.healthChecks as IGceProxyDataItem[]),\n references(backend?.healthCheck),\n ),\n networks: mergeGceResourceOptions(accountScoped(data.networks as IGceProxyDataItem[]), references(command.network)),\n regions: data.regions,\n subnets: mergeGceResourceOptions(subnetScoped, references(command.subnet)),\n };\n}\n\nexport function validateGceProxyLoadBalancerCommand(command: IGceLoadBalancerCommand): string[] {\n const errors: string[] = [];\n const type = command.loadBalancerType as GceProxyLoadBalancerType;\n const listener = command.listeners[0];\n const backend = command.backendServices[0];\n const healthCheck = command.healthChecks[0];\n const ports = splitPorts(listener?.portRange);\n\n if (!command.name.trim()) errors.push('Name is required.');\n if (!command.credentials) errors.push('Account is required.');\n if (!command.region) errors.push('Region is required.');\n\n if (type === 'INTERNAL') {\n if (ports.length < 1 || ports.length > 5 || ports.some((port) => !validPort(port))) {\n errors.push('INTERNAL load balancers accept between one and five listener ports.');\n }\n if (!command.network) errors.push('Network is required for INTERNAL load balancers.');\n if (!command.subnet) errors.push('Subnet is required for INTERNAL load balancers.');\n } else if (ports.length !== 1 || !PROXY_PORTS.includes(ports[0])) {\n errors.push(`${type} proxy port must be one of 25, 43, 110, 143, 195, 443, 465, 587, 700, 993, or 995.`);\n }\n\n if (type === 'SSL' && !listener?.certificate) errors.push('Certificate is required for SSL proxy load balancers.');\n if (!backend?.name) errors.push('Backend service is required.');\n if (type !== 'INTERNAL' && !backend?.portName) errors.push('Port name is required.');\n if (type !== 'INTERNAL' && negative(backend?.connectionDrainingTimeoutSec)) {\n errors.push('Connection draining timeout must be zero or greater.');\n }\n if (\n backend?.sessionAffinity === 'GENERATED_COOKIE' &&\n (!numberInRange(backend.affinityCookieTtlSec, 0, 86400) || backend.affinityCookieTtlSec === undefined)\n ) {\n errors.push('Generated cookie TTL must be between 0 and 86400 seconds.');\n }\n\n if (!healthCheck?.name && !backend?.healthCheck?.name) errors.push('Health check name is required.');\n if (healthCheck) {\n if (!validPort(healthCheck.port)) errors.push('Health check port must be between 1 and 65535.');\n if (\n (healthCheck.healthCheckType === 'HTTP' || healthCheck.healthCheckType === 'HTTPS') &&\n !healthCheck.requestPath\n ) {\n errors.push('HTTP and HTTPS health checks require a request path.');\n }\n if (negative(healthCheck.timeoutSec)) errors.push('Health check timeout must be zero or greater.');\n if (healthCheck.checkIntervalSec !== undefined && Number(healthCheck.checkIntervalSec) <= 0) {\n errors.push('Health check interval must be greater than zero.');\n }\n if (healthCheck.healthyThreshold !== undefined && Number(healthCheck.healthyThreshold) <= 0) {\n errors.push('Healthy threshold must be greater than zero.');\n }\n if (healthCheck.unhealthyThreshold !== undefined && Number(healthCheck.unhealthyThreshold) <= 0) {\n errors.push('Unhealthy threshold must be greater than zero.');\n }\n }\n return errors;\n}\n\nexport function GceProxyLoadBalancerEditor({\n command,\n data,\n disabled = false,\n onChange,\n}: IGceProxyLoadBalancerEditorProps): JSX.Element {\n const constrained = applyGceProxyTypeConstraints(command);\n const type = constrained.loadBalancerType as GceProxyLoadBalancerType;\n const listener = constrained.listeners[0];\n const backend = constrained.backendServices[0];\n const healthCheck = constrained.healthChecks[0] || ({ healthCheckType: 'TCP' } as IGceLoadBalancerHealthCheck);\n const options = getGceProxyResourceOptions(constrained, data);\n const sessionAffinities =\n type === 'INTERNAL'\n ? listener.protocol === 'UDP'\n ? ['NONE']\n : INTERNAL_SESSION_AFFINITIES\n : PROXY_SESSION_AFFINITIES;\n\n const update = (updates: Partial<IGceLoadBalancerCommand>) =>\n onChange(applyGceProxyTypeConstraints({ ...constrained, ...updates } as IGceLoadBalancerCommand));\n const updateListener = (updates: Record<string, unknown>) =>\n update({ listeners: [{ ...listener, ...updates }] } as Partial<IGceLoadBalancerCommand>);\n const updateBackend = (updates: Record<string, unknown>) =>\n update({ backendServices: [{ ...backend, ...updates }] } as Partial<IGceLoadBalancerCommand>);\n const updateHealthCheck = (updates: Partial<IGceLoadBalancerHealthCheck>) =>\n update({ healthChecks: [{ ...healthCheck, ...updates }] } as Partial<IGceLoadBalancerCommand>);\n const updateName = (name: string) =>\n update({\n name,\n listeners: [{ ...listener, name: listener.name === constrained.name ? name : listener.name }],\n backendServices: [{ ...backend, name: backend.name === constrained.name ? name : backend.name }],\n });\n const selectHealthCheck = (name: string) => {\n if (!name) return updateBackend({ healthCheck: undefined });\n const selected = options.healthChecks.find((healthCheckOption) => healthCheckOption.name === name);\n const healthCheck = normalizeGceHealthCheck(selected || { name });\n const selfLink = typeof healthCheck.selfLink === 'string' ? healthCheck.selfLink : undefined;\n const healthCheckReference = {\n name,\n ...(selfLink ? { selfLink } : {}),\n };\n update({ backendServices: [{ ...backend, healthCheck: healthCheckReference }], healthChecks: [healthCheck] });\n };\n\n return (\n <div className=\"form-horizontal gce-proxy-load-balancer-editor\">\n {textField('Name', 'name', constrained.name, updateName, disabled)}\n {selectField(\n 'Account',\n 'credentials',\n constrained.credentials,\n options.accounts,\n (credentials) => update({ credentials }),\n disabled,\n )}\n {type === 'INTERNAL'\n ? selectField('Region', 'region', constrained.region, options.regions, (region) => update({ region }), disabled)\n : textField('Region', 'region', constrained.region, () => undefined, true)}\n {type === 'INTERNAL' &&\n selectField(\n 'Network',\n 'network',\n constrained.network?.name,\n options.networks,\n (name) => update({ network: reference(name), subnet: undefined }),\n disabled,\n )}\n {type === 'INTERNAL' &&\n selectField(\n 'Subnet',\n 'subnet',\n constrained.subnet?.name,\n options.subnets,\n (name) => update({ subnet: reference(name) }),\n disabled,\n )}\n {selectField(\n 'Address',\n 'address',\n listener.address?.name,\n options.addresses,\n (name) => updateListener({ address: selectedResource(name, options.addresses) }),\n disabled,\n )}\n {selectField(\n 'Protocol',\n 'protocol',\n listener.protocol,\n GCE_PROXY_TYPE_CONFIG[type].frontendProtocols.map((name) => ({ name })),\n (protocol) => updateListener({ protocol }),\n disabled || GCE_PROXY_TYPE_CONFIG[type].frontendProtocols.length === 1,\n )}\n {type === 'INTERNAL'\n ? textField(\n 'Listener ports',\n 'portRange',\n listener.portRange,\n (portRange) => updateListener({ portRange }),\n disabled,\n )\n : selectField(\n 'Listener port',\n 'portRange',\n listener.portRange,\n PROXY_PORTS.map((name) => ({ name })),\n (portRange) => updateListener({ portRange }),\n disabled,\n )}\n {type === 'SSL' &&\n selectField('Certificate', 'certificate', listener.certificate?.name, options.certificates, (name) =>\n updateListener({ certificate: reference(name) }),\n )}\n\n <h4>Backend Service</h4>\n {selectField(\n 'Backend service',\n 'backendService',\n backend.name,\n options.backendServices,\n (name) => updateBackend({ name }),\n disabled,\n true,\n )}\n {type !== 'INTERNAL' &&\n textField('Port name', 'portName', String(backend.portName || ''), (portName) => updateBackend({ portName }))}\n {type !== 'INTERNAL' &&\n numberField(\n 'Connection draining timeout',\n 'connectionDrainingTimeoutSec',\n backend.connectionDrainingTimeoutSec,\n (connectionDrainingTimeoutSec) => updateBackend({ connectionDrainingTimeoutSec }),\n )}\n {selectField(\n 'Session affinity',\n 'sessionAffinity',\n String(backend.sessionAffinity || 'NONE'),\n sessionAffinities.map((name) => ({ name })),\n (sessionAffinity) => updateBackend({ sessionAffinity }),\n )}\n {backend.sessionAffinity === 'GENERATED_COOKIE' &&\n numberField(\n 'Affinity cookie TTL',\n 'affinityCookieTtlSec',\n backend.affinityCookieTtlSec,\n (affinityCookieTtlSec) => updateBackend({ affinityCookieTtlSec }),\n )}\n\n <h4>Health Check</h4>\n {selectField(\n 'Existing health check',\n 'healthCheck',\n backend.healthCheck?.name,\n options.healthChecks,\n selectHealthCheck,\n )}\n {selectField(\n 'Health check protocol',\n 'healthCheckType',\n healthCheck.healthCheckType,\n HEALTH_CHECK_PROTOCOLS.map((name) => ({ name })),\n (healthCheckType) =>\n updateHealthCheck({\n healthCheckType: healthCheckType as GceLoadBalancerProtocol,\n }),\n )}\n {textField('Health check name', 'healthCheckName', healthCheck.name || '', (name) => updateHealthCheck({ name }))}\n {(healthCheck.healthCheckType === 'HTTP' || healthCheck.healthCheckType === 'HTTPS') &&\n textField('Request path', 'requestPath', healthCheck.requestPath || '', (requestPath) =>\n updateHealthCheck({ requestPath }),\n )}\n {numberField('Health check port', 'healthCheckPort', healthCheck.port, (port) => updateHealthCheck({ port }))}\n {numberField('Timeout', 'timeoutSec', healthCheck.timeoutSec, (timeoutSec) => updateHealthCheck({ timeoutSec }))}\n {numberField('Interval', 'checkIntervalSec', healthCheck.checkIntervalSec, (checkIntervalSec) =>\n updateHealthCheck({ checkIntervalSec }),\n )}\n {numberField('Healthy threshold', 'healthyThreshold', healthCheck.healthyThreshold, (healthyThreshold) =>\n updateHealthCheck({ healthyThreshold }),\n )}\n {numberField('Unhealthy threshold', 'unhealthyThreshold', healthCheck.unhealthyThreshold, (unhealthyThreshold) =>\n updateHealthCheck({ unhealthyThreshold }),\n )}\n </div>\n );\n}\n\nfunction textField(\n label: string,\n field: string,\n value: string,\n onChange: (value: string) => void,\n disabled = false,\n): JSX.Element {\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <input\n className=\"form-control input-sm\"\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n value={value || ''}\n />\n </div>\n </div>\n );\n}\n\nfunction numberField(\n label: string,\n field: string,\n value: unknown,\n onChange: (value: number | undefined) => void,\n): JSX.Element {\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <input\n className=\"form-control input-sm\"\n type=\"number\"\n value={value === undefined || value === null ? '' : String(value)}\n onChange={(event) => onChange(event.target.value === '' ? undefined : Number(event.target.value))}\n />\n </div>\n </div>\n );\n}\n\nfunction selectField(\n label: string,\n field: string,\n value: string | undefined,\n options: readonly IGceLoadBalancerDataItem[],\n onChange: (value: string) => void,\n disabled = false,\n allowCustomValue = false,\n): JSX.Element {\n const names = options.map(({ name }) => name);\n if (allowCustomValue && value && !names.includes(value)) names.push(value);\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <select\n className=\"form-control input-sm\"\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n value={value || ''}\n >\n <option value=\"\">Select...</option>\n {names.map((name) => (\n <option key={name} value={name}>\n {name}\n </option>\n ))}\n </select>\n </div>\n </div>\n );\n}\n\nfunction references<T extends IGceLoadBalancerDataItem>(referenceValue?: T): T[] {\n return referenceValue?.name ? [referenceValue] : [];\n}\n\nfunction reference(name: string): IGceResourceReference | undefined {\n return name ? { name } : undefined;\n}\n\nfunction selectedResource(\n name: string,\n options: readonly IGceLoadBalancerDataItem[],\n): IGceResourceReference | undefined {\n return name ? ((options.find((option) => option.name === name) || { name }) as IGceResourceReference) : undefined;\n}\n\nfunction splitPorts(value: string | undefined): string[] {\n return String(value || '')\n .split(',')\n .map((port) => port.trim())\n .filter(Boolean);\n}\n\nfunction validPort(value: unknown): boolean {\n const port = Number(value);\n return Number.isInteger(port) && port >= 1 && port <= 65535;\n}\n\nfunction negative(value: unknown): boolean {\n return value !== undefined && value !== null && Number(value) < 0;\n}\n\nfunction numberInRange(value: unknown, min: number, max: number): boolean {\n const number = Number(value);\n return Number.isFinite(number) && number >= min && number <= max;\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps } from '@spinnaker/core';\nimport {\n InfrastructureCaches,\n LoadBalancerWriter,\n ModalClose,\n ReactModal,\n Spinner,\n SubmitButton,\n TaskMonitor,\n TaskMonitorWrapper,\n} from '@spinnaker/core';\n\nimport {\n applyGceProxyTypeConstraints,\n GceProxyLoadBalancerEditor,\n validateGceProxyLoadBalancerCommand,\n} from './GceProxyLoadBalancerEditor';\nimport type { GceProxyLoadBalancerType } from './GceProxyLoadBalancerEditor';\nimport type { IGceLoadBalancerDataReaders } from './gceLoadBalancerData';\nimport type {\n GceLoadBalancerEditorMode,\n IGceLoadBalancerCommand,\n IGceSerializedLoadBalancerCommand,\n} from './gceLoadBalancerModels';\nimport { normalizeGceLoadBalancerCommand, serializeGceLoadBalancerCommand } from './gceLoadBalancerModels';\nimport { useGceLoadBalancerData } from './useGceLoadBalancerData';\n\ntype UnknownRecord = Record<string, any>;\n\nexport interface IGceProxyLoadBalancerPayload extends IGceSerializedLoadBalancerCommand {\n backendService: UnknownRecord;\n backendServices?: undefined;\n healthChecks?: undefined;\n ports?: string[];\n}\n\nexport interface IGceProxyLoadBalancerModalProps extends IModalComponentProps {\n app?: Application;\n application?: Application;\n forPipelineConfig?: boolean;\n isNew?: boolean;\n loadBalancer?: UnknownRecord;\n loadBalancerType?: GceProxyLoadBalancerType | string;\n readers?: IGceLoadBalancerDataReaders;\n}\n\ninterface IGceProxySubmissionDependencies {\n application: Application;\n closeModal?: (command: IGceProxyLoadBalancerPayload) => void;\n taskMonitor: Pick<TaskMonitor, 'submit'>;\n}\n\nexport function normalizeGceProxyLoadBalancerCommand(\n persisted: UnknownRecord | undefined,\n mode: GceLoadBalancerEditorMode,\n loadBalancerType: GceProxyLoadBalancerType,\n applicationName = '',\n): IGceLoadBalancerCommand {\n const source = persisted || {};\n const backendService = source.backendService || source.backendServices?.[0];\n const nestedHealthCheck = backendService?.healthCheck;\n const normalizedSource: UnknownRecord = {\n ...source,\n backendServices: backendService ? [{ ...backendService }] : source.backendServices,\n healthChecks: source.healthChecks?.length ? source.healthChecks : nestedHealthCheck ? [nestedHealthCheck] : [],\n loadBalancerType,\n name: source.name || source.loadBalancerName || applicationName,\n };\n\n const normalized = normalizeGceLoadBalancerCommand(normalizedSource, mode);\n if (normalized.backendServices[0]?.healthCheck) {\n const { name, selfLink } = normalized.backendServices[0].healthCheck;\n normalized.backendServices[0].healthCheck = selfLink ? { name, selfLink } : { name };\n }\n return applyGceProxyTypeConstraints(normalized);\n}\n\nexport function serializeGceProxyLoadBalancerCommand(command: IGceLoadBalancerCommand): IGceProxyLoadBalancerPayload {\n const constrained = applyGceProxyTypeConstraints(command);\n const serialized = serializeGceLoadBalancerCommand(constrained) as IGceProxyLoadBalancerPayload;\n const backendSource = constrained.backendServices[0] || ({ name: constrained.name } as UnknownRecord);\n const backendService: UnknownRecord = { ...backendSource };\n const healthCheck = constrained.healthChecks[0] || backendSource.healthCheck;\n\n delete backendService.protocol;\n backendService.protocol = undefined;\n backendService.healthCheck = healthCheck ? { ...healthCheck } : undefined;\n backendService.name = backendService.name || constrained.name;\n serialized.backendService = backendService;\n delete serialized.backendServices;\n delete serialized.healthChecks;\n\n if (constrained.loadBalancerType === 'INTERNAL') {\n serialized.ipProtocol = constrained.listeners[0]?.protocol || 'TCP';\n serialized.ports = splitPorts(constrained.listeners[0]?.portRange);\n delete serialized.portRange;\n } else {\n serialized.ipProtocol = String(backendSource.protocol || 'TCP');\n }\n\n return serialized;\n}\n\nexport function submitGceProxyLoadBalancerCommand(\n command: IGceLoadBalancerCommand,\n { application, closeModal, taskMonitor }: IGceProxySubmissionDependencies,\n): void {\n const payload = serializeGceProxyLoadBalancerCommand(command);\n if (command.mode === 'pipeline') {\n closeModal?.(payload);\n return;\n }\n\n const descriptor = command.mode === 'edit' ? 'Update' : 'Create';\n taskMonitor.submit(() =>\n LoadBalancerWriter.upsertLoadBalancer(payload as any, application, descriptor, { healthCheck: {} }),\n );\n}\n\nfunction GceProxyLoadBalancerModalComponent(props: IGceProxyLoadBalancerModalProps): JSX.Element {\n const application = (props.application || props.app) as Application;\n const mode: GceLoadBalancerEditorMode = props.forPipelineConfig\n ? 'pipeline'\n : props.isNew === false\n ? 'edit'\n : 'create';\n const type = resolveProxyType(props.loadBalancerType || props.loadBalancer?.loadBalancerType);\n const [command, setCommand] = React.useState(() =>\n normalizeGceProxyLoadBalancerCommand(props.loadBalancer, mode, type, application?.name),\n );\n const dataState = useGceLoadBalancerData(command.credentials, props.readers);\n const applicationRefreshUnsubscribe = React.useRef<(() => void) | undefined>();\n const isUnmounted = React.useRef(false);\n const [taskMonitor] = React.useState(\n () =>\n new TaskMonitor({\n application,\n title: `${mode === 'edit' ? 'Updating' : 'Creating'} your load balancer`,\n onDismiss: () => props.dismissModal?.(),\n onTaskComplete: () => {\n InfrastructureCaches.clearCache('healthChecks');\n const loadBalancers = (application as any)?.loadBalancers || application?.getDataSource?.('loadBalancers');\n const close = () => {\n applicationRefreshUnsubscribe.current?.();\n applicationRefreshUnsubscribe.current = undefined;\n if (isUnmounted.current) {\n return;\n }\n props.closeModal?.();\n };\n if (loadBalancers?.onNextRefresh) {\n applicationRefreshUnsubscribe.current?.();\n applicationRefreshUnsubscribe.current = undefined;\n applicationRefreshUnsubscribe.current = loadBalancers.onNextRefresh(close);\n loadBalancers.refresh?.();\n } else {\n close();\n }\n },\n }),\n );\n React.useEffect(\n () => () => {\n isUnmounted.current = true;\n applicationRefreshUnsubscribe.current?.();\n applicationRefreshUnsubscribe.current = undefined;\n },\n [],\n );\n const errors = validateGceProxyLoadBalancerCommand(command);\n const submitting = taskMonitor.submitting;\n const heading =\n mode === 'create'\n ? `Create ${type} Load Balancer`\n : mode === 'pipeline'\n ? `Configure ${type} Load Balancer`\n : `Edit ${command.name}`;\n const submit = () =>\n submitGceProxyLoadBalancerCommand(command, { application, closeModal: props.closeModal, taskMonitor });\n\n return (\n <div className=\"modal-content\">\n <TaskMonitorWrapper monitor={taskMonitor} />\n <ModalClose dismiss={props.dismissModal} />\n <div className=\"modal-header\">\n <h3>{heading}</h3>\n </div>\n <div className=\"modal-body\">\n {dataState.status === 'loading' && <Spinner size=\"large\" />}\n {dataState.status === 'error' && (\n <div className=\"alert alert-danger\">Unable to load GCE load balancer resources.</div>\n )}\n <GceProxyLoadBalancerEditor\n command={command}\n data={dataState.data}\n disabled={mode === 'edit'}\n onChange={setCommand}\n />\n {!!errors.length && (\n <div className=\"alert alert-danger gce-proxy-validation-errors\">\n {errors.map((error) => (\n <div key={error}>{error}</div>\n ))}\n </div>\n )}\n </div>\n <div className=\"modal-footer\">\n <button className=\"btn btn-default\" disabled={submitting} onClick={props.dismissModal} type=\"button\">\n Cancel\n </button>\n <SubmitButton\n isDisabled={!!errors.length || dataState.status === 'loading' || submitting}\n isFormSubmit={false}\n label={mode === 'pipeline' ? 'Done' : mode === 'edit' ? 'Update' : 'Create'}\n onClick={submit}\n submitting={submitting}\n />\n </div>\n </div>\n );\n}\n\nexport const GceProxyLoadBalancerModal = Object.assign(GceProxyLoadBalancerModalComponent, {\n show: (props: IGceProxyLoadBalancerModalProps) =>\n ReactModal.show(GceProxyLoadBalancerModalComponent, props, { dialogClassName: 'modal-lg' }),\n supportsPipelineConfig: true,\n});\n\nfunction resolveProxyType(value: unknown): GceProxyLoadBalancerType {\n const type = String(value || '').toUpperCase();\n return type === 'INTERNAL' || type === 'SSL' || type === 'TCP' ? type : 'TCP';\n}\n\nfunction splitPorts(value: string | undefined): string[] {\n return String(value || '')\n .split(',')\n .map((port) => port.trim())\n .filter(Boolean);\n}\n","import { useEffect, useRef, useState } from 'react';\n\nimport { GceLoadBalancerDataController, gceLoadBalancerDataReaders } from './gceLoadBalancerData';\nimport type { IGceLoadBalancerDataReaders, IGceLoadBalancerDataState } from './gceLoadBalancerData';\n\nexport interface IUseGceLoadBalancerDataResult extends IGceLoadBalancerDataState {\n refresh: () => void;\n}\n\nexport function useGceLoadBalancerData(\n account: string,\n readers: IGceLoadBalancerDataReaders = gceLoadBalancerDataReaders,\n): IUseGceLoadBalancerDataResult {\n const controllerRef = useRef<GceLoadBalancerDataController | null>(null);\n if (!controllerRef.current) {\n controllerRef.current = new GceLoadBalancerDataController(readers);\n }\n const controller = controllerRef.current;\n const [state, setState] = useState<IGceLoadBalancerDataState>(controller.getState());\n\n useEffect(() => {\n const unsubscribe = controller.subscribe(setState);\n return () => {\n unsubscribe();\n controller.dispose();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.load(account);\n }, [account, controller]);\n\n return { ...state, refresh: () => controller.load(account) };\n}\n","import React from 'react';\n\nimport type {\n GceLoadBalancerType,\n IGceLoadBalancerDataItem,\n IGceLoadBalancerListener,\n IGceResourceReference,\n} from '../common';\n\nexport interface IGceHttpLoadBalancerListenerEditorProps {\n addresses: IGceLoadBalancerDataItem[];\n certificates: IGceLoadBalancerDataItem[];\n listener: IGceLoadBalancerListener;\n loadBalancerType: GceLoadBalancerType;\n onChange: (listener: IGceLoadBalancerListener) => void;\n onRemove: () => void;\n subnets: IGceLoadBalancerDataItem[];\n}\n\nfunction selectedReference(name: string, options: IGceLoadBalancerDataItem[]): IGceResourceReference | undefined {\n if (!name) {\n return undefined;\n }\n return (options.find((option) => option.name === name) || { name }) as IGceResourceReference;\n}\n\nexport function GceHttpLoadBalancerListenerEditor({\n addresses,\n certificates,\n listener,\n loadBalancerType,\n onChange,\n onRemove,\n subnets,\n}: IGceHttpLoadBalancerListenerEditorProps): JSX.Element {\n const protocols = ['HTTP', 'HTTPS'];\n\n return (\n <fieldset className=\"gce-http-listener\">\n <legend>Listener</legend>\n <label>\n Name\n <input\n data-testid=\"listener-name\"\n required\n type=\"text\"\n value={listener.name}\n onChange={(event) => onChange({ ...listener, name: event.target.value })}\n />\n </label>\n <label>\n Protocol\n <select\n data-testid=\"listener-protocol\"\n value={listener.protocol}\n onChange={(event) => {\n const protocol = event.target.value as IGceLoadBalancerListener['protocol'];\n onChange({ ...listener, ...(protocol === 'HTTPS' ? { portRange: '443' } : {}), protocol });\n }}\n >\n {protocols.map((protocol) => (\n <option key={protocol} value={protocol}>\n {protocol}\n </option>\n ))}\n </select>\n </label>\n <label>\n Port\n <input\n data-testid=\"listener-port\"\n disabled={listener.protocol === 'HTTPS'}\n required\n type=\"text\"\n value={listener.portRange}\n onChange={(event) => onChange({ ...listener, portRange: event.target.value })}\n />\n </label>\n {loadBalancerType === 'INTERNAL_MANAGED' && (\n <label>\n Subnet\n <select\n data-testid=\"listener-subnet\"\n required\n value={listener.subnet?.name || ''}\n onChange={(event) => onChange({ ...listener, subnet: selectedReference(event.target.value, subnets) })}\n >\n <option value=\"\">Select...</option>\n {subnets.map((subnet) => (\n <option key={subnet.name} value={subnet.name}>\n {subnet.name}\n </option>\n ))}\n </select>\n </label>\n )}\n <label>\n {loadBalancerType === 'INTERNAL_MANAGED' ? 'Internal IP' : 'External IP'}\n <select\n data-testid=\"listener-address\"\n value={listener.address?.name || ''}\n onChange={(event) => onChange({ ...listener, address: selectedReference(event.target.value, addresses) })}\n >\n <option value=\"\">Ephemeral</option>\n {addresses.map((address) => (\n <option key={address.name} value={address.name}>\n {address.name}\n </option>\n ))}\n </select>\n </label>\n {listener.protocol === 'HTTPS' && (\n <>\n <label>\n Certificate\n <select\n data-testid=\"listener-certificate\"\n value={listener.certificate?.name || ''}\n onChange={(event) =>\n onChange({\n ...listener,\n certificate: selectedReference(event.target.value, certificates),\n certificateMap: undefined,\n })\n }\n >\n <option value=\"\">Select...</option>\n {certificates.map((certificate) => (\n <option key={certificate.name} value={certificate.name}>\n {certificate.name}\n </option>\n ))}\n </select>\n </label>\n <label>\n Certificate map\n <input\n data-testid=\"listener-certificate-map\"\n type=\"text\"\n value={listener.certificateMap || ''}\n onChange={(event) =>\n onChange({ ...listener, certificate: undefined, certificateMap: event.target.value || undefined })\n }\n />\n </label>\n </>\n )}\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={onRemove}>\n Remove listener\n </button>\n </fieldset>\n );\n}\n","import React from 'react';\n\nimport type {\n GceLoadBalancerType,\n IGceLoadBalancerBackendService,\n IGceLoadBalancerDataItem,\n IGceLoadBalancerHealthCheck,\n IGceResourceReference,\n} from '../common';\n\nfunction numberValue(value: string): number | undefined {\n return value === '' ? undefined : Number(value);\n}\n\nfunction selectedReference(name: string, options: IGceLoadBalancerDataItem[]): IGceResourceReference | undefined {\n if (!name) {\n return undefined;\n }\n return (options.find((option) => option.name === name) || { name }) as IGceResourceReference;\n}\n\nexport interface IGceHttpLoadBalancerHealthCheckEditorProps {\n healthCheck: IGceLoadBalancerHealthCheck;\n healthChecks: IGceLoadBalancerDataItem[];\n onChange: (healthCheck: IGceLoadBalancerHealthCheck) => void;\n onRemove: () => void;\n}\n\nexport function GceHttpLoadBalancerHealthCheckEditor({\n healthCheck,\n healthChecks,\n onChange,\n onRemove,\n}: IGceHttpLoadBalancerHealthCheckEditorProps): JSX.Element {\n const updateNumber = (field: string, value: string): void =>\n onChange({ ...healthCheck, [field]: numberValue(value) });\n\n return (\n <fieldset className=\"gce-http-health-check\">\n <legend>Health check</legend>\n <label>\n Existing health check\n <select\n data-testid=\"health-check-reference\"\n value={healthCheck.name || ''}\n onChange={(event) => {\n const selected = healthChecks.find(({ name }) => name === event.target.value);\n onChange(selected ? ({ ...selected } as IGceLoadBalancerHealthCheck) : { ...healthCheck, name: '' });\n }}\n >\n <option value=\"\">Create new...</option>\n {healthChecks.map((option) => (\n <option key={option.name} value={option.name}>\n {option.name}\n </option>\n ))}\n </select>\n </label>\n <label>\n Protocol\n <select\n data-testid=\"health-check-protocol\"\n value={healthCheck.healthCheckType || 'HTTP'}\n onChange={(event) =>\n onChange({\n ...healthCheck,\n healthCheckType: event.target.value as IGceLoadBalancerHealthCheck['healthCheckType'],\n })\n }\n >\n {['HTTP', 'HTTPS', 'HTTP2', 'GRPC', 'TCP', 'SSL'].map((protocol) => (\n <option key={protocol} value={protocol}>\n {protocol}\n </option>\n ))}\n </select>\n </label>\n <label>\n Name\n <input\n data-testid=\"health-check-name\"\n required\n type=\"text\"\n value={healthCheck.name || ''}\n onChange={(event) => onChange({ ...healthCheck, name: event.target.value })}\n />\n </label>\n {(healthCheck.healthCheckType === 'HTTP' ||\n healthCheck.healthCheckType === 'HTTPS' ||\n healthCheck.healthCheckType === 'HTTP2') && (\n <label>\n Request path\n <input\n data-testid=\"health-check-path\"\n required\n type=\"text\"\n value={healthCheck.requestPath || ''}\n onChange={(event) => onChange({ ...healthCheck, requestPath: event.target.value })}\n />\n </label>\n )}\n {healthCheck.healthCheckType === 'GRPC' && (\n <label>\n Service name\n <input\n data-testid=\"health-check-grpc-service-name\"\n type=\"text\"\n value={healthCheck.grpcServiceName || ''}\n onChange={(event) => onChange({ ...healthCheck, grpcServiceName: event.target.value })}\n />\n </label>\n )}\n <label>\n Port\n <input\n data-testid=\"health-check-port\"\n max={65535}\n min={1}\n required\n type=\"number\"\n value={healthCheck.port ?? ''}\n onChange={(event) => updateNumber('port', event.target.value)}\n />\n </label>\n {[\n ['timeoutSec', 'Timeout'],\n ['checkIntervalSec', 'Interval'],\n ['healthyThreshold', 'Healthy threshold'],\n ['unhealthyThreshold', 'Unhealthy threshold'],\n ].map(([field, label]) => (\n <label key={field}>\n {label}\n <input\n data-testid={`health-check-${field}`}\n min={0}\n type=\"number\"\n value={(healthCheck[field] as number | undefined) ?? ''}\n onChange={(event) => updateNumber(field, event.target.value)}\n />\n </label>\n ))}\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={onRemove}>\n Remove health check\n </button>\n </fieldset>\n );\n}\n\nexport interface IGceHttpLoadBalancerBackendServiceEditorProps {\n backendService: IGceLoadBalancerBackendService;\n backendServices: IGceLoadBalancerDataItem[];\n healthChecks: IGceLoadBalancerDataItem[];\n loadBalancerType: GceLoadBalancerType;\n onChange: (backendService: IGceLoadBalancerBackendService) => void;\n onRemove: () => void;\n}\n\nexport function GceHttpLoadBalancerBackendServiceEditor({\n backendService,\n backendServices,\n healthChecks,\n loadBalancerType,\n onChange,\n onRemove,\n}: IGceHttpLoadBalancerBackendServiceEditorProps): JSX.Element {\n return (\n <fieldset className=\"gce-http-backend-service\">\n <legend>Backend service</legend>\n <label>\n Existing backend service\n <select\n data-testid=\"backend-service-reference\"\n value={backendService.name}\n onChange={(event) => {\n const selected = backendServices.find(({ name }) => name === event.target.value);\n onChange(selected ? ({ ...selected } as IGceLoadBalancerBackendService) : { ...backendService, name: '' });\n }}\n >\n <option value=\"\">Create new...</option>\n {backendServices.map((option) => (\n <option key={option.name} value={option.name}>\n {option.name}\n </option>\n ))}\n </select>\n </label>\n <label>\n Name\n <input\n data-testid=\"backend-service-name\"\n required\n type=\"text\"\n value={backendService.name}\n onChange={(event) => onChange({ ...backendService, name: event.target.value })}\n />\n </label>\n <label>\n Health check\n <select\n data-testid=\"backend-service-health-check\"\n required\n value={backendService.healthCheck?.name || ''}\n onChange={(event) =>\n onChange({\n ...backendService,\n healthCheck: selectedReference(event.target.value, healthChecks),\n })\n }\n >\n <option value=\"\">Select...</option>\n {healthChecks.map((option) => (\n <option key={option.name} value={option.name}>\n {option.name}\n </option>\n ))}\n </select>\n </label>\n <label>\n Session affinity\n <select\n data-testid=\"backend-service-session-affinity\"\n value={String(backendService.sessionAffinity || 'NONE')}\n onChange={(event) => onChange({ ...backendService, sessionAffinity: event.target.value })}\n >\n {['NONE', 'CLIENT_IP', 'GENERATED_COOKIE', 'HEADER_FIELD', 'HTTP_COOKIE'].map((affinity) => (\n <option key={affinity} value={affinity}>\n {affinity}\n </option>\n ))}\n </select>\n </label>\n <label>\n Port name\n <input\n data-testid=\"backend-service-port-name\"\n required\n type=\"text\"\n value={String(backendService.portName || '')}\n onChange={(event) => onChange({ ...backendService, portName: event.target.value })}\n />\n </label>\n <label>\n Connection draining timeout\n <input\n data-testid=\"backend-service-draining\"\n min={0}\n type=\"number\"\n value={(backendService.connectionDrainingTimeoutSec as number | undefined) ?? ''}\n onChange={(event) =>\n onChange({ ...backendService, connectionDrainingTimeoutSec: numberValue(event.target.value) })\n }\n />\n </label>\n {loadBalancerType === 'HTTP' && (\n <label>\n <input\n data-testid=\"backend-service-cdn\"\n checked={Boolean(backendService.enableCDN)}\n type=\"checkbox\"\n onChange={(event) => onChange({ ...backendService, enableCDN: event.target.checked })}\n />\n Enable CDN\n </label>\n )}\n {backendService.sessionAffinity === 'GENERATED_COOKIE' && (\n <label>\n Affinity cookie TTL seconds\n <input\n data-testid=\"backend-service-cookie-ttl\"\n max={86400}\n min={0}\n required\n type=\"number\"\n value={(backendService.affinityCookieTtlSec as number | undefined) ?? ''}\n onChange={(event) => onChange({ ...backendService, affinityCookieTtlSec: numberValue(event.target.value) })}\n />\n </label>\n )}\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={onRemove}>\n Remove backend service\n </button>\n </fieldset>\n );\n}\n","import React from 'react';\n\nimport type {\n IGceLoadBalancerDataItem,\n IGceLoadBalancerHostRule,\n IGceLoadBalancerPathRule,\n IGceResourceReference,\n} from '../common';\n\nfunction parseList(value: string): string[] {\n return value\n .split(/[\\n,]/)\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction selectedReference(name: string, options: IGceLoadBalancerDataItem[]): IGceResourceReference | undefined {\n if (!name) {\n return undefined;\n }\n return (options.find((option) => option.name === name) || { name }) as IGceResourceReference;\n}\n\nexport interface IGceHttpLoadBalancerPathRuleEditorProps {\n backendServices: IGceLoadBalancerDataItem[];\n onChange: (pathRule: IGceLoadBalancerPathRule) => void;\n onRemove: () => void;\n pathRule: IGceLoadBalancerPathRule;\n}\n\nexport function GceHttpLoadBalancerPathRuleEditor({\n backendServices,\n onChange,\n onRemove,\n pathRule,\n}: IGceHttpLoadBalancerPathRuleEditorProps): JSX.Element {\n return (\n <fieldset className=\"gce-http-path-rule\">\n <legend>Path rule</legend>\n <label>\n Paths\n <input\n data-testid=\"path-rule-paths\"\n required\n type=\"text\"\n value={pathRule.paths.join(', ')}\n onChange={(event) => onChange({ ...pathRule, paths: parseList(event.target.value) })}\n />\n </label>\n <label>\n Backend service\n <select\n data-testid=\"path-rule-backend\"\n required\n value={pathRule.backendService?.name || ''}\n onChange={(event) =>\n onChange({\n ...pathRule,\n backendService: selectedReference(event.target.value, backendServices),\n })\n }\n >\n <option value=\"\">Select...</option>\n {backendServices.map((service) => (\n <option key={service.name} value={service.name}>\n {service.name}\n </option>\n ))}\n </select>\n </label>\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={onRemove}>\n Remove path rule\n </button>\n </fieldset>\n );\n}\n\nexport interface IGceHttpLoadBalancerHostRuleEditorProps {\n backendServices: IGceLoadBalancerDataItem[];\n hostRule: IGceLoadBalancerHostRule;\n onChange: (hostRule: IGceLoadBalancerHostRule) => void;\n onRemove: () => void;\n}\n\nexport function GceHttpLoadBalancerHostRuleEditor({\n backendServices,\n hostRule,\n onChange,\n onRemove,\n}: IGceHttpLoadBalancerHostRuleEditorProps): JSX.Element {\n return (\n <fieldset className=\"gce-http-host-rule\">\n <legend>Host rule</legend>\n <label>\n Host patterns\n <input\n data-testid=\"host-rule-patterns\"\n type=\"text\"\n value={hostRule.hostPatterns.join(', ')}\n onChange={(event) => onChange({ ...hostRule, hostPatterns: parseList(event.target.value) })}\n />\n </label>\n <label>\n Default backend service\n <select\n data-testid=\"host-rule-default-backend\"\n required\n value={hostRule.pathMatcher.defaultService?.name || ''}\n onChange={(event) =>\n onChange({\n ...hostRule,\n pathMatcher: {\n ...hostRule.pathMatcher,\n defaultService: selectedReference(event.target.value, backendServices),\n },\n })\n }\n >\n {backendServices.map((service) => (\n <option key={service.name} value={service.name}>\n {service.name}\n </option>\n ))}\n </select>\n </label>\n {hostRule.pathMatcher.pathRules.map((pathRule, index) => (\n <GceHttpLoadBalancerPathRuleEditor\n backendServices={backendServices}\n key={index}\n onChange={(updated) =>\n onChange({\n ...hostRule,\n pathMatcher: {\n ...hostRule.pathMatcher,\n pathRules: hostRule.pathMatcher.pathRules.map((current, currentIndex) =>\n currentIndex === index ? updated : current,\n ),\n },\n })\n }\n onRemove={() =>\n onChange({\n ...hostRule,\n pathMatcher: {\n ...hostRule.pathMatcher,\n pathRules: hostRule.pathMatcher.pathRules.filter((_, currentIndex) => currentIndex !== index),\n },\n })\n }\n pathRule={pathRule}\n />\n ))}\n <button\n type=\"button\"\n className=\"add-new btn btn-block\"\n data-testid=\"add-path-rule\"\n onClick={() =>\n onChange({\n ...hostRule,\n pathMatcher: {\n ...hostRule.pathMatcher,\n pathRules: [...hostRule.pathMatcher.pathRules, { paths: [] }],\n },\n })\n }\n >\n Add path rule\n </button>\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={onRemove}>\n Remove host rule\n </button>\n </fieldset>\n );\n}\n","import { isEqual } from 'lodash';\n\nimport type { Application, ITask, ITaskCommand } from '@spinnaker/core';\nimport { TaskExecutor } from '@spinnaker/core';\n\nimport type {\n IGceLoadBalancerBackendService,\n IGceLoadBalancerCommand,\n IGceLoadBalancerHealthCheck,\n IGceResourceReference,\n IGceSerializedLoadBalancerCommand,\n} from './gceLoadBalancerModels';\nimport { serializeGceLoadBalancerCommand } from './gceLoadBalancerModels';\n\nexport interface IGceLoadBalancerSubmissionDependencies {\n application: Application;\n executeTask?: (taskCommand: ITaskCommand) => PromiseLike<ITask>;\n}\n\nexport type GceLoadBalancerOperationList = IGceSerializedLoadBalancerCommand[];\nexport type GceLoadBalancerSubmissionResult =\n | IGceSerializedLoadBalancerCommand\n | GceLoadBalancerOperationList\n | Promise<ITask>;\n\nexport function buildGceLoadBalancerJobs(command: IGceLoadBalancerCommand): GceLoadBalancerOperationList {\n const serialized = serializeGceLoadBalancerCommand(command);\n if (command.loadBalancerType !== 'HTTP' && command.loadBalancerType !== 'INTERNAL_MANAGED') {\n return [serialized];\n }\n\n const {\n backendServices: _backendServices,\n healthChecks: _healthChecks,\n hostRules: _hostRules,\n listeners,\n ...shared\n } = serialized;\n const backendServices = new Map(\n command.backendServices.map((service) => [service.name, serializeBackendService(service, command.healthChecks)]),\n );\n const defaultService = resolveBackendService(command.defaultService, backendServices);\n const hostRules = command.hostRules.flatMap((hostRule) =>\n hostRule.hostPatterns.map((hostPattern) => ({\n hostPatterns: [hostPattern],\n pathMatcher: {\n ...(hostRule.pathMatcher.defaultService\n ? { defaultService: resolveBackendService(hostRule.pathMatcher.defaultService, backendServices) }\n : {}),\n pathRules: hostRule.pathMatcher.pathRules.map((pathRule) => ({\n ...(pathRule.backendService\n ? { backendService: resolveBackendService(pathRule.backendService, backendServices) }\n : {}),\n paths: [...pathRule.paths],\n })),\n },\n })),\n );\n\n const jobs = ((listeners || []) as Array<Record<string, unknown>>).map((listener) => {\n const name = String(listener.name);\n return {\n ...shared,\n certificate: listener.certificate || null,\n ...(defaultService ? { defaultService } : {}),\n hostRules,\n ipAddress: listener.ipAddress,\n ipProtocol: 'TCP',\n loadBalancerName: name,\n name,\n portRange: listener.portRange,\n ...(listener.subnet ? { subnet: listener.subnet } : {}),\n urlMapName: command.name,\n } as IGceSerializedLoadBalancerCommand;\n });\n\n if (command.mode === 'edit' && command.original && jobs.length) {\n const listenerNames = new Set(command.listeners.map(({ name }) => name));\n const currentBackendServices = new Map(command.backendServices.map((service) => [service.name, service]));\n jobs[0].listenersToDelete = command.original.listeners\n .map(({ name }) => name)\n .filter((name) => !listenerNames.has(name));\n jobs[0].backendServiceDiff = command.original.backendServices\n .filter((service) => !isEqual(service, currentBackendServices.get(service.name)))\n .map((service) => serializeBackendService(service, command.original!.healthChecks));\n }\n\n return jobs;\n}\n\nfunction serializeBackendService(\n service: IGceLoadBalancerBackendService,\n healthChecks: IGceLoadBalancerHealthCheck[],\n): Record<string, unknown> {\n const healthCheck = service.healthCheck\n ? healthChecks.find(({ name }) => name === service.healthCheck?.name) || service.healthCheck\n : undefined;\n return {\n ...service,\n ...(healthCheck ? { healthCheck: { ...healthCheck } } : {}),\n };\n}\n\nfunction resolveBackendService(\n reference: IGceResourceReference | undefined,\n services: Map<string, Record<string, unknown>>,\n): Record<string, unknown> | undefined {\n return reference ? services.get(reference.name) || { ...reference } : undefined;\n}\n\nexport function submitGceLoadBalancerCommand(\n command: IGceLoadBalancerCommand,\n { application, executeTask = TaskExecutor.executeTask }: IGceLoadBalancerSubmissionDependencies,\n): GceLoadBalancerSubmissionResult {\n const jobs = buildGceLoadBalancerJobs(command);\n if (command.mode === 'pipeline') {\n return command.loadBalancerType === 'HTTP' || command.loadBalancerType === 'INTERNAL_MANAGED' ? jobs : jobs[0];\n }\n\n return Promise.resolve(\n executeTask({\n application,\n description: `${command.mode === 'edit' ? 'Update' : 'Create'} Load Balancer: ${command.name}`,\n job: jobs,\n }),\n );\n}\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","import React from 'react';\n\nimport { GceHttpLoadBalancerListenerEditor } from './GceHttpLoadBalancerListenerEditor';\nimport {\n GceHttpLoadBalancerBackendServiceEditor,\n GceHttpLoadBalancerHealthCheckEditor,\n} from './GceHttpLoadBalancerResourceEditors';\nimport { GceHttpLoadBalancerHostRuleEditor } from './GceHttpLoadBalancerRoutingEditor';\nimport type {\n GceLoadBalancerType,\n IGceLoadBalancerCommand,\n IGceLoadBalancerData,\n IGceLoadBalancerDataItem,\n IGceLoadBalancerListener,\n IGceResourceReference,\n} from '../common';\nimport { mergeGceResourceOptions } from '../common';\n\nimport './httpLoadBalancerWizard.component.less';\n\nexport interface IGceHttpLoadBalancerEditorProps {\n command: IGceLoadBalancerCommand;\n data: IGceLoadBalancerData;\n onChange: (command: IGceLoadBalancerCommand) => void;\n}\n\ninterface IGceHttpLoadBalancerDataItem extends IGceLoadBalancerDataItem {\n account?: string;\n id?: string;\n network?: string;\n region?: string;\n}\n\nexport function FormRow({ children, label }: { children: React.ReactNode; label: string }): JSX.Element {\n return (\n <div className=\"form-group\">\n <label className=\"col-md-2 sm-label-right\">{label}</label>\n <div className=\"col-md-8\">{children}</div>\n </div>\n );\n}\n\nexport interface IGceHttpLoadBalancerOptions extends IGceLoadBalancerData {\n accounts: IGceHttpLoadBalancerDataItem[];\n addresses: IGceHttpLoadBalancerDataItem[];\n backendServices: IGceHttpLoadBalancerDataItem[];\n certificates: IGceHttpLoadBalancerDataItem[];\n healthChecks: IGceHttpLoadBalancerDataItem[];\n networks: IGceHttpLoadBalancerDataItem[];\n regions: IGceHttpLoadBalancerDataItem[];\n subnets: IGceHttpLoadBalancerDataItem[];\n}\n\nfunction uniqueOptions<T extends { name?: string }>(options: T[]): Array<T & { name: string }> {\n return options.filter(\n (option, index): option is T & { name: string } =>\n Boolean(option.name) && options.findIndex(({ name }) => name === option.name) === index,\n );\n}\n\nexport function buildGceHttpLoadBalancerOptions(\n command: IGceLoadBalancerCommand,\n data: IGceLoadBalancerData,\n): IGceHttpLoadBalancerOptions {\n const internal = command.loadBalancerType === 'INTERNAL_MANAGED';\n const accountMatches = (item: IGceHttpLoadBalancerDataItem): boolean => item.account === command.credentials;\n const locationMatches = (item: IGceHttpLoadBalancerDataItem): boolean =>\n accountMatches(item) &&\n (internal ? item.region === command.region : item.region === undefined || item.region === 'global');\n const networks = (data.networks as IGceHttpLoadBalancerDataItem[]).filter(accountMatches);\n const selectedNetwork = networks.find(\n (network) => network.name === command.network?.name || network.id === command.network?.name,\n );\n const networkId = (command.network?.id as string | undefined) || selectedNetwork?.id || command.network?.name;\n const hostBackendServices = command.hostRules.flatMap((hostRule) => [\n ...(hostRule.pathMatcher.defaultService ? [hostRule.pathMatcher.defaultService] : []),\n ...hostRule.pathMatcher.pathRules.flatMap((pathRule) => (pathRule.backendService ? [pathRule.backendService] : [])),\n ]);\n const backendHealthChecks = command.backendServices.flatMap((service) =>\n service.healthCheck ? [service.healthCheck] : [],\n );\n\n return {\n accounts: mergeGceResourceOptions(data.accounts, command.credentials ? [{ name: command.credentials }] : []),\n addresses: mergeGceResourceOptions(\n (data.addresses as IGceHttpLoadBalancerDataItem[]).filter(locationMatches),\n uniqueOptions(command.listeners.flatMap((listener) => (listener.address ? [listener.address] : []))),\n ),\n backendServices: mergeGceResourceOptions(\n (data.backendServices as IGceHttpLoadBalancerDataItem[]).filter(locationMatches),\n uniqueOptions([\n ...command.backendServices,\n ...(command.defaultService ? [command.defaultService] : []),\n ...hostBackendServices,\n ]),\n ),\n certificates: mergeGceResourceOptions(\n (data.certificates as IGceHttpLoadBalancerDataItem[]).filter(locationMatches),\n uniqueOptions(command.listeners.flatMap((listener) => (listener.certificate ? [listener.certificate] : []))),\n ),\n healthChecks: mergeGceResourceOptions(\n (data.healthChecks as IGceHttpLoadBalancerDataItem[]).filter(locationMatches),\n uniqueOptions([...command.healthChecks, ...backendHealthChecks]),\n ),\n networks: mergeGceResourceOptions(networks, command.network ? [command.network] : []),\n regions: mergeGceResourceOptions(data.regions, command.region ? [{ name: command.region }] : []),\n subnets: mergeGceResourceOptions(\n internal\n ? (data.subnets as IGceHttpLoadBalancerDataItem[]).filter(\n (subnet) => accountMatches(subnet) && subnet.region === command.region && subnet.network === networkId,\n )\n : [],\n uniqueOptions([\n ...(command.subnet ? [command.subnet] : []),\n ...command.listeners.flatMap((listener) => (listener.subnet ? [listener.subnet] : [])),\n ]),\n ),\n };\n}\n\nexport function constrainGceHttpLoadBalancerCommand(command: IGceLoadBalancerCommand): IGceLoadBalancerCommand {\n const constrainListener = ({ subnet, ...listener }: IGceLoadBalancerListener, keepSubnet: boolean) => {\n if (listener.protocol === 'HTTPS') {\n return { ...listener, portRange: '443', protocol: 'HTTPS' as const, ...(keepSubnet && subnet ? { subnet } : {}) };\n }\n const { certificate: _certificate, ...plaintextListener } = listener;\n return { ...plaintextListener, protocol: 'HTTP' as const, ...(keepSubnet && subnet ? { subnet } : {}) };\n };\n\n if (command.loadBalancerType === 'INTERNAL_MANAGED') {\n return {\n ...command,\n listeners: command.listeners.map((listener) => constrainListener(listener, true)),\n region: command.region === 'global' ? '' : command.region,\n };\n }\n\n return {\n ...command,\n listeners: command.listeners.map((listener) => constrainListener(listener, false)),\n loadBalancerType: 'HTTP',\n network: undefined,\n region: 'global',\n subnet: undefined,\n };\n}\n\nexport function validateGceHttpLoadBalancerCommand(command: IGceLoadBalancerCommand): string[] {\n const errors = new Set<string>();\n const internal = command.loadBalancerType === 'INTERNAL_MANAGED';\n\n if (!command.name.trim()) errors.add('Name is required.');\n if (!command.credentials) errors.add('Account is required.');\n if (internal) {\n if (!command.region || command.region === 'global') {\n errors.add('Region is required for INTERNAL_MANAGED load balancers.');\n }\n if (!command.network?.name) errors.add('Network is required for INTERNAL_MANAGED load balancers.');\n if (!command.subnet?.name) errors.add('Subnet is required for INTERNAL_MANAGED load balancers.');\n } else if (command.region !== 'global') {\n errors.add('HTTP load balancers must use the global location.');\n }\n\n if (!command.listeners.length) errors.add('At least one listener is required.');\n command.listeners.forEach((listener) => {\n if (!listener.name.trim()) errors.add('Listener name is required.');\n if (listener.protocol !== 'HTTP' && listener.protocol !== 'HTTPS') {\n errors.add('Listener protocol must be HTTP or HTTPS.');\n }\n if (!validPort(listener.portRange)) {\n errors.add('Listener port must be a single port between 1 and 65535.');\n }\n if (listener.protocol === 'HTTPS' && !listener.certificate?.name) {\n errors.add('Certificate is required for HTTPS listeners.');\n }\n if (listener.protocol === 'HTTPS' && listener.portRange !== '443') {\n errors.add('HTTPS listeners must use port 443.');\n }\n });\n\n if (!command.backendServices.length) errors.add('At least one backend service is required.');\n command.backendServices.forEach((backendService) => {\n if (!backendService.name.trim()) errors.add('Backend service name is required.');\n if (!backendService.healthCheck?.name) errors.add('Each backend service requires a health check.');\n if (!backendService.portName) errors.add('Backend service port name is required.');\n if (negative(backendService.connectionDrainingTimeoutSec)) {\n errors.add('Connection draining timeout must be zero or greater.');\n }\n if (\n backendService.sessionAffinity === 'GENERATED_COOKIE' &&\n !numberInRange(backendService.affinityCookieTtlSec, 0, 86400)\n ) {\n errors.add('Generated cookie TTL must be between 0 and 86400 seconds.');\n }\n });\n\n command.healthChecks.forEach((healthCheck) => {\n if (!healthCheck.name?.trim()) errors.add('Health check name is required.');\n if (!['HTTP', 'HTTPS', 'TCP', 'SSL'].includes(String(healthCheck.healthCheckType))) {\n errors.add('Health check protocol must be HTTP, HTTPS, TCP, or SSL.');\n }\n if (!validPort(healthCheck.port)) errors.add('Health check port must be between 1 and 65535.');\n if (\n (healthCheck.healthCheckType === 'HTTP' || healthCheck.healthCheckType === 'HTTPS') &&\n !healthCheck.requestPath\n ) {\n errors.add('HTTP and HTTPS health checks require a request path.');\n }\n if (negative(healthCheck.timeoutSec)) errors.add('Health check timeout must be zero or greater.');\n if (healthCheck.checkIntervalSec !== undefined && Number(healthCheck.checkIntervalSec) <= 0) {\n errors.add('Health check interval must be greater than zero.');\n }\n if (healthCheck.healthyThreshold !== undefined && Number(healthCheck.healthyThreshold) <= 0) {\n errors.add('Healthy threshold must be greater than zero.');\n }\n if (healthCheck.unhealthyThreshold !== undefined && Number(healthCheck.unhealthyThreshold) <= 0) {\n errors.add('Unhealthy threshold must be greater than zero.');\n }\n });\n\n if (!command.defaultService?.name) errors.add('Default backend service is required.');\n command.hostRules.forEach((hostRule) => {\n if (!hostRule.hostPatterns.length) errors.add('Host rules require at least one host pattern.');\n if (!hostRule.pathMatcher.defaultService?.name) {\n errors.add('Path matcher default backend service is required.');\n }\n hostRule.pathMatcher.pathRules.forEach((pathRule) => {\n if (!pathRule.paths.length) errors.add('Path rules require at least one path.');\n if (!pathRule.backendService?.name) errors.add('Path rules require a backend service.');\n });\n });\n\n return Array.from(errors);\n}\n\nfunction validPort(value: unknown): boolean {\n const text = String(value ?? '').trim();\n if (!/^\\d+$/.test(text)) return false;\n const port = Number(text);\n return Number.isInteger(port) && port >= 1 && port <= 65535;\n}\n\nfunction negative(value: unknown): boolean {\n return value !== undefined && Number(value) < 0;\n}\n\nfunction numberInRange(value: unknown, minimum: number, maximum: number): boolean {\n const number = Number(value);\n return value !== undefined && Number.isFinite(number) && number >= minimum && number <= maximum;\n}\n\nfunction selectedReference(name: string, options: IGceLoadBalancerDataItem[]): IGceResourceReference | undefined {\n if (!name) {\n return undefined;\n }\n return (options.find((option) => option.name === name) || { name }) as IGceResourceReference;\n}\n\nexport function GceHttpLoadBalancerEditor({ command, data, onChange }: IGceHttpLoadBalancerEditorProps): JSX.Element {\n const options = buildGceHttpLoadBalancerOptions(command, data);\n const editing = command.mode === 'edit';\n\n const updateListener = (index: number, listener: IGceLoadBalancerListener): void => {\n const listeners = command.listeners.map((current, currentIndex) => (currentIndex === index ? listener : current));\n onChange(constrainGceHttpLoadBalancerCommand({ ...command, listeners }));\n };\n\n const update = (updates: Partial<IGceLoadBalancerCommand>): void => {\n onChange(constrainGceHttpLoadBalancerCommand({ ...command, ...updates } as IGceLoadBalancerCommand));\n };\n\n const updateBackendService = (\n index: number,\n backendService: IGceLoadBalancerCommand['backendServices'][number],\n ): void => {\n const backendServices = command.backendServices.map((current, currentIndex) =>\n currentIndex === index ? backendService : current,\n );\n const selectedHealthCheck = (backendService.healthCheck\n ? options.healthChecks.find(({ name }) => name === backendService.healthCheck?.name)\n : undefined) as IGceLoadBalancerCommand['healthChecks'][number] | undefined;\n const healthChecks =\n selectedHealthCheck && !command.healthChecks.some(({ name }) => name === selectedHealthCheck.name)\n ? [...command.healthChecks, selectedHealthCheck]\n : command.healthChecks;\n update({ backendServices, healthChecks });\n };\n\n const updateRouting = (\n hostRules: IGceLoadBalancerCommand['hostRules'],\n defaultService = command.defaultService,\n ): void => {\n const references = [\n ...(defaultService ? [defaultService] : []),\n ...hostRules.flatMap((hostRule) => [\n ...(hostRule.pathMatcher.defaultService ? [hostRule.pathMatcher.defaultService] : []),\n ...hostRule.pathMatcher.pathRules.flatMap((pathRule) =>\n pathRule.backendService ? [pathRule.backendService] : [],\n ),\n ]),\n ];\n const backendServices = [...command.backendServices];\n references.forEach((reference) => {\n if (!backendServices.some(({ name }) => name === reference.name)) {\n const selected = options.backendServices.find(({ name }) => name === reference.name) || reference;\n backendServices.push(selected as IGceLoadBalancerCommand['backendServices'][number]);\n }\n });\n const healthChecks = [...command.healthChecks];\n backendServices.forEach((service) => {\n if (service.healthCheck && !healthChecks.some(({ name }) => name === service.healthCheck?.name)) {\n const selected = options.healthChecks.find(({ name }) => name === service.healthCheck?.name);\n healthChecks.push((selected || service.healthCheck) as IGceLoadBalancerCommand['healthChecks'][number]);\n }\n });\n update({ backendServices, defaultService, healthChecks, hostRules });\n };\n\n return (\n <div className=\"gce-http-load-balancer-editor\">\n <section>\n <h4>Location</h4>\n <FormRow label=\"Name\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"load-balancer-name\"\n maxLength={63}\n required\n type=\"text\"\n disabled={editing}\n value={command.name}\n onChange={(event) => update({ name: event.target.value })}\n />\n </FormRow>\n <FormRow label=\"Type\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"load-balancer-type\"\n disabled={editing}\n value={command.loadBalancerType}\n onChange={(event) => update({ loadBalancerType: event.target.value as GceLoadBalancerType })}\n >\n <option value=\"HTTP\">HTTP(S)</option>\n <option value=\"INTERNAL_MANAGED\">Internal managed HTTP</option>\n </select>\n </FormRow>\n <FormRow label=\"Account\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"credentials\"\n disabled={editing}\n required\n value={command.credentials}\n onChange={(event) => update({ credentials: event.target.value })}\n >\n <option value=\"\">Select...</option>\n {options.accounts.map((account) => (\n <option key={account.name} value={account.name}>\n {account.name}\n </option>\n ))}\n </select>\n </FormRow>\n {command.loadBalancerType === 'INTERNAL_MANAGED' && (\n <React.Fragment>\n <FormRow label=\"Region\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"region\"\n disabled={editing}\n required\n value={command.region}\n onChange={(event) => update({ region: event.target.value })}\n >\n <option value=\"\">Select...</option>\n {options.regions.map((region) => (\n <option key={region.name} value={region.name}>\n {region.name}\n </option>\n ))}\n </select>\n </FormRow>\n <FormRow label=\"Network\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"network\"\n required\n value={command.network?.name || ''}\n onChange={(event) => update({ network: selectedReference(event.target.value, options.networks) })}\n >\n <option value=\"\">Select...</option>\n {options.networks.map((network) => (\n <option key={network.name} value={network.name}>\n {network.name}\n </option>\n ))}\n </select>\n </FormRow>\n <FormRow label=\"Subnet\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"subnet\"\n required\n value={command.subnet?.name || ''}\n onChange={(event) => {\n const subnet = selectedReference(event.target.value, options.subnets);\n update({\n subnet,\n listeners: command.listeners.map((listener) => ({ ...listener, subnet })),\n });\n }}\n >\n <option value=\"\">Select...</option>\n {options.subnets.map((subnet) => (\n <option key={subnet.name} value={subnet.name}>\n {subnet.name}\n </option>\n ))}\n </select>\n </FormRow>\n </React.Fragment>\n )}\n </section>\n <section>\n <h4>Listeners</h4>\n {command.listeners.map((listener, index) => (\n <GceHttpLoadBalancerListenerEditor\n addresses={options.addresses}\n certificates={options.certificates}\n key={index}\n listener={listener}\n loadBalancerType={command.loadBalancerType}\n onChange={(updated) => updateListener(index, updated)}\n onRemove={() =>\n update({ listeners: command.listeners.filter((_, currentIndex) => currentIndex !== index) })\n }\n subnets={options.subnets}\n />\n ))}\n <button\n type=\"button\"\n className=\"add-new btn btn-block\"\n onClick={() =>\n update({\n listeners: [\n ...command.listeners,\n {\n name: command.name,\n portRange: '80',\n protocol: 'HTTP',\n subnet: command.loadBalancerType === 'INTERNAL_MANAGED' ? command.subnet : undefined,\n },\n ],\n })\n }\n >\n Add listener\n </button>\n </section>\n <section>\n <h4>Backend services</h4>\n {command.backendServices.map((backendService, index) => (\n <GceHttpLoadBalancerBackendServiceEditor\n backendService={backendService}\n backendServices={options.backendServices}\n healthChecks={options.healthChecks}\n key={index}\n loadBalancerType={command.loadBalancerType}\n onChange={(updated) => updateBackendService(index, updated)}\n onRemove={() =>\n update({\n backendServices: command.backendServices.filter((_, currentIndex) => currentIndex !== index),\n })\n }\n />\n ))}\n <button\n type=\"button\"\n className=\"add-new btn btn-block\"\n onClick={() =>\n update({\n backendServices: [...command.backendServices, { name: '', portName: 'http', sessionAffinity: 'NONE' }],\n })\n }\n >\n Add backend service\n </button>\n </section>\n <section>\n <h4>Default service</h4>\n <FormRow label=\"Default backend service\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"default-backend-service\"\n required\n value={command.defaultService?.name || ''}\n onChange={(event) =>\n updateRouting(command.hostRules, selectedReference(event.target.value, options.backendServices))\n }\n >\n <option value=\"\">Select...</option>\n {options.backendServices.map((service) => (\n <option key={service.name} value={service.name}>\n {service.name}\n </option>\n ))}\n </select>\n </FormRow>\n </section>\n <section>\n <h4>Host and path rules</h4>\n {command.hostRules.map((hostRule, index) => (\n <GceHttpLoadBalancerHostRuleEditor\n backendServices={options.backendServices}\n hostRule={hostRule}\n key={index}\n onChange={(updated) =>\n updateRouting(\n command.hostRules.map((current, currentIndex) => (currentIndex === index ? updated : current)),\n )\n }\n onRemove={() => updateRouting(command.hostRules.filter((_, currentIndex) => currentIndex !== index))}\n />\n ))}\n <button\n type=\"button\"\n className=\"add-new btn btn-block\"\n onClick={() =>\n updateRouting([\n ...command.hostRules,\n {\n hostPatterns: [],\n pathMatcher: { defaultService: command.defaultService, pathRules: [] },\n },\n ])\n }\n >\n Add host rule\n </button>\n </section>\n <section>\n <h4>Health checks</h4>\n {command.healthChecks.map((healthCheck, index) => (\n <GceHttpLoadBalancerHealthCheckEditor\n healthCheck={healthCheck}\n healthChecks={options.healthChecks}\n key={index}\n onChange={(updated) =>\n update({\n healthChecks: command.healthChecks.map((current, currentIndex) =>\n currentIndex === index ? updated : current,\n ),\n })\n }\n onRemove={() =>\n update({ healthChecks: command.healthChecks.filter((_, currentIndex) => currentIndex !== index) })\n }\n />\n ))}\n <button\n type=\"button\"\n className=\"add-new btn btn-block\"\n onClick={() =>\n update({\n healthChecks: [\n ...command.healthChecks,\n {\n checkIntervalSec: 10,\n healthCheckType: 'HTTP',\n name: '',\n port: 80,\n requestPath: '/',\n timeoutSec: 5,\n healthyThreshold: 10,\n unhealthyThreshold: 2,\n },\n ],\n })\n }\n >\n Add health check\n </button>\n </section>\n </div>\n );\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps, ITask, ITaskCommand } from '@spinnaker/core';\nimport { ModalClose, ReactModal, TaskMonitor, TaskMonitorWrapper } from '@spinnaker/core';\n\nimport {\n constrainGceHttpLoadBalancerCommand,\n GceHttpLoadBalancerEditor,\n validateGceHttpLoadBalancerCommand,\n} from './GceHttpLoadBalancerEditor';\nimport type {\n GceLoadBalancerEditorMode,\n GceLoadBalancerType,\n IGceLoadBalancerCommand,\n IGceLoadBalancerData,\n IGceLoadBalancerDataReaders,\n IGceLoadBalancerDataState,\n} from '../common';\nimport {\n GceLoadBalancerDataController,\n normalizeGceLoadBalancerCommand,\n submitGceLoadBalancerCommand,\n} from '../common';\n\nconst EMPTY_DATA: IGceLoadBalancerData = {\n accounts: [],\n addresses: [],\n backendServices: [],\n certificates: [],\n healthChecks: [],\n networks: [],\n regions: [],\n subnets: [],\n};\n\nexport interface IGceHttpLoadBalancerModalProps extends IModalComponentProps {\n app?: Application;\n application?: Application;\n credentials?: string;\n data?: IGceLoadBalancerData;\n dataReaders?: IGceLoadBalancerDataReaders;\n executeTask?: (taskCommand: ITaskCommand) => PromiseLike<ITask>;\n forPipelineConfig?: boolean;\n isNew?: boolean;\n loadBalancer?: Record<string, unknown>;\n loadBalancerType?: Extract<GceLoadBalancerType, 'HTTP' | 'INTERNAL_MANAGED'>;\n mode?: GceLoadBalancerEditorMode;\n}\n\ninterface IGceHttpLoadBalancerModalState extends IGceLoadBalancerDataState {\n command: IGceLoadBalancerCommand;\n taskMonitor: TaskMonitor;\n}\n\nexport function initializeGceHttpLoadBalancerCommand(\n source: Record<string, unknown>,\n mode: GceLoadBalancerEditorMode,\n application: Application,\n defaults: Partial<Record<'credentials' | 'loadBalancerType', unknown>> = {},\n): IGceLoadBalancerCommand {\n const input = {\n ...defaults,\n ...source,\n credentials: source.credentials || source.account || defaults.credentials,\n loadBalancerType: source.loadBalancerType || defaults.loadBalancerType || 'HTTP',\n name: source.name || source.loadBalancerName || source.urlMapName || application?.name || '',\n };\n const command = normalizeGceLoadBalancerCommand(input, mode);\n const hasPersistedListener =\n (Array.isArray(source.listeners) && source.listeners.length > 0) ||\n source.port !== undefined ||\n source.portRange !== undefined ||\n source.ports !== undefined;\n if (!hasPersistedListener) {\n command.listeners = [{ name: command.name, portRange: '80', protocol: 'HTTP' }];\n }\n return constrainGceHttpLoadBalancerCommand(command);\n}\n\nexport class GceHttpLoadBalancerModal extends React.Component<\n IGceHttpLoadBalancerModalProps,\n IGceHttpLoadBalancerModalState\n> {\n public static supportsPipelineConfig = true;\n\n public static show(props: IGceHttpLoadBalancerModalProps): Promise<unknown> {\n return ReactModal.show(GceHttpLoadBalancerModal, props, { dialogClassName: 'wizard-modal modal-lg' });\n }\n\n private dataController?: GceLoadBalancerDataController;\n private unsubscribe?: () => void;\n\n public constructor(props: IGceHttpLoadBalancerModalProps) {\n super(props);\n const application = this.application(props);\n const mode = this.mode(props);\n const command = initializeGceHttpLoadBalancerCommand(props.loadBalancer || {}, mode, application, {\n credentials: props.credentials,\n loadBalancerType: props.loadBalancerType,\n });\n this.state = {\n command,\n data: props.data || EMPTY_DATA,\n status: props.data ? 'ready' : 'idle',\n taskMonitor: new TaskMonitor({\n application,\n title: `${mode === 'edit' ? 'Updating' : 'Creating'} your load balancer`,\n onDismiss: () => props.dismissModal(),\n onTaskComplete: () => {\n application.loadBalancers?.refresh?.();\n props.closeModal();\n },\n }),\n };\n }\n\n public componentDidMount(): void {\n if (this.props.data) {\n return;\n }\n this.dataController = new GceLoadBalancerDataController(this.props.dataReaders);\n this.unsubscribe = this.dataController.subscribe((state) => this.setState(state));\n this.dataController.load(this.state.command.credentials);\n }\n\n public componentWillUnmount(): void {\n this.unsubscribe?.();\n this.dataController?.dispose();\n }\n\n private application(props = this.props): Application {\n return (props.application || props.app) as Application;\n }\n\n private mode(props = this.props): GceLoadBalancerEditorMode {\n if (props.forPipelineConfig) {\n return 'pipeline';\n }\n if (props.mode) {\n return props.mode;\n }\n return props.isNew === false || props.loadBalancer ? 'edit' : 'create';\n }\n\n private updateCommand = (command: IGceLoadBalancerCommand): void => {\n const accountChanged = command.credentials !== this.state.command.credentials;\n this.setState({ command });\n if (accountChanged && this.dataController) {\n this.dataController.load(command.credentials);\n }\n };\n\n private submit = (): void => {\n if (validateGceHttpLoadBalancerCommand(this.state.command).length) {\n return;\n }\n const command = constrainGceHttpLoadBalancerCommand(this.state.command);\n const dependencies = {\n application: this.application(),\n executeTask: this.props.executeTask,\n };\n if (command.mode === 'pipeline') {\n this.props.closeModal(submitGceLoadBalancerCommand(command, dependencies));\n return;\n }\n this.state.taskMonitor.submit(() => submitGceLoadBalancerCommand(command, dependencies) as PromiseLike<ITask>);\n };\n\n public render(): JSX.Element {\n const { command, data, status, taskMonitor } = this.state;\n const validationErrors = validateGceHttpLoadBalancerCommand(command);\n const heading =\n command.mode === 'create'\n ? `Create ${command.loadBalancerType === 'HTTP' ? 'HTTP(S)' : 'Internal managed HTTP(S)'} load balancer`\n : `Edit ${command.name}`;\n\n return (\n <form className=\"form-horizontal gce-http-lb\" name=\"form\">\n <div className=\"modal-header\">\n <ModalClose dismiss={this.props.dismissModal} />\n <h3>{heading}</h3>\n </div>\n <div className=\"modal-body\">\n <TaskMonitorWrapper monitor={taskMonitor} />\n {status === 'loading' && <div className=\"horizontal center middle\">Loading...</div>}\n {status === 'error' && <div className=\"alert alert-danger\">Unable to load GCE resources.</div>}\n <GceHttpLoadBalancerEditor command={command} data={data} onChange={this.updateCommand} />\n {!!validationErrors.length && (\n <div className=\"alert alert-danger gce-http-validation-errors\">\n {validationErrors.map((error) => (\n <div key={error}>{error}</div>\n ))}\n </div>\n )}\n </div>\n <div className=\"modal-footer\">\n <button\n type=\"button\"\n className=\"btn btn-default\"\n disabled={taskMonitor.submitting}\n onClick={this.props.dismissModal}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"btn btn-primary\"\n disabled={taskMonitor.submitting || status === 'loading' || !!validationErrors.length}\n onClick={this.submit}\n >\n {command.mode === 'pipeline' ? 'Done' : command.mode === 'edit' ? 'Update' : 'Create'}\n </button>\n </div>\n </form>\n );\n }\n}\n","import React from 'react';\n\nimport type {\n GceLoadBalancerProtocol,\n IGceLoadBalancerCommand,\n IGceLoadBalancerData,\n IGceLoadBalancerDataItem,\n IGceLoadBalancerHealthCheck,\n IGceResourceReference,\n} from '../common';\nimport { mergeGceResourceOptions } from '../common';\n\nexport type GceNetworkSessionAffinity = 'NONE' | 'CLIENT_IP' | 'CLIENT_IP_PROTO';\n\nexport type IGceNetworkLoadBalancerCommand = IGceLoadBalancerCommand & {\n loadBalancerType: 'NETWORK';\n sessionAffinity: GceNetworkSessionAffinity;\n targetPool?: IGceResourceReference;\n};\n\ninterface IGceNetworkDataItem extends IGceLoadBalancerDataItem {\n account?: string;\n credentials?: string;\n network?: string | IGceResourceReference;\n region?: string;\n}\n\nexport interface IGceNetworkLoadBalancerOptions {\n accounts: IGceNetworkDataItem[];\n addresses: IGceNetworkDataItem[];\n networks: IGceNetworkDataItem[];\n regions: IGceNetworkDataItem[];\n}\n\nexport interface IGceNetworkLoadBalancerEditorProps {\n command: IGceNetworkLoadBalancerCommand;\n data: IGceLoadBalancerData;\n onChange: (command: IGceNetworkLoadBalancerCommand) => void;\n}\n\nconst SESSION_AFFINITIES: GceNetworkSessionAffinity[] = ['NONE', 'CLIENT_IP', 'CLIENT_IP_PROTO'];\nconst PROTOCOLS: GceLoadBalancerProtocol[] = ['TCP', 'UDP'];\n\nexport function createGceNetworkHealthCheck(): IGceLoadBalancerHealthCheck {\n return {\n checkIntervalSec: 10,\n healthCheckType: 'HTTP',\n healthyThreshold: 10,\n port: 80,\n requestPath: '/',\n timeoutSec: 5,\n unhealthyThreshold: 2,\n };\n}\n\nexport function buildGceNetworkLoadBalancerOptions(\n command: IGceNetworkLoadBalancerCommand,\n data: IGceLoadBalancerData,\n): IGceNetworkLoadBalancerOptions {\n const accountMatches = (item: IGceNetworkDataItem): boolean =>\n !item.account && !item.credentials ? true : (item.account || item.credentials) === command.credentials;\n const locationMatches = (item: IGceNetworkDataItem): boolean =>\n accountMatches(item) && (!item.region || item.region === command.region);\n const listener = command.listeners[0];\n\n return {\n accounts: mergeGceResourceOptions(data.accounts, command.credentials ? [{ name: command.credentials }] : []),\n addresses: mergeGceResourceOptions(\n (data.addresses as IGceNetworkDataItem[]).filter(locationMatches),\n references(listener?.address),\n ),\n networks: mergeGceResourceOptions(\n (data.networks as IGceNetworkDataItem[]).filter(accountMatches),\n references(command.network),\n ),\n regions: mergeGceResourceOptions(data.regions, command.region ? [{ name: command.region }] : []),\n };\n}\n\nexport function validateGceNetworkLoadBalancerCommand(command: IGceNetworkLoadBalancerCommand): string[] {\n const errors: string[] = [];\n const listener = command.listeners[0];\n const healthCheck = command.healthChecks[0];\n\n if (!command.name.trim()) errors.push('Name is required.');\n if (!command.credentials) errors.push('Account is required.');\n if (!command.region) errors.push('Region is required.');\n if (!validPortRange(listener?.portRange)) errors.push('Port range must contain ports between 1 and 65535.');\n\n if (healthCheck) {\n if (!validPort(healthCheck.port)) errors.push('Health check port must be between 1 and 65535.');\n if (!healthCheck.requestPath) errors.push('Health check path is required.');\n if (negative(healthCheck.timeoutSec)) errors.push('Health check timeout must be zero or greater.');\n if (healthCheck.checkIntervalSec !== undefined && Number(healthCheck.checkIntervalSec) <= 0) {\n errors.push('Health check interval must be greater than zero.');\n }\n if (healthCheck.healthyThreshold !== undefined && Number(healthCheck.healthyThreshold) <= 0) {\n errors.push('Healthy threshold must be greater than zero.');\n }\n if (healthCheck.unhealthyThreshold !== undefined && Number(healthCheck.unhealthyThreshold) <= 0) {\n errors.push('Unhealthy threshold must be greater than zero.');\n }\n }\n\n return errors;\n}\n\nexport function GceNetworkLoadBalancerEditor({\n command,\n data,\n onChange,\n}: IGceNetworkLoadBalancerEditorProps): JSX.Element {\n const options = buildGceNetworkLoadBalancerOptions(command, data);\n const listener = command.listeners[0] || { name: command.name, portRange: '', protocol: 'TCP' };\n const healthCheck = command.healthChecks[0];\n const editing = command.mode === 'edit';\n const update = (updates: Partial<IGceNetworkLoadBalancerCommand>): void =>\n onChange({ ...command, ...updates } as IGceNetworkLoadBalancerCommand);\n const updateListener = (updates: Partial<typeof listener>): void =>\n update({ listeners: [{ ...listener, ...updates }] });\n const updateHealthCheck = (updates: Partial<IGceLoadBalancerHealthCheck>): void =>\n update({ healthChecks: [{ ...healthCheck, ...updates }] });\n const updateName = (name: string): void =>\n update({\n name,\n listeners: [{ ...listener, name: listener.name === command.name ? name : listener.name }],\n });\n\n return (\n <div className=\"form-horizontal gce-network-load-balancer-editor\">\n {textField('Name', 'name', command.name, updateName, editing)}\n {selectField(\n 'Account',\n 'credentials',\n command.credentials,\n options.accounts,\n (credentials) => update({ credentials }),\n editing,\n )}\n {selectField('Region', 'region', command.region, options.regions, (region) => update({ region }), editing)}\n {selectField(\n 'Network',\n 'network',\n command.network?.name,\n options.networks,\n (name) => update({ network: selectedReference(name, options.networks) }),\n editing,\n )}\n\n <h4>Forwarding Rule</h4>\n {selectField('IP address', 'address', listener.address?.name, options.addresses, (name) =>\n updateListener({ address: selectedReference(name, options.addresses) }),\n )}\n {selectField(\n 'Protocol',\n 'protocol',\n listener.protocol,\n PROTOCOLS.map((name) => ({ name })),\n (protocol) => updateListener({ protocol: protocol as GceLoadBalancerProtocol }),\n )}\n {textField('Port range', 'portRange', listener.portRange, (portRange) => updateListener({ portRange }))}\n {textField('Target pool', 'targetPool', command.targetPool?.name || '', () => undefined, true)}\n {selectField(\n 'Session affinity',\n 'sessionAffinity',\n command.sessionAffinity,\n SESSION_AFFINITIES.map((name) => ({ name })),\n (sessionAffinity) => update({ sessionAffinity: sessionAffinity as GceNetworkSessionAffinity }),\n editing,\n )}\n\n <h4>Health Check</h4>\n <div className=\"form-group\" data-field=\"healthCheckEnabled\">\n <div className=\"col-md-7 col-md-offset-3\">\n <label>\n <input\n checked={Boolean(healthCheck)}\n onChange={(event) =>\n update({ healthChecks: event.target.checked ? [createGceNetworkHealthCheck()] : [] })\n }\n type=\"checkbox\"\n />{' '}\n Enable health check\n </label>\n </div>\n </div>\n {healthCheck && (\n <React.Fragment>\n {numberField('Port', 'healthCheckPort', healthCheck.port, (port) => updateHealthCheck({ port }))}\n {textField('Request path', 'requestPath', healthCheck.requestPath || '', (requestPath) =>\n updateHealthCheck({\n requestPath: requestPath && !requestPath.startsWith('/') ? `/${requestPath}` : requestPath,\n }),\n )}\n {numberField('Timeout', 'timeoutSec', healthCheck.timeoutSec, (timeoutSec) =>\n updateHealthCheck({ timeoutSec }),\n )}\n {numberField('Interval', 'checkIntervalSec', healthCheck.checkIntervalSec, (checkIntervalSec) =>\n updateHealthCheck({ checkIntervalSec }),\n )}\n {numberField('Healthy threshold', 'healthyThreshold', healthCheck.healthyThreshold, (healthyThreshold) =>\n updateHealthCheck({ healthyThreshold }),\n )}\n {numberField(\n 'Unhealthy threshold',\n 'unhealthyThreshold',\n healthCheck.unhealthyThreshold,\n (unhealthyThreshold) => updateHealthCheck({ unhealthyThreshold }),\n )}\n </React.Fragment>\n )}\n </div>\n );\n}\n\nfunction textField(\n label: string,\n field: string,\n value: string,\n onChange: (value: string) => void,\n disabled = false,\n): JSX.Element {\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <input\n className=\"form-control input-sm\"\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n value={value || ''}\n />\n </div>\n </div>\n );\n}\n\nfunction numberField(\n label: string,\n field: string,\n value: unknown,\n onChange: (value: number | undefined) => void,\n): JSX.Element {\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <input\n className=\"form-control input-sm\"\n onChange={(event) => onChange(event.target.value === '' ? undefined : Number(event.target.value))}\n type=\"number\"\n value={value === undefined || value === null ? '' : String(value)}\n />\n </div>\n </div>\n );\n}\n\nfunction selectField(\n label: string,\n field: string,\n value: string | undefined,\n options: readonly IGceLoadBalancerDataItem[],\n onChange: (value: string) => void,\n disabled = false,\n): JSX.Element {\n return (\n <div className=\"form-group\" data-field={field}>\n <label className=\"col-md-3 sm-label-right\">{label}</label>\n <div className=\"col-md-7\">\n <select\n className=\"form-control input-sm\"\n disabled={disabled}\n onChange={(event) => onChange(event.target.value)}\n value={value || ''}\n >\n <option value=\"\">Select...</option>\n {options.map(({ name }) => (\n <option key={name} value={name}>\n {name}\n </option>\n ))}\n </select>\n </div>\n </div>\n );\n}\n\nfunction selectedReference(\n name: string,\n options: readonly IGceLoadBalancerDataItem[],\n): IGceResourceReference | undefined {\n return name ? ((options.find((option) => option.name === name) || { name }) as IGceResourceReference) : undefined;\n}\n\nfunction references<T extends IGceLoadBalancerDataItem>(referenceValue?: T): T[] {\n return referenceValue?.name ? [referenceValue] : [];\n}\n\nfunction validPort(value: unknown): boolean {\n const port = Number(value);\n return Number.isInteger(port) && port >= 1 && port <= 65535;\n}\n\nfunction validPortRange(value: string | undefined): boolean {\n const match = String(value || '').match(/^(\\d+)(?:-(\\d+))?$/);\n if (!match) return false;\n const start = Number(match[1]);\n const end = Number(match[2] || match[1]);\n return validPort(start) && validPort(end) && start <= end;\n}\n\nfunction negative(value: unknown): boolean {\n return value !== undefined && value !== null && Number(value) < 0;\n}\n","import { defaults } from 'lodash';\n\nimport type { IInstanceStorage, IProviderSettings } from '@spinnaker/core';\nimport { SETTINGS } from '@spinnaker/core';\n\nexport interface IGCEProviderSettings extends IProviderSettings {\n defaults: {\n account?: string;\n region?: string;\n zone?: string;\n instanceTypeStorage?: IInstanceStorage;\n };\n feature: {\n predictiveAutoscaling?: boolean;\n statefulMigsEnabled?: boolean;\n };\n}\n\nexport const GCEProviderSettings: IGCEProviderSettings = defaults(SETTINGS.providers.gce || {}, {\n defaults: {},\n feature: {},\n resetToOriginal: SETTINGS.resetProvider('gce'),\n});\n","import React from 'react';\n\nimport type { Application, IModalComponentProps, ITask, ITaskCommand } from '@spinnaker/core';\nimport {\n InfrastructureCaches,\n ModalClose,\n ReactModal,\n SubmitButton,\n TaskExecutor,\n TaskMonitor,\n TaskMonitorWrapper,\n} from '@spinnaker/core';\n\nimport type { GceNetworkSessionAffinity, IGceNetworkLoadBalancerCommand } from './GceNetworkLoadBalancerEditor';\nimport {\n createGceNetworkHealthCheck,\n GceNetworkLoadBalancerEditor,\n validateGceNetworkLoadBalancerCommand,\n} from './GceNetworkLoadBalancerEditor';\nimport type {\n GceLoadBalancerEditorMode,\n IGceLoadBalancerData,\n IGceLoadBalancerDataReaders,\n IGceLoadBalancerDataState,\n IGceLoadBalancerHealthCheck,\n IGceResourceReference,\n IGceSerializedLoadBalancerCommand,\n} from '../common';\nimport {\n GceLoadBalancerDataController,\n normalizeGceLoadBalancerCommand,\n serializeGceLoadBalancerCommand,\n} from '../common';\nimport { GCEProviderSettings } from '../../../gce.settings';\n\ntype UnknownRecord = Record<string, any>;\n\nconst EMPTY_DATA: IGceLoadBalancerData = {\n accounts: [],\n addresses: [],\n backendServices: [],\n certificates: [],\n healthChecks: [],\n networks: [],\n regions: [],\n subnets: [],\n};\nconst SESSION_AFFINITIES: GceNetworkSessionAffinity[] = ['NONE', 'CLIENT_IP', 'CLIENT_IP_PROTO'];\n\ninterface IGceNetworkHealthCheckPayload {\n checkIntervalSec?: number;\n healthyThreshold?: number;\n port?: number;\n requestPath?: string;\n timeoutSec?: number;\n unhealthyThreshold?: number;\n}\n\nexport interface IGceNetworkLoadBalancerPayload extends IGceSerializedLoadBalancerCommand {\n healthCheck: IGceNetworkHealthCheckPayload | null;\n sessionAffinity: GceNetworkSessionAffinity;\n}\n\nexport interface IGceNetworkLoadBalancerModalProps extends IModalComponentProps {\n app?: Application;\n application?: Application;\n credentials?: string;\n data?: IGceLoadBalancerData;\n dataReaders?: IGceLoadBalancerDataReaders;\n executeTask?: (taskCommand: ITaskCommand) => PromiseLike<ITask>;\n forPipelineConfig?: boolean;\n isNew?: boolean;\n loadBalancer?: UnknownRecord;\n mode?: GceLoadBalancerEditorMode;\n}\n\ninterface IGceNetworkLoadBalancerModalState extends IGceLoadBalancerDataState {\n command: IGceNetworkLoadBalancerCommand;\n taskMonitor: TaskMonitor;\n}\n\ninterface IGceNetworkSubmissionDependencies {\n application: Application;\n executeTask?: (taskCommand: ITaskCommand) => PromiseLike<ITask>;\n}\n\nexport function normalizeGceNetworkLoadBalancerCommand(\n persisted: UnknownRecord | null | undefined = {},\n mode: GceLoadBalancerEditorMode,\n applicationName = '',\n defaults: Partial<Record<'credentials' | 'region', unknown>> = {},\n): IGceNetworkLoadBalancerCommand {\n const persistedLoadBalancer = persisted || {};\n const details =\n persistedLoadBalancer.elb && typeof persistedLoadBalancer.elb === 'object' ? persistedLoadBalancer.elb : {};\n const listener = details.listenerDescriptions?.[0]?.listener || {};\n const sourceDetails: UnknownRecord = {\n ...details,\n ...persistedLoadBalancer,\n healthCheck:\n persistedLoadBalancer.healthCheck !== undefined ? persistedLoadBalancer.healthCheck : details.healthCheck,\n ipAddress: persistedLoadBalancer.ipAddress !== undefined ? persistedLoadBalancer.ipAddress : details.ipAddress,\n ipProtocol:\n persistedLoadBalancer.ipProtocol !== undefined\n ? persistedLoadBalancer.ipProtocol\n : details.ipProtocol || listener.protocol,\n portRange:\n persistedLoadBalancer.portRange !== undefined\n ? persistedLoadBalancer.portRange\n : details.portRange || listener.loadBalancerPort,\n sessionAffinity:\n persistedLoadBalancer.sessionAffinity !== undefined\n ? persistedLoadBalancer.sessionAffinity\n : details.sessionAffinity,\n targetPool: persistedLoadBalancer.targetPool !== undefined ? persistedLoadBalancer.targetPool : details.targetPool,\n };\n const hasHealthCheck =\n Object.prototype.hasOwnProperty.call(persistedLoadBalancer, 'healthCheck') ||\n Object.prototype.hasOwnProperty.call(details, 'healthCheck') ||\n sourceDetails.healthChecks;\n const persistedHealthChecks = sourceDetails.healthChecks?.length\n ? sourceDetails.healthChecks\n : sourceDetails.healthCheck\n ? [normalizeHealthCheckInput(sourceDetails.healthCheck)]\n : [];\n const source: UnknownRecord = {\n ...defaults,\n ...sourceDetails,\n credentials: sourceDetails.credentials || sourceDetails.account || defaults.credentials,\n healthChecks: persistedHealthChecks,\n ipAddress: normalizeReference(sourceDetails.ipAddress),\n loadBalancerType: 'NETWORK',\n name: sourceDetails.name || sourceDetails.loadBalancerName || applicationName,\n network: normalizeReference(sourceDetails.network),\n region: sourceDetails.region || defaults.region,\n };\n const command = normalizeGceLoadBalancerCommand(source, mode);\n const hasListener =\n (Array.isArray(sourceDetails.listeners) && sourceDetails.listeners.length > 0) ||\n sourceDetails.ipAddress !== undefined ||\n sourceDetails.ipProtocol !== undefined ||\n sourceDetails.portRange !== undefined ||\n sourceDetails.ports !== undefined;\n if (!hasListener) {\n command.listeners = [{ name: command.name, portRange: '8080', protocol: 'TCP' }];\n }\n if (mode === 'create' && !hasHealthCheck) {\n command.healthChecks = [createGceNetworkHealthCheck()];\n }\n\n return {\n ...command,\n loadBalancerType: 'NETWORK',\n sessionAffinity: normalizeSessionAffinity(sourceDetails.sessionAffinity),\n targetPool: normalizeReference(sourceDetails.targetPool),\n } as IGceNetworkLoadBalancerCommand;\n}\n\nexport function serializeGceNetworkLoadBalancerCommand(\n command: IGceNetworkLoadBalancerCommand,\n): IGceNetworkLoadBalancerPayload {\n const serialized = serializeGceLoadBalancerCommand(command);\n delete serialized.healthChecks;\n delete serialized.listeners;\n delete serialized.network;\n delete serialized.targetPool;\n delete serialized.mode;\n\n return {\n ...serialized,\n healthCheck: serializeHealthCheck(command.healthChecks[0]),\n sessionAffinity: command.sessionAffinity,\n } as IGceNetworkLoadBalancerPayload;\n}\n\nexport function submitGceNetworkLoadBalancerCommand(\n command: IGceNetworkLoadBalancerCommand,\n { application, executeTask = TaskExecutor.executeTask }: IGceNetworkSubmissionDependencies,\n): IGceNetworkLoadBalancerPayload | Promise<ITask> {\n const payload = serializeGceNetworkLoadBalancerCommand(command);\n if (command.mode === 'pipeline') {\n return payload;\n }\n\n return Promise.resolve(\n executeTask({\n application,\n description: `${command.mode === 'edit' ? 'Update' : 'Create'} Load Balancer: ${command.name}`,\n job: [payload],\n }),\n );\n}\n\nclass GceNetworkLoadBalancerModalComponent extends React.Component<\n IGceNetworkLoadBalancerModalProps,\n IGceNetworkLoadBalancerModalState\n> {\n private dataController?: GceLoadBalancerDataController;\n private unsubscribe?: () => void;\n\n public constructor(props: IGceNetworkLoadBalancerModalProps) {\n super(props);\n const application = this.application(props);\n const mode = this.mode(props);\n const command = normalizeGceNetworkLoadBalancerCommand(props.loadBalancer, mode, application?.name, {\n credentials: props.credentials || GCEProviderSettings.defaults.account,\n region: GCEProviderSettings.defaults.region,\n });\n this.state = {\n command,\n data: props.data || EMPTY_DATA,\n status: props.data ? 'ready' : 'idle',\n taskMonitor: new TaskMonitor({\n application,\n title: `${mode === 'edit' ? 'Updating' : 'Creating'} your load balancer`,\n onDismiss: () => props.dismissModal?.(),\n onTaskComplete: () => {\n InfrastructureCaches.clearCache('healthChecks');\n application?.loadBalancers?.refresh?.();\n props.closeModal?.();\n },\n }),\n };\n }\n\n public componentDidMount(): void {\n if (this.props.data) return;\n this.dataController = new GceLoadBalancerDataController(this.props.dataReaders);\n this.unsubscribe = this.dataController.subscribe((state) => this.setState(state));\n this.dataController.load(this.state.command.credentials);\n }\n\n public componentWillUnmount(): void {\n this.unsubscribe?.();\n this.dataController?.dispose();\n }\n\n public render(): JSX.Element {\n const { command, data, status, taskMonitor } = this.state;\n const errors = validateGceNetworkLoadBalancerCommand(command);\n const heading =\n command.mode === 'create'\n ? 'Create Network Load Balancer'\n : command.mode === 'pipeline'\n ? 'Configure Network Load Balancer'\n : `Edit ${command.name}`;\n\n return (\n <div className=\"modal-content\">\n <TaskMonitorWrapper monitor={taskMonitor} />\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h3>{heading}</h3>\n </div>\n <div className=\"modal-body\">\n {status === 'loading' && <div className=\"horizontal center middle\">Loading...</div>}\n {status === 'error' && <div className=\"alert alert-danger\">Unable to load GCE resources.</div>}\n <GceNetworkLoadBalancerEditor command={command} data={data} onChange={this.updateCommand} />\n {!!errors.length && (\n <div className=\"alert alert-danger gce-network-validation-errors\">\n {errors.map((error) => (\n <div key={error}>{error}</div>\n ))}\n </div>\n )}\n </div>\n <div className=\"modal-footer\">\n <button\n className=\"btn btn-default\"\n disabled={taskMonitor.submitting}\n onClick={this.props.dismissModal}\n type=\"button\"\n >\n Cancel\n </button>\n <SubmitButton\n isDisabled={!!errors.length || status === 'loading' || taskMonitor.submitting}\n isFormSubmit={false}\n label={command.mode === 'pipeline' ? 'Done' : command.mode === 'edit' ? 'Update' : 'Create'}\n onClick={this.submit}\n submitting={taskMonitor.submitting}\n />\n </div>\n </div>\n );\n }\n\n private application(props = this.props): Application {\n return (props.application || props.app) as Application;\n }\n\n private mode(props = this.props): GceLoadBalancerEditorMode {\n if (props.forPipelineConfig) return 'pipeline';\n if (props.mode) return props.mode;\n return props.isNew === false || props.loadBalancer ? 'edit' : 'create';\n }\n\n private updateCommand = (command: IGceNetworkLoadBalancerCommand): void => {\n const accountChanged = command.credentials !== this.state.command.credentials;\n this.setState({ command });\n if (accountChanged) this.dataController?.load(command.credentials);\n };\n\n private submit = (): void => {\n if (this.state.command.mode === 'pipeline') {\n this.props.closeModal?.(\n submitGceNetworkLoadBalancerCommand(this.state.command, {\n application: this.application(),\n executeTask: this.props.executeTask,\n }),\n );\n return;\n }\n this.state.taskMonitor.submit(\n () =>\n submitGceNetworkLoadBalancerCommand(this.state.command, {\n application: this.application(),\n executeTask: this.props.executeTask,\n }) as PromiseLike<ITask>,\n );\n };\n}\n\nexport const GceNetworkLoadBalancerModal = Object.assign(GceNetworkLoadBalancerModalComponent, {\n show: (props: IGceNetworkLoadBalancerModalProps) =>\n ReactModal.show(GceNetworkLoadBalancerModalComponent, props, { dialogClassName: 'modal-lg' }),\n supportsPipelineConfig: true,\n});\n\nfunction normalizeHealthCheckInput(value: unknown): UnknownRecord {\n if (value && typeof value === 'object') return value as UnknownRecord;\n const reference = normalizeReference(value);\n return reference || {};\n}\n\nfunction normalizeReference(value: unknown): IGceResourceReference | undefined {\n if (!value) return undefined;\n if (typeof value === 'object') {\n const reference = value as UnknownRecord;\n const selfLink = String(reference.selfLink || '');\n const name = String(reference.name || reference.id || selfLink.split('/').filter(Boolean).pop() || '');\n return name ? ({ ...reference, name } as IGceResourceReference) : undefined;\n }\n const selfLink = String(value);\n const name = selfLink.split('/').filter(Boolean).pop() || selfLink;\n return selfLink.includes('/') ? { name, selfLink } : { name };\n}\n\nfunction normalizeSessionAffinity(value: unknown): GceNetworkSessionAffinity {\n const normalized = String(value || 'NONE').toUpperCase() as GceNetworkSessionAffinity;\n return SESSION_AFFINITIES.includes(normalized) ? normalized : 'NONE';\n}\n\nfunction serializeHealthCheck(healthCheck?: IGceLoadBalancerHealthCheck): IGceNetworkHealthCheckPayload | null {\n if (!healthCheck) return null;\n return {\n checkIntervalSec: numberOrUndefined(healthCheck.checkIntervalSec),\n healthyThreshold: numberOrUndefined(healthCheck.healthyThreshold),\n port: numberOrUndefined(healthCheck.port),\n requestPath: healthCheck.requestPath,\n timeoutSec: numberOrUndefined(healthCheck.timeoutSec),\n unhealthyThreshold: numberOrUndefined(healthCheck.unhealthyThreshold),\n };\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return value === undefined || value === null || value === '' ? undefined : Number(value);\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps } from '@spinnaker/core';\nimport { ModalClose, noop, ReactModal } from '@spinnaker/core';\n\nimport type { GceLoadBalancerEditorMode, GceLoadBalancerType } from '../common';\nimport { GceProxyLoadBalancerModal } from '../common/GceProxyLoadBalancerModal';\nimport { GceHttpLoadBalancerModal } from '../http/GceHttpLoadBalancerModal';\nimport { GceNetworkLoadBalancerModal } from '../network/GceNetworkLoadBalancerModal';\n\nimport './GceLoadBalancerChoiceModal.less';\n\ninterface IGceLoadBalancerModal {\n show: (props: any) => Promise<any>;\n}\n\nexport interface IGceLoadBalancerChoice {\n description: string;\n label: string;\n type: GceLoadBalancerType;\n}\n\nexport const GCE_LOAD_BALANCER_CHOICES: IGceLoadBalancerChoice[] = [\n { type: 'NETWORK', label: 'Network', description: 'Regional pass-through network load balancer.' },\n { type: 'INTERNAL', label: 'Internal', description: 'Regional internal pass-through load balancer.' },\n { type: 'TCP', label: 'TCP', description: 'Global external TCP proxy load balancer.' },\n { type: 'SSL', label: 'SSL', description: 'Global external SSL proxy load balancer.' },\n { type: 'HTTP', label: 'HTTP(S)', description: 'Global external HTTP(S) load balancer.' },\n {\n type: 'INTERNAL_MANAGED',\n label: 'Internal HTTP(S)',\n description: 'Regional internal managed HTTP(S) load balancer.',\n },\n];\n\nexport interface IGceLoadBalancerChoiceModalProps extends IModalComponentProps {\n app?: Application;\n application?: Application;\n forPipelineConfig?: boolean;\n isNew?: boolean;\n loadBalancer?: Record<string, any> | null;\n}\n\ninterface IGceLoadBalancerChoiceModalState {\n selectedChoice: IGceLoadBalancerChoice | null;\n}\n\nexport function getGceLoadBalancerModal(type: GceLoadBalancerType): IGceLoadBalancerModal {\n if (type === 'NETWORK') return GceNetworkLoadBalancerModal;\n if (type === 'HTTP' || type === 'INTERNAL_MANAGED') return GceHttpLoadBalancerModal;\n return GceProxyLoadBalancerModal;\n}\n\nexport class GceLoadBalancerChoiceModal extends React.Component<\n IGceLoadBalancerChoiceModalProps,\n IGceLoadBalancerChoiceModalState\n> {\n public static defaultProps: Partial<IGceLoadBalancerChoiceModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static supportsPipelineConfig = true;\n\n public static show(props: IGceLoadBalancerChoiceModalProps): Promise<any> {\n if (props.isNew === false && props.loadBalancer) {\n const type = getLoadBalancerType(props.loadBalancer.loadBalancerType);\n if (type) {\n const mode = props.forPipelineConfig ? 'pipeline' : 'edit';\n return getGceLoadBalancerModal(type).show(modalProps(props, type, mode));\n }\n }\n\n return ReactModal.show(GceLoadBalancerChoiceModal, props, {\n dialogClassName: 'create-pipeline-modal-overflow-visible modal-lg',\n });\n }\n\n public state: IGceLoadBalancerChoiceModalState = {\n selectedChoice: isBlockedEdit(this.props) ? null : GCE_LOAD_BALANCER_CHOICES[0],\n };\n\n public choiceSelected = (selectedChoice: IGceLoadBalancerChoice): void => {\n if (!isBlockedEdit(this.props)) {\n this.setState({ selectedChoice });\n }\n };\n\n private choose = (): void => {\n const { selectedChoice } = this.state;\n if (!selectedChoice || isBlockedEdit(this.props)) {\n return;\n }\n\n const { type } = selectedChoice;\n const mode = this.props.forPipelineConfig ? 'pipeline' : 'create';\n const result = getGceLoadBalancerModal(type).show(modalProps(this.props, type, mode));\n this.props.closeModal?.(result);\n };\n\n public render(): JSX.Element {\n const { selectedChoice } = this.state;\n const blocked = isBlockedEdit(this.props);\n const persistedType = this.props.loadBalancer?.loadBalancerType;\n const persistedTypeLabel = typeof persistedType === 'string' && persistedType ? `\"${persistedType}\"` : 'missing';\n return (\n <div className=\"gce-load-balancer-choice-modal\">\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h4 className=\"modal-title\">Select Type of Load Balancer</h4>\n </div>\n <div className=\"modal-body\">\n {blocked && (\n <div className=\"alert alert-danger\" role=\"alert\">\n This load balancer cannot be edited because its persisted load balancer type is {persistedTypeLabel} and\n unsupported. No changes can be submitted.\n </div>\n )}\n <div className=\"card-choices\">\n {GCE_LOAD_BALANCER_CHOICES.map((choice) => (\n <button\n aria-pressed={selectedChoice === choice}\n className={`card gce-load-balancer-choice-card ${selectedChoice === choice ? 'active' : ''}`}\n disabled={blocked}\n key={choice.type}\n onClick={() => this.choiceSelected(choice)}\n type=\"button\"\n >\n <h3 className=\"load-balancer-label\">{choice.label}</h3>\n <div>{choice.description}</div>\n </button>\n ))}\n </div>\n </div>\n <div className=\"modal-footer\">\n <button className=\"btn btn-primary\" disabled={blocked} onClick={this.choose} type=\"button\">\n Configure Load Balancer <span className=\"glyphicon glyphicon-chevron-right\" />\n </button>\n </div>\n </div>\n );\n }\n}\n\nfunction getLoadBalancerType(value: unknown): GceLoadBalancerType | undefined {\n return GCE_LOAD_BALANCER_CHOICES.find((choice) => choice.type === value)?.type;\n}\n\nfunction isBlockedEdit(props: IGceLoadBalancerChoiceModalProps): boolean {\n return props.isNew === false && !getLoadBalancerType(props.loadBalancer?.loadBalancerType);\n}\n\nfunction modalProps(\n props: IGceLoadBalancerChoiceModalProps,\n loadBalancerType: GceLoadBalancerType,\n mode: GceLoadBalancerEditorMode,\n): Record<string, any> {\n const application = props.application || props.app;\n return {\n ...props,\n app: application,\n application,\n forPipelineConfig: mode === 'pipeline',\n isNew: mode === 'create',\n loadBalancer: props.loadBalancer || null,\n loadBalancerType,\n mode,\n };\n}\n","import { uniq } from 'lodash';\n\nimport type { IGceHttpLoadBalancer, IGceLoadBalancer } from '../domain/loadBalancer';\n\nexport class GceHttpLoadBalancerUtils {\n public static REGION = 'global';\n\n public isHttpLoadBalancer(lb: IGceLoadBalancer): lb is IGceHttpLoadBalancer {\n const loadBalancer = lb as any;\n return (\n (loadBalancer.provider === 'gce' || loadBalancer.type === 'gce') &&\n (loadBalancer.loadBalancerType === 'HTTP' || loadBalancer.loadBalancerType === 'INTERNAL_MANAGED')\n );\n }\n\n public normalizeLoadBalancerNamesForAccount(\n loadBalancerNames: string[],\n account: string,\n loadBalancers: IGceLoadBalancer[],\n ): string[] {\n // Assume that loadBalancers is a list of all GCE load balancers in an application\n // (but possibly from several accounts), and has already been normalized (listener names mapped to URL map names).\n const normalizedLoadBalancerNames: string[] = [];\n loadBalancerNames.forEach((loadBalancerName) => {\n const matchingUrlMap = loadBalancers.find((loadBalancer) => {\n return (\n account === loadBalancer.account &&\n this.isHttpLoadBalancer(loadBalancer) &&\n loadBalancer.listeners.map((listener) => listener.name).includes(loadBalancerName)\n );\n });\n\n matchingUrlMap\n ? normalizedLoadBalancerNames.push(matchingUrlMap.name)\n : normalizedLoadBalancerNames.push(loadBalancerName);\n });\n return uniq(normalizedLoadBalancerNames);\n }\n}\n","import React, { useCallback, useEffect, useState } from 'react';\n\nimport {\n AccountService,\n AccountTag,\n CloudProviderRegistry,\n CollapsibleSection,\n ConfirmationModalService,\n InfrastructureCaches,\n LoadBalancerWriter,\n ManagedMenuItem,\n TaskExecutor,\n useDataSource,\n useDeckRuntimeServices,\n} from '@spinnaker/core';\n\nimport { GceLoadBalancerChoiceModal } from '../configure/choice/GceLoadBalancerChoiceModal';\nimport { GceHttpLoadBalancerUtils } from '../httpLoadBalancerUtils.service';\n\ninterface IUseDetailsProps {\n app: any;\n autoClose: () => void;\n loadBalancerParams: any;\n}\n\ninterface ILoadGceLoadBalancerDetailsProps extends IUseDetailsProps {\n accountService?: typeof AccountService;\n loadBalancers?: any[];\n loadBalancerReader: any;\n}\n\nconst gceHttpLoadBalancerUtils = new GceHttpLoadBalancerUtils();\n\nfunction isSameVpc(candidate: any, params: any): boolean {\n return (candidate.vpcId || candidate.vpcid || null) === (params.vpcId || null);\n}\n\nfunction findLoadBalancerInList(loadBalancers: any[], params: any): any {\n return (loadBalancers || []).find((candidate: any) => {\n return (\n candidate.name === params.name &&\n candidate.account === params.accountId &&\n (candidate.region === params.region || candidate.region === 'global') &&\n isSameVpc(candidate, params)\n );\n });\n}\n\nfunction uniqBy<T>(items: T[], getKey: (item: T) => string): T[] {\n const seen = new Set<string>();\n return items.filter((item) => {\n const key = getKey(item);\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n return true;\n });\n}\n\nfunction getProtocol(loadBalancer: any): string {\n const port = loadBalancer?.listenerDescriptions?.[0]?.listener?.loadBalancerPort;\n return port === '443' ? 'https:' : 'http:';\n}\n\nfunction getBackendServices(loadBalancer: any): any[] {\n let backendServices = [loadBalancer.defaultService].filter(Boolean);\n\n if ((loadBalancer.hostRules || []).length) {\n (loadBalancer.hostRules || []).forEach((hostRule: any) => {\n if (hostRule.pathMatcher?.defaultService) {\n backendServices.push(hostRule.pathMatcher.defaultService);\n }\n backendServices = backendServices.concat(\n (hostRule.pathMatcher?.pathRules || []).map((pathRule: any) => pathRule.backendService).filter(Boolean),\n );\n });\n }\n\n return uniqBy(backendServices, (backendService: any) => backendService.name || backendService.selfLink || '');\n}\n\nfunction getResourceTypes(loadBalancerType: string): string[] {\n switch (loadBalancerType) {\n case 'INTERNAL':\n return ['gce_forwarding_rule', 'gce_backend_service'];\n case 'NETWORK':\n return ['gce_forwarding_rule', 'gce_target_pool', 'gce_health_check'];\n case 'SSL':\n case 'TCP':\n return ['gce_forwarding_rule', 'gce_backend_service'];\n case 'INTERNAL_MANAGED':\n return ['http_load_balancer', 'gce_target_http_proxy', 'gce_url_map', 'gce_backend_service'];\n default:\n return ['http_load_balancer', 'gce_target_http_proxy', 'gce_url_map', 'gce_backend_service'];\n }\n}\n\nfunction buildLogsLink(project: string, loadBalancer: any): string {\n return `https://console.developers.google.com/project/${project}/logs?advancedFilter=resource.type=(${getResourceTypes(\n loadBalancer.loadBalancerType,\n ).join(' OR ')})%0A\"${loadBalancer.name}\"`;\n}\n\nasync function loadDetails(loadBalancer: any, loadBalancerParams: any, loadBalancerReader: any): Promise<any[]> {\n const provider =\n loadBalancer.provider || loadBalancer.cloudProvider || loadBalancer.type || loadBalancerParams.provider;\n const region = loadBalancer.region || loadBalancerParams.region;\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer(loadBalancer)) {\n const detailSets = await Promise.all(\n (loadBalancer.listeners || []).map((listener: any) =>\n loadBalancerReader.getLoadBalancerDetails(\n provider,\n loadBalancerParams.accountId,\n region,\n listener.name || listener,\n ),\n ),\n );\n const loadBalancers = ([] as any[]).concat(...detailSets);\n const representativeLoadBalancer = loadBalancers[0];\n\n if (!representativeLoadBalancer) {\n return [];\n }\n\n representativeLoadBalancer.dns = uniqBy(\n loadBalancers\n .map((detail: any) => ({ dnsname: detail.dnsname, protocol: getProtocol(detail) }))\n .filter((detail: any) => detail.dnsname),\n (detail: any) => detail.dnsname,\n );\n representativeLoadBalancer.listenerDescriptions = ([] as any[]).concat(\n ...loadBalancers.map((detail: any) => detail.listenerDescriptions || []),\n );\n return [representativeLoadBalancer];\n }\n\n const details = await loadBalancerReader.getLoadBalancerDetails(\n provider,\n loadBalancerParams.accountId,\n region,\n loadBalancer.name,\n );\n if (details[0]) {\n details[0].dns = { dnsname: details[0].dnsname, protocol: getProtocol(details[0]) };\n }\n return details;\n}\n\nexport async function loadGceLoadBalancerDetails({\n accountService = AccountService,\n app,\n autoClose,\n loadBalancers,\n loadBalancerParams,\n loadBalancerReader,\n}: ILoadGceLoadBalancerDetailsProps): Promise<any | undefined> {\n const loadBalancer = findLoadBalancerInList(loadBalancers || app?.loadBalancers?.data || [], loadBalancerParams);\n\n if (!loadBalancer) {\n autoClose();\n return undefined;\n }\n\n const details = await loadDetails(loadBalancer, loadBalancerParams, loadBalancerReader);\n const filtered = details.filter((detail: any) => (detail.vpcid || null) === (loadBalancerParams.vpcId || null));\n if (filtered.length) {\n loadBalancer.elb = filtered[0];\n loadBalancer.account = loadBalancerParams.accountId;\n\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer(loadBalancer)) {\n loadBalancer.elb.backendServices = getBackendServices(loadBalancer);\n loadBalancer.elb.healthChecks = uniqBy(\n loadBalancer.elb.backendServices.map((backendService: any) => backendService.healthCheck).filter(Boolean),\n (healthCheck: any) => healthCheck.name || healthCheck.selfLink || '',\n );\n }\n }\n\n const accountDetails: any = await accountService.getAccountDetails(loadBalancerParams.accountId);\n if (accountDetails?.project) {\n loadBalancer.project = accountDetails.project;\n loadBalancer.logsLink = buildLogsLink(accountDetails.project, loadBalancer);\n }\n\n return loadBalancer;\n}\n\nexport function useGceLoadBalancerDetails({ app, autoClose, loadBalancerParams }: IUseDetailsProps): any {\n const { loadBalancerReader } = useDeckRuntimeServices();\n const dataSource = app.getDataSource('loadBalancers');\n const { data: loadBalancers, loaded, refresh, error } = useDataSource<any[]>(dataSource);\n const [data, setData] = useState<any>();\n const [loadingDetails, setLoadingDetails] = useState(false);\n const [detailsError, setDetailsError] = useState<string | null>(null);\n\n const refetch = useCallback(async () => {\n if (!loaded || error) {\n return;\n }\n\n setLoadingDetails(true);\n setDetailsError(null);\n try {\n setData(\n await loadGceLoadBalancerDetails({\n app,\n autoClose,\n loadBalancers,\n loadBalancerParams,\n loadBalancerReader,\n }),\n );\n } catch (e) {\n setDetailsError(e?.message || String(e));\n } finally {\n setLoadingDetails(false);\n }\n }, [app, autoClose, error, loadBalancerReader, loadBalancers, loadBalancerParams, loaded]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n return {\n data,\n error: error || detailsError,\n loading: !loaded || loadingDetails,\n refetch: async () => {\n refresh();\n },\n };\n}\n\nfunction deleteGceHttpLoadBalancer(loadBalancer: any, app: any, params: any = {}): Promise<any> {\n const region = loadBalancer.region || 'global';\n const job = {\n cloudProvider: loadBalancer.provider || 'gce',\n credentials: loadBalancer.account,\n loadBalancerName: loadBalancer.listeners?.[0]?.name || loadBalancer.name,\n loadBalancerType: loadBalancer.loadBalancerType,\n region,\n regions: [region],\n type: 'deleteLoadBalancer',\n ...params,\n };\n\n InfrastructureCaches.clearCache('backendServices');\n InfrastructureCaches.clearCache('healthChecks');\n\n return TaskExecutor.executeTask({\n application: app,\n description: `Delete load balancer: ${loadBalancer.urlMapName || loadBalancer.name} in ${\n loadBalancer.account\n }:global`,\n job: [job],\n });\n}\n\nfunction deleteGceLoadBalancer(loadBalancer: any, app: any, params: any = {}): Promise<any> {\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer(loadBalancer)) {\n return deleteGceHttpLoadBalancer(loadBalancer, app, params);\n }\n\n const region = loadBalancer.region || 'global';\n return LoadBalancerWriter.deleteLoadBalancer(\n {\n accountName: loadBalancer.account,\n cloudProvider: 'gce',\n credentials: loadBalancer.account,\n deleteHealthChecks: false,\n loadBalancerName: loadBalancer.name,\n loadBalancerType: loadBalancer.loadBalancerType || 'NETWORK',\n region,\n regions: [region],\n vpcId: loadBalancer.vpcId,\n ...params,\n },\n app,\n );\n}\n\nfunction GceLoadBalancerDeleteOptions({\n deleteParams,\n loadBalancer,\n}: {\n deleteParams: { deleteHealthChecks: boolean };\n loadBalancer: any;\n}): JSX.Element {\n const hasHealthChecks = gceHttpLoadBalancerUtils.isHttpLoadBalancer(loadBalancer) || !!loadBalancer.healthCheck;\n if (!hasHealthChecks) {\n return null;\n }\n\n return (\n <label className=\"checkbox-inline\">\n <input\n type=\"checkbox\"\n onChange={(event) => {\n deleteParams.deleteHealthChecks = event.currentTarget.checked;\n }}\n />\n Delete associated health checks\n </label>\n );\n}\n\nexport function GceLoadBalancerActions({ app, loadBalancer }: { app: any; loadBalancer: any }): JSX.Element {\n if (CloudProviderRegistry.isDisabled('gce')) {\n return null;\n }\n\n const hasInstances = (loadBalancer.instances || []).length > 0;\n const editLoadBalancer = () => {\n GceLoadBalancerChoiceModal.show({\n app,\n application: app,\n forPipelineConfig: false,\n isNew: false,\n loadBalancer,\n mode: 'edit',\n } as any);\n };\n const deleteLoadBalancer = () => {\n const deleteParams = { deleteHealthChecks: false };\n ConfirmationModalService.confirm({\n account: loadBalancer.account,\n bodyContent: <GceLoadBalancerDeleteOptions deleteParams={deleteParams} loadBalancer={loadBalancer} />,\n buttonText: `Delete ${loadBalancer.name}`,\n header: `Really delete ${loadBalancer.name}?`,\n submitMethod: (params: any = {}) =>\n deleteGceLoadBalancer(loadBalancer, app, { deleteHealthChecks: deleteParams.deleteHealthChecks, ...params }),\n taskMonitorConfig: { application: app, title: `Deleting ${loadBalancer.name}` },\n });\n };\n\n return (\n <div className=\"dropdown\" id=\"gce-load-balancer-actions-dropdown\">\n <button className=\"btn btn-sm btn-primary dropdown-toggle\" data-toggle=\"dropdown\" type=\"button\">\n Load Balancer Actions\n </button>\n <ul className=\"dropdown-menu\">\n <ManagedMenuItem application={app} resource={loadBalancer} onClick={editLoadBalancer}>\n Edit Load Balancer\n </ManagedMenuItem>\n {!hasInstances && (\n <ManagedMenuItem application={app} resource={loadBalancer} onClick={deleteLoadBalancer}>\n Delete Load Balancer\n </ManagedMenuItem>\n )}\n {hasInstances && (\n <li className=\"disabled\" title=\"You must detach all instances before deleting this load balancer.\">\n <a>Delete Load Balancer</a>\n </li>\n )}\n </ul>\n </div>\n );\n}\n\nexport function GceLoadBalancerInformationSection({ loadBalancer }: { app: any; loadBalancer: any }): JSX.Element {\n return (\n <CollapsibleSection heading=\"Load Balancer Information\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Account</dt>\n <dd>\n <AccountTag account={loadBalancer.account} />\n </dd>\n <dt>Region</dt>\n <dd>{loadBalancer.region || 'global'}</dd>\n <dt>Type</dt>\n <dd>{loadBalancer.loadBalancerType || loadBalancer.providerType || '-'}</dd>\n {loadBalancer.project && (\n <>\n <dt>Project</dt>\n <dd>{loadBalancer.project}</dd>\n </>\n )}\n {loadBalancer.elb?.dns && (\n <>\n <dt>DNS</dt>\n <dd>\n {Array.isArray(loadBalancer.elb.dns)\n ? loadBalancer.elb.dns.map((dns: any) => `${dns.protocol}//${dns.dnsname}`).join(', ')\n : `${loadBalancer.elb.dns.protocol}//${loadBalancer.elb.dns.dnsname}`}\n </dd>\n </>\n )}\n </dl>\n </CollapsibleSection>\n );\n}\n\nexport function GceLoadBalancerListenersSection({ loadBalancer }: { app: any; loadBalancer: any }): JSX.Element {\n return (\n <CollapsibleSection heading=\"Listeners\" defaultExpanded={true}>\n {(loadBalancer.listeners || []).length ? (\n <ul>\n {loadBalancer.listeners.map((listener: any, index: number) => (\n <li key={index}>{[listener.protocol, listener.port || listener.portRange].filter(Boolean).join(':')}</li>\n ))}\n </ul>\n ) : (\n <span>No listeners configured</span>\n )}\n </CollapsibleSection>\n );\n}\n\nexport function GceLoadBalancerBackendServicesSection({ loadBalancer }: { app: any; loadBalancer: any }): JSX.Element {\n const backendServices = loadBalancer.elb?.backendServices || [];\n const healthChecks = loadBalancer.elb?.healthChecks || [];\n\n if (!backendServices.length && !healthChecks.length) {\n return null;\n }\n\n return (\n <CollapsibleSection heading=\"Backend Services\" defaultExpanded={true}>\n {backendServices.length > 0 && (\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Services</dt>\n <dd>{backendServices.map((backendService: any) => backendService.name).join(', ')}</dd>\n </dl>\n )}\n {healthChecks.length > 0 && (\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Health Checks</dt>\n <dd>{healthChecks.map((healthCheck: any) => healthCheck.name).join(', ')}</dd>\n </dl>\n )}\n </CollapsibleSection>\n );\n}\n\nexport function GceLoadBalancerLogsSection({ loadBalancer }: { app: any; loadBalancer: any }): JSX.Element {\n return (\n <CollapsibleSection heading=\"Logs\" defaultExpanded={false}>\n {loadBalancer.logsLink ? (\n <a href={loadBalancer.logsLink} target=\"_blank\" rel=\"noopener noreferrer\">\n View Google Cloud logs\n </a>\n ) : (\n <span>No log link available</span>\n )}\n </CollapsibleSection>\n );\n}\n\nexport const gceLoadBalancerDetailsSections = [\n GceLoadBalancerInformationSection,\n GceLoadBalancerListenersSection,\n GceLoadBalancerBackendServicesSection,\n GceLoadBalancerLogsSection,\n];\n","import { cloneDeep, groupBy, map, partition } from 'lodash';\n\nimport type { IGceHttpLoadBalancer, IGceLoadBalancer } from '../domain/loadBalancer';\n\nimport { GceHttpLoadBalancerUtils } from './httpLoadBalancerUtils.service';\n\nexport class GceLoadBalancerSetTransformer {\n private readonly gceHttpLoadBalancerUtils = new GceHttpLoadBalancerUtils();\n\n private static normalizeHttpLoadBalancerGroup(group: IGceHttpLoadBalancer[]): IGceHttpLoadBalancer {\n const normalized = cloneDeep(group[0]);\n\n normalized.listeners = group.map((loadBalancer) => {\n const port = loadBalancer.portRange ? GceLoadBalancerSetTransformer.parsePortRange(loadBalancer.portRange) : null;\n return {\n port,\n name: loadBalancer.name,\n certificate: loadBalancer.certificate,\n certificateMap: loadBalancer.certificateMap,\n ipAddress: loadBalancer.ipAddress,\n subnet: loadBalancer.subnet,\n };\n });\n\n normalized.name = normalized.urlMapName;\n delete normalized.subnet;\n return normalized;\n }\n\n private static parsePortRange(portRange: string): string {\n return portRange.split('-')[0];\n }\n\n public normalizeLoadBalancerSet = (loadBalancers: IGceLoadBalancer[]): IGceLoadBalancer[] => {\n const [httpLoadBalancers, otherLoadBalancers] = partition(loadBalancers, (lb) =>\n this.gceHttpLoadBalancerUtils.isHttpLoadBalancer(lb),\n );\n\n const groupedByUrlMap = groupBy(httpLoadBalancers, 'urlMapName');\n const normalizedElSevenLoadBalancers = map(\n groupedByUrlMap,\n GceLoadBalancerSetTransformer.normalizeHttpLoadBalancerGroup,\n );\n\n return (normalizedElSevenLoadBalancers as IGceLoadBalancer[]).concat(otherLoadBalancers);\n };\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { GCEProviderSettings } from '../gce.settings';\n\nexport class GceLoadBalancerTransformer {\n constructor(promiseService) {\n function updateHealthCounts(container) {\n const instances = container.instances;\n const serverGroups = container.serverGroups || [container];\n container.instanceCounts = {\n up: instances.filter((instance) => {\n return instance.health[0].state === 'InService';\n }).length,\n down: instances.filter((instance) => {\n return instance.health[0].state === 'OutOfService';\n }).length,\n outOfService: serverGroups.reduce((acc, serverGroup) => {\n return (\n serverGroup.instances.filter((instance) => {\n return instance.healthState === 'OutOfService';\n }).length + acc\n );\n }, 0),\n };\n }\n\n function transformInstance(instance, loadBalancer) {\n instance.health = instance.health || {};\n instance.provider = loadBalancer.type;\n instance.account = loadBalancer.account;\n instance.region = loadBalancer.region;\n instance.health.type = 'LoadBalancer';\n instance.healthState = instance.health.state\n ? instance.health.state === 'InService'\n ? 'Up'\n : 'Down'\n : 'OutOfService';\n instance.health = [instance.health];\n instance.loadBalancers = [loadBalancer.name];\n }\n\n function normalizeLoadBalancer(loadBalancer) {\n loadBalancer.serverGroups.forEach(function (serverGroup) {\n serverGroup.account = loadBalancer.account;\n if (serverGroup.detachedInstances) {\n serverGroup.detachedInstances = serverGroup.detachedInstances.map(function (instanceId) {\n return { id: instanceId };\n });\n serverGroup.instances = serverGroup.instances.concat(serverGroup.detachedInstances);\n } else {\n serverGroup.detachedInstances = [];\n }\n\n serverGroup.instances.forEach(function (instance) {\n transformInstance(instance, loadBalancer);\n });\n updateHealthCounts(serverGroup);\n });\n const activeServerGroups = _.filter(loadBalancer.serverGroups, { isDisabled: false });\n loadBalancer.provider = loadBalancer.type;\n loadBalancer.instances = _.chain(activeServerGroups).map('instances').flatten().value();\n loadBalancer.detachedInstances = _.chain(activeServerGroups).map('detachedInstances').flatten().value();\n if (_.get(loadBalancer, 'backendService.healthCheck')) {\n loadBalancer.backendService.healthCheck.timeout = loadBalancer.backendService.healthCheck.timeoutSec;\n loadBalancer.backendService.healthCheck.interval = loadBalancer.backendService.healthCheck.checkIntervalSec;\n }\n updateHealthCounts(loadBalancer);\n return promiseService.resolve(loadBalancer);\n }\n\n function convertLoadBalancerForEditing(loadBalancer) {\n const toEdit = {\n provider: 'gce',\n region: loadBalancer.region,\n credentials: loadBalancer.account,\n listeners: [],\n name: loadBalancer.name,\n regionZones: loadBalancer.availabilityZones,\n };\n\n if (loadBalancer.elb) {\n const elb = loadBalancer.elb;\n\n toEdit.vpcId = elb.vpcid;\n\n if (elb.listenerDescriptions) {\n toEdit.listeners = elb.listenerDescriptions.map(function (description) {\n const listener = description.listener;\n return {\n protocol: listener.protocol,\n portRange: listener.loadBalancerPort,\n healthCheck: elb.healthCheck !== undefined,\n };\n });\n }\n\n if (elb.healthCheck && elb.healthCheck.target) {\n toEdit.healthTimeout = elb.healthCheck.timeout;\n toEdit.healthInterval = elb.healthCheck.interval;\n toEdit.healthyThreshold = elb.healthCheck.healthyThreshold;\n toEdit.unhealthyThreshold = elb.healthCheck.unhealthyThreshold;\n\n const healthCheck = loadBalancer.elb.healthCheck.target;\n const protocolIndex = healthCheck.indexOf(':');\n const pathIndex = healthCheck.indexOf('/');\n\n if (protocolIndex !== -1 && pathIndex !== -1) {\n toEdit.healthCheckProtocol = healthCheck.substring(0, protocolIndex);\n toEdit.healthCheckPort = healthCheck.substring(protocolIndex + 1, pathIndex);\n toEdit.healthCheckPath = healthCheck.substring(pathIndex);\n if (!isNaN(toEdit.healthCheckPort)) {\n toEdit.healthCheckPort = Number(toEdit.healthCheckPort);\n }\n }\n } else {\n toEdit.healthCheckProtocol = 'HTTP';\n toEdit.healthCheckPort = 80;\n toEdit.healthCheckPath = '/';\n toEdit.healthTimeout = 5;\n toEdit.healthInterval = 10;\n toEdit.healthyThreshold = 10;\n toEdit.unhealthyThreshold = 2;\n }\n\n toEdit.sessionAffinity = loadBalancer.sessionAffinity || 'None';\n }\n return toEdit;\n }\n\n function constructNewLoadBalancerTemplate() {\n return {\n provider: 'gce',\n stack: '',\n detail: '',\n credentials: GCEProviderSettings.defaults.account,\n region: GCEProviderSettings.defaults.region,\n healthCheckProtocol: 'HTTP',\n healthCheckPort: 80,\n healthCheckPath: '/',\n healthTimeout: 5,\n healthInterval: 10,\n healthyThreshold: 10,\n unhealthyThreshold: 2,\n sessionAffinity: 'NONE',\n regionZones: [],\n listeners: [\n {\n protocol: 'TCP',\n portRange: '8080',\n healthCheck: true,\n },\n ],\n };\n }\n\n return {\n normalizeLoadBalancer: normalizeLoadBalancer,\n convertLoadBalancerForEditing: convertLoadBalancerForEditing,\n constructNewLoadBalancerTemplate: constructNewLoadBalancerTemplate,\n };\n }\n}\n","export default \"gce.logo2ae85d8704b1d6b8.png\"","import React from 'react';\n\nimport {\n ArtifactReferenceService,\n AuthenticationService,\n BakeExecutionLabel,\n BakeryReader,\n ExecutionArtifactTab,\n ExecutionDetailsSection,\n ExecutionDetailsTasks,\n ExpectedArtifactService,\n MapEditor,\n Registry,\n SETTINGS,\n StageConfigField,\n StageFailureMessage,\n} from '@spinnaker/core';\n\nconst h = React.createElement;\n\nfunction updateStage(stage, updateStage, changes) {\n updateStage({ ...stage, ...changes });\n}\n\nfunction showAdvanced(stage) {\n return !!(\n stage.templateFileName ||\n (stage.extendedAttributes && Object.keys(stage.extendedAttributes).length) ||\n stage.varFileName ||\n stage.baseAmi ||\n stage.accountName\n );\n}\n\nclass GceBakeStageConfig extends React.Component {\n state = {\n baseLabelOptions: [],\n baseOsOptions: [],\n roscoMode: false,\n showAdvancedOptions: showAdvanced(this.props.stage),\n };\n\n componentDidMount() {\n const { stage, updateStage: update } = this.props;\n stage.extendedAttributes = stage.extendedAttributes || {};\n stage.region = 'global';\n stage.cloudProvider = stage.cloudProvider || 'gce';\n stage.user = stage.user || AuthenticationService.getAuthenticatedUser().name;\n\n Promise.all([BakeryReader.getBaseOsOptions('gce'), BakeryReader.getBaseLabelOptions()]).then(\n ([baseOsOptions, baseLabelOptions]) => {\n const baseImages = baseOsOptions?.baseImages || [];\n const changes = {};\n if (!stage.baseOs && baseImages.length) {\n changes.baseOs = baseImages[0].id;\n }\n if (!stage.baseLabel && baseLabelOptions?.length) {\n changes.baseLabel = baseLabelOptions[0];\n }\n if (Object.keys(changes).length) {\n update({ ...stage, ...changes });\n }\n this.setState({\n baseLabelOptions: baseLabelOptions || [],\n baseOsOptions: baseImages,\n roscoMode:\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector(stage)),\n showAdvancedOptions: showAdvanced({ ...stage, ...changes }),\n });\n },\n );\n }\n\n renderArtifactSelector() {\n const { pipeline, stage, updateStage: update } = this.props;\n const expectedArtifacts = ExpectedArtifactService.getExpectedArtifactsAvailableToStage(stage, pipeline);\n const packageArtifactIds = stage.packageArtifactIds || [];\n\n return h(\n StageConfigField,\n { label: 'Package Artifacts' },\n h(\n 'select',\n {\n className: 'form-control input-sm',\n multiple: true,\n value: packageArtifactIds,\n onChange: (e) => {\n const selected = Array.from(e.target.selectedOptions).map((option) => option.value);\n updateStage(stage, update, { packageArtifactIds: selected });\n },\n },\n expectedArtifacts.map((artifact) =>\n h('option', { key: artifact.id, value: artifact.id }, artifact.displayName || artifact.id),\n ),\n ),\n );\n }\n\n renderAdvancedOptions() {\n const { stage, updateStage: update } = this.props;\n if (!this.state.showAdvancedOptions) {\n return null;\n }\n\n return h(\n React.Fragment,\n null,\n h(\n StageConfigField,\n { label: 'Template File Name' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.templateFileName || '',\n onChange: (e) => updateStage(stage, update, { templateFileName: e.target.value }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Account Name' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.accountName || '',\n onChange: (e) => updateStage(stage, update, { accountName: e.target.value }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Extended Attributes' },\n h(MapEditor, {\n allowEmpty: true,\n model: stage.extendedAttributes || {},\n onChange: (extendedAttributes) => updateStage(stage, update, { extendedAttributes }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Var File Name' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.varFileName || '',\n onChange: (e) => updateStage(stage, update, { varFileName: e.target.value }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Base Image' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.baseAmi || '',\n onChange: (e) => updateStage(stage, update, { baseAmi: e.target.value }),\n }),\n ),\n );\n }\n\n render() {\n const { stage, updateStage: update } = this.props;\n stage.extendedAttributes = stage.extendedAttributes || {};\n stage.region = 'global';\n stage.cloudProvider = stage.cloudProvider || 'gce';\n stage.user = stage.user || AuthenticationService.getAuthenticatedUser().name;\n\n return h(\n 'div',\n null,\n h(\n StageConfigField,\n { label: 'Package' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.package || '',\n onChange: (e) => updateStage(stage, update, { package: e.target.value }),\n }),\n ),\n this.renderArtifactSelector(),\n h('hr'),\n h(\n StageConfigField,\n { label: 'Base OS' },\n h(\n 'select',\n {\n className: 'form-control input-sm',\n value: stage.baseOs || '',\n onChange: (e) => updateStage(stage, update, { baseOs: e.target.value }),\n },\n this.state.baseOsOptions.map((option) =>\n h(\n 'option',\n { key: option.id, value: option.id },\n option.displayName || option.shortDescription || option.id,\n ),\n ),\n ),\n ),\n h(\n StageConfigField,\n { label: 'Base Label' },\n this.state.baseLabelOptions.map((baseLabel) =>\n h(\n 'label',\n { className: 'radio-inline', key: baseLabel },\n h('input', {\n checked: stage.baseLabel === baseLabel,\n type: 'radio',\n onChange: () => updateStage(stage, update, { baseLabel }),\n }),\n ` ${baseLabel}`,\n ),\n ),\n ),\n h('hr'),\n (this.state.roscoMode || stage.rebake) &&\n h(\n StageConfigField,\n { label: 'Rebake' },\n h(\n 'div',\n { className: 'checkbox', style: { marginBottom: 0 } },\n h(\n 'label',\n null,\n h('input', {\n checked: !!stage.rebake,\n type: 'checkbox',\n onChange: (e) => updateStage(stage, update, { rebake: e.target.checked }),\n }),\n ' Rebake image without regard to the status of any existing bake',\n ),\n ),\n ),\n h(\n 'div',\n { className: 'form-group' },\n h(\n 'div',\n { className: 'col-md-9 col-md-offset-1' },\n h(\n 'div',\n { className: 'checkbox' },\n h(\n 'label',\n null,\n h('input', {\n checked: this.state.showAdvancedOptions,\n type: 'checkbox',\n onChange: (e) => this.setState({ showAdvancedOptions: e.target.checked }),\n }),\n h('strong', null, ' Show Advanced Options'),\n ),\n ),\n ),\n ),\n this.renderAdvancedOptions(),\n );\n }\n}\n\nfunction valueForPath(source, path) {\n const value = path.split('.').reduce((acc, key) => acc?.[key], source);\n return value == null ? '' : String(value);\n}\n\nexport function interpolatedBakeDetailUrl(stage) {\n const context = stage.context || {};\n const roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector(context));\n const template = (roscoMode && SETTINGS.roscoDetailUrl ? SETTINGS.roscoDetailUrl : SETTINGS.bakeryDetailUrl) || '';\n const source = { context };\n\n return template.replace(/\\{\\{\\s*([^}]+?)\\s*\\}\\}/g, (_match, path) => valueForPath(source, path));\n}\n\nfunction GceBakeExecutionDetails(props) {\n const { current, execution, stage } = props;\n const context = stage.context || {};\n const roscoMode =\n SETTINGS.feature.roscoMode ||\n (typeof SETTINGS.feature.roscoSelector === 'function' && SETTINGS.feature.roscoSelector(context));\n const bakeDetailUrl = interpolatedBakeDetailUrl(stage);\n\n return h(\n ExecutionDetailsSection,\n { name: props.name, current },\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-6' },\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal' },\n h('dt', null, 'Image'),\n h('dd', null, context.ami),\n h('dt', null, 'Region'),\n h('dd', null, context.region),\n h('dt', null, 'Package'),\n h('dd', null, context.package),\n ),\n ),\n h(\n 'div',\n { className: 'col-md-6' },\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal' },\n h('dt', null, 'Base OS'),\n h('dd', null, context.baseOs),\n h('dt', null, 'Label'),\n h('dd', null, context.baseLabel),\n (roscoMode || execution.trigger?.rebake || context.rebake) && h('dt', null, 'Rebake'),\n (roscoMode || execution.trigger?.rebake || context.rebake) &&\n h('dd', null, String(execution.trigger?.rebake || context.rebake || false)),\n context.templateFileName && h('dt', null, 'Template'),\n context.templateFileName && h('dd', null, context.templateFileName),\n context.accountName && h('dt', null, 'Account Name'),\n context.accountName && h('dd', null, context.accountName),\n context.varFileName && h('dt', null, 'Var File'),\n context.varFileName && h('dd', null, context.varFileName),\n ),\n ),\n ),\n h(StageFailureMessage, { stage, message: stage.failureMessage }),\n context.region &&\n context.status?.resourceId &&\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-12' },\n h(\n 'div',\n { className: `alert alert-${stage.isFailed ? 'danger' : 'info'}` },\n context.previouslyBaked && h('div', null, 'No changes detected; reused existing bake'),\n bakeDetailUrl &&\n h('a', { target: '_blank', rel: 'noopener noreferrer', href: bakeDetailUrl }, 'View Bakery Details'),\n context.imageName &&\n h('div', null, h('strong', null, 'Image:'), h('div', { className: 'break-word' }, context.imageName)),\n ),\n ),\n ),\n );\n}\nGceBakeExecutionDetails.title = 'bakeConfig';\n\nexport function registerGceBakeStage() {\n Registry.pipeline.registerStage({\n provides: 'bake',\n cloudProvider: 'gce',\n label: 'Bake',\n description: 'Bakes an image',\n component: GceBakeStageConfig,\n executionDetailsSections: [GceBakeExecutionDetails, ExecutionDetailsTasks, ExecutionArtifactTab],\n executionLabelComponent: BakeExecutionLabel,\n extraLabelLines: (stage) => {\n return stage.masterStage.context.allPreviouslyBaked || stage.masterStage.context.somePreviouslyBaked ? 1 : 0;\n },\n producesArtifacts: true,\n supportsCustomTimeout: true,\n validators: [\n {\n type: 'anyFieldRequired',\n fields: [\n { fieldName: 'package', fieldLabel: 'Package' },\n { fieldName: 'packageArtifactIds', fieldLabel: 'Package Artifacts' },\n ],\n },\n ],\n restartable: true,\n artifactExtractor: ExpectedArtifactService.accumulateArtifacts(['packageArtifactIds']),\n artifactRemover: ArtifactReferenceService.removeArtifactFromFields(['packageArtifactIds']),\n });\n}\n","import React from 'react';\n\nimport {\n AccountRegionClusterSelector,\n AccountService,\n DeploymentStrategySelector,\n NameUtils,\n StageConfigField,\n StageConstants,\n TargetSelect,\n} from '@spinnaker/core';\n\nconst h = React.createElement;\n\nexport const gceSelectionStrategies = [\n {\n label: 'Largest',\n val: 'LARGEST',\n description: 'When multiple server groups exist, prefer the server group with the most instances',\n },\n { label: 'Newest', val: 'NEWEST', description: 'When multiple server groups exist, prefer the newest' },\n { label: 'Oldest', val: 'OLDEST', description: 'When multiple server groups exist, prefer the oldest' },\n { label: 'Fail', val: 'FAIL', description: 'When multiple server groups exist, fail' },\n];\n\nconst scaleActions = [\n { label: 'Scale Up', val: 'scale_up' },\n { label: 'Scale Down', val: 'scale_down' },\n { label: 'Scale to Cluster Size', val: 'scale_to_cluster' },\n { label: 'Scale to Exact Size', val: 'scale_exact' },\n];\n\nconst resizeTypes = [\n { label: 'Percentage', val: 'pct' },\n { label: 'Incremental', val: 'incr' },\n];\n\nfunction setDefault(stage, key, value) {\n if (stage[key] === undefined || stage[key] === null) {\n stage[key] = value;\n }\n}\n\nexport function initializeGceStage(stage, application, defaults = {}) {\n setDefault(stage, 'cloudProvider', 'gce');\n setDefault(stage, 'cloudProviderType', 'gce');\n setDefault(stage, 'credentials', application?.defaultCredentials?.gce);\n stage.regions = stage.regions || [];\n if (!stage.regions.length && application?.defaultRegions?.gce) {\n stage.regions.push(application.defaultRegions.gce);\n }\n Object.keys(defaults).forEach((key) => setDefault(stage, key, defaults[key]));\n if (\n stage.isNew &&\n application?.attributes?.platformHealthOnlyShowOverride &&\n application.attributes.platformHealthOnly\n ) {\n stage.interestingHealthProviderNames = ['Google'];\n }\n}\n\nfunction replaceStage(props, stage) {\n props.updateStage({ ...stage });\n}\n\nfunction updateStage(props, changes) {\n replaceStage(props, { ...props.stage, ...changes });\n}\n\nfunction parseNumber(value) {\n return value === '' ? undefined : Number(value);\n}\n\nfunction pluralize(label, value) {\n return Number(value) === 1 ? label : `${label}s`;\n}\n\nfunction TextInput({ value, onChange, type = 'text', disabled = false }) {\n return h('input', {\n className: 'form-control input-sm',\n disabled,\n type,\n value: value ?? '',\n onChange: (e) => onChange(e.target.value),\n });\n}\n\nfunction NumberInput({ value, onChange, disabled = false, style = undefined }) {\n return h('input', {\n className: 'form-control input-sm',\n disabled,\n min: 0,\n style,\n type: 'number',\n value: value ?? '',\n onChange: (e) => onChange(parseNumber(e.target.value)),\n });\n}\n\nfunction SelectInput({ value, onChange, options }) {\n return h(\n 'select',\n { className: 'form-control input-sm', value: value ?? '', onChange: (e) => onChange(e.target.value) },\n h('option', { value: '' }, 'Select...'),\n options.map((option) =>\n h('option', { key: option.val || option.name, value: option.val || option.name }, option.label || option.name),\n ),\n );\n}\n\nfunction InlineSelectInput({ value, onChange, options, style }) {\n return h(\n 'select',\n { className: 'form-control input-sm', style, value: value ?? '', onChange: (e) => onChange(e.target.value) },\n options.map((option) => h('option', { key: option.val, value: option.val }, option.label)),\n );\n}\n\nfunction CapacityFields({ capacity = {}, disabled = false, onChange }) {\n const updateCapacity = (field, value) => onChange({ ...capacity, [field]: value });\n return h(\n React.Fragment,\n null,\n h(\n 'div',\n { className: 'form-group' },\n h('div', { className: 'col-md-2 col-md-offset-3' }, 'Min'),\n h('div', { className: 'col-md-2' }, 'Max'),\n h('div', { className: 'col-md-2' }, 'Desired'),\n ),\n h(\n 'div',\n { className: 'form-group' },\n h(\n 'div',\n { className: 'col-md-2 col-md-offset-3' },\n h(NumberInput, { disabled, value: capacity.min, onChange: (value) => updateCapacity('min', value) }),\n ),\n h(\n 'div',\n { className: 'col-md-2' },\n h(NumberInput, { disabled, value: capacity.max, onChange: (value) => updateCapacity('max', value) }),\n ),\n h(\n 'div',\n { className: 'col-md-2' },\n h(NumberInput, { disabled, value: capacity.desired, onChange: (value) => updateCapacity('desired', value) }),\n ),\n ),\n );\n}\n\nfunction GcePlatformHealthOverride({ application, stage, updateStage: update }) {\n if (!application?.attributes?.platformHealthOnlyShowOverride) {\n return null;\n }\n\n const checked =\n Array.isArray(stage.interestingHealthProviderNames) && stage.interestingHealthProviderNames[0] === 'Google';\n\n return h(\n StageConfigField,\n { label: 'Task Completion' },\n h(\n 'div',\n { className: 'checkbox' },\n h(\n 'label',\n null,\n h('input', {\n checked,\n type: 'checkbox',\n onChange: (e) =>\n update({ ...stage, interestingHealthProviderNames: e.target.checked ? ['Google'] : undefined }),\n }),\n ' Consider only Google health',\n ),\n ),\n );\n}\n\nclass GceBaseStageConfig extends React.Component {\n state = { accounts: [] };\n\n componentDidMount() {\n AccountService.listAccounts('gce').then((accounts) => this.setState({ accounts }));\n }\n\n renderAccountRegionClusterSelector(options = {}) {\n const { application, pipeline, stage } = this.props;\n if (pipeline?.strategy) {\n return null;\n }\n\n return h(AccountRegionClusterSelector, {\n accounts: this.state.accounts,\n application,\n clusterField: options.clusterField,\n component: stage,\n singleRegion: options.singleRegion,\n });\n }\n\n renderTargetSelect(options = StageConstants.TARGET_LIST) {\n return h(\n StageConfigField,\n { label: 'Target' },\n h(TargetSelect, { model: this.props.stage, options, onChange: (target) => updateStage(this.props, { target }) }),\n );\n }\n\n renderDeploymentStrategySelector() {\n return h(DeploymentStrategySelector, {\n command: this.props.stage,\n fieldColumns: '6',\n onFieldChange: (key, value) => updateStage(this.props, { [key]: value }),\n onStrategyChange: (command) => replaceStage(this.props, command),\n });\n }\n}\n\nexport class GceTargetServerGroupStageConfig extends GceBaseStageConfig {\n render() {\n const { application, stage, showHealthOverride = false } = this.props;\n initializeGceStage(stage, application, { target: StageConstants.TARGET_LIST[0].val });\n return h(\n 'div',\n null,\n this.renderAccountRegionClusterSelector(),\n this.renderTargetSelect(),\n showHealthOverride &&\n h(GcePlatformHealthOverride, {\n application,\n stage,\n updateStage: (nextStage) => replaceStage(this.props, nextStage),\n }),\n );\n }\n}\n\nexport function GceDisableAsgStageConfig(props) {\n return h(GceTargetServerGroupStageConfig, { ...props, showHealthOverride: true });\n}\n\nexport function GceEnableAsgStageConfig(props) {\n return h(GceTargetServerGroupStageConfig, { ...props, showHealthOverride: true });\n}\n\nfunction syncTargetClusterFields(stage) {\n if (stage.targetCluster) {\n const clusterName = NameUtils.parseServerGroupName(stage.targetCluster);\n stage.stack = clusterName.stack;\n stage.freeFormDetails = clusterName.freeFormDetails;\n } else {\n stage.stack = '';\n stage.freeFormDetails = '';\n }\n}\n\nexport class GceCloneServerGroupStageConfig extends GceBaseStageConfig {\n render() {\n const { application, stage } = this.props;\n initializeGceStage(stage, application, { target: StageConstants.TARGET_LIST[0].val });\n setDefault(stage, 'application', application?.name);\n setDefault(stage, 'useSourceCapacity', true);\n syncTargetClusterFields(stage);\n\n const updateCapacity = (capacity) => updateStage(this.props, { capacity, useSourceCapacity: false });\n const useSourceCapacity = () => {\n const nextStage = { ...stage, useSourceCapacity: true };\n delete nextStage.capacity;\n replaceStage(this.props, nextStage);\n };\n\n return h(\n 'div',\n null,\n this.renderAccountRegionClusterSelector({ clusterField: 'targetCluster', singleRegion: true }),\n this.renderTargetSelect(),\n h(\n 'div',\n null,\n h(\n 'div',\n { className: 'form-group' },\n h('div', { className: 'col-md-3 sm-label-right' }, 'Capacity'),\n h(\n 'div',\n { className: 'col-md-9 radio' },\n h(\n 'label',\n null,\n h('input', { checked: stage.useSourceCapacity === true, type: 'radio', onChange: useSourceCapacity }),\n ' Copy the capacity from the current server group',\n ),\n ),\n h(\n 'div',\n { className: 'col-md-9 col-md-offset-3 radio' },\n h(\n 'label',\n null,\n h('input', {\n checked: stage.useSourceCapacity === false,\n type: 'radio',\n onChange: () => updateStage(this.props, { capacity: stage.capacity || {}, useSourceCapacity: false }),\n }),\n ' Let me specify the capacity',\n ),\n ),\n ),\n h(CapacityFields, { capacity: stage.capacity, disabled: stage.useSourceCapacity, onChange: updateCapacity }),\n ),\n h(\n StageConfigField,\n { label: 'Traffic' },\n h(\n 'div',\n { className: 'checkbox' },\n h(\n 'label',\n null,\n h('input', {\n checked: !stage.disableTraffic,\n type: 'checkbox',\n onChange: (e) => updateStage(this.props, { disableTraffic: !e.target.checked }),\n }),\n ' Send client requests to new instances',\n ),\n ),\n ),\n h(GcePlatformHealthOverride, {\n application,\n stage,\n updateStage: (nextStage) => replaceStage(this.props, nextStage),\n }),\n this.renderDeploymentStrategySelector(),\n );\n }\n}\n\nexport class GceFindImageStageConfig extends GceBaseStageConfig {\n render() {\n const { application, stage } = this.props;\n initializeGceStage(stage, application, { selectionStrategy: gceSelectionStrategies[0].val, onlyEnabled: true });\n return h(\n 'div',\n null,\n this.renderAccountRegionClusterSelector(),\n h(\n StageConfigField,\n { label: 'Server Group Selection' },\n h(SelectInput, {\n value: stage.selectionStrategy,\n options: gceSelectionStrategies,\n onChange: (selectionStrategy) => updateStage(this.props, { selectionStrategy }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Server Group Filters' },\n h(\n 'div',\n { className: 'checkbox' },\n h(\n 'label',\n null,\n h('input', {\n checked: stage.onlyEnabled,\n type: 'checkbox',\n onChange: (e) => updateStage(this.props, { onlyEnabled: e.target.checked }),\n }),\n ' Only consider enabled Server Groups',\n ),\n ),\n ),\n );\n }\n}\n\nfunction normalizeResizeStage(stage) {\n if (stage.action === 'scale_exact') {\n stage.resizeType = 'exact';\n delete stage.scalePct;\n delete stage.scaleNum;\n stage.capacity = stage.capacity || {};\n } else {\n stage.capacity = {};\n if (stage.resizeType === 'pct') {\n delete stage.scaleNum;\n } else {\n stage.resizeType = 'incr';\n delete stage.scalePct;\n stage.scaleNum = stage.scaleNum || 0;\n }\n }\n}\n\nexport class GceResizeServerGroupStageConfig extends GceBaseStageConfig {\n render() {\n const { application, stage } = this.props;\n initializeGceStage(stage, application, {\n target: StageConstants.TARGET_LIST[0].val,\n action: scaleActions[0].val,\n resizeType: resizeTypes[0].val,\n });\n stage.capacity = stage.capacity || {};\n if (!stage.action && stage.resizeType === 'exact') {\n stage.action = 'scale_exact';\n }\n\n const updateResize = (changes) => {\n const nextStage = { ...stage, ...changes };\n normalizeResizeStage(nextStage);\n replaceStage(this.props, nextStage);\n };\n\n return h(\n 'div',\n null,\n this.renderAccountRegionClusterSelector(),\n this.renderTargetSelect(),\n h(\n StageConfigField,\n { label: 'Action' },\n h(SelectInput, { value: stage.action, options: scaleActions, onChange: (action) => updateResize({ action }) }),\n ),\n stage.action !== 'scale_exact' &&\n h(\n React.Fragment,\n null,\n h(\n StageConfigField,\n { label: stage.action === 'scale_to_cluster' ? 'Additional Capacity' : 'Type' },\n h(SelectInput, {\n value: stage.resizeType,\n options: resizeTypes,\n onChange: (resizeType) => updateResize({ resizeType }),\n }),\n ),\n stage.resizeType === 'pct' &&\n h(\n StageConfigField,\n { label: 'Resize Percentage' },\n h(NumberInput, { value: stage.scalePct, onChange: (scalePct) => updateStage(this.props, { scalePct }) }),\n ),\n stage.resizeType === 'incr' &&\n h(\n StageConfigField,\n { label: 'Resize-by Amount' },\n h(NumberInput, { value: stage.scaleNum, onChange: (scaleNum) => updateStage(this.props, { scaleNum }) }),\n ),\n ),\n stage.action === 'scale_exact' &&\n h(CapacityFields, {\n capacity: stage.capacity,\n onChange: (capacity) => updateStage(this.props, { capacity }),\n }),\n h(GcePlatformHealthOverride, {\n application,\n stage,\n updateStage: (nextStage) => replaceStage(this.props, nextStage),\n }),\n );\n }\n}\n\nexport class GceClusterCapacityStageConfig extends GceBaseStageConfig {\n render() {\n const {\n application,\n stage,\n activeToggleField,\n activeToggleLabel,\n defaultValue = 1,\n fieldName,\n label,\n preferenceField = 'preferLargerOverNewer',\n preferenceLabel = 'Keep',\n showHealthOverride = false,\n } = this.props;\n initializeGceStage(stage, application, { [fieldName]: defaultValue });\n setDefault(stage, preferenceField, 'false');\n stage[preferenceField] = stage[preferenceField].toString();\n\n if (activeToggleField) {\n setDefault(stage, activeToggleField, false);\n }\n\n return h(\n 'div',\n null,\n this.renderAccountRegionClusterSelector(),\n h(\n StageConfigField,\n { label },\n h(\n 'div',\n { className: 'form-inline' },\n `${preferenceLabel} `,\n h(NumberInput, {\n style: { display: 'inline-block', width: '50px' },\n value: stage[fieldName],\n onChange: (value) => updateStage(this.props, { [fieldName]: value }),\n }),\n ' ',\n h(InlineSelectInput, {\n style: { display: 'inline-block', width: '100px' },\n value: stage[preferenceField],\n options: [\n { label: 'largest', val: 'true' },\n { label: 'newest', val: 'false' },\n ],\n onChange: (value) => updateStage(this.props, { [preferenceField]: value }),\n }),\n ` ${pluralize('server group', stage[fieldName])}.`,\n ),\n ),\n activeToggleField &&\n h(\n 'div',\n { className: 'form-group' },\n h(\n 'div',\n { className: 'col-md-offset-3 col-md-6 checkbox' },\n h(\n 'label',\n null,\n h('input', {\n checked: !!stage[activeToggleField],\n type: 'checkbox',\n onChange: (e) => updateStage(this.props, { [activeToggleField]: e.target.checked }),\n }),\n ` ${activeToggleLabel}`,\n ),\n ),\n ),\n showHealthOverride &&\n h(GcePlatformHealthOverride, {\n application,\n stage,\n updateStage: (nextStage) => replaceStage(this.props, nextStage),\n }),\n );\n }\n}\n\nexport function GceDisableClusterStageConfig(props) {\n return h(GceClusterCapacityStageConfig, {\n ...props,\n fieldName: 'remainingEnabledServerGroups',\n label: 'Disable Options',\n preferenceLabel: 'Keep the',\n showHealthOverride: true,\n });\n}\n\nexport function GceScaleDownClusterStageConfig(props) {\n return h(GceClusterCapacityStageConfig, {\n ...props,\n activeToggleField: 'allowScaleDownActive',\n activeToggleLabel: 'Allow scale down of active server groups',\n fieldName: 'remainingFullSizeServerGroups',\n label: 'Scale Down Options',\n preferenceLabel: 'Keep the',\n });\n}\n\nexport function GceShrinkClusterStageConfig(props) {\n return h(GceClusterCapacityStageConfig, {\n ...props,\n activeToggleField: 'allowDeleteActive',\n activeToggleLabel: 'Allow deletion of active server groups',\n fieldName: 'shrinkToSize',\n label: 'Shrink Options',\n preferenceField: 'retainLargerOverNewer',\n preferenceLabel: 'Shrink to',\n showHealthOverride: true,\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceCloneServerGroupStageConfig } from '../googleStageConfig';\n\nexport function registerGceCloneServerGroupStage() {\n Registry.pipeline.registerStage({\n provides: 'cloneServerGroup',\n cloudProvider: 'gce',\n component: GceCloneServerGroupStageConfig,\n validators: [\n { type: 'requiredField', fieldName: 'targetCluster', fieldLabel: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'region' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceTargetServerGroupStageConfig } from '../googleStageConfig';\n\nexport function registerGceDestroyAsgStage() {\n Registry.pipeline.registerStage({\n provides: 'destroyServerGroup',\n cloudProvider: 'gce',\n component: GceTargetServerGroupStageConfig,\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to destroy a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceDisableAsgStageConfig } from '../googleStageConfig';\n\nexport function registerGceDisableAsgStage() {\n Registry.pipeline.registerStage({\n provides: 'disableServerGroup',\n cloudProvider: 'gce',\n component: GceDisableAsgStageConfig,\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to disable a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceDisableClusterStageConfig } from '../googleStageConfig';\n\nexport function registerGceDisableClusterStage() {\n Registry.pipeline.registerStage({\n provides: 'disableCluster',\n cloudProvider: 'gce',\n component: GceDisableClusterStageConfig,\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n {\n type: 'requiredField',\n fieldName: 'remainingEnabledServerGroups',\n fieldLabel: 'Keep [X] enabled Server Groups',\n },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceEnableAsgStageConfig } from '../googleStageConfig';\n\nexport function registerGceEnableAsgStage() {\n Registry.pipeline.registerStage({\n provides: 'enableServerGroup',\n cloudProvider: 'gce',\n component: GceEnableAsgStageConfig,\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceFindImageStageConfig } from '../googleStageConfig';\n\nexport function registerGceFindAmiStage() {\n Registry.pipeline.registerStage({\n provides: 'findImage',\n cloudProvider: 'gce',\n component: GceFindImageStageConfig,\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'selectionStrategy', fieldLabel: 'Server Group Selection' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials' },\n ],\n });\n}\n","import React from 'react';\n\nimport {\n ExecutionDetailsSection,\n ExecutionDetailsTasks,\n MapEditor,\n Registry,\n StageConfigField,\n StageFailureMessage,\n} from '@spinnaker/core';\n\nconst h = React.createElement;\n\nfunction GceFindImageFromTagsStageConfig({ stage, updateStage }) {\n stage.tags = stage.tags || {};\n stage.regions = stage.regions || [];\n stage.cloudProvider = stage.cloudProvider || 'gce';\n return h(\n 'div',\n { className: 'form-horizontal' },\n h(\n StageConfigField,\n { label: 'Package' },\n h('input', {\n className: 'form-control input-sm',\n value: stage.packageName || '',\n onChange: (e) => updateStage({ ...stage, packageName: e.target.value }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Tags' },\n h(MapEditor, {\n allowEmpty: true,\n model: stage.tags,\n onChange: (tags) => updateStage({ ...stage, tags }),\n }),\n ),\n );\n}\n\nfunction Tags({ tags, separator = ':' }) {\n const entries = Object.entries(tags || {});\n if (!entries.length) {\n return null;\n }\n\n return h(\n React.Fragment,\n null,\n entries.map(([key, value], index) =>\n h('span', { key }, `${key}${separator}${value}${index === entries.length - 1 ? '' : ', '}`),\n ),\n );\n}\n\nfunction GceFindImageFromTagsExecutionDetails(props) {\n const { current, stage } = props;\n const context = stage.context || {};\n const images = context.amiDetails || [];\n\n return h(\n ExecutionDetailsSection,\n { name: props.name, current },\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-12' },\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal' },\n h('dt', null, 'Package'),\n h('dd', null, context.packageName),\n h('dt', null, 'Tags'),\n h('dd', null, h(Tags, { tags: context.tags })),\n ),\n ),\n ),\n h(StageFailureMessage, { stage, message: stage.failureMessage }),\n !!images.length &&\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-12' },\n h(\n 'div',\n { className: 'well alert alert-info' },\n h('h4', null, 'Results'),\n images.map((image) =>\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal', key: `${image.region}:${image.imageName}` },\n h('dt', null, 'Region'),\n h('dd', null, image.region),\n h('dt', null, 'Image'),\n h('dd', null, image.imageName),\n ),\n ),\n ),\n ),\n ),\n );\n}\nGceFindImageFromTagsExecutionDetails.title = 'findImageConfig';\n\nexport function registerGceFindImageFromTagsStage() {\n Registry.pipeline.registerStage({\n provides: 'findImageFromTags',\n cloudProvider: 'gce',\n component: GceFindImageFromTagsStageConfig,\n executionDetailsSections: [GceFindImageFromTagsExecutionDetails, ExecutionDetailsTasks],\n validators: [\n { type: 'requiredField', fieldName: 'packageName' },\n { type: 'requiredField', fieldName: 'tags' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceResizeServerGroupStageConfig } from '../googleStageConfig';\n\nexport function registerGceResizeAsgStage() {\n Registry.pipeline.registerStage({\n provides: 'resizeServerGroup',\n cloudProvider: 'gce',\n component: GceResizeServerGroupStageConfig,\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n supportsCustomTimeout: true,\n validators: [\n {\n type: 'targetImpedance',\n message:\n 'This pipeline will attempt to resize a server group without deploying a new version into the same cluster.',\n },\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'target' },\n { type: 'requiredField', fieldName: 'action' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceScaleDownClusterStageConfig } from '../googleStageConfig';\n\nexport function registerGceScaleDownClusterStage() {\n Registry.pipeline.registerStage({\n provides: 'scaleDownCluster',\n cloudProvider: 'gce',\n component: GceScaleDownClusterStageConfig,\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n {\n type: 'requiredField',\n fieldName: 'remainingFullSizeServerGroups',\n fieldLabel: 'Keep [X] full size Server Groups',\n },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n strategy: true,\n });\n}\n","import { Registry } from '@spinnaker/core';\n\nimport { GceShrinkClusterStageConfig } from '../googleStageConfig';\n\nexport function registerGceShrinkClusterStage() {\n Registry.pipeline.registerStage({\n provides: 'shrinkCluster',\n cloudProvider: 'gce',\n component: GceShrinkClusterStageConfig,\n accountExtractor: (stage) => [stage.context.credentials],\n configAccountExtractor: (stage) => [stage.credentials],\n validators: [\n { type: 'requiredField', fieldName: 'cluster' },\n { type: 'requiredField', fieldName: 'shrinkToSize', fieldLabel: 'shrink to [X] Server Groups' },\n { type: 'requiredField', fieldName: 'regions' },\n { type: 'requiredField', fieldName: 'credentials', fieldLabel: 'account' },\n ],\n });\n}\n","import React from 'react';\n\nimport {\n AccountService,\n ExecutionDetailsSection,\n ExecutionDetailsTasks,\n MapEditor,\n PipelineConfigService,\n Registry,\n StageConfigField,\n StageConstants,\n StageFailureMessage,\n} from '@spinnaker/core';\n\nconst h = React.createElement;\n\nfunction selectOptions(accounts) {\n return accounts.map((account) => h('option', { key: account.name, value: account.name }, account.name));\n}\n\nfunction toggleConsideredStage(stage, refId, checked) {\n const current = stage.consideredStages || [];\n if (checked && !current.includes(refId)) {\n return current.concat(refId);\n }\n if (!checked) {\n return current.filter((candidate) => candidate !== refId);\n }\n return current;\n}\n\nclass GceTagImageStageConfig extends React.Component {\n state = { accounts: [] };\n\n componentDidMount() {\n AccountService.listAccounts('gce').then((accounts) => this.setState({ accounts }));\n }\n\n render() {\n const { pipeline, stage, updateStage } = this.props;\n stage.tags = stage.tags || {};\n stage.cloudProvider = stage.cloudProvider || 'gce';\n\n const imageProducingStages = pipeline\n ? PipelineConfigService.getAllUpstreamDependencies(pipeline, stage).filter((upstreamStage) =>\n StageConstants.IMAGE_PRODUCING_STAGES.includes(upstreamStage.type),\n )\n : [];\n\n return h(\n 'div',\n { className: 'form-horizontal' },\n h(\n StageConfigField,\n { label: 'Account' },\n h(\n 'select',\n {\n className: 'form-control input-sm',\n required: true,\n value: stage.credentials || '',\n onChange: (e) => updateStage({ ...stage, credentials: e.target.value }),\n },\n h('option', { value: '' }, 'Select...'),\n selectOptions(this.state.accounts),\n ),\n ),\n h(\n StageConfigField,\n { label: 'Tags' },\n h(MapEditor, {\n allowEmpty: true,\n model: stage.tags,\n onChange: (tags) => updateStage({ ...stage, tags }),\n }),\n ),\n h(\n StageConfigField,\n { label: 'Stages (optional)' },\n h(\n 'div',\n { className: 'checkbox' },\n imageProducingStages.map((upstreamStage) =>\n h(\n 'label',\n { key: upstreamStage.refId, style: { display: 'block' } },\n h('input', {\n checked: (stage.consideredStages || []).includes(upstreamStage.refId),\n type: 'checkbox',\n onChange: (e) =>\n updateStage({\n ...stage,\n consideredStages: toggleConsideredStage(stage, upstreamStage.refId, e.target.checked),\n }),\n }),\n ` ${upstreamStage.name || upstreamStage.refId}`,\n ),\n ),\n ),\n ),\n );\n }\n}\n\nfunction stageName(execution, refId) {\n const stage = execution?.stages?.find((candidate) => candidate.refId === refId);\n return stage?.name || refId;\n}\n\nfunction GceTagImageExecutionDetails(props) {\n const { current, execution, stage } = props;\n const context = stage.context || {};\n const targets = context.targets || [];\n const tags = Object.entries(context.tags || {}).filter(([, value]) => value !== null);\n const consideredStages = context.consideredStages || [];\n\n return h(\n ExecutionDetailsSection,\n { name: props.name, current },\n !!targets.length &&\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-12' },\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal' },\n h('dt', null, 'Account'),\n h('dd', null, context.credentials),\n h('dt', null, 'Images'),\n targets.map((target) => h('dd', { key: target.imageName }, target.imageName)),\n ),\n ),\n ),\n h(\n 'div',\n { className: 'row' },\n h(\n 'div',\n { className: 'col-md-12' },\n h(\n 'dl',\n { className: 'dl-narrow dl-horizontal' },\n h('dt', null, 'Tags'),\n tags.map(([key, value]) => h('dd', { key }, `${key} = ${value}`)),\n !!consideredStages.length && h('dt', null, 'Stages'),\n consideredStages.map((refId) => h('dd', { key: refId }, stageName(execution, refId))),\n ),\n ),\n ),\n h(StageFailureMessage, { stage, message: stage.failureMessage }),\n );\n}\nGceTagImageExecutionDetails.title = 'tagImageConfig';\n\nexport function registerGceTagImageStage() {\n Registry.pipeline.registerStage({\n provides: 'upsertImageTags',\n cloudProvider: 'gce',\n component: GceTagImageStageConfig,\n executionDetailsSections: [GceTagImageExecutionDetails, ExecutionDetailsTasks],\n });\n}\n","import React from 'react';\n\nimport type { DeckRuntimeServices, IRouterInjectedProps, ISecurityGroupsByAccountSourceData } from '@spinnaker/core';\nimport {\n DeckRuntimeContext,\n FirewallLabels,\n ModalClose,\n ReactModal,\n SecurityGroupWriter,\n SubmitButton,\n TaskMonitor,\n TaskMonitorWrapper,\n withRouter,\n} from '@spinnaker/core';\n\nexport type GceSecurityGroupModalMode = 'create' | 'edit' | 'clone';\n\ninterface IGceSecurityGroupModalProps {\n app?: any;\n application?: any;\n closeModal?: () => void;\n credentials?: string;\n dismissModal?: () => void;\n mode?: GceSecurityGroupModalMode;\n securityGroup?: any;\n}\n\ninterface IGceIngressRule {\n endPort?: number;\n startPort?: number;\n type: string;\n}\n\ninterface IGceSecurityGroupModalState {\n securityGroupInventory?: ISecurityGroupsByAccountSourceData;\n securityGroupInventoryLoaded: boolean;\n securityGroupValidationError?: string;\n securityGroup: any;\n taskMonitor: TaskMonitor;\n}\n\nconst PROTOCOLS = ['tcp', 'udp', 'icmp', 'esp', 'ah', 'sctp'];\nconst PORT_PROTOCOLS = ['tcp', 'udp', 'sctp'];\n\nfunction parseList(value: any): string[] {\n if (Array.isArray(value)) {\n return value\n .map((item) => (typeof item === 'object' ? item.value : item))\n .filter((item) => item !== undefined && item !== null && `${item}`.trim())\n .map((item) => `${item}`.trim());\n }\n if (typeof value === 'string') {\n const unwrapped = value.startsWith('[') && value.endsWith(']') ? value.slice(1, -1) : value;\n return unwrapped\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n }\n return value ? [`${value}`] : [];\n}\n\nfunction sourceRangesFrom(securityGroup: any): string[] {\n const ipRangeRuleCidrs = (securityGroup.ipRangeRules || [])\n .map((rule: any) => {\n const ip = rule.range?.ip;\n return ip ? `${ip}${rule.range?.cidr || ''}` : '';\n })\n .filter(Boolean);\n return Array.from(new Set([...parseList(securityGroup.sourceRanges), ...ipRangeRuleCidrs]));\n}\n\nfunction normalizePortRange(portRange: any): { startPort?: number; endPort?: number } {\n if (typeof portRange === 'string' || typeof portRange === 'number') {\n const [startPort, endPort = startPort] = `${portRange}`.split('-');\n return { startPort: Number(startPort), endPort: Number(endPort) };\n }\n return {\n startPort: portRange?.startPort === undefined ? undefined : Number(portRange.startPort),\n endPort: portRange?.endPort === undefined ? undefined : Number(portRange.endPort),\n };\n}\n\nfunction ingressRulesFrom(securityGroup: any): IGceIngressRule[] {\n if ((securityGroup.ipIngress || []).length) {\n return securityGroup.ipIngress.map((rule: any) => ({\n type: rule.type || rule.protocol || rule.ipProtocol,\n ...normalizePortRange(rule),\n }));\n }\n\n const inboundRules =\n securityGroup.ipIngressRules ||\n securityGroup.inboundRules ||\n securityGroup.allowed ||\n securityGroup.ipRangeRules ||\n [];\n const rules = inboundRules.reduce((result: IGceIngressRule[], rule: any) => {\n const type = rule.type || rule.protocol || rule.ipProtocol || rule.IPProtocol;\n const portRanges = rule.portRanges || rule.ports || [];\n if (portRanges.length) {\n portRanges.forEach((portRange: any) => result.push({ type, ...normalizePortRange(portRange) }));\n } else if (type) {\n result.push({ type });\n }\n return result;\n }, []);\n\n const seen = new Set<string>();\n return rules.filter((rule: IGceIngressRule) => {\n const key = `${rule.type}:${rule.startPort ?? ''}:${rule.endPort ?? ''}`;\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n return true;\n });\n}\n\nfunction accountFor(securityGroup: any, credentials?: string): string {\n return (\n securityGroup.credentials ||\n securityGroup.accountName ||\n securityGroup.accountId ||\n securityGroup.account ||\n credentials ||\n ''\n );\n}\n\nfunction normalizedCoordinate(value: any): string {\n return String(value || '')\n .trim()\n .toLowerCase();\n}\n\nfunction isDuplicateSecurityGroupName(\n securityGroup: any,\n securityGroupInventory?: ISecurityGroupsByAccountSourceData,\n): boolean {\n const name = normalizedCoordinate(securityGroup.name);\n const account = normalizedCoordinate(accountFor(securityGroup));\n const accountInventoryKey = Object.keys(securityGroupInventory || {}).find(\n (inventoryAccount) => normalizedCoordinate(inventoryAccount) === account,\n );\n const existingSecurityGroups = accountInventoryKey\n ? securityGroupInventory?.[accountInventoryKey]?.gce?.global || []\n : [];\n\n return existingSecurityGroups.some((existingSecurityGroup: any) => {\n return normalizedCoordinate(existingSecurityGroup.name) === name;\n });\n}\n\nexport function initializeGceSecurityGroupForModal(props: IGceSecurityGroupModalProps, applicationName: string): any {\n const source = props.securityGroup || {};\n const mode = props.mode || 'create';\n const credentials = accountFor(source, props.credentials);\n const securityGroup = {\n ...source,\n accountId: source.accountId || credentials,\n accountName: source.accountName || credentials,\n credentials,\n description: source.description || '',\n ipIngress: ingressRulesFrom(source),\n name: source.name || applicationName || '',\n network: source.network || source.vpcId || 'default',\n region: 'global',\n sourceRanges: sourceRangesFrom(source),\n sourceTags: parseList(source.sourceTags),\n targetTags: parseList(source.targetTags),\n };\n\n if (mode === 'create' && !securityGroup.ipIngress.length) {\n securityGroup.ipIngress = [{ type: 'tcp' }];\n }\n if (mode === 'clone') {\n securityGroup.id = undefined;\n securityGroup.name = '';\n delete securityGroup.selfLink;\n }\n\n return securityGroup;\n}\n\nexport class GceSecurityGroupModalComponent extends React.Component<\n IGceSecurityGroupModalProps & IRouterInjectedProps,\n IGceSecurityGroupModalState\n> {\n public static contextType = DeckRuntimeContext;\n public declare context: React.ContextType<typeof DeckRuntimeContext>;\n\n private mounted = false;\n private applicationRefreshUnsubscribe?: () => void;\n\n public static show(props: IGceSecurityGroupModalProps, runtimeServices: DeckRuntimeServices): Promise<any> {\n return ReactModal.show(GceSecurityGroupModal, props, { dialogClassName: 'modal-lg' }, runtimeServices);\n }\n\n public constructor(props: IGceSecurityGroupModalProps & IRouterInjectedProps) {\n super(props);\n const application = this.getApplication(props);\n const mode = props.mode || 'create';\n this.state = {\n securityGroup: initializeGceSecurityGroupForModal(props, application?.name),\n securityGroupInventoryLoaded: mode === 'edit',\n taskMonitor: new TaskMonitor({\n application,\n title: `${mode === 'edit' ? 'Updating' : 'Creating'} your ${FirewallLabels.get('firewall')}`,\n onDismiss: () => props.dismissModal?.(),\n onTaskComplete: this.onTaskComplete,\n }),\n };\n }\n\n public componentDidMount(): void {\n this.mounted = true;\n if (this.getMode() === 'edit') {\n return;\n }\n\n this.context.services.securityGroupReader.getAllSecurityGroups().then(\n (securityGroupInventory) => {\n if (this.mounted) {\n this.setState({ securityGroupInventory, securityGroupInventoryLoaded: true });\n }\n },\n () => {\n if (this.mounted) {\n this.setState({ securityGroupValidationError: 'Unable to validate firewall name.' });\n }\n },\n );\n }\n\n public componentWillUnmount(): void {\n this.mounted = false;\n this.clearApplicationRefreshSubscription();\n }\n\n private getApplication(props = this.props): any {\n return props.application || props.app;\n }\n\n private getMode(): GceSecurityGroupModalMode {\n return this.props.mode || 'create';\n }\n\n private onTaskComplete = (): void => {\n const securityGroups = this.getApplication()?.securityGroups;\n if (this.getMode() === 'edit') {\n securityGroups?.refresh?.();\n this.props.closeModal?.();\n return;\n }\n\n const showNewSecurityGroup = (): void => {\n this.clearApplicationRefreshSubscription();\n if (!this.mounted) {\n return;\n }\n const { securityGroup } = this.state;\n this.props.closeModal?.();\n this.props.stateService.go(\n this.props.stateService.includes('**.firewallDetails') ? '^.firewallDetails' : '.firewallDetails',\n {\n accountId: accountFor(securityGroup),\n name: securityGroup.name.trim(),\n provider: 'gce',\n region: 'global',\n vpcId: (securityGroup.network || securityGroup.vpcId).trim(),\n },\n );\n };\n\n if (securityGroups?.onNextRefresh) {\n this.clearApplicationRefreshSubscription();\n this.applicationRefreshUnsubscribe = securityGroups.onNextRefresh(showNewSecurityGroup);\n securityGroups.refresh?.();\n return;\n }\n\n const refreshResult = securityGroups?.refresh?.();\n if (refreshResult?.then) {\n refreshResult.then(showNewSecurityGroup);\n } else {\n showNewSecurityGroup();\n }\n };\n\n private clearApplicationRefreshSubscription = (): void => {\n this.applicationRefreshUnsubscribe?.();\n this.applicationRefreshUnsubscribe = undefined;\n };\n\n private updateSecurityGroup = (updates: any): void => {\n this.setState(({ securityGroup }) => ({ securityGroup: { ...securityGroup, ...updates } }));\n };\n\n private updateRule = (index: number, updates: Partial<IGceIngressRule>): void => {\n const ipIngress = this.state.securityGroup.ipIngress.slice();\n ipIngress[index] = { ...ipIngress[index], ...updates };\n this.updateSecurityGroup({ ipIngress });\n };\n\n private addRule = (): void => {\n this.updateSecurityGroup({\n ipIngress: [...this.state.securityGroup.ipIngress, { type: 'tcp', startPort: 7001, endPort: 7001 }],\n });\n };\n\n private removeRule = (index: number): void => {\n this.updateSecurityGroup({\n ipIngress: this.state.securityGroup.ipIngress.filter((_rule: IGceIngressRule, ruleIndex: number) => {\n return ruleIndex !== index;\n }),\n });\n };\n\n private isValid(): boolean {\n const { securityGroup, securityGroupInventory, securityGroupInventoryLoaded } = this.state;\n const nameIsAvailable =\n this.getMode() === 'edit' ||\n (securityGroupInventoryLoaded && !isDuplicateSecurityGroupName(securityGroup, securityGroupInventory));\n return !!(\n securityGroup.name.trim() &&\n nameIsAvailable &&\n accountFor(securityGroup) &&\n securityGroup.network.trim() &&\n securityGroup.ipIngress.length &&\n (securityGroup.sourceRanges.length || securityGroup.sourceTags.length) &&\n securityGroup.ipIngress.every((rule: IGceIngressRule) => {\n return (\n rule.type &&\n (!PORT_PROTOCOLS.includes(rule.type) || (rule.startPort !== undefined && rule.endPort !== undefined))\n );\n })\n );\n }\n\n private submit = (): void => {\n const application = this.getApplication();\n const { securityGroup } = this.state;\n const credentials = accountFor(securityGroup);\n const allowed = securityGroup.ipIngress.map((rule: IGceIngressRule) => {\n const serializedRule: { ipProtocol: string; portRanges?: string[] } = { ipProtocol: rule.type };\n if (rule.startPort !== undefined && rule.endPort !== undefined) {\n serializedRule.portRanges = [`${rule.startPort}-${rule.endPort}`];\n }\n return serializedRule;\n });\n const command = {\n ...securityGroup,\n accountId: securityGroup.accountId || credentials,\n accountName: securityGroup.accountName || credentials,\n allowed,\n application: application.name,\n cloudProvider: 'gce',\n credentials,\n name: securityGroup.name.trim(),\n network: securityGroup.network.trim(),\n region: 'global',\n sourceRanges: Array.from(new Set(securityGroup.sourceRanges)),\n sourceTags: Array.from(new Set(securityGroup.sourceTags)),\n targetTags: Array.from(new Set(securityGroup.targetTags)),\n };\n const mode = this.getMode();\n const descriptor = mode === 'edit' ? 'Update' : mode === 'clone' ? 'Clone' : 'Create';\n\n this.state.taskMonitor.submit(() =>\n SecurityGroupWriter.upsertSecurityGroup(command as any, application, descriptor),\n );\n };\n\n private renderTextField(\n label: string,\n value: string,\n onChange: (value: string) => void,\n readOnly = false,\n ): JSX.Element {\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 control-label\">{label}</label>\n <div className=\"col-md-7\">\n <input\n className=\"form-control input-sm\"\n onChange={(event) => onChange(event.target.value)}\n readOnly={readOnly}\n value={value || ''}\n />\n </div>\n </div>\n );\n }\n\n private renderRules(): JSX.Element {\n return (\n <div className=\"form-group\">\n <div className=\"col-md-10 col-md-offset-1\">\n <table className=\"table table-condensed packed\">\n <thead>\n <tr>\n <th>Protocol</th>\n <th>Start Port</th>\n <th>End Port</th>\n <th />\n </tr>\n </thead>\n <tbody>\n {this.state.securityGroup.ipIngress.map((rule: IGceIngressRule, index: number) => (\n <tr key={index}>\n <td>\n <select\n className=\"form-control input-sm\"\n onChange={(event) => this.updateRule(index, { type: event.target.value })}\n value={rule.type}\n >\n {PROTOCOLS.map((protocol) => (\n <option key={protocol} value={protocol}>\n {protocol.toUpperCase()}\n </option>\n ))}\n </select>\n </td>\n <td>\n <input\n className=\"form-control input-sm\"\n min=\"0\"\n onChange={(event) =>\n this.updateRule(index, {\n startPort: event.target.value === '' ? undefined : Number(event.target.value),\n })\n }\n type=\"number\"\n value={rule.startPort === undefined ? '' : rule.startPort}\n />\n </td>\n <td>\n <input\n className=\"form-control input-sm\"\n min=\"0\"\n onChange={(event) =>\n this.updateRule(index, {\n endPort: event.target.value === '' ? undefined : Number(event.target.value),\n })\n }\n type=\"number\"\n value={rule.endPort === undefined ? '' : rule.endPort}\n />\n </td>\n <td>\n <button className=\"btn btn-link\" onClick={() => this.removeRule(index)} type=\"button\">\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n <button className=\"btn btn-block add-new\" onClick={this.addRule} type=\"button\">\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add New Protocol and Port Range\n </button>\n </div>\n </div>\n );\n }\n\n public render(): JSX.Element {\n const { securityGroup, securityGroupInventoryLoaded, securityGroupValidationError, taskMonitor } = this.state;\n const mode = this.getMode();\n const editing = mode === 'edit';\n const heading = `${mode === 'edit' ? 'Edit' : mode === 'clone' ? 'Clone' : 'Create'} ${FirewallLabels.get(\n 'Firewall',\n )}`;\n\n return (\n <div className=\"modal-content\">\n <TaskMonitorWrapper monitor={taskMonitor} />\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h3>{heading}</h3>\n </div>\n <div className=\"modal-body\">\n <div className=\"form-horizontal\">\n {this.renderTextField('Name', securityGroup.name, (name) => this.updateSecurityGroup({ name }), editing)}\n {!editing && !securityGroupInventoryLoaded && (\n <div\n className={securityGroupValidationError ? 'security-group-validation-error text-danger' : 'help-block'}\n >\n {securityGroupValidationError || 'Checking firewall name availability...'}\n </div>\n )}\n {this.renderTextField('Description', securityGroup.description, (description) =>\n this.updateSecurityGroup({ description }),\n )}\n {this.renderTextField(\n 'Account',\n accountFor(securityGroup),\n (credentials) =>\n this.updateSecurityGroup({\n accountId: credentials,\n accountName: credentials,\n credentials,\n }),\n editing,\n )}\n {this.renderTextField(\n 'Network',\n securityGroup.network,\n (network) => this.updateSecurityGroup({ network }),\n editing,\n )}\n {this.renderTextField('Target tags', securityGroup.targetTags.join(', '), (targetTags) =>\n this.updateSecurityGroup({ targetTags: parseList(targetTags) }),\n )}\n {this.renderTextField('Source tags', securityGroup.sourceTags.join(', '), (sourceTags) =>\n this.updateSecurityGroup({ sourceTags: parseList(sourceTags) }),\n )}\n {this.renderTextField('Source CIDRs', securityGroup.sourceRanges.join(', '), (sourceRanges) =>\n this.updateSecurityGroup({ sourceRanges: parseList(sourceRanges) }),\n )}\n {this.renderRules()}\n </div>\n </div>\n <div className=\"modal-footer\">\n <button className=\"btn btn-default\" onClick={this.props.dismissModal} type=\"button\">\n Cancel\n </button>\n <SubmitButton\n isDisabled={!this.isValid()}\n isFormSubmit={false}\n label={mode === 'edit' ? 'Update' : mode === 'clone' ? 'Clone' : 'Create'}\n onClick={this.submit}\n submitting={taskMonitor.submitting}\n />\n </div>\n </div>\n );\n }\n}\n\nexport const GceSecurityGroupModal = Object.assign(withRouter(GceSecurityGroupModalComponent), {\n show: GceSecurityGroupModalComponent.show,\n});\n","import React, { useEffect, useState } from 'react';\n\nimport {\n AccountTag,\n CollapsibleSection,\n ConfirmationModalService,\n FirewallLabels,\n SecurityGroupWriter,\n useDeckRuntimeServices,\n} from '@spinnaker/core';\n\nimport { GceSecurityGroupModal } from '../configure/GceSecurityGroupModal';\n\ninterface IGceSecurityGroupDetailsProps {\n app: any;\n resolvedSecurityGroup: any;\n}\n\nfunction parseList(value: any): string[] {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value === 'string' && value.startsWith('[') && value.endsWith(']')) {\n return value\n .slice(1, -1)\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n }\n return value ? [value] : [];\n}\n\nfunction withResolvedCoordinates(securityGroup: any, resolvedSecurityGroup?: any): any {\n if (!resolvedSecurityGroup) {\n return securityGroup;\n }\n const accountId =\n securityGroup.accountId ||\n securityGroup.accountName ||\n securityGroup.account ||\n securityGroup.credentials ||\n resolvedSecurityGroup.accountId;\n return {\n ...securityGroup,\n accountId,\n accountName: securityGroup.accountName || accountId,\n name: securityGroup.name || resolvedSecurityGroup.name,\n provider: securityGroup.provider || resolvedSecurityGroup.provider || 'gce',\n region: securityGroup.region || resolvedSecurityGroup.region || 'global',\n vpcId: securityGroup.vpcId || resolvedSecurityGroup.vpcId,\n };\n}\n\nfunction securityGroupCoordinatesKey(securityGroup: any): string {\n return [\n securityGroup.accountId,\n securityGroup.provider,\n securityGroup.region,\n securityGroup.vpcId || '',\n securityGroup.name,\n ].join(':');\n}\n\nexport function GceSecurityGroupActions({\n app,\n resolvedSecurityGroup,\n securityGroup,\n}: {\n app: any;\n resolvedSecurityGroup?: any;\n securityGroup: any;\n}): JSX.Element {\n const runtimeServices = useDeckRuntimeServices();\n const [menuOpen, setMenuOpen] = useState(false);\n const firewall = withResolvedCoordinates(securityGroup, resolvedSecurityGroup);\n const sharedVpcHostFirewall = typeof firewall.id === 'string' && firewall.id.includes('/');\n const readOnlyExplanation = 'You cannot modify shared VPC host project firewall rules.';\n const editInboundRules = (): void => {\n GceSecurityGroupModal.show({ application: app, mode: 'edit', securityGroup: firewall }, runtimeServices);\n };\n const cloneSecurityGroup = (): void => {\n GceSecurityGroupModal.show({ application: app, mode: 'clone', securityGroup: firewall }, runtimeServices);\n };\n const deleteSecurityGroup = (): void => {\n ConfirmationModalService.confirm({\n account: firewall.accountId,\n buttonText: `Delete ${firewall.name}`,\n header: `Really delete ${firewall.name}?`,\n submitMethod: () =>\n SecurityGroupWriter.deleteSecurityGroup(firewall, app, {\n cloudProvider: 'gce',\n securityGroupName: firewall.name,\n } as any),\n taskMonitorConfig: {\n application: app,\n title: `Deleting ${firewall.name}`,\n },\n });\n };\n\n return (\n <div className=\"actions\">\n <div className={`dropdown ${menuOpen ? 'open' : ''}`} id=\"gce-security-group-actions-dropdown\">\n <button\n aria-expanded={menuOpen}\n className=\"btn btn-sm btn-primary dropdown-toggle\"\n onClick={() => setMenuOpen(!menuOpen)}\n type=\"button\"\n >\n Firewall Actions <span className=\"caret\" />\n </button>\n <ul className=\"dropdown-menu\" role=\"menu\">\n <li className={sharedVpcHostFirewall ? 'disabled' : undefined}>\n <button\n className=\"btn btn-link\"\n data-action=\"edit\"\n disabled={sharedVpcHostFirewall}\n onClick={editInboundRules}\n title={sharedVpcHostFirewall ? readOnlyExplanation : undefined}\n type=\"button\"\n >\n Edit Inbound Rules\n </button>\n </li>\n <li className={sharedVpcHostFirewall ? 'disabled' : undefined}>\n <button\n className=\"btn btn-link\"\n data-action=\"clone\"\n disabled={sharedVpcHostFirewall}\n onClick={cloneSecurityGroup}\n title={sharedVpcHostFirewall ? readOnlyExplanation : undefined}\n type=\"button\"\n >\n Clone Firewall\n </button>\n </li>\n <li className={sharedVpcHostFirewall ? 'disabled' : undefined}>\n <button\n className=\"btn btn-link\"\n data-action=\"delete\"\n disabled={sharedVpcHostFirewall}\n onClick={deleteSecurityGroup}\n title={sharedVpcHostFirewall ? readOnlyExplanation : undefined}\n type=\"button\"\n >\n Delete Firewall\n </button>\n </li>\n </ul>\n </div>\n {sharedVpcHostFirewall && <div className=\"shared-vpc-warning help-block\">{readOnlyExplanation}</div>}\n </div>\n );\n}\n\nexport function GceSecurityGroupDetails({ app, resolvedSecurityGroup }: IGceSecurityGroupDetailsProps): JSX.Element {\n const { securityGroupReader } = useDeckRuntimeServices();\n const routeKey = securityGroupCoordinatesKey(resolvedSecurityGroup);\n const [loadedSecurityGroup, setLoadedSecurityGroup] = useState<{ key: string; value: any }>();\n\n useEffect(() => {\n let cancelled = false;\n\n const loadSecurityGroup = (): Promise<any> => {\n return securityGroupReader\n .getSecurityGroupDetails(\n app,\n resolvedSecurityGroup.accountId,\n resolvedSecurityGroup.provider,\n resolvedSecurityGroup.region,\n resolvedSecurityGroup.vpcId,\n resolvedSecurityGroup.name,\n )\n .then(\n (details: any) => {\n if (!cancelled) {\n setLoadedSecurityGroup({ key: routeKey, value: { ...resolvedSecurityGroup, ...details } });\n }\n },\n () => {\n if (!cancelled) {\n setLoadedSecurityGroup({ key: routeKey, value: resolvedSecurityGroup });\n }\n },\n );\n };\n\n loadSecurityGroup();\n const unsubscribeFromRefresh = app.securityGroups?.onRefresh?.(loadSecurityGroup);\n\n return () => {\n cancelled = true;\n unsubscribeFromRefresh?.();\n };\n }, [app, routeKey, securityGroupReader]);\n\n const loading = loadedSecurityGroup?.key !== routeKey;\n const securityGroup = loading ? resolvedSecurityGroup : loadedSecurityGroup.value;\n\n const targetTags = parseList(securityGroup.targetTags);\n const sourceTags = parseList(securityGroup.sourceTags);\n const sourceRanges = parseList(securityGroup.sourceRanges).concat(\n (securityGroup.ipRangeRules || []).map((rule: any) => `${rule.range?.ip || ''}${rule.range?.cidr || ''}`),\n );\n\n return (\n <div className=\"details-panel\">\n <div className=\"header\">\n <div className=\"header-text horizontal middle\">\n <span className=\"icon-gce\" />\n <h3>{securityGroup.name}</h3>\n </div>\n {!loading && (\n <GceSecurityGroupActions\n app={app}\n resolvedSecurityGroup={resolvedSecurityGroup}\n securityGroup={securityGroup}\n />\n )}\n </div>\n <div className=\"content\">\n {loading && <div className=\"text-center\">Loading...</div>}\n <CollapsibleSection heading={`${FirewallLabels.get('Firewall')} Information`} defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Account</dt>\n <dd>\n <AccountTag account={securityGroup.accountId || securityGroup.accountName} />\n </dd>\n <dt>Region</dt>\n <dd>{securityGroup.region || 'global'}</dd>\n <dt>Network</dt>\n <dd>{securityGroup.vpcId || securityGroup.network || '-'}</dd>\n <dt>Description</dt>\n <dd>{securityGroup.description || '-'}</dd>\n </dl>\n </CollapsibleSection>\n <CollapsibleSection heading=\"Targets\" defaultExpanded={true}>\n <p>{targetTags.join(', ') || 'All traffic'}</p>\n </CollapsibleSection>\n <CollapsibleSection heading=\"Sources\" defaultExpanded={true}>\n <p>{sourceTags.concat(sourceRanges).join(', ') || '-'}</p>\n </CollapsibleSection>\n <CollapsibleSection heading=\"Allowed Ingress\" defaultExpanded={true}>\n {(securityGroup.inboundRules || securityGroup.ipIngressRules || []).length ? (\n <ul>\n {(securityGroup.inboundRules || securityGroup.ipIngressRules || []).map((rule: any, index: number) => (\n <li key={index}>\n {[rule.protocol, rule.portRanges?.map((range: any) => range.startPort).join(', ')]\n .filter(Boolean)\n .join(' ')}\n </li>\n ))}\n </ul>\n ) : (\n <span>-</span>\n )}\n </CollapsibleSection>\n </div>\n </div>\n );\n}\n","'use strict';\n\nexport class GceSecurityGroupReader {\n resolveIndexedSecurityGroup(indexedSecurityGroups, container, securityGroupId) {\n return indexedSecurityGroups[container.account].global[securityGroupId];\n }\n}\n","'use strict';\n\nexport class GceSecurityGroupTransformer {\n constructor(promiseService) {\n this.promiseService = promiseService;\n }\n\n normalizeSecurityGroup(securityGroup) {\n return this.promiseService.resolve(securityGroup);\n }\n}\n","import type { IGceHealthCheck, IGceHealthCheckKind } from '../domain';\n\nexport interface IGceHealthCheckOption {\n displayName: string;\n kind: IGceHealthCheckKind;\n name: string;\n selfLink: string;\n}\n\nexport function parseHealthCheckUrl(url: string): { healthCheckName: string; healthCheckKind: IGceHealthCheckKind } {\n const healthCheckPathParts = url.split('/');\n if (healthCheckPathParts.length < 2) {\n throw new Error(`Health check url ${url} missing expected segments.`);\n }\n const healthCheckName = healthCheckPathParts[healthCheckPathParts.length - 1];\n const healthCheckKind = healthCheckPathParts[healthCheckPathParts.length - 2].slice(0, -1);\n return {\n healthCheckName,\n healthCheckKind: healthCheckKind as IGceHealthCheckKind,\n };\n}\n\nexport function getHealthCheckOptions(healthChecks: IGceHealthCheck[]): IGceHealthCheckOption[] {\n const duplicateNames = getDuplicateHealthCheckNames(healthChecks);\n return healthChecks.map((hc) => {\n const isNameDupe = duplicateNames.has(hc.name);\n return {\n displayName: isNameDupe ? `${hc.name} (${hc.kind})` : hc.name,\n kind: hc.kind,\n name: hc.name,\n selfLink: hc.selfLink,\n };\n });\n}\n\nexport function getDuplicateHealthCheckNames(healthChecks: IGceHealthCheck[]): Set<string> {\n const allNames = new Set<string>();\n const duplicateNames = new Set<string>();\n healthChecks.forEach((hc) => {\n if (allNames.has(hc.name)) {\n duplicateNames.add(hc.name);\n } else {\n allNames.add(hc.name);\n }\n });\n return duplicateNames;\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nexport class GceCustomInstanceBuilderService {\n vCpuCountForLocationIsValid(instanceFamily, vCpuCount, location, locationToInstanceTypesMap) {\n let max = 0;\n switch (instanceFamily) {\n case 'E2':\n // E2 support up to 32 cores\n // https://cloud.google.com/compute/docs/instances/creating-instance-with-custom-machine-type#e2_custom_machine_types\n max = 32;\n break;\n case 'N2':\n case 'N2D':\n case 'N1':\n default:\n max = locationToInstanceTypesMap[location].vCpuMax;\n }\n return vCpuCount <= max;\n }\n\n /*\n * Above 1, vCPU count must be even.\n * */\n numberOfVCpusIsValid(instanceFamily, vCpuCount) {\n if (vCpuCount === 1) {\n return true;\n }\n switch (instanceFamily) {\n case 'N2':\n case 'N2D':\n return vCpuCount % 4 === 0;\n case 'E2':\n case 'N1':\n default:\n return vCpuCount % 2 === 0;\n }\n }\n\n generateValidVCpuListForLocation(location, locationToInstanceTypesMap) {\n const max = locationToInstanceTypesMap[location].vCpuMax;\n return [1, ..._.range(2, max, 2), max];\n }\n\n generateValidInstanceFamilyList() {\n return ['n1', 'e2', 'n2', 'n2d'].map((x) => x.toUpperCase());\n }\n\n /*\n * Memory per vCPU must be between .9 GB and 6.5 GB\n * Total memory must be a multiple of 256 MB.\n * */\n minMemoryForVCpuCount(instanceFamily, vCpuCount) {\n switch (instanceFamily) {\n case 'E2':\n case 'N2':\n case 'N2D':\n return Math.ceil(0.5 * vCpuCount * 4) / 4;\n case 'N1':\n default:\n return Math.ceil(0.9 * vCpuCount * 4) / 4;\n }\n }\n\n maxMemoryForVCpuCount(instanceFamily, vCpuCount) {\n switch (instanceFamily) {\n case 'E2':\n return 8 * vCpuCount > 128 ? 128 : 8 * vCpuCount;\n case 'N2':\n case 'N2D':\n return 8 * vCpuCount;\n case 'N1':\n default:\n return 6.5 * vCpuCount;\n }\n }\n\n generateValidMemoryListForVCpuCount(instanceFamily, vCpuCount) {\n const min = this.minMemoryForVCpuCount(instanceFamily, vCpuCount);\n const max = this.maxMemoryForVCpuCount(instanceFamily, vCpuCount);\n return [..._.range(min, max, 0.25), max];\n }\n\n memoryIsValid(instanceFamily, totalMemory, vCpuCount, extendedMemory) {\n const min = this.minMemoryForVCpuCount(instanceFamily, vCpuCount);\n const max = extendedMemory ? 800 : this.maxMemoryForVCpuCount(instanceFamily, vCpuCount);\n return _.inRange(totalMemory, min, max) || totalMemory === max;\n }\n\n /*\n * In the API, you must always provide memory in MB units.\n * Format: custom-NUMBER_OF_CPUS-AMOUNT_OF_MEMORY\n * */\n generateInstanceTypeString(instanceFamily, vCpuCount, totalMemory, extendedMemory) {\n const extendedFlag = extendedMemory ? '-ext' : '';\n const memoryInMbs = Number(totalMemory) * 1024;\n instanceFamily = instanceFamily.toLowerCase();\n if (instanceFamily === 'n1') {\n return `custom-${vCpuCount}-${memoryInMbs}${extendedFlag}`;\n }\n return `${instanceFamily}-custom-${vCpuCount}-${memoryInMbs}${extendedFlag}`;\n }\n\n parseInstanceTypeString(instanceTypeString) {\n const [vCpuCount, memoryInMbs] = _.chain(instanceTypeString.split('-'))\n .takeRight(2)\n .map((value) => Number(value))\n .value();\n\n let instanceFamily = instanceTypeString.split('-')[0].toUpperCase();\n if (instanceFamily === 'CUSTOM') {\n instanceFamily = 'N1';\n }\n\n const memory = memoryInMbs / 1024;\n\n return { instanceFamily, vCpuCount, memory };\n }\n\n customInstanceChoicesAreValid(\n instanceFamily,\n vCpuCount,\n totalMemory,\n location,\n locationToInstanceTypesMap,\n extendedMemory,\n ) {\n return _.every([\n this.numberOfVCpusIsValid(instanceFamily, vCpuCount),\n this.memoryIsValid(instanceFamily, totalMemory, vCpuCount, extendedMemory),\n this.vCpuCountForLocationIsValid(instanceFamily, vCpuCount, location, locationToInstanceTypesMap),\n ]);\n }\n}\n","'use strict';\n\nexport const GCE_SERVER_GROUP_HIDDEN_METADATA_KEYS = [\n 'load-balancer-names',\n 'global-load-balancer-names',\n 'backend-service-names',\n 'load-balancing-policy',\n 'select-zones',\n 'customUserData',\n];\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { AccountService, ExpectedArtifactService } from '@spinnaker/core';\nimport { GceXpnNamingService } from '../../common/xpnNaming.gce.service';\nimport { GCEProviderSettings } from '../../gce.settings';\nimport { parseHealthCheckUrl } from '../../healthCheck/healthCheckUtils';\n\nimport { GceCustomInstanceBuilderService } from './../../instance/custom/customInstanceBuilder.gce.service';\nimport { GceInstanceTypeService } from '../../instance/gceInstanceType.service';\nimport { GCE_SERVER_GROUP_HIDDEN_METADATA_KEYS } from './wizard/hiddenMetadataKeys.value';\n\nexport class GceServerGroupCommandBuilder {\n constructor(\n promiseService,\n instanceTypeService = new GceInstanceTypeService(promiseService),\n gceCustomInstanceBuilderService = new GceCustomInstanceBuilderService(),\n gceXpnNamingService = new GceXpnNamingService(),\n gceServerGroupHiddenMetadataKeys = GCE_SERVER_GROUP_HIDDEN_METADATA_KEYS,\n ) {\n // Two assumptions here:\n // 1) All GCE machine types are represented in the tree of choices.\n // 2) Each machine type appears in exactly one category.\n function determineInstanceCategoryFromInstanceType(command) {\n return instanceTypeService.getCategories('gce').then(function (categories) {\n categories.forEach(function (category) {\n category.families.forEach(function (family) {\n family.instanceTypes.forEach(function (instanceType) {\n if (instanceType.name === command.instanceType) {\n command.viewState.instanceProfile = category.type;\n }\n });\n });\n });\n });\n }\n\n function extractNetworkName(serverGroup) {\n const projectId = gceXpnNamingService.deriveProjectId(serverGroup.launchConfig.instanceTemplate);\n const networkUrl = _.get(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].network');\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, networkUrl);\n }\n\n function extractSubnetName(serverGroup) {\n const projectId = gceXpnNamingService.deriveProjectId(serverGroup.launchConfig.instanceTemplate);\n const subnetworkUrl = _.get(\n serverGroup,\n 'launchConfig.instanceTemplate.properties.networkInterfaces[0].subnetwork',\n );\n return gceXpnNamingService.decorateXpnResourceIfNecessary(projectId, subnetworkUrl);\n }\n\n function determineAssociatePublicIPAddress(serverGroup) {\n return _.has(serverGroup, 'launchConfig.instanceTemplate.properties.networkInterfaces[0].accessConfigs');\n }\n\n function loadBalancerMetadataValues(value) {\n if (Array.isArray(value)) {\n return value;\n }\n if (typeof value === 'string') {\n return value.split(',').filter(Boolean);\n }\n return [];\n }\n\n function extractLoadBalancerMetadata(metadata) {\n return ['load-balancer-names', 'global-load-balancer-names'].reduce((loadBalancerMetadata, property) => {\n const values = loadBalancerMetadataValues(metadata[property]);\n if (values.length) {\n loadBalancerMetadata[property] = values;\n }\n return loadBalancerMetadata;\n }, {});\n }\n\n function extractLoadBalancers(asg) {\n return ['load-balancer-names', 'global-load-balancer-names'].reduce((loadBalancers, property) => {\n if (asg[property]) {\n loadBalancers = loadBalancers.concat(loadBalancerMetadataValues(asg[property]));\n }\n return loadBalancers;\n }, []);\n }\n\n function extractLoadBalancersFromMetadata(metadata) {\n return ['load-balancer-names', 'global-load-balancer-names'].reduce((loadBalancers, property) => {\n if (metadata[property]) {\n loadBalancers = loadBalancers.concat(loadBalancerMetadataValues(metadata[property]));\n }\n return loadBalancers;\n }, []);\n }\n\n function populateDisksFromExisting(disks, command) {\n disks = disks.map((disk, index) => {\n if (index === 0) {\n return {\n type: disk.initializeParams.diskType,\n sizeGb: disk.initializeParams.diskSizeGb,\n };\n } else {\n return {\n type: disk.initializeParams.diskType,\n sizeGb: disk.initializeParams.diskSizeGb,\n sourceImage: _.last(_.get(disk, 'initializeParams.sourceImage', '').split('/')) || null,\n };\n }\n });\n const localSSDDisks = disks.filter((disk) => disk.type === 'local-ssd');\n const persistentDisks = disks.filter((disk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'));\n\n if (persistentDisks.length) {\n command.disks = persistentDisks.concat(localSSDDisks);\n return instanceTypeService\n .getInstanceTypeDetails(\n command.selectedProvider,\n _.includes(command.instanceType, 'custom-') ? 'buildCustom' : command.instanceType,\n )\n .then((instanceTypeDetails) => {\n command.viewState.instanceTypeDetails = instanceTypeDetails;\n calculateOverriddenStorageDescription(instanceTypeDetails, command);\n });\n } else {\n command.disks = [{ type: 'pd-ssd', sizeGb: 10 }].concat(localSSDDisks);\n return promiseService.resolve(null);\n }\n }\n\n function populateDisksFromPipeline(command) {\n const persistentDisks = getPersistentDisks(command);\n const localSSDDisks = getLocalSSDDisks(command);\n\n if (persistentDisks.length) {\n command.disks = persistentDisks.concat(localSSDDisks);\n return instanceTypeService\n .getInstanceTypeDetails(\n command.selectedProvider,\n _.includes(command.instanceType, 'custom-') ? 'buildCustom' : command.instanceType,\n )\n .then((instanceTypeDetails) => {\n command.viewState.instanceTypeDetails = instanceTypeDetails;\n calculateOverriddenStorageDescription(instanceTypeDetails, command);\n });\n } else {\n command.disks = [{ type: 'pd-ssd', sizeGb: 10 }].concat(localSSDDisks);\n return promiseService.resolve(null);\n }\n }\n\n function getLocalSSDDisks(command) {\n return (command.disks || []).filter((disk) => disk.type === 'local-ssd');\n }\n\n function getPersistentDisks(command) {\n return (command.disks || []).filter((disk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'));\n }\n\n function calculatePersistentDiskOverriddenStorageDescription(command) {\n const persistentDisks = getPersistentDisks(command);\n\n const diskCountBySizeGb = new Map();\n persistentDisks.forEach((disk) => {\n if (diskCountBySizeGb.has(disk.sizeGb)) {\n diskCountBySizeGb.set(disk.sizeGb, diskCountBySizeGb.get(disk.sizeGb) + 1);\n } else {\n diskCountBySizeGb.set(disk.sizeGb, 1);\n }\n });\n\n return Array.from(diskCountBySizeGb)\n .sort(([sizeA], [sizeB]) => sizeB - sizeA)\n .map(([sizeGb, count]) => count + '×' + sizeGb)\n .join(', ');\n }\n\n function calculateOverriddenStorageDescription(instanceTypeDetails, command) {\n if (instanceTypeDetails.storage.localSSDSupported) {\n if (getLocalSSDDisks(command).length !== instanceTypeDetails.storage.count) {\n command.viewState.overriddenStorageDescription = getLocalSSDDisks(command).length + '×375';\n }\n } else {\n const persistentDisks = getPersistentDisks(command);\n const overrideStorageDescription =\n persistentDisks.some((disk) => disk.sizeGb !== instanceTypeDetails.storage.size) ||\n persistentDisks.length !== instanceTypeDetails.storage.count;\n\n if (overrideStorageDescription) {\n command.viewState.overriddenStorageDescription = calculatePersistentDiskOverriddenStorageDescription(command);\n }\n }\n }\n\n function populateAvailabilityPolicies(scheduling, command) {\n if (scheduling) {\n command.preemptible = scheduling.preemptible;\n command.automaticRestart = scheduling.automaticRestart;\n command.onHostMaintenance = scheduling.onHostMaintenance;\n } else {\n command.preemptible = false;\n command.automaticRestart = true;\n command.onHostMaintenance = 'MIGRATE';\n }\n }\n\n function populateAutoHealingPolicy(serverGroup, command) {\n // Always clear first: pipeline edit copies cluster JSON onto the command before this\n // runs, and legacy payloads may carry unsupported maxUnavailable alone or alongside\n // a health check. Rebuild from supported fields only so Deck cannot resubmit it.\n delete command.autoHealingPolicy;\n const autoHealingPolicy = serverGroup.autoHealingPolicy;\n if (!autoHealingPolicy) {\n return;\n }\n const healthCheckUrl = autoHealingPolicy.healthCheckUrl\n ? autoHealingPolicy.healthCheckUrl\n : autoHealingPolicy.healthCheck;\n if (!healthCheckUrl) {\n return;\n }\n const { healthCheckName, healthCheckKind } = parseHealthCheckUrl(healthCheckUrl);\n command.autoHealingPolicy = {\n healthCheck: healthCheckName,\n healthCheckKind,\n healthCheckUrl: healthCheckUrl,\n initialDelaySec: autoHealingPolicy.initialDelaySec,\n };\n }\n\n // Dual-key fallback: try v1 key (shieldedInstanceConfig) first, then legacy beta key\n // (shieldedVmConfig) for backward compat with server groups created before the v1 migration.\n // Ref: https://cloud.google.com/compute/docs/reference/rest/v1/instanceTemplates\n function populateShieldedVmConfig(source, command) {\n const shieldedInstanceConfig = _.get(source, 'launchConfig.instanceTemplate.properties.shieldedInstanceConfig');\n const shieldedVmConfig = _.get(source, 'launchConfig.instanceTemplate.properties.shieldedVmConfig');\n ['enableSecureBoot', 'enableVtpm', 'enableIntegrityMonitoring'].forEach((field) => {\n command[field] = _.has(shieldedInstanceConfig, field)\n ? shieldedInstanceConfig[field]\n : _.has(shieldedVmConfig, field)\n ? shieldedVmConfig[field]\n : _.get(source, field, false);\n });\n }\n\n function populateCustomMetadata(metadataItems, command) {\n // Hide metadata items in the wizard.\n if (metadataItems) {\n let customUserData = '';\n let customUserDataKeys = [];\n if (Array.isArray(metadataItems)) {\n const customUserDataItem = metadataItems.find((metadataItem) => metadataItem.key === 'customUserData');\n if (customUserDataItem) {\n customUserData = customUserDataItem.value;\n customUserDataKeys = getCustomUserDataKeys(customUserData);\n command.userData = customUserData;\n }\n metadataItems.forEach(function (metadataItem) {\n if (\n !_.includes(customUserDataKeys, metadataItem.key) &&\n !_.includes(gceServerGroupHiddenMetadataKeys, metadataItem.key)\n ) {\n command.instanceMetadata[metadataItem.key] = metadataItem.value;\n }\n });\n } else {\n if (metadataItems.customUserData) {\n customUserData = metadataItems.customUserData;\n customUserDataKeys = getCustomUserDataKeys(customUserData);\n command.userData = customUserData;\n metadataItems = _.omit(metadataItems, customUserDataKeys);\n }\n Object.assign(command.instanceMetadata, _.omit(metadataItems, gceServerGroupHiddenMetadataKeys));\n }\n }\n\n if (command.labels['spinnaker-moniker-sequence']) {\n delete command.labels['spinnaker-moniker-sequence'];\n }\n }\n\n function getCustomUserDataKeys(customUserData) {\n const customUserDataKeys = [];\n customUserData.split(/\\n|,/).forEach(function (userDataItem) {\n const customUserDataKey = userDataItem.split('=')[0];\n customUserDataKeys.push(customUserDataKey);\n });\n return customUserDataKeys;\n }\n\n function populateTags(instanceTemplateTags, command) {\n if (instanceTemplateTags && instanceTemplateTags.items) {\n _.map(instanceTemplateTags.items, function (tag) {\n command.tags.push({ value: tag });\n });\n }\n }\n\n function populateResourceManagerTags(instanceTemplateResourceManagerTags, command) {\n if (instanceTemplateResourceManagerTags) {\n Object.assign(command.resourceManagerTags, instanceTemplateResourceManagerTags);\n }\n }\n\n function populateLabels(instanceTemplateLabels, command) {\n if (instanceTemplateLabels) {\n Object.assign(command.labels, instanceTemplateLabels);\n\n if (command.labels['spinnaker-region']) {\n delete command.labels['spinnaker-region'];\n }\n\n if (command.labels['spinnaker-server-group']) {\n delete command.labels['spinnaker-server-group'];\n }\n\n // Need to delete the sequence, otherwise it won't increment\n if (command.labels['spinnaker-moniker-sequence']) {\n delete command.labels['spinnaker-moniker-sequence'];\n }\n }\n }\n\n function populateAuthScopes(serviceAccounts, command) {\n if (serviceAccounts && serviceAccounts.length) {\n command.serviceAccountEmail = serviceAccounts[0].email;\n command.authScopes = _.map(serviceAccounts[0].scopes, (authScope) => {\n return authScope.replace('https://www.googleapis.com/auth/', '');\n });\n } else {\n command.authScopes = [];\n }\n }\n\n function attemptToSetValidCredentials(application, defaultCredentials, command) {\n return AccountService.listAccounts('gce').then(function (gceAccounts) {\n const gceAccountNames = _.map(gceAccounts, 'name');\n const firstGCEAccount = gceAccountNames[0];\n\n const defaultCredentialsAreValid = defaultCredentials && gceAccountNames.includes(defaultCredentials);\n\n command.credentials = defaultCredentialsAreValid ? defaultCredentials : firstGCEAccount || 'my-account-name';\n });\n }\n\n function buildNewServerGroupCommand(application, defaults) {\n defaults = defaults || {};\n\n const defaultCredentials = defaults.account || GCEProviderSettings.defaults.account;\n const defaultRegion = defaults.region || GCEProviderSettings.defaults.region;\n const defaultZone = defaults.zone || GCEProviderSettings.defaults.zone;\n const associatePublicIpAddress = _.has(application, 'attributes.providerSettings.gce.associatePublicIpAddress')\n ? application.attributes.providerSettings.gce.associatePublicIpAddress\n : true;\n\n const command = {\n application: application.name,\n credentials: defaultCredentials,\n region: defaultRegion,\n zone: defaultZone,\n regional: false, // TODO(duftler): Externalize this default alongside defaultRegion and defaultZone.\n selectZones: false, // Explicitly select zones for regional server groups.\n distributionPolicy: { zones: [] },\n network: 'default',\n associatePublicIpAddress: associatePublicIpAddress,\n canIpForward: false,\n strategy: '',\n capacity: {\n min: 0,\n max: 0,\n desired: 1,\n },\n backendServiceMetadata: [],\n minCpuPlatform: '(Automatic)',\n disks: [\n { type: 'pd-ssd', sizeGb: 10 },\n { type: 'local-ssd', sizeGb: 375 },\n ],\n imageSource: 'priorStage',\n instanceMetadata: {},\n tags: [],\n labels: {},\n resourceManagerTags: {},\n enableSecureBoot: false,\n enableVtpm: false,\n enableIntegrityMonitoring: false,\n preemptible: false,\n automaticRestart: true,\n onHostMaintenance: 'MIGRATE',\n serviceAccountEmail: 'default',\n authScopes: ['cloud.useraccounts.readonly', 'devstorage.read_only', 'logging.write', 'monitoring.write'],\n enableTraffic: true,\n cloudProvider: 'gce',\n selectedProvider: 'gce',\n availabilityZones: [],\n viewState: {\n instanceProfile: 'custom',\n allImageSelection: null,\n useSimpleCapacity: true,\n usePreferredZones: true,\n listImplicitSecurityGroups: false,\n mode: defaults.mode || 'create',\n disableStrategySelection: true,\n expectedArtifacts: [],\n },\n };\n\n if (\n application.attributes &&\n application.attributes.platformHealthOnlyShowOverride &&\n application.attributes.platformHealthOnly\n ) {\n command.interestingHealthProviderNames = ['Google'];\n }\n\n return attemptToSetValidCredentials(application, defaultCredentials, command).then(() => command);\n }\n\n // Only used to prepare view requiring template selecting\n function buildNewServerGroupCommandForPipeline(currentStage, pipeline) {\n const expectedArtifacts = ExpectedArtifactService.getExpectedArtifactsAvailableToStage(currentStage, pipeline);\n return promiseService.resolve({\n viewState: {\n pipeline,\n expectedArtifacts: expectedArtifacts,\n requiresTemplateSelection: true,\n stage: currentStage,\n },\n });\n }\n\n function buildServerGroupCommandFromExisting(application, serverGroup, mode) {\n mode = mode || 'clone';\n const moniker = serverGroup.moniker;\n\n const command = {\n application: application.name,\n autoscalingPolicy: _.cloneDeep(serverGroup.autoscalingPolicy),\n strategy: '',\n stack: moniker.stack,\n freeFormDetails: moniker.detail,\n credentials: serverGroup.account,\n loadBalancers: extractLoadBalancers(serverGroup.asg),\n loadBalancerMetadata: extractLoadBalancerMetadata(serverGroup.asg),\n loadBalancingPolicy: _.cloneDeep(serverGroup.loadBalancingPolicy),\n backendServiceMetadata: serverGroup.asg['backend-service-names'],\n securityGroups: serverGroup.securityGroups,\n region: serverGroup.region,\n capacity: {\n min: serverGroup.asg.minSize,\n max: serverGroup.asg.maxSize,\n desired: serverGroup.asg.desiredCapacity,\n },\n regional: serverGroup.regional,\n network: extractNetworkName(serverGroup),\n subnet: extractSubnetName(serverGroup),\n associatePublicIpAddress: determineAssociatePublicIPAddress(serverGroup),\n canIpForward: serverGroup.canIpForward,\n minCpuPlatform: serverGroup.launchConfig.minCpuPlatform || '(Automatic)',\n instanceMetadata: {},\n tags: [],\n labels: {},\n resourceManagerTags: {},\n availabilityZones: [],\n enableSecureBoot: false,\n enableVtpm: false,\n enableIntegrityMonitoring: false,\n enableTraffic: true,\n cloudProvider: 'gce',\n selectedProvider: 'gce',\n distributionPolicy: {\n zones: serverGroup.distributionPolicy ? serverGroup.distributionPolicy.zones : [],\n targetShape: serverGroup.distributionPolicy ? serverGroup.distributionPolicy.targetShape : null,\n },\n // Preserve explicit empty policies while keeping absence distinct.\n instanceFlexibilityPolicy:\n serverGroup.instanceFlexibilityPolicy === undefined\n ? undefined\n : _.cloneDeep(serverGroup.instanceFlexibilityPolicy),\n selectZones: serverGroup.selectZones,\n source: {\n account: serverGroup.account,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n asgName: serverGroup.name,\n },\n viewState: {\n allImageSelection: null,\n useSimpleCapacity: !serverGroup.autoscalingPolicy,\n usePreferredZones: false,\n listImplicitSecurityGroups: false,\n mode: mode,\n },\n };\n\n populateShieldedVmConfig(serverGroup, command);\n\n if (!command.regional) {\n command.zone = serverGroup.zones[0];\n command.source.zone = serverGroup.zones[0];\n }\n\n if (\n application.attributes &&\n application.attributes.platformHealthOnlyShowOverride &&\n application.attributes.platformHealthOnly\n ) {\n command.interestingHealthProviderNames = ['Google'];\n }\n\n populateAutoHealingPolicy(serverGroup, command);\n\n if (serverGroup.launchConfig) {\n const instanceType = serverGroup.launchConfig.instanceType;\n Object.assign(command, {\n instanceType: instanceType,\n });\n\n if (_.includes(instanceType, 'custom-')) {\n command.viewState.customInstance = gceCustomInstanceBuilderService.parseInstanceTypeString(instanceType);\n command.viewState.instanceProfile = 'buildCustom';\n }\n\n command.viewState.imageId = serverGroup.launchConfig.imageId;\n return determineInstanceCategoryFromInstanceType(command).then(function () {\n populateAvailabilityPolicies(serverGroup.launchConfig.instanceTemplate.properties.scheduling, command);\n populateCustomMetadata(serverGroup.launchConfig.instanceTemplate.properties.metadata.items, command);\n populateTags(serverGroup.launchConfig.instanceTemplate.properties.tags, command);\n populateLabels(serverGroup.instanceTemplateLabels, command);\n populateAuthScopes(serverGroup.launchConfig.instanceTemplate.properties.serviceAccounts, command);\n populateResourceManagerTags(\n serverGroup.launchConfig.instanceTemplate.properties.resourceManagerTags,\n command,\n );\n\n return populateDisksFromExisting(serverGroup.launchConfig.instanceTemplate.properties.disks, command).then(\n function () {\n return command;\n },\n );\n });\n }\n\n return promiseService.resolve(command);\n }\n\n function buildServerGroupCommandFromPipeline(application, originalCluster, currentStage, pipeline) {\n const pipelineCluster = _.cloneDeep(originalCluster);\n const region = Object.keys(pipelineCluster.availabilityZones)[0];\n const zone = pipelineCluster.zone;\n const instanceTypeCategoryLoader = instanceTypeService.getCategoryForInstanceType(\n 'gce',\n pipelineCluster.instanceType,\n );\n\n const commandOptions = { account: pipelineCluster.account, region: region, zone: zone };\n return promiseService\n .all([buildNewServerGroupCommand(application, commandOptions), instanceTypeCategoryLoader])\n .then(function ([command, instanceProfile]) {\n const expectedArtifacts = ExpectedArtifactService.getExpectedArtifactsAvailableToStage(\n currentStage,\n pipeline,\n );\n const viewState = {\n pipeline,\n stage: currentStage,\n instanceProfile,\n disableImageSelection: true,\n expectedArtifacts: expectedArtifacts,\n showImageSourceSelector: true,\n useSimpleCapacity: !pipelineCluster.autoscalingPolicy,\n mode: 'editPipeline',\n submitButtonLabel: 'Done',\n customInstance:\n instanceProfile === 'buildCustom'\n ? gceCustomInstanceBuilderService.parseInstanceTypeString(pipelineCluster.instanceType)\n : null,\n templatingEnabled: true,\n };\n\n const viewOverrides = {\n region: region,\n credentials: pipelineCluster.account,\n enableTraffic: !pipelineCluster.disableTraffic,\n viewState: viewState,\n };\n\n pipelineCluster.strategy = pipelineCluster.strategy || '';\n\n const extendedCommand = Object.assign({}, command, pipelineCluster, viewOverrides);\n // Older saved pipeline payloads may still include partnerMetadata. Do not propagate it\n // into deploy/clone commands that eventually create stable Compute v1 instance templates.\n delete extendedCommand.partnerMetadata;\n\n return populateDisksFromPipeline(extendedCommand).then(function () {\n const instanceMetadata = extendedCommand.instanceMetadata;\n extendedCommand.loadBalancers = extractLoadBalancersFromMetadata(instanceMetadata);\n extendedCommand.loadBalancerMetadata = extractLoadBalancerMetadata(instanceMetadata);\n extendedCommand.backendServiceMetadata = instanceMetadata['backend-service-names']\n ? instanceMetadata['backend-service-names'].split(',')\n : [];\n extendedCommand.minCpuPlatform = pipelineCluster.minCpuPlatform || '(Automatic)';\n extendedCommand.instanceMetadata = {};\n populateCustomMetadata(instanceMetadata, extendedCommand);\n populateAutoHealingPolicy(pipelineCluster, extendedCommand);\n populateShieldedVmConfig(pipelineCluster, extendedCommand);\n\n const instanceTemplateTags = { items: extendedCommand.tags };\n extendedCommand.tags = [];\n populateTags(instanceTemplateTags, extendedCommand);\n\n const resourceManagerTags = extendedCommand.resourceManagerTags;\n populateResourceManagerTags(resourceManagerTags, extendedCommand);\n\n return extendedCommand;\n });\n });\n }\n\n return {\n buildNewServerGroupCommand: buildNewServerGroupCommand,\n buildNewServerGroupCommandForPipeline: buildNewServerGroupCommandForPipeline,\n buildServerGroupCommandFromExisting: buildServerGroupCommandFromExisting,\n buildServerGroupCommandFromPipeline: buildServerGroupCommandFromPipeline,\n };\n }\n}\n","import { get, intersectionBy, isFinite } from 'lodash';\n\nexport interface IGceAcceleratorTypeRaw {\n name: string;\n description: string;\n maximumCardsPerInstance: number;\n}\n\nexport interface IGceAcceleratorType extends IGceAcceleratorTypeRaw {\n availableCardCounts: number[];\n}\n\ninterface IZoneToAcceleratorTypesMap {\n [zone: string]: IGceAcceleratorTypeRaw[];\n}\n\nexport interface IGceAcceleratorCommand {\n backingData: any;\n credentials: string;\n distributionPolicy: { zones: string[]; targetShape?: string };\n regional: boolean;\n selectZones: boolean;\n zone: string;\n}\n\nexport class GceAcceleratorService {\n public static getAvailableAccelerators({\n backingData,\n credentials,\n distributionPolicy,\n regional,\n selectZones,\n zone,\n }: IGceAcceleratorCommand): IGceAcceleratorType[] {\n const acceleratorMap = this.getZoneToAcceleratorTypesMap(backingData, credentials);\n\n if (zone && !regional) {\n return this.getAcceleratorTypesForZone(acceleratorMap, zone);\n }\n\n if (regional && selectZones) {\n const zones = get(distributionPolicy, 'zones', []);\n const allZonesAcceleratorTypes = zones.map((z) => this.getAcceleratorTypesForZone(acceleratorMap, z));\n return intersectionBy.apply(null, [...allZonesAcceleratorTypes, 'name']);\n }\n\n return [];\n }\n\n private static getZoneToAcceleratorTypesMap(backingData: any, credentials: string): IZoneToAcceleratorTypesMap {\n return get(backingData, ['credentialsKeyedByAccount', credentials, 'zoneToAcceleratorTypesMap'], {});\n }\n\n private static getAcceleratorTypesForZone(\n acceleratorMap: IZoneToAcceleratorTypesMap,\n zone: string,\n ): IGceAcceleratorType[] {\n return get(acceleratorMap, [zone, 'acceleratorTypes', 'acceleratorTypes'], []).map((a) => {\n return {\n ...a,\n availableCardCounts: this.getAvailableCardCounts(a),\n };\n });\n }\n\n private static getAvailableCardCounts(accelerator: IGceAcceleratorTypeRaw): number[] {\n const maxCards = isFinite(accelerator.maximumCardsPerInstance) ? accelerator.maximumCardsPerInstance : 4;\n const availableCardCounts = [];\n for (let i = 1; i <= maxCards; i *= 2) {\n availableCardCounts.push(i);\n }\n return availableCardCounts;\n }\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { FirewallLabels } from '@spinnaker/core';\n\nexport class GceTagManager {\n constructor() {\n const resetKeys = ['command', 'securityGroups', 'securityGroupObjectsKeyedByTag', 'securityGroupObjectsKeyedById'];\n\n this.reset = () => {\n resetKeys.forEach((key) => delete this[key]);\n };\n\n this.register = (command) => {\n this.command = command;\n const { credentials, backingData } = command;\n if (backingData.securityGroups[credentials] !== undefined) {\n this.securityGroupObjects = _.cloneDeep(backingData.securityGroups[credentials].gce.global);\n\n initializeSecurityGroupObjects(this.securityGroupObjects, command.tags);\n\n const { byTag, bySecurityGroupId } = groupSecurityGroupObjects(this.securityGroupObjects);\n this.securityGroupObjectsKeyedByTag = byTag;\n this.securityGroupObjectsKeyedById = bySecurityGroupId;\n }\n\n if (!command.securityGroups) {\n command.securityGroups = this.inferSecurityGroupIdsFromTags(command.tags);\n }\n };\n\n this.inferSecurityGroupIdsFromTags = (commandTags = []) => {\n return _.chain(commandTags)\n .map((t) => this.securityGroupObjectsKeyedByTag[t.value])\n .flatten()\n .compact()\n .filter((sg) => sg.network === this.command.network)\n .map('id')\n .uniq()\n .value();\n };\n\n const initializeSecurityGroupObjects = (securityGroupObjects, commandTags = []) => {\n securityGroupObjects.forEach((sg) => {\n // Raw target tags look like '[tag-a, tag-b]'.\n const rawTags = sg.targetTags;\n sg.tagsArray = rawTags ? rawTags.substring(1, rawTags.length - 1).split(', ') : [];\n\n sg.selectedTags = commandTags\n ? _.intersection(\n commandTags.map((t) => t.value),\n sg.tagsArray,\n )\n : [];\n });\n };\n\n const groupSecurityGroupObjects = (securityGroupObjects) => {\n return securityGroupObjects.reduce(\n (groupings, sg) => {\n const { bySecurityGroupId } = groupings;\n bySecurityGroupId[sg.id] = sg;\n\n return sg.tagsArray.reduce((groupings, tag) => {\n const { byTag } = groupings;\n if (!byTag[tag]) {\n byTag[tag] = [];\n }\n byTag[tag].push(sg);\n\n return groupings;\n }, groupings);\n },\n { byTag: {}, bySecurityGroupId: {} },\n );\n };\n\n this.inferSelectedSecurityGroupFromTag = _.debounce((tagName) => {\n let securityGroupObjectsWithTag = this.securityGroupObjectsKeyedByTag[tagName];\n const c = this.command;\n\n if (securityGroupObjectsWithTag) {\n securityGroupObjectsWithTag = _.filter(\n securityGroupObjectsWithTag,\n (sg) => sg.network === this.command.network,\n );\n }\n\n if (securityGroupObjectsWithTag) {\n updateSelectedTagsOnSecurityGroupObjects(securityGroupObjectsWithTag, tagName);\n c.securityGroups = _.map(\n updateSelectedSecurityGroups(getSecurityGroupObjectsFromIds(c.securityGroups), securityGroupObjectsWithTag),\n 'id',\n );\n }\n\n // If you pause while typing \"tag-a,\" but you really want to add \"tag-abc,\"\n // make sure you remove \"tag-a\".\n this.updateSelectedTags();\n }, 100);\n\n this.updateSelectedTags = () => {\n const c = this.command;\n const tags = c.tags.map((t) => t.value);\n\n getSecurityGroupObjectsFromIds(c.securityGroups).forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = _.intersection(sg.selectedTags, tags);\n }\n\n if (!_.get(sg, 'selectedTags.length')) {\n c.securityGroups = _.without(c.securityGroups, sg.id);\n }\n });\n };\n\n this.addTag = (tagName) => {\n const c = this.command;\n const tags = c.tags;\n let securityGroupObjectsWithTag = this.securityGroupObjectsKeyedByTag[tagName];\n\n if (securityGroupObjectsWithTag) {\n securityGroupObjectsWithTag = _.filter(\n securityGroupObjectsWithTag,\n (sg) => sg.network === this.command.network,\n );\n }\n\n if (\n !_.includes(\n tags.map((t) => t.value),\n tagName,\n )\n ) {\n tags.push({ value: tagName });\n }\n\n if (securityGroupObjectsWithTag) {\n updateSelectedTagsOnSecurityGroupObjects(securityGroupObjectsWithTag, tagName);\n c.securityGroups = _.map(\n updateSelectedSecurityGroups(getSecurityGroupObjectsFromIds(c.securityGroups), securityGroupObjectsWithTag),\n 'id',\n );\n }\n };\n\n const getSecurityGroupObjectsFromIds = (ids) => ids.map((id) => this.securityGroupObjectsKeyedById[id]);\n\n const updateSelectedTagsOnSecurityGroupObjects = (securityGroupObjects, newTag) => {\n securityGroupObjects.forEach((sg) => {\n sg.selectedTags = _.chain(sg.selectedTags || [])\n .concat([newTag])\n .uniq()\n .value();\n });\n };\n\n const updateSelectedSecurityGroups = (oldGroups, newGroups) => {\n return _.chain(oldGroups).concat(newGroups).uniq().value();\n };\n\n this.removeTag = (tagName) => {\n const c = this.command;\n const securityGroupIds = c.securityGroups || [];\n const securityGroupObjects = getSecurityGroupObjectsFromIds(securityGroupIds);\n\n securityGroupObjects.forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = sg.selectedTags.filter((tag) => tag !== tagName);\n }\n });\n\n c.tags = c.tags.filter((tag) => tag.value !== tagName);\n };\n\n this.removeSecurityGroup = (securityGroupId) => {\n const securityGroupObject = this.securityGroupObjectsKeyedById[securityGroupId];\n const tagsToRemove = securityGroupObject.selectedTags;\n const c = this.command;\n\n getSecurityGroupObjectsFromIds(c.securityGroups).forEach((sg) => {\n if (sg.selectedTags) {\n sg.selectedTags = _.difference(sg.selectedTags, tagsToRemove);\n }\n });\n\n securityGroupObject.selectedTags = [];\n c.tags = _.chain(c.tags)\n .map((t) => t.value)\n .difference(tagsToRemove)\n .map((t) => ({ value: t }))\n .value();\n };\n\n this.getToolTipContent = (tagName) => {\n const groups = _.get(this, ['securityGroupObjectsKeyedByTag', tagName]);\n const groupIds = groups ? groups.filter((sg) => sg.network === this.command.network).map((sg) => sg.id) : [];\n\n return `This tag associates this server group with ${\n groupIds.length > 1 ? FirewallLabels.get('firewalls') : FirewallLabels.get('firewall')\n }\n <em>${groupIds.join(', ')}</em>.`;\n };\n\n this.showToolTip = (tagName) => {\n return !!_.get(this, ['securityGroupObjectsKeyedByTag', tagName]);\n };\n\n return this;\n }\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { AccountService, InfrastructureCaches, NetworkReader, SubnetReader } from '@spinnaker/core';\n\nimport { GCEProviderSettings } from '../../gce.settings';\nimport { GceHealthCheckReader } from '../../healthCheck/healthCheck.read.service';\nimport { getHealthCheckOptions } from '../../healthCheck/healthCheckUtils';\nimport { GceImageReader } from '../../image';\nimport { GceCustomInstanceBuilderService } from './../../instance/custom/customInstanceBuilder.gce.service';\nimport { GceInstanceTypeService } from '../../instance/gceInstanceType.service';\nimport { GceHttpLoadBalancerUtils } from '../../loadBalancer/httpLoadBalancerUtils.service';\nimport { GceLoadBalancerSetTransformer } from '../../loadBalancer/loadBalancer.setTransformer';\nimport { GceAcceleratorService } from './wizard/advancedSettings/gceAccelerator.service';\nimport { GceTagManager } from './wizard/securityGroups/tagManager.service';\n\nexport const GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE =\n 'spinnaker.serverGroup.configure.gce.configuration.service';\nexport const name = GOOGLE_SERVERGROUP_CONFIGURE_SERVERGROUPCONFIGURATION_SERVICE; // for backwards compatibility\n// EVEN remains for non-flex regional MIGs. Flexibility requires BALANCED, ANY, or ANY_SINGLE_ZONE.\nexport const GCE_DISTRIBUTION_POLICY_TARGET_SHAPES = ['ANY', 'EVEN', 'BALANCED', 'ANY_SINGLE_ZONE'];\nexport class GceServerGroupConfigurationService {\n static requiresDeckRuntimeServices = true;\n\n constructor(\n promiseService = { all: (values) => Promise.all(values), resolve: (value) => Promise.resolve(value) },\n runtimeServices,\n ) {\n const securityGroupReader = runtimeServices.securityGroupReader;\n const loadBalancerReader = runtimeServices.loadBalancerReader;\n const gceInstanceTypeService = new GceInstanceTypeService(promiseService);\n const gceCustomInstanceBuilderService = new GceCustomInstanceBuilderService();\n const gceHttpLoadBalancerUtils = new GceHttpLoadBalancerUtils();\n const gceHealthCheckReader = new GceHealthCheckReader();\n const gceTagManager = new GceTagManager();\n const gceLoadBalancerSetTransformer = new GceLoadBalancerSetTransformer();\n const persistentDiskTypes = ['pd-standard', 'pd-ssd', 'hyperdisk-balanced'];\n const authScopes = [\n 'cloud-platform',\n 'userinfo.email',\n 'compute.readonly',\n 'compute',\n 'cloud.useraccounts.readonly',\n 'cloud.useraccounts',\n 'devstorage.read_only',\n 'devstorage.write_only',\n 'devstorage.full_control',\n 'taskqueue',\n 'bigquery',\n 'sqlservice.admin',\n 'datastore',\n 'logging.write',\n 'logging.read',\n 'logging.admin',\n 'monitoring.write',\n 'monitoring.read',\n 'monitoring',\n 'bigtable.data.readonly',\n 'bigtable.data',\n 'bigtable.admin',\n 'bigtable.admin.table',\n ];\n\n function configureCommand(application, command) {\n return promiseService\n .all([\n AccountService.getCredentialsKeyedByAccount('gce'),\n securityGroupReader.getAllSecurityGroups(),\n NetworkReader.listNetworksByProvider('gce'),\n SubnetReader.listSubnetsByProvider('gce'),\n loadBalancerReader.listLoadBalancers('gce'),\n loadAllImages(command.credentials),\n gceInstanceTypeService.getAllTypesByRegion(),\n promiseService.resolve(_.cloneDeep(persistentDiskTypes)),\n promiseService.resolve(_.cloneDeep(authScopes)),\n gceHealthCheckReader.listHealthChecks(),\n AccountService.listAccounts('gce'),\n ])\n .then(function ([\n credentialsKeyedByAccount,\n securityGroups,\n networks,\n subnets,\n loadBalancers,\n allImages,\n instanceTypes,\n persistentDiskTypes,\n authScopes,\n healthChecks,\n accounts,\n ]) {\n const backingData = {\n credentialsKeyedByAccount,\n securityGroups,\n networks,\n subnets,\n loadBalancers,\n allImages,\n instanceTypes,\n persistentDiskTypes,\n authScopes,\n healthChecks,\n accounts,\n };\n let securityGroupReloader = promiseService.resolve(null);\n let networkReloader = promiseService.resolve(null);\n let healthCheckReloader = promiseService.resolve(null);\n backingData.filtered = {};\n backingData.distributionPolicyTargetShapes = getDistributionPolicyTargetShapes();\n command.backingData = backingData;\n configureImages(command);\n\n if (command.securityGroups && command.securityGroups.length) {\n // Verify all firewalls are accounted for; otherwise, try refreshing firewalls cache.\n const securityGroupIds = _.map(getSecurityGroups(command), 'id');\n if (_.intersection(command.securityGroups, securityGroupIds).length < command.securityGroups.length) {\n securityGroupReloader = refreshSecurityGroups(command, true);\n }\n }\n if (command.network) {\n // Verify network is accounted for; otherwise, try refreshing networks cache.\n const networkNames = getNetworkNames(command);\n if (!networkNames.includes(command.network)) {\n networkReloader = refreshNetworks(command);\n }\n }\n\n if (command.autoScalingPolicy) {\n command.enableAutoScaling = true;\n }\n\n if (command.autoHealingPolicy) {\n command.enableAutoHealing = true;\n }\n if (_.has(command, 'autoHealingPolicy.healthCheck')) {\n // Verify health check is accounted for; otherwise, try refreshing health checks cache.\n const healthChecks = getHealthChecks(command);\n if (!_.chain(healthChecks).map('selfLink').includes(command.autoHealingPolicy.healthCheckUrl).value()) {\n healthCheckReloader = refreshHealthChecks(command, true);\n }\n }\n\n return promiseService.all([securityGroupReloader, networkReloader, healthCheckReloader]).then(() => {\n gceTagManager.register(command);\n attachEventHandlers(command);\n });\n });\n }\n\n function getDistributionPolicyTargetShapes() {\n // EVEN remains for non-flex regional MIGs. Flexibility requires BALANCED, ANY, or\n // ANY_SINGLE_ZONE (enforced in the configurer and clone validation).\n return GCE_DISTRIBUTION_POLICY_TARGET_SHAPES.slice();\n }\n\n function configureDistributionPolicyTargetShape(command) {\n const accountDetails = command.backingData.credentialsKeyedByAccount[command.credentials];\n if (!command.distributionPolicy.targetShape) {\n command.distributionPolicy.targetShape = 'EVEN';\n }\n }\n\n function loadAllImages(account) {\n return GceImageReader.findImages({\n account: account,\n provider: 'gce',\n q: '*',\n });\n }\n\n function configureInstanceTypes(command) {\n const result = { dirty: {} };\n if (command.region) {\n const results = [result.dirty];\n\n results.push(configureCustomInstanceTypes(command).dirty);\n results.push(configureStandardInstanceTypes(command).dirty);\n\n Object.assign(...results);\n } else {\n command.backingData.filtered.instanceTypes = [];\n }\n return result;\n }\n\n function configureCpuPlatforms(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n const locationToCpuPlatformsMap =\n command.backingData.credentialsKeyedByAccount[command.credentials].locationToCpuPlatformsMap;\n\n filteredData.cpuPlatforms = ['(Automatic)'];\n\n const location = command.regional ? command.region : command.zone;\n\n if (_.has(locationToCpuPlatformsMap, location)) {\n filteredData.cpuPlatforms = _.concat(filteredData.cpuPlatforms, locationToCpuPlatformsMap[location]);\n }\n\n if (!_.includes(filteredData.cpuPlatforms, command.minCpuPlatform)) {\n delete command.minCpuPlatform;\n result.dirty.minCpuPlatform = true;\n }\n return result;\n }\n\n function configureStandardInstanceTypes(command) {\n const c = command;\n const result = { dirty: {} };\n\n const locations = c.regional ? c.distributionPolicy.zones : [c.zone];\n const { credentialsKeyedByAccount } = c.backingData;\n const { locationToInstanceTypesMap } = credentialsKeyedByAccount[c.credentials];\n\n if (locations.every((l) => !l)) {\n return result;\n }\n\n let filtered = gceInstanceTypeService.getAvailableTypesForLocations(locationToInstanceTypesMap, locations);\n\n filtered = sortInstanceTypes(filtered);\n const instanceType = c.instanceType;\n if (_.every([instanceType, !_.includes(instanceType, 'custom-'), !_.includes(filtered, instanceType)])) {\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n c.backingData.filtered.instanceTypes = filtered;\n return result;\n }\n\n function configureCustomInstanceTypes(command) {\n const c = command;\n const result = { dirty: {} };\n let vCpuCount = _.get(c, 'viewState.customInstance.vCpuCount');\n const instanceFamily = _.get(c, 'viewState.customInstance.instanceFamily');\n const memory = _.get(c, 'viewState.customInstance.memory');\n const extendedMemory = _.get(c, 'viewState.customInstance.extendedMemory');\n const { zone, regional, region } = c;\n const { locationToInstanceTypesMap } = c.backingData.credentialsKeyedByAccount[c.credentials];\n const location = regional ? region : zone;\n\n if (!location) {\n return result;\n }\n\n if (zone || regional) {\n _.set(\n c,\n 'backingData.customInstanceTypes.vCpuList',\n gceCustomInstanceBuilderService.generateValidVCpuListForLocation(location, locationToInstanceTypesMap),\n );\n }\n\n // initializes vCpuCount so that memory selector will be populated.\n if (\n !vCpuCount ||\n !gceCustomInstanceBuilderService.vCpuCountForLocationIsValid(\n instanceFamily,\n vCpuCount,\n location,\n locationToInstanceTypesMap,\n )\n ) {\n vCpuCount = _.get(c, 'backingData.customInstanceTypes.vCpuList[0]');\n _.set(c, 'viewState.customInstance.vCpuCount', vCpuCount);\n }\n\n _.set(\n c,\n 'backingData.customInstanceTypes.memoryList',\n gceCustomInstanceBuilderService.generateValidMemoryListForVCpuCount(instanceFamily, vCpuCount),\n );\n\n if (\n _.every([\n memory,\n vCpuCount,\n !gceCustomInstanceBuilderService.memoryIsValid(instanceFamily, memory, vCpuCount, extendedMemory),\n ])\n ) {\n _.set(c, 'viewState.customInstance.memory', undefined);\n result.dirty.instanceType = c.instanceType;\n c.instanceType = null;\n }\n\n _.set(\n c,\n 'backingData.customInstanceTypes.instanceFamilyList',\n gceCustomInstanceBuilderService.generateValidInstanceFamilyList(),\n );\n\n return result;\n }\n\n function configureAccelerators(command) {\n const result = { dirty: {} };\n const acceleratorTypes = GceAcceleratorService.getAvailableAccelerators(command);\n _.set(command, ['viewState', 'acceleratorTypes'], acceleratorTypes);\n result.dirty.acceleratorTypes = true;\n const chosenAccelerators = _.get(command, 'acceleratorConfigs', []);\n if (chosenAccelerators.length > 0) {\n command.acceleratorConfigs = chosenAccelerators.filter(\n (chosen) => !!acceleratorTypes.find((a) => a.name === chosen.acceleratorType),\n );\n if (command.acceleratorConfigs.length === 0) {\n delete command.acceleratorConfigs;\n }\n }\n return result;\n }\n\n // n1-standard-8 should come before n1-standard-16, so we must sort by the individual segments of the names.\n function sortInstanceTypes(instanceTypes) {\n const tokenizedInstanceTypes = _.map(instanceTypes, (instanceType) => {\n const tokens = instanceType.split('-');\n\n return {\n class: tokens[0],\n group: tokens[1],\n index: Number(tokens[2]) || 0,\n };\n });\n\n const sortedTokenizedInstanceTypes = _.sortBy(tokenizedInstanceTypes, ['class', 'group', 'index']);\n\n return _.map(sortedTokenizedInstanceTypes, (sortedTokenizedInstanceType) => {\n return (\n sortedTokenizedInstanceType.class +\n '-' +\n sortedTokenizedInstanceType.group +\n (sortedTokenizedInstanceType.index ? '-' + sortedTokenizedInstanceType.index : '')\n );\n });\n }\n\n function configureImages(command) {\n command.image = command.viewState.imageId;\n const result = { dirty: {} };\n if (command.credentials !== command.viewState.lastImageAccount) {\n command.viewState.lastImageAccount = command.credentials;\n if (!_.chain(command.backingData.allImages).find({ imageName: command.image }).value()) {\n command.image = null;\n result.dirty.imageName = true;\n }\n }\n return result;\n }\n\n function configureZones(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (command.region === null) {\n return result;\n }\n const regions = command.backingData.credentialsKeyedByAccount[command.credentials].regions;\n if (_.isArray(regions)) {\n filteredData.zones = _.find(regions, { name: command.region }).zones;\n filteredData.truncatedZones = _.takeRight(filteredData.zones.sort(), 3);\n } else {\n // TODO(duftler): Remove this once we finish deprecating the old style regions/zones in clouddriver GCE credentials.\n filteredData.zones = regions[command.region];\n }\n if (!_.chain(filteredData.zones).includes(command.zone).value()) {\n delete command.zone;\n if (!command.regional) {\n result.dirty.zone = true;\n }\n }\n return result;\n }\n\n function getHealthChecks(command) {\n const matchingHealthChecks = _.filter(command.backingData.healthChecks, { account: command.credentials });\n return getHealthCheckOptions(matchingHealthChecks);\n }\n\n function configureHealthChecks(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n\n if (command.credentials === null) {\n return result;\n }\n\n filteredData.healthChecks = getHealthChecks(command);\n\n if (\n _.has(command, 'autoHealingPolicy.healthCheck') &&\n !_.chain(filteredData.healthChecks).map('selfLink').includes(command.autoHealingPolicy.healthCheckUrl).value()\n ) {\n delete command.autoHealingPolicy.healthCheck;\n result.dirty.autoHealingPolicy = true;\n } else {\n result.dirty.autoHealingPolicy = null;\n }\n\n return result;\n }\n\n function getLoadBalancers(command) {\n return _.chain(command.backingData.loadBalancers)\n .map('accounts')\n .flattenDeep()\n .filter({ name: command.credentials })\n .map('regions')\n .flattenDeep()\n .map('loadBalancers')\n .flattenDeep()\n .filter(_.curry(isRelevantLoadBalancer)(command))\n .uniq()\n .value();\n }\n\n function isRelevantLoadBalancer(command, loadBalancer) {\n return loadBalancer.region === command.region || loadBalancer.region === 'global';\n }\n\n function configureLoadBalancerOptions(command) {\n const results = { dirty: {} };\n const current = command.loadBalancers;\n const newLoadBalancerObjects = gceLoadBalancerSetTransformer.normalizeLoadBalancerSet(getLoadBalancers(command));\n command.backingData.filtered.loadBalancerIndex = _.keyBy(newLoadBalancerObjects, 'name');\n command.backingData.filtered.loadBalancers = _.map(newLoadBalancerObjects, 'name');\n\n if (current && command.loadBalancers) {\n command.loadBalancers = gceHttpLoadBalancerUtils.normalizeLoadBalancerNamesForAccount(\n command.loadBalancers,\n command.credentials,\n newLoadBalancerObjects,\n );\n const matched = _.intersection(command.backingData.filtered.loadBalancers, command.loadBalancers);\n const removed = _.xor(matched, command.loadBalancers);\n command.loadBalancers = matched;\n configureBackendServiceOptions(command);\n\n if (removed.length) {\n results.dirty.loadBalancers = removed;\n }\n }\n return results;\n }\n\n function configureBackendServiceOptions(command) {\n /*\n a server group has a list of backend services, but there's no mapping from l7 -> backend service\n for the server group. this will not populate the wizard perfectly,\n but it is the best we can do with the given data.\n */\n\n const backendsFromMetadata = command.backendServiceMetadata;\n const lbIndex = command.backingData.filtered.loadBalancerIndex;\n\n const backendServices = command.loadBalancers.reduce((backendServices, lbName) => {\n if (gceHttpLoadBalancerUtils.isHttpLoadBalancer(lbIndex[lbName])) {\n backendServices[lbName] = _.intersection(lbIndex[lbName].backendServices, backendsFromMetadata);\n }\n return backendServices;\n }, {});\n\n if (Object.keys(backendServices).length > 0) {\n command.backendServices = backendServices;\n }\n }\n\n function refreshLoadBalancers(command, skipCommandReconfiguration) {\n return loadBalancerReader.listLoadBalancers('gce').then(function (loadBalancers) {\n command.backingData.loadBalancers = loadBalancers;\n if (!skipCommandReconfiguration) {\n configureLoadBalancerOptions(command);\n }\n });\n }\n\n function refreshHealthChecks(command, skipCommandReconfiguration) {\n InfrastructureCaches.clearCache('healthChecks');\n return gceHealthCheckReader.listHealthChecks().then(function (healthChecks) {\n command.backingData.healthChecks = healthChecks;\n if (!skipCommandReconfiguration) {\n configureHealthChecks(command);\n }\n });\n }\n\n function configureSubnets(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n if (command.region === null) {\n return result;\n }\n filteredData.subnets = _.chain(command.backingData.subnets)\n .filter({ account: command.credentials, network: command.network, region: command.region })\n .map('id')\n .value();\n\n if (!_.chain(filteredData.subnets).includes(command.subnet).value()) {\n command.subnet = '';\n result.dirty.subnet = true;\n }\n return result;\n }\n\n function getSecurityGroups(command) {\n let newSecurityGroups = command.backingData.securityGroups[command.credentials] || { gce: {} };\n newSecurityGroups = _.filter(newSecurityGroups.gce.global, function (securityGroup) {\n return securityGroup.network === command.network;\n });\n return _.chain(newSecurityGroups).sortBy('name').value();\n }\n\n function getXpnHostProjectIfAny(network) {\n if (network && network.includes('/')) {\n return network.split('/')[0] + '/';\n } else {\n return '';\n }\n }\n\n function configureSecurityGroupOptions(command) {\n const results = { dirty: {} };\n const currentOptions = command.backingData.filtered.securityGroups;\n const newSecurityGroups = getSecurityGroups(command);\n if (currentOptions && command.securityGroups) {\n // not initializing - we are actually changing groups\n const currentGroupNames = command.securityGroups.map(function (groupId) {\n const match = _.chain(currentOptions).find({ id: groupId }).value();\n return match ? match.id : groupId;\n });\n const matchedGroups = command.securityGroups\n .map(function (groupId) {\n const securityGroup = _.chain(currentOptions).find({ id: groupId }).value();\n return securityGroup ? securityGroup.id : null;\n })\n .map(function (groupName) {\n return _.chain(newSecurityGroups).find({ id: groupName }).value();\n })\n .filter(function (group) {\n return group;\n });\n command.securityGroups = _.map(matchedGroups, 'id');\n const removed = _.xor(currentGroupNames, command.securityGroups);\n if (removed.length) {\n results.dirty.securityGroups = removed;\n }\n }\n\n // Only include explicit firewall options in the pulldown list.\n command.backingData.filtered.securityGroups = _.filter(newSecurityGroups, function (securityGroup) {\n return !_.isEmpty(securityGroup.targetTags);\n });\n\n // Identify implicit firewalls so they can be optionally listed in a read-only state.\n command.implicitSecurityGroups = _.filter(newSecurityGroups, function (securityGroup) {\n return _.isEmpty(securityGroup.targetTags);\n });\n\n // Only include explicitly-selected firewalls in the body of the command.\n const xpnHostProject = getXpnHostProjectIfAny(command.network);\n const decoratedSecurityGroups = _.map(command.securityGroups, (sg) =>\n !sg.startsWith(xpnHostProject) ? xpnHostProject + sg : sg,\n );\n command.securityGroups = _.difference(decoratedSecurityGroups, _.map(command.implicitSecurityGroups, 'id'));\n\n return results;\n }\n\n function refreshSecurityGroups(command, skipCommandReconfiguration) {\n InfrastructureCaches.clearCache('securityGroups');\n return securityGroupReader.getAllSecurityGroups().then(function (securityGroups) {\n command.backingData.securityGroups = securityGroups;\n if (!skipCommandReconfiguration) {\n configureSecurityGroupOptions(command);\n }\n });\n }\n\n function getNetworkNames(command) {\n return _.map(_.filter(command.backingData.networks, { account: command.credentials }), 'id');\n }\n\n function refreshNetworks(command) {\n NetworkReader.listNetworksByProvider('gce').then(function (gceNetworks) {\n command.backingData.networks = gceNetworks;\n });\n }\n\n function refreshInstanceTypes(command) {\n InfrastructureCaches.clearCache('instanceTypes');\n return gceInstanceTypeService.getAllTypesByRegion().then(function (instanceTypes) {\n command.backingData.instanceTypes = instanceTypes;\n configureInstanceTypes(command);\n });\n }\n\n function attachEventHandlers(cmd) {\n cmd.regionalChanged = function regionalChanged(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n const defaults = GCEProviderSettings.defaults;\n if (command.regional) {\n command.zone = null;\n configureDistributionPolicyTargetShape(command);\n } else if (!command.zone) {\n if (command.region === defaults.region) {\n command.zone = defaults.zone;\n } else {\n command.zone = filteredData.zones[0];\n }\n\n Object.assign(result.dirty, configureZones(command).dirty);\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n return result;\n };\n\n cmd.regionChanged = function regionChanged(command) {\n const result = { dirty: {} };\n const filteredData = command.backingData.filtered;\n Object.assign(result.dirty, configureSubnets(command).dirty);\n if (command.region) {\n Object.assign(result.dirty, configureInstanceTypes(command).dirty);\n Object.assign(result.dirty, configureZones(command).dirty);\n Object.assign(result.dirty, configureCpuPlatforms(command).dirty);\n // TODO: Internal Load Balancers also need to be filtered by network.\n Object.assign(result.dirty, configureLoadBalancerOptions(command).dirty);\n Object.assign(result.dirty, configureImages(command).dirty);\n } else {\n filteredData.zones = null;\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n return result;\n };\n\n cmd.credentialsChanged = function credentialsChanged(command) {\n const result = { dirty: {} };\n const backingData = command.backingData;\n if (command.credentials) {\n const regions = backingData.credentialsKeyedByAccount[command.credentials].regions;\n if (_.isArray(regions)) {\n backingData.filtered.regions = _.map(regions, 'name');\n } else {\n // TODO(duftler): Remove this once we finish deprecating the old style regions/zones in clouddriver GCE credentials.\n backingData.filtered.regions = _.keys(regions);\n }\n if (!backingData.filtered.regions.includes(command.region)) {\n command.region = null;\n result.dirty.region = true;\n } else {\n Object.assign(result.dirty, command.regionChanged(command).dirty);\n }\n\n backingData.filtered.networks = getNetworkNames(command);\n if (!backingData.filtered.networks.includes(command.network)) {\n command.network = null;\n result.dirty.network = true;\n } else {\n Object.assign(result.dirty, command.networkChanged(command).dirty);\n }\n\n Object.assign(result.dirty, configureHealthChecks(command).dirty);\n Object.assign(result.dirty, configureInstanceTypes(command).dirty);\n\n configureDistributionPolicyTargetShape(command);\n } else {\n command.region = null;\n }\n\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n\n return result;\n };\n\n cmd.networkChanged = function networkChanged(command) {\n const result = { dirty: {} };\n\n command.viewState.autoCreateSubnets = _.chain(command.backingData.networks)\n .filter({ account: command.credentials, id: command.network })\n .map('autoCreateSubnets')\n .head()\n .value();\n\n command.viewState.subnets = _.chain(command.backingData.networks)\n .filter({ account: command.credentials, id: command.network })\n .map('subnets')\n .head()\n .value();\n\n Object.assign(result.dirty, configureSubnets(command).dirty);\n Object.assign(result.dirty, configureSecurityGroupOptions(command).dirty);\n\n // TODO: Internal Load Balancers also need to be filtered by network.\n\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n\n return result;\n };\n\n cmd.zoneChanged = function zoneChanged(command) {\n const result = { dirty: {} };\n if (command.zone === undefined && !command.regional) {\n result.dirty.zone = true;\n }\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n Object.assign(command.viewState.dirty, configureInstanceTypes(command).dirty);\n Object.assign(command.viewState.dirty, configureCpuPlatforms(command).dirty);\n Object.assign(command.viewState.dirty, configureAccelerators(command).dirty);\n return result;\n };\n\n cmd.selectZonesChanged = function selectZonesChanged(command) {\n const result = { dirty: {} };\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(command.viewState.dirty, result.dirty);\n Object.assign(command.viewState.dirty, configureAccelerators(command).dirty);\n return result;\n };\n\n cmd.customInstanceChanged = function customInstanceChanged(command) {\n const result = { dirty: {} };\n\n command.viewState.dirty = command.viewState.dirty || {};\n Object.assign(result, command.viewState.dirty, configureCustomInstanceTypes(command).dirty);\n\n return result;\n };\n }\n\n return {\n configureCommand,\n configureInstanceTypes,\n configureImages,\n configureZones,\n configureSubnets,\n configureLoadBalancerOptions,\n refreshLoadBalancers,\n refreshSecurityGroups,\n refreshInstanceTypes,\n refreshHealthChecks,\n };\n }\n}\n","import type {\n GceServerGroupLocationMode,\n IGceServerGroupCommand,\n IGceServerGroupCommandValidationErrors,\n IPersistedReference,\n} from './GceServerGroupWizard.types';\n\nexport function getGceServerGroupLocationMode(\n command: Pick<IGceServerGroupCommand, 'regional'>,\n): GceServerGroupLocationMode {\n return command.regional ? 'regional' : 'zonal';\n}\n\nexport function preservePersistedReference<T>(\n options: readonly T[],\n persistedValue: string | null | undefined,\n getValue: (option: T) => string,\n createOption: (value: string) => T,\n): Array<IPersistedReference<T>> {\n const references = options.map((value) => ({ value, unresolved: false }));\n if (persistedValue && !options.some((option) => getValue(option) === persistedValue)) {\n references.push({ value: createOption(persistedValue), unresolved: true });\n }\n return references;\n}\n\nexport function validateGceServerGroupCommand(command: IGceServerGroupCommand): IGceServerGroupCommandValidationErrors {\n const errors: IGceServerGroupCommandValidationErrors = {};\n if (!command.application?.trim()) {\n errors.application = 'Application required.';\n }\n if (!command.credentials?.trim()) {\n errors.credentials = 'Account required.';\n }\n if (!command.region?.trim()) {\n errors.region = 'Region required.';\n }\n if (!command.regional && !command.zone?.trim()) {\n errors.zone = 'Zone required.';\n }\n if (command.regional && command.selectZones && !command.distributionPolicy?.zones?.length) {\n errors.distributionPolicy = { zones: 'At least one zone required.' };\n }\n if (!command.viewState.disableImageSelection && !command.image?.trim()) {\n errors.image = 'Image required.';\n }\n if (command.capacity?.desired === null || command.capacity?.desired === undefined) {\n errors.capacity = { desired: 'Desired capacity required.' };\n }\n return errors;\n}\n","import { cloneDeep } from 'lodash';\n\nimport type { Application, IPipeline, IServerGroup, IStage } from '@spinnaker/core';\nimport type {\n GceCommandHandlerName,\n GceConfigurationRefreshMethod,\n GceConfigurationUpdateMethod,\n GceServerGroupOperationMode,\n IGceServerGroupCommand,\n IGceServerGroupCommandBuilderAdapter,\n IGceServerGroupCommandDefaults,\n IGceServerGroupCommandUpdate,\n IGceServerGroupCommandUpdateResult,\n IGceServerGroupConfigurationAdapter,\n IGceServerGroupWizardAdapter,\n} from './GceServerGroupWizard.types';\n\nconst EMPTY_UPDATE_RESULT: IGceServerGroupCommandUpdateResult = { dirty: {} };\n\nexport class GceServerGroupWizardAdapter implements IGceServerGroupWizardAdapter {\n public constructor(\n private commandBuilder: IGceServerGroupCommandBuilderAdapter,\n private configurationService: IGceServerGroupConfigurationAdapter,\n ) {}\n\n public buildNewServerGroupCommand(\n application: Application,\n defaults?: IGceServerGroupCommandDefaults,\n ): Promise<IGceServerGroupCommand> {\n return this.commandBuilder.buildNewServerGroupCommand(application, defaults);\n }\n\n public buildNewServerGroupCommandForPipeline(\n currentStage: IStage,\n pipeline: IPipeline,\n ): Promise<IGceServerGroupCommand> {\n return this.commandBuilder.buildNewServerGroupCommandForPipeline(currentStage, pipeline);\n }\n\n public buildServerGroupCommandFromExisting(\n application: Application,\n serverGroup: IServerGroup,\n mode?: GceServerGroupOperationMode,\n ): Promise<IGceServerGroupCommand> {\n return this.commandBuilder.buildServerGroupCommandFromExisting(application, serverGroup, mode);\n }\n\n public buildServerGroupCommandFromPipeline(\n application: Application,\n originalCluster: Partial<IGceServerGroupCommand>,\n currentStage: IStage,\n pipeline: IPipeline,\n ): Promise<IGceServerGroupCommand> {\n return this.commandBuilder.buildServerGroupCommandFromPipeline(\n application,\n originalCluster,\n currentStage,\n pipeline,\n );\n }\n\n public async configureCommand(\n application: Application,\n command: IGceServerGroupCommand,\n ): Promise<IGceServerGroupCommand> {\n const nextCommand = cloneDeep(command);\n await this.configurationService.configureCommand(application, nextCommand);\n return nextCommand;\n }\n\n public applyCommandHandler(\n command: IGceServerGroupCommand,\n handler: GceCommandHandlerName,\n ): Promise<IGceServerGroupCommandUpdate> {\n return this.applyUpdate(command, (nextCommand) => nextCommand[handler]?.(nextCommand));\n }\n\n public applyConfigurationUpdate(\n command: IGceServerGroupCommand,\n method: GceConfigurationUpdateMethod,\n ): Promise<IGceServerGroupCommandUpdate> {\n return this.applyUpdate(command, (nextCommand) => this.configurationService[method](nextCommand));\n }\n\n public applyConfigurationRefresh(\n command: IGceServerGroupCommand,\n method: GceConfigurationRefreshMethod,\n skipCommandReconfiguration?: boolean,\n ): Promise<IGceServerGroupCommandUpdate> {\n return this.applyUpdate(command, async (nextCommand) => {\n if (method === 'refreshInstanceTypes') {\n await this.configurationService.refreshInstanceTypes(nextCommand);\n } else {\n await this.configurationService[method](nextCommand, skipCommandReconfiguration);\n }\n return EMPTY_UPDATE_RESULT;\n });\n }\n\n private async applyUpdate(\n command: IGceServerGroupCommand,\n update: (\n nextCommand: IGceServerGroupCommand,\n ) => IGceServerGroupCommandUpdateResult | void | Promise<IGceServerGroupCommandUpdateResult | void>,\n ): Promise<IGceServerGroupCommandUpdate> {\n const nextCommand = cloneDeep(command);\n const result = (await update(nextCommand)) || EMPTY_UPDATE_RESULT;\n nextCommand.viewState = {\n ...nextCommand.viewState,\n dirty: { ...nextCommand.viewState.dirty, ...result.dirty },\n };\n nextCommand.processCommandUpdateResult?.(result);\n return { command: nextCommand, result };\n }\n}\n","import { isEqual, isPlainObject } from 'lodash';\nimport React from 'react';\n\nimport type { IWizardPageComponent } from '@spinnaker/core';\n\nimport type {\n GceCommandHandlerName,\n GceConfigurationRefreshMethod,\n GceConfigurationUpdateMethod,\n IGceServerGroupCommand,\n IGceServerGroupWizardCommandState,\n IGceServerGroupWizardFieldOrigin,\n IGceServerGroupWizardPageProps,\n} from './GceServerGroupWizard.types';\n\nexport function createGceServerGroupWizardCommandState(\n command: IGceServerGroupCommand,\n): IGceServerGroupWizardCommandState {\n return { command, fieldOrigins: {}, formikValues: command, requestGeneration: 0 };\n}\n\nexport abstract class GceServerGroupWizardPage<\n P extends IGceServerGroupWizardPageProps = IGceServerGroupWizardPageProps\n >\n extends React.Component<P>\n implements IWizardPageComponent<IGceServerGroupCommand> {\n private readonly commandState =\n this.props.commandState || createGceServerGroupWizardCommandState(this.props.formik.values);\n\n private requestGeneration = 0;\n private isUnmounted = false;\n\n protected get adapter() {\n if (!this.props.adapter) {\n throw new Error('GCE server group wizard pages require an adapter owned by the wizard modal');\n }\n return this.props.adapter;\n }\n\n public validate(_values: IGceServerGroupCommand): { [key: string]: any } {\n return {};\n }\n\n public componentWillUnmount(): void {\n this.isUnmounted = true;\n this.requestGeneration++;\n }\n\n protected configureCommand(): Promise<IGceServerGroupCommand | undefined> {\n return this.runLatestCommandRequest(this.props.formik.values, (command) =>\n this.adapter.configureCommand(this.props.app, command),\n );\n }\n\n protected applyCommandHandler(handler: GceCommandHandlerName): Promise<IGceServerGroupCommand | undefined> {\n return this.runLatestCommandRequest(this.props.formik.values, async (command) => {\n const update = await this.adapter.applyCommandHandler(command, handler);\n return update.command;\n });\n }\n\n protected applyConfigurationUpdate(\n method: GceConfigurationUpdateMethod,\n ): Promise<IGceServerGroupCommand | undefined> {\n return this.runLatestCommandRequest(this.props.formik.values, async (command) => {\n const update = await this.adapter.applyConfigurationUpdate(command, method);\n return update.command;\n });\n }\n\n protected applyConfigurationRefresh(\n method: GceConfigurationRefreshMethod,\n skipCommandReconfiguration?: boolean,\n ): Promise<IGceServerGroupCommand | undefined> {\n return this.runLatestCommandRequest(this.props.formik.values, async (command) => {\n const update = await this.adapter.applyConfigurationRefresh(command, method, skipCommandReconfiguration);\n return update.command;\n });\n }\n\n protected async runLatestCommandRequest(\n requestedCommand: IGceServerGroupCommand,\n request: (command: IGceServerGroupCommand) => Promise<IGceServerGroupCommand>,\n ): Promise<IGceServerGroupCommand | undefined> {\n const pageGeneration = ++this.requestGeneration;\n this.syncFormikValues();\n const commandGeneration = ++this.commandState.requestGeneration;\n const requestCommand = mergeCommandChanges(\n this.props.formik.values,\n requestedCommand,\n this.commandState.command,\n this.commandState.fieldOrigins,\n { generation: commandGeneration, source: 'user' },\n true,\n );\n this.commandState.command = requestCommand;\n this.props.onLoadingChanged?.(true);\n try {\n const command = await request(requestCommand);\n if (this.isUnmounted) {\n return undefined;\n }\n this.syncFormikValues();\n const currentCommand = this.commandState.command;\n const mergedCommand = mergeCommandChanges(\n requestCommand,\n command,\n currentCommand,\n this.commandState.fieldOrigins,\n { generation: commandGeneration, source: 'result' },\n );\n if (!isEqual(mergedCommand, currentCommand) || commandGeneration === this.commandState.requestGeneration) {\n this.commandState.command = mergedCommand;\n this.props.formik.setValues(mergedCommand);\n }\n return mergedCommand;\n } finally {\n if (!this.isUnmounted && pageGeneration === this.requestGeneration) {\n this.props.onLoadingChanged?.(false);\n }\n }\n }\n\n private syncFormikValues(): void {\n const { formikValues } = this.commandState;\n if (formikValues === this.props.formik.values) {\n return;\n }\n this.commandState.command = mergeCommandChanges(\n formikValues,\n this.props.formik.values,\n this.commandState.command,\n this.commandState.fieldOrigins,\n { generation: this.commandState.requestGeneration, source: 'user' },\n );\n this.commandState.formikValues = this.props.formik.values;\n }\n}\n\nfunction mergeCommandChanges(\n base: IGceServerGroupCommand,\n changed: IGceServerGroupCommand,\n current: IGceServerGroupCommand,\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n incomingOrigin: IGceServerGroupWizardFieldOrigin,\n markMatchingChanges = false,\n): IGceServerGroupCommand {\n return mergeValueChanges(\n base,\n changed,\n current,\n fieldOrigins,\n incomingOrigin,\n [],\n markMatchingChanges,\n ) as IGceServerGroupCommand;\n}\n\nfunction mergeValueChanges(\n base: any,\n changed: any,\n current: any,\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n incomingOrigin: IGceServerGroupWizardFieldOrigin,\n path: string[],\n markMatchingChanges: boolean,\n): any {\n if (isEqual(changed, base)) {\n return current;\n }\n if (isEqual(changed, current)) {\n if (markMatchingChanges) {\n recordChangedOrigins(base, changed, fieldOrigins, incomingOrigin, path);\n }\n return current;\n }\n\n if (\n isPlainObject(changed) &&\n (isPlainObject(base) || base === undefined) &&\n (isPlainObject(current) || current === undefined)\n ) {\n const baseObject = base || {};\n const currentObject = current || {};\n const result = { ...currentObject };\n new Set([...Object.keys(baseObject), ...Object.keys(changed)]).forEach((key) => {\n const childPath = [...path, key];\n if (!Object.prototype.hasOwnProperty.call(changed, key)) {\n if (\n isEqual(currentObject[key], baseObject[key]) ||\n incomingWinsConflict(fieldOrigins, incomingOrigin, childPath)\n ) {\n delete result[key];\n recordFieldOrigin(fieldOrigins, incomingOrigin, childPath);\n }\n return;\n }\n result[key] = mergeValueChanges(\n baseObject[key],\n changed[key],\n currentObject[key],\n fieldOrigins,\n incomingOrigin,\n childPath,\n markMatchingChanges,\n );\n });\n return result;\n }\n\n if (isEqual(current, base) || incomingWinsConflict(fieldOrigins, incomingOrigin, path)) {\n recordFieldOrigin(fieldOrigins, incomingOrigin, path);\n return changed;\n }\n return current;\n}\n\nfunction incomingWinsConflict(\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n incomingOrigin: IGceServerGroupWizardFieldOrigin,\n path: string[],\n): boolean {\n if (incomingOrigin.source === 'user') {\n return true;\n }\n const currentOrigin = findFieldOrigin(fieldOrigins, path);\n return currentOrigin?.source === 'result' && incomingOrigin.generation > currentOrigin.generation;\n}\n\nfunction findFieldOrigin(\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n path: string[],\n): IGceServerGroupWizardFieldOrigin | undefined {\n for (let length = path.length; length >= 0; length--) {\n const origin = fieldOrigins[fieldOriginKey(path.slice(0, length))];\n if (origin) {\n return origin;\n }\n }\n return undefined;\n}\n\nfunction recordChangedOrigins(\n base: any,\n changed: any,\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n incomingOrigin: IGceServerGroupWizardFieldOrigin,\n path: string[],\n): void {\n if (isEqual(base, changed)) {\n return;\n }\n if (isPlainObject(changed) && (isPlainObject(base) || base === undefined)) {\n const baseObject = base || {};\n new Set([...Object.keys(baseObject), ...Object.keys(changed)]).forEach((key) => {\n const childPath = [...path, key];\n if (!Object.prototype.hasOwnProperty.call(changed, key)) {\n recordFieldOrigin(fieldOrigins, incomingOrigin, childPath);\n return;\n }\n recordChangedOrigins(baseObject[key], changed[key], fieldOrigins, incomingOrigin, childPath);\n });\n return;\n }\n recordFieldOrigin(fieldOrigins, incomingOrigin, path);\n}\n\nfunction recordFieldOrigin(\n fieldOrigins: Record<string, IGceServerGroupWizardFieldOrigin>,\n incomingOrigin: IGceServerGroupWizardFieldOrigin,\n path: string[],\n): void {\n const key = fieldOriginKey(path);\n const descendantPrefix = `${key}\\u0000`;\n Object.keys(fieldOrigins).forEach((originKey) => {\n if (originKey.startsWith(descendantPrefix)) {\n delete fieldOrigins[originKey];\n }\n });\n fieldOrigins[key] = incomingOrigin;\n}\n\nfunction fieldOriginKey(path: string[]): string {\n return path.join('\\u0000');\n}\n","import React from 'react';\n\nimport { HelpField, MapEditor } from '@spinnaker/core';\n\nimport type { IGceServerGroupCommand } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\n\nfunction optionsWithPersistedValue(options: string[], persistedValue?: string): string[] {\n return Array.from(new Set([...options, persistedValue].filter(Boolean)) as Set<string>);\n}\n\nfunction hasEmptyKey(map: Record<string, unknown> = {}): boolean {\n return Object.keys(map).some((key) => !key.trim());\n}\n\nfunction hasEmptyValue(map: Record<string, unknown> = {}): boolean {\n return Object.values(map).some((value) => typeof value !== 'string' || !value.trim());\n}\n\nfunction isPipelineMode(values: IGceServerGroupCommand): boolean {\n return values.viewState.mode === 'createPipeline' || values.viewState.mode === 'editPipeline';\n}\n\nfunction isExpression(value: unknown): value is string {\n return typeof value === 'string' && /^\\s*\\$\\{.+\\}\\s*$/.test(value);\n}\n\nfunction parseNumericOrExpression(value: string): number | string {\n return isExpression(value) ? value : Number(value);\n}\n\nfunction isValidInteger(\n value: unknown,\n minimum: number,\n values: IGceServerGroupCommand,\n maximum = Number.MAX_SAFE_INTEGER,\n): boolean {\n if (isPipelineMode(values) && isExpression(value)) {\n return true;\n }\n const numericValue = Number(value);\n return (\n Number.isFinite(numericValue) &&\n Number.isInteger(numericValue) &&\n numericValue >= minimum &&\n numericValue <= maximum\n );\n}\n\nfunction isValidAccelerator(accelerator: any, values: IGceServerGroupCommand): boolean {\n if (!accelerator.acceleratorType || !isValidInteger(accelerator.acceleratorCount, 1, values)) {\n return false;\n }\n if (isPipelineMode(values) && isExpression(accelerator.acceleratorCount)) {\n return true;\n }\n const available = (values.viewState?.acceleratorTypes || []).find(\n (candidate: any) => candidate.name === accelerator.acceleratorType,\n );\n return available ? available.availableCardCounts.includes(Number(accelerator.acceleratorCount)) : true;\n}\n\nfunction getLocalSsds(values: IGceServerGroupCommand): any[] {\n return (values.disks || []).filter((disk: any) => disk.type === 'local-ssd');\n}\n\nfunction getPersistentDisks(values: IGceServerGroupCommand): any[] {\n return (values.disks || []).filter((disk: any) => disk.type !== 'local-ssd');\n}\n\nfunction renderValidationError(error: string, id: string): React.ReactNode {\n return (\n error && (\n <span className=\"help-block\" id={id} role=\"alert\">\n {error}\n </span>\n )\n );\n}\n\nexport class AdvancedSettings extends GceServerGroupWizardPage {\n public validate(values: IGceServerGroupCommand): { [key: string]: string } {\n const errors: { [key: string]: string } = {};\n if (getPersistentDisks(values).some((disk: any) => !disk.type || !isValidInteger(disk.sizeGb, 10, values, 65536))) {\n errors.disks = 'Every persistent disk requires a type and an integer size between 10 and 65536 GB.';\n }\n if ((values.acceleratorConfigs || []).some((accelerator: any) => !isValidAccelerator(accelerator, values))) {\n errors.acceleratorConfigs = 'Every accelerator requires a type and a supported positive integer count.';\n }\n if (hasEmptyKey(values.instanceMetadata)) {\n errors.instanceMetadata = 'Metadata keys cannot be empty.';\n }\n if (hasEmptyKey(values.labels) || hasEmptyValue(values.labels)) {\n errors.labels = hasEmptyKey(values.labels) ? 'Label keys cannot be empty.' : 'Label values cannot be empty.';\n }\n if (hasEmptyKey(values.resourceManagerTags) || hasEmptyValue(values.resourceManagerTags)) {\n errors.resourceManagerTags = hasEmptyKey(values.resourceManagerTags)\n ? 'Resource Manager tag keys cannot be empty.'\n : 'Resource Manager tag values cannot be empty.';\n }\n if ((values.tags || []).some((tag: any) => !(typeof tag === 'string' ? tag : tag.value)?.trim())) {\n errors.tags = 'Network tags cannot be empty.';\n }\n if ((values.authScopes || []).some((scope: string) => !scope.trim())) {\n errors.authScopes = 'Auth scopes cannot be empty.';\n }\n if (values.enableConfidentialCompute && 'confidentialInstanceType' in values && !values.confidentialInstanceType) {\n errors.confidentialInstanceType = 'Confidential instance type required.';\n }\n return errors;\n }\n\n private setField = (field: string, value: any): void => {\n this.props.formik.setFieldValue(field, value);\n };\n\n private updateDisk = (index: number, changes: Record<string, unknown>): void => {\n const values = this.props.formik.values;\n const persistentDisks = getPersistentDisks(values);\n this.setField(\n 'disks',\n persistentDisks\n .map((disk: any, diskIndex: number) => (diskIndex === index ? { ...disk, ...changes } : disk))\n .concat(getLocalSsds(values)),\n );\n };\n\n private removeDisk = (index: number): void => {\n const values = this.props.formik.values;\n this.setField(\n 'disks',\n getPersistentDisks(values)\n .filter((_disk: any, diskIndex: number) => diskIndex !== index)\n .concat(getLocalSsds(values)),\n );\n };\n\n private updateLocalSsdCount = (count: number): void => {\n const values = this.props.formik.values;\n const localSsds = getLocalSsds(values).slice(0, count);\n while (localSsds.length < count) {\n localSsds.push({ type: 'local-ssd', sizeGb: 375 });\n }\n this.setField('disks', getPersistentDisks(values).concat(localSsds));\n };\n\n private updateAccelerator = (index: number, changes: Record<string, unknown>): void => {\n const accelerators = this.props.formik.values.acceleratorConfigs || [];\n this.setField(\n 'acceleratorConfigs',\n accelerators.map((accelerator: any, acceleratorIndex: number) =>\n acceleratorIndex === index ? { ...accelerator, ...changes } : accelerator,\n ),\n );\n };\n\n private removeAccelerator = (index: number): void => {\n this.setField(\n 'acceleratorConfigs',\n (this.props.formik.values.acceleratorConfigs || []).filter(\n (_accelerator: any, acceleratorIndex: number) => acceleratorIndex !== index,\n ),\n );\n };\n\n private updateTag = (index: number, value: string): void => {\n const tags = this.props.formik.values.tags || [];\n this.setField(\n 'tags',\n tags.map((tag: any, tagIndex: number) =>\n tagIndex === index ? (typeof tag === 'string' ? value : { ...tag, value }) : tag,\n ),\n );\n };\n\n private removeTag = (index: number): void => {\n this.setField(\n 'tags',\n (this.props.formik.values.tags || []).filter((_tag: any, tagIndex: number) => tagIndex !== index),\n );\n };\n\n private removeAuthScope = (index: number): void => {\n this.setField(\n 'authScopes',\n (this.props.formik.values.authScopes || []).filter((_scope: string, scopeIndex: number) => scopeIndex !== index),\n );\n };\n\n private setPreemptible = (preemptible: boolean): void => {\n this.setField('preemptible', preemptible);\n this.setField('automaticRestart', !preemptible);\n this.setField('onHostMaintenance', preemptible ? 'TERMINATE' : 'MIGRATE');\n };\n\n private booleanRadios(label: string, field: string, value: boolean): JSX.Element {\n const id = field.replace(/([A-Z])/g, '-$1').toLowerCase();\n return (\n <div className=\"form-group\">\n <div className=\"col-md-5 sm-label-right\">\n <b>{label}</b>\n </div>\n <div className=\"col-md-2 radio\">\n <label>\n <input\n checked={value === true}\n data-testid={`${id}-yes`}\n name={field}\n onChange={() => this.setField(field, true)}\n type=\"radio\"\n />{' '}\n Yes\n </label>\n </div>\n <div className=\"col-md-2 radio\">\n <label>\n <input\n checked={value === false}\n data-testid={`${id}-no`}\n name={field}\n onChange={() => this.setField(field, false)}\n type=\"radio\"\n />{' '}\n No\n </label>\n </div>\n </div>\n );\n }\n\n public render(): JSX.Element {\n const { values } = this.props.formik;\n const errors = this.validate(values);\n const disks = getPersistentDisks(values);\n const localSsds = getLocalSsds(values);\n const accelerators = values.acceleratorConfigs || [];\n const acceleratorTypes = values.viewState?.acceleratorTypes || [];\n const tags = values.tags || [];\n const authScopes = values.authScopes || [];\n const cpuPlatforms = optionsWithPersistedValue(\n values.backingData?.filtered?.cpuPlatforms || [],\n values.minCpuPlatform,\n );\n const confidentialSettingsSupported = 'enableConfidentialCompute' in values || 'confidentialInstanceType' in values;\n const pipelineMode = isPipelineMode(values);\n\n return (\n <div className=\"container-fluid form-horizontal\" data-testid=\"gce-advanced-settings-page\">\n <div className=\"form-group\">\n <label className=\"col-md-5 control-label\">\n Minimum CPU Platform <HelpField id=\"gce.serverGroup.minCpuPlatform\" />\n </label>\n <div className=\"col-md-6\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"minimum-cpu-platform\"\n onChange={(event) => this.setField('minCpuPlatform', event.target.value)}\n value={values.minCpuPlatform || ''}\n >\n {cpuPlatforms.map((platform) => (\n <option key={platform} value={platform}>\n {platform}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n <b>Storage</b>\n </div>\n <label className=\"col-md-5 control-label\" htmlFor=\"gce-local-ssd-count\">\n Number of Local SSD Disks\n </label>\n <div className=\"col-md-2\">\n <input\n aria-describedby={errors.disks ? 'gce-advanced-disks-error' : undefined}\n aria-invalid={Boolean(errors.disks)}\n className=\"form-control input-sm\"\n data-testid=\"local-ssd-count\"\n disabled={values.viewState?.instanceTypeDetails?.storage?.localSSDSupported === false}\n id=\"gce-local-ssd-count\"\n max={8}\n min={0}\n onChange={(event) => this.updateLocalSsdCount(Number(event.target.value))}\n type=\"number\"\n value={localSsds.length}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n <b>Persistent Disks</b>\n </div>\n <table className=\"table table-condensed packed tags\">\n <thead>\n <tr>\n <th>Type</th>\n <th>Size (GB)</th>\n <th>Source image</th>\n <th />\n </tr>\n </thead>\n <tbody>\n {disks.map((disk: any, index: number) => {\n const diskTypes = optionsWithPersistedValue(values.backingData?.persistentDiskTypes || [], disk.type);\n return (\n <tr key={index}>\n <td>\n <select\n aria-describedby={errors.disks ? 'gce-advanced-disks-error' : undefined}\n aria-invalid={Boolean(errors.disks)}\n aria-label={`Disk type ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`disk-type-${index}`}\n onChange={(event) => this.updateDisk(index, { type: event.target.value })}\n required={true}\n value={disk.type || ''}\n >\n {diskTypes.map((type) => (\n <option key={type} value={type}>\n {type}\n </option>\n ))}\n </select>\n </td>\n <td>\n <input\n aria-describedby={errors.disks ? 'gce-advanced-disks-error' : undefined}\n aria-invalid={Boolean(errors.disks)}\n aria-label={`Disk size ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`disk-size-${index}`}\n max={pipelineMode ? undefined : 65536}\n min={pipelineMode ? undefined : 10}\n onChange={(event) =>\n this.updateDisk(index, { sizeGb: parseNumericOrExpression(event.target.value) })\n }\n required={true}\n type={pipelineMode ? 'text' : 'number'}\n value={disk.sizeGb ?? ''}\n />\n </td>\n <td>\n <input\n aria-label={`Disk source image ${index + 1}`}\n className=\"form-control input-sm\"\n onChange={(event) => this.updateDisk(index, { sourceImage: event.target.value || undefined })}\n type=\"text\"\n value={disk.sourceImage || ''}\n />\n </td>\n <td>\n <button\n aria-label={`Remove disk ${index + 1}`}\n className=\"btn btn-link\"\n data-testid={`remove-disk-${index}`}\n onClick={() => this.removeDisk(index)}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n <tfoot>\n <tr>\n <td colSpan={4}>\n <button\n className=\"btn btn-block btn-sm add-new\"\n data-testid=\"add-disk\"\n onClick={() => this.setField('disks', [...disks, { type: 'pd-ssd', sizeGb: 10 }, ...localSsds])}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add disk\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n {renderValidationError(errors.disks, 'gce-advanced-disks-error')}\n </div>\n\n {(accelerators.length > 0 || acceleratorTypes.length > 0) && (\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n <b>Accelerators</b> <HelpField id=\"gce.serverGroup.accelerator\" />\n </div>\n <table className=\"table table-condensed packed tags\">\n <thead>\n <tr>\n <th>Type</th>\n <th>Count</th>\n <th />\n </tr>\n </thead>\n <tbody>\n {accelerators.map((accelerator: any, index: number) => {\n const selectedType = acceleratorTypes.find((type: any) => type.name === accelerator.acceleratorType);\n const typeNames = optionsWithPersistedValue(\n acceleratorTypes.map((type: any) => type.name),\n accelerator.acceleratorType,\n );\n const counts = Array.from(\n new Set(\n [...(selectedType?.availableCardCounts || []), accelerator.acceleratorCount].filter(Boolean),\n ),\n );\n return (\n <tr key={index}>\n <td>\n <select\n aria-describedby={errors.acceleratorConfigs ? 'gce-advanced-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`Accelerator type ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`accelerator-type-${index}`}\n onChange={(event) => this.updateAccelerator(index, { acceleratorType: event.target.value })}\n required={true}\n value={accelerator.acceleratorType || ''}\n >\n {typeNames.map((type) => (\n <option key={type} value={type}>\n {acceleratorTypes.find((candidate: any) => candidate.name === type)?.description || type}\n </option>\n ))}\n </select>\n </td>\n <td>\n {pipelineMode ? (\n <input\n aria-describedby={errors.acceleratorConfigs ? 'gce-advanced-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`Accelerator count ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`accelerator-count-${index}`}\n onChange={(event) =>\n this.updateAccelerator(index, {\n acceleratorCount: parseNumericOrExpression(event.target.value),\n })\n }\n required={true}\n type=\"text\"\n value={accelerator.acceleratorCount ?? ''}\n />\n ) : counts.length ? (\n <select\n aria-describedby={errors.acceleratorConfigs ? 'gce-advanced-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`Accelerator count ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`accelerator-count-${index}`}\n onChange={(event) =>\n this.updateAccelerator(index, {\n acceleratorCount: parseNumericOrExpression(event.target.value),\n })\n }\n required={true}\n value={accelerator.acceleratorCount ?? ''}\n >\n {counts.map((count) => (\n <option key={count} value={count}>\n {count}\n </option>\n ))}\n </select>\n ) : (\n <input\n aria-describedby={errors.acceleratorConfigs ? 'gce-advanced-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`Accelerator count ${index + 1}`}\n className=\"form-control input-sm\"\n data-testid={`accelerator-count-${index}`}\n min={1}\n onChange={(event) =>\n this.updateAccelerator(index, {\n acceleratorCount: parseNumericOrExpression(event.target.value),\n })\n }\n required={true}\n type=\"number\"\n value={accelerator.acceleratorCount ?? ''}\n />\n )}\n </td>\n <td>\n <button\n aria-label={`Remove accelerator ${index + 1}`}\n className=\"btn btn-link\"\n data-testid={`remove-accelerator-${index}`}\n onClick={() => this.removeAccelerator(index)}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n <tfoot>\n <tr>\n <td colSpan={3}>\n <button\n className=\"btn btn-block btn-sm add-new\"\n data-testid=\"add-accelerator\"\n disabled={!acceleratorTypes.length}\n onClick={() => {\n const type = acceleratorTypes[0];\n this.setField('acceleratorConfigs', [\n ...accelerators,\n { acceleratorType: type.name, acceleratorCount: type.availableCardCounts?.[0] || 1 },\n ]);\n }}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add accelerator\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n {renderValidationError(errors.acceleratorConfigs, 'gce-advanced-accelerators-error')}\n </div>\n )}\n\n <div className=\"form-group\">\n <label className=\"sm-label-left\" htmlFor=\"gce-user-data\">\n User Data <HelpField id=\"gce.serverGroup.userData\" />\n </label>\n <textarea\n className=\"form-control\"\n id=\"gce-user-data\"\n onChange={(event) => this.setField('userData', event.target.value)}\n rows={3}\n value={values.userData || ''}\n />\n </div>\n\n <div\n aria-describedby={errors.instanceMetadata ? 'gce-advanced-instance-metadata-error' : undefined}\n aria-invalid={Boolean(errors.instanceMetadata)}\n aria-label=\"Custom Metadata\"\n className=\"form-group\"\n role=\"group\"\n >\n <MapEditor\n addButtonLabel=\"Add New Metadata\"\n allowEmpty={true}\n keyLabel=\"Metadata key\"\n label=\"Custom Metadata\"\n model={values.instanceMetadata || {}}\n onChange={(model) => this.setField('instanceMetadata', model)}\n valueLabel=\"Metadata value\"\n />\n {renderValidationError(errors.instanceMetadata, 'gce-advanced-instance-metadata-error')}\n </div>\n <div\n aria-describedby={errors.labels ? 'gce-advanced-labels-error' : undefined}\n aria-invalid={Boolean(errors.labels)}\n aria-label=\"Labels\"\n className=\"form-group\"\n role=\"group\"\n >\n <MapEditor\n addButtonLabel=\"Add New Label\"\n allowEmpty={true}\n keyLabel=\"Label key\"\n label=\"Labels\"\n model={values.labels || {}}\n onChange={(model) => this.setField('labels', model)}\n valueLabel=\"Label value\"\n />\n {renderValidationError(errors.labels, 'gce-advanced-labels-error')}\n </div>\n <div\n aria-describedby={errors.resourceManagerTags ? 'gce-advanced-resource-manager-tags-error' : undefined}\n aria-invalid={Boolean(errors.resourceManagerTags)}\n aria-label=\"Resource Manager Tags\"\n className=\"form-group\"\n role=\"group\"\n >\n <MapEditor\n addButtonLabel=\"Add New Resource Manager Tag\"\n allowEmpty={false}\n keyLabel=\"Tag key\"\n label=\"Resource Manager Tags\"\n model={values.resourceManagerTags || {}}\n onChange={(model) => this.setField('resourceManagerTags', model)}\n valueLabel=\"Tag value\"\n />\n {renderValidationError(errors.resourceManagerTags, 'gce-advanced-resource-manager-tags-error')}\n </div>\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n <b>Network Tags</b>\n </div>\n <table className=\"table table-condensed packed tags\">\n <tbody>\n {tags.map((tag: any, index: number) => (\n <tr key={index}>\n <td>\n <input\n aria-describedby={errors.tags ? 'gce-advanced-network-tags-error' : undefined}\n aria-invalid={Boolean(errors.tags)}\n aria-label={`Network tag ${index + 1}`}\n className=\"form-control input-sm\"\n onChange={(event) => this.updateTag(index, event.target.value)}\n required={true}\n value={typeof tag === 'string' ? tag : tag.value || ''}\n />\n </td>\n <td>\n <button\n aria-label={`Remove network tag ${index + 1}`}\n className=\"btn btn-link\"\n data-testid={`remove-network-tag-${index}`}\n onClick={() => this.removeTag(index)}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot>\n <tr>\n <td colSpan={2}>\n <button\n className=\"btn btn-block btn-sm add-new\"\n data-testid=\"add-network-tag\"\n onClick={() => this.setField('tags', [...tags, { value: '' }])}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add network tag\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n {renderValidationError(errors.tags, 'gce-advanced-network-tags-error')}\n </div>\n\n <fieldset className=\"form-group\">\n <legend className=\"sm-label-left\">\n Shielded VM <HelpField id=\"gce.serverGroup.shieldedInstanceConfig\" />\n </legend>\n <div className=\"col-md-9 checkbox\">\n <label>\n <input\n checked={Boolean(values.enableSecureBoot)}\n onChange={(event) => this.setField('enableSecureBoot', event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Turn on Secure Boot\n </label>\n </div>\n <div className=\"col-md-9 checkbox\">\n <label>\n <input\n checked={Boolean(values.enableVtpm)}\n data-testid=\"enable-vtpm\"\n onChange={(event) => {\n this.setField('enableVtpm', event.target.checked);\n if (!event.target.checked) {\n this.setField('enableIntegrityMonitoring', false);\n }\n }}\n type=\"checkbox\"\n />{' '}\n Turn on vTPM\n </label>\n </div>\n <div className=\"col-md-9 checkbox\">\n <label>\n <input\n checked={Boolean(values.enableIntegrityMonitoring)}\n disabled={!values.enableVtpm}\n onChange={(event) => this.setField('enableIntegrityMonitoring', event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Turn on Integrity Monitoring\n </label>\n </div>\n </fieldset>\n\n {confidentialSettingsSupported && (\n <fieldset className=\"form-group\">\n <legend className=\"sm-label-left\">Confidential VM</legend>\n {'enableConfidentialCompute' in values && (\n <div className=\"col-md-9 checkbox\" data-testid=\"enable-confidential-compute\">\n <label>\n <input\n checked={Boolean(values.enableConfidentialCompute)}\n onChange={(event) => this.setField('enableConfidentialCompute', event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Enable Confidential Compute\n </label>\n </div>\n )}\n {'confidentialInstanceType' in values && (\n <div className=\"col-md-9\">\n <label htmlFor=\"gce-confidential-instance-type\">Confidential instance type</label>\n <select\n aria-describedby={\n errors.confidentialInstanceType ? 'gce-advanced-confidential-instance-type-error' : undefined\n }\n aria-invalid={Boolean(errors.confidentialInstanceType)}\n className=\"form-control input-sm\"\n id=\"gce-confidential-instance-type\"\n onChange={(event) => this.setField('confidentialInstanceType', event.target.value)}\n required={Boolean(values.enableConfidentialCompute)}\n value={values.confidentialInstanceType || ''}\n >\n <option value=\"\">Select...</option>\n {optionsWithPersistedValue(\n values.backingData?.confidentialInstanceTypes || [],\n values.confidentialInstanceType,\n ).map((type) => (\n <option key={type} value={type}>\n {type}\n </option>\n ))}\n </select>\n {renderValidationError(\n errors.confidentialInstanceType,\n 'gce-advanced-confidential-instance-type-error',\n )}\n </div>\n )}\n </fieldset>\n )}\n\n <div className=\"form-group\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Preemptibility</b>\n </div>\n <div className=\"col-md-2 radio\">\n <label>\n <input\n checked={!values.preemptible}\n data-testid=\"preemptible-off\"\n name=\"preemptible\"\n onChange={() => this.setPreemptible(false)}\n type=\"radio\"\n />{' '}\n Off\n </label>\n </div>\n <div className=\"col-md-2 radio\">\n <label>\n <input\n checked={Boolean(values.preemptible)}\n data-testid=\"preemptible-on\"\n name=\"preemptible\"\n onChange={() => this.setPreemptible(true)}\n type=\"radio\"\n />{' '}\n On\n </label>\n </div>\n </div>\n\n {this.booleanRadios('Automatic Restart', 'automaticRestart', Boolean(values.automaticRestart))}\n <div className=\"form-group\">\n <label className=\"col-md-5 control-label\">On Host Maintenance</label>\n <div className=\"col-md-4\">\n <select\n className=\"form-control input-sm\"\n onChange={(event) => this.setField('onHostMaintenance', event.target.value)}\n value={values.onHostMaintenance || ''}\n >\n <option value=\"MIGRATE\">Migrate</option>\n <option value=\"TERMINATE\">Terminate</option>\n </select>\n </div>\n </div>\n {this.booleanRadios(\n 'Associate Public IP Address',\n 'associatePublicIpAddress',\n values.associatePublicIpAddress !== false,\n )}\n {this.booleanRadios('Can IP Forward', 'canIpForward', Boolean(values.canIpForward))}\n\n <div className=\"form-group\" data-testid=\"service-account\">\n <label className=\"col-md-5 control-label\" htmlFor=\"gce-service-account\">\n Service Account\n </label>\n <div className=\"col-md-6\">\n <input\n className=\"form-control input-sm\"\n id=\"gce-service-account\"\n onChange={(event) => this.setField('serviceAccountEmail', event.target.value)}\n type=\"text\"\n value={values.serviceAccountEmail || ''}\n />\n </div>\n </div>\n\n <div className=\"form-group\">\n <div className=\"sm-label-left\">\n <b>Auth Scopes</b>\n </div>\n <table className=\"table table-condensed packed tags\">\n <tbody>\n {authScopes.map((scope: string, index: number) => (\n <tr key={index} data-testid={`auth-scope-${index}`}>\n <td>\n <input\n aria-describedby={errors.authScopes ? 'gce-advanced-auth-scopes-error' : undefined}\n aria-invalid={Boolean(errors.authScopes)}\n aria-label={`Auth scope ${index + 1}`}\n className=\"form-control input-sm\"\n list=\"gce-auth-scopes\"\n onChange={(event) =>\n this.setField(\n 'authScopes',\n authScopes.map((candidate: string, scopeIndex: number) =>\n scopeIndex === index ? event.target.value : candidate,\n ),\n )\n }\n required={true}\n value={scope}\n />\n </td>\n <td>\n <button\n aria-label={`Remove auth scope ${index + 1}`}\n className=\"btn btn-link\"\n data-testid={`remove-auth-scope-${index}`}\n onClick={() => this.removeAuthScope(index)}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot>\n <tr>\n <td colSpan={2}>\n <button\n className=\"btn btn-block btn-sm add-new\"\n data-testid=\"add-auth-scope\"\n onClick={() => this.setField('authScopes', [...authScopes, ''])}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-plus-sign\" /> Add auth scope\n </button>\n </td>\n </tr>\n </tfoot>\n </table>\n <datalist id=\"gce-auth-scopes\">\n {(values.backingData?.authScopes || []).map((scope: string) => (\n <option key={scope} value={scope} />\n ))}\n </datalist>\n {renderValidationError(errors.authScopes, 'gce-advanced-auth-scopes-error')}\n </div>\n </div>\n );\n }\n}\n","import React from 'react';\n\nimport type { IGceServerGroupCommand } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\n\ninterface IFirewall {\n id: string;\n name: string;\n network?: string;\n targetTags: string[];\n}\n\ninterface IFirewallOption {\n firewall: IFirewall;\n unavailable: boolean;\n}\n\ninterface ITag {\n value: string;\n [key: string]: unknown;\n}\n\nexport class GceServerGroupFirewalls extends GceServerGroupWizardPage {\n private firewallsChanged = (event: React.ChangeEvent<HTMLSelectElement>): void => {\n const values = this.props.formik.values;\n const securityGroups = unique(Array.from(event.target.selectedOptions).map((option) => option.value));\n const available = scopedFirewalls(values);\n const removedTags = available\n .filter((firewall) => selectedFirewallIds(values).includes(firewall.id) && !securityGroups.includes(firewall.id))\n .flatMap((firewall) => firewall.targetTags);\n const tags = selectedTags(values).filter((tag) => !removedTags.includes(tag.value));\n this.reconcile({ ...values, securityGroups, tags }, securityGroups, tags);\n };\n\n private targetTagChanged = (tagName: string, selected: boolean): void => {\n const values = this.props.formik.values;\n const available = explicitFirewalls(values);\n const tags = selected\n ? uniqueTags([...selectedTags(values), { value: tagName }])\n : selectedTags(values).filter((tag) => tag.value !== tagName);\n const selectedTagNames = tags.map((tag) => tag.value);\n const currentlySelected = selectedFirewallIds(values);\n const unavailable = currentlySelected.filter((id) => !available.some((firewall) => firewall.id === id));\n const securityGroups = selected\n ? unique([\n ...currentlySelected,\n ...available.filter((firewall) => firewall.targetTags.includes(tagName)).map((firewall) => firewall.id),\n ])\n : unique([\n ...unavailable,\n ...available\n .filter(\n (firewall) =>\n currentlySelected.includes(firewall.id) &&\n firewall.targetTags.some((targetTag) => selectedTagNames.includes(targetTag)),\n )\n .map((firewall) => firewall.id),\n ]);\n this.reconcile({ ...values, securityGroups, tags }, securityGroups, tags);\n };\n\n private reconcile = (command: IGceServerGroupCommand, securityGroups: string[], tags: ITag[]): void => {\n void this.runLatestCommandRequest(command, async (latestCommand) => {\n const update = await this.adapter.applyCommandHandler(latestCommand, 'networkChanged');\n return preserveFirewallSelection(update.command, securityGroups, tags);\n });\n };\n\n private showImplicitChanged = (showImplicit: boolean): void => {\n const values = this.props.formik.values;\n this.props.formik.setFieldValue('viewState', {\n ...values.viewState,\n listImplicitSecurityGroups: showImplicit,\n });\n };\n\n private refreshFirewalls = (): void => {\n const command = this.props.formik.values;\n const securityGroups = selectedFirewallIds(command);\n const tags = selectedTags(command);\n void this.runLatestCommandRequest(command, async (latestCommand) => {\n const update = await this.adapter.applyConfigurationRefresh(latestCommand, 'refreshSecurityGroups');\n return preserveFirewallSelection(update.command, securityGroups, tags);\n });\n };\n\n public render(): JSX.Element {\n const values = this.props.formik.values;\n const selectedIds = selectedFirewallIds(values);\n const tags = selectedTags(values).map((tag) => tag.value);\n const explicit = explicitFirewalls(values);\n const implicit = implicitFirewalls(values);\n const options = firewallOptions(explicit, selectedIds);\n const selectedKnownFirewalls = explicit.filter((firewall) => selectedIds.includes(firewall.id));\n\n return (\n <div className=\"container-fluid form-horizontal\">\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-server-group-firewalls\">\n Firewalls\n </label>\n <div className=\"col-md-9\">\n <select\n aria-label=\"Firewalls\"\n className=\"form-control input-sm\"\n id=\"gce-server-group-firewalls\"\n multiple={true}\n onChange={this.firewallsChanged}\n value={selectedIds}\n >\n {options.map(({ firewall, unavailable }) => (\n <option key={firewall.id} value={firewall.id}>\n {unavailable ? `${firewall.id} (unavailable)` : `${firewall.name} (${firewall.id})`}\n </option>\n ))}\n </select>\n {!options.length && <p className=\"form-control-static\">No explicit firewalls found.</p>}\n </div>\n </div>\n\n {selectedKnownFirewalls.map((firewall) => (\n <fieldset className=\"form-group\" key={firewall.id}>\n <legend className=\"col-md-3 sm-label-right\">Target Tags for {firewall.name}</legend>\n <div className=\"col-md-9\">\n {firewall.targetTags.map((targetTag) => {\n const id = controlId('gce-firewall-target-tag', firewall.id, targetTag);\n return (\n <div className=\"checkbox\" key={targetTag}>\n <label htmlFor={id}>\n <input\n aria-label={`Target tag ${targetTag} for firewall ${firewall.id}`}\n checked={tags.includes(targetTag)}\n id={id}\n onChange={(event) => this.targetTagChanged(targetTag, event.target.checked)}\n type=\"checkbox\"\n />\n {targetTag}\n </label>\n </div>\n );\n })}\n </div>\n </fieldset>\n ))}\n\n <div className=\"form-group small\">\n <div className=\"col-md-9 col-md-offset-3 checkbox\">\n <label htmlFor=\"gce-show-implicit-firewalls\">\n <input\n aria-label=\"Show implicit firewalls\"\n checked={Boolean(values.viewState.listImplicitSecurityGroups)}\n id=\"gce-show-implicit-firewalls\"\n onChange={(event) => this.showImplicitChanged(event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Show implicit firewalls\n </label>\n </div>\n </div>\n\n {values.viewState.listImplicitSecurityGroups && (\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">\n <b>Implicit Firewalls</b>\n </div>\n <div className=\"col-md-9\">\n <ul aria-label=\"Implicit firewalls\">\n {implicit.length ? (\n implicit.map((firewall) => <li key={firewall.id}>{firewall.name}</li>)\n ) : (\n <li>None</li>\n )}\n </ul>\n </div>\n </div>\n )}\n\n <div className=\"form-group small\">\n <div className=\"col-md-9 col-md-offset-3\">\n <button\n aria-label=\"Refresh firewalls\"\n className=\"btn btn-link\"\n onClick={this.refreshFirewalls}\n type=\"button\"\n >\n Refresh firewalls\n </button>\n </div>\n </div>\n </div>\n );\n }\n}\n\nfunction firewallOptions(available: IFirewall[], selectedIds: string[]): IFirewallOption[] {\n const availableIds = available.map((firewall) => firewall.id);\n return [\n ...available.map((firewall) => ({ firewall, unavailable: false })),\n ...selectedIds\n .filter((id) => !availableIds.includes(id))\n .map((id) => ({ firewall: { id, name: id, targetTags: [] }, unavailable: true })),\n ];\n}\n\nfunction explicitFirewalls(command: IGceServerGroupCommand): IFirewall[] {\n return scopedFirewalls(command).filter((firewall) => firewall.targetTags.length > 0);\n}\n\nfunction implicitFirewalls(command: IGceServerGroupCommand): IFirewall[] {\n return scopedFirewalls(command).filter((firewall) => firewall.targetTags.length === 0);\n}\n\nfunction scopedFirewalls(command: IGceServerGroupCommand): IFirewall[] {\n const raw = command.backingData?.securityGroups?.[command.credentials || '']?.gce?.global || [];\n const byId = new Map<string, IFirewall>();\n raw\n .filter((firewall: any) => firewall.network === command.network)\n .forEach((firewall: any) => {\n const existing = byId.get(firewall.id);\n const targetTags = unique([...(existing?.targetTags || []), ...parseTargetTags(firewall.targetTags)]);\n byId.set(firewall.id, {\n id: firewall.id,\n name: firewall.name || existing?.name || firewall.id,\n network: firewall.network,\n targetTags,\n });\n });\n return Array.from(byId.values()).sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction parseTargetTags(targetTags: unknown): string[] {\n if (Array.isArray(targetTags)) {\n return unique(targetTags.map(String));\n }\n if (typeof targetTags !== 'string') {\n return [];\n }\n const content = targetTags.trim().replace(/^\\[/, '').replace(/\\]$/, '');\n return unique(content.split(',').map((tag) => tag.trim()));\n}\n\nfunction selectedFirewallIds(command: IGceServerGroupCommand): string[] {\n return unique(command.securityGroups || []);\n}\n\nfunction selectedTags(command: IGceServerGroupCommand): ITag[] {\n return uniqueTags((command.tags || []).map((tag: string | ITag) => (typeof tag === 'string' ? { value: tag } : tag)));\n}\n\nfunction uniqueTags(tags: ITag[]): ITag[] {\n const byValue = new Map<string, ITag>();\n tags.forEach((tag) => tag.value && !byValue.has(tag.value) && byValue.set(tag.value, tag));\n return Array.from(byValue.values());\n}\n\nfunction preserveFirewallSelection(\n command: IGceServerGroupCommand,\n securityGroups: string[],\n tags: ITag[],\n): IGceServerGroupCommand {\n return {\n ...command,\n securityGroups,\n tags,\n viewState: {\n ...command.viewState,\n dirty: { ...command.viewState.dirty, securityGroups: null },\n },\n };\n}\n\nfunction controlId(...parts: string[]): string {\n return parts.join('-').replace(/[^a-zA-Z0-9_-]/g, '-');\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values.filter(Boolean)));\n}\n","import React from 'react';\n\nimport { HelpField } from '@spinnaker/core';\n\nimport type {\n IGceServerGroupCommand,\n IGceServerGroupCommandValidationErrors,\n IGceServerGroupWizardPageProps,\n} from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\n\ninterface ILoadBalancerOption {\n name: string;\n region?: string;\n}\n\ninterface IBackendServiceData {\n name: string;\n portName?: string;\n}\n\ninterface ILoadBalancerData {\n backendServices?: Array<string | Partial<IBackendServiceData>>;\n listeners?: Array<{ name?: string }>;\n loadBalancerType?: string;\n name?: string;\n}\n\ninterface INamedPort {\n name: string;\n port: number | string;\n}\n\ninterface ILoadBalancingPolicy {\n [key: string]: any;\n balancingMode?: string;\n capacityScaler?: number | string;\n maxConnectionsPerInstance?: number | string;\n maxRatePerInstance?: number | string;\n maxUtilization?: number | string;\n namedPorts?: INamedPort[];\n}\n\ninterface ILoadBalancingPolicyErrors {\n balancingMode?: string;\n capacityScaler?: string;\n maxConnectionsPerInstance?: string;\n maxRatePerInstance?: string;\n maxUtilization?: string;\n namedPorts?: Array<{ name?: string; port?: string }>;\n}\n\ninterface ILoadBalancerMetadataReference {\n key: 'global-load-balancer-names' | 'load-balancer-names';\n names: string[];\n}\n\ninterface IStringReference {\n unavailable: boolean;\n value: string;\n}\n\ntype PreservedField =\n | 'backendServiceMetadata'\n | 'backendServices'\n | 'loadBalancerMetadata'\n | 'loadBalancers'\n | 'loadBalancingPolicy';\n\nconst HTTP_BALANCING_MODES = ['RATE', 'UTILIZATION'];\nconst CONNECTION_BALANCING_MODES = ['CONNECTION', 'UTILIZATION'];\nconst MODE_LIMIT_FIELDS = ['maxConnectionsPerInstance', 'maxRatePerInstance', 'maxUtilization'];\nconst DEFAULT_LOAD_BALANCING_POLICY = {\n balancingMode: 'UTILIZATION',\n capacityScaler: 1,\n maxUtilization: 0.8,\n namedPorts: [{ name: 'http', port: 80 }],\n};\n\nfunction policyErrorId(field: string): string {\n return `gce-load-balancing-policy-${field.replace(/([A-Z])/g, '-$1').toLowerCase()}-error`;\n}\n\nfunction renderPolicyError(error: string | undefined, id: string): React.ReactNode {\n return (\n error && (\n <span className=\"help-block\" id={id} role=\"alert\">\n {error}\n </span>\n )\n );\n}\n\nexport class GceServerGroupLoadBalancers extends GceServerGroupWizardPage<IGceServerGroupWizardPageProps> {\n public validate(values: IGceServerGroupCommand): IGceServerGroupCommandValidationErrors {\n const errors = super.validate(values) as IGceServerGroupCommandValidationErrors & {\n loadBalancingPolicy?: ILoadBalancingPolicyErrors;\n };\n const policy = values.loadBalancingPolicy as ILoadBalancingPolicy | undefined;\n if (!policy || !uniqueStrings(values.loadBalancers).length) {\n return errors;\n }\n\n const policyErrors: ILoadBalancingPolicyErrors = {};\n const balancingModes = getBalancingModes(values);\n if (!policy.balancingMode || !balancingModes.includes(policy.balancingMode)) {\n policyErrors.balancingMode = 'Select a balancing mode supported by the selected load balancers.';\n }\n if (!isValidBoundedValue(policy.capacityScaler, values, 0, 1)) {\n policyErrors.capacityScaler = 'Capacity must be between 0 and 100%.';\n }\n\n const namedPortErrors = (policy.namedPorts || []).map(({ name, port }) => {\n const namedPortError: { name?: string; port?: string } = {};\n if (!name?.trim()) {\n namedPortError.name = 'Port name required.';\n }\n if (!isValidInteger(port, values, 1, 65535)) {\n namedPortError.port = 'Port must be an integer between 1 and 65535.';\n }\n return namedPortError;\n });\n if (namedPortErrors.some((namedPortError) => Object.keys(namedPortError).length)) {\n policyErrors.namedPorts = namedPortErrors;\n }\n\n if (policy.balancingMode === 'RATE' && !isValidMinimum(policy.maxRatePerInstance, values, 0)) {\n policyErrors.maxRatePerInstance = 'Max rate must be a finite number greater than or equal to zero.';\n }\n if (policy.balancingMode === 'CONNECTION' && !isValidMinimum(policy.maxConnectionsPerInstance, values, 0)) {\n policyErrors.maxConnectionsPerInstance = 'Max connections must be a finite number greater than or equal to zero.';\n }\n if (policy.balancingMode === 'UTILIZATION' && !isValidBoundedValue(policy.maxUtilization, values, 0, 1)) {\n policyErrors.maxUtilization = 'Max utilization must be between 0 and 100%.';\n }\n\n if (Object.keys(policyErrors).length) {\n errors.loadBalancingPolicy = policyErrors;\n }\n return errors;\n }\n\n public render(): React.ReactElement {\n const values = this.props.formik.values;\n const selectedLoadBalancers = uniqueStrings(values.loadBalancers);\n const selectedReferences = preserveReferences(getAvailableLoadBalancers(values), selectedLoadBalancers);\n const policy = (values.loadBalancingPolicy || {}) as ILoadBalancingPolicy;\n const policyErrors = (this.validate(values) as IGceServerGroupCommandValidationErrors & {\n loadBalancingPolicy?: ILoadBalancingPolicyErrors;\n }).loadBalancingPolicy || { namedPorts: [] };\n const balancingModes = getBalancingModes(values);\n\n return (\n <div className=\"container-fluid form-horizontal\">\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-server-group-load-balancers\">\n Load Balancers\n </label>\n <div className=\"col-md-7\">\n <select\n aria-label=\"Load balancers\"\n className=\"form-control input-sm\"\n id=\"gce-server-group-load-balancers\"\n multiple={true}\n onChange={this.handleLoadBalancersChanged}\n value={selectedLoadBalancers}\n >\n {selectedReferences.map(({ name, unavailable }) => (\n <option key={name} value={name}>\n {name}\n {unavailable ? ' (unavailable)' : ''}\n </option>\n ))}\n </select>\n </div>\n <div className=\"col-md-1\">\n <button\n aria-label=\"Refresh load balancers\"\n className=\"btn btn-default btn-sm\"\n onClick={this.handleRefresh}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-refresh\" />\n </button>\n </div>\n </div>\n\n {selectedLoadBalancers.map((loadBalancerName) => this.renderBackendServiceSelector(values, loadBalancerName))}\n\n {selectedLoadBalancers.length > 0 && balancingModes.length > 0 && (\n <>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-balancing-mode\">\n Balancing mode\n </label>\n <div className=\"col-md-4\">\n <select\n aria-describedby={policyErrors.balancingMode ? policyErrorId('balancingMode') : undefined}\n aria-invalid={Boolean(policyErrors.balancingMode)}\n aria-label=\"Balancing mode\"\n className=\"form-control input-sm\"\n id=\"gce-balancing-mode\"\n onChange={this.handleBalancingModeChanged}\n required={true}\n value={policy.balancingMode || ''}\n >\n {!policy.balancingMode && <option value=\"\">Select...</option>}\n {balancingModes.map((mode) => (\n <option key={mode} value={mode}>\n {mode}\n </option>\n ))}\n </select>\n {renderPolicyError(policyErrors.balancingMode, policyErrorId('balancingMode'))}\n </div>\n </div>\n\n {this.renderNamedPorts(values, policy, policyErrors.namedPorts || [])}\n {this.renderPercentageInput(\n 'Capacity scaler',\n 'capacityScaler',\n policy.capacityScaler,\n values,\n policyErrors.capacityScaler,\n )}\n {policy.balancingMode === 'UTILIZATION' &&\n this.renderPercentageInput(\n 'Max utilization',\n 'maxUtilization',\n policy.maxUtilization,\n values,\n policyErrors.maxUtilization,\n )}\n {policy.balancingMode === 'RATE' &&\n this.renderNumberInput(\n 'Max rate per instance',\n 'maxRatePerInstance',\n policy.maxRatePerInstance,\n values,\n policyErrors.maxRatePerInstance,\n )}\n {policy.balancingMode === 'CONNECTION' &&\n this.renderNumberInput(\n 'Max connections per instance',\n 'maxConnectionsPerInstance',\n policy.maxConnectionsPerInstance,\n values,\n policyErrors.maxConnectionsPerInstance,\n )}\n </>\n )}\n </div>\n );\n }\n\n private renderBackendServiceSelector(\n values: IGceServerGroupCommand,\n loadBalancerName: string,\n ): React.ReactElement | null {\n const availableBackendServices = getBackendServiceData(values, loadBalancerName).map(({ name }) => name);\n const selectedBackendServices = uniqueStrings(values.backendServices?.[loadBalancerName]);\n if (!availableBackendServices.length && !selectedBackendServices.length) {\n return null;\n }\n const references = preserveStringReferences(availableBackendServices, selectedBackendServices);\n\n return (\n <div className=\"form-group\" key={loadBalancerName}>\n <label className=\"col-md-3 sm-label-right\" htmlFor={`gce-backend-services-${loadBalancerName}`}>\n Backend services for {loadBalancerName}\n </label>\n <div className=\"col-md-7\">\n <select\n aria-label={`Backend services for ${loadBalancerName}`}\n className=\"form-control input-sm\"\n id={`gce-backend-services-${loadBalancerName}`}\n multiple={true}\n onChange={(event) => this.handleBackendServicesChanged(loadBalancerName, event)}\n value={selectedBackendServices}\n >\n {references.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (unavailable)' : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n );\n }\n\n private renderNamedPorts(\n values: IGceServerGroupCommand,\n policy: ILoadBalancingPolicy,\n errors: Array<{ name?: string; port?: string }>,\n ): React.ReactElement {\n const availableNames = getNamedPortNames(values);\n const namedPorts = policy.namedPorts || [];\n return (\n <>\n {namedPorts.map((namedPort, index) => {\n const references = preserveStringReferences(availableNames, namedPort.name ? [namedPort.name] : []);\n const nameErrorId = policyErrorId(`namedPortName-${index}`);\n const portErrorId = policyErrorId(`namedPortPort-${index}`);\n return (\n <div className=\"form-group\" key={index}>\n <label className=\"col-md-3 sm-label-right\" htmlFor={`gce-named-port-name-${index}`}>\n Named port {index + 1}\n </label>\n <div className=\"col-md-3\">\n <select\n aria-describedby={errors[index]?.name ? nameErrorId : undefined}\n aria-invalid={Boolean(errors[index]?.name)}\n aria-label={`Named port name ${index + 1}`}\n className=\"form-control input-sm\"\n id={`gce-named-port-name-${index}`}\n onChange={(event) => this.handleNamedPortChanged(index, 'name', event.target.value)}\n required={true}\n value={namedPort.name}\n >\n {!namedPort.name && <option value=\"\">Select...</option>}\n {references.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (unavailable)' : ''}\n </option>\n ))}\n </select>\n {renderPolicyError(errors[index]?.name, nameErrorId)}\n </div>\n <div className=\"col-md-2\">\n <input\n aria-describedby={errors[index]?.port ? portErrorId : undefined}\n aria-invalid={Boolean(errors[index]?.port)}\n aria-label={`Named port number ${index + 1}`}\n className=\"form-control input-sm\"\n onChange={(event) =>\n this.handleNamedPortChanged(index, 'port', parseNumericValue(event.target.value))\n }\n required={true}\n type={isPipelineMode(values) ? 'text' : 'number'}\n value={namedPort.port}\n />\n {renderPolicyError(errors[index]?.port, portErrorId)}\n </div>\n <div className=\"col-md-1\">\n <button\n aria-label={`Remove named port ${index + 1}`}\n className=\"btn btn-default btn-sm\"\n onClick={() => this.handleRemoveNamedPort(index)}\n type=\"button\"\n >\n <span className=\"glyphicon glyphicon-trash\" />\n </button>\n </div>\n </div>\n );\n })}\n <div className=\"form-group\">\n <div className=\"col-md-offset-3 col-md-4\">\n <button\n aria-label=\"Add named port\"\n className=\"btn btn-default btn-sm\"\n onClick={this.handleAddNamedPort}\n type=\"button\"\n >\n Add named port\n </button>\n </div>\n </div>\n </>\n );\n }\n\n private renderPercentageInput(\n label: string,\n field: 'capacityScaler' | 'maxUtilization',\n value: number | string | undefined,\n values: IGceServerGroupCommand,\n error?: string,\n ): React.ReactElement {\n const errorId = policyErrorId(field);\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={`gce-${field}`}>\n {label}\n <HelpField id={`gce.serverGroup.loadBalancingPolicy.${field}`} />\n </label>\n <div className=\"col-md-3\">\n <div className=\"input-group\">\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={label}\n className=\"form-control input-sm\"\n id={`gce-${field}`}\n onChange={(event) => this.handlePolicyFieldChanged(field, parsePercentageValue(event.target.value))}\n required={true}\n type={isPipelineMode(values) ? 'text' : 'number'}\n value={toPercentageValue(value)}\n />\n <span className=\"input-group-addon\">%</span>\n </div>\n {renderPolicyError(error, errorId)}\n </div>\n </div>\n );\n }\n\n private renderNumberInput(\n label: string,\n field: 'maxConnectionsPerInstance' | 'maxRatePerInstance',\n value: number | string | undefined,\n values: IGceServerGroupCommand,\n error?: string,\n ): React.ReactElement {\n const errorId = policyErrorId(field);\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={`gce-${field}`}>\n {label}\n <HelpField id={`gce.serverGroup.loadBalancingPolicy.${field}`} />\n </label>\n <div className=\"col-md-3\">\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={label}\n className=\"form-control input-sm\"\n id={`gce-${field}`}\n onChange={(event) => this.handlePolicyFieldChanged(field, parseNumericValue(event.target.value))}\n required={true}\n type={isPipelineMode(values) ? 'text' : 'number'}\n value={value === undefined ? '' : value}\n />\n {renderPolicyError(error, errorId)}\n </div>\n </div>\n );\n }\n\n private handleLoadBalancersChanged = (event: React.ChangeEvent<HTMLSelectElement>): void => {\n const values = this.props.formik.values;\n const loadBalancers = uniqueStrings(Array.from(event.target.selectedOptions).map(({ value }) => value));\n const previouslySelected = new Set(uniqueStrings(values.loadBalancers));\n const backendServices = Object.entries(values.backendServices || {}).reduce<Record<string, string[]>>(\n (mappings, [loadBalancerName, services]) => {\n if (loadBalancers.includes(loadBalancerName) || !previouslySelected.has(loadBalancerName)) {\n mappings[loadBalancerName] = uniqueStrings(services);\n }\n return mappings;\n },\n {},\n );\n const nextCommand: IGceServerGroupCommand = {\n ...values,\n loadBalancers,\n loadBalancerMetadata: reconcileLoadBalancerMetadata(values, loadBalancers),\n backendServices,\n backendServiceMetadata: uniqueStrings(Object.values(backendServices).flat()),\n };\n nextCommand.loadBalancingPolicy = reconcileLoadBalancingPolicy(nextCommand);\n void this.applyPageUpdate(nextCommand, ['loadBalancers', 'loadBalancerMetadata', 'loadBalancingPolicy'], true);\n };\n\n private handleBackendServicesChanged = (\n loadBalancerName: string,\n event: React.ChangeEvent<HTMLSelectElement>,\n ): void => {\n const values = this.props.formik.values;\n const backendServices = {\n ...(values.backendServices || {}),\n [loadBalancerName]: uniqueStrings(Array.from(event.target.selectedOptions).map(({ value }) => value)),\n };\n const nextCommand = {\n ...values,\n backendServices,\n backendServiceMetadata: uniqueStrings(Object.values(backendServices).flat()),\n };\n void this.applyPageUpdate(nextCommand, ['backendServices', 'backendServiceMetadata']);\n };\n\n private handleBalancingModeChanged = (event: React.ChangeEvent<HTMLSelectElement>): void => {\n const policy = { ...((this.props.formik.values.loadBalancingPolicy || {}) as ILoadBalancingPolicy) };\n MODE_LIMIT_FIELDS.forEach((field) => delete policy[field]);\n policy.balancingMode = event.target.value;\n void this.updatePolicy(policy);\n };\n\n private handleNamedPortChanged = (index: number, field: keyof INamedPort, value: number | string): void => {\n const policy = { ...((this.props.formik.values.loadBalancingPolicy || {}) as ILoadBalancingPolicy) };\n policy.namedPorts = (policy.namedPorts || []).map((namedPort, namedPortIndex) =>\n namedPortIndex === index ? { ...namedPort, [field]: value } : namedPort,\n );\n void this.updatePolicy(policy);\n };\n\n private handleAddNamedPort = (): void => {\n const policy = { ...((this.props.formik.values.loadBalancingPolicy || {}) as ILoadBalancingPolicy) };\n policy.namedPorts = [...(policy.namedPorts || []), { name: '', port: 80 }];\n void this.updatePolicy(policy);\n };\n\n private handleRemoveNamedPort = (index: number): void => {\n const policy = { ...((this.props.formik.values.loadBalancingPolicy || {}) as ILoadBalancingPolicy) };\n policy.namedPorts = (policy.namedPorts || []).filter((_namedPort, namedPortIndex) => namedPortIndex !== index);\n void this.updatePolicy(policy);\n };\n\n private handlePolicyFieldChanged = (field: keyof ILoadBalancingPolicy, value: number | string): void => {\n const policy = {\n ...((this.props.formik.values.loadBalancingPolicy || {}) as ILoadBalancingPolicy),\n [field]: value,\n };\n void this.updatePolicy(policy);\n };\n\n private updatePolicy(policy: ILoadBalancingPolicy): Promise<IGceServerGroupCommand | undefined> {\n const values = this.props.formik.values;\n return this.applyPageUpdate({ ...values, loadBalancingPolicy: policy }, [\n 'backendServices',\n 'backendServiceMetadata',\n 'loadBalancers',\n 'loadBalancerMetadata',\n 'loadBalancingPolicy',\n ]);\n }\n\n private applyPageUpdate(\n nextCommand: IGceServerGroupCommand,\n preservedFields: PreservedField[],\n mergeConfiguredBackendServices = false,\n ): Promise<IGceServerGroupCommand | undefined> {\n return this.runLatestCommandRequest(nextCommand, async (latestCommand) => {\n const loadBalancerIndex = getLoadBalancerIndex(latestCommand);\n const configurationCommand = {\n ...latestCommand,\n loadBalancers: uniqueStrings(latestCommand.loadBalancers).filter((name) => Boolean(loadBalancerIndex[name])),\n };\n const update = await this.adapter.applyConfigurationUpdate(configurationCommand, 'configureLoadBalancerOptions');\n const command: IGceServerGroupCommand = {\n ...update.command,\n loadBalancers: latestCommand.loadBalancers,\n viewState: {\n ...update.command.viewState,\n dirty: update.result.dirty,\n },\n };\n if (mergeConfiguredBackendServices) {\n command.backendServices = {\n ...(latestCommand.backendServices || {}),\n ...(update.command.backendServices || {}),\n };\n command.backendServiceMetadata = uniqueStrings(Object.values(command.backendServices).flat());\n }\n preservedFields.forEach((field) => {\n command[field] = latestCommand[field];\n });\n return command;\n });\n }\n\n private handleRefresh = (): void => {\n const selectedLoadBalancers = uniqueStrings(this.props.formik.values.loadBalancers);\n void this.runLatestCommandRequest(this.props.formik.values, async (latestCommand) => {\n const update = await this.adapter.applyConfigurationRefresh(latestCommand, 'refreshLoadBalancers');\n return {\n ...update.command,\n loadBalancers: selectedLoadBalancers,\n viewState: {\n ...update.command.viewState,\n dirty: update.result.dirty,\n },\n };\n });\n };\n}\n\nfunction getAvailableLoadBalancers(command: IGceServerGroupCommand): ILoadBalancerOption[] {\n const rawLoadBalancers = command.backingData?.loadBalancers;\n if (Array.isArray(rawLoadBalancers)) {\n return uniqueLoadBalancers(\n rawLoadBalancers\n .flatMap((provider: any) => (Array.isArray(provider?.accounts) ? provider.accounts : []))\n .filter((account: any) => account?.name === command.credentials)\n .flatMap((account: any) => (Array.isArray(account?.regions) ? account.regions : []))\n .flatMap((region: any) => (Array.isArray(region?.loadBalancers) ? region.loadBalancers : []))\n .filter((loadBalancer: any) => isLoadBalancerInRegion(loadBalancer, command))\n .map(toLoadBalancerOption)\n .filter((loadBalancer): loadBalancer is ILoadBalancerOption => Boolean(loadBalancer)),\n );\n }\n\n const filteredLoadBalancers = command.backingData?.filtered?.loadBalancers;\n if (!Array.isArray(filteredLoadBalancers)) {\n return [];\n }\n return uniqueLoadBalancers(\n filteredLoadBalancers\n .map(toLoadBalancerOption)\n .filter((loadBalancer): loadBalancer is ILoadBalancerOption => Boolean(loadBalancer)),\n );\n}\n\nfunction getLoadBalancerIndex(command: IGceServerGroupCommand): Record<string, ILoadBalancerData> {\n return (command.backingData?.filtered?.loadBalancerIndex || {}) as Record<string, ILoadBalancerData>;\n}\n\nfunction getBackendServiceData(command: IGceServerGroupCommand, loadBalancerName: string): IBackendServiceData[] {\n const loadBalancer = getLoadBalancerIndex(command)[loadBalancerName];\n if (!Array.isArray(loadBalancer?.backendServices)) {\n return [];\n }\n const byName = new Map<string, IBackendServiceData>();\n loadBalancer.backendServices.forEach((backendService) => {\n const value =\n typeof backendService === 'string'\n ? { name: backendService }\n : { name: backendService.name || '', portName: backendService.portName };\n if (value.name && !byName.has(value.name)) {\n byName.set(value.name, value);\n }\n });\n return Array.from(byName.values());\n}\n\nfunction getNamedPortNames(command: IGceServerGroupCommand): string[] {\n return uniqueStrings(\n uniqueStrings(command.loadBalancers).flatMap((loadBalancerName) =>\n getBackendServiceData(command, loadBalancerName).map(({ portName }) => portName || ''),\n ),\n ).filter(Boolean);\n}\n\nfunction getBalancingModes(command: IGceServerGroupCommand): string[] {\n const loadBalancerIndex = getLoadBalancerIndex(command);\n const modeSets = uniqueStrings(command.loadBalancers)\n .map((loadBalancerName) => loadBalancerIndex[loadBalancerName]?.loadBalancerType)\n .filter((loadBalancerType): loadBalancerType is string => Boolean(loadBalancerType))\n .map((loadBalancerType) =>\n loadBalancerType === 'HTTP' || loadBalancerType === 'INTERNAL_MANAGED'\n ? HTTP_BALANCING_MODES\n : CONNECTION_BALANCING_MODES,\n );\n if (!modeSets.length) {\n const persistedMode = (command.loadBalancingPolicy as ILoadBalancingPolicy | undefined)?.balancingMode;\n return persistedMode ? [persistedMode] : [];\n }\n return modeSets.slice(1).reduce((modes, nextModes) => modes.filter((mode) => nextModes.includes(mode)), modeSets[0]);\n}\n\nfunction reconcileLoadBalancingPolicy(command: IGceServerGroupCommand): ILoadBalancingPolicy | undefined {\n const balancingModes = getBalancingModes(command);\n if (!balancingModes.length) {\n return undefined;\n }\n const existing = command.loadBalancingPolicy as ILoadBalancingPolicy | undefined;\n const balancingMode =\n existing?.balancingMode && balancingModes.includes(existing.balancingMode)\n ? existing.balancingMode\n : DEFAULT_LOAD_BALANCING_POLICY.balancingMode;\n const policy: ILoadBalancingPolicy = {\n ...existing,\n balancingMode,\n capacityScaler: existing?.capacityScaler ?? DEFAULT_LOAD_BALANCING_POLICY.capacityScaler,\n namedPorts: existing?.namedPorts ?? DEFAULT_LOAD_BALANCING_POLICY.namedPorts.map((namedPort) => ({ ...namedPort })),\n };\n if (existing?.balancingMode !== balancingMode) {\n MODE_LIMIT_FIELDS.forEach((field) => delete policy[field]);\n }\n if (balancingMode === 'UTILIZATION' && policy.maxUtilization === undefined) {\n policy.maxUtilization = DEFAULT_LOAD_BALANCING_POLICY.maxUtilization;\n }\n return policy;\n}\n\nfunction reconcileLoadBalancerMetadata(\n command: IGceServerGroupCommand,\n nextLoadBalancers: string[],\n): Record<string, string[]> {\n const metadata = Object.entries(command.loadBalancerMetadata || {}).reduce<Record<string, string[]>>(\n (copy, [key, values]) => ({ ...copy, [key]: uniqueStrings(values) }),\n {},\n );\n uniqueStrings(command.loadBalancers).forEach((loadBalancerName) => {\n const reference = getLoadBalancerMetadataReference(command, loadBalancerName);\n if (reference) {\n metadata[reference.key] = (metadata[reference.key] || []).filter((name) => !reference.names.includes(name));\n }\n });\n nextLoadBalancers.forEach((loadBalancerName) => {\n const reference = getLoadBalancerMetadataReference(command, loadBalancerName);\n if (reference) {\n metadata[reference.key] = uniqueStrings([...(metadata[reference.key] || []), ...reference.names]);\n }\n });\n return metadata;\n}\n\nfunction getLoadBalancerMetadataReference(\n command: IGceServerGroupCommand,\n loadBalancerName: string,\n): ILoadBalancerMetadataReference | undefined {\n const loadBalancer = getLoadBalancerIndex(command)[loadBalancerName];\n if (!loadBalancer) {\n return undefined;\n }\n if (loadBalancer.loadBalancerType === 'HTTP' || loadBalancer.loadBalancerType === 'INTERNAL_MANAGED') {\n const names = uniqueStrings((loadBalancer.listeners || []).map(({ name }) => name || ''));\n if (!names.length) {\n return undefined;\n }\n return {\n key: loadBalancer.loadBalancerType === 'HTTP' ? 'global-load-balancer-names' : 'load-balancer-names',\n names,\n };\n }\n return {\n key:\n loadBalancer.loadBalancerType === 'SSL' || loadBalancer.loadBalancerType === 'TCP'\n ? 'global-load-balancer-names'\n : 'load-balancer-names',\n names: [loadBalancerName],\n };\n}\n\nfunction preserveReferences(\n availableLoadBalancers: ILoadBalancerOption[],\n selectedLoadBalancers: string[],\n): Array<ILoadBalancerOption & { unavailable: boolean }> {\n const availableNames = new Set(availableLoadBalancers.map(({ name }) => name));\n return [\n ...availableLoadBalancers\n .map((loadBalancer) => ({ ...loadBalancer, unavailable: false }))\n .sort((left, right) => left.name.localeCompare(right.name)),\n ...selectedLoadBalancers.filter((name) => !availableNames.has(name)).map((name) => ({ name, unavailable: true })),\n ];\n}\n\nfunction preserveStringReferences(availableValues: string[], persistedValues: string[]): IStringReference[] {\n const available = uniqueStrings(availableValues);\n return [\n ...available.map((value) => ({ unavailable: false, value })),\n ...uniqueStrings(persistedValues)\n .filter((value) => !available.includes(value))\n .map((value) => ({ unavailable: true, value })),\n ];\n}\n\nfunction isPipelineMode(command: IGceServerGroupCommand): boolean {\n return command.viewState.mode === 'createPipeline' || command.viewState.mode === 'editPipeline';\n}\n\nfunction isExpression(value: unknown): boolean {\n return typeof value === 'string' && /^\\s*\\$\\{.+\\}\\s*$/.test(value);\n}\n\nfunction isValidBoundedValue(\n value: unknown,\n command: IGceServerGroupCommand,\n minimum: number,\n maximum: number,\n): boolean {\n if (isPipelineMode(command) && isExpression(value)) {\n return true;\n }\n if (!hasNumericValue(value)) {\n return false;\n }\n const numericValue = Number(value);\n return Number.isFinite(numericValue) && numericValue >= minimum && numericValue <= maximum;\n}\n\nfunction isValidMinimum(value: unknown, command: IGceServerGroupCommand, minimum: number): boolean {\n if (isPipelineMode(command) && isExpression(value)) {\n return true;\n }\n if (!hasNumericValue(value)) {\n return false;\n }\n const numericValue = Number(value);\n return Number.isFinite(numericValue) && numericValue >= minimum;\n}\n\nfunction isValidInteger(value: unknown, command: IGceServerGroupCommand, minimum: number, maximum: number): boolean {\n if (isPipelineMode(command) && isExpression(value)) {\n return true;\n }\n if (!hasNumericValue(value)) {\n return false;\n }\n const numericValue = Number(value);\n return (\n Number.isFinite(numericValue) &&\n Number.isInteger(numericValue) &&\n numericValue >= minimum &&\n numericValue <= maximum\n );\n}\n\nfunction hasNumericValue(value: unknown): boolean {\n return value !== null && value !== undefined && (typeof value !== 'string' || Boolean(value.trim()));\n}\n\nfunction parsePercentageValue(value: string): number | string {\n if (isExpression(value)) {\n return value;\n }\n return value.trim() ? Number(value) / 100 : '';\n}\n\nfunction parseNumericValue(value: string): number | string {\n if (isExpression(value)) {\n return value;\n }\n return value.trim() ? Number(value) : '';\n}\n\nfunction toPercentageValue(value: number | string | undefined): number | string {\n if (typeof value === 'number') {\n return value * 100;\n }\n return value === undefined ? '' : value;\n}\n\nfunction isLoadBalancerInRegion(loadBalancer: any, command: IGceServerGroupCommand): boolean {\n return loadBalancer?.region === command.region || loadBalancer?.region === 'global';\n}\n\nfunction toLoadBalancerOption(loadBalancer: unknown): ILoadBalancerOption | null {\n if (typeof loadBalancer === 'string') {\n return { name: loadBalancer };\n }\n if (loadBalancer && typeof (loadBalancer as ILoadBalancerOption).name === 'string') {\n const { name, region } = loadBalancer as ILoadBalancerOption;\n return { name, region };\n }\n return null;\n}\n\nfunction uniqueLoadBalancers(loadBalancers: ILoadBalancerOption[]): ILoadBalancerOption[] {\n return Array.from(new Map(loadBalancers.map((loadBalancer) => [loadBalancer.name, loadBalancer])).values());\n}\n\nfunction uniqueStrings(values: unknown): string[] {\n if (!Array.isArray(values)) {\n return [];\n }\n return Array.from(new Set(values.filter((value): value is string => typeof value === 'string' && Boolean(value))));\n}\n","import React from 'react';\n\nimport type { IGceAutoHealingPolicy } from '../domain';\nimport { GceHealthCheckReader } from '../healthCheck/healthCheck.read.service';\nimport type { IGceHealthCheckOption } from '../healthCheck/healthCheckUtils';\nimport { getHealthCheckOptions, parseHealthCheckUrl } from '../healthCheck/healthCheckUtils';\n\nexport interface IGceAutoHealingPolicyEditorProps {\n account: string;\n policy: IGceAutoHealingPolicy;\n onChange: (policy: IGceAutoHealingPolicy) => void;\n reader?: GceHealthCheckReader;\n}\n\ninterface IGceAutoHealingPolicyEditorState {\n healthChecks: IGceHealthCheckOption[];\n loading: boolean;\n}\n\nfunction numberValue(value: string): number | undefined {\n return value === '' ? undefined : Number(value);\n}\n\nexport class GceAutoHealingPolicyEditor extends React.Component<\n IGceAutoHealingPolicyEditorProps,\n IGceAutoHealingPolicyEditorState\n> {\n public state: IGceAutoHealingPolicyEditorState = { healthChecks: [], loading: true };\n\n public componentDidMount(): void {\n this.loadHealthChecks();\n }\n\n public loadHealthChecks = (): void => {\n this.setState({ loading: true });\n (this.props.reader || new GceHealthCheckReader()).listHealthChecks().then((healthChecks) => {\n const options = getHealthCheckOptions(\n healthChecks.filter((healthCheck) => healthCheck.account === this.props.account),\n );\n this.setState({\n healthChecks: options,\n loading: false,\n });\n this.normalizeHealthCheck(options);\n });\n };\n\n private update = (changes: Partial<IGceAutoHealingPolicy>): void => {\n this.props.onChange({ ...this.props.policy, ...changes });\n };\n\n private getHealthCheckUrl = (healthChecks = this.state.healthChecks): string => {\n const { healthCheck, healthCheckKind, healthCheckUrl } = this.props.policy;\n if (healthCheckUrl) {\n return healthCheckUrl;\n }\n if (healthCheck?.includes('/')) {\n return healthCheck;\n }\n const matches = healthChecks.filter(\n (option) => option.name === healthCheck && (!healthCheckKind || option.kind === healthCheckKind),\n );\n return matches.length === 1 ? matches[0].selfLink : '';\n };\n\n private normalizeHealthCheck(healthChecks: IGceHealthCheckOption[]): void {\n const healthCheckUrl = this.getHealthCheckUrl(healthChecks);\n if (!healthCheckUrl) {\n return;\n }\n const { healthCheckName, healthCheckKind } = parseHealthCheckUrl(healthCheckUrl);\n if (\n this.props.policy.healthCheckUrl !== healthCheckUrl ||\n this.props.policy.healthCheck !== healthCheckName ||\n this.props.policy.healthCheckKind !== healthCheckKind\n ) {\n this.update({ healthCheckUrl, healthCheck: healthCheckName, healthCheckKind });\n }\n }\n\n public render(): JSX.Element {\n const { policy } = this.props;\n\n return (\n <div className=\"form-horizontal gce-auto-healing-policy-editor\">\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Health check</label>\n <div className=\"col-md-6\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"health-check\"\n disabled={this.state.loading}\n value={this.getHealthCheckUrl()}\n onChange={(event) => {\n const healthCheckUrl = event.target.value;\n if (!healthCheckUrl) {\n this.update({ healthCheckUrl: undefined, healthCheck: undefined, healthCheckKind: undefined });\n return;\n }\n const { healthCheckName, healthCheckKind } = parseHealthCheckUrl(healthCheckUrl);\n this.update({ healthCheckUrl, healthCheck: healthCheckName, healthCheckKind });\n }}\n >\n <option value=\"\">Select...</option>\n {this.state.healthChecks.map((healthCheck) => (\n <option key={healthCheck.selfLink} value={healthCheck.selfLink}>\n {healthCheck.displayName}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Initial delay</label>\n <div className=\"col-md-6 input-group\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"initial-delay\"\n max={2147483647}\n min={0}\n type=\"number\"\n value={policy.initialDelaySec ?? ''}\n onChange={(event) => this.update({ initialDelaySec: numberValue(event.target.value) })}\n />\n <span className=\"input-group-addon\">seconds</span>\n </div>\n </div>\n <div className=\"form-group\">\n <div className=\"col-md-offset-4 col-md-6\">\n <button\n className=\"btn btn-link\"\n disabled={this.state.loading}\n type=\"button\"\n onClick={this.loadHealthChecks}\n >\n Refresh health checks\n </button>\n </div>\n </div>\n </div>\n );\n }\n}\n","export interface IGceAutoscalingPolicy {\n minNumReplicas?: number;\n maxNumReplicas?: number;\n coolDownPeriodSec?: number;\n mode?: 'ON' | 'OFF' | 'ONLY_SCALE_OUT';\n cpuUtilization?: IGceAutoscalingCpuUtilization;\n loadBalancingUtilization?: IGceAutoscalingUtilization;\n customMetricUtilizations?: IGceAutoscalingCustomMetric[];\n scaleInControl?: IGceScaleInControl;\n scalingSchedules?: IGceScalingSchedule[];\n}\n\nexport interface IGceScaleInControl {\n maxScaledInReplicas?: {\n fixed?: number;\n percent?: number;\n };\n timeWindowSec?: number;\n}\n\nexport interface IGceAutoscalingCpuUtilization {\n predictiveMethod?: GcePredictiveMethod;\n utilizationTarget?: number;\n}\n\nexport interface IGceAutoscalingUtilization {\n utilizationTarget?: number;\n}\n\nexport type GceUtilizationTargetType = 'GAUGE' | 'DELTA_PER_SECOND' | 'DELTA_PER_MINUTE';\nexport type GceMetricExportScope = 'TIME_SERIES_PER_INSTANCE' | 'SINGLE_TIME_SERIES_PER_GROUP';\nexport type GceScalingPolicyType = 'UTILIZATION_TARGET' | 'SINGLE_INSTANCE_ASSIGNMENT';\n\nexport interface IGceAutoscalingCustomMetric {\n metric?: string;\n filter?: string;\n metricExportScope?: GceMetricExportScope;\n scalingpolicy?: GceScalingPolicyType;\n singleInstanceAssignment?: number;\n utilizationTarget?: number;\n utilizationTargetType?: GceUtilizationTargetType;\n}\n\nexport interface IGceScalingSchedule {\n scheduleName?: string;\n scheduleDescription?: string;\n enabled?: boolean;\n minimumRequiredInstances?: number;\n scheduleCron?: string;\n timezone?: string;\n duration?: number;\n}\n\nexport enum GcePredictiveMethod {\n NONE = 'NONE',\n STANDARD = 'OPTIMIZE_AVAILABILITY',\n}\n","import type { Application, IJob, ITask } from '@spinnaker/core';\nimport { TaskExecutor } from '@spinnaker/core';\n\nimport type { IGceAutoscalingPolicy } from './IGceAutoscalingPolicy';\nimport type { IGceAutoHealingPolicy } from '../domain';\n\ninterface IGcePolicyServerGroupIdentity {\n account: string;\n name: string;\n}\n\nexport type IGcePolicyServerGroup = IGcePolicyServerGroupIdentity &\n ({ region: string; zone?: string } | { region?: undefined; zone: string });\n\nexport interface IGcePolicyTaskParams {\n interestingHealthProviderNames?: string[];\n reason?: string;\n}\n\ninterface IGcePolicyJob extends IJob {\n cloudProvider: 'gce';\n credentials: string;\n region: string;\n serverGroupName: string;\n type: 'upsertScalingPolicy' | 'deleteScalingPolicy';\n autoscalingPolicy?: IGceAutoscalingPolicy;\n autoHealingPolicy?: IGceAutoHealingPolicy;\n deleteAutoHealingPolicy?: true;\n interestingHealthProviderNames?: string[];\n reason?: string;\n}\n\nfunction policyJob(serverGroup: IGcePolicyServerGroup, type: IGcePolicyJob['type']): IGcePolicyJob {\n return {\n type,\n cloudProvider: 'gce',\n credentials: serverGroup.account,\n region: serverGroup.region ?? serverGroup.zone,\n serverGroupName: serverGroup.name,\n };\n}\n\nfunction supportedAutoHealingPolicy(policy: IGceAutoHealingPolicy): IGceAutoHealingPolicy {\n // This is the final task boundary: legacy server responses can still carry fields that\n // stable Compute v1 no longer accepts, so assemble the outbound contract explicitly.\n const supported: IGceAutoHealingPolicy = {};\n (['healthCheck', 'healthCheckKind', 'healthCheckUrl', 'initialDelaySec'] as const).forEach((field) => {\n if (policy[field] !== undefined) {\n (supported as any)[field] = policy[field];\n }\n });\n return supported;\n}\n\nexport class GceAutoscalingPolicyWriter {\n public static upsertAutoscalingPolicy(\n application: Application,\n serverGroup: IGcePolicyServerGroup,\n autoscalingPolicy: IGceAutoscalingPolicy,\n params: IGcePolicyTaskParams = {},\n ): Promise<ITask> {\n return TaskExecutor.executeTask({\n application,\n description: `Upsert scaling policy ${serverGroup.name}`,\n job: [{ ...policyJob(serverGroup, 'upsertScalingPolicy'), autoscalingPolicy, ...params }],\n });\n }\n\n public static deleteAutoscalingPolicy(application: Application, serverGroup: IGcePolicyServerGroup): Promise<ITask> {\n return TaskExecutor.executeTask({\n application,\n description: `Delete scaling policy ${serverGroup.name}`,\n job: [policyJob(serverGroup, 'deleteScalingPolicy')],\n });\n }\n\n public static upsertAutoHealingPolicy(\n application: Application,\n serverGroup: IGcePolicyServerGroup,\n autoHealingPolicy: IGceAutoHealingPolicy,\n ): Promise<ITask> {\n return TaskExecutor.executeTask({\n application,\n description: `Upsert autohealing policy ${serverGroup.name}`,\n job: [\n {\n ...policyJob(serverGroup, 'upsertScalingPolicy'),\n autoHealingPolicy: supportedAutoHealingPolicy(autoHealingPolicy),\n },\n ],\n });\n }\n\n public static deleteAutoHealingPolicy(application: Application, serverGroup: IGcePolicyServerGroup): Promise<ITask> {\n return TaskExecutor.executeTask({\n application,\n description: `Delete autohealing policy ${serverGroup.name}`,\n job: [{ ...policyJob(serverGroup, 'deleteScalingPolicy'), deleteAutoHealingPolicy: true }],\n });\n }\n}\n","import React from 'react';\n\nimport type {\n GceMetricExportScope,\n GceScalingPolicyType,\n GceUtilizationTargetType,\n IGceAutoscalingCustomMetric,\n IGceAutoscalingPolicy,\n IGceScalingSchedule,\n} from './IGceAutoscalingPolicy';\nimport { GcePredictiveMethod } from './IGceAutoscalingPolicy';\n// @ts-ignore JSON imports are bundled by Rollup's JSON plugin.\nimport timezoneData from './components/scalingSchedules/standardTimezone.json';\nimport { GCEProviderSettings } from '../gce.settings';\n\nconst timezones = timezoneData as string[];\n\nexport interface IGceAutoscalingPolicyEditorProps {\n policy: IGceAutoscalingPolicy;\n onChange: (policy: IGceAutoscalingPolicy) => void;\n predictiveAutoscalingEnabled?: boolean;\n}\n\nfunction numberValue(value: string): number | undefined {\n return value === '' ? undefined : Number(value);\n}\n\nfunction percentValue(value?: number): number | '' {\n return value === undefined ? '' : value * 100;\n}\n\nexport function GceAutoscalingPolicyEditor({\n policy,\n onChange,\n predictiveAutoscalingEnabled = Boolean(GCEProviderSettings.feature.predictiveAutoscaling),\n}: IGceAutoscalingPolicyEditorProps): JSX.Element {\n const update = <K extends keyof IGceAutoscalingPolicy>(key: K, value: IGceAutoscalingPolicy[K]): void => {\n onChange({ ...policy, [key]: value });\n };\n const customMetrics = policy.customMetricUtilizations || [];\n const schedules = policy.scalingSchedules || [];\n const cpuMetricConfigured = Boolean(policy.cpuUtilization && Object.keys(policy.cpuUtilization).length);\n const loadBalancingMetricConfigured = Boolean(\n policy.loadBalancingUtilization && Object.keys(policy.loadBalancingUtilization).length,\n );\n const scaleInUnit = typeof policy.scaleInControl?.maxScaledInReplicas?.percent === 'number' ? 'percent' : 'fixed';\n const scaleInMaximum = policy.scaleInControl?.maxScaledInReplicas?.[scaleInUnit];\n\n const updateCustomMetric = (index: number, changes: Partial<IGceAutoscalingCustomMetric>): void => {\n update(\n 'customMetricUtilizations',\n customMetrics.map((metric, metricIndex) => (metricIndex === index ? { ...metric, ...changes } : metric)),\n );\n };\n const updateSchedule = (index: number, changes: Partial<IGceScalingSchedule>): void => {\n update(\n 'scalingSchedules',\n schedules.map((schedule, scheduleIndex) => (scheduleIndex === index ? { ...schedule, ...changes } : schedule)),\n );\n };\n const updateCustomMetricScalingPolicy = (index: number, scalingpolicy: GceScalingPolicyType): void => {\n const metric = customMetrics[index];\n let compatibleMetric: IGceAutoscalingCustomMetric;\n if (scalingpolicy === 'SINGLE_INSTANCE_ASSIGNMENT') {\n const { utilizationTarget: _target, utilizationTargetType: _type, ...assignmentMetric } = metric;\n compatibleMetric = assignmentMetric;\n } else {\n const { singleInstanceAssignment: _assignment, ...utilizationMetric } = metric;\n compatibleMetric = utilizationMetric;\n }\n update(\n 'customMetricUtilizations',\n customMetrics.map((customMetric, metricIndex) =>\n metricIndex === index ? { ...compatibleMetric, scalingpolicy } : customMetric,\n ),\n );\n };\n\n return (\n <div className=\"form-horizontal gce-autoscaling-policy-editor\">\n <h4>Capacity</h4>\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Minimum number of instances</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"minimum-replicas\"\n min={0}\n type=\"number\"\n value={policy.minNumReplicas ?? ''}\n onChange={(event) => update('minNumReplicas', numberValue(event.target.value))}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Maximum number of instances</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"maximum-replicas\"\n min={policy.minNumReplicas ?? 0}\n type=\"number\"\n value={policy.maxNumReplicas ?? ''}\n onChange={(event) => update('maxNumReplicas', numberValue(event.target.value))}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Cool-down period (seconds)</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"cooldown\"\n min={15}\n type=\"number\"\n value={policy.coolDownPeriodSec ?? ''}\n onChange={(event) => update('coolDownPeriodSec', numberValue(event.target.value))}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Mode</label>\n <div className=\"col-md-4\">\n <select\n className=\"form-control input-sm\"\n data-testid=\"mode\"\n value={policy.mode || 'ON'}\n onChange={(event) => update('mode', event.target.value as IGceAutoscalingPolicy['mode'])}\n >\n <option value=\"ON\">ON</option>\n <option value=\"OFF\">OFF</option>\n <option value=\"ONLY_SCALE_OUT\">ONLY_SCALE_OUT</option>\n </select>\n </div>\n </div>\n\n <h4>Metrics</h4>\n {cpuMetricConfigured ? (\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">CPU utilization target (%)</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"cpu-target\"\n max={99}\n min={0}\n type=\"number\"\n value={percentValue(policy.cpuUtilization.utilizationTarget)}\n onChange={(event) =>\n update('cpuUtilization', {\n ...policy.cpuUtilization,\n utilizationTarget:\n event.target.value === '' ? undefined : (numberValue(event.target.value) as number) / 100,\n })\n }\n />\n <button className=\"btn btn-link\" type=\"button\" onClick={() => update('cpuUtilization', {})}>\n Delete CPU metric\n </button>\n </div>\n {predictiveAutoscalingEnabled && (\n <div className=\"col-md-4 checkbox\">\n <label>\n <input\n data-testid=\"predictive-autoscaling\"\n type=\"checkbox\"\n checked={policy.cpuUtilization.predictiveMethod === GcePredictiveMethod.STANDARD}\n onChange={(event) =>\n update('cpuUtilization', {\n ...policy.cpuUtilization,\n predictiveMethod: event.target.checked ? GcePredictiveMethod.STANDARD : GcePredictiveMethod.NONE,\n })\n }\n />{' '}\n Enable predictive autoscaling\n </label>\n </div>\n )}\n </div>\n ) : (\n <button\n className=\"btn btn-link\"\n type=\"button\"\n onClick={() => update('cpuUtilization', { utilizationTarget: undefined })}\n >\n Add CPU utilization metric\n </button>\n )}\n\n {loadBalancingMetricConfigured ? (\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">HTTP load-balancing target (%)</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"http-lb-target\"\n max={99}\n min={0}\n type=\"number\"\n value={percentValue(policy.loadBalancingUtilization.utilizationTarget)}\n onChange={(event) =>\n update('loadBalancingUtilization', {\n utilizationTarget:\n event.target.value === '' ? undefined : (numberValue(event.target.value) as number) / 100,\n })\n }\n />\n <button className=\"btn btn-link\" type=\"button\" onClick={() => update('loadBalancingUtilization', {})}>\n Delete HTTP load-balancing metric\n </button>\n </div>\n </div>\n ) : (\n <button\n className=\"btn btn-link\"\n type=\"button\"\n onClick={() => update('loadBalancingUtilization', { utilizationTarget: undefined })}\n >\n Add HTTP load-balancing metric\n </button>\n )}\n\n {customMetrics.map((metric, index) => (\n <fieldset key={index} className=\"well well-sm\">\n <legend>Custom metric {index + 1}</legend>\n <input\n aria-label=\"Metric identifier\"\n className=\"form-control input-sm\"\n data-testid={`custom-metric-name-${index}`}\n placeholder=\"Metric identifier\"\n value={metric.metric || ''}\n onChange={(event) => updateCustomMetric(index, { metric: event.target.value })}\n />\n <input\n aria-label=\"Additional filter expression\"\n className=\"form-control input-sm\"\n placeholder=\"Additional filter expression\"\n value={metric.filter || ''}\n onChange={(event) => updateCustomMetric(index, { filter: event.target.value })}\n />\n <select\n aria-label=\"Metric export scope\"\n className=\"form-control input-sm\"\n value={metric.metricExportScope || ''}\n onChange={(event) => {\n const metricExportScope = event.target.value as GceMetricExportScope;\n const {\n scalingpolicy: _scalingpolicy,\n singleInstanceAssignment: _assignment,\n ...compatibleMetric\n } = metric;\n update(\n 'customMetricUtilizations',\n customMetrics.map((customMetric, metricIndex) =>\n metricIndex === index\n ? metricExportScope === 'TIME_SERIES_PER_INSTANCE'\n ? { ...compatibleMetric, metricExportScope }\n : { ...customMetric, metricExportScope, scalingpolicy: 'UTILIZATION_TARGET' }\n : customMetric,\n ),\n );\n }}\n >\n <option value=\"\">Select export scope</option>\n <option value=\"TIME_SERIES_PER_INSTANCE\">Time series per instance</option>\n <option value=\"SINGLE_TIME_SERIES_PER_GROUP\">Single time series per group</option>\n </select>\n {metric.metricExportScope === 'SINGLE_TIME_SERIES_PER_GROUP' && (\n <select\n aria-label=\"Scaling policy\"\n className=\"form-control input-sm\"\n value={metric.scalingpolicy || ''}\n onChange={(event) => updateCustomMetricScalingPolicy(index, event.target.value as GceScalingPolicyType)}\n >\n <option value=\"UTILIZATION_TARGET\">Utilization target</option>\n <option value=\"SINGLE_INSTANCE_ASSIGNMENT\">Single instance assignment</option>\n </select>\n )}\n {metric.scalingpolicy === 'SINGLE_INSTANCE_ASSIGNMENT' ? (\n <input\n aria-label=\"Single instance assignment\"\n className=\"form-control input-sm\"\n min={0}\n type=\"number\"\n value={metric.singleInstanceAssignment ?? ''}\n onChange={(event) =>\n updateCustomMetric(index, { singleInstanceAssignment: numberValue(event.target.value) })\n }\n />\n ) : (\n <>\n <input\n aria-label=\"Utilization target\"\n className=\"form-control input-sm\"\n data-testid={`custom-metric-target-${index}`}\n type=\"number\"\n value={metric.utilizationTarget ?? ''}\n onChange={(event) => updateCustomMetric(index, { utilizationTarget: numberValue(event.target.value) })}\n />\n <select\n aria-label=\"Utilization target type\"\n className=\"form-control input-sm\"\n value={metric.utilizationTargetType || ''}\n onChange={(event) =>\n updateCustomMetric(index, { utilizationTargetType: event.target.value as GceUtilizationTargetType })\n }\n >\n <option value=\"\">Select target type</option>\n <option value=\"GAUGE\">Gauge</option>\n <option value=\"DELTA_PER_SECOND\">Delta / second</option>\n <option value=\"DELTA_PER_MINUTE\">Delta / minute</option>\n </select>\n </>\n )}\n <button\n className=\"btn btn-link\"\n type=\"button\"\n onClick={() =>\n update(\n 'customMetricUtilizations',\n customMetrics.filter((_, metricIndex) => metricIndex !== index),\n )\n }\n >\n Delete custom metric\n </button>\n </fieldset>\n ))}\n <button\n className=\"btn btn-link\"\n type=\"button\"\n onClick={() => update('customMetricUtilizations', [...customMetrics, {}])}\n >\n Add custom metric\n </button>\n\n <h4>Scale-in controls</h4>\n <label className=\"checkbox-inline\">\n <input\n data-testid=\"scale-in-enabled\"\n type=\"checkbox\"\n checked={Boolean(policy.scaleInControl)}\n onChange={(event) =>\n update(\n 'scaleInControl',\n event.target.checked ? { maxScaledInReplicas: { percent: 0 }, timeWindowSec: 60 } : undefined,\n )\n }\n />{' '}\n Enable scale-in controls\n </label>\n {policy.scaleInControl && (\n <div className=\"form-group\">\n <label className=\"col-md-4 control-label\">Max scaled-in replicas</label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n data-testid=\"scale-in-maximum\"\n min={0}\n type=\"number\"\n value={scaleInMaximum ?? ''}\n onChange={(event) =>\n update('scaleInControl', {\n ...policy.scaleInControl,\n maxScaledInReplicas: { [scaleInUnit]: numberValue(event.target.value) },\n })\n }\n />\n <select\n className=\"form-control input-sm\"\n data-testid=\"scale-in-unit\"\n value={scaleInUnit}\n onChange={(event) =>\n update('scaleInControl', {\n ...policy.scaleInControl,\n maxScaledInReplicas: { [event.target.value]: scaleInMaximum },\n })\n }\n >\n <option value=\"percent\">percent</option>\n <option value=\"fixed\">fixed</option>\n </select>\n <input\n aria-label=\"Scale-in time window in seconds\"\n className=\"form-control input-sm\"\n max={3600}\n min={60}\n type=\"number\"\n value={policy.scaleInControl.timeWindowSec ?? ''}\n onChange={(event) =>\n update('scaleInControl', { ...policy.scaleInControl, timeWindowSec: numberValue(event.target.value) })\n }\n />\n </div>\n </div>\n )}\n\n <h4>Scaling schedules</h4>\n {schedules.map((schedule, index) => (\n <fieldset key={index} className=\"well well-sm\">\n <legend>Schedule {index + 1}</legend>\n <input\n aria-label=\"Schedule name\"\n className=\"form-control input-sm\"\n value={schedule.scheduleName || ''}\n onChange={(event) => updateSchedule(index, { scheduleName: event.target.value })}\n />\n <input\n aria-label=\"Schedule description\"\n className=\"form-control input-sm\"\n value={schedule.scheduleDescription || ''}\n onChange={(event) => updateSchedule(index, { scheduleDescription: event.target.value })}\n />\n <label className=\"checkbox-inline\">\n <input\n data-testid={`schedule-enabled-${index}`}\n type=\"checkbox\"\n checked={schedule.enabled ?? false}\n onChange={(event) => updateSchedule(index, { enabled: event.target.checked })}\n />{' '}\n Enabled\n </label>\n <input\n aria-label=\"Minimum required instances\"\n className=\"form-control input-sm\"\n data-testid={`schedule-minimum-${index}`}\n min={0}\n type=\"number\"\n value={schedule.minimumRequiredInstances ?? ''}\n onChange={(event) => updateSchedule(index, { minimumRequiredInstances: numberValue(event.target.value) })}\n />\n <input\n aria-label=\"CRON expression\"\n className=\"form-control input-sm\"\n value={schedule.scheduleCron || ''}\n onChange={(event) => updateSchedule(index, { scheduleCron: event.target.value })}\n />\n <select\n aria-label=\"Time zone\"\n className=\"form-control input-sm\"\n data-testid={`schedule-timezone-${index}`}\n value={schedule.timezone || ''}\n onChange={(event) => updateSchedule(index, { timezone: event.target.value })}\n >\n <option value=\"\">Select time zone</option>\n {timezones.map((timezone) => (\n <option key={timezone} value={timezone}>\n {timezone}\n </option>\n ))}\n </select>\n <input\n aria-label=\"Duration in seconds\"\n className=\"form-control input-sm\"\n min={301}\n type=\"number\"\n value={schedule.duration ?? ''}\n onChange={(event) => updateSchedule(index, { duration: numberValue(event.target.value) })}\n />\n <button\n className=\"btn btn-link\"\n type=\"button\"\n onClick={() =>\n update(\n 'scalingSchedules',\n schedules.filter((_, scheduleIndex) => scheduleIndex !== index),\n )\n }\n >\n Delete schedule\n </button>\n </fieldset>\n ))}\n <button className=\"btn btn-link\" type=\"button\" onClick={() => update('scalingSchedules', [...schedules, {}])}>\n Add scaling schedule\n </button>\n </div>\n );\n}\n","import React from 'react';\n\nimport type { IGceServerGroupCommand } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\nimport { GceAutoHealingPolicyEditor } from '../../../../autoHealingPolicy';\nimport { GceAutoscalingPolicyEditor } from '../../../../autoscalingPolicy';\nimport type { IGceAutoscalingPolicy } from '../../../../autoscalingPolicy';\nimport { GcePredictiveMethod } from '../../../../autoscalingPolicy';\nimport type { IGceAutoHealingPolicy } from '../../../../domain';\nimport { GCEProviderSettings } from '../../../../gce.settings';\n\nconst MAX_INT = 2147483647;\nconst MAX_SCHEDULE_DURATION_SECONDS = 14 * 24 * 60 * 60;\n\nfunction isIntegerInRange(value: unknown, minimum: number, maximum = MAX_INT): value is number {\n return (\n typeof value === 'number' &&\n Number.isFinite(value) &&\n Number.isInteger(value) &&\n value >= minimum &&\n value <= maximum\n );\n}\n\nfunction isUtilizationTarget(value: unknown, maximum?: number): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 && (maximum === undefined || value < maximum);\n}\n\nfunction isValidCustomMetric(metric: NonNullable<IGceAutoscalingPolicy['customMetricUtilizations']>[number]): boolean {\n if (!metric.metric?.trim() || !metric.metricExportScope) {\n return false;\n }\n if (\n metric.metricExportScope === 'SINGLE_TIME_SERIES_PER_GROUP' &&\n metric.scalingpolicy === 'SINGLE_INSTANCE_ASSIGNMENT'\n ) {\n return (\n typeof metric.singleInstanceAssignment === 'number' &&\n Number.isFinite(metric.singleInstanceAssignment) &&\n metric.singleInstanceAssignment >= 0\n );\n }\n if (metric.metricExportScope === 'SINGLE_TIME_SERIES_PER_GROUP' && metric.scalingpolicy !== 'UTILIZATION_TARGET') {\n return false;\n }\n return isUtilizationTarget(metric.utilizationTarget) && Boolean(metric.utilizationTargetType);\n}\n\nfunction hasValidMetrics(policy: IGceAutoscalingPolicy): boolean {\n const cpuConfigured = Boolean(policy.cpuUtilization && Object.keys(policy.cpuUtilization).length);\n const loadBalancingConfigured = Boolean(\n policy.loadBalancingUtilization && Object.keys(policy.loadBalancingUtilization).length,\n );\n const customMetrics = policy.customMetricUtilizations || [];\n const cpuValid = !cpuConfigured || isUtilizationTarget(policy.cpuUtilization?.utilizationTarget, 1);\n const loadBalancingValid =\n !loadBalancingConfigured || isUtilizationTarget(policy.loadBalancingUtilization?.utilizationTarget, 1);\n return (\n cpuValid &&\n loadBalancingValid &&\n customMetrics.every(isValidCustomMetric) &&\n ((cpuConfigured && cpuValid) ||\n (loadBalancingConfigured && loadBalancingValid) ||\n (customMetrics.length > 0 && customMetrics.every(isValidCustomMetric)))\n );\n}\n\nfunction hasValidSchedules(policy: IGceAutoscalingPolicy): boolean {\n return (policy.scalingSchedules || []).every(\n (schedule) =>\n Boolean(schedule.scheduleName?.trim()) &&\n isIntegerInRange(schedule.minimumRequiredInstances, 0, policy.maxNumReplicas) &&\n Boolean(schedule.scheduleCron?.trim()) &&\n Boolean(schedule.timezone?.trim()) &&\n isIntegerInRange(schedule.duration, 301, MAX_SCHEDULE_DURATION_SECONDS),\n );\n}\n\nfunction hasValidScaleInControl(policy: IGceAutoscalingPolicy): boolean {\n if (!policy.scaleInControl) {\n return true;\n }\n const { maxScaledInReplicas, timeWindowSec } = policy.scaleInControl;\n const hasFixed = maxScaledInReplicas?.fixed !== undefined;\n const hasPercent = maxScaledInReplicas?.percent !== undefined;\n if (hasFixed === hasPercent || !isIntegerInRange(timeWindowSec, 60, 3600)) {\n return false;\n }\n return hasPercent\n ? isIntegerInRange(maxScaledInReplicas?.percent, 0, 100)\n : isIntegerInRange(maxScaledInReplicas?.fixed, 0);\n}\n\nexport class Policies extends GceServerGroupWizardPage {\n public validate(values: IGceServerGroupCommand): { [key: string]: any } {\n const errors: { [key: string]: any } = {};\n\n if (values.autoscalingPolicy) {\n const policy = values.autoscalingPolicy as IGceAutoscalingPolicy;\n const policyErrors: { [key: string]: string } = {};\n const validMinimum = isIntegerInRange(policy.minNumReplicas, 0);\n const validMaximum = isIntegerInRange(policy.maxNumReplicas, 0);\n if (!validMinimum) {\n policyErrors.minNumReplicas = 'Minimum capacity must be a nonnegative integer.';\n }\n if (!validMaximum) {\n policyErrors.maxNumReplicas = 'Maximum capacity must be a nonnegative integer.';\n } else if (validMinimum && policy.maxNumReplicas < policy.minNumReplicas) {\n policyErrors.maxNumReplicas = 'Maximum capacity must be at least the minimum capacity.';\n }\n if (!isIntegerInRange(policy.coolDownPeriodSec, 15)) {\n policyErrors.coolDownPeriodSec = 'Cool-down period must be an integer of at least 15 seconds.';\n }\n if (!hasValidMetrics(policy)) {\n policyErrors.metric = 'At least one complete autoscaling metric required.';\n }\n if (!hasValidSchedules(policy)) {\n policyErrors.scalingSchedules = 'Every scaling schedule must be complete and within supported bounds.';\n }\n if (!hasValidScaleInControl(policy)) {\n policyErrors.scaleInControl = 'Scale-in control values are outside supported bounds.';\n }\n const predictiveEnabled = policy.cpuUtilization?.predictiveMethod === GcePredictiveMethod.STANDARD;\n if (predictiveEnabled && !GCEProviderSettings.feature.predictiveAutoscaling) {\n policyErrors.predictiveAutoscaling = 'Predictive autoscaling is not enabled.';\n }\n if (Object.keys(policyErrors).length) {\n errors.autoscalingPolicy = policyErrors;\n }\n }\n\n if (values.enableAutoHealing) {\n const policy = (values.autoHealingPolicy || {}) as IGceAutoHealingPolicy;\n const policyErrors: { [key: string]: string } = {};\n if (!policy.healthCheck?.trim()) {\n policyErrors.healthCheck = 'Health check required.';\n }\n if (!policy.healthCheckKind) {\n policyErrors.healthCheckKind = 'Health check kind required.';\n }\n if (!isIntegerInRange(policy.initialDelaySec, 0)) {\n policyErrors.initialDelaySec = 'Initial delay must be an integer between 0 and 2147483647 seconds.';\n }\n if (Object.keys(policyErrors).length) {\n errors.autoHealingPolicy = policyErrors;\n }\n }\n\n return errors;\n }\n\n private setField = (field: string, value: any): void => {\n this.props.formik.setFieldValue(field, value);\n };\n\n private toggleAutoscaling = (enabled: boolean): void => {\n const { values } = this.props.formik;\n const persistedPolicy = values.autoscalingPolicy as IGceAutoscalingPolicy | undefined;\n this.setField(\n 'overwriteAncestorAutoscalingPolicy',\n !enabled && values.viewState?.mode === 'clone' && Boolean(persistedPolicy),\n );\n if (enabled) {\n const desired = values.capacity?.desired ?? 1;\n this.setAutoscalingPolicy(\n persistedPolicy || {\n minNumReplicas: desired,\n maxNumReplicas: desired,\n coolDownPeriodSec: 60,\n cpuUtilization: { utilizationTarget: 0.5 },\n },\n );\n return;\n }\n\n this.setField('enableAutoScaling', false);\n this.setField('autoscalingPolicy', null);\n this.setField('source', { ...values.source, useSourceCapacity: false });\n this.setField('viewState', { ...values.viewState, useSimpleCapacity: true });\n const desired = values.capacity?.desired ?? 1;\n this.setField('capacity', { min: desired, max: desired, desired });\n };\n\n private setAutoscalingPolicy = (policy: IGceAutoscalingPolicy): void => {\n const { values } = this.props.formik;\n const min = policy.minNumReplicas;\n const max = policy.maxNumReplicas;\n const desired = coherentDesiredCapacity(values.capacity?.desired, min, max);\n\n this.setField('enableAutoScaling', true);\n this.setField('autoscalingPolicy', policy);\n this.setField('source', { ...values.source, useSourceCapacity: false });\n this.setField('viewState', { ...values.viewState, useSimpleCapacity: false });\n this.setField('capacity', { ...values.capacity, min, max, desired });\n };\n\n private toggleAutohealing = (enabled: boolean): void => {\n const { values } = this.props.formik;\n const persistedPolicy = values.autoHealingPolicy as IGceAutoHealingPolicy | undefined;\n this.setField('enableAutoHealing', enabled);\n this.setField(\n 'overwriteAncestorAutoHealingPolicy',\n !enabled && values.viewState?.mode === 'clone' && Boolean(persistedPolicy),\n );\n if (enabled && !persistedPolicy) {\n this.setField('autoHealingPolicy', { initialDelaySec: 300 });\n }\n };\n\n private filteredHealthCheckReader(): any {\n const { values } = this.props.formik;\n const healthChecks = values.backingData?.filtered?.healthChecks || [];\n return {\n listHealthChecks: () =>\n Promise.resolve(\n healthChecks.map((healthCheck: any) => ({\n ...healthCheck,\n account: values.credentials,\n })),\n ),\n };\n }\n\n public render(): JSX.Element {\n const { values } = this.props.formik;\n const autoscalingEnabled = Boolean(values.autoscalingPolicy);\n const autohealingEnabled = values.enableAutoHealing ?? Boolean(values.autoHealingPolicy);\n\n return (\n <div className=\"container-fluid form-horizontal\" data-testid=\"gce-policies-page\">\n <section>\n <div className=\"form-group\">\n <div className=\"col-md-4 sm-label-right\">\n <b>Enable Autoscaling</b>\n </div>\n <div className=\"col-md-6 checkbox\">\n <label>\n <input\n checked={autoscalingEnabled}\n data-testid=\"enable-autoscaling\"\n onChange={(event) => this.toggleAutoscaling(event.target.checked)}\n type=\"checkbox\"\n />\n <span className=\"sr-only\">Enable Autoscaling</span>\n </label>\n </div>\n </div>\n {autoscalingEnabled && (\n <GceAutoscalingPolicyEditor\n policy={(values.autoscalingPolicy || {}) as IGceAutoscalingPolicy}\n onChange={this.setAutoscalingPolicy}\n />\n )}\n </section>\n\n <section>\n <div className=\"form-group\">\n <div className=\"col-md-4 sm-label-right\">\n <b>Enable Autohealing</b>\n </div>\n <div className=\"col-md-6 checkbox\">\n <label>\n <input\n checked={autohealingEnabled}\n data-testid=\"enable-autohealing\"\n onChange={(event) => this.toggleAutohealing(event.target.checked)}\n type=\"checkbox\"\n />\n <span className=\"sr-only\">Enable Autohealing</span>\n </label>\n </div>\n </div>\n {autohealingEnabled && (\n <GceAutoHealingPolicyEditor\n key={values.credentials || ''}\n account={values.credentials || ''}\n policy={(values.autoHealingPolicy || {}) as IGceAutoHealingPolicy}\n reader={this.filteredHealthCheckReader()}\n onChange={(policy) => this.setField('autoHealingPolicy', policy)}\n />\n )}\n </section>\n </div>\n );\n }\n}\n\nfunction coherentDesiredCapacity(desired: any, min: any, max: any): any {\n if (typeof desired === 'number' && typeof min === 'number' && typeof max === 'number') {\n return Math.min(max, Math.max(min, desired));\n }\n return desired ?? min ?? max ?? 1;\n}\n","import React from 'react';\n\nimport { DeploymentStrategySelector, TaskReason } from '@spinnaker/core';\n\nimport { preservePersistedReference, validateGceServerGroupCommand } from '../GceServerGroupWizard.helpers';\nimport type {\n GceCommandHandlerName,\n IGceServerGroupCommand,\n IGceServerGroupCommandValidationErrors,\n} from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\nimport { GceImageReader } from '../../../../image';\n\ninterface ISelectOption {\n label: string;\n unavailable?: boolean;\n value: string;\n}\n\nexport class ServerGroupBasicSettings extends GceServerGroupWizardPage {\n public validate(values: IGceServerGroupCommand): IGceServerGroupCommandValidationErrors {\n const sharedErrors = validateGceServerGroupCommand(values);\n const errors: IGceServerGroupCommandValidationErrors = {};\n if (sharedErrors.credentials) errors.credentials = sharedErrors.credentials;\n if (sharedErrors.region) errors.region = sharedErrors.region;\n if (sharedErrors.zone) errors.zone = sharedErrors.zone;\n if (sharedErrors.stack) errors.stack = sharedErrors.stack;\n if (sharedErrors.freeFormDetails) errors.freeFormDetails = sharedErrors.freeFormDetails;\n const stackPattern = values.viewState.templatingEnabled ? /^([a-zA-Z0-9]*(\\${.+})*)*$/ : /^[a-zA-Z0-9]*$/;\n const detailPattern = values.viewState.templatingEnabled ? /^([a-zA-Z0-9-]*(\\${.+})*)*$/ : /^[a-zA-Z0-9-]*$/;\n\n if (values.stack && !stackPattern.test(values.stack)) {\n errors.stack = 'Stack can only contain letters and numbers.';\n }\n if (values.freeFormDetails && !detailPattern.test(values.freeFormDetails)) {\n errors.freeFormDetails = 'Detail can only contain letters, numbers, and dashes.';\n }\n\n return errors;\n }\n\n private parentChanged = (\n field: string,\n value: string | boolean,\n handler: GceCommandHandlerName,\n ): Promise<IGceServerGroupCommand | undefined> => {\n const command = { ...this.props.formik.values, [field]: value };\n return this.runLatestCommandRequest(\n command,\n async (latestCommand) => (await this.adapter.applyCommandHandler(latestCommand, handler)).command,\n );\n };\n\n private accountChanged = (account: string): Promise<IGceServerGroupCommand | undefined> => {\n const command = { ...this.props.formik.values, credentials: account };\n return this.runLatestCommandRequest(command, async (latestCommand) => {\n const images = await GceImageReader.findImages({ account, provider: latestCommand.selectedProvider, q: '*' });\n const commandWithImages = {\n ...latestCommand,\n backingData: { ...latestCommand.backingData, allImages: images },\n };\n return (await this.adapter.applyCommandHandler(commandWithImages, 'credentialsChanged')).command;\n });\n };\n\n private renderSelect(\n label: string,\n field: string,\n options: ISelectOption[],\n onChange?: (value: string) => void,\n error?: string,\n ) {\n const id = `gce-server-group-${field}`;\n const errorId = `${id}-error`;\n const fieldValue = this.props.formik.values[field];\n const value = field === 'regional' ? (fieldValue ? 'regional' : 'zonal') : fieldValue || '';\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={id}>\n {label}\n </label>\n <div className=\"col-md-7\">\n <select\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={label}\n className=\"form-control input-sm\"\n id={id}\n onChange={(event) =>\n onChange ? onChange(event.target.value) : this.props.formik.setFieldValue(field, event.target.value)\n }\n value={value}\n >\n <option value=\"\">Select...</option>\n {options.map((option) => (\n <option disabled={option.unavailable} key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n {error && (\n <span className=\"help-block\" id={errorId} role=\"alert\">\n {error}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n private renderTextField(label: string, field: 'stack' | 'freeFormDetails', error?: string) {\n const id = `gce-server-group-${field}`;\n const errorId = `${id}-error`;\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={id}>\n {label}\n </label>\n <div className=\"col-md-7\">\n <input\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={label}\n className=\"form-control input-sm\"\n id={id}\n onChange={(event) => this.props.formik.setFieldValue(field, event.target.value)}\n type=\"text\"\n value={this.props.formik.values[field] || ''}\n />\n {error && (\n <span className=\"help-block\" id={errorId} role=\"alert\">\n {error}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n private strategyChanged = (command: IGceServerGroupCommand, strategy: any): void => {\n command.onStrategyChange?.(command, strategy);\n this.props.formik.setValues({ ...command, strategy: strategy.key });\n };\n\n private strategyFieldChanged = (field: string, value: any): void => {\n this.props.formik.setFieldValue(field, value);\n };\n\n public render(): JSX.Element {\n const { values } = this.props.formik;\n const filtered = values.backingData?.filtered || {};\n const accounts = referenceOptions(values.backingData?.accounts, values.credentials, ['name']);\n const regions = referenceOptions(filtered.regions, values.region, ['name']);\n const zones = referenceOptions(filtered.zones, values.zone, ['name']);\n const networks = referenceOptions(filtered.networks, values.network, ['id', 'name']);\n const subnets = referenceOptions(filtered.subnets, values.subnet, ['id', 'name']);\n const errors = this.validate(values);\n\n return (\n <div className=\"container-fluid form-horizontal\">\n {this.renderSelect('Account', 'credentials', accounts, this.accountChanged, errors.credentials)}\n {this.renderSelect(\n 'Region',\n 'region',\n regions,\n (region) => this.parentChanged('region', region, 'regionChanged'),\n errors.region,\n )}\n {this.renderSelect(\n 'Location mode',\n 'regional',\n [\n { label: 'Zonal', value: 'zonal' },\n { label: 'Regional', value: 'regional' },\n ],\n (mode) => this.parentChanged('regional', mode === 'regional', 'regionalChanged'),\n )}\n {!values.regional &&\n this.renderSelect(\n 'Zone',\n 'zone',\n zones,\n (zone) => this.parentChanged('zone', zone, 'zoneChanged'),\n errors.zone,\n )}\n {this.renderSelect('Network', 'network', networks, (network) =>\n this.parentChanged('network', network, 'networkChanged'),\n )}\n {this.renderSelect('Subnet', 'subnet', subnets)}\n {this.renderTextField('Stack', 'stack', errors.stack)}\n {this.renderTextField('Detail', 'freeFormDetails', errors.freeFormDetails)}\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">Traffic</div>\n <div className=\"col-md-7 checkbox\">\n <label>\n <input\n aria-label=\"Send client requests to new instances\"\n checked={values.enableTraffic !== false}\n onChange={(event) => this.props.formik.setFieldValue('enableTraffic', event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Send client requests to new instances\n </label>\n </div>\n </div>\n {!values.viewState.disableStrategySelection && values.selectedProvider && (\n <div aria-label=\"Deployment strategy\" role=\"group\">\n <DeploymentStrategySelector\n command={values as any}\n onFieldChange={this.strategyFieldChanged}\n onStrategyChange={this.strategyChanged as any}\n />\n </div>\n )}\n <TaskReason\n reason={values.reason || ''}\n onChange={(reason) => this.props.formik.setFieldValue('reason', reason)}\n />\n </div>\n );\n }\n}\n\nfunction referenceOptions(\n rawOptions: readonly any[] | null | undefined,\n persistedValue: string | null | undefined,\n objectKeys: string[],\n): ISelectOption[] {\n const values = (rawOptions || []).map((option) => optionValue(option, objectKeys)).filter(Boolean);\n return preservePersistedReference(\n values,\n persistedValue,\n (value) => value,\n (value) => value,\n ).map(({ unresolved, value }) => ({\n label: unresolved ? `${value} (unavailable)` : value,\n unavailable: unresolved,\n value,\n }));\n}\n\nfunction optionValue(option: any, objectKeys: string[]): string {\n if (typeof option === 'string') {\n return option;\n }\n return objectKeys.map((key) => option?.[key]).find(Boolean) || '';\n}\n","import { isEmpty } from 'lodash';\nimport React from 'react';\n\nimport { HelpField } from '@spinnaker/core';\n\nimport type { IGceInstanceFlexibilityPolicy, IGceInstanceSelection } from '../../../../domain/serverGroup';\n\nexport interface IGceInstanceFlexibilityConfigurerProps {\n instanceFlexibilityPolicy?: IGceInstanceFlexibilityPolicy;\n regional?: boolean;\n targetShape?: string;\n validationError?: string;\n setInstanceFlexibilityPolicy: (policy: IGceInstanceFlexibilityPolicy) => void;\n}\n\nconst FLEX_TARGET_SHAPES = new Set(['BALANCED', 'ANY', 'ANY_SINGLE_ZONE']);\nconst VALIDATION_ERROR_ID = 'gce-instance-flexibility-error';\n\nfunction hasSelections(policy?: IGceInstanceFlexibilityPolicy): boolean {\n return !isEmpty(policy?.instanceSelections);\n}\n\nfunction emptySelection(): IGceInstanceSelection {\n return { machineTypes: [''] };\n}\n\n/** First unused selection-N name so rename/remove cannot overwrite an existing entry. */\nexport function nextSelectionName(existingNames: string[]): string {\n const used = new Set(existingNames);\n let index = 1;\n while (used.has(`selection-${index}`)) {\n index += 1;\n }\n return `selection-${index}`;\n}\n\nfunction hasNonEmptyMachineTypes(selection?: IGceInstanceSelection): boolean {\n const machineTypes = selection?.machineTypes || [];\n return machineTypes.length > 0 && machineTypes.every((machineType) => !!machineType && machineType.trim().length > 0);\n}\n\nfunction normalizeMachineType(machineType?: string | null): string | undefined {\n const trimmed = machineType?.trim();\n if (!trimmed) {\n return undefined;\n }\n return trimmed.substring(trimmed.lastIndexOf('/') + 1).toLowerCase();\n}\n\n// GCP requires each normalized machine type to occur only once across the entire policy.\nfunction hasUniqueMachineTypes(policy?: IGceInstanceFlexibilityPolicy): boolean {\n const machineTypes = new Set<string>();\n for (const selection of Object.values(policy?.instanceSelections || {})) {\n for (const machineType of selection?.machineTypes || []) {\n const normalizedMachineType = normalizeMachineType(machineType);\n if (normalizedMachineType && machineTypes.has(normalizedMachineType)) {\n return false;\n }\n if (normalizedMachineType) {\n machineTypes.add(normalizedMachineType);\n }\n }\n }\n return true;\n}\n\nfunction hasValidRank(selection?: IGceInstanceSelection): boolean {\n return (\n selection?.rank == null ||\n (Number.isFinite(selection.rank) && Number.isInteger(selection.rank) && selection.rank >= 0)\n );\n}\n\nexport function GceInstanceFlexibilityConfigurer({\n instanceFlexibilityPolicy,\n regional,\n targetShape: targetShapeProp,\n validationError,\n setInstanceFlexibilityPolicy,\n}: IGceInstanceFlexibilityConfigurerProps) {\n const policy = instanceFlexibilityPolicy || { instanceSelections: {} };\n const entries = Object.entries(policy.instanceSelections || {});\n const enabled = entries.length > 0;\n const targetShape = (targetShapeProp || '').trim().toUpperCase();\n const regionalRequired = enabled && !regional;\n const evenBlocked = enabled && (!targetShape || targetShape === 'EVEN' || !FLEX_TARGET_SHAPES.has(targetShape));\n const duplicateMachineTypes = enabled && !hasUniqueMachineTypes(policy);\n\n const updateSelections = (instanceSelections: { [name: string]: IGceInstanceSelection }) => {\n setInstanceFlexibilityPolicy({ instanceSelections });\n };\n\n const addSelection = () => {\n const nextName = nextSelectionName(Object.keys(policy.instanceSelections || {}));\n updateSelections({ ...policy.instanceSelections, [nextName]: emptySelection() });\n };\n\n const removeSelection = (name: string) => {\n const next = { ...policy.instanceSelections };\n delete next[name];\n updateSelections(next);\n };\n\n const renameSelection = (oldName: string, newName: string): boolean => {\n const trimmed = newName.trim();\n if (!trimmed || trimmed === oldName || policy.instanceSelections[trimmed]) {\n return false;\n }\n const next: { [name: string]: IGceInstanceSelection } = {};\n Object.entries(policy.instanceSelections).forEach(([name, selection]) => {\n next[name === oldName ? trimmed : name] = selection;\n });\n updateSelections(next);\n return true;\n };\n\n const updateSelection = (name: string, selection: IGceInstanceSelection) => {\n updateSelections({ ...policy.instanceSelections, [name]: selection });\n };\n\n const updateMachineType = (name: string, index: number, value: string) => {\n const selection = policy.instanceSelections[name];\n const machineTypes = [...(selection.machineTypes || [])];\n machineTypes[index] = value;\n updateSelection(name, { ...selection, machineTypes });\n };\n\n const addMachineType = (name: string) => {\n const selection = policy.instanceSelections[name];\n updateSelection(name, {\n ...selection,\n machineTypes: [...(selection.machineTypes || []), ''],\n });\n };\n\n const removeMachineType = (name: string, index: number) => {\n const selection = policy.instanceSelections[name];\n const machineTypes = (selection.machineTypes || []).filter((_type, i) => i !== index);\n updateSelection(name, {\n ...selection,\n machineTypes: machineTypes.length ? machineTypes : [''],\n });\n };\n\n const updateRank = (name: string, rawRank: string) => {\n const selection = policy.instanceSelections[name];\n if (rawRank === '') {\n const { rank, ...withoutRank } = selection;\n updateSelection(name, withoutRank as IGceInstanceSelection);\n return;\n }\n const parsed = Number(rawRank);\n if (Number.isFinite(parsed) && Number.isInteger(parsed) && parsed >= 0) {\n updateSelection(name, { ...selection, rank: parsed });\n }\n };\n\n return (\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">\n <b>Instance Flexibility</b> <HelpField id=\"gce.serverGroup.instanceFlexibilityPolicy\" />\n </div>\n <div className=\"col-md-9\">\n {validationError && (\n <div className=\"alert alert-danger\" id={VALIDATION_ERROR_ID} role=\"alert\">\n {validationError}\n </div>\n )}\n {!enabled && (\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={addSelection}>\n Add flexibility policy\n </button>\n )}\n {enabled && (\n <div>\n {regionalRequired && (\n <div className=\"alert alert-warning\">Flexibility requires a regional server group.</div>\n )}\n {evenBlocked && (\n <div className=\"alert alert-warning\">\n Flexibility requires target shape BALANCED, ANY, or ANY_SINGLE_ZONE (not EVEN).\n </div>\n )}\n {duplicateMachineTypes && (\n <div className=\"alert alert-warning\" role=\"alert\">\n Machine types must be unique across instance selections.\n </div>\n )}\n {entries.map(([name, selection]) => (\n <div key={name} className=\"well well-sm\" style={{ marginBottom: '10px' }} data-selection-name={name}>\n {(() => {\n const selectionId = `instance-flexibility-selection-${encodeURIComponent(name)}`;\n const rankInvalid = !hasValidRank(selection);\n return (\n <>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={`${selectionId}-name`}>\n Selection name\n </label>\n <div className=\"col-md-6\">\n <input\n id={`${selectionId}-name`}\n className=\"form-control input-sm\"\n defaultValue={name}\n onBlur={(e) => {\n if (!renameSelection(name, e.currentTarget.value)) {\n e.currentTarget.value = name;\n }\n }}\n />\n </div>\n <div className=\"col-md-3\">\n <button\n type=\"button\"\n className=\"btn btn-sm btn-default\"\n aria-label={`Remove selection ${name}`}\n onClick={() => removeSelection(name)}\n >\n Remove\n </button>\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={`${selectionId}-rank`}>\n Rank (optional)\n </label>\n <div className=\"col-md-3\">\n <input\n id={`${selectionId}-rank`}\n type=\"number\"\n min={0}\n step={1}\n className=\"form-control input-sm\"\n aria-describedby={rankInvalid && validationError ? VALIDATION_ERROR_ID : undefined}\n aria-invalid={rankInvalid}\n value={selection.rank == null ? '' : selection.rank}\n onChange={(e) => updateRank(name, e.target.value)}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">Machine types</div>\n <div className=\"col-md-9\">\n {(selection.machineTypes || []).map((machineType, index) => (\n <div key={index} style={{ display: 'flex', marginBottom: '4px' }}>\n <input\n id={`${selectionId}-machine-type-${index}`}\n className=\"form-control input-sm\"\n aria-describedby={\n !machineType?.trim() && validationError ? VALIDATION_ERROR_ID : undefined\n }\n aria-invalid={!machineType?.trim()}\n value={machineType}\n onChange={(e) => updateMachineType(name, index, e.target.value)}\n placeholder=\"e.g. n2-standard-8\"\n aria-label={`Machine type ${index + 1} for selection ${name}`}\n />\n <button\n type=\"button\"\n className=\"btn btn-sm btn-default\"\n style={{ marginLeft: '4px' }}\n aria-label={`Remove machine type ${index + 1} from selection ${name}`}\n onClick={() => removeMachineType(name, index)}\n >\n ×\n </button>\n </div>\n ))}\n <button type=\"button\" className=\"btn btn-sm btn-link\" onClick={() => addMachineType(name)}>\n Add machine type\n </button>\n </div>\n </div>\n </>\n );\n })()}\n </div>\n ))}\n <button type=\"button\" className=\"btn btn-sm btn-default\" onClick={addSelection}>\n Add selection\n </button>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function hasValidFlexibilityPolicy(command: {\n regional?: boolean;\n distributionPolicy?: { targetShape?: string };\n instanceFlexibilityPolicy?: IGceInstanceFlexibilityPolicy;\n}): boolean {\n if (!hasSelections(command.instanceFlexibilityPolicy)) {\n return true;\n }\n if (!command.regional) {\n return false;\n }\n const targetShape = (command.distributionPolicy?.targetShape || '').trim().toUpperCase();\n if (!FLEX_TARGET_SHAPES.has(targetShape)) {\n return false;\n }\n // Clouddriver rejects empty machineTypes and negative ranks; blank placeholders must not pass submit.\n return (\n Object.values(command.instanceFlexibilityPolicy.instanceSelections || {}).every(\n (selection) => hasNonEmptyMachineTypes(selection) && hasValidRank(selection),\n ) && hasUniqueMachineTypes(command.instanceFlexibilityPolicy)\n );\n}\n","import React from 'react';\n\nimport type { GceCommandHandlerName, IGceServerGroupCommand } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\nimport type { IGceInstanceFlexibilityPolicy } from '../../../../domain/serverGroup';\nimport { GceInstanceFlexibilityConfigurer, hasValidFlexibilityPolicy } from '../zones/GceInstanceFlexibilityConfigurer';\n\ninterface ICapacityValidationErrors {\n autoscalingPolicy?: {\n maxNumReplicas?: string;\n minNumReplicas?: string;\n };\n capacity?: { desired?: string };\n distributionPolicy?: { targetShape?: string; zones?: string };\n instanceFlexibilityPolicy?: string;\n zone?: string;\n}\n\ninterface IZoneOption {\n unavailable: boolean;\n value: string;\n}\n\ntype CapacityValue = number | string | null | undefined;\n\nconst INTEGER_ERROR = 'must be a finite non-negative integer.';\n\nexport class ServerGroupCapacity extends GceServerGroupWizardPage {\n public validate(values: IGceServerGroupCommand): ICapacityValidationErrors {\n const errors: ICapacityValidationErrors = {};\n const desired = values.capacity?.desired;\n\n if (!isValidCapacityValue(desired, values)) {\n errors.capacity = { desired: `Desired capacity ${INTEGER_ERROR}` };\n }\n\n if (values.autoscalingPolicy) {\n const min = values.autoscalingPolicy?.minNumReplicas;\n const max = values.autoscalingPolicy?.maxNumReplicas;\n\n if (!isValidCapacityValue(min, values)) {\n errors.autoscalingPolicy = {\n ...errors.autoscalingPolicy,\n minNumReplicas: `Minimum capacity ${INTEGER_ERROR}`,\n };\n }\n if (!isValidCapacityValue(max, values)) {\n errors.autoscalingPolicy = {\n ...errors.autoscalingPolicy,\n maxNumReplicas: `Maximum capacity ${INTEGER_ERROR}`,\n };\n }\n if (isNonNegativeInteger(desired) && isNonNegativeInteger(min) && desired < min) {\n errors.capacity = { desired: 'Desired capacity must be at least minimum capacity.' };\n } else if (isNonNegativeInteger(desired) && isNonNegativeInteger(max) && desired > max) {\n errors.capacity = { desired: 'Desired capacity must not exceed maximum capacity.' };\n }\n }\n\n if (!values.regional && !values.zone?.trim()) {\n errors.zone = 'Zone required.';\n }\n if (values.regional && values.selectZones && !values.distributionPolicy?.zones?.length) {\n errors.distributionPolicy = { zones: 'At least one zone required.' };\n }\n if (!hasValidFlexibilityPolicy(values)) {\n errors.instanceFlexibilityPolicy = 'Instance flexibility policy is invalid.';\n }\n\n return errors;\n }\n\n private commandChanged = (\n command: IGceServerGroupCommand,\n handlers: GceCommandHandlerName[],\n ): Promise<IGceServerGroupCommand | undefined> =>\n this.runLatestCommandRequest(command, async (latestCommand) => {\n let nextCommand = latestCommand;\n for (const handler of handlers) {\n nextCommand = (await this.adapter.applyCommandHandler(nextCommand, handler)).command;\n }\n return nextCommand;\n });\n\n private capacityChanged = (field: 'desired' | 'max' | 'min', rawValue: string): void => {\n const value = parseCapacity(rawValue, this.props.formik.values);\n if (value === undefined) {\n return;\n }\n\n const { values } = this.props.formik;\n if (!values.autoscalingPolicy) {\n this.props.formik.setFieldValue('capacity', { min: value, max: value, desired: value });\n return;\n }\n\n if (field === 'desired') {\n this.props.formik.setFieldValue('capacity', { ...values.capacity, desired: value });\n return;\n }\n\n const policyField = field === 'min' ? 'minNumReplicas' : 'maxNumReplicas';\n this.props.formik.setFieldValue('autoscalingPolicy', {\n ...values.autoscalingPolicy,\n [policyField]: value,\n });\n this.props.formik.setFieldValue('capacity', { ...values.capacity, [field]: value });\n };\n\n private capacityModeChanged = (useSimpleCapacity: boolean): void => {\n const { values } = this.props.formik;\n this.props.formik.setFieldValue(\n 'overwriteAncestorAutoscalingPolicy',\n useSimpleCapacity && values.viewState?.mode === 'clone' && Boolean(values.autoscalingPolicy),\n );\n this.props.formik.setFieldValue('viewState', { ...values.viewState, useSimpleCapacity });\n this.props.formik.setFieldValue('source', { ...values.source, useSourceCapacity: false });\n\n if (useSimpleCapacity) {\n this.props.formik.setFieldValue('enableAutoScaling', false);\n this.props.formik.setFieldValue('autoscalingPolicy', null);\n if (isValidCapacityValue(values.capacity?.desired, values)) {\n const desired = values.capacity.desired;\n this.props.formik.setFieldValue('capacity', { min: desired, max: desired, desired });\n }\n return;\n }\n\n const desired = values.capacity?.desired ?? 1;\n const policy = values.autoscalingPolicy || {\n minNumReplicas: desired,\n maxNumReplicas: desired,\n coolDownPeriodSec: 60,\n cpuUtilization: { utilizationTarget: 0.5 },\n };\n this.props.formik.setFieldValue('enableAutoScaling', true);\n this.props.formik.setFieldValue('autoscalingPolicy', policy);\n this.props.formik.setFieldValue('capacity', {\n ...values.capacity,\n min: policy.minNumReplicas,\n max: policy.maxNumReplicas,\n desired: coherentDesiredCapacity(desired, policy.minNumReplicas, policy.maxNumReplicas),\n });\n };\n\n private regionalChanged = (regional: boolean): void => {\n void this.commandChanged({ ...this.props.formik.values, regional }, [\n 'regionalChanged',\n 'regionChanged',\n 'zoneChanged',\n 'selectZonesChanged',\n ]);\n };\n\n private zoneChanged = (zone: string): void => {\n void this.commandChanged({ ...this.props.formik.values, zone }, ['zoneChanged', 'selectZonesChanged']);\n };\n\n private selectZonesChanged = (selectZones: boolean): void => {\n void this.commandChanged({ ...this.props.formik.values, selectZones }, ['selectZonesChanged', 'zoneChanged']);\n };\n\n private selectedZoneChanged = (zone: string, selected: boolean): void => {\n const values = this.props.formik.values;\n const selectedZones = values.distributionPolicy?.zones || [];\n const zones = selected\n ? Array.from(new Set([...selectedZones, zone]))\n : selectedZones.filter((item) => item !== zone);\n const command = {\n ...values,\n distributionPolicy: { ...values.distributionPolicy, zones },\n };\n void this.commandChanged(command, ['selectZonesChanged', 'zoneChanged']);\n };\n\n private targetShapeChanged = (targetShape: string): void => {\n const { values } = this.props.formik;\n this.props.formik.setFieldValue('distributionPolicy', { ...values.distributionPolicy, targetShape });\n };\n\n private instanceFlexibilityPolicyChanged = (instanceFlexibilityPolicy: IGceInstanceFlexibilityPolicy): void => {\n this.props.formik.setFieldValue('instanceFlexibilityPolicy', instanceFlexibilityPolicy);\n };\n\n private renderCapacityInput(label: string, field: 'desired' | 'max' | 'min', value: CapacityValue) {\n const id = `gce-capacity-${field}`;\n const error = capacityError(this.props.formik.errors, field);\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor={id}>\n {label}\n </label>\n <div className=\"col-md-3\">\n <input\n aria-describedby={error ? `${id}-error` : undefined}\n aria-invalid={Boolean(error)}\n aria-label={`${label} capacity`}\n className=\"form-control input-sm\"\n id={id}\n min={0}\n onChange={(event) => this.capacityChanged(field, event.target.value)}\n required={true}\n step={1}\n type={isPipelineMode(this.props.formik.values) ? 'text' : 'number'}\n value={value ?? ''}\n />\n {error && (\n <span className=\"help-block\" id={`${id}-error`} role=\"alert\">\n {error}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n private renderZonalLocation(): React.ReactNode {\n const values = this.props.formik.values;\n const zones = zoneOptions(values.backingData?.filtered?.zones, values.zone ? [values.zone] : []);\n const error = (this.props.formik.errors as any)?.zone;\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-capacity-zone\">\n Zone\n </label>\n <div className=\"col-md-7\">\n <select\n aria-describedby={error ? 'gce-capacity-zone-error' : undefined}\n aria-invalid={Boolean(error)}\n aria-label=\"Zone\"\n className=\"form-control input-sm\"\n id=\"gce-capacity-zone\"\n onChange={(event) => this.zoneChanged(event.target.value)}\n required={true}\n value={values.zone || ''}\n >\n <option value=\"\">Select...</option>\n {zones.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (unavailable)' : ''}\n </option>\n ))}\n </select>\n {error && (\n <span className=\"help-block\" id=\"gce-capacity-zone-error\" role=\"alert\">\n {error}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n private renderRegionalDistribution(): React.ReactNode {\n const values = this.props.formik.values;\n const selectedZones = values.distributionPolicy?.zones || [];\n const zones = zoneOptions(values.backingData?.filtered?.zones, selectedZones);\n const errors = this.props.formik.errors as any;\n const zonesError = errors?.distributionPolicy?.zones;\n const targetShapes: string[] = values.backingData?.distributionPolicyTargetShapes || [\n 'ANY',\n 'EVEN',\n 'BALANCED',\n 'ANY_SINGLE_ZONE',\n ];\n\n return (\n <div>\n <fieldset className=\"form-group\">\n <legend className=\"col-md-3 sm-label-right\">Distribution</legend>\n <div className=\"col-md-7\">\n <label className=\"radio-inline\" htmlFor=\"gce-capacity-preferred-zones\">\n <input\n aria-label=\"Preferred zone distribution\"\n checked={!values.selectZones}\n id=\"gce-capacity-preferred-zones\"\n name=\"gce-capacity-zone-distribution\"\n onChange={(event) => event.target.checked && this.selectZonesChanged(false)}\n type=\"radio\"\n />\n Preferred zones\n </label>\n <label className=\"radio-inline\" htmlFor=\"gce-capacity-explicit-zones\">\n <input\n aria-label=\"Explicit zone distribution\"\n checked={Boolean(values.selectZones)}\n id=\"gce-capacity-explicit-zones\"\n name=\"gce-capacity-zone-distribution\"\n onChange={(event) => event.target.checked && this.selectZonesChanged(true)}\n type=\"radio\"\n />\n Select zones explicitly\n </label>\n </div>\n </fieldset>\n\n {values.selectZones && (\n <fieldset aria-describedby={zonesError ? 'gce-capacity-zones-error' : undefined} className=\"form-group\">\n <legend className=\"col-md-3 sm-label-right\">Zones</legend>\n <div aria-invalid={Boolean(zonesError)} className=\"col-md-7\">\n {zones.map(({ unavailable, value }) => {\n const id = `gce-capacity-zone-${value}`;\n return (\n <div className=\"checkbox\" key={value}>\n <label htmlFor={id}>\n <input\n aria-label={`Zone ${value}`}\n checked={selectedZones.includes(value)}\n id={id}\n onChange={(event) => this.selectedZoneChanged(value, event.target.checked)}\n type=\"checkbox\"\n />\n {value}\n {unavailable ? ' (unavailable)' : ''}\n </label>\n </div>\n );\n })}\n {zonesError && (\n <span className=\"help-block\" id=\"gce-capacity-zones-error\" role=\"alert\">\n {zonesError}\n </span>\n )}\n </div>\n </fieldset>\n )}\n\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-capacity-target-shape\">\n Target shape\n </label>\n <div className=\"col-md-3\">\n <select\n aria-label=\"Target shape\"\n className=\"form-control input-sm\"\n id=\"gce-capacity-target-shape\"\n onChange={(event) => this.targetShapeChanged(event.target.value)}\n value={values.distributionPolicy?.targetShape || ''}\n >\n <option value=\"\">Select...</option>\n {targetShapes.map((targetShape) => (\n <option key={targetShape} value={targetShape}>\n {targetShape}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n );\n }\n\n public render(): JSX.Element {\n const { values } = this.props.formik;\n const useSimpleCapacity = !values.autoscalingPolicy;\n\n return (\n <div className=\"container-fluid form-horizontal\">\n <fieldset className=\"form-group\">\n <legend className=\"col-md-3 sm-label-right\">Capacity mode</legend>\n <div className=\"col-md-7\">\n <label className=\"radio-inline\" htmlFor=\"gce-capacity-simple\">\n <input\n aria-label=\"Simple capacity\"\n checked={useSimpleCapacity}\n id=\"gce-capacity-simple\"\n name=\"gce-capacity-mode\"\n onChange={(event) => event.target.checked && this.capacityModeChanged(true)}\n type=\"radio\"\n />\n Simple\n </label>\n <label className=\"radio-inline\" htmlFor=\"gce-capacity-autoscaling\">\n <input\n aria-label=\"Autoscaling capacity\"\n checked={!useSimpleCapacity}\n id=\"gce-capacity-autoscaling\"\n name=\"gce-capacity-mode\"\n onChange={(event) => event.target.checked && this.capacityModeChanged(false)}\n type=\"radio\"\n />\n Autoscaling\n </label>\n </div>\n </fieldset>\n\n {!useSimpleCapacity && this.renderCapacityInput('Minimum', 'min', values.autoscalingPolicy?.minNumReplicas)}\n {!useSimpleCapacity && this.renderCapacityInput('Maximum', 'max', values.autoscalingPolicy?.maxNumReplicas)}\n {this.renderCapacityInput('Desired', 'desired', values.capacity?.desired)}\n\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">\n <b>Regional</b>\n </div>\n <div className=\"col-md-7 checkbox\">\n <label htmlFor=\"gce-capacity-regional\">\n <input\n aria-label=\"Regional server group\"\n checked={values.regional}\n id=\"gce-capacity-regional\"\n onChange={(event) => this.regionalChanged(event.target.checked)}\n type=\"checkbox\"\n />\n Distribute instances across multiple zones\n </label>\n </div>\n </div>\n\n {values.regional ? this.renderRegionalDistribution() : this.renderZonalLocation()}\n <GceInstanceFlexibilityConfigurer\n instanceFlexibilityPolicy={values.instanceFlexibilityPolicy}\n regional={values.regional}\n setInstanceFlexibilityPolicy={this.instanceFlexibilityPolicyChanged}\n targetShape={values.distributionPolicy?.targetShape || undefined}\n validationError={(this.props.formik.errors as any)?.instanceFlexibilityPolicy}\n />\n </div>\n );\n }\n}\n\nfunction capacityError(errors: unknown, field: 'desired' | 'max' | 'min'): string | undefined {\n if (field === 'desired') {\n return (errors as any)?.capacity?.desired;\n }\n return (errors as any)?.autoscalingPolicy?.[field === 'min' ? 'minNumReplicas' : 'maxNumReplicas'];\n}\n\nfunction isNonNegativeInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value >= 0;\n}\n\nfunction parseCapacity(rawValue: string, values: IGceServerGroupCommand): number | string | undefined {\n if (!rawValue.trim()) {\n return undefined;\n }\n if (isPipelineMode(values) && isExpression(rawValue)) {\n return rawValue;\n }\n const value = Number(rawValue);\n return isNonNegativeInteger(value) ? value : undefined;\n}\n\nfunction isValidCapacityValue(value: unknown, values: IGceServerGroupCommand): value is number | string {\n return isNonNegativeInteger(value) || (isPipelineMode(values) && isExpression(value));\n}\n\nfunction isPipelineMode(values: IGceServerGroupCommand): boolean {\n return values.viewState.mode === 'createPipeline' || values.viewState.mode === 'editPipeline';\n}\n\nfunction isExpression(value: unknown): value is string {\n return typeof value === 'string' && /^\\s*\\$\\{.+\\}\\s*$/.test(value);\n}\n\nfunction coherentDesiredCapacity(desired: any, min: any, max: any): any {\n if (typeof desired === 'number' && typeof min === 'number' && typeof max === 'number') {\n return Math.min(max, Math.max(min, desired));\n }\n return desired ?? min ?? max ?? 1;\n}\n\nfunction zoneOptions(rawZones: readonly string[] | null | undefined, selectedZones: readonly string[]): IZoneOption[] {\n const availableZones = rawZones || [];\n return Array.from(new Set([...availableZones, ...selectedZones])).map((value) => ({\n unavailable: !availableZones.includes(value),\n value,\n }));\n}\n","import React from 'react';\n\nimport { ArtifactTypePatterns, excludeAllTypesExcept, Markdown, StageArtifactSelectorDelegate } from '@spinnaker/core';\n\nimport { preservePersistedReference, validateGceServerGroupCommand } from '../GceServerGroupWizard.helpers';\nimport type { IGceServerGroupCommand, IGceServerGroupCommandValidationErrors } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\n\ninterface IImageOption {\n label: string;\n unavailable: boolean;\n value: string;\n}\n\nconst IMAGE_SOURCES = [\n { label: 'Artifact', value: 'artifact' },\n { label: 'Prior Stage', value: 'priorStage' },\n];\n\nexport class ServerGroupImageSettings extends GceServerGroupWizardPage {\n public validate(values: IGceServerGroupCommand): IGceServerGroupCommandValidationErrors {\n const image = validateGceServerGroupCommand(values).image;\n return image ? { image } : {};\n }\n\n private imageArtifactEdited = (artifact: any): void => {\n this.props.formik.setFieldValue('imageArtifactId', null);\n this.props.formik.setFieldValue('imageArtifact', artifact);\n };\n\n private expectedImageArtifactSelected = (expectedArtifact: any): void => {\n this.props.formik.setFieldValue('imageArtifactId', expectedArtifact.id);\n this.props.formik.setFieldValue('imageArtifact', null);\n };\n\n private renderImageSource(): React.ReactNode {\n const { values } = this.props.formik;\n if (!values.viewState.showImageSourceSelector) {\n return null;\n }\n const sourceControl = values.viewState.imageSourceText ? (\n <div className=\"form-group\">\n <div className=\"col-md-3 sm-label-right\">Image Source</div>\n <div className=\"col-md-7\">\n <Markdown tag=\"span\" message={values.viewState.imageSourceText} />\n </div>\n </div>\n ) : (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-server-group-image-source\">\n Image Source\n </label>\n <div className=\"col-md-7\">\n <select\n aria-label=\"Image source\"\n className=\"form-control input-sm\"\n id=\"gce-server-group-image-source\"\n onChange={(event) => this.props.formik.setFieldValue('imageSource', event.target.value)}\n value={values.imageSource || ''}\n >\n {preservePersistedReference(\n IMAGE_SOURCES,\n values.imageSource,\n (source) => source.value,\n (value) => ({ label: value, value }),\n ).map(({ unresolved, value }) => (\n <option disabled={unresolved} key={value.value} value={value.value}>\n {unresolved ? `${value.label} (unavailable)` : value.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n );\n\n return (\n <>\n {sourceControl}\n {values.imageSource === 'artifact' && (\n <StageArtifactSelectorDelegate\n artifact={values.imageArtifact}\n excludedArtifactTypePatterns={excludeAllTypesExcept(ArtifactTypePatterns.CUSTOM_OBJECT)}\n expectedArtifactId={values.imageArtifactId}\n fieldColumns={7}\n helpKey=\"gce.image.artifact\"\n label=\"Expected Artifact\"\n onArtifactEdited={this.imageArtifactEdited}\n onExpectedArtifactSelected={this.expectedImageArtifactSelected}\n pipeline={values.viewState.pipeline}\n stage={values.viewState.stage}\n />\n )}\n </>\n );\n }\n\n private renderImageSelect(): React.ReactNode {\n const { values } = this.props.formik;\n if (values.viewState.disableImageSelection) {\n return <div>Image selection is disabled for this command.</div>;\n }\n\n const availableImages = values.backingData?.filtered?.images || values.backingData?.allImages || [];\n const images = imageOptions(availableImages, values.image);\n const error = this.validate(values).image;\n return (\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-server-group-image\">\n Image\n </label>\n <div className=\"col-md-7\">\n <select\n aria-describedby={error ? 'gce-server-group-image-error' : undefined}\n aria-invalid={Boolean(error)}\n aria-label=\"Image\"\n className=\"form-control input-sm\"\n id=\"gce-server-group-image\"\n onChange={(event) => this.props.formik.setFieldValue('image', event.target.value)}\n required={true}\n value={values.image || ''}\n >\n <option value=\"\">Select...</option>\n {images.map((image) => (\n <option disabled={image.unavailable} key={image.value} value={image.value}>\n {image.label}\n </option>\n ))}\n </select>\n {error && (\n <span className=\"help-block\" id=\"gce-server-group-image-error\" role=\"alert\">\n {error}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n public render(): JSX.Element {\n return (\n <div className=\"container-fluid form-horizontal\">\n {this.renderImageSource()}\n {this.renderImageSelect()}\n </div>\n );\n }\n}\n\nfunction imageOptions(rawImages: readonly any[], persistedImage: string | null | undefined): IImageOption[] {\n const images = Array.from(\n new Set(rawImages.map((image) => (typeof image === 'string' ? image : image.imageName)).filter(Boolean)),\n );\n return preservePersistedReference(\n images,\n persistedImage,\n (image) => image,\n (image) => image,\n ).map(({ unresolved, value }) => ({\n label: unresolved ? `${value} (unavailable)` : value,\n unavailable: unresolved,\n value,\n }));\n}\n","import React from 'react';\n\nimport { DeckRuntimeContext, HelpField, SpelService } from '@spinnaker/core';\n\nimport type { IGceServerGroupCommand } from '../GceServerGroupWizard.types';\nimport { GceServerGroupWizardPage } from '../GceServerGroupWizardPage';\n\nconst MIN_BOOT_DISK_SIZE_GB = 10;\nconst MAX_BOOT_DISK_SIZE_GB = 65536;\n\ninterface IGceAcceleratorConfig {\n acceleratorCount: number | string;\n acceleratorType: string;\n}\n\ninterface IGceAcceleratorType {\n availableCardCounts: number[];\n description?: string;\n name: string;\n}\n\ninterface IGceCustomInstanceConfig {\n extendedMemory: boolean;\n instanceFamily: string;\n memory: number;\n vCpuCount: number;\n}\n\ninterface IGceDisk {\n sizeGb: number | string;\n sourceImage?: string;\n type: string;\n}\n\ninterface IGceInstanceTypeValidationErrors {\n acceleratorConfigs?: string;\n disks?: string;\n instanceType?: string;\n}\n\nexport class ServerGroupInstanceType extends GceServerGroupWizardPage {\n public static contextType = DeckRuntimeContext;\n public declare context: React.ContextType<typeof DeckRuntimeContext>;\n\n private instanceTypeRequestGeneration = 0;\n\n public validate(values: IGceServerGroupCommand): IGceInstanceTypeValidationErrors {\n const errors: IGceInstanceTypeValidationErrors = {};\n if (!values.instanceType) {\n errors.instanceType = 'Machine type required.';\n }\n\n const bootDisk = getBootDisk(values);\n if (\n !bootDisk?.type ||\n !isValidBoundedValue(bootDisk.sizeGb, values, MIN_BOOT_DISK_SIZE_GB, MAX_BOOT_DISK_SIZE_GB)\n ) {\n errors.disks = `Boot disk size must be between ${MIN_BOOT_DISK_SIZE_GB} and ${MAX_BOOT_DISK_SIZE_GB} GB.`;\n }\n\n const accelerators = getAcceleratorConfigs(values);\n const availableAccelerators = getAvailableAccelerators(values);\n if (\n accelerators.some((config) => {\n if (!config.acceleratorType || !isValidPositiveInteger(config.acceleratorCount, values)) {\n return true;\n }\n const available = availableAccelerators.find((accelerator) => accelerator.name === config.acceleratorType);\n return available ? !available.availableCardCounts.includes(Number(config.acceleratorCount)) : false;\n })\n ) {\n errors.acceleratorConfigs = 'Accelerator count is unavailable for the selected type.';\n }\n\n return errors;\n }\n\n private publish = (nextValues: IGceServerGroupCommand): void => {\n this.props.formik.setValues(nextValues);\n };\n\n private updateValues = (changes: Partial<IGceServerGroupCommand>): void => {\n this.publish({ ...this.props.formik.values, ...changes });\n };\n\n private updateMachineType = (instanceType: string): void => {\n const values = this.props.formik.values;\n const nextValues = {\n ...values,\n instanceType,\n viewState: { ...values.viewState, instanceProfile: 'custom' },\n };\n const requestGeneration = ++this.instanceTypeRequestGeneration;\n this.publish(nextValues);\n if (isPipelineMode(values) && SpelService.includesSpel(instanceType)) {\n return;\n }\n void this.runLatestCommandRequest(nextValues, async (latestCommand) => {\n const instanceTypeDetails = await this.context.services.instanceTypeService.getInstanceTypeDetails(\n latestCommand.selectedProvider || 'gce',\n instanceType,\n );\n if (requestGeneration !== this.instanceTypeRequestGeneration) {\n return latestCommand;\n }\n const reconciledCommand = reconcileInstanceTypeDetails(latestCommand, instanceTypeDetails);\n const update = await this.adapter.applyCommandHandler(reconciledCommand, 'zoneChanged');\n return requestGeneration === this.instanceTypeRequestGeneration ? update.command : latestCommand;\n });\n };\n\n private updateMachineTypeMode = (custom: boolean): void => {\n const values = this.props.formik.values;\n if (!custom) {\n this.publish({ ...values, viewState: { ...values.viewState, instanceProfile: 'custom' } });\n return;\n }\n this.updateCustomInstance(getCustomInstanceConfig(values));\n };\n\n private updateCustomInstance = (customInstance: IGceCustomInstanceConfig): void => {\n this.instanceTypeRequestGeneration++;\n const values = this.props.formik.values;\n const nextValues = {\n ...values,\n instanceType: buildCustomMachineType(customInstance),\n viewState: { ...values.viewState, customInstance, instanceProfile: 'buildCustom' },\n };\n void this.runLatestCommandRequest(nextValues, async (latestCommand) => {\n const update = await this.adapter.applyCommandHandler(latestCommand, 'customInstanceChanged');\n return update.command;\n });\n };\n\n private updatePreemptible = (preemptible: boolean): void => {\n this.updateValues({\n preemptible,\n automaticRestart: !preemptible,\n onHostMaintenance: preemptible ? 'TERMINATE' : 'MIGRATE',\n });\n };\n\n private updateAcceleratorType = (index: number, acceleratorType: string): void => {\n const values = this.props.formik.values;\n const accelerators = getAcceleratorConfigs(values);\n const available = getAvailableAccelerators(values).find((candidate) => candidate.name === acceleratorType);\n const currentCount = Number(accelerators[index].acceleratorCount);\n const acceleratorCount = available\n ? nearestAvailableCount(available.availableCardCounts, currentCount)\n : currentCount;\n this.updateValues({\n acceleratorConfigs: accelerators.map((config, configIndex) =>\n configIndex === index ? { acceleratorType, acceleratorCount } : config,\n ),\n });\n };\n\n private updateAcceleratorCount = (index: number, rawValue: string): void => {\n const accelerators = getAcceleratorConfigs(this.props.formik.values);\n this.updateValues({\n acceleratorConfigs: accelerators.map((config, configIndex) =>\n configIndex === index ? { ...config, acceleratorCount: parseNumericOrExpression(rawValue) } : config,\n ),\n });\n };\n\n private addAccelerator = (): void => {\n const values = this.props.formik.values;\n const available = getAvailableAccelerators(values)[0];\n if (!available) {\n return;\n }\n this.updateValues({\n acceleratorConfigs: getAcceleratorConfigs(values).concat({\n acceleratorType: available.name,\n acceleratorCount: available.availableCardCounts[0] || 1,\n }),\n });\n };\n\n private removeAccelerator = (index: number): void => {\n this.updateValues({\n acceleratorConfigs: getAcceleratorConfigs(this.props.formik.values).filter(\n (_config, configIndex) => configIndex !== index,\n ),\n });\n };\n\n private updateBootDisk = (changes: Partial<IGceDisk>): void => {\n const values = this.props.formik.values;\n const disks = ([...(values.disks || [])] as unknown) as IGceDisk[];\n const bootDiskIndex = getBootDiskIndex(disks);\n if (bootDiskIndex === -1) {\n disks.unshift({ type: 'pd-ssd', sizeGb: MIN_BOOT_DISK_SIZE_GB, ...changes });\n } else {\n disks[bootDiskIndex] = { ...disks[bootDiskIndex], ...changes };\n }\n this.updateValues({ disks });\n };\n\n public render(): JSX.Element {\n const values = this.props.formik.values;\n const errors = (this.props.formik.errors || {}) as IGceInstanceTypeValidationErrors;\n const customMode = values.viewState.instanceProfile === 'buildCustom';\n const pipelineMode = isPipelineMode(values);\n const machineTypes = preserveStringReference(\n values.backingData?.filtered?.instanceTypes || [],\n values.instanceType,\n );\n const cpuPlatforms = preserveStringReference(\n values.backingData?.filtered?.cpuPlatforms || ['(Automatic)'],\n values.minCpuPlatform,\n );\n const custom = getCustomInstanceConfig(values);\n const customChoices = values.backingData?.customInstanceTypes || {};\n const bootDisk = getBootDisk(values) || { type: 'pd-ssd', sizeGb: MIN_BOOT_DISK_SIZE_GB };\n const diskTypes = preserveStringReference(values.backingData?.persistentDiskTypes || [], bootDisk.type);\n const availableAccelerators = getAvailableAccelerators(values);\n const acceleratorConfigs = getAcceleratorConfigs(values);\n\n return (\n <div className=\"container-fluid form-horizontal\">\n <div className=\"form-group\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Machine type</b>\n </div>\n <div className=\"col-md-6\">\n <label className=\"radio-inline\" htmlFor=\"gce-machine-type-standard\">\n <input\n checked={!customMode}\n id=\"gce-machine-type-standard\"\n name=\"gce-machine-type-mode\"\n onChange={() => this.updateMachineTypeMode(false)}\n type=\"radio\"\n />\n Standard\n </label>\n <label className=\"radio-inline\" htmlFor=\"gce-machine-type-custom\">\n <input\n checked={customMode}\n id=\"gce-machine-type-custom\"\n name=\"gce-machine-type-mode\"\n onChange={() => this.updateMachineTypeMode(true)}\n type=\"radio\"\n />\n Custom CPU and memory\n </label>\n </div>\n </div>\n\n {!customMode && (\n <div className=\"form-group\">\n <label className=\"col-md-5 sm-label-right\" htmlFor=\"gce-machine-type\">\n Machine type\n </label>\n <div className=\"col-md-6\">\n {pipelineMode ? (\n <input\n aria-describedby={errors.instanceType ? 'gce-machine-type-error' : undefined}\n aria-invalid={Boolean(errors.instanceType)}\n aria-label=\"Machine type\"\n className=\"form-control input-sm\"\n id=\"gce-machine-type\"\n onChange={(event) => this.updateMachineType(event.target.value)}\n type=\"text\"\n value={values.instanceType || ''}\n />\n ) : (\n <select\n aria-describedby={errors.instanceType ? 'gce-machine-type-error' : undefined}\n aria-invalid={Boolean(errors.instanceType)}\n aria-label=\"Machine type\"\n className=\"form-control input-sm\"\n id=\"gce-machine-type\"\n onChange={(event) => this.updateMachineType(event.target.value)}\n required={true}\n value={values.instanceType || ''}\n >\n <option value=\"\">Select...</option>\n {machineTypes.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n )}\n {renderValidationError(errors.instanceType, 'gce-machine-type-error')}\n </div>\n </div>\n )}\n\n {customMode && (\n <>\n {this.renderSelect(\n 'gce-custom-family',\n 'Machine family',\n custom.instanceFamily,\n preserveNumberOrStringReference(\n customChoices.instanceFamilyList || ['N1', 'E2', 'N2', 'N2D'],\n custom.instanceFamily,\n ),\n (value) =>\n this.updateCustomInstance({\n ...custom,\n extendedMemory: value === 'E2' ? false : custom.extendedMemory,\n instanceFamily: value,\n }),\n )}\n {this.renderSelect(\n 'gce-custom-cpu',\n 'vCPU count',\n custom.vCpuCount,\n preserveNumberOrStringReference(customChoices.vCpuList || [], custom.vCpuCount),\n (value) => this.updateCustomInstance({ ...custom, vCpuCount: Number(value) }),\n errors.instanceType,\n 'gce-machine-type-error',\n )}\n {this.renderSelect(\n 'gce-custom-memory',\n 'Memory (GB)',\n custom.memory,\n preserveNumberOrStringReference(customChoices.memoryList || [], custom.memory),\n (value) => this.updateCustomInstance({ ...custom, memory: Number(value) }),\n errors.instanceType,\n 'gce-machine-type-error',\n )}\n {custom.instanceFamily !== 'E2' && (\n <div className=\"form-group\">\n <div className=\"col-md-offset-5 col-md-6 checkbox\">\n <label htmlFor=\"gce-custom-extended-memory\">\n <input\n checked={custom.extendedMemory}\n id=\"gce-custom-extended-memory\"\n onChange={(event) =>\n this.updateCustomInstance({ ...custom, extendedMemory: event.target.checked })\n }\n type=\"checkbox\"\n />{' '}\n Extended memory\n </label>\n </div>\n </div>\n )}\n {renderValidationError(errors.instanceType, 'gce-machine-type-error')}\n </>\n )}\n\n <div className=\"form-group\">\n <label className=\"col-md-5 sm-label-right\" htmlFor=\"gce-min-cpu-platform\">\n Minimum CPU platform <HelpField id=\"gce.serverGroup.minCpuPlatform\" />\n </label>\n <div className=\"col-md-6\">\n {pipelineMode ? (\n <input\n aria-label=\"Minimum CPU platform\"\n className=\"form-control input-sm\"\n id=\"gce-min-cpu-platform\"\n onChange={(event) => this.updateValues({ minCpuPlatform: event.target.value })}\n type=\"text\"\n value={values.minCpuPlatform || ''}\n />\n ) : (\n <select\n aria-label=\"Minimum CPU platform\"\n className=\"form-control input-sm\"\n id=\"gce-min-cpu-platform\"\n onChange={(event) => this.updateValues({ minCpuPlatform: event.target.value })}\n value={values.minCpuPlatform || ''}\n >\n {cpuPlatforms.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n )}\n </div>\n </div>\n\n <div className=\"form-group\">\n <div className=\"col-md-offset-5 col-md-6 checkbox\">\n <label htmlFor=\"gce-preemptible\">\n <input\n checked={Boolean(values.preemptible)}\n id=\"gce-preemptible\"\n onChange={(event) => this.updatePreemptible(event.target.checked)}\n type=\"checkbox\"\n />{' '}\n Spot (preemptible) instances <HelpField id=\"gce.serverGroup.preemptibility\" />\n </label>\n </div>\n </div>\n\n <fieldset>\n <legend className=\"sm-label-left\">Accelerators (GPUs)</legend>\n {acceleratorConfigs.map((config, index) => {\n const selectedAccelerator = availableAccelerators.find(\n (accelerator) => accelerator.name === config.acceleratorType,\n );\n const typeOptions = preserveAcceleratorReference(availableAccelerators, config.acceleratorType);\n const countOptions = preserveNumberOrStringReference(\n selectedAccelerator?.availableCardCounts || [],\n config.acceleratorCount,\n );\n return (\n <div className=\"form-group\" key={`${config.acceleratorType}-${index}`}>\n <label className=\"col-md-3 sm-label-right\" htmlFor={`gce-accelerator-type-${index}`}>\n GPU type\n </label>\n <div className=\"col-md-4\">\n <select\n aria-describedby={errors.acceleratorConfigs ? 'gce-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`GPU type ${index + 1}`}\n className=\"form-control input-sm\"\n id={`gce-accelerator-type-${index}`}\n onChange={(event) => this.updateAcceleratorType(index, event.target.value)}\n value={config.acceleratorType}\n >\n {typeOptions.map(({ description, name, unavailable }) => (\n <option key={name} value={name}>\n {unavailable ? name : description || name}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n </div>\n <label className=\"col-md-1 sm-label-right\" htmlFor={`gce-accelerator-count-${index}`}>\n Count\n </label>\n <div className=\"col-md-2\">\n {pipelineMode ? (\n <input\n aria-describedby={errors.acceleratorConfigs ? 'gce-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`GPU count ${index + 1}`}\n className=\"form-control input-sm\"\n id={`gce-accelerator-count-${index}`}\n onChange={(event) => this.updateAcceleratorCount(index, event.target.value)}\n type=\"text\"\n value={config.acceleratorCount}\n />\n ) : (\n <select\n aria-describedby={errors.acceleratorConfigs ? 'gce-accelerators-error' : undefined}\n aria-invalid={Boolean(errors.acceleratorConfigs)}\n aria-label={`GPU count ${index + 1}`}\n className=\"form-control input-sm\"\n id={`gce-accelerator-count-${index}`}\n onChange={(event) => this.updateAcceleratorCount(index, event.target.value)}\n value={config.acceleratorCount}\n >\n {countOptions.map(({ unavailable, value }) => (\n <option key={String(value)} value={value}>\n {value}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n )}\n </div>\n <div className=\"col-md-1\">\n <button\n aria-label={`Remove GPU ${index + 1}`}\n className=\"btn btn-link\"\n onClick={() => this.removeAccelerator(index)}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"glyphicon glyphicon-trash\" />\n </button>\n </div>\n </div>\n );\n })}\n <button\n className=\"btn btn-block btn-sm add-new\"\n disabled={!availableAccelerators.length}\n onClick={this.addAccelerator}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"glyphicon glyphicon-plus-sign\" /> Add accelerator\n </button>\n {renderValidationError(errors.acceleratorConfigs, 'gce-accelerators-error')}\n </fieldset>\n\n <fieldset>\n <legend className=\"sm-label-left\">Boot disk</legend>\n <div className=\"form-group\">\n <label className=\"col-md-5 sm-label-right\" htmlFor=\"gce-boot-disk-type\">\n Type\n </label>\n <div className=\"col-md-6\">\n <select\n aria-describedby={errors.disks ? 'gce-boot-disk-error' : undefined}\n aria-invalid={Boolean(errors.disks)}\n aria-label=\"Boot disk type\"\n className=\"form-control input-sm\"\n id=\"gce-boot-disk-type\"\n onChange={(event) => this.updateBootDisk({ type: event.target.value })}\n value={bootDisk.type}\n >\n {diskTypes.map(({ unavailable, value }) => (\n <option key={value} value={value}>\n {value}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-5 sm-label-right\" htmlFor=\"gce-boot-disk-size\">\n Size (GB)\n </label>\n <div className=\"col-md-3\">\n <input\n aria-describedby={errors.disks ? 'gce-boot-disk-error' : undefined}\n aria-invalid={Boolean(errors.disks)}\n aria-label=\"Boot disk size\"\n className=\"form-control input-sm\"\n id=\"gce-boot-disk-size\"\n max={pipelineMode ? undefined : MAX_BOOT_DISK_SIZE_GB}\n min={pipelineMode ? undefined : MIN_BOOT_DISK_SIZE_GB}\n onChange={(event) => this.updateBootDisk({ sizeGb: parseNumericOrExpression(event.target.value) })}\n required={true}\n type={pipelineMode ? 'text' : 'number'}\n value={bootDisk.sizeGb}\n />\n {renderValidationError(errors.disks, 'gce-boot-disk-error')}\n </div>\n </div>\n </fieldset>\n </div>\n );\n }\n\n private renderSelect(\n id: string,\n label: string,\n selected: number | string,\n options: Array<{ unavailable: boolean; value: number | string }>,\n onChange: (value: string) => void,\n error?: string,\n errorId?: string,\n ): JSX.Element {\n return (\n <div className=\"form-group\">\n <label className=\"col-md-5 sm-label-right\" htmlFor={id}>\n {label}\n </label>\n <div className=\"col-md-3\">\n <select\n aria-describedby={error ? errorId : undefined}\n aria-invalid={Boolean(error)}\n aria-label={label}\n className=\"form-control input-sm\"\n id={id}\n onChange={(event) => onChange(event.target.value)}\n value={selected}\n >\n {options.map(({ unavailable, value }) => (\n <option key={String(value)} value={value}>\n {value}\n {unavailable ? ' (Unavailable)' : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n );\n }\n}\n\nfunction renderValidationError(error: string | undefined, id: string): React.ReactNode {\n return (\n error && (\n <span className=\"help-block\" id={id} role=\"alert\">\n {error}\n </span>\n )\n );\n}\n\nfunction isPipelineMode(values: IGceServerGroupCommand): boolean {\n return values.viewState.mode === 'createPipeline' || values.viewState.mode === 'editPipeline';\n}\n\nfunction isExpression(value: unknown): value is string {\n return typeof value === 'string' && /^\\s*\\$\\{.+\\}\\s*$/.test(value);\n}\n\nfunction isValidBoundedValue(value: unknown, command: IGceServerGroupCommand, min: number, max: number): boolean {\n if (isPipelineMode(command) && isExpression(value)) {\n return true;\n }\n const numberValue = Number(value);\n return Number.isFinite(numberValue) && Number.isInteger(numberValue) && numberValue >= min && numberValue <= max;\n}\n\nfunction isValidPositiveInteger(value: unknown, command: IGceServerGroupCommand): boolean {\n if (isPipelineMode(command) && isExpression(value)) {\n return true;\n }\n const numberValue = Number(value);\n return Number.isFinite(numberValue) && Number.isInteger(numberValue) && numberValue > 0;\n}\n\nfunction parseNumericOrExpression(value: string): number | string {\n return isExpression(value) ? value : Number(value);\n}\n\nfunction preserveStringReference(\n availableValues: string[],\n selectedValue?: string | null,\n): Array<{ unavailable: boolean; value: string }> {\n const options = availableValues.map((value) => ({ unavailable: false, value }));\n if (selectedValue && !availableValues.includes(selectedValue)) {\n options.push({ unavailable: true, value: selectedValue });\n }\n return options;\n}\n\nfunction preserveNumberOrStringReference(\n availableValues: Array<number | string>,\n selectedValue: number | string,\n): Array<{ unavailable: boolean; value: number | string }> {\n const options = availableValues.map((value) => ({ unavailable: false, value }));\n if (!availableValues.some((value) => String(value) === String(selectedValue))) {\n options.push({ unavailable: true, value: selectedValue });\n }\n return options;\n}\n\nfunction preserveAcceleratorReference(\n availableAccelerators: IGceAcceleratorType[],\n selectedType: string,\n): Array<IGceAcceleratorType & { unavailable: boolean }> {\n const options = availableAccelerators.map((accelerator) => ({ ...accelerator, unavailable: false }));\n if (selectedType && !availableAccelerators.some((accelerator) => accelerator.name === selectedType)) {\n options.push({ availableCardCounts: [], name: selectedType, unavailable: true });\n }\n return options;\n}\n\nfunction getAvailableAccelerators(values: IGceServerGroupCommand): IGceAcceleratorType[] {\n return values.viewState.acceleratorTypes || [];\n}\n\nfunction getAcceleratorConfigs(values: IGceServerGroupCommand): IGceAcceleratorConfig[] {\n return values.acceleratorConfigs || [];\n}\n\nfunction nearestAvailableCount(availableCounts: number[], currentCount: number): number {\n if (!availableCounts.length) {\n return 1;\n }\n if (availableCounts.includes(currentCount)) {\n return currentCount;\n }\n return availableCounts.reduce(\n (nearest, count) => (count <= currentCount && count > nearest ? count : nearest),\n availableCounts[0],\n );\n}\n\nfunction getBootDiskIndex(disks: IGceDisk[]): number {\n return disks.findIndex((disk) => disk.type.startsWith('pd-') || disk.type.startsWith('hyperdisk-'));\n}\n\nfunction getBootDisk(values: IGceServerGroupCommand): IGceDisk | undefined {\n const disks = ((values.disks || []) as unknown) as IGceDisk[];\n return disks[getBootDiskIndex(disks)];\n}\n\nfunction reconcileInstanceTypeDetails(\n command: IGceServerGroupCommand,\n instanceTypeDetails: any,\n): IGceServerGroupCommand {\n const defaultDisks = instanceTypeDetails?.storage?.defaultSettings?.disks;\n const viewState = { ...command.viewState };\n if (defaultDisks) {\n delete viewState.overriddenStorageDescription;\n }\n return {\n ...command,\n ...(defaultDisks ? { disks: defaultDisks.map((disk: IGceDisk) => ({ ...disk })) } : {}),\n viewState: {\n ...viewState,\n instanceTypeDetails,\n },\n };\n}\n\nfunction getCustomInstanceConfig(values: IGceServerGroupCommand): IGceCustomInstanceConfig {\n const configured = values.viewState.customInstance || {};\n const parsed = parseCustomMachineType(values.instanceType);\n const choices = values.backingData?.customInstanceTypes || {};\n return {\n extendedMemory: configured.extendedMemory ?? parsed.extendedMemory,\n instanceFamily: configured.instanceFamily || parsed.instanceFamily || choices.instanceFamilyList?.[0] || 'N1',\n memory: configured.memory || parsed.memory || choices.memoryList?.[0] || 1,\n vCpuCount: configured.vCpuCount || parsed.vCpuCount || choices.vCpuList?.[0] || 1,\n };\n}\n\nfunction parseCustomMachineType(instanceType?: string | null): Partial<IGceCustomInstanceConfig> {\n if (!instanceType || !instanceType.includes('custom-')) {\n return { extendedMemory: false };\n }\n const match = /^(?:(n1|e2|n2|n2d)-)?custom-(\\d+)-(\\d+)(-ext)?$/i.exec(instanceType);\n if (!match) {\n return { extendedMemory: false };\n }\n return {\n extendedMemory: Boolean(match[4]),\n instanceFamily: (match[1] || 'N1').toUpperCase(),\n memory: Number(match[3]) / 1024,\n vCpuCount: Number(match[2]),\n };\n}\n\nfunction buildCustomMachineType(config: IGceCustomInstanceConfig): string {\n const family = config.instanceFamily.toLowerCase();\n const prefix = family === 'n1' ? '' : `${family}-`;\n return `${prefix}custom-${config.vCpuCount}-${Number(config.memory) * 1024}${config.extendedMemory ? '-ext' : ''}`;\n}\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type {\n Application,\n DeckRuntimeServices,\n IModalComponentProps,\n IRouterInjectedProps,\n IStage,\n IWizardPageInjectedProps,\n} from '@spinnaker/core';\nimport {\n DeckRuntimeContext,\n noop,\n ReactModal,\n TaskMonitor,\n withRouter,\n WizardModal,\n WizardPage,\n} from '@spinnaker/core';\n\nimport { validateGceServerGroupCommand } from './GceServerGroupWizard.helpers';\nimport type {\n IGceServerGroupCommand,\n IGceServerGroupCommandBuilderAdapter,\n IGceServerGroupConfigurationAdapter,\n IGceServerGroupWizardAdapter,\n IGceServerGroupWizardCommandState,\n} from './GceServerGroupWizard.types';\nimport { GceServerGroupWizardAdapter } from './GceServerGroupWizardAdapter';\nimport { createGceServerGroupWizardCommandState } from './GceServerGroupWizardPage';\nimport {\n AdvancedSettings,\n GceServerGroupFirewalls,\n GceServerGroupLoadBalancers,\n Policies,\n ServerGroupBasicSettings,\n ServerGroupCapacity,\n ServerGroupImageSettings,\n ServerGroupInstanceType,\n} from './pages';\n\ninterface IGceCloneServerGroupModalProps extends IModalComponentProps {\n adapter?: IGceServerGroupWizardAdapter;\n application: Application;\n command: IGceServerGroupCommand;\n forPipelineConfig?: boolean;\n isNew?: boolean;\n title?: string;\n}\n\ninterface IGceCloneServerGroupModalState {\n command: IGceServerGroupCommand;\n initializationError: boolean;\n loaded: boolean;\n taskMonitor: TaskMonitor;\n}\n\nconst GLOBAL_LOAD_BALANCER_NAMES = 'global-load-balancer-names';\nconst REGIONAL_LOAD_BALANCER_NAMES = 'load-balancer-names';\nconst BACKEND_SERVICE_NAMES = 'backend-service-names';\n\ninterface ILoadBalancerMetadataReference {\n key: typeof GLOBAL_LOAD_BALANCER_NAMES | typeof REGIONAL_LOAD_BALANCER_NAMES;\n names: string[];\n}\n\ninterface IPersistedSelectionSnapshot {\n autoHealingHealthCheck: any;\n backendServiceMetadata: string[];\n backendServices?: Record<string, string[]>;\n credentials: string;\n distributionZones: string[];\n image: any;\n implicitSecurityGroups: any[];\n instanceType: any;\n loadBalancerMetadata: Record<string, string[]>;\n loadBalancerReferences: Record<string, ILoadBalancerMetadataReference>;\n loadBalancers: any[];\n minCpuPlatform: any;\n network: any;\n region: string;\n regional: boolean;\n securityGroups: string[];\n subnet: any;\n zone: any;\n}\n\nfunction compactMetadata(metadata: Record<string, string[]>): Record<string, string> {\n return Object.keys(metadata).reduce((result: Record<string, string>, key: string) => {\n const values = Array.from(new Set(metadata[key].filter(Boolean)));\n if (values.length) {\n result[key] = values.join(',');\n }\n return result;\n }, {});\n}\n\nfunction loadBalancerName(loadBalancer: any): string {\n return loadBalancer.name || loadBalancer;\n}\n\nfunction metadataValues(value: any): string[] {\n if (Array.isArray(value)) {\n return value;\n }\n return typeof value === 'string' ? value.split(',').map((item) => item.trim()) : [];\n}\n\nfunction metadataSource(command: IGceServerGroupCommand): Record<string, string[]> {\n const loadBalancerMetadata = command.loadBalancerMetadata || {};\n const instanceMetadata = command.instanceMetadata || {};\n return {\n [GLOBAL_LOAD_BALANCER_NAMES]: metadataValues(\n loadBalancerMetadata[GLOBAL_LOAD_BALANCER_NAMES] || instanceMetadata[GLOBAL_LOAD_BALANCER_NAMES],\n ),\n [REGIONAL_LOAD_BALANCER_NAMES]: metadataValues(\n loadBalancerMetadata[REGIONAL_LOAD_BALANCER_NAMES] || instanceMetadata[REGIONAL_LOAD_BALANCER_NAMES],\n ),\n };\n}\n\nfunction loadBalancerMetadataReference(name: string, loadBalancer: any): ILoadBalancerMetadataReference | undefined {\n if (!loadBalancer) {\n return undefined;\n }\n if (loadBalancer.loadBalancerType === 'HTTP' || loadBalancer.loadBalancerType === 'INTERNAL_MANAGED') {\n const names = (loadBalancer.listeners || []).map((listener: any) => listener.name).filter(Boolean);\n return names.length\n ? {\n key: loadBalancer.loadBalancerType === 'HTTP' ? GLOBAL_LOAD_BALANCER_NAMES : REGIONAL_LOAD_BALANCER_NAMES,\n names,\n }\n : undefined;\n }\n return {\n key:\n loadBalancer.loadBalancerType === 'SSL' || loadBalancer.loadBalancerType === 'TCP'\n ? GLOBAL_LOAD_BALANCER_NAMES\n : REGIONAL_LOAD_BALANCER_NAMES,\n names: [name],\n };\n}\n\nfunction buildLoadBalancerMetadata(command: IGceServerGroupCommand): Record<string, string> {\n const loadBalancerIndex = command.backingData?.filtered?.loadBalancerIndex || {};\n const unavailableLoadBalancers = (command.loadBalancers || []).filter(\n (loadBalancer: any) => !loadBalancer.loadBalancerType && !loadBalancerIndex[loadBalancerName(loadBalancer)],\n );\n const persistedMetadata = metadataSource(command);\n const metadata: Record<string, string[]> = {\n [GLOBAL_LOAD_BALANCER_NAMES]: unavailableLoadBalancers.length\n ? [...persistedMetadata[GLOBAL_LOAD_BALANCER_NAMES]]\n : [],\n [REGIONAL_LOAD_BALANCER_NAMES]: unavailableLoadBalancers.length\n ? [...persistedMetadata[REGIONAL_LOAD_BALANCER_NAMES]]\n : [],\n };\n\n (command.loadBalancers || []).forEach((loadBalancer: any) => {\n const name = loadBalancerName(loadBalancer);\n const loadBalancerDetails = loadBalancer.loadBalancerType ? loadBalancer : loadBalancerIndex[name];\n const reference = loadBalancerMetadataReference(name, loadBalancerDetails);\n if (reference) {\n metadata[reference.key].push(...reference.names);\n }\n });\n\n const selectedLoadBalancers = new Set((command.loadBalancers || []).map(loadBalancerName));\n if (command.backendServices && Object.keys(command.backendServices).length) {\n metadata[BACKEND_SERVICE_NAMES] = Object.keys(command.backendServices)\n .filter((loadBalancer) => selectedLoadBalancers.has(loadBalancer))\n .flatMap((loadBalancer) => command.backendServices[loadBalancer]);\n } else if (unavailableLoadBalancers.length) {\n metadata[BACKEND_SERVICE_NAMES] = metadataValues(\n command.backendServiceMetadata || command.instanceMetadata?.[BACKEND_SERVICE_NAMES],\n );\n }\n\n return compactMetadata(metadata);\n}\n\nexport function transformGceServerGroupCommand(command: IGceServerGroupCommand): IGceServerGroupCommand {\n const transformed = cloneDeep(command);\n const instanceMetadata = { ...(command.instanceMetadata || {}) };\n delete instanceMetadata[GLOBAL_LOAD_BALANCER_NAMES];\n delete instanceMetadata[REGIONAL_LOAD_BALANCER_NAMES];\n delete instanceMetadata[BACKEND_SERVICE_NAMES];\n\n transformed.instanceMetadata = {\n ...instanceMetadata,\n ...buildLoadBalancerMetadata(command),\n };\n transformed.tags = (command.tags || []).map((tag: any) => tag.value || tag);\n transformed.targetSize = command.capacity?.desired;\n if (command.autoscalingPolicy) {\n transformed.capacity = {\n ...command.capacity,\n max: command.autoscalingPolicy.maxNumReplicas,\n min: command.autoscalingPolicy.minNumReplicas,\n };\n } else if (command.capacity) {\n transformed.capacity = {\n ...command.capacity,\n max: command.capacity.desired,\n min: command.capacity.desired,\n };\n }\n if (transformed.minCpuPlatform === '(Automatic)') {\n transformed.minCpuPlatform = '';\n }\n delete transformed.loadBalancerMetadata;\n delete transformed.securityGroups;\n return transformed;\n}\n\nexport class GceCloneServerGroupModalComponent extends React.Component<\n IGceCloneServerGroupModalProps & IRouterInjectedProps,\n IGceCloneServerGroupModalState\n> {\n public static contextType = DeckRuntimeContext;\n public declare context: React.ContextType<typeof DeckRuntimeContext>;\n\n public static defaultProps: Partial<IGceCloneServerGroupModalProps & IRouterInjectedProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n private adapter?: IGceServerGroupWizardAdapter;\n private command: IGceServerGroupCommand;\n private commandState: IGceServerGroupWizardCommandState;\n private configureRequest = 0;\n private applicationRefreshUnsubscribe?: () => void;\n private formik: IWizardPageInjectedProps<IGceServerGroupCommand>['formik'] = null;\n private unmounted = false;\n\n public static show(props: IGceCloneServerGroupModalProps, runtimeServices: DeckRuntimeServices): Promise<any> {\n return ReactModal.show(\n GceCloneServerGroupModal,\n props,\n { dialogClassName: 'wizard-modal modal-lg' },\n runtimeServices,\n );\n }\n\n public constructor(\n props: IGceCloneServerGroupModalProps & IRouterInjectedProps,\n context: React.ContextType<typeof DeckRuntimeContext>,\n ) {\n super(props, context);\n this.adapter = props.adapter;\n this.command = cloneDeep(props.command);\n this.commandState = createGceServerGroupWizardCommandState(this.command);\n this.state = {\n command: this.command,\n initializationError: false,\n loaded: Boolean(this.command.backingData?.filtered),\n taskMonitor: new TaskMonitor({\n application: props.application,\n title: props.title || 'Creating your server group',\n onDismiss: () => this.props.dismissModal(),\n onTaskComplete: this.onTaskComplete,\n }),\n };\n }\n\n public componentDidMount(): void {\n void this.configureCommand();\n }\n\n public componentWillUnmount(): void {\n this.unmounted = true;\n this.configureRequest++;\n this.clearApplicationRefreshSubscription();\n }\n\n private configureCommand = async (): Promise<void> => {\n const request = ++this.configureRequest;\n const adapter = this.getAdapter();\n try {\n let command = this.formik?.values || this.command;\n if (command.viewState?.requiresTemplateSelection) {\n const baseCommand = await adapter.buildNewServerGroupCommand(this.props.application, {\n mode: 'createPipeline',\n });\n command = initializePipelineCreateCommand(baseCommand, command);\n }\n if (this.unmounted || request !== this.configureRequest) {\n return;\n }\n\n const configured = await adapter.configureCommand(this.props.application, command);\n if (this.unmounted || request !== this.configureRequest) {\n return;\n }\n\n const latestCommand = this.formik?.values || command;\n const persistedSelections = snapshotPersistedSelections(latestCommand);\n const refreshedCommand = mergeRefreshedCommand(latestCommand, configured);\n initializeCommand(refreshedCommand, persistedSelections);\n restoreUnavailableSelections(refreshedCommand, persistedSelections);\n this.command = refreshedCommand;\n this.commandState.command = refreshedCommand;\n this.commandState.formikValues = refreshedCommand;\n this.formik?.setValues(refreshedCommand);\n this.setState({ command: refreshedCommand, initializationError: false, loaded: true });\n } catch (_error) {\n if (!this.unmounted && request === this.configureRequest) {\n this.setState({ initializationError: true, loaded: false });\n }\n }\n };\n\n private retryConfiguration = (): Promise<void> => {\n this.setState({ initializationError: false, loaded: false });\n return this.configureCommand();\n };\n\n private getAdapter(): IGceServerGroupWizardAdapter {\n if (!this.adapter) {\n if (!this.context?.services) {\n throw new Error('GCE server group wizard requires Deck runtime services');\n }\n const delegate = this.context.services.providerServiceDelegate;\n this.adapter = new GceServerGroupWizardAdapter(\n delegate.getDelegate<IGceServerGroupCommandBuilderAdapter>('gce', 'serverGroup.commandBuilder'),\n delegate.getDelegate<IGceServerGroupConfigurationAdapter>('gce', 'serverGroup.configurationService'),\n );\n }\n return this.adapter;\n }\n\n private submit = (command: IGceServerGroupCommand = this.formik?.values || this.command): any => {\n const transformed = transformGceServerGroupCommand(command);\n const mode = transformed.viewState?.mode;\n if (this.props.forPipelineConfig || mode === 'createPipeline' || mode === 'editPipeline') {\n return this.props.closeModal(transformed);\n }\n return this.state.taskMonitor.submit(() =>\n this.context.services.serverGroupWriter.cloneServerGroup(transformed as any, this.props.application),\n );\n };\n\n private onTaskComplete = (): void => {\n this.clearApplicationRefreshSubscription();\n this.applicationRefreshUnsubscribe = this.props.application.serverGroups.onNextRefresh(this.onApplicationRefresh);\n this.props.application.serverGroups.refresh();\n };\n\n private onApplicationRefresh = (): void => {\n this.clearApplicationRefreshSubscription();\n if (this.unmounted) {\n return;\n }\n\n const command = this.formik?.values || this.command;\n const cloneStage = this.state.taskMonitor.task?.execution?.stages?.find(\n (stage: IStage) => stage.type === 'cloneServerGroup',\n );\n const newServerGroupName = cloneStage?.context?.['deploy.server.groups']?.[command.region];\n if (!newServerGroupName) {\n return;\n }\n\n let transitionTo = '^.^.^.clusters.serverGroup';\n if (this.props.stateService.includes('**.clusters.serverGroup')) {\n transitionTo = '^.serverGroup';\n }\n if (this.props.stateService.includes('**.clusters.cluster.serverGroup')) {\n transitionTo = '^.^.serverGroup';\n }\n if (this.props.stateService.includes('**.clusters')) {\n transitionTo = '.serverGroup';\n }\n this.props.stateService.go(transitionTo, {\n accountId: command.credentials,\n provider: 'gce',\n region: command.region,\n serverGroup: newServerGroupName,\n });\n };\n\n private clearApplicationRefreshSubscription = (): void => {\n this.applicationRefreshUnsubscribe?.();\n this.applicationRefreshUnsubscribe = undefined;\n };\n\n public render(): JSX.Element {\n const { application, dismissModal, title } = this.props;\n const { command, initializationError, loaded, taskMonitor } = this.state;\n\n if (initializationError) {\n return (\n <div className=\"modal-content gce-server-group-initialization-error\">\n <div className=\"modal-header\">\n <button aria-label=\"Close\" className=\"close\" onClick={dismissModal} type=\"button\">\n <span aria-hidden=\"true\">×</span>\n </button>\n <h3>{title || 'Create Server Group'}</h3>\n </div>\n <div className=\"modal-body\">\n <div className=\"alert alert-danger\" role=\"alert\">\n Unable to load the resources required to configure this server group. Check your connection and try again.\n </div>\n </div>\n <div className=\"modal-footer\">\n <button\n className=\"btn btn-default gce-server-group-initialization-close\"\n onClick={dismissModal}\n type=\"button\"\n >\n Close\n </button>\n <button className=\"btn btn-primary\" onClick={this.retryConfiguration} type=\"button\">\n Retry\n </button>\n </div>\n </div>\n );\n }\n\n const adapter = this.getAdapter();\n\n return (\n <WizardModal<IGceServerGroupCommand>\n key={loaded ? 'loaded' : 'loading'}\n closeModal={this.submit}\n dismissModal={dismissModal}\n heading={title || 'Create Server Group'}\n initialValues={command}\n loading={!loaded}\n submitButtonLabel={command.viewState?.submitButtonLabel || 'Done'}\n taskMonitor={taskMonitor}\n validate={validateGceServerGroupCommand}\n render={({ formik, nextIdx, wizard }) => {\n this.formik = formik;\n this.command = formik.values;\n const pageProps = { adapter, app: application, commandState: this.commandState, formik };\n return (\n <>\n <WizardPage\n label=\"Basic Settings\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <ServerGroupBasicSettings ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Image\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <ServerGroupImageSettings ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Instance Type\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <ServerGroupInstanceType ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Capacity/Distribution\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <ServerGroupCapacity ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Load Balancers\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <GceServerGroupLoadBalancers ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Firewalls\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <GceServerGroupFirewalls ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Policies\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <Policies ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n <WizardPage\n label=\"Advanced Settings\"\n order={nextIdx()}\n render={({ innerRef, onLoadingChanged }) => (\n <AdvancedSettings ref={innerRef} {...pageProps} onLoadingChanged={onLoadingChanged} />\n )}\n wizard={wizard}\n />\n </>\n );\n }}\n />\n );\n }\n}\n\nexport const GceCloneServerGroupModal = Object.assign(withRouter(GceCloneServerGroupModalComponent), {\n show: GceCloneServerGroupModalComponent.show,\n});\n\nfunction initializeCommand(command: IGceServerGroupCommand, snapshot: IPersistedSelectionSnapshot): void {\n const accountAvailable =\n !snapshot.credentials || referenceValues(command.backingData?.accounts, ['name']).includes(snapshot.credentials);\n if (!accountAvailable) {\n return;\n }\n\n command.credentialsChanged?.(command);\n const regionAvailable =\n !snapshot.region || referenceValues(command.backingData?.filtered?.regions, ['name']).includes(snapshot.region);\n if (!regionAvailable) {\n return;\n }\n\n ['regionalChanged', 'regionChanged', 'networkChanged', 'zoneChanged', 'customInstanceChanged'].forEach((handler) =>\n command[handler]?.(command),\n );\n}\n\nfunction snapshotPersistedSelections(command: IGceServerGroupCommand): IPersistedSelectionSnapshot {\n const loadBalancers = cloneDeep(command.loadBalancers || []);\n const loadBalancerIndex = command.backingData?.filtered?.loadBalancerIndex || {};\n return {\n autoHealingHealthCheck: command.autoHealingPolicy\n ? cloneDeep({\n healthCheck: command.autoHealingPolicy.healthCheck,\n healthCheckKind: command.autoHealingPolicy.healthCheckKind,\n healthCheckUrl: command.autoHealingPolicy.healthCheckUrl,\n })\n : undefined,\n backendServiceMetadata: metadataValues(command.backendServiceMetadata),\n backendServices: command.backendServices ? cloneDeep(command.backendServices) : undefined,\n credentials: command.credentials,\n distributionZones: cloneDeep(command.distributionPolicy?.zones || []),\n image: command.viewState?.imageId || command.image,\n implicitSecurityGroups: cloneDeep(command.implicitSecurityGroups || []),\n instanceType: command.instanceType,\n loadBalancerMetadata: cloneDeep(metadataSource(command)),\n loadBalancerReferences: loadBalancers.reduce(\n (references: Record<string, ILoadBalancerMetadataReference>, loadBalancer: any) => {\n const name = loadBalancerName(loadBalancer);\n const reference = loadBalancerMetadataReference(\n name,\n loadBalancer.loadBalancerType ? loadBalancer : indexedLoadBalancer(loadBalancerIndex, name),\n );\n if (reference) {\n references[name] = reference;\n }\n return references;\n },\n {},\n ),\n loadBalancers,\n minCpuPlatform: command.minCpuPlatform,\n network: command.network,\n region: command.region,\n regional: command.regional,\n securityGroups: cloneDeep(command.securityGroups || []),\n subnet: command.subnet,\n zone: command.zone,\n };\n}\n\nfunction restoreUnavailableSelections(command: IGceServerGroupCommand, snapshot: IPersistedSelectionSnapshot): void {\n const filtered = command.backingData?.filtered || {};\n if (!referenceValues(command.backingData?.accounts, ['name']).includes(snapshot.credentials)) {\n command.credentials = snapshot.credentials;\n }\n if (!referenceValues(filtered.regions, ['name']).includes(snapshot.region)) {\n command.region = snapshot.region;\n }\n if (snapshot.instanceType && !metadataValues(filtered.instanceTypes).includes(snapshot.instanceType)) {\n command.instanceType = snapshot.instanceType;\n }\n if (snapshot.minCpuPlatform && !metadataValues(filtered.cpuPlatforms).includes(snapshot.minCpuPlatform)) {\n command.minCpuPlatform = snapshot.minCpuPlatform;\n }\n if (\n snapshot.image &&\n !referenceValues(command.backingData?.allImages, ['imageName', 'name', 'id']).includes(snapshot.image)\n ) {\n command.image = snapshot.image;\n command.viewState.imageId = snapshot.image;\n }\n if (snapshot.network && !referenceValues(filtered.networks, ['id', 'name']).includes(snapshot.network)) {\n command.network = snapshot.network;\n }\n if (snapshot.subnet && !referenceValues(filtered.subnets, ['id', 'name']).includes(snapshot.subnet)) {\n command.subnet = snapshot.subnet;\n }\n if (!snapshot.regional && snapshot.zone && !metadataValues(filtered.zones).includes(snapshot.zone)) {\n command.zone = snapshot.zone;\n }\n if (snapshot.regional) {\n const unavailableZones = snapshot.distributionZones.filter(\n (zone) => !metadataValues(filtered.zones).includes(zone),\n );\n command.distributionPolicy = {\n ...command.distributionPolicy,\n zones: unique([...(command.distributionPolicy?.zones || []), ...unavailableZones]),\n };\n }\n\n const firewallProperties = ['id', 'name'];\n const availableFirewalls = new Set([\n ...referenceValues(filtered.securityGroups, firewallProperties),\n ...referenceValues(command.implicitSecurityGroups, firewallProperties),\n ]);\n command.securityGroups = unique([\n ...(command.securityGroups || []),\n ...snapshot.securityGroups.filter((firewall) => !availableFirewalls.has(firewall)),\n ]);\n command.implicitSecurityGroups = uniqueByReference(\n [\n ...(command.implicitSecurityGroups || []),\n ...snapshot.implicitSecurityGroups.filter(\n (firewall) => !availableFirewalls.has(referenceValue(firewall, firewallProperties)),\n ),\n ],\n firewallProperties,\n );\n\n const healthCheck = snapshot.autoHealingHealthCheck;\n const healthCheckAvailable = (filtered.healthChecks || []).some(\n (option: any) => option.name === healthCheck?.healthCheck && option.kind === healthCheck?.healthCheckKind,\n );\n if (healthCheck?.healthCheck && !healthCheckAvailable) {\n command.autoHealingPolicy = {\n ...(command.autoHealingPolicy || {}),\n ...healthCheck,\n };\n }\n\n const loadBalancerIndex = filtered.loadBalancerIndex || {};\n const unavailableLoadBalancers = snapshot.loadBalancers.filter(\n (loadBalancer) => !indexedLoadBalancer(loadBalancerIndex, loadBalancerName(loadBalancer)),\n );\n const unavailableNames = new Set(unavailableLoadBalancers.map(loadBalancerName));\n command.loadBalancers = uniqueByName([...(command.loadBalancers || []), ...unavailableLoadBalancers]);\n\n const backendServices = cloneDeep(command.backendServices || {});\n unavailableNames.forEach((name) => {\n if (snapshot.backendServices?.[name]) {\n backendServices[name] = snapshot.backendServices[name];\n }\n });\n if (Object.keys(backendServices).length) {\n command.backendServices = backendServices;\n } else {\n delete command.backendServices;\n }\n const knownBackendServices = Object.keys(snapshot.backendServices || {})\n .filter((name) => !unavailableNames.has(name))\n .flatMap((name) => snapshot.backendServices?.[name] || []);\n const unavailableBackendMetadata = unavailableNames.size\n ? snapshot.backendServiceMetadata.filter((backendService) => !knownBackendServices.includes(backendService))\n : [];\n command.backendServiceMetadata = unique([\n ...metadataValues(command.backendServiceMetadata),\n ...Object.keys(backendServices)\n .filter((name) => unavailableNames.has(name))\n .flatMap((name) => backendServices[name]),\n ...unavailableBackendMetadata,\n ]);\n\n const metadata = metadataSource(command);\n Object.keys(loadBalancerIndex).forEach((name) => {\n const oldReference = snapshot.loadBalancerReferences[name];\n if (oldReference) {\n metadata[oldReference.key] = metadata[oldReference.key].filter((value) => !oldReference.names.includes(value));\n }\n });\n (command.loadBalancers || []).forEach((loadBalancer: any) => {\n const name = loadBalancerName(loadBalancer);\n const refreshedReference = loadBalancerMetadataReference(name, loadBalancerIndex[name]);\n if (refreshedReference) {\n metadata[refreshedReference.key].push(...refreshedReference.names);\n }\n });\n unavailableNames.forEach((name) => {\n const reference = snapshot.loadBalancerReferences[name];\n if (reference) {\n metadata[reference.key].push(...reference.names);\n }\n });\n const attributedMetadata = Object.values(snapshot.loadBalancerReferences).reduce(\n (attributed, reference) => ({\n ...attributed,\n [reference.key]: unique([...(attributed[reference.key] || []), ...reference.names]),\n }),\n {} as Record<string, string[]>,\n );\n if (unavailableNames.size) {\n [GLOBAL_LOAD_BALANCER_NAMES, REGIONAL_LOAD_BALANCER_NAMES].forEach((key) => {\n metadata[key].push(\n ...snapshot.loadBalancerMetadata[key].filter((value) => !(attributedMetadata[key] || []).includes(value)),\n );\n });\n }\n command.loadBalancerMetadata = {\n [GLOBAL_LOAD_BALANCER_NAMES]: unique(metadata[GLOBAL_LOAD_BALANCER_NAMES]),\n [REGIONAL_LOAD_BALANCER_NAMES]: unique(metadata[REGIONAL_LOAD_BALANCER_NAMES]),\n };\n Object.keys(command.loadBalancerMetadata).forEach((key) => {\n if (!command.loadBalancerMetadata[key].length) {\n delete command.loadBalancerMetadata[key];\n }\n });\n}\n\nfunction indexedLoadBalancer(loadBalancerIndex: Record<string, any>, name: string): any {\n return (\n loadBalancerIndex[name] ||\n Object.values(loadBalancerIndex).find((loadBalancer: any) =>\n (loadBalancer.listeners || []).some((listener: any) => listener.name === name),\n )\n );\n}\n\nfunction unique(values: string[]): string[] {\n return Array.from(new Set(values.filter(Boolean)));\n}\n\nfunction referenceValue(value: any, properties: string[]): string {\n if (typeof value === 'string') {\n return value;\n }\n return properties.map((property) => value?.[property]).find((property) => typeof property === 'string');\n}\n\nfunction referenceValues(values: any[], properties: string[]): string[] {\n return (values || []).map((value) => referenceValue(value, properties)).filter(Boolean);\n}\n\nfunction uniqueByReference(values: any[], properties: string[]): any[] {\n const seen = new Set<string>();\n return values.filter((value) => {\n const reference = referenceValue(value, properties);\n if (!reference || seen.has(reference)) {\n return false;\n }\n seen.add(reference);\n return true;\n });\n}\n\nfunction uniqueByName(values: any[]): any[] {\n const seen = new Set<string>();\n return values.filter((value) => {\n const name = loadBalancerName(value);\n if (!name || seen.has(name)) {\n return false;\n }\n seen.add(name);\n return true;\n });\n}\n\nfunction mergeRefreshedCommand(\n current: IGceServerGroupCommand,\n configured: IGceServerGroupCommand,\n): IGceServerGroupCommand {\n const handlers = Object.keys(configured).reduce((result: Partial<IGceServerGroupCommand>, key) => {\n if (typeof configured[key] === 'function') {\n result[key] = configured[key];\n }\n return result;\n }, {});\n\n return {\n ...configured,\n ...current,\n ...handlers,\n backingData: configured.backingData,\n viewState: {\n ...configured.viewState,\n ...current.viewState,\n dirty: { ...configured.viewState?.dirty, ...current.viewState?.dirty },\n },\n };\n}\n\nfunction initializePipelineCreateCommand(\n baseCommand: IGceServerGroupCommand,\n placeholder: IGceServerGroupCommand,\n): IGceServerGroupCommand {\n const placeholderViewState = placeholder.viewState || ({} as IGceServerGroupCommand['viewState']);\n return {\n ...baseCommand,\n ...(placeholderViewState.overrides || {}),\n viewState: {\n ...baseCommand.viewState,\n disableImageSelection: true,\n disableStrategySelection: placeholderViewState.disableStrategySelection || false,\n expectedArtifacts: placeholderViewState.expectedArtifacts || [],\n hideClusterNamePreview: placeholderViewState.hideClusterNamePreview || false,\n imageId: null,\n imageSourceText: placeholderViewState.imageSourceText,\n mode: 'createPipeline',\n pipeline: placeholderViewState.pipeline,\n readOnlyFields: placeholderViewState.readOnlyFields || {},\n showImageSourceSelector: true,\n stage: placeholderViewState.stage,\n submitButtonLabel: 'Add',\n templatingEnabled: true,\n },\n };\n}\n","import React from 'react';\nimport type { Option } from 'react-select';\nimport Select from 'react-select';\n\nimport { CheckboxInput, HelpField } from '@spinnaker/core';\nimport './customInstanceConfigurer.component.less';\n\nexport interface ICustomInstanceConfig {\n vCpuCount: number;\n memory: number;\n instanceFamily: string;\n extendedMemory: boolean;\n}\n\nexport interface ICustomInstanceConfigurerProps {\n vCpuList: number[];\n memoryList: number[];\n instanceFamilyList: string[];\n selectedVCpuCount: number;\n selectedMemory: number;\n selectedInstanceFamily: string;\n selectedExtendedMemory: boolean;\n onChange: (config: ICustomInstanceConfig) => void;\n}\n\nexport class CustomInstanceConfigurer extends React.Component<ICustomInstanceConfigurerProps> {\n public render() {\n const instanceFamilyOptions: Option[] = (this.props.instanceFamilyList || []).map((instanceFamily) => ({\n label: instanceFamily,\n value: instanceFamily,\n }));\n const vCpuOptions: Option[] = (this.props.vCpuList || []).map((vCpu) => ({ label: vCpu + '', value: vCpu }));\n const memoryOptions: Option[] = (this.props.memoryList || []).map((memory) => ({\n label: memory + '',\n value: memory,\n }));\n const selectedVCpuCountLabel = this.props.selectedVCpuCount ? this.props.selectedVCpuCount + '' : null;\n const selectedMemoryLabel = this.props.selectedMemory ? this.props.selectedMemory + '' : null;\n const selectedInstanceFamilyLabel = this.props.selectedInstanceFamily ? this.props.selectedInstanceFamily : null;\n\n return (\n <div>\n <div className=\"row\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Family </b>\n </div>\n <div className=\"col-md-3\">\n <Select\n options={instanceFamilyOptions}\n clearable={false}\n value={{ label: selectedInstanceFamilyLabel, value: this.props.selectedInstanceFamily }}\n onChange={this.handleInstanceFamilyChange}\n />\n </div>\n </div>\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Cores </b>\n <HelpField id=\"gce.instance.customInstance.cores\" />\n </div>\n <div className=\"col-md-3\">\n <Select\n options={vCpuOptions}\n clearable={false}\n value={{ label: selectedVCpuCountLabel, value: this.props.selectedVCpuCount }}\n onChange={this.handleVCpuChange}\n />\n </div>\n </div>\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\">\n <b>Memory (Gb) </b>\n <HelpField id=\"gce.instance.customInstance.memory\" />\n </div>\n <div className=\"col-md-3\">\n {this.props.selectedExtendedMemory ? (\n <input\n type=\"number\"\n name=\"memory\"\n className=\"form-control\"\n value={this.props.selectedMemory}\n onChange={(event) => this.handleMemoryChangeCustom(event.target.value)}\n />\n ) : (\n <Select\n options={memoryOptions}\n clearable={false}\n value={{ label: selectedMemoryLabel, value: this.props.selectedMemory }}\n onChange={this.handleMemoryChange}\n />\n )}\n </div>\n </div>\n {this.props.selectedInstanceFamily !== 'E2' ? (\n <div className=\"row gce-instance-build-custom-select\">\n <div className=\"col-md-5 sm-label-right\"></div>\n <div className=\"col-md-3\">\n <span className=\"gce-instance-build-custom-extended-memory-checkbox\">\n <CheckboxInput\n name=\"extendedMemory\"\n text=\"Extended Memory\"\n checked={this.props.selectedExtendedMemory}\n onChange={(event: { target: { checked: boolean } }) => {\n this.handleExtendedMemory(event.target.checked);\n }}\n />\n <div className=\"gce-instance-build-custom-extended-memory-checkbox-helptext\">\n <HelpField id=\"gce.instance.customInstance.extendedmemory\" />\n </div>\n </span>\n </div>\n </div>\n ) : null}\n </div>\n );\n }\n\n private handleVCpuChange = (option: Option) => {\n const value = (option ? option.value : null) as number;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: value,\n memory: this.props.selectedMemory,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleMemoryChange = (option: Option) => {\n const value = (option ? option.value : null) as number;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: value,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleInstanceFamilyChange = (option: Option) => {\n const value = (option ? option.value : null) as string;\n this.props.onChange({\n instanceFamily: value,\n vCpuCount: this.props.selectedVCpuCount,\n memory: this.props.selectedMemory,\n extendedMemory: value === 'E2' ? false : this.props.selectedExtendedMemory,\n });\n };\n\n private handleMemoryChangeCustom = (val: string) => {\n const value = +val;\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: value,\n extendedMemory: this.props.selectedExtendedMemory,\n });\n };\n\n private handleExtendedMemory = (checked: boolean) => {\n this.props.onChange({\n instanceFamily: this.props.selectedInstanceFamily,\n vCpuCount: this.props.selectedVCpuCount,\n memory: this.props.selectedMemory,\n extendedMemory: checked,\n });\n };\n}\n","import React from 'react';\n\nimport type { ICustomInstanceBuilderProps } from '@spinnaker/core';\nimport { useDeckRuntimeServices } from '@spinnaker/core';\n\nimport type { ICustomInstanceConfig } from './CustomInstanceConfigurer';\nimport { CustomInstanceConfigurer } from './CustomInstanceConfigurer';\nimport { GceCustomInstanceBuilderService } from '../../../../instance/custom/customInstanceBuilder.gce.service';\n\nconst customInstanceBuilderService = new GceCustomInstanceBuilderService();\n\nexport function GceCustomInstanceBuilder({ command, onTypeChanged }: ICustomInstanceBuilderProps) {\n const { instanceTypeService } = useDeckRuntimeServices();\n const gceCommand = command as any;\n const [config, setConfig] = React.useState<ICustomInstanceConfig>(() => getInitialConfig(gceCommand));\n const choices = getChoices(gceCommand, config);\n const effectiveConfig = withValidDefaults(config, choices);\n\n const handleChange = (nextConfig: ICustomInstanceConfig) => {\n const nextChoices = getChoices(gceCommand, nextConfig);\n const completeConfig = withValidDefaults(nextConfig, nextChoices);\n const nextInstanceType = customInstanceBuilderService.generateInstanceTypeString(\n completeConfig.instanceFamily,\n completeConfig.vCpuCount,\n completeConfig.memory,\n completeConfig.extendedMemory,\n );\n gceCommand.viewState.customInstance = completeConfig;\n gceCommand.instanceType = nextInstanceType;\n gceCommand.customInstanceChanged && gceCommand.customInstanceChanged(gceCommand);\n setConfig(completeConfig);\n instanceTypeService\n .getInstanceTypeDetails(gceCommand.selectedProvider, nextInstanceType)\n .then((instanceTypeDetails) => {\n gceCommand.viewState.instanceTypeDetails = instanceTypeDetails;\n });\n onTypeChanged && onTypeChanged(nextInstanceType);\n };\n\n return (\n <CustomInstanceConfigurer\n instanceFamilyList={choices.instanceFamilyList}\n memoryList={choices.memoryList}\n onChange={handleChange}\n selectedExtendedMemory={effectiveConfig.extendedMemory}\n selectedInstanceFamily={effectiveConfig.instanceFamily}\n selectedMemory={effectiveConfig.memory}\n selectedVCpuCount={effectiveConfig.vCpuCount}\n vCpuList={choices.vCpuList}\n />\n );\n}\n\nfunction getInitialConfig(command: any): ICustomInstanceConfig {\n if (command.viewState.customInstance) {\n return {\n extendedMemory: isExtendedMemory(command.instanceType),\n ...command.viewState.customInstance,\n };\n }\n\n const parsed = command.instanceType\n ? customInstanceBuilderService.parseInstanceTypeString(stripExtendedMemorySuffix(command.instanceType))\n : { instanceFamily: 'N1', vCpuCount: null, memory: null };\n\n const config = withValidDefaults(\n {\n ...parsed,\n extendedMemory: isExtendedMemory(command.instanceType),\n },\n getChoices(command, parsed as Partial<ICustomInstanceConfig>),\n );\n command.viewState.customInstance = config;\n return config;\n}\n\nfunction withValidDefaults(\n config: Partial<ICustomInstanceConfig>,\n choices: ReturnType<typeof getChoices>,\n): ICustomInstanceConfig {\n const instanceFamily = config.instanceFamily || choices.instanceFamilyList[0] || 'N1';\n const vCpuCount = config.vCpuCount || choices.vCpuList[0];\n const memoryList = choices.memoryList.length\n ? choices.memoryList\n : vCpuCount\n ? customInstanceBuilderService.generateValidMemoryListForVCpuCount(instanceFamily, vCpuCount)\n : [];\n\n return {\n extendedMemory: Boolean(config.extendedMemory),\n instanceFamily,\n memory: config.memory || memoryList[0],\n vCpuCount,\n };\n}\n\nfunction getChoices(command: any, config: Partial<ICustomInstanceConfig>) {\n const customInstanceTypes = command.backingData.customInstanceTypes || {};\n const location = command.regional ? command.region : command.zone;\n const locationToInstanceTypesMap =\n command.backingData.credentialsKeyedByAccount?.[command.credentials]?.locationToInstanceTypesMap;\n const vCpuList =\n customInstanceTypes.vCpuList ||\n (location && locationToInstanceTypesMap\n ? customInstanceBuilderService.generateValidVCpuListForLocation(location, locationToInstanceTypesMap)\n : []);\n const selectedVCpu = config.vCpuCount || vCpuList[0];\n\n return {\n instanceFamilyList:\n customInstanceTypes.instanceFamilyList || customInstanceBuilderService.generateValidInstanceFamilyList(),\n memoryList:\n customInstanceTypes.memoryList ||\n (selectedVCpu\n ? customInstanceBuilderService.generateValidMemoryListForVCpuCount(config.instanceFamily || 'N1', selectedVCpu)\n : []),\n vCpuList,\n };\n}\n\nfunction isExtendedMemory(instanceType: string | null) {\n return Boolean(instanceType && instanceType.endsWith('-ext'));\n}\n\nfunction stripExtendedMemorySuffix(instanceType: string) {\n return isExtendedMemory(instanceType) ? instanceType.replace(/-ext$/, '') : instanceType;\n}\n","import { isEmpty } from 'lodash';\nimport React from 'react';\n\nimport type { IGceInstanceFlexibilityPolicy } from '../../domain/serverGroup';\n\nexport interface IGceInstanceFlexibilityPolicyDetailsProps {\n instanceFlexibilityPolicy?: IGceInstanceFlexibilityPolicy;\n}\n\nexport function GceInstanceFlexibilityPolicyDetails({\n instanceFlexibilityPolicy,\n}: IGceInstanceFlexibilityPolicyDetailsProps) {\n const selections = instanceFlexibilityPolicy?.instanceSelections;\n if (isEmpty(selections)) {\n return null;\n }\n\n return (\n <dl className=\"dl-horizontal dl-narrow\">\n {Object.entries(selections).map(([name, selection]) => (\n <React.Fragment key={name}>\n <dt>Selection</dt>\n <dd>{name}</dd>\n {selection.rank != null && (\n <>\n <dt>Rank</dt>\n <dd>{selection.rank}</dd>\n </>\n )}\n <dt>Machine types</dt>\n <dd>{(selection.machineTypes || []).join(', ')}</dd>\n </React.Fragment>\n ))}\n </dl>\n );\n}\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { Application, IModalComponentProps } from '@spinnaker/core';\nimport { ModalClose, ReactModal, SubmitButton, TaskMonitor, TaskMonitorWrapper } from '@spinnaker/core';\n\nimport { GceAutoHealingPolicyEditor } from '../../../../autoHealingPolicy';\nimport type { IGcePolicyServerGroup } from '../../../../autoscalingPolicy';\nimport { GceAutoscalingPolicyWriter } from '../../../../autoscalingPolicy';\nimport type { IGceAutoHealingPolicy } from '../../../../domain';\n\nexport interface IGceUpsertAutoHealingPolicyModalProps extends IModalComponentProps {\n application: Application;\n serverGroup: IGcePolicyServerGroup;\n policy?: IGceAutoHealingPolicy;\n}\n\ninterface IGceUpsertAutoHealingPolicyModalState {\n policy: IGceAutoHealingPolicy;\n taskMonitor: TaskMonitor;\n}\n\nconst MAX_INT = 2147483647;\n\nfunction isIntegerInRange(value: unknown, maximum = MAX_INT): value is number {\n return (\n typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value) && value >= 0 && value <= maximum\n );\n}\n\nfunction isValidPolicy(policy: IGceAutoHealingPolicy): boolean {\n return Boolean(policy.healthCheck?.trim() && policy.healthCheckKind && isIntegerInRange(policy.initialDelaySec));\n}\n\nexport class GceUpsertAutoHealingPolicyModal extends React.Component<\n IGceUpsertAutoHealingPolicyModalProps,\n IGceUpsertAutoHealingPolicyModalState\n> {\n public static show(props: IGceUpsertAutoHealingPolicyModalProps): Promise<void> {\n return ReactModal.show(GceUpsertAutoHealingPolicyModal, props, { dialogClassName: 'modal-md' });\n }\n\n public constructor(props: IGceUpsertAutoHealingPolicyModalProps) {\n super(props);\n const action = props.policy ? 'Edit' : 'New';\n const policy = cloneDeep(props.policy || { initialDelaySec: 300 });\n Reflect.deleteProperty(policy, 'maxUnavailable');\n this.state = {\n policy,\n taskMonitor: new TaskMonitor({\n application: props.application,\n title: `${action} autohealing policy for ${props.serverGroup.name}`,\n onDismiss: () => props.dismissModal?.(),\n onTaskComplete: () => {\n props.application.serverGroups?.refresh?.();\n props.closeModal?.();\n },\n }),\n };\n }\n\n private submit = (): void => {\n this.state.taskMonitor.submit(() =>\n GceAutoscalingPolicyWriter.upsertAutoHealingPolicy(\n this.props.application,\n this.props.serverGroup,\n this.state.policy,\n ),\n );\n };\n\n public render(): JSX.Element {\n const isNew = !this.props.policy;\n return (\n <>\n <TaskMonitorWrapper monitor={this.state.taskMonitor} />\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h4 className=\"modal-title\">{isNew ? 'New' : 'Edit'} autohealing policy</h4>\n </div>\n <div className=\"modal-body\">\n <GceAutoHealingPolicyEditor\n account={this.props.serverGroup.account}\n policy={this.state.policy}\n onChange={(policy) => this.setState({ policy })}\n />\n </div>\n <div className=\"modal-footer\">\n <button className=\"btn btn-default\" type=\"button\" onClick={() => this.props.dismissModal?.()}>\n Cancel\n </button>\n <SubmitButton\n isDisabled={!isValidPolicy(this.state.policy)}\n label={isNew ? 'Create' : 'Update'}\n onClick={this.submit}\n submitting={this.state.taskMonitor.submitting}\n />\n </div>\n </>\n );\n }\n}\n","import React from 'react';\n\nimport type { Application, IManagedResource } from '@spinnaker/core';\nimport { ConfirmationModalService, confirmNotManaged } from '@spinnaker/core';\n\nimport type { IGcePolicyServerGroup } from '../../../autoscalingPolicy';\nimport { GceAutoscalingPolicyWriter } from '../../../autoscalingPolicy';\nimport type { IGceAutoHealingPolicy } from '../../../domain';\nimport { GceUpsertAutoHealingPolicyModal } from './modal/GceUpsertAutoHealingPolicyModal';\n\nexport interface IGceAutoHealingPolicyDetailsProps {\n application: Application;\n mutationsEnabled: boolean;\n serverGroup: IGcePolicyServerGroup & IManagedResource;\n policy?: IGceAutoHealingPolicy;\n}\n\nexport function GceAutoHealingPolicyDetails({\n application,\n mutationsEnabled,\n serverGroup,\n policy,\n}: IGceAutoHealingPolicyDetailsProps): JSX.Element | null {\n const runIfNotManaged = (action: () => void): void => {\n confirmNotManaged(serverGroup, application).then((notManaged) => notManaged && action());\n };\n\n if (!policy) {\n return mutationsEnabled ? (\n <button\n className=\"btn btn-link\"\n data-testid=\"add-auto-healing-policy\"\n type=\"button\"\n onClick={() => runIfNotManaged(() => GceUpsertAutoHealingPolicyModal.show({ application, serverGroup }))}\n >\n Add auto-healing policy\n </button>\n ) : null;\n }\n\n const deletePolicy = (): void => {\n ConfirmationModalService.confirm({\n header: `Really delete autohealer for ${serverGroup.name}?`,\n buttonText: 'Delete autohealer',\n account: serverGroup.account,\n taskMonitorConfig: { application, title: `Deleting autohealing policy for ${serverGroup.name}` },\n submitMethod: () => GceAutoscalingPolicyWriter.deleteAutoHealingPolicy(application, serverGroup),\n });\n };\n\n return (\n <div className=\"gce-auto-healing-policy-details\">\n <dl className=\"horizontal-when-filters-collapsed\">\n <dt>Health Check</dt>\n <dd>{policy.healthCheck || policy.healthCheckUrl || '-'}</dd>\n <dt>Initial Delay</dt>\n <dd>{policy.initialDelaySec ?? '-'} seconds</dd>\n </dl>\n {mutationsEnabled && (\n <div className=\"text-right\">\n <button\n className=\"btn btn-link\"\n data-testid=\"edit-auto-healing-policy\"\n type=\"button\"\n onClick={() =>\n runIfNotManaged(() => GceUpsertAutoHealingPolicyModal.show({ application, serverGroup, policy }))\n }\n >\n Edit\n </button>\n <button\n className=\"btn btn-link\"\n data-testid=\"delete-auto-healing-policy\"\n type=\"button\"\n onClick={() => runIfNotManaged(deletePolicy)}\n >\n Delete\n </button>\n </div>\n )}\n </div>\n );\n}\n","import { cloneDeep } from 'lodash';\nimport React from 'react';\n\nimport type { Application, IModalComponentProps } from '@spinnaker/core';\nimport { ModalClose, ReactModal, SubmitButton, TaskMonitor, TaskMonitorWrapper } from '@spinnaker/core';\n\nimport type { IGceAutoscalingPolicy, IGcePolicyServerGroup } from '../../../../autoscalingPolicy';\nimport {\n GceAutoscalingPolicyEditor,\n GceAutoscalingPolicyWriter,\n GcePredictiveMethod,\n} from '../../../../autoscalingPolicy';\nimport { GCEProviderSettings } from '../../../../gce.settings';\n\nconst MAX_INT = 2147483647;\nconst MAX_SCHEDULE_DURATION_SECONDS = 14 * 24 * 60 * 60;\n\nfunction isIntegerInRange(value: unknown, minimum: number, maximum = MAX_INT): value is number {\n return (\n typeof value === 'number' &&\n Number.isFinite(value) &&\n Number.isInteger(value) &&\n value >= minimum &&\n value <= maximum\n );\n}\n\nfunction isUtilizationTarget(value: unknown, maximum?: number): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 && (maximum === undefined || value < maximum);\n}\n\nfunction isSingleInstanceAssignment(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0;\n}\n\nfunction isValidCustomMetric(metric: NonNullable<IGceAutoscalingPolicy['customMetricUtilizations']>[number]): boolean {\n if (!metric.metric?.trim() || !metric.metricExportScope) {\n return false;\n }\n if (\n metric.metricExportScope === 'SINGLE_TIME_SERIES_PER_GROUP' &&\n metric.scalingpolicy === 'SINGLE_INSTANCE_ASSIGNMENT'\n ) {\n return isSingleInstanceAssignment(metric.singleInstanceAssignment);\n }\n if (metric.metricExportScope === 'SINGLE_TIME_SERIES_PER_GROUP' && metric.scalingpolicy !== 'UTILIZATION_TARGET') {\n return false;\n }\n return isUtilizationTarget(metric.utilizationTarget) && Boolean(metric.utilizationTargetType);\n}\n\nfunction hasValidMetrics(policy: IGceAutoscalingPolicy): boolean {\n const cpuConfigured = Boolean(policy.cpuUtilization && Object.keys(policy.cpuUtilization).length);\n const loadBalancingConfigured = Boolean(\n policy.loadBalancingUtilization && Object.keys(policy.loadBalancingUtilization).length,\n );\n const customMetrics = policy.customMetricUtilizations || [];\n const cpuValid = !cpuConfigured || isUtilizationTarget(policy.cpuUtilization?.utilizationTarget, 1);\n const loadBalancingValid =\n !loadBalancingConfigured || isUtilizationTarget(policy.loadBalancingUtilization?.utilizationTarget, 1);\n const customMetricsValid = customMetrics.every(isValidCustomMetric);\n return (\n cpuValid &&\n loadBalancingValid &&\n customMetricsValid &&\n ((cpuConfigured && cpuValid) || (loadBalancingConfigured && loadBalancingValid) || customMetrics.length > 0)\n );\n}\n\nfunction hasValidSchedules(policy: IGceAutoscalingPolicy): boolean {\n return (policy.scalingSchedules || []).every(\n (schedule) =>\n Boolean(schedule.scheduleName?.trim()) &&\n isIntegerInRange(schedule.minimumRequiredInstances, 0, policy.maxNumReplicas) &&\n Boolean(schedule.scheduleCron?.trim()) &&\n Boolean(schedule.timezone?.trim()) &&\n isIntegerInRange(schedule.duration, 301, MAX_SCHEDULE_DURATION_SECONDS),\n );\n}\n\nfunction hasValidScaleInControl(policy: IGceAutoscalingPolicy): boolean {\n if (!policy.scaleInControl) {\n return true;\n }\n const { maxScaledInReplicas, timeWindowSec } = policy.scaleInControl;\n const hasFixed = maxScaledInReplicas?.fixed !== undefined;\n const hasPercent = maxScaledInReplicas?.percent !== undefined;\n if (hasFixed === hasPercent || !isIntegerInRange(timeWindowSec, 60, 3600)) {\n return false;\n }\n return hasPercent\n ? isIntegerInRange(maxScaledInReplicas?.percent, 0, 100)\n : isIntegerInRange(maxScaledInReplicas?.fixed, 0);\n}\n\nexport interface IGceUpsertAutoscalingPolicyModalProps extends IModalComponentProps {\n application: Application;\n serverGroup: IGcePolicyServerGroup & { capacity?: { min?: number; max?: number } };\n policy?: IGceAutoscalingPolicy;\n}\n\ninterface IGceUpsertAutoscalingPolicyModalState {\n policy: IGceAutoscalingPolicy;\n taskMonitor: TaskMonitor;\n}\n\nfunction initialPolicy(props: IGceUpsertAutoscalingPolicyModalProps): IGceAutoscalingPolicy {\n return cloneDeep(\n props.policy || {\n minNumReplicas: props.serverGroup.capacity?.min ?? 0,\n maxNumReplicas: props.serverGroup.capacity?.max ?? 1,\n coolDownPeriodSec: 60,\n mode: 'ON',\n cpuUtilization: { utilizationTarget: 0.6 },\n },\n );\n}\n\nexport class GceUpsertAutoscalingPolicyModal extends React.Component<\n IGceUpsertAutoscalingPolicyModalProps,\n IGceUpsertAutoscalingPolicyModalState\n> {\n public static show(props: IGceUpsertAutoscalingPolicyModalProps): Promise<void> {\n return ReactModal.show(GceUpsertAutoscalingPolicyModal, props, { dialogClassName: 'modal-lg' });\n }\n\n public constructor(props: IGceUpsertAutoscalingPolicyModalProps) {\n super(props);\n const action = props.policy ? 'Edit' : 'New';\n this.state = {\n policy: initialPolicy(props),\n taskMonitor: new TaskMonitor({\n application: props.application,\n title: `${action} scaling policy for ${props.serverGroup.name}`,\n onDismiss: () => props.dismissModal?.(),\n onTaskComplete: () => {\n props.application.serverGroups?.refresh?.();\n props.closeModal?.();\n },\n }),\n };\n }\n\n private submit = (): void => {\n this.state.taskMonitor.submit(() =>\n GceAutoscalingPolicyWriter.upsertAutoscalingPolicy(\n this.props.application,\n this.props.serverGroup,\n this.state.policy,\n ),\n );\n };\n\n public render(): JSX.Element {\n const isNew = !this.props.policy;\n return (\n <>\n <TaskMonitorWrapper monitor={this.state.taskMonitor} />\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h4 className=\"modal-title\">{isNew ? 'New' : 'Edit'} autoscaling policy</h4>\n </div>\n <div className=\"modal-body\">\n <GceAutoscalingPolicyEditor policy={this.state.policy} onChange={(policy) => this.setState({ policy })} />\n </div>\n <div className=\"modal-footer\">\n <button className=\"btn btn-default\" type=\"button\" onClick={() => this.props.dismissModal?.()}>\n Cancel\n </button>\n <SubmitButton\n isDisabled={!this.isValid()}\n label={isNew ? 'Create' : 'Update'}\n onClick={this.submit}\n submitting={this.state.taskMonitor.submitting}\n />\n </div>\n </>\n );\n }\n\n private isValid(): boolean {\n const { policy } = this.state;\n const predictiveEnabled = policy.cpuUtilization?.predictiveMethod === GcePredictiveMethod.STANDARD;\n return (\n isIntegerInRange(policy.minNumReplicas, 0) &&\n isIntegerInRange(policy.maxNumReplicas, 0) &&\n policy.minNumReplicas <= policy.maxNumReplicas &&\n isIntegerInRange(policy.coolDownPeriodSec, 15) &&\n hasValidMetrics(policy) &&\n hasValidSchedules(policy) &&\n hasValidScaleInControl(policy) &&\n (!predictiveEnabled || Boolean(GCEProviderSettings.feature.predictiveAutoscaling)) &&\n (!predictiveEnabled || isUtilizationTarget(policy.cpuUtilization?.utilizationTarget, 1))\n );\n }\n}\n","import React from 'react';\n\nimport type { Application, IManagedResource } from '@spinnaker/core';\nimport { ConfirmationModalService, confirmNotManaged } from '@spinnaker/core';\n\nimport type { IGceAutoscalingPolicy, IGcePolicyServerGroup } from '../../../autoscalingPolicy';\nimport { GceAutoscalingPolicyWriter } from '../../../autoscalingPolicy';\nimport { GCEProviderSettings } from '../../../gce.settings';\nimport { GceUpsertAutoscalingPolicyModal } from './modal/GceUpsertAutoscalingPolicyModal';\n\nexport interface IGceAutoscalingPolicyDetailsProps {\n application: Application;\n mutationsEnabled: boolean;\n serverGroup: IGcePolicyServerGroup & IManagedResource & { autoscalingMessages?: string[] };\n policy?: IGceAutoscalingPolicy;\n}\n\nfunction percentage(value?: number): string {\n return value === undefined ? '-' : `${Math.round(value * 100)}%`;\n}\n\nexport function GceAutoscalingPolicyDetails({\n application,\n mutationsEnabled,\n serverGroup,\n policy,\n}: IGceAutoscalingPolicyDetailsProps): JSX.Element | null {\n const runIfNotManaged = (action: () => void): void => {\n confirmNotManaged(serverGroup, application).then((notManaged) => notManaged && action());\n };\n\n if (!policy) {\n return mutationsEnabled ? (\n <button\n className=\"btn btn-link\"\n data-testid=\"add-autoscaling-policy\"\n type=\"button\"\n onClick={() => runIfNotManaged(() => GceUpsertAutoscalingPolicyModal.show({ application, serverGroup }))}\n >\n Add autoscaling policy\n </button>\n ) : null;\n }\n\n const maxScaledInReplicas = policy.scaleInControl?.maxScaledInReplicas;\n const maxScaledIn =\n typeof maxScaledInReplicas?.percent === 'number'\n ? `${maxScaledInReplicas.percent}%`\n : typeof maxScaledInReplicas?.fixed === 'number'\n ? `${maxScaledInReplicas.fixed}`\n : undefined;\n\n const deletePolicy = (): void => {\n ConfirmationModalService.confirm({\n header: `Really delete autoscaler for ${serverGroup.name}?`,\n buttonText: 'Delete autoscaler',\n account: serverGroup.account,\n taskMonitorConfig: { application, title: `Deleting autoscaler for ${serverGroup.name}` },\n submitMethod: () => GceAutoscalingPolicyWriter.deleteAutoscalingPolicy(application, serverGroup),\n });\n };\n\n return (\n <div className=\"gce-autoscaling-policy-details\">\n <dl className=\"horizontal-when-filters-collapsed\">\n {policy.cpuUtilization && (\n <>\n <dt>Target CPU Usage</dt>\n <dd>CPU Usage: {percentage(policy.cpuUtilization.utilizationTarget)}</dd>\n </>\n )}\n {GCEProviderSettings.feature.predictiveAutoscaling && policy.cpuUtilization?.predictiveMethod !== undefined && (\n <>\n <dt>Predictive Autoscaling</dt>\n <dd>{policy.cpuUtilization.predictiveMethod}</dd>\n </>\n )}\n {policy.loadBalancingUtilization && (\n <>\n <dt>Target HTTP Load Balancing Usage</dt>\n <dd>{percentage(policy.loadBalancingUtilization.utilizationTarget)}</dd>\n </>\n )}\n {(policy.customMetricUtilizations || []).map((metric, index) => (\n <React.Fragment key={`${metric.metric}-${index}`}>\n <dt>Monitoring Metric</dt>\n <dd>\n {metric.metric || '-'}: {metric.utilizationTarget ?? metric.singleInstanceAssignment ?? '-'}\n {metric.utilizationTargetType === 'DELTA_PER_SECOND'\n ? '/sec'\n : metric.utilizationTargetType === 'DELTA_PER_MINUTE'\n ? '/min'\n : ''}\n </dd>\n </React.Fragment>\n ))}\n <dt>Min # VMs</dt>\n <dd>{policy.minNumReplicas ?? '-'}</dd>\n <dt>Max # VMs</dt>\n <dd>{policy.maxNumReplicas ?? '-'}</dd>\n <dt>Cool-down Period</dt>\n <dd>{policy.coolDownPeriodSec ?? '-'} sec</dd>\n <dt>Mode</dt>\n <dd>{policy.mode || '-'}</dd>\n {policy.scaleInControl && (\n <>\n <dt>Max Scaled-in Replicas</dt>\n <dd>{maxScaledIn ?? '-'}</dd>\n <dt>Scale-in Time Window</dt>\n <dd>{policy.scaleInControl.timeWindowSec ?? '-'} seconds</dd>\n </>\n )}\n {(policy.scalingSchedules || []).map((schedule, index) => (\n <React.Fragment key={`${schedule.scheduleName}-${index}`}>\n <dt>Scaling Schedule</dt>\n <dd>\n {schedule.scheduleName || '-'} ({schedule.enabled ? 'enabled' : 'disabled'})\n {schedule.timezone ? `, ${schedule.timezone}` : ''}\n </dd>\n </React.Fragment>\n ))}\n {(serverGroup.autoscalingMessages || []).map((message, index) => (\n <React.Fragment key={index}>\n <dt>Message</dt>\n <dd>{message}</dd>\n </React.Fragment>\n ))}\n </dl>\n {mutationsEnabled && (\n <div className=\"text-right\">\n <button\n className=\"btn btn-link\"\n data-testid=\"edit-autoscaling-policy\"\n type=\"button\"\n onClick={() =>\n runIfNotManaged(() => GceUpsertAutoscalingPolicyModal.show({ application, serverGroup, policy }))\n }\n >\n Edit\n </button>\n <button\n className=\"btn btn-link\"\n data-testid=\"delete-autoscaling-policy\"\n type=\"button\"\n onClick={() => runIfNotManaged(deletePolicy)}\n >\n Delete\n </button>\n </div>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps, IServerGroup, IServerGroupJob, ITask } from '@spinnaker/core';\nimport {\n ModalClose,\n PlatformHealthOverride,\n ReactModal,\n TaskMonitor,\n TaskMonitorWrapper,\n TaskReason,\n UserVerification,\n ValidationMessage,\n} from '@spinnaker/core';\n\nimport type { IGceAutoscalingPolicy } from '../../../autoscalingPolicy/IGceAutoscalingPolicy';\n\nexport interface IGceResizeValues {\n interestingHealthProviderNames?: string[];\n newMaxNumReplicas?: number;\n newMinNumReplicas?: number;\n newSize?: number;\n reason?: string;\n}\n\nexport type GceResizeErrors = Partial<Record<keyof IGceResizeValues, string>>;\n\nexport interface IGceFixedResizeJob extends IServerGroupJob {\n interestingHealthProviderNames?: string[];\n reason?: string;\n targetSize: number;\n}\n\nexport interface IGceAutoscalerResizeRequest {\n params: {\n interestingHealthProviderNames?: string[];\n reason?: string;\n };\n policy: IGceAutoscalingPolicy & {\n maxNumReplicas: number;\n minNumReplicas: number;\n };\n}\n\nexport interface IGceAutoscalingPolicyWriter {\n upsertAutoscalingPolicy(\n application: Application,\n serverGroup: IServerGroup,\n policy: IGceAutoscalerResizeRequest['policy'],\n params: IGceAutoscalerResizeRequest['params'],\n ): Promise<ITask>;\n}\n\nexport interface IGceResizeServerGroupWriter {\n resizeServerGroup(serverGroup: IServerGroup, application: Application, command: IGceFixedResizeJob): Promise<ITask>;\n}\n\nexport interface IGceResizeServerGroupModalProps extends IModalComponentProps {\n application: Application;\n autoscalingPolicyWriter: IGceAutoscalingPolicyWriter;\n serverGroup: IServerGroup;\n serverGroupWriter: IGceResizeServerGroupWriter;\n}\n\ninterface IGceResizeServerGroupModalState {\n taskMonitor: TaskMonitor;\n values: IGceResizeValues;\n verified: boolean;\n}\n\nexport function buildGceAutoscalerResizeRequest(\n values: IGceResizeValues & { newMaxNumReplicas: number; newMinNumReplicas: number },\n): IGceAutoscalerResizeRequest {\n return {\n params: {\n interestingHealthProviderNames: values.interestingHealthProviderNames,\n reason: values.reason,\n },\n policy: {\n maxNumReplicas: values.newMaxNumReplicas,\n minNumReplicas: values.newMinNumReplicas,\n },\n };\n}\n\nexport function buildGceFixedResizeJob(\n serverGroup: IServerGroup,\n values: IGceResizeValues & { newSize: number },\n): IGceFixedResizeJob {\n return {\n capacity: { desired: values.newSize, max: values.newSize, min: values.newSize },\n interestingHealthProviderNames: values.interestingHealthProviderNames,\n reason: values.reason,\n region: serverGroup.region,\n serverGroupName: serverGroup.name,\n targetSize: values.newSize,\n };\n}\n\nexport function validateGceResizeValues(serverGroup: IServerGroup, values: IGceResizeValues): GceResizeErrors {\n if (!serverGroup.autoscalingPolicy && values.newSize === undefined) {\n return { newSize: 'Size is required' };\n }\n\n if (\n !serverGroup.autoscalingPolicy &&\n values.newSize !== undefined &&\n (!Number.isInteger(values.newSize) || values.newSize < 0)\n ) {\n return { newSize: 'Size must be a finite non-negative integer' };\n }\n\n if (serverGroup.autoscalingPolicy) {\n const errors: GceResizeErrors = {};\n if (values.newMinNumReplicas === undefined) {\n errors.newMinNumReplicas = 'Min is required';\n }\n if (values.newMaxNumReplicas === undefined) {\n errors.newMaxNumReplicas = 'Max is required';\n }\n if (Object.keys(errors).length) {\n return errors;\n }\n if (!Number.isInteger(values.newMinNumReplicas) || values.newMinNumReplicas < 0) {\n errors.newMinNumReplicas = 'Min must be a finite non-negative integer';\n }\n if (!Number.isInteger(values.newMaxNumReplicas) || values.newMaxNumReplicas < 0) {\n errors.newMaxNumReplicas = 'Max must be a finite non-negative integer';\n }\n if (Object.keys(errors).length) {\n return errors;\n }\n }\n\n if (\n serverGroup.autoscalingPolicy &&\n values.newMinNumReplicas !== undefined &&\n values.newMaxNumReplicas !== undefined &&\n values.newMinNumReplicas > values.newMaxNumReplicas\n ) {\n return {\n newMaxNumReplicas: 'Min cannot be larger than Max',\n newMinNumReplicas: 'Min cannot be larger than Max',\n };\n }\n\n return {};\n}\n\nexport class GceResizeServerGroupModal extends React.Component<\n IGceResizeServerGroupModalProps,\n IGceResizeServerGroupModalState\n> {\n public static show(props: IGceResizeServerGroupModalProps): Promise<void> {\n return ReactModal.show(GceResizeServerGroupModal, props);\n }\n\n constructor(props: IGceResizeServerGroupModalProps) {\n super(props);\n const { application } = props;\n this.state = {\n taskMonitor: new TaskMonitor({\n application,\n title: `Resizing ${props.serverGroup.name}`,\n onDismiss: () => this.props.dismissModal(),\n onTaskComplete: () => application.serverGroups.refresh(),\n }),\n values: {\n interestingHealthProviderNames:\n application.attributes?.platformHealthOnlyShowOverride && application.attributes?.platformHealthOnly\n ? ['Google']\n : undefined,\n },\n verified: false,\n };\n }\n\n private isValid = (): boolean =>\n this.state.verified && Object.keys(validateGceResizeValues(this.props.serverGroup, this.state.values)).length === 0;\n\n private submit = (): void => {\n if (!this.isValid()) {\n return;\n }\n\n const { application, autoscalingPolicyWriter, serverGroup, serverGroupWriter } = this.props;\n if (serverGroup.autoscalingPolicy) {\n const { params, policy } = buildGceAutoscalerResizeRequest(\n this.state.values as IGceResizeValues & { newMaxNumReplicas: number; newMinNumReplicas: number },\n );\n this.state.taskMonitor.submit(() =>\n autoscalingPolicyWriter.upsertAutoscalingPolicy(application, serverGroup, policy, params),\n );\n return;\n }\n\n const command = buildGceFixedResizeJob(serverGroup, this.state.values as IGceResizeValues & { newSize: number });\n this.state.taskMonitor.submit(() => serverGroupWriter.resizeServerGroup(serverGroup, application, command));\n };\n\n public render(): JSX.Element {\n const { application, serverGroup } = this.props;\n const { values } = this.state;\n const currentSize = serverGroup.asg?.desiredCapacity ?? serverGroup.capacity?.desired;\n const errorMessage = Object.values(validateGceResizeValues(serverGroup, values))[0];\n\n return (\n <>\n <TaskMonitorWrapper monitor={this.state.taskMonitor} />\n <ModalClose dismiss={this.props.dismissModal} />\n <div className=\"modal-header\">\n <h4 className=\"modal-title\">Resize {serverGroup.name}</h4>\n </div>\n <div className=\"modal-body\">\n <form className=\"form-horizontal\">\n {serverGroup.autoscalingPolicy ? (\n <>\n <p>Sets min and max instance counts for this server group's autoscaling policy.</p>\n <div className=\"form-group\">\n <div className=\"col-md-2 col-md-offset-3\">\n <b>Min</b>\n </div>\n <div className=\"col-md-2\">\n <b>Max</b>\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\">Current</label>\n <div className=\"col-md-2\">\n <input\n className=\"form-control input-sm\"\n disabled={true}\n type=\"number\"\n value={serverGroup.autoscalingPolicy.minNumReplicas}\n />\n </div>\n <div className=\"col-md-2\">\n <input\n className=\"form-control input-sm\"\n disabled={true}\n type=\"number\"\n value={serverGroup.autoscalingPolicy.maxNumReplicas}\n />\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\">Resize to</label>\n <div className=\"col-md-2\">\n <input\n className=\"form-control input-sm\"\n min={0}\n name=\"newMinNumReplicas\"\n onChange={(event) =>\n this.setState({\n values: {\n ...values,\n newMinNumReplicas: event.target.value === '' ? undefined : Number(event.target.value),\n },\n })\n }\n type=\"number\"\n value={values.newMinNumReplicas ?? ''}\n />\n </div>\n <div className=\"col-md-2\">\n <input\n className=\"form-control input-sm\"\n min={0}\n name=\"newMaxNumReplicas\"\n onChange={(event) =>\n this.setState({\n values: {\n ...values,\n newMaxNumReplicas: event.target.value === '' ? undefined : Number(event.target.value),\n },\n })\n }\n type=\"number\"\n value={values.newMaxNumReplicas ?? ''}\n />\n </div>\n </div>\n </>\n ) : (\n <>\n <p>Sets desired instance count for this server group.</p>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\">Current size</label>\n <div className=\"col-md-4\">\n <input className=\"form-control input-sm\" disabled={true} type=\"number\" value={currentSize} />\n </div>\n </div>\n <div className=\"form-group\">\n <label className=\"col-md-3 sm-label-right\" htmlFor=\"gce-resize-new-size\">\n Resize to\n </label>\n <div className=\"col-md-4\">\n <input\n className=\"form-control input-sm\"\n id=\"gce-resize-new-size\"\n min={0}\n name=\"newSize\"\n onChange={(event) =>\n this.setState({\n values: {\n ...values,\n newSize: event.target.value === '' ? undefined : Number(event.target.value),\n },\n })\n }\n type=\"number\"\n value={values.newSize ?? ''}\n />\n </div>\n </div>\n </>\n )}\n {errorMessage && <ValidationMessage message={errorMessage} type=\"error\" />}\n {application.attributes?.platformHealthOnlyShowOverride && (\n <PlatformHealthOverride\n interestingHealthProviderNames={values.interestingHealthProviderNames}\n onChange={(interestingHealthProviderNames) =>\n this.setState({ values: { ...values, interestingHealthProviderNames } })\n }\n platformHealthType=\"Google\"\n showHelpDetails={true}\n />\n )}\n <TaskReason\n reason={values.reason}\n onChange={(reason) => this.setState({ values: { ...values, reason } })}\n />\n </form>\n </div>\n <div className=\"modal-footer\">\n <UserVerification account={serverGroup.account} onValidChange={(verified) => this.setState({ verified })} />\n <button className=\"btn btn-default\" onClick={this.props.dismissModal} type=\"button\">\n Cancel\n </button>\n <button className=\"btn btn-primary\" disabled={!this.isValid()} onClick={this.submit} type=\"button\">\n Submit\n </button>\n </div>\n </>\n );\n }\n}\n","import React from 'react';\n\nimport type { Application, IModalComponentProps, IServerGroup, IServerGroupJob, ITask } from '@spinnaker/core';\nimport {\n ModalClose,\n noop,\n PlatformHealthOverride,\n ReactModal,\n TaskMonitor,\n TaskMonitorWrapper,\n TaskReason,\n UserVerification,\n} from '@spinnaker/core';\n\nexport interface IGceRollbackValues {\n interestingHealthProviderNames?: string[];\n reason?: string;\n restoreServerGroupName?: string;\n}\n\nexport interface IGceRollbackJob extends IServerGroupJob {\n interestingHealthProviderNames?: string[];\n platformHealthOnlyShowOverride?: boolean;\n reason?: string;\n rollbackContext: {\n restoreServerGroupName?: string;\n rollbackServerGroupName: string;\n };\n rollbackType: 'EXPLICIT';\n}\n\nexport interface IGceRollbackServerGroupWriter {\n rollbackServerGroup(serverGroup: IServerGroup, application: Application, command: IGceRollbackJob): Promise<ITask>;\n}\n\nexport interface IGceRollbackServerGroupModalProps extends IModalComponentProps {\n application: Application;\n serverGroup: IServerGroup;\n serverGroups: IServerGroup[];\n serverGroupWriter: IGceRollbackServerGroupWriter;\n}\n\ninterface IGceRollbackServerGroupModalState {\n taskMonitor: TaskMonitor;\n values: IGceRollbackValues;\n verified: boolean;\n}\n\nexport function buildGceRollbackJob(\n application: Application,\n serverGroup: IServerGroup,\n values: IGceRollbackValues,\n): IGceRollbackJob {\n return {\n interestingHealthProviderNames: values.interestingHealthProviderNames,\n platformHealthOnlyShowOverride: application.attributes?.platformHealthOnlyShowOverride,\n reason: values.reason,\n rollbackContext: {\n restoreServerGroupName: values.restoreServerGroupName,\n rollbackServerGroupName: serverGroup.name,\n },\n rollbackType: 'EXPLICIT',\n };\n}\n\nexport function getGceRollbackCandidates(\n application: Application,\n serverGroup: IServerGroup,\n candidates: IServerGroup[],\n): IServerGroup[] {\n return candidates\n .filter((candidate) => {\n const candidateApplication = candidate.app || candidate.moniker?.app;\n return (\n candidate.isDisabled === true &&\n candidateApplication === application.name &&\n candidate.cluster === serverGroup.cluster &&\n candidate.account === serverGroup.account &&\n candidate.region === serverGroup.region\n );\n })\n .sort((a, b) => b.name.localeCompare(a.name));\n}\n\nexport class GceRollbackServerGroupModal extends React.Component<\n IGceRollbackServerGroupModalProps,\n IGceRollbackServerGroupModalState\n> {\n public static defaultProps: Partial<IGceRollbackServerGroupModalProps> = {\n closeModal: noop,\n dismissModal: noop,\n };\n\n public static show(props: IGceRollbackServerGroupModalProps): Promise<IGceRollbackJob> {\n return ReactModal.show(GceRollbackServerGroupModal, props);\n }\n\n constructor(props: IGceRollbackServerGroupModalProps) {\n super(props);\n const { application, serverGroup } = props;\n this.state = {\n taskMonitor: new TaskMonitor({\n application,\n title: `Rollback ${serverGroup.name}`,\n onDismiss: () => this.props.dismissModal(),\n onTaskComplete: () => application.serverGroups.refresh(),\n }),\n values: {\n interestingHealthProviderNames:\n application.attributes?.platformHealthOnlyShowOverride && application.attributes?.platformHealthOnly\n ? ['Google']\n : undefined,\n },\n verified: false,\n };\n }\n\n private close = (): void => this.props.dismissModal();\n\n private isValid = (): boolean => this.state.verified && !!this.state.values.restoreServerGroupName;\n\n private submit = (): void => {\n if (!this.isValid()) {\n return;\n }\n\n const { application, serverGroup, serverGroupWriter } = this.props;\n const job = buildGceRollbackJob(application, serverGroup, this.state.values);\n this.state.taskMonitor.submit(() => serverGroupWriter.rollbackServerGroup(serverGroup, application, job));\n };\n\n public render(): JSX.Element {\n const { application, serverGroup, serverGroups } = this.props;\n const { taskMonitor, values } = this.state;\n const candidates = getGceRollbackCandidates(application, serverGroup, serverGroups);\n\n return (\n <>\n <TaskMonitorWrapper monitor={taskMonitor} />\n <ModalClose dismiss={this.close} />\n <div className=\"modal-header\">\n <h4 className=\"modal-title\">Rollback {serverGroup.name}</h4>\n </div>\n <div className=\"modal-body\">\n <form className=\"form-horizontal\">\n <div className=\"form-group\">\n <label className=\"col-sm-3 sm-label-right\" htmlFor=\"gce-rollback-server-group\">\n Restore to\n </label>\n <div className=\"col-sm-6\">\n <select\n className=\"form-control input-sm\"\n id=\"gce-rollback-server-group\"\n onChange={(event) =>\n this.setState({ values: { ...values, restoreServerGroupName: event.target.value || undefined } })\n }\n value={values.restoreServerGroupName || ''}\n >\n <option value=\"\">Select...</option>\n {candidates.map((candidate) => (\n <option key={candidate.name} value={candidate.name}>\n {candidate.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n {application.attributes?.platformHealthOnlyShowOverride && (\n <PlatformHealthOverride\n interestingHealthProviderNames={values.interestingHealthProviderNames}\n onChange={(interestingHealthProviderNames) =>\n this.setState({ values: { ...values, interestingHealthProviderNames } })\n }\n platformHealthType=\"Google\"\n showHelpDetails={true}\n />\n )}\n <TaskReason\n reason={values.reason}\n onChange={(reason) => this.setState({ values: { ...values, reason } })}\n />\n </form>\n </div>\n <div className=\"modal-footer\">\n <UserVerification account={serverGroup.account} onValidChange={(verified) => this.setState({ verified })} />\n <button className=\"btn btn-default\" onClick={this.close} type=\"button\">\n Cancel\n </button>\n <button className=\"btn btn-primary\" disabled={!this.isValid()} onClick={this.submit} type=\"button\">\n Submit\n </button>\n </div>\n </>\n );\n }\n}\n","import React from 'react';\nimport { Observable } from 'rxjs';\n\nimport {\n AccountTag,\n CloudProviderRegistry,\n CollapsibleSection,\n ConfirmationModalService,\n ErrorModalService,\n ManagedMenuItem,\n ServerGroupReader,\n ServerGroupWarningMessageService,\n useDeckRuntimeServices,\n} from '@spinnaker/core';\nimport type { Application } from '@spinnaker/core';\n\nimport { GceInstanceFlexibilityPolicyDetails } from './GceInstanceFlexibilityPolicyDetails';\nimport { GceAutoHealingPolicyDetails } from './autoHealingPolicy';\nimport { GceAutoscalingPolicyWriter } from '../../autoscalingPolicy';\nimport { GceAutoscalingPolicyDetails } from './autoscalingPolicy';\nimport { GceXpnNamingService } from '../../common/xpnNaming.gce.service';\nimport { GceCloneServerGroupModal } from '../configure/wizard/GceCloneServerGroupModal';\nimport type { IGceServerGroup } from '../../domain';\nimport { GceResizeServerGroupModal } from './resize/GceResizeServerGroupModal';\nimport { GceRollbackServerGroupModal, getGceRollbackCandidates } from './rollback/GceRollbackServerGroupModal';\n\nfunction findServerGroupSummary(app: any, serverGroup: any): any {\n const serverGroups = app?.serverGroups?.data || [];\n const summary = serverGroups.find((candidate: any) => {\n return (\n candidate.name === serverGroup.name &&\n candidate.account === serverGroup.accountId &&\n candidate.region === serverGroup.region\n );\n });\n if (summary) {\n return summary;\n }\n\n const loadBalancers = app?.loadBalancers?.data || [];\n for (const loadBalancer of loadBalancers) {\n const match = (loadBalancer.serverGroups || []).find((candidate: any) => {\n return (\n candidate.name === serverGroup.name &&\n candidate.account === serverGroup.accountId &&\n candidate.region === serverGroup.region\n );\n });\n if (match) {\n return match;\n }\n }\n\n return null;\n}\n\nfunction projectFromTemplate(serverGroup: any): string | undefined {\n const instanceTemplate = serverGroup.launchConfig?.instanceTemplate;\n return instanceTemplate ? new GceXpnNamingService().deriveProjectId(instanceTemplate) : undefined;\n}\n\nfunction decorateServerGroup(serverGroup: any): any {\n const project = projectFromTemplate(serverGroup);\n const instanceTemplate = serverGroup.launchConfig?.instanceTemplate;\n const networkInterface = instanceTemplate?.properties?.networkInterfaces?.[0] || {};\n const xpnNaming = new GceXpnNamingService();\n return {\n ...serverGroup,\n account: serverGroup.account || serverGroup.accountId,\n logsLink: project\n ? `https://console.cloud.google.com/logs/query?project=${encodeURIComponent(project)}&resource=gce_instance_group`\n : undefined,\n network: xpnNaming.decorateXpnResourceIfNecessary(project, networkInterface.network),\n subnet: xpnNaming.decorateXpnResourceIfNecessary(project, networkInterface.subnetwork),\n zones: [...(serverGroup.zones || [])].sort(),\n };\n}\n\nexport function gceServerGroupDetailsGetter(props: any, autoClose: () => void): Observable<any> {\n return new Observable((observer) => {\n const summary = findServerGroupSummary(props.app, props.serverGroup);\n\n ServerGroupReader.getServerGroup(\n props.app.name,\n props.serverGroup.accountId,\n props.serverGroup.region,\n props.serverGroup.name,\n ).then(\n (details: any) => {\n if (!details || Object.keys(details).length === 0) {\n autoClose();\n observer.complete();\n return;\n }\n observer.next(decorateServerGroup({ ...(summary || {}), ...details, account: props.serverGroup.accountId }));\n observer.complete();\n },\n () => {\n autoClose();\n observer.complete();\n },\n );\n });\n}\n\nfunction withGcePlatformHealthParams(app: any, params: any = {}): any {\n if (app.attributes?.platformHealthOnlyShowOverride && app.attributes?.platformHealthOnly) {\n return { ...params, interestingHealthProviderNames: params.interestingHealthProviderNames || ['Google'] };\n }\n\n return params;\n}\n\nexport function cloneGceServerGroup(\n app: any,\n serverGroup: any,\n commandBuilder: any,\n runtimeServices: ReturnType<typeof useDeckRuntimeServices>,\n): Promise<void> {\n return Promise.resolve(commandBuilder.buildServerGroupCommandFromExisting(app, serverGroup))\n .then((command: any) => {\n GceCloneServerGroupModal.show({ application: app, command, title: `Clone ${serverGroup.name}` }, runtimeServices);\n })\n .catch((error: any) => {\n ErrorModalService.error({\n header: `Error cloning ${serverGroup.name}`,\n body: error?.data?.message || error?.message || 'Unable to build the clone server group command.',\n });\n });\n}\n\nexport function GceServerGroupActions({ app, serverGroup }: { app: any; serverGroup: any }): JSX.Element {\n const runtimeServices = useDeckRuntimeServices();\n const { serverGroupCommandBuilder, serverGroupWriter } = runtimeServices;\n if (CloudProviderRegistry.isDisabled('gce')) {\n return null;\n }\n\n const confirmationDefaults = {\n account: serverGroup.account,\n askForReason: true,\n platformHealthOnlyShowOverride: app.attributes?.platformHealthOnlyShowOverride,\n platformHealthType: 'Google',\n };\n\n const cloneServerGroup = () => {\n cloneGceServerGroup(app, serverGroup, serverGroupCommandBuilder, runtimeServices);\n };\n\n const rollbackServerGroup = () => {\n const serverGroups = getGceRollbackCandidates(app, serverGroup, app.serverGroups?.data || []);\n GceRollbackServerGroupModal.show({\n application: app,\n serverGroup,\n serverGroups,\n serverGroupWriter,\n });\n };\n\n const resizeServerGroup = () => {\n GceResizeServerGroupModal.show({\n application: app,\n autoscalingPolicyWriter: GceAutoscalingPolicyWriter,\n serverGroup,\n serverGroupWriter,\n });\n };\n\n const destroyServerGroup = () => {\n const confirmationModalParams: any = {\n ...confirmationDefaults,\n buttonText: `Destroy ${serverGroup.name}`,\n header: `Really destroy ${serverGroup.name}?`,\n submitMethod: (params: any) =>\n serverGroupWriter.destroyServerGroup(serverGroup, app, withGcePlatformHealthParams(app, params)),\n taskMonitorConfig: { application: app, title: `Destroying ${serverGroup.name}` },\n };\n ServerGroupWarningMessageService.addDestroyWarningMessage(app, serverGroup, confirmationModalParams);\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n const disableServerGroup = () => {\n const confirmationModalParams: any = {\n ...confirmationDefaults,\n buttonText: `Disable ${serverGroup.name}`,\n header: `Really disable ${serverGroup.name}?`,\n submitMethod: (params: any) =>\n serverGroupWriter.disableServerGroup(serverGroup, app.name, withGcePlatformHealthParams(app, params)),\n taskMonitorConfig: { application: app, title: `Disabling ${serverGroup.name}` },\n };\n ServerGroupWarningMessageService.addDisableWarningMessage(app, serverGroup, confirmationModalParams);\n ConfirmationModalService.confirm(confirmationModalParams);\n };\n\n const enableServerGroup = () => {\n ConfirmationModalService.confirm({\n ...confirmationDefaults,\n buttonText: `Enable ${serverGroup.name}`,\n header: `Really enable ${serverGroup.name}?`,\n submitMethod: (params: any) =>\n serverGroupWriter.enableServerGroup(serverGroup, app, withGcePlatformHealthParams(app, params)),\n taskMonitorConfig: { application: app, title: `Enabling ${serverGroup.name}` },\n });\n };\n\n return (\n <div className=\"dropdown\" id=\"gce-server-group-actions-dropdown\">\n <button className=\"btn btn-sm btn-primary dropdown-toggle\" data-toggle=\"dropdown\" type=\"button\">\n Server Group Actions\n </button>\n <ul className=\"dropdown-menu\">\n {!serverGroup.isDisabled && (\n <ManagedMenuItem resource={serverGroup} application={app} onClick={rollbackServerGroup}>\n Rollback\n </ManagedMenuItem>\n )}\n <ManagedMenuItem resource={serverGroup} application={app} onClick={resizeServerGroup}>\n Resize\n </ManagedMenuItem>\n <li>\n <a onClick={cloneServerGroup}>Clone</a>\n </li>\n {!serverGroup.isDisabled && (\n <li>\n <a onClick={disableServerGroup}>Disable</a>\n </li>\n )}\n {serverGroup.isDisabled && (\n <li>\n <a onClick={enableServerGroup}>Enable</a>\n </li>\n )}\n <li>\n <a onClick={destroyServerGroup}>Destroy</a>\n </li>\n </ul>\n </div>\n );\n}\n\nexport function GceServerGroupInformationSection({ serverGroup }: { app: any; serverGroup: any }): JSX.Element {\n return (\n <CollapsibleSection heading=\"Server Group Information\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Account</dt>\n <dd>\n <AccountTag account={serverGroup.account} />\n </dd>\n <dt>Region</dt>\n <dd>{serverGroup.region}</dd>\n <dt>Network</dt>\n <dd>{serverGroup.network || '-'}</dd>\n <dt>Subnet</dt>\n <dd>{serverGroup.subnet || '-'}</dd>\n </dl>\n </CollapsibleSection>\n );\n}\n\nexport function GceServerGroupCapacitySection({ serverGroup }: { app: any; serverGroup: any }): JSX.Element {\n return (\n <CollapsibleSection heading=\"Capacity\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Desired</dt>\n <dd>{serverGroup.capacity?.desired ?? serverGroup.instances?.length ?? '-'}</dd>\n <dt>Min</dt>\n <dd>{serverGroup.capacity?.min ?? '-'}</dd>\n <dt>Max</dt>\n <dd>{serverGroup.capacity?.max ?? '-'}</dd>\n </dl>\n </CollapsibleSection>\n );\n}\n\ntype ShieldedField = 'enableSecureBoot' | 'enableVtpm' | 'enableIntegrityMonitoring';\n\nfunction shieldedValue(serverGroup: any, field: ShieldedField): boolean | undefined {\n const properties = serverGroup.launchConfig?.instanceTemplate?.properties;\n const stableConfig = serverGroup.shieldedInstanceConfig || properties?.shieldedInstanceConfig;\n const legacyConfig = serverGroup.shieldedVmConfig || properties?.shieldedVmConfig;\n if (Object.prototype.hasOwnProperty.call(stableConfig || {}, field)) {\n return stableConfig[field];\n }\n if (Object.prototype.hasOwnProperty.call(legacyConfig || {}, field)) {\n return legacyConfig[field];\n }\n return serverGroup[field];\n}\n\nexport function GceServerGroupLaunchConfigSection({ serverGroup }: { app: any; serverGroup: any }): JSX.Element {\n const template = serverGroup.launchConfig?.instanceTemplate;\n const shieldedSettings: Array<[string, boolean | undefined]> = [\n ['Secure Boot', shieldedValue(serverGroup, 'enableSecureBoot')],\n ['vTPM', shieldedValue(serverGroup, 'enableVtpm')],\n ['Integrity Monitoring', shieldedValue(serverGroup, 'enableIntegrityMonitoring')],\n ];\n return (\n <CollapsibleSection heading=\"Launch Configuration\" defaultExpanded={true}>\n <dl className=\"dl-horizontal dl-narrow\">\n <dt>Instance Template</dt>\n <dd>{template?.name || '-'}</dd>\n <dt>Zones</dt>\n <dd>{(serverGroup.zones || []).join(', ') || '-'}</dd>\n <dt>Target shape</dt>\n <dd>{serverGroup.distributionPolicy?.targetShape || '-'}</dd>\n {shieldedSettings.map(([label, value]) => (\n <React.Fragment key={label}>\n <dt>{label}</dt>\n <dd>{value === undefined ? '-' : String(value)}</dd>\n </React.Fragment>\n ))}\n <dt>Logs</dt>\n <dd>\n {serverGroup.logsLink ? (\n <a href={serverGroup.logsLink} target=\"_blank\" rel=\"noopener noreferrer\">\n View Google Cloud logs\n </a>\n ) : (\n '-'\n )}\n </dd>\n </dl>\n <GceInstanceFlexibilityPolicyDetails instanceFlexibilityPolicy={serverGroup.instanceFlexibilityPolicy} />\n </CollapsibleSection>\n );\n}\n\nexport function GceAutoscalingPolicySection({\n app,\n serverGroup,\n}: {\n app: Application;\n serverGroup: IGceServerGroup;\n}): JSX.Element {\n return (\n <CollapsibleSection heading=\"Autoscaling\">\n <GceAutoscalingPolicyDetails\n application={app}\n mutationsEnabled={!CloudProviderRegistry.isDisabled('gce')}\n policy={serverGroup.autoscalingPolicy}\n serverGroup={serverGroup}\n />\n </CollapsibleSection>\n );\n}\n\nexport function GceAutoHealingPolicySection({\n app,\n serverGroup,\n}: {\n app: Application;\n serverGroup: IGceServerGroup;\n}): JSX.Element {\n return (\n <CollapsibleSection heading=\"Auto-healing\">\n <GceAutoHealingPolicyDetails\n application={app}\n mutationsEnabled={!CloudProviderRegistry.isDisabled('gce')}\n policy={serverGroup.autoHealingPolicy}\n serverGroup={serverGroup}\n />\n </CollapsibleSection>\n );\n}\n\nexport const gceServerGroupDetailsSections = [\n GceServerGroupInformationSection,\n GceServerGroupCapacitySection,\n GceServerGroupLaunchConfigSection,\n GceAutoscalingPolicySection,\n GceAutoHealingPolicySection,\n];\n","'use strict';\n\nimport { defaults, get } from 'lodash';\n\nimport { GceHttpLoadBalancerUtils } from '../loadBalancer/httpLoadBalancerUtils.service';\n\nexport class GceServerGroupTransformer {\n constructor() {\n const gceHttpLoadBalancerUtils = new GceHttpLoadBalancerUtils();\n function normalizeServerGroup(serverGroup, application) {\n return application\n .getDataSource('loadBalancers')\n .ready()\n .then(() => {\n if (serverGroup.loadBalancers) {\n // At this point, the HTTP(S) load balancers have been normalized (listener names mapped to URL map names).\n // Our server groups' lists of load balancer names still need to make this mapping.\n serverGroup.loadBalancers = gceHttpLoadBalancerUtils.normalizeLoadBalancerNamesForAccount(\n serverGroup.loadBalancers,\n serverGroup.account,\n application.getDataSource('loadBalancers').data,\n );\n }\n return serverGroup;\n });\n }\n\n function getAvailabilityZones(base) {\n if (base.zone) {\n return [base.zone];\n }\n\n return (\n [\n get(base, 'backingData.filtered.truncatedZones'),\n get(base, ['availabilityZones', base.region]),\n get(base, 'distributionPolicy.zones'),\n ].find((zones) => Array.isArray(zones) && zones.length) || []\n );\n }\n\n function convertServerGroupCommandToDeployConfiguration(base) {\n // use defaults to avoid copying the backingData, which is huge and expensive to copy over\n const command = defaults({ backingData: [], viewState: [] }, base);\n if (base.viewState.mode !== 'clone') {\n delete command.source;\n }\n // We took this approach to avoid a breaking change to existing pipelines.\n command.disableTraffic = !command.enableTraffic;\n command.cloudProvider = 'gce';\n command.availabilityZones = {};\n command.availabilityZones[command.region] = getAvailabilityZones(base);\n command.account = command.credentials;\n delete command.viewState;\n delete command.backingData;\n delete command.selectedProvider;\n delete command.implicitSecurityGroups;\n delete command.enableTraffic;\n delete command.providerType;\n delete command.enableAutoHealing;\n delete command.partnerMetadata;\n\n if (command.autoHealingPolicy) {\n command.autoHealingPolicy = ['healthCheck', 'healthCheckKind', 'healthCheckUrl', 'initialDelaySec'].reduce(\n (supportedPolicy, field) => {\n if (command.autoHealingPolicy[field] !== undefined) {\n supportedPolicy[field] = command.autoHealingPolicy[field];\n }\n return supportedPolicy;\n },\n {},\n );\n }\n\n return command;\n }\n\n return {\n convertServerGroupCommandToDeployConfiguration: convertServerGroupCommandToDeployConfiguration,\n normalizeServerGroup: normalizeServerGroup,\n };\n }\n}\n","'use strict';\n\nimport _ from 'lodash';\n\nimport { NetworkReader } from '@spinnaker/core';\n\nexport class GceSubnetRenderer {\n constructor() {\n this.gceNetworks = undefined;\n\n NetworkReader.listNetworksByProvider('gce').then((networks) => {\n this.gceNetworks = networks;\n });\n }\n\n render(serverGroup) {\n if (serverGroup.subnet) {\n return serverGroup.subnet;\n } else {\n const autoCreateSubnets = _.chain(this.gceNetworks)\n .filter({ account: serverGroup.account, name: serverGroup.network })\n .map('autoCreateSubnets')\n .head()\n .value();\n\n return autoCreateSubnets ? '(Auto-select)' : '[none]';\n }\n }\n}\n","import type { IApplicationNameValidator, IValidationResult } from '@spinnaker/core';\nimport { ApplicationNameValidator, FirewallLabels } from '@spinnaker/core';\n\nexport class GoogleApplicationNameValidator implements IApplicationNameValidator {\n private validateSpecialCharacters(name: string, errors: string[]): void {\n const pattern = /^([a-zA-Z][a-zA-Z0-9]*)?$/;\n if (!pattern.test(name)) {\n errors.push(\n 'The application name must begin with a letter and must contain only letters or digits. No ' +\n 'special characters are allowed.',\n );\n }\n }\n\n private validateLength(name: string, warnings: string[], errors: string[]): void {\n const maxResourceNameLength = 63;\n const maxLengthForLoadBalancers = maxResourceNameLength - 17;\n const maxLengthForServerGroups = maxResourceNameLength - 10;\n\n if (name.length > maxResourceNameLength) {\n errors.push('The maximum length for an application in Google is 63 characters.');\n return;\n }\n\n if (name.length > maxLengthForLoadBalancers - 12) {\n if (name.length > maxLengthForLoadBalancers) {\n warnings.push(`You will not be able to create a Google load balancer for this application if the\n application's name is longer than ${maxLengthForLoadBalancers} characters (currently: ${name.length}\n characters).`);\n } else if (name.length >= maxLengthForLoadBalancers - 2) {\n warnings.push(\n 'With separators (\"-\"), you will not be able to include a stack and detail field for ' +\n 'Google load balancers.',\n );\n } else {\n const remaining = maxLengthForLoadBalancers - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google load balancers, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n\n if (name.length > maxLengthForServerGroups - 12) {\n if (name.length > maxLengthForServerGroups) {\n warnings.push(`You will not be able to create a Google server group for this application if the\n application's name is longer than ${maxLengthForServerGroups} characters (currently: ${name.length}\n characters).`);\n } else if (name.length >= maxLengthForServerGroups - 2) {\n warnings.push(\n 'With separators (\"-\"), you will not be able to include a stack and detail field for ' +\n 'Google server groups.',\n );\n } else {\n const remaining = maxLengthForServerGroups - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google server groups, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n\n if (name.length > maxResourceNameLength - 12) {\n if (name.length >= maxResourceNameLength - 2) {\n warnings.push(\n `With separators (\"-\"), you will not be able to include a stack and detail field for Google ${FirewallLabels.get(\n 'firewalls',\n )}.`,\n );\n } else {\n const remaining = maxResourceNameLength - 2 - name.length;\n warnings.push(`If you plan to include a stack or detail field for Google ${FirewallLabels.get(\n 'firewalls',\n )}, you will only\n have ~${remaining} characters to do so.`);\n }\n }\n }\n\n public validate(name = ''): IValidationResult {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n if (name.length) {\n this.validateSpecialCharacters(name, errors);\n this.validateLength(name, warnings, errors);\n }\n\n return { warnings, errors };\n }\n}\n\nApplicationNameValidator.registerValidator('gce', new GoogleApplicationNameValidator());\n","import { CloudProviderRegistry, DeploymentStrategyRegistry, Registry } from '@spinnaker/core';\n\nimport { GceCacheConfigurer } from './cache/cacheConfigurer.service';\nimport './help/gce.help';\nimport { GceImageReader } from './image';\nimport { GceInstanceDetails } from './instance/details/GceInstanceDetails';\nimport { GceInstanceTypeService } from './instance/gceInstanceType.service';\nimport { GceMultiInstanceTaskTransformer } from './instance/gceMultiInstanceTask.transformer';\nimport { GceLoadBalancerChoiceModal } from './loadBalancer/configure/choice/GceLoadBalancerChoiceModal';\nimport {\n GceLoadBalancerActions,\n gceLoadBalancerDetailsSections,\n useGceLoadBalancerDetails,\n} from './loadBalancer/details/gceLoadBalancerDetails';\nimport { GceLoadBalancerSetTransformer } from './loadBalancer/loadBalancer.setTransformer';\nimport { GceLoadBalancerTransformer } from './loadBalancer/loadBalancer.transformer';\nimport logo from './logo/gce.logo.png';\nimport { registerGceBakeStage } from './pipeline/stages/bake/gceBakeStage';\nimport { registerGceCloneServerGroupStage } from './pipeline/stages/cloneServerGroup/gceCloneServerGroupStage';\nimport { registerGceDestroyAsgStage } from './pipeline/stages/destroyAsg/gceDestroyAsgStage';\nimport { registerGceDisableAsgStage } from './pipeline/stages/disableAsg/gceDisableAsgStage';\nimport { registerGceDisableClusterStage } from './pipeline/stages/disableCluster/gceDisableClusterStage';\nimport { registerGceEnableAsgStage } from './pipeline/stages/enableAsg/gceEnableAsgStage';\nimport { registerGceFindAmiStage } from './pipeline/stages/findAmi/gceFindAmiStage';\nimport { registerGceFindImageFromTagsStage } from './pipeline/stages/findImageFromTags/gceFindImageFromTagsStage';\nimport { registerGceResizeAsgStage } from './pipeline/stages/resizeAsg/gceResizeAsgStage';\nimport { registerGceScaleDownClusterStage } from './pipeline/stages/scaleDownCluster/gceScaleDownClusterStage';\nimport { registerGceShrinkClusterStage } from './pipeline/stages/shrinkCluster/gceShrinkClusterStage';\nimport { registerGceTagImageStage } from './pipeline/stages/tagImage/gceTagImageStage';\nimport { GceSecurityGroupModal } from './securityGroup/configure/GceSecurityGroupModal';\nimport { GceSecurityGroupDetails } from './securityGroup/details/GceSecurityGroupDetails';\nimport { GceSecurityGroupReader } from './securityGroup/securityGroup.reader';\nimport { GceSecurityGroupTransformer } from './securityGroup/securityGroup.transformer';\nimport { GceServerGroupCommandBuilder } from './serverGroup/configure/serverGroupCommandBuilder.service';\nimport { GceServerGroupConfigurationService } from './serverGroup/configure/serverGroupConfiguration.service';\nimport { GceCloneServerGroupModal } from './serverGroup/configure/wizard/GceCloneServerGroupModal';\nimport { GceCustomInstanceBuilder } from './serverGroup/configure/wizard/customInstance/GceCustomInstanceBuilder';\nimport {\n GceServerGroupActions,\n gceServerGroupDetailsGetter,\n gceServerGroupDetailsSections,\n} from './serverGroup/details/gceServerGroupDetails';\nimport { GceServerGroupTransformer } from './serverGroup/serverGroup.transformer';\nimport { GceSubnetRenderer } from './subnet/subnet.renderer';\nimport './validation/ApplicationNameValidator';\n\nimport './logo/gce.logo.less';\n\nexport function registerGoogleProvider(): void {\n CloudProviderRegistry.registerProvider('gce', {\n name: 'Google',\n logo: {\n path: logo,\n },\n applicationProviderFields: [\n {\n field: 'associatePublicIpAddress',\n helpKey: 'gce.serverGroup.associatePublicIpAddress.providerField',\n label: 'Associate Public IP Address',\n type: 'boolean',\n },\n ],\n cache: {\n configurer: GceCacheConfigurer,\n },\n image: {\n reader: GceImageReader,\n },\n serverGroup: {\n transformer: GceServerGroupTransformer,\n commandBuilder: GceServerGroupCommandBuilder,\n configurationService: GceServerGroupConfigurationService,\n CloneServerGroupModal: GceCloneServerGroupModal,\n detailsActions: GceServerGroupActions,\n detailsGetter: gceServerGroupDetailsGetter,\n detailsSections: gceServerGroupDetailsSections,\n },\n instance: {\n CustomInstanceBuilder: GceCustomInstanceBuilder,\n details: GceInstanceDetails,\n instanceTypeService: GceInstanceTypeService,\n multiInstanceTaskTransformer: GceMultiInstanceTaskTransformer,\n },\n loadBalancer: {\n CreateLoadBalancerModal: GceLoadBalancerChoiceModal,\n pipelineCreateLoadBalancerModal: (props: any) =>\n GceLoadBalancerChoiceModal.show({ ...props, app: props.application, forPipelineConfig: true }),\n detailsActions: GceLoadBalancerActions,\n detailsSections: gceLoadBalancerDetailsSections,\n transformer: GceLoadBalancerTransformer,\n setTransformer: GceLoadBalancerSetTransformer,\n useDetailsHook: useGceLoadBalancerDetails,\n },\n securityGroup: {\n CreateSecurityGroupModal: GceSecurityGroupModal,\n details: GceSecurityGroupDetails,\n transformer: GceSecurityGroupTransformer,\n reader: GceSecurityGroupReader,\n },\n subnet: {\n renderer: GceSubnetRenderer,\n },\n snapshotsEnabled: true,\n });\n}\n\nregisterGoogleProvider();\n\nfunction registerPipelineStageOnce(stageKey: string, registerStage: () => void): void {\n const isRegistered = Registry.pipeline.getStageTypes().some((stage) => {\n const registeredStageKey = stage.provides || stage.key;\n return registeredStageKey === stageKey && stage.cloudProvider === 'gce';\n });\n\n if (!isRegistered) {\n registerStage();\n }\n}\n\nexport function registerGooglePipelineStages(): void {\n registerPipelineStageOnce('bake', registerGceBakeStage);\n registerPipelineStageOnce('cloneServerGroup', registerGceCloneServerGroupStage);\n registerPipelineStageOnce('destroyServerGroup', registerGceDestroyAsgStage);\n registerPipelineStageOnce('disableServerGroup', registerGceDisableAsgStage);\n registerPipelineStageOnce('disableCluster', registerGceDisableClusterStage);\n registerPipelineStageOnce('enableServerGroup', registerGceEnableAsgStage);\n registerPipelineStageOnce('findImage', registerGceFindAmiStage);\n registerPipelineStageOnce('findImageFromTags', registerGceFindImageFromTagsStage);\n registerPipelineStageOnce('resizeServerGroup', registerGceResizeAsgStage);\n registerPipelineStageOnce('scaleDownCluster', registerGceScaleDownClusterStage);\n registerPipelineStageOnce('shrinkCluster', registerGceShrinkClusterStage);\n registerPipelineStageOnce('upsertImageTags', registerGceTagImageStage);\n}\n\nregisterGooglePipelineStages();\n\nDeploymentStrategyRegistry.registerProvider('gce', ['custom', 'redblack']);\n"],"names":["GceCertificateReader","listCertificates","SearchService","search","q","type","allowShortQuery","InfrastructureCaches","get","then","searchResults","results","filter","certificate","provider","catch","GceHealthCheckReader","listHealthChecks","this","healthChecks","healthCheck","healthCheckType","result","map","JSON","parse","account","uniqWith","checkA","checkB","name","GceCacheConfigurer","constructor","gceCertificateReader","gceHealthCheckReader","config","Object","create","addresses","initializers","address","region","backendServices","REST","useCache","query","certificates","helpContents","keys","forEach","key","HelpContentsRegistry","register","GceImageReader","findImages","params","getImage","Promise","resolve","React","Component","GceXpnNamingService","__publicField","resourceWithSelfLink","pathSegments","selfLink","split","indexOf","projectId","xpnResource","xpnResourcePathSegments","xpnResourceProjectId","xpnResourceName","_","last","hasHealthState","instance","state","health","some","getNetworkLoadBalancerNames","app","_a","loadBalancers","length","data","loadBalancer","loadBalancerType","includes","GceInstanceActionsComponent","stateService","closeIfCurrentInstance","instanceId","go","confirm","header","buttonText","title","submitMethod","closeOnComplete","ConfirmationModalService","askForReason","taskMonitorConfig","application","onTaskComplete","networkLoadBalancerNames","loadBalancerInstance","loadBalancerNames","join","actions","canRegisterWithDiscovery","push","label","triggerAction","InstanceWriter","enableInstanceInDiscovery","disableInstanceInDiscovery","canRegisterWithLoadBalancer","registerInstanceWithLoadBalancer","deregisterInstanceFromLoadBalancer","rebootInstance","interestingHealthProviderNames","terminateInstance","cloudProvider","serverGroup","managedInstanceGroupName","terminateInstanceAndShrinkServerGroup","instanceIds","serverGroupName","zone","placement","availabilityZone","createElement","InstanceActions","withRouter","GceInstanceDetails","props","setInstance","useState","initialInstance","loading","setLoading","notFound","setNotFound","useLayoutEffect","cancelled","stateParams","$stateParams","accountId","id","getInstanceParams","summary","_b","serverGroups","instances","find","candidate","vpcId","isDisabled","disabledSummary","serverGroupDisabled","findInstanceSummary","RecentHistoryService","addExtraDataToLatest","InstanceReader","getInstanceDetails","details","_c","_d","xpnNaming","networkInterface","networkInterfaces","project","match","exec","projectFromSelfLink","network","decorateXpnResourceIfNecessary","subnet","subnetwork","externalIpAddress","accessConfigs","natIP","internalIpAddress","networkIP","sshLink","replace","baseIpAddress","gcloudSSHCommand","internalDnsName","logsLink","encodeURIComponent","decorateInstance","className","Details","Fragment","Header","icon","router","Content","CollapsibleSection","heading","defaultExpanded","AccountTag","machineType","instanceType","href","target","rel","GCE_INSTANCE_TYPE_DISK_DEFAULTS","freeze","disks","sizeGb","supportsLocalSSD","GceInstanceTypeService","promiseService","logger","console","categories","families","description","storageType","storageHelpFieldKey","instanceTypes","cpu","memory","costFactor","nameRegex","storage","localSSDSupported","getCategories","memoize","initializedCategories","cloneDeep","AccountService","getAllAccountDetailsForProvider","accountDetails","instanceTypeDisks","isEmpty","flatten","category","family","diskDefaults","instanceTypeDisk","disk","warn","size","count","persistentDisks","startsWith","reduce","maxSizeGb","Math","max","defaultSettings","getAvailableTypesForLocations","locationToInstanceTypesMap","selectedLocations","error","location","flatMap","getAvailableTypesForRegions","getAllTypesByRegion","chain","value","resolveInstanceTypeDetails","assign","isDefault","SETTINGS","providers","gce","defaults","instanceTypeStorage","transformers","rebootInstances","job","GceMultiInstanceTaskTransformer","instanceGroup","transformAll","EMPTY_DATA","accounts","networks","regions","subnets","GceLoadBalancerDataController","readers","gceLoadBalancerDataReaders","disposed","listeners","Set","requestId","status","getState","subscribe","listener","add","delete","load","publish","all","isCurrent","dispose","clear","mergeGceResourceOptions","available","persisted","availableNames","has","certificateReader","healthCheckReader","listAccounts","getRegionsForAccount","Array","isArray","NetworkReader","listNetworksByProvider","SubnetReader","listSubnetsByProvider","normalizeBackendServiceResults","response","first","GCE_LOAD_BALANCER_TYPES","GCE_LOAD_BALANCER_CAPABILITIES","NETWORK","capabilities","INTERNAL","TCP","SSL","HTTP","hostRules","INTERNAL_MANAGED","normalizeGceLoadBalancerCommand","mode","normalized","asString","toUpperCase","normalizeLoadBalancerType","isHttpType","urlMapName","loadBalancerName","topLevelListener","ipAddress","portRange","ports","protocol","ipProtocol","asArray","candidates","backendService","defaultService","hostRuleValue","pathMatcher","asRecord","pathRules","pathRuleValue","services","Map","service","normalizeReference","healthCheckLink","normalizeBackendService","set","from","values","collectBackendServices","index","normalizeGceHealthCheck","collectHealthChecks","command","credentials","fallbackName","normalizeProtocol","certificateMap","Number","port","normalizePortRange","normalizeListener","hostRule","hostPatterns","asStringArray","pathRule","rule","paths","normalizeHostRule","original","cloneValue","serializeGceLoadBalancerCommand","capabilitiesForType","serialized","currentListener","serializeReservedAddress","serializeCertificateName","serializeSubnetName","serializeListener","serializeBackendService","serializeHostRule","serializeBackendServiceName","reference","serializeNetworkName","overrides","field","requestPath","Boolean","pop","serializeHealthCheckName","String","fromEntries","entries","item","GCE_PROXY_TYPE_CONFIG","frontendProtocols","backendProtocols","PROXY_PORTS","HEALTH_CHECK_PROTOCOLS","PROXY_SESSION_AFFINITIES","INTERNAL_SESSION_AFFINITIES","applyGceProxyTypeConstraints","originalListener","frontendProtocol","originalBackend","backendProtocol","portName","sessionAffinity","affinityCookieTtlSec","validateGceProxyLoadBalancerCommand","errors","backend","trim","validPort","negative","connectionDrainingTimeoutSec","min","number","isFinite","numberInRange","timeoutSec","checkIntervalSec","healthyThreshold","unhealthyThreshold","GceProxyLoadBalancerEditor","disabled","onChange","_e","constrained","options","accountScoped","items","locationScoped","networkName","subnetScoped","itemNetwork","references","getGceProxyResourceOptions","sessionAffinities","update","updates","updateListener","updateBackend","updateHealthCheck","textField","selectField","selectedResource","numberField","healthCheckOption","healthCheckReference","event","allowCustomValue","names","referenceValue","option","isInteger","serializeGceProxyLoadBalancerCommand","backendSource","GceProxyLoadBalancerModalComponent","forPipelineConfig","isNew","resolveProxyType","setCommand","applicationName","source","nestedHealthCheck","normalizeGceProxyLoadBalancerCommand","dataState","controllerRef","useRef","current","controller","setState","useEffect","unsubscribe","refresh","useGceLoadBalancerData","applicationRefreshUnsubscribe","isUnmounted","taskMonitor","TaskMonitor","onDismiss","dismissModal","call","clearCache","getDataSource","close","closeModal","onNextRefresh","submitting","TaskMonitorWrapper","monitor","ModalClose","dismiss","Spinner","onClick","SubmitButton","isFormSubmit","payload","descriptor","submit","LoadBalancerWriter","upsertLoadBalancer","submitGceProxyLoadBalancerCommand","GceProxyLoadBalancerModal","show","ReactModal","dialogClassName","supportsPipelineConfig","selectedReference","GceHttpLoadBalancerListenerEditor","onRemove","required","numberValue","GceHttpLoadBalancerHealthCheckEditor","updateNumber","selected","grpcServiceName","GceHttpLoadBalancerBackendServiceEditor","affinity","checked","enableCDN","parseList","GceHttpLoadBalancerPathRuleEditor","GceHttpLoadBalancerHostRuleEditor","updated","currentIndex","resolveBackendService","submitGceLoadBalancerCommand","executeTask","TaskExecutor","jobs","_backendServices","_healthChecks","_hostRules","shared","hostPattern","listenerNames","currentBackendServices","listenersToDelete","backendServiceDiff","isEqual","buildGceLoadBalancerJobs","styleInject","css","ref","insertAt","document","head","getElementsByTagName","style","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","FormRow","children","uniqueOptions","findIndex","constrainGceHttpLoadBalancerCommand","constrainListener","keepSubnet","_certificate","plaintextListener","validateGceHttpLoadBalancerCommand","internal","minimum","maximum","text","test","GceHttpLoadBalancerEditor","accountMatches","locationMatches","selectedNetwork","networkId","hostBackendServices","backendHealthChecks","buildGceHttpLoadBalancerOptions","editing","updateRouting","maxLength","selectedHealthCheck","updateBackendService","_GceHttpLoadBalancerModal","super","updateCommand","accountChanged","dataController","dependencies","initializeGceHttpLoadBalancerCommand","componentDidMount","dataReaders","componentWillUnmount","render","validationErrors","GceHttpLoadBalancerModal","SESSION_AFFINITIES","PROTOCOLS","validateGceNetworkLoadBalancerCommand","start","end","validPortRange","GceNetworkLoadBalancerEditor","buildGceNetworkLoadBalancerOptions","targetPool","GCEProviderSettings","feature","resetToOriginal","resetProvider","submitGceNetworkLoadBalancerCommand","serializeHealthCheck","serializeGceNetworkLoadBalancerCommand","GceNetworkLoadBalancerModalComponent","persistedLoadBalancer","elb","listenerDescriptions","sourceDetails","loadBalancerPort","hasHealthCheck","prototype","hasOwnProperty","persistedHealthChecks","normalizeHealthCheckInput","normalizeSessionAffinity","normalizeGceNetworkLoadBalancerCommand","GceNetworkLoadBalancerModal","numberOrUndefined","GCE_LOAD_BALANCER_CHOICES","getGceLoadBalancerModal","_GceLoadBalancerChoiceModal","arguments","selectedChoice","isBlockedEdit","choiceSelected","choose","modalProps","getLoadBalancerType","blocked","persistedType","persistedTypeLabel","role","choice","defaultProps","noop","GceLoadBalancerChoiceModal","GceHttpLoadBalancerUtils","isHttpLoadBalancer","lb","normalizeLoadBalancerNamesForAccount","normalizedLoadBalancerNames","matchingUrlMap","uniq","REGION","gceHttpLoadBalancerUtils","uniqBy","getKey","seen","getProtocol","async","loadGceLoadBalancerDetails","accountService","autoClose","loadBalancerParams","loadBalancerReader","vpcid","isSameVpc","findLoadBalancerInList","detailSets","getLoadBalancerDetails","concat","representativeLoadBalancer","dns","detail","dnsname","loadDetails","filtered","getBackendServices","getAccountDetails","getResourceTypes","buildLogsLink","useGceLoadBalancerDetails","useDeckRuntimeServices","dataSource","loaded","useDataSource","setData","loadingDetails","setLoadingDetails","detailsError","setDetailsError","refetch","useCallback","e","message","deleteGceLoadBalancer","deleteGceHttpLoadBalancer","deleteLoadBalancer","accountName","deleteHealthChecks","GceLoadBalancerDeleteOptions","deleteParams","currentTarget","GceLoadBalancerActions","CloudProviderRegistry","hasInstances","ManagedMenuItem","resource","bodyContent","gceLoadBalancerDetailsSections","providerType","GceLoadBalancerSetTransformer","normalizeLoadBalancerSet","httpLoadBalancers","otherLoadBalancers","partition","groupedByUrlMap","groupBy","normalizeHttpLoadBalancerGroup","group","parsePortRange","GceLoadBalancerTransformer","updateHealthCounts","container","instanceCounts","up","down","outOfService","acc","healthState","normalizeLoadBalancer","detachedInstances","transformInstance","activeServerGroups","timeout","interval","convertLoadBalancerForEditing","toEdit","regionZones","availabilityZones","healthTimeout","healthInterval","protocolIndex","pathIndex","healthCheckProtocol","substring","healthCheckPort","healthCheckPath","isNaN","constructNewLoadBalancerTemplate","stack","h","updateStage","stage","changes","showAdvanced","templateFileName","extendedAttributes","varFileName","baseAmi","GceBakeStageConfig","baseLabelOptions","baseOsOptions","roscoMode","showAdvancedOptions","user","AuthenticationService","getAuthenticatedUser","BakeryReader","getBaseOsOptions","getBaseLabelOptions","baseImages","baseOs","baseLabel","roscoSelector","renderArtifactSelector","pipeline","expectedArtifacts","ExpectedArtifactService","getExpectedArtifactsAvailableToStage","packageArtifactIds","StageConfigField","multiple","selectedOptions","artifact","displayName","renderAdvancedOptions","MapEditor","allowEmpty","model","package","shortDescription","rebake","marginBottom","interpolatedBakeDetailUrl","context","template","roscoDetailUrl","bakeryDetailUrl","_match","path","valueForPath","GceBakeExecutionDetails","execution","bakeDetailUrl","ExecutionDetailsSection","ami","trigger","StageFailureMessage","failureMessage","resourceId","isFailed","previouslyBaked","imageName","registerGceBakeStage","Registry","registerStage","provides","component","executionDetailsSections","ExecutionDetailsTasks","ExecutionArtifactTab","executionLabelComponent","BakeExecutionLabel","extraLabelLines","masterStage","allPreviouslyBaked","somePreviouslyBaked","producesArtifacts","supportsCustomTimeout","validators","fields","fieldName","fieldLabel","restartable","artifactExtractor","accumulateArtifacts","artifactRemover","ArtifactReferenceService","removeArtifactFromFields","gceSelectionStrategies","val","scaleActions","resizeTypes","setDefault","initializeGceStage","defaultCredentials","defaultRegions","attributes","platformHealthOnlyShowOverride","platformHealthOnly","replaceStage","NumberInput","parseNumber","SelectInput","InlineSelectInput","CapacityFields","capacity","updateCapacity","desired","GcePlatformHealthOverride","GceBaseStageConfig","renderAccountRegionClusterSelector","strategy","AccountRegionClusterSelector","clusterField","singleRegion","renderTargetSelect","StageConstants","TARGET_LIST","TargetSelect","renderDeploymentStrategySelector","DeploymentStrategySelector","fieldColumns","onFieldChange","onStrategyChange","GceTargetServerGroupStageConfig","showHealthOverride","nextStage","GceDisableAsgStageConfig","GceEnableAsgStageConfig","GceCloneServerGroupStageConfig","targetCluster","clusterName","NameUtils","parseServerGroupName","freeFormDetails","syncTargetClusterFields","useSourceCapacity","disableTraffic","GceFindImageStageConfig","selectionStrategy","onlyEnabled","GceResizeServerGroupStageConfig","action","resizeType","updateResize","scalePct","scaleNum","normalizeResizeStage","GceClusterCapacityStageConfig","activeToggleField","activeToggleLabel","defaultValue","preferenceField","preferenceLabel","toString","display","width","pluralize","GceDisableClusterStageConfig","GceScaleDownClusterStageConfig","GceShrinkClusterStageConfig","registerGceCloneServerGroupStage","registerGceDestroyAsgStage","accountExtractor","configAccountExtractor","registerGceDisableAsgStage","registerGceDisableClusterStage","registerGceEnableAsgStage","registerGceFindAmiStage","GceFindImageFromTagsStageConfig","tags","packageName","Tags","separator","GceFindImageFromTagsExecutionDetails","images","amiDetails","image","registerGceFindImageFromTagsStage","registerGceResizeAsgStage","registerGceScaleDownClusterStage","registerGceShrinkClusterStage","toggleConsideredStage","refId","consideredStages","GceTagImageStageConfig","imageProducingStages","PipelineConfigService","getAllUpstreamDependencies","upstreamStage","IMAGE_PRODUCING_STAGES","GceTagImageExecutionDetails","targets","stages","stageName","registerGceTagImageStage","PORT_PROTOCOLS","endsWith","slice","sourceRangesFrom","securityGroup","ipRangeRuleCidrs","ipRangeRules","ip","range","cidr","sourceRanges","startPort","endPort","ingressRulesFrom","ipIngress","rules","ipIngressRules","inboundRules","allowed","IPProtocol","portRanges","accountFor","normalizedCoordinate","toLowerCase","initializeGceSecurityGroupForModal","sourceTags","targetTags","GceSecurityGroupModalComponent","mounted","_f","securityGroups","getApplication","getMode","showNewSecurityGroup","clearApplicationRefreshSubscription","refreshResult","updateSecurityGroup","updateRule","addRule","removeRule","_rule","ruleIndex","serializedRule","SecurityGroupWriter","upsertSecurityGroup","securityGroupInventoryLoaded","FirewallLabels","runtimeServices","GceSecurityGroupModal","securityGroupReader","getAllSecurityGroups","securityGroupInventory","securityGroupValidationError","isValid","nameIsAvailable","accountInventoryKey","inventoryAccount","global","existingSecurityGroup","isDuplicateSecurityGroupName","every","renderTextField","readOnly","renderRules","contextType","DeckRuntimeContext","GceSecurityGroupActions","resolvedSecurityGroup","menuOpen","setMenuOpen","firewall","withResolvedCoordinates","sharedVpcHostFirewall","readOnlyExplanation","deleteSecurityGroup","securityGroupName","GceSecurityGroupDetails","routeKey","securityGroupCoordinatesKey","loadedSecurityGroup","setLoadedSecurityGroup","loadSecurityGroup","getSecurityGroupDetails","unsubscribeFromRefresh","onRefresh","GceSecurityGroupReader","resolveIndexedSecurityGroup","indexedSecurityGroups","securityGroupId","GceSecurityGroupTransformer","normalizeSecurityGroup","parseHealthCheckUrl","url","healthCheckPathParts","Error","healthCheckName","healthCheckKind","getHealthCheckOptions","duplicateNames","allNames","hc","getDuplicateHealthCheckNames","kind","GceCustomInstanceBuilderService","vCpuCountForLocationIsValid","instanceFamily","vCpuCount","vCpuMax","numberOfVCpusIsValid","generateValidVCpuListForLocation","generateValidInstanceFamilyList","x","minMemoryForVCpuCount","ceil","maxMemoryForVCpuCount","generateValidMemoryListForVCpuCount","memoryIsValid","totalMemory","extendedMemory","inRange","generateInstanceTypeString","extendedFlag","memoryInMbs","parseInstanceTypeString","instanceTypeString","takeRight","customInstanceChoicesAreValid","GCE_SERVER_GROUP_HIDDEN_METADATA_KEYS","GceServerGroupCommandBuilder","instanceTypeService","gceCustomInstanceBuilderService","gceXpnNamingService","gceServerGroupHiddenMetadataKeys","extractNetworkName","deriveProjectId","launchConfig","instanceTemplate","networkUrl","extractSubnetName","subnetworkUrl","determineAssociatePublicIPAddress","loadBalancerMetadataValues","extractLoadBalancerMetadata","metadata","loadBalancerMetadata","property","getLocalSSDDisks","getPersistentDisks","calculateOverriddenStorageDescription","instanceTypeDetails","viewState","overriddenStorageDescription","diskCountBySizeGb","sort","sizeA","sizeB","calculatePersistentDiskOverriddenStorageDescription","populateAutoHealingPolicy","autoHealingPolicy","healthCheckUrl","initialDelaySec","populateShieldedVmConfig","shieldedInstanceConfig","shieldedVmConfig","populateCustomMetadata","metadataItems","customUserData","customUserDataKeys","customUserDataItem","metadataItem","getCustomUserDataKeys","userData","instanceMetadata","omit","labels","userDataItem","customUserDataKey","populateTags","instanceTemplateTags","tag","populateResourceManagerTags","instanceTemplateResourceManagerTags","resourceManagerTags","buildNewServerGroupCommand","defaultRegion","defaultZone","associatePublicIpAddress","providerSettings","regional","selectZones","distributionPolicy","zones","canIpForward","backendServiceMetadata","minCpuPlatform","imageSource","enableSecureBoot","enableVtpm","enableIntegrityMonitoring","preemptible","automaticRestart","onHostMaintenance","serviceAccountEmail","authScopes","enableTraffic","selectedProvider","instanceProfile","allImageSelection","useSimpleCapacity","usePreferredZones","listImplicitSecurityGroups","disableStrategySelection","gceAccounts","gceAccountNames","firstGCEAccount","defaultCredentialsAreValid","attemptToSetValidCredentials","buildNewServerGroupCommandForPipeline","currentStage","requiresTemplateSelection","buildServerGroupCommandFromExisting","moniker","autoscalingPolicy","asg","loadBalancingPolicy","minSize","maxSize","desiredCapacity","targetShape","instanceFlexibilityPolicy","asgName","customInstance","imageId","determineInstanceCategoryFromInstanceType","scheduling","populateAvailabilityPolicies","properties","instanceTemplateLabels","populateLabels","serviceAccounts","email","scopes","authScope","populateAuthScopes","localSSDDisks","initializeParams","diskType","diskSizeGb","sourceImage","getInstanceTypeDetails","populateDisksFromExisting","buildServerGroupCommandFromPipeline","originalCluster","pipelineCluster","instanceTypeCategoryLoader","getCategoryForInstanceType","commandOptions","disableImageSelection","showImageSourceSelector","submitButtonLabel","templatingEnabled","viewOverrides","extendedCommand","partnerMetadata","populateDisksFromPipeline","GceAcceleratorService","getAvailableAccelerators","backingData","acceleratorMap","getZoneToAcceleratorTypesMap","getAcceleratorTypesForZone","allZonesAcceleratorTypes","z","intersectionBy","apply","a","availableCardCounts","getAvailableCardCounts","accelerator","maxCards","maximumCardsPerInstance","i","GceTagManager","resetKeys","reset","securityGroupObjects","initializeSecurityGroupObjects","byTag","bySecurityGroupId","groupSecurityGroupObjects","securityGroupObjectsKeyedByTag","securityGroupObjectsKeyedById","inferSecurityGroupIdsFromTags","commandTags","t","compact","sg","rawTags","tagsArray","selectedTags","intersection","groupings","inferSelectedSecurityGroupFromTag","debounce","tagName","securityGroupObjectsWithTag","c","updateSelectedTagsOnSecurityGroupObjects","updateSelectedSecurityGroups","getSecurityGroupObjectsFromIds","updateSelectedTags","without","addTag","ids","newTag","oldGroups","newGroups","removeTag","securityGroupIds","removeSecurityGroup","securityGroupObject","tagsToRemove","difference","getToolTipContent","groups","groupIds","showToolTip","GCE_DISTRIBUTION_POLICY_TARGET_SHAPES","GceServerGroupConfigurationService","gceInstanceTypeService","gceTagManager","gceLoadBalancerSetTransformer","persistentDiskTypes","configureDistributionPolicyTargetShape","credentialsKeyedByAccount","configureInstanceTypes","dirty","configureCustomInstanceTypes","locations","l","tokenizedInstanceTypes","tokens","class","sortedTokenizedInstanceTypes","sortBy","sortedTokenizedInstanceType","sortInstanceTypes","configureStandardInstanceTypes","configureCpuPlatforms","filteredData","locationToCpuPlatformsMap","cpuPlatforms","configureAccelerators","acceleratorTypes","chosenAccelerators","acceleratorConfigs","chosen","acceleratorType","configureImages","lastImageAccount","allImages","configureZones","truncatedZones","getHealthChecks","configureHealthChecks","isRelevantLoadBalancer","configureLoadBalancerOptions","newLoadBalancerObjects","flattenDeep","curry","getLoadBalancers","loadBalancerIndex","keyBy","matched","removed","xor","backendsFromMetadata","lbIndex","lbName","configureBackendServiceOptions","refreshHealthChecks","skipCommandReconfiguration","configureSubnets","getSecurityGroups","newSecurityGroups","configureSecurityGroupOptions","currentOptions","currentGroupNames","groupId","matchedGroups","groupName","implicitSecurityGroups","xpnHostProject","decoratedSecurityGroups","refreshSecurityGroups","getNetworkNames","configureCommand","getCredentialsKeyedByAccount","listLoadBalancers","securityGroupReloader","networkReloader","healthCheckReloader","distributionPolicyTargetShapes","gceNetworks","refreshNetworks","autoScalingPolicy","enableAutoScaling","enableAutoHealing","cmd","regionalChanged","regionChanged","credentialsChanged","networkChanged","autoCreateSubnets","zoneChanged","selectZonesChanged","customInstanceChanged","refreshLoadBalancers","refreshInstanceTypes","preservePersistedReference","persistedValue","getValue","createOption","unresolved","validateGceServerGroupCommand","_g","_h","_i","EMPTY_UPDATE_RESULT","GceServerGroupWizardAdapter","commandBuilder","configurationService","nextCommand","applyCommandHandler","handler","applyUpdate","applyConfigurationUpdate","method","applyConfigurationRefresh","processCommandUpdateResult","createGceServerGroupWizardCommandState","fieldOrigins","formikValues","requestGeneration","GceServerGroupWizardPage","commandState","formik","adapter","validate","_values","runLatestCommandRequest","requestedCommand","request","pageGeneration","syncFormikValues","commandGeneration","requestCommand","mergeCommandChanges","generation","onLoadingChanged","currentCommand","mergedCommand","setValues","base","changed","incomingOrigin","markMatchingChanges","mergeValueChanges","recordChangedOrigins","isPlainObject","baseObject","currentObject","childPath","incomingWinsConflict","recordFieldOrigin","currentOrigin","origin","fieldOriginKey","findFieldOrigin","descendantPrefix","originKey","optionsWithPersistedValue","hasEmptyKey","hasEmptyValue","isPipelineMode","isExpression","parseNumericOrExpression","isValidInteger","MAX_SAFE_INTEGER","numericValue","getLocalSsds","renderValidationError","AdvancedSettings","setField","setFieldValue","updateDisk","diskIndex","removeDisk","_disk","updateLocalSsdCount","localSsds","updateAccelerator","accelerators","acceleratorIndex","removeAccelerator","_accelerator","updateTag","tagIndex","_tag","removeAuthScope","_scope","scopeIndex","setPreemptible","acceleratorCount","isValidAccelerator","scope","enableConfidentialCompute","confidentialInstanceType","booleanRadios","confidentialSettingsSupported","pipelineMode","HelpField","platform","htmlFor","diskTypes","colSpan","selectedType","typeNames","counts","rows","addButtonLabel","keyLabel","valueLabel","confidentialInstanceTypes","list","GceServerGroupFirewalls","firewallsChanged","unique","removedTags","scopedFirewalls","selectedFirewallIds","reconcile","targetTagChanged","explicitFirewalls","uniqueTags","selectedTagNames","currentlySelected","unavailable","targetTag","latestCommand","preserveFirewallSelection","showImplicitChanged","showImplicit","refreshFirewalls","selectedIds","explicit","implicit","availableIds","firewallOptions","selectedKnownFirewalls","parts","controlId","raw","byId","existing","parseTargetTags","left","right","localeCompare","byValue","HTTP_BALANCING_MODES","CONNECTION_BALANCING_MODES","MODE_LIMIT_FIELDS","DEFAULT_LOAD_BALANCING_POLICY","balancingMode","capacityScaler","maxUtilization","namedPorts","policyErrorId","renderPolicyError","GceServerGroupLoadBalancers","handleLoadBalancersChanged","uniqueStrings","previouslySelected","mappings","reconcileLoadBalancerMetadata","flat","balancingModes","getBalancingModes","policy","namedPort","reconcileLoadBalancingPolicy","applyPageUpdate","handleBackendServicesChanged","handleBalancingModeChanged","updatePolicy","handleNamedPortChanged","namedPortIndex","handleAddNamedPort","handleRemoveNamedPort","_namedPort","handlePolicyFieldChanged","handleRefresh","selectedLoadBalancers","policyErrors","isValidBoundedValue","namedPortErrors","namedPortError","hasNumericValue","isValidMinimum","maxRatePerInstance","maxConnectionsPerInstance","selectedReferences","availableLoadBalancers","preserveReferences","rawLoadBalancers","uniqueLoadBalancers","isLoadBalancerInRegion","toLoadBalancerOption","filteredLoadBalancers","getAvailableLoadBalancers","renderBackendServiceSelector","renderNamedPorts","renderPercentageInput","renderNumberInput","availableBackendServices","getBackendServiceData","selectedBackendServices","preserveStringReferences","nameErrorId","portErrorId","parseNumericValue","errorId","parsePercentageValue","toPercentageValue","preservedFields","mergeConfiguredBackendServices","getLoadBalancerIndex","configurationCommand","byName","modeSets","persistedMode","modes","nextModes","nextLoadBalancers","copy","getLoadBalancerMetadataReference","availableValues","persistedValues","GceAutoHealingPolicyEditor","loadHealthChecks","reader","normalizeHealthCheck","getHealthCheckUrl","matches","GcePredictiveMethod","policyJob","supportedAutoHealingPolicy","supported","GceAutoscalingPolicyWriter","upsertAutoscalingPolicy","deleteAutoscalingPolicy","upsertAutoHealingPolicy","deleteAutoHealingPolicy","timezones","percentValue","GceAutoscalingPolicyEditor","predictiveAutoscalingEnabled","predictiveAutoscaling","customMetrics","customMetricUtilizations","schedules","scalingSchedules","cpuMetricConfigured","cpuUtilization","loadBalancingMetricConfigured","loadBalancingUtilization","scaleInUnit","scaleInControl","maxScaledInReplicas","percent","scaleInMaximum","updateCustomMetric","metric","metricIndex","updateSchedule","schedule","scheduleIndex","minNumReplicas","maxNumReplicas","coolDownPeriodSec","utilizationTarget","predictiveMethod","STANDARD","NONE","placeholder","metricExportScope","scalingpolicy","_scalingpolicy","singleInstanceAssignment","_assignment","compatibleMetric","customMetric","_target","utilizationTargetType","_type","assignmentMetric","utilizationMetric","updateCustomMetricScalingPolicy","timeWindowSec","scheduleName","scheduleDescription","enabled","minimumRequiredInstances","scheduleCron","timezone","duration","isIntegerInRange","isUtilizationTarget","isValidCustomMetric","Policies","toggleAutoscaling","persistedPolicy","setAutoscalingPolicy","coherentDesiredCapacity","toggleAutohealing","validMinimum","validMaximum","cpuConfigured","loadBalancingConfigured","cpuValid","loadBalancingValid","hasValidMetrics","hasValidSchedules","hasFixed","fixed","hasPercent","hasValidScaleInControl","filteredHealthCheckReader","autoscalingEnabled","autohealingEnabled","ServerGroupBasicSettings","parentChanged","commandWithImages","strategyChanged","strategyFieldChanged","sharedErrors","stackPattern","detailPattern","renderSelect","fieldValue","referenceOptions","TaskReason","reason","rawOptions","objectKeys","optionValue","FLEX_TARGET_SHAPES","VALIDATION_ERROR_ID","normalizeMachineType","trimmed","lastIndexOf","hasUniqueMachineTypes","machineTypes","selection","instanceSelections","normalizedMachineType","hasValidRank","rank","GceInstanceFlexibilityConfigurer","targetShapeProp","validationError","setInstanceFlexibilityPolicy","regionalRequired","evenBlocked","duplicateMachineTypes","updateSelections","addSelection","nextName","existingNames","used","nextSelectionName","updateSelection","selectionId","rankInvalid","onBlur","oldName","newName","next","renameSelection","removeSelection","step","rawRank","withoutRank","parsed","updateRank","updateMachineType","marginLeft","removeMachineType","addMachineType","hasValidFlexibilityPolicy","hasNonEmptyMachineTypes","INTEGER_ERROR","ServerGroupCapacity","commandChanged","handlers","capacityChanged","rawValue","isNonNegativeInteger","parseCapacity","policyField","capacityModeChanged","isValidCapacityValue","selectedZoneChanged","selectedZones","targetShapeChanged","instanceFlexibilityPolicyChanged","renderCapacityInput","capacityError","renderZonalLocation","zoneOptions","renderRegionalDistribution","zonesError","targetShapes","rawZones","availableZones","IMAGE_SOURCES","ServerGroupImageSettings","imageArtifactEdited","expectedImageArtifactSelected","expectedArtifact","renderImageSource","sourceControl","imageSourceText","Markdown","StageArtifactSelectorDelegate","imageArtifact","excludedArtifactTypePatterns","excludeAllTypesExcept","ArtifactTypePatterns","CUSTOM_OBJECT","expectedArtifactId","imageArtifactId","helpKey","onArtifactEdited","onExpectedArtifactSelected","renderImageSelect","rawImages","persistedImage","imageOptions","MAX_BOOT_DISK_SIZE_GB","ServerGroupInstanceType","instanceTypeRequestGeneration","nextValues","updateValues","SpelService","includesSpel","reconciledCommand","defaultDisks","reconcileInstanceTypeDetails","updateMachineTypeMode","custom","updateCustomInstance","getCustomInstanceConfig","buildCustomMachineType","updatePreemptible","updateAcceleratorType","getAcceleratorConfigs","currentCount","availableCounts","nearest","nearestAvailableCount","configIndex","updateAcceleratorCount","addAccelerator","_config","updateBootDisk","bootDiskIndex","getBootDiskIndex","unshift","bootDisk","getBootDisk","availableAccelerators","isValidPositiveInteger","customMode","preserveStringReference","customChoices","customInstanceTypes","preserveNumberOrStringReference","instanceFamilyList","vCpuList","memoryList","selectedAccelerator","typeOptions","preserveAcceleratorReference","countOptions","selectedValue","configured","parseCustomMachineType","choices","GLOBAL_LOAD_BALANCER_NAMES","REGIONAL_LOAD_BALANCER_NAMES","BACKEND_SERVICE_NAMES","metadataValues","metadataSource","loadBalancerMetadataReference","buildLoadBalancerMetadata","unavailableLoadBalancers","persistedMetadata","compactMetadata","GceCloneServerGroupModalComponent","configureRequest","unmounted","getAdapter","baseCommand","placeholderViewState","hideClusterNamePreview","readOnlyFields","initializePipelineCreateCommand","persistedSelections","autoHealingHealthCheck","distributionZones","loadBalancerReferences","indexedLoadBalancer","snapshotPersistedSelections","refreshedCommand","mergeRefreshedCommand","snapshot","accountAvailable","referenceValues","regionAvailable","initializeCommand","unavailableZones","firewallProperties","availableFirewalls","uniqueByReference","healthCheckAvailable","unavailableNames","uniqueByName","knownBackendServices","unavailableBackendMetadata","oldReference","refreshedReference","attributedMetadata","attributed","restoreUnavailableSelections","initializationError","_error","retryConfiguration","transformed","targetSize","transformGceServerGroupCommand","serverGroupWriter","cloneServerGroup","onApplicationRefresh","cloneStage","task","newServerGroupName","transitionTo","GceCloneServerGroupModal","delegate","providerServiceDelegate","getDelegate","WizardModal","initialValues","nextIdx","wizard","pageProps","WizardPage","order","innerRef","CustomInstanceConfigurer","handleVCpuChange","selectedInstanceFamily","selectedMemory","selectedExtendedMemory","handleMemoryChange","selectedVCpuCount","handleInstanceFamilyChange","handleMemoryChangeCustom","handleExtendedMemory","instanceFamilyOptions","vCpuOptions","vCpu","memoryOptions","selectedVCpuCountLabel","selectedMemoryLabel","selectedInstanceFamilyLabel","Select","clearable","CheckboxInput","customInstanceBuilderService","GceCustomInstanceBuilder","onTypeChanged","gceCommand","setConfig","isExtendedMemory","withValidDefaults","getChoices","getInitialConfig","effectiveConfig","nextConfig","completeConfig","nextInstanceType","selectedVCpu","GceInstanceFlexibilityPolicyDetails","selections","isValidPolicy","GceUpsertAutoHealingPolicyModal","Reflect","deleteProperty","GceAutoHealingPolicyDetails","mutationsEnabled","runIfNotManaged","confirmNotManaged","notManaged","deletePolicy","isSingleInstanceAssignment","initialPolicy","GceUpsertAutoscalingPolicyModal","predictiveEnabled","customMetricsValid","percentage","round","GceAutoscalingPolicyDetails","maxScaledIn","autoscalingMessages","validateGceResizeValues","newSize","newMinNumReplicas","newMaxNumReplicas","GceResizeServerGroupModal","verified","autoscalingPolicyWriter","buildGceFixedResizeJob","resizeServerGroup","currentSize","errorMessage","ValidationMessage","PlatformHealthOverride","platformHealthType","showHelpDetails","UserVerification","onValidChange","getGceRollbackCandidates","candidateApplication","cluster","b","_GceRollbackServerGroupModal","restoreServerGroupName","rollbackContext","rollbackServerGroupName","rollbackType","buildGceRollbackJob","rollbackServerGroup","GceRollbackServerGroupModal","decorateServerGroup","projectFromTemplate","gceServerGroupDetailsGetter","Observable","observer","findServerGroupSummary","ServerGroupReader","getServerGroup","complete","withGcePlatformHealthParams","GceServerGroupActions","serverGroupCommandBuilder","confirmationDefaults","ErrorModalService","body","cloneGceServerGroup","confirmationModalParams","disableServerGroup","ServerGroupWarningMessageService","addDisableWarningMessage","enableServerGroup","destroyServerGroup","addDestroyWarningMessage","shieldedValue","stableConfig","legacyConfig","gceServerGroupDetailsSections","shieldedSettings","GceServerGroupTransformer","convertServerGroupCommandToDeployConfiguration","getAvailabilityZones","supportedPolicy","normalizeServerGroup","ready","GceSubnetRenderer","ApplicationNameValidator","registerValidator","validateSpecialCharacters","validateLength","warnings","maxResourceNameLength","maxLengthForLoadBalancers","remaining","maxLengthForServerGroups","registerGoogleProvider","registerProvider","logo","applicationProviderFields","cache","configurer","transformer","CloneServerGroupModal","detailsActions","detailsGetter","detailsSections","CustomInstanceBuilder","multiInstanceTaskTransformer","CreateLoadBalancerModal","pipelineCreateLoadBalancerModal","setTransformer","useDetailsHook","CreateSecurityGroupModal","renderer","snapshotsEnabled","registerPipelineStageOnce","stageKey","getStageTypes","registerGooglePipelineStages","DeploymentStrategyRegistry"],"mappings":"s8DAUO,MAAMA,GACJ,gBAAAC,GACL,OAAOC,EAAcC,OACnB,CAAEC,EAAG,GAAIC,KAAM,kBAAmBC,gBAAiB,QACnDC,EAAqBC,IAAI,iBAExBC,KAAMC,GACDA,GAAiBA,EAAcC,QAC1BD,EAAcC,QAAQC,OAAQC,GAAyC,QAAzBA,EAAYC,UAE1D,IAGVC,MAAM,IAAM,GACjB,ECRK,MAAMC,GACJ,gBAAAC,CAAiBZ,GACtB,OAAIA,EACKa,KAAKD,mBAAmBR,KAAMU,GACnCA,EAAaP,OAAQQ,GAAgBA,EAAYC,kBAAoBhB,IAGhEH,EAAcC,OACnB,CAAEC,EAAG,GAAIC,KAAM,eAAgBC,gBAAiB,QAChDC,EAAqBC,IAAI,iBAExBC,KAAMC,IACL,GAAIA,GAAiBA,EAAcC,QAAS,CAC1C,MAAMQ,EAAeT,EAAcC,QAChCC,OAAQU,GAA+B,QAApBA,EAAOR,UAC1BS,IAAKD,IACJ,MAAMF,EAAcI,KAAKC,MAAMH,EAAOF,aAEtC,OADAA,EAAYM,QAAUJ,EAAOI,QACtBN,IAEX,OAAOO,GAASR,EAAc,CAACS,EAAyBC,IAEpDD,EAAOE,OAASD,EAAOC,MACvBF,EAAOP,kBAAoBQ,EAAOR,iBAClCO,EAAOF,UAAYG,EAAOH,QAGhC,CACE,MAAO,KAGVX,MAAM,IAAM,GAEnB,EC1CK,MAAMgB,GACX,WAAAC,GACE,MAAMC,EAAuB,IAAIjC,GAC3BkC,EAAuB,IAAIlB,GAkB3BmB,EAASC,OAAOC,OAAO,MAkB7B,OAhBAF,EAAOG,UAAY,CACjBC,aAAc,CApBM,IACpBrC,EAAcC,OAAO,CAAEC,EAAG,GAAIC,KAAM,YAAaC,gBAAiB,QAAUC,EAAqBC,IAAI,cAClGC,KAAMC,GACDA,GAAiBA,EAAcC,QAC1BD,EAAcC,QAClBC,OAAQU,GAA+B,QAApBA,EAAOR,UAC1BS,IAAKD,IAAA,IAAiBE,KAAKC,MAAMH,EAAOkB,SAAUd,QAASJ,EAAOI,QAASe,OAAQnB,EAAOmB,UAExF,IAER1B,MAAM,IAAM,MAajBoB,EAAOO,gBAAkB,CACvBH,aAAc,CAbY,IAC1BI,EAAK,WACFC,SAASrC,EAAqBC,IAAI,oBAClCqC,MAAM,CAAEzC,EAAG,GAAIC,KAAM,kBAAmBC,gBAAiB,SACzDE,QAYL2B,EAAOW,aAAe,CACpBP,aAAc,CAAC,IAAMN,EAAqBhC,qBAG5CkC,EAAOhB,aAAe,CACpBoB,aAAc,CAAC,IAAML,EAAqBjB,qBAGrCkB,CACT,EC7CF,MAAMY,GAA0C,CAC9C,mCACE,8FACF,sCACE,4JACF,sCACE,wGACF,kCACE,iHACF,4CAA6C,mCAC7C,iCAAkC,kVAKlC,sCAAuC,uDACvC,4BACE,qHACF,qBACE,0GACF,mBAAoB,qWASpB,oCACE,mPACF,qCACE,uNACF,6CACE,kOACF,gDAAiD,yDACjD,kDACE,qHACF,yDACE,4HACF,oDACE,uHACF,oDACE,2HACF,6CAA8C,oDAC9C,uCAAwC,uEACxC,6CAA8C,uEAC9C,uBACE,sLACF,gCACE,wLACF,8BACE,gOACF,0BACE,6PACF,yCACE,+FACF,0BACE,mGACF,iCAAkC,gDAClC,uCACE,+EACF,sCACE,yOACF,0BACE,gIACF,mDACE,4GACF,qDACE,4JACF,uDACE,wIACF,+BACE,8FACF,4BACE,8QACF,6BACE,kSACF,gCACE,6GACF,+BACE,6GACF,+BAAgC,wEAChC,0CACE,+EACF,0CACE,+EACF,yDACE,wGACF,8CAA+C,qTAI/C,kDACE,4IACF,+CACE,oFACF,sDACE,yIACF,yDACE,0FACF,yDACE,iFACF,+CAAgD,mQAQhD,4BACE,6GACF,2BACE,0KACF,iCACE,uIACF,iCACE,oLACF,2BACE,gNACF,qDACE,qIACF,4DACE,4IACF,uDACE,uIACF,uDACE,4QACF,8CACE,wFACF,gDAAiD,oDACjD,0CAA2C,uEAC3C,gDACE,uEACF,4CACE,0LACF,yCACE,8JACF,uCACE,wGACF,iCACE,wIACF,gDACE,0KACF,iCACE,gHACF,mCACE,6KACF,oCACE,wIACF,+BACE,4LACF,0CACE,4IACF,4CACE,qGACF,6CACE,+FACF,2DACE,uMACF,2CACE,gFACF,qCACE,0FACF,qCAAsC,8EACtC,uCACE,6OACF,mCACE,+KACF,8BACE,iNACF,kCACE,uGACF,yBAA0B,+uBAO1B,oDACE,iPACF,yDACE,sIACF,qDACE,wMACF,gEACE,sIACF,qDAAsD,uZAItD,+CACE,sGACF,oDACE,oIACF,0BACE,wJACF,8BACE,mLACF,gCACE,wJACF,uCACE,oIACF,qCACE,kFACF,+BAAgC,4XAGhC,+BACE,6IACF,gCACE,oOACF,2BACE,qQACF,2BACE,8OAGJX,OAAOY,KAAKD,IAAcE,QAASC,GAAQC,EAAqBC,SAASF,EAAKH,GAAaG,KCxNpF,MAAMG,GACX,iBAAcC,CAAWC,GACvB,OAAOZ,EAAK,gBACTE,MAAMU,GACN/C,MACAO,MAAM,IAAM,GACjB,CAEA,eAAcyC,GAEZ,OAAOC,QAAQC,QAAQ,KACzB,ECH+BC,GAAMC,uKCVhC,MAAMC,GAAN,WAAA7B,GACL8B,GAAA5C,KAAA,kBAAmB6C,IACjB,MAAMC,EAAeD,EAAqBE,SAASC,MAAM,KACzD,OAAOF,EAAaA,EAAaG,QAAQ,YAAc,KAGzDL,GAAA5C,KAAA,iCAAiC,CAACkD,EAAWC,KAC3C,IAAKA,EACH,OAAO,KAKT,MAAMC,EAA0BD,EAAYH,MAAM,KAC5CK,EAAuBD,EAAwBA,EAAwBH,QAAQ,YAAc,GAC7FK,EAAkBC,GAAEC,KAAKJ,GAC/B,OAAIC,IAAyBH,EACpBG,EAAuB,IAAMC,EAE7BA,GAEX,EC6FF,SAASG,GAAeC,EAAevE,EAAcwE,GACnD,OAAQD,EAASE,QAAU,IAAIC,KAAMD,GAAgBA,EAAOzE,OAASA,GAAQyE,EAAOD,QAAUA,EAChG,CAEA,SAASG,GAA4BC,EAAUL,GA1H/C,IAAAM,EA2HE,OAAK,OAAAA,EAAAN,EAASO,wBAAeC,SAAWH,EAAIE,eAIpCF,EAAIE,cAAcE,MAAQ,IAC/BzE,OACE0E,GACCA,EAAa5D,UAAYkD,EAASlD,SACA,YAAlC4D,EAAaC,kBACbX,EAASO,cAAcK,SAASF,EAAaxD,OAEhDP,IAAK+D,GAAsBA,EAAaxD,MAVlC,EAWX,CAkBO,SAAS2D,IAA4BR,IAC1CA,EAAAL,SACAA,EAAAc,aACAA,IAKA,MAAMC,EAAyB,KACzBD,EAAaF,SAAS,qBAAsB,CAAEI,WAAYhB,EAASgB,cACrEF,EAAaG,GAAG,MAGdC,EAAU,CACdC,EACAC,EACAC,EACAC,EACAC,GAAkB,KAElBC,EAAyBN,QAAQ,CAC/BpE,QAASkD,EAASlD,QAClB2E,cAAc,EACdL,aACAD,SACAG,eACAI,kBAAmB,CACjBC,YAAatB,EACbuB,eAAgBL,EAAkBR,OAAyB,EAC3DM,YAIAQ,EAA2BzB,GAA4BC,EAAKL,GAC5D8B,EAAuB,IAAK9B,EAAUO,cAAesB,GACrDE,EAAoBF,EAAyBG,KAAK,SAClDC,EAAU,GAyGhB,OAlJF,SAAkCjC,GApJlC,IAAAM,EAsJE,MAAqC,kBAA9B,OAAAA,GADkBN,EAASE,QAAU,IAAIlE,OAAQkE,GAAgC,cAAhBA,EAAOzE,MACxD,SAAhB,EAAA6E,EAAoBL,MAC7B,CAwCMiC,CAAyBlC,IAC3BiC,EAAQE,KAAK,CACXC,MAAO,sBACPC,cAAe,IACbnB,EACE,iBAAiBlB,EAASgB,2BAC1B,UAAUhB,EAASgB,aACnB,YAAYhB,EAASgB,0BACrB,CAACrC,EAAS,CAAA,IAAO2D,EAAeC,0BAA0BvC,EAAUK,EAAK1B,MAK7EoB,GAAeC,EAAU,YAAa,OACxCiC,EAAQE,KAAK,CACXC,MAAO,uBACPC,cAAe,IACbnB,EACE,kBAAkBlB,EAASgB,2BAC3B,WAAWhB,EAASgB,aACpB,aAAahB,EAASgB,0BACtB,CAACrC,EAAS,CAAA,IAAO2D,EAAeE,2BAA2BxC,EAAUK,EAAK1B,MA3EpF,SAAqC0B,EAAUL,GAC7C,QAAKI,GAA4BC,EAAKL,GAAUQ,SAK9CT,GAAeC,EAAU,eAAgB,mBACvCA,EAASE,QAAU,IAAIC,KAAMD,GAAgC,iBAAhBA,EAAOzE,MAE1D,CAuEMgH,CAA4BpC,EAAKL,IACnCiC,EAAQE,KAAK,CACXC,MAAO,8BACPC,cAAe,IACbnB,EACE,mBAAmBlB,EAASgB,mBAAmBe,KAC/C,YAAY/B,EAASgB,aACrB,eAAehB,EAASgB,mBAAmBe,IAC3C,CAACpD,EAAS,CAAA,IAAO2D,EAAeI,iCAAiCZ,EAAsBzB,EAAK1B,MAMlGkD,EAAyBrB,OAAS,IACjCR,EAASE,QAAU,IAAIC,KAAMD,GAAgC,iBAAhBA,EAAOzE,OAErDwG,EAAQE,KAAK,CACXC,MAAO,gCACPC,cAAe,IACbnB,EACE,qBAAqBlB,EAASgB,mBAAmBe,KACjD,cAAc/B,EAASgB,aACvB,iBAAiBhB,EAASgB,mBAAmBe,IAC7C,CAACpD,EAAS,CAAA,IAAO2D,EAAeK,mCAAmCb,EAAsBzB,EAAK1B,MAKtGsD,EAAQE,KAAK,CACXC,MAAO,SACPC,cAAe,IACbnB,EACE,iBAAiBlB,EAASgB,cAC1B,UAAUhB,EAASgB,aACnB,aAAahB,EAASgB,aACtB,CAACrC,EAAS,CAAA,IACR2D,EAAeM,eAAe5C,EAAUK,EAAK,IAAK1B,EAAQkE,+BAAgC,QAGlGZ,EAAQE,KAAK,CACXC,MAAO,YACPC,cAAe,IACbnB,EACE,oBAAoBlB,EAASgB,cAC7B,aAAahB,EAASgB,aACtB,eAAehB,EAASgB,aACxB,CAACrC,EAAS,CAAA,IACR2D,EAAeQ,kBAAkB9C,EAAUK,EAAK,IAC3C1B,EACHoE,cAAe,SACX/C,EAASgD,YAAc,CAAEC,yBAA0BjD,EAASgD,aAAgB,CAAA,KAEpF,KAIFhD,EAASgD,aACXf,EAAQE,KAAK,CACXC,MAAO,oCACPC,cAAe,IACbnB,EACE,oBAAoBlB,EAASgB,yBAAyBhB,EAASgD,eAC/D,aAAahD,EAASgB,yBAAyBhB,EAASgD,cACxD,eAAehD,EAASgB,wCACxB,CAACrC,EAAS,CAAA,IACR2D,EAAeY,sCAAsClD,EAAUK,EAAK,IAC/D1B,EACHwE,YAAa,CAACnD,EAASgB,YACvBoC,gBAAiBpD,EAASgD,YAC1BK,KAAMrD,EAASsD,UAAUC,oBAE7B,KAKDxE,GAAAyE,cAACC,GAAgBxB,WAC1B,CA0HkCyB,EAAW7C,IACtC,MAAM8C,GAAqBD,EAzH3B,SAAqCE,GAC1C,MAAO5D,EAAU6D,GAAeC,GAAcF,EAAMG,iBAAmB,OAChEC,EAASC,GAAcH,IAAkB,IACzCI,EAAUC,GAAeL,IAAkB,GA2ClD,OAzCAM,GAAgB,KACd,IAAIC,GAAY,EAChB,MAAM1F,EAxRV,SAA2BiF,GACzB,MAAMU,EAAcV,EAAMW,cAAgBX,EAAMU,aAAe,CAAA,EACzDtE,EAAW4D,EAAM5D,UAAY4D,EAAMG,iBAAmB,CAAA,EAC5D,MAAO,CACLjH,QAASkD,EAASlD,SAAWwH,EAAYxH,SAAWwH,EAAYE,UAChExD,WAAYhB,EAASgB,YAAcsD,EAAYtD,YAAcsD,EAAYG,GACzE5G,OAAQmC,EAASnC,QAAUyG,EAAYzG,OAE3C,CAgRmB6G,CAAkBd,GAC3Be,EAAUhG,EAAOqC,WA/Q3B,SAA6BX,EAAUW,GAlCvC,IAAAV,EAAAsE,EAmCE,MAAMC,GAAe,OAAAvE,EAAA,MAAAD,OAAA,EAAAA,EAAKwE,mBAAL,EAAAvE,EAAmBG,OAAQ,GAChD,IAAA,MAAWuC,KAAe6B,EAAc,CACtC,MAAMF,GAAW3B,EAAY8B,WAAa,IAAIC,KAAMC,GAAmBA,EAAUP,KAAOzD,GACxF,GAAI2D,EACF,MAAO,IACFA,EACH7H,QAASkG,EAAYlG,QACrByD,cAAeyC,EAAYzC,eAAiB,GAC5C1C,OAAQmF,EAAYnF,OACpBmF,YAAaA,EAAY9F,KACzB+H,MAAOjC,EAAYiC,MAGzB,CAEA,MAAM1E,GAAgB,OAAAqE,EAAA,MAAAvE,OAAA,EAAAA,EAAKE,oBAAL,EAAAqE,EAAoBnE,OAAQ,GAClD,IAAA,MAAWC,KAAgBH,EAAe,CACxC,MAAMoE,GAAWjE,EAAaoE,WAAa,IAAIC,KAAMC,GAAmBA,EAAUP,KAAOzD,GACzF,GAAI2D,EACF,MAAO,IACFA,EACH7H,QAAS4D,EAAa5D,QACtByD,cAAe,CAACG,EAAaxD,MAC7BW,OAAQ6C,EAAa7C,OACrBoH,MAAOvE,EAAauE,OAIxB,IAAA,MAAWjC,KAAgBtC,EAAamE,cAAgB,IAAI7I,OAAQgJ,GAAmBA,EAAUE,YAAa,CAC5G,MAAMC,GAAmBnC,EAAY8B,WAAa,IAAIC,KAAMC,GAAmBA,EAAUP,KAAOzD,GAChG,GAAImE,EACF,MAAO,IACFA,EACHrI,QAAS4D,EAAa5D,QACtByD,cAAe,CAACG,EAAaxD,MAC7BW,OAAQ6C,EAAa7C,OACrBmF,YAAamC,EAAgBnC,aAAeA,EAAY9F,KACxDkI,qBAAqB,EACrBH,MAAOvE,EAAauE,MAG1B,CACF,CAEA,OAAO,IACT,CAiOwCI,CAAoBzB,EAAMvD,IAAK1B,EAAOqC,YAAc,KAClFlE,GAAU,MAAA6H,OAAA,EAAAA,EAAS7H,UAAW6B,EAAO7B,QACrCe,GAAS,MAAA8G,OAAA,EAAAA,EAAS9G,SAAUc,EAAOd,OAMzC,OAJAgG,EAAY,MACZI,GAAW,GACXE,GAAY,GAEPxF,EAAOqC,YAAelE,GAAYe,GAMvCyH,EAAqBC,qBAAqB,YAAa,CAAEzI,UAASe,SAAQmF,YAAa,MAAA2B,OAAA,EAAAA,EAAS3B,cAEhGwC,EAAeC,mBAAmB3I,EAASe,EAAQc,EAAOqC,YAAYnF,KACnE6J,IACKrB,IAGJR,EA/OD,SAA0B7D,GAvFjC,IAAAM,EAAAsE,EAAAe,EAAAC,EAwFE,MAAMC,EAAY,IAAI5G,GAChB6G,GAAmB,OAAAxF,EAAAN,EAAS+F,0BAATzF,EAA6B,KAAM,CAAA,EACtD0F,EARR,SAA6B3G,GAC3B,MAAM4G,EAAQ,sBAAsBC,KAAK7G,GAAY,IACrD,OAAO,MAAA4G,SAAAA,EAAQ,EACjB,CAKkBE,CAAoBnG,EAASX,WAAaW,EAASlD,QAC7DuG,EAAOrD,EAASqD,OAAQ,OAAAuB,IAAStB,gBAAT,EAAAsB,EAAoBrB,mBAAoBvD,EAASnC,OACzEuI,EAAUP,EAAUQ,+BAA+BL,EAASF,EAAiBM,SAC7EE,EAAST,EAAUQ,+BAA+BL,EAASF,EAAiBS,YAC5EC,EAAoB,OAAAZ,EAAA,OAAAD,EAAAG,EAAiBW,oBAAjB,EAAAd,EAAiC,SAAjC,EAAAC,EAAqCc,MACzDC,EAAoBb,EAAiBc,UACrCC,EAAU7G,EAASX,SACrBW,EAASX,SAASyH,QAAQ,gCAAiC,kCAC3D,KAEJ,MAAO,IACF9G,EACH+G,cAAeP,GAAqBG,EACpCH,oBACAQ,iBAAkB3D,EAAO,sBAAsBrD,EAAS9C,MAAQ8C,EAASgB,qBAAqBqC,SAAS,EACvGnD,QAASF,EAASE,QAAU,IAAIlE,OAAQkE,GAAgC,WAAhBA,EAAOzE,MAAsC,YAAjByE,EAAOD,OAC3FgH,gBAAiBjH,EAASgB,WAC1B2F,oBACAO,SAAUlB,EACN,uDAAuDmB,mBAAmBnB,gCAC1E,EACJI,UACAvI,OAAQmC,EAASnC,QAAUwF,EAC3BwD,UACAP,SAEJ,CAkNoBc,CAAiB,IAAKzC,KAAYe,EAAS5I,UAASkE,WAAYrC,EAAOqC,WAAYnD,YAC/FoG,GAAW,KAEb,KACMI,IAGJF,GAAY,GACZF,GAAW,MAIR,KACLI,GAAY,KAzBZF,GAAY,QACZF,GAAW,KA0BZ,CAACL,EAAMvD,IAAKuD,EAAM5D,SAAU4D,EAAMG,gBAAiBH,EAAMW,aAAcX,EAAMU,cAE5EJ,EACKnF,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,uBAAsB,uBAI5CtI,GAAAyE,cAAC8D,EAAA,CAAQtD,WACNhE,GACCjB,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC8D,EAAQE,OAAR,CACCC,KAAM1I,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aACtBnK,KAAM8C,EAAS9C,MAAQ8C,EAASgB,WAChCiB,QACElD,GAAAyE,cAAC3C,GAAA,CACCR,IAAKuD,EAAMvD,IACXL,WACA0H,OAAQ9D,EAAM8D,OACdpD,YAAaV,EAAMU,YACnBxD,aAAc8C,EAAM9C,iBAI1B/B,GAAAyE,cAAC8D,EAAQK,QAAR,CAAgB3D,WACfjF,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,uBAAuBC,iBAAiB,GAClE/I,GAAAyE,cAAC,MAAG6D,UAAU,4CACX,KAAA,KAAG,WACJtI,GAAAyE,cAAC,UACCzE,GAAAyE,cAACuE,EAAA,CAAWjL,QAASkD,EAASlD,WAEhCiC,GAAAyE,cAAC,KAAA,KAAG,UACJzE,GAAAyE,cAAC,KAAA,KAAIxD,EAASnC,yBACb,KAAA,KAAG,QACJkB,GAAAyE,cAAC,UAAIxD,EAASgI,aAAehI,EAASiI,cAAgBjI,EAASvE,MAC/DsD,GAAAyE,cAAC,KAAA,KAAG,WACJzE,GAAAyE,cAAC,KAAA,KAAIxD,EAASoG,SAAW,KACzBrH,GAAAyE,cAAC,KAAA,KAAG,2BACH,KAAA,KAAIxD,EAASsG,QAAU,OAG5BvH,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,MAAMC,iBAAiB,oBAChD,KAAA,CAAGT,UAAU,2BACZtI,GAAAyE,cAAC,KAAA,KAAG,sCACH,KAAA,KAAIxD,EAASiH,iBAAmB,KACjClI,GAAAyE,cAAC,KAAA,KAAG,gCACH,KAAA,KAAIxD,EAAS2G,mBAAqB,sBAClC,KAAA,KAAG,eACJ5H,GAAAyE,cAAC,UAAIxD,EAASwG,mBAAqB,OAGvCzH,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,MAAMC,iBAAiB,GAChD9H,EAAS6G,SACR9H,GAAAyE,cAAC,IAAA,sBACE,IAAA,CAAE0E,KAAMlI,EAAS6G,QAASsB,OAAO,SAASC,IAAI,uBAAsB,gCAKxEpI,EAASgH,kBAAoBjI,GAAAyE,cAAC,MAAA,KAAKxD,EAASgH,mBAE/CjI,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,OAAOC,iBAAiB,GACjD9H,EAASkH,SACRnI,GAAAyE,cAAC,IAAA,CAAE0E,KAAMlI,EAASkH,SAAUiB,OAAO,SAASC,IAAI,uBAAsB,0BAItErJ,GAAAyE,cAAC,OAAA,KAAK,4BAQtB,GC7Za6E,GAAkC7K,OAAO8K,OAAO,CAC3D,CACEL,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,iBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,iBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,iBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,iBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,WACdQ,kBAAkB,EAClBF,MAAO,CACL,CACE9M,KAAM,cACN+M,OAAQ,MAId,CACEP,aAAc,WACdQ,kBAAkB,EAClBF,MAAO,CACL,CACE9M,KAAM,cACN+M,OAAQ,MAId,CACEP,aAAc,WACdQ,kBAAkB,EAClBF,MAAO,CACL,CACE9M,KAAM,cACN+M,OAAQ,MAId,CACEP,aAAc,WACdQ,kBAAkB,EAClBF,MAAO,CACL,CACE9M,KAAM,cACN+M,OAAQ,MAId,CACEP,aAAc,YACdQ,kBAAkB,EAClBF,MAAO,CACL,CACE9M,KAAM,cACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,eACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,gBACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,MAId,CACEP,aAAc,UACdM,MAAO,CACL,CACE9M,KAAM,SACN+M,OAAQ,QCxPT,MAAME,GACX,WAAAtL,CAAYuL,EAAgBC,EAASC,SAGnC,MAgQMC,EAAa,CACjB,CACErN,KAAM,UACN2G,MAAO,kBACP2G,SAAU,CApQK,CACjBtN,KAAM,cACNuN,YACE,sIACFC,YAAa,MACbC,oBAAqB,uBACrBC,cAAe,CACb,CACEjM,KAAM,gBACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,KACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,iBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,iBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,iBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,iBACNkF,MAAO,WACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,MAwMd7B,KAAM,OAER,CACEhM,KAAM,SACN2G,MAAO,cACP2G,SAAU,CA3JI,CAChBtN,KAAM,aACNuN,YACE,mKACFC,YAAa,MACbC,oBAAqB,uBACrBC,cAAe,CACb,CACEjM,KAAM,eACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,eACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,eACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,WACPgH,IAAK,GACLC,OAAQ,IACRC,WAAY,MAsGd7B,KAAM,OAER,CACEhM,KAAM,MACN2G,MAAO,WACP2G,SAAU,CAtGI,CAChBtN,KAAM,aACNuN,YACE,uKACFC,YAAa,MACbC,oBAAqB,uBACrBC,cAAe,CACb,CACEjM,KAAM,eACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,eACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,eACNkF,MAAO,SACPgH,IAAK,EACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,KACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,KACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,UACPgH,IAAK,GACLC,OAAQ,KACRC,WAAY,GAEd,CACEpM,KAAM,gBACNkF,MAAO,WACPgH,IAAK,GACLC,OAAQ,KACRC,WAAY,MAiDd7B,KAAM,OAER,CACEhM,KAAM,QACN2G,MAAO,gBACP2G,SAAU,CApNE,CACdtN,KAAM,oBACNuN,YACE,8OACFC,YAAa,MACbC,oBAAqB,uBACrBC,cAAe,CACb,CACEjM,KAAM,WACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,GACRC,WAAY,GAEd,CACEpM,KAAM,WACNkF,MAAO,QACPgH,IAAK,EACLC,OAAQ,IACRC,WAAY,GAEd,CACEpM,KAAM,WACNkF,MAAO,WACPgH,IAAK,EACLC,OAAQ,EACRC,WAAY,GAEd,CACEpM,KAAM,WACNkF,MAAO,WACPgH,IAAK,EACLC,OAAQ,EACRC,WAAY,GAEd,CACEpM,KAAM,YACNkF,MAAO,YACPgH,IAAK,EACLC,OAAQ,EACRC,WAAY,MA6Kd7B,KAAM,OAER,CACEhM,KAAM,SACN2G,MAAO,cACP2G,SAAU,GACVtB,KAAM,YAER,CACEhM,KAAM,cACN2G,MAAO,eACP2G,SAAU,CA7DQ,CACpBtN,KAAM,cACN0N,cAAe,CACb,CACEjM,KAAM,gBACNqM,UAAW,yBACXC,QAAS,CACPC,mBAAmB,IAGvB,CACEvM,KAAM,gBACNqM,UAAW,gCACXC,QAAS,CACPC,mBAAmB,IAGvB,CACEvM,KAAM,mBACNqM,UAAW,mCACXC,QAAS,CACPC,mBAAmB,OAyCvBhC,KAAM,WAIJiC,EAAgB7J,GAAE8J,QAAQ,KAC9B,MAAMC,EAAwB/J,GAAEgK,UAAUf,GAC1C,OAAOgB,EAAeC,gCAAgC,OAAOlO,KAAMmO,IAEjE,IAAIC,EAAoBpK,GAAEjE,IAAIoO,EAAgB,yBAI9C,GAHInK,GAAEqK,QAAQD,KACZA,EAAoB5B,IAElB4B,EAAmB,CACJpK,GAAEsK,QAAQP,EAAsBjN,IAAKyN,GAAaA,EAASrB,WACnE1K,QAASgM,IAChBA,EAAOlB,cAAc9K,QAAS4J,IAC5B,MAAMqC,EAAeL,EAAkBlF,KACpCwF,GAAqBA,EAAiBtC,eAAiBA,EAAa/K,MAEvE,GAAIoN,EAAc,CAChB,MAAM/B,EAAQ+B,EAAa/B,MACxB5L,IAAK6N,IACJ,OAAQA,EAAK/O,MACX,IAAK,SACH,MAAO,CACLA,KAAM,SACN+M,OAAQgC,EAAKhC,QAEjB,IAAK,cACH,MAAO,CACL/M,KAAM,cACN+M,OAAQgC,EAAKhC,QAEjB,IAAK,YACH,MAAO,CACL/M,KAAM,YACN+M,OAAQ,KAEZ,QAEE,OADAI,EAAO6B,KAAK,cAAcD,EAAK/O,wBACxB,QAGZO,OAAQwO,KAAWA,GAEtB,IAAIE,EAAO,EACPC,EAAQ,EACZ,GAAIL,EAAa7B,iBACfkC,EAAQpC,EAAMvM,OAAQwO,GAAuB,cAAdA,EAAK/O,MAAsB+E,OAC1DkK,EAAO,QACF,CAKL,MAAME,EAAkBrC,EAAMvM,OAAQwO,GAASA,EAAK/O,KAAKoP,WAAW,QAChED,EAAgBpK,SAClBkK,EAAOE,EAAgBE,OAAO,CAACC,EAAWP,IAASQ,KAAKC,IAAIF,EAAWP,EAAKhC,QAAS,GACrFmC,EAAQC,EAAgB5O,OAAQwO,GAASA,EAAKhC,SAAWkC,GAAMlK,OAEnE,CAEAyH,EAAauB,QAAU,CACrBC,kBAAmBa,EAAa7B,iBAChCiC,OACAC,QACAO,gBAAiB,CAAE3C,SAEvB,KAGN,CACA,OAAOqB,MAqBX,SAASuB,EAA8BC,EAA4BC,GACjE,IAAKD,IAA+BC,GAAkD,IAA7BA,EAAkB7K,OAEzE,OADAqI,QAAQyC,MAAM,4BACP,GAOT,OAJuBD,EACpBrP,OAAQuP,GAAaH,EAA2BG,IAChDC,QAASD,GAAaH,EAA2BG,GAAUpC,eAAiB,GAGjF,CAWA,MAAO,CACLO,gBACA+B,4BAXkCN,EAYlCO,oBA1CF,WAKE,OAAOhC,IAAgB7N,KAAMiN,GACpBjJ,GAAE8L,MAAM7C,GACZnM,IAAI,YACJwN,UACAxN,IAAI,iBACJwN,UACAxN,IAAI,QACJX,OAAQkB,GAAkB,kBAATA,GAAqC,kBAATA,GAAqC,qBAATA,GACzE0O,QAEP,EA4BET,gCACAU,2BAZkC5D,IAC3B,CACL/K,KAAM+K,EACNuB,QAAShM,OAAOsO,OAAO,CAAEC,WAAW,GAAQC,EAASC,UAAUC,IAAIC,SAASC,uBAWlF,0ICvaF,MAAMC,GAAe,CACnBC,gBAAkBC,IAChBA,EAAI1J,+BAAiC,KAQlC,MAAM2J,GAAN,WAAApP,GACL8B,GAAA5C,KAAA,YAAY,CAACmQ,EAAeF,KALT,EAACE,EAAeF,KACnCA,EAAIlJ,KAAOoJ,EAAc3H,UAAU,GAAGvB,kBAKpCmJ,CAAaD,EAAeF,GACxBF,GAAaE,EAAI9Q,OACnB4Q,GAAaE,EAAI9Q,MAAM8Q,IAE3B,EC+BF,MAAMI,GAAmC,CACvCC,SAAU,GACVlP,UAAW,GACXI,gBAAiB,GACjBI,aAAc,GACd3B,aAAc,GACdsQ,SAAU,GACVC,QAAS,GACTC,QAAS,IAGJ,MAAMC,GAMX,WAAA5P,CAAoB6P,EAAuCC,IAAvC5Q,KAAA2Q,QAAAA,EALpB3Q,KAAQ6Q,UAAW,EACnB7Q,KAAQ8Q,cAAgBC,IACxB/Q,KAAQgR,UAAY,EACpBhR,KAAQ2D,MAAmC,CAAEQ,KAAMkM,GAAYY,OAAQ,OAEiB,CAEjF,QAAAC,GACL,OAAOlR,KAAK2D,KACd,CAEO,SAAAwN,CAAUC,GAIf,OAHKpR,KAAK6Q,UACR7Q,KAAK8Q,UAAUO,IAAID,GAEd,IAAMpR,KAAK8Q,UAAUQ,OAAOF,EACrC,CAEA,UAAaG,CAAK/Q,GAChB,MAAMwQ,IAAchR,KAAKgR,UACzBhR,KAAKwR,QAAQ,CAAErN,KAAMnE,KAAK2D,MAAMQ,KAAM6K,WAAO,EAAWiC,OAAQ,YAEhE,IACE,MACEX,EACAlP,EACAI,EACAI,EACA3B,EACAsQ,EACAC,EACAC,SACQlO,QAAQkP,IAAI,CACpBzR,KAAK2Q,QAAQL,WACbtQ,KAAK2Q,QAAQvP,YACbpB,KAAK2Q,QAAQnP,kBACbxB,KAAK2Q,QAAQ/O,eACb5B,KAAK2Q,QAAQ1Q,eACbD,KAAK2Q,QAAQJ,WACbvQ,KAAK2Q,QAAQH,QAAQhQ,GACrBR,KAAK2Q,QAAQF,YAEXzQ,KAAK0R,UAAUV,IACjBhR,KAAKwR,QAAQ,CACXrN,KAAM,CAAEmM,WAAUlP,YAAWI,kBAAiBI,eAAc3B,eAAcsQ,WAAUC,UAASC,WAC7FzB,WAAO,EACPiC,OAAQ,SAGd,OAASjC,GACHhP,KAAK0R,UAAUV,IACjBhR,KAAKwR,QAAQ,CAAErN,KAAMnE,KAAK2D,MAAMQ,KAAM6K,QAAOiC,OAAQ,SAEzD,CACF,CAEO,OAAAU,GACL3R,KAAK6Q,UAAW,EAChB7Q,KAAKgR,WAAa,EAClBhR,KAAK8Q,UAAUc,OACjB,CAEQ,SAAAF,CAAUV,GAChB,OAAQhR,KAAK6Q,UAAYG,IAAchR,KAAKgR,SAC9C,CAEQ,OAAAQ,CAAQ7N,GACV3D,KAAK6Q,WAGT7Q,KAAK2D,MAAQA,EACb3D,KAAK8Q,UAAU/O,QAASqP,GAAaA,EAASzN,IAChD,EAGK,SAASkO,GACdC,EACAC,GAEA,MAAMC,EAAiB,IAAIjB,IAAIe,EAAUzR,IAAI,EAAGO,UAAWA,IAC3D,MAAO,IAAIkR,KAAcC,EAAUrS,OAAO,EAAGkB,UAAWA,IAASoR,EAAeC,IAAIrR,IACtF,CAWA,MAAMsR,GAAoB,IAAIpT,GACxBqT,GAAoB,IAAIrS,GAEjB8Q,GAA0D,CACrEN,SAAU,IAAM9C,EAAe4E,aAAa,OAC5C5B,QAAUhQ,GACRgN,EAAe6E,qBAAqB7R,GAASjB,KAAMiR,GAC7C8B,MAAMC,QAAQ/B,GACTA,EAEFtP,OAAOY,KAAK0O,GAAW,CAAA,GAAInQ,IAAKO,IAAA,CAAYA,WAEvD2P,SAAU,IAAMiC,EAAcC,uBAAuB,OACrDhC,QAAS,IAAMiC,EAAaC,sBAAsB,OAClD/Q,aAAc,IAAMsQ,GAAkBnT,mBACtCkB,aAAc,IAAMkS,GAAkBpS,mBACtCqB,UAAW,IACTpC,EAAcC,OACZ,CAAEC,EAAG,GAAIC,KAAM,YAAaC,gBAAiB,QAC7CC,EAAqBC,IAAI,cACzBC,KAAMC,KACL,MAAAA,OAAA,EAAAA,EAAeC,UAAW,IACxBC,OAAO,EAAGE,cAA4B,QAAbA,GACzBS,IAAKD,IAAA,IAAiBE,KAAKC,MAAMH,EAAOkB,SAAUd,QAASJ,EAAOI,QAASe,OAAQnB,EAAOmB,WAEjGC,gBAAiB,IACfC,EAAK,WACFC,UAAS,GACTC,MAAM,CAAEzC,EAAG,GAAIC,KAAM,kBAAmBC,gBAAiB,SACzDE,MACAC,KAAKqT,KAGZ,SAASA,GAA+BC,GACtC,MAAMC,EAAQR,MAAMC,QAAQM,IAAiC,IAApBA,EAAS3O,OAAe2O,EAAS,GAAKA,EACzEpT,EAAUqT,GAA0B,iBAAVA,GAAsB,YAAaA,EAAQA,EAAMrT,QAAUqT,EAC3F,OAAOR,MAAMC,QAAQ9S,GAAYA,EAAyC,EAC5E,CC9LO,MAAMsT,GAA0B,CAAC,UAAW,WAAY,MAAO,MAAO,OAAQ,oBAgBxEC,GAA4F,CACvGC,QAASC,GAAa,CAAE5R,SAAS,EAAMrB,cAAc,IACrDkT,SAAUD,GAAa,CACrB5R,SAAS,EACTE,iBAAiB,EACjBvB,cAAc,EACd6J,SAAS,EACTE,QAAQ,IAEVoJ,IAAKF,GAAa,CAAE5R,SAAS,EAAME,iBAAiB,EAAMvB,cAAc,IACxEoT,IAAKH,GAAa,CAAE5R,SAAS,EAAME,iBAAiB,EAAMI,cAAc,EAAM3B,cAAc,IAC5FqT,KAAMJ,GAAa,CACjB5R,SAAS,EACTE,iBAAiB,EACjBI,cAAc,EACd3B,cAAc,EACdsT,WAAW,IAEbC,iBAAkBN,GAAa,CAC7B5R,SAAS,EACTE,iBAAiB,EACjBI,cAAc,EACd3B,cAAc,EACdsT,WAAW,EACXzJ,SAAS,EACTE,QAAQ,KA8GL,SAASyJ,GACd1B,EACA2B,GAEA,MAAMrP,EAwGR,SAAmCiL,GACjC,MAAMqE,EAAaC,GAAStE,GAAOuE,cACnC,OAAOd,GAAwBzO,SAASqP,GAAcA,EAAa,SACrE,CA3G2BG,CAA0B/B,EAAU1N,kBACvDzD,EAAOgT,GACXG,GAAW1P,GACP0N,EAAUiC,YAAcjC,EAAUnR,MAAQmR,EAAUkC,iBACpDlC,EAAUnR,MAAQmR,EAAUkC,kBAE5BC,EAAmB,CACvB5S,QAASyQ,EAAUoC,WAAapC,EAAUzQ,QAC1C3B,YAAaoS,EAAUpS,YACvBiB,KAAMmT,GAAW1P,KAAoB0N,EAAUkC,kBAAoBlC,EAAUnR,OAAeA,EAC5FwT,UAAWrC,EAAUqC,WAAarC,EAAUsC,MAC5CC,SACEvC,EAAUuC,WACTP,GAAW1P,GAAqB0N,EAAUpS,YAAc,QAAU,OAAUoS,EAAUwC,YACzFvK,OAAQ+H,EAAU/H,QAEd8G,EAAY0D,GAAQzC,EAAUjB,WAAW5M,OAASsQ,GAAQzC,EAAUjB,WAAa,CAACoD,GAClF1S,EAyKR,SAAgCuQ,GAC9B,MAAM0C,EAAa,IAAID,GAAQzC,EAAUvQ,oBAAqBgT,GAAQzC,EAAU2C,iBAC5E3C,EAAU4C,gBAAsD,iBAA7B5C,EAAU4C,gBAC/CF,EAAW5O,KAAKkM,EAAU4C,gBAE5BH,GAAQzC,EAAUwB,WAAWxR,QAAS6S,IACpC,MAAMC,EAAcC,GAASA,GAASF,GAAeC,aACjDA,EAAYF,gBAAwD,iBAA/BE,EAAYF,gBACnDF,EAAW5O,KAAKgP,EAAYF,gBAE9BH,GAAQK,EAAYE,WAAWhT,QAASiT,IACtC,MAAMN,EAAiBI,GAASE,GAAeN,eAC3CA,GAA4C,iBAAnBA,GAC3BD,EAAW5O,KAAK6O,OAKtB,MAAMO,MAAeC,IASrB,OARAT,EAAW1S,QAAS2G,IAClB,MAAMyM,EA9BV,SAAiCA,GAC/B,MAAMxB,EAA6C,IAAKwB,EAASvU,KAAMgT,GAASuB,EAAQvU,OAClFV,EAAckV,GAAmBD,EAAQjV,aAAeiV,EAAQE,iBAClEnV,IACFyT,EAAWzT,YAAcA,GAG3B,cADOyT,EAAW0B,gBACX1B,CACT,CAsBoB2B,CACO,iBAAd5M,EAAyBoM,GAASpM,GAAa,CAAE9H,KAAMgT,GAASlL,KAErEyM,EAAQvU,OAASqU,EAAShD,IAAIkD,EAAQvU,OACxCqU,EAASM,IAAIJ,EAAQvU,KAAMuU,KAGxB7C,MAAMkD,KAAKP,EAASQ,SAC7B,CArM0BC,CAAuB3D,GACzC9R,EAsMR,SACE8R,EACAvQ,GAEA,MAAMiT,EAAa,IAAID,GAAQzC,EAAU9R,iBAAkBuU,GAAQzC,EAAU7R,cAC7EsB,EAAgBO,QAASoT,IACnBA,EAAQjV,aAAegB,OAAOY,KAAKqT,EAAQjV,aAAa2D,KAAM7B,GAAgB,SAARA,GAA0B,aAARA,IAC1FyS,EAAW5O,KAAKsP,EAAQjV,eAG5B,MAAMD,MAAmBiV,IAQzB,OAPAT,EAAW1S,QAAQ,CAAC2G,EAAWiN,KAC7B,MAAMzV,EAAc0V,GAAwBd,GAASpM,IAC/C1G,EAAM9B,EAAYU,OAASM,OAAOY,KAAK5B,GAAagE,OAAS,WAAWyR,IAAU,IACpF3T,IAAQ/B,EAAagS,IAAIjQ,IAC3B/B,EAAasV,IAAIvT,EAAK9B,KAGnBoS,MAAMkD,KAAKvV,EAAawV,SACjC,CAzNuBI,CAAoB9D,EAAWvQ,GAE9CsU,EAAU,CACdpC,OACA9S,OACAmV,YAAanC,GAAS7B,EAAUgE,aAAehE,EAAUvR,SACzDe,OAAQqS,GAAS7B,EAAUxQ,UA+TRpC,EA/TiCkF,EAgU/C,CAAC,MAAO,MAAO,QAAQC,SAASnF,GAAQ,SAAW,IA/TxDkF,mBACAyM,UAAWA,EAAUzQ,IAAK+Q,GA8F9B,SACEA,EACAjS,EACA6W,GAEA,MAAMrC,EAAuC,CAC3C/S,KAAMgT,GAASxC,EAASxQ,OAASoV,EACjC1B,SAAU2B,GACR7E,EAASkD,WACNP,GAAW5U,GACRiS,EAASzR,aAAeyR,EAAS8E,gBAAkE,MAAhDC,OAAO/E,EAASgF,MAAQhF,EAASgD,WAClF,QACA,OACFhD,EAASmD,YACfpV,GAEFiV,UAAWiC,GAAmBjF,EAASgD,WAAahD,EAASgF,MAAQhF,EAASiD,QAE1E/S,EAAU8T,GAAmBhE,EAAS9P,SAAW8P,EAAS+C,WAC1DxU,EAAcyV,GAAmBhE,EAASzR,aAC1CuW,EAAiBtC,GAASxC,EAAS8E,gBACnClM,EAASoL,GAAmBhE,EAASpH,QACvC1I,IACFqS,EAAWrS,QAAUA,GAEnB3B,IACFgU,EAAWhU,YAAcA,GAEvBuW,IACFvC,EAAWuC,eAAiBA,GAE1BlM,IACF2J,EAAW3J,OAASA,GAEtB,OAAO2J,CACT,CAjI2C2C,CAAkBxB,GAAS1D,GAAW/M,EAAkBzD,IAC/FX,eACAuB,kBACA+R,UAAWiB,GAAQzC,EAAUwB,WAAWlT,IAAKkW,GAgNjD,SAA2BA,GACzB,MAAM1B,EAAcC,GAASyB,EAAS1B,aACtC,MAAO,CACL2B,aAAcC,GAAcF,EAASC,cACrC3B,YAAa,CACXF,eAAgBS,GAAmBP,EAAYF,gBAC/CI,UAAWP,GAAQK,EAAYE,WAAW1U,IAAKqW,IAC7C,MAAMC,EAAO7B,GAAS4B,GACtB,MAAO,CACLhC,eAAgBU,GAAmBuB,EAAKjC,gBACxCkC,MAAOH,GAAcE,EAAKC,WAKpC,CA/N8DC,CAAkB/B,GAASyB,KACrF5B,eAAgBS,GAAmBrD,EAAU4C,gBAC7C7K,QAASsL,GAAmBrD,EAAUjI,SACtCE,OAAQoL,GAAmBrD,EAAU/H,SAuTzC,IAAuB7K,EAjTrB,MAHa,SAATuU,IACFoC,EAAQgB,SAAWC,GAAW,CAAEvV,kBAAiBvB,eAAc6Q,UAAWgF,EAAQhF,aAE7EgF,CACT,CAEO,SAASkB,GAAgClB,GAC9C,MAAMmB,EAAsBjE,GAA+B8C,EAAQzR,kBAC7D+M,EAAW0E,EAAQhF,UAAU,GAC7BoG,EAAgD,CACpDzQ,cAAe,MACfsP,YAAaD,EAAQC,YACrB9B,iBAAkB6B,EAAQlV,KAC1ByD,iBAAkByR,EAAQzR,iBAC1BzD,KAAMkV,EAAQlV,KACdhB,SAAU,MACV2B,OAAQuU,EAAQvU,OAChBpC,KAAM,sBAoCR,OAjCI4U,GAAW+B,EAAQzR,kBACrB6S,EAAWpG,UAAYgF,EAAQhF,UAAUzQ,IAAK8W,GA4OlD,SACE/F,EACA6F,GAEA,MAAMC,EAA4B,CAChCtW,KAAMwQ,EAASxQ,KACfwT,UAAiC,UAAtBhD,EAASkD,SAAuB,MAAQlD,EAASgD,UAC5DE,SAAUlD,EAASkD,UAEjB2C,EAAoB3V,SAAW8P,EAAS9P,UAC1C4V,EAAW/C,UAAYiD,GAAyBhG,EAAS9P,UAEvD2V,EAAoBrV,cAAgBwP,EAASzR,cAC/CuX,EAAWvX,YAAc0X,GAAyBjG,EAASzR,cAEzDsX,EAAoBrV,cAAgBwP,EAAS8E,iBAC/CgB,EAAWhB,eAAiB9E,EAAS8E,gBAEnCe,EAAoBjN,QAAUoH,EAASpH,SACzCkN,EAAWlN,OAASsN,GAAoBlG,EAASpH,SAEnD,OAAOkN,CACT,CAjQMK,CAAkBJ,EAAiBF,IAE5B7F,IACT8F,EAAW3C,WAAanD,EAASkD,SACjC4C,EAAW9C,UAAYhD,EAASgD,WAE9B6C,EAAoB3V,UAAW,MAAA8P,SAAAA,EAAU9P,WAC3C4V,EAAW/C,UAAYiD,GAAyBhG,EAAS9P,UAEvD2V,EAAoBrV,eAAgB,MAAAwP,SAAAA,EAAUzR,eAChDuX,EAAWvX,YAAc0X,GAAyBjG,EAASzR,cAEzDsX,EAAoBhX,cAAgB6V,EAAQ7V,aAAaiE,SAC3DgT,EAAWjX,aAAe6V,EAAQ7V,aAAaI,IAAKH,IAAA,IAAsBA,MAExE+W,EAAoBzV,iBAAmBsU,EAAQtU,gBAAgB0C,SACjEgT,EAAW1V,gBAAkBsU,EAAQtU,gBAAgBnB,IAAImX,KAEvDP,EAAoB1D,WAAauC,EAAQvC,UAAUrP,SACrDgT,EAAW3D,UAAYuC,EAAQvC,UAAUlT,IAAIoX,KAE3CR,EAAoBzV,iBAAmBsU,EAAQnB,iBACjDuC,EAAWvC,eAAiB+C,GAA4B5B,EAAQnB,iBAE9DsC,EAAoBnN,SAAWgM,EAAQhM,UACzCoN,EAAWpN,QAkMf,SAA8B6N,GAC5B,OAAOA,EAAU/W,IACnB,CApMyBgX,CAAqB9B,EAAQhM,UAEhDmN,EAAoBjN,QAAU8L,EAAQ9L,SACxCkN,EAAWlN,OAASsN,GAAoBxB,EAAQ9L,SAG3CkN,CACT,CAEA,SAAShE,GAAa2E,GACpB,MAAO,CACLvW,SAAS,EACTE,iBAAiB,EACjBI,cAAc,EACd3B,cAAc,EACdsT,WAAW,EACXzJ,SAAS,EACTE,QAAQ,KACL6N,EAEP,CAOA,SAAS5B,GAAkB3G,EAAgBnQ,GACzC,MAAMwU,EAAaC,GAAStE,GAAOuE,cACnC,MAAI,CAAC,MAAO,MAAO,OAAQ,QAAS,QAAS,OAAQ,OAAOvP,SAASqP,GAC5DA,EAEI,QAATxU,EACK,MAEF4U,GAAW5U,GAAQ,OAAS,KACrC,CAuCO,SAASyW,GAAwBtG,GACtC,MAAMpP,EAAc4U,GAASxF,GACvBqE,EAA0C,IAAKzT,GAC/CC,EAAkByT,GAAS1T,EAAYC,iBAAmBD,EAAYoU,UAS5E,GARInU,IACFwT,EAAWxT,gBAAkB8V,GAAkB9V,EAAiB,YAEjE,CAAC,OAAQ,mBAAoB,aAAc,mBAAoB,sBAAgC4B,QAAS+V,SAC5E,IAAvB5X,EAAY4X,IAA+C,OAAvB5X,EAAY4X,IAA0C,KAAvB5X,EAAY4X,KACjFnE,EAAWmE,GAAS3B,OAAOjW,EAAY4X,OAGvC5X,EAAY6X,YAAa,CAC3B,MAAMA,EAAcnE,GAAS1T,EAAY6X,aACzCpE,EAAWoE,YAAcA,EAAYxJ,WAAW,KAAOwJ,EAAc,IAAIA,GAC3E,CACA,OAAOpE,CACT,CAgFA,SAASyB,GAAmB9F,GAC1B,IAAKA,EACH,OAEF,GAAqB,iBAAVA,EAAoB,CAC7B,MAAMqI,EAAY7C,GAASxF,GACrB1O,EAAOgT,GAAS+D,EAAU/W,MAAQ+W,EAAUxP,IAAMwP,EAAUrW,SAAWqW,EAAU5U,UACvF,OAAOnC,EAAQ,IAAK+W,EAAW/W,KAAAA,QAAmC,CACpE,CACA,MAAM+W,EAAY/D,GAAStE,GACrB1O,EAAO+W,EAAU3U,MAAM,KAAKtD,OAAOsY,SAASC,OAASN,EAC3D,OAAOA,EAAUrT,SAAS,KAAO,CAAE1D,OAAMmC,SAAU4U,GAAc,CAAE/W,OACrE,CAEA,SAASwW,GAAyBO,GAChC,OAAO/D,GAAS+D,EAAUrW,UAAYqW,EAAU/W,IAClD,CAEA,SAASyW,GAAyBM,GAChC,OAAOA,EAAU/W,IACnB,CAMA,SAAS0W,GAAoBK,GAC3B,OAAOA,EAAU/W,IACnB,CAEA,SAAS8W,GAA4BC,GACnC,OAAOA,EAAU/W,IACnB,CA8BA,SAAS4W,GAAwBrC,GAC/B,MAAM+B,EAA4B,IAAK/B,GAIvC,OAHIA,EAAQjV,cACVgX,EAAWhX,YA/Bf,SAAkCyX,GAChC,OAAOA,EAAU/W,IACnB,CA6B6BsX,CAAyB/C,EAAQjV,cAErDgX,CACT,CAEA,SAASO,GAAkBlB,GACzB,MAAO,CACLC,aAAc,IAAID,EAASC,cAC3B3B,YAAa,CACXF,eAAgB4B,EAAS1B,YAAYF,eACjC+C,GAA4BnB,EAAS1B,YAAYF,qBACjD,EACJI,UAAWwB,EAAS1B,YAAYE,UAAU1U,IAAKqW,IAAA,CAC7ChC,eAAgBgC,EAAShC,eAAiBgD,GAA4BhB,EAAShC,qBAAkB,EACjGkC,MAAO,IAAIF,EAASE,WAI5B,CAEA,SAASP,GAAmB/G,GAC1B,OAAOgD,MAAMC,QAAQjD,GAASA,EAAMjP,IAAI8X,QAAQzS,KAAK,KAAOkO,GAAStE,EACvE,CAMA,SAASyE,GAAW5U,GAClB,MAAgB,SAATA,GAA4B,qBAATA,CAC5B,CAEA,SAAS2V,GAASxF,GAChB,OAAOA,GAA0B,iBAAVA,EAAsBA,EAA0B,CAAA,CACzE,CAEA,SAASkF,GAAQlF,GACf,OAAIA,QACK,GAEFgD,MAAMC,QAAQjD,GAASA,EAAQ,CAACA,EACzC,CAEA,SAASsE,GAAStE,GAChB,OAAOA,QAAwC,GAAK6I,OAAO7I,EAC7D,CAEA,SAASmH,GAAcnH,GACrB,OAAOkF,GAAQlF,GAAOjP,IAAIuT,IAAUlU,OAAOsY,QAC7C,CAEA,SAASjB,GAAczH,GACrB,OAAIgD,MAAMC,QAAQjD,GACTA,EAAMjP,IAAI0W,IAEfzH,GAA0B,iBAAVA,EACXpO,OAAOkX,YAAYlX,OAAOmX,QAAQ/I,GAAOjP,IAAI,EAAE2B,EAAKsW,KAAU,CAACtW,EAAK+U,GAAWuB,MAEjFhJ,CACT,CCjgBO,MAAMiJ,GAA+E,CAC1FpF,SAAU,CAAEqF,kBAAmB,CAAC,MAAO,OAAQC,iBAAkB,CAAC,MAAO,QACzErF,IAAK,CAAEoF,kBAAmB,CAAC,OAAQC,iBAAkB,CAAC,QACtDpF,IAAK,CAAEmF,kBAAmB,CAAC,OAAQC,iBAAkB,CAAC,SAGlDC,GAAc,CAAC,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OACnFC,GAAoD,CAAC,OAAQ,QAAS,MAAO,OAC7EC,GAA2B,CAAC,OAAQ,YAAa,oBACjDC,GAA8B,CAAC,OAAQ,YAAa,kBAAmB,wBA2BtE,SAASC,GAA6BhD,GAC3C,MAAM3W,EAAO2W,EAAQzR,iBACfpD,EAASsX,GAAsBpZ,GACrC,IAAK8B,EACH,OAAO6U,EAGT,MAAMiD,EAAmBjD,EAAQhF,UAAU,IAAM,CAC/ClQ,KAAMkV,EAAQlV,KACdwT,UAAW,GACXE,SAAUrT,EAAOuX,kBAAkB,IAE/BQ,EAAmB/X,EAAOuX,kBAAkBlU,SAASyU,EAAiBzE,UACxEyE,EAAiBzE,SACjBrT,EAAOuX,kBAAkB,GACvBS,EAAkBnD,EAAQtU,gBAAgB,GAC1C0X,EACK,aAAT/Z,GACI8B,EAAOwX,iBAAiBnU,SAAS0U,GAC/BA,EAEF/X,EAAOwX,iBAAiB,GACxB/D,EAAiD,IACjDuE,GAAmB,CACrBrY,KAAMkV,EAAQlV,KACduY,SAAmB,aAATha,OAAsB,EAAY,OAC5Cia,gBAAiB,QAEnB9E,SAAU4E,GAOZ,MALyB,QAArBF,IACFtE,EAAe0E,gBAAkB,cAC1B1E,EAAe2E,sBAGjB,IACFvD,EACHvU,OAAiB,aAATpC,EAAsB2W,EAAQvU,OAAS,SAC/CuP,UAAW,CACT,IACKiI,EACHnY,KAAMmY,EAAiBnY,MAAQkV,EAAQlV,KACvCwT,UAAW2E,EAAiB3E,YAAuB,aAATjV,EAAsB,GAAK,OACrEmV,SAAU0E,IAGdxX,gBAAiB,CAACkT,GAEtB,CA4CO,SAAS4E,GAAoCxD,GApJpD,IAAA9R,EAqJE,MAAMuV,EAAmB,GACnBpa,EAAO2W,EAAQzR,iBACf+M,EAAW0E,EAAQhF,UAAU,GAC7B0I,EAAU1D,EAAQtU,gBAAgB,GAClCtB,EAAc4V,EAAQ7V,aAAa,GACnCoU,GAyUY/E,EAzUO,MAAA8B,OAAA,EAAAA,EAAUgD,UA0U5B+D,OAAO7I,GAAS,IACpBtM,MAAM,KACN3C,IAAK+V,GAASA,EAAKqD,QACnB/Z,OAAOsY,UAJZ,IAAoB1I,EAxRlB,OA/CKwG,EAAQlV,KAAK6Y,QAAQF,EAAO1T,KAAK,qBACjCiQ,EAAQC,aAAawD,EAAO1T,KAAK,wBACjCiQ,EAAQvU,QAAQgY,EAAO1T,KAAK,uBAEpB,aAAT1G,IACEkV,EAAMnQ,OAAS,GAAKmQ,EAAMnQ,OAAS,GAAKmQ,EAAMxQ,KAAMuS,IAAUsD,GAAUtD,MAC1EmD,EAAO1T,KAAK,uEAETiQ,EAAQhM,SAASyP,EAAO1T,KAAK,oDAC7BiQ,EAAQ9L,QAAQuP,EAAO1T,KAAK,oDACP,IAAjBwO,EAAMnQ,QAAiBwU,GAAYpU,SAAS+P,EAAM,KAC3DkF,EAAO1T,KAAK,GAAG1G,uFAGJ,QAATA,UAAmBiS,WAAUzR,cAAa4Z,EAAO1T,KAAK,0DACrD,MAAA2T,SAAAA,EAAS5Y,OAAM2Y,EAAO1T,KAAK,gCACnB,aAAT1G,UAAwBqa,WAASL,WAAUI,EAAO1T,KAAK,0BAC9C,aAAT1G,GAAuBwa,GAAS,MAAAH,OAAA,EAAAA,EAASI,+BAC3CL,EAAO1T,KAAK,wDAGiB,sBAA7B,MAAA2T,OAAA,EAAAA,EAASJ,kBAkUb,SAAuB9J,EAAgBuK,EAAalL,GAClD,MAAMmL,EAAS3D,OAAO7G,GACtB,OAAO6G,OAAO4D,SAASD,IAAWA,GAAUD,GAAOC,GAAUnL,CAC/D,CApUMqL,CAAcR,EAAQH,qBAAsB,EAAG,aAA2C,IAAjCG,EAAQH,sBAEnEE,EAAO1T,KAAK,8DAGT,MAAA3F,SAAAA,EAAaU,QAAS,OAAAoD,EAAA,MAAAwV,OAAA,EAAAA,EAAStZ,kBAAT,EAAA8D,EAAsBpD,OAAM2Y,EAAO1T,KAAK,kCAC/D3F,IACGwZ,GAAUxZ,EAAYkW,OAAOmD,EAAO1T,KAAK,kDAEX,SAAhC3F,EAAYC,iBAA8D,UAAhCD,EAAYC,iBACtDD,EAAY6X,aAEbwB,EAAO1T,KAAK,wDAEV8T,GAASzZ,EAAY+Z,aAAaV,EAAO1T,KAAK,sDACb,IAAjC3F,EAAYga,kBAAkC/D,OAAOjW,EAAYga,mBAAqB,GACxFX,EAAO1T,KAAK,yDAEuB,IAAjC3F,EAAYia,kBAAkChE,OAAOjW,EAAYia,mBAAqB,GACxFZ,EAAO1T,KAAK,qDAEyB,IAAnC3F,EAAYka,oBAAoCjE,OAAOjW,EAAYka,qBAAuB,GAC5Fb,EAAO1T,KAAK,mDAGT0T,CACT,CAEO,SAASc,IAA2BvE,QACzCA,EAAA3R,KACAA,EAAAmW,SACAA,GAAW,EAAAC,SACXA,IAlNF,IAAAvW,EAAAsE,EAAAe,EAAAC,EAAAkR,EAoNE,MAAMC,EAAc3B,GAA6BhD,GAC3C3W,EAAOsb,EAAYpW,iBACnB+M,EAAWqJ,EAAY3J,UAAU,GACjC0I,EAAUiB,EAAYjZ,gBAAgB,GACtCtB,EAAcua,EAAYxa,aAAa,IAAO,CAAEE,gBAAiB,OACjEua,EA/GD,SACL5E,EACA3R,GA5GF,IAAAH,EA8GE,MAAMoN,EAAW0E,EAAQhF,UAAU,GAC7B0I,EAAU1D,EAAQtU,gBAAgB,GAClCmZ,EAAiBC,GACrBA,EAAMlb,OAAQ4Y,IACXA,EAAK9X,UAAY8X,EAAKvC,cAAsBuC,EAAK9X,SAAW8X,EAAKvC,eAAiBD,EAAQC,aAEzF8E,EAAkBD,GACtBD,EAAcC,GAAOlb,OAAQ4Y,IAAUA,EAAK/W,QAAU+W,EAAK/W,SAAWuU,EAAQvU,QAC1EuZ,EAAc,OAAA9W,EAAA8R,EAAQhM,cAAR,EAAA9F,EAAiBpD,KAC/Bma,EAAeJ,EAAcxW,EAAKsM,SAAgC/Q,OAAQ4Y,IAvHlF,IAAAtU,EAwHI,MAAMgX,EAAsC,iBAAjB1C,EAAKxO,QAAuBwO,EAAKxO,QAAU,OAAA9F,EAAAsU,EAAKxO,cAAL,EAAA9F,EAAcpD,KACpF,QAAS0X,EAAK/W,QAAU+W,EAAK/W,SAAWuU,EAAQvU,QAAayZ,GAAeA,IAAgBF,KAG9F,MAAO,CACLxK,SAAUnM,EAAKmM,SACflP,UAAWyQ,GACTgJ,EAAe1W,EAAK/C,WACpB6Z,SAAW7J,WAAU9P,UAEvBE,gBAAiBqQ,GACfgJ,EAAe1W,EAAK3C,iBACpByZ,GAAWzB,IAEb5X,aAAciQ,GACZ8I,EAAcxW,EAAKvC,cACnBqZ,SAAW7J,WAAUzR,cAEvBM,aAAc4R,GACZ8I,EAAcxW,EAAKlE,cACnBgb,SAAWzB,WAAStZ,cAEtBqQ,SAAUsB,GAAwB8I,EAAcxW,EAAKoM,UAAkC0K,GAAWnF,EAAQhM,UAC1G0G,QAASrM,EAAKqM,QACdC,QAASoB,GAAwBkJ,EAAcE,GAAWnF,EAAQ9L,SAEtE,CAuEkBkR,CAA2BT,EAAatW,GAClDgX,EACK,aAAThc,EAC0B,QAAtBiS,EAASkD,SACP,CAAC,QACDuE,GACFD,GAEAwC,EAAUC,GACdd,EAASzB,GAA6B,IAAK2B,KAAgBY,KACvDC,EAAkBD,GACtBD,EAAO,CAAEtK,UAAW,CAAC,IAAKM,KAAaiK,MACnCE,EAAiBF,GACrBD,EAAO,CAAE5Z,gBAAiB,CAAC,IAAKgY,KAAY6B,MACxCG,EAAqBH,GACzBD,EAAO,CAAEnb,aAAc,CAAC,IAAKC,KAAgBmb,MAmB/C,OACE5Y,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,kDACZ0Q,GAAU,OAAQ,OAAQhB,EAAY7Z,KApBvBA,GAClBwa,EAAO,CACLxa,OACAkQ,UAAW,CAAC,IAAKM,EAAUxQ,KAAMwQ,EAASxQ,OAAS6Z,EAAY7Z,KAAOA,EAAOwQ,EAASxQ,OACtFY,gBAAiB,CAAC,IAAKgY,EAAS5Y,KAAM4Y,EAAQ5Y,OAAS6Z,EAAY7Z,KAAOA,EAAO4Y,EAAQ5Y,SAgBhC0Z,GACxDoB,GACC,UACA,cACAjB,EAAY1E,YACZ2E,EAAQpK,SACPyF,GAAgBqF,EAAO,CAAErF,gBAC1BuE,GAEQ,aAATnb,EACGuc,GAAY,SAAU,SAAUjB,EAAYlZ,OAAQmZ,EAAQlK,QAAUjP,GAAW6Z,EAAO,CAAE7Z,WAAW+Y,GACrGmB,GAAU,SAAU,SAAUhB,EAAYlZ,OAAQ,QAAiB,GAC7D,aAATpC,GACCuc,GACE,UACA,UACA,OAAA1X,EAAAyW,EAAY3Q,cAAZ,EAAA9F,EAAqBpD,KACrB8Z,EAAQnK,SACP3P,GAASwa,EAAO,CAAEtR,QAAS6N,GAAU/W,GAAOoJ,YAAQ,IACrDsQ,GAEM,aAATnb,GACCuc,GACE,SACA,SACA,OAAApT,EAAAmS,EAAYzQ,aAAZ,EAAA1B,EAAoB1H,KACpB8Z,EAAQjK,QACP7P,GAASwa,EAAO,CAAEpR,OAAQ2N,GAAU/W,KACrC0Z,GAEHoB,GACC,UACA,UACA,OAAArS,EAAA+H,EAAS9P,cAAT,EAAA+H,EAAkBzI,KAClB8Z,EAAQtZ,UACPR,GAAS0a,EAAe,CAAEha,QAASqa,GAAiB/a,EAAM8Z,EAAQtZ,aACnEkZ,GAEDoB,GACC,WACA,WACAtK,EAASkD,SACTiE,GAAsBpZ,GAAMqZ,kBAAkBnY,IAAKO,IAAA,CAAYA,UAC9D0T,GAAagH,EAAe,CAAEhH,aAC/BgG,GAAqE,IAAzD/B,GAAsBpZ,GAAMqZ,kBAAkBtU,QAElD,aAAT/E,EACGsc,GACE,iBACA,YACArK,EAASgD,UACRA,GAAckH,EAAe,CAAElH,cAChCkG,GAEFoB,GACE,gBACA,YACAtK,EAASgD,UACTsE,GAAYrY,IAAKO,IAAA,CAAYA,UAC5BwT,GAAckH,EAAe,CAAElH,cAChCkG,GAEI,QAATnb,GACCuc,GAAY,cAAe,cAAe,OAAApS,EAAA8H,EAASzR,kBAAT,EAAA2J,EAAsB1I,KAAM8Z,EAAQ9Y,aAAehB,GAC3F0a,EAAe,CAAE3b,YAAagY,GAAU/W,MAG5C6B,GAAAyE,cAAC,KAAA,KAAG,mBACHwU,GACC,kBACA,iBACAlC,EAAQ5Y,KACR8Z,EAAQlZ,gBACPZ,GAAS2a,EAAc,CAAE3a,SAC1B0Z,GACA,GAEQ,aAATnb,GACCsc,GAAU,YAAa,WAAYtD,OAAOqB,EAAQL,UAAY,IAAMA,GAAaoC,EAAc,CAAEpC,cACzF,aAATha,GACCyc,GACE,8BACA,+BACApC,EAAQI,6BACPA,GAAiC2B,EAAc,CAAE3B,kCAErD8B,GACC,mBACA,kBACAvD,OAAOqB,EAAQJ,iBAAmB,QAClC+B,EAAkB9a,IAAKO,IAAA,CAAYA,UAClCwY,GAAoBmC,EAAc,CAAEnC,qBAEV,qBAA5BI,EAAQJ,iBACPwC,GACE,sBACA,uBACApC,EAAQH,qBACPA,GAAyBkC,EAAc,CAAElC,0BAG9C5W,GAAAyE,cAAC,KAAA,KAAG,gBACHwU,GACC,wBACA,cACA,OAAAlB,EAAAhB,EAAQtZ,kBAAR,EAAAsa,EAAqB5Z,KACrB8Z,EAAQza,aAxHaW,IACzB,IAAKA,EAAM,OAAO2a,EAAc,CAAErb,iBAAa,IAC/C,MACMA,EAAc0V,GADH8E,EAAQza,aAAawI,KAAMoT,GAAsBA,EAAkBjb,OAASA,IACrC,CAAEA,SACpDmC,EAA2C,iBAAzB7C,EAAY6C,SAAwB7C,EAAY6C,cAAW,EAC7E+Y,EAAuB,CAC3Blb,UACImC,EAAW,CAAEA,YAAa,CAAA,GAEhCqY,EAAO,CAAE5Z,gBAAiB,CAAC,IAAKgY,EAAStZ,YAAa4b,IAAyB7b,aAAc,CAACC,OAkH3Fwb,GACC,wBACA,kBACAxb,EAAYC,gBACZwY,GAAuBtY,IAAKO,IAAA,CAAYA,UACvCT,GACCqb,EAAkB,CAChBrb,qBAGLsb,GAAU,oBAAqB,kBAAmBvb,EAAYU,MAAQ,GAAKA,GAAS4a,EAAkB,CAAE5a,WACvE,SAAhCV,EAAYC,iBAA8D,UAAhCD,EAAYC,kBACtDsb,GAAU,eAAgB,cAAevb,EAAY6X,aAAe,GAAKA,GACvEyD,EAAkB,CAAEzD,iBAEvB6D,GAAY,oBAAqB,kBAAmB1b,EAAYkW,KAAOA,GAASoF,EAAkB,CAAEpF,UACpGwF,GAAY,UAAW,aAAc1b,EAAY+Z,WAAaA,GAAeuB,EAAkB,CAAEvB,gBACjG2B,GAAY,WAAY,mBAAoB1b,EAAYga,iBAAmBA,GAC1EsB,EAAkB,CAAEtB,sBAErB0B,GAAY,oBAAqB,mBAAoB1b,EAAYia,iBAAmBA,GACnFqB,EAAkB,CAAErB,sBAErByB,GAAY,sBAAuB,qBAAsB1b,EAAYka,mBAAqBA,GACzFoB,EAAkB,CAAEpB,wBAI5B,CAEA,SAASqB,GACP3V,EACAgS,EACAxI,EACAiL,EACAD,GAAW,GAEX,OACE7X,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVuP,WACAC,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3CA,MAAOA,GAAS,MAK1B,CAEA,SAASsM,GACP9V,EACAgS,EACAxI,EACAiL,GAEA,OACE9X,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV5L,KAAK,SACLmQ,MAAOA,QAAwC,GAAK6I,OAAO7I,GAC3DiL,SAAWwB,GAAUxB,EAAgC,KAAvBwB,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,WAKpG,CAEA,SAASoM,GACP5V,EACAgS,EACAxI,EACAoL,EACAH,EACAD,GAAW,EACX0B,GAAmB,GAEnB,MAAMC,EAAQvB,EAAQra,IAAI,EAAGO,UAAWA,GAExC,OADIob,GAAoB1M,IAAU2M,EAAM3X,SAASgL,IAAQ2M,EAAMpW,KAAKyJ,GAElE7M,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACVuP,WACAC,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3CA,MAAOA,GAAS,IAEhB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChB2M,EAAM5b,IAAKO,GACV6B,GAAAyE,cAAC,SAAA,CAAOlF,IAAKpB,EAAM0O,MAAO1O,GACvBA,MAOf,CAEA,SAASqa,GAA+CiB,GACtD,OAAO,MAAAA,OAAA,EAAAA,EAAgBtb,MAAO,CAACsb,GAAkB,EACnD,CAEA,SAASvE,GAAU/W,GACjB,OAAOA,EAAO,CAAEA,aAAS,CAC3B,CAEA,SAAS+a,GACP/a,EACA8Z,GAEA,OAAO9Z,EAAS8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,aAAoC,CAC1G,CASA,SAAS8Y,GAAUpK,GACjB,MAAM8G,EAAOD,OAAO7G,GACpB,OAAO6G,OAAOiG,UAAUhG,IAASA,GAAQ,GAAKA,GAAQ,KACxD,CAEA,SAASuD,GAASrK,GAChB,OAAOA,SAAyC6G,OAAO7G,GAAS,CAClE,CClaO,SAAS+M,GAAqCvG,GA/ErD,IAAA9R,EAAAsE,EAgFE,MAAMmS,EAAc3B,GAA6BhD,GAC3CoB,EAAaF,GAAgCyD,GAC7C6B,EAAgB7B,EAAYjZ,gBAAgB,IAAO,CAAEZ,KAAM6Z,EAAY7Z,MACvE8T,EAAgC,IAAK4H,GACrCpc,EAAcua,EAAYxa,aAAa,IAAMqc,EAAcpc,YAuJnE,IAAoBoP,EArIlB,cAhBOoF,EAAeJ,SACtBI,EAAeJ,cAAW,EAC1BI,EAAexU,YAAcA,EAAc,IAAKA,QAAgB,EAChEwU,EAAe9T,KAAO8T,EAAe9T,MAAQ6Z,EAAY7Z,KACzDsW,EAAWxC,eAAiBA,SACrBwC,EAAW1V,uBACX0V,EAAWjX,aAEmB,aAAjCwa,EAAYpW,kBACd6S,EAAW3C,YAAa,OAAAvQ,EAAAyW,EAAY3J,UAAU,aAAIwD,WAAY,MAC9D4C,EAAW7C,OA2IK/E,EA3Ic,OAAAhH,EAAAmS,EAAY3J,UAAU,aAAIsD,UA4InD+D,OAAO7I,GAAS,IACpBtM,MAAM,KACN3C,IAAK+V,GAASA,EAAKqD,QACnB/Z,OAAOsY,iBA9IDd,EAAW9C,WAElB8C,EAAW3C,WAAa4D,OAAOmE,EAAchI,UAAY,OAGpD4C,CACT,CAkBA,SAASqF,GAAmCjV,GAzH5C,IAAAtD,EA0HE,MAAMqB,EAAeiC,EAAMjC,aAAeiC,EAAMvD,IAC1C2P,EAAkCpM,EAAMkV,kBAC1C,YACgB,IAAhBlV,EAAMmV,MACN,OACA,SACEtd,EAsGR,SAA0BmQ,GACxB,MAAMnQ,EAAOgZ,OAAO7I,GAAS,IAAIuE,cACjC,MAAgB,aAAT1U,GAAgC,QAATA,GAA2B,QAATA,EAAiBA,EAAO,KAC1E,CAzGeud,CAAiBpV,EAAMjD,mBAAoB,OAAAL,EAAAsD,EAAMlD,uBAAcC,oBACrEyR,EAAS6G,GAAcla,GAAM+E,SAAS,IA3ExC,SACLuK,EACA2B,EACArP,EACAuY,EAAkB,IA1DpB,IAAA5Y,EAAAsE,EAAAe,EA4DE,MAAMwT,EAAS9K,GAAa,CAAA,EACtB2C,EAAiBmI,EAAOnI,iBAAkB,OAAA1Q,EAAA6Y,EAAOrb,sBAAP,EAAAwC,EAAyB,IACnE8Y,EAAoB,MAAApI,OAAA,EAAAA,EAAgBxU,YASpCyT,EAAaF,GARqB,IACnCoJ,EACHrb,gBAAiBkT,EAAiB,CAAC,IAAKA,IAAoBmI,EAAOrb,gBACnEvB,cAAc,OAAAqI,EAAAuU,EAAO5c,mBAAP,EAAAqI,EAAqBpE,QAAS2Y,EAAO5c,aAAe6c,EAAoB,CAACA,GAAqB,GAC5GzY,mBACAzD,KAAMic,EAAOjc,MAAQic,EAAO5I,kBAAoB2I,GAGmBlJ,GACrE,GAAI,OAAArK,EAAAsK,EAAWnS,gBAAgB,aAAItB,YAAa,CAC9C,MAAMU,KAAEA,EAAAmC,SAAMA,GAAa4Q,EAAWnS,gBAAgB,GAAGtB,YACzDyT,EAAWnS,gBAAgB,GAAGtB,YAAc6C,EAAW,CAAEnC,OAAMmC,YAAa,CAAEnC,OAChF,CACA,OAAOkY,GAA6BnF,EACtC,CAqDIoJ,CAAqCzV,EAAMlD,aAAcsP,EAAMvU,QAAMkG,WAAazE,OAE9Eoc,EC3HD,SACLxc,EACAmQ,EAAuCC,IAEvC,MAAMqM,EAAgBC,GAA6C,MAC9DD,EAAcE,UACjBF,EAAcE,QAAU,IAAIzM,GAA8BC,IAE5D,MAAMyM,EAAaH,EAAcE,SAC1BxZ,EAAO0Z,GAAY7V,GAAoC4V,EAAWlM,YAczE,OAZAoM,GAAU,KACR,MAAMC,EAAcH,EAAWjM,UAAUkM,GACzC,MAAO,KACLE,IACAH,EAAWzL,YAEZ,CAACyL,IAEJE,GAAU,KACRF,EAAW7L,KAAK/Q,IACf,CAACA,EAAS4c,IAEN,IAAKzZ,EAAO6Z,QAAS,IAAMJ,EAAW7L,KAAK/Q,GACpD,CDmGoBid,CAAuB3H,EAAQC,YAAazO,EAAMqJ,SAC9D+M,EAAgCjb,GAAMya,SACtCS,EAAclb,GAAMya,QAAO,IAC1BU,GAAenb,GAAM+E,SAC1B,IACE,IAAIqW,EAAY,CACdxY,cACAN,OAAmB,SAAT2O,EAAkB,WAAa,YAAlC,sBACPoK,UAAW,KA5InB,IAAA9Z,EA4IyB,OAAA,OAAAA,EAAAsD,EAAMyW,qBAAN/Z,EAAAga,KAAA1W,IACjBhC,eAAgB,KA7IxB,IAAAtB,EAAAsE,EAAAe,EA8IUhK,EAAqB4e,WAAW,gBAChC,MAAMha,SAAiBoB,WAAqBpB,iBAAiB,OAAAD,QAAAqB,WAAa6Y,oBAAb,EAAAla,EAAAga,KAAA3Y,EAA6B,kBACpF8Y,EAAQ,KAhJxB,IAAAna,EAAAsE,EAiJY,OAAAtE,EAAA0Z,EAA8BP,UAA9BnZ,EAAAga,KAAAN,GACAA,EAA8BP,aAAU,EACpCQ,EAAYR,SAGhB,OAAA7U,EAAAhB,EAAM8W,aAAN9V,EAAA0V,KAAA1W,WAEErD,WAAeoa,gBACjB,OAAA/V,EAAAoV,EAA8BP,UAA9B7U,EAAA0V,KAAAN,GACAA,EAA8BP,aAAU,EACxCO,EAA8BP,QAAUlZ,EAAcoa,cAAcF,GACpE,OAAA9U,EAAApF,EAAcuZ,UAAdnU,EAAA2U,KAAA/Z,IAEAka,QAKV1b,GAAM6a,UACJ,IAAM,KApKV,IAAAtZ,EAqKM2Z,EAAYR,SAAU,EACtB,OAAAnZ,EAAA0Z,EAA8BP,UAA9BnZ,EAAAga,KAAAN,GACAA,EAA8BP,aAAU,GAE1C,IAEF,MAAM5D,EAASD,GAAoCxD,GAC7CwI,EAAaV,EAAYU,WACzB/S,EACK,WAATmI,EACI,UAAUvU,kBACD,aAATuU,EACA,aAAavU,kBACb,QAAQ2W,EAAQlV,OAItB,OACE6B,GAAAyE,cAAC,OAAI6D,UAAU,kCACZwT,EAAA,CAAmBC,QAASZ,IAC7Bnb,GAAAyE,cAACuX,GAAWC,QAASpX,EAAMyW,eAC3Btb,GAAAyE,cAAC,OAAI6D,UAAU,iCACZ,KAAA,KAAIQ,IAEP9I,GAAAyE,cAAC,OAAI6D,UAAU,cACS,YAArBiS,EAAU/L,yBAAyB0N,EAAA,CAAQvQ,KAAK,UAC3B,UAArB4O,EAAU/L,QACTxO,GAAAyE,cAAC,OAAI6D,UAAU,sBAAqB,+CAEtCtI,GAAAyE,cAACmT,GAAA,CACCvE,UACA3R,KAAM6Y,EAAU7Y,KAChBmW,SAAmB,SAAT5G,EACV6G,SAAUoC,MAETpD,EAAOrV,yBACP,MAAA,CAAI6G,UAAU,kDACZwO,EAAOlZ,IAAK2O,oBACV,MAAA,CAAIhN,IAAKgN,GAAQA,MAK1BvM,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iCACZ,SAAA,CAAOA,UAAU,kBAAkBuP,SAAUgE,EAAYM,QAAStX,EAAMyW,aAAc5e,KAAK,UAAS,UAGrGsD,GAAAyE,cAAC2X,EAAA,CACCjW,aAAc2Q,EAAOrV,QAA+B,YAArB8Y,EAAU/L,QAAwBqN,EACjEQ,cAAc,EACdhZ,MAAgB,aAAT4N,EAAsB,OAAkB,SAATA,EAAkB,SAAW,SACnEkL,QArCO,IA1EV,SACL9I,GACAzQ,YAAEA,EAAA+Y,WAAaA,EAAAR,YAAYA,IAE3B,MAAMmB,EAAU1C,GAAqCvG,GACrD,GAAqB,aAAjBA,EAAQpC,KAEV,YADA,MAAA0K,GAAAA,EAAaW,IAIf,MAAMC,EAA8B,SAAjBlJ,EAAQpC,KAAkB,SAAW,SACxDkK,EAAYqB,OAAO,IACjBC,EAAmBC,mBAAmBJ,EAAgB1Z,EAAa2Z,EAAY,CAAE9e,YAAa,KAElG,CA6DIkf,CAAkCtJ,EAAS,CAAEzQ,cAAa+Y,WAAY9W,EAAM8W,WAAYR,gBAqClFU,gBAKV,CAEO,MAAMe,GAA4Bne,OAAOsO,OAAO+M,GAAoC,CACzF+C,KAAOhY,GACLiY,EAAWD,KAAK/C,GAAoCjV,EAAO,CAAEkY,gBAAiB,aAChFC,wBAAwB,IEhN1B,SAASC,GAAkB9e,EAAc8Z,GACvC,GAAK9Z,EAGL,OAAQ8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,OAC9D,CAEO,SAAS+e,IAAkCve,UAChDA,EAAAQ,aACAA,EAAAwP,SACAA,EAAA/M,iBACAA,EAAAkW,SACAA,EAAAqF,SACAA,EAAAnP,QACAA,IAjCF,IAAAzM,EAAAsE,EAAAe,EAqCE,OACE5G,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,qBAClBtI,GAAAyE,cAAC,cAAO,YACRzE,GAAAyE,cAAC,QAAA,KAAM,OAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,gBACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAO8B,EAASxQ,KAChB2Z,SAAWwB,GAAUxB,EAAS,IAAKnJ,EAAUxQ,KAAMmb,EAAMlQ,OAAOyD,WAGpE7M,GAAAyE,cAAC,QAAA,KAAM,WAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,oBACZoI,MAAO8B,EAASkD,SAChBiG,SAAWwB,IACT,MAAMzH,EAAWyH,EAAMlQ,OAAOyD,MAC9BiL,EAAS,IAAKnJ,KAA2B,UAAbkD,EAAuB,CAAEF,UAAW,OAAU,CAAA,EAAKE,eAtBvE,CAAC,OAAQ,SAyBRjU,IAAKiU,GACd7R,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsS,EAAUhF,MAAOgF,GAC3BA,MAKT7R,GAAAyE,cAAC,QAAA,KAAM,OAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,gBACZoT,SAAgC,UAAtBlJ,EAASkD,SACnBuL,UAAQ,EACR1gB,KAAK,OACLmQ,MAAO8B,EAASgD,UAChBmG,SAAWwB,GAAUxB,EAAS,IAAKnJ,EAAUgD,UAAW2H,EAAMlQ,OAAOyD,WAGnD,qBAArBjL,GACC5B,GAAAyE,cAAC,aAAM,SAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,kBACZ2Y,UAAQ,EACRvQ,OAAO,OAAAtL,EAAAoN,EAASpH,aAAT,EAAAhG,EAAiBpD,OAAQ,GAChC2Z,SAAWwB,GAAUxB,EAAS,IAAKnJ,EAAUpH,OAAQ0V,GAAkB3D,EAAMlQ,OAAOyD,MAAOmB,MAE3FhO,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBmB,EAAQpQ,IAAK2J,oBACX,SAAA,CAAOhI,IAAKgI,EAAOpJ,KAAM0O,MAAOtF,EAAOpJ,MACrCoJ,EAAOpJ,SAMlB6B,GAAAyE,cAAC,aACuB,qBAArB7C,EAA0C,cAAgB,cAC3D5B,GAAAyE,cAAC,SAAA,CACC,cAAY,mBACZoI,OAAO,OAAAhH,EAAA8I,EAAS9P,cAAT,EAAAgH,EAAkB1H,OAAQ,GACjC2Z,SAAWwB,GAAUxB,EAAS,IAAKnJ,EAAU9P,QAASoe,GAAkB3D,EAAMlQ,OAAOyD,MAAOlO,MAE5FqB,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBlO,EAAUf,IAAKiB,oBACb,SAAA,CAAOU,IAAKV,EAAQV,KAAM0O,MAAOhO,EAAQV,MACvCU,EAAQV,SAKM,UAAtBwQ,EAASkD,UACR7R,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,aAAM,cAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,uBACZoI,OAAO,OAAAjG,EAAA+H,EAASzR,kBAAT,EAAA0J,EAAsBzI,OAAQ,GACrC2Z,SAAWwB,GACTxB,EAAS,IACJnJ,EACHzR,YAAa+f,GAAkB3D,EAAMlQ,OAAOyD,MAAO1N,GACnDsU,oBAAgB,KAIpBzT,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChB1N,EAAavB,IAAKV,oBAChB,SAAA,CAAOqC,IAAKrC,EAAYiB,KAAM0O,MAAO3P,EAAYiB,MAC/CjB,EAAYiB,SAKrB6B,GAAAyE,cAAC,QAAA,KAAM,kBAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,2BACZ/H,KAAK,OACLmQ,MAAO8B,EAAS8E,gBAAkB,GAClCqE,SAAWwB,GACTxB,EAAS,IAAKnJ,EAAUzR,iBAAa,EAAWuW,eAAgB6F,EAAMlQ,OAAOyD,YAAS,QAMhG7M,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAASgB,GAAU,mBAKlF,CC9IA,SAASE,GAAYxQ,GACnB,MAAiB,KAAVA,SAA2B6G,OAAO7G,EAC3C,CAEA,SAASoQ,GAAkB9e,EAAc8Z,GACvC,GAAK9Z,EAGL,OAAQ8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,OAC9D,CASO,SAASmf,IAAqC7f,YACnDA,EAAAD,aACAA,EAAAsa,SACAA,EAAAqF,SACAA,IAhCF,IAAA5b,EAkCE,MAAMgc,EAAe,CAAClI,EAAexI,IACnCiL,EAAS,IAAKra,EAAa4X,CAACA,GAAQgI,GAAYxQ,KAElD,OACE7M,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,yBAClBtI,GAAAyE,cAAC,cAAO,gBACRzE,GAAAyE,cAAC,QAAA,KAAM,wBAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,yBACZoI,MAAOpP,EAAYU,MAAQ,GAC3B2Z,SAAWwB,IACT,MAAMkE,EAAWhgB,EAAawI,KAAK,EAAG7H,UAAWA,IAASmb,EAAMlQ,OAAOyD,OACvEiL,EAAS0F,EAAY,IAAKA,GAA6C,IAAK/f,EAAaU,KAAM,OAGjG6B,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,iBAChBrP,EAAaI,IAAK8b,oBAChB,SAAA,CAAOna,IAAKma,EAAOvb,KAAM0O,MAAO6M,EAAOvb,MACrCub,EAAOvb,SAKhB6B,GAAAyE,cAAC,QAAA,KAAM,WAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,wBACZoI,MAAOpP,EAAYC,iBAAmB,OACtCoa,SAAWwB,GACTxB,EAAS,IACJra,EACHC,gBAAiB4b,EAAMlQ,OAAOyD,SAIjC,CAAC,OAAQ,QAAS,QAAS,OAAQ,MAAO,OAAOjP,IAAKiU,oBACpD,SAAA,CAAOtS,IAAKsS,EAAUhF,MAAOgF,GAC3BA,MAKT7R,GAAAyE,cAAC,QAAA,KAAM,OAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,oBACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAOpP,EAAYU,MAAQ,GAC3B2Z,SAAWwB,GAAUxB,EAAS,IAAKra,EAAaU,KAAMmb,EAAMlQ,OAAOyD,YAGrC,SAAhCpP,EAAYC,iBACoB,UAAhCD,EAAYC,iBACoB,UAAhCD,EAAYC,kBACZsC,GAAAyE,cAAC,aAAM,eAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,oBACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAOpP,EAAY6X,aAAe,GAClCwC,SAAWwB,GAAUxB,EAAS,IAAKra,EAAa6X,YAAagE,EAAMlQ,OAAOyD,WAI/C,SAAhCpP,EAAYC,iBACXsC,GAAAyE,cAAC,aAAM,eAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,iCACZ/H,KAAK,OACLmQ,MAAOpP,EAAYggB,iBAAmB,GACtC3F,SAAWwB,GAAUxB,EAAS,IAAKra,EAAaggB,gBAAiBnE,EAAMlQ,OAAOyD,WAIpF7M,GAAAyE,cAAC,QAAA,KAAM,OAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,oBACZyH,IAAK,MACLkL,IAAK,EACLgG,UAAQ,EACR1gB,KAAK,SACLmQ,MAAO,OAAAtL,EAAA9D,EAAYkW,MAAZpS,EAAoB,GAC3BuW,SAAWwB,GAAUiE,EAAa,OAAQjE,EAAMlQ,OAAOyD,UAG1D,CACC,CAAC,aAAc,WACf,CAAC,mBAAoB,YACrB,CAAC,mBAAoB,qBACrB,CAAC,qBAAsB,wBACvBjP,IAAI,EAAEyX,EAAOhS,MAjIrB,IAAA9B,EAkIQ,OAAAvB,GAAAyE,cAAC,QAAA,CAAMlF,IAAK8V,GACThS,EACDrD,GAAAyE,cAAC,QAAA,CACC,cAAa,gBAAgB4Q,IAC7B+B,IAAK,EACL1a,KAAK,SACLmQ,MAAQ,OAAAtL,EAAA9D,EAAY4X,IAAZ9T,EAA6C,GACrDuW,SAAWwB,GAAUiE,EAAalI,EAAOiE,EAAMlQ,OAAOyD,YAI5D7M,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAASgB,GAAU,uBAKlF,CAWO,SAASO,IAAwCzL,eACtDA,EAAAlT,gBACAA,EAAAvB,aACAA,EAAAoE,iBACAA,EAAAkW,SACAA,EAAAqF,SACAA,IAnKF,IAAA5b,EAAAsE,EAAAe,EAqKE,OACE5G,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,4BAClBtI,GAAAyE,cAAC,cAAO,mBACRzE,GAAAyE,cAAC,QAAA,KAAM,2BAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,4BACZoI,MAAOoF,EAAe9T,KACtB2Z,SAAWwB,IACT,MAAMkE,EAAWze,EAAgBiH,KAAK,EAAG7H,UAAWA,IAASmb,EAAMlQ,OAAOyD,OAC1EiL,EAAS0F,EAAY,IAAKA,GAAgD,IAAKvL,EAAgB9T,KAAM,OAGvG6B,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,iBAChB9N,EAAgBnB,IAAK8b,oBACnB,SAAA,CAAOna,IAAKma,EAAOvb,KAAM0O,MAAO6M,EAAOvb,MACrCub,EAAOvb,SAKhB6B,GAAAyE,cAAC,QAAA,KAAM,OAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,uBACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAOoF,EAAe9T,KACtB2Z,SAAWwB,GAAUxB,EAAS,IAAK7F,EAAgB9T,KAAMmb,EAAMlQ,OAAOyD,WAG1E7M,GAAAyE,cAAC,QAAA,KAAM,eAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,+BACZ2Y,UAAQ,EACRvQ,OAAO,OAAAtL,EAAA0Q,EAAexU,kBAAf,EAAA8D,EAA4BpD,OAAQ,GAC3C2Z,SAAWwB,GACTxB,EAAS,IACJ7F,EACHxU,YAAawf,GAAkB3D,EAAMlQ,OAAOyD,MAAOrP,MAIvDwC,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBrP,EAAaI,IAAK8b,oBAChB,SAAA,CAAOna,IAAKma,EAAOvb,KAAM0O,MAAO6M,EAAOvb,MACrCub,EAAOvb,SAKhB6B,GAAAyE,cAAC,QAAA,KAAM,mBAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,mCACZoI,MAAO6I,OAAOzD,EAAe0E,iBAAmB,QAChDmB,SAAWwB,GAAUxB,EAAS,IAAK7F,EAAgB0E,gBAAiB2C,EAAMlQ,OAAOyD,SAEhF,CAAC,OAAQ,YAAa,mBAAoB,eAAgB,eAAejP,IAAK+f,oBAC5E,SAAA,CAAOpe,IAAKoe,EAAU9Q,MAAO8Q,GAC3BA,MAKT3d,GAAAyE,cAAC,QAAA,KAAM,YAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,4BACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAO6I,OAAOzD,EAAeyE,UAAY,IACzCoB,SAAWwB,GAAUxB,EAAS,IAAK7F,EAAgByE,SAAU4C,EAAMlQ,OAAOyD,WAG9E7M,GAAAyE,cAAC,QAAA,KAAM,8BAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,2BACZ2S,IAAK,EACL1a,KAAK,SACLmQ,MAAQ,OAAAhH,EAAAoM,EAAekF,8BAAftR,EAAsE,GAC9EiS,SAAWwB,GACTxB,EAAS,IAAK7F,EAAgBkF,6BAA8BkG,GAAY/D,EAAMlQ,OAAOyD,YAIrE,SAArBjL,oBACE,QAAA,KACC5B,GAAAyE,cAAC,QAAA,CACC,cAAY,sBACZmZ,QAASrI,QAAQtD,EAAe4L,WAChCnhB,KAAK,WACLob,SAAWwB,GAAUxB,EAAS,IAAK7F,EAAgB4L,UAAWvE,EAAMlQ,OAAOwU,YAC3E,cAI8B,qBAAnC3L,EAAe0E,iBACd3W,GAAAyE,cAAC,aAAM,8BAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,6BACZyH,IAAK,MACLkL,IAAK,EACLgG,UAAQ,EACR1gB,KAAK,SACLmQ,MAAQ,OAAAjG,EAAAqL,EAAe2E,sBAAfhQ,EAA8D,GACtEkR,SAAWwB,GAAUxB,EAAS,IAAK7F,EAAgB2E,qBAAsByG,GAAY/D,EAAMlQ,OAAOyD,YAIxG7M,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAASgB,GAAU,0BAKlF,CClRA,SAASW,GAAUjR,GACjB,OAAOA,EACJtM,MAAM,SACN3C,IAAKiY,GAASA,EAAKmB,QACnB/Z,OAAOsY,QACZ,CAEA,SAAS0H,GAAkB9e,EAAc8Z,GACvC,GAAK9Z,EAGL,OAAQ8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,OAC9D,CASO,SAAS4f,IAAkChf,gBAChDA,EAAA+Y,SACAA,EAAAqF,SACAA,EAAAlJ,SACAA,IAlCF,IAAA1S,EAoCE,OACEvB,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,sBAClBtI,GAAAyE,cAAC,cAAO,aACRzE,GAAAyE,cAAC,QAAA,KAAM,QAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,kBACZ2Y,UAAQ,EACR1gB,KAAK,OACLmQ,MAAOoH,EAASE,MAAMlR,KAAK,MAC3B6U,SAAWwB,GAAUxB,EAAS,IAAK7D,EAAUE,MAAO2J,GAAUxE,EAAMlQ,OAAOyD,YAG/E7M,GAAAyE,cAAC,QAAA,KAAM,kBAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,oBACZ2Y,UAAQ,EACRvQ,OAAO,OAAAtL,EAAA0S,EAAShC,qBAAT,EAAA1Q,EAAyBpD,OAAQ,GACxC2Z,SAAWwB,GACTxB,EAAS,IACJ7D,EACHhC,eAAgBgL,GAAkB3D,EAAMlQ,OAAOyD,MAAO9N,MAI1DiB,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChB9N,EAAgBnB,IAAK8U,oBACnB,SAAA,CAAOnT,IAAKmT,EAAQvU,KAAM0O,MAAO6F,EAAQvU,MACvCuU,EAAQvU,SAKjB6B,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAASgB,GAAU,oBAKlF,CASO,SAASa,IAAkCjf,gBAChDA,EAAA+U,SACAA,EAAAgE,SACAA,EAAAqF,SACAA,IAxFF,IAAA5b,EA0FE,OACEvB,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,sBAClBtI,GAAAyE,cAAC,cAAO,aACRzE,GAAAyE,cAAC,QAAA,KAAM,gBAELzE,GAAAyE,cAAC,QAAA,CACC,cAAY,qBACZ/H,KAAK,OACLmQ,MAAOiH,EAASC,aAAa9Q,KAAK,MAClC6U,SAAWwB,GAAUxB,EAAS,IAAKhE,EAAUC,aAAc+J,GAAUxE,EAAMlQ,OAAOyD,YAGtF7M,GAAAyE,cAAC,QAAA,KAAM,0BAELzE,GAAAyE,cAAC,SAAA,CACC,cAAY,4BACZ2Y,UAAQ,EACRvQ,OAAO,OAAAtL,EAAAuS,EAAS1B,YAAYF,yBAAgB/T,OAAQ,GACpD2Z,SAAWwB,GACTxB,EAAS,IACJhE,EACH1B,YAAa,IACR0B,EAAS1B,YACZF,eAAgB+K,GAAkB3D,EAAMlQ,OAAOyD,MAAO9N,OAK3DA,EAAgBnB,IAAK8U,oBACnB,SAAA,CAAOnT,IAAKmT,EAAQvU,KAAM0O,MAAO6F,EAAQvU,MACvCuU,EAAQvU,SAKhB2V,EAAS1B,YAAYE,UAAU1U,IAAI,CAACqW,EAAUf,IAC7ClT,GAAAyE,cAACsZ,GAAA,CACChf,kBACAQ,IAAK2T,EACL4E,SAAWmG,GACTnG,EAAS,IACJhE,EACH1B,YAAa,IACR0B,EAAS1B,YACZE,UAAWwB,EAAS1B,YAAYE,UAAU1U,IAAI,CAAC8c,EAASwD,IACtDA,IAAiBhL,EAAQ+K,EAAUvD,MAK3CyC,SAAU,IACRrF,EAAS,IACJhE,EACH1B,YAAa,IACR0B,EAAS1B,YACZE,UAAWwB,EAAS1B,YAAYE,UAAUrV,OAAO,CAAC6D,EAAGod,IAAiBA,IAAiBhL,MAI7Fe,cAGJjU,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,wBACV,cAAY,gBACZ6T,QAAS,IACPrE,EAAS,IACJhE,EACH1B,YAAa,IACR0B,EAAS1B,YACZE,UAAW,IAAIwB,EAAS1B,YAAYE,UAAW,CAAE6B,MAAO,SAI/D,iBAGDnU,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAASgB,GAAU,oBAKlF,CCnFA,SAASpI,GACPrC,EACAlV,GAEA,MAAMC,EAAciV,EAAQjV,YACxBD,EAAawI,KAAK,EAAG7H,WA/F3B,IAAAoD,EA+FsC,OAAApD,KAAS,OAAAoD,EAAAmR,EAAQjV,kBAAR,EAAA8D,EAAqBpD,SAASuU,EAAQjV,iBAC/E,EACJ,MAAO,IACFiV,KACCjV,EAAc,CAAEA,YAAa,IAAKA,IAAkB,CAAA,EAE5D,CAEA,SAAS0gB,GACPjJ,EACA1C,GAEA,OAAO0C,EAAY1C,EAAS3V,IAAIqY,EAAU/W,OAAS,IAAK+W,QAAc,CACxE,CAEO,SAASkJ,GACd/K,GACAzQ,YAAEA,cAAayb,EAAcC,EAAaD,cAE1C,MAAME,EAzFD,SAAkClL,GACvC,MAAMoB,EAAaF,GAAgClB,GACnD,GAAiC,SAA7BA,EAAQzR,kBAA4D,qBAA7ByR,EAAQzR,iBACjD,MAAO,CAAC6S,GAGV,MACE1V,gBAAiByf,EACjBhhB,aAAcihB,EACd3N,UAAW4N,EAAArQ,UACXA,KACGsQ,GACDlK,EACE1V,EAAkB,IAAI0T,IAC1BY,EAAQtU,gBAAgBnB,IAAK8U,GAAY,CAACA,EAAQvU,KAAM4W,GAAwBrC,EAASW,EAAQ7V,iBAE7F0U,EAAiBiM,GAAsB9K,EAAQnB,eAAgBnT,GAC/D+R,EAAYuC,EAAQvC,UAAUrE,QAASqH,GAC3CA,EAASC,aAAanW,IAAKghB,IAAA,CACzB7K,aAAc,CAAC6K,GACfxM,YAAa,IACP0B,EAAS1B,YAAYF,eACrB,CAAEA,eAAgBiM,GAAsBrK,EAAS1B,YAAYF,eAAgBnT,IAC7E,CAAA,EACJuT,UAAWwB,EAAS1B,YAAYE,UAAU1U,IAAKqW,IAAA,IACzCA,EAAShC,eACT,CAAEA,eAAgBkM,GAAsBlK,EAAShC,eAAgBlT,IACjE,CAAA,EACJoV,MAAO,IAAIF,EAASE,eAMtBoK,GAASlQ,GAAa,IAAuCzQ,IAAK+Q,IACtE,MAAMxQ,EAAOuX,OAAO/G,EAASxQ,MAC7B,MAAO,IACFwgB,EACHzhB,YAAayR,EAASzR,aAAe,QACjCgV,EAAiB,CAAEA,kBAAmB,CAAA,EAC1CpB,YACAY,UAAW/C,EAAS+C,UACpBI,WAAY,MACZN,iBAAkBrT,EAClBA,OACAwT,UAAWhD,EAASgD,aAChBhD,EAASpH,OAAS,CAAEA,OAAQoH,EAASpH,QAAW,CAAA,EACpDgK,WAAY8B,EAAQlV,QAIxB,GAAqB,SAAjBkV,EAAQpC,MAAmBoC,EAAQgB,UAAYkK,EAAK9c,OAAQ,CAC9D,MAAMod,EAAgB,IAAIvQ,IAAI+E,EAAQhF,UAAUzQ,IAAI,EAAGO,UAAWA,IAC5D2gB,EAAyB,IAAIrM,IAAIY,EAAQtU,gBAAgBnB,IAAK8U,GAAY,CAACA,EAAQvU,KAAMuU,KAC/F6L,EAAK,GAAGQ,kBAAoB1L,EAAQgB,SAAShG,UAC1CzQ,IAAI,EAAGO,UAAWA,GAClBlB,OAAQkB,IAAU0gB,EAAcrP,IAAIrR,IACvCogB,EAAK,GAAGS,mBAAqB3L,EAAQgB,SAAStV,gBAC3C9B,OAAQyV,IAAauM,GAAQvM,EAASoM,EAAuBjiB,IAAI6V,EAAQvU,QACzEP,IAAK8U,GAAYqC,GAAwBrC,EAASW,EAAQgB,SAAU7W,cACzE,CAEA,OAAO+gB,CACT,CA0BeW,CAAyB7L,GACtC,MAAqB,aAAjBA,EAAQpC,KAC0B,SAA7BoC,EAAQzR,kBAA4D,qBAA7ByR,EAAQzR,iBAA0C2c,EAAOA,EAAK,GAGvGze,QAAQC,QACbse,EAAY,CACVzb,cACAqH,YAAa,GAAoB,SAAjBoJ,EAAQpC,KAAkB,SAAW,2BAA2BoC,EAAQlV,OACxFqP,IAAK+Q,IAGX,CC9HA,SAASY,GAAYC,EAAKC,YACnBA,IAAiBA,EAAM,CAAA,GAC5B,IAAIC,EAAWD,EAAIC,SAEnB,GAAKF,GAA2B,oBAAbG,SAAnB,CAEA,IAAIC,EAAOD,SAASC,MAAQD,SAASE,qBAAqB,QAAQ,GAC9DC,EAAQH,SAAS9a,cAAc,SACnCib,EAAMhjB,KAAO,WAEI,QAAb4iB,GACEE,EAAKG,WACPH,EAAKI,aAAaF,EAAOF,EAAKG,YAKhCH,EAAKK,YAAYH,GAGfA,EAAMI,WACRJ,EAAMI,WAAWC,QAAUX,EAE3BM,EAAMG,YAAYN,SAASS,eAAeZ,GAnBW,CAqBzD,CCQO,SAASa,IAAQC,SAAEA,EAAA7c,MAAUA,IAClC,OACErD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YAAY4X,GAGjC,CAaA,SAASC,GAA2ClI,GAClD,OAAOA,EAAQhb,OACb,CAACyc,EAAQxG,IACPqC,QAAQmE,EAAOvb,OAAS8Z,EAAQmI,UAAU,EAAGjiB,UAAWA,IAASub,EAAOvb,QAAU+U,EAExF,CA8DO,SAASmN,GAAoChN,GAClD,MAAMiN,EAAoB,EAAG/Y,YAAWoH,GAAsC4R,KAC5E,GAA0B,UAAtB5R,EAASkD,SACX,MAAO,IAAKlD,EAAUgD,UAAW,MAAOE,SAAU,WAAsB0O,GAAchZ,EAAS,CAAEA,UAAW,CAAA,GAE9G,MAAQrK,YAAasjB,KAAiBC,GAAsB9R,EAC5D,MAAO,IAAK8R,EAAmB5O,SAAU,UAAqB0O,GAAchZ,EAAS,CAAEA,UAAW,KAGpG,MAAiC,qBAA7B8L,EAAQzR,iBACH,IACFyR,EACHhF,UAAWgF,EAAQhF,UAAUzQ,IAAK+Q,GAAa2R,EAAkB3R,GAAU,IAC3E7P,OAA2B,WAAnBuU,EAAQvU,OAAsB,GAAKuU,EAAQvU,QAIhD,IACFuU,EACHhF,UAAWgF,EAAQhF,UAAUzQ,IAAK+Q,GAAa2R,EAAkB3R,GAAU,IAC3E/M,iBAAkB,OAClByF,aAAS,EACTvI,OAAQ,SACRyI,YAAQ,EAEZ,CAEO,SAASmZ,GAAmCrN,GAnJnD,IAAA9R,EAAAsE,EAAAe,EAoJE,MAAMkQ,MAAaxI,IACbqS,EAAwC,qBAA7BtN,EAAQzR,iBAmFzB,OAjFKyR,EAAQlV,KAAK6Y,QAAQF,EAAOlI,IAAI,qBAChCyE,EAAQC,aAAawD,EAAOlI,IAAI,wBACjC+R,GACGtN,EAAQvU,QAA6B,WAAnBuU,EAAQvU,QAC7BgY,EAAOlI,IAAI,4DAER,OAAArN,EAAA8R,EAAQhM,kBAASlJ,OAAM2Y,EAAOlI,IAAI,6DAClC,OAAA/I,EAAAwN,EAAQ9L,iBAAQpJ,OAAM2Y,EAAOlI,IAAI,4DACV,WAAnByE,EAAQvU,QACjBgY,EAAOlI,IAAI,qDAGRyE,EAAQhF,UAAU5M,QAAQqV,EAAOlI,IAAI,sCAC1CyE,EAAQhF,UAAU/O,QAASqP,IApK7B,IAAApN,EAqKSoN,EAASxQ,KAAK6Y,QAAQF,EAAOlI,IAAI,8BACZ,SAAtBD,EAASkD,UAA6C,UAAtBlD,EAASkD,UAC3CiF,EAAOlI,IAAI,4CAERqI,GAAUtI,EAASgD,YACtBmF,EAAOlI,IAAI,4DAEa,UAAtBD,EAASkD,WAAyB,OAAAtQ,EAAAoN,EAASzR,kBAAT,EAAAqE,EAAsBpD,OAC1D2Y,EAAOlI,IAAI,gDAEa,UAAtBD,EAASkD,UAA+C,QAAvBlD,EAASgD,WAC5CmF,EAAOlI,IAAI,wCAIVyE,EAAQtU,gBAAgB0C,QAAQqV,EAAOlI,IAAI,6CAChDyE,EAAQtU,gBAAgBO,QAAS2S,IArLnC,IAAA1Q,EAsLS0Q,EAAe9T,KAAK6Y,QAAQF,EAAOlI,IAAI,sCACvC,OAAArN,EAAA0Q,EAAexU,oBAAf8D,EAA4BpD,OAAM2Y,EAAOlI,IAAI,iDAC7CqD,EAAeyE,UAAUI,EAAOlI,IAAI,0CACrCsI,GAASjF,EAAekF,+BAC1BL,EAAOlI,IAAI,wDAGwB,qBAAnCqD,EAAe0E,iBAyDrB,SAAuB9J,EAAgB+T,EAAiBC,GACtD,MAAMxJ,EAAS3D,OAAO7G,GACtB,gBAAOA,GAAuB6G,OAAO4D,SAASD,IAAWA,GAAUuJ,GAAWvJ,GAAUwJ,CAC1F,CA3DOtJ,CAActF,EAAe2E,qBAAsB,EAAG,QAEvDE,EAAOlI,IAAI,+DAIfyE,EAAQ7V,aAAa8B,QAAS7B,IApMhC,IAAA8D,GAqMS,OAAAA,EAAA9D,EAAYU,aAAZoD,EAAkByV,SAAQF,EAAOlI,IAAI,kCACrC,CAAC,OAAQ,QAAS,MAAO,OAAO/M,SAAS6T,OAAOjY,EAAYC,mBAC/DoZ,EAAOlI,IAAI,2DAERqI,GAAUxZ,EAAYkW,OAAOmD,EAAOlI,IAAI,kDAEV,SAAhCnR,EAAYC,iBAA8D,UAAhCD,EAAYC,iBACtDD,EAAY6X,aAEbwB,EAAOlI,IAAI,wDAETsI,GAASzZ,EAAY+Z,aAAaV,EAAOlI,IAAI,sDACZ,IAAjCnR,EAAYga,kBAAkC/D,OAAOjW,EAAYga,mBAAqB,GACxFX,EAAOlI,IAAI,yDAEwB,IAAjCnR,EAAYia,kBAAkChE,OAAOjW,EAAYia,mBAAqB,GACxFZ,EAAOlI,IAAI,qDAE0B,IAAnCnR,EAAYka,oBAAoCjE,OAAOjW,EAAYka,qBAAuB,GAC5Fb,EAAOlI,IAAI,qDAIV,OAAAhI,EAAAyM,EAAQnB,yBAAgB/T,OAAM2Y,EAAOlI,IAAI,wCAC9CyE,EAAQvC,UAAUxR,QAASwU,IA7N7B,IAAAvS,EA8NSuS,EAASC,aAAatS,QAAQqV,EAAOlI,IAAI,kDACzC,OAAArN,EAAAuS,EAAS1B,YAAYF,qBAArB,EAAA3Q,EAAqCpD,OACxC2Y,EAAOlI,IAAI,qDAEbkF,EAAS1B,YAAYE,UAAUhT,QAAS2U,IAlO5C,IAAA1S,EAmOW0S,EAASE,MAAM1S,QAAQqV,EAAOlI,IAAI,0CAClC,OAAArN,EAAA0S,EAAShC,uBAAT1Q,EAAyBpD,OAAM2Y,EAAOlI,IAAI,6CAI5CiB,MAAMkD,KAAK+D,EACpB,CAEA,SAASG,GAAUpK,GACjB,MAAMiU,EAAOpL,OAAO,MAAA7I,EAAAA,EAAS,IAAImK,OACjC,IAAK,QAAQ+J,KAAKD,GAAO,OAAO,EAChC,MAAMnN,EAAOD,OAAOoN,GACpB,OAAOpN,OAAOiG,UAAUhG,IAASA,GAAQ,GAAKA,GAAQ,KACxD,CAEA,SAASuD,GAASrK,GAChB,YAAiB,IAAVA,GAAuB6G,OAAO7G,GAAS,CAChD,CAOA,SAASoQ,GAAkB9e,EAAc8Z,GACvC,GAAK9Z,EAGL,OAAQ8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,OAC9D,CAEO,SAAS6iB,IAA0B3N,QAAEA,EAAA3R,KAASA,EAAAoW,SAAMA,IAlQ3D,IAAAvW,EAAAsE,EAAAe,EAmQE,MAAMqR,EAvMD,SACL5E,EACA3R,GA9DF,IAAAH,EAAAsE,EAgEE,MAAM8a,EAAwC,qBAA7BtN,EAAQzR,iBACnBqf,EAAkBpL,GAAgDA,EAAK9X,UAAYsV,EAAQC,YAC3F4N,EAAmBrL,GACvBoL,EAAepL,KACd8K,EAAW9K,EAAK/W,SAAWuU,EAAQvU,YAAyB,IAAhB+W,EAAK/W,QAAwC,WAAhB+W,EAAK/W,QAC3EgP,EAAYpM,EAAKoM,SAA4C7Q,OAAOgkB,GACpEE,EAAkBrT,EAAS9H,KAC9BqB,IAvEL,IAAA9F,EAAAsE,EAuEiB,OAAAwB,EAAQlJ,QAAS,OAAAoD,EAAA8R,EAAQhM,cAAR,EAAA9F,EAAiBpD,OAAQkJ,EAAQ3B,MAAO,OAAAG,EAAAwN,EAAQhM,gBAARxB,EAAiB1H,QAEnFijB,GAAa,OAAA7f,IAAQ8F,gBAAR9F,EAAiBmE,MAA6B,MAAAyb,OAAA,EAAAA,EAAiBzb,MAAM,OAAAG,EAAAwN,EAAQhM,cAAR,EAAAxB,EAAiB1H,MACnGkjB,EAAsBhO,EAAQvC,UAAUrE,QAASqH,GAAa,IAC9DA,EAAS1B,YAAYF,eAAiB,CAAC4B,EAAS1B,YAAYF,gBAAkB,MAC/E4B,EAAS1B,YAAYE,UAAU7F,QAASwH,GAAcA,EAAShC,eAAiB,CAACgC,EAAShC,gBAAkB,MAE3GqP,EAAsBjO,EAAQtU,gBAAgB0N,QAASiG,GAC3DA,EAAQjV,YAAc,CAACiV,EAAQjV,aAAe,IAGhD,MAAO,CACLoQ,SAAUuB,GAAwB1N,EAAKmM,SAAUwF,EAAQC,YAAc,CAAC,CAAEnV,KAAMkV,EAAQC,cAAiB,IACzG3U,UAAWyQ,GACR1N,EAAK/C,UAA6C1B,OAAOikB,GAC1Df,GAAc9M,EAAQhF,UAAU5B,QAASkC,GAAcA,EAAS9P,QAAU,CAAC8P,EAAS9P,SAAW,MAEjGE,gBAAiBqQ,GACd1N,EAAK3C,gBAAmD9B,OAAOikB,GAChEf,GAAc,IACT9M,EAAQtU,mBACPsU,EAAQnB,eAAiB,CAACmB,EAAQnB,gBAAkB,MACrDmP,KAGPliB,aAAciQ,GACX1N,EAAKvC,aAAgDlC,OAAOikB,GAC7Df,GAAc9M,EAAQhF,UAAU5B,QAASkC,GAAcA,EAASzR,YAAc,CAACyR,EAASzR,aAAe,MAEzGM,aAAc4R,GACX1N,EAAKlE,aAAgDP,OAAOikB,GAC7Df,GAAc,IAAI9M,EAAQ7V,gBAAiB8jB,KAE7CxT,SAAUsB,GAAwBtB,EAAUuF,EAAQhM,QAAU,CAACgM,EAAQhM,SAAW,IAClF0G,QAASqB,GAAwB1N,EAAKqM,QAASsF,EAAQvU,OAAS,CAAC,CAAEX,KAAMkV,EAAQvU,SAAY,IAC7FkP,QAASoB,GACPuR,EACKjf,EAAKsM,QAA2C/Q,OAC9CsK,GAAW0Z,EAAe1Z,IAAWA,EAAOzI,SAAWuU,EAAQvU,QAAUyI,EAAOF,UAAY+Z,GAE/F,GACJjB,GAAc,IACR9M,EAAQ9L,OAAS,CAAC8L,EAAQ9L,QAAU,MACrC8L,EAAQhF,UAAU5B,QAASkC,GAAcA,EAASpH,OAAS,CAACoH,EAASpH,QAAU,OAI1F,CA6IkBga,CAAgClO,EAAS3R,GACnD8f,EAA2B,SAAjBnO,EAAQpC,KAOlB0H,EAAUC,IACdd,EAASuI,GAAoC,IAAKhN,KAAYuF,MAoB1D6I,EAAgB,CACpB3Q,EACAoB,EAAiBmB,EAAQnB,kBAEzB,MAAMsG,EAAa,IACbtG,EAAiB,CAACA,GAAkB,MACrCpB,EAAUrE,QAASqH,GAAa,IAC7BA,EAAS1B,YAAYF,eAAiB,CAAC4B,EAAS1B,YAAYF,gBAAkB,MAC/E4B,EAAS1B,YAAYE,UAAU7F,QAASwH,GACzCA,EAAShC,eAAiB,CAACgC,EAAShC,gBAAkB,OAItDlT,EAAkB,IAAIsU,EAAQtU,iBACpCyZ,EAAWlZ,QAAS4V,IAClB,IAAKnW,EAAgBqC,KAAK,EAAGjD,UAAWA,IAAS+W,EAAU/W,MAAO,CAChE,MAAMqf,EAAWvF,EAAQlZ,gBAAgBiH,KAAK,EAAG7H,UAAWA,IAAS+W,EAAU/W,OAAS+W,EACxFnW,EAAgBqE,KAAKoa,EACvB,IAEF,MAAMhgB,EAAe,IAAI6V,EAAQ7V,cACjCuB,EAAgBO,QAASoT,IACvB,GAAIA,EAAQjV,cAAgBD,EAAa4D,KAAK,EAAGjD,WAtTvD,IAAAoD,EAsTkE,OAAApD,KAAS,OAAAoD,EAAAmR,EAAQjV,kBAAR,EAAA8D,EAAqBpD,QAAO,CAC/F,MAAMqf,EAAWvF,EAAQza,aAAawI,KAAK,EAAG7H,WAvTtD,IAAAoD,EAuTiE,OAAApD,KAAS,OAAAoD,EAAAmR,EAAQjV,kBAAR,EAAA8D,EAAqBpD,QACvFX,EAAa4F,KAAMoa,GAAY9K,EAAQjV,YACzC,IAEFkb,EAAO,CAAE5Z,kBAAiBmT,iBAAgB1U,eAAcsT,eAG1D,OACE9Q,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iCACbtI,GAAAyE,cAAC,UAAA,KACCzE,GAAAyE,cAAC,KAAA,KAAG,YACJzE,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,QACbrD,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,qBACZoZ,UAAW,GACXtE,UAAQ,EACR1gB,KAAK,OACLmb,SAAU2J,EACV3U,MAAOwG,EAAQlV,KACf2Z,SAAWwB,GAAUX,EAAO,CAAExa,KAAMmb,EAAMlQ,OAAOyD,WAGrD7M,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,QACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,qBACZuP,SAAU2J,EACV3U,MAAOwG,EAAQzR,iBACfkW,SAAWwB,GAAUX,EAAO,CAAE/W,iBAAkB0X,EAAMlQ,OAAOyD,SAE7D7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,QAAO,WACrB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,oBAAmB,2BAGrC7M,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,WACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,cACZuP,SAAU2J,EACVpE,UAAQ,EACRvQ,MAAOwG,EAAQC,YACfwE,SAAWwB,GAAUX,EAAO,CAAErF,YAAagG,EAAMlQ,OAAOyD,SAExD7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQpK,SAASjQ,IAAKG,GACrBiC,GAAAyE,cAAC,SAAA,CAAOlF,IAAKxB,EAAQI,KAAM0O,MAAO9O,EAAQI,MACvCJ,EAAQI,SAKa,qBAA7BkV,EAAQzR,kBACP5B,GAAAyE,cAACzE,GAAMwI,SAAN,KACCxI,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,UACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,SACZuP,SAAU2J,EACVpE,UAAQ,EACRvQ,MAAOwG,EAAQvU,OACfgZ,SAAWwB,GAAUX,EAAO,CAAE7Z,OAAQwa,EAAMlQ,OAAOyD,SAEnD7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQlK,QAAQnQ,IAAKkB,GACpBkB,GAAAyE,cAAC,SAAA,CAAOlF,IAAKT,EAAOX,KAAM0O,MAAO/N,EAAOX,MACrCW,EAAOX,SAKhB6B,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,WACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,UACZ8U,UAAQ,EACRvQ,OAAO,OAAAtL,EAAA8R,EAAQhM,cAAR,EAAA9F,EAAiBpD,OAAQ,GAChC2Z,SAAWwB,GAAUX,EAAO,CAAEtR,QAAS4V,GAAkB3D,EAAMlQ,OAAOyD,MAAOoL,EAAQnK,aAErF9N,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQnK,SAASlQ,IAAKyJ,GACrBrH,GAAAyE,cAAC,SAAA,CAAOlF,IAAK8H,EAAQlJ,KAAM0O,MAAOxF,EAAQlJ,MACvCkJ,EAAQlJ,SAKjB6B,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,UACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,SACZ8U,UAAQ,EACRvQ,OAAO,OAAAhH,EAAAwN,EAAQ9L,aAAR,EAAA1B,EAAgB1H,OAAQ,GAC/B2Z,SAAWwB,IACT,MAAM/R,EAAS0V,GAAkB3D,EAAMlQ,OAAOyD,MAAOoL,EAAQjK,SAC7D2K,EAAO,CACLpR,SACA8G,UAAWgF,EAAQhF,UAAUzQ,IAAK+Q,QAAmBA,EAAUpH,gBAInEvH,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQjK,QAAQpQ,IAAK2J,GACpBvH,GAAAyE,cAAC,SAAA,CAAOlF,IAAKgI,EAAOpJ,KAAM0O,MAAOtF,EAAOpJ,MACrCoJ,EAAOpJ,4BAQrB,UAAA,KACC6B,GAAAyE,cAAC,KAAA,KAAG,aACH4O,EAAQhF,UAAUzQ,IAAI,CAAC+Q,EAAUuE,IAChClT,GAAAyE,cAACyY,GAAA,CACCve,UAAWsZ,EAAQtZ,UACnBQ,aAAc8Y,EAAQ9Y,aACtBI,IAAK2T,EACLvE,WACA/M,iBAAkByR,EAAQzR,iBAC1BkW,SAAWmG,GA1KE,EAAC/K,EAAevE,KACrC,MAAMN,EAAYgF,EAAQhF,UAAUzQ,IAAI,CAAC8c,EAASwD,IAAkBA,IAAiBhL,EAAQvE,EAAW+L,GACxG5C,EAASuI,GAAoC,IAAKhN,EAAShF,gBAwK5BwK,CAAe3F,EAAO+K,GAC7Cd,SAAU,IACRxE,EAAO,CAAEtK,UAAWgF,EAAQhF,UAAUpR,OAAO,CAAC6D,EAAGod,IAAiBA,IAAiBhL,KAErFlF,QAASiK,EAAQjK,WAGrBhO,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,wBACV6T,QAAS,IACPxD,EAAO,CACLtK,UAAW,IACNgF,EAAQhF,UACX,CACElQ,KAAMkV,EAAQlV,KACdwT,UAAW,KACXE,SAAU,OACVtK,OAAqC,qBAA7B8L,EAAQzR,iBAA0CyR,EAAQ9L,YAAS,OAKpF,iBAIHvH,GAAAyE,cAAC,UAAA,KACCzE,GAAAyE,cAAC,KAAA,KAAG,oBACH4O,EAAQtU,gBAAgBnB,IAAI,CAACqU,EAAgBiB,IAC5ClT,GAAAyE,cAACiZ,GAAA,CACCzL,iBACAlT,gBAAiBkZ,EAAQlZ,gBACzBvB,aAAcya,EAAQza,aACtB+B,IAAK2T,EACLtR,iBAAkByR,EAAQzR,iBAC1BkW,SAAWmG,GArMQ,EAC3B/K,EACAjB,KAEA,MAAMlT,EAAkBsU,EAAQtU,gBAAgBnB,IAAI,CAAC8c,EAASwD,IAC5DA,IAAiBhL,EAAQjB,EAAiByI,GAEtCiH,EAAuB1P,EAAexU,YACxCwa,EAAQza,aAAawI,KAAK,EAAG7H,WAvRrC,IAAAoD,EAuRgD,OAAApD,KAAS,OAAAoD,EAAA0Q,EAAexU,kBAAf,EAAA8D,EAA4BpD,aAC7E,EACEX,EACJmkB,IAAwBtO,EAAQ7V,aAAa4D,KAAK,EAAGjD,UAAWA,IAASwjB,EAAoBxjB,MACzF,IAAIkV,EAAQ7V,aAAcmkB,GAC1BtO,EAAQ7V,aACdmb,EAAO,CAAE5Z,kBAAiBvB,kBAuLKokB,CAAqB1O,EAAO+K,GACnDd,SAAU,IACRxE,EAAO,CACL5Z,gBAAiBsU,EAAQtU,gBAAgB9B,OAAO,CAAC6D,EAAGod,IAAiBA,IAAiBhL,QAK9FlT,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,wBACV6T,QAAS,IACPxD,EAAO,CACL5Z,gBAAiB,IAAIsU,EAAQtU,gBAAiB,CAAEZ,KAAM,GAAIuY,SAAU,OAAQC,gBAAiB,YAGlG,wBAIH3W,GAAAyE,cAAC,UAAA,KACCzE,GAAAyE,cAAC,KAAA,KAAG,mBACJzE,GAAAyE,cAACwb,GAAA,CAAQ5c,MAAM,2BACbrD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,0BACZ8U,UAAQ,EACRvQ,OAAO,OAAAjG,EAAAyM,EAAQnB,qBAAR,EAAAtL,EAAwBzI,OAAQ,GACvC2Z,SAAWwB,GACTmI,EAAcpO,EAAQvC,UAAWmM,GAAkB3D,EAAMlQ,OAAOyD,MAAOoL,EAAQlZ,mBAGjFiB,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQlZ,gBAAgBnB,IAAK8U,GAC5B1S,GAAAyE,cAAC,SAAA,CAAOlF,IAAKmT,EAAQvU,KAAM0O,MAAO6F,EAAQvU,MACvCuU,EAAQvU,UAMnB6B,GAAAyE,cAAC,eACCzE,GAAAyE,cAAC,KAAA,KAAG,uBACH4O,EAAQvC,UAAUlT,IAAI,CAACkW,EAAUZ,IAChClT,GAAAyE,cAACuZ,GAAA,CACCjf,gBAAiBkZ,EAAQlZ,gBACzB+U,WACAvU,IAAK2T,EACL4E,SAAWmG,GACTwD,EACEpO,EAAQvC,UAAUlT,IAAI,CAAC8c,EAASwD,IAAkBA,IAAiBhL,EAAQ+K,EAAUvD,IAGzFyC,SAAU,IAAMsE,EAAcpO,EAAQvC,UAAU7T,OAAO,CAAC6D,EAAGod,IAAiBA,IAAiBhL,OAGjGlT,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,wBACV6T,QAAS,IACPsF,EAAc,IACTpO,EAAQvC,UACX,CACEiD,aAAc,GACd3B,YAAa,CAAEF,eAAgBmB,EAAQnB,eAAgBI,UAAW,QAIzE,kBAIHtS,GAAAyE,cAAC,UAAA,KACCzE,GAAAyE,cAAC,KAAA,KAAG,iBACH4O,EAAQ7V,aAAaI,IAAI,CAACH,EAAayV,IACtClT,GAAAyE,cAAC6Y,GAAA,CACC7f,cACAD,aAAcya,EAAQza,aACtB+B,IAAK2T,EACL4E,SAAWmG,GACTtF,EAAO,CACLnb,aAAc6V,EAAQ7V,aAAaI,IAAI,CAAC8c,EAASwD,IAC/CA,IAAiBhL,EAAQ+K,EAAUvD,KAIzCyC,SAAU,IACRxE,EAAO,CAAEnb,aAAc6V,EAAQ7V,aAAaP,OAAO,CAAC6D,EAAGod,IAAiBA,IAAiBhL,QAI/FlT,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,wBACV6T,QAAS,IACPxD,EAAO,CACLnb,aAAc,IACT6V,EAAQ7V,aACX,CACEia,iBAAkB,GAClB/Z,gBAAiB,OACjBS,KAAM,GACNwV,KAAM,GACN2B,YAAa,IACbkC,WAAY,EACZE,iBAAkB,GAClBC,mBAAoB,OAK7B,qBAMT,s4BCjjBA,MAAM/J,GAAmC,CACvCC,SAAU,GACVlP,UAAW,GACXI,gBAAiB,GACjBI,aAAc,GACd3B,aAAc,GACdsQ,SAAU,GACVC,QAAS,GACTC,QAAS,IA+CJ,MAAM6T,GAAN,MAAMA,UAAiC7hB,GAAMC,UAa3C,WAAA5B,CAAYwG,GACjBid,MAAMjd,GAmDRtH,KAAQwkB,cAAiB1O,IACvB,MAAM2O,EAAiB3O,EAAQC,cAAgB/V,KAAK2D,MAAMmS,QAAQC,YAClE/V,KAAKqd,SAAS,CAAEvH,YACZ2O,GAAkBzkB,KAAK0kB,gBACzB1kB,KAAK0kB,eAAenT,KAAKuE,EAAQC,cAIrC/V,KAAQif,OAAS,KACf,GAAIkE,GAAmCnjB,KAAK2D,MAAMmS,SAAS5R,OACzD,OAEF,MAAM4R,EAAUgN,GAAoC9iB,KAAK2D,MAAMmS,SACzD6O,EAAe,CACnBtf,YAAarF,KAAKqF,cAClByb,YAAa9gB,KAAKsH,MAAMwZ,aAEL,aAAjBhL,EAAQpC,KAIZ1T,KAAK2D,MAAMia,YAAYqB,OAAO,IAAM4B,GAA6B/K,EAAS6O,IAHxE3kB,KAAKsH,MAAM8W,WAAWyC,GAA6B/K,EAAS6O,KApE9D,MAAMtf,EAAcrF,KAAKqF,YAAYiC,GAC/BoM,EAAO1T,KAAK0T,KAAKpM,GACjBwO,EA1CH,SACL+G,EACAnJ,EACArO,EACAwK,EAAyE,CAAA,GAEzE,MAOMiG,EAAUrC,GAPF,IACT5D,KACAgN,EACH9G,YAAa8G,EAAO9G,aAAe8G,EAAOrc,SAAWqP,EAASkG,YAC9D1R,iBAAkBwY,EAAOxY,kBAAoBwL,EAASxL,kBAAoB,OAC1EzD,KAAMic,EAAOjc,MAAQic,EAAO5I,kBAAoB4I,EAAO7I,mBAAc3O,WAAazE,OAAQ,IAErC8S,GASvD,OAPGpB,MAAMC,QAAQsK,EAAO/L,YAAc+L,EAAO/L,UAAU5M,OAAS,QAC9C,IAAhB2Y,EAAOzG,eACPyG,EAAOzI,gBACU,IAAjByI,EAAOxI,QAEPyB,EAAQhF,UAAY,CAAC,CAAElQ,KAAMkV,EAAQlV,KAAMwT,UAAW,KAAME,SAAU,UAEjEwO,GAAoChN,EAC7C,CAmBoB8O,CAAqCtd,EAAMlD,cAAgB,CAAA,EAAIsP,EAAMrO,EAAa,CAChG0Q,YAAazO,EAAMyO,YACnB1R,iBAAkBiD,EAAMjD,mBAE1BrE,KAAK2D,MAAQ,CACXmS,UACA3R,KAAMmD,EAAMnD,MAAQkM,GACpBY,OAAQ3J,EAAMnD,KAAO,QAAU,OAC/ByZ,YAAa,IAAIC,EAAY,CAC3BxY,cACAN,OAAmB,SAAT2O,EAAkB,WAAa,YAAlC,sBACPoK,UAAW,IAAMxW,EAAMyW,eACvBzY,eAAgB,KA5GxB,IAAAtB,EAAAsE,EA6GU,OAAAA,EAAA,OAAAtE,EAAAqB,EAAYpB,wBAAeuZ,UAA3BlV,EAAA0V,KAAAha,GACAsD,EAAM8W,gBAId,CA7BA,WAAckB,CAAKhY,GACjB,OAAOiY,EAAWD,KAAKgF,EAA0Bhd,EAAO,CAAEkY,gBAAiB,yBAC7E,CA6BO,iBAAAqF,GACD7kB,KAAKsH,MAAMnD,OAGfnE,KAAK0kB,eAAiB,IAAIhU,GAA8B1Q,KAAKsH,MAAMwd,aACnE9kB,KAAKud,YAAcvd,KAAK0kB,eAAevT,UAAWxN,GAAU3D,KAAKqd,SAAS1Z,IAC1E3D,KAAK0kB,eAAenT,KAAKvR,KAAK2D,MAAMmS,QAAQC,aAC9C,CAEO,oBAAAgP,GA7HT,IAAA/gB,EAAAsE,EA8HI,OAAAtE,EAAAhE,KAAKud,cAALvZ,EAAAga,KAAAhe,MACA,OAAAsI,EAAAtI,KAAK0kB,iBAALpc,EAAqBqJ,SACvB,CAEQ,WAAAtM,CAAYiC,EAAQtH,KAAKsH,OAC/B,OAAQA,EAAMjC,aAAeiC,EAAMvD,GACrC,CAEQ,IAAA2P,CAAKpM,EAAQtH,KAAKsH,OACxB,OAAIA,EAAMkV,kBACD,WAELlV,EAAMoM,KACDpM,EAAMoM,MAEQ,IAAhBpM,EAAMmV,OAAmBnV,EAAMlD,aAAe,OAAS,QAChE,CA0BO,MAAA4gB,GACL,MAAMlP,QAAEA,EAAA3R,KAASA,EAAA8M,OAAMA,EAAA2M,YAAQA,GAAgB5d,KAAK2D,MAC9CshB,EAAmB9B,GAAmCrN,GACtDvK,EACa,WAAjBuK,EAAQpC,KACJ,UAAuC,SAA7BoC,EAAQzR,iBAA8B,UAAY,2CAC5D,QAAQyR,EAAQlV,OAEtB,wBACG,OAAA,CAAKmK,UAAU,8BAA8BnK,KAAK,QACjD6B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iCACZ0T,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,KAAA,KAAIqE,IAEP9I,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAACqX,EAAA,CAAmBC,QAASZ,IACjB,YAAX3M,oBAAyB,MAAA,CAAIlG,UAAU,4BAA2B,cACvD,UAAXkG,oBAAuB,MAAA,CAAIlG,UAAU,sBAAqB,iCAC3DtI,GAAAyE,cAACuc,GAAA,CAA0B3N,UAAkB3R,OAAYoW,SAAUva,KAAKwkB,kBACrES,EAAiB/gB,QAClBzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iDACZka,EAAiB5kB,IAAK2O,oBACpB,MAAA,CAAIhN,IAAKgN,GAAQA,MAK1BvM,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,kBACVuP,SAAUsD,EAAYU,WACtBM,QAAS5e,KAAKsH,MAAMyW,cACrB,UAGDtb,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,kBACVuP,SAAUsD,EAAYU,YAAyB,YAAXrN,KAA0BgU,EAAiB/gB,OAC/E0a,QAAS5e,KAAKif,QAEI,aAAjBnJ,EAAQpC,KAAsB,OAA0B,SAAjBoC,EAAQpC,KAAkB,SAAW,WAKvF,GAxIW4Q,GAIG7E,wBAAyB,EAJlC,IAAMyF,GAANZ,GCvCP,MAAMa,GAAkD,CAAC,OAAQ,YAAa,mBACxEC,GAAuC,CAAC,MAAO,OAsC9C,SAASC,GAAsCvP,GACpD,MAAMyD,EAAmB,GACnBnI,EAAW0E,EAAQhF,UAAU,GAC7B5Q,EAAc4V,EAAQ7V,aAAa,GAsO3C,IAAkBqP,EAhNhB,OApBKwG,EAAQlV,KAAK6Y,QAAQF,EAAO1T,KAAK,qBACjCiQ,EAAQC,aAAawD,EAAO1T,KAAK,wBACjCiQ,EAAQvU,QAAQgY,EAAO1T,KAAK,uBA0NnC,SAAwByJ,GACtB,MAAM3F,EAAQwO,OAAO7I,GAAS,IAAI3F,MAAM,sBACxC,IAAKA,EAAO,OAAO,EACnB,MAAM2b,EAAQnP,OAAOxM,EAAM,IACrB4b,EAAMpP,OAAOxM,EAAM,IAAMA,EAAM,IACrC,OAAO+P,GAAU4L,IAAU5L,GAAU6L,IAAQD,GAASC,CACxD,CA/NOC,CAAe,MAAApU,OAAA,EAAAA,EAAUgD,YAAYmF,EAAO1T,KAAK,sDAElD3F,IACGwZ,GAAUxZ,EAAYkW,OAAOmD,EAAO1T,KAAK,kDACzC3F,EAAY6X,aAAawB,EAAO1T,KAAK,kCA8NrCyJ,OADSA,EA5NDpP,EAAY+Z,aA6NqB9D,OAAO7G,GAAS,GA7NxBiK,EAAO1T,KAAK,sDACb,IAAjC3F,EAAYga,kBAAkC/D,OAAOjW,EAAYga,mBAAqB,GACxFX,EAAO1T,KAAK,yDAEuB,IAAjC3F,EAAYia,kBAAkChE,OAAOjW,EAAYia,mBAAqB,GACxFZ,EAAO1T,KAAK,qDAEyB,IAAnC3F,EAAYka,oBAAoCjE,OAAOjW,EAAYka,qBAAuB,GAC5Fb,EAAO1T,KAAK,mDAIT0T,CACT,CAEO,SAASkM,IAA6B3P,QAC3CA,EAAA3R,KACAA,EAAAoW,SACAA,IA9GF,IAAAvW,EAAAsE,EAAAe,EAgHE,MAAMqR,EAzDD,SACL5E,EACA3R,GAEA,MAAMuf,EAAkBpL,IACrBA,EAAK9X,UAAY8X,EAAKvC,cAAsBuC,EAAK9X,SAAW8X,EAAKvC,eAAiBD,EAAQC,YAGvF3E,EAAW0E,EAAQhF,UAAU,GAEnC,MAAO,CACLR,SAAUuB,GAAwB1N,EAAKmM,SAAUwF,EAAQC,YAAc,CAAC,CAAEnV,KAAMkV,EAAQC,cAAiB,IACzG3U,UAAWyQ,GACR1N,EAAK/C,UAAoC1B,OAPrB4Y,GACvBoL,EAAepL,MAAWA,EAAK/W,QAAU+W,EAAK/W,SAAWuU,EAAQvU,SAO/D0Z,SAAW7J,WAAU9P,UAEvBiP,SAAUsB,GACP1N,EAAKoM,SAAmC7Q,OAAOgkB,GAChDzI,GAAWnF,EAAQhM,UAErB0G,QAASqB,GAAwB1N,EAAKqM,QAASsF,EAAQvU,OAAS,CAAC,CAAEX,KAAMkV,EAAQvU,SAAY,IAEjG,CAmCkBmkB,CAAmC5P,EAAS3R,GACtDiN,EAAW0E,EAAQhF,UAAU,IAAM,CAAElQ,KAAMkV,EAAQlV,KAAMwT,UAAW,GAAIE,SAAU,OAClFpU,EAAc4V,EAAQ7V,aAAa,GACnCgkB,EAA2B,SAAjBnO,EAAQpC,KAClB0H,EAAUC,GACdd,EAAS,IAAKzE,KAAYuF,IACtBC,EAAkBD,GACtBD,EAAO,CAAEtK,UAAW,CAAC,IAAKM,KAAaiK,MACnCG,EAAqBH,GACzBD,EAAO,CAAEnb,aAAc,CAAC,IAAKC,KAAgBmb,MAO/C,OACE5Y,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,oDACZ0Q,GAAU,OAAQ,OAAQ3F,EAAQlV,KARnBA,GAClBwa,EAAO,CACLxa,OACAkQ,UAAW,CAAC,IAAKM,EAAUxQ,KAAMwQ,EAASxQ,OAASkV,EAAQlV,KAAOA,EAAOwQ,EAASxQ,SAK7BqjB,GACpDvI,GACC,UACA,cACA5F,EAAQC,YACR2E,EAAQpK,SACPyF,GAAgBqF,EAAO,CAAErF,gBAC1BkO,GAEDvI,GAAY,SAAU,SAAU5F,EAAQvU,OAAQmZ,EAAQlK,QAAUjP,GAAW6Z,EAAO,CAAE7Z,WAAW0iB,GACjGvI,GACC,UACA,UACA,OAAA1X,EAAA8R,EAAQhM,cAAR,EAAA9F,EAAiBpD,KACjB8Z,EAAQnK,SACP3P,GAASwa,EAAO,CAAEtR,QAAS4V,GAAkB9e,EAAM8Z,EAAQnK,YAC5D0T,GAGFxhB,GAAAyE,cAAC,KAAA,KAAG,mBACHwU,GAAY,aAAc,UAAW,OAAApT,EAAA8I,EAAS9P,cAAT,EAAAgH,EAAkB1H,KAAM8Z,EAAQtZ,UAAYR,GAChF0a,EAAe,CAAEha,QAASoe,GAAkB9e,EAAM8Z,EAAQtZ,cAE3Dsa,GACC,WACA,WACAtK,EAASkD,SACT8Q,GAAU/kB,IAAKO,IAAA,CAAYA,UAC1B0T,GAAagH,EAAe,CAAEhH,cAEhCmH,GAAU,aAAc,YAAarK,EAASgD,UAAYA,GAAckH,EAAe,CAAElH,eACzFqH,GAAU,cAAe,cAAc,OAAApS,EAAAyM,EAAQ6P,iBAAR,EAAAtc,EAAoBzI,OAAQ,GAAI,QAAiB,GACxF8a,GACC,mBACA,kBACA5F,EAAQsD,gBACR+L,GAAmB9kB,IAAKO,IAAA,CAAYA,UACnCwY,GAAoBgC,EAAO,CAAEhC,oBAC9B6K,GAGFxhB,GAAAyE,cAAC,KAAA,KAAG,iCACH,MAAA,CAAI6D,UAAU,aAAa,aAAW,sBACrCtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,6CACZ,QAAA,KACCtI,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQ9X,GACjBqa,SAAWwB,GACTX,EAAO,CAAEnb,aAAc8b,EAAMlQ,OAAOwU,QAAU,CAtIrD,CACLnG,iBAAkB,GAClB/Z,gBAAiB,OACjBga,iBAAkB,GAClB/D,KAAM,GACN2B,YAAa,IACbkC,WAAY,EACZG,mBAAoB,IA+HwE,KAElFjb,KAAK,aACJ,IAAI,yBAKZe,GACCuC,GAAAyE,cAACzE,GAAMwI,SAAN,KACE2Q,GAAY,OAAQ,kBAAmB1b,EAAYkW,KAAOA,GAASoF,EAAkB,CAAEpF,UACvFqF,GAAU,eAAgB,cAAevb,EAAY6X,aAAe,GAAKA,GACxEyD,EAAkB,CAChBzD,YAAaA,IAAgBA,EAAYxJ,WAAW,KAAO,IAAIwJ,IAAgBA,KAGlF6D,GAAY,UAAW,aAAc1b,EAAY+Z,WAAaA,GAC7DuB,EAAkB,CAAEvB,gBAErB2B,GAAY,WAAY,mBAAoB1b,EAAYga,iBAAmBA,GAC1EsB,EAAkB,CAAEtB,sBAErB0B,GAAY,oBAAqB,mBAAoB1b,EAAYia,iBAAmBA,GACnFqB,EAAkB,CAAErB,sBAErByB,GACC,sBACA,qBACA1b,EAAYka,mBACXA,GAAuBoB,EAAkB,CAAEpB,yBAMxD,CAEA,SAASqB,GACP3V,EACAgS,EACAxI,EACAiL,EACAD,GAAW,GAEX,OACE7X,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVuP,WACAC,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3CA,MAAOA,GAAS,MAK1B,CAEA,SAASsM,GACP9V,EACAgS,EACAxI,EACAiL,GAEA,OACE9X,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVwP,SAAWwB,GAAUxB,EAAgC,KAAvBwB,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,QAC1FnQ,KAAK,SACLmQ,MAAOA,QAAwC,GAAK6I,OAAO7I,MAKrE,CAEA,SAASoM,GACP5V,EACAgS,EACAxI,EACAoL,EACAH,EACAD,GAAW,GAEX,OACE7X,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,aAAY+M,GACtCrV,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA2BjF,GAC5CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACVuP,WACAC,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3CA,MAAOA,GAAS,IAEhB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQra,IAAI,EAAGO,UACd6B,GAAAyE,cAAC,SAAA,CAAOlF,IAAKpB,EAAM0O,MAAO1O,GACvBA,MAOf,CAEA,SAAS8e,GACP9e,EACA8Z,GAEA,OAAO9Z,EAAS8Z,EAAQjS,KAAM0T,GAAWA,EAAOvb,OAASA,IAAS,CAAEA,aAAoC,CAC1G,CAEA,SAASqa,GAA+CiB,GACtD,OAAO,MAAAA,OAAA,EAAAA,EAAgBtb,MAAO,CAACsb,GAAkB,EACnD,CAEA,SAASxC,GAAUpK,GACjB,MAAM8G,EAAOD,OAAO7G,GACpB,OAAO6G,OAAOiG,UAAUhG,IAASA,GAAQ,GAAKA,GAAQ,KACxD,CC5RO,MAAMwP,GAA4C/V,GAASH,EAASC,UAAUC,KAAO,CAAA,EAAI,CAC9FC,SAAU,CAAA,EACVgW,QAAS,CAAA,EACTC,gBAAiBpW,EAASqW,cAAc,SCgBpC1V,GAAmC,CACvCC,SAAU,GACVlP,UAAW,GACXI,gBAAiB,GACjBI,aAAc,GACd3B,aAAc,GACdsQ,SAAU,GACVC,QAAS,GACTC,QAAS,IAEL0U,GAAkD,CAAC,OAAQ,YAAa,mBAgIvE,SAASa,GACdlQ,GACAzQ,YAAEA,cAAayb,EAAcC,EAAaD,cAE1C,MAAM/B,EArBD,SACLjJ,GAEA,MAAMoB,EAAaF,GAAgClB,GAOnD,cANOoB,EAAWjX,oBACXiX,EAAWpG,iBACXoG,EAAWpN,eACXoN,EAAWyO,kBACXzO,EAAWxD,KAEX,IACFwD,EACHhX,YAAa+lB,GAAqBnQ,EAAQ7V,aAAa,IACvDmZ,gBAAiBtD,EAAQsD,gBAE7B,CAMkB8M,CAAuCpQ,GACvD,MAAqB,aAAjBA,EAAQpC,KACHqL,EAGFxc,QAAQC,QACbse,EAAY,CACVzb,cACAqH,YAAa,GAAoB,SAAjBoJ,EAAQpC,KAAkB,SAAW,2BAA2BoC,EAAQlV,OACxFqP,IAAK,CAAC8O,KAGZ,CAEA,MAAMoH,WAA6C1jB,GAAMC,UAOhD,WAAA5B,CAAYwG,GACjBid,MAAMjd,GAgGRtH,KAAQwkB,cAAiB1O,IAzS3B,IAAA9R,EA0SI,MAAMygB,EAAiB3O,EAAQC,cAAgB/V,KAAK2D,MAAMmS,QAAQC,YAClE/V,KAAKqd,SAAS,CAAEvH,YACZ2O,IAAgB,OAAAzgB,EAAAhE,KAAK0kB,iBAAL1gB,EAAqBuN,KAAKuE,EAAQC,eAGxD/V,KAAQif,OAAS,KA/SnB,IAAAjb,EAAAsE,EAgToC,aAA5BtI,KAAK2D,MAAMmS,QAAQpC,KASvB1T,KAAK2D,MAAMia,YAAYqB,OACrB,IACE+G,GAAoChmB,KAAK2D,MAAMmS,QAAS,CACtDzQ,YAAarF,KAAKqF,cAClByb,YAAa9gB,KAAKsH,MAAMwZ,eAZ5B,OAAAxY,GAAAtE,EAAAhE,KAAKsH,OAAM8W,aAAX9V,EAAA0V,KAAAha,EACEgiB,GAAoChmB,KAAK2D,MAAMmS,QAAS,CACtDzQ,YAAarF,KAAKqF,cAClByb,YAAa9gB,KAAKsH,MAAMwZ,gBA1G9B,MAAMzb,EAAcrF,KAAKqF,YAAYiC,GAC/BoM,EAAO1T,KAAK0T,KAAKpM,GACjBwO,EAtHH,SACL/D,EAA8C,GAC9C2B,EACAkJ,EAAkB,GAClB/M,EAA+D,IA1FjE,IAAA7L,EAAAsE,EAAAe,EA4FE,MAAM+c,EAAwBrU,GAAa,CAAA,EACrC3I,EACJgd,EAAsBC,KAA4C,iBAA9BD,EAAsBC,IAAmBD,EAAsBC,IAAM,CAAA,EACrGjV,GAAW,OAAA9I,EAAA,OAAAtE,EAAAoF,EAAQkd,+BAAuB,SAA/B,EAAAhe,EAAmC8I,WAAY,CAAA,EAC1DmV,EAA+B,IAChCnd,KACAgd,EACHlmB,iBACwC,IAAtCkmB,EAAsBlmB,YAA4BkmB,EAAsBlmB,YAAckJ,EAAQlJ,YAChGiU,eAA+C,IAApCiS,EAAsBjS,UAA0BiS,EAAsBjS,UAAY/K,EAAQ+K,UACrGI,oBACE6R,EAAsB7R,WAClB6R,EAAsB7R,WACtBnL,EAAQmL,YAAcnD,EAASkD,SACrCF,mBACEgS,EAAsBhS,UAClBgS,EAAsBhS,UACtBhL,EAAQgL,WAAahD,EAASoV,iBACpCpN,qBAC4C,IAA1CgN,EAAsBhN,gBAClBgN,EAAsBhN,gBACtBhQ,EAAQgQ,gBACduM,gBAAiD,IAArCS,EAAsBT,WAA2BS,EAAsBT,WAAavc,EAAQuc,YAEpGc,EACJvlB,OAAOwlB,UAAUC,eAAe3I,KAAKoI,EAAuB,gBAC5DllB,OAAOwlB,UAAUC,eAAe3I,KAAK5U,EAAS,gBAC9Cmd,EAActmB,aACV2mB,GAAwB,OAAAvd,EAAAkd,EAActmB,mBAAd,EAAAoJ,EAA4BnF,QACtDqiB,EAActmB,aACdsmB,EAAcrmB,YACd,CAAC2mB,GAA0BN,EAAcrmB,cACzC,GAYE4V,EAAUrC,GAXc,IACzB5D,KACA0W,EACHxQ,YAAawQ,EAAcxQ,aAAewQ,EAAc/lB,SAAWqP,EAASkG,YAC5E9V,aAAc2mB,EACdzS,UAAWiB,GAAmBmR,EAAcpS,WAC5C9P,iBAAkB,UAClBzD,KAAM2lB,EAAc3lB,MAAQ2lB,EAActS,kBAAoB2I,EAC9D9S,QAASsL,GAAmBmR,EAAczc,SAC1CvI,OAAQglB,EAAchlB,QAAUsO,EAAStO,QAEamS,GAcxD,OAZGpB,MAAMC,QAAQgU,EAAczV,YAAcyV,EAAczV,UAAU5M,OAAS,QAChD,IAA5BqiB,EAAcpS,gBACe,IAA7BoS,EAAchS,iBACc,IAA5BgS,EAAcnS,gBACU,IAAxBmS,EAAclS,QAEdyB,EAAQhF,UAAY,CAAC,CAAElQ,KAAMkV,EAAQlV,KAAMwT,UAAW,OAAQE,SAAU,SAE7D,WAATZ,GAAsB+S,IACxB3Q,EAAQ7V,aAAe,CFvGlB,CACLia,iBAAkB,GAClB/Z,gBAAiB,OACjBga,iBAAkB,GAClB/D,KAAM,GACN2B,YAAa,IACbkC,WAAY,EACZG,mBAAoB,KEmGf,IACFtE,EACHzR,iBAAkB,UAClB+U,gBAAiB0N,GAAyBP,EAAcnN,iBACxDuM,WAAYvQ,GAAmBmR,EAAcZ,YAEjD,CAgDoBoB,CAAuCzf,EAAMlD,aAAcsP,QAAMrO,WAAazE,KAAM,CAClGmV,YAAazO,EAAMyO,aAAe6P,GAAoB/V,SAASrP,QAC/De,OAAQqkB,GAAoB/V,SAAStO,SAEvCvB,KAAK2D,MAAQ,CACXmS,UACA3R,KAAMmD,EAAMnD,MAAQkM,GACpBY,OAAQ3J,EAAMnD,KAAO,QAAU,OAC/ByZ,YAAa,IAAIC,EAAY,CAC3BxY,cACAN,OAAmB,SAAT2O,EAAkB,WAAa,YAAlC,sBACPoK,UAAW,KAvNnB,IAAA9Z,EAuNyB,OAAA,OAAAA,EAAAsD,EAAMyW,qBAAN/Z,EAAAga,KAAA1W,IACjBhC,eAAgB,KAxNxB,IAAAtB,EAAAsE,EAAAe,EAyNUhK,EAAqB4e,WAAW,gBAChC,OAAA3V,EAAA,OAAAtE,EAAA,MAAAqB,OAAA,EAAAA,EAAapB,wBAAeuZ,UAA5BlV,EAAA0V,KAAAha,GACA,OAAAqF,EAAA/B,EAAM8W,aAAN/U,EAAA2U,KAAA1W,MAIR,CAEO,iBAAAud,GACD7kB,KAAKsH,MAAMnD,OACfnE,KAAK0kB,eAAiB,IAAIhU,GAA8B1Q,KAAKsH,MAAMwd,aACnE9kB,KAAKud,YAAcvd,KAAK0kB,eAAevT,UAAWxN,GAAU3D,KAAKqd,SAAS1Z,IAC1E3D,KAAK0kB,eAAenT,KAAKvR,KAAK2D,MAAMmS,QAAQC,aAC9C,CAEO,oBAAAgP,GAxOT,IAAA/gB,EAAAsE,EAyOI,OAAAtE,EAAAhE,KAAKud,cAALvZ,EAAAga,KAAAhe,MACA,OAAAsI,EAAAtI,KAAK0kB,iBAALpc,EAAqBqJ,SACvB,CAEO,MAAAqT,GACL,MAAMlP,QAAEA,EAAA3R,KAASA,EAAA8M,OAAMA,EAAA2M,YAAQA,GAAgB5d,KAAK2D,MAC9C4V,EAAS8L,GAAsCvP,GAC/CvK,EACa,WAAjBuK,EAAQpC,KACJ,+BACiB,aAAjBoC,EAAQpC,KACR,kCACA,QAAQoC,EAAQlV,OAEtB,wBACG,MAAA,CAAImK,UAAU,iBACbtI,GAAAyE,cAACqX,GAAmBC,QAASZ,IAC7Bnb,GAAAyE,cAACuX,GAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iCACZ,KAAA,KAAIQ,qBAEN,MAAA,CAAIR,UAAU,cACD,YAAXkG,GAAwBxO,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,4BAA2B,cACvD,UAAXkG,GAAsBxO,GAAAyE,cAAC,OAAI6D,UAAU,sBAAqB,kDAC1D0a,GAAA,CAA6B3P,UAAkB3R,OAAYoW,SAAUva,KAAKwkB,kBACxEjL,EAAOrV,QACRzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,oDACZwO,EAAOlZ,IAAK2O,oBACV,MAAA,CAAIhN,IAAKgN,GAAQA,MAK1BvM,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,kBACVuP,SAAUsD,EAAYU,WACtBM,QAAS5e,KAAKsH,MAAMyW,aACpB5e,KAAK,UACN,UAGDsD,GAAAyE,cAAC2X,EAAA,CACCjW,aAAc2Q,EAAOrV,QAAqB,YAAX+M,GAAwB2M,EAAYU,WACnEQ,cAAc,EACdhZ,MAAwB,aAAjBgQ,EAAQpC,KAAsB,OAA0B,SAAjBoC,EAAQpC,KAAkB,SAAW,SACnFkL,QAAS5e,KAAKif,OACdX,WAAYV,EAAYU,cAKlC,CAEQ,WAAAjZ,CAAYiC,EAAQtH,KAAKsH,OAC/B,OAAQA,EAAMjC,aAAeiC,EAAMvD,GACrC,CAEQ,IAAA2P,CAAKpM,EAAQtH,KAAKsH,OACxB,OAAIA,EAAMkV,kBAA0B,WAChClV,EAAMoM,KAAapM,EAAMoM,MACN,IAAhBpM,EAAMmV,OAAmBnV,EAAMlD,aAAe,OAAS,QAChE,EA4BK,MAAM4iB,GAA8B9lB,OAAOsO,OAAO2W,GAAsC,CAC7F7G,KAAOhY,GACLiY,EAAWD,KAAK6G,GAAsC7e,EAAO,CAAEkY,gBAAiB,aAClFC,wBAAwB,IAG1B,SAASoH,GAA0BvX,GACjC,GAAIA,GAA0B,iBAAVA,EAAoB,OAAOA,EAE/C,OADkB8F,GAAmB9F,IACjB,CAAA,CACtB,CAEA,SAAS8F,GAAmB9F,GAC1B,IAAKA,EAAO,OACZ,GAAqB,iBAAVA,EAAoB,CAC7B,MAAMqI,EAAYrI,EACZvM,EAAWoV,OAAOR,EAAU5U,UAAY,IACxCnC,EAAOuX,OAAOR,EAAU/W,MAAQ+W,EAAUxP,IAAMpF,EAASC,MAAM,KAAKtD,OAAOsY,SAASC,OAAS,IACnG,OAAOrX,EAAQ,IAAK+W,EAAW/W,KAAAA,QAAmC,CACpE,CACA,MAAMmC,EAAWoV,OAAO7I,GAClB1O,EAAOmC,EAASC,MAAM,KAAKtD,OAAOsY,SAASC,OAASlV,EAC1D,OAAOA,EAASuB,SAAS,KAAO,CAAE1D,OAAMmC,YAAa,CAAEnC,OACzD,CAEA,SAASkmB,GAAyBxX,GAChC,MAAMqE,EAAawE,OAAO7I,GAAS,QAAQuE,cAC3C,OAAOsR,GAAmB7gB,SAASqP,GAAcA,EAAa,MAChE,CAEA,SAASsS,GAAqB/lB,GAC5B,OAAKA,EACE,CACLga,iBAAkB+M,GAAkB/mB,EAAYga,kBAChDC,iBAAkB8M,GAAkB/mB,EAAYia,kBAChD/D,KAAM6Q,GAAkB/mB,EAAYkW,MACpC2B,YAAa7X,EAAY6X,YACzBkC,WAAYgN,GAAkB/mB,EAAY+Z,YAC1CG,mBAAoB6M,GAAkB/mB,EAAYka,qBAP3B,IAS3B,CAEA,SAAS6M,GAAkB3X,GACzB,OAAOA,SAAmD,KAAVA,OAAe,EAAY6G,OAAO7G,EACpF,siBCzVO,MAAM4X,GAAsD,CACjE,CAAE/nB,KAAM,UAAW2G,MAAO,UAAW4G,YAAa,gDAClD,CAAEvN,KAAM,WAAY2G,MAAO,WAAY4G,YAAa,iDACpD,CAAEvN,KAAM,MAAO2G,MAAO,MAAO4G,YAAa,4CAC1C,CAAEvN,KAAM,MAAO2G,MAAO,MAAO4G,YAAa,4CAC1C,CAAEvN,KAAM,OAAQ2G,MAAO,UAAW4G,YAAa,0CAC/C,CACEvN,KAAM,mBACN2G,MAAO,mBACP4G,YAAa,qDAgBV,SAASya,GAAwBhoB,GACtC,MAAa,YAATA,EAA2B6nB,GAClB,SAAT7nB,GAA4B,qBAATA,EAAoC+lB,GACpD7F,EACT,CAEO,MAAM+H,GAAN,MAAMA,UAAmC3kB,GAAMC,UAA/C,WAAA5B,GAAAyjB,SAAA8C,WAyBLrnB,KAAO2D,MAA0C,CAC/C2jB,eAAgBC,GAAcvnB,KAAKsH,OAAS,KAAO4f,GAA0B,IAG/ElnB,KAAOwnB,eAAkBF,IAClBC,GAAcvnB,KAAKsH,QACtBtH,KAAKqd,SAAS,CAAEiK,oBAIpBtnB,KAAQynB,OAAS,KAxFnB,IAAAzjB,EAAAsE,EAyFI,MAAMgf,eAAEA,GAAmBtnB,KAAK2D,MAChC,IAAK2jB,GAAkBC,GAAcvnB,KAAKsH,OACxC,OAGF,MAAMnI,KAAEA,GAASmoB,EACX5T,EAAO1T,KAAKsH,MAAMkV,kBAAoB,WAAa,SACnDpc,EAAS+mB,GAAwBhoB,GAAMmgB,KAAKoI,GAAW1nB,KAAKsH,MAAOnI,EAAMuU,IAC/E,OAAApL,GAAAtE,EAAAhE,KAAKsH,OAAM8W,aAAX9V,EAAA0V,KAAAha,EAAwB5D,GAC1B,CAlCA,WAAckf,CAAKhY,GACjB,IAAoB,IAAhBA,EAAMmV,OAAmBnV,EAAMlD,aAAc,CAC/C,MAAMjF,EAAOwoB,GAAoBrgB,EAAMlD,aAAaC,kBACpD,GAAIlF,EAAM,CACR,MAAMuU,EAAOpM,EAAMkV,kBAAoB,WAAa,OACpD,OAAO2K,GAAwBhoB,GAAMmgB,KAAKoI,GAAWpgB,EAAOnI,EAAMuU,GACpE,CACF,CAEA,OAAO6L,EAAWD,KAAK8H,EAA4B9f,EAAO,CACxDkY,gBAAiB,mDAErB,CAwBO,MAAAwF,GApGT,IAAAhhB,EAqGI,MAAMsjB,eAAEA,GAAmBtnB,KAAK2D,MAC1BikB,EAAUL,GAAcvnB,KAAKsH,OAC7BugB,EAAgB,OAAA7jB,EAAAhE,KAAKsH,MAAMlD,qBAAXJ,EAAyBK,iBACzCyjB,EAA8C,iBAAlBD,GAA8BA,EAAgB,IAAIA,KAAmB,UACvG,OACEplB,GAAAyE,cAAC,OAAI6D,UAAU,mDACZ0T,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,MAAG6D,UAAU,eAAc,kDAE7B,MAAA,CAAIA,UAAU,cACZ6c,GACCnlB,GAAAyE,cAAC,OAAI6D,UAAU,qBAAqBgd,KAAK,SAAQ,mFACkCD,EAAmB,mEAIvG,MAAA,CAAI/c,UAAU,gBACZmc,GAA0B7mB,IAAK2nB,GAC9BvlB,GAAAyE,cAAC,SAAA,CACC,eAAcogB,IAAmBU,EACjCjd,UAAW,uCAAsCuc,IAAmBU,EAAS,SAAW,IACxF1N,SAAUsN,EACV5lB,IAAKgmB,EAAO7oB,KACZyf,QAAS,IAAM5e,KAAKwnB,eAAeQ,GACnC7oB,KAAK,UAELsD,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,uBAAuBid,EAAOliB,OAC5CrD,GAAAyE,cAAC,MAAA,KAAK8gB,EAAOtb,iBAKrBjK,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkBuP,SAAUsN,EAAShJ,QAAS5e,KAAKynB,OAAQtoB,KAAK,UAAS,2BACjEsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,wCAKlD,GAxFWqc,GAIGa,aAA0D,CACtE7J,WAAY8J,EACZnK,aAAcmK,GANLd,GASG3H,wBAAyB,EATlC,IAAM0I,GAANf,GA2FP,SAASO,GAAoBrY,GAhJ7B,IAAAtL,EAiJE,OAAO,OAAAA,EAAAkjB,GAA0Bze,KAAMuf,GAAWA,EAAO7oB,OAASmQ,SAA3D,EAAAtL,EAAmE7E,IAC5E,CAEA,SAASooB,GAAcjgB,GApJvB,IAAAtD,EAqJE,OAAuB,IAAhBsD,EAAMmV,QAAoBkL,GAAoB,OAAA3jB,EAAAsD,EAAMlD,uBAAcC,iBAC3E,CAEA,SAASqjB,GACPpgB,EACAjD,EACAqP,GAEA,MAAMrO,EAAciC,EAAMjC,aAAeiC,EAAMvD,IAC/C,MAAO,IACFuD,EACHvD,IAAKsB,EACLA,cACAmX,kBAA4B,aAAT9I,EACnB+I,MAAgB,WAAT/I,EACPtP,aAAckD,EAAMlD,cAAgB,KACpCC,mBACAqP,OAEJ,CCpKO,MAAM0U,GAGJ,kBAAAC,CAAmBC,GACxB,MAAMlkB,EAAekkB,EACrB,QAC6B,QAA1BlkB,EAAaxE,UAA4C,QAAtBwE,EAAajF,MACd,SAAlCiF,EAAaC,kBAAiE,qBAAlCD,EAAaC,iBAE9D,CAEO,oCAAAkkB,CACL9iB,EACAjF,EACAyD,GAIA,MAAMukB,EAAwC,GAc9C,OAbA/iB,EAAkB1D,QAASkS,IACzB,MAAMwU,EAAiBxkB,EAAcwE,KAAMrE,GAEvC5D,IAAY4D,EAAa5D,SACzBR,KAAKqoB,mBAAmBjkB,IACxBA,EAAa0M,UAAUzQ,IAAK+Q,GAAaA,EAASxQ,MAAM0D,SAAS2P,IAIrEwU,EACID,EAA4B3iB,KAAK4iB,EAAe7nB,MAChD4nB,EAA4B3iB,KAAKoO,KAEhCyU,GAAKF,EACd,EAjCWJ,GACGO,OAAS,SC0BzB,MAAMC,GAA2B,IAAIR,GAiBrC,SAASS,GAAUjO,EAAYkO,GAC7B,MAAMC,MAAWhY,IACjB,OAAO6J,EAAMlb,OAAQ4Y,IACnB,MAAMtW,EAAM8mB,EAAOxQ,GACnB,OAAIyQ,EAAK9W,IAAIjQ,KAGb+mB,EAAK1X,IAAIrP,IACF,IAEX,CAEA,SAASgnB,GAAY5kB,GA5DrB,IAAAJ,EAAAsE,EAAAe,EA8DE,MAAgB,SADH,OAAAA,EAAA,OAAAf,EAAA,OAAAtE,EAAA,MAAAI,SAAAA,EAAckiB,+BAAuB,SAArC,EAAAhe,EAAyC8I,eAAzC,EAAA/H,EAAmDmd,kBACxC,SAAW,OACrC,CAuFAyC,eAAsBC,IAA2BC,eAC/CA,EAAiB3b,EAAAzJ,IACjBA,EAAAqlB,UACAA,EAAAnlB,cACAA,EAAAolB,mBACAA,EAAAC,mBACAA,IA5JF,IAAAtlB,EA8JE,MAAMI,EAzHR,SAAgCH,EAAsB5B,GACpD,OAAQ4B,GAAiB,IAAIwE,KAAMC,GAE/BA,EAAU9H,OAASyB,EAAOzB,MAC1B8H,EAAUlI,UAAY6B,EAAO6F,YAC5BQ,EAAUnH,SAAWc,EAAOd,QAA+B,WAArBmH,EAAUnH,SATvD,SAAmBmH,EAAgBrG,GACjC,OAAQqG,EAAUC,OAASD,EAAU6gB,OAAS,SAAWlnB,EAAOsG,OAAS,KAC3E,CAQM6gB,CAAU9gB,EAAWrG,GAG3B,CAgHuBonB,CAAuBxlB,IAAiB,OAAAD,EAAA,MAAAD,OAAA,EAAAA,EAAKE,sBAALD,EAAoBG,OAAQ,GAAIklB,GAE7F,IAAKjlB,EAEH,YADAglB,IAIF,MAAMhgB,QA7DR6f,eAA2B7kB,EAAmBilB,EAAyBC,GACrE,MAAM1pB,EACJwE,EAAaxE,UAAYwE,EAAaqC,eAAiBrC,EAAajF,MAAQkqB,EAAmBzpB,SAC3F2B,EAAS6C,EAAa7C,QAAU8nB,EAAmB9nB,OACzD,GAAIqnB,GAAyBP,mBAAmBjkB,GAAe,CAC7D,MAAMslB,QAAmBnnB,QAAQkP,KAC9BrN,EAAa0M,WAAa,IAAIzQ,IAAK+Q,GAClCkY,EAAmBK,uBACjB/pB,EACAypB,EAAmBnhB,UACnB3G,EACA6P,EAASxQ,MAAQwQ,KAIjBnN,EAAiB,GAAa2lB,UAAUF,GACxCG,EAA6B5lB,EAAc,GAEjD,OAAK4lB,GAILA,EAA2BC,IAAMjB,GAC/B5kB,EACG5D,IAAK0pB,KAAmBC,QAASD,EAAOC,QAAS1V,SAAU0U,GAAYe,MACvErqB,OAAQqqB,GAAgBA,EAAOC,SACjCD,GAAgBA,EAAOC,SAE1BH,EAA2BvD,qBAAwB,GAAasD,UAC3D3lB,EAAc5D,IAAK0pB,GAAgBA,EAAOzD,sBAAwB,KAEhE,CAACuD,IAZC,EAaX,CAEA,MAAMzgB,QAAgBkgB,EAAmBK,uBACvC/pB,EACAypB,EAAmBnhB,UACnB3G,EACA6C,EAAaxD,MAKf,OAHIwI,EAAQ,KACVA,EAAQ,GAAG0gB,IAAM,CAAEE,QAAS5gB,EAAQ,GAAG4gB,QAAS1V,SAAU0U,GAAY5f,EAAQ,MAEzEA,CACT,CAiBwB6gB,CAAY7lB,EAAcilB,EAAoBC,GAC9DY,EAAW9gB,EAAQ1J,OAAQqqB,IAAiBA,EAAOR,OAAS,SAAWF,EAAmB1gB,OAAS,OACrGuhB,EAAShmB,SACXE,EAAaiiB,IAAM6D,EAAS,GAC5B9lB,EAAa5D,QAAU6oB,EAAmBnhB,UAEtC0gB,GAAyBP,mBAAmBjkB,KAC9CA,EAAaiiB,IAAI7kB,gBA3GvB,SAA4B4C,GAC1B,IAAI5C,EAAkB,CAAC4C,EAAauQ,gBAAgBjV,OAAOsY,SAa3D,OAXK5T,EAAamP,WAAa,IAAIrP,SAChCE,EAAamP,WAAa,IAAIxR,QAASwU,IArE5C,IAAAvS,EAAAsE,GAsEU,OAAAtE,EAAAuS,EAAS1B,kBAAT,EAAA7Q,EAAsB2Q,iBACxBnT,EAAgBqE,KAAK0Q,EAAS1B,YAAYF,gBAE5CnT,EAAkBA,EAAgBooB,SAC/B,OAAAthB,EAAAiO,EAAS1B,kBAAT,EAAAvM,EAAsByM,YAAa,IAAI1U,IAAKqW,GAAkBA,EAAShC,gBAAgBhV,OAAOsY,YAK9F6Q,GAAOrnB,EAAkBkT,GAAwBA,EAAe9T,MAAQ8T,EAAe3R,UAAY,GAC5G,CA4FyConB,CAAmB/lB,GACtDA,EAAaiiB,IAAIpmB,aAAe4oB,GAC9BzkB,EAAaiiB,IAAI7kB,gBAAgBnB,IAAKqU,GAAwBA,EAAexU,aAAaR,OAAOsY,SAChG9X,GAAqBA,EAAYU,MAAQV,EAAY6C,UAAY,MAKxE,MAAM2K,QAA4Byb,EAAeiB,kBAAkBf,EAAmBnhB,WAMtF,aALIwF,WAAgBhE,WAClBtF,EAAasF,QAAUgE,EAAehE,QACtCtF,EAAawG,SArFjB,SAAuBlB,EAAiBtF,GACtC,MAAO,iDAAiDsF,wCAjB1D,SAA0BrF,GACxB,OAAQA,GACN,IAAK,WAIL,IAAK,MACL,IAAK,MACH,MAAO,CAAC,sBAAuB,uBAJjC,IAAK,UACH,MAAO,CAAC,sBAAuB,kBAAmB,oBAMpD,QACE,MAAO,CAAC,qBAAsB,wBAAyB,cAAe,uBAE5E,CAGwGgmB,CACpGjmB,EAAaC,kBACbqB,KAAK,eAAetB,EAAaxD,OACrC,CAiF4B0pB,CAAc5c,EAAehE,QAAStF,IAGzDA,CACT,CAEO,SAASmmB,IAA0BxmB,IAAEA,EAAAqlB,UAAKA,EAAAC,mBAAWA,IAC1D,MAAMC,mBAAEA,GAAuBkB,IACzBC,EAAa1mB,EAAIma,cAAc,kBAC7B/Z,KAAMF,EAAAymB,OAAeA,EAAAlN,QAAQA,QAASxO,GAAU2b,EAAqBF,IACtEtmB,EAAMymB,GAAWpjB,MACjBqjB,EAAgBC,GAAqBtjB,IAAS,IAC9CujB,EAAcC,GAAmBxjB,GAAwB,MAE1DyjB,EAAUC,GAAYjC,UAC1B,GAAKyB,IAAU1b,EAAf,CAIA8b,GAAkB,GAClBE,EAAgB,MAChB,IACEJ,QACQ1B,GAA2B,CAC/BnlB,MACAqlB,YACAnlB,gBACAolB,qBACAC,uBAGN,OAAS6B,GACPH,GAAgB,MAAAG,OAAA,EAAAA,EAAGC,UAAWjT,OAAOgT,GACvC,CAAA,QACEL,GAAkB,EACpB,CAlBA,GAmBC,CAAC/mB,EAAKqlB,EAAWpa,EAAOsa,EAAoBrlB,EAAeolB,EAAoBqB,IAMlF,OAJApN,GAAU,KACR2N,KACC,CAACA,IAEG,CACL9mB,OACA6K,MAAOA,GAAS+b,EAChBrjB,SAAUgjB,GAAUG,EACpBI,QAAShC,UACPzL,KAGN,CA2BA,SAAS6N,GAAsBjnB,EAAmBL,EAAU1B,EAAc,CAAA,GACxE,GAAIumB,GAAyBP,mBAAmBjkB,GAC9C,OA3BJ,SAAmCA,EAAmBL,EAAU1B,EAAc,CAAA,GA3O9E,IAAA2B,EAAAsE,EA4OE,MAAM/G,EAAS6C,EAAa7C,QAAU,SAChC0O,EAAM,CACVxJ,cAAerC,EAAaxE,UAAY,MACxCmW,YAAa3R,EAAa5D,QAC1ByT,kBAAkB,OAAA3L,EAAA,OAAAtE,EAAAI,EAAa0M,oBAAY,SAAzB,EAAAxI,EAA6B1H,OAAQwD,EAAaxD,KACpEyD,iBAAkBD,EAAaC,iBAC/B9C,SACAiP,QAAS,CAACjP,GACVpC,KAAM,wBACHkD,GAML,OAHAhD,EAAqB4e,WAAW,mBAChC5e,EAAqB4e,WAAW,gBAEzB8C,EAAaD,YAAY,CAC9Bzb,YAAatB,EACb2I,YAAa,yBAAyBtI,EAAa4P,YAAc5P,EAAaxD,WAC5EwD,EAAa5D,iBAEfyP,IAAK,CAACA,IAEV,CAIWqb,CAA0BlnB,EAAcL,EAAK1B,GAGtD,MAAMd,EAAS6C,EAAa7C,QAAU,SACtC,OAAO2d,EAAmBqM,mBACxB,CACEC,YAAapnB,EAAa5D,QAC1BiG,cAAe,MACfsP,YAAa3R,EAAa5D,QAC1BirB,oBAAoB,EACpBxX,iBAAkB7P,EAAaxD,KAC/ByD,iBAAkBD,EAAaC,kBAAoB,UACnD9C,SACAiP,QAAS,CAACjP,GACVoH,MAAOvE,EAAauE,SACjBtG,GAEL0B,EAEJ,CAEA,SAAS2nB,IAA6BC,aACpCA,EAAAvnB,aACAA,IAMA,OADwBwkB,GAAyBP,mBAAmBjkB,MAAmBA,EAAalE,YAMlGuC,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,mBACftI,GAAAyE,cAAC,QAAA,CACC/H,KAAK,WACLob,SAAWwB,IACT4P,EAAaF,mBAAqB1P,EAAM6P,cAAcvL,WAExD,mCAVG,IAcX,CAEO,SAASwL,IAAuB9nB,IAAEA,EAAAK,aAAKA,IAC5C,GAAI0nB,EAAsBljB,WAAW,OACnC,OAAO,KAGT,MAAMmjB,GAAgB3nB,EAAaoE,WAAa,IAAItE,OAAS,EAwB7D,OACEzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,WAAW5C,GAAG,sCAC3B1F,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,yCAAyC,cAAY,WAAW5L,KAAK,UAAS,yBAGhGsD,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,iBACZtI,GAAAyE,cAAC8kB,EAAA,CAAgB3mB,YAAatB,EAAKkoB,SAAU7nB,EAAcwa,QA7BxC,KACvBuJ,GAA2B7I,KAAK,CAC9Bvb,MACAsB,YAAatB,EACbyY,mBAAmB,EACnBC,OAAO,EACPrY,eACAsP,KAAM,WAsBkF,uBAGpFqY,GACAtpB,GAAAyE,cAAC8kB,EAAA,CAAgB3mB,YAAatB,EAAKkoB,SAAU7nB,EAAcwa,QAvBxC,KACzB,MAAM+M,EAAe,CAAEF,oBAAoB,GAC3CvmB,EAAyBN,QAAQ,CAC/BpE,QAAS4D,EAAa5D,QACtB0rB,YAAazpB,GAAAyE,cAACwkB,GAAA,CAA6BC,eAA4BvnB,iBACvEU,WAAY,UAAUV,EAAaxD,OACnCiE,OAAQ,iBAAiBT,EAAaxD,QACtCoE,aAAc,CAAC3C,EAAc,CAAA,IAC3BgpB,GAAsBjnB,EAAcL,EAAK,CAAE0nB,mBAAoBE,EAAaF,sBAAuBppB,IACrG+C,kBAAmB,CAAEC,YAAatB,EAAKgB,MAAO,YAAYX,EAAaxD,YAcqB,wBAIzFmrB,GACCtpB,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,WAAWhG,MAAM,qEAC7BtC,GAAAyE,cAAC,IAAA,KAAE,0BAMf,CA2FO,MAAMilB,GAAiC,CAzFvC,UAA2C/nB,aAAEA,IAzWpD,IAAAJ,EA0WE,OACEvB,GAAAyE,cAACoE,GAAmBC,QAAQ,4BAA4BC,iBAAiB,GACvE/I,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,UAAG,WACJzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAACuE,EAAA,CAAWjL,QAAS4D,EAAa5D,WAEpCiC,GAAAyE,cAAC,KAAA,KAAG,UACJzE,GAAAyE,cAAC,UAAI9C,EAAa7C,QAAU,UAC5BkB,GAAAyE,cAAC,KAAA,KAAG,QACJzE,GAAAyE,cAAC,UAAI9C,EAAaC,kBAAoBD,EAAagoB,cAAgB,KAClEhoB,EAAasF,SACZjH,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,4BACH,KAAA,KAAI9C,EAAasF,WAGrB,OAAA1F,IAAaqiB,UAAb,EAAAriB,EAAkB8lB,MACjBrnB,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,OACJzE,GAAAyE,cAAC,KAAA,KACEoL,MAAMC,QAAQnO,EAAaiiB,IAAIyD,KAC5B1lB,EAAaiiB,IAAIyD,IAAIzpB,IAAKypB,GAAa,GAAGA,EAAIxV,aAAawV,EAAIE,WAAWtkB,KAAK,MAC/E,GAAGtB,EAAaiiB,IAAIyD,IAAIxV,aAAalQ,EAAaiiB,IAAIyD,IAAIE,aAO5E,EAEO,UAAyC5lB,aAAEA,IAChD,wBACGkH,EAAA,CAAmBC,QAAQ,YAAYC,iBAAiB,IACrDpH,EAAa0M,WAAa,IAAI5M,OAC9BzB,GAAAyE,cAAC,UACE9C,EAAa0M,UAAUzQ,IAAI,CAAC+Q,EAAeuE,IAC1ClT,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,GAAQ,CAACvE,EAASkD,SAAUlD,EAASgF,MAAQhF,EAASgD,WAAW1U,OAAOsY,SAAStS,KAAK,QAInGjD,GAAAyE,cAAC,OAAA,KAAK,2BAId,EAEO,UAA+C9C,aAAEA,IA1ZxD,IAAAJ,EAAAsE,EA2ZE,MAAM9G,GAAkB,OAAAwC,EAAAI,EAAaiiB,UAAb,EAAAriB,EAAkBxC,kBAAmB,GACvDvB,GAAe,OAAAqI,EAAAlE,EAAaiiB,UAAb,EAAA/d,EAAkBrI,eAAgB,GAEvD,OAAKuB,EAAgB0C,QAAWjE,EAAaiE,OAK3CzB,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,mBAAmBC,iBAAiB,GAC7DhK,EAAgB0C,OAAS,GACxBzB,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,KAAA,KAAG,YACJzE,GAAAyE,cAAC,KAAA,KAAI1F,EAAgBnB,IAAKqU,GAAwBA,EAAe9T,MAAM8E,KAAK,QAG/EzF,EAAaiE,OAAS,GACrBzB,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,KAAA,KAAG,kCACH,KAAA,KAAIjH,EAAaI,IAAKH,GAAqBA,EAAYU,MAAM8E,KAAK,SAdlE,IAmBX,EAEO,UAAoCtB,aAAEA,IAC3C,OACE3B,GAAAyE,cAACoE,GAAmBC,QAAQ,OAAOC,iBAAiB,GACjDpH,EAAawG,SACZnI,GAAAyE,cAAC,IAAA,CAAE0E,KAAMxH,EAAawG,SAAUiB,OAAO,SAASC,IAAI,uBAAsB,0BAI1ErJ,GAAAyE,cAAC,OAAA,KAAK,yBAId,GC1bO,MAAMmlB,GAAN,WAAAvrB,GACLd,KAAiB4oB,yBAA2B,IAAIR,GA0BhDpoB,KAAOssB,yBAA4BroB,IACjC,MAAOsoB,EAAmBC,GAAsBC,GAAUxoB,EAAgBqkB,GACxEtoB,KAAK4oB,yBAAyBP,mBAAmBC,IAG7CoE,EAAkBC,GAAQJ,EAAmB,cAMnD,OALuClsB,GACrCqsB,EACAL,GAA8BO,gCAG8BhD,OAAO4C,GACvE,CApCA,qCAAeI,CAA+BC,GAC5C,MAAMlZ,EAAapG,GAAUsf,EAAM,IAgBnC,OAdAlZ,EAAW7C,UAAY+b,EAAMxsB,IAAK+D,IAEzB,CACLgS,KAFWhS,EAAagQ,UAAYiY,GAA8BS,eAAe1oB,EAAagQ,WAAa,KAG3GxT,KAAMwD,EAAaxD,KACnBjB,YAAayE,EAAazE,YAC1BuW,eAAgB9R,EAAa8R,eAC7B/B,UAAW/P,EAAa+P,UACxBnK,OAAQ5F,EAAa4F,UAIzB2J,EAAW/S,KAAO+S,EAAWK,kBACtBL,EAAW3J,OACX2J,CACT,CAEA,qBAAemZ,CAAe1Y,GAC5B,OAAOA,EAAUpR,MAAM,KAAK,EAC9B,ECzBK,MAAM+pB,GACX,WAAAjsB,CAAYuL,GACV,SAAS2gB,EAAmBC,GAC1B,MAAMzkB,EAAYykB,EAAUzkB,UACtBD,EAAe0kB,EAAU1kB,cAAgB,CAAC0kB,GAChDA,EAAUC,eAAiB,CACzBC,GAAI3kB,EAAU9I,OAAQgE,GACgB,cAA7BA,EAASE,OAAO,GAAGD,OACzBO,OACHkpB,KAAM5kB,EAAU9I,OAAQgE,GACc,iBAA7BA,EAASE,OAAO,GAAGD,OACzBO,OACHmpB,aAAc9kB,EAAaiG,OAAO,CAAC8e,EAAK5mB,IAEpCA,EAAY8B,UAAU9I,OAAQgE,GACI,iBAAzBA,EAAS6pB,aACfrpB,OAASopB,EAEb,GAEP,CAmIA,MAAO,CACLE,sBAnHF,SAA+BppB,GAC7BA,EAAamE,aAAaxG,QAAQ,SAAU2E,GAC1CA,EAAYlG,QAAU4D,EAAa5D,QAC/BkG,EAAY+mB,mBACd/mB,EAAY+mB,kBAAoB/mB,EAAY+mB,kBAAkBptB,IAAI,SAAUqE,GAC1E,MAAO,CAAEyD,GAAIzD,EACf,GACAgC,EAAY8B,UAAY9B,EAAY8B,UAAUohB,OAAOljB,EAAY+mB,oBAEjE/mB,EAAY+mB,kBAAoB,GAGlC/mB,EAAY8B,UAAUzG,QAAQ,SAAU2B,IA3B5C,SAA2BA,EAAUU,GACnCV,EAASE,OAASF,EAASE,QAAU,CAAA,EACrCF,EAAS9D,SAAWwE,EAAajF,KACjCuE,EAASlD,QAAU4D,EAAa5D,QAChCkD,EAASnC,OAAS6C,EAAa7C,OAC/BmC,EAASE,OAAOzE,KAAO,eACvBuE,EAAS6pB,YAAc7pB,EAASE,OAAOD,MACT,cAA1BD,EAASE,OAAOD,MACd,KACA,OACF,eACJD,EAASE,OAAS,CAACF,EAASE,QAC5BF,EAASO,cAAgB,CAACG,EAAaxD,KACzC,CAeM8sB,CAAkBhqB,EAAUU,EAC9B,GACA4oB,EAAmBtmB,EACrB,GACA,MAAMinB,EAAqBpqB,GAAE7D,OAAO0E,EAAamE,aAAc,CAAEK,YAAY,IAS7E,OARAxE,EAAaxE,SAAWwE,EAAajF,KACrCiF,EAAaoE,UAAYjF,GAAE8L,MAAMse,GAAoBttB,IAAI,aAAawN,UAAUyB,QAChFlL,EAAaqpB,kBAAoBlqB,GAAE8L,MAAMse,GAAoBttB,IAAI,qBAAqBwN,UAAUyB,QAC5F/L,GAAEjE,IAAI8E,EAAc,gCACtBA,EAAasQ,eAAexU,YAAY0tB,QAAUxpB,EAAasQ,eAAexU,YAAY+Z,WAC1F7V,EAAasQ,eAAexU,YAAY2tB,SAAWzpB,EAAasQ,eAAexU,YAAYga,kBAE7F8S,EAAmB5oB,GACZiI,EAAe7J,QAAQ4B,EAChC,EAyFE0pB,8BAvFF,SAAuC1pB,GACrC,MAAM2pB,EAAS,CACbnuB,SAAU,MACV2B,OAAQ6C,EAAa7C,OACrBwU,YAAa3R,EAAa5D,QAC1BsQ,UAAW,GACXlQ,KAAMwD,EAAaxD,KACnBotB,YAAa5pB,EAAa6pB,mBAG5B,GAAI7pB,EAAaiiB,IAAK,CACpB,MAAMA,EAAMjiB,EAAaiiB,IAezB,GAbA0H,EAAOplB,MAAQ0d,EAAIkD,MAEflD,EAAIC,uBACNyH,EAAOjd,UAAYuV,EAAIC,qBAAqBjmB,IAAI,SAAUqM,GACxD,MAAM0E,EAAW1E,EAAY0E,SAC7B,MAAO,CACLkD,SAAUlD,EAASkD,SACnBF,UAAWhD,EAASoV,iBACpBtmB,iBAAiC,IAApBmmB,EAAInmB,YAErB,IAGEmmB,EAAInmB,aAAemmB,EAAInmB,YAAY2L,OAAQ,CAC7CkiB,EAAOG,cAAgB7H,EAAInmB,YAAY0tB,QACvCG,EAAOI,eAAiB9H,EAAInmB,YAAY2tB,SACxCE,EAAO5T,iBAAmBkM,EAAInmB,YAAYia,iBAC1C4T,EAAO3T,mBAAqBiM,EAAInmB,YAAYka,mBAE5C,MAAMla,EAAckE,EAAaiiB,IAAInmB,YAAY2L,OAC3CuiB,EAAgBluB,EAAY+C,QAAQ,KACpCorB,EAAYnuB,EAAY+C,QAAQ,MAEhB,IAAlBmrB,QAAwBC,IAC1BN,EAAOO,oBAAsBpuB,EAAYquB,UAAU,EAAGH,GACtDL,EAAOS,gBAAkBtuB,EAAYquB,UAAUH,EAAgB,EAAGC,GAClEN,EAAOU,gBAAkBvuB,EAAYquB,UAAUF,GAC1CK,MAAMX,EAAOS,mBAChBT,EAAOS,gBAAkBrY,OAAO4X,EAAOS,kBAG7C,MACET,EAAOO,oBAAsB,OAC7BP,EAAOS,gBAAkB,GACzBT,EAAOU,gBAAkB,IACzBV,EAAOG,cAAgB,EACvBH,EAAOI,eAAiB,GACxBJ,EAAO5T,iBAAmB,GAC1B4T,EAAO3T,mBAAqB,EAG9B2T,EAAO3U,gBAAkBhV,EAAagV,iBAAmB,MAC3D,CACA,OAAO2U,CACT,EA+BEY,iCA7BF,WACE,MAAO,CACL/uB,SAAU,MACVgvB,MAAO,GACP7E,OAAQ,GACRhU,YAAa6P,GAAoB/V,SAASrP,QAC1Ce,OAAQqkB,GAAoB/V,SAAStO,OACrC+sB,oBAAqB,OACrBE,gBAAiB,GACjBC,gBAAiB,IACjBP,cAAe,EACfC,eAAgB,GAChBhU,iBAAkB,GAClBC,mBAAoB,EACpBhB,gBAAiB,OACjB4U,YAAa,GACbld,UAAW,CACT,CACEwD,SAAU,MACVF,UAAW,OACXlU,aAAa,IAIrB,EAOF,EClKF,wICkBA,MAAM2uB,GAAIpsB,GAAMyE,cAEhB,SAAS4nB,GAAYC,EAAOD,EAAaE,GACvCF,EAAY,IAAKC,KAAUC,GAC7B,CAEA,SAASC,GAAaF,GACpB,SACEA,EAAMG,kBACLH,EAAMI,oBAAsBjuB,OAAOY,KAAKitB,EAAMI,oBAAoBjrB,QACnE6qB,EAAMK,aACNL,EAAMM,SACNN,EAAMvD,YAEV,CAEA,MAAM8D,WAA2B7sB,GAAMC,UAAvC,WAAA5B,GAAAyjB,SAAA8C,WACEzkB,GAAA5C,KAAA,QAAQ,CACNuvB,iBAAkB,GAClBC,cAAe,GACfC,WAAW,EACXC,oBAAqBT,GAAajvB,KAAKsH,MAAMynB,QAC/C,CAEA,iBAAAlK,GACE,MAAMkK,MAAEA,EAAOD,YAAa1T,GAAWpb,KAAKsH,MAC5CynB,EAAMI,mBAAqBJ,EAAMI,oBAAsB,CAAA,EACvDJ,EAAMxtB,OAAS,SACfwtB,EAAMtoB,cAAgBsoB,EAAMtoB,eAAiB,MAC7CsoB,EAAMY,KAAOZ,EAAMY,MAAQC,EAAsBC,uBAAuBjvB,KAExE2B,QAAQkP,IAAI,CAACqe,EAAaC,iBAAiB,OAAQD,EAAaE,wBAAwBzwB,KACtF,EAAEiwB,EAAeD,MACf,MAAMU,GAAa,MAAAT,OAAA,EAAAA,EAAeS,aAAc,GAC1CjB,EAAU,CAAA,GACXD,EAAMmB,QAAUD,EAAW/rB,SAC9B8qB,EAAQkB,OAASD,EAAW,GAAG9nB,KAE5B4mB,EAAMoB,YAAa,MAAAZ,SAAAA,EAAkBrrB,UACxC8qB,EAAQmB,UAAYZ,EAAiB,IAEnCruB,OAAOY,KAAKktB,GAAS9qB,QACvBkX,EAAO,IAAK2T,KAAUC,IAExBhvB,KAAKqd,SAAS,CACZkS,iBAAkBA,GAAoB,GACtCC,cAAeS,EACfR,UACE/f,EAASmW,QAAQ4J,WAC0B,mBAAnC/f,EAASmW,QAAQuK,eAAgC1gB,EAASmW,QAAQuK,cAAcrB,GAC1FW,oBAAqBT,GAAa,IAAKF,KAAUC,OAIzD,CAEA,sBAAAqB,GACE,MAAMC,SAAEA,EAAAvB,MAAUA,EAAOD,YAAa1T,GAAWpb,KAAKsH,MAChDipB,EAAoBC,EAAwBC,qCAAqC1B,EAAOuB,GACxFI,EAAqB3B,EAAM2B,oBAAsB,GAEvD,OAAO7B,GACL8B,EACA,CAAE7qB,MAAO,qBACT+oB,GACE,SACA,CACE9jB,UAAW,wBACX6lB,UAAU,EACVthB,MAAOohB,EACPnW,SAAW4Q,IACT,MAAMlL,EAAW3N,MAAMkD,KAAK2V,EAAEtf,OAAOglB,iBAAiBxwB,IAAK8b,GAAWA,EAAO7M,OAC7Ewf,GAAYC,EAAO3T,EAAQ,CAAEsV,mBAAoBzQ,MAGrDsQ,EAAkBlwB,IAAKywB,GACrBjC,GAAE,SAAU,CAAE7sB,IAAK8uB,EAAS3oB,GAAImH,MAAOwhB,EAAS3oB,IAAM2oB,EAASC,aAAeD,EAAS3oB,MAI/F,CAEA,qBAAA6oB,GACE,MAAMjC,MAAEA,EAAOD,YAAa1T,GAAWpb,KAAKsH,MAC5C,OAAKtH,KAAK2D,MAAM+rB,oBAITb,GACLpsB,GAAMwI,SACN,KACA4jB,GACE8B,EACA,CAAE7qB,MAAO,sBACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAMG,kBAAoB,GACjC3U,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAE8T,iBAAkB/D,EAAEtf,OAAOyD,WAG7Euf,GACE8B,EACA,CAAE7qB,MAAO,gBACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAMvD,aAAe,GAC5BjR,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAEoQ,YAAaL,EAAEtf,OAAOyD,WAGxEuf,GACE8B,EACA,CAAE7qB,MAAO,uBACT+oB,GAAEoC,EAAW,CACXC,YAAY,EACZC,MAAOpC,EAAMI,oBAAsB,CAAA,EACnC5U,SAAW4U,GAAuBL,GAAYC,EAAO3T,EAAQ,CAAE+T,0BAGnEN,GACE8B,EACA,CAAE7qB,MAAO,iBACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAMK,aAAe,GAC5B7U,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAEgU,YAAajE,EAAEtf,OAAOyD,WAGxEuf,GACE8B,EACA,CAAE7qB,MAAO,cACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAMM,SAAW,GACxB9U,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAEiU,QAASlE,EAAEtf,OAAOyD,YAhD7D,IAoDX,CAEA,MAAA0V,GACE,MAAM+J,MAAEA,EAAOD,YAAa1T,GAAWpb,KAAKsH,MAM5C,OALAynB,EAAMI,mBAAqBJ,EAAMI,oBAAsB,CAAA,EACvDJ,EAAMxtB,OAAS,SACfwtB,EAAMtoB,cAAgBsoB,EAAMtoB,eAAiB,MAC7CsoB,EAAMY,KAAOZ,EAAMY,MAAQC,EAAsBC,uBAAuBjvB,KAEjEiuB,GACL,MACA,KACAA,GACE8B,EACA,CAAE7qB,MAAO,WACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAMqC,SAAW,GACxB7W,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAEgW,QAASjG,EAAEtf,OAAOyD,WAGpEtP,KAAKqwB,yBACLxB,GAAE,MACFA,GACE8B,EACA,CAAE7qB,MAAO,WACT+oB,GACE,SACA,CACE9jB,UAAW,wBACXuE,MAAOyf,EAAMmB,QAAU,GACvB3V,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAE8U,OAAQ/E,EAAEtf,OAAOyD,SAEjEtP,KAAK2D,MAAM6rB,cAAcnvB,IAAK8b,GAC5B0S,GACE,SACA,CAAE7sB,IAAKma,EAAOhU,GAAImH,MAAO6M,EAAOhU,IAChCgU,EAAO4U,aAAe5U,EAAOkV,kBAAoBlV,EAAOhU,OAKhE0mB,GACE8B,EACA,CAAE7qB,MAAO,cACT9F,KAAK2D,MAAM4rB,iBAAiBlvB,IAAK8vB,GAC/BtB,GACE,QACA,CAAE9jB,UAAW,eAAgB/I,IAAKmuB,GAClCtB,GAAE,QAAS,CACTxO,QAAS0O,EAAMoB,YAAcA,EAC7BhxB,KAAM,QACNob,SAAU,IAAMuU,GAAYC,EAAO3T,EAAQ,CAAE+U,gBAE/C,IAAIA,OAIVtB,GAAE,OACD7uB,KAAK2D,MAAM8rB,WAAaV,EAAMuC,SAC7BzC,GACE8B,EACA,CAAE7qB,MAAO,UACT+oB,GACE,MACA,CAAE9jB,UAAW,WAAYoX,MAAO,CAAEoP,aAAc,IAChD1C,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,UAAW0O,EAAMuC,OACjBnyB,KAAM,WACNob,SAAW4Q,GAAM2D,GAAYC,EAAO3T,EAAQ,CAAEkW,OAAQnG,EAAEtf,OAAOwU,YAEjE,qEAIRwO,GACE,MACA,CAAE9jB,UAAW,cACb8jB,GACE,MACA,CAAE9jB,UAAW,4BACb8jB,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,QAASrgB,KAAK2D,MAAM+rB,oBACpBvwB,KAAM,WACNob,SAAW4Q,GAAMnrB,KAAKqd,SAAS,CAAEqS,oBAAqBvE,EAAEtf,OAAOwU,YAEjEwO,GAAE,SAAU,KAAM,8BAK1B7uB,KAAKgxB,wBAET,EAQK,SAASQ,GAA0BzC,GACxC,MAAM0C,EAAU1C,EAAM0C,SAAW,CAAA,EAI3BC,IAFJhiB,EAASmW,QAAQ4J,WAC0B,mBAAnC/f,EAASmW,QAAQuK,eAAgC1gB,EAASmW,QAAQuK,cAAcqB,KAC3D/hB,EAASiiB,eAAiBjiB,EAASiiB,eAAiBjiB,EAASkiB,kBAAoB,GAC1G/U,EAAS,CAAE4U,WAEjB,OAAOC,EAASlnB,QAAQ,0BAA2B,CAACqnB,EAAQC,IAb9D,SAAsBjV,EAAQiV,GAC5B,MAAMxiB,EAAQwiB,EAAK9uB,MAAM,KAAKwL,OAAO,CAAC8e,EAAKtrB,IAAQ,MAAAsrB,OAAA,EAAAA,EAAMtrB,GAAM6a,GAC/D,OAAgB,MAATvN,EAAgB,GAAK6I,OAAO7I,EACrC,CAUuEyiB,CAAalV,EAAQiV,GAC5F,CAEA,SAASE,GAAwB1qB,GApRjC,IAAAtD,EAAAsE,EAAAe,EAAAC,EAqRE,MAAM6T,QAAEA,EAAA8U,UAASA,EAAAlD,MAAWA,GAAUznB,EAChCmqB,EAAU1C,EAAM0C,SAAW,CAAA,EAC3BhC,EACJ/f,EAASmW,QAAQ4J,WAC0B,mBAAnC/f,EAASmW,QAAQuK,eAAgC1gB,EAASmW,QAAQuK,cAAcqB,GACpFS,EAAgBV,GAA0BzC,GAEhD,OAAOF,GACLsD,EACA,CAAEvxB,KAAM0G,EAAM1G,KAAMuc,WACpB0R,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,KACA,CAAE9jB,UAAW,2BACb8jB,GAAE,KAAM,KAAM,SACdA,GAAE,KAAM,KAAM4C,EAAQW,KACtBvD,GAAE,KAAM,KAAM,UACdA,GAAE,KAAM,KAAM4C,EAAQlwB,QACtBstB,GAAE,KAAM,KAAM,WACdA,GAAE,KAAM,KAAM4C,EAAQL,WAG1BvC,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,KACA,CAAE9jB,UAAW,2BACb8jB,GAAE,KAAM,KAAM,WACdA,GAAE,KAAM,KAAM4C,EAAQvB,QACtBrB,GAAE,KAAM,KAAM,SACdA,GAAE,KAAM,KAAM4C,EAAQtB,YACrBV,IAAa,OAAAzrB,EAAAiuB,EAAUI,gBAAVruB,EAAmBstB,SAAUG,EAAQH,SAAWzC,GAAE,KAAM,KAAM,WAC3EY,IAAa,OAAAnnB,EAAA2pB,EAAUI,kBAASf,SAAUG,EAAQH,SACjDzC,GAAE,KAAM,KAAM1W,QAAO,OAAA9O,IAAUgpB,cAAV,EAAAhpB,EAAmBioB,SAAUG,EAAQH,SAAU,IACtEG,EAAQvC,kBAAoBL,GAAE,KAAM,KAAM,YAC1C4C,EAAQvC,kBAAoBL,GAAE,KAAM,KAAM4C,EAAQvC,kBAClDuC,EAAQjG,aAAeqD,GAAE,KAAM,KAAM,gBACrC4C,EAAQjG,aAAeqD,GAAE,KAAM,KAAM4C,EAAQjG,aAC7CiG,EAAQrC,aAAeP,GAAE,KAAM,KAAM,YACrC4C,EAAQrC,aAAeP,GAAE,KAAM,KAAM4C,EAAQrC,gBAInDP,GAAEyD,EAAqB,CAAEvD,QAAO3D,QAAS2D,EAAMwD,iBAC/Cd,EAAQlwB,SACN,OAAA+H,EAAAmoB,EAAQxgB,iBAAQuhB,aAChB3D,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,aACb8jB,GACE,MACA,CAAE9jB,UAAW,gBAAegkB,EAAM0D,SAAW,SAAW,SACxDhB,EAAQiB,iBAAmB7D,GAAE,MAAO,KAAM,6CAC1CqD,GACErD,GAAE,IAAK,CAAEhjB,OAAQ,SAAUC,IAAK,sBAAuBF,KAAMsmB,GAAiB,uBAChFT,EAAQkB,WACN9D,GAAE,MAAO,KAAMA,GAAE,SAAU,KAAM,UAAWA,GAAE,MAAO,CAAE9jB,UAAW,cAAgB0mB,EAAQkB,eAKxG,CAGO,SAASC,KACdC,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,OACVtsB,cAAe,MACfX,MAAO,OACP4G,YAAa,iBACbsmB,UAAW1D,GACX2D,yBAA0B,CAACjB,GAAyBkB,EAAuBC,GAC3EC,wBAAyBC,EACzBC,gBAAkBvE,GACTA,EAAMwE,YAAY9B,QAAQ+B,oBAAsBzE,EAAMwE,YAAY9B,QAAQgC,oBAAsB,EAAI,EAE7GC,mBAAmB,EACnBC,uBAAuB,EACvBC,WAAY,CACV,CACEz0B,KAAM,mBACN00B,OAAQ,CACN,CAAEC,UAAW,UAAWC,WAAY,WACpC,CAAED,UAAW,qBAAsBC,WAAY,wBAIrDC,aAAa,EACbC,kBAAmBzD,EAAwB0D,oBAAoB,CAAC,uBAChEC,gBAAiBC,EAAyBC,yBAAyB,CAAC,wBAExE,CA7BArC,GAAwBjtB,MAAQ,qJChVhC,MAAM8pB,GAAIpsB,GAAMyE,cAEHotB,GAAyB,CACpC,CACExuB,MAAO,UACPyuB,IAAK,UACL7nB,YAAa,sFAEf,CAAE5G,MAAO,SAAUyuB,IAAK,SAAU7nB,YAAa,wDAC/C,CAAE5G,MAAO,SAAUyuB,IAAK,SAAU7nB,YAAa,wDAC/C,CAAE5G,MAAO,OAAQyuB,IAAK,OAAQ7nB,YAAa,4CAGvC8nB,GAAe,CACnB,CAAE1uB,MAAO,WAAYyuB,IAAK,YAC1B,CAAEzuB,MAAO,aAAcyuB,IAAK,cAC5B,CAAEzuB,MAAO,wBAAyByuB,IAAK,oBACvC,CAAEzuB,MAAO,sBAAuByuB,IAAK,gBAGjCE,GAAc,CAClB,CAAE3uB,MAAO,aAAcyuB,IAAK,OAC5B,CAAEzuB,MAAO,cAAeyuB,IAAK,SAG/B,SAASG,GAAW3F,EAAO/sB,EAAKsN,QACX,IAAfyf,EAAM/sB,IAAqC,OAAf+sB,EAAM/sB,KACpC+sB,EAAM/sB,GAAOsN,EAEjB,CAEO,SAASqlB,GAAmB5F,EAAO1pB,EAAawK,EAAW,CAAA,GA3ClE,IAAA7L,EAAAsE,EAAAe,EA4CEqrB,GAAW3F,EAAO,gBAAiB,OACnC2F,GAAW3F,EAAO,oBAAqB,OACvC2F,GAAW3F,EAAO,cAAe,OAAA/qB,EAAA,MAAAqB,SAAAA,EAAauvB,6BAAoBhlB,KAClEmf,EAAMve,QAAUue,EAAMve,SAAW,IAC5Bue,EAAMve,QAAQtM,SAAU,OAAAoE,EAAA,MAAAjD,OAAA,EAAAA,EAAawvB,yBAAgBjlB,MACxDmf,EAAMve,QAAQ3K,KAAKR,EAAYwvB,eAAejlB,KAEhD1O,OAAOY,KAAK+N,GAAU9N,QAASC,GAAQ0yB,GAAW3F,EAAO/sB,EAAK6N,EAAS7N,KAErE+sB,EAAMtS,QACN,OAAApT,EAAA,MAAAhE,OAAA,EAAAA,EAAayvB,qBAAYC,iCACzB1vB,EAAYyvB,WAAWE,qBAEvBjG,EAAMxoB,+BAAiC,CAAC,UAE5C,CAEA,SAAS0uB,GAAa3tB,EAAOynB,GAC3BznB,EAAMwnB,YAAY,IAAKC,GACzB,CAEA,SAASD,GAAYxnB,EAAO0nB,GAC1BiG,GAAa3tB,EAAO,IAAKA,EAAMynB,SAAUC,GAC3C,CAoBA,SAASkG,IAAY5lB,MAAEA,EAAAiL,SAAOA,EAAAD,SAAUA,GAAW,EAAA6H,MAAOA,IACxD,OAAO0M,GAAE,QAAS,CAChB9jB,UAAW,wBACXuP,WACAT,IAAK,EACLsI,QACAhjB,KAAM,SACNmQ,MAAO,MAAAA,EAAAA,EAAS,GAChBiL,SAAW4Q,GAAM5Q,EA1BrB,SAAqBjL,GACnB,MAAiB,KAAVA,SAA2B6G,OAAO7G,EAC3C,CAwB8B6lB,CAAYhK,EAAEtf,OAAOyD,SAEnD,CAEA,SAAS8lB,IAAY9lB,MAAEA,EAAAiL,SAAOA,EAAAG,QAAUA,IACtC,OAAOmU,GACL,SACA,CAAE9jB,UAAW,wBAAyBuE,MAAO,MAAAA,EAAAA,EAAS,GAAIiL,SAAW4Q,GAAM5Q,EAAS4Q,EAAEtf,OAAOyD,QAC7Fuf,GAAE,SAAU,CAAEvf,MAAO,IAAM,aAC3BoL,EAAQra,IAAK8b,GACX0S,GAAE,SAAU,CAAE7sB,IAAKma,EAAOoY,KAAOpY,EAAOvb,KAAM0O,MAAO6M,EAAOoY,KAAOpY,EAAOvb,MAAQub,EAAOrW,OAASqW,EAAOvb,OAG/G,CAEA,SAASy0B,IAAkB/lB,MAAEA,EAAAiL,SAAOA,EAAAG,QAAUA,EAAAyH,MAASA,IACrD,OAAO0M,GACL,SACA,CAAE9jB,UAAW,wBAAyBoX,QAAO7S,MAAO,MAAAA,EAAAA,EAAS,GAAIiL,SAAW4Q,GAAM5Q,EAAS4Q,EAAEtf,OAAOyD,QACpGoL,EAAQra,IAAK8b,GAAW0S,GAAE,SAAU,CAAE7sB,IAAKma,EAAOoY,IAAKjlB,MAAO6M,EAAOoY,KAAOpY,EAAOrW,QAEvF,CAEA,SAASwvB,IAAeC,SAAEA,EAAW,CAAA,WAAIjb,GAAW,EAAAC,SAAOA,IACzD,MAAMib,EAAiB,CAAC1d,EAAOxI,IAAUiL,EAAS,IAAKgb,EAAUzd,CAACA,GAAQxI,IAC1E,OAAOuf,GACLpsB,GAAMwI,SACN,KACA4jB,GACE,MACA,CAAE9jB,UAAW,cACb8jB,GAAE,MAAO,CAAE9jB,UAAW,4BAA8B,OACpD8jB,GAAE,MAAO,CAAE9jB,UAAW,YAAc,OACpC8jB,GAAE,MAAO,CAAE9jB,UAAW,YAAc,YAEtC8jB,GACE,MACA,CAAE9jB,UAAW,cACb8jB,GACE,MACA,CAAE9jB,UAAW,4BACb8jB,GAAEqG,GAAa,CAAE5a,WAAUhL,MAAOimB,EAAS1b,IAAKU,SAAWjL,GAAUkmB,EAAe,MAAOlmB,MAE7Fuf,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GAAEqG,GAAa,CAAE5a,WAAUhL,MAAOimB,EAAS5mB,IAAK4L,SAAWjL,GAAUkmB,EAAe,MAAOlmB,MAE7Fuf,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GAAEqG,GAAa,CAAE5a,WAAUhL,MAAOimB,EAASE,QAASlb,SAAWjL,GAAUkmB,EAAe,UAAWlmB,OAI3G,CAEA,SAASomB,IAA0BrwB,YAAEA,EAAA0pB,MAAaA,EAAOD,YAAa1T,IAxJtE,IAAApX,EAyJE,KAAK,OAAAA,EAAA,MAAAqB,OAAA,EAAAA,EAAayvB,iBAAb,EAAA9wB,EAAyB+wB,gCAC5B,OAAO,KAGT,MAAM1U,EACJ/N,MAAMC,QAAQwc,EAAMxoB,iCAA+E,WAA5CwoB,EAAMxoB,+BAA+B,GAE9F,OAAOsoB,GACL8B,EACA,CAAE7qB,MAAO,mBACT+oB,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,UACAlhB,KAAM,WACNob,SAAW4Q,GACT/P,EAAO,IAAK2T,EAAOxoB,+BAAgC4kB,EAAEtf,OAAOwU,QAAU,CAAC,eAAY,MAEvF,iCAIR,CAEA,MAAMsV,WAA2BlzB,GAAMC,UAAvC,WAAA5B,GAAAyjB,SAAA8C,WACEzkB,GAAA5C,KAAA,QAAQ,CAAEsQ,SAAU,IAAG,CAEvB,iBAAAuU,GACErX,EAAe4E,aAAa,OAAO7S,KAAM+Q,GAAatQ,KAAKqd,SAAS,CAAE/M,aACxE,CAEA,kCAAAslB,CAAmClb,EAAU,IAC3C,MAAMrV,YAAEA,EAAAirB,SAAaA,EAAAvB,MAAUA,GAAU/uB,KAAKsH,MAC9C,aAAIgpB,WAAUuF,UACL,KAGFhH,GAAEiH,EAA8B,CACrCxlB,SAAUtQ,KAAK2D,MAAM2M,SACrBjL,cACA0wB,aAAcrb,EAAQqb,aACtB/C,UAAWjE,EACXiH,aAActb,EAAQsb,cAE1B,CAEA,kBAAAC,CAAmBvb,EAAUwb,EAAeC,aAC1C,OAAOtH,GACL8B,EACA,CAAE7qB,MAAO,UACT+oB,GAAEuH,EAAc,CAAEjF,MAAOnxB,KAAKsH,MAAMynB,MAAOrU,UAASH,SAAW1O,GAAWijB,GAAY9uB,KAAKsH,MAAO,CAAEuE,aAExG,CAEA,gCAAAwqB,GACE,OAAOxH,GAAEyH,EAA4B,CACnCxgB,QAAS9V,KAAKsH,MAAMynB,MACpBwH,aAAc,IACdC,cAAe,CAACx0B,EAAKsN,IAAUwf,GAAY9uB,KAAKsH,MAAO,CAAEtF,CAACA,GAAMsN,IAChEmnB,iBAAmB3gB,GAAYmf,GAAaj1B,KAAKsH,MAAOwO,IAE5D,EAGK,MAAM4gB,WAAwCf,GACnD,MAAA3Q,GACE,MAAM3f,YAAEA,EAAA0pB,MAAaA,EAAA4H,mBAAOA,GAAqB,GAAU32B,KAAKsH,MAEhE,OADAqtB,GAAmB5F,EAAO1pB,EAAa,CAAEwG,OAAQqqB,EAAeC,YAAY,GAAG5B,MACxE1F,GACL,MACA,KACA7uB,KAAK41B,qCACL51B,KAAKi2B,qBACLU,GACE9H,GAAE6G,GAA2B,CAC3BrwB,cACA0pB,QACAD,YAAc8H,GAAc3B,GAAaj1B,KAAKsH,MAAOsvB,KAG7D,EAGK,SAASC,GAAyBvvB,GACvC,OAAOunB,GAAE6H,GAAiC,IAAKpvB,EAAOqvB,oBAAoB,GAC5E,CAEO,SAASG,GAAwBxvB,GACtC,OAAOunB,GAAE6H,GAAiC,IAAKpvB,EAAOqvB,oBAAoB,GAC5E,CAaO,MAAMI,WAAuCpB,GAClD,MAAA3Q,GACE,MAAM3f,YAAEA,EAAA0pB,MAAaA,GAAU/uB,KAAKsH,MACpCqtB,GAAmB5F,EAAO1pB,EAAa,CAAEwG,OAAQqqB,EAAeC,YAAY,GAAG5B,MAC/EG,GAAW3F,EAAO,cAAe,MAAA1pB,OAAA,EAAAA,EAAazE,MAC9C8zB,GAAW3F,EAAO,qBAAqB,GAhB3C,SAAiCA,GAC/B,GAAIA,EAAMiI,cAAe,CACvB,MAAMC,EAAcC,EAAUC,qBAAqBpI,EAAMiI,eACzDjI,EAAMH,MAAQqI,EAAYrI,MAC1BG,EAAMqI,gBAAkBH,EAAYG,eACtC,MACErI,EAAMH,MAAQ,GACdG,EAAMqI,gBAAkB,EAE5B,CAQIC,CAAwBtI,GASxB,OAAOF,GACL,MACA,KACA7uB,KAAK41B,mCAAmC,CAAEG,aAAc,gBAAiBC,cAAc,IACvFh2B,KAAKi2B,qBACLpH,GACE,MACA,KACAA,GACE,MACA,CAAE9jB,UAAW,cACb8jB,GAAE,MAAO,CAAE9jB,UAAW,2BAA6B,YACnD8jB,GACE,MACA,CAAE9jB,UAAW,kBACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CAAExO,SAAqC,IAA5B0O,EAAMuI,kBAA4Bn4B,KAAM,QAASob,SAxBvD,KACxB,MAAMqc,EAAY,IAAK7H,EAAOuI,mBAAmB,UAC1CV,EAAUrB,SACjBN,GAAaj1B,KAAKsH,MAAOsvB,MAsBjB,qDAGJ/H,GACE,MACA,CAAE9jB,UAAW,kCACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,SAAqC,IAA5B0O,EAAMuI,kBACfn4B,KAAM,QACNob,SAAU,IAAMuU,GAAY9uB,KAAKsH,MAAO,CAAEiuB,SAAUxG,EAAMwG,UAAY,GAAI+B,mBAAmB,MAE/F,kCAINzI,GAAEyG,GAAgB,CAAEC,SAAUxG,EAAMwG,SAAUjb,SAAUyU,EAAMuI,kBAAmB/c,SA5C7Dgb,GAAazG,GAAY9uB,KAAKsH,MAAO,CAAEiuB,WAAU+B,mBAAmB,OA8C1FzI,GACE8B,EACA,CAAE7qB,MAAO,WACT+oB,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,SAAU0O,EAAMwI,eAChBp4B,KAAM,WACNob,SAAW4Q,GAAM2D,GAAY9uB,KAAKsH,MAAO,CAAEiwB,gBAAiBpM,EAAEtf,OAAOwU,YAEvE,4CAINwO,GAAE6G,GAA2B,CAC3BrwB,cACA0pB,QACAD,YAAc8H,GAAc3B,GAAaj1B,KAAKsH,MAAOsvB,KAEvD52B,KAAKq2B,mCAET,EAGK,MAAMmB,WAAgC7B,GAC3C,MAAA3Q,GACE,MAAM3f,YAAEA,EAAA0pB,MAAaA,GAAU/uB,KAAKsH,MAEpC,OADAqtB,GAAmB5F,EAAO1pB,EAAa,CAAEoyB,kBAAmBnD,GAAuB,GAAGC,IAAKmD,aAAa,IACjG7I,GACL,MACA,KACA7uB,KAAK41B,qCACL/G,GACE8B,EACA,CAAE7qB,MAAO,0BACT+oB,GAAEuG,GAAa,CACb9lB,MAAOyf,EAAM0I,kBACb/c,QAAS4Z,GACT/Z,SAAWkd,GAAsB3I,GAAY9uB,KAAKsH,MAAO,CAAEmwB,yBAG/D5I,GACE8B,EACA,CAAE7qB,MAAO,wBACT+oB,GACE,MACA,CAAE9jB,UAAW,YACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,QAAS0O,EAAM2I,YACfv4B,KAAM,WACNob,SAAW4Q,GAAM2D,GAAY9uB,KAAKsH,MAAO,CAAEowB,YAAavM,EAAEtf,OAAOwU,YAEnE,0CAKV,EAqBK,MAAMsX,WAAwChC,GACnD,MAAA3Q,GACE,MAAM3f,YAAEA,EAAA0pB,MAAaA,GAAU/uB,KAAKsH,MACpCqtB,GAAmB5F,EAAO1pB,EAAa,CACrCwG,OAAQqqB,EAAeC,YAAY,GAAG5B,IACtCqD,OAAQpD,GAAa,GAAGD,IACxBsD,WAAYpD,GAAY,GAAGF,MAE7BxF,EAAMwG,SAAWxG,EAAMwG,UAAY,CAAA,EAC9BxG,EAAM6I,QAA+B,UAArB7I,EAAM8I,aACzB9I,EAAM6I,OAAS,eAGjB,MAAME,EAAgB9I,IACpB,MAAM4H,EAAY,IAAK7H,KAAUC,IAhCvC,SAA8BD,GACP,gBAAjBA,EAAM6I,QACR7I,EAAM8I,WAAa,eACZ9I,EAAMgJ,gBACNhJ,EAAMiJ,SACbjJ,EAAMwG,SAAWxG,EAAMwG,UAAY,CAAA,IAEnCxG,EAAMwG,SAAW,CAAA,EACQ,QAArBxG,EAAM8I,kBACD9I,EAAMiJ,UAEbjJ,EAAM8I,WAAa,cACZ9I,EAAMgJ,SACbhJ,EAAMiJ,SAAWjJ,EAAMiJ,UAAY,GAGzC,CAiBMC,CAAqBrB,GACrB3B,GAAaj1B,KAAKsH,MAAOsvB,IAG3B,OAAO/H,GACL,MACA,KACA7uB,KAAK41B,qCACL51B,KAAKi2B,qBACLpH,GACE8B,EACA,CAAE7qB,MAAO,UACT+oB,GAAEuG,GAAa,CAAE9lB,MAAOyf,EAAM6I,OAAQld,QAAS8Z,GAAcja,SAAWqd,GAAWE,EAAa,CAAEF,cAEnF,gBAAjB7I,EAAM6I,QACJ/I,GACEpsB,GAAMwI,SACN,KACA4jB,GACE8B,EACA,CAAE7qB,MAAwB,qBAAjBipB,EAAM6I,OAAgC,sBAAwB,QACvE/I,GAAEuG,GAAa,CACb9lB,MAAOyf,EAAM8I,WACbnd,QAAS+Z,GACTla,SAAWsd,GAAeC,EAAa,CAAED,kBAGxB,QAArB9I,EAAM8I,YACJhJ,GACE8B,EACA,CAAE7qB,MAAO,qBACT+oB,GAAEqG,GAAa,CAAE5lB,MAAOyf,EAAMgJ,SAAUxd,SAAWwd,GAAajJ,GAAY9uB,KAAKsH,MAAO,CAAEywB,gBAEzE,SAArBhJ,EAAM8I,YACJhJ,GACE8B,EACA,CAAE7qB,MAAO,oBACT+oB,GAAEqG,GAAa,CAAE5lB,MAAOyf,EAAMiJ,SAAUzd,SAAWyd,GAAalJ,GAAY9uB,KAAKsH,MAAO,CAAE0wB,iBAGjF,gBAAjBjJ,EAAM6I,QACJ/I,GAAEyG,GAAgB,CAChBC,SAAUxG,EAAMwG,SAChBhb,SAAWgb,GAAazG,GAAY9uB,KAAKsH,MAAO,CAAEiuB,eAEtD1G,GAAE6G,GAA2B,CAC3BrwB,cACA0pB,QACAD,YAAc8H,GAAc3B,GAAaj1B,KAAKsH,MAAOsvB,KAG3D,EAGK,MAAMsB,WAAsCvC,GACjD,MAAA3Q,GACE,MAAM3f,YACJA,EAAA0pB,MACAA,EAAAoJ,kBACAA,EAAAC,kBACAA,EAAAC,aACAA,EAAe,EAAAvE,UACfA,EAAAhuB,MACAA,EAAAwyB,gBACAA,EAAkB,wBAAAC,gBAClBA,EAAkB,OAAA5B,mBAClBA,GAAqB,GACnB32B,KAAKsH,MAST,OARAqtB,GAAmB5F,EAAO1pB,EAAa,CAAEyuB,CAACA,GAAYuE,IACtD3D,GAAW3F,EAAOuJ,EAAiB,SACnCvJ,EAAMuJ,GAAmBvJ,EAAMuJ,GAAiBE,WAE5CL,GACFzD,GAAW3F,EAAOoJ,GAAmB,GAGhCtJ,GACL,MACA,KACA7uB,KAAK41B,qCACL/G,GACE8B,EACA,CAAE7qB,SACF+oB,GACE,MACA,CAAE9jB,UAAW,eACb,GAAGwtB,KACH1J,GAAEqG,GAAa,CACb/S,MAAO,CAAEsW,QAAS,eAAgBC,MAAO,QACzCppB,MAAOyf,EAAM+E,GACbvZ,SAAWjL,GAAUwf,GAAY9uB,KAAKsH,MAAO,CAAEwsB,CAACA,GAAYxkB,MAE9D,IACAuf,GAAEwG,GAAmB,CACnBlT,MAAO,CAAEsW,QAAS,eAAgBC,MAAO,SACzCppB,MAAOyf,EAAMuJ,GACb5d,QAAS,CACP,CAAE5U,MAAO,UAAWyuB,IAAK,QACzB,CAAEzuB,MAAO,SAAUyuB,IAAK,UAE1Bha,SAAWjL,GAAUwf,GAAY9uB,KAAKsH,MAAO,CAAEgxB,CAACA,GAAkBhpB,MAEpE,IA1bV,SAAmBxJ,EAAOwJ,GACxB,OAAyB,IAAlB6G,OAAO7G,GAAexJ,EAAQ,GAAGA,IAC1C,CAwbc6yB,CAAU,eAAgB5J,EAAM+E,SAGxCqE,GACEtJ,GACE,MACA,CAAE9jB,UAAW,cACb8jB,GACE,MACA,CAAE9jB,UAAW,qCACb8jB,GACE,QACA,KACAA,GAAE,QAAS,CACTxO,UAAW0O,EAAMoJ,GACjBh5B,KAAM,WACNob,SAAW4Q,GAAM2D,GAAY9uB,KAAKsH,MAAO,CAAE6wB,CAACA,GAAoBhN,EAAEtf,OAAOwU,YAE3E,IAAI+X,OAIZzB,GACE9H,GAAE6G,GAA2B,CAC3BrwB,cACA0pB,QACAD,YAAc8H,GAAc3B,GAAaj1B,KAAKsH,MAAOsvB,KAG7D,EAGK,SAASgC,GAA6BtxB,GAC3C,OAAOunB,GAAEqJ,GAA+B,IACnC5wB,EACHwsB,UAAW,+BACXhuB,MAAO,kBACPyyB,gBAAiB,WACjB5B,oBAAoB,GAExB,CAEO,SAASkC,GAA+BvxB,GAC7C,OAAOunB,GAAEqJ,GAA+B,IACnC5wB,EACH6wB,kBAAmB,uBACnBC,kBAAmB,2CACnBtE,UAAW,gCACXhuB,MAAO,qBACPyyB,gBAAiB,YAErB,CAEO,SAASO,GAA4BxxB,GAC1C,OAAOunB,GAAEqJ,GAA+B,IACnC5wB,EACH6wB,kBAAmB,oBACnBC,kBAAmB,yCACnBtE,UAAW,eACXhuB,MAAO,iBACPwyB,gBAAiB,wBACjBC,gBAAiB,YACjB5B,oBAAoB,GAExB,CC/jBO,SAASoC,KACdlG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,mBACVtsB,cAAe,MACfusB,UAAW+D,GACXnD,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,gBAAiBC,WAAY,WACjE,CAAE50B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CCZO,SAASiF,KACdnG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,qBACVtsB,cAAe,MACfusB,UAAW0D,GACXuC,iBAAmBlK,GAAU,CAACA,EAAM0C,QAAQ1b,aAC5CmjB,uBAAyBnK,GAAU,CAACA,EAAMhZ,aAC1C6d,WAAY,CACV,CACEz0B,KAAM,kBACNisB,QACE,+GAEJ,CAAEjsB,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CCnBO,SAASoF,KACdtG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,qBACVtsB,cAAe,MACfusB,UAAW6D,GACXjD,WAAY,CACV,CACEz0B,KAAM,kBACNisB,QACE,+GAEJ,CAAEjsB,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CCjBO,SAASqF,KACdvG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,iBACVtsB,cAAe,MACfusB,UAAW4F,GACXhF,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,WACpC,CACE30B,KAAM,gBACN20B,UAAW,+BACXC,WAAY,kCAEd,CAAE50B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CChBO,SAASsF,KACdxG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,oBACVtsB,cAAe,MACfusB,UAAW8D,GACXlD,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CCZO,SAASuF,KACdzG,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,YACVtsB,cAAe,MACfusB,UAAWwE,GACX5D,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,oBAAqBC,WAAY,0BACrE,CAAE50B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,iBAG1C,CCLA,MAAMjF,GAAIpsB,GAAMyE,cAEhB,SAASqyB,IAAgCxK,MAAEA,EAAAD,YAAOA,IAIhD,OAHAC,EAAMyK,KAAOzK,EAAMyK,MAAQ,CAAA,EAC3BzK,EAAMve,QAAUue,EAAMve,SAAW,GACjCue,EAAMtoB,cAAgBsoB,EAAMtoB,eAAiB,MACtCooB,GACL,MACA,CAAE9jB,UAAW,mBACb8jB,GACE8B,EACA,CAAE7qB,MAAO,WACT+oB,GAAE,QAAS,CACT9jB,UAAW,wBACXuE,MAAOyf,EAAM0K,aAAe,GAC5Blf,SAAW4Q,GAAM2D,EAAY,IAAKC,EAAO0K,YAAatO,EAAEtf,OAAOyD,WAGnEuf,GACE8B,EACA,CAAE7qB,MAAO,QACT+oB,GAAEoC,EAAW,CACXC,YAAY,EACZC,MAAOpC,EAAMyK,KACbjf,SAAWif,GAAS1K,EAAY,IAAKC,EAAOyK,YAIpD,CAEA,SAASE,IAAKF,KAAEA,EAAAG,UAAMA,EAAY,MAChC,MAAMthB,EAAUnX,OAAOmX,QAAQmhB,GAAQ,CAAA,GACvC,OAAKnhB,EAAQnU,OAIN2qB,GACLpsB,GAAMwI,SACN,KACAoN,EAAQhY,IAAI,EAAE2B,EAAKsN,GAAQqG,IACzBkZ,GAAE,OAAQ,CAAE7sB,OAAO,GAAGA,IAAM23B,IAAYrqB,IAAQqG,IAAU0C,EAAQnU,OAAS,EAAI,GAAK,UAP/E,IAUX,CAEA,SAAS01B,GAAqCtyB,GAC5C,MAAM6V,QAAEA,EAAA4R,MAASA,GAAUznB,EACrBmqB,EAAU1C,EAAM0C,SAAW,CAAA,EAC3BoI,EAASpI,EAAQqI,YAAc,GAErC,OAAOjL,GACLsD,EACA,CAAEvxB,KAAM0G,EAAM1G,KAAMuc,WACpB0R,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,aACb8jB,GACE,KACA,CAAE9jB,UAAW,2BACb8jB,GAAE,KAAM,KAAM,WACdA,GAAE,KAAM,KAAM4C,EAAQgI,aACtB5K,GAAE,KAAM,KAAM,QACdA,GAAE,KAAM,KAAMA,GAAE6K,GAAM,CAAEF,KAAM/H,EAAQ+H,WAI5C3K,GAAEyD,EAAqB,CAAEvD,QAAO3D,QAAS2D,EAAMwD,mBAC7CsH,EAAO31B,QACP2qB,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,aACb8jB,GACE,MACA,CAAE9jB,UAAW,yBACb8jB,GAAE,KAAM,KAAM,WACdgL,EAAOx5B,IAAK05B,GACVlL,GACE,KACA,CAAE9jB,UAAW,0BAA2B/I,IAAK,GAAG+3B,EAAMx4B,UAAUw4B,EAAMpH,aACtE9D,GAAE,KAAM,KAAM,UACdA,GAAE,KAAM,KAAMkL,EAAMx4B,QACpBstB,GAAE,KAAM,KAAM,SACdA,GAAE,KAAM,KAAMkL,EAAMpH,gBAOpC,CAGO,SAASqH,KACdnH,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,oBACVtsB,cAAe,MACfusB,UAAWuG,GACXtG,yBAA0B,CAAC2G,GAAsC1G,GACjEU,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,eACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UAG1C,CCpHO,SAASmG,KACdpH,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,oBACVtsB,cAAe,MACfusB,UAAW2E,GACXsB,iBAAmBlK,GAAU,CAACA,EAAM0C,QAAQ1b,aAC5CmjB,uBAAyBnK,GAAU,CAACA,EAAMhZ,aAC1C4d,uBAAuB,EACvBC,WAAY,CACV,CACEz0B,KAAM,kBACNisB,QACE,8GAEJ,CAAEjsB,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,UACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CCrBO,SAASmG,KACdrH,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,mBACVtsB,cAAe,MACfusB,UAAW6F,GACXI,iBAAmBlK,GAAU,CAACA,EAAM0C,QAAQ1b,aAC5CmjB,uBAAyBnK,GAAU,CAACA,EAAMhZ,aAC1C6d,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,WACpC,CACE30B,KAAM,gBACN20B,UAAW,gCACXC,WAAY,oCAEd,CAAE50B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,YAEjE8B,UAAU,GAEd,CCnBO,SAASsE,KACdtH,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,gBACVtsB,cAAe,MACfusB,UAAW8F,GACXG,iBAAmBlK,GAAU,CAACA,EAAM0C,QAAQ1b,aAC5CmjB,uBAAyBnK,GAAU,CAACA,EAAMhZ,aAC1C6d,WAAY,CACV,CAAEz0B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,eAAgBC,WAAY,+BAChE,CAAE50B,KAAM,gBAAiB20B,UAAW,WACpC,CAAE30B,KAAM,gBAAiB20B,UAAW,cAAeC,WAAY,aAGrE,CHyFA6F,GAAqC70B,MAAQ,0JI7F7C,MAAM8pB,GAAIpsB,GAAMyE,cAMhB,SAASkzB,GAAsBrL,EAAOsL,EAAOha,GAC3C,MAAMlD,EAAU4R,EAAMuL,kBAAoB,GAC1C,OAAIja,IAAYlD,EAAQ7Y,SAAS+1B,GACxBld,EAAQyM,OAAOyQ,GAEnBha,EAGElD,EAFEA,EAAQzd,OAAQgJ,GAAcA,IAAc2xB,EAGvD,CAEA,MAAME,WAA+B93B,GAAMC,UAA3C,WAAA5B,GAAAyjB,SAAA8C,WACEzkB,GAAA5C,KAAA,QAAQ,CAAEsQ,SAAU,IAAG,CAEvB,iBAAAuU,GACErX,EAAe4E,aAAa,OAAO7S,KAAM+Q,GAAatQ,KAAKqd,SAAS,CAAE/M,aACxE,CAEA,MAAA0U,GACE,MAAMsL,SAAEA,EAAAvB,MAAUA,EAAAD,YAAOA,GAAgB9uB,KAAKsH,MAC9CynB,EAAMyK,KAAOzK,EAAMyK,MAAQ,CAAA,EAC3BzK,EAAMtoB,cAAgBsoB,EAAMtoB,eAAiB,MAE7C,MAAM+zB,EAAuBlK,EACzBmK,EAAsBC,2BAA2BpK,EAAUvB,GAAOrvB,OAAQi7B,GACxEzE,EAAe0E,uBAAuBt2B,SAASq2B,EAAcx7B,OAE/D,GAEJ,OAAO0vB,GACL,MACA,CAAE9jB,UAAW,mBACb8jB,GACE8B,EACA,CAAE7qB,MAAO,WACT+oB,GACE,SACA,CACE9jB,UAAW,wBACX8U,UAAU,EACVvQ,MAAOyf,EAAMhZ,aAAe,GAC5BwE,SAAW4Q,GAAM2D,EAAY,IAAKC,EAAOhZ,YAAaoV,EAAEtf,OAAOyD,SAEjEuf,GAAE,SAAU,CAAEvf,MAAO,IAAM,aACbtP,KAAK2D,MAAM2M,SA/CjBjQ,IAAKG,GAAYquB,GAAE,SAAU,CAAE7sB,IAAKxB,EAAQI,KAAM0O,MAAO9O,EAAQI,MAAQJ,EAAQI,SAkD7FiuB,GACE8B,EACA,CAAE7qB,MAAO,QACT+oB,GAAEoC,EAAW,CACXC,YAAY,EACZC,MAAOpC,EAAMyK,KACbjf,SAAWif,GAAS1K,EAAY,IAAKC,EAAOyK,YAGhD3K,GACE8B,EACA,CAAE7qB,MAAO,qBACT+oB,GACE,MACA,CAAE9jB,UAAW,YACbyvB,EAAqBn6B,IAAKs6B,GACxB9L,GACE,QACA,CAAE7sB,IAAK24B,EAAcN,MAAOlY,MAAO,CAAEsW,QAAS,UAC9C5J,GAAE,QAAS,CACTxO,SAAU0O,EAAMuL,kBAAoB,IAAIh2B,SAASq2B,EAAcN,OAC/Dl7B,KAAM,WACNob,SAAW4Q,GACT2D,EAAY,IACPC,EACHuL,iBAAkBF,GAAsBrL,EAAO4L,EAAcN,MAAOlP,EAAEtf,OAAOwU,aAGnF,IAAIsa,EAAc/5B,MAAQ+5B,EAAcN,YAMpD,EAQF,SAASQ,GAA4BvzB,GACnC,MAAM6V,QAAEA,EAAA8U,UAASA,EAAAlD,MAAWA,GAAUznB,EAChCmqB,EAAU1C,EAAM0C,SAAW,CAAA,EAC3BqJ,EAAUrJ,EAAQqJ,SAAW,GAC7BtB,EAAOt4B,OAAOmX,QAAQoZ,EAAQ+H,MAAQ,CAAA,GAAI95B,OAAO,EAAC,CAAG4P,KAAqB,OAAVA,GAChEgrB,EAAmB7I,EAAQ6I,kBAAoB,GAErD,OAAOzL,GACLsD,EACA,CAAEvxB,KAAM0G,EAAM1G,KAAMuc,aAClB2d,EAAQ52B,QACR2qB,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,aACb8jB,GACE,KACA,CAAE9jB,UAAW,2BACb8jB,GAAE,KAAM,KAAM,WACdA,GAAE,KAAM,KAAM4C,EAAQ1b,aACtB8Y,GAAE,KAAM,KAAM,UACdiM,EAAQz6B,IAAKwL,GAAWgjB,GAAE,KAAM,CAAE7sB,IAAK6J,EAAO8mB,WAAa9mB,EAAO8mB,eAI1E9D,GACE,MACA,CAAE9jB,UAAW,OACb8jB,GACE,MACA,CAAE9jB,UAAW,aACb8jB,GACE,KACA,CAAE9jB,UAAW,2BACb8jB,GAAE,KAAM,KAAM,QACd2K,EAAKn5B,IAAI,EAAE2B,EAAKsN,KAAWuf,GAAE,KAAM,CAAE7sB,OAAO,GAAGA,OAASsN,QACtDgrB,EAAiBp2B,QAAU2qB,GAAE,KAAM,KAAM,UAC3CyL,EAAiBj6B,IAAKg6B,GAAUxL,GAAE,KAAM,CAAE7sB,IAAKq4B,GA5CzD,SAAmBpI,EAAWoI,GAxG9B,IAAAr2B,EAyGE,MAAM+qB,EAAQ,OAAA/qB,mBAAW+2B,aAAX,EAAA/2B,EAAmByE,KAAMC,GAAcA,EAAU2xB,QAAUA,GACzE,aAAOtL,WAAOnuB,OAAQy5B,CACxB,CAyCkEW,CAAU/I,EAAWoI,QAInFxL,GAAEyD,EAAqB,CAAEvD,QAAO3D,QAAS2D,EAAMwD,iBAEnD,CAGO,SAAS0I,KACdpI,EAASvC,SAASwC,cAAc,CAC9BC,SAAU,kBACVtsB,cAAe,MACfusB,UAAWuH,GACXtH,yBAA0B,CAAC4H,GAA6B3H,IAE5D,CATA2H,GAA4B91B,MAAQ,iBClHpC,MAAMqgB,GAAY,CAAC,MAAO,MAAO,OAAQ,MAAO,KAAM,QAChD8V,GAAiB,CAAC,MAAO,MAAO,QAEtC,SAAS3a,GAAUjR,GACjB,GAAIgD,MAAMC,QAAQjD,GAChB,OAAOA,EACJjP,IAAKiY,GAA0B,iBAATA,EAAoBA,EAAKhJ,MAAQgJ,GACvD5Y,OAAQ4Y,GAASA,SAAuC,GAAGA,IAAOmB,QAClEpZ,IAAKiY,GAAS,GAAGA,IAAOmB,QAE7B,GAAqB,iBAAVnK,EAAoB,CAE7B,OADkBA,EAAMf,WAAW,MAAQe,EAAM6rB,SAAS,KAAO7rB,EAAM8rB,MAAM,GAAG,GAAM9rB,GAEnFtM,MAAM,KACN3C,IAAKiY,GAASA,EAAKmB,QACnB/Z,OAAOsY,QACZ,CACA,OAAO1I,EAAQ,CAAC,GAAGA,KAAW,EAChC,CAEA,SAAS+rB,GAAiBC,GACxB,MAAMC,GAAoBD,EAAcE,cAAgB,IACrDn7B,IAAKsW,IA/DV,IAAA3S,EAAAsE,EAgEM,MAAMmzB,EAAK,OAAAz3B,EAAA2S,EAAK+kB,YAAL,EAAA13B,EAAYy3B,GACvB,OAAOA,EAAK,GAAGA,KAAK,OAAAnzB,IAAKozB,YAAL,EAAApzB,EAAYqzB,OAAQ,KAAO,KAEhDj8B,OAAOsY,SACV,OAAO1F,MAAMkD,KAAK,IAAIzE,IAAI,IAAIwP,GAAU+a,EAAcM,iBAAkBL,IAC1E,CAEA,SAASllB,GAAmBjC,GAC1B,GAAyB,iBAAdA,GAA+C,iBAAdA,EAAwB,CAClE,MAAOynB,EAAWC,EAAUD,GAAa,GAAGznB,IAAYpR,MAAM,KAC9D,MAAO,CAAE64B,UAAW1lB,OAAO0lB,GAAYC,QAAS3lB,OAAO2lB,GACzD,CACA,MAAO,CACLD,eAAoC,KAAzB,MAAAznB,OAAA,EAAAA,EAAWynB,gBAA0B,EAAY1lB,OAAO/B,EAAUynB,WAC7EC,kBAAS,MAAA1nB,SAAAA,EAAW0nB,cAAwB,EAAY3lB,OAAO/B,EAAU0nB,SAE7E,CAEA,SAASC,GAAiBT,GACxB,IAAKA,EAAcU,WAAa,IAAI93B,OAClC,OAAOo3B,EAAcU,UAAU37B,IAAKsW,IAAA,CAClCxX,KAAMwX,EAAKxX,MAAQwX,EAAKrC,UAAYqC,EAAKpC,cACtC8B,GAAmBM,MAI1B,MAMMslB,GALJX,EAAcY,gBACdZ,EAAca,cACdb,EAAcc,SACdd,EAAcE,cACd,IACyBhtB,OAAO,CAACpO,EAA2BuW,KAC5D,MAAMxX,EAAOwX,EAAKxX,MAAQwX,EAAKrC,UAAYqC,EAAKpC,YAAcoC,EAAK0lB,WAC7DC,EAAa3lB,EAAK2lB,YAAc3lB,EAAKtC,OAAS,GAMpD,OALIioB,EAAWp4B,OACbo4B,EAAWv6B,QAASqS,GAAmBhU,EAAOyF,KAAK,CAAE1G,UAASkX,GAAmBjC,MACxEjV,GACTiB,EAAOyF,KAAK,CAAE1G,SAETiB,GACN,IAEG2oB,MAAWhY,IACjB,OAAOkrB,EAAMv8B,OAAQiX,IA5GvB,IAAA3S,EAAAsE,EA6GI,MAAMtG,EAAM,GAAG2U,EAAKxX,QAAQ,OAAA6E,EAAA2S,EAAKklB,WAAL73B,EAAkB,MAAM,OAAAsE,EAAAqO,EAAKmlB,WAAW,KACpE,OAAI/S,EAAK9W,IAAIjQ,KAGb+mB,EAAK1X,IAAIrP,IACF,IAEX,CAEA,SAASu6B,GAAWjB,EAAoBvlB,GACtC,OACEulB,EAAcvlB,aACdulB,EAAc9P,aACd8P,EAAcpzB,WACdozB,EAAc96B,SACduV,GACA,EAEJ,CAEA,SAASymB,GAAqBltB,GAC5B,OAAO6I,OAAO7I,GAAS,IACpBmK,OACAgjB,aACL,CAoBO,SAASC,GAAmCp1B,EAAoCsV,GACrF,MAAMC,EAASvV,EAAMg0B,eAAiB,CAAA,EAChC5nB,EAAOpM,EAAMoM,MAAQ,SACrBqC,EAAcwmB,GAAW1f,EAAQvV,EAAMyO,aACvCulB,EAAgB,IACjBze,EACH3U,UAAW2U,EAAO3U,WAAa6N,EAC/ByV,YAAa3O,EAAO2O,aAAezV,EACnCA,cACArJ,YAAamQ,EAAOnQ,aAAe,GACnCsvB,UAAWD,GAAiBlf,GAC5Bjc,KAAMic,EAAOjc,MAAQgc,GAAmB,GACxC9S,QAAS+S,EAAO/S,SAAW+S,EAAOlU,OAAS,UAC3CpH,OAAQ,SACRq6B,aAAcP,GAAiBxe,GAC/B8f,WAAYpc,GAAU1D,EAAO8f,YAC7BC,WAAYrc,GAAU1D,EAAO+f,aAY/B,MATa,WAATlpB,GAAsB4nB,EAAcU,UAAU93B,SAChDo3B,EAAcU,UAAY,CAAC,CAAE78B,KAAM,SAExB,UAATuU,IACF4nB,EAAcnzB,QAAK,EACnBmzB,EAAc16B,KAAO,UACd06B,EAAcv4B,UAGhBu4B,CACT,CAEO,MAAMuB,WAAuCp6B,GAAMC,UAcjD,WAAA5B,CAAYwG,GACjBid,MAAMjd,GARRtH,KAAQ88B,SAAU,EAwDlB98B,KAAQsF,eAAiB,KAvP3B,IAAAtB,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAwPI,MAAMC,EAAiB,OAAAh5B,EAAAhE,KAAKi9B,yBAALj5B,EAAuBg5B,eAC9C,GAAuB,SAAnBh9B,KAAKk9B,UAGP,OAFA,OAAA50B,EAAA,MAAA00B,OAAA,EAAAA,EAAgBxf,UAAhBlV,EAAA0V,KAAAgf,QACA,OAAA1zB,GAAAD,EAAArJ,KAAKsH,OAAM8W,aAAX9U,EAAA0U,KAAA3U,IAIF,MAAM8zB,EAAuB,KA/PjC,IAAAn5B,EAAAsE,EAiQM,GADAtI,KAAKo9B,uCACAp9B,KAAK88B,QACR,OAEF,MAAMxB,cAAEA,GAAkBt7B,KAAK2D,MAC/B,OAAA2E,GAAAtE,EAAAhE,KAAKsH,OAAM8W,aAAX9V,EAAA0V,KAAAha,GACAhE,KAAKsH,MAAM9C,aAAaG,GACtB3E,KAAKsH,MAAM9C,aAAaF,SAAS,sBAAwB,oBAAsB,mBAC/E,CACE4D,UAAWq0B,GAAWjB,GACtB16B,KAAM06B,EAAc16B,KAAK6Y,OACzB7Z,SAAU,MACV2B,OAAQ,SACRoH,OAAQ2yB,EAAcxxB,SAAWwxB,EAAc3yB,OAAO8Q,UAK5D,SAAIujB,WAAgB3e,cAIlB,OAHAre,KAAKo9B,sCACLp9B,KAAK0d,8BAAgCsf,EAAe3e,cAAc8e,QAClE,OAAA3iB,EAAAwiB,EAAexf,UAAfhD,EAAAwD,KAAAgf,IAIF,MAAMK,EAAgB,OAAAN,mBAAgBvf,cAAhB,EAAAuf,EAAA/e,KAAAgf,UAClBK,WAAe99B,MACjB89B,EAAc99B,KAAK49B,GAEnBA,KAIJn9B,KAAQo9B,oCAAsC,KAjShD,IAAAp5B,EAkSI,OAAAA,EAAAhE,KAAK0d,gCAAL1Z,EAAAga,KAAAhe,MACAA,KAAK0d,mCAAgC,GAGvC1d,KAAQs9B,oBAAuBjiB,IAC7Brb,KAAKqd,SAAS,EAAGie,oBAAc,CAASA,cAAe,IAAKA,KAAkBjgB,OAGhFrb,KAAQu9B,WAAa,CAAC5nB,EAAe0F,KACnC,MAAM2gB,EAAYh8B,KAAK2D,MAAM23B,cAAcU,UAAUZ,QACrDY,EAAUrmB,GAAS,IAAKqmB,EAAUrmB,MAAW0F,GAC7Crb,KAAKs9B,oBAAoB,CAAEtB,eAG7Bh8B,KAAQw9B,QAAU,KAChBx9B,KAAKs9B,oBAAoB,CACvBtB,UAAW,IAAIh8B,KAAK2D,MAAM23B,cAAcU,UAAW,CAAE78B,KAAM,MAAO08B,UAAW,KAAMC,QAAS,UAIhG97B,KAAQy9B,WAAc9nB,IACpB3V,KAAKs9B,oBAAoB,CACvBtB,UAAWh8B,KAAK2D,MAAM23B,cAAcU,UAAUt8B,OAAO,CAACg+B,EAAwBC,IACrEA,IAAchoB,MA0B3B3V,KAAQif,OAAS,KACf,MAAM5Z,EAAcrF,KAAKi9B,kBACnB3B,cAAEA,GAAkBt7B,KAAK2D,MACzBoS,EAAcwmB,GAAWjB,GACzBc,EAAUd,EAAcU,UAAU37B,IAAKsW,IAC3C,MAAMinB,EAAgE,CAAErpB,WAAYoC,EAAKxX,MAIzF,YAHuB,IAAnBwX,EAAKklB,gBAA4C,IAAjBllB,EAAKmlB,UACvC8B,EAAetB,WAAa,CAAC,GAAG3lB,EAAKklB,aAAallB,EAAKmlB,YAElD8B,IAEH9nB,EAAU,IACXwlB,EACHpzB,UAAWozB,EAAcpzB,WAAa6N,EACtCyV,YAAa8P,EAAc9P,aAAezV,EAC1CqmB,UACA/2B,YAAaA,EAAYzE,KACzB6F,cAAe,MACfsP,cACAnV,KAAM06B,EAAc16B,KAAK6Y,OACzB3P,QAASwxB,EAAcxxB,QAAQ2P,OAC/BlY,OAAQ,SACRq6B,aAActpB,MAAMkD,KAAK,IAAIzE,IAAIuqB,EAAcM,eAC/Ce,WAAYrqB,MAAMkD,KAAK,IAAIzE,IAAIuqB,EAAcqB,aAC7CC,WAAYtqB,MAAMkD,KAAK,IAAIzE,IAAIuqB,EAAcsB,cAEzClpB,EAAO1T,KAAKk9B,UACZle,EAAsB,SAATtL,EAAkB,SAAoB,UAATA,EAAmB,QAAU,SAE7E1T,KAAK2D,MAAMia,YAAYqB,OAAO,IAC5B4e,EAAoBC,oBAAoBhoB,EAAgBzQ,EAAa2Z,KAzKvE,MAAM3Z,EAAcrF,KAAKi9B,eAAe31B,GAClCoM,EAAOpM,EAAMoM,MAAQ,SAC3B1T,KAAK2D,MAAQ,CACX23B,cAAeoB,GAAmCp1B,EAAO,MAAAjC,OAAA,EAAAA,EAAazE,MACtEm9B,6BAAuC,SAATrqB,EAC9BkK,YAAa,IAAIC,EAAY,CAC3BxY,cACAN,MAAO,GAAY,SAAT2O,EAAkB,WAAa,mBAAmBsqB,EAAe1+B,IAAI,cAC/Ewe,UAAW,KAhNnB,IAAA9Z,EAgNyB,OAAA,OAAAA,EAAAsD,EAAMyW,qBAAN/Z,EAAAga,KAAA1W,IACjBhC,eAAgBtF,KAAKsF,iBAG3B,CAlBA,WAAcga,CAAKhY,EAAoC22B,GACrD,OAAO1e,EAAWD,KAAK4e,GAAuB52B,EAAO,CAAEkY,gBAAiB,YAAcye,EACxF,CAkBO,iBAAApZ,GACL7kB,KAAK88B,SAAU,EACQ,SAAnB98B,KAAKk9B,WAITl9B,KAAKyxB,QAAQxc,SAASkpB,oBAAoBC,uBAAuB7+B,KAC9D8+B,IACKr+B,KAAK88B,SACP98B,KAAKqd,SAAS,CAAEghB,yBAAwBN,8BAA8B,KAG1E,KACM/9B,KAAK88B,SACP98B,KAAKqd,SAAS,CAAEihB,6BAA8B,uCAItD,CAEO,oBAAAvZ,GACL/kB,KAAK88B,SAAU,EACf98B,KAAKo9B,qCACP,CAEQ,cAAAH,CAAe31B,EAAQtH,KAAKsH,OAClC,OAAOA,EAAMjC,aAAeiC,EAAMvD,GACpC,CAEQ,OAAAm5B,GACN,OAAOl9B,KAAKsH,MAAMoM,MAAQ,QAC5B,CAyEQ,OAAA6qB,GACN,MAAMjD,cAAEA,EAAA+C,uBAAeA,EAAAN,6BAAwBA,GAAiC/9B,KAAK2D,MAC/E66B,EACe,SAAnBx+B,KAAKk9B,WACJa,IA3LP,SACEzC,EACA+C,GAzIF,IAAAr6B,EAAAsE,EA2IE,MAAM1H,EAAO47B,GAAqBlB,EAAc16B,MAC1CJ,EAAUg8B,GAAqBD,GAAWjB,IAC1CmD,EAAsBv9B,OAAOY,KAAKu8B,GAA0B,CAAA,GAAI51B,KACnEi2B,GAAqBlC,GAAqBkC,KAAsBl+B,GAMnE,OAJ+Bi+B,IAC3B,OAAAn2B,EAAA,OAAAtE,EAAA,MAAAq6B,OAAA,EAAAA,EAAyBI,WAAzBz6B,EAA+C4L,UAA/C,EAAAtH,EAAoDq2B,SACpD,IAE0B96B,KAAM+6B,GAC3BpC,GAAqBoC,EAAsBh+B,QAAUA,EAEhE,CA2KwCi+B,CAA6BvD,EAAe+C,GAChF,SACE/C,EAAc16B,KAAK6Y,QACnB+kB,GACAjC,GAAWjB,IACXA,EAAcxxB,QAAQ2P,QACtB6hB,EAAcU,UAAU93B,SACvBo3B,EAAcM,aAAa13B,QAAUo3B,EAAcqB,WAAWz4B,SAC/Do3B,EAAcU,UAAU8C,MAAOnoB,GAE3BA,EAAKxX,QACH+7B,GAAe52B,SAASqS,EAAKxX,YAA6B,IAAnBwX,EAAKklB,gBAA4C,IAAjBllB,EAAKmlB,UAItF,CAoCQ,eAAAiD,CACNj5B,EACAwJ,EACAiL,EACAykB,GAAW,GAEX,OACEv8B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0BjF,GAC3CrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVwP,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3C0vB,WACA1vB,MAAOA,GAAS,MAK1B,CAEQ,WAAA2vB,GACN,OACEx8B,GAAAyE,cAAC,OAAI6D,UAAU,+BACZ,MAAA,CAAIA,UAAU,6BACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,gCACftI,GAAAyE,cAAC,QAAA,sBACE,KAAA,KACCzE,GAAAyE,cAAC,UAAG,YACJzE,GAAAyE,cAAC,KAAA,KAAG,+BACH,KAAA,KAAG,YACJzE,GAAAyE,cAAC,KAAA,QAGLzE,GAAAyE,cAAC,QAAA,KACElH,KAAK2D,MAAM23B,cAAcU,UAAU37B,IAAI,CAACsW,EAAuBhB,qBAC7D,KAAA,CAAG3T,IAAK2T,GACPlT,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACVwP,SAAWwB,GAAU/b,KAAKu9B,WAAW5nB,EAAO,CAAExW,KAAM4c,EAAMlQ,OAAOyD,QACjEA,MAAOqH,EAAKxX,MAEXimB,GAAU/kB,IAAKiU,GACd7R,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsS,EAAUhF,MAAOgF,GAC3BA,EAAST,kBAKlBpR,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV8O,IAAI,IACJU,SAAWwB,GACT/b,KAAKu9B,WAAW5nB,EAAO,CACrBkmB,UAAkC,KAAvB9f,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,SAG3EnQ,KAAK,SACLmQ,WAA0B,IAAnBqH,EAAKklB,UAA0B,GAAKllB,EAAKklB,aAGpDp5B,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV8O,IAAI,IACJU,SAAWwB,GACT/b,KAAKu9B,WAAW5nB,EAAO,CACrBmmB,QAAgC,KAAvB/f,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,SAGzEnQ,KAAK,SACLmQ,WAAwB,IAAjBqH,EAAKmlB,QAAwB,GAAKnlB,EAAKmlB,WAGlDr5B,GAAAyE,cAAC,UACCzE,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,eAAe6T,QAAS,IAAM5e,KAAKy9B,WAAW9nB,GAAQxW,KAAK,UAC3EsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,qDAO3B,SAAA,CAAOA,UAAU,wBAAwB6T,QAAS5e,KAAKw9B,QAASr+B,KAAK,2BACnE,OAAA,CAAK4L,UAAU,kCAAkC,qCAK5D,CAEO,MAAAia,GACL,MAAMsW,cAAEA,EAAAyC,6BAAeA,EAAAO,6BAA8BA,EAAA1gB,YAA8BA,GAAgB5d,KAAK2D,MAClG+P,EAAO1T,KAAKk9B,UACZjZ,EAAmB,SAATvQ,EACVnI,EAAU,GAAY,SAATmI,EAAkB,OAAkB,UAATA,EAAmB,QAAU,YAAYsqB,EAAe1+B,IACpG,cAGF,OACEmD,GAAAyE,cAAC,OAAI6D,UAAU,kCACZwT,EAAA,CAAmBC,QAASZ,IAC7Bnb,GAAAyE,cAACuX,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,KAAA,KAAIqE,qBAEN,MAAA,CAAIR,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,mBACZ/K,KAAK++B,gBAAgB,OAAQzD,EAAc16B,KAAOA,GAASZ,KAAKs9B,oBAAoB,CAAE18B,SAASqjB,IAC9FA,IAAY8Z,GACZt7B,GAAAyE,cAAC,MAAA,CACC6D,UAAWuzB,EAA+B,8CAAgD,cAEzFA,GAAgC,0CAGpCt+B,KAAK++B,gBAAgB,cAAezD,EAAc5uB,YAAcA,GAC/D1M,KAAKs9B,oBAAoB,CAAE5wB,iBAE5B1M,KAAK++B,gBACJ,UACAxC,GAAWjB,GACVvlB,GACC/V,KAAKs9B,oBAAoB,CACvBp1B,UAAW6N,EACXyV,YAAazV,EACbA,gBAEJkO,GAEDjkB,KAAK++B,gBACJ,UACAzD,EAAcxxB,QACbA,GAAY9J,KAAKs9B,oBAAoB,CAAExzB,YACxCma,GAEDjkB,KAAK++B,gBAAgB,cAAezD,EAAcsB,WAAWl3B,KAAK,MAAQk3B,GACzE58B,KAAKs9B,oBAAoB,CAAEV,WAAYrc,GAAUqc,MAElD58B,KAAK++B,gBAAgB,cAAezD,EAAcqB,WAAWj3B,KAAK,MAAQi3B,GACzE38B,KAAKs9B,oBAAoB,CAAEX,WAAYpc,GAAUoc,MAElD38B,KAAK++B,gBAAgB,eAAgBzD,EAAcM,aAAal2B,KAAK,MAAQk2B,GAC5E57B,KAAKs9B,oBAAoB,CAAE1B,aAAcrb,GAAUqb,MAEpD57B,KAAKi/B,gBAGVx8B,GAAAyE,cAAC,OAAI6D,UAAU,iCACZ,SAAA,CAAOA,UAAU,kBAAkB6T,QAAS5e,KAAKsH,MAAMyW,aAAc5e,KAAK,UAAS,UAGpFsD,GAAAyE,cAAC2X,EAAA,CACCjW,YAAa5I,KAAKu+B,UAClBzf,cAAc,EACdhZ,MAAgB,SAAT4N,EAAkB,SAAoB,UAATA,EAAmB,QAAU,SACjEkL,QAAS5e,KAAKif,OACdX,WAAYV,EAAYU,cAKlC,EAjWWue,GAIGqC,YAAcC,EAgWvB,MAAMjB,GAAwBh9B,OAAOsO,OAAOpI,EAAWy1B,IAAiC,CAC7Fvd,KAAMud,GAA+Bvd,OC3gBvC,SAASiB,GAAUjR,GACjB,OAAIgD,MAAMC,QAAQjD,GACTA,EAEY,iBAAVA,GAAsBA,EAAMf,WAAW,MAAQe,EAAM6rB,SAAS,KAChE7rB,EACJ8rB,MAAM,GAAG,GACTp4B,MAAM,KACN3C,IAAKiY,GAASA,EAAKmB,QACnB/Z,OAAOsY,SAEL1I,EAAQ,CAACA,GAAS,EAC3B,CAiCO,SAAS8vB,IAAwBr7B,IACtCA,EAAAs7B,sBACAA,EAAA/D,cACAA,IAMA,MAAM2C,EAAkBzT,KACjB8U,EAAUC,GAAe/3B,IAAS,GACnCg4B,EA1CR,SAAiClE,EAAoB+D,GACnD,IAAKA,EACH,OAAO/D,EAET,MAAMpzB,EACJozB,EAAcpzB,WACdozB,EAAc9P,aACd8P,EAAc96B,SACd86B,EAAcvlB,aACdspB,EAAsBn3B,UACxB,MAAO,IACFozB,EACHpzB,YACAsjB,YAAa8P,EAAc9P,aAAetjB,EAC1CtH,KAAM06B,EAAc16B,MAAQy+B,EAAsBz+B,KAClDhB,SAAU07B,EAAc17B,UAAYy/B,EAAsBz/B,UAAY,MACtE2B,OAAQ+5B,EAAc/5B,QAAU89B,EAAsB99B,QAAU,SAChEoH,MAAO2yB,EAAc3yB,OAAS02B,EAAsB12B,MAExD,CAuBmB82B,CAAwBnE,EAAe+D,GAClDK,EAA+C,iBAAhBF,EAASr3B,IAAmBq3B,EAASr3B,GAAG7D,SAAS,KAChFq7B,EAAsB,4DAwB5B,OACEl9B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,WACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAW,aAAYu0B,EAAW,OAAS,IAAMn3B,GAAG,uCACvD1F,GAAAyE,cAAC,SAAA,CACC,gBAAeo4B,EACfv0B,UAAU,yCACV6T,QAAS,IAAM2gB,GAAaD,GAC5BngC,KAAK,UACN,oBACkBsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,WAEnCtI,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,gBAAgBgd,KAAK,QACjCtlB,GAAAyE,cAAC,KAAA,CAAG6D,UAAW20B,EAAwB,gBAAa,GAClDj9B,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,OACZuP,SAAUolB,EACV9gB,QAxCa,KACvBsf,GAAsB5e,KAAK,CAAEja,YAAatB,EAAK2P,KAAM,OAAQ4nB,cAAekE,GAAYvB,IAwC9El5B,MAAO26B,EAAwBC,OAAsB,EACrDxgC,KAAK,UACN,uBAIHsD,GAAAyE,cAAC,MAAG6D,UAAW20B,EAAwB,gBAAa,GAClDj9B,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,QACZuP,SAAUolB,EACV9gB,QAjDe,KACzBsf,GAAsB5e,KAAK,CAAEja,YAAatB,EAAK2P,KAAM,QAAS4nB,cAAekE,GAAYvB,IAiD/El5B,MAAO26B,EAAwBC,OAAsB,EACrDxgC,KAAK,UACN,mBAIHsD,GAAAyE,cAAC,MAAG6D,UAAW20B,EAAwB,gBAAa,GAClDj9B,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,SACZuP,SAAUolB,EACV9gB,QA1DgB,KAC1B1Z,EAAyBN,QAAQ,CAC/BpE,QAASg/B,EAASt3B,UAClBpD,WAAY,UAAU06B,EAAS5+B,OAC/BiE,OAAQ,iBAAiB26B,EAAS5+B,QAClCoE,aAAc,IACZ64B,EAAoB+B,oBAAoBJ,EAAUz7B,EAAK,CACrD0C,cAAe,MACfo5B,kBAAmBL,EAAS5+B,OAEhCwE,kBAAmB,CACjBC,YAAatB,EACbgB,MAAO,YAAYy6B,EAAS5+B,WA+CtBmE,MAAO26B,EAAwBC,OAAsB,EACrDxgC,KAAK,UACN,sBAMNugC,oBAA0B,MAAA,CAAI30B,UAAU,iCAAiC40B,GAGhF,CAEO,SAASG,IAAwB/7B,IAAEA,EAAAs7B,sBAAKA,IAC7C,MAAMlB,oBAAEA,GAAwB3T,IAC1BuV,EAxGR,SAAqCzE,GACnC,MAAO,CACLA,EAAcpzB,UACdozB,EAAc17B,SACd07B,EAAc/5B,OACd+5B,EAAc3yB,OAAS,GACvB2yB,EAAc16B,MACd8E,KAAK,IACT,CAgGmBs6B,CAA4BX,IACtCY,EAAqBC,GAA0B14B,KAEtD8V,GAAU,KAhKZ,IAAAtZ,EAAAsE,EAiKI,IAAIP,GAAY,EAEhB,MAAMo4B,EAAoB,IACjBhC,EACJiC,wBACCr8B,EACAs7B,EAAsBn3B,UACtBm3B,EAAsBz/B,SACtBy/B,EAAsB99B,OACtB89B,EAAsB12B,MACtB02B,EAAsBz+B,MAEvBrB,KACE6J,IACMrB,GACHm4B,EAAuB,CAAEl+B,IAAK+9B,EAAUzwB,MAAO,IAAK+vB,KAA0Bj2B,MAGlF,KACOrB,GACHm4B,EAAuB,CAAEl+B,IAAK+9B,EAAUzwB,MAAO+vB,MAMzDc,IACA,MAAME,EAAyB,OAAA/3B,EAAA,OAAAtE,EAAAD,EAAIi5B,qBAAJ,EAAAh5B,EAAoBs8B,gBAApB,EAAAh4B,EAAA0V,KAAAha,EAAgCm8B,GAE/D,MAAO,KACLp4B,GAAY,EACZ,MAAAs4B,GAAAA,MAED,CAACt8B,EAAKg8B,EAAU5B,IAEnB,MAAMz2B,SAAUu4B,WAAqBj+B,OAAQ+9B,EACvCzE,EAAgB5zB,EAAU23B,EAAwBY,EAAoB3wB,MAEtEstB,EAAarc,GAAU+a,EAAcsB,YACrCD,EAAapc,GAAU+a,EAAcqB,YACrCf,EAAerb,GAAU+a,EAAcM,cAAchS,QACxD0R,EAAcE,cAAgB,IAAIn7B,IAAKsW,IA1M5C,IAAA3S,EAAAsE,EA0M0D,MAAA,IAAG,OAAAtE,EAAA2S,EAAK+kB,YAAL,EAAA13B,EAAYy3B,KAAM,MAAK,OAAAnzB,EAAAqO,EAAK+kB,YAAL,EAAApzB,EAAYqzB,OAAQ,QAGtG,OACEl5B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iBACbtI,GAAAyE,cAAC,OAAI6D,UAAU,UACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,kDACZ,OAAA,CAAKA,UAAU,aAChBtI,GAAAyE,cAAC,KAAA,KAAIo0B,EAAc16B,QAEnB8G,GACAjF,GAAAyE,cAACk4B,GAAA,CACCr7B,MACAs7B,wBACA/D,mBAIN74B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,WACZrD,GAAWjF,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,eAAc,cACzCtI,GAAAyE,cAACoE,EAAA,CAAmBC,QAAS,GAAGyyB,EAAe1+B,IAAI,0BAA2BkM,iBAAiB,GAC7F/I,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,UAAG,WACJzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAACuE,EAAA,CAAWjL,QAAS86B,EAAcpzB,WAAaozB,EAAc9P,eAEhE/oB,GAAAyE,cAAC,KAAA,KAAG,UACJzE,GAAAyE,cAAC,KAAA,KAAIo0B,EAAc/5B,QAAU,UAC7BkB,GAAAyE,cAAC,KAAA,KAAG,WACJzE,GAAAyE,cAAC,KAAA,KAAIo0B,EAAc3yB,OAAS2yB,EAAcxxB,SAAW,KACrDrH,GAAAyE,cAAC,KAAA,KAAG,eACJzE,GAAAyE,cAAC,KAAA,KAAIo0B,EAAc5uB,aAAe,OAGtCjK,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,UAAUC,iBAAiB,GACrD/I,GAAAyE,cAAC,IAAA,KAAG01B,EAAWl3B,KAAK,OAAS,gBAE/BjD,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,UAAUC,iBAAiB,oBACpD,IAAA,KAAGmxB,EAAW/S,OAAOgS,GAAcl2B,KAAK,OAAS,MAEpDjD,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,kBAAkBC,iBAAiB,IAC3D8vB,EAAca,cAAgBb,EAAcY,gBAAkB,IAAIh4B,OAClEzB,GAAAyE,cAAC,WACGo0B,EAAca,cAAgBb,EAAcY,gBAAkB,IAAI77B,IAAI,CAACsW,EAAWhB,KArPlG,IAAA3R,EAsPgB,OAAAvB,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,GACN,CAACgB,EAAKrC,SAAU,OAAAtQ,EAAA2S,EAAK2lB,iBAAL,EAAAt4B,EAAiB3D,IAAKq7B,GAAeA,EAAMG,WAAWn2B,KAAK,OACzEhG,OAAOsY,SACPtS,KAAK,SAKdjD,GAAAyE,cAAC,YAAK,OAMlB,CClQO,MAAMq5B,GACX,2BAAAC,CAA4BC,EAAuBxT,EAAWyT,GAC5D,OAAOD,EAAsBxT,EAAUzsB,SAASm+B,OAAO+B,EACzD,ECHK,MAAMC,GACX,WAAA7/B,CAAYuL,GACVrM,KAAKqM,eAAiBA,CACxB,CAEA,sBAAAu0B,CAAuBtF,GACrB,OAAOt7B,KAAKqM,eAAe7J,QAAQ84B,EACrC,ECAK,SAASuF,GAAoBC,GAClC,MAAMC,EAAuBD,EAAI99B,MAAM,KACvC,GAAI+9B,EAAqB78B,OAAS,EAChC,MAAM,IAAI88B,MAAM,oBAAoBF,gCAItC,MAAO,CACLG,gBAHsBF,EAAqBA,EAAqB78B,OAAS,GAIzEg9B,gBAHsBH,EAAqBA,EAAqB78B,OAAS,GAAGk3B,MAAM,MAKtF,CAEO,SAAS+F,GAAsBlhC,GACpC,MAAMmhC,EAYD,SAAsCnhC,GAC3C,MAAMohC,MAAetwB,IACfqwB,MAAqBrwB,IAQ3B,OAPA9Q,EAAa8B,QAASu/B,IAChBD,EAASpvB,IAAIqvB,EAAG1gC,MAClBwgC,EAAe/vB,IAAIiwB,EAAG1gC,MAEtBygC,EAAShwB,IAAIiwB,EAAG1gC,QAGbwgC,CACT,CAvByBG,CAA6BthC,GACpD,OAAOA,EAAaI,IAAKihC,IAEhB,CACLvQ,YAFiBqQ,EAAenvB,IAAIqvB,EAAG1gC,MAEb,GAAG0gC,EAAG1gC,SAAS0gC,EAAGE,QAAUF,EAAG1gC,KACzD4gC,KAAMF,EAAGE,KACT5gC,KAAM0gC,EAAG1gC,KACTmC,SAAUu+B,EAAGv+B,WAGnB,CC7BO,MAAM0+B,GACX,2BAAAC,CAA4BC,EAAgBC,EAAW3yB,EAAUH,GAC/D,IAAIH,EAAM,EACV,GACO,OADCgzB,EAIJhzB,EAAM,QAMNA,EAAMG,EAA2BG,GAAU4yB,QAE/C,OAAOD,GAAajzB,CACtB,CAKA,oBAAAmzB,CAAqBH,EAAgBC,GACnC,GAAkB,IAAdA,EACF,OAAO,EAET,OAAQD,GACN,IAAK,KACL,IAAK,MACH,OAAOC,EAAY,GAAM,EAG3B,QACE,OAAOA,EAAY,GAAM,EAE/B,CAEA,gCAAAG,CAAiC9yB,EAAUH,GACzC,MAAMH,EAAMG,EAA2BG,GAAU4yB,QACjD,MAAO,CAAC,KAAMt+B,GAAEm4B,MAAM,EAAG/sB,EAAK,GAAIA,EACpC,CAEA,+BAAAqzB,GACE,MAAO,CAAC,KAAM,KAAM,KAAM,OAAO3hC,IAAK4hC,GAAMA,EAAEpuB,cAChD,CAMA,qBAAAquB,CAAsBP,EAAgBC,GACpC,OAAQD,GACN,IAAK,KACL,IAAK,KACL,IAAK,MACH,OAAOjzB,KAAKyzB,KAAK,GAAMP,EAAY,GAAK,EAE1C,QACE,OAAOlzB,KAAKyzB,KAAK,GAAMP,EAAY,GAAK,EAE9C,CAEA,qBAAAQ,CAAsBT,EAAgBC,GACpC,OAAQD,GACN,IAAK,KACH,OAAO,EAAIC,EAAY,IAAM,IAAM,EAAIA,EACzC,IAAK,KACL,IAAK,MACH,OAAO,EAAIA,EAEb,QACE,OAAO,IAAMA,EAEnB,CAEA,mCAAAS,CAAoCV,EAAgBC,GAClD,MAAM/nB,EAAM7Z,KAAKkiC,sBAAsBP,EAAgBC,GACjDjzB,EAAM3O,KAAKoiC,sBAAsBT,EAAgBC,GACvD,MAAO,IAAIr+B,GAAEm4B,MAAM7hB,EAAKlL,EAAK,KAAOA,EACtC,CAEA,aAAA2zB,CAAcX,EAAgBY,EAAaX,EAAWY,GACpD,MAAM3oB,EAAM7Z,KAAKkiC,sBAAsBP,EAAgBC,GACjDjzB,EAAM6zB,EAAiB,IAAMxiC,KAAKoiC,sBAAsBT,EAAgBC,GAC9E,OAAOr+B,GAAEk/B,QAAQF,EAAa1oB,EAAKlL,IAAQ4zB,IAAgB5zB,CAC7D,CAMA,0BAAA+zB,CAA2Bf,EAAgBC,EAAWW,EAAaC,GACjE,MAAMG,EAAeH,EAAiB,OAAS,GACzCI,EAAoC,KAAtBzsB,OAAOosB,GAE3B,MAAuB,QADvBZ,EAAiBA,EAAelF,eAEvB,UAAUmF,KAAagB,IAAcD,IAEvC,GAAGhB,YAAyBC,KAAagB,IAAcD,GAChE,CAEA,uBAAAE,CAAwBC,GACtB,MAAOlB,EAAWgB,GAAer/B,GAAE8L,MAAMyzB,EAAmB9/B,MAAM,MAC/D+/B,UAAU,GACV1iC,IAAKiP,GAAU6G,OAAO7G,IACtBA,QAEH,IAAIqyB,EAAiBmB,EAAmB9/B,MAAM,KAAK,GAAG6Q,cAC/B,WAAnB8tB,IACFA,EAAiB,MAKnB,MAAO,CAAEA,iBAAgBC,YAAW70B,OAFrB61B,EAAc,KAG/B,CAEA,6BAAAI,CACErB,EACAC,EACAW,EACAtzB,EACAH,EACA0zB,GAEA,OAAOj/B,GAAEu7B,MAAM,CACb9+B,KAAK8hC,qBAAqBH,EAAgBC,GAC1C5hC,KAAKsiC,cAAcX,EAAgBY,EAAaX,EAAWY,GAC3DxiC,KAAK0hC,4BAA4BC,EAAgBC,EAAW3yB,EAAUH,IAE1E,ECnIK,MAAMm0B,GAAwC,CACnD,sBACA,6BACA,wBACA,wBACA,eACA,kBCKK,MAAMC,GACX,WAAApiC,CACEuL,EACA82B,EAAsB,IAAI/2B,GAAuBC,GACjD+2B,EAAkC,IAAI3B,GACtC4B,EAAsB,IAAI1gC,GAC1B2gC,EAAmCL,IAmBnC,SAASM,EAAmB78B,GAC1B,MAAMxD,EAAYmgC,EAAoBG,gBAAgB98B,EAAY+8B,aAAaC,kBACzEC,EAAapgC,GAAEjE,IAAIoH,EAAa,yEACtC,OAAO28B,EAAoBt5B,+BAA+B7G,EAAWygC,EACvE,CAEA,SAASC,EAAkBl9B,GACzB,MAAMxD,EAAYmgC,EAAoBG,gBAAgB98B,EAAY+8B,aAAaC,kBACzEG,EAAgBtgC,GAAEjE,IACtBoH,EACA,4EAEF,OAAO28B,EAAoBt5B,+BAA+B7G,EAAW2gC,EACvE,CAEA,SAASC,EAAkCp9B,GACzC,OAAOnD,GAAE0O,IAAIvL,EAAa,8EAC5B,CAEA,SAASq9B,EAA2Bz0B,GAClC,OAAIgD,MAAMC,QAAQjD,GACTA,EAEY,iBAAVA,EACFA,EAAMtM,MAAM,KAAKtD,OAAOsY,SAE1B,EACT,CAEA,SAASgsB,EAA4BC,GACnC,MAAO,CAAC,sBAAuB,8BAA8Bz1B,OAAO,CAAC01B,EAAsBC,KACzF,MAAM1uB,EAASsuB,EAA2BE,EAASE,IAInD,OAHI1uB,EAAOvR,SACTggC,EAAqBC,GAAY1uB,GAE5ByuB,GACN,CAAA,EACL,CA4EA,SAASE,EAAiBtuB,GACxB,OAAQA,EAAQ7J,OAAS,IAAIvM,OAAQwO,GAAuB,cAAdA,EAAK/O,KACrD,CAEA,SAASklC,EAAmBvuB,GAC1B,OAAQA,EAAQ7J,OAAS,IAAIvM,OAAQwO,GAASA,EAAK/O,KAAKoP,WAAW,QAAUL,EAAK/O,KAAKoP,WAAW,cACpG,CAoBA,SAAS+1B,EAAsCC,EAAqBzuB,GAClE,GAAIyuB,EAAoBr3B,QAAQC,kBAC1Bi3B,EAAiBtuB,GAAS5R,SAAWqgC,EAAoBr3B,QAAQmB,QACnEyH,EAAQ0uB,UAAUC,6BAA+BL,EAAiBtuB,GAAS5R,OAAS,YAEjF,CACL,MAAMoK,EAAkB+1B,EAAmBvuB,IAEzCxH,EAAgBzK,KAAMqK,GAASA,EAAKhC,SAAWq4B,EAAoBr3B,QAAQkB,OAC3EE,EAAgBpK,SAAWqgC,EAAoBr3B,QAAQmB,SAGvDyH,EAAQ0uB,UAAUC,6BA9BxB,SAA6D3uB,GAC3D,MAAMxH,EAAkB+1B,EAAmBvuB,GAErC4uB,MAAwBxvB,IAS9B,OARA5G,EAAgBvM,QAASmM,IACnBw2B,EAAkBzyB,IAAI/D,EAAKhC,QAC7Bw4B,EAAkBnvB,IAAIrH,EAAKhC,OAAQw4B,EAAkBplC,IAAI4O,EAAKhC,QAAU,GAExEw4B,EAAkBnvB,IAAIrH,EAAKhC,OAAQ,KAIhCoG,MAAMkD,KAAKkvB,GACfC,KAAK,EAAEC,IAASC,KAAWA,EAAQD,GACnCvkC,IAAI,EAAE6L,EAAQmC,KAAWA,EAAQ,IAAMnC,GACvCxG,KAAK,KACV,CAcuDo/B,CAAoDhvB,GAEzG,CACF,CAcA,SAASivB,EAA0Br+B,EAAaoP,UAIvCA,EAAQkvB,kBACf,MAAMA,EAAoBt+B,EAAYs+B,kBACtC,IAAKA,EACH,OAEF,MAAMC,EAAiBD,EAAkBC,eACrCD,EAAkBC,eAClBD,EAAkB9kC,YACtB,IAAK+kC,EACH,OAEF,MAAMhE,gBAAEA,EAAAC,gBAAiBA,GAAoBL,GAAoBoE,GACjEnvB,EAAQkvB,kBAAoB,CAC1B9kC,YAAa+gC,EACbC,kBACA+D,iBACAC,gBAAiBF,EAAkBE,gBAEvC,CAKA,SAASC,EAAyBtoB,EAAQ/G,GACxC,MAAMsvB,EAAyB7hC,GAAEjE,IAAIud,EAAQ,mEACvCwoB,EAAmB9hC,GAAEjE,IAAIud,EAAQ,6DACvC,CAAC,mBAAoB,aAAc,6BAA6B9a,QAAS+V,IACvEhC,EAAQgC,GAASvU,GAAE0O,IAAImzB,EAAwBttB,GAC3CstB,EAAuBttB,GACvBvU,GAAE0O,IAAIozB,EAAkBvtB,GACxButB,EAAiBvtB,GACjBvU,GAAEjE,IAAIud,EAAQ/E,GAAO,IAE7B,CAEA,SAASwtB,EAAuBC,EAAezvB,GAE7C,GAAIyvB,EAAe,CACjB,IAAIC,EAAiB,GACjBC,EAAqB,GACzB,GAAInzB,MAAMC,QAAQgzB,GAAgB,CAChC,MAAMG,EAAqBH,EAAc98B,KAAMk9B,GAAsC,mBAArBA,EAAa3jC,KACzE0jC,IACFF,EAAiBE,EAAmBp2B,MACpCm2B,EAAqBG,EAAsBJ,GAC3C1vB,EAAQ+vB,SAAWL,GAErBD,EAAcxjC,QAAQ,SAAU4jC,GAE3BpiC,GAAEe,SAASmhC,EAAoBE,EAAa3jC,MAC5CuB,GAAEe,SAASg/B,EAAkCqC,EAAa3jC,OAE3D8T,EAAQgwB,iBAAiBH,EAAa3jC,KAAO2jC,EAAar2B,MAE9D,EACF,MACMi2B,EAAcC,iBAChBA,EAAiBD,EAAcC,eAC/BC,EAAqBG,EAAsBJ,GAC3C1vB,EAAQ+vB,SAAWL,EACnBD,EAAgBhiC,GAAEwiC,KAAKR,EAAeE,IAExCvkC,OAAOsO,OAAOsG,EAAQgwB,iBAAkBviC,GAAEwiC,KAAKR,EAAejC,GAElE,CAEIxtB,EAAQkwB,OAAO,sCACVlwB,EAAQkwB,OAAO,6BAE1B,CAEA,SAASJ,EAAsBJ,GAC7B,MAAMC,EAAqB,GAK3B,OAJAD,EAAexiC,MAAM,QAAQjB,QAAQ,SAAUkkC,GAC7C,MAAMC,EAAoBD,EAAajjC,MAAM,KAAK,GAClDyiC,EAAmB5/B,KAAKqgC,EAC1B,GACOT,CACT,CAEA,SAASU,EAAaC,EAAsBtwB,GACtCswB,GAAwBA,EAAqBxrB,OAC/CrX,GAAElD,IAAI+lC,EAAqBxrB,MAAO,SAAUyrB,GAC1CvwB,EAAQ0jB,KAAK3zB,KAAK,CAAEyJ,MAAO+2B,GAC7B,EAEJ,CAEA,SAASC,EAA4BC,EAAqCzwB,GACpEywB,GACFrlC,OAAOsO,OAAOsG,EAAQ0wB,oBAAqBD,EAE/C,CA2CA,SAASE,EAA2BphC,EAAawK,GAG/C,MAAM+kB,GAFN/kB,EAAWA,GAAY,CAAA,GAEarP,SAAWolB,GAAoB/V,SAASrP,QACtEkmC,EAAgB72B,EAAStO,QAAUqkB,GAAoB/V,SAAStO,OAChEolC,EAAc92B,EAAS9I,MAAQ6e,GAAoB/V,SAAS9I,KAC5D6/B,GAA2BrjC,GAAE0O,IAAI5M,EAAa,6DAChDA,EAAYyvB,WAAW+R,iBAAiBj3B,IAAIg3B,yBAG1C9wB,EAAU,CACdzQ,YAAaA,EAAYzE,KACzBmV,YAAa6e,EACbrzB,OAAQmlC,EACR3/B,KAAM4/B,EACNG,UAAU,EACVC,aAAa,EACbC,mBAAoB,CAAEC,MAAO,IAC7Bn9B,QAAS,UACT88B,2BACAM,cAAc,EACdrR,SAAU,GACVN,SAAU,CACR1b,IAAK,EACLlL,IAAK,EACL8mB,QAAS,GAEX0R,uBAAwB,GACxBC,eAAgB,cAChBn7B,MAAO,CACL,CAAE9M,KAAM,SAAU+M,OAAQ,IAC1B,CAAE/M,KAAM,YAAa+M,OAAQ,MAE/Bm7B,YAAa,aACbvB,iBAAkB,CAAA,EAClBtM,KAAM,GACNwM,OAAQ,CAAA,EACRQ,oBAAqB,CAAA,EACrBc,kBAAkB,EAClBC,YAAY,EACZC,2BAA2B,EAC3BC,aAAa,EACbC,kBAAkB,EAClBC,kBAAmB,UACnBC,oBAAqB,UACrBC,WAAY,CAAC,8BAA+B,uBAAwB,gBAAiB,oBACrFC,eAAe,EACfrhC,cAAe,MACfshC,iBAAkB,MAClB9Z,kBAAmB,GACnBuW,UAAW,CACTwD,gBAAiB,SACjBC,kBAAmB,KACnBC,mBAAmB,EACnBC,mBAAmB,EACnBC,4BAA4B,EAC5B10B,KAAM7D,EAAS6D,MAAQ,SACvB20B,0BAA0B,EAC1B9X,kBAAmB,KAYvB,OAPElrB,EAAYyvB,YACZzvB,EAAYyvB,WAAWC,gCACvB1vB,EAAYyvB,WAAWE,qBAEvBlf,EAAQvP,+BAAiC,CAAC,WA9E9C,SAAsClB,EAAauvB,EAAoB9e,GACrE,OAAOtI,EAAe4E,aAAa,OAAO7S,KAAK,SAAU+oC,GACvD,MAAMC,EAAkBhlC,GAAElD,IAAIioC,EAAa,QACrCE,EAAkBD,EAAgB,GAElCE,EAA6B7T,GAAsB2T,EAAgBjkC,SAASswB,GAElF9e,EAAQC,YAAc0yB,EAA6B7T,EAAqB4T,GAAmB,iBAC7F,EACF,CAwESE,CAA6BrjC,EAAauvB,EAAoB9e,GAASvW,KAAK,IAAMuW,EAC3F,CA2MA,MAAO,CACL2wB,6BACAkC,sCA1MF,SAA+CC,EAActY,GAC3D,MAAMC,EAAoBC,EAAwBC,qCAAqCmY,EAActY,GACrG,OAAOjkB,EAAe7J,QAAQ,CAC5BgiC,UAAW,CACTlU,WACAC,oBACAsY,2BAA2B,EAC3B9Z,MAAO6Z,IAGb,EAiMEE,oCA/LF,SAA6CzjC,EAAaqB,EAAagN,GACrEA,EAAOA,GAAQ,QACf,MAAMq1B,EAAUriC,EAAYqiC,QAEtBjzB,EAAU,CACdzQ,YAAaA,EAAYzE,KACzBooC,kBAAmBzlC,GAAEgK,UAAU7G,EAAYsiC,mBAC3CnT,SAAU,GACVjH,MAAOma,EAAQna,MACfwI,gBAAiB2R,EAAQhf,OACzBhU,YAAarP,EAAYlG,QACzByD,eA7W0BglC,EA6WUviC,EAAYuiC,IA5W3C,CAAC,sBAAuB,8BAA8Bz6B,OAAO,CAACvK,EAAekgC,KAC9E8E,EAAI9E,KACNlgC,EAAgBA,EAAc2lB,OAAOma,EAA2BkF,EAAI9E,MAE/DlgC,GACN,KAwWDigC,qBAAsBF,EAA4Bt9B,EAAYuiC,KAC9DC,oBAAqB3lC,GAAEgK,UAAU7G,EAAYwiC,qBAC7C/B,uBAAwBzgC,EAAYuiC,IAAI,yBACxCjM,eAAgBt2B,EAAYs2B,eAC5Bz7B,OAAQmF,EAAYnF,OACpBg0B,SAAU,CACR1b,IAAKnT,EAAYuiC,IAAIE,QACrBx6B,IAAKjI,EAAYuiC,IAAIG,QACrB3T,QAAS/uB,EAAYuiC,IAAII,iBAE3BvC,SAAUpgC,EAAYogC,SACtBh9B,QAASy5B,EAAmB78B,GAC5BsD,OAAQ45B,EAAkBl9B,GAC1BkgC,yBAA0B9C,EAAkCp9B,GAC5DwgC,aAAcxgC,EAAYwgC,aAC1BE,eAAgB1gC,EAAY+8B,aAAa2D,gBAAkB,cAC3DtB,iBAAkB,CAAA,EAClBtM,KAAM,GACNwM,OAAQ,CAAA,EACRQ,oBAAqB,CAAA,EACrBvY,kBAAmB,GACnBqZ,kBAAkB,EAClBC,YAAY,EACZC,2BAA2B,EAC3BM,eAAe,EACfrhC,cAAe,MACfshC,iBAAkB,MAClBf,mBAAoB,CAClBC,MAAOvgC,EAAYsgC,mBAAqBtgC,EAAYsgC,mBAAmBC,MAAQ,GAC/EqC,YAAa5iC,EAAYsgC,mBAAqBtgC,EAAYsgC,mBAAmBsC,YAAc,MAG7FC,+BAC4C,IAA1C7iC,EAAY6iC,+BACR,EACAhmC,GAAEgK,UAAU7G,EAAY6iC,2BAC9BxC,YAAargC,EAAYqgC,YACzBlqB,OAAQ,CACNrc,QAASkG,EAAYlG,QACrBe,OAAQmF,EAAYnF,OACpBuF,gBAAiBJ,EAAY9F,KAC7B4oC,QAAS9iC,EAAY9F,MAEvB4jC,UAAW,CACTyD,kBAAmB,KACnBC,mBAAoBxhC,EAAYsiC,kBAChCb,mBAAmB,EACnBC,4BAA4B,EAC5B10B,SA9ZN,IAA8Bu1B,EAmb5B,GAjBA9D,EAAyBz+B,EAAaoP,GAEjCA,EAAQgxB,WACXhxB,EAAQ/O,KAAOL,EAAYugC,MAAM,GACjCnxB,EAAQ+G,OAAO9V,KAAOL,EAAYugC,MAAM,IAIxC5hC,EAAYyvB,YACZzvB,EAAYyvB,WAAWC,gCACvB1vB,EAAYyvB,WAAWE,qBAEvBlf,EAAQvP,+BAAiC,CAAC,WAG5Cw+B,EAA0Br+B,EAAaoP,GAEnCpP,EAAY+8B,aAAc,CAC5B,MAAM93B,EAAejF,EAAY+8B,aAAa93B,aAW9C,OAVAzK,OAAOsO,OAAOsG,EAAS,CACrBnK,iBAGEpI,GAAEe,SAASqH,EAAc,aAC3BmK,EAAQ0uB,UAAUiF,eAAiBrG,EAAgCP,wBAAwBl3B,GAC3FmK,EAAQ0uB,UAAUwD,gBAAkB,eAGtClyB,EAAQ0uB,UAAUkF,QAAUhjC,EAAY+8B,aAAaiG,QAnfzD,SAAmD5zB,GACjD,OAAOqtB,EAAoB/1B,cAAc,OAAO7N,KAAK,SAAUiN,GAC7DA,EAAWzK,QAAQ,SAAU+L,GAC3BA,EAASrB,SAAS1K,QAAQ,SAAUgM,GAClCA,EAAOlB,cAAc9K,QAAQ,SAAU4J,GACjCA,EAAa/K,OAASkV,EAAQnK,eAChCmK,EAAQ0uB,UAAUwD,gBAAkBl6B,EAAS3O,KAEjD,EACF,EACF,EACF,EACF,CAweWwqC,CAA0C7zB,GAASvW,KAAK,WAW7D,OArVN,SAAsCqqC,EAAY9zB,GAC5C8zB,GACF9zB,EAAQ2xB,YAAcmC,EAAWnC,YACjC3xB,EAAQ4xB,iBAAmBkC,EAAWlC,iBACtC5xB,EAAQ6xB,kBAAoBiC,EAAWjC,oBAEvC7xB,EAAQ2xB,aAAc,EACtB3xB,EAAQ4xB,kBAAmB,EAC3B5xB,EAAQ6xB,kBAAoB,UAEhC,CAiUMkC,CAA6BnjC,EAAY+8B,aAAaC,iBAAiBoG,WAAWF,WAAY9zB,GAC9FwvB,EAAuB5+B,EAAY+8B,aAAaC,iBAAiBoG,WAAW7F,SAASrpB,MAAO9E,GAC5FqwB,EAAaz/B,EAAY+8B,aAAaC,iBAAiBoG,WAAWtQ,KAAM1jB,GA/N9E,SAAwBi0B,EAAwBj0B,GAC1Ci0B,IACF7oC,OAAOsO,OAAOsG,EAAQkwB,OAAQ+D,GAE1Bj0B,EAAQkwB,OAAO,4BACVlwB,EAAQkwB,OAAO,oBAGpBlwB,EAAQkwB,OAAO,kCACVlwB,EAAQkwB,OAAO,0BAIpBlwB,EAAQkwB,OAAO,sCACVlwB,EAAQkwB,OAAO,8BAG5B,CA+MMgE,CAAetjC,EAAYqjC,uBAAwBj0B,GA7MzD,SAA4Bm0B,EAAiBn0B,GACvCm0B,GAAmBA,EAAgB/lC,QACrC4R,EAAQ8xB,oBAAsBqC,EAAgB,GAAGC,MACjDp0B,EAAQ+xB,WAAatkC,GAAElD,IAAI4pC,EAAgB,GAAGE,OAASC,GAC9CA,EAAU5/B,QAAQ,mCAAoC,MAG/DsL,EAAQ+xB,WAAa,EAEzB,CAqMMwC,CAAmB3jC,EAAY+8B,aAAaC,iBAAiBoG,WAAWG,gBAAiBn0B,GACzFwwB,EACE5/B,EAAY+8B,aAAaC,iBAAiBoG,WAAWtD,oBACrD1wB,GArbR,SAAmC7J,EAAO6J,GAexC,MAAMw0B,GAdNr+B,EAAQA,EAAM5L,IAAI,CAAC6N,EAAMyH,IACT,IAAVA,EACK,CACLxW,KAAM+O,EAAKq8B,iBAAiBC,SAC5Bt+B,OAAQgC,EAAKq8B,iBAAiBE,YAGzB,CACLtrC,KAAM+O,EAAKq8B,iBAAiBC,SAC5Bt+B,OAAQgC,EAAKq8B,iBAAiBE,WAC9BC,YAAannC,GAAEC,KAAKD,GAAEjE,IAAI4O,EAAM,+BAAgC,IAAIlL,MAAM,OAAS,QAI7DtD,OAAQwO,GAAuB,cAAdA,EAAK/O,MAC5CmP,EAAkBrC,EAAMvM,OAAQwO,GAASA,EAAK/O,KAAKoP,WAAW,QAAUL,EAAK/O,KAAKoP,WAAW,eAEnG,OAAID,EAAgBpK,QAClB4R,EAAQ7J,MAAQqC,EAAgBsb,OAAO0gB,GAChCnH,EACJwH,uBACC70B,EAAQiyB,iBACRxkC,GAAEe,SAASwR,EAAQnK,aAAc,WAAa,cAAgBmK,EAAQnK,cAEvEpM,KAAMglC,IACLzuB,EAAQ0uB,UAAUD,oBAAsBA,EACxCD,EAAsCC,EAAqBzuB,OAG/DA,EAAQ7J,MAAQ,CAAC,CAAE9M,KAAM,SAAU+M,OAAQ,KAAM0d,OAAO0gB,GACjDj+B,EAAe7J,QAAQ,MAElC,CAuZaooC,CAA0BlkC,EAAY+8B,aAAaC,iBAAiBoG,WAAW79B,MAAO6J,GAASvW,KACpG,WACE,OAAOuW,CACT,EAEJ,EACF,CAEA,OAAOzJ,EAAe7J,QAAQsT,EAChC,EA+EE+0B,oCA7EF,SAA6CxlC,EAAaylC,EAAiBlC,EAActY,GACvF,MAAMya,EAAkBxnC,GAAEgK,UAAUu9B,GAC9BvpC,EAASL,OAAOY,KAAKipC,EAAgB9c,mBAAmB,GACxDlnB,EAAOgkC,EAAgBhkC,KACvBikC,EAA6B7H,EAAoB8H,2BACrD,MACAF,EAAgBp/B,cAGZu/B,EAAiB,CAAE1qC,QAASuqC,EAAgBvqC,QAASe,SAAgBwF,QAC3E,OAAOsF,EACJoF,IAAI,CAACg1B,EAA2BphC,EAAa6lC,GAAiBF,IAC9DzrC,KAAK,UAAWuW,EAASkyB,IACxB,MAAMzX,EAAoBC,EAAwBC,qCAChDmY,EACAtY,GAEIkU,EAAY,CAChBlU,WACAvB,MAAO6Z,EACPZ,kBACAmD,uBAAuB,EACvB5a,oBACA6a,yBAAyB,EACzBlD,mBAAoB6C,EAAgB/B,kBACpCt1B,KAAM,eACN23B,kBAAmB,OACnB5B,eACsB,gBAApBzB,EACI5E,EAAgCP,wBAAwBkI,EAAgBp/B,cACxE,KACN2/B,mBAAmB,GAGfC,EAAgB,CACpBhqC,SACAwU,YAAag1B,EAAgBvqC,QAC7BsnC,eAAgBiD,EAAgBxT,eAChCiN,aAGFuG,EAAgBlV,SAAWkV,EAAgBlV,UAAY,GAEvD,MAAM2V,EAAkBtqC,OAAOsO,OAAO,CAAA,EAAIsG,EAASi1B,EAAiBQ,GAKpE,cAFOC,EAAgBC,gBA9c7B,SAAmC31B,GACjC,MAAMxH,EAAkB+1B,EAAmBvuB,GACrCw0B,EAAgBlG,EAAiBtuB,GAEvC,OAAIxH,EAAgBpK,QAClB4R,EAAQ7J,MAAQqC,EAAgBsb,OAAO0gB,GAChCnH,EACJwH,uBACC70B,EAAQiyB,iBACRxkC,GAAEe,SAASwR,EAAQnK,aAAc,WAAa,cAAgBmK,EAAQnK,cAEvEpM,KAAMglC,IACLzuB,EAAQ0uB,UAAUD,oBAAsBA,EACxCD,EAAsCC,EAAqBzuB,OAG/DA,EAAQ7J,MAAQ,CAAC,CAAE9M,KAAM,SAAU+M,OAAQ,KAAM0d,OAAO0gB,GACjDj+B,EAAe7J,QAAQ,MAElC,CA6bakpC,CAA0BF,GAAiBjsC,KAAK,WACrD,MAAMumC,EAAmB0F,EAAgB1F,iBA7fjD,IAA0C7B,EA8flCuH,EAAgBvnC,eA9fkBggC,EA8f+B6B,EA7fhE,CAAC,sBAAuB,8BAA8Bt3B,OAAO,CAACvK,EAAekgC,KAC9EF,EAASE,KACXlgC,EAAgBA,EAAc2lB,OAAOma,EAA2BE,EAASE,MAEpElgC,GACN,KAyfGunC,EAAgBtH,qBAAuBF,EAA4B8B,GACnE0F,EAAgBrE,uBAAyBrB,EAAiB,yBACtDA,EAAiB,yBAAyB9iC,MAAM,KAChD,GACJwoC,EAAgBpE,eAAiB2D,EAAgB3D,gBAAkB,cACnEoE,EAAgB1F,iBAAmB,CAAA,EACnCR,EAAuBQ,EAAkB0F,GACzCzG,EAA0BgG,EAAiBS,GAC3CrG,EAAyB4F,EAAiBS,GAE1C,MAAMpF,EAAuB,CAAExrB,MAAO4wB,EAAgBhS,MACtDgS,EAAgBhS,KAAO,GACvB2M,EAAaC,EAAsBoF,GAKnC,OAFAlF,EAD4BkF,EAAgBhF,oBACKgF,GAE1CA,CACT,EACF,EACJ,EAQF,ECxlBK,MAAMG,GACX,+BAAcC,EAAyBC,YACrCA,EAAA91B,YACAA,EAAAixB,mBACAA,EAAAF,SACAA,EAAAC,YACAA,EAAAhgC,KACAA,IAEA,MAAM+kC,EAAiB9rC,KAAK+rC,6BAA6BF,EAAa91B,GAEtE,GAAIhP,IAAS+/B,EACX,OAAO9mC,KAAKgsC,2BAA2BF,EAAgB/kC,GAGzD,GAAI+/B,GAAYC,EAAa,CAC3B,MACMkF,EADQ3sC,GAAI0nC,EAAoB,QAAS,IACR3mC,IAAK6rC,GAAMlsC,KAAKgsC,2BAA2BF,EAAgBI,IAClG,OAAOC,GAAeC,MAAM,KAAM,IAAIH,EAA0B,QAClE,CAEA,MAAO,EACT,CAEA,mCAAeF,CAA6BF,EAAkB91B,GAC5D,OAAOzW,GAAIusC,EAAa,CAAC,4BAA6B91B,EAAa,6BAA8B,GACnG,CAEA,iCAAei2B,CACbF,EACA/kC,GAEA,OAAOzH,GAAIwsC,EAAgB,CAAC/kC,EAAM,mBAAoB,oBAAqB,IAAI1G,IAAKgsC,IAC3E,IACFA,EACHC,oBAAqBtsC,KAAKusC,uBAAuBF,KAGvD,CAEA,6BAAeE,CAAuBC,GACpC,MAAMC,EAAW1yB,GAASyyB,EAAYE,yBAA2BF,EAAYE,wBAA0B,EACjGJ,EAAsB,GAC5B,IAAA,IAASK,EAAI,EAAGA,GAAKF,EAAUE,GAAK,EAClCL,EAAoBzmC,KAAK8mC,GAE3B,OAAOL,CACT,EClEK,MAAMM,GACX,WAAA9rC,GACE,MAAM+rC,EAAY,CAAC,UAAW,iBAAkB,iCAAkC,iCAElF7sC,KAAK8sC,MAAQ,KACXD,EAAU9qC,QAASC,UAAehC,KAAKgC,KAGzChC,KAAKkC,SAAY4T,IACf9V,KAAK8V,QAAUA,EACf,MAAMC,YAAEA,EAAA81B,YAAaA,GAAgB/1B,EACrC,QAAgD,IAA5C+1B,EAAY7O,eAAejnB,GAA4B,CACzD/V,KAAK+sC,qBAAuBxpC,GAAEgK,UAAUs+B,EAAY7O,eAAejnB,GAAanG,IAAI+uB,QAEpFqO,EAA+BhtC,KAAK+sC,qBAAsBj3B,EAAQ0jB,MAElE,MAAMyT,MAAEA,EAAAC,kBAAOA,GAAsBC,EAA0BntC,KAAK+sC,sBACpE/sC,KAAKotC,+BAAiCH,EACtCjtC,KAAKqtC,8BAAgCH,CACvC,CAEKp3B,EAAQknB,iBACXlnB,EAAQknB,eAAiBh9B,KAAKstC,8BAA8Bx3B,EAAQ0jB,QAIxEx5B,KAAKstC,8BAAgC,CAACC,EAAc,KAC3ChqC,GAAE8L,MAAMk+B,GACZltC,IAAKmtC,GAAMxtC,KAAKotC,+BAA+BI,EAAEl+B,QACjDzB,UACA4/B,UACA/tC,OAAQguC,GAAOA,EAAG5jC,UAAY9J,KAAK8V,QAAQhM,SAC3CzJ,IAAI,MACJqoB,OACApZ,QAGL,MAAM09B,EAAiC,CAACD,EAAsBQ,EAAc,MAC1ER,EAAqBhrC,QAAS2rC,IAE5B,MAAMC,EAAUD,EAAG9Q,WACnB8Q,EAAGE,UAAYD,EAAUA,EAAQpf,UAAU,EAAGof,EAAQzpC,OAAS,GAAGlB,MAAM,MAAQ,GAEhF0qC,EAAGG,aAAeN,EACdhqC,GAAEuqC,aACAP,EAAYltC,IAAKmtC,GAAMA,EAAEl+B,OACzBo+B,EAAGE,WAEL,MAIFT,EAA6BJ,GAC1BA,EAAqBv+B,OAC1B,CAACu/B,EAAWL,KACV,MAAMR,kBAAEA,GAAsBa,EAG9B,OAFAb,EAAkBQ,EAAGvlC,IAAMulC,EAEpBA,EAAGE,UAAUp/B,OAAO,CAACu/B,EAAW1H,KACrC,MAAM4G,MAAEA,GAAUc,EAMlB,OALKd,EAAM5G,KACT4G,EAAM5G,GAAO,IAEf4G,EAAM5G,GAAKxgC,KAAK6nC,GAETK,GACNA,IAEL,CAAEd,MAAO,GAAIC,kBAAmB,CAAA,IAIpCltC,KAAKguC,kCAAoCzqC,GAAE0qC,SAAUC,IACnD,IAAIC,EAA8BnuC,KAAKotC,+BAA+Bc,GACtE,MAAME,EAAIpuC,KAAK8V,QAEXq4B,IACFA,EAA8B5qC,GAAE7D,OAC9ByuC,EACCT,GAAOA,EAAG5jC,UAAY9J,KAAK8V,QAAQhM,UAIpCqkC,IACFE,EAAyCF,EAA6BD,GACtEE,EAAEpR,eAAiBz5B,GAAElD,IACnBiuC,EAA6BC,EAA+BH,EAAEpR,gBAAiBmR,GAC/E,OAMJnuC,KAAKwuC,sBACJ,KAEHxuC,KAAKwuC,mBAAqB,KACxB,MAAMJ,EAAIpuC,KAAK8V,QACT0jB,EAAO4U,EAAE5U,KAAKn5B,IAAKmtC,GAAMA,EAAEl+B,OAEjCi/B,EAA+BH,EAAEpR,gBAAgBj7B,QAAS2rC,IACpDA,EAAGG,eACLH,EAAGG,aAAetqC,GAAEuqC,aAAaJ,EAAGG,aAAcrU,IAG/Cj2B,GAAEjE,IAAIouC,EAAI,yBACbU,EAAEpR,eAAiBz5B,GAAEkrC,QAAQL,EAAEpR,eAAgB0Q,EAAGvlC,QAKxDnI,KAAK0uC,OAAUR,IACb,MAAME,EAAIpuC,KAAK8V,QACT0jB,EAAO4U,EAAE5U,KACf,IAAI2U,EAA8BnuC,KAAKotC,+BAA+Bc,GAElEC,IACFA,EAA8B5qC,GAAE7D,OAC9ByuC,EACCT,GAAOA,EAAG5jC,UAAY9J,KAAK8V,QAAQhM,UAKrCvG,GAAEe,SACDk1B,EAAKn5B,IAAKmtC,GAAMA,EAAEl+B,OAClB4+B,IAGF1U,EAAK3zB,KAAK,CAAEyJ,MAAO4+B,IAGjBC,IACFE,EAAyCF,EAA6BD,GACtEE,EAAEpR,eAAiBz5B,GAAElD,IACnBiuC,EAA6BC,EAA+BH,EAAEpR,gBAAiBmR,GAC/E,QAKN,MAAMI,EAAkCI,GAAQA,EAAItuC,IAAK8H,GAAOnI,KAAKqtC,8BAA8BllC,IAE7FkmC,EAA2C,CAACtB,EAAsB6B,KACtE7B,EAAqBhrC,QAAS2rC,IAC5BA,EAAGG,aAAetqC,GAAE8L,MAAMq+B,EAAGG,cAAgB,IAC1CjkB,OAAO,CAACglB,IACRlmB,OACApZ,WAIDg/B,EAA+B,CAACO,EAAWC,IACxCvrC,GAAE8L,MAAMw/B,GAAWjlB,OAAOklB,GAAWpmB,OAAOpZ,QAkDrD,OA/CAtP,KAAK+uC,UAAab,IAChB,MAAME,EAAIpuC,KAAK8V,QACTk5B,EAAmBZ,EAAEpR,gBAAkB,GAChBuR,EAA+BS,GAEvCjtC,QAAS2rC,IACxBA,EAAGG,eACLH,EAAGG,aAAeH,EAAGG,aAAanuC,OAAQ2mC,GAAQA,IAAQ6H,MAI9DE,EAAE5U,KAAO4U,EAAE5U,KAAK95B,OAAQ2mC,GAAQA,EAAI/2B,QAAU4+B,IAGhDluC,KAAKivC,oBAAuBvO,IAC1B,MAAMwO,EAAsBlvC,KAAKqtC,8BAA8B3M,GACzDyO,EAAeD,EAAoBrB,aACnCO,EAAIpuC,KAAK8V,QAEfy4B,EAA+BH,EAAEpR,gBAAgBj7B,QAAS2rC,IACpDA,EAAGG,eACLH,EAAGG,aAAetqC,GAAE6rC,WAAW1B,EAAGG,aAAcsB,MAIpDD,EAAoBrB,aAAe,GACnCO,EAAE5U,KAAOj2B,GAAE8L,MAAM++B,EAAE5U,MAChBn5B,IAAKmtC,GAAMA,EAAEl+B,OACb8/B,WAAWD,GACX9uC,IAAKmtC,KAASl+B,MAAOk+B,KACrBl+B,SAGLtP,KAAKqvC,kBAAqBnB,IACxB,MAAMoB,EAAS/rC,GAAEjE,IAAIU,KAAM,CAAC,iCAAkCkuC,IACxDqB,EAAWD,EAASA,EAAO5vC,OAAQguC,GAAOA,EAAG5jC,UAAY9J,KAAK8V,QAAQhM,SAASzJ,IAAKqtC,GAAOA,EAAGvlC,IAAM,GAE1G,MAAO,8CACLonC,EAASrrC,OAAS,EAAI85B,EAAe1+B,IAAI,aAAe0+B,EAAe1+B,IAAI,kCAE/DiwC,EAAS7pC,KAAK,eAG9B1F,KAAKwvC,YAAetB,KACT3qC,GAAEjE,IAAIU,KAAM,CAAC,iCAAkCkuC,IAGnDluC,IACT,+BC7LK,MAAMyvC,GAAwC,CAAC,MAAO,OAAQ,WAAY,mBAC1E,MAAMC,GAGX,WAAA5uC,CACEuL,EAAiB,CAAEoF,IAAMgE,GAAWlT,QAAQkP,IAAIgE,GAASjT,QAAU8M,GAAU/M,QAAQC,QAAQ8M,IAC7F2uB,GAEA,MAAME,EAAsBF,EAAgBE,oBACtC7U,EAAqB2U,EAAgB3U,mBACrCqmB,EAAyB,IAAIvjC,GAAuBC,GACpD+2B,EAAkC,IAAI3B,GACtC7Y,EAA2B,IAAIR,GAC/BpnB,EAAuB,IAAIlB,GAC3B8vC,EAAgB,IAAIhD,GACpBiD,EAAgC,IAAIxjB,GACpCyjB,EAAsB,CAAC,cAAe,SAAU,sBAChDjI,EAAa,CACjB,iBACA,iBACA,mBACA,UACA,8BACA,qBACA,uBACA,wBACA,0BACA,YACA,WACA,mBACA,YACA,gBACA,eACA,gBACA,mBACA,kBACA,aACA,yBACA,gBACA,iBACA,wBA+FF,SAASkI,EAAuCj6B,GACvBA,EAAQ+1B,YAAYmE,0BAA0Bl6B,EAAQC,aACxED,EAAQkxB,mBAAmBsC,cAC9BxzB,EAAQkxB,mBAAmBsC,YAAc,OAE7C,CAUA,SAAS2G,EAAuBn6B,GAC9B,MAAM1V,EAAS,CAAE8vC,MAAO,IACxB,GAAIp6B,EAAQvU,OAAQ,CAClB,MAAM9B,EAAU,CAACW,EAAO8vC,OAExBzwC,EAAQoG,KAAKsqC,EAA6Br6B,GAASo6B,OACnDzwC,EAAQoG,KA8BZ,SAAwCiQ,GACtC,MAAMs4B,EAAIt4B,EACJ1V,EAAS,CAAE8vC,MAAO,IAElBE,EAAYhC,EAAEtH,SAAWsH,EAAEpH,mBAAmBC,MAAQ,CAACmH,EAAErnC,OACzDipC,0BAAEA,GAA8B5B,EAAEvC,aAClC/8B,2BAAEA,GAA+BkhC,EAA0B5B,EAAEr4B,aAEnE,GAAIq6B,EAAUtR,MAAOuR,IAAOA,GAC1B,OAAOjwC,EAGT,IAAI8pB,EAAWylB,EAAuB9gC,8BAA8BC,EAA4BshC,GAEhGlmB,EA4FF,SAA2Brd,GACzB,MAAMyjC,EAAyB/sC,GAAElD,IAAIwM,EAAgBlB,IACnD,MAAM4kC,EAAS5kC,EAAa3I,MAAM,KAElC,MAAO,CACLwtC,MAAOD,EAAO,GACd1jB,MAAO0jB,EAAO,GACd56B,MAAOQ,OAAOo6B,EAAO,KAAO,KAI1BE,EAA+BltC,GAAEmtC,OAAOJ,EAAwB,CAAC,QAAS,QAAS,UAEzF,OAAO/sC,GAAElD,IAAIowC,EAA+BE,GAExCA,EAA4BH,MAC5B,IACAG,EAA4B9jB,OAC3B8jB,EAA4Bh7B,MAAQ,IAAMg7B,EAA4Bh7B,MAAQ,IAGrF,CAjHai7B,CAAkB1mB,GAC7B,MAAMve,EAAeyiC,EAAEziC,aACnBpI,GAAEu7B,MAAM,CAACnzB,GAAepI,GAAEe,SAASqH,EAAc,YAAapI,GAAEe,SAAS4lB,EAAUve,OACrFvL,EAAO8vC,MAAMvkC,aAAeyiC,EAAEziC,aAC9ByiC,EAAEziC,aAAe,MAGnB,OADAyiC,EAAEvC,YAAY3hB,SAASrd,cAAgBqd,EAChC9pB,CACT,CApDiBywC,CAA+B/6B,GAASo6B,OAErDhvC,OAAOsO,UAAU/P,EACnB,MACEqW,EAAQ+1B,YAAY3hB,SAASrd,cAAgB,GAE/C,OAAOzM,CACT,CAEA,SAAS0wC,EAAsBh7B,GAC7B,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SACnC8mB,EACJl7B,EAAQ+1B,YAAYmE,0BAA0Bl6B,EAAQC,aAAai7B,0BAErED,EAAaE,aAAe,CAAC,eAE7B,MAAMhiC,EAAW6G,EAAQgxB,SAAWhxB,EAAQvU,OAASuU,EAAQ/O,KAU7D,OARIxD,GAAE0O,IAAI++B,EAA2B/hC,KACnC8hC,EAAaE,aAAe1tC,GAAEqmB,OAAOmnB,EAAaE,aAAcD,EAA0B/hC,KAGvF1L,GAAEe,SAASysC,EAAaE,aAAcn7B,EAAQsxB,yBAC1CtxB,EAAQsxB,eACfhnC,EAAO8vC,MAAM9I,gBAAiB,GAEzBhnC,CACT,CA0BA,SAAS+vC,EAA6Br6B,GACpC,MAAMs4B,EAAIt4B,EACJ1V,EAAS,CAAE8vC,MAAO,IACxB,IAAItO,EAAYr+B,GAAEjE,IAAI8uC,EAAG,sCACzB,MAAMzM,EAAiBp+B,GAAEjE,IAAI8uC,EAAG,2CAC1BrhC,EAASxJ,GAAEjE,IAAI8uC,EAAG,mCAClB5L,EAAiBj/B,GAAEjE,IAAI8uC,EAAG,4CAC1BrnC,KAAEA,EAAA+/B,SAAMA,EAAAvlC,OAAUA,GAAW6sC,GAC7Bt/B,2BAAEA,GAA+Bs/B,EAAEvC,YAAYmE,0BAA0B5B,EAAEr4B,aAC3E9G,EAAW63B,EAAWvlC,EAASwF,EAErC,OAAKkI,IAIDlI,GAAQ+/B,IACVvjC,GAAEgS,IACA64B,EACA,2CACAhL,EAAgCrB,iCAAiC9yB,EAAUH,IAM5E8yB,GACAwB,EAAgC1B,4BAC/BC,EACAC,EACA3yB,EACAH,KAGF8yB,EAAYr+B,GAAEjE,IAAI8uC,EAAG,+CACrB7qC,GAAEgS,IAAI64B,EAAG,qCAAsCxM,IAGjDr+B,GAAEgS,IACA64B,EACA,6CACAhL,EAAgCf,oCAAoCV,EAAgBC,IAIpFr+B,GAAEu7B,MAAM,CACN/xB,EACA60B,GACCwB,EAAgCd,cAAcX,EAAgB50B,EAAQ60B,EAAWY,OAGpFj/B,GAAEgS,IAAI64B,EAAG,uCAAmC,GAC5ChuC,EAAO8vC,MAAMvkC,aAAeyiC,EAAEziC,aAC9ByiC,EAAEziC,aAAe,MAGnBpI,GAAEgS,IACA64B,EACA,qDACAhL,EAAgCpB,mCAG3B5hC,GAjDEA,CAkDX,CAEA,SAAS8wC,EAAsBp7B,GAC7B,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBiB,EAAmBxF,GAAsBC,yBAAyB91B,GACxEvS,GAAEgS,IAAIO,EAAS,CAAC,YAAa,oBAAqBq7B,GAClD/wC,EAAO8vC,MAAMiB,kBAAmB,EAChC,MAAMC,EAAqB7tC,GAAEjE,IAAIwW,EAAS,qBAAsB,IAShE,OARIs7B,EAAmBltC,OAAS,IAC9B4R,EAAQu7B,mBAAqBD,EAAmB1xC,OAC7C4xC,KAAaH,EAAiB1oC,KAAM4jC,GAAMA,EAAEzrC,OAAS0wC,EAAOC,kBAErB,IAAtCz7B,EAAQu7B,mBAAmBntC,eACtB4R,EAAQu7B,oBAGZjxC,CACT,CA0BA,SAASoxC,EAAgB17B,GACvBA,EAAQikB,MAAQjkB,EAAQ0uB,UAAUkF,QAClC,MAAMtpC,EAAS,CAAE8vC,MAAO,IAQxB,OAPIp6B,EAAQC,cAAgBD,EAAQ0uB,UAAUiN,mBAC5C37B,EAAQ0uB,UAAUiN,iBAAmB37B,EAAQC,YACxCxS,GAAE8L,MAAMyG,EAAQ+1B,YAAY6F,WAAWjpC,KAAK,CAAEkqB,UAAW7c,EAAQikB,QAASzqB,UAC7EwG,EAAQikB,MAAQ,KAChB35B,EAAO8vC,MAAMvd,WAAY,IAGtBvyB,CACT,CAEA,SAASuxC,EAAe77B,GACtB,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SACzC,GAAuB,OAAnBpU,EAAQvU,OACV,OAAOnB,EAET,MAAMoQ,EAAUsF,EAAQ+1B,YAAYmE,0BAA0Bl6B,EAAQC,aAAavF,QAcnF,OAbIjN,GAAEgP,QAAQ/B,IACZugC,EAAa9J,MAAQ1jC,GAAEkF,KAAK+H,EAAS,CAAE5P,KAAMkV,EAAQvU,SAAU0lC,MAC/D8J,EAAaa,eAAiBruC,GAAEw/B,UAAUgO,EAAa9J,MAAMtC,OAAQ,IAGrEoM,EAAa9J,MAAQz2B,EAAQsF,EAAQvU,QAElCgC,GAAE8L,MAAM0hC,EAAa9J,OAAO3iC,SAASwR,EAAQ/O,MAAMuI,iBAC/CwG,EAAQ/O,KACV+O,EAAQgxB,WACX1mC,EAAO8vC,MAAMnpC,MAAO,IAGjB3G,CACT,CAEA,SAASyxC,EAAgB/7B,GAEvB,OAAOqrB,GADsB59B,GAAE7D,OAAOoW,EAAQ+1B,YAAY5rC,aAAc,CAAEO,QAASsV,EAAQC,cAE7F,CAEA,SAAS+7B,EAAsBh8B,GAC7B,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SAEzC,OAA4B,OAAxBpU,EAAQC,cAIZg7B,EAAa9wC,aAAe4xC,EAAgB/7B,GAG1CvS,GAAE0O,IAAI6D,EAAS,mCACdvS,GAAE8L,MAAM0hC,EAAa9wC,cAAcI,IAAI,YAAYiE,SAASwR,EAAQkvB,kBAAkBC,gBAAgB31B,gBAEhGwG,EAAQkvB,kBAAkB9kC,YACjCE,EAAO8vC,MAAMlL,mBAAoB,GAEjC5kC,EAAO8vC,MAAMlL,kBAAoB,MAZ1B5kC,CAgBX,CAgBA,SAAS2xC,EAAuBj8B,EAAS1R,GACvC,OAAOA,EAAa7C,SAAWuU,EAAQvU,QAAkC,WAAxB6C,EAAa7C,MAChE,CAEA,SAASywC,EAA6Bl8B,GACpC,MAAMrW,EAAU,CAAEywC,MAAO,IACnB/yB,EAAUrH,EAAQ7R,cAClBguC,EAAyBpC,EAA8BvjB,yBArB/D,SAA0BxW,GACxB,OAAOvS,GAAE8L,MAAMyG,EAAQ+1B,YAAY5nC,eAChC5D,IAAI,YACJ6xC,cACAxyC,OAAO,CAAEkB,KAAMkV,EAAQC,cACvB1V,IAAI,WACJ6xC,cACA7xC,IAAI,iBACJ6xC,cACAxyC,OAAO6D,GAAE4uC,MAAMJ,EAARxuC,CAAgCuS,IACvC4S,OACApZ,OACL,CASwF8iC,CAAiBt8B,IAIvG,GAHAA,EAAQ+1B,YAAY3hB,SAASmoB,kBAAoB9uC,GAAE+uC,MAAML,EAAwB,QACjFn8B,EAAQ+1B,YAAY3hB,SAASjmB,cAAgBV,GAAElD,IAAI4xC,EAAwB,QAEvE90B,GAAWrH,EAAQ7R,cAAe,CACpC6R,EAAQ7R,cAAgB2kB,EAAyBL,qCAC/CzS,EAAQ7R,cACR6R,EAAQC,YACRk8B,GAEF,MAAMM,EAAUhvC,GAAEuqC,aAAah4B,EAAQ+1B,YAAY3hB,SAASjmB,cAAe6R,EAAQ7R,eAC7EuuC,EAAUjvC,GAAEkvC,IAAIF,EAASz8B,EAAQ7R,eACvC6R,EAAQ7R,cAAgBsuC,EAU5B,SAAwCz8B,GAOtC,MAAM48B,EAAuB58B,EAAQqxB,uBAC/BwL,EAAU78B,EAAQ+1B,YAAY3hB,SAASmoB,kBAEvC7wC,EAAkBsU,EAAQ7R,cAAcuK,OAAO,CAAChN,EAAiBoxC,KACjEhqB,EAAyBP,mBAAmBsqB,EAAQC,MACtDpxC,EAAgBoxC,GAAUrvC,GAAEuqC,aAAa6E,EAAQC,GAAQpxC,gBAAiBkxC,IAErElxC,GACN,CAAA,GAECN,OAAOY,KAAKN,GAAiB0C,OAAS,IACxC4R,EAAQtU,gBAAkBA,EAE9B,CA7BIqxC,CAA+B/8B,GAE3B08B,EAAQtuC,SACVzE,EAAQywC,MAAMjsC,cAAgBuuC,EAElC,CACA,OAAO/yC,CACT,CAiCA,SAASqzC,EAAoBh9B,EAASi9B,GAEpC,OADA1zC,EAAqB4e,WAAW,gBACzBjd,EAAqBjB,mBAAmBR,KAAK,SAAUU,GAC5D6V,EAAQ+1B,YAAY5rC,aAAeA,EAC9B8yC,GACHjB,EAAsBh8B,EAE1B,EACF,CAEA,SAASk9B,EAAiBl9B,GACxB,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SACzC,OAAuB,OAAnBpU,EAAQvU,SAGZwvC,EAAatgC,QAAUlN,GAAE8L,MAAMyG,EAAQ+1B,YAAYp7B,SAChD/Q,OAAO,CAAEc,QAASsV,EAAQC,YAAajM,QAASgM,EAAQhM,QAASvI,OAAQuU,EAAQvU,SACjFlB,IAAI,MACJiP,QAEE/L,GAAE8L,MAAM0hC,EAAatgC,SAASnM,SAASwR,EAAQ9L,QAAQsF,UAC1DwG,EAAQ9L,OAAS,GACjB5J,EAAO8vC,MAAMlmC,QAAS,IATf5J,CAYX,CAEA,SAAS6yC,EAAkBn9B,GACzB,IAAIo9B,EAAoBp9B,EAAQ+1B,YAAY7O,eAAelnB,EAAQC,cAAgB,CAAEnG,IAAK,IAI1F,OAHAsjC,EAAoB3vC,GAAE7D,OAAOwzC,EAAkBtjC,IAAI+uB,OAAQ,SAAUrD,GACnE,OAAOA,EAAcxxB,UAAYgM,EAAQhM,OAC3C,GACOvG,GAAE8L,MAAM6jC,GAAmBxC,OAAO,QAAQphC,OACnD,CAUA,SAAS6jC,EAA8Br9B,GACrC,MAAMrW,EAAU,CAAEywC,MAAO,IACnBkD,EAAiBt9B,EAAQ+1B,YAAY3hB,SAAS8S,eAC9CkW,EAAoBD,EAAkBn9B,GAC5C,GAAIs9B,GAAkBt9B,EAAQknB,eAAgB,CAE5C,MAAMqW,EAAoBv9B,EAAQknB,eAAe38B,IAAI,SAAUizC,GAC7D,MAAM3pC,EAAQpG,GAAE8L,MAAM+jC,GAAgB3qC,KAAK,CAAEN,GAAImrC,IAAWhkC,QAC5D,OAAO3F,EAAQA,EAAMxB,GAAKmrC,CAC5B,GACMC,EAAgBz9B,EAAQknB,eAC3B38B,IAAI,SAAUizC,GACb,MAAMhY,EAAgB/3B,GAAE8L,MAAM+jC,GAAgB3qC,KAAK,CAAEN,GAAImrC,IAAWhkC,QACpE,OAAOgsB,EAAgBA,EAAcnzB,GAAK,IAC5C,GACC9H,IAAI,SAAUmzC,GACb,OAAOjwC,GAAE8L,MAAM6jC,GAAmBzqC,KAAK,CAAEN,GAAIqrC,IAAalkC,OAC5D,GACC5P,OAAO,SAAUmtB,GAChB,OAAOA,CACT,GACF/W,EAAQknB,eAAiBz5B,GAAElD,IAAIkzC,EAAe,MAC9C,MAAMf,EAAUjvC,GAAEkvC,IAAIY,EAAmBv9B,EAAQknB,gBAC7CwV,EAAQtuC,SACVzE,EAAQywC,MAAMlT,eAAiBwV,EAEnC,CAGA18B,EAAQ+1B,YAAY3hB,SAAS8S,eAAiBz5B,GAAE7D,OAAOwzC,EAAmB,SAAU5X,GAClF,OAAQ/3B,GAAEqK,QAAQ0tB,EAAcsB,WAClC,GAGA9mB,EAAQ29B,uBAAyBlwC,GAAE7D,OAAOwzC,EAAmB,SAAU5X,GACrE,OAAO/3B,GAAEqK,QAAQ0tB,EAAcsB,WACjC,GAGA,MAAM8W,GA/CwB5pC,EA+CgBgM,EAAQhM,UA9CvCA,EAAQxF,SAAS,KACvBwF,EAAQ9G,MAAM,KAAK,GAAK,IAExB,GAJX,IAAgC8G,EAgD9B,MAAM6pC,EAA0BpwC,GAAElD,IAAIyV,EAAQknB,eAAiB0Q,GAC5DA,EAAGn/B,WAAWmlC,GAAwChG,EAAtBgG,EAAiBhG,GAIpD,OAFA53B,EAAQknB,eAAiBz5B,GAAE6rC,WAAWuE,EAAyBpwC,GAAElD,IAAIyV,EAAQ29B,uBAAwB,OAE9Fh0C,CACT,CAEA,SAASm0C,EAAsB99B,EAASi9B,GAEtC,OADA1zC,EAAqB4e,WAAW,kBACzBkgB,EAAoBC,uBAAuB7+B,KAAK,SAAUy9B,GAC/DlnB,EAAQ+1B,YAAY7O,eAAiBA,EAChC+V,GACHI,EAA8Br9B,EAElC,EACF,CAEA,SAAS+9B,EAAgB/9B,GACvB,OAAOvS,GAAElD,IAAIkD,GAAE7D,OAAOoW,EAAQ+1B,YAAYt7B,SAAU,CAAE/P,QAASsV,EAAQC,cAAgB,KACzF,CA4JA,MAAO,CACL+9B,iBA/pBF,SAA0BzuC,EAAayQ,GACrC,OAAOzJ,EACJoF,IAAI,CACHjE,EAAeumC,6BAA6B,OAC5C5V,EAAoBC,uBACpB5rB,EAAcC,uBAAuB,OACrCC,EAAaC,sBAAsB,OACnC2W,EAAmB0qB,kBAAkB,QA4FpBxzC,EA3FHsV,EAAQC,YA4FnB5T,GAAeC,WAAW,CAC/B5B,UACAZ,SAAU,MACVV,EAAG,OA9FDywC,EAAuBvgC,sBACvB/C,EAAe7J,QAAQe,GAAEgK,UAAUuiC,IACnCzjC,EAAe7J,QAAQe,GAAEgK,UAAUs6B,IACnC7mC,EAAqBjB,mBACrByN,EAAe4E,aAAa,SAE7B7S,KAAK,UACJywC,EACAhT,EACAzsB,EACAE,EACAxM,EACAytC,EACA7kC,EACAijC,EACAjI,EACA5nC,EACAqQ,IAEA,MAAMu7B,EAAc,CAClBmE,4BACAhT,iBACAzsB,WACAE,UACAxM,gBACAytC,YACA7kC,gBACAijC,oBAAAA,EACAjI,WAAAA,EACA5nC,eACAqQ,YAEF,IAAI2jC,EAAwB5nC,EAAe7J,QAAQ,MAC/C0xC,EAAkB7nC,EAAe7J,QAAQ,MACzC2xC,EAAsB9nC,EAAe7J,QAAQ,MAMjD,GALAqpC,EAAY3hB,SAAW,CAAA,EACvB2hB,EAAYuI,+BA4CT3E,GAAsCrU,QA3CzCtlB,EAAQ+1B,YAAcA,EACtB2F,EAAgB17B,GAEZA,EAAQknB,gBAAkBlnB,EAAQknB,eAAe94B,OAAQ,CAE3D,MAAM8qC,EAAmBzrC,GAAElD,IAAI4yC,EAAkBn9B,GAAU,MACvDvS,GAAEuqC,aAAah4B,EAAQknB,eAAgBgS,GAAkB9qC,OAAS4R,EAAQknB,eAAe94B,SAC3F+vC,EAAwBL,EAAsB99B,GAAS,GAE3D,CACA,GAAIA,EAAQhM,QAAS,CAEE+pC,EAAgB/9B,GACnBxR,SAASwR,EAAQhM,WACjCoqC,EAwcV,SAAyBp+B,GACvBtD,EAAcC,uBAAuB,OAAOlT,KAAK,SAAU80C,GACzDv+B,EAAQ+1B,YAAYt7B,SAAW8jC,CACjC,EACF,CA5c4BC,CAAgBx+B,GAEtC,CASA,GAPIA,EAAQy+B,oBACVz+B,EAAQ0+B,mBAAoB,GAG1B1+B,EAAQkvB,oBACVlvB,EAAQ2+B,mBAAoB,GAE1BlxC,GAAE0O,IAAI6D,EAAS,iCAAkC,CAEnD,MAAM7V,EAAe4xC,EAAgB/7B,GAChCvS,GAAE8L,MAAMpP,GAAcI,IAAI,YAAYiE,SAASwR,EAAQkvB,kBAAkBC,gBAAgB31B,UAC5F6kC,EAAsBrB,EAAoBh9B,GAAS,GAEvD,CAEA,OAAOzJ,EAAeoF,IAAI,CAACwiC,EAAuBC,EAAiBC,IAAsB50C,KAAK,KAmcpG,IAA6Bm1C,EAlcrB9E,EAAc1tC,SAAS4T,IAkcF4+B,EAjcD5+B,GAkctB6+B,gBAAkB,SAAyB7+B,GAC7C,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SACnCra,EAAW+V,GAAoB/V,SAgBrC,OAfIiG,EAAQgxB,UACVhxB,EAAQ/O,KAAO,KACfgpC,EAAuCj6B,IAC7BA,EAAQ/O,OACd+O,EAAQvU,SAAWsO,EAAStO,OAC9BuU,EAAQ/O,KAAO8I,EAAS9I,KAExB+O,EAAQ/O,KAAOgqC,EAAa9J,MAAM,GAGpC/lC,OAAOsO,OAAOpP,EAAO8vC,MAAOyB,EAAe77B,GAASo6B,QAGtDp6B,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OACvC9vC,CACT,EAEAs0C,EAAIE,cAAgB,SAAuB9+B,GACzC,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBa,EAAej7B,EAAQ+1B,YAAY3hB,SAezC,OAdAhpB,OAAOsO,OAAOpP,EAAO8vC,MAAO8C,EAAiBl9B,GAASo6B,OAClDp6B,EAAQvU,QACVL,OAAOsO,OAAOpP,EAAO8vC,MAAOD,EAAuBn6B,GAASo6B,OAC5DhvC,OAAOsO,OAAOpP,EAAO8vC,MAAOyB,EAAe77B,GAASo6B,OACpDhvC,OAAOsO,OAAOpP,EAAO8vC,MAAOY,EAAsBh7B,GAASo6B,OAE3DhvC,OAAOsO,OAAOpP,EAAO8vC,MAAO8B,EAA6Bl8B,GAASo6B,OAClEhvC,OAAOsO,OAAOpP,EAAO8vC,MAAOsB,EAAgB17B,GAASo6B,QAErDa,EAAa9J,MAAQ,KAGvBnxB,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OACvC9vC,CACT,EAEAs0C,EAAIG,mBAAqB,SAA4B/+B,GACnD,MAAM1V,EAAS,CAAE8vC,MAAO,IAClBrE,EAAc/1B,EAAQ+1B,YAC5B,GAAI/1B,EAAQC,YAAa,CACvB,MAAMvF,EAAUq7B,EAAYmE,0BAA0Bl6B,EAAQC,aAAavF,QACvEjN,GAAEgP,QAAQ/B,GACZq7B,EAAY3hB,SAAS1Z,QAAUjN,GAAElD,IAAImQ,EAAS,QAG9Cq7B,EAAY3hB,SAAS1Z,QAAUjN,GAAEzB,KAAK0O,GAEnCq7B,EAAY3hB,SAAS1Z,QAAQlM,SAASwR,EAAQvU,QAIjDL,OAAOsO,OAAOpP,EAAO8vC,MAAOp6B,EAAQ8+B,cAAc9+B,GAASo6B,QAH3Dp6B,EAAQvU,OAAS,KACjBnB,EAAO8vC,MAAM3uC,QAAS,GAKxBsqC,EAAY3hB,SAAS3Z,SAAWsjC,EAAgB/9B,GAC3C+1B,EAAY3hB,SAAS3Z,SAASjM,SAASwR,EAAQhM,SAIlD5I,OAAOsO,OAAOpP,EAAO8vC,MAAOp6B,EAAQg/B,eAAeh/B,GAASo6B,QAH5Dp6B,EAAQhM,QAAU,KAClB1J,EAAO8vC,MAAMpmC,SAAU,GAKzB5I,OAAOsO,OAAOpP,EAAO8vC,MAAO4B,EAAsBh8B,GAASo6B,OAC3DhvC,OAAOsO,OAAOpP,EAAO8vC,MAAOD,EAAuBn6B,GAASo6B,OAE5DH,EAAuCj6B,EACzC,MACEA,EAAQvU,OAAS,KAMnB,OAHAuU,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OAEvC9vC,CACT,EAEAs0C,EAAII,eAAiB,SAAwBh/B,GAC3C,MAAM1V,EAAS,CAAE8vC,MAAO,IAsBxB,OApBAp6B,EAAQ0uB,UAAUuQ,kBAAoBxxC,GAAE8L,MAAMyG,EAAQ+1B,YAAYt7B,UAC/D7Q,OAAO,CAAEc,QAASsV,EAAQC,YAAa5N,GAAI2N,EAAQhM,UACnDzJ,IAAI,qBACJ4hB,OACA3S,QAEHwG,EAAQ0uB,UAAU/zB,QAAUlN,GAAE8L,MAAMyG,EAAQ+1B,YAAYt7B,UACrD7Q,OAAO,CAAEc,QAASsV,EAAQC,YAAa5N,GAAI2N,EAAQhM,UACnDzJ,IAAI,WACJ4hB,OACA3S,QAEHpO,OAAOsO,OAAOpP,EAAO8vC,MAAO8C,EAAiBl9B,GAASo6B,OACtDhvC,OAAOsO,OAAOpP,EAAO8vC,MAAOiD,EAA8Br9B,GAASo6B,OAInEp6B,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OAEvC9vC,CACT,EAEAs0C,EAAIM,YAAc,SAAqBl/B,GACrC,MAAM1V,EAAS,CAAE8vC,MAAO,IASxB,YARqB,IAAjBp6B,EAAQ/O,MAAuB+O,EAAQgxB,WACzC1mC,EAAO8vC,MAAMnpC,MAAO,GAEtB+O,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OAC9ChvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAOD,EAAuBn6B,GAASo6B,OACvEhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAOY,EAAsBh7B,GAASo6B,OACtEhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAOgB,EAAsBp7B,GAASo6B,OAC/D9vC,CACT,EAEAs0C,EAAIO,mBAAqB,SAA4Bn/B,GACnD,MAAM1V,EAAS,CAAE8vC,MAAO,IAIxB,OAHAp6B,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAO9vC,EAAO8vC,OAC9ChvC,OAAOsO,OAAOsG,EAAQ0uB,UAAU0L,MAAOgB,EAAsBp7B,GAASo6B,OAC/D9vC,CACT,EAEAs0C,EAAIQ,sBAAwB,SAA+Bp/B,GACzD,MAAM1V,EAAS,CAAE8vC,MAAO,IAKxB,OAHAp6B,EAAQ0uB,UAAU0L,MAAQp6B,EAAQ0uB,UAAU0L,OAAS,CAAA,EACrDhvC,OAAOsO,OAAOpP,EAAQ0V,EAAQ0uB,UAAU0L,MAAOC,EAA6Br6B,GAASo6B,OAE9E9vC,CACT,GAxkBE,GAgBJ,IAAuBI,CAfvB,EA4kBEyvC,yBACAuB,kBACAG,iBACAqB,mBACAhB,+BACAmD,qBApRF,SAA8Br/B,EAASi9B,GACrC,OAAOzpB,EAAmB0qB,kBAAkB,OAAOz0C,KAAK,SAAU0E,GAChE6R,EAAQ+1B,YAAY5nC,cAAgBA,EAC/B8uC,GACHf,EAA6Bl8B,EAEjC,EACF,EA8QE89B,wBACAwB,qBA7JF,SAA8Bt/B,GAE5B,OADAzW,EAAqB4e,WAAW,iBACzB0xB,EAAuBvgC,sBAAsB7P,KAAK,SAAUsN,GACjEiJ,EAAQ+1B,YAAYh/B,cAAgBA,EACpCojC,EAAuBn6B,EACzB,EACF,EAwJEg9B,sBAEJ,EC7tBK,SAASuC,GACd36B,EACA46B,EACAC,EACAC,GAEA,MAAMv6B,EAAaP,EAAQra,IAAKiP,KAAaA,QAAOmmC,YAAY,KAIhE,OAHIH,IAAmB56B,EAAQ7W,KAAMsY,GAAWo5B,EAASp5B,KAAYm5B,IACnEr6B,EAAWpV,KAAK,CAAEyJ,MAAOkmC,EAAaF,GAAiBG,YAAY,IAE9Dx6B,CACT,CAEO,SAASy6B,GAA8B5/B,GA1B9C,IAAA9R,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAAA4Y,EAAAC,EAAAC,EA2BE,MAAMt8B,EAAiD,CAAA,EAsBvD,OArBK,OAAAvV,EAAA8R,EAAQzQ,oBAARrB,EAAqByV,UACxBF,EAAOlU,YAAc,0BAElB,OAAAiD,EAAAwN,EAAQC,oBAARzN,EAAqBmR,UACxBF,EAAOxD,YAAc,sBAElB,OAAA1M,EAAAyM,EAAQvU,eAAR8H,EAAgBoQ,UACnBF,EAAOhY,OAAS,oBAEbuU,EAAQgxB,WAAa,OAAAx9B,EAAAwM,EAAQ/O,eAAM0S,UACtCF,EAAOxS,KAAO,kBAEZ+O,EAAQgxB,UAAYhxB,EAAQixB,eAAgB,OAAAhK,EAAA,WAAQiK,yBAAR,EAAAxsB,EAA4BysB,cAA5BlK,EAAmC74B,UACjFqV,EAAOytB,mBAAqB,CAAEC,MAAO,gCAElCnxB,EAAQ0uB,UAAU2G,wBAA0B,OAAAwK,EAAA7/B,EAAQikB,gBAAOtgB,UAC9DF,EAAOwgB,MAAQ,mBAEiB,QAA9B,OAAA6b,EAAA9/B,EAAQyf,eAAR,EAAAqgB,EAAkBngB,oBAAoB,OAAAogB,EAAA//B,EAAQyf,eAAR,EAAAsgB,EAAkBpgB,WAC1Dlc,EAAOgc,SAAW,CAAEE,QAAS,+BAExBlc,CACT,wFD5Bam2B,GACJ,kCAA8B,GENvC,MAAMoG,GAA0D,CAAE5F,MAAO,IAElE,MAAM6F,GACJ,WAAAj1C,CACGk1C,EACAC,GADAj2C,KAAAg2C,eAAAA,EACAh2C,KAAAi2C,qBAAAA,CACP,CAEI,0BAAAxP,CACLphC,EACAwK,GAEA,OAAO7P,KAAKg2C,eAAevP,2BAA2BphC,EAAawK,EACrE,CAEO,qCAAA84B,CACLC,EACAtY,GAEA,OAAOtwB,KAAKg2C,eAAerN,sCAAsCC,EAActY,EACjF,CAEO,mCAAAwY,CACLzjC,EACAqB,EACAgN,GAEA,OAAO1T,KAAKg2C,eAAelN,oCAAoCzjC,EAAaqB,EAAagN,EAC3F,CAEO,mCAAAm3B,CACLxlC,EACAylC,EACAlC,EACAtY,GAEA,OAAOtwB,KAAKg2C,eAAenL,oCACzBxlC,EACAylC,EACAlC,EACAtY,EAEJ,CAEA,sBAAawjB,CACXzuC,EACAyQ,GAEA,MAAMogC,EAAc3oC,GAAUuI,GAE9B,aADM9V,KAAKi2C,qBAAqBnC,iBAAiBzuC,EAAa6wC,GACvDA,CACT,CAEO,mBAAAC,CACLrgC,EACAsgC,GAEA,OAAOp2C,KAAKq2C,YAAYvgC,EAAUogC,IA1EtC,IAAAlyC,EA0EsD,OAAA,OAAAA,EAAAkyC,EAAYE,SAAZ,EAAApyC,EAAAga,KAAAk4B,EAAuBA,IAC3E,CAEO,wBAAAI,CACLxgC,EACAygC,GAEA,OAAOv2C,KAAKq2C,YAAYvgC,EAAUogC,GAAgBl2C,KAAKi2C,qBAAqBM,GAAQL,GACtF,CAEO,yBAAAM,CACL1gC,EACAygC,EACAxD,GAEA,OAAO/yC,KAAKq2C,YAAYvgC,EAASmT,MAAOitB,IACvB,yBAAXK,QACIv2C,KAAKi2C,qBAAqBb,qBAAqBc,SAE/Cl2C,KAAKi2C,qBAAqBM,GAAQL,EAAanD,GAEhD+C,IAEX,CAEA,iBAAcO,CACZvgC,EACAsF,GArGJ,IAAApX,EAyGI,MAAMkyC,EAAc3oC,GAAUuI,GACxB1V,QAAgBgb,EAAO86B,IAAiBJ,GAM9C,OALAI,EAAY1R,UAAY,IACnB0R,EAAY1R,UACf0L,MAAO,IAAKgG,EAAY1R,UAAU0L,SAAU9vC,EAAO8vC,QAErD,OAAAlsC,EAAAkyC,EAAYO,6BAAZzyC,EAAAga,KAAAk4B,EAAyC91C,GAClC,CAAE0V,QAASogC,EAAa91C,SACjC,EClGK,SAASs2C,GACd5gC,GAEA,MAAO,CAAEA,UAAS6gC,aAAc,CAAA,EAAIC,aAAc9gC,EAAS+gC,kBAAmB,EAChF,CAEO,MAAeC,WAGZr0C,GAAMC,UAHT,WAAA5B,GAAAyjB,SAAA8C,WAKLrnB,KAAiB+2C,aACf/2C,KAAKsH,MAAMyvC,cAAgBL,GAAuC12C,KAAKsH,MAAM0vC,OAAOvhC,QAEtFzV,KAAQ62C,kBAAoB,EAC5B72C,KAAQ2d,aAAc,CAAA,CAEtB,WAAcs5B,GACZ,IAAKj3C,KAAKsH,MAAM2vC,QACd,MAAM,IAAIjW,MAAM,8EAElB,OAAOhhC,KAAKsH,MAAM2vC,OACpB,CAEO,QAAAC,CAASC,GACd,MAAO,CAAA,CACT,CAEO,oBAAApyB,GACL/kB,KAAK2d,aAAc,EACnB3d,KAAK62C,mBACP,CAEU,gBAAA/C,GACR,OAAO9zC,KAAKo3C,wBAAwBp3C,KAAKsH,MAAM0vC,OAAOvhC,OAASK,GAC7D9V,KAAKi3C,QAAQnD,iBAAiB9zC,KAAKsH,MAAMvD,IAAK+R,GAElD,CAEU,mBAAAqgC,CAAoBC,GAC5B,OAAOp2C,KAAKo3C,wBAAwBp3C,KAAKsH,MAAM0vC,OAAOvhC,OAAQwT,MAAOnT,UAC9C9V,KAAKi3C,QAAQd,oBAAoBrgC,EAASsgC,IACjDtgC,QAElB,CAEU,wBAAAwgC,CACRC,GAEA,OAAOv2C,KAAKo3C,wBAAwBp3C,KAAKsH,MAAM0vC,OAAOvhC,OAAQwT,MAAOnT,UAC9C9V,KAAKi3C,QAAQX,yBAAyBxgC,EAASygC,IACtDzgC,QAElB,CAEU,yBAAA0gC,CACRD,EACAxD,GAEA,OAAO/yC,KAAKo3C,wBAAwBp3C,KAAKsH,MAAM0vC,OAAOvhC,OAAQwT,MAAOnT,UAC9C9V,KAAKi3C,QAAQT,0BAA0B1gC,EAASygC,EAAQxD,IAC/Dj9B,QAElB,CAEA,6BAAgBshC,CACdC,EACAC,GAlFJ,IAAAtzC,EAAAsE,EAAAe,EAAAC,EAoFI,MAAMiuC,IAAmBv3C,KAAK62C,kBAC9B72C,KAAKw3C,mBACL,MAAMC,IAAsBz3C,KAAK+2C,aAAaF,kBACxCa,EAAiBC,GACrB33C,KAAKsH,MAAM0vC,OAAOvhC,OAClB4hC,EACAr3C,KAAK+2C,aAAajhC,QAClB9V,KAAK+2C,aAAaJ,aAClB,CAAEiB,WAAYH,EAAmB56B,OAAQ,SACzC,GAEF7c,KAAK+2C,aAAajhC,QAAU4hC,EAC5B,OAAApvC,GAAAtE,EAAAhE,KAAKsH,OAAMuwC,mBAAXvvC,EAAA0V,KAAAha,GAA8B,GAC9B,IACE,MAAM8R,QAAgBwhC,EAAQI,GAC9B,GAAI13C,KAAK2d,YACP,OAEF3d,KAAKw3C,mBACL,MAAMM,EAAiB93C,KAAK+2C,aAAajhC,QACnCiiC,EAAgBJ,GACpBD,EACA5hC,EACAgiC,EACA93C,KAAK+2C,aAAaJ,aAClB,CAAEiB,WAAYH,EAAmB56B,OAAQ,WAM3C,OAJK6E,GAAQq2B,EAAeD,IAAmBL,IAAsBz3C,KAAK+2C,aAAaF,oBACrF72C,KAAK+2C,aAAajhC,QAAUiiC,EAC5B/3C,KAAKsH,MAAM0vC,OAAOgB,UAAUD,IAEvBA,CACT,CAAA,QACO/3C,KAAK2d,aAAe45B,IAAmBv3C,KAAK62C,mBAC/C,OAAAvtC,GAAAD,EAAArJ,KAAKsH,OAAMuwC,mBAAXvuC,EAAA0U,KAAA3U,GAA8B,EAElC,CACF,CAEQ,gBAAAmuC,GACN,MAAMZ,aAAEA,GAAiB52C,KAAK+2C,aAC1BH,IAAiB52C,KAAKsH,MAAM0vC,OAAOvhC,SAGvCzV,KAAK+2C,aAAajhC,QAAU6hC,GAC1Bf,EACA52C,KAAKsH,MAAM0vC,OAAOvhC,OAClBzV,KAAK+2C,aAAajhC,QAClB9V,KAAK+2C,aAAaJ,aAClB,CAAEiB,WAAY53C,KAAK+2C,aAAaF,kBAAmBh6B,OAAQ,SAE7D7c,KAAK+2C,aAAaH,aAAe52C,KAAKsH,MAAM0vC,OAAOvhC,OACrD,EAGF,SAASkiC,GACPM,EACAC,EACA/6B,EACAw5B,EACAwB,EACAC,GAAsB,GAEtB,OAAOC,GACLJ,EACAC,EACA/6B,EACAw5B,EACAwB,EACA,GACAC,EAEJ,CAEA,SAASC,GACPJ,EACAC,EACA/6B,EACAw5B,EACAwB,EACArmB,EACAsmB,GAEA,GAAI12B,GAAQw2B,EAASD,GACnB,OAAO96B,EAET,GAAIuE,GAAQw2B,EAAS/6B,GAInB,OAHIi7B,GACFE,GAAqBL,EAAMC,EAASvB,EAAcwB,EAAgBrmB,GAE7D3U,EAGT,GACEo7B,GAAcL,KACbK,GAAcN,SAAkB,IAATA,KACvBM,GAAcp7B,SAAwB,IAAZA,GAC3B,CACA,MAAMq7B,EAAaP,GAAQ,CAAA,EACrBQ,EAAgBt7B,GAAW,CAAA,EAC3B/c,EAAS,IAAKq4C,GAuBpB,OAtBA,IAAI1nC,IAAI,IAAI7P,OAAOY,KAAK02C,MAAgBt3C,OAAOY,KAAKo2C,KAAWn2C,QAASC,IACtE,MAAM02C,EAAY,IAAI5mB,EAAM9vB,GACvBd,OAAOwlB,UAAUC,eAAe3I,KAAKk6B,EAASl2C,GAUnD5B,EAAO4B,GAAOq2C,GACZG,EAAWx2C,GACXk2C,EAAQl2C,GACRy2C,EAAcz2C,GACd20C,EACAwB,EACAO,EACAN,IAfE12B,GAAQ+2B,EAAcz2C,GAAMw2C,EAAWx2C,KACvC22C,GAAqBhC,EAAcwB,EAAgBO,aAE5Ct4C,EAAO4B,GACd42C,GAAkBjC,EAAcwB,EAAgBO,MAc/Ct4C,CACT,CAEA,OAAIshB,GAAQvE,EAAS86B,IAASU,GAAqBhC,EAAcwB,EAAgBrmB,IAC/E8mB,GAAkBjC,EAAcwB,EAAgBrmB,GACzComB,GAEF/6B,CACT,CAEA,SAASw7B,GACPhC,EACAwB,EACArmB,GAEA,GAA8B,SAA1BqmB,EAAet7B,OACjB,OAAO,EAET,MAAMg8B,EAIR,SACElC,EACA7kB,GAEA,IAAA,IAAS5tB,EAAS4tB,EAAK5tB,OAAQA,GAAU,EAAGA,IAAU,CACpD,MAAM40C,EAASnC,EAAaoC,GAAejnB,EAAKsJ,MAAM,EAAGl3B,KACzD,GAAI40C,EACF,OAAOA,CAEX,CACA,MACF,CAfwBE,CAAgBrC,EAAc7kB,GACpD,MAAiC,YAA1B,MAAA+mB,OAAA,EAAAA,EAAeh8B,SAAuBs7B,EAAeP,WAAaiB,EAAcjB,UACzF,CAeA,SAASU,GACPL,EACAC,EACAvB,EACAwB,EACArmB,GAEA,IAAIpQ,GAAQu2B,EAAMC,GAAlB,CAGA,GAAIK,GAAcL,KAAaK,GAAcN,SAAkB,IAATA,GAAqB,CACzE,MAAMO,EAAaP,GAAQ,CAAA,EAS3B,YARA,IAAIlnC,IAAI,IAAI7P,OAAOY,KAAK02C,MAAgBt3C,OAAOY,KAAKo2C,KAAWn2C,QAASC,IACtE,MAAM02C,EAAY,IAAI5mB,EAAM9vB,GACvBd,OAAOwlB,UAAUC,eAAe3I,KAAKk6B,EAASl2C,GAInDs2C,GAAqBE,EAAWx2C,GAAMk2C,EAAQl2C,GAAM20C,EAAcwB,EAAgBO,GAHhFE,GAAkBjC,EAAcwB,EAAgBO,IAMtD,CACAE,GAAkBjC,EAAcwB,EAAgBrmB,EAbhD,CAcF,CAEA,SAAS8mB,GACPjC,EACAwB,EACArmB,GAEA,MAAM9vB,EAAM+2C,GAAejnB,GACrBmnB,EAAmB,GAAGj3C,MAC5Bd,OAAOY,KAAK60C,GAAc50C,QAASm3C,IAC7BA,EAAU3qC,WAAW0qC,WAChBtC,EAAauC,KAGxBvC,EAAa30C,GAAOm2C,CACtB,CAEA,SAASY,GAAejnB,GACtB,OAAOA,EAAKpsB,KAAK,KACnB,CCrRA,SAASyzC,GAA0Bz+B,EAAmB46B,GACpD,OAAOhjC,MAAMkD,KAAK,IAAIzE,IAAI,IAAI2J,EAAS46B,GAAgB51C,OAAOsY,UAChE,CAEA,SAASohC,GAAY/4C,EAA+B,IAClD,OAAOa,OAAOY,KAAKzB,GAAKwD,KAAM7B,IAASA,EAAIyX,OAC7C,CAEA,SAAS4/B,GAAch5C,EAA+B,IACpD,OAAOa,OAAOuU,OAAOpV,GAAKwD,KAAMyL,GAA2B,iBAAVA,IAAuBA,EAAMmK,OAChF,CAEA,SAAS6/B,GAAe7jC,GACtB,MAAiC,mBAA1BA,EAAO+uB,UAAU9wB,MAAuD,iBAA1B+B,EAAO+uB,UAAU9wB,IACxE,CAEA,SAAS6lC,GAAajqC,GACpB,MAAwB,iBAAVA,GAAsB,mBAAmBkU,KAAKlU,EAC9D,CAEA,SAASkqC,GAAyBlqC,GAChC,OAAOiqC,GAAajqC,GAASA,EAAQ6G,OAAO7G,EAC9C,CAEA,SAASmqC,GACPnqC,EACA+T,EACA5N,EACA6N,EAAUnN,OAAOujC,kBAEjB,GAAIJ,GAAe7jC,IAAW8jC,GAAajqC,GACzC,OAAO,EAET,MAAMqqC,EAAexjC,OAAO7G,GAC5B,OACE6G,OAAO4D,SAAS4/B,IAChBxjC,OAAOiG,UAAUu9B,IACjBA,GAAgBt2B,GAChBs2B,GAAgBr2B,CAEpB,CAeA,SAASs2B,GAAankC,GACpB,OAAQA,EAAOxJ,OAAS,IAAIvM,OAAQwO,GAA4B,cAAdA,EAAK/O,KACzD,CAEA,SAASklC,GAAmB5uB,GAC1B,OAAQA,EAAOxJ,OAAS,IAAIvM,OAAQwO,GAA4B,cAAdA,EAAK/O,KACzD,CAEA,SAAS06C,GAAsB7qC,EAAe7G,GAC5C,OACE6G,oBACG,OAAA,CAAKjE,UAAU,aAAa5C,KAAQ4f,KAAK,SACvC/Y,EAIT,CAEO,MAAM8qC,WAAyBhD,GAA/B,WAAAh2C,GAAAyjB,SAAA8C,WAgCLrnB,KAAQ+5C,SAAW,CAACjiC,EAAexI,KACjCtP,KAAKsH,MAAM0vC,OAAOgD,cAAcliC,EAAOxI,IAGzCtP,KAAQi6C,WAAa,CAACtkC,EAAeqZ,KACnC,MAAMvZ,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BnH,EAAkB+1B,GAAmB5uB,GAC3CzV,KAAK+5C,SACH,QACAzrC,EACGjO,IAAI,CAAC6N,EAAWgsC,IAAuBA,IAAcvkC,EAAQ,IAAKzH,KAAS8gB,GAAY9gB,GACvF0b,OAAOgwB,GAAankC,MAI3BzV,KAAQm6C,WAAcxkC,IACpB,MAAMF,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OACjCzV,KAAK+5C,SACH,QACA1V,GAAmB5uB,GAChB/V,OAAO,CAAC06C,EAAYF,IAAsBA,IAAcvkC,GACxDiU,OAAOgwB,GAAankC,MAI3BzV,KAAQq6C,oBAAuBhsC,IAC7B,MAAMoH,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B6kC,EAAYV,GAAankC,GAAQ2lB,MAAM,EAAG/sB,GAChD,KAAOisC,EAAUp2C,OAASmK,GACxBisC,EAAUz0C,KAAK,CAAE1G,KAAM,YAAa+M,OAAQ,MAE9ClM,KAAK+5C,SAAS,QAAS1V,GAAmB5uB,GAAQmU,OAAO0wB,KAG3Dt6C,KAAQu6C,kBAAoB,CAAC5kC,EAAeqZ,KAC1C,MAAMwrB,EAAex6C,KAAKsH,MAAM0vC,OAAOvhC,OAAO47B,oBAAsB,GACpErxC,KAAK+5C,SACH,qBACAS,EAAan6C,IAAI,CAACmsC,EAAkBiO,IAClCA,IAAqB9kC,EAAQ,IAAK62B,KAAgBxd,GAAYwd,KAKpExsC,KAAQ06C,kBAAqB/kC,IAC3B3V,KAAK+5C,SACH,sBACC/5C,KAAKsH,MAAM0vC,OAAOvhC,OAAO47B,oBAAsB,IAAI3xC,OAClD,CAACi7C,EAAmBF,IAA6BA,IAAqB9kC,KAK5E3V,KAAQ46C,UAAY,CAACjlC,EAAerG,KAClC,MAAMkqB,EAAOx5B,KAAKsH,MAAM0vC,OAAOvhC,OAAO+jB,MAAQ,GAC9Cx5B,KAAK+5C,SACH,OACAvgB,EAAKn5B,IAAI,CAACgmC,EAAUwU,IAClBA,IAAallC,EAAwB,iBAAR0wB,EAAmB/2B,EAAQ,IAAK+2B,EAAK/2B,SAAW+2B,KAKnFrmC,KAAQ+uC,UAAap5B,IACnB3V,KAAK+5C,SACH,QACC/5C,KAAKsH,MAAM0vC,OAAOvhC,OAAO+jB,MAAQ,IAAI95B,OAAO,CAACo7C,EAAWD,IAAqBA,IAAallC,KAI/F3V,KAAQ+6C,gBAAmBplC,IACzB3V,KAAK+5C,SACH,cACC/5C,KAAKsH,MAAM0vC,OAAOvhC,OAAOoyB,YAAc,IAAInoC,OAAO,CAACs7C,EAAgBC,IAAuBA,IAAetlC,KAI9G3V,KAAQk7C,eAAkBzT,IACxBznC,KAAK+5C,SAAS,cAAetS,GAC7BznC,KAAK+5C,SAAS,oBAAqBtS,GACnCznC,KAAK+5C,SAAS,oBAAqBtS,EAAc,YAAc,WACjE,CAhHO,QAAAyP,CAASzhC,GACd,MAAM8D,EAAoC,CAAA,EA2B1C,OA1BI8qB,GAAmB5uB,GAAQ5R,KAAMqK,IAAeA,EAAK/O,OAASs6C,GAAevrC,EAAKhC,OAAQ,GAAIuJ,EAAQ,UACxG8D,EAAOtN,MAAQ,uFAEZwJ,EAAO47B,oBAAsB,IAAIxtC,KAAM2oC,IArChD,SAA4BA,EAAkB/2B,GAjD9C,IAAAzR,EAkDE,IAAKwoC,EAAY+E,kBAAoBkI,GAAejN,EAAY2O,iBAAkB,EAAG1lC,GACnF,OAAO,EAET,GAAI6jC,GAAe7jC,IAAW8jC,GAAa/M,EAAY2O,kBACrD,OAAO,EAET,MAAMrpC,IAAa,OAAA9N,EAAAyR,EAAO+uB,kBAAPxgC,EAAkBmtC,mBAAoB,IAAI1oC,KAC1DC,GAAmBA,EAAU9H,OAAS4rC,EAAY+E,iBAErD,OAAOz/B,GAAYA,EAAUw6B,oBAAoBhoC,SAAS6R,OAAOq2B,EAAY2O,kBAC/E,CA0BsEC,CAAmB5O,EAAa/2B,MAChG8D,EAAO83B,mBAAqB,6EAE1B+H,GAAY3jC,EAAOqwB,oBACrBvsB,EAAOusB,iBAAmB,mCAExBsT,GAAY3jC,EAAOuwB,SAAWqT,GAAc5jC,EAAOuwB,WACrDzsB,EAAOysB,OAASoT,GAAY3jC,EAAOuwB,QAAU,8BAAgC,kCAE3EoT,GAAY3jC,EAAO+wB,sBAAwB6S,GAAc5jC,EAAO+wB,wBAClEjtB,EAAOitB,oBAAsB4S,GAAY3jC,EAAO+wB,qBAC5C,6CACA,iDAED/wB,EAAO+jB,MAAQ,IAAI31B,KAAMwiC,IApGlC,IAAAriC,EAoG+C,QAAE,OAAAA,EAAe,iBAARqiC,EAAmBA,EAAMA,EAAI/2B,YAApC,EAAAtL,EAA4CyV,YACvFF,EAAOigB,KAAO,kCAEX/jB,EAAOoyB,YAAc,IAAIhkC,KAAMw3C,IAAmBA,EAAM5hC,UAC3DF,EAAOsuB,WAAa,gCAElBpyB,EAAO6lC,2BAA6B,6BAA8B7lC,IAAWA,EAAO8lC,2BACtFhiC,EAAOgiC,yBAA2B,wCAE7BhiC,CACT,CAqFQ,aAAAiiC,CAAc11C,EAAegS,EAAexI,GAClD,MAAMnH,EAAK2P,EAAMtN,QAAQ,WAAY,OAAOiyB,cAC5C,wBACG,MAAA,CAAI1xB,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAGpB,IAENrD,GAAAyE,cAAC,OAAI6D,UAAU,mCACZ,QAAA,KACCtI,GAAAyE,cAAC,QAAA,CACCmZ,SAAmB,IAAV/Q,EACT,cAAa,GAAGnH,QAChBvH,KAAMkX,EACNyC,SAAU,IAAMva,KAAK+5C,SAASjiC,GAAO,GACrC3Y,KAAK,UACJ,IAAI,yBAIV,MAAA,CAAI4L,UAAU,kBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,SAAmB,IAAV/Q,EACT,cAAa,GAAGnH,OAChBvH,KAAMkX,EACNyC,SAAU,IAAMva,KAAK+5C,SAASjiC,GAAO,GACrC3Y,KAAK,UACJ,IAAI,OAMjB,CAEO,MAAA6lB,GAtOT,IAAAhhB,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAAA4Y,EAAAC,EAuOI,MAAMngC,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxBz9B,EAASvZ,KAAKk3C,SAASzhC,GACvBxJ,EAAQo4B,GAAmB5uB,GAC3B6kC,EAAYV,GAAankC,GACzB+kC,EAAe/kC,EAAO47B,oBAAsB,GAC5CF,GAAmB,OAAAntC,EAAAyR,EAAO+uB,gBAAP,EAAAxgC,EAAkBmtC,mBAAoB,GACzD3X,EAAO/jB,EAAO+jB,MAAQ,GACtBqO,EAAapyB,EAAOoyB,YAAc,GAClCoJ,EAAekI,IACnB,OAAA9vC,EAAA,WAAOwiC,kBAAP,EAAAvjC,EAAoB4hB,eAApB,EAAA7gB,EAA8B4nC,eAAgB,GAC9Cx7B,EAAO2xB,gBAEHqU,EAAgC,8BAA+BhmC,GAAU,6BAA8BA,EACvGimC,EAAepC,GAAe7jC,GAEpC,OACEhT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,kCAAkC,cAAY,8BAC3DtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,wBACnBtI,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,oCAErC1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,uBACZwP,SAAWwB,GAAU/b,KAAK+5C,SAAS,iBAAkBh+B,EAAMlQ,OAAOyD,OAClEA,MAAOmG,EAAO2xB,gBAAkB,IAE/B6J,EAAa5wC,IAAKu7C,GACjBn5C,GAAAyE,cAAC,SAAA,CAAOlF,IAAK45C,EAAUtsC,MAAOssC,GAC3BA,OAOXn5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iBACbtI,GAAAyE,cAAC,IAAA,KAAE,YAELzE,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,yBAAyB8wC,QAAQ,uBAAsB,6BAGxEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAOtN,MAAQ,gCAA6B,EAC9D,eAAc+L,QAAQuB,EAAOtN,OAC7BlB,UAAU,wBACV,cAAY,kBACZuP,UAAgF,KAAtE,OAAAyiB,EAAA,SAAA,WAAOyH,gBAAP,EAAAl7B,EAAkBi7B,0BAAlB,EAAA/pB,EAAuCtN,kBAASC,mBAC1DhF,GAAG,sBACHwG,IAAK,EACLkL,IAAK,EACLU,SAAWwB,GAAU/b,KAAKq6C,oBAAoBlkC,OAAO4F,EAAMlQ,OAAOyD,QAClEnQ,KAAK,SACLmQ,MAAOgrC,EAAUp2C,WAIvBzB,GAAAyE,cAAC,OAAI6D,UAAU,+BACZ,MAAA,CAAIA,UAAU,iBACbtI,GAAAyE,cAAC,IAAA,KAAE,sCAEJ,QAAA,CAAM6D,UAAU,qCACftI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,UACCzE,GAAAyE,cAAC,KAAA,KAAG,QACJzE,GAAAyE,cAAC,UAAG,aACJzE,GAAAyE,cAAC,KAAA,KAAG,iCACH,KAAA,QAGLzE,GAAAyE,cAAC,aACE+E,EAAM5L,IAAI,CAAC6N,EAAWyH,KAjTrC,IAAA3R,EAAAsE,EAkTgB,MAAMwzC,EAAY3C,IAA0B,OAAAn1C,EAAAyR,EAAOo2B,kBAAP,EAAA7nC,EAAoB8rC,sBAAuB,GAAI5hC,EAAK/O,MAChG,OACEsD,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,oBACN,KAAA,KACClT,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAOtN,MAAQ,gCAA6B,EAC9D,eAAc+L,QAAQuB,EAAOtN,OAC7B,aAAY,aAAa0J,EAAQ,IACjC5K,UAAU,wBACV,cAAa,aAAa4K,IAC1B4E,SAAWwB,GAAU/b,KAAKi6C,WAAWtkC,EAAO,CAAExW,KAAM4c,EAAMlQ,OAAOyD,QACjEuQ,UAAU,EACVvQ,MAAOpB,EAAK/O,MAAQ,IAEnB28C,EAAUz7C,IAAKlB,GACdsD,GAAAyE,cAAC,SAAA,CAAOlF,IAAK7C,EAAMmQ,MAAOnQ,GACvBA,MAKTsD,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAOtN,MAAQ,gCAA6B,EAC9D,eAAc+L,QAAQuB,EAAOtN,OAC7B,aAAY,aAAa0J,EAAQ,IACjC5K,UAAU,wBACV,cAAa,aAAa4K,IAC1BhH,IAAK+sC,OAAe,EAAY,MAChC7hC,IAAK6hC,OAAe,EAAY,GAChCnhC,SAAWwB,GACT/b,KAAKi6C,WAAWtkC,EAAO,CAAEzJ,OAAQstC,GAAyBz9B,EAAMlQ,OAAOyD,SAEzEuQ,UAAU,EACV1gB,KAAMu8C,EAAe,OAAS,SAC9BpsC,MAAO,OAAAhH,EAAA4F,EAAKhC,QAAL5D,EAAe,MAG1B7F,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,QAAA,CACC,aAAY,qBAAqByO,EAAQ,IACzC5K,UAAU,wBACVwP,SAAWwB,GAAU/b,KAAKi6C,WAAWtkC,EAAO,CAAE+0B,YAAa3uB,EAAMlQ,OAAOyD,YAAS,IACjFnQ,KAAK,OACLmQ,MAAOpB,EAAKw8B,aAAe,MAG/BjoC,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,SAAA,CACC,aAAY,eAAeyO,EAAQ,IACnC5K,UAAU,eACV,cAAa,eAAe4K,IAC5BiJ,QAAS,IAAM5e,KAAKm6C,WAAWxkC,GAC/BxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,oCAO5BtI,GAAAyE,cAAC,QAAA,sBACE,KAAA,KACCzE,GAAAyE,cAAC,KAAA,CAAG60C,QAAS,GACXt5C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,+BACV,cAAY,WACZ6T,QAAS,IAAM5e,KAAK+5C,SAAS,QAAS,IAAI9tC,EAAO,CAAE9M,KAAM,SAAU+M,OAAQ,OAASouC,IACpFn7C,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,kCAAkC,iBAM3D8uC,GAAsBtgC,EAAOtN,MAAO,8BAGrCuuC,EAAat2C,OAAS,GAAKitC,EAAiBjtC,OAAS,IACrDzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iBACbtI,GAAAyE,cAAC,IAAA,KAAE,gBAAgB,IAACzE,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,iCAEpC1F,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,qCACftI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,UAAG,QACJzE,GAAAyE,cAAC,KAAA,KAAG,SACJzE,GAAAyE,cAAC,KAAA,QAGLzE,GAAAyE,cAAC,QAAA,KACEszC,EAAan6C,IAAI,CAACmsC,EAAkB72B,KAhZrD,IAAA3R,EAAAsE,EAAAe,EAiZkB,MAAM2yC,EAAe7K,EAAiB1oC,KAAMtJ,GAAcA,EAAKyB,OAAS4rC,EAAY+E,iBAC9E0K,EAAY9C,GAChBhI,EAAiB9wC,IAAKlB,GAAcA,EAAKyB,MACzC4rC,EAAY+E,iBAER2K,EAAS5pC,MAAMkD,KACnB,IAAIzE,IACF,KAAK,MAAAirC,OAAA,EAAAA,EAAc1P,sBAAuB,GAAKE,EAAY2O,kBAAkBz7C,OAAOsY,WAGxF,OACEvV,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,oBACN,KAAA,KACClT,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,uCAAoC,EAClF,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,oBAAoB17B,EAAQ,IACxC5K,UAAU,wBACV,cAAa,oBAAoB4K,IACjC4E,SAAWwB,GAAU/b,KAAKu6C,kBAAkB5kC,EAAO,CAAE47B,gBAAiBx1B,EAAMlQ,OAAOyD,QACnFuQ,UAAU,EACVvQ,MAAOk9B,EAAY+E,iBAAmB,IAErC0K,EAAU57C,IAAKlB,IAxa1C,IAAA6E,EAya4B,OAAAvB,GAAAyE,cAAC,UAAOlF,IAAK7C,EAAMmQ,MAAOnQ,IACvB,OAAA6E,EAAAmtC,EAAiB1oC,KAAMC,GAAmBA,EAAU9H,OAASzB,WAA7D6E,EAAoE0I,cAAevN,OAK5FsD,GAAAyE,cAAC,KAAA,KACEw0C,EACCj5C,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,uCAAoC,EAClF,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,qBAAqB17B,EAAQ,IACzC5K,UAAU,wBACV,cAAa,qBAAqB4K,IAClC4E,SAAWwB,GACT/b,KAAKu6C,kBAAkB5kC,EAAO,CAC5BwlC,iBAAkB3B,GAAyBz9B,EAAMlQ,OAAOyD,SAG5DuQ,UAAU,EACV1gB,KAAK,OACLmQ,MAAO,OAAAtL,EAAAwoC,EAAY2O,kBAAZn3C,EAAgC,KAEvCk4C,EAAOh4C,OACTzB,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,uCAAoC,EAClF,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,qBAAqB17B,EAAQ,IACzC5K,UAAU,wBACV,cAAa,qBAAqB4K,IAClC4E,SAAWwB,GACT/b,KAAKu6C,kBAAkB5kC,EAAO,CAC5BwlC,iBAAkB3B,GAAyBz9B,EAAMlQ,OAAOyD,SAG5DuQ,UAAU,EACVvQ,MAAO,OAAAhH,EAAAkkC,EAAY2O,kBAAZ7yC,EAAgC,IAEtC4zC,EAAO77C,IAAKgO,GACX5L,GAAAyE,cAAC,SAAA,CAAOlF,IAAKqM,EAAOiB,MAAOjB,GACxBA,KAKP5L,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,uCAAoC,EAClF,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,qBAAqB17B,EAAQ,IACzC5K,UAAU,wBACV,cAAa,qBAAqB4K,IAClCkE,IAAK,EACLU,SAAWwB,GACT/b,KAAKu6C,kBAAkB5kC,EAAO,CAC5BwlC,iBAAkB3B,GAAyBz9B,EAAMlQ,OAAOyD,SAG5DuQ,UAAU,EACV1gB,KAAK,SACLmQ,MAAO,OAAAjG,EAAAmjC,EAAY2O,kBAAZ9xC,EAAgC,MAI7C5G,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,SAAA,CACC,aAAY,sBAAsByO,EAAQ,IAC1C5K,UAAU,eACV,cAAa,sBAAsB4K,IACnCiJ,QAAS,IAAM5e,KAAK06C,kBAAkB/kC,GACtCxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,oCAO5BtI,GAAAyE,cAAC,QAAA,sBACE,KAAA,KACCzE,GAAAyE,cAAC,KAAA,CAAG60C,QAAS,GACXt5C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,+BACV,cAAY,kBACZuP,UAAW62B,EAAiBjtC,OAC5B0a,QAAS,KA9f/B,IAAA5a,EA+fwB,MAAM7E,EAAOgyC,EAAiB,GAC9BnxC,KAAK+5C,SAAS,qBAAsB,IAC/BS,EACH,CAAEjJ,gBAAiBpyC,EAAKyB,KAAMu6C,kBAAkB,OAAAn3C,EAAA7E,EAAKmtC,0BAAL,EAAAtoC,EAA2B,KAAM,MAGrF7E,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,kCAAkC,wBAM3D8uC,GAAsBtgC,EAAO83B,mBAAoB,oCAItD5uC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,gBAAgB8wC,QAAQ,iBAAgB,aAC7Cp5C,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,8BAE1B1F,GAAAyE,cAAC,WAAA,CACC6D,UAAU,eACV5C,GAAG,gBACHoS,SAAWwB,GAAU/b,KAAK+5C,SAAS,WAAYh+B,EAAMlQ,OAAOyD,OAC5D6sC,KAAM,EACN7sC,MAAOmG,EAAOowB,UAAY,MAI9BpjC,GAAAyE,cAAC,MAAA,CACC,mBAAkBqS,EAAOusB,iBAAmB,4CAAyC,EACrF,eAAc9tB,QAAQuB,EAAOusB,kBAC7B,aAAW,kBACX/6B,UAAU,aACVgd,KAAK,SAELtlB,GAAAyE,cAAC+pB,EAAA,CACCmrB,eAAe,mBACflrB,YAAY,EACZmrB,SAAS,eACTv2C,MAAM,kBACNqrB,MAAO1b,EAAOqwB,kBAAoB,CAAA,EAClCvrB,SAAW4W,GAAUnxB,KAAK+5C,SAAS,mBAAoB5oB,GACvDmrB,WAAW,mBAEZzC,GAAsBtgC,EAAOusB,iBAAkB,yCAElDrjC,GAAAyE,cAAC,MAAA,CACC,mBAAkBqS,EAAOysB,OAAS,iCAA8B,EAChE,eAAchuB,QAAQuB,EAAOysB,QAC7B,aAAW,SACXj7B,UAAU,aACVgd,KAAK,SAELtlB,GAAAyE,cAAC+pB,EAAA,CACCmrB,eAAe,gBACflrB,YAAY,EACZmrB,SAAS,YACTv2C,MAAM,SACNqrB,MAAO1b,EAAOuwB,QAAU,CAAA,EACxBzrB,SAAW4W,GAAUnxB,KAAK+5C,SAAS,SAAU5oB,GAC7CmrB,WAAW,gBAEZzC,GAAsBtgC,EAAOysB,OAAQ,8BAExCvjC,GAAAyE,cAAC,MAAA,CACC,mBAAkBqS,EAAOitB,oBAAsB,gDAA6C,EAC5F,eAAcxuB,QAAQuB,EAAOitB,qBAC7B,aAAW,wBACXz7B,UAAU,aACVgd,KAAK,SAELtlB,GAAAyE,cAAC+pB,EAAA,CACCmrB,eAAe,+BACflrB,YAAY,EACZmrB,SAAS,UACTv2C,MAAM,wBACNqrB,MAAO1b,EAAO+wB,qBAAuB,CAAA,EACrCjsB,SAAW4W,GAAUnxB,KAAK+5C,SAAS,sBAAuB5oB,GAC1DmrB,WAAW,cAEZzC,GAAsBtgC,EAAOitB,oBAAqB,6CAErD/jC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iBACbtI,GAAAyE,cAAC,IAAA,KAAE,iBAELzE,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,qCACftI,GAAAyE,cAAC,QAAA,KACEsyB,EAAKn5B,IAAI,CAACgmC,EAAU1wB,IACnBlT,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,oBACN,KAAA,KACClT,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAOigB,KAAO,uCAAoC,EACpE,eAAcxhB,QAAQuB,EAAOigB,MAC7B,aAAY,eAAe7jB,EAAQ,IACnC5K,UAAU,wBACVwP,SAAWwB,GAAU/b,KAAK46C,UAAUjlC,EAAOoG,EAAMlQ,OAAOyD,OACxDuQ,UAAU,EACVvQ,MAAsB,iBAAR+2B,EAAmBA,EAAMA,EAAI/2B,OAAS,MAGxD7M,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,SAAA,CACC,aAAY,sBAAsByO,EAAQ,IAC1C5K,UAAU,eACV,cAAa,sBAAsB4K,IACnCiJ,QAAS,IAAM5e,KAAK+uC,UAAUp5B,GAC9BxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,mCAM1BtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,KAAA,CAAG60C,QAAS,GACXt5C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,+BACV,cAAY,kBACZ6T,QAAS,IAAM5e,KAAK+5C,SAAS,OAAQ,IAAIvgB,EAAM,CAAElqB,MAAO,MACxDnQ,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,kCAAkC,wBAM3D8uC,GAAsBtgC,EAAOigB,KAAM,oCAGtC/2B,GAAAyE,cAAC,YAAS6D,UAAU,cAClBtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,iBAAgB,eACpBtI,GAAAyE,cAACy0C,GAAUxzC,GAAG,4CAE5B1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,sCACZ,QAAA,KACCtI,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAO6xB,kBACxB/sB,SAAWwB,GAAU/b,KAAK+5C,SAAS,mBAAoBh+B,EAAMlQ,OAAOwU,SACpElhB,KAAK,aACJ,IAAI,yCAIV,MAAA,CAAI4L,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAO8xB,YACxB,cAAY,cACZhtB,SAAWwB,IACT/b,KAAK+5C,SAAS,aAAch+B,EAAMlQ,OAAOwU,SACpCtE,EAAMlQ,OAAOwU,SAChBrgB,KAAK+5C,SAAS,6BAA6B,IAG/C56C,KAAK,aACJ,IAAI,kCAIV,MAAA,CAAI4L,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAO+xB,2BACxBltB,UAAW7E,EAAO8xB,WAClBhtB,SAAWwB,GAAU/b,KAAK+5C,SAAS,4BAA6Bh+B,EAAMlQ,OAAOwU,SAC7ElhB,KAAK,aACJ,IAAI,kCAMZs8C,GACCh5C,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,cAClBtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,iBAAgB,mBACjC,8BAA+B0K,GAC9BhT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,oBAAoB,cAAY,+BAC7CtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAO6lC,2BACxB/gC,SAAWwB,GAAU/b,KAAK+5C,SAAS,4BAA6Bh+B,EAAMlQ,OAAOwU,SAC7ElhB,KAAK,aACJ,IAAI,gCAKZ,6BAA8BsW,GAC7BhT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CAAM20C,QAAQ,kCAAiC,8BAChDp5C,GAAAyE,cAAC,SAAA,CACC,mBACEqS,EAAOgiC,yBAA2B,qDAAkD,EAEtF,eAAcvjC,QAAQuB,EAAOgiC,0BAC7BxwC,UAAU,wBACV5C,GAAG,iCACHoS,SAAWwB,GAAU/b,KAAK+5C,SAAS,2BAA4Bh+B,EAAMlQ,OAAOyD,OAC5EuQ,SAAU7H,QAAQvC,EAAO6lC,2BACzBhsC,MAAOmG,EAAO8lC,0BAA4B,IAE1C94C,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChB6pC,IACC,OAAAxD,EAAAlgC,EAAOo2B,oBAAP8J,EAAoB4G,4BAA6B,GACjD9mC,EAAO8lC,0BACPl7C,IAAKlB,GACLsD,GAAAyE,cAAC,SAAA,CAAOlF,IAAK7C,EAAMmQ,MAAOnQ,GACvBA,KAIN06C,GACCtgC,EAAOgiC,yBACP,mDAOV94C,GAAAyE,cAAC,OAAI6D,UAAU,+BACZ,MAAA,CAAIA,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,oCAEJ,MAAA,CAAI6D,UAAU,kBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,SAAU5K,EAAOgyB,YACjB,cAAY,kBACZ7mC,KAAK,cACL2Z,SAAU,IAAMva,KAAKk7C,gBAAe,GACpC/7C,KAAK,UACJ,IAAI,yBAIV,MAAA,CAAI4L,UAAU,kBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAOgyB,aACxB,cAAY,iBACZ7mC,KAAK,cACL2Z,SAAU,IAAMva,KAAKk7C,gBAAe,GACpC/7C,KAAK,UACJ,IAAI,QAMZa,KAAKw7C,cAAc,oBAAqB,mBAAoBxjC,QAAQvC,EAAOiyB,mBAC5EjlC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,uBAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACVwP,SAAWwB,GAAU/b,KAAK+5C,SAAS,oBAAqBh+B,EAAMlQ,OAAOyD,OACrEA,MAAOmG,EAAOkyB,mBAAqB,IAEnCllC,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,WAAU,WACxB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,aAAY,gBAI/BtP,KAAKw7C,cACJ,8BACA,4BACoC,IAApC/lC,EAAOmxB,0BAER5mC,KAAKw7C,cAAc,iBAAkB,eAAgBxjC,QAAQvC,EAAOyxB,eAErEzkC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa,cAAY,mBACtCtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,yBAAyB8wC,QAAQ,uBAAsB,mBAGxEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV5C,GAAG,sBACHoS,SAAWwB,GAAU/b,KAAK+5C,SAAS,sBAAuBh+B,EAAMlQ,OAAOyD,OACvEnQ,KAAK,OACLmQ,MAAOmG,EAAOmyB,qBAAuB,OAK3CnlC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,iBACbtI,GAAAyE,cAAC,IAAA,KAAE,gBAELzE,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,sDACd,QAAA,KACE88B,EAAWxnC,IAAI,CAACg7C,EAAe1lC,IAC9BlT,GAAAyE,cAAC,KAAA,CAAGlF,IAAK2T,EAAO,cAAa,cAAcA,sBACxC,KAAA,KACClT,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAOsuB,WAAa,sCAAmC,EACzE,eAAc7vB,QAAQuB,EAAOsuB,YAC7B,aAAY,cAAclyB,EAAQ,IAClC5K,UAAU,wBACVyxC,KAAK,kBACLjiC,SAAWwB,GACT/b,KAAK+5C,SACH,aACAlS,EAAWxnC,IAAI,CAACqI,EAAmBuyC,IACjCA,IAAetlC,EAAQoG,EAAMlQ,OAAOyD,MAAQ5G,IAIlDmX,UAAU,EACVvQ,MAAO+rC,KAGX54C,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,SAAA,CACC,aAAY,qBAAqByO,EAAQ,IACzC5K,UAAU,eACV,cAAa,qBAAqB4K,IAClCiJ,QAAS,IAAM5e,KAAK+6C,gBAAgBplC,GACpCxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,mCAM1BtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAAC,KAAA,CAAG60C,QAAS,GACXt5C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,+BACV,cAAY,iBACZ6T,QAAS,IAAM5e,KAAK+5C,SAAS,aAAc,IAAIlS,EAAY,KAC3D1oC,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,kCAAkC,uBAM5DtI,GAAAyE,cAAC,WAAA,CAASiB,GAAG,qBACT,OAAAytC,EAAAngC,EAAOo2B,kBAAP,EAAA+J,EAAoB/N,aAAc,IAAIxnC,IAAKg7C,GAC3C54C,GAAAyE,cAAC,SAAA,CAAOlF,IAAKq5C,EAAO/rC,MAAO+rC,MAG9BxB,GAAsBtgC,EAAOsuB,WAAY,mCAIlD,EC/0BK,MAAM4U,WAAgC3F,GAAtC,WAAAh2C,GAAAyjB,SAAA8C,WACLrnB,KAAQ08C,iBAAoB3gC,IAC1B,MAAMtG,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BunB,EAAiB2f,GAAOrqC,MAAMkD,KAAKuG,EAAMlQ,OAAOglB,iBAAiBxwB,IAAK8b,GAAWA,EAAO7M,QAExFstC,EADYC,GAAgBpnC,GAE/B/V,OAAQ8/B,GAAasd,GAAoBrnC,GAAQnR,SAASk7B,EAASr3B,MAAQ60B,EAAe14B,SAASk7B,EAASr3B,KAC5G+G,QAASswB,GAAaA,EAAS5C,YAC5BpD,EAAOqU,GAAap4B,GAAQ/V,OAAQ2mC,IAASuW,EAAYt4C,SAAS+hC,EAAI/2B,QAC5EtP,KAAK+8C,UAAU,IAAKtnC,EAAQunB,iBAAgBxD,QAAQwD,EAAgBxD,IAGtEx5B,KAAQg9C,iBAAmB,CAAC9O,EAAiBjuB,KAC3C,MAAMxK,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B3D,EAAYmrC,GAAkBxnC,GAC9B+jB,EAAOvZ,EACTi9B,GAAW,IAAIrP,GAAap4B,GAAS,CAAEnG,MAAO4+B,KAC9CL,GAAap4B,GAAQ/V,OAAQ2mC,GAAQA,EAAI/2B,QAAU4+B,GACjDiP,EAAmB3jB,EAAKn5B,IAAKgmC,GAAQA,EAAI/2B,OACzC8tC,EAAoBN,GAAoBrnC,GACxC4nC,EAAcD,EAAkB19C,OAAQyI,IAAQ2J,EAAUjO,KAAM27B,GAAaA,EAASr3B,KAAOA,IAC7F60B,EACF2f,GADmB18B,EACZ,IACFm9B,KACAtrC,EAAUpS,OAAQ8/B,GAAaA,EAAS5C,WAAWt4B,SAAS4pC,IAAU7tC,IAAKm/B,GAAaA,EAASr3B,KAE/F,IACFk1C,KACAvrC,EACApS,OACE8/B,GACC4d,EAAkB94C,SAASk7B,EAASr3B,KACpCq3B,EAAS5C,WAAW/4B,KAAMy5C,GAAcH,EAAiB74C,SAASg5C,KAErEj9C,IAAKm/B,GAAaA,EAASr3B,MAEpCnI,KAAK+8C,UAAU,IAAKtnC,EAAQunB,iBAAgBxD,QAAQwD,EAAgBxD,IAGtEx5B,KAAQ+8C,UAAY,CAACjnC,EAAiCknB,EAA0BxD,KACzEx5B,KAAKo3C,wBAAwBthC,EAASmT,MAAOs0B,GAEzCC,UADcx9C,KAAKi3C,QAAQd,oBAAoBoH,EAAe,mBAC7BznC,QAASknB,EAAgBxD,KAIrEx5B,KAAQy9C,oBAAuBC,IAC7B,MAAMjoC,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OACjCzV,KAAKsH,MAAM0vC,OAAOgD,cAAc,YAAa,IACxCvkC,EAAO+uB,UACV4D,2BAA4BsV,KAIhC19C,KAAQ29C,iBAAmB,KACzB,MAAM7nC,EAAU9V,KAAKsH,MAAM0vC,OAAOvhC,OAC5BunB,EAAiB8f,GAAoBhnC,GACrC0jB,EAAOqU,GAAa/3B,GACrB9V,KAAKo3C,wBAAwBthC,EAASmT,MAAOs0B,GAEzCC,UADcx9C,KAAKi3C,QAAQT,0BAA0B+G,EAAe,0BACnCznC,QAASknB,EAAgBxD,IAErE,CAEO,MAAAxU,GACL,MAAMvP,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BmoC,EAAcd,GAAoBrnC,GAClC+jB,EAAOqU,GAAap4B,GAAQpV,IAAKgmC,GAAQA,EAAI/2B,OAC7CuuC,EAAWZ,GAAkBxnC,GAC7BqoC,EAsHDjB,GAtH8BpnC,GAsHL/V,OAAQ8/B,GAA4C,IAA/BA,EAAS5C,WAAW14B,QArHvE,MAAMwW,EAsGV,SAAyB5I,EAAwB8rC,GAC/C,MAAMG,EAAejsC,EAAUzR,IAAKm/B,GAAaA,EAASr3B,IAC1D,MAAO,IACF2J,EAAUzR,IAAKm/B,KAAgBA,WAAU6d,aAAa,QACtDO,EACAl+C,OAAQyI,IAAQ41C,EAAaz5C,SAAS6D,IACtC9H,IAAK8H,KAAUq3B,SAAU,CAAEr3B,KAAIvH,KAAMuH,EAAIy0B,WAAY,IAAMygB,aAAa,KAE/E,CA9GoBW,CAAgBH,EAAUD,GACpCK,EAAyBJ,EAASn+C,OAAQ8/B,GAAaoe,EAAYt5C,SAASk7B,EAASr3B,KAE3F,wBACG,MAAA,CAAI4C,UAAU,mCACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAQ,8BAA6B,aAGhFp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,YACX6D,UAAU,wBACV5C,GAAG,6BACHyoB,UAAU,EACVrW,SAAUva,KAAK08C,iBACfptC,MAAOsuC,GAENljC,EAAQra,IAAI,EAAGm/B,WAAU6d,iBACxB56C,GAAAyE,cAAC,SAAA,CAAOlF,IAAKw9B,EAASr3B,GAAImH,MAAOkwB,EAASr3B,IACvCk1C,EAAc,GAAG7d,EAASr3B,mBAAqB,GAAGq3B,EAAS5+B,SAAS4+B,EAASr3B,UAIlFuS,EAAQxW,QAAUzB,GAAAyE,cAAC,KAAE6D,UAAU,uBAAsB,kCAI1DkzC,EAAuB59C,IAAKm/B,oBAC1B,WAAA,CAASz0B,UAAU,aAAa/I,IAAKw9B,EAASr3B,IAC7C1F,GAAAyE,cAAC,UAAO6D,UAAU,2BAA0B,mBAAiBy0B,EAAS5+B,MACtE6B,GAAAyE,cAAC,OAAI6D,UAAU,YACZy0B,EAAS5C,WAAWv8B,IAAKi9C,IACxB,MAAMn1C,EAkJtB,YAAsB+1C,GACpB,OAAOA,EAAMx4C,KAAK,KAAK8E,QAAQ,kBAAmB,IACpD,CApJ2B2zC,CAAU,0BAA2B3e,EAASr3B,GAAIm1C,GAC7D,OACE76C,GAAAyE,cAAC,OAAI6D,UAAU,WAAW/I,IAAKs7C,GAC7B76C,GAAAyE,cAAC,QAAA,CAAM20C,QAAS1zC,GACd1F,GAAAyE,cAAC,QAAA,CACC,aAAY,cAAco2C,kBAA0B9d,EAASr3B,KAC7DkY,QAASmZ,EAAKl1B,SAASg5C,GACvBn1C,KACAoS,SAAWwB,GAAU/b,KAAKg9C,iBAAiBM,EAAWvhC,EAAMlQ,OAAOwU,SACnElhB,KAAK,aAENm+C,0BASd,MAAA,CAAIvyC,UAAU,oBACbtI,GAAAyE,cAAC,OAAI6D,UAAU,qCACbtI,GAAAyE,cAAC,QAAA,CAAM20C,QAAQ,+BACbp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,0BACXmZ,QAASrI,QAAQvC,EAAO+uB,UAAU4D,4BAClCjgC,GAAG,8BACHoS,SAAWwB,GAAU/b,KAAKy9C,oBAAoB1hC,EAAMlQ,OAAOwU,SAC3DlhB,KAAK,aACJ,IAAI,6BAMZsW,EAAO+uB,UAAU4D,4BAChB3lC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,uBAELzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,KAAA,CAAG,aAAW,sBACZ42C,EAAS55C,OACR45C,EAASz9C,IAAKm/B,GAAa/8B,GAAAyE,cAAC,KAAA,CAAGlF,IAAKw9B,EAASr3B,IAAKq3B,EAAS5+B,OAE3D6B,GAAAyE,cAAC,KAAA,KAAG,WAOdzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,oBACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,4BACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,oBACX6D,UAAU,eACV6T,QAAS5e,KAAK29C,iBACdx+C,KAAK,UACN,uBAOX,EAaF,SAAS89C,GAAkBnnC,GACzB,OAAO+mC,GAAgB/mC,GAASpW,OAAQ8/B,GAAaA,EAAS5C,WAAW14B,OAAS,EACpF,CAMA,SAAS24C,GAAgB/mC,GApNzB,IAAA9R,EAAAsE,EAAAe,EAAAC,EAqNE,MAAM80C,GAAM,OAAA90C,EAAA,OAAAD,EAAA,OAAAf,EAAA,OAAAtE,EAAA8R,EAAQ+1B,kBAAR,EAAA7nC,EAAqBg5B,qBAArB,EAAA10B,EAAsCwN,EAAQC,aAAe,UAA7D,EAAA1M,EAAkEuG,UAAlE,EAAAtG,EAAuEq1B,SAAU,GACvF0f,MAAWnpC,IAajB,OAZAkpC,EACG1+C,OAAQ8/B,GAAkBA,EAAS11B,UAAYgM,EAAQhM,SACvD/H,QAASy9B,IACR,MAAM8e,EAAWD,EAAK/+C,IAAIkgC,EAASr3B,IAC7By0B,EAAa+f,GAAO,KAAK,MAAA2B,OAAA,EAAAA,EAAU1hB,aAAc,MAAQ2hB,GAAgB/e,EAAS5C,cACxFyhB,EAAK9oC,IAAIiqB,EAASr3B,GAAI,CACpBA,GAAIq3B,EAASr3B,GACbvH,KAAM4+B,EAAS5+B,OAAQ,MAAA09C,OAAA,EAAAA,EAAU19C,OAAQ4+B,EAASr3B,GAClD2B,QAAS01B,EAAS11B,QAClB8yB,iBAGCtqB,MAAMkD,KAAK6oC,EAAK5oC,UAAUkvB,KAAK,CAAC6Z,EAAMC,IAAUD,EAAK59C,KAAK89C,cAAcD,EAAM79C,MACvF,CAEA,SAAS29C,GAAgB3hB,GACvB,GAAItqB,MAAMC,QAAQqqB,GAChB,OAAO+f,GAAO/f,EAAWv8B,IAAI8X,SAE/B,GAA0B,iBAAfykB,EACT,MAAO,GAGT,OAAO+f,GADS/f,EAAWnjB,OAAOjP,QAAQ,MAAO,IAAIA,QAAQ,MAAO,IAC9CxH,MAAM,KAAK3C,IAAKgmC,GAAQA,EAAI5sB,QACpD,CAEA,SAASqjC,GAAoBhnC,GAC3B,OAAO6mC,GAAO7mC,EAAQknB,gBAAkB,GAC1C,CAEA,SAAS6Q,GAAa/3B,GACpB,OAAOonC,IAAYpnC,EAAQ0jB,MAAQ,IAAIn5B,IAAKgmC,GAAuC,iBAARA,EAAmB,CAAE/2B,MAAO+2B,GAAQA,GACjH,CAEA,SAAS6W,GAAW1jB,GAClB,MAAMmlB,MAAczpC,IAEpB,OADAskB,EAAKz3B,QAASskC,GAAQA,EAAI/2B,QAAUqvC,EAAQ1sC,IAAIo0B,EAAI/2B,QAAUqvC,EAAQppC,IAAI8wB,EAAI/2B,MAAO+2B,IAC9E/zB,MAAMkD,KAAKmpC,EAAQlpC,SAC5B,CAEA,SAAS+nC,GACP1nC,EACAknB,EACAxD,GAEA,MAAO,IACF1jB,EACHknB,iBACAxD,OACAgL,UAAW,IACN1uB,EAAQ0uB,UACX0L,MAAO,IAAKp6B,EAAQ0uB,UAAU0L,MAAOlT,eAAgB,OAG3D,CAMA,SAAS2f,GAAOlnC,GACd,OAAOnD,MAAMkD,KAAK,IAAIzE,IAAI0E,EAAO/V,OAAOsY,UAC1C,CChNA,MAAM4mC,GAAuB,CAAC,OAAQ,eAChCC,GAA6B,CAAC,aAAc,eAC5CC,GAAoB,CAAC,4BAA6B,qBAAsB,kBACxEC,GAAgC,CACpCC,cAAe,cACfC,eAAgB,EAChBC,eAAgB,GAChBC,WAAY,CAAC,CAAEv+C,KAAM,OAAQwV,KAAM,MAGrC,SAASgpC,GAActnC,GACrB,MAAO,6BAA6BA,EAAMtN,QAAQ,WAAY,OAAOiyB,qBACvE,CAEA,SAAS4iB,GAAkBrwC,EAA2B7G,GACpD,OACE6G,oBACG,OAAA,CAAKjE,UAAU,aAAa5C,KAAQ4f,KAAK,SACvC/Y,EAIT,CAEO,MAAMswC,WAAoCxI,GAA1C,WAAAh2C,GAAAyjB,SAAA8C,WA6VLrnB,KAAQu/C,2BAA8BxjC,IACpC,MAAMtG,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BxR,EAAgBu7C,GAAcltC,MAAMkD,KAAKuG,EAAMlQ,OAAOglB,iBAAiBxwB,IAAI,EAAGiP,WAAYA,IAC1FmwC,EAAqB,IAAI1uC,IAAIyuC,GAAc/pC,EAAOxR,gBAClDzC,EAAkBN,OAAOmX,QAAQ5C,EAAOjU,iBAAmB,CAAA,GAAIgN,OACnE,CAACkxC,GAAWzrC,EAAkBgB,OACxBhR,EAAcK,SAAS2P,IAAsBwrC,EAAmBxtC,IAAIgC,KACtEyrC,EAASzrC,GAAoBurC,GAAcvqC,IAEtCyqC,GAET,CAAA,GAEIxJ,EAAsC,IACvCzgC,EACHxR,gBACAigC,qBAAsByb,GAA8BlqC,EAAQxR,GAC5DzC,kBACA2lC,uBAAwBqY,GAAct+C,OAAOuU,OAAOjU,GAAiBo+C,SAEvE1J,EAAYhN,oBA8LhB,SAAsCpzB,GA5oBtC,IAAA9R,EAAAsE,EA6oBE,MAAMu3C,EAAiBC,GAAkBhqC,GACzC,IAAK+pC,EAAe37C,OAClB,OAEF,MAAMo6C,EAAWxoC,EAAQozB,oBACnB8V,GACJ,MAAAV,OAAA,EAAAA,EAAUU,gBAAiBa,EAAev7C,SAASg6C,EAASU,eACxDV,EAASU,cACTD,GAA8BC,cAC9Be,EAA+B,IAChCzB,EACHU,gBACAC,eAAgB,OAAAj7C,EAAA,MAAAs6C,OAAA,EAAAA,EAAUW,gBAAVj7C,EAA4B+6C,GAA8BE,eAC1EE,WAAY,OAAA72C,EAAA,MAAAg2C,OAAA,EAAAA,EAAUa,YAAV72C,EAAwBy2C,GAA8BI,WAAW9+C,IAAK2/C,IAAA,IAAoBA,OAEpG,MAAA1B,OAAA,EAAAA,EAAUU,iBAAkBA,GAC9BF,GAAkB/8C,QAAS+V,UAAiBioC,EAAOjoC,IAE/B,gBAAlBknC,QAA6D,IAA1Be,EAAOb,iBAC5Ca,EAAOb,eAAiBH,GAA8BG,gBAExD,OAAOa,CACT,CArNsCE,CAA6B/J,GAC1Dl2C,KAAKkgD,gBAAgBhK,EAAa,CAAC,gBAAiB,uBAAwB,wBAAwB,IAG3Gl2C,KAAQmgD,6BAA+B,CACrClsC,EACA8H,KAEA,MAAMtG,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BjU,EAAkB,IAClBiU,EAAOjU,iBAAmB,CAAA,EAC9ByS,CAACA,GAAmBurC,GAAcltC,MAAMkD,KAAKuG,EAAMlQ,OAAOglB,iBAAiBxwB,IAAI,EAAGiP,WAAYA,KAE1F4mC,EAAc,IACfzgC,EACHjU,kBACA2lC,uBAAwBqY,GAAct+C,OAAOuU,OAAOjU,GAAiBo+C,SAElE5/C,KAAKkgD,gBAAgBhK,EAAa,CAAC,kBAAmB,4BAG7Dl2C,KAAQogD,2BAA8BrkC,IACpC,MAAMgkC,EAAS,IAAO//C,KAAKsH,MAAM0vC,OAAOvhC,OAAOyzB,qBAAuB,IACtE4V,GAAkB/8C,QAAS+V,UAAiBioC,EAAOjoC,IACnDioC,EAAOf,cAAgBjjC,EAAMlQ,OAAOyD,MAC/BtP,KAAKqgD,aAAaN,IAGzB//C,KAAQsgD,uBAAyB,CAAC3qC,EAAemC,EAAyBxI,KACxE,MAAMywC,EAAS,IAAO//C,KAAKsH,MAAM0vC,OAAOvhC,OAAOyzB,qBAAuB,IACtE6W,EAAOZ,YAAcY,EAAOZ,YAAc,IAAI9+C,IAAI,CAAC2/C,EAAWO,IAC5DA,IAAmB5qC,EAAQ,IAAKqqC,EAAWloC,CAACA,GAAQxI,GAAU0wC,GAE3DhgD,KAAKqgD,aAAaN,IAGzB//C,KAAQwgD,mBAAqB,KAC3B,MAAMT,EAAS,IAAO//C,KAAKsH,MAAM0vC,OAAOvhC,OAAOyzB,qBAAuB,IACtE6W,EAAOZ,WAAa,IAAKY,EAAOZ,YAAc,GAAK,CAAEv+C,KAAM,GAAIwV,KAAM,KAChEpW,KAAKqgD,aAAaN,IAGzB//C,KAAQygD,sBAAyB9qC,IAC/B,MAAMoqC,EAAS,IAAO//C,KAAKsH,MAAM0vC,OAAOvhC,OAAOyzB,qBAAuB,IACtE6W,EAAOZ,YAAcY,EAAOZ,YAAc,IAAIz/C,OAAO,CAACghD,EAAYH,IAAmBA,IAAmB5qC,GACnG3V,KAAKqgD,aAAaN,IAGzB//C,KAAQ2gD,yBAA2B,CAAC7oC,EAAmCxI,KACrE,MAAMywC,EAAS,IACR//C,KAAKsH,MAAM0vC,OAAOvhC,OAAOyzB,qBAAuB,CAAA,EACrDpxB,CAACA,GAAQxI,GAENtP,KAAKqgD,aAAaN,IAgDzB//C,KAAQ4gD,cAAgB,KACtB,MAAMC,EAAwBrB,GAAcx/C,KAAKsH,MAAM0vC,OAAOvhC,OAAOxR,eAChEjE,KAAKo3C,wBAAwBp3C,KAAKsH,MAAM0vC,OAAOvhC,OAAQwT,MAAOs0B,IACjE,MAAMniC,QAAepb,KAAKi3C,QAAQT,0BAA0B+G,EAAe,wBAC3E,MAAO,IACFniC,EAAOtF,QACV7R,cAAe48C,EACfrc,UAAW,IACNppB,EAAOtF,QAAQ0uB,UAClB0L,MAAO90B,EAAOhb,OAAO8vC,UAI7B,CAleO,QAAAgH,CAASzhC,GACd,MAAM8D,EAASgL,MAAM2yB,SAASzhC,GAGxBsqC,EAAStqC,EAAOyzB,oBACtB,IAAK6W,IAAWP,GAAc/pC,EAAOxR,eAAeC,OAClD,OAAOqV,EAGT,MAAMunC,EAA2C,CAAA,EAC3CjB,EAAiBC,GAAkBrqC,GACpCsqC,EAAOf,eAAkBa,EAAev7C,SAASy7C,EAAOf,iBAC3D8B,EAAa9B,cAAgB,qEAE1B+B,GAAoBhB,EAAOd,eAAgBxpC,EAAQ,EAAG,KACzDqrC,EAAa7B,eAAiB,wCAGhC,MAAM+B,GAAmBjB,EAAOZ,YAAc,IAAI9+C,IAAI,EAAGO,OAAMwV,WAC7D,MAAM6qC,EAAmD,CAAA,EAOzD,aANKrgD,WAAM6Y,UACTwnC,EAAergD,KAAO,uBA8pB9B,SAAwB0O,EAAgBwG,EAAiCuN,EAAiBC,GACxF,GAAIg2B,GAAexjC,IAAYyjC,GAAajqC,GAC1C,OAAO,EAET,IAAK4xC,GAAgB5xC,GACnB,OAAO,EAET,MAAMqqC,EAAexjC,OAAO7G,GAC5B,OACE6G,OAAO4D,SAAS4/B,IAChBxjC,OAAOiG,UAAUu9B,IACjBA,GAAgBt2B,GAChBs2B,GAAgBr2B,CAEpB,CA1qBWm2B,CAAerjC,EAAMX,EAAQ,EAAG,SACnCwrC,EAAe7qC,KAAO,gDAEjB6qC,IAmBT,OAjBID,EAAgBn9C,KAAMo9C,GAAmB//C,OAAOY,KAAKm/C,GAAgB/8C,UACvE48C,EAAa3B,WAAa6B,GAGC,SAAzBjB,EAAOf,eAA6BmC,GAAepB,EAAOqB,mBAAoB3rC,EAAQ,KACxFqrC,EAAaM,mBAAqB,mEAEP,eAAzBrB,EAAOf,eAAmCmC,GAAepB,EAAOsB,0BAA2B5rC,EAAQ,KACrGqrC,EAAaO,0BAA4B,0EAEd,gBAAzBtB,EAAOf,eAAoC+B,GAAoBhB,EAAOb,eAAgBzpC,EAAQ,EAAG,KACnGqrC,EAAa5B,eAAiB,+CAG5Bh+C,OAAOY,KAAKg/C,GAAc58C,SAC5BqV,EAAO2vB,oBAAsB4X,GAExBvnC,CACT,CAEO,MAAAyL,GACL,MAAMvP,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BorC,EAAwBrB,GAAc/pC,EAAOxR,eAC7Cq9C,EAskBV,SACEC,EACAV,GAEA,MAAM7uC,EAAiB,IAAIjB,IAAIwwC,EAAuBlhD,IAAI,EAAGO,UAAWA,IACxE,MAAO,IACF2gD,EACAlhD,IAAK+D,QAAuBA,EAAci5C,aAAa,KACvD1Y,KAAK,CAAC6Z,EAAMC,IAAUD,EAAK59C,KAAK89C,cAAcD,EAAM79C,UACpDigD,EAAsBnhD,OAAQkB,IAAUoR,EAAeC,IAAIrR,IAAOP,IAAKO,IAAA,CAAYA,OAAMy8C,aAAa,KAE7G,CAjlB+BmE,CAkb/B,SAAmC1rC,GAnkBnC,IAAA9R,EAAAsE,EAAAe,EAokBE,MAAMo4C,EAAmB,OAAAz9C,EAAA8R,EAAQ+1B,kBAAR,EAAA7nC,EAAqBC,cAC9C,GAAIqO,MAAMC,QAAQkvC,GAChB,OAAOC,GACLD,EACGvyC,QAAStP,GAAmB0S,MAAMC,QAAQ,MAAA3S,OAAA,EAAAA,EAAU0Q,UAAY1Q,EAAS0Q,SAAW,IACpF5Q,OAAQc,IAAiB,MAAAA,OAAA,EAAAA,EAASI,QAASkV,EAAQC,aACnD7G,QAAS1O,GAAkB8R,MAAMC,QAAQ,MAAA/R,OAAA,EAAAA,EAASgQ,SAAWhQ,EAAQgQ,QAAU,IAC/EtB,QAAS3N,GAAiB+Q,MAAMC,QAAQ,MAAAhR,OAAA,EAAAA,EAAQ0C,eAAiB1C,EAAO0C,cAAgB,IACxFvE,OAAQ0E,GA8OjB,SAAgCA,EAAmB0R,GACjD,OAAO,MAAA1R,OAAA,EAAAA,EAAc7C,UAAWuU,EAAQvU,QAAmC,kBAAzB6C,WAAc7C,OAClE,CAhPuCogD,CAAuBv9C,EAAc0R,IACnEzV,IAAIuhD,IACJliD,OAAQ0E,GAAsD4T,QAAQ5T,KAI7E,MAAMy9C,EAAwB,OAAAx4C,EAAA,OAAAf,EAAAwN,EAAQ+1B,kBAAR,EAAAvjC,EAAqB4hB,eAArB,EAAA7gB,EAA+BpF,cAC7D,IAAKqO,MAAMC,QAAQsvC,GACjB,MAAO,GAET,OAAOH,GACLG,EACGxhD,IAAIuhD,IACJliD,OAAQ0E,GAAsD4T,QAAQ5T,IAE7E,CA1ckD09C,CAA0BrsC,GAASorC,GAC3Ed,EAAUtqC,EAAOyzB,qBAAuB,CAAA,EACxC4X,EAAgB9gD,KAAKk3C,SAASzhC,GAEjCyzB,qBAAuB,CAAEiW,WAAY,IAClCU,EAAiBC,GAAkBrqC,GAEzC,wBACG,MAAA,CAAI1K,UAAU,mCACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAQ,mCAAkC,kBAGrFp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,iBACX6D,UAAU,wBACV5C,GAAG,kCACHyoB,UAAU,EACVrW,SAAUva,KAAKu/C,2BACfjwC,MAAOuxC,GAENS,EAAmBjhD,IAAI,EAAGO,OAAMy8C,iBAC/B56C,GAAAyE,cAAC,SAAA,CAAOlF,IAAKpB,EAAM0O,MAAO1O,GACvBA,EACAy8C,EAAc,iBAAmB,OAK1C56C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,yBACX6D,UAAU,yBACV6T,QAAS5e,KAAK4gD,cACdzhD,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,mCAKrB81C,EAAsBxgD,IAAK4T,GAAqBjU,KAAK+hD,6BAA6BtsC,EAAQxB,IAE1F4sC,EAAsB38C,OAAS,GAAK27C,EAAe37C,OAAS,qCAEzDzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAQ,sBAAqB,kBAGxEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkB45C,EAAa9B,cAAgBI,GAAc,sBAAmB,EAChF,eAAcpnC,QAAQ8oC,EAAa9B,eACnC,aAAW,iBACXj0C,UAAU,wBACV5C,GAAG,qBACHoS,SAAUva,KAAKogD,2BACfvgC,UAAU,EACVvQ,MAAOywC,EAAOf,eAAiB,KAE7Be,EAAOf,gCAAkB,SAAA,CAAO1vC,MAAM,IAAG,aAC1CuwC,EAAex/C,IAAKqT,GACnBjR,GAAAyE,cAAC,SAAA,CAAOlF,IAAK0R,EAAMpE,MAAOoE,GACvBA,KAIN2rC,GAAkByB,EAAa9B,cAAeI,GAAc,oBAIhEp/C,KAAKgiD,iBAAiBvsC,EAAQsqC,EAAQe,EAAa3B,YAAc,IACjEn/C,KAAKiiD,sBACJ,kBACA,iBACAlC,EAAOd,eACPxpC,EACAqrC,EAAa7B,gBAEW,gBAAzBc,EAAOf,eACNh/C,KAAKiiD,sBACH,kBACA,iBACAlC,EAAOb,eACPzpC,EACAqrC,EAAa5B,gBAES,SAAzBa,EAAOf,eACNh/C,KAAKkiD,kBACH,wBACA,qBACAnC,EAAOqB,mBACP3rC,EACAqrC,EAAaM,oBAES,eAAzBrB,EAAOf,eACNh/C,KAAKkiD,kBACH,+BACA,4BACAnC,EAAOsB,0BACP5rC,EACAqrC,EAAaO,4BAM3B,CAEQ,4BAAAU,CACNtsC,EACAxB,GAjQJ,IAAAjQ,EAmQI,MAAMm+C,EAA2BC,GAAsB3sC,EAAQxB,GAAkB5T,IAAI,EAAGO,UAAWA,GAC7FyhD,EAA0B7C,GAAc,OAAAx7C,EAAAyR,EAAOjU,0BAAkByS,IACvE,IAAKkuC,EAAyBj+C,SAAWm+C,EAAwBn+C,OAC/D,OAAO,KAET,MAAM+W,EAAaqnC,GAAyBH,EAA0BE,GAEtE,OACE5/C,GAAAyE,cAAC,OAAI6D,UAAU,aAAa/I,IAAKiS,GAC/BxR,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAS,wBAAwB5nC,KAAoB,wBACxEA,GAExBxR,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAY,wBAAwB+M,IACpClJ,UAAU,wBACV5C,GAAI,wBAAwB8L,IAC5B2c,UAAU,EACVrW,SAAWwB,GAAU/b,KAAKmgD,6BAA6BlsC,EAAkB8H,GACzEzM,MAAO+yC,GAENpnC,EAAW5a,IAAI,EAAGg9C,cAAa/tC,WAC9B7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,OAOhD,CAEQ,gBAAA2E,CACNvsC,EACAsqC,EACAxmC,GAEA,MAAMvH,EA2UDwtC,GACLA,IAFuB1pC,EA1UkBL,GA4UnBxR,eAAeiL,QAAS+E,GAC5CmuC,GAAsBtsC,EAAS7B,GAAkB5T,IAAI,EAAG8Y,cAAeA,GAAY,MAErFzZ,OAAOsY,SALX,IAA2BlC,EAzUvB,MAAMqpC,EAAaY,EAAOZ,YAAc,GACxC,OACE18C,GAAAyE,cAAAzE,GAAAwI,SAAA,KACGk0C,EAAW9+C,IAAI,CAAC2/C,EAAWrqC,KA7SpC,IAAA3R,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EA8SU,MAAM9hB,EAAaqnC,GAAyBtwC,EAAgBguC,EAAUp/C,KAAO,CAACo/C,EAAUp/C,MAAQ,IAC1F2hD,EAAcnD,GAAc,iBAAiBzpC,KAC7C6sC,EAAcpD,GAAc,iBAAiBzpC,KACnD,OACElT,GAAAyE,cAAC,OAAI6D,UAAU,aAAa/I,IAAK2T,GAC/BlT,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAS,uBAAuBlmC,KAAS,cACtEA,EAAQ,GAEtBlT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,oBAAkB,OAAAlD,EAAAuV,EAAO5D,WAAP3R,EAAepD,MAAO2hD,OAAc,EACtD,eAAcvqC,QAAQ,OAAA1P,EAAAiR,EAAO5D,aAAQ/U,MACrC,aAAY,mBAAmB+U,EAAQ,IACvC5K,UAAU,wBACV5C,GAAI,uBAAuBwN,IAC3B4E,SAAWwB,GAAU/b,KAAKsgD,uBAAuB3qC,EAAO,OAAQoG,EAAMlQ,OAAOyD,OAC7EuQ,UAAU,EACVvQ,MAAO0wC,EAAUp/C,OAEfo/C,EAAUp/C,uBAAS,SAAA,CAAO0O,MAAM,IAAG,aACpC2L,EAAW5a,IAAI,EAAGg9C,cAAa/tC,WAC9B7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,MAIvCgC,GAAkB,OAAAh2C,EAAAkQ,EAAO5D,SAAP,EAAAtM,EAAezI,KAAM2hD,IAE1C9/C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,oBAAkB,OAAAoC,EAAAiQ,EAAO5D,WAAPrM,EAAe8M,MAAOosC,OAAc,EACtD,eAAcxqC,QAAQ,OAAAwC,EAAAjB,EAAO5D,aAAQS,MACrC,aAAY,qBAAqBT,EAAQ,IACzC5K,UAAU,wBACVwP,SAAWwB,GACT/b,KAAKsgD,uBAAuB3qC,EAAO,OAAQ8sC,GAAkB1mC,EAAMlQ,OAAOyD,QAE5EuQ,UAAU,EACV1gB,KAAMm6C,GAAe7jC,GAAU,OAAS,SACxCnG,MAAO0wC,EAAU5pC,OAElBipC,GAAkB,OAAAtiB,EAAAxjB,EAAO5D,SAAP,EAAAonB,EAAe3mB,KAAMosC,IAE1C//C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAY,qBAAqByO,EAAQ,IACzC5K,UAAU,yBACV6T,QAAS,IAAM5e,KAAKygD,sBAAsB9qC,GAC1CxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,mCAM1BtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,4BACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,iBACX6D,UAAU,yBACV6T,QAAS5e,KAAKwgD,mBACdrhD,KAAK,UACN,oBAOX,CAEQ,qBAAA8iD,CACNn8C,EACAgS,EACAxI,EACAmG,EACAzG,GAEA,MAAM0zC,EAAUtD,GAActnC,GAC9B,OACErV,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAS,OAAO/jC,KACxDhS,EACDrD,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAI,uCAAuC2P,OAExDrV,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,eACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkB8H,EAAQ0zC,OAAU,EACpC,eAAc1qC,QAAQhJ,GACtB,aAAYlJ,EACZiF,UAAU,wBACV5C,GAAI,OAAO2P,IACXyC,SAAWwB,GAAU/b,KAAK2gD,yBAAyB7oC,EAwZjE,SAA8BxI,GAC5B,GAAIiqC,GAAajqC,GACf,OAAOA,EAET,OAAOA,EAAMmK,OAAStD,OAAO7G,GAAS,IAAM,EAC9C,CA7ZwEqzC,CAAqB5mC,EAAMlQ,OAAOyD,QAC5FuQ,UAAU,EACV1gB,KAAMm6C,GAAe7jC,GAAU,OAAS,SACxCnG,MAAOszC,GAAkBtzC,KAE3B7M,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,qBAAoB,MAErCs0C,GAAkBrwC,EAAO0zC,IAIlC,CAEQ,iBAAAR,CACNp8C,EACAgS,EACAxI,EACAmG,EACAzG,GAEA,MAAM0zC,EAAUtD,GAActnC,GAC9B,OACErV,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAS,OAAO/jC,KACxDhS,EACDrD,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAI,uCAAuC2P,OAExDrV,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkB8H,EAAQ0zC,OAAU,EACpC,eAAc1qC,QAAQhJ,GACtB,aAAYlJ,EACZiF,UAAU,wBACV5C,GAAI,OAAO2P,IACXyC,SAAWwB,GAAU/b,KAAK2gD,yBAAyB7oC,EAAO2qC,GAAkB1mC,EAAMlQ,OAAOyD,QACzFuQ,UAAU,EACV1gB,KAAMm6C,GAAe7jC,GAAU,OAAS,SACxCnG,WAAiB,IAAVA,EAAsB,GAAKA,IAEnC+vC,GAAkBrwC,EAAO0zC,IAIlC,CA8EQ,YAAArC,CAAaN,GACnB,MAAMtqC,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OACjC,OAAOzV,KAAKkgD,gBAAgB,IAAKzqC,EAAQyzB,oBAAqB6W,GAAU,CACtE,kBACA,yBACA,gBACA,uBACA,uBAEJ,CAEQ,eAAAG,CACNhK,EACA2M,EACAC,GAAiC,GAEjC,OAAO9iD,KAAKo3C,wBAAwBlB,EAAajtB,MAAOs0B,IACtD,MAAMlL,EAAoB0Q,GAAqBxF,GACzCyF,EAAuB,IACxBzF,EACHt5C,cAAeu7C,GAAcjC,EAAct5C,eAAevE,OAAQkB,GAASoX,QAAQq6B,EAAkBzxC,MAEjGwa,QAAepb,KAAKi3C,QAAQX,yBAAyB0M,EAAsB,gCAC3EltC,EAAkC,IACnCsF,EAAOtF,QACV7R,cAAes5C,EAAct5C,cAC7BugC,UAAW,IACNppB,EAAOtF,QAAQ0uB,UAClB0L,MAAO90B,EAAOhb,OAAO8vC,QAazB,OAVI4S,IACFhtC,EAAQtU,gBAAkB,IACpB+7C,EAAc/7C,iBAAmB,CAAA,KACjC4Z,EAAOtF,QAAQtU,iBAAmB,CAAA,GAExCsU,EAAQqxB,uBAAyBqY,GAAct+C,OAAOuU,OAAOK,EAAQtU,iBAAiBo+C,SAExFiD,EAAgB9gD,QAAS+V,IACvBhC,EAAQgC,GAASylC,EAAczlC,KAE1BhC,GAEX,EA4CF,SAASitC,GAAqBjtC,GA7lB9B,IAAA9R,EAAAsE,EA8lBE,OAAQ,OAAAA,EAAA,WAAQujC,kBAAR,EAAA7nC,EAAqBkmB,eAArB,EAAA5hB,EAA+B+pC,oBAAqB,CAAA,CAC9D,CAEA,SAAS+P,GAAsBtsC,EAAiC7B,GAC9D,MAAM7P,EAAe2+C,GAAqBjtC,GAAS7B,GACnD,IAAK3B,MAAMC,QAAQ,MAAAnO,SAAAA,EAAc5C,iBAC/B,MAAO,GAET,MAAMyhD,MAAa/tC,IAUnB,OATA9Q,EAAa5C,gBAAgBO,QAAS2S,IACpC,MAAMpF,EACsB,iBAAnBoF,EACH,CAAE9T,KAAM8T,GACR,CAAE9T,KAAM8T,EAAe9T,MAAQ,GAAIuY,SAAUzE,EAAeyE,UAC9D7J,EAAM1O,OAASqiD,EAAOhxC,IAAI3C,EAAM1O,OAClCqiD,EAAO1tC,IAAIjG,EAAM1O,KAAM0O,KAGpBgD,MAAMkD,KAAKytC,EAAOxtC,SAC3B,CAUA,SAASqqC,GAAkBhqC,GA3nB3B,IAAA9R,EA4nBE,MAAMquC,EAAoB0Q,GAAqBjtC,GACzCotC,EAAW1D,GAAc1pC,EAAQ7R,eACpC5D,IAAK4T,IA9nBV,IAAAjQ,EA8nB+B,OAAA,OAAAA,EAAAquC,EAAkBp+B,WAAlBjQ,EAAqCK,mBAC/D3E,OAAQ2E,GAAiD2T,QAAQ3T,IACjEhE,IAAKgE,GACiB,SAArBA,GAAoD,qBAArBA,EAC3Bu6C,GACAC,IAER,IAAKqE,EAASh/C,OAAQ,CACpB,MAAMi/C,EAAiB,OAAAn/C,EAAA8R,EAAQozB,0BAAR,EAAAllC,EAAkEg7C,cACzF,OAAOmE,EAAgB,CAACA,GAAiB,EAC3C,CACA,OAAOD,EAAS9nB,MAAM,GAAG5sB,OAAO,CAAC40C,EAAOC,IAAcD,EAAM1jD,OAAQgU,GAAS2vC,EAAU/+C,SAASoP,IAAQwvC,EAAS,GACnH,CA2BA,SAASvD,GACP7pC,EACAwtC,GAEA,MAAMrf,EAAW/iC,OAAOmX,QAAQvC,EAAQouB,sBAAwB,CAAA,GAAI11B,OAClE,CAAC+0C,GAAOvhD,EAAKyT,MAAM,IAAY8tC,EAAMvhD,CAACA,GAAMw9C,GAAc/pC,KAC1D,CAAA,GAcF,OAZA+pC,GAAc1pC,EAAQ7R,eAAelC,QAASkS,IAC5C,MAAM0D,EAAY6rC,GAAiC1tC,EAAS7B,GACxD0D,IACFssB,EAAStsB,EAAU3V,MAAQiiC,EAAStsB,EAAU3V,MAAQ,IAAItC,OAAQkB,IAAU+W,EAAUsE,MAAM3X,SAAS1D,OAGzG0iD,EAAkBvhD,QAASkS,IACzB,MAAM0D,EAAY6rC,GAAiC1tC,EAAS7B,GACxD0D,IACFssB,EAAStsB,EAAU3V,KAAOw9C,GAAc,IAAKvb,EAAStsB,EAAU3V,MAAQ,MAAQ2V,EAAUsE,WAGvFgoB,CACT,CAEA,SAASuf,GACP1tC,EACA7B,GAEA,MAAM7P,EAAe2+C,GAAqBjtC,GAAS7B,GACnD,GAAK7P,EAAL,CAGA,GAAsC,SAAlCA,EAAaC,kBAAiE,qBAAlCD,EAAaC,iBAAyC,CACpG,MAAM4X,EAAQujC,IAAep7C,EAAa0M,WAAa,IAAIzQ,IAAI,EAAGO,UAAWA,GAAQ,KACrF,IAAKqb,EAAM/X,OACT,OAEF,MAAO,CACLlC,IAAuC,SAAlCoC,EAAaC,iBAA8B,6BAA+B,sBAC/E4X,QAEJ,CACA,MAAO,CACLja,IACoC,QAAlCoC,EAAaC,kBAAgE,QAAlCD,EAAaC,iBACpD,6BACA,sBACN4X,MAAO,CAAChI,GAhBV,CAkBF,CAeA,SAASquC,GAAyBmB,EAA2BC,GAC3D,MAAM5xC,EAAY0tC,GAAciE,GAChC,MAAO,IACF3xC,EAAUzR,IAAKiP,KAAa+tC,aAAa,EAAO/tC,cAChDkwC,GAAckE,GACdhkD,OAAQ4P,IAAWwC,EAAUxN,SAASgL,IACtCjP,IAAKiP,IAAA,CAAa+tC,aAAa,EAAM/tC,WAE5C,CAEA,SAASgqC,GAAexjC,GACtB,MAAkC,mBAA3BA,EAAQ0uB,UAAU9wB,MAAwD,iBAA3BoC,EAAQ0uB,UAAU9wB,IAC1E,CAEA,SAAS6lC,GAAajqC,GACpB,MAAwB,iBAAVA,GAAsB,mBAAmBkU,KAAKlU,EAC9D,CAEA,SAASyxC,GACPzxC,EACAwG,EACAuN,EACAC,GAEA,GAAIg2B,GAAexjC,IAAYyjC,GAAajqC,GAC1C,OAAO,EAET,IAAK4xC,GAAgB5xC,GACnB,OAAO,EAET,MAAMqqC,EAAexjC,OAAO7G,GAC5B,OAAO6G,OAAO4D,SAAS4/B,IAAiBA,GAAgBt2B,GAAWs2B,GAAgBr2B,CACrF,CAEA,SAAS69B,GAAe7xC,EAAgBwG,EAAiCuN,GACvE,GAAIi2B,GAAexjC,IAAYyjC,GAAajqC,GAC1C,OAAO,EAET,IAAK4xC,GAAgB5xC,GACnB,OAAO,EAET,MAAMqqC,EAAexjC,OAAO7G,GAC5B,OAAO6G,OAAO4D,SAAS4/B,IAAiBA,GAAgBt2B,CAC1D,CAkBA,SAAS69B,GAAgB5xC,GACvB,OAAOA,UAA2D,iBAAVA,GAAsB0I,QAAQ1I,EAAMmK,QAC9F,CASA,SAASgpC,GAAkBnzC,GACzB,OAAIiqC,GAAajqC,GACRA,EAEFA,EAAMmK,OAAStD,OAAO7G,GAAS,EACxC,CAEA,SAASszC,GAAkBtzC,GACzB,MAAqB,iBAAVA,EACM,IAARA,WAEFA,EAAsB,GAAKA,CACpC,CAMA,SAASsyC,GAAqBx9C,GAC5B,GAA4B,iBAAjBA,EACT,MAAO,CAAExD,KAAMwD,GAEjB,GAAIA,GAAsE,iBAA9CA,EAAqCxD,KAAmB,CAClF,MAAMA,KAAEA,EAAAW,OAAMA,GAAW6C,EACzB,MAAO,CAAExD,OAAMW,SACjB,CACA,OAAO,IACT,CAEA,SAASmgD,GAAoBz9C,GAC3B,OAAOqO,MAAMkD,KAAK,IAAIN,IAAIjR,EAAc5D,IAAK+D,GAAiB,CAACA,EAAaxD,KAAMwD,KAAgBqR,SACpG,CAEA,SAAS+pC,GAAc/pC,GACrB,OAAKnD,MAAMC,QAAQkD,GAGZnD,MAAMkD,KAAK,IAAIzE,IAAI0E,EAAO/V,OAAQ4P,GAA4C,iBAAVA,GAAsB0I,QAAQ1I,MAFhG,EAGX,CC/zBA,SAASwQ,GAAYxQ,GACnB,MAAiB,KAAVA,SAA2B6G,OAAO7G,EAC3C,CAEO,MAAMq0C,WAAmClhD,GAAMC,UAA/C,WAAA5B,GAAAyjB,SAAA8C,WAILrnB,KAAO2D,MAA0C,CAAE1D,aAAc,GAAIyH,SAAS,GAM9E1H,KAAO4jD,iBAAmB,KACxB5jD,KAAKqd,SAAS,CAAE3V,SAAS,KACxB1H,KAAKsH,MAAMu8C,QAAU,IAAI/jD,IAAwBC,mBAAmBR,KAAMU,IACzE,MAAMya,EAAUymB,GACdlhC,EAAaP,OAAQQ,GAAgBA,EAAYM,UAAYR,KAAKsH,MAAM9G,UAE1ER,KAAKqd,SAAS,CACZpd,aAAcya,EACdhT,SAAS,IAEX1H,KAAK8jD,qBAAqBppC,MAI9B1a,KAAQob,OAAU4T,IAChBhvB,KAAKsH,MAAMiT,SAAS,IAAKva,KAAKsH,MAAMy4C,UAAW/wB,KAGjDhvB,KAAQ+jD,kBAAoB,CAAC9jD,EAAeD,KAAK2D,MAAM1D,gBACrD,MAAMC,YAAEA,EAAAghC,gBAAaA,EAAA+D,eAAiBA,GAAmBjlC,KAAKsH,MAAMy4C,OACpE,GAAI9a,EACF,OAAOA,EAET,GAAI,MAAA/kC,OAAA,EAAAA,EAAaoE,SAAS,KACxB,OAAOpE,EAET,MAAM8jD,EAAU/jD,EAAaP,OAC1Byc,GAAWA,EAAOvb,OAASV,KAAiBghC,GAAmB/kB,EAAOqlB,OAASN,IAElF,OAA0B,IAAnB8iB,EAAQ9/C,OAAe8/C,EAAQ,GAAGjhD,SAAW,GACtD,CAlCO,iBAAA8hB,GACL7kB,KAAK4jD,kBACP,CAkCQ,oBAAAE,CAAqB7jD,GAC3B,MAAMglC,EAAiBjlC,KAAK+jD,kBAAkB9jD,GAC9C,IAAKglC,EACH,OAEF,MAAMhE,gBAAEA,EAAAC,gBAAiBA,GAAoBL,GAAoBoE,GAE/DjlC,KAAKsH,MAAMy4C,OAAO9a,iBAAmBA,GACrCjlC,KAAKsH,MAAMy4C,OAAO7/C,cAAgB+gC,GAClCjhC,KAAKsH,MAAMy4C,OAAO7e,kBAAoBA,GAEtClhC,KAAKob,OAAO,CAAE6pB,iBAAgB/kC,YAAa+gC,EAAiBC,mBAEhE,CAEO,MAAAlc,GAhFT,IAAAhhB,EAiFI,MAAM+7C,OAAEA,GAAW//C,KAAKsH,MAExB,wBACG,MAAA,CAAIyD,UAAU,kDACbtI,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,gBAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,eACZuP,SAAUta,KAAK2D,MAAM+D,QACrB4H,MAAOtP,KAAK+jD,oBACZxpC,SAAWwB,IACT,MAAMkpB,EAAiBlpB,EAAMlQ,OAAOyD,MACpC,IAAK21B,EAEH,YADAjlC,KAAKob,OAAO,CAAE6pB,oBAAgB,EAAW/kC,iBAAa,EAAWghC,qBAAiB,IAGpF,MAAMD,gBAAEA,EAAAC,gBAAiBA,GAAoBL,GAAoBoE,GACjEjlC,KAAKob,OAAO,CAAE6pB,iBAAgB/kC,YAAa+gC,EAAiBC,sBAG9Dz+B,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBtP,KAAK2D,MAAM1D,aAAaI,IAAKH,GAC5BuC,GAAAyE,cAAC,SAAA,CAAOlF,IAAK9B,EAAY6C,SAAUuM,MAAOpP,EAAY6C,UACnD7C,EAAY6wB,iBAMvBtuB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,iBAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,wBACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,gBACZ4D,IAAK,WACLkL,IAAK,EACL1a,KAAK,SACLmQ,MAAO,OAAAtL,EAAA+7C,EAAO7a,iBAAPlhC,EAA0B,GACjCuW,SAAWwB,GAAU/b,KAAKob,OAAO,CAAE8pB,gBAAiBplB,GAAY/D,EAAMlQ,OAAOyD,WAE/E7M,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,qBAAoB,aAGxCtI,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,4BACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACVuP,SAAUta,KAAK2D,MAAM+D,QACrBvI,KAAK,SACLyf,QAAS5e,KAAK4jD,kBACf,2BAOX,ECxFK,IAAKK,IAAAA,IACVA,EAAA,KAAO,OACPA,EAAA,SAAW,wBAFDA,IAAAA,IAAA,CAAA,GCrBZ,SAASC,GAAUx9C,EAAoCvH,GAhCvD,IAAA6E,EAiCE,MAAO,CACL7E,OACAsH,cAAe,MACfsP,YAAarP,EAAYlG,QACzBe,OAAQ,OAAAyC,EAAA0C,EAAYnF,QAAZyC,EAAsB0C,EAAYK,KAC1CD,gBAAiBJ,EAAY9F,KAEjC,CAEA,SAASujD,GAA2BpE,GAGlC,MAAMqE,EAAmC,CAAA,EAMzC,MALC,CAAC,cAAe,kBAAmB,iBAAkB,mBAA6BriD,QAAS+V,aACtFioC,EAAOjoC,KACRssC,EAAkBtsC,GAASioC,EAAOjoC,MAGhCssC,CACT,yFAEO,MAAMC,GACX,8BAAcC,CACZj/C,EACAqB,EACAsiC,EACA3mC,EAA+B,CAAA,GAE/B,OAAO0e,EAAaD,YAAY,CAC9Bzb,cACAqH,YAAa,yBAAyBhG,EAAY9F,OAClDqP,IAAK,CAAC,IAAKi0C,GAAUx9C,EAAa,uBAAwBsiC,uBAAsB3mC,KAEpF,CAEA,8BAAckiD,CAAwBl/C,EAA0BqB,GAC9D,OAAOqa,EAAaD,YAAY,CAC9Bzb,cACAqH,YAAa,yBAAyBhG,EAAY9F,OAClDqP,IAAK,CAACi0C,GAAUx9C,EAAa,yBAEjC,CAEA,8BAAc89C,CACZn/C,EACAqB,EACAs+B,GAEA,OAAOjkB,EAAaD,YAAY,CAC9Bzb,cACAqH,YAAa,6BAA6BhG,EAAY9F,OACtDqP,IAAK,CACH,IACKi0C,GAAUx9C,EAAa,uBAC1Bs+B,kBAAmBmf,GAA2Bnf,MAItD,CAEA,8BAAcyf,CAAwBp/C,EAA0BqB,GAC9D,OAAOqa,EAAaD,YAAY,CAC9Bzb,cACAqH,YAAa,6BAA6BhG,EAAY9F,OACtDqP,IAAK,CAAC,IAAKi0C,GAAUx9C,EAAa,uBAAwB+9C,yBAAyB,KAEvF,ECpFF,MAAMC,2/TAQN,SAAS5kC,GAAYxQ,GACnB,MAAiB,KAAVA,SAA2B6G,OAAO7G,EAC3C,CAEA,SAASq1C,GAAar1C,GACpB,YAAiB,IAAVA,EAAsB,GAAa,IAARA,CACpC,CAEO,SAASs1C,IAA2B7E,OACzCA,EAAAxlC,SACAA,EAAAsqC,6BACAA,EAA+B7sC,QAAQ4N,GAAoBC,QAAQi/B,yBAlCrE,IAAA9gD,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAAA4Y,EAAAC,EAAAC,EAoCE,MAAMz6B,EAAS,CAAwCpZ,EAAQsN,KAC7DiL,EAAS,IAAKwlC,EAAQ/9C,CAACA,GAAMsN,KAEzBy1C,EAAgBhF,EAAOiF,0BAA4B,GACnDC,EAAYlF,EAAOmF,kBAAoB,GACvCC,EAAsBntC,QAAQ+nC,EAAOqF,gBAAkBlkD,OAAOY,KAAKi+C,EAAOqF,gBAAgBlhD,QAC1FmhD,EAAgCrtC,QACpC+nC,EAAOuF,0BAA4BpkD,OAAOY,KAAKi+C,EAAOuF,0BAA0BphD,QAE5EqhD,EAA6E,iBAAxD,OAAAj9C,EAAA,OAAAtE,EAAA+7C,EAAOyF,yBAAgBC,4BAAvBn9C,EAA4Co9C,SAAuB,UAAY,QACpGC,EAAiB,OAAAr8C,EAAA,OAAAD,EAAA02C,EAAOyF,qBAAP,EAAAn8C,EAAuBo8C,0BAAvB,EAAAn8C,EAA6Ci8C,GAE9DK,EAAqB,CAACjwC,EAAeqZ,KACzC5T,EACE,2BACA2pC,EAAc1kD,IAAI,CAACwlD,EAAQC,IAAiBA,IAAgBnwC,EAAQ,IAAKkwC,KAAW72B,GAAY62B,KAG9FE,EAAiB,CAACpwC,EAAeqZ,KACrC5T,EACE,mBACA6pC,EAAU5kD,IAAI,CAAC2lD,EAAUC,IAAmBA,IAAkBtwC,EAAQ,IAAKqwC,KAAah3B,GAAYg3B,KAqBxG,OACEvjD,GAAAyE,cAAC,OAAI6D,UAAU,kEACZ,KAAA,KAAG,YACJtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAAyB,+BAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,mBACZ8O,IAAK,EACL1a,KAAK,SACLmQ,MAAO,OAAAkL,EAAAulC,EAAOmG,gBAAP1rC,EAAyB,GAChCD,SAAWwB,GAAUX,EAAO,iBAAkB0E,GAAY/D,EAAMlQ,OAAOyD,YAI7E7M,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,+BAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,mBACZ8O,IAAK,OAAAkjB,EAAAgjB,EAAOmG,gBAAPnpB,EAAyB,EAC9B59B,KAAK,SACLmQ,MAAO,OAAAqmC,EAAAoK,EAAOoG,gBAAPxQ,EAAyB,GAChCp7B,SAAWwB,GAAUX,EAAO,iBAAkB0E,GAAY/D,EAAMlQ,OAAOyD,YAI7E7M,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,8BAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,WACZ8O,IAAK,GACL1a,KAAK,SACLmQ,MAAO,OAAAsmC,EAAAmK,EAAOqG,mBAAPxQ,EAA4B,GACnCr7B,SAAWwB,GAAUX,EAAO,oBAAqB0E,GAAY/D,EAAMlQ,OAAOyD,YAIhF7M,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,QAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,OACZuE,MAAOywC,EAAOrsC,MAAQ,KACtB6G,SAAWwB,GAAUX,EAAO,OAAQW,EAAMlQ,OAAOyD,QAEjD7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,MAAK,MACnB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,OAAM,OACpB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,kBAAiB,qBAKrC7M,GAAAyE,cAAC,UAAG,WACHi+C,EACC1iD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAAyB,8BAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,aACZ4D,IAAK,GACLkL,IAAK,EACL1a,KAAK,SACLmQ,MAAOq1C,GAAa5E,EAAOqF,eAAeiB,mBAC1C9rC,SAAWwB,GACTX,EAAO,iBAAkB,IACpB2kC,EAAOqF,eACViB,kBACyB,KAAvBtqC,EAAMlQ,OAAOyD,aAA4BwQ,GAAY/D,EAAMlQ,OAAOyD,OAAoB,yBAI7F,SAAA,CAAOvE,UAAU,eAAe5L,KAAK,SAASyf,QAAS,IAAMxD,EAAO,iBAAkB,CAAA,IAAK,sBAI7FypC,oBACE,MAAA,CAAI95C,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACC,cAAY,yBACZ/H,KAAK,WACLkhB,QAAS0/B,EAAOqF,eAAekB,mBAAqBrC,GAAoBsC,SACxEhsC,SAAWwB,GACTX,EAAO,iBAAkB,IACpB2kC,EAAOqF,eACVkB,iBAAkBvqC,EAAMlQ,OAAOwU,QAAU4jC,GAAoBsC,SAAWtC,GAAoBuC,SAG/F,IAAI,mCAOf/jD,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV5L,KAAK,SACLyf,QAAS,IAAMxD,EAAO,iBAAkB,CAAEirC,uBAAmB,KAC9D,8BAKFhB,EACC5iD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,kCAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,iBACZ4D,IAAK,GACLkL,IAAK,EACL1a,KAAK,SACLmQ,MAAOq1C,GAAa5E,EAAOuF,yBAAyBe,mBACpD9rC,SAAWwB,GACTX,EAAO,2BAA4B,CACjCirC,kBACyB,KAAvBtqC,EAAMlQ,OAAOyD,aAA4BwQ,GAAY/D,EAAMlQ,OAAOyD,OAAoB,QAI9F7M,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,eAAe5L,KAAK,SAASyf,QAAS,IAAMxD,EAAO,2BAA4B,KAAK,uCAM1G3Y,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV5L,KAAK,SACLyf,QAAS,IAAMxD,EAAO,2BAA4B,CAAEirC,uBAAmB,KACxE,kCAKFtB,EAAc1kD,IAAI,CAACwlD,EAAQlwC,KA9NlC,IAAA3R,EAAAsE,EA+NQ,OAAA7F,GAAAyE,cAAC,WAAA,CAASlF,IAAK2T,EAAO5K,UAAU,iCAC7B,SAAA,KAAO,iBAAe4K,EAAQ,GAC/BlT,GAAAyE,cAAC,QAAA,CACC,aAAW,oBACX6D,UAAU,wBACV,cAAa,sBAAsB4K,IACnC8wC,YAAY,oBACZn3C,MAAOu2C,EAAOA,QAAU,GACxBtrC,SAAWwB,GAAU6pC,EAAmBjwC,EAAO,CAAEkwC,OAAQ9pC,EAAMlQ,OAAOyD,UAExE7M,GAAAyE,cAAC,QAAA,CACC,aAAW,+BACX6D,UAAU,wBACV07C,YAAY,+BACZn3C,MAAOu2C,EAAOnmD,QAAU,GACxB6a,SAAWwB,GAAU6pC,EAAmBjwC,EAAO,CAAEjW,OAAQqc,EAAMlQ,OAAOyD,UAExE7M,GAAAyE,cAAC,SAAA,CACC,aAAW,sBACX6D,UAAU,wBACVuE,MAAOu2C,EAAOa,mBAAqB,GACnCnsC,SAAWwB,IACT,MAAM2qC,EAAoB3qC,EAAMlQ,OAAOyD,OAErCq3C,cAAeC,EACfC,yBAA0BC,KACvBC,GACDlB,EACJzqC,EACE,2BACA2pC,EAAc1kD,IAAI,CAAC2mD,EAAclB,IAC/BA,IAAgBnwC,EACU,6BAAtB+wC,EACE,IAAKK,EAAkBL,qBACvB,IAAKM,EAAcN,oBAAmBC,cAAe,sBACvDK,MAKVvkD,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,uBACjB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,4BAA2B,4BACzC7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,gCAA+B,iCAEjB,iCAA7Bu2C,EAAOa,mBACNjkD,GAAAyE,cAAC,SAAA,CACC,aAAW,iBACX6D,UAAU,wBACVuE,MAAOu2C,EAAOc,eAAiB,GAC/BpsC,SAAWwB,GApNiB,EAACpG,EAAegxC,KACtD,MAAMd,EAASd,EAAcpvC,GAC7B,IAAIoxC,EACJ,GAAsB,+BAAlBJ,EAAgD,CAClD,MAAQN,kBAAmBY,EAASC,sBAAuBC,KAAUC,GAAqBvB,EAC1FkB,EAAmBK,CACrB,KAAO,CACL,MAAQP,yBAA0BC,KAAgBO,GAAsBxB,EACxEkB,EAAmBM,CACrB,CACAjsC,EACE,2BACA2pC,EAAc1kD,IAAI,CAAC2mD,EAAclB,IAC/BA,IAAgBnwC,EAAQ,IAAKoxC,EAAkBJ,iBAAkBK,KAuMtCM,CAAgC3xC,EAAOoG,EAAMlQ,OAAOyD,QAEzE7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,sBAAqB,sBACnC7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,8BAA6B,+BAGrB,+BAAzBu2C,EAAOc,cACNlkD,GAAAyE,cAAC,QAAA,CACC,aAAW,6BACX6D,UAAU,wBACV8O,IAAK,EACL1a,KAAK,SACLmQ,MAAO,OAAAtL,EAAA6hD,EAAOgB,0BAAP7iD,EAAmC,GAC1CuW,SAAWwB,GACT6pC,EAAmBjwC,EAAO,CAAEkxC,yBAA0B/mC,GAAY/D,EAAMlQ,OAAOyD,WAInF7M,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,QAAA,CACC,aAAW,qBACX6D,UAAU,wBACV,cAAa,wBAAwB4K,IACrCxW,KAAK,SACLmQ,MAAO,OAAAhH,EAAAu9C,EAAOQ,mBAAP/9C,EAA4B,GACnCiS,SAAWwB,GAAU6pC,EAAmBjwC,EAAO,CAAE0wC,kBAAmBvmC,GAAY/D,EAAMlQ,OAAOyD,WAE/F7M,GAAAyE,cAAC,SAAA,CACC,aAAW,0BACX6D,UAAU,wBACVuE,MAAOu2C,EAAOqB,uBAAyB,GACvC3sC,SAAWwB,GACT6pC,EAAmBjwC,EAAO,CAAEuxC,sBAAuBnrC,EAAMlQ,OAAOyD,SAGlE7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,sBACjB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,SAAQ,SACtB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,oBAAmB,kBACjC7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,oBAAmB,oBAIvC7M,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV5L,KAAK,SACLyf,QAAS,IACPxD,EACE,2BACA2pC,EAAcrlD,OAAO,CAAC6D,EAAGuiD,IAAgBA,IAAgBnwC,KAG9D,2BAKLlT,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV5L,KAAK,SACLyf,QAAS,IAAMxD,EAAO,2BAA4B,IAAI2pC,EAAe,CAAA,KACtE,sCAIA,KAAA,KAAG,qBACJtiD,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,mBACftI,GAAAyE,cAAC,QAAA,CACC,cAAY,mBACZ/H,KAAK,WACLkhB,QAASrI,QAAQ+nC,EAAOyF,gBACxBjrC,SAAWwB,GACTX,EACE,iBACAW,EAAMlQ,OAAOwU,QAAU,CAAEolC,oBAAqB,CAAEC,QAAS,GAAK6B,cAAe,SAAO,KAGvF,IAAI,4BAGRxH,EAAOyF,iCACL,MAAA,CAAIz6C,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAAyB,0BAC1CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV,cAAY,mBACZ8O,IAAK,EACL1a,KAAK,SACLmQ,MAAO,MAAAq2C,EAAAA,EAAkB,GACzBprC,SAAWwB,GACTX,EAAO,iBAAkB,IACpB2kC,EAAOyF,eACVC,oBAAqB,CAAEF,CAACA,GAAczlC,GAAY/D,EAAMlQ,OAAOyD,YAIrE7M,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV,cAAY,gBACZuE,MAAOi2C,EACPhrC,SAAWwB,GACTX,EAAO,iBAAkB,IACpB2kC,EAAOyF,eACVC,oBAAqB,CAAE,CAAC1pC,EAAMlQ,OAAOyD,OAAQq2C,MAIjDljD,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,WAAU,WACxB7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,SAAQ,UAExB7M,GAAAyE,cAAC,QAAA,CACC,aAAW,kCACX6D,UAAU,wBACV4D,IAAK,KACLkL,IAAK,GACL1a,KAAK,SACLmQ,MAAO,OAAAumC,EAAAkK,EAAOyF,eAAe+B,eAAtB1R,EAAuC,GAC9Ct7B,SAAWwB,GACTX,EAAO,iBAAkB,IAAK2kC,EAAOyF,eAAgB+B,cAAeznC,GAAY/D,EAAMlQ,OAAOyD,aAOvG7M,GAAAyE,cAAC,KAAA,KAAG,qBACH+9C,EAAU5kD,IAAI,CAAC2lD,EAAUrwC,KA9YhC,IAAA3R,EAAAsE,EAAAe,EA+YQ,OAAA5G,GAAAyE,cAAC,WAAA,CAASlF,IAAK2T,EAAO5K,UAAU,iCAC7B,SAAA,KAAO,YAAU4K,EAAQ,GAC1BlT,GAAAyE,cAAC,QAAA,CACC,aAAW,gBACX6D,UAAU,wBACVuE,MAAO02C,EAASwB,cAAgB,GAChCjtC,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAE6xC,aAAczrC,EAAMlQ,OAAOyD,UAE1E7M,GAAAyE,cAAC,QAAA,CACC,aAAW,uBACX6D,UAAU,wBACVuE,MAAO02C,EAASyB,qBAAuB,GACvCltC,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAE8xC,oBAAqB1rC,EAAMlQ,OAAOyD,UAEjF7M,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,mBACftI,GAAAyE,cAAC,QAAA,CACC,cAAa,oBAAoByO,IACjCxW,KAAK,WACLkhB,QAAS,OAAArc,EAAAgiD,EAAS0B,UAAT1jD,EACTuW,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAE+xC,QAAS3rC,EAAMlQ,OAAOwU,YAClE,IAAI,WAGT5d,GAAAyE,cAAC,QAAA,CACC,aAAW,6BACX6D,UAAU,wBACV,cAAa,oBAAoB4K,IACjCkE,IAAK,EACL1a,KAAK,SACLmQ,MAAO,OAAAhH,EAAA09C,EAAS2B,0BAATr/C,EAAqC,GAC5CiS,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAEgyC,yBAA0B7nC,GAAY/D,EAAMlQ,OAAOyD,WAElG7M,GAAAyE,cAAC,QAAA,CACC,aAAW,kBACX6D,UAAU,wBACVuE,MAAO02C,EAAS4B,cAAgB,GAChCrtC,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAEiyC,aAAc7rC,EAAMlQ,OAAOyD,UAE1E7M,GAAAyE,cAAC,SAAA,CACC,aAAW,YACX6D,UAAU,wBACV,cAAa,qBAAqB4K,IAClCrG,MAAO02C,EAAS6B,UAAY,GAC5BttC,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAEkyC,SAAU9rC,EAAMlQ,OAAOyD,SAEpE7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,oBAChBo1C,GAAUrkD,IAAKwnD,GACdplD,GAAAyE,cAAC,SAAA,CAAOlF,IAAK6lD,EAAUv4C,MAAOu4C,GAC3BA,KAIPplD,GAAAyE,cAAC,QAAA,CACC,aAAW,sBACX6D,UAAU,wBACV8O,IAAK,IACL1a,KAAK,SACLmQ,MAAO,OAAAjG,EAAA28C,EAAS8B,UAATz+C,EAAqB,GAC5BkR,SAAWwB,GAAUgqC,EAAepwC,EAAO,CAAEmyC,SAAUhoC,GAAY/D,EAAMlQ,OAAOyD,WAElF7M,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV5L,KAAK,SACLyf,QAAS,IACPxD,EACE,mBACA6pC,EAAUvlD,OAAO,CAAC6D,EAAG0iD,IAAkBA,IAAkBtwC,KAG9D,sBAKLlT,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,eAAe5L,KAAK,SAASyf,QAAS,IAAMxD,EAAO,mBAAoB,IAAI6pC,EAAW,CAAA,KAAM,wBAKpH,CChdA,SAAS8C,GAAiBz4C,EAAgB+T,EAAiBC,EAH3C,YAId,MACmB,iBAAVhU,GACP6G,OAAO4D,SAASzK,IAChB6G,OAAOiG,UAAU9M,IACjBA,GAAS+T,GACT/T,GAASgU,CAEb,CAEA,SAAS0kC,GAAoB14C,EAAgBgU,GAC3C,MAAwB,iBAAVhU,GAAsB6G,OAAO4D,SAASzK,IAAUA,EAAQ,aAAMgU,GAAyBhU,EAAQgU,EAC/G,CAEA,SAAS2kC,GAAoBpC,GA5B7B,IAAA7hD,EA6BE,UAAK,OAAAA,EAAA6hD,EAAOA,iBAAQpsC,UAAWosC,EAAOa,qBAIP,iCAA7Bb,EAAOa,mBACkB,+BAAzBb,EAAOc,cAGsC,iBAApCd,EAAOgB,0BACd1wC,OAAO4D,SAAS8rC,EAAOgB,2BACvBhB,EAAOgB,0BAA4B,GAGN,iCAA7BhB,EAAOa,mBAAiF,uBAAzBb,EAAOc,iBAGnEqB,GAAoBnC,EAAOQ,oBAAsBruC,QAAQ6tC,EAAOqB,wBACzE,CA+CO,MAAMgB,WAAiBpR,GAAvB,WAAAh2C,GAAAyjB,SAAA8C,WA0DLrnB,KAAQ+5C,SAAW,CAACjiC,EAAexI,KACjCtP,KAAKsH,MAAM0vC,OAAOgD,cAAcliC,EAAOxI,IAGzCtP,KAAQmoD,kBAAqBT,IA3J/B,IAAA1jD,EAAAsE,EAAAe,EAAAC,EAAAkR,EA4JI,MAAM/E,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxBoR,EAAkB3yC,EAAOuzB,kBAK/B,GAJAhpC,KAAK+5C,SACH,sCACC2N,GAAsC,WAA3B,OAAA1jD,EAAAyR,EAAO+uB,oBAAW9wB,OAAoBsE,QAAQowC,IAExDV,EAAS,CACX,MAAMjyB,EAAU,OAAApsB,EAAA,OAAAf,EAAAmN,EAAO8f,eAAP,EAAAjtB,EAAiBmtB,SAAjBpsB,EAA4B,EAS5C,YARArJ,KAAKqoD,qBACHD,GAAmB,CACjBlC,eAAgBzwB,EAChB0wB,eAAgB1wB,EAChB2wB,kBAAmB,GACnBhB,eAAgB,CAAEiB,kBAAmB,KAI3C,CAEArmD,KAAK+5C,SAAS,qBAAqB,GACnC/5C,KAAK+5C,SAAS,oBAAqB,MACnC/5C,KAAK+5C,SAAS,SAAU,IAAKtkC,EAAOoH,OAAQya,mBAAmB,IAC/Dt3B,KAAK+5C,SAAS,YAAa,IAAKtkC,EAAO+uB,UAAW0D,mBAAmB,IACrE,MAAMzS,EAAU,OAAAjb,EAAA,OAAAlR,EAAAmM,EAAO8f,eAAP,EAAAjsB,EAAiBmsB,SAAjBjb,EAA4B,EAC5Cxa,KAAK+5C,SAAS,WAAY,CAAElgC,IAAK4b,EAAS9mB,IAAK8mB,EAASA,aAG1Dz1B,KAAQqoD,qBAAwBtI,IAvLlC,IAAA/7C,EAwLI,MAAMyR,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxBn9B,EAAMkmC,EAAOmG,eACbv3C,EAAMoxC,EAAOoG,eACb1wB,EAoGV,SAAiCA,EAAc5b,EAAUlL,GA/RzD,IAAA3K,EAAAsE,EAgSE,GAAuB,iBAAZmtB,GAAuC,iBAAR5b,GAAmC,iBAARlL,EACnE,OAAOD,KAAKmL,IAAIlL,EAAKD,KAAKC,IAAIkL,EAAK4b,IAErC,OAAO,OAAAntB,EAAA,OAAAtE,EAAA,MAAAyxB,EAAAA,EAAW5b,GAAX7V,EAAkB2K,GAAlBrG,EAAyB,CAClC,CAzGoBggD,CAAwB,OAAAtkD,EAAAyR,EAAO8f,eAAP,EAAAvxB,EAAiByxB,QAAS5b,EAAKlL,GAEvE3O,KAAK+5C,SAAS,qBAAqB,GACnC/5C,KAAK+5C,SAAS,oBAAqBgG,GACnC//C,KAAK+5C,SAAS,SAAU,IAAKtkC,EAAOoH,OAAQya,mBAAmB,IAC/Dt3B,KAAK+5C,SAAS,YAAa,IAAKtkC,EAAO+uB,UAAW0D,mBAAmB,IACrEloC,KAAK+5C,SAAS,WAAY,IAAKtkC,EAAO8f,SAAU1b,MAAKlL,MAAK8mB,aAG5Dz1B,KAAQuoD,kBAAqBb,IApM/B,IAAA1jD,EAqMI,MAAMyR,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxBoR,EAAkB3yC,EAAOuvB,kBAC/BhlC,KAAK+5C,SAAS,oBAAqB2N,GACnC1nD,KAAK+5C,SACH,sCACC2N,GAAsC,WAA3B,OAAA1jD,EAAAyR,EAAO+uB,oBAAW9wB,OAAoBsE,QAAQowC,IAExDV,IAAYU,GACdpoD,KAAK+5C,SAAS,oBAAqB,CAAE7U,gBAAiB,MAE1D,CAjHO,QAAAgS,CAASzhC,GA9FlB,IAAAzR,EAAAsE,EA+FI,MAAMiR,EAAiC,CAAA,EAEvC,GAAI9D,EAAOuzB,kBAAmB,CAC5B,MAAM+W,EAAStqC,EAAOuzB,kBAChB8X,EAA0C,CAAA,EAC1C0H,EAAeT,GAAiBhI,EAAOmG,eAAgB,GACvDuC,EAAeV,GAAiBhI,EAAOoG,eAAgB,GACxDqC,IACH1H,EAAaoF,eAAiB,mDAE3BuC,EAEMD,GAAgBzI,EAAOoG,eAAiBpG,EAAOmG,iBACxDpF,EAAaqF,eAAiB,2DAF9BrF,EAAaqF,eAAiB,kDAI3B4B,GAAiBhI,EAAOqG,kBAAmB,MAC9CtF,EAAasF,kBAAoB,+DA/DzC,SAAyBrG,GAhDzB,IAAA/7C,EAAAsE,EAiDE,MAAMogD,EAAgB1wC,QAAQ+nC,EAAOqF,gBAAkBlkD,OAAOY,KAAKi+C,EAAOqF,gBAAgBlhD,QACpFykD,EAA0B3wC,QAC9B+nC,EAAOuF,0BAA4BpkD,OAAOY,KAAKi+C,EAAOuF,0BAA0BphD,QAE5E6gD,EAAgBhF,EAAOiF,0BAA4B,GACnD4D,GAAYF,GAAiBV,GAAoB,OAAAhkD,IAAOohD,qBAAP,EAAAphD,EAAuBqiD,kBAAmB,GAC3FwC,GACHF,GAA2BX,GAAoB,OAAA1/C,IAAOg9C,+BAAP,EAAAh9C,EAAiC+9C,kBAAmB,GACtG,OACEuC,GACAC,GACA9D,EAAcjmB,MAAMmpB,MAClBS,GAAiBE,GAChBD,GAA2BE,GAC3B9D,EAAc7gD,OAAS,GAAK6gD,EAAcjmB,MAAMmpB,IAEvD,CAgDWa,CAAgB/I,KACnBe,EAAa+E,OAAS,sDA/C9B,SAA2B9F,GACzB,OAAQA,EAAOmF,kBAAoB,IAAIpmB,MACpCknB,IArEL,IAAAhiD,EAAAsE,EAAAe,EAsEM,OAAA2O,QAAQ,OAAAhU,EAAAgiD,EAASwB,mBAAT,EAAAxjD,EAAuByV,SAC/BsuC,GAAiB/B,EAAS2B,yBAA0B,EAAG5H,EAAOoG,iBAC9DnuC,QAAQ,OAAA1P,EAAA09C,EAAS4B,mBAAT,EAAAt/C,EAAuBmR,SAC/BzB,QAAQ,OAAA3O,EAAA28C,EAAS6B,iBAATx+C,EAAmBoQ,SAC3BsuC,GAAiB/B,EAAS8B,SAAU,IA9DJ,UAgEtC,CAwCWiB,CAAkBhJ,KACrBe,EAAaoE,iBAAmB,wEAvCxC,SAAgCnF,GAC9B,IAAKA,EAAOyF,eACV,OAAO,EAET,MAAMC,oBAAEA,EAAA8B,cAAqBA,GAAkBxH,EAAOyF,eAChDwD,OAA0C,WAA/BvD,WAAqBwD,OAChCC,OAA8C,WAAjCzD,WAAqBC,SACxC,QAAIsD,IAAaE,IAAenB,GAAiBR,EAAe,GAAI,SAG7D2B,EACHnB,GAAiB,MAAAtC,OAAA,EAAAA,EAAqBC,QAAS,EAAG,KAClDqC,GAAiB,MAAAtC,OAAA,EAAAA,EAAqBwD,MAAO,GACnD,CA4BWE,CAAuBpJ,KAC1Be,EAAa0E,eAAiB,0DAEN,OAAAxhD,EAAA+7C,EAAOqF,uBAAPphD,EAAuBsiD,oBAAqBrC,GAAoBsC,WAChE3gC,GAAoBC,QAAQi/B,wBACpDhE,EAAagE,sBAAwB,0CAEnC5jD,OAAOY,KAAKg/C,GAAc58C,SAC5BqV,EAAOyvB,kBAAoB8X,EAE/B,CAEA,GAAIrrC,EAAOg/B,kBAAmB,CAC5B,MAAMsL,EAAUtqC,EAAOuvB,mBAAqB,CAAA,EACtC8b,EAA0C,CAAA,GAC3C,OAAAx4C,EAAAy3C,EAAO7/C,oBAAPoI,EAAoBmR,UACvBqnC,EAAa5gD,YAAc,0BAExB6/C,EAAO7e,kBACV4f,EAAa5f,gBAAkB,+BAE5B6mB,GAAiBhI,EAAO7a,gBAAiB,KAC5C4b,EAAa5b,gBAAkB,sEAE7BhkC,OAAOY,KAAKg/C,GAAc58C,SAC5BqV,EAAOyrB,kBAAoB8b,EAE/B,CAEA,OAAOvnC,CACT,CA4DQ,yBAAA6vC,GAjNV,IAAAplD,EAAAsE,EAkNI,MAAMmN,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxB/2C,GAAe,OAAAqI,EAAA,OAAAtE,EAAAyR,EAAOo2B,sBAAa3hB,eAApB,EAAA5hB,EAA8BrI,eAAgB,GACnE,MAAO,CACLF,iBAAkB,IAChBwC,QAAQC,QACNvC,EAAaI,IAAKH,IAAA,IACbA,EACHM,QAASiV,EAAOM,gBAI1B,CAEO,MAAAiP,GA/NT,IAAAhhB,EAgOI,MAAMyR,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxBqS,EAAqBrxC,QAAQvC,EAAOuzB,mBACpCsgB,EAAqB,OAAAtlD,EAAAyR,EAAOg/B,mBAAPzwC,EAA4BgU,QAAQvC,EAAOuvB,mBAEtE,OACEviC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,kCAAkC,cAAY,qBAC3DtI,GAAAyE,cAAC,UAAA,KACCzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,OAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,uBAELzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASgpC,EACT,cAAY,qBACZ9uC,SAAWwB,GAAU/b,KAAKmoD,kBAAkBpsC,EAAMlQ,OAAOwU,SACzDlhB,KAAK,aAEPsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,WAAU,yBAI/Bs+C,GACC5mD,GAAAyE,cAAC09C,GAAA,CACC7E,OAAStqC,EAAOuzB,mBAAqB,CAAA,EACrCzuB,SAAUva,KAAKqoD,wBAKrB5lD,GAAAyE,cAAC,UAAA,sBACE,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,wCAEJ,MAAA,CAAI6D,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,KACCzE,GAAAyE,cAAC,QAAA,CACCmZ,QAASipC,EACT,cAAY,qBACZ/uC,SAAWwB,GAAU/b,KAAKuoD,kBAAkBxsC,EAAMlQ,OAAOwU,SACzDlhB,KAAK,aAEPsD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,WAAU,yBAI/Bu+C,GACC7mD,GAAAyE,cAACy8C,GAAA,CACC3hD,IAAKyT,EAAOM,aAAe,GAC3BvV,QAASiV,EAAOM,aAAe,GAC/BgqC,OAAStqC,EAAOuvB,mBAAqB,CAAA,EACrC6e,OAAQ7jD,KAAKopD,4BACb7uC,SAAWwlC,GAAW//C,KAAK+5C,SAAS,oBAAqBgG,MAMrE,ECzQK,MAAMwJ,WAAiCzS,GAAvC,WAAAh2C,GAAAyjB,SAAA8C,WAsBLrnB,KAAQwpD,cAAgB,CACtB1xC,EACAxI,EACA8mC,KAEA,MAAMtgC,EAAU,IAAK9V,KAAKsH,MAAM0vC,OAAOvhC,OAAQqC,CAACA,GAAQxI,GACxD,OAAOtP,KAAKo3C,wBACVthC,EACAmT,MAAOs0B,UAAyBv9C,KAAKi3C,QAAQd,oBAAoBoH,EAAenH,IAAUtgC,UAI9F9V,KAAQykB,eAAkBjkB,IACxB,MAAMsV,EAAU,IAAK9V,KAAKsH,MAAM0vC,OAAOvhC,OAAQM,YAAavV,GAC5D,OAAOR,KAAKo3C,wBAAwBthC,EAASmT,MAAOs0B,IAClD,MAAM1jB,QAAe13B,GAAeC,WAAW,CAAE5B,UAASZ,SAAU29C,EAAcxV,iBAAkB7oC,EAAG,MACjGuqD,EAAoB,IACrBlM,EACH1R,YAAa,IAAK0R,EAAc1R,YAAa6F,UAAW7X,IAE1D,aAAc75B,KAAKi3C,QAAQd,oBAAoBsT,EAAmB,uBAAuB3zC,WA8E7F9V,KAAQ0pD,gBAAkB,CAAC5zC,EAAiC+f,KA3I9D,IAAA7xB,EA4II,OAAAA,EAAA8R,EAAQ2gB,4BAAmB3gB,EAAS+f,GACpC71B,KAAKsH,MAAM0vC,OAAOgB,UAAU,IAAKliC,EAAS+f,SAAUA,EAAS7zB,OAG/DhC,KAAQ2pD,qBAAuB,CAAC7xC,EAAexI,KAC7CtP,KAAKsH,MAAM0vC,OAAOgD,cAAcliC,EAAOxI,GACzC,CA9HO,QAAA4nC,CAASzhC,GACd,MAAMm0C,EAAelU,GAA8BjgC,GAC7C8D,EAAiD,CAAA,EACnDqwC,EAAa7zC,cAAawD,EAAOxD,YAAc6zC,EAAa7zC,aAC5D6zC,EAAaroD,SAAQgY,EAAOhY,OAASqoD,EAAaroD,QAClDqoD,EAAa7iD,OAAMwS,EAAOxS,KAAO6iD,EAAa7iD,MAC9C6iD,EAAah7B,QAAOrV,EAAOqV,MAAQg7B,EAAah7B,OAChDg7B,EAAaxyB,kBAAiB7d,EAAO6d,gBAAkBwyB,EAAaxyB,iBACxE,MAAMyyB,EAAep0C,EAAO+uB,UAAU8G,kBAAoB,6BAA+B,iBACnFwe,EAAgBr0C,EAAO+uB,UAAU8G,kBAAoB,8BAAgC,kBAS3F,OAPI71B,EAAOmZ,QAAUi7B,EAAarmC,KAAK/N,EAAOmZ,SAC5CrV,EAAOqV,MAAQ,+CAEbnZ,EAAO2hB,kBAAoB0yB,EAActmC,KAAK/N,EAAO2hB,mBACvD7d,EAAO6d,gBAAkB,yDAGpB7d,CACT,CA0BQ,YAAAwwC,CACNjkD,EACAgS,EACA4C,EACAH,EACAvL,GAEA,MAAM7G,EAAK,oBAAoB2P,IACzB4qC,EAAU,GAAGv6C,UACb6hD,EAAahqD,KAAKsH,MAAM0vC,OAAOvhC,OAAOqC,GACtCxI,EAAkB,aAAVwI,EAAwBkyC,EAAa,WAAa,QAAWA,GAAc,GACzF,OACEvnD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAS1zC,GACjDrC,GAEHrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkB8H,EAAQ0zC,OAAU,EACpC,eAAc1qC,QAAQhJ,GACtB,aAAYlJ,EACZiF,UAAU,wBACV5C,KACAoS,SAAWwB,GACTxB,EAAWA,EAASwB,EAAMlQ,OAAOyD,OAAStP,KAAKsH,MAAM0vC,OAAOgD,cAAcliC,EAAOiE,EAAMlQ,OAAOyD,OAEhGA,SAEA7M,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBoL,EAAQra,IAAK8b,GACZ1Z,GAAAyE,cAAC,UAAOoT,SAAU6B,EAAOkhC,YAAar7C,IAAKma,EAAO7M,MAAOA,MAAO6M,EAAO7M,OACpE6M,EAAOrW,SAIbkJ,GACCvM,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAIu6C,EAAS36B,KAAK,SAC5C/Y,IAMb,CAEQ,eAAA+vB,CAAgBj5B,EAAegS,EAAoC9I,GACzE,MAAM7G,EAAK,oBAAoB2P,IACzB4qC,EAAU,GAAGv6C,UACnB,OACE1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAS1zC,GACjDrC,GAEHrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkB8H,EAAQ0zC,OAAU,EACpC,eAAc1qC,QAAQhJ,GACtB,aAAYlJ,EACZiF,UAAU,wBACV5C,KACAoS,SAAWwB,GAAU/b,KAAKsH,MAAM0vC,OAAOgD,cAAcliC,EAAOiE,EAAMlQ,OAAOyD,OACzEnQ,KAAK,OACLmQ,MAAOtP,KAAKsH,MAAM0vC,OAAOvhC,OAAOqC,IAAU,KAE3C9I,GACCvM,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAIu6C,EAAS36B,KAAK,SAC5C/Y,IAMb,CAWO,MAAAgW,GApJT,IAAAhhB,EAAAsE,EAqJI,MAAMmN,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxB9sB,GAAW,OAAAlmB,EAAAyR,EAAOo2B,kBAAP,EAAA7nC,EAAoBkmB,WAAY,CAAA,EAC3C5Z,EAAW25C,GAAiB,OAAA3hD,EAAAmN,EAAOo2B,kBAAP,EAAAvjC,EAAoBgI,SAAUmF,EAAOM,YAAa,CAAC,SAC/EvF,EAAUy5C,GAAiB//B,EAAS1Z,QAASiF,EAAOlU,OAAQ,CAAC,SAC7D0lC,EAAQgjB,GAAiB//B,EAAS+c,MAAOxxB,EAAO1O,KAAM,CAAC,SACvDwJ,EAAW05C,GAAiB//B,EAAS3Z,SAAUkF,EAAO3L,QAAS,CAAC,KAAM,SACtE2G,EAAUw5C,GAAiB//B,EAASzZ,QAASgF,EAAOzL,OAAQ,CAAC,KAAM,SACnEuP,EAASvZ,KAAKk3C,SAASzhC,GAE7B,OACEhT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,mCACZ/K,KAAK+pD,aAAa,UAAW,cAAez5C,EAAUtQ,KAAKykB,eAAgBlL,EAAOxD,aAClF/V,KAAK+pD,aACJ,SACA,SACAv5C,EACCjP,GAAWvB,KAAKwpD,cAAc,SAAUjoD,EAAQ,iBACjDgY,EAAOhY,QAERvB,KAAK+pD,aACJ,gBACA,WACA,CACE,CAAEjkD,MAAO,QAASwJ,MAAO,SACzB,CAAExJ,MAAO,WAAYwJ,MAAO,aAE7BoE,GAAS1T,KAAKwpD,cAAc,WAAqB,aAAT91C,EAAqB,qBAE9D+B,EAAOqxB,UACP9mC,KAAK+pD,aACH,OACA,OACA9iB,EACClgC,GAAS/G,KAAKwpD,cAAc,OAAQziD,EAAM,eAC3CwS,EAAOxS,MAEV/G,KAAK+pD,aAAa,UAAW,UAAWx5C,EAAWzG,GAClD9J,KAAKwpD,cAAc,UAAW1/C,EAAS,mBAExC9J,KAAK+pD,aAAa,SAAU,SAAUt5C,GACtCzQ,KAAK++B,gBAAgB,QAAS,QAASxlB,EAAOqV,OAC9C5uB,KAAK++B,gBAAgB,SAAU,kBAAmBxlB,EAAO6d,iBAC1D30B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,MAAA,CAAIA,UAAU,2BAA0B,WACzCtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,sCACZ,QAAA,KACCtI,GAAAyE,cAAC,QAAA,CACC,aAAW,wCACXmZ,SAAkC,IAAzB5K,EAAOqyB,cAChBvtB,SAAWwB,GAAU/b,KAAKsH,MAAM0vC,OAAOgD,cAAc,gBAAiBj+B,EAAMlQ,OAAOwU,SACnFlhB,KAAK,aACJ,IAAI,4CAKXsW,EAAO+uB,UAAU6D,0BAA4B5yB,EAAOsyB,kBACpDtlC,GAAAyE,cAAC,OAAI,aAAW,sBAAsB6gB,KAAK,SACzCtlB,GAAAyE,cAACovB,EAAA,CACCxgB,QAASL,EACT+gB,cAAex2B,KAAK2pD,qBACpBlzB,iBAAkBz2B,KAAK0pD,mBAI7BjnD,GAAAyE,cAACgjD,EAAA,CACCC,OAAQ10C,EAAO00C,QAAU,GACzB5vC,SAAW4vC,GAAWnqD,KAAKsH,MAAM0vC,OAAOgD,cAAc,SAAUmQ,KAIxE,EAGF,SAASF,GACPG,EACA9U,EACA+U,GAEA,MAAM50C,GAAU20C,GAAc,IAAI/pD,IAAK8b,GAazC,SAAqBA,EAAakuC,GAChC,GAAsB,iBAAXluC,EACT,OAAOA,EAET,OAAOkuC,EAAWhqD,IAAK2B,SAAQma,WAASna,IAAMyG,KAAKuP,UAAY,EACjE,CAlBoDsyC,CAAYnuC,EAAQkuC,IAAa3qD,OAAOsY,SAC1F,OAAOq9B,GACL5/B,EACA6/B,EACChmC,GAAUA,EACVA,GAAUA,GACXjP,IAAI,EAAGo1C,aAAYnmC,YAAM,CACzBxJ,MAAO2vC,EAAa,GAAGnmC,kBAAwBA,EAC/C+tC,YAAa5H,EACbnmC,UAEJ,CChOA,MAAMi7C,GAAqB,IAAIx5C,IAAI,CAAC,WAAY,MAAO,oBACjDy5C,GAAsB,iCAyB5B,SAASC,GAAqB/+C,GAC5B,MAAMg/C,EAAU,MAAAh/C,OAAA,EAAAA,EAAa+N,OAC7B,GAAKixC,EAGL,OAAOA,EAAQn8B,UAAUm8B,EAAQC,YAAY,KAAO,GAAGluB,aACzD,CAGA,SAASmuB,GAAsB7K,GAC7B,MAAM8K,MAAmB95C,IACzB,IAAA,MAAW+5C,KAAa5pD,OAAOuU,cAAOsqC,WAAQgL,qBAAsB,CAAA,GAClE,IAAA,MAAWr/C,KAAe,MAAAo/C,OAAA,EAAAA,EAAWD,eAAgB,GAAI,CACvD,MAAMG,EAAwBP,GAAqB/+C,GACnD,GAAIs/C,GAAyBH,EAAa54C,IAAI+4C,GAC5C,OAAO,EAELA,GACFH,EAAax5C,IAAI25C,EAErB,CAEF,OAAO,CACT,CAEA,SAASC,GAAaH,GACpB,OACqB,OAAnB,MAAAA,OAAA,EAAAA,EAAWI,OACV/0C,OAAO4D,SAAS+wC,EAAUI,OAAS/0C,OAAOiG,UAAU0uC,EAAUI,OAASJ,EAAUI,MAAQ,CAE9F,CAEO,SAASC,IAAiC5hB,0BAC/CA,EAAAzC,SACAA,EACAwC,YAAa8hB,EAAAC,gBACbA,EAAAC,6BACAA,IAEA,MAAMvL,EAASxW,GAA6B,CAAEwhB,mBAAoB,CAAA,GAC5D1yC,EAAUnX,OAAOmX,QAAQ0nC,EAAOgL,oBAAsB,CAAA,GACtDrD,EAAUrvC,EAAQnU,OAAS,EAC3BolC,GAAe8hB,GAAmB,IAAI3xC,OAAO5F,cAC7C03C,EAAmB7D,IAAY5gB,EAC/B0kB,EAAc9D,KAAape,GAA+B,SAAhBA,IAA2BihB,GAAmBt4C,IAAIq3B,IAC5FmiB,EAAwB/D,IAAYkD,GAAsB7K,GAE1D2L,EAAoBX,IACxBO,EAA6B,CAAEP,wBAG3BY,EAAe,KACnB,MAAMC,EAlEH,SAA2BC,GAChC,MAAMC,EAAO,IAAI/6C,IAAI86C,GACrB,IAAIl2C,EAAQ,EACZ,KAAOm2C,EAAK75C,IAAI,aAAa0D,MAC3BA,GAAS,EAEX,MAAO,aAAaA,GACtB,CA2DqBo2C,CAAkB7qD,OAAOY,KAAKi+C,EAAOgL,oBAAsB,CAAA,IAC5EW,EAAiB,IAAK3L,EAAOgL,mBAAoBa,CAACA,GAvE7C,CAAEf,aAAc,CAAC,QA6FlBmB,EAAkB,CAACprD,EAAckqD,KACrCY,EAAiB,IAAK3L,EAAOgL,mBAAoBnqD,CAACA,GAAOkqD,KAwC3D,OACEroD,GAAAyE,cAAC,OAAI6D,UAAU,+BACZ,MAAA,CAAIA,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,wBAAwB,qBAAEy0C,EAAA,CAAUxzC,GAAG,gEAE3C,MAAA,CAAI4C,UAAU,YACZsgD,GACC5oD,GAAAyE,cAAC,OAAI6D,UAAU,qBAAqB5C,GAAIqiD,GAAqBziC,KAAK,SAC/DsjC,IAGH3D,GACAjlD,GAAAyE,cAAC,UAAO/H,KAAK,SAAS4L,UAAU,yBAAyB6T,QAAS+sC,GAAc,0BAIjFjE,GACCjlD,GAAAyE,cAAC,MAAA,KACEqkD,GACC9oD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,uBAAsB,iDAEtCygD,GACC/oD,GAAAyE,cAAC,OAAI6D,UAAU,uBAAsB,mFAItC0gD,oBACE,MAAA,CAAI1gD,UAAU,sBAAsBgd,KAAK,SAAQ,4DAInD1P,EAAQhY,IAAI,EAAEO,EAAMkqD,sBAClB,MAAA,CAAI9oD,IAAKpB,EAAMmK,UAAU,eAAeoX,MAAO,CAAEoP,aAAc,QAAU,sBAAqB3wB,SAE3F,MAAMqrD,EAAc,kCAAkCphD,mBAAmBjK,KACnEsrD,GAAejB,GAAaH,GAClC,yCAEIroD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAS,GAAGoQ,UAAoB,kBAG3ExpD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACCiB,GAAI,GAAG8jD,SACPlhD,UAAU,wBACVstB,aAAcz3B,EACdurD,OAAShhC,IArGX,EAACihC,EAAiBC,KACxC,MAAM3B,EAAU2B,EAAQ5yC,OACxB,IAAKixC,GAAWA,IAAY0B,GAAWrM,EAAOgL,mBAAmBL,GAC/D,OAAO,EAET,MAAM4B,EAAkD,CAAA,EAKxD,OAJAprD,OAAOmX,QAAQ0nC,EAAOgL,oBAAoBhpD,QAAQ,EAAEnB,EAAMkqD,MACxDwB,EAAK1rD,IAASwrD,EAAU1B,EAAU9pD,GAAQkqD,IAE5CY,EAAiBY,IACV,GA4FwBC,CAAgB3rD,EAAMuqB,EAAES,cAActc,SACzC6b,EAAES,cAActc,MAAQ1O,OAKhC6B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,yBACV,aAAY,oBAAoBnK,IAChCge,QAAS,IAvHX,CAAChe,IACvB,MAAM0rD,EAAO,IAAKvM,EAAOgL,2BAClBuB,EAAK1rD,GACZ8qD,EAAiBY,IAoHsBE,CAAgB5rD,IAChC,YAKL6B,GAAAyE,cAAC,OAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAS,GAAGoQ,UAAoB,mBAG3ExpD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACCiB,GAAI,GAAG8jD,SACP9sD,KAAK,SACL0a,IAAK,EACL4yC,KAAM,EACN1hD,UAAU,wBACV,mBAAkBmhD,GAAeb,EAAkBb,QAAsB,EACzE,eAAc0B,EACd58C,MAAyB,MAAlBw7C,EAAUI,KAAe,GAAKJ,EAAUI,KAC/C3wC,SAAW4Q,GA5FlB,EAACvqB,EAAc8rD,KAChC,MAAM5B,EAAY/K,EAAOgL,mBAAmBnqD,GAC5C,GAAgB,KAAZ8rD,EAAgB,CAClB,MAAMxB,KAAEA,KAASyB,GAAgB7B,EAEjC,YADAkB,EAAgBprD,EAAM+rD,EAExB,CACA,MAAMC,EAASz2C,OAAOu2C,GAClBv2C,OAAO4D,SAAS6yC,IAAWz2C,OAAOiG,UAAUwwC,IAAWA,GAAU,GACnEZ,EAAgBprD,EAAM,IAAKkqD,EAAWI,KAAM0B,KAmFLC,CAAWjsD,EAAMuqB,EAAEtf,OAAOyD,WAIjD7M,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BAA0B,iBACzCtI,GAAAyE,cAAC,OAAI6D,UAAU,aACX+/C,EAAUD,cAAgB,IAAIxqD,IAAI,CAACqL,EAAaiK,IAChDlT,GAAAyE,cAAC,MAAA,CAAIlF,IAAK2T,EAAOwM,MAAO,CAAEsW,QAAS,OAAQlH,aAAc,QACvD9uB,GAAAyE,cAAC,QAAA,CACCiB,GAAI,GAAG8jD,kBAA4Bt2C,IACnC5K,UAAU,wBACV,qBACG,MAAAW,OAAA,EAAAA,EAAa+N,SAAU4xC,EAAkBb,QAAsB,EAElE,iBAAe,MAAA9+C,OAAA,EAAAA,EAAa+N,QAC5BnK,MAAO5D,EACP6O,SAAW4Q,GArIf,EAACvqB,EAAc+U,EAAerG,KACtD,MAAMw7C,EAAY/K,EAAOgL,mBAAmBnqD,GACtCiqD,EAAe,IAAKC,EAAUD,cAAgB,IACpDA,EAAal1C,GAASrG,EACtB08C,EAAgBprD,EAAM,IAAKkqD,EAAWD,kBAiIOiC,CAAkBlsD,EAAM+U,EAAOwV,EAAEtf,OAAOyD,OACzDm3C,YAAY,qBACZ,aAAY,gBAAgB9wC,EAAQ,mBAAmB/U,MAEzD6B,GAAAyE,cAAC,SAAA,CACC/H,KAAK,SACL4L,UAAU,yBACVoX,MAAO,CAAE4qC,WAAY,OACrB,aAAY,uBAAuBp3C,EAAQ,oBAAoB/U,IAC/Dge,QAAS,IA/Hb,EAAChe,EAAc+U,KACvC,MAAMm1C,EAAY/K,EAAOgL,mBAAmBnqD,GACtCiqD,GAAgBC,EAAUD,cAAgB,IAAInrD,OAAO,CAACynD,EAAOxa,IAAMA,IAAMh3B,GAC/Eq2C,EAAgBprD,EAAM,IACjBkqD,EACHD,aAAcA,EAAa3mD,OAAS2mD,EAAe,CAAC,OA0HXmC,CAAkBpsD,EAAM+U,IACxC,OAKLlT,GAAAyE,cAAC,SAAA,CAAO/H,KAAK,SAAS4L,UAAU,sBAAsB6T,QAAS,IA7IhE,CAAChe,IACtB,MAAMkqD,EAAY/K,EAAOgL,mBAAmBnqD,GAC5CorD,EAAgBprD,EAAM,IACjBkqD,EACHD,aAAc,IAAKC,EAAUD,cAAgB,GAAK,OAyIuCoC,CAAersD,IAAO,sBAOrG,wBAGH,SAAA,CAAOzB,KAAK,SAAS4L,UAAU,yBAAyB6T,QAAS+sC,GAAc,mBAQ5F,CAEO,SAASuB,GAA0Bp3C,GAhS1C,IAAA9R,EAkBuB+7C,EAmRrB,GAnRqBA,EAmRFjqC,EAAQyzB,0BAlRnB37B,GAAQ,MAAAmyC,OAAA,EAAAA,EAAQgL,oBAmRtB,OAAO,EAET,IAAKj1C,EAAQgxB,SACX,OAAO,EAET,MAAMwC,IAAe,OAAAtlC,IAAQgjC,yBAAR,EAAAhjC,EAA4BslC,cAAe,IAAI7vB,OAAO5F,cAC3E,QAAK02C,GAAmBt4C,IAAIq3B,KAK1BpoC,OAAOuU,OAAOK,EAAQyzB,0BAA0BwhB,oBAAsB,CAAA,GAAIjsB,MACvEgsB,GA9QP,SAAiCA,GAC/B,MAAMD,GAAe,MAAAC,OAAA,EAAAA,EAAWD,eAAgB,GAChD,OAAOA,EAAa3mD,OAAS,GAAK2mD,EAAa/rB,MAAOpzB,KAAkBA,GAAeA,EAAY+N,OAAOvV,OAAS,EACrH,CA2QqBipD,CAAwBrC,IAAcG,GAAaH,KAC/DF,GAAsB90C,EAAQyzB,2BAEvC,CC5RA,MAAM6jB,GAAgB,yCAEf,MAAMC,WAA4BvW,GAAlC,WAAAh2C,GAAAyjB,SAAA8C,WA6CLrnB,KAAQstD,eAAiB,CACvBx3C,EACAy3C,IAEAvtD,KAAKo3C,wBAAwBthC,EAASmT,MAAOs0B,IAC3C,IAAIrH,EAAcqH,EAClB,IAAA,MAAWnH,KAAWmX,EACpBrX,SAAqBl2C,KAAKi3C,QAAQd,oBAAoBD,EAAaE,IAAUtgC,QAE/E,OAAOogC,IAGXl2C,KAAQwtD,gBAAkB,CAAC11C,EAAkC21C,KAC3D,MAAMn+C,EA4VV,SAAuBm+C,EAAkBh4C,GACvC,IAAKg4C,EAASh0C,OACZ,OAEF,GAAI6/B,GAAe7jC,IAAW8jC,GAAakU,GACzC,OAAOA,EAET,MAAMn+C,EAAQ6G,OAAOs3C,GACrB,OAAOC,GAAqBp+C,GAASA,OAAQ,CAC/C,CArWkBq+C,CAAcF,EAAUztD,KAAKsH,MAAM0vC,OAAOvhC,QACxD,QAAc,IAAVnG,EACF,OAGF,MAAMmG,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OAC9B,IAAKvhC,EAAOuzB,kBAEV,YADAhpC,KAAKsH,MAAM0vC,OAAOgD,cAAc,WAAY,CAAEngC,IAAKvK,EAAOX,IAAKW,EAAOmmB,QAASnmB,IAIjF,GAAc,YAAVwI,EAEF,YADA9X,KAAKsH,MAAM0vC,OAAOgD,cAAc,WAAY,IAAKvkC,EAAO8f,SAAUE,QAASnmB,IAI7E,MAAMs+C,EAAwB,QAAV91C,EAAkB,iBAAmB,iBACzD9X,KAAKsH,MAAM0vC,OAAOgD,cAAc,oBAAqB,IAChDvkC,EAAOuzB,kBACV4kB,CAACA,GAAct+C,IAEjBtP,KAAKsH,MAAM0vC,OAAOgD,cAAc,WAAY,IAAKvkC,EAAO8f,SAAUzd,CAACA,GAAQxI,KAG7EtP,KAAQ6tD,oBAAuB3lB,IA7GjC,IAAAlkC,EAAAsE,EAAAe,EAAAC,EA8GI,MAAMmM,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OAQ9B,GAPAh3C,KAAKsH,MAAM0vC,OAAOgD,cAChB,qCACA9R,GAAgD,WAA3B,OAAAlkC,IAAOwgC,kBAAPxgC,EAAkB0P,OAAoBsE,QAAQvC,EAAOuzB,oBAE5EhpC,KAAKsH,MAAM0vC,OAAOgD,cAAc,YAAa,IAAKvkC,EAAO+uB,UAAW0D,sBACpEloC,KAAKsH,MAAM0vC,OAAOgD,cAAc,SAAU,IAAKvkC,EAAOoH,OAAQya,mBAAmB,IAE7E4Q,EAAmB,CAGrB,GAFAloC,KAAKsH,MAAM0vC,OAAOgD,cAAc,qBAAqB,GACrDh6C,KAAKsH,MAAM0vC,OAAOgD,cAAc,oBAAqB,MACjD8T,GAAqB,OAAAxlD,EAAAmN,EAAO8f,eAAP,EAAAjtB,EAAiBmtB,QAAShgB,GAAS,CAC1D,MAAMggB,EAAUhgB,EAAO8f,SAASE,QAChCz1B,KAAKsH,MAAM0vC,OAAOgD,cAAc,WAAY,CAAEngC,IAAK4b,EAAS9mB,IAAK8mB,EAASA,QAAAA,GAC5E,CACA,MACF,CAEA,MAAMA,EAAU,OAAAnsB,EAAA,OAAAD,EAAAoM,EAAO8f,eAAP,EAAAlsB,EAAiBosB,SAAjBnsB,EAA4B,EACtCy2C,EAAStqC,EAAOuzB,mBAAqB,CACzCkd,eAAgBzwB,EAChB0wB,eAAgB1wB,EAChB2wB,kBAAmB,GACnBhB,eAAgB,CAAEiB,kBAAmB,KAEvCrmD,KAAKsH,MAAM0vC,OAAOgD,cAAc,qBAAqB,GACrDh6C,KAAKsH,MAAM0vC,OAAOgD,cAAc,oBAAqB+F,GACrD//C,KAAKsH,MAAM0vC,OAAOgD,cAAc,WAAY,IACvCvkC,EAAO8f,SACV1b,IAAKkmC,EAAOmG,eACZv3C,IAAKoxC,EAAOoG,eACZ1wB,QAAS6yB,GAAwB7yB,EAASsqB,EAAOmG,eAAgBnG,EAAOoG,mBAI5EnmD,KAAQ20C,gBAAmB7N,IACpB9mC,KAAKstD,eAAe,IAAKttD,KAAKsH,MAAM0vC,OAAOvhC,OAAQqxB,YAAY,CAClE,kBACA,gBACA,cACA,wBAIJ9mC,KAAQg1C,YAAejuC,IAChB/G,KAAKstD,eAAe,IAAKttD,KAAKsH,MAAM0vC,OAAOvhC,OAAQ1O,QAAQ,CAAC,cAAe,wBAGlF/G,KAAQi1C,mBAAsBlO,IACvB/mC,KAAKstD,eAAe,IAAKttD,KAAKsH,MAAM0vC,OAAOvhC,OAAQsxB,eAAe,CAAC,qBAAsB,iBAGhG/mC,KAAQ+tD,oBAAsB,CAAChnD,EAAckZ,KAlK/C,IAAAjc,EAmKI,MAAMyR,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3Bu4C,GAAgB,OAAAhqD,EAAAyR,EAAOuxB,yBAAP,EAAAhjC,EAA2BijC,QAAS,GACpDA,EAAQhnB,EACV3N,MAAMkD,KAAK,IAAIzE,IAAI,IAAIi9C,EAAejnD,KACtCinD,EAActuD,OAAQ4Y,GAASA,IAASvR,GACtC+O,EAAU,IACXL,EACHuxB,mBAAoB,IAAKvxB,EAAOuxB,mBAAoBC,UAEjDjnC,KAAKstD,eAAex3C,EAAS,CAAC,qBAAsB,iBAG3D9V,KAAQiuD,mBAAsB3kB,IAC5B,MAAM7zB,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OAC9Bh3C,KAAKsH,MAAM0vC,OAAOgD,cAAc,qBAAsB,IAAKvkC,EAAOuxB,mBAAoBsC,iBAGxFtpC,KAAQkuD,iCAAoC3kB,IAC1CvpC,KAAKsH,MAAM0vC,OAAOgD,cAAc,4BAA6BzQ,GAC/D,CA1JO,QAAA2N,CAASzhC,GA5BlB,IAAAzR,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EA6BI,MAAMxjB,EAAoC,CAAA,EACpCkc,EAAU,OAAAzxB,EAAAyR,EAAO8f,eAAP,EAAAvxB,EAAiByxB,QAMjC,GAJKq4B,GAAqBr4B,EAAShgB,KACjC8D,EAAOgc,SAAW,CAAEE,QAAS,oBAAoB23B,OAG/C33C,EAAOuzB,kBAAmB,CAC5B,MAAMnvB,EAAM,OAAAvR,EAAAmN,EAAOuzB,wBAAP,EAAA1gC,EAA0B49C,eAChCv3C,EAAM,OAAAtF,EAAAoM,EAAOuzB,wBAAP,EAAA3/B,EAA0B88C,eAEjC2H,GAAqBj0C,EAAKpE,KAC7B8D,EAAOyvB,kBAAoB,IACtBzvB,EAAOyvB,kBACVkd,eAAgB,oBAAoBkH,OAGnCU,GAAqBn/C,EAAK8G,KAC7B8D,EAAOyvB,kBAAoB,IACtBzvB,EAAOyvB,kBACVmd,eAAgB,oBAAoBiH,OAGpCM,GAAqBj4B,IAAYi4B,GAAqB7zC,IAAQ4b,EAAU5b,EAC1EN,EAAOgc,SAAW,CAAEE,QAAS,uDACpBi4B,GAAqBj4B,IAAYi4B,GAAqB/+C,IAAQ8mB,EAAU9mB,IACjF4K,EAAOgc,SAAW,CAAEE,QAAS,sDAEjC,CAYA,OAVKhgB,EAAOqxB,WAAa,OAAAx9B,EAAAmM,EAAO1O,eAAM0S,UACpCF,EAAOxS,KAAO,kBAEZ0O,EAAOqxB,UAAYrxB,EAAOsxB,eAAgB,OAAAhK,EAAA,WAAOiK,yBAAP,EAAAxsB,EAA2BysB,cAA3BlK,EAAkC74B,UAC9EqV,EAAOytB,mBAAqB,CAAEC,MAAO,gCAElCimB,GAA0Bz3C,KAC7B8D,EAAOgwB,0BAA4B,2CAG9BhwB,CACT,CAkHQ,mBAAA40C,CAAoBroD,EAAegS,EAAkCxI,GAC3E,MAAMnH,EAAK,gBAAgB2P,IACrB9I,EA4OV,SAAuBuK,EAAiBzB,GAtaxC,IAAA9T,EAAAsE,EAuaE,GAAc,YAAVwP,EACF,OAAQ,OAAA9T,EAAA,MAAAuV,OAAA,EAAAA,EAAgBgc,iBAAhBvxB,EAA0ByxB,QAEpC,OAAQ,OAAAntB,EAAA,MAAAiR,OAAA,EAAAA,EAAgByvB,wBAAhB,EAAA1gC,EAA8C,QAAVwP,EAAkB,iBAAmB,iBACnF,CAjPkBs2C,CAAcpuD,KAAKsH,MAAM0vC,OAAOz9B,OAAQzB,GACtD,OACErV,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAS1zC,GACjDrC,GAEHrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkB8H,EAAQ,GAAG7G,eAAa,EAC1C,eAAc6P,QAAQhJ,GACtB,aAAY,GAAGlJ,aACfiF,UAAU,wBACV5C,KACA0R,IAAK,EACLU,SAAWwB,GAAU/b,KAAKwtD,gBAAgB11C,EAAOiE,EAAMlQ,OAAOyD,OAC9DuQ,UAAU,EACV4sC,KAAM,EACNttD,KAAMm6C,GAAet5C,KAAKsH,MAAM0vC,OAAOvhC,QAAU,OAAS,SAC1DnG,MAAO,MAAAA,EAAAA,EAAS,KAEjBN,GACCvM,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAI,GAAGA,UAAY4f,KAAK,SAClD/Y,IAMb,CAEQ,mBAAAq/C,GAxNV,IAAArqD,EAAAsE,EAAAe,EAyNI,MAAMoM,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3BwxB,EAAQqnB,GAAY,OAAAhmD,EAAA,OAAAtE,EAAAyR,EAAOo2B,sBAAa3hB,eAApB,EAAA5hB,EAA8B2+B,MAAOxxB,EAAO1O,KAAO,CAAC0O,EAAO1O,MAAQ,IACvFiI,EAAS,OAAA3F,EAAArJ,KAAKsH,MAAM0vC,OAAOz9B,eAAlBlQ,EAAkCtC,KACjD,OACEtE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAQ,qBAAoB,QAGvEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkB8H,EAAQ,+BAA4B,EACtD,eAAcgJ,QAAQhJ,GACtB,aAAW,OACXjE,UAAU,wBACV5C,GAAG,oBACHoS,SAAWwB,GAAU/b,KAAKg1C,YAAYj5B,EAAMlQ,OAAOyD,OACnDuQ,UAAU,EACVvQ,MAAOmG,EAAO1O,MAAQ,IAEtBtE,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChB23B,EAAM5mC,IAAI,EAAGg9C,cAAa/tC,WACzB7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,MAIvCruC,GACCvM,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAG,0BAA0B4f,KAAK,SAC5D/Y,IAMb,CAEQ,0BAAAu/C,GA9PV,IAAAvqD,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EA+PI,MAAMtnB,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3Bu4C,GAAgB,OAAAhqD,EAAAyR,EAAOuxB,yBAAP,EAAAhjC,EAA2BijC,QAAS,GACpDA,EAAQqnB,GAAY,OAAAjlD,EAAA,OAAAf,EAAAmN,EAAOo2B,sBAAa3hB,eAApB,EAAA7gB,EAA8B49B,MAAO+mB,GACzDz0C,EAASvZ,KAAKsH,MAAM0vC,OAAOz9B,OAC3Bi1C,EAAa,OAAAllD,EAAA,MAAAiQ,OAAA,EAAAA,EAAQytB,yBAAR,EAAA19B,EAA4B29B,MACzCwnB,GAAyB,OAAAj0C,EAAA/E,EAAOo2B,kBAAP,EAAArxB,EAAoB45B,iCAAkC,CACnF,MACA,OACA,WACA,mBAGF,OACE3xC,GAAAyE,cAAC,WACCzE,GAAAyE,cAAC,WAAA,CAAS6D,UAAU,cAClBtI,GAAAyE,cAAC,UAAO6D,UAAU,2BAA0B,gBAC5CtI,GAAAyE,cAAC,OAAI6D,UAAU,6BACZ,QAAA,CAAMA,UAAU,eAAe8wC,QAAQ,gCACtCp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,8BACXmZ,SAAU5K,EAAOsxB,YACjB5+B,GAAG,+BACHvH,KAAK,iCACL2Z,SAAWwB,GAAUA,EAAMlQ,OAAOwU,SAAWrgB,KAAKi1C,oBAAmB,GACrE91C,KAAK,UACL,mBAGJsD,GAAAyE,cAAC,SAAM6D,UAAU,eAAe8wC,QAAQ,+BACtCp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,6BACXmZ,QAASrI,QAAQvC,EAAOsxB,aACxB5+B,GAAG,8BACHvH,KAAK,iCACL2Z,SAAWwB,GAAUA,EAAMlQ,OAAOwU,SAAWrgB,KAAKi1C,oBAAmB,GACrE91C,KAAK,UACL,6BAMPsW,EAAOsxB,aACNtkC,GAAAyE,cAAC,WAAA,CAAS,mBAAkBsnD,EAAa,gCAA6B,EAAWzjD,UAAU,cACzFtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,2BAA0B,SAC5CtI,GAAAyE,cAAC,MAAA,CAAI,eAAc8Q,QAAQw2C,GAAazjD,UAAU,YAC/Ck8B,EAAM5mC,IAAI,EAAGg9C,cAAa/tC,YACzB,MAAMnH,EAAK,qBAAqBmH,IAChC,OACE7M,GAAAyE,cAAC,OAAI6D,UAAU,WAAW/I,IAAKsN,GAC7B7M,GAAAyE,cAAC,QAAA,CAAM20C,QAAS1zC,GACd1F,GAAAyE,cAAC,QAAA,CACC,aAAY,QAAQoI,IACpB+Q,QAAS2tC,EAAc1pD,SAASgL,GAChCnH,KACAoS,SAAWwB,GAAU/b,KAAK+tD,oBAAoBz+C,EAAOyM,EAAMlQ,OAAOwU,SAClElhB,KAAK,aAENmQ,EACA+tC,EAAc,iBAAmB,OAKzCmR,GACC/rD,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAG,2BAA2B4f,KAAK,SAC7DymC,KAOX/rD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAQ,6BAA4B,gBAG/Ep5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,eACX6D,UAAU,wBACV5C,GAAG,4BACHoS,SAAWwB,GAAU/b,KAAKiuD,mBAAmBlyC,EAAMlQ,OAAOyD,OAC1DA,OAAO,OAAAytB,EAAAtnB,EAAOuxB,yBAAP,EAAAjK,EAA2BuM,cAAe,IAEjD7mC,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBm/C,EAAapuD,IAAKipC,GACjB7mC,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsnC,EAAah6B,MAAOg6B,GAC9BA,OAQjB,CAEO,MAAAtkB,GAjWT,IAAAhhB,EAAAsE,EAAAe,EAAAC,EAAAkR,EAkWI,MAAM/E,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OACxB9O,GAAqBzyB,EAAOuzB,kBAElC,OACEvmC,GAAAyE,cAAC,OAAI6D,UAAU,oDACZ,WAAA,CAASA,UAAU,cAClBtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,2BAA0B,iBAC5CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,6BACZ,QAAA,CAAMA,UAAU,eAAe8wC,QAAQ,uBACtCp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,kBACXmZ,QAAS6nB,EACT//B,GAAG,sBACHvH,KAAK,oBACL2Z,SAAWwB,GAAUA,EAAMlQ,OAAOwU,SAAWrgB,KAAK6tD,qBAAoB,GACtE1uD,KAAK,UACL,UAGJsD,GAAAyE,cAAC,SAAM6D,UAAU,eAAe8wC,QAAQ,4BACtCp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,uBACXmZ,SAAU6nB,EACV//B,GAAG,2BACHvH,KAAK,oBACL2Z,SAAWwB,GAAUA,EAAMlQ,OAAOwU,SAAWrgB,KAAK6tD,qBAAoB,GACtE1uD,KAAK,UACL,kBAMN+oC,GAAqBloC,KAAKmuD,oBAAoB,UAAW,MAAO,OAAAnqD,EAAAyR,EAAOuzB,4BAAmBkd,iBAC1Fhe,GAAqBloC,KAAKmuD,oBAAoB,UAAW,MAAO,OAAA7lD,EAAAmN,EAAOuzB,wBAAP,EAAA1gC,EAA0B69C,gBAC3FnmD,KAAKmuD,oBAAoB,UAAW,UAAW,OAAA9kD,EAAAoM,EAAO8f,eAAP,EAAAlsB,EAAiBosB,SAEjEhzB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,aAELzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,qBACbtI,GAAAyE,cAAC,QAAA,CAAM20C,QAAQ,yBACbp5C,GAAAyE,cAAC,QAAA,CACC,aAAW,wBACXmZ,QAAS5K,EAAOqxB,SAChB3+B,GAAG,wBACHoS,SAAWwB,GAAU/b,KAAK20C,gBAAgB54B,EAAMlQ,OAAOwU,SACvDlhB,KAAK,aACL,gDAMPsW,EAAOqxB,SAAW9mC,KAAKuuD,6BAA+BvuD,KAAKquD,sBAC5D5rD,GAAAyE,cAACikD,GAAA,CACC5hB,0BAA2B9zB,EAAO8zB,0BAClCzC,SAAUrxB,EAAOqxB,SACjBwkB,6BAA8BtrD,KAAKkuD,iCACnC5kB,aAAa,OAAAhgC,EAAAmM,EAAOuxB,yBAAP,EAAA19B,EAA2BggC,mBAAe,EACvD+hB,gBAAkB,OAAA7wC,EAAAxa,KAAKsH,MAAM0vC,OAAOz9B,aAAlB,EAAAiB,EAAkC+uB,4BAI5D,EAUF,SAASmkB,GAAqBp+C,GAC5B,MAAwB,iBAAVA,GAAsB6G,OAAO4D,SAASzK,IAAU6G,OAAOiG,UAAU9M,IAAUA,GAAS,CACpG,CAaA,SAASw+C,GAAqBx+C,EAAgBmG,GAC5C,OAAOi4C,GAAqBp+C,IAAWgqC,GAAe7jC,IAAW8jC,GAAajqC,EAChF,CAEA,SAASgqC,GAAe7jC,GACtB,MAAiC,mBAA1BA,EAAO+uB,UAAU9wB,MAAuD,iBAA1B+B,EAAO+uB,UAAU9wB,IACxE,CAEA,SAAS6lC,GAAajqC,GACpB,MAAwB,iBAAVA,GAAsB,mBAAmBkU,KAAKlU,EAC9D,CAEA,SAASg5C,GAAwB7yB,EAAc5b,EAAUlL,GAxczD,IAAA3K,EAAAsE,EAycE,MAAuB,iBAAZmtB,GAAuC,iBAAR5b,GAAmC,iBAARlL,EAC5DD,KAAKmL,IAAIlL,EAAKD,KAAKC,IAAIkL,EAAK4b,IAE9B,OAAAntB,EAAA,OAAAtE,EAAA,MAAAyxB,EAAAA,EAAW5b,GAAX7V,EAAkB2K,GAAlBrG,EAAyB,CAClC,CAEA,SAASgmD,GAAYI,EAAgDV,GACnE,MAAMW,EAAiBD,GAAY,GACnC,OAAOp8C,MAAMkD,KAAK,IAAIzE,IAAI,IAAI49C,KAAmBX,KAAiB3tD,IAAKiP,IAAA,CACrE+tC,aAAcsR,EAAerqD,SAASgL,GACtCA,UAEJ,CCvcA,MAAMs/C,GAAgB,CACpB,CAAE9oD,MAAO,WAAYwJ,MAAO,YAC5B,CAAExJ,MAAO,cAAewJ,MAAO,eAG1B,MAAMu/C,WAAiC/X,GAAvC,WAAAh2C,GAAAyjB,SAAA8C,WAMLrnB,KAAQ8uD,oBAAuBh+B,IAC7B9wB,KAAKsH,MAAM0vC,OAAOgD,cAAc,kBAAmB,MACnDh6C,KAAKsH,MAAM0vC,OAAOgD,cAAc,gBAAiBlpB,IAGnD9wB,KAAQ+uD,8BAAiCC,IACvChvD,KAAKsH,MAAM0vC,OAAOgD,cAAc,kBAAmBgV,EAAiB7mD,IACpEnI,KAAKsH,MAAM0vC,OAAOgD,cAAc,gBAAiB,MACnD,CAbO,QAAA9C,CAASzhC,GACd,MAAMskB,EAAQ2b,GAA8BjgC,GAAQskB,MACpD,OAAOA,EAAQ,CAAEA,SAAU,CAAA,CAC7B,CAYQ,iBAAAk1B,GACN,MAAMx5C,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OAC9B,IAAKvhC,EAAO+uB,UAAU4G,wBACpB,OAAO,KAET,MAAM8jB,EAAgBz5C,EAAO+uB,UAAU2qB,iCACpC,MAAA,CAAIpkD,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BAA0B,gBACzCtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAACkoD,GAAS/oB,IAAI,OAAOjb,QAAS3V,EAAO+uB,UAAU2qB,oBAInD1sD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAQ,iCAAgC,gBAGnFp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAW,eACX6D,UAAU,wBACV5C,GAAG,gCACHoS,SAAWwB,GAAU/b,KAAKsH,MAAM0vC,OAAOgD,cAAc,cAAej+B,EAAMlQ,OAAOyD,OACjFA,MAAOmG,EAAO4xB,aAAe,IAE5BgO,GACCuZ,GACAn5C,EAAO4xB,YACNxqB,GAAWA,EAAOvN,MAClBA,IAAA,CAAaxJ,MAAOwJ,EAAOA,WAC5BjP,IAAI,EAAGo1C,aAAYnmC,WACnB7M,GAAAyE,cAAC,SAAA,CAAOoT,SAAUm7B,EAAYzzC,IAAKsN,EAAMA,MAAOA,MAAOA,EAAMA,OAC1DmmC,EAAa,GAAGnmC,EAAMxJ,sBAAwBwJ,EAAMxJ,WAQjE,OACErD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACGikD,EACuB,aAAvBz5C,EAAO4xB,aACN5kC,GAAAyE,cAACmoD,GAAA,CACCv+B,SAAUrb,EAAO65C,cACjBC,6BAA8BC,GAAsBC,GAAqBC,eACzEC,mBAAoBl6C,EAAOm6C,gBAC3Br5B,aAAc,EACds5B,QAAQ,qBACR/pD,MAAM,oBACNgqD,iBAAkB9vD,KAAK8uD,oBACvBiB,2BAA4B/vD,KAAK+uD,8BACjCz+B,SAAU7a,EAAO+uB,UAAUlU,SAC3BvB,MAAOtZ,EAAO+uB,UAAUzV,QAKlC,CAEQ,iBAAAihC,GAhGV,IAAAhsD,EAAAsE,EAAAe,EAiGI,MAAMoM,OAAEA,GAAWzV,KAAKsH,MAAM0vC,OAC9B,GAAIvhC,EAAO+uB,UAAU2G,sBACnB,OAAO1oC,GAAAyE,cAAC,WAAI,iDAGd,MACM2yB,EA6CV,SAAsBo2B,EAA2BC,GAC/C,MAAMr2B,EAASvnB,MAAMkD,KACnB,IAAIzE,IAAIk/C,EAAU5vD,IAAK05B,GAA4B,iBAAVA,EAAqBA,EAAQA,EAAMpH,WAAYjzB,OAAOsY,WAEjG,OAAOq9B,GACLxb,EACAq2B,EACCn2B,GAAUA,EACVA,GAAUA,GACX15B,IAAI,EAAGo1C,aAAYnmC,YAAM,CACzBxJ,MAAO2vC,EAAa,GAAGnmC,kBAAwBA,EAC/C+tC,YAAa5H,EACbnmC,UAEJ,CA3DmB6gD,EADS,OAAA7nD,EAAA,OAAAtE,EAAAyR,EAAOo2B,oBAAP7nC,EAAoBkmB,eAApB,EAAA5hB,EAA8BuxB,UAAU,OAAAxwB,EAAAoM,EAAOo2B,kBAAP,EAAAxiC,EAAoBqoC,YAAa,GACpDj8B,EAAOskB,OAC9C/qB,EAAQhP,KAAKk3C,SAASzhC,GAAQskB,MACpC,OACEt3B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAQ,0BAAyB,SAG5Ep5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkB8H,EAAQ,oCAAiC,EAC3D,eAAcgJ,QAAQhJ,GACtB,aAAW,QACXjE,UAAU,wBACV5C,GAAG,yBACHoS,SAAWwB,GAAU/b,KAAKsH,MAAM0vC,OAAOgD,cAAc,QAASj+B,EAAMlQ,OAAOyD,OAC3EuQ,UAAU,EACVvQ,MAAOmG,EAAOskB,OAAS,IAEvBt3B,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBuqB,EAAOx5B,IAAK05B,GACXt3B,GAAAyE,cAAC,UAAOoT,SAAUyf,EAAMsjB,YAAar7C,IAAK+3B,EAAMzqB,MAAOA,MAAOyqB,EAAMzqB,OACjEyqB,EAAMj0B,SAIZkJ,GACCvM,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,aAAa5C,GAAG,+BAA+B4f,KAAK,SACjE/Y,IAMb,CAEO,MAAAgW,GACL,OACEviB,GAAAyE,cAAC,OAAI6D,UAAU,mCACZ/K,KAAKivD,oBACLjvD,KAAKgwD,oBAGZ,EC1IF,MACMI,GAAwB,MAgCvB,MAAMC,WAAgCvZ,GAAtC,WAAAh2C,GAAAyjB,SAAA8C,WAILrnB,KAAQswD,8BAAgC,EAiCxCtwD,KAAQwR,QAAW++C,IACjBvwD,KAAKsH,MAAM0vC,OAAOgB,UAAUuY,IAG9BvwD,KAAQwwD,aAAgBxhC,IACtBhvB,KAAKwR,QAAQ,IAAKxR,KAAKsH,MAAM0vC,OAAOvhC,UAAWuZ,KAGjDhvB,KAAQ8sD,kBAAqBnhD,IAC3B,MAAM8J,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B86C,EAAa,IACd96C,EACH9J,eACA64B,UAAW,IAAK/uB,EAAO+uB,UAAWwD,gBAAiB,WAE/C6O,IAAsB72C,KAAKswD,8BACjCtwD,KAAKwR,QAAQ++C,GACTjX,GAAe7jC,IAAWg7C,GAAYC,aAAa/kD,IAGlD3L,KAAKo3C,wBAAwBmZ,EAAYtnC,MAAOs0B,IACnD,MAAMhZ,QAA4BvkC,KAAKyxB,QAAQxc,SAASkuB,oBAAoBwH,uBAC1E4S,EAAcxV,kBAAoB,MAClCp8B,GAEF,GAAIkrC,IAAsB72C,KAAKswD,8BAC7B,OAAO/S,EAET,MAAMoT,EA2jBZ,SACE76C,EACAyuB,GAtqBF,IAAAvgC,EAAAsE,EAwqBE,MAAMsoD,EAAe,OAAAtoD,EAAA,OAAAtE,EAAA,MAAAugC,SAAAA,EAAqBr3B,cAArB,EAAAlJ,EAA8B4K,sBAA9B,EAAAtG,EAA+C2D,MAC9Du4B,EAAY,IAAK1uB,EAAQ0uB,WAC3BosB,UACKpsB,EAAUC,6BAEnB,MAAO,IACF3uB,KACC86C,EAAe,CAAE3kD,MAAO2kD,EAAavwD,IAAK6N,IAAA,IAAyBA,MAAa,CAAA,EACpFs2B,UAAW,IACNA,EACHD,uBAGN,CA5kBgCssB,CAA6BtT,EAAehZ,GAChEnpB,QAAepb,KAAKi3C,QAAQd,oBAAoBwa,EAAmB,eACzE,OAAO9Z,IAAsB72C,KAAKswD,8BAAgCl1C,EAAOtF,QAAUynC,KAIvFv9C,KAAQ8wD,sBAAyBC,IAC/B,MAAMt7C,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC5Bs7C,EAIL/wD,KAAKgxD,qBAAqBC,GAAwBx7C,IAHhDzV,KAAKwR,QAAQ,IAAKiE,EAAQ+uB,UAAW,IAAK/uB,EAAO+uB,UAAWwD,gBAAiB,aAMjFhoC,KAAQgxD,qBAAwBvnB,IAC9BzpC,KAAKswD,gCACL,MAAM76C,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B86C,EAAa,IACd96C,EACH9J,aAAculD,GAAuBznB,GACrCjF,UAAW,IAAK/uB,EAAO+uB,UAAWiF,iBAAgBzB,gBAAiB,gBAEhEhoC,KAAKo3C,wBAAwBmZ,EAAYtnC,MAAOs0B,UAC9Bv9C,KAAKi3C,QAAQd,oBAAoBoH,EAAe,0BACvDznC,UAIlB9V,KAAQmxD,kBAAqB1pB,IAC3BznC,KAAKwwD,aAAa,CAChB/oB,cACAC,kBAAmBD,EACnBE,kBAAmBF,EAAc,YAAc,aAInDznC,KAAQoxD,sBAAwB,CAACz7C,EAAe47B,KAC9C,MAAM97B,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B+kC,EAAe6W,GAAsB57C,GACrC3D,EAAY85B,GAAyBn2B,GAAQhN,KAAMC,GAAcA,EAAU9H,OAAS2wC,GACpF+f,EAAen7C,OAAOqkC,EAAa7kC,GAAOwlC,kBAC1CA,EAAmBrpC,EA2f7B,SAA+By/C,EAA2BD,GACxD,IAAKC,EAAgBrtD,OACnB,OAAO,EAET,GAAIqtD,EAAgBjtD,SAASgtD,GAC3B,OAAOA,EAET,OAAOC,EAAgB/iD,OACrB,CAACgjD,EAASnjD,IAAWA,GAASijD,GAAgBjjD,EAAQmjD,EAAUnjD,EAAQmjD,EACxED,EAAgB,GAEpB,CArgBQE,CAAsB3/C,EAAUw6B,oBAAqBglB,GACrDA,EACJtxD,KAAKwwD,aAAa,CAChBnf,mBAAoBmJ,EAAan6C,IAAI,CAACY,EAAQywD,IAC5CA,IAAgB/7C,EAAQ,CAAE47B,kBAAiB4J,oBAAqBl6C,MAKtEjB,KAAQ2xD,uBAAyB,CAACh8C,EAAe83C,KAC/C,MAAMjT,EAAe6W,GAAsBrxD,KAAKsH,MAAM0vC,OAAOvhC,QAC7DzV,KAAKwwD,aAAa,CAChBnf,mBAAoBmJ,EAAan6C,IAAI,CAACY,EAAQywD,IAC5CA,IAAgB/7C,EAAQ,IAAK1U,EAAQk6C,iBAAkB3B,GAAyBiU,IAAcxsD,MAKpGjB,KAAQ4xD,eAAiB,KACvB,MAAMn8C,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B3D,EAAY85B,GAAyBn2B,GAAQ,GAC9C3D,GAGL9R,KAAKwwD,aAAa,CAChBnf,mBAAoBggB,GAAsB57C,GAAQmU,OAAO,CACvD2nB,gBAAiBz/B,EAAUlR,KAC3Bu6C,iBAAkBrpC,EAAUw6B,oBAAoB,IAAM,OAK5DtsC,KAAQ06C,kBAAqB/kC,IAC3B3V,KAAKwwD,aAAa,CAChBnf,mBAAoBggB,GAAsBrxD,KAAKsH,MAAM0vC,OAAOvhC,QAAQ/V,OAClE,CAACmyD,EAASH,IAAgBA,IAAgB/7C,MAKhD3V,KAAQ8xD,eAAkB9iC,IACxB,MACM/iB,EAAS,IADAjM,KAAKsH,MAAM0vC,OAAOvhC,OACNxJ,OAAS,IAC9B8lD,EAAgBC,GAAiB/lD,IACjB,IAAlB8lD,EACF9lD,EAAMgmD,QAAQ,CAAE9yD,KAAM,SAAU+M,OA1LR,MA0L0C8iB,IAElE/iB,EAAM8lD,GAAiB,IAAK9lD,EAAM8lD,MAAmB/iC,GAEvDhvB,KAAKwwD,aAAa,CAAEvkD,UACtB,CAxJO,QAAAirC,CAASzhC,GACd,MAAM8D,EAA2C,CAAA,EAC5C9D,EAAO9J,eACV4N,EAAO5N,aAAe,0BAGxB,MAAMumD,EAAWC,GAAY18C,IAE1B,MAAAy8C,OAAA,EAAAA,EAAU/yD,OA2hBjB,SAA6BmQ,EAAgBwG,EAAiC+D,EAAalL,GACzF,GAAI2qC,GAAexjC,IAAYyjC,GAAajqC,GAC1C,OAAO,EAET,MAAMwQ,EAAc3J,OAAO7G,GAC3B,OAAO6G,OAAO4D,SAAS+F,IAAgB3J,OAAOiG,UAAU0D,IAAgBA,GAAejG,GAAOiG,GAAenR,CAC/G,CAhiBOoyC,CAAoBmR,EAAShmD,OAAQuJ,EAhDd,GAgD6C26C,MAErE72C,EAAOtN,MAAQ,mDAGjB,MAAMuuC,EAAe6W,GAAsB57C,GACrC28C,EAAwBxmB,GAAyBn2B,GAavD,OAXE+kC,EAAa32C,KAAM5C,IACjB,IAAKA,EAAOswC,kBAyhBpB,SAAgCjiC,EAAgBwG,GAC9C,GAAIwjC,GAAexjC,IAAYyjC,GAAajqC,GAC1C,OAAO,EAET,MAAMwQ,EAAc3J,OAAO7G,GAC3B,OAAO6G,OAAO4D,SAAS+F,IAAgB3J,OAAOiG,UAAU0D,IAAgBA,EAAc,CACxF,CA/hBwCuyC,CAAuBpxD,EAAOk6C,iBAAkB1lC,GAC9E,OAAO,EAET,MAAM3D,EAAYsgD,EAAsB3pD,KAAM+jC,GAAgBA,EAAY5rC,OAASK,EAAOswC,iBAC1F,QAAOz/B,IAAaA,EAAUw6B,oBAAoBhoC,SAAS6R,OAAOlV,EAAOk6C,uBAG3E5hC,EAAO83B,mBAAqB,2DAGvB93B,CACT,CA6HO,MAAAyL,GAxMT,IAAAhhB,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAyMI,MAAMtnB,EAASzV,KAAKsH,MAAM0vC,OAAOvhC,OAC3B8D,EAAUvZ,KAAKsH,MAAM0vC,OAAOz9B,QAAU,CAAA,EACtC+4C,EAAkD,gBAArC78C,EAAO+uB,UAAUwD,gBAC9B0T,EAAepC,GAAe7jC,GAC9Bo1C,EAAe0H,IACnB,OAAAjqD,EAAA,WAAOujC,kBAAP,EAAA7nC,EAAoBkmB,eAApB,EAAA5hB,EAA8BuE,gBAAiB,GAC/C4I,EAAO9J,cAEHslC,EAAeshB,IACnB,OAAAjpD,EAAA,WAAOuiC,kBAAP,EAAAxiC,EAAoB6gB,eAApB,EAAA5gB,EAA8B2nC,eAAgB,CAAC,eAC/Cx7B,EAAO2xB,gBAEH2pB,EAASE,GAAwBx7C,GACjC+8C,GAAgB,OAAAh4C,EAAA/E,EAAOo2B,kBAAP,EAAArxB,EAAoBi4C,sBAAuB,CAAA,EAC3DP,EAAWC,GAAY18C,IAAW,CAAEtW,KAAM,SAAU+M,OAhNhC,IAiNpB4vC,EAAYyW,IAAwB,OAAAx1B,EAAAtnB,EAAOo2B,sBAAaiE,sBAAuB,GAAIoiB,EAAS/yD,MAC5FizD,EAAwBxmB,GAAyBn2B,GACjD47B,EAAqBggB,GAAsB57C,GAEjD,OACEhT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,mCACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,SAAE,iBAELzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,eAAe8wC,QAAQ,6BACtCp5C,GAAAyE,cAAC,QAAA,CACCmZ,SAAUiyC,EACVnqD,GAAG,4BACHvH,KAAK,wBACL2Z,SAAU,IAAMva,KAAK8wD,uBAAsB,GAC3C3xD,KAAK,UACL,YAGJsD,GAAAyE,cAAC,SAAM6D,UAAU,eAAe8wC,QAAQ,2BACtCp5C,GAAAyE,cAAC,QAAA,CACCmZ,QAASiyC,EACTnqD,GAAG,0BACHvH,KAAK,wBACL2Z,SAAU,IAAMva,KAAK8wD,uBAAsB,GAC3C3xD,KAAK,UACL,4BAMNmzD,GACA7vD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAQ,oBAAmB,gBAGtEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACZ2wC,EACCj5C,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAO5N,aAAe,8BAA2B,EACnE,eAAcqM,QAAQuB,EAAO5N,cAC7B,aAAW,eACXZ,UAAU,wBACV5C,GAAG,mBACHoS,SAAWwB,GAAU/b,KAAK8sD,kBAAkB/wC,EAAMlQ,OAAOyD,OACzDnQ,KAAK,OACLmQ,MAAOmG,EAAO9J,cAAgB,KAGhClJ,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAO5N,aAAe,8BAA2B,EACnE,eAAcqM,QAAQuB,EAAO5N,cAC7B,aAAW,eACXZ,UAAU,wBACV5C,GAAG,mBACHoS,SAAWwB,GAAU/b,KAAK8sD,kBAAkB/wC,EAAMlQ,OAAOyD,OACzDuQ,UAAU,EACVvQ,MAAOmG,EAAO9J,cAAgB,IAE9BlJ,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBu7C,EAAaxqD,IAAI,EAAGg9C,cAAa/tC,WAChC7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,MAKzCxD,GAAsBtgC,EAAO5N,aAAc,4BAKjD2mD,GACC7vD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACGjL,KAAK+pD,aACJ,oBACA,iBACAgH,EAAOpvB,eACP+wB,GACEF,EAAcG,oBAAsB,CAAC,KAAM,KAAM,KAAM,OACvD5B,EAAOpvB,gBAERryB,GACCtP,KAAKgxD,qBAAqB,IACrBD,EACHvuB,eAA0B,OAAVlzB,GAAyByhD,EAAOvuB,eAChDb,eAAgBryB,KAGrBtP,KAAK+pD,aACJ,iBACA,aACAgH,EAAOnvB,UACP8wB,GAAgCF,EAAcI,UAAY,GAAI7B,EAAOnvB,WACpEtyB,GAAUtP,KAAKgxD,qBAAqB,IAAKD,EAAQnvB,UAAWzrB,OAAO7G,KACpEiK,EAAO5N,aACP,0BAED3L,KAAK+pD,aACJ,oBACA,cACAgH,EAAOhkD,OACP2lD,GAAgCF,EAAcK,YAAc,GAAI9B,EAAOhkD,QACtEuC,GAAUtP,KAAKgxD,qBAAqB,IAAKD,EAAQhkD,OAAQoJ,OAAO7G,KACjEiK,EAAO5N,aACP,0BAEyB,OAA1BolD,EAAOpvB,iCACL,MAAA,CAAI52B,UAAU,cACbtI,GAAAyE,cAAC,OAAI6D,UAAU,qCACbtI,GAAAyE,cAAC,QAAA,CAAM20C,QAAQ,8BACbp5C,GAAAyE,cAAC,QAAA,CACCmZ,QAAS0wC,EAAOvuB,eAChBr6B,GAAG,6BACHoS,SAAWwB,GACT/b,KAAKgxD,qBAAqB,IAAKD,EAAQvuB,eAAgBzmB,EAAMlQ,OAAOwU,UAEtElhB,KAAK,aACJ,IAAI,qBAMd06C,GAAsBtgC,EAAO5N,aAAc,2BAIhDlJ,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAQ,wBAAuB,wBACnDp5C,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,oCAErC1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACZ2wC,EACCj5C,GAAAyE,cAAC,QAAA,CACC,aAAW,uBACX6D,UAAU,wBACV5C,GAAG,uBACHoS,SAAWwB,GAAU/b,KAAKwwD,aAAa,CAAEppB,eAAgBrrB,EAAMlQ,OAAOyD,QACtEnQ,KAAK,OACLmQ,MAAOmG,EAAO2xB,gBAAkB,KAGlC3kC,GAAAyE,cAAC,SAAA,CACC,aAAW,uBACX6D,UAAU,wBACV5C,GAAG,uBACHoS,SAAWwB,GAAU/b,KAAKwwD,aAAa,CAAEppB,eAAgBrrB,EAAMlQ,OAAOyD,QACtEA,MAAOmG,EAAO2xB,gBAAkB,IAE/B6J,EAAa5wC,IAAI,EAAGg9C,cAAa/tC,WAChC7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,QAQ9C56C,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,qCACbtI,GAAAyE,cAAC,QAAA,CAAM20C,QAAQ,mBACbp5C,GAAAyE,cAAC,QAAA,CACCmZ,QAASrI,QAAQvC,EAAOgyB,aACxBt/B,GAAG,kBACHoS,SAAWwB,GAAU/b,KAAKmxD,kBAAkBp1C,EAAMlQ,OAAOwU,SACzDlhB,KAAK,aACJ,IAAI,gCACsBsD,GAAAyE,cAACy0C,GAAUxzC,GAAG,uDAKhD,WAAA,KACC1F,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,iBAAgB,uBACjCsmC,EAAmBhxC,IAAI,CAACY,EAAQ0U,KAC/B,MAAMm9C,EAAsBV,EAAsB3pD,KAC/C+jC,GAAgBA,EAAY5rC,OAASK,EAAOswC,iBAEzCwhB,EA0OlB,SACEX,EACApW,GAEA,MAAMthC,EAAU03C,EAAsB/xD,IAAKmsC,QAAsBA,EAAa6Q,aAAa,KACvFrB,IAAiBoW,EAAsBvuD,KAAM2oC,GAAgBA,EAAY5rC,OAASo7C,IACpFthC,EAAQ7U,KAAK,CAAEymC,oBAAqB,GAAI1rC,KAAMo7C,EAAcqB,aAAa,IAE3E,OAAO3iC,CACT,CAnPgCs4C,CAA6BZ,EAAuBnxD,EAAOswC,iBACzE0hB,EAAeP,IACnB,MAAAI,OAAA,EAAAA,EAAqBxmB,sBAAuB,GAC5CrrC,EAAOk6C,kBAET,OACE14C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,aAAa/I,IAAK,GAAGf,EAAOswC,mBAAmB57B,KAC5DlT,GAAAyE,cAAC,SAAM6D,UAAU,0BAA0B8wC,QAAS,wBAAwBlmC,KAAS,YAGrFlT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,8BAA2B,EACzE,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,YAAY17B,EAAQ,IAChC5K,UAAU,wBACV5C,GAAI,wBAAwBwN,IAC5B4E,SAAWwB,GAAU/b,KAAKoxD,sBAAsBz7C,EAAOoG,EAAMlQ,OAAOyD,OACpEA,MAAOrO,EAAOswC,iBAEbwhB,EAAY1yD,IAAI,EAAGqM,cAAa9L,OAAMy8C,iBACrC56C,GAAAyE,cAAC,SAAA,CAAOlF,IAAKpB,EAAM0O,MAAO1O,GACvBy8C,EAAcz8C,EAAO8L,GAAe9L,EACpCy8C,EAAc,iBAAmB,OAK1C56C,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAS,yBAAyBlmC,KAAS,SAGtFlT,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACZ2wC,EACCj5C,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,8BAA2B,EACzE,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,aAAa17B,EAAQ,IACjC5K,UAAU,wBACV5C,GAAI,yBAAyBwN,IAC7B4E,SAAWwB,GAAU/b,KAAK2xD,uBAAuBh8C,EAAOoG,EAAMlQ,OAAOyD,OACrEnQ,KAAK,OACLmQ,MAAOrO,EAAOk6C,mBAGhB14C,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAO83B,mBAAqB,8BAA2B,EACzE,eAAcr5B,QAAQuB,EAAO83B,oBAC7B,aAAY,aAAa17B,EAAQ,IACjC5K,UAAU,wBACV5C,GAAI,yBAAyBwN,IAC7B4E,SAAWwB,GAAU/b,KAAK2xD,uBAAuBh8C,EAAOoG,EAAMlQ,OAAOyD,OACrEA,MAAOrO,EAAOk6C,kBAEb8X,EAAa5yD,IAAI,EAAGg9C,cAAa/tC,WAChC7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKmW,OAAO7I,GAAQA,SACzBA,EACA+tC,EAAc,iBAAmB,OAM5C56C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,aAAY,cAAcyO,EAAQ,IAClC5K,UAAU,eACV6T,QAAS,IAAM5e,KAAK06C,kBAAkB/kC,GACtCxW,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK,cAAY,OAAO6D,UAAU,mCAM7CtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,+BACVuP,UAAW83C,EAAsBluD,OACjC0a,QAAS5e,KAAK4xD,eACdzyD,KAAK,UAELsD,GAAAyE,cAAC,OAAA,CAAK,cAAY,OAAO6D,UAAU,kCAAkC,oBAEtE8uC,GAAsBtgC,EAAO83B,mBAAoB,2BAGpD5uC,GAAAyE,cAAC,WAAA,KACCzE,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,iBAAgB,aAClCtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAQ,sBAAqB,QAGxEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkBqS,EAAOtN,MAAQ,2BAAwB,EACzD,eAAc+L,QAAQuB,EAAOtN,OAC7B,aAAW,iBACXlB,UAAU,wBACV5C,GAAG,qBACHoS,SAAWwB,GAAU/b,KAAK8xD,eAAe,CAAE3yD,KAAM4c,EAAMlQ,OAAOyD,QAC9DA,MAAO4iD,EAAS/yD,MAEf28C,EAAUz7C,IAAI,EAAGg9C,cAAa/tC,WAC7B7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKsN,EAAOA,SACjBA,EACA+tC,EAAc,iBAAmB,yBAM3C,MAAA,CAAItyC,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAQ,sBAAqB,aAGxEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC,mBAAkBqS,EAAOtN,MAAQ,2BAAwB,EACzD,eAAc+L,QAAQuB,EAAOtN,OAC7B,aAAW,iBACXlB,UAAU,wBACV5C,GAAG,qBACHwG,IAAK+sC,OAAe,EAAY0U,GAChCv2C,IAAK6hC,OAAe,EArgBN,GAsgBdnhC,SAAWwB,GAAU/b,KAAK8xD,eAAe,CAAE5lD,OAAQstC,GAAyBz9B,EAAMlQ,OAAOyD,SACzFuQ,UAAU,EACV1gB,KAAMu8C,EAAe,OAAS,SAC9BpsC,MAAO4iD,EAAShmD,SAEjB2tC,GAAsBtgC,EAAOtN,MAAO,0BAMjD,CAEQ,YAAA89C,CACN5hD,EACArC,EACAma,EACAvF,EACAH,EACAvL,EACA0zC,GAEA,OACEjgD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAS1zC,GACjDrC,GAEHrD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC,mBAAkB8H,EAAQ0zC,OAAU,EACpC,eAAc1qC,QAAQhJ,GACtB,aAAYlJ,EACZiF,UAAU,wBACV5C,KACAoS,SAAWwB,GAAUxB,EAASwB,EAAMlQ,OAAOyD,OAC3CA,MAAO2Q,GAENvF,EAAQra,IAAI,EAAGg9C,cAAa/tC,WAC3B7M,GAAAyE,cAAC,SAAA,CAAOlF,IAAKmW,OAAO7I,GAAQA,SACzBA,EACA+tC,EAAc,iBAAmB,OAOhD,EAGF,SAASxD,GAAsB7qC,EAA2B7G,GACxD,OACE6G,oBACG,OAAA,CAAKjE,UAAU,aAAa5C,KAAQ4f,KAAK,SACvC/Y,EAIT,CAEA,SAASsqC,GAAe7jC,GACtB,MAAiC,mBAA1BA,EAAO+uB,UAAU9wB,MAAuD,iBAA1B+B,EAAO+uB,UAAU9wB,IACxE,CAEA,SAAS6lC,GAAajqC,GACpB,MAAwB,iBAAVA,GAAsB,mBAAmBkU,KAAKlU,EAC9D,CAkBA,SAASkqC,GAAyBlqC,GAChC,OAAOiqC,GAAajqC,GAASA,EAAQ6G,OAAO7G,EAC9C,CAEA,SAASijD,GACP9O,EACAyP,GAEA,MAAMx4C,EAAU+oC,EAAgBpjD,IAAKiP,KAAa+tC,aAAa,EAAO/tC,WAItE,OAHI4jD,IAAkBzP,EAAgBn/C,SAAS4uD,IAC7Cx4C,EAAQ7U,KAAK,CAAEw3C,aAAa,EAAM/tC,MAAO4jD,IAEpCx4C,CACT,CAEA,SAASg4C,GACPjP,EACAyP,GAEA,MAAMx4C,EAAU+oC,EAAgBpjD,IAAKiP,KAAa+tC,aAAa,EAAO/tC,WAItE,OAHKm0C,EAAgB5/C,KAAMyL,GAAU6I,OAAO7I,KAAW6I,OAAO+6C,KAC5Dx4C,EAAQ7U,KAAK,CAAEw3C,aAAa,EAAM/tC,MAAO4jD,IAEpCx4C,CACT,CAaA,SAASkxB,GAAyBn2B,GAChC,OAAOA,EAAO+uB,UAAU2M,kBAAoB,EAC9C,CAEA,SAASkgB,GAAsB57C,GAC7B,OAAOA,EAAO47B,oBAAsB,EACtC,CAeA,SAAS2gB,GAAiB/lD,GACxB,OAAOA,EAAM4W,UAAW3U,GAASA,EAAK/O,KAAKoP,WAAW,QAAUL,EAAK/O,KAAKoP,WAAW,cACvF,CAEA,SAAS4jD,GAAY18C,GACnB,MAAMxJ,EAAUwJ,EAAOxJ,OAAS,GAChC,OAAOA,EAAM+lD,GAAiB/lD,GAChC,CAqBA,SAASglD,GAAwBx7C,GAvrBjC,IAAAzR,EAAAsE,EAAAe,EAAAC,EAAAkR,EAwrBE,MAAM24C,EAAa19C,EAAO+uB,UAAUiF,gBAAkB,CAAA,EAChDmjB,EAUR,SAAgCjhD,GAC9B,IAAKA,IAAiBA,EAAarH,SAAS,WAC1C,MAAO,CAAEk+B,gBAAgB,GAE3B,MAAM74B,EAAQ,mDAAmDC,KAAK+B,GACtE,IAAKhC,EACH,MAAO,CAAE64B,gBAAgB,GAE3B,MAAO,CACLA,eAAgBxqB,QAAQrO,EAAM,IAC9Bg4B,gBAAiBh4B,EAAM,IAAM,MAAMkK,cACnC9G,OAAQoJ,OAAOxM,EAAM,IAAM,KAC3Bi4B,UAAWzrB,OAAOxM,EAAM,IAE5B,CAxBiBypD,CAAuB39C,EAAO9J,cACvC0nD,GAAU,OAAArvD,EAAAyR,EAAOo2B,kBAAP,EAAA7nC,EAAoByuD,sBAAuB,CAAA,EAC3D,MAAO,CACLjwB,eAAgB,OAAAl6B,EAAA6qD,EAAW3wB,gBAAXl6B,EAA6BskD,EAAOpqB,eACpDb,eAAgBwxB,EAAWxxB,gBAAkBirB,EAAOjrB,iBAAkB,OAAAt4B,EAAAgqD,EAAQV,6BAAqB,KAAM,KACzG5lD,OAAQomD,EAAWpmD,QAAU6/C,EAAO7/C,SAAU,OAAAzD,EAAA+pD,EAAQR,qBAAa,KAAM,EACzEjxB,UAAWuxB,EAAWvxB,WAAagrB,EAAOhrB,YAAa,OAAApnB,EAAA64C,EAAQT,mBAAW,KAAM,EAEpF,CAkBA,SAAS1B,GAAuBjwD,GAC9B,MAAM8M,EAAS9M,EAAO0gC,eAAelF,cAErC,MAAO,GADmB,OAAX1uB,EAAkB,GAAK,GAAGA,cACf9M,EAAO2gC,aAAqC,KAAxBzrB,OAAOlV,EAAO8L,UAAiB9L,EAAOuhC,eAAiB,OAAS,IAChH,CA/qBa6tB,GACGnxB,YAAcC,ECiB9B,MAAMm0B,GAA6B,6BAC7BC,GAA+B,sBAC/BC,GAAwB,wBAsC9B,SAASv/C,GAAiB7P,GACxB,OAAOA,EAAaxD,MAAQwD,CAC9B,CAEA,SAASqvD,GAAenkD,GACtB,OAAIgD,MAAMC,QAAQjD,GACTA,EAEe,iBAAVA,EAAqBA,EAAMtM,MAAM,KAAK3C,IAAKiY,GAASA,EAAKmB,QAAU,EACnF,CAEA,SAASi6C,GAAe59C,GACtB,MAAMouB,EAAuBpuB,EAAQouB,sBAAwB,CAAA,EACvD4B,EAAmBhwB,EAAQgwB,kBAAoB,CAAA,EACrD,MAAO,CACLwtB,CAACA,IAA6BG,GAC5BvvB,EAAqBovB,KAA+BxtB,EAAiBwtB,KAEvEC,CAACA,IAA+BE,GAC9BvvB,EAAqBqvB,KAAiCztB,EAAiBytB,KAG7E,CAEA,SAASI,GAA8B/yD,EAAcwD,GACnD,GAAKA,EAAL,CAGA,GAAsC,SAAlCA,EAAaC,kBAAiE,qBAAlCD,EAAaC,iBAAyC,CACpG,MAAM4X,GAAS7X,EAAa0M,WAAa,IAAIzQ,IAAK+Q,GAAkBA,EAASxQ,MAAMlB,OAAOsY,SAC1F,OAAOiE,EAAM/X,OACT,CACElC,IAAuC,SAAlCoC,EAAaC,iBAA8BivD,GAA6BC,GAC7Et3C,cAEF,CACN,CACA,MAAO,CACLja,IACoC,QAAlCoC,EAAaC,kBAAgE,QAAlCD,EAAaC,iBACpDivD,GACAC,GACNt3C,MAAO,CAACrb,GAfV,CAiBF,CAEA,SAASgzD,GAA0B99C,GAhJnC,IAAA9R,EAAAsE,EAAAe,EAiJE,MAAMgpC,GAAoB,OAAA/pC,EAAA,OAAAtE,EAAA8R,EAAQ+1B,sBAAa3hB,eAArB,EAAA5hB,EAA+B+pC,oBAAqB,CAAA,EACxEwhB,GAA4B/9C,EAAQ7R,eAAiB,IAAIvE,OAC5D0E,IAAuBA,EAAaC,mBAAqBguC,EAAkBp+B,GAAiB7P,KAEzF0vD,EAAoBJ,GAAe59C,GACnCmuB,EAAqC,CACzCqvB,CAACA,IAA6BO,EAAyB3vD,OACnD,IAAI4vD,EAAkBR,KACtB,GACJC,CAACA,IAA+BM,EAAyB3vD,OACrD,IAAI4vD,EAAkBP,KACtB,KAGLz9C,EAAQ7R,eAAiB,IAAIlC,QAASqC,IACrC,MAAMxD,EAAOqT,GAAiB7P,GAExBuT,EAAYg8C,GAA8B/yD,EADpBwD,EAAaC,iBAAmBD,EAAeiuC,EAAkBzxC,IAEzF+W,GACFssB,EAAStsB,EAAU3V,KAAK6D,QAAQ8R,EAAUsE,SAI9C,MAAM4kC,EAAwB,IAAI9vC,KAAK+E,EAAQ7R,eAAiB,IAAI5D,IAAI4T,KAWxE,OAVI6B,EAAQtU,iBAAmBN,OAAOY,KAAKgU,EAAQtU,iBAAiB0C,OAClE+/B,EAASuvB,IAAyBtyD,OAAOY,KAAKgU,EAAQtU,iBACnD9B,OAAQ0E,GAAiBy8C,EAAsB5uC,IAAI7N,IACnD8K,QAAS9K,GAAiB0R,EAAQtU,gBAAgB4C,IAC5CyvD,EAAyB3vD,SAClC+/B,EAASuvB,IAAyBC,GAChC39C,EAAQqxB,yBAA0B,OAAA99B,EAAAyM,EAAQgwB,uBAAR,EAAAz8B,EAA2BmqD,OAvFnE,SAAyBvvB,GACvB,OAAO/iC,OAAOY,KAAKmiC,GAAUz1B,OAAO,CAACpO,EAAgC4B,KACnE,MAAMyT,EAASnD,MAAMkD,KAAK,IAAIzE,IAAIkzB,EAASjiC,GAAKtC,OAAOsY,WAIvD,OAHIvC,EAAOvR,SACT9D,EAAO4B,GAAOyT,EAAO/P,KAAK,MAErBtF,GACN,CAAA,EACL,CAmFS2zD,CAAgB9vB,EACzB,CAoCO,MAAM+vB,WAA0CvxD,GAAMC,UA6BpD,WAAA5B,CACLwG,EACAmqB,GAvPJ,IAAAztB,EAyPIugB,MAAMjd,EAAOmqB,GAlBfzxB,KAAQi0D,iBAAmB,EAE3Bj0D,KAAQg3C,OAAqE,KAC7Eh3C,KAAQk0D,WAAY,EA0CpBl0D,KAAQ8zC,iBAAmB7qB,UApR7B,IAAAjlB,EAAAsE,EAAAe,EAAAC,EAqRI,MAAMguC,IAAYt3C,KAAKi0D,iBACjBhd,EAAUj3C,KAAKm0D,aACrB,IACE,IAAIr+C,GAAU,OAAA9R,EAAAhE,KAAKg3C,aAAL,EAAAhzC,EAAayR,SAAUzV,KAAK8V,QAC1C,GAAI,OAAAxN,EAAAwN,EAAQ0uB,gBAAR,EAAAl8B,EAAmBugC,0BAA2B,CAIhD/yB,EAigBR,SACEs+C,EACA3N,GAEA,MAAM4N,EAAuB5N,EAAYjiB,WAAc,CAAA,EACvD,MAAO,IACF4vB,KACCC,EAAqBx8C,WAAa,CAAA,EACtC2sB,UAAW,IACN4vB,EAAY5vB,UACf2G,uBAAuB,EACvB9C,yBAA0BgsB,EAAqBhsB,2BAA4B,EAC3E9X,kBAAmB8jC,EAAqB9jC,mBAAqB,GAC7D+jC,uBAAwBD,EAAqBC,yBAA0B,EACvE5qB,QAAS,KACTylB,gBAAiBkF,EAAqBlF,gBACtCz7C,KAAM,iBACN4c,SAAU+jC,EAAqB/jC,SAC/BikC,eAAgBF,EAAqBE,gBAAkB,CAAA,EACvDnpB,yBAAyB,EACzBrc,MAAOslC,EAAqBtlC,MAC5Bsc,kBAAmB,MACnBC,mBAAmB,GAGzB,CA1hBkBkpB,OAHgBvd,EAAQxQ,2BAA2BzmC,KAAKsH,MAAMjC,YAAa,CACnFqO,KAAM,mBAE+CoC,EACzD,CACA,GAAI9V,KAAKk0D,WAAa5c,IAAYt3C,KAAKi0D,iBACrC,OAGF,MAAMd,QAAmBlc,EAAQnD,iBAAiB9zC,KAAKsH,MAAMjC,YAAayQ,GAC1E,GAAI9V,KAAKk0D,WAAa5c,IAAYt3C,KAAKi0D,iBACrC,OAGF,MAAM1W,GAAgB,OAAAl0C,EAAArJ,KAAKg3C,aAAL,EAAA3tC,EAAaoM,SAAUK,EACvC2+C,EA8OZ,SAAqC3+C,GAvhBrC,IAAA9R,EAAAsE,EAAAe,EAAAC,EAwhBE,MAAMrF,EAAgBsJ,GAAUuI,EAAQ7R,eAAiB,IACnDouC,GAAoB,OAAA/pC,EAAA,OAAAtE,EAAA8R,EAAQ+1B,sBAAa3hB,eAArB,EAAA5hB,EAA+B+pC,oBAAqB,CAAA,EAC9E,MAAO,CACLqiB,uBAAwB5+C,EAAQkvB,kBAC5Bz3B,GAAU,CACRrN,YAAa4V,EAAQkvB,kBAAkB9kC,YACvCghC,gBAAiBprB,EAAQkvB,kBAAkB9D,gBAC3C+D,eAAgBnvB,EAAQkvB,kBAAkBC,sBAE5C,EACJkC,uBAAwBssB,GAAe39C,EAAQqxB,wBAC/C3lC,gBAAiBsU,EAAQtU,gBAAkB+L,GAAUuI,EAAQtU,sBAAmB,EAChFuU,YAAaD,EAAQC,YACrB4+C,kBAAmBpnD,IAAU,OAAAlE,EAAAyM,EAAQkxB,yBAAR,EAAA39B,EAA4B49B,QAAS,IAClElN,OAAO,OAAAzwB,EAAAwM,EAAQ0uB,gBAAR,EAAAl7B,EAAmBogC,UAAW5zB,EAAQikB,MAC7C0Z,uBAAwBlmC,GAAUuI,EAAQ29B,wBAA0B,IACpE9nC,aAAcmK,EAAQnK,aACtBu4B,qBAAsB32B,GAAUmmD,GAAe59C,IAC/C8+C,uBAAwB3wD,EAAcuK,OACpC,CAACyM,EAA4D7W,KAC3D,MAAMxD,EAAOqT,GAAiB7P,GACxBuT,EAAYg8C,GAChB/yD,EACAwD,EAAaC,iBAAmBD,EAAeywD,GAAoBxiB,EAAmBzxC,IAKxF,OAHI+W,IACFsD,EAAWra,GAAQ+W,GAEdsD,GAET,CAAA,GAEFhX,gBACAmjC,eAAgBtxB,EAAQsxB,eACxBt9B,QAASgM,EAAQhM,QACjBvI,OAAQuU,EAAQvU,OAChBulC,SAAUhxB,EAAQgxB,SAClB9J,eAAgBzvB,GAAUuI,EAAQknB,gBAAkB,IACpDhzB,OAAQ8L,EAAQ9L,OAChBjD,KAAM+O,EAAQ/O,KAElB,CAxRkC+tD,CAA4BvX,GAClDwX,EA4dZ,SACE53C,EACAg2C,GAxwBF,IAAAnvD,EAAAsE,EA0wBE,MAAMilD,EAAWrsD,OAAOY,KAAKqxD,GAAY3kD,OAAO,CAACpO,EAAyC4B,KACzD,mBAApBmxD,EAAWnxD,KACpB5B,EAAO4B,GAAOmxD,EAAWnxD,IAEpB5B,GACN,CAAA,GAEH,MAAO,IACF+yD,KACAh2C,KACAowC,EACH1hB,YAAasnB,EAAWtnB,YACxBrH,UAAW,IACN2uB,EAAW3uB,aACXrnB,EAAQqnB,UACX0L,MAAO,IAAK,OAAAlsC,EAAAmvD,EAAW3uB,kBAAXxgC,EAAsBksC,SAAU,OAAA5nC,EAAA6U,EAAQqnB,gBAAR,EAAAl8B,EAAmB4nC,QAGrE,CAlf+B8kB,CAAsBzX,EAAe4V,IA0NpE,SAA2Br9C,EAAiCm/C,GApgB5D,IAAAjxD,EAAAsE,EAAAe,EAAAC,EAqgBE,MAAM4rD,GACHD,EAASl/C,aAAeo/C,GAAgB,OAAAnxD,EAAA8R,EAAQ+1B,oBAAR7nC,EAAqBsM,SAAU,CAAC,SAAShM,SAAS2wD,EAASl/C,aACtG,IAAKm/C,EACH,OAGF,OAAA5sD,EAAAwN,EAAQ++B,qBAARvsC,EAAA0V,KAAAlI,EAA6BA,GAC7B,MAAMs/C,GACHH,EAAS1zD,QAAU4zD,GAAgB,OAAA7rD,EAAA,WAAQuiC,kBAAR,EAAAxiC,EAAqB6gB,eAArB,EAAA5gB,EAA+BkH,QAAS,CAAC,SAASlM,SAAS2wD,EAAS1zD,QAC1G,IAAK6zD,EACH,OAGF,CAAC,kBAAmB,gBAAiB,iBAAkB,cAAe,yBAAyBrzD,QAASq0C,IAlhB1G,IAAApyC,EAmhBI,OAAA,OAAAA,EAAA8R,EAAQsgC,SAAR,EAAApyC,EAAAga,KAAAlI,EAAmBA,IAEvB,CA1OMu/C,CAAkBN,EAAkBN,GAwR1C,SAAsC3+C,EAAiCm/C,GAnkBvE,IAAAjxD,EAAAsE,EAAAe,EAAAC,EAokBE,MAAM4gB,GAAW,OAAAlmB,EAAA8R,EAAQ+1B,kBAAR,EAAA7nC,EAAqBkmB,WAAY,CAAA,EAC7CirC,GAAgB,OAAA7sD,EAAAwN,EAAQ+1B,kBAAR,EAAAvjC,EAAqBgI,SAAU,CAAC,SAAShM,SAAS2wD,EAASl/C,eAC9ED,EAAQC,YAAck/C,EAASl/C,aAE5Bo/C,GAAgBjrC,EAAS1Z,QAAS,CAAC,SAASlM,SAAS2wD,EAAS1zD,UACjEuU,EAAQvU,OAAS0zD,EAAS1zD,QAExB0zD,EAAStpD,eAAiB8nD,GAAevpC,EAASrd,eAAevI,SAAS2wD,EAAStpD,gBACrFmK,EAAQnK,aAAespD,EAAStpD,cAE9BspD,EAAS7tB,iBAAmBqsB,GAAevpC,EAAS+mB,cAAc3sC,SAAS2wD,EAAS7tB,kBACtFtxB,EAAQsxB,eAAiB6tB,EAAS7tB,gBAGlC6tB,EAASl7B,QACRo7B,GAAgB,OAAA9rD,EAAAyM,EAAQ+1B,kBAAR,EAAAxiC,EAAqBqoC,UAAW,CAAC,YAAa,OAAQ,OAAOptC,SAAS2wD,EAASl7B,SAEhGjkB,EAAQikB,MAAQk7B,EAASl7B,MACzBjkB,EAAQ0uB,UAAUkF,QAAUurB,EAASl7B,OAEnCk7B,EAASnrD,UAAYqrD,GAAgBjrC,EAAS3Z,SAAU,CAAC,KAAM,SAASjM,SAAS2wD,EAASnrD,WAC5FgM,EAAQhM,QAAUmrD,EAASnrD,SAEzBmrD,EAASjrD,SAAWmrD,GAAgBjrC,EAASzZ,QAAS,CAAC,KAAM,SAASnM,SAAS2wD,EAASjrD,UAC1F8L,EAAQ9L,OAASirD,EAASjrD,QAEvBirD,EAASnuB,WAAYmuB,EAASluD,MAAS0sD,GAAevpC,EAAS+c,OAAO3iC,SAAS2wD,EAASluD,QAC3F+O,EAAQ/O,KAAOkuD,EAASluD,MAE1B,GAAIkuD,EAASnuB,SAAU,CACrB,MAAMwuB,EAAmBL,EAASN,kBAAkBj1D,OACjDqH,IAAU0sD,GAAevpC,EAAS+c,OAAO3iC,SAASyC,IAErD+O,EAAQkxB,mBAAqB,IACxBlxB,EAAQkxB,mBACXC,MAAO0V,GAAO,KAAK,OAAArzC,EAAAwM,EAAQkxB,yBAAR,EAAA19B,EAA4B29B,QAAS,MAAQquB,IAEpE,CAEA,MAAMC,EAAqB,CAAC,KAAM,QAC5BC,MAAyBzkD,IAAI,IAC9BokD,GAAgBjrC,EAAS8S,eAAgBu4B,MACzCJ,GAAgBr/C,EAAQ29B,uBAAwB8hB,KAErDz/C,EAAQknB,eAAiB2f,GAAO,IAC1B7mC,EAAQknB,gBAAkB,MAC3Bi4B,EAASj4B,eAAet9B,OAAQ8/B,IAAcg2B,EAAmBvjD,IAAIutB,MAE1E1pB,EAAQ29B,uBA0HV,SAA2Bh+B,EAAeq0B,GACxC,MAAM/gB,MAAWhY,IACjB,OAAO0E,EAAO/V,OAAQ4P,IACpB,MAAMqI,EAAYuE,GAAe5M,EAAOw6B,GACxC,SAAKnyB,GAAaoR,EAAK9W,IAAI0F,MAG3BoR,EAAK1X,IAAIsG,IACF,IAEX,CApImC89C,CAC/B,IACM3/C,EAAQ29B,wBAA0B,MACnCwhB,EAASxhB,uBAAuB/zC,OAChC8/B,IAAcg2B,EAAmBvjD,IAAIiK,GAAesjB,EAAU+1B,MAGnEA,GAGF,MAAMr1D,EAAc+0D,EAASP,uBACvBgB,GAAwBxrC,EAASjqB,cAAgB,IAAI4D,KACxDsY,GAAgBA,EAAOvb,cAASV,WAAaA,cAAeic,EAAOqlB,QAAS,MAAAthC,OAAA,EAAAA,EAAaghC,mBAExF,MAAAhhC,OAAA,EAAAA,EAAaA,eAAgBw1D,IAC/B5/C,EAAQkvB,kBAAoB,IACtBlvB,EAAQkvB,mBAAqB,CAAA,KAC9B9kC,IAIP,MAAMmyC,EAAoBnoB,EAASmoB,mBAAqB,CAAA,EAClDwhB,EAA2BoB,EAAShxD,cAAcvE,OACrD0E,IAAkBywD,GAAoBxiB,EAAmBp+B,GAAiB7P,KAEvEuxD,EAAmB,IAAI5kD,IAAI8iD,EAAyBxzD,IAAI4T,KAC9D6B,EAAQ7R,cA4GV,SAAsBwR,GACpB,MAAMsT,MAAWhY,IACjB,OAAO0E,EAAO/V,OAAQ4P,IACpB,MAAM1O,EAAOqT,GAAiB3E,GAC9B,SAAK1O,GAAQmoB,EAAK9W,IAAIrR,MAGtBmoB,EAAK1X,IAAIzQ,IACF,IAEX,CAtH0Bg1D,CAAa,IAAK9/C,EAAQ7R,eAAiB,MAAQ4vD,IAE3E,MAAMryD,EAAkB+L,GAAUuI,EAAQtU,iBAAmB,CAAA,GAC7Dm0D,EAAiB5zD,QAASnB,IAjpB5B,IAAAoD,GAkpBQ,OAAAA,EAAAixD,EAASzzD,wBAATwC,EAA2BpD,MAC7BY,EAAgBZ,GAAQq0D,EAASzzD,gBAAgBZ,MAGjDM,OAAOY,KAAKN,GAAiB0C,OAC/B4R,EAAQtU,gBAAkBA,SAEnBsU,EAAQtU,gBAEjB,MAAMq0D,EAAuB30D,OAAOY,KAAKmzD,EAASzzD,iBAAmB,CAAA,GAClE9B,OAAQkB,IAAU+0D,EAAiB1jD,IAAIrR,IACvCsO,QAAStO,IA7pBd,IAAAoD,EA6pBuB,OAAA,OAAAA,EAAAixD,EAASzzD,wBAATwC,EAA2BpD,KAAS,KACnDk1D,EAA6BH,EAAiBvnD,KAChD6mD,EAAS9tB,uBAAuBznC,OAAQgV,IAAoBmhD,EAAqBvxD,SAASoQ,IAC1F,GACJoB,EAAQqxB,uBAAyBwV,GAAO,IACnC8W,GAAe39C,EAAQqxB,2BACvBjmC,OAAOY,KAAKN,GACZ9B,OAAQkB,GAAS+0D,EAAiB1jD,IAAIrR,IACtCsO,QAAStO,GAASY,EAAgBZ,OAClCk1D,IAGL,MAAM7xB,EAAWyvB,GAAe59C,GAChC5U,OAAOY,KAAKuwC,GAAmBtwC,QAASnB,IACtC,MAAMm1D,EAAed,EAASL,uBAAuBh0D,GACjDm1D,IACF9xB,EAAS8xB,EAAa/zD,KAAOiiC,EAAS8xB,EAAa/zD,KAAKtC,OAAQ4P,IAAWymD,EAAa95C,MAAM3X,SAASgL,QAG1GwG,EAAQ7R,eAAiB,IAAIlC,QAASqC,IACrC,MAAMxD,EAAOqT,GAAiB7P,GACxB4xD,EAAqBrC,GAA8B/yD,EAAMyxC,EAAkBzxC,IAC7Eo1D,GACF/xB,EAAS+xB,EAAmBh0D,KAAK6D,QAAQmwD,EAAmB/5C,SAGhE05C,EAAiB5zD,QAASnB,IACxB,MAAM+W,EAAYs9C,EAASL,uBAAuBh0D,GAC9C+W,GACFssB,EAAStsB,EAAU3V,KAAK6D,QAAQ8R,EAAUsE,SAG9C,MAAMg6C,EAAqB/0D,OAAOuU,OAAOw/C,EAASL,wBAAwBpmD,OACxE,CAAC0nD,EAAYv+C,KAAA,IACRu+C,EACH,CAACv+C,EAAU3V,KAAM26C,GAAO,IAAKuZ,EAAWv+C,EAAU3V,MAAQ,MAAQ2V,EAAUsE,UAE9E,CAAA,GAEE05C,EAAiBvnD,MACnB,CAACklD,GAA4BC,IAA8BxxD,QAASC,IAClEiiC,EAASjiC,GAAK6D,QACTovD,EAAS/wB,qBAAqBliC,GAAKtC,OAAQ4P,KAAY2mD,EAAmBj0D,IAAQ,IAAIsC,SAASgL,OAIxGwG,EAAQouB,qBAAuB,CAC7BovB,CAACA,IAA6B3W,GAAO1Y,EAASqvB,KAC9CC,CAACA,IAA+B5W,GAAO1Y,EAASsvB,MAElDryD,OAAOY,KAAKgU,EAAQouB,sBAAsBniC,QAASC,IAC5C8T,EAAQouB,qBAAqBliC,GAAKkC,eAC9B4R,EAAQouB,qBAAqBliC,IAG1C,CAxaMm0D,CAA6BpB,EAAkBN,GAC/Cz0D,KAAK8V,QAAUi/C,EACf/0D,KAAK+2C,aAAajhC,QAAUi/C,EAC5B/0D,KAAK+2C,aAAaH,aAAeme,EACjC,OAAAzrD,EAAAtJ,KAAKg3C,WAAQgB,UAAU+c,GACvB/0D,KAAKqd,SAAS,CAAEvH,QAASi/C,EAAkBqB,qBAAqB,EAAO1rC,QAAQ,GACjF,OAAS2rC,GACFr2D,KAAKk0D,WAAa5c,IAAYt3C,KAAKi0D,kBACtCj0D,KAAKqd,SAAS,CAAE+4C,qBAAqB,EAAM1rC,QAAQ,GAEvD,GAGF1qB,KAAQs2D,mBAAqB,KAC3Bt2D,KAAKqd,SAAS,CAAE+4C,qBAAqB,EAAO1rC,QAAQ,IAC7C1qB,KAAK8zC,oBAiBd9zC,KAAQif,OAAS,CAACnJ,EAAA,CAAkC9R,GAAA,OAAAA,EAAAhE,KAAKg3C,aAAL,EAAAhzC,EAAayR,OAA/C,IAAyDzV,KAAK8V,WA5UlF,IAAA9R,EA6UI,MAAMuyD,EAvJH,SAAwCzgD,GAtL/C,IAAA9R,EAuLE,MAAMuyD,EAAchpD,GAAUuI,GACxBgwB,EAAmB,IAAMhwB,EAAQgwB,kBAAoB,CAAA,GA6B3D,cA5BOA,EAAiBwtB,WACjBxtB,EAAiBytB,WACjBztB,EAAiB0tB,IAExB+C,EAAYzwB,iBAAmB,IAC1BA,KACA8tB,GAA0B99C,IAE/BygD,EAAY/8B,MAAQ1jB,EAAQ0jB,MAAQ,IAAIn5B,IAAKgmC,GAAaA,EAAI/2B,OAAS+2B,GACvEkwB,EAAYC,WAAa,OAAAxyD,EAAA8R,EAAQyf,iBAARvxB,EAAkByxB,QACvC3f,EAAQkzB,kBACVutB,EAAYhhC,SAAW,IAClBzf,EAAQyf,SACX5mB,IAAKmH,EAAQkzB,kBAAkBmd,eAC/BtsC,IAAK/D,EAAQkzB,kBAAkBkd,gBAExBpwC,EAAQyf,WACjBghC,EAAYhhC,SAAW,IAClBzf,EAAQyf,SACX5mB,IAAKmH,EAAQyf,SAASE,QACtB5b,IAAK/D,EAAQyf,SAASE,UAGS,gBAA/B8gC,EAAYnvB,iBACdmvB,EAAYnvB,eAAiB,WAExBmvB,EAAYryB,4BACZqyB,EAAYv5B,eACZu5B,CACT,CAuHwBE,CAA+B3gD,GAC7CpC,EAAO,OAAA1P,EAAAuyD,EAAY/xB,kBAAZxgC,EAAuB0P,KACpC,OAAI1T,KAAKsH,MAAMkV,mBAA8B,mBAAT9I,GAAsC,iBAATA,EACxD1T,KAAKsH,MAAM8W,WAAWm4C,GAExBv2D,KAAK2D,MAAMia,YAAYqB,OAAO,IACnCjf,KAAKyxB,QAAQxc,SAASyhD,kBAAkBC,iBAAiBJ,EAAoBv2D,KAAKsH,MAAMjC,eAI5FrF,KAAQsF,eAAiB,KACvBtF,KAAKo9B,sCACLp9B,KAAK0d,8BAAgC1d,KAAKsH,MAAMjC,YAAYkD,aAAa8V,cAAcre,KAAK42D,sBAC5F52D,KAAKsH,MAAMjC,YAAYkD,aAAaiV,WAGtCxd,KAAQ42D,qBAAuB,KA7VjC,IAAA5yD,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EA+VI,GADA/8B,KAAKo9B,sCACDp9B,KAAKk0D,UACP,OAGF,MAAMp+C,GAAU,OAAA9R,EAAAhE,KAAKg3C,eAALhzC,EAAayR,SAAUzV,KAAK8V,QACtC+gD,EAAa,OAAAvtD,EAAA,SAAA,cAAK3F,MAAMia,YAAYk5C,WAAvB,EAAAxuD,EAA6B2pB,gBAA7B,EAAA5oB,EAAwC0xB,eAAxCzxB,EAAgDb,KAChEsmB,GAAiC,qBAAfA,EAAM5vB,MAErB43D,EAAqB,OAAAh6B,EAAA,OAAAviB,EAAA,MAAAq8C,OAAA,EAAAA,EAAYplC,cAAZ,EAAAjX,EAAsB,kCAA0B1E,EAAQvU,QACnF,IAAKw1D,EACH,OAGF,IAAIC,EAAe,6BACfh3D,KAAKsH,MAAM9C,aAAaF,SAAS,6BACnC0yD,EAAe,iBAEbh3D,KAAKsH,MAAM9C,aAAaF,SAAS,qCACnC0yD,EAAe,mBAEbh3D,KAAKsH,MAAM9C,aAAaF,SAAS,iBACnC0yD,EAAe,gBAEjBh3D,KAAKsH,MAAM9C,aAAaG,GAAGqyD,EAAc,CACvC9uD,UAAW4N,EAAQC,YACnBnW,SAAU,MACV2B,OAAQuU,EAAQvU,OAChBmF,YAAaqwD,KAIjB/2D,KAAQo9B,oCAAsC,KA9XhD,IAAAp5B,EA+XI,OAAAA,EAAAhE,KAAK0d,gCAAL1Z,EAAAga,KAAAhe,MACAA,KAAK0d,mCAAgC,GAtIrC1d,KAAKi3C,QAAU3vC,EAAM2vC,QACrBj3C,KAAK8V,QAAUvI,GAAUjG,EAAMwO,SAC/B9V,KAAK+2C,aAAeL,GAAuC12C,KAAK8V,SAChE9V,KAAK2D,MAAQ,CACXmS,QAAS9V,KAAK8V,QACdsgD,qBAAqB,EACrB1rC,OAAQ1S,QAAQ,OAAAhU,EAAAhE,KAAK8V,QAAQ+1B,sBAAa3hB,UAC1CtM,YAAa,IAAIC,EAAY,CAC3BxY,YAAaiC,EAAMjC,YACnBN,MAAOuC,EAAMvC,OAAS,6BACtB+Y,UAAW,IAAM9d,KAAKsH,MAAMyW,eAC5BzY,eAAgBtF,KAAKsF,iBAG3B,CA5BA,WAAcga,CAAKhY,EAAuC22B,GACxD,OAAO1e,EAAWD,KAChB23C,GACA3vD,EACA,CAAEkY,gBAAiB,yBACnBye,EAEJ,CAuBO,iBAAApZ,GACA7kB,KAAK8zC,kBACZ,CAEO,oBAAA/uB,GACL/kB,KAAKk0D,WAAY,EACjBl0D,KAAKi0D,mBACLj0D,KAAKo9B,qCACP,CA4CQ,UAAA+2B,GA9TV,IAAAnwD,EA+TI,IAAKhE,KAAKi3C,QAAS,CACjB,KAAK,OAAAjzC,EAAAhE,KAAKyxB,cAAL,EAAAztB,EAAciR,UACjB,MAAM,IAAI+rB,MAAM,0DAElB,MAAMk2B,EAAWl3D,KAAKyxB,QAAQxc,SAASkiD,wBACvCn3D,KAAKi3C,QAAU,IAAIlB,GACjBmhB,EAASE,YAAkD,MAAO,8BAClEF,EAASE,YAAiD,MAAO,oCAErE,CACA,OAAOp3D,KAAKi3C,OACd,CAyDO,MAAAjyB,GAnYT,IAAAhhB,EAoYI,MAAMqB,YAAEA,EAAA0Y,aAAaA,EAAAhZ,MAAcA,GAAU/E,KAAKsH,OAC5CwO,QAAEA,EAAAsgD,oBAASA,EAAA1rC,OAAqBA,EAAA9M,YAAQA,GAAgB5d,KAAK2D,MAEnE,GAAIyyD,EACF,OACE3zD,GAAAyE,cAAC,OAAI6D,UAAU,wEACZ,MAAA,CAAIA,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CAAO,aAAW,QAAQ6D,UAAU,QAAQ6T,QAASb,EAAc5e,KAAK,UACvEsD,GAAAyE,cAAC,OAAA,CAAK,cAAY,QAAO,MAE3BzE,GAAAyE,cAAC,UAAInC,GAAS,wBAEhBtC,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,OAAI6D,UAAU,qBAAqBgd,KAAK,SAAQ,+GAInDtlB,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wDACV6T,QAASb,EACT5e,KAAK,UACN,SAGDsD,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkB6T,QAAS5e,KAAKs2D,mBAAoBn3D,KAAK,UAAS,WAQ5F,MAAM83C,EAAUj3C,KAAKm0D,aAErB,OACE1xD,GAAAyE,cAACmwD,GAAA,CACCr1D,IAAK0oB,EAAS,SAAW,UACzBtM,WAAYpe,KAAKif,OACjBlB,eACAxS,QAASxG,GAAS,sBAClBuyD,cAAexhD,EACfpO,SAAUgjB,EACV2gB,mBAAmB,OAAArnC,EAAA8R,EAAQ0uB,gBAAR,EAAAxgC,EAAmBqnC,oBAAqB,OAC3DztB,cACAs5B,SAAUxB,GACV1wB,OAAQ,EAAGgyB,SAAQugB,UAASC,aAC1Bx3D,KAAKg3C,OAASA,EACdh3C,KAAK8V,QAAUkhC,EAAOvhC,OACtB,MAAMgiD,EAAY,CAAExgB,UAASlzC,IAAKsB,EAAa0xC,aAAc/2C,KAAK+2C,aAAcC,UAChF,OACEv0C,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,iBACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACqiD,GAAA,CAAyBznC,IAAK81C,KAAcH,EAAW5f,qBAE1D2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,QACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAAC2nD,GAAA,CAAyB/sC,IAAK81C,KAAcH,EAAW5f,qBAE1D2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,gBACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACmpD,GAAA,CAAwBvuC,IAAK81C,KAAcH,EAAW5f,qBAEzD2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,wBACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACmmD,GAAA,CAAoBvrC,IAAK81C,KAAcH,EAAW5f,qBAErD2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,iBACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACo4C,GAAA,CAA4Bx9B,IAAK81C,KAAcH,EAAW5f,qBAE7D2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,YACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACu1C,GAAA,CAAwB36B,IAAK81C,KAAcH,EAAW5f,qBAEzD2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,WACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAACghD,GAAA,CAASpmC,IAAK81C,KAAcH,EAAW5f,qBAE1C2f,WAEF/0D,GAAAyE,cAACwwD,GAAA,CACC5xD,MAAM,oBACN6xD,MAAOJ,IACPvyC,OAAQ,EAAG4yC,WAAU/f,sBACnBp1C,GAAAyE,cAAC4yC,GAAA,CAAiBh4B,IAAK81C,KAAcH,EAAW5f,qBAElD2f,cAOd,EArSWxD,GAIG90B,YAAcC,EAJjB60B,GAOG/rC,aAA+E,CAC3F7J,WAAY8J,EACZnK,aAAcmK,GA+RX,MAAM+uC,GAA2B/1D,OAAOsO,OAAOpI,EAAW4sD,IAAoC,CACnG10C,KAAM00C,GAAkC10C,OAqN1C,SAASu1C,GAAoBxiB,EAAwCzxC,GACnE,OACEyxC,EAAkBzxC,IAClBM,OAAOuU,OAAO48B,GAAmB5pC,KAAMrE,IACpCA,EAAa0M,WAAa,IAAIjN,KAAMuN,GAAkBA,EAASxQ,OAASA,GAG/E,CAEA,SAAS+7C,GAAOlnC,GACd,OAAOnD,MAAMkD,KAAK,IAAIzE,IAAI0E,EAAO/V,OAAOsY,UAC1C,CAEA,SAASkE,GAAe5M,EAAYw6B,GAClC,MAAqB,iBAAVx6B,EACFA,EAEFw6B,EAAWzpC,IAAK8jC,GAAa,MAAA70B,OAAA,EAAAA,EAAQ60B,IAAW17B,KAAM07B,GAAiC,iBAAbA,EACnF,CAEA,SAASgxB,GAAgB1/C,EAAeq0B,GACtC,OAAQr0B,GAAU,IAAIpV,IAAKiP,GAAU4M,GAAe5M,EAAOw6B,IAAapqC,OAAOsY,QACjF,mTCntBO,MAAM6/C,WAAiCp1D,GAAMC,UAA7C,WAAA5B,GAAAyjB,SAAA8C,WA4FLrnB,KAAQ83D,iBAAoB37C,IAC1B,MAAM7M,EAAS6M,EAASA,EAAO7M,MAAQ,KACvCtP,KAAKsH,MAAMiT,SAAS,CAClBonB,eAAgB3hC,KAAKsH,MAAMywD,uBAC3Bn2B,UAAWtyB,EACXvC,OAAQ/M,KAAKsH,MAAM0wD,eACnBx1B,eAAgBxiC,KAAKsH,MAAM2wD,0BAI/Bj4D,KAAQk4D,mBAAsB/7C,IAC5B,MAAM7M,EAAS6M,EAASA,EAAO7M,MAAQ,KACvCtP,KAAKsH,MAAMiT,SAAS,CAClBonB,eAAgB3hC,KAAKsH,MAAMywD,uBAC3Bn2B,UAAW5hC,KAAKsH,MAAM6wD,kBACtBprD,OAAQuC,EACRkzB,eAAgBxiC,KAAKsH,MAAM2wD,0BAI/Bj4D,KAAQo4D,2BAA8Bj8C,IACpC,MAAM7M,EAAS6M,EAASA,EAAO7M,MAAQ,KACvCtP,KAAKsH,MAAMiT,SAAS,CAClBonB,eAAgBryB,EAChBsyB,UAAW5hC,KAAKsH,MAAM6wD,kBACtBprD,OAAQ/M,KAAKsH,MAAM0wD,eACnBx1B,eAA0B,OAAVlzB,GAAyBtP,KAAKsH,MAAM2wD,0BAIxDj4D,KAAQq4D,yBAA4B9jC,IAClC,MAAMjlB,GAASilB,EACfv0B,KAAKsH,MAAMiT,SAAS,CAClBonB,eAAgB3hC,KAAKsH,MAAMywD,uBAC3Bn2B,UAAW5hC,KAAKsH,MAAM6wD,kBACtBprD,OAAQuC,EACRkzB,eAAgBxiC,KAAKsH,MAAM2wD,0BAI/Bj4D,KAAQs4D,qBAAwBj4C,IAC9BrgB,KAAKsH,MAAMiT,SAAS,CAClBonB,eAAgB3hC,KAAKsH,MAAMywD,uBAC3Bn2B,UAAW5hC,KAAKsH,MAAM6wD,kBACtBprD,OAAQ/M,KAAKsH,MAAM0wD,eACnBx1B,eAAgBniB,IAEpB,CA1IO,MAAA2E,GACL,MAAMuzC,GAAmCv4D,KAAKsH,MAAMqrD,oBAAsB,IAAItyD,IAAKshC,IAAA,CACjF77B,MAAO67B,EACPryB,MAAOqyB,KAEH62B,GAAyBx4D,KAAKsH,MAAMsrD,UAAY,IAAIvyD,IAAKo4D,IAAA,CAAY3yD,MAAO2yD,EAAO,GAAInpD,MAAOmpD,KAC9FC,GAA2B14D,KAAKsH,MAAMurD,YAAc,IAAIxyD,IAAK0M,IAAA,CACjEjH,MAAOiH,EAAS,GAChBuC,MAAOvC,KAEH4rD,EAAyB34D,KAAKsH,MAAM6wD,kBAAoBn4D,KAAKsH,MAAM6wD,kBAAoB,GAAK,KAC5FS,EAAsB54D,KAAKsH,MAAM0wD,eAAiBh4D,KAAKsH,MAAM0wD,eAAiB,GAAK,KACnFa,EAA8B74D,KAAKsH,MAAMywD,uBAAyB/3D,KAAKsH,MAAMywD,uBAAyB,KAE5G,wBACG,MAAA,KACCt1D,GAAAyE,cAAC,OAAI6D,UAAU,wBACZ,MAAA,CAAIA,UAAU,2BACbtI,GAAAyE,cAAC,SAAE,YAELzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC4xD,GAAA,CACCp+C,QAAS69C,EACTQ,WAAW,EACXzpD,MAAO,CAAExJ,MAAO+yD,EAA6BvpD,MAAOtP,KAAKsH,MAAMywD,wBAC/Dx9C,SAAUva,KAAKo4D,+BAIrB31D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,wCACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,SAAE,UACHzE,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,uCAEhB1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC4xD,GAAA,CACCp+C,QAAS89C,EACTO,WAAW,EACXzpD,MAAO,CAAExJ,MAAO6yD,EAAwBrpD,MAAOtP,KAAKsH,MAAM6wD,mBAC1D59C,SAAUva,KAAK83D,qBAIrBr1D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,wCACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,2BACbtI,GAAAyE,cAAC,IAAA,KAAE,gBACHzE,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,wCAEhB1F,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACZ/K,KAAKsH,MAAM2wD,uBACVx1D,GAAAyE,cAAC,QAAA,CACC/H,KAAK,SACLyB,KAAK,SACLmK,UAAU,eACVuE,MAAOtP,KAAKsH,MAAM0wD,eAClBz9C,SAAWwB,GAAU/b,KAAKq4D,yBAAyBt8C,EAAMlQ,OAAOyD,SAGlE7M,GAAAyE,cAAC4xD,GAAA,CACCp+C,QAASg+C,EACTK,WAAW,EACXzpD,MAAO,CAAExJ,MAAO8yD,EAAqBtpD,MAAOtP,KAAKsH,MAAM0wD,gBACvDz9C,SAAUva,KAAKk4D,uBAKgB,OAAtCl4D,KAAKsH,MAAMywD,uBACVt1D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,yDACZ,MAAA,CAAIA,UAAU,4BACftI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,OAAA,CAAK6D,UAAU,sDACdtI,GAAAyE,cAAC8xD,GAAA,CACCp4D,KAAK,iBACL2iB,KAAK,kBACLlD,QAASrgB,KAAKsH,MAAM2wD,uBACpB19C,SAAWwB,IACT/b,KAAKs4D,qBAAqBv8C,EAAMlQ,OAAOwU,YAG3C5d,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+DACbtI,GAAAyE,cAACy0C,EAAA,CAAUxzC,GAAG,mDAKpB,KAGV,EC1GF,MAAM8wD,GAA+B,IAAIx3B,GAElC,SAASy3B,IAAyBpjD,QAAEA,EAAAqjD,cAASA,IAClD,MAAMh2B,oBAAEA,GAAwB3Y,IAC1B4uC,EAAatjD,GACZ7U,EAAQo4D,GAAa52D,GAAM+E,SAAgC,IAuCpE,SAA0BsO,GACxB,GAAIA,EAAQ0uB,UAAUiF,eACpB,MAAO,CACLjH,eAAgB82B,GAAiBxjD,EAAQnK,iBACtCmK,EAAQ0uB,UAAUiF,gBAIzB,MAAMmjB,EAAS92C,EAAQnK,aACnBstD,GAA6Bp2B,yBA8DAl3B,EA9DkDmK,EAAQnK,aA+DpF2tD,GAAiB3tD,GAAgBA,EAAanB,QAAQ,QAAS,IAAMmB,IA9DxE,CAAEg2B,eAAgB,KAAMC,UAAW,KAAM70B,OAAQ,MAE/C9L,EAASs4D,GACb,IACK3M,EACHpqB,eAAgB82B,GAAiBxjD,EAAQnK,eAE3C6tD,GAAW1jD,EAAS82C,IAsDxB,IAAmCjhD,EAnDjC,OADAmK,EAAQ0uB,UAAUiF,eAAiBxoC,EAC5BA,CACT,CA5D0Ew4D,CAAiBL,IACnF/F,EAAUmG,GAAWJ,EAAYn4D,GACjCy4D,EAAkBH,GAAkBt4D,EAAQoyD,GAuBlD,OACE5wD,GAAAyE,cAAC2wD,GAAA,CACClF,mBAAoBU,EAAQV,mBAC5BE,WAAYQ,EAAQR,WACpBt4C,SAzBkBo/C,IACpB,MACMC,EAAiBL,GAAkBI,EADrBH,GAAWJ,EAAYO,IAErCE,EAAmBZ,GAA6Bv2B,2BACpDk3B,EAAej4B,eACfi4B,EAAeh4B,UACfg4B,EAAe7sD,OACf6sD,EAAep3B,gBAEjB42B,EAAW50B,UAAUiF,eAAiBmwB,EACtCR,EAAWztD,aAAekuD,EAC1BT,EAAWlkB,uBAAyBkkB,EAAWlkB,sBAAsBkkB,GACrEC,EAAUO,GACVz2B,EACGwH,uBAAuByuB,EAAWrxB,iBAAkB8xB,GACpDt6D,KAAMglC,IACL60B,EAAW50B,UAAUD,oBAAsBA,IAE/C40B,GAAiBA,EAAcU,IAQ7B5B,uBAAwByB,EAAgBl3B,eACxCu1B,uBAAwB2B,EAAgB/3B,eACxCq2B,eAAgB0B,EAAgB3sD,OAChCorD,kBAAmBuB,EAAgB93B,UACnCgxB,SAAUS,EAAQT,UAGxB,CAyBA,SAAS2G,GACPt4D,EACAoyD,GAEA,MAAM1xB,EAAiB1gC,EAAO0gC,gBAAkB0xB,EAAQV,mBAAmB,IAAM,KAC3E/wB,EAAY3gC,EAAO2gC,WAAayxB,EAAQT,SAAS,GACjDC,EAAaQ,EAAQR,WAAW3uD,OAClCmvD,EAAQR,WACRjxB,EACAq3B,GAA6B52B,oCAAoCV,EAAgBC,GACjF,GAEJ,MAAO,CACLY,eAAgBxqB,QAAQ/W,EAAOuhC,gBAC/Bb,iBACA50B,OAAQ9L,EAAO8L,QAAU8lD,EAAW,GACpCjxB,YAEJ,CAEA,SAAS43B,GAAW1jD,EAAc7U,GAhGlC,IAAA+C,EAAAsE,EAiGE,MAAMmqD,EAAsB38C,EAAQ+1B,YAAY4mB,qBAAuB,CAAA,EACjExjD,EAAW6G,EAAQgxB,SAAWhxB,EAAQvU,OAASuU,EAAQ/O,KACvD+H,EACJ,OAAAxG,EAAA,OAAAtE,EAAA8R,EAAQ+1B,YAAYmE,gCAApB,EAAAhsC,EAAgD8R,EAAQC,mBAAxD,EAAAzN,EAAsEwG,2BAClE8jD,EACJH,EAAoBG,WACnB3jD,GAAYH,EACTmqD,GAA6Bl3B,iCAAiC9yB,EAAUH,GACxE,IACAgrD,EAAe74D,EAAO2gC,WAAagxB,EAAS,GAElD,MAAO,CACLD,mBACEF,EAAoBE,oBAAsBsG,GAA6Bj3B,kCACzE6wB,WACEJ,EAAoBI,aACnBiH,EACGb,GAA6B52B,oCAAoCphC,EAAO0gC,gBAAkB,KAAMm4B,GAChG,IACNlH,WAEJ,CAEA,SAAS0G,GAAiB3tD,GACxB,OAAOqM,QAAQrM,GAAgBA,EAAawvB,SAAS,QACvD,CCjHO,SAAS4+B,IAAoCxwB,0BAClDA,IAEA,MAAMywB,EAAa,MAAAzwB,OAAA,EAAAA,EAA2BwhB,mBAC9C,OAAIn9C,GAAQosD,GACH,KAIPv3D,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACX7J,OAAOmX,QAAQ2hD,GAAY35D,IAAI,EAAEO,EAAMkqD,KACtCroD,GAAAyE,cAACzE,GAAMwI,SAAN,CAAejJ,IAAKpB,GACnB6B,GAAAyE,cAAC,KAAA,KAAG,aACJzE,GAAAyE,cAAC,KAAA,KAAItG,GACc,MAAlBkqD,EAAUI,MACTzoD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,QACJzE,GAAAyE,cAAC,KAAA,KAAI4jD,EAAUI,OAGnBzoD,GAAAyE,cAAC,KAAA,KAAG,iBACJzE,GAAAyE,cAAC,KAAA,MAAK4jD,EAAUD,cAAgB,IAAInlD,KAAK,SAKnD,CCLA,SAASu0D,GAAcla,GA9BvB,IAAA/7C,EA+BE,OAAOgU,SAAQ,OAAAhU,EAAA+7C,EAAO7/C,kBAAP,EAAA8D,EAAoByV,SAAUsmC,EAAO7e,iBAPtD,SAA0B5xB,EAAgBgU,EAF1B,YAGd,MACmB,iBAAVhU,GAAsB6G,OAAO4D,SAASzK,IAAU6G,OAAOiG,UAAU9M,IAAUA,GAAS,GAAKA,GAASgU,CAE7G,CAGyEykC,CAAiBhI,EAAO7a,iBACjG,CAEO,MAAMg1B,WAAwCz3D,GAAMC,UAQlD,WAAA5B,CAAYwG,GACjBid,MAAMjd,GAkBRtH,KAAQif,OAAS,KACfjf,KAAK2D,MAAMia,YAAYqB,OAAO,IAC5BolC,GAA2BG,wBACzBxkD,KAAKsH,MAAMjC,YACXrF,KAAKsH,MAAMZ,YACX1G,KAAK2D,MAAMo8C,UAtBf,MAAMnoB,EAAStwB,EAAMy4C,OAAS,OAAS,MACjCA,EAASxyC,GAAUjG,EAAMy4C,QAAU,CAAE7a,gBAAiB,MAC5Di1B,QAAQC,eAAera,EAAQ,kBAC/B//C,KAAK2D,MAAQ,CACXo8C,SACAniC,YAAa,IAAIC,EAAY,CAC3BxY,YAAaiC,EAAMjC,YACnBN,MAAO,GAAG6yB,4BAAiCtwB,EAAMZ,YAAY9F,OAC7Dkd,UAAW,KApDnB,IAAA9Z,EAoDyB,OAAA,OAAAA,EAAAsD,EAAMyW,qBAAN/Z,EAAAga,KAAA1W,IACjBhC,eAAgB,KArDxB,IAAAtB,EAAAsE,EAAAe,EAsDU,OAAAf,EAAA,OAAAtE,EAAAsD,EAAMjC,YAAYkD,mBAAlB,EAAAvE,EAAgCwZ,UAAhClV,EAAA0V,KAAAha,GACA,OAAAqF,EAAA/B,EAAM8W,aAAN/U,EAAA2U,KAAA1W,MAIR,CArBA,WAAcgY,CAAKhY,GACjB,OAAOiY,EAAWD,KAAK46C,GAAiC5yD,EAAO,CAAEkY,gBAAiB,YACpF,CA+BO,MAAAwF,GACL,MAAMvI,GAASzc,KAAKsH,MAAMy4C,OAC1B,OACEt9C,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAACqX,EAAA,CAAmBC,QAASxe,KAAK2D,MAAMia,cACxCnb,GAAAyE,cAACuX,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,eAAe0R,EAAQ,MAAQ,OAAO,wBAEtDha,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAACy8C,GAAA,CACCnjD,QAASR,KAAKsH,MAAMZ,YAAYlG,QAChCu/C,OAAQ//C,KAAK2D,MAAMo8C,OACnBxlC,SAAWwlC,GAAW//C,KAAKqd,SAAS,CAAE0iC,cAG1Ct9C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkB5L,KAAK,SAASyf,QAAS,KAxFrE,IAAA5a,EAAAsE,EAwF2E,OAAA,OAAAA,GAAAtE,EAAAhE,KAAKsH,OAAMyW,mBAAX,EAAAzV,EAAA0V,KAAAha,KAA6B,UAG9FvB,GAAAyE,cAAC2X,EAAA,CACCjW,YAAaqxD,GAAcj6D,KAAK2D,MAAMo8C,QACtCj6C,MAAO2W,EAAQ,SAAW,SAC1BmC,QAAS5e,KAAKif,OACdX,WAAYte,KAAK2D,MAAMia,YAAYU,cAK7C,ECnFK,SAAS+7C,IAA4Bh1D,YAC1CA,EAAAi1D,iBACAA,EAAA5zD,YACAA,EAAAq5C,OACAA,IArBF,IAAA/7C,EAuBE,MAAMu2D,EAAmB3iC,IACvB4iC,GAAkB9zD,EAAarB,GAAa9F,KAAMk7D,GAAeA,GAAc7iC,MAGjF,IAAKmoB,EACH,OAAOua,EACL73D,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,0BACZ5L,KAAK,SACLyf,QAAS,IAAM27C,EAAgB,IAAML,GAAgC56C,KAAK,CAAEja,cAAaqB,kBAC1F,2BAGC,KAGN,MAAMg0D,EAAe,KACnBx1D,EAAyBN,QAAQ,CAC/BC,OAAQ,gCAAgC6B,EAAY9F,QACpDkE,WAAY,oBACZtE,QAASkG,EAAYlG,QACrB4E,kBAAmB,CAAEC,cAAaN,MAAO,mCAAmC2B,EAAY9F,QACxFoE,aAAc,IAAMq/C,GAA2BI,wBAAwBp/C,EAAaqB,MAIxF,wBACG,MAAA,CAAIqE,UAAU,mCACbtI,GAAAyE,cAAC,MAAG6D,UAAU,qCACZtI,GAAAyE,cAAC,KAAA,KAAG,gBACJzE,GAAAyE,cAAC,KAAA,KAAI64C,EAAO7/C,aAAe6/C,EAAO9a,gBAAkB,sBACnD,KAAA,KAAG,iBACJxiC,GAAAyE,cAAC,UAAI,OAAAlD,EAAA+7C,EAAO7a,iBAAPlhC,EAA0B,IAAI,aAEpCs2D,GACC73D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,2BACZ5L,KAAK,SACLyf,QAAS,IACP27C,EAAgB,IAAML,GAAgC56C,KAAK,CAAEja,cAAaqB,cAAaq5C,aAE1F,QAGDt9C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,6BACZ5L,KAAK,SACLyf,QAAS,IAAM27C,EAAgBG,IAChC,WAOX,CCjEA,SAAS3S,GAAiBz4C,EAAgB+T,EAAiBC,EAH3C,YAId,MACmB,iBAAVhU,GACP6G,OAAO4D,SAASzK,IAChB6G,OAAOiG,UAAU9M,IACjBA,GAAS+T,GACT/T,GAASgU,CAEb,CAEA,SAAS0kC,GAAoB14C,EAAgBgU,GAC3C,MAAwB,iBAAVhU,GAAsB6G,OAAO4D,SAASzK,IAAUA,EAAQ,aAAMgU,GAAyBhU,EAAQgU,EAC/G,CAMA,SAAS2kC,GAAoBpC,GAnC7B,IAAA7hD,EAoCE,UAAK,OAAAA,EAAA6hD,EAAOA,iBAAQpsC,UAAWosC,EAAOa,qBAIP,iCAA7Bb,EAAOa,mBACkB,+BAAzBb,EAAOc,cAVX,SAAoCr3C,GAClC,MAAwB,iBAAVA,GAAsB6G,OAAO4D,SAASzK,IAAUA,GAAS,CACzE,CAUWqrD,CAA2B9U,EAAOgB,2BAEV,iCAA7BhB,EAAOa,mBAAiF,uBAAzBb,EAAOc,iBAGnEqB,GAAoBnC,EAAOQ,oBAAsBruC,QAAQ6tC,EAAOqB,wBACzE,CAyDA,SAAS0T,GAActzD,GA1GvB,IAAAtD,EAAAsE,EAAAe,EAAAC,EA2GE,OAAOiE,GACLjG,EAAMy4C,QAAU,CACdmG,eAAgB,OAAA59C,EAAA,OAAAtE,EAAAsD,EAAMZ,YAAY6uB,eAAlB,EAAAvxB,EAA4B6V,KAA5BvR,EAAmC,EACnD69C,eAAgB,OAAA78C,EAAA,OAAAD,EAAA/B,EAAMZ,YAAY6uB,eAAlB,EAAAlsB,EAA4BsF,KAA5BrF,EAAmC,EACnD88C,kBAAmB,GACnB1yC,KAAM,KACN0xC,eAAgB,CAAEiB,kBAAmB,KAG3C,CAEO,MAAMwU,WAAwCp4D,GAAMC,UAQlD,WAAA5B,CAAYwG,GACjBid,MAAMjd,GAgBRtH,KAAQif,OAAS,KACfjf,KAAK2D,MAAMia,YAAYqB,OAAO,IAC5BolC,GAA2BC,wBACzBtkD,KAAKsH,MAAMjC,YACXrF,KAAKsH,MAAMZ,YACX1G,KAAK2D,MAAMo8C,UApBf,MAAMnoB,EAAStwB,EAAMy4C,OAAS,OAAS,MACvC//C,KAAK2D,MAAQ,CACXo8C,OAAQ6a,GAActzD,GACtBsW,YAAa,IAAIC,EAAY,CAC3BxY,YAAaiC,EAAMjC,YACnBN,MAAO,GAAG6yB,wBAA6BtwB,EAAMZ,YAAY9F,OACzDkd,UAAW,KAtInB,IAAA9Z,EAsIyB,OAAA,OAAAA,EAAAsD,EAAMyW,qBAAN/Z,EAAAga,KAAA1W,IACjBhC,eAAgB,KAvIxB,IAAAtB,EAAAsE,EAAAe,EAwIU,OAAAf,EAAA,OAAAtE,EAAAsD,EAAMjC,YAAYkD,mBAAlB,EAAAvE,EAAgCwZ,UAAhClV,EAAA0V,KAAAha,GACA,OAAAqF,EAAA/B,EAAM8W,aAAN/U,EAAA2U,KAAA1W,MAIR,CAnBA,WAAcgY,CAAKhY,GACjB,OAAOiY,EAAWD,KAAKu7C,GAAiCvzD,EAAO,CAAEkY,gBAAiB,YACpF,CA6BO,MAAAwF,GACL,MAAMvI,GAASzc,KAAKsH,MAAMy4C,OAC1B,OACEt9C,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAACqX,EAAA,CAAmBC,QAASxe,KAAK2D,MAAMia,cACxCnb,GAAAyE,cAACuX,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,eAChCtb,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,eAAe0R,EAAQ,MAAQ,OAAO,wBAEtDha,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC09C,GAAA,CAA2B7E,OAAQ//C,KAAK2D,MAAMo8C,OAAQxlC,SAAWwlC,GAAW//C,KAAKqd,SAAS,CAAE0iC,cAE/Ft9C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkB5L,KAAK,SAASyf,QAAS,KAtKrE,IAAA5a,EAAAsE,EAsK2E,OAAA,OAAAA,GAAAtE,EAAAhE,KAAKsH,OAAMyW,mBAAX,EAAAzV,EAAA0V,KAAAha,KAA6B,UAG9FvB,GAAAyE,cAAC2X,EAAA,CACCjW,YAAa5I,KAAKu+B,UAClBz4B,MAAO2W,EAAQ,SAAW,SAC1BmC,QAAS5e,KAAKif,OACdX,WAAYte,KAAK2D,MAAMia,YAAYU,cAK7C,CAEQ,OAAAigB,GApLV,IAAAv6B,EAAAsE,EAqLI,MAAMy3C,OAAEA,GAAW//C,KAAK2D,MAClBm3D,GAAoB,OAAA92D,EAAA+7C,EAAOqF,uBAAPphD,EAAuBsiD,oBAAqBrC,GAAoBsC,SAC1F,OACEwB,GAAiBhI,EAAOmG,eAAgB,IACxC6B,GAAiBhI,EAAOoG,eAAgB,IACxCpG,EAAOmG,gBAAkBnG,EAAOoG,gBAChC4B,GAAiBhI,EAAOqG,kBAAmB,KAxIjD,SAAyBrG,GAnDzB,IAAA/7C,EAAAsE,EAoDE,MAAMogD,EAAgB1wC,QAAQ+nC,EAAOqF,gBAAkBlkD,OAAOY,KAAKi+C,EAAOqF,gBAAgBlhD,QACpFykD,EAA0B3wC,QAC9B+nC,EAAOuF,0BAA4BpkD,OAAOY,KAAKi+C,EAAOuF,0BAA0BphD,QAE5E6gD,EAAgBhF,EAAOiF,0BAA4B,GACnD4D,GAAYF,GAAiBV,GAAoB,OAAAhkD,IAAOohD,qBAAP,EAAAphD,EAAuBqiD,kBAAmB,GAC3FwC,GACHF,GAA2BX,GAAoB,OAAA1/C,IAAOg9C,+BAAP,EAAAh9C,EAAiC+9C,kBAAmB,GAChG0U,EAAqBhW,EAAcjmB,MAAMmpB,IAC/C,OACEW,GACAC,GACAkS,IACErS,GAAiBE,GAAcD,GAA2BE,GAAuB9D,EAAc7gD,OAAS,EAE9G,CAyHM4kD,CAAgB/I,IAvHtB,SAA2BA,GACzB,OAAQA,EAAOmF,kBAAoB,IAAIpmB,MACpCknB,IAvEL,IAAAhiD,EAAAsE,EAAAe,EAwEM,OAAA2O,QAAQ,OAAAhU,EAAAgiD,EAASwB,mBAAT,EAAAxjD,EAAuByV,SAC/BsuC,GAAiB/B,EAAS2B,yBAA0B,EAAG5H,EAAOoG,iBAC9DnuC,QAAQ,OAAA1P,EAAA09C,EAAS4B,mBAAT,EAAAt/C,EAAuBmR,SAC/BzB,QAAQ,OAAA3O,EAAA28C,EAAS6B,iBAATx+C,EAAmBoQ,SAC3BsuC,GAAiB/B,EAAS8B,SAAU,IA7DJ,UA+DtC,CA+GMiB,CAAkBhJ,IA7GxB,SAAgCA,GAC9B,IAAKA,EAAOyF,eACV,OAAO,EAET,MAAMC,oBAAEA,EAAA8B,cAAqBA,GAAkBxH,EAAOyF,eAChDwD,OAA0C,WAA/BvD,WAAqBwD,OAChCC,OAA8C,WAAjCzD,WAAqBC,SACxC,QAAIsD,IAAaE,IAAenB,GAAiBR,EAAe,GAAI,SAG7D2B,EACHnB,GAAiB,MAAAtC,OAAA,EAAAA,EAAqBC,QAAS,EAAG,KAClDqC,GAAiB,MAAAtC,OAAA,EAAAA,EAAqBwD,MAAO,GACnD,CAiGME,CAAuBpJ,MACrB+a,GAAqB9iD,QAAQ4N,GAAoBC,QAAQi/B,2BACzDgW,GAAqB9S,GAAoB,OAAA1/C,IAAO88C,qBAAP,EAAA98C,EAAuB+9C,kBAAmB,GAEzF,ECjLF,SAAS2U,GAAW1rD,GAClB,gBAAOA,EAAsB,IAAM,GAAGZ,KAAKusD,MAAc,IAAR3rD,KACnD,CAEO,SAAS4rD,IAA4B71D,YAC1CA,EAAAi1D,iBACAA,EAAA5zD,YACAA,EAAAq5C,OACAA,IAzBF,IAAA/7C,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EA2BE,MAAMw9B,EAAmB3iC,IACvB4iC,GAAkB9zD,EAAarB,GAAa9F,KAAMk7D,GAAeA,GAAc7iC,MAGjF,IAAKmoB,EACH,OAAOua,EACL73D,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,yBACZ5L,KAAK,SACLyf,QAAS,IAAM27C,EAAgB,IAAMM,GAAgCv7C,KAAK,CAAEja,cAAaqB,kBAC1F,0BAGC,KAGN,MAAM++C,EAAsB,OAAAzhD,EAAA+7C,EAAOyF,qBAAP,EAAAxhD,EAAuByhD,oBAC7C0V,EACoC,iBAAjC,MAAA1V,OAAA,EAAAA,EAAqBC,SACxB,GAAGD,EAAoBC,WACe,uBAA/BD,WAAqBwD,OAC5B,GAAGxD,EAAoBwD,aACvB,EAEAyR,EAAe,KACnBx1D,EAAyBN,QAAQ,CAC/BC,OAAQ,gCAAgC6B,EAAY9F,QACpDkE,WAAY,oBACZtE,QAASkG,EAAYlG,QACrB4E,kBAAmB,CAAEC,cAAaN,MAAO,2BAA2B2B,EAAY9F,QAChFoE,aAAc,IAAMq/C,GAA2BE,wBAAwBl/C,EAAaqB,MAIxF,OACEjE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,mDACZ,KAAA,CAAGA,UAAU,qCACXg1C,EAAOqF,gBACN3iD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,oBACJzE,GAAAyE,cAAC,KAAA,KAAG,cAAY8zD,GAAWjb,EAAOqF,eAAeiB,qBAGpDzgC,GAAoBC,QAAQi/B,4BAAqE,KAA5C,OAAAx8C,EAAAy3C,EAAOqF,qBAAP,EAAA98C,EAAuBg+C,mBAC3E7jD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,0BACJzE,GAAAyE,cAAC,KAAA,KAAI64C,EAAOqF,eAAekB,mBAG9BvG,EAAOuF,0BACN7iD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,UAAG,oCACJzE,GAAAyE,cAAC,KAAA,KAAI8zD,GAAWjb,EAAOuF,yBAAyBe,sBAGlDtG,EAAOiF,0BAA4B,IAAI3kD,IAAI,CAACwlD,EAAQlwC,KAnF9D,IAAA3R,EAAAsE,EAoFU,OAAA7F,GAAAyE,cAACzE,GAAMwI,SAAN,CAAejJ,IAAK,GAAG6jD,EAAOA,UAAUlwC,KACvClT,GAAAyE,cAAC,UAAG,sCACH,KAAA,KACE2+C,EAAOA,QAAU,IAAI,KAAG,OAAAv9C,EAAA,OAAAtE,EAAA6hD,EAAOQ,mBAAPriD,EAA4B6hD,EAAOgB,0BAAnCv+C,EAA+D,IACtD,qBAAjCu9C,EAAOqB,sBACJ,OACiC,qBAAjCrB,EAAOqB,sBACP,OACA,OAIVzkD,GAAAyE,cAAC,KAAA,KAAG,aACJzE,GAAAyE,cAAC,KAAA,KAAI,OAAAmC,EAAA02C,EAAOmG,gBAAP78C,EAAyB,KAC9B5G,GAAAyE,cAAC,UAAG,aACJzE,GAAAyE,cAAC,KAAA,KAAI,OAAAoC,EAAAy2C,EAAOoG,gBAAP78C,EAAyB,KAC9B7G,GAAAyE,cAAC,KAAA,KAAG,qCACH,KAAA,KAAI,OAAAsT,EAAAulC,EAAOqG,mBAAP5rC,EAA4B,IAAI,QACrC/X,GAAAyE,cAAC,KAAA,KAAG,QACJzE,GAAAyE,cAAC,KAAA,KAAI64C,EAAOrsC,MAAQ,KACnBqsC,EAAOyF,gBACN/iD,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,KAAA,KAAG,0BACJzE,GAAAyE,cAAC,KAAA,KAAI,MAAAi0D,EAAAA,EAAe,KACpB14D,GAAAyE,cAAC,KAAA,KAAG,wBACJzE,GAAAyE,cAAC,KAAA,KAAI,OAAA61B,EAAAgjB,EAAOyF,eAAe+B,eAAtBxqB,EAAuC,IAAI,cAGlDgjB,EAAOmF,kBAAoB,IAAI7kD,IAAI,CAAC2lD,EAAUrwC,IAC9ClT,GAAAyE,cAACzE,GAAMwI,SAAN,CAAejJ,IAAK,GAAGgkD,EAASwB,gBAAgB7xC,KAC/ClT,GAAAyE,cAAC,KAAA,KAAG,oBACJzE,GAAAyE,cAAC,KAAA,KACE8+C,EAASwB,cAAgB,IAAI,KAAGxB,EAAS0B,QAAU,UAAY,WAAW,IAC1E1B,EAAS6B,SAAW,KAAK7B,EAAS6B,WAAa,OAIpDnhD,EAAY00D,qBAAuB,IAAI/6D,IAAI,CAAC+qB,EAASzV,IACrDlT,GAAAyE,cAACzE,GAAMwI,SAAN,CAAejJ,IAAK2T,GACnBlT,GAAAyE,cAAC,KAAA,KAAG,4BACH,KAAA,KAAIkkB,MAIVkvC,GACC73D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,0BACZ5L,KAAK,SACLyf,QAAS,IACP27C,EAAgB,IAAMM,GAAgCv7C,KAAK,CAAEja,cAAaqB,cAAaq5C,aAE1F,QAGDt9C,GAAAyE,cAAC,SAAA,CACC6D,UAAU,eACV,cAAY,4BACZ5L,KAAK,SACLyf,QAAS,IAAM27C,EAAgBG,IAChC,WAOX,CCtDO,SAASW,GAAwB30D,EAA2B+O,GACjE,IAAK/O,EAAYsiC,wBAAwC,IAAnBvzB,EAAO6lD,QAC3C,MAAO,CAAEA,QAAS,oBAGpB,IACG50D,EAAYsiC,wBACM,IAAnBvzB,EAAO6lD,WACLnlD,OAAOiG,UAAU3G,EAAO6lD,UAAY7lD,EAAO6lD,QAAU,GAEvD,MAAO,CAAEA,QAAS,8CAGpB,GAAI50D,EAAYsiC,kBAAmB,CACjC,MAAMzvB,EAA0B,CAAA,EAOhC,YANI9D,EAAO8lD,oBACThiD,EAAOgiD,kBAAoB,4BAEzB9lD,EAAO+lD,oBACTjiD,EAAOiiD,kBAAoB,mBAEzBt6D,OAAOY,KAAKyX,GAAQrV,OACtB,OAAOqV,EAQT,KANKpD,OAAOiG,UAAU3G,EAAO8lD,oBAAsB9lD,EAAO8lD,kBAAoB,KAC5EhiD,EAAOgiD,kBAAoB,+CAExBplD,OAAOiG,UAAU3G,EAAO+lD,oBAAsB/lD,EAAO+lD,kBAAoB,KAC5EjiD,EAAOiiD,kBAAoB,6CAEzBt6D,OAAOY,KAAKyX,GAAQrV,OACtB,OAAOqV,CAEX,CAEA,OACE7S,EAAYsiC,wBACiB,IAA7BvzB,EAAO8lD,wBACsB,IAA7B9lD,EAAO+lD,mBACP/lD,EAAO8lD,kBAAoB9lD,EAAO+lD,kBAE3B,CACLA,kBAAmB,gCACnBD,kBAAmB,iCAIhB,CAAA,CACT,CAEO,MAAME,WAAkCh5D,GAAMC,UAQnD,WAAA5B,CAAYwG,GA5Jd,IAAAtD,EAAAsE,EA6JIic,MAAMjd,GAmBRtH,KAAQu+B,QAAU,IAChBv+B,KAAK2D,MAAM+3D,UAAuG,IAA3Fx6D,OAAOY,KAAKu5D,GAAwBr7D,KAAKsH,MAAMZ,YAAa1G,KAAK2D,MAAM8R,SAASvR,OAEzGlE,KAAQif,OAAS,KACf,IAAKjf,KAAKu+B,UACR,OAGF,MAAMl5B,YAAEA,EAAAs2D,wBAAaA,EAAAj1D,YAAyBA,EAAAgwD,kBAAaA,GAAsB12D,KAAKsH,MACtF,GAAIZ,EAAYsiC,kBAAmB,CACjC,MAAM3mC,OAAEA,EAAA09C,OAAQA,GAlHb,CACL19C,OAAQ,CACNkE,gCAJJkP,EAqHMzV,KAAK2D,MAAM8R,QAjH0BlP,+BACvC4jD,OAAQ10C,EAAO00C,QAEjBpK,OAAQ,CACNoG,eAAgB1wC,EAAO+lD,kBACvBtV,eAAgBzwC,EAAO8lD,oBAiHvB,YAHAv7D,KAAK2D,MAAMia,YAAYqB,OAAO,IAC5B08C,EAAwBrX,wBAAwBj/C,EAAaqB,EAAaq5C,EAAQ19C,GAGtF,CA5HG,IACLoT,EA6HE,MAAMK,EA/GH,SACLpP,EACA+O,GAEA,MAAO,CACL8f,SAAU,CAAEE,QAAShgB,EAAO6lD,QAAS3sD,IAAK8G,EAAO6lD,QAASzhD,IAAKpE,EAAO6lD,SACtE/0D,+BAAgCkP,EAAOlP,+BACvC4jD,OAAQ10C,EAAO00C,OACf5oD,OAAQmF,EAAYnF,OACpBuF,gBAAiBJ,EAAY9F,KAC7B41D,WAAY/gD,EAAO6lD,QAEvB,CAmGoBM,CAAuBl1D,EAAa1G,KAAK2D,MAAM8R,QAC/DzV,KAAK2D,MAAMia,YAAYqB,OAAO,IAAMy3C,EAAkBmF,kBAAkBn1D,EAAarB,EAAayQ,KAtClG,MAAMzQ,YAAEA,GAAgBiC,EACxBtH,KAAK2D,MAAQ,CACXia,YAAa,IAAIC,EAAY,CAC3BxY,cACAN,MAAO,YAAYuC,EAAMZ,YAAY9F,OACrCkd,UAAW,IAAM9d,KAAKsH,MAAMyW,eAC5BzY,eAAgB,IAAMD,EAAYkD,aAAaiV,YAEjD/H,OAAQ,CACNlP,gCACE,OAAAvC,EAAAqB,EAAYyvB,iBAAZ,EAAA9wB,EAAwB+wB,kCAAkC,OAAAzsB,EAAAjD,EAAYyvB,iBAAZ,EAAAxsB,EAAwB0sB,oBAC9E,CAAC,eACD,GAER0mC,UAAU,EAEd,CAtBA,WAAcp8C,CAAKhY,GACjB,OAAOiY,EAAWD,KAAKm8C,GAA2Bn0D,EACpD,CA6CO,MAAA0d,GAvMT,IAAAhhB,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAAA4Y,EAwMI,MAAMtwC,YAAEA,EAAAqB,YAAaA,GAAgB1G,KAAKsH,OACpCmO,OAAEA,GAAWzV,KAAK2D,MAClBm4D,EAAc,OAAAzyD,EAAA,WAAY4/B,UAAZ,EAAAjlC,EAAiBqlC,iBAAjBhgC,EAAoC,OAAAf,EAAA5B,EAAY6uB,iBAAZjtB,EAAsBmtB,QACxEsmC,EAAe76D,OAAOuU,OAAO4lD,GAAwB30D,EAAa+O,IAAS,GAEjF,yCAEIhT,GAAAyE,cAACqX,EAAA,CAAmBC,QAASxe,KAAK2D,MAAMia,cACxCnb,GAAAyE,cAACuX,EAAA,CAAWC,QAAS1e,KAAKsH,MAAMyW,gCAC/B,MAAA,CAAIhT,UAAU,gBACbtI,GAAAyE,cAAC,MAAG6D,UAAU,eAAc,UAAQrE,EAAY9F,OAElD6B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAK6D,UAAU,mBACbrE,EAAYsiC,kBACXvmC,GAAAyE,cAAAzE,GAAAwI,SAAA,KACExI,GAAAyE,cAAC,IAAA,KAAE,gFACHzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,6CACZ,IAAA,KAAE,QAELtI,GAAAyE,cAAC,OAAI6D,UAAU,YACbtI,GAAAyE,cAAC,IAAA,KAAE,SAGPzE,GAAAyE,cAAC,OAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA0B,WAC3CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVuP,UAAU,EACVnb,KAAK,SACLmQ,MAAO5I,EAAYsiC,kBAAkBkd,kBAGzCzjD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACVuP,UAAU,EACVnb,KAAK,SACLmQ,MAAO5I,EAAYsiC,kBAAkBmd,mBAI3C1jD,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA0B,aAC3CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV8O,IAAK,EACLjZ,KAAK,oBACL2Z,SAAWwB,GACT/b,KAAKqd,SAAS,CACZ5H,OAAQ,IACHA,EACH8lD,kBAA0C,KAAvBx/C,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,UAIrFnQ,KAAK,SACLmQ,MAAO,OAAAhG,EAAAmM,EAAO8lD,mBAAPjyD,EAA4B,MAGvC7G,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV8O,IAAK,EACLjZ,KAAK,oBACL2Z,SAAWwB,GACT/b,KAAKqd,SAAS,CACZ5H,OAAQ,IACHA,EACH+lD,kBAA0C,KAAvBz/C,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,UAIrFnQ,KAAK,SACLmQ,MAAO,OAAAkL,EAAA/E,EAAO+lD,mBAAPhhD,EAA4B,0CAOzC/X,GAAAyE,cAAC,IAAA,KAAE,sDACHzE,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,2BAA0B,gBAC3CtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,wBAAwBuP,UAAU,EAAMnb,KAAK,SAASmQ,MAAOwsD,MAGlFr5D,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAA,CAAM6D,UAAU,0BAA0B8wC,QAAQ,uBAAsB,aAGzEp5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,QAAA,CACC6D,UAAU,wBACV5C,GAAG,sBACH0R,IAAK,EACLjZ,KAAK,UACL2Z,SAAWwB,GACT/b,KAAKqd,SAAS,CACZ5H,OAAQ,IACHA,EACH6lD,QAAgC,KAAvBv/C,EAAMlQ,OAAOyD,WAAe,EAAY6G,OAAO4F,EAAMlQ,OAAOyD,UAI3EnQ,KAAK,SACLmQ,MAAO,OAAAytB,EAAAtnB,EAAO6lD,SAAPv+B,EAAkB,QAMlCg/B,GAAgBt5D,GAAAyE,cAAC80D,GAAA,CAAkB5wC,QAAS2wC,EAAc58D,KAAK,WAC/D,OAAAw2C,EAAAtwC,EAAYyvB,qBAAYC,iCACvBtyB,GAAAyE,cAAC+0D,GAAA,CACC11D,+BAAgCkP,EAAOlP,+BACvCgU,SAAWhU,GACTvG,KAAKqd,SAAS,CAAE5H,OAAQ,IAAKA,EAAQlP,oCAEvC21D,mBAAmB,SACnBC,iBAAiB,IAGrB15D,GAAAyE,cAACgjD,EAAA,CACCC,OAAQ10C,EAAO00C,OACf5vC,SAAW4vC,GAAWnqD,KAAKqd,SAAS,CAAE5H,OAAQ,IAAKA,EAAQ00C,gBAIjE1nD,GAAAyE,cAAC,OAAI6D,UAAU,gBACbtI,GAAAyE,cAACk1D,GAAA,CAAiB57D,QAASkG,EAAYlG,QAAS67D,cAAgBX,GAAa17D,KAAKqd,SAAS,CAAEq+C,eAC7Fj5D,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkB6T,QAAS5e,KAAKsH,MAAMyW,aAAc5e,KAAK,UAAS,UAGpFsD,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkBuP,UAAWta,KAAKu+B,UAAW3f,QAAS5e,KAAKif,OAAQ9f,KAAK,UAAS,WAM3G,ECvRK,SAASm9D,GACdj3D,EACAqB,EACA+N,GAEA,OAAOA,EACJ/U,OAAQgJ,IAvEb,IAAA1E,EAwEM,MAAMu4D,EAAuB7zD,EAAU3E,MAAO,OAAAC,EAAA0E,EAAUqgC,gBAAV/kC,EAAmBD,KACjE,OAC2B,IAAzB2E,EAAUE,YACV2zD,IAAyBl3D,EAAYzE,MACrC8H,EAAU8zD,UAAY91D,EAAY81D,SAClC9zD,EAAUlI,UAAYkG,EAAYlG,SAClCkI,EAAUnH,SAAWmF,EAAYnF,SAGpCojC,KAAK,CAAC0H,EAAGowB,IAAMA,EAAE77D,KAAK89C,cAAcrS,EAAEzrC,MAC3C,CAEO,MAAM87D,GAAN,MAAMA,UAAoCj6D,GAAMC,UAarD,WAAA5B,CAAYwG,GAjGd,IAAAtD,EAAAsE,EAkGIic,MAAMjd,GAmBRtH,KAAQme,MAAQ,IAAYne,KAAKsH,MAAMyW,eAEvC/d,KAAQu+B,QAAU,IAAev+B,KAAK2D,MAAM+3D,YAAc17D,KAAK2D,MAAM8R,OAAOknD,uBAE5E38D,KAAQif,OAAS,KACf,IAAKjf,KAAKu+B,UACR,OAGF,MAAMl5B,YAAEA,EAAAqB,YAAaA,EAAAgwD,kBAAaA,GAAsB12D,KAAKsH,MACvD2I,EA/EH,SACL5K,EACAqB,EACA+O,GAnDF,IAAAzR,EAqDE,MAAO,CACLuC,+BAAgCkP,EAAOlP,+BACvCwuB,+BAAgC,OAAA/wB,EAAAqB,EAAYyvB,iBAAZ,EAAA9wB,EAAwB+wB,+BACxDo1B,OAAQ10C,EAAO00C,OACfyS,gBAAiB,CACfD,uBAAwBlnD,EAAOknD,uBAC/BE,wBAAyBn2D,EAAY9F,MAEvCk8D,aAAc,WAElB,CAgEgBC,CAAoB13D,EAAaqB,EAAa1G,KAAK2D,MAAM8R,QACrEzV,KAAK2D,MAAMia,YAAYqB,OAAO,IAAMy3C,EAAkBsG,oBAAoBt2D,EAAarB,EAAa4K,KA7BpG,MAAM5K,YAAEA,EAAAqB,YAAaA,GAAgBY,EACrCtH,KAAK2D,MAAQ,CACXia,YAAa,IAAIC,EAAY,CAC3BxY,cACAN,MAAO,YAAY2B,EAAY9F,OAC/Bkd,UAAW,IAAM9d,KAAKsH,MAAMyW,eAC5BzY,eAAgB,IAAMD,EAAYkD,aAAaiV,YAEjD/H,OAAQ,CACNlP,gCACE,OAAAvC,EAAAqB,EAAYyvB,iBAAZ,EAAA9wB,EAAwB+wB,kCAAkC,OAAAzsB,EAAAjD,EAAYyvB,iBAAZ,EAAAxsB,EAAwB0sB,oBAC9E,CAAC,eACD,GAER0mC,UAAU,EAEd,CAtBA,WAAcp8C,CAAKhY,GACjB,OAAOiY,EAAWD,KAAKo9C,EAA6Bp1D,EACtD,CAoCO,MAAA0d,GAnIT,IAAAhhB,EAoII,MAAMqB,YAAEA,EAAAqB,YAAaA,EAAA6B,aAAaA,GAAiBvI,KAAKsH,OAClDsW,YAAEA,EAAAnI,OAAaA,GAAWzV,KAAK2D,MAC/B8Q,EAAa6nD,GAAyBj3D,EAAaqB,EAAa6B,GAEtE,OACE9F,GAAAyE,cAAAzE,GAAAwI,SAAA,sBACGsT,EAAA,CAAmBC,QAASZ,IAC7Bnb,GAAAyE,cAACuX,EAAA,CAAWC,QAAS1e,KAAKme,QAC1B1b,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,gBACbtI,GAAAyE,cAAC,MAAG6D,UAAU,eAAc,YAAUrE,EAAY9F,OAEpD6B,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,cACbtI,GAAAyE,cAAC,QAAK6D,UAAU,mBACdtI,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,+BACZ,QAAA,CAAMA,UAAU,0BAA0B8wC,QAAQ,6BAA4B,cAG/Ep5C,GAAAyE,cAAC,MAAA,CAAI6D,UAAU,YACbtI,GAAAyE,cAAC,SAAA,CACC6D,UAAU,wBACV5C,GAAG,4BACHoS,SAAWwB,GACT/b,KAAKqd,SAAS,CAAE5H,OAAQ,IAAKA,EAAQknD,uBAAwB5gD,EAAMlQ,OAAOyD,YAAS,KAErFA,MAAOmG,EAAOknD,wBAA0B,IAExCl6D,GAAAyE,cAAC,SAAA,CAAOoI,MAAM,IAAG,aAChBmF,EAAWpU,IAAKqI,oBACd,SAAA,CAAO1G,IAAK0G,EAAU9H,KAAM0O,MAAO5G,EAAU9H,MAC3C8H,EAAU9H,WAMpB,OAAAoD,EAAAqB,EAAYyvB,qBAAYC,iCACvBtyB,GAAAyE,cAAC+0D,GAAA,CACC11D,+BAAgCkP,EAAOlP,+BACvCgU,SAAWhU,GACTvG,KAAKqd,SAAS,CAAE5H,OAAQ,IAAKA,EAAQlP,oCAEvC21D,mBAAmB,SACnBC,iBAAiB,IAGrB15D,GAAAyE,cAACgjD,EAAA,CACCC,OAAQ10C,EAAO00C,OACf5vC,SAAW4vC,GAAWnqD,KAAKqd,SAAS,CAAE5H,OAAQ,IAAKA,EAAQ00C,gBAIjE1nD,GAAAyE,cAAC,OAAI6D,UAAU,gBACbtI,GAAAyE,cAACk1D,GAAA,CAAiB57D,QAASkG,EAAYlG,QAAS67D,cAAgBX,GAAa17D,KAAKqd,SAAS,CAAEq+C,eAC7Fj5D,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkB6T,QAAS5e,KAAKme,MAAOhf,KAAK,UAAS,UAGvEsD,GAAAyE,cAAC,SAAA,CAAO6D,UAAU,kBAAkBuP,UAAWta,KAAKu+B,UAAW3f,QAAS5e,KAAKif,OAAQ9f,KAAK,UAAS,WAM3G,GA9GWu9D,GAIGz0C,aAA2D,CACvE7J,WAAY8J,EACZnK,aAAcmK,GANX,IAAM+0C,GAANP,GCvBP,SAASQ,GAAoBx2D,GA7D7B,IAAA1C,EAAAsE,EAAAe,EA8DE,MAAMK,EANR,SAA6BhD,GAxD7B,IAAA1C,EAyDE,MAAM0/B,EAAmB,OAAA1/B,EAAA0C,EAAY+8B,mBAAZ,EAAAz/B,EAA0B0/B,iBACnD,OAAOA,GAAmB,IAAI/gC,IAAsB6gC,gBAAgBE,QAAoB,CAC1F,CAGkBy5B,CAAoBz2D,GAC9Bg9B,EAAmB,OAAA1/B,EAAA0C,EAAY+8B,mBAAZ,EAAAz/B,EAA0B0/B,iBAC7Cl6B,GAAmB,OAAAH,EAAA,OAAAf,EAAA,MAAAo7B,OAAA,EAAAA,EAAkBoG,qBAAYrgC,0BAA9BJ,EAAkD,KAAM,CAAA,EAC3EE,EAAY,IAAI5G,GACtB,MAAO,IACF+D,EACHlG,QAASkG,EAAYlG,SAAWkG,EAAYwB,UAC5C0C,SAAUlB,EACN,uDAAuDmB,mBAAmBnB,sCAC1E,EACJI,QAASP,EAAUQ,+BAA+BL,EAASF,EAAiBM,SAC5EE,OAAQT,EAAUQ,+BAA+BL,EAASF,EAAiBS,YAC3Eg9B,MAAO,IAAKvgC,EAAYugC,OAAS,IAAKtC,OAE1C,CAEO,SAASy4B,GAA4B91D,EAAY8hB,GACtD,OAAO,IAAIi0C,GAAYC,IACrB,MAAMj1D,EAtDV,SAAgCtE,EAAU2C,GA1B1C,IAAA1C,EAAAsE,EA2BE,MACMD,IADe,OAAArE,EAAA,MAAAD,OAAA,EAAAA,EAAKwE,mBAAL,EAAAvE,EAAmBG,OAAQ,IACnBsE,KAAMC,GAE/BA,EAAU9H,OAAS8F,EAAY9F,MAC/B8H,EAAUlI,UAAYkG,EAAYwB,WAClCQ,EAAUnH,SAAWmF,EAAYnF,QAGrC,GAAI8G,EACF,OAAOA,EAGT,MAAMpE,GAAgB,OAAAqE,EAAA,MAAAvE,OAAA,EAAAA,EAAKE,oBAAL,EAAAqE,EAAoBnE,OAAQ,GAClD,IAAA,MAAWC,KAAgBH,EAAe,CACxC,MAAM0F,GAASvF,EAAamE,cAAgB,IAAIE,KAAMC,GAElDA,EAAU9H,OAAS8F,EAAY9F,MAC/B8H,EAAUlI,UAAYkG,EAAYwB,WAClCQ,EAAUnH,SAAWmF,EAAYnF,QAGrC,GAAIoI,EACF,OAAOA,CAEX,CAEA,OAAO,IACT,CA0BoB4zD,CAAuBj2D,EAAMvD,IAAKuD,EAAMZ,aAExD82D,GAAkBC,eAChBn2D,EAAMvD,IAAInD,KACV0G,EAAMZ,YAAYwB,UAClBZ,EAAMZ,YAAYnF,OAClB+F,EAAMZ,YAAY9F,MAClBrB,KACC6J,IACC,IAAKA,GAA2C,IAAhClI,OAAOY,KAAKsH,GAASlF,OAGnC,OAFAklB,SACAk0C,EAASI,WAGXJ,EAAShR,KAAK4Q,GAAoB,IAAM70D,GAAW,CAAA,KAAQe,EAAS5I,QAAS8G,EAAMZ,YAAYwB,aAC/Fo1D,EAASI,YAEX,KACEt0C,IACAk0C,EAASI,cAIjB,CAEA,SAASC,GAA4B55D,EAAU1B,EAAc,IAzG7D,IAAA2B,EAAAsE,EA0GE,OAAI,OAAAtE,IAAI8wB,iBAAJ,EAAA9wB,EAAgB+wB,kCAAkC,OAAAzsB,EAAAvE,EAAI+wB,qBAAYE,oBAC7D,IAAK3yB,EAAQkE,+BAAgClE,EAAOkE,gCAAkC,CAAC,WAGzFlE,CACT,CAoBO,SAASu7D,IAAsB75D,IAAEA,EAAA2C,YAAKA,IAnI7C,IAAA1C,EAoIE,MAAMi6B,EAAkBzT,KAClBqzC,0BAAEA,EAAAnH,kBAA2BA,GAAsBz4B,EACzD,GAAInS,EAAsBljB,WAAW,OACnC,OAAO,KAGT,MAAMk1D,EAAuB,CAC3Bt9D,QAASkG,EAAYlG,QACrB2E,cAAc,EACd4vB,+BAAgC,OAAA/wB,EAAAD,EAAI+wB,iBAAJ,EAAA9wB,EAAgB+wB,+BAChDmnC,mBAAoB,UA+DtB,wBACG,MAAA,CAAInxD,UAAU,WAAW5C,GAAG,sDAC1B,SAAA,CAAO4C,UAAU,yCAAyC,cAAY,WAAW5L,KAAK,UAAS,wBAGhGsD,GAAAyE,cAAC,MAAG6D,UAAU,kBACVrE,EAAYkC,YACZnG,GAAAyE,cAAC8kB,EAAA,CAAgBC,SAAUvlB,EAAarB,YAAatB,EAAK6a,QA/DtC,KArJ9B,IAAA5a,EAsJI,MAAMuE,EAAe+zD,GAAyBv4D,EAAK2C,GAAa,OAAA1C,EAAAD,EAAIwE,mBAAJ,EAAAvE,EAAkBG,OAAQ,IAC1F84D,GAA4B39C,KAAK,CAC/Bja,YAAatB,EACb2C,cACA6B,eACAmuD,wBAyD4F,6BAIzF1qC,EAAA,CAAgBC,SAAUvlB,EAAarB,YAAatB,EAAK6a,QAzDtC,KACxB68C,GAA0Bn8C,KAAK,CAC7Bja,YAAatB,EACb43D,wBAAyBtX,GACzB39C,cACAgwD,wBAoDwF,UAGtFj0D,GAAAyE,cAAC,UACCzE,GAAAyE,cAAC,IAAA,CAAE0X,QA3Ec,MAhCpB,SACL7a,EACA2C,EACAsvC,EACA/X,GAEO17B,QAAQC,QAAQwzC,EAAelN,oCAAoC/kC,EAAK2C,IAC5EnH,KAAMuW,IACLmhD,GAAyB33C,KAAK,CAAEja,YAAatB,EAAK+R,UAAS/Q,MAAO,SAAS2B,EAAY9F,QAAUq9B,KAElGp+B,MAAOmP,IA3HZ,IAAAhL,EA4HM+5D,GAAkB/uD,MAAM,CACtBnK,OAAQ,iBAAiB6B,EAAY9F,OACrCo9D,MAAM,OAAAh6D,EAAA,MAAAgL,OAAA,EAAAA,EAAO7K,WAAP,EAAAH,EAAaonB,iBAAWpc,WAAOoc,UAAW,qDAGxD,CAiBI6yC,CAAoBl6D,EAAK2C,EAAam3D,EAA2B5/B,KA0E7B,WAE9Bv3B,EAAYkC,6BACX,KAAA,KACCnG,GAAAyE,cAAC,KAAE0X,QA3Cc,KACzB,MAAMs/C,EAA+B,IAChCJ,EACHh5D,WAAY,WAAW4B,EAAY9F,OACnCiE,OAAQ,kBAAkB6B,EAAY9F,QACtCoE,aAAe3C,GACbq0D,EAAkByH,mBAAmBz3D,EAAa3C,EAAInD,KAAM+8D,GAA4B55D,EAAK1B,IAC/F+C,kBAAmB,CAAEC,YAAatB,EAAKgB,MAAO,aAAa2B,EAAY9F,SAEzEw9D,GAAiCC,yBAAyBt6D,EAAK2C,EAAaw3D,GAC5Eh5D,EAAyBN,QAAQs5D,KAiCO,YAGnCx3D,EAAYkC,6BACV,KAAA,KACCnG,GAAAyE,cAAC,KAAE0X,QAnCa,KACxB1Z,EAAyBN,QAAQ,IAC5Bk5D,EACHh5D,WAAY,UAAU4B,EAAY9F,OAClCiE,OAAQ,iBAAiB6B,EAAY9F,QACrCoE,aAAe3C,GACbq0D,EAAkB4H,kBAAkB53D,EAAa3C,EAAK45D,GAA4B55D,EAAK1B,IACzF+C,kBAAmB,CAAEC,YAAatB,EAAKgB,MAAO,YAAY2B,EAAY9F,YA4BjC,WAGnC6B,GAAAyE,cAAC,KAAA,sBACE,IAAA,CAAE0X,QAjEgB,KACzB,MAAMs/C,EAA+B,IAChCJ,EACHh5D,WAAY,WAAW4B,EAAY9F,OACnCiE,OAAQ,kBAAkB6B,EAAY9F,QACtCoE,aAAe3C,GACbq0D,EAAkB6H,mBAAmB73D,EAAa3C,EAAK45D,GAA4B55D,EAAK1B,IAC1F+C,kBAAmB,CAAEC,YAAatB,EAAKgB,MAAO,cAAc2B,EAAY9F,SAE1Ew9D,GAAiCI,yBAAyBz6D,EAAK2C,EAAaw3D,GAC5Eh5D,EAAyBN,QAAQs5D,KAuDK,aAK1C,CAsCA,SAASO,GAAc/3D,EAAkBoR,GApRzC,IAAA9T,EAAAsE,EAqRE,MAAMwhC,EAAa,OAAAxhC,EAAA,OAAAtE,EAAA0C,EAAY+8B,mBAAZ,EAAAz/B,EAA0B0/B,uBAA1B,EAAAp7B,EAA4CwhC,WACzD40B,EAAeh4D,EAAY0+B,yBAA0B,MAAA0E,OAAA,EAAAA,EAAY1E,wBACjEu5B,EAAej4D,EAAY2+B,mBAAoB,MAAAyE,OAAA,EAAAA,EAAYzE,kBACjE,OAAInkC,OAAOwlB,UAAUC,eAAe3I,KAAK0gD,GAAgB,CAAA,EAAI5mD,GACpD4mD,EAAa5mD,GAElB5W,OAAOwlB,UAAUC,eAAe3I,KAAK2gD,GAAgB,CAAA,EAAI7mD,GACpD6mD,EAAa7mD,GAEfpR,EAAYoR,EACrB,CA8EO,MAAM8mD,GAAgC,CA7HtC,UAA0Cl4D,YAAEA,IACjD,OACEjE,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,2BAA2BC,iBAAiB,GACtE/I,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,KAAA,KAAG,WACJzE,GAAAyE,cAAC,KAAA,KACCzE,GAAAyE,cAACuE,EAAA,CAAWjL,QAASkG,EAAYlG,WAEnCiC,GAAAyE,cAAC,KAAA,KAAG,UACJzE,GAAAyE,cAAC,KAAA,KAAIR,EAAYnF,QACjBkB,GAAAyE,cAAC,UAAG,WACJzE,GAAAyE,cAAC,KAAA,KAAIR,EAAYoD,SAAW,KAC5BrH,GAAAyE,cAAC,KAAA,KAAG,UACJzE,GAAAyE,cAAC,UAAIR,EAAYsD,QAAU,MAInC,EAEO,UAAuCtD,YAAEA,IAnQhD,IAAA1C,EAAAsE,EAAAe,EAAAC,EAAAkR,EAAAuiB,EAAA4Y,EAAAC,EAoQE,OACEnzC,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,WAAWC,iBAAiB,GACtD/I,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,KAAA,KAAG,WACJzE,GAAAyE,cAAC,KAAA,KAAI,OAAAoC,EAAA,OAAAD,EAAA,OAAArF,EAAA0C,EAAY6uB,eAAZ,EAAAvxB,EAAsByxB,SAAtBpsB,EAAiC,OAAAf,EAAA5B,EAAY8B,kBAAZF,EAAuBpE,QAAxDoF,EAAkE,KACvE7G,GAAAyE,cAAC,KAAA,KAAG,OACJzE,GAAAyE,cAAC,KAAA,KAAI,OAAA61B,EAAA,WAAYxH,iBAAZ/a,EAAsBX,KAAtBkjB,EAA6B,sBACjC,KAAA,KAAG,OACJt6B,GAAAyE,cAAC,KAAA,KAAI,OAAA0uC,EAAA,OAAAD,EAAAjvC,EAAY6uB,iBAAZogB,EAAsBhnC,KAAtBinC,EAA6B,MAI1C,EAiBO,UAA2ClvC,YAAEA,IAjSpD,IAAA1C,EAAAsE,EAkSE,MAAMopB,EAAW,OAAA1tB,EAAA0C,EAAY+8B,mBAAZ,EAAAz/B,EAA0B0/B,iBACrCm7B,EAAyD,CAC7D,CAAC,cAAeJ,GAAc/3D,EAAa,qBAC3C,CAAC,OAAQ+3D,GAAc/3D,EAAa,eACpC,CAAC,uBAAwB+3D,GAAc/3D,EAAa,+BAEtD,OACEjE,GAAAyE,cAACoE,GAAmBC,QAAQ,uBAAuBC,iBAAiB,GAClE/I,GAAAyE,cAAC,KAAA,CAAG6D,UAAU,2BACZtI,GAAAyE,cAAC,UAAG,sCACH,KAAA,MAAI,MAAAwqB,OAAA,EAAAA,EAAU9wB,OAAQ,KACvB6B,GAAAyE,cAAC,KAAA,KAAG,0BACH,KAAA,MAAKR,EAAYugC,OAAS,IAAIvhC,KAAK,OAAS,KAC7CjD,GAAAyE,cAAC,KAAA,KAAG,gBACJzE,GAAAyE,cAAC,KAAA,MAAI,OAAAoB,EAAA5B,EAAYsgC,yBAAZ,EAAA1+B,EAAgCghC,cAAe,KACnDu1B,EAAiBx+D,IAAI,EAAEyF,EAAOwJ,sBAC5B7M,GAAMwI,SAAN,CAAejJ,IAAK8D,GACnBrD,GAAAyE,cAAC,KAAA,KAAIpB,oBACJ,KAAA,UAAc,IAAVwJ,EAAsB,IAAM6I,OAAO7I,MAG5C7M,GAAAyE,cAAC,KAAA,KAAG,QACJzE,GAAAyE,cAAC,UACER,EAAYkE,0BACV,IAAA,CAAEgB,KAAMlF,EAAYkE,SAAUiB,OAAO,SAASC,IAAI,uBAAsB,0BAIzE,uBAILiuD,GAAA,CAAoCxwB,0BAA2B7iC,EAAY6iC,4BAGlF,EAEO,UAAqCxlC,IAC1CA,EAAA2C,YACAA,IAKA,OACEjE,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,eAC1B9I,GAAAyE,cAACg0D,GAAA,CACC71D,YAAatB,EACbu2D,kBAAmBxuC,EAAsBljB,WAAW,OACpDm3C,OAAQr5C,EAAYsiC,kBACpBtiC,gBAIR,EAEO,UAAqC3C,IAC1CA,EAAA2C,YACAA,IAKA,OACEjE,GAAAyE,cAACoE,EAAA,CAAmBC,QAAQ,gBAC1B9I,GAAAyE,cAACmzD,GAAA,CACCh1D,YAAatB,EACbu2D,kBAAmBxuC,EAAsBljB,WAAW,OACpDm3C,OAAQr5C,EAAYs+B,kBACpBt+B,gBAIR,GCrWO,MAAMo4D,GACX,WAAAh+D,GACE,MAAM8nB,EAA2B,IAAIR,GAqErC,MAAO,CACL22C,+CArCF,SAAwD9mB,GAEtD,MAAMniC,EAAUjG,GAAS,CAAEg8B,YAAa,GAAIrH,UAAW,IAAMyT,GA+B7D,MA9B4B,UAAxBA,EAAKzT,UAAU9wB,aACVoC,EAAQ+G,OAGjB/G,EAAQyhB,gBAAkBzhB,EAAQgyB,cAClChyB,EAAQrP,cAAgB,MACxBqP,EAAQmY,kBAAoB,CAAA,EAC5BnY,EAAQmY,kBAAkBnY,EAAQvU,QAxBpC,SAA8B02C,GAC5B,OAAIA,EAAKlxC,KACA,CAACkxC,EAAKlxC,MAIb,CACEzH,GAAI24C,EAAM,uCACV34C,GAAI24C,EAAM,CAAC,oBAAqBA,EAAK12C,SACrCjC,GAAI24C,EAAM,6BACVxvC,KAAMw+B,GAAU30B,MAAMC,QAAQ00B,IAAUA,EAAM/iC,SAAW,EAE/D,CAY8C86D,CAAqB/mB,GACjEniC,EAAQtV,QAAUsV,EAAQC,mBACnBD,EAAQ0uB,iBACR1uB,EAAQ+1B,mBACR/1B,EAAQiyB,wBACRjyB,EAAQ29B,8BACR39B,EAAQgyB,qBACRhyB,EAAQsW,oBACRtW,EAAQ2+B,yBACR3+B,EAAQ21B,gBAEX31B,EAAQkvB,oBACVlvB,EAAQkvB,kBAAoB,CAAC,cAAe,kBAAmB,iBAAkB,mBAAmBx2B,OAClG,CAACywD,EAAiBnnD,UACyB,IAArChC,EAAQkvB,kBAAkBltB,KAC5BmnD,EAAgBnnD,GAAShC,EAAQkvB,kBAAkBltB,IAE9CmnD,GAET,CAAA,IAIGnpD,CACT,EAIEopD,qBAtEF,SAA8Bx4D,EAAarB,GACzC,OAAOA,EACJ6Y,cAAc,iBACdihD,QACA5/D,KAAK,KACAmH,EAAYzC,gBAGdyC,EAAYzC,cAAgB2kB,EAAyBL,qCACnD7hB,EAAYzC,cACZyC,EAAYlG,QACZ6E,EAAY6Y,cAAc,iBAAiB/Z,OAGxCuC,GAEb,EAwDF,EC3EK,MAAM04D,GACX,WAAAt+D,GACEd,KAAKq0C,iBAAc,EAEnB7hC,EAAcC,uBAAuB,OAAOlT,KAAMgR,IAChDvQ,KAAKq0C,YAAc9jC,GAEvB,CAEA,MAAAyU,CAAOte,GACL,GAAIA,EAAYsD,OACd,OAAOtD,EAAYsD,OAQnB,OAN0BzG,GAAE8L,MAAMrP,KAAKq0C,aACpC30C,OAAO,CAAEc,QAASkG,EAAYlG,QAASI,KAAM8F,EAAYoD,UACzDzJ,IAAI,qBACJ4hB,OACA3S,QAEwB,gBAAkB,QAEjD,EC6DF+vD,GAAyBC,kBAAkB,MAAO,IArF3C,MACG,yBAAAC,CAA0B3+D,EAAc2Y,GAC9B,4BACHiK,KAAK5iB,IAChB2Y,EAAO1T,KACL,4HAIN,CAEQ,cAAA25D,CAAe5+D,EAAc6+D,EAAoBlmD,GACvD,MAAMmmD,EAAwB,GAI9B,GAAI9+D,EAAKsD,OAASw7D,EAChBnmD,EAAO1T,KAAK,yEADd,CAKA,GAAIjF,EAAKsD,OAASy7D,GAChB,GAAI/+D,EAAKsD,OATuBw7D,GAU9BD,EAAS55D,KAAK,8JAC8EjF,EAAKsD,uCAEnG,GAAWtD,EAAKsD,QAAUy7D,GACxBF,EAAS55D,KACP,kHAGG,CACL,MAAM+5D,EAAYD,GAAgC/+D,EAAKsD,OACvDu7D,EAAS55D,KAAK,8GACF+5D,yBACd,CAGF,GAAIh/D,EAAKsD,OAAS27D,GAChB,GAAIj/D,EAAKsD,OAzBsBw7D,GA0B7BD,EAAS55D,KAAK,6JAC6EjF,EAAKsD,yCAElG,GAAWtD,EAAKsD,QAAU27D,GACxBJ,EAAS55D,KACP,iHAGG,CACL,MAAM+5D,EAAYC,GAA+Bj/D,EAAKsD,OACtDu7D,EAAS55D,KAAK,6GACF+5D,yBACd,CAGF,GAAIh/D,EAAKsD,OAASw7D,GAChB,GAAI9+D,EAAKsD,QAAUw7D,GACjBD,EAAS55D,KACP,8FAA8Fm4B,EAAe1+B,IAC3G,qBAGC,CACL,MAAMsgE,EAAYF,GAA4B9+D,EAAKsD,OACnDu7D,EAAS55D,KAAK,6DAA6Dm4B,EAAe1+B,IACxF,kDAEUsgE,yBACd,CAjDF,CAmDF,CAEO,QAAA1oB,CAASt2C,EAAO,IACrB,MAAM6+D,EAAqB,GACrBlmD,EAAmB,GAOzB,OALI3Y,EAAKsD,SACPlE,KAAKu/D,0BAA0B3+D,EAAM2Y,GACrCvZ,KAAKw/D,eAAe5+D,EAAM6+D,EAAUlmD,IAG/B,CAAEkmD,WAAUlmD,SACrB,ICrCK,SAASumD,KACdh0C,EAAsBi0C,iBAAiB,MAAO,CAC5Cn/D,KAAM,SACNo/D,KAAM,CACJluC,KvDpDS,gCuDsDXmuC,0BAA2B,CACzB,CACEnoD,MAAO,2BACP+3C,QAAS,yDACT/pD,MAAO,8BACP3G,KAAM,YAGV+gE,MAAO,CACLC,WAAYt/D,IAEdk5B,MAAO,CACL8pB,OAAQ1hD,IAEVuE,YAAa,CACX05D,YAAatB,GACb9oB,eAAgB9S,GAChB+S,qBAAsBvG,GACtB2wB,sBAAuBpJ,GACvBqJ,eAAgB1C,GAChB2C,cAAenD,GACfoD,gBAAiB5B,IAEnBl7D,SAAU,CACR+8D,sBAAuBvH,GACvB9vD,QAAS/B,GACT87B,oBAAqB/2B,GACrBs0D,6BAA8BxwD,IAEhC9L,aAAc,CACZu8D,wBAAyBx4C,GACzBy4C,gCAAkCt5D,GAChC6gB,GAA2B7I,KAAK,IAAKhY,EAAOvD,IAAKuD,EAAMjC,YAAamX,mBAAmB,IACzF8jD,eAAgBz0C,GAChB20C,gBAAiBr0C,GACjBi0C,YAAarzC,GACb8zC,eAAgBx0C,GAChBy0C,eAAgBv2C,IAElB+Q,cAAe,CACbylC,yBAA0B7iC,GAC1B90B,QAAS02B,GACTsgC,YAAaz/B,GACbkjB,OAAQtjB,IAEVv2B,OAAQ,CACNg3D,SAAU5B,IAEZ6B,kBAAkB,GAEtB,CAIA,SAASC,GAA0BC,EAAkBruC,GAC9BD,EAASvC,SAAS8wC,gBAAgBv9D,KAAMkrB,IAChCA,EAAMgE,UAAYhE,EAAM/sB,OACrBm/D,GAAoC,QAAxBpyC,EAAMtoB,gBAIhDqsB,GAEJ,CAEO,SAASuuC,KACdH,GAA0B,OAAQtuC,IAClCsuC,GAA0B,mBAAoBnoC,IAC9CmoC,GAA0B,qBAAsBloC,IAChDkoC,GAA0B,qBAAsB/nC,IAChD+nC,GAA0B,iBAAkB9nC,IAC5C8nC,GAA0B,oBAAqB7nC,IAC/C6nC,GAA0B,YAAa5nC,IACvC4nC,GAA0B,oBAAqBlnC,IAC/CknC,GAA0B,oBAAqBjnC,IAC/CinC,GAA0B,mBAAoBhnC,IAC9CgnC,GAA0B,gBAAiB/mC,IAC3C+mC,GAA0B,kBAAmBjmC,GAC/C,uqQA1BA6kC,KA4BAuB,KAEAC,GAA2BvB,iBAAiB,MAAO,CAAC,SAAU","x_google_ignoreList":[20]}
|