Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_00013b
T

308 lines
32 KiB
Plaintext

import { createHotContext as __vite__createHotContext } from "/_nuxt/@vite/client";import.meta.hot = __vite__createHotContext("/components/viewer/anchored-point/NewThread.vue");import { default as __nuxt_component_0 } from "/_nuxt/components/viewer/comments/Editor.vue";
import { FormButton as __nuxt_component_1 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
import { FormFileUploadZone as __nuxt_component_2 } from "/_nuxt/@fs/D:/speckle-server/packages/ui-components/dist/lib.js";
import { default as __nuxt_component_3 } from "/_nuxt/components/viewer/comments/PortalOrDiv.vue";
/* Injection by vite-plugin-vue-inspector Start */
import { createVNode as __createVNode,createElementBlock as __createElementBlock,createElementVNode as __createElementVNode,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 _createVNode(...args) { return _interopVNode(__createVNode(...args)) }
function _createElementBlock(...args) { return _interopVNode(__createElementBlock(...args)) }
function _createElementVNode(...args) { return _interopVNode(__createElementVNode(...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 { onKeyDown } from "/_nuxt/node_modules/@vueuse/core/index.mjs?v=e4f18c29";
import { useIsTypingUpdateEmitter } from "/_nuxt/lib/viewer/composables/commentBubbles.ts";
import { useSubmitComment } from "/_nuxt/lib/viewer/composables/commentManagement.ts";
import {
isValidCommentContentInput,
convertCommentEditorValueToInput
} from "/_nuxt/lib/viewer/helpers/comments.ts";
import { useMixpanel } from "/_nuxt/lib/core/composables/mp.ts";
import { useThreadUtilities, useSelectionUtilities } from "/_nuxt/lib/viewer/composables/ui.ts";
import { useEmbed } from "/_nuxt/lib/viewer/composables/setup/embed.ts";
import { useServerFileUploadLimit } from "/_nuxt/lib/common/composables/serverInfo.ts";
import { UniqueFileTypeSpecifier } from "/_nuxt/lib/core/helpers/file.ts";
import { acceptedFileExtensions } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/blobs/index.js";
import { Paperclip, SendHorizonal, Plus } from "/_nuxt/node_modules/.cache/vite/client/deps/lucide-vue-next.js?v=e4f18c29";
import { ref, computed, watch } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
import { useActiveUser } from "/_nuxt/composables/globals.ts";
const _sfc_main = /* @__PURE__ */ _defineComponent({
__name: "ViewerAnchoredPointNewThread",
props: {
modelValue: { type: Object, required: true },
canPostComment: { type: [Boolean, null], required: false }
},
emits: ["update:modelValue", "close", "login"],
setup(__props, { expose: __expose, emit: __emit }) {
__expose();
const { isEnabled: isEmbedEnabled } = useEmbed();
const emit = __emit;
const props = __props;
const { onKeyDownHandler, updateIsTyping, pauseAutomaticUpdates } = useIsTypingUpdateEmitter();
const { closeAllThreads, open } = useThreadUtilities();
const { maxSizeInBytes } = useServerFileUploadLimit();
const editor = ref(
null
);
const uploadZone = ref(null);
const commentValue = ref({ doc: void 0, attachments: void 0 });
const threadContainer = ref(null);
const isPostingNewThread = ref(false);
const acceptValue = [
UniqueFileTypeSpecifier.AnyImage,
UniqueFileTypeSpecifier.AnyVideo,
...acceptedFileExtensions.map((fileExtension) => `.${fileExtension}`)
].join(",");
const onFilesSelected = (payload) => {
editor.value?.onFilesSelected(payload);
};
const createThread = useSubmitComment();
const { isLoggedIn } = useActiveUser();
const { objects } = useSelectionUtilities();
const onThreadClick = () => {
const newIsExpanded = !props.modelValue.isExpanded;
if (!isLoggedIn.value || !props.canPostComment) {
if (!isLoggedIn.value) {
emit("login");
}
return;
}
if (!newIsExpanded) {
updateIsTyping(false);
}
emit("update:modelValue", {
...props.modelValue,
isExpanded: newIsExpanded
});
};
const mp = useMixpanel();
const onSubmit = (comment) => {
comment ||= comment || commentValue.value;
if (!comment?.doc) return;
const content = convertCommentEditorValueToInput(commentValue.value);
if (!isValidCommentContentInput(content)) return;
isPostingNewThread.value = true;
pauseAutomaticUpdates.value = true;
updateIsTyping(true);
createThread(content).then(async (newThread) => {
const threadId = newThread?.id;
if (!threadId) return;
await open(threadId);
emit("update:modelValue", {
...props.modelValue,
isExpanded: false
});
}).finally(() => {
isPostingNewThread.value = false;
updateIsTyping(false);
pauseAutomaticUpdates.value = false;
});
mp.track("Comment Action", { type: "action", name: "create" });
comment.attachments?.forEach((a) => {
a.inUse = true;
});
};
const trackAttachAndOpenFilePicker = () => {
uploadZone.value?.triggerPicker();
mp.track("Comment Action", { type: "action", name: "attach" });
};
const shouldShowThreadBubble = computed(() => {
return props.modelValue.isVisible && objects.value.length > 0;
});
onKeyDown("Escape", () => {
if (props.modelValue.isExpanded) {
onThreadClick();
}
});
watch(
() => props.modelValue.isExpanded,
async (newVal) => {
if (newVal) {
await closeAllThreads();
}
commentValue.value = {
doc: void 0,
attachments: void 0
};
}
);
const __returned__ = { isEmbedEnabled, emit, props, onKeyDownHandler, updateIsTyping, pauseAutomaticUpdates, closeAllThreads, open, maxSizeInBytes, editor, uploadZone, commentValue, threadContainer, isPostingNewThread, acceptValue, onFilesSelected, createThread, isLoggedIn, objects, onThreadClick, mp, onSubmit, trackAttachAndOpenFilePicker, shouldShowThreadBubble, get Paperclip() {
return Paperclip;
}, get SendHorizonal() {
return SendHorizonal;
}, get Plus() {
return Plus;
} };
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
import { normalizeClass as _normalizeClass, resolveDirective as _resolveDirective, openBlock as _openBlock, withDirectives as _withDirectives, createTextVNode as _createTextVNode, createCommentVNode as _createCommentVNode, resolveComponent as _resolveComponent, withCtx as _withCtx, normalizeStyle as _normalizeStyle } from "/_nuxt/node_modules/vue/dist/vue.runtime.esm-bundler.js?v=e4f18c29";
const _hoisted_1 = {
class: "relative",
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:11:5"
};
const _hoisted_2 = {
key: 0,
class: "bg-foundation p-3 text-body-2xs text-foreground font-semibold sm:hidden flex justify-between items-center",
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:24:9"
};
const _hoisted_3 = {
class: "w-full flex justify-between items-center p-1",
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:61:13"
};
const _hoisted_4 = {
key: 1,
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:81:3"
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_ViewerCommentsEditor = __nuxt_component_0;
const _component_FormButton = __nuxt_component_1;
const _component_FormFileUploadZone = __nuxt_component_2;
const _component_ViewerCommentsPortalOrDiv = __nuxt_component_3;
const _directive_tippy = _resolveDirective("tippy");
return $setup.shouldShowThreadBubble ? (_openBlock(), _createElementBlock(
"div",
{
key: 0,
class: "absolute pointer-events-auto",
style: _normalizeStyle({
...$props.modelValue.style,
opacity: 1
}),
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:3:3"
},
[
_createElementVNode("div", _hoisted_1, [
_withDirectives((_openBlock(), _createElementBlock("button", {
class: "bg-foundation-2 outline outline-2 outline-primary rounded-tr-full rounded-tl-full rounded-br-full w-8 h-8 -top-10 absolute flex justify-center items-center hover:shadow-md",
onClick: $setup.onThreadClick,
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:12:7"
}, [
_createVNode($setup["Plus"], {
class: _normalizeClass(`w-5 h-5 text-primary ${$props.modelValue.isExpanded ? "rotate-45" : ""} transition`),
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:17:9"
}, null, 8, ["class"])
])), [
[_directive_tippy, !$props.modelValue.isExpanded ? "New comment" : "Close"]
]),
_createVNode(_component_ViewerCommentsPortalOrDiv, {
to: "mobileComments",
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:23:7"
}, {
default: _withCtx(() => [
$props.modelValue.isExpanded && !$setup.isEmbedEnabled ? (_openBlock(), _createElementBlock("div", _hoisted_2, [
_cache[4] || (_cache[4] = _createTextVNode(
" Add Comment ",
-1
/* CACHED */
)),
_withDirectives((_openBlock(), _createElementBlock("button", {
onClick: $setup.onThreadClick,
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:29:11"
}, [
_createVNode($setup["Plus"], {
class: "w-4 h-4 text-foreground-2 rotate-45",
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:30:13"
})
])), [
[_directive_tippy, "Close"]
])
])) : _createCommentVNode("v-if", true),
$props.modelValue.isExpanded && $props.canPostComment ? (_openBlock(), _createBlock(_component_FormFileUploadZone, {
key: 1,
ref: "uploadZone",
"size-limit": $setup.maxSizeInBytes,
accept: $setup.acceptValue,
disabled: $setup.isPostingNewThread,
multiple: "",
onFilesSelected: $setup.onFilesSelected,
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:33:9"
}, {
default: _withCtx(({ isDraggingFiles }) => [
_createElementVNode(
"div",
{
ref: "threadContainer",
class: _normalizeClass([
"sm:absolute w-full sm:w-[260px] bg-foundation dark:bg-foundation-2 border sm:rounded-xl shadow-md",
isDraggingFiles ? "border-dashed border-primary" : "border-outline-2"
]),
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:43:11"
},
[
_createVNode(_component_ViewerCommentsEditor, {
ref: "editor",
modelValue: $setup.commentValue,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $setup.commentValue = $event),
prompt: "Add comment",
"max-height": "300px",
autofocus: "",
"disable-drop-zone": "",
disabled: $setup.isPostingNewThread,
onSubmit: _cache[1] || (_cache[1] = () => $setup.onSubmit()),
onKeydown: $setup.onKeyDownHandler,
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:50:13"
}, null, 8, ["modelValue", "disabled", "onKeydown"]),
_createElementVNode("div", _hoisted_3, [
_createVNode(_component_FormButton, {
"icon-left": $setup.Paperclip,
"hide-text": "",
disabled: $setup.isPostingNewThread,
color: "subtle",
onClick: _cache[2] || (_cache[2] = ($event) => $setup.trackAttachAndOpenFilePicker()),
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:62:15"
}, null, 8, ["icon-left", "disabled"]),
_createVNode(_component_FormButton, {
"icon-left": $setup.SendHorizonal,
"hide-text": "",
loading: $setup.isPostingNewThread,
onClick: _cache[3] || (_cache[3] = () => $setup.onSubmit()),
"data-v-inspector": "components/viewer/anchored-point/NewThread.vue:69:15"
}, null, 8, ["icon-left", "loading"])
])
],
2
/* CLASS */
)
]),
_: 1
/* STABLE */
}, 8, ["size-limit", "accept", "disabled"])) : _createCommentVNode("v-if", true)
]),
_: 1
/* STABLE */
})
])
],
4
/* STYLE */
)) : (_openBlock(), _createElementBlock("div", _hoisted_4));
}
_sfc_main.__hmrId = "4c7fb6d5";
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/anchored-point/NewThread.vue"]]);
//# sourceMappingURL=data:application/json;base64,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QUEsd0JBSkMsYUFBVztBQUFBLHdCQUNaO0FBQUEsd0JBQ0MsU0FBUztBQUFBLHdCQUNULFNBQUssZ0NBQVEsZ0JBQVE7QUFBQSx3QkFBSSxvQkFBaUI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O3NCQVF6RCxvQkFBeUYsT0FBekYsVUFBeUYiLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbIk5ld1RocmVhZC52dWUiXSwic291cmNlc0NvbnRlbnQiOlsiPCEtLSBlc2xpbnQtZGlzYWJsZSB2dWVqcy1hY2Nlc3NpYmlsaXR5L25vLWF1dG9mb2N1cyAtLT5cclxuPHRlbXBsYXRlPlxyXG4gIDxkaXZcclxuICAgIHYtaWY9XCJzaG91bGRTaG93VGhyZWFkQnViYmxlXCJcclxuICAgIGNsYXNzPVwiYWJzb2x1dGUgcG9pbnRlci1ldmVudHMtYXV0b1wiXHJcbiAgICA6c3R5bGU9XCJ7XHJcbiAgICAgIC4uLm1vZGVsVmFsdWUuc3R5bGUsXHJcbiAgICAgIG9wYWNpdHk6IDFcclxuICAgIH1cIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvYW5jaG9yZWQtcG9pbnQvTmV3VGhyZWFkLnZ1ZTozOjNcIlxyXG4gID5cclxuICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZVwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjExOjVcIj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIHYtdGlwcHk9XCIhbW9kZWxWYWx1ZS5pc0V4cGFuZGVkID8gJ05ldyBjb21tZW50JyA6ICdDbG9zZSdcIlxyXG4gICAgICAgIGNsYXNzPVwiYmctZm91bmRhdGlvbi0yIG91dGxpbmUgb3V0bGluZS0yIG91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXRyLWZ1bGwgcm91bmRlZC10bC1mdWxsIHJvdW5kZWQtYnItZnVsbCB3LTggaC04IC10b3AtMTAgYWJzb2x1dGUgZmxleCBqdXN0aWZ5LWNlbnRlciBpdGVtcy1jZW50ZXIgaG92ZXI6c2hhZG93LW1kXCJcclxuICAgICAgICBAY2xpY2s9XCJvblRocmVhZENsaWNrXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2FuY2hvcmVkLXBvaW50L05ld1RocmVhZC52dWU6MTI6N1wiXHJcbiAgICAgID5cclxuICAgICAgICA8UGx1c1xyXG4gICAgICAgICAgOmNsYXNzPVwiYHctNSBoLTUgdGV4dC1wcmltYXJ5ICR7XHJcbiAgICAgICAgICAgIG1vZGVsVmFsdWUuaXNFeHBhbmRlZCA/ICdyb3RhdGUtNDUnIDogJydcclxuICAgICAgICAgIH0gdHJhbnNpdGlvbmBcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvYW5jaG9yZWQtcG9pbnQvTmV3VGhyZWFkLnZ1ZToxNzo5XCJcclxuICAgICAgICAvPlxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPFZpZXdlckNvbW1lbnRzUG9ydGFsT3JEaXYgdG89XCJtb2JpbGVDb21tZW50c1wiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjIzOjdcIj5cclxuICAgICAgICA8ZGl2XHJcbiAgICAgICAgICB2LWlmPVwibW9kZWxWYWx1ZS5pc0V4cGFuZGVkICYmICFpc0VtYmVkRW5hYmxlZFwiXHJcbiAgICAgICAgICBjbGFzcz1cImJnLWZvdW5kYXRpb24gcC0zIHRleHQtYm9keS0yeHMgdGV4dC1mb3JlZ3JvdW5kIGZvbnQtc2VtaWJvbGQgc206aGlkZGVuIGZsZXgganVzdGlmeS1iZXR3ZWVuIGl0ZW1zLWNlbnRlclwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjI0OjlcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIEFkZCBDb21tZW50XHJcbiAgICAgICAgICA8YnV0dG9uIHYtdGlwcHk9XCInQ2xvc2UnXCIgQGNsaWNrPVwib25UaHJlYWRDbGlja1wiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjI5OjExXCI+XHJcbiAgICAgICAgICAgIDxQbHVzIGNsYXNzPVwidy00IGgtNCB0ZXh0LWZvcmVncm91bmQtMiByb3RhdGUtNDVcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvYW5jaG9yZWQtcG9pbnQvTmV3VGhyZWFkLnZ1ZTozMDoxM1wiIC8+XHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8Rm9ybUZpbGVVcGxvYWRab25lXHJcbiAgICAgICAgICB2LWlmPVwibW9kZWxWYWx1ZS5pc0V4cGFuZGVkICYmIGNhblBvc3RDb21tZW50XCJcclxuICAgICAgICAgIHJlZj1cInVwbG9hZFpvbmVcIlxyXG4gICAgICAgICAgdi1zbG90PVwieyBpc0RyYWdnaW5nRmlsZXMgfVwiXHJcbiAgICAgICAgICA6c2l6ZS1saW1pdD1cIm1heFNpemVJbkJ5dGVzXCJcclxuICAgICAgICAgIDphY2NlcHQ9XCJhY2NlcHRWYWx1ZVwiXHJcbiAgICAgICAgICA6ZGlzYWJsZWQ9XCJpc1Bvc3RpbmdOZXdUaHJlYWRcIlxyXG4gICAgICAgICAgbXVsdGlwbGVcclxuICAgICAgICAgIEBmaWxlcy1zZWxlY3RlZD1cIm9uRmlsZXNTZWxlY3RlZFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjMzOjlcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxkaXZcclxuICAgICAgICAgICAgcmVmPVwidGhyZWFkQ29udGFpbmVyXCJcclxuICAgICAgICAgICAgY2xhc3M9XCJzbTphYnNvbHV0ZSB3LWZ1bGwgc206dy1bMjYwcHhdIGJnLWZvdW5kYXRpb24gZGFyazpiZy1mb3VuZGF0aW9uLTIgYm9yZGVyIHNtOnJvdW5kZWQteGwgc2hhZG93LW1kXCJcclxuICAgICAgICAgICAgOmNsYXNzPVwiXHJcbiAgICAgICAgICAgICAgaXNEcmFnZ2luZ0ZpbGVzID8gJ2JvcmRlci1kYXNoZWQgYm9yZGVyLXByaW1hcnknIDogJ2JvcmRlci1vdXRsaW5lLTInXHJcbiAgICAgICAgICAgIFwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjQzOjExXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPFZpZXdlckNvbW1lbnRzRWRpdG9yXHJcbiAgICAgICAgICAgICAgcmVmPVwiZWRpdG9yXCJcclxuICAgICAgICAgICAgICB2LW1vZGVsPVwiY29tbWVudFZhbHVlXCJcclxuICAgICAgICAgICAgICBwcm9tcHQ9XCJBZGQgY29tbWVudFwiXHJcbiAgICAgICAgICAgICAgbWF4LWhlaWdodD1cIjMwMHB4XCJcclxuICAgICAgICAgICAgICBhdXRvZm9jdXNcclxuICAgICAgICAgICAgICBkaXNhYmxlLWRyb3Atem9uZVxyXG4gICAgICAgICAgICAgIDpkaXNhYmxlZD1cImlzUG9zdGluZ05ld1RocmVhZFwiXHJcbiAgICAgICAgICAgICAgQHN1Ym1pdD1cIigpID0+IG9uU3VibWl0KClcIlxyXG4gICAgICAgICAgICAgIEBrZXlkb3duPVwib25LZXlEb3duSGFuZGxlclwiIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjUwOjEzXCJcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBmbGV4IGp1c3RpZnktYmV0d2VlbiBpdGVtcy1jZW50ZXIgcC0xXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2FuY2hvcmVkLXBvaW50L05ld1RocmVhZC52dWU6NjE6MTNcIj5cclxuICAgICAgICAgICAgICA8Rm9ybUJ1dHRvblxyXG4gICAgICAgICAgICAgICAgOmljb24tbGVmdD1cIlBhcGVyY2xpcFwiXHJcbiAgICAgICAgICAgICAgICBoaWRlLXRleHRcclxuICAgICAgICAgICAgICAgIDpkaXNhYmxlZD1cImlzUG9zdGluZ05ld1RocmVhZFwiXHJcbiAgICAgICAgICAgICAgICBjb2xvcj1cInN1YnRsZVwiXHJcbiAgICAgICAgICAgICAgICBAY2xpY2s9XCJ0cmFja0F0dGFjaEFuZE9wZW5GaWxlUGlja2VyKClcIiBkYXRhLXYtaW5zcGVjdG9yPVwiY29tcG9uZW50cy92aWV3ZXIvYW5jaG9yZWQtcG9pbnQvTmV3VGhyZWFkLnZ1ZTo2MjoxNVwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgICA8Rm9ybUJ1dHRvblxyXG4gICAgICAgICAgICAgICAgOmljb24tbGVmdD1cIlNlbmRIb3Jpem9uYWxcIlxyXG4gICAgICAgICAgICAgICAgaGlkZS10ZXh0XHJcbiAgICAgICAgICAgICAgICA6bG9hZGluZz1cImlzUG9zdGluZ05ld1RocmVhZFwiXHJcbiAgICAgICAgICAgICAgICBAY2xpY2s9XCIoKSA9PiBvblN1Ym1pdCgpXCIgZGF0YS12LWluc3BlY3Rvcj1cImNvbXBvbmVudHMvdmlld2VyL2FuY2hvcmVkLXBvaW50L05ld1RocmVhZC52dWU6Njk6MTVcIlxyXG4gICAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9Gb3JtRmlsZVVwbG9hZFpvbmU+XHJcbiAgICAgIDwvVmlld2VyQ29tbWVudHNQb3J0YWxPckRpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDxkaXYgdi1lbHNlIGRhdGEtdi1pbnNwZWN0b3I9XCJjb21wb25lbnRzL3ZpZXdlci9hbmNob3JlZC1wb2ludC9OZXdUaHJlYWQudnVlOjgxOjNcIj48L2Rpdj5cclxuPC90ZW1wbGF0ZT5cclxuPHNjcmlwdCBzZXR1cCBsYW5nPVwidHNcIj5cclxuaW1wb3J0IHR5cGUgeyBOdWxsYWJsZSB9IGZyb20gJ0BzcGVja2xlL3NoYXJlZCdcclxuaW1wb3J0IHsgb25LZXlEb3duIH0gZnJvbSAnQHZ1ZXVzZS9jb3JlJ1xyXG5pbXBvcnQgeyB1c2VJc1R5cGluZ1VwZGF0ZUVtaXR0ZXIgfSBmcm9tICd+fi9saWIvdmlld2VyL2NvbXBvc2FibGVzL2NvbW1lbnRCdWJibGVzJ1xyXG5pbXBvcnQgdHlwZSB7IFZpZXdlck5ld1RocmVhZEJ1YmJsZU1vZGVsIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9jb21tZW50QnViYmxlcydcclxuaW1wb3J0IHsgdXNlU3VibWl0Q29tbWVudCB9IGZyb20gJ35+L2xpYi92aWV3ZXIvY29tcG9zYWJsZXMvY29tbWVudE1hbmFnZW1lbnQnXHJcbmltcG9ydCB0eXBlIHsgQ29tbWVudEVkaXRvclZhbHVlIH0gZnJvbSAnfn4vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9jb21tZW50TWFuYWdlbWVudCdcclxuaW1wb3J0IHtcclxuICBpc1ZhbGlkQ29tbWVudENvbnRlbnRJbnB1dCxcclxuICBjb252ZXJ0Q29tbWVudEVkaXRvclZhbHVlVG9JbnB1dFxyXG59IGZyb20gJ35+L2xpYi92aWV3ZXIvaGVscGVycy9jb21tZW50cydcclxuaW1wb3J0IHsgdXNlTWl4cGFuZWwgfSBmcm9tICd+fi9saWIvY29yZS9jb21wb3NhYmxlcy9tcCdcclxuaW1wb3J0IHsgdXNlVGhyZWFkVXRpbGl0aWVzLCB1c2VTZWxlY3Rpb25VdGlsaXRpZXMgfSBmcm9tICd+fi9saWIvdmlld2VyL2NvbXBvc2FibGVzL3VpJ1xyXG5pbXBvcnQgeyB1c2VFbWJlZCB9IGZyb20gJ34vbGliL3ZpZXdlci9jb21wb3NhYmxlcy9zZXR1cC9lbWJlZCdcclxuaW1wb3J0IHsgdXNlU2VydmVyRmlsZVVwbG9hZExpbWl0IH0gZnJvbSAnfn4vbGliL2NvbW1vbi9jb21wb3NhYmxlcy9zZXJ2ZXJJbmZvJ1xyXG5pbXBvcnQgeyBVbmlxdWVGaWxlVHlwZVNwZWNpZmllciB9IGZyb20gJ35+L2xpYi9jb3JlL2hlbHBlcnMvZmlsZSdcclxuaW1wb3J0IHsgYWNjZXB0ZWRGaWxlRXh0ZW5zaW9ucyB9IGZyb20gJ0BzcGVja2xlL3NoYXJlZC9ibG9icydcclxuaW1wb3J0IHR5cGUgeyBVcGxvYWRhYmxlRmlsZUl0ZW0gfSBmcm9tICdAc3BlY2tsZS91aS1jb21wb25lbnRzJ1xyXG5pbXBvcnQgeyBQYXBlcmNsaXAsIFNlbmRIb3Jpem9uYWwsIFBsdXMgfSBmcm9tICdsdWNpZGUtdnVlLW5leHQnXHJcblxyXG5jb25zdCB7IGlzRW5hYmxlZDogaXNFbWJlZEVuYWJsZWQgfSA9IHVzZUVtYmVkKClcclxuXHJcbmNvbnN0IGVtaXQgPSBkZWZpbmVFbWl0czx7XHJcbiAgKGU6ICd1cGRhdGU6bW9kZWxWYWx1ZScsIHY6IFZpZXdlck5ld1RocmVhZEJ1YmJsZU1vZGVsKTogdm9pZFxyXG4gIChlOiAnY2xvc2UnKTogdm9pZFxyXG4gIChlOiAnbG9naW4nKTogdm9pZFxyXG59PigpXHJcblxyXG5jb25zdCBwcm9wcyA9IGRlZmluZVByb3BzPHtcclxuICBtb2RlbFZhbHVlOiBWaWV3ZXJOZXdUaHJlYWRCdWJibGVNb2RlbFxyXG4gIGNhblBvc3RDb21tZW50PzogTnVsbGFibGU8Ym9vbGVhbj5cclxufT4oKVxyXG5cclxuY29uc3QgeyBvbktleURvd25IYW5kbGVyLCB1cGRhdGVJc1R5cGluZywgcGF1c2VBdXRvbWF0aWNVcGRhdGVzIH0gPVxyXG4gIHVzZUlzVHlwaW5nVXBkYXRlRW1pdHRlcigpXHJcbmNvbnN0IHsgY2xvc2VBbGxUaHJlYWRzLCBvcGVuIH0gPSB1c2VUaHJlYWRVdGlsaXRpZXMoKVxyXG5jb25zdCB7IG1heFNpemVJbkJ5dGVzIH0gPSB1c2VTZXJ2ZXJGaWxlVXBsb2FkTGltaXQoKVxyXG5cclxuY29uc3QgZWRpdG9yID0gcmVmKFxyXG4gIG51bGwgYXMgTnVsbGFibGU8e1xyXG4gICAgb3BlbkZpbGVQaWNrZXI6ICgpID0+IHZvaWRcclxuICAgIG9uRmlsZXNTZWxlY3RlZDogKHBheWxvYWQ6IHsgZmlsZXM6IFVwbG9hZGFibGVGaWxlSXRlbVtdIH0pID0+IHZvaWRcclxuICB9PlxyXG4pXHJcbmNvbnN0IHVwbG9hZFpvbmUgPSByZWYobnVsbCBhcyBOdWxsYWJsZTx7IHRyaWdnZXJQaWNrZXI6ICgpID0+IHZvaWQgfT4pXHJcbmNvbnN0IGNvbW1lbnRWYWx1ZSA9IHJlZjxDb21tZW50RWRpdG9yVmFsdWU+KHsgZG9jOiB1bmRlZmluZWQsIGF0dGFjaG1lbnRzOiB1bmRlZmluZWQgfSlcclxuY29uc3QgdGhyZWFkQ29udGFpbmVyID0gcmVmKG51bGwgYXMgTnVsbGFibGU8SFRNTEVsZW1lbnQ+KVxyXG5jb25zdCBpc1Bvc3RpbmdOZXdUaHJlYWQgPSByZWYoZmFsc2UpXHJcblxyXG5jb25zdCBhY2NlcHRWYWx1ZSA9IFtcclxuICBVbmlxdWVGaWxlVHlwZVNwZWNpZmllci5BbnlJbWFnZSxcclxuICBVbmlxdWVGaWxlVHlwZVNwZWNpZmllci5BbnlWaWRlbyxcclxuICAuLi5hY2NlcHRlZEZpbGVFeHRlbnNpb25zLm1hcCgoZmlsZUV4dGVuc2lvbikgPT4gYC4ke2ZpbGVFeHRlbnNpb259YClcclxuXS5qb2luKCcsJylcclxuXHJcbmNvbnN0IG9uRmlsZXNTZWxlY3RlZCA9IChwYXlsb2FkOiB7IGZpbGVzOiBVcGxvYWRhYmxlRmlsZUl0ZW1bXSB9KSA9PiB7XHJcbiAgZWRpdG9yLnZhbHVlPy5vbkZpbGVzU2VsZWN0ZWQocGF5bG9hZClcclxufVxyXG5cclxuLy8gY29uc3QgeyBzdHlsZSB9ID0gdXNlRXhwYW5kZWRUaHJlYWRSZXNwb25zaXZlTG9jYXRpb24oe1xyXG4vLyAgIHRocmVhZENvbnRhaW5lcixcclxuLy8gICB3aWR0aDogMzIwXHJcbi8vIH0pXHJcbmNvbnN0IGNyZWF0ZVRocmVhZCA9IHVzZVN1Ym1pdENvbW1lbnQoKVxyXG5jb25zdCB7IGlzTG9nZ2VkSW4gfSA9IHVzZUFjdGl2ZVVzZXIoKVxyXG5jb25zdCB7IG9iamVjdHMgfSA9IHVzZVNlbGVjdGlvblV0aWxpdGllcygpXHJcblxyXG5jb25zdCBvblRocmVhZENsaWNrID0gKCkgPT4ge1xyXG4gIGNvbnN0IG5ld0lzRXhwYW5kZWQgPSAhcHJvcHMubW9kZWxWYWx1ZS5pc0V4cGFuZGVkXHJcblxyXG4gIGlmICghaXNMb2dnZWRJbi52YWx1ZSB8fCAhcHJvcHMuY2FuUG9zdENvbW1lbnQpIHtcclxuICAgIGlmICghaXNMb2dnZWRJbi52YWx1ZSkge1xyXG4gICAgICBlbWl0KCdsb2dpbicpXHJcbiAgICB9XHJcbiAgICByZXR1cm5cclxuICB9XHJcblxyXG4gIGlmICghbmV3SXNFeHBhbmRlZCkge1xyXG4gICAgdXBkYXRlSXNUeXBpbmcoZmFsc2UpXHJcbiAgfVxyXG4gIGVtaXQoJ3VwZGF0ZTptb2RlbFZhbHVlJywge1xyXG4gICAgLi4ucHJvcHMubW9kZWxWYWx1ZSxcclxuICAgIGlzRXhwYW5kZWQ6IG5ld0lzRXhwYW5kZWRcclxuICB9KVxyXG59XHJcblxyXG5jb25zdCBtcCA9IHVzZU1peHBhbmVsKClcclxuXHJcbmNvbnN0IG9uU3VibWl0ID0gKGNvbW1lbnQ/OiBDb21tZW50RWRpdG9yVmFsdWUpID0+IHtcclxuICBjb21tZW50IHx8PSBjb21tZW50IHx8IGNvbW1lbnRWYWx1ZS52YWx1ZVxyXG4gIGlmICghY29tbWVudD8uZG9jKSByZXR1cm5cclxuXHJcbiAgY29uc3QgY29udGVudCA9IGNvbnZlcnRDb21tZW50RWRpdG9yVmFsdWVUb0lucHV0KGNvbW1lbnRWYWx1ZS52YWx1ZSlcclxuICBpZiAoIWlzVmFsaWRDb21tZW50Q29udGVudElucHV0KGNvbnRlbnQpKSByZXR1cm5cclxuXHJcbiAgaXNQb3N0aW5nTmV3VGhyZWFkLnZhbHVlID0gdHJ1ZVxyXG4gIHBhdXNlQXV0b21hdGljVXBkYXRlcy52YWx1ZSA9IHRydWVcclxuICB1cGRhdGVJc1R5cGluZyh0cnVlKSAvLyBzbyB0aGF0IHVzZXIgc2hvd3MgdXAgYXMgdHlwaW5nIHVudGlsIHRoZSBuZXcgYnViYmxlIGFwcGVhcnNcclxuICBjcmVhdGVUaHJlYWQoY29udGVudClcclxuICAgIC50aGVuKGFzeW5jIChuZXdUaHJlYWQpID0+IHtcclxuICAgICAgY29uc3QgdGhyZWFkSWQgPSBuZXdUaHJlYWQ/LmlkXHJcbiAgICAgIGlmICghdGhyZWFkSWQpIHJldHVyblxyXG5cclxuICAgICAgLy8gc3dpdGNoIHRvIG5ldyB0aHJlYWRcclxuICAgICAgYXdhaXQgb3Blbih0aHJlYWRJZClcclxuXHJcbiAgICAgIC8vIENsb3NlIHRoZSBuZXcgdGhyZWFkIGJ1YmJsZSBhZnRlciBzdWNjZXNzZnVsIHN1Ym1pc3Npb25cclxuICAgICAgZW1pdCgndXBkYXRlOm1vZGVsVmFsdWUnLCB7XHJcbiAgICAgICAgLi4ucHJvcHMubW9kZWxWYWx1ZSxcclxuICAgICAgICBpc0V4cGFuZGVkOiBmYWxzZVxyXG4gICAgICB9KVxyXG4gICAgfSlcclxuICAgIC5maW5hbGx5KCgpID0+IHtcclxuICAgICAgaXNQb3N0aW5nTmV3VGhyZWFkLnZhbHVlID0gZmFsc2VcclxuICAgICAgdXBkYXRlSXNUeXBpbmcoZmFsc2UpXHJcbiAgICAgIHBhdXNlQXV0b21hdGljVXBkYXRlcy52YWx1ZSA9IGZhbHNlXHJcbiAgICB9KVxyXG5cclxuICBtcC50cmFjaygnQ29tbWVudCBBY3Rpb24nLCB7IHR5cGU6ICdhY3Rpb24nLCBuYW1lOiAnY3JlYXRlJyB9KVxyXG4gIC8vIE1hcmtpbmcgYWxsIHVwbG9hZHMgYXMgaW4gdXNlIHRvIHByZXZlbnQgY2xlYW51cFxyXG4gIGNvbW1lbnQuYXR0YWNobWVudHM/LmZvckVhY2goKGEpID0+IHtcclxuICAgIGEuaW5Vc2UgPSB0cnVlXHJcbiAgfSlcclxufVxyXG5cclxuY29uc3QgdHJhY2tBdHRhY2hBbmRPcGVuRmlsZVBpY2tlciA9ICgpID0+IHtcclxuICB1cGxvYWRab25lLnZhbHVlPy50cmlnZ2VyUGlja2VyKClcclxuICBtcC50cmFjaygnQ29tbWVudCBBY3Rpb24nLCB7IHR5cGU6ICdhY3Rpb24nLCBuYW1lOiAnYXR0YWNoJyB9KVxyXG59XHJcblxyXG5jb25zdCBzaG91bGRTaG93VGhyZWFkQnViYmxlID0gY29tcHV0ZWQoKCkgPT4ge1xyXG4gIHJldHVybiBwcm9wcy5tb2RlbFZhbHVlLmlzVmlzaWJsZSAmJiBvYmplY3RzLnZhbHVlLmxlbmd0aCA+IDBcclxufSlcclxuXHJcbm9uS2V5RG93bignRXNjYXBlJywgKCkgPT4ge1xyXG4gIGlmIChwcm9wcy5tb2RlbFZhbHVlLmlzRXhwYW5kZWQpIHtcclxuICAgIG9uVGhyZWFkQ2xpY2soKVxyXG4gIH1cclxufSlcclxuXHJcbndhdGNoKFxyXG4gICgpID0+IHByb3BzLm1vZGVsVmFsdWUuaXNFeHBhbmRlZCxcclxuICBhc3luYyAobmV3VmFsKSA9PiB7XHJcbiAgICBpZiAobmV3VmFsKSB7XHJcbiAgICAgIGF3YWl0IGNsb3NlQWxsVGhyZWFkcygpXHJcbiAgICB9XHJcbiAgICBjb21tZW50VmFsdWUudmFsdWUgPSB7XHJcbiAgICAgIGRvYzogdW5kZWZpbmVkLFxyXG4gICAgICBhdHRhY2htZW50czogdW5kZWZpbmVkXHJcbiAgICB9XHJcbiAgfVxyXG4pXHJcbjwvc2NyaXB0PlxyXG4iXSwiZmlsZSI6IkQ6L3NwZWNrbGUtc2VydmVyL3BhY2thZ2VzL2Zyb250ZW5kLTIvY29tcG9uZW50cy92aWV3ZXIvYW5jaG9yZWQtcG9pbnQvTmV3VGhyZWFkLnZ1ZSJ9