@genspectrum/dashboard-components 0.10.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +384 -56
- package/dist/assets/mutationOverTimeWorker-BjjkMGzd.js.map +1 -0
- package/dist/components.d.ts +250 -31
- package/dist/components.js +1220 -198
- package/dist/components.js.map +1 -1
- package/dist/{dateRangeOption-DjtcAEWq.js → dateRangeOption-Bh2p78z0.js} +11 -5
- package/dist/dateRangeOption-Bh2p78z0.js.map +1 -0
- package/dist/style.css +5 -1
- package/dist/util.d.ts +626 -16
- package/dist/util.js +1 -1
- package/package.json +13 -7
- package/src/preact/aggregatedData/aggregate.stories.tsx +2 -2
- package/src/preact/aggregatedData/aggregate.tsx +11 -8
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +4 -12
- package/src/preact/dateRangeSelector/date-range-selector.tsx +4 -4
- package/src/preact/lineageFilter/lineage-filter.stories.tsx +1 -1
- package/src/preact/locationFilter/location-filter.stories.tsx +1 -1
- package/src/preact/map/__mockData__/aggregatedGermany.json +83 -0
- package/src/preact/map/__mockData__/aggregatedWorld.json +259 -0
- package/src/preact/map/__mockData__/germanyMap.json +9083 -0
- package/src/preact/map/__mockData__/howToGenerateWorldMap.md +9 -0
- package/src/preact/map/__mockData__/worldAtlas.json +497127 -0
- package/src/preact/map/leafletStyleModifications.css +3 -0
- package/src/preact/map/sequences-by-location-map.tsx +202 -0
- package/src/preact/map/sequences-by-location-table.tsx +18 -0
- package/src/preact/map/sequences-by-location.stories.tsx +144 -0
- package/src/preact/map/sequences-by-location.tsx +151 -0
- package/src/preact/map/useGeoJsonMap.tsx +62 -0
- package/src/preact/mutationComparison/mutation-comparison.tsx +5 -7
- package/src/preact/mutationFilter/mutation-filter.tsx +4 -13
- package/src/preact/mutations/mutations.tsx +4 -4
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +1 -1
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +4 -4
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +5 -14
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -4
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +15 -26
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +8 -8
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +4 -15
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +11 -7
- package/src/preact/shared/stories/expectErrorMessage.ts +21 -0
- package/src/preact/textInput/text-input.stories.tsx +1 -1
- package/src/preact/useQuery.ts +9 -1
- package/src/query/queryNumberOfSequencesOverTime.spec.ts +4 -4
- package/src/query/queryNumberOfSequencesOverTime.ts +1 -4
- package/src/query/queryPrevalenceOverTime.ts +1 -4
- package/src/styles/tailwind.css +1 -1
- package/src/types.ts +12 -4
- package/src/utilEntrypoint.ts +16 -4
- package/src/utils/utils.ts +0 -29
- package/src/web-components/app.ts +1 -1
- package/src/web-components/input/gs-date-range-selector.stories.ts +4 -4
- package/src/web-components/input/gs-date-range-selector.tsx +5 -5
- package/src/web-components/input/gs-lineage-filter.tsx +1 -1
- package/src/web-components/input/gs-location-filter.tsx +1 -1
- package/src/web-components/input/gs-mutation-filter.tsx +5 -8
- package/src/web-components/input/gs-text-input.tsx +1 -1
- package/src/web-components/visualization/gs-aggregate.stories.ts +3 -3
- package/src/web-components/visualization/gs-aggregate.tsx +10 -6
- package/src/web-components/visualization/gs-mutation-comparison.tsx +7 -2
- package/src/web-components/visualization/gs-mutations-over-time.tsx +7 -2
- package/src/web-components/visualization/gs-mutations.tsx +7 -2
- package/src/web-components/visualization/gs-number-sequences-over-time.stories.ts +5 -5
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +13 -15
- package/src/web-components/visualization/gs-prevalence-over-time.stories.ts +8 -8
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +17 -14
- package/src/web-components/visualization/gs-relative-growth-advantage.stories.ts +4 -5
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +17 -15
- package/src/web-components/visualization/gs-sequences-by-location.stories.ts +234 -0
- package/src/web-components/visualization/gs-sequences-by-location.tsx +258 -0
- package/src/web-components/visualization/gs-statistics.tsx +12 -3
- package/src/web-components/visualization/index.ts +1 -0
- package/standalone-bundle/assets/mutationOverTimeWorker-DoUBht2e.js.map +1 -0
- package/standalone-bundle/dashboard-components.js +16208 -9408
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/dist/assets/mutationOverTimeWorker-CNg_ztNp.js.map +0 -1
- package/dist/dateRangeOption-DjtcAEWq.js.map +0 -1
- package/src/preact/shared/stories/expectInvalidAttributesErrorMessage.ts +0 -13
- package/src/utils/utils.spec.ts +0 -16
- package/standalone-bundle/assets/mutationOverTimeWorker-cIyshfj_.js.map +0 -1
package/dist/components.js
CHANGED
|
@@ -6,10 +6,12 @@ import { options, createContext as createContext$1, Fragment, render } from "pre
|
|
|
6
6
|
import { Grid } from "gridjs";
|
|
7
7
|
import { Chart, registerables, Scale } from "chart.js";
|
|
8
8
|
import { VennDiagramController, ArcSlice, extractSets } from "chartjs-chart-venn";
|
|
9
|
-
import {
|
|
9
|
+
import { v as views, n as namedLapisFilterSchema, s as sequenceTypeSchema, l as lapisFilterSchema, t as temporalGranularitySchema, a as dateRangeOptionSchema, b as toYYYYMMDD, D as DateRangeOptionChangedEvent, m as mutationsFilterSchema } from "./dateRangeOption-Bh2p78z0.js";
|
|
10
10
|
import { autoUpdate, computePosition, offset, shift, flip } from "@floating-ui/dom";
|
|
11
11
|
import { ReactiveElement } from "@lit/reactive-element";
|
|
12
12
|
import { BarWithErrorBarsController, BarWithErrorBar } from "chartjs-chart-error-bars";
|
|
13
|
+
import Leaflet from "leaflet";
|
|
14
|
+
import * as topojson from "topojson-client";
|
|
13
15
|
import flatpickr from "flatpickr";
|
|
14
16
|
/**
|
|
15
17
|
* @license
|
|
@@ -61,7 +63,7 @@ const r$3 = (t2) => new n$2("string" == typeof t2 ? t2 : t2 + "", void 0, s$1),
|
|
|
61
63
|
* Copyright 2017 Google LLC
|
|
62
64
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
63
65
|
*/
|
|
64
|
-
const { is: i$1, defineProperty: e$1, getOwnPropertyDescriptor: r$2, getOwnPropertyNames: h$1, getOwnPropertySymbols: o$2, getPrototypeOf: n$1 } = Object, a$1 = globalThis, c$1 = a$1.trustedTypes, l$1 = c$1 ? c$1.emptyScript : "", p$
|
|
66
|
+
const { is: i$1, defineProperty: e$1, getOwnPropertyDescriptor: r$2, getOwnPropertyNames: h$1, getOwnPropertySymbols: o$2, getPrototypeOf: n$1 } = Object, a$1 = globalThis, c$1 = a$1.trustedTypes, l$1 = c$1 ? c$1.emptyScript : "", p$2 = a$1.reactiveElementPolyfillSupport, d$1 = (t2, s2) => t2, u$2 = { toAttribute(t2, s2) {
|
|
65
67
|
switch (s2) {
|
|
66
68
|
case Boolean:
|
|
67
69
|
t2 = t2 ? l$1 : null;
|
|
@@ -289,7 +291,7 @@ let b$1 = class b extends HTMLElement {
|
|
|
289
291
|
firstUpdated(t2) {
|
|
290
292
|
}
|
|
291
293
|
};
|
|
292
|
-
b$1.elementStyles = [], b$1.shadowRootOptions = { mode: "open" }, b$1[d$1("elementProperties")] = /* @__PURE__ */ new Map(), b$1[d$1("finalized")] = /* @__PURE__ */ new Map(), p$
|
|
294
|
+
b$1.elementStyles = [], b$1.shadowRootOptions = { mode: "open" }, b$1[d$1("elementProperties")] = /* @__PURE__ */ new Map(), b$1[d$1("finalized")] = /* @__PURE__ */ new Map(), p$2 == null ? void 0 : p$2({ ReactiveElement: b$1 }), (a$1.reactiveElementVersions ?? (a$1.reactiveElementVersions = [])).push("2.0.4");
|
|
293
295
|
/**
|
|
294
296
|
* @license
|
|
295
297
|
* Copyright 2017 Google LLC
|
|
@@ -521,14 +523,14 @@ const substitutionsOrDeletionsEndpoint = (lapisUrl, sequenceType) => {
|
|
|
521
523
|
return sequenceType === "amino acid" ? `${lapisUrl}/sample/aminoAcidMutations` : `${lapisUrl}/sample/nucleotideMutations`;
|
|
522
524
|
};
|
|
523
525
|
const referenceGenomeEndpoint = (lapisUrl) => `${lapisUrl}/sample/referenceGenome`;
|
|
524
|
-
var __defProp$
|
|
525
|
-
var __getOwnPropDesc$
|
|
526
|
-
var __decorateClass$
|
|
527
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
526
|
+
var __defProp$f = Object.defineProperty;
|
|
527
|
+
var __getOwnPropDesc$e = Object.getOwnPropertyDescriptor;
|
|
528
|
+
var __decorateClass$f = (decorators, target, key, kind) => {
|
|
529
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$e(target, key) : target;
|
|
528
530
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
529
531
|
if (decorator = decorators[i2])
|
|
530
532
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
531
|
-
if (kind && result) __defProp$
|
|
533
|
+
if (kind && result) __defProp$f(target, key, result);
|
|
532
534
|
return result;
|
|
533
535
|
};
|
|
534
536
|
const lapisUrlSchema = z$1.string().url();
|
|
@@ -564,14 +566,14 @@ let App = class extends LitElement {
|
|
|
564
566
|
return this;
|
|
565
567
|
}
|
|
566
568
|
};
|
|
567
|
-
__decorateClass$
|
|
569
|
+
__decorateClass$f([
|
|
568
570
|
provide({ context: lapisContext }),
|
|
569
571
|
n2()
|
|
570
572
|
], App.prototype, "lapis", 2);
|
|
571
|
-
__decorateClass$
|
|
573
|
+
__decorateClass$f([
|
|
572
574
|
provide({ context: referenceGenomeContext })
|
|
573
575
|
], App.prototype, "referenceGenome", 2);
|
|
574
|
-
App = __decorateClass$
|
|
576
|
+
App = __decorateClass$f([
|
|
575
577
|
t$2("gs-app")
|
|
576
578
|
], App);
|
|
577
579
|
function GsAppError(error) {
|
|
@@ -593,9 +595,9 @@ function d(n3, t2) {
|
|
|
593
595
|
return n3 >= u2.__.length && u2.__.push({}), u2.__[n3];
|
|
594
596
|
}
|
|
595
597
|
function h(n3) {
|
|
596
|
-
return o = 1, p(D$1, n3);
|
|
598
|
+
return o = 1, p$1(D$1, n3);
|
|
597
599
|
}
|
|
598
|
-
function p(n3, u2, i2) {
|
|
600
|
+
function p$1(n3, u2, i2) {
|
|
599
601
|
var o2 = d(t++, 2);
|
|
600
602
|
if (o2.t = n3, !o2.__c && (o2.__ = [D$1(void 0, u2), function(n4) {
|
|
601
603
|
var t2 = o2.__N ? o2.__N[0] : o2.__[0], r2 = o2.t(t2, n4);
|
|
@@ -2028,8 +2030,15 @@ function useQuery(fetchDataCallback, dependencies) {
|
|
|
2028
2030
|
};
|
|
2029
2031
|
fetchData();
|
|
2030
2032
|
}, [JSON.stringify(dependencies)]);
|
|
2031
|
-
|
|
2033
|
+
if (isLoading) {
|
|
2034
|
+
return { isLoading: true };
|
|
2035
|
+
}
|
|
2036
|
+
if (error !== null) {
|
|
2037
|
+
return { error, isLoading: false };
|
|
2038
|
+
}
|
|
2039
|
+
return { data, error: null, isLoading: false };
|
|
2032
2040
|
}
|
|
2041
|
+
const mutationComparisonViewSchema = z$1.union([z$1.literal(views.table), z$1.literal(views.venn)]);
|
|
2033
2042
|
const mutationComparisonPropsSchema = z$1.object({
|
|
2034
2043
|
width: z$1.string(),
|
|
2035
2044
|
height: z$1.string(),
|
|
@@ -2104,7 +2113,7 @@ const MutationComparisonTabs = ({ data, originalComponentProps }) => {
|
|
|
2104
2113
|
{
|
|
2105
2114
|
tabs,
|
|
2106
2115
|
toolbar: /* @__PURE__ */ u$1(
|
|
2107
|
-
Toolbar$
|
|
2116
|
+
Toolbar$6,
|
|
2108
2117
|
{
|
|
2109
2118
|
displayedSegments,
|
|
2110
2119
|
setDisplayedSegments,
|
|
@@ -2119,7 +2128,7 @@ const MutationComparisonTabs = ({ data, originalComponentProps }) => {
|
|
|
2119
2128
|
}
|
|
2120
2129
|
);
|
|
2121
2130
|
};
|
|
2122
|
-
const Toolbar$
|
|
2131
|
+
const Toolbar$6 = ({
|
|
2123
2132
|
displayedSegments,
|
|
2124
2133
|
setDisplayedSegments,
|
|
2125
2134
|
displayedMutationTypes,
|
|
@@ -4935,6 +4944,9 @@ input.tab:checked + .tab-content,
|
|
|
4935
4944
|
--tw-translate-y: -50%;
|
|
4936
4945
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
4937
4946
|
}
|
|
4947
|
+
.transform {
|
|
4948
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
4949
|
+
}
|
|
4938
4950
|
.cursor-pointer {
|
|
4939
4951
|
cursor: pointer;
|
|
4940
4952
|
}
|
|
@@ -5267,14 +5279,15 @@ input.tab:checked + .tab-content,
|
|
|
5267
5279
|
font-size: 2.25rem;
|
|
5268
5280
|
line-height: 2.5rem;
|
|
5269
5281
|
}
|
|
5270
|
-
}
|
|
5271
|
-
|
|
5272
|
-
var
|
|
5282
|
+
}
|
|
5283
|
+
`;
|
|
5284
|
+
var __defProp$e = Object.defineProperty;
|
|
5285
|
+
var __decorateClass$e = (decorators, target, key, kind) => {
|
|
5273
5286
|
var result = void 0;
|
|
5274
5287
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
5275
5288
|
if (decorator = decorators[i2])
|
|
5276
5289
|
result = decorator(target, key, result) || result;
|
|
5277
|
-
if (result) __defProp$
|
|
5290
|
+
if (result) __defProp$e(target, key, result);
|
|
5278
5291
|
return result;
|
|
5279
5292
|
};
|
|
5280
5293
|
const tailwindElementCss = unsafeCSS(tailwindStyle);
|
|
@@ -5296,10 +5309,10 @@ const _PreactLitAdapter = class _PreactLitAdapter extends ReactiveElement {
|
|
|
5296
5309
|
};
|
|
5297
5310
|
_PreactLitAdapter.styles = [tailwindElementCss, minMaxPercentSliderElementCss];
|
|
5298
5311
|
let PreactLitAdapter = _PreactLitAdapter;
|
|
5299
|
-
__decorateClass$
|
|
5312
|
+
__decorateClass$e([
|
|
5300
5313
|
consume({ context: lapisContext })
|
|
5301
5314
|
], PreactLitAdapter.prototype, "lapis");
|
|
5302
|
-
__decorateClass$
|
|
5315
|
+
__decorateClass$e([
|
|
5303
5316
|
consume({ context: referenceGenomeContext, subscribe: true })
|
|
5304
5317
|
], PreactLitAdapter.prototype, "referenceGenome");
|
|
5305
5318
|
const gridJsElementCss = unsafeCSS(gridJsStyle);
|
|
@@ -5307,14 +5320,14 @@ const _PreactLitAdapterWithGridJsStyles = class _PreactLitAdapterWithGridJsStyle
|
|
|
5307
5320
|
};
|
|
5308
5321
|
_PreactLitAdapterWithGridJsStyles.styles = [...PreactLitAdapter.styles, gridJsElementCss];
|
|
5309
5322
|
let PreactLitAdapterWithGridJsStyles = _PreactLitAdapterWithGridJsStyles;
|
|
5310
|
-
var __defProp$
|
|
5311
|
-
var __getOwnPropDesc$
|
|
5312
|
-
var __decorateClass$
|
|
5313
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
5323
|
+
var __defProp$d = Object.defineProperty;
|
|
5324
|
+
var __getOwnPropDesc$d = Object.getOwnPropertyDescriptor;
|
|
5325
|
+
var __decorateClass$d = (decorators, target, key, kind) => {
|
|
5326
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$d(target, key) : target;
|
|
5314
5327
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
5315
5328
|
if (decorator = decorators[i2])
|
|
5316
5329
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
5317
|
-
if (kind && result) __defProp$
|
|
5330
|
+
if (kind && result) __defProp$d(target, key, result);
|
|
5318
5331
|
return result;
|
|
5319
5332
|
};
|
|
5320
5333
|
let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
@@ -5341,25 +5354,25 @@ let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles
|
|
|
5341
5354
|
);
|
|
5342
5355
|
}
|
|
5343
5356
|
};
|
|
5344
|
-
__decorateClass$
|
|
5357
|
+
__decorateClass$d([
|
|
5345
5358
|
n2({ type: Array })
|
|
5346
5359
|
], MutationComparisonComponent.prototype, "lapisFilters", 2);
|
|
5347
|
-
__decorateClass$
|
|
5360
|
+
__decorateClass$d([
|
|
5348
5361
|
n2({ type: String })
|
|
5349
5362
|
], MutationComparisonComponent.prototype, "sequenceType", 2);
|
|
5350
|
-
__decorateClass$
|
|
5363
|
+
__decorateClass$d([
|
|
5351
5364
|
n2({ type: Array })
|
|
5352
5365
|
], MutationComparisonComponent.prototype, "views", 2);
|
|
5353
|
-
__decorateClass$
|
|
5366
|
+
__decorateClass$d([
|
|
5354
5367
|
n2({ type: String })
|
|
5355
5368
|
], MutationComparisonComponent.prototype, "width", 2);
|
|
5356
|
-
__decorateClass$
|
|
5369
|
+
__decorateClass$d([
|
|
5357
5370
|
n2({ type: String })
|
|
5358
5371
|
], MutationComparisonComponent.prototype, "height", 2);
|
|
5359
|
-
__decorateClass$
|
|
5372
|
+
__decorateClass$d([
|
|
5360
5373
|
n2({ type: Object })
|
|
5361
5374
|
], MutationComparisonComponent.prototype, "pageSize", 2);
|
|
5362
|
-
MutationComparisonComponent = __decorateClass$
|
|
5375
|
+
MutationComparisonComponent = __decorateClass$d([
|
|
5363
5376
|
t$2("gs-mutation-comparison")
|
|
5364
5377
|
], MutationComparisonComponent);
|
|
5365
5378
|
function getInsertionsTableData(data) {
|
|
@@ -5628,11 +5641,11 @@ function filterMutationsData(data, displayedSegments, displayedMutationTypes) {
|
|
|
5628
5641
|
gridData: filteredSubstitutionsOrDeletions
|
|
5629
5642
|
};
|
|
5630
5643
|
}
|
|
5631
|
-
const
|
|
5644
|
+
const mutationsViewSchema = z$1.union([z$1.literal(views.table), z$1.literal(views.grid), z$1.literal(views.insertions)]);
|
|
5632
5645
|
const mutationsPropsSchema = z$1.object({
|
|
5633
5646
|
lapisFilter: lapisFilterSchema,
|
|
5634
5647
|
sequenceType: sequenceTypeSchema,
|
|
5635
|
-
views:
|
|
5648
|
+
views: mutationsViewSchema.array(),
|
|
5636
5649
|
pageSize: z$1.union([z$1.boolean(), z$1.number()]),
|
|
5637
5650
|
width: z$1.string(),
|
|
5638
5651
|
height: z$1.string()
|
|
@@ -5703,7 +5716,7 @@ const MutationsTabs = ({ mutationsData, originalComponentProps }) => {
|
|
|
5703
5716
|
};
|
|
5704
5717
|
const tabs = originalComponentProps.views.map((view) => getTab(view));
|
|
5705
5718
|
const toolbar = (activeTab) => /* @__PURE__ */ u$1(
|
|
5706
|
-
Toolbar$
|
|
5719
|
+
Toolbar$5,
|
|
5707
5720
|
{
|
|
5708
5721
|
activeTab,
|
|
5709
5722
|
displayedSegments,
|
|
@@ -5718,7 +5731,7 @@ const MutationsTabs = ({ mutationsData, originalComponentProps }) => {
|
|
|
5718
5731
|
);
|
|
5719
5732
|
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
|
|
5720
5733
|
};
|
|
5721
|
-
const Toolbar$
|
|
5734
|
+
const Toolbar$5 = ({
|
|
5722
5735
|
activeTab,
|
|
5723
5736
|
displayedSegments,
|
|
5724
5737
|
setDisplayedSegments,
|
|
@@ -5806,14 +5819,14 @@ const MutationsInfo = ({ originalComponentProps }) => {
|
|
|
5806
5819
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutations", params: originalComponentProps, lapisUrl: lapis })
|
|
5807
5820
|
] });
|
|
5808
5821
|
};
|
|
5809
|
-
var __defProp$
|
|
5810
|
-
var __getOwnPropDesc$
|
|
5811
|
-
var __decorateClass$
|
|
5812
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
5822
|
+
var __defProp$c = Object.defineProperty;
|
|
5823
|
+
var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
|
|
5824
|
+
var __decorateClass$c = (decorators, target, key, kind) => {
|
|
5825
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
|
|
5813
5826
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
5814
5827
|
if (decorator = decorators[i2])
|
|
5815
5828
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
5816
|
-
if (kind && result) __defProp$
|
|
5829
|
+
if (kind && result) __defProp$c(target, key, result);
|
|
5817
5830
|
return result;
|
|
5818
5831
|
};
|
|
5819
5832
|
let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
@@ -5840,25 +5853,25 @@ let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
5840
5853
|
);
|
|
5841
5854
|
}
|
|
5842
5855
|
};
|
|
5843
|
-
__decorateClass$
|
|
5856
|
+
__decorateClass$c([
|
|
5844
5857
|
n2({ type: Object })
|
|
5845
5858
|
], MutationsComponent.prototype, "lapisFilter", 2);
|
|
5846
|
-
__decorateClass$
|
|
5859
|
+
__decorateClass$c([
|
|
5847
5860
|
n2({ type: String })
|
|
5848
5861
|
], MutationsComponent.prototype, "sequenceType", 2);
|
|
5849
|
-
__decorateClass$
|
|
5862
|
+
__decorateClass$c([
|
|
5850
5863
|
n2({ type: Array })
|
|
5851
5864
|
], MutationsComponent.prototype, "views", 2);
|
|
5852
|
-
__decorateClass$
|
|
5865
|
+
__decorateClass$c([
|
|
5853
5866
|
n2({ type: String })
|
|
5854
5867
|
], MutationsComponent.prototype, "width", 2);
|
|
5855
|
-
__decorateClass$
|
|
5868
|
+
__decorateClass$c([
|
|
5856
5869
|
n2({ type: String })
|
|
5857
5870
|
], MutationsComponent.prototype, "height", 2);
|
|
5858
|
-
__decorateClass$
|
|
5871
|
+
__decorateClass$c([
|
|
5859
5872
|
n2({ type: Object })
|
|
5860
5873
|
], MutationsComponent.prototype, "pageSize", 2);
|
|
5861
|
-
MutationsComponent = __decorateClass$
|
|
5874
|
+
MutationsComponent = __decorateClass$c([
|
|
5862
5875
|
t$2("gs-mutations")
|
|
5863
5876
|
], MutationsComponent);
|
|
5864
5877
|
function getPrevalenceOverTimeTableData(data, granularity) {
|
|
@@ -5944,7 +5957,7 @@ const confidenceIntervalDataLabel = (value, lowerLimit, upperLimit, prefix) => {
|
|
|
5944
5957
|
};
|
|
5945
5958
|
const confidenceIntervalMethodSchema = z$1.union([z$1.literal("wilson"), z$1.literal("none")]);
|
|
5946
5959
|
const axisMaxSchema = z$1.union([z$1.literal("maxInData"), z$1.literal("limitTo1"), z$1.number()]);
|
|
5947
|
-
|
|
5960
|
+
z$1.object({
|
|
5948
5961
|
linear: axisMaxSchema.optional(),
|
|
5949
5962
|
logarithmic: axisMaxSchema.optional()
|
|
5950
5963
|
});
|
|
@@ -6553,6 +6566,7 @@ const advancedFormat = function(o2, c2) {
|
|
|
6553
6566
|
return _this.isoWeekYear();
|
|
6554
6567
|
case "wo":
|
|
6555
6568
|
return locale.ordinal(_this.week(), "W");
|
|
6569
|
+
// W for week
|
|
6556
6570
|
case "w":
|
|
6557
6571
|
case "ww":
|
|
6558
6572
|
return utils.s(_this.week(), match === "w" ? 1 : 2, "0");
|
|
@@ -7006,12 +7020,6 @@ function getMinMaxNumber(values) {
|
|
|
7006
7020
|
}
|
|
7007
7021
|
return [min, max];
|
|
7008
7022
|
}
|
|
7009
|
-
function makeArray(arrayOrSingleItem) {
|
|
7010
|
-
if (Array.isArray(arrayOrSingleItem)) {
|
|
7011
|
-
return arrayOrSingleItem;
|
|
7012
|
-
}
|
|
7013
|
-
return [arrayOrSingleItem];
|
|
7014
|
-
}
|
|
7015
7023
|
Chart.register(...registerables, LogitScale);
|
|
7016
7024
|
const PrevalenceOverTimeBubbleChart = ({
|
|
7017
7025
|
data,
|
|
@@ -7437,8 +7445,7 @@ class DivisionOperator {
|
|
|
7437
7445
|
return { content };
|
|
7438
7446
|
}
|
|
7439
7447
|
}
|
|
7440
|
-
function queryPrevalenceOverTime(
|
|
7441
|
-
const numeratorFilters = makeArray(numeratorFilter);
|
|
7448
|
+
function queryPrevalenceOverTime(numeratorFilters, denominatorFilter, granularity, smoothingWindow, lapis, lapisDateField, signal) {
|
|
7442
7449
|
const denominatorData = queryAggregatedDataOverTime(
|
|
7443
7450
|
denominatorFilter,
|
|
7444
7451
|
granularity,
|
|
@@ -7530,7 +7537,7 @@ const ScalingSelector = ({
|
|
|
7530
7537
|
}
|
|
7531
7538
|
);
|
|
7532
7539
|
};
|
|
7533
|
-
const
|
|
7540
|
+
const prevalenceOverTimeViewSchema = z$1.union([
|
|
7534
7541
|
z$1.literal(views.table),
|
|
7535
7542
|
z$1.literal(views.bar),
|
|
7536
7543
|
z$1.literal(views.line),
|
|
@@ -7539,11 +7546,11 @@ const viewSchema$3 = z$1.union([
|
|
|
7539
7546
|
const prevalenceOverTimePropsSchema = z$1.object({
|
|
7540
7547
|
width: z$1.string(),
|
|
7541
7548
|
height: z$1.string(),
|
|
7542
|
-
|
|
7549
|
+
numeratorFilters: z$1.array(namedLapisFilterSchema).min(1),
|
|
7543
7550
|
denominatorFilter: lapisFilterSchema,
|
|
7544
7551
|
granularity: temporalGranularitySchema,
|
|
7545
7552
|
smoothingWindow: z$1.number(),
|
|
7546
|
-
views: z$1.array(
|
|
7553
|
+
views: z$1.array(prevalenceOverTimeViewSchema),
|
|
7547
7554
|
confidenceIntervalMethods: z$1.array(confidenceIntervalMethodSchema),
|
|
7548
7555
|
lapisDateField: z$1.string().min(1),
|
|
7549
7556
|
pageSize: z$1.union([z$1.boolean(), z$1.number()]),
|
|
@@ -7556,18 +7563,18 @@ const PrevalenceOverTime = (componentProps) => {
|
|
|
7556
7563
|
return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: prevalenceOverTimePropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(PrevalenceOverTimeInner, { ...componentProps }) }) });
|
|
7557
7564
|
};
|
|
7558
7565
|
const PrevalenceOverTimeInner = (componentProps) => {
|
|
7559
|
-
const {
|
|
7566
|
+
const { numeratorFilters, denominatorFilter, granularity, smoothingWindow, lapisDateField } = componentProps;
|
|
7560
7567
|
const lapis = x(LapisUrlContext);
|
|
7561
7568
|
const { data, error, isLoading } = useQuery(
|
|
7562
7569
|
() => queryPrevalenceOverTime(
|
|
7563
|
-
|
|
7570
|
+
numeratorFilters,
|
|
7564
7571
|
denominatorFilter,
|
|
7565
7572
|
granularity,
|
|
7566
7573
|
smoothingWindow,
|
|
7567
7574
|
lapis,
|
|
7568
7575
|
lapisDateField
|
|
7569
7576
|
),
|
|
7570
|
-
[lapis,
|
|
7577
|
+
[lapis, numeratorFilters, denominatorFilter, granularity, smoothingWindow, lapisDateField]
|
|
7571
7578
|
);
|
|
7572
7579
|
if (isLoading) {
|
|
7573
7580
|
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
@@ -7644,7 +7651,7 @@ const PrevalenceOverTimeTabs = ({ data, ...componentProps }) => {
|
|
|
7644
7651
|
};
|
|
7645
7652
|
const tabs = views2.map((view) => getTab(view));
|
|
7646
7653
|
const toolbar = (activeTab) => /* @__PURE__ */ u$1(
|
|
7647
|
-
Toolbar$
|
|
7654
|
+
Toolbar$4,
|
|
7648
7655
|
{
|
|
7649
7656
|
activeTab,
|
|
7650
7657
|
yAxisScaleType,
|
|
@@ -7657,7 +7664,7 @@ const PrevalenceOverTimeTabs = ({ data, ...componentProps }) => {
|
|
|
7657
7664
|
);
|
|
7658
7665
|
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
|
|
7659
7666
|
};
|
|
7660
|
-
const Toolbar$
|
|
7667
|
+
const Toolbar$4 = ({
|
|
7661
7668
|
activeTab,
|
|
7662
7669
|
yAxisScaleType,
|
|
7663
7670
|
setYAxisScaleType,
|
|
@@ -7716,20 +7723,20 @@ const PrevalenceOverTimeInfo = (componentProps) => {
|
|
|
7716
7723
|
] });
|
|
7717
7724
|
};
|
|
7718
7725
|
const maxInData = (data) => Math.max(...data.flatMap((variant) => variant.content.map((dataPoint) => dataPoint.prevalence)));
|
|
7719
|
-
var __defProp$
|
|
7720
|
-
var __getOwnPropDesc$
|
|
7721
|
-
var __decorateClass$
|
|
7722
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
7726
|
+
var __defProp$b = Object.defineProperty;
|
|
7727
|
+
var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
|
|
7728
|
+
var __decorateClass$b = (decorators, target, key, kind) => {
|
|
7729
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
|
|
7723
7730
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
7724
7731
|
if (decorator = decorators[i2])
|
|
7725
7732
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
7726
|
-
if (kind && result) __defProp$
|
|
7733
|
+
if (kind && result) __defProp$b(target, key, result);
|
|
7727
7734
|
return result;
|
|
7728
7735
|
};
|
|
7729
7736
|
let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
7730
7737
|
constructor() {
|
|
7731
7738
|
super(...arguments);
|
|
7732
|
-
this.
|
|
7739
|
+
this.numeratorFilters = [];
|
|
7733
7740
|
this.denominatorFilter = {};
|
|
7734
7741
|
this.granularity = "day";
|
|
7735
7742
|
this.smoothingWindow = 0;
|
|
@@ -7746,7 +7753,7 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
|
|
|
7746
7753
|
return /* @__PURE__ */ u$1(
|
|
7747
7754
|
PrevalenceOverTime,
|
|
7748
7755
|
{
|
|
7749
|
-
|
|
7756
|
+
numeratorFilters: this.numeratorFilters,
|
|
7750
7757
|
denominatorFilter: this.denominatorFilter,
|
|
7751
7758
|
granularity: this.granularity,
|
|
7752
7759
|
smoothingWindow: this.smoothingWindow,
|
|
@@ -7762,43 +7769,43 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
|
|
|
7762
7769
|
);
|
|
7763
7770
|
}
|
|
7764
7771
|
};
|
|
7765
|
-
__decorateClass$
|
|
7772
|
+
__decorateClass$b([
|
|
7766
7773
|
n2({ type: Object })
|
|
7767
|
-
], PrevalenceOverTimeComponent.prototype, "
|
|
7768
|
-
__decorateClass$
|
|
7774
|
+
], PrevalenceOverTimeComponent.prototype, "numeratorFilters", 2);
|
|
7775
|
+
__decorateClass$b([
|
|
7769
7776
|
n2({ type: Object })
|
|
7770
7777
|
], PrevalenceOverTimeComponent.prototype, "denominatorFilter", 2);
|
|
7771
|
-
__decorateClass$
|
|
7778
|
+
__decorateClass$b([
|
|
7772
7779
|
n2({ type: String })
|
|
7773
7780
|
], PrevalenceOverTimeComponent.prototype, "granularity", 2);
|
|
7774
|
-
__decorateClass$
|
|
7781
|
+
__decorateClass$b([
|
|
7775
7782
|
n2({ type: Number })
|
|
7776
7783
|
], PrevalenceOverTimeComponent.prototype, "smoothingWindow", 2);
|
|
7777
|
-
__decorateClass$
|
|
7784
|
+
__decorateClass$b([
|
|
7778
7785
|
n2({ type: Array })
|
|
7779
7786
|
], PrevalenceOverTimeComponent.prototype, "views", 2);
|
|
7780
|
-
__decorateClass$
|
|
7787
|
+
__decorateClass$b([
|
|
7781
7788
|
n2({ type: Array })
|
|
7782
7789
|
], PrevalenceOverTimeComponent.prototype, "confidenceIntervalMethods", 2);
|
|
7783
|
-
__decorateClass$
|
|
7790
|
+
__decorateClass$b([
|
|
7784
7791
|
n2({ type: String })
|
|
7785
7792
|
], PrevalenceOverTimeComponent.prototype, "width", 2);
|
|
7786
|
-
__decorateClass$
|
|
7793
|
+
__decorateClass$b([
|
|
7787
7794
|
n2({ type: String })
|
|
7788
7795
|
], PrevalenceOverTimeComponent.prototype, "height", 2);
|
|
7789
|
-
__decorateClass$
|
|
7796
|
+
__decorateClass$b([
|
|
7790
7797
|
n2({ type: String })
|
|
7791
7798
|
], PrevalenceOverTimeComponent.prototype, "lapisDateField", 2);
|
|
7792
|
-
__decorateClass$
|
|
7799
|
+
__decorateClass$b([
|
|
7793
7800
|
n2({ type: Object })
|
|
7794
7801
|
], PrevalenceOverTimeComponent.prototype, "pageSize", 2);
|
|
7795
|
-
__decorateClass$
|
|
7802
|
+
__decorateClass$b([
|
|
7796
7803
|
n2({ type: String })
|
|
7797
7804
|
], PrevalenceOverTimeComponent.prototype, "yAxisMaxLinear", 2);
|
|
7798
|
-
__decorateClass$
|
|
7805
|
+
__decorateClass$b([
|
|
7799
7806
|
n2({ type: String })
|
|
7800
7807
|
], PrevalenceOverTimeComponent.prototype, "yAxisMaxLogarithmic", 2);
|
|
7801
|
-
PrevalenceOverTimeComponent = __decorateClass$
|
|
7808
|
+
PrevalenceOverTimeComponent = __decorateClass$b([
|
|
7802
7809
|
t$2("gs-prevalence-over-time")
|
|
7803
7810
|
], PrevalenceOverTimeComponent);
|
|
7804
7811
|
Chart.register(...registerables, LogitScale);
|
|
@@ -8028,16 +8035,17 @@ function toYearMonthDay(d2) {
|
|
|
8028
8035
|
count: d2.count
|
|
8029
8036
|
};
|
|
8030
8037
|
}
|
|
8031
|
-
const
|
|
8038
|
+
const relativeGrowthAdvantageViewSchema = z$1.literal(views.line);
|
|
8032
8039
|
const relativeGrowthAdvantagePropsSchema = z$1.object({
|
|
8033
8040
|
width: z$1.string(),
|
|
8034
8041
|
height: z$1.string(),
|
|
8035
8042
|
numeratorFilter: lapisFilterSchema,
|
|
8036
8043
|
denominatorFilter: lapisFilterSchema,
|
|
8037
8044
|
generationTime: z$1.number(),
|
|
8038
|
-
views: z$1.array(
|
|
8045
|
+
views: z$1.array(relativeGrowthAdvantageViewSchema),
|
|
8039
8046
|
lapisDateField: z$1.string().min(1),
|
|
8040
|
-
|
|
8047
|
+
yAxisMaxLinear: axisMaxSchema,
|
|
8048
|
+
yAxisMaxLogarithmic: axisMaxSchema
|
|
8041
8049
|
});
|
|
8042
8050
|
const RelativeGrowthAdvantage = (componentProps) => {
|
|
8043
8051
|
const { width, height } = componentProps;
|
|
@@ -8094,7 +8102,10 @@ const RelativeGrowthAdvantageTabs = ({
|
|
|
8094
8102
|
params: data.params
|
|
8095
8103
|
},
|
|
8096
8104
|
yAxisScaleType,
|
|
8097
|
-
yAxisMaxConfig:
|
|
8105
|
+
yAxisMaxConfig: {
|
|
8106
|
+
linear: originalComponentProps.yAxisMaxLinear,
|
|
8107
|
+
logarithmic: originalComponentProps.yAxisMaxLogarithmic
|
|
8108
|
+
}
|
|
8098
8109
|
}
|
|
8099
8110
|
)
|
|
8100
8111
|
};
|
|
@@ -8155,14 +8166,14 @@ const RelativeGrowthAdvantageInfo = ({
|
|
|
8155
8166
|
)
|
|
8156
8167
|
] });
|
|
8157
8168
|
};
|
|
8158
|
-
var __defProp$
|
|
8159
|
-
var __getOwnPropDesc$
|
|
8160
|
-
var __decorateClass$
|
|
8161
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
8169
|
+
var __defProp$a = Object.defineProperty;
|
|
8170
|
+
var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
|
|
8171
|
+
var __decorateClass$a = (decorators, target, key, kind) => {
|
|
8172
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
|
|
8162
8173
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
8163
8174
|
if (decorator = decorators[i2])
|
|
8164
8175
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8165
|
-
if (kind && result) __defProp$
|
|
8176
|
+
if (kind && result) __defProp$a(target, key, result);
|
|
8166
8177
|
return result;
|
|
8167
8178
|
};
|
|
8168
8179
|
let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
|
|
@@ -8189,42 +8200,40 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
|
|
|
8189
8200
|
width: this.width,
|
|
8190
8201
|
height: this.height,
|
|
8191
8202
|
lapisDateField: this.lapisDateField,
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
logarithmic: this.yAxisMaxLogarithmic
|
|
8195
|
-
}
|
|
8203
|
+
yAxisMaxLinear: this.yAxisMaxLinear,
|
|
8204
|
+
yAxisMaxLogarithmic: this.yAxisMaxLogarithmic
|
|
8196
8205
|
}
|
|
8197
8206
|
);
|
|
8198
8207
|
}
|
|
8199
8208
|
};
|
|
8200
|
-
__decorateClass$
|
|
8209
|
+
__decorateClass$a([
|
|
8201
8210
|
n2({ type: Object })
|
|
8202
8211
|
], RelativeGrowthAdvantageComponent.prototype, "numeratorFilter", 2);
|
|
8203
|
-
__decorateClass$
|
|
8212
|
+
__decorateClass$a([
|
|
8204
8213
|
n2({ type: Object })
|
|
8205
8214
|
], RelativeGrowthAdvantageComponent.prototype, "denominatorFilter", 2);
|
|
8206
|
-
__decorateClass$
|
|
8215
|
+
__decorateClass$a([
|
|
8207
8216
|
n2({ type: Number })
|
|
8208
8217
|
], RelativeGrowthAdvantageComponent.prototype, "generationTime", 2);
|
|
8209
|
-
__decorateClass$
|
|
8218
|
+
__decorateClass$a([
|
|
8210
8219
|
n2({ type: Array })
|
|
8211
8220
|
], RelativeGrowthAdvantageComponent.prototype, "views", 2);
|
|
8212
|
-
__decorateClass$
|
|
8221
|
+
__decorateClass$a([
|
|
8213
8222
|
n2({ type: String })
|
|
8214
8223
|
], RelativeGrowthAdvantageComponent.prototype, "width", 2);
|
|
8215
|
-
__decorateClass$
|
|
8224
|
+
__decorateClass$a([
|
|
8216
8225
|
n2({ type: String })
|
|
8217
8226
|
], RelativeGrowthAdvantageComponent.prototype, "height", 2);
|
|
8218
|
-
__decorateClass$
|
|
8227
|
+
__decorateClass$a([
|
|
8219
8228
|
n2({ type: String })
|
|
8220
8229
|
], RelativeGrowthAdvantageComponent.prototype, "lapisDateField", 2);
|
|
8221
|
-
__decorateClass$
|
|
8230
|
+
__decorateClass$a([
|
|
8222
8231
|
n2({ type: String })
|
|
8223
8232
|
], RelativeGrowthAdvantageComponent.prototype, "yAxisMaxLinear", 2);
|
|
8224
|
-
__decorateClass$
|
|
8233
|
+
__decorateClass$a([
|
|
8225
8234
|
n2({ type: String })
|
|
8226
8235
|
], RelativeGrowthAdvantageComponent.prototype, "yAxisMaxLogarithmic", 2);
|
|
8227
|
-
RelativeGrowthAdvantageComponent = __decorateClass$
|
|
8236
|
+
RelativeGrowthAdvantageComponent = __decorateClass$a([
|
|
8228
8237
|
t$2("gs-relative-growth-advantage")
|
|
8229
8238
|
], RelativeGrowthAdvantageComponent);
|
|
8230
8239
|
const compareAscending = (a2, b3) => {
|
|
@@ -8275,11 +8284,11 @@ const AggregateTable = ({ data, fields, pageSize }) => {
|
|
|
8275
8284
|
];
|
|
8276
8285
|
return /* @__PURE__ */ u$1(Table, { data, columns: headers, pageSize });
|
|
8277
8286
|
};
|
|
8278
|
-
const
|
|
8287
|
+
const aggregateViewSchema = z$1.literal(views.table);
|
|
8279
8288
|
const aggregatePropsSchema = z$1.object({
|
|
8280
|
-
|
|
8289
|
+
lapisFilter: lapisFilterSchema,
|
|
8281
8290
|
fields: z$1.array(z$1.string().min(1)),
|
|
8282
|
-
views: z$1.array(
|
|
8291
|
+
views: z$1.array(aggregateViewSchema),
|
|
8283
8292
|
initialSortField: z$1.string(),
|
|
8284
8293
|
initialSortDirection: z$1.union([z$1.literal("ascending"), z$1.literal("descending")]),
|
|
8285
8294
|
pageSize: z$1.union([z$1.boolean(), z$1.number()]),
|
|
@@ -8292,11 +8301,14 @@ const Aggregate = (componentProps) => {
|
|
|
8292
8301
|
return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: aggregatePropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(AggregateInner, { ...componentProps }) }) });
|
|
8293
8302
|
};
|
|
8294
8303
|
const AggregateInner = (componentProps) => {
|
|
8295
|
-
const { fields,
|
|
8304
|
+
const { fields, lapisFilter, initialSortField, initialSortDirection } = componentProps;
|
|
8296
8305
|
const lapis = x(LapisUrlContext);
|
|
8297
8306
|
const { data, error, isLoading } = useQuery(async () => {
|
|
8298
|
-
return queryAggregateData(
|
|
8299
|
-
|
|
8307
|
+
return queryAggregateData(lapisFilter, fields, lapis, {
|
|
8308
|
+
field: initialSortField,
|
|
8309
|
+
direction: initialSortDirection
|
|
8310
|
+
});
|
|
8311
|
+
}, [lapisFilter, fields, lapis]);
|
|
8300
8312
|
if (isLoading) {
|
|
8301
8313
|
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
8302
8314
|
}
|
|
@@ -8326,9 +8338,9 @@ const AggregatedDataTabs = ({ data, originalComponentProps }) => {
|
|
|
8326
8338
|
}
|
|
8327
8339
|
};
|
|
8328
8340
|
const tabs = originalComponentProps.views.map((view) => getTab(view));
|
|
8329
|
-
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar$
|
|
8341
|
+
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar$3, { data, originalComponentProps }) });
|
|
8330
8342
|
};
|
|
8331
|
-
const Toolbar$
|
|
8343
|
+
const Toolbar$3 = ({ data, originalComponentProps }) => {
|
|
8332
8344
|
return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
|
|
8333
8345
|
/* @__PURE__ */ u$1(CsvDownloadButton, { className: "mx-1 btn btn-xs", getData: () => data, filename: "aggregate.csv" }),
|
|
8334
8346
|
/* @__PURE__ */ u$1(AggregateInfo, { originalComponentProps }),
|
|
@@ -8348,14 +8360,14 @@ const AggregateInfo = ({ originalComponentProps }) => {
|
|
|
8348
8360
|
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "aggregate", params: originalComponentProps, lapisUrl: lapis })
|
|
8349
8361
|
] });
|
|
8350
8362
|
};
|
|
8351
|
-
var __defProp$
|
|
8352
|
-
var __getOwnPropDesc$
|
|
8353
|
-
var __decorateClass$
|
|
8354
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
8363
|
+
var __defProp$9 = Object.defineProperty;
|
|
8364
|
+
var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
|
|
8365
|
+
var __decorateClass$9 = (decorators, target, key, kind) => {
|
|
8366
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
|
|
8355
8367
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
8356
8368
|
if (decorator = decorators[i2])
|
|
8357
8369
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8358
|
-
if (kind && result) __defProp$
|
|
8370
|
+
if (kind && result) __defProp$9(target, key, result);
|
|
8359
8371
|
return result;
|
|
8360
8372
|
};
|
|
8361
8373
|
let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
@@ -8363,7 +8375,7 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
8363
8375
|
super(...arguments);
|
|
8364
8376
|
this.fields = [];
|
|
8365
8377
|
this.views = ["table"];
|
|
8366
|
-
this.
|
|
8378
|
+
this.lapisFilter = {};
|
|
8367
8379
|
this.width = "100%";
|
|
8368
8380
|
this.height = "700px";
|
|
8369
8381
|
this.initialSortField = "count";
|
|
@@ -8376,7 +8388,7 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
8376
8388
|
{
|
|
8377
8389
|
fields: this.fields,
|
|
8378
8390
|
views: this.views,
|
|
8379
|
-
|
|
8391
|
+
lapisFilter: this.lapisFilter,
|
|
8380
8392
|
width: this.width,
|
|
8381
8393
|
height: this.height,
|
|
8382
8394
|
initialSortField: this.initialSortField,
|
|
@@ -8386,31 +8398,31 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
|
8386
8398
|
);
|
|
8387
8399
|
}
|
|
8388
8400
|
};
|
|
8389
|
-
__decorateClass$
|
|
8401
|
+
__decorateClass$9([
|
|
8390
8402
|
n2({ type: Array })
|
|
8391
8403
|
], AggregateComponent.prototype, "fields", 2);
|
|
8392
|
-
__decorateClass$
|
|
8404
|
+
__decorateClass$9([
|
|
8393
8405
|
n2({ type: Array })
|
|
8394
8406
|
], AggregateComponent.prototype, "views", 2);
|
|
8395
|
-
__decorateClass$
|
|
8407
|
+
__decorateClass$9([
|
|
8396
8408
|
n2({ type: Object })
|
|
8397
|
-
], AggregateComponent.prototype, "
|
|
8398
|
-
__decorateClass$
|
|
8409
|
+
], AggregateComponent.prototype, "lapisFilter", 2);
|
|
8410
|
+
__decorateClass$9([
|
|
8399
8411
|
n2({ type: String })
|
|
8400
8412
|
], AggregateComponent.prototype, "width", 2);
|
|
8401
|
-
__decorateClass$
|
|
8413
|
+
__decorateClass$9([
|
|
8402
8414
|
n2({ type: String })
|
|
8403
8415
|
], AggregateComponent.prototype, "height", 2);
|
|
8404
|
-
__decorateClass$
|
|
8416
|
+
__decorateClass$9([
|
|
8405
8417
|
n2({ type: String })
|
|
8406
8418
|
], AggregateComponent.prototype, "initialSortField", 2);
|
|
8407
|
-
__decorateClass$
|
|
8419
|
+
__decorateClass$9([
|
|
8408
8420
|
n2({ type: String })
|
|
8409
8421
|
], AggregateComponent.prototype, "initialSortDirection", 2);
|
|
8410
|
-
__decorateClass$
|
|
8422
|
+
__decorateClass$9([
|
|
8411
8423
|
n2({ type: Object })
|
|
8412
8424
|
], AggregateComponent.prototype, "pageSize", 2);
|
|
8413
|
-
AggregateComponent = __decorateClass$
|
|
8425
|
+
AggregateComponent = __decorateClass$9([
|
|
8414
8426
|
t$2("gs-aggregate")
|
|
8415
8427
|
], AggregateComponent);
|
|
8416
8428
|
const getNumberOfSequencesOverTimeTableData = (data, dateRangeKey) => {
|
|
@@ -8553,11 +8565,10 @@ const NumberSequencesOverTimeTable = ({ data, granularity, pageSize }) => {
|
|
|
8553
8565
|
}, [data, granularity]);
|
|
8554
8566
|
return /* @__PURE__ */ u$1(Table, { data: flatTableData, columns, pageSize });
|
|
8555
8567
|
};
|
|
8556
|
-
async function queryNumberOfSequencesOverTime(lapis,
|
|
8557
|
-
const
|
|
8558
|
-
const queries = lapisFilters.map(async ({ displayName, lapisFilter: lapisFilter2 }) => {
|
|
8568
|
+
async function queryNumberOfSequencesOverTime(lapis, lapisFilters, lapisDateField, granularity, smoothingWindow) {
|
|
8569
|
+
const queries = lapisFilters.map(async ({ displayName, lapisFilter }) => {
|
|
8559
8570
|
const { content } = await queryAggregatedDataOverTime(
|
|
8560
|
-
|
|
8571
|
+
lapisFilter,
|
|
8561
8572
|
granularity,
|
|
8562
8573
|
smoothingWindow,
|
|
8563
8574
|
lapisDateField
|
|
@@ -8577,7 +8588,7 @@ const numberSequencesOverTimeViewSchema = z$1.union([
|
|
|
8577
8588
|
const numberSequencesOverTimePropsSchema = z$1.object({
|
|
8578
8589
|
width: z$1.string(),
|
|
8579
8590
|
height: z$1.string(),
|
|
8580
|
-
|
|
8591
|
+
lapisFilters: z$1.array(namedLapisFilterSchema).min(1),
|
|
8581
8592
|
lapisDateField: z$1.string().min(1),
|
|
8582
8593
|
views: z$1.array(numberSequencesOverTimeViewSchema),
|
|
8583
8594
|
granularity: temporalGranularitySchema,
|
|
@@ -8590,11 +8601,11 @@ const NumberSequencesOverTime = (componentProps) => {
|
|
|
8590
8601
|
return /* @__PURE__ */ u$1(ErrorBoundary, { size, componentProps, schema: numberSequencesOverTimePropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(NumberSequencesOverTimeInner, { ...componentProps }) }) });
|
|
8591
8602
|
};
|
|
8592
8603
|
const NumberSequencesOverTimeInner = (componentProps) => {
|
|
8593
|
-
const {
|
|
8604
|
+
const { lapisFilters, lapisDateField, granularity, smoothingWindow } = componentProps;
|
|
8594
8605
|
const lapis = x(LapisUrlContext);
|
|
8595
8606
|
const { data, error, isLoading } = useQuery(
|
|
8596
|
-
() => queryNumberOfSequencesOverTime(lapis,
|
|
8597
|
-
[lapis,
|
|
8607
|
+
() => queryNumberOfSequencesOverTime(lapis, lapisFilters, lapisDateField, granularity, smoothingWindow),
|
|
8608
|
+
[lapis, lapisFilters, lapisDateField, granularity, smoothingWindow]
|
|
8598
8609
|
);
|
|
8599
8610
|
if (isLoading) {
|
|
8600
8611
|
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
@@ -8642,7 +8653,7 @@ const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }) => {
|
|
|
8642
8653
|
{
|
|
8643
8654
|
tabs: originalComponentProps.views.map((view) => getTab(view)),
|
|
8644
8655
|
toolbar: (activeTab) => /* @__PURE__ */ u$1(
|
|
8645
|
-
Toolbar$
|
|
8656
|
+
Toolbar$2,
|
|
8646
8657
|
{
|
|
8647
8658
|
activeTab,
|
|
8648
8659
|
data,
|
|
@@ -8654,7 +8665,7 @@ const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }) => {
|
|
|
8654
8665
|
}
|
|
8655
8666
|
);
|
|
8656
8667
|
};
|
|
8657
|
-
const Toolbar$
|
|
8668
|
+
const Toolbar$2 = ({ activeTab, data, yAxisScaleType, setYAxisScaleType, originalComponentProps }) => {
|
|
8658
8669
|
return /* @__PURE__ */ u$1(Fragment, { children: [
|
|
8659
8670
|
activeTab !== "Table" && /* @__PURE__ */ u$1(
|
|
8660
8671
|
ScalingSelector,
|
|
@@ -8699,20 +8710,20 @@ const NumberSequencesOverTimeInfo = ({
|
|
|
8699
8710
|
)
|
|
8700
8711
|
] });
|
|
8701
8712
|
};
|
|
8702
|
-
var __defProp$
|
|
8703
|
-
var __getOwnPropDesc$
|
|
8704
|
-
var __decorateClass$
|
|
8705
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
8713
|
+
var __defProp$8 = Object.defineProperty;
|
|
8714
|
+
var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
|
|
8715
|
+
var __decorateClass$8 = (decorators, target, key, kind) => {
|
|
8716
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
|
|
8706
8717
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
8707
8718
|
if (decorator = decorators[i2])
|
|
8708
8719
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8709
|
-
if (kind && result) __defProp$
|
|
8720
|
+
if (kind && result) __defProp$8(target, key, result);
|
|
8710
8721
|
return result;
|
|
8711
8722
|
};
|
|
8712
8723
|
let NumberSequencesOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
8713
8724
|
constructor() {
|
|
8714
8725
|
super(...arguments);
|
|
8715
|
-
this.
|
|
8726
|
+
this.lapisFilters = [];
|
|
8716
8727
|
this.lapisDateField = "";
|
|
8717
8728
|
this.views = ["bar", "line", "table"];
|
|
8718
8729
|
this.width = "100%";
|
|
@@ -8725,7 +8736,7 @@ let NumberSequencesOverTimeComponent = class extends PreactLitAdapterWithGridJsS
|
|
|
8725
8736
|
return /* @__PURE__ */ u$1(
|
|
8726
8737
|
NumberSequencesOverTime,
|
|
8727
8738
|
{
|
|
8728
|
-
|
|
8739
|
+
lapisFilters: this.lapisFilters,
|
|
8729
8740
|
lapisDateField: this.lapisDateField,
|
|
8730
8741
|
views: this.views,
|
|
8731
8742
|
width: this.width,
|
|
@@ -8737,36 +8748,35 @@ let NumberSequencesOverTimeComponent = class extends PreactLitAdapterWithGridJsS
|
|
|
8737
8748
|
);
|
|
8738
8749
|
}
|
|
8739
8750
|
};
|
|
8740
|
-
__decorateClass$
|
|
8751
|
+
__decorateClass$8([
|
|
8741
8752
|
n2({ type: Object })
|
|
8742
|
-
], NumberSequencesOverTimeComponent.prototype, "
|
|
8743
|
-
__decorateClass$
|
|
8753
|
+
], NumberSequencesOverTimeComponent.prototype, "lapisFilters", 2);
|
|
8754
|
+
__decorateClass$8([
|
|
8744
8755
|
n2({ type: String })
|
|
8745
8756
|
], NumberSequencesOverTimeComponent.prototype, "lapisDateField", 2);
|
|
8746
|
-
__decorateClass$
|
|
8757
|
+
__decorateClass$8([
|
|
8747
8758
|
n2({ type: Array })
|
|
8748
8759
|
], NumberSequencesOverTimeComponent.prototype, "views", 2);
|
|
8749
|
-
__decorateClass$
|
|
8760
|
+
__decorateClass$8([
|
|
8750
8761
|
n2({ type: String })
|
|
8751
8762
|
], NumberSequencesOverTimeComponent.prototype, "width", 2);
|
|
8752
|
-
__decorateClass$
|
|
8763
|
+
__decorateClass$8([
|
|
8753
8764
|
n2({ type: String })
|
|
8754
8765
|
], NumberSequencesOverTimeComponent.prototype, "height", 2);
|
|
8755
|
-
__decorateClass$
|
|
8766
|
+
__decorateClass$8([
|
|
8756
8767
|
n2({ type: String })
|
|
8757
8768
|
], NumberSequencesOverTimeComponent.prototype, "granularity", 2);
|
|
8758
|
-
__decorateClass$
|
|
8769
|
+
__decorateClass$8([
|
|
8759
8770
|
n2({ type: Number })
|
|
8760
8771
|
], NumberSequencesOverTimeComponent.prototype, "smoothingWindow", 2);
|
|
8761
|
-
__decorateClass$
|
|
8772
|
+
__decorateClass$8([
|
|
8762
8773
|
n2({ type: Object })
|
|
8763
8774
|
], NumberSequencesOverTimeComponent.prototype, "pageSize", 2);
|
|
8764
|
-
NumberSequencesOverTimeComponent = __decorateClass$
|
|
8775
|
+
NumberSequencesOverTimeComponent = __decorateClass$8([
|
|
8765
8776
|
t$2("gs-number-sequences-over-time")
|
|
8766
8777
|
], NumberSequencesOverTimeComponent);
|
|
8767
|
-
const encodedJs = "KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICB2YXIgdXRpbDsKICAoZnVuY3Rpb24odXRpbDIpIHsKICAgIHV0aWwyLmFzc2VydEVxdWFsID0gKHZhbCkgPT4gdmFsOwogICAgZnVuY3Rpb24gYXNzZXJ0SXMoX2FyZykgewogICAgfQogICAgdXRpbDIuYXNzZXJ0SXMgPSBhc3NlcnRJczsKICAgIGZ1bmN0aW9uIGFzc2VydE5ldmVyKF94KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgfQogICAgdXRpbDIuYXNzZXJ0TmV2ZXIgPSBhc3NlcnROZXZlcjsKICAgIHV0aWwyLmFycmF5VG9FbnVtID0gKGl0ZW1zKSA9PiB7CiAgICAgIGNvbnN0IG9iaiA9IHt9OwogICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHsKICAgICAgICBvYmpbaXRlbV0gPSBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiBvYmo7CiAgICB9OwogICAgdXRpbDIuZ2V0VmFsaWRFbnVtVmFsdWVzID0gKG9iaikgPT4gewogICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsMi5vYmplY3RLZXlzKG9iaikuZmlsdGVyKChrMikgPT4gdHlwZW9mIG9ialtvYmpbazJdXSAhPT0gIm51bWJlciIpOwogICAgICBjb25zdCBmaWx0ZXJlZCA9IHt9OwogICAgICBmb3IgKGNvbnN0IGsyIG9mIHZhbGlkS2V5cykgewogICAgICAgIGZpbHRlcmVkW2syXSA9IG9ialtrMl07CiAgICAgIH0KICAgICAgcmV0dXJuIHV0aWwyLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7CiAgICB9OwogICAgdXRpbDIub2JqZWN0VmFsdWVzID0gKG9iaikgPT4gewogICAgICByZXR1cm4gdXRpbDIub2JqZWN0S2V5cyhvYmopLm1hcChmdW5jdGlvbihlMikgewogICAgICAgIHJldHVybiBvYmpbZTJdOwogICAgICB9KTsKICAgIH07CiAgICB1dGlsMi5vYmplY3RLZXlzID0gdHlwZW9mIE9iamVjdC5rZXlzID09PSAiZnVuY3Rpb24iID8gKG9iaikgPT4gT2JqZWN0LmtleXMob2JqKSA6IChvYmplY3QpID0+IHsKICAgICAgY29uc3Qga2V5cyA9IFtdOwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHsKICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkgewogICAgICAgICAga2V5cy5wdXNoKGtleSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBrZXlzOwogICAgfTsKICAgIHV0aWwyLmZpbmQgPSAoYXJyLCBjaGVja2VyKSA9PiB7CiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhcnIpIHsKICAgICAgICBpZiAoY2hlY2tlcihpdGVtKSkKICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkIDA7CiAgICB9OwogICAgdXRpbDIuaXNJbnRlZ2VyID0gdHlwZW9mIE51bWJlci5pc0ludGVnZXIgPT09ICJmdW5jdGlvbiIgPyAodmFsKSA9PiBOdW1iZXIuaXNJbnRlZ2VyKHZhbCkgOiAodmFsKSA9PiB0eXBlb2YgdmFsID09PSAibnVtYmVyIiAmJiBpc0Zpbml0ZSh2YWwpICYmIE1hdGguZmxvb3IodmFsKSA9PT0gdmFsOwogICAgZnVuY3Rpb24gam9pblZhbHVlcyhhcnJheSwgc2VwYXJhdG9yID0gIiB8ICIpIHsKICAgICAgcmV0dXJuIGFycmF5Lm1hcCgodmFsKSA9PiB0eXBlb2YgdmFsID09PSAic3RyaW5nIiA/IGAnJHt2YWx9J2AgOiB2YWwpLmpvaW4oc2VwYXJhdG9yKTsKICAgIH0KICAgIHV0aWwyLmpvaW5WYWx1ZXMgPSBqb2luVmFsdWVzOwogICAgdXRpbDIuanNvblN0cmluZ2lmeVJlcGxhY2VyID0gKF8sIHZhbHVlKSA9PiB7CiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICJiaWdpbnQiKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfTsKICB9KSh1dGlsIHx8ICh1dGlsID0ge30pKTsKICB2YXIgb2JqZWN0VXRpbDsKICAoZnVuY3Rpb24ob2JqZWN0VXRpbDIpIHsKICAgIG9iamVjdFV0aWwyLm1lcmdlU2hhcGVzID0gKGZpcnN0LCBzZWNvbmQpID0+IHsKICAgICAgcmV0dXJuIHsKICAgICAgICAuLi5maXJzdCwKICAgICAgICAuLi5zZWNvbmQKICAgICAgICAvLyBzZWNvbmQgb3ZlcndyaXRlcyBmaXJzdAogICAgICB9OwogICAgfTsKICB9KShvYmplY3RVdGlsIHx8IChvYmplY3RVdGlsID0ge30pKTsKICBjb25zdCBab2RQYXJzZWRUeXBlID0gdXRpbC5hcnJheVRvRW51bShbCiAgICAic3RyaW5nIiwKICAgICJuYW4iLAogICAgIm51bWJlciIsCiAgICAiaW50ZWdlciIsCiAgICAiZmxvYXQiLAogICAgImJvb2xlYW4iLAogICAgImRhdGUiLAogICAgImJpZ2ludCIsCiAgICAic3ltYm9sIiwKICAgICJmdW5jdGlvbiIsCiAgICAidW5kZWZpbmVkIiwKICAgICJudWxsIiwKICAgICJhcnJheSIsCiAgICAib2JqZWN0IiwKICAgICJ1bmtub3duIiwKICAgICJwcm9taXNlIiwKICAgICJ2b2lkIiwKICAgICJuZXZlciIsCiAgICAibWFwIiwKICAgICJzZXQiCiAgXSk7CiAgY29uc3QgZ2V0UGFyc2VkVHlwZSA9IChkYXRhKSA9PiB7CiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7CiAgICBzd2l0Y2ggKHQpIHsKICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQ7CiAgICAgIGNhc2UgInN0cmluZyI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3RyaW5nOwogICAgICBjYXNlICJudW1iZXIiOgogICAgICAgIHJldHVybiBpc05hTihkYXRhKSA/IFpvZFBhcnNlZFR5cGUubmFuIDogWm9kUGFyc2VkVHlwZS5udW1iZXI7CiAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmJvb2xlYW47CiAgICAgIGNhc2UgImZ1bmN0aW9uIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbjsKICAgICAgY2FzZSAiYmlnaW50IjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5iaWdpbnQ7CiAgICAgIGNhc2UgInN5bWJvbCI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3ltYm9sOwogICAgICBjYXNlICJvYmplY3QiOgogICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5hcnJheTsKICAgICAgICB9CiAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLm51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChkYXRhLnRoZW4gJiYgdHlwZW9mIGRhdGEudGhlbiA9PT0gImZ1bmN0aW9uIiAmJiBkYXRhLmNhdGNoICYmIHR5cGVvZiBkYXRhLmNhdGNoID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5wcm9taXNlOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIE1hcCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubWFwOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIFNldCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc2V0OwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIERhdGUgIT09ICJ1bmRlZmluZWQiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5kYXRlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5vYmplY3Q7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUudW5rbm93bjsKICAgIH0KICB9OwogIGNvbnN0IFpvZElzc3VlQ29kZSA9IHV0aWwuYXJyYXlUb0VudW0oWwogICAgImludmFsaWRfdHlwZSIsCiAgICAiaW52YWxpZF9saXRlcmFsIiwKICAgICJjdXN0b20iLAogICAgImludmFsaWRfdW5pb24iLAogICAgImludmFsaWRfdW5pb25fZGlzY3JpbWluYXRvciIsCiAgICAiaW52YWxpZF9lbnVtX3ZhbHVlIiwKICAgICJ1bnJlY29nbml6ZWRfa2V5cyIsCiAgICAiaW52YWxpZF9hcmd1bWVudHMiLAogICAgImludmFsaWRfcmV0dXJuX3R5cGUiLAogICAgImludmFsaWRfZGF0ZSIsCiAgICAiaW52YWxpZF9zdHJpbmciLAogICAgInRvb19zbWFsbCIsCiAgICAidG9vX2JpZyIsCiAgICAiaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMiLAogICAgIm5vdF9tdWx0aXBsZV9vZiIsCiAgICAibm90X2Zpbml0ZSIKICBdKTsKICBjb25zdCBxdW90ZWxlc3NKc29uID0gKG9iaikgPT4gewogICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KG9iaiwgbnVsbCwgMik7CiAgICByZXR1cm4ganNvbi5yZXBsYWNlKC8iKFteIl0rKSI6L2csICIkMToiKTsKICB9OwogIGNsYXNzIFpvZEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IoaXNzdWVzKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMuaXNzdWVzID0gW107CiAgICAgIHRoaXMuYWRkSXNzdWUgPSAoc3ViKSA9PiB7CiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbLi4udGhpcy5pc3N1ZXMsIHN1Yl07CiAgICAgIH07CiAgICAgIHRoaXMuYWRkSXNzdWVzID0gKHN1YnMgPSBbXSkgPT4gewogICAgICAgIHRoaXMuaXNzdWVzID0gWy4uLnRoaXMuaXNzdWVzLCAuLi5zdWJzXTsKICAgICAgfTsKICAgICAgY29uc3QgYWN0dWFsUHJvdG8gPSBuZXcudGFyZ2V0LnByb3RvdHlwZTsKICAgICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikgewogICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBhY3R1YWxQcm90byk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBhY3R1YWxQcm90bzsKICAgICAgfQogICAgICB0aGlzLm5hbWUgPSAiWm9kRXJyb3IiOwogICAgICB0aGlzLmlzc3VlcyA9IGlzc3VlczsKICAgIH0KICAgIGdldCBlcnJvcnMoKSB7CiAgICAgIHJldHVybiB0aGlzLmlzc3VlczsKICAgIH0KICAgIGZvcm1hdChfbWFwcGVyKSB7CiAgICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHwgZnVuY3Rpb24oaXNzdWUpIHsKICAgICAgICByZXR1cm4gaXNzdWUubWVzc2FnZTsKICAgICAgfTsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7IF9lcnJvcnM6IFtdIH07CiAgICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvcikgPT4gewogICAgICAgIGZvciAoY29uc3QgaXNzdWUgb2YgZXJyb3IuaXNzdWVzKSB7CiAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gImludmFsaWRfdW5pb24iKSB7CiAgICAgICAgICAgIGlzc3VlLnVuaW9uRXJyb3JzLm1hcChwcm9jZXNzRXJyb3IpOwogICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSAiaW52YWxpZF9yZXR1cm5fdHlwZSIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLnJldHVyblR5cGVFcnJvcik7CiAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09ICJpbnZhbGlkX2FyZ3VtZW50cyIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTsKICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUucGF0aC5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgZmllbGRFcnJvcnMuX2Vycm9ycy5wdXNoKG1hcHBlcihpc3N1ZSkpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9yczsKICAgICAgICAgICAgbGV0IGkyID0gMDsKICAgICAgICAgICAgd2hpbGUgKGkyIDwgaXNzdWUucGF0aC5sZW5ndGgpIHsKICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaTJdOwogICAgICAgICAgICAgIGNvbnN0IHRlcm1pbmFsID0gaTIgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTsKICAgICAgICAgICAgICBpZiAoIXRlcm1pbmFsKSB7CiAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCB7IF9lcnJvcnM6IFtdIH07CiAgICAgICAgICAgICAgICBjdXJyW2VsXS5fZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGN1cnIgPSBjdXJyW2VsXTsKICAgICAgICAgICAgICBpMisrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9OwogICAgICBwcm9jZXNzRXJyb3IodGhpcyk7CiAgICAgIHJldHVybiBmaWVsZEVycm9yczsKICAgIH0KICAgIHN0YXRpYyBhc3NlcnQodmFsdWUpIHsKICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBab2RFcnJvcikpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIFpvZEVycm9yOiAke3ZhbHVlfWApOwogICAgICB9CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZTsKICAgIH0KICAgIGdldCBtZXNzYWdlKCkgewogICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5pc3N1ZXMsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTsKICAgIH0KICAgIGdldCBpc0VtcHR5KCkgewogICAgICByZXR1cm4gdGhpcy5pc3N1ZXMubGVuZ3RoID09PSAwOwogICAgfQogICAgZmxhdHRlbihtYXBwZXIgPSAoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpIHsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7fTsKICAgICAgY29uc3QgZm9ybUVycm9ycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHN1YiBvZiB0aGlzLmlzc3VlcykgewogICAgICAgIGlmIChzdWIucGF0aC5sZW5ndGggPiAwKSB7CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gPSBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gfHwgW107CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0ucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvcm1FcnJvcnMucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7IGZvcm1FcnJvcnMsIGZpZWxkRXJyb3JzIH07CiAgICB9CiAgICBnZXQgZm9ybUVycm9ycygpIHsKICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpOwogICAgfQogIH0KICBab2RFcnJvci5jcmVhdGUgPSAoaXNzdWVzKSA9PiB7CiAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihpc3N1ZXMpOwogICAgcmV0dXJuIGVycm9yOwogIH07CiAgY29uc3QgZXJyb3JNYXAgPSAoaXNzdWUsIF9jdHgpID0+IHsKICAgIGxldCBtZXNzYWdlOwogICAgc3dpdGNoIChpc3N1ZS5jb2RlKSB7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZToKICAgICAgICBpZiAoaXNzdWUucmVjZWl2ZWQgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgICBtZXNzYWdlID0gIlJlcXVpcmVkIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZSA9IGBFeHBlY3RlZCAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWl2ZWQgJHtpc3N1ZS5yZWNlaXZlZH1gOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBsaXRlcmFsIHZhbHVlLCBleHBlY3RlZCAke0pTT04uc3RyaW5naWZ5KGlzc3VlLmV4cGVjdGVkLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlcil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudW5yZWNvZ25pemVkX2tleXM6CiAgICAgICAgbWVzc2FnZSA9IGBVbnJlY29nbml6ZWQga2V5KHMpIGluIG9iamVjdDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgIiwgIil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbjoKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3I6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfWA7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZToKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZW51bSB2YWx1ZS4gRXhwZWN0ZWQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUub3B0aW9ucyl9LCByZWNlaXZlZCAnJHtpc3N1ZS5yZWNlaXZlZH0nYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIGFyZ3VtZW50c2A7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGU6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIHJldHVybiB0eXBlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9kYXRlOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBkYXRlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmc6CiAgICAgICAgaWYgKHR5cGVvZiBpc3N1ZS52YWxpZGF0aW9uID09PSAib2JqZWN0IikgewogICAgICAgICAgaWYgKCJpbmNsdWRlcyIgaW4gaXNzdWUudmFsaWRhdGlvbikgewogICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQ6IG11c3QgaW5jbHVkZSAiJHtpc3N1ZS52YWxpZGF0aW9uLmluY2x1ZGVzfSJgOwogICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24ucG9zaXRpb24gPT09ICJudW1iZXIiKSB7CiAgICAgICAgICAgICAgbWVzc2FnZSA9IGAke21lc3NhZ2V9IGF0IG9uZSBvciBtb3JlIHBvc2l0aW9ucyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJHtpc3N1ZS52YWxpZGF0aW9uLnBvc2l0aW9ufWA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoInN0YXJ0c1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IHN0YXJ0IHdpdGggIiR7aXNzdWUudmFsaWRhdGlvbi5zdGFydHNXaXRofSJgOwogICAgICAgICAgfSBlbHNlIGlmICgiZW5kc1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGVuZCB3aXRoICIke2lzc3VlLnZhbGlkYXRpb24uZW5kc1dpdGh9ImA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlLnZhbGlkYXRpb24pOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoaXNzdWUudmFsaWRhdGlvbiAhPT0gInJlZ2V4IikgewogICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkICR7aXNzdWUudmFsaWRhdGlvbn1gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQiOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/ICJleGFjdGx5IiA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBsZWFzdGAgOiBgbW9yZSB0aGFuYH0gJHtpc3N1ZS5taW5pbXVtfSBlbGVtZW50KHMpYDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAic3RyaW5nIikKICAgICAgICAgIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gImV4YWN0bHkiIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IGxlYXN0YCA6IGBvdmVyYH0gJHtpc3N1ZS5taW5pbXVtfSBjaGFyYWN0ZXIocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJudW1iZXIiKQogICAgICAgICAgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke2lzc3VlLm1pbmltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiZGF0ZSIpCiAgICAgICAgICBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke25ldyBEYXRlKE51bWJlcihpc3N1ZS5taW5pbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS50b29fYmlnOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBtb3N0YCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19IGVsZW1lbnQocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJzdHJpbmciKQogICAgICAgICAgbWVzc2FnZSA9IGBTdHJpbmcgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbW9zdGAgOiBgdW5kZXJgfSAke2lzc3VlLm1heGltdW19IGNoYXJhY3RlcihzKWA7CiAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gIm51bWJlciIpCiAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgbGVzcyB0aGFuIG9yIGVxdWFsIHRvYCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiYmlnaW50IikKICAgICAgICAgIG1lc3NhZ2UgPSBgQmlnSW50IG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBsZXNzIHRoYW4gb3IgZXF1YWwgdG9gIDogYGxlc3MgdGhhbmB9ICR7aXNzdWUubWF4aW11bX1gOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJkYXRlIikKICAgICAgICAgIG1lc3NhZ2UgPSBgRGF0ZSBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgc21hbGxlciB0aGFuIG9yIGVxdWFsIHRvYCA6IGBzbWFsbGVyIHRoYW5gfSAke25ldyBEYXRlKE51bWJlcihpc3N1ZS5tYXhpbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X211bHRpcGxlX29mOgogICAgICAgIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAke2lzc3VlLm11bHRpcGxlT2Z9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZToKICAgICAgICBtZXNzYWdlID0gIk51bWJlciBtdXN0IGJlIGZpbml0ZSI7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgbWVzc2FnZSA9IF9jdHguZGVmYXVsdEVycm9yOwogICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoaXNzdWUpOwogICAgfQogICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogIH07CiAgbGV0IG92ZXJyaWRlRXJyb3JNYXAgPSBlcnJvck1hcDsKICBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHsKICAgIG92ZXJyaWRlRXJyb3JNYXAgPSBtYXA7CiAgfQogIGZ1bmN0aW9uIGdldEVycm9yTWFwKCkgewogICAgcmV0dXJuIG92ZXJyaWRlRXJyb3JNYXA7CiAgfQogIGNvbnN0IG1ha2VJc3N1ZSA9IChwYXJhbXMpID0+IHsKICAgIGNvbnN0IHsgZGF0YSwgcGF0aCwgZXJyb3JNYXBzLCBpc3N1ZURhdGEgfSA9IHBhcmFtczsKICAgIGNvbnN0IGZ1bGxQYXRoID0gWy4uLnBhdGgsIC4uLmlzc3VlRGF0YS5wYXRoIHx8IFtdXTsKICAgIGNvbnN0IGZ1bGxJc3N1ZSA9IHsKICAgICAgLi4uaXNzdWVEYXRhLAogICAgICBwYXRoOiBmdWxsUGF0aAogICAgfTsKICAgIGlmIChpc3N1ZURhdGEubWVzc2FnZSAhPT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgLi4uaXNzdWVEYXRhLAogICAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICAgIG1lc3NhZ2U6IGlzc3VlRGF0YS5tZXNzYWdlCiAgICAgIH07CiAgICB9CiAgICBsZXQgZXJyb3JNZXNzYWdlID0gIiI7CiAgICBjb25zdCBtYXBzID0gZXJyb3JNYXBzLmZpbHRlcigobTIpID0+ICEhbTIpLnNsaWNlKCkucmV2ZXJzZSgpOwogICAgZm9yIChjb25zdCBtYXAgb2YgbWFwcykgewogICAgICBlcnJvck1lc3NhZ2UgPSBtYXAoZnVsbElzc3VlLCB7IGRhdGEsIGRlZmF1bHRFcnJvcjogZXJyb3JNZXNzYWdlIH0pLm1lc3NhZ2U7CiAgICB9CiAgICByZXR1cm4gewogICAgICAuLi5pc3N1ZURhdGEsCiAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICBtZXNzYWdlOiBlcnJvck1lc3NhZ2UKICAgIH07CiAgfTsKICBjb25zdCBFTVBUWV9QQVRIID0gW107CiAgZnVuY3Rpb24gYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBpc3N1ZURhdGEpIHsKICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gZ2V0RXJyb3JNYXAoKTsKICAgIGNvbnN0IGlzc3VlID0gbWFrZUlzc3VlKHsKICAgICAgaXNzdWVEYXRhLAogICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgIGVycm9yTWFwczogWwogICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgIGN0eC5zY2hlbWFFcnJvck1hcCwKICAgICAgICBvdmVycmlkZU1hcCwKICAgICAgICBvdmVycmlkZU1hcCA9PT0gZXJyb3JNYXAgPyB2b2lkIDAgOiBlcnJvck1hcAogICAgICAgIC8vIHRoZW4gZ2xvYmFsIGRlZmF1bHQgbWFwCiAgICAgIF0uZmlsdGVyKCh4KSA9PiAhIXgpCiAgICB9KTsKICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goaXNzdWUpOwogIH0KICBjbGFzcyBQYXJzZVN0YXR1cyB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy52YWx1ZSA9ICJ2YWxpZCI7CiAgICB9CiAgICBkaXJ0eSgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgPT09ICJ2YWxpZCIpCiAgICAgICAgdGhpcy52YWx1ZSA9ICJkaXJ0eSI7CiAgICB9CiAgICBhYm9ydCgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgIT09ICJhYm9ydGVkIikKICAgICAgICB0aGlzLnZhbHVlID0gImFib3J0ZWQiOwogICAgfQogICAgc3RhdGljIG1lcmdlQXJyYXkoc3RhdHVzLCByZXN1bHRzKSB7CiAgICAgIGNvbnN0IGFycmF5VmFsdWUgPSBbXTsKICAgICAgZm9yIChjb25zdCBzMiBvZiByZXN1bHRzKSB7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGFycmF5VmFsdWUucHVzaChzMi52YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBhcnJheVZhbHVlIH07CiAgICB9CiAgICBzdGF0aWMgYXN5bmMgbWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKSB7CiAgICAgIGNvbnN0IHN5bmNQYWlycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7CiAgICAgICAgc3luY1BhaXJzLnB1c2goewogICAgICAgICAga2V5LAogICAgICAgICAgdmFsdWUKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgc3luY1BhaXJzKTsKICAgIH0KICAgIHN0YXRpYyBtZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycykgewogICAgICBjb25zdCBmaW5hbE9iamVjdCA9IHt9OwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHBhaXI7CiAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiKQogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgaWYgKHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGlmIChrZXkudmFsdWUgIT09ICJfX3Byb3RvX18iICYmICh0eXBlb2YgdmFsdWUudmFsdWUgIT09ICJ1bmRlZmluZWQiIHx8IHBhaXIuYWx3YXlzU2V0KSkgewogICAgICAgICAgZmluYWxPYmplY3Rba2V5LnZhbHVlXSA9IHZhbHVlLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGZpbmFsT2JqZWN0IH07CiAgICB9CiAgfQogIGNvbnN0IElOVkFMSUQgPSBPYmplY3QuZnJlZXplKHsKICAgIHN0YXR1czogImFib3J0ZWQiCiAgfSk7CiAgY29uc3QgRElSVFkgPSAodmFsdWUpID0+ICh7IHN0YXR1czogImRpcnR5IiwgdmFsdWUgfSk7CiAgY29uc3QgT0sgPSAodmFsdWUpID0+ICh7IHN0YXR1czogInZhbGlkIiwgdmFsdWUgfSk7CiAgY29uc3QgaXNBYm9ydGVkID0gKHgpID0+IHguc3RhdHVzID09PSAiYWJvcnRlZCI7CiAgY29uc3QgaXNEaXJ0eSA9ICh4KSA9PiB4LnN0YXR1cyA9PT0gImRpcnR5IjsKICBjb25zdCBpc1ZhbGlkID0gKHgpID0+IHguc3RhdHVzID09PSAidmFsaWQiOwogIGNvbnN0IGlzQXN5bmMgPSAoeCkgPT4gdHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHggaW5zdGFuY2VvZiBQcm9taXNlOwogIGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0Iik7CiAgICByZXR1cm4gc3RhdGUuZ2V0KHJlY2VpdmVyKTsKICB9CiAgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXQiKTsKICAgIHJldHVybiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSwgdmFsdWU7CiAgfQogIHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09ICJmdW5jdGlvbiIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbihlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkgewogICAgdmFyIGUyID0gbmV3IEVycm9yKG1lc3NhZ2UpOwogICAgcmV0dXJuIGUyLm5hbWUgPSAiU3VwcHJlc3NlZEVycm9yIiwgZTIuZXJyb3IgPSBlcnJvciwgZTIuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGUyOwogIH07CiAgdmFyIGVycm9yVXRpbDsKICAoZnVuY3Rpb24oZXJyb3JVdGlsMikgewogICAgZXJyb3JVdGlsMi5lcnJUb09iaiA9IChtZXNzYWdlKSA9PiB0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIgPyB7IG1lc3NhZ2UgfSA6IG1lc3NhZ2UgfHwge307CiAgICBlcnJvclV0aWwyLnRvU3RyaW5nID0gKG1lc3NhZ2UpID0+IHR5cGVvZiBtZXNzYWdlID09PSAic3RyaW5nIiA/IG1lc3NhZ2UgOiBtZXNzYWdlID09PSBudWxsIHx8IG1lc3NhZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1lc3NhZ2UubWVzc2FnZTsKICB9KShlcnJvclV0aWwgfHwgKGVycm9yVXRpbCA9IHt9KSk7CiAgdmFyIF9ab2RFbnVtX2NhY2hlLCBfWm9kTmF0aXZlRW51bV9jYWNoZTsKICBjbGFzcyBQYXJzZUlucHV0TGF6eVBhdGggewogICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KSB7CiAgICAgIHRoaXMuX2NhY2hlZFBhdGggPSBbXTsKICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgIHRoaXMuZGF0YSA9IHZhbHVlOwogICAgICB0aGlzLl9wYXRoID0gcGF0aDsKICAgICAgdGhpcy5fa2V5ID0ga2V5OwogICAgfQogICAgZ2V0IHBhdGgoKSB7CiAgICAgIGlmICghdGhpcy5fY2FjaGVkUGF0aC5sZW5ndGgpIHsKICAgICAgICBpZiAodGhpcy5fa2V5IGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCAuLi50aGlzLl9rZXkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLl9jYWNoZWRQYXRoLnB1c2goLi4udGhpcy5fcGF0aCwgdGhpcy5fa2V5KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFBhdGg7CiAgICB9CiAgfQogIGNvbnN0IGhhbmRsZVJlc3VsdCA9IChjdHgsIHJlc3VsdCkgPT4gewogICAgaWYgKGlzVmFsaWQocmVzdWx0KSkgewogICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBkYXRhOiByZXN1bHQudmFsdWUgfTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICghY3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJWYWxpZGF0aW9uIGZhaWxlZCBidXQgbm8gaXNzdWVzIGRldGVjdGVkLiIpOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3VjY2VzczogZmFsc2UsCiAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKQogICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3I7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihjdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICB0aGlzLl9lcnJvciA9IGVycm9yOwogICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yOwogICAgICAgIH0KICAgICAgfTsKICAgIH0KICB9OwogIGZ1bmN0aW9uIHByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSB7CiAgICBpZiAoIXBhcmFtcykKICAgICAgcmV0dXJuIHt9OwogICAgY29uc3QgeyBlcnJvck1hcDogZXJyb3JNYXAyLCBpbnZhbGlkX3R5cGVfZXJyb3IsIHJlcXVpcmVkX2Vycm9yLCBkZXNjcmlwdGlvbiB9ID0gcGFyYW1zOwogICAgaWYgKGVycm9yTWFwMiAmJiAoaW52YWxpZF90eXBlX2Vycm9yIHx8IHJlcXVpcmVkX2Vycm9yKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IHVzZSAiaW52YWxpZF90eXBlX2Vycm9yIiBvciAicmVxdWlyZWRfZXJyb3IiIGluIGNvbmp1bmN0aW9uIHdpdGggY3VzdG9tIGVycm9yIG1hcC5gKTsKICAgIH0KICAgIGlmIChlcnJvck1hcDIpCiAgICAgIHJldHVybiB7IGVycm9yTWFwOiBlcnJvck1hcDIsIGRlc2NyaXB0aW9uIH07CiAgICBjb25zdCBjdXN0b21NYXAgPSAoaXNzLCBjdHgpID0+IHsKICAgICAgdmFyIF9hLCBfYjsKICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSBwYXJhbXM7CiAgICAgIGlmIChpc3MuY29kZSA9PT0gImludmFsaWRfZW51bV92YWx1ZSIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBjdHguZGVmYXVsdEVycm9yIH07CiAgICAgIH0KICAgICAgaWYgKHR5cGVvZiBjdHguZGF0YSA9PT0gInVuZGVmaW5lZCIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2EgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiByZXF1aXJlZF9lcnJvcikgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICB9CiAgICAgIGlmIChpc3MuY29kZSAhPT0gImludmFsaWRfdHlwZSIpCiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZTogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2IgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBpbnZhbGlkX3R5cGVfZXJyb3IpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IGN0eC5kZWZhdWx0RXJyb3IgfTsKICAgIH07CiAgICByZXR1cm4geyBlcnJvck1hcDogY3VzdG9tTWFwLCBkZXNjcmlwdGlvbiB9OwogIH0KICBjbGFzcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKGRlZikgewogICAgICB0aGlzLnNwYSA9IHRoaXMuc2FmZVBhcnNlQXN5bmM7CiAgICAgIHRoaXMuX2RlZiA9IGRlZjsKICAgICAgdGhpcy5wYXJzZSA9IHRoaXMucGFyc2UuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2UgPSB0aGlzLnNhZmVQYXJzZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnBhcnNlQXN5bmMgPSB0aGlzLnBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2VBc3luYyA9IHRoaXMuc2FmZVBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zcGEgPSB0aGlzLnNwYS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnJlZmluZSA9IHRoaXMucmVmaW5lLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVmaW5lbWVudCA9IHRoaXMucmVmaW5lbWVudC5iaW5kKHRoaXMpOwogICAgICB0aGlzLnN1cGVyUmVmaW5lID0gdGhpcy5zdXBlclJlZmluZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm9wdGlvbmFsID0gdGhpcy5vcHRpb25hbC5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxhYmxlID0gdGhpcy5udWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxpc2ggPSB0aGlzLm51bGxpc2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5hcnJheSA9IHRoaXMuYXJyYXkuYmluZCh0aGlzKTsKICAgICAgdGhpcy5wcm9taXNlID0gdGhpcy5wcm9taXNlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMub3IgPSB0aGlzLm9yLmJpbmQodGhpcyk7CiAgICAgIHRoaXMuYW5kID0gdGhpcy5hbmQuYmluZCh0aGlzKTsKICAgICAgdGhpcy50cmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmJyYW5kID0gdGhpcy5icmFuZC5iaW5kKHRoaXMpOwogICAgICB0aGlzLmRlZmF1bHQgPSB0aGlzLmRlZmF1bHQuYmluZCh0aGlzKTsKICAgICAgdGhpcy5jYXRjaCA9IHRoaXMuY2F0Y2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5kZXNjcmliZSA9IHRoaXMuZGVzY3JpYmUuYmluZCh0aGlzKTsKICAgICAgdGhpcy5waXBlID0gdGhpcy5waXBlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVhZG9ubHkgPSB0aGlzLnJlYWRvbmx5LmJpbmQodGhpcyk7CiAgICAgIHRoaXMuaXNOdWxsYWJsZSA9IHRoaXMuaXNOdWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmlzT3B0aW9uYWwgPSB0aGlzLmlzT3B0aW9uYWwuYmluZCh0aGlzKTsKICAgIH0KICAgIGdldCBkZXNjcmlwdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kZXNjcmlwdGlvbjsKICAgIH0KICAgIF9nZXRUeXBlKGlucHV0KSB7CiAgICAgIHJldHVybiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpOwogICAgfQogICAgX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpIHsKICAgICAgcmV0dXJuIGN0eCB8fCB7CiAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgIGRhdGE6IGlucHV0LmRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShpbnB1dC5kYXRhKSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhdGg6IGlucHV0LnBhdGgsCiAgICAgICAgcGFyZW50OiBpbnB1dC5wYXJlbnQKICAgICAgfTsKICAgIH0KICAgIF9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBzdGF0dXM6IG5ldyBQYXJzZVN0YXR1cygpLAogICAgICAgIGN0eDogewogICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSwKICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSksCiAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgICAgcGF0aDogaW5wdXQucGF0aCwKICAgICAgICAgIHBhcmVudDogaW5wdXQucGFyZW50CiAgICAgICAgfQogICAgICB9OwogICAgfQogICAgX3BhcnNlU3luYyhpbnB1dCkgewogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9wYXJzZShpbnB1dCk7CiAgICAgIGlmIChpc0FzeW5jKHJlc3VsdCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlN5bmNocm9ub3VzIHBhcnNlIGVuY291bnRlcmVkIHByb21pc2UuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIF9wYXJzZUFzeW5jKGlucHV0KSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpOwogICAgfQogICAgcGFyc2UoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FmZVBhcnNlKGRhdGEsIHBhcmFtcyk7CiAgICAgIGlmIChyZXN1bHQuc3VjY2VzcykKICAgICAgICByZXR1cm4gcmVzdWx0LmRhdGE7CiAgICAgIHRocm93IHJlc3VsdC5lcnJvcjsKICAgIH0KICAgIHNhZmVQYXJzZShkYXRhLCBwYXJhbXMpIHsKICAgICAgdmFyIF9hOwogICAgICBjb25zdCBjdHggPSB7CiAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICBpc3N1ZXM6IFtdLAogICAgICAgICAgYXN5bmM6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5hc3luYykgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcAogICAgICAgIH0sCiAgICAgICAgcGF0aDogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5wYXRoKSB8fCBbXSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhcmVudDogbnVsbCwKICAgICAgICBkYXRhLAogICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSkKICAgICAgfTsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2VTeW5jKHsgZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgICByZXR1cm4gaGFuZGxlUmVzdWx0KGN0eCwgcmVzdWx0KTsKICAgIH0KICAgIGFzeW5jIHBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKTsKICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKQogICAgICAgIHJldHVybiByZXN1bHQuZGF0YTsKICAgICAgdGhyb3cgcmVzdWx0LmVycm9yOwogICAgfQogICAgYXN5bmMgc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IGN0eCA9IHsKICAgICAgICBjb21tb246IHsKICAgICAgICAgIGlzc3VlczogW10sCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcCwKICAgICAgICAgIGFzeW5jOiB0cnVlCiAgICAgICAgfSwKICAgICAgICBwYXRoOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLnBhdGgpIHx8IFtdLAogICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsCiAgICAgICAgcGFyZW50OiBudWxsLAogICAgICAgIGRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKQogICAgICB9OwogICAgICBjb25zdCBtYXliZUFzeW5jUmVzdWx0ID0gdGhpcy5fcGFyc2UoeyBkYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSk7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChpc0FzeW5jKG1heWJlQXN5bmNSZXN1bHQpID8gbWF5YmVBc3luY1Jlc3VsdCA6IFByb21pc2UucmVzb2x2ZShtYXliZUFzeW5jUmVzdWx0KSk7CiAgICAgIHJldHVybiBoYW5kbGVSZXN1bHQoY3R4LCByZXN1bHQpOwogICAgfQogICAgcmVmaW5lKGNoZWNrLCBtZXNzYWdlKSB7CiAgICAgIGNvbnN0IGdldElzc3VlUHJvcGVydGllcyA9ICh2YWwpID0+IHsKICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJzdHJpbmciIHx8IHR5cGVvZiBtZXNzYWdlID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlKHZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlOwogICAgICAgIH0KICAgICAgfTsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2hlY2sodmFsKTsKICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpID0+IGN0eC5hZGRJc3N1ZSh7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuY3VzdG9tLAogICAgICAgICAgLi4uZ2V0SXNzdWVQcm9wZXJ0aWVzKHZhbCkKICAgICAgICB9KTsKICAgICAgICBpZiAodHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHsKICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigoZGF0YSkgPT4gewogICAgICAgICAgICBpZiAoIWRhdGEpIHsKICAgICAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmVmaW5lbWVudChjaGVjaywgcmVmaW5lbWVudERhdGEpIHsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgaWYgKCFjaGVjayh2YWwpKSB7CiAgICAgICAgICBjdHguYWRkSXNzdWUodHlwZW9mIHJlZmluZW1lbnREYXRhID09PSAiZnVuY3Rpb24iID8gcmVmaW5lbWVudERhdGEodmFsLCBjdHgpIDogcmVmaW5lbWVudERhdGEpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoewogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJyZWZpbmVtZW50IiwgcmVmaW5lbWVudCB9CiAgICAgIH0pOwogICAgfQogICAgc3VwZXJSZWZpbmUocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudChyZWZpbmVtZW50KTsKICAgIH0KICAgIG9wdGlvbmFsKCkgewogICAgICByZXR1cm4gWm9kT3B0aW9uYWwuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7CiAgICB9CiAgICBudWxsYWJsZSgpIHsKICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgbnVsbGlzaCgpIHsKICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpOwogICAgfQogICAgYXJyYXkoKSB7CiAgICAgIHJldHVybiBab2RBcnJheS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTsKICAgIH0KICAgIHByb21pc2UoKSB7CiAgICAgIHJldHVybiBab2RQcm9taXNlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgb3Iob3B0aW9uKSB7CiAgICAgIHJldHVybiBab2RVbmlvbi5jcmVhdGUoW3RoaXMsIG9wdGlvbl0sIHRoaXMuX2RlZik7CiAgICB9CiAgICBhbmQoaW5jb21pbmcpIHsKICAgICAgcmV0dXJuIFpvZEludGVyc2VjdGlvbi5jcmVhdGUodGhpcywgaW5jb21pbmcsIHRoaXMuX2RlZik7CiAgICB9CiAgICB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlzLl9kZWYpLAogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJ0cmFuc2Zvcm0iLCB0cmFuc2Zvcm0gfQogICAgICB9KTsKICAgIH0KICAgIGRlZmF1bHQoZGVmKSB7CiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZUZ1bmMgPSB0eXBlb2YgZGVmID09PSAiZnVuY3Rpb24iID8gZGVmIDogKCkgPT4gZGVmOwogICAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgZGVmYXVsdFZhbHVlOiBkZWZhdWx0VmFsdWVGdW5jLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdAogICAgICB9KTsKICAgIH0KICAgIGJyYW5kKCkgewogICAgICByZXR1cm4gbmV3IFpvZEJyYW5kZWQoewogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZCwKICAgICAgICB0eXBlOiB0aGlzLAogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKQogICAgICB9KTsKICAgIH0KICAgIGNhdGNoKGRlZikgewogICAgICBjb25zdCBjYXRjaFZhbHVlRnVuYyA9IHR5cGVvZiBkZWYgPT09ICJmdW5jdGlvbiIgPyBkZWYgOiAoKSA9PiBkZWY7CiAgICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgY2F0Y2hWYWx1ZTogY2F0Y2hWYWx1ZUZ1bmMsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RDYXRjaAogICAgICB9KTsKICAgIH0KICAgIGRlc2NyaWJlKGRlc2NyaXB0aW9uKSB7CiAgICAgIGNvbnN0IFRoaXMgPSB0aGlzLmNvbnN0cnVjdG9yOwogICAgICByZXR1cm4gbmV3IFRoaXMoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBkZXNjcmlwdGlvbgogICAgICB9KTsKICAgIH0KICAgIHBpcGUodGFyZ2V0KSB7CiAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTsKICAgIH0KICAgIHJlYWRvbmx5KCkgewogICAgICByZXR1cm4gWm9kUmVhZG9ubHkuY3JlYXRlKHRoaXMpOwogICAgfQogICAgaXNPcHRpb25hbCgpIHsKICAgICAgcmV0dXJuIHRoaXMuc2FmZVBhcnNlKHZvaWQgMCkuc3VjY2VzczsKICAgIH0KICAgIGlzTnVsbGFibGUoKSB7CiAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzOwogICAgfQogIH0KICBjb25zdCBjdWlkUmVnZXggPSAvXmNbXlxzLV17OCx9JC9pOwogIGNvbnN0IGN1aWQyUmVnZXggPSAvXlswLTlhLXpdKyQvOwogIGNvbnN0IHVsaWRSZWdleCA9IC9eWzAtOUEtSEpLTU5QLVRWLVpdezI2fSQvOwogIGNvbnN0IHV1aWRSZWdleCA9IC9eWzAtOWEtZkEtRl17OH1cYi1bMC05YS1mQS1GXXs0fVxiLVswLTlhLWZBLUZdezR9XGItWzAtOWEtZkEtRl17NH1cYi1bMC05YS1mQS1GXXsxMn0kL2k7CiAgY29uc3QgbmFub2lkUmVnZXggPSAvXlthLXowLTlfLV17MjF9JC9pOwogIGNvbnN0IGR1cmF0aW9uUmVnZXggPSAvXlstK10/UCg/ISQpKD86KD86Wy0rXT9cZCtZKXwoPzpbLStdP1xkK1suLF1cZCtZJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzooPzpbLStdP1xkK1cpfCg/OlstK10/XGQrWy4sXVxkK1ckKSk/KD86KD86Wy0rXT9cZCtEKXwoPzpbLStdP1xkK1suLF1cZCtEJCkpPyg/OlQoPz1bXGQrLV0pKD86KD86Wy0rXT9cZCtIKXwoPzpbLStdP1xkK1suLF1cZCtIJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzpbLStdP1xkKyg/OlsuLF1cZCspP1MpPyk/PyQvOwogIGNvbnN0IGVtYWlsUmVnZXggPSAvXig/IVwuKSg/IS4qXC5cLikoW0EtWjAtOV8nK1wtXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XC1dKlwuKStbQS1aXXsyLH0kL2k7CiAgY29uc3QgX2Vtb2ppUmVnZXggPSBgXihcXHB7RXh0ZW5kZWRfUGljdG9ncmFwaGljfXxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7CiAgbGV0IGVtb2ppUmVnZXg7CiAgY29uc3QgaXB2NFJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKSQvOwogIGNvbnN0IGlwdjZSZWdleCA9IC9eKChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87CiAgY29uc3QgYmFzZTY0UmVnZXggPSAvXihbMC05YS16QS1aKy9dezR9KSooKFswLTlhLXpBLVorL117Mn09PSl8KFswLTlhLXpBLVorL117M309KSk/JC87CiAgY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYCgoXFxkXFxkWzI0NjhdWzA0OF18XFxkXFxkWzEzNTc5XVsyNl18XFxkXFxkMFs0OF18WzAyNDY4XVswNDhdMDB8WzEzNTc5XVsyNl0wMCktMDItMjl8XFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcZHwzWzAxXSl8KDBbNDY5XXwxMSktKDBbMS05XXxbMTJdXFxkfDMwKXwoMDIpLSgwWzEtOV18MVxcZHwyWzAtOF0pKSlgOwogIGNvbnN0IGRhdGVSZWdleCA9IG5ldyBSZWdFeHAoYF4ke2RhdGVSZWdleFNvdXJjZX0kYCk7CiAgZnVuY3Rpb24gdGltZVJlZ2V4U291cmNlKGFyZ3MpIHsKICAgIGxldCByZWdleCA9IGAoWzAxXVxcZHwyWzAtM10pOlswLTVdXFxkOlswLTVdXFxkYDsKICAgIGlmIChhcmdzLnByZWNpc2lvbikgewogICAgICByZWdleCA9IGAke3JlZ2V4fVxcLlxcZHske2FyZ3MucHJlY2lzaW9ufX1gOwogICAgfSBlbHNlIGlmIChhcmdzLnByZWNpc2lvbiA9PSBudWxsKSB7CiAgICAgIHJlZ2V4ID0gYCR7cmVnZXh9KFxcLlxcZCspP2A7CiAgICB9CiAgICByZXR1cm4gcmVnZXg7CiAgfQogIGZ1bmN0aW9uIHRpbWVSZWdleChhcmdzKSB7CiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfSRgKTsKICB9CiAgZnVuY3Rpb24gZGF0ZXRpbWVSZWdleChhcmdzKSB7CiAgICBsZXQgcmVnZXggPSBgJHtkYXRlUmVnZXhTb3VyY2V9VCR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfWA7CiAgICBjb25zdCBvcHRzID0gW107CiAgICBvcHRzLnB1c2goYXJncy5sb2NhbCA/IGBaP2AgOiBgWmApOwogICAgaWYgKGFyZ3Mub2Zmc2V0KQogICAgICBvcHRzLnB1c2goYChbKy1dXFxkezJ9Oj9cXGR7Mn0pYCk7CiAgICByZWdleCA9IGAke3JlZ2V4fSgke29wdHMuam9pbigifCIpfSlgOwogICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3JlZ2V4fSRgKTsKICB9CiAgZnVuY3Rpb24gaXNWYWxpZElQKGlwLCB2ZXJzaW9uKSB7CiAgICBpZiAoKHZlcnNpb24gPT09ICJ2NCIgfHwgIXZlcnNpb24pICYmIGlwdjRSZWdleC50ZXN0KGlwKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICgodmVyc2lvbiA9PT0gInY2IiB8fCAhdmVyc2lvbikgJiYgaXB2NlJlZ2V4LnRlc3QoaXApKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICBjbGFzcyBab2RTdHJpbmcgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkgewogICAgICAgIGlucHV0LmRhdGEgPSBTdHJpbmcoaW5wdXQuZGF0YSk7CiAgICAgIH0KICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcpIHsKICAgICAgICBjb25zdCBjdHgyID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eDIsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zdHJpbmcsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7CiAgICAgIGxldCBjdHggPSB2b2lkIDA7CiAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgaWYgKGlucHV0LmRhdGEubGVuZ3RoIDwgY2hlY2sudmFsdWUpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5sZW5ndGggPiBjaGVjay52YWx1ZSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJsZW5ndGgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBpbnB1dC5kYXRhLmxlbmd0aCA+IGNoZWNrLnZhbHVlOwogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZyB8fCB0b29TbWFsbCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1haWwiKSB7CiAgICAgICAgICBpZiAoIWVtYWlsUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtYWlsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1vamkiKSB7CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHsKICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsICJ1Iik7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtb2ppIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXVpZCIpIHsKICAgICAgICAgIGlmICghdXVpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1dWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibmFub2lkIikgewogICAgICAgICAgaWYgKCFuYW5vaWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAibmFub2lkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZCIpIHsKICAgICAgICAgIGlmICghY3VpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJjdWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZDIiKSB7CiAgICAgICAgICBpZiAoIWN1aWQyUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImN1aWQyIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidWxpZCIpIHsKICAgICAgICAgIGlmICghdWxpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1bGlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXJsIikgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbmV3IFVSTChpbnB1dC5kYXRhKTsKICAgICAgICAgIH0gY2F0Y2ggKF9hKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAidXJsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAicmVnZXgiKSB7CiAgICAgICAgICBjaGVjay5yZWdleC5sYXN0SW5kZXggPSAwOwogICAgICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGNoZWNrLnJlZ2V4LnRlc3QoaW5wdXQuZGF0YSk7CiAgICAgICAgICBpZiAoIXRlc3RSZXN1bHQpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJyZWdleCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInRyaW0iKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiaW5jbHVkZXMiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuaW5jbHVkZXMoY2hlY2sudmFsdWUsIGNoZWNrLnBvc2l0aW9uKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246IHsgaW5jbHVkZXM6IGNoZWNrLnZhbHVlLCBwb3NpdGlvbjogY2hlY2sucG9zaXRpb24gfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0b0xvd2VyQ2FzZSIpIHsKICAgICAgICAgIGlucHV0LmRhdGEgPSBpbnB1dC5kYXRhLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidG9VcHBlckNhc2UiKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b1VwcGVyQ2FzZSgpOwogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInN0YXJ0c1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuc3RhcnRzV2l0aChjaGVjay52YWx1ZSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IHN0YXJ0c1dpdGg6IGNoZWNrLnZhbHVlIH0sCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW5kc1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuZW5kc1dpdGgoY2hlY2sudmFsdWUpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogeyBlbmRzV2l0aDogY2hlY2sudmFsdWUgfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJkYXRldGltZSIpIHsKICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZXRpbWVSZWdleChjaGVjayk7CiAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAiZGF0ZXRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImRhdGUiKSB7CiAgICAgICAgICBjb25zdCByZWdleCA9IGRhdGVSZWdleDsKICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkYXRlIiwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0aW1lIikgewogICAgICAgICAgY29uc3QgcmVnZXggPSB0aW1lUmVnZXgoY2hlY2spOwogICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogInRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImR1cmF0aW9uIikgewogICAgICAgICAgaWYgKCFkdXJhdGlvblJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkdXJhdGlvbiIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImlwIikgewogICAgICAgICAgaWYgKCFpc1ZhbGlkSVAoaW5wdXQuZGF0YSwgY2hlY2sudmVyc2lvbikpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJpcCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImJhc2U2NCIpIHsKICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImJhc2U2NCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgICBfcmVnZXgocmVnZXgsIHZhbGlkYXRpb24sIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMucmVmaW5lbWVudCgoZGF0YSkgPT4gcmVnZXgudGVzdChkYXRhKSwgewogICAgICAgIHZhbGlkYXRpb24sCiAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIF9hZGRDaGVjayhjaGVjaykgewogICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIGVtYWlsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtYWlsIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXJsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogInVybCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGVtb2ppKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtb2ppIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXVpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1dWlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgbmFub2lkKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogIm5hbm9pZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiAiY3VpZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQyKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImN1aWQyIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdWxpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1bGlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgYmFzZTY0KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImJhc2U2NCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGlwKG9wdGlvbnMpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImlwIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpIH0pOwogICAgfQogICAgZGF0ZXRpbWUob3B0aW9ucykgewogICAgICB2YXIgX2EsIF9iOwogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJkYXRldGltZSIsCiAgICAgICAgICBwcmVjaXNpb246IG51bGwsCiAgICAgICAgICBvZmZzZXQ6IGZhbHNlLAogICAgICAgICAgbG9jYWw6IGZhbHNlLAogICAgICAgICAgbWVzc2FnZTogb3B0aW9ucwogICAgICAgIH0pOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImRhdGV0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgb2Zmc2V0OiAoX2EgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMub2Zmc2V0KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZSwKICAgICAgICBsb2NhbDogKF9iID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmxvY2FsKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBmYWxzZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLm1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgZGF0ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJkYXRlIiwgbWVzc2FnZSB9KTsKICAgIH0KICAgIHRpbWUob3B0aW9ucykgewogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICAgIHByZWNpc2lvbjogbnVsbCwKICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5tZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGR1cmF0aW9uKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImR1cmF0aW9uIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgcmVnZXgocmVnZXgsIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAicmVnZXgiLAogICAgICAgIHJlZ2V4LAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGluY2x1ZGVzKHZhbHVlLCBvcHRpb25zKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImluY2x1ZGVzIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBwb3NpdGlvbjogb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnBvc2l0aW9uLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBzdGFydHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogInN0YXJ0c1dpdGgiLAogICAgICAgIHZhbHVlLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGVuZHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImVuZHNXaXRoIiwKICAgICAgICB2YWx1ZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkxlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heExlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImxlbmd0aCIsCiAgICAgICAgdmFsdWU6IGxlbiwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXByZWNhdGVkIFVzZSB6LnN0cmluZygpLm1pbigxKSBpbnN0ZWFkLgogICAgICogQHNlZSB7QGxpbmsgWm9kU3RyaW5nLm1pbn0KICAgICAqLwogICAgbm9uZW1wdHkobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5taW4oMSwgZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpKTsKICAgIH0KICAgIHRyaW0oKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgeyBraW5kOiAidHJpbSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b0xvd2VyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b0xvd2VyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b1VwcGVyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b1VwcGVyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICBnZXQgaXNEYXRldGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImRhdGV0aW1lIik7CiAgICB9CiAgICBnZXQgaXNEYXRlKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZGF0ZSIpOwogICAgfQogICAgZ2V0IGlzVGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInRpbWUiKTsKICAgIH0KICAgIGdldCBpc0R1cmF0aW9uKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZHVyYXRpb24iKTsKICAgIH0KICAgIGdldCBpc0VtYWlsKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZW1haWwiKTsKICAgIH0KICAgIGdldCBpc1VSTCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInVybCIpOwogICAgfQogICAgZ2V0IGlzRW1vamkoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJlbW9qaSIpOwogICAgfQogICAgZ2V0IGlzVVVJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInV1aWQiKTsKICAgIH0KICAgIGdldCBpc05BTk9JRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gIm5hbm9pZCIpOwogICAgfQogICAgZ2V0IGlzQ1VJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImN1aWQiKTsKICAgIH0KICAgIGdldCBpc0NVSUQyKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiY3VpZDIiKTsKICAgIH0KICAgIGdldCBpc1VMSUQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJ1bGlkIik7CiAgICB9CiAgICBnZXQgaXNJUCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImlwIik7CiAgICB9CiAgICBnZXQgaXNCYXNlNjQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJiYXNlNjQiKTsKICAgIH0KICAgIGdldCBtaW5MZW5ndGgoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heExlbmd0aCgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXg7CiAgICB9CiAgfQogIFpvZFN0cmluZy5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICB2YXIgX2E7CiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLAogICAgICBjb2VyY2U6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gZmxvYXRTYWZlUmVtYWluZGVyKHZhbCwgc3RlcCkgewogICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoIi4iKVsxXSB8fCAiIikubGVuZ3RoOwogICAgY29uc3Qgc3RlcERlY0NvdW50ID0gKHN0ZXAudG9TdHJpbmcoKS5zcGxpdCgiLiIpWzFdIHx8ICIiKS5sZW5ndGg7CiAgICBjb25zdCBkZWNDb3VudCA9IHZhbERlY0NvdW50ID4gc3RlcERlY0NvdW50ID8gdmFsRGVjQ291bnQgOiBzdGVwRGVjQ291bnQ7CiAgICBjb25zdCB2YWxJbnQgPSBwYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZSgiLiIsICIiKSk7CiAgICBjb25zdCBzdGVwSW50ID0gcGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKCIuIiwgIiIpKTsKICAgIHJldHVybiB2YWxJbnQgJSBzdGVwSW50IC8gTWF0aC5wb3coMTAsIGRlY0NvdW50KTsKICB9CiAgY2xhc3MgWm9kTnVtYmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5taW4gPSB0aGlzLmd0ZTsKICAgICAgdGhpcy5tYXggPSB0aGlzLmx0ZTsKICAgICAgdGhpcy5zdGVwID0gdGhpcy5tdWx0aXBsZU9mOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IE51bWJlcihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bWJlcikgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm51bWJlciwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJpbnQiKSB7CiAgICAgICAgICBpZiAoIXV0aWwuaXNJbnRlZ2VyKGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgICAgIGV4cGVjdGVkOiAiaW50ZWdlciIsCiAgICAgICAgICAgICAgcmVjZWl2ZWQ6ICJmbG9hdCIsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhIDwgY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhIDw9IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb1NtYWxsKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIHR5cGU6ICJudW1iZXIiLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogIm51bWJlciIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoZmxvYXRTYWZlUmVtYWluZGVyKGlucHV0LmRhdGEsIGNoZWNrLnZhbHVlKSAhPT0gMCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9tdWx0aXBsZV9vZiwKICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJmaW5pdGUiKSB7CiAgICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9maW5pdGUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgaW50KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAiaW50IiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBwb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25wb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbm5lZ2F0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWluIiwKICAgICAgICB2YWx1ZTogMCwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBmaW5pdGUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJmaW5pdGUiLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIHNhZmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICB2YWx1ZTogTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIHZhbHVlOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICAgIGdldCBpc0ludCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiICYmIHV0aWwuaXNJbnRlZ2VyKGNoLnZhbHVlKSk7CiAgICB9CiAgICBnZXQgaXNGaW5pdGUoKSB7CiAgICAgIGxldCBtYXggPSBudWxsLCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gImZpbml0ZSIgfHwgY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShtaW4pICYmIE51bWJlci5pc0Zpbml0ZShtYXgpOwogICAgfQogIH0KICBab2ROdW1iZXIuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoewogICAgICBjaGVja3M6IFtdLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bWJlciwKICAgICAgY29lcmNlOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgfHwgZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCaWdJbnQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLm1pbiA9IHRoaXMuZ3RlOwogICAgICB0aGlzLm1heCA9IHRoaXMubHRlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IEJpZ0ludChpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJpZ2ludCkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmJpZ2ludCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBjb25zdCB0b29TbWFsbCA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPCBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPD0gY2hlY2sudmFsdWU7CiAgICAgICAgICBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgdHlwZTogImJpZ2ludCIsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWF4IikgewogICAgICAgICAgY29uc3QgdG9vQmlnID0gY2hlY2suaW5jbHVzaXZlID8gaW5wdXQuZGF0YSA+IGNoZWNrLnZhbHVlIDogaW5wdXQuZGF0YSA+PSBjaGVjay52YWx1ZTsKICAgICAgICAgIGlmICh0b29CaWcpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICAgIHR5cGU6ICJiaWdpbnQiLAogICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YSAlIGNoZWNrLnZhbHVlICE9PSBCaWdJbnQoMCkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsCiAgICAgICAgICAgICAgbXVsdGlwbGVPZjogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgcG9zaXRpdmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIHZhbHVlOiBCaWdJbnQoMCksCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbnBvc2l0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWF4IiwKICAgICAgICB2YWx1ZTogQmlnSW50KDApLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICB9CiAgWm9kQmlnSW50LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHZhciBfYTsKICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgY2hlY2tzOiBbXSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCaWdJbnQsCiAgICAgIGNvZXJjZTogKF9hID0gcGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCb29sZWFuIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKHRoaXMuX2RlZi5jb2VyY2UpIHsKICAgICAgICBpbnB1dC5kYXRhID0gQm9vbGVhbihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJvb2xlYW4pIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuYm9vbGVhbiwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQm9vbGVhbi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZEJvb2xlYW4oewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJvb2xlYW4sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGF0ZSBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IG5ldyBEYXRlKGlucHV0LmRhdGEpOwogICAgICB9CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZGF0ZSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmRhdGUsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHN0YXR1cyA9IG5ldyBQYXJzZVN0YXR1cygpOwogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBmb3IgKGNvbnN0IGNoZWNrIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA8IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICB0eXBlOiAiZGF0ZSIKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm1heCIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA+IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogImRhdGUiCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihjaGVjayk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsCiAgICAgICAgdmFsdWU6IG5ldyBEYXRlKGlucHV0LmRhdGEuZ2V0VGltZSgpKQogICAgICB9OwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIG1pbihtaW5EYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkRhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG1heChtYXhEYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heERhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGdldCBtaW5EYXRlKCkgewogICAgICBsZXQgbWluID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1pbiAhPSBudWxsID8gbmV3IERhdGUobWluKSA6IG51bGw7CiAgICB9CiAgICBnZXQgbWF4RGF0ZSgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXggIT0gbnVsbCA/IG5ldyBEYXRlKG1heCkgOiBudWxsOwogICAgfQogIH0KICBab2REYXRlLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERhdGUsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTeW1ib2wgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN5bWJvbCkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zeW1ib2wsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFN5bWJvbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZFN5bWJvbCh7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3ltYm9sLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmRlZmluZWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RVbmRlZmluZWQoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuZGVmaW5lZCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGwgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bGwpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubnVsbCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kTnVsbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGwoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RBbnkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLl9hbnkgPSB0cnVlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQW55KHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBbnksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmtub3duIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5fdW5rbm93biA9IHRydWU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmtub3duLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5rbm93bih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVW5rbm93biwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE5ldmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm5ldmVyLAogICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICB9KTsKICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICB9CiAgfQogIFpvZE5ldmVyLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kTmV2ZXIoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5ldmVyLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVm9pZCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnZvaWQsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RWb2lkKHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RWb2lkLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQXJyYXkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGRlZi5leGFjdExlbmd0aCAhPT0gbnVsbCkgewogICAgICAgIGNvbnN0IHRvb0JpZyA9IGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBjb25zdCB0b29TbWFsbCA9IGN0eC5kYXRhLmxlbmd0aCA8IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogdG9vQmlnID8gWm9kSXNzdWVDb2RlLnRvb19iaWcgOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICBtaW5pbXVtOiB0b29TbWFsbCA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHZvaWQgMCwKICAgICAgICAgICAgbWF4aW11bTogdG9vQmlnID8gZGVmLmV4YWN0TGVuZ3RoLnZhbHVlIDogdm9pZCAwLAogICAgICAgICAgICB0eXBlOiAiYXJyYXkiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiB0cnVlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYuZXhhY3RMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5taW5MZW5ndGggIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5MZW5ndGgudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJhcnJheSIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2UKICAgICAgICAgIH0pOwogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChkZWYubWF4TGVuZ3RoICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5tYXhMZW5ndGgudmFsdWUpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgbWF4aW11bTogZGVmLm1heExlbmd0aC52YWx1ZSwKICAgICAgICAgICAgdHlwZTogImFycmF5IiwKICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5tYXhMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoWy4uLmN0eC5kYXRhXS5tYXAoKGl0ZW0sIGkyKSA9PiB7CiAgICAgICAgICByZXR1cm4gZGVmLnR5cGUuX3BhcnNlQXN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpMikpOwogICAgICAgIH0pKS50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdDIpOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGNvbnN0IHJlc3VsdCA9IFsuLi5jdHguZGF0YV0ubWFwKChpdGVtLCBpMikgPT4gewogICAgICAgIHJldHVybiBkZWYudHlwZS5fcGFyc2VTeW5jKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKTsKICAgICAgfSk7CiAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0KTsKICAgIH0KICAgIGdldCBlbGVtZW50KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtaW5MZW5ndGg6IHsgdmFsdWU6IG1pbkxlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtYXhMZW5ndGg6IHsgdmFsdWU6IG1heExlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBleGFjdExlbmd0aDogeyB2YWx1ZTogbGVuLCBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkgfQogICAgICB9KTsKICAgIH0KICAgIG5vbmVtcHR5KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMubWluKDEsIG1lc3NhZ2UpOwogICAgfQogIH0KICBab2RBcnJheS5jcmVhdGUgPSAoc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICB0eXBlOiBzY2hlbWEsCiAgICAgIG1pbkxlbmd0aDogbnVsbCwKICAgICAgbWF4TGVuZ3RoOiBudWxsLAogICAgICBleGFjdExlbmd0aDogbnVsbCwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBcnJheSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGRlZXBQYXJ0aWFsaWZ5KHNjaGVtYSkgewogICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuc2hhcGUpIHsKICAgICAgICBjb25zdCBmaWVsZFNjaGVtYSA9IHNjaGVtYS5zaGFwZVtrZXldOwogICAgICAgIG5ld1NoYXBlW2tleV0gPSBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoZmllbGRTY2hlbWEpKTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4uc2NoZW1hLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RBcnJheSkgewogICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHsKICAgICAgICAuLi5zY2hlbWEuX2RlZiwKICAgICAgICB0eXBlOiBkZWVwUGFydGlhbGlmeShzY2hlbWEuZWxlbWVudCkKICAgICAgfSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9wdGlvbmFsKSB7CiAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7CiAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZFR1cGxlKSB7CiAgICAgIHJldHVybiBab2RUdXBsZS5jcmVhdGUoc2NoZW1hLml0ZW1zLm1hcCgoaXRlbSkgPT4gZGVlcFBhcnRpYWxpZnkoaXRlbSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBzY2hlbWE7CiAgICB9CiAgfQogIGNsYXNzIFpvZE9iamVjdCBleHRlbmRzIFpvZFR5cGUgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7CiAgICAgIHRoaXMuX2NhY2hlZCA9IG51bGw7CiAgICAgIHRoaXMubm9uc3RyaWN0ID0gdGhpcy5wYXNzdGhyb3VnaDsKICAgICAgdGhpcy5hdWdtZW50ID0gdGhpcy5leHRlbmQ7CiAgICB9CiAgICBfZ2V0Q2FjaGVkKCkgewogICAgICBpZiAodGhpcy5fY2FjaGVkICE9PSBudWxsKQogICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWQ7CiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICAgIGNvbnN0IGtleXMgPSB1dGlsLm9iamVjdEtleXMoc2hhcGUpOwogICAgICByZXR1cm4gdGhpcy5fY2FjaGVkID0geyBzaGFwZSwga2V5cyB9OwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7CiAgICAgICAgY29uc3QgY3R4MiA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgyLCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUub2JqZWN0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eDIucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGNvbnN0IHsgc2hhcGUsIGtleXM6IHNoYXBlS2V5cyB9ID0gdGhpcy5fZ2V0Q2FjaGVkKCk7CiAgICAgIGNvbnN0IGV4dHJhS2V5cyA9IFtdOwogICAgICBpZiAoISh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlciAmJiB0aGlzLl9kZWYudW5rbm93bktleXMgPT09ICJzdHJpcCIpKSB7CiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICAgIGlmICghc2hhcGVLZXlzLmluY2x1ZGVzKGtleSkpIHsKICAgICAgICAgICAgZXh0cmFLZXlzLnB1c2goa2V5KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgY29uc3QgcGFpcnMgPSBbXTsKICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcGVLZXlzKSB7CiAgICAgICAgY29uc3Qga2V5VmFsaWRhdG9yID0gc2hhcGVba2V5XTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGN0eC5kYXRhW2tleV07CiAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICB2YWx1ZToga2V5VmFsaWRhdG9yLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKHRoaXMuX2RlZi5jYXRjaGFsbCBpbnN0YW5jZW9mIFpvZE5ldmVyKSB7CiAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7CiAgICAgICAgaWYgKHVua25vd25LZXlzID09PSAicGFzc3Rocm91Z2giKSB7CiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5OiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGtleSB9LAogICAgICAgICAgICAgIHZhbHVlOiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGN0eC5kYXRhW2tleV0gfQogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHVua25vd25LZXlzID09PSAic3RyaWN0IikgewogICAgICAgICAgaWYgKGV4dHJhS2V5cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS51bnJlY29nbml6ZWRfa2V5cywKICAgICAgICAgICAgICBrZXlzOiBleHRyYUtleXMKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodW5rbm93bktleXMgPT09ICJzdHJpcCIpIDsKICAgICAgICBlbHNlIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgWm9kT2JqZWN0IGVycm9yOiBpbnZhbGlkIHVua25vd25LZXlzIHZhbHVlLmApOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBjYXRjaGFsbCA9IHRoaXMuX2RlZi5jYXRjaGFsbDsKICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gY3R4LmRhdGFba2V5XTsKICAgICAgICAgIHBhaXJzLnB1c2goewogICAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICAgIHZhbHVlOiBjYXRjaGFsbC5fcGFyc2UoCiAgICAgICAgICAgICAgbmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIHZhbHVlLCBjdHgucGF0aCwga2V5KQogICAgICAgICAgICAgIC8vLCBjdHguY2hpbGQoa2V5KSwgdmFsdWUsIGdldFBhcnNlZFR5cGUodmFsdWUpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTsKICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykgewogICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwYWlyLnZhbHVlOwogICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgIHZhbHVlLAogICAgICAgICAgICAgIGFsd2F5c1NldDogcGFpci5hbHdheXNTZXQKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gc3luY1BhaXJzOwogICAgICAgIH0pLnRoZW4oKHN5bmNQYWlycykgPT4gewogICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfQogICAgfQogICAgZ2V0IHNoYXBlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICB9CiAgICBzdHJpY3QobWVzc2FnZSkgewogICAgICBlcnJvclV0aWwuZXJyVG9PYmo7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICAgIC4uLm1lc3NhZ2UgIT09IHZvaWQgMCA/IHsKICAgICAgICAgIGVycm9yTWFwOiAoaXNzdWUsIGN0eCkgPT4gewogICAgICAgICAgICB2YXIgX2EsIF9iLCBfYywgX2Q7CiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRFcnJvciA9IChfYyA9IChfYiA9IChfYSA9IHRoaXMuX2RlZikuZXJyb3JNYXApID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKF9hLCBpc3N1ZSwgY3R4KS5tZXNzYWdlKSAhPT0gbnVsbCAmJiBfYyAhPT0gdm9pZCAwID8gX2MgOiBjdHguZGVmYXVsdEVycm9yOwogICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gInVucmVjb2duaXplZF9rZXlzIikKICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgbWVzc2FnZTogKF9kID0gZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLm1lc3NhZ2UpICE9PSBudWxsICYmIF9kICE9PSB2b2lkIDAgPyBfZCA6IGRlZmF1bHRFcnJvcgogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgbWVzc2FnZTogZGVmYXVsdEVycm9yCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgfSA6IHt9CiAgICAgIH0pOwogICAgfQogICAgc3RyaXAoKSB7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIKICAgICAgfSk7CiAgICB9CiAgICBwYXNzdGhyb3VnaCgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICB1bmtub3duS2V5czogInBhc3N0aHJvdWdoIgogICAgICB9KTsKICAgIH0KICAgIC8vIGNvbnN0IEF1Z21lbnRGYWN0b3J5ID0KICAgIC8vICAgPERlZiBleHRlbmRzIFpvZE9iamVjdERlZj4oZGVmOiBEZWYpID0+CiAgICAvLyAgIDxBdWdtZW50YXRpb24gZXh0ZW5kcyBab2RSYXdTaGFwZT4oCiAgICAvLyAgICAgYXVnbWVudGF0aW9uOiBBdWdtZW50YXRpb24KICAgIC8vICAgKTogWm9kT2JqZWN0PAogICAgLy8gICAgIGV4dGVuZFNoYXBlPFJldHVyblR5cGU8RGVmWyJzaGFwZSJdPiwgQXVnbWVudGF0aW9uPiwKICAgIC8vICAgICBEZWZbInVua25vd25LZXlzIl0sCiAgICAvLyAgICAgRGVmWyJjYXRjaGFsbCJdCiAgICAvLyAgID4gPT4gewogICAgLy8gICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICAgIC4uLmRlZiwKICAgIC8vICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgLy8gICAgICAgICAuLi5kZWYuc2hhcGUoKSwKICAgIC8vICAgICAgICAgLi4uYXVnbWVudGF0aW9uLAogICAgLy8gICAgICAgfSksCiAgICAvLyAgICAgfSkgYXMgYW55OwogICAgLy8gICB9OwogICAgZXh0ZW5kKGF1Z21lbnRhdGlvbikgewogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksCiAgICAgICAgICAuLi5hdWdtZW50YXRpb24KICAgICAgICB9KQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlCiAgICAgKiBpbmZlcnJlZCB0eXBlIG9mIG1lcmdlZCBvYmplY3RzLiBQbGVhc2UKICAgICAqIHVwZ3JhZGUgaWYgeW91IGFyZSBleHBlcmllbmNpbmcgaXNzdWVzLgogICAgICovCiAgICBtZXJnZShtZXJnaW5nKSB7CiAgICAgIGNvbnN0IG1lcmdlZCA9IG5ldyBab2RPYmplY3QoewogICAgICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgICAgICBzaGFwZTogKCkgPT4gKHsKICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLAogICAgICAgICAgLi4ubWVyZ2luZy5fZGVmLnNoYXBlKCkKICAgICAgICB9KSwKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdAogICAgICB9KTsKICAgICAgcmV0dXJuIG1lcmdlZDsKICAgIH0KICAgIC8vIG1lcmdlPAogICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCwKICAgIC8vICAgQXVnbWVudGF0aW9uIGV4dGVuZHMgSW5jb21pbmdbInNoYXBlIl0sCiAgICAvLyAgIE5ld091dHB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBPdXRwdXRdOiBrIGV4dGVuZHMga2V5b2YgQXVnbWVudGF0aW9uCiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVsiX291dHB1dCJdCiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXQKICAgIC8vICAgICAgID8gT3V0cHV0W2tdCiAgICAvLyAgICAgICA6IG5ldmVyOwogICAgLy8gICB9LAogICAgLy8gICBOZXdJbnB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBJbnB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb24KICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdWyJfaW5wdXQiXQogICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXQKICAgIC8vICAgICAgID8gSW5wdXRba10KICAgIC8vICAgICAgIDogbmV2ZXI7CiAgICAvLyAgIH0KICAgIC8vID4oCiAgICAvLyAgIG1lcmdpbmc6IEluY29taW5nCiAgICAvLyApOiBab2RPYmplY3Q8CiAgICAvLyAgIGV4dGVuZFNoYXBlPFQsIFJldHVyblR5cGU8SW5jb21pbmdbIl9kZWYiXVsic2hhcGUiXT4+LAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJ1bmtub3duS2V5cyJdLAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJjYXRjaGFsbCJdLAogICAgLy8gICBOZXdPdXRwdXQsCiAgICAvLyAgIE5ld0lucHV0CiAgICAvLyA+IHsKICAgIC8vICAgY29uc3QgbWVyZ2VkOiBhbnkgPSBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLAogICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsCiAgICAvLyAgICAgc2hhcGU6ICgpID0+CiAgICAvLyAgICAgICBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKHRoaXMuX2RlZi5zaGFwZSgpLCBtZXJnaW5nLl9kZWYuc2hhcGUoKSksCiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAvLyAgIH0pIGFzIGFueTsKICAgIC8vICAgcmV0dXJuIG1lcmdlZDsKICAgIC8vIH0KICAgIHNldEtleShrZXksIHNjaGVtYSkgewogICAgICByZXR1cm4gdGhpcy5hdWdtZW50KHsgW2tleV06IHNjaGVtYSB9KTsKICAgIH0KICAgIC8vIG1lcmdlPEluY29taW5nIGV4dGVuZHMgQW55Wm9kT2JqZWN0PigKICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmcKICAgIC8vICk6IC8vWm9kT2JqZWN0PFQgJiBJbmNvbWluZ1siX3NoYXBlIl0sIFVua25vd25LZXlzLCBDYXRjaGFsbD4gPSAobWVyZ2luZykgPT4gewogICAgLy8gWm9kT2JqZWN0PAogICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nWyJfZGVmIl1bInNoYXBlIl0+PiwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsidW5rbm93bktleXMiXSwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsiY2F0Y2hhbGwiXQogICAgLy8gPiB7CiAgICAvLyAgIC8vIGNvbnN0IG1lcmdlZFNoYXBlID0gb2JqZWN0VXRpbC5tZXJnZVNoYXBlcygKICAgIC8vICAgLy8gICB0aGlzLl9kZWYuc2hhcGUoKSwKICAgIC8vICAgLy8gICBtZXJnaW5nLl9kZWYuc2hhcGUoKQogICAgLy8gICAvLyApOwogICAgLy8gICBjb25zdCBtZXJnZWQ6IGFueSA9IG5ldyBab2RPYmplY3QoewogICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAvLyAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgIC8vICAgICBzaGFwZTogKCkgPT4KICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSwKICAgIC8vICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCwKICAgIC8vICAgfSkgYXMgYW55OwogICAgLy8gICByZXR1cm4gbWVyZ2VkOwogICAgLy8gfQogICAgY2F0Y2hhbGwoaW5kZXgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjYXRjaGFsbDogaW5kZXgKICAgICAgfSk7CiAgICB9CiAgICBwaWNrKG1hc2spIHsKICAgICAgY29uc3Qgc2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKG1hc2spLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrW2tleV0gJiYgdGhpcy5zaGFwZVtrZXldKSB7CiAgICAgICAgICBzaGFwZVtrZXldID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IHNoYXBlCiAgICAgIH0pOwogICAgfQogICAgb21pdChtYXNrKSB7CiAgICAgIGNvbnN0IHNoYXBlID0ge307CiAgICAgIHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKS5mb3JFYWNoKChrZXkpID0+IHsKICAgICAgICBpZiAoIW1hc2tba2V5XSkgewogICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogQGRlcHJlY2F0ZWQKICAgICAqLwogICAgZGVlcFBhcnRpYWwoKSB7CiAgICAgIHJldHVybiBkZWVwUGFydGlhbGlmeSh0aGlzKTsKICAgIH0KICAgIHBhcnRpYWwobWFzaykgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgY29uc3QgZmllbGRTY2hlbWEgPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkgewogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXdTaGFwZVtrZXldID0gZmllbGRTY2hlbWEub3B0aW9uYWwoKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBuZXdTaGFwZQogICAgICB9KTsKICAgIH0KICAgIHJlcXVpcmVkKG1hc2spIHsKICAgICAgY29uc3QgbmV3U2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrICYmICFtYXNrW2tleV0pIHsKICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgICAgbGV0IG5ld0ZpZWxkID0gZmllbGRTY2hlbWE7CiAgICAgICAgICB3aGlsZSAobmV3RmllbGQgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICAgICAgICBuZXdGaWVsZCA9IG5ld0ZpZWxkLl9kZWYuaW5uZXJUeXBlOwogICAgICAgICAgfQogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IG5ld0ZpZWxkOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfQogICAga2V5b2YoKSB7CiAgICAgIHJldHVybiBjcmVhdGVab2RFbnVtKHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSk7CiAgICB9CiAgfQogIFpvZE9iamVjdC5jcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZTogKCkgPT4gc2hhcGUsCiAgICAgIHVua25vd25LZXlzOiAic3RyaXAiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LmxhenljcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIsCiAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmlvbiBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZGVmLm9wdGlvbnM7CiAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3VsdHMocmVzdWx0cykgewogICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHsKICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gInZhbGlkIikgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykgewogICAgICAgICAgaWYgKHJlc3VsdC5yZXN1bHQuc3RhdHVzID09PSAiZGlydHkiKSB7CiAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4ucmVzdWx0LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4gbmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sCiAgICAgICAgICB1bmlvbkVycm9ycwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKG9wdGlvbnMubWFwKGFzeW5jIChvcHRpb24pID0+IHsKICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0gewogICAgICAgICAgICAuLi5jdHgsCiAgICAgICAgICAgIGNvbW1vbjogewogICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICAgICAgaXNzdWVzOiBbXQogICAgICAgICAgICB9LAogICAgICAgICAgICBwYXJlbnQ6IG51bGwKICAgICAgICAgIH07CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICByZXN1bHQ6IGF3YWl0IG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eAogICAgICAgICAgICB9KSwKICAgICAgICAgICAgY3R4OiBjaGlsZEN0eAogICAgICAgICAgfTsKICAgICAgICB9KSkudGhlbihoYW5kbGVSZXN1bHRzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZXQgZGlydHkgPSB2b2lkIDA7CiAgICAgICAgY29uc3QgaXNzdWVzID0gW107CiAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykgewogICAgICAgICAgY29uc3QgY2hpbGRDdHggPSB7CiAgICAgICAgICAgIC4uLmN0eCwKICAgICAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbiwKICAgICAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHBhcmVudDogbnVsbAogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4CiAgICAgICAgICB9KTsKICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAidmFsaWQiKSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJkaXJ0eSIgJiYgIWRpcnR5KSB7CiAgICAgICAgICAgIGRpcnR5ID0geyByZXN1bHQsIGN0eDogY2hpbGRDdHggfTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChjaGlsZEN0eC5jb21tb24uaXNzdWVzLmxlbmd0aCkgewogICAgICAgICAgICBpc3N1ZXMucHVzaChjaGlsZEN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRpcnR5KSB7CiAgICAgICAgICBjdHguY29tbW9uLmlzc3Vlcy5wdXNoKC4uLmRpcnR5LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIHJldHVybiBkaXJ0eS5yZXN1bHQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gaXNzdWVzLm1hcCgoaXNzdWVzMikgPT4gbmV3IFpvZEVycm9yKGlzc3VlczIpKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uLAogICAgICAgICAgdW5pb25FcnJvcnMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgfQogICAgZ2V0IG9wdGlvbnMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uczsKICAgIH0KICB9CiAgWm9kVW5pb24uY3JlYXRlID0gKHR5cGVzLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5pb24oewogICAgICBvcHRpb25zOiB0eXBlcywKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmlvbiwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNvbnN0IGdldERpc2NyaW1pbmF0b3IgPSAodHlwZSkgPT4gewogICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMYXp5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUuc2NoZW1hKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEVmZmVjdHMpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5pbm5lclR5cGUoKSk7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMaXRlcmFsKSB7CiAgICAgIHJldHVybiBbdHlwZS52YWx1ZV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RFbnVtKSB7CiAgICAgIHJldHVybiB0eXBlLm9wdGlvbnM7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROYXRpdmVFbnVtKSB7CiAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyh0eXBlLmVudW0pOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRGVmYXVsdCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFVuZGVmaW5lZCkgewogICAgICByZXR1cm4gW3ZvaWQgMF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsKSB7CiAgICAgIHJldHVybiBbbnVsbF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICByZXR1cm4gW3ZvaWQgMCwgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsYWJsZSkgewogICAgICByZXR1cm4gW251bGwsIC4uLmdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSldOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQnJhbmRlZCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFJlYWRvbmx5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUudW53cmFwKCkpOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQ2F0Y2gpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5fZGVmLmlubmVyVHlwZSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gW107CiAgICB9CiAgfTsKICBjbGFzcyBab2REaXNjcmltaW5hdGVkVW5pb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3IgPSB0aGlzLmRpc2NyaW1pbmF0b3I7CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZSA9IGN0eC5kYXRhW2Rpc2NyaW1pbmF0b3JdOwogICAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnNNYXAuZ2V0KGRpc2NyaW1pbmF0b3JWYWx1ZSk7CiAgICAgIGlmICghb3B0aW9uKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yLAogICAgICAgICAgb3B0aW9uczogQXJyYXkuZnJvbSh0aGlzLm9wdGlvbnNNYXAua2V5cygpKSwKICAgICAgICAgIHBhdGg6IFtkaXNjcmltaW5hdG9yXQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGdldCBkaXNjcmltaW5hdG9yKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmRpc2NyaW1pbmF0b3I7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zOwogICAgfQogICAgZ2V0IG9wdGlvbnNNYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uc01hcDsKICAgIH0KICAgIC8qKgogICAgICogVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBkaXNjcmltaW5hdGVkIHVuaW9uIHNjaGVtYS4gSXRzIGJlaGF2aW91ciBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhhdCBvZiB0aGUgbm9ybWFsIHoudW5pb24oKSBjb25zdHJ1Y3Rvci4KICAgICAqIEhvd2V2ZXIsIGl0IG9ubHkgYWxsb3dzIGEgdW5pb24gb2Ygb2JqZWN0cywgYWxsIG9mIHdoaWNoIG5lZWQgdG8gc2hhcmUgYSBkaXNjcmltaW5hdG9yIHByb3BlcnR5LiBUaGlzIHByb3BlcnR5IG11c3QKICAgICAqIGhhdmUgYSBkaWZmZXJlbnQgdmFsdWUgZm9yIGVhY2ggb2JqZWN0IGluIHRoZSB1bmlvbi4KICAgICAqIEBwYXJhbSBkaXNjcmltaW5hdG9yIHRoZSBuYW1lIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5CiAgICAgKiBAcGFyYW0gdHlwZXMgYW4gYXJyYXkgb2Ygb2JqZWN0IHNjaGVtYXMKICAgICAqIEBwYXJhbSBwYXJhbXMKICAgICAqLwogICAgc3RhdGljIGNyZWF0ZShkaXNjcmltaW5hdG9yLCBvcHRpb25zLCBwYXJhbXMpIHsKICAgICAgY29uc3Qgb3B0aW9uc01hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKSB7CiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlcyA9IGdldERpc2NyaW1pbmF0b3IodHlwZS5zaGFwZVtkaXNjcmltaW5hdG9yXSk7CiAgICAgICAgaWYgKCFkaXNjcmltaW5hdG9yVmFsdWVzLmxlbmd0aCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIGRpc2NyaW1pbmF0b3IgdmFsdWUgZm9yIGtleSBcYCR7ZGlzY3JpbWluYXRvcn1cYCBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gYWxsIHNjaGVtYSBvcHRpb25zYCk7CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZGlzY3JpbWluYXRvclZhbHVlcykgewogICAgICAgICAgaWYgKG9wdGlvbnNNYXAuaGFzKHZhbHVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc2NyaW1pbmF0b3IgcHJvcGVydHkgJHtTdHJpbmcoZGlzY3JpbWluYXRvcil9IGhhcyBkdXBsaWNhdGUgdmFsdWUgJHtTdHJpbmcodmFsdWUpfWApOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uc01hcC5zZXQodmFsdWUsIHR5cGUpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZERpc2NyaW1pbmF0ZWRVbmlvbih7CiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REaXNjcmltaW5hdGVkVW5pb24sCiAgICAgICAgZGlzY3JpbWluYXRvciwKICAgICAgICBvcHRpb25zLAogICAgICAgIG9wdGlvbnNNYXAsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBmdW5jdGlvbiBtZXJnZVZhbHVlcyhhMiwgYikgewogICAgY29uc3QgYVR5cGUgPSBnZXRQYXJzZWRUeXBlKGEyKTsKICAgIGNvbnN0IGJUeXBlID0gZ2V0UGFyc2VkVHlwZShiKTsKICAgIGlmIChhMiA9PT0gYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUub2JqZWN0ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICBjb25zdCBiS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhiKTsKICAgICAgY29uc3Qgc2hhcmVkS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhhMikuZmlsdGVyKChrZXkpID0+IGJLZXlzLmluZGV4T2Yoa2V5KSAhPT0gLTEpOwogICAgICBjb25zdCBuZXdPYmogPSB7IC4uLmEyLCAuLi5iIH07CiAgICAgIGZvciAoY29uc3Qga2V5IG9mIHNoYXJlZEtleXMpIHsKICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGEyW2tleV0sIGJba2V5XSk7CiAgICAgICAgaWYgKCFzaGFyZWRWYWx1ZS52YWxpZCkgewogICAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgICAgfQogICAgICAgIG5ld09ialtrZXldID0gc2hhcmVkVmFsdWUuZGF0YTsKICAgICAgfQogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogbmV3T2JqIH07CiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7CiAgICAgIGlmIChhMi5sZW5ndGggIT09IGIubGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgIH0KICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTsKICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGEyLmxlbmd0aDsgaW5kZXgrKykgewogICAgICAgIGNvbnN0IGl0ZW1BID0gYTJbaW5kZXhdOwogICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07CiAgICAgICAgY29uc3Qgc2hhcmVkVmFsdWUgPSBtZXJnZVZhbHVlcyhpdGVtQSwgaXRlbUIpOwogICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHsKICAgICAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgICAgIH0KICAgICAgICBuZXdBcnJheS5wdXNoKHNoYXJlZFZhbHVlLmRhdGEpOwogICAgICB9CiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCBkYXRhOiBuZXdBcnJheSB9OwogICAgfSBlbHNlIGlmIChhVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5kYXRlICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmRhdGUgJiYgK2EyID09PSArYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgfQogIH0KICBjbGFzcyBab2RJbnRlcnNlY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBoYW5kbGVQYXJzZWQgPSAocGFyc2VkTGVmdCwgcGFyc2VkUmlnaHQpID0+IHsKICAgICAgICBpZiAoaXNBYm9ydGVkKHBhcnNlZExlZnQpIHx8IGlzQWJvcnRlZChwYXJzZWRSaWdodCkpIHsKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIH0KICAgICAgICBjb25zdCBtZXJnZWQgPSBtZXJnZVZhbHVlcyhwYXJzZWRMZWZ0LnZhbHVlLCBwYXJzZWRSaWdodC52YWx1ZSk7CiAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMKICAgICAgICAgIH0pOwogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgfQogICAgICAgIGlmIChpc0RpcnR5KHBhcnNlZExlZnQpIHx8IGlzRGlydHkocGFyc2VkUmlnaHQpKSB7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBtZXJnZWQuZGF0YSB9OwogICAgICB9OwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbCiAgICAgICAgICB0aGlzLl9kZWYubGVmdC5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pLAogICAgICAgICAgdGhpcy5fZGVmLnJpZ2h0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSkKICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKSA9PiBoYW5kbGVQYXJzZWQobGVmdCwgcmlnaHQpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaGFuZGxlUGFyc2VkKHRoaXMuX2RlZi5sZWZ0Ll9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSksIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VTeW5jKHsKICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgIH0pKTsKICAgICAgfQogICAgfQogIH0KICBab2RJbnRlcnNlY3Rpb24uY3JlYXRlID0gKGxlZnQsIHJpZ2h0LCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHsKICAgICAgbGVmdCwKICAgICAgcmlnaHQsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYXJyYXkpIHsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguZGF0YS5sZW5ndGggPCB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgbWluaW11bTogdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCwKICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgIHR5cGU6ICJhcnJheSIKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCByZXN0ID0gdGhpcy5fZGVmLnJlc3Q7CiAgICAgIGlmICghcmVzdCAmJiBjdHguZGF0YS5sZW5ndGggPiB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgIG1heGltdW06IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgsCiAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICB0eXBlOiAiYXJyYXkiCiAgICAgICAgfSk7CiAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgIH0KICAgICAgY29uc3QgaXRlbXMgPSBbLi4uY3R4LmRhdGFdLm1hcCgoaXRlbSwgaXRlbUluZGV4KSA9PiB7CiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5fZGVmLml0ZW1zW2l0ZW1JbmRleF0gfHwgdGhpcy5fZGVmLnJlc3Q7CiAgICAgICAgaWYgKCFzY2hlbWEpCiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpOwogICAgICB9KS5maWx0ZXIoKHgpID0+ICEheCk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGl0ZW1zKS50aGVuKChyZXN1bHRzKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpOwogICAgICAgIH0pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgaXRlbXMpOwogICAgICB9CiAgICB9CiAgICBnZXQgaXRlbXMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7CiAgICB9CiAgICByZXN0KHJlc3QpIHsKICAgICAgcmV0dXJuIG5ldyBab2RUdXBsZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHJlc3QKICAgICAgfSk7CiAgICB9CiAgfQogIFpvZFR1cGxlLmNyZWF0ZSA9IChzY2hlbWFzLCBwYXJhbXMpID0+IHsKICAgIGlmICghQXJyYXkuaXNBcnJheShzY2hlbWFzKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIllvdSBtdXN0IHBhc3MgYW4gYXJyYXkgb2Ygc2NoZW1hcyB0byB6LnR1cGxlKFsgLi4uIF0pIik7CiAgICB9CiAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHsKICAgICAgaXRlbXM6IHNjaGVtYXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVHVwbGUsCiAgICAgIHJlc3Q6IG51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RSZWNvcmQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHBhaXJzID0gW107CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICBwYWlycy5wdXNoKHsKICAgICAgICAgIGtleToga2V5VHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGtleSwgY3R4LnBhdGgsIGtleSkpLAogICAgICAgICAgdmFsdWU6IHZhbHVlVHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGN0eC5kYXRhW2tleV0sIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpOwogICAgICB9CiAgICB9CiAgICBnZXQgZWxlbWVudCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBzdGF0aWMgY3JlYXRlKGZpcnN0LCBzZWNvbmQsIHRoaXJkKSB7CiAgICAgIGlmIChzZWNvbmQgaW5zdGFuY2VvZiBab2RUeXBlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoewogICAgICAgICAga2V5VHlwZTogZmlyc3QsCiAgICAgICAgICB2YWx1ZVR5cGU6IHNlY29uZCwKICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLAogICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlyZCkKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZFJlY29yZCh7CiAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLAogICAgICAgIHZhbHVlVHlwZTogZmlyc3QsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWNvcmQsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RNYXAgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm1hcCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm1hcCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgY29uc3QgcGFpcnMgPSBbLi4uY3R4LmRhdGEuZW50cmllcygpXS5tYXAoKFtrZXksIHZhbHVlXSwgaW5kZXgpID0+IHsKICAgICAgICByZXR1cm4gewogICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwgW2luZGV4LCAia2V5Il0pKSwKICAgICAgICAgIHZhbHVlOiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIFtpbmRleCwgInZhbHVlIl0pKQogICAgICAgIH07CiAgICAgIH0pOwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIGNvbnN0IGZpbmFsTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgcGFpci5rZXk7CiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTsKICAgICAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikgewogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiIHx8IHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsTWFwLnNldChrZXkudmFsdWUsIHZhbHVlLnZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBmaW5hbE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKSB7CiAgICAgICAgICBjb25zdCBrZXkgPSBwYWlyLmtleTsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFpci52YWx1ZTsKICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiYWJvcnRlZCIgfHwgdmFsdWUuc3RhdHVzID09PSAiYWJvcnRlZCIpIHsKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gImRpcnR5IiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJkaXJ0eSIpIHsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgfQogICAgfQogIH0KICBab2RNYXAuY3JlYXRlID0gKGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE1hcCh7CiAgICAgIHZhbHVlVHlwZSwKICAgICAga2V5VHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RNYXAsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTZXQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc2V0KSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3QgZGVmID0gdGhpcy5fZGVmOwogICAgICBpZiAoZGVmLm1pblNpemUgIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEuc2l6ZSA8IGRlZi5taW5TaXplLnZhbHVlKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCwKICAgICAgICAgICAgbWluaW11bTogZGVmLm1pblNpemUudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJzZXQiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgbWVzc2FnZTogZGVmLm1pblNpemUubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5tYXhTaXplICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPiBkZWYubWF4U2l6ZS52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICBtYXhpbXVtOiBkZWYubWF4U2l6ZS52YWx1ZSwKICAgICAgICAgICAgdHlwZTogInNldCIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWF4U2l6ZS5tZXNzYWdlCiAgICAgICAgICB9KTsKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLl9kZWYudmFsdWVUeXBlOwogICAgICBmdW5jdGlvbiBmaW5hbGl6ZVNldChlbGVtZW50czIpIHsKICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpOwogICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50czIpIHsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBwYXJzZWRTZXQuYWRkKGVsZW1lbnQudmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHBhcnNlZFNldCB9OwogICAgICB9CiAgICAgIGNvbnN0IGVsZW1lbnRzID0gWy4uLmN0eC5kYXRhLnZhbHVlcygpXS5tYXAoKGl0ZW0sIGkyKSA9PiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKSk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGVsZW1lbnRzKS50aGVuKChlbGVtZW50czIpID0+IGZpbmFsaXplU2V0KGVsZW1lbnRzMikpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmaW5hbGl6ZVNldChlbGVtZW50cyk7CiAgICAgIH0KICAgIH0KICAgIG1pbihtaW5TaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU2V0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgbWluU2l6ZTogeyB2YWx1ZTogbWluU2l6ZSwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4U2l6ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gbmV3IFpvZFNldCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIG1heFNpemU6IHsgdmFsdWU6IG1heFNpemUsIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9CiAgICAgIH0pOwogICAgfQogICAgc2l6ZShzaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbihzaXplLCBtZXNzYWdlKS5tYXgoc2l6ZSwgbWVzc2FnZSk7CiAgICB9CiAgICBub25lbXB0eShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbigxLCBtZXNzYWdlKTsKICAgIH0KICB9CiAgWm9kU2V0LmNyZWF0ZSA9ICh2YWx1ZVR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RTZXQoewogICAgICB2YWx1ZVR5cGUsCiAgICAgIG1pblNpemU6IG51bGwsCiAgICAgIG1heFNpemU6IG51bGwsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU2V0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRnVuY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLnZhbGlkYXRlID0gdGhpcy5pbXBsZW1lbnQ7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbikgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmZ1bmN0aW9uLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgZnVuY3Rpb24gbWFrZUFyZ3NJc3N1ZShhcmdzLCBlcnJvcikgewogICAgICAgIHJldHVybiBtYWtlSXNzdWUoewogICAgICAgICAgZGF0YTogYXJncywKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgZXJyb3JNYXBzOiBbCiAgICAgICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsCiAgICAgICAgICAgIGdldEVycm9yTWFwKCksCiAgICAgICAgICAgIGVycm9yTWFwCiAgICAgICAgICBdLmZpbHRlcigoeCkgPT4gISF4KSwKICAgICAgICAgIGlzc3VlRGF0YTogewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHMsCiAgICAgICAgICAgIGFyZ3VtZW50c0Vycm9yOiBlcnJvcgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIG1ha2VSZXR1cm5zSXNzdWUocmV0dXJucywgZXJyb3IpIHsKICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHsKICAgICAgICAgIGRhdGE6IHJldHVybnMsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIGVycm9yTWFwczogWwogICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCwKICAgICAgICAgICAgY3R4LnNjaGVtYUVycm9yTWFwLAogICAgICAgICAgICBnZXRFcnJvck1hcCgpLAogICAgICAgICAgICBlcnJvck1hcAogICAgICAgICAgXS5maWx0ZXIoKHgpID0+ICEheCksCiAgICAgICAgICBpc3N1ZURhdGE6IHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGUsCiAgICAgICAgICAgIHJldHVyblR5cGVFcnJvcjogZXJyb3IKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgICBjb25zdCBwYXJhbXMgPSB7IGVycm9yTWFwOiBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCB9OwogICAgICBjb25zdCBmbiA9IGN0eC5kYXRhOwogICAgICBpZiAodGhpcy5fZGVmLnJldHVybnMgaW5zdGFuY2VvZiBab2RQcm9taXNlKSB7CiAgICAgICAgY29uc3QgbWUgPSB0aGlzOwogICAgICAgIHJldHVybiBPSyhhc3luYyBmdW5jdGlvbiguLi5hcmdzKSB7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihbXSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gYXdhaXQgbWUuX2RlZi5hcmdzLnBhcnNlQXN5bmMoYXJncywgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZUFyZ3NJc3N1ZShhcmdzLCBlMikpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUmVmbGVjdC5hcHBseShmbiwgdGhpcywgcGFyc2VkQXJncyk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gYXdhaXQgbWUuX2RlZi5yZXR1cm5zLl9kZWYudHlwZS5wYXJzZUFzeW5jKHJlc3VsdCwgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZVJldHVybnNJc3N1ZShyZXN1bHQsIGUyKSk7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gcGFyc2VkUmV0dXJuczsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBtZSA9IHRoaXM7CiAgICAgICAgcmV0dXJuIE9LKGZ1bmN0aW9uKC4uLmFyZ3MpIHsKICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBtZS5fZGVmLmFyZ3Muc2FmZVBhcnNlKGFyZ3MsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZEFyZ3Muc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VBcmdzSXNzdWUoYXJncywgcGFyc2VkQXJncy5lcnJvcildKTsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXMsIHBhcnNlZEFyZ3MuZGF0YSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gbWUuX2RlZi5yZXR1cm5zLnNhZmVQYXJzZShyZXN1bHQsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZFJldHVybnMuc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBwYXJzZWRSZXR1cm5zLmVycm9yKV0pOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHBhcnNlZFJldHVybnMuZGF0YTsKICAgICAgICB9KTsKICAgICAgfQogICAgfQogICAgcGFyYW1ldGVycygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5hcmdzOwogICAgfQogICAgcmV0dXJuVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5yZXR1cm5zOwogICAgfQogICAgYXJncyguLi5pdGVtcykgewogICAgICByZXR1cm4gbmV3IFpvZEZ1bmN0aW9uKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgYXJnczogWm9kVHVwbGUuY3JlYXRlKGl0ZW1zKS5yZXN0KFpvZFVua25vd24uY3JlYXRlKCkpCiAgICAgIH0pOwogICAgfQogICAgcmV0dXJucyhyZXR1cm5UeXBlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICByZXR1cm5zOiByZXR1cm5UeXBlCiAgICAgIH0pOwogICAgfQogICAgaW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RyaWN0SW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RhdGljIGNyZWF0ZShhcmdzLCByZXR1cm5zLCBwYXJhbXMpIHsKICAgICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7CiAgICAgICAgYXJnczogYXJncyA/IGFyZ3MgOiBab2RUdXBsZS5jcmVhdGUoW10pLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksCiAgICAgICAgcmV0dXJuczogcmV0dXJucyB8fCBab2RVbmtub3duLmNyZWF0ZSgpLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRnVuY3Rpb24sCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBnZXQgc2NoZW1hKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmdldHRlcigpOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpOwogICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2UoeyBkYXRhOiBjdHguZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgfQogIH0KICBab2RMYXp5LmNyZWF0ZSA9IChnZXR0ZXIsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RMYXp5KHsKICAgICAgZ2V0dGVyLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExhenksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKGlucHV0LmRhdGEgIT09IHRoaXMuX2RlZi52YWx1ZSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSwKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2xpdGVyYWwsCiAgICAgICAgICBleHBlY3RlZDogdGhpcy5fZGVmLnZhbHVlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZTogaW5wdXQuZGF0YSB9OwogICAgfQogICAgZ2V0IHZhbHVlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlOwogICAgfQogIH0KICBab2RMaXRlcmFsLmNyZWF0ZSA9ICh2YWx1ZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZExpdGVyYWwoewogICAgICB2YWx1ZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RMaXRlcmFsLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gY3JlYXRlWm9kRW51bSh2YWx1ZXMsIHBhcmFtcykgewogICAgcmV0dXJuIG5ldyBab2RFbnVtKHsKICAgICAgdmFsdWVzLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVudW0sCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfQogIGNsYXNzIFpvZEVudW0gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICBfWm9kRW51bV9jYWNoZS5zZXQodGhpcywgdm9pZCAwKTsKICAgIH0KICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09ICJzdHJpbmciKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlczsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2RFbnVtX2NhY2hlLCBuZXcgU2V0KHRoaXMuX2RlZi52YWx1ZXMpKTsKICAgICAgfQogICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1pvZEVudW1fY2FjaGUpLmhhcyhpbnB1dC5kYXRhKSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHRoaXMuX2RlZi52YWx1ZXM7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICByZWNlaXZlZDogY3R4LmRhdGEsCiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlLAogICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7CiAgICB9CiAgICBnZXQgZW51bSgpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IFZhbHVlcygpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IEVudW0oKSB7CiAgICAgIGNvbnN0IGVudW1WYWx1ZXMgPSB7fTsKICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5fZGVmLnZhbHVlcykgewogICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDsKICAgICAgfQogICAgICByZXR1cm4gZW51bVZhbHVlczsKICAgIH0KICAgIGV4dHJhY3QodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHsKICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHZhbHVlcywgewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICAuLi5uZXdEZWYKICAgICAgfSk7CiAgICB9CiAgICBleGNsdWRlKHZhbHVlcywgbmV3RGVmID0gdGhpcy5fZGVmKSB7CiAgICAgIHJldHVybiBab2RFbnVtLmNyZWF0ZSh0aGlzLm9wdGlvbnMuZmlsdGVyKChvcHQpID0+ICF2YWx1ZXMuaW5jbHVkZXMob3B0KSksIHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgLi4ubmV3RGVmCiAgICAgIH0pOwogICAgfQogIH0KICBfWm9kRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZEVudW0uY3JlYXRlID0gY3JlYXRlWm9kRW51bTsKICBjbGFzcyBab2ROYXRpdmVFbnVtIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgX1pvZE5hdGl2ZUVudW1fY2FjaGUuc2V0KHRoaXMsIHZvaWQgMCk7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgbmF0aXZlRW51bVZhbHVlcyA9IHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpOwogICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcgJiYgY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVtYmVyKSB7CiAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB1dGlsLm9iamVjdFZhbHVlcyhuYXRpdmVFbnVtVmFsdWVzKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kTmF0aXZlRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlLCBuZXcgU2V0KHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpKSk7CiAgICAgIH0KICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlKS5oYXMoaW5wdXQuZGF0YSkpIHsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHV0aWwub2JqZWN0VmFsdWVzKG5hdGl2ZUVudW1WYWx1ZXMpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZSwKICAgICAgICAgIG9wdGlvbnM6IGV4cGVjdGVkVmFsdWVzCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogICAgZ2V0IGVudW0oKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYudmFsdWVzOwogICAgfQogIH0KICBfWm9kTmF0aXZlRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZE5hdGl2ZUVudW0uY3JlYXRlID0gKHZhbHVlcywgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hdGl2ZUVudW0oewogICAgICB2YWx1ZXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmF0aXZlRW51bSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZFByb21pc2UgZXh0ZW5kcyBab2RUeXBlIHsKICAgIHVud3JhcCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUucHJvbWlzZSAmJiBjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnByb21pc2UsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7CiAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKSA9PiB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlLnBhcnNlQXN5bmMoZGF0YSwgewogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBlcnJvck1hcDogY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAKICAgICAgICB9KTsKICAgICAgfSkpOwogICAgfQogIH0KICBab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RQcm9taXNlKHsKICAgICAgdHlwZTogc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFByb21pc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RFZmZlY3RzIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBpbm5lclR5cGUoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hOwogICAgfQogICAgc291cmNlVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMgPyB0aGlzLl9kZWYuc2NoZW1hLnNvdXJjZVR5cGUoKSA6IHRoaXMuX2RlZi5zY2hlbWE7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZWZmZWN0ID0gdGhpcy5fZGVmLmVmZmVjdCB8fCBudWxsOwogICAgICBjb25zdCBjaGVja0N0eCA9IHsKICAgICAgICBhZGRJc3N1ZTogKGFyZykgPT4gewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBhcmcpOwogICAgICAgICAgaWYgKGFyZy5mYXRhbCkgewogICAgICAgICAgICBzdGF0dXMuYWJvcnQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZ2V0IHBhdGgoKSB7CiAgICAgICAgICByZXR1cm4gY3R4LnBhdGg7CiAgICAgICAgfQogICAgICB9OwogICAgICBjaGVja0N0eC5hZGRJc3N1ZSA9IGNoZWNrQ3R4LmFkZElzc3VlLmJpbmQoY2hlY2tDdHgpOwogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJwcmVwcm9jZXNzIikgewogICAgICAgIGNvbnN0IHByb2Nlc3NlZCA9IGVmZmVjdC50cmFuc2Zvcm0oY3R4LmRhdGEsIGNoZWNrQ3R4KTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwcm9jZXNzZWQpLnRoZW4oYXN5bmMgKHByb2Nlc3NlZDIpID0+IHsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBwcm9jZXNzZWQyLAogICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiZGlydHkiKQogICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gInJlZmluZW1lbnQiKSB7CiAgICAgICAgY29uc3QgZXhlY3V0ZVJlZmluZW1lbnQgPSAoYWNjKSA9PiB7CiAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QucmVmaW5lbWVudChhY2MsIGNoZWNrQ3R4KTsKICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQXN5bmMgcmVmaW5lbWVudCBlbmNvdW50ZXJlZCBkdXJpbmcgc3luY2hyb25vdXMgcGFyc2Ugb3BlcmF0aW9uLiBVc2UgLnBhcnNlQXN5bmMgaW5zdGVhZC4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBhY2M7CiAgICAgICAgfTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYyA9PT0gZmFsc2UpIHsKICAgICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGlubmVyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSk7CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlubmVyLnZhbHVlIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsgZGF0YTogY3R4LmRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KS50aGVuKChpbm5lcikgPT4gewogICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09ICJkaXJ0eSIpCiAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICAgIHJldHVybiBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSkudGhlbigoKSA9PiB7CiAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbm5lci52YWx1ZSB9OwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJ0cmFuc2Zvcm0iKSB7CiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMgPT09IGZhbHNlKSB7CiAgICAgICAgICBjb25zdCBiYXNlID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgIHJldHVybiBiYXNlOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCk7CiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jaHJvbm91cyB0cmFuc2Zvcm0gZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuYCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHJlc3VsdCB9OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VBc3luYyh7IGRhdGE6IGN0eC5kYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSkudGhlbigoYmFzZSkgPT4gewogICAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgICAgcmV0dXJuIGJhc2U7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCkpLnRoZW4oKHJlc3VsdCkgPT4gKHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiByZXN1bHQgfSkpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoZWZmZWN0KTsKICAgIH0KICB9CiAgWm9kRWZmZWN0cy5jcmVhdGUgPSAoc2NoZW1hLCBlZmZlY3QsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHsKICAgICAgc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgIGVmZmVjdCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3MgPSAocHJlcHJvY2Vzcywgc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgIHNjaGVtYSwKICAgICAgZWZmZWN0OiB7IHR5cGU6ICJwcmVwcm9jZXNzIiwgdHJhbnNmb3JtOiBwcmVwcm9jZXNzIH0sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cywKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE9wdGlvbmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4gT0sodm9pZCAwKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPcHRpb25hbCh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGxhYmxlIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7CiAgICAgICAgcmV0dXJuIE9LKG51bGwpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7CiAgICB9CiAgICB1bndyYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlOwogICAgfQogIH0KICBab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGxhYmxlKHsKICAgICAgaW5uZXJUeXBlOiB0eXBlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGxhYmxlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGVmYXVsdCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgZGF0YSA9IHRoaXMuX2RlZi5kZWZhdWx0VmFsdWUoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoewogICAgICAgIGRhdGEsCiAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiBjdHgKICAgICAgfSk7CiAgICB9CiAgICByZW1vdmVEZWZhdWx0KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kRGVmYXVsdC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdCwKICAgICAgZGVmYXVsdFZhbHVlOiB0eXBlb2YgcGFyYW1zLmRlZmF1bHQgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuZGVmYXVsdCA6ICgpID0+IHBhcmFtcy5kZWZhdWx0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQ2F0Y2ggZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgbmV3Q3R4ID0gewogICAgICAgIC4uLmN0eCwKICAgICAgICBjb21tb246IHsKICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7CiAgICAgICAgZGF0YTogbmV3Q3R4LmRhdGEsCiAgICAgICAgcGF0aDogbmV3Q3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiB7CiAgICAgICAgICAuLi5uZXdDdHgKICAgICAgICB9CiAgICAgIH0pOwogICAgICBpZiAoaXNBc3luYyhyZXN1bHQpKSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJ2YWxpZCIsCiAgICAgICAgICAgIHZhbHVlOiByZXN1bHQyLnN0YXR1cyA9PT0gInZhbGlkIiA/IHJlc3VsdDIudmFsdWUgOiB0aGlzLl9kZWYuY2F0Y2hWYWx1ZSh7CiAgICAgICAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICBpbnB1dDogbmV3Q3R4LmRhdGEKICAgICAgICAgICAgfSkKICAgICAgICAgIH07CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHN0YXR1czogInZhbGlkIiwKICAgICAgICAgIHZhbHVlOiByZXN1bHQuc3RhdHVzID09PSAidmFsaWQiID8gcmVzdWx0LnZhbHVlIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoewogICAgICAgICAgICBnZXQgZXJyb3IoKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGlucHV0OiBuZXdDdHguZGF0YQogICAgICAgICAgfSkKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgICByZW1vdmVDYXRjaCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7CiAgICB9CiAgfQogIFpvZENhdGNoLmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2gsCiAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBwYXJhbXMuY2F0Y2ggPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuY2F0Y2ggOiAoKSA9PiBwYXJhbXMuY2F0Y2gsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2ROYU4gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm5hbikgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5uYW4sCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6ICJ2YWxpZCIsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgfQogIFpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hTih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmFOLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY29uc3QgQlJBTkQgPSBTeW1ib2woInpvZF9icmFuZCIpOwogIGNsYXNzIFpvZEJyYW5kZWQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZGF0YSA9IGN0eC5kYXRhOwogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGUuX3BhcnNlKHsKICAgICAgICBkYXRhLAogICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgIHBhcmVudDogY3R4CiAgICAgIH0pOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgfQogIGNsYXNzIFpvZFBpcGVsaW5lIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICBjb25zdCBoYW5kbGVBc3luYyA9IGFzeW5jICgpID0+IHsKICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgICAgcmV0dXJuIERJUlRZKGluUmVzdWx0LnZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYub3V0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBpblJlc3VsdC52YWx1ZSwKICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHJldHVybiBoYW5kbGVBc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGluUmVzdWx0ID0gdGhpcy5fZGVmLmluLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJkaXJ0eSIsCiAgICAgICAgICAgIHZhbHVlOiBpblJlc3VsdC52YWx1ZQogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlU3luYyh7CiAgICAgICAgICAgIGRhdGE6IGluUmVzdWx0LnZhbHVlLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgc3RhdGljIGNyZWF0ZShhMiwgYikgewogICAgICByZXR1cm4gbmV3IFpvZFBpcGVsaW5lKHsKICAgICAgICBpbjogYTIsCiAgICAgICAgb3V0OiBiLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUGlwZWxpbmUKICAgICAgfSk7CiAgICB9CiAgfQogIGNsYXNzIFpvZFJlYWRvbmx5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgICBjb25zdCBmcmVlemUgPSAoZGF0YSkgPT4gewogICAgICAgIGlmIChpc1ZhbGlkKGRhdGEpKSB7CiAgICAgICAgICBkYXRhLnZhbHVlID0gT2JqZWN0LmZyZWV6ZShkYXRhLnZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgIH07CiAgICAgIHJldHVybiBpc0FzeW5jKHJlc3VsdCkgPyByZXN1bHQudGhlbigoZGF0YSkgPT4gZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kUmVhZG9ubHkuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGN1c3RvbShjaGVjaywgcGFyYW1zID0ge30sIGZhdGFsKSB7CiAgICBpZiAoY2hlY2spCiAgICAgIHJldHVybiBab2RBbnkuY3JlYXRlKCkuc3VwZXJSZWZpbmUoKGRhdGEsIGN0eCkgPT4gewogICAgICAgIHZhciBfYSwgX2I7CiAgICAgICAgaWYgKCFjaGVjayhkYXRhKSkgewogICAgICAgICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMoZGF0YSkgOiB0eXBlb2YgcGFyYW1zID09PSAic3RyaW5nIiA/IHsgbWVzc2FnZTogcGFyYW1zIH0gOiBwYXJhbXM7CiAgICAgICAgICBjb25zdCBfZmF0YWwgPSAoX2IgPSAoX2EgPSBwLmZhdGFsKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYXRhbCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogdHJ1ZTsKICAgICAgICAgIGNvbnN0IHAyID0gdHlwZW9mIHAgPT09ICJzdHJpbmciID8geyBtZXNzYWdlOiBwIH0gOiBwOwogICAgICAgICAgY3R4LmFkZElzc3VlKHsgY29kZTogImN1c3RvbSIsIC4uLnAyLCBmYXRhbDogX2ZhdGFsIH0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICByZXR1cm4gWm9kQW55LmNyZWF0ZSgpOwogIH0KICBjb25zdCBsYXRlID0gewogICAgb2JqZWN0OiBab2RPYmplY3QubGF6eWNyZWF0ZQogIH07CiAgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDsKICAoZnVuY3Rpb24oWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMikgewogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kU3RyaW5nIl0gPSAiWm9kU3RyaW5nIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bWJlciJdID0gIlpvZE51bWJlciI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYU4iXSA9ICJab2ROYU4iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQmlnSW50Il0gPSAiWm9kQmlnSW50IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZEJvb2xlYW4iXSA9ICJab2RCb29sZWFuIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZERhdGUiXSA9ICJab2REYXRlIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFN5bWJvbCJdID0gIlpvZFN5bWJvbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RVbmRlZmluZWQiXSA9ICJab2RVbmRlZmluZWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kTnVsbCJdID0gIlpvZE51bGwiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQW55Il0gPSAiWm9kQW55IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFVua25vd24iXSA9ICJab2RVbmtub3duIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE5ldmVyIl0gPSAiWm9kTmV2ZXIiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVm9pZCJdID0gIlpvZFZvaWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQXJyYXkiXSA9ICJab2RBcnJheSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPYmplY3QiXSA9ICJab2RPYmplY3QiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVW5pb24iXSA9ICJab2RVbmlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2REaXNjcmltaW5hdGVkVW5pb24iXSA9ICJab2REaXNjcmltaW5hdGVkVW5pb24iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kSW50ZXJzZWN0aW9uIl0gPSAiWm9kSW50ZXJzZWN0aW9uIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFR1cGxlIl0gPSAiWm9kVHVwbGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kUmVjb3JkIl0gPSAiWm9kUmVjb3JkIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE1hcCJdID0gIlpvZE1hcCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RTZXQiXSA9ICJab2RTZXQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRnVuY3Rpb24iXSA9ICJab2RGdW5jdGlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMYXp5Il0gPSAiWm9kTGF6eSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMaXRlcmFsIl0gPSAiWm9kTGl0ZXJhbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFbnVtIl0gPSAiWm9kRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFZmZlY3RzIl0gPSAiWm9kRWZmZWN0cyI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYXRpdmVFbnVtIl0gPSAiWm9kTmF0aXZlRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPcHRpb25hbCJdID0gIlpvZE9wdGlvbmFsIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bGxhYmxlIl0gPSAiWm9kTnVsbGFibGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRGVmYXVsdCJdID0gIlpvZERlZmF1bHQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQ2F0Y2giXSA9ICJab2RDYXRjaCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQcm9taXNlIl0gPSAiWm9kUHJvbWlzZSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RCcmFuZGVkIl0gPSAiWm9kQnJhbmRlZCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQaXBlbGluZSJdID0gIlpvZFBpcGVsaW5lIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFJlYWRvbmx5Il0gPSAiWm9kUmVhZG9ubHkiOwogIH0pKFpvZEZpcnN0UGFydHlUeXBlS2luZCB8fCAoWm9kRmlyc3RQYXJ0eVR5cGVLaW5kID0ge30pKTsKICBjb25zdCBpbnN0YW5jZU9mVHlwZSA9IChjbHMsIHBhcmFtcyA9IHsKICAgIG1lc3NhZ2U6IGBJbnB1dCBub3QgaW5zdGFuY2Ugb2YgJHtjbHMubmFtZX1gCiAgfSkgPT4gY3VzdG9tKChkYXRhKSA9PiBkYXRhIGluc3RhbmNlb2YgY2xzLCBwYXJhbXMpOwogIGNvbnN0IHN0cmluZ1R5cGUgPSBab2RTdHJpbmcuY3JlYXRlOwogIGNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlOwogIGNvbnN0IG5hblR5cGUgPSBab2ROYU4uY3JlYXRlOwogIGNvbnN0IGJpZ0ludFR5cGUgPSBab2RCaWdJbnQuY3JlYXRlOwogIGNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7CiAgY29uc3QgZGF0ZVR5cGUgPSBab2REYXRlLmNyZWF0ZTsKICBjb25zdCBzeW1ib2xUeXBlID0gWm9kU3ltYm9sLmNyZWF0ZTsKICBjb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTsKICBjb25zdCBudWxsVHlwZSA9IFpvZE51bGwuY3JlYXRlOwogIGNvbnN0IGFueVR5cGUgPSBab2RBbnkuY3JlYXRlOwogIGNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7CiAgY29uc3QgbmV2ZXJUeXBlID0gWm9kTmV2ZXIuY3JlYXRlOwogIGNvbnN0IHZvaWRUeXBlID0gWm9kVm9pZC5jcmVhdGU7CiAgY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlOwogIGNvbnN0IG9iamVjdFR5cGUgPSBab2RPYmplY3QuY3JlYXRlOwogIGNvbnN0IHN0cmljdE9iamVjdFR5cGUgPSBab2RPYmplY3Quc3RyaWN0Q3JlYXRlOwogIGNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBkaXNjcmltaW5hdGVkVW5pb25UeXBlID0gWm9kRGlzY3JpbWluYXRlZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBpbnRlcnNlY3Rpb25UeXBlID0gWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZTsKICBjb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7CiAgY29uc3QgcmVjb3JkVHlwZSA9IFpvZFJlY29yZC5jcmVhdGU7CiAgY29uc3QgbWFwVHlwZSA9IFpvZE1hcC5jcmVhdGU7CiAgY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7CiAgY29uc3QgZnVuY3Rpb25UeXBlID0gWm9kRnVuY3Rpb24uY3JlYXRlOwogIGNvbnN0IGxhenlUeXBlID0gWm9kTGF6eS5jcmVhdGU7CiAgY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTsKICBjb25zdCBlbnVtVHlwZSA9IFpvZEVudW0uY3JlYXRlOwogIGNvbnN0IG5hdGl2ZUVudW1UeXBlID0gWm9kTmF0aXZlRW51bS5jcmVhdGU7CiAgY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTsKICBjb25zdCBlZmZlY3RzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlOwogIGNvbnN0IG9wdGlvbmFsVHlwZSA9IFpvZE9wdGlvbmFsLmNyZWF0ZTsKICBjb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7CiAgY29uc3QgcHJlcHJvY2Vzc1R5cGUgPSBab2RFZmZlY3RzLmNyZWF0ZVdpdGhQcmVwcm9jZXNzOwogIGNvbnN0IHBpcGVsaW5lVHlwZSA9IFpvZFBpcGVsaW5lLmNyZWF0ZTsKICBjb25zdCBvc3RyaW5nID0gKCkgPT4gc3RyaW5nVHlwZSgpLm9wdGlvbmFsKCk7CiAgY29uc3Qgb251bWJlciA9ICgpID0+IG51bWJlclR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IG9ib29sZWFuID0gKCkgPT4gYm9vbGVhblR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IGNvZXJjZSA9IHsKICAgIHN0cmluZzogKGFyZykgPT4gWm9kU3RyaW5nLmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgbnVtYmVyOiAoYXJnKSA9PiBab2ROdW1iZXIuY3JlYXRlKHsgLi4uYXJnLCBjb2VyY2U6IHRydWUgfSksCiAgICBib29sZWFuOiAoYXJnKSA9PiBab2RCb29sZWFuLmNyZWF0ZSh7CiAgICAgIC4uLmFyZywKICAgICAgY29lcmNlOiB0cnVlCiAgICB9KSwKICAgIGJpZ2ludDogKGFyZykgPT4gWm9kQmlnSW50LmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgZGF0ZTogKGFyZykgPT4gWm9kRGF0ZS5jcmVhdGUoeyAuLi5hcmcsIGNvZXJjZTogdHJ1ZSB9KQogIH07CiAgY29uc3QgTkVWRVIgPSBJTlZBTElEOwogIHZhciB6JDEgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmZyZWV6ZSh7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBkZWZhdWx0RXJyb3JNYXA6IGVycm9yTWFwLAogICAgc2V0RXJyb3JNYXAsCiAgICBnZXRFcnJvck1hcCwKICAgIG1ha2VJc3N1ZSwKICAgIEVNUFRZX1BBVEgsCiAgICBhZGRJc3N1ZVRvQ29udGV4dCwKICAgIFBhcnNlU3RhdHVzLAogICAgSU5WQUxJRCwKICAgIERJUlRZLAogICAgT0ssCiAgICBpc0Fib3J0ZWQsCiAgICBpc0RpcnR5LAogICAgaXNWYWxpZCwKICAgIGlzQXN5bmMsCiAgICBnZXQgdXRpbCgpIHsKICAgICAgcmV0dXJuIHV0aWw7CiAgICB9LAogICAgZ2V0IG9iamVjdFV0aWwoKSB7CiAgICAgIHJldHVybiBvYmplY3RVdGlsOwogICAgfSwKICAgIFpvZFBhcnNlZFR5cGUsCiAgICBnZXRQYXJzZWRUeXBlLAogICAgWm9kVHlwZSwKICAgIGRhdGV0aW1lUmVnZXgsCiAgICBab2RTdHJpbmcsCiAgICBab2ROdW1iZXIsCiAgICBab2RCaWdJbnQsCiAgICBab2RCb29sZWFuLAogICAgWm9kRGF0ZSwKICAgIFpvZFN5bWJvbCwKICAgIFpvZFVuZGVmaW5lZCwKICAgIFpvZE51bGwsCiAgICBab2RBbnksCiAgICBab2RVbmtub3duLAogICAgWm9kTmV2ZXIsCiAgICBab2RWb2lkLAogICAgWm9kQXJyYXksCiAgICBab2RPYmplY3QsCiAgICBab2RVbmlvbiwKICAgIFpvZERpc2NyaW1pbmF0ZWRVbmlvbiwKICAgIFpvZEludGVyc2VjdGlvbiwKICAgIFpvZFR1cGxlLAogICAgWm9kUmVjb3JkLAogICAgWm9kTWFwLAogICAgWm9kU2V0LAogICAgWm9kRnVuY3Rpb24sCiAgICBab2RMYXp5LAogICAgWm9kTGl0ZXJhbCwKICAgIFpvZEVudW0sCiAgICBab2ROYXRpdmVFbnVtLAogICAgWm9kUHJvbWlzZSwKICAgIFpvZEVmZmVjdHMsCiAgICBab2RUcmFuc2Zvcm1lcjogWm9kRWZmZWN0cywKICAgIFpvZE9wdGlvbmFsLAogICAgWm9kTnVsbGFibGUsCiAgICBab2REZWZhdWx0LAogICAgWm9kQ2F0Y2gsCiAgICBab2ROYU4sCiAgICBCUkFORCwKICAgIFpvZEJyYW5kZWQsCiAgICBab2RQaXBlbGluZSwKICAgIFpvZFJlYWRvbmx5LAogICAgY3VzdG9tLAogICAgU2NoZW1hOiBab2RUeXBlLAogICAgWm9kU2NoZW1hOiBab2RUeXBlLAogICAgbGF0ZSwKICAgIGdldCBab2RGaXJzdFBhcnR5VHlwZUtpbmQoKSB7CiAgICAgIHJldHVybiBab2RGaXJzdFBhcnR5VHlwZUtpbmQ7CiAgICB9LAogICAgY29lcmNlLAogICAgYW55OiBhbnlUeXBlLAogICAgYXJyYXk6IGFycmF5VHlwZSwKICAgIGJpZ2ludDogYmlnSW50VHlwZSwKICAgIGJvb2xlYW46IGJvb2xlYW5UeXBlLAogICAgZGF0ZTogZGF0ZVR5cGUsCiAgICBkaXNjcmltaW5hdGVkVW5pb246IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUsCiAgICBlZmZlY3Q6IGVmZmVjdHNUeXBlLAogICAgImVudW0iOiBlbnVtVHlwZSwKICAgICJmdW5jdGlvbiI6IGZ1bmN0aW9uVHlwZSwKICAgICJpbnN0YW5jZW9mIjogaW5zdGFuY2VPZlR5cGUsCiAgICBpbnRlcnNlY3Rpb246IGludGVyc2VjdGlvblR5cGUsCiAgICBsYXp5OiBsYXp5VHlwZSwKICAgIGxpdGVyYWw6IGxpdGVyYWxUeXBlLAogICAgbWFwOiBtYXBUeXBlLAogICAgbmFuOiBuYW5UeXBlLAogICAgbmF0aXZlRW51bTogbmF0aXZlRW51bVR5cGUsCiAgICBuZXZlcjogbmV2ZXJUeXBlLAogICAgIm51bGwiOiBudWxsVHlwZSwKICAgIG51bGxhYmxlOiBudWxsYWJsZVR5cGUsCiAgICBudW1iZXI6IG51bWJlclR5cGUsCiAgICBvYmplY3Q6IG9iamVjdFR5cGUsCiAgICBvYm9vbGVhbiwKICAgIG9udW1iZXIsCiAgICBvcHRpb25hbDogb3B0aW9uYWxUeXBlLAogICAgb3N0cmluZywKICAgIHBpcGVsaW5lOiBwaXBlbGluZVR5cGUsCiAgICBwcmVwcm9jZXNzOiBwcmVwcm9jZXNzVHlwZSwKICAgIHByb21pc2U6IHByb21pc2VUeXBlLAogICAgcmVjb3JkOiByZWNvcmRUeXBlLAogICAgc2V0OiBzZXRUeXBlLAogICAgc3RyaWN0T2JqZWN0OiBzdHJpY3RPYmplY3RUeXBlLAogICAgc3RyaW5nOiBzdHJpbmdUeXBlLAogICAgc3ltYm9sOiBzeW1ib2xUeXBlLAogICAgdHJhbnNmb3JtZXI6IGVmZmVjdHNUeXBlLAogICAgdHVwbGU6IHR1cGxlVHlwZSwKICAgICJ1bmRlZmluZWQiOiB1bmRlZmluZWRUeXBlLAogICAgdW5pb246IHVuaW9uVHlwZSwKICAgIHVua25vd246IHVua25vd25UeXBlLAogICAgInZvaWQiOiB2b2lkVHlwZSwKICAgIE5FVkVSLAogICAgWm9kSXNzdWVDb2RlLAogICAgcXVvdGVsZXNzSnNvbiwKICAgIFpvZEVycm9yCiAgfSk7CiAgeiQxLm9iamVjdCh7CiAgICBudWNsZW90aWRlU2VxdWVuY2VzOiB6JDEuYXJyYXkoCiAgICAgIHokMS5vYmplY3QoewogICAgICAgIG5hbWU6IHokMS5zdHJpbmcoKSwKICAgICAgICBzZXF1ZW5jZTogeiQxLnN0cmluZygpCiAgICAgIH0pCiAgICApLAogICAgZ2VuZXM6IHokMS5hcnJheSgKICAgICAgeiQxLm9iamVjdCh7CiAgICAgICAgbmFtZTogeiQxLnN0cmluZygpLAogICAgICAgIHNlcXVlbmNlOiB6JDEuc3RyaW5nKCkKICAgICAgfSkKICAgICkKICB9KTsKICBjb25zdCBvcmRlckJ5VHlwZSA9IHokMS5lbnVtKFsiYXNjZW5kaW5nIiwgImRlc2NlbmRpbmciXSk7CiAgY29uc3Qgb3JkZXJCeSA9IHokMS5vYmplY3QoewogICAgZmllbGQ6IHokMS5zdHJpbmcoKSwKICAgIHR5cGU6IG9yZGVyQnlUeXBlCiAgfSk7CiAgY29uc3QgbGFwaXNCYXNlUmVxdWVzdCA9IHokMS5vYmplY3QoewogICAgbGltaXQ6IHokMS5udW1iZXIoKS5vcHRpb25hbCgpLAogICAgb2Zmc2V0OiB6JDEubnVtYmVyKCkub3B0aW9uYWwoKSwKICAgIGZpZWxkczogeiQxLmFycmF5KHokMS5zdHJpbmcoKSkub3B0aW9uYWwoKSwKICAgIG9yZGVyQnk6IHokMS5hcnJheShvcmRlckJ5KS5vcHRpb25hbCgpCiAgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuYm9vbGVhbigpLCB6JDEudW5kZWZpbmVkKCksIHokMS5zdHJpbmcoKSwgeiQxLm51bWJlcigpLCB6JDEubnVsbCgpLCB6JDEuYXJyYXkoeiQxLnN0cmluZygpKV0pKTsKICBsYXBpc0Jhc2VSZXF1ZXN0LmV4dGVuZCh7IG1pblByb3BvcnRpb246IHokMS5udW1iZXIoKS5vcHRpb25hbCgpIH0pOwogIGNvbnN0IG11dGF0aW9uUHJvcG9ydGlvbkNvdW50ID0geiQxLm9iamVjdCh7CiAgICBtdXRhdGlvbjogeiQxLnN0cmluZygpLAogICAgcHJvcG9ydGlvbjogeiQxLm51bWJlcigpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKSwKICAgIG11dGF0aW9uRnJvbTogeiQxLnN0cmluZygpLAogICAgbXV0YXRpb25UbzogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKQogIH0pOwogIGNvbnN0IG11dGF0aW9uc1Jlc3BvbnNlID0gbWFrZUxhcGlzUmVzcG9uc2UoeiQxLmFycmF5KG11dGF0aW9uUHJvcG9ydGlvbkNvdW50KSk7CiAgY29uc3QgaW5zZXJ0aW9uQ291bnQgPSB6JDEub2JqZWN0KHsKICAgIGluc2VydGlvbjogeiQxLnN0cmluZygpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIGluc2VydGVkU3ltYm9sczogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKQogIH0pOwogIG1ha2VMYXBpc1Jlc3BvbnNlKHokMS5hcnJheShpbnNlcnRpb25Db3VudCkpOwogIGNvbnN0IGFnZ3JlZ2F0ZWRJdGVtID0geiQxLm9iamVjdCh7IGNvdW50OiB6JDEubnVtYmVyKCkgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udW1iZXIoKSwgeiQxLm51bGwoKV0pKTsKICBjb25zdCBhZ2dyZWdhdGVkUmVzcG9uc2UgPSBtYWtlTGFwaXNSZXNwb25zZSh6JDEuYXJyYXkoYWdncmVnYXRlZEl0ZW0pKTsKICBmdW5jdGlvbiBtYWtlTGFwaXNSZXNwb25zZShkYXRhKSB7CiAgICByZXR1cm4geiQxLm9iamVjdCh7CiAgICAgIGRhdGEKICAgIH0pOwogIH0KICBjb25zdCBwcm9ibGVtRGV0YWlsID0geiQxLm9iamVjdCh7CiAgICB0aXRsZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICBzdGF0dXM6IHokMS5udW1iZXIoKSwKICAgIGRldGFpbDogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICB0eXBlOiB6JDEuc3RyaW5nKCksCiAgICBpbnN0YW5jZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCkKICB9KTsKICBjb25zdCBsYXBpc0Vycm9yID0geiQxLm9iamVjdCh7CiAgICBlcnJvcjogcHJvYmxlbURldGFpbAogIH0pOwogIGNsYXNzIFVua25vd25MYXBpc0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzLCByZXF1ZXN0ZWREYXRhKSB7CiAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIlVua25vd25MYXBpc0Vycm9yIjsKICAgIH0KICB9CiAgY2xhc3MgTGFwaXNFcnJvciBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHN0YXR1cywgcHJvYmxlbURldGFpbDIsIHJlcXVlc3RlZERhdGEpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzOwogICAgICB0aGlzLnByb2JsZW1EZXRhaWwgPSBwcm9ibGVtRGV0YWlsMjsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIkxhcGlzRXJyb3IiOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBmZXRjaEFnZ3JlZ2F0ZWQobGFwaXNVcmwsIGJvZHksIHNpZ25hbCkgewogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjYWxsTGFwaXMoCiAgICAgIGFnZ3JlZ2F0ZWRFbmRwb2ludChsYXBpc1VybCksCiAgICAgIHsKICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICBoZWFkZXJzOiB7CiAgICAgICAgICAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgfSwKICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSwKICAgICAgICBzaWduYWwKICAgICAgfSwKICAgICAgImFnZ3JlZ2F0ZWQgZGF0YSIKICAgICk7CiAgICByZXR1cm4gYWdncmVnYXRlZFJlc3BvbnNlLnBhcnNlKGF3YWl0IHJlc3BvbnNlLmpzb24oKSk7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIGZldGNoU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGxhcGlzVXJsLCBib2R5LCBzZXF1ZW5jZVR5cGUsIHNpZ25hbCkgewogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjYWxsTGFwaXMoCiAgICAgIHN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc0VuZHBvaW50KGxhcGlzVXJsLCBzZXF1ZW5jZVR5cGUpLAogICAgICB7CiAgICAgICAgbWV0aG9kOiAiUE9TVCIsCiAgICAgICAgaGVhZGVyczogewogICAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIH0sCiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksCiAgICAgICAgc2lnbmFsCiAgICAgIH0sCiAgICAgIGAke3NlcXVlbmNlVHlwZX0gbXV0YXRpb25zYAogICAgKTsKICAgIHJldHVybiBtdXRhdGlvbnNSZXNwb25zZS5wYXJzZShhd2FpdCByZXNwb25zZS5qc29uKCkpOwogIH0KICBhc3luYyBmdW5jdGlvbiBjYWxsTGFwaXMoaW5wdXQsIGluaXQsIHJlcXVlc3RlZERhdGFOYW1lKSB7CiAgICB0cnkgewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGlucHV0LCBpbml0KTsKICAgICAgYXdhaXQgaGFuZGxlRXJyb3JzKHJlc3BvbnNlLCByZXF1ZXN0ZWREYXRhTmFtZSk7CiAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGAke2Vycm9yfWA7CiAgICAgIHRocm93IG5ldyBVbmtub3duTGFwaXNFcnJvcihgRmFpbGVkIHRvIGNvbm5lY3QgdG8gTEFQSVM6ICR7bWVzc2FnZX1gLCA1MDAsIHJlcXVlc3RlZERhdGFOYW1lKTsKICAgIH0KICB9CiAgY29uc3QgaGFuZGxlRXJyb3JzID0gYXN5bmMgKHJlc3BvbnNlLCByZXF1ZXN0ZWREYXRhKSA9PiB7CiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7CiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gNDAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDUwMCkgewogICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgY29uc3QgbGFwaXNFcnJvclJlc3VsdCA9IGxhcGlzRXJyb3Iuc2FmZVBhcnNlKGpzb24pOwogICAgICAgIGlmIChsYXBpc0Vycm9yUmVzdWx0LnN1Y2Nlc3MpIHsKICAgICAgICAgIHRocm93IG5ldyBMYXBpc0Vycm9yKAogICAgICAgICAgICByZXNwb25zZS5zdGF0dXNUZXh0ICsgbGFwaXNFcnJvclJlc3VsdC5kYXRhLmVycm9yLmRldGFpbCwKICAgICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzLAogICAgICAgICAgICBsYXBpc0Vycm9yUmVzdWx0LmRhdGEuZXJyb3IsCiAgICAgICAgICAgIHJlcXVlc3RlZERhdGEKICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByb2JsZW1EZXRhaWxSZXN1bHQgPSBwcm9ibGVtRGV0YWlsLnNhZmVQYXJzZShqc29uKTsKICAgICAgICBpZiAocHJvYmxlbURldGFpbFJlc3VsdC5zdWNjZXNzKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTGFwaXNFcnJvcigKICAgICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCArIHByb2JsZW1EZXRhaWxSZXN1bHQuZGF0YS5kZXRhaWwsCiAgICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cywKICAgICAgICAgICAgcHJvYmxlbURldGFpbFJlc3VsdC5kYXRhLAogICAgICAgICAgICByZXF1ZXN0ZWREYXRhCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkxhcGlzRXJyb3IoCiAgICAgICAgICBgJHtyZXNwb25zZS5zdGF0dXNUZXh0fTogJHtKU09OLnN0cmluZ2lmeShqc29uKX1gLAogICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzLAogICAgICAgICAgcmVxdWVzdGVkRGF0YQogICAgICAgICk7CiAgICAgIH0KICAgICAgdGhyb3cgbmV3IFVua25vd25MYXBpc0Vycm9yKGAke3Jlc3BvbnNlLnN0YXR1c1RleHR9OiAke3Jlc3BvbnNlLnN0YXR1c31gLCByZXNwb25zZS5zdGF0dXMsIHJlcXVlc3RlZERhdGEpOwogICAgfQogIH07CiAgY29uc3QgYWdncmVnYXRlZEVuZHBvaW50ID0gKGxhcGlzVXJsKSA9PiBgJHtsYXBpc1VybH0vc2FtcGxlL2FnZ3JlZ2F0ZWRgOwogIGNvbnN0IHN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc0VuZHBvaW50ID0gKGxhcGlzVXJsLCBzZXF1ZW5jZVR5cGUpID0+IHsKICAgIHJldHVybiBzZXF1ZW5jZVR5cGUgPT09ICJhbWlubyBhY2lkIiA/IGAke2xhcGlzVXJsfS9zYW1wbGUvYW1pbm9BY2lkTXV0YXRpb25zYCA6IGAke2xhcGlzVXJsfS9zYW1wbGUvbnVjbGVvdGlkZU11dGF0aW9uc2A7CiAgfTsKICBjbGFzcyBGZXRjaEFnZ3JlZ2F0ZWRPcGVyYXRvciB7CiAgICBjb25zdHJ1Y3RvcihmaWx0ZXIsIGZpZWxkcyA9IFtdKSB7CiAgICAgIHRoaXMuZmlsdGVyID0gZmlsdGVyOwogICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkczsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzVXJsLCBzaWduYWwpIHsKICAgICAgY29uc3QgYWdncmVnYXRlZFJlc3BvbnNlMiA9IChhd2FpdCBmZXRjaEFnZ3JlZ2F0ZWQoCiAgICAgICAgbGFwaXNVcmwsCiAgICAgICAgewogICAgICAgICAgLi4udGhpcy5maWx0ZXIsCiAgICAgICAgICBmaWVsZHM6IHRoaXMuZmllbGRzCiAgICAgICAgfSwKICAgICAgICBzaWduYWwKICAgICAgKSkuZGF0YTsKICAgICAgaWYgKGlzRmllbGRzQXJyYXlXaXRoQ291bnQoYWdncmVnYXRlZFJlc3BvbnNlMikpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgY29udGVudDogYWdncmVnYXRlZFJlc3BvbnNlMgogICAgICAgIH07CiAgICAgIH0KICAgICAgdGhyb3cgbmV3IEVycm9yKCJBZ2dyZWdhdGVkIHJlc3BvbnNlIGRvZXMgbm90IGhhdmUgY291bnQiKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gaXNGaWVsZHNBcnJheVdpdGhDb3VudChkYXRhKSB7CiAgICByZXR1cm4gZGF0YS5ldmVyeSgoaXRlbSkgPT4gdHlwZW9mIGl0ZW0gPT09ICJvYmplY3QiICYmICJjb3VudCIgaW4gaXRlbSAmJiB0eXBlb2YgaXRlbS5jb3VudCA9PT0gIm51bWJlciIpOwogIH0KICBjbGFzcyBHcm91cEJ5T3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGZpZWxkLCBhZ2dyZWdhdGUpIHsKICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkOwogICAgICB0aGlzLmZpZWxkID0gZmllbGQ7CiAgICAgIHRoaXMuYWdncmVnYXRlID0gYWdncmVnYXRlOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IGdyb3VwZWQgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICBmb3IgKGNvbnN0IHJvdyBvZiBjaGlsZEV2YWx1YXRlZC5jb250ZW50KSB7CiAgICAgICAgY29uc3Qga2V5ID0gcm93W3RoaXMuZmllbGRdOwogICAgICAgIGlmICghZ3JvdXBlZC5oYXMoa2V5KSkgewogICAgICAgICAgZ3JvdXBlZC5zZXQoa2V5LCBbXSk7CiAgICAgICAgfQogICAgICAgIGdyb3VwZWQuZ2V0KGtleSkucHVzaChyb3cpOwogICAgICB9CiAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheSgpOwogICAgICBmb3IgKGNvbnN0IFssIHZhbHVlc10gb2YgZ3JvdXBlZCkgewogICAgICAgIHJlc3VsdC5wdXNoKHRoaXMuYWdncmVnYXRlKHZhbHVlcykpOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogcmVzdWx0CiAgICAgIH07CiAgICB9CiAgfQogIGNsYXNzIEdyb3VwQnlBbmRTdW1PcGVyYXRvciBleHRlbmRzIEdyb3VwQnlPcGVyYXRvciB7CiAgICBjb25zdHJ1Y3RvcihjaGlsZCwgZ3JvdXBCeUZpZWxkLCBzdW1GaWVsZCkgewogICAgICBzdXBlcihjaGlsZCwgZ3JvdXBCeUZpZWxkLCAodmFsdWVzKSA9PiB7CiAgICAgICAgbGV0IG4gPSAwOwogICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKSB7CiAgICAgICAgICBuICs9IHZhbHVlW3N1bUZpZWxkXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIFtncm91cEJ5RmllbGRdOiB2YWx1ZXNbMF1bZ3JvdXBCeUZpZWxkXSwKICAgICAgICAgIFtzdW1GaWVsZF06IG4KICAgICAgICB9OwogICAgICB9KTsKICAgIH0KICB9CiAgY2xhc3MgTWFwT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGZ1bmMpIHsKICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkOwogICAgICB0aGlzLmZ1bmMgPSBmdW5jOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogY2hpbGRFdmFsdWF0ZWQuY29udGVudC5tYXAodGhpcy5mdW5jKQogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBSZW5hbWVGaWVsZE9wZXJhdG9yIGV4dGVuZHMgTWFwT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIG9sZEZpZWxkTmFtZSwgbmV3RmllbGROYW1lKSB7CiAgICAgIHN1cGVyKAogICAgICAgIGNoaWxkLAogICAgICAgICh2YWx1ZSkgPT4gKHsKICAgICAgICAgIC4uLnZhbHVlLAogICAgICAgICAgW25ld0ZpZWxkTmFtZV06IHZhbHVlW29sZEZpZWxkTmFtZV0KICAgICAgICB9KQogICAgICApOwogICAgfQogIH0KICBjbGFzcyBTb3J0T3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGNvbXBhcmVGbikgewogICAgICB0aGlzLmNoaWxkID0gY2hpbGQ7CiAgICAgIHRoaXMuY29tcGFyZUZuID0gY29tcGFyZUZuOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogY2hpbGRFdmFsdWF0ZWQuY29udGVudC5zb3J0KHRoaXMuY29tcGFyZUZuKQogICAgICB9OwogICAgfQogIH0KICB2YXIgU0VDT05EU19BX01JTlVURSA9IDYwOwogIHZhciBTRUNPTkRTX0FfSE9VUiA9IFNFQ09ORFNfQV9NSU5VVEUgKiA2MDsKICB2YXIgU0VDT05EU19BX0RBWSA9IFNFQ09ORFNfQV9IT1VSICogMjQ7CiAgdmFyIFNFQ09ORFNfQV9XRUVLID0gU0VDT05EU19BX0RBWSAqIDc7CiAgdmFyIE1JTExJU0VDT05EU19BX1NFQ09ORCA9IDFlMzsKICB2YXIgTUlMTElTRUNPTkRTX0FfTUlOVVRFID0gU0VDT05EU19BX01JTlVURSAqIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICB2YXIgTUlMTElTRUNPTkRTX0FfSE9VUiA9IFNFQ09ORFNfQV9IT1VSICogTUlMTElTRUNPTkRTX0FfU0VDT05EOwogIHZhciBNSUxMSVNFQ09ORFNfQV9EQVkgPSBTRUNPTkRTX0FfREFZICogTUlMTElTRUNPTkRTX0FfU0VDT05EOwogIHZhciBNSUxMSVNFQ09ORFNfQV9XRUVLID0gU0VDT05EU19BX1dFRUsgKiBNSUxMSVNFQ09ORFNfQV9TRUNPTkQ7CiAgdmFyIE1TID0gIm1pbGxpc2Vjb25kIjsKICB2YXIgUyA9ICJzZWNvbmQiOwogIHZhciBNSU4gPSAibWludXRlIjsKICB2YXIgSCA9ICJob3VyIjsKICB2YXIgRCA9ICJkYXkiOwogIHZhciBXID0gIndlZWsiOwogIHZhciBNID0gIm1vbnRoIjsKICB2YXIgUSA9ICJxdWFydGVyIjsKICB2YXIgWSA9ICJ5ZWFyIjsKICB2YXIgREFURSA9ICJkYXRlIjsKICB2YXIgRk9STUFUX0RFRkFVTFQgPSAiWVlZWS1NTS1ERFRISDptbTpzc1oiOwogIHZhciBJTlZBTElEX0RBVEVfU1RSSU5HID0gIkludmFsaWQgRGF0ZSI7CiAgdmFyIFJFR0VYX1BBUlNFID0gL14oXGR7NH0pWy0vXT8oXGR7MSwyfSk/Wy0vXT8oXGR7MCwyfSlbVHRcc10qKFxkezEsMn0pPzo/KFxkezEsMn0pPzo/KFxkezEsMn0pP1suOl0/KFxkKyk/JC87CiAgdmFyIFJFR0VYX0ZPUk1BVCA9IC9cWyhbXlxdXSspXXxZezEsNH18TXsxLDR9fER7MSwyfXxkezEsNH18SHsxLDJ9fGh7MSwyfXxhfEF8bXsxLDJ9fHN7MSwyfXxaezEsMn18U1NTL2c7CiAgdmFyIGVuID0gewogICAgbmFtZTogImVuIiwKICAgIHdlZWtkYXlzOiAiU3VuZGF5X01vbmRheV9UdWVzZGF5X1dlZG5lc2RheV9UaHVyc2RheV9GcmlkYXlfU2F0dXJkYXkiLnNwbGl0KCJfIiksCiAgICBtb250aHM6ICJKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyIi5zcGxpdCgiXyIpLAogICAgb3JkaW5hbDogZnVuY3Rpb24gb3JkaW5hbChuKSB7CiAgICAgIHZhciBzMiA9IFsidGgiLCAic3QiLCAibmQiLCAicmQiXTsKICAgICAgdmFyIHYyID0gbiAlIDEwMDsKICAgICAgcmV0dXJuICJbIiArIG4gKyAoczJbKHYyIC0gMjApICUgMTBdIHx8IHMyW3YyXSB8fCBzMlswXSkgKyAiXSI7CiAgICB9CiAgfTsKICB2YXIgcGFkU3RhcnQgPSBmdW5jdGlvbiBwYWRTdGFydDIoc3RyaW5nLCBsZW5ndGgsIHBhZCkgewogICAgdmFyIHMyID0gU3RyaW5nKHN0cmluZyk7CiAgICBpZiAoIXMyIHx8IHMyLmxlbmd0aCA+PSBsZW5ndGgpIHJldHVybiBzdHJpbmc7CiAgICByZXR1cm4gIiIgKyBBcnJheShsZW5ndGggKyAxIC0gczIubGVuZ3RoKS5qb2luKHBhZCkgKyBzdHJpbmc7CiAgfTsKICB2YXIgcGFkWm9uZVN0ciA9IGZ1bmN0aW9uIHBhZFpvbmVTdHIyKGluc3RhbmNlKSB7CiAgICB2YXIgbmVnTWludXRlcyA9IC1pbnN0YW5jZS51dGNPZmZzZXQoKTsKICAgIHZhciBtaW51dGVzID0gTWF0aC5hYnMobmVnTWludXRlcyk7CiAgICB2YXIgaG91ck9mZnNldCA9IE1hdGguZmxvb3IobWludXRlcyAvIDYwKTsKICAgIHZhciBtaW51dGVPZmZzZXQgPSBtaW51dGVzICUgNjA7CiAgICByZXR1cm4gKG5lZ01pbnV0ZXMgPD0gMCA/ICIrIiA6ICItIikgKyBwYWRTdGFydChob3VyT2Zmc2V0LCAyLCAiMCIpICsgIjoiICsgcGFkU3RhcnQobWludXRlT2Zmc2V0LCAyLCAiMCIpOwogIH07CiAgdmFyIG1vbnRoRGlmZiA9IGZ1bmN0aW9uIG1vbnRoRGlmZjIoYTIsIGIpIHsKICAgIGlmIChhMi5kYXRlKCkgPCBiLmRhdGUoKSkgcmV0dXJuIC1tb250aERpZmYyKGIsIGEyKTsKICAgIHZhciB3aG9sZU1vbnRoRGlmZiA9IChiLnllYXIoKSAtIGEyLnllYXIoKSkgKiAxMiArIChiLm1vbnRoKCkgLSBhMi5tb250aCgpKTsKICAgIHZhciBhbmNob3IgPSBhMi5jbG9uZSgpLmFkZCh3aG9sZU1vbnRoRGlmZiwgTSk7CiAgICB2YXIgYzIgPSBiIC0gYW5jaG9yIDwgMDsKICAgIHZhciBhbmNob3IyID0gYTIuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYgKyAoYzIgPyAtMSA6IDEpLCBNKTsKICAgIHJldHVybiArKC0od2hvbGVNb250aERpZmYgKyAoYiAtIGFuY2hvcikgLyAoYzIgPyBhbmNob3IgLSBhbmNob3IyIDogYW5jaG9yMiAtIGFuY2hvcikpIHx8IDApOwogIH07CiAgdmFyIGFic0Zsb29yID0gZnVuY3Rpb24gYWJzRmxvb3IyKG4pIHsKICAgIHJldHVybiBuIDwgMCA/IE1hdGguY2VpbChuKSB8fCAwIDogTWF0aC5mbG9vcihuKTsKICB9OwogIHZhciBwcmV0dHlVbml0ID0gZnVuY3Rpb24gcHJldHR5VW5pdDIodTIpIHsKICAgIHZhciBzcGVjaWFsID0gewogICAgICBNLAogICAgICB5OiBZLAogICAgICB3OiBXLAogICAgICBkOiBELAogICAgICBEOiBEQVRFLAogICAgICBoOiBILAogICAgICBtOiBNSU4sCiAgICAgIHM6IFMsCiAgICAgIG1zOiBNUywKICAgICAgUQogICAgfTsKICAgIHJldHVybiBzcGVjaWFsW3UyXSB8fCBTdHJpbmcodTIgfHwgIiIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvcyQvLCAiIik7CiAgfTsKICB2YXIgaXNVbmRlZmluZWQgPSBmdW5jdGlvbiBpc1VuZGVmaW5lZDIoczIpIHsKICAgIHJldHVybiBzMiA9PT0gdm9pZCAwOwogIH07CiAgdmFyIFUgPSB7CiAgICBzOiBwYWRTdGFydCwKICAgIHo6IHBhZFpvbmVTdHIsCiAgICBtOiBtb250aERpZmYsCiAgICBhOiBhYnNGbG9vciwKICAgIHA6IHByZXR0eVVuaXQsCiAgICB1OiBpc1VuZGVmaW5lZAogIH07CiAgdmFyIEwgPSAiZW4iOwogIHZhciBMcyA9IHt9OwogIExzW0xdID0gZW47CiAgdmFyIElTX0RBWUpTID0gIiRpc0RheWpzT2JqZWN0IjsKICB2YXIgaXNEYXlqcyA9IGZ1bmN0aW9uIGlzRGF5anMyKGQpIHsKICAgIHJldHVybiBkIGluc3RhbmNlb2YgRGF5anMgfHwgISEoZCAmJiBkW0lTX0RBWUpTXSk7CiAgfTsKICB2YXIgcGFyc2VMb2NhbGUgPSBmdW5jdGlvbiBwYXJzZUxvY2FsZTIocHJlc2V0LCBvYmplY3QsIGlzTG9jYWwpIHsKICAgIHZhciBsMjsKICAgIGlmICghcHJlc2V0KSByZXR1cm4gTDsKICAgIGlmICh0eXBlb2YgcHJlc2V0ID09PSAic3RyaW5nIikgewogICAgICB2YXIgcHJlc2V0TG93ZXIgPSBwcmVzZXQudG9Mb3dlckNhc2UoKTsKICAgICAgaWYgKExzW3ByZXNldExvd2VyXSkgewogICAgICAgIGwyID0gcHJlc2V0TG93ZXI7CiAgICAgIH0KICAgICAgaWYgKG9iamVjdCkgewogICAgICAgIExzW3ByZXNldExvd2VyXSA9IG9iamVjdDsKICAgICAgICBsMiA9IHByZXNldExvd2VyOwogICAgICB9CiAgICAgIHZhciBwcmVzZXRTcGxpdCA9IHByZXNldC5zcGxpdCgiLSIpOwogICAgICBpZiAoIWwyICYmIHByZXNldFNwbGl0Lmxlbmd0aCA+IDEpIHsKICAgICAgICByZXR1cm4gcGFyc2VMb2NhbGUyKHByZXNldFNwbGl0WzBdKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdmFyIG5hbWUgPSBwcmVzZXQubmFtZTsKICAgICAgTHNbbmFtZV0gPSBwcmVzZXQ7CiAgICAgIGwyID0gbmFtZTsKICAgIH0KICAgIGlmICghaXNMb2NhbCAmJiBsMikgTCA9IGwyOwogICAgcmV0dXJuIGwyIHx8ICFpc0xvY2FsICYmIEw7CiAgfTsKICB2YXIgZGF5anMgPSBmdW5jdGlvbiBkYXlqczIoZGF0ZSwgYzIpIHsKICAgIGlmIChpc0RheWpzKGRhdGUpKSB7CiAgICAgIHJldHVybiBkYXRlLmNsb25lKCk7CiAgICB9CiAgICB2YXIgY2ZnID0gdHlwZW9mIGMyID09PSAib2JqZWN0IiA/IGMyIDoge307CiAgICBjZmcuZGF0ZSA9IGRhdGU7CiAgICBjZmcuYXJncyA9IGFyZ3VtZW50czsKICAgIHJldHVybiBuZXcgRGF5anMoY2ZnKTsKICB9OwogIHZhciB3cmFwcGVyID0gZnVuY3Rpb24gd3JhcHBlcjIoZGF0ZSwgaW5zdGFuY2UpIHsKICAgIHJldHVybiBkYXlqcyhkYXRlLCB7CiAgICAgIGxvY2FsZTogaW5zdGFuY2UuJEwsCiAgICAgIHV0YzogaW5zdGFuY2UuJHUsCiAgICAgIHg6IGluc3RhbmNlLiR4LAogICAgICAkb2Zmc2V0OiBpbnN0YW5jZS4kb2Zmc2V0CiAgICAgIC8vIHRvZG86IHJlZmFjdG9yOyBkbyBub3QgdXNlIHRoaXMuJG9mZnNldCBpbiB5b3UgY29kZQogICAgfSk7CiAgfTsKICB2YXIgVXRpbHMgPSBVOwogIFV0aWxzLmwgPSBwYXJzZUxvY2FsZTsKICBVdGlscy5pID0gaXNEYXlqczsKICBVdGlscy53ID0gd3JhcHBlcjsKICB2YXIgcGFyc2VEYXRlID0gZnVuY3Rpb24gcGFyc2VEYXRlMihjZmcpIHsKICAgIHZhciBkYXRlID0gY2ZnLmRhdGUsIHV0YyA9IGNmZy51dGM7CiAgICBpZiAoZGF0ZSA9PT0gbnVsbCkgcmV0dXJuIC8qIEBfX1BVUkVfXyAqLyBuZXcgRGF0ZShOYU4pOwogICAgaWYgKFV0aWxzLnUoZGF0ZSkpIHJldHVybiAvKiBAX19QVVJFX18gKi8gbmV3IERhdGUoKTsKICAgIGlmIChkYXRlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIG5ldyBEYXRlKGRhdGUpOwogICAgaWYgKHR5cGVvZiBkYXRlID09PSAic3RyaW5nIiAmJiAhL1okL2kudGVzdChkYXRlKSkgewogICAgICB2YXIgZCA9IGRhdGUubWF0Y2goUkVHRVhfUEFSU0UpOwogICAgICBpZiAoZCkgewogICAgICAgIHZhciBtMiA9IGRbMl0gLSAxIHx8IDA7CiAgICAgICAgdmFyIG1zID0gKGRbN10gfHwgIjAiKS5zdWJzdHJpbmcoMCwgMyk7CiAgICAgICAgaWYgKHV0YykgewogICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKGRbMV0sIG0yLCBkWzNdIHx8IDEsIGRbNF0gfHwgMCwgZFs1XSB8fCAwLCBkWzZdIHx8IDAsIG1zKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgRGF0ZShkWzFdLCBtMiwgZFszXSB8fCAxLCBkWzRdIHx8IDAsIGRbNV0gfHwgMCwgZFs2XSB8fCAwLCBtcyk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKTsKICB9OwogIHZhciBEYXlqcyA9IC8qIEBfX1BVUkVfXyAqLyBmdW5jdGlvbigpIHsKICAgIGZ1bmN0aW9uIERheWpzMihjZmcpIHsKICAgICAgdGhpcy4kTCA9IHBhcnNlTG9jYWxlKGNmZy5sb2NhbGUsIG51bGwsIHRydWUpOwogICAgICB0aGlzLnBhcnNlKGNmZyk7CiAgICAgIHRoaXMuJHggPSB0aGlzLiR4IHx8IGNmZy54IHx8IHt9OwogICAgICB0aGlzW0lTX0RBWUpTXSA9IHRydWU7CiAgICB9CiAgICB2YXIgX3Byb3RvID0gRGF5anMyLnByb3RvdHlwZTsKICAgIF9wcm90by5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKGNmZykgewogICAgICB0aGlzLiRkID0gcGFyc2VEYXRlKGNmZyk7CiAgICAgIHRoaXMuaW5pdCgpOwogICAgfTsKICAgIF9wcm90by5pbml0ID0gZnVuY3Rpb24gaW5pdCgpIHsKICAgICAgdmFyICRkID0gdGhpcy4kZDsKICAgICAgdGhpcy4keSA9ICRkLmdldEZ1bGxZZWFyKCk7CiAgICAgIHRoaXMuJE0gPSAkZC5nZXRNb250aCgpOwogICAgICB0aGlzLiREID0gJGQuZ2V0RGF0ZSgpOwogICAgICB0aGlzLiRXID0gJGQuZ2V0RGF5KCk7CiAgICAgIHRoaXMuJEggPSAkZC5nZXRIb3VycygpOwogICAgICB0aGlzLiRtID0gJGQuZ2V0TWludXRlcygpOwogICAgICB0aGlzLiRzID0gJGQuZ2V0U2Vjb25kcygpOwogICAgICB0aGlzLiRtcyA9ICRkLmdldE1pbGxpc2Vjb25kcygpOwogICAgfTsKICAgIF9wcm90by4kdXRpbHMgPSBmdW5jdGlvbiAkdXRpbHMoKSB7CiAgICAgIHJldHVybiBVdGlsczsKICAgIH07CiAgICBfcHJvdG8uaXNWYWxpZCA9IGZ1bmN0aW9uIGlzVmFsaWQyKCkgewogICAgICByZXR1cm4gISh0aGlzLiRkLnRvU3RyaW5nKCkgPT09IElOVkFMSURfREFURV9TVFJJTkcpOwogICAgfTsKICAgIF9wcm90by5pc1NhbWUgPSBmdW5jdGlvbiBpc1NhbWUodGhhdCwgdW5pdHMpIHsKICAgICAgdmFyIG90aGVyID0gZGF5anModGhhdCk7CiAgICAgIHJldHVybiB0aGlzLnN0YXJ0T2YodW5pdHMpIDw9IG90aGVyICYmIG90aGVyIDw9IHRoaXMuZW5kT2YodW5pdHMpOwogICAgfTsKICAgIF9wcm90by5pc0FmdGVyID0gZnVuY3Rpb24gaXNBZnRlcih0aGF0LCB1bml0cykgewogICAgICByZXR1cm4gZGF5anModGhhdCkgPCB0aGlzLnN0YXJ0T2YodW5pdHMpOwogICAgfTsKICAgIF9wcm90by5pc0JlZm9yZSA9IGZ1bmN0aW9uIGlzQmVmb3JlKHRoYXQsIHVuaXRzKSB7CiAgICAgIHJldHVybiB0aGlzLmVuZE9mKHVuaXRzKSA8IGRheWpzKHRoYXQpOwogICAgfTsKICAgIF9wcm90by4kZyA9IGZ1bmN0aW9uICRnKGlucHV0LCBnZXQsIHNldCkgewogICAgICBpZiAoVXRpbHMudShpbnB1dCkpIHJldHVybiB0aGlzW2dldF07CiAgICAgIHJldHVybiB0aGlzLnNldChzZXQsIGlucHV0KTsKICAgIH07CiAgICBfcHJvdG8udW5peCA9IGZ1bmN0aW9uIHVuaXgoKSB7CiAgICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMudmFsdWVPZigpIC8gMWUzKTsKICAgIH07CiAgICBfcHJvdG8udmFsdWVPZiA9IGZ1bmN0aW9uIHZhbHVlT2YoKSB7CiAgICAgIHJldHVybiB0aGlzLiRkLmdldFRpbWUoKTsKICAgIH07CiAgICBfcHJvdG8uc3RhcnRPZiA9IGZ1bmN0aW9uIHN0YXJ0T2YodW5pdHMsIF9zdGFydE9mKSB7CiAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgIHZhciBpc1N0YXJ0T2YgPSAhVXRpbHMudShfc3RhcnRPZikgPyBfc3RhcnRPZiA6IHRydWU7CiAgICAgIHZhciB1bml0ID0gVXRpbHMucCh1bml0cyk7CiAgICAgIHZhciBpbnN0YW5jZUZhY3RvcnkgPSBmdW5jdGlvbiBpbnN0YW5jZUZhY3RvcnkyKGQsIG0yKSB7CiAgICAgICAgdmFyIGlucyA9IFV0aWxzLncoX3RoaXMuJHUgPyBEYXRlLlVUQyhfdGhpcy4keSwgbTIsIGQpIDogbmV3IERhdGUoX3RoaXMuJHksIG0yLCBkKSwgX3RoaXMpOwogICAgICAgIHJldHVybiBpc1N0YXJ0T2YgPyBpbnMgOiBpbnMuZW5kT2YoRCk7CiAgICAgIH07CiAgICAgIHZhciBpbnN0YW5jZUZhY3RvcnlTZXQgPSBmdW5jdGlvbiBpbnN0YW5jZUZhY3RvcnlTZXQyKG1ldGhvZCwgc2xpY2UpIHsKICAgICAgICB2YXIgYXJndW1lbnRTdGFydCA9IFswLCAwLCAwLCAwXTsKICAgICAgICB2YXIgYXJndW1lbnRFbmQgPSBbMjMsIDU5LCA1OSwgOTk5XTsKICAgICAgICByZXR1cm4gVXRpbHMudyhfdGhpcy50b0RhdGUoKVttZXRob2RdLmFwcGx5KAogICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBwcmVmZXItc3ByZWFkCiAgICAgICAgICBfdGhpcy50b0RhdGUoInMiKSwKICAgICAgICAgIChpc1N0YXJ0T2YgPyBhcmd1bWVudFN0YXJ0IDogYXJndW1lbnRFbmQpLnNsaWNlKHNsaWNlKQogICAgICAgICksIF90aGlzKTsKICAgICAgfTsKICAgICAgdmFyICRXID0gdGhpcy4kVywgJE0gPSB0aGlzLiRNLCAkRCA9IHRoaXMuJEQ7CiAgICAgIHZhciB1dGNQYWQgPSAic2V0IiArICh0aGlzLiR1ID8gIlVUQyIgOiAiIik7CiAgICAgIHN3aXRjaCAodW5pdCkgewogICAgICAgIGNhc2UgWToKICAgICAgICAgIHJldHVybiBpc1N0YXJ0T2YgPyBpbnN0YW5jZUZhY3RvcnkoMSwgMCkgOiBpbnN0YW5jZUZhY3RvcnkoMzEsIDExKTsKICAgICAgICBjYXNlIE06CiAgICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gaW5zdGFuY2VGYWN0b3J5KDEsICRNKSA6IGluc3RhbmNlRmFjdG9yeSgwLCAkTSArIDEpOwogICAgICAgIGNhc2UgVzogewogICAgICAgICAgdmFyIHdlZWtTdGFydCA9IHRoaXMuJGxvY2FsZSgpLndlZWtTdGFydCB8fCAwOwogICAgICAgICAgdmFyIGdhcCA9ICgkVyA8IHdlZWtTdGFydCA/ICRXICsgNyA6ICRXKSAtIHdlZWtTdGFydDsKICAgICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnkoaXNTdGFydE9mID8gJEQgLSBnYXAgOiAkRCArICg2IC0gZ2FwKSwgJE0pOwogICAgICAgIH0KICAgICAgICBjYXNlIEQ6CiAgICAgICAgY2FzZSBEQVRFOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiSG91cnMiLCAwKTsKICAgICAgICBjYXNlIEg6CiAgICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KHV0Y1BhZCArICJNaW51dGVzIiwgMSk7CiAgICAgICAgY2FzZSBNSU46CiAgICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KHV0Y1BhZCArICJTZWNvbmRzIiwgMik7CiAgICAgICAgY2FzZSBTOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiTWlsbGlzZWNvbmRzIiwgMyk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiB0aGlzLmNsb25lKCk7CiAgICAgIH0KICAgIH07CiAgICBfcHJvdG8uZW5kT2YgPSBmdW5jdGlvbiBlbmRPZihhcmcpIHsKICAgICAgcmV0dXJuIHRoaXMuc3RhcnRPZihhcmcsIGZhbHNlKTsKICAgIH07CiAgICBfcHJvdG8uJHNldCA9IGZ1bmN0aW9uICRzZXQodW5pdHMsIF9pbnQpIHsKICAgICAgdmFyIF9DJEQkQyREQVRFJEMkTSRDJFkkQzsKICAgICAgdmFyIHVuaXQgPSBVdGlscy5wKHVuaXRzKTsKICAgICAgdmFyIHV0Y1BhZCA9ICJzZXQiICsgKHRoaXMuJHUgPyAiVVRDIiA6ICIiKTsKICAgICAgdmFyIG5hbWUgPSAoX0MkRCRDJERBVEUkQyRNJEMkWSRDID0ge30sIF9DJEQkQyREQVRFJEMkTSRDJFkkQ1tEXSA9IHV0Y1BhZCArICJEYXRlIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW0RBVEVdID0gdXRjUGFkICsgIkRhdGUiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTV0gPSB1dGNQYWQgKyAiTW9udGgiLCBfQyREJEMkREFURSRDJE0kQyRZJENbWV0gPSB1dGNQYWQgKyAiRnVsbFllYXIiLCBfQyREJEMkREFURSRDJE0kQyRZJENbSF0gPSB1dGNQYWQgKyAiSG91cnMiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTUlOXSA9IHV0Y1BhZCArICJNaW51dGVzIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW1NdID0gdXRjUGFkICsgIlNlY29uZHMiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTVNdID0gdXRjUGFkICsgIk1pbGxpc2Vjb25kcyIsIF9DJEQkQyREQVRFJEMkTSRDJFkkQylbdW5pdF07CiAgICAgIHZhciBhcmcgPSB1bml0ID09PSBEID8gdGhpcy4kRCArIChfaW50IC0gdGhpcy4kVykgOiBfaW50OwogICAgICBpZiAodW5pdCA9PT0gTSB8fCB1bml0ID09PSBZKSB7CiAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmNsb25lKCkuc2V0KERBVEUsIDEpOwogICAgICAgIGRhdGUuJGRbbmFtZV0oYXJnKTsKICAgICAgICBkYXRlLmluaXQoKTsKICAgICAgICB0aGlzLiRkID0gZGF0ZS5zZXQoREFURSwgTWF0aC5taW4odGhpcy4kRCwgZGF0ZS5kYXlzSW5Nb250aCgpKSkuJGQ7CiAgICAgIH0gZWxzZSBpZiAobmFtZSkgdGhpcy4kZFtuYW1lXShhcmcpOwogICAgICB0aGlzLmluaXQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9OwogICAgX3Byb3RvLnNldCA9IGZ1bmN0aW9uIHNldChzdHJpbmcsIF9pbnQyKSB7CiAgICAgIHJldHVybiB0aGlzLmNsb25lKCkuJHNldChzdHJpbmcsIF9pbnQyKTsKICAgIH07CiAgICBfcHJvdG8uZ2V0ID0gZnVuY3Rpb24gZ2V0KHVuaXQpIHsKICAgICAgcmV0dXJuIHRoaXNbVXRpbHMucCh1bml0KV0oKTsKICAgIH07CiAgICBfcHJvdG8uYWRkID0gZnVuY3Rpb24gYWRkKG51bWJlciwgdW5pdHMpIHsKICAgICAgdmFyIF90aGlzMiA9IHRoaXMsIF9DJE1JTiRDJEgkQyRTJHVuaXQ7CiAgICAgIG51bWJlciA9IE51bWJlcihudW1iZXIpOwogICAgICB2YXIgdW5pdCA9IFV0aWxzLnAodW5pdHMpOwogICAgICB2YXIgaW5zdGFuY2VGYWN0b3J5U2V0ID0gZnVuY3Rpb24gaW5zdGFuY2VGYWN0b3J5U2V0MihuKSB7CiAgICAgICAgdmFyIGQgPSBkYXlqcyhfdGhpczIpOwogICAgICAgIHJldHVybiBVdGlscy53KGQuZGF0ZShkLmRhdGUoKSArIE1hdGgucm91bmQobiAqIG51bWJlcikpLCBfdGhpczIpOwogICAgICB9OwogICAgICBpZiAodW5pdCA9PT0gTSkgewogICAgICAgIHJldHVybiB0aGlzLnNldChNLCB0aGlzLiRNICsgbnVtYmVyKTsKICAgICAgfQogICAgICBpZiAodW5pdCA9PT0gWSkgewogICAgICAgIHJldHVybiB0aGlzLnNldChZLCB0aGlzLiR5ICsgbnVtYmVyKTsKICAgICAgfQogICAgICBpZiAodW5pdCA9PT0gRCkgewogICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnlTZXQoMSk7CiAgICAgIH0KICAgICAgaWYgKHVuaXQgPT09IFcpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KDcpOwogICAgICB9CiAgICAgIHZhciBzdGVwID0gKF9DJE1JTiRDJEgkQyRTJHVuaXQgPSB7fSwgX0MkTUlOJEMkSCRDJFMkdW5pdFtNSU5dID0gTUlMTElTRUNPTkRTX0FfTUlOVVRFLCBfQyRNSU4kQyRIJEMkUyR1bml0W0hdID0gTUlMTElTRUNPTkRTX0FfSE9VUiwgX0MkTUlOJEMkSCRDJFMkdW5pdFtTXSA9IE1JTExJU0VDT05EU19BX1NFQ09ORCwgX0MkTUlOJEMkSCRDJFMkdW5pdClbdW5pdF0gfHwgMTsKICAgICAgdmFyIG5leHRUaW1lU3RhbXAgPSB0aGlzLiRkLmdldFRpbWUoKSArIG51bWJlciAqIHN0ZXA7CiAgICAgIHJldHVybiBVdGlscy53KG5leHRUaW1lU3RhbXAsIHRoaXMpOwogICAgfTsKICAgIF9wcm90by5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KG51bWJlciwgc3RyaW5nKSB7CiAgICAgIHJldHVybiB0aGlzLmFkZChudW1iZXIgKiAtMSwgc3RyaW5nKTsKICAgIH07CiAgICBfcHJvdG8uZm9ybWF0ID0gZnVuY3Rpb24gZm9ybWF0KGZvcm1hdFN0cikgewogICAgICB2YXIgX3RoaXMzID0gdGhpczsKICAgICAgdmFyIGxvY2FsZSA9IHRoaXMuJGxvY2FsZSgpOwogICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSByZXR1cm4gbG9jYWxlLmludmFsaWREYXRlIHx8IElOVkFMSURfREFURV9TVFJJTkc7CiAgICAgIHZhciBzdHIgPSBmb3JtYXRTdHIgfHwgRk9STUFUX0RFRkFVTFQ7CiAgICAgIHZhciB6b25lU3RyID0gVXRpbHMueih0aGlzKTsKICAgICAgdmFyICRIID0gdGhpcy4kSCwgJG0gPSB0aGlzLiRtLCAkTSA9IHRoaXMuJE07CiAgICAgIHZhciB3ZWVrZGF5cyA9IGxvY2FsZS53ZWVrZGF5cywgbW9udGhzID0gbG9jYWxlLm1vbnRocywgbWVyaWRpZW0gPSBsb2NhbGUubWVyaWRpZW07CiAgICAgIHZhciBnZXRTaG9ydCA9IGZ1bmN0aW9uIGdldFNob3J0MihhcnIsIGluZGV4LCBmdWxsLCBsZW5ndGgpIHsKICAgICAgICByZXR1cm4gYXJyICYmIChhcnJbaW5kZXhdIHx8IGFycihfdGhpczMsIHN0cikpIHx8IGZ1bGxbaW5kZXhdLnNsaWNlKDAsIGxlbmd0aCk7CiAgICAgIH07CiAgICAgIHZhciBnZXQkSCA9IGZ1bmN0aW9uIGdldCRIMihudW0pIHsKICAgICAgICByZXR1cm4gVXRpbHMucygkSCAlIDEyIHx8IDEyLCBudW0sICIwIik7CiAgICAgIH07CiAgICAgIHZhciBtZXJpZGllbUZ1bmMgPSBtZXJpZGllbSB8fCBmdW5jdGlvbihob3VyLCBtaW51dGUsIGlzTG93ZXJjYXNlKSB7CiAgICAgICAgdmFyIG0yID0gaG91ciA8IDEyID8gIkFNIiA6ICJQTSI7CiAgICAgICAgcmV0dXJuIGlzTG93ZXJjYXNlID8gbTIudG9Mb3dlckNhc2UoKSA6IG0yOwogICAgICB9OwogICAgICB2YXIgbWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMyKG1hdGNoKSB7CiAgICAgICAgc3dpdGNoIChtYXRjaCkgewogICAgICAgICAgY2FzZSAiWVkiOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKF90aGlzMy4keSkuc2xpY2UoLTIpOwogICAgICAgICAgY2FzZSAiWVlZWSI6CiAgICAgICAgICAgIHJldHVybiBVdGlscy5zKF90aGlzMy4keSwgNCwgIjAiKTsKICAgICAgICAgIGNhc2UgIk0iOgogICAgICAgICAgICByZXR1cm4gJE0gKyAxOwogICAgICAgICAgY2FzZSAiTU0iOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucygkTSArIDEsIDIsICIwIik7CiAgICAgICAgICBjYXNlICJNTU0iOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobG9jYWxlLm1vbnRoc1Nob3J0LCAkTSwgbW9udGhzLCAzKTsKICAgICAgICAgIGNhc2UgIk1NTU0iOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobW9udGhzLCAkTSk7CiAgICAgICAgICBjYXNlICJEIjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzMy4kRDsKICAgICAgICAgIGNhc2UgIkREIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoX3RoaXMzLiRELCAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiZCI6CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcoX3RoaXMzLiRXKTsKICAgICAgICAgIGNhc2UgImRkIjoKICAgICAgICAgICAgcmV0dXJuIGdldFNob3J0KGxvY2FsZS53ZWVrZGF5c01pbiwgX3RoaXMzLiRXLCB3ZWVrZGF5cywgMik7CiAgICAgICAgICBjYXNlICJkZGQiOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobG9jYWxlLndlZWtkYXlzU2hvcnQsIF90aGlzMy4kVywgd2Vla2RheXMsIDMpOwogICAgICAgICAgY2FzZSAiZGRkZCI6CiAgICAgICAgICAgIHJldHVybiB3ZWVrZGF5c1tfdGhpczMuJFddOwogICAgICAgICAgY2FzZSAiSCI6CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcoJEgpOwogICAgICAgICAgY2FzZSAiSEgiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucygkSCwgMiwgIjAiKTsKICAgICAgICAgIGNhc2UgImgiOgogICAgICAgICAgICByZXR1cm4gZ2V0JEgoMSk7CiAgICAgICAgICBjYXNlICJoaCI6CiAgICAgICAgICAgIHJldHVybiBnZXQkSCgyKTsKICAgICAgICAgIGNhc2UgImEiOgogICAgICAgICAgICByZXR1cm4gbWVyaWRpZW1GdW5jKCRILCAkbSwgdHJ1ZSk7CiAgICAgICAgICBjYXNlICJBIjoKICAgICAgICAgICAgcmV0dXJuIG1lcmlkaWVtRnVuYygkSCwgJG0sIGZhbHNlKTsKICAgICAgICAgIGNhc2UgIm0iOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKCRtKTsKICAgICAgICAgIGNhc2UgIm1tIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoJG0sIDIsICIwIik7CiAgICAgICAgICBjYXNlICJzIjoKICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhfdGhpczMuJHMpOwogICAgICAgICAgY2FzZSAic3MiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucyhfdGhpczMuJHMsIDIsICIwIik7CiAgICAgICAgICBjYXNlICJTU1MiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucyhfdGhpczMuJG1zLCAzLCAiMCIpOwogICAgICAgICAgY2FzZSAiWiI6CiAgICAgICAgICAgIHJldHVybiB6b25lU3RyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfTsKICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKFJFR0VYX0ZPUk1BVCwgZnVuY3Rpb24obWF0Y2gsICQxKSB7CiAgICAgICAgcmV0dXJuICQxIHx8IG1hdGNoZXMobWF0Y2gpIHx8IHpvbmVTdHIucmVwbGFjZSgiOiIsICIiKTsKICAgICAgfSk7CiAgICB9OwogICAgX3Byb3RvLnV0Y09mZnNldCA9IGZ1bmN0aW9uIHV0Y09mZnNldCgpIHsKICAgICAgcmV0dXJuIC1NYXRoLnJvdW5kKHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAvIDE1KSAqIDE1OwogICAgfTsKICAgIF9wcm90by5kaWZmID0gZnVuY3Rpb24gZGlmZihpbnB1dCwgdW5pdHMsIF9mbG9hdCkgewogICAgICB2YXIgX3RoaXM0ID0gdGhpczsKICAgICAgdmFyIHVuaXQgPSBVdGlscy5wKHVuaXRzKTsKICAgICAgdmFyIHRoYXQgPSBkYXlqcyhpbnB1dCk7CiAgICAgIHZhciB6b25lRGVsdGEgPSAodGhhdC51dGNPZmZzZXQoKSAtIHRoaXMudXRjT2Zmc2V0KCkpICogTUlMTElTRUNPTkRTX0FfTUlOVVRFOwogICAgICB2YXIgZGlmZjIgPSB0aGlzIC0gdGhhdDsKICAgICAgdmFyIGdldE1vbnRoID0gZnVuY3Rpb24gZ2V0TW9udGgyKCkgewogICAgICAgIHJldHVybiBVdGlscy5tKF90aGlzNCwgdGhhdCk7CiAgICAgIH07CiAgICAgIHZhciByZXN1bHQ7CiAgICAgIHN3aXRjaCAodW5pdCkgewogICAgICAgIGNhc2UgWToKICAgICAgICAgIHJlc3VsdCA9IGdldE1vbnRoKCkgLyAxMjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTToKICAgICAgICAgIHJlc3VsdCA9IGdldE1vbnRoKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFE6CiAgICAgICAgICByZXN1bHQgPSBnZXRNb250aCgpIC8gMzsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVzoKICAgICAgICAgIHJlc3VsdCA9IChkaWZmMiAtIHpvbmVEZWx0YSkgLyBNSUxMSVNFQ09ORFNfQV9XRUVLOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBEOgogICAgICAgICAgcmVzdWx0ID0gKGRpZmYyIC0gem9uZURlbHRhKSAvIE1JTExJU0VDT05EU19BX0RBWTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSDoKICAgICAgICAgIHJlc3VsdCA9IGRpZmYyIC8gTUlMTElTRUNPTkRTX0FfSE9VUjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTUlOOgogICAgICAgICAgcmVzdWx0ID0gZGlmZjIgLyBNSUxMSVNFQ09ORFNfQV9NSU5VVEU7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFM6CiAgICAgICAgICByZXN1bHQgPSBkaWZmMiAvIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXN1bHQgPSBkaWZmMjsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHJldHVybiBfZmxvYXQgPyByZXN1bHQgOiBVdGlscy5hKHJlc3VsdCk7CiAgICB9OwogICAgX3Byb3RvLmRheXNJbk1vbnRoID0gZnVuY3Rpb24gZGF5c0luTW9udGgoKSB7CiAgICAgIHJldHVybiB0aGlzLmVuZE9mKE0pLiREOwogICAgfTsKICAgIF9wcm90by4kbG9jYWxlID0gZnVuY3Rpb24gJGxvY2FsZSgpIHsKICAgICAgcmV0dXJuIExzW3RoaXMuJExdOwogICAgfTsKICAgIF9wcm90by5sb2NhbGUgPSBmdW5jdGlvbiBsb2NhbGUocHJlc2V0LCBvYmplY3QpIHsKICAgICAgaWYgKCFwcmVzZXQpIHJldHVybiB0aGlzLiRMOwogICAgICB2YXIgdGhhdCA9IHRoaXMuY2xvbmUoKTsKICAgICAgdmFyIG5leHRMb2NhbGVOYW1lID0gcGFyc2VMb2NhbGUocHJlc2V0LCBvYmplY3QsIHRydWUpOwogICAgICBpZiAobmV4dExvY2FsZU5hbWUpIHRoYXQuJEwgPSBuZXh0TG9jYWxlTmFtZTsKICAgICAgcmV0dXJuIHRoYXQ7CiAgICB9OwogICAgX3Byb3RvLmNsb25lID0gZnVuY3Rpb24gY2xvbmUoKSB7CiAgICAgIHJldHVybiBVdGlscy53KHRoaXMuJGQsIHRoaXMpOwogICAgfTsKICAgIF9wcm90by50b0RhdGUgPSBmdW5jdGlvbiB0b0RhdGUoKSB7CiAgICAgIHJldHVybiBuZXcgRGF0ZSh0aGlzLnZhbHVlT2YoKSk7CiAgICB9OwogICAgX3Byb3RvLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy50b0lTT1N0cmluZygpIDogbnVsbDsKICAgIH07CiAgICBfcHJvdG8udG9JU09TdHJpbmcgPSBmdW5jdGlvbiB0b0lTT1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuJGQudG9JU09TdHJpbmcoKTsKICAgIH07CiAgICBfcHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuJGQudG9VVENTdHJpbmcoKTsKICAgIH07CiAgICByZXR1cm4gRGF5anMyOwogIH0oKTsKICB2YXIgcHJvdG8gPSBEYXlqcy5wcm90b3R5cGU7CiAgZGF5anMucHJvdG90eXBlID0gcHJvdG87CiAgW1siJG1zIiwgTVNdLCBbIiRzIiwgU10sIFsiJG0iLCBNSU5dLCBbIiRIIiwgSF0sIFsiJFciLCBEXSwgWyIkTSIsIE1dLCBbIiR5IiwgWV0sIFsiJEQiLCBEQVRFXV0uZm9yRWFjaChmdW5jdGlvbihnKSB7CiAgICBwcm90b1tnWzFdXSA9IGZ1bmN0aW9uKGlucHV0KSB7CiAgICAgIHJldHVybiB0aGlzLiRnKGlucHV0LCBnWzBdLCBnWzFdKTsKICAgIH07CiAgfSk7CiAgZGF5anMuZXh0ZW5kID0gZnVuY3Rpb24ocGx1Z2luLCBvcHRpb24pIHsKICAgIGlmICghcGx1Z2luLiRpKSB7CiAgICAgIHBsdWdpbihvcHRpb24sIERheWpzLCBkYXlqcyk7CiAgICAgIHBsdWdpbi4kaSA9IHRydWU7CiAgICB9CiAgICByZXR1cm4gZGF5anM7CiAgfTsKICBkYXlqcy5sb2NhbGUgPSBwYXJzZUxvY2FsZTsKICBkYXlqcy5pc0RheWpzID0gaXNEYXlqczsKICBkYXlqcy51bml4ID0gZnVuY3Rpb24odGltZXN0YW1wKSB7CiAgICByZXR1cm4gZGF5anModGltZXN0YW1wICogMWUzKTsKICB9OwogIGRheWpzLmVuID0gTHNbTF07CiAgZGF5anMuTHMgPSBMczsKICBkYXlqcy5wID0ge307CiAgdmFyIGFkdmFuY2VkRm9ybWF0ID0gZnVuY3Rpb24obywgYzIpIHsKICAgIHZhciBwcm90bzIgPSBjMi5wcm90b3R5cGU7CiAgICB2YXIgb2xkRm9ybWF0ID0gcHJvdG8yLmZvcm1hdDsKICAgIHByb3RvMi5mb3JtYXQgPSBmdW5jdGlvbihmb3JtYXRTdHIpIHsKICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgdmFyIGxvY2FsZSA9IHRoaXMuJGxvY2FsZSgpOwogICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7CiAgICAgICAgcmV0dXJuIG9sZEZvcm1hdC5iaW5kKHRoaXMpKGZvcm1hdFN0cik7CiAgICAgIH0KICAgICAgdmFyIHV0aWxzID0gdGhpcy4kdXRpbHMoKTsKICAgICAgdmFyIHN0ciA9IGZvcm1hdFN0ciB8fCBGT1JNQVRfREVGQVVMVDsKICAgICAgdmFyIHJlc3VsdCA9IHN0ci5yZXBsYWNlKC9cWyhbXlxdXSspXXxRfHdvfHd3fHd8V1d8V3x6enp8enxnZ2dnfEdHR0d8RG98WHx4fGt7MSwyfXxTL2csIGZ1bmN0aW9uKG1hdGNoKSB7CiAgICAgICAgc3dpdGNoIChtYXRjaCkgewogICAgICAgICAgY2FzZSAiUSI6CiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwoKF90aGlzLiRNICsgMSkgLyAzKTsKICAgICAgICAgIGNhc2UgIkRvIjoKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5vcmRpbmFsKF90aGlzLiREKTsKICAgICAgICAgIGNhc2UgImdnZ2ciOgogICAgICAgICAgICByZXR1cm4gX3RoaXMud2Vla1llYXIoKTsKICAgICAgICAgIGNhc2UgIkdHR0ciOgogICAgICAgICAgICByZXR1cm4gX3RoaXMuaXNvV2Vla1llYXIoKTsKICAgICAgICAgIGNhc2UgIndvIjoKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5vcmRpbmFsKF90aGlzLndlZWsoKSwgIlciKTsKICAgICAgICAgIGNhc2UgInciOgogICAgICAgICAgY2FzZSAid3ciOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhfdGhpcy53ZWVrKCksIG1hdGNoID09PSAidyIgPyAxIDogMiwgIjAiKTsKICAgICAgICAgIGNhc2UgIlciOgogICAgICAgICAgY2FzZSAiV1ciOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhfdGhpcy5pc29XZWVrKCksIG1hdGNoID09PSAiVyIgPyAxIDogMiwgIjAiKTsKICAgICAgICAgIGNhc2UgImsiOgogICAgICAgICAgY2FzZSAia2siOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhTdHJpbmcoX3RoaXMuJEggPT09IDAgPyAyNCA6IF90aGlzLiRIKSwgbWF0Y2ggPT09ICJrIiA/IDEgOiAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiWCI6CiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKF90aGlzLiRkLmdldFRpbWUoKSAvIDFlMyk7CiAgICAgICAgICBjYXNlICJ4IjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzLiRkLmdldFRpbWUoKTsKICAgICAgICAgIGNhc2UgInoiOgogICAgICAgICAgICByZXR1cm4gIlsiICsgX3RoaXMub2Zmc2V0TmFtZSgpICsgIl0iOwogICAgICAgICAgY2FzZSAienp6IjoKICAgICAgICAgICAgcmV0dXJuICJbIiArIF90aGlzLm9mZnNldE5hbWUoImxvbmciKSArICJdIjsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBtYXRjaDsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gb2xkRm9ybWF0LmJpbmQodGhpcykocmVzdWx0KTsKICAgIH07CiAgfTsKICB2YXIgaXNvV2Vla1ByZXR0eVVuaXQgPSAiaXNvd2VlayI7CiAgdmFyIGlzb1dlZWsgPSBmdW5jdGlvbihvLCBjMiwgZCkgewogICAgdmFyIGdldFllYXJGaXJzdFRodXJzZGF5ID0gZnVuY3Rpb24gZ2V0WWVhckZpcnN0VGh1cnNkYXkyKHllYXIsIGlzVXRjKSB7CiAgICAgIHZhciB5ZWFyRmlyc3REYXkgPSAoaXNVdGMgPyBkLnV0YyA6IGQpKCkueWVhcih5ZWFyKS5zdGFydE9mKFkpOwogICAgICB2YXIgYWRkRGlmZkRheXMgPSA0IC0geWVhckZpcnN0RGF5Lmlzb1dlZWtkYXkoKTsKICAgICAgaWYgKHllYXJGaXJzdERheS5pc29XZWVrZGF5KCkgPiA0KSB7CiAgICAgICAgYWRkRGlmZkRheXMgKz0gNzsKICAgICAgfQogICAgICByZXR1cm4geWVhckZpcnN0RGF5LmFkZChhZGREaWZmRGF5cywgRCk7CiAgICB9OwogICAgdmFyIGdldEN1cnJlbnRXZWVrVGh1cnNkYXkgPSBmdW5jdGlvbiBnZXRDdXJyZW50V2Vla1RodXJzZGF5MihpbnMpIHsKICAgICAgcmV0dXJuIGlucy5hZGQoNCAtIGlucy5pc29XZWVrZGF5KCksIEQpOwogICAgfTsKICAgIHZhciBwcm90bzIgPSBjMi5wcm90b3R5cGU7CiAgICBwcm90bzIuaXNvV2Vla1llYXIgPSBmdW5jdGlvbigpIHsKICAgICAgdmFyIG5vd1dlZWtUaHVyc2RheSA9IGdldEN1cnJlbnRXZWVrVGh1cnNkYXkodGhpcyk7CiAgICAgIHJldHVybiBub3dXZWVrVGh1cnNkYXkueWVhcigpOwogICAgfTsKICAgIHByb3RvMi5pc29XZWVrID0gZnVuY3Rpb24od2VlaykgewogICAgICBpZiAoIXRoaXMuJHV0aWxzKCkudSh3ZWVrKSkgewogICAgICAgIHJldHVybiB0aGlzLmFkZCgod2VlayAtIHRoaXMuaXNvV2VlaygpKSAqIDcsIEQpOwogICAgICB9CiAgICAgIHZhciBub3dXZWVrVGh1cnNkYXkgPSBnZXRDdXJyZW50V2Vla1RodXJzZGF5KHRoaXMpOwogICAgICB2YXIgZGlmZldlZWtUaHVyc2RheSA9IGdldFllYXJGaXJzdFRodXJzZGF5KHRoaXMuaXNvV2Vla1llYXIoKSwgdGhpcy4kdSk7CiAgICAgIHJldHVybiBub3dXZWVrVGh1cnNkYXkuZGlmZihkaWZmV2Vla1RodXJzZGF5LCBXKSArIDE7CiAgICB9OwogICAgcHJvdG8yLmlzb1dlZWtkYXkgPSBmdW5jdGlvbih3ZWVrKSB7CiAgICAgIGlmICghdGhpcy4kdXRpbHMoKS51KHdlZWspKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZGF5KHRoaXMuZGF5KCkgJSA3ID8gd2VlayA6IHdlZWsgLSA3KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5kYXkoKSB8fCA3OwogICAgfTsKICAgIHZhciBvbGRTdGFydE9mID0gcHJvdG8yLnN0YXJ0T2Y7CiAgICBwcm90bzIuc3RhcnRPZiA9IGZ1bmN0aW9uKHVuaXRzLCBzdGFydE9mKSB7CiAgICAgIHZhciB1dGlscyA9IHRoaXMuJHV0aWxzKCk7CiAgICAgIHZhciBpc1N0YXJ0T2YgPSAhdXRpbHMudShzdGFydE9mKSA/IHN0YXJ0T2YgOiB0cnVlOwogICAgICB2YXIgdW5pdCA9IHV0aWxzLnAodW5pdHMpOwogICAgICBpZiAodW5pdCA9PT0gaXNvV2Vla1ByZXR0eVVuaXQpIHsKICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gdGhpcy5kYXRlKHRoaXMuZGF0ZSgpIC0gKHRoaXMuaXNvV2Vla2RheSgpIC0gMSkpLnN0YXJ0T2YoImRheSIpIDogdGhpcy5kYXRlKHRoaXMuZGF0ZSgpIC0gMSAtICh0aGlzLmlzb1dlZWtkYXkoKSAtIDEpICsgNykuZW5kT2YoImRheSIpOwogICAgICB9CiAgICAgIHJldHVybiBvbGRTdGFydE9mLmJpbmQodGhpcykodW5pdHMsIHN0YXJ0T2YpOwogICAgfTsKICB9OwogIGRheWpzLmV4dGVuZChpc29XZWVrKTsKICBkYXlqcy5leHRlbmQoYWR2YW5jZWRGb3JtYXQpOwogIGNvbnN0IEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUsgPSAiR0dHRy1bV11XVyI7CiAgY29uc3QgX1RlbXBvcmFsQ2FjaGUgPSBjbGFzcyBfVGVtcG9yYWxDYWNoZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy55ZWFyTW9udGhEYXlDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMueWVhcldlZWtDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMueWVhck1vbnRoQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLnllYXJDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB9CiAgICBnZXRZZWFyTW9udGhEYXkoczIpIHsKICAgICAgaWYgKCF0aGlzLnllYXJNb250aERheUNhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJNb250aERheUNhY2hlLnNldChzMiwgWWVhck1vbnRoRGF5Q2xhc3MucGFyc2UoczIsIHRoaXMpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy55ZWFyTW9udGhEYXlDYWNoZS5nZXQoczIpOwogICAgfQogICAgZ2V0WWVhck1vbnRoKHMyKSB7CiAgICAgIGlmICghdGhpcy55ZWFyTW9udGhDYWNoZS5oYXMoczIpKSB7CiAgICAgICAgdGhpcy55ZWFyTW9udGhDYWNoZS5zZXQoczIsIFllYXJNb250aENsYXNzLnBhcnNlKHMyLCB0aGlzKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueWVhck1vbnRoQ2FjaGUuZ2V0KHMyKTsKICAgIH0KICAgIGdldFllYXJXZWVrKHMyKSB7CiAgICAgIGlmICghdGhpcy55ZWFyV2Vla0NhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJXZWVrQ2FjaGUuc2V0KHMyLCBZZWFyV2Vla0NsYXNzLnBhcnNlKHMyLCB0aGlzKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueWVhcldlZWtDYWNoZS5nZXQoczIpOwogICAgfQogICAgZ2V0WWVhcihzMikgewogICAgICBpZiAoIXRoaXMueWVhckNhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJDYWNoZS5zZXQoczIsIFllYXJDbGFzcy5wYXJzZShzMiwgdGhpcykpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnllYXJDYWNoZS5nZXQoczIpOwogICAgfQogICAgc3RhdGljIGdldEluc3RhbmNlKCkgewogICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZTsKICAgIH0KICB9OwogIF9UZW1wb3JhbENhY2hlLmluc3RhbmNlID0gbmV3IF9UZW1wb3JhbENhY2hlKCk7CiAgbGV0IFRlbXBvcmFsQ2FjaGUgPSBfVGVtcG9yYWxDYWNoZTsKICBjbGFzcyBZZWFyTW9udGhEYXlDbGFzcyB7CiAgICBjb25zdHJ1Y3Rvcih5ZWFyTnVtYmVyLCBtb250aE51bWJlciwgZGF5TnVtYmVyLCBjYWNoZSkgewogICAgICB0aGlzLnllYXJOdW1iZXIgPSB5ZWFyTnVtYmVyOwogICAgICB0aGlzLm1vbnRoTnVtYmVyID0gbW9udGhOdW1iZXI7CiAgICAgIHRoaXMuZGF5TnVtYmVyID0gZGF5TnVtYmVyOwogICAgICB0aGlzLmNhY2hlID0gY2FjaGU7CiAgICAgIHRoaXMudHlwZSA9ICJZZWFyTW9udGhEYXkiOwogICAgICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSh0aGlzLnllYXJOdW1iZXIsIHRoaXMubW9udGhOdW1iZXIgLSAxLCB0aGlzLmRheU51bWJlcik7CiAgICAgIHRoaXMuZGF5anMgPSBkYXlqcyh0aGlzLmRhdGUpOwogICAgICB0aGlzLmRhdGVTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7CiAgICB9CiAgICBnZXQgdGV4dCgpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF5anMuZm9ybWF0KCJZWVlZLU1NLUREIik7CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMudGV4dDsKICAgIH0KICAgIGVuZ2xpc2hOYW1lKCkgewogICAgICByZXR1cm4gdGhpcy5kYXlqcy5mb3JtYXQoImRkZGQsIE1NTU0gRCwgWVlZWSIpOwogICAgfQogICAgZ2V0IGZpcnN0RGF5KCkgewogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIGdldCBsYXN0RGF5KCkgewogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMueWVhck51bWJlcn1gKTsKICAgIH0KICAgIGdldCBtb250aCgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoKHRoaXMuZGF5anMuZm9ybWF0KCJZWVlZLU1NIikpOwogICAgfQogICAgZ2V0IHdlZWsoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJXZWVrKHRoaXMuZGF5anMuZm9ybWF0KEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUspKTsKICAgIH0KICAgIGFkZERheXMoZGF5cykgewogICAgICBjb25zdCBkYXRlID0gdGhpcy5kYXlqcy5hZGQoZGF5cywgImRheSIpOwogICAgICBjb25zdCBzMiA9IGRhdGUuZm9ybWF0KCJZWVlZLU1NLUREIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShzMik7CiAgICB9CiAgICBtaW51cyhvdGhlcikgewogICAgICByZXR1cm4gdGhpcy5kYXlqcy5kaWZmKG90aGVyLmRheWpzLCAiZGF5Iik7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UoczIsIGNhY2hlKSB7CiAgICAgIGNvbnN0IFt5ZWFyLCBtb250aCwgZGF5XSA9IHMyLnNwbGl0KCItIikubWFwKChzMjIpID0+IHBhcnNlSW50KHMyMiwgMTApKTsKICAgICAgcmV0dXJuIG5ldyBZZWFyTW9udGhEYXlDbGFzcyh5ZWFyLCBtb250aCwgZGF5LCBjYWNoZSk7CiAgICB9CiAgfQogIGNsYXNzIFllYXJXZWVrQ2xhc3MgewogICAgY29uc3RydWN0b3IoaXNvWWVhck51bWJlciwgaXNvV2Vla051bWJlciwgY2FjaGUpIHsKICAgICAgdGhpcy5pc29ZZWFyTnVtYmVyID0gaXNvWWVhck51bWJlcjsKICAgICAgdGhpcy5pc29XZWVrTnVtYmVyID0gaXNvV2Vla051bWJlcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhcldlZWsiOwogICAgICB0aGlzLmRhdGVTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7CiAgICB9CiAgICBnZXQgdGV4dCgpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZm9ybWF0KEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUspOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIGBXZWVrICR7dGhpcy5pc29XZWVrTnVtYmVyfSwgJHt0aGlzLmlzb1llYXJOdW1iZXJ9YDsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgY29uc3QgZmlyc3REYXkgPSBkYXlqcygpLnllYXIodGhpcy5pc29ZZWFyTnVtYmVyKS5tb250aCgxKS5kYXRlKDQpLmlzb1dlZWsodGhpcy5pc29XZWVrTnVtYmVyKS5zdGFydE9mKCJpc29XZWVrIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShmaXJzdERheS5mb3JtYXQoIllZWVktTU0tREQiKSk7CiAgICB9CiAgICBnZXQgbGFzdERheSgpIHsKICAgICAgY29uc3QgZmlyc3REYXkgPSBkYXlqcygpLnllYXIodGhpcy5pc29ZZWFyTnVtYmVyKS5zdGFydE9mKCJ5ZWFyIikuYWRkKCh0aGlzLmlzb1dlZWtOdW1iZXIgLSAxKSAqIDcsICJkYXkiKS5zdGFydE9mKCJ3ZWVrIikuYWRkKDEsICJkYXkiKTsKICAgICAgY29uc3QgbGFzdERheSA9IGZpcnN0RGF5LmFkZCg2LCAiZGF5Iik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShsYXN0RGF5LmZvcm1hdCgiWVlZWS1NTS1ERCIpKTsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMuaXNvWWVhck51bWJlcn1gKTsKICAgIH0KICAgIGFkZFdlZWtzKHdlZWtzKSB7CiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZpcnN0RGF5LmRheWpzLmFkZCh3ZWVrcywgIndlZWsiKTsKICAgICAgY29uc3QgczIgPSBkYXRlLmZvcm1hdChGT1JNQVRfSVNPX1dFRUtfWUVBUl9XRUVLKTsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhcldlZWsoczIpOwogICAgfQogICAgbWludXMob3RoZXIpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZGlmZihvdGhlci5maXJzdERheS5kYXlqcywgIndlZWsiKTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShzMiwgY2FjaGUpIHsKICAgICAgY29uc3QgW3llYXIsIHdlZWtdID0gczIuc3BsaXQoIi1XIikubWFwKChzMjIpID0+IHBhcnNlSW50KHMyMiwgMTApKTsKICAgICAgcmV0dXJuIG5ldyBZZWFyV2Vla0NsYXNzKHllYXIsIHdlZWssIGNhY2hlKTsKICAgIH0KICB9CiAgY2xhc3MgWWVhck1vbnRoQ2xhc3MgewogICAgY29uc3RydWN0b3IoeWVhck51bWJlciwgbW9udGhOdW1iZXIsIGNhY2hlKSB7CiAgICAgIHRoaXMueWVhck51bWJlciA9IHllYXJOdW1iZXI7CiAgICAgIHRoaXMubW9udGhOdW1iZXIgPSBtb250aE51bWJlcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhck1vbnRoIjsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmZvcm1hdCgiWVlZWS1NTSIpOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIGAke21vbnRoTmFtZSh0aGlzLm1vbnRoTnVtYmVyKX0gJHt0aGlzLnllYXJOdW1iZXJ9YDsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoRGF5KGRheWpzKGAke3RoaXMueWVhck51bWJlcn0tJHt0aGlzLm1vbnRoTnVtYmVyfS0wMWApLmZvcm1hdCgiWVlZWS1NTS1ERCIpKTsKICAgIH0KICAgIGdldCBsYXN0RGF5KCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGhEYXkoCiAgICAgICAgZGF5anMoYCR7dGhpcy55ZWFyTnVtYmVyfS0ke3RoaXMubW9udGhOdW1iZXJ9LTAxYCkuZW5kT2YoIm1vbnRoIikuZm9ybWF0KCJZWVlZLU1NLUREIikKICAgICAgKTsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMueWVhck51bWJlcn1gKTsKICAgIH0KICAgIGFkZE1vbnRocyhtb250aHMpIHsKICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZmlyc3REYXkuZGF5anMuYWRkKG1vbnRocywgIm1vbnRoIik7CiAgICAgIGNvbnN0IHMyID0gZGF0ZS5mb3JtYXQoIllZWVktTU0iKTsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoKHMyKTsKICAgIH0KICAgIG1pbnVzKG90aGVyKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmRpZmYob3RoZXIuZmlyc3REYXkuZGF5anMsICJtb250aCIpOwogICAgfQogICAgc3RhdGljIHBhcnNlKHMyLCBjYWNoZSkgewogICAgICBjb25zdCBbeWVhciwgbW9udGhdID0gczIuc3BsaXQoIi0iKS5tYXAoKHMyMikgPT4gcGFyc2VJbnQoczIyLCAxMCkpOwogICAgICByZXR1cm4gbmV3IFllYXJNb250aENsYXNzKHllYXIsIG1vbnRoLCBjYWNoZSk7CiAgICB9CiAgfQogIGNsYXNzIFllYXJDbGFzcyB7CiAgICBjb25zdHJ1Y3Rvcih5ZWFyLCBjYWNoZSkgewogICAgICB0aGlzLnllYXIgPSB5ZWFyOwogICAgICB0aGlzLmNhY2hlID0gY2FjaGU7CiAgICAgIHRoaXMudHlwZSA9ICJZZWFyIjsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmZvcm1hdCgiWVlZWSIpOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIHRoaXMueWVhci50b1N0cmluZygpOwogICAgfQogICAgZ2V0IGZpcnN0TW9udGgoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aChgJHt0aGlzLnllYXJ9LTAxYCk7CiAgICB9CiAgICBnZXQgbGFzdE1vbnRoKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGgoYCR7dGhpcy55ZWFyfS0xMmApOwogICAgfQogICAgZ2V0IGZpcnN0RGF5KCkgewogICAgICByZXR1cm4gdGhpcy5maXJzdE1vbnRoLmZpcnN0RGF5OwogICAgfQogICAgZ2V0IGxhc3REYXkoKSB7CiAgICAgIHJldHVybiB0aGlzLmxhc3RNb250aC5sYXN0RGF5OwogICAgfQogICAgYWRkWWVhcnMoeWVhcnMpIHsKICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZmlyc3REYXkuZGF5anMuYWRkKHllYXJzLCAieWVhciIpOwogICAgICBjb25zdCBzMiA9IGRhdGUuZm9ybWF0KCJZWVlZIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXIoczIpOwogICAgfQogICAgbWludXMob3RoZXIpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZGlmZihvdGhlci5maXJzdERheS5kYXlqcywgInllYXIiKTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShzMiwgY2FjaGUpIHsKICAgICAgY29uc3QgeWVhciA9IHBhcnNlSW50KHMyLCAxMCk7CiAgICAgIHJldHVybiBuZXcgWWVhckNsYXNzKHllYXIsIGNhY2hlKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gbW9udGhOYW1lKG1vbnRoKSB7CiAgICByZXR1cm4gZGF5anMoKS5tb250aChtb250aCAtIDEpLmZvcm1hdCgiTU1NTSIpOwogIH0KICBmdW5jdGlvbiB0b1RlbXBvcmFsKHRlbXBvcmFsQ2xhc3MpIHsKICAgIHN3aXRjaCAodGVtcG9yYWxDbGFzcy50eXBlKSB7CiAgICAgIGNhc2UgIlllYXJNb250aERheSI6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHR5cGU6ICJZZWFyTW9udGhEYXkiLAogICAgICAgICAgeWVhck51bWJlcjogdGVtcG9yYWxDbGFzcy55ZWFyTnVtYmVyLAogICAgICAgICAgbW9udGhOdW1iZXI6IHRlbXBvcmFsQ2xhc3MubW9udGhOdW1iZXIsCiAgICAgICAgICBkYXlOdW1iZXI6IHRlbXBvcmFsQ2xhc3MuZGF5TnVtYmVyLAogICAgICAgICAgZGF0ZVN0cmluZzogdGVtcG9yYWxDbGFzcy5kYXRlU3RyaW5nCiAgICAgICAgfTsKICAgICAgY2FzZSAiWWVhcldlZWsiOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiWWVhcldlZWsiLAogICAgICAgICAgaXNvWWVhck51bWJlcjogdGVtcG9yYWxDbGFzcy5pc29ZZWFyTnVtYmVyLAogICAgICAgICAgaXNvV2Vla051bWJlcjogdGVtcG9yYWxDbGFzcy5pc29XZWVrTnVtYmVyLAogICAgICAgICAgZGF0ZVN0cmluZzogdGVtcG9yYWxDbGFzcy5kYXRlU3RyaW5nCiAgICAgICAgfTsKICAgICAgY2FzZSAiWWVhck1vbnRoIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogIlllYXJNb250aCIsCiAgICAgICAgICB5ZWFyTnVtYmVyOiB0ZW1wb3JhbENsYXNzLnllYXJOdW1iZXIsCiAgICAgICAgICBtb250aE51bWJlcjogdGVtcG9yYWxDbGFzcy5tb250aE51bWJlciwKICAgICAgICAgIGRhdGVTdHJpbmc6IHRlbXBvcmFsQ2xhc3MuZGF0ZVN0cmluZwogICAgICAgIH07CiAgICAgIGNhc2UgIlllYXIiOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiWWVhciIsCiAgICAgICAgICB5ZWFyOiB0ZW1wb3JhbENsYXNzLnllYXIsCiAgICAgICAgICBkYXRlU3RyaW5nOiB0ZW1wb3JhbENsYXNzLmRhdGVTdHJpbmcKICAgICAgICB9OwogICAgfQogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbERheXNJblJhbmdlKHN0YXJ0LCBlbmQpIHsKICAgIGNvbnN0IGRheXMgPSBbXTsKICAgIGNvbnN0IGRheXNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSBkYXlzSW5CZXR3ZWVuOyBpMisrKSB7CiAgICAgIGRheXMucHVzaChzdGFydC5hZGREYXlzKGkyKSk7CiAgICB9CiAgICByZXR1cm4gZGF5czsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVBbGxXZWVrc0luUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgY29uc3Qgd2Vla3MgPSBbXTsKICAgIGNvbnN0IHdlZWtzSW5CZXR3ZWVuID0gZW5kLm1pbnVzKHN0YXJ0KTsKICAgIGZvciAobGV0IGkyID0gMDsgaTIgPD0gd2Vla3NJbkJldHdlZW47IGkyKyspIHsKICAgICAgd2Vla3MucHVzaChzdGFydC5hZGRXZWVrcyhpMikpOwogICAgfQogICAgcmV0dXJuIHdlZWtzOwogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbE1vbnRoc0luUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgY29uc3QgbW9udGhzID0gW107CiAgICBjb25zdCBtb250aHNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSBtb250aHNJbkJldHdlZW47IGkyKyspIHsKICAgICAgbW9udGhzLnB1c2goc3RhcnQuYWRkTW9udGhzKGkyKSk7CiAgICB9CiAgICByZXR1cm4gbW9udGhzOwogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbFllYXJzSW5SYW5nZShzdGFydCwgZW5kKSB7CiAgICBjb25zdCB5ZWFycyA9IFtdOwogICAgY29uc3QgeWVhcnNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSB5ZWFyc0luQmV0d2VlbjsgaTIrKykgewogICAgICB5ZWFycy5wdXNoKHN0YXJ0LmFkZFllYXJzKGkyKSk7CiAgICB9CiAgICByZXR1cm4geWVhcnM7CiAgfQogIGZ1bmN0aW9uIGdlbmVyYXRlQWxsSW5SYW5nZShzdGFydCwgZW5kKSB7CiAgICBpZiAoc3RhcnQgPT09IG51bGwgfHwgZW5kID09PSBudWxsKSB7CiAgICAgIHJldHVybiBbXTsKICAgIH0KICAgIGlmIChzdGFydCBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzICYmIGVuZCBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbERheXNJblJhbmdlKHN0YXJ0LCBlbmQpOwogICAgfQogICAgaWYgKHN0YXJ0IGluc3RhbmNlb2YgWWVhcldlZWtDbGFzcyAmJiBlbmQgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbFdlZWtzSW5SYW5nZShzdGFydCwgZW5kKTsKICAgIH0KICAgIGlmIChzdGFydCBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzICYmIGVuZCBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbE1vbnRoc0luUmFuZ2Uoc3RhcnQsIGVuZCk7CiAgICB9CiAgICBpZiAoc3RhcnQgaW5zdGFuY2VvZiBZZWFyQ2xhc3MgJiYgZW5kIGluc3RhbmNlb2YgWWVhckNsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbFllYXJzSW5SYW5nZShzdGFydCwgZW5kKTsKICAgIH0KICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcmd1bWVudHM6IHN0YXJ0IGFuZCBlbmQgbXVzdCBiZSBvZiB0aGUgc2FtZSB0eXBlOiAke3N0YXJ0fSwgJHtlbmR9YCk7CiAgfQogIGZ1bmN0aW9uIG1pbnVzVGVtcG9yYWwoYTIsIGIpIHsKICAgIGlmIChhMiBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyTW9udGhEYXlDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzKSB7CiAgICAgIHJldHVybiBhMi5taW51cyhiKTsKICAgIH0KICAgIGlmIChhMiBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyTW9udGhDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyQ2xhc3MgJiYgYiBpbnN0YW5jZW9mIFllYXJDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wYXJlICR7YTJ9IGFuZCAke2J9YCk7CiAgfQogIGZ1bmN0aW9uIGNvbXBhcmVUZW1wb3JhbChhMiwgYikgewogICAgaWYgKGEyID09PSBudWxsKSB7CiAgICAgIHJldHVybiAxOwogICAgfQogICAgaWYgKGIgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29uc3QgZGlmZiA9IG1pbnVzVGVtcG9yYWwoYTIsIGIpOwogICAgaWYgKGRpZmYgPCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChkaWZmID4gMCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwogIH0KICBmdW5jdGlvbiBnZXRNaW5NYXhUZW1wb3JhbCh2YWx1ZXMpIHsKICAgIGxldCBtaW4gPSBudWxsOwogICAgbGV0IG1heCA9IG51bGw7CiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykgewogICAgICBpZiAodmFsdWUgPT09IG51bGwpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAobWluID09PSBudWxsIHx8IGNvbXBhcmVUZW1wb3JhbCh2YWx1ZSwgbWluKSA8IDApIHsKICAgICAgICBtaW4gPSB2YWx1ZTsKICAgICAgfQogICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNvbXBhcmVUZW1wb3JhbCh2YWx1ZSwgbWF4KSA+IDApIHsKICAgICAgICBtYXggPSB2YWx1ZTsKICAgICAgfQogICAgfQogICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBtYXggPT09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgbWluOiBudWxsLCBtYXg6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IG1pbiwgbWF4IH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwoZGF0ZSwgZ3JhbnVsYXJpdHkpIHsKICAgIGNvbnN0IGNhY2hlID0gVGVtcG9yYWxDYWNoZS5nZXRJbnN0YW5jZSgpOwogICAgY29uc3QgZGF5ID0gY2FjaGUuZ2V0WWVhck1vbnRoRGF5KGRhdGUpOwogICAgc3dpdGNoIChncmFudWxhcml0eSkgewogICAgICBjYXNlICJkYXkiOgogICAgICAgIHJldHVybiBkYXk7CiAgICAgIGNhc2UgIndlZWsiOgogICAgICAgIHJldHVybiBkYXkud2VlazsKICAgICAgY2FzZSAibW9udGgiOgogICAgICAgIHJldHVybiBkYXkubW9udGg7CiAgICAgIGNhc2UgInllYXIiOgogICAgICAgIHJldHVybiBkYXkueWVhcjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZGF0ZVJhbmdlQ29tcGFyZShhMiwgYikgewogICAgaWYgKGEyLmRhdGVSYW5nZSA9PT0gbnVsbCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIGlmIChiLmRhdGVSYW5nZSA9PT0gbnVsbCkgewogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICByZXR1cm4gY29tcGFyZVRlbXBvcmFsKGEyLmRhdGVSYW5nZSwgYi5kYXRlUmFuZ2UpOwogIH0KICBmdW5jdGlvbiBtYXBEYXRlVG9HcmFudWxhcml0eVJhbmdlKGRhdGEsIGdyYW51bGFyaXR5KSB7CiAgICByZXR1cm4gewogICAgICBkYXRlUmFuZ2U6IGRhdGEuZGF0ZSA9PT0gbnVsbCA/IG51bGwgOiBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKGRhdGEuZGF0ZSwgZ3JhbnVsYXJpdHkpLAogICAgICBjb3VudDogZGF0YS5jb3VudAogICAgfTsKICB9CiAgY29uc3Qgc3Vic3RpdHV0aW9uUmVnZXggPSAvXigoPzxzZWdtZW50PltBLVowLTlfLV0rKSg/PTopOik/KD88dmFsdWVBdFJlZmVyZW5jZT5bQS1aXSk/KD88cG9zaXRpb24+XGQrKSg/PHN1YnN0aXR1dGlvblZhbHVlPltBLVouXSk/JC9pOwogIGNsYXNzIFN1YnN0aXR1dGlvbkNsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHNlZ21lbnQsIHZhbHVlQXRSZWZlcmVuY2UsIHN1YnN0aXR1dGlvblZhbHVlLCBwb3NpdGlvbikgewogICAgICB0aGlzLnNlZ21lbnQgPSBzZWdtZW50OwogICAgICB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPSB2YWx1ZUF0UmVmZXJlbmNlOwogICAgICB0aGlzLnN1YnN0aXR1dGlvblZhbHVlID0gc3Vic3RpdHV0aW9uVmFsdWU7CiAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgdGhpcy50eXBlID0gInN1YnN0aXR1dGlvbiI7CiAgICAgIGNvbnN0IHNlZ21lbnRTdHJpbmcgPSB0aGlzLnNlZ21lbnQgPyBgJHt0aGlzLnNlZ21lbnR9OmAgOiAiIjsKICAgICAgY29uc3QgdmFsdWVBdFJlZmVyZW5jZVN0cmluZyA9IHRoaXMudmFsdWVBdFJlZmVyZW5jZSA/IGAke3RoaXMudmFsdWVBdFJlZmVyZW5jZX1gIDogIiI7CiAgICAgIGNvbnN0IHN1YnN0aXR1dGlvblZhbHVlU3RyaW5nID0gdGhpcy5zdWJzdGl0dXRpb25WYWx1ZSA/IGAke3RoaXMuc3Vic3RpdHV0aW9uVmFsdWV9YCA6ICIiOwogICAgICB0aGlzLmNvZGUgPSBgJHtzZWdtZW50U3RyaW5nfSR7dmFsdWVBdFJlZmVyZW5jZVN0cmluZ30ke3RoaXMucG9zaXRpb259JHtzdWJzdGl0dXRpb25WYWx1ZVN0cmluZ31gOwogICAgfQogICAgZXF1YWxzKG90aGVyKSB7CiAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU3Vic3RpdHV0aW9uQ2xhc3MpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnNlZ21lbnQgPT09IG90aGVyLnNlZ21lbnQgJiYgdGhpcy52YWx1ZUF0UmVmZXJlbmNlID09PSBvdGhlci52YWx1ZUF0UmVmZXJlbmNlICYmIHRoaXMuc3Vic3RpdHV0aW9uVmFsdWUgPT09IG90aGVyLnN1YnN0aXR1dGlvblZhbHVlICYmIHRoaXMucG9zaXRpb24gPT09IG90aGVyLnBvc2l0aW9uOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLmNvZGU7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UobXV0YXRpb25TdHIpIHsKICAgICAgY29uc3QgbWF0Y2ggPSBtdXRhdGlvblN0ci5tYXRjaChzdWJzdGl0dXRpb25SZWdleCk7CiAgICAgIGlmIChtYXRjaCA9PT0gbnVsbCB8fCBtYXRjaC5ncm91cHMgPT09IHZvaWQgMCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBuZXcgU3Vic3RpdHV0aW9uQ2xhc3MoCiAgICAgICAgbWF0Y2guZ3JvdXBzLnNlZ21lbnQsCiAgICAgICAgbWF0Y2guZ3JvdXBzLnZhbHVlQXRSZWZlcmVuY2UsCiAgICAgICAgbWF0Y2guZ3JvdXBzLnN1YnN0aXR1dGlvblZhbHVlLAogICAgICAgIHBhcnNlSW50KG1hdGNoLmdyb3Vwcy5wb3NpdGlvbiwgMTApCiAgICAgICk7CiAgICB9CiAgfQogIGNvbnN0IGRlbGV0aW9uUmVnZXggPSAvXigoPzxzZWdtZW50PltBLVowLTlfLV0rKSg/PTopOik/KD88dmFsdWVBdFJlZmVyZW5jZT5bQS1aXSk/KD88cG9zaXRpb24+XGQrKSgtKSQvaTsKICBjbGFzcyBEZWxldGlvbkNsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHNlZ21lbnQsIHZhbHVlQXRSZWZlcmVuY2UsIHBvc2l0aW9uKSB7CiAgICAgIHRoaXMuc2VnbWVudCA9IHNlZ21lbnQ7CiAgICAgIHRoaXMudmFsdWVBdFJlZmVyZW5jZSA9IHZhbHVlQXRSZWZlcmVuY2U7CiAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgdGhpcy50eXBlID0gImRlbGV0aW9uIjsKICAgICAgY29uc3Qgc2VnbWVudFN0cmluZyA9IHRoaXMuc2VnbWVudCA/IGAke3RoaXMuc2VnbWVudH06YCA6ICIiOwogICAgICBjb25zdCB2YWx1ZUF0UmVmZXJlbmNlU3RyaW5nID0gdGhpcy52YWx1ZUF0UmVmZXJlbmNlID8gYCR7dGhpcy52YWx1ZUF0UmVmZXJlbmNlfWAgOiAiIjsKICAgICAgdGhpcy5jb2RlID0gYCR7c2VnbWVudFN0cmluZ30ke3ZhbHVlQXRSZWZlcmVuY2VTdHJpbmd9JHt0aGlzLnBvc2l0aW9ufS1gOwogICAgfQogICAgZXF1YWxzKG90aGVyKSB7CiAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgRGVsZXRpb25DbGFzcykpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuc2VnbWVudCA9PT0gb3RoZXIuc2VnbWVudCAmJiB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPT09IG90aGVyLnZhbHVlQXRSZWZlcmVuY2UgJiYgdGhpcy5wb3NpdGlvbiA9PT0gb3RoZXIucG9zaXRpb247CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuY29kZTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShtdXRhdGlvblN0cikgewogICAgICBjb25zdCBtYXRjaCA9IG11dGF0aW9uU3RyLm1hdGNoKGRlbGV0aW9uUmVnZXgpOwogICAgICBpZiAobWF0Y2ggPT09IG51bGwgfHwgbWF0Y2guZ3JvdXBzID09PSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfQogICAgICByZXR1cm4gbmV3IERlbGV0aW9uQ2xhc3MoCiAgICAgICAgbWF0Y2guZ3JvdXBzLnNlZ21lbnQsCiAgICAgICAgbWF0Y2guZ3JvdXBzLnZhbHVlQXRSZWZlcmVuY2UsCiAgICAgICAgcGFyc2VJbnQobWF0Y2guZ3JvdXBzLnBvc2l0aW9uLCAxMCkKICAgICAgKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gdG9TdWJzdGl0dXRpb25PckRlbGV0aW9uKG11dGF0aW9uKSB7CiAgICBzd2l0Y2ggKG11dGF0aW9uLnR5cGUpIHsKICAgICAgY2FzZSAic3Vic3RpdHV0aW9uIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogInN1YnN0aXR1dGlvbiIsCiAgICAgICAgICBjb2RlOiBtdXRhdGlvbi5jb2RlLAogICAgICAgICAgc2VnbWVudDogbXV0YXRpb24uc2VnbWVudCwKICAgICAgICAgIHBvc2l0aW9uOiBtdXRhdGlvbi5wb3NpdGlvbiwKICAgICAgICAgIHZhbHVlQXRSZWZlcmVuY2U6IG11dGF0aW9uLnZhbHVlQXRSZWZlcmVuY2UsCiAgICAgICAgICBzdWJzdGl0dXRpb25WYWx1ZTogbXV0YXRpb24uc3Vic3RpdHV0aW9uVmFsdWUKICAgICAgICB9OwogICAgICBjYXNlICJkZWxldGlvbiI6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHR5cGU6ICJkZWxldGlvbiIsCiAgICAgICAgICBjb2RlOiBtdXRhdGlvbi5jb2RlLAogICAgICAgICAgc2VnbWVudDogbXV0YXRpb24uc2VnbWVudCwKICAgICAgICAgIHBvc2l0aW9uOiBtdXRhdGlvbi5wb3NpdGlvbiwKICAgICAgICAgIHZhbHVlQXRSZWZlcmVuY2U6IG11dGF0aW9uLnZhbHVlQXRSZWZlcmVuY2UKICAgICAgICB9OwogICAgfQogIH0KICBjbGFzcyBGZXRjaFN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc09wZXJhdG9yIHsKICAgIGNvbnN0cnVjdG9yKGZpbHRlciwgc2VxdWVuY2VUeXBlLCBtaW5Qcm9wb3J0aW9uKSB7CiAgICAgIHRoaXMuZmlsdGVyID0gZmlsdGVyOwogICAgICB0aGlzLnNlcXVlbmNlVHlwZSA9IHNlcXVlbmNlVHlwZTsKICAgICAgdGhpcy5taW5Qcm9wb3J0aW9uID0gbWluUHJvcG9ydGlvbjsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzLCBzaWduYWwpIHsKICAgICAgY29uc3QgbXV0YXRpb25zID0gYXdhaXQgdGhpcy5mZXRjaE11dGF0aW9ucyhsYXBpcywgc2lnbmFsKTsKICAgICAgY29uc3QgY29udGVudCA9IG11dGF0aW9ucy5tYXAoCiAgICAgICAgKHsgY291bnQsIHByb3BvcnRpb24sIG11dGF0aW9uRnJvbSwgbXV0YXRpb25UbywgcG9zaXRpb24sIHNlcXVlbmNlTmFtZSB9KSA9PiB7CiAgICAgICAgICBpZiAobXV0YXRpb25UbyA9PT0gIi0iKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgdHlwZTogImRlbGV0aW9uIiwKICAgICAgICAgICAgICBtdXRhdGlvbjogbmV3IERlbGV0aW9uQ2xhc3Moc2VxdWVuY2VOYW1lID8/IHZvaWQgMCwgbXV0YXRpb25Gcm9tLCBwb3NpdGlvbiksCiAgICAgICAgICAgICAgY291bnQsCiAgICAgICAgICAgICAgcHJvcG9ydGlvbgogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgdHlwZTogInN1YnN0aXR1dGlvbiIsCiAgICAgICAgICAgIG11dGF0aW9uOiBuZXcgU3Vic3RpdHV0aW9uQ2xhc3Moc2VxdWVuY2VOYW1lID8/IHZvaWQgMCwgbXV0YXRpb25Gcm9tLCBtdXRhdGlvblRvLCBwb3NpdGlvbiksCiAgICAgICAgICAgIGNvdW50LAogICAgICAgICAgICBwcm9wb3J0aW9uCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgKTsKICAgICAgcmV0dXJuIHsgY29udGVudCB9OwogICAgfQogICAgYXN5bmMgZmV0Y2hNdXRhdGlvbnMobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBmaWx0ZXIgPSB7CiAgICAgICAgLi4udGhpcy5maWx0ZXIsCiAgICAgICAgbWluUHJvcG9ydGlvbjogdGhpcy5taW5Qcm9wb3J0aW9uCiAgICAgIH07CiAgICAgIHJldHVybiBmZXRjaFN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhsYXBpcywgZmlsdGVyLCB0aGlzLnNlcXVlbmNlVHlwZSwgc2lnbmFsKS50aGVuKAogICAgICAgIChyZXNwb25zZSkgPT4gcmVzcG9uc2UuZGF0YQogICAgICApOwogICAgfQogIH0KICB2YXIgbCQxOwogIGwkMSA9IHsgX19lOiBmdW5jdGlvbihuLCBsMiwgdTIsIHQpIHsKICAgIGZvciAodmFyIGkyLCByMiwgbzsgbDIgPSBsMi5fXzsgKSBpZiAoKGkyID0gbDIuX19jKSAmJiAhaTIuX18pIHRyeSB7CiAgICAgIGlmICgocjIgPSBpMi5jb25zdHJ1Y3RvcikgJiYgbnVsbCAhPSByMi5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgJiYgKGkyLnNldFN0YXRlKHIyLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcihuKSksIG8gPSBpMi5fX2QpLCBudWxsICE9IGkyLmNvbXBvbmVudERpZENhdGNoICYmIChpMi5jb21wb25lbnREaWRDYXRjaChuLCB0IHx8IHt9KSwgbyA9IGkyLl9fZCksIG8pIHJldHVybiBpMi5fX0UgPSBpMjsKICAgIH0gY2F0Y2ggKGwzKSB7CiAgICAgIG4gPSBsMzsKICAgIH0KICAgIHRocm93IG47CiAgfSB9LCAiZnVuY3Rpb24iID09IHR5cGVvZiBQcm9taXNlID8gUHJvbWlzZS5wcm90b3R5cGUudGhlbi5iaW5kKFByb21pc2UucmVzb2x2ZSgpKSA6IHNldFRpbWVvdXQ7CiAgdmFyIHIsIHUsIGksIGYgPSBbXSwgYyA9IGwkMSwgZSA9IGMuX19iLCBhID0gYy5fX3IsIHYgPSBjLmRpZmZlZCwgbCA9IGMuX19jLCBtID0gYy51bm1vdW50LCBzID0gYy5fXzsKICBmdW5jdGlvbiBqKCkgewogICAgZm9yICh2YXIgbjsgbiA9IGYuc2hpZnQoKTsgKSBpZiAobi5fX1AgJiYgbi5fX0gpIHRyeSB7CiAgICAgIG4uX19ILl9faC5mb3JFYWNoKHopLCBuLl9fSC5fX2guZm9yRWFjaChCKSwgbi5fX0guX19oID0gW107CiAgICB9IGNhdGNoICh0KSB7CiAgICAgIG4uX19ILl9faCA9IFtdLCBjLl9fZSh0LCBuLl9fdik7CiAgICB9CiAgfQogIGMuX19iID0gZnVuY3Rpb24obikgewogICAgciA9IG51bGwsIGUgJiYgZShuKTsKICB9LCBjLl9fID0gZnVuY3Rpb24obiwgdCkgewogICAgbiAmJiB0Ll9fayAmJiB0Ll9fay5fX20gJiYgKG4uX19tID0gdC5fX2suX19tKSwgcyAmJiBzKG4sIHQpOwogIH0sIGMuX19yID0gZnVuY3Rpb24obikgewogICAgYSAmJiBhKG4pOwogICAgdmFyIGkyID0gKHIgPSBuLl9fYykuX19IOwogICAgaTIgJiYgKHUgPT09IHIgPyAoaTIuX19oID0gW10sIHIuX19oID0gW10sIGkyLl9fLmZvckVhY2goZnVuY3Rpb24objIpIHsKICAgICAgbjIuX19OICYmIChuMi5fXyA9IG4yLl9fTiksIG4yLmkgPSBuMi5fX04gPSB2b2lkIDA7CiAgICB9KSkgOiAoaTIuX19oLmZvckVhY2goeiksIGkyLl9faC5mb3JFYWNoKEIpLCBpMi5fX2ggPSBbXSwgMCkpLCB1ID0gcjsKICB9LCBjLmRpZmZlZCA9IGZ1bmN0aW9uKG4pIHsKICAgIHYgJiYgdihuKTsKICAgIHZhciB0ID0gbi5fX2M7CiAgICB0ICYmIHQuX19IICYmICh0Ll9fSC5fX2gubGVuZ3RoICYmICgxICE9PSBmLnB1c2godCkgJiYgaSA9PT0gYy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgKChpID0gYy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHx8IHcpKGopKSwgdC5fX0guX18uZm9yRWFjaChmdW5jdGlvbihuMikgewogICAgICBuMi5pICYmIChuMi5fX0ggPSBuMi5pKSwgbjIuaSA9IHZvaWQgMDsKICAgIH0pKSwgdSA9IHIgPSBudWxsOwogIH0sIGMuX19jID0gZnVuY3Rpb24obiwgdCkgewogICAgdC5zb21lKGZ1bmN0aW9uKG4yKSB7CiAgICAgIHRyeSB7CiAgICAgICAgbjIuX19oLmZvckVhY2goeiksIG4yLl9faCA9IG4yLl9faC5maWx0ZXIoZnVuY3Rpb24objMpIHsKICAgICAgICAgIHJldHVybiAhbjMuX18gfHwgQihuMyk7CiAgICAgICAgfSk7CiAgICAgIH0gY2F0Y2ggKHIyKSB7CiAgICAgICAgdC5zb21lKGZ1bmN0aW9uKG4zKSB7CiAgICAgICAgICBuMy5fX2ggJiYgKG4zLl9faCA9IFtdKTsKICAgICAgICB9KSwgdCA9IFtdLCBjLl9fZShyMiwgbjIuX192KTsKICAgICAgfQogICAgfSksIGwgJiYgbChuLCB0KTsKICB9LCBjLnVubW91bnQgPSBmdW5jdGlvbihuKSB7CiAgICBtICYmIG0obik7CiAgICB2YXIgdCwgcjIgPSBuLl9fYzsKICAgIHIyICYmIHIyLl9fSCAmJiAocjIuX19ILl9fLmZvckVhY2goZnVuY3Rpb24objIpIHsKICAgICAgdHJ5IHsKICAgICAgICB6KG4yKTsKICAgICAgfSBjYXRjaCAobjMpIHsKICAgICAgICB0ID0gbjM7CiAgICAgIH0KICAgIH0pLCByMi5fX0ggPSB2b2lkIDAsIHQgJiYgYy5fX2UodCwgcjIuX192KSk7CiAgfTsKICB2YXIgayA9ICJmdW5jdGlvbiIgPT0gdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZTsKICBmdW5jdGlvbiB3KG4pIHsKICAgIHZhciB0LCByMiA9IGZ1bmN0aW9uKCkgewogICAgICBjbGVhclRpbWVvdXQodTIpLCBrICYmIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHQpLCBzZXRUaW1lb3V0KG4pOwogICAgfSwgdTIgPSBzZXRUaW1lb3V0KHIyLCAxMDApOwogICAgayAmJiAodCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShyMikpOwogIH0KICBmdW5jdGlvbiB6KG4pIHsKICAgIHZhciB0ID0gciwgdTIgPSBuLl9fYzsKICAgICJmdW5jdGlvbiIgPT0gdHlwZW9mIHUyICYmIChuLl9fYyA9IHZvaWQgMCwgdTIoKSksIHIgPSB0OwogIH0KICBmdW5jdGlvbiBCKG4pIHsKICAgIHZhciB0ID0gcjsKICAgIG4uX19jID0gbi5fXygpLCByID0gdDsKICB9CiAgY2xhc3MgVXNlckZhY2luZ0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IoaGVhZGxpbmUsIG1lc3NhZ2UpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuaGVhZGxpbmUgPSBoZWFkbGluZTsKICAgICAgdGhpcy5uYW1lID0gIlVzZXJGYWNpbmdFcnJvciI7CiAgICB9CiAgfQogIGNsYXNzIE1hcDJkQmFzZSB7CiAgICBjb25zdHJ1Y3RvcihzZXJpYWxpemVGaXJzdEF4aXMsIHNlcmlhbGl6ZVNlY29uZEF4aXMsIGluaXRpYWxDb250ZW50KSB7CiAgICAgIHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzID0gc2VyaWFsaXplRmlyc3RBeGlzOwogICAgICB0aGlzLnNlcmlhbGl6ZVNlY29uZEF4aXMgPSBzZXJpYWxpemVTZWNvbmRBeGlzOwogICAgICB0aGlzLmRhdGEgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLmtleXNGaXJzdEF4aXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLmtleXNTZWNvbmRBeGlzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgaWYgKGluaXRpYWxDb250ZW50KSB7CiAgICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5rZXlzRmlyc3RBeGlzKTsKICAgICAgICB0aGlzLmtleXNTZWNvbmRBeGlzID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5rZXlzU2Vjb25kQXhpcyk7CiAgICAgICAgdGhpcy5kYXRhID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5kYXRhKTsKICAgICAgfQogICAgfQogICAgZ2V0KGtleUZpcnN0QXhpcywga2V5U2Vjb25kQXhpcykgewogICAgICB2YXIgX2E7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMgPSB0aGlzLnNlcmlhbGl6ZUZpcnN0QXhpcyhrZXlGaXJzdEF4aXMpOwogICAgICBjb25zdCBzZXJpYWxpemVkS2V5U2Vjb25kQXhpcyA9IHRoaXMuc2VyaWFsaXplU2Vjb25kQXhpcyhrZXlTZWNvbmRBeGlzKTsKICAgICAgcmV0dXJuIChfYSA9IHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcykpID09IG51bGwgPyB2b2lkIDAgOiBfYS5nZXQoc2VyaWFsaXplZEtleVNlY29uZEF4aXMpOwogICAgfQogICAgZ2V0Um93KGtleSkgewogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5KTsKICAgICAgY29uc3Qgcm93ID0gdGhpcy5kYXRhLmdldChzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgICAgaWYgKHJvdyA9PT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIFtdOwogICAgICB9CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c1NlY29uZEF4aXMua2V5cygpKS5tYXAoKGtleTIpID0+IHJvdy5nZXQoa2V5MikpOwogICAgfQogICAgc2V0KGtleUZpcnN0QXhpcywga2V5U2Vjb25kQXhpcywgdmFsdWUpIHsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleUZpcnN0QXhpcyk7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzID0gdGhpcy5zZXJpYWxpemVTZWNvbmRBeGlzKGtleVNlY29uZEF4aXMpOwogICAgICBpZiAoIXRoaXMuZGF0YS5oYXMoc2VyaWFsaXplZEtleUZpcnN0QXhpcykpIHsKICAgICAgICB0aGlzLmRhdGEuc2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpOwogICAgICB9CiAgICAgIHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcykuc2V0KHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzLCB2YWx1ZSk7CiAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcy5zZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcywga2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzU2Vjb25kQXhpcy5zZXQoc2VyaWFsaXplZEtleVNlY29uZEF4aXMsIGtleVNlY29uZEF4aXMpOwogICAgfQogICAgZGVsZXRlUm93KGtleSkgewogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5KTsKICAgICAgdGhpcy5kYXRhLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgIH0KICAgIGdldEZpcnN0QXhpc0tleXMoKSB7CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c0ZpcnN0QXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRTZWNvbmRBeGlzS2V5cygpIHsKICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5rZXlzU2Vjb25kQXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRBc0FycmF5KCkgewogICAgICByZXR1cm4gdGhpcy5nZXRGaXJzdEF4aXNLZXlzKCkubWFwKChmaXJzdEF4aXNLZXkpID0+IHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRTZWNvbmRBeGlzS2V5cygpLm1hcCgoc2Vjb25kQXhpc0tleSkgPT4gewogICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KGZpcnN0QXhpc0tleSwgc2Vjb25kQXhpc0tleSk7CiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQogICAgZ2V0Q29udGVudHMoKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAga2V5c0ZpcnN0QXhpczogdGhpcy5rZXlzRmlyc3RBeGlzLAogICAgICAgIGtleXNTZWNvbmRBeGlzOiB0aGlzLmtleXNTZWNvbmRBeGlzLAogICAgICAgIGRhdGE6IHRoaXMuZGF0YQogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBCYXNlTXV0YXRpb25PdmVyVGltZURhdGFNYXAgZXh0ZW5kcyBNYXAyZEJhc2UgewogICAgY29uc3RydWN0b3IoaW5pdGlhbENvbnRlbnQpIHsKICAgICAgc3VwZXIoc2VyaWFsaXplU3Vic3RpdHV0aW9uT3JEZWxldGlvbiwgc2VyaWFsaXplVGVtcG9yYWwsIGluaXRpYWxDb250ZW50KTsKICAgIH0KICB9CiAgY29uc3Qgc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMi5zZWdtZW50ICE9PSBiLnNlZ21lbnQpIHsKICAgICAgcmV0dXJuIGNvbXBhcmVTZWdtZW50cyhhMi5zZWdtZW50LCBiLnNlZ21lbnQpOwogICAgfQogICAgaWYgKGEyLnBvc2l0aW9uICE9PSBiLnBvc2l0aW9uKSB7CiAgICAgIHJldHVybiBjb21wYXJlUG9zaXRpb25zKGEyLnBvc2l0aW9uLCBiLnBvc2l0aW9uKTsKICAgIH0KICAgIGNvbnN0IGFJc0RlbGV0aW9uID0gYTIgaW5zdGFuY2VvZiBEZWxldGlvbkNsYXNzOwogICAgY29uc3QgYklzRGVsZXRpb24gPSBiIGluc3RhbmNlb2YgRGVsZXRpb25DbGFzczsKICAgIGlmIChhSXNEZWxldGlvbiAhPT0gYklzRGVsZXRpb24pIHsKICAgICAgcmV0dXJuIGFJc0RlbGV0aW9uID8gMSA6IC0xOwogICAgfQogICAgaWYgKCFhSXNEZWxldGlvbiAmJiAhYklzRGVsZXRpb24pIHsKICAgICAgaWYgKGEyLnN1YnN0aXR1dGlvblZhbHVlICE9PSBiLnN1YnN0aXR1dGlvblZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMoYTIuc3Vic3RpdHV0aW9uVmFsdWUsIGIuc3Vic3RpdHV0aW9uVmFsdWUpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKICB9OwogIGNvbnN0IGNvbXBhcmVTZWdtZW50cyA9IChhMiwgYikgPT4gewogICAgaWYgKGEyID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgaWYgKGIgPT09IHZvaWQgMCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiBhMi5sb2NhbGVDb21wYXJlKGIpOwogIH07CiAgY29uc3QgY29tcGFyZVBvc2l0aW9ucyA9IChhMiwgYikgPT4gewogICAgcmV0dXJuIGEyIC0gYjsKICB9OwogIGNvbnN0IGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMiA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChiID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gYTIubG9jYWxlQ29tcGFyZShiKTsKICB9OwogIGNvbnN0IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TID0gMjAwOwogIGFzeW5jIGZ1bmN0aW9uIHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICBsYXBpc0ZpbHRlciwKICAgIHNlcXVlbmNlVHlwZSwKICAgIGxhcGlzLAogICAgZ3JhbnVsYXJpdHksCiAgICBsYXBpc0RhdGVGaWVsZCwKICAgIHNpZ25hbAogIH0pIHsKICAgIGNvbnN0IGFsbERhdGVzID0gYXdhaXQgZ2V0RGF0ZXNJbkRhdGFzZXQobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCk7CiAgICBpZiAoYWxsRGF0ZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogW10KICAgICAgfTsKICAgIH0KICAgIGNvbnN0IGZpbHRlciA9IHsKICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF06IGFsbERhdGVzWzBdLmZpcnN0RGF5LnRvU3RyaW5nKCksCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Ub2BdOiBhbGxEYXRlc1thbGxEYXRlcy5sZW5ndGggLSAxXS5sYXN0RGF5LnRvU3RyaW5nKCkKICAgIH07CiAgICByZXR1cm4gZmV0Y2hBbmRQcmVwYXJlU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGZpbHRlciwgc2VxdWVuY2VUeXBlKS5ldmFsdWF0ZShsYXBpcywgc2lnbmFsKTsKICB9CiAgYXN5bmMgZnVuY3Rpb24gcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoewogICAgbGFwaXNGaWx0ZXIsCiAgICBzZXF1ZW5jZVR5cGUsCiAgICBsYXBpcywKICAgIGxhcGlzRGF0ZUZpZWxkLAogICAgZ3JhbnVsYXJpdHksCiAgICBzaWduYWwKICB9KSB7CiAgICBjb25zdCBhbGxEYXRlcyA9IGF3YWl0IGdldERhdGVzSW5EYXRhc2V0KGxhcGlzRmlsdGVyLCBsYXBpcywgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkLCBzaWduYWwpOwogICAgaWYgKGFsbERhdGVzLmxlbmd0aCA+IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TKSB7CiAgICAgIHRocm93IG5ldyBVc2VyRmFjaW5nRXJyb3IoCiAgICAgICAgIlRvbyBtYW55IGRhdGVzIiwKICAgICAgICBgVGhlIGRhdGFzZXQgd291bGQgY29udGFpbiAke2FsbERhdGVzLmxlbmd0aH0gZGF0ZSBpbnRlcnZhbHMuIFBsZWFzZSByZWR1Y2UgdGhlIG51bWJlciB0byBiZWxvdyAke01BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TfSB0byBkaXNwbGF5IHRoZSBkYXRhLiBZb3UgY2FuIGFjaGlldmUgdGhpcyBieSBlaXRoZXIgbmFycm93aW5nIHRoZSBkYXRlIHJhbmdlIGluIHRoZSBwcm92aWRlZCBMQVBJUyBmaWx0ZXIgb3IgYnkgc2VsZWN0aW5nIGEgbGFyZ2VyIGdyYW51bGFyaXR5LmAKICAgICAgKTsKICAgIH0KICAgIGNvbnN0IHN1YlF1ZXJpZXMgPSBhbGxEYXRlcy5tYXAoYXN5bmMgKGRhdGUpID0+IHsKICAgICAgY29uc3QgZGF0ZUZyb20gPSBkYXRlLmZpcnN0RGF5LnRvU3RyaW5nKCk7CiAgICAgIGNvbnN0IGRhdGVUbyA9IGRhdGUubGFzdERheS50b1N0cmluZygpOwogICAgICBjb25zdCBmaWx0ZXIgPSB7CiAgICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfUZyb21gXTogZGF0ZUZyb20sCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfVRvYF06IGRhdGVUbwogICAgICB9OwogICAgICBjb25zdCBkYXRhMiA9IGF3YWl0IGZldGNoQW5kUHJlcGFyZVN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhmaWx0ZXIsIHNlcXVlbmNlVHlwZSkuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IHRvdGFsQ291bnRRdWVyeSA9IGF3YWl0IGdldFRvdGFsTnVtYmVyT2ZTZXF1ZW5jZXNJbkRhdGVSYW5nZShmaWx0ZXIpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICByZXR1cm4gewogICAgICAgIGRhdGUsCiAgICAgICAgbXV0YXRpb25zOiBkYXRhMi5jb250ZW50LAogICAgICAgIHRvdGFsQ291bnQ6IHRvdGFsQ291bnRRdWVyeS5jb250ZW50WzBdLmNvdW50CiAgICAgIH07CiAgICB9KTsKICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChzdWJRdWVyaWVzKTsKICAgIGNvbnN0IG92ZXJhbGxNdXRhdGlvbnNEYXRhID0gKGF3YWl0IHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICAgIGxhcGlzRmlsdGVyLAogICAgICBzZXF1ZW5jZVR5cGUsCiAgICAgIGxhcGlzLAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgZ3JhbnVsYXJpdHkKICAgIH0pKS5jb250ZW50OwogICAgcmV0dXJuIHsKICAgICAgbXV0YXRpb25PdmVyVGltZURhdGE6IGdyb3VwQnlNdXRhdGlvbihkYXRhLCBvdmVyYWxsTXV0YXRpb25zRGF0YSksCiAgICAgIG92ZXJhbGxNdXRhdGlvbkRhdGE6IG92ZXJhbGxNdXRhdGlvbnNEYXRhCiAgICB9OwogIH0KICBhc3luYyBmdW5jdGlvbiBnZXREYXRlc0luRGF0YXNldChsYXBpc0ZpbHRlciwgbGFwaXMsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCwgc2lnbmFsKSB7CiAgICBjb25zdCB7IGNvbnRlbnQ6IGF2YWlsYWJsZURhdGVzIH0gPSBhd2FpdCBxdWVyeUF2YWlsYWJsZURhdGVzKAogICAgICBsYXBpc0ZpbHRlciwKICAgICAgbGFwaXMsCiAgICAgIGdyYW51bGFyaXR5LAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgc2lnbmFsCiAgICApOwogICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvIH0gPSBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpOwogICAgY29uc3QgeyBtaW4sIG1heCB9ID0gZ2V0TWluTWF4VGVtcG9yYWwoYXZhaWxhYmxlRGF0ZXMpOwogICAgcmV0dXJuIGdlbmVyYXRlQWxsSW5SYW5nZShkYXRlRnJvbSA/PyBtaW4sIGRhdGVUbyA/PyBtYXgpOwogIH0KICBmdW5jdGlvbiBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpIHsKICAgIGNvbnN0IHZhbHVlRnJvbUZpbHRlciA9IGxhcGlzRmlsdGVyW2xhcGlzRGF0ZUZpZWxkXTsKICAgIGlmICh2YWx1ZUZyb21GaWx0ZXIpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBkYXRlRnJvbTogcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbCh2YWx1ZUZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSwKICAgICAgICBkYXRlVG86IHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwodmFsdWVGcm9tRmlsdGVyLCBncmFudWxhcml0eSkKICAgICAgfTsKICAgIH0KICAgIGNvbnN0IG1pbkZyb21GaWx0ZXIgPSBsYXBpc0ZpbHRlcltgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF07CiAgICBjb25zdCBtYXhGcm9tRmlsdGVyID0gbGFwaXNGaWx0ZXJbYCR7bGFwaXNEYXRlRmllbGR9VG9gXTsKICAgIHJldHVybiB7CiAgICAgIGRhdGVGcm9tOiBtaW5Gcm9tRmlsdGVyID8gcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbChtaW5Gcm9tRmlsdGVyLCBncmFudWxhcml0eSkgOiBudWxsLAogICAgICBkYXRlVG86IG1heEZyb21GaWx0ZXIgPyBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKG1heEZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSA6IG51bGwKICAgIH07CiAgfQogIGZ1bmN0aW9uIHF1ZXJ5QXZhaWxhYmxlRGF0ZXMobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCkgewogICAgcmV0dXJuIGZldGNoQW5kUHJlcGFyZURhdGVzKGxhcGlzRmlsdGVyLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVEYXRlcyhmaWx0ZXIsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCkgewogICAgY29uc3QgZmV0Y2hEYXRhID0gbmV3IEZldGNoQWdncmVnYXRlZE9wZXJhdG9yKGZpbHRlciwgW2xhcGlzRGF0ZUZpZWxkXSk7CiAgICBjb25zdCBkYXRhV2l0aEZpeGVkRGF0ZUtleSA9IG5ldyBSZW5hbWVGaWVsZE9wZXJhdG9yKGZldGNoRGF0YSwgbGFwaXNEYXRlRmllbGQsICJkYXRlIik7CiAgICBjb25zdCBtYXBEYXRhID0gbmV3IE1hcE9wZXJhdG9yKGRhdGFXaXRoRml4ZWREYXRlS2V5LCAoZGF0YSkgPT4gbWFwRGF0ZVRvR3JhbnVsYXJpdHlSYW5nZShkYXRhLCBncmFudWxhcml0eSkpOwogICAgY29uc3QgZ3JvdXBCeURhdGEgPSBuZXcgR3JvdXBCeUFuZFN1bU9wZXJhdG9yKG1hcERhdGEsICJkYXRlUmFuZ2UiLCAiY291bnQiKTsKICAgIGNvbnN0IHNvcnREYXRhID0gbmV3IFNvcnRPcGVyYXRvcihncm91cEJ5RGF0YSwgZGF0ZVJhbmdlQ29tcGFyZSk7CiAgICByZXR1cm4gbmV3IE1hcE9wZXJhdG9yKHNvcnREYXRhLCAoZGF0YSkgPT4gZGF0YS5kYXRlUmFuZ2UpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVTdWJzdGl0dXRpb25zT3JEZWxldGlvbnMoZmlsdGVyLCBzZXF1ZW5jZVR5cGUpIHsKICAgIHJldHVybiBuZXcgRmV0Y2hTdWJzdGl0dXRpb25zT3JEZWxldGlvbnNPcGVyYXRvcihmaWx0ZXIsIHNlcXVlbmNlVHlwZSwgMWUtMyk7CiAgfQogIGZ1bmN0aW9uIHNlcmlhbGl6ZVN1YnN0aXR1dGlvbk9yRGVsZXRpb24obXV0YXRpb24pIHsKICAgIHJldHVybiBtdXRhdGlvbi5jb2RlOwogIH0KICBmdW5jdGlvbiBzZXJpYWxpemVUZW1wb3JhbChkYXRlKSB7CiAgICByZXR1cm4gZGF0ZS5kYXRlU3RyaW5nOwogIH0KICBmdW5jdGlvbiBncm91cEJ5TXV0YXRpb24oZGF0YSwgb3ZlcmFsbE11dGF0aW9uRGF0YSkgewogICAgY29uc3QgZGF0YUFycmF5ID0gbmV3IEJhc2VNdXRhdGlvbk92ZXJUaW1lRGF0YU1hcCgpOwogICAgY29uc3QgYWxsRGF0ZXMgPSBkYXRhLm1hcCgobXV0YXRpb25EYXRhKSA9PiBtdXRhdGlvbkRhdGEuZGF0ZSk7CiAgICBjb25zdCBzb3J0ZWRPdmVyYWxsTXV0YXRpb25EYXRhID0gb3ZlcmFsbE11dGF0aW9uRGF0YS5zb3J0KChhMiwgYikgPT4gc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMoYTIubXV0YXRpb24sIGIubXV0YXRpb24pKS5tYXAoKGVudHJ5KSA9PiB7CiAgICAgIHJldHVybiB0b1N1YnN0aXR1dGlvbk9yRGVsZXRpb24oZW50cnkubXV0YXRpb24pOwogICAgfSk7CiAgICBjb25zdCBzb3J0ZWREYXRlcyA9IGFsbERhdGVzLnNvcnQoKGEyLCBiKSA9PiBjb21wYXJlVGVtcG9yYWwoYTIsIGIpKS5tYXAoKGRhdGUpID0+IHRvVGVtcG9yYWwoZGF0ZSkpOwogICAgc29ydGVkT3ZlcmFsbE11dGF0aW9uRGF0YS5mb3JFYWNoKChtdXRhdGlvbkRhdGEpID0+IHsKICAgICAgc29ydGVkRGF0ZXMuZm9yRWFjaCgoZGF0ZSkgPT4gewogICAgICAgIGRhdGFBcnJheS5zZXQobXV0YXRpb25EYXRhLCBkYXRlLCBudWxsKTsKICAgICAgfSk7CiAgICB9KTsKICAgIGRhdGEuZm9yRWFjaCgobXV0YXRpb25EYXRhKSA9PiB7CiAgICAgIG11dGF0aW9uRGF0YS5tdXRhdGlvbnMuZm9yRWFjaCgobXV0YXRpb25FbnRyeSkgPT4gewogICAgICAgIGNvbnN0IG11dGF0aW9uID0gdG9TdWJzdGl0dXRpb25PckRlbGV0aW9uKG11dGF0aW9uRW50cnkubXV0YXRpb24pOwogICAgICAgIGNvbnN0IGRhdGUgPSB0b1RlbXBvcmFsKG11dGF0aW9uRGF0YS5kYXRlKTsKICAgICAgICBpZiAoZGF0YUFycmF5LmdldChtdXRhdGlvbiwgZGF0ZSkgIT09IHZvaWQgMCkgewogICAgICAgICAgZGF0YUFycmF5LnNldChtdXRhdGlvbiwgZGF0ZSwgewogICAgICAgICAgICBjb3VudDogbXV0YXRpb25FbnRyeS5jb3VudCwKICAgICAgICAgICAgcHJvcG9ydGlvbjogbXV0YXRpb25FbnRyeS5wcm9wb3J0aW9uLAogICAgICAgICAgICB0b3RhbENvdW50OiBtdXRhdGlvbkRhdGEudG90YWxDb3VudAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwogICAgcmV0dXJuIGRhdGFBcnJheTsKICB9CiAgZnVuY3Rpb24gZ2V0VG90YWxOdW1iZXJPZlNlcXVlbmNlc0luRGF0ZVJhbmdlKGZpbHRlcikgewogICAgcmV0dXJuIG5ldyBGZXRjaEFnZ3JlZ2F0ZWRPcGVyYXRvcihmaWx0ZXIpOwogIH0KICBhc3luYyBmdW5jdGlvbiB3b3JrZXJGdW5jdGlvbihxdWVyeUZ1bmN0aW9uKSB7CiAgICB0cnkgewogICAgICBwb3N0TWVzc2FnZSh7IHN0YXR1czogImxvYWRpbmciIH0pOwogICAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IGF3YWl0IHF1ZXJ5RnVuY3Rpb24oKTsKICAgICAgcG9zdE1lc3NhZ2UoewogICAgICAgIHN0YXR1czogInN1Y2Nlc3MiLAogICAgICAgIGRhdGE6IHdvcmtlclJlc3BvbnNlCiAgICAgIH0pOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgcG9zdE1lc3NhZ2UoCiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBVc2VyRmFjaW5nRXJyb3IgPyB7CiAgICAgICAgICBzdGF0dXM6ICJlcnJvciIsCiAgICAgICAgICB1c2VyRmFjaW5nOiB0cnVlLAogICAgICAgICAgaGVhZGxpbmU6IGVycm9yLmhlYWRsaW5lLAogICAgICAgICAgZXJyb3IKICAgICAgICB9IDogewogICAgICAgICAgc3RhdHVzOiAiZXJyb3IiLAogICAgICAgICAgdXNlckZhY2luZzogZmFsc2UsCiAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKGAke2Vycm9yfWApCiAgICAgICAgfQogICAgICApOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBnZXRNdXRhdGlvbk92ZXJUaW1lV29ya2VyRnVuY3Rpb24oZXZlbnQpIHsKICAgIGNvbnN0IG11dGF0aW9uT3ZlclRpbWVEYXRhID0gYXdhaXQgcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoZXZlbnQuZGF0YSk7CiAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IHsKICAgICAgb3ZlcmFsbE11dGF0aW9uRGF0YTogbXV0YXRpb25PdmVyVGltZURhdGEub3ZlcmFsbE11dGF0aW9uRGF0YSwKICAgICAgbXV0YXRpb25PdmVyVGltZVNlcmlhbGl6ZWQ6IG11dGF0aW9uT3ZlclRpbWVEYXRhLm11dGF0aW9uT3ZlclRpbWVEYXRhLmdldENvbnRlbnRzKCkKICAgIH07CiAgICByZXR1cm4gd29ya2VyUmVzcG9uc2U7CiAgfQogIHNlbGYub25tZXNzYWdlID0gYXN5bmMgZnVuY3Rpb24oZXZlbnQpIHsKICAgIGF3YWl0IHdvcmtlckZ1bmN0aW9uKCgpID0+IGdldE11dGF0aW9uT3ZlclRpbWVXb3JrZXJGdW5jdGlvbihldmVudCkpOwogIH07Cn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPW11dGF0aW9uT3ZlclRpbWVXb3JrZXItQ05nX3p0TnAuanMubWFwCg==";
|
|
8768
|
-
const
|
|
8769
|
-
const blob = typeof self !== "undefined" && self.Blob && new Blob([decodeBase64(encodedJs)], { type: "text/javascript;charset=utf-8" });
|
|
8778
|
+
const jsContent = '(function() {\n "use strict";\n var util;\n (function(util2) {\n util2.assertEqual = (val) => val;\n function assertIs(_arg) {\n }\n util2.assertIs = assertIs;\n function assertNever(_x) {\n throw new Error();\n }\n util2.assertNever = assertNever;\n util2.arrayToEnum = (items) => {\n const obj = {};\n for (const item of items) {\n obj[item] = item;\n }\n return obj;\n };\n util2.getValidEnumValues = (obj) => {\n const validKeys = util2.objectKeys(obj).filter((k2) => typeof obj[obj[k2]] !== "number");\n const filtered = {};\n for (const k2 of validKeys) {\n filtered[k2] = obj[k2];\n }\n return util2.objectValues(filtered);\n };\n util2.objectValues = (obj) => {\n return util2.objectKeys(obj).map(function(e2) {\n return obj[e2];\n });\n };\n util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {\n const keys = [];\n for (const key in object) {\n if (Object.prototype.hasOwnProperty.call(object, key)) {\n keys.push(key);\n }\n }\n return keys;\n };\n util2.find = (arr, checker) => {\n for (const item of arr) {\n if (checker(item))\n return item;\n }\n return void 0;\n };\n util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;\n function joinValues(array, separator = " | ") {\n return array.map((val) => typeof val === "string" ? `\'${val}\'` : val).join(separator);\n }\n util2.joinValues = joinValues;\n util2.jsonStringifyReplacer = (_, value) => {\n if (typeof value === "bigint") {\n return value.toString();\n }\n return value;\n };\n })(util || (util = {}));\n var objectUtil;\n (function(objectUtil2) {\n objectUtil2.mergeShapes = (first, second) => {\n return {\n ...first,\n ...second\n // second overwrites first\n };\n };\n })(objectUtil || (objectUtil = {}));\n const ZodParsedType = util.arrayToEnum([\n "string",\n "nan",\n "number",\n "integer",\n "float",\n "boolean",\n "date",\n "bigint",\n "symbol",\n "function",\n "undefined",\n "null",\n "array",\n "object",\n "unknown",\n "promise",\n "void",\n "never",\n "map",\n "set"\n ]);\n const getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case "undefined":\n return ZodParsedType.undefined;\n case "string":\n return ZodParsedType.string;\n case "number":\n return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;\n case "boolean":\n return ZodParsedType.boolean;\n case "function":\n return ZodParsedType.function;\n case "bigint":\n return ZodParsedType.bigint;\n case "symbol":\n return ZodParsedType.symbol;\n case "object":\n if (Array.isArray(data)) {\n return ZodParsedType.array;\n }\n if (data === null) {\n return ZodParsedType.null;\n }\n if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {\n return ZodParsedType.promise;\n }\n if (typeof Map !== "undefined" && data instanceof Map) {\n return ZodParsedType.map;\n }\n if (typeof Set !== "undefined" && data instanceof Set) {\n return ZodParsedType.set;\n }\n if (typeof Date !== "undefined" && data instanceof Date) {\n return ZodParsedType.date;\n }\n return ZodParsedType.object;\n default:\n return ZodParsedType.unknown;\n }\n };\n const ZodIssueCode = util.arrayToEnum([\n "invalid_type",\n "invalid_literal",\n "custom",\n "invalid_union",\n "invalid_union_discriminator",\n "invalid_enum_value",\n "unrecognized_keys",\n "invalid_arguments",\n "invalid_return_type",\n "invalid_date",\n "invalid_string",\n "too_small",\n "too_big",\n "invalid_intersection_types",\n "not_multiple_of",\n "not_finite"\n ]);\n const quotelessJson = (obj) => {\n const json = JSON.stringify(obj, null, 2);\n return json.replace(/"([^"]+)":/g, "$1:");\n };\n class ZodError extends Error {\n constructor(issues) {\n super();\n this.issues = [];\n this.addIssue = (sub) => {\n this.issues = [...this.issues, sub];\n };\n this.addIssues = (subs = []) => {\n this.issues = [...this.issues, ...subs];\n };\n const actualProto = new.target.prototype;\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(this, actualProto);\n } else {\n this.__proto__ = actualProto;\n }\n this.name = "ZodError";\n this.issues = issues;\n }\n get errors() {\n return this.issues;\n }\n format(_mapper) {\n const mapper = _mapper || function(issue) {\n return issue.message;\n };\n const fieldErrors = { _errors: [] };\n const processError = (error) => {\n for (const issue of error.issues) {\n if (issue.code === "invalid_union") {\n issue.unionErrors.map(processError);\n } else if (issue.code === "invalid_return_type") {\n processError(issue.returnTypeError);\n } else if (issue.code === "invalid_arguments") {\n processError(issue.argumentsError);\n } else if (issue.path.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n } else {\n let curr = fieldErrors;\n let i2 = 0;\n while (i2 < issue.path.length) {\n const el = issue.path[i2];\n const terminal = i2 === issue.path.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n } else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i2++;\n }\n }\n }\n };\n processError(this);\n return fieldErrors;\n }\n static assert(value) {\n if (!(value instanceof ZodError)) {\n throw new Error(`Not a ZodError: ${value}`);\n }\n }\n toString() {\n return this.message;\n }\n get message() {\n return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);\n }\n get isEmpty() {\n return this.issues.length === 0;\n }\n flatten(mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of this.issues) {\n if (sub.path.length > 0) {\n fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];\n fieldErrors[sub.path[0]].push(mapper(sub));\n } else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n }\n get formErrors() {\n return this.flatten();\n }\n }\n ZodError.create = (issues) => {\n const error = new ZodError(issues);\n return error;\n };\n const errorMap = (issue, _ctx) => {\n let message;\n switch (issue.code) {\n case ZodIssueCode.invalid_type:\n if (issue.received === ZodParsedType.undefined) {\n message = "Required";\n } else {\n message = `Expected ${issue.expected}, received ${issue.received}`;\n }\n break;\n case ZodIssueCode.invalid_literal:\n message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;\n break;\n case ZodIssueCode.unrecognized_keys:\n message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;\n break;\n case ZodIssueCode.invalid_union:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_union_discriminator:\n message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;\n break;\n case ZodIssueCode.invalid_enum_value:\n message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received \'${issue.received}\'`;\n break;\n case ZodIssueCode.invalid_arguments:\n message = `Invalid function arguments`;\n break;\n case ZodIssueCode.invalid_return_type:\n message = `Invalid function return type`;\n break;\n case ZodIssueCode.invalid_date:\n message = `Invalid date`;\n break;\n case ZodIssueCode.invalid_string:\n if (typeof issue.validation === "object") {\n if ("includes" in issue.validation) {\n message = `Invalid input: must include "${issue.validation.includes}"`;\n if (typeof issue.validation.position === "number") {\n message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;\n }\n } else if ("startsWith" in issue.validation) {\n message = `Invalid input: must start with "${issue.validation.startsWith}"`;\n } else if ("endsWith" in issue.validation) {\n message = `Invalid input: must end with "${issue.validation.endsWith}"`;\n } else {\n util.assertNever(issue.validation);\n }\n } else if (issue.validation !== "regex") {\n message = `Invalid ${issue.validation}`;\n } else {\n message = "Invalid";\n }\n break;\n case ZodIssueCode.too_small:\n if (issue.type === "array")\n message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;\n else if (issue.type === "string")\n message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;\n else if (issue.type === "number")\n message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;\n else if (issue.type === "date")\n message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;\n else\n message = "Invalid input";\n break;\n case ZodIssueCode.too_big:\n if (issue.type === "array")\n message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;\n else if (issue.type === "string")\n message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;\n else if (issue.type === "number")\n message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === "bigint")\n message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;\n else if (issue.type === "date")\n message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;\n else\n message = "Invalid input";\n break;\n case ZodIssueCode.custom:\n message = `Invalid input`;\n break;\n case ZodIssueCode.invalid_intersection_types:\n message = `Intersection results could not be merged`;\n break;\n case ZodIssueCode.not_multiple_of:\n message = `Number must be a multiple of ${issue.multipleOf}`;\n break;\n case ZodIssueCode.not_finite:\n message = "Number must be finite";\n break;\n default:\n message = _ctx.defaultError;\n util.assertNever(issue);\n }\n return { message };\n };\n let overrideErrorMap = errorMap;\n function setErrorMap(map) {\n overrideErrorMap = map;\n }\n function getErrorMap() {\n return overrideErrorMap;\n }\n const makeIssue = (params) => {\n const { data, path, errorMaps, issueData } = params;\n const fullPath = [...path, ...issueData.path || []];\n const fullIssue = {\n ...issueData,\n path: fullPath\n };\n if (issueData.message !== void 0) {\n return {\n ...issueData,\n path: fullPath,\n message: issueData.message\n };\n }\n let errorMessage = "";\n const maps = errorMaps.filter((m2) => !!m2).slice().reverse();\n for (const map of maps) {\n errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;\n }\n return {\n ...issueData,\n path: fullPath,\n message: errorMessage\n };\n };\n const EMPTY_PATH = [];\n function addIssueToContext(ctx, issueData) {\n const overrideMap = getErrorMap();\n const issue = makeIssue({\n issueData,\n data: ctx.data,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n overrideMap,\n overrideMap === errorMap ? void 0 : errorMap\n // then global default map\n ].filter((x) => !!x)\n });\n ctx.common.issues.push(issue);\n }\n class ParseStatus {\n constructor() {\n this.value = "valid";\n }\n dirty() {\n if (this.value === "valid")\n this.value = "dirty";\n }\n abort() {\n if (this.value !== "aborted")\n this.value = "aborted";\n }\n static mergeArray(status, results) {\n const arrayValue = [];\n for (const s2 of results) {\n if (s2.status === "aborted")\n return INVALID;\n if (s2.status === "dirty")\n status.dirty();\n arrayValue.push(s2.value);\n }\n return { status: status.value, value: arrayValue };\n }\n static async mergeObjectAsync(status, pairs) {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value\n });\n }\n return ParseStatus.mergeObjectSync(status, syncPairs);\n }\n static mergeObjectSync(status, pairs) {\n const finalObject = {};\n for (const pair of pairs) {\n const { key, value } = pair;\n if (key.status === "aborted")\n return INVALID;\n if (value.status === "aborted")\n return INVALID;\n if (key.status === "dirty")\n status.dirty();\n if (value.status === "dirty")\n status.dirty();\n if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {\n finalObject[key.value] = value.value;\n }\n }\n return { status: status.value, value: finalObject };\n }\n }\n const INVALID = Object.freeze({\n status: "aborted"\n });\n const DIRTY = (value) => ({ status: "dirty", value });\n const OK = (value) => ({ status: "valid", value });\n const isAborted = (x) => x.status === "aborted";\n const isDirty = (x) => x.status === "dirty";\n const isValid = (x) => x.status === "valid";\n const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;\n function __classPrivateFieldGet(receiver, state, kind, f2) {\n if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");\n return state.get(receiver);\n }\n function __classPrivateFieldSet(receiver, state, value, kind, f2) {\n if (typeof state === "function" ? receiver !== state || !f2 : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");\n return state.set(receiver, value), value;\n }\n typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {\n var e2 = new Error(message);\n return e2.name = "SuppressedError", e2.error = error, e2.suppressed = suppressed, e2;\n };\n var errorUtil;\n (function(errorUtil2) {\n errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};\n errorUtil2.toString = (message) => typeof message === "string" ? message : message === null || message === void 0 ? void 0 : message.message;\n })(errorUtil || (errorUtil = {}));\n var _ZodEnum_cache, _ZodNativeEnum_cache;\n class ParseInputLazyPath {\n constructor(parent, value, path, key) {\n this._cachedPath = [];\n this.parent = parent;\n this.data = value;\n this._path = path;\n this._key = key;\n }\n get path() {\n if (!this._cachedPath.length) {\n if (this._key instanceof Array) {\n this._cachedPath.push(...this._path, ...this._key);\n } else {\n this._cachedPath.push(...this._path, this._key);\n }\n }\n return this._cachedPath;\n }\n }\n const handleResult = (ctx, result) => {\n if (isValid(result)) {\n return { success: true, data: result.value };\n } else {\n if (!ctx.common.issues.length) {\n throw new Error("Validation failed but no issues detected.");\n }\n return {\n success: false,\n get error() {\n if (this._error)\n return this._error;\n const error = new ZodError(ctx.common.issues);\n this._error = error;\n return this._error;\n }\n };\n }\n };\n function processCreateParams(params) {\n if (!params)\n return {};\n const { errorMap: errorMap2, invalid_type_error, required_error, description } = params;\n if (errorMap2 && (invalid_type_error || required_error)) {\n throw new Error(`Can\'t use "invalid_type_error" or "required_error" in conjunction with custom error map.`);\n }\n if (errorMap2)\n return { errorMap: errorMap2, description };\n const customMap = (iss, ctx) => {\n var _a, _b;\n const { message } = params;\n if (iss.code === "invalid_enum_value") {\n return { message: message !== null && message !== void 0 ? message : ctx.defaultError };\n }\n if (typeof ctx.data === "undefined") {\n return { message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError };\n }\n if (iss.code !== "invalid_type")\n return { message: ctx.defaultError };\n return { message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError };\n };\n return { errorMap: customMap, description };\n }\n class ZodType {\n constructor(def) {\n this.spa = this.safeParseAsync;\n this._def = def;\n this.parse = this.parse.bind(this);\n this.safeParse = this.safeParse.bind(this);\n this.parseAsync = this.parseAsync.bind(this);\n this.safeParseAsync = this.safeParseAsync.bind(this);\n this.spa = this.spa.bind(this);\n this.refine = this.refine.bind(this);\n this.refinement = this.refinement.bind(this);\n this.superRefine = this.superRefine.bind(this);\n this.optional = this.optional.bind(this);\n this.nullable = this.nullable.bind(this);\n this.nullish = this.nullish.bind(this);\n this.array = this.array.bind(this);\n this.promise = this.promise.bind(this);\n this.or = this.or.bind(this);\n this.and = this.and.bind(this);\n this.transform = this.transform.bind(this);\n this.brand = this.brand.bind(this);\n this.default = this.default.bind(this);\n this.catch = this.catch.bind(this);\n this.describe = this.describe.bind(this);\n this.pipe = this.pipe.bind(this);\n this.readonly = this.readonly.bind(this);\n this.isNullable = this.isNullable.bind(this);\n this.isOptional = this.isOptional.bind(this);\n this["~standard"] = {\n version: 1,\n vendor: "zod",\n validate: (data) => this["~validate"](data)\n };\n }\n get description() {\n return this._def.description;\n }\n _getType(input) {\n return getParsedType(input.data);\n }\n _getOrReturnCtx(input, ctx) {\n return ctx || {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent\n };\n }\n _processInputParams(input) {\n return {\n status: new ParseStatus(),\n ctx: {\n common: input.parent.common,\n data: input.data,\n parsedType: getParsedType(input.data),\n schemaErrorMap: this._def.errorMap,\n path: input.path,\n parent: input.parent\n }\n };\n }\n _parseSync(input) {\n const result = this._parse(input);\n if (isAsync(result)) {\n throw new Error("Synchronous parse encountered promise.");\n }\n return result;\n }\n _parseAsync(input) {\n const result = this._parse(input);\n return Promise.resolve(result);\n }\n parse(data, params) {\n const result = this.safeParse(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n safeParse(data, params) {\n var _a;\n const ctx = {\n common: {\n issues: [],\n async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data)\n };\n const result = this._parseSync({ data, path: ctx.path, parent: ctx });\n return handleResult(ctx, result);\n }\n "~validate"(data) {\n var _a, _b, _c;\n const ctx = {\n common: {\n issues: [],\n async: !!this["~standard"].async\n },\n path: [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data)\n };\n if (!this["~standard"].async) {\n try {\n const result = this._parseSync({ data, path: [], parent: ctx });\n return isValid(result) ? {\n value: result.value\n } : {\n issues: ctx.common.issues\n };\n } catch (err) {\n if ((_c = (_b = (_a = err) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === null || _c === void 0 ? void 0 : _c.includes("encountered")) {\n this["~standard"].async = true;\n }\n ctx.common = {\n issues: [],\n async: true\n };\n }\n }\n return this._parseAsync({ data, path: [], parent: ctx }).then((result) => isValid(result) ? {\n value: result.value\n } : {\n issues: ctx.common.issues\n });\n }\n async parseAsync(data, params) {\n const result = await this.safeParseAsync(data, params);\n if (result.success)\n return result.data;\n throw result.error;\n }\n async safeParseAsync(data, params) {\n const ctx = {\n common: {\n issues: [],\n contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,\n async: true\n },\n path: (params === null || params === void 0 ? void 0 : params.path) || [],\n schemaErrorMap: this._def.errorMap,\n parent: null,\n data,\n parsedType: getParsedType(data)\n };\n const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });\n const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));\n return handleResult(ctx, result);\n }\n refine(check, message) {\n const getIssueProperties = (val) => {\n if (typeof message === "string" || typeof message === "undefined") {\n return { message };\n } else if (typeof message === "function") {\n return message(val);\n } else {\n return message;\n }\n };\n return this._refinement((val, ctx) => {\n const result = check(val);\n const setError = () => ctx.addIssue({\n code: ZodIssueCode.custom,\n ...getIssueProperties(val)\n });\n if (typeof Promise !== "undefined" && result instanceof Promise) {\n return result.then((data) => {\n if (!data) {\n setError();\n return false;\n } else {\n return true;\n }\n });\n }\n if (!result) {\n setError();\n return false;\n } else {\n return true;\n }\n });\n }\n refinement(check, refinementData) {\n return this._refinement((val, ctx) => {\n if (!check(val)) {\n ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);\n return false;\n } else {\n return true;\n }\n });\n }\n _refinement(refinement) {\n return new ZodEffects({\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: "refinement", refinement }\n });\n }\n superRefine(refinement) {\n return this._refinement(refinement);\n }\n optional() {\n return ZodOptional.create(this, this._def);\n }\n nullable() {\n return ZodNullable.create(this, this._def);\n }\n nullish() {\n return this.nullable().optional();\n }\n array() {\n return ZodArray.create(this);\n }\n promise() {\n return ZodPromise.create(this, this._def);\n }\n or(option) {\n return ZodUnion.create([this, option], this._def);\n }\n and(incoming) {\n return ZodIntersection.create(this, incoming, this._def);\n }\n transform(transform) {\n return new ZodEffects({\n ...processCreateParams(this._def),\n schema: this,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect: { type: "transform", transform }\n });\n }\n default(def) {\n const defaultValueFunc = typeof def === "function" ? def : () => def;\n return new ZodDefault({\n ...processCreateParams(this._def),\n innerType: this,\n defaultValue: defaultValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodDefault\n });\n }\n brand() {\n return new ZodBranded({\n typeName: ZodFirstPartyTypeKind.ZodBranded,\n type: this,\n ...processCreateParams(this._def)\n });\n }\n catch(def) {\n const catchValueFunc = typeof def === "function" ? def : () => def;\n return new ZodCatch({\n ...processCreateParams(this._def),\n innerType: this,\n catchValue: catchValueFunc,\n typeName: ZodFirstPartyTypeKind.ZodCatch\n });\n }\n describe(description) {\n const This = this.constructor;\n return new This({\n ...this._def,\n description\n });\n }\n pipe(target) {\n return ZodPipeline.create(this, target);\n }\n readonly() {\n return ZodReadonly.create(this);\n }\n isOptional() {\n return this.safeParse(void 0).success;\n }\n isNullable() {\n return this.safeParse(null).success;\n }\n }\n const cuidRegex = /^c[^\\s-]{8,}$/i;\n const cuid2Regex = /^[0-9a-z]+$/;\n const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;\n const uuidRegex = /^[0-9a-fA-F]{8}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{4}\\b-[0-9a-fA-F]{12}$/i;\n const nanoidRegex = /^[a-z0-9_-]{21}$/i;\n const jwtRegex = /^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$/;\n const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/;\n const emailRegex = /^(?!\\.)(?!.*\\.\\.)([A-Z0-9_\'+\\-\\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\\-]*\\.)+[A-Z]{2,}$/i;\n const _emojiRegex = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\n let emojiRegex;\n const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;\n const ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/(3[0-2]|[12]?[0-9])$/;\n const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;\n const ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;\n const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;\n const base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;\n const dateRegexSource = `((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))`;\n const dateRegex = new RegExp(`^${dateRegexSource}$`);\n function timeRegexSource(args) {\n let regex = `([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d`;\n if (args.precision) {\n regex = `${regex}\\\\.\\\\d{${args.precision}}`;\n } else if (args.precision == null) {\n regex = `${regex}(\\\\.\\\\d+)?`;\n }\n return regex;\n }\n function timeRegex(args) {\n return new RegExp(`^${timeRegexSource(args)}$`);\n }\n function datetimeRegex(args) {\n let regex = `${dateRegexSource}T${timeRegexSource(args)}`;\n const opts = [];\n opts.push(args.local ? `Z?` : `Z`);\n if (args.offset)\n opts.push(`([+-]\\\\d{2}:?\\\\d{2})`);\n regex = `${regex}(${opts.join("|")})`;\n return new RegExp(`^${regex}$`);\n }\n function isValidIP(ip, version) {\n if ((version === "v4" || !version) && ipv4Regex.test(ip)) {\n return true;\n }\n if ((version === "v6" || !version) && ipv6Regex.test(ip)) {\n return true;\n }\n return false;\n }\n function isValidJWT(jwt, alg) {\n if (!jwtRegex.test(jwt))\n return false;\n try {\n const [header] = jwt.split(".");\n const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");\n const decoded = JSON.parse(atob(base64));\n if (typeof decoded !== "object" || decoded === null)\n return false;\n if (!decoded.typ || !decoded.alg)\n return false;\n if (alg && decoded.alg !== alg)\n return false;\n return true;\n } catch (_a) {\n return false;\n }\n }\n function isValidCidr(ip, version) {\n if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {\n return true;\n }\n if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {\n return true;\n }\n return false;\n }\n class ZodString extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = String(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.string) {\n const ctx2 = this._getOrReturnCtx(input);\n addIssueToContext(ctx2, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.string,\n received: ctx2.parsedType\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = void 0;\n for (const check of this._def.checks) {\n if (check.kind === "min") {\n if (input.data.length < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: "string",\n inclusive: true,\n exact: false,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "max") {\n if (input.data.length > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: "string",\n inclusive: true,\n exact: false,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "length") {\n const tooBig = input.data.length > check.value;\n const tooSmall = input.data.length < check.value;\n if (tooBig || tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n if (tooBig) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: "string",\n inclusive: true,\n exact: true,\n message: check.message\n });\n } else if (tooSmall) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: "string",\n inclusive: true,\n exact: true,\n message: check.message\n });\n }\n status.dirty();\n }\n } else if (check.kind === "email") {\n if (!emailRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "email",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "emoji") {\n if (!emojiRegex) {\n emojiRegex = new RegExp(_emojiRegex, "u");\n }\n if (!emojiRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "emoji",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "uuid") {\n if (!uuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "uuid",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "nanoid") {\n if (!nanoidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "nanoid",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "cuid") {\n if (!cuidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "cuid",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "cuid2") {\n if (!cuid2Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "cuid2",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "ulid") {\n if (!ulidRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "ulid",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "url") {\n try {\n new URL(input.data);\n } catch (_a) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "url",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "regex") {\n check.regex.lastIndex = 0;\n const testResult = check.regex.test(input.data);\n if (!testResult) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "regex",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "trim") {\n input.data = input.data.trim();\n } else if (check.kind === "includes") {\n if (!input.data.includes(check.value, check.position)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { includes: check.value, position: check.position },\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "toLowerCase") {\n input.data = input.data.toLowerCase();\n } else if (check.kind === "toUpperCase") {\n input.data = input.data.toUpperCase();\n } else if (check.kind === "startsWith") {\n if (!input.data.startsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { startsWith: check.value },\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "endsWith") {\n if (!input.data.endsWith(check.value)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: { endsWith: check.value },\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "datetime") {\n const regex = datetimeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: "datetime",\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "date") {\n const regex = dateRegex;\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: "date",\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "time") {\n const regex = timeRegex(check);\n if (!regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_string,\n validation: "time",\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "duration") {\n if (!durationRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "duration",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "ip") {\n if (!isValidIP(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "ip",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "jwt") {\n if (!isValidJWT(input.data, check.alg)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "jwt",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "cidr") {\n if (!isValidCidr(input.data, check.version)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "cidr",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "base64") {\n if (!base64Regex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "base64",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "base64url") {\n if (!base64urlRegex.test(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n validation: "base64url",\n code: ZodIssueCode.invalid_string,\n message: check.message\n });\n status.dirty();\n }\n } else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _regex(regex, validation, message) {\n return this.refinement((data) => regex.test(data), {\n validation,\n code: ZodIssueCode.invalid_string,\n ...errorUtil.errToObj(message)\n });\n }\n _addCheck(check) {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, check]\n });\n }\n email(message) {\n return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });\n }\n url(message) {\n return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });\n }\n emoji(message) {\n return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });\n }\n uuid(message) {\n return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });\n }\n nanoid(message) {\n return this._addCheck({ kind: "nanoid", ...errorUtil.errToObj(message) });\n }\n cuid(message) {\n return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });\n }\n cuid2(message) {\n return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });\n }\n ulid(message) {\n return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });\n }\n base64(message) {\n return this._addCheck({ kind: "base64", ...errorUtil.errToObj(message) });\n }\n base64url(message) {\n return this._addCheck({ kind: "base64url", ...errorUtil.errToObj(message) });\n }\n jwt(options) {\n return this._addCheck({ kind: "jwt", ...errorUtil.errToObj(options) });\n }\n ip(options) {\n return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });\n }\n cidr(options) {\n return this._addCheck({ kind: "cidr", ...errorUtil.errToObj(options) });\n }\n datetime(options) {\n var _a, _b;\n if (typeof options === "string") {\n return this._addCheck({\n kind: "datetime",\n precision: null,\n offset: false,\n local: false,\n message: options\n });\n }\n return this._addCheck({\n kind: "datetime",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision,\n offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,\n local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message)\n });\n }\n date(message) {\n return this._addCheck({ kind: "date", message });\n }\n time(options) {\n if (typeof options === "string") {\n return this._addCheck({\n kind: "time",\n precision: null,\n message: options\n });\n }\n return this._addCheck({\n kind: "time",\n precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message)\n });\n }\n duration(message) {\n return this._addCheck({ kind: "duration", ...errorUtil.errToObj(message) });\n }\n regex(regex, message) {\n return this._addCheck({\n kind: "regex",\n regex,\n ...errorUtil.errToObj(message)\n });\n }\n includes(value, options) {\n return this._addCheck({\n kind: "includes",\n value,\n position: options === null || options === void 0 ? void 0 : options.position,\n ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message)\n });\n }\n startsWith(value, message) {\n return this._addCheck({\n kind: "startsWith",\n value,\n ...errorUtil.errToObj(message)\n });\n }\n endsWith(value, message) {\n return this._addCheck({\n kind: "endsWith",\n value,\n ...errorUtil.errToObj(message)\n });\n }\n min(minLength, message) {\n return this._addCheck({\n kind: "min",\n value: minLength,\n ...errorUtil.errToObj(message)\n });\n }\n max(maxLength, message) {\n return this._addCheck({\n kind: "max",\n value: maxLength,\n ...errorUtil.errToObj(message)\n });\n }\n length(len, message) {\n return this._addCheck({\n kind: "length",\n value: len,\n ...errorUtil.errToObj(message)\n });\n }\n /**\n * @deprecated Use z.string().min(1) instead.\n * @see {@link ZodString.min}\n */\n nonempty(message) {\n return this.min(1, errorUtil.errToObj(message));\n }\n trim() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: "trim" }]\n });\n }\n toLowerCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: "toLowerCase" }]\n });\n }\n toUpperCase() {\n return new ZodString({\n ...this._def,\n checks: [...this._def.checks, { kind: "toUpperCase" }]\n });\n }\n get isDatetime() {\n return !!this._def.checks.find((ch) => ch.kind === "datetime");\n }\n get isDate() {\n return !!this._def.checks.find((ch) => ch.kind === "date");\n }\n get isTime() {\n return !!this._def.checks.find((ch) => ch.kind === "time");\n }\n get isDuration() {\n return !!this._def.checks.find((ch) => ch.kind === "duration");\n }\n get isEmail() {\n return !!this._def.checks.find((ch) => ch.kind === "email");\n }\n get isURL() {\n return !!this._def.checks.find((ch) => ch.kind === "url");\n }\n get isEmoji() {\n return !!this._def.checks.find((ch) => ch.kind === "emoji");\n }\n get isUUID() {\n return !!this._def.checks.find((ch) => ch.kind === "uuid");\n }\n get isNANOID() {\n return !!this._def.checks.find((ch) => ch.kind === "nanoid");\n }\n get isCUID() {\n return !!this._def.checks.find((ch) => ch.kind === "cuid");\n }\n get isCUID2() {\n return !!this._def.checks.find((ch) => ch.kind === "cuid2");\n }\n get isULID() {\n return !!this._def.checks.find((ch) => ch.kind === "ulid");\n }\n get isIP() {\n return !!this._def.checks.find((ch) => ch.kind === "ip");\n }\n get isCIDR() {\n return !!this._def.checks.find((ch) => ch.kind === "cidr");\n }\n get isBase64() {\n return !!this._def.checks.find((ch) => ch.kind === "base64");\n }\n get isBase64url() {\n return !!this._def.checks.find((ch) => ch.kind === "base64url");\n }\n get minLength() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "min") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxLength() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "max") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n }\n ZodString.create = (params) => {\n var _a;\n return new ZodString({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodString,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params)\n });\n };\n function floatSafeRemainder(val, step) {\n const valDecCount = (val.toString().split(".")[1] || "").length;\n const stepDecCount = (step.toString().split(".")[1] || "").length;\n const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;\n const valInt = parseInt(val.toFixed(decCount).replace(".", ""));\n const stepInt = parseInt(step.toFixed(decCount).replace(".", ""));\n return valInt % stepInt / Math.pow(10, decCount);\n }\n class ZodNumber extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n this.step = this.multipleOf;\n }\n _parse(input) {\n if (this._def.coerce) {\n input.data = Number(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.number) {\n const ctx2 = this._getOrReturnCtx(input);\n addIssueToContext(ctx2, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.number,\n received: ctx2.parsedType\n });\n return INVALID;\n }\n let ctx = void 0;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === "int") {\n if (!util.isInteger(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: "integer",\n received: "float",\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "min") {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: check.value,\n type: "number",\n inclusive: check.inclusive,\n exact: false,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "max") {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: check.value,\n type: "number",\n inclusive: check.inclusive,\n exact: false,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "multipleOf") {\n if (floatSafeRemainder(input.data, check.value) !== 0) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "finite") {\n if (!Number.isFinite(input.data)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_finite,\n message: check.message\n });\n status.dirty();\n }\n } else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n gte(value, message) {\n return this.setLimit("min", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit("min", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit("max", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit("max", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodNumber({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message)\n }\n ]\n });\n }\n _addCheck(check) {\n return new ZodNumber({\n ...this._def,\n checks: [...this._def.checks, check]\n });\n }\n int(message) {\n return this._addCheck({\n kind: "int",\n message: errorUtil.toString(message)\n });\n }\n positive(message) {\n return this._addCheck({\n kind: "min",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message)\n });\n }\n negative(message) {\n return this._addCheck({\n kind: "max",\n value: 0,\n inclusive: false,\n message: errorUtil.toString(message)\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: "max",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message)\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: "min",\n value: 0,\n inclusive: true,\n message: errorUtil.toString(message)\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: "multipleOf",\n value,\n message: errorUtil.toString(message)\n });\n }\n finite(message) {\n return this._addCheck({\n kind: "finite",\n message: errorUtil.toString(message)\n });\n }\n safe(message) {\n return this._addCheck({\n kind: "min",\n inclusive: true,\n value: Number.MIN_SAFE_INTEGER,\n message: errorUtil.toString(message)\n })._addCheck({\n kind: "max",\n inclusive: true,\n value: Number.MAX_SAFE_INTEGER,\n message: errorUtil.toString(message)\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "min") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "max") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n get isInt() {\n return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util.isInteger(ch.value));\n }\n get isFinite() {\n let max = null, min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {\n return true;\n } else if (ch.kind === "min") {\n if (min === null || ch.value > min)\n min = ch.value;\n } else if (ch.kind === "max") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return Number.isFinite(min) && Number.isFinite(max);\n }\n }\n ZodNumber.create = (params) => {\n return new ZodNumber({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodNumber,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params)\n });\n };\n class ZodBigInt extends ZodType {\n constructor() {\n super(...arguments);\n this.min = this.gte;\n this.max = this.lte;\n }\n _parse(input) {\n if (this._def.coerce) {\n try {\n input.data = BigInt(input.data);\n } catch (_a) {\n return this._getInvalidInput(input);\n }\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.bigint) {\n return this._getInvalidInput(input);\n }\n let ctx = void 0;\n const status = new ParseStatus();\n for (const check of this._def.checks) {\n if (check.kind === "min") {\n const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;\n if (tooSmall) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n type: "bigint",\n minimum: check.value,\n inclusive: check.inclusive,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "max") {\n const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;\n if (tooBig) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n type: "bigint",\n maximum: check.value,\n inclusive: check.inclusive,\n message: check.message\n });\n status.dirty();\n }\n } else if (check.kind === "multipleOf") {\n if (input.data % check.value !== BigInt(0)) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.not_multiple_of,\n multipleOf: check.value,\n message: check.message\n });\n status.dirty();\n }\n } else {\n util.assertNever(check);\n }\n }\n return { status: status.value, value: input.data };\n }\n _getInvalidInput(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.bigint,\n received: ctx.parsedType\n });\n return INVALID;\n }\n gte(value, message) {\n return this.setLimit("min", value, true, errorUtil.toString(message));\n }\n gt(value, message) {\n return this.setLimit("min", value, false, errorUtil.toString(message));\n }\n lte(value, message) {\n return this.setLimit("max", value, true, errorUtil.toString(message));\n }\n lt(value, message) {\n return this.setLimit("max", value, false, errorUtil.toString(message));\n }\n setLimit(kind, value, inclusive, message) {\n return new ZodBigInt({\n ...this._def,\n checks: [\n ...this._def.checks,\n {\n kind,\n value,\n inclusive,\n message: errorUtil.toString(message)\n }\n ]\n });\n }\n _addCheck(check) {\n return new ZodBigInt({\n ...this._def,\n checks: [...this._def.checks, check]\n });\n }\n positive(message) {\n return this._addCheck({\n kind: "min",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message)\n });\n }\n negative(message) {\n return this._addCheck({\n kind: "max",\n value: BigInt(0),\n inclusive: false,\n message: errorUtil.toString(message)\n });\n }\n nonpositive(message) {\n return this._addCheck({\n kind: "max",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message)\n });\n }\n nonnegative(message) {\n return this._addCheck({\n kind: "min",\n value: BigInt(0),\n inclusive: true,\n message: errorUtil.toString(message)\n });\n }\n multipleOf(value, message) {\n return this._addCheck({\n kind: "multipleOf",\n value,\n message: errorUtil.toString(message)\n });\n }\n get minValue() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "min") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min;\n }\n get maxValue() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "max") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max;\n }\n }\n ZodBigInt.create = (params) => {\n var _a;\n return new ZodBigInt({\n checks: [],\n typeName: ZodFirstPartyTypeKind.ZodBigInt,\n coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,\n ...processCreateParams(params)\n });\n };\n class ZodBoolean extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = Boolean(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.boolean) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.boolean,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return OK(input.data);\n }\n }\n ZodBoolean.create = (params) => {\n return new ZodBoolean({\n typeName: ZodFirstPartyTypeKind.ZodBoolean,\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n ...processCreateParams(params)\n });\n };\n class ZodDate extends ZodType {\n _parse(input) {\n if (this._def.coerce) {\n input.data = new Date(input.data);\n }\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.date) {\n const ctx2 = this._getOrReturnCtx(input);\n addIssueToContext(ctx2, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.date,\n received: ctx2.parsedType\n });\n return INVALID;\n }\n if (isNaN(input.data.getTime())) {\n const ctx2 = this._getOrReturnCtx(input);\n addIssueToContext(ctx2, {\n code: ZodIssueCode.invalid_date\n });\n return INVALID;\n }\n const status = new ParseStatus();\n let ctx = void 0;\n for (const check of this._def.checks) {\n if (check.kind === "min") {\n if (input.data.getTime() < check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n message: check.message,\n inclusive: true,\n exact: false,\n minimum: check.value,\n type: "date"\n });\n status.dirty();\n }\n } else if (check.kind === "max") {\n if (input.data.getTime() > check.value) {\n ctx = this._getOrReturnCtx(input, ctx);\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n message: check.message,\n inclusive: true,\n exact: false,\n maximum: check.value,\n type: "date"\n });\n status.dirty();\n }\n } else {\n util.assertNever(check);\n }\n }\n return {\n status: status.value,\n value: new Date(input.data.getTime())\n };\n }\n _addCheck(check) {\n return new ZodDate({\n ...this._def,\n checks: [...this._def.checks, check]\n });\n }\n min(minDate, message) {\n return this._addCheck({\n kind: "min",\n value: minDate.getTime(),\n message: errorUtil.toString(message)\n });\n }\n max(maxDate, message) {\n return this._addCheck({\n kind: "max",\n value: maxDate.getTime(),\n message: errorUtil.toString(message)\n });\n }\n get minDate() {\n let min = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "min") {\n if (min === null || ch.value > min)\n min = ch.value;\n }\n }\n return min != null ? new Date(min) : null;\n }\n get maxDate() {\n let max = null;\n for (const ch of this._def.checks) {\n if (ch.kind === "max") {\n if (max === null || ch.value < max)\n max = ch.value;\n }\n }\n return max != null ? new Date(max) : null;\n }\n }\n ZodDate.create = (params) => {\n return new ZodDate({\n checks: [],\n coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,\n typeName: ZodFirstPartyTypeKind.ZodDate,\n ...processCreateParams(params)\n });\n };\n class ZodSymbol extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.symbol) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.symbol,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return OK(input.data);\n }\n }\n ZodSymbol.create = (params) => {\n return new ZodSymbol({\n typeName: ZodFirstPartyTypeKind.ZodSymbol,\n ...processCreateParams(params)\n });\n };\n class ZodUndefined extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.undefined,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return OK(input.data);\n }\n }\n ZodUndefined.create = (params) => {\n return new ZodUndefined({\n typeName: ZodFirstPartyTypeKind.ZodUndefined,\n ...processCreateParams(params)\n });\n };\n class ZodNull extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.null) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.null,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return OK(input.data);\n }\n }\n ZodNull.create = (params) => {\n return new ZodNull({\n typeName: ZodFirstPartyTypeKind.ZodNull,\n ...processCreateParams(params)\n });\n };\n class ZodAny extends ZodType {\n constructor() {\n super(...arguments);\n this._any = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n }\n ZodAny.create = (params) => {\n return new ZodAny({\n typeName: ZodFirstPartyTypeKind.ZodAny,\n ...processCreateParams(params)\n });\n };\n class ZodUnknown extends ZodType {\n constructor() {\n super(...arguments);\n this._unknown = true;\n }\n _parse(input) {\n return OK(input.data);\n }\n }\n ZodUnknown.create = (params) => {\n return new ZodUnknown({\n typeName: ZodFirstPartyTypeKind.ZodUnknown,\n ...processCreateParams(params)\n });\n };\n class ZodNever extends ZodType {\n _parse(input) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.never,\n received: ctx.parsedType\n });\n return INVALID;\n }\n }\n ZodNever.create = (params) => {\n return new ZodNever({\n typeName: ZodFirstPartyTypeKind.ZodNever,\n ...processCreateParams(params)\n });\n };\n class ZodVoid extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.undefined) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.void,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return OK(input.data);\n }\n }\n ZodVoid.create = (params) => {\n return new ZodVoid({\n typeName: ZodFirstPartyTypeKind.ZodVoid,\n ...processCreateParams(params)\n });\n };\n class ZodArray extends ZodType {\n _parse(input) {\n const { ctx, status } = this._processInputParams(input);\n const def = this._def;\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType\n });\n return INVALID;\n }\n if (def.exactLength !== null) {\n const tooBig = ctx.data.length > def.exactLength.value;\n const tooSmall = ctx.data.length < def.exactLength.value;\n if (tooBig || tooSmall) {\n addIssueToContext(ctx, {\n code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,\n minimum: tooSmall ? def.exactLength.value : void 0,\n maximum: tooBig ? def.exactLength.value : void 0,\n type: "array",\n inclusive: true,\n exact: true,\n message: def.exactLength.message\n });\n status.dirty();\n }\n }\n if (def.minLength !== null) {\n if (ctx.data.length < def.minLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minLength.value,\n type: "array",\n inclusive: true,\n exact: false,\n message: def.minLength.message\n });\n status.dirty();\n }\n }\n if (def.maxLength !== null) {\n if (ctx.data.length > def.maxLength.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxLength.value,\n type: "array",\n inclusive: true,\n exact: false,\n message: def.maxLength.message\n });\n status.dirty();\n }\n }\n if (ctx.common.async) {\n return Promise.all([...ctx.data].map((item, i2) => {\n return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i2));\n })).then((result2) => {\n return ParseStatus.mergeArray(status, result2);\n });\n }\n const result = [...ctx.data].map((item, i2) => {\n return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i2));\n });\n return ParseStatus.mergeArray(status, result);\n }\n get element() {\n return this._def.type;\n }\n min(minLength, message) {\n return new ZodArray({\n ...this._def,\n minLength: { value: minLength, message: errorUtil.toString(message) }\n });\n }\n max(maxLength, message) {\n return new ZodArray({\n ...this._def,\n maxLength: { value: maxLength, message: errorUtil.toString(message) }\n });\n }\n length(len, message) {\n return new ZodArray({\n ...this._def,\n exactLength: { value: len, message: errorUtil.toString(message) }\n });\n }\n nonempty(message) {\n return this.min(1, message);\n }\n }\n ZodArray.create = (schema, params) => {\n return new ZodArray({\n type: schema,\n minLength: null,\n maxLength: null,\n exactLength: null,\n typeName: ZodFirstPartyTypeKind.ZodArray,\n ...processCreateParams(params)\n });\n };\n function deepPartialify(schema) {\n if (schema instanceof ZodObject) {\n const newShape = {};\n for (const key in schema.shape) {\n const fieldSchema = schema.shape[key];\n newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));\n }\n return new ZodObject({\n ...schema._def,\n shape: () => newShape\n });\n } else if (schema instanceof ZodArray) {\n return new ZodArray({\n ...schema._def,\n type: deepPartialify(schema.element)\n });\n } else if (schema instanceof ZodOptional) {\n return ZodOptional.create(deepPartialify(schema.unwrap()));\n } else if (schema instanceof ZodNullable) {\n return ZodNullable.create(deepPartialify(schema.unwrap()));\n } else if (schema instanceof ZodTuple) {\n return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));\n } else {\n return schema;\n }\n }\n class ZodObject extends ZodType {\n constructor() {\n super(...arguments);\n this._cached = null;\n this.nonstrict = this.passthrough;\n this.augment = this.extend;\n }\n _getCached() {\n if (this._cached !== null)\n return this._cached;\n const shape = this._def.shape();\n const keys = util.objectKeys(shape);\n return this._cached = { shape, keys };\n }\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.object) {\n const ctx2 = this._getOrReturnCtx(input);\n addIssueToContext(ctx2, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx2.parsedType\n });\n return INVALID;\n }\n const { status, ctx } = this._processInputParams(input);\n const { shape, keys: shapeKeys } = this._getCached();\n const extraKeys = [];\n if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {\n for (const key in ctx.data) {\n if (!shapeKeys.includes(key)) {\n extraKeys.push(key);\n }\n }\n }\n const pairs = [];\n for (const key of shapeKeys) {\n const keyValidator = shape[key];\n const value = ctx.data[key];\n pairs.push({\n key: { status: "valid", value: key },\n value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),\n alwaysSet: key in ctx.data\n });\n }\n if (this._def.catchall instanceof ZodNever) {\n const unknownKeys = this._def.unknownKeys;\n if (unknownKeys === "passthrough") {\n for (const key of extraKeys) {\n pairs.push({\n key: { status: "valid", value: key },\n value: { status: "valid", value: ctx.data[key] }\n });\n }\n } else if (unknownKeys === "strict") {\n if (extraKeys.length > 0) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.unrecognized_keys,\n keys: extraKeys\n });\n status.dirty();\n }\n } else if (unknownKeys === "strip") ;\n else {\n throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);\n }\n } else {\n const catchall = this._def.catchall;\n for (const key of extraKeys) {\n const value = ctx.data[key];\n pairs.push({\n key: { status: "valid", value: key },\n value: catchall._parse(\n new ParseInputLazyPath(ctx, value, ctx.path, key)\n //, ctx.child(key), value, getParsedType(value)\n ),\n alwaysSet: key in ctx.data\n });\n }\n }\n if (ctx.common.async) {\n return Promise.resolve().then(async () => {\n const syncPairs = [];\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n syncPairs.push({\n key,\n value,\n alwaysSet: pair.alwaysSet\n });\n }\n return syncPairs;\n }).then((syncPairs) => {\n return ParseStatus.mergeObjectSync(status, syncPairs);\n });\n } else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get shape() {\n return this._def.shape();\n }\n strict(message) {\n errorUtil.errToObj;\n return new ZodObject({\n ...this._def,\n unknownKeys: "strict",\n ...message !== void 0 ? {\n errorMap: (issue, ctx) => {\n var _a, _b, _c, _d;\n const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;\n if (issue.code === "unrecognized_keys")\n return {\n message: (_d = errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError\n };\n return {\n message: defaultError\n };\n }\n } : {}\n });\n }\n strip() {\n return new ZodObject({\n ...this._def,\n unknownKeys: "strip"\n });\n }\n passthrough() {\n return new ZodObject({\n ...this._def,\n unknownKeys: "passthrough"\n });\n }\n // const AugmentFactory =\n // <Def extends ZodObjectDef>(def: Def) =>\n // <Augmentation extends ZodRawShape>(\n // augmentation: Augmentation\n // ): ZodObject<\n // extendShape<ReturnType<Def["shape"]>, Augmentation>,\n // Def["unknownKeys"],\n // Def["catchall"]\n // > => {\n // return new ZodObject({\n // ...def,\n // shape: () => ({\n // ...def.shape(),\n // ...augmentation,\n // }),\n // }) as any;\n // };\n extend(augmentation) {\n return new ZodObject({\n ...this._def,\n shape: () => ({\n ...this._def.shape(),\n ...augmentation\n })\n });\n }\n /**\n * Prior to zod@1.0.12 there was a bug in the\n * inferred type of merged objects. Please\n * upgrade if you are experiencing issues.\n */\n merge(merging) {\n const merged = new ZodObject({\n unknownKeys: merging._def.unknownKeys,\n catchall: merging._def.catchall,\n shape: () => ({\n ...this._def.shape(),\n ...merging._def.shape()\n }),\n typeName: ZodFirstPartyTypeKind.ZodObject\n });\n return merged;\n }\n // merge<\n // Incoming extends AnyZodObject,\n // Augmentation extends Incoming["shape"],\n // NewOutput extends {\n // [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation\n // ? Augmentation[k]["_output"]\n // : k extends keyof Output\n // ? Output[k]\n // : never;\n // },\n // NewInput extends {\n // [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation\n // ? Augmentation[k]["_input"]\n // : k extends keyof Input\n // ? Input[k]\n // : never;\n // }\n // >(\n // merging: Incoming\n // ): ZodObject<\n // extendShape<T, ReturnType<Incoming["_def"]["shape"]>>,\n // Incoming["_def"]["unknownKeys"],\n // Incoming["_def"]["catchall"],\n // NewOutput,\n // NewInput\n // > {\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n setKey(key, schema) {\n return this.augment({ [key]: schema });\n }\n // merge<Incoming extends AnyZodObject>(\n // merging: Incoming\n // ): //ZodObject<T & Incoming["_shape"], UnknownKeys, Catchall> = (merging) => {\n // ZodObject<\n // extendShape<T, ReturnType<Incoming["_def"]["shape"]>>,\n // Incoming["_def"]["unknownKeys"],\n // Incoming["_def"]["catchall"]\n // > {\n // // const mergedShape = objectUtil.mergeShapes(\n // // this._def.shape(),\n // // merging._def.shape()\n // // );\n // const merged: any = new ZodObject({\n // unknownKeys: merging._def.unknownKeys,\n // catchall: merging._def.catchall,\n // shape: () =>\n // objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),\n // typeName: ZodFirstPartyTypeKind.ZodObject,\n // }) as any;\n // return merged;\n // }\n catchall(index) {\n return new ZodObject({\n ...this._def,\n catchall: index\n });\n }\n pick(mask) {\n const shape = {};\n util.objectKeys(mask).forEach((key) => {\n if (mask[key] && this.shape[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape\n });\n }\n omit(mask) {\n const shape = {};\n util.objectKeys(this.shape).forEach((key) => {\n if (!mask[key]) {\n shape[key] = this.shape[key];\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => shape\n });\n }\n /**\n * @deprecated\n */\n deepPartial() {\n return deepPartialify(this);\n }\n partial(mask) {\n const newShape = {};\n util.objectKeys(this.shape).forEach((key) => {\n const fieldSchema = this.shape[key];\n if (mask && !mask[key]) {\n newShape[key] = fieldSchema;\n } else {\n newShape[key] = fieldSchema.optional();\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape\n });\n }\n required(mask) {\n const newShape = {};\n util.objectKeys(this.shape).forEach((key) => {\n if (mask && !mask[key]) {\n newShape[key] = this.shape[key];\n } else {\n const fieldSchema = this.shape[key];\n let newField = fieldSchema;\n while (newField instanceof ZodOptional) {\n newField = newField._def.innerType;\n }\n newShape[key] = newField;\n }\n });\n return new ZodObject({\n ...this._def,\n shape: () => newShape\n });\n }\n keyof() {\n return createZodEnum(util.objectKeys(this.shape));\n }\n }\n ZodObject.create = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: "strip",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params)\n });\n };\n ZodObject.strictCreate = (shape, params) => {\n return new ZodObject({\n shape: () => shape,\n unknownKeys: "strict",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params)\n });\n };\n ZodObject.lazycreate = (shape, params) => {\n return new ZodObject({\n shape,\n unknownKeys: "strip",\n catchall: ZodNever.create(),\n typeName: ZodFirstPartyTypeKind.ZodObject,\n ...processCreateParams(params)\n });\n };\n class ZodUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const options = this._def.options;\n function handleResults(results) {\n for (const result of results) {\n if (result.result.status === "valid") {\n return result.result;\n }\n }\n for (const result of results) {\n if (result.result.status === "dirty") {\n ctx.common.issues.push(...result.ctx.common.issues);\n return result.result;\n }\n }\n const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return Promise.all(options.map(async (option) => {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: []\n },\n parent: null\n };\n return {\n result: await option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx\n }),\n ctx: childCtx\n };\n })).then(handleResults);\n } else {\n let dirty = void 0;\n const issues = [];\n for (const option of options) {\n const childCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: []\n },\n parent: null\n };\n const result = option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: childCtx\n });\n if (result.status === "valid") {\n return result;\n } else if (result.status === "dirty" && !dirty) {\n dirty = { result, ctx: childCtx };\n }\n if (childCtx.common.issues.length) {\n issues.push(childCtx.common.issues);\n }\n }\n if (dirty) {\n ctx.common.issues.push(...dirty.ctx.common.issues);\n return dirty.result;\n }\n const unionErrors = issues.map((issues2) => new ZodError(issues2));\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union,\n unionErrors\n });\n return INVALID;\n }\n }\n get options() {\n return this._def.options;\n }\n }\n ZodUnion.create = (types, params) => {\n return new ZodUnion({\n options: types,\n typeName: ZodFirstPartyTypeKind.ZodUnion,\n ...processCreateParams(params)\n });\n };\n const getDiscriminator = (type) => {\n if (type instanceof ZodLazy) {\n return getDiscriminator(type.schema);\n } else if (type instanceof ZodEffects) {\n return getDiscriminator(type.innerType());\n } else if (type instanceof ZodLiteral) {\n return [type.value];\n } else if (type instanceof ZodEnum) {\n return type.options;\n } else if (type instanceof ZodNativeEnum) {\n return util.objectValues(type.enum);\n } else if (type instanceof ZodDefault) {\n return getDiscriminator(type._def.innerType);\n } else if (type instanceof ZodUndefined) {\n return [void 0];\n } else if (type instanceof ZodNull) {\n return [null];\n } else if (type instanceof ZodOptional) {\n return [void 0, ...getDiscriminator(type.unwrap())];\n } else if (type instanceof ZodNullable) {\n return [null, ...getDiscriminator(type.unwrap())];\n } else if (type instanceof ZodBranded) {\n return getDiscriminator(type.unwrap());\n } else if (type instanceof ZodReadonly) {\n return getDiscriminator(type.unwrap());\n } else if (type instanceof ZodCatch) {\n return getDiscriminator(type._def.innerType);\n } else {\n return [];\n }\n };\n class ZodDiscriminatedUnion extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType\n });\n return INVALID;\n }\n const discriminator = this.discriminator;\n const discriminatorValue = ctx.data[discriminator];\n const option = this.optionsMap.get(discriminatorValue);\n if (!option) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_union_discriminator,\n options: Array.from(this.optionsMap.keys()),\n path: [discriminator]\n });\n return INVALID;\n }\n if (ctx.common.async) {\n return option._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n } else {\n return option._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n }\n }\n get discriminator() {\n return this._def.discriminator;\n }\n get options() {\n return this._def.options;\n }\n get optionsMap() {\n return this._def.optionsMap;\n }\n /**\n * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.\n * However, it only allows a union of objects, all of which need to share a discriminator property. This property must\n * have a different value for each object in the union.\n * @param discriminator the name of the discriminator property\n * @param types an array of object schemas\n * @param params\n */\n static create(discriminator, options, params) {\n const optionsMap = /* @__PURE__ */ new Map();\n for (const type of options) {\n const discriminatorValues = getDiscriminator(type.shape[discriminator]);\n if (!discriminatorValues.length) {\n throw new Error(`A discriminator value for key \\`${discriminator}\\` could not be extracted from all schema options`);\n }\n for (const value of discriminatorValues) {\n if (optionsMap.has(value)) {\n throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);\n }\n optionsMap.set(value, type);\n }\n }\n return new ZodDiscriminatedUnion({\n typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,\n discriminator,\n options,\n optionsMap,\n ...processCreateParams(params)\n });\n }\n }\n function mergeValues(a2, b) {\n const aType = getParsedType(a2);\n const bType = getParsedType(b);\n if (a2 === b) {\n return { valid: true, data: a2 };\n } else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {\n const bKeys = util.objectKeys(b);\n const sharedKeys = util.objectKeys(a2).filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a2, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a2[key], b[key]);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n } else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {\n if (a2.length !== b.length) {\n return { valid: false };\n }\n const newArray = [];\n for (let index = 0; index < a2.length; index++) {\n const itemA = a2[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return { valid: false };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n } else if (aType === ZodParsedType.date && bType === ZodParsedType.date && +a2 === +b) {\n return { valid: true, data: a2 };\n } else {\n return { valid: false };\n }\n }\n class ZodIntersection extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const handleParsed = (parsedLeft, parsedRight) => {\n if (isAborted(parsedLeft) || isAborted(parsedRight)) {\n return INVALID;\n }\n const merged = mergeValues(parsedLeft.value, parsedRight.value);\n if (!merged.valid) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_intersection_types\n });\n return INVALID;\n }\n if (isDirty(parsedLeft) || isDirty(parsedRight)) {\n status.dirty();\n }\n return { status: status.value, value: merged.data };\n };\n if (ctx.common.async) {\n return Promise.all([\n this._def.left._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n }),\n this._def.right._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n })\n ]).then(([left, right]) => handleParsed(left, right));\n } else {\n return handleParsed(this._def.left._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n }), this._def.right._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n }));\n }\n }\n }\n ZodIntersection.create = (left, right, params) => {\n return new ZodIntersection({\n left,\n right,\n typeName: ZodFirstPartyTypeKind.ZodIntersection,\n ...processCreateParams(params)\n });\n };\n class ZodTuple extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.array) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.array,\n received: ctx.parsedType\n });\n return INVALID;\n }\n if (ctx.data.length < this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: "array"\n });\n return INVALID;\n }\n const rest = this._def.rest;\n if (!rest && ctx.data.length > this._def.items.length) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: this._def.items.length,\n inclusive: true,\n exact: false,\n type: "array"\n });\n status.dirty();\n }\n const items = [...ctx.data].map((item, itemIndex) => {\n const schema = this._def.items[itemIndex] || this._def.rest;\n if (!schema)\n return null;\n return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));\n }).filter((x) => !!x);\n if (ctx.common.async) {\n return Promise.all(items).then((results) => {\n return ParseStatus.mergeArray(status, results);\n });\n } else {\n return ParseStatus.mergeArray(status, items);\n }\n }\n get items() {\n return this._def.items;\n }\n rest(rest) {\n return new ZodTuple({\n ...this._def,\n rest\n });\n }\n }\n ZodTuple.create = (schemas, params) => {\n if (!Array.isArray(schemas)) {\n throw new Error("You must pass an array of schemas to z.tuple([ ... ])");\n }\n return new ZodTuple({\n items: schemas,\n typeName: ZodFirstPartyTypeKind.ZodTuple,\n rest: null,\n ...processCreateParams(params)\n });\n };\n class ZodRecord extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.object) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.object,\n received: ctx.parsedType\n });\n return INVALID;\n }\n const pairs = [];\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n for (const key in ctx.data) {\n pairs.push({\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),\n value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),\n alwaysSet: key in ctx.data\n });\n }\n if (ctx.common.async) {\n return ParseStatus.mergeObjectAsync(status, pairs);\n } else {\n return ParseStatus.mergeObjectSync(status, pairs);\n }\n }\n get element() {\n return this._def.valueType;\n }\n static create(first, second, third) {\n if (second instanceof ZodType) {\n return new ZodRecord({\n keyType: first,\n valueType: second,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(third)\n });\n }\n return new ZodRecord({\n keyType: ZodString.create(),\n valueType: first,\n typeName: ZodFirstPartyTypeKind.ZodRecord,\n ...processCreateParams(second)\n });\n }\n }\n class ZodMap extends ZodType {\n get keySchema() {\n return this._def.keyType;\n }\n get valueSchema() {\n return this._def.valueType;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.map) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.map,\n received: ctx.parsedType\n });\n return INVALID;\n }\n const keyType = this._def.keyType;\n const valueType = this._def.valueType;\n const pairs = [...ctx.data.entries()].map(([key, value], index) => {\n return {\n key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),\n value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))\n };\n });\n if (ctx.common.async) {\n const finalMap = /* @__PURE__ */ new Map();\n return Promise.resolve().then(async () => {\n for (const pair of pairs) {\n const key = await pair.key;\n const value = await pair.value;\n if (key.status === "aborted" || value.status === "aborted") {\n return INVALID;\n }\n if (key.status === "dirty" || value.status === "dirty") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n });\n } else {\n const finalMap = /* @__PURE__ */ new Map();\n for (const pair of pairs) {\n const key = pair.key;\n const value = pair.value;\n if (key.status === "aborted" || value.status === "aborted") {\n return INVALID;\n }\n if (key.status === "dirty" || value.status === "dirty") {\n status.dirty();\n }\n finalMap.set(key.value, value.value);\n }\n return { status: status.value, value: finalMap };\n }\n }\n }\n ZodMap.create = (keyType, valueType, params) => {\n return new ZodMap({\n valueType,\n keyType,\n typeName: ZodFirstPartyTypeKind.ZodMap,\n ...processCreateParams(params)\n });\n };\n class ZodSet extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.set) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.set,\n received: ctx.parsedType\n });\n return INVALID;\n }\n const def = this._def;\n if (def.minSize !== null) {\n if (ctx.data.size < def.minSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_small,\n minimum: def.minSize.value,\n type: "set",\n inclusive: true,\n exact: false,\n message: def.minSize.message\n });\n status.dirty();\n }\n }\n if (def.maxSize !== null) {\n if (ctx.data.size > def.maxSize.value) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.too_big,\n maximum: def.maxSize.value,\n type: "set",\n inclusive: true,\n exact: false,\n message: def.maxSize.message\n });\n status.dirty();\n }\n }\n const valueType = this._def.valueType;\n function finalizeSet(elements2) {\n const parsedSet = /* @__PURE__ */ new Set();\n for (const element of elements2) {\n if (element.status === "aborted")\n return INVALID;\n if (element.status === "dirty")\n status.dirty();\n parsedSet.add(element.value);\n }\n return { status: status.value, value: parsedSet };\n }\n const elements = [...ctx.data.values()].map((item, i2) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i2)));\n if (ctx.common.async) {\n return Promise.all(elements).then((elements2) => finalizeSet(elements2));\n } else {\n return finalizeSet(elements);\n }\n }\n min(minSize, message) {\n return new ZodSet({\n ...this._def,\n minSize: { value: minSize, message: errorUtil.toString(message) }\n });\n }\n max(maxSize, message) {\n return new ZodSet({\n ...this._def,\n maxSize: { value: maxSize, message: errorUtil.toString(message) }\n });\n }\n size(size, message) {\n return this.min(size, message).max(size, message);\n }\n nonempty(message) {\n return this.min(1, message);\n }\n }\n ZodSet.create = (valueType, params) => {\n return new ZodSet({\n valueType,\n minSize: null,\n maxSize: null,\n typeName: ZodFirstPartyTypeKind.ZodSet,\n ...processCreateParams(params)\n });\n };\n class ZodFunction extends ZodType {\n constructor() {\n super(...arguments);\n this.validate = this.implement;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.function) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.function,\n received: ctx.parsedType\n });\n return INVALID;\n }\n function makeArgsIssue(args, error) {\n return makeIssue({\n data: args,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n getErrorMap(),\n errorMap\n ].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_arguments,\n argumentsError: error\n }\n });\n }\n function makeReturnsIssue(returns, error) {\n return makeIssue({\n data: returns,\n path: ctx.path,\n errorMaps: [\n ctx.common.contextualErrorMap,\n ctx.schemaErrorMap,\n getErrorMap(),\n errorMap\n ].filter((x) => !!x),\n issueData: {\n code: ZodIssueCode.invalid_return_type,\n returnTypeError: error\n }\n });\n }\n const params = { errorMap: ctx.common.contextualErrorMap };\n const fn = ctx.data;\n if (this._def.returns instanceof ZodPromise) {\n const me = this;\n return OK(async function(...args) {\n const error = new ZodError([]);\n const parsedArgs = await me._def.args.parseAsync(args, params).catch((e2) => {\n error.addIssue(makeArgsIssue(args, e2));\n throw error;\n });\n const result = await Reflect.apply(fn, this, parsedArgs);\n const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e2) => {\n error.addIssue(makeReturnsIssue(result, e2));\n throw error;\n });\n return parsedReturns;\n });\n } else {\n const me = this;\n return OK(function(...args) {\n const parsedArgs = me._def.args.safeParse(args, params);\n if (!parsedArgs.success) {\n throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);\n }\n const result = Reflect.apply(fn, this, parsedArgs.data);\n const parsedReturns = me._def.returns.safeParse(result, params);\n if (!parsedReturns.success) {\n throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);\n }\n return parsedReturns.data;\n });\n }\n }\n parameters() {\n return this._def.args;\n }\n returnType() {\n return this._def.returns;\n }\n args(...items) {\n return new ZodFunction({\n ...this._def,\n args: ZodTuple.create(items).rest(ZodUnknown.create())\n });\n }\n returns(returnType) {\n return new ZodFunction({\n ...this._def,\n returns: returnType\n });\n }\n implement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n strictImplement(func) {\n const validatedFunc = this.parse(func);\n return validatedFunc;\n }\n static create(args, returns, params) {\n return new ZodFunction({\n args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()),\n returns: returns || ZodUnknown.create(),\n typeName: ZodFirstPartyTypeKind.ZodFunction,\n ...processCreateParams(params)\n });\n }\n }\n class ZodLazy extends ZodType {\n get schema() {\n return this._def.getter();\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const lazySchema = this._def.getter();\n return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });\n }\n }\n ZodLazy.create = (getter, params) => {\n return new ZodLazy({\n getter,\n typeName: ZodFirstPartyTypeKind.ZodLazy,\n ...processCreateParams(params)\n });\n };\n class ZodLiteral extends ZodType {\n _parse(input) {\n if (input.data !== this._def.value) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_literal,\n expected: this._def.value\n });\n return INVALID;\n }\n return { status: "valid", value: input.data };\n }\n get value() {\n return this._def.value;\n }\n }\n ZodLiteral.create = (value, params) => {\n return new ZodLiteral({\n value,\n typeName: ZodFirstPartyTypeKind.ZodLiteral,\n ...processCreateParams(params)\n });\n };\n function createZodEnum(values, params) {\n return new ZodEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodEnum,\n ...processCreateParams(params)\n });\n }\n class ZodEnum extends ZodType {\n constructor() {\n super(...arguments);\n _ZodEnum_cache.set(this, void 0);\n }\n _parse(input) {\n if (typeof input.data !== "string") {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type\n });\n return INVALID;\n }\n if (!__classPrivateFieldGet(this, _ZodEnum_cache)) {\n __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values));\n }\n if (!__classPrivateFieldGet(this, _ZodEnum_cache).has(input.data)) {\n const ctx = this._getOrReturnCtx(input);\n const expectedValues = this._def.values;\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get options() {\n return this._def.values;\n }\n get enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Values() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n get Enum() {\n const enumValues = {};\n for (const val of this._def.values) {\n enumValues[val] = val;\n }\n return enumValues;\n }\n extract(values, newDef = this._def) {\n return ZodEnum.create(values, {\n ...this._def,\n ...newDef\n });\n }\n exclude(values, newDef = this._def) {\n return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {\n ...this._def,\n ...newDef\n });\n }\n }\n _ZodEnum_cache = /* @__PURE__ */ new WeakMap();\n ZodEnum.create = createZodEnum;\n class ZodNativeEnum extends ZodType {\n constructor() {\n super(...arguments);\n _ZodNativeEnum_cache.set(this, void 0);\n }\n _parse(input) {\n const nativeEnumValues = util.getValidEnumValues(this._def.values);\n const ctx = this._getOrReturnCtx(input);\n if (ctx.parsedType !== ZodParsedType.string && ctx.parsedType !== ZodParsedType.number) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n expected: util.joinValues(expectedValues),\n received: ctx.parsedType,\n code: ZodIssueCode.invalid_type\n });\n return INVALID;\n }\n if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache)) {\n __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util.getValidEnumValues(this._def.values)));\n }\n if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache).has(input.data)) {\n const expectedValues = util.objectValues(nativeEnumValues);\n addIssueToContext(ctx, {\n received: ctx.data,\n code: ZodIssueCode.invalid_enum_value,\n options: expectedValues\n });\n return INVALID;\n }\n return OK(input.data);\n }\n get enum() {\n return this._def.values;\n }\n }\n _ZodNativeEnum_cache = /* @__PURE__ */ new WeakMap();\n ZodNativeEnum.create = (values, params) => {\n return new ZodNativeEnum({\n values,\n typeName: ZodFirstPartyTypeKind.ZodNativeEnum,\n ...processCreateParams(params)\n });\n };\n class ZodPromise extends ZodType {\n unwrap() {\n return this._def.type;\n }\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n if (ctx.parsedType !== ZodParsedType.promise && ctx.common.async === false) {\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.promise,\n received: ctx.parsedType\n });\n return INVALID;\n }\n const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);\n return OK(promisified.then((data) => {\n return this._def.type.parseAsync(data, {\n path: ctx.path,\n errorMap: ctx.common.contextualErrorMap\n });\n }));\n }\n }\n ZodPromise.create = (schema, params) => {\n return new ZodPromise({\n type: schema,\n typeName: ZodFirstPartyTypeKind.ZodPromise,\n ...processCreateParams(params)\n });\n };\n class ZodEffects extends ZodType {\n innerType() {\n return this._def.schema;\n }\n sourceType() {\n return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;\n }\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n const effect = this._def.effect || null;\n const checkCtx = {\n addIssue: (arg) => {\n addIssueToContext(ctx, arg);\n if (arg.fatal) {\n status.abort();\n } else {\n status.dirty();\n }\n },\n get path() {\n return ctx.path;\n }\n };\n checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);\n if (effect.type === "preprocess") {\n const processed = effect.transform(ctx.data, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(processed).then(async (processed2) => {\n if (status.value === "aborted")\n return INVALID;\n const result = await this._def.schema._parseAsync({\n data: processed2,\n path: ctx.path,\n parent: ctx\n });\n if (result.status === "aborted")\n return INVALID;\n if (result.status === "dirty")\n return DIRTY(result.value);\n if (status.value === "dirty")\n return DIRTY(result.value);\n return result;\n });\n } else {\n if (status.value === "aborted")\n return INVALID;\n const result = this._def.schema._parseSync({\n data: processed,\n path: ctx.path,\n parent: ctx\n });\n if (result.status === "aborted")\n return INVALID;\n if (result.status === "dirty")\n return DIRTY(result.value);\n if (status.value === "dirty")\n return DIRTY(result.value);\n return result;\n }\n }\n if (effect.type === "refinement") {\n const executeRefinement = (acc) => {\n const result = effect.refinement(acc, checkCtx);\n if (ctx.common.async) {\n return Promise.resolve(result);\n }\n if (result instanceof Promise) {\n throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");\n }\n return acc;\n };\n if (ctx.common.async === false) {\n const inner = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n if (inner.status === "aborted")\n return INVALID;\n if (inner.status === "dirty")\n status.dirty();\n executeRefinement(inner.value);\n return { status: status.value, value: inner.value };\n } else {\n return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {\n if (inner.status === "aborted")\n return INVALID;\n if (inner.status === "dirty")\n status.dirty();\n return executeRefinement(inner.value).then(() => {\n return { status: status.value, value: inner.value };\n });\n });\n }\n }\n if (effect.type === "transform") {\n if (ctx.common.async === false) {\n const base = this._def.schema._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n if (!isValid(base))\n return base;\n const result = effect.transform(base.value, checkCtx);\n if (result instanceof Promise) {\n throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);\n }\n return { status: status.value, value: result };\n } else {\n return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {\n if (!isValid(base))\n return base;\n return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));\n });\n }\n }\n util.assertNever(effect);\n }\n }\n ZodEffects.create = (schema, effect, params) => {\n return new ZodEffects({\n schema,\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n effect,\n ...processCreateParams(params)\n });\n };\n ZodEffects.createWithPreprocess = (preprocess, schema, params) => {\n return new ZodEffects({\n schema,\n effect: { type: "preprocess", transform: preprocess },\n typeName: ZodFirstPartyTypeKind.ZodEffects,\n ...processCreateParams(params)\n });\n };\n class ZodOptional extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.undefined) {\n return OK(void 0);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n ZodOptional.create = (type, params) => {\n return new ZodOptional({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodOptional,\n ...processCreateParams(params)\n });\n };\n class ZodNullable extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType === ZodParsedType.null) {\n return OK(null);\n }\n return this._def.innerType._parse(input);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n ZodNullable.create = (type, params) => {\n return new ZodNullable({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodNullable,\n ...processCreateParams(params)\n });\n };\n class ZodDefault extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n let data = ctx.data;\n if (ctx.parsedType === ZodParsedType.undefined) {\n data = this._def.defaultValue();\n }\n return this._def.innerType._parse({\n data,\n path: ctx.path,\n parent: ctx\n });\n }\n removeDefault() {\n return this._def.innerType;\n }\n }\n ZodDefault.create = (type, params) => {\n return new ZodDefault({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodDefault,\n defaultValue: typeof params.default === "function" ? params.default : () => params.default,\n ...processCreateParams(params)\n });\n };\n class ZodCatch extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const newCtx = {\n ...ctx,\n common: {\n ...ctx.common,\n issues: []\n }\n };\n const result = this._def.innerType._parse({\n data: newCtx.data,\n path: newCtx.path,\n parent: {\n ...newCtx\n }\n });\n if (isAsync(result)) {\n return result.then((result2) => {\n return {\n status: "valid",\n value: result2.status === "valid" ? result2.value : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data\n })\n };\n });\n } else {\n return {\n status: "valid",\n value: result.status === "valid" ? result.value : this._def.catchValue({\n get error() {\n return new ZodError(newCtx.common.issues);\n },\n input: newCtx.data\n })\n };\n }\n }\n removeCatch() {\n return this._def.innerType;\n }\n }\n ZodCatch.create = (type, params) => {\n return new ZodCatch({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodCatch,\n catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,\n ...processCreateParams(params)\n });\n };\n class ZodNaN extends ZodType {\n _parse(input) {\n const parsedType = this._getType(input);\n if (parsedType !== ZodParsedType.nan) {\n const ctx = this._getOrReturnCtx(input);\n addIssueToContext(ctx, {\n code: ZodIssueCode.invalid_type,\n expected: ZodParsedType.nan,\n received: ctx.parsedType\n });\n return INVALID;\n }\n return { status: "valid", value: input.data };\n }\n }\n ZodNaN.create = (params) => {\n return new ZodNaN({\n typeName: ZodFirstPartyTypeKind.ZodNaN,\n ...processCreateParams(params)\n });\n };\n const BRAND = Symbol("zod_brand");\n class ZodBranded extends ZodType {\n _parse(input) {\n const { ctx } = this._processInputParams(input);\n const data = ctx.data;\n return this._def.type._parse({\n data,\n path: ctx.path,\n parent: ctx\n });\n }\n unwrap() {\n return this._def.type;\n }\n }\n class ZodPipeline extends ZodType {\n _parse(input) {\n const { status, ctx } = this._processInputParams(input);\n if (ctx.common.async) {\n const handleAsync = async () => {\n const inResult = await this._def.in._parseAsync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n if (inResult.status === "aborted")\n return INVALID;\n if (inResult.status === "dirty") {\n status.dirty();\n return DIRTY(inResult.value);\n } else {\n return this._def.out._parseAsync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx\n });\n }\n };\n return handleAsync();\n } else {\n const inResult = this._def.in._parseSync({\n data: ctx.data,\n path: ctx.path,\n parent: ctx\n });\n if (inResult.status === "aborted")\n return INVALID;\n if (inResult.status === "dirty") {\n status.dirty();\n return {\n status: "dirty",\n value: inResult.value\n };\n } else {\n return this._def.out._parseSync({\n data: inResult.value,\n path: ctx.path,\n parent: ctx\n });\n }\n }\n }\n static create(a2, b) {\n return new ZodPipeline({\n in: a2,\n out: b,\n typeName: ZodFirstPartyTypeKind.ZodPipeline\n });\n }\n }\n class ZodReadonly extends ZodType {\n _parse(input) {\n const result = this._def.innerType._parse(input);\n const freeze = (data) => {\n if (isValid(data)) {\n data.value = Object.freeze(data.value);\n }\n return data;\n };\n return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);\n }\n unwrap() {\n return this._def.innerType;\n }\n }\n ZodReadonly.create = (type, params) => {\n return new ZodReadonly({\n innerType: type,\n typeName: ZodFirstPartyTypeKind.ZodReadonly,\n ...processCreateParams(params)\n });\n };\n function custom(check, params = {}, fatal) {\n if (check)\n return ZodAny.create().superRefine((data, ctx) => {\n var _a, _b;\n if (!check(data)) {\n const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;\n const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;\n const p2 = typeof p === "string" ? { message: p } : p;\n ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });\n }\n });\n return ZodAny.create();\n }\n const late = {\n object: ZodObject.lazycreate\n };\n var ZodFirstPartyTypeKind;\n (function(ZodFirstPartyTypeKind2) {\n ZodFirstPartyTypeKind2["ZodString"] = "ZodString";\n ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";\n ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";\n ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";\n ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";\n ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";\n ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";\n ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";\n ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";\n ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";\n ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";\n ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";\n ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";\n ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";\n ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";\n ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";\n ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";\n ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";\n ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";\n ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";\n ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";\n ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";\n ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";\n ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";\n ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";\n ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";\n ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";\n ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";\n ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";\n ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";\n ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";\n ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";\n ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";\n ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";\n ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";\n ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";\n })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));\n const instanceOfType = (cls, params = {\n message: `Input not instance of ${cls.name}`\n }) => custom((data) => data instanceof cls, params);\n const stringType = ZodString.create;\n const numberType = ZodNumber.create;\n const nanType = ZodNaN.create;\n const bigIntType = ZodBigInt.create;\n const booleanType = ZodBoolean.create;\n const dateType = ZodDate.create;\n const symbolType = ZodSymbol.create;\n const undefinedType = ZodUndefined.create;\n const nullType = ZodNull.create;\n const anyType = ZodAny.create;\n const unknownType = ZodUnknown.create;\n const neverType = ZodNever.create;\n const voidType = ZodVoid.create;\n const arrayType = ZodArray.create;\n const objectType = ZodObject.create;\n const strictObjectType = ZodObject.strictCreate;\n const unionType = ZodUnion.create;\n const discriminatedUnionType = ZodDiscriminatedUnion.create;\n const intersectionType = ZodIntersection.create;\n const tupleType = ZodTuple.create;\n const recordType = ZodRecord.create;\n const mapType = ZodMap.create;\n const setType = ZodSet.create;\n const functionType = ZodFunction.create;\n const lazyType = ZodLazy.create;\n const literalType = ZodLiteral.create;\n const enumType = ZodEnum.create;\n const nativeEnumType = ZodNativeEnum.create;\n const promiseType = ZodPromise.create;\n const effectsType = ZodEffects.create;\n const optionalType = ZodOptional.create;\n const nullableType = ZodNullable.create;\n const preprocessType = ZodEffects.createWithPreprocess;\n const pipelineType = ZodPipeline.create;\n const ostring = () => stringType().optional();\n const onumber = () => numberType().optional();\n const oboolean = () => booleanType().optional();\n const coerce = {\n string: (arg) => ZodString.create({ ...arg, coerce: true }),\n number: (arg) => ZodNumber.create({ ...arg, coerce: true }),\n boolean: (arg) => ZodBoolean.create({\n ...arg,\n coerce: true\n }),\n bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),\n date: (arg) => ZodDate.create({ ...arg, coerce: true })\n };\n const NEVER = INVALID;\n var z$1 = /* @__PURE__ */ Object.freeze({\n __proto__: null,\n defaultErrorMap: errorMap,\n setErrorMap,\n getErrorMap,\n makeIssue,\n EMPTY_PATH,\n addIssueToContext,\n ParseStatus,\n INVALID,\n DIRTY,\n OK,\n isAborted,\n isDirty,\n isValid,\n isAsync,\n get util() {\n return util;\n },\n get objectUtil() {\n return objectUtil;\n },\n ZodParsedType,\n getParsedType,\n ZodType,\n datetimeRegex,\n ZodString,\n ZodNumber,\n ZodBigInt,\n ZodBoolean,\n ZodDate,\n ZodSymbol,\n ZodUndefined,\n ZodNull,\n ZodAny,\n ZodUnknown,\n ZodNever,\n ZodVoid,\n ZodArray,\n ZodObject,\n ZodUnion,\n ZodDiscriminatedUnion,\n ZodIntersection,\n ZodTuple,\n ZodRecord,\n ZodMap,\n ZodSet,\n ZodFunction,\n ZodLazy,\n ZodLiteral,\n ZodEnum,\n ZodNativeEnum,\n ZodPromise,\n ZodEffects,\n ZodTransformer: ZodEffects,\n ZodOptional,\n ZodNullable,\n ZodDefault,\n ZodCatch,\n ZodNaN,\n BRAND,\n ZodBranded,\n ZodPipeline,\n ZodReadonly,\n custom,\n Schema: ZodType,\n ZodSchema: ZodType,\n late,\n get ZodFirstPartyTypeKind() {\n return ZodFirstPartyTypeKind;\n },\n coerce,\n any: anyType,\n array: arrayType,\n bigint: bigIntType,\n boolean: booleanType,\n date: dateType,\n discriminatedUnion: discriminatedUnionType,\n effect: effectsType,\n "enum": enumType,\n "function": functionType,\n "instanceof": instanceOfType,\n intersection: intersectionType,\n lazy: lazyType,\n literal: literalType,\n map: mapType,\n nan: nanType,\n nativeEnum: nativeEnumType,\n never: neverType,\n "null": nullType,\n nullable: nullableType,\n number: numberType,\n object: objectType,\n oboolean,\n onumber,\n optional: optionalType,\n ostring,\n pipeline: pipelineType,\n preprocess: preprocessType,\n promise: promiseType,\n record: recordType,\n set: setType,\n strictObject: strictObjectType,\n string: stringType,\n symbol: symbolType,\n transformer: effectsType,\n tuple: tupleType,\n "undefined": undefinedType,\n union: unionType,\n unknown: unknownType,\n "void": voidType,\n NEVER,\n ZodIssueCode,\n quotelessJson,\n ZodError\n });\n z$1.object({\n nucleotideSequences: z$1.array(\n z$1.object({\n name: z$1.string(),\n sequence: z$1.string()\n })\n ),\n genes: z$1.array(\n z$1.object({\n name: z$1.string(),\n sequence: z$1.string()\n })\n )\n });\n const orderByType = z$1.enum(["ascending", "descending"]);\n const orderBy = z$1.object({\n field: z$1.string(),\n type: orderByType\n });\n const lapisBaseRequest = z$1.object({\n limit: z$1.number().optional(),\n offset: z$1.number().optional(),\n fields: z$1.array(z$1.string()).optional(),\n orderBy: z$1.array(orderBy).optional()\n }).catchall(z$1.union([z$1.boolean(), z$1.undefined(), z$1.string(), z$1.number(), z$1.null(), z$1.array(z$1.string())]));\n lapisBaseRequest.extend({ minProportion: z$1.number().optional() });\n const mutationProportionCount = z$1.object({\n mutation: z$1.string(),\n proportion: z$1.number(),\n count: z$1.number(),\n sequenceName: z$1.union([z$1.string(), z$1.null()]),\n mutationFrom: z$1.string(),\n mutationTo: z$1.string(),\n position: z$1.number()\n });\n const mutationsResponse = makeLapisResponse(z$1.array(mutationProportionCount));\n const insertionCount = z$1.object({\n insertion: z$1.string(),\n count: z$1.number(),\n insertedSymbols: z$1.string(),\n position: z$1.number(),\n sequenceName: z$1.union([z$1.string(), z$1.null()])\n });\n makeLapisResponse(z$1.array(insertionCount));\n const aggregatedItem = z$1.object({ count: z$1.number() }).catchall(z$1.union([z$1.string(), z$1.number(), z$1.null()]));\n const aggregatedResponse = makeLapisResponse(z$1.array(aggregatedItem));\n function makeLapisResponse(data) {\n return z$1.object({\n data\n });\n }\n const problemDetail = z$1.object({\n title: z$1.string().optional(),\n status: z$1.number(),\n detail: z$1.string().optional(),\n type: z$1.string(),\n instance: z$1.string().optional()\n });\n const lapisError = z$1.object({\n error: problemDetail\n });\n class UnknownLapisError extends Error {\n constructor(message, status, requestedData) {\n super(message);\n this.status = status;\n this.requestedData = requestedData;\n this.name = "UnknownLapisError";\n }\n }\n class LapisError extends Error {\n constructor(message, status, problemDetail2, requestedData) {\n super(message);\n this.status = status;\n this.problemDetail = problemDetail2;\n this.requestedData = requestedData;\n this.name = "LapisError";\n }\n }\n async function fetchAggregated(lapisUrl, body, signal) {\n const response = await callLapis(\n aggregatedEndpoint(lapisUrl),\n {\n method: "POST",\n headers: {\n "Content-Type": "application/json"\n },\n body: JSON.stringify(body),\n signal\n },\n "aggregated data"\n );\n return aggregatedResponse.parse(await response.json());\n }\n async function fetchSubstitutionsOrDeletions(lapisUrl, body, sequenceType, signal) {\n const response = await callLapis(\n substitutionsOrDeletionsEndpoint(lapisUrl, sequenceType),\n {\n method: "POST",\n headers: {\n "Content-Type": "application/json"\n },\n body: JSON.stringify(body),\n signal\n },\n `${sequenceType} mutations`\n );\n return mutationsResponse.parse(await response.json());\n }\n async function callLapis(input, init, requestedDataName) {\n try {\n const response = await fetch(input, init);\n await handleErrors(response, requestedDataName);\n return response;\n } catch (error) {\n const message = error instanceof Error ? error.message : `${error}`;\n throw new UnknownLapisError(`Failed to connect to LAPIS: ${message}`, 500, requestedDataName);\n }\n }\n const handleErrors = async (response, requestedData) => {\n if (!response.ok) {\n if (response.status >= 400 && response.status < 500) {\n const json = await response.json();\n const lapisErrorResult = lapisError.safeParse(json);\n if (lapisErrorResult.success) {\n throw new LapisError(\n response.statusText + lapisErrorResult.data.error.detail,\n response.status,\n lapisErrorResult.data.error,\n requestedData\n );\n }\n const problemDetailResult = problemDetail.safeParse(json);\n if (problemDetailResult.success) {\n throw new LapisError(\n response.statusText + problemDetailResult.data.detail,\n response.status,\n problemDetailResult.data,\n requestedData\n );\n }\n throw new UnknownLapisError(\n `${response.statusText}: ${JSON.stringify(json)}`,\n response.status,\n requestedData\n );\n }\n throw new UnknownLapisError(`${response.statusText}: ${response.status}`, response.status, requestedData);\n }\n };\n const aggregatedEndpoint = (lapisUrl) => `${lapisUrl}/sample/aggregated`;\n const substitutionsOrDeletionsEndpoint = (lapisUrl, sequenceType) => {\n return sequenceType === "amino acid" ? `${lapisUrl}/sample/aminoAcidMutations` : `${lapisUrl}/sample/nucleotideMutations`;\n };\n class FetchAggregatedOperator {\n constructor(filter, fields = []) {\n this.filter = filter;\n this.fields = fields;\n }\n async evaluate(lapisUrl, signal) {\n const aggregatedResponse2 = (await fetchAggregated(\n lapisUrl,\n {\n ...this.filter,\n fields: this.fields\n },\n signal\n )).data;\n if (isFieldsArrayWithCount(aggregatedResponse2)) {\n return {\n content: aggregatedResponse2\n };\n }\n throw new Error("Aggregated response does not have count");\n }\n }\n function isFieldsArrayWithCount(data) {\n return data.every((item) => typeof item === "object" && "count" in item && typeof item.count === "number");\n }\n class GroupByOperator {\n constructor(child, field, aggregate) {\n this.child = child;\n this.field = field;\n this.aggregate = aggregate;\n }\n async evaluate(lapis, signal) {\n const childEvaluated = await this.child.evaluate(lapis, signal);\n const grouped = /* @__PURE__ */ new Map();\n for (const row of childEvaluated.content) {\n const key = row[this.field];\n if (!grouped.has(key)) {\n grouped.set(key, []);\n }\n grouped.get(key).push(row);\n }\n const result = new Array();\n for (const [, values] of grouped) {\n result.push(this.aggregate(values));\n }\n return {\n content: result\n };\n }\n }\n class GroupByAndSumOperator extends GroupByOperator {\n constructor(child, groupByField, sumField) {\n super(child, groupByField, (values) => {\n let n = 0;\n for (const value of values) {\n n += value[sumField];\n }\n return {\n [groupByField]: values[0][groupByField],\n [sumField]: n\n };\n });\n }\n }\n class MapOperator {\n constructor(child, func) {\n this.child = child;\n this.func = func;\n }\n async evaluate(lapis, signal) {\n const childEvaluated = await this.child.evaluate(lapis, signal);\n return {\n content: childEvaluated.content.map(this.func)\n };\n }\n }\n class RenameFieldOperator extends MapOperator {\n constructor(child, oldFieldName, newFieldName) {\n super(\n child,\n (value) => ({\n ...value,\n [newFieldName]: value[oldFieldName]\n })\n );\n }\n }\n class SortOperator {\n constructor(child, compareFn) {\n this.child = child;\n this.compareFn = compareFn;\n }\n async evaluate(lapis, signal) {\n const childEvaluated = await this.child.evaluate(lapis, signal);\n return {\n content: childEvaluated.content.sort(this.compareFn)\n };\n }\n }\n var SECONDS_A_MINUTE = 60;\n var SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;\n var SECONDS_A_DAY = SECONDS_A_HOUR * 24;\n var SECONDS_A_WEEK = SECONDS_A_DAY * 7;\n var MILLISECONDS_A_SECOND = 1e3;\n var MILLISECONDS_A_MINUTE = SECONDS_A_MINUTE * MILLISECONDS_A_SECOND;\n var MILLISECONDS_A_HOUR = SECONDS_A_HOUR * MILLISECONDS_A_SECOND;\n var MILLISECONDS_A_DAY = SECONDS_A_DAY * MILLISECONDS_A_SECOND;\n var MILLISECONDS_A_WEEK = SECONDS_A_WEEK * MILLISECONDS_A_SECOND;\n var MS = "millisecond";\n var S = "second";\n var MIN = "minute";\n var H = "hour";\n var D = "day";\n var W = "week";\n var M = "month";\n var Q = "quarter";\n var Y = "year";\n var DATE = "date";\n var FORMAT_DEFAULT = "YYYY-MM-DDTHH:mm:ssZ";\n var INVALID_DATE_STRING = "Invalid Date";\n var REGEX_PARSE = /^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[Tt\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/;\n var REGEX_FORMAT = /\\[([^\\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g;\n var en = {\n name: "en",\n weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),\n months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),\n ordinal: function ordinal(n) {\n var s2 = ["th", "st", "nd", "rd"];\n var v2 = n % 100;\n return "[" + n + (s2[(v2 - 20) % 10] || s2[v2] || s2[0]) + "]";\n }\n };\n var padStart = function padStart2(string, length, pad) {\n var s2 = String(string);\n if (!s2 || s2.length >= length) return string;\n return "" + Array(length + 1 - s2.length).join(pad) + string;\n };\n var padZoneStr = function padZoneStr2(instance) {\n var negMinutes = -instance.utcOffset();\n var minutes = Math.abs(negMinutes);\n var hourOffset = Math.floor(minutes / 60);\n var minuteOffset = minutes % 60;\n return (negMinutes <= 0 ? "+" : "-") + padStart(hourOffset, 2, "0") + ":" + padStart(minuteOffset, 2, "0");\n };\n var monthDiff = function monthDiff2(a2, b) {\n if (a2.date() < b.date()) return -monthDiff2(b, a2);\n var wholeMonthDiff = (b.year() - a2.year()) * 12 + (b.month() - a2.month());\n var anchor = a2.clone().add(wholeMonthDiff, M);\n var c2 = b - anchor < 0;\n var anchor2 = a2.clone().add(wholeMonthDiff + (c2 ? -1 : 1), M);\n return +(-(wholeMonthDiff + (b - anchor) / (c2 ? anchor - anchor2 : anchor2 - anchor)) || 0);\n };\n var absFloor = function absFloor2(n) {\n return n < 0 ? Math.ceil(n) || 0 : Math.floor(n);\n };\n var prettyUnit = function prettyUnit2(u2) {\n var special = {\n M,\n y: Y,\n w: W,\n d: D,\n D: DATE,\n h: H,\n m: MIN,\n s: S,\n ms: MS,\n Q\n };\n return special[u2] || String(u2 || "").toLowerCase().replace(/s$/, "");\n };\n var isUndefined = function isUndefined2(s2) {\n return s2 === void 0;\n };\n var U = {\n s: padStart,\n z: padZoneStr,\n m: monthDiff,\n a: absFloor,\n p: prettyUnit,\n u: isUndefined\n };\n var L = "en";\n var Ls = {};\n Ls[L] = en;\n var IS_DAYJS = "$isDayjsObject";\n var isDayjs = function isDayjs2(d) {\n return d instanceof Dayjs || !!(d && d[IS_DAYJS]);\n };\n var parseLocale = function parseLocale2(preset, object, isLocal) {\n var l2;\n if (!preset) return L;\n if (typeof preset === "string") {\n var presetLower = preset.toLowerCase();\n if (Ls[presetLower]) {\n l2 = presetLower;\n }\n if (object) {\n Ls[presetLower] = object;\n l2 = presetLower;\n }\n var presetSplit = preset.split("-");\n if (!l2 && presetSplit.length > 1) {\n return parseLocale2(presetSplit[0]);\n }\n } else {\n var name = preset.name;\n Ls[name] = preset;\n l2 = name;\n }\n if (!isLocal && l2) L = l2;\n return l2 || !isLocal && L;\n };\n var dayjs = function dayjs2(date, c2) {\n if (isDayjs(date)) {\n return date.clone();\n }\n var cfg = typeof c2 === "object" ? c2 : {};\n cfg.date = date;\n cfg.args = arguments;\n return new Dayjs(cfg);\n };\n var wrapper = function wrapper2(date, instance) {\n return dayjs(date, {\n locale: instance.$L,\n utc: instance.$u,\n x: instance.$x,\n $offset: instance.$offset\n // todo: refactor; do not use this.$offset in you code\n });\n };\n var Utils = U;\n Utils.l = parseLocale;\n Utils.i = isDayjs;\n Utils.w = wrapper;\n var parseDate = function parseDate2(cfg) {\n var date = cfg.date, utc = cfg.utc;\n if (date === null) return /* @__PURE__ */ new Date(NaN);\n if (Utils.u(date)) return /* @__PURE__ */ new Date();\n if (date instanceof Date) return new Date(date);\n if (typeof date === "string" && !/Z$/i.test(date)) {\n var d = date.match(REGEX_PARSE);\n if (d) {\n var m2 = d[2] - 1 || 0;\n var ms = (d[7] || "0").substring(0, 3);\n if (utc) {\n return new Date(Date.UTC(d[1], m2, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms));\n }\n return new Date(d[1], m2, d[3] || 1, d[4] || 0, d[5] || 0, d[6] || 0, ms);\n }\n }\n return new Date(date);\n };\n var Dayjs = /* @__PURE__ */ function() {\n function Dayjs2(cfg) {\n this.$L = parseLocale(cfg.locale, null, true);\n this.parse(cfg);\n this.$x = this.$x || cfg.x || {};\n this[IS_DAYJS] = true;\n }\n var _proto = Dayjs2.prototype;\n _proto.parse = function parse(cfg) {\n this.$d = parseDate(cfg);\n this.init();\n };\n _proto.init = function init() {\n var $d = this.$d;\n this.$y = $d.getFullYear();\n this.$M = $d.getMonth();\n this.$D = $d.getDate();\n this.$W = $d.getDay();\n this.$H = $d.getHours();\n this.$m = $d.getMinutes();\n this.$s = $d.getSeconds();\n this.$ms = $d.getMilliseconds();\n };\n _proto.$utils = function $utils() {\n return Utils;\n };\n _proto.isValid = function isValid2() {\n return !(this.$d.toString() === INVALID_DATE_STRING);\n };\n _proto.isSame = function isSame(that, units) {\n var other = dayjs(that);\n return this.startOf(units) <= other && other <= this.endOf(units);\n };\n _proto.isAfter = function isAfter(that, units) {\n return dayjs(that) < this.startOf(units);\n };\n _proto.isBefore = function isBefore(that, units) {\n return this.endOf(units) < dayjs(that);\n };\n _proto.$g = function $g(input, get, set) {\n if (Utils.u(input)) return this[get];\n return this.set(set, input);\n };\n _proto.unix = function unix() {\n return Math.floor(this.valueOf() / 1e3);\n };\n _proto.valueOf = function valueOf() {\n return this.$d.getTime();\n };\n _proto.startOf = function startOf(units, _startOf) {\n var _this = this;\n var isStartOf = !Utils.u(_startOf) ? _startOf : true;\n var unit = Utils.p(units);\n var instanceFactory = function instanceFactory2(d, m2) {\n var ins = Utils.w(_this.$u ? Date.UTC(_this.$y, m2, d) : new Date(_this.$y, m2, d), _this);\n return isStartOf ? ins : ins.endOf(D);\n };\n var instanceFactorySet = function instanceFactorySet2(method, slice) {\n var argumentStart = [0, 0, 0, 0];\n var argumentEnd = [23, 59, 59, 999];\n return Utils.w(_this.toDate()[method].apply(\n // eslint-disable-line prefer-spread\n _this.toDate("s"),\n (isStartOf ? argumentStart : argumentEnd).slice(slice)\n ), _this);\n };\n var $W = this.$W, $M = this.$M, $D = this.$D;\n var utcPad = "set" + (this.$u ? "UTC" : "");\n switch (unit) {\n case Y:\n return isStartOf ? instanceFactory(1, 0) : instanceFactory(31, 11);\n case M:\n return isStartOf ? instanceFactory(1, $M) : instanceFactory(0, $M + 1);\n case W: {\n var weekStart = this.$locale().weekStart || 0;\n var gap = ($W < weekStart ? $W + 7 : $W) - weekStart;\n return instanceFactory(isStartOf ? $D - gap : $D + (6 - gap), $M);\n }\n case D:\n case DATE:\n return instanceFactorySet(utcPad + "Hours", 0);\n case H:\n return instanceFactorySet(utcPad + "Minutes", 1);\n case MIN:\n return instanceFactorySet(utcPad + "Seconds", 2);\n case S:\n return instanceFactorySet(utcPad + "Milliseconds", 3);\n default:\n return this.clone();\n }\n };\n _proto.endOf = function endOf(arg) {\n return this.startOf(arg, false);\n };\n _proto.$set = function $set(units, _int) {\n var _C$D$C$DATE$C$M$C$Y$C;\n var unit = Utils.p(units);\n var utcPad = "set" + (this.$u ? "UTC" : "");\n var name = (_C$D$C$DATE$C$M$C$Y$C = {}, _C$D$C$DATE$C$M$C$Y$C[D] = utcPad + "Date", _C$D$C$DATE$C$M$C$Y$C[DATE] = utcPad + "Date", _C$D$C$DATE$C$M$C$Y$C[M] = utcPad + "Month", _C$D$C$DATE$C$M$C$Y$C[Y] = utcPad + "FullYear", _C$D$C$DATE$C$M$C$Y$C[H] = utcPad + "Hours", _C$D$C$DATE$C$M$C$Y$C[MIN] = utcPad + "Minutes", _C$D$C$DATE$C$M$C$Y$C[S] = utcPad + "Seconds", _C$D$C$DATE$C$M$C$Y$C[MS] = utcPad + "Milliseconds", _C$D$C$DATE$C$M$C$Y$C)[unit];\n var arg = unit === D ? this.$D + (_int - this.$W) : _int;\n if (unit === M || unit === Y) {\n var date = this.clone().set(DATE, 1);\n date.$d[name](arg);\n date.init();\n this.$d = date.set(DATE, Math.min(this.$D, date.daysInMonth())).$d;\n } else if (name) this.$d[name](arg);\n this.init();\n return this;\n };\n _proto.set = function set(string, _int2) {\n return this.clone().$set(string, _int2);\n };\n _proto.get = function get(unit) {\n return this[Utils.p(unit)]();\n };\n _proto.add = function add(number, units) {\n var _this2 = this, _C$MIN$C$H$C$S$unit;\n number = Number(number);\n var unit = Utils.p(units);\n var instanceFactorySet = function instanceFactorySet2(n) {\n var d = dayjs(_this2);\n return Utils.w(d.date(d.date() + Math.round(n * number)), _this2);\n };\n if (unit === M) {\n return this.set(M, this.$M + number);\n }\n if (unit === Y) {\n return this.set(Y, this.$y + number);\n }\n if (unit === D) {\n return instanceFactorySet(1);\n }\n if (unit === W) {\n return instanceFactorySet(7);\n }\n var step = (_C$MIN$C$H$C$S$unit = {}, _C$MIN$C$H$C$S$unit[MIN] = MILLISECONDS_A_MINUTE, _C$MIN$C$H$C$S$unit[H] = MILLISECONDS_A_HOUR, _C$MIN$C$H$C$S$unit[S] = MILLISECONDS_A_SECOND, _C$MIN$C$H$C$S$unit)[unit] || 1;\n var nextTimeStamp = this.$d.getTime() + number * step;\n return Utils.w(nextTimeStamp, this);\n };\n _proto.subtract = function subtract(number, string) {\n return this.add(number * -1, string);\n };\n _proto.format = function format(formatStr) {\n var _this3 = this;\n var locale = this.$locale();\n if (!this.isValid()) return locale.invalidDate || INVALID_DATE_STRING;\n var str = formatStr || FORMAT_DEFAULT;\n var zoneStr = Utils.z(this);\n var $H = this.$H, $m = this.$m, $M = this.$M;\n var weekdays = locale.weekdays, months = locale.months, meridiem = locale.meridiem;\n var getShort = function getShort2(arr, index, full, length) {\n return arr && (arr[index] || arr(_this3, str)) || full[index].slice(0, length);\n };\n var get$H = function get$H2(num) {\n return Utils.s($H % 12 || 12, num, "0");\n };\n var meridiemFunc = meridiem || function(hour, minute, isLowercase) {\n var m2 = hour < 12 ? "AM" : "PM";\n return isLowercase ? m2.toLowerCase() : m2;\n };\n var matches = function matches2(match) {\n switch (match) {\n case "YY":\n return String(_this3.$y).slice(-2);\n case "YYYY":\n return Utils.s(_this3.$y, 4, "0");\n case "M":\n return $M + 1;\n case "MM":\n return Utils.s($M + 1, 2, "0");\n case "MMM":\n return getShort(locale.monthsShort, $M, months, 3);\n case "MMMM":\n return getShort(months, $M);\n case "D":\n return _this3.$D;\n case "DD":\n return Utils.s(_this3.$D, 2, "0");\n case "d":\n return String(_this3.$W);\n case "dd":\n return getShort(locale.weekdaysMin, _this3.$W, weekdays, 2);\n case "ddd":\n return getShort(locale.weekdaysShort, _this3.$W, weekdays, 3);\n case "dddd":\n return weekdays[_this3.$W];\n case "H":\n return String($H);\n case "HH":\n return Utils.s($H, 2, "0");\n case "h":\n return get$H(1);\n case "hh":\n return get$H(2);\n case "a":\n return meridiemFunc($H, $m, true);\n case "A":\n return meridiemFunc($H, $m, false);\n case "m":\n return String($m);\n case "mm":\n return Utils.s($m, 2, "0");\n case "s":\n return String(_this3.$s);\n case "ss":\n return Utils.s(_this3.$s, 2, "0");\n case "SSS":\n return Utils.s(_this3.$ms, 3, "0");\n case "Z":\n return zoneStr;\n }\n return null;\n };\n return str.replace(REGEX_FORMAT, function(match, $1) {\n return $1 || matches(match) || zoneStr.replace(":", "");\n });\n };\n _proto.utcOffset = function utcOffset() {\n return -Math.round(this.$d.getTimezoneOffset() / 15) * 15;\n };\n _proto.diff = function diff(input, units, _float) {\n var _this4 = this;\n var unit = Utils.p(units);\n var that = dayjs(input);\n var zoneDelta = (that.utcOffset() - this.utcOffset()) * MILLISECONDS_A_MINUTE;\n var diff2 = this - that;\n var getMonth = function getMonth2() {\n return Utils.m(_this4, that);\n };\n var result;\n switch (unit) {\n case Y:\n result = getMonth() / 12;\n break;\n case M:\n result = getMonth();\n break;\n case Q:\n result = getMonth() / 3;\n break;\n case W:\n result = (diff2 - zoneDelta) / MILLISECONDS_A_WEEK;\n break;\n case D:\n result = (diff2 - zoneDelta) / MILLISECONDS_A_DAY;\n break;\n case H:\n result = diff2 / MILLISECONDS_A_HOUR;\n break;\n case MIN:\n result = diff2 / MILLISECONDS_A_MINUTE;\n break;\n case S:\n result = diff2 / MILLISECONDS_A_SECOND;\n break;\n default:\n result = diff2;\n break;\n }\n return _float ? result : Utils.a(result);\n };\n _proto.daysInMonth = function daysInMonth() {\n return this.endOf(M).$D;\n };\n _proto.$locale = function $locale() {\n return Ls[this.$L];\n };\n _proto.locale = function locale(preset, object) {\n if (!preset) return this.$L;\n var that = this.clone();\n var nextLocaleName = parseLocale(preset, object, true);\n if (nextLocaleName) that.$L = nextLocaleName;\n return that;\n };\n _proto.clone = function clone() {\n return Utils.w(this.$d, this);\n };\n _proto.toDate = function toDate() {\n return new Date(this.valueOf());\n };\n _proto.toJSON = function toJSON() {\n return this.isValid() ? this.toISOString() : null;\n };\n _proto.toISOString = function toISOString() {\n return this.$d.toISOString();\n };\n _proto.toString = function toString() {\n return this.$d.toUTCString();\n };\n return Dayjs2;\n }();\n var proto = Dayjs.prototype;\n dayjs.prototype = proto;\n [["$ms", MS], ["$s", S], ["$m", MIN], ["$H", H], ["$W", D], ["$M", M], ["$y", Y], ["$D", DATE]].forEach(function(g) {\n proto[g[1]] = function(input) {\n return this.$g(input, g[0], g[1]);\n };\n });\n dayjs.extend = function(plugin, option) {\n if (!plugin.$i) {\n plugin(option, Dayjs, dayjs);\n plugin.$i = true;\n }\n return dayjs;\n };\n dayjs.locale = parseLocale;\n dayjs.isDayjs = isDayjs;\n dayjs.unix = function(timestamp) {\n return dayjs(timestamp * 1e3);\n };\n dayjs.en = Ls[L];\n dayjs.Ls = Ls;\n dayjs.p = {};\n var advancedFormat = function(o, c2) {\n var proto2 = c2.prototype;\n var oldFormat = proto2.format;\n proto2.format = function(formatStr) {\n var _this = this;\n var locale = this.$locale();\n if (!this.isValid()) {\n return oldFormat.bind(this)(formatStr);\n }\n var utils = this.$utils();\n var str = formatStr || FORMAT_DEFAULT;\n var result = str.replace(/\\[([^\\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g, function(match) {\n switch (match) {\n case "Q":\n return Math.ceil((_this.$M + 1) / 3);\n case "Do":\n return locale.ordinal(_this.$D);\n case "gggg":\n return _this.weekYear();\n case "GGGG":\n return _this.isoWeekYear();\n case "wo":\n return locale.ordinal(_this.week(), "W");\n // W for week\n case "w":\n case "ww":\n return utils.s(_this.week(), match === "w" ? 1 : 2, "0");\n case "W":\n case "WW":\n return utils.s(_this.isoWeek(), match === "W" ? 1 : 2, "0");\n case "k":\n case "kk":\n return utils.s(String(_this.$H === 0 ? 24 : _this.$H), match === "k" ? 1 : 2, "0");\n case "X":\n return Math.floor(_this.$d.getTime() / 1e3);\n case "x":\n return _this.$d.getTime();\n case "z":\n return "[" + _this.offsetName() + "]";\n case "zzz":\n return "[" + _this.offsetName("long") + "]";\n default:\n return match;\n }\n });\n return oldFormat.bind(this)(result);\n };\n };\n var isoWeekPrettyUnit = "isoweek";\n var isoWeek = function(o, c2, d) {\n var getYearFirstThursday = function getYearFirstThursday2(year, isUtc) {\n var yearFirstDay = (isUtc ? d.utc : d)().year(year).startOf(Y);\n var addDiffDays = 4 - yearFirstDay.isoWeekday();\n if (yearFirstDay.isoWeekday() > 4) {\n addDiffDays += 7;\n }\n return yearFirstDay.add(addDiffDays, D);\n };\n var getCurrentWeekThursday = function getCurrentWeekThursday2(ins) {\n return ins.add(4 - ins.isoWeekday(), D);\n };\n var proto2 = c2.prototype;\n proto2.isoWeekYear = function() {\n var nowWeekThursday = getCurrentWeekThursday(this);\n return nowWeekThursday.year();\n };\n proto2.isoWeek = function(week) {\n if (!this.$utils().u(week)) {\n return this.add((week - this.isoWeek()) * 7, D);\n }\n var nowWeekThursday = getCurrentWeekThursday(this);\n var diffWeekThursday = getYearFirstThursday(this.isoWeekYear(), this.$u);\n return nowWeekThursday.diff(diffWeekThursday, W) + 1;\n };\n proto2.isoWeekday = function(week) {\n if (!this.$utils().u(week)) {\n return this.day(this.day() % 7 ? week : week - 7);\n }\n return this.day() || 7;\n };\n var oldStartOf = proto2.startOf;\n proto2.startOf = function(units, startOf) {\n var utils = this.$utils();\n var isStartOf = !utils.u(startOf) ? startOf : true;\n var unit = utils.p(units);\n if (unit === isoWeekPrettyUnit) {\n return isStartOf ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day");\n }\n return oldStartOf.bind(this)(units, startOf);\n };\n };\n dayjs.extend(isoWeek);\n dayjs.extend(advancedFormat);\n const FORMAT_ISO_WEEK_YEAR_WEEK = "GGGG-[W]WW";\n const _TemporalCache = class _TemporalCache {\n constructor() {\n this.yearMonthDayCache = /* @__PURE__ */ new Map();\n this.yearWeekCache = /* @__PURE__ */ new Map();\n this.yearMonthCache = /* @__PURE__ */ new Map();\n this.yearCache = /* @__PURE__ */ new Map();\n }\n getYearMonthDay(s2) {\n if (!this.yearMonthDayCache.has(s2)) {\n this.yearMonthDayCache.set(s2, YearMonthDayClass.parse(s2, this));\n }\n return this.yearMonthDayCache.get(s2);\n }\n getYearMonth(s2) {\n if (!this.yearMonthCache.has(s2)) {\n this.yearMonthCache.set(s2, YearMonthClass.parse(s2, this));\n }\n return this.yearMonthCache.get(s2);\n }\n getYearWeek(s2) {\n if (!this.yearWeekCache.has(s2)) {\n this.yearWeekCache.set(s2, YearWeekClass.parse(s2, this));\n }\n return this.yearWeekCache.get(s2);\n }\n getYear(s2) {\n if (!this.yearCache.has(s2)) {\n this.yearCache.set(s2, YearClass.parse(s2, this));\n }\n return this.yearCache.get(s2);\n }\n static getInstance() {\n return this.instance;\n }\n };\n _TemporalCache.instance = new _TemporalCache();\n let TemporalCache = _TemporalCache;\n class YearMonthDayClass {\n constructor(yearNumber, monthNumber, dayNumber, cache) {\n this.yearNumber = yearNumber;\n this.monthNumber = monthNumber;\n this.dayNumber = dayNumber;\n this.cache = cache;\n this.type = "YearMonthDay";\n this.date = new Date(this.yearNumber, this.monthNumber - 1, this.dayNumber);\n this.dayjs = dayjs(this.date);\n this.dateString = this.toString();\n }\n get text() {\n return this.dayjs.format("YYYY-MM-DD");\n }\n toString() {\n return this.text;\n }\n englishName() {\n return this.dayjs.format("dddd, MMMM D, YYYY");\n }\n get firstDay() {\n return this;\n }\n get lastDay() {\n return this;\n }\n get year() {\n return this.cache.getYear(`${this.yearNumber}`);\n }\n get month() {\n return this.cache.getYearMonth(this.dayjs.format("YYYY-MM"));\n }\n get week() {\n return this.cache.getYearWeek(this.dayjs.format(FORMAT_ISO_WEEK_YEAR_WEEK));\n }\n addDays(days) {\n const date = this.dayjs.add(days, "day");\n const s2 = date.format("YYYY-MM-DD");\n return this.cache.getYearMonthDay(s2);\n }\n minus(other) {\n return this.dayjs.diff(other.dayjs, "day");\n }\n static parse(s2, cache) {\n const [year, month, day] = s2.split("-").map((s22) => parseInt(s22, 10));\n return new YearMonthDayClass(year, month, day, cache);\n }\n }\n class YearWeekClass {\n constructor(isoYearNumber, isoWeekNumber, cache) {\n this.isoYearNumber = isoYearNumber;\n this.isoWeekNumber = isoWeekNumber;\n this.cache = cache;\n this.type = "YearWeek";\n this.dateString = this.toString();\n }\n get text() {\n return this.firstDay.dayjs.format(FORMAT_ISO_WEEK_YEAR_WEEK);\n }\n toString() {\n return this.text;\n }\n englishName() {\n return `Week ${this.isoWeekNumber}, ${this.isoYearNumber}`;\n }\n get firstDay() {\n const firstDay = dayjs().year(this.isoYearNumber).month(1).date(4).isoWeek(this.isoWeekNumber).startOf("isoWeek");\n return this.cache.getYearMonthDay(firstDay.format("YYYY-MM-DD"));\n }\n get lastDay() {\n const firstDay = dayjs().year(this.isoYearNumber).startOf("year").add((this.isoWeekNumber - 1) * 7, "day").startOf("week").add(1, "day");\n const lastDay = firstDay.add(6, "day");\n return this.cache.getYearMonthDay(lastDay.format("YYYY-MM-DD"));\n }\n get year() {\n return this.cache.getYear(`${this.isoYearNumber}`);\n }\n addWeeks(weeks) {\n const date = this.firstDay.dayjs.add(weeks, "week");\n const s2 = date.format(FORMAT_ISO_WEEK_YEAR_WEEK);\n return this.cache.getYearWeek(s2);\n }\n minus(other) {\n return this.firstDay.dayjs.diff(other.firstDay.dayjs, "week");\n }\n static parse(s2, cache) {\n const [year, week] = s2.split("-W").map((s22) => parseInt(s22, 10));\n return new YearWeekClass(year, week, cache);\n }\n }\n class YearMonthClass {\n constructor(yearNumber, monthNumber, cache) {\n this.yearNumber = yearNumber;\n this.monthNumber = monthNumber;\n this.cache = cache;\n this.type = "YearMonth";\n this.dateString = this.toString();\n }\n get text() {\n return this.firstDay.dayjs.format("YYYY-MM");\n }\n toString() {\n return this.text;\n }\n englishName() {\n return `${monthName(this.monthNumber)} ${this.yearNumber}`;\n }\n get firstDay() {\n return this.cache.getYearMonthDay(dayjs(`${this.yearNumber}-${this.monthNumber}-01`).format("YYYY-MM-DD"));\n }\n get lastDay() {\n return this.cache.getYearMonthDay(\n dayjs(`${this.yearNumber}-${this.monthNumber}-01`).endOf("month").format("YYYY-MM-DD")\n );\n }\n get year() {\n return this.cache.getYear(`${this.yearNumber}`);\n }\n addMonths(months) {\n const date = this.firstDay.dayjs.add(months, "month");\n const s2 = date.format("YYYY-MM");\n return this.cache.getYearMonth(s2);\n }\n minus(other) {\n return this.firstDay.dayjs.diff(other.firstDay.dayjs, "month");\n }\n static parse(s2, cache) {\n const [year, month] = s2.split("-").map((s22) => parseInt(s22, 10));\n return new YearMonthClass(year, month, cache);\n }\n }\n class YearClass {\n constructor(year, cache) {\n this.year = year;\n this.cache = cache;\n this.type = "Year";\n this.dateString = this.toString();\n }\n get text() {\n return this.firstDay.dayjs.format("YYYY");\n }\n toString() {\n return this.text;\n }\n englishName() {\n return this.year.toString();\n }\n get firstMonth() {\n return this.cache.getYearMonth(`${this.year}-01`);\n }\n get lastMonth() {\n return this.cache.getYearMonth(`${this.year}-12`);\n }\n get firstDay() {\n return this.firstMonth.firstDay;\n }\n get lastDay() {\n return this.lastMonth.lastDay;\n }\n addYears(years) {\n const date = this.firstDay.dayjs.add(years, "year");\n const s2 = date.format("YYYY");\n return this.cache.getYear(s2);\n }\n minus(other) {\n return this.firstDay.dayjs.diff(other.firstDay.dayjs, "year");\n }\n static parse(s2, cache) {\n const year = parseInt(s2, 10);\n return new YearClass(year, cache);\n }\n }\n function monthName(month) {\n return dayjs().month(month - 1).format("MMMM");\n }\n function toTemporal(temporalClass) {\n switch (temporalClass.type) {\n case "YearMonthDay":\n return {\n type: "YearMonthDay",\n yearNumber: temporalClass.yearNumber,\n monthNumber: temporalClass.monthNumber,\n dayNumber: temporalClass.dayNumber,\n dateString: temporalClass.dateString\n };\n case "YearWeek":\n return {\n type: "YearWeek",\n isoYearNumber: temporalClass.isoYearNumber,\n isoWeekNumber: temporalClass.isoWeekNumber,\n dateString: temporalClass.dateString\n };\n case "YearMonth":\n return {\n type: "YearMonth",\n yearNumber: temporalClass.yearNumber,\n monthNumber: temporalClass.monthNumber,\n dateString: temporalClass.dateString\n };\n case "Year":\n return {\n type: "Year",\n year: temporalClass.year,\n dateString: temporalClass.dateString\n };\n }\n }\n function generateAllDaysInRange(start, end) {\n const days = [];\n const daysInBetween = end.minus(start);\n for (let i2 = 0; i2 <= daysInBetween; i2++) {\n days.push(start.addDays(i2));\n }\n return days;\n }\n function generateAllWeeksInRange(start, end) {\n const weeks = [];\n const weeksInBetween = end.minus(start);\n for (let i2 = 0; i2 <= weeksInBetween; i2++) {\n weeks.push(start.addWeeks(i2));\n }\n return weeks;\n }\n function generateAllMonthsInRange(start, end) {\n const months = [];\n const monthsInBetween = end.minus(start);\n for (let i2 = 0; i2 <= monthsInBetween; i2++) {\n months.push(start.addMonths(i2));\n }\n return months;\n }\n function generateAllYearsInRange(start, end) {\n const years = [];\n const yearsInBetween = end.minus(start);\n for (let i2 = 0; i2 <= yearsInBetween; i2++) {\n years.push(start.addYears(i2));\n }\n return years;\n }\n function generateAllInRange(start, end) {\n if (start === null || end === null) {\n return [];\n }\n if (start instanceof YearMonthDayClass && end instanceof YearMonthDayClass) {\n return generateAllDaysInRange(start, end);\n }\n if (start instanceof YearWeekClass && end instanceof YearWeekClass) {\n return generateAllWeeksInRange(start, end);\n }\n if (start instanceof YearMonthClass && end instanceof YearMonthClass) {\n return generateAllMonthsInRange(start, end);\n }\n if (start instanceof YearClass && end instanceof YearClass) {\n return generateAllYearsInRange(start, end);\n }\n throw new Error(`Invalid arguments: start and end must be of the same type: ${start}, ${end}`);\n }\n function minusTemporal(a2, b) {\n if (a2 instanceof YearMonthDayClass && b instanceof YearMonthDayClass) {\n return a2.minus(b);\n }\n if (a2 instanceof YearWeekClass && b instanceof YearWeekClass) {\n return a2.minus(b);\n }\n if (a2 instanceof YearMonthClass && b instanceof YearMonthClass) {\n return a2.minus(b);\n }\n if (a2 instanceof YearClass && b instanceof YearClass) {\n return a2.minus(b);\n }\n throw new Error(`Cannot compare ${a2} and ${b}`);\n }\n function compareTemporal(a2, b) {\n if (a2 === null) {\n return 1;\n }\n if (b === null) {\n return -1;\n }\n const diff = minusTemporal(a2, b);\n if (diff < 0) {\n return -1;\n }\n if (diff > 0) {\n return 1;\n }\n return 0;\n }\n function getMinMaxTemporal(values) {\n let min = null;\n let max = null;\n for (const value of values) {\n if (value === null) {\n continue;\n }\n if (min === null || compareTemporal(value, min) < 0) {\n min = value;\n }\n if (max === null || compareTemporal(value, max) > 0) {\n max = value;\n }\n }\n if (min === null || max === null) {\n return { min: null, max: null };\n }\n return { min, max };\n }\n function parseDateStringToTemporal(date, granularity) {\n const cache = TemporalCache.getInstance();\n const day = cache.getYearMonthDay(date);\n switch (granularity) {\n case "day":\n return day;\n case "week":\n return day.week;\n case "month":\n return day.month;\n case "year":\n return day.year;\n }\n }\n function dateRangeCompare(a2, b) {\n if (a2.dateRange === null) {\n return 1;\n }\n if (b.dateRange === null) {\n return -1;\n }\n return compareTemporal(a2.dateRange, b.dateRange);\n }\n function mapDateToGranularityRange(data, granularity) {\n return {\n dateRange: data.date === null ? null : parseDateStringToTemporal(data.date, granularity),\n count: data.count\n };\n }\n const substitutionRegex = /^((?<segment>[A-Z0-9_-]+)(?=:):)?(?<valueAtReference>[A-Z])?(?<position>\\d+)(?<substitutionValue>[A-Z.])?$/i;\n class SubstitutionClass {\n constructor(segment, valueAtReference, substitutionValue, position) {\n this.segment = segment;\n this.valueAtReference = valueAtReference;\n this.substitutionValue = substitutionValue;\n this.position = position;\n this.type = "substitution";\n const segmentString = this.segment ? `${this.segment}:` : "";\n const valueAtReferenceString = this.valueAtReference ? `${this.valueAtReference}` : "";\n const substitutionValueString = this.substitutionValue ? `${this.substitutionValue}` : "";\n this.code = `${segmentString}${valueAtReferenceString}${this.position}${substitutionValueString}`;\n }\n equals(other) {\n if (!(other instanceof SubstitutionClass)) {\n return false;\n }\n return this.segment === other.segment && this.valueAtReference === other.valueAtReference && this.substitutionValue === other.substitutionValue && this.position === other.position;\n }\n toString() {\n return this.code;\n }\n static parse(mutationStr) {\n const match = mutationStr.match(substitutionRegex);\n if (match === null || match.groups === void 0) {\n return null;\n }\n return new SubstitutionClass(\n match.groups.segment,\n match.groups.valueAtReference,\n match.groups.substitutionValue,\n parseInt(match.groups.position, 10)\n );\n }\n }\n const deletionRegex = /^((?<segment>[A-Z0-9_-]+)(?=:):)?(?<valueAtReference>[A-Z])?(?<position>\\d+)(-)$/i;\n class DeletionClass {\n constructor(segment, valueAtReference, position) {\n this.segment = segment;\n this.valueAtReference = valueAtReference;\n this.position = position;\n this.type = "deletion";\n const segmentString = this.segment ? `${this.segment}:` : "";\n const valueAtReferenceString = this.valueAtReference ? `${this.valueAtReference}` : "";\n this.code = `${segmentString}${valueAtReferenceString}${this.position}-`;\n }\n equals(other) {\n if (!(other instanceof DeletionClass)) {\n return false;\n }\n return this.segment === other.segment && this.valueAtReference === other.valueAtReference && this.position === other.position;\n }\n toString() {\n return this.code;\n }\n static parse(mutationStr) {\n const match = mutationStr.match(deletionRegex);\n if (match === null || match.groups === void 0) {\n return null;\n }\n return new DeletionClass(\n match.groups.segment,\n match.groups.valueAtReference,\n parseInt(match.groups.position, 10)\n );\n }\n }\n function toSubstitutionOrDeletion(mutation) {\n switch (mutation.type) {\n case "substitution":\n return {\n type: "substitution",\n code: mutation.code,\n segment: mutation.segment,\n position: mutation.position,\n valueAtReference: mutation.valueAtReference,\n substitutionValue: mutation.substitutionValue\n };\n case "deletion":\n return {\n type: "deletion",\n code: mutation.code,\n segment: mutation.segment,\n position: mutation.position,\n valueAtReference: mutation.valueAtReference\n };\n }\n }\n class FetchSubstitutionsOrDeletionsOperator {\n constructor(filter, sequenceType, minProportion) {\n this.filter = filter;\n this.sequenceType = sequenceType;\n this.minProportion = minProportion;\n }\n async evaluate(lapis, signal) {\n const mutations = await this.fetchMutations(lapis, signal);\n const content = mutations.map(\n ({ count, proportion, mutationFrom, mutationTo, position, sequenceName }) => {\n if (mutationTo === "-") {\n return {\n type: "deletion",\n mutation: new DeletionClass(sequenceName ?? void 0, mutationFrom, position),\n count,\n proportion\n };\n }\n return {\n type: "substitution",\n mutation: new SubstitutionClass(sequenceName ?? void 0, mutationFrom, mutationTo, position),\n count,\n proportion\n };\n }\n );\n return { content };\n }\n async fetchMutations(lapis, signal) {\n const filter = {\n ...this.filter,\n minProportion: this.minProportion\n };\n return fetchSubstitutionsOrDeletions(lapis, filter, this.sequenceType, signal).then(\n (response) => response.data\n );\n }\n }\n var l$1;\n l$1 = { __e: function(n, l2, u2, t) {\n for (var i2, r2, o; l2 = l2.__; ) if ((i2 = l2.__c) && !i2.__) try {\n if ((r2 = i2.constructor) && null != r2.getDerivedStateFromError && (i2.setState(r2.getDerivedStateFromError(n)), o = i2.__d), null != i2.componentDidCatch && (i2.componentDidCatch(n, t || {}), o = i2.__d), o) return i2.__E = i2;\n } catch (l3) {\n n = l3;\n }\n throw n;\n } }, "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout;\n var r, u, i, f = [], c = l$1, e = c.__b, a = c.__r, v = c.diffed, l = c.__c, m = c.unmount, s = c.__;\n function j() {\n for (var n; n = f.shift(); ) if (n.__P && n.__H) try {\n n.__H.__h.forEach(z), n.__H.__h.forEach(B), n.__H.__h = [];\n } catch (t) {\n n.__H.__h = [], c.__e(t, n.__v);\n }\n }\n c.__b = function(n) {\n r = null, e && e(n);\n }, c.__ = function(n, t) {\n n && t.__k && t.__k.__m && (n.__m = t.__k.__m), s && s(n, t);\n }, c.__r = function(n) {\n a && a(n);\n var i2 = (r = n.__c).__H;\n i2 && (u === r ? (i2.__h = [], r.__h = [], i2.__.forEach(function(n2) {\n n2.__N && (n2.__ = n2.__N), n2.i = n2.__N = void 0;\n })) : (i2.__h.forEach(z), i2.__h.forEach(B), i2.__h = [], 0)), u = r;\n }, c.diffed = function(n) {\n v && v(n);\n var t = n.__c;\n t && t.__H && (t.__H.__h.length && (1 !== f.push(t) && i === c.requestAnimationFrame || ((i = c.requestAnimationFrame) || w)(j)), t.__H.__.forEach(function(n2) {\n n2.i && (n2.__H = n2.i), n2.i = void 0;\n })), u = r = null;\n }, c.__c = function(n, t) {\n t.some(function(n2) {\n try {\n n2.__h.forEach(z), n2.__h = n2.__h.filter(function(n3) {\n return !n3.__ || B(n3);\n });\n } catch (r2) {\n t.some(function(n3) {\n n3.__h && (n3.__h = []);\n }), t = [], c.__e(r2, n2.__v);\n }\n }), l && l(n, t);\n }, c.unmount = function(n) {\n m && m(n);\n var t, r2 = n.__c;\n r2 && r2.__H && (r2.__H.__.forEach(function(n2) {\n try {\n z(n2);\n } catch (n3) {\n t = n3;\n }\n }), r2.__H = void 0, t && c.__e(t, r2.__v));\n };\n var k = "function" == typeof requestAnimationFrame;\n function w(n) {\n var t, r2 = function() {\n clearTimeout(u2), k && cancelAnimationFrame(t), setTimeout(n);\n }, u2 = setTimeout(r2, 100);\n k && (t = requestAnimationFrame(r2));\n }\n function z(n) {\n var t = r, u2 = n.__c;\n "function" == typeof u2 && (n.__c = void 0, u2()), r = t;\n }\n function B(n) {\n var t = r;\n n.__c = n.__(), r = t;\n }\n class UserFacingError extends Error {\n constructor(headline, message) {\n super(message);\n this.headline = headline;\n this.name = "UserFacingError";\n }\n }\n class Map2dBase {\n constructor(serializeFirstAxis, serializeSecondAxis, initialContent) {\n this.serializeFirstAxis = serializeFirstAxis;\n this.serializeSecondAxis = serializeSecondAxis;\n this.data = /* @__PURE__ */ new Map();\n this.keysFirstAxis = /* @__PURE__ */ new Map();\n this.keysSecondAxis = /* @__PURE__ */ new Map();\n if (initialContent) {\n this.keysFirstAxis = new Map(initialContent.keysFirstAxis);\n this.keysSecondAxis = new Map(initialContent.keysSecondAxis);\n this.data = new Map(initialContent.data);\n }\n }\n get(keyFirstAxis, keySecondAxis) {\n var _a;\n const serializedKeyFirstAxis = this.serializeFirstAxis(keyFirstAxis);\n const serializedKeySecondAxis = this.serializeSecondAxis(keySecondAxis);\n return (_a = this.data.get(serializedKeyFirstAxis)) == null ? void 0 : _a.get(serializedKeySecondAxis);\n }\n getRow(key) {\n const serializedKeyFirstAxis = this.serializeFirstAxis(key);\n const row = this.data.get(serializedKeyFirstAxis);\n if (row === void 0) {\n return [];\n }\n return Array.from(this.keysSecondAxis.keys()).map((key2) => row.get(key2));\n }\n set(keyFirstAxis, keySecondAxis, value) {\n const serializedKeyFirstAxis = this.serializeFirstAxis(keyFirstAxis);\n const serializedKeySecondAxis = this.serializeSecondAxis(keySecondAxis);\n if (!this.data.has(serializedKeyFirstAxis)) {\n this.data.set(serializedKeyFirstAxis, /* @__PURE__ */ new Map());\n }\n this.data.get(serializedKeyFirstAxis).set(serializedKeySecondAxis, value);\n this.keysFirstAxis.set(serializedKeyFirstAxis, keyFirstAxis);\n this.keysSecondAxis.set(serializedKeySecondAxis, keySecondAxis);\n }\n deleteRow(key) {\n const serializedKeyFirstAxis = this.serializeFirstAxis(key);\n this.data.delete(serializedKeyFirstAxis);\n this.keysFirstAxis.delete(serializedKeyFirstAxis);\n }\n getFirstAxisKeys() {\n return Array.from(this.keysFirstAxis.values());\n }\n getSecondAxisKeys() {\n return Array.from(this.keysSecondAxis.values());\n }\n getAsArray() {\n return this.getFirstAxisKeys().map((firstAxisKey) => {\n return this.getSecondAxisKeys().map((secondAxisKey) => {\n return this.get(firstAxisKey, secondAxisKey);\n });\n });\n }\n getContents() {\n return {\n keysFirstAxis: this.keysFirstAxis,\n keysSecondAxis: this.keysSecondAxis,\n data: this.data\n };\n }\n }\n class BaseMutationOverTimeDataMap extends Map2dBase {\n constructor(initialContent) {\n super(serializeSubstitutionOrDeletion, serializeTemporal, initialContent);\n }\n }\n const sortSubstitutionsAndDeletions = (a2, b) => {\n if (a2.segment !== b.segment) {\n return compareSegments(a2.segment, b.segment);\n }\n if (a2.position !== b.position) {\n return comparePositions(a2.position, b.position);\n }\n const aIsDeletion = a2 instanceof DeletionClass;\n const bIsDeletion = b instanceof DeletionClass;\n if (aIsDeletion !== bIsDeletion) {\n return aIsDeletion ? 1 : -1;\n }\n if (!aIsDeletion && !bIsDeletion) {\n if (a2.substitutionValue !== b.substitutionValue) {\n return compareSubstitutionValues(a2.substitutionValue, b.substitutionValue);\n }\n }\n return 0;\n };\n const compareSegments = (a2, b) => {\n if (a2 === void 0) {\n return -1;\n }\n if (b === void 0) {\n return 1;\n }\n return a2.localeCompare(b);\n };\n const comparePositions = (a2, b) => {\n return a2 - b;\n };\n const compareSubstitutionValues = (a2, b) => {\n if (a2 === void 0) {\n return -1;\n }\n if (b === void 0) {\n return 1;\n }\n return a2.localeCompare(b);\n };\n const MAX_NUMBER_OF_GRID_COLUMNS = 200;\n async function queryOverallMutationData({\n lapisFilter,\n sequenceType,\n lapis,\n granularity,\n lapisDateField,\n signal\n }) {\n const allDates = await getDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal);\n if (allDates.length === 0) {\n return {\n content: []\n };\n }\n const filter = {\n ...lapisFilter,\n [`${lapisDateField}From`]: allDates[0].firstDay.toString(),\n [`${lapisDateField}To`]: allDates[allDates.length - 1].lastDay.toString()\n };\n return fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType).evaluate(lapis, signal);\n }\n async function queryMutationsOverTimeData({\n lapisFilter,\n sequenceType,\n lapis,\n lapisDateField,\n granularity,\n signal\n }) {\n const allDates = await getDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal);\n if (allDates.length > MAX_NUMBER_OF_GRID_COLUMNS) {\n throw new UserFacingError(\n "Too many dates",\n `The dataset would contain ${allDates.length} date intervals. Please reduce the number to below ${MAX_NUMBER_OF_GRID_COLUMNS} to display the data. You can achieve this by either narrowing the date range in the provided LAPIS filter or by selecting a larger granularity.`\n );\n }\n const subQueries = allDates.map(async (date) => {\n const dateFrom = date.firstDay.toString();\n const dateTo = date.lastDay.toString();\n const filter = {\n ...lapisFilter,\n [`${lapisDateField}From`]: dateFrom,\n [`${lapisDateField}To`]: dateTo\n };\n const data2 = await fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType).evaluate(lapis, signal);\n const totalCountQuery = await getTotalNumberOfSequencesInDateRange(filter).evaluate(lapis, signal);\n return {\n date,\n mutations: data2.content,\n totalCount: totalCountQuery.content[0].count\n };\n });\n const data = await Promise.all(subQueries);\n const overallMutationsData = (await queryOverallMutationData({\n lapisFilter,\n sequenceType,\n lapis,\n lapisDateField,\n granularity\n })).content;\n return {\n mutationOverTimeData: groupByMutation(data, overallMutationsData),\n overallMutationData: overallMutationsData\n };\n }\n async function getDatesInDataset(lapisFilter, lapis, granularity, lapisDateField, signal) {\n const { content: availableDates } = await queryAvailableDates(\n lapisFilter,\n lapis,\n granularity,\n lapisDateField,\n signal\n );\n const { dateFrom, dateTo } = getDateRangeFromFilter(lapisFilter, lapisDateField, granularity);\n const { min, max } = getMinMaxTemporal(availableDates);\n return generateAllInRange(dateFrom ?? min, dateTo ?? max);\n }\n function getDateRangeFromFilter(lapisFilter, lapisDateField, granularity) {\n const valueFromFilter = lapisFilter[lapisDateField];\n if (valueFromFilter) {\n return {\n dateFrom: parseDateStringToTemporal(valueFromFilter, granularity),\n dateTo: parseDateStringToTemporal(valueFromFilter, granularity)\n };\n }\n const minFromFilter = lapisFilter[`${lapisDateField}From`];\n const maxFromFilter = lapisFilter[`${lapisDateField}To`];\n return {\n dateFrom: minFromFilter ? parseDateStringToTemporal(minFromFilter, granularity) : null,\n dateTo: maxFromFilter ? parseDateStringToTemporal(maxFromFilter, granularity) : null\n };\n }\n function queryAvailableDates(lapisFilter, lapis, granularity, lapisDateField, signal) {\n return fetchAndPrepareDates(lapisFilter, granularity, lapisDateField).evaluate(lapis, signal);\n }\n function fetchAndPrepareDates(filter, granularity, lapisDateField) {\n const fetchData = new FetchAggregatedOperator(filter, [lapisDateField]);\n const dataWithFixedDateKey = new RenameFieldOperator(fetchData, lapisDateField, "date");\n const mapData = new MapOperator(dataWithFixedDateKey, (data) => mapDateToGranularityRange(data, granularity));\n const groupByData = new GroupByAndSumOperator(mapData, "dateRange", "count");\n const sortData = new SortOperator(groupByData, dateRangeCompare);\n return new MapOperator(sortData, (data) => data.dateRange);\n }\n function fetchAndPrepareSubstitutionsOrDeletions(filter, sequenceType) {\n return new FetchSubstitutionsOrDeletionsOperator(filter, sequenceType, 1e-3);\n }\n function serializeSubstitutionOrDeletion(mutation) {\n return mutation.code;\n }\n function serializeTemporal(date) {\n return date.dateString;\n }\n function groupByMutation(data, overallMutationData) {\n const dataArray = new BaseMutationOverTimeDataMap();\n const allDates = data.map((mutationData) => mutationData.date);\n const sortedOverallMutationData = overallMutationData.sort((a2, b) => sortSubstitutionsAndDeletions(a2.mutation, b.mutation)).map((entry) => {\n return toSubstitutionOrDeletion(entry.mutation);\n });\n const sortedDates = allDates.sort((a2, b) => compareTemporal(a2, b)).map((date) => toTemporal(date));\n sortedOverallMutationData.forEach((mutationData) => {\n sortedDates.forEach((date) => {\n dataArray.set(mutationData, date, null);\n });\n });\n data.forEach((mutationData) => {\n mutationData.mutations.forEach((mutationEntry) => {\n const mutation = toSubstitutionOrDeletion(mutationEntry.mutation);\n const date = toTemporal(mutationData.date);\n if (dataArray.get(mutation, date) !== void 0) {\n dataArray.set(mutation, date, {\n count: mutationEntry.count,\n proportion: mutationEntry.proportion,\n totalCount: mutationData.totalCount\n });\n }\n });\n });\n return dataArray;\n }\n function getTotalNumberOfSequencesInDateRange(filter) {\n return new FetchAggregatedOperator(filter);\n }\n async function workerFunction(queryFunction) {\n try {\n postMessage({ status: "loading" });\n const workerResponse = await queryFunction();\n postMessage({\n status: "success",\n data: workerResponse\n });\n } catch (error) {\n postMessage(\n error instanceof UserFacingError ? {\n status: "error",\n userFacing: true,\n headline: error.headline,\n error\n } : {\n status: "error",\n userFacing: false,\n error: error instanceof Error ? error : new Error(`${error}`)\n }\n );\n }\n }\n async function getMutationOverTimeWorkerFunction(event) {\n const mutationOverTimeData = await queryMutationsOverTimeData(event.data);\n const workerResponse = {\n overallMutationData: mutationOverTimeData.overallMutationData,\n mutationOverTimeSerialized: mutationOverTimeData.mutationOverTimeData.getContents()\n };\n return workerResponse;\n }\n self.onmessage = async function(event) {\n await workerFunction(() => getMutationOverTimeWorkerFunction(event));\n };\n})();\n//# sourceMappingURL=mutationOverTimeWorker-BjjkMGzd.js.map\n';
|
|
8779
|
+
const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
|
|
8770
8780
|
function WorkerWrapper(options2) {
|
|
8771
8781
|
let objURL;
|
|
8772
8782
|
try {
|
|
@@ -8781,7 +8791,7 @@ function WorkerWrapper(options2) {
|
|
|
8781
8791
|
return worker;
|
|
8782
8792
|
} catch (e2) {
|
|
8783
8793
|
return new Worker(
|
|
8784
|
-
"data:text/javascript;
|
|
8794
|
+
"data:text/javascript;charset=utf-8," + encodeURIComponent(jsContent),
|
|
8785
8795
|
{
|
|
8786
8796
|
name: options2 == null ? void 0 : options2.name
|
|
8787
8797
|
}
|
|
@@ -9187,11 +9197,11 @@ function useWebWorker(messageToWorker, WorkerConstructor) {
|
|
|
9187
9197
|
}, [messageToWorker, worker]);
|
|
9188
9198
|
return { data, error, isLoading };
|
|
9189
9199
|
}
|
|
9190
|
-
const
|
|
9200
|
+
const mutationsOverTimeViewSchema = z$1.literal(views.grid);
|
|
9191
9201
|
const mutationOverTimeSchema = z$1.object({
|
|
9192
9202
|
lapisFilter: lapisFilterSchema,
|
|
9193
9203
|
sequenceType: sequenceTypeSchema,
|
|
9194
|
-
views: z$1.array(
|
|
9204
|
+
views: z$1.array(mutationsOverTimeViewSchema),
|
|
9195
9205
|
granularity: temporalGranularitySchema,
|
|
9196
9206
|
lapisDateField: z$1.string().min(1),
|
|
9197
9207
|
width: z$1.string(),
|
|
@@ -9276,7 +9286,7 @@ const MutationsOverTimeTabs = ({
|
|
|
9276
9286
|
};
|
|
9277
9287
|
const tabs = originalComponentProps.views.map((view) => getTab(view));
|
|
9278
9288
|
const toolbar = (activeTab) => /* @__PURE__ */ u$1(
|
|
9279
|
-
Toolbar,
|
|
9289
|
+
Toolbar$1,
|
|
9280
9290
|
{
|
|
9281
9291
|
activeTab,
|
|
9282
9292
|
displayedSegments,
|
|
@@ -9293,7 +9303,7 @@ const MutationsOverTimeTabs = ({
|
|
|
9293
9303
|
);
|
|
9294
9304
|
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
|
|
9295
9305
|
};
|
|
9296
|
-
const Toolbar = ({
|
|
9306
|
+
const Toolbar$1 = ({
|
|
9297
9307
|
activeTab,
|
|
9298
9308
|
displayedSegments,
|
|
9299
9309
|
setDisplayedSegments,
|
|
@@ -9368,14 +9378,14 @@ function getDownloadData(filteredData) {
|
|
|
9368
9378
|
);
|
|
9369
9379
|
});
|
|
9370
9380
|
}
|
|
9371
|
-
var __defProp$
|
|
9372
|
-
var __getOwnPropDesc$
|
|
9373
|
-
var __decorateClass$
|
|
9374
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$
|
|
9381
|
+
var __defProp$7 = Object.defineProperty;
|
|
9382
|
+
var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
|
|
9383
|
+
var __decorateClass$7 = (decorators, target, key, kind) => {
|
|
9384
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
|
|
9375
9385
|
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
9376
9386
|
if (decorator = decorators[i2])
|
|
9377
9387
|
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
9378
|
-
if (kind && result) __defProp$
|
|
9388
|
+
if (kind && result) __defProp$7(target, key, result);
|
|
9379
9389
|
return result;
|
|
9380
9390
|
};
|
|
9381
9391
|
let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
@@ -9404,30 +9414,1047 @@ let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
|
|
|
9404
9414
|
);
|
|
9405
9415
|
}
|
|
9406
9416
|
};
|
|
9407
|
-
__decorateClass$
|
|
9417
|
+
__decorateClass$7([
|
|
9408
9418
|
n2({ type: Object })
|
|
9409
9419
|
], MutationsOverTimeComponent.prototype, "lapisFilter", 2);
|
|
9410
|
-
__decorateClass$
|
|
9420
|
+
__decorateClass$7([
|
|
9411
9421
|
n2({ type: String })
|
|
9412
9422
|
], MutationsOverTimeComponent.prototype, "sequenceType", 2);
|
|
9413
|
-
__decorateClass$
|
|
9423
|
+
__decorateClass$7([
|
|
9414
9424
|
n2({ type: Array })
|
|
9415
9425
|
], MutationsOverTimeComponent.prototype, "views", 2);
|
|
9416
|
-
__decorateClass$
|
|
9426
|
+
__decorateClass$7([
|
|
9417
9427
|
n2({ type: String })
|
|
9418
9428
|
], MutationsOverTimeComponent.prototype, "width", 2);
|
|
9419
|
-
__decorateClass$
|
|
9429
|
+
__decorateClass$7([
|
|
9420
9430
|
n2({ type: String })
|
|
9421
9431
|
], MutationsOverTimeComponent.prototype, "height", 2);
|
|
9422
|
-
__decorateClass$
|
|
9432
|
+
__decorateClass$7([
|
|
9423
9433
|
n2({ type: String })
|
|
9424
9434
|
], MutationsOverTimeComponent.prototype, "granularity", 2);
|
|
9425
|
-
__decorateClass$
|
|
9435
|
+
__decorateClass$7([
|
|
9426
9436
|
n2({ type: String })
|
|
9427
9437
|
], MutationsOverTimeComponent.prototype, "lapisDateField", 2);
|
|
9428
|
-
MutationsOverTimeComponent = __decorateClass$
|
|
9438
|
+
MutationsOverTimeComponent = __decorateClass$7([
|
|
9429
9439
|
t$2("gs-mutations-over-time")
|
|
9430
9440
|
], MutationsOverTimeComponent);
|
|
9441
|
+
const leafletStyle = `/* required styles */\r
|
|
9442
|
+
\r
|
|
9443
|
+
.leaflet-pane,\r
|
|
9444
|
+
.leaflet-tile,\r
|
|
9445
|
+
.leaflet-marker-icon,\r
|
|
9446
|
+
.leaflet-marker-shadow,\r
|
|
9447
|
+
.leaflet-tile-container,\r
|
|
9448
|
+
.leaflet-pane > svg,\r
|
|
9449
|
+
.leaflet-pane > canvas,\r
|
|
9450
|
+
.leaflet-zoom-box,\r
|
|
9451
|
+
.leaflet-image-layer,\r
|
|
9452
|
+
.leaflet-layer {\r
|
|
9453
|
+
position: absolute;\r
|
|
9454
|
+
left: 0;\r
|
|
9455
|
+
top: 0;\r
|
|
9456
|
+
}\r
|
|
9457
|
+
.leaflet-container {\r
|
|
9458
|
+
overflow: hidden;\r
|
|
9459
|
+
}\r
|
|
9460
|
+
.leaflet-tile,\r
|
|
9461
|
+
.leaflet-marker-icon,\r
|
|
9462
|
+
.leaflet-marker-shadow {\r
|
|
9463
|
+
-webkit-user-select: none;\r
|
|
9464
|
+
-moz-user-select: none;\r
|
|
9465
|
+
user-select: none;\r
|
|
9466
|
+
-webkit-user-drag: none;\r
|
|
9467
|
+
}\r
|
|
9468
|
+
/* Prevents IE11 from highlighting tiles in blue */\r
|
|
9469
|
+
.leaflet-tile::-moz-selection {\r
|
|
9470
|
+
background: transparent;\r
|
|
9471
|
+
}\r
|
|
9472
|
+
.leaflet-tile::selection {\r
|
|
9473
|
+
background: transparent;\r
|
|
9474
|
+
}\r
|
|
9475
|
+
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */\r
|
|
9476
|
+
.leaflet-safari .leaflet-tile {\r
|
|
9477
|
+
image-rendering: -webkit-optimize-contrast;\r
|
|
9478
|
+
}\r
|
|
9479
|
+
/* hack that prevents hw layers "stretching" when loading new tiles */\r
|
|
9480
|
+
.leaflet-safari .leaflet-tile-container {\r
|
|
9481
|
+
width: 1600px;\r
|
|
9482
|
+
height: 1600px;\r
|
|
9483
|
+
-webkit-transform-origin: 0 0;\r
|
|
9484
|
+
}\r
|
|
9485
|
+
.leaflet-marker-icon,\r
|
|
9486
|
+
.leaflet-marker-shadow {\r
|
|
9487
|
+
display: block;\r
|
|
9488
|
+
}\r
|
|
9489
|
+
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */\r
|
|
9490
|
+
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */\r
|
|
9491
|
+
.leaflet-container .leaflet-overlay-pane svg {\r
|
|
9492
|
+
max-width: none !important;\r
|
|
9493
|
+
max-height: none !important;\r
|
|
9494
|
+
}\r
|
|
9495
|
+
.leaflet-container .leaflet-marker-pane img,\r
|
|
9496
|
+
.leaflet-container .leaflet-shadow-pane img,\r
|
|
9497
|
+
.leaflet-container .leaflet-tile-pane img,\r
|
|
9498
|
+
.leaflet-container img.leaflet-image-layer,\r
|
|
9499
|
+
.leaflet-container .leaflet-tile {\r
|
|
9500
|
+
max-width: none !important;\r
|
|
9501
|
+
max-height: none !important;\r
|
|
9502
|
+
width: auto;\r
|
|
9503
|
+
padding: 0;\r
|
|
9504
|
+
}\r
|
|
9505
|
+
\r
|
|
9506
|
+
.leaflet-container img.leaflet-tile {\r
|
|
9507
|
+
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */\r
|
|
9508
|
+
mix-blend-mode: plus-lighter;\r
|
|
9509
|
+
}\r
|
|
9510
|
+
\r
|
|
9511
|
+
.leaflet-container.leaflet-touch-zoom {\r
|
|
9512
|
+
touch-action: pan-x pan-y;\r
|
|
9513
|
+
}\r
|
|
9514
|
+
.leaflet-container.leaflet-touch-drag {\r
|
|
9515
|
+
/* Fallback for FF which doesn't support pinch-zoom */\r
|
|
9516
|
+
touch-action: none;\r
|
|
9517
|
+
touch-action: pinch-zoom;\r
|
|
9518
|
+
}\r
|
|
9519
|
+
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {\r
|
|
9520
|
+
touch-action: none;\r
|
|
9521
|
+
}\r
|
|
9522
|
+
.leaflet-container {\r
|
|
9523
|
+
-webkit-tap-highlight-color: transparent;\r
|
|
9524
|
+
}\r
|
|
9525
|
+
.leaflet-container a {\r
|
|
9526
|
+
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);\r
|
|
9527
|
+
}\r
|
|
9528
|
+
.leaflet-tile {\r
|
|
9529
|
+
filter: inherit;\r
|
|
9530
|
+
visibility: hidden;\r
|
|
9531
|
+
}\r
|
|
9532
|
+
.leaflet-tile-loaded {\r
|
|
9533
|
+
visibility: inherit;\r
|
|
9534
|
+
}\r
|
|
9535
|
+
.leaflet-zoom-box {\r
|
|
9536
|
+
width: 0;\r
|
|
9537
|
+
height: 0;\r
|
|
9538
|
+
box-sizing: border-box;\r
|
|
9539
|
+
z-index: 800;\r
|
|
9540
|
+
}\r
|
|
9541
|
+
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */\r
|
|
9542
|
+
.leaflet-overlay-pane svg {\r
|
|
9543
|
+
-moz-user-select: none;\r
|
|
9544
|
+
}\r
|
|
9545
|
+
\r
|
|
9546
|
+
.leaflet-pane { z-index: 400; }\r
|
|
9547
|
+
\r
|
|
9548
|
+
.leaflet-tile-pane { z-index: 200; }\r
|
|
9549
|
+
.leaflet-overlay-pane { z-index: 400; }\r
|
|
9550
|
+
.leaflet-shadow-pane { z-index: 500; }\r
|
|
9551
|
+
.leaflet-marker-pane { z-index: 600; }\r
|
|
9552
|
+
.leaflet-tooltip-pane { z-index: 650; }\r
|
|
9553
|
+
.leaflet-popup-pane { z-index: 700; }\r
|
|
9554
|
+
\r
|
|
9555
|
+
.leaflet-map-pane canvas { z-index: 100; }\r
|
|
9556
|
+
.leaflet-map-pane svg { z-index: 200; }\r
|
|
9557
|
+
\r
|
|
9558
|
+
.leaflet-vml-shape {\r
|
|
9559
|
+
width: 1px;\r
|
|
9560
|
+
height: 1px;\r
|
|
9561
|
+
}\r
|
|
9562
|
+
.lvml {\r
|
|
9563
|
+
behavior: url(#default#VML);\r
|
|
9564
|
+
display: inline-block;\r
|
|
9565
|
+
position: absolute;\r
|
|
9566
|
+
}\r
|
|
9567
|
+
\r
|
|
9568
|
+
\r
|
|
9569
|
+
/* control positioning */\r
|
|
9570
|
+
\r
|
|
9571
|
+
.leaflet-control {\r
|
|
9572
|
+
position: relative;\r
|
|
9573
|
+
z-index: 800;\r
|
|
9574
|
+
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */\r
|
|
9575
|
+
pointer-events: auto;\r
|
|
9576
|
+
}\r
|
|
9577
|
+
.leaflet-top,\r
|
|
9578
|
+
.leaflet-bottom {\r
|
|
9579
|
+
position: absolute;\r
|
|
9580
|
+
z-index: 1000;\r
|
|
9581
|
+
pointer-events: none;\r
|
|
9582
|
+
}\r
|
|
9583
|
+
.leaflet-top {\r
|
|
9584
|
+
top: 0;\r
|
|
9585
|
+
}\r
|
|
9586
|
+
.leaflet-right {\r
|
|
9587
|
+
right: 0;\r
|
|
9588
|
+
}\r
|
|
9589
|
+
.leaflet-bottom {\r
|
|
9590
|
+
bottom: 0;\r
|
|
9591
|
+
}\r
|
|
9592
|
+
.leaflet-left {\r
|
|
9593
|
+
left: 0;\r
|
|
9594
|
+
}\r
|
|
9595
|
+
.leaflet-control {\r
|
|
9596
|
+
float: left;\r
|
|
9597
|
+
clear: both;\r
|
|
9598
|
+
}\r
|
|
9599
|
+
.leaflet-right .leaflet-control {\r
|
|
9600
|
+
float: right;\r
|
|
9601
|
+
}\r
|
|
9602
|
+
.leaflet-top .leaflet-control {\r
|
|
9603
|
+
margin-top: 10px;\r
|
|
9604
|
+
}\r
|
|
9605
|
+
.leaflet-bottom .leaflet-control {\r
|
|
9606
|
+
margin-bottom: 10px;\r
|
|
9607
|
+
}\r
|
|
9608
|
+
.leaflet-left .leaflet-control {\r
|
|
9609
|
+
margin-left: 10px;\r
|
|
9610
|
+
}\r
|
|
9611
|
+
.leaflet-right .leaflet-control {\r
|
|
9612
|
+
margin-right: 10px;\r
|
|
9613
|
+
}\r
|
|
9614
|
+
\r
|
|
9615
|
+
\r
|
|
9616
|
+
/* zoom and fade animations */\r
|
|
9617
|
+
\r
|
|
9618
|
+
.leaflet-fade-anim .leaflet-popup {\r
|
|
9619
|
+
opacity: 0;\r
|
|
9620
|
+
transition: opacity 0.2s linear;\r
|
|
9621
|
+
}\r
|
|
9622
|
+
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {\r
|
|
9623
|
+
opacity: 1;\r
|
|
9624
|
+
}\r
|
|
9625
|
+
.leaflet-zoom-animated {\r
|
|
9626
|
+
transform-origin: 0 0;\r
|
|
9627
|
+
}\r
|
|
9628
|
+
svg.leaflet-zoom-animated {\r
|
|
9629
|
+
will-change: transform;\r
|
|
9630
|
+
}\r
|
|
9631
|
+
\r
|
|
9632
|
+
.leaflet-zoom-anim .leaflet-zoom-animated {\r
|
|
9633
|
+
transition: transform 0.25s cubic-bezier(0,0,0.25,1);\r
|
|
9634
|
+
}\r
|
|
9635
|
+
.leaflet-zoom-anim .leaflet-tile,\r
|
|
9636
|
+
.leaflet-pan-anim .leaflet-tile {\r
|
|
9637
|
+
transition: none;\r
|
|
9638
|
+
}\r
|
|
9639
|
+
\r
|
|
9640
|
+
.leaflet-zoom-anim .leaflet-zoom-hide {\r
|
|
9641
|
+
visibility: hidden;\r
|
|
9642
|
+
}\r
|
|
9643
|
+
\r
|
|
9644
|
+
\r
|
|
9645
|
+
/* cursors */\r
|
|
9646
|
+
\r
|
|
9647
|
+
.leaflet-interactive {\r
|
|
9648
|
+
cursor: pointer;\r
|
|
9649
|
+
}\r
|
|
9650
|
+
.leaflet-grab {\r
|
|
9651
|
+
cursor: grab;\r
|
|
9652
|
+
}\r
|
|
9653
|
+
.leaflet-crosshair,\r
|
|
9654
|
+
.leaflet-crosshair .leaflet-interactive {\r
|
|
9655
|
+
cursor: crosshair;\r
|
|
9656
|
+
}\r
|
|
9657
|
+
.leaflet-popup-pane,\r
|
|
9658
|
+
.leaflet-control {\r
|
|
9659
|
+
cursor: auto;\r
|
|
9660
|
+
}\r
|
|
9661
|
+
.leaflet-dragging .leaflet-grab,\r
|
|
9662
|
+
.leaflet-dragging .leaflet-grab .leaflet-interactive,\r
|
|
9663
|
+
.leaflet-dragging .leaflet-marker-draggable {\r
|
|
9664
|
+
cursor: move;\r
|
|
9665
|
+
cursor: grabbing;\r
|
|
9666
|
+
}\r
|
|
9667
|
+
\r
|
|
9668
|
+
/* marker & overlays interactivity */\r
|
|
9669
|
+
.leaflet-marker-icon,\r
|
|
9670
|
+
.leaflet-marker-shadow,\r
|
|
9671
|
+
.leaflet-image-layer,\r
|
|
9672
|
+
.leaflet-pane > svg path,\r
|
|
9673
|
+
.leaflet-tile-container {\r
|
|
9674
|
+
pointer-events: none;\r
|
|
9675
|
+
}\r
|
|
9676
|
+
\r
|
|
9677
|
+
.leaflet-marker-icon.leaflet-interactive,\r
|
|
9678
|
+
.leaflet-image-layer.leaflet-interactive,\r
|
|
9679
|
+
.leaflet-pane > svg path.leaflet-interactive,\r
|
|
9680
|
+
svg.leaflet-image-layer.leaflet-interactive path {\r
|
|
9681
|
+
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */\r
|
|
9682
|
+
pointer-events: auto;\r
|
|
9683
|
+
}\r
|
|
9684
|
+
\r
|
|
9685
|
+
/* visual tweaks */\r
|
|
9686
|
+
\r
|
|
9687
|
+
.leaflet-container {\r
|
|
9688
|
+
background: #ddd;\r
|
|
9689
|
+
outline-offset: 1px;\r
|
|
9690
|
+
}\r
|
|
9691
|
+
.leaflet-container a {\r
|
|
9692
|
+
color: #0078A8;\r
|
|
9693
|
+
}\r
|
|
9694
|
+
.leaflet-zoom-box {\r
|
|
9695
|
+
border: 2px dotted #38f;\r
|
|
9696
|
+
background: rgba(255,255,255,0.5);\r
|
|
9697
|
+
}\r
|
|
9698
|
+
\r
|
|
9699
|
+
\r
|
|
9700
|
+
/* general typography */\r
|
|
9701
|
+
.leaflet-container {\r
|
|
9702
|
+
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;\r
|
|
9703
|
+
font-size: 12px;\r
|
|
9704
|
+
font-size: 0.75rem;\r
|
|
9705
|
+
line-height: 1.5;\r
|
|
9706
|
+
}\r
|
|
9707
|
+
\r
|
|
9708
|
+
\r
|
|
9709
|
+
/* general toolbar styles */\r
|
|
9710
|
+
\r
|
|
9711
|
+
.leaflet-bar {\r
|
|
9712
|
+
box-shadow: 0 1px 5px rgba(0,0,0,0.65);\r
|
|
9713
|
+
border-radius: 4px;\r
|
|
9714
|
+
}\r
|
|
9715
|
+
.leaflet-bar a {\r
|
|
9716
|
+
background-color: #fff;\r
|
|
9717
|
+
border-bottom: 1px solid #ccc;\r
|
|
9718
|
+
width: 26px;\r
|
|
9719
|
+
height: 26px;\r
|
|
9720
|
+
line-height: 26px;\r
|
|
9721
|
+
display: block;\r
|
|
9722
|
+
text-align: center;\r
|
|
9723
|
+
text-decoration: none;\r
|
|
9724
|
+
color: black;\r
|
|
9725
|
+
}\r
|
|
9726
|
+
.leaflet-bar a,\r
|
|
9727
|
+
.leaflet-control-layers-toggle {\r
|
|
9728
|
+
background-position: 50% 50%;\r
|
|
9729
|
+
background-repeat: no-repeat;\r
|
|
9730
|
+
display: block;\r
|
|
9731
|
+
}\r
|
|
9732
|
+
.leaflet-bar a:hover,\r
|
|
9733
|
+
.leaflet-bar a:focus {\r
|
|
9734
|
+
background-color: #f4f4f4;\r
|
|
9735
|
+
}\r
|
|
9736
|
+
.leaflet-bar a:first-child {\r
|
|
9737
|
+
border-top-left-radius: 4px;\r
|
|
9738
|
+
border-top-right-radius: 4px;\r
|
|
9739
|
+
}\r
|
|
9740
|
+
.leaflet-bar a:last-child {\r
|
|
9741
|
+
border-bottom-left-radius: 4px;\r
|
|
9742
|
+
border-bottom-right-radius: 4px;\r
|
|
9743
|
+
border-bottom: none;\r
|
|
9744
|
+
}\r
|
|
9745
|
+
.leaflet-bar a.leaflet-disabled {\r
|
|
9746
|
+
cursor: default;\r
|
|
9747
|
+
background-color: #f4f4f4;\r
|
|
9748
|
+
color: #bbb;\r
|
|
9749
|
+
}\r
|
|
9750
|
+
\r
|
|
9751
|
+
.leaflet-touch .leaflet-bar a {\r
|
|
9752
|
+
width: 30px;\r
|
|
9753
|
+
height: 30px;\r
|
|
9754
|
+
line-height: 30px;\r
|
|
9755
|
+
}\r
|
|
9756
|
+
.leaflet-touch .leaflet-bar a:first-child {\r
|
|
9757
|
+
border-top-left-radius: 2px;\r
|
|
9758
|
+
border-top-right-radius: 2px;\r
|
|
9759
|
+
}\r
|
|
9760
|
+
.leaflet-touch .leaflet-bar a:last-child {\r
|
|
9761
|
+
border-bottom-left-radius: 2px;\r
|
|
9762
|
+
border-bottom-right-radius: 2px;\r
|
|
9763
|
+
}\r
|
|
9764
|
+
\r
|
|
9765
|
+
/* zoom control */\r
|
|
9766
|
+
\r
|
|
9767
|
+
.leaflet-control-zoom-in,\r
|
|
9768
|
+
.leaflet-control-zoom-out {\r
|
|
9769
|
+
font: bold 18px 'Lucida Console', Monaco, monospace;\r
|
|
9770
|
+
text-indent: 1px;\r
|
|
9771
|
+
}\r
|
|
9772
|
+
\r
|
|
9773
|
+
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {\r
|
|
9774
|
+
font-size: 22px;\r
|
|
9775
|
+
}\r
|
|
9776
|
+
\r
|
|
9777
|
+
\r
|
|
9778
|
+
/* layers control */\r
|
|
9779
|
+
\r
|
|
9780
|
+
.leaflet-control-layers {\r
|
|
9781
|
+
box-shadow: 0 1px 5px rgba(0,0,0,0.4);\r
|
|
9782
|
+
background: #fff;\r
|
|
9783
|
+
border-radius: 5px;\r
|
|
9784
|
+
}\r
|
|
9785
|
+
.leaflet-control-layers-toggle {\r
|
|
9786
|
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAQAAAADQ4RFAAACf0lEQVR4AY1UM3gkARTePdvdoTxXKc+qTl3aU5U6b2Kbkz3Gtq3Zw6ziLGNPzrYx7946Tr6/ee/XeCQ4D3ykPtL5tHno4n0d/h3+xfuWHGLX81cn7r0iTNzjr7LrlxCqPtkbTQEHeqOrTy4Yyt3VCi/IOB0v7rVC7q45Q3Gr5K6jt+3Gl5nCoDD4MtO+j96Wu8atmhGqcNGHObuf8OM/x3AMx38+4Z2sPqzCxRFK2aF2e5Jol56XTLyggAMTL56XOMoS1W4pOyjUcGGQdZxU6qRh7B9Zp+PfpOFlqt0zyDZckPi1ttmIp03jX8gyJ8a/PG2yutpS/Vol7peZIbZcKBAEEheEIAgFbDkz5H6Zrkm2hVWGiXKiF4Ycw0RWKdtC16Q7qe3X4iOMxruonzegJzWaXFrU9utOSsLUmrc0YjeWYjCW4PDMADElpJSSQ0vQvA1Tm6/JlKnqFs1EGyZiFCqnRZTEJJJiKRYzVYzJck2Rm6P4iH+cmSY0YzimYa8l0EtTODFWhcMIMVqdsI2uiTvKmTisIDHJ3od5GILVhBCarCfVRmo4uTjkhrhzkiBV7SsaqS+TzrzM1qpGGUFt28pIySQHR6h7F6KSwGWm97ay+Z+ZqMcEjEWebE7wxCSQwpkhJqoZA5ivCdZDjJepuJ9IQjGGUmuXJdBFUygxVqVsxFsLMbDe8ZbDYVCGKxs+W080max1hFCarCfV+C1KATwcnvE9gRRuMP2prdbWGowm1KB1y+zwMMENkM755cJ2yPDtqhTI6ED1M/82yIDtC/4j4BijjeObflpO9I9MwXTCsSX8jWAFeHr05WoLTJ5G8IQVS/7vwR6ohirYM7f6HzYpogfS3R2OAAAAAElFTkSuQmCC);\r
|
|
9787
|
+
width: 36px;\r
|
|
9788
|
+
height: 36px;\r
|
|
9789
|
+
}\r
|
|
9790
|
+
.leaflet-retina .leaflet-control-layers-toggle {\r
|
|
9791
|
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADQAAAA0CAQAAABvcdNgAAAEsklEQVR4AWL4TydIhpZK1kpWOlg0w3ZXP6D2soBtG42jeI6ZmQTHzAxiTbSJsYLjO9HhP+WOmcuhciVnmHVQcJnp7DFvScowZorad/+V/fVzMdMT2g9Cv9guXGv/7pYOrXh2U+RRR3dSd9JRx6bIFc/ekqHI29JC6pJ5ZEh1yWkhkbcFeSjxgx3L2m1cb1C7bceyxA+CNjT/Ifff+/kDk2u/w/33/IeCMOSaWZ4glosqT3DNnNZQ7Cs58/3Ce5HL78iZH/vKVIaYlqzfdLu8Vi7dnvUbEza5Idt36tquZFldl6N5Z/POLof0XLK61mZCmJSWjVF9tEjUluu74IUXvgttuVIHE7YxSkaYhJZam7yiM9Pv82JYfl9nptxZaxMJE4YSPty+vF0+Y2up9d3wwijfjZbabqm/3bZ9ecKHsiGmRflnn1MW4pjHf9oLufyn2z3y1D6n8g8TZhxyzipLNPnAUpsOiuWimg52psrTZYnOWYNDTMuWBWa0tJb4rgq1UvmutpaYEbZlwU3CLJm/ayYjHW5/h7xWLn9Hh1vepDkyf7dE7MtT5LR4e7yYpHrkhOUpEfssBLq2pPhAqoSWKUkk7EDqkmK6RrCEzqDjhNDWNE+XSMvkJRDWlZTmCW0l0PHQGRZY5t1L83kT0Y3l2SItk5JAWHl2dCOBm+fPu3fo5/3v61RMCO9Jx2EEYYhb0rmNQMX/vm7gqOEJLcXTGw3CAuRNeyaPWwjR8PRqKQ1PDA/dpv+on9Shox52WFnx0KY8onHayrJzm87i5h9xGw/tfkev0jGsQizqezUKjk12hBMKJ4kbCqGPVNXudyyrShovGw5CgxsRICxF6aRmSjlBnHRzg7Gx8fKqEubI2rahQYdR1YgDIRQO7JvQyD52hoIQx0mxa0ODtW2Iozn1le2iIRdzwWewedyZzewidueOGqlsn1MvcnQpuVwLGG3/IR1hIKxCjelIDZ8ldqWz25jWAsnldEnK0Zxro19TGVb2ffIZEsIO89EIEDvKMPrzmBOQcKQ+rroye6NgRRxqR4U8EAkz0CL6uSGOm6KQCdWjvjRiSP1BPalCRS5iQYiEIvxuBMJEWgzSoHADcVMuN7IuqqTeyUPq22qFimFtxDyBBJEwNyt6TM88blFHao/6tWWhuuOM4SAK4EI4QmFHA+SEyWlp4EQoJ13cYGzMu7yszEIBOm2rVmHUNqwAIQabISNMRstmdhNWcFLsSm+0tjJH1MdRxO5Nx0WDMhCtgD6OKgZeljJqJKc9po8juskR9XN0Y1lZ3mWjLR9JCO1jRDMd0fpYC2VnvjBSEFg7wBENc0R9HFlb0xvF1+TBEpF68d+DHR6IOWVv2BECtxo46hOFUBd/APU57WIoEwJhIi2CdpyZX0m93BZicktMj1AS9dClteUFAUNUIEygRZCtik5zSxI9MubTBH1GOiHsiLJ3OCoSZkILa9PxiN0EbvhsAo8tdAf9Seepd36lGWHmtNANTv5Jd0z4QYyeo/UEJqxKRpg5LZx6btLPsOaEmdMyxYdlc8LMaJnikDlhclqmPiQnTEpLUIZEwkRagjYkEibQErwhkTAKCLQEbUgkzJQWc/0PstHHcfEdQ+UAAAAASUVORK5CYII=);\r
|
|
9792
|
+
background-size: 26px 26px;\r
|
|
9793
|
+
}\r
|
|
9794
|
+
.leaflet-touch .leaflet-control-layers-toggle {\r
|
|
9795
|
+
width: 44px;\r
|
|
9796
|
+
height: 44px;\r
|
|
9797
|
+
}\r
|
|
9798
|
+
.leaflet-control-layers .leaflet-control-layers-list,\r
|
|
9799
|
+
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {\r
|
|
9800
|
+
display: none;\r
|
|
9801
|
+
}\r
|
|
9802
|
+
.leaflet-control-layers-expanded .leaflet-control-layers-list {\r
|
|
9803
|
+
display: block;\r
|
|
9804
|
+
position: relative;\r
|
|
9805
|
+
}\r
|
|
9806
|
+
.leaflet-control-layers-expanded {\r
|
|
9807
|
+
padding: 6px 10px 6px 6px;\r
|
|
9808
|
+
color: #333;\r
|
|
9809
|
+
background: #fff;\r
|
|
9810
|
+
}\r
|
|
9811
|
+
.leaflet-control-layers-scrollbar {\r
|
|
9812
|
+
overflow-y: scroll;\r
|
|
9813
|
+
overflow-x: hidden;\r
|
|
9814
|
+
padding-right: 5px;\r
|
|
9815
|
+
}\r
|
|
9816
|
+
.leaflet-control-layers-selector {\r
|
|
9817
|
+
margin-top: 2px;\r
|
|
9818
|
+
position: relative;\r
|
|
9819
|
+
top: 1px;\r
|
|
9820
|
+
}\r
|
|
9821
|
+
.leaflet-control-layers label {\r
|
|
9822
|
+
display: block;\r
|
|
9823
|
+
font-size: 13px;\r
|
|
9824
|
+
font-size: 1.08333em;\r
|
|
9825
|
+
}\r
|
|
9826
|
+
.leaflet-control-layers-separator {\r
|
|
9827
|
+
height: 0;\r
|
|
9828
|
+
border-top: 1px solid #ddd;\r
|
|
9829
|
+
margin: 5px -10px 5px -6px;\r
|
|
9830
|
+
}\r
|
|
9831
|
+
\r
|
|
9832
|
+
/* Default icon URLs */\r
|
|
9833
|
+
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */\r
|
|
9834
|
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII=);\r
|
|
9835
|
+
}\r
|
|
9836
|
+
\r
|
|
9837
|
+
\r
|
|
9838
|
+
/* attribution and scale controls */\r
|
|
9839
|
+
\r
|
|
9840
|
+
.leaflet-container .leaflet-control-attribution {\r
|
|
9841
|
+
background: #fff;\r
|
|
9842
|
+
background: rgba(255, 255, 255, 0.8);\r
|
|
9843
|
+
margin: 0;\r
|
|
9844
|
+
}\r
|
|
9845
|
+
.leaflet-control-attribution,\r
|
|
9846
|
+
.leaflet-control-scale-line {\r
|
|
9847
|
+
padding: 0 5px;\r
|
|
9848
|
+
color: #333;\r
|
|
9849
|
+
line-height: 1.4;\r
|
|
9850
|
+
}\r
|
|
9851
|
+
.leaflet-control-attribution a {\r
|
|
9852
|
+
text-decoration: none;\r
|
|
9853
|
+
}\r
|
|
9854
|
+
.leaflet-control-attribution a:hover,\r
|
|
9855
|
+
.leaflet-control-attribution a:focus {\r
|
|
9856
|
+
text-decoration: underline;\r
|
|
9857
|
+
}\r
|
|
9858
|
+
.leaflet-attribution-flag {\r
|
|
9859
|
+
display: inline !important;\r
|
|
9860
|
+
vertical-align: baseline !important;\r
|
|
9861
|
+
width: 1em;\r
|
|
9862
|
+
height: 0.6669em;\r
|
|
9863
|
+
}\r
|
|
9864
|
+
.leaflet-left .leaflet-control-scale {\r
|
|
9865
|
+
margin-left: 5px;\r
|
|
9866
|
+
}\r
|
|
9867
|
+
.leaflet-bottom .leaflet-control-scale {\r
|
|
9868
|
+
margin-bottom: 5px;\r
|
|
9869
|
+
}\r
|
|
9870
|
+
.leaflet-control-scale-line {\r
|
|
9871
|
+
border: 2px solid #777;\r
|
|
9872
|
+
border-top: none;\r
|
|
9873
|
+
line-height: 1.1;\r
|
|
9874
|
+
padding: 2px 5px 1px;\r
|
|
9875
|
+
white-space: nowrap;\r
|
|
9876
|
+
box-sizing: border-box;\r
|
|
9877
|
+
background: rgba(255, 255, 255, 0.8);\r
|
|
9878
|
+
text-shadow: 1px 1px #fff;\r
|
|
9879
|
+
}\r
|
|
9880
|
+
.leaflet-control-scale-line:not(:first-child) {\r
|
|
9881
|
+
border-top: 2px solid #777;\r
|
|
9882
|
+
border-bottom: none;\r
|
|
9883
|
+
margin-top: -2px;\r
|
|
9884
|
+
}\r
|
|
9885
|
+
.leaflet-control-scale-line:not(:first-child):not(:last-child) {\r
|
|
9886
|
+
border-bottom: 2px solid #777;\r
|
|
9887
|
+
}\r
|
|
9888
|
+
\r
|
|
9889
|
+
.leaflet-touch .leaflet-control-attribution,\r
|
|
9890
|
+
.leaflet-touch .leaflet-control-layers,\r
|
|
9891
|
+
.leaflet-touch .leaflet-bar {\r
|
|
9892
|
+
box-shadow: none;\r
|
|
9893
|
+
}\r
|
|
9894
|
+
.leaflet-touch .leaflet-control-layers,\r
|
|
9895
|
+
.leaflet-touch .leaflet-bar {\r
|
|
9896
|
+
border: 2px solid rgba(0,0,0,0.2);\r
|
|
9897
|
+
background-clip: padding-box;\r
|
|
9898
|
+
}\r
|
|
9899
|
+
\r
|
|
9900
|
+
\r
|
|
9901
|
+
/* popup */\r
|
|
9902
|
+
\r
|
|
9903
|
+
.leaflet-popup {\r
|
|
9904
|
+
position: absolute;\r
|
|
9905
|
+
text-align: center;\r
|
|
9906
|
+
margin-bottom: 20px;\r
|
|
9907
|
+
}\r
|
|
9908
|
+
.leaflet-popup-content-wrapper {\r
|
|
9909
|
+
padding: 1px;\r
|
|
9910
|
+
text-align: left;\r
|
|
9911
|
+
border-radius: 12px;\r
|
|
9912
|
+
}\r
|
|
9913
|
+
.leaflet-popup-content {\r
|
|
9914
|
+
margin: 13px 24px 13px 20px;\r
|
|
9915
|
+
line-height: 1.3;\r
|
|
9916
|
+
font-size: 13px;\r
|
|
9917
|
+
font-size: 1.08333em;\r
|
|
9918
|
+
min-height: 1px;\r
|
|
9919
|
+
}\r
|
|
9920
|
+
.leaflet-popup-content p {\r
|
|
9921
|
+
margin: 17px 0;\r
|
|
9922
|
+
margin: 1.3em 0;\r
|
|
9923
|
+
}\r
|
|
9924
|
+
.leaflet-popup-tip-container {\r
|
|
9925
|
+
width: 40px;\r
|
|
9926
|
+
height: 20px;\r
|
|
9927
|
+
position: absolute;\r
|
|
9928
|
+
left: 50%;\r
|
|
9929
|
+
margin-top: -1px;\r
|
|
9930
|
+
margin-left: -20px;\r
|
|
9931
|
+
overflow: hidden;\r
|
|
9932
|
+
pointer-events: none;\r
|
|
9933
|
+
}\r
|
|
9934
|
+
.leaflet-popup-tip {\r
|
|
9935
|
+
width: 17px;\r
|
|
9936
|
+
height: 17px;\r
|
|
9937
|
+
padding: 1px;\r
|
|
9938
|
+
\r
|
|
9939
|
+
margin: -10px auto 0;\r
|
|
9940
|
+
pointer-events: auto;\r
|
|
9941
|
+
transform: rotate(45deg);\r
|
|
9942
|
+
}\r
|
|
9943
|
+
.leaflet-popup-content-wrapper,\r
|
|
9944
|
+
.leaflet-popup-tip {\r
|
|
9945
|
+
background: white;\r
|
|
9946
|
+
color: #333;\r
|
|
9947
|
+
box-shadow: 0 3px 14px rgba(0,0,0,0.4);\r
|
|
9948
|
+
}\r
|
|
9949
|
+
.leaflet-container a.leaflet-popup-close-button {\r
|
|
9950
|
+
position: absolute;\r
|
|
9951
|
+
top: 0;\r
|
|
9952
|
+
right: 0;\r
|
|
9953
|
+
border: none;\r
|
|
9954
|
+
text-align: center;\r
|
|
9955
|
+
width: 24px;\r
|
|
9956
|
+
height: 24px;\r
|
|
9957
|
+
font: 16px/24px Tahoma, Verdana, sans-serif;\r
|
|
9958
|
+
color: #757575;\r
|
|
9959
|
+
text-decoration: none;\r
|
|
9960
|
+
background: transparent;\r
|
|
9961
|
+
}\r
|
|
9962
|
+
.leaflet-container a.leaflet-popup-close-button:hover,\r
|
|
9963
|
+
.leaflet-container a.leaflet-popup-close-button:focus {\r
|
|
9964
|
+
color: #585858;\r
|
|
9965
|
+
}\r
|
|
9966
|
+
.leaflet-popup-scrolled {\r
|
|
9967
|
+
overflow: auto;\r
|
|
9968
|
+
}\r
|
|
9969
|
+
\r
|
|
9970
|
+
.leaflet-oldie .leaflet-popup-content-wrapper {\r
|
|
9971
|
+
-ms-zoom: 1;\r
|
|
9972
|
+
}\r
|
|
9973
|
+
.leaflet-oldie .leaflet-popup-tip {\r
|
|
9974
|
+
width: 24px;\r
|
|
9975
|
+
margin: 0 auto;\r
|
|
9976
|
+
\r
|
|
9977
|
+
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";\r
|
|
9978
|
+
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);\r
|
|
9979
|
+
}\r
|
|
9980
|
+
\r
|
|
9981
|
+
.leaflet-oldie .leaflet-control-zoom,\r
|
|
9982
|
+
.leaflet-oldie .leaflet-control-layers,\r
|
|
9983
|
+
.leaflet-oldie .leaflet-popup-content-wrapper,\r
|
|
9984
|
+
.leaflet-oldie .leaflet-popup-tip {\r
|
|
9985
|
+
border: 1px solid #999;\r
|
|
9986
|
+
}\r
|
|
9987
|
+
\r
|
|
9988
|
+
\r
|
|
9989
|
+
/* div icon */\r
|
|
9990
|
+
\r
|
|
9991
|
+
.leaflet-div-icon {\r
|
|
9992
|
+
background: #fff;\r
|
|
9993
|
+
border: 1px solid #666;\r
|
|
9994
|
+
}\r
|
|
9995
|
+
\r
|
|
9996
|
+
\r
|
|
9997
|
+
/* Tooltip */\r
|
|
9998
|
+
/* Base styles for the element that has a tooltip */\r
|
|
9999
|
+
.leaflet-tooltip {\r
|
|
10000
|
+
position: absolute;\r
|
|
10001
|
+
padding: 6px;\r
|
|
10002
|
+
background-color: #fff;\r
|
|
10003
|
+
border: 1px solid #fff;\r
|
|
10004
|
+
border-radius: 3px;\r
|
|
10005
|
+
color: #222;\r
|
|
10006
|
+
white-space: nowrap;\r
|
|
10007
|
+
-webkit-user-select: none;\r
|
|
10008
|
+
-moz-user-select: none;\r
|
|
10009
|
+
user-select: none;\r
|
|
10010
|
+
pointer-events: none;\r
|
|
10011
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.4);\r
|
|
10012
|
+
}\r
|
|
10013
|
+
.leaflet-tooltip.leaflet-interactive {\r
|
|
10014
|
+
cursor: pointer;\r
|
|
10015
|
+
pointer-events: auto;\r
|
|
10016
|
+
}\r
|
|
10017
|
+
.leaflet-tooltip-top:before,\r
|
|
10018
|
+
.leaflet-tooltip-bottom:before,\r
|
|
10019
|
+
.leaflet-tooltip-left:before,\r
|
|
10020
|
+
.leaflet-tooltip-right:before {\r
|
|
10021
|
+
position: absolute;\r
|
|
10022
|
+
pointer-events: none;\r
|
|
10023
|
+
border: 6px solid transparent;\r
|
|
10024
|
+
background: transparent;\r
|
|
10025
|
+
content: "";\r
|
|
10026
|
+
}\r
|
|
10027
|
+
\r
|
|
10028
|
+
/* Directions */\r
|
|
10029
|
+
\r
|
|
10030
|
+
.leaflet-tooltip-bottom {\r
|
|
10031
|
+
margin-top: 6px;\r
|
|
10032
|
+
}\r
|
|
10033
|
+
.leaflet-tooltip-top {\r
|
|
10034
|
+
margin-top: -6px;\r
|
|
10035
|
+
}\r
|
|
10036
|
+
.leaflet-tooltip-bottom:before,\r
|
|
10037
|
+
.leaflet-tooltip-top:before {\r
|
|
10038
|
+
left: 50%;\r
|
|
10039
|
+
margin-left: -6px;\r
|
|
10040
|
+
}\r
|
|
10041
|
+
.leaflet-tooltip-top:before {\r
|
|
10042
|
+
bottom: 0;\r
|
|
10043
|
+
margin-bottom: -12px;\r
|
|
10044
|
+
border-top-color: #fff;\r
|
|
10045
|
+
}\r
|
|
10046
|
+
.leaflet-tooltip-bottom:before {\r
|
|
10047
|
+
top: 0;\r
|
|
10048
|
+
margin-top: -12px;\r
|
|
10049
|
+
margin-left: -6px;\r
|
|
10050
|
+
border-bottom-color: #fff;\r
|
|
10051
|
+
}\r
|
|
10052
|
+
.leaflet-tooltip-left {\r
|
|
10053
|
+
margin-left: -6px;\r
|
|
10054
|
+
}\r
|
|
10055
|
+
.leaflet-tooltip-right {\r
|
|
10056
|
+
margin-left: 6px;\r
|
|
10057
|
+
}\r
|
|
10058
|
+
.leaflet-tooltip-left:before,\r
|
|
10059
|
+
.leaflet-tooltip-right:before {\r
|
|
10060
|
+
top: 50%;\r
|
|
10061
|
+
margin-top: -6px;\r
|
|
10062
|
+
}\r
|
|
10063
|
+
.leaflet-tooltip-left:before {\r
|
|
10064
|
+
right: 0;\r
|
|
10065
|
+
margin-right: -12px;\r
|
|
10066
|
+
border-left-color: #fff;\r
|
|
10067
|
+
}\r
|
|
10068
|
+
.leaflet-tooltip-right:before {\r
|
|
10069
|
+
left: 0;\r
|
|
10070
|
+
margin-left: -12px;\r
|
|
10071
|
+
border-right-color: #fff;\r
|
|
10072
|
+
}\r
|
|
10073
|
+
\r
|
|
10074
|
+
/* Printing */\r
|
|
10075
|
+
\r
|
|
10076
|
+
@media print {\r
|
|
10077
|
+
/* Prevent printers from removing background-images of controls. */\r
|
|
10078
|
+
.leaflet-control {\r
|
|
10079
|
+
-webkit-print-color-adjust: exact;\r
|
|
10080
|
+
print-color-adjust: exact;\r
|
|
10081
|
+
}\r
|
|
10082
|
+
}\r
|
|
10083
|
+
`;
|
|
10084
|
+
const leafletStyleModifications = ".leaflet-container {\n background: transparent;\n}\n";
|
|
10085
|
+
const mapSourceSchema = z$1.object({
|
|
10086
|
+
type: z$1.literal("topojson"),
|
|
10087
|
+
url: z$1.string().min(1),
|
|
10088
|
+
topologyObjectsKey: z$1.string().min(1)
|
|
10089
|
+
});
|
|
10090
|
+
function useGeoJsonMap(mapSource) {
|
|
10091
|
+
const {
|
|
10092
|
+
data: geojsonData,
|
|
10093
|
+
error,
|
|
10094
|
+
isLoading
|
|
10095
|
+
} = useQuery(async () => {
|
|
10096
|
+
switch (mapSource.type) {
|
|
10097
|
+
case "topojson":
|
|
10098
|
+
return await loadTopojsonMap(mapSource);
|
|
10099
|
+
}
|
|
10100
|
+
}, [mapSource]);
|
|
10101
|
+
if (isLoading) {
|
|
10102
|
+
return { isLoading };
|
|
10103
|
+
}
|
|
10104
|
+
if (error) {
|
|
10105
|
+
throw error;
|
|
10106
|
+
}
|
|
10107
|
+
return { geojsonData, isLoading: false };
|
|
10108
|
+
}
|
|
10109
|
+
async function loadTopojsonMap(mapSource) {
|
|
10110
|
+
var _a;
|
|
10111
|
+
const response = await fetch(mapSource.url);
|
|
10112
|
+
const topology = await response.json();
|
|
10113
|
+
if ((topology == null ? void 0 : topology.type) !== "Topology") {
|
|
10114
|
+
throw new UserFacingError(
|
|
10115
|
+
"Invalid map source",
|
|
10116
|
+
`JSON downloaded from ${mapSource.url} does not look like a topojson Topology definition: missing 'type: "Topology"', got '${JSON.stringify(topology).substring(0, 100)}'`
|
|
10117
|
+
);
|
|
10118
|
+
}
|
|
10119
|
+
const object = topology == null ? void 0 : topology.objects[mapSource.topologyObjectsKey];
|
|
10120
|
+
if ((object == null ? void 0 : object.type) !== "GeometryCollection") {
|
|
10121
|
+
throw new UserFacingError(
|
|
10122
|
+
"Invalid map source",
|
|
10123
|
+
`JSON downloaded from ${mapSource.url} does not have a GeometryCollection at key objects.${mapSource.topologyObjectsKey}, got '${(_a = JSON.stringify(topology)) == null ? void 0 : _a.substring(0, 100)}'`
|
|
10124
|
+
);
|
|
10125
|
+
}
|
|
10126
|
+
return topojson.feature(topology, object);
|
|
10127
|
+
}
|
|
10128
|
+
const SequencesByLocationMap = ({
|
|
10129
|
+
mapSource,
|
|
10130
|
+
...otherProps
|
|
10131
|
+
}) => {
|
|
10132
|
+
const { isLoading: isLoadingMap, geojsonData } = useGeoJsonMap(mapSource);
|
|
10133
|
+
if (isLoadingMap) {
|
|
10134
|
+
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
10135
|
+
}
|
|
10136
|
+
return /* @__PURE__ */ u$1(SequencesByLocationMapInner$1, { geojsonData, ...otherProps });
|
|
10137
|
+
};
|
|
10138
|
+
const SequencesByLocationMapInner$1 = ({
|
|
10139
|
+
geojsonData,
|
|
10140
|
+
locationData,
|
|
10141
|
+
enableMapNavigation,
|
|
10142
|
+
lapisLocationField,
|
|
10143
|
+
zoom,
|
|
10144
|
+
offsetX,
|
|
10145
|
+
offsetY
|
|
10146
|
+
}) => {
|
|
10147
|
+
const ref = A(null);
|
|
10148
|
+
y(() => {
|
|
10149
|
+
if (!ref.current || geojsonData === void 0 || locationData === void 0) {
|
|
10150
|
+
return;
|
|
10151
|
+
}
|
|
10152
|
+
const countAndProportionByCountry = buildLookupByLocationField(locationData, lapisLocationField);
|
|
10153
|
+
const locations = matchLocationDataAndGeoJsonFeatures(
|
|
10154
|
+
geojsonData,
|
|
10155
|
+
countAndProportionByCountry,
|
|
10156
|
+
lapisLocationField
|
|
10157
|
+
);
|
|
10158
|
+
const leafletMap = Leaflet.map(ref.current, {
|
|
10159
|
+
scrollWheelZoom: enableMapNavigation,
|
|
10160
|
+
zoomControl: enableMapNavigation,
|
|
10161
|
+
keyboard: enableMapNavigation,
|
|
10162
|
+
dragging: enableMapNavigation,
|
|
10163
|
+
zoomSnap: 0,
|
|
10164
|
+
zoom,
|
|
10165
|
+
center: [offsetY, offsetX]
|
|
10166
|
+
});
|
|
10167
|
+
Leaflet.geoJson(locations, {
|
|
10168
|
+
style: (feature) => {
|
|
10169
|
+
var _a;
|
|
10170
|
+
return {
|
|
10171
|
+
fillColor: getColor((_a = feature == null ? void 0 : feature.properties.data) == null ? void 0 : _a.proportion),
|
|
10172
|
+
fillOpacity: 1,
|
|
10173
|
+
color: "grey",
|
|
10174
|
+
weight: 1
|
|
10175
|
+
};
|
|
10176
|
+
}
|
|
10177
|
+
}).bindTooltip(createTooltip).addTo(leafletMap);
|
|
10178
|
+
return () => {
|
|
10179
|
+
leafletMap.remove();
|
|
10180
|
+
};
|
|
10181
|
+
}, [ref, locationData, geojsonData, enableMapNavigation, lapisLocationField, zoom, offsetX, offsetY]);
|
|
10182
|
+
return /* @__PURE__ */ u$1("div", { ref, className: "h-full" });
|
|
10183
|
+
};
|
|
10184
|
+
function buildLookupByLocationField(locationData, lapisLocationField) {
|
|
10185
|
+
return new Map(
|
|
10186
|
+
locationData.filter((row) => typeof row[lapisLocationField] === "string").map((row) => [row[lapisLocationField], row])
|
|
10187
|
+
);
|
|
10188
|
+
}
|
|
10189
|
+
function matchLocationDataAndGeoJsonFeatures(geojsonData, countAndProportionByCountry, lapisLocationField) {
|
|
10190
|
+
const matchedLocations = [];
|
|
10191
|
+
const locations = geojsonData.features.map(
|
|
10192
|
+
(feature) => {
|
|
10193
|
+
var _a;
|
|
10194
|
+
const name = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.name;
|
|
10195
|
+
if (typeof name !== "string") {
|
|
10196
|
+
throw new Error(
|
|
10197
|
+
`GeoJSON feature with id '${feature.id}' does not have 'properties.name' of type string, was: '${name}'`
|
|
10198
|
+
);
|
|
10199
|
+
}
|
|
10200
|
+
const data = countAndProportionByCountry.get(name) ?? null;
|
|
10201
|
+
if (data !== null) {
|
|
10202
|
+
matchedLocations.push(name);
|
|
10203
|
+
}
|
|
10204
|
+
return {
|
|
10205
|
+
...feature,
|
|
10206
|
+
properties: {
|
|
10207
|
+
...feature.properties,
|
|
10208
|
+
data
|
|
10209
|
+
}
|
|
10210
|
+
};
|
|
10211
|
+
}
|
|
10212
|
+
);
|
|
10213
|
+
const unmatchedLocations = [...countAndProportionByCountry.keys()].filter(
|
|
10214
|
+
(name) => !matchedLocations.includes(name)
|
|
10215
|
+
);
|
|
10216
|
+
if (unmatchedLocations.length > 0) {
|
|
10217
|
+
const unmatchedLocationsWarning = `gs-map: Found location data from LAPIS (aggregated by "${lapisLocationField}") that could not be matched on locations on the given map. Unmatched location names are: ${unmatchedLocations.map((it) => `"${it}"`).join(", ")}`;
|
|
10218
|
+
console.warn(unmatchedLocationsWarning);
|
|
10219
|
+
}
|
|
10220
|
+
return locations;
|
|
10221
|
+
}
|
|
10222
|
+
function getColor(value) {
|
|
10223
|
+
if (value === void 0) {
|
|
10224
|
+
return "#888888";
|
|
10225
|
+
}
|
|
10226
|
+
const thresholds = [
|
|
10227
|
+
{ limit: 0.4, color: "#662506" },
|
|
10228
|
+
{ limit: 0.3, color: "#993404" },
|
|
10229
|
+
{ limit: 0.2, color: "#CC4C02" },
|
|
10230
|
+
{ limit: 0.1, color: "#EC7014" },
|
|
10231
|
+
{ limit: 0.05, color: "#FB9A29" },
|
|
10232
|
+
{ limit: 0.02, color: "#FEC44F" },
|
|
10233
|
+
{ limit: 0.01, color: "#FEE391" },
|
|
10234
|
+
{ limit: 5e-3, color: "#FFF7BC" },
|
|
10235
|
+
{ limit: 2e-3, color: "#FFFFE5" }
|
|
10236
|
+
];
|
|
10237
|
+
for (const { limit, color } of thresholds) {
|
|
10238
|
+
if (value > limit) {
|
|
10239
|
+
return color;
|
|
10240
|
+
}
|
|
10241
|
+
}
|
|
10242
|
+
return "#FFFFE5";
|
|
10243
|
+
}
|
|
10244
|
+
function createTooltip(layer) {
|
|
10245
|
+
const feature = layer.feature;
|
|
10246
|
+
if (feature === void 0 || feature.type !== "Feature") {
|
|
10247
|
+
return "";
|
|
10248
|
+
}
|
|
10249
|
+
const properties = feature.properties;
|
|
10250
|
+
const div = document.createElement("div");
|
|
10251
|
+
div.appendChild(p({ innerText: properties.name, className: "font-bold" }));
|
|
10252
|
+
if (properties.data !== null) {
|
|
10253
|
+
div.appendChild(
|
|
10254
|
+
p({
|
|
10255
|
+
innerText: `Count: ${properties.data.count.toLocaleString("en-us")}`
|
|
10256
|
+
})
|
|
10257
|
+
);
|
|
10258
|
+
div.appendChild(
|
|
10259
|
+
p({
|
|
10260
|
+
innerText: `Proportion: ${formatProportion(properties.data.proportion)}`
|
|
10261
|
+
})
|
|
10262
|
+
);
|
|
10263
|
+
} else {
|
|
10264
|
+
div.appendChild(p({ innerText: "No data" }));
|
|
10265
|
+
}
|
|
10266
|
+
return div;
|
|
10267
|
+
}
|
|
10268
|
+
function p({ innerText, className = "" }) {
|
|
10269
|
+
const headline = document.createElement("p");
|
|
10270
|
+
headline.innerText = innerText;
|
|
10271
|
+
headline.className = className;
|
|
10272
|
+
return headline;
|
|
10273
|
+
}
|
|
10274
|
+
const SequencesByLocationTable = ({
|
|
10275
|
+
locationData,
|
|
10276
|
+
lapisLocationField,
|
|
10277
|
+
pageSize
|
|
10278
|
+
}) => {
|
|
10279
|
+
return /* @__PURE__ */ u$1(AggregateTable, { data: locationData, fields: [lapisLocationField], pageSize });
|
|
10280
|
+
};
|
|
10281
|
+
const sequencesByLocationViewSchema = z$1.union([z$1.literal(views.map), z$1.literal(views.table)]);
|
|
10282
|
+
const sequencesByLocationPropsSchema = z$1.object({
|
|
10283
|
+
lapisFilter: lapisFilterSchema,
|
|
10284
|
+
lapisLocationField: z$1.string().min(1),
|
|
10285
|
+
mapSource: mapSourceSchema.optional(),
|
|
10286
|
+
enableMapNavigation: z$1.boolean(),
|
|
10287
|
+
width: z$1.string(),
|
|
10288
|
+
height: z$1.string(),
|
|
10289
|
+
views: z$1.array(sequencesByLocationViewSchema),
|
|
10290
|
+
zoom: z$1.number(),
|
|
10291
|
+
offsetX: z$1.number(),
|
|
10292
|
+
offsetY: z$1.number(),
|
|
10293
|
+
pageSize: z$1.union([z$1.boolean(), z$1.number()])
|
|
10294
|
+
});
|
|
10295
|
+
const SequencesByLocation = (componentProps) => {
|
|
10296
|
+
const { width, height } = componentProps;
|
|
10297
|
+
const size = { height, width };
|
|
10298
|
+
return /* @__PURE__ */ u$1(ErrorBoundary, { size, componentProps, schema: sequencesByLocationPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(SequencesByLocationMapInner, { ...componentProps }) }) });
|
|
10299
|
+
};
|
|
10300
|
+
const SequencesByLocationMapInner = (props) => {
|
|
10301
|
+
const { lapisFilter, lapisLocationField } = props;
|
|
10302
|
+
const lapis = x(LapisUrlContext);
|
|
10303
|
+
const {
|
|
10304
|
+
data,
|
|
10305
|
+
error,
|
|
10306
|
+
isLoading: isLoadingLapisData
|
|
10307
|
+
} = useQuery(
|
|
10308
|
+
async () => queryAggregateData(lapisFilter, [lapisLocationField], lapis),
|
|
10309
|
+
[lapisFilter, lapisLocationField, lapis]
|
|
10310
|
+
);
|
|
10311
|
+
if (isLoadingLapisData) {
|
|
10312
|
+
return /* @__PURE__ */ u$1(LoadingDisplay, {});
|
|
10313
|
+
}
|
|
10314
|
+
if (error) {
|
|
10315
|
+
throw error;
|
|
10316
|
+
}
|
|
10317
|
+
return /* @__PURE__ */ u$1(SequencesByLocationMapTabs, { data, originalComponentProps: props });
|
|
10318
|
+
};
|
|
10319
|
+
const SequencesByLocationMapTabs = ({
|
|
10320
|
+
originalComponentProps,
|
|
10321
|
+
data
|
|
10322
|
+
}) => {
|
|
10323
|
+
const getTab = (view) => {
|
|
10324
|
+
switch (view) {
|
|
10325
|
+
case views.map:
|
|
10326
|
+
if (originalComponentProps.mapSource === void 0) {
|
|
10327
|
+
throw new Error("mapSource is required when using the map view");
|
|
10328
|
+
}
|
|
10329
|
+
return {
|
|
10330
|
+
title: "Map",
|
|
10331
|
+
content: /* @__PURE__ */ u$1(
|
|
10332
|
+
SequencesByLocationMap,
|
|
10333
|
+
{
|
|
10334
|
+
locationData: data,
|
|
10335
|
+
mapSource: originalComponentProps.mapSource,
|
|
10336
|
+
enableMapNavigation: originalComponentProps.enableMapNavigation,
|
|
10337
|
+
lapisLocationField: originalComponentProps.lapisLocationField,
|
|
10338
|
+
zoom: originalComponentProps.zoom,
|
|
10339
|
+
offsetX: originalComponentProps.offsetX,
|
|
10340
|
+
offsetY: originalComponentProps.offsetY
|
|
10341
|
+
}
|
|
10342
|
+
)
|
|
10343
|
+
};
|
|
10344
|
+
case views.table:
|
|
10345
|
+
return {
|
|
10346
|
+
title: "Table",
|
|
10347
|
+
content: /* @__PURE__ */ u$1(
|
|
10348
|
+
SequencesByLocationTable,
|
|
10349
|
+
{
|
|
10350
|
+
locationData: data,
|
|
10351
|
+
lapisLocationField: originalComponentProps.lapisLocationField,
|
|
10352
|
+
pageSize: originalComponentProps.pageSize
|
|
10353
|
+
}
|
|
10354
|
+
)
|
|
10355
|
+
};
|
|
10356
|
+
}
|
|
10357
|
+
};
|
|
10358
|
+
const tabs = originalComponentProps.views.map((view) => getTab(view));
|
|
10359
|
+
return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar, { originalComponentProps }) });
|
|
10360
|
+
};
|
|
10361
|
+
const Toolbar = ({ originalComponentProps }) => {
|
|
10362
|
+
return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
|
|
10363
|
+
/* @__PURE__ */ u$1(SequencesByLocationMapInfo, { originalComponentProps }),
|
|
10364
|
+
/* @__PURE__ */ u$1(Fullscreen, {})
|
|
10365
|
+
] });
|
|
10366
|
+
};
|
|
10367
|
+
const SequencesByLocationMapInfo = ({ originalComponentProps }) => {
|
|
10368
|
+
const lapis = x(LapisUrlContext);
|
|
10369
|
+
return /* @__PURE__ */ u$1(Info, { children: [
|
|
10370
|
+
/* @__PURE__ */ u$1(InfoHeadline1, { children: "Prevalence by location" }),
|
|
10371
|
+
/* @__PURE__ */ u$1(InfoParagraph, { children: "TODO: Add description https://github.com/GenSpectrum/dashboard-components/issues/598" }),
|
|
10372
|
+
/* @__PURE__ */ u$1(InfoComponentCode, { componentName: "sequences-by-location", params: originalComponentProps, lapisUrl: lapis })
|
|
10373
|
+
] });
|
|
10374
|
+
};
|
|
10375
|
+
var __defProp$6 = Object.defineProperty;
|
|
10376
|
+
var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
|
|
10377
|
+
var __decorateClass$6 = (decorators, target, key, kind) => {
|
|
10378
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
|
|
10379
|
+
for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
|
|
10380
|
+
if (decorator = decorators[i2])
|
|
10381
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
10382
|
+
if (kind && result) __defProp$6(target, key, result);
|
|
10383
|
+
return result;
|
|
10384
|
+
};
|
|
10385
|
+
const leafletCss = unsafeCSS(leafletStyle);
|
|
10386
|
+
const leafletModificationsCss = unsafeCSS(leafletStyleModifications);
|
|
10387
|
+
let SequencesByLocationComponent = class extends PreactLitAdapterWithGridJsStyles {
|
|
10388
|
+
constructor() {
|
|
10389
|
+
super(...arguments);
|
|
10390
|
+
this.lapisFilter = {};
|
|
10391
|
+
this.lapisLocationField = "";
|
|
10392
|
+
this.mapSource = void 0;
|
|
10393
|
+
this.enableMapNavigation = true;
|
|
10394
|
+
this.width = "100%";
|
|
10395
|
+
this.height = "700px";
|
|
10396
|
+
this.views = ["map", "table"];
|
|
10397
|
+
this.zoom = 1;
|
|
10398
|
+
this.offsetX = 0;
|
|
10399
|
+
this.offsetY = 0;
|
|
10400
|
+
this.pageSize = false;
|
|
10401
|
+
}
|
|
10402
|
+
render() {
|
|
10403
|
+
return /* @__PURE__ */ u$1(
|
|
10404
|
+
SequencesByLocation,
|
|
10405
|
+
{
|
|
10406
|
+
lapisFilter: this.lapisFilter,
|
|
10407
|
+
lapisLocationField: this.lapisLocationField,
|
|
10408
|
+
mapSource: this.mapSource,
|
|
10409
|
+
enableMapNavigation: this.enableMapNavigation,
|
|
10410
|
+
width: this.width,
|
|
10411
|
+
height: this.height,
|
|
10412
|
+
views: this.views,
|
|
10413
|
+
zoom: this.zoom,
|
|
10414
|
+
offsetX: this.offsetX,
|
|
10415
|
+
offsetY: this.offsetY,
|
|
10416
|
+
pageSize: this.pageSize
|
|
10417
|
+
}
|
|
10418
|
+
);
|
|
10419
|
+
}
|
|
10420
|
+
};
|
|
10421
|
+
SequencesByLocationComponent.styles = [...PreactLitAdapterWithGridJsStyles.styles, leafletCss, leafletModificationsCss];
|
|
10422
|
+
__decorateClass$6([
|
|
10423
|
+
n2({ type: Object })
|
|
10424
|
+
], SequencesByLocationComponent.prototype, "lapisFilter", 2);
|
|
10425
|
+
__decorateClass$6([
|
|
10426
|
+
n2({ type: String })
|
|
10427
|
+
], SequencesByLocationComponent.prototype, "lapisLocationField", 2);
|
|
10428
|
+
__decorateClass$6([
|
|
10429
|
+
n2({ type: Object })
|
|
10430
|
+
], SequencesByLocationComponent.prototype, "mapSource", 2);
|
|
10431
|
+
__decorateClass$6([
|
|
10432
|
+
n2({ type: Boolean })
|
|
10433
|
+
], SequencesByLocationComponent.prototype, "enableMapNavigation", 2);
|
|
10434
|
+
__decorateClass$6([
|
|
10435
|
+
n2({ type: String })
|
|
10436
|
+
], SequencesByLocationComponent.prototype, "width", 2);
|
|
10437
|
+
__decorateClass$6([
|
|
10438
|
+
n2({ type: String })
|
|
10439
|
+
], SequencesByLocationComponent.prototype, "height", 2);
|
|
10440
|
+
__decorateClass$6([
|
|
10441
|
+
n2({ type: Array })
|
|
10442
|
+
], SequencesByLocationComponent.prototype, "views", 2);
|
|
10443
|
+
__decorateClass$6([
|
|
10444
|
+
n2({ type: Number })
|
|
10445
|
+
], SequencesByLocationComponent.prototype, "zoom", 2);
|
|
10446
|
+
__decorateClass$6([
|
|
10447
|
+
n2({ type: Number })
|
|
10448
|
+
], SequencesByLocationComponent.prototype, "offsetX", 2);
|
|
10449
|
+
__decorateClass$6([
|
|
10450
|
+
n2({ type: Number })
|
|
10451
|
+
], SequencesByLocationComponent.prototype, "offsetY", 2);
|
|
10452
|
+
__decorateClass$6([
|
|
10453
|
+
n2({ type: Object })
|
|
10454
|
+
], SequencesByLocationComponent.prototype, "pageSize", 2);
|
|
10455
|
+
SequencesByLocationComponent = __decorateClass$6([
|
|
10456
|
+
t$2("gs-sequences-by-location")
|
|
10457
|
+
], SequencesByLocationComponent);
|
|
9431
10458
|
async function queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis, signal) {
|
|
9432
10459
|
const numeratorCount = await queryAggregateData(numeratorFilter, [], lapis, void 0, signal);
|
|
9433
10460
|
const denominatorCount = await queryAggregateData(denominatorFilter, [], lapis, void 0, signal);
|
|
@@ -9601,7 +10628,7 @@ const dateRangeSelectorInnerPropsSchema = z$1.object({
|
|
|
9601
10628
|
initialValue: z$1.string().optional(),
|
|
9602
10629
|
initialDateFrom: z$1.string().date().optional(),
|
|
9603
10630
|
initialDateTo: z$1.string().date().optional(),
|
|
9604
|
-
|
|
10631
|
+
lapisDateField: z$1.string().min(1)
|
|
9605
10632
|
});
|
|
9606
10633
|
const dateRangeSelectorPropsSchema = dateRangeSelectorInnerPropsSchema.extend({
|
|
9607
10634
|
width: z$1.string()
|
|
@@ -9615,7 +10642,7 @@ const DateRangeSelectorInner = ({
|
|
|
9615
10642
|
dateRangeOptions,
|
|
9616
10643
|
earliestDate = "1900-01-01",
|
|
9617
10644
|
initialValue,
|
|
9618
|
-
|
|
10645
|
+
lapisDateField,
|
|
9619
10646
|
initialDateFrom,
|
|
9620
10647
|
initialDateTo
|
|
9621
10648
|
}) => {
|
|
@@ -9717,8 +10744,8 @@ const DateRangeSelectorInner = ({
|
|
|
9717
10744
|
const dateFrom = dateFromPicker == null ? void 0 : dateFromPicker.selectedDates[0];
|
|
9718
10745
|
const dateTo = dateToPicker == null ? void 0 : dateToPicker.selectedDates[0];
|
|
9719
10746
|
const detail = {
|
|
9720
|
-
...dateFrom !== void 0 && { [`${
|
|
9721
|
-
...dateTo !== void 0 && { [`${
|
|
10747
|
+
...dateFrom !== void 0 && { [`${lapisDateField}From`]: toYYYYMMDD(dateFrom) },
|
|
10748
|
+
...dateTo !== void 0 && { [`${lapisDateField}To`]: toYYYYMMDD(dateTo) }
|
|
9722
10749
|
};
|
|
9723
10750
|
(_a = divRef.current) == null ? void 0 : _a.dispatchEvent(
|
|
9724
10751
|
new CustomEvent("gs-date-range-filter-changed", {
|
|
@@ -9791,7 +10818,7 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
|
|
|
9791
10818
|
this.initialDateFrom = void 0;
|
|
9792
10819
|
this.initialDateTo = void 0;
|
|
9793
10820
|
this.width = "100%";
|
|
9794
|
-
this.
|
|
10821
|
+
this.lapisDateField = "";
|
|
9795
10822
|
}
|
|
9796
10823
|
render() {
|
|
9797
10824
|
return /* @__PURE__ */ u$1(
|
|
@@ -9802,7 +10829,7 @@ let DateRangeSelectorComponent = class extends PreactLitAdapter {
|
|
|
9802
10829
|
initialValue: this.initialValue,
|
|
9803
10830
|
initialDateFrom: this.initialDateFrom,
|
|
9804
10831
|
initialDateTo: this.initialDateTo,
|
|
9805
|
-
|
|
10832
|
+
lapisDateField: this.lapisDateField,
|
|
9806
10833
|
width: this.width
|
|
9807
10834
|
}
|
|
9808
10835
|
);
|
|
@@ -9828,7 +10855,7 @@ __decorateClass$4([
|
|
|
9828
10855
|
], DateRangeSelectorComponent.prototype, "width", 2);
|
|
9829
10856
|
__decorateClass$4([
|
|
9830
10857
|
n2({ type: String })
|
|
9831
|
-
], DateRangeSelectorComponent.prototype, "
|
|
10858
|
+
], DateRangeSelectorComponent.prototype, "lapisDateField", 2);
|
|
9832
10859
|
DateRangeSelectorComponent = __decorateClass$4([
|
|
9833
10860
|
t$2("gs-date-range-selector")
|
|
9834
10861
|
], DateRangeSelectorComponent);
|
|
@@ -10373,14 +11400,8 @@ const parseAndValidateMutation = (value, referenceGenome) => {
|
|
|
10373
11400
|
}
|
|
10374
11401
|
return null;
|
|
10375
11402
|
};
|
|
10376
|
-
const selectedMutationFilterStringsSchema = z$1.object({
|
|
10377
|
-
nucleotideMutations: z$1.array(z$1.string()),
|
|
10378
|
-
aminoAcidMutations: z$1.array(z$1.string()),
|
|
10379
|
-
nucleotideInsertions: z$1.array(z$1.string()),
|
|
10380
|
-
aminoAcidInsertions: z$1.array(z$1.string())
|
|
10381
|
-
});
|
|
10382
11403
|
const mutationFilterInnerPropsSchema = z$1.object({
|
|
10383
|
-
initialValue: z$1.union([
|
|
11404
|
+
initialValue: z$1.union([mutationsFilterSchema.optional(), z$1.array(z$1.string()), z$1.undefined()])
|
|
10384
11405
|
});
|
|
10385
11406
|
const mutationFilterPropsSchema = mutationFilterInnerPropsSchema.extend({
|
|
10386
11407
|
width: z$1.string()
|
|
@@ -10803,6 +11824,7 @@ export {
|
|
|
10803
11824
|
NumberSequencesOverTimeComponent,
|
|
10804
11825
|
PrevalenceOverTimeComponent,
|
|
10805
11826
|
RelativeGrowthAdvantageComponent,
|
|
11827
|
+
SequencesByLocationComponent,
|
|
10806
11828
|
StatisticsComponent,
|
|
10807
11829
|
TextInputComponent,
|
|
10808
11830
|
UserFacingError
|