@colijnit/configurator 261.1.0 → 261.1.1
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/bundles/colijnit-configurator.umd.js +18012 -1838
- package/bundles/colijnit-configurator.umd.js.map +1 -1
- package/colijnit-configurator.d.ts +2 -6
- package/esm2015/colijnit-configurator.js +2 -7
- package/esm2015/lib/builder.js +795 -0
- package/esm2015/lib/components/answer-card/answer-card.component.js +313 -0
- package/esm2015/lib/components/answer-card/answer-card.module.js +50 -0
- package/esm2015/lib/components/answer-info-dialog/answer-info-dialog.component.js +182 -0
- package/esm2015/lib/components/answer-info-dialog/answer-info-dialog.module.js +34 -0
- package/esm2015/lib/components/answers-slideout/answers-slideout.component.js +490 -0
- package/esm2015/lib/components/answers-slideout/answers-slideout.module.js +61 -0
- package/esm2015/lib/components/color-filter/color-filter.component.js +59 -0
- package/esm2015/lib/components/color-filter/color-filter.module.js +26 -0
- package/esm2015/lib/components/configurator/configurator.component.js +133 -0
- package/esm2015/lib/components/configurator/configurator.module.js +42 -0
- package/esm2015/lib/components/configurator-dialog/configurator-camera-settings.component.js +222 -0
- package/esm2015/lib/components/configurator-dialog/configurator-dialog.module.js +48 -0
- package/esm2015/lib/components/configurator-dialog/configurator-error-dialog.component.js +82 -0
- package/esm2015/lib/components/configurator-dialog/configurator-export-dialog.component.js +163 -0
- package/esm2015/lib/components/configurator-loader/configurator-loader.component.js +49 -0
- package/esm2015/lib/components/configurator-loader/configurator-loader.module.js +33 -0
- package/esm2015/lib/components/configurator-scene/configurator-scene.component.js +60 -0
- package/esm2015/lib/components/configurator-scene/configurator-scene.module.js +17 -0
- package/esm2015/lib/components/configurator-scene-loader/configurator-scene-loader.component.js +46 -0
- package/esm2015/lib/components/configurator-scene-loader/configurator-scene-loader.module.js +26 -0
- package/esm2015/lib/components/element-buttons/element-buttons.component.js +168 -0
- package/esm2015/lib/components/element-buttons/element-buttons.module.js +30 -0
- package/esm2015/lib/components/element-toolbar/element-toolbar.component.js +186 -0
- package/esm2015/lib/components/element-toolbar/element-toolbar.module.js +34 -0
- package/esm2015/lib/components/image-zoom/image-zoom.component.js +61 -0
- package/esm2015/lib/components/image-zoom/image-zoom.module.js +30 -0
- package/esm2015/lib/components/lite-selector/lite-selector.component.js +206 -0
- package/esm2015/lib/components/lite-selector/lite-selector.module.js +34 -0
- package/esm2015/lib/components/product-configurator/product-configurator.component.js +184 -0
- package/esm2015/lib/components/product-configurator/product-configurator.module.js +72 -0
- package/esm2015/lib/components/product-configurator-selector/product-configurator-selector.component.js +237 -0
- package/esm2015/lib/components/product-configurator-selector/product-configurator-selector.module.js +38 -0
- package/esm2015/lib/components/product-configurator-selector-option/product-configurator-selector-option.component.js +284 -0
- package/esm2015/lib/components/product-configurator-selector-option/product-configurator-selector-option.module.js +42 -0
- package/esm2015/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.component.js +72 -0
- package/esm2015/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.module.js +34 -0
- package/esm2015/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.component.js +82 -0
- package/esm2015/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.module.js +30 -0
- package/esm2015/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.component.js +80 -0
- package/esm2015/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.module.js +34 -0
- package/esm2015/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.component.js +93 -0
- package/esm2015/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.module.js +34 -0
- package/esm2015/lib/components/progress-bar/progress-bar.component.js +55 -0
- package/esm2015/lib/components/progress-bar/progress-bar.module.js +29 -0
- package/esm2015/lib/components/scene-options/scene-options.component.js +164 -0
- package/esm2015/lib/components/scene-options/scene-options.module.js +38 -0
- package/esm2015/lib/components/selections-summary/selections-summary.component.js +163 -0
- package/esm2015/lib/components/selections-summary/selections-summary.module.js +45 -0
- package/esm2015/lib/components/selections-summary-line/selections-summary-line.component.js +171 -0
- package/esm2015/lib/components/selections-summary-line/selections-summary-line.module.js +34 -0
- package/esm2015/lib/components/slideout/slideout.component.js +83 -0
- package/esm2015/lib/components/slideout/slideout.module.js +17 -0
- package/esm2015/lib/components/summary-line/summary-line.component.js +273 -0
- package/esm2015/lib/components/summary-line/summary-line.module.js +44 -0
- package/esm2015/lib/components/tag-filter/tag-filter.component.js +39 -0
- package/esm2015/lib/components/tag-filter/tag-filter.module.js +21 -0
- package/esm2015/lib/components/threedselector/threedselector.component.js +155 -0
- package/esm2015/lib/components/threedselector/threedselector.module.js +34 -0
- package/esm2015/lib/core/helper/variation-helper.js +553 -0
- package/esm2015/lib/core/shader/floor-fade.shader.js +33 -0
- package/esm2015/lib/core/textures/depth-data-texture.js +19 -0
- package/esm2015/lib/directives/directives.module.js +26 -0
- package/esm2015/lib/directives/visibility-observer-master.directive.js +53 -0
- package/esm2015/lib/directives/visibility-observer.directive.js +54 -0
- package/esm2015/lib/enum/ar-feature.enum.js +14 -0
- package/esm2015/lib/enum/configuration-key.enum.js +41 -0
- package/esm2015/lib/enum/configuration-template.enum.js +6 -0
- package/esm2015/lib/enum/device-size-type.js +7 -0
- package/esm2015/lib/enum/device-tier.enum.js +7 -0
- package/esm2015/lib/enum/icon.enum.js +113 -0
- package/esm2015/lib/enum/item-type.enum.js +23 -0
- package/esm2015/lib/enum/light.enum.js +9 -0
- package/esm2015/lib/enum/navigator-type.enum.js +6 -0
- package/esm2015/lib/enum/output-encoding.enum.js +9 -0
- package/esm2015/lib/enum/result-type.enum.js +21 -0
- package/esm2015/lib/enum/scene-event.enum.js +12 -0
- package/esm2015/lib/enum/shadow-map-type.enum.js +8 -0
- package/esm2015/lib/enum/texture-type.js +9 -0
- package/esm2015/lib/enum/tone-mapping-local.enum.js +12 -0
- package/esm2015/lib/enum/view-mode.enum.js +7 -0
- package/esm2015/lib/enum/xr-mode.enum.js +6 -0
- package/esm2015/lib/environments/environment.js +8 -0
- package/esm2015/lib/interfaces/aa-options.interface.js +2 -0
- package/esm2015/lib/interfaces/adjustable-element.interface.js +2 -0
- package/esm2015/lib/interfaces/ao-options.interface.js +2 -0
- package/esm2015/lib/interfaces/changes.interface.js +2 -0
- package/esm2015/lib/interfaces/configuration-data.interface.js +2 -0
- package/esm2015/lib/interfaces/light-preset.interface.js +2 -0
- package/esm2015/lib/interfaces/post-processing-setting.interface.js +2 -0
- package/esm2015/lib/interfaces/scene-option-button.interface.js +6 -0
- package/esm2015/lib/interfaces/screen-size-info.js +2 -0
- package/esm2015/lib/interfaces/setting.interface.js +2 -0
- package/esm2015/lib/interfaces/texture.interface.js +2 -0
- package/esm2015/lib/interfaces/vignette-options.interface.js +2 -0
- package/esm2015/lib/model/ar-position-indicator.js +18 -0
- package/esm2015/lib/model/camera-settings.js +14 -0
- package/esm2015/lib/model/configuration-result-object.js +6 -0
- package/esm2015/lib/model/configurator-error-message.js +9 -0
- package/esm2015/lib/model/configurator-settings.js +25 -0
- package/esm2015/lib/model/custom-button.js +16 -0
- package/esm2015/lib/model/factory.js +28 -0
- package/esm2015/lib/model/icon.js +112 -0
- package/esm2015/lib/model/intersected-objects.js +7 -0
- package/esm2015/lib/model/light-preset.js +73 -0
- package/esm2015/lib/model/light-properties.js +45 -0
- package/esm2015/lib/model/material.js +11 -0
- package/esm2015/lib/model/metadata.js +2 -0
- package/esm2015/lib/model/render-parameters.js +16 -0
- package/esm2015/lib/model/setting-options.js +71 -0
- package/esm2015/lib/model/settings.js +16 -0
- package/esm2015/lib/model/shadow-properties.js +10 -0
- package/esm2015/lib/model/skin.js +3 -0
- package/esm2015/lib/model/texture.js +76 -0
- package/esm2015/lib/model/variation-settings.js +54 -0
- package/esm2015/lib/model/variation.js +3 -0
- package/esm2015/lib/model/xr-reticle.js +79 -0
- package/esm2015/lib/modules/render/enum/scene-type.enum.js +6 -0
- package/esm2015/lib/modules/render/model/ar-parameters.js +12 -0
- package/esm2015/lib/modules/render/model/scene-setting.js +6 -0
- package/esm2015/lib/modules/render/model/scene-settings.js +3 -0
- package/esm2015/lib/pipes/append.pipe.js +21 -0
- package/esm2015/lib/pipes/google-translate.pipe.js +21 -0
- package/esm2015/lib/pipes/localize.pipe.js +28 -0
- package/esm2015/lib/pipes/pipes.module.js +41 -0
- package/esm2015/lib/pipes/prepend.pipe.js +21 -0
- package/esm2015/lib/pipes/strip-html.pipe.js +17 -0
- package/esm2015/lib/services/app-event.service.js +36 -0
- package/esm2015/lib/services/app-initializer.service.js +27 -0
- package/esm2015/lib/services/ar.service.js +844 -0
- package/esm2015/lib/services/build-furniture-base.service.js +1181 -0
- package/esm2015/lib/services/build-furniture-without-scene.service.js +86 -0
- package/esm2015/lib/services/build-furniture.service.js +169 -0
- package/esm2015/lib/services/bundle-initialzer.service.js +113 -0
- package/esm2015/lib/services/camera.service.js +123 -0
- package/esm2015/lib/services/configuration.service.js +79 -0
- package/esm2015/lib/services/configurator-connector.service.js +830 -0
- package/esm2015/lib/services/configurator.service.js +285 -0
- package/esm2015/lib/services/configuring.service.js +119 -0
- package/esm2015/lib/services/controls.js +799 -0
- package/esm2015/lib/services/debug.service.js +43 -0
- package/esm2015/lib/services/dictionary.service.js +65 -0
- package/esm2015/lib/services/dynamic-camera.service.js +96 -0
- package/esm2015/lib/services/floor-plane.service.js +252 -0
- package/esm2015/lib/services/font.service.js +27 -0
- package/esm2015/lib/services/google-translate.service.js +79 -0
- package/esm2015/lib/services/icon-cache.service.js +44 -0
- package/esm2015/lib/services/intersection.service.js +47 -0
- package/esm2015/lib/services/item.service.js +75 -0
- package/esm2015/lib/services/json-utils.service.js +48 -0
- package/esm2015/lib/services/light-creation.service.js +35 -0
- package/esm2015/lib/services/light-presets.service.js +157 -0
- package/esm2015/lib/services/lights.service.js +146 -0
- package/esm2015/lib/services/load-furniture-base.service.js +164 -0
- package/esm2015/lib/services/load-furniture-without-scene.service.js +45 -0
- package/esm2015/lib/services/load-furniture.service.js +72 -0
- package/esm2015/lib/services/loader.service.js +32 -0
- package/esm2015/lib/services/locator.service.js +11 -0
- package/esm2015/lib/services/message-board.service.js +50 -0
- package/esm2015/lib/services/post-processing.service.js +378 -0
- package/esm2015/lib/services/product-configurator.service.js +16 -0
- package/esm2015/lib/services/progress.service.js +20 -0
- package/esm2015/lib/services/scene-event.service.js +246 -0
- package/esm2015/lib/services/scene-options.service.js +24 -0
- package/esm2015/lib/services/scene.service.js +313 -0
- package/esm2015/lib/services/screen-size-analysis.service.js +97 -0
- package/esm2015/lib/services/settings.service.js +142 -0
- package/esm2015/lib/services/switch-build-furniture.service.js +37 -0
- package/esm2015/lib/services/switch-load-furniture.service.js +35 -0
- package/esm2015/lib/services/threedselector.service.js +72 -0
- package/esm2015/lib/services/utils.service.js +207 -0
- package/esm2015/lib/services/variation-cache.service.js +143 -0
- package/esm2015/lib/services/variation.service.js +490 -0
- package/esm2015/lib/services/view-mode.service.js +37 -0
- package/esm2015/lib/services/vr.service.js +191 -0
- package/esm2015/lib/services/xr.service.js +294 -0
- package/esm2015/lib/utils/asset.utils.js +120 -0
- package/esm2015/lib/utils/base-utils.js +9 -0
- package/esm2015/lib/utils/color.utils.js +30 -0
- package/esm2015/lib/utils/debug.utils.js +9 -0
- package/esm2015/lib/utils/device.utils.js +25 -0
- package/esm2015/lib/utils/file.utils.js +167 -0
- package/esm2015/lib/utils/image.utils.js +61 -0
- package/esm2015/lib/utils/json-parser.utils.js +180 -0
- package/esm2015/lib/utils/material.utils.js +433 -0
- package/esm2015/lib/utils/object.utils.js +360 -0
- package/esm2015/lib/utils/relative-position.utils.js +75 -0
- package/esm2015/lib/utils/rotation-helper.utils.js +15 -0
- package/esm2015/lib/utils/scene-3d.utils.js +213 -0
- package/esm2015/lib/utils/scene-utils.js +191 -0
- package/esm2015/lib/utils/text-utils.js +68 -0
- package/esm2015/lib/utils/threed.utils.js +281 -0
- package/esm2015/lib/utils/variation-utils.js +459 -0
- package/esm2015/public-api.js +65 -0
- package/fesm2015/colijnit-configurator.js +17512 -1451
- package/fesm2015/colijnit-configurator.js.map +1 -1
- package/{app → lib}/builder.d.ts +9 -1
- package/lib/components/answer-card/answer-card.component.d.ts +58 -0
- package/lib/components/answer-card/answer-card.module.d.ts +11 -0
- package/lib/components/answer-card/style/_layout.scss +88 -0
- package/lib/components/answer-card/style/_material-definition.scss +3 -0
- package/lib/components/answer-card/style/_theme.scss +67 -0
- package/lib/components/answer-card/style/material.scss +2 -0
- package/lib/components/answer-info-dialog/answer-info-dialog.component.d.ts +38 -0
- package/lib/components/answer-info-dialog/answer-info-dialog.module.d.ts +10 -0
- package/lib/components/answer-info-dialog/style/_layout.scss +88 -0
- package/lib/components/answer-info-dialog/style/_material-definition.scss +3 -0
- package/lib/components/answer-info-dialog/style/_theme.scss +44 -0
- package/lib/components/answer-info-dialog/style/material.scss +3 -0
- package/lib/components/answers-slideout/answers-slideout.component.d.ts +86 -0
- package/lib/components/answers-slideout/answers-slideout.module.d.ts +16 -0
- package/lib/components/answers-slideout/style/_layout.scss +198 -0
- package/lib/components/answers-slideout/style/_material-definition.scss +3 -0
- package/lib/components/answers-slideout/style/_theme.scss +54 -0
- package/lib/components/answers-slideout/style/material.scss +3 -0
- package/lib/components/color-filter/color-filter.component.d.ts +20 -0
- package/lib/components/color-filter/color-filter.module.d.ts +8 -0
- package/lib/components/color-filter/style/_layout.scss +41 -0
- package/lib/components/color-filter/style/_material-definition.scss +3 -0
- package/lib/components/color-filter/style/_theme.scss +7 -0
- package/lib/components/color-filter/style/material.scss +3 -0
- package/lib/components/configurator/configurator.component.d.ts +37 -0
- package/lib/components/configurator/configurator.module.d.ts +12 -0
- package/lib/components/configurator/style/_layout.scss +7 -0
- package/lib/components/configurator/style/_material-definition.scss +3 -0
- package/lib/components/configurator/style/_theme.scss +7 -0
- package/lib/components/configurator/style/material.scss +3 -0
- package/lib/components/configurator-dialog/configurator-camera-settings.component.d.ts +30 -0
- package/lib/components/configurator-dialog/configurator-dialog.module.d.ts +13 -0
- package/lib/components/configurator-dialog/configurator-error-dialog.component.d.ts +16 -0
- package/lib/components/configurator-dialog/configurator-export-dialog.component.d.ts +26 -0
- package/lib/components/configurator-dialog/style/_layout.scss +129 -0
- package/lib/components/configurator-dialog/style/_material-definition.scss +4 -0
- package/lib/components/configurator-dialog/style/_theme.scss +89 -0
- package/lib/components/configurator-dialog/style/material.scss +3 -0
- package/lib/components/configurator-loader/configurator-loader.component.d.ts +7 -0
- package/lib/components/configurator-loader/configurator-loader.module.d.ts +9 -0
- package/lib/components/configurator-loader/style/_layout.scss +72 -0
- package/lib/components/configurator-loader/style/_material-definition.scss +5 -0
- package/lib/components/configurator-loader/style/_theme.scss +26 -0
- package/lib/components/configurator-loader/style/material.scss +14 -0
- package/lib/components/configurator-scene/configurator-scene.component.d.ts +24 -0
- package/lib/components/configurator-scene/configurator-scene.module.d.ts +7 -0
- package/lib/components/configurator-scene/style/_layout.scss +22 -0
- package/lib/components/configurator-scene/style/_material-definition.scss +3 -0
- package/lib/components/configurator-scene/style/_theme.scss +7 -0
- package/lib/components/configurator-scene/style/material.scss +3 -0
- package/lib/components/configurator-scene-loader/configurator-scene-loader.component.d.ts +7 -0
- package/lib/components/configurator-scene-loader/configurator-scene-loader.module.d.ts +8 -0
- package/lib/components/configurator-scene-loader/style/_layout.scss +72 -0
- package/lib/components/configurator-scene-loader/style/_material-definition.scss +5 -0
- package/lib/components/configurator-scene-loader/style/_theme.scss +26 -0
- package/lib/components/configurator-scene-loader/style/material.scss +14 -0
- package/lib/components/element-buttons/element-buttons.component.d.ts +32 -0
- package/lib/components/element-buttons/element-buttons.module.d.ts +9 -0
- package/lib/components/element-buttons/style/_layout.scss +52 -0
- package/lib/components/element-buttons/style/_material-definition.scss +3 -0
- package/lib/components/element-buttons/style/_theme.scss +23 -0
- package/lib/components/element-buttons/style/material.scss +3 -0
- package/lib/components/element-toolbar/element-toolbar.component.d.ts +27 -0
- package/lib/components/element-toolbar/element-toolbar.component.scss +59 -0
- package/lib/components/element-toolbar/element-toolbar.module.d.ts +10 -0
- package/lib/components/element-toolbar/style/_layout.scss +107 -0
- package/lib/components/element-toolbar/style/_material-definition.scss +3 -0
- package/lib/components/element-toolbar/style/_theme.scss +47 -0
- package/lib/components/element-toolbar/style/material.scss +3 -0
- package/lib/components/image-zoom/image-zoom.component.d.ts +15 -0
- package/lib/components/image-zoom/image-zoom.module.d.ts +9 -0
- package/lib/components/image-zoom/style/_layout.scss +51 -0
- package/lib/components/image-zoom/style/_material-definition.scss +3 -0
- package/lib/components/image-zoom/style/_theme.scss +17 -0
- package/lib/components/image-zoom/style/material.scss +3 -0
- package/lib/components/lite-selector/lite-selector.component.d.ts +40 -0
- package/lib/components/lite-selector/lite-selector.module.d.ts +10 -0
- package/lib/components/lite-selector/style/_layout.scss +21 -0
- package/lib/components/lite-selector/style/_material-definition.scss +3 -0
- package/lib/components/lite-selector/style/_theme.scss +7 -0
- package/lib/components/lite-selector/style/material.scss +3 -0
- package/lib/components/product-configurator/product-configurator.component.d.ts +50 -0
- package/lib/components/product-configurator/product-configurator.module.d.ts +15 -0
- package/lib/components/product-configurator/style/_layout.scss +46 -0
- package/lib/components/product-configurator/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator/style/_theme.scss +22 -0
- package/lib/components/product-configurator/style/material.scss +3 -0
- package/lib/components/product-configurator-selector/product-configurator-selector.component.d.ts +35 -0
- package/lib/components/product-configurator-selector/product-configurator-selector.module.d.ts +11 -0
- package/lib/components/product-configurator-selector/style/_layout.scss +145 -0
- package/lib/components/product-configurator-selector/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector/style/_theme.scss +57 -0
- package/lib/components/product-configurator-selector/style/material.scss +3 -0
- package/lib/components/product-configurator-selector-option/product-configurator-selector-option.component.d.ts +31 -0
- package/lib/components/product-configurator-selector-option/product-configurator-selector-option.module.d.ts +13 -0
- package/lib/components/product-configurator-selector-option/style/_layout.scss +7 -0
- package/lib/components/product-configurator-selector-option/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector-option/style/_theme.scss +7 -0
- package/lib/components/product-configurator-selector-option/style/material.scss +3 -0
- package/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.component.d.ts +20 -0
- package/lib/components/product-configurator-selector-option-button/product-configurator-selector-option-button.module.d.ts +10 -0
- package/lib/components/product-configurator-selector-option-button/style/_layout.scss +28 -0
- package/lib/components/product-configurator-selector-option-button/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector-option-button/style/_theme.scss +33 -0
- package/lib/components/product-configurator-selector-option-button/style/material.scss +3 -0
- package/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.component.d.ts +20 -0
- package/lib/components/product-configurator-selector-option-checkbox/product-configurator-selector-option-checkbox.module.d.ts +10 -0
- package/lib/components/product-configurator-selector-option-checkbox/style/_layout.scss +28 -0
- package/lib/components/product-configurator-selector-option-checkbox/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector-option-checkbox/style/_theme.scss +27 -0
- package/lib/components/product-configurator-selector-option-checkbox/style/material.scss +3 -0
- package/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.component.d.ts +21 -0
- package/lib/components/product-configurator-selector-option-dropdown/product-configurator-selector-option-dropdown.module.d.ts +10 -0
- package/lib/components/product-configurator-selector-option-dropdown/style/_layout.scss +34 -0
- package/lib/components/product-configurator-selector-option-dropdown/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector-option-dropdown/style/_theme.scss +28 -0
- package/lib/components/product-configurator-selector-option-dropdown/style/material.scss +3 -0
- package/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.component.d.ts +21 -0
- package/lib/components/product-configurator-selector-option-tile/product-configurator-selector-option-tile.module.d.ts +10 -0
- package/lib/components/product-configurator-selector-option-tile/style/_layout.scss +58 -0
- package/lib/components/product-configurator-selector-option-tile/style/_material-definition.scss +3 -0
- package/lib/components/product-configurator-selector-option-tile/style/_theme.scss +56 -0
- package/lib/components/product-configurator-selector-option-tile/style/material.scss +3 -0
- package/lib/components/progress-bar/progress-bar.component.d.ts +10 -0
- package/lib/components/progress-bar/progress-bar.component.scss +14 -0
- package/lib/components/progress-bar/progress-bar.module.d.ts +8 -0
- package/lib/components/progress-bar/style/_layout.scss +18 -0
- package/lib/components/progress-bar/style/_material-definition.scss +3 -0
- package/lib/components/progress-bar/style/_theme.scss +10 -0
- package/lib/components/progress-bar/style/material.scss +3 -0
- package/lib/components/scene-options/scene-options.component.d.ts +24 -0
- package/lib/components/scene-options/scene-options.module.d.ts +11 -0
- package/lib/components/scene-options/style/_layout.scss +52 -0
- package/lib/components/scene-options/style/_material-definition.scss +3 -0
- package/lib/components/scene-options/style/_theme.scss +7 -0
- package/lib/components/scene-options/style/material.scss +3 -0
- package/lib/components/selections-summary/selections-summary.component.d.ts +38 -0
- package/lib/components/selections-summary/selections-summary.module.d.ts +12 -0
- package/lib/components/selections-summary/style/_layout.scss +87 -0
- package/lib/components/selections-summary/style/_material-definition.scss +5 -0
- package/lib/components/selections-summary/style/_theme.scss +13 -0
- package/lib/components/selections-summary/style/material.scss +3 -0
- package/lib/components/selections-summary-line/selections-summary-line.component.d.ts +27 -0
- package/lib/components/selections-summary-line/selections-summary-line.module.d.ts +10 -0
- package/lib/components/selections-summary-line/style/_layout.scss +12 -0
- package/lib/components/selections-summary-line/style/_material-definition.scss +4 -0
- package/lib/components/selections-summary-line/style/_theme.scss +12 -0
- package/lib/components/selections-summary-line/style/material.scss +3 -0
- package/lib/components/slideout/slideout.component.d.ts +22 -0
- package/lib/components/slideout/slideout.module.d.ts +7 -0
- package/lib/components/slideout/style/_layout.scss +27 -0
- package/lib/components/slideout/style/_material-definition.scss +3 -0
- package/lib/components/slideout/style/_theme.scss +5 -0
- package/lib/components/slideout/style/material.scss +3 -0
- package/lib/components/summary-line/style/_layout.scss +137 -0
- package/lib/components/summary-line/style/_material-definition.scss +4 -0
- package/lib/components/summary-line/style/_theme.scss +56 -0
- package/lib/components/summary-line/style/material.scss +3 -0
- package/lib/components/summary-line/summary-line.component.d.ts +50 -0
- package/lib/components/summary-line/summary-line.module.d.ts +11 -0
- package/lib/components/tag-filter/style/_layout.scss +14 -0
- package/lib/components/tag-filter/style/_material-definition.scss +3 -0
- package/lib/components/tag-filter/style/_theme.scss +7 -0
- package/lib/components/tag-filter/style/material.scss +3 -0
- package/lib/components/tag-filter/tag-filter.component.d.ts +9 -0
- package/lib/components/tag-filter/tag-filter.module.d.ts +7 -0
- package/lib/components/threedselector/style/_layout.scss +32 -0
- package/lib/components/threedselector/style/_material-definition.scss +3 -0
- package/lib/components/threedselector/style/_theme.scss +7 -0
- package/lib/components/threedselector/style/material.scss +9 -0
- package/lib/components/threedselector/threedselector.component.d.ts +38 -0
- package/lib/components/threedselector/threedselector.module.d.ts +10 -0
- package/{helper → lib/core/helper}/variation-helper.d.ts +2 -2
- package/lib/core/shader/floor-fade.shader.d.ts +5 -0
- package/lib/core/textures/depth-data-texture.d.ts +5 -0
- package/lib/directives/directives.module.d.ts +8 -0
- package/{app → lib}/directives/visibility-observer-master.directive.d.ts +3 -0
- package/{app → lib}/directives/visibility-observer.directive.d.ts +3 -0
- package/lib/enum/ar-feature.enum.d.ts +12 -0
- package/lib/enum/configuration-key.enum.d.ts +39 -0
- package/lib/enum/configuration-template.enum.d.ts +4 -0
- package/lib/enum/device-size-type.d.ts +5 -0
- package/lib/enum/device-tier.enum.d.ts +5 -0
- package/lib/enum/icon.enum.d.ts +111 -0
- package/lib/enum/item-type.enum.d.ts +21 -0
- package/lib/enum/light.enum.d.ts +7 -0
- package/lib/enum/navigator-type.enum.d.ts +4 -0
- package/lib/enum/output-encoding.enum.d.ts +7 -0
- package/lib/enum/result-type.enum.d.ts +19 -0
- package/lib/enum/scene-event.enum.d.ts +10 -0
- package/lib/enum/shadow-map-type.enum.d.ts +6 -0
- package/lib/enum/texture-type.d.ts +7 -0
- package/lib/enum/tone-mapping-local.enum.d.ts +10 -0
- package/lib/enum/view-mode.enum.d.ts +5 -0
- package/lib/enum/xr-mode.enum.d.ts +4 -0
- package/lib/environments/environment.d.ts +4 -0
- package/lib/interfaces/aa-options.interface.d.ts +4 -0
- package/lib/interfaces/adjustable-element.interface.d.ts +5 -0
- package/lib/interfaces/ao-options.interface.d.ts +18 -0
- package/lib/interfaces/changes.interface.d.ts +9 -0
- package/lib/interfaces/configuration-data.interface.d.ts +40 -0
- package/lib/interfaces/light-preset.interface.d.ts +22 -0
- package/lib/interfaces/post-processing-setting.interface.d.ts +11 -0
- package/lib/interfaces/scene-option-button.interface.d.ts +19 -0
- package/lib/interfaces/screen-size-info.d.ts +10 -0
- package/lib/interfaces/setting.interface.d.ts +8 -0
- package/lib/interfaces/texture.interface.d.ts +44 -0
- package/lib/interfaces/vignette-options.interface.d.ts +4 -0
- package/lib/model/ar-position-indicator.d.ts +4 -0
- package/lib/model/camera-settings.d.ts +12 -0
- package/lib/model/configuration-result-object.d.ts +30 -0
- package/lib/model/configurator-error-message.d.ts +8 -0
- package/lib/model/configurator-settings.d.ts +62 -0
- package/lib/model/custom-button.d.ts +10 -0
- package/lib/model/factory.d.ts +5 -0
- package/lib/model/icon.d.ts +4 -0
- package/lib/model/intersected-objects.d.ts +6 -0
- package/lib/model/light-preset.d.ts +33 -0
- package/lib/model/light-properties.d.ts +25 -0
- package/lib/model/material.d.ts +41 -0
- package/lib/model/metadata.d.ts +78 -0
- package/lib/model/render-parameters.d.ts +12 -0
- package/lib/model/setting-options.d.ts +67 -0
- package/lib/model/settings.d.ts +10 -0
- package/lib/model/shadow-properties.d.ts +7 -0
- package/lib/model/skin.d.ts +15 -0
- package/lib/model/texture.d.ts +52 -0
- package/{model → lib/model}/variation-settings.d.ts +9 -8
- package/{model → lib/model}/variation.d.ts +2 -1
- package/lib/model/xr-reticle.d.ts +17 -0
- package/lib/modules/render/enum/scene-type.enum.d.ts +4 -0
- package/lib/modules/render/model/ar-parameters.d.ts +9 -0
- package/lib/modules/render/model/scene-setting.d.ts +13 -0
- package/lib/modules/render/model/scene-settings.d.ts +4 -0
- package/lib/pipes/append.pipe.d.ts +7 -0
- package/lib/pipes/google-translate.pipe.d.ts +11 -0
- package/lib/pipes/localize.pipe.d.ts +10 -0
- package/lib/pipes/pipes.module.d.ts +11 -0
- package/lib/pipes/prepend.pipe.d.ts +7 -0
- package/lib/pipes/strip-html.pipe.d.ts +7 -0
- package/lib/services/app-event.service.d.ts +32 -0
- package/lib/services/app-initializer.service.d.ts +14 -0
- package/lib/services/ar.service.d.ts +120 -0
- package/lib/services/build-furniture-base.service.d.ts +117 -0
- package/lib/services/build-furniture-without-scene.service.d.ts +14 -0
- package/lib/services/build-furniture.service.d.ts +14 -0
- package/lib/services/bundle-initialzer.service.d.ts +45 -0
- package/lib/services/camera.service.d.ts +44 -0
- package/lib/services/configuration.service.d.ts +18 -0
- package/lib/services/configurator-connector.service.d.ts +140 -0
- package/lib/services/configurator.service.d.ts +62 -0
- package/lib/services/configuring.service.d.ts +46 -0
- package/lib/services/controls.d.ts +11 -0
- package/lib/services/debug.service.d.ts +16 -0
- package/lib/services/dictionary.service.d.ts +15 -0
- package/lib/services/dynamic-camera.service.d.ts +21 -0
- package/lib/services/floor-plane.service.d.ts +47 -0
- package/lib/services/font.service.d.ts +10 -0
- package/lib/services/google-translate.service.d.ts +26 -0
- package/lib/services/icon-cache.service.d.ts +21 -0
- package/lib/services/intersection.service.d.ts +11 -0
- package/lib/services/item.service.d.ts +18 -0
- package/lib/services/json-utils.service.d.ts +7 -0
- package/lib/services/light-creation.service.d.ts +9 -0
- package/lib/services/light-presets.service.d.ts +34 -0
- package/lib/services/lights.service.d.ts +34 -0
- package/lib/services/load-furniture-base.service.d.ts +37 -0
- package/lib/services/load-furniture-without-scene.service.d.ts +9 -0
- package/lib/services/load-furniture.service.d.ts +9 -0
- package/lib/services/loader.service.d.ts +11 -0
- package/lib/services/locator.service.d.ts +7 -0
- package/lib/services/message-board.service.d.ts +18 -0
- package/lib/services/post-processing.service.d.ts +74 -0
- package/lib/services/product-configurator.service.d.ts +11 -0
- package/lib/services/progress.service.d.ts +9 -0
- package/lib/services/scene-event.service.d.ts +72 -0
- package/lib/services/scene-options.service.d.ts +11 -0
- package/lib/services/scene.service.d.ts +71 -0
- package/lib/services/screen-size-analysis.service.d.ts +32 -0
- package/lib/services/settings.service.d.ts +24 -0
- package/lib/services/switch-build-furniture.service.d.ts +21 -0
- package/lib/services/switch-load-furniture.service.d.ts +21 -0
- package/lib/services/threedselector.service.d.ts +17 -0
- package/lib/services/utils.service.d.ts +24 -0
- package/lib/services/variation-cache.service.d.ts +23 -0
- package/lib/services/variation.service.d.ts +26 -0
- package/lib/services/view-mode.service.d.ts +17 -0
- package/lib/services/vr.service.d.ts +42 -0
- package/lib/services/xr.service.d.ts +56 -0
- package/lib/style/_mixin.scss +9 -0
- package/lib/style/configurator-globals.scss +21 -0
- package/lib/style/template_variables.scss +37 -0
- package/lib/utils/color.utils.d.ts +8 -0
- package/lib/utils/debug.utils.d.ts +3 -0
- package/lib/utils/device.utils.d.ts +7 -0
- package/{utils → lib/utils}/file.utils.d.ts +3 -0
- package/{utils → lib/utils}/image.utils.d.ts +2 -3
- package/lib/utils/json-parser.utils.d.ts +9 -0
- package/lib/utils/material.utils.d.ts +34 -0
- package/lib/utils/object.utils.d.ts +32 -0
- package/lib/utils/relative-position.utils.d.ts +12 -0
- package/lib/utils/rotation-helper.utils.d.ts +6 -0
- package/lib/utils/scene-3d.utils.d.ts +8 -0
- package/lib/utils/text-utils.d.ts +4 -0
- package/{utils → lib/utils}/threed.utils.d.ts +7 -3
- package/{utils → lib/utils}/variation-utils.d.ts +4 -2
- package/package.json +17 -30
- package/public-api.d.ts +60 -0
- package/README.md +0 -28
- package/app/components/answers/answer/answer.component.d.ts +0 -11
- package/app/components/answers/answers.component.d.ts +0 -8
- package/app/components/answers/answers.module.d.ts +0 -2
- package/app/components/selections/selections.component.d.ts +0 -21
- package/app/components/selections/selections.module.d.ts +0 -2
- package/app/components/shared/loader/loader.component.d.ts +0 -2
- package/app/components/shared/shared.module.d.ts +0 -2
- package/app/services/configurator.service.d.ts +0 -19
- package/app/services/image-cache.service.d.ts +0 -10
- package/app/utils/object.utils.d.ts +0 -7
- package/colijnit-configurator.metadata.json +0 -1
- package/esm2015/app/builder.js +0 -710
- package/esm2015/app/components/answers/answer/answer.component.js +0 -66
- package/esm2015/app/components/answers/answers.component.js +0 -38
- package/esm2015/app/components/answers/answers.module.js +0 -27
- package/esm2015/app/components/selections/selections.component.js +0 -129
- package/esm2015/app/components/selections/selections.module.js +0 -21
- package/esm2015/app/components/shared/loader/loader.component.js +0 -22
- package/esm2015/app/components/shared/shared.module.js +0 -19
- package/esm2015/app/directives/visibility-observer-master.directive.js +0 -50
- package/esm2015/app/directives/visibility-observer.directive.js +0 -55
- package/esm2015/app/services/configurator.service.js +0 -79
- package/esm2015/app/services/image-cache.service.js +0 -63
- package/esm2015/app/utils/object.utils.js +0 -51
- package/esm2015/helper/variation-helper.js +0 -549
- package/esm2015/model/material.js +0 -11
- package/esm2015/model/variation-settings.js +0 -54
- package/esm2015/model/variation.js +0 -3
- package/esm2015/public_api.js +0 -7
- package/esm2015/utils/asset.utils.js +0 -124
- package/esm2015/utils/base-utils.js +0 -9
- package/esm2015/utils/file.utils.js +0 -142
- package/esm2015/utils/image.utils.js +0 -66
- package/esm2015/utils/object.utils.js +0 -49
- package/esm2015/utils/scene-utils.js +0 -187
- package/esm2015/utils/threed.utils.js +0 -226
- package/esm2015/utils/variation-utils.js +0 -388
- package/model/material.d.ts +0 -40
- package/public_api.d.ts +0 -6
- package/utils/object.utils.d.ts +0 -7
- /package/{utils → lib/utils}/asset.utils.d.ts +0 -0
- /package/{utils → lib/utils}/base-utils.d.ts +0 -0
- /package/{utils → lib/utils}/scene-utils.d.ts +0 -0
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { Box3, DirectionalLight, DoubleSide, LightProbe, Matrix4, Mesh, MeshBasicMaterial, MeshPhongMaterial, PCFSoftShadowMap, PlaneGeometry, Raycaster, Scene, ShadowMaterial, SphereGeometry, SRGBColorSpace, Texture, Vector3 } from 'three';
|
|
5
|
+
import * as TWEEN from '@tweenjs/tween.js';
|
|
6
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
7
|
+
import { ArFeature } from '../enum/ar-feature.enum';
|
|
8
|
+
import { Reticle } from '../model/xr-reticle';
|
|
9
|
+
import { DepthDataTexture } from '../core/textures/depth-data-texture';
|
|
10
|
+
import { ArPositionIndicator } from '../model/ar-position-indicator';
|
|
11
|
+
import { ObjectUtils } from '../utils/object.utils';
|
|
12
|
+
import { MaterialUtils } from '../utils/material.utils';
|
|
13
|
+
import { DeviceUtils } from '../utils/device.utils';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "./camera.service";
|
|
16
|
+
import * as i2 from "./settings.service";
|
|
17
|
+
import * as i3 from "./configurator-connector.service";
|
|
18
|
+
export class ArService {
|
|
19
|
+
constructor(_cameraService, _settingsService, _iOne) {
|
|
20
|
+
this._cameraService = _cameraService;
|
|
21
|
+
this._settingsService = _settingsService;
|
|
22
|
+
this._iOne = _iOne;
|
|
23
|
+
this.updateContextMenu = new BehaviorSubject(null);
|
|
24
|
+
this.shouldAddObjectToScene = new Subject();
|
|
25
|
+
this.showConfigurator = false;
|
|
26
|
+
this.userInSelectionMenu = false;
|
|
27
|
+
this.showContextMenu = false;
|
|
28
|
+
this._arFeatures = [];
|
|
29
|
+
this._debug = false;
|
|
30
|
+
this._surfaceFoundOnce = false;
|
|
31
|
+
this._aRModelRotationStartingValue = 0;
|
|
32
|
+
this._vertexList = [];
|
|
33
|
+
this._detectedPlanes = [];
|
|
34
|
+
this._rawPlanes = new Set();
|
|
35
|
+
this._doubleTapTimeframe = 500;
|
|
36
|
+
this._holdingTouch = false;
|
|
37
|
+
this._cleanup = true;
|
|
38
|
+
this._animating = false;
|
|
39
|
+
this._pointRepresentation = new Mesh(new SphereGeometry(0.02, 12, 12), new MeshBasicMaterial({
|
|
40
|
+
color: 0x4ccaed,
|
|
41
|
+
transparent: true,
|
|
42
|
+
opacity: 0.2
|
|
43
|
+
}));
|
|
44
|
+
window.onbeforeunload = () => this.ngOnDestroy();
|
|
45
|
+
}
|
|
46
|
+
ngOnDestroy() {
|
|
47
|
+
ObjectUtils.DisposeObject(this._reticle);
|
|
48
|
+
ObjectUtils.DisposeObject(this._sunLight);
|
|
49
|
+
ObjectUtils.DisposeObject(this._pointRepresentation);
|
|
50
|
+
}
|
|
51
|
+
resetPlaneDetection() {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
this._reticle.visible = false;
|
|
54
|
+
this._activeARModel.visible = false;
|
|
55
|
+
this._vertexList = [];
|
|
56
|
+
this._detectedPlanes.forEach((plane) => this.scene.remove(plane));
|
|
57
|
+
this._detectedPlanes = [];
|
|
58
|
+
this.scene.remove(this._positionIndicator);
|
|
59
|
+
this._rawPlanes = new Set();
|
|
60
|
+
this._cleanup = false;
|
|
61
|
+
yield this._session.end();
|
|
62
|
+
this._cleanup = true;
|
|
63
|
+
this._session = null;
|
|
64
|
+
this._initSession();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
endSessionEvent() {
|
|
68
|
+
this._session.end();
|
|
69
|
+
}
|
|
70
|
+
arIOSSupported() {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const a = document.createElement('a');
|
|
73
|
+
// relList.supports('ar') exists on Safari that supports Quick Look
|
|
74
|
+
return !!(a.relList && a.relList.supports && a.relList.supports('ar'));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
arSupported() {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
if (navigator.xr) {
|
|
80
|
+
return yield navigator.xr.isSessionSupported('immersive-ar');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
addObjectToARScene(object) {
|
|
88
|
+
this._activeARModel = object;
|
|
89
|
+
this._activeARModel.visible = false;
|
|
90
|
+
this._activeARModel.castShadow = true;
|
|
91
|
+
this._activeARModel.receiveShadow = true;
|
|
92
|
+
this._positionIndicator = new ArPositionIndicator(new Box3().setFromObject(object));
|
|
93
|
+
this.scene.add(this._activeARModel, this._positionIndicator);
|
|
94
|
+
}
|
|
95
|
+
modelLoading() {
|
|
96
|
+
return !this._activeARModel;
|
|
97
|
+
}
|
|
98
|
+
modelPlaced() {
|
|
99
|
+
return this._activeARModel && this._activeARModel.visible && !this._holdingTouch;
|
|
100
|
+
}
|
|
101
|
+
handleFrame(xrFrame) {
|
|
102
|
+
if (this._session && this._activeARModel) {
|
|
103
|
+
// TODO FIX
|
|
104
|
+
// this._iOne.shouldShowLoader = false;
|
|
105
|
+
this._checkAvailableFeatures(xrFrame);
|
|
106
|
+
this._checkHitTestMethod(xrFrame);
|
|
107
|
+
this._checkExtraFeatures(xrFrame);
|
|
108
|
+
this._handleHoldMoveEvent();
|
|
109
|
+
this._handleMultiTouchEvent();
|
|
110
|
+
if (this._activeARModel.visible) {
|
|
111
|
+
this.updateContextMenu.next();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
TWEEN.update();
|
|
115
|
+
this._renderer.render(this.scene, this._cameraService.camera);
|
|
116
|
+
}
|
|
117
|
+
init(renderer) {
|
|
118
|
+
// TODO FIX
|
|
119
|
+
// this._iOne.shouldShowLoader = true;
|
|
120
|
+
if (!this._renderer) {
|
|
121
|
+
this._renderer = renderer;
|
|
122
|
+
this._renderer.outputColorSpace = SRGBColorSpace;
|
|
123
|
+
this._initScene();
|
|
124
|
+
this._initLighting();
|
|
125
|
+
this._initController();
|
|
126
|
+
this._reticle = new Reticle();
|
|
127
|
+
this.scene.add(this._reticle);
|
|
128
|
+
}
|
|
129
|
+
this._initRenderer();
|
|
130
|
+
this._initSession();
|
|
131
|
+
}
|
|
132
|
+
savePreSelectionPosition() {
|
|
133
|
+
this._aRModelBackupPosition = this._activeARModel.position.clone();
|
|
134
|
+
}
|
|
135
|
+
updateChangedModel() {
|
|
136
|
+
if (this._aRModelBackupPosition) {
|
|
137
|
+
this._activeARModel.position.set(this._aRModelBackupPosition.x, this._aRModelBackupPosition.y, this._aRModelBackupPosition.z);
|
|
138
|
+
}
|
|
139
|
+
if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) {
|
|
140
|
+
this._updateMeshMaterials();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
arModeHasBeenActive() {
|
|
144
|
+
return this.scene !== undefined;
|
|
145
|
+
}
|
|
146
|
+
showMovePhoneAnimation() {
|
|
147
|
+
return this._activeARModel && !this._reticle.visible && !this._surfaceFoundOnce;
|
|
148
|
+
}
|
|
149
|
+
getActiveModel() {
|
|
150
|
+
return this._activeARModel;
|
|
151
|
+
}
|
|
152
|
+
_initSession() {
|
|
153
|
+
if (!this._session) {
|
|
154
|
+
// 'depth-sensing'
|
|
155
|
+
const features = {
|
|
156
|
+
requiredFeatures: ['local-floor', 'hit-test'],
|
|
157
|
+
optionalFeatures: ['light-estimation', 'plane-detection', 'anchors', 'dom-overlay'],
|
|
158
|
+
domOverlay: { root: document.getElementById('ar-root') },
|
|
159
|
+
depthSensing: {
|
|
160
|
+
usagePreference: ['cpu-optimized'],
|
|
161
|
+
dataFormatPreference: ['luminance-alpha']
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
navigator.xr.requestSession('immersive-ar', features).then((session) => {
|
|
165
|
+
this._renderer.xr.setReferenceSpaceType('local');
|
|
166
|
+
session.requestReferenceSpace('viewer').then((refSpace) => {
|
|
167
|
+
session.requestHitTestSource({ space: refSpace }).then((hitTestSource) => {
|
|
168
|
+
this.hitTestSource = hitTestSource;
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
session.requestReferenceSpace('local').then((refSpace) => {
|
|
172
|
+
this.refSpace = refSpace;
|
|
173
|
+
this._onSessionStarted(session);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
_checkAvailableFeatures(xrFrame) {
|
|
179
|
+
if (this._settingsService.settings.arParameters.depthOcclusion && this._settingsService.settings.arParameters.depthHitTest &&
|
|
180
|
+
!(this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) && this._session.depthUsage) {
|
|
181
|
+
this._arFeatures.push(ArFeature.CPUDepthOcclusion, ArFeature.CPUDepthHitTest);
|
|
182
|
+
this._initCPUDepthOcclusion();
|
|
183
|
+
}
|
|
184
|
+
if (this._settingsService.settings.arParameters.anchoredHitTest &&
|
|
185
|
+
!(this._arFeatures.includes(ArFeature.AnchoredHitTest)) && xrFrame.trackedAnchors) {
|
|
186
|
+
this._arFeatures.push(ArFeature.AnchoredHitTest);
|
|
187
|
+
this._initAnchoredHitTest();
|
|
188
|
+
}
|
|
189
|
+
if (this._settingsService.settings.arParameters.lightEstimation &&
|
|
190
|
+
!(this._arFeatures.includes(ArFeature.LightEstimation))) {
|
|
191
|
+
this._session.requestLightProbe().then((lightProbe) => {
|
|
192
|
+
if (lightProbe) {
|
|
193
|
+
this._arFeatures.push(ArFeature.LightEstimation);
|
|
194
|
+
this._initLightEstimation(lightProbe);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (this._settingsService.settings.arParameters.reflectionEstimation &&
|
|
199
|
+
!(this._arFeatures.includes(ArFeature.ReflectionCubeMap)) && this._lightProbe
|
|
200
|
+
&& this._glBinding.getReflectionCubeMap(this._lightProbe)) {
|
|
201
|
+
this._arFeatures.push(ArFeature.ReflectionCubeMap);
|
|
202
|
+
this._initReflectionCubeMap();
|
|
203
|
+
}
|
|
204
|
+
if (this._settingsService.settings.arParameters.planeDetection && this._settingsService.settings.arParameters.planeHitTest &&
|
|
205
|
+
!(this._arFeatures.includes(ArFeature.PlaneDetection)) && xrFrame.worldInformation) {
|
|
206
|
+
this._arFeatures.push(ArFeature.PlaneDetection, ArFeature.PlaneDetectionHitTest);
|
|
207
|
+
this._initPlaneDetection();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
_initRenderer() {
|
|
211
|
+
this._renderer.xr.enabled = true;
|
|
212
|
+
this._renderer.shadowMap.type = PCFSoftShadowMap;
|
|
213
|
+
this._renderer.setClearColor(0x000000, 0);
|
|
214
|
+
this._renderer.autoClear = false;
|
|
215
|
+
}
|
|
216
|
+
_initController() {
|
|
217
|
+
this._tempMatrix = new Matrix4();
|
|
218
|
+
this._raycaster = new Raycaster();
|
|
219
|
+
this._controller = this._renderer.xr.getController(0);
|
|
220
|
+
this.scene.add(this._controller);
|
|
221
|
+
}
|
|
222
|
+
_initScene() {
|
|
223
|
+
this.scene = new Scene();
|
|
224
|
+
const planeGeometry = new PlaneGeometry(100, 100);
|
|
225
|
+
const material = new ShadowMaterial({ opacity: 0.2 });
|
|
226
|
+
this._shadowPlane = new Mesh(planeGeometry, material);
|
|
227
|
+
this._shadowPlane.name = 'shadowPlane';
|
|
228
|
+
this._shadowPlane.rotation.x -= Math.PI / 2;
|
|
229
|
+
this._shadowPlane.receiveShadow = true;
|
|
230
|
+
this._shadowPlane.visible = false;
|
|
231
|
+
this.scene.add(this._shadowPlane);
|
|
232
|
+
}
|
|
233
|
+
_initLightEstimation(lightProbe) {
|
|
234
|
+
this._threeLightProbe = new LightProbe();
|
|
235
|
+
this.scene.add(this._threeLightProbe);
|
|
236
|
+
this._lightProbe = lightProbe;
|
|
237
|
+
// @ts-ignore
|
|
238
|
+
this._glBinding = new XRWebGLBinding(this._session, this._renderer.getContext());
|
|
239
|
+
}
|
|
240
|
+
_initReflectionCubeMap() {
|
|
241
|
+
this._cubeMapTexture = new Texture();
|
|
242
|
+
this._renderer.initTexture(this._cubeMapTexture);
|
|
243
|
+
this.scene.environment = this._cubeMapTexture;
|
|
244
|
+
this._lightProbe.addEventListener('reflectionchange', () => {
|
|
245
|
+
const rawData = this._glBinding.getReflectionCubeMap(this._lightProbe);
|
|
246
|
+
const texProps = this._renderer.properties.get(this._cubeMapTexture);
|
|
247
|
+
// @ts-ignore
|
|
248
|
+
texProps.__webglTexture = rawData;
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
_initCPUDepthOcclusion() {
|
|
252
|
+
this._depthDataTexture = new DepthDataTexture();
|
|
253
|
+
this._updateMeshMaterials();
|
|
254
|
+
}
|
|
255
|
+
_initAnchoredHitTest() {
|
|
256
|
+
this._anchoredObjects = [];
|
|
257
|
+
}
|
|
258
|
+
_initPlaneDetection() {
|
|
259
|
+
this._createPlaneMaterial();
|
|
260
|
+
}
|
|
261
|
+
_initLighting() {
|
|
262
|
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
|
|
263
|
+
ambientLight.color.setHex(0xffffff).convertSRGBToLinear();
|
|
264
|
+
ambientLight.name = 'ambientLight';
|
|
265
|
+
this._sunLight = new DirectionalLight('black', 0.3);
|
|
266
|
+
this._sunLight.castShadow = true;
|
|
267
|
+
this._sunLight.shadow.mapSize.width = 4096;
|
|
268
|
+
this._sunLight.shadow.mapSize.height = 4096;
|
|
269
|
+
this._sunLight.shadow.camera.left = -10;
|
|
270
|
+
this._sunLight.shadow.camera.right = 10;
|
|
271
|
+
this._sunLight.shadow.camera.top = 10;
|
|
272
|
+
this._sunLight.shadow.camera.bottom = -10;
|
|
273
|
+
this._sunLight.shadow.camera.near = 0.1;
|
|
274
|
+
this._sunLight.shadow.camera.far = 30;
|
|
275
|
+
this._sunLight.visible = true;
|
|
276
|
+
this._sunLight.target.visible = true;
|
|
277
|
+
this._sunLight.name = 'sunLight';
|
|
278
|
+
this.scene.add(/*ambientLight, */ this._sunLight.target, this._sunLight);
|
|
279
|
+
}
|
|
280
|
+
_checkHitTestMethod(xrFrame) {
|
|
281
|
+
if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion) && this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
|
|
282
|
+
this._executeDepthAnchorHitTest(xrFrame);
|
|
283
|
+
}
|
|
284
|
+
else if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
|
|
285
|
+
this._executeAnchoredHitTest(xrFrame);
|
|
286
|
+
}
|
|
287
|
+
else if (this._arFeatures.includes(ArFeature.CPUDepthHitTest)) {
|
|
288
|
+
this._executeCPUDepthHitTest(xrFrame);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
this._executeDefaultHitTest(xrFrame);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
_executeDepthAnchorHitTest(xrFrame) {
|
|
295
|
+
const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
|
|
296
|
+
const xrCamera = this._renderer.xr.getCamera( /*this._cameraService.camera*/); // todo: due to threejs update parameter not needed anymore, check this!
|
|
297
|
+
this._reticle.visible = false;
|
|
298
|
+
if (this.hitTestSource && xrViewerPose) {
|
|
299
|
+
const hitTestResults = xrFrame.getHitTestResults(this.hitTestSource);
|
|
300
|
+
if (hitTestResults.length === 0) {
|
|
301
|
+
if (xrViewerPose.views.length > 0 && xrCamera) {
|
|
302
|
+
for (const view of xrViewerPose.views) {
|
|
303
|
+
if (!this._activeARModel.visible) {
|
|
304
|
+
const depthData = xrFrame.getDepthInformation(view);
|
|
305
|
+
// Place object as soon as depth data is available and distance is within reasonable values
|
|
306
|
+
if (depthData && depthData.getDepthInMeters(0.5, 0.5) > 0.1 && depthData.getDepthInMeters(0.5, 0.5) < 2.5) {
|
|
307
|
+
this._activeARModel.position.set(xrCamera.position.x, xrCamera.position.y, xrCamera.position.z);
|
|
308
|
+
this._activeARModel.rotation.setFromQuaternion(xrCamera.quaternion);
|
|
309
|
+
this._activeARModel.translateZ(-depthData.getDepthInMeters(0.5, 0.5));
|
|
310
|
+
this._activeARModel.position.y += 0.02;
|
|
311
|
+
this._activeARModel.rotation.set(0, 0, 0);
|
|
312
|
+
this._activeARModel.visible = true;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// When hit test results are available we switch to the anchored hit test method and place the model accordingly
|
|
320
|
+
this._executeAnchoredHitTest(xrFrame);
|
|
321
|
+
if (this._anchoredObjects.length === 0) {
|
|
322
|
+
this._handleTouchEvent(false);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
_executeAnchoredHitTest(xrFrame) {
|
|
328
|
+
this._executeDefaultHitTest(xrFrame);
|
|
329
|
+
for (const { anchoredObject, anchor } of this._anchoredObjects) {
|
|
330
|
+
if (!xrFrame.trackedAnchors.has(anchor)) {
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const anchorPose = xrFrame.getPose(anchor.anchorSpace, this.refSpace);
|
|
334
|
+
if (anchorPose) {
|
|
335
|
+
const hitMatrix = new Matrix4().fromArray(anchorPose.transform.matrix);
|
|
336
|
+
anchoredObject.position.setFromMatrixPosition(hitMatrix);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
_executeCPUDepthHitTest(xrFrame) {
|
|
341
|
+
const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
|
|
342
|
+
const xrCamera = this._renderer.xr.getCamera( /*this._cameraService.camera*/); // todo: due to threejs update parameter not needed anymore, check this!
|
|
343
|
+
this._reticle.visible = false;
|
|
344
|
+
if (xrViewerPose && xrViewerPose.views.length > 0 && xrCamera) {
|
|
345
|
+
for (const view of xrViewerPose.views) {
|
|
346
|
+
if (!this._activeARModel.visible) {
|
|
347
|
+
this._reticle.visible = true;
|
|
348
|
+
this._surfaceFoundOnce = true;
|
|
349
|
+
}
|
|
350
|
+
const depthData = xrFrame.getDepthInformation(view);
|
|
351
|
+
if (depthData) {
|
|
352
|
+
this._reticle.position.set(xrCamera.position.x, xrCamera.position.y, xrCamera.position.z);
|
|
353
|
+
this._reticle.rotation.setFromQuaternion(xrCamera.quaternion);
|
|
354
|
+
this._reticle.translateZ(-depthData.getDepthInMeters(0.5, 0.5));
|
|
355
|
+
this._reticle.position.y += 0.02;
|
|
356
|
+
this._reticle.rotation.set(0, 0, 0);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
_executeDefaultHitTest(xrFrame) {
|
|
362
|
+
const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
|
|
363
|
+
this._reticle.visible = false;
|
|
364
|
+
if (this.hitTestSource && xrViewerPose) {
|
|
365
|
+
const hitTestResults = xrFrame.getHitTestResults(this.hitTestSource);
|
|
366
|
+
if (hitTestResults.length > 0) {
|
|
367
|
+
const pose = hitTestResults[0].getPose(this.refSpace);
|
|
368
|
+
if (!this._activeARModel.visible) {
|
|
369
|
+
this._reticle.visible = true;
|
|
370
|
+
this._surfaceFoundOnce = true;
|
|
371
|
+
}
|
|
372
|
+
const hitMatrix = new Matrix4().fromArray(pose.transform.matrix);
|
|
373
|
+
this._hitTestResult = hitMatrix;
|
|
374
|
+
this._reticle.position.setFromMatrixPosition(hitMatrix);
|
|
375
|
+
this._reticle.position.y += 0.02; // Prevents z-fighting
|
|
376
|
+
this._reticleHitTestResult = hitTestResults[0];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
_checkExtraFeatures(xrFrame) {
|
|
381
|
+
if (this._arFeatures.includes(ArFeature.LightEstimation)) {
|
|
382
|
+
this._adjustLighting(xrFrame);
|
|
383
|
+
}
|
|
384
|
+
if (this._arFeatures.includes(ArFeature.CPUDepthOcclusion)) {
|
|
385
|
+
this._hideOccludedMeshes(xrFrame);
|
|
386
|
+
}
|
|
387
|
+
// if (this._arFeatures.includes(ArFeature.PlaneDetection)) {
|
|
388
|
+
// this._drawPlanes(xrFrame);
|
|
389
|
+
// }
|
|
390
|
+
}
|
|
391
|
+
_hideOccludedMeshes(xrFrame) {
|
|
392
|
+
const xrViewerPose = xrFrame.getViewerPose(this.refSpace);
|
|
393
|
+
if (xrViewerPose && xrViewerPose.views.length > 0) {
|
|
394
|
+
for (const view of xrViewerPose.views) {
|
|
395
|
+
const depthData = xrFrame.getDepthInformation(view);
|
|
396
|
+
if (depthData) {
|
|
397
|
+
this._depthDataTexture.updateDepth(depthData);
|
|
398
|
+
this._updateAugmentedMaterialUniforms(depthData.normDepthBufferFromNormView.matrix);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
_createPlaneMaterial() {
|
|
404
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
405
|
+
const pm = new MeshPhongMaterial({ transparent: true, side: DoubleSide });
|
|
406
|
+
pm.map = yield MaterialUtils.FromUrl('assets/textures/Floor/Tiles/ar_floor_texture.png', false, 1, 2, 2);
|
|
407
|
+
pm.map.flipY = false;
|
|
408
|
+
pm.needsUpdate = true;
|
|
409
|
+
this._planeMaterial = pm;
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
_onSessionStarted(session) {
|
|
413
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
414
|
+
const domOverlay = document.getElementById('ar-root');
|
|
415
|
+
session.addEventListener('end', this._onSessionEnded.bind(this));
|
|
416
|
+
session.addEventListener('select', () => this._handleTouchEvent());
|
|
417
|
+
session.addEventListener('selectstart', ($event) => this._handleHoldStartEvent($event));
|
|
418
|
+
session.addEventListener('selectend', ($event) => this._handleHoldEndEvent($event));
|
|
419
|
+
domOverlay.addEventListener('beforexrselect', ($event) => this._checkingInterfaceInteraction($event));
|
|
420
|
+
yield this._renderer.getContext().makeXRCompatible();
|
|
421
|
+
this._renderer.xr.setSession(session);
|
|
422
|
+
this._session = session;
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
_onSessionEnded() {
|
|
426
|
+
if (this._cleanup) {
|
|
427
|
+
this._session = null;
|
|
428
|
+
this._surfaceFoundOnce = false;
|
|
429
|
+
this._reticle.visible = false;
|
|
430
|
+
this.scene.remove(this._positionIndicator);
|
|
431
|
+
this._activeARModel.visible = true;
|
|
432
|
+
this._activeARModel.position.set(0, 0, 0);
|
|
433
|
+
this._removeMaterialShaders();
|
|
434
|
+
this.shouldAddObjectToScene.next(this._activeARModel);
|
|
435
|
+
this._activeARModel = null;
|
|
436
|
+
this._holdingTouch = false;
|
|
437
|
+
this._arFeatures = [];
|
|
438
|
+
this._lightProbe = null;
|
|
439
|
+
this._vertexList = [];
|
|
440
|
+
this._detectedPlanes = [];
|
|
441
|
+
this._rawPlanes = new Set();
|
|
442
|
+
this._renderer.xr.enabled = false;
|
|
443
|
+
this._renderer.shadowMap.type = PCFSoftShadowMap;
|
|
444
|
+
this._renderer.setClearColor(0xfafafa);
|
|
445
|
+
this._renderer.autoClear = true;
|
|
446
|
+
// TODO FIX
|
|
447
|
+
// this._viewModeService.viewMode = ViewMode.RoomPlan3D;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
_setArModelShadows() {
|
|
451
|
+
if (this._activeARModel) {
|
|
452
|
+
this._activeARModel.traverse((node) => {
|
|
453
|
+
if (node instanceof Mesh) {
|
|
454
|
+
node.castShadow = true;
|
|
455
|
+
node.receiveShadow = true;
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
_handleTouchEvent(manualTouch = true) {
|
|
461
|
+
this._handleDoubleTapEvent();
|
|
462
|
+
if (manualTouch) {
|
|
463
|
+
if (this._reticle.visible && !this._activeARModel.visible) {
|
|
464
|
+
if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
|
|
465
|
+
this._activeARModel.position.copy(this._reticle.position);
|
|
466
|
+
this._reticleHitTestResult.createAnchor().then((anchor) => {
|
|
467
|
+
this._anchoredObjects.push({
|
|
468
|
+
anchoredObject: this._shadowPlane,
|
|
469
|
+
anchor: anchor
|
|
470
|
+
});
|
|
471
|
+
}).catch((e) => {
|
|
472
|
+
// Unable to create anchor
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
this._activeARModel.position.copy(this._reticle.position);
|
|
477
|
+
this._aRModelBackupYPosition = this._reticle.position.y;
|
|
478
|
+
this._shadowPlane.position.copy(this._reticle.position);
|
|
479
|
+
this._positionIndicator.position.copy(this._reticle.position);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
if (this._arFeatures.includes(ArFeature.AnchoredHitTest)) {
|
|
485
|
+
this._activeARModel.position.copy(this._reticle.position);
|
|
486
|
+
this._reticleHitTestResult.createAnchor().then((anchor) => {
|
|
487
|
+
this._anchoredObjects.push({
|
|
488
|
+
anchoredObject: this._shadowPlane,
|
|
489
|
+
anchor: anchor
|
|
490
|
+
});
|
|
491
|
+
}).catch((e) => {
|
|
492
|
+
// Unable to create anchor
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
else {
|
|
496
|
+
this._activeARModel.position.copy(this._reticle.position);
|
|
497
|
+
this._aRModelBackupYPosition = this._reticle.position.y;
|
|
498
|
+
this._shadowPlane.position.copy(this._reticle.position);
|
|
499
|
+
this._positionIndicator.position.copy(this._reticle.position);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
this._activeARModel.visible = true;
|
|
503
|
+
this._shadowPlane.visible = true;
|
|
504
|
+
this._positionIndicator.visible = true;
|
|
505
|
+
this._setArModelShadows();
|
|
506
|
+
this._setPlanesVisibilty(false);
|
|
507
|
+
}
|
|
508
|
+
_handleMultiTouchEvent() {
|
|
509
|
+
const inputSources = this._session.inputSources;
|
|
510
|
+
if (inputSources.length === 2 && this._activeARModel.visible && !this._holdingTouch) {
|
|
511
|
+
this._aRModelBackupYRotation = this._aRModelBackupYRotation === 0 ? this._activeARModel.rotation.y / 2 : this._aRModelBackupYRotation;
|
|
512
|
+
const dx = inputSources[1].gamepad.axes[0] - inputSources[0].gamepad.axes[0];
|
|
513
|
+
const dy = inputSources[1].gamepad.axes[1] - inputSources[0].gamepad.axes[1];
|
|
514
|
+
const angle = Math.atan2(dy, dx);
|
|
515
|
+
this._aRModelRotationStartingValue = this._aRModelRotationStartingValue === 0 ? angle : this._aRModelRotationStartingValue;
|
|
516
|
+
const difference = this._aRModelBackupYRotation - (angle - this._aRModelRotationStartingValue);
|
|
517
|
+
this._activeARModel.rotation.y = this._aRModelBackupYRotation + difference;
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
this._aRModelBackupYRotation = 0;
|
|
521
|
+
this._aRModelRotationStartingValue = 0;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
_handleDoubleTapEvent() {
|
|
525
|
+
const intersections = this._getObjectIntersections([this._activeARModel]);
|
|
526
|
+
if (intersections.length > 0) {
|
|
527
|
+
const currentTimestamp = Date.now();
|
|
528
|
+
this.showContextMenu = this._lastObjectTouchTimestamp && currentTimestamp - this._lastObjectTouchTimestamp < this._doubleTapTimeframe;
|
|
529
|
+
this._lastObjectTouchTimestamp = currentTimestamp;
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
this.showContextMenu = false;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
_checkIfHoldTouchEvent($event) {
|
|
536
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
537
|
+
setTimeout(() => {
|
|
538
|
+
if (!this.userInSelectionMenu && this._lastEventTimestamp === $event.timeStamp && this._session.inputSources.length === 1) {
|
|
539
|
+
this._holdingTouch = true;
|
|
540
|
+
this._toggleHoldTouchEvent();
|
|
541
|
+
}
|
|
542
|
+
}, 200);
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
_handleHoldStartEvent($event) {
|
|
546
|
+
this._lastEventTimestamp = $event.timeStamp;
|
|
547
|
+
this._checkIfHoldTouchEvent($event);
|
|
548
|
+
}
|
|
549
|
+
_handleHoldEndEvent($event) {
|
|
550
|
+
this._lastEventTimestamp = $event.timeStamp;
|
|
551
|
+
if (this._holdingTouch) {
|
|
552
|
+
this._holdingTouch = false;
|
|
553
|
+
this._toggleHoldTouchEvent();
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
_toggleHoldTouchEvent() {
|
|
557
|
+
if (this._holdingTouch) {
|
|
558
|
+
// this._setPlanesVisibilty(true);
|
|
559
|
+
this._callLiftAnimation();
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
this._callDropAnimation();
|
|
563
|
+
this._setPlanesVisibilty(false);
|
|
564
|
+
this._activeARModel.position.y = this._aRModelBackupYPosition;
|
|
565
|
+
}
|
|
566
|
+
this._toggleARModelTransparency();
|
|
567
|
+
}
|
|
568
|
+
_handleHoldMoveEvent() {
|
|
569
|
+
if (this._holdingTouch && !this.userInSelectionMenu) {
|
|
570
|
+
const intersections = this._getObjectIntersections([this._shadowPlane]);
|
|
571
|
+
if (intersections.length > 0) {
|
|
572
|
+
const movePosition = !this._animating ? new Vector3(intersections[0].point.x, intersections[0].point.y + 0.2, intersections[0].point.z) :
|
|
573
|
+
new Vector3(intersections[0].point.x, this._activeARModel.position.y, intersections[0].point.z);
|
|
574
|
+
this._activeARModel.position.copy(movePosition);
|
|
575
|
+
this._aRModelBackupYPosition = intersections[0].point.y;
|
|
576
|
+
this._positionIndicator.position.copy(intersections[0].point);
|
|
577
|
+
this._updateShadows(intersections[0].point);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
_updateShadows(centerPosition) {
|
|
582
|
+
this._shadowPlane.position.copy(centerPosition);
|
|
583
|
+
this.scene.traverse((node) => {
|
|
584
|
+
if (node instanceof DirectionalLight) {
|
|
585
|
+
node.target.position.copy(centerPosition);
|
|
586
|
+
node.shadow.camera.updateProjectionMatrix();
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
_adjustLighting(frame) {
|
|
591
|
+
const lightEstimate = frame.getLightEstimate(this._lightProbe);
|
|
592
|
+
if (lightEstimate) {
|
|
593
|
+
this._threeLightProbe.sh.fromArray(lightEstimate.sphericalHarmonicsCoefficients);
|
|
594
|
+
const intensity = Math.max(1.0, Math.max(lightEstimate.primaryLightIntensity.x, Math.max(lightEstimate.primaryLightIntensity.y, lightEstimate.primaryLightIntensity.z)));
|
|
595
|
+
this._sunLight.position.set(lightEstimate.primaryLightDirection.x, lightEstimate.primaryLightDirection.y, lightEstimate.primaryLightDirection.z);
|
|
596
|
+
this._sunLight.color.setRGB(lightEstimate.primaryLightIntensity.x / intensity, lightEstimate.primaryLightIntensity.y / intensity, lightEstimate.primaryLightIntensity.z / intensity);
|
|
597
|
+
this._sunLight.intensity = intensity;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
_toggleARModelTransparency() {
|
|
601
|
+
this._activeARModel.traverse((node) => {
|
|
602
|
+
if (node instanceof Mesh) {
|
|
603
|
+
const materials = !Array.isArray(node.material) ? [node.material] : node.material;
|
|
604
|
+
materials.forEach(material => {
|
|
605
|
+
material.transparent = this._holdingTouch;
|
|
606
|
+
material.opacity = this._holdingTouch ? 0.5 : 1;
|
|
607
|
+
material.needsUpdate = true;
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
_setPlanesVisibilty(visible) {
|
|
613
|
+
this._detectedPlanes.forEach((plane) => plane.visible = visible);
|
|
614
|
+
}
|
|
615
|
+
_getObjectIntersections(objects) {
|
|
616
|
+
this._tempMatrix.identity().extractRotation(this._controller.matrixWorld);
|
|
617
|
+
this._raycaster.ray.origin.setFromMatrixPosition(this._controller.matrixWorld);
|
|
618
|
+
this._raycaster.ray.direction.set(0, 0, -1).applyMatrix4(this._tempMatrix);
|
|
619
|
+
return this._raycaster.intersectObjects(objects);
|
|
620
|
+
}
|
|
621
|
+
// TODO: Needs to be made compatible with BufferGeometry if we want to keep plane detection visualization
|
|
622
|
+
_drawPlane(vertices, planePose) {
|
|
623
|
+
// const hitMatrix = new Matrix4().fromArray(planePose.transform.matrix);
|
|
624
|
+
// const pointGroup = new Group();
|
|
625
|
+
//
|
|
626
|
+
// // Create vertices
|
|
627
|
+
// vertices.forEach((vertex) => {
|
|
628
|
+
// if (this._debug) {
|
|
629
|
+
// const point = this._pointRepresentation.clone();
|
|
630
|
+
// point.position.set(vertex.x, 0, vertex.z);
|
|
631
|
+
// pointGroup.add(point);
|
|
632
|
+
// }
|
|
633
|
+
// this._vertexList.push(new DOMPoint(vertex.x, vertex.z));
|
|
634
|
+
// });
|
|
635
|
+
//
|
|
636
|
+
// if (this._debug) {
|
|
637
|
+
// pointGroup.position.setFromMatrixPosition(hitMatrix);
|
|
638
|
+
// this.scene.add(pointGroup);
|
|
639
|
+
// }
|
|
640
|
+
//
|
|
641
|
+
// // Generate polygon from vertices
|
|
642
|
+
// const hull = makeHull(this._vertexList);
|
|
643
|
+
// const geometry = new BufferGeometry();
|
|
644
|
+
// const vectorTwoList = hull.map((point) => new Vector2(point.x, point.y));
|
|
645
|
+
// const vectorThreeList = hull.map((point) => new Vector3(point.x, this._detectedPlanes.length > 0 ? this._detectedPlanes[0].position.y : 0, point.y));
|
|
646
|
+
// const faceArray = ShapeUtils.triangulateShape(vectorTwoList, []);
|
|
647
|
+
// geometry.vertices.push(...vectorThreeList);
|
|
648
|
+
//
|
|
649
|
+
// // Generate faces
|
|
650
|
+
// for (let i = 0; i < faceArray.length; i++) {
|
|
651
|
+
// geometry.faces.push(new THREE.Face3(faceArray[i][0], faceArray[i][1], faceArray[i][2]));
|
|
652
|
+
// }
|
|
653
|
+
// geometry.computeVertexNormals();
|
|
654
|
+
// geometry.normalize();
|
|
655
|
+
//
|
|
656
|
+
// // Generate UV's
|
|
657
|
+
// geometry.computeBoundingBox();
|
|
658
|
+
// const max = geometry.boundingBox.max, min = geometry.boundingBox.min;
|
|
659
|
+
// const offset = new THREE.Vector2(0 - min.x, 0 - min.z);
|
|
660
|
+
// const range = new THREE.Vector2(max.x - min.x, max.z - min.z);
|
|
661
|
+
// const faces = geometry.faces;
|
|
662
|
+
// geometry.faceVertexUvs[0] = [];
|
|
663
|
+
//
|
|
664
|
+
// for (let i = 0; i < faces.length; i++) {
|
|
665
|
+
// const v1 = geometry.vertices[faces[i].a],
|
|
666
|
+
// v2 = geometry.vertices[faces[i].b],
|
|
667
|
+
// v3 = geometry.vertices[faces[i].c];
|
|
668
|
+
//
|
|
669
|
+
// geometry.faceVertexUvs[0].push([
|
|
670
|
+
// new THREE.Vector2((v1.x + offset.x) / range.x, (v1.z + offset.y) / range.y),
|
|
671
|
+
// new THREE.Vector2((v2.x + offset.x) / range.x, (v2.z + offset.y) / range.y),
|
|
672
|
+
// new THREE.Vector2((v3.x + offset.x) / range.x, (v3.z + offset.y) / range.y)
|
|
673
|
+
// ]);
|
|
674
|
+
// }
|
|
675
|
+
// geometry.uvsNeedUpdate = true;
|
|
676
|
+
//
|
|
677
|
+
// // Create and set plane
|
|
678
|
+
// const mesh = new Mesh(geometry, this._planeMaterial);
|
|
679
|
+
// mesh.position.setFromMatrixPosition(hitMatrix);
|
|
680
|
+
// this._detectedPlanes.push(mesh);
|
|
681
|
+
// this.scene.add(mesh);
|
|
682
|
+
}
|
|
683
|
+
_drawPlanes(xrFrame) {
|
|
684
|
+
if (!this._activeARModel.visible) {
|
|
685
|
+
const planesDetected = xrFrame.worldInformation.detectedPlanes;
|
|
686
|
+
if (planesDetected.size > 0) {
|
|
687
|
+
planesDetected.forEach(plane => {
|
|
688
|
+
if (!this._rawPlanes.has(plane)) {
|
|
689
|
+
const planePose = xrFrame.getPose(plane.planeSpace, this.refSpace);
|
|
690
|
+
if (planePose) {
|
|
691
|
+
this._rawPlanes.add(plane);
|
|
692
|
+
const planeVertices = plane.polygon;
|
|
693
|
+
this._drawPlane(planeVertices, planePose);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
_callLiftAnimation() {
|
|
701
|
+
this._animating = true;
|
|
702
|
+
const position = this._activeARModel.position.clone();
|
|
703
|
+
const targetPosition = new Vector3(this._activeARModel.position.x, this._activeARModel.position.y + 0.2, this._activeARModel.position.z);
|
|
704
|
+
this._liftAnimation = new TWEEN.Tween(position)
|
|
705
|
+
.to(targetPosition, 500)
|
|
706
|
+
.easing(TWEEN.Easing.Quadratic.Out)
|
|
707
|
+
.onUpdate(() => this._activeARModel.position.copy(new Vector3(this._activeARModel.position.x, position.y, this._activeARModel.position.z)))
|
|
708
|
+
.onComplete(() => this._animating = false);
|
|
709
|
+
this._liftAnimation.start();
|
|
710
|
+
}
|
|
711
|
+
_callDropAnimation() {
|
|
712
|
+
this._animating = true;
|
|
713
|
+
const position = this._activeARModel.position.clone();
|
|
714
|
+
const targetPosition = new Vector3(this._activeARModel.position.x, this._activeARModel.position.y - 0.2, this._activeARModel.position.z);
|
|
715
|
+
this._dropAnimation = new TWEEN.Tween(position)
|
|
716
|
+
.to(targetPosition, 500)
|
|
717
|
+
.easing(TWEEN.Easing.Quadratic.Out)
|
|
718
|
+
.onUpdate(() => this._activeARModel.position.copy(new Vector3(this._activeARModel.position.x, position.y, this._activeARModel.position.z)))
|
|
719
|
+
.onComplete(() => this._animating = false);
|
|
720
|
+
this._dropAnimation.start();
|
|
721
|
+
}
|
|
722
|
+
_createAugmentedMaterial(material, depthMap) {
|
|
723
|
+
material.userData = {
|
|
724
|
+
uDepthTexture: { value: depthMap },
|
|
725
|
+
uWidth: { value: 1.0 },
|
|
726
|
+
uHeight: { value: 1.0 },
|
|
727
|
+
uUvTransform: { value: new Matrix4() },
|
|
728
|
+
uOcclusionEnabled: { value: true }
|
|
729
|
+
};
|
|
730
|
+
material.userData.isAgumentedMaterial = true;
|
|
731
|
+
material.onBeforeCompile = (shader) => {
|
|
732
|
+
// Pass uniforms from userData to the
|
|
733
|
+
for (const i in material.userData) {
|
|
734
|
+
shader.uniforms[i] = material.userData[i];
|
|
735
|
+
}
|
|
736
|
+
// Fragment variables
|
|
737
|
+
shader.fragmentShader = `
|
|
738
|
+
uniform sampler2D uDepthTexture;
|
|
739
|
+
uniform float uWidth;
|
|
740
|
+
uniform float uHeight;
|
|
741
|
+
uniform mat4 uUvTransform;
|
|
742
|
+
uniform bool uOcclusionEnabled;
|
|
743
|
+
varying float vDepth;
|
|
744
|
+
` + shader.fragmentShader;
|
|
745
|
+
let fragmentEntryPoint = '#include <clipping_planes_fragment>';
|
|
746
|
+
if (material instanceof ShadowMaterial) {
|
|
747
|
+
fragmentEntryPoint = '#include <fog_fragment>';
|
|
748
|
+
}
|
|
749
|
+
// Fragment depth logic
|
|
750
|
+
shader.fragmentShader = shader.fragmentShader.replace('void main', `float getDepthInMillimeters(in sampler2D depthText, in vec2 uv)
|
|
751
|
+
{
|
|
752
|
+
vec2 packedDepth = texture2D(depthText, uv).ra;
|
|
753
|
+
return dot(packedDepth, vec2(255.0, 65280.0));
|
|
754
|
+
}
|
|
755
|
+
void main`);
|
|
756
|
+
shader.fragmentShader = shader.fragmentShader.replace(fragmentEntryPoint, `
|
|
757
|
+
${fragmentEntryPoint}
|
|
758
|
+
// Normalize x, y to range [0, 1]
|
|
759
|
+
float x = gl_FragCoord.x / uWidth;
|
|
760
|
+
float y = gl_FragCoord.y / uHeight;
|
|
761
|
+
vec2 texCoord = (uUvTransform * vec4(x, 1.0 - y, 0.0, 1.0)).xy;
|
|
762
|
+
float depth = getDepthInMillimeters(uDepthTexture, texCoord) / 1000.0;
|
|
763
|
+
if (depth < vDepth)
|
|
764
|
+
{
|
|
765
|
+
discard;
|
|
766
|
+
}
|
|
767
|
+
`);
|
|
768
|
+
// Vertex variables
|
|
769
|
+
shader.vertexShader = `
|
|
770
|
+
varying float vDepth;
|
|
771
|
+
` + shader.vertexShader;
|
|
772
|
+
// Vertex depth logic
|
|
773
|
+
shader.vertexShader = shader.vertexShader.replace('#include <fog_vertex>', `
|
|
774
|
+
#include <fog_vertex>
|
|
775
|
+
vDepth = gl_Position.z;
|
|
776
|
+
`);
|
|
777
|
+
};
|
|
778
|
+
return material;
|
|
779
|
+
}
|
|
780
|
+
_updateAugmentedMaterialUniforms(normTextureFromNormViewMatrix) {
|
|
781
|
+
this.scene.traverse((child) => {
|
|
782
|
+
if (child instanceof Mesh && child.material) {
|
|
783
|
+
if (child.material instanceof Array) {
|
|
784
|
+
for (const material of child.material) {
|
|
785
|
+
if (material.userData.isAgumentedMaterial) {
|
|
786
|
+
material.userData.uWidth.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerWidth);
|
|
787
|
+
material.userData.uHeight.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerHeight);
|
|
788
|
+
material.userData.uUvTransform.value.fromArray(normTextureFromNormViewMatrix);
|
|
789
|
+
material.needsUpdate = true;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
else if (child.userData.isAgumentedMaterial) {
|
|
794
|
+
child.material.userData.uWidth.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerWidth);
|
|
795
|
+
child.material.userData.uHeight.value = Math.floor(DeviceUtils.GetPixelRatio() * window.innerHeight);
|
|
796
|
+
child.material.userData.uUvTransform.value.fromArray(normTextureFromNormViewMatrix);
|
|
797
|
+
child.material.needsUpdate = true;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
_updateMeshMaterials() {
|
|
803
|
+
this.scene.traverse((object) => {
|
|
804
|
+
if (object instanceof Mesh) {
|
|
805
|
+
if (object.material instanceof Array) {
|
|
806
|
+
for (let material of object.material) {
|
|
807
|
+
material = this._createAugmentedMaterial(material, this._depthDataTexture);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
object.material = this._createAugmentedMaterial(object.material, this._depthDataTexture);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
_removeMaterialShaders() {
|
|
817
|
+
this.scene.traverse((object) => {
|
|
818
|
+
if (object instanceof Mesh) {
|
|
819
|
+
if (object.material instanceof Array) {
|
|
820
|
+
for (const material of object.material) {
|
|
821
|
+
material.onBeforeCompile = (shader) => {
|
|
822
|
+
shader = null;
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
object.material.onBeforeCompile = (shader) => {
|
|
828
|
+
shader = null;
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
_checkingInterfaceInteraction(event) {
|
|
835
|
+
this.userInSelectionMenu = event.path.filter((entry) => entry.localName === 'ar-gui-configurator').length > 0;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
ArService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, deps: [{ token: i1.CameraService }, { token: i2.SettingsService }, { token: i3.ConfiguratorConnectorService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
839
|
+
ArService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, providedIn: 'root' });
|
|
840
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: ArService, decorators: [{
|
|
841
|
+
type: Injectable,
|
|
842
|
+
args: [{ providedIn: 'root' }]
|
|
843
|
+
}], ctorParameters: function () { return [{ type: i1.CameraService }, { type: i2.SettingsService }, { type: i3.ConfiguratorConnectorService }]; } });
|
|
844
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbmZpZ3VyYXRvci9zcmMvbGliL3NlcnZpY2VzL2FyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQVksTUFBTSxlQUFlLENBQUM7QUFDcEQsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDL0IsT0FBTyxFQUNMLElBQUksRUFDSixnQkFBZ0IsRUFDaEIsVUFBVSxFQUVWLFVBQVUsRUFFVixPQUFPLEVBQ1AsSUFBSSxFQUNKLGlCQUFpQixFQUNqQixpQkFBaUIsRUFFakIsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFDYixTQUFTLEVBQ1QsS0FBSyxFQUNMLGNBQWMsRUFDZCxjQUFjLEVBRWQsY0FBYyxFQUNkLE9BQU8sRUFDUCxPQUFPLEVBRVIsTUFBTSxPQUFPLENBQUM7QUFDZixPQUFPLEtBQUssS0FBSyxNQUFNLG1CQUFtQixDQUFDO0FBQzNDLE9BQU8sRUFBQyxlQUFlLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUVsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDckUsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFHbkUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ2xELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUV0RCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7Ozs7O0FBUWxELE1BQU0sT0FBTyxTQUFTO0lBaUVwQixZQUNVLGNBQTZCLEVBQzdCLGdCQUFpQyxFQUNq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O0lBQ2hILENBQUM7O3VHQTE2QlUsU0FBUzsyR0FBVCxTQUFTLGNBREcsTUFBTTs0RkFDbEIsU0FBUztrQkFEckIsVUFBVTttQkFBQyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0luamVjdGFibGUsIE9uRGVzdHJveX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcclxuaW1wb3J0IHtcclxuICBCb3gzLFxyXG4gIERpcmVjdGlvbmFsTGlnaHQsXHJcbiAgRG91YmxlU2lkZSxcclxuICBJbnRlcnNlY3Rpb24sXHJcbiAgTGlnaHRQcm9iZSxcclxuICBNYXRlcmlhbCxcclxuICBNYXRyaXg0LFxyXG4gIE1lc2gsXHJcbiAgTWVzaEJhc2ljTWF0ZXJpYWwsXHJcbiAgTWVzaFBob25nTWF0ZXJpYWwsXHJcbiAgT2JqZWN0M0QsXHJcbiAgUENGU29mdFNoYWRvd01hcCxcclxuICBQbGFuZUdlb21ldHJ5LFxyXG4gIFJheWNhc3RlcixcclxuICBTY2VuZSxcclxuICBTaGFkb3dNYXRlcmlhbCxcclxuICBTcGhlcmVHZW9tZXRyeSxcclxuICBTcG90TGlnaHQsXHJcbiAgU1JHQkNvbG9yU3BhY2UsXHJcbiAgVGV4dHVyZSxcclxuICBWZWN0b3IzLFxyXG4gIFdlYkdMUmVuZGVyZXJcclxufSBmcm9tICd0aHJlZSc7XHJcbmltcG9ydCAqIGFzIFRXRUVOIGZyb20gJ0B0d2VlbmpzL3R3ZWVuLmpzJztcclxuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge0FyRmVhdHVyZX0gZnJvbSAnLi4vZW51bS9hci1mZWF0dXJlLmVudW0nO1xyXG5pbXBvcnQge0NhbWVyYVNlcnZpY2V9IGZyb20gJy4vY2FtZXJhLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBSZXRpY2xlIH0gZnJvbSAnLi4vbW9kZWwveHItcmV0aWNsZSc7XHJcbmltcG9ydCB7RGVwdGhEYXRhVGV4dHVyZX0gZnJvbSAnLi4vY29yZS90ZXh0dXJlcy9kZXB0aC1kYXRhLXRleHR1cmUnO1xyXG5pbXBvcnQge0FyUG9zaXRpb25JbmRpY2F0b3J9IGZyb20gJy4uL21vZGVsL2FyLXBvc2l0aW9uLWluZGljYXRvcic7XHJcbmltcG9ydCB7U2V0dGluZ3NTZXJ2aWNlfSBmcm9tICcuL3NldHRpbmdzLnNlcnZpY2UnO1xyXG5pbXBvcnQge0NvbmZpZ3VyYXRvckNvbm5lY3RvclNlcnZpY2V9IGZyb20gJy4vY29uZmlndXJhdG9yLWNvbm5lY3Rvci5zZXJ2aWNlJztcclxuaW1wb3J0IHtPYmplY3RVdGlsc30gZnJvbSAnLi4vdXRpbHMvb2JqZWN0LnV0aWxzJztcclxuaW1wb3J0IHtNYXRlcmlhbFV0aWxzfSBmcm9tICcuLi91dGlscy9tYXRlcmlhbC51dGlscyc7XHJcbmltcG9ydCB7Vmlld01vZGV9IGZyb20gJy4uL2VudW0vdmlldy1tb2RlLmVudW0nO1xyXG5pbXBvcnQge0RldmljZVV0aWxzfSBmcm9tICcuLi91dGlscy9kZXZpY2UudXRpbHMnO1xyXG5cclxuaW50ZXJmYWNlIFBvaW50IHtcclxuICB4OiBudW1iZXI7XHJcbiAgeTogbnVtYmVyO1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcclxuZXhwb3J0IGNsYXNzIEFyU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XHJcblxyXG4gIHB1YmxpYyB1cGRhdGVDb250ZXh0TWVudTogQmVoYXZpb3JTdWJqZWN0PHZvaWQ+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDx2b2lkPihudWxsKTtcclxuXHJcbiAgcHVibGljIHNob3VsZEFkZE9iamVjdFRvU2NlbmU6IFN1YmplY3Q8T2JqZWN0M0Q+ID0gbmV3IFN1YmplY3Q8T2JqZWN0M0Q+KCk7XHJcbiAgcHVibGljIHNob3dDb25maWd1cmF0b3I6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcHVibGljIHJlZlNwYWNlOiBhbnk7XHJcbiAgcHVibGljIGhpdFRlc3RTb3VyY2U6IGFueTtcclxuICBwdWJsaWMgc2NlbmU6IFNjZW5lO1xyXG4gIHB1YmxpYyB1c2VySW5TZWxlY3Rpb25NZW51OiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHVibGljIHNob3dDb250ZXh0TWVudTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwcml2YXRlIF9hckZlYXR1cmVzOiBBckZlYXR1cmVbXSA9IFtdO1xyXG4gIHByaXZhdGUgX3JlbmRlcmVyOiBXZWJHTFJlbmRlcmVyO1xyXG4gIHByaXZhdGUgX2dsQmluZGluZzogYW55O1xyXG4gIHByaXZhdGUgX3Nlc3Npb246IGFueTtcclxuICBwcml2YXRlIF9kZWJ1ZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHByaXZhdGUgX3N1cmZhY2VGb3VuZE9uY2UgPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBfcmV0aWNsZTogUmV0aWNsZTtcclxuICBwcml2YXRlIF9oaXRUZXN0UmVzdWx0OiBNYXRyaXg0O1xyXG4gIHByaXZhdGUgX3JldGljbGVIaXRUZXN0UmVzdWx0OiBhbnk7XHJcbiAgcHJpdmF0ZSBfYW5jaG9yZWRPYmplY3RzOiB7YW5jaG9yZWRPYmplY3Q6IE9iamVjdDNELCBhbmNob3I6IGFueX1bXTtcclxuICBwcml2YXRlIF9hY3RpdmVBUk1vZGVsOiBPYmplY3QzRDtcclxuICBwcml2YXRlIF9hUk1vZGVsQmFja3VwWVBvc2l0aW9uOiBudW1iZXI7XHJcbiAgcHJpdmF0ZSBfYVJNb2RlbEJhY2t1cFBvc2l0aW9uOiBWZWN0b3IzO1xyXG4gIHByaXZhdGUgX2FSTW9kZWxCYWNrdXBZUm90YXRpb246IG51bWJlcjtcclxuICBwcml2YXRlIF9hUk1vZGVsUm90YXRpb25TdGFydGluZ1ZhbHVlOiBudW1iZXIgPSAwO1xyXG4gIHByaXZhdGUgX3ZlcnRleExpc3Q6IEFycmF5PFBvaW50PiA9IFtdO1xyXG4gIHByaXZhdGUgX2RldGVjdGVkUGxhbmVzOiBNZXNoW10gPSBbXTtcclxuICBwcml2YXRlIF9yYXdQbGFuZXM6IFNldDxhbnk+ID0gbmV3IFNldCgpO1xyXG4gIHByaXZhdGUgX3BsYW5lTWF0ZXJpYWw6IE1lc2hQaG9uZ01hdGVyaWFsO1xyXG4gIHByaXZhdGUgX3NoYWRvd1BsYW5lOiBNZXNoO1xyXG5cclxuICBwcml2YXRlIF9sYXN0RXZlbnRUaW1lc3RhbXA6IG51bWJlcjtcclxuICBwcml2YXRlIF9sYXN0T2JqZWN0VG91Y2hUaW1lc3RhbXA6IG51bWJlcjtcclxuICBwcml2YXRlIF9kb3VibGVUYXBUaW1lZnJhbWU6IG51bWJlciA9IDUwMDtcclxuICBwcml2YXRlIF9ob2xkaW5nVG91Y2g6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIF9jb250cm9sbGVyOiBhbnk7XHJcbiAgcHJpdmF0ZSBfcmF5Y2FzdGVyOiBSYXljYXN0ZXI7XHJcbiAgcHJpdmF0ZSBfdGVtcE1hdHJpeDogTWF0cml4NDtcclxuICBwcml2YXRlIF9jbGVhbnVwOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgcHJpdmF0ZSBfYW5pbWF0aW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfbGlmdEFuaW1hdGlvbjogVFdFRU4uVHdlZW48YW55PjtcclxuICBwcml2YXRlIF9kcm9wQW5pbWF0aW9uOiBUV0VFTi5Ud2Vlbjxhbnk+O1xyXG5cclxuICBwcml2YXRlIF9saWdodFByb2JlOiBhbnk7XHJcbiAgcHJpdmF0ZSBfdGhyZWVMaWdodFByb2JlOiBMaWdodFByb2JlO1xyXG4gIHByaXZhdGUgX2N1YmVNYXBUZXh0dXJlOiBUZXh0dXJlO1xyXG4gIHByaXZhdGUgX2RlcHRoRGF0YVRleHR1cmU6IERlcHRoRGF0YVRleHR1cmU7XHJcbiAgcHJpdmF0ZSBfc3VuTGlnaHQ6IFNwb3RMaWdodCB8IERpcmVjdGlvbmFsTGlnaHQ7XHJcblxyXG4gIHByaXZhdGUgX3Bvc2l0aW9uSW5kaWNhdG9yOiBBclBvc2l0aW9uSW5kaWNhdG9yO1xyXG5cclxuICBwcml2YXRlIF9wb2ludFJlcHJlc2VudGF0aW9uID0gbmV3IE1lc2goXHJcbiAgICBuZXcgU3BoZXJlR2VvbWV0cnkoMC4wMiwgMTIsIDEyKSxcclxuICAgIG5ldyBNZXNoQmFzaWNNYXRlcmlhbCh7XHJcbiAgICAgIGNvbG9yOiAweDRjY2FlZCxcclxuICAgICAgdHJhbnNwYXJlbnQ6IHRydWUsXHJcbiAgICAgIG9wYWNpdHk6IDAuMlxyXG4gICAgfSlcclxuICApO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX2NhbWVyYVNlcnZpY2U6IENhbWVyYVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9zZXR0aW5nc1NlcnZpY2U6IFNldHRpbmdzU2VydmljZSxcclxuICAgIHByaXZhdGUgX2lPbmU6IENvbmZpZ3VyYXRvckNvbm5lY3RvclNlcnZpY2VcclxuICApIHtcclxuICAgIHdpbmRvdy5vbmJlZm9yZXVubG9hZCA9ICgpID0+IHRoaXMubmdPbkRlc3Ryb3koKTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgT2JqZWN0VXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLl9yZXRpY2xlKTtcclxuICAgIE9iamVjdFV0aWxzLkRpc3Bvc2VPYmplY3QodGhpcy5fc3VuTGlnaHQpO1xyXG4gICAgT2JqZWN0VXRpbHMuRGlzcG9zZU9iamVjdCh0aGlzLl9wb2ludFJlcHJlc2VudGF0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBhc3luYyByZXNldFBsYW5lRGV0ZWN0aW9uKCkge1xyXG4gICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgPSBmYWxzZTtcclxuICAgIHRoaXMuX3ZlcnRleExpc3QgPSBbXTtcclxuICAgIHRoaXMuX2RldGVjdGVkUGxhbmVzLmZvckVhY2goKHBsYW5lKSA9PiB0aGlzLnNjZW5lLnJlbW92ZShwbGFuZSkpO1xyXG4gICAgdGhpcy5fZGV0ZWN0ZWRQbGFuZXMgPSBbXTtcclxuICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICAgIHRoaXMuX3Jhd1BsYW5lcyA9IG5ldyBTZXQ8YW55PigpO1xyXG4gICAgdGhpcy5fY2xlYW51cCA9IGZhbHNlO1xyXG4gICAgYXdhaXQgdGhpcy5fc2Vzc2lvbi5lbmQoKTtcclxuICAgIHRoaXMuX2NsZWFudXAgPSB0cnVlO1xyXG4gICAgdGhpcy5fc2Vzc2lvbiA9IG51bGw7XHJcbiAgICB0aGlzLl9pbml0U2Vzc2lvbigpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGVuZFNlc3Npb25FdmVudCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX3Nlc3Npb24uZW5kKCk7XHJcbiAgfVxyXG4gIHB1YmxpYyBhc3luYyBhcklPU1N1cHBvcnRlZCgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIGNvbnN0IGEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAvLyByZWxMaXN0LnN1cHBvcnRzKCdhcicpIGV4aXN0cyBvbiBTYWZhcmkgdGhhdCBzdXBwb3J0cyBRdWljayBMb29rXHJcbiAgICByZXR1cm4gISEoYS5yZWxMaXN0ICYmIChhLnJlbExpc3QgYXMgYW55KS5zdXBwb3J0cyAmJiBhLnJlbExpc3Quc3VwcG9ydHMoJ2FyJykpO1xyXG4gIH1cclxuICBwdWJsaWMgYXN5bmMgYXJTdXBwb3J0ZWQoKSB7XHJcbiAgICBpZiAoKG5hdmlnYXRvciBhcyBhbnkpLnhyKSB7XHJcbiAgICAgIHJldHVybiBhd2FpdCAobmF2aWdhdG9yIGFzIGFueSkueHIuaXNTZXNzaW9uU3VwcG9ydGVkKCdpbW1lcnNpdmUtYXInKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBhZGRPYmplY3RUb0FSU2NlbmUob2JqZWN0OiBPYmplY3QzRCk6IHZvaWQge1xyXG4gICAgdGhpcy5fYWN0aXZlQVJNb2RlbCA9IG9iamVjdDtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudmlzaWJsZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5jYXN0U2hhZG93ID0gdHJ1ZTtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9wb3NpdGlvbkluZGljYXRvciA9IG5ldyBBclBvc2l0aW9uSW5kaWNhdG9yKG5ldyBCb3gzKCkuc2V0RnJvbU9iamVjdChvYmplY3QpKTtcclxuICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMuX2FjdGl2ZUFSTW9kZWwsIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBtb2RlbExvYWRpbmcoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gIXRoaXMuX2FjdGl2ZUFSTW9kZWw7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbW9kZWxQbGFjZWQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fYWN0aXZlQVJNb2RlbCAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgJiYgIXRoaXMuX2hvbGRpbmdUb3VjaDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBoYW5kbGVGcmFtZSh4ckZyYW1lKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5fc2Vzc2lvbiAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsKSB7XHJcbiAgICAgIC8vIFRPRE8gRklYXHJcbiAgICAgIC8vIHRoaXMuX2lPbmUuc2hvdWxkU2hvd0xvYWRlciA9IGZhbHNlO1xyXG5cclxuICAgICAgdGhpcy5fY2hlY2tBdmFpbGFibGVGZWF0dXJlcyh4ckZyYW1lKTtcclxuICAgICAgdGhpcy5fY2hlY2tIaXRUZXN0TWV0aG9kKHhyRnJhbWUpO1xyXG4gICAgICB0aGlzLl9jaGVja0V4dHJhRmVhdHVyZXMoeHJGcmFtZSk7XHJcbiAgICAgIHRoaXMuX2hhbmRsZUhvbGRNb3ZlRXZlbnQoKTtcclxuICAgICAgdGhpcy5faGFuZGxlTXVsdGlUb3VjaEV2ZW50KCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgdGhpcy51cGRhdGVDb250ZXh0TWVudS5uZXh0KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIFRXRUVOLnVwZGF0ZSgpO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIucmVuZGVyKHRoaXMuc2NlbmUsIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpbml0KHJlbmRlcmVyOiBXZWJHTFJlbmRlcmVyKTogdm9pZCB7XHJcbiAgICAvLyBUT0RPIEZJWFxyXG4gICAgLy8gdGhpcy5faU9uZS5zaG91bGRTaG93TG9hZGVyID0gdHJ1ZTtcclxuICAgIGlmICghdGhpcy5fcmVuZGVyZXIpIHtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIgPSByZW5kZXJlcjtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIub3V0cHV0Q29sb3JTcGFjZSA9IFNSR0JDb2xvclNwYWNlO1xyXG4gICAgICB0aGlzLl9pbml0U2NlbmUoKTtcclxuICAgICAgdGhpcy5faW5pdExpZ2h0aW5nKCk7XHJcbiAgICAgIHRoaXMuX2luaXRDb250cm9sbGVyKCk7XHJcblxyXG4gICAgICB0aGlzLl9yZXRpY2xlID0gbmV3IFJldGljbGUoKTtcclxuICAgICAgdGhpcy5zY2VuZS5hZGQodGhpcy5fcmV0aWNsZSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9pbml0UmVuZGVyZXIoKTtcclxuICAgIHRoaXMuX2luaXRTZXNzaW9uKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2F2ZVByZVNlbGVjdGlvblBvc2l0aW9uKCkge1xyXG4gICAgdGhpcy5fYVJNb2RlbEJhY2t1cFBvc2l0aW9uID0gdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5jbG9uZSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHVwZGF0ZUNoYW5nZWRNb2RlbCgpIHtcclxuICAgIGlmICh0aGlzLl9hUk1vZGVsQmFja3VwUG9zaXRpb24pIHtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5zZXQodGhpcy5fYVJNb2RlbEJhY2t1cFBvc2l0aW9uLngsIHRoaXMuX2FSTW9kZWxCYWNrdXBQb3NpdGlvbi55LCB0aGlzLl9hUk1vZGVsQmFja3VwUG9zaXRpb24ueik7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSB7XHJcbiAgICAgIHRoaXMuX3VwZGF0ZU1lc2hNYXRlcmlhbHMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBhck1vZGVIYXNCZWVuQWN0aXZlKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuc2NlbmUgIT09IHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzaG93TW92ZVBob25lQW5pbWF0aW9uKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUFSTW9kZWwgJiYgIXRoaXMuX3JldGljbGUudmlzaWJsZSAmJiAhdGhpcy5fc3VyZmFjZUZvdW5kT25jZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXRBY3RpdmVNb2RlbCgpOiBhbnkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUFSTW9kZWw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0U2Vzc2lvbigpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5fc2Vzc2lvbikge1xyXG4gICAgICAvLyAnZGVwdGgtc2Vuc2luZydcclxuICAgICAgY29uc3QgZmVhdHVyZXMgPSB7XHJcbiAgICAgICAgcmVxdWlyZWRGZWF0dXJlczogWydsb2NhbC1mbG9vcicsICdoaXQtdGVzdCddLFxyXG4gICAgICAgIG9wdGlvbmFsRmVhdHVyZXM6IFsnbGlnaHQtZXN0aW1hdGlvbicsICdwbGFuZS1kZXRlY3Rpb24nLCAnYW5jaG9ycycsICdkb20tb3ZlcmxheSddXHJcbiAgICAgICAgLCBkb21PdmVybGF5OiB7cm9vdDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FyLXJvb3QnKX1cclxuICAgICAgICAsIGRlcHRoU2Vuc2luZzoge1xyXG4gICAgICAgICAgdXNhZ2VQcmVmZXJlbmNlOiBbJ2NwdS1vcHRpbWl6ZWQnXSxcclxuICAgICAgICAgIGRhdGFGb3JtYXRQcmVmZXJlbmNlOiBbJ2x1bWluYW5jZS1hbHBoYSddXHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgKG5hdmlnYXRvciBhcyBhbnkpLnhyLnJlcXVlc3RTZXNzaW9uKCdpbW1lcnNpdmUtYXInLCBmZWF0dXJlcykudGhlbigoc2Vzc2lvbikgPT4ge1xyXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnhyLnNldFJlZmVyZW5jZVNwYWNlVHlwZSgnbG9jYWwnKTtcclxuXHJcbiAgICAgICAgc2Vzc2lvbi5yZXF1ZXN0UmVmZXJlbmNlU3BhY2UoJ3ZpZXdlcicpLnRoZW4oKHJlZlNwYWNlKSA9PiB7XHJcbiAgICAgICAgICBzZXNzaW9uLnJlcXVlc3RIaXRUZXN0U291cmNlKHtzcGFjZTogcmVmU3BhY2V9KS50aGVuKChoaXRUZXN0U291cmNlKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuaGl0VGVzdFNvdXJjZSA9IGhpdFRlc3RTb3VyY2U7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc2Vzc2lvbi5yZXF1ZXN0UmVmZXJlbmNlU3BhY2UoJ2xvY2FsJykudGhlbigocmVmU3BhY2UpID0+IHtcclxuICAgICAgICAgIHRoaXMucmVmU3BhY2UgPSByZWZTcGFjZTtcclxuICAgICAgICAgIHRoaXMuX29uU2Vzc2lvblN0YXJ0ZWQoc2Vzc2lvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hlY2tBdmFpbGFibGVGZWF0dXJlcyh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLmRlcHRoT2NjbHVzaW9uICYmIHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMuZGVwdGhIaXRUZXN0ICYmXHJcbiAgICAgICEodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSAmJiB0aGlzLl9zZXNzaW9uLmRlcHRoVXNhZ2UpIHtcclxuICAgICAgdGhpcy5fYXJGZWF0dXJlcy5wdXNoKEFyRmVhdHVyZS5DUFVEZXB0aE9jY2x1c2lvbiwgQXJGZWF0dXJlLkNQVURlcHRoSGl0VGVzdCk7XHJcbiAgICAgIHRoaXMuX2luaXRDUFVEZXB0aE9jY2x1c2lvbigpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLmFuY2hvcmVkSGl0VGVzdCAmJlxyXG4gICAgICAhKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkFuY2hvcmVkSGl0VGVzdCkpICYmIHhyRnJhbWUudHJhY2tlZEFuY2hvcnMpIHtcclxuICAgICAgdGhpcy5fYXJGZWF0dXJlcy5wdXNoKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpO1xyXG4gICAgICB0aGlzLl9pbml0QW5jaG9yZWRIaXRUZXN0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMubGlnaHRFc3RpbWF0aW9uICYmXHJcbiAgICAgICEodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuTGlnaHRFc3RpbWF0aW9uKSkpIHtcclxuICAgICAgdGhpcy5fc2Vzc2lvbi5yZXF1ZXN0TGlnaHRQcm9iZSgpLnRoZW4oKGxpZ2h0UHJvYmU6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmIChsaWdodFByb2JlKSB7XHJcbiAgICAgICAgICB0aGlzLl9hckZlYXR1cmVzLnB1c2goQXJGZWF0dXJlLkxpZ2h0RXN0aW1hdGlvbik7XHJcbiAgICAgICAgICB0aGlzLl9pbml0TGlnaHRFc3RpbWF0aW9uKGxpZ2h0UHJvYmUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5hclBhcmFtZXRlcnMucmVmbGVjdGlvbkVzdGltYXRpb24gJiZcclxuICAgICAgISh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5SZWZsZWN0aW9uQ3ViZU1hcCkpICYmIHRoaXMuX2xpZ2h0UHJvYmVcclxuICAgICAgJiYgdGhpcy5fZ2xCaW5kaW5nLmdldFJlZmxlY3Rpb25DdWJlTWFwKHRoaXMuX2xpZ2h0UHJvYmUpKSB7XHJcbiAgICAgIHRoaXMuX2FyRmVhdHVyZXMucHVzaChBckZlYXR1cmUuUmVmbGVjdGlvbkN1YmVNYXApO1xyXG4gICAgICB0aGlzLl9pbml0UmVmbGVjdGlvbkN1YmVNYXAoKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5fc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzLmFyUGFyYW1ldGVycy5wbGFuZURldGVjdGlvbiAmJiB0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3MuYXJQYXJhbWV0ZXJzLnBsYW5lSGl0VGVzdCAmJlxyXG4gICAgICAhKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLlBsYW5lRGV0ZWN0aW9uKSkgJiYgeHJGcmFtZS53b3JsZEluZm9ybWF0aW9uKSB7XHJcbiAgICAgIHRoaXMuX2FyRmVhdHVyZXMucHVzaChBckZlYXR1cmUuUGxhbmVEZXRlY3Rpb24sIEFyRmVhdHVyZS5QbGFuZURldGVjdGlvbkhpdFRlc3QpO1xyXG4gICAgICB0aGlzLl9pbml0UGxhbmVEZXRlY3Rpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRSZW5kZXJlcigpOiB2b2lkIHtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnhyLmVuYWJsZWQgPSB0cnVlO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIuc2hhZG93TWFwLnR5cGUgPSBQQ0ZTb2Z0U2hhZG93TWFwO1xyXG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0Q2xlYXJDb2xvcigweDAwMDAwMCwgMCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5hdXRvQ2xlYXIgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRDb250cm9sbGVyKCk6IHZvaWQge1xyXG4gICAgdGhpcy5fdGVtcE1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XHJcbiAgICB0aGlzLl9yYXljYXN0ZXIgPSBuZXcgUmF5Y2FzdGVyKCk7XHJcbiAgICB0aGlzLl9jb250cm9sbGVyID0gdGhpcy5fcmVuZGVyZXIueHIuZ2V0Q29udHJvbGxlcigwKTtcclxuICAgIHRoaXMuc2NlbmUuYWRkKHRoaXMuX2NvbnRyb2xsZXIpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdFNjZW5lKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2VuZSA9IG5ldyBTY2VuZSgpO1xyXG4gICAgY29uc3QgcGxhbmVHZW9tZXRyeSA9IG5ldyBQbGFuZUdlb21ldHJ5KDEwMCwgMTAwKTtcclxuICAgIGNvbnN0IG1hdGVyaWFsID0gbmV3IFNoYWRvd01hdGVyaWFsKHtvcGFjaXR5OiAwLjJ9KTtcclxuICAgIHRoaXMuX3NoYWRvd1BsYW5lID0gbmV3IE1lc2gocGxhbmVHZW9tZXRyeSwgbWF0ZXJpYWwpO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUubmFtZSA9ICdzaGFkb3dQbGFuZSc7XHJcbiAgICB0aGlzLl9zaGFkb3dQbGFuZS5yb3RhdGlvbi54IC09IE1hdGguUEkgLyAyO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUucmVjZWl2ZVNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9zaGFkb3dQbGFuZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLl9zaGFkb3dQbGFuZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0TGlnaHRFc3RpbWF0aW9uKGxpZ2h0UHJvYmU6IGFueSkge1xyXG4gICAgdGhpcy5fdGhyZWVMaWdodFByb2JlID0gIG5ldyBMaWdodFByb2JlKCk7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCh0aGlzLl90aHJlZUxpZ2h0UHJvYmUpO1xyXG4gICAgdGhpcy5fbGlnaHRQcm9iZSA9IGxpZ2h0UHJvYmU7XHJcblxyXG4gICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgdGhpcy5fZ2xCaW5kaW5nID0gbmV3IFhSV2ViR0xCaW5kaW5nKHRoaXMuX3Nlc3Npb24sIHRoaXMuX3JlbmRlcmVyLmdldENvbnRleHQoKSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbml0UmVmbGVjdGlvbkN1YmVNYXAoKSB7XHJcbiAgICB0aGlzLl9jdWJlTWFwVGV4dHVyZSA9IG5ldyBUZXh0dXJlKCk7XHJcbiAgICB0aGlzLl9yZW5kZXJlci5pbml0VGV4dHVyZSh0aGlzLl9jdWJlTWFwVGV4dHVyZSk7XHJcbiAgICB0aGlzLnNjZW5lLmVudmlyb25tZW50ID0gdGhpcy5fY3ViZU1hcFRleHR1cmU7XHJcblxyXG4gICAgdGhpcy5fbGlnaHRQcm9iZS5hZGRFdmVudExpc3RlbmVyKCdyZWZsZWN0aW9uY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICBjb25zdCByYXdEYXRhID0gdGhpcy5fZ2xCaW5kaW5nLmdldFJlZmxlY3Rpb25DdWJlTWFwKHRoaXMuX2xpZ2h0UHJvYmUpO1xyXG4gICAgICBjb25zdCB0ZXhQcm9wcyA9IHRoaXMuX3JlbmRlcmVyLnByb3BlcnRpZXMuZ2V0KHRoaXMuX2N1YmVNYXBUZXh0dXJlKTtcclxuICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICB0ZXhQcm9wcy5fX3dlYmdsVGV4dHVyZSA9IHJhd0RhdGE7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2luaXRDUFVEZXB0aE9jY2x1c2lvbigpIHtcclxuICAgIHRoaXMuX2RlcHRoRGF0YVRleHR1cmUgPSBuZXcgRGVwdGhEYXRhVGV4dHVyZSgpO1xyXG4gICAgdGhpcy5fdXBkYXRlTWVzaE1hdGVyaWFscygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdEFuY2hvcmVkSGl0VGVzdCgpIHtcclxuICAgIHRoaXMuX2FuY2hvcmVkT2JqZWN0cyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdFBsYW5lRGV0ZWN0aW9uKCkge1xyXG4gICAgdGhpcy5fY3JlYXRlUGxhbmVNYXRlcmlhbCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaW5pdExpZ2h0aW5nKCkge1xyXG4gICAgY29uc3QgYW1iaWVudExpZ2h0ID0gbmV3IFRIUkVFLkFtYmllbnRMaWdodCgweGZmZmZmZiwgMC4xKTtcclxuICAgIGFtYmllbnRMaWdodC5jb2xvci5zZXRIZXgoMHhmZmZmZmYpLmNvbnZlcnRTUkdCVG9MaW5lYXIoKTtcclxuICAgIGFtYmllbnRMaWdodC5uYW1lID0gJ2FtYmllbnRMaWdodCc7XHJcblxyXG4gICAgdGhpcy5fc3VuTGlnaHQgPSBuZXcgRGlyZWN0aW9uYWxMaWdodCgnYmxhY2snLCAwLjMpO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICB0aGlzLl9zdW5MaWdodC5zaGFkb3cubWFwU2l6ZS53aWR0aCA9IDQwOTY7XHJcbiAgICB0aGlzLl9zdW5MaWdodC5zaGFkb3cubWFwU2l6ZS5oZWlnaHQgPSA0MDk2O1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5sZWZ0ID0gLTEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5yaWdodCA9IDEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS50b3AgPSAxMDtcclxuICAgIHRoaXMuX3N1bkxpZ2h0LnNoYWRvdy5jYW1lcmEuYm90dG9tID0gLTEwO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5uZWFyID0gMC4xO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQuc2hhZG93LmNhbWVyYS5mYXIgPSAzMDtcclxuICAgIHRoaXMuX3N1bkxpZ2h0LnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQudGFyZ2V0LnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc3VuTGlnaHQubmFtZSA9ICdzdW5MaWdodCc7XHJcbiAgICB0aGlzLnNjZW5lLmFkZCgvKmFtYmllbnRMaWdodCwgKi90aGlzLl9zdW5MaWdodC50YXJnZXQsIHRoaXMuX3N1bkxpZ2h0KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NoZWNrSGl0VGVzdE1ldGhvZCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5DUFVEZXB0aE9jY2x1c2lvbikgJiYgdGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQW5jaG9yZWRIaXRUZXN0KSkge1xyXG4gICAgICB0aGlzLl9leGVjdXRlRGVwdGhBbmNob3JIaXRUZXN0KHhyRnJhbWUpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpKSB7XHJcbiAgICAgIHRoaXMuX2V4ZWN1dGVBbmNob3JlZEhpdFRlc3QoeHJGcmFtZSk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkNQVURlcHRoSGl0VGVzdCkpIHtcclxuICAgICAgdGhpcy5fZXhlY3V0ZUNQVURlcHRoSGl0VGVzdCh4ckZyYW1lKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVEZXB0aEFuY2hvckhpdFRlc3QoeHJGcmFtZSkge1xyXG4gICAgY29uc3QgeHJWaWV3ZXJQb3NlOiBhbnkgPSB4ckZyYW1lLmdldFZpZXdlclBvc2UodGhpcy5yZWZTcGFjZSk7XHJcbiAgICBjb25zdCB4ckNhbWVyYTogYW55ID0gdGhpcy5fcmVuZGVyZXIueHIuZ2V0Q2FtZXJhKC8qdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmEqLyk7IC8vIHRvZG86IGR1ZSB0byB0aHJlZWpzIHVwZGF0ZSBwYXJhbWV0ZXIgbm90IG5lZWRlZCBhbnltb3JlLCBjaGVjayB0aGlzIVxyXG4gICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKHRoaXMuaGl0VGVzdFNvdXJjZSAmJiB4clZpZXdlclBvc2UpIHtcclxuICAgICAgY29uc3QgaGl0VGVzdFJlc3VsdHMgPSB4ckZyYW1lLmdldEhpdFRlc3RSZXN1bHRzKHRoaXMuaGl0VGVzdFNvdXJjZSk7XHJcbiAgICAgIGlmIChoaXRUZXN0UmVzdWx0cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICBpZiAoeHJWaWV3ZXJQb3NlLnZpZXdzLmxlbmd0aCA+IDAgJiYgeHJDYW1lcmEpIHtcclxuICAgICAgICAgIGZvciAoY29uc3QgdmlldyBvZiB4clZpZXdlclBvc2Uudmlld3MpIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUpIHtcclxuICAgICAgICAgICAgICBjb25zdCBkZXB0aERhdGE6IGFueSA9IHhyRnJhbWUuZ2V0RGVwdGhJbmZvcm1hdGlvbih2aWV3KTtcclxuICAgICAgICAgICAgICAvLyBQbGFjZSBvYmplY3QgYXMgc29vbiBhcyBkZXB0aCBkYXRhIGlzIGF2YWlsYWJsZSBhbmQgZGlzdGFuY2UgaXMgd2l0aGluIHJlYXNvbmFibGUgdmFsdWVzXHJcbiAgICAgICAgICAgICAgaWYgKGRlcHRoRGF0YSAmJiBkZXB0aERhdGEuZ2V0RGVwdGhJbk1ldGVycygwLjUsIDAuNSkgPiAwLjEgJiYgZGVwdGhEYXRhLmdldERlcHRoSW5NZXRlcnMoMC41LCAwLjUpIDwgMi41KSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnNldCh4ckNhbWVyYS5wb3NpdGlvbi54LCB4ckNhbWVyYS5wb3NpdGlvbi55LCB4ckNhbWVyYS5wb3NpdGlvbi56KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24uc2V0RnJvbVF1YXRlcm5pb24oeHJDYW1lcmEucXVhdGVybmlvbik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnRyYW5zbGF0ZVooLWRlcHRoRGF0YS5nZXREZXB0aEluTWV0ZXJzKDAuNSwgMC41KSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnkgKz0gMC4wMjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24uc2V0KDAsIDAsIDApO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gV2hlbiBoaXQgdGVzdCByZXN1bHRzIGFyZSBhdmFpbGFibGUgd2Ugc3dpdGNoIHRvIHRoZSBhbmNob3JlZCBoaXQgdGVzdCBtZXRob2QgYW5kIHBsYWNlIHRoZSBtb2RlbCBhY2NvcmRpbmdseVxyXG4gICAgICAgIHRoaXMuX2V4ZWN1dGVBbmNob3JlZEhpdFRlc3QoeHJGcmFtZSk7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FuY2hvcmVkT2JqZWN0cy5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgIHRoaXMuX2hhbmRsZVRvdWNoRXZlbnQoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfZXhlY3V0ZUFuY2hvcmVkSGl0VGVzdCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIHRoaXMuX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHthbmNob3JlZE9iamVjdCwgYW5jaG9yfSBvZiB0aGlzLl9hbmNob3JlZE9iamVjdHMpIHtcclxuICAgICAgaWYgKCF4ckZyYW1lLnRyYWNrZWRBbmNob3JzLmhhcyhhbmNob3IpKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgYW5jaG9yUG9zZSA9IHhyRnJhbWUuZ2V0UG9zZShhbmNob3IuYW5jaG9yU3BhY2UsIHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICBpZiAoYW5jaG9yUG9zZSkge1xyXG4gICAgICAgIGNvbnN0IGhpdE1hdHJpeCA9IG5ldyBNYXRyaXg0KCkuZnJvbUFycmF5KGFuY2hvclBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAgICAgYW5jaG9yZWRPYmplY3QucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKGhpdE1hdHJpeCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVDUFVEZXB0aEhpdFRlc3QoeHJGcmFtZTogYW55KSB7XHJcbiAgICBjb25zdCB4clZpZXdlclBvc2U6IGFueSA9IHhyRnJhbWUuZ2V0Vmlld2VyUG9zZSh0aGlzLnJlZlNwYWNlKTtcclxuICAgIGNvbnN0IHhyQ2FtZXJhOiBhbnkgPSB0aGlzLl9yZW5kZXJlci54ci5nZXRDYW1lcmEoLyp0aGlzLl9jYW1lcmFTZXJ2aWNlLmNhbWVyYSovKTsgLy8gdG9kbzogZHVlIHRvIHRocmVlanMgdXBkYXRlIHBhcmFtZXRlciBub3QgbmVlZGVkIGFueW1vcmUsIGNoZWNrIHRoaXMhXHJcbiAgICB0aGlzLl9yZXRpY2xlLnZpc2libGUgPSBmYWxzZTtcclxuXHJcbiAgICBpZiAoeHJWaWV3ZXJQb3NlICYmIHhyVmlld2VyUG9zZS52aWV3cy5sZW5ndGggPiAwICYmIHhyQ2FtZXJhKSB7XHJcbiAgICAgIGZvciAoY29uc3QgdmlldyBvZiB4clZpZXdlclBvc2Uudmlld3MpIHtcclxuICAgICAgICBpZiAoIXRoaXMuX2FjdGl2ZUFSTW9kZWwudmlzaWJsZSkge1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuX3N1cmZhY2VGb3VuZE9uY2UgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZGVwdGhEYXRhOiBhbnkgPSB4ckZyYW1lLmdldERlcHRoSW5mb3JtYXRpb24odmlldyk7XHJcbiAgICAgICAgaWYgKGRlcHRoRGF0YSkge1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS5wb3NpdGlvbi5zZXQoeHJDYW1lcmEucG9zaXRpb24ueCwgeHJDYW1lcmEucG9zaXRpb24ueSwgeHJDYW1lcmEucG9zaXRpb24ueik7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnJvdGF0aW9uLnNldEZyb21RdWF0ZXJuaW9uKHhyQ2FtZXJhLnF1YXRlcm5pb24pO1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS50cmFuc2xhdGVaKC1kZXB0aERhdGEuZ2V0RGVwdGhJbk1ldGVycygwLjUsIDAuNSkpO1xyXG4gICAgICAgICAgdGhpcy5fcmV0aWNsZS5wb3NpdGlvbi55ICs9IDAuMDI7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnJvdGF0aW9uLnNldCgwLCAwLCAwKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2V4ZWN1dGVEZWZhdWx0SGl0VGVzdCh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGNvbnN0IHhyVmlld2VyUG9zZSA9IHhyRnJhbWUuZ2V0Vmlld2VyUG9zZSh0aGlzLnJlZlNwYWNlKTtcclxuICAgIHRoaXMuX3JldGljbGUudmlzaWJsZSA9IGZhbHNlO1xyXG5cclxuICAgIGlmICh0aGlzLmhpdFRlc3RTb3VyY2UgJiYgeHJWaWV3ZXJQb3NlKSB7XHJcbiAgICAgIGNvbnN0IGhpdFRlc3RSZXN1bHRzID0geHJGcmFtZS5nZXRIaXRUZXN0UmVzdWx0cyh0aGlzLmhpdFRlc3RTb3VyY2UpO1xyXG4gICAgICBpZiAoaGl0VGVzdFJlc3VsdHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IHBvc2UgPSBoaXRUZXN0UmVzdWx0c1swXS5nZXRQb3NlKHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICAgIGlmICghdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgICB0aGlzLl9yZXRpY2xlLnZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgdGhpcy5fc3VyZmFjZUZvdW5kT25jZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGhpdE1hdHJpeCA9IG5ldyBNYXRyaXg0KCkuZnJvbUFycmF5KHBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAgICAgdGhpcy5faGl0VGVzdFJlc3VsdCA9IGhpdE1hdHJpeDtcclxuICAgICAgICB0aGlzLl9yZXRpY2xlLnBvc2l0aW9uLnNldEZyb21NYXRyaXhQb3NpdGlvbihoaXRNYXRyaXgpO1xyXG4gICAgICAgIHRoaXMuX3JldGljbGUucG9zaXRpb24ueSArPSAwLjAyOyAvLyBQcmV2ZW50cyB6LWZpZ2h0aW5nXHJcbiAgICAgICAgdGhpcy5fcmV0aWNsZUhpdFRlc3RSZXN1bHQgPSBoaXRUZXN0UmVzdWx0c1swXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2hlY2tFeHRyYUZlYXR1cmVzKHhyRnJhbWU6IGFueSkge1xyXG4gICAgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkxpZ2h0RXN0aW1hdGlvbikpIHtcclxuICAgICAgdGhpcy5fYWRqdXN0TGlnaHRpbmcoeHJGcmFtZSk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5fYXJGZWF0dXJlcy5pbmNsdWRlcyhBckZlYXR1cmUuQ1BVRGVwdGhPY2NsdXNpb24pKSB7XHJcbiAgICAgIHRoaXMuX2hpZGVPY2NsdWRlZE1lc2hlcyh4ckZyYW1lKTtcclxuICAgIH1cclxuICAgIC8vIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5QbGFuZURldGVjdGlvbikpIHtcclxuICAgIC8vICAgdGhpcy5fZHJhd1BsYW5lcyh4ckZyYW1lKTtcclxuICAgIC8vIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hpZGVPY2NsdWRlZE1lc2hlcyh4ckZyYW1lOiBhbnkpIHtcclxuICAgIGNvbnN0IHhyVmlld2VyUG9zZTogYW55ID0geHJGcmFtZS5nZXRWaWV3ZXJQb3NlKHRoaXMucmVmU3BhY2UpO1xyXG4gICAgaWYgKHhyVmlld2VyUG9zZSAmJiB4clZpZXdlclBvc2Uudmlld3MubGVuZ3RoID4gMCkge1xyXG4gICAgICBmb3IgKGNvbnN0IHZpZXcgb2YgeHJWaWV3ZXJQb3NlLnZpZXdzKSB7XHJcbiAgICAgICAgY29uc3QgZGVwdGhEYXRhOiBhbnkgPSB4ckZyYW1lLmdldERlcHRoSW5mb3JtYXRpb24odmlldyk7XHJcbiAgICAgICAgaWYgKGRlcHRoRGF0YSkge1xyXG4gICAgICAgICAgdGhpcy5fZGVwdGhEYXRhVGV4dHVyZS51cGRhdGVEZXB0aChkZXB0aERhdGEpO1xyXG4gICAgICAgICAgdGhpcy5fdXBkYXRlQXVnbWVudGVkTWF0ZXJpYWxVbmlmb3JtcyhkZXB0aERhdGEubm9ybURlcHRoQnVmZmVyRnJvbU5vcm1WaWV3Lm1hdHJpeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIF9jcmVhdGVQbGFuZU1hdGVyaWFsKCkge1xyXG4gICAgY29uc3QgcG0gPSBuZXcgTWVzaFBob25nTWF0ZXJpYWwoe3RyYW5zcGFyZW50OiB0cnVlLCBzaWRlOiBEb3VibGVTaWRlfSk7XHJcbiAgICBwbS5tYXAgPSBhd2FpdCBNYXRlcmlhbFV0aWxzLkZyb21VcmwoJ2Fzc2V0cy90ZXh0dXJlcy9GbG9vci9UaWxlcy9hcl9mbG9vcl90ZXh0dXJlLnBuZycsXHJcbiAgICAgIGZhbHNlLCAxLCAyLCAyKTtcclxuICAgIHBtLm1hcC5mbGlwWSA9IGZhbHNlO1xyXG4gICAgcG0ubmVlZHNVcGRhdGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fcGxhbmVNYXRlcmlhbCA9IHBtO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBfb25TZXNzaW9uU3RhcnRlZChzZXNzaW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGRvbU92ZXJsYXkgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXItcm9vdCcpO1xyXG4gICAgc2Vzc2lvbi5hZGRFdmVudExpc3RlbmVyKCdlbmQnLCB0aGlzLl9vblNlc3Npb25FbmRlZC5iaW5kKHRoaXMpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0JywgKCkgPT4gdGhpcy5faGFuZGxlVG91Y2hFdmVudCgpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0c3RhcnQnLCAoJGV2ZW50KSA9PiB0aGlzLl9oYW5kbGVIb2xkU3RhcnRFdmVudCgkZXZlbnQpKTtcclxuICAgIHNlc3Npb24uYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0ZW5kJywgKCRldmVudCkgPT4gdGhpcy5faGFuZGxlSG9sZEVuZEV2ZW50KCRldmVudCkpO1xyXG4gICAgZG9tT3ZlcmxheS5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV4cnNlbGVjdCcsICgkZXZlbnQpID0+IHRoaXMuX2NoZWNraW5nSW50ZXJmYWNlSW50ZXJhY3Rpb24oJGV2ZW50KSk7XHJcbiAgICBhd2FpdCAoPGFueT50aGlzLl9yZW5kZXJlci5nZXRDb250ZXh0KCkpLm1ha2VYUkNvbXBhdGlibGUoKTtcclxuICAgIHRoaXMuX3JlbmRlcmVyLnhyLnNldFNlc3Npb24oc2Vzc2lvbik7XHJcbiAgICB0aGlzLl9zZXNzaW9uID0gc2Vzc2lvbjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX29uU2Vzc2lvbkVuZGVkKCkge1xyXG4gICAgaWYgKHRoaXMuX2NsZWFudXApIHtcclxuICAgICAgdGhpcy5fc2Vzc2lvbiA9IG51bGw7XHJcbiAgICAgIHRoaXMuX3N1cmZhY2VGb3VuZE9uY2UgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fcmV0aWNsZS52aXNpYmxlID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yKTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlID0gdHJ1ZTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5zZXQoMCwgMCwgMCk7XHJcbiAgICAgIHRoaXMuX3JlbW92ZU1hdGVyaWFsU2hhZGVycygpO1xyXG4gICAgICB0aGlzLnNob3VsZEFkZE9iamVjdFRvU2NlbmUubmV4dCh0aGlzLl9hY3RpdmVBUk1vZGVsKTtcclxuICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbCA9IG51bGw7XHJcbiAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLl9hckZlYXR1cmVzID0gW107XHJcbiAgICAgIHRoaXMuX2xpZ2h0UHJvYmUgPSBudWxsO1xyXG5cclxuICAgICAgdGhpcy5fdmVydGV4TGlzdCA9IFtdO1xyXG4gICAgICB0aGlzLl9kZXRlY3RlZFBsYW5lcyA9IFtdO1xyXG4gICAgICB0aGlzLl9yYXdQbGFuZXMgPSBuZXcgU2V0PGFueT4oKTtcclxuXHJcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnhyLmVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuc2hhZG93TWFwLnR5cGUgPSBQQ0ZTb2Z0U2hhZG93TWFwO1xyXG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRDbGVhckNvbG9yKDB4ZmFmYWZhKTtcclxuICAgICAgdGhpcy5fcmVuZGVyZXIuYXV0b0NsZWFyID0gdHJ1ZTtcclxuXHJcbiAgICAgIC8vIFRPRE8gRklYXHJcbiAgICAgIC8vIHRoaXMuX3ZpZXdNb2RlU2VydmljZS52aWV3TW9kZSA9IFZpZXdNb2RlLlJvb21QbGFuM0Q7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zZXRBck1vZGVsU2hhZG93cygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9hY3RpdmVBUk1vZGVsKSB7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudHJhdmVyc2UoKG5vZGUpID0+IHtcclxuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICAgIG5vZGUuY2FzdFNoYWRvdyA9IHRydWU7XHJcbiAgICAgICAgICBub2RlLnJlY2VpdmVTaGFkb3cgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVUb3VjaEV2ZW50KG1hbnVhbFRvdWNoOiBib29sZWFuID0gdHJ1ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5faGFuZGxlRG91YmxlVGFwRXZlbnQoKTtcclxuXHJcbiAgICBpZiAobWFudWFsVG91Y2gpIHtcclxuICAgICAgaWYgKHRoaXMuX3JldGljbGUudmlzaWJsZSAmJiAhdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX2FyRmVhdHVyZXMuaW5jbHVkZXMoQXJGZWF0dXJlLkFuY2hvcmVkSGl0VGVzdCkpIHtcclxuICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICAgIHRoaXMuX3JldGljbGVIaXRUZXN0UmVzdWx0LmNyZWF0ZUFuY2hvcigpLnRoZW4oKGFuY2hvcikgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLl9hbmNob3JlZE9iamVjdHMucHVzaCh7XHJcbiAgICAgICAgICAgICAgYW5jaG9yZWRPYmplY3Q6IHRoaXMuX3NoYWRvd1BsYW5lLFxyXG4gICAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yfSk7XHJcbiAgICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgICAvLyBVbmFibGUgdG8gY3JlYXRlIGFuY2hvclxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICAgIHRoaXMuX2FSTW9kZWxCYWNrdXBZUG9zaXRpb24gPSB0aGlzLl9yZXRpY2xlLnBvc2l0aW9uLnk7XHJcbiAgICAgICAgICB0aGlzLl9zaGFkb3dQbGFuZS5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgICAgdGhpcy5fcG9zaXRpb25JbmRpY2F0b3IucG9zaXRpb24uY29weSh0aGlzLl9yZXRpY2xlLnBvc2l0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICh0aGlzLl9hckZlYXR1cmVzLmluY2x1ZGVzKEFyRmVhdHVyZS5BbmNob3JlZEhpdFRlc3QpKSB7XHJcbiAgICAgICAgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgIHRoaXMuX3JldGljbGVIaXRUZXN0UmVzdWx0LmNyZWF0ZUFuY2hvcigpLnRoZW4oKGFuY2hvcikgPT4ge1xyXG4gICAgICAgICAgdGhpcy5fYW5jaG9yZWRPYmplY3RzLnB1c2goe1xyXG4gICAgICAgICAgICBhbmNob3JlZE9iamVjdDogdGhpcy5fc2hhZG93UGxhbmUsXHJcbiAgICAgICAgICAgIGFuY2hvcjogYW5jaG9yXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KS5jYXRjaCgoZSkgPT4ge1xyXG4gICAgICAgICAgLy8gVW5hYmxlIHRvIGNyZWF0ZSBhbmNob3JcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkodGhpcy5fcmV0aWNsZS5wb3NpdGlvbik7XHJcbiAgICAgICAgdGhpcy5fYVJNb2RlbEJhY2t1cFlQb3NpdGlvbiA9IHRoaXMuX3JldGljbGUucG9zaXRpb24ueTtcclxuICAgICAgICB0aGlzLl9zaGFkb3dQbGFuZS5wb3NpdGlvbi5jb3B5KHRoaXMuX3JldGljbGUucG9zaXRpb24pO1xyXG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yLnBvc2l0aW9uLmNvcHkodGhpcy5fcmV0aWNsZS5wb3NpdGlvbik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgPSB0cnVlO1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUudmlzaWJsZSA9IHRydWU7XHJcbiAgICB0aGlzLl9wb3NpdGlvbkluZGljYXRvci52aXNpYmxlID0gdHJ1ZTtcclxuICAgIHRoaXMuX3NldEFyTW9kZWxTaGFkb3dzKCk7XHJcbiAgICB0aGlzLl9zZXRQbGFuZXNWaXNpYmlsdHkoZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaGFuZGxlTXVsdGlUb3VjaEV2ZW50KCk6IHZvaWQge1xyXG4gICAgY29uc3QgaW5wdXRTb3VyY2VzID0gdGhpcy5fc2Vzc2lvbi5pbnB1dFNvdXJjZXM7XHJcbiAgICBpZiAoaW5wdXRTb3VyY2VzLmxlbmd0aCA9PT0gMiAmJiB0aGlzLl9hY3RpdmVBUk1vZGVsLnZpc2libGUgJiYgIXRoaXMuX2hvbGRpbmdUb3VjaCkge1xyXG4gICAgICB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uID0gdGhpcy5fYVJNb2RlbEJhY2t1cFlSb3RhdGlvbiA9PT0gMCA/IHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24ueSAvIDIgOiB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uO1xyXG4gICAgICBjb25zdCBkeCA9IGlucHV0U291cmNlc1sxXS5nYW1lcGFkLmF4ZXNbMF0gLSBpbnB1dFNvdXJjZXNbMF0uZ2FtZXBhZC5heGVzWzBdO1xyXG4gICAgICBjb25zdCBkeSA9IGlucHV0U291cmNlc1sxXS5nYW1lcGFkLmF4ZXNbMV0gLSBpbnB1dFNvdXJjZXNbMF0uZ2FtZXBhZC5heGVzWzFdO1xyXG4gICAgICBjb25zdCBhbmdsZSA9IE1hdGguYXRhbjIoZHksIGR4KTtcclxuICAgICAgdGhpcy5fYVJNb2RlbFJvdGF0aW9uU3RhcnRpbmdWYWx1ZSA9IHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWUgPT09IDAgPyBhbmdsZSA6IHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWU7XHJcbiAgICAgIGNvbnN0IGRpZmZlcmVuY2UgPSB0aGlzLl9hUk1vZGVsQmFja3VwWVJvdGF0aW9uIC0gKGFuZ2xlIC0gdGhpcy5fYVJNb2RlbFJvdGF0aW9uU3RhcnRpbmdWYWx1ZSk7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucm90YXRpb24ueSA9IHRoaXMuX2FSTW9kZWxCYWNrdXBZUm90YXRpb24gKyBkaWZmZXJlbmNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fYVJNb2RlbEJhY2t1cFlSb3RhdGlvbiA9IDA7XHJcbiAgICAgIHRoaXMuX2FSTW9kZWxSb3RhdGlvblN0YXJ0aW5nVmFsdWUgPSAwO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfaGFuZGxlRG91YmxlVGFwRXZlbnQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBpbnRlcnNlY3Rpb25zOiBJbnRlcnNlY3Rpb25bXSA9IHRoaXMuX2dldE9iamVjdEludGVyc2VjdGlvbnMoW3RoaXMuX2FjdGl2ZUFSTW9kZWxdKTtcclxuICAgIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgY29uc3QgY3VycmVudFRpbWVzdGFtcDogbnVtYmVyID0gRGF0ZS5ub3coKTtcclxuICAgICAgdGhpcy5zaG93Q29udGV4dE1lbnUgPSB0aGlzLl9sYXN0T2JqZWN0VG91Y2hUaW1lc3RhbXAgJiYgY3VycmVudFRpbWVzdGFtcCAtIHRoaXMuX2xhc3RPYmplY3RUb3VjaFRpbWVzdGFtcCA8IHRoaXMuX2RvdWJsZVRhcFRpbWVmcmFtZTtcclxuICAgICAgdGhpcy5fbGFzdE9iamVjdFRvdWNoVGltZXN0YW1wID0gY3VycmVudFRpbWVzdGFtcDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc2hvd0NvbnRleHRNZW51ID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIF9jaGVja0lmSG9sZFRvdWNoRXZlbnQoJGV2ZW50KSB7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgaWYgKCF0aGlzLnVzZXJJblNlbGVjdGlvbk1lbnUgJiYgdGhpcy5fbGFzdEV2ZW50VGltZXN0YW1wID09PSAkZXZlbnQudGltZVN0YW1wICYmIHRoaXMuX3Nlc3Npb24uaW5wdXRTb3VyY2VzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5fdG9nZ2xlSG9sZFRvdWNoRXZlbnQoKTtcclxuICAgICAgfVxyXG4gICAgfSwgMjAwKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2hhbmRsZUhvbGRTdGFydEV2ZW50KCRldmVudDogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLl9sYXN0RXZlbnRUaW1lc3RhbXAgPSAkZXZlbnQudGltZVN0YW1wO1xyXG4gICAgdGhpcy5fY2hlY2tJZkhvbGRUb3VjaEV2ZW50KCRldmVudCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVIb2xkRW5kRXZlbnQoJGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgIHRoaXMuX2xhc3RFdmVudFRpbWVzdGFtcCA9ICRldmVudC50aW1lU3RhbXA7XHJcbiAgICBpZiAodGhpcy5faG9sZGluZ1RvdWNoKSB7XHJcbiAgICAgIHRoaXMuX2hvbGRpbmdUb3VjaCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLl90b2dnbGVIb2xkVG91Y2hFdmVudCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdG9nZ2xlSG9sZFRvdWNoRXZlbnQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5faG9sZGluZ1RvdWNoKSB7XHJcbiAgICAgIC8vIHRoaXMuX3NldFBsYW5lc1Zpc2liaWx0eSh0cnVlKTtcclxuICAgICAgdGhpcy5fY2FsbExpZnRBbmltYXRpb24oKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2NhbGxEcm9wQW5pbWF0aW9uKCk7XHJcbiAgICAgIHRoaXMuX3NldFBsYW5lc1Zpc2liaWx0eShmYWxzZSk7XHJcbiAgICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueSA9IHRoaXMuX2FSTW9kZWxCYWNrdXBZUG9zaXRpb247XHJcbiAgICB9XHJcbiAgICB0aGlzLl90b2dnbGVBUk1vZGVsVHJhbnNwYXJlbmN5KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9oYW5kbGVIb2xkTW92ZUV2ZW50KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuX2hvbGRpbmdUb3VjaCAmJiAhdGhpcy51c2VySW5TZWxlY3Rpb25NZW51KSB7XHJcbiAgICAgIGNvbnN0IGludGVyc2VjdGlvbnM6IEludGVyc2VjdGlvbltdID0gdGhpcy5fZ2V0T2JqZWN0SW50ZXJzZWN0aW9ucyhbdGhpcy5fc2hhZG93UGxhbmVdKTtcclxuICAgICAgaWYgKGludGVyc2VjdGlvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IG1vdmVQb3NpdGlvbiA9ICF0aGlzLl9hbmltYXRpbmcgPyBuZXcgVmVjdG9yMyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50LngsIGludGVyc2VjdGlvbnNbMF0ucG9pbnQueSArIDAuMiwgaW50ZXJzZWN0aW9uc1swXS5wb2ludC56KSA6XHJcbiAgICAgICAgICBuZXcgVmVjdG9yMyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50LngsIHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueSwgaW50ZXJzZWN0aW9uc1swXS5wb2ludC56KTtcclxuICAgICAgICB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobW92ZVBvc2l0aW9uKTtcclxuICAgICAgICB0aGlzLl9hUk1vZGVsQmFja3VwWVBvc2l0aW9uID0gaW50ZXJzZWN0aW9uc1swXS5wb2ludC55O1xyXG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uSW5kaWNhdG9yLnBvc2l0aW9uLmNvcHkoaW50ZXJzZWN0aW9uc1swXS5wb2ludCk7XHJcbiAgICAgICAgdGhpcy5fdXBkYXRlU2hhZG93cyhpbnRlcnNlY3Rpb25zWzBdLnBvaW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdXBkYXRlU2hhZG93cyhjZW50ZXJQb3NpdGlvbjogVmVjdG9yMyk6IHZvaWQge1xyXG4gICAgdGhpcy5fc2hhZG93UGxhbmUucG9zaXRpb24uY29weShjZW50ZXJQb3NpdGlvbik7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChub2RlKSA9PiB7XHJcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgRGlyZWN0aW9uYWxMaWdodCkge1xyXG4gICAgICAgIG5vZGUudGFyZ2V0LnBvc2l0aW9uLmNvcHkoY2VudGVyUG9zaXRpb24pO1xyXG4gICAgICAgIG5vZGUuc2hhZG93LmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfYWRqdXN0TGlnaHRpbmcoZnJhbWUpOiB2b2lkIHtcclxuICAgIGNvbnN0IGxpZ2h0RXN0aW1hdGUgPSBmcmFtZS5nZXRMaWdodEVzdGltYXRlKHRoaXMuX2xpZ2h0UHJvYmUpO1xyXG5cclxuICAgIGlmIChsaWdodEVzdGltYXRlKSB7XHJcbiAgICAgIHRoaXMuX3RocmVlTGlnaHRQcm9iZS5zaC5mcm9tQXJyYXkobGlnaHRFc3RpbWF0ZS5zcGhlcmljYWxIYXJtb25pY3NDb2VmZmljaWVudHMpO1xyXG5cclxuICAgICAgY29uc3QgaW50ZW5zaXR5ID0gTWF0aC5tYXgoMS4wLFxyXG4gICAgICAgIE1hdGgubWF4KGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0SW50ZW5zaXR5LngsXHJcbiAgICAgICAgICBNYXRoLm1heChsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS55LFxyXG4gICAgICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS56KSkpO1xyXG5cclxuICAgICAgdGhpcy5fc3VuTGlnaHQucG9zaXRpb24uc2V0KGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0RGlyZWN0aW9uLngsXHJcbiAgICAgICAgbGlnaHRFc3RpbWF0ZS5wcmltYXJ5TGlnaHREaXJlY3Rpb24ueSxcclxuICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodERpcmVjdGlvbi56KTtcclxuICAgICAgdGhpcy5fc3VuTGlnaHQuY29sb3Iuc2V0UkdCKGxpZ2h0RXN0aW1hdGUucHJpbWFyeUxpZ2h0SW50ZW5zaXR5LnggLyBpbnRlbnNpdHksXHJcbiAgICAgICAgbGlnaHRFc3RpbWF0ZS5wcmltYXJ5TGlnaHRJbnRlbnNpdHkueSAvIGludGVuc2l0eSxcclxuICAgICAgICBsaWdodEVzdGltYXRlLnByaW1hcnlMaWdodEludGVuc2l0eS56IC8gaW50ZW5zaXR5KTtcclxuICAgICAgdGhpcy5fc3VuTGlnaHQuaW50ZW5zaXR5ID0gaW50ZW5zaXR5O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfdG9nZ2xlQVJNb2RlbFRyYW5zcGFyZW5jeSgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2FjdGl2ZUFSTW9kZWwudHJhdmVyc2UoKG5vZGUpID0+IHtcclxuICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgY29uc3QgbWF0ZXJpYWxzOiBhbnkgPSAhQXJyYXkuaXNBcnJheShub2RlLm1hdGVyaWFsKSA/IFtub2RlLm1hdGVyaWFsXSA6IG5vZGUubWF0ZXJpYWw7XHJcbiAgICAgICAgbWF0ZXJpYWxzLmZvckVhY2gobWF0ZXJpYWwgPT4ge1xyXG4gICAgICAgICAgbWF0ZXJpYWwudHJhbnNwYXJlbnQgPSB0aGlzLl9ob2xkaW5nVG91Y2g7XHJcbiAgICAgICAgICBtYXRlcmlhbC5vcGFjaXR5ID0gdGhpcy5faG9sZGluZ1RvdWNoID8gMC41IDogMTtcclxuICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9zZXRQbGFuZXNWaXNpYmlsdHkodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5fZGV0ZWN0ZWRQbGFuZXMuZm9yRWFjaCgocGxhbmUpID0+IHBsYW5lLnZpc2libGUgPSB2aXNpYmxlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldE9iamVjdEludGVyc2VjdGlvbnMob2JqZWN0czogT2JqZWN0M0RbXSkge1xyXG4gICAgdGhpcy5fdGVtcE1hdHJpeC5pZGVudGl0eSgpLmV4dHJhY3RSb3RhdGlvbih0aGlzLl9jb250cm9sbGVyLm1hdHJpeFdvcmxkKTtcclxuICAgIHRoaXMuX3JheWNhc3Rlci5yYXkub3JpZ2luLnNldEZyb21NYXRyaXhQb3NpdGlvbih0aGlzLl9jb250cm9sbGVyLm1hdHJpeFdvcmxkKTtcclxuICAgIHRoaXMuX3JheWNhc3Rlci5yYXkuZGlyZWN0aW9uLnNldCgwLCAwLCAtMSkuYXBwbHlNYXRyaXg0KHRoaXMuX3RlbXBNYXRyaXgpO1xyXG4gICAgcmV0dXJuIHRoaXMuX3JheWNhc3Rlci5pbnRlcnNlY3RPYmplY3RzKG9iamVjdHMpO1xyXG4gIH1cclxuXHJcbiAgLy8gVE9ETzogTmVlZHMgdG8gYmUgbWFkZSBjb21wYXRpYmxlIHdpdGggQnVmZmVyR2VvbWV0cnkgaWYgd2Ugd2FudCB0byBrZWVwIHBsYW5lIGRldGVjdGlvbiB2aXN1YWxpemF0aW9uXHJcbiAgcHJpdmF0ZSBfZHJhd1BsYW5lKHZlcnRpY2VzOiBBcnJheTxET01Qb2ludFJlYWRPbmx5PiwgcGxhbmVQb3NlKSB7XHJcbiAgICAvLyBjb25zdCBoaXRNYXRyaXggPSBuZXcgTWF0cml4NCgpLmZyb21BcnJheShwbGFuZVBvc2UudHJhbnNmb3JtLm1hdHJpeCk7XHJcbiAgICAvLyBjb25zdCBwb2ludEdyb3VwID0gbmV3IEdyb3VwKCk7XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gQ3JlYXRlIHZlcnRpY2VzXHJcbiAgICAvLyB2ZXJ0aWNlcy5mb3JFYWNoKCh2ZXJ0ZXgpID0+IHtcclxuICAgIC8vICAgaWYgKHRoaXMuX2RlYnVnKSB7XHJcbiAgICAvLyAgICAgY29uc3QgcG9pbnQgPSB0aGlzLl9wb2ludFJlcHJlc2VudGF0aW9uLmNsb25lKCk7XHJcbiAgICAvLyAgICAgcG9pbnQucG9zaXRpb24uc2V0KHZlcnRleC54LCAwLCB2ZXJ0ZXgueik7XHJcbiAgICAvLyAgICAgcG9pbnRHcm91cC5hZGQocG9pbnQpO1xyXG4gICAgLy8gICB9XHJcbiAgICAvLyAgIHRoaXMuX3ZlcnRleExpc3QucHVzaChuZXcgRE9NUG9pbnQodmVydGV4LngsIHZlcnRleC56KSk7XHJcbiAgICAvLyB9KTtcclxuICAgIC8vXHJcbiAgICAvLyBpZiAodGhpcy5fZGVidWcpIHtcclxuICAgIC8vICAgcG9pbnRHcm91cC5wb3NpdGlvbi5zZXRGcm9tTWF0cml4UG9zaXRpb24oaGl0TWF0cml4KTtcclxuICAgIC8vICAgdGhpcy5zY2VuZS5hZGQocG9pbnRHcm91cCk7XHJcbiAgICAvLyB9XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gR2VuZXJhdGUgcG9seWdvbiBmcm9tIHZlcnRpY2VzXHJcbiAgICAvLyBjb25zdCBodWxsID0gbWFrZUh1bGwodGhpcy5fdmVydGV4TGlzdCk7XHJcbiAgICAvLyBjb25zdCBnZW9tZXRyeSA9IG5ldyBCdWZmZXJHZW9tZXRyeSgpO1xyXG4gICAgLy8gY29uc3QgdmVjdG9yVHdvTGlzdCA9IGh1bGwubWFwKChwb2ludCkgPT4gbmV3IFZlY3RvcjIocG9pbnQueCwgcG9pbnQueSkpO1xyXG4gICAgLy8gY29uc3QgdmVjdG9yVGhyZWVMaXN0ID0gaHVsbC5tYXAoKHBvaW50KSA9PiBuZXcgVmVjdG9yMyhwb2ludC54LCB0aGlzLl9kZXRlY3RlZFBsYW5lcy5sZW5ndGggPiAwID8gdGhpcy5fZGV0ZWN0ZWRQbGFuZXNbMF0ucG9zaXRpb24ueSA6IDAsIHBvaW50LnkpKTtcclxuICAgIC8vIGNvbnN0IGZhY2VBcnJheSA9IFNoYXBlVXRpbHMudHJpYW5ndWxhdGVTaGFwZSh2ZWN0b3JUd29MaXN0LCBbXSk7XHJcbiAgICAvLyBnZW9tZXRyeS52ZXJ0aWNlcy5wdXNoKC4uLnZlY3RvclRocmVlTGlzdCk7XHJcbiAgICAvL1xyXG4gICAgLy8gLy8gR2VuZXJhdGUgZmFjZXNcclxuICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgZmFjZUFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAvLyAgIGdlb21ldHJ5LmZhY2VzLnB1c2gobmV3IFRIUkVFLkZhY2UzKGZhY2VBcnJheVtpXVswXSwgZmFjZUFycmF5W2ldWzFdLCBmYWNlQXJyYXlbaV1bMl0pKTtcclxuICAgIC8vIH1cclxuICAgIC8vIGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCk7XHJcbiAgICAvLyBnZW9tZXRyeS5ub3JtYWxpemUoKTtcclxuICAgIC8vXHJcbiAgICAvLyAvLyBHZW5lcmF0ZSBVVidzXHJcbiAgICAvLyBnZW9tZXRyeS5jb21wdXRlQm91bmRpbmdCb3goKTtcclxuICAgIC8vIGNvbnN0IG1heCA9IGdlb21ldHJ5LmJvdW5kaW5nQm94Lm1heCwgbWluID0gZ2VvbWV0cnkuYm91bmRpbmdCb3gubWluO1xyXG4gICAgLy8gY29uc3Qgb2Zmc2V0ID0gbmV3IFRIUkVFLlZlY3RvcjIoMCAtIG1pbi54LCAwIC0gbWluLnopO1xyXG4gICAgLy8gY29uc3QgcmFuZ2UgPSBuZXcgVEhSRUUuVmVjdG9yMihtYXgueCAtIG1pbi54LCBtYXgueiAtIG1pbi56KTtcclxuICAgIC8vIGNvbnN0IGZhY2VzID0gZ2VvbWV0cnkuZmFjZXM7XHJcbiAgICAvLyBnZW9tZXRyeS5mYWNlVmVydGV4VXZzWzBdID0gW107XHJcbiAgICAvL1xyXG4gICAgLy8gZm9yIChsZXQgaSA9IDA7IGkgPCBmYWNlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgLy8gICBjb25zdCB2MSA9IGdlb21ldHJ5LnZlcnRpY2VzW2ZhY2VzW2ldLmFdLFxyXG4gICAgLy8gICAgIHYyID0gZ2VvbWV0cnkudmVydGljZXNbZmFjZXNbaV0uYl0sXHJcbiAgICAvLyAgICAgdjMgPSBnZW9tZXRyeS52ZXJ0aWNlc1tmYWNlc1tpXS5jXTtcclxuICAgIC8vXHJcbiAgICAvLyAgIGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbMF0ucHVzaChbXHJcbiAgICAvLyAgICAgbmV3IFRIUkVFLlZlY3RvcjIoKHYxLnggKyBvZmZzZXQueCkgLyByYW5nZS54LCAodjEueiArIG9mZnNldC55KSAvIHJhbmdlLnkpLFxyXG4gICAgLy8gICAgIG5ldyBUSFJFRS5WZWN0b3IyKCh2Mi54ICsgb2Zmc2V0LngpIC8gcmFuZ2UueCwgKHYyLnogKyBvZmZzZXQueSkgLyByYW5nZS55KSxcclxuICAgIC8vICAgICBuZXcgVEhSRUUuVmVjdG9yMigodjMueCArIG9mZnNldC54KSAvIHJhbmdlLngsICh2My56ICsgb2Zmc2V0LnkpIC8gcmFuZ2UueSlcclxuICAgIC8vICAgXSk7XHJcbiAgICAvLyB9XHJcbiAgICAvLyBnZW9tZXRyeS51dnNOZWVkVXBkYXRlID0gdHJ1ZTtcclxuICAgIC8vXHJcbiAgICAvLyAvLyBDcmVhdGUgYW5kIHNldCBwbGFuZVxyXG4gICAgLy8gY29uc3QgbWVzaCA9IG5ldyBNZXNoKGdlb21ldHJ5LCB0aGlzLl9wbGFuZU1hdGVyaWFsKTtcclxuICAgIC8vIG1lc2gucG9zaXRpb24uc2V0RnJvbU1hdHJpeFBvc2l0aW9uKGhpdE1hdHJpeCk7XHJcbiAgICAvLyB0aGlzLl9kZXRlY3RlZFBsYW5lcy5wdXNoKG1lc2gpO1xyXG4gICAgLy8gdGhpcy5zY2VuZS5hZGQobWVzaCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9kcmF3UGxhbmVzKHhyRnJhbWUpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5fYWN0aXZlQVJNb2RlbC52aXNpYmxlKSB7XHJcbiAgICAgIGNvbnN0IHBsYW5lc0RldGVjdGVkID0geHJGcmFtZS53b3JsZEluZm9ybWF0aW9uLmRldGVjdGVkUGxhbmVzO1xyXG4gICAgICBpZiAocGxhbmVzRGV0ZWN0ZWQuc2l6ZSA+IDApIHtcclxuICAgICAgICBwbGFuZXNEZXRlY3RlZC5mb3JFYWNoKHBsYW5lID0+IHtcclxuICAgICAgICAgIGlmICghdGhpcy5fcmF3UGxhbmVzLmhhcyhwbGFuZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgcGxhbmVQb3NlID0geHJGcmFtZS5nZXRQb3NlKHBsYW5lLnBsYW5lU3BhY2UsIHRoaXMucmVmU3BhY2UpO1xyXG4gICAgICAgICAgICBpZiAocGxhbmVQb3NlKSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fcmF3UGxhbmVzLmFkZChwbGFuZSk7XHJcbiAgICAgICAgICAgICAgY29uc3QgcGxhbmVWZXJ0aWNlcyA9IHBsYW5lLnBvbHlnb247XHJcbiAgICAgICAgICAgICAgdGhpcy5fZHJhd1BsYW5lKHBsYW5lVmVydGljZXMsIHBsYW5lUG9zZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2FsbExpZnRBbmltYXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLl9hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNsb25lKCk7XHJcbiAgICBjb25zdCB0YXJnZXRQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueCwgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi55ICsgMC4yLCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopO1xyXG4gICAgdGhpcy5fbGlmdEFuaW1hdGlvbiA9IG5ldyBUV0VFTi5Ud2Vlbihwb3NpdGlvbilcclxuICAgICAgLnRvKHRhcmdldFBvc2l0aW9uLCA1MDApXHJcbiAgICAgIC5lYXNpbmcoVFdFRU4uRWFzaW5nLlF1YWRyYXRpYy5PdXQpXHJcbiAgICAgIC5vblVwZGF0ZSgoKSA9PiB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobmV3IFZlY3RvcjModGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi54LCBwb3NpdGlvbi55LCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopKSlcclxuICAgICAgLm9uQ29tcGxldGUoKCkgPT4gdGhpcy5fYW5pbWF0aW5nID0gZmFsc2UpO1xyXG4gICAgdGhpcy5fbGlmdEFuaW1hdGlvbi5zdGFydCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2FsbERyb3BBbmltYXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLl9hbmltYXRpbmcgPSB0cnVlO1xyXG4gICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNsb25lKCk7XHJcbiAgICBjb25zdCB0YXJnZXRQb3NpdGlvbiA9IG5ldyBWZWN0b3IzKHRoaXMuX2FjdGl2ZUFSTW9kZWwucG9zaXRpb24ueCwgdGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi55IC0gMC4yLCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopO1xyXG4gICAgdGhpcy5fZHJvcEFuaW1hdGlvbiA9IG5ldyBUV0VFTi5Ud2Vlbihwb3NpdGlvbilcclxuICAgICAgLnRvKHRhcmdldFBvc2l0aW9uLCA1MDApXHJcbiAgICAgIC5lYXNpbmcoVFdFRU4uRWFzaW5nLlF1YWRyYXRpYy5PdXQpXHJcbiAgICAgIC5vblVwZGF0ZSgoKSA9PiB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLmNvcHkobmV3IFZlY3RvcjModGhpcy5fYWN0aXZlQVJNb2RlbC5wb3NpdGlvbi54LCBwb3NpdGlvbi55LCB0aGlzLl9hY3RpdmVBUk1vZGVsLnBvc2l0aW9uLnopKSlcclxuICAgICAgLm9uQ29tcGxldGUoKCkgPT4gdGhpcy5fYW5pbWF0aW5nID0gZmFsc2UpO1xyXG4gICAgdGhpcy5fZHJvcEFuaW1hdGlvbi5zdGFydCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY3JlYXRlQXVnbWVudGVkTWF0ZXJpYWwobWF0ZXJpYWw6IE1hdGVyaWFsIHwgU2hhZG93TWF0ZXJpYWwsIGRlcHRoTWFwKSB7XHJcbiAgICBtYXRlcmlhbC51c2VyRGF0YSA9IHtcclxuICAgICAgdURlcHRoVGV4dHVyZToge3ZhbHVlOiBkZXB0aE1hcH0sXHJcbiAgICAgIHVXaWR0aDoge3ZhbHVlOiAxLjB9LFxyXG4gICAgICB1SGVpZ2h0OiB7dmFsdWU6IDEuMH0sXHJcbiAgICAgIHVVdlRyYW5zZm9ybToge3ZhbHVlOiBuZXcgTWF0cml4NCgpfSxcclxuICAgICAgdU9jY2x1c2lvbkVuYWJsZWQ6IHt2YWx1ZTogdHJ1ZX1cclxuICAgIH07XHJcblxyXG4gICAgbWF0ZXJpYWwudXNlckRhdGEuaXNBZ3VtZW50ZWRNYXRlcmlhbCA9IHRydWU7XHJcblxyXG4gICAgbWF0ZXJpYWwub25CZWZvcmVDb21waWxlID0gKHNoYWRlcikgPT4ge1xyXG4gICAgICAvLyBQYXNzIHVuaWZvcm1zIGZyb20gdXNlckRhdGEgdG8gdGhlXHJcbiAgICAgIGZvciAoY29uc3QgaSBpbiBtYXRlcmlhbC51c2VyRGF0YSkge1xyXG4gICAgICAgIHNoYWRlci51bmlmb3Jtc1tpXSA9IG1hdGVyaWFsLnVzZXJEYXRhW2ldO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBGcmFnbWVudCB2YXJpYWJsZXNcclxuICAgICAgc2hhZGVyLmZyYWdtZW50U2hhZGVyID0gYFxyXG5cdFx0XHR1bmlmb3JtIHNhbXBsZXIyRCB1RGVwdGhUZXh0dXJlO1xyXG5cdFx0XHR1bmlmb3JtIGZsb2F0IHVXaWR0aDtcclxuXHRcdFx0dW5pZm9ybSBmbG9hdCB1SGVpZ2h0O1xyXG5cdFx0XHR1bmlmb3JtIG1hdDQgdVV2VHJhbnNmb3JtO1xyXG5cdFx0XHR1bmlmb3JtIGJvb2wgdU9jY2x1c2lvbkVuYWJsZWQ7XHJcblx0XHRcdHZhcnlpbmcgZmxvYXQgdkRlcHRoO1xyXG5cdFx0XHRgICsgc2hhZGVyLmZyYWdtZW50U2hhZGVyO1xyXG5cclxuXHJcbiAgICAgIGxldCBmcmFnbWVudEVudHJ5UG9pbnQgPSAnI2luY2x1ZGUgPGNsaXBwaW5nX3BsYW5lc19mcmFnbWVudD4nO1xyXG4gICAgICBpZiAobWF0ZXJpYWwgaW5zdGFuY2VvZiBTaGFkb3dNYXRlcmlhbCkge1xyXG4gICAgICAgIGZyYWdtZW50RW50cnlQb2ludCA9ICcjaW5jbHVkZSA8Zm9nX2ZyYWdtZW50Pic7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEZyYWdtZW50IGRlcHRoIGxvZ2ljXHJcbiAgICAgIHNoYWRlci5mcmFnbWVudFNoYWRlciA9IHNoYWRlci5mcmFnbWVudFNoYWRlci5yZXBsYWNlKCd2b2lkIG1haW4nLFxyXG4gICAgICAgIGBmbG9hdCBnZXREZXB0aEluTWlsbGltZXRlcnMoaW4gc2FtcGxlcjJEIGRlcHRoVGV4dCwgaW4gdmVjMiB1dilcclxuXHRcdFx0e1xyXG5cdFx0XHRcdHZlYzIgcGFja2VkRGVwdGggPSB0ZXh0dXJlMkQoZGVwdGhUZXh0LCB1dikucmE7XHJcblx0XHRcdFx0cmV0dXJuIGRvdChwYWNrZWREZXB0aCwgdmVjMigyNTUuMCwgNjUyODAuMCkpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZvaWQgbWFpbmApO1xyXG5cclxuXHJcbiAgICAgIHNoYWRlci5mcmFnbWVudFNoYWRlciA9IHNoYWRlci5mcmFnbWVudFNoYWRlci5yZXBsYWNlKGZyYWdtZW50RW50cnlQb2ludCwgYFxyXG5cdFx0XHQke2ZyYWdtZW50RW50cnlQb2ludH1cclxuXHRcdFx0XHQvLyBOb3JtYWxpemUgeCwgeSB0byByYW5nZSBbMCwgMV1cclxuXHRcdFx0XHRmbG9hdCB4ID0gZ2xfRnJhZ0Nvb3JkLnggLyB1V2lkdGg7XHJcblx0XHRcdFx0ZmxvYXQgeSA9IGdsX0ZyYWdDb29yZC55IC8gdUhlaWdodDtcclxuXHRcdFx0XHR2ZWMyIHRleENvb3JkID0gKHVVdlRyYW5zZm9ybSAqIHZlYzQoeCwgMS4wIC0geSwgMC4wLCAxLjApKS54eTtcclxuXHRcdFx0XHRmbG9hdCBkZXB0aCA9IGdldERlcHRoSW5NaWxsaW1ldGVycyh1RGVwdGhUZXh0dXJlLCB0ZXhDb29yZCkgLyAxMDAwLjA7XHJcblx0XHRcdFx0aWYgKGRlcHRoIDwgdkRlcHRoKVxyXG5cdFx0XHRcdHtcclxuXHRcdFx0XHRcdGRpc2NhcmQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRgKTtcclxuXHJcbiAgICAgIC8vIFZlcnRleCB2YXJpYWJsZXNcclxuICAgICAgc2hhZGVyLnZlcnRleFNoYWRlciA9IGBcclxuXHRcdFx0dmFyeWluZyBmbG9hdCB2RGVwdGg7XHJcblx0XHRcdGAgKyBzaGFkZXIudmVydGV4U2hhZGVyO1xyXG5cclxuICAgICAgLy8gVmVydGV4IGRlcHRoIGxvZ2ljXHJcbiAgICAgIHNoYWRlci52ZXJ0ZXhTaGFkZXIgPSBzaGFkZXIudmVydGV4U2hhZGVyLnJlcGxhY2UoJyNpbmNsdWRlIDxmb2dfdmVydGV4PicsIGBcclxuXHRcdFx0I2luY2x1ZGUgPGZvZ192ZXJ0ZXg+XHJcblx0XHRcdHZEZXB0aCA9IGdsX1Bvc2l0aW9uLno7XHJcblx0XHRcdGApO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gbWF0ZXJpYWw7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF91cGRhdGVBdWdtZW50ZWRNYXRlcmlhbFVuaWZvcm1zKG5vcm1UZXh0dXJlRnJvbU5vcm1WaWV3TWF0cml4KSB7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChjaGlsZCkgPT4ge1xyXG4gICAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiBNZXNoICYmIGNoaWxkLm1hdGVyaWFsKSB7XHJcbiAgICAgICAgaWYgKGNoaWxkLm1hdGVyaWFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgIGZvciAoY29uc3QgbWF0ZXJpYWwgb2YgY2hpbGQubWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgaWYgKG1hdGVyaWFsLnVzZXJEYXRhLmlzQWd1bWVudGVkTWF0ZXJpYWwpIHtcclxuICAgICAgICAgICAgICBtYXRlcmlhbC51c2VyRGF0YS51V2lkdGgudmFsdWUgPSBNYXRoLmZsb29yKERldmljZVV0aWxzLkdldFBpeGVsUmF0aW8oKSAqIHdpbmRvdy5pbm5lcldpZHRoKTtcclxuICAgICAgICAgICAgICBtYXRlcmlhbC51c2VyRGF0YS51SGVpZ2h0LnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJIZWlnaHQpO1xyXG4gICAgICAgICAgICAgIG1hdGVyaWFsLnVzZXJEYXRhLnVVdlRyYW5zZm9ybS52YWx1ZS5mcm9tQXJyYXkobm9ybVRleHR1cmVGcm9tTm9ybVZpZXdNYXRyaXgpO1xyXG4gICAgICAgICAgICAgIG1hdGVyaWFsLm5lZWRzVXBkYXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAoY2hpbGQudXNlckRhdGEuaXNBZ3VtZW50ZWRNYXRlcmlhbCkge1xyXG4gICAgICAgICAgY2hpbGQubWF0ZXJpYWwudXNlckRhdGEudVdpZHRoLnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJXaWR0aCk7XHJcbiAgICAgICAgICBjaGlsZC5tYXRlcmlhbC51c2VyRGF0YS51SGVpZ2h0LnZhbHVlID0gTWF0aC5mbG9vcihEZXZpY2VVdGlscy5HZXRQaXhlbFJhdGlvKCkgKiB3aW5kb3cuaW5uZXJIZWlnaHQpO1xyXG4gICAgICAgICAgY2hpbGQubWF0ZXJpYWwudXNlckRhdGEudVV2VHJhbnNmb3JtLnZhbHVlLmZyb21BcnJheShub3JtVGV4dHVyZUZyb21Ob3JtVmlld01hdHJpeCk7XHJcbiAgICAgICAgICBjaGlsZC5tYXRlcmlhbC5uZWVkc1VwZGF0ZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3VwZGF0ZU1lc2hNYXRlcmlhbHMoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNjZW5lLnRyYXZlcnNlKChvYmplY3QpID0+IHtcclxuICAgICAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIE1lc2gpIHtcclxuICAgICAgICBpZiAob2JqZWN0Lm1hdGVyaWFsIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgIGZvciAobGV0IG1hdGVyaWFsIG9mIG9iamVjdC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbCA9IHRoaXMuX2NyZWF0ZUF1Z21lbnRlZE1hdGVyaWFsKG1hdGVyaWFsLCB0aGlzLl9kZXB0aERhdGFUZXh0dXJlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2JqZWN0Lm1hdGVyaWFsID0gdGhpcy5fY3JlYXRlQXVnbWVudGVkTWF0ZXJpYWwob2JqZWN0Lm1hdGVyaWFsLCB0aGlzLl9kZXB0aERhdGFUZXh0dXJlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfcmVtb3ZlTWF0ZXJpYWxTaGFkZXJzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zY2VuZS50cmF2ZXJzZSgob2JqZWN0KSA9PiB7XHJcbiAgICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNZXNoKSB7XHJcbiAgICAgICAgaWYgKG9iamVjdC5tYXRlcmlhbCBpbnN0YW5jZW9mIEFycmF5KSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IG1hdGVyaWFsIG9mIG9iamVjdC5tYXRlcmlhbCkge1xyXG4gICAgICAgICAgICBtYXRlcmlhbC5vbkJlZm9yZUNvbXBpbGUgPSAoc2hhZGVyKSA9PiB7XHJcbiAgICAgICAgICAgICAgc2hhZGVyID0gbnVsbDtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2JqZWN0Lm1hdGVyaWFsLm9uQmVmb3JlQ29tcGlsZSA9IChzaGFkZXIpID0+IHtcclxuICAgICAgICAgICAgc2hhZGVyID0gbnVsbDtcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2NoZWNraW5nSW50ZXJmYWNlSW50ZXJhY3Rpb24oZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy51c2VySW5TZWxlY3Rpb25NZW51ID0gZXZlbnQucGF0aC5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeS5sb2NhbE5hbWUgPT09ICdhci1ndWktY29uZmlndXJhdG9yJykubGVuZ3RoID4gMDtcclxuICB9XHJcbn1cclxuIl19
|