import { createHotContext as __vite__createHotContext } from "/_nuxt/@vite/client";import.meta.hot = __vite__createHotContext("/components/viewer/elements/Panel.vue");import { default as __nuxt_component_0 } from "/_nuxt/components/viewer/SearchInput.vue"; import { CommonBadge as __nuxt_component_1 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js"; import { default as __nuxt_component_2 } from "/_nuxt/components/viewer/layout/SidePanel.vue"; /* Injection by vite-plugin-vue-inspector Start */ import { createElementVNode as __createElementVNode,createVNode as __createVNode,createElementBlock as __createElementBlock,createBlock as __createBlock } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29" function _interopVNode(vnode) { if (vnode && vnode.props && 'data-v-inspector' in vnode.props) { const data = vnode.props['data-v-inspector'] delete vnode.props['data-v-inspector'] Object.defineProperty(vnode.props, '__v_inspector', { value: data, enumerable: false }) } return vnode } function _createElementVNode(...args) { return _interopVNode(__createElementVNode(...args)) } function _createVNode(...args) { return _interopVNode(__createVNode(...args)) } function _createElementBlock(...args) { return _interopVNode(__createElementBlock(...args)) } function _createBlock(...args) { return _interopVNode(__createBlock(...args)) } /* Injection by vite-plugin-vue-inspector End */ import { defineComponent as _defineComponent } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; import { CameraController, FilteringExtension, SelectionExtension } from "/_nuxt/@fs/D:/speckle-server/packages/viewer/dist/index.js"; import { FormButton } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js"; import { Layers, Paintbrush, RotateCcw, Search, X } from "/_nuxt/node_modules/.cache/vite/client/deps/lucide-vue-next.js?v=e4f18c29"; import { uniq } from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29"; import { getTargetObjectIds } from "/_nuxt/lib/object-sidebar/helpers.ts"; import { useFilterUtilities } from "/_nuxt/lib/viewer/composables/filtering/filtering.ts"; import { useInjectedViewerState, useInjectedViewerInterfaceState } from "/_nuxt/lib/viewer/composables/setup.ts"; import { useSelectionUtilities } from "/_nuxt/lib/viewer/composables/ui.ts"; import { ref, shallowRef, computed } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; const MAX_RESULTS = 50; const _sfc_main = /* @__PURE__ */ _defineComponent({ __name: "ViewerElementsPanel", setup(__props, { expose: __expose }) { __expose(); const GUID_KEYS = /* @__PURE__ */ new Set([ "id", "uuid", "name", "applicationid", "guid", "sourceguid", "ifcguid", "ifcelementguid", "ifcelementsourceguid", "ifcelementassemblyguid", "ifcelementassemblysourceguid", "globalid", "expressid", "ifcexpressid" ]); const SKIP_KEYS = /* @__PURE__ */ new Set([ "vertices", "faces", "colors", "displayvalue", "displayvalues", "geometry", "matrix", "matrixworld", "children", "parent" ]); const { viewer: { instance } } = useInjectedViewerState(); const { filters: { isolatedObjectIds } } = useInjectedViewerInterfaceState(); const { objects: selectedObjects, setSelectionFromObjectIds } = useSelectionUtilities(); const { isolateObjects, resetIsolations } = useFilterUtilities(); const guidQuery = ref(""); const searchMessage = ref(""); const searchResults = shallowRef([]); const selectedResultKey = ref(null); const selectionColor = ref("#047efb"); const paintedGroups = shallowRef([]); const hasPaint = computed(() => paintedGroups.value.length > 0); const hasSelection = computed(() => selectedTargetIds.value.length > 0); const hasIsolation = computed(() => isolatedObjectIds.value.length > 0); const selectedTargetIds = computed( () => uniq( selectedObjects.value.flatMap( (obj) => getTargetObjectIds(obj) ) ) ); const onSearchKeydown = (event) => { if (event.key === "Enter") searchGuid(); }; const normalize = (value) => String(value ?? "").trim().toLowerCase(); const getRecord = (value) => value && typeof value === "object" ? value : {}; const getString = (value) => typeof value === "string" && value.length > 0 ? value : void 0; const collectSearchCandidates = (value, depth = 0) => { if (value === null || value === void 0 || depth > 3) return []; if (["string", "number", "boolean"].includes(typeof value)) { const text = String(value).trim(); return text ? [text] : []; } if (Array.isArray(value)) { if (value.length > 20) return []; return value.flatMap((item) => collectSearchCandidates(item, depth + 1)); } if (typeof value !== "object") return []; const candidates = []; for (const [key, childValue] of Object.entries(value)) { const normalizedKey = key.toLowerCase(); if (SKIP_KEYS.has(normalizedKey)) continue; if (GUID_KEYS.has(normalizedKey) || normalizedKey.includes("guid") || normalizedKey.includes("globalid")) { candidates.push(...collectSearchCandidates(childValue, depth + 1)); continue; } if (normalizedKey === "properties" || normalizedKey === "parameters" || normalizedKey === "userdata") { candidates.push(...collectSearchCandidates(childValue, depth + 1)); } } return candidates; }; const getNodeGuid = (node) => { return getNodeGuidCandidates(node)[0]; }; const getNodeGuidCandidates = (node) => { const raw = node.model.raw; const userData = getRecord(raw.userData); const candidates = [ raw.ifcElementAssemblySourceGuid, raw.ifcElementSourceGuid, raw.sourceGuid, raw.ifcElementAssemblyGuid, raw.ifcElementGuid, raw.ifcGuid, raw.guid, raw.globalId, raw.GlobalId, raw.applicationId, userData?.ifcElementAssemblySourceGuid, userData?.ifcElementSourceGuid, userData?.sourceGuid, userData?.ifcElementAssemblyGuid, userData?.ifcElementGuid, userData?.ifcGuid, userData?.guid, userData?.globalId, userData?.GlobalId, userData?.applicationId ]; return uniq(candidates.map(getString).filter((value) => !!value)); }; const getNodeLabel = (node, guid) => { const raw = node.model.raw; return typeof raw.name === "string" && raw.name || typeof raw.type === "string" && raw.type || guid || node.model.id; }; const upsertSearchResult = (groups, node) => { const raw = node.model.raw; const guid = getNodeGuid(node); const key = guid || node.model.id; const existing = groups.get(key); const ids = getTargetObjectIds(raw); const nodeIds = ids.length ? ids : typeof node.model.id === "string" ? [node.model.id] : []; if (!nodeIds.length) return; if (existing) { existing.ids = uniq([...existing.ids, ...nodeIds]); return; } groups.set(key, { key, guid, ids: nodeIds, label: getNodeLabel(node, guid) }); }; const findGuidMatches = (query) => { const exact = /* @__PURE__ */ new Map(); const partial = /* @__PURE__ */ new Map(); const normalizedQuery = normalize(query); instance.getWorldTree().walk((node) => { if (!node.model.raw || node.model.id === "ROOT") return true; const candidates = uniq([ ...getNodeGuidCandidates(node), ...collectSearchCandidates(node.model.raw) ]); if (!candidates.length) return true; const normalizedCandidates = candidates.map(normalize); if (normalizedCandidates.some((candidate) => candidate === normalizedQuery)) { upsertSearchResult(exact, node); return true; } if (normalizedCandidates.some((candidate) => candidate.includes(normalizedQuery))) { upsertSearchResult(partial, node); } return true; }); return Array.from((exact.size ? exact : partial).values()).slice(0, MAX_RESULTS); }; const searchGuid = () => { const query = guidQuery.value.trim(); selectedResultKey.value = null; if (!query) { searchResults.value = []; searchMessage.value = ""; return; } const results = findGuidMatches(query); searchResults.value = results; searchMessage.value = results.length ? `${results.length} found` : "No match"; if (results.length === 1) selectSearchResult(results[0]); }; const selectSearchResult = (result) => { selectedResultKey.value = result.key; setSelectionFromObjectIds(result.ids); instance.getExtension(CameraController).setCameraView(result.ids, true); }; const parseColor = (color) => Number.parseInt(color.replace("#", ""), 16); const refreshViewerSelection = () => { const ids = selectedTargetIds.value; const extension = instance.getExtension(SelectionExtension); extension.clearSelection(); if (ids.length) extension.selectObjects(ids); }; const applySelectionOverlayColor = () => { const extension = instance.getExtension(SelectionExtension); extension.options = { ...extension.options, selectionMaterialData: { ...extension.options.selectionMaterialData, color: parseColor(selectionColor.value) } }; refreshViewerSelection(); }; const paintSelectedObjects = () => { const ids = selectedTargetIds.value; if (!ids.length) return; paintedGroups.value = [ ...paintedGroups.value, { objectIds: ids, color: selectionColor.value } ]; instance.getExtension(FilteringExtension).setUserObjectColors(paintedGroups.value); refreshViewerSelection(); }; const clearPaint = () => { paintedGroups.value = []; instance.getExtension(FilteringExtension).removeUserObjectColors(); refreshViewerSelection(); }; const ghostIsolateSelection = () => { const ids = selectedTargetIds.value; if (!ids.length) return; isolateObjects(ids, { replace: true }); instance.getExtension(CameraController).setCameraView(ids, true); }; const __returned__ = { MAX_RESULTS, GUID_KEYS, SKIP_KEYS, instance, isolatedObjectIds, selectedObjects, setSelectionFromObjectIds, isolateObjects, resetIsolations, guidQuery, searchMessage, searchResults, selectedResultKey, selectionColor, paintedGroups, hasPaint, hasSelection, hasIsolation, selectedTargetIds, onSearchKeydown, normalize, getRecord, getString, collectSearchCandidates, getNodeGuid, getNodeGuidCandidates, getNodeLabel, upsertSearchResult, findGuidMatches, searchGuid, selectSearchResult, parseColor, refreshViewerSelection, applySelectionOverlayColor, paintSelectedObjects, clearPaint, ghostIsolateSelection, get FormButton() { return FormButton; }, get Layers() { return Layers; }, get Paintbrush() { return Paintbrush; }, get RotateCcw() { return RotateCcw; }, get Search() { return Search; }, get X() { return X; } }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }); import { resolveComponent as _resolveComponent, createTextVNode as _createTextVNode, withCtx as _withCtx, toDisplayString as _toDisplayString, openBlock as _openBlock, createCommentVNode as _createCommentVNode, renderList as _renderList, Fragment as _Fragment, normalizeClass as _normalizeClass, vModelText as _vModelText, withDirectives as _withDirectives } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29"; const _hoisted_1 = { class: "flex flex-col gap-3 p-3", "data-v-inspector": "components/viewer/elements/Panel.vue:7:5" }; const _hoisted_2 = { class: "flex flex-col gap-2", "data-v-inspector": "components/viewer/elements/Panel.vue:8:7" }; const _hoisted_3 = { class: "flex gap-1.5", "data-v-inspector": "components/viewer/elements/Panel.vue:12:9" }; const _hoisted_4 = { key: 0, class: "text-body-3xs text-foreground-2", "data-v-inspector": "components/viewer/elements/Panel.vue:30:9" }; const _hoisted_5 = { key: 1, class: "flex flex-col gap-1", "data-v-inspector": "components/viewer/elements/Panel.vue:34:9" }; const _hoisted_6 = ["onClick"]; const _hoisted_7 = { class: "min-w-0", "data-v-inspector": "components/viewer/elements/Panel.vue:42:13" }; const _hoisted_8 = { class: "block truncate font-medium text-foreground", "data-v-inspector": "components/viewer/elements/Panel.vue:43:15" }; const _hoisted_9 = { class: "block truncate text-foreground-2", "data-v-inspector": "components/viewer/elements/Panel.vue:46:15" }; const _hoisted_10 = { class: "flex flex-col gap-2 border-t border-outline-3 pt-3", "data-v-inspector": "components/viewer/elements/Panel.vue:57:7" }; const _hoisted_11 = { class: "flex items-center justify-between gap-2", "data-v-inspector": "components/viewer/elements/Panel.vue:58:9" }; const _hoisted_12 = { class: "grid grid-cols-2 gap-1.5", "data-v-inspector": "components/viewer/elements/Panel.vue:70:9" }; const _hoisted_13 = { class: "flex flex-col gap-2 border-t border-outline-3 pt-3", "data-v-inspector": "components/viewer/elements/Panel.vue:92:7" }; const _hoisted_14 = { class: "grid grid-cols-2 gap-1.5", "data-v-inspector": "components/viewer/elements/Panel.vue:93:9" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_ViewerSearchInput = __nuxt_component_0; const _component_CommonBadge = __nuxt_component_1; const _component_ViewerLayoutSidePanel = __nuxt_component_2; return _openBlock(), _createBlock(_component_ViewerLayoutSidePanel, { "data-v-inspector": "components/viewer/elements/Panel.vue:2:3" }, { title: _withCtx(() => [..._cache[2] || (_cache[2] = [ _createElementVNode( "span", { "data-v-inspector": "components/viewer/elements/Panel.vue:4:7" }, "Elements", -1 /* CACHED */ ) ])]), default: _withCtx(() => [ _createElementVNode("div", _hoisted_1, [ _createElementVNode("section", _hoisted_2, [ _cache[4] || (_cache[4] = _createElementVNode( "label", { class: "text-body-3xs font-medium text-foreground-2", for: "ifc-guid-search", "data-v-inspector": "components/viewer/elements/Panel.vue:9:9" }, " GUID ", -1 /* CACHED */ )), _createElementVNode("div", _hoisted_3, [ _createVNode(_component_ViewerSearchInput, { id: "ifc-guid-search", modelValue: $setup.guidQuery, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.guidQuery = $event), placeholder: "GlobalId / GUID", onKeydown: $setup.onSearchKeydown, "data-v-inspector": "components/viewer/elements/Panel.vue:13:11" }, null, 8, ["modelValue"]), _createVNode($setup["FormButton"], { "hide-text": "", size: "sm", color: "outline", "icon-left": $setup.Search, onClick: $setup.searchGuid, "data-v-inspector": "components/viewer/elements/Panel.vue:19:11" }, { default: _withCtx(() => [..._cache[3] || (_cache[3] = [ _createTextVNode( " Search ", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }, 8, ["icon-left"]) ]), $setup.searchMessage ? (_openBlock(), _createElementBlock( "p", _hoisted_4, _toDisplayString($setup.searchMessage), 1 /* TEXT */ )) : _createCommentVNode("v-if", true), $setup.searchResults.length ? (_openBlock(), _createElementBlock("div", _hoisted_5, [ (_openBlock(true), _createElementBlock( _Fragment, null, _renderList($setup.searchResults, (result) => { return _openBlock(), _createElementBlock("button", { key: result.key, class: _normalizeClass(["flex min-h-8 w-full items-center justify-between rounded border border-outline-3 px-2 py-1 text-left text-body-3xs hover:bg-highlight-2", $setup.selectedResultKey === result.key ? "bg-highlight-2" : ""]), onClick: ($event) => $setup.selectSearchResult(result), "data-v-inspector": "components/viewer/elements/Panel.vue:35:11" }, [ _createElementVNode("span", _hoisted_7, [ _createElementVNode( "span", _hoisted_8, _toDisplayString(result.label), 1 /* TEXT */ ), _createElementVNode( "span", _hoisted_9, _toDisplayString(result.guid || result.key), 1 /* TEXT */ ) ]), result.ids.length > 1 ? (_openBlock(), _createBlock( _component_CommonBadge, { key: 0, rounded: "", "data-v-inspector": "components/viewer/elements/Panel.vue:50:13" }, { default: _withCtx(() => [ _createTextVNode( _toDisplayString(result.ids.length), 1 /* TEXT */ ) ]), _: 2 /* DYNAMIC */ }, 1024 /* DYNAMIC_SLOTS */ )) : _createCommentVNode("v-if", true) ], 10, _hoisted_6); }), 128 /* KEYED_FRAGMENT */ )) ])) : _createCommentVNode("v-if", true) ]), _createElementVNode("section", _hoisted_10, [ _createElementVNode("div", _hoisted_11, [ _cache[5] || (_cache[5] = _createElementVNode( "label", { class: "text-body-3xs font-medium text-foreground-2", for: "selection-color", "data-v-inspector": "components/viewer/elements/Panel.vue:59:11" }, " Selection color ", -1 /* CACHED */ )), _withDirectives(_createElementVNode( "input", { id: "selection-color", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $setup.selectionColor = $event), class: "h-7 w-10 rounded border border-outline-3 bg-foundation", type: "color", onInput: $setup.applySelectionOverlayColor, "data-v-inspector": "components/viewer/elements/Panel.vue:62:11" }, null, 544 /* NEED_HYDRATION, NEED_PATCH */ ), [ [_vModelText, $setup.selectionColor] ]) ]), _createElementVNode("div", _hoisted_12, [ _createVNode($setup["FormButton"], { size: "sm", color: "outline", disabled: !$setup.hasSelection, "icon-left": $setup.Paintbrush, onClick: $setup.paintSelectedObjects, "data-v-inspector": "components/viewer/elements/Panel.vue:71:11" }, { default: _withCtx(() => [..._cache[6] || (_cache[6] = [ _createTextVNode( " Paint ", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }, 8, ["disabled", "icon-left"]), _createVNode($setup["FormButton"], { size: "sm", color: "subtle", disabled: !$setup.hasPaint, "icon-left": $setup.RotateCcw, onClick: $setup.clearPaint, "data-v-inspector": "components/viewer/elements/Panel.vue:80:11" }, { default: _withCtx(() => [..._cache[7] || (_cache[7] = [ _createTextVNode( " Clear ", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }, 8, ["disabled", "icon-left"]) ]) ]), _createElementVNode("section", _hoisted_13, [ _createElementVNode("div", _hoisted_14, [ _createVNode($setup["FormButton"], { size: "sm", color: "outline", disabled: !$setup.hasSelection, "icon-left": $setup.Layers, onClick: $setup.ghostIsolateSelection, "data-v-inspector": "components/viewer/elements/Panel.vue:94:11" }, { default: _withCtx(() => [..._cache[8] || (_cache[8] = [ _createTextVNode( " Ghost ", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }, 8, ["disabled", "icon-left"]), _createVNode($setup["FormButton"], { size: "sm", color: "subtle", disabled: !$setup.hasIsolation, "icon-left": $setup.X, onClick: $setup.resetIsolations, "data-v-inspector": "components/viewer/elements/Panel.vue:103:11" }, { default: _withCtx(() => [..._cache[9] || (_cache[9] = [ _createTextVNode( " Reset ", -1 /* CACHED */ ) ])]), _: 1 /* STABLE */ }, 8, ["disabled", "icon-left", "onClick"]) ]) ]) ]) ]), _: 1 /* STABLE */ }); } _sfc_main.__hmrId = "5c410b27"; typeof __VUE_HMR_RUNTIME__ !== "undefined" && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main); import.meta.hot.on("file-changed", ({ file }) => { __VUE_HMR_RUNTIME__.CHANGED_FILE = file; }); import.meta.hot.accept((mod) => { if (!mod) return; const { default: updated, _rerender_only } = mod; if (_rerender_only) { __VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render); } else { __VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated); } }); import _export_sfc from "/_nuxt/@id/__x00__plugin-vue:export-helper"; export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "D:/speckle-server/packages/frontend-2/components/viewer/elements/Panel.vue"]]); //# sourceMappingURL=data:application/json;base64,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Ozs7WUFDQSxhQVFhO0FBQUEsY0FQWCxNQUFLO0FBQUEsY0FDTCxPQUFNO0FBQUEsY0FDTCxVQUFRLENBQUc7QUFBQSxjQUNYLGFBQVc7QUFBQSxjQUNYLFNBQU87QUFBQSxjQUFpQixvQkFBaUI7QUFBQTtnQ0FDM0MsTUFFRDtBQUFBO2tCQUZDO0FBQUEsa0JBRUQ7QUFBQTtBQUFBO0FBQUEiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbIlBhbmVsLnZ1ZSJdLCJzb3VyY2VzQ29udGVudCI6WyI8dGVtcGxhdGU+XG4gIDxWaWV3ZXJMYXlvdXRTaWRlUGFuZWwgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZToyOjNcIj5cbiAgICA8dGVtcGxhdGUgI3RpdGxlPlxuICAgICAgPHNwYW4gZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo0OjdcIj5FbGVtZW50czwvc3Bhbj5cbiAgICA8L3RlbXBsYXRlPlxuXG4gICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTMgcC0zXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo3OjVcIj5cbiAgICAgIDxzZWN0aW9uIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMlwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6ODo3XCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtYm9keS0zeHMgZm9udC1tZWRpdW0gdGV4dC1mb3JlZ3JvdW5kLTJcIiBmb3I9XCJpZmMtZ3VpZC1zZWFyY2hcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjk6OVwiPlxuICAgICAgICAgIEdVSURcbiAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZ2FwLTEuNVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6MTI6OVwiPlxuICAgICAgICAgIDxWaWV3ZXJTZWFyY2hJbnB1dFxuICAgICAgICAgICAgaWQ9XCJpZmMtZ3VpZC1zZWFyY2hcIlxuICAgICAgICAgICAgdi1tb2RlbD1cImd1aWRRdWVyeVwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkdsb2JhbElkIC8gR1VJRFwiXG4gICAgICAgICAgICBAa2V5ZG93bj1cIm9uU2VhcmNoS2V5ZG93blwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6MTM6MTFcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPEZvcm1CdXR0b25cbiAgICAgICAgICAgIGhpZGUtdGV4dFxuICAgICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICAgIGNvbG9yPVwib3V0bGluZVwiXG4gICAgICAgICAgICA6aWNvbi1sZWZ0PVwiU2VhcmNoXCJcbiAgICAgICAgICAgIEBjbGljaz1cInNlYXJjaEd1aWRcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjE5OjExXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBTZWFyY2hcbiAgICAgICAgICA8L0Zvcm1CdXR0b24+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxwIHYtaWY9XCJzZWFyY2hNZXNzYWdlXCIgY2xhc3M9XCJ0ZXh0LWJvZHktM3hzIHRleHQtZm9yZWdyb3VuZC0yXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTozMDo5XCI+XG4gICAgICAgICAge3sgc2VhcmNoTWVzc2FnZSB9fVxuICAgICAgICA8L3A+XG5cbiAgICAgICAgPGRpdiB2LWlmPVwic2VhcmNoUmVzdWx0cy5sZW5ndGhcIiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTFcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjM0OjlcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB2LWZvcj1cInJlc3VsdCBpbiBzZWFyY2hSZXN1bHRzXCJcbiAgICAgICAgICAgIDprZXk9XCJyZXN1bHQua2V5XCJcbiAgICAgICAgICAgIGNsYXNzPVwiZmxleCBtaW4taC04IHctZnVsbCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIHJvdW5kZWQgYm9yZGVyIGJvcmRlci1vdXRsaW5lLTMgcHgtMiBweS0xIHRleHQtbGVmdCB0ZXh0LWJvZHktM3hzIGhvdmVyOmJnLWhpZ2hsaWdodC0yXCJcbiAgICAgICAgICAgIDpjbGFzcz1cInNlbGVjdGVkUmVzdWx0S2V5ID09PSByZXN1bHQua2V5ID8gJ2JnLWhpZ2hsaWdodC0yJyA6ICcnXCJcbiAgICAgICAgICAgIEBjbGljaz1cInNlbGVjdFNlYXJjaFJlc3VsdChyZXN1bHQpXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTozNToxMVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtaW4tdy0wXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo0MjoxM1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJsb2NrIHRydW5jYXRlIGZvbnQtbWVkaXVtIHRleHQtZm9yZWdyb3VuZFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6NDM6MTVcIj5cbiAgICAgICAgICAgICAgICB7eyByZXN1bHQubGFiZWwgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJsb2NrIHRydW5jYXRlIHRleHQtZm9yZWdyb3VuZC0yXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo0NjoxNVwiPlxuICAgICAgICAgICAgICAgIHt7IHJlc3VsdC5ndWlkIHx8IHJlc3VsdC5rZXkgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPENvbW1vbkJhZGdlIHYtaWY9XCJyZXN1bHQuaWRzLmxlbmd0aCA+IDFcIiByb3VuZGVkIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6NTA6MTNcIj5cbiAgICAgICAgICAgICAge3sgcmVzdWx0Lmlkcy5sZW5ndGggfX1cbiAgICAgICAgICAgIDwvQ29tbW9uQmFkZ2U+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9zZWN0aW9uPlxuXG4gICAgICA8c2VjdGlvbiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTIgYm9yZGVyLXQgYm9yZGVyLW91dGxpbmUtMyBwdC0zXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo1Nzo3XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gZ2FwLTJcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjU4OjlcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LWJvZHktM3hzIGZvbnQtbWVkaXVtIHRleHQtZm9yZWdyb3VuZC0yXCIgZm9yPVwic2VsZWN0aW9uLWNvbG9yXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZTo1OToxMVwiPlxuICAgICAgICAgICAgU2VsZWN0aW9uIGNvbG9yXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIGlkPVwic2VsZWN0aW9uLWNvbG9yXCJcbiAgICAgICAgICAgIHYtbW9kZWw9XCJzZWxlY3Rpb25Db2xvclwiXG4gICAgICAgICAgICBjbGFzcz1cImgtNyB3LTEwIHJvdW5kZWQgYm9yZGVyIGJvcmRlci1vdXRsaW5lLTMgYmctZm91bmRhdGlvblwiXG4gICAgICAgICAgICB0eXBlPVwiY29sb3JcIlxuICAgICAgICAgICAgQGlucHV0PVwiYXBwbHlTZWxlY3Rpb25PdmVybGF5Q29sb3JcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjYyOjExXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQgZ3JpZC1jb2xzLTIgZ2FwLTEuNVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6NzA6OVwiPlxuICAgICAgICAgIDxGb3JtQnV0dG9uXG4gICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgICAgY29sb3I9XCJvdXRsaW5lXCJcbiAgICAgICAgICAgIDpkaXNhYmxlZD1cIiFoYXNTZWxlY3Rpb25cIlxuICAgICAgICAgICAgOmljb24tbGVmdD1cIlBhaW50YnJ1c2hcIlxuICAgICAgICAgICAgQGNsaWNrPVwicGFpbnRTZWxlY3RlZE9iamVjdHNcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjcxOjExXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBQYWludFxuICAgICAgICAgIDwvRm9ybUJ1dHRvbj5cbiAgICAgICAgICA8Rm9ybUJ1dHRvblxuICAgICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICAgIGNvbG9yPVwic3VidGxlXCJcbiAgICAgICAgICAgIDpkaXNhYmxlZD1cIiFoYXNQYWludFwiXG4gICAgICAgICAgICA6aWNvbi1sZWZ0PVwiUm90YXRlQ2N3XCJcbiAgICAgICAgICAgIEBjbGljaz1cImNsZWFyUGFpbnRcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjgwOjExXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBDbGVhclxuICAgICAgICAgIDwvRm9ybUJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L3NlY3Rpb24+XG5cbiAgICAgIDxzZWN0aW9uIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMiBib3JkZXItdCBib3JkZXItb3V0bGluZS0zIHB0LTNcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjkyOjdcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQgZ3JpZC1jb2xzLTIgZ2FwLTEuNVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWU6OTM6OVwiPlxuICAgICAgICAgIDxGb3JtQnV0dG9uXG4gICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgICAgY29sb3I9XCJvdXRsaW5lXCJcbiAgICAgICAgICAgIDpkaXNhYmxlZD1cIiFoYXNTZWxlY3Rpb25cIlxuICAgICAgICAgICAgOmljb24tbGVmdD1cIkxheWVyc1wiXG4gICAgICAgICAgICBAY2xpY2s9XCJnaG9zdElzb2xhdGVTZWxlY3Rpb25cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvZWxlbWVudHMvUGFuZWwudnVlOjk0OjExXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBHaG9zdFxuICAgICAgICAgIDwvRm9ybUJ1dHRvbj5cbiAgICAgICAgICA8Rm9ybUJ1dHRvblxuICAgICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICAgIGNvbG9yPVwic3VidGxlXCJcbiAgICAgICAgICAgIDpkaXNhYmxlZD1cIiFoYXNJc29sYXRpb25cIlxuICAgICAgICAgICAgOmljb24tbGVmdD1cIlhcIlxuICAgICAgICAgICAgQGNsaWNrPVwicmVzZXRJc29sYXRpb25zXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2VsZW1lbnRzL1BhbmVsLnZ1ZToxMDM6MTFcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIFJlc2V0XG4gICAgICAgICAgPC9Gb3JtQnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvc2VjdGlvbj5cbiAgICA8L2Rpdj5cbiAgPC9WaWV3ZXJMYXlvdXRTaWRlUGFuZWw+XG48L3RlbXBsYXRlPlxuXG48c2NyaXB0IHNldHVwIGxhbmc9XCJ0c1wiPlxuaW1wb3J0IHtcbiAgQ2FtZXJhQ29udHJvbGxlcixcbiAgRmlsdGVyaW5nRXh0ZW5zaW9uLFxuICBTZWxlY3Rpb25FeHRlbnNpb24sXG4gIHR5cGUgVHJlZU5vZGVcbn0gZnJvbSAnQHNwZWNrbGUvdmlld2VyJ1xuaW1wb3J0IHsgRm9ybUJ1dHRvbiB9IGZyb20gJ0BzcGVja2xlL3VpLWNvbXBvbmVudHMnXG5pbXBvcnQgeyBMYXllcnMsIFBhaW50YnJ1c2gsIFJvdGF0ZUNjdywgU2VhcmNoLCBYIH0gZnJvbSAnbHVjaWRlLXZ1ZS1uZXh0J1xuaW1wb3J0IHsgdW5pcSB9IGZyb20gJ2xvZGFzaC1lcydcbmltcG9ydCB7IGdldFRhcmdldE9iamVjdElkcyB9IGZyb20gJ34vbGliL29iamVjdC1zaWRlYmFyL2hlbHBlcnMnXG5pbXBvcnQgeyB1c2VGaWx0ZXJVdGlsaXRpZXMgfSBmcm9tICd+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvZmlsdGVyaW5nL2ZpbHRlcmluZydcbmltcG9ydCB7XG4gIHVzZUluamVjdGVkVmlld2VyU3RhdGUsXG4gIHVzZUluamVjdGVkVmlld2VySW50ZXJmYWNlU3RhdGVcbn0gZnJvbSAnfi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3NldHVwJ1xuaW1wb3J0IHsgdXNlU2VsZWN0aW9uVXRpbGl0aWVzIH0gZnJvbSAnfi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3VpJ1xuXG50eXBlIEVsZW1lbnRTZWFyY2hSZXN1bHQgPSB7XG4gIGtleTogc3RyaW5nXG4gIGxhYmVsOiBzdHJpbmdcbiAgZ3VpZD86IHN0cmluZ1xuICBpZHM6IHN0cmluZ1tdXG59XG5cbmNvbnN0IE1BWF9SRVNVTFRTID0gNTBcbmNvbnN0IEdVSURfS0VZUyA9IG5ldyBTZXQoW1xuICAnaWQnLFxuICAndXVpZCcsXG4gICduYW1lJyxcbiAgJ2FwcGxpY2F0aW9uaWQnLFxuICAnZ3VpZCcsXG4gICdzb3VyY2VndWlkJyxcbiAgJ2lmY2d1aWQnLFxuICAnaWZjZWxlbWVudGd1aWQnLFxuICAnaWZjZWxlbWVudHNvdXJjZWd1aWQnLFxuICAnaWZjZWxlbWVudGFzc2VtYmx5Z3VpZCcsXG4gICdpZmNlbGVtZW50YXNzZW1ibHlzb3VyY2VndWlkJyxcbiAgJ2dsb2JhbGlkJyxcbiAgJ2V4cHJlc3NpZCcsXG4gICdpZmNleHByZXNzaWQnXG5dKVxuY29uc3QgU0tJUF9LRVlTID0gbmV3IFNldChbXG4gICd2ZXJ0aWNlcycsXG4gICdmYWNlcycsXG4gICdjb2xvcnMnLFxuICAnZGlzcGxheXZhbHVlJyxcbiAgJ2Rpc3BsYXl2YWx1ZXMnLFxuICAnZ2VvbWV0cnknLFxuICAnbWF0cml4JyxcbiAgJ21hdHJpeHdvcmxkJyxcbiAgJ2NoaWxkcmVuJyxcbiAgJ3BhcmVudCdcbl0pXG5cbmNvbnN0IHtcbiAgdmlld2VyOiB7IGluc3RhbmNlIH1cbn0gPSB1c2VJbmplY3RlZFZpZXdlclN0YXRlKClcbmNvbnN0IHtcbiAgZmlsdGVyczogeyBpc29sYXRlZE9iamVjdElkcyB9XG59ID0gdXNlSW5qZWN0ZWRWaWV3ZXJJbnRlcmZhY2VTdGF0ZSgpXG5jb25zdCB7IG9iamVjdHM6IHNlbGVjdGVkT2JqZWN0cywgc2V0U2VsZWN0aW9uRnJvbU9iamVjdElkcyB9ID0gdXNlU2VsZWN0aW9uVXRpbGl0aWVzKClcbmNvbnN0IHsgaXNvbGF0ZU9iamVjdHMsIHJlc2V0SXNvbGF0aW9ucyB9ID0gdXNlRmlsdGVyVXRpbGl0aWVzKClcblxuY29uc3QgZ3VpZFF1ZXJ5ID0gcmVmKCcnKVxuY29uc3Qgc2VhcmNoTWVzc2FnZSA9IHJlZignJylcbmNvbnN0IHNlYXJjaFJlc3VsdHMgPSBzaGFsbG93UmVmPEVsZW1lbnRTZWFyY2hSZXN1bHRbXT4oW10pXG5jb25zdCBzZWxlY3RlZFJlc3VsdEtleSA9IHJlZjxzdHJpbmcgfCBudWxsPihudWxsKVxuY29uc3Qgc2VsZWN0aW9uQ29sb3IgPSByZWYoJyMwNDdlZmInKVxuY29uc3QgcGFpbnRlZEdyb3VwcyA9IHNoYWxsb3dSZWY8eyBvYmplY3RJZHM6IHN0cmluZ1tdOyBjb2xvcjogc3RyaW5nIH1bXT4oW10pXG5cbmNvbnN0IGhhc1BhaW50ID0gY29tcHV0ZWQoKCkgPT4gcGFpbnRlZEdyb3Vwcy52YWx1ZS5sZW5ndGggPiAwKVxuY29uc3QgaGFzU2VsZWN0aW9uID0gY29tcHV0ZWQoKCkgPT4gc2VsZWN0ZWRUYXJnZXRJZHMudmFsdWUubGVuZ3RoID4gMClcbmNvbnN0IGhhc0lzb2xhdGlvbiA9IGNvbXB1dGVkKCgpID0+IGlzb2xhdGVkT2JqZWN0SWRzLnZhbHVlLmxlbmd0aCA+IDApXG5cbmNvbnN0IHNlbGVjdGVkVGFyZ2V0SWRzID0gY29tcHV0ZWQoKCkgPT5cbiAgdW5pcShcbiAgICBzZWxlY3RlZE9iamVjdHMudmFsdWUuZmxhdE1hcCgob2JqKSA9PlxuICAgICAgZ2V0VGFyZ2V0T2JqZWN0SWRzKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICApXG4gIClcbilcblxuY29uc3Qgb25TZWFyY2hLZXlkb3duID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB7XG4gIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHNlYXJjaEd1aWQoKVxufVxuXG5jb25zdCBub3JtYWxpemUgPSAodmFsdWU6IHVua25vd24pID0+IFN0cmluZyh2YWx1ZSA/PyAnJykudHJpbSgpLnRvTG93ZXJDYXNlKClcbmNvbnN0IGdldFJlY29yZCA9ICh2YWx1ZTogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0+XG4gIHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyAodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pIDoge31cbmNvbnN0IGdldFN0cmluZyA9ICh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnICYmIHZhbHVlLmxlbmd0aCA+IDAgPyB2YWx1ZSA6IHVuZGVmaW5lZFxuXG5jb25zdCBjb2xsZWN0U2VhcmNoQ2FuZGlkYXRlcyA9ICh2YWx1ZTogdW5rbm93biwgZGVwdGggPSAwKTogc3RyaW5nW10gPT4ge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCBkZXB0aCA+IDMpIHJldHVybiBbXVxuICBpZiAoWydzdHJpbmcnLCAnbnVtYmVyJywgJ2Jvb2xlYW4nXS5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpKSB7XG4gICAgY29uc3QgdGV4dCA9IFN0cmluZyh2YWx1ZSkudHJpbSgpXG4gICAgcmV0dXJuIHRleHQgPyBbdGV4dF0gOiBbXVxuICB9XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPiAyMCkgcmV0dXJuIFtdXG4gICAgcmV0dXJuIHZhbHVlLmZsYXRNYXAoKGl0ZW0pID0+IGNvbGxlY3RTZWFyY2hDYW5kaWRhdGVzKGl0ZW0sIGRlcHRoICsgMSkpXG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ29iamVjdCcpIHJldHVybiBbXVxuXG4gIGNvbnN0IGNhbmRpZGF0ZXM6IHN0cmluZ1tdID0gW11cbiAgZm9yIChjb25zdCBba2V5LCBjaGlsZFZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikpIHtcbiAgICBjb25zdCBub3JtYWxpemVkS2V5ID0ga2V5LnRvTG93ZXJDYXNlKClcbiAgICBpZiAoU0tJUF9LRVlTLmhhcyhub3JtYWxpemVkS2V5KSkgY29udGludWVcbiAgICBpZiAoXG4gICAgICBHVUlEX0tFWVMuaGFzKG5vcm1hbGl6ZWRLZXkpIHx8XG4gICAgICBub3JtYWxpemVkS2V5LmluY2x1ZGVzKCdndWlkJykgfHxcbiAgICAgIG5vcm1hbGl6ZWRLZXkuaW5jbHVkZXMoJ2dsb2JhbGlkJylcbiAgICApIHtcbiAgICAgIGNhbmRpZGF0ZXMucHVzaCguLi5jb2xsZWN0U2VhcmNoQ2FuZGlkYXRlcyhjaGlsZFZhbHVlLCBkZXB0aCArIDEpKVxuICAgICAgY29udGludWVcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBub3JtYWxpemVkS2V5ID09PSAncHJvcGVydGllcycgfHxcbiAgICAgIG5vcm1hbGl6ZWRLZXkgPT09ICdwYXJhbWV0ZXJzJyB8fFxuICAgICAgbm9ybWFsaXplZEtleSA9PT0gJ3VzZXJkYXRhJ1xuICAgICkge1xuICAgICAgY2FuZGlkYXRlcy5wdXNoKC4uLmNvbGxlY3RTZWFyY2hDYW5kaWRhdGVzKGNoaWxkVmFsdWUsIGRlcHRoICsgMSkpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNhbmRpZGF0ZXNcbn1cblxuY29uc3QgZ2V0Tm9kZUd1aWQgPSAobm9kZTogVHJlZU5vZGUpOiBzdHJpbmcgfCB1bmRlZmluZWQgPT4ge1xuICByZXR1cm4gZ2V0Tm9kZUd1aWRDYW5kaWRhdGVzKG5vZGUpWzBdXG59XG5cbmNvbnN0IGdldE5vZGVHdWlkQ2FuZGlkYXRlcyA9IChub2RlOiBUcmVlTm9kZSk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3QgcmF3ID0gbm9kZS5tb2RlbC5yYXcgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cbiAgY29uc3QgdXNlckRhdGEgPSBnZXRSZWNvcmQocmF3LnVzZXJEYXRhKVxuICBjb25zdCBjYW5kaWRhdGVzID0gW1xuICAgIHJhdy5pZmNFbGVtZW50QXNzZW1ibHlTb3VyY2VHdWlkLFxuICAgIHJhdy5pZmNFbGVtZW50U291cmNlR3VpZCxcbiAgICByYXcuc291cmNlR3VpZCxcbiAgICByYXcuaWZjRWxlbWVudEFzc2VtYmx5R3VpZCxcbiAgICByYXcuaWZjRWxlbWVudEd1aWQsXG4gICAgcmF3LmlmY0d1aWQsXG4gICAgcmF3Lmd1aWQsXG4gICAgcmF3Lmdsb2JhbElkLFxuICAgIHJhdy5HbG9iYWxJZCxcbiAgICByYXcuYXBwbGljYXRpb25JZCxcbiAgICB1c2VyRGF0YT8uaWZjRWxlbWVudEFzc2VtYmx5U291cmNlR3VpZCxcbiAgICB1c2VyRGF0YT8uaWZjRWxlbWVudFNvdXJjZUd1aWQsXG4gICAgdXNlckRhdGE/LnNvdXJjZUd1aWQsXG4gICAgdXNlckRhdGE/LmlmY0VsZW1lbnRBc3NlbWJseUd1aWQsXG4gICAgdXNlckRhdGE/LmlmY0VsZW1lbnRHdWlkLFxuICAgIHVzZXJEYXRhPy5pZmNHdWlkLFxuICAgIHVzZXJEYXRhPy5ndWlkLFxuICAgIHVzZXJEYXRhPy5nbG9iYWxJZCxcbiAgICB1c2VyRGF0YT8uR2xvYmFsSWQsXG4gICAgdXNlckRhdGE/LmFwcGxpY2F0aW9uSWRcbiAgXVxuICByZXR1cm4gdW5pcShjYW5kaWRhdGVzLm1hcChnZXRTdHJpbmcpLmZpbHRlcigodmFsdWUpOiB2YWx1ZSBpcyBzdHJpbmcgPT4gISF2YWx1ZSkpXG59XG5cbmNvbnN0IGdldE5vZGVMYWJlbCA9IChub2RlOiBUcmVlTm9kZSwgZ3VpZD86IHN0cmluZykgPT4ge1xuICBjb25zdCByYXcgPSBub2RlLm1vZGVsLnJhdyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPlxuICByZXR1cm4gKFxuICAgICh0eXBlb2YgcmF3Lm5hbWUgPT09ICdzdHJpbmcnICYmIHJhdy5uYW1lKSB8fFxuICAgICh0eXBlb2YgcmF3LnR5cGUgPT09ICdzdHJpbmcnICYmIHJhdy50eXBlKSB8fFxuICAgIGd1aWQgfHxcbiAgICBub2RlLm1vZGVsLmlkXG4gIClcbn1cblxuY29uc3QgdXBzZXJ0U2VhcmNoUmVzdWx0ID0gKFxuICBncm91cHM6IE1hcDxzdHJpbmcsIEVsZW1lbnRTZWFyY2hSZXN1bHQ+LFxuICBub2RlOiBUcmVlTm9kZVxuKSA9PiB7XG4gIGNvbnN0IHJhdyA9IG5vZGUubW9kZWwucmF3IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4gIGNvbnN0IGd1aWQgPSBnZXROb2RlR3VpZChub2RlKVxuICBjb25zdCBrZXkgPSBndWlkIHx8IG5vZGUubW9kZWwuaWRcbiAgY29uc3QgZXhpc3RpbmcgPSBncm91cHMuZ2V0KGtleSlcbiAgY29uc3QgaWRzID0gZ2V0VGFyZ2V0T2JqZWN0SWRzKHJhdylcbiAgY29uc3Qgbm9kZUlkcyA9IGlkcy5sZW5ndGhcbiAgICA/IGlkc1xuICAgIDogdHlwZW9mIG5vZGUubW9kZWwuaWQgPT09ICdzdHJpbmcnXG4gICAgICA/IFtub2RlLm1vZGVsLmlkXVxuICAgICAgOiBbXVxuICBpZiAoIW5vZGVJZHMubGVuZ3RoKSByZXR1cm5cblxuICBpZiAoZXhpc3RpbmcpIHtcbiAgICBleGlzdGluZy5pZHMgPSB1bmlxKFsuLi5leGlzdGluZy5pZHMsIC4uLm5vZGVJZHNdKVxuICAgIHJldHVyblxuICB9XG5cbiAgZ3JvdXBzLnNldChrZXksIHtcbiAgICBrZXksXG4gICAgZ3VpZCxcbiAgICBpZHM6IG5vZGVJZHMsXG4gICAgbGFiZWw6IGdldE5vZGVMYWJlbChub2RlLCBndWlkKVxuICB9KVxufVxuXG5jb25zdCBmaW5kR3VpZE1hdGNoZXMgPSAocXVlcnk6IHN0cmluZykgPT4ge1xuICBjb25zdCBleGFjdCA9IG5ldyBNYXA8c3RyaW5nLCBFbGVtZW50U2VhcmNoUmVzdWx0PigpXG4gIGNvbnN0IHBhcnRpYWwgPSBuZXcgTWFwPHN0cmluZywgRWxlbWVudFNlYXJjaFJlc3VsdD4oKVxuICBjb25zdCBub3JtYWxpemVkUXVlcnkgPSBub3JtYWxpemUocXVlcnkpXG5cbiAgaW5zdGFuY2UuZ2V0V29ybGRUcmVlKCkud2Fsaygobm9kZSkgPT4ge1xuICAgIGlmICghbm9kZS5tb2RlbC5yYXcgfHwgbm9kZS5tb2RlbC5pZCA9PT0gJ1JPT1QnKSByZXR1cm4gdHJ1ZVxuICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSB1bmlxKFtcbiAgICAgIC4uLmdldE5vZGVHdWlkQ2FuZGlkYXRlcyhub2RlKSxcbiAgICAgIC4uLmNvbGxlY3RTZWFyY2hDYW5kaWRhdGVzKG5vZGUubW9kZWwucmF3KVxuICAgIF0pXG4gICAgaWYgKCFjYW5kaWRhdGVzLmxlbmd0aCkgcmV0dXJuIHRydWVcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWRDYW5kaWRhdGVzID0gY2FuZGlkYXRlcy5tYXAobm9ybWFsaXplKVxuICAgIGlmIChub3JtYWxpemVkQ2FuZGlkYXRlcy5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZSA9PT0gbm9ybWFsaXplZFF1ZXJ5KSkge1xuICAgICAgdXBzZXJ0U2VhcmNoUmVzdWx0KGV4YWN0LCBub2RlKVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgaWYgKG5vcm1hbGl6ZWRDYW5kaWRhdGVzLnNvbWUoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSkpKSB7XG4gICAgICB1cHNlcnRTZWFyY2hSZXN1bHQocGFydGlhbCwgbm9kZSlcbiAgICB9XG4gICAgcmV0dXJuIHRydWVcbiAgfSlcblxuICByZXR1cm4gQXJyYXkuZnJvbSgoZXhhY3Quc2l6ZSA/IGV4YWN0IDogcGFydGlhbCkudmFsdWVzKCkpLnNsaWNlKDAsIE1BWF9SRVNVTFRTKVxufVxuXG5jb25zdCBzZWFyY2hHdWlkID0gKCkgPT4ge1xuICBjb25zdCBxdWVyeSA9IGd1aWRRdWVyeS52YWx1ZS50cmltKClcbiAgc2VsZWN0ZWRSZXN1bHRLZXkudmFsdWUgPSBudWxsXG4gIGlmICghcXVlcnkpIHtcbiAgICBzZWFyY2hSZXN1bHRzLnZhbHVlID0gW11cbiAgICBzZWFyY2hNZXNzYWdlLnZhbHVlID0gJydcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IHJlc3VsdHMgPSBmaW5kR3VpZE1hdGNoZXMocXVlcnkpXG4gIHNlYXJjaFJlc3VsdHMudmFsdWUgPSByZXN1bHRzXG4gIHNlYXJjaE1lc3NhZ2UudmFsdWUgPSByZXN1bHRzLmxlbmd0aCA/IGAke3Jlc3VsdHMubGVuZ3RofSBmb3VuZGAgOiAnTm8gbWF0Y2gnXG4gIGlmIChyZXN1bHRzLmxlbmd0aCA9PT0gMSkgc2VsZWN0U2VhcmNoUmVzdWx0KHJlc3VsdHNbMF0pXG59XG5cbmNvbnN0IHNlbGVjdFNlYXJjaFJlc3VsdCA9IChyZXN1bHQ6IEVsZW1lbnRTZWFyY2hSZXN1bHQpID0+IHtcbiAgc2VsZWN0ZWRSZXN1bHRLZXkudmFsdWUgPSByZXN1bHQua2V5XG4gIHNldFNlbGVjdGlvbkZyb21PYmplY3RJZHMocmVzdWx0LmlkcylcbiAgaW5zdGFuY2UuZ2V0RXh0ZW5zaW9uKENhbWVyYUNvbnRyb2xsZXIpLnNldENhbWVyYVZpZXcocmVzdWx0LmlkcywgdHJ1ZSlcbn1cblxuY29uc3QgcGFyc2VDb2xvciA9IChjb2xvcjogc3RyaW5nKSA9PiBOdW1iZXIucGFyc2VJbnQoY29sb3IucmVwbGFjZSgnIycsICcnKSwgMTYpXG5cbmNvbnN0IHJlZnJlc2hWaWV3ZXJTZWxlY3Rpb24gPSAoKSA9PiB7XG4gIGNvbnN0IGlkcyA9IHNlbGVjdGVkVGFyZ2V0SWRzLnZhbHVlXG4gIGNvbnN0IGV4dGVuc2lvbiA9IGluc3RhbmNlLmdldEV4dGVuc2lvbihTZWxlY3Rpb25FeHRlbnNpb24pXG4gIGV4dGVuc2lvbi5jbGVhclNlbGVjdGlvbigpXG4gIGlmIChpZHMubGVuZ3RoKSBleHRlbnNpb24uc2VsZWN0T2JqZWN0cyhpZHMpXG59XG5cbmNvbnN0IGFwcGx5U2VsZWN0aW9uT3ZlcmxheUNvbG9yID0gKCkgPT4ge1xuICBjb25zdCBleHRlbnNpb24gPSBpbnN0YW5jZS5nZXRFeHRlbnNpb24oU2VsZWN0aW9uRXh0ZW5zaW9uKVxuICBleHRlbnNpb24ub3B0aW9ucyA9IHtcbiAgICAuLi5leHRlbnNpb24ub3B0aW9ucyxcbiAgICBzZWxlY3Rpb25NYXRlcmlhbERhdGE6IHtcbiAgICAgIC4uLmV4dGVuc2lvbi5vcHRpb25zLnNlbGVjdGlvbk1hdGVyaWFsRGF0YSxcbiAgICAgIGNvbG9yOiBwYXJzZUNvbG9yKHNlbGVjdGlvbkNvbG9yLnZhbHVlKVxuICAgIH1cbiAgfVxuICByZWZyZXNoVmlld2VyU2VsZWN0aW9uKClcbn1cblxuY29uc3QgcGFpbnRTZWxlY3RlZE9iamVjdHMgPSAoKSA9PiB7XG4gIGNvbnN0IGlkcyA9IHNlbGVjdGVkVGFyZ2V0SWRzLnZhbHVlXG4gIGlmICghaWRzLmxlbmd0aCkgcmV0dXJuXG5cbiAgcGFpbnRlZEdyb3Vwcy52YWx1ZSA9IFtcbiAgICAuLi5wYWludGVkR3JvdXBzLnZhbHVlLFxuICAgIHsgb2JqZWN0SWRzOiBpZHMsIGNvbG9yOiBzZWxlY3Rpb25Db2xvci52YWx1ZSB9XG4gIF1cbiAgaW5zdGFuY2UuZ2V0RXh0ZW5zaW9uKEZpbHRlcmluZ0V4dGVuc2lvbikuc2V0VXNlck9iamVjdENvbG9ycyhwYWludGVkR3JvdXBzLnZhbHVlKVxuICByZWZyZXNoVmlld2VyU2VsZWN0aW9uKClcbn1cblxuY29uc3QgY2xlYXJQYWludCA9ICgpID0+IHtcbiAgcGFpbnRlZEdyb3Vwcy52YWx1ZSA9IFtdXG4gIGluc3RhbmNlLmdldEV4dGVuc2lvbihGaWx0ZXJpbmdFeHRlbnNpb24pLnJlbW92ZVVzZXJPYmplY3RDb2xvcnMoKVxuICByZWZyZXNoVmlld2VyU2VsZWN0aW9uKClcbn1cblxuY29uc3QgZ2hvc3RJc29sYXRlU2VsZWN0aW9uID0gKCkgPT4ge1xuICBjb25zdCBpZHMgPSBzZWxlY3RlZFRhcmdldElkcy52YWx1ZVxuICBpZiAoIWlkcy5sZW5ndGgpIHJldHVyblxuICBpc29sYXRlT2JqZWN0cyhpZHMsIHsgcmVwbGFjZTogdHJ1ZSB9KVxuICBpbnN0YW5jZS5nZXRFeHRlbnNpb24oQ2FtZXJhQ29udHJvbGxlcikuc2V0Q2FtZXJhVmlldyhpZHMsIHRydWUpXG59XG48L3NjcmlwdD5cbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9jb21wb25lbnRzL3ZpZXdlci9lbGVtZW50cy9QYW5lbC52dWUifQ==