@mnaoumov/typescript-dev-toolkit 1.3.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/README.md +4 -0
  2. package/assets/docs-site/components/ConstructorBlock.astro +16 -0
  3. package/assets/docs-site/components/ImportStatement.astro +12 -0
  4. package/assets/docs-site/components/MemberDetail.astro +101 -0
  5. package/assets/docs-site/components/MethodTable.astro +45 -0
  6. package/assets/docs-site/components/PropertyTable.astro +45 -0
  7. package/assets/docs-site/components/SiteTitle.astro +43 -0
  8. package/assets/docs-site/components/TypeSignature.astro +20 -0
  9. package/assets/docs-site/fonts/inter-latin-400-normal.ttf +0 -0
  10. package/assets/docs-site/fonts/inter-latin-700-normal.ttf +0 -0
  11. package/assets/docs-site/styles/global.css +221 -0
  12. package/dist/lib/cjs/build.cjs +1 -1
  13. package/dist/lib/cjs/build.d.cts +1 -1
  14. package/dist/lib/cjs/commitlint-config.cjs +18 -3
  15. package/dist/lib/cjs/commitlint-config.d.cts +6 -0
  16. package/dist/lib/cjs/commitlint-forbidden-patterns.cjs +2 -2
  17. package/dist/lib/cjs/commitlint-forbidden-patterns.d.cts +1 -1
  18. package/dist/lib/cjs/commitlint-spellcheck-header.cjs +2 -2
  19. package/dist/lib/cjs/commitlint-spellcheck-header.d.cts +1 -1
  20. package/dist/lib/cjs/docs-site/api-doc-constants.cjs +171 -0
  21. package/dist/lib/cjs/docs-site/api-doc-constants.d.cts +18 -0
  22. package/dist/lib/cjs/docs-site/api-doc-jsdoc.cjs +414 -0
  23. package/dist/lib/cjs/docs-site/api-doc-jsdoc.d.cts +149 -0
  24. package/dist/lib/cjs/docs-site/api-doc-link-rendering.cjs +377 -0
  25. package/dist/lib/cjs/docs-site/api-doc-link-rendering.d.cts +185 -0
  26. package/dist/lib/cjs/docs-site/api-doc-package-sites.cjs +118 -0
  27. package/dist/lib/cjs/docs-site/api-doc-package-sites.d.cts +36 -0
  28. package/dist/lib/cjs/docs-site/api-doc-page-generation.cjs +561 -0
  29. package/dist/lib/cjs/docs-site/api-doc-page-generation.d.cts +159 -0
  30. package/dist/lib/cjs/docs-site/api-doc-route-segments.cjs +42 -0
  31. package/dist/lib/cjs/docs-site/api-doc-route-segments.d.cts +25 -0
  32. package/dist/lib/cjs/docs-site/api-doc-settings.cjs +47 -0
  33. package/dist/lib/cjs/docs-site/api-doc-settings.d.cts +53 -0
  34. package/dist/lib/cjs/docs-site/api-doc-source-processing.cjs +288 -0
  35. package/dist/lib/cjs/docs-site/api-doc-source-processing.d.cts +75 -0
  36. package/dist/lib/cjs/docs-site/api-doc-text-utils.cjs +281 -0
  37. package/dist/lib/cjs/docs-site/api-doc-text-utils.d.cts +178 -0
  38. package/dist/lib/cjs/docs-site/api-doc-type-merging.cjs +157 -0
  39. package/dist/lib/cjs/docs-site/api-doc-type-merging.d.cts +51 -0
  40. package/dist/lib/cjs/docs-site/api-doc-types.cjs +22 -0
  41. package/dist/lib/cjs/docs-site/api-doc-types.d.cts +157 -0
  42. package/dist/lib/cjs/docs-site/api-docs.cjs +143 -0
  43. package/dist/lib/cjs/docs-site/api-docs.d.cts +34 -0
  44. package/dist/lib/cjs/docs-site/astro-config.cjs +169 -0
  45. package/dist/lib/cjs/docs-site/astro-config.d.cts +23 -0
  46. package/dist/lib/cjs/docs-site/docs-links.cjs +123 -0
  47. package/dist/lib/cjs/docs-site/docs-links.d.cts +32 -0
  48. package/dist/lib/cjs/docs-site/docs-site-assets.cjs +64 -0
  49. package/dist/lib/cjs/docs-site/docs-site-assets.d.cts +23 -0
  50. package/dist/lib/cjs/docs-site/docs-site-commands.cjs +72 -0
  51. package/dist/lib/cjs/docs-site/docs-site-commands.d.cts +29 -0
  52. package/dist/lib/cjs/docs-site/docs-site-config.cjs +122 -0
  53. package/dist/lib/cjs/docs-site/docs-site-config.d.cts +162 -0
  54. package/dist/lib/cjs/docs-site/index.cjs +116 -0
  55. package/dist/lib/cjs/docs-site/index.d.cts +26 -0
  56. package/dist/lib/cjs/docs-site/link-check.cjs +197 -0
  57. package/dist/lib/cjs/docs-site/link-check.d.cts +163 -0
  58. package/dist/lib/cjs/docs-site/og-image-page.cjs +45 -0
  59. package/dist/lib/cjs/docs-site/og-image-page.d.cts +15 -0
  60. package/dist/lib/cjs/docs-site/og-image.cjs +326 -0
  61. package/dist/lib/cjs/docs-site/og-image.d.cts +70 -0
  62. package/dist/lib/cjs/docs-site/og-images.cjs +170 -0
  63. package/dist/lib/cjs/docs-site/og-images.d.cts +41 -0
  64. package/dist/lib/cjs/docs-site/route-data.cjs +47 -0
  65. package/dist/lib/cjs/docs-site/route-data.d.cts +14 -0
  66. package/dist/lib/cjs/docs-site/satteri-github-alerts.cjs +97 -0
  67. package/dist/lib/cjs/docs-site/satteri-github-alerts.d.cts +31 -0
  68. package/dist/lib/cjs/docs-site/satteri-relative-links.cjs +87 -0
  69. package/dist/lib/cjs/docs-site/satteri-relative-links.d.cts +29 -0
  70. package/dist/lib/cjs/docs-site/unrendered-alerts.cjs +51 -0
  71. package/dist/lib/cjs/docs-site/unrendered-alerts.d.cts +38 -0
  72. package/dist/lib/cjs/index.cjs +4 -1
  73. package/dist/lib/cjs/index.d.cts +1 -0
  74. package/dist/lib/cjs/library-build.cjs +1 -1
  75. package/dist/lib/cjs/library-build.d.cts +2 -2
  76. package/dist/lib/cjs/linters/eslint-config.cjs +17 -17
  77. package/dist/lib/cjs/linters/eslint-config.d.cts +1 -7
  78. package/dist/lib/cjs/linters/eslint-rules/in-house-plugin.cjs +2 -2
  79. package/dist/lib/cjs/linters/eslint-rules/in-house-plugin.d.cts +5 -8
  80. package/dist/lib/cjs/package-manager.cjs +2 -2
  81. package/dist/lib/esm/build.d.mts +1 -1
  82. package/dist/lib/esm/build.mjs +1 -1
  83. package/dist/lib/esm/commitlint-config.d.mts +6 -0
  84. package/dist/lib/esm/commitlint-config.mjs +7 -3
  85. package/dist/lib/esm/commitlint-forbidden-patterns.d.mts +1 -1
  86. package/dist/lib/esm/commitlint-forbidden-patterns.mjs +2 -2
  87. package/dist/lib/esm/commitlint-spellcheck-header.d.mts +1 -1
  88. package/dist/lib/esm/commitlint-spellcheck-header.mjs +2 -2
  89. package/dist/lib/esm/docs-site/api-doc-constants.d.mts +18 -0
  90. package/dist/lib/esm/docs-site/api-doc-constants.mjs +143 -0
  91. package/dist/lib/esm/docs-site/api-doc-jsdoc.d.mts +149 -0
  92. package/dist/lib/esm/docs-site/api-doc-jsdoc.mjs +377 -0
  93. package/dist/lib/esm/docs-site/api-doc-link-rendering.d.mts +185 -0
  94. package/dist/lib/esm/docs-site/api-doc-link-rendering.mjs +356 -0
  95. package/dist/lib/esm/docs-site/api-doc-package-sites.d.mts +36 -0
  96. package/dist/lib/esm/docs-site/api-doc-package-sites.mjs +91 -0
  97. package/dist/lib/esm/docs-site/api-doc-page-generation.d.mts +159 -0
  98. package/dist/lib/esm/docs-site/api-doc-page-generation.mjs +548 -0
  99. package/dist/lib/esm/docs-site/api-doc-route-segments.d.mts +25 -0
  100. package/dist/lib/esm/docs-site/api-doc-route-segments.mjs +17 -0
  101. package/dist/lib/esm/docs-site/api-doc-settings.d.mts +53 -0
  102. package/dist/lib/esm/docs-site/api-doc-settings.mjs +22 -0
  103. package/dist/lib/esm/docs-site/api-doc-source-processing.d.mts +75 -0
  104. package/dist/lib/esm/docs-site/api-doc-source-processing.mjs +274 -0
  105. package/dist/lib/esm/docs-site/api-doc-text-utils.d.mts +178 -0
  106. package/dist/lib/esm/docs-site/api-doc-text-utils.mjs +239 -0
  107. package/dist/lib/esm/docs-site/api-doc-type-merging.d.mts +51 -0
  108. package/dist/lib/esm/docs-site/api-doc-type-merging.mjs +129 -0
  109. package/dist/lib/esm/docs-site/api-doc-types.d.mts +157 -0
  110. package/dist/lib/esm/docs-site/api-doc-types.mjs +6 -0
  111. package/dist/lib/esm/docs-site/api-docs.d.mts +34 -0
  112. package/dist/lib/esm/docs-site/api-docs.mjs +139 -0
  113. package/dist/lib/esm/docs-site/astro-config.d.mts +23 -0
  114. package/dist/lib/esm/docs-site/astro-config.mjs +135 -0
  115. package/dist/lib/esm/docs-site/docs-links.d.mts +32 -0
  116. package/dist/lib/esm/docs-site/docs-links.mjs +113 -0
  117. package/dist/lib/esm/docs-site/docs-site-assets.d.mts +23 -0
  118. package/dist/lib/esm/docs-site/docs-site-assets.mjs +32 -0
  119. package/dist/lib/esm/docs-site/docs-site-commands.d.mts +29 -0
  120. package/dist/lib/esm/docs-site/docs-site-commands.mjs +46 -0
  121. package/dist/lib/esm/docs-site/docs-site-config.d.mts +162 -0
  122. package/dist/lib/esm/docs-site/docs-site-config.mjs +98 -0
  123. package/dist/lib/esm/docs-site/index.d.mts +26 -0
  124. package/dist/lib/esm/docs-site/index.mjs +58 -0
  125. package/dist/lib/esm/docs-site/link-check.d.mts +163 -0
  126. package/dist/lib/esm/docs-site/link-check.mjs +166 -0
  127. package/dist/lib/esm/docs-site/og-image-page.d.mts +15 -0
  128. package/dist/lib/esm/docs-site/og-image-page.mjs +21 -0
  129. package/dist/lib/esm/docs-site/og-image.d.mts +70 -0
  130. package/dist/lib/esm/docs-site/og-image.mjs +292 -0
  131. package/dist/lib/esm/docs-site/og-images.d.mts +41 -0
  132. package/dist/lib/esm/docs-site/og-images.mjs +156 -0
  133. package/dist/lib/esm/docs-site/route-data.d.mts +14 -0
  134. package/dist/lib/esm/docs-site/route-data.mjs +23 -0
  135. package/dist/lib/esm/docs-site/satteri-github-alerts.d.mts +31 -0
  136. package/dist/lib/esm/docs-site/satteri-github-alerts.mjs +72 -0
  137. package/dist/lib/esm/docs-site/satteri-relative-links.d.mts +29 -0
  138. package/dist/lib/esm/docs-site/satteri-relative-links.mjs +63 -0
  139. package/dist/lib/esm/docs-site/unrendered-alerts.d.mts +38 -0
  140. package/dist/lib/esm/docs-site/unrendered-alerts.mjs +26 -0
  141. package/dist/lib/esm/index.d.mts +1 -0
  142. package/dist/lib/esm/index.mjs +3 -1
  143. package/dist/lib/esm/library-build.d.mts +2 -2
  144. package/dist/lib/esm/library-build.mjs +1 -1
  145. package/dist/lib/esm/linters/eslint-config.d.mts +1 -7
  146. package/dist/lib/esm/linters/eslint-config.mjs +17 -17
  147. package/dist/lib/esm/linters/eslint-rules/in-house-plugin.d.mts +5 -8
  148. package/dist/lib/esm/linters/eslint-rules/in-house-plugin.mjs +2 -2
  149. package/dist/lib/esm/package-manager.mjs +2 -2
  150. package/docs-site/api-doc-constants/package.json +6 -0
  151. package/docs-site/api-doc-jsdoc/package.json +6 -0
  152. package/docs-site/api-doc-link-rendering/package.json +6 -0
  153. package/docs-site/api-doc-package-sites/package.json +6 -0
  154. package/docs-site/api-doc-page-generation/package.json +6 -0
  155. package/docs-site/api-doc-route-segments/package.json +6 -0
  156. package/docs-site/api-doc-settings/package.json +6 -0
  157. package/docs-site/api-doc-source-processing/package.json +6 -0
  158. package/docs-site/api-doc-text-utils/package.json +6 -0
  159. package/docs-site/api-doc-type-merging/package.json +6 -0
  160. package/docs-site/api-doc-types/package.json +6 -0
  161. package/docs-site/api-docs/package.json +6 -0
  162. package/docs-site/astro-config/package.json +6 -0
  163. package/docs-site/docs-links/package.json +6 -0
  164. package/docs-site/docs-site-assets/package.json +6 -0
  165. package/docs-site/docs-site-commands/package.json +6 -0
  166. package/docs-site/docs-site-config/package.json +6 -0
  167. package/docs-site/index/package.json +6 -0
  168. package/docs-site/link-check/package.json +6 -0
  169. package/docs-site/og-image/package.json +6 -0
  170. package/docs-site/og-image-page/package.json +6 -0
  171. package/docs-site/og-images/package.json +6 -0
  172. package/docs-site/package.json +6 -0
  173. package/docs-site/route-data/package.json +6 -0
  174. package/docs-site/satteri-github-alerts/package.json +6 -0
  175. package/docs-site/satteri-relative-links/package.json +6 -0
  176. package/docs-site/unrendered-alerts/package.json +6 -0
  177. package/package.json +75 -5
@@ -0,0 +1,548 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+ (function () {
6
+ function ensureBrowserProcess() {
7
+ const browserProcess = {
8
+ browser: true,
9
+ cwd() {
10
+ return '/';
11
+ },
12
+ env: {},
13
+ platform: 'android'
14
+ };
15
+
16
+ const existingProcess = globalThis.process;
17
+
18
+ if (!existingProcess) {
19
+ globalThis.process = browserProcess;
20
+ return;
21
+ }
22
+
23
+ if (existingProcess.versions?.node) {
24
+ return;
25
+ }
26
+
27
+ const existingProcessRecord = existingProcess;
28
+
29
+ for (const [key, value] of Object.entries(browserProcess)) {
30
+ existingProcessRecord[key] ??= value;
31
+ }
32
+
33
+ existingProcessRecord['browser'] = true;
34
+ }
35
+
36
+ ensureBrowserProcess();
37
+ })();
38
+
39
+ import { getMandatoryNamedGroup } from "@mnaoumov/typescript-lib/reg-exp";
40
+ import { ensureNonNullable } from "@mnaoumov/typescript-lib/type-guards";
41
+ import { writeFile } from "node:fs/promises";
42
+ import { join } from "node:path";
43
+ import { EVENT_METHODS } from "./api-doc-constants.mjs";
44
+ import {
45
+ linkBaseType,
46
+ markdownToHtml,
47
+ memberHref,
48
+ renderExampleMdx,
49
+ renderMdxProse,
50
+ renderTypeWithLinks,
51
+ resolveLinks,
52
+ toTypeFileSegment,
53
+ toTypeRouteSegment,
54
+ typeLink
55
+ } from "./api-doc-link-rendering.mjs";
56
+ import { getApiDocSettings } from "./api-doc-settings.mjs";
57
+ import {
58
+ ensureDirectory,
59
+ escapeJsString,
60
+ escapeJsxAttribute,
61
+ escapeMarkdown,
62
+ escapeMdxAngleBrackets,
63
+ escapeMdxBraces,
64
+ escapeYaml,
65
+ getDisplayName,
66
+ getImportStatement,
67
+ getNamespaceDirectory,
68
+ memberRouteSegment,
69
+ memberSlug,
70
+ overloadRouteSegment,
71
+ overloadSlug,
72
+ stripMarkdown,
73
+ truncateSignature
74
+ } from "./api-doc-text-utils.mjs";
75
+ import { API_COMPONENTS_IMPORT_PREFIX } from "./docs-site-assets.mjs";
76
+ const JSON_INDENT = 2;
77
+ async function appendBacklinksAndWrite(pageContents, allTypes) {
78
+ const backlinks = buildBacklinksFromContent(pageContents, allTypes);
79
+ for (const [key, { content, filePath }] of pageContents) {
80
+ const typeBacklinks = backlinks.get(key) ?? [];
81
+ const lines = [content];
82
+ if (typeBacklinks.length > 0) {
83
+ const sortedBacklinks = [...typeBacklinks].sort((a, b) => a.localeCompare(b));
84
+ lines.push("", "---", "", "**Links to this page:**", "");
85
+ for (const blKey of sortedBacklinks) {
86
+ const blInfo = ensureNonNullable(allTypes.get(blKey));
87
+ const blNsDirectory = getNamespaceDirectory(blInfo.namespace);
88
+ lines.push(`- [${blInfo.name}](${getApiDocSettings().basePath}/api/${blNsDirectory}/${toTypeRouteSegment(blInfo.namespace, blInfo.name)}/)`);
89
+ }
90
+ }
91
+ await writeFile(filePath, lines.join("\n"), "utf-8");
92
+ }
93
+ }
94
+ function buildBacklinksFromContent(pageContents, allTypes) {
95
+ const backlinks = /* @__PURE__ */ new Map();
96
+ const routeKeyToTypeKey = /* @__PURE__ */ new Map();
97
+ for (const [typeKey, info] of allTypes) {
98
+ routeKeyToTypeKey.set(`${getNamespaceDirectory(info.namespace)}#${toTypeRouteSegment(info.namespace, info.name)}`, typeKey);
99
+ }
100
+ const escapedBase = getApiDocSettings().basePath.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
101
+ const linkPattern = new RegExp(`${escapedBase}/api/(?<path>(?:[a-zA-Z0-9_@-]+/)+)`, "g");
102
+ for (const [sourceKey, { content }] of pageContents) {
103
+ const referenced = /* @__PURE__ */ new Set();
104
+ for (const match of content.matchAll(linkPattern)) {
105
+ const segments = getMandatoryNamedGroup(match, "path").split("/").filter(Boolean);
106
+ const typeName = ensureNonNullable(segments.at(-1));
107
+ const namespace = segments.slice(0, -1).join("/");
108
+ const routeKey = `${namespace}#${typeName}`;
109
+ const resolvedKey = routeKeyToTypeKey.get(routeKey);
110
+ if (resolvedKey !== void 0 && resolvedKey !== sourceKey) {
111
+ referenced.add(resolvedKey);
112
+ }
113
+ }
114
+ for (const reference of referenced) {
115
+ if (!backlinks.has(reference)) {
116
+ backlinks.set(reference, []);
117
+ }
118
+ backlinks.get(reference)?.push(sourceKey);
119
+ }
120
+ }
121
+ return backlinks;
122
+ }
123
+ function buildSidebarTree(types) {
124
+ const root = { children: /* @__PURE__ */ new Map(), types: [] };
125
+ for (const [, info] of types) {
126
+ const parts = info.namespace.split("/");
127
+ let node = root;
128
+ for (const part of parts) {
129
+ let child = node.children.get(part);
130
+ if (!child) {
131
+ child = { children: /* @__PURE__ */ new Map(), types: [] };
132
+ node.children.set(part, child);
133
+ }
134
+ node = child;
135
+ }
136
+ node.types.push(info);
137
+ }
138
+ return root;
139
+ }
140
+ function computeOverviewSignature(name, info) {
141
+ if (info.kind === "function") {
142
+ const $function = info.methods[0];
143
+ return $function ? `function ${$function.signature}: ${$function.returnType}` : void 0;
144
+ }
145
+ if (info.kind === "type") {
146
+ return `type ${getDisplayName(info.name, info)} = ${info.typeAliasText ?? "unknown"}`;
147
+ }
148
+ return info.kind === "variable" ? `${info.variableKeyword ?? "let"} ${name}: ${info.variableType ?? "unknown"}` : void 0;
149
+ }
150
+ async function generateMemberPages(name, info, allTypes) {
151
+ const nsDirectory = getNamespaceDirectory(info.namespace);
152
+ const typeFileDirectory = toTypeFileSegment(info.namespace, name);
153
+ const typeRouteDirectory = toTypeRouteSegment(info.namespace, name);
154
+ const componentImports = getComponentImports(["MemberDetail"]);
155
+ const properties = info.properties.filter((p) => !p.inheritedFrom);
156
+ for (const property of properties) {
157
+ const filePath = join(getApiDocSettings().outputDirectory, nsDirectory, typeFileDirectory, `${memberSlug(property.name)}.mdx`);
158
+ await ensureDirectory(filePath);
159
+ const propertyTitle = `${name}.${property.name}`;
160
+ const lines = renderFrontMatter({
161
+ description: property.description,
162
+ sidebarLabel: propertyTitle,
163
+ signature: `${property.signature}: ${property.type}`,
164
+ slug: `api/${nsDirectory}/${typeRouteDirectory}/${memberRouteSegment(property.name)}`,
165
+ title: propertyTitle
166
+ });
167
+ lines.push(
168
+ ...componentImports,
169
+ "",
170
+ // Breadcrumb
171
+ `[${name}](${getApiDocSettings().basePath}/api/${nsDirectory}/${typeRouteDirectory}/) \u203A ${property.name}`,
172
+ ""
173
+ );
174
+ const staticAttribute = property.isStatic ? " isStatic={true}" : "";
175
+ const typeAttribute = ` type="${escapeJsxAttribute(markdownToHtml(renderTypeWithLinks(property.type, allTypes, name, info.namespace)))}"`;
176
+ const descAttribute = property.description ? ` description="${escapeJsxAttribute(markdownToHtml(resolveLinks(property.description, allTypes, info.namespace)))}"` : "";
177
+ const remarksAttribute = property.remarks ? ` remarks="${escapeJsxAttribute(markdownToHtml(resolveLinks(property.remarks, allTypes, info.namespace)))}"` : "";
178
+ const sinceAttribute = property.since ? ` since="${escapeJsxAttribute(property.since)}"` : "";
179
+ const examplesAttribute = property.examples.length > 0 ? ` examples={${JSON.stringify(property.examples)}}` : "";
180
+ lines.push(`<MemberDetail${staticAttribute}${typeAttribute}${descAttribute}${remarksAttribute}${sinceAttribute}${examplesAttribute} />`, "");
181
+ await writeFile(filePath, lines.join("\n"), "utf-8");
182
+ }
183
+ const methods = info.methods.filter((m) => !m.inheritedFrom);
184
+ const overloadGroups = /* @__PURE__ */ new Map();
185
+ for (const method of methods) {
186
+ const key = method.overloadKey;
187
+ if (!overloadGroups.has(key)) {
188
+ overloadGroups.set(key, []);
189
+ }
190
+ overloadGroups.get(key)?.push(method);
191
+ }
192
+ for (const [overloadKey, overloads] of overloadGroups) {
193
+ const fileSlug = overloadSlug(overloadKey);
194
+ const filePath = join(getApiDocSettings().outputDirectory, nsDirectory, typeFileDirectory, `${fileSlug}.mdx`);
195
+ await ensureDirectory(filePath);
196
+ const displayName = `${name}.${overloadKey} method`;
197
+ const firstOverload = ensureNonNullable(overloads[0]);
198
+ const lines = renderFrontMatter({
199
+ description: firstOverload.description,
200
+ sidebarLabel: `${name}.${overloadKey}`,
201
+ signature: `${firstOverload.signature}: ${firstOverload.returnType}`,
202
+ slug: `api/${nsDirectory}/${typeRouteDirectory}/${overloadRouteSegment(overloadKey)}`,
203
+ title: displayName
204
+ });
205
+ lines.push(
206
+ ...componentImports,
207
+ "",
208
+ // Breadcrumb
209
+ `[${name}](${getApiDocSettings().basePath}/api/${nsDirectory}/${typeRouteDirectory}/) \u203A ${overloadKey}`,
210
+ ""
211
+ );
212
+ for (const overload of overloads) {
213
+ renderMethodOverloadMdx(lines, overload, name, info.namespace, allTypes);
214
+ if (overloads.length > 1) {
215
+ lines.push("---", "");
216
+ }
217
+ }
218
+ await writeFile(filePath, lines.join("\n"), "utf-8");
219
+ }
220
+ }
221
+ async function generateNamespaceIndexPages(types, allTypes, moduleOverviews) {
222
+ const namespaces = /* @__PURE__ */ new Map();
223
+ for (const [, info] of types) {
224
+ if (!namespaces.has(info.namespace)) {
225
+ namespaces.set(info.namespace, []);
226
+ }
227
+ namespaces.get(info.namespace)?.push(info);
228
+ }
229
+ for (const [namespace, nsTypes] of namespaces) {
230
+ const nsDirectory = getNamespaceDirectory(namespace);
231
+ const filePath = join(getApiDocSettings().outputDirectory, nsDirectory, "index.mdx");
232
+ await ensureDirectory(filePath);
233
+ const overview = moduleOverviews.get(namespace);
234
+ const lines = renderFrontMatter({
235
+ description: overview,
236
+ sidebarLabel: namespace,
237
+ slug: `api/${nsDirectory}`,
238
+ title: namespace
239
+ });
240
+ if (overview) {
241
+ lines.push(renderMdxProse(overview, allTypes, namespace), "");
242
+ }
243
+ renderNamespaceTable(lines, "Classes", "Class", nsTypes.filter((t) => t.kind === "class"), allTypes, namespace);
244
+ renderNamespaceTable(lines, "Interfaces", "Interface", nsTypes.filter((t) => t.kind === "interface"), allTypes, namespace);
245
+ renderNamespaceTable(lines, "Functions", "Function", nsTypes.filter((t) => t.kind === "function"), allTypes, namespace);
246
+ renderNamespaceTable(lines, "Types", "Type", nsTypes.filter((t) => t.kind === "type"), allTypes, namespace);
247
+ renderNamespaceTable(lines, "Enums", "Enum", nsTypes.filter((t) => t.kind === "enum"), allTypes, namespace);
248
+ renderNamespaceTable(lines, "Variables", "Variable", nsTypes.filter((t) => t.kind === "variable"), allTypes, namespace);
249
+ await writeFile(filePath, lines.join("\n"), "utf-8");
250
+ }
251
+ const sortedNamespaces = [...namespaces.keys()].sort((a, b) => a.localeCompare(b));
252
+ const apiIndexIntro = getApiIndexIntro(sortedNamespaces);
253
+ const rootLines = renderFrontMatter({
254
+ description: apiIndexIntro,
255
+ sidebarLabel: "Overview",
256
+ slug: "api",
257
+ title: "API reference"
258
+ });
259
+ rootLines.push(apiIndexIntro, "", "## Modules", "");
260
+ for (const namespace of sortedNamespaces) {
261
+ rootLines.push(`- [${namespace}](${getApiDocSettings().basePath}/api/${getNamespaceDirectory(namespace)}/)`);
262
+ }
263
+ rootLines.push("");
264
+ const rootFilePath = join(getApiDocSettings().outputDirectory, "index.mdx");
265
+ await ensureDirectory(rootFilePath);
266
+ await writeFile(rootFilePath, rootLines.join("\n"), "utf-8");
267
+ }
268
+ async function generateOverviewPage(name, info, allTypes) {
269
+ const nsDirectory = getNamespaceDirectory(info.namespace);
270
+ const typeFileSlug = toTypeFileSegment(info.namespace, name);
271
+ const typeRouteSlug = toTypeRouteSegment(info.namespace, name);
272
+ const filePath = join(getApiDocSettings().outputDirectory, nsDirectory, typeFileSlug, "index.mdx");
273
+ await ensureDirectory(filePath);
274
+ const displayName = getDisplayName(name, info);
275
+ const lines = renderFrontMatter({
276
+ description: info.description,
277
+ sidebarLabel: displayName,
278
+ signature: computeOverviewSignature(name, info),
279
+ slug: `api/${nsDirectory}/${typeRouteSlug}`,
280
+ title: displayName
281
+ });
282
+ lines.push(...getComponentImports(["ConstructorBlock", "ImportStatement", "MethodTable", "PropertyTable", "TypeSignature"]), "");
283
+ if (info.description) {
284
+ lines.push(renderMdxProse(info.description, allTypes, info.namespace), "");
285
+ }
286
+ if (info.remarks) {
287
+ const remarksBlock = renderMdxProse(info.remarks, allTypes, info.namespace);
288
+ lines.push(remarksBlock.split("\n").map((line) => line.length > 0 ? `> ${line}` : ">").join("\n"), "");
289
+ }
290
+ lines.push(`<ImportStatement text="${escapeJsxAttribute(getImportStatement(info))}" />`, "");
291
+ for (const example of info.examples) {
292
+ lines.push("**Example:**", "", renderExampleMdx(example, allTypes, info.namespace), "");
293
+ }
294
+ if (info.kind === "function") {
295
+ renderFunctionPage(lines, info, allTypes);
296
+ return { content: lines.join("\n"), filePath };
297
+ }
298
+ if (info.kind === "variable") {
299
+ renderVariablePage(lines, name, info, allTypes);
300
+ return { content: lines.join("\n"), filePath };
301
+ }
302
+ if (info.kind === "enum") {
303
+ renderEnumPage(lines, info, allTypes);
304
+ return { content: lines.join("\n"), filePath };
305
+ }
306
+ if (info.kind === "type") {
307
+ renderTypeAliasPage(lines, info, allTypes);
308
+ return { content: lines.join("\n"), filePath };
309
+ }
310
+ const typeParamsAttribute = info.typeParameters.length > 0 ? ` typeParams={${JSON.stringify(info.typeParameters)}}` : "";
311
+ const extendsAttribute = info.baseTypes.length > 0 ? ` extends={${JSON.stringify(info.baseTypes)}}` : "";
312
+ const implementsAttribute = info.implementsTypes.length > 0 ? ` implements={${JSON.stringify(info.implementsTypes)}}` : "";
313
+ lines.push(`<TypeSignature kind="${info.kind}" name="${name}"${typeParamsAttribute}${extendsAttribute}${implementsAttribute} />`, "");
314
+ if (info.baseTypes.length > 0) {
315
+ const linkedTypes = info.baseTypes.map((t) => linkBaseType(t, allTypes, info.namespace));
316
+ lines.push(`**Extends:** ${linkedTypes.join(", ")}`, "");
317
+ }
318
+ if (info.implementsTypes.length > 0) {
319
+ const linkedTypes = info.implementsTypes.map((t) => linkBaseType(t, allTypes, info.namespace));
320
+ lines.push(`**Implements:** ${linkedTypes.join(", ")}`, "");
321
+ }
322
+ renderConstructorMdx(lines, name, info, allTypes);
323
+ renderPropertyTableMdx(lines, info, allTypes);
324
+ renderMethodTableMdx(lines, info, allTypes);
325
+ return { content: lines.join("\n"), filePath };
326
+ }
327
+ async function generateSidebarJson(types) {
328
+ const root = buildSidebarTree(types);
329
+ const groups = [];
330
+ const topLevels = [...root.children].sort(([a], [b]) => a.localeCompare(b));
331
+ for (const [topLevel, child] of topLevels) {
332
+ groups.push(sidebarTreeToEntries(child, topLevel));
333
+ }
334
+ const wrappedSidebar = [{
335
+ collapsed: false,
336
+ items: groups,
337
+ label: "API reference"
338
+ }];
339
+ await writeFile(getApiDocSettings().sidebarFile, JSON.stringify(wrappedSidebar, null, JSON_INDENT), "utf-8");
340
+ console.warn(`Generated sidebar with ${String(groups.length)} top-level module groups`);
341
+ }
342
+ function renderConstructorMdx(lines, name, info, allTypes) {
343
+ const constructor = info.constructorInfo;
344
+ if (!constructor) {
345
+ return;
346
+ }
347
+ const ctorSig = `new ${name}${constructor.signature}`;
348
+ const ctorDesc = constructor.description ? ` description="${escapeJsxAttribute(markdownToHtml(resolveLinks(constructor.description, allTypes, info.namespace)))}"` : "";
349
+ lines.push(`<ConstructorBlock signature="${escapeJsxAttribute(ctorSig)}"${ctorDesc} />`, "");
350
+ }
351
+ function renderEnumPage(lines, info, allTypes) {
352
+ lines.push(`<TypeSignature kind="enum" name="${info.name}" />`, "");
353
+ if (info.enumMembers.length === 0) {
354
+ return;
355
+ }
356
+ lines.push("**Members:**", "", "| Member | Value | Description |", "| :-- | :-- | :-- |");
357
+ for (const member of info.enumMembers) {
358
+ const value = member.value ? `\`${escapeMarkdown(member.value)}\`` : "";
359
+ lines.push(`| \`${member.name}\` | ${value} | ${escapeMarkdown(resolveLinks(member.description, allTypes, info.namespace))} |`);
360
+ }
361
+ lines.push("");
362
+ }
363
+ function renderFrontMatter(frontMatter) {
364
+ return [
365
+ "---",
366
+ `title: "${escapeYaml(frontMatter.title)}"`,
367
+ `slug: "${frontMatter.slug}"`,
368
+ ...frontMatter.description ? [`description: "${escapeYaml(stripMarkdown(frontMatter.description))}"`] : [],
369
+ ...frontMatter.signature ? [`signature: "${escapeYaml(truncateSignature(frontMatter.signature))}"`] : [],
370
+ "editUrl: false",
371
+ "sidebar:",
372
+ ` label: "${escapeYaml(frontMatter.sidebarLabel)}"`,
373
+ "---",
374
+ ""
375
+ ];
376
+ }
377
+ function renderFunctionPage(lines, info, allTypes) {
378
+ const $function = info.methods[0];
379
+ if (!$function) {
380
+ return;
381
+ }
382
+ lines.push("**Signature:**", "", "```ts", `function ${$function.signature}: ${$function.returnType}`, "```", "");
383
+ if ($function.parameters.length > 0) {
384
+ lines.push("**Parameters:**", "", "| Parameter | Type | Description |", "| :-- | :-- | :-- |");
385
+ for (const parameter of $function.parameters) {
386
+ lines.push(
387
+ `| \`${parameter.name}\` | ${escapeMarkdown(escapeMdxAngleBrackets(renderTypeWithLinks(parameter.type, allTypes, info.name, info.namespace)))} | ${escapeMarkdown(resolveLinks(parameter.description, allTypes, info.namespace))} |`
388
+ );
389
+ }
390
+ lines.push("");
391
+ }
392
+ const returnDesc = $function.returnDescription ? ` \u2014 ${escapeMdxAngleBrackets(resolveLinks($function.returnDescription, allTypes, info.namespace))}` : "";
393
+ lines.push(`**Returns:** ${escapeMdxAngleBrackets(renderTypeWithLinks($function.returnType, allTypes, info.name, info.namespace))}${returnDesc}`, "");
394
+ for (const example of $function.examples) {
395
+ lines.push("**Example:**", "", renderExampleMdx(example, allTypes, info.namespace), "");
396
+ }
397
+ }
398
+ function renderMethodOverloadMdx(lines, overload, typeName, namespace, allTypes) {
399
+ const sig = `${overload.signature}: ${overload.returnType}`;
400
+ const staticAttribute = overload.isStatic ? " isStatic={true}" : "";
401
+ const descAttribute = overload.description ? ` description="${escapeJsxAttribute(markdownToHtml(resolveLinks(overload.description, allTypes, namespace)))}"` : "";
402
+ const remarksAttribute = overload.remarks ? ` remarks="${escapeJsxAttribute(markdownToHtml(resolveLinks(overload.remarks, allTypes, namespace)))}"` : "";
403
+ const sinceAttribute = overload.since ? ` since="${escapeJsxAttribute(overload.since)}"` : "";
404
+ const returnTypeAttribute = ` returnType="${escapeJsxAttribute(markdownToHtml(renderTypeWithLinks(overload.returnType, allTypes, typeName, namespace)))}"`;
405
+ const returnDescAttribute = overload.returnDescription ? ` returnDescription="${escapeJsxAttribute(markdownToHtml(resolveLinks(overload.returnDescription, allTypes, namespace)))}"` : "";
406
+ const examplesAttribute = overload.examples.length > 0 ? ` examples={${JSON.stringify(overload.examples)}}` : "";
407
+ const params = overload.parameters.map((p) => ({
408
+ description: markdownToHtml(p.description || (p.name.endsWith("?") ? "*(Optional)*" : "")),
409
+ name: p.name,
410
+ type: markdownToHtml(renderTypeWithLinks(p.type, allTypes, typeName, namespace))
411
+ }));
412
+ const paramsAttribute = params.length > 0 ? ` parameters={${JSON.stringify(params)}}` : "";
413
+ lines.push(
414
+ `<MemberDetail${staticAttribute} signature="${escapeJsxAttribute(sig)}"${descAttribute}${remarksAttribute}${sinceAttribute}${returnTypeAttribute}${returnDescAttribute}${paramsAttribute}${examplesAttribute} />`,
415
+ ""
416
+ );
417
+ }
418
+ function renderMethodTableMdx(lines, info, allTypes) {
419
+ const methods = [...info.methods].sort((a, b) => {
420
+ if (a.isStatic !== b.isStatic) {
421
+ return a.isStatic ? 1 : -1;
422
+ }
423
+ return a.name.localeCompare(b.name);
424
+ });
425
+ if (methods.length === 0) {
426
+ return;
427
+ }
428
+ lines.push("<MethodTable rows={[");
429
+ for (const method of methods) {
430
+ const desc = escapeJsString(markdownToHtml(resolveLinks(method.description, allTypes, info.namespace)));
431
+ const staticPrefix = method.isStatic ? "static " : "";
432
+ const shortParams = method.parameters.map((p, index) => {
433
+ return index === 0 && EVENT_METHODS.has(method.name) && (p.type.startsWith('"') || p.type.startsWith("'")) ? p.type.replaceAll('"', "'") : p.name;
434
+ }).join(", ");
435
+ const shortSig = `${staticPrefix}${method.name}(${shortParams})`;
436
+ const sig = escapeJsString(shortSig);
437
+ const slug = overloadRouteSegment(method.overloadKey);
438
+ const returnType = markdownToHtml(renderTypeWithLinks(method.returnType, allTypes, info.name, info.namespace));
439
+ const inheritedAttribute = method.inheritedFrom ? `, inheritedFrom: "${escapeJsString(markdownToHtml(typeLink(method.inheritedFrom, allTypes, info.namespace)))}"` : "";
440
+ const href = memberHref(slug, method.inheritedFrom, allTypes, info.namespace);
441
+ lines.push(
442
+ ` { signature: "${sig}", href: "${escapeJsString(href)}", returns: "${escapeJsString(returnType)}", description: "${desc}"${inheritedAttribute} },`
443
+ );
444
+ }
445
+ lines.push("]} />", "");
446
+ }
447
+ function renderPropertyTableMdx(lines, info, allTypes) {
448
+ const properties = info.properties;
449
+ if (properties.length === 0) {
450
+ return;
451
+ }
452
+ lines.push("<PropertyTable rows={[");
453
+ for (const property of properties) {
454
+ const desc = escapeJsString(markdownToHtml(resolveLinks(property.description, allTypes, info.namespace)));
455
+ const type = markdownToHtml(renderTypeWithLinks(property.type, allTypes, info.name, info.namespace));
456
+ const inheritedAttribute = property.inheritedFrom ? `, inheritedFrom: "${escapeJsString(markdownToHtml(typeLink(property.inheritedFrom, allTypes, info.namespace)))}"` : "";
457
+ const href = memberHref(memberRouteSegment(property.name), property.inheritedFrom, allTypes, info.namespace);
458
+ lines.push(
459
+ ` { name: "${escapeJsString(property.name)}", href: "${escapeJsString(href)}", type: "${escapeJsString(type)}", description: "${desc}"${inheritedAttribute} },`
460
+ );
461
+ }
462
+ lines.push("]} />", "");
463
+ }
464
+ function renderTypeAliasPage(lines, info, allTypes) {
465
+ const typeParamsAttribute = info.typeParameters.length > 0 ? ` typeParams={${JSON.stringify(info.typeParameters)}}` : "";
466
+ lines.push(`<TypeSignature kind="type" name="${info.name}"${typeParamsAttribute} />`, "");
467
+ const rhs = info.typeAliasText ?? "unknown";
468
+ lines.push(
469
+ "**Signature:**",
470
+ "",
471
+ "```ts",
472
+ `type ${getDisplayName(info.name, info)} = ${rhs}`,
473
+ "```",
474
+ "",
475
+ `**Type:** ${escapeMdxBraces(escapeMdxAngleBrackets(renderTypeWithLinks(rhs, allTypes, info.name, info.namespace)))}`,
476
+ ""
477
+ );
478
+ }
479
+ function renderVariablePage(lines, name, info, allTypes) {
480
+ const keyword = info.variableKeyword ?? "let";
481
+ const variableType = info.variableType ?? "unknown";
482
+ lines.push(
483
+ "**Signature:**",
484
+ "",
485
+ "```ts",
486
+ `${keyword} ${name}: ${variableType}`,
487
+ "```",
488
+ "",
489
+ `**Type:** ${escapeMdxBraces(escapeMdxAngleBrackets(renderTypeWithLinks(variableType, allTypes, name, info.namespace)))}`,
490
+ ""
491
+ );
492
+ }
493
+ function sidebarTreeToEntries(node, label) {
494
+ const items = [];
495
+ const sortedChildren = [...node.children].sort(([a], [b]) => a.localeCompare(b));
496
+ for (const [childName, child] of sortedChildren) {
497
+ items.push(sidebarTreeToEntries(child, childName));
498
+ }
499
+ if (node.types.length > 0) {
500
+ const { namespace } = ensureNonNullable(node.types[0]);
501
+ items.push({ label: "Overview", link: `/api/${namespace}/` });
502
+ const sortedTypes = [...node.types].sort((a, b) => a.name.localeCompare(b.name));
503
+ for (const t of sortedTypes) {
504
+ items.push({ label: t.name, link: `/api/${t.namespace}/${toTypeRouteSegment(t.namespace, t.name)}/` });
505
+ }
506
+ }
507
+ return { collapsed: true, items, label };
508
+ }
509
+ function getApiIndexIntro(namespaces) {
510
+ const { packageName } = getApiDocSettings();
511
+ const [exampleNamespace = "module"] = namespaces;
512
+ return `The complete API reference for \`${packageName}\`, generated from its TSDoc. Each module below maps to an import subpath (e.g. the \`${exampleNamespace}\` module is \`${packageName}/${exampleNamespace}\`).`;
513
+ }
514
+ function getComponentImports(componentNames) {
515
+ return componentNames.map((componentName) => `import ${componentName} from "${API_COMPONENTS_IMPORT_PREFIX}/${componentName}.astro";`);
516
+ }
517
+ function renderNamespaceTable(lines, heading, columnLabel, entries, allTypes, namespace) {
518
+ if (entries.length === 0) {
519
+ return;
520
+ }
521
+ const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
522
+ lines.push(`## ${heading}`, "", `| ${columnLabel} | Description |`, "| :-- | :-- |");
523
+ for (const entry of sorted) {
524
+ lines.push(`| [${entry.name}](./${toTypeRouteSegment(entry.namespace, entry.name)}/) | ${escapeMarkdown(resolveLinks(entry.description, allTypes, namespace))} |`);
525
+ }
526
+ lines.push("");
527
+ }
528
+ export {
529
+ appendBacklinksAndWrite,
530
+ buildBacklinksFromContent,
531
+ buildSidebarTree,
532
+ computeOverviewSignature,
533
+ generateMemberPages,
534
+ generateNamespaceIndexPages,
535
+ generateOverviewPage,
536
+ generateSidebarJson,
537
+ renderConstructorMdx,
538
+ renderEnumPage,
539
+ renderFrontMatter,
540
+ renderFunctionPage,
541
+ renderMethodOverloadMdx,
542
+ renderMethodTableMdx,
543
+ renderPropertyTableMdx,
544
+ renderTypeAliasPage,
545
+ renderVariablePage,
546
+ sidebarTreeToEntries
547
+ };
548
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb2NzLXNpdGUvYXBpLWRvYy1wYWdlLWdlbmVyYXRpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIE1EWCBwYWdlICsgc2lkZWJhciBlbWlzc2lvbjogcmVuZGVycyBtb2R1bGUgaW5kZXggcGFnZXMsIHBlci10eXBlIG92ZXJ2aWV3IHBhZ2VzLCBwZXItbWVtYmVyIHBhZ2VzLFxuICogYmFja2xpbmtzLCBhbmQgdGhlIFN0YXJsaWdodCBzaWRlYmFyIEpTT04uXG4gKi9cblxuaW1wb3J0IHsgZ2V0TWFuZGF0b3J5TmFtZWRHcm91cCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9yZWctZXhwJztcbmltcG9ydCB7IGVuc3VyZU5vbk51bGxhYmxlIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3R5cGUtZ3VhcmRzJztcbmltcG9ydCB7IHdyaXRlRmlsZSB9IGZyb20gJ25vZGU6ZnMvcHJvbWlzZXMnO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB0eXBlIHtcbiAgTWVtYmVySW5mbyxcbiAgUGFnZUNvbnRlbnQsXG4gIFBhZ2VGcm9udE1hdHRlcixcbiAgU2lkZWJhckVudHJ5LFxuICBTaWRlYmFyTGluayxcbiAgU2lkZWJhclRyZWVOb2RlLFxuICBUeXBlSW5mb1xufSBmcm9tICcuL2FwaS1kb2MtdHlwZXMudHMnO1xuXG5pbXBvcnQgeyBFVkVOVF9NRVRIT0RTIH0gZnJvbSAnLi9hcGktZG9jLWNvbnN0YW50cy50cyc7XG5pbXBvcnQge1xuICBsaW5rQmFzZVR5cGUsXG4gIG1hcmtkb3duVG9IdG1sLFxuICBtZW1iZXJIcmVmLFxuICByZW5kZXJFeGFtcGxlTWR4LFxuICByZW5kZXJNZHhQcm9zZSxcbiAgcmVuZGVyVHlwZVdpdGhMaW5rcyxcbiAgcmVzb2x2ZUxpbmtzLFxuICB0b1R5cGVGaWxlU2VnbWVudCxcbiAgdG9UeXBlUm91dGVTZWdtZW50LFxuICB0eXBlTGlua1xufSBmcm9tICcuL2FwaS1kb2MtbGluay1yZW5kZXJpbmcudHMnO1xuaW1wb3J0IHsgZ2V0QXBpRG9jU2V0dGluZ3MgfSBmcm9tICcuL2FwaS1kb2Mtc2V0dGluZ3MudHMnO1xuaW1wb3J0IHtcbiAgZW5zdXJlRGlyZWN0b3J5LFxuICBlc2NhcGVKc1N0cmluZyxcbiAgZXNjYXBlSnN4QXR0cmlidXRlLFxuICBlc2NhcGVNYXJrZG93bixcbiAgZXNjYXBlTWR4QW5nbGVCcmFja2V0cyxcbiAgZXNjYXBlTWR4QnJhY2VzLFxuICBlc2NhcGVZYW1sLFxuICBnZXREaXNwbGF5TmFtZSxcbiAgZ2V0SW1wb3J0U3RhdGVtZW50LFxuICBnZXROYW1lc3BhY2VEaXJlY3RvcnksXG4gIG1lbWJlclJvdXRlU2VnbWVudCxcbiAgbWVtYmVyU2x1ZyxcbiAgb3ZlcmxvYWRSb3V0ZVNlZ21lbnQsXG4gIG92ZXJsb2FkU2x1ZyxcbiAgc3RyaXBNYXJrZG93bixcbiAgdHJ1bmNhdGVTaWduYXR1cmVcbn0gZnJvbSAnLi9hcGktZG9jLXRleHQtdXRpbHMudHMnO1xuaW1wb3J0IHsgQVBJX0NPTVBPTkVOVFNfSU1QT1JUX1BSRUZJWCB9IGZyb20gJy4vZG9jcy1zaXRlLWFzc2V0cy50cyc7XG5cbmNvbnN0IEpTT05fSU5ERU5UID0gMjtcblxuLyoqXG4gKiBBcHBlbmQgYmFja2xpbmtzIHRvIG92ZXJ2aWV3IHBhZ2VzIGFuZCB3cml0ZSBhbGwgZmlsZXMuIEtleWVkIGJ5IHF1YWxpZmllZCBgJHtuYW1lc3BhY2V9IyR7bmFtZX1gLlxuICpcbiAqIEBwYXJhbSBwYWdlQ29udGVudHMgLSBFdmVyeSBvdmVydmlldyBwYWdlJ3MgY29udGVudCBhbmQgcGF0aCwga2V5ZWQgYnkgcXVhbGlmaWVkIGlkLlxuICogQHBhcmFtIGFsbFR5cGVzIC0gRXZlcnkgZG9jdW1lbnRlZCB0eXBlLCBrZXllZCBieSBgJHtuYW1lc3BhY2V9IyR7bmFtZX1gLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwZW5kQmFja2xpbmtzQW5kV3JpdGUoXG4gIHBhZ2VDb250ZW50czogTWFwPHN0cmluZywgUGFnZUNvbnRlbnQ+LFxuICBhbGxUeXBlczogTWFwPHN0cmluZywgVHlwZUluZm8+XG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgYmFja2xpbmtzID0gYnVpbGRCYWNrbGlua3NGcm9tQ29udGVudChwYWdlQ29udGVudHMsIGFsbFR5cGVzKTtcblxuICBmb3IgKGNvbnN0IFtrZXksIHsgY29udGVudCwgZmlsZVBhdGggfV0gb2YgcGFnZUNvbnRlbnRzKSB7XG4gICAgY29uc3QgdHlwZUJhY2tsaW5rcyA9IGJhY2tsaW5rcy5nZXQoa2V5KSA/PyBbXTtcbiAgICBjb25zdCBsaW5lcyA9IFtjb250ZW50XTtcbiAgICBpZiAodHlwZUJhY2tsaW5rcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBzb3J0ZWRCYWNrbGlua3MgPSBbLi4udHlwZUJhY2tsaW5rc10uc29ydCgoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpKTtcbiAgICAgIGxpbmVzLnB1c2goJycsICctLS0nLCAnJywgJyoqTGlua3MgdG8gdGhpcyBwYWdlOioqJywgJycpO1xuICAgICAgZm9yIChjb25zdCBibEtleSBvZiBzb3J0ZWRCYWNrbGlua3MpIHtcbiAgICAgICAgY29uc3QgYmxJbmZvID0gZW5zdXJlTm9uTnVsbGFibGUoYWxsVHlwZXMuZ2V0KGJsS2V5KSk7XG4gICAgICAgIGNvbnN0IGJsTnNEaXJlY3RvcnkgPSBnZXROYW1lc3BhY2VEaXJlY3RvcnkoYmxJbmZvLm5hbWVzcGFjZSk7XG4gICAgICAgIGxpbmVzLnB1c2goYC0gWyR7YmxJbmZvLm5hbWV9XSgke2dldEFwaURvY1NldHRpbmdzKCkuYmFzZVBhdGh9L2FwaS8ke2JsTnNEaXJlY3Rvcnl9LyR7dG9UeXBlUm91dGVTZWdtZW50KGJsSW5mby5uYW1lc3BhY2UsIGJsSW5mby5uYW1lKX0vKWApO1xuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIGxpbmVzLmpvaW4oJ1xcbicpLCAndXRmLTgnKTtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkIGJhY2tsaW5rcyBieSBzY2FubmluZyBnZW5lcmF0ZWQgcGFnZSBjb250ZW50IGZvciBpbnRlcm5hbCBBUEkgbGlua3MuIEtleWVkIGJ5IHF1YWxpZmllZCBpZC5cbiAqXG4gKiBAcGFyYW0gcGFnZUNvbnRlbnRzIC0gRXZlcnkgb3ZlcnZpZXcgcGFnZSdzIGNvbnRlbnQgYW5kIHBhdGgsIGtleWVkIGJ5IHF1YWxpZmllZCBpZC5cbiAqIEBwYXJhbSBhbGxUeXBlcyAtIEV2ZXJ5IGRvY3VtZW50ZWQgdHlwZSwga2V5ZWQgYnkgYCR7bmFtZXNwYWNlfSMke25hbWV9YC5cbiAqIEByZXR1cm5zIEVhY2ggcmVmZXJlbmNlZCB0eXBlJ3MgcXVhbGlmaWVkIGlkIG1hcHBlZCB0byB0aGUgaWRzIG9mIHRoZSBwYWdlcyBsaW5raW5nIHRvIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCYWNrbGlua3NGcm9tQ29udGVudChcbiAgcGFnZUNvbnRlbnRzOiBNYXA8c3RyaW5nLCBQYWdlQ29udGVudD4sXG4gIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz5cbik6IE1hcDxzdHJpbmcsIHN0cmluZ1tdPiB7XG4gIGNvbnN0IGJhY2tsaW5rcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgLy8gRW1pdHRlZCBVUkxzIGxvd2VyY2FzZSB0aGUgdHlwZSBzZWdtZW50IChzZWUgdG9Sb3V0ZVNlZ21lbnQpLCBzbyBtYXAgZWFjaCBsb3dlcmNhc2VkIHJvdXRlXG4gIC8vIGlkZW50aXR5IGJhY2sgdG8gaXRzIG9yaWdpbmFsIHF1YWxpZmllZCB0eXBlIGtleS5cbiAgY29uc3Qgcm91dGVLZXlUb1R5cGVLZXkgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBmb3IgKGNvbnN0IFt0eXBlS2V5LCBpbmZvXSBvZiBhbGxUeXBlcykge1xuICAgIHJvdXRlS2V5VG9UeXBlS2V5LnNldChgJHtnZXROYW1lc3BhY2VEaXJlY3RvcnkoaW5mby5uYW1lc3BhY2UpfSMke3RvVHlwZVJvdXRlU2VnbWVudChpbmZvLm5hbWVzcGFjZSwgaW5mby5uYW1lKX1gLCB0eXBlS2V5KTtcbiAgfVxuICBjb25zdCBlc2NhcGVkQmFzZSA9IGdldEFwaURvY1NldHRpbmdzKCkuYmFzZVBhdGgucmVwbGFjZUFsbCgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2csIFN0cmluZy5yYXdgXFwkJmApO1xuICBjb25zdCBsaW5rUGF0dGVybiA9IG5ldyBSZWdFeHAoYCR7ZXNjYXBlZEJhc2V9L2FwaS8oPzxwYXRoPig/OlthLXpBLVowLTlfQC1dKy8pKylgLCAnZycpO1xuICBmb3IgKGNvbnN0IFtzb3VyY2VLZXksIHsgY29udGVudCB9XSBvZiBwYWdlQ29udGVudHMpIHtcbiAgICBjb25zdCByZWZlcmVuY2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIGNvbnRlbnQubWF0Y2hBbGwobGlua1BhdHRlcm4pKSB7XG4gICAgICAvLyBUaGUgcGF0dGVybiByZXF1aXJlcyBhdCBsZWFzdCBvbmUgc2VnbWVudC5cbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gZ2V0TWFuZGF0b3J5TmFtZWRHcm91cChtYXRjaCwgJ3BhdGgnKS5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKTtcbiAgICAgIGNvbnN0IHR5cGVOYW1lID0gZW5zdXJlTm9uTnVsbGFibGUoc2VnbWVudHMuYXQoLTEpKTtcbiAgICAgIGNvbnN0IG5hbWVzcGFjZSA9IHNlZ21lbnRzLnNsaWNlKDAsIC0xKS5qb2luKCcvJyk7XG4gICAgICBjb25zdCByb3V0ZUtleSA9IGAke25hbWVzcGFjZX0jJHt0eXBlTmFtZX1gO1xuICAgICAgY29uc3QgcmVzb2x2ZWRLZXkgPSByb3V0ZUtleVRvVHlwZUtleS5nZXQocm91dGVLZXkpO1xuICAgICAgaWYgKHJlc29sdmVkS2V5ICE9PSB1bmRlZmluZWQgJiYgcmVzb2x2ZWRLZXkgIT09IHNvdXJjZUtleSkge1xuICAgICAgICByZWZlcmVuY2VkLmFkZChyZXNvbHZlZEtleSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByZWZlcmVuY2Ugb2YgcmVmZXJlbmNlZCkge1xuICAgICAgaWYgKCFiYWNrbGlua3MuaGFzKHJlZmVyZW5jZSkpIHtcbiAgICAgICAgYmFja2xpbmtzLnNldChyZWZlcmVuY2UsIFtdKTtcbiAgICAgIH1cbiAgICAgIGJhY2tsaW5rcy5nZXQocmVmZXJlbmNlKT8ucHVzaChzb3VyY2VLZXkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBiYWNrbGlua3M7XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBuYW1lc3BhY2UgdHJlZSB0aGUgc2lkZWJhciBpcyBnZW5lcmF0ZWQgZnJvbS5cbiAqXG4gKiBAcGFyYW0gdHlwZXMgLSBUaGUgZG9jdW1lbnRlZCB0eXBlcywga2V5ZWQgYnkgcXVhbGlmaWVkIGlkLlxuICogQHJldHVybnMgVGhlIHJvb3Qgb2YgdGhlIHRyZWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFNpZGViYXJUcmVlKHR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiBTaWRlYmFyVHJlZU5vZGUge1xuICBjb25zdCByb290OiBTaWRlYmFyVHJlZU5vZGUgPSB7IGNoaWxkcmVuOiBuZXcgTWFwKCksIHR5cGVzOiBbXSB9O1xuICBmb3IgKGNvbnN0IFssIGluZm9dIG9mIHR5cGVzKSB7XG4gICAgY29uc3QgcGFydHMgPSBpbmZvLm5hbWVzcGFjZS5zcGxpdCgnLycpO1xuICAgIGxldCBub2RlID0gcm9vdDtcbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIGxldCBjaGlsZCA9IG5vZGUuY2hpbGRyZW4uZ2V0KHBhcnQpO1xuICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICBjaGlsZCA9IHsgY2hpbGRyZW46IG5ldyBNYXAoKSwgdHlwZXM6IFtdIH07XG4gICAgICAgIG5vZGUuY2hpbGRyZW4uc2V0KHBhcnQsIGNoaWxkKTtcbiAgICAgIH1cbiAgICAgIG5vZGUgPSBjaGlsZDtcbiAgICB9XG4gICAgbm9kZS50eXBlcy5wdXNoKGluZm8pO1xuICB9XG4gIHJldHVybiByb290O1xufVxuXG4vKipcbiAqIFRoZSByYXcgY29kZSBzaWduYXR1cmUgc2hvd24gb24gYSB0eXBlLW92ZXJ2aWV3IHBhZ2UncyBPRyBjYXJkLCBmb3IgdGhlIGtpbmRzIHRoYXQgcmVuZGVyIGEgc2luZ2xlXG4gKiBzaWduYXR1cmUgbGluZSAoZnVuY3Rpb24gLyB0eXBlIGFsaWFzIC8gdmFyaWFibGUpLiBDbGFzc2VzLCBpbnRlcmZhY2VzIGFuZCBlbnVtcyByZW5kZXIgbWVtYmVyXG4gKiB0YWJsZXMgaW5zdGVhZCwgc28gdGhleSBnZXQgbm8gc2lnbmF0dXJlIGJsb2NrLlxuICpcbiAqIEBwYXJhbSBuYW1lIC0gVGhlIHR5cGUncyBuYW1lLlxuICogQHBhcmFtIGluZm8gLSBUaGUgZG9jdW1lbnRlZCB0eXBlLlxuICogQHJldHVybnMgVGhlIHNpZ25hdHVyZSwgb3IgYHVuZGVmaW5lZGAgZm9yIGEga2luZCB0aGF0IHJlbmRlcnMgbWVtYmVyIHRhYmxlcyBpbnN0ZWFkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZU92ZXJ2aWV3U2lnbmF0dXJlKG5hbWU6IHN0cmluZywgaW5mbzogVHlwZUluZm8pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoaW5mby5raW5kID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgJGZ1bmN0aW9uID0gaW5mby5tZXRob2RzWzBdO1xuICAgIHJldHVybiAkZnVuY3Rpb24gPyBgZnVuY3Rpb24gJHskZnVuY3Rpb24uc2lnbmF0dXJlfTogJHskZnVuY3Rpb24ucmV0dXJuVHlwZX1gIDogdW5kZWZpbmVkO1xuICB9XG4gIGlmIChpbmZvLmtpbmQgPT09ICd0eXBlJykge1xuICAgIHJldHVybiBgdHlwZSAke2dldERpc3BsYXlOYW1lKGluZm8ubmFtZSwgaW5mbyl9ID0gJHtpbmZvLnR5cGVBbGlhc1RleHQgPz8gJ3Vua25vd24nfWA7XG4gIH1cbiAgcmV0dXJuIGluZm8ua2luZCA9PT0gJ3ZhcmlhYmxlJyA/IGAke2luZm8udmFyaWFibGVLZXl3b3JkID8/ICdsZXQnfSAke25hbWV9OiAke2luZm8udmFyaWFibGVUeXBlID8/ICd1bmtub3duJ31gIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdyaXRlcyBvbmUgcGFnZSBwZXIgb3duIHByb3BlcnR5IGFuZCBwZXIgb3duIG1ldGhvZCBvdmVybG9hZCBrZXkgb2YgYSBjbGFzcyBvciBpbnRlcmZhY2UuXG4gKlxuICogQHBhcmFtIG5hbWUgLSBUaGUgdHlwZSdzIG5hbWUuXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBkb2N1bWVudGVkIHR5cGUuXG4gKiBAcGFyYW0gYWxsVHlwZXMgLSBFdmVyeSBkb2N1bWVudGVkIHR5cGUsIGtleWVkIGJ5IGAke25hbWVzcGFjZX0jJHtuYW1lfWAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZU1lbWJlclBhZ2VzKG5hbWU6IHN0cmluZywgaW5mbzogVHlwZUluZm8sIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgbnNEaXJlY3RvcnkgPSBnZXROYW1lc3BhY2VEaXJlY3RvcnkoaW5mby5uYW1lc3BhY2UpO1xuICBjb25zdCB0eXBlRmlsZURpcmVjdG9yeSA9IHRvVHlwZUZpbGVTZWdtZW50KGluZm8ubmFtZXNwYWNlLCBuYW1lKTtcbiAgY29uc3QgdHlwZVJvdXRlRGlyZWN0b3J5ID0gdG9UeXBlUm91dGVTZWdtZW50KGluZm8ubmFtZXNwYWNlLCBuYW1lKTtcbiAgY29uc3QgY29tcG9uZW50SW1wb3J0cyA9IGdldENvbXBvbmVudEltcG9ydHMoWydNZW1iZXJEZXRhaWwnXSk7XG5cbiAgLy8gUHJvcGVydHkgcGFnZXMgKHNraXAgaW5oZXJpdGVkIOKAlCB0aGV5IGxpdmUgb24gdGhlIHBhcmVudCB0eXBlKVxuICBjb25zdCBwcm9wZXJ0aWVzID0gaW5mby5wcm9wZXJ0aWVzLmZpbHRlcigocCkgPT4gIXAuaW5oZXJpdGVkRnJvbSk7XG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydGllcykge1xuICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbihnZXRBcGlEb2NTZXR0aW5ncygpLm91dHB1dERpcmVjdG9yeSwgbnNEaXJlY3RvcnksIHR5cGVGaWxlRGlyZWN0b3J5LCBgJHttZW1iZXJTbHVnKHByb3BlcnR5Lm5hbWUpfS5tZHhgKTtcbiAgICBhd2FpdCBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGgpO1xuXG4gICAgY29uc3QgcHJvcGVydHlUaXRsZSA9IGAke25hbWV9LiR7cHJvcGVydHkubmFtZX1gO1xuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IHJlbmRlckZyb250TWF0dGVyKHtcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wZXJ0eS5kZXNjcmlwdGlvbixcbiAgICAgIHNpZGViYXJMYWJlbDogcHJvcGVydHlUaXRsZSxcbiAgICAgIHNpZ25hdHVyZTogYCR7cHJvcGVydHkuc2lnbmF0dXJlfTogJHtwcm9wZXJ0eS50eXBlfWAsXG4gICAgICBzbHVnOiBgYXBpLyR7bnNEaXJlY3Rvcnl9LyR7dHlwZVJvdXRlRGlyZWN0b3J5fS8ke21lbWJlclJvdXRlU2VnbWVudChwcm9wZXJ0eS5uYW1lKX1gLFxuICAgICAgdGl0bGU6IHByb3BlcnR5VGl0bGVcbiAgICB9KTtcbiAgICBsaW5lcy5wdXNoKFxuICAgICAgLi4uY29tcG9uZW50SW1wb3J0cyxcbiAgICAgICcnLFxuICAgICAgLy8gQnJlYWRjcnVtYlxuICAgICAgYFske25hbWV9XSgke2dldEFwaURvY1NldHRpbmdzKCkuYmFzZVBhdGh9L2FwaS8ke25zRGlyZWN0b3J5fS8ke3R5cGVSb3V0ZURpcmVjdG9yeX0vKSDigLogJHtwcm9wZXJ0eS5uYW1lfWAsXG4gICAgICAnJ1xuICAgICk7XG5cbiAgICBjb25zdCBzdGF0aWNBdHRyaWJ1dGUgPSBwcm9wZXJ0eS5pc1N0YXRpYyA/ICcgaXNTdGF0aWM9e3RydWV9JyA6ICcnO1xuICAgIGNvbnN0IHR5cGVBdHRyaWJ1dGUgPSBgIHR5cGU9XCIke2VzY2FwZUpzeEF0dHJpYnV0ZShtYXJrZG93blRvSHRtbChyZW5kZXJUeXBlV2l0aExpbmtzKHByb3BlcnR5LnR5cGUsIGFsbFR5cGVzLCBuYW1lLCBpbmZvLm5hbWVzcGFjZSkpKX1cImA7XG4gICAgY29uc3QgZGVzY0F0dHJpYnV0ZSA9IHByb3BlcnR5LmRlc2NyaXB0aW9uID8gYCBkZXNjcmlwdGlvbj1cIiR7ZXNjYXBlSnN4QXR0cmlidXRlKG1hcmtkb3duVG9IdG1sKHJlc29sdmVMaW5rcyhwcm9wZXJ0eS5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIGluZm8ubmFtZXNwYWNlKSkpfVwiYCA6ICcnO1xuICAgIGNvbnN0IHJlbWFya3NBdHRyaWJ1dGUgPSBwcm9wZXJ0eS5yZW1hcmtzID8gYCByZW1hcmtzPVwiJHtlc2NhcGVKc3hBdHRyaWJ1dGUobWFya2Rvd25Ub0h0bWwocmVzb2x2ZUxpbmtzKHByb3BlcnR5LnJlbWFya3MsIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSkpKX1cImAgOiAnJztcbiAgICBjb25zdCBzaW5jZUF0dHJpYnV0ZSA9IHByb3BlcnR5LnNpbmNlID8gYCBzaW5jZT1cIiR7ZXNjYXBlSnN4QXR0cmlidXRlKHByb3BlcnR5LnNpbmNlKX1cImAgOiAnJztcbiAgICBjb25zdCBleGFtcGxlc0F0dHJpYnV0ZSA9IHByb3BlcnR5LmV4YW1wbGVzLmxlbmd0aCA+IDAgPyBgIGV4YW1wbGVzPXske0pTT04uc3RyaW5naWZ5KHByb3BlcnR5LmV4YW1wbGVzKX19YCA6ICcnO1xuXG4gICAgbGluZXMucHVzaChgPE1lbWJlckRldGFpbCR7c3RhdGljQXR0cmlidXRlfSR7dHlwZUF0dHJpYnV0ZX0ke2Rlc2NBdHRyaWJ1dGV9JHtyZW1hcmtzQXR0cmlidXRlfSR7c2luY2VBdHRyaWJ1dGV9JHtleGFtcGxlc0F0dHJpYnV0ZX0gLz5gLCAnJyk7XG5cbiAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIGxpbmVzLmpvaW4oJ1xcbicpLCAndXRmLTgnKTtcbiAgfVxuXG4gIC8vIE1ldGhvZCBwYWdlcyDigJQgZWFjaCBvdmVybG9hZCBrZXkgZ2V0cyBpdHMgb3duIHBhZ2UgKHNraXAgaW5oZXJpdGVkKVxuICBjb25zdCBtZXRob2RzID0gaW5mby5tZXRob2RzLmZpbHRlcigobSkgPT4gIW0uaW5oZXJpdGVkRnJvbSk7XG4gIGNvbnN0IG92ZXJsb2FkR3JvdXBzID0gbmV3IE1hcDxzdHJpbmcsIE1lbWJlckluZm9bXT4oKTtcbiAgZm9yIChjb25zdCBtZXRob2Qgb2YgbWV0aG9kcykge1xuICAgIGNvbnN0IGtleSA9IG1ldGhvZC5vdmVybG9hZEtleTtcbiAgICBpZiAoIW92ZXJsb2FkR3JvdXBzLmhhcyhrZXkpKSB7XG4gICAgICBvdmVybG9hZEdyb3Vwcy5zZXQoa2V5LCBbXSk7XG4gICAgfVxuICAgIG92ZXJsb2FkR3JvdXBzLmdldChrZXkpPy5wdXNoKG1ldGhvZCk7XG4gIH1cblxuICBmb3IgKGNvbnN0IFtvdmVybG9hZEtleSwgb3ZlcmxvYWRzXSBvZiBvdmVybG9hZEdyb3Vwcykge1xuICAgIGNvbnN0IGZpbGVTbHVnID0gb3ZlcmxvYWRTbHVnKG92ZXJsb2FkS2V5KTtcbiAgICBjb25zdCBmaWxlUGF0aCA9IGpvaW4oZ2V0QXBpRG9jU2V0dGluZ3MoKS5vdXRwdXREaXJlY3RvcnksIG5zRGlyZWN0b3J5LCB0eXBlRmlsZURpcmVjdG9yeSwgYCR7ZmlsZVNsdWd9Lm1keGApO1xuICAgIGF3YWl0IGVuc3VyZURpcmVjdG9yeShmaWxlUGF0aCk7XG5cbiAgICBjb25zdCBkaXNwbGF5TmFtZSA9IGAke25hbWV9LiR7b3ZlcmxvYWRLZXl9IG1ldGhvZGA7XG4gICAgLy8gQSBncm91cCBpcyBjcmVhdGVkIGJ5IGl0cyBmaXJzdCBvdmVybG9hZC5cbiAgICBjb25zdCBmaXJzdE92ZXJsb2FkID0gZW5zdXJlTm9uTnVsbGFibGUob3ZlcmxvYWRzWzBdKTtcblxuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IHJlbmRlckZyb250TWF0dGVyKHtcbiAgICAgIGRlc2NyaXB0aW9uOiBmaXJzdE92ZXJsb2FkLmRlc2NyaXB0aW9uLFxuICAgICAgc2lkZWJhckxhYmVsOiBgJHtuYW1lfS4ke292ZXJsb2FkS2V5fWAsXG4gICAgICBzaWduYXR1cmU6IGAke2ZpcnN0T3ZlcmxvYWQuc2lnbmF0dXJlfTogJHtmaXJzdE92ZXJsb2FkLnJldHVyblR5cGV9YCxcbiAgICAgIHNsdWc6IGBhcGkvJHtuc0RpcmVjdG9yeX0vJHt0eXBlUm91dGVEaXJlY3Rvcnl9LyR7b3ZlcmxvYWRSb3V0ZVNlZ21lbnQob3ZlcmxvYWRLZXkpfWAsXG4gICAgICB0aXRsZTogZGlzcGxheU5hbWVcbiAgICB9KTtcbiAgICBsaW5lcy5wdXNoKFxuICAgICAgLi4uY29tcG9uZW50SW1wb3J0cyxcbiAgICAgICcnLFxuICAgICAgLy8gQnJlYWRjcnVtYlxuICAgICAgYFske25hbWV9XSgke2dldEFwaURvY1NldHRpbmdzKCkuYmFzZVBhdGh9L2FwaS8ke25zRGlyZWN0b3J5fS8ke3R5cGVSb3V0ZURpcmVjdG9yeX0vKSDigLogJHtvdmVybG9hZEtleX1gLFxuICAgICAgJydcbiAgICApO1xuXG4gICAgZm9yIChjb25zdCBvdmVybG9hZCBvZiBvdmVybG9hZHMpIHtcbiAgICAgIHJlbmRlck1ldGhvZE92ZXJsb2FkTWR4KGxpbmVzLCBvdmVybG9hZCwgbmFtZSwgaW5mby5uYW1lc3BhY2UsIGFsbFR5cGVzKTtcbiAgICAgIGlmIChvdmVybG9hZHMubGVuZ3RoID4gMSkge1xuICAgICAgICBsaW5lcy5wdXNoKCctLS0nLCAnJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgd3JpdGVGaWxlKGZpbGVQYXRoLCBsaW5lcy5qb2luKCdcXG4nKSwgJ3V0Zi04Jyk7XG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZXMgZWFjaCBtb2R1bGUncyBpbmRleCBwYWdlIGFuZCB0aGUgcm9vdCBBUEkgaW5kZXguXG4gKlxuICogQHBhcmFtIHR5cGVzIC0gVGhlIGRvY3VtZW50ZWQgdHlwZXMsIGtleWVkIGJ5IHF1YWxpZmllZCBpZC5cbiAqIEBwYXJhbSBhbGxUeXBlcyAtIEV2ZXJ5IGRvY3VtZW50ZWQgdHlwZSwga2V5ZWQgYnkgYCR7bmFtZXNwYWNlfSMke25hbWV9YC5cbiAqIEBwYXJhbSBtb2R1bGVPdmVydmlld3MgLSBFYWNoIG5hbWVzcGFjZSdzIGBAZmlsZWAgb3ZlcnZpZXcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZU5hbWVzcGFjZUluZGV4UGFnZXMoXG4gIHR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4sXG4gIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4sXG4gIG1vZHVsZU92ZXJ2aWV3czogTWFwPHN0cmluZywgc3RyaW5nPlxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IG5hbWVzcGFjZXMgPSBuZXcgTWFwPHN0cmluZywgVHlwZUluZm9bXT4oKTtcbiAgZm9yIChjb25zdCBbLCBpbmZvXSBvZiB0eXBlcykge1xuICAgIGlmICghbmFtZXNwYWNlcy5oYXMoaW5mby5uYW1lc3BhY2UpKSB7XG4gICAgICBuYW1lc3BhY2VzLnNldChpbmZvLm5hbWVzcGFjZSwgW10pO1xuICAgIH1cbiAgICBuYW1lc3BhY2VzLmdldChpbmZvLm5hbWVzcGFjZSk/LnB1c2goaW5mbyk7XG4gIH1cblxuICBmb3IgKGNvbnN0IFtuYW1lc3BhY2UsIG5zVHlwZXNdIG9mIG5hbWVzcGFjZXMpIHtcbiAgICBjb25zdCBuc0RpcmVjdG9yeSA9IGdldE5hbWVzcGFjZURpcmVjdG9yeShuYW1lc3BhY2UpO1xuICAgIGNvbnN0IGZpbGVQYXRoID0gam9pbihnZXRBcGlEb2NTZXR0aW5ncygpLm91dHB1dERpcmVjdG9yeSwgbnNEaXJlY3RvcnksICdpbmRleC5tZHgnKTtcbiAgICBhd2FpdCBlbnN1cmVEaXJlY3RvcnkoZmlsZVBhdGgpO1xuXG4gICAgLy8gVGhlIG1vZHVsZSdzIGBAZmlsZWAgdGV4dCBkb3VibGVzIGFzIGl0cyBkZXNjcmlwdGlvbi5cbiAgICAvLyBXaXRob3V0IGl0IHRoZSBtb2R1bGUgY2FyZCB3YXMgdGl0bGUtb25seSB3aGlsZSBldmVyeSBtZW1iZXIgY2FyZCB1bmRlciBpdCBjYXJyaWVkIG9uZS5cbiAgICBjb25zdCBvdmVydmlldyA9IG1vZHVsZU92ZXJ2aWV3cy5nZXQobmFtZXNwYWNlKTtcbiAgICBjb25zdCBsaW5lczogc3RyaW5nW10gPSByZW5kZXJGcm9udE1hdHRlcih7XG4gICAgICBkZXNjcmlwdGlvbjogb3ZlcnZpZXcsXG4gICAgICBzaWRlYmFyTGFiZWw6IG5hbWVzcGFjZSxcbiAgICAgIHNsdWc6IGBhcGkvJHtuc0RpcmVjdG9yeX1gLFxuICAgICAgdGl0bGU6IG5hbWVzcGFjZVxuICAgIH0pO1xuXG4gICAgLy8gTW9kdWxlIEBmaWxlIG92ZXJ2aWV3IHRleHRcbiAgICBpZiAob3ZlcnZpZXcpIHtcbiAgICAgIGxpbmVzLnB1c2gocmVuZGVyTWR4UHJvc2Uob3ZlcnZpZXcsIGFsbFR5cGVzLCBuYW1lc3BhY2UpLCAnJyk7XG4gICAgfVxuXG4gICAgcmVuZGVyTmFtZXNwYWNlVGFibGUobGluZXMsICdDbGFzc2VzJywgJ0NsYXNzJywgbnNUeXBlcy5maWx0ZXIoKHQpID0+IHQua2luZCA9PT0gJ2NsYXNzJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuICAgIHJlbmRlck5hbWVzcGFjZVRhYmxlKGxpbmVzLCAnSW50ZXJmYWNlcycsICdJbnRlcmZhY2UnLCBuc1R5cGVzLmZpbHRlcigodCkgPT4gdC5raW5kID09PSAnaW50ZXJmYWNlJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuICAgIHJlbmRlck5hbWVzcGFjZVRhYmxlKGxpbmVzLCAnRnVuY3Rpb25zJywgJ0Z1bmN0aW9uJywgbnNUeXBlcy5maWx0ZXIoKHQpID0+IHQua2luZCA9PT0gJ2Z1bmN0aW9uJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuICAgIHJlbmRlck5hbWVzcGFjZVRhYmxlKGxpbmVzLCAnVHlwZXMnLCAnVHlwZScsIG5zVHlwZXMuZmlsdGVyKCh0KSA9PiB0LmtpbmQgPT09ICd0eXBlJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuICAgIHJlbmRlck5hbWVzcGFjZVRhYmxlKGxpbmVzLCAnRW51bXMnLCAnRW51bScsIG5zVHlwZXMuZmlsdGVyKCh0KSA9PiB0LmtpbmQgPT09ICdlbnVtJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuICAgIHJlbmRlck5hbWVzcGFjZVRhYmxlKGxpbmVzLCAnVmFyaWFibGVzJywgJ1ZhcmlhYmxlJywgbnNUeXBlcy5maWx0ZXIoKHQpID0+IHQua2luZCA9PT0gJ3ZhcmlhYmxlJyksIGFsbFR5cGVzLCBuYW1lc3BhY2UpO1xuXG4gICAgYXdhaXQgd3JpdGVGaWxlKGZpbGVQYXRoLCBsaW5lcy5qb2luKCdcXG4nKSwgJ3V0Zi04Jyk7XG4gIH1cblxuICAvLyBSb290IEFQSSBpbmRleCBwYWdlIGxpc3RpbmcgZXZlcnkgbW9kdWxlLlxuICBjb25zdCBzb3J0ZWROYW1lc3BhY2VzID0gWy4uLm5hbWVzcGFjZXMua2V5cygpXS5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpO1xuICBjb25zdCBhcGlJbmRleEludHJvID0gZ2V0QXBpSW5kZXhJbnRybyhzb3J0ZWROYW1lc3BhY2VzKTtcbiAgY29uc3Qgcm9vdExpbmVzOiBzdHJpbmdbXSA9IHJlbmRlckZyb250TWF0dGVyKHtcbiAgICBkZXNjcmlwdGlvbjogYXBpSW5kZXhJbnRybyxcbiAgICBzaWRlYmFyTGFiZWw6ICdPdmVydmlldycsXG4gICAgc2x1ZzogJ2FwaScsXG4gICAgdGl0bGU6ICdBUEkgcmVmZXJlbmNlJ1xuICB9KTtcbiAgcm9vdExpbmVzLnB1c2goYXBpSW5kZXhJbnRybywgJycsICcjIyBNb2R1bGVzJywgJycpO1xuICBmb3IgKGNvbnN0IG5hbWVzcGFjZSBvZiBzb3J0ZWROYW1lc3BhY2VzKSB7XG4gICAgcm9vdExpbmVzLnB1c2goYC0gWyR7bmFtZXNwYWNlfV0oJHtnZXRBcGlEb2NTZXR0aW5ncygpLmJhc2VQYXRofS9hcGkvJHtnZXROYW1lc3BhY2VEaXJlY3RvcnkobmFtZXNwYWNlKX0vKWApO1xuICB9XG4gIHJvb3RMaW5lcy5wdXNoKCcnKTtcbiAgY29uc3Qgcm9vdEZpbGVQYXRoID0gam9pbihnZXRBcGlEb2NTZXR0aW5ncygpLm91dHB1dERpcmVjdG9yeSwgJ2luZGV4Lm1keCcpO1xuICBhd2FpdCBlbnN1cmVEaXJlY3Rvcnkocm9vdEZpbGVQYXRoKTtcbiAgYXdhaXQgd3JpdGVGaWxlKHJvb3RGaWxlUGF0aCwgcm9vdExpbmVzLmpvaW4oJ1xcbicpLCAndXRmLTgnKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgdHlwZSdzIG92ZXJ2aWV3IHBhZ2UuXG4gKlxuICogQHBhcmFtIG5hbWUgLSBUaGUgdHlwZSdzIG5hbWUuXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBkb2N1bWVudGVkIHR5cGUuXG4gKiBAcGFyYW0gYWxsVHlwZXMgLSBFdmVyeSBkb2N1bWVudGVkIHR5cGUsIGtleWVkIGJ5IGAke25hbWVzcGFjZX0jJHtuYW1lfWAuXG4gKiBAcmV0dXJucyBUaGUgcGFnZSdzIGNvbnRlbnQsIGJlZm9yZSBiYWNrbGlua3MsIGFuZCB0aGUgcGF0aCBpdCBpcyB3cml0dGVuIHRvLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVPdmVydmlld1BhZ2UobmFtZTogc3RyaW5nLCBpbmZvOiBUeXBlSW5mbywgYWxsVHlwZXM6IE1hcDxzdHJpbmcsIFR5cGVJbmZvPik6IFByb21pc2U8UGFnZUNvbnRlbnQ+IHtcbiAgY29uc3QgbnNEaXJlY3RvcnkgPSBnZXROYW1lc3BhY2VEaXJlY3RvcnkoaW5mby5uYW1lc3BhY2UpO1xuICBjb25zdCB0eXBlRmlsZVNsdWcgPSB0b1R5cGVGaWxlU2VnbWVudChpbmZvLm5hbWVzcGFjZSwgbmFtZSk7XG4gIGNvbnN0IHR5cGVSb3V0ZVNsdWcgPSB0b1R5cGVSb3V0ZVNlZ21lbnQoaW5mby5uYW1lc3BhY2UsIG5hbWUpO1xuICBjb25zdCBmaWxlUGF0aCA9IGpvaW4oZ2V0QXBpRG9jU2V0dGluZ3MoKS5vdXRwdXREaXJlY3RvcnksIG5zRGlyZWN0b3J5LCB0eXBlRmlsZVNsdWcsICdpbmRleC5tZHgnKTtcbiAgYXdhaXQgZW5zdXJlRGlyZWN0b3J5KGZpbGVQYXRoKTtcblxuICAvLyBGcm9udG1hdHRlclxuICBjb25zdCBkaXNwbGF5TmFtZSA9IGdldERpc3BsYXlOYW1lKG5hbWUsIGluZm8pO1xuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSByZW5kZXJGcm9udE1hdHRlcih7XG4gICAgZGVzY3JpcHRpb246IGluZm8uZGVzY3JpcHRpb24sXG4gICAgc2lkZWJhckxhYmVsOiBkaXNwbGF5TmFtZSxcbiAgICBzaWduYXR1cmU6IGNvbXB1dGVPdmVydmlld1NpZ25hdHVyZShuYW1lLCBpbmZvKSxcbiAgICBzbHVnOiBgYXBpLyR7bnNEaXJlY3Rvcnl9LyR7dHlwZVJvdXRlU2x1Z31gLFxuICAgIHRpdGxlOiBkaXNwbGF5TmFtZVxuICB9KTtcblxuICAvLyBDb21wb25lbnQgaW1wb3J0cyDigJQgY29tcHV0ZSByZWxhdGl2ZSBwYXRoIGZyb20gZ2VuZXJhdGVkIHBhZ2UgdG8gY29tcG9uZW50c1xuICBsaW5lcy5wdXNoKC4uLmdldENvbXBvbmVudEltcG9ydHMoWydDb25zdHJ1Y3RvckJsb2NrJywgJ0ltcG9ydFN0YXRlbWVudCcsICdNZXRob2RUYWJsZScsICdQcm9wZXJ0eVRhYmxlJywgJ1R5cGVTaWduYXR1cmUnXSksICcnKTtcblxuICAvLyBEZXNjcmlwdGlvblxuICBpZiAoaW5mby5kZXNjcmlwdGlvbikge1xuICAgIGxpbmVzLnB1c2gocmVuZGVyTWR4UHJvc2UoaW5mby5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIGluZm8ubmFtZXNwYWNlKSwgJycpO1xuICB9XG5cbiAgLy8gUmVtYXJrc1xuICBpZiAoaW5mby5yZW1hcmtzKSB7XG4gICAgY29uc3QgcmVtYXJrc0Jsb2NrID0gcmVuZGVyTWR4UHJvc2UoaW5mby5yZW1hcmtzLCBhbGxUeXBlcywgaW5mby5uYW1lc3BhY2UpO1xuICAgIGxpbmVzLnB1c2gocmVtYXJrc0Jsb2NrLnNwbGl0KCdcXG4nKS5tYXAoKGxpbmUpID0+IChsaW5lLmxlbmd0aCA+IDAgPyBgPiAke2xpbmV9YCA6ICc+JykpLmpvaW4oJ1xcbicpLCAnJyk7XG4gIH1cblxuICAvLyBJbXBvcnQgc3RhdGVtZW50XG4gIGxpbmVzLnB1c2goYDxJbXBvcnRTdGF0ZW1lbnQgdGV4dD1cIiR7ZXNjYXBlSnN4QXR0cmlidXRlKGdldEltcG9ydFN0YXRlbWVudChpbmZvKSl9XCIgLz5gLCAnJyk7XG5cbiAgLy8gRXhhbXBsZXNcbiAgZm9yIChjb25zdCBleGFtcGxlIG9mIGluZm8uZXhhbXBsZXMpIHtcbiAgICBsaW5lcy5wdXNoKCcqKkV4YW1wbGU6KionLCAnJywgcmVuZGVyRXhhbXBsZU1keChleGFtcGxlLCBhbGxUeXBlcywgaW5mby5uYW1lc3BhY2UpLCAnJyk7XG4gIH1cblxuICAvLyBGdW5jdGlvbnMgcmVuZGVyIGxpa2UgbWV0aG9kIGRldGFpbCBwYWdlcyDigJQgc2lnbmF0dXJlLCBwYXJhbXMsIHJldHVybnNcbiAgaWYgKGluZm8ua2luZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJlbmRlckZ1bmN0aW9uUGFnZShsaW5lcywgaW5mbywgYWxsVHlwZXMpO1xuICAgIHJldHVybiB7IGNvbnRlbnQ6IGxpbmVzLmpvaW4oJ1xcbicpLCBmaWxlUGF0aCB9O1xuICB9XG5cbiAgLy8gVmFyaWFibGVzIHJlbmRlciB3aXRoIGRlY2xhcmF0aW9uIGtleXdvcmQgYW5kIHR5cGVcbiAgaWYgKGluZm8ua2luZCA9PT0gJ3ZhcmlhYmxlJykge1xuICAgIHJlbmRlclZhcmlhYmxlUGFnZShsaW5lcywgbmFtZSwgaW5mbywgYWxsVHlwZXMpO1xuICAgIHJldHVybiB7IGNvbnRlbnQ6IGxpbmVzLmpvaW4oJ1xcbicpLCBmaWxlUGF0aCB9O1xuICB9XG5cbiAgLy8gRW51bXMgcmVuZGVyIHRoZWlyIG1lbWJlcnMgbGlzdFxuICBpZiAoaW5mby5raW5kID09PSAnZW51bScpIHtcbiAgICByZW5kZXJFbnVtUGFnZShsaW5lcywgaW5mbywgYWxsVHlwZXMpO1xuICAgIHJldHVybiB7IGNvbnRlbnQ6IGxpbmVzLmpvaW4oJ1xcbicpLCBmaWxlUGF0aCB9O1xuICB9XG5cbiAgLy8gVHlwZSBhbGlhc2VzIHJlbmRlciB0aGVpciByaWdodC1oYW5kLXNpZGUgc2lnbmF0dXJlXG4gIGlmIChpbmZvLmtpbmQgPT09ICd0eXBlJykge1xuICAgIHJlbmRlclR5cGVBbGlhc1BhZ2UobGluZXMsIGluZm8sIGFsbFR5cGVzKTtcbiAgICByZXR1cm4geyBjb250ZW50OiBsaW5lcy5qb2luKCdcXG4nKSwgZmlsZVBhdGggfTtcbiAgfVxuXG4gIC8vIENsYXNzZXMgLyBpbnRlcmZhY2VzOiBzaWduYXR1cmUgKyBleHRlbmRzL2ltcGxlbWVudHMgKyBjb25zdHJ1Y3RvciArIG1lbWJlciB0YWJsZXNcbiAgY29uc3QgdHlwZVBhcmFtc0F0dHJpYnV0ZSA9IGluZm8udHlwZVBhcmFtZXRlcnMubGVuZ3RoID4gMCA/IGAgdHlwZVBhcmFtcz17JHtKU09OLnN0cmluZ2lmeShpbmZvLnR5cGVQYXJhbWV0ZXJzKX19YCA6ICcnO1xuICBjb25zdCBleHRlbmRzQXR0cmlidXRlID0gaW5mby5iYXNlVHlwZXMubGVuZ3RoID4gMCA/IGAgZXh0ZW5kcz17JHtKU09OLnN0cmluZ2lmeShpbmZvLmJhc2VUeXBlcyl9fWAgOiAnJztcbiAgY29uc3QgaW1wbGVtZW50c0F0dHJpYnV0ZSA9IGluZm8uaW1wbGVtZW50c1R5cGVzLmxlbmd0aCA+IDAgPyBgIGltcGxlbWVudHM9eyR7SlNPTi5zdHJpbmdpZnkoaW5mby5pbXBsZW1lbnRzVHlwZXMpfX1gIDogJyc7XG4gIGxpbmVzLnB1c2goYDxUeXBlU2lnbmF0dXJlIGtpbmQ9XCIke2luZm8ua2luZH1cIiBuYW1lPVwiJHtuYW1lfVwiJHt0eXBlUGFyYW1zQXR0cmlidXRlfSR7ZXh0ZW5kc0F0dHJpYnV0ZX0ke2ltcGxlbWVudHNBdHRyaWJ1dGV9IC8+YCwgJycpO1xuXG4gIGlmIChpbmZvLmJhc2VUeXBlcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgbGlua2VkVHlwZXMgPSBpbmZvLmJhc2VUeXBlcy5tYXAoKHQpID0+IGxpbmtCYXNlVHlwZSh0LCBhbGxUeXBlcywgaW5mby5uYW1lc3BhY2UpKTtcbiAgICBsaW5lcy5wdXNoKGAqKkV4dGVuZHM6KiogJHtsaW5rZWRUeXBlcy5qb2luKCcsICcpfWAsICcnKTtcbiAgfVxuXG4gIGlmIChpbmZvLmltcGxlbWVudHNUeXBlcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgbGlua2VkVHlwZXMgPSBpbmZvLmltcGxlbWVudHNUeXBlcy5tYXAoKHQpID0+IGxpbmtCYXNlVHlwZSh0LCBhbGxUeXBlcywgaW5mby5uYW1lc3BhY2UpKTtcbiAgICBsaW5lcy5wdXNoKGAqKkltcGxlbWVudHM6KiogJHtsaW5rZWRUeXBlcy5qb2luKCcsICcpfWAsICcnKTtcbiAgfVxuXG4gIHJlbmRlckNvbnN0cnVjdG9yTWR4KGxpbmVzLCBuYW1lLCBpbmZvLCBhbGxUeXBlcyk7XG4gIHJlbmRlclByb3BlcnR5VGFibGVNZHgobGluZXMsIGluZm8sIGFsbFR5cGVzKTtcbiAgcmVuZGVyTWV0aG9kVGFibGVNZHgobGluZXMsIGluZm8sIGFsbFR5cGVzKTtcblxuICByZXR1cm4geyBjb250ZW50OiBsaW5lcy5qb2luKCdcXG4nKSwgZmlsZVBhdGggfTtcbn1cblxuLyoqXG4gKiBXcml0ZXMgdGhlIFN0YXJsaWdodCBzaWRlYmFyIG9mIHRoZSBBUEkgcmVmZXJlbmNlLlxuICpcbiAqIEBwYXJhbSB0eXBlcyAtIFRoZSBkb2N1bWVudGVkIHR5cGVzLCBrZXllZCBieSBxdWFsaWZpZWQgaWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZVNpZGViYXJKc29uKHR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3Qgcm9vdCA9IGJ1aWxkU2lkZWJhclRyZWUodHlwZXMpO1xuXG4gIGNvbnN0IGdyb3VwczogU2lkZWJhckVudHJ5W10gPSBbXTtcbiAgY29uc3QgdG9wTGV2ZWxzID0gWy4uLnJvb3QuY2hpbGRyZW5dLnNvcnQoKFthXSwgW2JdKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpO1xuICBmb3IgKGNvbnN0IFt0b3BMZXZlbCwgY2hpbGRdIG9mIHRvcExldmVscykge1xuICAgIGdyb3Vwcy5wdXNoKHNpZGViYXJUcmVlVG9FbnRyaWVzKGNoaWxkLCB0b3BMZXZlbCkpO1xuICB9XG5cbiAgY29uc3Qgd3JhcHBlZFNpZGViYXI6IFNpZGViYXJFbnRyeVtdID0gW3tcbiAgICBjb2xsYXBzZWQ6IGZhbHNlLFxuICAgIGl0ZW1zOiBncm91cHMsXG4gICAgbGFiZWw6ICdBUEkgcmVmZXJlbmNlJ1xuICB9XTtcblxuICBhd2FpdCB3cml0ZUZpbGUoZ2V0QXBpRG9jU2V0dGluZ3MoKS5zaWRlYmFyRmlsZSwgSlNPTi5zdHJpbmdpZnkod3JhcHBlZFNpZGViYXIsIG51bGwsIEpTT05fSU5ERU5UKSwgJ3V0Zi04Jyk7XG4gIGNvbnNvbGUud2FybihgR2VuZXJhdGVkIHNpZGViYXIgd2l0aCAke1N0cmluZyhncm91cHMubGVuZ3RoKX0gdG9wLWxldmVsIG1vZHVsZSBncm91cHNgKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgY2xhc3MncyBjb25zdHJ1Y3RvciBibG9jay5cbiAqXG4gKiBAcGFyYW0gbGluZXMgLSBUaGUgcGFnZSBsaW5lcyB0byBhcHBlbmQgdG8uXG4gKiBAcGFyYW0gbmFtZSAtIFRoZSB0eXBlJ3MgbmFtZS5cbiAqIEBwYXJhbSBpbmZvIC0gVGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAqIEBwYXJhbSBhbGxUeXBlcyAtIEV2ZXJ5IGRvY3VtZW50ZWQgdHlwZSwga2V5ZWQgYnkgYCR7bmFtZXNwYWNlfSMke25hbWV9YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckNvbnN0cnVjdG9yTWR4KGxpbmVzOiBzdHJpbmdbXSwgbmFtZTogc3RyaW5nLCBpbmZvOiBUeXBlSW5mbywgYWxsVHlwZXM6IE1hcDxzdHJpbmcsIFR5cGVJbmZvPik6IHZvaWQge1xuICBjb25zdCBjb25zdHJ1Y3RvciA9IGluZm8uY29uc3RydWN0b3JJbmZvO1xuICBpZiAoIWNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IGN0b3JTaWcgPSBgbmV3ICR7bmFtZX0ke2NvbnN0cnVjdG9yLnNpZ25hdHVyZX1gO1xuICBjb25zdCBjdG9yRGVzYyA9IGNvbnN0cnVjdG9yLmRlc2NyaXB0aW9uXG4gICAgPyBgIGRlc2NyaXB0aW9uPVwiJHtlc2NhcGVKc3hBdHRyaWJ1dGUobWFya2Rvd25Ub0h0bWwocmVzb2x2ZUxpbmtzKGNvbnN0cnVjdG9yLmRlc2NyaXB0aW9uLCBhbGxUeXBlcywgaW5mby5uYW1lc3BhY2UpKSl9XCJgXG4gICAgOiAnJztcbiAgbGluZXMucHVzaChgPENvbnN0cnVjdG9yQmxvY2sgc2lnbmF0dXJlPVwiJHtlc2NhcGVKc3hBdHRyaWJ1dGUoY3RvclNpZyl9XCIke2N0b3JEZXNjfSAvPmAsICcnKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGFuIGVudW0ncyBtZW1iZXJzLlxuICpcbiAqIEBwYXJhbSBsaW5lcyAtIFRoZSBwYWdlIGxpbmVzIHRvIGFwcGVuZCB0by5cbiAqIEBwYXJhbSBpbmZvIC0gVGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAqIEBwYXJhbSBhbGxUeXBlcyAtIEV2ZXJ5IGRvY3VtZW50ZWQgdHlwZSwga2V5ZWQgYnkgYCR7bmFtZXNwYWNlfSMke25hbWV9YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckVudW1QYWdlKGxpbmVzOiBzdHJpbmdbXSwgaW5mbzogVHlwZUluZm8sIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiB2b2lkIHtcbiAgbGluZXMucHVzaChgPFR5cGVTaWduYXR1cmUga2luZD1cImVudW1cIiBuYW1lPVwiJHtpbmZvLm5hbWV9XCIgLz5gLCAnJyk7XG5cbiAgaWYgKGluZm8uZW51bU1lbWJlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGluZXMucHVzaCgnKipNZW1iZXJzOioqJywgJycsICd8IE1lbWJlciB8IFZhbHVlIHwgRGVzY3JpcHRpb24gfCcsICd8IDotLSB8IDotLSB8IDotLSB8Jyk7XG4gIGZvciAoY29uc3QgbWVtYmVyIG9mIGluZm8uZW51bU1lbWJlcnMpIHtcbiAgICBjb25zdCB2YWx1ZSA9IG1lbWJlci52YWx1ZSA/IGBcXGAke2VzY2FwZU1hcmtkb3duKG1lbWJlci52YWx1ZSl9XFxgYCA6ICcnO1xuICAgIGxpbmVzLnB1c2goYHwgXFxgJHttZW1iZXIubmFtZX1cXGAgfCAke3ZhbHVlfSB8ICR7ZXNjYXBlTWFya2Rvd24ocmVzb2x2ZUxpbmtzKG1lbWJlci5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIGluZm8ubmFtZXNwYWNlKSl9IHxgKTtcbiAgfVxuICBsaW5lcy5wdXNoKCcnKTtcbn1cblxuLyoqXG4gKiBSZW5kZXIgdGhlIFN0YXJsaWdodCBmcm9udG1hdHRlciBibG9jayAodGhyb3VnaCB0aGUgY2xvc2luZyBgLS0tYCBhbmQgaXRzIGJsYW5rIGxpbmUpIHNoYXJlZCBieSBldmVyeVxuICogZ2VuZXJhdGVkIHBhZ2Uga2luZDogbW9kdWxlIGluZGV4LCB0eXBlIG92ZXJ2aWV3LCBwcm9wZXJ0eSwgYW5kIG1ldGhvZC5cbiAqXG4gKiBFdmVyeSBwYWdlIGtpbmQgZ29lcyB0aHJvdWdoIGhlcmUgc28gbm8gZmllbGQgY2FuIGJlIGVtaXR0ZWQgb24gc29tZSBraW5kcyBhbmQgc2lsZW50bHkgZHJvcHBlZCBvblxuICogb3RoZXJzLiBgZGVzY3JpcHRpb25gIGluIHBhcnRpY3VsYXIgaXMgbm90IGp1c3QgU0VPIG1ldGFkYXRhIOKAlCBpdCBpcyB0aGUgbGluZSB0aGUgT0cgY2FyZCByZW5kZXJzIHVuZGVyXG4gKiB0aGUgdGl0bGUsIHNvIGEgcGFnZSBraW5kIHRoYXQgc2tpcHBlZCBpdCBwcm9kdWNlZCBhIHRpdGxlLW9ubHkgY2FyZCBuZXh0IHRvIGZ1bGx5IHBvcHVsYXRlZCBvbmVzLlxuICpcbiAqIEBwYXJhbSBmcm9udE1hdHRlciAtIFRoZSBwYWdlJ3MgZnJvbnRtYXR0ZXIgZmllbGRzLlxuICogQHJldHVybnMgVGhlIGZyb250bWF0dGVyIGxpbmVzLCB0aHJvdWdoIHRoZSBjbG9zaW5nIGAtLS1gIGFuZCBpdHMgYmxhbmsgbGluZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbmRlckZyb250TWF0dGVyKGZyb250TWF0dGVyOiBQYWdlRnJvbnRNYXR0ZXIpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBbXG4gICAgJy0tLScsXG4gICAgYHRpdGxlOiBcIiR7ZXNjYXBlWWFtbChmcm9udE1hdHRlci50aXRsZSl9XCJgLFxuICAgIGBzbHVnOiBcIiR7ZnJvbnRNYXR0ZXIuc2x1Z31cImAsXG4gICAgLi4uKGZyb250TWF0dGVyLmRlc2NyaXB0aW9uID8gW2BkZXNjcmlwdGlvbjogXCIke2VzY2FwZVlhbWwoc3RyaXBNYXJrZG93bihmcm9udE1hdHRlci5kZXNjcmlwdGlvbikpfVwiYF0gOiBbXSksXG4gICAgLi4uKGZyb250TWF0dGVyLnNpZ25hdHVyZSA/IFtgc2lnbmF0dXJlOiBcIiR7ZXNjYXBlWWFtbCh0cnVuY2F0ZVNpZ25hdHVyZShmcm9udE1hdHRlci5zaWduYXR1cmUpKX1cImBdIDogW10pLFxuICAgICdlZGl0VXJsOiBmYWxzZScsXG4gICAgJ3NpZGViYXI6JyxcbiAgICBgICBsYWJlbDogXCIke2VzY2FwZVlhbWwoZnJvbnRNYXR0ZXIuc2lkZWJhckxhYmVsKX1cImAsXG4gICAgJy0tLScsXG4gICAgJydcbiAgXTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgZnVuY3Rpb24ncyBzaWduYXR1cmUsIHBhcmFtZXRlcnMsIHJldHVybiB2YWx1ZSBhbmQgZXhhbXBsZXMuXG4gKlxuICogQHBhcmFtIGxpbmVzIC0gVGhlIHBhZ2UgbGluZXMgdG8gYXBwZW5kIHRvLlxuICogQHBhcmFtIGluZm8gLSBUaGUgZG9jdW1lbnRlZCB0eXBlLlxuICogQHBhcmFtIGFsbFR5cGVzIC0gRXZlcnkgZG9jdW1lbnRlZCB0eXBlLCBrZXllZCBieSBgJHtuYW1lc3BhY2V9IyR7bmFtZX1gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyRnVuY3Rpb25QYWdlKGxpbmVzOiBzdHJpbmdbXSwgaW5mbzogVHlwZUluZm8sIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiB2b2lkIHtcbiAgY29uc3QgJGZ1bmN0aW9uID0gaW5mby5tZXRob2RzWzBdO1xuICBpZiAoISRmdW5jdGlvbikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxpbmVzLnB1c2goJyoqU2lnbmF0dXJlOioqJywgJycsICdgYGB0cycsIGBmdW5jdGlvbiAkeyRmdW5jdGlvbi5zaWduYXR1cmV9OiAkeyRmdW5jdGlvbi5yZXR1cm5UeXBlfWAsICdgYGAnLCAnJyk7XG5cbiAgaWYgKCRmdW5jdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICBsaW5lcy5wdXNoKCcqKlBhcmFtZXRlcnM6KionLCAnJywgJ3wgUGFyYW1ldGVyIHwgVHlwZSB8IERlc2NyaXB0aW9uIHwnLCAnfCA6LS0gfCA6LS0gfCA6LS0gfCcpO1xuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mICRmdW5jdGlvbi5wYXJhbWV0ZXJzKSB7XG4gICAgICBsaW5lcy5wdXNoKFxuICAgICAgICBgfCBcXGAke3BhcmFtZXRlci5uYW1lfVxcYCB8ICR7ZXNjYXBlTWFya2Rvd24oZXNjYXBlTWR4QW5nbGVCcmFja2V0cyhyZW5kZXJUeXBlV2l0aExpbmtzKHBhcmFtZXRlci50eXBlLCBhbGxUeXBlcywgaW5mby5uYW1lLCBpbmZvLm5hbWVzcGFjZSkpKX0gfCAke2VzY2FwZU1hcmtkb3duKHJlc29sdmVMaW5rcyhwYXJhbWV0ZXIuZGVzY3JpcHRpb24sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSkpfSB8YFxuICAgICAgKTtcbiAgICB9XG4gICAgbGluZXMucHVzaCgnJyk7XG4gIH1cblxuICBjb25zdCByZXR1cm5EZXNjID0gJGZ1bmN0aW9uLnJldHVybkRlc2NyaXB0aW9uID8gYCDigJQgJHtlc2NhcGVNZHhBbmdsZUJyYWNrZXRzKHJlc29sdmVMaW5rcygkZnVuY3Rpb24ucmV0dXJuRGVzY3JpcHRpb24sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSkpfWAgOiAnJztcbiAgbGluZXMucHVzaChgKipSZXR1cm5zOioqICR7ZXNjYXBlTWR4QW5nbGVCcmFja2V0cyhyZW5kZXJUeXBlV2l0aExpbmtzKCRmdW5jdGlvbi5yZXR1cm5UeXBlLCBhbGxUeXBlcywgaW5mby5uYW1lLCBpbmZvLm5hbWVzcGFjZSkpfSR7cmV0dXJuRGVzY31gLCAnJyk7XG5cbiAgZm9yIChjb25zdCBleGFtcGxlIG9mICRmdW5jdGlvbi5leGFtcGxlcykge1xuICAgIGxpbmVzLnB1c2goJyoqRXhhbXBsZToqKicsICcnLCByZW5kZXJFeGFtcGxlTWR4KGV4YW1wbGUsIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSksICcnKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlbmRlcnMgb25lIG1ldGhvZCBvdmVybG9hZC5cbiAqXG4gKiBAcGFyYW0gbGluZXMgLSBUaGUgcGFnZSBsaW5lcyB0byBhcHBlbmQgdG8uXG4gKiBAcGFyYW0gb3ZlcmxvYWQgLSBUaGUgb3ZlcmxvYWQuXG4gKiBAcGFyYW0gdHlwZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdHlwZSB0aGUgbWV0aG9kIGJlbG9uZ3MgdG8uXG4gKiBAcGFyYW0gbmFtZXNwYWNlIC0gVGhlIG5hbWVzcGFjZSBvZiB0aGUgdHlwZSB0aGUgbWV0aG9kIGJlbG9uZ3MgdG8uXG4gKiBAcGFyYW0gYWxsVHlwZXMgLSBFdmVyeSBkb2N1bWVudGVkIHR5cGUsIGtleWVkIGJ5IGAke25hbWVzcGFjZX0jJHtuYW1lfWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJNZXRob2RPdmVybG9hZE1keChsaW5lczogc3RyaW5nW10sIG92ZXJsb2FkOiBNZW1iZXJJbmZvLCB0eXBlTmFtZTogc3RyaW5nLCBuYW1lc3BhY2U6IHN0cmluZywgYWxsVHlwZXM6IE1hcDxzdHJpbmcsIFR5cGVJbmZvPik6IHZvaWQge1xuICBjb25zdCBzaWcgPSBgJHtvdmVybG9hZC5zaWduYXR1cmV9OiAke292ZXJsb2FkLnJldHVyblR5cGV9YDtcbiAgY29uc3Qgc3RhdGljQXR0cmlidXRlID0gb3ZlcmxvYWQuaXNTdGF0aWMgPyAnIGlzU3RhdGljPXt0cnVlfScgOiAnJztcbiAgY29uc3QgZGVzY0F0dHJpYnV0ZSA9IG92ZXJsb2FkLmRlc2NyaXB0aW9uID8gYCBkZXNjcmlwdGlvbj1cIiR7ZXNjYXBlSnN4QXR0cmlidXRlKG1hcmtkb3duVG9IdG1sKHJlc29sdmVMaW5rcyhvdmVybG9hZC5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIG5hbWVzcGFjZSkpKX1cImAgOiAnJztcbiAgY29uc3QgcmVtYXJrc0F0dHJpYnV0ZSA9IG92ZXJsb2FkLnJlbWFya3MgPyBgIHJlbWFya3M9XCIke2VzY2FwZUpzeEF0dHJpYnV0ZShtYXJrZG93blRvSHRtbChyZXNvbHZlTGlua3Mob3ZlcmxvYWQucmVtYXJrcywgYWxsVHlwZXMsIG5hbWVzcGFjZSkpKX1cImAgOiAnJztcbiAgY29uc3Qgc2luY2VBdHRyaWJ1dGUgPSBvdmVybG9hZC5zaW5jZSA/IGAgc2luY2U9XCIke2VzY2FwZUpzeEF0dHJpYnV0ZShvdmVybG9hZC5zaW5jZSl9XCJgIDogJyc7XG4gIGNvbnN0IHJldHVyblR5cGVBdHRyaWJ1dGUgPSBgIHJldHVyblR5cGU9XCIke2VzY2FwZUpzeEF0dHJpYnV0ZShtYXJrZG93blRvSHRtbChyZW5kZXJUeXBlV2l0aExpbmtzKG92ZXJsb2FkLnJldHVyblR5cGUsIGFsbFR5cGVzLCB0eXBlTmFtZSwgbmFtZXNwYWNlKSkpfVwiYDtcbiAgY29uc3QgcmV0dXJuRGVzY0F0dHJpYnV0ZSA9IG92ZXJsb2FkLnJldHVybkRlc2NyaXB0aW9uXG4gICAgPyBgIHJldHVybkRlc2NyaXB0aW9uPVwiJHtlc2NhcGVKc3hBdHRyaWJ1dGUobWFya2Rvd25Ub0h0bWwocmVzb2x2ZUxpbmtzKG92ZXJsb2FkLnJldHVybkRlc2NyaXB0aW9uLCBhbGxUeXBlcywgbmFtZXNwYWNlKSkpfVwiYFxuICAgIDogJyc7XG4gIGNvbnN0IGV4YW1wbGVzQXR0cmlidXRlID0gb3ZlcmxvYWQuZXhhbXBsZXMubGVuZ3RoID4gMCA/IGAgZXhhbXBsZXM9eyR7SlNPTi5zdHJpbmdpZnkob3ZlcmxvYWQuZXhhbXBsZXMpfX1gIDogJyc7XG5cbiAgY29uc3QgcGFyYW1zID0gb3ZlcmxvYWQucGFyYW1ldGVycy5tYXAoKHApID0+ICh7XG4gICAgZGVzY3JpcHRpb246IG1hcmtkb3duVG9IdG1sKHAuZGVzY3JpcHRpb24gfHwgKHAubmFtZS5lbmRzV2l0aCgnPycpID8gJyooT3B0aW9uYWwpKicgOiAnJykpLFxuICAgIG5hbWU6IHAubmFtZSxcbiAgICB0eXBlOiBtYXJrZG93blRvSHRtbChyZW5kZXJUeXBlV2l0aExpbmtzKHAudHlwZSwgYWxsVHlwZXMsIHR5cGVOYW1lLCBuYW1lc3BhY2UpKVxuICB9KSk7XG4gIGNvbnN0IHBhcmFtc0F0dHJpYnV0ZSA9IHBhcmFtcy5sZW5ndGggPiAwID8gYCBwYXJhbWV0ZXJzPXske0pTT04uc3RyaW5naWZ5KHBhcmFtcyl9fWAgOiAnJztcblxuICBsaW5lcy5wdXNoKFxuICAgIGA8TWVtYmVyRGV0YWlsJHtzdGF0aWNBdHRyaWJ1dGV9IHNpZ25hdHVyZT1cIiR7ZXNjYXBlSnN4QXR0cmlidXRlKHNpZyl9XCIke2Rlc2NBdHRyaWJ1dGV9JHtyZW1hcmtzQXR0cmlidXRlfSR7c2luY2VBdHRyaWJ1dGV9JHtyZXR1cm5UeXBlQXR0cmlidXRlfSR7cmV0dXJuRGVzY0F0dHJpYnV0ZX0ke3BhcmFtc0F0dHJpYnV0ZX0ke2V4YW1wbGVzQXR0cmlidXRlfSAvPmAsXG4gICAgJydcbiAgKTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgdHlwZSdzIG1ldGhvZCB0YWJsZS5cbiAqXG4gKiBAcGFyYW0gbGluZXMgLSBUaGUgcGFnZSBsaW5lcyB0byBhcHBlbmQgdG8uXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBkb2N1bWVudGVkIHR5cGUuXG4gKiBAcGFyYW0gYWxsVHlwZXMgLSBFdmVyeSBkb2N1bWVudGVkIHR5cGUsIGtleWVkIGJ5IGAke25hbWVzcGFjZX0jJHtuYW1lfWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJNZXRob2RUYWJsZU1keChsaW5lczogc3RyaW5nW10sIGluZm86IFR5cGVJbmZvLCBhbGxUeXBlczogTWFwPHN0cmluZywgVHlwZUluZm8+KTogdm9pZCB7XG4gIGNvbnN0IG1ldGhvZHMgPSBbLi4uaW5mby5tZXRob2RzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgaWYgKGEuaXNTdGF0aWMgIT09IGIuaXNTdGF0aWMpIHtcbiAgICAgIHJldHVybiBhLmlzU3RhdGljID8gMSA6IC0xO1xuICAgIH1cbiAgICByZXR1cm4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKTtcbiAgfSk7XG4gIGlmIChtZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuICBsaW5lcy5wdXNoKCc8TWV0aG9kVGFibGUgcm93cz17WycpO1xuICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBtZXRob2RzKSB7XG4gICAgY29uc3QgZGVzYyA9IGVzY2FwZUpzU3RyaW5nKG1hcmtkb3duVG9IdG1sKHJlc29sdmVMaW5rcyhtZXRob2QuZGVzY3JpcHRpb24sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSkpKTtcbiAgICBjb25zdCBzdGF0aWNQcmVmaXggPSBtZXRob2QuaXNTdGF0aWMgPyAnc3RhdGljICcgOiAnJztcbiAgICBjb25zdCBzaG9ydFBhcmFtcyA9IG1ldGhvZC5wYXJhbWV0ZXJzLm1hcCgocCwgaW5kZXgpID0+IHtcbiAgICAgIHJldHVybiBpbmRleCA9PT0gMCAmJiBFVkVOVF9NRVRIT0RTLmhhcyhtZXRob2QubmFtZSkgJiYgKHAudHlwZS5zdGFydHNXaXRoKCdcIicpIHx8IHAudHlwZS5zdGFydHNXaXRoKCdcXCcnKSkgPyBwLnR5cGUucmVwbGFjZUFsbCgnXCInLCAnXFwnJykgOiBwLm5hbWU7XG4gICAgfSkuam9pbignLCAnKTtcbiAgICBjb25zdCBzaG9ydFNpZyA9IGAke3N0YXRpY1ByZWZpeH0ke21ldGhvZC5uYW1lfSgke3Nob3J0UGFyYW1zfSlgO1xuICAgIGNvbnN0IHNpZyA9IGVzY2FwZUpzU3RyaW5nKHNob3J0U2lnKTtcbiAgICBjb25zdCBzbHVnID0gb3ZlcmxvYWRSb3V0ZVNlZ21lbnQobWV0aG9kLm92ZXJsb2FkS2V5KTtcbiAgICBjb25zdCByZXR1cm5UeXBlID0gbWFya2Rvd25Ub0h0bWwocmVuZGVyVHlwZVdpdGhMaW5rcyhtZXRob2QucmV0dXJuVHlwZSwgYWxsVHlwZXMsIGluZm8ubmFtZSwgaW5mby5uYW1lc3BhY2UpKTtcbiAgICBjb25zdCBpbmhlcml0ZWRBdHRyaWJ1dGUgPSBtZXRob2QuaW5oZXJpdGVkRnJvbVxuICAgICAgPyBgLCBpbmhlcml0ZWRGcm9tOiBcIiR7ZXNjYXBlSnNTdHJpbmcobWFya2Rvd25Ub0h0bWwodHlwZUxpbmsobWV0aG9kLmluaGVyaXRlZEZyb20sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSkpKX1cImBcbiAgICAgIDogJyc7XG4gICAgY29uc3QgaHJlZiA9IG1lbWJlckhyZWYoc2x1ZywgbWV0aG9kLmluaGVyaXRlZEZyb20sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSk7XG4gICAgbGluZXMucHVzaChcbiAgICAgIGAgIHsgc2lnbmF0dXJlOiBcIiR7c2lnfVwiLCBocmVmOiBcIiR7ZXNjYXBlSnNTdHJpbmcoaHJlZil9XCIsIHJldHVybnM6IFwiJHtlc2NhcGVKc1N0cmluZyhyZXR1cm5UeXBlKX1cIiwgZGVzY3JpcHRpb246IFwiJHtkZXNjfVwiJHtpbmhlcml0ZWRBdHRyaWJ1dGV9IH0sYFxuICAgICk7XG4gIH1cbiAgbGluZXMucHVzaCgnXX0gLz4nLCAnJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyBhIHR5cGUncyBwcm9wZXJ0eSB0YWJsZS5cbiAqXG4gKiBAcGFyYW0gbGluZXMgLSBUaGUgcGFnZSBsaW5lcyB0byBhcHBlbmQgdG8uXG4gKiBAcGFyYW0gaW5mbyAtIFRoZSBkb2N1bWVudGVkIHR5cGUuXG4gKiBAcGFyYW0gYWxsVHlwZXMgLSBFdmVyeSBkb2N1bWVudGVkIHR5cGUsIGtleWVkIGJ5IGAke25hbWVzcGFjZX0jJHtuYW1lfWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJQcm9wZXJ0eVRhYmxlTWR4KGxpbmVzOiBzdHJpbmdbXSwgaW5mbzogVHlwZUluZm8sIGFsbFR5cGVzOiBNYXA8c3RyaW5nLCBUeXBlSW5mbz4pOiB2b2lkIHtcbiAgY29uc3QgcHJvcGVydGllcyA9IGluZm8ucHJvcGVydGllcztcbiAgaWYgKHByb3BlcnRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxpbmVzLnB1c2goJzxQcm9wZXJ0eVRhYmxlIHJvd3M9e1snKTtcbiAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgZGVzYyA9IGVzY2FwZUpzU3RyaW5nKG1hcmtkb3duVG9IdG1sKHJlc29sdmVMaW5rcyhwcm9wZXJ0eS5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIGluZm8ubmFtZXNwYWNlKSkpO1xuICAgIGNvbnN0IHR5cGUgPSBtYXJrZG93blRvSHRtbChyZW5kZXJUeXBlV2l0aExpbmtzKHByb3BlcnR5LnR5cGUsIGFsbFR5cGVzLCBpbmZvLm5hbWUsIGluZm8ubmFtZXNwYWNlKSk7XG4gICAgY29uc3QgaW5oZXJpdGVkQXR0cmlidXRlID0gcHJvcGVydHkuaW5oZXJpdGVkRnJvbVxuICAgICAgPyBgLCBpbmhlcml0ZWRGcm9tOiBcIiR7ZXNjYXBlSnNTdHJpbmcobWFya2Rvd25Ub0h0bWwodHlwZUxpbmsocHJvcGVydHkuaW5oZXJpdGVkRnJvbSwgYWxsVHlwZXMsIGluZm8ubmFtZXNwYWNlKSkpfVwiYFxuICAgICAgOiAnJztcbiAgICBjb25zdCBocmVmID0gbWVtYmVySHJlZihtZW1iZXJSb3V0ZVNlZ21lbnQocHJvcGVydHkubmFtZSksIHByb3BlcnR5LmluaGVyaXRlZEZyb20sIGFsbFR5cGVzLCBpbmZvLm5hbWVzcGFjZSk7XG4gICAgbGluZXMucHVzaChcbiAgICAgIGAgIHsgbmFtZTogXCIke2VzY2FwZUpzU3RyaW5nKHByb3BlcnR5Lm5hbWUpfVwiLCBocmVmOiBcIiR7ZXNjYXBlSnNTdHJpbmcoaHJlZil9XCIsIHR5cGU6IFwiJHtlc2NhcGVKc1N0cmluZyh0eXBlKX1cIiwgZGVzY3JpcHRpb246IFwiJHtkZXNjfVwiJHtpbmhlcml0ZWRBdHRyaWJ1dGV9IH0sYFxuICAgICk7XG4gIH1cbiAgbGluZXMucHVzaCgnXX0gLz4nLCAnJyk7XG59XG5cbi8qKlxuICogUmVuZGVycyBhIHR5cGUgYWxpYXMncyBzaWduYXR1cmUuXG4gKlxuICogQHBhcmFtIGxpbmVzIC0gVGhlIHBhZ2UgbGluZXMgdG8gYXBwZW5kIHRvLlxuICogQHBhcmFtIGluZm8gLSBUaGUgZG9jdW1lbnRlZCB0eXBlLlxuICogQHBhcmFtIGFsbFR5cGVzIC0gRXZlcnkgZG9jdW1lbnRlZCB0eXBlLCBrZXllZCBieSBgJHtuYW1lc3BhY2V9IyR7bmFtZX1gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyVHlwZUFsaWFzUGFnZShsaW5lczogc3RyaW5nW10sIGluZm86IFR5cGVJbmZvLCBhbGxUeXBlczogTWFwPHN0cmluZywgVHlwZUluZm8+KTogdm9pZCB7XG4gIGNvbnN0IHR5cGVQYXJhbXNBdHRyaWJ1dGUgPSBpbmZvLnR5cGVQYXJhbWV0ZXJzLmxlbmd0aCA+IDAgPyBgIHR5cGVQYXJhbXM9eyR7SlNPTi5zdHJpbmdpZnkoaW5mby50eXBlUGFyYW1ldGVycyl9fWAgOiAnJztcbiAgbGluZXMucHVzaChgPFR5cGVTaWduYXR1cmUga2luZD1cInR5cGVcIiBuYW1lPVwiJHtpbmZvLm5hbWV9XCIke3R5cGVQYXJhbXNBdHRyaWJ1dGV9IC8+YCwgJycpO1xuXG4gIGNvbnN0IHJocyA9IGluZm8udHlwZUFsaWFzVGV4dCA/PyAndW5rbm93bic7XG4gIGxpbmVzLnB1c2goXG4gICAgJyoqU2lnbmF0dXJlOioqJyxcbiAgICAnJyxcbiAgICAnYGBgdHMnLFxuICAgIGB0eXBlICR7Z2V0RGlzcGxheU5hbWUoaW5mby5uYW1lLCBpbmZvKX0gPSAke3Joc31gLFxuICAgICdgYGAnLFxuICAgICcnLFxuICAgIGAqKlR5cGU6KiogJHtlc2NhcGVNZHhCcmFjZXMoZXNjYXBlTWR4QW5nbGVCcmFja2V0cyhyZW5kZXJUeXBlV2l0aExpbmtzKHJocywgYWxsVHlwZXMsIGluZm8ubmFtZSwgaW5mby5uYW1lc3BhY2UpKSl9YCxcbiAgICAnJ1xuICApO1xufVxuXG4vKipcbiAqIFJlbmRlcnMgYSB2YXJpYWJsZSdzIGRlY2xhcmF0aW9uIGFuZCB0eXBlLlxuICpcbiAqIEBwYXJhbSBsaW5lcyAtIFRoZSBwYWdlIGxpbmVzIHRvIGFwcGVuZCB0by5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIHR5cGUncyBuYW1lLlxuICogQHBhcmFtIGluZm8gLSBUaGUgZG9jdW1lbnRlZCB0eXBlLlxuICogQHBhcmFtIGFsbFR5cGVzIC0gRXZlcnkgZG9jdW1lbnRlZCB0eXBlLCBrZXllZCBieSBgJHtuYW1lc3BhY2V9IyR7bmFtZX1gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyVmFyaWFibGVQYWdlKGxpbmVzOiBzdHJpbmdbXSwgbmFtZTogc3RyaW5nLCBpbmZvOiBUeXBlSW5mbywgYWxsVHlwZXM6IE1hcDxzdHJpbmcsIFR5cGVJbmZvPik6IHZvaWQge1xuICBjb25zdCBrZXl3b3JkID0gaW5mby52YXJpYWJsZUtleXdvcmQgPz8gJ2xldCc7XG4gIGNvbnN0IHZhcmlhYmxlVHlwZSA9IGluZm8udmFyaWFibGVUeXBlID8/ICd1bmtub3duJztcbiAgbGluZXMucHVzaChcbiAgICAnKipTaWduYXR1cmU6KionLFxuICAgICcnLFxuICAgICdgYGB0cycsXG4gICAgYCR7a2V5d29yZH0gJHtuYW1lfTogJHt2YXJpYWJsZVR5cGV9YCxcbiAgICAnYGBgJyxcbiAgICAnJyxcbiAgICBgKipUeXBlOioqICR7ZXNjYXBlTWR4QnJhY2VzKGVzY2FwZU1keEFuZ2xlQnJhY2tldHMocmVuZGVyVHlwZVdpdGhMaW5rcyh2YXJpYWJsZVR5cGUsIGFsbFR5cGVzLCBuYW1lLCBpbmZvLm5hbWVzcGFjZSkpKX1gLFxuICAgICcnXG4gICk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBuYW1lc3BhY2UgdHJlZSBub2RlIGludG8gYSBzaWRlYmFyIGdyb3VwLlxuICpcbiAqIEBwYXJhbSBub2RlIC0gVGhlIG5vZGUuXG4gKiBAcGFyYW0gbGFiZWwgLSBUaGUgZ3JvdXAncyBsYWJlbC5cbiAqIEByZXR1cm5zIFRoZSBzaWRlYmFyIGdyb3VwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2lkZWJhclRyZWVUb0VudHJpZXMobm9kZTogU2lkZWJhclRyZWVOb2RlLCBsYWJlbDogc3RyaW5nKTogU2lkZWJhckVudHJ5IHtcbiAgY29uc3QgaXRlbXM6IChTaWRlYmFyRW50cnkgfCBTaWRlYmFyTGluaylbXSA9IFtdO1xuXG4gIC8vIENoaWxkIGRpcmVjdG9yeSBncm91cHMgZmlyc3QgKGJlZm9yZSB0aGlzIG1vZHVsZSdzIG93biBwYWdlcylcbiAgY29uc3Qgc29ydGVkQ2hpbGRyZW4gPSBbLi4ubm9kZS5jaGlsZHJlbl0uc29ydCgoW2FdLCBbYl0pID0+IGEubG9jYWxlQ29tcGFyZShiKSk7XG4gIGZvciAoY29uc3QgW2NoaWxkTmFtZSwgY2hpbGRdIG9mIHNvcnRlZENoaWxkcmVuKSB7XG4gICAgaXRlbXMucHVzaChzaWRlYmFyVHJlZVRvRW50cmllcyhjaGlsZCwgY2hpbGROYW1lKSk7XG4gIH1cblxuICAvLyBUaGlzIG1vZHVsZSdzIG93biBvdmVydmlldyBwYWdlICsgdHlwZS9mdW5jdGlvbiBwYWdlcyAoaW5kaXZpZHVhbCBtZW1iZXJzIGFyZSBub3QgbGlzdGVkKS5cbiAgLy8gU2lkZWJhciBgbGlua2AgZmllbGRzIG11c3QgTk9UIGVtYmVkIEJBU0VfUEFUSDogU3RhcmxpZ2h0IHByZXBlbmRzIHRoZSBjb25maWcgYGJhc2VgIHRvIGV2ZXJ5XG4gIC8vIHNpZGViYXIgbGluayBpdHNlbGYsIHNvIGluY2x1ZGluZyBpdCBoZXJlIHdvdWxkIGRvdWJsZSB0aGUgYmFzZSAoZS5nLiBgL2Jhc2UvYmFzZS9hcGkvLi4uYCDihpIgNDA0KS5cbiAgLy8gVGhpcyBkaWZmZXJzIGZyb20gaW4tY29udGVudCBsaW5rcywgd2hpY2ggYXJlIHJhdyBhbmNob3JzIHRoYXQgU3RhcmxpZ2h0IGRvZXMgbm90IGJhc2UtcHJlcGVuZC5cbiAgaWYgKG5vZGUudHlwZXMubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHsgbmFtZXNwYWNlIH0gPSBlbnN1cmVOb25OdWxsYWJsZShub2RlLnR5cGVzWzBdKTtcbiAgICBpdGVtcy5wdXNoKHsgbGFiZWw6ICdPdmVydmlldycsIGxpbms6IGAvYXBpLyR7bmFtZXNwYWNlfS9gIH0pO1xuICAgIGNvbnN0IHNvcnRlZFR5cGVzID0gWy4uLm5vZGUudHlwZXNdLnNvcnQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICAgIGZvciAoY29uc3QgdCBvZiBzb3J0ZWRUeXBlcykge1xuICAgICAgaXRlbXMucHVzaCh7IGxhYmVsOiB0Lm5hbWUsIGxpbms6IGAvYXBpLyR7dC5uYW1lc3BhY2V9LyR7dG9UeXBlUm91dGVTZWdtZW50KHQubmFtZXNwYWNlLCB0Lm5hbWUpfS9gIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGNvbGxhcHNlZDogdHJ1ZSwgaXRlbXMsIGxhYmVsIH07XG59XG5cbi8vIFNlcnZlcyBib3RoIGFzIHRoZSByb290IEFQSSBwYWdlJ3MgcHJvc2UgYW5kIChzdHJpcHBlZCkgYXMgaXRzIGBkZXNjcmlwdGlvbmAgZnJvbnRtYXR0ZXIuXG4vLyBTaGFyaW5nIG9uZSBmdW5jdGlvbiBrZWVwcyB0aGUgcGFnZSBhbmQgaXRzIE9HIGNhcmQgZnJvbSBkcmlmdGluZyBhcGFydC5cbmZ1bmN0aW9uIGdldEFwaUluZGV4SW50cm8obmFtZXNwYWNlczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcge1xuICBjb25zdCB7IHBhY2thZ2VOYW1lIH0gPSBnZXRBcGlEb2NTZXR0aW5ncygpO1xuICBjb25zdCBbZXhhbXBsZU5hbWVzcGFjZSA9ICdtb2R1bGUnXSA9IG5hbWVzcGFjZXM7XG4gIHJldHVybiBgVGhlIGNvbXBsZXRlIEFQSSByZWZlcmVuY2UgZm9yIFxcYCR7cGFja2FnZU5hbWV9XFxgLCBnZW5lcmF0ZWQgZnJvbSBpdHMgVFNEb2MuIGBcbiAgICArIGBFYWNoIG1vZHVsZSBiZWxvdyBtYXBzIHRvIGFuIGltcG9ydCBzdWJwYXRoIChlLmcuIHRoZSBcXGAke2V4YW1wbGVOYW1lc3BhY2V9XFxgIG1vZHVsZSBpcyBcXGAke3BhY2thZ2VOYW1lfS8ke2V4YW1wbGVOYW1lc3BhY2V9XFxgKS5gO1xufVxuXG5mdW5jdGlvbiBnZXRDb21wb25lbnRJbXBvcnRzKGNvbXBvbmVudE5hbWVzOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIGNvbXBvbmVudE5hbWVzLm1hcCgoY29tcG9uZW50TmFtZSkgPT4gYGltcG9ydCAke2NvbXBvbmVudE5hbWV9IGZyb20gXCIke0FQSV9DT01QT05FTlRTX0lNUE9SVF9QUkVGSVh9LyR7Y29tcG9uZW50TmFtZX0uYXN0cm9cIjtgKTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyTmFtZXNwYWNlVGFibGUoXG4gIGxpbmVzOiBzdHJpbmdbXSxcbiAgaGVhZGluZzogc3RyaW5nLFxuICBjb2x1bW5MYWJlbDogc3RyaW5nLFxuICBlbnRyaWVzOiBUeXBlSW5mb1tdLFxuICBhbGxUeXBlczogTWFwPHN0cmluZywgVHlwZUluZm8+LFxuICBuYW1lc3BhY2U6IHN0cmluZ1xuKTogdm9pZCB7XG4gIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZW50cmllc10uc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIGxpbmVzLnB1c2goYCMjICR7aGVhZGluZ31gLCAnJywgYHwgJHtjb2x1bW5MYWJlbH0gfCBEZXNjcmlwdGlvbiB8YCwgJ3wgOi0tIHwgOi0tIHwnKTtcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3J0ZWQpIHtcbiAgICBsaW5lcy5wdXNoKGB8IFske2VudHJ5Lm5hbWV9XSguLyR7dG9UeXBlUm91dGVTZWdtZW50KGVudHJ5Lm5hbWVzcGFjZSwgZW50cnkubmFtZSl9LykgfCAke2VzY2FwZU1hcmtkb3duKHJlc29sdmVMaW5rcyhlbnRyeS5kZXNjcmlwdGlvbiwgYWxsVHlwZXMsIG5hbWVzcGFjZSkpfSB8YCk7XG4gIH1cbiAgbGluZXMucHVzaCgnJyk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBT0EsU0FBUyw4QkFBOEI7QUFDdkMsU0FBUyx5QkFBeUI7QUFDbEMsU0FBUyxpQkFBaUI7QUFDMUIsU0FBUyxZQUFZO0FBWXJCLFNBQVMscUJBQXFCO0FBQzlCO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLHlCQUF5QjtBQUNsQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1AsU0FBUyxvQ0FBb0M7QUFFN0MsTUFBTSxjQUFjO0FBUXBCLGVB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