"use strict"; /* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ exports.id = "vendor-chunks/@fullcalendar"; exports.ids = ["vendor-chunks/@fullcalendar"]; exports.modules = { /***/ "(ssr)/./node_modules/@fullcalendar/core/index.js": /*!**************************************************!*\ !*** ./node_modules/@fullcalendar/core/index.js ***! \**************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Calendar: () => (/* binding */ Calendar),\n/* harmony export */ JsonRequestError: () => (/* reexport safe */ _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ae),\n/* harmony export */ createPlugin: () => (/* binding */ createPlugin),\n/* harmony export */ formatDate: () => (/* binding */ formatDate),\n/* harmony export */ formatRange: () => (/* binding */ formatRange),\n/* harmony export */ globalLocales: () => (/* binding */ globalLocales),\n/* harmony export */ globalPlugins: () => (/* binding */ globalPlugins),\n/* harmony export */ sliceEvents: () => (/* binding */ sliceEvents),\n/* harmony export */ version: () => (/* binding */ version)\n/* harmony export */ });\n/* harmony import */ var _internal_common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal-common.js */ \"(ssr)/./node_modules/@fullcalendar/core/internal-common.js\");\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact */ \"(ssr)/./node_modules/preact/dist/preact.mjs\");\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! preact/compat */ \"(ssr)/./node_modules/preact/compat/dist/compat.mjs\");\n\n\n\n\n\nconst globalLocales = [];\n\nconst MINIMAL_RAW_EN_LOCALE = {\n code: 'en',\n week: {\n dow: 0,\n doy: 4, // 4 days need to be within the year to be considered the first week\n },\n direction: 'ltr',\n buttonText: {\n prev: 'prev',\n next: 'next',\n prevYear: 'prev year',\n nextYear: 'next year',\n year: 'year',\n today: 'today',\n month: 'month',\n week: 'week',\n day: 'day',\n list: 'list',\n },\n weekText: 'W',\n weekTextLong: 'Week',\n closeHint: 'Close',\n timeHint: 'Time',\n eventHint: 'Event',\n allDayText: 'all-day',\n moreLinkText: 'more',\n noEventsText: 'No events to display',\n};\nconst RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), { \n // Includes things we don't want other locales to inherit,\n // things that derive from other translatable strings.\n buttonHints: {\n prev: 'Previous $0',\n next: 'Next $0',\n today(buttonText, unit) {\n return (unit === 'day')\n ? 'Today'\n : `This ${buttonText}`;\n },\n }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint(eventCnt) {\n return `Show ${eventCnt} more event${eventCnt === 1 ? '' : 's'}`;\n } });\nfunction organizeRawLocales(explicitRawLocales) {\n let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';\n let allRawLocales = globalLocales.concat(explicitRawLocales);\n let rawLocaleMap = {\n en: RAW_EN_LOCALE,\n };\n for (let rawLocale of allRawLocales) {\n rawLocaleMap[rawLocale.code] = rawLocale;\n }\n return {\n map: rawLocaleMap,\n defaultCode,\n };\n}\nfunction buildLocale(inputSingular, available) {\n if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {\n return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);\n }\n return queryLocale(inputSingular, available);\n}\nfunction queryLocale(codeArg, available) {\n let codes = [].concat(codeArg || []); // will convert to array\n let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;\n return parseLocale(codeArg, codes, raw);\n}\nfunction queryRawLocale(codes, available) {\n for (let i = 0; i < codes.length; i += 1) {\n let parts = codes[i].toLocaleLowerCase().split('-');\n for (let j = parts.length; j > 0; j -= 1) {\n let simpleId = parts.slice(0, j).join('-');\n if (available[simpleId]) {\n return available[simpleId];\n }\n }\n }\n return null;\n}\nfunction parseLocale(codeArg, codes, raw) {\n let merged = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.m)([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);\n delete merged.code; // don't want this part of the options\n let { week } = merged;\n delete merged.week;\n return {\n codeArg,\n codes,\n week,\n simpleNumberFormat: new Intl.NumberFormat(codeArg),\n options: merged,\n };\n}\n\n// TODO: easier way to add new hooks? need to update a million things\nfunction createPlugin(input) {\n return {\n id: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)(),\n name: input.name,\n premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : undefined,\n deps: input.deps || [],\n reducers: input.reducers || [],\n isLoadingFuncs: input.isLoadingFuncs || [],\n contextInit: [].concat(input.contextInit || []),\n eventRefiners: input.eventRefiners || {},\n eventDefMemberAdders: input.eventDefMemberAdders || [],\n eventSourceRefiners: input.eventSourceRefiners || {},\n isDraggableTransformers: input.isDraggableTransformers || [],\n eventDragMutationMassagers: input.eventDragMutationMassagers || [],\n eventDefMutationAppliers: input.eventDefMutationAppliers || [],\n dateSelectionTransformers: input.dateSelectionTransformers || [],\n datePointTransforms: input.datePointTransforms || [],\n dateSpanTransforms: input.dateSpanTransforms || [],\n views: input.views || {},\n viewPropsTransformers: input.viewPropsTransformers || [],\n isPropsValid: input.isPropsValid || null,\n externalDefTransforms: input.externalDefTransforms || [],\n viewContainerAppends: input.viewContainerAppends || [],\n eventDropTransformers: input.eventDropTransformers || [],\n componentInteractions: input.componentInteractions || [],\n calendarInteractions: input.calendarInteractions || [],\n themeClasses: input.themeClasses || {},\n eventSourceDefs: input.eventSourceDefs || [],\n cmdFormatter: input.cmdFormatter,\n recurringTypes: input.recurringTypes || [],\n namedTimeZonedImpl: input.namedTimeZonedImpl,\n initialView: input.initialView || '',\n elementDraggingImpl: input.elementDraggingImpl,\n optionChangeHandlers: input.optionChangeHandlers || {},\n scrollGridImpl: input.scrollGridImpl || null,\n listenerRefiners: input.listenerRefiners || {},\n optionRefiners: input.optionRefiners || {},\n propSetHandlers: input.propSetHandlers || {},\n };\n}\nfunction buildPluginHooks(pluginDefs, globalDefs) {\n let currentPluginIds = {};\n let hooks = {\n premiumReleaseDate: undefined,\n reducers: [],\n isLoadingFuncs: [],\n contextInit: [],\n eventRefiners: {},\n eventDefMemberAdders: [],\n eventSourceRefiners: {},\n isDraggableTransformers: [],\n eventDragMutationMassagers: [],\n eventDefMutationAppliers: [],\n dateSelectionTransformers: [],\n datePointTransforms: [],\n dateSpanTransforms: [],\n views: {},\n viewPropsTransformers: [],\n isPropsValid: null,\n externalDefTransforms: [],\n viewContainerAppends: [],\n eventDropTransformers: [],\n componentInteractions: [],\n calendarInteractions: [],\n themeClasses: {},\n eventSourceDefs: [],\n cmdFormatter: null,\n recurringTypes: [],\n namedTimeZonedImpl: null,\n initialView: '',\n elementDraggingImpl: null,\n optionChangeHandlers: {},\n scrollGridImpl: null,\n listenerRefiners: {},\n optionRefiners: {},\n propSetHandlers: {},\n };\n function addDefs(defs) {\n for (let def of defs) {\n const pluginName = def.name;\n const currentId = currentPluginIds[pluginName];\n if (currentId === undefined) {\n currentPluginIds[pluginName] = def.id;\n addDefs(def.deps);\n hooks = combineHooks(hooks, def);\n }\n else if (currentId !== def.id) {\n // different ID than the one already added\n console.warn(`Duplicate plugin '${pluginName}'`);\n }\n }\n }\n if (pluginDefs) {\n addDefs(pluginDefs);\n }\n addDefs(globalDefs);\n return hooks;\n}\nfunction buildBuildPluginHooks() {\n let currentOverrideDefs = [];\n let currentGlobalDefs = [];\n let currentHooks;\n return (overrideDefs, globalDefs) => {\n if (!currentHooks || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(overrideDefs, currentOverrideDefs) || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(globalDefs, currentGlobalDefs)) {\n currentHooks = buildPluginHooks(overrideDefs, globalDefs);\n }\n currentOverrideDefs = overrideDefs;\n currentGlobalDefs = globalDefs;\n return currentHooks;\n };\n}\nfunction combineHooks(hooks0, hooks1) {\n return {\n premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate),\n reducers: hooks0.reducers.concat(hooks1.reducers),\n isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),\n contextInit: hooks0.contextInit.concat(hooks1.contextInit),\n eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners),\n eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),\n eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),\n isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),\n eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),\n eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),\n dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),\n datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),\n dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),\n views: Object.assign(Object.assign({}, hooks0.views), hooks1.views),\n viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),\n isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,\n externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),\n viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),\n eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),\n calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),\n componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),\n themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses),\n eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),\n cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,\n recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),\n namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,\n initialView: hooks0.initialView || hooks1.initialView,\n elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,\n optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),\n scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,\n listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),\n optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners),\n propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),\n };\n}\nfunction compareOptionalDates(date0, date1) {\n if (date0 === undefined) {\n return date1;\n }\n if (date1 === undefined) {\n return date0;\n }\n return new Date(Math.max(date0.valueOf(), date1.valueOf()));\n}\n\nclass StandardTheme extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.T {\n}\nStandardTheme.prototype.classes = {\n root: 'fc-theme-standard',\n tableCellShaded: 'fc-cell-shaded',\n buttonGroup: 'fc-button-group',\n button: 'fc-button fc-button-primary',\n buttonActive: 'fc-button-active',\n};\nStandardTheme.prototype.baseIconClass = 'fc-icon';\nStandardTheme.prototype.iconClasses = {\n close: 'fc-icon-x',\n prev: 'fc-icon-chevron-left',\n next: 'fc-icon-chevron-right',\n prevYear: 'fc-icon-chevrons-left',\n nextYear: 'fc-icon-chevrons-right',\n};\nStandardTheme.prototype.rtlIconClasses = {\n prev: 'fc-icon-chevron-right',\n next: 'fc-icon-chevron-left',\n prevYear: 'fc-icon-chevrons-right',\n nextYear: 'fc-icon-chevrons-left',\n};\nStandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly\nStandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';\nStandardTheme.prototype.iconOverridePrefix = 'fc-icon-';\n\nfunction compileViewDefs(defaultConfigs, overrideConfigs) {\n let hash = {};\n let viewType;\n for (viewType in defaultConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n for (viewType in overrideConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n return hash;\n}\nfunction ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n if (hash[viewType]) {\n return hash[viewType];\n }\n let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n if (viewDef) {\n hash[viewType] = viewDef;\n }\n return viewDef;\n}\nfunction buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n let defaultConfig = defaultConfigs[viewType];\n let overrideConfig = overrideConfigs[viewType];\n let queryProp = (name) => ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :\n ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null));\n let theComponent = queryProp('component');\n let superType = queryProp('superType');\n let superDef = null;\n if (superType) {\n if (superType === viewType) {\n throw new Error('Can\\'t have a custom view type that references itself');\n }\n superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);\n }\n if (!theComponent && superDef) {\n theComponent = superDef.component;\n }\n if (!theComponent) {\n return null; // don't throw a warning, might be settings for a single-unit view\n }\n return {\n type: viewType,\n component: theComponent,\n defaults: Object.assign(Object.assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),\n overrides: Object.assign(Object.assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),\n };\n}\n\nfunction parseViewConfigs(inputs) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(inputs, parseViewConfig);\n}\nfunction parseViewConfig(input) {\n let rawOptions = typeof input === 'function' ?\n { component: input } :\n input;\n let { component } = rawOptions;\n if (rawOptions.content) {\n // TODO: remove content/classNames/didMount/etc from options?\n component = createViewHookComponent(rawOptions);\n }\n else if (component && !(component.prototype instanceof _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B)) {\n // WHY?: people were using `component` property for `content`\n // TODO: converge on one setting name\n component = createViewHookComponent(Object.assign(Object.assign({}, rawOptions), { content: component }));\n }\n return {\n superType: rawOptions.type,\n component: component,\n rawOptions, // includes type and component too :(\n };\n}\nfunction createViewHookComponent(options) {\n return (viewProps) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, (context) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"div\", elClasses: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.b)(context.viewSpec), renderProps: Object.assign(Object.assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }), generatorName: undefined, customGenerator: options.content, classNameGenerator: options.classNames, didMount: options.didMount, willUnmount: options.willUnmount }))));\n}\n\nfunction buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let defaultConfigs = parseViewConfigs(defaultInputs);\n let overrideConfigs = parseViewConfigs(optionOverrides.views);\n let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(viewDefs, (viewDef) => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults));\n}\nfunction buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let durationInput = viewDef.overrides.duration ||\n viewDef.defaults.duration ||\n dynamicOptionOverrides.duration ||\n optionOverrides.duration;\n let duration = null;\n let durationUnit = '';\n let singleUnit = '';\n let singleUnitOverrides = {};\n if (durationInput) {\n duration = createDurationCached(durationInput);\n if (duration) { // valid?\n let denom = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.c)(duration);\n durationUnit = denom.unit;\n if (denom.value === 1) {\n singleUnit = durationUnit;\n singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};\n }\n }\n }\n let queryButtonText = (optionsSubset) => {\n let buttonTextMap = optionsSubset.buttonText || {};\n let buttonTextKey = viewDef.defaults.buttonTextKey;\n if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {\n return buttonTextMap[buttonTextKey];\n }\n if (buttonTextMap[viewDef.type] != null) {\n return buttonTextMap[viewDef.type];\n }\n if (buttonTextMap[singleUnit] != null) {\n return buttonTextMap[singleUnit];\n }\n return null;\n };\n let queryButtonTitle = (optionsSubset) => {\n let buttonHints = optionsSubset.buttonHints || {};\n let buttonKey = viewDef.defaults.buttonTextKey; // use same key as text\n if (buttonKey != null && buttonHints[buttonKey] != null) {\n return buttonHints[buttonKey];\n }\n if (buttonHints[viewDef.type] != null) {\n return buttonHints[viewDef.type];\n }\n if (buttonHints[singleUnit] != null) {\n return buttonHints[singleUnit];\n }\n return null;\n };\n return {\n type: viewDef.type,\n component: viewDef.component,\n duration,\n durationUnit,\n singleUnit,\n optionDefaults: viewDef.defaults,\n optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides),\n buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||\n queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence\n viewDef.overrides.buttonText,\n buttonTextDefault: queryButtonText(localeDefaults) ||\n viewDef.defaults.buttonText ||\n queryButtonText(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e) ||\n viewDef.type,\n // not DRY\n buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) ||\n queryButtonTitle(optionOverrides) ||\n viewDef.overrides.buttonHint,\n buttonTitleDefault: queryButtonTitle(localeDefaults) ||\n viewDef.defaults.buttonHint ||\n queryButtonTitle(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e),\n // will eventually fall back to buttonText\n };\n}\n// hack to get memoization working\nlet durationInputMap = {};\nfunction createDurationCached(durationInput) {\n let json = JSON.stringify(durationInput);\n let res = durationInputMap[json];\n if (res === undefined) {\n res = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d)(durationInput);\n durationInputMap[json] = res;\n }\n return res;\n}\n\nfunction reduceViewType(viewType, action) {\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n viewType = action.viewType;\n }\n return viewType;\n}\n\nfunction reduceCurrentDate(currentDate, action) {\n switch (action.type) {\n case 'CHANGE_DATE':\n return action.dateMarker;\n default:\n return currentDate;\n }\n}\n// should be initialized once and stay constant\n// this will change too\nfunction getInitialDate(options, dateEnv, nowManager) {\n let initialDateInput = options.initialDate;\n // compute the initial ambig-timezone date\n if (initialDateInput != null) {\n return dateEnv.createMarker(initialDateInput);\n }\n return nowManager.getDateMarker();\n}\n\nfunction reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {\n switch (action.type) {\n case 'SET_OPTION':\n return Object.assign(Object.assign({}, dynamicOptionOverrides), { [action.optionName]: action.rawOptionValue });\n default:\n return dynamicOptionOverrides;\n }\n}\n\nfunction reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {\n let dp;\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n return dateProfileGenerator.build(action.dateMarker || currentDate);\n case 'CHANGE_DATE':\n return dateProfileGenerator.build(action.dateMarker);\n case 'PREV':\n dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n case 'NEXT':\n dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n }\n return currentDateProfile;\n}\n\nfunction initEventSources(calendarOptions, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null;\n return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);\n}\nfunction reduceEventSources(eventSources, action, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n switch (action.type) {\n case 'ADD_EVENT_SOURCES': // already parsed\n return addSources(eventSources, action.sources, activeRange, context);\n case 'REMOVE_EVENT_SOURCE':\n return removeSource(eventSources, action.sourceId);\n case 'PREV': // TODO: how do we track all actions that affect dateProfile :(\n case 'NEXT':\n case 'CHANGE_DATE':\n case 'CHANGE_VIEW_TYPE':\n if (dateProfile) {\n return fetchDirtySources(eventSources, activeRange, context);\n }\n return eventSources;\n case 'FETCH_EVENT_SOURCES':\n return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(action.sourceIds) :\n excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);\n case 'RECEIVE_EVENTS':\n case 'RECEIVE_EVENT_ERROR':\n return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);\n case 'REMOVE_ALL_EVENT_SOURCES':\n return {};\n default:\n return eventSources;\n }\n}\nfunction reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);\n}\nfunction computeEventSourcesLoading(eventSources) {\n for (let sourceId in eventSources) {\n if (eventSources[sourceId].isFetching) {\n return true;\n }\n }\n return false;\n}\nfunction addSources(eventSourceHash, sources, fetchRange, context) {\n let hash = {};\n for (let source of sources) {\n hash[source.sourceId] = source;\n }\n if (fetchRange) {\n hash = fetchDirtySources(hash, fetchRange, context);\n }\n return Object.assign(Object.assign({}, eventSourceHash), hash);\n}\nfunction removeSource(eventSourceHash, sourceId) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSourceHash, (eventSource) => eventSource.sourceId !== sourceId);\n}\nfunction fetchDirtySources(sourceHash, fetchRange, context) {\n return fetchSourcesByIds(sourceHash, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(sourceHash, (eventSource) => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context);\n}\nfunction isSourceDirty(eventSource, fetchRange, context) {\n if (!doesSourceNeedRange(eventSource, context)) {\n return !eventSource.latestFetchId;\n }\n return !context.options.lazyFetching ||\n !eventSource.fetchRange ||\n eventSource.isFetching || // always cancel outdated in-progress fetches\n fetchRange.start < eventSource.fetchRange.start ||\n fetchRange.end > eventSource.fetchRange.end;\n}\nfunction fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {\n let nextSources = {};\n for (let sourceId in prevSources) {\n let source = prevSources[sourceId];\n if (sourceIdHash[sourceId]) {\n nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);\n }\n else {\n nextSources[sourceId] = source;\n }\n }\n return nextSources;\n}\nfunction fetchSource(eventSource, fetchRange, isRefetch, context) {\n let { options, calendarApi } = context;\n let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];\n let fetchId = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)();\n sourceDef.fetch({\n eventSource,\n range: fetchRange,\n isRefetch,\n context,\n }, (res) => {\n let { rawEvents } = res;\n if (options.eventSourceSuccess) {\n rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n if (eventSource.success) {\n rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n context.dispatch({\n type: 'RECEIVE_EVENTS',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n rawEvents,\n });\n }, (error) => {\n let errorHandled = false;\n if (options.eventSourceFailure) {\n options.eventSourceFailure.call(calendarApi, error);\n errorHandled = true;\n }\n if (eventSource.failure) {\n eventSource.failure(error);\n errorHandled = true;\n }\n if (!errorHandled) {\n console.warn(error.message, error);\n }\n context.dispatch({\n type: 'RECEIVE_EVENT_ERROR',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n error,\n });\n });\n return Object.assign(Object.assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });\n}\nfunction receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {\n let eventSource = sourceHash[sourceId];\n if (eventSource && // not already removed\n fetchId === eventSource.latestFetchId) {\n return Object.assign(Object.assign({}, sourceHash), { [sourceId]: Object.assign(Object.assign({}, eventSource), { isFetching: false, fetchRange }) });\n }\n return sourceHash;\n}\nfunction excludeStaticSources(eventSources, context) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSources, (eventSource) => doesSourceNeedRange(eventSource, context));\n}\nfunction parseInitialSources(rawOptions, context) {\n let refiners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.j)(context);\n let rawSources = [].concat(rawOptions.eventSources || []);\n let sources = []; // parsed\n if (rawOptions.initialEvents) {\n rawSources.unshift(rawOptions.initialEvents);\n }\n if (rawOptions.events) {\n rawSources.unshift(rawOptions.events);\n }\n for (let rawSource of rawSources) {\n let source = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.p)(rawSource, context, refiners);\n if (source) {\n sources.push(source);\n }\n }\n return sources;\n}\nfunction doesSourceNeedRange(eventSource, context) {\n let defs = context.pluginHooks.eventSourceDefs;\n return !defs[eventSource.sourceDefId].ignoreRange;\n}\n\nfunction reduceDateSelection(currentSelection, action) {\n switch (action.type) {\n case 'UNSELECT_DATES':\n return null;\n case 'SELECT_DATES':\n return action.selection;\n default:\n return currentSelection;\n }\n}\n\nfunction reduceSelectedEvent(currentInstanceId, action) {\n switch (action.type) {\n case 'UNSELECT_EVENT':\n return '';\n case 'SELECT_EVENT':\n return action.eventInstanceId;\n default:\n return currentInstanceId;\n }\n}\n\nfunction reduceEventDrag(currentDrag, action) {\n let newDrag;\n switch (action.type) {\n case 'UNSET_EVENT_DRAG':\n return null;\n case 'SET_EVENT_DRAG':\n newDrag = action.state;\n return {\n affectedEvents: newDrag.affectedEvents,\n mutatedEvents: newDrag.mutatedEvents,\n isEvent: newDrag.isEvent,\n };\n default:\n return currentDrag;\n }\n}\n\nfunction reduceEventResize(currentResize, action) {\n let newResize;\n switch (action.type) {\n case 'UNSET_EVENT_RESIZE':\n return null;\n case 'SET_EVENT_RESIZE':\n newResize = action.state;\n return {\n affectedEvents: newResize.affectedEvents,\n mutatedEvents: newResize.mutatedEvents,\n isEvent: newResize.isEvent,\n };\n default:\n return currentResize;\n }\n}\n\nfunction parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n return { header, footer };\n}\nfunction parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let sectionWidgets = {};\n let viewsWithButtons = [];\n let hasTitle = false;\n for (let sectionName in sectionStrHash) {\n let sectionStr = sectionStrHash[sectionName];\n let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);\n sectionWidgets[sectionName] = sectionRes.widgets;\n viewsWithButtons.push(...sectionRes.viewsWithButtons);\n hasTitle = hasTitle || sectionRes.hasTitle;\n }\n return { sectionWidgets, viewsWithButtons, hasTitle };\n}\n/*\nBAD: querying icons and text here. should be done at render time\n*/\nfunction parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined\ncalendarOptionOverrides, // overrides only!, unrefined :(\ntheme, viewSpecs, calendarApi) {\n let isRtl = calendarOptions.direction === 'rtl';\n let calendarCustomButtons = calendarOptions.customButtons || {};\n let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};\n let calendarButtonText = calendarOptions.buttonText || {};\n let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};\n let calendarButtonHints = calendarOptions.buttonHints || {};\n let sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];\n let viewsWithButtons = [];\n let hasTitle = false;\n let widgets = sectionSubstrs.map((buttonGroupStr) => (buttonGroupStr.split(',').map((buttonName) => {\n if (buttonName === 'title') {\n hasTitle = true;\n return { buttonName };\n }\n let customButtonProps;\n let viewSpec;\n let buttonClick;\n let buttonIcon; // only one of these will be set\n let buttonText; // \"\n let buttonHint;\n // ^ for the title=\"\" attribute, for accessibility\n if ((customButtonProps = calendarCustomButtons[buttonName])) {\n buttonClick = (ev) => {\n if (customButtonProps.click) {\n customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?\n }\n };\n (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = customButtonProps.text);\n buttonHint = customButtonProps.hint || customButtonProps.text;\n }\n else if ((viewSpec = viewSpecs[buttonName])) {\n viewsWithButtons.push(buttonName);\n buttonClick = () => {\n calendarApi.changeView(buttonName);\n };\n (buttonText = viewSpec.buttonTextOverride) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = viewSpec.buttonTextDefault);\n let textFallback = viewSpec.buttonTextOverride ||\n viewSpec.buttonTextDefault;\n buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(viewSpec.buttonTitleOverride ||\n viewSpec.buttonTitleDefault ||\n calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName\n textFallback);\n }\n else if (calendarApi[buttonName]) { // a calendarApi method\n buttonClick = () => {\n calendarApi[buttonName]();\n };\n (buttonText = calendarButtonTextOverrides[buttonName]) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = calendarButtonText[buttonName]); // everything else is considered default\n if (buttonName === 'prevYear' || buttonName === 'nextYear') {\n let prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';\n buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[prevOrNext] ||\n calendarButtonHints[prevOrNext], [\n calendarButtonText.year || 'year',\n 'year',\n ], calendarButtonText[buttonName]);\n }\n else {\n buttonHint = (navUnit) => (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[buttonName] ||\n calendarButtonHints[buttonName], [\n calendarButtonText[navUnit] || navUnit,\n navUnit,\n ], calendarButtonText[buttonName]);\n }\n }\n return { buttonName, buttonClick, buttonIcon, buttonText, buttonHint };\n })));\n return { widgets, viewsWithButtons, hasTitle };\n}\n\n// always represents the current view. otherwise, it'd need to change value every time date changes\nclass ViewImpl {\n constructor(type, getCurrentData, dateEnv) {\n this.type = type;\n this.getCurrentData = getCurrentData;\n this.dateEnv = dateEnv;\n }\n get calendar() {\n return this.getCurrentData().calendarApi;\n }\n get title() {\n return this.getCurrentData().viewTitle;\n }\n get activeStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);\n }\n get activeEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);\n }\n get currentStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);\n }\n get currentEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);\n }\n getOption(name) {\n return this.getCurrentData().options[name]; // are the view-specific options\n }\n}\n\nlet eventSourceDef$2 = {\n ignoreRange: true,\n parseMeta(refined) {\n if (Array.isArray(refined.events)) {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback) {\n successCallback({\n rawEvents: arg.eventSource.meta,\n });\n },\n};\nconst arrayEventSourcePlugin = createPlugin({\n name: 'array-event-source',\n eventSourceDefs: [eventSourceDef$2],\n});\n\nlet eventSourceDef$1 = {\n parseMeta(refined) {\n if (typeof refined.events === 'function') {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { dateEnv } = arg.context;\n const func = arg.eventSource.meta;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.u)(func.bind(null, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(arg.range, dateEnv)), (rawEvents) => successCallback({ rawEvents }), errorCallback);\n },\n};\nconst funcEventSourcePlugin = createPlugin({\n name: 'func-event-source',\n eventSourceDefs: [eventSourceDef$1],\n});\n\nconst JSON_FEED_EVENT_SOURCE_REFINERS = {\n method: String,\n extraParams: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startParam: String,\n endParam: String,\n timeZoneParam: String,\n};\n\nlet eventSourceDef = {\n parseMeta(refined) {\n if (refined.url && (refined.format === 'json' || !refined.format)) {\n return {\n url: refined.url,\n format: 'json',\n method: (refined.method || 'GET').toUpperCase(),\n extraParams: refined.extraParams,\n startParam: refined.startParam,\n endParam: refined.endParam,\n timeZoneParam: refined.timeZoneParam,\n };\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { meta } = arg.eventSource;\n const requestParams = buildRequestParams(meta, arg.range, arg.context);\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.r)(meta.method, meta.url, requestParams).then(([rawEvents, response]) => {\n successCallback({ rawEvents, response });\n }, errorCallback);\n },\n};\nconst jsonFeedEventSourcePlugin = createPlugin({\n name: 'json-event-source',\n eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,\n eventSourceDefs: [eventSourceDef],\n});\nfunction buildRequestParams(meta, range, context) {\n let { dateEnv, options } = context;\n let startParam;\n let endParam;\n let timeZoneParam;\n let customRequestParams;\n let params = {};\n startParam = meta.startParam;\n if (startParam == null) {\n startParam = options.startParam;\n }\n endParam = meta.endParam;\n if (endParam == null) {\n endParam = options.endParam;\n }\n timeZoneParam = meta.timeZoneParam;\n if (timeZoneParam == null) {\n timeZoneParam = options.timeZoneParam;\n }\n // retrieve any outbound GET/POST data from the options\n if (typeof meta.extraParams === 'function') {\n // supplied as a function that returns a key/value object\n customRequestParams = meta.extraParams();\n }\n else {\n // probably supplied as a straight key/value object\n customRequestParams = meta.extraParams || {};\n }\n Object.assign(params, customRequestParams);\n params[startParam] = dateEnv.formatIso(range.start);\n params[endParam] = dateEnv.formatIso(range.end);\n if (dateEnv.timeZone !== 'local') {\n params[timeZoneParam] = dateEnv.timeZone;\n }\n return params;\n}\n\nconst SIMPLE_RECURRING_REFINERS = {\n daysOfWeek: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n endTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n duration: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,\n startRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n endRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,\n};\n\nlet recurring = {\n parse(refined, dateEnv) {\n if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {\n let recurringData = {\n daysOfWeek: refined.daysOfWeek || null,\n startTime: refined.startTime || null,\n endTime: refined.endTime || null,\n startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,\n endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,\n dateEnv,\n };\n let duration;\n if (refined.duration) {\n duration = refined.duration;\n }\n if (!duration && refined.startTime && refined.endTime) {\n duration = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.s)(refined.endTime, refined.startTime);\n }\n return {\n allDayGuess: Boolean(!refined.startTime && !refined.endTime),\n duration,\n typeData: recurringData, // doesn't need endTime anymore but oh well\n };\n }\n return null;\n },\n expand(typeData, framingRange, dateEnv) {\n let clippedFramingRange = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.o)(framingRange, { start: typeData.startRecur, end: typeData.endRecur });\n if (clippedFramingRange) {\n return expandRanges(typeData.daysOfWeek, typeData.startTime, typeData.dateEnv, dateEnv, clippedFramingRange);\n }\n return [];\n },\n};\nconst simpleRecurringEventsPlugin = createPlugin({\n name: 'simple-recurring-event',\n recurringTypes: [recurring],\n eventRefiners: SIMPLE_RECURRING_REFINERS,\n});\nfunction expandRanges(daysOfWeek, startTime, eventDateEnv, calendarDateEnv, framingRange) {\n let dowHash = daysOfWeek ? (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(daysOfWeek) : null;\n let dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.q)(framingRange.start);\n let endMarker = framingRange.end;\n let instanceStarts = [];\n // https://github.com/fullcalendar/fullcalendar/issues/7934\n if (startTime) {\n if (startTime.milliseconds < 0) {\n // possible for next-day to have negative business hours that go into current day\n endMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(endMarker, 1);\n }\n else if (startTime.milliseconds >= 1000 * 60 * 60 * 24) {\n // possible for prev-day to have >24hr business hours that go into current day\n dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, -1);\n }\n }\n while (dayMarker < endMarker) {\n let instanceStart;\n // if everyday, or this particular day-of-week\n if (!dowHash || dowHash[dayMarker.getUTCDay()]) {\n if (startTime) {\n instanceStart = calendarDateEnv.add(dayMarker, startTime);\n }\n else {\n instanceStart = dayMarker;\n }\n instanceStarts.push(calendarDateEnv.createMarker(eventDateEnv.toDate(instanceStart)));\n }\n dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, 1);\n }\n return instanceStarts;\n}\n\nconst changeHandlerPlugin = createPlugin({\n name: 'change-handler',\n optionChangeHandlers: {\n events(events, context) {\n handleEventSources([events], context);\n },\n eventSources: handleEventSources,\n },\n});\n/*\nBUG: if `event` was supplied, all previously-given `eventSources` will be wiped out\n*/\nfunction handleEventSources(inputs, context) {\n let unfoundSources = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.v)(context.getCurrentData().eventSources);\n if (unfoundSources.length === 1 &&\n inputs.length === 1 &&\n Array.isArray(unfoundSources[0]._raw) &&\n Array.isArray(inputs[0])) {\n context.dispatch({\n type: 'RESET_RAW_EVENTS',\n sourceId: unfoundSources[0].sourceId,\n rawEvents: inputs[0],\n });\n return;\n }\n let newInputs = [];\n for (let input of inputs) {\n let inputFound = false;\n for (let i = 0; i < unfoundSources.length; i += 1) {\n if (unfoundSources[i]._raw === input) {\n unfoundSources.splice(i, 1); // delete\n inputFound = true;\n break;\n }\n }\n if (!inputFound) {\n newInputs.push(input);\n }\n }\n for (let unfoundSource of unfoundSources) {\n context.dispatch({\n type: 'REMOVE_EVENT_SOURCE',\n sourceId: unfoundSource.sourceId,\n });\n }\n for (let newInput of newInputs) {\n context.calendarApi.addEventSource(newInput);\n }\n}\n\nfunction handleDateProfile(dateProfile, context) {\n context.emitter.trigger('datesSet', Object.assign(Object.assign({}, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));\n}\n\nfunction handleEventStore(eventStore, context) {\n let { emitter } = context;\n if (emitter.hasHandlers('eventsSet')) {\n emitter.trigger('eventsSet', (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.w)(eventStore, context));\n }\n}\n\n/*\nthis array is exposed on the root namespace so that UMD plugins can add to it.\nsee the rollup-bundles script.\n*/\nconst globalPlugins = [\n arrayEventSourcePlugin,\n funcEventSourcePlugin,\n jsonFeedEventSourcePlugin,\n simpleRecurringEventsPlugin,\n changeHandlerPlugin,\n createPlugin({\n name: 'misc',\n isLoadingFuncs: [\n (state) => computeEventSourcesLoading(state.eventSources),\n ],\n propSetHandlers: {\n dateProfile: handleDateProfile,\n eventStore: handleEventStore,\n },\n }),\n];\n\nclass TaskRunner {\n constructor(runTaskOption, drainedOption) {\n this.runTaskOption = runTaskOption;\n this.drainedOption = drainedOption;\n this.queue = [];\n this.delayedRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.drain.bind(this));\n }\n request(task, delay) {\n this.queue.push(task);\n this.delayedRunner.request(delay);\n }\n pause(scope) {\n this.delayedRunner.pause(scope);\n }\n resume(scope, force) {\n this.delayedRunner.resume(scope, force);\n }\n drain() {\n let { queue } = this;\n while (queue.length) {\n let completedTasks = [];\n let task;\n while ((task = queue.shift())) {\n this.runTask(task);\n completedTasks.push(task);\n }\n this.drained(completedTasks);\n } // keep going, in case new tasks were added in the drained handler\n }\n runTask(task) {\n if (this.runTaskOption) {\n this.runTaskOption(task);\n }\n }\n drained(completedTasks) {\n if (this.drainedOption) {\n this.drainedOption(completedTasks);\n }\n }\n}\n\n// Computes what the title at the top of the calendarApi should be for this view\nfunction buildTitle(dateProfile, viewOptions, dateEnv) {\n let range;\n // for views that span a large unit of time, show the proper interval, ignoring stray days before and after\n if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {\n range = dateProfile.currentRange;\n }\n else { // for day units or smaller, use the actual day range\n range = dateProfile.activeRange;\n }\n return dateEnv.formatRange(range.start, range.end, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {\n isEndExclusive: dateProfile.isRangeAllDay,\n defaultSeparator: viewOptions.titleRangeSeparator,\n });\n}\n// Generates the format string that should be used to generate the title for the current date range.\n// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.\nfunction buildTitleFormat(dateProfile) {\n let { currentRangeUnit } = dateProfile;\n if (currentRangeUnit === 'year') {\n return { year: 'numeric' };\n }\n if (currentRangeUnit === 'month') {\n return { year: 'numeric', month: 'long' }; // like \"September 2014\"\n }\n let days = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.y)(dateProfile.currentRange.start, dateProfile.currentRange.end);\n if (days !== null && days > 1) {\n // multi-day range. shorter, like \"Sep 9 - 10 2014\"\n return { year: 'numeric', month: 'short', day: 'numeric' };\n }\n // one day. longer, like \"September 9 2014\"\n return { year: 'numeric', month: 'long', day: 'numeric' };\n}\n\n/*\nTODO: test switching timezones when NO timezone plugin\n*/\nclass CalendarNowManager {\n constructor() {\n this.resetListeners = new Set();\n }\n handleInput(dateEnv, // will change if timezone setup changed\n nowInput) {\n const oldDateEnv = this.dateEnv;\n if (dateEnv !== oldDateEnv) {\n if (typeof nowInput === 'function') {\n this.nowFn = nowInput;\n }\n else if (!oldDateEnv) { // first time?\n this.nowAnchorDate = dateEnv.toDate(nowInput\n ? dateEnv.createMarker(nowInput)\n : dateEnv.createNowMarker());\n this.nowAnchorQueried = Date.now();\n }\n this.dateEnv = dateEnv;\n // not first time? fire reset handlers\n if (oldDateEnv) {\n for (const resetListener of this.resetListeners.values()) {\n resetListener();\n }\n }\n }\n }\n getDateMarker() {\n return this.nowAnchorDate\n ? this.dateEnv.timestampToMarker(this.nowAnchorDate.valueOf() +\n (Date.now() - this.nowAnchorQueried))\n : this.dateEnv.createMarker(this.nowFn());\n }\n addResetListener(handler) {\n this.resetListeners.add(handler);\n }\n removeResetListener(handler) {\n this.resetListeners.delete(handler);\n }\n}\n\n// in future refactor, do the redux-style function(state=initial) for initial-state\n// also, whatever is happening in constructor, have it happen in action queue too\nclass CalendarDataManager {\n constructor(props) {\n this.computeCurrentViewData = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._computeCurrentViewData);\n this.organizeRawLocales = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(organizeRawLocales);\n this.buildLocale = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildLocale);\n this.buildPluginHooks = buildBuildPluginHooks();\n this.buildDateEnv = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDateEnv$1);\n this.buildTheme = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTheme);\n this.parseToolbars = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(parseToolbars);\n this.buildViewSpecs = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewSpecs);\n this.buildDateProfileGenerator = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildDateProfileGenerator);\n this.buildViewApi = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewApi);\n this.buildViewUiProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildViewUiProps);\n this.buildEventUiBySource = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBySource, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.E);\n this.buildEventUiBases = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBases);\n this.parseContextBusinessHours = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(parseContextBusinessHours);\n this.buildTitle = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTitle);\n this.nowManager = new CalendarNowManager();\n this.emitter = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.F();\n this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));\n this.currentCalendarOptionsInput = {};\n this.currentCalendarOptionsRefined = {};\n this.currentViewOptionsInput = {};\n this.currentViewOptionsRefined = {};\n this.currentCalendarOptionsRefiners = {};\n this.optionsForRefining = [];\n this.optionsForHandling = [];\n this.getCurrentData = () => this.data;\n this.dispatch = (action) => {\n this.actionRunner.request(action); // protects against recursive calls to _handleAction\n };\n this.props = props;\n this.actionRunner.pause();\n this.nowManager = new CalendarNowManager();\n let dynamicOptionOverrides = {};\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n this.emitter.setThisContext(props.calendarApi);\n this.emitter.setOptions(currentViewData.options);\n let calendarContext = {\n nowManager: this.nowManager,\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter: this.emitter,\n getCurrentData: this.getCurrentData,\n };\n let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv, this.nowManager);\n let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.activeRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n // needs to be after setThisContext\n for (let callback of optionsData.pluginHooks.contextInit) {\n callback(calendarContext);\n }\n // NOT DRY\n let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);\n let initialState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n businessHours: this.parseContextBusinessHours(calendarContext),\n eventSources,\n eventUiBases: {},\n eventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),\n renderableEventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),\n dateSelection: null,\n eventSelection: '',\n eventDrag: null,\n eventResize: null,\n selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(initialState, reducer(null, null, contextAndState));\n }\n if (computeIsLoading(initialState, calendarContext)) {\n this.emitter.trigger('loading', true); // NOT DRY\n }\n this.state = initialState;\n this.updateData();\n this.actionRunner.resume();\n }\n resetOptions(optionOverrides, changedOptionNames) {\n let { props } = this;\n if (changedOptionNames === undefined) {\n props.optionOverrides = optionOverrides;\n }\n else {\n props.optionOverrides = Object.assign(Object.assign({}, (props.optionOverrides || {})), optionOverrides);\n this.optionsForRefining.push(...changedOptionNames);\n }\n if (changedOptionNames === undefined || changedOptionNames.length) {\n this.actionRunner.request({\n type: 'NOTHING',\n });\n }\n }\n _handleAction(action) {\n let { props, state, emitter } = this;\n let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = reduceViewType(state.currentViewType, action);\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n emitter.setThisContext(props.calendarApi);\n emitter.setOptions(currentViewData.options);\n let calendarContext = {\n nowManager: this.nowManager,\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter,\n getCurrentData: this.getCurrentData,\n };\n let { currentDate, dateProfile } = state;\n if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack\n dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n }\n currentDate = reduceCurrentDate(currentDate, action);\n dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);\n if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator\n action.type === 'NEXT' || // \"\n !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);\n let eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.I)(state.eventStore, action, eventSources, dateProfile, calendarContext);\n let isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading\n let renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?\n (state.renderableEventStore || eventStore) : // try from previous state\n eventStore;\n let { eventUiSingleBase, selectionConfig } = this.buildViewUiProps(calendarContext); // will memoize obj\n let eventUiBySource = this.buildEventUiBySource(eventSources);\n let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);\n let newState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n eventSources,\n eventStore,\n renderableEventStore,\n selectionConfig,\n eventUiBases,\n businessHours: this.parseContextBusinessHours(calendarContext),\n dateSelection: reduceDateSelection(state.dateSelection, action),\n eventSelection: reduceSelectedEvent(state.eventSelection, action),\n eventDrag: reduceEventDrag(state.eventDrag, action),\n eventResize: reduceEventResize(state.eventResize, action),\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), newState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value\n }\n let wasLoading = computeIsLoading(state, calendarContext);\n let isLoading = computeIsLoading(newState, calendarContext);\n // TODO: use propSetHandlers in plugin system\n if (!wasLoading && isLoading) {\n emitter.trigger('loading', true);\n }\n else if (wasLoading && !isLoading) {\n emitter.trigger('loading', false);\n }\n this.state = newState;\n if (props.onAction) {\n props.onAction(action);\n }\n }\n updateData() {\n let { props, state } = this;\n let oldData = this.data;\n let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);\n let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);\n let data = this.data = Object.assign(Object.assign(Object.assign({ nowManager: this.nowManager, viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);\n let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;\n let oldCalendarOptions = oldData && oldData.calendarOptions;\n let newCalendarOptions = optionsData.calendarOptions;\n if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {\n if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {\n // hack\n state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);\n state.eventStore = data.eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.eventStore, oldData.dateEnv, data.dateEnv);\n state.renderableEventStore = data.renderableEventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.renderableEventStore, oldData.dateEnv, data.dateEnv);\n }\n for (let optionName in changeHandlers) {\n if (this.optionsForHandling.indexOf(optionName) !== -1 ||\n oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {\n changeHandlers[optionName](newCalendarOptions[optionName], data);\n }\n }\n }\n this.optionsForHandling = [];\n if (props.onData) {\n props.onData(data);\n }\n }\n computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) {\n // TODO: blacklist options that are handled by optionChangeHandlers\n if (!this.optionsForRefining.length &&\n optionOverrides === this.stableOptionOverrides &&\n dynamicOptionOverrides === this.stableDynamicOptionOverrides) {\n return this.stableCalendarOptionsData;\n }\n let { refinedOptions, pluginHooks, localeDefaults, availableLocaleData, extra, } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);\n let viewSpecs = this.buildViewSpecs(pluginHooks.views, this.stableOptionOverrides, this.stableDynamicOptionOverrides, localeDefaults);\n let theme = this.buildTheme(refinedOptions, pluginHooks);\n let toolbarConfig = this.parseToolbars(refinedOptions, this.stableOptionOverrides, theme, viewSpecs, calendarApi);\n return this.stableCalendarOptionsData = {\n calendarOptions: refinedOptions,\n pluginHooks,\n dateEnv,\n viewSpecs,\n theme,\n toolbarConfig,\n localeDefaults,\n availableRawLocales: availableLocaleData.map,\n };\n }\n // always called from behind a memoizer\n processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) {\n let { locales, locale } = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let availableLocaleData = this.organizeRawLocales(locales);\n let availableRawLocales = availableLocaleData.map;\n let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;\n let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);\n let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let extra = {};\n let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n localeDefaults,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refined = {};\n let currentRaw = this.currentCalendarOptionsInput;\n let currentRefined = this.currentCalendarOptionsRefined;\n let anyChanges = false;\n for (let optionName in raw) {\n if (this.optionsForRefining.indexOf(optionName) === -1 && (raw[optionName] === currentRaw[optionName] || (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n (optionName in currentRaw) &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](currentRaw[optionName], raw[optionName])))) {\n refined[optionName] = currentRefined[optionName];\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n anyChanges = true;\n }\n else {\n extra[optionName] = currentRaw[optionName];\n }\n }\n if (anyChanges) {\n this.currentCalendarOptionsInput = raw;\n this.currentCalendarOptionsRefined = refined;\n this.stableOptionOverrides = optionOverrides;\n this.stableDynamicOptionOverrides = dynamicOptionOverrides;\n }\n this.optionsForHandling.push(...this.optionsForRefining);\n this.optionsForRefining = [];\n return {\n rawOptions: this.currentCalendarOptionsInput,\n refinedOptions: this.currentCalendarOptionsRefined,\n pluginHooks,\n availableLocaleData,\n localeDefaults,\n extra,\n };\n }\n _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) {\n let viewSpec = optionsData.viewSpecs[viewType];\n if (!viewSpec) {\n throw new Error(`viewType \"${viewType}\" is not available. Please make sure you've loaded all neccessary plugins`);\n }\n let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n this.nowManager.handleInput(optionsData.dateEnv, refinedOptions.now);\n let dateProfileGenerator = this.buildDateProfileGenerator({\n dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,\n nowManager: this.nowManager,\n duration: viewSpec.duration,\n durationUnit: viewSpec.durationUnit,\n usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,\n dateEnv: optionsData.dateEnv,\n calendarApi: this.props.calendarApi,\n slotMinTime: refinedOptions.slotMinTime,\n slotMaxTime: refinedOptions.slotMaxTime,\n showNonCurrentDates: refinedOptions.showNonCurrentDates,\n dayCount: refinedOptions.dayCount,\n dateAlignment: refinedOptions.dateAlignment,\n dateIncrement: refinedOptions.dateIncrement,\n hiddenDays: refinedOptions.hiddenDays,\n weekends: refinedOptions.weekends,\n validRangeInput: refinedOptions.validRange,\n visibleRangeInput: refinedOptions.visibleRange,\n fixedWeekCount: refinedOptions.fixedWeekCount,\n });\n let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);\n return { viewSpec, options: refinedOptions, dateProfileGenerator, viewApi };\n }\n processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {\n let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e,\n viewSpec.optionDefaults,\n localeDefaults,\n optionOverrides,\n viewSpec.optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.P), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let refined = {};\n let currentRaw = this.currentViewOptionsInput;\n let currentRefined = this.currentViewOptionsRefined;\n let anyChanges = false;\n let extra = {};\n for (let optionName in raw) {\n if (raw[optionName] === currentRaw[optionName] ||\n (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], currentRaw[optionName]))) {\n refined[optionName] = currentRefined[optionName];\n }\n else {\n if (raw[optionName] === this.currentCalendarOptionsInput[optionName] ||\n (_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] &&\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) {\n if (optionName in this.currentCalendarOptionsRefined) { // might be an \"extra\" prop\n refined[optionName] = this.currentCalendarOptionsRefined[optionName];\n }\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n }\n else {\n extra[optionName] = raw[optionName];\n }\n anyChanges = true;\n }\n }\n if (anyChanges) {\n this.currentViewOptionsInput = raw;\n this.currentViewOptionsRefined = refined;\n }\n return {\n rawOptions: this.currentViewOptionsInput,\n refinedOptions: this.currentViewOptionsRefined,\n extra,\n };\n }\n}\nfunction buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {\n let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);\n return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q({\n calendarSystem: 'gregory',\n timeZone,\n namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,\n locale,\n weekNumberCalculation,\n firstDay,\n weekText,\n cmdFormatter: pluginHooks.cmdFormatter,\n defaultSeparator,\n });\n}\nfunction buildTheme(options, pluginHooks) {\n let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;\n return new ThemeClass(options);\n}\nfunction buildDateProfileGenerator(props) {\n let DateProfileGeneratorClass = props.dateProfileGeneratorClass || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.R;\n return new DateProfileGeneratorClass(props);\n}\nfunction buildViewApi(type, getCurrentData, dateEnv) {\n return new ViewImpl(type, getCurrentData, dateEnv);\n}\nfunction buildEventUiBySource(eventSources) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(eventSources, (eventSource) => eventSource.ui);\n}\nfunction buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {\n let eventUiBases = { '': eventUiSingleBase };\n for (let defId in eventDefs) {\n let def = eventDefs[defId];\n if (def.sourceId && eventUiBySource[def.sourceId]) {\n eventUiBases[defId] = eventUiBySource[def.sourceId];\n }\n }\n return eventUiBases;\n}\nfunction buildViewUiProps(calendarContext) {\n let { options } = calendarContext;\n return {\n eventUiSingleBase: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({\n display: options.eventDisplay,\n editable: options.editable,\n startEditable: options.eventStartEditable,\n durationEditable: options.eventDurationEditable,\n constraint: options.eventConstraint,\n overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,\n allow: options.eventAllow,\n backgroundColor: options.eventBackgroundColor,\n borderColor: options.eventBorderColor,\n textColor: options.eventTextColor,\n color: options.eventColor,\n // classNames: options.eventClassNames // render hook will handle this\n }, calendarContext),\n selectionConfig: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({\n constraint: options.selectConstraint,\n overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,\n allow: options.selectAllow,\n }, calendarContext),\n };\n}\nfunction computeIsLoading(state, context) {\n for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {\n if (isLoadingFunc(state)) {\n return true;\n }\n }\n return false;\n}\nfunction parseContextBusinessHours(calendarContext) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.U)(calendarContext.options.businessHours, calendarContext);\n}\nfunction warnUnknownOptions(options, viewName) {\n for (let optionName in options) {\n console.warn(`Unknown option '${optionName}'` +\n (viewName ? ` for view '${viewName}'` : ''));\n }\n}\n\nclass ToolbarSection extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n render() {\n let children = this.props.widgetGroups.map((widgetGroup) => this.renderWidgetGroup(widgetGroup));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: 'fc-toolbar-chunk' }, ...children);\n }\n renderWidgetGroup(widgetGroup) {\n let { props } = this;\n let { theme } = this.context;\n let children = [];\n let isOnlyButtons = true;\n for (let widget of widgetGroup) {\n let { buttonName, buttonClick, buttonText, buttonIcon, buttonHint } = widget;\n if (buttonName === 'title') {\n isOnlyButtons = false;\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"h2\", { className: \"fc-toolbar-title\", id: props.titleId }, props.title));\n }\n else {\n let isPressed = buttonName === props.activeButton;\n let isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||\n (!props.isPrevEnabled && buttonName === 'prev') ||\n (!props.isNextEnabled && buttonName === 'next');\n let buttonClasses = [`fc-${buttonName}-button`, theme.getClass('button')];\n if (isPressed) {\n buttonClasses.push(theme.getClass('buttonActive'));\n }\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"button\", { type: \"button\", title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, \"aria-pressed\": isPressed, className: buttonClasses.join(' '), onClick: buttonClick }, buttonText || (buttonIcon ? (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"span\", { className: buttonIcon, role: \"img\" }) : '')));\n }\n }\n if (children.length > 1) {\n let groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: groupClassName }, ...children);\n }\n return children[0];\n }\n}\n\nclass Toolbar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n render() {\n let { model, extraClassName } = this.props;\n let forceLtr = false;\n let startContent;\n let endContent;\n let sectionWidgets = model.sectionWidgets;\n let centerContent = sectionWidgets.center;\n if (sectionWidgets.left) {\n forceLtr = true;\n startContent = sectionWidgets.left;\n }\n else {\n startContent = sectionWidgets.start;\n }\n if (sectionWidgets.right) {\n forceLtr = true;\n endContent = sectionWidgets.right;\n }\n else {\n endContent = sectionWidgets.end;\n }\n let classNames = [\n extraClassName || '',\n 'fc-toolbar',\n forceLtr ? 'fc-toolbar-ltr' : '',\n ];\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: classNames.join(' ') },\n this.renderSection('start', startContent || []),\n this.renderSection('center', centerContent || []),\n this.renderSection('end', endContent || [])));\n }\n renderSection(key, widgetGroups) {\n let { props } = this;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId }));\n }\n}\n\nclass ViewHarness extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {\n constructor() {\n super(...arguments);\n this.state = {\n availableWidth: null,\n };\n this.handleEl = (el) => {\n this.el = el;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.W)(this.props.elRef, el);\n this.updateAvailableWidth();\n };\n this.handleResize = () => {\n this.updateAvailableWidth();\n };\n }\n render() {\n let { props, state } = this;\n let { aspectRatio } = props;\n let classNames = [\n 'fc-view-harness',\n (aspectRatio || props.liquid || props.height)\n ? 'fc-view-harness-active' // harness controls the height\n : 'fc-view-harness-passive', // let the view do the height\n ];\n let height = '';\n let paddingBottom = '';\n if (aspectRatio) {\n if (state.availableWidth !== null) {\n height = state.availableWidth / aspectRatio;\n }\n else {\n // while waiting to know availableWidth, we can't set height to *zero*\n // because will cause lots of unnecessary scrollbars within scrollgrid.\n // BETTER: don't start rendering ANYTHING yet until we know container width\n // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)\n paddingBottom = `${(1 / aspectRatio) * 100}%`;\n }\n }\n else {\n height = props.height || '';\n }\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { \"aria-labelledby\": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height, paddingBottom } }, props.children));\n }\n componentDidMount() {\n this.context.addResizeHandler(this.handleResize);\n }\n componentWillUnmount() {\n this.context.removeResizeHandler(this.handleResize);\n }\n updateAvailableWidth() {\n if (this.el && // needed. but why?\n this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth\n ) {\n this.setState({ availableWidth: this.el.offsetWidth });\n }\n }\n}\n\n/*\nDetects when the user clicks on an event within a DateComponent\n*/\nclass EventClicking extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {\n constructor(settings) {\n super(settings);\n this.handleSegClick = (ev, segEl) => {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);\n if (seg && // might be the
surrounding the more link\n component.isValidSegDownEl(ev.target)) {\n // our way to simulate a link click for elements that can't be tags\n // grab before trigger fired in case trigger trashes DOM thru rerendering\n let hasUrlContainer = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ev.target, '.fc-event-forced-url');\n let url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';\n context.emitter.trigger('eventClick', {\n el: segEl,\n event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(component.context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n if (url && !ev.defaultPrevented) {\n window.location.href = url;\n }\n }\n };\n this.destroy = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.$)(settings.el, 'click', '.fc-event', // on both fg and bg events\n this.handleSegClick);\n }\n}\n\n/*\nTriggers events and adds/removes core classNames when the user's pointer\nenters/leaves event-elements of a component.\n*/\nclass EventHovering extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {\n constructor(settings) {\n super(settings);\n // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it\n this.handleEventElRemove = (el) => {\n if (el === this.currentSegEl) {\n this.handleSegLeave(null, this.currentSegEl);\n }\n };\n this.handleSegEnter = (ev, segEl) => {\n if ((0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper\n this.currentSegEl = segEl;\n this.triggerEvent('eventMouseEnter', ev, segEl);\n }\n };\n this.handleSegLeave = (ev, segEl) => {\n if (this.currentSegEl) {\n this.currentSegEl = null;\n this.triggerEvent('eventMouseLeave', ev, segEl);\n }\n };\n this.removeHoverListeners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a0)(settings.el, '.fc-event', // on both fg and bg events\n this.handleSegEnter, this.handleSegLeave);\n }\n destroy() {\n this.removeHoverListeners();\n }\n triggerEvent(publicEvName, ev, segEl) {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);\n if (!ev || component.isValidSegDownEl(ev.target)) {\n context.emitter.trigger(publicEvName, {\n el: segEl,\n event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n }\n }\n}\n\nclass CalendarContent extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a1 {\n constructor() {\n super(...arguments);\n this.buildViewContext = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a2);\n this.buildViewPropTransformers = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewPropTransformers);\n this.buildToolbarProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildToolbarProps);\n this.headerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.footerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.interactionsStore = {};\n // eslint-disable-next-line\n this.state = {\n viewLabelId: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a3)(),\n };\n // Component Registration\n // -----------------------------------------------------------------------------------------------------------------\n this.registerInteractiveComponent = (component, settingsInput) => {\n let settings = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a4)(component, settingsInput);\n let DEFAULT_INTERACTIONS = [\n EventClicking,\n EventHovering,\n ];\n let interactionClasses = DEFAULT_INTERACTIONS.concat(this.props.pluginHooks.componentInteractions);\n let interactions = interactionClasses.map((TheInteractionClass) => new TheInteractionClass(settings));\n this.interactionsStore[component.uid] = interactions;\n _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid] = settings;\n };\n this.unregisterInteractiveComponent = (component) => {\n let listeners = this.interactionsStore[component.uid];\n if (listeners) {\n for (let listener of listeners) {\n listener.destroy();\n }\n delete this.interactionsStore[component.uid];\n }\n delete _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid];\n };\n // Resizing\n // -----------------------------------------------------------------------------------------------------------------\n this.resizeRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(() => {\n this.props.emitter.trigger('_resize', true); // should window resizes be considered \"forced\" ?\n this.props.emitter.trigger('windowResize', { view: this.props.viewApi });\n });\n this.handleWindowResize = (ev) => {\n let { options } = this.props;\n if (options.handleWindowResize &&\n ev.target === window // avoid jqui events\n ) {\n this.resizeRunner.request(options.windowResizeDelay);\n }\n };\n }\n /*\n renders INSIDE of an outer div\n */\n render() {\n let { props } = this;\n let { toolbarConfig, options } = props;\n let viewVGrow = false;\n let viewHeight = '';\n let viewAspectRatio;\n if (props.isHeightAuto || props.forPrint) {\n viewHeight = '';\n }\n else if (options.height != null) {\n viewVGrow = true;\n }\n else if (options.contentHeight != null) {\n viewHeight = options.contentHeight;\n }\n else {\n viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall\n }\n let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.nowManager, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);\n let viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle)\n ? this.state.viewLabelId\n : undefined;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Provider, { value: viewContext },\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a6, { unit: \"day\" }, (nowDate) => {\n let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, nowDate, props.viewTitle);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n toolbarConfig.header && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: \"fc-header-toolbar\", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewHarness, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },\n this.renderView(props),\n this.buildAppendContent()),\n toolbarConfig.footer && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: \"fc-footer-toolbar\", model: toolbarConfig.footer, titleId: \"\" }, toolbarProps)))));\n })));\n }\n componentDidMount() {\n let { props } = this;\n this.calendarInteractions = props.pluginHooks.calendarInteractions\n .map((CalendarInteractionClass) => new CalendarInteractionClass(props));\n window.addEventListener('resize', this.handleWindowResize);\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n componentDidUpdate(prevProps) {\n let { props } = this;\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n if (props[propName] !== prevProps[propName]) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n }\n componentWillUnmount() {\n window.removeEventListener('resize', this.handleWindowResize);\n this.resizeRunner.clear();\n for (let interaction of this.calendarInteractions) {\n interaction.destroy();\n }\n this.props.emitter.trigger('_unmount');\n }\n buildAppendContent() {\n let { props } = this;\n let children = props.pluginHooks.viewContainerAppends.map((buildAppendContent) => buildAppendContent(props));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...children);\n }\n renderView(props) {\n let { pluginHooks } = props;\n let { viewSpec } = props;\n let viewProps = {\n dateProfile: props.dateProfile,\n businessHours: props.businessHours,\n eventStore: props.renderableEventStore,\n eventUiBases: props.eventUiBases,\n dateSelection: props.dateSelection,\n eventSelection: props.eventSelection,\n eventDrag: props.eventDrag,\n eventResize: props.eventResize,\n isHeightAuto: props.isHeightAuto,\n forPrint: props.forPrint,\n };\n let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);\n for (let transformer of transformers) {\n Object.assign(viewProps, transformer.transform(viewProps, props));\n }\n let ViewComponent = viewSpec.component;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewComponent, Object.assign({}, viewProps)));\n }\n}\nfunction buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {\n // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid\n let todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason\n let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);\n let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);\n return {\n title,\n activeButton: viewSpec.type,\n navUnit: viewSpec.singleUnit,\n isTodayEnabled: todayInfo.isValid && !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, now),\n isPrevEnabled: prevInfo.isValid,\n isNextEnabled: nextInfo.isValid,\n };\n}\n// Plugin\n// -----------------------------------------------------------------------------------------------------------------\nfunction buildViewPropTransformers(theClasses) {\n return theClasses.map((TheClass) => new TheClass());\n}\n\nclass Calendar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a7 {\n constructor(el, optionOverrides = {}) {\n super();\n this.isRendering = false;\n this.isRendered = false;\n this.currentClassNames = [];\n this.customContentRenderId = 0;\n this.handleAction = (action) => {\n // actions we know we want to render immediately\n switch (action.type) {\n case 'SET_EVENT_DRAG':\n case 'SET_EVENT_RESIZE':\n this.renderRunner.tryDrain();\n }\n };\n this.handleData = (data) => {\n this.currentData = data;\n this.renderRunner.request(data.calendarOptions.rerenderDelay);\n };\n this.handleRenderRequest = () => {\n if (this.isRendering) {\n this.isRendered = true;\n let { currentData } = this;\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a9, { options: currentData.calendarOptions, theme: currentData.theme, emitter: currentData.emitter }, (classNames, height, isHeightAuto, forPrint) => {\n this.setClassNames(classNames);\n this.setHeight(height);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.aa.Provider, { value: this.customContentRenderId },\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(CalendarContent, Object.assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData))));\n }), this.el);\n });\n }\n else if (this.isRendered) {\n this.isRendered = false;\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)(null, this.el);\n this.setClassNames([]);\n this.setHeight('');\n }\n };\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ab)(el);\n this.el = el;\n this.renderRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.handleRenderRequest);\n new CalendarDataManager({\n optionOverrides,\n calendarApi: this,\n onAction: this.handleAction,\n onData: this.handleData,\n });\n }\n render() {\n let wasRendering = this.isRendering;\n if (!wasRendering) {\n this.isRendering = true;\n }\n else {\n this.customContentRenderId += 1;\n }\n this.renderRunner.request();\n if (wasRendering) {\n this.updateSize();\n }\n }\n destroy() {\n if (this.isRendering) {\n this.isRendering = false;\n this.renderRunner.request();\n }\n }\n updateSize() {\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {\n super.updateSize();\n });\n }\n batchRendering(func) {\n this.renderRunner.pause('batchRendering');\n func();\n this.renderRunner.resume('batchRendering');\n }\n pauseRendering() {\n this.renderRunner.pause('pauseRendering');\n }\n resumeRendering() {\n this.renderRunner.resume('pauseRendering', true);\n }\n resetOptions(optionOverrides, changedOptionNames) {\n this.currentDataManager.resetOptions(optionOverrides, changedOptionNames);\n }\n setClassNames(classNames) {\n if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(classNames, this.currentClassNames)) {\n let { classList } = this.el;\n for (let className of this.currentClassNames) {\n classList.remove(className);\n }\n for (let className of classNames) {\n classList.add(className);\n }\n this.currentClassNames = classNames;\n }\n }\n setHeight(height) {\n (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ac)(this.el, 'height', height);\n }\n}\n\nfunction formatDate(dateInput, options = {}) {\n let dateEnv = buildDateEnv(options);\n let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let dateMeta = dateEnv.createMarkerMeta(dateInput);\n if (!dateMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.format(dateMeta.marker, formatter, {\n forcedTzo: dateMeta.forcedTzo,\n });\n}\nfunction formatRange(startInput, endInput, options) {\n let dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object\n let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let startMeta = dateEnv.createMarkerMeta(startInput);\n let endMeta = dateEnv.createMarkerMeta(endInput);\n if (!startMeta || !endMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {\n forcedStartTzo: startMeta.forcedTzo,\n forcedEndTzo: endMeta.forcedTzo,\n isEndExclusive: options.isEndExclusive,\n defaultSeparator: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.defaultRangeSeparator,\n });\n}\n// TODO: more DRY and optimized\nfunction buildDateEnv(settings) {\n let locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere\n return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q(Object.assign(Object.assign({ timeZone: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.timeZone, calendarSystem: 'gregory' }, settings), { locale }));\n}\n\n// HELPERS\n/*\nif nextDayThreshold is specified, slicing is done in an all-day fashion.\nyou can get nextDayThreshold from context.nextDayThreshold\n*/\nfunction sliceEvents(props, allDay) {\n return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ad)(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;\n}\n\nconst version = '6.1.20';\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2luZGV4LmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUFvL0M7QUFDdDdDO0FBQ007QUFDN0M7O0FBRXZCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLFdBQVc7QUFDckMsU0FBUztBQUNULEtBQUs7QUFDTCx1QkFBdUIsVUFBVSxZQUFZLDBCQUEwQjtBQUN2RSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLGtCQUFrQjtBQUN0QztBQUNBLG1DQUFtQyxPQUFPO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixzREFBVTtBQUMzQix3QkFBd0I7QUFDeEIsVUFBVSxPQUFPO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHNEQUFJO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBLDREQUE0RDtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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QUFlLFFBQVE7QUFDaEo7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx1REFBZTtBQUMxQjs7QUFFQTs7QUFFK0ciLCJzb3VyY2VzIjpbIi9ob21lL3NpbHZpby9EZXZlbG9wL0NJUlVYLUFQUC9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG0gYXMgbWVyZ2VQcm9wcywgZyBhcyBndWlkLCBpIGFzIGlzQXJyYXlzRXF1YWwsIFQgYXMgVGhlbWUsIGEgYXMgbWFwSGFzaCwgQiBhcyBCYXNlQ29tcG9uZW50LCBWIGFzIFZpZXdDb250ZXh0VHlwZSwgQyBhcyBDb250ZW50Q29udGFpbmVyLCBiIGFzIGJ1aWxkVmlld0NsYXNzTmFtZXMsIGMgYXMgZ3JlYXRlc3REdXJhdGlvbkRlbm9taW5hdG9yLCBkIGFzIGNyZWF0ZUR1cmF0aW9uLCBlIGFzIEJBU0VfT1BUSU9OX0RFRkFVTFRTLCBmIGFzIGFycmF5VG9IYXNoLCBoIGFzIGZpbHRlckhhc2gsIGogYXMgYnVpbGRFdmVudFNvdXJjZVJlZmluZXJzLCBwIGFzIHBhcnNlRXZlbnRTb3VyY2UsIGsgYXMgZm9ybWF0V2l0aE9yZGluYWxzLCB1IGFzIHVucHJvbWlzaWZ5LCBsIGFzIGJ1aWxkUmFuZ2VBcGlXaXRoVGltZVpvbmUsIG4gYXMgaWRlbnRpdHksIHIgYXMgcmVxdWVzdEpzb24sIHMgYXMgc3VidHJhY3REdXJhdGlvbnMsIG8gYXMgaW50ZXJzZWN0UmFuZ2VzLCBxIGFzIHN0YXJ0T2ZEYXksIHQgYXMgYWRkRGF5cywgdiBhcyBoYXNoVmFsdWVzVG9BcnJheSwgdyBhcyBidWlsZEV2ZW50QXBpcywgRCBhcyBEZWxheWVkUnVubmVyLCB4IGFzIGNyZWF0ZUZvcm1hdHRlciwgeSBhcyBkaWZmV2hvbGVEYXlzLCB6IGFzIG1lbW9pemUsIEEgYXMgbWVtb2l6ZU9iakFyZywgRSBhcyBpc1Byb3BzRXF1YWwsIEYgYXMgRW1pdHRlciwgRyBhcyByYW5nZUNvbnRhaW5zTWFya2VyLCBIIGFzIGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSwgSSBhcyByZWR1Y2VFdmVudFN0b3JlLCBKIGFzIHJlem9uZUV2ZW50U3RvcmVEYXRlcywgSyBhcyBtZXJnZVJhd09wdGlvbnMsIEwgYXMgQkFTRV9PUFRJT05fUkVGSU5FUlMsIE0gYXMgQ0FMRU5EQVJfTElTVEVORVJfUkVGSU5FUlMsIE4gYXMgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTLCBPIGFzIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTLCBQIGFzIFZJRVdfT1BUSU9OX1JFRklORVJTLCBRIGFzIERhdGVFbnYsIFIgYXMgRGF0ZVByb2ZpbGVHZW5lcmF0b3IsIFMgYXMgY3JlYXRlRXZlbnRVaSwgVSBhcyBwYXJzZUJ1c2luZXNzSG91cnMsIFcgYXMgc2V0UmVmLCBYIGFzIEludGVyYWN0aW9uLCBZIGFzIGdldEVsU2VnLCBaIGFzIGVsZW1lbnRDbG9zZXN0LCBfIGFzIEV2ZW50SW1wbCwgJCBhcyBsaXN0ZW5CeVNlbGVjdG9yLCBhMCBhcyBsaXN0ZW5Ub0hvdmVyQnlTZWxlY3RvciwgYTEgYXMgUHVyZUNvbXBvbmVudCwgYTIgYXMgYnVpbGRWaWV3Q29udGV4dCwgYTMgYXMgZ2V0VW5pcXVlRG9tSWQsIGE0IGFzIHBhcnNlSW50ZXJhY3Rpb25TZXR0aW5ncywgYTUgYXMgaW50ZXJhY3Rpb25TZXR0aW5nc1N0b3JlLCBhNiBhcyBOb3dUaW1lciwgYTcgYXMgQ2FsZW5kYXJJbXBsLCBhOCBhcyBmbHVzaFN5bmMsIGE5IGFzIENhbGVuZGFyUm9vdCwgYWEgYXMgUmVuZGVySWQsIGFiIGFzIGVuc3VyZUVsSGFzU3R5bGVzLCBhYyBhcyBhcHBseVN0eWxlUHJvcCwgYWQgYXMgc2xpY2VFdmVudFN0b3JlIH0gZnJvbSAnLi9pbnRlcm5hbC1jb21tb24uanMnO1xuZXhwb3J0IHsgYWUgYXMgSnNvblJlcXVlc3RFcnJvciB9IGZyb20gJy4vaW50ZXJuYWwtY29tbW9uLmpzJztcbmltcG9ydCB7IGNyZWF0ZUVsZW1lbnQsIGNyZWF0ZVJlZiwgRnJhZ21lbnQsIHJlbmRlciB9IGZyb20gJ3ByZWFjdCc7XG5pbXBvcnQgJ3ByZWFjdC9jb21wYXQnO1xuXG5jb25zdCBnbG9iYWxMb2NhbGVzID0gW107XG5cbmNvbnN0IE1JTklNQUxfUkFXX0VOX0xPQ0FMRSA9IHtcbiAgICBjb2RlOiAnZW4nLFxuICAgIHdlZWs6IHtcbiAgICAgICAgZG93OiAwLFxuICAgICAgICBkb3k6IDQsIC8vIDQgZGF5cyBuZWVkIHRvIGJlIHdpdGhpbiB0aGUgeWVhciB0byBiZSBjb25zaWRlcmVkIHRoZSBmaXJzdCB3ZWVrXG4gICAgfSxcbiAgICBkaXJlY3Rpb246ICdsdHInLFxuICAgIGJ1dHRvblRleHQ6IHtcbiAgICAgICAgcHJldjogJ3ByZXYnLFxuICAgICAgICBuZXh0OiAnbmV4dCcsXG4gICAgICAgIHByZXZZZWFyOiAncHJldiB5ZWFyJyxcbiAgICAgICAgbmV4dFllYXI6ICduZXh0IHllYXInLFxuICAgICAgICB5ZWFyOiAneWVhcicsXG4gICAgICAgIHRvZGF5OiAndG9kYXknLFxuICAgICAgICBtb250aDogJ21vbnRoJyxcbiAgICAgICAgd2VlazogJ3dlZWsnLFxuICAgICAgICBkYXk6ICdkYXknLFxuICAgICAgICBsaXN0OiAnbGlzdCcsXG4gICAgfSxcbiAgICB3ZWVrVGV4dDogJ1cnLFxuICAgIHdlZWtUZXh0TG9uZzogJ1dlZWsnLFxuICAgIGNsb3NlSGludDogJ0Nsb3NlJyxcbiAgICB0aW1lSGludDogJ1RpbWUnLFxuICAgIGV2ZW50SGludDogJ0V2ZW50JyxcbiAgICBhbGxEYXlUZXh0OiAnYWxsLWRheScsXG4gICAgbW9yZUxpbmtUZXh0OiAnbW9yZScsXG4gICAgbm9FdmVudHNUZXh0OiAnTm8gZXZlbnRzIHRvIGRpc3BsYXknLFxufTtcbmNvbnN0IFJBV19FTl9MT0NBTEUgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIE1JTklNQUxfUkFXX0VOX0xPQ0FMRSksIHsgXG4gICAgLy8gSW5jbHVkZXMgdGhpbmdzIHdlIGRvbid0IHdhbnQgb3RoZXIgbG9jYWxlcyB0byBpbmhlcml0LFxuICAgIC8vIHRoaW5ncyB0aGF0IGRlcml2ZSBmcm9tIG90aGVyIHRyYW5zbGF0YWJsZSBzdHJpbmdzLlxuICAgIGJ1dHRvbkhpbnRzOiB7XG4gICAgICAgIHByZXY6ICdQcmV2aW91cyAkMCcsXG4gICAgICAgIG5leHQ6ICdOZXh0ICQwJyxcbiAgICAgICAgdG9kYXkoYnV0dG9uVGV4dCwgdW5pdCkge1xuICAgICAgICAgICAgcmV0dXJuICh1bml0ID09PSAnZGF5JylcbiAgICAgICAgICAgICAgICA/ICdUb2RheSdcbiAgICAgICAgICAgICAgICA6IGBUaGlzICR7YnV0dG9uVGV4dH1gO1xuICAgICAgICB9LFxuICAgIH0sIHZpZXdIaW50OiAnJDAgdmlldycsIG5hdkxpbmtIaW50OiAnR28gdG8gJDAnLCBtb3JlTGlua0hpbnQoZXZlbnRDbnQpIHtcbiAgICAgICAgcmV0dXJuIGBTaG93ICR7ZXZlbnRDbnR9IG1vcmUgZXZlbnQke2V2ZW50Q250ID09PSAxID8gJycgOiAncyd9YDtcbiAgICB9IH0pO1xuZnVuY3Rpb24gb3JnYW5pemVSYXdMb2NhbGVzKGV4cGxpY2l0UmF3TG9jYWxlcykge1xuICAgIGxldCBkZWZhdWx0Q29kZSA9IGV4cGxpY2l0UmF3TG9jYWxlcy5sZW5ndGggPiAwID8gZXhwbGljaXRSYXdMb2NhbGVzWzBdLmNvZGUgOiAnZW4nO1xuICAgIGxldCBhbGxSYXdMb2NhbGVzID0gZ2xvYmFsTG9jYWxlcy5jb25jYXQoZXhwbGljaXRSYXdMb2NhbGVzKTtcbiAgICBsZXQgcmF3TG9jYWxlTWFwID0ge1xuICAgICAgICBlbjogUkFXX0VOX0xPQ0FMRSxcbiAgICB9O1xuICAgIGZvciAobGV0IHJhd0xvY2FsZSBvZiBhbGxSYXdMb2NhbGVzKSB7XG4gICAgICAgIHJhd0xvY2FsZU1hcFtyYXdMb2NhbGUuY29kZV0gPSByYXdMb2NhbGU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIG1hcDogcmF3TG9jYWxlTWFwLFxuICAgICAgICBkZWZhdWx0Q29kZSxcbiAgICB9O1xufVxuZnVuY3Rpb24gYnVpbGRMb2NhbGUoaW5wdXRTaW5ndWxhciwgYXZhaWxhYmxlKSB7XG4gICAgaWYgKHR5cGVvZiBpbnB1dFNpbmd1bGFyID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShpbnB1dFNpbmd1bGFyKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VMb2NhbGUoaW5wdXRTaW5ndWxhci5jb2RlLCBbaW5wdXRTaW5ndWxhci5jb2RlXSwgaW5wdXRTaW5ndWxhcik7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeUxvY2FsZShpbnB1dFNpbmd1bGFyLCBhdmFpbGFibGUpO1xufVxuZnVuY3Rpb24gcXVlcnlMb2NhbGUoY29kZUFyZywgYXZhaWxhYmxlKSB7XG4gICAgbGV0IGNvZGVzID0gW10uY29uY2F0KGNvZGVBcmcgfHwgW10pOyAvLyB3aWxsIGNvbnZlcnQgdG8gYXJyYXlcbiAgICBsZXQgcmF3ID0gcXVlcnlSYXdMb2NhbGUoY29kZXMsIGF2YWlsYWJsZSkgfHwgUkFXX0VOX0xPQ0FMRTtcbiAgICByZXR1cm4gcGFyc2VMb2NhbGUoY29kZUFyZywgY29kZXMsIHJhdyk7XG59XG5mdW5jdGlvbiBxdWVyeVJhd0xvY2FsZShjb2RlcywgYXZhaWxhYmxlKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBsZXQgcGFydHMgPSBjb2Rlc1tpXS50b0xvY2FsZUxvd2VyQ2FzZSgpLnNwbGl0KCctJyk7XG4gICAgICAgIGZvciAobGV0IGogPSBwYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHtcbiAgICAgICAgICAgIGxldCBzaW1wbGVJZCA9IHBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy0nKTtcbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVbc2ltcGxlSWRdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF2YWlsYWJsZVtzaW1wbGVJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBwYXJzZUxvY2FsZShjb2RlQXJnLCBjb2RlcywgcmF3KSB7XG4gICAgbGV0IG1lcmdlZCA9IG1lcmdlUHJvcHMoW01JTklNQUxfUkFXX0VOX0xPQ0FMRSwgcmF3XSwgWydidXR0b25UZXh0J10pO1xuICAgIGRlbGV0ZSBtZXJnZWQuY29kZTsgLy8gZG9uJ3Qgd2FudCB0aGlzIHBhcnQgb2YgdGhlIG9wdGlvbnNcbiAgICBsZXQgeyB3ZWVrIH0gPSBtZXJnZWQ7XG4gICAgZGVsZXRlIG1lcmdlZC53ZWVrO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvZGVBcmcsXG4gICAgICAgIGNvZGVzLFxuICAgICAgICB3ZWVrLFxuICAgICAgICBzaW1wbGVOdW1iZXJGb3JtYXQ6IG5ldyBJbnRsLk51bWJlckZvcm1hdChjb2RlQXJnKSxcbiAgICAgICAgb3B0aW9uczogbWVyZ2VkLFxuICAgIH07XG59XG5cbi8vIFRPRE86IGVhc2llciB3YXkgdG8gYWRkIG5ldyBob29rcz8gbmVlZCB0byB1cGRhdGUgYSBtaWxsaW9uIHRoaW5nc1xuZnVuY3Rpb24gY3JlYXRlUGx1Z2luKGlucHV0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IGd1aWQoKSxcbiAgICAgICAgbmFtZTogaW5wdXQubmFtZSxcbiAgICAgICAgcHJlbWl1bVJlbGVhc2VEYXRlOiBpbnB1dC5wcmVtaXVtUmVsZWFzZURhdGUgPyBuZXcgRGF0ZShpbnB1dC5wcmVtaXVtUmVsZWFzZURhdGUpIDogdW5kZWZpbmVkLFxuICAgICAgICBkZXBzOiBpbnB1dC5kZXBzIHx8IFtdLFxuICAgICAgICByZWR1Y2VyczogaW5wdXQucmVkdWNlcnMgfHwgW10sXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBpbnB1dC5pc0xvYWRpbmdGdW5jcyB8fCBbXSxcbiAgICAgICAgY29udGV4dEluaXQ6IFtdLmNvbmNhdChpbnB1dC5jb250ZXh0SW5pdCB8fCBbXSksXG4gICAgICAgIGV2ZW50UmVmaW5lcnM6IGlucHV0LmV2ZW50UmVmaW5lcnMgfHwge30sXG4gICAgICAgIGV2ZW50RGVmTWVtYmVyQWRkZXJzOiBpbnB1dC5ldmVudERlZk1lbWJlckFkZGVycyB8fCBbXSxcbiAgICAgICAgZXZlbnRTb3VyY2VSZWZpbmVyczogaW5wdXQuZXZlbnRTb3VyY2VSZWZpbmVycyB8fCB7fSxcbiAgICAgICAgaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnM6IGlucHV0LmlzRHJhZ2dhYmxlVHJhbnNmb3JtZXJzIHx8IFtdLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogaW5wdXQuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMgfHwgW10sXG4gICAgICAgIGV2ZW50RGVmTXV0YXRpb25BcHBsaWVyczogaW5wdXQuZXZlbnREZWZNdXRhdGlvbkFwcGxpZXJzIHx8IFtdLFxuICAgICAgICBkYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzOiBpbnB1dC5kYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzIHx8IFtdLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBpbnB1dC5kYXRlUG9pbnRUcmFuc2Zvcm1zIHx8IFtdLFxuICAgICAgICBkYXRlU3BhblRyYW5zZm9ybXM6IGlucHV0LmRhdGVTcGFuVHJhbnNmb3JtcyB8fCBbXSxcbiAgICAgICAgdmlld3M6IGlucHV0LnZpZXdzIHx8IHt9LFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IGlucHV0LnZpZXdQcm9wc1RyYW5zZm9ybWVycyB8fCBbXSxcbiAgICAgICAgaXNQcm9wc1ZhbGlkOiBpbnB1dC5pc1Byb3BzVmFsaWQgfHwgbnVsbCxcbiAgICAgICAgZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zOiBpbnB1dC5leHRlcm5hbERlZlRyYW5zZm9ybXMgfHwgW10sXG4gICAgICAgIHZpZXdDb250YWluZXJBcHBlbmRzOiBpbnB1dC52aWV3Q29udGFpbmVyQXBwZW5kcyB8fCBbXSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBpbnB1dC5ldmVudERyb3BUcmFuc2Zvcm1lcnMgfHwgW10sXG4gICAgICAgIGNvbXBvbmVudEludGVyYWN0aW9uczogaW5wdXQuY29tcG9uZW50SW50ZXJhY3Rpb25zIHx8IFtdLFxuICAgICAgICBjYWxlbmRhckludGVyYWN0aW9uczogaW5wdXQuY2FsZW5kYXJJbnRlcmFjdGlvbnMgfHwgW10sXG4gICAgICAgIHRoZW1lQ2xhc3NlczogaW5wdXQudGhlbWVDbGFzc2VzIHx8IHt9LFxuICAgICAgICBldmVudFNvdXJjZURlZnM6IGlucHV0LmV2ZW50U291cmNlRGVmcyB8fCBbXSxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBpbnB1dC5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBpbnB1dC5yZWN1cnJpbmdUeXBlcyB8fCBbXSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZWRJbXBsOiBpbnB1dC5uYW1lZFRpbWVab25lZEltcGwsXG4gICAgICAgIGluaXRpYWxWaWV3OiBpbnB1dC5pbml0aWFsVmlldyB8fCAnJyxcbiAgICAgICAgZWxlbWVudERyYWdnaW5nSW1wbDogaW5wdXQuZWxlbWVudERyYWdnaW5nSW1wbCxcbiAgICAgICAgb3B0aW9uQ2hhbmdlSGFuZGxlcnM6IGlucHV0Lm9wdGlvbkNoYW5nZUhhbmRsZXJzIHx8IHt9LFxuICAgICAgICBzY3JvbGxHcmlkSW1wbDogaW5wdXQuc2Nyb2xsR3JpZEltcGwgfHwgbnVsbCxcbiAgICAgICAgbGlzdGVuZXJSZWZpbmVyczogaW5wdXQubGlzdGVuZXJSZWZpbmVycyB8fCB7fSxcbiAgICAgICAgb3B0aW9uUmVmaW5lcnM6IGlucHV0Lm9wdGlvblJlZmluZXJzIHx8IHt9LFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IGlucHV0LnByb3BTZXRIYW5kbGVycyB8fCB7fSxcbiAgICB9O1xufVxuZnVuY3Rpb24gYnVpbGRQbHVnaW5Ib29rcyhwbHVnaW5EZWZzLCBnbG9iYWxEZWZzKSB7XG4gICAgbGV0IGN1cnJlbnRQbHVnaW5JZHMgPSB7fTtcbiAgICBsZXQgaG9va3MgPSB7XG4gICAgICAgIHByZW1pdW1SZWxlYXNlRGF0ZTogdW5kZWZpbmVkLFxuICAgICAgICByZWR1Y2VyczogW10sXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBbXSxcbiAgICAgICAgY29udGV4dEluaXQ6IFtdLFxuICAgICAgICBldmVudFJlZmluZXJzOiB7fSxcbiAgICAgICAgZXZlbnREZWZNZW1iZXJBZGRlcnM6IFtdLFxuICAgICAgICBldmVudFNvdXJjZVJlZmluZXJzOiB7fSxcbiAgICAgICAgaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogW10sXG4gICAgICAgIGV2ZW50RGVmTXV0YXRpb25BcHBsaWVyczogW10sXG4gICAgICAgIGRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBbXSxcbiAgICAgICAgZGF0ZVNwYW5UcmFuc2Zvcm1zOiBbXSxcbiAgICAgICAgdmlld3M6IHt9LFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBpc1Byb3BzVmFsaWQ6IG51bGwsXG4gICAgICAgIGV4dGVybmFsRGVmVHJhbnNmb3JtczogW10sXG4gICAgICAgIHZpZXdDb250YWluZXJBcHBlbmRzOiBbXSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBbXSxcbiAgICAgICAgY29tcG9uZW50SW50ZXJhY3Rpb25zOiBbXSxcbiAgICAgICAgY2FsZW5kYXJJbnRlcmFjdGlvbnM6IFtdLFxuICAgICAgICB0aGVtZUNsYXNzZXM6IHt9LFxuICAgICAgICBldmVudFNvdXJjZURlZnM6IFtdLFxuICAgICAgICBjbWRGb3JtYXR0ZXI6IG51bGwsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBbXSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZWRJbXBsOiBudWxsLFxuICAgICAgICBpbml0aWFsVmlldzogJycsXG4gICAgICAgIGVsZW1lbnREcmFnZ2luZ0ltcGw6IG51bGwsXG4gICAgICAgIG9wdGlvbkNoYW5nZUhhbmRsZXJzOiB7fSxcbiAgICAgICAgc2Nyb2xsR3JpZEltcGw6IG51bGwsXG4gICAgICAgIGxpc3RlbmVyUmVmaW5lcnM6IHt9LFxuICAgICAgICBvcHRpb25SZWZpbmVyczoge30sXG4gICAgICAgIHByb3BTZXRIYW5kbGVyczoge30sXG4gICAgfTtcbiAgICBmdW5jdGlvbiBhZGREZWZzKGRlZnMpIHtcbiAgICAgICAgZm9yIChsZXQgZGVmIG9mIGRlZnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBsdWdpbk5hbWUgPSBkZWYubmFtZTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRJZCA9IGN1cnJlbnRQbHVnaW5JZHNbcGx1Z2luTmFtZV07XG4gICAgICAgICAgICBpZiAoY3VycmVudElkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UGx1Z2luSWRzW3BsdWdpbk5hbWVdID0gZGVmLmlkO1xuICAgICAgICAgICAgICAgIGFkZERlZnMoZGVmLmRlcHMpO1xuICAgICAgICAgICAgICAgIGhvb2tzID0gY29tYmluZUhvb2tzKGhvb2tzLCBkZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudElkICE9PSBkZWYuaWQpIHtcbiAgICAgICAgICAgICAgICAvLyBkaWZmZXJlbnQgSUQgdGhhbiB0aGUgb25lIGFscmVhZHkgYWRkZWRcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYER1cGxpY2F0ZSBwbHVnaW4gJyR7cGx1Z2luTmFtZX0nYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBsdWdpbkRlZnMpIHtcbiAgICAgICAgYWRkRGVmcyhwbHVnaW5EZWZzKTtcbiAgICB9XG4gICAgYWRkRGVmcyhnbG9iYWxEZWZzKTtcbiAgICByZXR1cm4gaG9va3M7XG59XG5mdW5jdGlvbiBidWlsZEJ1aWxkUGx1Z2luSG9va3MoKSB7XG4gICAgbGV0IGN1cnJlbnRPdmVycmlkZURlZnMgPSBbXTtcbiAgICBsZXQgY3VycmVudEdsb2JhbERlZnMgPSBbXTtcbiAgICBsZXQgY3VycmVudEhvb2tzO1xuICAgIHJldHVybiAob3ZlcnJpZGVEZWZzLCBnbG9iYWxEZWZzKSA9PiB7XG4gICAgICAgIGlmICghY3VycmVudEhvb2tzIHx8ICFpc0FycmF5c0VxdWFsKG92ZXJyaWRlRGVmcywgY3VycmVudE92ZXJyaWRlRGVmcykgfHwgIWlzQXJyYXlzRXF1YWwoZ2xvYmFsRGVmcywgY3VycmVudEdsb2JhbERlZnMpKSB7XG4gICAgICAgICAgICBjdXJyZW50SG9va3MgPSBidWlsZFBsdWdpbkhvb2tzKG92ZXJyaWRlRGVmcywgZ2xvYmFsRGVmcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudE92ZXJyaWRlRGVmcyA9IG92ZXJyaWRlRGVmcztcbiAgICAgICAgY3VycmVudEdsb2JhbERlZnMgPSBnbG9iYWxEZWZzO1xuICAgICAgICByZXR1cm4gY3VycmVudEhvb2tzO1xuICAgIH07XG59XG5mdW5jdGlvbiBjb21iaW5lSG9va3MoaG9va3MwLCBob29rczEpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBwcmVtaXVtUmVsZWFzZURhdGU6IGNvbXBhcmVPcHRpb25hbERhdGVzKGhvb2tzMC5wcmVtaXVtUmVsZWFzZURhdGUsIGhvb2tzMS5wcmVtaXVtUmVsZWFzZURhdGUpLFxuICAgICAgICByZWR1Y2VyczogaG9va3MwLnJlZHVjZXJzLmNvbmNhdChob29rczEucmVkdWNlcnMpLFxuICAgICAgICBpc0xvYWRpbmdGdW5jczogaG9va3MwLmlzTG9hZGluZ0Z1bmNzLmNvbmNhdChob29rczEuaXNMb2FkaW5nRnVuY3MpLFxuICAgICAgICBjb250ZXh0SW5pdDogaG9va3MwLmNvbnRleHRJbml0LmNvbmNhdChob29rczEuY29udGV4dEluaXQpLFxuICAgICAgICBldmVudFJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5ldmVudFJlZmluZXJzKSwgaG9va3MxLmV2ZW50UmVmaW5lcnMpLFxuICAgICAgICBldmVudERlZk1lbWJlckFkZGVyczogaG9va3MwLmV2ZW50RGVmTWVtYmVyQWRkZXJzLmNvbmNhdChob29rczEuZXZlbnREZWZNZW1iZXJBZGRlcnMpLFxuICAgICAgICBldmVudFNvdXJjZVJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5ldmVudFNvdXJjZVJlZmluZXJzKSwgaG9va3MxLmV2ZW50U291cmNlUmVmaW5lcnMpLFxuICAgICAgICBpc0RyYWdnYWJsZVRyYW5zZm9ybWVyczogaG9va3MwLmlzRHJhZ2dhYmxlVHJhbnNmb3JtZXJzLmNvbmNhdChob29rczEuaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnMpLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogaG9va3MwLmV2ZW50RHJhZ011dGF0aW9uTWFzc2FnZXJzLmNvbmNhdChob29rczEuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMpLFxuICAgICAgICBldmVudERlZk11dGF0aW9uQXBwbGllcnM6IGhvb2tzMC5ldmVudERlZk11dGF0aW9uQXBwbGllcnMuY29uY2F0KGhvb2tzMS5ldmVudERlZk11dGF0aW9uQXBwbGllcnMpLFxuICAgICAgICBkYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzOiBob29rczAuZGF0ZVNlbGVjdGlvblRyYW5zZm9ybWVycy5jb25jYXQoaG9va3MxLmRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnMpLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBob29rczAuZGF0ZVBvaW50VHJhbnNmb3Jtcy5jb25jYXQoaG9va3MxLmRhdGVQb2ludFRyYW5zZm9ybXMpLFxuICAgICAgICBkYXRlU3BhblRyYW5zZm9ybXM6IGhvb2tzMC5kYXRlU3BhblRyYW5zZm9ybXMuY29uY2F0KGhvb2tzMS5kYXRlU3BhblRyYW5zZm9ybXMpLFxuICAgICAgICB2aWV3czogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBob29rczAudmlld3MpLCBob29rczEudmlld3MpLFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IGhvb2tzMC52aWV3UHJvcHNUcmFuc2Zvcm1lcnMuY29uY2F0KGhvb2tzMS52aWV3UHJvcHNUcmFuc2Zvcm1lcnMpLFxuICAgICAgICBpc1Byb3BzVmFsaWQ6IGhvb2tzMS5pc1Byb3BzVmFsaWQgfHwgaG9va3MwLmlzUHJvcHNWYWxpZCxcbiAgICAgICAgZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zOiBob29rczAuZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zLmNvbmNhdChob29rczEuZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zKSxcbiAgICAgICAgdmlld0NvbnRhaW5lckFwcGVuZHM6IGhvb2tzMC52aWV3Q29udGFpbmVyQXBwZW5kcy5jb25jYXQoaG9va3MxLnZpZXdDb250YWluZXJBcHBlbmRzKSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBob29rczAuZXZlbnREcm9wVHJhbnNmb3JtZXJzLmNvbmNhdChob29rczEuZXZlbnREcm9wVHJhbnNmb3JtZXJzKSxcbiAgICAgICAgY2FsZW5kYXJJbnRlcmFjdGlvbnM6IGhvb2tzMC5jYWxlbmRhckludGVyYWN0aW9ucy5jb25jYXQoaG9va3MxLmNhbGVuZGFySW50ZXJhY3Rpb25zKSxcbiAgICAgICAgY29tcG9uZW50SW50ZXJhY3Rpb25zOiBob29rczAuY29tcG9uZW50SW50ZXJhY3Rpb25zLmNvbmNhdChob29rczEuY29tcG9uZW50SW50ZXJhY3Rpb25zKSxcbiAgICAgICAgdGhlbWVDbGFzc2VzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC50aGVtZUNsYXNzZXMpLCBob29rczEudGhlbWVDbGFzc2VzKSxcbiAgICAgICAgZXZlbnRTb3VyY2VEZWZzOiBob29rczAuZXZlbnRTb3VyY2VEZWZzLmNvbmNhdChob29rczEuZXZlbnRTb3VyY2VEZWZzKSxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBob29rczEuY21kRm9ybWF0dGVyIHx8IGhvb2tzMC5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBob29rczAucmVjdXJyaW5nVHlwZXMuY29uY2F0KGhvb2tzMS5yZWN1cnJpbmdUeXBlcyksXG4gICAgICAgIG5hbWVkVGltZVpvbmVkSW1wbDogaG9va3MxLm5hbWVkVGltZVpvbmVkSW1wbCB8fCBob29rczAubmFtZWRUaW1lWm9uZWRJbXBsLFxuICAgICAgICBpbml0aWFsVmlldzogaG9va3MwLmluaXRpYWxWaWV3IHx8IGhvb2tzMS5pbml0aWFsVmlldyxcbiAgICAgICAgZWxlbWVudERyYWdnaW5nSW1wbDogaG9va3MwLmVsZW1lbnREcmFnZ2luZ0ltcGwgfHwgaG9va3MxLmVsZW1lbnREcmFnZ2luZ0ltcGwsXG4gICAgICAgIG9wdGlvbkNoYW5nZUhhbmRsZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5vcHRpb25DaGFuZ2VIYW5kbGVycyksIGhvb2tzMS5vcHRpb25DaGFuZ2VIYW5kbGVycyksXG4gICAgICAgIHNjcm9sbEdyaWRJbXBsOiBob29rczEuc2Nyb2xsR3JpZEltcGwgfHwgaG9va3MwLnNjcm9sbEdyaWRJbXBsLFxuICAgICAgICBsaXN0ZW5lclJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5saXN0ZW5lclJlZmluZXJzKSwgaG9va3MxLmxpc3RlbmVyUmVmaW5lcnMpLFxuICAgICAgICBvcHRpb25SZWZpbmVyczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBob29rczAub3B0aW9uUmVmaW5lcnMpLCBob29rczEub3B0aW9uUmVmaW5lcnMpLFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLnByb3BTZXRIYW5kbGVycyksIGhvb2tzMS5wcm9wU2V0SGFuZGxlcnMpLFxuICAgIH07XG59XG5mdW5jdGlvbiBjb21wYXJlT3B0aW9uYWxEYXRlcyhkYXRlMCwgZGF0ZTEpIHtcbiAgICBpZiAoZGF0ZTAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGF0ZTE7XG4gICAgfVxuICAgIGlmIChkYXRlMSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkYXRlMDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEYXRlKE1hdGgubWF4KGRhdGUwLnZhbHVlT2YoKSwgZGF0ZTEudmFsdWVPZigpKSk7XG59XG5cbmNsYXNzIFN0YW5kYXJkVGhlbWUgZXh0ZW5kcyBUaGVtZSB7XG59XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5jbGFzc2VzID0ge1xuICAgIHJvb3Q6ICdmYy10aGVtZS1zdGFuZGFyZCcsXG4gICAgdGFibGVDZWxsU2hhZGVkOiAnZmMtY2VsbC1zaGFkZWQnLFxuICAgIGJ1dHRvbkdyb3VwOiAnZmMtYnV0dG9uLWdyb3VwJyxcbiAgICBidXR0b246ICdmYy1idXR0b24gZmMtYnV0dG9uLXByaW1hcnknLFxuICAgIGJ1dHRvbkFjdGl2ZTogJ2ZjLWJ1dHRvbi1hY3RpdmUnLFxufTtcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmJhc2VJY29uQ2xhc3MgPSAnZmMtaWNvbic7XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5pY29uQ2xhc3NlcyA9IHtcbiAgICBjbG9zZTogJ2ZjLWljb24teCcsXG4gICAgcHJldjogJ2ZjLWljb24tY2hldnJvbi1sZWZ0JyxcbiAgICBuZXh0OiAnZmMtaWNvbi1jaGV2cm9uLXJpZ2h0JyxcbiAgICBwcmV2WWVhcjogJ2ZjLWljb24tY2hldnJvbnMtbGVmdCcsXG4gICAgbmV4dFllYXI6ICdmYy1pY29uLWNoZXZyb25zLXJpZ2h0Jyxcbn07XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5ydGxJY29uQ2xhc3NlcyA9IHtcbiAgICBwcmV2OiAnZmMtaWNvbi1jaGV2cm9uLXJpZ2h0JyxcbiAgICBuZXh0OiAnZmMtaWNvbi1jaGV2cm9uLWxlZnQnLFxuICAgIHByZXZZZWFyOiAnZmMtaWNvbi1jaGV2cm9ucy1yaWdodCcsXG4gICAgbmV4dFllYXI6ICdmYy1pY29uLWNoZXZyb25zLWxlZnQnLFxufTtcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZU9wdGlvbiA9ICdidXR0b25JY29ucyc7IC8vIFRPRE86IG1ha2UgVFMtZnJpZW5kbHlcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZUN1c3RvbUJ1dHRvbk9wdGlvbiA9ICdpY29uJztcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZVByZWZpeCA9ICdmYy1pY29uLSc7XG5cbmZ1bmN0aW9uIGNvbXBpbGVWaWV3RGVmcyhkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKSB7XG4gICAgbGV0IGhhc2ggPSB7fTtcbiAgICBsZXQgdmlld1R5cGU7XG4gICAgZm9yICh2aWV3VHlwZSBpbiBkZWZhdWx0Q29uZmlncykge1xuICAgICAgICBlbnN1cmVWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICB9XG4gICAgZm9yICh2aWV3VHlwZSBpbiBvdmVycmlkZUNvbmZpZ3MpIHtcbiAgICAgICAgZW5zdXJlVmlld0RlZih2aWV3VHlwZSwgaGFzaCwgZGVmYXVsdENvbmZpZ3MsIG92ZXJyaWRlQ29uZmlncyk7XG4gICAgfVxuICAgIHJldHVybiBoYXNoO1xufVxuZnVuY3Rpb24gZW5zdXJlVmlld0RlZih2aWV3VHlwZSwgaGFzaCwgZGVmYXVsdENvbmZpZ3MsIG92ZXJyaWRlQ29uZmlncykge1xuICAgIGlmIChoYXNoW3ZpZXdUeXBlXSkge1xuICAgICAgICByZXR1cm4gaGFzaFt2aWV3VHlwZV07XG4gICAgfVxuICAgIGxldCB2aWV3RGVmID0gYnVpbGRWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICBpZiAodmlld0RlZikge1xuICAgICAgICBoYXNoW3ZpZXdUeXBlXSA9IHZpZXdEZWY7XG4gICAgfVxuICAgIHJldHVybiB2aWV3RGVmO1xufVxuZnVuY3Rpb24gYnVpbGRWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKSB7XG4gICAgbGV0IGRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnc1t2aWV3VHlwZV07XG4gICAgbGV0IG92ZXJyaWRlQ29uZmlnID0gb3ZlcnJpZGVDb25maWdzW3ZpZXdUeXBlXTtcbiAgICBsZXQgcXVlcnlQcm9wID0gKG5hbWUpID0+ICgoZGVmYXVsdENvbmZpZyAmJiBkZWZhdWx0Q29uZmlnW25hbWVdICE9PSBudWxsKSA/IGRlZmF1bHRDb25maWdbbmFtZV0gOlxuICAgICAgICAoKG92ZXJyaWRlQ29uZmlnICYmIG92ZXJyaWRlQ29uZmlnW25hbWVdICE9PSBudWxsKSA/IG92ZXJyaWRlQ29uZmlnW25hbWVdIDogbnVsbCkpO1xuICAgIGxldCB0aGVDb21wb25lbnQgPSBxdWVyeVByb3AoJ2NvbXBvbmVudCcpO1xuICAgIGxldCBzdXBlclR5cGUgPSBxdWVyeVByb3AoJ3N1cGVyVHlwZScpO1xuICAgIGxldCBzdXBlckRlZiA9IG51bGw7XG4gICAgaWYgKHN1cGVyVHlwZSkge1xuICAgICAgICBpZiAoc3VwZXJUeXBlID09PSB2aWV3VHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGhhdmUgYSBjdXN0b20gdmlldyB0eXBlIHRoYXQgcmVmZXJlbmNlcyBpdHNlbGYnKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlckRlZiA9IGVuc3VyZVZpZXdEZWYoc3VwZXJUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICB9XG4gICAgaWYgKCF0aGVDb21wb25lbnQgJiYgc3VwZXJEZWYpIHtcbiAgICAgICAgdGhlQ29tcG9uZW50ID0gc3VwZXJEZWYuY29tcG9uZW50O1xuICAgIH1cbiAgICBpZiAoIXRoZUNvbXBvbmVudCkge1xuICAgICAgICByZXR1cm4gbnVsbDsgLy8gZG9uJ3QgdGhyb3cgYSB3YXJuaW5nLCBtaWdodCBiZSBzZXR0aW5ncyBmb3IgYSBzaW5nbGUtdW5pdCB2aWV3XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHZpZXdUeXBlLFxuICAgICAgICBjb21wb25lbnQ6IHRoZUNvbXBvbmVudCxcbiAgICAgICAgZGVmYXVsdHM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgKHN1cGVyRGVmID8gc3VwZXJEZWYuZGVmYXVsdHMgOiB7fSkpLCAoZGVmYXVsdENvbmZpZyA/IGRlZmF1bHRDb25maWcucmF3T3B0aW9ucyA6IHt9KSksXG4gICAgICAgIG92ZXJyaWRlczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCAoc3VwZXJEZWYgPyBzdXBlckRlZi5vdmVycmlkZXMgOiB7fSkpLCAob3ZlcnJpZGVDb25maWcgPyBvdmVycmlkZUNvbmZpZy5yYXdPcHRpb25zIDoge30pKSxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZVZpZXdDb25maWdzKGlucHV0cykge1xuICAgIHJldHVybiBtYXBIYXNoKGlucHV0cywgcGFyc2VWaWV3Q29uZmlnKTtcbn1cbmZ1bmN0aW9uIHBhcnNlVmlld0NvbmZpZyhpbnB1dCkge1xuICAgIGxldCByYXdPcHRpb25zID0gdHlwZW9mIGlucHV0ID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgeyBjb21wb25lbnQ6IGlucHV0IH0gOlxuICAgICAgICBpbnB1dDtcbiAgICBsZXQgeyBjb21wb25lbnQgfSA9IHJhd09wdGlvbnM7XG4gICAgaWYgKHJhd09wdGlvbnMuY29udGVudCkge1xuICAgICAgICAvLyBUT0RPOiByZW1vdmUgY29udGVudC9jbGFzc05hbWVzL2RpZE1vdW50L2V0YyBmcm9tIG9wdGlvbnM/XG4gICAgICAgIGNvbXBvbmVudCA9IGNyZWF0ZVZpZXdIb29rQ29tcG9uZW50KHJhd09wdGlvbnMpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb21wb25lbnQgJiYgIShjb21wb25lbnQucHJvdG90eXBlIGluc3RhbmNlb2YgQmFzZUNvbXBvbmVudCkpIHtcbiAgICAgICAgLy8gV0hZPzogcGVvcGxlIHdlcmUgdXNpbmcgYGNvbXBvbmVudGAgcHJvcGVydHkgZm9yIGBjb250ZW50YFxuICAgICAgICAvLyBUT0RPOiBjb252ZXJnZSBvbiBvbmUgc2V0dGluZyBuYW1lXG4gICAgICAgIGNvbXBvbmVudCA9IGNyZWF0ZVZpZXdIb29rQ29tcG9uZW50KE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgcmF3T3B0aW9ucyksIHsgY29udGVudDogY29tcG9uZW50IH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3VwZXJUeXBlOiByYXdPcHRpb25zLnR5cGUsXG4gICAgICAgIGNvbXBvbmVudDogY29tcG9uZW50LFxuICAgICAgICByYXdPcHRpb25zLCAvLyBpbmNsdWRlcyB0eXBlIGFuZCBjb21wb25lbnQgdG9vIDooXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVZpZXdIb29rQ29tcG9uZW50KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gKHZpZXdQcm9wcykgPT4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbnRleHRUeXBlLkNvbnN1bWVyLCBudWxsLCAoY29udGV4dCkgPT4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgeyBlbFRhZzogXCJkaXZcIiwgZWxDbGFzc2VzOiBidWlsZFZpZXdDbGFzc05hbWVzKGNvbnRleHQudmlld1NwZWMpLCByZW5kZXJQcm9wczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCB2aWV3UHJvcHMpLCB7IG5leHREYXlUaHJlc2hvbGQ6IGNvbnRleHQub3B0aW9ucy5uZXh0RGF5VGhyZXNob2xkIH0pLCBnZW5lcmF0b3JOYW1lOiB1bmRlZmluZWQsIGN1c3RvbUdlbmVyYXRvcjogb3B0aW9ucy5jb250ZW50LCBjbGFzc05hbWVHZW5lcmF0b3I6IG9wdGlvbnMuY2xhc3NOYW1lcywgZGlkTW91bnQ6IG9wdGlvbnMuZGlkTW91bnQsIHdpbGxVbm1vdW50OiBvcHRpb25zLndpbGxVbm1vdW50IH0pKSkpO1xufVxuXG5mdW5jdGlvbiBidWlsZFZpZXdTcGVjcyhkZWZhdWx0SW5wdXRzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKSB7XG4gICAgbGV0IGRlZmF1bHRDb25maWdzID0gcGFyc2VWaWV3Q29uZmlncyhkZWZhdWx0SW5wdXRzKTtcbiAgICBsZXQgb3ZlcnJpZGVDb25maWdzID0gcGFyc2VWaWV3Q29uZmlncyhvcHRpb25PdmVycmlkZXMudmlld3MpO1xuICAgIGxldCB2aWV3RGVmcyA9IGNvbXBpbGVWaWV3RGVmcyhkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICByZXR1cm4gbWFwSGFzaCh2aWV3RGVmcywgKHZpZXdEZWYpID0+IGJ1aWxkVmlld1NwZWModmlld0RlZiwgb3ZlcnJpZGVDb25maWdzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKSk7XG59XG5mdW5jdGlvbiBidWlsZFZpZXdTcGVjKHZpZXdEZWYsIG92ZXJyaWRlQ29uZmlncywgb3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBsb2NhbGVEZWZhdWx0cykge1xuICAgIGxldCBkdXJhdGlvbklucHV0ID0gdmlld0RlZi5vdmVycmlkZXMuZHVyYXRpb24gfHxcbiAgICAgICAgdmlld0RlZi5kZWZhdWx0cy5kdXJhdGlvbiB8fFxuICAgICAgICBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLmR1cmF0aW9uIHx8XG4gICAgICAgIG9wdGlvbk92ZXJyaWRlcy5kdXJhdGlvbjtcbiAgICBsZXQgZHVyYXRpb24gPSBudWxsO1xuICAgIGxldCBkdXJhdGlvblVuaXQgPSAnJztcbiAgICBsZXQgc2luZ2xlVW5pdCA9ICcnO1xuICAgIGxldCBzaW5nbGVVbml0T3ZlcnJpZGVzID0ge307XG4gICAgaWYgKGR1cmF0aW9uSW5wdXQpIHtcbiAgICAgICAgZHVyYXRpb24gPSBjcmVhdGVEdXJhdGlvbkNhY2hlZChkdXJhdGlvbklucHV0KTtcbiAgICAgICAgaWYgKGR1cmF0aW9uKSB7IC8vIHZhbGlkP1xuICAgICAgICAgICAgbGV0IGRlbm9tID0gZ3JlYXRlc3REdXJhdGlvbkRlbm9taW5hdG9yKGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGR1cmF0aW9uVW5pdCA9IGRlbm9tLnVuaXQ7XG4gICAgICAgICAgICBpZiAoZGVub20udmFsdWUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICBzaW5nbGVVbml0ID0gZHVyYXRpb25Vbml0O1xuICAgICAgICAgICAgICAgIHNpbmdsZVVuaXRPdmVycmlkZXMgPSBvdmVycmlkZUNvbmZpZ3NbZHVyYXRpb25Vbml0XSA/IG92ZXJyaWRlQ29uZmlnc1tkdXJhdGlvblVuaXRdLnJhd09wdGlvbnMgOiB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgcXVlcnlCdXR0b25UZXh0ID0gKG9wdGlvbnNTdWJzZXQpID0+IHtcbiAgICAgICAgbGV0IGJ1dHRvblRleHRNYXAgPSBvcHRpb25zU3Vic2V0LmJ1dHRvblRleHQgfHwge307XG4gICAgICAgIGxldCBidXR0b25UZXh0S2V5ID0gdmlld0RlZi5kZWZhdWx0cy5idXR0b25UZXh0S2V5O1xuICAgICAgICBpZiAoYnV0dG9uVGV4dEtleSAhPSBudWxsICYmIGJ1dHRvblRleHRNYXBbYnV0dG9uVGV4dEtleV0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGJ1dHRvblRleHRNYXBbYnV0dG9uVGV4dEtleV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ1dHRvblRleHRNYXBbdmlld0RlZi50eXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uVGV4dE1hcFt2aWV3RGVmLnR5cGVdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidXR0b25UZXh0TWFwW3NpbmdsZVVuaXRdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25UZXh0TWFwW3NpbmdsZVVuaXRdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgbGV0IHF1ZXJ5QnV0dG9uVGl0bGUgPSAob3B0aW9uc1N1YnNldCkgPT4ge1xuICAgICAgICBsZXQgYnV0dG9uSGludHMgPSBvcHRpb25zU3Vic2V0LmJ1dHRvbkhpbnRzIHx8IHt9O1xuICAgICAgICBsZXQgYnV0dG9uS2V5ID0gdmlld0RlZi5kZWZhdWx0cy5idXR0b25UZXh0S2V5OyAvLyB1c2Ugc2FtZSBrZXkgYXMgdGV4dFxuICAgICAgICBpZiAoYnV0dG9uS2V5ICE9IG51bGwgJiYgYnV0dG9uSGludHNbYnV0dG9uS2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uSGludHNbYnV0dG9uS2V5XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnV0dG9uSGludHNbdmlld0RlZi50eXBlXSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uSGludHNbdmlld0RlZi50eXBlXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnV0dG9uSGludHNbc2luZ2xlVW5pdF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGJ1dHRvbkhpbnRzW3NpbmdsZVVuaXRdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogdmlld0RlZi50eXBlLFxuICAgICAgICBjb21wb25lbnQ6IHZpZXdEZWYuY29tcG9uZW50LFxuICAgICAgICBkdXJhdGlvbixcbiAgICAgICAgZHVyYXRpb25Vbml0LFxuICAgICAgICBzaW5nbGVVbml0LFxuICAgICAgICBvcHRpb25EZWZhdWx0czogdmlld0RlZi5kZWZhdWx0cyxcbiAgICAgICAgb3B0aW9uT3ZlcnJpZGVzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHNpbmdsZVVuaXRPdmVycmlkZXMpLCB2aWV3RGVmLm92ZXJyaWRlcyksXG4gICAgICAgIGJ1dHRvblRleHRPdmVycmlkZTogcXVlcnlCdXR0b25UZXh0KGR5bmFtaWNPcHRpb25PdmVycmlkZXMpIHx8XG4gICAgICAgICAgICBxdWVyeUJ1dHRvblRleHQob3B0aW9uT3ZlcnJpZGVzKSB8fCAvLyBjb25zdHJ1Y3Rvci1zcGVjaWZpZWQgYnV0dG9uVGV4dCBsb29rdXAgaGFzaCB0YWtlcyBwcmVjZWRlbmNlXG4gICAgICAgICAgICB2aWV3RGVmLm92ZXJyaWRlcy5idXR0b25UZXh0LFxuICAgICAgICBidXR0b25UZXh0RGVmYXVsdDogcXVlcnlCdXR0b25UZXh0KGxvY2FsZURlZmF1bHRzKSB8fFxuICAgICAgICAgICAgdmlld0RlZi5kZWZhdWx0cy5idXR0b25UZXh0IHx8XG4gICAgICAgICAgICBxdWVyeUJ1dHRvblRleHQoQkFTRV9PUFRJT05fREVGQVVMVFMpIHx8XG4gICAgICAgICAgICB2aWV3RGVmLnR5cGUsXG4gICAgICAgIC8vIG5vdCBEUllcbiAgICAgICAgYnV0dG9uVGl0bGVPdmVycmlkZTogcXVlcnlCdXR0b25UaXRsZShkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB8fFxuICAgICAgICAgICAgcXVlcnlCdXR0b25UaXRsZShvcHRpb25PdmVycmlkZXMpIHx8XG4gICAgICAgICAgICB2aWV3RGVmLm92ZXJyaWRlcy5idXR0b25IaW50LFxuICAgICAgICBidXR0b25UaXRsZURlZmF1bHQ6IHF1ZXJ5QnV0dG9uVGl0bGUobG9jYWxlRGVmYXVsdHMpIHx8XG4gICAgICAgICAgICB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvbkhpbnQgfHxcbiAgICAgICAgICAgIHF1ZXJ5QnV0dG9uVGl0bGUoQkFTRV9PUFRJT05fREVGQVVMVFMpLFxuICAgICAgICAvLyB3aWxsIGV2ZW50dWFsbHkgZmFsbCBiYWNrIHRvIGJ1dHRvblRleHRcbiAgICB9O1xufVxuLy8gaGFjayB0byBnZXQgbWVtb2l6YXRpb24gd29ya2luZ1xubGV0IGR1cmF0aW9uSW5wdXRNYXAgPSB7fTtcbmZ1bmN0aW9uIGNyZWF0ZUR1cmF0aW9uQ2FjaGVkKGR1cmF0aW9uSW5wdXQpIHtcbiAgICBsZXQganNvbiA9IEpTT04uc3RyaW5naWZ5KGR1cmF0aW9uSW5wdXQpO1xuICAgIGxldCByZXMgPSBkdXJhdGlvbklucHV0TWFwW2pzb25dO1xuICAgIGlmIChyZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXMgPSBjcmVhdGVEdXJhdGlvbihkdXJhdGlvbklucHV0KTtcbiAgICAgICAgZHVyYXRpb25JbnB1dE1hcFtqc29uXSA9IHJlcztcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuZnVuY3Rpb24gcmVkdWNlVmlld1R5cGUodmlld1R5cGUsIGFjdGlvbikge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnQ0hBTkdFX1ZJRVdfVFlQRSc6XG4gICAgICAgICAgICB2aWV3VHlwZSA9IGFjdGlvbi52aWV3VHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXdUeXBlO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VDdXJyZW50RGF0ZShjdXJyZW50RGF0ZSwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdDSEFOR0VfREFURSc6XG4gICAgICAgICAgICByZXR1cm4gYWN0aW9uLmRhdGVNYXJrZXI7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERhdGU7XG4gICAgfVxufVxuLy8gc2hvdWxkIGJlIGluaXRpYWxpemVkIG9uY2UgYW5kIHN0YXkgY29uc3RhbnRcbi8vIHRoaXMgd2lsbCBjaGFuZ2UgdG9vXG5mdW5jdGlvbiBnZXRJbml0aWFsRGF0ZShvcHRpb25zLCBkYXRlRW52LCBub3dNYW5hZ2VyKSB7XG4gICAgbGV0IGluaXRpYWxEYXRlSW5wdXQgPSBvcHRpb25zLmluaXRpYWxEYXRlO1xuICAgIC8vIGNvbXB1dGUgdGhlIGluaXRpYWwgYW1iaWctdGltZXpvbmUgZGF0ZVxuICAgIGlmIChpbml0aWFsRGF0ZUlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGRhdGVFbnYuY3JlYXRlTWFya2VyKGluaXRpYWxEYXRlSW5wdXQpO1xuICAgIH1cbiAgICByZXR1cm4gbm93TWFuYWdlci5nZXREYXRlTWFya2VyKCk7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUR5bmFtaWNPcHRpb25PdmVycmlkZXMoZHluYW1pY09wdGlvbk92ZXJyaWRlcywgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdTRVRfT1BUSU9OJzpcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpLCB7IFthY3Rpb24ub3B0aW9uTmFtZV06IGFjdGlvbi5yYXdPcHRpb25WYWx1ZSB9KTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlRGF0ZVByb2ZpbGUoY3VycmVudERhdGVQcm9maWxlLCBhY3Rpb24sIGN1cnJlbnREYXRlLCBkYXRlUHJvZmlsZUdlbmVyYXRvcikge1xuICAgIGxldCBkcDtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9WSUVXX1RZUEUnOlxuICAgICAgICAgICAgcmV0dXJuIGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGFjdGlvbi5kYXRlTWFya2VyIHx8IGN1cnJlbnREYXRlKTtcbiAgICAgICAgY2FzZSAnQ0hBTkdFX0RBVEUnOlxuICAgICAgICAgICAgcmV0dXJuIGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGFjdGlvbi5kYXRlTWFya2VyKTtcbiAgICAgICAgY2FzZSAnUFJFVic6XG4gICAgICAgICAgICBkcCA9IGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkUHJldihjdXJyZW50RGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlKTtcbiAgICAgICAgICAgIGlmIChkcC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ05FWFQnOlxuICAgICAgICAgICAgZHAgPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZE5leHQoY3VycmVudERhdGVQcm9maWxlLCBjdXJyZW50RGF0ZSk7XG4gICAgICAgICAgICBpZiAoZHAuaXNWYWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudERhdGVQcm9maWxlO1xufVxuXG5mdW5jdGlvbiBpbml0RXZlbnRTb3VyY2VzKGNhbGVuZGFyT3B0aW9ucywgZGF0ZVByb2ZpbGUsIGNvbnRleHQpIHtcbiAgICBsZXQgYWN0aXZlUmFuZ2UgPSBkYXRlUHJvZmlsZSA/IGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlIDogbnVsbDtcbiAgICByZXR1cm4gYWRkU291cmNlcyh7fSwgcGFyc2VJbml0aWFsU291cmNlcyhjYWxlbmRhck9wdGlvbnMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgY29udGV4dCk7XG59XG5mdW5jdGlvbiByZWR1Y2VFdmVudFNvdXJjZXMoZXZlbnRTb3VyY2VzLCBhY3Rpb24sIGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgbGV0IGFjdGl2ZVJhbmdlID0gZGF0ZVByb2ZpbGUgPyBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSA6IG51bGw7IC8vIG5lZWQgdGhpcyBjaGVjaz9cbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0FERF9FVkVOVF9TT1VSQ0VTJzogLy8gYWxyZWFkeSBwYXJzZWRcbiAgICAgICAgICAgIHJldHVybiBhZGRTb3VyY2VzKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZXMsIGFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbiAgICAgICAgY2FzZSAnUkVNT1ZFX0VWRU5UX1NPVVJDRSc6XG4gICAgICAgICAgICByZXR1cm4gcmVtb3ZlU291cmNlKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkKTtcbiAgICAgICAgY2FzZSAnUFJFVic6IC8vIFRPRE86IGhvdyBkbyB3ZSB0cmFjayBhbGwgYWN0aW9ucyB0aGF0IGFmZmVjdCBkYXRlUHJvZmlsZSA6KFxuICAgICAgICBjYXNlICdORVhUJzpcbiAgICAgICAgY2FzZSAnQ0hBTkdFX0RBVEUnOlxuICAgICAgICBjYXNlICdDSEFOR0VfVklFV19UWVBFJzpcbiAgICAgICAgICAgIGlmIChkYXRlUHJvZmlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaERpcnR5U291cmNlcyhldmVudFNvdXJjZXMsIGFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBldmVudFNvdXJjZXM7XG4gICAgICAgIGNhc2UgJ0ZFVENIX0VWRU5UX1NPVVJDRVMnOlxuICAgICAgICAgICAgcmV0dXJuIGZldGNoU291cmNlc0J5SWRzKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkcyA/IC8vIHdoeSBubyB0eXBlP1xuICAgICAgICAgICAgICAgIGFycmF5VG9IYXNoKGFjdGlvbi5zb3VyY2VJZHMpIDpcbiAgICAgICAgICAgICAgICBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgYWN0aW9uLmlzUmVmZXRjaCB8fCBmYWxzZSwgY29udGV4dCk7XG4gICAgICAgIGNhc2UgJ1JFQ0VJVkVfRVZFTlRTJzpcbiAgICAgICAgY2FzZSAnUkVDRUlWRV9FVkVOVF9FUlJPUic6XG4gICAgICAgICAgICByZXR1cm4gcmVjZWl2ZVJlc3BvbnNlKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkLCBhY3Rpb24uZmV0Y2hJZCwgYWN0aW9uLmZldGNoUmFuZ2UpO1xuICAgICAgICBjYXNlICdSRU1PVkVfQUxMX0VWRU5UX1NPVVJDRVMnOlxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50U291cmNlcztcbiAgICB9XG59XG5mdW5jdGlvbiByZWR1Y2VFdmVudFNvdXJjZXNOZXdUaW1lWm9uZShldmVudFNvdXJjZXMsIGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgbGV0IGFjdGl2ZVJhbmdlID0gZGF0ZVByb2ZpbGUgPyBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSA6IG51bGw7IC8vIG5lZWQgdGhpcyBjaGVjaz9cbiAgICByZXR1cm4gZmV0Y2hTb3VyY2VzQnlJZHMoZXZlbnRTb3VyY2VzLCBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgdHJ1ZSwgY29udGV4dCk7XG59XG5mdW5jdGlvbiBjb21wdXRlRXZlbnRTb3VyY2VzTG9hZGluZyhldmVudFNvdXJjZXMpIHtcbiAgICBmb3IgKGxldCBzb3VyY2VJZCBpbiBldmVudFNvdXJjZXMpIHtcbiAgICAgICAgaWYgKGV2ZW50U291cmNlc1tzb3VyY2VJZF0uaXNGZXRjaGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gYWRkU291cmNlcyhldmVudFNvdXJjZUhhc2gsIHNvdXJjZXMsIGZldGNoUmFuZ2UsIGNvbnRleHQpIHtcbiAgICBsZXQgaGFzaCA9IHt9O1xuICAgIGZvciAobGV0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgICAgIGhhc2hbc291cmNlLnNvdXJjZUlkXSA9IHNvdXJjZTtcbiAgICB9XG4gICAgaWYgKGZldGNoUmFuZ2UpIHtcbiAgICAgICAgaGFzaCA9IGZldGNoRGlydHlTb3VyY2VzKGhhc2gsIGZldGNoUmFuZ2UsIGNvbnRleHQpO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudFNvdXJjZUhhc2gpLCBoYXNoKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZVNvdXJjZShldmVudFNvdXJjZUhhc2gsIHNvdXJjZUlkKSB7XG4gICAgcmV0dXJuIGZpbHRlckhhc2goZXZlbnRTb3VyY2VIYXNoLCAoZXZlbnRTb3VyY2UpID0+IGV2ZW50U291cmNlLnNvdXJjZUlkICE9PSBzb3VyY2VJZCk7XG59XG5mdW5jdGlvbiBmZXRjaERpcnR5U291cmNlcyhzb3VyY2VIYXNoLCBmZXRjaFJhbmdlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIGZldGNoU291cmNlc0J5SWRzKHNvdXJjZUhhc2gsIGZpbHRlckhhc2goc291cmNlSGFzaCwgKGV2ZW50U291cmNlKSA9PiBpc1NvdXJjZURpcnR5KGV2ZW50U291cmNlLCBmZXRjaFJhbmdlLCBjb250ZXh0KSksIGZldGNoUmFuZ2UsIGZhbHNlLCBjb250ZXh0KTtcbn1cbmZ1bmN0aW9uIGlzU291cmNlRGlydHkoZXZlbnRTb3VyY2UsIGZldGNoUmFuZ2UsIGNvbnRleHQpIHtcbiAgICBpZiAoIWRvZXNTb3VyY2VOZWVkUmFuZ2UoZXZlbnRTb3VyY2UsIGNvbnRleHQpKSB7XG4gICAgICAgIHJldHVybiAhZXZlbnRTb3VyY2UubGF0ZXN0RmV0Y2hJZDtcbiAgICB9XG4gICAgcmV0dXJuICFjb250ZXh0Lm9wdGlvbnMubGF6eUZldGNoaW5nIHx8XG4gICAgICAgICFldmVudFNvdXJjZS5mZXRjaFJhbmdlIHx8XG4gICAgICAgIGV2ZW50U291cmNlLmlzRmV0Y2hpbmcgfHwgLy8gYWx3YXlzIGNhbmNlbCBvdXRkYXRlZCBpbi1wcm9ncmVzcyBmZXRjaGVzXG4gICAgICAgIGZldGNoUmFuZ2Uuc3RhcnQgPCBldmVudFNvdXJjZS5mZXRjaFJhbmdlLnN0YXJ0IHx8XG4gICAgICAgIGZldGNoUmFuZ2UuZW5kID4gZXZlbnRTb3VyY2UuZmV0Y2hSYW5nZS5lbmQ7XG59XG5mdW5jdGlvbiBmZXRjaFNvdXJjZXNCeUlkcyhwcmV2U291cmNlcywgc291cmNlSWRIYXNoLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpIHtcbiAgICBsZXQgbmV4dFNvdXJjZXMgPSB7fTtcbiAgICBmb3IgKGxldCBzb3VyY2VJZCBpbiBwcmV2U291cmNlcykge1xuICAgICAgICBsZXQgc291cmNlID0gcHJldlNvdXJjZXNbc291cmNlSWRdO1xuICAgICAgICBpZiAoc291cmNlSWRIYXNoW3NvdXJjZUlkXSkge1xuICAgICAgICAgICAgbmV4dFNvdXJjZXNbc291cmNlSWRdID0gZmV0Y2hTb3VyY2Uoc291cmNlLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbmV4dFNvdXJjZXNbc291cmNlSWRdID0gc291cmNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXh0U291cmNlcztcbn1cbmZ1bmN0aW9uIGZldGNoU291cmNlKGV2ZW50U291cmNlLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpIHtcbiAgICBsZXQgeyBvcHRpb25zLCBjYWxlbmRhckFwaSB9ID0gY29udGV4dDtcbiAgICBsZXQgc291cmNlRGVmID0gY29udGV4dC5wbHVnaW5Ib29rcy5ldmVudFNvdXJjZURlZnNbZXZlbnRTb3VyY2Uuc291cmNlRGVmSWRdO1xuICAgIGxldCBmZXRjaElkID0gZ3VpZCgpO1xuICAgIHNvdXJjZURlZi5mZXRjaCh7XG4gICAgICAgIGV2ZW50U291cmNlLFxuICAgICAgICByYW5nZTogZmV0Y2hSYW5nZSxcbiAgICAgICAgaXNSZWZldGNoLFxuICAgICAgICBjb250ZXh0LFxuICAgIH0sIChyZXMpID0+IHtcbiAgICAgICAgbGV0IHsgcmF3RXZlbnRzIH0gPSByZXM7XG4gICAgICAgIGlmIChvcHRpb25zLmV2ZW50U291cmNlU3VjY2Vzcykge1xuICAgICAgICAgICAgcmF3RXZlbnRzID0gb3B0aW9ucy5ldmVudFNvdXJjZVN1Y2Nlc3MuY2FsbChjYWxlbmRhckFwaSwgcmF3RXZlbnRzLCByZXMucmVzcG9uc2UpIHx8IHJhd0V2ZW50cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnRTb3VyY2Uuc3VjY2Vzcykge1xuICAgICAgICAgICAgcmF3RXZlbnRzID0gZXZlbnRTb3VyY2Uuc3VjY2Vzcy5jYWxsKGNhbGVuZGFyQXBpLCByYXdFdmVudHMsIHJlcy5yZXNwb25zZSkgfHwgcmF3RXZlbnRzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFQ0VJVkVfRVZFTlRTJyxcbiAgICAgICAgICAgIHNvdXJjZUlkOiBldmVudFNvdXJjZS5zb3VyY2VJZCxcbiAgICAgICAgICAgIGZldGNoSWQsXG4gICAgICAgICAgICBmZXRjaFJhbmdlLFxuICAgICAgICAgICAgcmF3RXZlbnRzLFxuICAgICAgICB9KTtcbiAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgICAgbGV0IGVycm9ySGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICBpZiAob3B0aW9ucy5ldmVudFNvdXJjZUZhaWx1cmUpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZXZlbnRTb3VyY2VGYWlsdXJlLmNhbGwoY2FsZW5kYXJBcGksIGVycm9yKTtcbiAgICAgICAgICAgIGVycm9ySGFuZGxlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50U291cmNlLmZhaWx1cmUpIHtcbiAgICAgICAgICAgIGV2ZW50U291cmNlLmZhaWx1cmUoZXJyb3IpO1xuICAgICAgICAgICAgZXJyb3JIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVycm9ySGFuZGxlZCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm1lc3NhZ2UsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdSRUNFSVZFX0VWRU5UX0VSUk9SJyxcbiAgICAgICAgICAgIHNvdXJjZUlkOiBldmVudFNvdXJjZS5zb3VyY2VJZCxcbiAgICAgICAgICAgIGZldGNoSWQsXG4gICAgICAgICAgICBmZXRjaFJhbmdlLFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGV2ZW50U291cmNlKSwgeyBpc0ZldGNoaW5nOiB0cnVlLCBsYXRlc3RGZXRjaElkOiBmZXRjaElkIH0pO1xufVxuZnVuY3Rpb24gcmVjZWl2ZVJlc3BvbnNlKHNvdXJjZUhhc2gsIHNvdXJjZUlkLCBmZXRjaElkLCBmZXRjaFJhbmdlKSB7XG4gICAgbGV0IGV2ZW50U291cmNlID0gc291cmNlSGFzaFtzb3VyY2VJZF07XG4gICAgaWYgKGV2ZW50U291cmNlICYmIC8vIG5vdCBhbHJlYWR5IHJlbW92ZWRcbiAgICAgICAgZmV0Y2hJZCA9PT0gZXZlbnRTb3VyY2UubGF0ZXN0RmV0Y2hJZCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBzb3VyY2VIYXNoKSwgeyBbc291cmNlSWRdOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGV2ZW50U291cmNlKSwgeyBpc0ZldGNoaW5nOiBmYWxzZSwgZmV0Y2hSYW5nZSB9KSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNvdXJjZUhhc2g7XG59XG5mdW5jdGlvbiBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gZmlsdGVySGFzaChldmVudFNvdXJjZXMsIChldmVudFNvdXJjZSkgPT4gZG9lc1NvdXJjZU5lZWRSYW5nZShldmVudFNvdXJjZSwgY29udGV4dCkpO1xufVxuZnVuY3Rpb24gcGFyc2VJbml0aWFsU291cmNlcyhyYXdPcHRpb25zLCBjb250ZXh0KSB7XG4gICAgbGV0IHJlZmluZXJzID0gYnVpbGRFdmVudFNvdXJjZVJlZmluZXJzKGNvbnRleHQpO1xuICAgIGxldCByYXdTb3VyY2VzID0gW10uY29uY2F0KHJhd09wdGlvbnMuZXZlbnRTb3VyY2VzIHx8IFtdKTtcbiAgICBsZXQgc291cmNlcyA9IFtdOyAvLyBwYXJzZWRcbiAgICBpZiAocmF3T3B0aW9ucy5pbml0aWFsRXZlbnRzKSB7XG4gICAgICAgIHJhd1NvdXJjZXMudW5zaGlmdChyYXdPcHRpb25zLmluaXRpYWxFdmVudHMpO1xuICAgIH1cbiAgICBpZiAocmF3T3B0aW9ucy5ldmVudHMpIHtcbiAgICAgICAgcmF3U291cmNlcy51bnNoaWZ0KHJhd09wdGlvbnMuZXZlbnRzKTtcbiAgICB9XG4gICAgZm9yIChsZXQgcmF3U291cmNlIG9mIHJhd1NvdXJjZXMpIHtcbiAgICAgICAgbGV0IHNvdXJjZSA9IHBhcnNlRXZlbnRTb3VyY2UocmF3U291cmNlLCBjb250ZXh0LCByZWZpbmVycyk7XG4gICAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VzO1xufVxuZnVuY3Rpb24gZG9lc1NvdXJjZU5lZWRSYW5nZShldmVudFNvdXJjZSwgY29udGV4dCkge1xuICAgIGxldCBkZWZzID0gY29udGV4dC5wbHVnaW5Ib29rcy5ldmVudFNvdXJjZURlZnM7XG4gICAgcmV0dXJuICFkZWZzW2V2ZW50U291cmNlLnNvdXJjZURlZklkXS5pZ25vcmVSYW5nZTtcbn1cblxuZnVuY3Rpb24gcmVkdWNlRGF0ZVNlbGVjdGlvbihjdXJyZW50U2VsZWN0aW9uLCBhY3Rpb24pIHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ1VOU0VMRUNUX0RBVEVTJzpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjYXNlICdTRUxFQ1RfREFURVMnOlxuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5zZWxlY3Rpb247XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFNlbGVjdGlvbjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZVNlbGVjdGVkRXZlbnQoY3VycmVudEluc3RhbmNlSWQsIGFjdGlvbikge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRUxFQ1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICBjYXNlICdTRUxFQ1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5ldmVudEluc3RhbmNlSWQ7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudEluc3RhbmNlSWQ7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWR1Y2VFdmVudERyYWcoY3VycmVudERyYWcsIGFjdGlvbikge1xuICAgIGxldCBuZXdEcmFnO1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRVRfRVZFTlRfRFJBRyc6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgY2FzZSAnU0VUX0VWRU5UX0RSQUcnOlxuICAgICAgICAgICAgbmV3RHJhZyA9IGFjdGlvbi5zdGF0ZTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IG5ld0RyYWcuYWZmZWN0ZWRFdmVudHMsXG4gICAgICAgICAgICAgICAgbXV0YXRlZEV2ZW50czogbmV3RHJhZy5tdXRhdGVkRXZlbnRzLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IG5ld0RyYWcuaXNFdmVudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERyYWc7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWR1Y2VFdmVudFJlc2l6ZShjdXJyZW50UmVzaXplLCBhY3Rpb24pIHtcbiAgICBsZXQgbmV3UmVzaXplO1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRVRfRVZFTlRfUkVTSVpFJzpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjYXNlICdTRVRfRVZFTlRfUkVTSVpFJzpcbiAgICAgICAgICAgIG5ld1Jlc2l6ZSA9IGFjdGlvbi5zdGF0ZTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IG5ld1Jlc2l6ZS5hZmZlY3RlZEV2ZW50cyxcbiAgICAgICAgICAgICAgICBtdXRhdGVkRXZlbnRzOiBuZXdSZXNpemUubXV0YXRlZEV2ZW50cyxcbiAgICAgICAgICAgICAgICBpc0V2ZW50OiBuZXdSZXNpemUuaXNFdmVudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFJlc2l6ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlVG9vbGJhcnMoY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpIHtcbiAgICBsZXQgaGVhZGVyID0gY2FsZW5kYXJPcHRpb25zLmhlYWRlclRvb2xiYXIgPyBwYXJzZVRvb2xiYXIoY2FsZW5kYXJPcHRpb25zLmhlYWRlclRvb2xiYXIsIGNhbGVuZGFyT3B0aW9ucywgY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSA6IG51bGw7XG4gICAgbGV0IGZvb3RlciA9IGNhbGVuZGFyT3B0aW9ucy5mb290ZXJUb29sYmFyID8gcGFyc2VUb29sYmFyKGNhbGVuZGFyT3B0aW9ucy5mb290ZXJUb29sYmFyLCBjYWxlbmRhck9wdGlvbnMsIGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLCB0aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSkgOiBudWxsO1xuICAgIHJldHVybiB7IGhlYWRlciwgZm9vdGVyIH07XG59XG5mdW5jdGlvbiBwYXJzZVRvb2xiYXIoc2VjdGlvblN0ckhhc2gsIGNhbGVuZGFyT3B0aW9ucywgY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSB7XG4gICAgbGV0IHNlY3Rpb25XaWRnZXRzID0ge307XG4gICAgbGV0IHZpZXdzV2l0aEJ1dHRvbnMgPSBbXTtcbiAgICBsZXQgaGFzVGl0bGUgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBzZWN0aW9uTmFtZSBpbiBzZWN0aW9uU3RySGFzaCkge1xuICAgICAgICBsZXQgc2VjdGlvblN0ciA9IHNlY3Rpb25TdHJIYXNoW3NlY3Rpb25OYW1lXTtcbiAgICAgICAgbGV0IHNlY3Rpb25SZXMgPSBwYXJzZVNlY3Rpb24oc2VjdGlvblN0ciwgY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpO1xuICAgICAgICBzZWN0aW9uV2lkZ2V0c1tzZWN0aW9uTmFtZV0gPSBzZWN0aW9uUmVzLndpZGdldHM7XG4gICAgICAgIHZpZXdzV2l0aEJ1dHRvbnMucHVzaCguLi5zZWN0aW9uUmVzLnZpZXdzV2l0aEJ1dHRvbnMpO1xuICAgICAgICBoYXNUaXRsZSA9IGhhc1RpdGxlIHx8IHNlY3Rpb25SZXMuaGFzVGl0bGU7XG4gICAgfVxuICAgIHJldHVybiB7IHNlY3Rpb25XaWRnZXRzLCB2aWV3c1dpdGhCdXR0b25zLCBoYXNUaXRsZSB9O1xufVxuLypcbkJBRDogcXVlcnlpbmcgaWNvbnMgYW5kIHRleHQgaGVyZS4gc2hvdWxkIGJlIGRvbmUgYXQgcmVuZGVyIHRpbWVcbiovXG5mdW5jdGlvbiBwYXJzZVNlY3Rpb24oc2VjdGlvblN0ciwgY2FsZW5kYXJPcHRpb25zLCAvLyBkZWZhdWx0cytvdmVycmlkZXMsIHRoZW4gcmVmaW5lZFxuY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIC8vIG92ZXJyaWRlcyBvbmx5ISwgdW5yZWZpbmVkIDooXG50aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSkge1xuICAgIGxldCBpc1J0bCA9IGNhbGVuZGFyT3B0aW9ucy5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIGxldCBjYWxlbmRhckN1c3RvbUJ1dHRvbnMgPSBjYWxlbmRhck9wdGlvbnMuY3VzdG9tQnV0dG9ucyB8fCB7fTtcbiAgICBsZXQgY2FsZW5kYXJCdXR0b25UZXh0T3ZlcnJpZGVzID0gY2FsZW5kYXJPcHRpb25PdmVycmlkZXMuYnV0dG9uVGV4dCB8fCB7fTtcbiAgICBsZXQgY2FsZW5kYXJCdXR0b25UZXh0ID0gY2FsZW5kYXJPcHRpb25zLmJ1dHRvblRleHQgfHwge307XG4gICAgbGV0IGNhbGVuZGFyQnV0dG9uSGludE92ZXJyaWRlcyA9IGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLmJ1dHRvbkhpbnRzIHx8IHt9O1xuICAgIGxldCBjYWxlbmRhckJ1dHRvbkhpbnRzID0gY2FsZW5kYXJPcHRpb25zLmJ1dHRvbkhpbnRzIHx8IHt9O1xuICAgIGxldCBzZWN0aW9uU3Vic3RycyA9IHNlY3Rpb25TdHIgPyBzZWN0aW9uU3RyLnNwbGl0KCcgJykgOiBbXTtcbiAgICBsZXQgdmlld3NXaXRoQnV0dG9ucyA9IFtdO1xuICAgIGxldCBoYXNUaXRsZSA9IGZhbHNlO1xuICAgIGxldCB3aWRnZXRzID0gc2VjdGlvblN1YnN0cnMubWFwKChidXR0b25Hcm91cFN0cikgPT4gKGJ1dHRvbkdyb3VwU3RyLnNwbGl0KCcsJykubWFwKChidXR0b25OYW1lKSA9PiB7XG4gICAgICAgIGlmIChidXR0b25OYW1lID09PSAndGl0bGUnKSB7XG4gICAgICAgICAgICBoYXNUaXRsZSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4geyBidXR0b25OYW1lIH07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1c3RvbUJ1dHRvblByb3BzO1xuICAgICAgICBsZXQgdmlld1NwZWM7XG4gICAgICAgIGxldCBidXR0b25DbGljaztcbiAgICAgICAgbGV0IGJ1dHRvbkljb247IC8vIG9ubHkgb25lIG9mIHRoZXNlIHdpbGwgYmUgc2V0XG4gICAgICAgIGxldCBidXR0b25UZXh0OyAvLyBcIlxuICAgICAgICBsZXQgYnV0dG9uSGludDtcbiAgICAgICAgLy8gXiBmb3IgdGhlIHRpdGxlPVwiXCIgYXR0cmlidXRlLCBmb3IgYWNjZXNzaWJpbGl0eVxuICAgICAgICBpZiAoKGN1c3RvbUJ1dHRvblByb3BzID0gY2FsZW5kYXJDdXN0b21CdXR0b25zW2J1dHRvbk5hbWVdKSkge1xuICAgICAgICAgICAgYnV0dG9uQ2xpY2sgPSAoZXYpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY3VzdG9tQnV0dG9uUHJvcHMuY2xpY2spIHtcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tQnV0dG9uUHJvcHMuY2xpY2suY2FsbChldi50YXJnZXQsIGV2LCBldi50YXJnZXQpOyAvLyBUT0RPOiB1c2UgQ2FsZW5kYXIgdGhpcyBjb250ZXh0P1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEN1c3RvbUJ1dHRvbkljb25DbGFzcyhjdXN0b21CdXR0b25Qcm9wcykpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvbkljb24gPSB0aGVtZS5nZXRJY29uQ2xhc3MoYnV0dG9uTmFtZSwgaXNSdGwpKSB8fFxuICAgICAgICAgICAgICAgIChidXR0b25UZXh0ID0gY3VzdG9tQnV0dG9uUHJvcHMudGV4dCk7XG4gICAgICAgICAgICBidXR0b25IaW50ID0gY3VzdG9tQnV0dG9uUHJvcHMuaGludCB8fCBjdXN0b21CdXR0b25Qcm9wcy50ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCh2aWV3U3BlYyA9IHZpZXdTcGVjc1tidXR0b25OYW1lXSkpIHtcbiAgICAgICAgICAgIHZpZXdzV2l0aEJ1dHRvbnMucHVzaChidXR0b25OYW1lKTtcbiAgICAgICAgICAgIGJ1dHRvbkNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGVuZGFyQXBpLmNoYW5nZVZpZXcoYnV0dG9uTmFtZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgKGJ1dHRvblRleHQgPSB2aWV3U3BlYy5idXR0b25UZXh0T3ZlcnJpZGUpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvbkljb24gPSB0aGVtZS5nZXRJY29uQ2xhc3MoYnV0dG9uTmFtZSwgaXNSdGwpKSB8fFxuICAgICAgICAgICAgICAgIChidXR0b25UZXh0ID0gdmlld1NwZWMuYnV0dG9uVGV4dERlZmF1bHQpO1xuICAgICAgICAgICAgbGV0IHRleHRGYWxsYmFjayA9IHZpZXdTcGVjLmJ1dHRvblRleHRPdmVycmlkZSB8fFxuICAgICAgICAgICAgICAgIHZpZXdTcGVjLmJ1dHRvblRleHREZWZhdWx0O1xuICAgICAgICAgICAgYnV0dG9uSGludCA9IGZvcm1hdFdpdGhPcmRpbmFscyh2aWV3U3BlYy5idXR0b25UaXRsZU92ZXJyaWRlIHx8XG4gICAgICAgICAgICAgICAgdmlld1NwZWMuYnV0dG9uVGl0bGVEZWZhdWx0IHx8XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJPcHRpb25zLnZpZXdIaW50LCBbdGV4dEZhbGxiYWNrLCBidXR0b25OYW1lXSwgLy8gdmlldy1uYW1lID0gYnV0dG9uTmFtZVxuICAgICAgICAgICAgdGV4dEZhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjYWxlbmRhckFwaVtidXR0b25OYW1lXSkgeyAvLyBhIGNhbGVuZGFyQXBpIG1ldGhvZFxuICAgICAgICAgICAgYnV0dG9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJBcGlbYnV0dG9uTmFtZV0oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoYnV0dG9uVGV4dCA9IGNhbGVuZGFyQnV0dG9uVGV4dE92ZXJyaWRlc1tidXR0b25OYW1lXSkgfHxcbiAgICAgICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEljb25DbGFzcyhidXR0b25OYW1lLCBpc1J0bCkpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvblRleHQgPSBjYWxlbmRhckJ1dHRvblRleHRbYnV0dG9uTmFtZV0pOyAvLyBldmVyeXRoaW5nIGVsc2UgaXMgY29uc2lkZXJlZCBkZWZhdWx0XG4gICAgICAgICAgICBpZiAoYnV0dG9uTmFtZSA9PT0gJ3ByZXZZZWFyJyB8fCBidXR0b25OYW1lID09PSAnbmV4dFllYXInKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByZXZPck5leHQgPSBidXR0b25OYW1lID09PSAncHJldlllYXInID8gJ3ByZXYnIDogJ25leHQnO1xuICAgICAgICAgICAgICAgIGJ1dHRvbkhpbnQgPSBmb3JtYXRXaXRoT3JkaW5hbHMoY2FsZW5kYXJCdXR0b25IaW50T3ZlcnJpZGVzW3ByZXZPck5leHRdIHx8XG4gICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyQnV0dG9uSGludHNbcHJldk9yTmV4dF0sIFtcbiAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXJCdXR0b25UZXh0LnllYXIgfHwgJ3llYXInLFxuICAgICAgICAgICAgICAgICAgICAneWVhcicsXG4gICAgICAgICAgICAgICAgXSwgY2FsZW5kYXJCdXR0b25UZXh0W2J1dHRvbk5hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1dHRvbkhpbnQgPSAobmF2VW5pdCkgPT4gZm9ybWF0V2l0aE9yZGluYWxzKGNhbGVuZGFyQnV0dG9uSGludE92ZXJyaWRlc1tidXR0b25OYW1lXSB8fFxuICAgICAgICAgICAgICAgICAgICBjYWxlbmRhckJ1dHRvbkhpbnRzW2J1dHRvbk5hbWVdLCBbXG4gICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyQnV0dG9uVGV4dFtuYXZVbml0XSB8fCBuYXZVbml0LFxuICAgICAgICAgICAgICAgICAgICBuYXZVbml0LFxuICAgICAgICAgICAgICAgIF0sIGNhbGVuZGFyQnV0dG9uVGV4dFtidXR0b25OYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgYnV0dG9uTmFtZSwgYnV0dG9uQ2xpY2ssIGJ1dHRvbkljb24sIGJ1dHRvblRleHQsIGJ1dHRvbkhpbnQgfTtcbiAgICB9KSkpO1xuICAgIHJldHVybiB7IHdpZGdldHMsIHZpZXdzV2l0aEJ1dHRvbnMsIGhhc1RpdGxlIH07XG59XG5cbi8vIGFsd2F5cyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXcuIG90aGVyd2lzZSwgaXQnZCBuZWVkIHRvIGNoYW5nZSB2YWx1ZSBldmVyeSB0aW1lIGRhdGUgY2hhbmdlc1xuY2xhc3MgVmlld0ltcGwge1xuICAgIGNvbnN0cnVjdG9yKHR5cGUsIGdldEN1cnJlbnREYXRhLCBkYXRlRW52KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudERhdGEgPSBnZXRDdXJyZW50RGF0YTtcbiAgICAgICAgdGhpcy5kYXRlRW52ID0gZGF0ZUVudjtcbiAgICB9XG4gICAgZ2V0IGNhbGVuZGFyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50RGF0YSgpLmNhbGVuZGFyQXBpO1xuICAgIH1cbiAgICBnZXQgdGl0bGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnREYXRhKCkudmlld1RpdGxlO1xuICAgIH1cbiAgICBnZXQgYWN0aXZlU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5hY3RpdmVSYW5nZS5zdGFydCk7XG4gICAgfVxuICAgIGdldCBhY3RpdmVFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5hY3RpdmVSYW5nZS5lbmQpO1xuICAgIH1cbiAgICBnZXQgY3VycmVudFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlRW52LnRvRGF0ZSh0aGlzLmdldEN1cnJlbnREYXRhKCkuZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0KTtcbiAgICB9XG4gICAgZ2V0IGN1cnJlbnRFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UuZW5kKTtcbiAgICB9XG4gICAgZ2V0T3B0aW9uKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q3VycmVudERhdGEoKS5vcHRpb25zW25hbWVdOyAvLyBhcmUgdGhlIHZpZXctc3BlY2lmaWMgb3B0aW9uc1xuICAgIH1cbn1cblxubGV0IGV2ZW50U291cmNlRGVmJDIgPSB7XG4gICAgaWdub3JlUmFuZ2U6IHRydWUsXG4gICAgcGFyc2VNZXRhKHJlZmluZWQpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVmaW5lZC5ldmVudHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVmaW5lZC5ldmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBmZXRjaChhcmcsIHN1Y2Nlc3NDYWxsYmFjaykge1xuICAgICAgICBzdWNjZXNzQ2FsbGJhY2soe1xuICAgICAgICAgICAgcmF3RXZlbnRzOiBhcmcuZXZlbnRTb3VyY2UubWV0YSxcbiAgICAgICAgfSk7XG4gICAgfSxcbn07XG5jb25zdCBhcnJheUV2ZW50U291cmNlUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnYXJyYXktZXZlbnQtc291cmNlJyxcbiAgICBldmVudFNvdXJjZURlZnM6IFtldmVudFNvdXJjZURlZiQyXSxcbn0pO1xuXG5sZXQgZXZlbnRTb3VyY2VEZWYkMSA9IHtcbiAgICBwYXJzZU1ldGEocmVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIHJlZmluZWQuZXZlbnRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVmaW5lZC5ldmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBmZXRjaChhcmcsIHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaykge1xuICAgICAgICBjb25zdCB7IGRhdGVFbnYgfSA9IGFyZy5jb250ZXh0O1xuICAgICAgICBjb25zdCBmdW5jID0gYXJnLmV2ZW50U291cmNlLm1ldGE7XG4gICAgICAgIHVucHJvbWlzaWZ5KGZ1bmMuYmluZChudWxsLCBidWlsZFJhbmdlQXBpV2l0aFRpbWVab25lKGFyZy5yYW5nZSwgZGF0ZUVudikpLCAocmF3RXZlbnRzKSA9PiBzdWNjZXNzQ2FsbGJhY2soeyByYXdFdmVudHMgfSksIGVycm9yQ2FsbGJhY2spO1xuICAgIH0sXG59O1xuY29uc3QgZnVuY0V2ZW50U291cmNlUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnZnVuYy1ldmVudC1zb3VyY2UnLFxuICAgIGV2ZW50U291cmNlRGVmczogW2V2ZW50U291cmNlRGVmJDFdLFxufSk7XG5cbmNvbnN0IEpTT05fRkVFRF9FVkVOVF9TT1VSQ0VfUkVGSU5FUlMgPSB7XG4gICAgbWV0aG9kOiBTdHJpbmcsXG4gICAgZXh0cmFQYXJhbXM6IGlkZW50aXR5LFxuICAgIHN0YXJ0UGFyYW06IFN0cmluZyxcbiAgICBlbmRQYXJhbTogU3RyaW5nLFxuICAgIHRpbWVab25lUGFyYW06IFN0cmluZyxcbn07XG5cbmxldCBldmVudFNvdXJjZURlZiA9IHtcbiAgICBwYXJzZU1ldGEocmVmaW5lZCkge1xuICAgICAgICBpZiAocmVmaW5lZC51cmwgJiYgKHJlZmluZWQuZm9ybWF0ID09PSAnanNvbicgfHwgIXJlZmluZWQuZm9ybWF0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB1cmw6IHJlZmluZWQudXJsLFxuICAgICAgICAgICAgICAgIGZvcm1hdDogJ2pzb24nLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogKHJlZmluZWQubWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICAgICAgICAgIGV4dHJhUGFyYW1zOiByZWZpbmVkLmV4dHJhUGFyYW1zLFxuICAgICAgICAgICAgICAgIHN0YXJ0UGFyYW06IHJlZmluZWQuc3RhcnRQYXJhbSxcbiAgICAgICAgICAgICAgICBlbmRQYXJhbTogcmVmaW5lZC5lbmRQYXJhbSxcbiAgICAgICAgICAgICAgICB0aW1lWm9uZVBhcmFtOiByZWZpbmVkLnRpbWVab25lUGFyYW0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgZmV0Y2goYXJnLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgeyBtZXRhIH0gPSBhcmcuZXZlbnRTb3VyY2U7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RQYXJhbXMgPSBidWlsZFJlcXVlc3RQYXJhbXMobWV0YSwgYXJnLnJhbmdlLCBhcmcuY29udGV4dCk7XG4gICAgICAgIHJlcXVlc3RKc29uKG1ldGEubWV0aG9kLCBtZXRhLnVybCwgcmVxdWVzdFBhcmFtcykudGhlbigoW3Jhd0V2ZW50cywgcmVzcG9uc2VdKSA9PiB7XG4gICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soeyByYXdFdmVudHMsIHJlc3BvbnNlIH0pO1xuICAgICAgICB9LCBlcnJvckNhbGxiYWNrKTtcbiAgICB9LFxufTtcbmNvbnN0IGpzb25GZWVkRXZlbnRTb3VyY2VQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdqc29uLWV2ZW50LXNvdXJjZScsXG4gICAgZXZlbnRTb3VyY2VSZWZpbmVyczogSlNPTl9GRUVEX0VWRU5UX1NPVVJDRV9SRUZJTkVSUyxcbiAgICBldmVudFNvdXJjZURlZnM6IFtldmVudFNvdXJjZURlZl0sXG59KTtcbmZ1bmN0aW9uIGJ1aWxkUmVxdWVzdFBhcmFtcyhtZXRhLCByYW5nZSwgY29udGV4dCkge1xuICAgIGxldCB7IGRhdGVFbnYsIG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgbGV0IHN0YXJ0UGFyYW07XG4gICAgbGV0IGVuZFBhcmFtO1xuICAgIGxldCB0aW1lWm9uZVBhcmFtO1xuICAgIGxldCBjdXN0b21SZXF1ZXN0UGFyYW1zO1xuICAgIGxldCBwYXJhbXMgPSB7fTtcbiAgICBzdGFydFBhcmFtID0gbWV0YS5zdGFydFBhcmFtO1xuICAgIGlmIChzdGFydFBhcmFtID09IG51bGwpIHtcbiAgICAgICAgc3RhcnRQYXJhbSA9IG9wdGlvbnMuc3RhcnRQYXJhbTtcbiAgICB9XG4gICAgZW5kUGFyYW0gPSBtZXRhLmVuZFBhcmFtO1xuICAgIGlmIChlbmRQYXJhbSA9PSBudWxsKSB7XG4gICAgICAgIGVuZFBhcmFtID0gb3B0aW9ucy5lbmRQYXJhbTtcbiAgICB9XG4gICAgdGltZVpvbmVQYXJhbSA9IG1ldGEudGltZVpvbmVQYXJhbTtcbiAgICBpZiAodGltZVpvbmVQYXJhbSA9PSBudWxsKSB7XG4gICAgICAgIHRpbWVab25lUGFyYW0gPSBvcHRpb25zLnRpbWVab25lUGFyYW07XG4gICAgfVxuICAgIC8vIHJldHJpZXZlIGFueSBvdXRib3VuZCBHRVQvUE9TVCBkYXRhIGZyb20gdGhlIG9wdGlvbnNcbiAgICBpZiAodHlwZW9mIG1ldGEuZXh0cmFQYXJhbXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gc3VwcGxpZWQgYXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBrZXkvdmFsdWUgb2JqZWN0XG4gICAgICAgIGN1c3RvbVJlcXVlc3RQYXJhbXMgPSBtZXRhLmV4dHJhUGFyYW1zKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBwcm9iYWJseSBzdXBwbGllZCBhcyBhIHN0cmFpZ2h0IGtleS92YWx1ZSBvYmplY3RcbiAgICAgICAgY3VzdG9tUmVxdWVzdFBhcmFtcyA9IG1ldGEuZXh0cmFQYXJhbXMgfHwge307XG4gICAgfVxuICAgIE9iamVjdC5hc3NpZ24ocGFyYW1zLCBjdXN0b21SZXF1ZXN0UGFyYW1zKTtcbiAgICBwYXJhbXNbc3RhcnRQYXJhbV0gPSBkYXRlRW52LmZvcm1hdElzbyhyYW5nZS5zdGFydCk7XG4gICAgcGFyYW1zW2VuZFBhcmFtXSA9IGRhdGVFbnYuZm9ybWF0SXNvKHJhbmdlLmVuZCk7XG4gICAgaWYgKGRhdGVFbnYudGltZVpvbmUgIT09ICdsb2NhbCcpIHtcbiAgICAgICAgcGFyYW1zW3RpbWVab25lUGFyYW1dID0gZGF0ZUVudi50aW1lWm9uZTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtcztcbn1cblxuY29uc3QgU0lNUExFX1JFQ1VSUklOR19SRUZJTkVSUyA9IHtcbiAgICBkYXlzT2ZXZWVrOiBpZGVudGl0eSxcbiAgICBzdGFydFRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGVuZFRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGR1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBzdGFydFJlY3VyOiBpZGVudGl0eSxcbiAgICBlbmRSZWN1cjogaWRlbnRpdHksXG59O1xuXG5sZXQgcmVjdXJyaW5nID0ge1xuICAgIHBhcnNlKHJlZmluZWQsIGRhdGVFbnYpIHtcbiAgICAgICAgaWYgKHJlZmluZWQuZGF5c09mV2VlayB8fCByZWZpbmVkLnN0YXJ0VGltZSB8fCByZWZpbmVkLmVuZFRpbWUgfHwgcmVmaW5lZC5zdGFydFJlY3VyIHx8IHJlZmluZWQuZW5kUmVjdXIpIHtcbiAgICAgICAgICAgIGxldCByZWN1cnJpbmdEYXRhID0ge1xuICAgICAgICAgICAgICAgIGRheXNPZldlZWs6IHJlZmluZWQuZGF5c09mV2VlayB8fCBudWxsLFxuICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogcmVmaW5lZC5zdGFydFRpbWUgfHwgbnVsbCxcbiAgICAgICAgICAgICAgICBlbmRUaW1lOiByZWZpbmVkLmVuZFRpbWUgfHwgbnVsbCxcbiAgICAgICAgICAgICAgICBzdGFydFJlY3VyOiByZWZpbmVkLnN0YXJ0UmVjdXIgPyBkYXRlRW52LmNyZWF0ZU1hcmtlcihyZWZpbmVkLnN0YXJ0UmVjdXIpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBlbmRSZWN1cjogcmVmaW5lZC5lbmRSZWN1ciA/IGRhdGVFbnYuY3JlYXRlTWFya2VyKHJlZmluZWQuZW5kUmVjdXIpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBkYXRlRW52LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgIGlmIChyZWZpbmVkLmR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb24gPSByZWZpbmVkLmR1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFkdXJhdGlvbiAmJiByZWZpbmVkLnN0YXJ0VGltZSAmJiByZWZpbmVkLmVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHN1YnRyYWN0RHVyYXRpb25zKHJlZmluZWQuZW5kVGltZSwgcmVmaW5lZC5zdGFydFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBhbGxEYXlHdWVzczogQm9vbGVhbighcmVmaW5lZC5zdGFydFRpbWUgJiYgIXJlZmluZWQuZW5kVGltZSksXG4gICAgICAgICAgICAgICAgZHVyYXRpb24sXG4gICAgICAgICAgICAgICAgdHlwZURhdGE6IHJlY3VycmluZ0RhdGEsIC8vIGRvZXNuJ3QgbmVlZCBlbmRUaW1lIGFueW1vcmUgYnV0IG9oIHdlbGxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBleHBhbmQodHlwZURhdGEsIGZyYW1pbmdSYW5nZSwgZGF0ZUVudikge1xuICAgICAgICBsZXQgY2xpcHBlZEZyYW1pbmdSYW5nZSA9IGludGVyc2VjdFJhbmdlcyhmcmFtaW5nUmFuZ2UsIHsgc3RhcnQ6IHR5cGVEYXRhLnN0YXJ0UmVjdXIsIGVuZDogdHlwZURhdGEuZW5kUmVjdXIgfSk7XG4gICAgICAgIGlmIChjbGlwcGVkRnJhbWluZ1JhbmdlKSB7XG4gICAgICAgICAgICByZXR1cm4gZXhwYW5kUmFuZ2VzKHR5cGVEYXRhLmRheXNPZldlZWssIHR5cGVEYXRhLnN0YXJ0VGltZSwgdHlwZURhdGEuZGF0ZUVudiwgZGF0ZUVudiwgY2xpcHBlZEZyYW1pbmdSYW5nZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH0sXG59O1xuY29uc3Qgc2ltcGxlUmVjdXJyaW5nRXZlbnRzUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnc2ltcGxlLXJlY3VycmluZy1ldmVudCcsXG4gICAgcmVjdXJyaW5nVHlwZXM6IFtyZWN1cnJpbmddLFxuICAgIGV2ZW50UmVmaW5lcnM6IFNJTVBMRV9SRUNVUlJJTkdfUkVGSU5FUlMsXG59KTtcbmZ1bmN0aW9uIGV4cGFuZFJhbmdlcyhkYXlzT2ZXZWVrLCBzdGFydFRpbWUsIGV2ZW50RGF0ZUVudiwgY2FsZW5kYXJEYXRlRW52LCBmcmFtaW5nUmFuZ2UpIHtcbiAgICBsZXQgZG93SGFzaCA9IGRheXNPZldlZWsgPyBhcnJheVRvSGFzaChkYXlzT2ZXZWVrKSA6IG51bGw7XG4gICAgbGV0IGRheU1hcmtlciA9IHN0YXJ0T2ZEYXkoZnJhbWluZ1JhbmdlLnN0YXJ0KTtcbiAgICBsZXQgZW5kTWFya2VyID0gZnJhbWluZ1JhbmdlLmVuZDtcbiAgICBsZXQgaW5zdGFuY2VTdGFydHMgPSBbXTtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZnVsbGNhbGVuZGFyL2Z1bGxjYWxlbmRhci9pc3N1ZXMvNzkzNFxuICAgIGlmIChzdGFydFRpbWUpIHtcbiAgICAgICAgaWYgKHN0YXJ0VGltZS5taWxsaXNlY29uZHMgPCAwKSB7XG4gICAgICAgICAgICAvLyBwb3NzaWJsZSBmb3IgbmV4dC1kYXkgdG8gaGF2ZSBuZWdhdGl2ZSBidXNpbmVzcyBob3VycyB0aGF0IGdvIGludG8gY3VycmVudCBkYXlcbiAgICAgICAgICAgIGVuZE1hcmtlciA9IGFkZERheXMoZW5kTWFya2VyLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzdGFydFRpbWUubWlsbGlzZWNvbmRzID49IDEwMDAgKiA2MCAqIDYwICogMjQpIHtcbiAgICAgICAgICAgIC8vIHBvc3NpYmxlIGZvciBwcmV2LWRheSB0byBoYXZlID4yNGhyIGJ1c2luZXNzIGhvdXJzIHRoYXQgZ28gaW50byBjdXJyZW50IGRheVxuICAgICAgICAgICAgZGF5TWFya2VyID0gYWRkRGF5cyhkYXlNYXJrZXIsIC0xKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoZGF5TWFya2VyIDwgZW5kTWFya2VyKSB7XG4gICAgICAgIGxldCBpbnN0YW5jZVN0YXJ0O1xuICAgICAgICAvLyBpZiBldmVyeWRheSwgb3IgdGhpcyBwYXJ0aWN1bGFyIGRheS1vZi13ZWVrXG4gICAgICAgIGlmICghZG93SGFzaCB8fCBkb3dIYXNoW2RheU1hcmtlci5nZXRVVENEYXkoKV0pIHtcbiAgICAgICAgICAgIGlmIChzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZVN0YXJ0ID0gY2FsZW5kYXJEYXRlRW52LmFkZChkYXlNYXJrZXIsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZVN0YXJ0ID0gZGF5TWFya2VyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5zdGFuY2VTdGFydHMucHVzaChjYWxlbmRhckRhdGVFbnYuY3JlYXRlTWFya2VyKGV2ZW50RGF0ZUVudi50b0RhdGUoaW5zdGFuY2VTdGFydCkpKTtcbiAgICAgICAgfVxuICAgICAgICBkYXlNYXJrZXIgPSBhZGREYXlzKGRheU1hcmtlciwgMSk7XG4gICAgfVxuICAgIHJldHVybiBpbnN0YW5jZVN0YXJ0cztcbn1cblxuY29uc3QgY2hhbmdlSGFuZGxlclBsdWdpbiA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ2NoYW5nZS1oYW5kbGVyJyxcbiAgICBvcHRpb25DaGFuZ2VIYW5kbGVyczoge1xuICAgICAgICBldmVudHMoZXZlbnRzLCBjb250ZXh0KSB7XG4gICAgICAgICAgICBoYW5kbGVFdmVudFNvdXJjZXMoW2V2ZW50c10sIGNvbnRleHQpO1xuICAgICAgICB9LFxuICAgICAgICBldmVudFNvdXJjZXM6IGhhbmRsZUV2ZW50U291cmNlcyxcbiAgICB9LFxufSk7XG4vKlxuQlVHOiBpZiBgZXZlbnRgIHdhcyBzdXBwbGllZCwgYWxsIHByZXZpb3VzbHktZ2l2ZW4gYGV2ZW50U291cmNlc2Agd2lsbCBiZSB3aXBlZCBvdXRcbiovXG5mdW5jdGlvbiBoYW5kbGVFdmVudFNvdXJjZXMoaW5wdXRzLCBjb250ZXh0KSB7XG4gICAgbGV0IHVuZm91bmRTb3VyY2VzID0gaGFzaFZhbHVlc1RvQXJyYXkoY29udGV4dC5nZXRDdXJyZW50RGF0YSgpLmV2ZW50U291cmNlcyk7XG4gICAgaWYgKHVuZm91bmRTb3VyY2VzLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICBpbnB1dHMubGVuZ3RoID09PSAxICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkodW5mb3VuZFNvdXJjZXNbMF0uX3JhdykgJiZcbiAgICAgICAgQXJyYXkuaXNBcnJheShpbnB1dHNbMF0pKSB7XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFU0VUX1JBV19FVkVOVFMnLFxuICAgICAgICAgICAgc291cmNlSWQ6IHVuZm91bmRTb3VyY2VzWzBdLnNvdXJjZUlkLFxuICAgICAgICAgICAgcmF3RXZlbnRzOiBpbnB1dHNbMF0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBuZXdJbnB1dHMgPSBbXTtcbiAgICBmb3IgKGxldCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAgICAgbGV0IGlucHV0Rm91bmQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1bmZvdW5kU291cmNlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKHVuZm91bmRTb3VyY2VzW2ldLl9yYXcgPT09IGlucHV0KSB7XG4gICAgICAgICAgICAgICAgdW5mb3VuZFNvdXJjZXMuc3BsaWNlKGksIDEpOyAvLyBkZWxldGVcbiAgICAgICAgICAgICAgICBpbnB1dEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlucHV0Rm91bmQpIHtcbiAgICAgICAgICAgIG5ld0lucHV0cy5wdXNoKGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCB1bmZvdW5kU291cmNlIG9mIHVuZm91bmRTb3VyY2VzKSB7XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFTU9WRV9FVkVOVF9TT1VSQ0UnLFxuICAgICAgICAgICAgc291cmNlSWQ6IHVuZm91bmRTb3VyY2Uuc291cmNlSWQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmb3IgKGxldCBuZXdJbnB1dCBvZiBuZXdJbnB1dHMpIHtcbiAgICAgICAgY29udGV4dC5jYWxlbmRhckFwaS5hZGRFdmVudFNvdXJjZShuZXdJbnB1dCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVEYXRlUHJvZmlsZShkYXRlUHJvZmlsZSwgY29udGV4dCkge1xuICAgIGNvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdkYXRlc1NldCcsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYnVpbGRSYW5nZUFwaVdpdGhUaW1lWm9uZShkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSwgY29udGV4dC5kYXRlRW52KSksIHsgdmlldzogY29udGV4dC52aWV3QXBpIH0pKTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlRXZlbnRTdG9yZShldmVudFN0b3JlLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgZW1pdHRlciB9ID0gY29udGV4dDtcbiAgICBpZiAoZW1pdHRlci5oYXNIYW5kbGVycygnZXZlbnRzU2V0JykpIHtcbiAgICAgICAgZW1pdHRlci50cmlnZ2VyKCdldmVudHNTZXQnLCBidWlsZEV2ZW50QXBpcyhldmVudFN0b3JlLCBjb250ZXh0KSk7XG4gICAgfVxufVxuXG4vKlxudGhpcyBhcnJheSBpcyBleHBvc2VkIG9uIHRoZSByb290IG5hbWVzcGFjZSBzbyB0aGF0IFVNRCBwbHVnaW5zIGNhbiBhZGQgdG8gaXQuXG5zZWUgdGhlIHJvbGx1cC1idW5kbGVzIHNjcmlwdC5cbiovXG5jb25zdCBnbG9iYWxQbHVnaW5zID0gW1xuICAgIGFycmF5RXZlbnRTb3VyY2VQbHVnaW4sXG4gICAgZnVuY0V2ZW50U291cmNlUGx1Z2luLFxuICAgIGpzb25GZWVkRXZlbnRTb3VyY2VQbHVnaW4sXG4gICAgc2ltcGxlUmVjdXJyaW5nRXZlbnRzUGx1Z2luLFxuICAgIGNoYW5nZUhhbmRsZXJQbHVnaW4sXG4gICAgY3JlYXRlUGx1Z2luKHtcbiAgICAgICAgbmFtZTogJ21pc2MnLFxuICAgICAgICBpc0xvYWRpbmdGdW5jczogW1xuICAgICAgICAgICAgKHN0YXRlKSA9PiBjb21wdXRlRXZlbnRTb3VyY2VzTG9hZGluZyhzdGF0ZS5ldmVudFNvdXJjZXMpLFxuICAgICAgICBdLFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IHtcbiAgICAgICAgICAgIGRhdGVQcm9maWxlOiBoYW5kbGVEYXRlUHJvZmlsZSxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IGhhbmRsZUV2ZW50U3RvcmUsXG4gICAgICAgIH0sXG4gICAgfSksXG5dO1xuXG5jbGFzcyBUYXNrUnVubmVyIHtcbiAgICBjb25zdHJ1Y3RvcihydW5UYXNrT3B0aW9uLCBkcmFpbmVkT3B0aW9uKSB7XG4gICAgICAgIHRoaXMucnVuVGFza09wdGlvbiA9IHJ1blRhc2tPcHRpb247XG4gICAgICAgIHRoaXMuZHJhaW5lZE9wdGlvbiA9IGRyYWluZWRPcHRpb247XG4gICAgICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5kZWxheWVkUnVubmVyID0gbmV3IERlbGF5ZWRSdW5uZXIodGhpcy5kcmFpbi5iaW5kKHRoaXMpKTtcbiAgICB9XG4gICAgcmVxdWVzdCh0YXNrLCBkZWxheSkge1xuICAgICAgICB0aGlzLnF1ZXVlLnB1c2godGFzayk7XG4gICAgICAgIHRoaXMuZGVsYXllZFJ1bm5lci5yZXF1ZXN0KGRlbGF5KTtcbiAgICB9XG4gICAgcGF1c2Uoc2NvcGUpIHtcbiAgICAgICAgdGhpcy5kZWxheWVkUnVubmVyLnBhdXNlKHNjb3BlKTtcbiAgICB9XG4gICAgcmVzdW1lKHNjb3BlLCBmb3JjZSkge1xuICAgICAgICB0aGlzLmRlbGF5ZWRSdW5uZXIucmVzdW1lKHNjb3BlLCBmb3JjZSk7XG4gICAgfVxuICAgIGRyYWluKCkge1xuICAgICAgICBsZXQgeyBxdWV1ZSB9ID0gdGhpcztcbiAgICAgICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGNvbXBsZXRlZFRhc2tzID0gW107XG4gICAgICAgICAgICBsZXQgdGFzaztcbiAgICAgICAgICAgIHdoaWxlICgodGFzayA9IHF1ZXVlLnNoaWZ0KCkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW5UYXNrKHRhc2spO1xuICAgICAgICAgICAgICAgIGNvbXBsZXRlZFRhc2tzLnB1c2godGFzayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRyYWluZWQoY29tcGxldGVkVGFza3MpO1xuICAgICAgICB9IC8vIGtlZXAgZ29pbmcsIGluIGNhc2UgbmV3IHRhc2tzIHdlcmUgYWRkZWQgaW4gdGhlIGRyYWluZWQgaGFuZGxlclxuICAgIH1cbiAgICBydW5UYXNrKHRhc2spIHtcbiAgICAgICAgaWYgKHRoaXMucnVuVGFza09wdGlvbikge1xuICAgICAgICAgICAgdGhpcy5ydW5UYXNrT3B0aW9uKHRhc2spO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRyYWluZWQoY29tcGxldGVkVGFza3MpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJhaW5lZE9wdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kcmFpbmVkT3B0aW9uKGNvbXBsZXRlZFRhc2tzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gQ29tcHV0ZXMgd2hhdCB0aGUgdGl0bGUgYXQgdGhlIHRvcCBvZiB0aGUgY2FsZW5kYXJBcGkgc2hvdWxkIGJlIGZvciB0aGlzIHZpZXdcbmZ1bmN0aW9uIGJ1aWxkVGl0bGUoZGF0ZVByb2ZpbGUsIHZpZXdPcHRpb25zLCBkYXRlRW52KSB7XG4gICAgbGV0IHJhbmdlO1xuICAgIC8vIGZvciB2aWV3cyB0aGF0IHNwYW4gYSBsYXJnZSB1bml0IG9mIHRpbWUsIHNob3cgdGhlIHByb3BlciBpbnRlcnZhbCwgaWdub3Jpbmcgc3RyYXkgZGF5cyBiZWZvcmUgYW5kIGFmdGVyXG4gICAgaWYgKC9eKHllYXJ8bW9udGgpJC8udGVzdChkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2VVbml0KSkge1xuICAgICAgICByYW5nZSA9IGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZTtcbiAgICB9XG4gICAgZWxzZSB7IC8vIGZvciBkYXkgdW5pdHMgb3Igc21hbGxlciwgdXNlIHRoZSBhY3R1YWwgZGF5IHJhbmdlXG4gICAgICAgIHJhbmdlID0gZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2U7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRW52LmZvcm1hdFJhbmdlKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQsIGNyZWF0ZUZvcm1hdHRlcih2aWV3T3B0aW9ucy50aXRsZUZvcm1hdCB8fCBidWlsZFRpdGxlRm9ybWF0KGRhdGVQcm9maWxlKSksIHtcbiAgICAgICAgaXNFbmRFeGNsdXNpdmU6IGRhdGVQcm9maWxlLmlzUmFuZ2VBbGxEYXksXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3I6IHZpZXdPcHRpb25zLnRpdGxlUmFuZ2VTZXBhcmF0b3IsXG4gICAgfSk7XG59XG4vLyBHZW5lcmF0ZXMgdGhlIGZvcm1hdCBzdHJpbmcgdGhhdCBzaG91bGQgYmUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgdGl0bGUgZm9yIHRoZSBjdXJyZW50IGRhdGUgcmFuZ2UuXG4vLyBBdHRlbXB0cyB0byBjb21wdXRlIHRoZSBtb3N0IGFwcHJvcHJpYXRlIGZvcm1hdCBpZiBub3QgZXhwbGljaXRseSBzcGVjaWZpZWQgd2l0aCBgdGl0bGVGb3JtYXRgLlxuZnVuY3Rpb24gYnVpbGRUaXRsZUZvcm1hdChkYXRlUHJvZmlsZSkge1xuICAgIGxldCB7IGN1cnJlbnRSYW5nZVVuaXQgfSA9IGRhdGVQcm9maWxlO1xuICAgIGlmIChjdXJyZW50UmFuZ2VVbml0ID09PSAneWVhcicpIHtcbiAgICAgICAgcmV0dXJuIHsgeWVhcjogJ251bWVyaWMnIH07XG4gICAgfVxuICAgIGlmIChjdXJyZW50UmFuZ2VVbml0ID09PSAnbW9udGgnKSB7XG4gICAgICAgIHJldHVybiB7IHllYXI6ICdudW1lcmljJywgbW9udGg6ICdsb25nJyB9OyAvLyBsaWtlIFwiU2VwdGVtYmVyIDIwMTRcIlxuICAgIH1cbiAgICBsZXQgZGF5cyA9IGRpZmZXaG9sZURheXMoZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0LCBkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UuZW5kKTtcbiAgICBpZiAoZGF5cyAhPT0gbnVsbCAmJiBkYXlzID4gMSkge1xuICAgICAgICAvLyBtdWx0aS1kYXkgcmFuZ2UuIHNob3J0ZXIsIGxpa2UgXCJTZXAgOSAtIDEwIDIwMTRcIlxuICAgICAgICByZXR1cm4geyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnc2hvcnQnLCBkYXk6ICdudW1lcmljJyB9O1xuICAgIH1cbiAgICAvLyBvbmUgZGF5LiBsb25nZXIsIGxpa2UgXCJTZXB0ZW1iZXIgOSAyMDE0XCJcbiAgICByZXR1cm4geyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnbG9uZycsIGRheTogJ251bWVyaWMnIH07XG59XG5cbi8qXG5UT0RPOiB0ZXN0IHN3aXRjaGluZyB0aW1lem9uZXMgd2hlbiBOTyB0aW1lem9uZSBwbHVnaW5cbiovXG5jbGFzcyBDYWxlbmRhck5vd01hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnJlc2V0TGlzdGVuZXJzID0gbmV3IFNldCgpO1xuICAgIH1cbiAgICBoYW5kbGVJbnB1dChkYXRlRW52LCAvLyB3aWxsIGNoYW5nZSBpZiB0aW1lem9uZSBzZXR1cCBjaGFuZ2VkXG4gICAgbm93SW5wdXQpIHtcbiAgICAgICAgY29uc3Qgb2xkRGF0ZUVudiA9IHRoaXMuZGF0ZUVudjtcbiAgICAgICAgaWYgKGRhdGVFbnYgIT09IG9sZERhdGVFbnYpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygbm93SW5wdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vd0ZuID0gbm93SW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghb2xkRGF0ZUVudikgeyAvLyBmaXJzdCB0aW1lP1xuICAgICAgICAgICAgICAgIHRoaXMubm93QW5jaG9yRGF0ZSA9IGRhdGVFbnYudG9EYXRlKG5vd0lucHV0XG4gICAgICAgICAgICAgICAgICAgID8gZGF0ZUVudi5jcmVhdGVNYXJrZXIobm93SW5wdXQpXG4gICAgICAgICAgICAgICAgICAgIDogZGF0ZUVudi5jcmVhdGVOb3dNYXJrZXIoKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5ub3dBbmNob3JRdWVyaWVkID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGF0ZUVudiA9IGRhdGVFbnY7XG4gICAgICAgICAgICAvLyBub3QgZmlyc3QgdGltZT8gZmlyZSByZXNldCBoYW5kbGVyc1xuICAgICAgICAgICAgaWYgKG9sZERhdGVFbnYpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlc2V0TGlzdGVuZXIgb2YgdGhpcy5yZXNldExpc3RlbmVycy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNldExpc3RlbmVyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldERhdGVNYXJrZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5vd0FuY2hvckRhdGVcbiAgICAgICAgICAgID8gdGhpcy5kYXRlRW52LnRpbWVzdGFtcFRvTWFya2VyKHRoaXMubm93QW5jaG9yRGF0ZS52YWx1ZU9mKCkgK1xuICAgICAgICAgICAgICAgIChEYXRlLm5vdygpIC0gdGhpcy5ub3dBbmNob3JRdWVyaWVkKSlcbiAgICAgICAgICAgIDogdGhpcy5kYXRlRW52LmNyZWF0ZU1hcmtlcih0aGlzLm5vd0ZuKCkpO1xuICAgIH1cbiAgICBhZGRSZXNldExpc3RlbmVyKGhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5yZXNldExpc3RlbmVycy5hZGQoaGFuZGxlcik7XG4gICAgfVxuICAgIHJlbW92ZVJlc2V0TGlzdGVuZXIoaGFuZGxlcikge1xuICAgICAgICB0aGlzLnJlc2V0TGlzdGVuZXJzLmRlbGV0ZShoYW5kbGVyKTtcbiAgICB9XG59XG5cbi8vIGluIGZ1dHVyZSByZWZhY3RvciwgZG8gdGhlIHJlZHV4LXN0eWxlIGZ1bmN0aW9uKHN0YXRlPWluaXRpYWwpIGZvciBpbml0aWFsLXN0YXRlXG4vLyBhbHNvLCB3aGF0ZXZlciBpcyBoYXBwZW5pbmcgaW4gY29uc3RydWN0b3IsIGhhdmUgaXQgaGFwcGVuIGluIGFjdGlvbiBxdWV1ZSB0b29cbmNsYXNzIENhbGVuZGFyRGF0YU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YSA9IG1lbW9pemUodGhpcy5fY29tcHV0ZUN1cnJlbnRWaWV3RGF0YSk7XG4gICAgICAgIHRoaXMub3JnYW5pemVSYXdMb2NhbGVzID0gbWVtb2l6ZShvcmdhbml6ZVJhd0xvY2FsZXMpO1xuICAgICAgICB0aGlzLmJ1aWxkTG9jYWxlID0gbWVtb2l6ZShidWlsZExvY2FsZSk7XG4gICAgICAgIHRoaXMuYnVpbGRQbHVnaW5Ib29rcyA9IGJ1aWxkQnVpbGRQbHVnaW5Ib29rcygpO1xuICAgICAgICB0aGlzLmJ1aWxkRGF0ZUVudiA9IG1lbW9pemUoYnVpbGREYXRlRW52JDEpO1xuICAgICAgICB0aGlzLmJ1aWxkVGhlbWUgPSBtZW1vaXplKGJ1aWxkVGhlbWUpO1xuICAgICAgICB0aGlzLnBhcnNlVG9vbGJhcnMgPSBtZW1vaXplKHBhcnNlVG9vbGJhcnMpO1xuICAgICAgICB0aGlzLmJ1aWxkVmlld1NwZWNzID0gbWVtb2l6ZShidWlsZFZpZXdTcGVjcyk7XG4gICAgICAgIHRoaXMuYnVpbGREYXRlUHJvZmlsZUdlbmVyYXRvciA9IG1lbW9pemVPYmpBcmcoYnVpbGREYXRlUHJvZmlsZUdlbmVyYXRvcik7XG4gICAgICAgIHRoaXMuYnVpbGRWaWV3QXBpID0gbWVtb2l6ZShidWlsZFZpZXdBcGkpO1xuICAgICAgICB0aGlzLmJ1aWxkVmlld1VpUHJvcHMgPSBtZW1vaXplT2JqQXJnKGJ1aWxkVmlld1VpUHJvcHMpO1xuICAgICAgICB0aGlzLmJ1aWxkRXZlbnRVaUJ5U291cmNlID0gbWVtb2l6ZShidWlsZEV2ZW50VWlCeVNvdXJjZSwgaXNQcm9wc0VxdWFsKTtcbiAgICAgICAgdGhpcy5idWlsZEV2ZW50VWlCYXNlcyA9IG1lbW9pemUoYnVpbGRFdmVudFVpQmFzZXMpO1xuICAgICAgICB0aGlzLnBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMgPSBtZW1vaXplT2JqQXJnKHBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMpO1xuICAgICAgICB0aGlzLmJ1aWxkVGl0bGUgPSBtZW1vaXplKGJ1aWxkVGl0bGUpO1xuICAgICAgICB0aGlzLm5vd01hbmFnZXIgPSBuZXcgQ2FsZW5kYXJOb3dNYW5hZ2VyKCk7XG4gICAgICAgIHRoaXMuZW1pdHRlciA9IG5ldyBFbWl0dGVyKCk7XG4gICAgICAgIHRoaXMuYWN0aW9uUnVubmVyID0gbmV3IFRhc2tSdW5uZXIodGhpcy5faGFuZGxlQWN0aW9uLmJpbmQodGhpcyksIHRoaXMudXBkYXRlRGF0YS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXQgPSB7fTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCA9IHt9O1xuICAgICAgICB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc0lucHV0ID0ge307XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXdPcHRpb25zUmVmaW5lZCA9IHt9O1xuICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVycyA9IHt9O1xuICAgICAgICB0aGlzLm9wdGlvbnNGb3JSZWZpbmluZyA9IFtdO1xuICAgICAgICB0aGlzLm9wdGlvbnNGb3JIYW5kbGluZyA9IFtdO1xuICAgICAgICB0aGlzLmdldEN1cnJlbnREYXRhID0gKCkgPT4gdGhpcy5kYXRhO1xuICAgICAgICB0aGlzLmRpc3BhdGNoID0gKGFjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIucmVxdWVzdChhY3Rpb24pOyAvLyBwcm90ZWN0cyBhZ2FpbnN0IHJlY3Vyc2l2ZSBjYWxscyB0byBfaGFuZGxlQWN0aW9uXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIucGF1c2UoKTtcbiAgICAgICAgdGhpcy5ub3dNYW5hZ2VyID0gbmV3IENhbGVuZGFyTm93TWFuYWdlcigpO1xuICAgICAgICBsZXQgZHluYW1pY09wdGlvbk92ZXJyaWRlcyA9IHt9O1xuICAgICAgICBsZXQgb3B0aW9uc0RhdGEgPSB0aGlzLmNvbXB1dGVPcHRpb25zRGF0YShwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3VHlwZSA9IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucy5pbml0aWFsVmlldyB8fCBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcy5pbml0aWFsVmlldztcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3RGF0YSA9IHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YShjdXJyZW50Vmlld1R5cGUsIG9wdGlvbnNEYXRhLCBwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICAvLyB3aXJlIHRoaW5ncyB1cFxuICAgICAgICAvLyBUT0RPOiBub3QgRFJZXG4gICAgICAgIHByb3BzLmNhbGVuZGFyQXBpLmN1cnJlbnREYXRhTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMuZW1pdHRlci5zZXRUaGlzQ29udGV4dChwcm9wcy5jYWxlbmRhckFwaSk7XG4gICAgICAgIHRoaXMuZW1pdHRlci5zZXRPcHRpb25zKGN1cnJlbnRWaWV3RGF0YS5vcHRpb25zKTtcbiAgICAgICAgbGV0IGNhbGVuZGFyQ29udGV4dCA9IHtcbiAgICAgICAgICAgIG5vd01hbmFnZXI6IHRoaXMubm93TWFuYWdlcixcbiAgICAgICAgICAgIGRhdGVFbnY6IG9wdGlvbnNEYXRhLmRhdGVFbnYsXG4gICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zRGF0YS5jYWxlbmRhck9wdGlvbnMsXG4gICAgICAgICAgICBwbHVnaW5Ib29rczogb3B0aW9uc0RhdGEucGx1Z2luSG9va3MsXG4gICAgICAgICAgICBjYWxlbmRhckFwaTogcHJvcHMuY2FsZW5kYXJBcGksXG4gICAgICAgICAgICBkaXNwYXRjaDogdGhpcy5kaXNwYXRjaCxcbiAgICAgICAgICAgIGVtaXR0ZXI6IHRoaXMuZW1pdHRlcixcbiAgICAgICAgICAgIGdldEN1cnJlbnREYXRhOiB0aGlzLmdldEN1cnJlbnREYXRhLFxuICAgICAgICB9O1xuICAgICAgICBsZXQgY3VycmVudERhdGUgPSBnZXRJbml0aWFsRGF0ZShvcHRpb25zRGF0YS5jYWxlbmRhck9wdGlvbnMsIG9wdGlvbnNEYXRhLmRhdGVFbnYsIHRoaXMubm93TWFuYWdlcik7XG4gICAgICAgIGxldCBkYXRlUHJvZmlsZSA9IGN1cnJlbnRWaWV3RGF0YS5kYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZChjdXJyZW50RGF0ZSk7XG4gICAgICAgIGlmICghcmFuZ2VDb250YWluc01hcmtlcihkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSwgY3VycmVudERhdGUpKSB7XG4gICAgICAgICAgICBjdXJyZW50RGF0ZSA9IGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZS5zdGFydDtcbiAgICAgICAgfVxuICAgICAgICAvLyBuZWVkcyB0byBiZSBhZnRlciBzZXRUaGlzQ29udGV4dFxuICAgICAgICBmb3IgKGxldCBjYWxsYmFjayBvZiBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcy5jb250ZXh0SW5pdCkge1xuICAgICAgICAgICAgY2FsbGJhY2soY2FsZW5kYXJDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBOT1QgRFJZXG4gICAgICAgIGxldCBldmVudFNvdXJjZXMgPSBpbml0RXZlbnRTb3VyY2VzKG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucywgZGF0ZVByb2ZpbGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIGxldCBpbml0aWFsU3RhdGUgPSB7XG4gICAgICAgICAgICBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgY3VycmVudFZpZXdUeXBlLFxuICAgICAgICAgICAgY3VycmVudERhdGUsXG4gICAgICAgICAgICBkYXRlUHJvZmlsZSxcbiAgICAgICAgICAgIGJ1c2luZXNzSG91cnM6IHRoaXMucGFyc2VDb250ZXh0QnVzaW5lc3NIb3VycyhjYWxlbmRhckNvbnRleHQpLFxuICAgICAgICAgICAgZXZlbnRTb3VyY2VzLFxuICAgICAgICAgICAgZXZlbnRVaUJhc2VzOiB7fSxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpLFxuICAgICAgICAgICAgcmVuZGVyYWJsZUV2ZW50U3RvcmU6IGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpLFxuICAgICAgICAgICAgZGF0ZVNlbGVjdGlvbjogbnVsbCxcbiAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiAnJyxcbiAgICAgICAgICAgIGV2ZW50RHJhZzogbnVsbCxcbiAgICAgICAgICAgIGV2ZW50UmVzaXplOiBudWxsLFxuICAgICAgICAgICAgc2VsZWN0aW9uQ29uZmlnOiB0aGlzLmJ1aWxkVmlld1VpUHJvcHMoY2FsZW5kYXJDb250ZXh0KS5zZWxlY3Rpb25Db25maWcsXG4gICAgICAgIH07XG4gICAgICAgIGxldCBjb250ZXh0QW5kU3RhdGUgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGNhbGVuZGFyQ29udGV4dCksIGluaXRpYWxTdGF0ZSk7XG4gICAgICAgIGZvciAobGV0IHJlZHVjZXIgb2Ygb3B0aW9uc0RhdGEucGx1Z2luSG9va3MucmVkdWNlcnMpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oaW5pdGlhbFN0YXRlLCByZWR1Y2VyKG51bGwsIG51bGwsIGNvbnRleHRBbmRTdGF0ZSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb21wdXRlSXNMb2FkaW5nKGluaXRpYWxTdGF0ZSwgY2FsZW5kYXJDb250ZXh0KSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ2xvYWRpbmcnLCB0cnVlKTsgLy8gTk9UIERSWVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUgPSBpbml0aWFsU3RhdGU7XG4gICAgICAgIHRoaXMudXBkYXRlRGF0YSgpO1xuICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5yZXN1bWUoKTtcbiAgICB9XG4gICAgcmVzZXRPcHRpb25zKG9wdGlvbk92ZXJyaWRlcywgY2hhbmdlZE9wdGlvbk5hbWVzKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBpZiAoY2hhbmdlZE9wdGlvbk5hbWVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHByb3BzLm9wdGlvbk92ZXJyaWRlcyA9IG9wdGlvbk92ZXJyaWRlcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHByb3BzLm9wdGlvbk92ZXJyaWRlcyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgKHByb3BzLm9wdGlvbk92ZXJyaWRlcyB8fCB7fSkpLCBvcHRpb25PdmVycmlkZXMpO1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zRm9yUmVmaW5pbmcucHVzaCguLi5jaGFuZ2VkT3B0aW9uTmFtZXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFuZ2VkT3B0aW9uTmFtZXMgPT09IHVuZGVmaW5lZCB8fCBjaGFuZ2VkT3B0aW9uTmFtZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5yZXF1ZXN0KHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnTk9USElORycsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBfaGFuZGxlQWN0aW9uKGFjdGlvbikge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUsIGVtaXR0ZXIgfSA9IHRoaXM7XG4gICAgICAgIGxldCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzID0gcmVkdWNlRHluYW1pY09wdGlvbk92ZXJyaWRlcyhzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBhY3Rpb24pO1xuICAgICAgICBsZXQgb3B0aW9uc0RhdGEgPSB0aGlzLmNvbXB1dGVPcHRpb25zRGF0YShwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3VHlwZSA9IHJlZHVjZVZpZXdUeXBlKHN0YXRlLmN1cnJlbnRWaWV3VHlwZSwgYWN0aW9uKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3RGF0YSA9IHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YShjdXJyZW50Vmlld1R5cGUsIG9wdGlvbnNEYXRhLCBwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICAvLyB3aXJlIHRoaW5ncyB1cFxuICAgICAgICAvLyBUT0RPOiBub3QgRFJZXG4gICAgICAgIHByb3BzLmNhbGVuZGFyQXBpLmN1cnJlbnREYXRhTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIGVtaXR0ZXIuc2V0VGhpc0NvbnRleHQocHJvcHMuY2FsZW5kYXJBcGkpO1xuICAgICAgICBlbWl0dGVyLnNldE9wdGlvbnMoY3VycmVudFZpZXdEYXRhLm9wdGlvbnMpO1xuICAgICAgICBsZXQgY2FsZW5kYXJDb250ZXh0ID0ge1xuICAgICAgICAgICAgbm93TWFuYWdlcjogdGhpcy5ub3dNYW5hZ2VyLFxuICAgICAgICAgICAgZGF0ZUVudjogb3B0aW9uc0RhdGEuZGF0ZUVudixcbiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucyxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzOiBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcyxcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiBwcm9wcy5jYWxlbmRhckFwaSxcbiAgICAgICAgICAgIGRpc3BhdGNoOiB0aGlzLmRpc3BhdGNoLFxuICAgICAgICAgICAgZW1pdHRlcixcbiAgICAgICAgICAgIGdldEN1cnJlbnREYXRhOiB0aGlzLmdldEN1cnJlbnREYXRhLFxuICAgICAgICB9O1xuICAgICAgICBsZXQgeyBjdXJyZW50RGF0ZSwgZGF0ZVByb2ZpbGUgfSA9IHN0YXRlO1xuICAgICAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YS5kYXRlUHJvZmlsZUdlbmVyYXRvciAhPT0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yKSB7IC8vIGhhY2tcbiAgICAgICAgICAgIGRhdGVQcm9maWxlID0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGN1cnJlbnREYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50RGF0ZSA9IHJlZHVjZUN1cnJlbnREYXRlKGN1cnJlbnREYXRlLCBhY3Rpb24pO1xuICAgICAgICBkYXRlUHJvZmlsZSA9IHJlZHVjZURhdGVQcm9maWxlKGRhdGVQcm9maWxlLCBhY3Rpb24sIGN1cnJlbnREYXRlLCBjdXJyZW50Vmlld0RhdGEuZGF0ZVByb2ZpbGVHZW5lcmF0b3IpO1xuICAgICAgICBpZiAoYWN0aW9uLnR5cGUgPT09ICdQUkVWJyB8fCAvLyBUT0RPOiBtb3ZlIHRoaXMgbG9naWMgaW50byBEYXRlUHJvZmlsZUdlbmVyYXRvclxuICAgICAgICAgICAgYWN0aW9uLnR5cGUgPT09ICdORVhUJyB8fCAvLyBcIlxuICAgICAgICAgICAgIXJhbmdlQ29udGFpbnNNYXJrZXIoZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLCBjdXJyZW50RGF0ZSkpIHtcbiAgICAgICAgICAgIGN1cnJlbnREYXRlID0gZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIGxldCBldmVudFNvdXJjZXMgPSByZWR1Y2VFdmVudFNvdXJjZXMoc3RhdGUuZXZlbnRTb3VyY2VzLCBhY3Rpb24sIGRhdGVQcm9maWxlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICBsZXQgZXZlbnRTdG9yZSA9IHJlZHVjZUV2ZW50U3RvcmUoc3RhdGUuZXZlbnRTdG9yZSwgYWN0aW9uLCBldmVudFNvdXJjZXMsIGRhdGVQcm9maWxlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICBsZXQgaXNFdmVudHNMb2FkaW5nID0gY29tcHV0ZUV2ZW50U291cmNlc0xvYWRpbmcoZXZlbnRTb3VyY2VzKTsgLy8gQkFELiBhbHNvIGNhbGxlZCBpbiB0aGlzIGZ1bmMgaW4gY29tcHV0ZUlzTG9hZGluZ1xuICAgICAgICBsZXQgcmVuZGVyYWJsZUV2ZW50U3RvcmUgPSAoaXNFdmVudHNMb2FkaW5nICYmICFjdXJyZW50Vmlld0RhdGEub3B0aW9ucy5wcm9ncmVzc2l2ZUV2ZW50UmVuZGVyaW5nKSA/XG4gICAgICAgICAgICAoc3RhdGUucmVuZGVyYWJsZUV2ZW50U3RvcmUgfHwgZXZlbnRTdG9yZSkgOiAvLyB0cnkgZnJvbSBwcmV2aW91cyBzdGF0ZVxuICAgICAgICAgICAgZXZlbnRTdG9yZTtcbiAgICAgICAgbGV0IHsgZXZlbnRVaVNpbmdsZUJhc2UsIHNlbGVjdGlvbkNvbmZpZyB9ID0gdGhpcy5idWlsZFZpZXdVaVByb3BzKGNhbGVuZGFyQ29udGV4dCk7IC8vIHdpbGwgbWVtb2l6ZSBvYmpcbiAgICAgICAgbGV0IGV2ZW50VWlCeVNvdXJjZSA9IHRoaXMuYnVpbGRFdmVudFVpQnlTb3VyY2UoZXZlbnRTb3VyY2VzKTtcbiAgICAgICAgbGV0IGV2ZW50VWlCYXNlcyA9IHRoaXMuYnVpbGRFdmVudFVpQmFzZXMocmVuZGVyYWJsZUV2ZW50U3RvcmUuZGVmcywgZXZlbnRVaVNpbmdsZUJhc2UsIGV2ZW50VWlCeVNvdXJjZSk7XG4gICAgICAgIGxldCBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBjdXJyZW50Vmlld1R5cGUsXG4gICAgICAgICAgICBjdXJyZW50RGF0ZSxcbiAgICAgICAgICAgIGRhdGVQcm9maWxlLFxuICAgICAgICAgICAgZXZlbnRTb3VyY2VzLFxuICAgICAgICAgICAgZXZlbnRTdG9yZSxcbiAgICAgICAgICAgIHJlbmRlcmFibGVFdmVudFN0b3JlLFxuICAgICAgICAgICAgc2VsZWN0aW9uQ29uZmlnLFxuICAgICAgICAgICAgZXZlbnRVaUJhc2VzLFxuICAgICAgICAgICAgYnVzaW5lc3NIb3VyczogdGhpcy5wYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzKGNhbGVuZGFyQ29udGV4dCksXG4gICAgICAgICAgICBkYXRlU2VsZWN0aW9uOiByZWR1Y2VEYXRlU2VsZWN0aW9uKHN0YXRlLmRhdGVTZWxlY3Rpb24sIGFjdGlvbiksXG4gICAgICAgICAgICBldmVudFNlbGVjdGlvbjogcmVkdWNlU2VsZWN0ZWRFdmVudChzdGF0ZS5ldmVudFNlbGVjdGlvbiwgYWN0aW9uKSxcbiAgICAgICAgICAgIGV2ZW50RHJhZzogcmVkdWNlRXZlbnREcmFnKHN0YXRlLmV2ZW50RHJhZywgYWN0aW9uKSxcbiAgICAgICAgICAgIGV2ZW50UmVzaXplOiByZWR1Y2VFdmVudFJlc2l6ZShzdGF0ZS5ldmVudFJlc2l6ZSwgYWN0aW9uKSxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNvbnRleHRBbmRTdGF0ZSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgY2FsZW5kYXJDb250ZXh0KSwgbmV3U3RhdGUpO1xuICAgICAgICBmb3IgKGxldCByZWR1Y2VyIG9mIG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLnJlZHVjZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKG5ld1N0YXRlLCByZWR1Y2VyKHN0YXRlLCBhY3Rpb24sIGNvbnRleHRBbmRTdGF0ZSkpOyAvLyBnaXZlIHRoZSBPTEQgc3RhdGUsIGZvciBvbGQgdmFsdWVcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2FzTG9hZGluZyA9IGNvbXB1dGVJc0xvYWRpbmcoc3RhdGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIGxldCBpc0xvYWRpbmcgPSBjb21wdXRlSXNMb2FkaW5nKG5ld1N0YXRlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICAvLyBUT0RPOiB1c2UgcHJvcFNldEhhbmRsZXJzIGluIHBsdWdpbiBzeXN0ZW1cbiAgICAgICAgaWYgKCF3YXNMb2FkaW5nICYmIGlzTG9hZGluZykge1xuICAgICAgICAgICAgZW1pdHRlci50cmlnZ2VyKCdsb2FkaW5nJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAod2FzTG9hZGluZyAmJiAhaXNMb2FkaW5nKSB7XG4gICAgICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2xvYWRpbmcnLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgICBpZiAocHJvcHMub25BY3Rpb24pIHtcbiAgICAgICAgICAgIHByb3BzLm9uQWN0aW9uKGFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlRGF0YSgpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMsIHN0YXRlIH0gPSB0aGlzO1xuICAgICAgICBsZXQgb2xkRGF0YSA9IHRoaXMuZGF0YTtcbiAgICAgICAgbGV0IG9wdGlvbnNEYXRhID0gdGhpcy5jb21wdXRlT3B0aW9uc0RhdGEocHJvcHMub3B0aW9uT3ZlcnJpZGVzLCBzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBwcm9wcy5jYWxlbmRhckFwaSk7XG4gICAgICAgIGxldCBjdXJyZW50Vmlld0RhdGEgPSB0aGlzLmNvbXB1dGVDdXJyZW50Vmlld0RhdGEoc3RhdGUuY3VycmVudFZpZXdUeXBlLCBvcHRpb25zRGF0YSwgcHJvcHMub3B0aW9uT3ZlcnJpZGVzLCBzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzKTtcbiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmRhdGEgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IG5vd01hbmFnZXI6IHRoaXMubm93TWFuYWdlciwgdmlld1RpdGxlOiB0aGlzLmJ1aWxkVGl0bGUoc3RhdGUuZGF0ZVByb2ZpbGUsIGN1cnJlbnRWaWV3RGF0YS5vcHRpb25zLCBvcHRpb25zRGF0YS5kYXRlRW52KSwgY2FsZW5kYXJBcGk6IHByb3BzLmNhbGVuZGFyQXBpLCBkaXNwYXRjaDogdGhpcy5kaXNwYXRjaCwgZW1pdHRlcjogdGhpcy5lbWl0dGVyLCBnZXRDdXJyZW50RGF0YTogdGhpcy5nZXRDdXJyZW50RGF0YSB9LCBvcHRpb25zRGF0YSksIGN1cnJlbnRWaWV3RGF0YSksIHN0YXRlKTtcbiAgICAgICAgbGV0IGNoYW5nZUhhbmRsZXJzID0gb3B0aW9uc0RhdGEucGx1Z2luSG9va3Mub3B0aW9uQ2hhbmdlSGFuZGxlcnM7XG4gICAgICAgIGxldCBvbGRDYWxlbmRhck9wdGlvbnMgPSBvbGREYXRhICYmIG9sZERhdGEuY2FsZW5kYXJPcHRpb25zO1xuICAgICAgICBsZXQgbmV3Q2FsZW5kYXJPcHRpb25zID0gb3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zO1xuICAgICAgICBpZiAob2xkQ2FsZW5kYXJPcHRpb25zICYmIG9sZENhbGVuZGFyT3B0aW9ucyAhPT0gbmV3Q2FsZW5kYXJPcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAob2xkQ2FsZW5kYXJPcHRpb25zLnRpbWVab25lICE9PSBuZXdDYWxlbmRhck9wdGlvbnMudGltZVpvbmUpIHtcbiAgICAgICAgICAgICAgICAvLyBoYWNrXG4gICAgICAgICAgICAgICAgc3RhdGUuZXZlbnRTb3VyY2VzID0gZGF0YS5ldmVudFNvdXJjZXMgPSByZWR1Y2VFdmVudFNvdXJjZXNOZXdUaW1lWm9uZShkYXRhLmV2ZW50U291cmNlcywgc3RhdGUuZGF0ZVByb2ZpbGUsIGRhdGEpO1xuICAgICAgICAgICAgICAgIHN0YXRlLmV2ZW50U3RvcmUgPSBkYXRhLmV2ZW50U3RvcmUgPSByZXpvbmVFdmVudFN0b3JlRGF0ZXMoZGF0YS5ldmVudFN0b3JlLCBvbGREYXRhLmRhdGVFbnYsIGRhdGEuZGF0ZUVudik7XG4gICAgICAgICAgICAgICAgc3RhdGUucmVuZGVyYWJsZUV2ZW50U3RvcmUgPSBkYXRhLnJlbmRlcmFibGVFdmVudFN0b3JlID0gcmV6b25lRXZlbnRTdG9yZURhdGVzKGRhdGEucmVuZGVyYWJsZUV2ZW50U3RvcmUsIG9sZERhdGEuZGF0ZUVudiwgZGF0YS5kYXRlRW52KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IG9wdGlvbk5hbWUgaW4gY2hhbmdlSGFuZGxlcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zRm9ySGFuZGxpbmcuaW5kZXhPZihvcHRpb25OYW1lKSAhPT0gLTEgfHxcbiAgICAgICAgICAgICAgICAgICAgb2xkQ2FsZW5kYXJPcHRpb25zW29wdGlvbk5hbWVdICE9PSBuZXdDYWxlbmRhck9wdGlvbnNbb3B0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbmdlSGFuZGxlcnNbb3B0aW9uTmFtZV0obmV3Q2FsZW5kYXJPcHRpb25zW29wdGlvbk5hbWVdLCBkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zRm9ySGFuZGxpbmcgPSBbXTtcbiAgICAgICAgaWYgKHByb3BzLm9uRGF0YSkge1xuICAgICAgICAgICAgcHJvcHMub25EYXRhKGRhdGEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbXB1dGVPcHRpb25zRGF0YShvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGNhbGVuZGFyQXBpKSB7XG4gICAgICAgIC8vIFRPRE86IGJsYWNrbGlzdCBvcHRpb25zIHRoYXQgYXJlIGhhbmRsZWQgYnkgb3B0aW9uQ2hhbmdlSGFuZGxlcnNcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnNGb3JSZWZpbmluZy5sZW5ndGggJiZcbiAgICAgICAgICAgIG9wdGlvbk92ZXJyaWRlcyA9PT0gdGhpcy5zdGFibGVPcHRpb25PdmVycmlkZXMgJiZcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMgPT09IHRoaXMuc3RhYmxlRHluYW1pY09wdGlvbk92ZXJyaWRlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhYmxlQ2FsZW5kYXJPcHRpb25zRGF0YTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyByZWZpbmVkT3B0aW9ucywgcGx1Z2luSG9va3MsIGxvY2FsZURlZmF1bHRzLCBhdmFpbGFibGVMb2NhbGVEYXRhLCBleHRyYSwgfSA9IHRoaXMucHJvY2Vzc1Jhd0NhbGVuZGFyT3B0aW9ucyhvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICB3YXJuVW5rbm93bk9wdGlvbnMoZXh0cmEpO1xuICAgICAgICBsZXQgZGF0ZUVudiA9IHRoaXMuYnVpbGREYXRlRW52KHJlZmluZWRPcHRpb25zLnRpbWVab25lLCByZWZpbmVkT3B0aW9ucy5sb2NhbGUsIHJlZmluZWRPcHRpb25zLndlZWtOdW1iZXJDYWxjdWxhdGlvbiwgcmVmaW5lZE9wdGlvbnMuZmlyc3REYXksIHJlZmluZWRPcHRpb25zLndlZWtUZXh0LCBwbHVnaW5Ib29rcywgYXZhaWxhYmxlTG9jYWxlRGF0YSwgcmVmaW5lZE9wdGlvbnMuZGVmYXVsdFJhbmdlU2VwYXJhdG9yKTtcbiAgICAgICAgbGV0IHZpZXdTcGVjcyA9IHRoaXMuYnVpbGRWaWV3U3BlY3MocGx1Z2luSG9va3Mudmlld3MsIHRoaXMuc3RhYmxlT3B0aW9uT3ZlcnJpZGVzLCB0aGlzLnN0YWJsZUR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKTtcbiAgICAgICAgbGV0IHRoZW1lID0gdGhpcy5idWlsZFRoZW1lKHJlZmluZWRPcHRpb25zLCBwbHVnaW5Ib29rcyk7XG4gICAgICAgIGxldCB0b29sYmFyQ29uZmlnID0gdGhpcy5wYXJzZVRvb2xiYXJzKHJlZmluZWRPcHRpb25zLCB0aGlzLnN0YWJsZU9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFibGVDYWxlbmRhck9wdGlvbnNEYXRhID0ge1xuICAgICAgICAgICAgY2FsZW5kYXJPcHRpb25zOiByZWZpbmVkT3B0aW9ucyxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzLFxuICAgICAgICAgICAgZGF0ZUVudixcbiAgICAgICAgICAgIHZpZXdTcGVjcyxcbiAgICAgICAgICAgIHRoZW1lLFxuICAgICAgICAgICAgdG9vbGJhckNvbmZpZyxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgYXZhaWxhYmxlUmF3TG9jYWxlczogYXZhaWxhYmxlTG9jYWxlRGF0YS5tYXAsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vIGFsd2F5cyBjYWxsZWQgZnJvbSBiZWhpbmQgYSBtZW1vaXplclxuICAgIHByb2Nlc3NSYXdDYWxlbmRhck9wdGlvbnMob3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgIGxldCB7IGxvY2FsZXMsIGxvY2FsZSB9ID0gbWVyZ2VSYXdPcHRpb25zKFtcbiAgICAgICAgICAgIEJBU0VfT1BUSU9OX0RFRkFVTFRTLFxuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgXSk7XG4gICAgICAgIGxldCBhdmFpbGFibGVMb2NhbGVEYXRhID0gdGhpcy5vcmdhbml6ZVJhd0xvY2FsZXMobG9jYWxlcyk7XG4gICAgICAgIGxldCBhdmFpbGFibGVSYXdMb2NhbGVzID0gYXZhaWxhYmxlTG9jYWxlRGF0YS5tYXA7XG4gICAgICAgIGxldCBsb2NhbGVEZWZhdWx0cyA9IHRoaXMuYnVpbGRMb2NhbGUobG9jYWxlIHx8IGF2YWlsYWJsZUxvY2FsZURhdGEuZGVmYXVsdENvZGUsIGF2YWlsYWJsZVJhd0xvY2FsZXMpLm9wdGlvbnM7XG4gICAgICAgIGxldCBwbHVnaW5Ib29rcyA9IHRoaXMuYnVpbGRQbHVnaW5Ib29rcyhvcHRpb25PdmVycmlkZXMucGx1Z2lucyB8fCBbXSwgZ2xvYmFsUGx1Z2lucyk7XG4gICAgICAgIGxldCByZWZpbmVycyA9IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZXJzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBCQVNFX09QVElPTl9SRUZJTkVSUyksIENBTEVOREFSX0xJU1RFTkVSX1JFRklORVJTKSwgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTKSwgcGx1Z2luSG9va3MubGlzdGVuZXJSZWZpbmVycyksIHBsdWdpbkhvb2tzLm9wdGlvblJlZmluZXJzKTtcbiAgICAgICAgbGV0IGV4dHJhID0ge307XG4gICAgICAgIGxldCByYXcgPSBtZXJnZVJhd09wdGlvbnMoW1xuICAgICAgICAgICAgQkFTRV9PUFRJT05fREVGQVVMVFMsXG4gICAgICAgICAgICBsb2NhbGVEZWZhdWx0cyxcbiAgICAgICAgICAgIG9wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgIF0pO1xuICAgICAgICBsZXQgcmVmaW5lZCA9IHt9O1xuICAgICAgICBsZXQgY3VycmVudFJhdyA9IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc0lucHV0O1xuICAgICAgICBsZXQgY3VycmVudFJlZmluZWQgPSB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkO1xuICAgICAgICBsZXQgYW55Q2hhbmdlcyA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBvcHRpb25OYW1lIGluIHJhdykge1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9uc0ZvclJlZmluaW5nLmluZGV4T2Yob3B0aW9uTmFtZSkgPT09IC0xICYmIChyYXdbb3B0aW9uTmFtZV0gPT09IGN1cnJlbnRSYXdbb3B0aW9uTmFtZV0gfHwgKENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdICYmXG4gICAgICAgICAgICAgICAgKG9wdGlvbk5hbWUgaW4gY3VycmVudFJhdykgJiZcbiAgICAgICAgICAgICAgICBDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXShjdXJyZW50UmF3W29wdGlvbk5hbWVdLCByYXdbb3B0aW9uTmFtZV0pKSkpIHtcbiAgICAgICAgICAgICAgICByZWZpbmVkW29wdGlvbk5hbWVdID0gY3VycmVudFJlZmluZWRbb3B0aW9uTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZWZpbmVyc1tvcHRpb25OYW1lXSkge1xuICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSByZWZpbmVyc1tvcHRpb25OYW1lXShyYXdbb3B0aW9uTmFtZV0pO1xuICAgICAgICAgICAgICAgIGFueUNoYW5nZXMgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZXh0cmFbb3B0aW9uTmFtZV0gPSBjdXJyZW50UmF3W29wdGlvbk5hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhbnlDaGFuZ2VzKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dCA9IHJhdztcbiAgICAgICAgICAgIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZWQgPSByZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5zdGFibGVPcHRpb25PdmVycmlkZXMgPSBvcHRpb25PdmVycmlkZXM7XG4gICAgICAgICAgICB0aGlzLnN0YWJsZUR5bmFtaWNPcHRpb25PdmVycmlkZXMgPSBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3B0aW9uc0ZvckhhbmRsaW5nLnB1c2goLi4udGhpcy5vcHRpb25zRm9yUmVmaW5pbmcpO1xuICAgICAgICB0aGlzLm9wdGlvbnNGb3JSZWZpbmluZyA9IFtdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmF3T3B0aW9uczogdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXQsXG4gICAgICAgICAgICByZWZpbmVkT3B0aW9uczogdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzLFxuICAgICAgICAgICAgYXZhaWxhYmxlTG9jYWxlRGF0YSxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgZXh0cmEsXG4gICAgICAgIH07XG4gICAgfVxuICAgIF9jb21wdXRlQ3VycmVudFZpZXdEYXRhKHZpZXdUeXBlLCBvcHRpb25zRGF0YSwgb3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgIGxldCB2aWV3U3BlYyA9IG9wdGlvbnNEYXRhLnZpZXdTcGVjc1t2aWV3VHlwZV07XG4gICAgICAgIGlmICghdmlld1NwZWMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdmlld1R5cGUgXCIke3ZpZXdUeXBlfVwiIGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBtYWtlIHN1cmUgeW91J3ZlIGxvYWRlZCBhbGwgbmVjY2Vzc2FyeSBwbHVnaW5zYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgcmVmaW5lZE9wdGlvbnMsIGV4dHJhIH0gPSB0aGlzLnByb2Nlc3NSYXdWaWV3T3B0aW9ucyh2aWV3U3BlYywgb3B0aW9uc0RhdGEucGx1Z2luSG9va3MsIG9wdGlvbnNEYXRhLmxvY2FsZURlZmF1bHRzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICB3YXJuVW5rbm93bk9wdGlvbnMoZXh0cmEpO1xuICAgICAgICB0aGlzLm5vd01hbmFnZXIuaGFuZGxlSW5wdXQob3B0aW9uc0RhdGEuZGF0ZUVudiwgcmVmaW5lZE9wdGlvbnMubm93KTtcbiAgICAgICAgbGV0IGRhdGVQcm9maWxlR2VuZXJhdG9yID0gdGhpcy5idWlsZERhdGVQcm9maWxlR2VuZXJhdG9yKHtcbiAgICAgICAgICAgIGRhdGVQcm9maWxlR2VuZXJhdG9yQ2xhc3M6IHZpZXdTcGVjLm9wdGlvbkRlZmF1bHRzLmRhdGVQcm9maWxlR2VuZXJhdG9yQ2xhc3MsXG4gICAgICAgICAgICBub3dNYW5hZ2VyOiB0aGlzLm5vd01hbmFnZXIsXG4gICAgICAgICAgICBkdXJhdGlvbjogdmlld1NwZWMuZHVyYXRpb24sXG4gICAgICAgICAgICBkdXJhdGlvblVuaXQ6IHZpZXdTcGVjLmR1cmF0aW9uVW5pdCxcbiAgICAgICAgICAgIHVzZXNNaW5NYXhUaW1lOiB2aWV3U3BlYy5vcHRpb25EZWZhdWx0cy51c2VzTWluTWF4VGltZSxcbiAgICAgICAgICAgIGRhdGVFbnY6IG9wdGlvbnNEYXRhLmRhdGVFbnYsXG4gICAgICAgICAgICBjYWxlbmRhckFwaTogdGhpcy5wcm9wcy5jYWxlbmRhckFwaSxcbiAgICAgICAgICAgIHNsb3RNaW5UaW1lOiByZWZpbmVkT3B0aW9ucy5zbG90TWluVGltZSxcbiAgICAgICAgICAgIHNsb3RNYXhUaW1lOiByZWZpbmVkT3B0aW9ucy5zbG90TWF4VGltZSxcbiAgICAgICAgICAgIHNob3dOb25DdXJyZW50RGF0ZXM6IHJlZmluZWRPcHRpb25zLnNob3dOb25DdXJyZW50RGF0ZXMsXG4gICAgICAgICAgICBkYXlDb3VudDogcmVmaW5lZE9wdGlvbnMuZGF5Q291bnQsXG4gICAgICAgICAgICBkYXRlQWxpZ25tZW50OiByZWZpbmVkT3B0aW9ucy5kYXRlQWxpZ25tZW50LFxuICAgICAgICAgICAgZGF0ZUluY3JlbWVudDogcmVmaW5lZE9wdGlvbnMuZGF0ZUluY3JlbWVudCxcbiAgICAgICAgICAgIGhpZGRlbkRheXM6IHJlZmluZWRPcHRpb25zLmhpZGRlbkRheXMsXG4gICAgICAgICAgICB3ZWVrZW5kczogcmVmaW5lZE9wdGlvbnMud2Vla2VuZHMsXG4gICAgICAgICAgICB2YWxpZFJhbmdlSW5wdXQ6IHJlZmluZWRPcHRpb25zLnZhbGlkUmFuZ2UsXG4gICAgICAgICAgICB2aXNpYmxlUmFuZ2VJbnB1dDogcmVmaW5lZE9wdGlvbnMudmlzaWJsZVJhbmdlLFxuICAgICAgICAgICAgZml4ZWRXZWVrQ291bnQ6IHJlZmluZWRPcHRpb25zLmZpeGVkV2Vla0NvdW50LFxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHZpZXdBcGkgPSB0aGlzLmJ1aWxkVmlld0FwaSh2aWV3VHlwZSwgdGhpcy5nZXRDdXJyZW50RGF0YSwgb3B0aW9uc0RhdGEuZGF0ZUVudik7XG4gICAgICAgIHJldHVybiB7IHZpZXdTcGVjLCBvcHRpb25zOiByZWZpbmVkT3B0aW9ucywgZGF0ZVByb2ZpbGVHZW5lcmF0b3IsIHZpZXdBcGkgfTtcbiAgICB9XG4gICAgcHJvY2Vzc1Jhd1ZpZXdPcHRpb25zKHZpZXdTcGVjLCBwbHVnaW5Ib29rcywgbG9jYWxlRGVmYXVsdHMsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcykge1xuICAgICAgICBsZXQgcmF3ID0gbWVyZ2VSYXdPcHRpb25zKFtcbiAgICAgICAgICAgIEJBU0VfT1BUSU9OX0RFRkFVTFRTLFxuICAgICAgICAgICAgdmlld1NwZWMub3B0aW9uRGVmYXVsdHMsXG4gICAgICAgICAgICBsb2NhbGVEZWZhdWx0cyxcbiAgICAgICAgICAgIG9wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIHZpZXdTcGVjLm9wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgIF0pO1xuICAgICAgICBsZXQgcmVmaW5lcnMgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgQkFTRV9PUFRJT05fUkVGSU5FUlMpLCBDQUxFTkRBUl9MSVNURU5FUl9SRUZJTkVSUyksIENBTEVOREFSX09QVElPTl9SRUZJTkVSUyksIFZJRVdfT1BUSU9OX1JFRklORVJTKSwgcGx1Z2luSG9va3MubGlzdGVuZXJSZWZpbmVycyksIHBsdWdpbkhvb2tzLm9wdGlvblJlZmluZXJzKTtcbiAgICAgICAgbGV0IHJlZmluZWQgPSB7fTtcbiAgICAgICAgbGV0IGN1cnJlbnRSYXcgPSB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc0lucHV0O1xuICAgICAgICBsZXQgY3VycmVudFJlZmluZWQgPSB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc1JlZmluZWQ7XG4gICAgICAgIGxldCBhbnlDaGFuZ2VzID0gZmFsc2U7XG4gICAgICAgIGxldCBleHRyYSA9IHt9O1xuICAgICAgICBmb3IgKGxldCBvcHRpb25OYW1lIGluIHJhdykge1xuICAgICAgICAgICAgaWYgKHJhd1tvcHRpb25OYW1lXSA9PT0gY3VycmVudFJhd1tvcHRpb25OYW1lXSB8fFxuICAgICAgICAgICAgICAgIChDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXSAmJlxuICAgICAgICAgICAgICAgICAgICBDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXShyYXdbb3B0aW9uTmFtZV0sIGN1cnJlbnRSYXdbb3B0aW9uTmFtZV0pKSkge1xuICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSBjdXJyZW50UmVmaW5lZFtvcHRpb25OYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChyYXdbb3B0aW9uTmFtZV0gPT09IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc0lucHV0W29wdGlvbk5hbWVdIHx8XG4gICAgICAgICAgICAgICAgICAgIChDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgQ09NUExFWF9PUFRJT05fQ09NUEFSQVRPUlNbb3B0aW9uTmFtZV0ocmF3W29wdGlvbk5hbWVdLCB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dFtvcHRpb25OYW1lXSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25OYW1lIGluIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZWQpIHsgLy8gbWlnaHQgYmUgYW4gXCJleHRyYVwiIHByb3BcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkW29wdGlvbk5hbWVdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlZmluZXJzW29wdGlvbk5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSByZWZpbmVyc1tvcHRpb25OYW1lXShyYXdbb3B0aW9uTmFtZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFbb3B0aW9uTmFtZV0gPSByYXdbb3B0aW9uTmFtZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFueUNoYW5nZXMgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhbnlDaGFuZ2VzKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc0lucHV0ID0gcmF3O1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Vmlld09wdGlvbnNSZWZpbmVkID0gcmVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmF3T3B0aW9uczogdGhpcy5jdXJyZW50Vmlld09wdGlvbnNJbnB1dCxcbiAgICAgICAgICAgIHJlZmluZWRPcHRpb25zOiB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc1JlZmluZWQsXG4gICAgICAgICAgICBleHRyYSxcbiAgICAgICAgfTtcbiAgICB9XG59XG5mdW5jdGlvbiBidWlsZERhdGVFbnYkMSh0aW1lWm9uZSwgZXhwbGljaXRMb2NhbGUsIHdlZWtOdW1iZXJDYWxjdWxhdGlvbiwgZmlyc3REYXksIHdlZWtUZXh0LCBwbHVnaW5Ib29rcywgYXZhaWxhYmxlTG9jYWxlRGF0YSwgZGVmYXVsdFNlcGFyYXRvcikge1xuICAgIGxldCBsb2NhbGUgPSBidWlsZExvY2FsZShleHBsaWNpdExvY2FsZSB8fCBhdmFpbGFibGVMb2NhbGVEYXRhLmRlZmF1bHRDb2RlLCBhdmFpbGFibGVMb2NhbGVEYXRhLm1hcCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlRW52KHtcbiAgICAgICAgY2FsZW5kYXJTeXN0ZW06ICdncmVnb3J5JyxcbiAgICAgICAgdGltZVpvbmUsXG4gICAgICAgIG5hbWVkVGltZVpvbmVJbXBsOiBwbHVnaW5Ib29rcy5uYW1lZFRpbWVab25lZEltcGwsXG4gICAgICAgIGxvY2FsZSxcbiAgICAgICAgd2Vla051bWJlckNhbGN1bGF0aW9uLFxuICAgICAgICBmaXJzdERheSxcbiAgICAgICAgd2Vla1RleHQsXG4gICAgICAgIGNtZEZvcm1hdHRlcjogcGx1Z2luSG9va3MuY21kRm9ybWF0dGVyLFxuICAgICAgICBkZWZhdWx0U2VwYXJhdG9yLFxuICAgIH0pO1xufVxuZnVuY3Rpb24gYnVpbGRUaGVtZShvcHRpb25zLCBwbHVnaW5Ib29rcykge1xuICAgIGxldCBUaGVtZUNsYXNzID0gcGx1Z2luSG9va3MudGhlbWVDbGFzc2VzW29wdGlvbnMudGhlbWVTeXN0ZW1dIHx8IFN0YW5kYXJkVGhlbWU7XG4gICAgcmV0dXJuIG5ldyBUaGVtZUNsYXNzKG9wdGlvbnMpO1xufVxuZnVuY3Rpb24gYnVpbGREYXRlUHJvZmlsZUdlbmVyYXRvcihwcm9wcykge1xuICAgIGxldCBEYXRlUHJvZmlsZUdlbmVyYXRvckNsYXNzID0gcHJvcHMuZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzcyB8fCBEYXRlUHJvZmlsZUdlbmVyYXRvcjtcbiAgICByZXR1cm4gbmV3IERhdGVQcm9maWxlR2VuZXJhdG9yQ2xhc3MocHJvcHMpO1xufVxuZnVuY3Rpb24gYnVpbGRWaWV3QXBpKHR5cGUsIGdldEN1cnJlbnREYXRhLCBkYXRlRW52KSB7XG4gICAgcmV0dXJuIG5ldyBWaWV3SW1wbCh0eXBlLCBnZXRDdXJyZW50RGF0YSwgZGF0ZUVudik7XG59XG5mdW5jdGlvbiBidWlsZEV2ZW50VWlCeVNvdXJjZShldmVudFNvdXJjZXMpIHtcbiAgICByZXR1cm4gbWFwSGFzaChldmVudFNvdXJjZXMsIChldmVudFNvdXJjZSkgPT4gZXZlbnRTb3VyY2UudWkpO1xufVxuZnVuY3Rpb24gYnVpbGRFdmVudFVpQmFzZXMoZXZlbnREZWZzLCBldmVudFVpU2luZ2xlQmFzZSwgZXZlbnRVaUJ5U291cmNlKSB7XG4gICAgbGV0IGV2ZW50VWlCYXNlcyA9IHsgJyc6IGV2ZW50VWlTaW5nbGVCYXNlIH07XG4gICAgZm9yIChsZXQgZGVmSWQgaW4gZXZlbnREZWZzKSB7XG4gICAgICAgIGxldCBkZWYgPSBldmVudERlZnNbZGVmSWRdO1xuICAgICAgICBpZiAoZGVmLnNvdXJjZUlkICYmIGV2ZW50VWlCeVNvdXJjZVtkZWYuc291cmNlSWRdKSB7XG4gICAgICAgICAgICBldmVudFVpQmFzZXNbZGVmSWRdID0gZXZlbnRVaUJ5U291cmNlW2RlZi5zb3VyY2VJZF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGV2ZW50VWlCYXNlcztcbn1cbmZ1bmN0aW9uIGJ1aWxkVmlld1VpUHJvcHMoY2FsZW5kYXJDb250ZXh0KSB7XG4gICAgbGV0IHsgb3B0aW9ucyB9ID0gY2FsZW5kYXJDb250ZXh0O1xuICAgIHJldHVybiB7XG4gICAgICAgIGV2ZW50VWlTaW5nbGVCYXNlOiBjcmVhdGVFdmVudFVpKHtcbiAgICAgICAgICAgIGRpc3BsYXk6IG9wdGlvbnMuZXZlbnREaXNwbGF5LFxuICAgICAgICAgICAgZWRpdGFibGU6IG9wdGlvbnMuZWRpdGFibGUsXG4gICAgICAgICAgICBzdGFydEVkaXRhYmxlOiBvcHRpb25zLmV2ZW50U3RhcnRFZGl0YWJsZSxcbiAgICAgICAgICAgIGR1cmF0aW9uRWRpdGFibGU6IG9wdGlvbnMuZXZlbnREdXJhdGlvbkVkaXRhYmxlLFxuICAgICAgICAgICAgY29uc3RyYWludDogb3B0aW9ucy5ldmVudENvbnN0cmFpbnQsXG4gICAgICAgICAgICBvdmVybGFwOiB0eXBlb2Ygb3B0aW9ucy5ldmVudE92ZXJsYXAgPT09ICdib29sZWFuJyA/IG9wdGlvbnMuZXZlbnRPdmVybGFwIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYWxsb3c6IG9wdGlvbnMuZXZlbnRBbGxvdyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5ldmVudEJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiBvcHRpb25zLmV2ZW50Qm9yZGVyQ29sb3IsXG4gICAgICAgICAgICB0ZXh0Q29sb3I6IG9wdGlvbnMuZXZlbnRUZXh0Q29sb3IsXG4gICAgICAgICAgICBjb2xvcjogb3B0aW9ucy5ldmVudENvbG9yLFxuICAgICAgICAgICAgLy8gY2xhc3NOYW1lczogb3B0aW9ucy5ldmVudENsYXNzTmFtZXMgLy8gcmVuZGVyIGhvb2sgd2lsbCBoYW5kbGUgdGhpc1xuICAgICAgICB9LCBjYWxlbmRhckNvbnRleHQpLFxuICAgICAgICBzZWxlY3Rpb25Db25maWc6IGNyZWF0ZUV2ZW50VWkoe1xuICAgICAgICAgICAgY29uc3RyYWludDogb3B0aW9ucy5zZWxlY3RDb25zdHJhaW50LFxuICAgICAgICAgICAgb3ZlcmxhcDogdHlwZW9mIG9wdGlvbnMuc2VsZWN0T3ZlcmxhcCA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5zZWxlY3RPdmVybGFwIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgYWxsb3c6IG9wdGlvbnMuc2VsZWN0QWxsb3csXG4gICAgICAgIH0sIGNhbGVuZGFyQ29udGV4dCksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVJc0xvYWRpbmcoc3RhdGUsIGNvbnRleHQpIHtcbiAgICBmb3IgKGxldCBpc0xvYWRpbmdGdW5jIG9mIGNvbnRleHQucGx1Z2luSG9va3MuaXNMb2FkaW5nRnVuY3MpIHtcbiAgICAgICAgaWYgKGlzTG9hZGluZ0Z1bmMoc3RhdGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBwYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzKGNhbGVuZGFyQ29udGV4dCkge1xuICAgIHJldHVybiBwYXJzZUJ1c2luZXNzSG91cnMoY2FsZW5kYXJDb250ZXh0Lm9wdGlvbnMuYnVzaW5lc3NIb3VycywgY2FsZW5kYXJDb250ZXh0KTtcbn1cbmZ1bmN0aW9uIHdhcm5Vbmtub3duT3B0aW9ucyhvcHRpb25zLCB2aWV3TmFtZSkge1xuICAgIGZvciAobGV0IG9wdGlvbk5hbWUgaW4gb3B0aW9ucykge1xuICAgICAgICBjb25zb2xlLndhcm4oYFVua25vd24gb3B0aW9uICcke29wdGlvbk5hbWV9J2AgK1xuICAgICAgICAgICAgKHZpZXdOYW1lID8gYCBmb3IgdmlldyAnJHt2aWV3TmFtZX0nYCA6ICcnKSk7XG4gICAgfVxufVxuXG5jbGFzcyBUb29sYmFyU2VjdGlvbiBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IGNoaWxkcmVuID0gdGhpcy5wcm9wcy53aWRnZXRHcm91cHMubWFwKCh3aWRnZXRHcm91cCkgPT4gdGhpcy5yZW5kZXJXaWRnZXRHcm91cCh3aWRnZXRHcm91cCkpO1xuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgnZGl2JywgeyBjbGFzc05hbWU6ICdmYy10b29sYmFyLWNodW5rJyB9LCAuLi5jaGlsZHJlbik7XG4gICAgfVxuICAgIHJlbmRlcldpZGdldEdyb3VwKHdpZGdldEdyb3VwKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyB0aGVtZSB9ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgbGV0IGlzT25seUJ1dHRvbnMgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCB3aWRnZXQgb2Ygd2lkZ2V0R3JvdXApIHtcbiAgICAgICAgICAgIGxldCB7IGJ1dHRvbk5hbWUsIGJ1dHRvbkNsaWNrLCBidXR0b25UZXh0LCBidXR0b25JY29uLCBidXR0b25IaW50IH0gPSB3aWRnZXQ7XG4gICAgICAgICAgICBpZiAoYnV0dG9uTmFtZSA9PT0gJ3RpdGxlJykge1xuICAgICAgICAgICAgICAgIGlzT25seUJ1dHRvbnMgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNyZWF0ZUVsZW1lbnQoXCJoMlwiLCB7IGNsYXNzTmFtZTogXCJmYy10b29sYmFyLXRpdGxlXCIsIGlkOiBwcm9wcy50aXRsZUlkIH0sIHByb3BzLnRpdGxlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgaXNQcmVzc2VkID0gYnV0dG9uTmFtZSA9PT0gcHJvcHMuYWN0aXZlQnV0dG9uO1xuICAgICAgICAgICAgICAgIGxldCBpc0Rpc2FibGVkID0gKCFwcm9wcy5pc1RvZGF5RW5hYmxlZCAmJiBidXR0b25OYW1lID09PSAndG9kYXknKSB8fFxuICAgICAgICAgICAgICAgICAgICAoIXByb3BzLmlzUHJldkVuYWJsZWQgJiYgYnV0dG9uTmFtZSA9PT0gJ3ByZXYnKSB8fFxuICAgICAgICAgICAgICAgICAgICAoIXByb3BzLmlzTmV4dEVuYWJsZWQgJiYgYnV0dG9uTmFtZSA9PT0gJ25leHQnKTtcbiAgICAgICAgICAgICAgICBsZXQgYnV0dG9uQ2xhc3NlcyA9IFtgZmMtJHtidXR0b25OYW1lfS1idXR0b25gLCB0aGVtZS5nZXRDbGFzcygnYnV0dG9uJyldO1xuICAgICAgICAgICAgICAgIGlmIChpc1ByZXNzZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9uQ2xhc3Nlcy5wdXNoKHRoZW1lLmdldENsYXNzKCdidXR0b25BY3RpdmUnKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY3JlYXRlRWxlbWVudChcImJ1dHRvblwiLCB7IHR5cGU6IFwiYnV0dG9uXCIsIHRpdGxlOiB0eXBlb2YgYnV0dG9uSGludCA9PT0gJ2Z1bmN0aW9uJyA/IGJ1dHRvbkhpbnQocHJvcHMubmF2VW5pdCkgOiBidXR0b25IaW50LCBkaXNhYmxlZDogaXNEaXNhYmxlZCwgXCJhcmlhLXByZXNzZWRcIjogaXNQcmVzc2VkLCBjbGFzc05hbWU6IGJ1dHRvbkNsYXNzZXMuam9pbignICcpLCBvbkNsaWNrOiBidXR0b25DbGljayB9LCBidXR0b25UZXh0IHx8IChidXR0b25JY29uID8gY3JlYXRlRWxlbWVudChcInNwYW5cIiwgeyBjbGFzc05hbWU6IGJ1dHRvbkljb24sIHJvbGU6IFwiaW1nXCIgfSkgOiAnJykpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hpbGRyZW4ubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgbGV0IGdyb3VwQ2xhc3NOYW1lID0gKGlzT25seUJ1dHRvbnMgJiYgdGhlbWUuZ2V0Q2xhc3MoJ2J1dHRvbkdyb3VwJykpIHx8ICcnO1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgY2xhc3NOYW1lOiBncm91cENsYXNzTmFtZSB9LCAuLi5jaGlsZHJlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoaWxkcmVuWzBdO1xuICAgIH1cbn1cblxuY2xhc3MgVG9vbGJhciBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHsgbW9kZWwsIGV4dHJhQ2xhc3NOYW1lIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgZm9yY2VMdHIgPSBmYWxzZTtcbiAgICAgICAgbGV0IHN0YXJ0Q29udGVudDtcbiAgICAgICAgbGV0IGVuZENvbnRlbnQ7XG4gICAgICAgIGxldCBzZWN0aW9uV2lkZ2V0cyA9IG1vZGVsLnNlY3Rpb25XaWRnZXRzO1xuICAgICAgICBsZXQgY2VudGVyQ29udGVudCA9IHNlY3Rpb25XaWRnZXRzLmNlbnRlcjtcbiAgICAgICAgaWYgKHNlY3Rpb25XaWRnZXRzLmxlZnQpIHtcbiAgICAgICAgICAgIGZvcmNlTHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIHN0YXJ0Q29udGVudCA9IHNlY3Rpb25XaWRnZXRzLmxlZnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydENvbnRlbnQgPSBzZWN0aW9uV2lkZ2V0cy5zdGFydDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VjdGlvbldpZGdldHMucmlnaHQpIHtcbiAgICAgICAgICAgIGZvcmNlTHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIGVuZENvbnRlbnQgPSBzZWN0aW9uV2lkZ2V0cy5yaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVuZENvbnRlbnQgPSBzZWN0aW9uV2lkZ2V0cy5lbmQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICAgICBleHRyYUNsYXNzTmFtZSB8fCAnJyxcbiAgICAgICAgICAgICdmYy10b29sYmFyJyxcbiAgICAgICAgICAgIGZvcmNlTHRyID8gJ2ZjLXRvb2xiYXItbHRyJyA6ICcnLFxuICAgICAgICBdO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IGNsYXNzTmFtZXMuam9pbignICcpIH0sXG4gICAgICAgICAgICB0aGlzLnJlbmRlclNlY3Rpb24oJ3N0YXJ0Jywgc3RhcnRDb250ZW50IHx8IFtdKSxcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU2VjdGlvbignY2VudGVyJywgY2VudGVyQ29udGVudCB8fCBbXSksXG4gICAgICAgICAgICB0aGlzLnJlbmRlclNlY3Rpb24oJ2VuZCcsIGVuZENvbnRlbnQgfHwgW10pKSk7XG4gICAgfVxuICAgIHJlbmRlclNlY3Rpb24oa2V5LCB3aWRnZXRHcm91cHMpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChUb29sYmFyU2VjdGlvbiwgeyBrZXk6IGtleSwgd2lkZ2V0R3JvdXBzOiB3aWRnZXRHcm91cHMsIHRpdGxlOiBwcm9wcy50aXRsZSwgbmF2VW5pdDogcHJvcHMubmF2VW5pdCwgYWN0aXZlQnV0dG9uOiBwcm9wcy5hY3RpdmVCdXR0b24sIGlzVG9kYXlFbmFibGVkOiBwcm9wcy5pc1RvZGF5RW5hYmxlZCwgaXNQcmV2RW5hYmxlZDogcHJvcHMuaXNQcmV2RW5hYmxlZCwgaXNOZXh0RW5hYmxlZDogcHJvcHMuaXNOZXh0RW5hYmxlZCwgdGl0bGVJZDogcHJvcHMudGl0bGVJZCB9KSk7XG4gICAgfVxufVxuXG5jbGFzcyBWaWV3SGFybmVzcyBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgYXZhaWxhYmxlV2lkdGg6IG51bGwsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlRWwgPSAoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZWwgPSBlbDtcbiAgICAgICAgICAgIHNldFJlZih0aGlzLnByb3BzLmVsUmVmLCBlbCk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUF2YWlsYWJsZVdpZHRoKCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUmVzaXplID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVXaWR0aCgpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgYXNwZWN0UmF0aW8gfSA9IHByb3BzO1xuICAgICAgICBsZXQgY2xhc3NOYW1lcyA9IFtcbiAgICAgICAgICAgICdmYy12aWV3LWhhcm5lc3MnLFxuICAgICAgICAgICAgKGFzcGVjdFJhdGlvIHx8IHByb3BzLmxpcXVpZCB8fCBwcm9wcy5oZWlnaHQpXG4gICAgICAgICAgICAgICAgPyAnZmMtdmlldy1oYXJuZXNzLWFjdGl2ZScgLy8gaGFybmVzcyBjb250cm9scyB0aGUgaGVpZ2h0XG4gICAgICAgICAgICAgICAgOiAnZmMtdmlldy1oYXJuZXNzLXBhc3NpdmUnLCAvLyBsZXQgdGhlIHZpZXcgZG8gdGhlIGhlaWdodFxuICAgICAgICBdO1xuICAgICAgICBsZXQgaGVpZ2h0ID0gJyc7XG4gICAgICAgIGxldCBwYWRkaW5nQm90dG9tID0gJyc7XG4gICAgICAgIGlmIChhc3BlY3RSYXRpbykge1xuICAgICAgICAgICAgaWYgKHN0YXRlLmF2YWlsYWJsZVdpZHRoICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaGVpZ2h0ID0gc3RhdGUuYXZhaWxhYmxlV2lkdGggLyBhc3BlY3RSYXRpbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHdoaWxlIHdhaXRpbmcgdG8ga25vdyBhdmFpbGFibGVXaWR0aCwgd2UgY2FuJ3Qgc2V0IGhlaWdodCB0byAqemVybypcbiAgICAgICAgICAgICAgICAvLyBiZWNhdXNlIHdpbGwgY2F1c2UgbG90cyBvZiB1bm5lY2Vzc2FyeSBzY3JvbGxiYXJzIHdpdGhpbiBzY3JvbGxncmlkLlxuICAgICAgICAgICAgICAgIC8vIEJFVFRFUjogZG9uJ3Qgc3RhcnQgcmVuZGVyaW5nIEFOWVRISU5HIHlldCB1bnRpbCB3ZSBrbm93IGNvbnRhaW5lciB3aWR0aFxuICAgICAgICAgICAgICAgIC8vIE5PVEU6IHdoeSBub3QgYWx3YXlzIHVzZSBwYWRkaW5nQm90dG9tPyBDYXVzZXMgaGVpZ2h0IG9zY2lsbGF0aW9uIChpc3N1ZSA1NjA2KVxuICAgICAgICAgICAgICAgIHBhZGRpbmdCb3R0b20gPSBgJHsoMSAvIGFzcGVjdFJhdGlvKSAqIDEwMH0lYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhlaWdodCA9IHByb3BzLmhlaWdodCB8fCAnJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBcImFyaWEtbGFiZWxsZWRieVwiOiBwcm9wcy5sYWJlbGVkQnlJZCwgcmVmOiB0aGlzLmhhbmRsZUVsLCBjbGFzc05hbWU6IGNsYXNzTmFtZXMuam9pbignICcpLCBzdHlsZTogeyBoZWlnaHQsIHBhZGRpbmdCb3R0b20gfSB9LCBwcm9wcy5jaGlsZHJlbikpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZFJlc2l6ZUhhbmRsZXIodGhpcy5oYW5kbGVSZXNpemUpO1xuICAgIH1cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnJlbW92ZVJlc2l6ZUhhbmRsZXIodGhpcy5oYW5kbGVSZXNpemUpO1xuICAgIH1cbiAgICB1cGRhdGVBdmFpbGFibGVXaWR0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuZWwgJiYgLy8gbmVlZGVkLiBidXQgd2h5P1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5hc3BlY3RSYXRpbyAvLyBhc3BlY3RSYXRpbyBpcyB0aGUgb25seSBoZWlnaHQgc2V0dGluZyB0aGF0IG5lZWRzIGF2YWlsYWJsZVdpZHRoXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGF2YWlsYWJsZVdpZHRoOiB0aGlzLmVsLm9mZnNldFdpZHRoIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKlxuRGV0ZWN0cyB3aGVuIHRoZSB1c2VyIGNsaWNrcyBvbiBhbiBldmVudCB3aXRoaW4gYSBEYXRlQ29tcG9uZW50XG4qL1xuY2xhc3MgRXZlbnRDbGlja2luZyBleHRlbmRzIEludGVyYWN0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncykge1xuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XG4gICAgICAgIHRoaXMuaGFuZGxlU2VnQ2xpY2sgPSAoZXYsIHNlZ0VsKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBjb21wb25lbnQgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgeyBjb250ZXh0IH0gPSBjb21wb25lbnQ7XG4gICAgICAgICAgICBsZXQgc2VnID0gZ2V0RWxTZWcoc2VnRWwpO1xuICAgICAgICAgICAgaWYgKHNlZyAmJiAvLyBtaWdodCBiZSB0aGUgPGRpdj4gc3Vycm91bmRpbmcgdGhlIG1vcmUgbGlua1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5pc1ZhbGlkU2VnRG93bkVsKGV2LnRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICAvLyBvdXIgd2F5IHRvIHNpbXVsYXRlIGEgbGluayBjbGljayBmb3IgZWxlbWVudHMgdGhhdCBjYW4ndCBiZSA8YT4gdGFnc1xuICAgICAgICAgICAgICAgIC8vIGdyYWIgYmVmb3JlIHRyaWdnZXIgZmlyZWQgaW4gY2FzZSB0cmlnZ2VyIHRyYXNoZXMgRE9NIHRocnUgcmVyZW5kZXJpbmdcbiAgICAgICAgICAgICAgICBsZXQgaGFzVXJsQ29udGFpbmVyID0gZWxlbWVudENsb3Nlc3QoZXYudGFyZ2V0LCAnLmZjLWV2ZW50LWZvcmNlZC11cmwnKTtcbiAgICAgICAgICAgICAgICBsZXQgdXJsID0gaGFzVXJsQ29udGFpbmVyID8gaGFzVXJsQ29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ2FbaHJlZl0nKS5ocmVmIDogJyc7XG4gICAgICAgICAgICAgICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50Q2xpY2snLCB7XG4gICAgICAgICAgICAgICAgICAgIGVsOiBzZWdFbCxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQ6IG5ldyBFdmVudEltcGwoY29tcG9uZW50LmNvbnRleHQsIHNlZy5ldmVudFJhbmdlLmRlZiwgc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UpLFxuICAgICAgICAgICAgICAgICAgICBqc0V2ZW50OiBldixcbiAgICAgICAgICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmICh1cmwgJiYgIWV2LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSB1cmw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmRlc3Ryb3kgPSBsaXN0ZW5CeVNlbGVjdG9yKHNldHRpbmdzLmVsLCAnY2xpY2snLCAnLmZjLWV2ZW50JywgLy8gb24gYm90aCBmZyBhbmQgYmcgZXZlbnRzXG4gICAgICAgIHRoaXMuaGFuZGxlU2VnQ2xpY2spO1xuICAgIH1cbn1cblxuLypcblRyaWdnZXJzIGV2ZW50cyBhbmQgYWRkcy9yZW1vdmVzIGNvcmUgY2xhc3NOYW1lcyB3aGVuIHRoZSB1c2VyJ3MgcG9pbnRlclxuZW50ZXJzL2xlYXZlcyBldmVudC1lbGVtZW50cyBvZiBhIGNvbXBvbmVudC5cbiovXG5jbGFzcyBFdmVudEhvdmVyaW5nIGV4dGVuZHMgSW50ZXJhY3Rpb24ge1xuICAgIGNvbnN0cnVjdG9yKHNldHRpbmdzKSB7XG4gICAgICAgIHN1cGVyKHNldHRpbmdzKTtcbiAgICAgICAgLy8gZm9yIHNpbXVsYXRpbmcgYW4gZXZlbnRNb3VzZUxlYXZlIHdoZW4gdGhlIGV2ZW50IGVsIGlzIGRlc3Ryb3llZCB3aGlsZSBtb3VzZSBpcyBvdmVyIGl0XG4gICAgICAgIHRoaXMuaGFuZGxlRXZlbnRFbFJlbW92ZSA9IChlbCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsID09PSB0aGlzLmN1cnJlbnRTZWdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlU2VnTGVhdmUobnVsbCwgdGhpcy5jdXJyZW50U2VnRWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVNlZ0VudGVyID0gKGV2LCBzZWdFbCkgPT4ge1xuICAgICAgICAgICAgaWYgKGdldEVsU2VnKHNlZ0VsKSkgeyAvLyBUT0RPOiBiZXR0ZXIgd2F5IHRvIG1ha2Ugc3VyZSBub3QgaG92ZXJpbmcgb3ZlciBtb3JlKyBsaW5rIG9yIGl0cyB3cmFwcGVyXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2VnRWwgPSBzZWdFbDtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJFdmVudCgnZXZlbnRNb3VzZUVudGVyJywgZXYsIHNlZ0VsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVTZWdMZWF2ZSA9IChldiwgc2VnRWwpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRTZWdFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFNlZ0VsID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJFdmVudCgnZXZlbnRNb3VzZUxlYXZlJywgZXYsIHNlZ0VsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5yZW1vdmVIb3Zlckxpc3RlbmVycyA9IGxpc3RlblRvSG92ZXJCeVNlbGVjdG9yKHNldHRpbmdzLmVsLCAnLmZjLWV2ZW50JywgLy8gb24gYm90aCBmZyBhbmQgYmcgZXZlbnRzXG4gICAgICAgIHRoaXMuaGFuZGxlU2VnRW50ZXIsIHRoaXMuaGFuZGxlU2VnTGVhdmUpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLnJlbW92ZUhvdmVyTGlzdGVuZXJzKCk7XG4gICAgfVxuICAgIHRyaWdnZXJFdmVudChwdWJsaWNFdk5hbWUsIGV2LCBzZWdFbCkge1xuICAgICAgICBsZXQgeyBjb21wb25lbnQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IGNvbnRleHQgfSA9IGNvbXBvbmVudDtcbiAgICAgICAgbGV0IHNlZyA9IGdldEVsU2VnKHNlZ0VsKTtcbiAgICAgICAgaWYgKCFldiB8fCBjb21wb25lbnQuaXNWYWxpZFNlZ0Rvd25FbChldi50YXJnZXQpKSB7XG4gICAgICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcihwdWJsaWNFdk5hbWUsIHtcbiAgICAgICAgICAgICAgICBlbDogc2VnRWwsXG4gICAgICAgICAgICAgICAgZXZlbnQ6IG5ldyBFdmVudEltcGwoY29udGV4dCwgc2VnLmV2ZW50UmFuZ2UuZGVmLCBzZWcuZXZlbnRSYW5nZS5pbnN0YW5jZSksXG4gICAgICAgICAgICAgICAganNFdmVudDogZXYsXG4gICAgICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIENhbGVuZGFyQ29udGVudCBleHRlbmRzIFB1cmVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmJ1aWxkVmlld0NvbnRleHQgPSBtZW1vaXplKGJ1aWxkVmlld0NvbnRleHQpO1xuICAgICAgICB0aGlzLmJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnMgPSBtZW1vaXplKGJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnMpO1xuICAgICAgICB0aGlzLmJ1aWxkVG9vbGJhclByb3BzID0gbWVtb2l6ZShidWlsZFRvb2xiYXJQcm9wcyk7XG4gICAgICAgIHRoaXMuaGVhZGVyUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMuZm9vdGVyUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMuaW50ZXJhY3Rpb25zU3RvcmUgPSB7fTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICB2aWV3TGFiZWxJZDogZ2V0VW5pcXVlRG9tSWQoKSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gQ29tcG9uZW50IFJlZ2lzdHJhdGlvblxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQgPSAoY29tcG9uZW50LCBzZXR0aW5nc0lucHV0KSA9PiB7XG4gICAgICAgICAgICBsZXQgc2V0dGluZ3MgPSBwYXJzZUludGVyYWN0aW9uU2V0dGluZ3MoY29tcG9uZW50LCBzZXR0aW5nc0lucHV0KTtcbiAgICAgICAgICAgIGxldCBERUZBVUxUX0lOVEVSQUNUSU9OUyA9IFtcbiAgICAgICAgICAgICAgICBFdmVudENsaWNraW5nLFxuICAgICAgICAgICAgICAgIEV2ZW50SG92ZXJpbmcsXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgbGV0IGludGVyYWN0aW9uQ2xhc3NlcyA9IERFRkFVTFRfSU5URVJBQ1RJT05TLmNvbmNhdCh0aGlzLnByb3BzLnBsdWdpbkhvb2tzLmNvbXBvbmVudEludGVyYWN0aW9ucyk7XG4gICAgICAgICAgICBsZXQgaW50ZXJhY3Rpb25zID0gaW50ZXJhY3Rpb25DbGFzc2VzLm1hcCgoVGhlSW50ZXJhY3Rpb25DbGFzcykgPT4gbmV3IFRoZUludGVyYWN0aW9uQ2xhc3Moc2V0dGluZ3MpKTtcbiAgICAgICAgICAgIHRoaXMuaW50ZXJhY3Rpb25zU3RvcmVbY29tcG9uZW50LnVpZF0gPSBpbnRlcmFjdGlvbnM7XG4gICAgICAgICAgICBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmVbY29tcG9uZW50LnVpZF0gPSBzZXR0aW5ncztcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy51bnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQgPSAoY29tcG9uZW50KSA9PiB7XG4gICAgICAgICAgICBsZXQgbGlzdGVuZXJzID0gdGhpcy5pbnRlcmFjdGlvbnNTdG9yZVtjb21wb25lbnQudWlkXTtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBsaXN0ZW5lciBvZiBsaXN0ZW5lcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIuZGVzdHJveSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5pbnRlcmFjdGlvbnNTdG9yZVtjb21wb25lbnQudWlkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbGV0ZSBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmVbY29tcG9uZW50LnVpZF07XG4gICAgICAgIH07XG4gICAgICAgIC8vIFJlc2l6aW5nXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMucmVzaXplUnVubmVyID0gbmV3IERlbGF5ZWRSdW5uZXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5lbWl0dGVyLnRyaWdnZXIoJ19yZXNpemUnLCB0cnVlKTsgLy8gc2hvdWxkIHdpbmRvdyByZXNpemVzIGJlIGNvbnNpZGVyZWQgXCJmb3JjZWRcIiA/XG4gICAgICAgICAgICB0aGlzLnByb3BzLmVtaXR0ZXIudHJpZ2dlcignd2luZG93UmVzaXplJywgeyB2aWV3OiB0aGlzLnByb3BzLnZpZXdBcGkgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhbmRsZVdpbmRvd1Jlc2l6ZSA9IChldikgPT4ge1xuICAgICAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgICAgIGlmIChvcHRpb25zLmhhbmRsZVdpbmRvd1Jlc2l6ZSAmJlxuICAgICAgICAgICAgICAgIGV2LnRhcmdldCA9PT0gd2luZG93IC8vIGF2b2lkIGpxdWkgZXZlbnRzXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZVJ1bm5lci5yZXF1ZXN0KG9wdGlvbnMud2luZG93UmVzaXplRGVsYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKlxuICAgIHJlbmRlcnMgSU5TSURFIG9mIGFuIG91dGVyIGRpdlxuICAgICovXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgdG9vbGJhckNvbmZpZywgb3B0aW9ucyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCB2aWV3Vkdyb3cgPSBmYWxzZTtcbiAgICAgICAgbGV0IHZpZXdIZWlnaHQgPSAnJztcbiAgICAgICAgbGV0IHZpZXdBc3BlY3RSYXRpbztcbiAgICAgICAgaWYgKHByb3BzLmlzSGVpZ2h0QXV0byB8fCBwcm9wcy5mb3JQcmludCkge1xuICAgICAgICAgICAgdmlld0hlaWdodCA9ICcnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuaGVpZ2h0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZpZXdWR3JvdyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5jb250ZW50SGVpZ2h0ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHZpZXdIZWlnaHQgPSBvcHRpb25zLmNvbnRlbnRIZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2aWV3QXNwZWN0UmF0aW8gPSBNYXRoLm1heChvcHRpb25zLmFzcGVjdFJhdGlvLCAwLjUpOyAvLyBwcmV2ZW50IGZyb20gZ2V0dGluZyB0b28gdGFsbFxuICAgICAgICB9XG4gICAgICAgIGxldCB2aWV3Q29udGV4dCA9IHRoaXMuYnVpbGRWaWV3Q29udGV4dChwcm9wcy52aWV3U3BlYywgcHJvcHMudmlld0FwaSwgcHJvcHMub3B0aW9ucywgcHJvcHMuZGF0ZVByb2ZpbGVHZW5lcmF0b3IsIHByb3BzLmRhdGVFbnYsIHByb3BzLm5vd01hbmFnZXIsIHByb3BzLnRoZW1lLCBwcm9wcy5wbHVnaW5Ib29rcywgcHJvcHMuZGlzcGF0Y2gsIHByb3BzLmdldEN1cnJlbnREYXRhLCBwcm9wcy5lbWl0dGVyLCBwcm9wcy5jYWxlbmRhckFwaSwgdGhpcy5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50LCB0aGlzLnVucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCk7XG4gICAgICAgIGxldCB2aWV3TGFiZWxJZCA9ICh0b29sYmFyQ29uZmlnLmhlYWRlciAmJiB0b29sYmFyQ29uZmlnLmhlYWRlci5oYXNUaXRsZSlcbiAgICAgICAgICAgID8gdGhpcy5zdGF0ZS52aWV3TGFiZWxJZFxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChWaWV3Q29udGV4dFR5cGUuUHJvdmlkZXIsIHsgdmFsdWU6IHZpZXdDb250ZXh0IH0sXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KE5vd1RpbWVyLCB7IHVuaXQ6IFwiZGF5XCIgfSwgKG5vd0RhdGUpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgdG9vbGJhclByb3BzID0gdGhpcy5idWlsZFRvb2xiYXJQcm9wcyhwcm9wcy52aWV3U3BlYywgcHJvcHMuZGF0ZVByb2ZpbGUsIHByb3BzLmRhdGVQcm9maWxlR2VuZXJhdG9yLCBwcm9wcy5jdXJyZW50RGF0ZSwgbm93RGF0ZSwgcHJvcHMudmlld1RpdGxlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRvb2xiYXJDb25maWcuaGVhZGVyICYmIChjcmVhdGVFbGVtZW50KFRvb2xiYXIsIE9iamVjdC5hc3NpZ24oeyByZWY6IHRoaXMuaGVhZGVyUmVmLCBleHRyYUNsYXNzTmFtZTogXCJmYy1oZWFkZXItdG9vbGJhclwiLCBtb2RlbDogdG9vbGJhckNvbmZpZy5oZWFkZXIsIHRpdGxlSWQ6IHZpZXdMYWJlbElkIH0sIHRvb2xiYXJQcm9wcykpKSxcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChWaWV3SGFybmVzcywgeyBsaXF1aWQ6IHZpZXdWR3JvdywgaGVpZ2h0OiB2aWV3SGVpZ2h0LCBhc3BlY3RSYXRpbzogdmlld0FzcGVjdFJhdGlvLCBsYWJlbGVkQnlJZDogdmlld0xhYmVsSWQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyVmlldyhwcm9wcyksXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkQXBwZW5kQ29udGVudCgpKSxcbiAgICAgICAgICAgICAgICAgICAgdG9vbGJhckNvbmZpZy5mb290ZXIgJiYgKGNyZWF0ZUVsZW1lbnQoVG9vbGJhciwgT2JqZWN0LmFzc2lnbih7IHJlZjogdGhpcy5mb290ZXJSZWYsIGV4dHJhQ2xhc3NOYW1lOiBcImZjLWZvb3Rlci10b29sYmFyXCIsIG1vZGVsOiB0b29sYmFyQ29uZmlnLmZvb3RlciwgdGl0bGVJZDogXCJcIiB9LCB0b29sYmFyUHJvcHMpKSkpKTtcbiAgICAgICAgICAgIH0pKSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgdGhpcy5jYWxlbmRhckludGVyYWN0aW9ucyA9IHByb3BzLnBsdWdpbkhvb2tzLmNhbGVuZGFySW50ZXJhY3Rpb25zXG4gICAgICAgICAgICAubWFwKChDYWxlbmRhckludGVyYWN0aW9uQ2xhc3MpID0+IG5ldyBDYWxlbmRhckludGVyYWN0aW9uQ2xhc3MocHJvcHMpKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuaGFuZGxlV2luZG93UmVzaXplKTtcbiAgICAgICAgbGV0IHsgcHJvcFNldEhhbmRsZXJzIH0gPSBwcm9wcy5wbHVnaW5Ib29rcztcbiAgICAgICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gcHJvcFNldEhhbmRsZXJzKSB7XG4gICAgICAgICAgICBwcm9wU2V0SGFuZGxlcnNbcHJvcE5hbWVdKHByb3BzW3Byb3BOYW1lXSwgcHJvcHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHByb3BTZXRIYW5kbGVycyB9ID0gcHJvcHMucGx1Z2luSG9va3M7XG4gICAgICAgIGZvciAobGV0IHByb3BOYW1lIGluIHByb3BTZXRIYW5kbGVycykge1xuICAgICAgICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSAhPT0gcHJldlByb3BzW3Byb3BOYW1lXSkge1xuICAgICAgICAgICAgICAgIHByb3BTZXRIYW5kbGVyc1twcm9wTmFtZV0ocHJvcHNbcHJvcE5hbWVdLCBwcm9wcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLmhhbmRsZVdpbmRvd1Jlc2l6ZSk7XG4gICAgICAgIHRoaXMucmVzaXplUnVubmVyLmNsZWFyKCk7XG4gICAgICAgIGZvciAobGV0IGludGVyYWN0aW9uIG9mIHRoaXMuY2FsZW5kYXJJbnRlcmFjdGlvbnMpIHtcbiAgICAgICAgICAgIGludGVyYWN0aW9uLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb3BzLmVtaXR0ZXIudHJpZ2dlcignX3VubW91bnQnKTtcbiAgICB9XG4gICAgYnVpbGRBcHBlbmRDb250ZW50KCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGNoaWxkcmVuID0gcHJvcHMucGx1Z2luSG9va3Mudmlld0NvbnRhaW5lckFwcGVuZHMubWFwKChidWlsZEFwcGVuZENvbnRlbnQpID0+IGJ1aWxkQXBwZW5kQ29udGVudChwcm9wcykpO1xuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudChGcmFnbWVudCwge30sIC4uLmNoaWxkcmVuKTtcbiAgICB9XG4gICAgcmVuZGVyVmlldyhwcm9wcykge1xuICAgICAgICBsZXQgeyBwbHVnaW5Ib29rcyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCB7IHZpZXdTcGVjIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHZpZXdQcm9wcyA9IHtcbiAgICAgICAgICAgIGRhdGVQcm9maWxlOiBwcm9wcy5kYXRlUHJvZmlsZSxcbiAgICAgICAgICAgIGJ1c2luZXNzSG91cnM6IHByb3BzLmJ1c2luZXNzSG91cnMsXG4gICAgICAgICAgICBldmVudFN0b3JlOiBwcm9wcy5yZW5kZXJhYmxlRXZlbnRTdG9yZSxcbiAgICAgICAgICAgIGV2ZW50VWlCYXNlczogcHJvcHMuZXZlbnRVaUJhc2VzLFxuICAgICAgICAgICAgZGF0ZVNlbGVjdGlvbjogcHJvcHMuZGF0ZVNlbGVjdGlvbixcbiAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbixcbiAgICAgICAgICAgIGV2ZW50RHJhZzogcHJvcHMuZXZlbnREcmFnLFxuICAgICAgICAgICAgZXZlbnRSZXNpemU6IHByb3BzLmV2ZW50UmVzaXplLFxuICAgICAgICAgICAgaXNIZWlnaHRBdXRvOiBwcm9wcy5pc0hlaWdodEF1dG8sXG4gICAgICAgICAgICBmb3JQcmludDogcHJvcHMuZm9yUHJpbnQsXG4gICAgICAgIH07XG4gICAgICAgIGxldCB0cmFuc2Zvcm1lcnMgPSB0aGlzLmJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnMocGx1Z2luSG9va3Mudmlld1Byb3BzVHJhbnNmb3JtZXJzKTtcbiAgICAgICAgZm9yIChsZXQgdHJhbnNmb3JtZXIgb2YgdHJhbnNmb3JtZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHZpZXdQcm9wcywgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHZpZXdQcm9wcywgcHJvcHMpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgVmlld0NvbXBvbmVudCA9IHZpZXdTcGVjLmNvbXBvbmVudDtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb21wb25lbnQsIE9iamVjdC5hc3NpZ24oe30sIHZpZXdQcm9wcykpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBidWlsZFRvb2xiYXJQcm9wcyh2aWV3U3BlYywgZGF0ZVByb2ZpbGUsIGRhdGVQcm9maWxlR2VuZXJhdG9yLCBjdXJyZW50RGF0ZSwgbm93LCB0aXRsZSkge1xuICAgIC8vIGRvbid0IGZvcmNlIGFueSBkYXRlLXByb2ZpbGVzIHRvIHZhbGlkIGRhdGUgcHJvZmlsZXMgKHRoZSBgZmFsc2VgKSBzbyB0aGF0IHdlIGNhbiB0ZWxsIGlmIGl0J3MgaW52YWxpZFxuICAgIGxldCB0b2RheUluZm8gPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZChub3csIHVuZGVmaW5lZCwgZmFsc2UpOyAvLyBUT0RPOiBuZWVkIGB1bmRlZmluZWRgIG9yIGVsc2UgSU5GSU5JVEUgTE9PUCBmb3Igc29tZSByZWFzb25cbiAgICBsZXQgcHJldkluZm8gPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZFByZXYoZGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlLCBmYWxzZSk7XG4gICAgbGV0IG5leHRJbmZvID0gZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGROZXh0KGRhdGVQcm9maWxlLCBjdXJyZW50RGF0ZSwgZmFsc2UpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHRpdGxlLFxuICAgICAgICBhY3RpdmVCdXR0b246IHZpZXdTcGVjLnR5cGUsXG4gICAgICAgIG5hdlVuaXQ6IHZpZXdTcGVjLnNpbmdsZVVuaXQsXG4gICAgICAgIGlzVG9kYXlFbmFibGVkOiB0b2RheUluZm8uaXNWYWxpZCAmJiAhcmFuZ2VDb250YWluc01hcmtlcihkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UsIG5vdyksXG4gICAgICAgIGlzUHJldkVuYWJsZWQ6IHByZXZJbmZvLmlzVmFsaWQsXG4gICAgICAgIGlzTmV4dEVuYWJsZWQ6IG5leHRJbmZvLmlzVmFsaWQsXG4gICAgfTtcbn1cbi8vIFBsdWdpblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnModGhlQ2xhc3Nlcykge1xuICAgIHJldHVybiB0aGVDbGFzc2VzLm1hcCgoVGhlQ2xhc3MpID0+IG5ldyBUaGVDbGFzcygpKTtcbn1cblxuY2xhc3MgQ2FsZW5kYXIgZXh0ZW5kcyBDYWxlbmRhckltcGwge1xuICAgIGNvbnN0cnVjdG9yKGVsLCBvcHRpb25PdmVycmlkZXMgPSB7fSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmlzUmVuZGVyaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNSZW5kZXJlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRDbGFzc05hbWVzID0gW107XG4gICAgICAgIHRoaXMuY3VzdG9tQ29udGVudFJlbmRlcklkID0gMDtcbiAgICAgICAgdGhpcy5oYW5kbGVBY3Rpb24gPSAoYWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAvLyBhY3Rpb25zIHdlIGtub3cgd2Ugd2FudCB0byByZW5kZXIgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdTRVRfRVZFTlRfRFJBRyc6XG4gICAgICAgICAgICAgICAgY2FzZSAnU0VUX0VWRU5UX1JFU0laRSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnRyeURyYWluKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlRGF0YSA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnREYXRhID0gZGF0YTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlcXVlc3QoZGF0YS5jYWxlbmRhck9wdGlvbnMucmVyZW5kZXJEZWxheSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUmVuZGVyUmVxdWVzdCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzUmVuZGVyaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1JlbmRlcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsZXQgeyBjdXJyZW50RGF0YSB9ID0gdGhpcztcbiAgICAgICAgICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZW5kZXIoY3JlYXRlRWxlbWVudChDYWxlbmRhclJvb3QsIHsgb3B0aW9uczogY3VycmVudERhdGEuY2FsZW5kYXJPcHRpb25zLCB0aGVtZTogY3VycmVudERhdGEudGhlbWUsIGVtaXR0ZXI6IGN1cnJlbnREYXRhLmVtaXR0ZXIgfSwgKGNsYXNzTmFtZXMsIGhlaWdodCwgaXNIZWlnaHRBdXRvLCBmb3JQcmludCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRIZWlnaHQoaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChSZW5kZXJJZC5Qcm92aWRlciwgeyB2YWx1ZTogdGhpcy5jdXN0b21Db250ZW50UmVuZGVySWQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KENhbGVuZGFyQ29udGVudCwgT2JqZWN0LmFzc2lnbih7IGlzSGVpZ2h0QXV0bzogaXNIZWlnaHRBdXRvLCBmb3JQcmludDogZm9yUHJpbnQgfSwgY3VycmVudERhdGEpKSkpO1xuICAgICAgICAgICAgICAgICAgICB9KSwgdGhpcy5lbCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmlzUmVuZGVyZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzUmVuZGVyZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZW5kZXIobnVsbCwgdGhpcy5lbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDbGFzc05hbWVzKFtdKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEhlaWdodCgnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGVuc3VyZUVsSGFzU3R5bGVzKGVsKTtcbiAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lciA9IG5ldyBEZWxheWVkUnVubmVyKHRoaXMuaGFuZGxlUmVuZGVyUmVxdWVzdCk7XG4gICAgICAgIG5ldyBDYWxlbmRhckRhdGFNYW5hZ2VyKHtcbiAgICAgICAgICAgIG9wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiB0aGlzLFxuICAgICAgICAgICAgb25BY3Rpb246IHRoaXMuaGFuZGxlQWN0aW9uLFxuICAgICAgICAgICAgb25EYXRhOiB0aGlzLmhhbmRsZURhdGEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB3YXNSZW5kZXJpbmcgPSB0aGlzLmlzUmVuZGVyaW5nO1xuICAgICAgICBpZiAoIXdhc1JlbmRlcmluZykge1xuICAgICAgICAgICAgdGhpcy5pc1JlbmRlcmluZyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1c3RvbUNvbnRlbnRSZW5kZXJJZCArPSAxO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlcXVlc3QoKTtcbiAgICAgICAgaWYgKHdhc1JlbmRlcmluZykge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVTaXplKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNSZW5kZXJpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuaXNSZW5kZXJpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlcXVlc3QoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVTaXplKCkge1xuICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgc3VwZXIudXBkYXRlU2l6ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgYmF0Y2hSZW5kZXJpbmcoZnVuYykge1xuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5wYXVzZSgnYmF0Y2hSZW5kZXJpbmcnKTtcbiAgICAgICAgZnVuYygpO1xuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5yZXN1bWUoJ2JhdGNoUmVuZGVyaW5nJyk7XG4gICAgfVxuICAgIHBhdXNlUmVuZGVyaW5nKCkge1xuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5wYXVzZSgncGF1c2VSZW5kZXJpbmcnKTtcbiAgICB9XG4gICAgcmVzdW1lUmVuZGVyaW5nKCkge1xuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5yZXN1bWUoJ3BhdXNlUmVuZGVyaW5nJywgdHJ1ZSk7XG4gICAgfVxuICAgIHJlc2V0T3B0aW9ucyhvcHRpb25PdmVycmlkZXMsIGNoYW5nZWRPcHRpb25OYW1lcykge1xuICAgICAgICB0aGlzLmN1cnJlbnREYXRhTWFuYWdlci5yZXNldE9wdGlvbnMob3B0aW9uT3ZlcnJpZGVzLCBjaGFuZ2VkT3B0aW9uTmFtZXMpO1xuICAgIH1cbiAgICBzZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpIHtcbiAgICAgICAgaWYgKCFpc0FycmF5c0VxdWFsKGNsYXNzTmFtZXMsIHRoaXMuY3VycmVudENsYXNzTmFtZXMpKSB7XG4gICAgICAgICAgICBsZXQgeyBjbGFzc0xpc3QgfSA9IHRoaXMuZWw7XG4gICAgICAgICAgICBmb3IgKGxldCBjbGFzc05hbWUgb2YgdGhpcy5jdXJyZW50Q2xhc3NOYW1lcykge1xuICAgICAgICAgICAgICAgIGNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGNsYXNzTmFtZSBvZiBjbGFzc05hbWVzKSB7XG4gICAgICAgICAgICAgICAgY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2xhc3NOYW1lcyA9IGNsYXNzTmFtZXM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0SGVpZ2h0KGhlaWdodCkge1xuICAgICAgICBhcHBseVN0eWxlUHJvcCh0aGlzLmVsLCAnaGVpZ2h0JywgaGVpZ2h0KTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGZvcm1hdERhdGUoZGF0ZUlucHV0LCBvcHRpb25zID0ge30pIHtcbiAgICBsZXQgZGF0ZUVudiA9IGJ1aWxkRGF0ZUVudihvcHRpb25zKTtcbiAgICBsZXQgZm9ybWF0dGVyID0gY3JlYXRlRm9ybWF0dGVyKG9wdGlvbnMpO1xuICAgIGxldCBkYXRlTWV0YSA9IGRhdGVFbnYuY3JlYXRlTWFya2VyTWV0YShkYXRlSW5wdXQpO1xuICAgIGlmICghZGF0ZU1ldGEpIHsgLy8gVE9ETzogd2FybmluZz9cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gZGF0ZUVudi5mb3JtYXQoZGF0ZU1ldGEubWFya2VyLCBmb3JtYXR0ZXIsIHtcbiAgICAgICAgZm9yY2VkVHpvOiBkYXRlTWV0YS5mb3JjZWRUem8sXG4gICAgfSk7XG59XG5mdW5jdGlvbiBmb3JtYXRSYW5nZShzdGFydElucHV0LCBlbmRJbnB1dCwgb3B0aW9ucykge1xuICAgIGxldCBkYXRlRW52ID0gYnVpbGREYXRlRW52KHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0JyAmJiBvcHRpb25zID8gb3B0aW9ucyA6IHt9KTsgLy8gcGFzcyBpbiBpZiBub24tbnVsbCBvYmplY3RcbiAgICBsZXQgZm9ybWF0dGVyID0gY3JlYXRlRm9ybWF0dGVyKG9wdGlvbnMpO1xuICAgIGxldCBzdGFydE1ldGEgPSBkYXRlRW52LmNyZWF0ZU1hcmtlck1ldGEoc3RhcnRJbnB1dCk7XG4gICAgbGV0IGVuZE1ldGEgPSBkYXRlRW52LmNyZWF0ZU1hcmtlck1ldGEoZW5kSW5wdXQpO1xuICAgIGlmICghc3RhcnRNZXRhIHx8ICFlbmRNZXRhKSB7IC8vIFRPRE86IHdhcm5pbmc/XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIGRhdGVFbnYuZm9ybWF0UmFuZ2Uoc3RhcnRNZXRhLm1hcmtlciwgZW5kTWV0YS5tYXJrZXIsIGZvcm1hdHRlciwge1xuICAgICAgICBmb3JjZWRTdGFydFR6bzogc3RhcnRNZXRhLmZvcmNlZFR6byxcbiAgICAgICAgZm9yY2VkRW5kVHpvOiBlbmRNZXRhLmZvcmNlZFR6byxcbiAgICAgICAgaXNFbmRFeGNsdXNpdmU6IG9wdGlvbnMuaXNFbmRFeGNsdXNpdmUsXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3I6IEJBU0VfT1BUSU9OX0RFRkFVTFRTLmRlZmF1bHRSYW5nZVNlcGFyYXRvcixcbiAgICB9KTtcbn1cbi8vIFRPRE86IG1vcmUgRFJZIGFuZCBvcHRpbWl6ZWRcbmZ1bmN0aW9uIGJ1aWxkRGF0ZUVudihzZXR0aW5ncykge1xuICAgIGxldCBsb2NhbGUgPSBidWlsZExvY2FsZShzZXR0aW5ncy5sb2NhbGUgfHwgJ2VuJywgb3JnYW5pemVSYXdMb2NhbGVzKFtdKS5tYXApOyAvLyBUT0RPOiBkb24ndCBoYXJkY29kZSAnZW4nIGV2ZXJ5d2hlcmVcbiAgICByZXR1cm4gbmV3IERhdGVFbnYoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHsgdGltZVpvbmU6IEJBU0VfT1BUSU9OX0RFRkFVTFRTLnRpbWVab25lLCBjYWxlbmRhclN5c3RlbTogJ2dyZWdvcnknIH0sIHNldHRpbmdzKSwgeyBsb2NhbGUgfSkpO1xufVxuXG4vLyBIRUxQRVJTXG4vKlxuaWYgbmV4dERheVRocmVzaG9sZCBpcyBzcGVjaWZpZWQsIHNsaWNpbmcgaXMgZG9uZSBpbiBhbiBhbGwtZGF5IGZhc2hpb24uXG55b3UgY2FuIGdldCBuZXh0RGF5VGhyZXNob2xkIGZyb20gY29udGV4dC5uZXh0RGF5VGhyZXNob2xkXG4qL1xuZnVuY3Rpb24gc2xpY2VFdmVudHMocHJvcHMsIGFsbERheSkge1xuICAgIHJldHVybiBzbGljZUV2ZW50U3RvcmUocHJvcHMuZXZlbnRTdG9yZSwgcHJvcHMuZXZlbnRVaUJhc2VzLCBwcm9wcy5kYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSwgYWxsRGF5ID8gcHJvcHMubmV4dERheVRocmVzaG9sZCA6IG51bGwpLmZnO1xufVxuXG5jb25zdCB2ZXJzaW9uID0gJzYuMS4yMCc7XG5cbmV4cG9ydCB7IENhbGVuZGFyLCBjcmVhdGVQbHVnaW4sIGZvcm1hdERhdGUsIGZvcm1hdFJhbmdlLCBnbG9iYWxMb2NhbGVzLCBnbG9iYWxQbHVnaW5zLCBzbGljZUV2ZW50cywgdmVyc2lvbiB9O1xuIl0sIm5hbWVzIjpbXSwiaWdub3JlTGlzdCI6WzBdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@fullcalendar/core/index.js\n"); /***/ }), /***/ "(ssr)/./node_modules/@fullcalendar/core/internal-common.js": /*!************************************************************!*\ !*** ./node_modules/@fullcalendar/core/internal-common.js ***! \************************************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ $: () => (/* binding */ listenBySelector),\n/* harmony export */ A: () => (/* binding */ memoizeObjArg),\n/* harmony export */ B: () => (/* binding */ BaseComponent),\n/* harmony export */ C: () => (/* binding */ ContentContainer),\n/* harmony export */ D: () => (/* binding */ DelayedRunner),\n/* harmony export */ E: () => (/* binding */ isPropsEqual),\n/* harmony export */ F: () => (/* binding */ Emitter),\n/* harmony export */ G: () => (/* binding */ rangeContainsMarker),\n/* harmony export */ H: () => (/* binding */ createEmptyEventStore),\n/* harmony export */ I: () => (/* binding */ reduceEventStore),\n/* harmony export */ J: () => (/* binding */ rezoneEventStoreDates),\n/* harmony export */ K: () => (/* binding */ mergeRawOptions),\n/* harmony export */ L: () => (/* binding */ BASE_OPTION_REFINERS),\n/* harmony export */ M: () => (/* binding */ CALENDAR_LISTENER_REFINERS),\n/* harmony export */ N: () => (/* binding */ CALENDAR_OPTION_REFINERS),\n/* harmony export */ O: () => (/* binding */ COMPLEX_OPTION_COMPARATORS),\n/* harmony export */ P: () => (/* binding */ VIEW_OPTION_REFINERS),\n/* harmony export */ Q: () => (/* binding */ DateEnv),\n/* harmony export */ R: () => (/* binding */ DateProfileGenerator),\n/* harmony export */ S: () => (/* binding */ createEventUi),\n/* harmony export */ T: () => (/* binding */ Theme),\n/* harmony export */ U: () => (/* binding */ parseBusinessHours),\n/* harmony export */ V: () => (/* binding */ ViewContextType),\n/* harmony export */ W: () => (/* binding */ setRef),\n/* harmony export */ X: () => (/* binding */ Interaction),\n/* harmony export */ Y: () => (/* binding */ getElSeg),\n/* harmony export */ Z: () => (/* binding */ elementClosest),\n/* harmony export */ _: () => (/* binding */ EventImpl),\n/* harmony export */ a: () => (/* binding */ mapHash),\n/* harmony export */ a$: () => (/* binding */ preventDefault),\n/* harmony export */ a0: () => (/* binding */ listenToHoverBySelector),\n/* harmony export */ a1: () => (/* binding */ PureComponent),\n/* harmony export */ a2: () => (/* binding */ buildViewContext),\n/* harmony export */ a3: () => (/* binding */ getUniqueDomId),\n/* harmony export */ a4: () => (/* binding */ parseInteractionSettings),\n/* harmony export */ a5: () => (/* binding */ interactionSettingsStore),\n/* harmony export */ a6: () => (/* binding */ NowTimer),\n/* harmony export */ a7: () => (/* binding */ CalendarImpl),\n/* harmony export */ a8: () => (/* binding */ flushSync),\n/* harmony export */ a9: () => (/* binding */ CalendarRoot),\n/* harmony export */ aA: () => (/* binding */ memoizeArraylike),\n/* harmony export */ aB: () => (/* binding */ memoizeHashlike),\n/* harmony export */ aC: () => (/* binding */ intersectRects),\n/* harmony export */ aD: () => (/* binding */ pointInsideRect),\n/* harmony export */ aE: () => (/* binding */ constrainPoint),\n/* harmony export */ aF: () => (/* binding */ getRectCenter),\n/* harmony export */ aG: () => (/* binding */ diffPoints),\n/* harmony export */ aH: () => (/* binding */ translateRect),\n/* harmony export */ aI: () => (/* binding */ compareObjs),\n/* harmony export */ aJ: () => (/* binding */ collectFromHash),\n/* harmony export */ aK: () => (/* binding */ findElements),\n/* harmony export */ aL: () => (/* binding */ findDirectChildren),\n/* harmony export */ aM: () => (/* binding */ removeElement),\n/* harmony export */ aN: () => (/* binding */ applyStyle),\n/* harmony export */ aO: () => (/* binding */ elementMatches),\n/* harmony export */ aP: () => (/* binding */ getEventTargetViaRoot),\n/* harmony export */ aQ: () => (/* binding */ parseClassNames),\n/* harmony export */ aR: () => (/* binding */ getCanVGrowWithinCell),\n/* harmony export */ aS: () => (/* binding */ mergeEventStores),\n/* harmony export */ aT: () => (/* binding */ getRelevantEvents),\n/* harmony export */ aU: () => (/* binding */ eventTupleToStore),\n/* harmony export */ aV: () => (/* binding */ combineEventUis),\n/* harmony export */ aW: () => (/* binding */ Splitter),\n/* harmony export */ aX: () => (/* binding */ getDayClassNames),\n/* harmony export */ aY: () => (/* binding */ getDateMeta),\n/* harmony export */ aZ: () => (/* binding */ getSlotClassNames),\n/* harmony export */ a_: () => (/* binding */ buildNavLinkAttrs),\n/* harmony export */ aa: () => (/* binding */ RenderId),\n/* harmony export */ ab: () => (/* binding */ ensureElHasStyles),\n/* harmony export */ ac: () => (/* binding */ applyStyleProp),\n/* harmony export */ ad: () => (/* binding */ sliceEventStore),\n/* harmony export */ ae: () => (/* binding */ JsonRequestError),\n/* harmony export */ af: () => (/* binding */ createContext),\n/* harmony export */ ag: () => (/* binding */ refineProps),\n/* harmony export */ ah: () => (/* binding */ createEventInstance),\n/* harmony export */ ai: () => (/* binding */ parseEventDef),\n/* harmony export */ aj: () => (/* binding */ refineEventDef),\n/* harmony export */ ak: () => (/* binding */ padStart),\n/* harmony export */ al: () => (/* binding */ isInt),\n/* harmony export */ am: () => (/* binding */ parseFieldSpecs),\n/* harmony export */ an: () => (/* binding */ compareByFieldSpecs),\n/* harmony export */ ao: () => (/* binding */ flexibleCompare),\n/* harmony export */ ap: () => (/* binding */ preventSelection),\n/* harmony export */ aq: () => (/* binding */ allowSelection),\n/* harmony export */ ar: () => (/* binding */ preventContextMenu),\n/* harmony export */ as: () => (/* binding */ allowContextMenu),\n/* harmony export */ at: () => (/* binding */ compareNumbers),\n/* harmony export */ au: () => (/* binding */ enableCursor),\n/* harmony export */ av: () => (/* binding */ disableCursor),\n/* harmony export */ aw: () => (/* binding */ computeVisibleDayRange),\n/* harmony export */ ax: () => (/* binding */ isMultiDayRange),\n/* harmony export */ ay: () => (/* binding */ diffDates),\n/* harmony export */ az: () => (/* binding */ removeExact),\n/* harmony export */ b: () => (/* binding */ buildViewClassNames),\n/* harmony export */ b$: () => (/* binding */ renderMicroColGroup),\n/* harmony export */ b0: () => (/* binding */ whenTransitionDone),\n/* harmony export */ b1: () => (/* binding */ computeInnerRect),\n/* harmony export */ b2: () => (/* binding */ computeEdges),\n/* harmony export */ b3: () => (/* binding */ getClippingParents),\n/* harmony export */ b4: () => (/* binding */ computeRect),\n/* harmony export */ b5: () => (/* binding */ rangesEqual),\n/* harmony export */ b6: () => (/* binding */ rangesIntersect),\n/* harmony export */ b7: () => (/* binding */ rangeContainsRange),\n/* harmony export */ b8: () => (/* binding */ PositionCache),\n/* harmony export */ b9: () => (/* binding */ ScrollController),\n/* harmony export */ bA: () => (/* binding */ getEntrySpanEnd),\n/* harmony export */ bB: () => (/* binding */ binarySearch),\n/* harmony export */ bC: () => (/* binding */ groupIntersectingEntries),\n/* harmony export */ bD: () => (/* binding */ intersectSpans),\n/* harmony export */ bE: () => (/* binding */ interactionSettingsToStore),\n/* harmony export */ bF: () => (/* binding */ ElementDragging),\n/* harmony export */ bG: () => (/* binding */ config),\n/* harmony export */ bH: () => (/* binding */ parseDragMeta),\n/* harmony export */ bI: () => (/* binding */ DayHeader),\n/* harmony export */ bJ: () => (/* binding */ computeFallbackHeaderFormat),\n/* harmony export */ bK: () => (/* binding */ TableDateCell),\n/* harmony export */ bL: () => (/* binding */ TableDowCell),\n/* harmony export */ bM: () => (/* binding */ DaySeriesModel),\n/* harmony export */ bN: () => (/* binding */ hasBgRendering),\n/* harmony export */ bO: () => (/* binding */ buildSegTimeText),\n/* harmony export */ bP: () => (/* binding */ sortEventSegs),\n/* harmony export */ bQ: () => (/* binding */ getSegMeta),\n/* harmony export */ bR: () => (/* binding */ buildEventRangeKey),\n/* harmony export */ bS: () => (/* binding */ getSegAnchorAttrs),\n/* harmony export */ bT: () => (/* binding */ DayTableModel),\n/* harmony export */ bU: () => (/* binding */ Slicer),\n/* harmony export */ bV: () => (/* binding */ applyMutationToEventStore),\n/* harmony export */ bW: () => (/* binding */ isPropsValid),\n/* harmony export */ bX: () => (/* binding */ isInteractionValid),\n/* harmony export */ bY: () => (/* binding */ isDateSelectionValid),\n/* harmony export */ bZ: () => (/* binding */ SimpleScrollGrid),\n/* harmony export */ b_: () => (/* binding */ hasShrinkWidth),\n/* harmony export */ ba: () => (/* binding */ ElementScrollController),\n/* harmony export */ bb: () => (/* binding */ WindowScrollController),\n/* harmony export */ bc: () => (/* binding */ DateComponent),\n/* harmony export */ bd: () => (/* binding */ isDateSpansEqual),\n/* harmony export */ be: () => (/* binding */ addMs),\n/* harmony export */ bf: () => (/* binding */ addWeeks),\n/* harmony export */ bg: () => (/* binding */ diffWeeks),\n/* harmony export */ bh: () => (/* binding */ diffWholeWeeks),\n/* harmony export */ bi: () => (/* binding */ diffDayAndTime),\n/* harmony export */ bj: () => (/* binding */ diffDays),\n/* harmony export */ bk: () => (/* binding */ isValidDate),\n/* harmony export */ bl: () => (/* binding */ asCleanDays),\n/* harmony export */ bm: () => (/* binding */ multiplyDuration),\n/* harmony export */ bn: () => (/* binding */ addDurations),\n/* harmony export */ bo: () => (/* binding */ asRoughMinutes),\n/* harmony export */ bp: () => (/* binding */ asRoughSeconds),\n/* harmony export */ bq: () => (/* binding */ asRoughMs),\n/* harmony export */ br: () => (/* binding */ wholeDivideDurations),\n/* harmony export */ bs: () => (/* binding */ formatIsoTimeString),\n/* harmony export */ bt: () => (/* binding */ formatDayString),\n/* harmony export */ bu: () => (/* binding */ buildIsoString),\n/* harmony export */ bv: () => (/* binding */ formatIsoMonthStr),\n/* harmony export */ bw: () => (/* binding */ NamedTimeZoneImpl),\n/* harmony export */ bx: () => (/* binding */ parse),\n/* harmony export */ by: () => (/* binding */ SegHierarchy),\n/* harmony export */ bz: () => (/* binding */ buildEntryKey),\n/* harmony export */ c: () => (/* binding */ greatestDurationDenominator),\n/* harmony export */ c0: () => (/* binding */ getScrollGridClassNames),\n/* harmony export */ c1: () => (/* binding */ getSectionClassNames),\n/* harmony export */ c2: () => (/* binding */ getSectionHasLiquidHeight),\n/* harmony export */ c3: () => (/* binding */ getAllowYScrolling),\n/* harmony export */ c4: () => (/* binding */ renderChunkContent),\n/* harmony export */ c5: () => (/* binding */ computeShrinkWidth),\n/* harmony export */ c6: () => (/* binding */ sanitizeShrinkWidth),\n/* harmony export */ c7: () => (/* binding */ isColPropsEqual),\n/* harmony export */ c8: () => (/* binding */ renderScrollShim),\n/* harmony export */ c9: () => (/* binding */ getStickyFooterScrollbar),\n/* harmony export */ ca: () => (/* binding */ getStickyHeaderDates),\n/* harmony export */ cb: () => (/* binding */ Scroller),\n/* harmony export */ cc: () => (/* binding */ getScrollbarWidths),\n/* harmony export */ cd: () => (/* binding */ RefMap),\n/* harmony export */ ce: () => (/* binding */ getIsRtlScrollbarOnLeft),\n/* harmony export */ cf: () => (/* binding */ ScrollResponder),\n/* harmony export */ cg: () => (/* binding */ StandardEvent),\n/* harmony export */ ch: () => (/* binding */ NowIndicatorContainer),\n/* harmony export */ ci: () => (/* binding */ DayCellContainer),\n/* harmony export */ cj: () => (/* binding */ hasCustomDayCellContent),\n/* harmony export */ ck: () => (/* binding */ EventContainer),\n/* harmony export */ cl: () => (/* binding */ renderFill),\n/* harmony export */ cm: () => (/* binding */ BgEvent),\n/* harmony export */ cn: () => (/* binding */ WeekNumberContainer),\n/* harmony export */ co: () => (/* binding */ MoreLinkContainer),\n/* harmony export */ cp: () => (/* binding */ computeEarliestSegStart),\n/* harmony export */ cq: () => (/* binding */ ViewContainer),\n/* harmony export */ cr: () => (/* binding */ triggerDateSelect),\n/* harmony export */ cs: () => (/* binding */ getDefaultEventEnd),\n/* harmony export */ ct: () => (/* binding */ injectStyles),\n/* harmony export */ cu: () => (/* binding */ buildElAttrs),\n/* harmony export */ cv: () => (/* binding */ CustomRenderingStore),\n/* harmony export */ d: () => (/* binding */ createDuration),\n/* harmony export */ e: () => (/* binding */ BASE_OPTION_DEFAULTS),\n/* harmony export */ f: () => (/* binding */ arrayToHash),\n/* harmony export */ g: () => (/* binding */ guid),\n/* harmony export */ h: () => (/* binding */ filterHash),\n/* harmony export */ i: () => (/* binding */ isArraysEqual),\n/* harmony export */ j: () => (/* binding */ buildEventSourceRefiners),\n/* harmony export */ k: () => (/* binding */ formatWithOrdinals),\n/* harmony export */ l: () => (/* binding */ buildRangeApiWithTimeZone),\n/* harmony export */ m: () => (/* binding */ mergeProps),\n/* harmony export */ n: () => (/* binding */ identity),\n/* harmony export */ o: () => (/* binding */ intersectRanges),\n/* harmony export */ p: () => (/* binding */ parseEventSource),\n/* harmony export */ q: () => (/* binding */ startOfDay),\n/* harmony export */ r: () => (/* binding */ requestJson),\n/* harmony export */ s: () => (/* binding */ subtractDurations),\n/* harmony export */ t: () => (/* binding */ addDays),\n/* harmony export */ u: () => (/* binding */ unpromisify),\n/* harmony export */ v: () => (/* binding */ hashValuesToArray),\n/* harmony export */ w: () => (/* binding */ buildEventApis),\n/* harmony export */ x: () => (/* binding */ createFormatter),\n/* harmony export */ y: () => (/* binding */ diffWholeDays),\n/* harmony export */ z: () => (/* binding */ memoize)\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"(ssr)/./node_modules/preact/dist/preact.mjs\");\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact/compat */ \"(ssr)/./node_modules/preact/compat/dist/compat.mjs\");\n\n\n\n\nconst styleTexts = [];\nconst styleEls = new Map();\nfunction injectStyles(styleText) {\n styleTexts.push(styleText);\n styleEls.forEach((styleEl) => {\n appendStylesTo(styleEl, styleText);\n });\n}\nfunction ensureElHasStyles(el) {\n if (el.isConnected && // sometimes true if SSR system simulates DOM\n el.getRootNode // sometimes undefined if SSR system simulates DOM\n ) {\n registerStylesRoot(el.getRootNode());\n }\n}\nfunction registerStylesRoot(rootNode) {\n let styleEl = styleEls.get(rootNode);\n if (!styleEl || !styleEl.isConnected) {\n styleEl = rootNode.querySelector('style[data-fullcalendar]');\n if (!styleEl) {\n styleEl = document.createElement('style');\n styleEl.setAttribute('data-fullcalendar', '');\n const nonce = getNonceValue();\n if (nonce) {\n styleEl.nonce = nonce;\n }\n const parentEl = rootNode === document ? document.head : rootNode;\n const insertBefore = rootNode === document\n ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style')\n : parentEl.firstChild;\n parentEl.insertBefore(styleEl, insertBefore);\n }\n styleEls.set(rootNode, styleEl);\n hydrateStylesRoot(styleEl);\n }\n}\nfunction hydrateStylesRoot(styleEl) {\n for (const styleText of styleTexts) {\n appendStylesTo(styleEl, styleText);\n }\n}\nfunction appendStylesTo(styleEl, styleText) {\n const { sheet } = styleEl;\n const ruleCnt = sheet.cssRules.length;\n styleText.split('}').forEach((styleStr, i) => {\n styleStr = styleStr.trim();\n if (styleStr) {\n sheet.insertRule(styleStr + '}', ruleCnt + i);\n }\n });\n}\n// nonce\n// -------------------------------------------------------------------------------------------------\nlet queriedNonceValue;\nfunction getNonceValue() {\n if (queriedNonceValue === undefined) {\n queriedNonceValue = queryNonceValue();\n }\n return queriedNonceValue;\n}\n/*\nTODO: discourage meta tag and instead put nonce attribute on placeholder