@genspectrum/dashboard-components 0.10.2 → 0.10.4

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.
Files changed (76) hide show
  1. package/README.md +19 -19
  2. package/custom-elements.json +377 -33
  3. package/dist/assets/mutationOverTimeWorker-BjjkMGzd.js.map +1 -0
  4. package/dist/components.d.ts +217 -59
  5. package/dist/components.js +1365 -177
  6. package/dist/components.js.map +1 -1
  7. package/dist/{dateRangeOption-du8H7LWu.js → dateRangeOption-Doo6WHKu.js} +17 -3
  8. package/dist/dateRangeOption-Doo6WHKu.js.map +1 -0
  9. package/dist/style.css +16 -6
  10. package/dist/util.d.ts +107 -41
  11. package/dist/util.js +1 -1
  12. package/package.json +10 -4
  13. package/src/preact/aggregatedData/aggregate.stories.tsx +14 -0
  14. package/src/preact/aggregatedData/aggregate.tsx +17 -15
  15. package/src/preact/components/error-boundary.stories.tsx +24 -3
  16. package/src/preact/components/error-boundary.tsx +3 -4
  17. package/src/preact/components/error-display.tsx +38 -17
  18. package/src/preact/components/tabs.tsx +2 -2
  19. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +1 -1
  20. package/src/preact/lineageFilter/lineage-filter.stories.tsx +1 -1
  21. package/src/preact/locationFilter/location-filter.stories.tsx +1 -1
  22. package/src/preact/map/__mockData__/aggregatedGermany.json +83 -0
  23. package/src/preact/map/__mockData__/aggregatedWorld.json +259 -0
  24. package/src/preact/map/__mockData__/germanyMap.json +9083 -0
  25. package/src/preact/map/__mockData__/howToGenerateWorldMap.md +9 -0
  26. package/src/preact/map/__mockData__/worldAtlas.json +497127 -0
  27. package/src/preact/map/leafletStyleModifications.css +3 -0
  28. package/src/preact/map/sequences-by-location-map.tsx +202 -0
  29. package/src/preact/map/sequences-by-location-table.tsx +18 -0
  30. package/src/preact/map/sequences-by-location.stories.tsx +144 -0
  31. package/src/preact/map/sequences-by-location.tsx +151 -0
  32. package/src/preact/map/useGeoJsonMap.tsx +62 -0
  33. package/src/preact/mutationComparison/mutation-comparison.tsx +1 -1
  34. package/src/preact/mutationFilter/mutation-filter.tsx +26 -13
  35. package/src/preact/mutations/mutations.tsx +16 -12
  36. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +14 -0
  37. package/src/preact/mutationsOverTime/mutations-over-time.tsx +18 -14
  38. package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +14 -0
  39. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +22 -14
  40. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +14 -0
  41. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +28 -19
  42. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +14 -0
  43. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +18 -15
  44. package/src/preact/shared/charts/confideceInterval.ts +10 -8
  45. package/src/preact/shared/charts/getYAxisMax.ts +10 -5
  46. package/src/preact/shared/stories/expectErrorMessage.ts +21 -0
  47. package/src/preact/statistic/statistics.tsx +10 -8
  48. package/src/preact/textInput/text-input.stories.tsx +14 -0
  49. package/src/preact/textInput/text-input.tsx +16 -11
  50. package/src/preact/useQuery.ts +9 -1
  51. package/src/query/queryAggregateData.ts +2 -1
  52. package/src/styles/tailwind.css +1 -1
  53. package/src/types.ts +13 -1
  54. package/src/utilEntrypoint.ts +7 -0
  55. package/src/web-components/app.stories.ts +17 -2
  56. package/src/web-components/app.ts +17 -5
  57. package/src/web-components/input/gs-mutation-filter.stories.ts +2 -0
  58. package/src/web-components/input/gs-text-input.tsx +2 -2
  59. package/src/web-components/introduction.mdx +4 -4
  60. package/src/web-components/visualization/data_visualization_statistical_analysis.mdx +3 -3
  61. package/src/web-components/visualization/gs-mutations-over-time.tsx +1 -3
  62. package/src/web-components/visualization/gs-mutations.tsx +1 -3
  63. package/src/web-components/visualization/gs-number-sequences-over-time.tsx +1 -3
  64. package/src/web-components/visualization/gs-prevalence-over-time.tsx +3 -6
  65. package/src/web-components/visualization/gs-relative-growth-advantage.tsx +1 -5
  66. package/src/web-components/visualization/gs-sequences-by-location.stories.ts +234 -0
  67. package/src/web-components/visualization/gs-sequences-by-location.tsx +253 -0
  68. package/src/web-components/visualization/index.ts +1 -0
  69. package/standalone-bundle/assets/mutationOverTimeWorker-DoUBht2e.js.map +1 -0
  70. package/standalone-bundle/dashboard-components.js +16223 -9292
  71. package/standalone-bundle/dashboard-components.js.map +1 -1
  72. package/standalone-bundle/style.css +1 -1
  73. package/dist/assets/mutationOverTimeWorker-Di6yP1e6.js.map +0 -1
  74. package/dist/dateRangeOption-du8H7LWu.js.map +0 -1
  75. package/src/preact/shared/stories/expectInvalidAttributesErrorMessage.ts +0 -13
  76. package/standalone-bundle/assets/mutationOverTimeWorker-cIyshfj_.js.map +0 -1
@@ -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 { n as namedLapisFilterSchema, s as sequenceTypeSchema, m as mutationComparisonViewSchema, a as dateRangeOptionSchema, t as toYYYYMMDD, D as DateRangeOptionChangedEvent } from "./dateRangeOption-du8H7LWu.js";
9
+ import { n as namedLapisFilterSchema, s as sequenceTypeSchema, m as mutationComparisonViewSchema, v as views, l as lapisFilterSchema, t as temporalGranularitySchema, a as dateRangeOptionSchema, b as toYYYYMMDD, D as DateRangeOptionChangedEvent } from "./dateRangeOption-Doo6WHKu.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$1 = a$1.reactiveElementPolyfillSupport, d$1 = (t2, s2) => t2, u$2 = { toAttribute(t2, s2) {
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$1 == null ? void 0 : p$1({ ReactiveElement: b$1 }), (a$1.reactiveElementVersions ?? (a$1.reactiveElementVersions = [])).push("2.0.4");
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,16 +523,17 @@ 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$e = Object.defineProperty;
525
- var __getOwnPropDesc$d = Object.getOwnPropertyDescriptor;
526
- var __decorateClass$e = (decorators, target, key, kind) => {
527
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$d(target, key) : target;
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$e(target, key, result);
533
+ if (kind && result) __defProp$f(target, key, result);
532
534
  return result;
533
535
  };
536
+ const lapisUrlSchema = z$1.string().url();
534
537
  let App = class extends LitElement {
535
538
  constructor() {
536
539
  super(...arguments);
@@ -541,7 +544,8 @@ let App = class extends LitElement {
541
544
  };
542
545
  this.updateReferenceGenome = new Task(this, {
543
546
  task: async () => {
544
- this.referenceGenome = await fetchReferenceGenome(this.lapis);
547
+ const lapisUrl = lapisUrlSchema.parse(this.lapis);
548
+ this.referenceGenome = await fetchReferenceGenome(lapisUrl);
545
549
  },
546
550
  args: () => [this.lapis]
547
551
  });
@@ -550,31 +554,37 @@ let App = class extends LitElement {
550
554
  return this.updateReferenceGenome.render({
551
555
  complete: () => html``,
552
556
  // Children will be rendered in the light DOM anyway. We can't use slots without a shadow DOM.
553
- error: () => html` <div class="m-2 w-full alert alert-error">
554
- Error: Cannot fetch reference genome. Is LAPIS available?
555
- </div>`
557
+ error: (error) => {
558
+ if (error instanceof z$1.ZodError) {
559
+ return GsAppError(`Invalid LAPIS URL: '${this.lapis}'`);
560
+ }
561
+ return GsAppError("Cannot fetch reference genome. Is LAPIS available?");
562
+ }
556
563
  });
557
564
  }
558
565
  createRenderRoot() {
559
566
  return this;
560
567
  }
561
568
  };
562
- __decorateClass$e([
569
+ __decorateClass$f([
563
570
  provide({ context: lapisContext }),
564
571
  n2()
565
572
  ], App.prototype, "lapis", 2);
566
- __decorateClass$e([
573
+ __decorateClass$f([
567
574
  provide({ context: referenceGenomeContext })
568
575
  ], App.prototype, "referenceGenome", 2);
569
- App = __decorateClass$e([
576
+ App = __decorateClass$f([
570
577
  t$2("gs-app")
571
578
  ], App);
579
+ function GsAppError(error) {
580
+ return html` <div class="m-2 w-full alert alert-error">Error: ${error}</div>`;
581
+ }
572
582
  var f$1 = 0;
573
583
  function u$1(e2, t2, n3, o2, i2, u2) {
574
584
  t2 || (t2 = {});
575
585
  var a2, c2, l2 = t2;
576
586
  "ref" in t2 && (a2 = t2.ref, delete t2.ref);
577
- var p2 = { type: e2, props: l2, key: n3, ref: a2, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: --f$1, __i: -1, __u: 0, __source: i2, __self: u2 };
587
+ var p2 = { type: e2, props: l2, key: n3, ref: a2, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f$1, __i: -1, __u: 0, __source: i2, __self: u2 };
578
588
  if ("function" == typeof e2 && (a2 = e2.defaultProps)) for (c2 in a2) void 0 === l2[c2] && (l2[c2] = a2[c2]);
579
589
  return options.vnode && options.vnode(p2), p2;
580
590
  }
@@ -585,9 +595,9 @@ function d(n3, t2) {
585
595
  return n3 >= u2.__.length && u2.__.push({}), u2.__[n3];
586
596
  }
587
597
  function h(n3) {
588
- return o = 1, p(D$1, n3);
598
+ return o = 1, p$1(D$1, n3);
589
599
  }
590
- function p(n3, u2, i2) {
600
+ function p$1(n3, u2, i2) {
591
601
  var o2 = d(t++, 2);
592
602
  if (o2.t = n3, !o2.__c && (o2.__ = [D$1(void 0, u2), function(n4) {
593
603
  var t2 = o2.__N ? o2.__N[0] : o2.__[0], r2 = o2.t(t2, n4);
@@ -1286,7 +1296,7 @@ const ErrorDisplay = ({ error, resetError, layout }) => {
1286
1296
  /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1287
1297
  /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1288
1298
  /* @__PURE__ */ u$1("h1", { class: "text-lg", children: details.headline }),
1289
- /* @__PURE__ */ u$1("p", { class: "py-4", children: details.message })
1299
+ /* @__PURE__ */ u$1("div", { class: "py-4", children: details.message })
1290
1300
  ] }),
1291
1301
  /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1292
1302
  ] })
@@ -1330,21 +1340,45 @@ function getDisplayedErrorMessage(error) {
1330
1340
  };
1331
1341
  }
1332
1342
  if (error instanceof InvalidPropsError) {
1333
- const firstError = error.zodError.errors[0];
1334
- let message = error.zodError.issues.map((issue) => {
1335
- const actual = issue.path[0] in error.componentProps ? ` '${JSON.stringify(error.componentProps[issue.path[0]])}'` : "";
1336
- return `Unexpected value${actual} for "${issue.path.join(".")}": ${issue.message}`;
1337
- }).join(" - ");
1338
- if (firstError.code === "invalid_type" && firstError.received === "null") {
1339
- message = `Is the "${firstError.path[0]}" attribute in the HTML of the correct type? ${message}`;
1340
- }
1341
1343
  return {
1342
1344
  headline: "Error - Invalid component attributes",
1343
- details: { headline: "Invalid component attributes", message }
1345
+ details: { headline: "Invalid component attributes", message: /* @__PURE__ */ u$1(ZodErrorDetails, { error }) }
1344
1346
  };
1345
1347
  }
1346
1348
  return { headline: "Error", details: void 0 };
1347
1349
  }
1350
+ function ZodErrorDetails({ error }) {
1351
+ const firstError = error.zodError.errors[0];
1352
+ return /* @__PURE__ */ u$1(Fragment, { children: [
1353
+ /* @__PURE__ */ u$1("p", { children: [
1354
+ /* @__PURE__ */ u$1("span", { className: "font-bold", children: "You are a regular user?" }),
1355
+ " Unfortunately, there is nothing you can do at the moment. This component is misconfigured. Please contact the administrator of this page."
1356
+ ] }),
1357
+ /* @__PURE__ */ u$1("p", { children: [
1358
+ /* @__PURE__ */ u$1("span", { className: "font-bold", children: "You are the administrator of this page?" }),
1359
+ " You supplied invalid attributes to this component. Please check the browser console for more detailed error messages."
1360
+ ] }),
1361
+ firstError.code === "invalid_type" && firstError.received === "null" && /* @__PURE__ */ u$1("p", { children: [
1362
+ 'Is the "',
1363
+ firstError.path[0],
1364
+ '" attribute in the HTML of the correct type? The attribute is expected to be of type "',
1365
+ firstError.expected,
1366
+ '".'
1367
+ ] }),
1368
+ /* @__PURE__ */ u$1("p", { children: "This is a summary of the unexpected attribute values:" }),
1369
+ /* @__PURE__ */ u$1("ul", { class: "m-4 list-outside list-disc ", children: error.zodError.issues.map((issue, index) => {
1370
+ const actual = issue.path[0] in error.componentProps ? `'${JSON.stringify(error.componentProps[issue.path[0]])}'` : "";
1371
+ return /* @__PURE__ */ u$1("li", { children: [
1372
+ "Unexpected value ",
1373
+ actual,
1374
+ ' for "',
1375
+ issue.path.join("."),
1376
+ '": ',
1377
+ issue.message
1378
+ ] }, index);
1379
+ }) })
1380
+ ] });
1381
+ }
1348
1382
  const ResizeContainer = ({ children, size }) => {
1349
1383
  return /* @__PURE__ */ u$1("div", { style: size, className: "bg-white", children });
1350
1384
  };
@@ -1932,7 +1966,8 @@ function useDisplayedSegments(sequenceType) {
1932
1966
  return h(displayedSegments);
1933
1967
  }
1934
1968
  const Tabs = ({ tabs, toolbar }) => {
1935
- const [activeTab, setActiveTab] = h(tabs[0].title);
1969
+ var _a, _b;
1970
+ const [activeTab, setActiveTab] = h((_a = tabs[0]) == null ? void 0 : _a.title);
1936
1971
  const [heightOfTabs, setHeightOfTabs] = h("3rem");
1937
1972
  const tabRef = A(null);
1938
1973
  const updateHeightOfTabs = () => {
@@ -1969,7 +2004,7 @@ const Tabs = ({ tabs, toolbar }) => {
1969
2004
  /* @__PURE__ */ u$1(
1970
2005
  "div",
1971
2006
  {
1972
- className: `p-2 border-2 border-gray-100 rounded-b-md rounded-tr-md ${activeTab === tabs[0].title ? "" : "rounded-tl-md"}`,
2007
+ className: `p-2 border-2 border-gray-100 rounded-b-md rounded-tr-md ${activeTab === ((_b = tabs[0]) == null ? void 0 : _b.title) ? "" : "rounded-tl-md"}`,
1973
2008
  style: { height: `calc(100% - ${heightOfTabs})` },
1974
2009
  children: tabs.map((tab) => /* @__PURE__ */ u$1("div", { className: "h-full overflow-auto", hidden: activeTab !== tab.title, children: tab.content }, tab.title))
1975
2010
  }
@@ -1995,7 +2030,13 @@ function useQuery(fetchDataCallback, dependencies) {
1995
2030
  };
1996
2031
  fetchData();
1997
2032
  }, [JSON.stringify(dependencies)]);
1998
- return { data, error, isLoading };
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 };
1999
2040
  }
2000
2041
  const mutationComparisonPropsSchema = z$1.object({
2001
2042
  width: z$1.string(),
@@ -2071,7 +2112,7 @@ const MutationComparisonTabs = ({ data, originalComponentProps }) => {
2071
2112
  {
2072
2113
  tabs,
2073
2114
  toolbar: /* @__PURE__ */ u$1(
2074
- Toolbar$5,
2115
+ Toolbar$6,
2075
2116
  {
2076
2117
  displayedSegments,
2077
2118
  setDisplayedSegments,
@@ -2086,7 +2127,7 @@ const MutationComparisonTabs = ({ data, originalComponentProps }) => {
2086
2127
  }
2087
2128
  );
2088
2129
  };
2089
- const Toolbar$5 = ({
2130
+ const Toolbar$6 = ({
2090
2131
  displayedSegments,
2091
2132
  setDisplayedSegments,
2092
2133
  displayedMutationTypes,
@@ -2242,7 +2283,7 @@ const tailwindStyle = `*, ::before, ::after {
2242
2283
  --tw-contain-paint: ;
2243
2284
  --tw-contain-style: ;
2244
2285
  }/*
2245
- ! tailwindcss v3.4.15 | MIT License | https://tailwindcss.com
2286
+ ! tailwindcss v3.4.16 | MIT License | https://tailwindcss.com
2246
2287
  *//*
2247
2288
  1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2248
2289
  2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
@@ -3741,12 +3782,12 @@ input.tab:checked + .tab-content,
3741
3782
  mask-repeat: no-repeat;
3742
3783
  -webkit-mask-position: center;
3743
3784
  mask-position: center;
3744
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");
3745
- mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");
3785
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
3786
+ mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
3746
3787
  }
3747
3788
  .loading-spinner {
3748
- -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");
3749
- mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='%23000' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cstyle%3E.spinner_V8m1%7Btransform-origin:center;animation:spinner_zKoa 2s linear infinite%7D.spinner_V8m1 circle%7Bstroke-linecap:round;animation:spinner_YpZS 1.5s ease-out infinite%7D%40keyframes spinner_zKoa%7B100%25%7Btransform:rotate(360deg)%7D%7D%40keyframes spinner_YpZS%7B0%25%7Bstroke-dasharray:0 150;stroke-dashoffset:0%7D47.5%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-16%7D95%25%2C100%25%7Bstroke-dasharray:42 150;stroke-dashoffset:-59%7D%7D%3C%2Fstyle%3E%3Cg class='spinner_V8m1'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3'%3E%3C%2Fcircle%3E%3C%2Fg%3E%3C%2Fsvg%3E");
3789
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
3790
+ mask-image: url("data:image/svg+xml,%3Csvg width='24' height='24' stroke='black' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg transform-origin='center'%3E%3Ccircle cx='12' cy='12' r='9.5' fill='none' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='2s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dasharray' values='0,150;42,150;42,150' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3Canimate attributeName='stroke-dashoffset' values='0;-16;-59' keyTimes='0;0.475;1' dur='1.5s' repeatCount='indefinite'/%3E%3C/circle%3E%3C/g%3E%3C/svg%3E");
3750
3791
  }
3751
3792
  .loading-md {
3752
3793
  width: 1.5rem;
@@ -3843,6 +3884,9 @@ input.tab:checked + .tab-content,
3843
3884
  margin-right: calc(0.5rem * var(--tw-space-x-reverse));
3844
3885
  margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
3845
3886
  }
3887
+ .modal-action:where([dir="rtl"], [dir="rtl"] *) > :not([hidden]) ~ :not([hidden]) {
3888
+ --tw-space-x-reverse: 1;
3889
+ }
3846
3890
  @keyframes modal-pop {
3847
3891
 
3848
3892
  0% {
@@ -4899,6 +4943,9 @@ input.tab:checked + .tab-content,
4899
4943
  --tw-translate-y: -50%;
4900
4944
  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));
4901
4945
  }
4946
+ .transform {
4947
+ 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));
4948
+ }
4902
4949
  .cursor-pointer {
4903
4950
  cursor: pointer;
4904
4951
  }
@@ -4908,6 +4955,9 @@ input.tab:checked + .tab-content,
4908
4955
  .list-inside {
4909
4956
  list-style-position: inside;
4910
4957
  }
4958
+ .list-outside {
4959
+ list-style-position: outside;
4960
+ }
4911
4961
  .list-disc {
4912
4962
  list-style-type: disc;
4913
4963
  }
@@ -5228,14 +5278,15 @@ input.tab:checked + .tab-content,
5228
5278
  font-size: 2.25rem;
5229
5279
  line-height: 2.5rem;
5230
5280
  }
5231
- }`;
5232
- var __defProp$d = Object.defineProperty;
5233
- var __decorateClass$d = (decorators, target, key, kind) => {
5281
+ }
5282
+ `;
5283
+ var __defProp$e = Object.defineProperty;
5284
+ var __decorateClass$e = (decorators, target, key, kind) => {
5234
5285
  var result = void 0;
5235
5286
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
5236
5287
  if (decorator = decorators[i2])
5237
5288
  result = decorator(target, key, result) || result;
5238
- if (result) __defProp$d(target, key, result);
5289
+ if (result) __defProp$e(target, key, result);
5239
5290
  return result;
5240
5291
  };
5241
5292
  const tailwindElementCss = unsafeCSS(tailwindStyle);
@@ -5257,10 +5308,10 @@ const _PreactLitAdapter = class _PreactLitAdapter extends ReactiveElement {
5257
5308
  };
5258
5309
  _PreactLitAdapter.styles = [tailwindElementCss, minMaxPercentSliderElementCss];
5259
5310
  let PreactLitAdapter = _PreactLitAdapter;
5260
- __decorateClass$d([
5311
+ __decorateClass$e([
5261
5312
  consume({ context: lapisContext })
5262
5313
  ], PreactLitAdapter.prototype, "lapis");
5263
- __decorateClass$d([
5314
+ __decorateClass$e([
5264
5315
  consume({ context: referenceGenomeContext, subscribe: true })
5265
5316
  ], PreactLitAdapter.prototype, "referenceGenome");
5266
5317
  const gridJsElementCss = unsafeCSS(gridJsStyle);
@@ -5268,14 +5319,14 @@ const _PreactLitAdapterWithGridJsStyles = class _PreactLitAdapterWithGridJsStyle
5268
5319
  };
5269
5320
  _PreactLitAdapterWithGridJsStyles.styles = [...PreactLitAdapter.styles, gridJsElementCss];
5270
5321
  let PreactLitAdapterWithGridJsStyles = _PreactLitAdapterWithGridJsStyles;
5271
- var __defProp$c = Object.defineProperty;
5272
- var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
5273
- var __decorateClass$c = (decorators, target, key, kind) => {
5274
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
5322
+ var __defProp$d = Object.defineProperty;
5323
+ var __getOwnPropDesc$d = Object.getOwnPropertyDescriptor;
5324
+ var __decorateClass$d = (decorators, target, key, kind) => {
5325
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$d(target, key) : target;
5275
5326
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
5276
5327
  if (decorator = decorators[i2])
5277
5328
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
5278
- if (kind && result) __defProp$c(target, key, result);
5329
+ if (kind && result) __defProp$d(target, key, result);
5279
5330
  return result;
5280
5331
  };
5281
5332
  let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles {
@@ -5302,25 +5353,25 @@ let MutationComparisonComponent = class extends PreactLitAdapterWithGridJsStyles
5302
5353
  );
5303
5354
  }
5304
5355
  };
5305
- __decorateClass$c([
5356
+ __decorateClass$d([
5306
5357
  n2({ type: Array })
5307
5358
  ], MutationComparisonComponent.prototype, "lapisFilters", 2);
5308
- __decorateClass$c([
5359
+ __decorateClass$d([
5309
5360
  n2({ type: String })
5310
5361
  ], MutationComparisonComponent.prototype, "sequenceType", 2);
5311
- __decorateClass$c([
5362
+ __decorateClass$d([
5312
5363
  n2({ type: Array })
5313
5364
  ], MutationComparisonComponent.prototype, "views", 2);
5314
- __decorateClass$c([
5365
+ __decorateClass$d([
5315
5366
  n2({ type: String })
5316
5367
  ], MutationComparisonComponent.prototype, "width", 2);
5317
- __decorateClass$c([
5368
+ __decorateClass$d([
5318
5369
  n2({ type: String })
5319
5370
  ], MutationComparisonComponent.prototype, "height", 2);
5320
- __decorateClass$c([
5371
+ __decorateClass$d([
5321
5372
  n2({ type: Object })
5322
5373
  ], MutationComparisonComponent.prototype, "pageSize", 2);
5323
- MutationComparisonComponent = __decorateClass$c([
5374
+ MutationComparisonComponent = __decorateClass$d([
5324
5375
  t$2("gs-mutation-comparison")
5325
5376
  ], MutationComparisonComponent);
5326
5377
  function getInsertionsTableData(data) {
@@ -5589,10 +5640,19 @@ function filterMutationsData(data, displayedSegments, displayedMutationTypes) {
5589
5640
  gridData: filteredSubstitutionsOrDeletions
5590
5641
  };
5591
5642
  }
5643
+ const viewSchema$4 = z$1.union([z$1.literal(views.table), z$1.literal(views.grid), z$1.literal(views.insertions)]);
5644
+ const mutationsPropsSchema = z$1.object({
5645
+ lapisFilter: lapisFilterSchema,
5646
+ sequenceType: sequenceTypeSchema,
5647
+ views: viewSchema$4.array(),
5648
+ pageSize: z$1.union([z$1.boolean(), z$1.number()]),
5649
+ width: z$1.string(),
5650
+ height: z$1.string()
5651
+ });
5592
5652
  const Mutations = (componentProps) => {
5593
5653
  const { width, height } = componentProps;
5594
5654
  const size = { height, width };
5595
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsInner, { ...componentProps }) }) });
5655
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, componentProps, schema: mutationsPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsInner, { ...componentProps }) }) });
5596
5656
  };
5597
5657
  const MutationsInner = (componentProps) => {
5598
5658
  const lapis = x(LapisUrlContext);
@@ -5655,7 +5715,7 @@ const MutationsTabs = ({ mutationsData, originalComponentProps }) => {
5655
5715
  };
5656
5716
  const tabs = originalComponentProps.views.map((view) => getTab(view));
5657
5717
  const toolbar = (activeTab) => /* @__PURE__ */ u$1(
5658
- Toolbar$4,
5718
+ Toolbar$5,
5659
5719
  {
5660
5720
  activeTab,
5661
5721
  displayedSegments,
@@ -5670,7 +5730,7 @@ const MutationsTabs = ({ mutationsData, originalComponentProps }) => {
5670
5730
  );
5671
5731
  return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
5672
5732
  };
5673
- const Toolbar$4 = ({
5733
+ const Toolbar$5 = ({
5674
5734
  activeTab,
5675
5735
  displayedSegments,
5676
5736
  setDisplayedSegments,
@@ -5758,14 +5818,14 @@ const MutationsInfo = ({ originalComponentProps }) => {
5758
5818
  /* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutations", params: originalComponentProps, lapisUrl: lapis })
5759
5819
  ] });
5760
5820
  };
5761
- var __defProp$b = Object.defineProperty;
5762
- var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
5763
- var __decorateClass$b = (decorators, target, key, kind) => {
5764
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
5821
+ var __defProp$c = Object.defineProperty;
5822
+ var __getOwnPropDesc$c = Object.getOwnPropertyDescriptor;
5823
+ var __decorateClass$c = (decorators, target, key, kind) => {
5824
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$c(target, key) : target;
5765
5825
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
5766
5826
  if (decorator = decorators[i2])
5767
5827
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
5768
- if (kind && result) __defProp$b(target, key, result);
5828
+ if (kind && result) __defProp$c(target, key, result);
5769
5829
  return result;
5770
5830
  };
5771
5831
  let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
@@ -5792,25 +5852,25 @@ let MutationsComponent = class extends PreactLitAdapterWithGridJsStyles {
5792
5852
  );
5793
5853
  }
5794
5854
  };
5795
- __decorateClass$b([
5855
+ __decorateClass$c([
5796
5856
  n2({ type: Object })
5797
5857
  ], MutationsComponent.prototype, "lapisFilter", 2);
5798
- __decorateClass$b([
5858
+ __decorateClass$c([
5799
5859
  n2({ type: String })
5800
5860
  ], MutationsComponent.prototype, "sequenceType", 2);
5801
- __decorateClass$b([
5861
+ __decorateClass$c([
5802
5862
  n2({ type: Array })
5803
5863
  ], MutationsComponent.prototype, "views", 2);
5804
- __decorateClass$b([
5864
+ __decorateClass$c([
5805
5865
  n2({ type: String })
5806
5866
  ], MutationsComponent.prototype, "width", 2);
5807
- __decorateClass$b([
5867
+ __decorateClass$c([
5808
5868
  n2({ type: String })
5809
5869
  ], MutationsComponent.prototype, "height", 2);
5810
- __decorateClass$b([
5870
+ __decorateClass$c([
5811
5871
  n2({ type: Object })
5812
5872
  ], MutationsComponent.prototype, "pageSize", 2);
5813
- MutationsComponent = __decorateClass$b([
5873
+ MutationsComponent = __decorateClass$c([
5814
5874
  t$2("gs-mutations")
5815
5875
  ], MutationsComponent);
5816
5876
  function getPrevalenceOverTimeTableData(data, granularity) {
@@ -5894,6 +5954,12 @@ const confidenceIntervalDataLabel = (value, lowerLimit, upperLimit, prefix) => {
5894
5954
  const label = prefix ? `${prefix}: ` : "";
5895
5955
  return `${label}${value.toFixed(3)} (${lowerLimit == null ? void 0 : lowerLimit.toFixed(3)} - ${upperLimit == null ? void 0 : upperLimit.toFixed(3)})`;
5896
5956
  };
5957
+ const confidenceIntervalMethodSchema = z$1.union([z$1.literal("wilson"), z$1.literal("none")]);
5958
+ const axisMaxSchema = z$1.union([z$1.literal("maxInData"), z$1.literal("limitTo1"), z$1.number()]);
5959
+ const yAxisMaxConfigSchema = z$1.object({
5960
+ linear: axisMaxSchema.optional(),
5961
+ logarithmic: axisMaxSchema.optional()
5962
+ });
5897
5963
  const getYAxisMax = (maxInData2, axisMax) => {
5898
5964
  if (!axisMax) {
5899
5965
  return 1;
@@ -6499,6 +6565,7 @@ const advancedFormat = function(o2, c2) {
6499
6565
  return _this.isoWeekYear();
6500
6566
  case "wo":
6501
6567
  return locale.ordinal(_this.week(), "W");
6568
+ // W for week
6502
6569
  case "w":
6503
6570
  case "ww":
6504
6571
  return utils.s(_this.week(), match === "w" ? 1 : 2, "0");
@@ -7476,10 +7543,30 @@ const ScalingSelector = ({
7476
7543
  }
7477
7544
  );
7478
7545
  };
7546
+ const viewSchema$3 = z$1.union([
7547
+ z$1.literal(views.table),
7548
+ z$1.literal(views.bar),
7549
+ z$1.literal(views.line),
7550
+ z$1.literal(views.bubble)
7551
+ ]);
7552
+ const prevalenceOverTimePropsSchema = z$1.object({
7553
+ width: z$1.string(),
7554
+ height: z$1.string(),
7555
+ numeratorFilter: z$1.union([namedLapisFilterSchema, z$1.array(namedLapisFilterSchema)]),
7556
+ denominatorFilter: lapisFilterSchema,
7557
+ granularity: temporalGranularitySchema,
7558
+ smoothingWindow: z$1.number(),
7559
+ views: z$1.array(viewSchema$3),
7560
+ confidenceIntervalMethods: z$1.array(confidenceIntervalMethodSchema),
7561
+ lapisDateField: z$1.string().min(1),
7562
+ pageSize: z$1.union([z$1.boolean(), z$1.number()]),
7563
+ yAxisMaxLinear: axisMaxSchema,
7564
+ yAxisMaxLogarithmic: axisMaxSchema
7565
+ });
7479
7566
  const PrevalenceOverTime = (componentProps) => {
7480
7567
  const { width, height } = componentProps;
7481
7568
  const size = { height, width };
7482
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(PrevalenceOverTimeInner, { ...componentProps }) }) });
7569
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: prevalenceOverTimePropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(PrevalenceOverTimeInner, { ...componentProps }) }) });
7483
7570
  };
7484
7571
  const PrevalenceOverTimeInner = (componentProps) => {
7485
7572
  const { numeratorFilter, denominatorFilter, granularity, smoothingWindow, lapisDateField } = componentProps;
@@ -7507,7 +7594,7 @@ const PrevalenceOverTimeInner = (componentProps) => {
7507
7594
  return /* @__PURE__ */ u$1(PrevalenceOverTimeTabs, { data, ...componentProps });
7508
7595
  };
7509
7596
  const PrevalenceOverTimeTabs = ({ data, ...componentProps }) => {
7510
- const { views, granularity, confidenceIntervalMethods, pageSize, yAxisMaxLinear, yAxisMaxLogarithmic } = componentProps;
7597
+ const { views: views2, granularity, confidenceIntervalMethods, pageSize, yAxisMaxLinear, yAxisMaxLogarithmic } = componentProps;
7511
7598
  const [yAxisScaleType, setYAxisScaleType] = h("linear");
7512
7599
  const [confidenceIntervalMethod, setConfidenceIntervalMethod] = h(
7513
7600
  confidenceIntervalMethods.length > 0 ? confidenceIntervalMethods[0] : "none"
@@ -7568,9 +7655,9 @@ const PrevalenceOverTimeTabs = ({ data, ...componentProps }) => {
7568
7655
  };
7569
7656
  }
7570
7657
  };
7571
- const tabs = views.map((view) => getTab(view));
7658
+ const tabs = views2.map((view) => getTab(view));
7572
7659
  const toolbar = (activeTab) => /* @__PURE__ */ u$1(
7573
- Toolbar$3,
7660
+ Toolbar$4,
7574
7661
  {
7575
7662
  activeTab,
7576
7663
  yAxisScaleType,
@@ -7583,7 +7670,7 @@ const PrevalenceOverTimeTabs = ({ data, ...componentProps }) => {
7583
7670
  );
7584
7671
  return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
7585
7672
  };
7586
- const Toolbar$3 = ({
7673
+ const Toolbar$4 = ({
7587
7674
  activeTab,
7588
7675
  yAxisScaleType,
7589
7676
  setYAxisScaleType,
@@ -7616,7 +7703,7 @@ const Toolbar$3 = ({
7616
7703
  ] });
7617
7704
  };
7618
7705
  const PrevalenceOverTimeInfo = (componentProps) => {
7619
- const { granularity, smoothingWindow, views } = componentProps;
7706
+ const { granularity, smoothingWindow, views: views2 } = componentProps;
7620
7707
  const lapis = x(LapisUrlContext);
7621
7708
  return /* @__PURE__ */ u$1(Info, { children: [
7622
7709
  /* @__PURE__ */ u$1(InfoHeadline1, { children: "Prevalence over time" }),
@@ -7629,7 +7716,7 @@ const PrevalenceOverTimeInfo = (componentProps) => {
7629
7716
  " (see below)."
7630
7717
  ] }),
7631
7718
  /* @__PURE__ */ u$1(InfoParagraph, { children: 'Sequences that have no assigned date will not be shown in the line and bubble chart. They will show up in the bar and table view with date "unknown".' }),
7632
- views.includes("bubble") && /* @__PURE__ */ u$1(Fragment, { children: [
7719
+ views2.includes("bubble") && /* @__PURE__ */ u$1(Fragment, { children: [
7633
7720
  /* @__PURE__ */ u$1(InfoHeadline2, { children: "Bubble chart" }),
7634
7721
  /* @__PURE__ */ u$1(InfoParagraph, { children: [
7635
7722
  "The size of the bubble scales with the total number of available sequences from the",
@@ -7642,14 +7729,14 @@ const PrevalenceOverTimeInfo = (componentProps) => {
7642
7729
  ] });
7643
7730
  };
7644
7731
  const maxInData = (data) => Math.max(...data.flatMap((variant) => variant.content.map((dataPoint) => dataPoint.prevalence)));
7645
- var __defProp$a = Object.defineProperty;
7646
- var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
7647
- var __decorateClass$a = (decorators, target, key, kind) => {
7648
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
7732
+ var __defProp$b = Object.defineProperty;
7733
+ var __getOwnPropDesc$b = Object.getOwnPropertyDescriptor;
7734
+ var __decorateClass$b = (decorators, target, key, kind) => {
7735
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$b(target, key) : target;
7649
7736
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
7650
7737
  if (decorator = decorators[i2])
7651
7738
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
7652
- if (kind && result) __defProp$a(target, key, result);
7739
+ if (kind && result) __defProp$b(target, key, result);
7653
7740
  return result;
7654
7741
  };
7655
7742
  let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
@@ -7663,7 +7750,7 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
7663
7750
  this.confidenceIntervalMethods = ["none", "wilson"];
7664
7751
  this.width = "100%";
7665
7752
  this.height = "700px";
7666
- this.lapisDateField = "date";
7753
+ this.lapisDateField = "";
7667
7754
  this.pageSize = false;
7668
7755
  this.yAxisMaxLinear = 1;
7669
7756
  this.yAxisMaxLogarithmic = 1;
@@ -7688,43 +7775,43 @@ let PrevalenceOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
7688
7775
  );
7689
7776
  }
7690
7777
  };
7691
- __decorateClass$a([
7778
+ __decorateClass$b([
7692
7779
  n2({ type: Object })
7693
7780
  ], PrevalenceOverTimeComponent.prototype, "numeratorFilter", 2);
7694
- __decorateClass$a([
7781
+ __decorateClass$b([
7695
7782
  n2({ type: Object })
7696
7783
  ], PrevalenceOverTimeComponent.prototype, "denominatorFilter", 2);
7697
- __decorateClass$a([
7784
+ __decorateClass$b([
7698
7785
  n2({ type: String })
7699
7786
  ], PrevalenceOverTimeComponent.prototype, "granularity", 2);
7700
- __decorateClass$a([
7787
+ __decorateClass$b([
7701
7788
  n2({ type: Number })
7702
7789
  ], PrevalenceOverTimeComponent.prototype, "smoothingWindow", 2);
7703
- __decorateClass$a([
7790
+ __decorateClass$b([
7704
7791
  n2({ type: Array })
7705
7792
  ], PrevalenceOverTimeComponent.prototype, "views", 2);
7706
- __decorateClass$a([
7793
+ __decorateClass$b([
7707
7794
  n2({ type: Array })
7708
7795
  ], PrevalenceOverTimeComponent.prototype, "confidenceIntervalMethods", 2);
7709
- __decorateClass$a([
7796
+ __decorateClass$b([
7710
7797
  n2({ type: String })
7711
7798
  ], PrevalenceOverTimeComponent.prototype, "width", 2);
7712
- __decorateClass$a([
7799
+ __decorateClass$b([
7713
7800
  n2({ type: String })
7714
7801
  ], PrevalenceOverTimeComponent.prototype, "height", 2);
7715
- __decorateClass$a([
7802
+ __decorateClass$b([
7716
7803
  n2({ type: String })
7717
7804
  ], PrevalenceOverTimeComponent.prototype, "lapisDateField", 2);
7718
- __decorateClass$a([
7805
+ __decorateClass$b([
7719
7806
  n2({ type: Object })
7720
7807
  ], PrevalenceOverTimeComponent.prototype, "pageSize", 2);
7721
- __decorateClass$a([
7808
+ __decorateClass$b([
7722
7809
  n2({ type: String })
7723
7810
  ], PrevalenceOverTimeComponent.prototype, "yAxisMaxLinear", 2);
7724
- __decorateClass$a([
7811
+ __decorateClass$b([
7725
7812
  n2({ type: String })
7726
7813
  ], PrevalenceOverTimeComponent.prototype, "yAxisMaxLogarithmic", 2);
7727
- PrevalenceOverTimeComponent = __decorateClass$a([
7814
+ PrevalenceOverTimeComponent = __decorateClass$b([
7728
7815
  t$2("gs-prevalence-over-time")
7729
7816
  ], PrevalenceOverTimeComponent);
7730
7817
  Chart.register(...registerables, LogitScale);
@@ -7954,10 +8041,21 @@ function toYearMonthDay(d2) {
7954
8041
  count: d2.count
7955
8042
  };
7956
8043
  }
8044
+ const viewSchema$2 = z$1.literal(views.line);
8045
+ const relativeGrowthAdvantagePropsSchema = z$1.object({
8046
+ width: z$1.string(),
8047
+ height: z$1.string(),
8048
+ numeratorFilter: lapisFilterSchema,
8049
+ denominatorFilter: lapisFilterSchema,
8050
+ generationTime: z$1.number(),
8051
+ views: z$1.array(viewSchema$2),
8052
+ lapisDateField: z$1.string().min(1),
8053
+ yAxisMaxConfig: yAxisMaxConfigSchema
8054
+ });
7957
8055
  const RelativeGrowthAdvantage = (componentProps) => {
7958
8056
  const { width, height } = componentProps;
7959
8057
  const size = { height, width };
7960
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(RelativeGrowthAdvantageInner, { ...componentProps }) }) });
8058
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: relativeGrowthAdvantagePropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(RelativeGrowthAdvantageInner, { ...componentProps }) }) });
7961
8059
  };
7962
8060
  const RelativeGrowthAdvantageInner = (componentProps) => {
7963
8061
  const lapis = x(LapisUrlContext);
@@ -8070,14 +8168,14 @@ const RelativeGrowthAdvantageInfo = ({
8070
8168
  )
8071
8169
  ] });
8072
8170
  };
8073
- var __defProp$9 = Object.defineProperty;
8074
- var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
8075
- var __decorateClass$9 = (decorators, target, key, kind) => {
8076
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
8171
+ var __defProp$a = Object.defineProperty;
8172
+ var __getOwnPropDesc$a = Object.getOwnPropertyDescriptor;
8173
+ var __decorateClass$a = (decorators, target, key, kind) => {
8174
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$a(target, key) : target;
8077
8175
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
8078
8176
  if (decorator = decorators[i2])
8079
8177
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8080
- if (kind && result) __defProp$9(target, key, result);
8178
+ if (kind && result) __defProp$a(target, key, result);
8081
8179
  return result;
8082
8180
  };
8083
8181
  let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
@@ -8089,7 +8187,7 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
8089
8187
  this.views = ["line"];
8090
8188
  this.width = "100%";
8091
8189
  this.height = "700px";
8092
- this.lapisDateField = "date";
8190
+ this.lapisDateField = "";
8093
8191
  this.yAxisMaxLinear = 1;
8094
8192
  this.yAxisMaxLogarithmic = 1;
8095
8193
  }
@@ -8112,34 +8210,34 @@ let RelativeGrowthAdvantageComponent = class extends PreactLitAdapter {
8112
8210
  );
8113
8211
  }
8114
8212
  };
8115
- __decorateClass$9([
8213
+ __decorateClass$a([
8116
8214
  n2({ type: Object })
8117
8215
  ], RelativeGrowthAdvantageComponent.prototype, "numeratorFilter", 2);
8118
- __decorateClass$9([
8216
+ __decorateClass$a([
8119
8217
  n2({ type: Object })
8120
8218
  ], RelativeGrowthAdvantageComponent.prototype, "denominatorFilter", 2);
8121
- __decorateClass$9([
8219
+ __decorateClass$a([
8122
8220
  n2({ type: Number })
8123
8221
  ], RelativeGrowthAdvantageComponent.prototype, "generationTime", 2);
8124
- __decorateClass$9([
8222
+ __decorateClass$a([
8125
8223
  n2({ type: Array })
8126
8224
  ], RelativeGrowthAdvantageComponent.prototype, "views", 2);
8127
- __decorateClass$9([
8225
+ __decorateClass$a([
8128
8226
  n2({ type: String })
8129
8227
  ], RelativeGrowthAdvantageComponent.prototype, "width", 2);
8130
- __decorateClass$9([
8228
+ __decorateClass$a([
8131
8229
  n2({ type: String })
8132
8230
  ], RelativeGrowthAdvantageComponent.prototype, "height", 2);
8133
- __decorateClass$9([
8231
+ __decorateClass$a([
8134
8232
  n2({ type: String })
8135
8233
  ], RelativeGrowthAdvantageComponent.prototype, "lapisDateField", 2);
8136
- __decorateClass$9([
8234
+ __decorateClass$a([
8137
8235
  n2({ type: String })
8138
8236
  ], RelativeGrowthAdvantageComponent.prototype, "yAxisMaxLinear", 2);
8139
- __decorateClass$9([
8237
+ __decorateClass$a([
8140
8238
  n2({ type: String })
8141
8239
  ], RelativeGrowthAdvantageComponent.prototype, "yAxisMaxLogarithmic", 2);
8142
- RelativeGrowthAdvantageComponent = __decorateClass$9([
8240
+ RelativeGrowthAdvantageComponent = __decorateClass$a([
8143
8241
  t$2("gs-relative-growth-advantage")
8144
8242
  ], RelativeGrowthAdvantageComponent);
8145
8243
  const compareAscending = (a2, b3) => {
@@ -8190,10 +8288,21 @@ const AggregateTable = ({ data, fields, pageSize }) => {
8190
8288
  ];
8191
8289
  return /* @__PURE__ */ u$1(Table, { data, columns: headers, pageSize });
8192
8290
  };
8291
+ const viewSchema$1 = z$1.literal(views.table);
8292
+ const aggregatePropsSchema = z$1.object({
8293
+ filter: lapisFilterSchema,
8294
+ fields: z$1.array(z$1.string().min(1)),
8295
+ views: z$1.array(viewSchema$1),
8296
+ initialSortField: z$1.string(),
8297
+ initialSortDirection: z$1.union([z$1.literal("ascending"), z$1.literal("descending")]),
8298
+ pageSize: z$1.union([z$1.boolean(), z$1.number()]),
8299
+ width: z$1.string(),
8300
+ height: z$1.string()
8301
+ });
8193
8302
  const Aggregate = (componentProps) => {
8194
8303
  const { width, height } = componentProps;
8195
8304
  const size = { height, width };
8196
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(AggregateInner, { ...componentProps }) }) });
8305
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: aggregatePropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(AggregateInner, { ...componentProps }) }) });
8197
8306
  };
8198
8307
  const AggregateInner = (componentProps) => {
8199
8308
  const { fields, filter, initialSortField, initialSortDirection } = componentProps;
@@ -8230,9 +8339,9 @@ const AggregatedDataTabs = ({ data, originalComponentProps }) => {
8230
8339
  }
8231
8340
  };
8232
8341
  const tabs = originalComponentProps.views.map((view) => getTab(view));
8233
- return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar$2, { data, originalComponentProps }) });
8342
+ return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar$3, { data, originalComponentProps }) });
8234
8343
  };
8235
- const Toolbar$2 = ({ data, originalComponentProps }) => {
8344
+ const Toolbar$3 = ({ data, originalComponentProps }) => {
8236
8345
  return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
8237
8346
  /* @__PURE__ */ u$1(CsvDownloadButton, { className: "mx-1 btn btn-xs", getData: () => data, filename: "aggregate.csv" }),
8238
8347
  /* @__PURE__ */ u$1(AggregateInfo, { originalComponentProps }),
@@ -8252,14 +8361,14 @@ const AggregateInfo = ({ originalComponentProps }) => {
8252
8361
  /* @__PURE__ */ u$1(InfoComponentCode, { componentName: "aggregate", params: originalComponentProps, lapisUrl: lapis })
8253
8362
  ] });
8254
8363
  };
8255
- var __defProp$8 = Object.defineProperty;
8256
- var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
8257
- var __decorateClass$8 = (decorators, target, key, kind) => {
8258
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
8364
+ var __defProp$9 = Object.defineProperty;
8365
+ var __getOwnPropDesc$9 = Object.getOwnPropertyDescriptor;
8366
+ var __decorateClass$9 = (decorators, target, key, kind) => {
8367
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$9(target, key) : target;
8259
8368
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
8260
8369
  if (decorator = decorators[i2])
8261
8370
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8262
- if (kind && result) __defProp$8(target, key, result);
8371
+ if (kind && result) __defProp$9(target, key, result);
8263
8372
  return result;
8264
8373
  };
8265
8374
  let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
@@ -8290,31 +8399,31 @@ let AggregateComponent = class extends PreactLitAdapterWithGridJsStyles {
8290
8399
  );
8291
8400
  }
8292
8401
  };
8293
- __decorateClass$8([
8402
+ __decorateClass$9([
8294
8403
  n2({ type: Array })
8295
8404
  ], AggregateComponent.prototype, "fields", 2);
8296
- __decorateClass$8([
8405
+ __decorateClass$9([
8297
8406
  n2({ type: Array })
8298
8407
  ], AggregateComponent.prototype, "views", 2);
8299
- __decorateClass$8([
8408
+ __decorateClass$9([
8300
8409
  n2({ type: Object })
8301
8410
  ], AggregateComponent.prototype, "filter", 2);
8302
- __decorateClass$8([
8411
+ __decorateClass$9([
8303
8412
  n2({ type: String })
8304
8413
  ], AggregateComponent.prototype, "width", 2);
8305
- __decorateClass$8([
8414
+ __decorateClass$9([
8306
8415
  n2({ type: String })
8307
8416
  ], AggregateComponent.prototype, "height", 2);
8308
- __decorateClass$8([
8417
+ __decorateClass$9([
8309
8418
  n2({ type: String })
8310
8419
  ], AggregateComponent.prototype, "initialSortField", 2);
8311
- __decorateClass$8([
8420
+ __decorateClass$9([
8312
8421
  n2({ type: String })
8313
8422
  ], AggregateComponent.prototype, "initialSortDirection", 2);
8314
- __decorateClass$8([
8423
+ __decorateClass$9([
8315
8424
  n2({ type: Object })
8316
8425
  ], AggregateComponent.prototype, "pageSize", 2);
8317
- AggregateComponent = __decorateClass$8([
8426
+ AggregateComponent = __decorateClass$9([
8318
8427
  t$2("gs-aggregate")
8319
8428
  ], AggregateComponent);
8320
8429
  const getNumberOfSequencesOverTimeTableData = (data, dateRangeKey) => {
@@ -8473,10 +8582,25 @@ async function queryNumberOfSequencesOverTime(lapis, lapisFilter, lapisDateField
8473
8582
  });
8474
8583
  return Promise.all(queries);
8475
8584
  }
8585
+ const numberSequencesOverTimeViewSchema = z$1.union([
8586
+ z$1.literal(views.bar),
8587
+ z$1.literal(views.line),
8588
+ z$1.literal(views.table)
8589
+ ]);
8590
+ const numberSequencesOverTimePropsSchema = z$1.object({
8591
+ width: z$1.string(),
8592
+ height: z$1.string(),
8593
+ lapisFilter: z$1.union([namedLapisFilterSchema, z$1.array(namedLapisFilterSchema)]),
8594
+ lapisDateField: z$1.string().min(1),
8595
+ views: z$1.array(numberSequencesOverTimeViewSchema),
8596
+ granularity: temporalGranularitySchema,
8597
+ smoothingWindow: z$1.number(),
8598
+ pageSize: z$1.union([z$1.boolean(), z$1.number()])
8599
+ });
8476
8600
  const NumberSequencesOverTime = (componentProps) => {
8477
8601
  const { width, height } = componentProps;
8478
8602
  const size = { height, width };
8479
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(NumberSequencesOverTimeInner, { ...componentProps }) }) });
8603
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, componentProps, schema: numberSequencesOverTimePropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(NumberSequencesOverTimeInner, { ...componentProps }) }) });
8480
8604
  };
8481
8605
  const NumberSequencesOverTimeInner = (componentProps) => {
8482
8606
  const { lapisFilter, lapisDateField, granularity, smoothingWindow } = componentProps;
@@ -8531,7 +8655,7 @@ const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }) => {
8531
8655
  {
8532
8656
  tabs: originalComponentProps.views.map((view) => getTab(view)),
8533
8657
  toolbar: (activeTab) => /* @__PURE__ */ u$1(
8534
- Toolbar$1,
8658
+ Toolbar$2,
8535
8659
  {
8536
8660
  activeTab,
8537
8661
  data,
@@ -8543,7 +8667,7 @@ const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }) => {
8543
8667
  }
8544
8668
  );
8545
8669
  };
8546
- const Toolbar$1 = ({ activeTab, data, yAxisScaleType, setYAxisScaleType, originalComponentProps }) => {
8670
+ const Toolbar$2 = ({ activeTab, data, yAxisScaleType, setYAxisScaleType, originalComponentProps }) => {
8547
8671
  return /* @__PURE__ */ u$1(Fragment, { children: [
8548
8672
  activeTab !== "Table" && /* @__PURE__ */ u$1(
8549
8673
  ScalingSelector,
@@ -8588,21 +8712,21 @@ const NumberSequencesOverTimeInfo = ({
8588
8712
  )
8589
8713
  ] });
8590
8714
  };
8591
- var __defProp$7 = Object.defineProperty;
8592
- var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
8593
- var __decorateClass$7 = (decorators, target, key, kind) => {
8594
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
8715
+ var __defProp$8 = Object.defineProperty;
8716
+ var __getOwnPropDesc$8 = Object.getOwnPropertyDescriptor;
8717
+ var __decorateClass$8 = (decorators, target, key, kind) => {
8718
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$8(target, key) : target;
8595
8719
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
8596
8720
  if (decorator = decorators[i2])
8597
8721
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8598
- if (kind && result) __defProp$7(target, key, result);
8722
+ if (kind && result) __defProp$8(target, key, result);
8599
8723
  return result;
8600
8724
  };
8601
8725
  let NumberSequencesOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
8602
8726
  constructor() {
8603
8727
  super(...arguments);
8604
8728
  this.lapisFilter = { displayName: "", lapisFilter: {} };
8605
- this.lapisDateField = "date";
8729
+ this.lapisDateField = "";
8606
8730
  this.views = ["bar", "line", "table"];
8607
8731
  this.width = "100%";
8608
8732
  this.height = "700px";
@@ -8626,36 +8750,35 @@ let NumberSequencesOverTimeComponent = class extends PreactLitAdapterWithGridJsS
8626
8750
  );
8627
8751
  }
8628
8752
  };
8629
- __decorateClass$7([
8753
+ __decorateClass$8([
8630
8754
  n2({ type: Object })
8631
8755
  ], NumberSequencesOverTimeComponent.prototype, "lapisFilter", 2);
8632
- __decorateClass$7([
8756
+ __decorateClass$8([
8633
8757
  n2({ type: String })
8634
8758
  ], NumberSequencesOverTimeComponent.prototype, "lapisDateField", 2);
8635
- __decorateClass$7([
8759
+ __decorateClass$8([
8636
8760
  n2({ type: Array })
8637
8761
  ], NumberSequencesOverTimeComponent.prototype, "views", 2);
8638
- __decorateClass$7([
8762
+ __decorateClass$8([
8639
8763
  n2({ type: String })
8640
8764
  ], NumberSequencesOverTimeComponent.prototype, "width", 2);
8641
- __decorateClass$7([
8765
+ __decorateClass$8([
8642
8766
  n2({ type: String })
8643
8767
  ], NumberSequencesOverTimeComponent.prototype, "height", 2);
8644
- __decorateClass$7([
8768
+ __decorateClass$8([
8645
8769
  n2({ type: String })
8646
8770
  ], NumberSequencesOverTimeComponent.prototype, "granularity", 2);
8647
- __decorateClass$7([
8771
+ __decorateClass$8([
8648
8772
  n2({ type: Number })
8649
8773
  ], NumberSequencesOverTimeComponent.prototype, "smoothingWindow", 2);
8650
- __decorateClass$7([
8774
+ __decorateClass$8([
8651
8775
  n2({ type: Object })
8652
8776
  ], NumberSequencesOverTimeComponent.prototype, "pageSize", 2);
8653
- NumberSequencesOverTimeComponent = __decorateClass$7([
8777
+ NumberSequencesOverTimeComponent = __decorateClass$8([
8654
8778
  t$2("gs-number-sequences-over-time")
8655
8779
  ], NumberSequencesOverTimeComponent);
8656
- 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/IHZvaWQgMCwgbXV0YXRpb25Gcm9tLCBtdXRhdGlvblRvLCBwb3NpdGlvbiksCiAgICAgICAgICAgIGNvdW50LAogICAgICAgICAgICBwcm9wb3J0aW9uCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgKTsKICAgICAgcmV0dXJuIHsgY29udGVudCB9OwogICAgfQogICAgYXN5bmMgZmV0Y2hNdXRhdGlvbnMobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBmaWx0ZXIgPSB7CiAgICAgICAgLi4udGhpcy5maWx0ZXIsCiAgICAgICAgbWluUHJvcG9ydGlvbjogdGhpcy5taW5Qcm9wb3J0aW9uCiAgICAgIH07CiAgICAgIHJldHVybiBmZXRjaFN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhsYXBpcywgZmlsdGVyLCB0aGlzLnNlcXVlbmNlVHlwZSwgc2lnbmFsKS50aGVuKAogICAgICAgIChyZXNwb25zZSkgPT4gcmVzcG9uc2UuZGF0YQogICAgICApOwogICAgfQogIH0KICB2YXIgbCQxOwogIGwkMSA9IHsgX19lOiBmdW5jdGlvbihuLCBsMiwgdTIsIHQpIHsKICAgIGZvciAodmFyIGkyLCBvLCByMjsgbDIgPSBsMi5fXzsgKSBpZiAoKGkyID0gbDIuX19jKSAmJiAhaTIuX18pIHRyeSB7CiAgICAgIGlmICgobyA9IGkyLmNvbnN0cnVjdG9yKSAmJiBudWxsICE9IG8uZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yICYmIChpMi5zZXRTdGF0ZShvLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcihuKSksIHIyID0gaTIuX19kKSwgbnVsbCAhPSBpMi5jb21wb25lbnREaWRDYXRjaCAmJiAoaTIuY29tcG9uZW50RGlkQ2F0Y2gobiwgdCB8fCB7fSksIHIyID0gaTIuX19kKSwgcjIpIHJldHVybiBpMi5fX0UgPSBpMjsKICAgIH0gY2F0Y2ggKGwzKSB7CiAgICAgIG4gPSBsMzsKICAgIH0KICAgIHRocm93IG47CiAgfSB9LCAiZnVuY3Rpb24iID09IHR5cGVvZiBQcm9taXNlID8gUHJvbWlzZS5wcm90b3R5cGUudGhlbi5iaW5kKFByb21pc2UucmVzb2x2ZSgpKSA6IHNldFRpbWVvdXQ7CiAgdmFyIHIsIHUsIGksIGYgPSBbXSwgYyA9IGwkMSwgZSA9IGMuX19iLCBhID0gYy5fX3IsIHYgPSBjLmRpZmZlZCwgbCA9IGMuX19jLCBtID0gYy51bm1vdW50LCBzID0gYy5fXzsKICBmdW5jdGlvbiBqKCkgewogICAgZm9yICh2YXIgbjsgbiA9IGYuc2hpZnQoKTsgKSBpZiAobi5fX1AgJiYgbi5fX0gpIHRyeSB7CiAgICAgIG4uX19ILl9faC5mb3JFYWNoKHopLCBuLl9fSC5fX2guZm9yRWFjaChCKSwgbi5fX0guX19oID0gW107CiAgICB9IGNhdGNoICh0KSB7CiAgICAgIG4uX19ILl9faCA9IFtdLCBjLl9fZSh0LCBuLl9fdik7CiAgICB9CiAgfQogIGMuX19iID0gZnVuY3Rpb24obikgewogICAgciA9IG51bGwsIGUgJiYgZShuKTsKICB9LCBjLl9fID0gZnVuY3Rpb24obiwgdCkgewogICAgbiAmJiB0Ll9fayAmJiB0Ll9fay5fX20gJiYgKG4uX19tID0gdC5fX2suX19tKSwgcyAmJiBzKG4sIHQpOwogIH0sIGMuX19yID0gZnVuY3Rpb24obikgewogICAgYSAmJiBhKG4pOwogICAgdmFyIGkyID0gKHIgPSBuLl9fYykuX19IOwogICAgaTIgJiYgKHUgPT09IHIgPyAoaTIuX19oID0gW10sIHIuX19oID0gW10sIGkyLl9fLmZvckVhY2goZnVuY3Rpb24objIpIHsKICAgICAgbjIuX19OICYmIChuMi5fXyA9IG4yLl9fTiksIG4yLmkgPSBuMi5fX04gPSB2b2lkIDA7CiAgICB9KSkgOiAoaTIuX19oLmZvckVhY2goeiksIGkyLl9faC5mb3JFYWNoKEIpLCBpMi5fX2ggPSBbXSwgMCkpLCB1ID0gcjsKICB9LCBjLmRpZmZlZCA9IGZ1bmN0aW9uKG4pIHsKICAgIHYgJiYgdihuKTsKICAgIHZhciB0ID0gbi5fX2M7CiAgICB0ICYmIHQuX19IICYmICh0Ll9fSC5fX2gubGVuZ3RoICYmICgxICE9PSBmLnB1c2godCkgJiYgaSA9PT0gYy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgKChpID0gYy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHx8IHcpKGopKSwgdC5fX0guX18uZm9yRWFjaChmdW5jdGlvbihuMikgewogICAgICBuMi5pICYmIChuMi5fX0ggPSBuMi5pKSwgbjIuaSA9IHZvaWQgMDsKICAgIH0pKSwgdSA9IHIgPSBudWxsOwogIH0sIGMuX19jID0gZnVuY3Rpb24obiwgdCkgewogICAgdC5zb21lKGZ1bmN0aW9uKG4yKSB7CiAgICAgIHRyeSB7CiAgICAgICAgbjIuX19oLmZvckVhY2goeiksIG4yLl9faCA9IG4yLl9faC5maWx0ZXIoZnVuY3Rpb24objMpIHsKICAgICAgICAgIHJldHVybiAhbjMuX18gfHwgQihuMyk7CiAgICAgICAgfSk7CiAgICAgIH0gY2F0Y2ggKHIyKSB7CiAgICAgICAgdC5zb21lKGZ1bmN0aW9uKG4zKSB7CiAgICAgICAgICBuMy5fX2ggJiYgKG4zLl9faCA9IFtdKTsKICAgICAgICB9KSwgdCA9IFtdLCBjLl9fZShyMiwgbjIuX192KTsKICAgICAgfQogICAgfSksIGwgJiYgbChuLCB0KTsKICB9LCBjLnVubW91bnQgPSBmdW5jdGlvbihuKSB7CiAgICBtICYmIG0obik7CiAgICB2YXIgdCwgcjIgPSBuLl9fYzsKICAgIHIyICYmIHIyLl9fSCAmJiAocjIuX19ILl9fLmZvckVhY2goZnVuY3Rpb24objIpIHsKICAgICAgdHJ5IHsKICAgICAgICB6KG4yKTsKICAgICAgfSBjYXRjaCAobjMpIHsKICAgICAgICB0ID0gbjM7CiAgICAgIH0KICAgIH0pLCByMi5fX0ggPSB2b2lkIDAsIHQgJiYgYy5fX2UodCwgcjIuX192KSk7CiAgfTsKICB2YXIgayA9ICJmdW5jdGlvbiIgPT0gdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZTsKICBmdW5jdGlvbiB3KG4pIHsKICAgIHZhciB0LCByMiA9IGZ1bmN0aW9uKCkgewogICAgICBjbGVhclRpbWVvdXQodTIpLCBrICYmIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHQpLCBzZXRUaW1lb3V0KG4pOwogICAgfSwgdTIgPSBzZXRUaW1lb3V0KHIyLCAxMDApOwogICAgayAmJiAodCA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShyMikpOwogIH0KICBmdW5jdGlvbiB6KG4pIHsKICAgIHZhciB0ID0gciwgdTIgPSBuLl9fYzsKICAgICJmdW5jdGlvbiIgPT0gdHlwZW9mIHUyICYmIChuLl9fYyA9IHZvaWQgMCwgdTIoKSksIHIgPSB0OwogIH0KICBmdW5jdGlvbiBCKG4pIHsKICAgIHZhciB0ID0gcjsKICAgIG4uX19jID0gbi5fXygpLCByID0gdDsKICB9CiAgY2xhc3MgVXNlckZhY2luZ0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IoaGVhZGxpbmUsIG1lc3NhZ2UpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuaGVhZGxpbmUgPSBoZWFkbGluZTsKICAgICAgdGhpcy5uYW1lID0gIlVzZXJGYWNpbmdFcnJvciI7CiAgICB9CiAgfQogIGNsYXNzIE1hcDJkQmFzZSB7CiAgICBjb25zdHJ1Y3RvcihzZXJpYWxpemVGaXJzdEF4aXMsIHNlcmlhbGl6ZVNlY29uZEF4aXMsIGluaXRpYWxDb250ZW50KSB7CiAgICAgIHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzID0gc2VyaWFsaXplRmlyc3RBeGlzOwogICAgICB0aGlzLnNlcmlhbGl6ZVNlY29uZEF4aXMgPSBzZXJpYWxpemVTZWNvbmRBeGlzOwogICAgICB0aGlzLmRhdGEgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLmtleXNGaXJzdEF4aXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLmtleXNTZWNvbmRBeGlzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgaWYgKGluaXRpYWxDb250ZW50KSB7CiAgICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5rZXlzRmlyc3RBeGlzKTsKICAgICAgICB0aGlzLmtleXNTZWNvbmRBeGlzID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5rZXlzU2Vjb25kQXhpcyk7CiAgICAgICAgdGhpcy5kYXRhID0gbmV3IE1hcChpbml0aWFsQ29udGVudC5kYXRhKTsKICAgICAgfQogICAgfQogICAgZ2V0KGtleUZpcnN0QXhpcywga2V5U2Vjb25kQXhpcykgewogICAgICB2YXIgX2E7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMgPSB0aGlzLnNlcmlhbGl6ZUZpcnN0QXhpcyhrZXlGaXJzdEF4aXMpOwogICAgICBjb25zdCBzZXJpYWxpemVkS2V5U2Vjb25kQXhpcyA9IHRoaXMuc2VyaWFsaXplU2Vjb25kQXhpcyhrZXlTZWNvbmRBeGlzKTsKICAgICAgcmV0dXJuIChfYSA9IHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcykpID09IG51bGwgPyB2b2lkIDAgOiBfYS5nZXQoc2VyaWFsaXplZEtleVNlY29uZEF4aXMpOwogICAgfQogICAgZ2V0Um93KGtleSkgewogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5KTsKICAgICAgY29uc3Qgcm93ID0gdGhpcy5kYXRhLmdldChzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgICAgaWYgKHJvdyA9PT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIFtdOwogICAgICB9CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c1NlY29uZEF4aXMua2V5cygpKS5tYXAoKGtleTIpID0+IHJvdy5nZXQoa2V5MikpOwogICAgfQogICAgc2V0KGtleUZpcnN0QXhpcywga2V5U2Vjb25kQXhpcywgdmFsdWUpIHsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleUZpcnN0QXhpcyk7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzID0gdGhpcy5zZXJpYWxpemVTZWNvbmRBeGlzKGtleVNlY29uZEF4aXMpOwogICAgICBpZiAoIXRoaXMuZGF0YS5oYXMoc2VyaWFsaXplZEtleUZpcnN0QXhpcykpIHsKICAgICAgICB0aGlzLmRhdGEuc2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpOwogICAgICB9CiAgICAgIHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcykuc2V0KHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzLCB2YWx1ZSk7CiAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcy5zZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcywga2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzU2Vjb25kQXhpcy5zZXQoc2VyaWFsaXplZEtleVNlY29uZEF4aXMsIGtleVNlY29uZEF4aXMpOwogICAgfQogICAgZGVsZXRlUm93KGtleSkgewogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5KTsKICAgICAgdGhpcy5kYXRhLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgIH0KICAgIGdldEZpcnN0QXhpc0tleXMoKSB7CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c0ZpcnN0QXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRTZWNvbmRBeGlzS2V5cygpIHsKICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5rZXlzU2Vjb25kQXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRBc0FycmF5KCkgewogICAgICByZXR1cm4gdGhpcy5nZXRGaXJzdEF4aXNLZXlzKCkubWFwKChmaXJzdEF4aXNLZXkpID0+IHsKICAgICAgICByZXR1cm4gdGhpcy5nZXRTZWNvbmRBeGlzS2V5cygpLm1hcCgoc2Vjb25kQXhpc0tleSkgPT4gewogICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KGZpcnN0QXhpc0tleSwgc2Vjb25kQXhpc0tleSk7CiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQogICAgZ2V0Q29udGVudHMoKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAga2V5c0ZpcnN0QXhpczogdGhpcy5rZXlzRmlyc3RBeGlzLAogICAgICAgIGtleXNTZWNvbmRBeGlzOiB0aGlzLmtleXNTZWNvbmRBeGlzLAogICAgICAgIGRhdGE6IHRoaXMuZGF0YQogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBCYXNlTXV0YXRpb25PdmVyVGltZURhdGFNYXAgZXh0ZW5kcyBNYXAyZEJhc2UgewogICAgY29uc3RydWN0b3IoaW5pdGlhbENvbnRlbnQpIHsKICAgICAgc3VwZXIoc2VyaWFsaXplU3Vic3RpdHV0aW9uT3JEZWxldGlvbiwgc2VyaWFsaXplVGVtcG9yYWwsIGluaXRpYWxDb250ZW50KTsKICAgIH0KICB9CiAgY29uc3Qgc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMi5zZWdtZW50ICE9PSBiLnNlZ21lbnQpIHsKICAgICAgcmV0dXJuIGNvbXBhcmVTZWdtZW50cyhhMi5zZWdtZW50LCBiLnNlZ21lbnQpOwogICAgfQogICAgaWYgKGEyLnBvc2l0aW9uICE9PSBiLnBvc2l0aW9uKSB7CiAgICAgIHJldHVybiBjb21wYXJlUG9zaXRpb25zKGEyLnBvc2l0aW9uLCBiLnBvc2l0aW9uKTsKICAgIH0KICAgIGNvbnN0IGFJc0RlbGV0aW9uID0gYTIgaW5zdGFuY2VvZiBEZWxldGlvbkNsYXNzOwogICAgY29uc3QgYklzRGVsZXRpb24gPSBiIGluc3RhbmNlb2YgRGVsZXRpb25DbGFzczsKICAgIGlmIChhSXNEZWxldGlvbiAhPT0gYklzRGVsZXRpb24pIHsKICAgICAgcmV0dXJuIGFJc0RlbGV0aW9uID8gMSA6IC0xOwogICAgfQogICAgaWYgKCFhSXNEZWxldGlvbiAmJiAhYklzRGVsZXRpb24pIHsKICAgICAgaWYgKGEyLnN1YnN0aXR1dGlvblZhbHVlICE9PSBiLnN1YnN0aXR1dGlvblZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMoYTIuc3Vic3RpdHV0aW9uVmFsdWUsIGIuc3Vic3RpdHV0aW9uVmFsdWUpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKICB9OwogIGNvbnN0IGNvbXBhcmVTZWdtZW50cyA9IChhMiwgYikgPT4gewogICAgaWYgKGEyID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgaWYgKGIgPT09IHZvaWQgMCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiBhMi5sb2NhbGVDb21wYXJlKGIpOwogIH07CiAgY29uc3QgY29tcGFyZVBvc2l0aW9ucyA9IChhMiwgYikgPT4gewogICAgcmV0dXJuIGEyIC0gYjsKICB9OwogIGNvbnN0IGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMiA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChiID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gYTIubG9jYWxlQ29tcGFyZShiKTsKICB9OwogIGNvbnN0IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TID0gMjAwOwogIGFzeW5jIGZ1bmN0aW9uIHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICBsYXBpc0ZpbHRlciwKICAgIHNlcXVlbmNlVHlwZSwKICAgIGxhcGlzLAogICAgZ3JhbnVsYXJpdHksCiAgICBsYXBpc0RhdGVGaWVsZCwKICAgIHNpZ25hbAogIH0pIHsKICAgIGNvbnN0IGFsbERhdGVzID0gYXdhaXQgZ2V0RGF0ZXNJbkRhdGFzZXQobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCk7CiAgICBpZiAoYWxsRGF0ZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogW10KICAgICAgfTsKICAgIH0KICAgIGNvbnN0IGZpbHRlciA9IHsKICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF06IGFsbERhdGVzWzBdLmZpcnN0RGF5LnRvU3RyaW5nKCksCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Ub2BdOiBhbGxEYXRlc1thbGxEYXRlcy5sZW5ndGggLSAxXS5sYXN0RGF5LnRvU3RyaW5nKCkKICAgIH07CiAgICByZXR1cm4gZmV0Y2hBbmRQcmVwYXJlU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGZpbHRlciwgc2VxdWVuY2VUeXBlKS5ldmFsdWF0ZShsYXBpcywgc2lnbmFsKTsKICB9CiAgYXN5bmMgZnVuY3Rpb24gcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoewogICAgbGFwaXNGaWx0ZXIsCiAgICBzZXF1ZW5jZVR5cGUsCiAgICBsYXBpcywKICAgIGxhcGlzRGF0ZUZpZWxkLAogICAgZ3JhbnVsYXJpdHksCiAgICBzaWduYWwKICB9KSB7CiAgICBjb25zdCBhbGxEYXRlcyA9IGF3YWl0IGdldERhdGVzSW5EYXRhc2V0KGxhcGlzRmlsdGVyLCBsYXBpcywgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkLCBzaWduYWwpOwogICAgaWYgKGFsbERhdGVzLmxlbmd0aCA+IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TKSB7CiAgICAgIHRocm93IG5ldyBVc2VyRmFjaW5nRXJyb3IoCiAgICAgICAgIlRvbyBtYW55IGRhdGVzIiwKICAgICAgICBgVGhlIGRhdGFzZXQgd291bGQgY29udGFpbiAke2FsbERhdGVzLmxlbmd0aH0gZGF0ZSBpbnRlcnZhbHMuIFBsZWFzZSByZWR1Y2UgdGhlIG51bWJlciB0byBiZWxvdyAke01BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TfSB0byBkaXNwbGF5IHRoZSBkYXRhLiBZb3UgY2FuIGFjaGlldmUgdGhpcyBieSBlaXRoZXIgbmFycm93aW5nIHRoZSBkYXRlIHJhbmdlIGluIHRoZSBwcm92aWRlZCBMQVBJUyBmaWx0ZXIgb3IgYnkgc2VsZWN0aW5nIGEgbGFyZ2VyIGdyYW51bGFyaXR5LmAKICAgICAgKTsKICAgIH0KICAgIGNvbnN0IHN1YlF1ZXJpZXMgPSBhbGxEYXRlcy5tYXAoYXN5bmMgKGRhdGUpID0+IHsKICAgICAgY29uc3QgZGF0ZUZyb20gPSBkYXRlLmZpcnN0RGF5LnRvU3RyaW5nKCk7CiAgICAgIGNvbnN0IGRhdGVUbyA9IGRhdGUubGFzdERheS50b1N0cmluZygpOwogICAgICBjb25zdCBmaWx0ZXIgPSB7CiAgICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfUZyb21gXTogZGF0ZUZyb20sCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfVRvYF06IGRhdGVUbwogICAgICB9OwogICAgICBjb25zdCBkYXRhMiA9IGF3YWl0IGZldGNoQW5kUHJlcGFyZVN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhmaWx0ZXIsIHNlcXVlbmNlVHlwZSkuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IHRvdGFsQ291bnRRdWVyeSA9IGF3YWl0IGdldFRvdGFsTnVtYmVyT2ZTZXF1ZW5jZXNJbkRhdGVSYW5nZShmaWx0ZXIpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICByZXR1cm4gewogICAgICAgIGRhdGUsCiAgICAgICAgbXV0YXRpb25zOiBkYXRhMi5jb250ZW50LAogICAgICAgIHRvdGFsQ291bnQ6IHRvdGFsQ291bnRRdWVyeS5jb250ZW50WzBdLmNvdW50CiAgICAgIH07CiAgICB9KTsKICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChzdWJRdWVyaWVzKTsKICAgIGNvbnN0IG92ZXJhbGxNdXRhdGlvbnNEYXRhID0gKGF3YWl0IHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICAgIGxhcGlzRmlsdGVyLAogICAgICBzZXF1ZW5jZVR5cGUsCiAgICAgIGxhcGlzLAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgZ3JhbnVsYXJpdHkKICAgIH0pKS5jb250ZW50OwogICAgcmV0dXJuIHsKICAgICAgbXV0YXRpb25PdmVyVGltZURhdGE6IGdyb3VwQnlNdXRhdGlvbihkYXRhLCBvdmVyYWxsTXV0YXRpb25zRGF0YSksCiAgICAgIG92ZXJhbGxNdXRhdGlvbkRhdGE6IG92ZXJhbGxNdXRhdGlvbnNEYXRhCiAgICB9OwogIH0KICBhc3luYyBmdW5jdGlvbiBnZXREYXRlc0luRGF0YXNldChsYXBpc0ZpbHRlciwgbGFwaXMsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCwgc2lnbmFsKSB7CiAgICBjb25zdCB7IGNvbnRlbnQ6IGF2YWlsYWJsZURhdGVzIH0gPSBhd2FpdCBxdWVyeUF2YWlsYWJsZURhdGVzKAogICAgICBsYXBpc0ZpbHRlciwKICAgICAgbGFwaXMsCiAgICAgIGdyYW51bGFyaXR5LAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgc2lnbmFsCiAgICApOwogICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvIH0gPSBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpOwogICAgY29uc3QgeyBtaW4sIG1heCB9ID0gZ2V0TWluTWF4VGVtcG9yYWwoYXZhaWxhYmxlRGF0ZXMpOwogICAgcmV0dXJuIGdlbmVyYXRlQWxsSW5SYW5nZShkYXRlRnJvbSA/PyBtaW4sIGRhdGVUbyA/PyBtYXgpOwogIH0KICBmdW5jdGlvbiBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpIHsKICAgIGNvbnN0IHZhbHVlRnJvbUZpbHRlciA9IGxhcGlzRmlsdGVyW2xhcGlzRGF0ZUZpZWxkXTsKICAgIGlmICh2YWx1ZUZyb21GaWx0ZXIpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBkYXRlRnJvbTogcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbCh2YWx1ZUZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSwKICAgICAgICBkYXRlVG86IHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwodmFsdWVGcm9tRmlsdGVyLCBncmFudWxhcml0eSkKICAgICAgfTsKICAgIH0KICAgIGNvbnN0IG1pbkZyb21GaWx0ZXIgPSBsYXBpc0ZpbHRlcltgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF07CiAgICBjb25zdCBtYXhGcm9tRmlsdGVyID0gbGFwaXNGaWx0ZXJbYCR7bGFwaXNEYXRlRmllbGR9VG9gXTsKICAgIHJldHVybiB7CiAgICAgIGRhdGVGcm9tOiBtaW5Gcm9tRmlsdGVyID8gcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbChtaW5Gcm9tRmlsdGVyLCBncmFudWxhcml0eSkgOiBudWxsLAogICAgICBkYXRlVG86IG1heEZyb21GaWx0ZXIgPyBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKG1heEZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSA6IG51bGwKICAgIH07CiAgfQogIGZ1bmN0aW9uIHF1ZXJ5QXZhaWxhYmxlRGF0ZXMobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCkgewogICAgcmV0dXJuIGZldGNoQW5kUHJlcGFyZURhdGVzKGxhcGlzRmlsdGVyLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVEYXRlcyhmaWx0ZXIsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCkgewogICAgY29uc3QgZmV0Y2hEYXRhID0gbmV3IEZldGNoQWdncmVnYXRlZE9wZXJhdG9yKGZpbHRlciwgW2xhcGlzRGF0ZUZpZWxkXSk7CiAgICBjb25zdCBkYXRhV2l0aEZpeGVkRGF0ZUtleSA9IG5ldyBSZW5hbWVGaWVsZE9wZXJhdG9yKGZldGNoRGF0YSwgbGFwaXNEYXRlRmllbGQsICJkYXRlIik7CiAgICBjb25zdCBtYXBEYXRhID0gbmV3IE1hcE9wZXJhdG9yKGRhdGFXaXRoRml4ZWREYXRlS2V5LCAoZGF0YSkgPT4gbWFwRGF0ZVRvR3JhbnVsYXJpdHlSYW5nZShkYXRhLCBncmFudWxhcml0eSkpOwogICAgY29uc3QgZ3JvdXBCeURhdGEgPSBuZXcgR3JvdXBCeUFuZFN1bU9wZXJhdG9yKG1hcERhdGEsICJkYXRlUmFuZ2UiLCAiY291bnQiKTsKICAgIGNvbnN0IHNvcnREYXRhID0gbmV3IFNvcnRPcGVyYXRvcihncm91cEJ5RGF0YSwgZGF0ZVJhbmdlQ29tcGFyZSk7CiAgICByZXR1cm4gbmV3IE1hcE9wZXJhdG9yKHNvcnREYXRhLCAoZGF0YSkgPT4gZGF0YS5kYXRlUmFuZ2UpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVTdWJzdGl0dXRpb25zT3JEZWxldGlvbnMoZmlsdGVyLCBzZXF1ZW5jZVR5cGUpIHsKICAgIHJldHVybiBuZXcgRmV0Y2hTdWJzdGl0dXRpb25zT3JEZWxldGlvbnNPcGVyYXRvcihmaWx0ZXIsIHNlcXVlbmNlVHlwZSwgMWUtMyk7CiAgfQogIGZ1bmN0aW9uIHNlcmlhbGl6ZVN1YnN0aXR1dGlvbk9yRGVsZXRpb24obXV0YXRpb24pIHsKICAgIHJldHVybiBtdXRhdGlvbi5jb2RlOwogIH0KICBmdW5jdGlvbiBzZXJpYWxpemVUZW1wb3JhbChkYXRlKSB7CiAgICByZXR1cm4gZGF0ZS5kYXRlU3RyaW5nOwogIH0KICBmdW5jdGlvbiBncm91cEJ5TXV0YXRpb24oZGF0YSwgb3ZlcmFsbE11dGF0aW9uRGF0YSkgewogICAgY29uc3QgZGF0YUFycmF5ID0gbmV3IEJhc2VNdXRhdGlvbk92ZXJUaW1lRGF0YU1hcCgpOwogICAgY29uc3QgYWxsRGF0ZXMgPSBkYXRhLm1hcCgobXV0YXRpb25EYXRhKSA9PiBtdXRhdGlvbkRhdGEuZGF0ZSk7CiAgICBjb25zdCBzb3J0ZWRPdmVyYWxsTXV0YXRpb25EYXRhID0gb3ZlcmFsbE11dGF0aW9uRGF0YS5zb3J0KChhMiwgYikgPT4gc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMoYTIubXV0YXRpb24sIGIubXV0YXRpb24pKS5tYXAoKGVudHJ5KSA9PiB7CiAgICAgIHJldHVybiB0b1N1YnN0aXR1dGlvbk9yRGVsZXRpb24oZW50cnkubXV0YXRpb24pOwogICAgfSk7CiAgICBjb25zdCBzb3J0ZWREYXRlcyA9IGFsbERhdGVzLnNvcnQoKGEyLCBiKSA9PiBjb21wYXJlVGVtcG9yYWwoYTIsIGIpKS5tYXAoKGRhdGUpID0+IHRvVGVtcG9yYWwoZGF0ZSkpOwogICAgc29ydGVkT3ZlcmFsbE11dGF0aW9uRGF0YS5mb3JFYWNoKChtdXRhdGlvbkRhdGEpID0+IHsKICAgICAgc29ydGVkRGF0ZXMuZm9yRWFjaCgoZGF0ZSkgPT4gewogICAgICAgIGRhdGFBcnJheS5zZXQobXV0YXRpb25EYXRhLCBkYXRlLCBudWxsKTsKICAgICAgfSk7CiAgICB9KTsKICAgIGRhdGEuZm9yRWFjaCgobXV0YXRpb25EYXRhKSA9PiB7CiAgICAgIG11dGF0aW9uRGF0YS5tdXRhdGlvbnMuZm9yRWFjaCgobXV0YXRpb25FbnRyeSkgPT4gewogICAgICAgIGNvbnN0IG11dGF0aW9uID0gdG9TdWJzdGl0dXRpb25PckRlbGV0aW9uKG11dGF0aW9uRW50cnkubXV0YXRpb24pOwogICAgICAgIGNvbnN0IGRhdGUgPSB0b1RlbXBvcmFsKG11dGF0aW9uRGF0YS5kYXRlKTsKICAgICAgICBpZiAoZGF0YUFycmF5LmdldChtdXRhdGlvbiwgZGF0ZSkgIT09IHZvaWQgMCkgewogICAgICAgICAgZGF0YUFycmF5LnNldChtdXRhdGlvbiwgZGF0ZSwgewogICAgICAgICAgICBjb3VudDogbXV0YXRpb25FbnRyeS5jb3VudCwKICAgICAgICAgICAgcHJvcG9ydGlvbjogbXV0YXRpb25FbnRyeS5wcm9wb3J0aW9uLAogICAgICAgICAgICB0b3RhbENvdW50OiBtdXRhdGlvbkRhdGEudG90YWxDb3VudAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwogICAgcmV0dXJuIGRhdGFBcnJheTsKICB9CiAgZnVuY3Rpb24gZ2V0VG90YWxOdW1iZXJPZlNlcXVlbmNlc0luRGF0ZVJhbmdlKGZpbHRlcikgewogICAgcmV0dXJuIG5ldyBGZXRjaEFnZ3JlZ2F0ZWRPcGVyYXRvcihmaWx0ZXIpOwogIH0KICBhc3luYyBmdW5jdGlvbiB3b3JrZXJGdW5jdGlvbihxdWVyeUZ1bmN0aW9uKSB7CiAgICB0cnkgewogICAgICBwb3N0TWVzc2FnZSh7IHN0YXR1czogImxvYWRpbmciIH0pOwogICAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IGF3YWl0IHF1ZXJ5RnVuY3Rpb24oKTsKICAgICAgcG9zdE1lc3NhZ2UoewogICAgICAgIHN0YXR1czogInN1Y2Nlc3MiLAogICAgICAgIGRhdGE6IHdvcmtlclJlc3BvbnNlCiAgICAgIH0pOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgcG9zdE1lc3NhZ2UoCiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBVc2VyRmFjaW5nRXJyb3IgPyB7CiAgICAgICAgICBzdGF0dXM6ICJlcnJvciIsCiAgICAgICAgICB1c2VyRmFjaW5nOiB0cnVlLAogICAgICAgICAgaGVhZGxpbmU6IGVycm9yLmhlYWRsaW5lLAogICAgICAgICAgZXJyb3IKICAgICAgICB9IDogewogICAgICAgICAgc3RhdHVzOiAiZXJyb3IiLAogICAgICAgICAgdXNlckZhY2luZzogZmFsc2UsCiAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKGAke2Vycm9yfWApCiAgICAgICAgfQogICAgICApOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBnZXRNdXRhdGlvbk92ZXJUaW1lV29ya2VyRnVuY3Rpb24oZXZlbnQpIHsKICAgIGNvbnN0IG11dGF0aW9uT3ZlclRpbWVEYXRhID0gYXdhaXQgcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoZXZlbnQuZGF0YSk7CiAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IHsKICAgICAgb3ZlcmFsbE11dGF0aW9uRGF0YTogbXV0YXRpb25PdmVyVGltZURhdGEub3ZlcmFsbE11dGF0aW9uRGF0YSwKICAgICAgbXV0YXRpb25PdmVyVGltZVNlcmlhbGl6ZWQ6IG11dGF0aW9uT3ZlclRpbWVEYXRhLm11dGF0aW9uT3ZlclRpbWVEYXRhLmdldENvbnRlbnRzKCkKICAgIH07CiAgICByZXR1cm4gd29ya2VyUmVzcG9uc2U7CiAgfQogIHNlbGYub25tZXNzYWdlID0gYXN5bmMgZnVuY3Rpb24oZXZlbnQpIHsKICAgIGF3YWl0IHdvcmtlckZ1bmN0aW9uKCgpID0+IGdldE11dGF0aW9uT3ZlclRpbWVXb3JrZXJGdW5jdGlvbihldmVudCkpOwogIH07Cn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPW11dGF0aW9uT3ZlclRpbWVXb3JrZXItRGk2eVAxZTYuanMubWFwCg==";
8657
- const decodeBase64 = (base64) => Uint8Array.from(atob(base64), (c2) => c2.charCodeAt(0));
8658
- const blob = typeof self !== "undefined" && self.Blob && new Blob([decodeBase64(encodedJs)], { type: "text/javascript;charset=utf-8" });
8780
+ 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';
8781
+ const blob = typeof self !== "undefined" && self.Blob && new Blob([jsContent], { type: "text/javascript;charset=utf-8" });
8659
8782
  function WorkerWrapper(options2) {
8660
8783
  let objURL;
8661
8784
  try {
@@ -8670,7 +8793,7 @@ function WorkerWrapper(options2) {
8670
8793
  return worker;
8671
8794
  } catch (e2) {
8672
8795
  return new Worker(
8673
- "data:text/javascript;base64," + encodedJs,
8796
+ "data:text/javascript;charset=utf-8," + encodeURIComponent(jsContent),
8674
8797
  {
8675
8798
  name: options2 == null ? void 0 : options2.name
8676
8799
  }
@@ -9076,10 +9199,20 @@ function useWebWorker(messageToWorker, WorkerConstructor) {
9076
9199
  }, [messageToWorker, worker]);
9077
9200
  return { data, error, isLoading };
9078
9201
  }
9202
+ const viewSchema = z$1.literal(views.grid);
9203
+ const mutationOverTimeSchema = z$1.object({
9204
+ lapisFilter: lapisFilterSchema,
9205
+ sequenceType: sequenceTypeSchema,
9206
+ views: z$1.array(viewSchema),
9207
+ granularity: temporalGranularitySchema,
9208
+ lapisDateField: z$1.string().min(1),
9209
+ width: z$1.string(),
9210
+ height: z$1.string()
9211
+ });
9079
9212
  const MutationsOverTime = (componentProps) => {
9080
9213
  const { width, height } = componentProps;
9081
9214
  const size = { height, width };
9082
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsOverTimeInner, { ...componentProps }) }) });
9215
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: mutationOverTimeSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(MutationsOverTimeInner, { ...componentProps }) }) });
9083
9216
  };
9084
9217
  const MutationsOverTimeInner = (componentProps) => {
9085
9218
  const lapis = x(LapisUrlContext);
@@ -9155,7 +9288,7 @@ const MutationsOverTimeTabs = ({
9155
9288
  };
9156
9289
  const tabs = originalComponentProps.views.map((view) => getTab(view));
9157
9290
  const toolbar = (activeTab) => /* @__PURE__ */ u$1(
9158
- Toolbar,
9291
+ Toolbar$1,
9159
9292
  {
9160
9293
  activeTab,
9161
9294
  displayedSegments,
@@ -9172,7 +9305,7 @@ const MutationsOverTimeTabs = ({
9172
9305
  );
9173
9306
  return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar });
9174
9307
  };
9175
- const Toolbar = ({
9308
+ const Toolbar$1 = ({
9176
9309
  activeTab,
9177
9310
  displayedSegments,
9178
9311
  setDisplayedSegments,
@@ -9247,14 +9380,14 @@ function getDownloadData(filteredData) {
9247
9380
  );
9248
9381
  });
9249
9382
  }
9250
- var __defProp$6 = Object.defineProperty;
9251
- var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
9252
- var __decorateClass$6 = (decorators, target, key, kind) => {
9253
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
9383
+ var __defProp$7 = Object.defineProperty;
9384
+ var __getOwnPropDesc$7 = Object.getOwnPropertyDescriptor;
9385
+ var __decorateClass$7 = (decorators, target, key, kind) => {
9386
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$7(target, key) : target;
9254
9387
  for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
9255
9388
  if (decorator = decorators[i2])
9256
9389
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9257
- if (kind && result) __defProp$6(target, key, result);
9390
+ if (kind && result) __defProp$7(target, key, result);
9258
9391
  return result;
9259
9392
  };
9260
9393
  let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles {
@@ -9283,30 +9416,1047 @@ let MutationsOverTimeComponent = class extends PreactLitAdapterWithGridJsStyles
9283
9416
  );
9284
9417
  }
9285
9418
  };
9286
- __decorateClass$6([
9419
+ __decorateClass$7([
9287
9420
  n2({ type: Object })
9288
9421
  ], MutationsOverTimeComponent.prototype, "lapisFilter", 2);
9289
- __decorateClass$6([
9422
+ __decorateClass$7([
9290
9423
  n2({ type: String })
9291
9424
  ], MutationsOverTimeComponent.prototype, "sequenceType", 2);
9292
- __decorateClass$6([
9425
+ __decorateClass$7([
9293
9426
  n2({ type: Array })
9294
9427
  ], MutationsOverTimeComponent.prototype, "views", 2);
9295
- __decorateClass$6([
9428
+ __decorateClass$7([
9296
9429
  n2({ type: String })
9297
9430
  ], MutationsOverTimeComponent.prototype, "width", 2);
9298
- __decorateClass$6([
9431
+ __decorateClass$7([
9299
9432
  n2({ type: String })
9300
9433
  ], MutationsOverTimeComponent.prototype, "height", 2);
9301
- __decorateClass$6([
9434
+ __decorateClass$7([
9302
9435
  n2({ type: String })
9303
9436
  ], MutationsOverTimeComponent.prototype, "granularity", 2);
9304
- __decorateClass$6([
9437
+ __decorateClass$7([
9305
9438
  n2({ type: String })
9306
9439
  ], MutationsOverTimeComponent.prototype, "lapisDateField", 2);
9307
- MutationsOverTimeComponent = __decorateClass$6([
9440
+ MutationsOverTimeComponent = __decorateClass$7([
9308
9441
  t$2("gs-mutations-over-time")
9309
9442
  ], MutationsOverTimeComponent);
9443
+ const leafletStyle = `/* required styles */\r
9444
+ \r
9445
+ .leaflet-pane,\r
9446
+ .leaflet-tile,\r
9447
+ .leaflet-marker-icon,\r
9448
+ .leaflet-marker-shadow,\r
9449
+ .leaflet-tile-container,\r
9450
+ .leaflet-pane > svg,\r
9451
+ .leaflet-pane > canvas,\r
9452
+ .leaflet-zoom-box,\r
9453
+ .leaflet-image-layer,\r
9454
+ .leaflet-layer {\r
9455
+ position: absolute;\r
9456
+ left: 0;\r
9457
+ top: 0;\r
9458
+ }\r
9459
+ .leaflet-container {\r
9460
+ overflow: hidden;\r
9461
+ }\r
9462
+ .leaflet-tile,\r
9463
+ .leaflet-marker-icon,\r
9464
+ .leaflet-marker-shadow {\r
9465
+ -webkit-user-select: none;\r
9466
+ -moz-user-select: none;\r
9467
+ user-select: none;\r
9468
+ -webkit-user-drag: none;\r
9469
+ }\r
9470
+ /* Prevents IE11 from highlighting tiles in blue */\r
9471
+ .leaflet-tile::-moz-selection {\r
9472
+ background: transparent;\r
9473
+ }\r
9474
+ .leaflet-tile::selection {\r
9475
+ background: transparent;\r
9476
+ }\r
9477
+ /* Safari renders non-retina tile on retina better with this, but Chrome is worse */\r
9478
+ .leaflet-safari .leaflet-tile {\r
9479
+ image-rendering: -webkit-optimize-contrast;\r
9480
+ }\r
9481
+ /* hack that prevents hw layers "stretching" when loading new tiles */\r
9482
+ .leaflet-safari .leaflet-tile-container {\r
9483
+ width: 1600px;\r
9484
+ height: 1600px;\r
9485
+ -webkit-transform-origin: 0 0;\r
9486
+ }\r
9487
+ .leaflet-marker-icon,\r
9488
+ .leaflet-marker-shadow {\r
9489
+ display: block;\r
9490
+ }\r
9491
+ /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */\r
9492
+ /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */\r
9493
+ .leaflet-container .leaflet-overlay-pane svg {\r
9494
+ max-width: none !important;\r
9495
+ max-height: none !important;\r
9496
+ }\r
9497
+ .leaflet-container .leaflet-marker-pane img,\r
9498
+ .leaflet-container .leaflet-shadow-pane img,\r
9499
+ .leaflet-container .leaflet-tile-pane img,\r
9500
+ .leaflet-container img.leaflet-image-layer,\r
9501
+ .leaflet-container .leaflet-tile {\r
9502
+ max-width: none !important;\r
9503
+ max-height: none !important;\r
9504
+ width: auto;\r
9505
+ padding: 0;\r
9506
+ }\r
9507
+ \r
9508
+ .leaflet-container img.leaflet-tile {\r
9509
+ /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */\r
9510
+ mix-blend-mode: plus-lighter;\r
9511
+ }\r
9512
+ \r
9513
+ .leaflet-container.leaflet-touch-zoom {\r
9514
+ touch-action: pan-x pan-y;\r
9515
+ }\r
9516
+ .leaflet-container.leaflet-touch-drag {\r
9517
+ /* Fallback for FF which doesn't support pinch-zoom */\r
9518
+ touch-action: none;\r
9519
+ touch-action: pinch-zoom;\r
9520
+ }\r
9521
+ .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {\r
9522
+ touch-action: none;\r
9523
+ }\r
9524
+ .leaflet-container {\r
9525
+ -webkit-tap-highlight-color: transparent;\r
9526
+ }\r
9527
+ .leaflet-container a {\r
9528
+ -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);\r
9529
+ }\r
9530
+ .leaflet-tile {\r
9531
+ filter: inherit;\r
9532
+ visibility: hidden;\r
9533
+ }\r
9534
+ .leaflet-tile-loaded {\r
9535
+ visibility: inherit;\r
9536
+ }\r
9537
+ .leaflet-zoom-box {\r
9538
+ width: 0;\r
9539
+ height: 0;\r
9540
+ box-sizing: border-box;\r
9541
+ z-index: 800;\r
9542
+ }\r
9543
+ /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */\r
9544
+ .leaflet-overlay-pane svg {\r
9545
+ -moz-user-select: none;\r
9546
+ }\r
9547
+ \r
9548
+ .leaflet-pane { z-index: 400; }\r
9549
+ \r
9550
+ .leaflet-tile-pane { z-index: 200; }\r
9551
+ .leaflet-overlay-pane { z-index: 400; }\r
9552
+ .leaflet-shadow-pane { z-index: 500; }\r
9553
+ .leaflet-marker-pane { z-index: 600; }\r
9554
+ .leaflet-tooltip-pane { z-index: 650; }\r
9555
+ .leaflet-popup-pane { z-index: 700; }\r
9556
+ \r
9557
+ .leaflet-map-pane canvas { z-index: 100; }\r
9558
+ .leaflet-map-pane svg { z-index: 200; }\r
9559
+ \r
9560
+ .leaflet-vml-shape {\r
9561
+ width: 1px;\r
9562
+ height: 1px;\r
9563
+ }\r
9564
+ .lvml {\r
9565
+ behavior: url(#default#VML);\r
9566
+ display: inline-block;\r
9567
+ position: absolute;\r
9568
+ }\r
9569
+ \r
9570
+ \r
9571
+ /* control positioning */\r
9572
+ \r
9573
+ .leaflet-control {\r
9574
+ position: relative;\r
9575
+ z-index: 800;\r
9576
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */\r
9577
+ pointer-events: auto;\r
9578
+ }\r
9579
+ .leaflet-top,\r
9580
+ .leaflet-bottom {\r
9581
+ position: absolute;\r
9582
+ z-index: 1000;\r
9583
+ pointer-events: none;\r
9584
+ }\r
9585
+ .leaflet-top {\r
9586
+ top: 0;\r
9587
+ }\r
9588
+ .leaflet-right {\r
9589
+ right: 0;\r
9590
+ }\r
9591
+ .leaflet-bottom {\r
9592
+ bottom: 0;\r
9593
+ }\r
9594
+ .leaflet-left {\r
9595
+ left: 0;\r
9596
+ }\r
9597
+ .leaflet-control {\r
9598
+ float: left;\r
9599
+ clear: both;\r
9600
+ }\r
9601
+ .leaflet-right .leaflet-control {\r
9602
+ float: right;\r
9603
+ }\r
9604
+ .leaflet-top .leaflet-control {\r
9605
+ margin-top: 10px;\r
9606
+ }\r
9607
+ .leaflet-bottom .leaflet-control {\r
9608
+ margin-bottom: 10px;\r
9609
+ }\r
9610
+ .leaflet-left .leaflet-control {\r
9611
+ margin-left: 10px;\r
9612
+ }\r
9613
+ .leaflet-right .leaflet-control {\r
9614
+ margin-right: 10px;\r
9615
+ }\r
9616
+ \r
9617
+ \r
9618
+ /* zoom and fade animations */\r
9619
+ \r
9620
+ .leaflet-fade-anim .leaflet-popup {\r
9621
+ opacity: 0;\r
9622
+ transition: opacity 0.2s linear;\r
9623
+ }\r
9624
+ .leaflet-fade-anim .leaflet-map-pane .leaflet-popup {\r
9625
+ opacity: 1;\r
9626
+ }\r
9627
+ .leaflet-zoom-animated {\r
9628
+ transform-origin: 0 0;\r
9629
+ }\r
9630
+ svg.leaflet-zoom-animated {\r
9631
+ will-change: transform;\r
9632
+ }\r
9633
+ \r
9634
+ .leaflet-zoom-anim .leaflet-zoom-animated {\r
9635
+ transition: transform 0.25s cubic-bezier(0,0,0.25,1);\r
9636
+ }\r
9637
+ .leaflet-zoom-anim .leaflet-tile,\r
9638
+ .leaflet-pan-anim .leaflet-tile {\r
9639
+ transition: none;\r
9640
+ }\r
9641
+ \r
9642
+ .leaflet-zoom-anim .leaflet-zoom-hide {\r
9643
+ visibility: hidden;\r
9644
+ }\r
9645
+ \r
9646
+ \r
9647
+ /* cursors */\r
9648
+ \r
9649
+ .leaflet-interactive {\r
9650
+ cursor: pointer;\r
9651
+ }\r
9652
+ .leaflet-grab {\r
9653
+ cursor: grab;\r
9654
+ }\r
9655
+ .leaflet-crosshair,\r
9656
+ .leaflet-crosshair .leaflet-interactive {\r
9657
+ cursor: crosshair;\r
9658
+ }\r
9659
+ .leaflet-popup-pane,\r
9660
+ .leaflet-control {\r
9661
+ cursor: auto;\r
9662
+ }\r
9663
+ .leaflet-dragging .leaflet-grab,\r
9664
+ .leaflet-dragging .leaflet-grab .leaflet-interactive,\r
9665
+ .leaflet-dragging .leaflet-marker-draggable {\r
9666
+ cursor: move;\r
9667
+ cursor: grabbing;\r
9668
+ }\r
9669
+ \r
9670
+ /* marker & overlays interactivity */\r
9671
+ .leaflet-marker-icon,\r
9672
+ .leaflet-marker-shadow,\r
9673
+ .leaflet-image-layer,\r
9674
+ .leaflet-pane > svg path,\r
9675
+ .leaflet-tile-container {\r
9676
+ pointer-events: none;\r
9677
+ }\r
9678
+ \r
9679
+ .leaflet-marker-icon.leaflet-interactive,\r
9680
+ .leaflet-image-layer.leaflet-interactive,\r
9681
+ .leaflet-pane > svg path.leaflet-interactive,\r
9682
+ svg.leaflet-image-layer.leaflet-interactive path {\r
9683
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */\r
9684
+ pointer-events: auto;\r
9685
+ }\r
9686
+ \r
9687
+ /* visual tweaks */\r
9688
+ \r
9689
+ .leaflet-container {\r
9690
+ background: #ddd;\r
9691
+ outline-offset: 1px;\r
9692
+ }\r
9693
+ .leaflet-container a {\r
9694
+ color: #0078A8;\r
9695
+ }\r
9696
+ .leaflet-zoom-box {\r
9697
+ border: 2px dotted #38f;\r
9698
+ background: rgba(255,255,255,0.5);\r
9699
+ }\r
9700
+ \r
9701
+ \r
9702
+ /* general typography */\r
9703
+ .leaflet-container {\r
9704
+ font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;\r
9705
+ font-size: 12px;\r
9706
+ font-size: 0.75rem;\r
9707
+ line-height: 1.5;\r
9708
+ }\r
9709
+ \r
9710
+ \r
9711
+ /* general toolbar styles */\r
9712
+ \r
9713
+ .leaflet-bar {\r
9714
+ box-shadow: 0 1px 5px rgba(0,0,0,0.65);\r
9715
+ border-radius: 4px;\r
9716
+ }\r
9717
+ .leaflet-bar a {\r
9718
+ background-color: #fff;\r
9719
+ border-bottom: 1px solid #ccc;\r
9720
+ width: 26px;\r
9721
+ height: 26px;\r
9722
+ line-height: 26px;\r
9723
+ display: block;\r
9724
+ text-align: center;\r
9725
+ text-decoration: none;\r
9726
+ color: black;\r
9727
+ }\r
9728
+ .leaflet-bar a,\r
9729
+ .leaflet-control-layers-toggle {\r
9730
+ background-position: 50% 50%;\r
9731
+ background-repeat: no-repeat;\r
9732
+ display: block;\r
9733
+ }\r
9734
+ .leaflet-bar a:hover,\r
9735
+ .leaflet-bar a:focus {\r
9736
+ background-color: #f4f4f4;\r
9737
+ }\r
9738
+ .leaflet-bar a:first-child {\r
9739
+ border-top-left-radius: 4px;\r
9740
+ border-top-right-radius: 4px;\r
9741
+ }\r
9742
+ .leaflet-bar a:last-child {\r
9743
+ border-bottom-left-radius: 4px;\r
9744
+ border-bottom-right-radius: 4px;\r
9745
+ border-bottom: none;\r
9746
+ }\r
9747
+ .leaflet-bar a.leaflet-disabled {\r
9748
+ cursor: default;\r
9749
+ background-color: #f4f4f4;\r
9750
+ color: #bbb;\r
9751
+ }\r
9752
+ \r
9753
+ .leaflet-touch .leaflet-bar a {\r
9754
+ width: 30px;\r
9755
+ height: 30px;\r
9756
+ line-height: 30px;\r
9757
+ }\r
9758
+ .leaflet-touch .leaflet-bar a:first-child {\r
9759
+ border-top-left-radius: 2px;\r
9760
+ border-top-right-radius: 2px;\r
9761
+ }\r
9762
+ .leaflet-touch .leaflet-bar a:last-child {\r
9763
+ border-bottom-left-radius: 2px;\r
9764
+ border-bottom-right-radius: 2px;\r
9765
+ }\r
9766
+ \r
9767
+ /* zoom control */\r
9768
+ \r
9769
+ .leaflet-control-zoom-in,\r
9770
+ .leaflet-control-zoom-out {\r
9771
+ font: bold 18px 'Lucida Console', Monaco, monospace;\r
9772
+ text-indent: 1px;\r
9773
+ }\r
9774
+ \r
9775
+ .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {\r
9776
+ font-size: 22px;\r
9777
+ }\r
9778
+ \r
9779
+ \r
9780
+ /* layers control */\r
9781
+ \r
9782
+ .leaflet-control-layers {\r
9783
+ box-shadow: 0 1px 5px rgba(0,0,0,0.4);\r
9784
+ background: #fff;\r
9785
+ border-radius: 5px;\r
9786
+ }\r
9787
+ .leaflet-control-layers-toggle {\r
9788
+ 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
9789
+ width: 36px;\r
9790
+ height: 36px;\r
9791
+ }\r
9792
+ .leaflet-retina .leaflet-control-layers-toggle {\r
9793
+ 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
9794
+ background-size: 26px 26px;\r
9795
+ }\r
9796
+ .leaflet-touch .leaflet-control-layers-toggle {\r
9797
+ width: 44px;\r
9798
+ height: 44px;\r
9799
+ }\r
9800
+ .leaflet-control-layers .leaflet-control-layers-list,\r
9801
+ .leaflet-control-layers-expanded .leaflet-control-layers-toggle {\r
9802
+ display: none;\r
9803
+ }\r
9804
+ .leaflet-control-layers-expanded .leaflet-control-layers-list {\r
9805
+ display: block;\r
9806
+ position: relative;\r
9807
+ }\r
9808
+ .leaflet-control-layers-expanded {\r
9809
+ padding: 6px 10px 6px 6px;\r
9810
+ color: #333;\r
9811
+ background: #fff;\r
9812
+ }\r
9813
+ .leaflet-control-layers-scrollbar {\r
9814
+ overflow-y: scroll;\r
9815
+ overflow-x: hidden;\r
9816
+ padding-right: 5px;\r
9817
+ }\r
9818
+ .leaflet-control-layers-selector {\r
9819
+ margin-top: 2px;\r
9820
+ position: relative;\r
9821
+ top: 1px;\r
9822
+ }\r
9823
+ .leaflet-control-layers label {\r
9824
+ display: block;\r
9825
+ font-size: 13px;\r
9826
+ font-size: 1.08333em;\r
9827
+ }\r
9828
+ .leaflet-control-layers-separator {\r
9829
+ height: 0;\r
9830
+ border-top: 1px solid #ddd;\r
9831
+ margin: 5px -10px 5px -6px;\r
9832
+ }\r
9833
+ \r
9834
+ /* Default icon URLs */\r
9835
+ .leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */\r
9836
+ 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
9837
+ }\r
9838
+ \r
9839
+ \r
9840
+ /* attribution and scale controls */\r
9841
+ \r
9842
+ .leaflet-container .leaflet-control-attribution {\r
9843
+ background: #fff;\r
9844
+ background: rgba(255, 255, 255, 0.8);\r
9845
+ margin: 0;\r
9846
+ }\r
9847
+ .leaflet-control-attribution,\r
9848
+ .leaflet-control-scale-line {\r
9849
+ padding: 0 5px;\r
9850
+ color: #333;\r
9851
+ line-height: 1.4;\r
9852
+ }\r
9853
+ .leaflet-control-attribution a {\r
9854
+ text-decoration: none;\r
9855
+ }\r
9856
+ .leaflet-control-attribution a:hover,\r
9857
+ .leaflet-control-attribution a:focus {\r
9858
+ text-decoration: underline;\r
9859
+ }\r
9860
+ .leaflet-attribution-flag {\r
9861
+ display: inline !important;\r
9862
+ vertical-align: baseline !important;\r
9863
+ width: 1em;\r
9864
+ height: 0.6669em;\r
9865
+ }\r
9866
+ .leaflet-left .leaflet-control-scale {\r
9867
+ margin-left: 5px;\r
9868
+ }\r
9869
+ .leaflet-bottom .leaflet-control-scale {\r
9870
+ margin-bottom: 5px;\r
9871
+ }\r
9872
+ .leaflet-control-scale-line {\r
9873
+ border: 2px solid #777;\r
9874
+ border-top: none;\r
9875
+ line-height: 1.1;\r
9876
+ padding: 2px 5px 1px;\r
9877
+ white-space: nowrap;\r
9878
+ box-sizing: border-box;\r
9879
+ background: rgba(255, 255, 255, 0.8);\r
9880
+ text-shadow: 1px 1px #fff;\r
9881
+ }\r
9882
+ .leaflet-control-scale-line:not(:first-child) {\r
9883
+ border-top: 2px solid #777;\r
9884
+ border-bottom: none;\r
9885
+ margin-top: -2px;\r
9886
+ }\r
9887
+ .leaflet-control-scale-line:not(:first-child):not(:last-child) {\r
9888
+ border-bottom: 2px solid #777;\r
9889
+ }\r
9890
+ \r
9891
+ .leaflet-touch .leaflet-control-attribution,\r
9892
+ .leaflet-touch .leaflet-control-layers,\r
9893
+ .leaflet-touch .leaflet-bar {\r
9894
+ box-shadow: none;\r
9895
+ }\r
9896
+ .leaflet-touch .leaflet-control-layers,\r
9897
+ .leaflet-touch .leaflet-bar {\r
9898
+ border: 2px solid rgba(0,0,0,0.2);\r
9899
+ background-clip: padding-box;\r
9900
+ }\r
9901
+ \r
9902
+ \r
9903
+ /* popup */\r
9904
+ \r
9905
+ .leaflet-popup {\r
9906
+ position: absolute;\r
9907
+ text-align: center;\r
9908
+ margin-bottom: 20px;\r
9909
+ }\r
9910
+ .leaflet-popup-content-wrapper {\r
9911
+ padding: 1px;\r
9912
+ text-align: left;\r
9913
+ border-radius: 12px;\r
9914
+ }\r
9915
+ .leaflet-popup-content {\r
9916
+ margin: 13px 24px 13px 20px;\r
9917
+ line-height: 1.3;\r
9918
+ font-size: 13px;\r
9919
+ font-size: 1.08333em;\r
9920
+ min-height: 1px;\r
9921
+ }\r
9922
+ .leaflet-popup-content p {\r
9923
+ margin: 17px 0;\r
9924
+ margin: 1.3em 0;\r
9925
+ }\r
9926
+ .leaflet-popup-tip-container {\r
9927
+ width: 40px;\r
9928
+ height: 20px;\r
9929
+ position: absolute;\r
9930
+ left: 50%;\r
9931
+ margin-top: -1px;\r
9932
+ margin-left: -20px;\r
9933
+ overflow: hidden;\r
9934
+ pointer-events: none;\r
9935
+ }\r
9936
+ .leaflet-popup-tip {\r
9937
+ width: 17px;\r
9938
+ height: 17px;\r
9939
+ padding: 1px;\r
9940
+ \r
9941
+ margin: -10px auto 0;\r
9942
+ pointer-events: auto;\r
9943
+ transform: rotate(45deg);\r
9944
+ }\r
9945
+ .leaflet-popup-content-wrapper,\r
9946
+ .leaflet-popup-tip {\r
9947
+ background: white;\r
9948
+ color: #333;\r
9949
+ box-shadow: 0 3px 14px rgba(0,0,0,0.4);\r
9950
+ }\r
9951
+ .leaflet-container a.leaflet-popup-close-button {\r
9952
+ position: absolute;\r
9953
+ top: 0;\r
9954
+ right: 0;\r
9955
+ border: none;\r
9956
+ text-align: center;\r
9957
+ width: 24px;\r
9958
+ height: 24px;\r
9959
+ font: 16px/24px Tahoma, Verdana, sans-serif;\r
9960
+ color: #757575;\r
9961
+ text-decoration: none;\r
9962
+ background: transparent;\r
9963
+ }\r
9964
+ .leaflet-container a.leaflet-popup-close-button:hover,\r
9965
+ .leaflet-container a.leaflet-popup-close-button:focus {\r
9966
+ color: #585858;\r
9967
+ }\r
9968
+ .leaflet-popup-scrolled {\r
9969
+ overflow: auto;\r
9970
+ }\r
9971
+ \r
9972
+ .leaflet-oldie .leaflet-popup-content-wrapper {\r
9973
+ -ms-zoom: 1;\r
9974
+ }\r
9975
+ .leaflet-oldie .leaflet-popup-tip {\r
9976
+ width: 24px;\r
9977
+ margin: 0 auto;\r
9978
+ \r
9979
+ -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";\r
9980
+ filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);\r
9981
+ }\r
9982
+ \r
9983
+ .leaflet-oldie .leaflet-control-zoom,\r
9984
+ .leaflet-oldie .leaflet-control-layers,\r
9985
+ .leaflet-oldie .leaflet-popup-content-wrapper,\r
9986
+ .leaflet-oldie .leaflet-popup-tip {\r
9987
+ border: 1px solid #999;\r
9988
+ }\r
9989
+ \r
9990
+ \r
9991
+ /* div icon */\r
9992
+ \r
9993
+ .leaflet-div-icon {\r
9994
+ background: #fff;\r
9995
+ border: 1px solid #666;\r
9996
+ }\r
9997
+ \r
9998
+ \r
9999
+ /* Tooltip */\r
10000
+ /* Base styles for the element that has a tooltip */\r
10001
+ .leaflet-tooltip {\r
10002
+ position: absolute;\r
10003
+ padding: 6px;\r
10004
+ background-color: #fff;\r
10005
+ border: 1px solid #fff;\r
10006
+ border-radius: 3px;\r
10007
+ color: #222;\r
10008
+ white-space: nowrap;\r
10009
+ -webkit-user-select: none;\r
10010
+ -moz-user-select: none;\r
10011
+ user-select: none;\r
10012
+ pointer-events: none;\r
10013
+ box-shadow: 0 1px 3px rgba(0,0,0,0.4);\r
10014
+ }\r
10015
+ .leaflet-tooltip.leaflet-interactive {\r
10016
+ cursor: pointer;\r
10017
+ pointer-events: auto;\r
10018
+ }\r
10019
+ .leaflet-tooltip-top:before,\r
10020
+ .leaflet-tooltip-bottom:before,\r
10021
+ .leaflet-tooltip-left:before,\r
10022
+ .leaflet-tooltip-right:before {\r
10023
+ position: absolute;\r
10024
+ pointer-events: none;\r
10025
+ border: 6px solid transparent;\r
10026
+ background: transparent;\r
10027
+ content: "";\r
10028
+ }\r
10029
+ \r
10030
+ /* Directions */\r
10031
+ \r
10032
+ .leaflet-tooltip-bottom {\r
10033
+ margin-top: 6px;\r
10034
+ }\r
10035
+ .leaflet-tooltip-top {\r
10036
+ margin-top: -6px;\r
10037
+ }\r
10038
+ .leaflet-tooltip-bottom:before,\r
10039
+ .leaflet-tooltip-top:before {\r
10040
+ left: 50%;\r
10041
+ margin-left: -6px;\r
10042
+ }\r
10043
+ .leaflet-tooltip-top:before {\r
10044
+ bottom: 0;\r
10045
+ margin-bottom: -12px;\r
10046
+ border-top-color: #fff;\r
10047
+ }\r
10048
+ .leaflet-tooltip-bottom:before {\r
10049
+ top: 0;\r
10050
+ margin-top: -12px;\r
10051
+ margin-left: -6px;\r
10052
+ border-bottom-color: #fff;\r
10053
+ }\r
10054
+ .leaflet-tooltip-left {\r
10055
+ margin-left: -6px;\r
10056
+ }\r
10057
+ .leaflet-tooltip-right {\r
10058
+ margin-left: 6px;\r
10059
+ }\r
10060
+ .leaflet-tooltip-left:before,\r
10061
+ .leaflet-tooltip-right:before {\r
10062
+ top: 50%;\r
10063
+ margin-top: -6px;\r
10064
+ }\r
10065
+ .leaflet-tooltip-left:before {\r
10066
+ right: 0;\r
10067
+ margin-right: -12px;\r
10068
+ border-left-color: #fff;\r
10069
+ }\r
10070
+ .leaflet-tooltip-right:before {\r
10071
+ left: 0;\r
10072
+ margin-left: -12px;\r
10073
+ border-right-color: #fff;\r
10074
+ }\r
10075
+ \r
10076
+ /* Printing */\r
10077
+ \r
10078
+ @media print {\r
10079
+ /* Prevent printers from removing background-images of controls. */\r
10080
+ .leaflet-control {\r
10081
+ -webkit-print-color-adjust: exact;\r
10082
+ print-color-adjust: exact;\r
10083
+ }\r
10084
+ }\r
10085
+ `;
10086
+ const leafletStyleModifications = ".leaflet-container {\n background: transparent;\n}\n";
10087
+ const mapSourceSchema = z$1.object({
10088
+ type: z$1.literal("topojson"),
10089
+ url: z$1.string().min(1),
10090
+ topologyObjectsKey: z$1.string().min(1)
10091
+ });
10092
+ function useGeoJsonMap(mapSource) {
10093
+ const {
10094
+ data: geojsonData,
10095
+ error,
10096
+ isLoading
10097
+ } = useQuery(async () => {
10098
+ switch (mapSource.type) {
10099
+ case "topojson":
10100
+ return await loadTopojsonMap(mapSource);
10101
+ }
10102
+ }, [mapSource]);
10103
+ if (isLoading) {
10104
+ return { isLoading };
10105
+ }
10106
+ if (error) {
10107
+ throw error;
10108
+ }
10109
+ return { geojsonData, isLoading: false };
10110
+ }
10111
+ async function loadTopojsonMap(mapSource) {
10112
+ var _a;
10113
+ const response = await fetch(mapSource.url);
10114
+ const topology = await response.json();
10115
+ if ((topology == null ? void 0 : topology.type) !== "Topology") {
10116
+ throw new UserFacingError(
10117
+ "Invalid map source",
10118
+ `JSON downloaded from ${mapSource.url} does not look like a topojson Topology definition: missing 'type: "Topology"', got '${JSON.stringify(topology).substring(0, 100)}'`
10119
+ );
10120
+ }
10121
+ const object = topology == null ? void 0 : topology.objects[mapSource.topologyObjectsKey];
10122
+ if ((object == null ? void 0 : object.type) !== "GeometryCollection") {
10123
+ throw new UserFacingError(
10124
+ "Invalid map source",
10125
+ `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)}'`
10126
+ );
10127
+ }
10128
+ return topojson.feature(topology, object);
10129
+ }
10130
+ const SequencesByLocationMap = ({
10131
+ mapSource,
10132
+ ...otherProps
10133
+ }) => {
10134
+ const { isLoading: isLoadingMap, geojsonData } = useGeoJsonMap(mapSource);
10135
+ if (isLoadingMap) {
10136
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
10137
+ }
10138
+ return /* @__PURE__ */ u$1(SequencesByLocationMapInner$1, { geojsonData, ...otherProps });
10139
+ };
10140
+ const SequencesByLocationMapInner$1 = ({
10141
+ geojsonData,
10142
+ locationData,
10143
+ enableMapNavigation,
10144
+ lapisLocationField,
10145
+ zoom,
10146
+ offsetX,
10147
+ offsetY
10148
+ }) => {
10149
+ const ref = A(null);
10150
+ y(() => {
10151
+ if (!ref.current || geojsonData === void 0 || locationData === void 0) {
10152
+ return;
10153
+ }
10154
+ const countAndProportionByCountry = buildLookupByLocationField(locationData, lapisLocationField);
10155
+ const locations = matchLocationDataAndGeoJsonFeatures(
10156
+ geojsonData,
10157
+ countAndProportionByCountry,
10158
+ lapisLocationField
10159
+ );
10160
+ const leafletMap = Leaflet.map(ref.current, {
10161
+ scrollWheelZoom: enableMapNavigation,
10162
+ zoomControl: enableMapNavigation,
10163
+ keyboard: enableMapNavigation,
10164
+ dragging: enableMapNavigation,
10165
+ zoomSnap: 0,
10166
+ zoom,
10167
+ center: [offsetY, offsetX]
10168
+ });
10169
+ Leaflet.geoJson(locations, {
10170
+ style: (feature) => {
10171
+ var _a;
10172
+ return {
10173
+ fillColor: getColor((_a = feature == null ? void 0 : feature.properties.data) == null ? void 0 : _a.proportion),
10174
+ fillOpacity: 1,
10175
+ color: "grey",
10176
+ weight: 1
10177
+ };
10178
+ }
10179
+ }).bindTooltip(createTooltip).addTo(leafletMap);
10180
+ return () => {
10181
+ leafletMap.remove();
10182
+ };
10183
+ }, [ref, locationData, geojsonData, enableMapNavigation, lapisLocationField, zoom, offsetX, offsetY]);
10184
+ return /* @__PURE__ */ u$1("div", { ref, className: "h-full" });
10185
+ };
10186
+ function buildLookupByLocationField(locationData, lapisLocationField) {
10187
+ return new Map(
10188
+ locationData.filter((row) => typeof row[lapisLocationField] === "string").map((row) => [row[lapisLocationField], row])
10189
+ );
10190
+ }
10191
+ function matchLocationDataAndGeoJsonFeatures(geojsonData, countAndProportionByCountry, lapisLocationField) {
10192
+ const matchedLocations = [];
10193
+ const locations = geojsonData.features.map(
10194
+ (feature) => {
10195
+ var _a;
10196
+ const name = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.name;
10197
+ if (typeof name !== "string") {
10198
+ throw new Error(
10199
+ `GeoJSON feature with id '${feature.id}' does not have 'properties.name' of type string, was: '${name}'`
10200
+ );
10201
+ }
10202
+ const data = countAndProportionByCountry.get(name) ?? null;
10203
+ if (data !== null) {
10204
+ matchedLocations.push(name);
10205
+ }
10206
+ return {
10207
+ ...feature,
10208
+ properties: {
10209
+ ...feature.properties,
10210
+ data
10211
+ }
10212
+ };
10213
+ }
10214
+ );
10215
+ const unmatchedLocations = [...countAndProportionByCountry.keys()].filter(
10216
+ (name) => !matchedLocations.includes(name)
10217
+ );
10218
+ if (unmatchedLocations.length > 0) {
10219
+ 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(", ")}`;
10220
+ console.warn(unmatchedLocationsWarning);
10221
+ }
10222
+ return locations;
10223
+ }
10224
+ function getColor(value) {
10225
+ if (value === void 0) {
10226
+ return "#888888";
10227
+ }
10228
+ const thresholds = [
10229
+ { limit: 0.4, color: "#662506" },
10230
+ { limit: 0.3, color: "#993404" },
10231
+ { limit: 0.2, color: "#CC4C02" },
10232
+ { limit: 0.1, color: "#EC7014" },
10233
+ { limit: 0.05, color: "#FB9A29" },
10234
+ { limit: 0.02, color: "#FEC44F" },
10235
+ { limit: 0.01, color: "#FEE391" },
10236
+ { limit: 5e-3, color: "#FFF7BC" },
10237
+ { limit: 2e-3, color: "#FFFFE5" }
10238
+ ];
10239
+ for (const { limit, color } of thresholds) {
10240
+ if (value > limit) {
10241
+ return color;
10242
+ }
10243
+ }
10244
+ return "#FFFFE5";
10245
+ }
10246
+ function createTooltip(layer) {
10247
+ const feature = layer.feature;
10248
+ if (feature === void 0 || feature.type !== "Feature") {
10249
+ return "";
10250
+ }
10251
+ const properties = feature.properties;
10252
+ const div = document.createElement("div");
10253
+ div.appendChild(p({ innerText: properties.name, className: "font-bold" }));
10254
+ if (properties.data !== null) {
10255
+ div.appendChild(
10256
+ p({
10257
+ innerText: `Count: ${properties.data.count.toLocaleString("en-us")}`
10258
+ })
10259
+ );
10260
+ div.appendChild(
10261
+ p({
10262
+ innerText: `Proportion: ${formatProportion(properties.data.proportion)}`
10263
+ })
10264
+ );
10265
+ } else {
10266
+ div.appendChild(p({ innerText: "No data" }));
10267
+ }
10268
+ return div;
10269
+ }
10270
+ function p({ innerText, className = "" }) {
10271
+ const headline = document.createElement("p");
10272
+ headline.innerText = innerText;
10273
+ headline.className = className;
10274
+ return headline;
10275
+ }
10276
+ const SequencesByLocationTable = ({
10277
+ locationData,
10278
+ lapisLocationField,
10279
+ pageSize
10280
+ }) => {
10281
+ return /* @__PURE__ */ u$1(AggregateTable, { data: locationData, fields: [lapisLocationField], pageSize });
10282
+ };
10283
+ const sequencesByLocationViewSchema = z$1.union([z$1.literal(views.map), z$1.literal(views.table)]);
10284
+ const sequencesByLocationPropsSchema = z$1.object({
10285
+ lapisFilter: lapisFilterSchema,
10286
+ lapisLocationField: z$1.string().min(1),
10287
+ mapSource: mapSourceSchema.optional(),
10288
+ enableMapNavigation: z$1.boolean(),
10289
+ width: z$1.string(),
10290
+ height: z$1.string(),
10291
+ views: z$1.array(sequencesByLocationViewSchema),
10292
+ zoom: z$1.number(),
10293
+ offsetX: z$1.number(),
10294
+ offsetY: z$1.number(),
10295
+ pageSize: z$1.union([z$1.boolean(), z$1.number()])
10296
+ });
10297
+ const SequencesByLocation = (componentProps) => {
10298
+ const { width, height } = componentProps;
10299
+ const size = { height, width };
10300
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, componentProps, schema: sequencesByLocationPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(SequencesByLocationMapInner, { ...componentProps }) }) });
10301
+ };
10302
+ const SequencesByLocationMapInner = (props) => {
10303
+ const { lapisFilter, lapisLocationField } = props;
10304
+ const lapis = x(LapisUrlContext);
10305
+ const {
10306
+ data,
10307
+ error,
10308
+ isLoading: isLoadingLapisData
10309
+ } = useQuery(
10310
+ async () => queryAggregateData(lapisFilter, [lapisLocationField], lapis),
10311
+ [lapisFilter, lapisLocationField, lapis]
10312
+ );
10313
+ if (isLoadingLapisData) {
10314
+ return /* @__PURE__ */ u$1(LoadingDisplay, {});
10315
+ }
10316
+ if (error) {
10317
+ throw error;
10318
+ }
10319
+ return /* @__PURE__ */ u$1(SequencesByLocationMapTabs, { data, originalComponentProps: props });
10320
+ };
10321
+ const SequencesByLocationMapTabs = ({
10322
+ originalComponentProps,
10323
+ data
10324
+ }) => {
10325
+ const getTab = (view) => {
10326
+ switch (view) {
10327
+ case views.map:
10328
+ if (originalComponentProps.mapSource === void 0) {
10329
+ throw new Error("mapSource is required when using the map view");
10330
+ }
10331
+ return {
10332
+ title: "Map",
10333
+ content: /* @__PURE__ */ u$1(
10334
+ SequencesByLocationMap,
10335
+ {
10336
+ locationData: data,
10337
+ mapSource: originalComponentProps.mapSource,
10338
+ enableMapNavigation: originalComponentProps.enableMapNavigation,
10339
+ lapisLocationField: originalComponentProps.lapisLocationField,
10340
+ zoom: originalComponentProps.zoom,
10341
+ offsetX: originalComponentProps.offsetX,
10342
+ offsetY: originalComponentProps.offsetY
10343
+ }
10344
+ )
10345
+ };
10346
+ case views.table:
10347
+ return {
10348
+ title: "Table",
10349
+ content: /* @__PURE__ */ u$1(
10350
+ SequencesByLocationTable,
10351
+ {
10352
+ locationData: data,
10353
+ lapisLocationField: originalComponentProps.lapisLocationField,
10354
+ pageSize: originalComponentProps.pageSize
10355
+ }
10356
+ )
10357
+ };
10358
+ }
10359
+ };
10360
+ const tabs = originalComponentProps.views.map((view) => getTab(view));
10361
+ return /* @__PURE__ */ u$1(Tabs, { tabs, toolbar: /* @__PURE__ */ u$1(Toolbar, { originalComponentProps }) });
10362
+ };
10363
+ const Toolbar = ({ originalComponentProps }) => {
10364
+ return /* @__PURE__ */ u$1("div", { class: "flex flex-row", children: [
10365
+ /* @__PURE__ */ u$1(SequencesByLocationMapInfo, { originalComponentProps }),
10366
+ /* @__PURE__ */ u$1(Fullscreen, {})
10367
+ ] });
10368
+ };
10369
+ const SequencesByLocationMapInfo = ({ originalComponentProps }) => {
10370
+ const lapis = x(LapisUrlContext);
10371
+ return /* @__PURE__ */ u$1(Info, { children: [
10372
+ /* @__PURE__ */ u$1(InfoHeadline1, { children: "Prevalence by location" }),
10373
+ /* @__PURE__ */ u$1(InfoParagraph, { children: "TODO: Add description https://github.com/GenSpectrum/dashboard-components/issues/598" }),
10374
+ /* @__PURE__ */ u$1(InfoComponentCode, { componentName: "sequences-by-location", params: originalComponentProps, lapisUrl: lapis })
10375
+ ] });
10376
+ };
10377
+ var __defProp$6 = Object.defineProperty;
10378
+ var __getOwnPropDesc$6 = Object.getOwnPropertyDescriptor;
10379
+ var __decorateClass$6 = (decorators, target, key, kind) => {
10380
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$6(target, key) : target;
10381
+ for (var i2 = decorators.length - 1, decorator; i2 >= 0; i2--)
10382
+ if (decorator = decorators[i2])
10383
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
10384
+ if (kind && result) __defProp$6(target, key, result);
10385
+ return result;
10386
+ };
10387
+ const leafletCss = unsafeCSS(leafletStyle);
10388
+ const leafletModificationsCss = unsafeCSS(leafletStyleModifications);
10389
+ let SequencesByLocationComponent = class extends PreactLitAdapterWithGridJsStyles {
10390
+ constructor() {
10391
+ super(...arguments);
10392
+ this.lapisFilter = {};
10393
+ this.lapisLocationField = "";
10394
+ this.mapSource = void 0;
10395
+ this.enableMapNavigation = true;
10396
+ this.width = "100%";
10397
+ this.height = "700px";
10398
+ this.views = ["map", "table"];
10399
+ this.zoom = 1;
10400
+ this.offsetX = 0;
10401
+ this.offsetY = 0;
10402
+ this.pageSize = false;
10403
+ }
10404
+ render() {
10405
+ return /* @__PURE__ */ u$1(
10406
+ SequencesByLocation,
10407
+ {
10408
+ lapisFilter: this.lapisFilter,
10409
+ lapisLocationField: this.lapisLocationField,
10410
+ mapSource: this.mapSource,
10411
+ enableMapNavigation: this.enableMapNavigation,
10412
+ width: this.width,
10413
+ height: this.height,
10414
+ views: this.views,
10415
+ zoom: this.zoom,
10416
+ offsetX: this.offsetX,
10417
+ offsetY: this.offsetY,
10418
+ pageSize: this.pageSize
10419
+ }
10420
+ );
10421
+ }
10422
+ };
10423
+ SequencesByLocationComponent.styles = [...PreactLitAdapterWithGridJsStyles.styles, leafletCss, leafletModificationsCss];
10424
+ __decorateClass$6([
10425
+ n2({ type: Object })
10426
+ ], SequencesByLocationComponent.prototype, "lapisFilter", 2);
10427
+ __decorateClass$6([
10428
+ n2({ type: String })
10429
+ ], SequencesByLocationComponent.prototype, "lapisLocationField", 2);
10430
+ __decorateClass$6([
10431
+ n2({ type: Object })
10432
+ ], SequencesByLocationComponent.prototype, "mapSource", 2);
10433
+ __decorateClass$6([
10434
+ n2({ type: Boolean })
10435
+ ], SequencesByLocationComponent.prototype, "enableMapNavigation", 2);
10436
+ __decorateClass$6([
10437
+ n2({ type: String })
10438
+ ], SequencesByLocationComponent.prototype, "width", 2);
10439
+ __decorateClass$6([
10440
+ n2({ type: String })
10441
+ ], SequencesByLocationComponent.prototype, "height", 2);
10442
+ __decorateClass$6([
10443
+ n2({ type: Array })
10444
+ ], SequencesByLocationComponent.prototype, "views", 2);
10445
+ __decorateClass$6([
10446
+ n2({ type: Number })
10447
+ ], SequencesByLocationComponent.prototype, "zoom", 2);
10448
+ __decorateClass$6([
10449
+ n2({ type: Number })
10450
+ ], SequencesByLocationComponent.prototype, "offsetX", 2);
10451
+ __decorateClass$6([
10452
+ n2({ type: Number })
10453
+ ], SequencesByLocationComponent.prototype, "offsetY", 2);
10454
+ __decorateClass$6([
10455
+ n2({ type: Object })
10456
+ ], SequencesByLocationComponent.prototype, "pageSize", 2);
10457
+ SequencesByLocationComponent = __decorateClass$6([
10458
+ t$2("gs-sequences-by-location")
10459
+ ], SequencesByLocationComponent);
9310
10460
  async function queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis, signal) {
9311
10461
  const numeratorCount = await queryAggregateData(numeratorFilter, [], lapis, void 0, signal);
9312
10462
  const denominatorCount = await queryAggregateData(denominatorFilter, [], lapis, void 0, signal);
@@ -9315,10 +10465,16 @@ async function queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis,
9315
10465
  }
9316
10466
  return { proportion: numeratorCount[0].count / denominatorCount[0].count, count: numeratorCount[0].count };
9317
10467
  }
10468
+ const statisticsPropsSchema = z$1.object({
10469
+ width: z$1.string(),
10470
+ height: z$1.string(),
10471
+ numeratorFilter: lapisFilterSchema,
10472
+ denominatorFilter: lapisFilterSchema
10473
+ });
9318
10474
  const Statistics = (componentProps) => {
9319
10475
  const { width, height } = componentProps;
9320
10476
  const size = { height, width };
9321
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(StatisticsInner, { ...componentProps }) }) });
10477
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, schema: statisticsPropsSchema, componentProps, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(StatisticsInner, { ...componentProps }) }) });
9322
10478
  };
9323
10479
  const StatisticsInner = (componentProps) => {
9324
10480
  const { numeratorFilter, denominatorFilter } = componentProps;
@@ -9866,9 +11022,18 @@ async function fetchAutocompleteList(lapis, field, signal) {
9866
11022
  const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
9867
11023
  return data.map((item) => item[field]);
9868
11024
  }
9869
- const TextInput = ({ width, ...innerProps }) => {
11025
+ const textInputInnerPropsSchema = z$1.object({
11026
+ lapisField: z$1.string().min(1),
11027
+ placeholderText: z$1.string().optional(),
11028
+ initialValue: z$1.string().optional()
11029
+ });
11030
+ const textInputPropsSchema = textInputInnerPropsSchema.extend({
11031
+ width: z$1.string()
11032
+ });
11033
+ const TextInput = (props) => {
11034
+ const { width, ...innerProps } = props;
9870
11035
  const size = { width, height: "3rem" };
9871
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
11036
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", componentProps: props, schema: textInputPropsSchema, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
9872
11037
  };
9873
11038
  const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
9874
11039
  const lapis = x(LapisUrlContext);
@@ -9908,7 +11073,7 @@ const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
9908
11073
  {
9909
11074
  type: "text",
9910
11075
  class: "input input-bordered w-full",
9911
- placeholder: placeholderText !== void 0 ? placeholderText : lapisField,
11076
+ placeholder: placeholderText ?? lapisField,
9912
11077
  onInput,
9913
11078
  ref: inputRef,
9914
11079
  list: lapisField,
@@ -9931,9 +11096,9 @@ var __decorateClass$2 = (decorators, target, key, kind) => {
9931
11096
  let TextInputComponent = class extends PreactLitAdapter {
9932
11097
  constructor() {
9933
11098
  super(...arguments);
9934
- this.initialValue = "";
11099
+ this.initialValue = void 0;
9935
11100
  this.lapisField = "";
9936
- this.placeholderText = "";
11101
+ this.placeholderText = void 0;
9937
11102
  this.width = "100%";
9938
11103
  }
9939
11104
  render() {
@@ -10237,8 +11402,30 @@ const parseAndValidateMutation = (value, referenceGenome) => {
10237
11402
  }
10238
11403
  return null;
10239
11404
  };
10240
- const MutationFilter = ({ initialValue, width }) => {
10241
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: { height: "3.375rem", width }, layout: "horizontal", children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
11405
+ const selectedMutationFilterStringsSchema = z$1.object({
11406
+ nucleotideMutations: z$1.array(z$1.string()),
11407
+ aminoAcidMutations: z$1.array(z$1.string()),
11408
+ nucleotideInsertions: z$1.array(z$1.string()),
11409
+ aminoAcidInsertions: z$1.array(z$1.string())
11410
+ });
11411
+ const mutationFilterInnerPropsSchema = z$1.object({
11412
+ initialValue: z$1.union([selectedMutationFilterStringsSchema.optional(), z$1.array(z$1.string()), z$1.undefined()])
11413
+ });
11414
+ const mutationFilterPropsSchema = mutationFilterInnerPropsSchema.extend({
11415
+ width: z$1.string()
11416
+ });
11417
+ const MutationFilter = (props) => {
11418
+ const { width, initialValue } = props;
11419
+ return /* @__PURE__ */ u$1(
11420
+ ErrorBoundary,
11421
+ {
11422
+ size: { height: "3.375rem", width },
11423
+ layout: "horizontal",
11424
+ schema: mutationFilterPropsSchema,
11425
+ componentProps: props,
11426
+ children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) })
11427
+ }
11428
+ );
10242
11429
  };
10243
11430
  const MutationFilterInner = ({ initialValue }) => {
10244
11431
  const referenceGenome = x(ReferenceGenomeContext);
@@ -10645,6 +11832,7 @@ export {
10645
11832
  NumberSequencesOverTimeComponent,
10646
11833
  PrevalenceOverTimeComponent,
10647
11834
  RelativeGrowthAdvantageComponent,
11835
+ SequencesByLocationComponent,
10648
11836
  StatisticsComponent,
10649
11837
  TextInputComponent,
10650
11838
  UserFacingError