velocious 1.0.604 → 1.0.606

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 (53) hide show
  1. package/README.md +26 -10
  2. package/build/background-jobs/main.js +6 -1
  3. package/build/cli/commands/test/timing-manifest/merge.js +14 -0
  4. package/build/environment-handlers/base.js +9 -0
  5. package/build/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +108 -0
  6. package/build/environment-handlers/node/cli/commands/test.js +48 -7
  7. package/build/environment-handlers/node.js +10 -0
  8. package/build/src/background-jobs/main.d.ts.map +1 -1
  9. package/build/src/background-jobs/main.js +8 -2
  10. package/build/src/cli/commands/test/timing-manifest/merge.d.ts +10 -0
  11. package/build/src/cli/commands/test/timing-manifest/merge.d.ts.map +1 -0
  12. package/build/src/cli/commands/test/timing-manifest/merge.js +13 -0
  13. package/build/src/environment-handlers/base.d.ts +6 -0
  14. package/build/src/environment-handlers/base.d.ts.map +1 -1
  15. package/build/src/environment-handlers/base.js +9 -1
  16. package/build/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.d.ts +32 -0
  17. package/build/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.d.ts.map +1 -0
  18. package/build/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +97 -0
  19. package/build/src/environment-handlers/node/cli/commands/test.d.ts +3 -3
  20. package/build/src/environment-handlers/node/cli/commands/test.d.ts.map +1 -1
  21. package/build/src/environment-handlers/node/cli/commands/test.js +36 -9
  22. package/build/src/environment-handlers/node.d.ts +6 -0
  23. package/build/src/environment-handlers/node.d.ts.map +1 -1
  24. package/build/src/environment-handlers/node.js +10 -1
  25. package/build/src/testing/test-profile-output.d.ts +11 -0
  26. package/build/src/testing/test-profile-output.d.ts.map +1 -1
  27. package/build/src/testing/test-profile-output.js +21 -7
  28. package/build/src/testing/test-profiler.d.ts.map +1 -1
  29. package/build/src/testing/test-profiler.js +3 -2
  30. package/build/src/testing/test-suite-splitter.d.ts +33 -0
  31. package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
  32. package/build/src/testing/test-suite-splitter.js +84 -8
  33. package/build/src/testing/timing-manifest.d.ts +94 -0
  34. package/build/src/testing/timing-manifest.d.ts.map +1 -0
  35. package/build/src/testing/timing-manifest.js +284 -0
  36. package/build/testing/test-profile-output.js +23 -8
  37. package/build/testing/test-profiler.js +2 -1
  38. package/build/testing/test-suite-splitter.js +91 -7
  39. package/build/testing/timing-manifest.js +346 -0
  40. package/build/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +1 -1
  42. package/scripts/bootstrap-provider-runtime.sh +249 -0
  43. package/scripts/verify-docker-dev-environment.js +219 -29
  44. package/src/background-jobs/main.js +6 -1
  45. package/src/cli/commands/test/timing-manifest/merge.js +14 -0
  46. package/src/environment-handlers/base.js +9 -0
  47. package/src/environment-handlers/node/cli/commands/test/timing-manifest/merge.js +108 -0
  48. package/src/environment-handlers/node/cli/commands/test.js +48 -7
  49. package/src/environment-handlers/node.js +10 -0
  50. package/src/testing/test-profile-output.js +23 -8
  51. package/src/testing/test-profiler.js +2 -1
  52. package/src/testing/test-suite-splitter.js +91 -7
  53. package/src/testing/timing-manifest.js +346 -0
@@ -1 +1 @@
1
- {"version":3,"file":"test-suite-splitter.d.ts","sourceRoot":"","sources":["../../../src/testing/test-suite-splitter.js"],"names":[],"mappings":"AAOG,YAAkB,iBAAiB,GACnC;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,MAAM,EAAd,MAAM,CACnB;CAAA,CAAA;AAIE,YAAkB,WAAW,GAC7B;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAqB,KAAK,EAAf,MAAM,EAAE,CACrB;CAAA,CAAA;AAmBD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAqB7B,OAAO;IACP,YAAY;IACZ,UAAU;IACV,cAAc;IACd,eAAe;IAxBtB;;;;;;;;OAQG;IACH,YAAY,EAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAC,EANrF;QAAqB,MAAM,EAAnB,MAAM,CACd;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAuB,SAAS,EAAxB,MAAM,EAAE,CAChB;QAAsB,aAAa,AAAnC,CACA,EADQ,MAAM,CACd;QAA6C,cAAc,AAA3D,CACF,EADU,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACvC;KACuF,EAgBvF;IAED;;;OAGG;IACH,aAAa,IAFA,MAAM,EAAE,CAQpB;IAED;;;OAGG;IACH,oBAAoB,IAFP,iBAAiB,EAAE,CAO/B;IAED;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAHX,MAGW,GAFT,MAAM,CA+BlB;IAED;;;;OAIG;IACH,uBAAuB,CAAC,cAAc,EAH3B,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGD,GAFzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBlC;IAED;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAHnB,MAGmB,GAFjB,MAAM,CAMlB;IAED;;;;OAIG;IACH,sBAAsB,CAAC,KAAK,EAHjB,iBAAiB,EAGA,GAFf,iBAAiB,EAAE,CAU/B;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAHnB,iBAAiB,EAGE,GAFjB,WAAW,EAAE,CAoBzB;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAHf,WAAW,EAGI,GAFb,WAAW,CAYvB;CACF"}
1
+ {"version":3,"file":"test-suite-splitter.d.ts","sourceRoot":"","sources":["../../../src/testing/test-suite-splitter.js"],"names":[],"mappings":"AAQG,YAAkB,iBAAiB,GACnC;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,MAAM,EAAd,MAAM,CACnB;CAAA,CAAA;AAIE,YAAkB,WAAW,GAC7B;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAqB,KAAK,EAAf,MAAM,EAAE,CACrB;CAAA,CAAA;AAmBD;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAqB7B,OAAO;IACP,YAAY;IACZ,UAAU;IACV,cAAc;IACd,eAAe;IAxBtB;;;;;;;;OAQG;IACH,YAAY,EAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,QAAQ,EAAC,EANrF;QAAqB,MAAM,EAAnB,MAAM,CACd;QAAqB,WAAW,EAAxB,MAAM,CACd;QAAuB,SAAS,EAAxB,MAAM,EAAE,CAChB;QAAsB,aAAa,AAAnC,CACA,EADQ,MAAM,CACd;QAA6C,cAAc,AAA3D,CACF,EADU,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACvC;KACuF,EAgBvF;IAED;;;OAGG;IACH,aAAa,IAFA,MAAM,EAAE,CAQpB;IAED;;;OAGG;IACH,oBAAoB,IAFP,iBAAiB,EAAE,CAO/B;IAED;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAHX,MAGW,GAFT,MAAM,CA8BlB;IAED;;;;OAIG;IACH,uBAAuB,CAAC,cAAc,EAH3B,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAGD,GAFzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBlC;IAED;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAHnB,MAGmB,GAFjB,MAAM,CAIlB;IAED;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAHnB,MAGmB,GAFjB,MAAM,CAMlB;IAED;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAHlB,MAGkB,GAFhB,MAAM,GAAG,SAAS,CAS9B;IAED;;;;OAIG;IACH,sBAAsB,CAAC,QAAQ,EAHpB,MAGoB,GAFlB,MAAM,GAAG,SAAS,CAQ9B;IAED;;;;OAIG;IACH,mBAAmB,CAAC,QAAQ,EAHjB,MAGiB,GAFf,MAAM,EAAE,CAUpB;IAED;;;OAGG;IACH,yBAAyB,IAFZ;QAAC,cAAc,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAC,CAyBjF;IAED;;;;OAIG;IACH,sBAAsB,CAAC,KAAK,EAHjB,iBAAiB,EAGA,GAFf,iBAAiB,EAAE,CAU/B;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAHnB,iBAAiB,EAGE,GAFjB,WAAW,EAAE,CAoBzB;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,OAAO,EAHf,WAAW,EAGI,GAFb,WAAW,CAYvB;CACF"}
@@ -1,6 +1,7 @@
1
1
  // @ts-check
2
2
  import path from "path";
3
3
  import restArgsError from "../utils/rest-args-error.js";
4
+ import { canonicalTimingManifestPath, compareTimingManifestPaths } from "./timing-manifest.js";
4
5
  /**
5
6
  * SplitterFileEntry type.
6
7
  * @typedef {object} SplitterFileEntry
@@ -81,12 +82,11 @@ export default class TestSuiteSplitter {
81
82
  * @returns {number} - Weight value.
82
83
  */
83
84
  computeWeight(filePath) {
84
- const relativePath = this.normalizeRelativePath(path.relative(this._baseDirectory, filePath));
85
- const projectRelativePath = this.normalizeRelativePath(path.join(path.basename(this._baseDirectory), relativePath));
86
- const duration = this._timingManifest[relativePath] ?? this._timingManifest[projectRelativePath];
87
- if (duration !== undefined) {
85
+ const duration = this.timingManifestDuration(filePath);
86
+ if (duration !== undefined && duration > 0) {
88
87
  return duration;
89
88
  }
89
+ const relativePath = this.heuristicRelativePath(filePath);
90
90
  let weight = DEFAULT_WEIGHT;
91
91
  // Extract the type directory from the relative path.
92
92
  // Matches both "spec/system/..." (base is project root) and "system/..." (base is spec/ itself).
@@ -115,9 +115,15 @@ export default class TestSuiteSplitter {
115
115
  return normalized;
116
116
  }
117
117
  for (const [filePath, duration] of Object.entries(timingManifest)) {
118
- if (typeof duration === "number" && Number.isFinite(duration) && duration > 0) {
118
+ if (typeof duration !== "number" || !Number.isFinite(duration) || duration < 0)
119
+ continue;
120
+ try {
119
121
  normalized[this.normalizeRelativePath(filePath)] = duration;
120
122
  }
123
+ catch (error) {
124
+ if (!(error instanceof Error))
125
+ throw error;
126
+ }
121
127
  }
122
128
  return normalized;
123
129
  }
@@ -127,10 +133,80 @@ export default class TestSuiteSplitter {
127
133
  * @returns {string} - Normalized relative test path.
128
134
  */
129
135
  normalizeRelativePath(filePath) {
130
- return filePath
136
+ return canonicalTimingManifestPath(filePath);
137
+ }
138
+ /**
139
+ * Returns the permissive relative path used only for heuristic classification.
140
+ * @param {string} filePath - Absolute test file path.
141
+ * @returns {string} - Portable relative path which may escape the profiling base.
142
+ */
143
+ heuristicRelativePath(filePath) {
144
+ return path.relative(this._baseDirectory, filePath)
131
145
  .replaceAll("\\", "/")
132
146
  .replace(/^\.\//, "");
133
147
  }
148
+ /**
149
+ * Returns a canonical manifest key when the file is representable under the profiling base.
150
+ * @param {string} filePath - Absolute test file path.
151
+ * @returns {string | undefined} - Canonical relative path, or undefined for an external file.
152
+ */
153
+ manifestRelativePath(filePath) {
154
+ const relativePath = path.relative(this._baseDirectory, filePath);
155
+ if (!relativePath || path.isAbsolute(relativePath))
156
+ return;
157
+ if (relativePath === ".." || relativePath.startsWith(`..${path.sep}`))
158
+ return;
159
+ return this.normalizeRelativePath(relativePath);
160
+ }
161
+ /**
162
+ * Returns the first manifest entry matching a discovered test file.
163
+ * @param {string} filePath - Absolute test file path.
164
+ * @returns {number | undefined} - Recorded duration, including zero.
165
+ */
166
+ timingManifestDuration(filePath) {
167
+ for (const manifestPath of this.timingManifestPaths(filePath)) {
168
+ if (Object.hasOwn(this._timingManifest, manifestPath))
169
+ return this._timingManifest[manifestPath];
170
+ }
171
+ return undefined;
172
+ }
173
+ /**
174
+ * Returns compatible manifest keys for one discovered file.
175
+ * @param {string} filePath - Absolute test file path.
176
+ * @returns {string[]} - Canonical keys in matching priority order.
177
+ */
178
+ timingManifestPaths(filePath) {
179
+ const relativePath = this.manifestRelativePath(filePath);
180
+ if (!relativePath)
181
+ return [];
182
+ const projectRelativePath = this.normalizeRelativePath(path.join(path.basename(this._baseDirectory), relativePath));
183
+ return relativePath === projectRelativePath ? [relativePath] : [relativePath, projectRelativePath];
184
+ }
185
+ /**
186
+ * Summarizes timing-history coverage for the complete discovered suite.
187
+ * @returns {{heuristicFiles: number, measuredFiles: number, staleEntries: number}} - Compact coverage counts.
188
+ */
189
+ getTimingManifestCoverage() {
190
+ const matchedManifestPaths = new Set();
191
+ let measuredFiles = 0;
192
+ for (const filePath of this._testFiles) {
193
+ let matchedDuration;
194
+ for (const manifestPath of this.timingManifestPaths(filePath)) {
195
+ if (!Object.hasOwn(this._timingManifest, manifestPath))
196
+ continue;
197
+ matchedManifestPaths.add(manifestPath);
198
+ matchedDuration = this._timingManifest[manifestPath];
199
+ break;
200
+ }
201
+ if (matchedDuration !== undefined && matchedDuration > 0)
202
+ measuredFiles++;
203
+ }
204
+ return {
205
+ heuristicFiles: this._testFiles.length - measuredFiles,
206
+ measuredFiles,
207
+ staleEntries: Object.keys(this._timingManifest).length - matchedManifestPaths.size
208
+ };
209
+ }
134
210
  /**
135
211
  * Sorts files by weight descending, then by path for determinism.
136
212
  * @param {SplitterFileEntry[]} files - Weighted files.
@@ -141,7 +217,7 @@ export default class TestSuiteSplitter {
141
217
  if (b.weight !== a.weight) {
142
218
  return b.weight - a.weight;
143
219
  }
144
- return a.filePath.localeCompare(b.filePath);
220
+ return compareTimingManifestPaths(a.filePath, b.filePath);
145
221
  });
146
222
  }
147
223
  /**
@@ -181,4 +257,4 @@ export default class TestSuiteSplitter {
181
257
  return lightest;
182
258
  }
183
259
  }
184
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdWl0ZS1zcGxpdHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3Qtc3VpdGUtc3BsaXR0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUV2RDs7Ozs7R0FLRztBQUVIOzs7OztHQUtHO0FBRUgsOENBQThDO0FBQzlDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQTtBQUV4Qjs7OztHQUlHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixNQUFNLEVBQUUsRUFBRTtJQUNWLGlCQUFpQixFQUFFLEVBQUU7SUFDckIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFBO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0FBRWpDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8saUJBQWlCO0lBQ3BDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDdEYsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxJQUFJLFdBQVcsR0FBRyxNQUFNLEVBQUUsQ0FBQztZQUM5RSxNQUFNLElBQUksS0FBSyxDQUFDLHdDQUF3QyxNQUFNLFVBQVUsV0FBVyxF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QUMsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUE7UUFDM0MsQ0FBQztRQUVELEtBQUssTUFBTSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBRWpELFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUNuQyxRQUFRLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUE7UUFDdEMsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGtCQUFrQixDQUFDLE9BQU87UUFDeEIsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRXpCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDeEMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbEQsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcblxuLyoqXG4gKiBTcGxpdHRlckZpbGVFbnRyeSB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gU3BsaXR0ZXJGaWxlRW50cnlcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBmaWxlUGF0aCAtIEFic29sdXRlIGZpbGUgcGF0aC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB3ZWlnaHQgLSBDb21wdXRlZCB3ZWlnaHQgZm9yIGxvYWQgYmFsYW5jaW5nLlxuICovXG5cbi8qKlxuICogR3JvdXBCdWNrZXQgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEdyb3VwQnVja2V0XG4gKiBAcHJvcGVydHkge251bWJlcn0gdG90YWxXZWlnaHQgLSBBY2N1bXVsYXRlZCB3ZWlnaHQuXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBmaWxlcyAtIEZpbGVzIGFzc2lnbmVkIHRvIHRoaXMgZ3JvdXAuXG4gKi9cblxuLyoqIERlZmF1bHQgd2VpZ2h0IGZvciBhIHJlZ3VsYXIgdGVzdCBmaWxlLiAqL1xuY29uc3QgREVGQVVMVF9XRUlHSFQgPSAxXG5cbi8qKlxuICogV2VpZ2h0IG11bHRpcGxpZXJzIGJ5IHNwZWMgZGlyZWN0b3J5IG5hbWUuXG4gKiBIZWF2aWVyIHRlc3QgdHlwZXMgZ2V0IGhpZ2hlciB3ZWlnaHRzIHNvIGdyZWVkeSBkaXN0cmlidXRpb24gYmFsYW5jZXMgd2FsbC1jbG9jayB0aW1lLlxuICogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59XG4gKi9cbmNvbnN0IERJUkVDVE9SWV9XRUlHSFRTID0ge1xuICBzeXN0ZW06IDIwLFxuICBcImZyb250ZW5kLW1vZGVsc1wiOiAxMCxcbiAgY29udHJvbGxlcjogM1xufVxuXG4vKiogRXh0cmEgbXVsdGlwbGllciBhcHBsaWVkIHRvIGJyb3dzZXIgc3BlYyBmaWxlcyBvbiB0b3Agb2YgZGlyZWN0b3J5IHdlaWdodC4gKi9cbmNvbnN0IEJST1dTRVJfU1BFQ19NVUxUSVBMSUVSID0gMlxuXG4vKipcbiAqIFNwbGl0cyBhIGxpc3Qgb2YgdGVzdCBmaWxlcyBpbnRvIGJhbGFuY2VkIGdyb3VwcyB1c2luZyBhIGdyZWVkeSBsb2FkLWJhbGFuY2luZyBhbGdvcml0aG0uXG4gKiBNb2RlbGVkIGFmdGVyIHRlc3Rfc3VpdGVfc3BsaXR0ZXIgZm9yIFJTcGVjLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUZXN0U3VpdGVTcGxpdHRlciB7XG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmdyb3VwcyAtIFRvdGFsIG51bWJlciBvZiBncm91cHMuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBhcmdzLmdyb3VwTnVtYmVyIC0gV2hpY2ggZ3JvdXAgdG8gcmV0dXJuICgxLWluZGV4ZWQpLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzLnRlc3RGaWxlcyAtIEFsbCBkaXNjb3ZlcmVkIHRlc3QgZmlsZSBwYXRocy5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmJhc2VEaXJlY3RvcnldIC0gQmFzZSBkaXJlY3RvcnkgZm9yIHJlbGF0aXZlIHBhdGggY29tcHV0YXRpb24uXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IFthcmdzLnRpbWluZ01hbmlmZXN0XSAtIFJlbGF0aXZlIHRlc3QgcGF0aHMgbWFwcGVkIHRvIGR1cmF0aW9ucy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtncm91cHMsIGdyb3VwTnVtYmVyLCB0ZXN0RmlsZXMsIGJhc2VEaXJlY3RvcnksIHRpbWluZ01hbmlmZXN0LCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGdyb3VwcykgfHwgZ3JvdXBzIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAtLWdyb3VwcyBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgZ290OiAke2dyb3Vwc31gKVxuICAgIH1cblxuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihncm91cE51bWJlcikgfHwgZ3JvdXBOdW1iZXIgPCAxIHx8IGdyb3VwTnVtYmVyID4gZ3JvdXBzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYC0tZ3JvdXAtbnVtYmVyIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAke2dyb3Vwc30sIGdvdDogJHtncm91cE51bWJlcn1gKVxuICAgIH1cblxuICAgIHRoaXMuX2dyb3VwcyA9IGdyb3Vwc1xuICAgIHRoaXMuX2dyb3VwTnVtYmVyID0gZ3JvdXBOdW1iZXJcbiAgICB0aGlzLl90ZXN0RmlsZXMgPSB0ZXN0RmlsZXNcbiAgICB0aGlzLl9iYXNlRGlyZWN0b3J5ID0gYmFzZURpcmVjdG9yeSB8fCBwcm9jZXNzLmN3ZCgpXG4gICAgdGhpcy5fdGltaW5nTWFuaWZlc3QgPSB0aGlzLm5vcm1hbGl6ZVRpbWluZ01hbmlmZXN0KHRpbWluZ01hbmlmZXN0KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHRlc3QgZmlsZXMgYXNzaWduZWQgdG8gdGhpcyBncm91cC5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIEZpbGUgcGF0aHMgZm9yIHRoZSByZXF1ZXN0ZWQgZ3JvdXAuXG4gICAqL1xuICBnZXRHcm91cEZpbGVzKCkge1xuICAgIGNvbnN0IHdlaWdodGVkID0gdGhpcy5jb21wdXRlV2VpZ2h0ZWRGaWxlcygpXG4gICAgY29uc3Qgc29ydGVkID0gdGhpcy5zb3J0QnlXZWlnaHREZXNjZW5kaW5nKHdlaWdodGVkKVxuICAgIGNvbnN0IGJ1Y2tldHMgPSB0aGlzLmRpc3RyaWJ1dGVHcmVlZGlseShzb3J0ZWQpXG5cbiAgICByZXR1cm4gYnVja2V0c1t0aGlzLl9ncm91cE51bWJlciAtIDFdLmZpbGVzXG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgd2VpZ2h0IGZvciBlYWNoIHRlc3QgZmlsZSBiYXNlZCBvbiBkaXJlY3RvcnkgdHlwZSBhbmQgZmlsZSBzdWZmaXguXG4gICAqIEByZXR1cm5zIHtTcGxpdHRlckZpbGVFbnRyeVtdfSAtIFdlaWdodGVkIGZpbGUgZW50cmllcy5cbiAgICovXG4gIGNvbXB1dGVXZWlnaHRlZEZpbGVzKCkge1xuICAgIHJldHVybiB0aGlzLl90ZXN0RmlsZXMubWFwKChmaWxlUGF0aCkgPT4gKHtcbiAgICAgIGZpbGVQYXRoLFxuICAgICAgd2VpZ2h0OiB0aGlzLmNvbXB1dGVXZWlnaHQoZmlsZVBhdGgpXG4gICAgfSkpXG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgdGhlIHdlaWdodCBmb3IgYSBzaW5nbGUgZmlsZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoIC0gQWJzb2x1dGUgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFdlaWdodCB2YWx1ZS5cbiAgICovXG4gIGNvbXB1dGVXZWlnaHQoZmlsZVBhdGgpIHtcbiAgICBjb25zdCByZWxhdGl2ZVBhdGggPSB0aGlzLm5vcm1hbGl6ZVJlbGF0aXZlUGF0aChwYXRoLnJlbGF0aXZlKHRoaXMuX2Jhc2VEaXJlY3RvcnksIGZpbGVQYXRoKSlcbiAgICBjb25zdCBwcm9qZWN0UmVsYXRpdmVQYXRoID0gdGhpcy5ub3JtYWxpemVSZWxhdGl2ZVBhdGgocGF0aC5qb2luKHBhdGguYmFzZW5hbWUodGhpcy5fYmFzZURpcmVjdG9yeSksIHJlbGF0aXZlUGF0aCkpXG4gICAgY29uc3QgZHVyYXRpb24gPSB0aGlzLl90aW1pbmdNYW5pZmVzdFtyZWxhdGl2ZVBhdGhdID8/IHRoaXMuX3RpbWluZ01hbmlmZXN0W3Byb2plY3RSZWxhdGl2ZVBhdGhdXG5cbiAgICBpZiAoZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIGR1cmF0aW9uXG4gICAgfVxuXG4gICAgbGV0IHdlaWdodCA9IERFRkFVTFRfV0VJR0hUXG5cbiAgICAvLyBFeHRyYWN0IHRoZSB0eXBlIGRpcmVjdG9yeSBmcm9tIHRoZSByZWxhdGl2ZSBwYXRoLlxuICAgIC8vIE1hdGNoZXMgYm90aCBcInNwZWMvc3lzdGVtLy4uLlwiIChiYXNlIGlzIHByb2plY3Qgcm9vdCkgYW5kIFwic3lzdGVtLy4uLlwiIChiYXNlIGlzIHNwZWMvIGl0c2VsZikuXG4gICAgY29uc3Qgc3BlY0Rpck1hdGNoID0gcmVsYXRpdmVQYXRoLm1hdGNoKC9eKD86KD86c3BlY3xfX3Rlc3RzX198dGVzdHMpXFwvKT8oW14vXSspXFwvLylcblxuICAgIGlmIChzcGVjRGlyTWF0Y2gpIHtcbiAgICAgIGNvbnN0IGRpck5hbWUgPSBzcGVjRGlyTWF0Y2hbMV1cblxuICAgICAgaWYgKERJUkVDVE9SWV9XRUlHSFRTW2Rpck5hbWVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgd2VpZ2h0ID0gRElSRUNUT1JZX1dFSUdIVFNbZGlyTmFtZV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCcm93c2VyIHNwZWMgZmlsZXMgYXJlIGhlYXZpZXJcbiAgICBpZiAoZmlsZVBhdGguZW5kc1dpdGgoXCIuYnJvd3Nlci1zcGVjLmpzXCIpIHx8IGZpbGVQYXRoLmVuZHNXaXRoKFwiLmJyb3dzZXItc3BlYy5tanNcIikpIHtcbiAgICAgIHdlaWdodCAqPSBCUk9XU0VSX1NQRUNfTVVMVElQTElFUlxuICAgIH1cblxuICAgIHJldHVybiB3ZWlnaHRcbiAgfVxuXG4gIC8qKlxuICAgKiBLZWVwcyBvbmx5IHVzYWJsZSBwb3NpdGl2ZSBmaW5pdGUgZHVyYXRpb24gZW50cmllcyBrZXllZCBieSBub3JtYWxpemVkIHJlbGF0aXZlIHBhdGguXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHRpbWluZ01hbmlmZXN0IC0gUGFyc2VkIHRpbWluZyBtYW5pZmVzdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIG51bWJlcj59IC0gVmFsaWQgbm9ybWFsaXplZCBkdXJhdGlvbiB3ZWlnaHRzLlxuICAgKi9cbiAgbm9ybWFsaXplVGltaW5nTWFuaWZlc3QodGltaW5nTWFuaWZlc3QpIHtcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59ICovXG4gICAgY29uc3Qgbm9ybWFsaXplZCA9IHt9XG5cbiAgICBpZiAoIXRpbWluZ01hbmlmZXN0IHx8IHR5cGVvZiB0aW1pbmdNYW5pZmVzdCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHRpbWluZ01hbmlmZXN0KSkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtmaWxlUGF0aCwgZHVyYXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKHRpbWluZ01hbmlmZXN0KSkge1xuICAgICAgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUoZHVyYXRpb24pICYmIGR1cmF0aW9uID4gMCkge1xuICAgICAgICBub3JtYWxpemVkW3RoaXMubm9ybWFsaXplUmVsYXRpdmVQYXRoKGZpbGVQYXRoKV0gPSBkdXJhdGlvblxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHJlbGF0aXZlIHRlc3QgcGF0aCB0byB0aGUgbWFuaWZlc3QncyBwb3J0YWJsZSBzbGFzaCBmb3JtYXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIFJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBOb3JtYWxpemVkIHJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICovXG4gIG5vcm1hbGl6ZVJlbGF0aXZlUGF0aChmaWxlUGF0aCkge1xuICAgIHJldHVybiBmaWxlUGF0aFxuICAgICAgLnJlcGxhY2VBbGwoXCJcXFxcXCIsIFwiL1wiKVxuICAgICAgLnJlcGxhY2UoL15cXC5cXC8vLCBcIlwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFNvcnRzIGZpbGVzIGJ5IHdlaWdodCBkZXNjZW5kaW5nLCB0aGVuIGJ5IHBhdGggZm9yIGRldGVybWluaXNtLlxuICAgKiBAcGFyYW0ge1NwbGl0dGVyRmlsZUVudHJ5W119IGZpbGVzIC0gV2VpZ2h0ZWQgZmlsZXMuXG4gICAqIEByZXR1cm5zIHtTcGxpdHRlckZpbGVFbnRyeVtdfSAtIFNvcnRlZCBmaWxlcy5cbiAgICovXG4gIHNvcnRCeVdlaWdodERlc2NlbmRpbmcoZmlsZXMpIHtcbiAgICByZXR1cm4gWy4uLmZpbGVzXS5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBpZiAoYi53ZWlnaHQgIT09IGEud2VpZ2h0KSB7XG4gICAgICAgIHJldHVybiBiLndlaWdodCAtIGEud2VpZ2h0XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhLmZpbGVQYXRoLmxvY2FsZUNvbXBhcmUoYi5maWxlUGF0aClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIERpc3RyaWJ1dGVzIGZpbGVzIGdyZWVkaWx5IGludG8gTiBiYWxhbmNlZCBncm91cHMuXG4gICAqIEVhY2ggZmlsZSBpcyBhc3NpZ25lZCB0byB0aGUgZ3JvdXAgd2l0aCB0aGUgbGVhc3QgYWNjdW11bGF0ZWQgd2VpZ2h0LlxuICAgKiBAcGFyYW0ge1NwbGl0dGVyRmlsZUVudHJ5W119IHNvcnRlZEZpbGVzIC0gRmlsZXMgc29ydGVkIGJ5IHdlaWdodCBkZXNjZW5kaW5nLlxuICAgKiBAcmV0dXJucyB7R3JvdXBCdWNrZXRbXX0gLSBBcnJheSBvZiBncm91cCBidWNrZXRzLlxuICAgKi9cbiAgZGlzdHJpYnV0ZUdyZWVkaWx5KHNvcnRlZEZpbGVzKSB7XG4gICAgLyoqXG4gICAgICogQnVja2V0cy5cbiAgICAgKiBAdHlwZSB7R3JvdXBCdWNrZXRbXX0gKi9cbiAgICBjb25zdCBidWNrZXRzID0gW11cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3JvdXBzOyBpKyspIHtcbiAgICAgIGJ1Y2tldHMucHVzaCh7dG90YWxXZWlnaHQ6IDAsIGZpbGVzOiBbXX0pXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3J0ZWRGaWxlcykge1xuICAgICAgY29uc3QgbGlnaHRlc3QgPSB0aGlzLmZpbmRMaWdodGVzdEJ1Y2tldChidWNrZXRzKVxuXG4gICAgICBsaWdodGVzdC5maWxlcy5wdXNoKGVudHJ5LmZpbGVQYXRoKVxuICAgICAgbGlnaHRlc3QudG90YWxXZWlnaHQgKz0gZW50cnkud2VpZ2h0XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ1Y2tldHNcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyB0aGUgYnVja2V0IHdpdGggdGhlIGxlYXN0IGFjY3VtdWxhdGVkIHdlaWdodC5cbiAgICogVGllcyBhcmUgYnJva2VuIGJ5IGJ1Y2tldCBpbmRleCAoZWFybGllciBidWNrZXQgd2lucykgZm9yIGRldGVybWluaXNtLlxuICAgKiBAcGFyYW0ge0dyb3VwQnVja2V0W119IGJ1Y2tldHMgLSBHcm91cCBidWNrZXRzLlxuICAgKiBAcmV0dXJucyB7R3JvdXBCdWNrZXR9IC0gVGhlIGxpZ2h0ZXN0IGJ1Y2tldC5cbiAgICovXG4gIGZpbmRMaWdodGVzdEJ1Y2tldChidWNrZXRzKSB7XG4gICAgbGV0IGxpZ2h0ZXN0ID0gYnVja2V0c1swXVxuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBidWNrZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYnVja2V0c1tpXS50b3RhbFdlaWdodCA8IGxpZ2h0ZXN0LnRvdGFsV2VpZ2h0KSB7XG4gICAgICAgIGxpZ2h0ZXN0ID0gYnVja2V0c1tpXVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsaWdodGVzdFxuICB9XG59XG4iXX0=
260
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1zdWl0ZS1zcGxpdHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3Rlc3Qtc3VpdGUtc3BsaXR0ZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUN2RCxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUU5Rjs7Ozs7R0FLRztBQUVIOzs7OztHQUtHO0FBRUgsOENBQThDO0FBQzlDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQTtBQUV4Qjs7OztHQUlHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRztJQUN4QixNQUFNLEVBQUUsRUFBRTtJQUNWLGlCQUFpQixFQUFFLEVBQUU7SUFDckIsVUFBVSxFQUFFLENBQUM7Q0FDZCxDQUFBO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0FBRWpDOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8saUJBQWlCO0lBQ3BDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDdEYsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM1QyxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QyxNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ3hFLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxJQUFJLFdBQVcsR0FBRyxNQUFNLEVB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RUFBRSxFQUFFLENBQUM7WUFDdEMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUE7UUFDM0MsQ0FBQztRQUVELEtBQUssTUFBTSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBRWpELFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUNuQyxRQUFRLENBQUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUE7UUFDdEMsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGtCQUFrQixDQUFDLE9BQU87UUFDeEIsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRXpCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDeEMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztnQkFDbEQsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUN2QixDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sUUFBUSxDQUFBO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcbmltcG9ydCB7IGNhbm9uaWNhbFRpbWluZ01hbmlmZXN0UGF0aCwgY29tcGFyZVRpbWluZ01hbmlmZXN0UGF0aHMgfSBmcm9tIFwiLi90aW1pbmctbWFuaWZlc3QuanNcIlxuXG4vKipcbiAqIFNwbGl0dGVyRmlsZUVudHJ5IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBTcGxpdHRlckZpbGVFbnRyeVxuICogQHByb3BlcnR5IHtzdHJpbmd9IGZpbGVQYXRoIC0gQWJzb2x1dGUgZmlsZSBwYXRoLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHdlaWdodCAtIENvbXB1dGVkIHdlaWdodCBmb3IgbG9hZCBiYWxhbmNpbmcuXG4gKi9cblxuLyoqXG4gKiBHcm91cEJ1Y2tldCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gR3JvdXBCdWNrZXRcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSB0b3RhbFdlaWdodCAtIEFjY3VtdWxhdGVkIHdlaWdodC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IGZpbGVzIC0gRmlsZXMgYXNzaWduZWQgdG8gdGhpcyBncm91cC5cbiAqL1xuXG4vKiogRGVmYXVsdCB3ZWlnaHQgZm9yIGEgcmVndWxhciB0ZXN0IGZpbGUuICovXG5jb25zdCBERUZBVUxUX1dFSUdIVCA9IDFcblxuLyoqXG4gKiBXZWlnaHQgbXVsdGlwbGllcnMgYnkgc3BlYyBkaXJlY3RvcnkgbmFtZS5cbiAqIEhlYXZpZXIgdGVzdCB0eXBlcyBnZXQgaGlnaGVyIHdlaWdodHMgc28gZ3JlZWR5IGRpc3RyaWJ1dGlvbiBiYWxhbmNlcyB3YWxsLWNsb2NrIHRpbWUuXG4gKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgbnVtYmVyPn1cbiAqL1xuY29uc3QgRElSRUNUT1JZX1dFSUdIVFMgPSB7XG4gIHN5c3RlbTogMjAsXG4gIFwiZnJvbnRlbmQtbW9kZWxzXCI6IDEwLFxuICBjb250cm9sbGVyOiAzXG59XG5cbi8qKiBFeHRyYSBtdWx0aXBsaWVyIGFwcGxpZWQgdG8gYnJvd3NlciBzcGVjIGZpbGVzIG9uIHRvcCBvZiBkaXJlY3Rvcnkgd2VpZ2h0LiAqL1xuY29uc3QgQlJPV1NFUl9TUEVDX01VTFRJUExJRVIgPSAyXG5cbi8qKlxuICogU3BsaXRzIGEgbGlzdCBvZiB0ZXN0IGZpbGVzIGludG8gYmFsYW5jZWQgZ3JvdXBzIHVzaW5nIGEgZ3JlZWR5IGxvYWQtYmFsYW5jaW5nIGFsZ29yaXRobS5cbiAqIE1vZGVsZWQgYWZ0ZXIgdGVzdF9zdWl0ZV9zcGxpdHRlciBmb3IgUlNwZWMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RTdWl0ZVNwbGl0dGVyIHtcbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuZ3JvdXBzIC0gVG90YWwgbnVtYmVyIG9mIGdyb3Vwcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFyZ3MuZ3JvdXBOdW1iZXIgLSBXaGljaCBncm91cCB0byByZXR1cm4gKDEtaW5kZXhlZCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MudGVzdEZpbGVzIC0gQWxsIGRpc2NvdmVyZWQgdGVzdCBmaWxlIHBhdGhzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYmFzZURpcmVjdG9yeV0gLSBCYXNlIGRpcmVjdG9yeSBmb3IgcmVsYXRpdmUgcGF0aCBjb21wdXRhdGlvbi5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gW2FyZ3MudGltaW5nTWFuaWZlc3RdIC0gUmVsYXRpdmUgdGVzdCBwYXRocyBtYXBwZWQgdG8gZHVyYXRpb25zLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2dyb3VwcywgZ3JvdXBOdW1iZXIsIHRlc3RGaWxlcywgYmFzZURpcmVjdG9yeSwgdGltaW5nTWFuaWZlc3QsIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIoZ3JvdXBzKSB8fCBncm91cHMgPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYC0tZ3JvdXBzIG11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyLCBnb3Q6ICR7Z3JvdXBzfWApXG4gICAgfVxuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGdyb3VwTnVtYmVyKSB8fCBncm91cE51bWJlciA8IDEgfHwgZ3JvdXBOdW1iZXIgPiBncm91cHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgLS1ncm91cC1udW1iZXIgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kICR7Z3JvdXBzfSwgZ290OiAke2dyb3VwTnVtYmVyfWApXG4gICAgfVxuXG4gICAgdGhpcy5fZ3JvdXBzID0gZ3JvdXBzXG4gICAgdGhpcy5fZ3JvdXBOdW1iZXIgPSBncm91cE51bWJlclxuICAgIHRoaXMuX3Rlc3RGaWxlcyA9IHRlc3RGaWxlc1xuICAgIHRoaXMuX2Jhc2VEaXJlY3RvcnkgPSBiYXNlRGlyZWN0b3J5IHx8IHByb2Nlc3MuY3dkKClcbiAgICB0aGlzLl90aW1pbmdNYW5pZmVzdCA9IHRoaXMubm9ybWFsaXplVGltaW5nTWFuaWZlc3QodGltaW5nTWFuaWZlc3QpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgdGVzdCBmaWxlcyBhc3NpZ25lZCB0byB0aGlzIGdyb3VwLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gRmlsZSBwYXRocyBmb3IgdGhlIHJlcXVlc3RlZCBncm91cC5cbiAgICovXG4gIGdldEdyb3VwRmlsZXMoKSB7XG4gICAgY29uc3Qgd2VpZ2h0ZWQgPSB0aGlzLmNvbXB1dGVXZWlnaHRlZEZpbGVzKClcbiAgICBjb25zdCBzb3J0ZWQgPSB0aGlzLnNvcnRCeVdlaWdodERlc2NlbmRpbmcod2VpZ2h0ZWQpXG4gICAgY29uc3QgYnVja2V0cyA9IHRoaXMuZGlzdHJpYnV0ZUdyZWVkaWx5KHNvcnRlZClcblxuICAgIHJldHVybiBidWNrZXRzW3RoaXMuX2dyb3VwTnVtYmVyIC0gMV0uZmlsZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB3ZWlnaHQgZm9yIGVhY2ggdGVzdCBmaWxlIGJhc2VkIG9uIGRpcmVjdG9yeSB0eXBlIGFuZCBmaWxlIHN1ZmZpeC5cbiAgICogQHJldHVybnMge1NwbGl0dGVyRmlsZUVudHJ5W119IC0gV2VpZ2h0ZWQgZmlsZSBlbnRyaWVzLlxuICAgKi9cbiAgY29tcHV0ZVdlaWdodGVkRmlsZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rlc3RGaWxlcy5tYXAoKGZpbGVQYXRoKSA9PiAoe1xuICAgICAgZmlsZVBhdGgsXG4gICAgICB3ZWlnaHQ6IHRoaXMuY29tcHV0ZVdlaWdodChmaWxlUGF0aClcbiAgICB9KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlcyB0aGUgd2VpZ2h0IGZvciBhIHNpbmdsZSBmaWxlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGggLSBBYnNvbHV0ZSBmaWxlIHBhdGguXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gV2VpZ2h0IHZhbHVlLlxuICAgKi9cbiAgY29tcHV0ZVdlaWdodChmaWxlUGF0aCkge1xuICAgIGNvbnN0IGR1cmF0aW9uID0gdGhpcy50aW1pbmdNYW5pZmVzdER1cmF0aW9uKGZpbGVQYXRoKVxuXG4gICAgaWYgKGR1cmF0aW9uICE9PSB1bmRlZmluZWQgJiYgZHVyYXRpb24gPiAwKSB7XG4gICAgICByZXR1cm4gZHVyYXRpb25cbiAgICB9XG5cbiAgICBjb25zdCByZWxhdGl2ZVBhdGggPSB0aGlzLmhldXJpc3RpY1JlbGF0aXZlUGF0aChmaWxlUGF0aClcbiAgICBsZXQgd2VpZ2h0ID0gREVGQVVMVF9XRUlHSFRcblxuICAgIC8vIEV4dHJhY3QgdGhlIHR5cGUgZGlyZWN0b3J5IGZyb20gdGhlIHJlbGF0aXZlIHBhdGguXG4gICAgLy8gTWF0Y2hlcyBib3RoIFwic3BlYy9zeXN0ZW0vLi4uXCIgKGJhc2UgaXMgcHJvamVjdCByb290KSBhbmQgXCJzeXN0ZW0vLi4uXCIgKGJhc2UgaXMgc3BlYy8gaXRzZWxmKS5cbiAgICBjb25zdCBzcGVjRGlyTWF0Y2ggPSByZWxhdGl2ZVBhdGgubWF0Y2goL14oPzooPzpzcGVjfF9fdGVzdHNfX3x0ZXN0cylcXC8pPyhbXi9dKylcXC8vKVxuXG4gICAgaWYgKHNwZWNEaXJNYXRjaCkge1xuICAgICAgY29uc3QgZGlyTmFtZSA9IHNwZWNEaXJNYXRjaFsxXVxuXG4gICAgICBpZiAoRElSRUNUT1JZX1dFSUdIVFNbZGlyTmFtZV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB3ZWlnaHQgPSBESVJFQ1RPUllfV0VJR0hUU1tkaXJOYW1lXVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEJyb3dzZXIgc3BlYyBmaWxlcyBhcmUgaGVhdmllclxuICAgIGlmIChmaWxlUGF0aC5lbmRzV2l0aChcIi5icm93c2VyLXNwZWMuanNcIikgfHwgZmlsZVBhdGguZW5kc1dpdGgoXCIuYnJvd3Nlci1zcGVjLm1qc1wiKSkge1xuICAgICAgd2VpZ2h0ICo9IEJST1dTRVJfU1BFQ19NVUxUSVBMSUVSXG4gICAgfVxuXG4gICAgcmV0dXJuIHdlaWdodFxuICB9XG5cbiAgLyoqXG4gICAqIEtlZXBzIG9ubHkgdXNhYmxlIHBvc2l0aXZlIGZpbml0ZSBkdXJhdGlvbiBlbnRyaWVzIGtleWVkIGJ5IG5vcm1hbGl6ZWQgcmVsYXRpdmUgcGF0aC5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gdGltaW5nTWFuaWZlc3QgLSBQYXJzZWQgdGltaW5nIG1hbmlmZXN0LlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgbnVtYmVyPn0gLSBWYWxpZCBub3JtYWxpemVkIGR1cmF0aW9uIHdlaWdodHMuXG4gICAqL1xuICBub3JtYWxpemVUaW1pbmdNYW5pZmVzdCh0aW1pbmdNYW5pZmVzdCkge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgbnVtYmVyPn0gKi9cbiAgICBjb25zdCBub3JtYWxpemVkID0ge31cblxuICAgIGlmICghdGltaW5nTWFuaWZlc3QgfHwgdHlwZW9mIHRpbWluZ01hbmlmZXN0ICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodGltaW5nTWFuaWZlc3QpKSB7XG4gICAgICByZXR1cm4gbm9ybWFsaXplZFxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBkdXJhdGlvbl0gb2YgT2JqZWN0LmVudHJpZXModGltaW5nTWFuaWZlc3QpKSB7XG4gICAgICBpZiAodHlwZW9mIGR1cmF0aW9uICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNGaW5pdGUoZHVyYXRpb24pIHx8IGR1cmF0aW9uIDwgMCkgY29udGludWVcblxuICAgICAgdHJ5IHtcbiAgICAgICAgbm9ybWFsaXplZFt0aGlzLm5vcm1hbGl6ZVJlbGF0aXZlUGF0aChmaWxlUGF0aCldID0gZHVyYXRpb25cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGlmICghKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpKSB0aHJvdyBlcnJvclxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHJlbGF0aXZlIHRlc3QgcGF0aCB0byB0aGUgbWFuaWZlc3QncyBwb3J0YWJsZSBzbGFzaCBmb3JtYXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIFJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBOb3JtYWxpemVkIHJlbGF0aXZlIHRlc3QgcGF0aC5cbiAgICovXG4gIG5vcm1hbGl6ZVJlbGF0aXZlUGF0aChmaWxlUGF0aCkge1xuICAgIHJldHVybiBjYW5vbmljYWxUaW1pbmdNYW5pZmVzdFBhdGgoZmlsZVBhdGgpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcGVybWlzc2l2ZSByZWxhdGl2ZSBwYXRoIHVzZWQgb25seSBmb3IgaGV1cmlzdGljIGNsYXNzaWZpY2F0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZVBhdGggLSBBYnNvbHV0ZSB0ZXN0IGZpbGUgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBQb3J0YWJsZSByZWxhdGl2ZSBwYXRoIHdoaWNoIG1heSBlc2NhcGUgdGhlIHByb2ZpbGluZyBiYXNlLlxuICAgKi9cbiAgaGV1cmlzdGljUmVsYXRpdmVQYXRoKGZpbGVQYXRoKSB7XG4gICAgcmV0dXJuIHBhdGgucmVsYXRpdmUodGhpcy5fYmFzZURpcmVjdG9yeSwgZmlsZVBhdGgpXG4gICAgICAucmVwbGFjZUFsbChcIlxcXFxcIiwgXCIvXCIpXG4gICAgICAucmVwbGFjZSgvXlxcLlxcLy8sIFwiXCIpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGNhbm9uaWNhbCBtYW5pZmVzdCBrZXkgd2hlbiB0aGUgZmlsZSBpcyByZXByZXNlbnRhYmxlIHVuZGVyIHRoZSBwcm9maWxpbmcgYmFzZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVQYXRoIC0gQWJzb2x1dGUgdGVzdCBmaWxlIHBhdGguXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCB1bmRlZmluZWR9IC0gQ2Fub25pY2FsIHJlbGF0aXZlIHBhdGgsIG9yIHVuZGVmaW5lZCBmb3IgYW4gZXh0ZXJuYWwgZmlsZS5cbiAgICovXG4gIG1hbmlmZXN0UmVsYXRpdmVQYXRoKGZpbGVQYXRoKSB7XG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLl9iYXNlRGlyZWN0b3J5LCBmaWxlUGF0aClcblxuICAgIGlmICghcmVsYXRpdmVQYXRoIHx8IHBhdGguaXNBYnNvbHV0ZShyZWxhdGl2ZVBhdGgpKSByZXR1cm5cbiAgICBpZiAocmVsYXRpdmVQYXRoID09PSBcIi4uXCIgfHwgcmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoYC4uJHtwYXRoLnNlcH1gKSkgcmV0dXJuXG5cbiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemVSZWxhdGl2ZVBhdGgocmVsYXRpdmVQYXRoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGZpcnN0IG1hbmlmZXN0IGVudHJ5IG1hdGNoaW5nIGEgZGlzY292ZXJlZCB0ZXN0IGZpbGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIEFic29sdXRlIHRlc3QgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgdW5kZWZpbmVkfSAtIFJlY29yZGVkIGR1cmF0aW9uLCBpbmNsdWRpbmcgemVyby5cbiAgICovXG4gIHRpbWluZ01hbmlmZXN0RHVyYXRpb24oZmlsZVBhdGgpIHtcbiAgICBmb3IgKGNvbnN0IG1hbmlmZXN0UGF0aCBvZiB0aGlzLnRpbWluZ01hbmlmZXN0UGF0aHMoZmlsZVBhdGgpKSB7XG4gICAgICBpZiAoT2JqZWN0Lmhhc093bih0aGlzLl90aW1pbmdNYW5pZmVzdCwgbWFuaWZlc3RQYXRoKSkgcmV0dXJuIHRoaXMuX3RpbWluZ01hbmlmZXN0W21hbmlmZXN0UGF0aF1cbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBjb21wYXRpYmxlIG1hbmlmZXN0IGtleXMgZm9yIG9uZSBkaXNjb3ZlcmVkIGZpbGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCAtIEFic29sdXRlIHRlc3QgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gQ2Fub25pY2FsIGtleXMgaW4gbWF0Y2hpbmcgcHJpb3JpdHkgb3JkZXIuXG4gICAqL1xuICB0aW1pbmdNYW5pZmVzdFBhdGhzKGZpbGVQYXRoKSB7XG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gdGhpcy5tYW5pZmVzdFJlbGF0aXZlUGF0aChmaWxlUGF0aClcblxuICAgIGlmICghcmVsYXRpdmVQYXRoKSByZXR1cm4gW11cblxuICAgIGNvbnN0IHByb2plY3RSZWxhdGl2ZVBhdGggPSB0aGlzLm5vcm1hbGl6ZVJlbGF0aXZlUGF0aChwYXRoLmpvaW4ocGF0aC5iYXNlbmFtZSh0aGlzLl9iYXNlRGlyZWN0b3J5KSwgcmVsYXRpdmVQYXRoKSlcblxuICAgIHJldHVybiByZWxhdGl2ZVBhdGggPT09IHByb2plY3RSZWxhdGl2ZVBhdGggPyBbcmVsYXRpdmVQYXRoXSA6IFtyZWxhdGl2ZVBhdGgsIHByb2plY3RSZWxhdGl2ZVBhdGhdXG4gIH1cblxuICAvKipcbiAgICogU3VtbWFyaXplcyB0aW1pbmctaGlzdG9yeSBjb3ZlcmFnZSBmb3IgdGhlIGNvbXBsZXRlIGRpc2NvdmVyZWQgc3VpdGUuXG4gICAqIEByZXR1cm5zIHt7aGV1cmlzdGljRmlsZXM6IG51bWJlciwgbWVhc3VyZWRGaWxlczogbnVtYmVyLCBzdGFsZUVudHJpZXM6IG51bWJlcn19IC0gQ29tcGFjdCBjb3ZlcmFnZSBjb3VudHMuXG4gICAqL1xuICBnZXRUaW1pbmdNYW5pZmVzdENvdmVyYWdlKCkge1xuICAgIGNvbnN0IG1hdGNoZWRNYW5pZmVzdFBhdGhzID0gbmV3IFNldCgpXG4gICAgbGV0IG1lYXN1cmVkRmlsZXMgPSAwXG5cbiAgICBmb3IgKGNvbnN0IGZpbGVQYXRoIG9mIHRoaXMuX3Rlc3RGaWxlcykge1xuICAgICAgbGV0IG1hdGNoZWREdXJhdGlvblxuXG4gICAgICBmb3IgKGNvbnN0IG1hbmlmZXN0UGF0aCBvZiB0aGlzLnRpbWluZ01hbmlmZXN0UGF0aHMoZmlsZVBhdGgpKSB7XG4gICAgICAgIGlmICghT2JqZWN0Lmhhc093bih0aGlzLl90aW1pbmdNYW5pZmVzdCwgbWFuaWZlc3RQYXRoKSkgY29udGludWVcblxuICAgICAgICBtYXRjaGVkTWFuaWZlc3RQYXRocy5hZGQobWFuaWZlc3RQYXRoKVxuICAgICAgICBtYXRjaGVkRHVyYXRpb24gPSB0aGlzLl90aW1pbmdNYW5pZmVzdFttYW5pZmVzdFBhdGhdXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG5cbiAgICAgIGlmIChtYXRjaGVkRHVyYXRpb24gIT09IHVuZGVmaW5lZCAmJiBtYXRjaGVkRHVyYXRpb24gPiAwKSBtZWFzdXJlZEZpbGVzKytcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaGV1cmlzdGljRmlsZXM6IHRoaXMuX3Rlc3RGaWxlcy5sZW5ndGggLSBtZWFzdXJlZEZpbGVzLFxuICAgICAgbWVhc3VyZWRGaWxlcyxcbiAgICAgIHN0YWxlRW50cmllczogT2JqZWN0LmtleXModGhpcy5fdGltaW5nTWFuaWZlc3QpLmxlbmd0aCAtIG1hdGNoZWRNYW5pZmVzdFBhdGhzLnNpemVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU29ydHMgZmlsZXMgYnkgd2VpZ2h0IGRlc2NlbmRpbmcsIHRoZW4gYnkgcGF0aCBmb3IgZGV0ZXJtaW5pc20uXG4gICAqIEBwYXJhbSB7U3BsaXR0ZXJGaWxlRW50cnlbXX0gZmlsZXMgLSBXZWlnaHRlZCBmaWxlcy5cbiAgICogQHJldHVybnMge1NwbGl0dGVyRmlsZUVudHJ5W119IC0gU29ydGVkIGZpbGVzLlxuICAgKi9cbiAgc29ydEJ5V2VpZ2h0RGVzY2VuZGluZyhmaWxlcykge1xuICAgIHJldHVybiBbLi4uZmlsZXNdLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGlmIChiLndlaWdodCAhPT0gYS53ZWlnaHQpIHtcbiAgICAgICAgcmV0dXJuIGIud2VpZ2h0IC0gYS53ZWlnaHRcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbXBhcmVUaW1pbmdNYW5pZmVzdFBhdGhzKGEuZmlsZVBhdGgsIGIuZmlsZVBhdGgpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXN0cmlidXRlcyBmaWxlcyBncmVlZGlseSBpbnRvIE4gYmFsYW5jZWQgZ3JvdXBzLlxuICAgKiBFYWNoIGZpbGUgaXMgYXNzaWduZWQgdG8gdGhlIGdyb3VwIHdpdGggdGhlIGxlYXN0IGFjY3VtdWxhdGVkIHdlaWdodC5cbiAgICogQHBhcmFtIHtTcGxpdHRlckZpbGVFbnRyeVtdfSBzb3J0ZWRGaWxlcyAtIEZpbGVzIHNvcnRlZCBieSB3ZWlnaHQgZGVzY2VuZGluZy5cbiAgICogQHJldHVybnMge0dyb3VwQnVja2V0W119IC0gQXJyYXkgb2YgZ3JvdXAgYnVja2V0cy5cbiAgICovXG4gIGRpc3RyaWJ1dGVHcmVlZGlseShzb3J0ZWRGaWxlcykge1xuICAgIC8qKlxuICAgICAqIEJ1Y2tldHMuXG4gICAgICogQHR5cGUge0dyb3VwQnVja2V0W119ICovXG4gICAgY29uc3QgYnVja2V0cyA9IFtdXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2dyb3VwczsgaSsrKSB7XG4gICAgICBidWNrZXRzLnB1c2goe3RvdGFsV2VpZ2h0OiAwLCBmaWxlczogW119KVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZW50cnkgb2Ygc29ydGVkRmlsZXMpIHtcbiAgICAgIGNvbnN0IGxpZ2h0ZXN0ID0gdGhpcy5maW5kTGlnaHRlc3RCdWNrZXQoYnVja2V0cylcblxuICAgICAgbGlnaHRlc3QuZmlsZXMucHVzaChlbnRyeS5maWxlUGF0aClcbiAgICAgIGxpZ2h0ZXN0LnRvdGFsV2VpZ2h0ICs9IGVudHJ5LndlaWdodFxuICAgIH1cblxuICAgIHJldHVybiBidWNrZXRzXG4gIH1cblxuICAvKipcbiAgICogRmluZHMgdGhlIGJ1Y2tldCB3aXRoIHRoZSBsZWFzdCBhY2N1bXVsYXRlZCB3ZWlnaHQuXG4gICAqIFRpZXMgYXJlIGJyb2tlbiBieSBidWNrZXQgaW5kZXggKGVhcmxpZXIgYnVja2V0IHdpbnMpIGZvciBkZXRlcm1pbmlzbS5cbiAgICogQHBhcmFtIHtHcm91cEJ1Y2tldFtdfSBidWNrZXRzIC0gR3JvdXAgYnVja2V0cy5cbiAgICogQHJldHVybnMge0dyb3VwQnVja2V0fSAtIFRoZSBsaWdodGVzdCBidWNrZXQuXG4gICAqL1xuICBmaW5kTGlnaHRlc3RCdWNrZXQoYnVja2V0cykge1xuICAgIGxldCBsaWdodGVzdCA9IGJ1Y2tldHNbMF1cblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYnVja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGJ1Y2tldHNbaV0udG90YWxXZWlnaHQgPCBsaWdodGVzdC50b3RhbFdlaWdodCkge1xuICAgICAgICBsaWdodGVzdCA9IGJ1Y2tldHNbaV1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGlnaHRlc3RcbiAgfVxufVxuIl19
@@ -0,0 +1,94 @@
1
+ export type TimingManifest = Record<string, number>;
2
+ export type ValidatedProfileShard = {
3
+ /**
4
+ * - Complete pre-shard file count.
5
+ */
6
+ discoveredFileCount: number;
7
+ /**
8
+ * - Selected post-shard file count.
9
+ */
10
+ fileCount: number;
11
+ /**
12
+ * - One-indexed shard number.
13
+ */
14
+ groupNumber: number;
15
+ /**
16
+ * - Complete shard count.
17
+ */
18
+ groups: number;
19
+ /**
20
+ * - Profiling path-base semantics.
21
+ */
22
+ pathBase: string;
23
+ /**
24
+ * - Complete canonical file-set identity.
25
+ */
26
+ testFileSetHash: string;
27
+ /**
28
+ * - Canonical shard timing map.
29
+ */
30
+ timingManifest: TimingManifest;
31
+ };
32
+ export type TestProfileTimingManifestInput = {
33
+ /**
34
+ * - Parsed rich test profile.
35
+ */
36
+ profile: ReturnType<typeof JSON.parse>;
37
+ /**
38
+ * - Human-readable input source for validation errors.
39
+ */
40
+ source: string;
41
+ };
42
+ /** @typedef {Record<string, number>} TimingManifest */
43
+ /**
44
+ * ValidatedProfileShard type.
45
+ * @typedef {object} ValidatedProfileShard
46
+ * @property {number} discoveredFileCount - Complete pre-shard file count.
47
+ * @property {number} fileCount - Selected post-shard file count.
48
+ * @property {number} groupNumber - One-indexed shard number.
49
+ * @property {number} groups - Complete shard count.
50
+ * @property {string} pathBase - Profiling path-base semantics.
51
+ * @property {string} testFileSetHash - Complete canonical file-set identity.
52
+ * @property {TimingManifest} timingManifest - Canonical shard timing map.
53
+ */
54
+ /**
55
+ * TestProfileTimingManifestInput type.
56
+ * @typedef {object} TestProfileTimingManifestInput
57
+ * @property {ReturnType<typeof JSON.parse>} profile - Parsed rich test profile.
58
+ * @property {string} source - Human-readable input source for validation errors.
59
+ */
60
+ /**
61
+ * Canonicalizes a timing-manifest path relative to its profiling base.
62
+ * @param {string} filePath - Candidate relative path.
63
+ * @returns {string} - Portable canonical path.
64
+ */
65
+ export declare function canonicalTimingManifestPath(filePath: string): string;
66
+ /**
67
+ * Compares timing-manifest paths by JavaScript code units without locale rules.
68
+ * @param {string} filePathA - First path.
69
+ * @param {string} filePathB - Second path.
70
+ * @returns {number} - Negative, zero, or positive ordering result.
71
+ */
72
+ export declare function compareTimingManifestPaths(filePathA: string, filePathB: string): number;
73
+ /**
74
+ * Validates and sorts a plain timing manifest.
75
+ * @param {ReturnType<typeof JSON.parse>} timingManifest - Parsed timing manifest.
76
+ * @param {{source?: string}} [options] - Validation context.
77
+ * @returns {TimingManifest} - Canonical sorted timing manifest.
78
+ */
79
+ export declare function validateTimingManifest(timingManifest: ReturnType<typeof JSON.parse>, { source }?: {
80
+ source?: string;
81
+ }): TimingManifest;
82
+ /**
83
+ * Returns an opaque deterministic identity for a complete canonical test-file set.
84
+ * @param {string[]} filePaths - Paths relative to one profiling base.
85
+ * @returns {string} - SHA-256 file-set identity.
86
+ */
87
+ export declare function timingManifestFileSetHash(filePaths: string[]): string;
88
+ /**
89
+ * Merges a complete compatible set of rich Velocious shard profiles.
90
+ * @param {TestProfileTimingManifestInput[]} inputs - Parsed profile documents and sources.
91
+ * @returns {TimingManifest} - Complete sorted plain timing manifest.
92
+ */
93
+ export declare function mergeTestProfileTimingManifests(inputs: TestProfileTimingManifestInput[]): TimingManifest;
94
+ //# sourceMappingURL=timing-manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timing-manifest.d.ts","sourceRoot":"","sources":["../../../src/testing/timing-manifest.js"],"names":[],"mappings":"AAII,YAAkC,cAAc,GAAtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAgB;AAIjD,YAAkB,qBAAqB,GACvC;;;;IAAmB,mBAAmB,EAA3B,MAAM,CACjB;;;;IAAmB,SAAS,EAAjB,MAAM,CACjB;;;;IAAmB,WAAW,EAAnB,MAAM,CACjB;;;;IAAmB,MAAM,EAAd,MAAM,CACjB;;;;IAAmB,QAAQ,EAAhB,MAAM,CACjB;;;;IAAmB,eAAe,EAAvB,MAAM,CACjB;;;;IAA2B,cAAc,EAA9B,cAAc,CAC3B;CAAA,CAAA;AAIE,YAAkB,8BAA8B,GAChD;;;;IAA0C,OAAO,EAAtC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACxC;;;;IAAmB,MAAM,EAAd,MAAM,CACnB;CAAA,CAAA;AAnBD,uDAAuD;AAEvD;;;;;;;;;;GAUG;AAEH;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAHzC,MAGyC,GAFvC,MAAM,CAmClB;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAJzC,MAIyC,EAAE,SAAS,EAHpD,MAGoD,GAFlD,MAAM,CAMlB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAJ1C,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAIc,EAAE,EAAC,MAA0B,EAAC,AAHhF,CACA,EADQ;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAG6D,GAF3E,cAAc,CA8B1B;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAHxC,MAAM,EAGkC,GAFtC,MAAM,CAQlB;AAqKD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAH3C,8BAA8B,EAGa,GAFzC,cAAc,CAqD1B"}