@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +418 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +724 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +128 -6
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/region-editor-api.contract.d.ts +84 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +133 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +12 -4
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +138 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +206 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +31 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/** Points per line at most: the longest line is resampled at about one point per `step` px. */
|
|
2
|
+
const MAX_POINTS = 2048;
|
|
3
|
+
/** Points per line when matching lines across slices. */
|
|
4
|
+
const MATCH_POINTS = 32;
|
|
5
|
+
/**
|
|
6
|
+
* The sheet through `slices`' lines, in image pixels (x, y) and slice indices (z: slice k's line at
|
|
7
|
+
* z = k). Every line is resampled at the same number of points, evenly along its length (about one
|
|
8
|
+
* per `step` px of the longest), so a line shared by the strips above and below it is one row of
|
|
9
|
+
* vertices. Lines are matched between neighbouring slices closest first, each at most once, and only
|
|
10
|
+
* when their boxes overlap; a line without a match ends the sheet there. Empty without two slices
|
|
11
|
+
* with lines.
|
|
12
|
+
*/
|
|
13
|
+
export function loftLines(slices, step = 1) {
|
|
14
|
+
const stack = slices
|
|
15
|
+
.map((s) => ({ z: s.z, lines: s.lines.filter((l) => l.length >= 4) }))
|
|
16
|
+
.filter((s) => s.lines.length)
|
|
17
|
+
.sort((a, b) => a.z - b.z);
|
|
18
|
+
if (stack.length < 2)
|
|
19
|
+
return { vertices: new Float32Array(0), faces: new Uint32Array(0) };
|
|
20
|
+
let longest = 0;
|
|
21
|
+
for (const s of stack)
|
|
22
|
+
for (const l of s.lines)
|
|
23
|
+
longest = Math.max(longest, lineLength(l));
|
|
24
|
+
const n = Math.min(MAX_POINTS, Math.max(2, Math.ceil(longest / Math.max(step, 1e-6)) + 1));
|
|
25
|
+
// Each line's resampled points, once: rows of n vertices.
|
|
26
|
+
const rows = [];
|
|
27
|
+
const verts = [];
|
|
28
|
+
for (const s of stack) {
|
|
29
|
+
rows.push(s.lines.map((l) => {
|
|
30
|
+
const first = verts.length / 3;
|
|
31
|
+
const pts = resample(l, n);
|
|
32
|
+
for (let i = 0; i < n; i++)
|
|
33
|
+
verts.push(pts[2 * i], pts[2 * i + 1], s.z);
|
|
34
|
+
return { first, probe: resample(l, MATCH_POINTS), box: lineBox(l) };
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
const faces = [];
|
|
38
|
+
for (let k = 0; k + 1 < rows.length; k++) {
|
|
39
|
+
for (const { a, b, reversed } of matchLines(rows[k], rows[k + 1])) {
|
|
40
|
+
const at = (i) => b.first + (reversed ? n - 1 - i : i);
|
|
41
|
+
for (let i = 0; i + 1 < n; i++) {
|
|
42
|
+
const a0 = a.first + i, a1 = a0 + 1, b0 = at(i), b1 = at(i + 1);
|
|
43
|
+
faces.push(a0, b0, a1, a1, b0, b1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (!faces.length)
|
|
48
|
+
return { vertices: new Float32Array(0), faces: new Uint32Array(0) };
|
|
49
|
+
return { vertices: Float32Array.from(verts), faces: Uint32Array.from(faces) };
|
|
50
|
+
}
|
|
51
|
+
/** Pairs of lines of two neighbouring slices: closest first (mean distance, either direction), each once. */
|
|
52
|
+
function matchLines(as, bs) {
|
|
53
|
+
const pairs = [];
|
|
54
|
+
as.forEach((a, i) => bs.forEach((b, j) => {
|
|
55
|
+
if (!boxesOverlap(a.box, b.box))
|
|
56
|
+
return;
|
|
57
|
+
const forward = meanDistance(a.probe, b.probe, false);
|
|
58
|
+
const backward = meanDistance(a.probe, b.probe, true);
|
|
59
|
+
pairs.push({ a: i, b: j, cost: Math.min(forward, backward), reversed: backward < forward });
|
|
60
|
+
}));
|
|
61
|
+
pairs.sort((p, q) => p.cost - q.cost);
|
|
62
|
+
const usedA = new Set();
|
|
63
|
+
const usedB = new Set();
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const p of pairs) {
|
|
66
|
+
if (usedA.has(p.a) || usedB.has(p.b))
|
|
67
|
+
continue;
|
|
68
|
+
usedA.add(p.a);
|
|
69
|
+
usedB.add(p.b);
|
|
70
|
+
out.push({ a: as[p.a], b: bs[p.b], reversed: p.reversed });
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function meanDistance(a, b, reversed) {
|
|
75
|
+
const n = a.length >> 1;
|
|
76
|
+
let sum = 0;
|
|
77
|
+
for (let i = 0; i < n; i++) {
|
|
78
|
+
const j = reversed ? n - 1 - i : i;
|
|
79
|
+
sum += Math.hypot(a[2 * i] - b[2 * j], a[2 * i + 1] - b[2 * j + 1]);
|
|
80
|
+
}
|
|
81
|
+
return sum / n;
|
|
82
|
+
}
|
|
83
|
+
/** `n` points evenly spaced along the polyline, both ends kept. */
|
|
84
|
+
function resample(line, n) {
|
|
85
|
+
const m = line.length >> 1;
|
|
86
|
+
const cumulative = new Float64Array(m);
|
|
87
|
+
for (let i = 1; i < m; i++) {
|
|
88
|
+
cumulative[i] =
|
|
89
|
+
cumulative[i - 1] + Math.hypot(line[2 * i] - line[2 * i - 2], line[2 * i + 1] - line[2 * i - 1]);
|
|
90
|
+
}
|
|
91
|
+
const total = cumulative[m - 1];
|
|
92
|
+
const out = new Float64Array(2 * n);
|
|
93
|
+
let seg = 1;
|
|
94
|
+
for (let i = 0; i < n; i++) {
|
|
95
|
+
const d = n === 1 ? 0 : (total * i) / (n - 1);
|
|
96
|
+
while (seg < m - 1 && cumulative[seg] < d)
|
|
97
|
+
seg++;
|
|
98
|
+
const span = cumulative[seg] - cumulative[seg - 1];
|
|
99
|
+
const t = span > 0 ? Math.min(1, Math.max(0, (d - cumulative[seg - 1]) / span)) : 0;
|
|
100
|
+
out[2 * i] = line[2 * seg - 2] + t * (line[2 * seg] - line[2 * seg - 2]);
|
|
101
|
+
out[2 * i + 1] = line[2 * seg - 1] + t * (line[2 * seg + 1] - line[2 * seg - 1]);
|
|
102
|
+
}
|
|
103
|
+
return out;
|
|
104
|
+
}
|
|
105
|
+
function lineLength(line) {
|
|
106
|
+
let len = 0;
|
|
107
|
+
for (let i = 2; i + 1 < line.length; i += 2)
|
|
108
|
+
len += Math.hypot(line[i] - line[i - 2], line[i + 1] - line[i - 1]);
|
|
109
|
+
return len;
|
|
110
|
+
}
|
|
111
|
+
function lineBox(line) {
|
|
112
|
+
const box = [Infinity, Infinity, -Infinity, -Infinity];
|
|
113
|
+
for (let i = 0; i + 1 < line.length; i += 2) {
|
|
114
|
+
box[0] = Math.min(box[0], line[i]);
|
|
115
|
+
box[1] = Math.min(box[1], line[i + 1]);
|
|
116
|
+
box[2] = Math.max(box[2], line[i]);
|
|
117
|
+
box[3] = Math.max(box[3], line[i + 1]);
|
|
118
|
+
}
|
|
119
|
+
return box;
|
|
120
|
+
}
|
|
121
|
+
/** Whether the boxes overlap, each grown by a tenth of its larger side (a flat line has a thin box). */
|
|
122
|
+
function boxesOverlap(a, b) {
|
|
123
|
+
const ga = 0.1 * Math.max(a[2] - a[0], a[3] - a[1]);
|
|
124
|
+
const gb = 0.1 * Math.max(b[2] - b[0], b[3] - b[1]);
|
|
125
|
+
const g = ga + gb;
|
|
126
|
+
return a[0] - g <= b[2] && b[0] - g <= a[2] && a[1] - g <= b[3] && b[1] - g <= a[3];
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9mdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZ2VvbWV0cnkvbG9mdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlQSwrRkFBK0Y7QUFDL0YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLHlEQUF5RDtBQUN6RCxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7QUFFeEI7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsTUFBNkIsRUFBRSxJQUFJLEdBQUcsQ0FBQztJQUMvRCxNQUFNLEtBQUssR0FBRyxNQUFNO1NBQ2pCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDckUsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUM3QixJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QixJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQztRQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFMUYsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLEtBQUssTUFBTSxDQUFDLElBQUksS0FBSztRQUFFLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUs7WUFB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Q0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBQ0QsT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxtRUFBbUU7QUFDbkUsU0FBUyxRQUFRLENBQUMsSUFBdUIsRUFBRSxDQUFTO0lBQ2xELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO0lBQzNCLE1BQU0sVUFBVSxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUMzQixVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ1gsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyRyxDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNoQyxNQUFNLEdBQUcsR0FBRyxJQUFJLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ1osS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzNCLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDOUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ2pELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsSUFBdUI7SUFDekMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ1osS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakgsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsU0FBUyxPQUFPLENBQUMsSUFBdUI7SUFDdEMsTUFBTSxHQUFHLEdBQVEsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDNUQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM1QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsd0dBQXdHO0FBQ3hHLFNBQVMsWUFBWSxDQUFDLENBQU0sRUFBRSxDQUFNO0lBQ2xDLE1BQU0sRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BELE1BQU0sRUFBRSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDbEIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN0RixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgc2hlZXQgdGhyb3VnaCBvcGVuIHBvbHlsaW5lcyB0cmFjZWQgb24gYSBzdGFjayBvZiBzbGljZXMgKGEgcmV0aW5hbCBsYXllciBib3VuZGFyeSBvbiBlYWNoXG4gKiBCLXNjYW4sIHNheSk6IGVhY2ggbGluZSBqb2luZWQgdG8gaXRzIGNvdW50ZXJwYXJ0IG9uIHRoZSBuZXh0IHNsaWNlIHRoYXQgaGFzIGxpbmVzIGJ5IGEgc3RyaXAgb2ZcbiAqIHRyaWFuZ2xlcy4gU2xpY2VzIHdpdGhvdXQgbGluZXMgaW4gYmV0d2VlbiBhcmUgYnJpZGdlZCBzdHJhaWdodCBhY3Jvc3MuXG4gKlxuICogUHVyZTogdXNhYmxlIGZyb20gd29ya2Vycy5cbiAqL1xuaW1wb3J0IHR5cGUgeyBNZXNoIH0gZnJvbSAnbmFwYXJpLWpzL2dlb21ldHJ5JztcblxuLyoqIEEgY2xhc3MncyBvcGVuIHBvbHlsaW5lcyBvbiBvbmUgc2xpY2U6IGludGVybGVhdmVkIGB4LCB5YCBpbWFnZSBwaXhlbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFNsaWNlTGluZXMge1xuICB6OiBudW1iZXI7XG4gIGxpbmVzOiByZWFkb25seSBBcnJheUxpa2U8bnVtYmVyPltdO1xufVxuXG4vKiogUG9pbnRzIHBlciBsaW5lIGF0IG1vc3Q6IHRoZSBsb25nZXN0IGxpbmUgaXMgcmVzYW1wbGVkIGF0IGFib3V0IG9uZSBwb2ludCBwZXIgYHN0ZXBgIHB4LiAqL1xuY29uc3QgTUFYX1BPSU5UUyA9IDIwNDg7XG4vKiogUG9pbnRzIHBlciBsaW5lIHdoZW4gbWF0Y2hpbmcgbGluZXMgYWNyb3NzIHNsaWNlcy4gKi9cbmNvbnN0IE1BVENIX1BPSU5UUyA9IDMyO1xuXG4vKipcbiAqIFRoZSBzaGVldCB0aHJvdWdoIGBzbGljZXNgJyBsaW5lcywgaW4gaW1hZ2UgcGl4ZWxzICh4LCB5KSBhbmQgc2xpY2UgaW5kaWNlcyAoejogc2xpY2UgaydzIGxpbmUgYXRcbiAqIHogPSBrKS4gRXZlcnkgbGluZSBpcyByZXNhbXBsZWQgYXQgdGhlIHNhbWUgbnVtYmVyIG9mIHBvaW50cywgZXZlbmx5IGFsb25nIGl0cyBsZW5ndGggKGFib3V0IG9uZVxuICogcGVyIGBzdGVwYCBweCBvZiB0aGUgbG9uZ2VzdCksIHNvIGEgbGluZSBzaGFyZWQgYnkgdGhlIHN0cmlwcyBhYm92ZSBhbmQgYmVsb3cgaXQgaXMgb25lIHJvdyBvZlxuICogdmVydGljZXMuIExpbmVzIGFyZSBtYXRjaGVkIGJldHdlZW4gbmVpZ2hib3VyaW5nIHNsaWNlcyBjbG9zZXN0IGZpcnN0LCBlYWNoIGF0IG1vc3Qgb25jZSwgYW5kIG9ubHlcbiAqIHdoZW4gdGhlaXIgYm94ZXMgb3ZlcmxhcDsgYSBsaW5lIHdpdGhvdXQgYSBtYXRjaCBlbmRzIHRoZSBzaGVldCB0aGVyZS4gRW1wdHkgd2l0aG91dCB0d28gc2xpY2VzXG4gKiB3aXRoIGxpbmVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9mdExpbmVzKHNsaWNlczogcmVhZG9ubHkgU2xpY2VMaW5lc1tdLCBzdGVwID0gMSk6IE1lc2gge1xuICBjb25zdCBzdGFjayA9IHNsaWNlc1xuICAgIC5tYXAoKHMpID0+ICh7IHo6IHMueiwgbGluZXM6IHMubGluZXMuZmlsdGVyKChsKSA9PiBsLmxlbmd0aCA+PSA0KSB9KSlcbiAgICAuZmlsdGVyKChzKSA9PiBzLmxpbmVzLmxlbmd0aClcbiAgICAuc29ydCgoYSwgYikgPT4gYS56IC0gYi56KTtcbiAgaWYgKHN0YWNrLmxlbmd0aCA8IDIpIHJldHVybiB7IHZlcnRpY2VzOiBuZXcgRmxvYXQzMkFycmF5KDApLCBmYWNlczogbmV3IFVpbnQzMkFycmF5KDApIH07XG5cbiAgbGV0IGxvbmdlc3QgPSAwO1xuICBmb3IgKGNvbnN0IHMgb2Ygc3RhY2spIGZvciAoY29uc3QgbCBvZiBzLmxpbmVzKSBsb25nZXN0ID0gTWF0aC5tYXgobG9uZ2VzdCwgbGluZUxlbmd0aChsKSk7XG4gIGNvbnN0IG4gPSBNYXRoLm1pbihNQVhfUE9JTlRTLCBNYXRoLm1heCgyLCBNYXRoLmNlaWwobG9uZ2VzdCAvIE1hdGgubWF4KHN0ZXAsIDFlLTYpKSArIDEpKTtcblxuICAvLyBFYWNoIGxpbmUncyByZXNhbXBsZWQgcG9pbnRzLCBvbmNlOiByb3dzIG9mIG4gdmVydGljZXMuXG4gIGNvbnN0IHJvd3M6IExpbmVbXVtdID0gW107XG4gIGNvbnN0IHZlcnRzOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGNvbnN0IHMgb2Ygc3RhY2spIHtcbiAgICByb3dzLnB1c2goXG4gICAgICBzLmxpbmVzLm1hcCgobCkgPT4ge1xuICAgICAgICBjb25zdCBmaXJzdCA9IHZlcnRzLmxlbmd0aCAvIDM7XG4gICAgICAgIGNvbnN0IHB0cyA9IHJlc2FtcGxlKGwsIG4pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgdmVydHMucHVzaChwdHNbMiAqIGldLCBwdHNbMiAqIGkgKyAxXSwgcy56KTtcbiAgICAgICAgcmV0dXJuIHsgZmlyc3QsIHByb2JlOiByZXNhbXBsZShsLCBNQVRDSF9QT0lOVFMpLCBib3g6IGxpbmVCb3gobCkgfTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBmYWNlczogbnVtYmVyW10gPSBbXTtcbiAgZm9yIChsZXQgayA9IDA7IGsgKyAxIDwgcm93cy5sZW5ndGg7IGsrKykge1xuICAgIGZvciAoY29uc3QgeyBhLCBiLCByZXZlcnNlZCB9IG9mIG1hdGNoTGluZXMocm93c1trXSwgcm93c1trICsgMV0pKSB7XG4gICAgICBjb25zdCBhdCA9IChpOiBudW1iZXIpID0+IGIuZmlyc3QgKyAocmV2ZXJzZWQgPyBuIC0gMSAtIGkgOiBpKTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpICsgMSA8IG47IGkrKykge1xuICAgICAgICBjb25zdCBhMCA9IGEuZmlyc3QgKyBpLFxuICAgICAgICAgIGExID0gYTAgKyAxLFxuICAgICAgICAgIGIwID0gYXQoaSksXG4gICAgICAgICAgYjEgPSBhdChpICsgMSk7XG4gICAgICAgIGZhY2VzLnB1c2goYTAsIGIwLCBhMSwgYTEsIGIwLCBiMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmICghZmFjZXMubGVuZ3RoKSByZXR1cm4geyB2ZXJ0aWNlczogbmV3IEZsb2F0MzJBcnJheSgwKSwgZmFjZXM6IG5ldyBVaW50MzJBcnJheSgwKSB9O1xuICByZXR1cm4geyB2ZXJ0aWNlczogRmxvYXQzMkFycmF5LmZyb20odmVydHMpLCBmYWNlczogVWludDMyQXJyYXkuZnJvbShmYWNlcykgfTtcbn1cblxudHlwZSBCb3ggPSBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbmludGVyZmFjZSBMaW5lIHtcbiAgZmlyc3Q6IG51bWJlcjtcbiAgcHJvYmU6IEZsb2F0NjRBcnJheTtcbiAgYm94OiBCb3g7XG59XG5cbi8qKiBQYWlycyBvZiBsaW5lcyBvZiB0d28gbmVpZ2hib3VyaW5nIHNsaWNlczogY2xvc2VzdCBmaXJzdCAobWVhbiBkaXN0YW5jZSwgZWl0aGVyIGRpcmVjdGlvbiksIGVhY2ggb25jZS4gKi9cbmZ1bmN0aW9uIG1hdGNoTGluZXMoYXM6IHJlYWRvbmx5IExpbmVbXSwgYnM6IHJlYWRvbmx5IExpbmVbXSk6IEFycmF5PHsgYTogTGluZTsgYjogTGluZTsgcmV2ZXJzZWQ6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBwYWlyczogQXJyYXk8eyBhOiBudW1iZXI7IGI6IG51bWJlcjsgY29zdDogbnVtYmVyOyByZXZlcnNlZDogYm9vbGVhbiB9PiA9IFtdO1xuICBhcy5mb3JFYWNoKChhLCBpKSA9PlxuICAgIGJzLmZvckVhY2goKGIsIGopID0+IHtcbiAgICAgIGlmICghYm94ZXNPdmVybGFwKGEuYm94LCBiLmJveCkpIHJldHVybjtcbiAgICAgIGNvbnN0IGZvcndhcmQgPSBtZWFuRGlzdGFuY2UoYS5wcm9iZSwgYi5wcm9iZSwgZmFsc2UpO1xuICAgICAgY29uc3QgYmFja3dhcmQgPSBtZWFuRGlzdGFuY2UoYS5wcm9iZSwgYi5wcm9iZSwgdHJ1ZSk7XG4gICAgICBwYWlycy5wdXNoKHsgYTogaSwgYjogaiwgY29zdDogTWF0aC5taW4oZm9yd2FyZCwgYmFja3dhcmQpLCByZXZlcnNlZDogYmFja3dhcmQgPCBmb3J3YXJkIH0pO1xuICAgIH0pLFxuICApO1xuICBwYWlycy5zb3J0KChwLCBxKSA9PiBwLmNvc3QgLSBxLmNvc3QpO1xuICBjb25zdCB1c2VkQSA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBjb25zdCB1c2VkQiA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBjb25zdCBvdXQ6IEFycmF5PHsgYTogTGluZTsgYjogTGluZTsgcmV2ZXJzZWQ6IGJvb2xlYW4gfT4gPSBbXTtcbiAgZm9yIChjb25zdCBwIG9mIHBhaXJzKSB7XG4gICAgaWYgKHVzZWRBLmhhcyhwLmEpIHx8IHVzZWRCLmhhcyhwLmIpKSBjb250aW51ZTtcbiAgICB1c2VkQS5hZGQocC5hKTtcbiAgICB1c2VkQi5hZGQocC5iKTtcbiAgICBvdXQucHVzaCh7IGE6IGFzW3AuYV0sIGI6IGJzW3AuYl0sIHJldmVyc2VkOiBwLnJldmVyc2VkIH0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIG1lYW5EaXN0YW5jZShhOiBGbG9hdDY0QXJyYXksIGI6IEZsb2F0NjRBcnJheSwgcmV2ZXJzZWQ6IGJvb2xlYW4pOiBudW1iZXIge1xuICBjb25zdCBuID0gYS5sZW5ndGggPj4gMTtcbiAgbGV0IHN1bSA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgY29uc3QgaiA9IHJldmVyc2VkID8gbiAtIDEgLSBpIDogaTtcbiAgICBzdW0gKz0gTWF0aC5oeXBvdChhWzIgKiBpXSAtIGJbMiAqIGpdLCBhWzIgKiBpICsgMV0gLSBiWzIgKiBqICsgMV0pO1xuICB9XG4gIHJldHVybiBzdW0gLyBuO1xufVxuXG4vKiogYG5gIHBvaW50cyBldmVubHkgc3BhY2VkIGFsb25nIHRoZSBwb2x5bGluZSwgYm90aCBlbmRzIGtlcHQuICovXG5mdW5jdGlvbiByZXNhbXBsZShsaW5lOiBBcnJheUxpa2U8bnVtYmVyPiwgbjogbnVtYmVyKTogRmxvYXQ2NEFycmF5IHtcbiAgY29uc3QgbSA9IGxpbmUubGVuZ3RoID4+IDE7XG4gIGNvbnN0IGN1bXVsYXRpdmUgPSBuZXcgRmxvYXQ2NEFycmF5KG0pO1xuICBmb3IgKGxldCBpID0gMTsgaSA8IG07IGkrKykge1xuICAgIGN1bXVsYXRpdmVbaV0gPVxuICAgICAgY3VtdWxhdGl2ZVtpIC0gMV0gKyBNYXRoLmh5cG90KGxpbmVbMiAqIGldIC0gbGluZVsyICogaSAtIDJdLCBsaW5lWzIgKiBpICsgMV0gLSBsaW5lWzIgKiBpIC0gMV0pO1xuICB9XG4gIGNvbnN0IHRvdGFsID0gY3VtdWxhdGl2ZVttIC0gMV07XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDY0QXJyYXkoMiAqIG4pO1xuICBsZXQgc2VnID0gMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICBjb25zdCBkID0gbiA9PT0gMSA/IDAgOiAodG90YWwgKiBpKSAvIChuIC0gMSk7XG4gICAgd2hpbGUgKHNlZyA8IG0gLSAxICYmIGN1bXVsYXRpdmVbc2VnXSA8IGQpIHNlZysrO1xuICAgIGNvbnN0IHNwYW4gPSBjdW11bGF0aXZlW3NlZ10gLSBjdW11bGF0aXZlW3NlZyAtIDFdO1xuICAgIGNvbnN0IHQgPSBzcGFuID4gMCA/IE1hdGgubWluKDEsIE1hdGgubWF4KDAsIChkIC0gY3VtdWxhdGl2ZVtzZWcgLSAxXSkgLyBzcGFuKSkgOiAwO1xuICAgIG91dFsyICogaV0gPSBsaW5lWzIgKiBzZWcgLSAyXSArIHQgKiAobGluZVsyICogc2VnXSAtIGxpbmVbMiAqIHNlZyAtIDJdKTtcbiAgICBvdXRbMiAqIGkgKyAxXSA9IGxpbmVbMiAqIHNlZyAtIDFdICsgdCAqIChsaW5lWzIgKiBzZWcgKyAxXSAtIGxpbmVbMiAqIHNlZyAtIDFdKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG5mdW5jdGlvbiBsaW5lTGVuZ3RoKGxpbmU6IEFycmF5TGlrZTxudW1iZXI+KTogbnVtYmVyIHtcbiAgbGV0IGxlbiA9IDA7XG4gIGZvciAobGV0IGkgPSAyOyBpICsgMSA8IGxpbmUubGVuZ3RoOyBpICs9IDIpIGxlbiArPSBNYXRoLmh5cG90KGxpbmVbaV0gLSBsaW5lW2kgLSAyXSwgbGluZVtpICsgMV0gLSBsaW5lW2kgLSAxXSk7XG4gIHJldHVybiBsZW47XG59XG5cbmZ1bmN0aW9uIGxpbmVCb3gobGluZTogQXJyYXlMaWtlPG51bWJlcj4pOiBCb3gge1xuICBjb25zdCBib3g6IEJveCA9IFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgKyAxIDwgbGluZS5sZW5ndGg7IGkgKz0gMikge1xuICAgIGJveFswXSA9IE1hdGgubWluKGJveFswXSwgbGluZVtpXSk7XG4gICAgYm94WzFdID0gTWF0aC5taW4oYm94WzFdLCBsaW5lW2kgKyAxXSk7XG4gICAgYm94WzJdID0gTWF0aC5tYXgoYm94WzJdLCBsaW5lW2ldKTtcbiAgICBib3hbM10gPSBNYXRoLm1heChib3hbM10sIGxpbmVbaSArIDFdKTtcbiAgfVxuICByZXR1cm4gYm94O1xufVxuXG4vKiogV2hldGhlciB0aGUgYm94ZXMgb3ZlcmxhcCwgZWFjaCBncm93biBieSBhIHRlbnRoIG9mIGl0cyBsYXJnZXIgc2lkZSAoYSBmbGF0IGxpbmUgaGFzIGEgdGhpbiBib3gpLiAqL1xuZnVuY3Rpb24gYm94ZXNPdmVybGFwKGE6IEJveCwgYjogQm94KTogYm9vbGVhbiB7XG4gIGNvbnN0IGdhID0gMC4xICogTWF0aC5tYXgoYVsyXSAtIGFbMF0sIGFbM10gLSBhWzFdKTtcbiAgY29uc3QgZ2IgPSAwLjEgKiBNYXRoLm1heChiWzJdIC0gYlswXSwgYlszXSAtIGJbMV0pO1xuICBjb25zdCBnID0gZ2EgKyBnYjtcbiAgcmV0dXJuIGFbMF0gLSBnIDw9IGJbMl0gJiYgYlswXSAtIGcgPD0gYVsyXSAmJiBhWzFdIC0gZyA8PSBiWzNdICYmIGJbMV0gLSBnIDw9IGFbM107XG59XG4iXX0=
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where to put a label inside a polygon: its pole of inaccessibility, the inside point farthest
|
|
3
|
+
* from every edge (Garcia-Castellanos & Lombardo's grid search, as in Mapbox's polylabel). Unlike
|
|
4
|
+
* the centroid it is always inside, also for a U-shaped or ring-shaped region.
|
|
5
|
+
*
|
|
6
|
+
* Pure: usable from workers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The pole of inaccessibility of `rings`, to within `precision` (default: 1/100 of the shorter
|
|
10
|
+
* side of the exterior's box, at least 0.5). Null for an exterior with fewer than three vertices.
|
|
11
|
+
*/
|
|
12
|
+
export function polylabel(rings, precision) {
|
|
13
|
+
const outer = rings[0];
|
|
14
|
+
if (!outer || outer.length < 6)
|
|
15
|
+
return null;
|
|
16
|
+
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
17
|
+
for (let i = 0; i + 1 < outer.length; i += 2) {
|
|
18
|
+
if (outer[i] < minX)
|
|
19
|
+
minX = outer[i];
|
|
20
|
+
if (outer[i] > maxX)
|
|
21
|
+
maxX = outer[i];
|
|
22
|
+
if (outer[i + 1] < minY)
|
|
23
|
+
minY = outer[i + 1];
|
|
24
|
+
if (outer[i + 1] > maxY)
|
|
25
|
+
maxY = outer[i + 1];
|
|
26
|
+
}
|
|
27
|
+
const width = maxX - minX;
|
|
28
|
+
const height = maxY - minY;
|
|
29
|
+
const cellSize = Math.min(width, height);
|
|
30
|
+
const eps = precision ?? Math.max(0.5, cellSize / 100);
|
|
31
|
+
if (cellSize <= 0)
|
|
32
|
+
return { x: minX, y: minY, distance: 0 };
|
|
33
|
+
const cell = (x, y, h) => {
|
|
34
|
+
const d = signedDistance(x, y, rings);
|
|
35
|
+
return { x, y, h, d, max: d + h * Math.SQRT2 };
|
|
36
|
+
};
|
|
37
|
+
const queue = new MaxHeap();
|
|
38
|
+
const h = cellSize / 2;
|
|
39
|
+
for (let x = minX; x < maxX; x += cellSize) {
|
|
40
|
+
for (let y = minY; y < maxY; y += cellSize)
|
|
41
|
+
queue.push(cell(x + h, y + h, h));
|
|
42
|
+
}
|
|
43
|
+
// The centroid of the box is a good first guess, the area centroid often a better one.
|
|
44
|
+
let best = cell(minX + width / 2, minY + height / 2, 0);
|
|
45
|
+
const centroid = areaCentroid(outer);
|
|
46
|
+
if (centroid) {
|
|
47
|
+
const c = cell(centroid[0], centroid[1], 0);
|
|
48
|
+
if (c.d > best.d)
|
|
49
|
+
best = c;
|
|
50
|
+
}
|
|
51
|
+
let guard = 0;
|
|
52
|
+
while (queue.size && guard++ < 10_000) {
|
|
53
|
+
const c = queue.pop();
|
|
54
|
+
if (c.d > best.d)
|
|
55
|
+
best = c;
|
|
56
|
+
if (c.max - best.d <= eps)
|
|
57
|
+
continue;
|
|
58
|
+
const q = c.h / 2;
|
|
59
|
+
queue.push(cell(c.x - q, c.y - q, q));
|
|
60
|
+
queue.push(cell(c.x + q, c.y - q, q));
|
|
61
|
+
queue.push(cell(c.x - q, c.y + q, q));
|
|
62
|
+
queue.push(cell(c.x + q, c.y + q, q));
|
|
63
|
+
}
|
|
64
|
+
return { x: best.x, y: best.y, distance: Math.max(0, best.d) };
|
|
65
|
+
}
|
|
66
|
+
/** Distance from (x, y) to the nearest edge of `rings`, positive inside (even-odd), negative outside. */
|
|
67
|
+
export function signedDistance(x, y, rings) {
|
|
68
|
+
let inside = false;
|
|
69
|
+
let min = Infinity;
|
|
70
|
+
for (const r of rings) {
|
|
71
|
+
const n = r.length >> 1;
|
|
72
|
+
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
73
|
+
const ax = r[2 * i], ay = r[2 * i + 1], bx = r[2 * j], by = r[2 * j + 1];
|
|
74
|
+
if (ay > y !== by > y && x < ((bx - ax) * (y - ay)) / (by - ay) + ax)
|
|
75
|
+
inside = !inside;
|
|
76
|
+
const d = segmentDistanceSq(x, y, ax, ay, bx, by);
|
|
77
|
+
if (d < min)
|
|
78
|
+
min = d;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return (inside ? 1 : -1) * Math.sqrt(min);
|
|
82
|
+
}
|
|
83
|
+
function segmentDistanceSq(px, py, ax, ay, bx, by) {
|
|
84
|
+
let x = ax, y = ay;
|
|
85
|
+
let dx = bx - x, dy = by - y;
|
|
86
|
+
if (dx !== 0 || dy !== 0) {
|
|
87
|
+
const t = ((px - x) * dx + (py - y) * dy) / (dx * dx + dy * dy);
|
|
88
|
+
if (t > 1) {
|
|
89
|
+
x = bx;
|
|
90
|
+
y = by;
|
|
91
|
+
}
|
|
92
|
+
else if (t > 0) {
|
|
93
|
+
x += dx * t;
|
|
94
|
+
y += dy * t;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
dx = px - x;
|
|
98
|
+
dy = py - y;
|
|
99
|
+
return dx * dx + dy * dy;
|
|
100
|
+
}
|
|
101
|
+
/** The area centroid of one ring, or null for a degenerate one. */
|
|
102
|
+
function areaCentroid(r) {
|
|
103
|
+
const n = r.length >> 1;
|
|
104
|
+
let area = 0, cx = 0, cy = 0;
|
|
105
|
+
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
106
|
+
const f = r[2 * i] * r[2 * j + 1] - r[2 * j] * r[2 * i + 1];
|
|
107
|
+
cx += (r[2 * i] + r[2 * j]) * f;
|
|
108
|
+
cy += (r[2 * i + 1] + r[2 * j + 1]) * f;
|
|
109
|
+
area += f * 3;
|
|
110
|
+
}
|
|
111
|
+
return area === 0 ? null : [cx / area, cy / area];
|
|
112
|
+
}
|
|
113
|
+
/** A binary max-heap of cells by `max`. */
|
|
114
|
+
class MaxHeap {
|
|
115
|
+
constructor() {
|
|
116
|
+
this.items = [];
|
|
117
|
+
}
|
|
118
|
+
get size() {
|
|
119
|
+
return this.items.length;
|
|
120
|
+
}
|
|
121
|
+
push(c) {
|
|
122
|
+
const a = this.items;
|
|
123
|
+
a.push(c);
|
|
124
|
+
let i = a.length - 1;
|
|
125
|
+
while (i > 0) {
|
|
126
|
+
const p = (i - 1) >> 1;
|
|
127
|
+
if (a[p].max >= a[i].max)
|
|
128
|
+
break;
|
|
129
|
+
[a[p], a[i]] = [a[i], a[p]];
|
|
130
|
+
i = p;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
pop() {
|
|
134
|
+
const a = this.items;
|
|
135
|
+
const top = a[0];
|
|
136
|
+
const last = a.pop();
|
|
137
|
+
if (a.length && last) {
|
|
138
|
+
a[0] = last;
|
|
139
|
+
let i = 0;
|
|
140
|
+
for (;;) {
|
|
141
|
+
const l = 2 * i + 1, r = l + 1;
|
|
142
|
+
let m = i;
|
|
143
|
+
if (l < a.length && a[l].max > a[m].max)
|
|
144
|
+
m = l;
|
|
145
|
+
if (r < a.length && a[r].max > a[m].max)
|
|
146
|
+
m = r;
|
|
147
|
+
if (m === i)
|
|
148
|
+
break;
|
|
149
|
+
[a[m], a[i]] = [a[i], a[m]];
|
|
150
|
+
i = m;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return top;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWxhYmVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9nZW9tZXRyeS9wb2x5bGFiZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBd0JIOzs7R0FHRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBZ0IsRUFBRSxTQUFrQjtJQUM1RCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUM1QyxJQUFJLElBQUksR0FBRyxRQUFRLEVBQ2pCLElBQUksR0FBRyxRQUFRLEVBQ2YsSUFBSSxHQUFHLENBQUMsUUFBUSxFQUNoQixJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUM7SUFDbkIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUM3QyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO1lBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJO1lBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSTtZQUFFLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdDLElBQUksS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJO1lBQUUsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7SUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztJQUMzQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN6QyxNQUFNLEdBQUcsR0FBRyxTQUFTLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsUUFBUSxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZELElBQUksUUFBUSxJQUFJLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsQ0FBQztJQUU1RCxNQUFNLElBQUksR0FBRyxDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsQ0FBUyxFQUFRLEVBQUU7UUFDckQsTUFBTSxDQUFDLEdBQUcsY0FBYyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdEMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDakQsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxLQUFLLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQUM1QixNQUFNLENBQUMsR0FBRyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzNDLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxJQUFJLFFBQVE7WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FB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LENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDNUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNSLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFdoZXJlIHRvIHB1dCBhIGxhYmVsIGluc2lkZSBhIHBvbHlnb246IGl0cyBwb2xlIG9mIGluYWNjZXNzaWJpbGl0eSwgdGhlIGluc2lkZSBwb2ludCBmYXJ0aGVzdFxuICogZnJvbSBldmVyeSBlZGdlIChHYXJjaWEtQ2FzdGVsbGFub3MgJiBMb21iYXJkbydzIGdyaWQgc2VhcmNoLCBhcyBpbiBNYXBib3gncyBwb2x5bGFiZWwpLiBVbmxpa2VcbiAqIHRoZSBjZW50cm9pZCBpdCBpcyBhbHdheXMgaW5zaWRlLCBhbHNvIGZvciBhIFUtc2hhcGVkIG9yIHJpbmctc2hhcGVkIHJlZ2lvbi5cbiAqXG4gKiBQdXJlOiB1c2FibGUgZnJvbSB3b3JrZXJzLlxuICovXG5cbi8qKiBBIHBvbHlnb24gYXMgaW50ZXJsZWF2ZWQgYHgsIHlgIHJpbmdzOiB0aGUgZXh0ZXJpb3IgZmlyc3QsIHRoZW4gaXRzIGhvbGVzLiAqL1xuZXhwb3J0IHR5cGUgRmxhdFJpbmdzID0gcmVhZG9ubHkgQXJyYXlMaWtlPG51bWJlcj5bXTtcblxuLyoqIFRoZSBwb2xlIG9mIGluYWNjZXNzaWJpbGl0eSBgW3gsIHldYCBhbmQgaXRzIGRpc3RhbmNlIHRvIHRoZSBuZWFyZXN0IGVkZ2UuICovXG5leHBvcnQgaW50ZXJmYWNlIExhYmVsUG9pbnQge1xuICB4OiBudW1iZXI7XG4gIHk6IG51bWJlcjtcbiAgLyoqIERpc3RhbmNlIGZyb20gdGhlIHBvaW50IHRvIHRoZSBuZWFyZXN0IGVkZ2U6IGhvdyBtdWNoIHJvb20gYSBsYWJlbCBoYXMgYXJvdW5kIGl0LiAqL1xuICBkaXN0YW5jZTogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQ2VsbCB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICAvKiogSGFsZiB0aGUgY2VsbCdzIGVkZ2UuICovXG4gIGg6IG51bWJlcjtcbiAgLyoqIFNpZ25lZCBkaXN0YW5jZSBmcm9tIHRoZSBjZW50cmUgdG8gdGhlIHBvbHlnb24gKHBvc2l0aXZlIGluc2lkZSkuICovXG4gIGQ6IG51bWJlcjtcbiAgLyoqIFRoZSBiZXN0IGRpc3RhbmNlIGFueSBwb2ludCBvZiB0aGUgY2VsbCBjYW4gcmVhY2guICovXG4gIG1heDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBwb2xlIG9mIGluYWNjZXNzaWJpbGl0eSBvZiBgcmluZ3NgLCB0byB3aXRoaW4gYHByZWNpc2lvbmAgKGRlZmF1bHQ6IDEvMTAwIG9mIHRoZSBzaG9ydGVyXG4gKiBzaWRlIG9mIHRoZSBleHRlcmlvcidzIGJveCwgYXQgbGVhc3QgMC41KS4gTnVsbCBmb3IgYW4gZXh0ZXJpb3Igd2l0aCBmZXdlciB0aGFuIHRocmVlIHZlcnRpY2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9seWxhYmVsKHJpbmdzOiBGbGF0UmluZ3MsIHByZWNpc2lvbj86IG51bWJlcik6IExhYmVsUG9pbnQgfCBudWxsIHtcbiAgY29uc3Qgb3V0ZXIgPSByaW5nc1swXTtcbiAgaWYgKCFvdXRlciB8fCBvdXRlci5sZW5ndGggPCA2KSByZXR1cm4gbnVsbDtcbiAgbGV0IG1pblggPSBJbmZpbml0eSxcbiAgICBtaW5ZID0gSW5maW5pdHksXG4gICAgbWF4WCA9IC1JbmZpbml0eSxcbiAgICBtYXhZID0gLUluZmluaXR5O1xuICBmb3IgKGxldCBpID0gMDsgaSArIDEgPCBvdXRlci5sZW5ndGg7IGkgKz0gMikge1xuICAgIGlmIChvdXRlcltpXSA8IG1pblgpIG1pblggPSBvdXRlcltpXTtcbiAgICBpZiAob3V0ZXJbaV0gPiBtYXhYKSBtYXhYID0gb3V0ZXJbaV07XG4gICAgaWYgKG91dGVyW2kgKyAxXSA8IG1pblkpIG1pblkgPSBvdXRlcltpICsgMV07XG4gICAgaWYgKG91dGVyW2kgKyAxXSA+IG1heFkpIG1heFkgPSBvdXRlcltpICsgMV07XG4gIH1cbiAgY29uc3Qgd2lkdGggPSBtYXhYIC0gbWluWDtcbiAgY29uc3QgaGVpZ2h0ID0gbWF4WSAtIG1pblk7XG4gIGNvbnN0IGNlbGxTaXplID0gTWF0aC5taW4od2lkdGgsIGhlaWdodCk7XG4gIGNvbnN0IGVwcyA9IHByZWNpc2lvbiA/PyBNYXRoLm1heCgwLjUsIGNlbGxTaXplIC8gMTAwKTtcbiAgaWYgKGNlbGxTaXplIDw9IDApIHJldHVybiB7IHg6IG1pblgsIHk6IG1pblksIGRpc3RhbmNlOiAwIH07XG5cbiAgY29uc3QgY2VsbCA9ICh4OiBudW1iZXIsIHk6IG51bWJlciwgaDogbnVtYmVyKTogQ2VsbCA9PiB7XG4gICAgY29uc3QgZCA9IHNpZ25lZERpc3RhbmNlKHgsIHksIHJpbmdzKTtcbiAgICByZXR1cm4geyB4LCB5LCBoLCBkLCBtYXg6IGQgKyBoICogTWF0aC5TUVJUMiB9O1xuICB9O1xuICBjb25zdCBxdWV1ZSA9IG5ldyBNYXhIZWFwKCk7XG4gIGNvbnN0IGggPSBjZWxsU2l6ZSAvIDI7XG4gIGZvciAobGV0IHggPSBtaW5YOyB4IDwgbWF4WDsgeCArPSBjZWxsU2l6ZSkge1xuICAgIGZvciAobGV0IHkgPSBtaW5ZOyB5IDwgbWF4WTsgeSArPSBjZWxsU2l6ZSkgcXVldWUucHVzaChjZWxsKHggKyBoLCB5ICsgaCwgaCkpO1xuICB9XG4gIC8vIFRoZSBjZW50cm9pZCBvZiB0aGUgYm94IGlzIGEgZ29vZCBmaXJzdCBndWVzcywgdGhlIGFyZWEgY2VudHJvaWQgb2Z0ZW4gYSBiZXR0ZXIgb25lLlxuICBsZXQgYmVzdCA9IGNlbGwobWluWCArIHdpZHRoIC8gMiwgbWluWSArIGhlaWdodCAvIDIsIDApO1xuICBjb25zdCBjZW50cm9pZCA9IGFyZWFDZW50cm9pZChvdXRlcik7XG4gIGlmIChjZW50cm9pZCkge1xuICAgIGNvbnN0IGMgPSBjZWxsKGNlbnRyb2lkWzBdLCBjZW50cm9pZFsxXSwgMCk7XG4gICAgaWYgKGMuZCA+IGJlc3QuZCkgYmVzdCA9IGM7XG4gIH1cbiAgbGV0IGd1YXJkID0gMDtcbiAgd2hpbGUgKHF1ZXVlLnNpemUgJiYgZ3VhcmQrKyA8IDEwXzAwMCkge1xuICAgIGNvbnN0IGMgPSBxdWV1ZS5wb3AoKSBhcyBDZWxsO1xuICAgIGlmIChjLmQgPiBiZXN0LmQpIGJlc3QgPSBjO1xuICAgIGlmIChjLm1heCAtIGJlc3QuZCA8PSBlcHMpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHEgPSBjLmggLyAyO1xuICAgIHF1ZXVlLnB1c2goY2VsbChjLnggLSBxLCBjLnkgLSBxLCBxKSk7XG4gICAgcXVldWUucHVzaChjZWxsKGMueCArIHEsIGMueSAtIHEsIHEpKTtcbiAgICBxdWV1ZS5wdXNoKGNlbGwoYy54IC0gcSwgYy55ICsgcSwgcSkpO1xuICAgIHF1ZXVlLnB1c2goY2VsbChjLnggKyBxLCBjLnkgKyBxLCBxKSk7XG4gIH1cbiAgcmV0dXJuIHsgeDogYmVzdC54LCB5OiBiZXN0LnksIGRpc3RhbmNlOiBNYXRoLm1heCgwLCBiZXN0LmQpIH07XG59XG5cbi8qKiBEaXN0YW5jZSBmcm9tICh4LCB5KSB0byB0aGUgbmVhcmVzdCBlZGdlIG9mIGByaW5nc2AsIHBvc2l0aXZlIGluc2lkZSAoZXZlbi1vZGQpLCBuZWdhdGl2ZSBvdXRzaWRlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25lZERpc3RhbmNlKHg6IG51bWJlciwgeTogbnVtYmVyLCByaW5nczogRmxhdFJpbmdzKTogbnVtYmVyIHtcbiAgbGV0IGluc2lkZSA9IGZhbHNlO1xuICBsZXQgbWluID0gSW5maW5pdHk7XG4gIGZvciAoY29uc3QgciBvZiByaW5ncykge1xuICAgIGNvbnN0IG4gPSByLmxlbmd0aCA+PiAxO1xuICAgIGZvciAobGV0IGkgPSAwLCBqID0gbiAtIDE7IGkgPCBuOyBqID0gaSsrKSB7XG4gICAgICBjb25zdCBheCA9IHJbMiAqIGldLFxuICAgICAgICBheSA9IHJbMiAqIGkgKyAxXSxcbiAgICAgICAgYnggPSByWzIgKiBqXSxcbiAgICAgICAgYnkgPSByWzIgKiBqICsgMV07XG4gICAgICBpZiAoYXkgPiB5ICE9PSBieSA+IHkgJiYgeCA8ICgoYnggLSBheCkgKiAoeSAtIGF5KSkgLyAoYnkgLSBheSkgKyBheCkgaW5zaWRlID0gIWluc2lkZTtcbiAgICAgIGNvbnN0IGQgPSBzZWdtZW50RGlzdGFuY2VTcSh4LCB5LCBheCwgYXksIGJ4LCBieSk7XG4gICAgICBpZiAoZCA8IG1pbikgbWluID0gZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIChpbnNpZGUgPyAxIDogLTEpICogTWF0aC5zcXJ0KG1pbik7XG59XG5cbmZ1bmN0aW9uIHNlZ21lbnREaXN0YW5jZVNxKHB4OiBudW1iZXIsIHB5OiBudW1iZXIsIGF4OiBudW1iZXIsIGF5OiBudW1iZXIsIGJ4OiBudW1iZXIsIGJ5OiBudW1iZXIpOiBudW1iZXIge1xuICBsZXQgeCA9IGF4LFxuICAgIHkgPSBheTtcbiAgbGV0IGR4ID0gYnggLSB4LFxuICAgIGR5ID0gYnkgLSB5O1xuICBpZiAoZHggIT09IDAgfHwgZHkgIT09IDApIHtcbiAgICBjb25zdCB0ID0gKChweCAtIHgpICogZHggKyAocHkgLSB5KSAqIGR5KSAvIChkeCAqIGR4ICsgZHkgKiBkeSk7XG4gICAgaWYgKHQgPiAxKSB7XG4gICAgICB4ID0gYng7XG4gICAgICB5ID0gYnk7XG4gICAgfSBlbHNlIGlmICh0ID4gMCkge1xuICAgICAgeCArPSBkeCAqIHQ7XG4gICAgICB5ICs9IGR5ICogdDtcbiAgICB9XG4gIH1cbiAgZHggPSBweCAtIHg7XG4gIGR5ID0gcHkgLSB5O1xuICByZXR1cm4gZHggKiBkeCArIGR5ICogZHk7XG59XG5cbi8qKiBUaGUgYXJlYSBjZW50cm9pZCBvZiBvbmUgcmluZywgb3IgbnVsbCBmb3IgYSBkZWdlbmVyYXRlIG9uZS4gKi9cbmZ1bmN0aW9uIGFyZWFDZW50cm9pZChyOiBBcnJheUxpa2U8bnVtYmVyPik6IFtudW1iZXIsIG51bWJlcl0gfCBudWxsIHtcbiAgY29uc3QgbiA9IHIubGVuZ3RoID4+IDE7XG4gIGxldCBhcmVhID0gMCxcbiAgICBjeCA9IDAsXG4gICAgY3kgPSAwO1xuICBmb3IgKGxldCBpID0gMCwgaiA9IG4gLSAxOyBpIDwgbjsgaiA9IGkrKykge1xuICAgIGNvbnN0IGYgPSByWzIgKiBpXSAqIHJbMiAqIGogKyAxXSAtIHJbMiAqIGpdICogclsyICogaSArIDFdO1xuICAgIGN4ICs9IChyWzIgKiBpXSArIHJbMiAqIGpdKSAqIGY7XG4gICAgY3kgKz0gKHJbMiAqIGkgKyAxXSArIHJbMiAqIGogKyAxXSkgKiBmO1xuICAgIGFyZWEgKz0gZiAqIDM7XG4gIH1cbiAgcmV0dXJuIGFyZWEgPT09IDAgPyBudWxsIDogW2N4IC8gYXJlYSwgY3kgLyBhcmVhXTtcbn1cblxuLyoqIEEgYmluYXJ5IG1heC1oZWFwIG9mIGNlbGxzIGJ5IGBtYXhgLiAqL1xuY2xhc3MgTWF4SGVhcCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgaXRlbXM6IENlbGxbXSA9IFtdO1xuXG4gIGdldCBzaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaXRlbXMubGVuZ3RoO1xuICB9XG5cbiAgcHVzaChjOiBDZWxsKTogdm9pZCB7XG4gICAgY29uc3QgYSA9IHRoaXMuaXRlbXM7XG4gICAgYS5wdXNoKGMpO1xuICAgIGxldCBpID0gYS5sZW5ndGggLSAxO1xuICAgIHdoaWxlIChpID4gMCkge1xuICAgICAgY29uc3QgcCA9IChpIC0gMSkgPj4gMTtcbiAgICAgIGlmIChhW3BdLm1heCA+PSBhW2ldLm1heCkgYnJlYWs7XG4gICAgICBbYVtwXSwgYVtpXV0gPSBbYVtpXSwgYVtwXV07XG4gICAgICBpID0gcDtcbiAgICB9XG4gIH1cblxuICBwb3AoKTogQ2VsbCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgYSA9IHRoaXMuaXRlbXM7XG4gICAgY29uc3QgdG9wID0gYVswXTtcbiAgICBjb25zdCBsYXN0ID0gYS5wb3AoKTtcbiAgICBpZiAoYS5sZW5ndGggJiYgbGFzdCkge1xuICAgICAgYVswXSA9IGxhc3Q7XG4gICAgICBsZXQgaSA9IDA7XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGNvbnN0IGwgPSAyICogaSArIDEsXG4gICAgICAgICAgciA9IGwgKyAxO1xuICAgICAgICBsZXQgbSA9IGk7XG4gICAgICAgIGlmIChsIDwgYS5sZW5ndGggJiYgYVtsXS5tYXggPiBhW21dLm1heCkgbSA9IGw7XG4gICAgICAgIGlmIChyIDwgYS5sZW5ndGggJiYgYVtyXS5tYXggPiBhW21dLm1heCkgbSA9IHI7XG4gICAgICAgIGlmIChtID09PSBpKSBicmVhaztcbiAgICAgICAgW2FbbV0sIGFbaV1dID0gW2FbaV0sIGFbbV1dO1xuICAgICAgICBpID0gbTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRvcDtcbiAgfVxufVxuIl19
|