@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.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/lib/contracts/display-types.mjs +3 -2
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.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/spatial-dataset.contract.mjs +1 -1
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
- package/esm2022/lib/geometry/place.mjs +47 -0
- package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +81 -15
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +325 -18
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +182 -24
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +30 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +111 -28
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +14 -2
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +180 -48
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +28 -8
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
- package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
- package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
- package/esm2022/lib/region-source/region-tiles.mjs +1 -1
- package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
- package/esm2022/lib/routing-visualizer.service.mjs +404 -7
- package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
- package/esm2022/lib/spatial/plane-cells.mjs +119 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +298 -5
- package/esm2022/lib/spatial/spatial-encoding.mjs +35 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
- package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
- package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
- package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
- package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +47 -12
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +38 -10
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
- package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
- package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
- package/esm2022/lib/store/region-source-scope.mjs +10 -1
- package/esm2022/lib/store/region-store.service.mjs +33 -2
- package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
- package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
- package/esm2022/lib/visualizer.component.mjs +40 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4521 -759
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
- package/fesm2022/region-source.worker.js +84 -2
- package/lib/contracts/display-types.d.ts +90 -4
- package/lib/contracts/image.contract.d.ts +6 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
- package/lib/contracts/region-editor-api.contract.d.ts +9 -0
- package/lib/contracts/region-store.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
- package/lib/contracts/visualizer.contract.d.ts +43 -1
- package/lib/geometry/cell-meshes.d.ts +27 -0
- package/lib/geometry/place.d.ts +45 -0
- package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
- package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
- package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +87 -0
- package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +49 -8
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +15 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +38 -19
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +53 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
- package/lib/region-editor/region-editor.component.d.ts +4 -0
- package/lib/region-source/region-source-ops.d.ts +12 -0
- package/lib/region-source/region-tiles.d.ts +8 -0
- package/lib/region-source/worker-region-source.d.ts +18 -0
- package/lib/routing-visualizer.service.d.ts +140 -1
- package/lib/spatial/observations-in-selection.d.ts +43 -0
- package/lib/spatial/plane-cells.d.ts +37 -0
- package/lib/spatial/spatial-controls.facade.d.ts +59 -0
- package/lib/spatial/spatial-encoding.d.ts +14 -1
- package/lib/spatial/spatial-hover.d.ts +23 -0
- package/lib/spatial/spatial-planes.d.ts +22 -0
- package/lib/spatial/spatial-selection.d.ts +2 -1
- package/lib/spatial/spatial-tile-merge.d.ts +9 -0
- package/lib/spatial/transcripts-in-selection.d.ts +95 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
- package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +17 -2
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +16 -6
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
- package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
- package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
- package/lib/store/region-source-scope.d.ts +4 -0
- package/lib/store/region-store.service.d.ts +21 -0
- package/lib/toolbar/toolbar.component.d.ts +6 -1
- package/lib/visualizer/spatial-region-set.d.ts +55 -0
- package/lib/visualizer.component.d.ts +14 -0
- package/package.json +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +0 -1
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { isCategoricalColumn, } from '../contracts/spatial-dataset.contract';
|
|
2
|
+
import { cellTypeColumnFor } from './lod';
|
|
3
|
+
import { categoryColorsFor } from './spatial-encoding';
|
|
4
|
+
/**
|
|
5
|
+
* The observations of a selection (a mask), described: how many, by the grouping they are coloured
|
|
6
|
+
* by (else the cell types), the mean of a few measurements — or, for one cell, its id, its groups
|
|
7
|
+
* and its values. Pure but for the port's columns (cached by it).
|
|
8
|
+
*/
|
|
9
|
+
/** At most this many measurements (continuous columns) are given. */
|
|
10
|
+
export const OBSERVATION_DETAIL_COLUMNS = 6;
|
|
11
|
+
/**
|
|
12
|
+
* Describe the observations `mask` selects (see {@link ObservationsDescription}): counted by the
|
|
13
|
+
* categorical column the view colours by, else the cell-type column; at most `maxMeasures`
|
|
14
|
+
* continuous columns averaged (or read, for one cell).
|
|
15
|
+
*/
|
|
16
|
+
export async function describeObservations(port, dataset, view, mask, maxMeasures = OBSERVATION_DETAIL_COLUMNS) {
|
|
17
|
+
const indices = [];
|
|
18
|
+
for (let i = 0; i < mask.length; i++)
|
|
19
|
+
if (mask[i])
|
|
20
|
+
indices.push(i);
|
|
21
|
+
const total = indices.length;
|
|
22
|
+
const one = total === 1 ? indices[0] : -1;
|
|
23
|
+
const categorical = dataset.columns.filter((c) => c.kind === 'categorical');
|
|
24
|
+
const colored = view.colorBy?.kind === 'column' ? view.colorBy.name : null;
|
|
25
|
+
const groupColumn = (colored && categorical.some((c) => c.name === colored) ? colored : null) ?? cellTypeColumnFor(dataset, view);
|
|
26
|
+
let groups = [];
|
|
27
|
+
const measures = [];
|
|
28
|
+
if (groupColumn && total) {
|
|
29
|
+
const column = await port.getColumn(groupColumn);
|
|
30
|
+
if (isCategoricalColumn(column)) {
|
|
31
|
+
const categories = column.meta.categories;
|
|
32
|
+
const colors = categoryColorsFor(groupColumn, column.meta, view.groupColors);
|
|
33
|
+
const counts = new Map();
|
|
34
|
+
for (const i of indices)
|
|
35
|
+
counts.set(column.codes[i], (counts.get(column.codes[i]) ?? 0) + 1);
|
|
36
|
+
groups = [...counts.entries()]
|
|
37
|
+
.map(([code, count]) => ({
|
|
38
|
+
name: categories[code] ?? '(none)',
|
|
39
|
+
count,
|
|
40
|
+
color: colors[code] ?? '#9e9e9e',
|
|
41
|
+
}))
|
|
42
|
+
.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (total) {
|
|
46
|
+
// One cell: its other groupings first (its type, its cluster…), as text.
|
|
47
|
+
if (one >= 0) {
|
|
48
|
+
for (const meta of categorical.filter((c) => c.name !== groupColumn).slice(0, maxMeasures)) {
|
|
49
|
+
const column = await port.getColumn(meta.name);
|
|
50
|
+
if (!isCategoricalColumn(column))
|
|
51
|
+
continue;
|
|
52
|
+
const name = column.meta.categories[column.codes[one]];
|
|
53
|
+
if (name !== undefined)
|
|
54
|
+
measures.push({ name: meta.name, value: name, mean: false });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const continuous = dataset.columns.filter((c) => c.kind === 'continuous');
|
|
58
|
+
for (const meta of continuous.slice(0, maxMeasures)) {
|
|
59
|
+
const column = await port.getColumn(meta.name);
|
|
60
|
+
if (isCategoricalColumn(column))
|
|
61
|
+
continue;
|
|
62
|
+
let sum = 0;
|
|
63
|
+
let n = 0;
|
|
64
|
+
for (const i of indices) {
|
|
65
|
+
const v = column.values[i];
|
|
66
|
+
if (Number.isFinite(v)) {
|
|
67
|
+
sum += v;
|
|
68
|
+
n++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (n)
|
|
72
|
+
measures.push({ name: meta.name, value: sum / n, unit: meta.unit, mean: one < 0 });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
total,
|
|
77
|
+
groupColumn: groups.length ? groupColumn : null,
|
|
78
|
+
groups,
|
|
79
|
+
measures,
|
|
80
|
+
...(one >= 0 ? { cellId: dataset.observations.ids?.[one] ?? String(one) } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JzZXJ2YXRpb25zLWluLXNlbGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC9vYnNlcnZhdGlvbnMtaW4tc2VsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFJTCxtQkFBbUIsR0FDcEIsTUFBTSx1Q0FBdUMsQ0FBQztBQUMvQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFdkQ7Ozs7R0FJRztBQUVILHFFQUFxRTtBQUNyRSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLENBQUM7QUEwQjVDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxJQUF3QyxFQUN4QyxPQUF1QixFQUN2QixJQUEwRSxFQUMxRSxJQUFnQixFQUNoQixXQUFXLEdBQUcsMEJBQTBCO0lBRXhDLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUU7UUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7WUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDN0IsTUFBTSxHQUFHLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUUxQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBOEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssYUFB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QUs7UUFDTCxXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJO1FBQy9DLE1BQU07UUFDTixRQUFRO1FBQ1IsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNoRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU3BhdGlhbFZpZXdTdGF0ZSB9IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB0eXBlIHsgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7XG4gIHR5cGUgQ2F0ZWdvcmljYWxDb2x1bW5NZXRhLFxuICB0eXBlIENvbnRpbnVvdXNDb2x1bW5NZXRhLFxuICB0eXBlIFNwYXRpYWxEYXRhc2V0LFxuICBpc0NhdGVnb3JpY2FsQ29sdW1uLFxufSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IGNlbGxUeXBlQ29sdW1uRm9yIH0gZnJvbSAnLi9sb2QnO1xuaW1wb3J0IHsgY2F0ZWdvcnlDb2xvcnNGb3IgfSBmcm9tICcuL3NwYXRpYWwtZW5jb2RpbmcnO1xuXG4vKipcbiAqIFRoZSBvYnNlcnZhdGlvbnMgb2YgYSBzZWxlY3Rpb24gKGEgbWFzayksIGRlc2NyaWJlZDogaG93IG1hbnksIGJ5IHRoZSBncm91cGluZyB0aGV5IGFyZSBjb2xvdXJlZFxuICogYnkgKGVsc2UgdGhlIGNlbGwgdHlwZXMpLCB0aGUgbWVhbiBvZiBhIGZldyBtZWFzdXJlbWVudHMg4oCUIG9yLCBmb3Igb25lIGNlbGwsIGl0cyBpZCwgaXRzIGdyb3Vwc1xuICogYW5kIGl0cyB2YWx1ZXMuIFB1cmUgYnV0IGZvciB0aGUgcG9ydCdzIGNvbHVtbnMgKGNhY2hlZCBieSBpdCkuXG4gKi9cblxuLyoqIEF0IG1vc3QgdGhpcyBtYW55IG1lYXN1cmVtZW50cyAoY29udGludW91cyBjb2x1bW5zKSBhcmUgZ2l2ZW4uICovXG5leHBvcnQgY29uc3QgT0JTRVJWQVRJT05fREVUQUlMX0NPTFVNTlMgPSA2O1xuXG4vKiogT25lIGdyb3VwJ3Mgb2JzZXJ2YXRpb25zIGluIHRoZSBzZWxlY3Rpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIEdyb3VwQ291bnQge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNvdW50OiBudW1iZXI7XG4gIC8qKiBUaGUgZ3JvdXAncyBjb2xvdXIsIGFzIHRoZSBsZWdlbmQgc2hvd3MgaXQuICovXG4gIGNvbG9yOiBzdHJpbmc7XG59XG5cbi8qKiBXaGF0IHtAbGluayBkZXNjcmliZU9ic2VydmF0aW9uc30gZmluZHMuICovXG5leHBvcnQgaW50ZXJmYWNlIE9ic2VydmF0aW9uc0Rlc2NyaXB0aW9uIHtcbiAgdG90YWw6IG51bWJlcjtcbiAgLyoqIFRoZSBncm91cGluZyB0aGUgb2JzZXJ2YXRpb25zIGFyZSBjb3VudGVkIGJ5LCBvciBudWxsIHdoZW4gdGhlIGRhdGFzZXQgaGFzIG5vbmUuICovXG4gIGdyb3VwQ29sdW1uOiBzdHJpbmcgfCBudWxsO1xuICAvKiogR3JvdXBzIGJ5IGNvdW50LCBtb3N0IGZpcnN0IChlbXB0eSBncm91cHMgbGVmdCBvdXQpLiAqL1xuICBncm91cHM6IEdyb3VwQ291bnRbXTtcbiAgLyoqXG4gICAqIEEgZmV3IG1lYXN1cmVtZW50czogdGhlIG1lYW4gb3ZlciB0aGUgc2VsZWN0aW9uIChgbWVhbmAgdHJ1ZSksIG9yIG9uZSBjZWxsJ3Mgb3duIHZhbHVlcy4gV2l0aFxuICAgKiBvbmUgY2VsbCwgaXRzIG90aGVyIGdyb3VwaW5ncyBjb21lIGZpcnN0LCBhcyB0ZXh0LlxuICAgKi9cbiAgbWVhc3VyZXM6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyOyB1bml0Pzogc3RyaW5nOyBtZWFuOiBib29sZWFuIH1bXTtcbiAgLyoqIFRoZSBvbmUgY2VsbCdzIGlkLCB3aGVuIHRoZSBzZWxlY3Rpb24gaXMgb25lIGNlbGwuICovXG4gIGNlbGxJZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZXNjcmliZSB0aGUgb2JzZXJ2YXRpb25zIGBtYXNrYCBzZWxlY3RzIChzZWUge0BsaW5rIE9ic2VydmF0aW9uc0Rlc2NyaXB0aW9ufSk6IGNvdW50ZWQgYnkgdGhlXG4gKiBjYXRlZ29yaWNhbCBjb2x1bW4gdGhlIHZpZXcgY29sb3VycyBieSwgZWxzZSB0aGUgY2VsbC10eXBlIGNvbHVtbjsgYXQgbW9zdCBgbWF4TWVhc3VyZXNgXG4gKiBjb250aW51b3VzIGNvbHVtbnMgYXZlcmFnZWQgKG9yIHJlYWQsIGZvciBvbmUgY2VsbCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZXNjcmliZU9ic2VydmF0aW9ucyhcbiAgcG9ydDogUGljazxTcGF0aWFsRGF0YVBvcnQsICdnZXRDb2x1bW4nPixcbiAgZGF0YXNldDogU3BhdGlhbERhdGFzZXQsXG4gIHZpZXc6IFBpY2s8U3BhdGlhbFZpZXdTdGF0ZSwgJ2NvbG9yQnknIHwgJ2NlbGxUeXBlQ29sdW1uJyB8ICdncm91cENvbG9ycyc+LFxuICBtYXNrOiBVaW50OEFycmF5LFxuICBtYXhNZWFzdXJlcyA9IE9CU0VSVkFUSU9OX0RFVEFJTF9DT0xVTU5TLFxuKTogUHJvbWlzZTxPYnNlcnZhdGlvbnNEZXNjcmlwdGlvbj4ge1xuICBjb25zdCBpbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG1hc2subGVuZ3RoOyBpKyspIGlmIChtYXNrW2ldKSBpbmRpY2VzLnB1c2goaSk7XG4gIGNvbnN0IHRvdGFsID0gaW5kaWNlcy5sZW5ndGg7XG4gIGNvbnN0IG9uZSA9IHRvdGFsID09PSAxID8gaW5kaWNlc1swXSA6IC0xO1xuXG4gIGNvbnN0IGNhdGVnb3JpY2FsID0gZGF0YXNldC5jb2x1bW5zLmZpbHRlcigoYyk6IGMgaXMgQ2F0ZWdvcmljYWxDb2x1bW5NZXRhID0+IGMua2luZCA9PT0gJ2NhdGVnb3JpY2FsJyk7XG4gIGNvbnN0IGNvbG9yZWQgPSB2aWV3LmNvbG9yQnk/LmtpbmQgPT09ICdjb2x1bW4nID8gdmlldy5jb2xvckJ5Lm5hbWUgOiBudWxsO1xuICBjb25zdCBncm91cENvbHVtbiA9XG4gICAgKGNvbG9yZWQgJiYgY2F0ZWdvcmljYWwuc29tZSgoYykgPT4gYy5uYW1lID09PSBjb2xvcmVkKSA/IGNvbG9yZWQgOiBudWxsKSA/PyBjZWxsVHlwZUNvbHVtbkZvcihkYXRhc2V0LCB2aWV3KTtcblxuICBsZXQgZ3JvdXBzOiBHcm91cENvdW50W10gPSBbXTtcbiAgY29uc3QgbWVhc3VyZXM6IE9ic2VydmF0aW9uc0Rlc2NyaXB0aW9uWydtZWFzdXJlcyddID0gW107XG4gIGlmIChncm91cENvbHVtbiAmJiB0b3RhbCkge1xuICAgIGNvbnN0IGNvbHVtbiA9IGF3YWl0IHBvcnQuZ2V0Q29sdW1uKGdyb3VwQ29sdW1uKTtcbiAgICBpZiAoaXNDYXRlZ29yaWNhbENvbHVtbihjb2x1bW4pKSB7XG4gICAgICBjb25zdCBjYXRlZ29yaWVzID0gY29sdW1uLm1ldGEuY2F0ZWdvcmllcztcbiAgICAgIGNvbnN0IGNvbG9ycyA9IGNhdGVnb3J5Q29sb3JzRm9yKGdyb3VwQ29sdW1uLCBjb2x1bW4ubWV0YSwgdmlldy5ncm91cENvbG9ycyk7XG4gICAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICAgICAgZm9yIChjb25zdCBpIG9mIGluZGljZXMpIGNvdW50cy5zZXQoY29sdW1uLmNvZGVzW2ldLCAoY291bnRzLmdldChjb2x1bW4uY29kZXNbaV0pID8/IDApICsgMSk7XG4gICAgICBncm91cHMgPSBbLi4uY291bnRzLmVudHJpZXMoKV1cbiAgICAgICAgLm1hcCgoW2NvZGUsIGNvdW50XSkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBjYXRlZ29yaWVzW2NvZGVdID8/ICcobm9uZSknLFxuICAgICAgICAgIGNvdW50LFxuICAgICAgICAgIGNvbG9yOiBjb2xvcnNbY29kZV0gPz8gJyM5ZTllOWUnLFxuICAgICAgICB9KSlcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IGIuY291bnQgLSBhLmNvdW50IHx8IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICAgIH1cbiAgfVxuXG4gIGlmICh0b3RhbCkge1xuICAgIC8vIE9uZSBjZWxsOiBpdHMgb3RoZXIgZ3JvdXBpbmdzIGZpcnN0IChpdHMgdHlwZSwgaXRzIGNsdXN0ZXLigKYpLCBhcyB0ZXh0LlxuICAgIGlmIChvbmUgPj0gMCkge1xuICAgICAgZm9yIChjb25zdCBtZXRhIG9mIGNhdGVnb3JpY2FsLmZpbHRlcigoYykgPT4gYy5uYW1lICE9PSBncm91cENvbHVtbikuc2xpY2UoMCwgbWF4TWVhc3VyZXMpKSB7XG4gICAgICAgIGNvbnN0IGNvbHVtbiA9IGF3YWl0IHBvcnQuZ2V0Q29sdW1uKG1ldGEubmFtZSk7XG4gICAgICAgIGlmICghaXNDYXRlZ29yaWNhbENvbHVtbihjb2x1bW4pKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgbmFtZSA9IGNvbHVtbi5tZXRhLmNhdGVnb3JpZXNbY29sdW1uLmNvZGVzW29uZV1dO1xuICAgICAgICBpZiAobmFtZSAhPT0gdW5kZWZpbmVkKSBtZWFzdXJlcy5wdXNoKHsgbmFtZTogbWV0YS5uYW1lLCB2YWx1ZTogbmFtZSwgbWVhbjogZmFsc2UgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGNvbnRpbnVvdXMgPSBkYXRhc2V0LmNvbHVtbnMuZmlsdGVyKChjKTogYyBpcyBDb250aW51b3VzQ29sdW1uTWV0YSA9PiBjLmtpbmQgPT09ICdjb250aW51b3VzJyk7XG4gICAgZm9yIChjb25zdCBtZXRhIG9mIGNvbnRpbnVvdXMuc2xpY2UoMCwgbWF4TWVhc3VyZXMpKSB7XG4gICAgICBjb25zdCBjb2x1bW4gPSBhd2FpdCBwb3J0LmdldENvbHVtbihtZXRhLm5hbWUpO1xuICAgICAgaWYgKGlzQ2F0ZWdvcmljYWxDb2x1bW4oY29sdW1uKSkgY29udGludWU7XG4gICAgICBsZXQgc3VtID0gMDtcbiAgICAgIGxldCBuID0gMDtcbiAgICAgIGZvciAoY29uc3QgaSBvZiBpbmRpY2VzKSB7XG4gICAgICAgIGNvbnN0IHYgPSBjb2x1bW4udmFsdWVzW2ldO1xuICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHYpKSB7XG4gICAgICAgICAgc3VtICs9IHY7XG4gICAgICAgICAgbisrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobikgbWVhc3VyZXMucHVzaCh7IG5hbWU6IG1ldGEubmFtZSwgdmFsdWU6IHN1bSAvIG4sIHVuaXQ6IG1ldGEudW5pdCwgbWVhbjogb25lIDwgMCB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHRvdGFsLFxuICAgIGdyb3VwQ29sdW1uOiBncm91cHMubGVuZ3RoID8gZ3JvdXBDb2x1bW4gOiBudWxsLFxuICAgIGdyb3VwcyxcbiAgICBtZWFzdXJlcyxcbiAgICAuLi4ob25lID49IDAgPyB7IGNlbGxJZDogZGF0YXNldC5vYnNlcnZhdGlvbnMuaWRzPy5bb25lXSA/PyBTdHJpbmcob25lKSB9IDoge30pLFxuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A 3D segmentation's cells on one plane as the 2D view's cell layer draws them: the outlines of a
|
|
3
|
+
* boundary set's region set (`SpatialPolygonTilesMeta.sets[i].regionSource`, every cell outlined on
|
|
4
|
+
* every plane it spans), read from the region source's tiles of that plane, as rings owned by their
|
|
5
|
+
* observations, so the Cells panel's colouring, groups and selection apply to them as to any ring.
|
|
6
|
+
*
|
|
7
|
+
* A feature is a cell by its id: the cell's id among the observations' (`SpatialObservations.ids`),
|
|
8
|
+
* qualified by its slice (`<slice>:<id>`) as a folder region set serves it. Pure, like
|
|
9
|
+
* `spatial-tile-merge.ts`.
|
|
10
|
+
*/
|
|
11
|
+
/** Memoized per observations object: their ids to their indices. */
|
|
12
|
+
const indices = new WeakMap();
|
|
13
|
+
/** Each observation's index by its id, or null when the observations carry no ids. */
|
|
14
|
+
export function observationIndex(obs) {
|
|
15
|
+
const hit = indices.get(obs);
|
|
16
|
+
if (hit !== undefined)
|
|
17
|
+
return hit;
|
|
18
|
+
const ids = obs.ids;
|
|
19
|
+
const out = ids ? new Map(ids.map((id, i) => [id, i])) : null;
|
|
20
|
+
indices.set(obs, out);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
/** A feature's cell id: its id without the slice a folder region set qualifies it with. */
|
|
24
|
+
export function cellIdOf(featureId) {
|
|
25
|
+
const at = featureId.indexOf(':');
|
|
26
|
+
return at < 0 ? featureId : featureId.slice(at + 1);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The rings of `tiles`' features (each once, though a feature is in every tile it meets), owned by
|
|
30
|
+
* their cells, in observation units (the region set's are the image's pixels: back through `ref`).
|
|
31
|
+
* A feature of no observation, and an open one (a polyline), is left out; each ring of a feature
|
|
32
|
+
* (its parts and holes) is a ring of its cell.
|
|
33
|
+
*/
|
|
34
|
+
export function planeCellRings(tiles, index, ref) {
|
|
35
|
+
const [sx, sy] = ref?.scale ?? [1, 1];
|
|
36
|
+
const [tx, ty] = ref?.translate ?? [0, 0];
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const rings = [];
|
|
39
|
+
const owners = [];
|
|
40
|
+
let vertices = 0;
|
|
41
|
+
for (const tile of tiles) {
|
|
42
|
+
for (const f of tile.features) {
|
|
43
|
+
if (f.open || seen.has(f.id))
|
|
44
|
+
continue;
|
|
45
|
+
seen.add(f.id);
|
|
46
|
+
const o = index.get(cellIdOf(f.id));
|
|
47
|
+
if (o === undefined)
|
|
48
|
+
continue;
|
|
49
|
+
for (const ring of f.rings) {
|
|
50
|
+
if (ring.length < 6)
|
|
51
|
+
continue;
|
|
52
|
+
rings.push(ring);
|
|
53
|
+
owners.push(o);
|
|
54
|
+
vertices += ring.length / 2;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const coords = new Float32Array(vertices * 2);
|
|
59
|
+
const offsets = new Uint32Array(rings.length + 1);
|
|
60
|
+
let v = 0;
|
|
61
|
+
rings.forEach((ring, r) => {
|
|
62
|
+
offsets[r] = v;
|
|
63
|
+
for (let i = 0; i < ring.length; i += 2) {
|
|
64
|
+
coords[v * 2] = (ring[i] - tx) / sx;
|
|
65
|
+
coords[v * 2 + 1] = (ring[i + 1] - ty) / sy;
|
|
66
|
+
v++;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
offsets[rings.length] = v;
|
|
70
|
+
return { count: rings.length, coords, offsets, observation: Uint32Array.from(owners) };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Each cell's outlines on every plane it spans, from the planes' tiles (a feature once, though in
|
|
74
|
+
* every tile it meets), for the 3D reconstruction of each cell by itself (`CellOutlines`, slice k
|
|
75
|
+
* at z = k). Only cells of `classes` (all when null), whose outlines' centre over all planes is in
|
|
76
|
+
* `within` (`[x0, y0, x1, y1]`, image px; anywhere when absent): the tiles fetched for an area hold
|
|
77
|
+
* the cells crossing its edge too, which belong to the area their centre is in.
|
|
78
|
+
*/
|
|
79
|
+
export function cellOutlinesFromTiles(planes, index, classes, within) {
|
|
80
|
+
const byCell = new Map();
|
|
81
|
+
for (const plane of planes) {
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
for (const tile of plane.tiles) {
|
|
84
|
+
for (const f of tile.features) {
|
|
85
|
+
if (f.open || seen.has(f.id) || !f.rings.length)
|
|
86
|
+
continue;
|
|
87
|
+
seen.add(f.id);
|
|
88
|
+
if (classes && !classes.has(f.label ?? ''))
|
|
89
|
+
continue;
|
|
90
|
+
const cell = index.get(cellIdOf(f.id));
|
|
91
|
+
if (cell === undefined)
|
|
92
|
+
continue;
|
|
93
|
+
let entry = byCell.get(cell);
|
|
94
|
+
if (!entry) {
|
|
95
|
+
entry = { label: f.label, slices: [], box: [Infinity, Infinity, -Infinity, -Infinity] };
|
|
96
|
+
byCell.set(cell, entry);
|
|
97
|
+
}
|
|
98
|
+
entry.slices.push({ z: plane.slice, rings: f.rings });
|
|
99
|
+
const b = entry.box;
|
|
100
|
+
b[0] = Math.min(b[0], f.bbox[0]);
|
|
101
|
+
b[1] = Math.min(b[1], f.bbox[1]);
|
|
102
|
+
b[2] = Math.max(b[2], f.bbox[2]);
|
|
103
|
+
b[3] = Math.max(b[3], f.bbox[3]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const out = [];
|
|
108
|
+
for (const [cell, e] of byCell) {
|
|
109
|
+
if (within) {
|
|
110
|
+
const cx = (e.box[0] + e.box[2]) / 2;
|
|
111
|
+
const cy = (e.box[1] + e.box[3]) / 2;
|
|
112
|
+
if (cx < within[0] || cx >= within[2] || cy < within[1] || cy >= within[3])
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
out.push({ cell, label: e.label, slices: e.slices });
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbmUtY2VsbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwvcGxhbmUtY2VsbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBT0E7Ozs7Ozs7OztHQVNHO0FBRUgsb0VBQW9FO0FBQ3BFLE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxFQUFtRCxDQUFDO0FBRS9FLHNGQUFzRjtBQUN0RixNQUFNLFVBQVUsZ0JBQWdCLENBQUMsR0FBd0I7SUFDdkQsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixJQUFJLEdBQUcsS0FBSyxTQUFTO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFDbEMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQztJQUNwQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDbEYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDdEIsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBRUQsMkZBQTJGO0FBQzNGLE1BQU0sVUFBVSxRQUFRLENBQUMsU0FBaUI7SUFDeEMsTUFBTSxFQUFFLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNsQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGNBQWMs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QUFDLENBQUM7WUFDckMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckMsSUFBSSxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFBRSxTQUFTO1FBQ3ZGLENBQUM7UUFDRCxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuICBTcGF0aWFsSW1hZ2VSZWYsXG4gIFNwYXRpYWxPYnNlcnZhdGlvbnMsXG4gIFNwYXRpYWxQb2x5Z29uVGlsZSxcbn0gZnJvbSAnLi4vY29udHJhY3RzL3NwYXRpYWwtZGF0YXNldC5jb250cmFjdCc7XG5pbXBvcnQgdHlwZSB7IFRpbGVGZWF0dXJlIH0gZnJvbSAnLi4vcmVnaW9uLXNvdXJjZS9yZWdpb24tdGlsZXMnO1xuXG4vKipcbiAqIEEgM0Qgc2VnbWVudGF0aW9uJ3MgY2VsbHMgb24gb25lIHBsYW5lIGFzIHRoZSAyRCB2aWV3J3MgY2VsbCBsYXllciBkcmF3cyB0aGVtOiB0aGUgb3V0bGluZXMgb2YgYVxuICogYm91bmRhcnkgc2V0J3MgcmVnaW9uIHNldCAoYFNwYXRpYWxQb2x5Z29uVGlsZXNNZXRhLnNldHNbaV0ucmVnaW9uU291cmNlYCwgZXZlcnkgY2VsbCBvdXRsaW5lZCBvblxuICogZXZlcnkgcGxhbmUgaXQgc3BhbnMpLCByZWFkIGZyb20gdGhlIHJlZ2lvbiBzb3VyY2UncyB0aWxlcyBvZiB0aGF0IHBsYW5lLCBhcyByaW5ncyBvd25lZCBieSB0aGVpclxuICogb2JzZXJ2YXRpb25zLCBzbyB0aGUgQ2VsbHMgcGFuZWwncyBjb2xvdXJpbmcsIGdyb3VwcyBhbmQgc2VsZWN0aW9uIGFwcGx5IHRvIHRoZW0gYXMgdG8gYW55IHJpbmcuXG4gKlxuICogQSBmZWF0dXJlIGlzIGEgY2VsbCBieSBpdHMgaWQ6IHRoZSBjZWxsJ3MgaWQgYW1vbmcgdGhlIG9ic2VydmF0aW9ucycgKGBTcGF0aWFsT2JzZXJ2YXRpb25zLmlkc2ApLFxuICogcXVhbGlmaWVkIGJ5IGl0cyBzbGljZSAoYDxzbGljZT46PGlkPmApIGFzIGEgZm9sZGVyIHJlZ2lvbiBzZXQgc2VydmVzIGl0LiBQdXJlLCBsaWtlXG4gKiBgc3BhdGlhbC10aWxlLW1lcmdlLnRzYC5cbiAqL1xuXG4vKiogTWVtb2l6ZWQgcGVyIG9ic2VydmF0aW9ucyBvYmplY3Q6IHRoZWlyIGlkcyB0byB0aGVpciBpbmRpY2VzLiAqL1xuY29uc3QgaW5kaWNlcyA9IG5ldyBXZWFrTWFwPFNwYXRpYWxPYnNlcnZhdGlvbnMsIE1hcDxzdHJpbmcsIG51bWJlcj4gfCBudWxsPigpO1xuXG4vKiogRWFjaCBvYnNlcnZhdGlvbidzIGluZGV4IGJ5IGl0cyBpZCwgb3IgbnVsbCB3aGVuIHRoZSBvYnNlcnZhdGlvbnMgY2Fycnkgbm8gaWRzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmF0aW9uSW5kZXgob2JzOiBTcGF0aWFsT2JzZXJ2YXRpb25zKTogTWFwPHN0cmluZywgbnVtYmVyPiB8IG51bGwge1xuICBjb25zdCBoaXQgPSBpbmRpY2VzLmdldChvYnMpO1xuICBpZiAoaGl0ICE9PSB1bmRlZmluZWQpIHJldHVybiBoaXQ7XG4gIGNvbnN0IGlkcyA9IG9icy5pZHM7XG4gIGNvbnN0IG91dCA9IGlkcyA/IG5ldyBNYXAoaWRzLm1hcCgoaWQsIGkpID0+IFtpZCwgaV0gYXMgW3N0cmluZywgbnVtYmVyXSkpIDogbnVsbDtcbiAgaW5kaWNlcy5zZXQob2JzLCBvdXQpO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKiogQSBmZWF0dXJlJ3MgY2VsbCBpZDogaXRzIGlkIHdpdGhvdXQgdGhlIHNsaWNlIGEgZm9sZGVyIHJlZ2lvbiBzZXQgcXVhbGlmaWVzIGl0IHdpdGguICovXG5leHBvcnQgZnVuY3Rpb24gY2VsbElkT2YoZmVhdHVyZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBhdCA9IGZlYXR1cmVJZC5pbmRleE9mKCc6Jyk7XG4gIHJldHVybiBhdCA8IDAgPyBmZWF0dXJlSWQgOiBmZWF0dXJlSWQuc2xpY2UoYXQgKyAxKTtcbn1cblxuLyoqXG4gKiBUaGUgcmluZ3Mgb2YgYHRpbGVzYCcgZmVhdHVyZXMgKGVhY2ggb25jZSwgdGhvdWdoIGEgZmVhdHVyZSBpcyBpbiBldmVyeSB0aWxlIGl0IG1lZXRzKSwgb3duZWQgYnlcbiAqIHRoZWlyIGNlbGxzLCBpbiBvYnNlcnZhdGlvbiB1bml0cyAodGhlIHJlZ2lvbiBzZXQncyBhcmUgdGhlIGltYWdlJ3MgcGl4ZWxzOiBiYWNrIHRocm91Z2ggYHJlZmApLlxuICogQSBmZWF0dXJlIG9mIG5vIG9ic2VydmF0aW9uLCBhbmQgYW4gb3BlbiBvbmUgKGEgcG9seWxpbmUpLCBpcyBsZWZ0IG91dDsgZWFjaCByaW5nIG9mIGEgZmVhdHVyZVxuICogKGl0cyBwYXJ0cyBhbmQgaG9sZXMpIGlzIGEgcmluZyBvZiBpdHMgY2VsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBsYW5lQ2VsbFJpbmdzKFxuICB0aWxlczogcmVhZG9ubHkgeyBmZWF0dXJlczogcmVhZG9ubHkgVGlsZUZlYXR1cmVbXSB9W10sXG4gIGluZGV4OiBSZWFkb25seU1hcDxzdHJpbmcsIG51bWJlcj4sXG4gIHJlZjogU3BhdGlhbEltYWdlUmVmIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IFNwYXRpYWxQb2x5Z29uVGlsZSB7XG4gIGNvbnN0IFtzeCwgc3ldID0gcmVmPy5zY2FsZSA/PyBbMSwgMV07XG4gIGNvbnN0IFt0eCwgdHldID0gcmVmPy50cmFuc2xhdGUgPz8gWzAsIDBdO1xuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IHJpbmdzOiBGbG9hdDMyQXJyYXlbXSA9IFtdO1xuICBjb25zdCBvd25lcnM6IG51bWJlcltdID0gW107XG4gIGxldCB2ZXJ0aWNlcyA9IDA7XG4gIGZvciAoY29uc3QgdGlsZSBvZiB0aWxlcykge1xuICAgIGZvciAoY29uc3QgZiBvZiB0aWxlLmZlYXR1cmVzKSB7XG4gICAgICBpZiAoZi5vcGVuIHx8IHNlZW4uaGFzKGYuaWQpKSBjb250aW51ZTtcbiAgICAgIHNlZW4uYWRkKGYuaWQpO1xuICAgICAgY29uc3QgbyA9IGluZGV4LmdldChjZWxsSWRPZihmLmlkKSk7XG4gICAgICBpZiAobyA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgIGZvciAoY29uc3QgcmluZyBvZiBmLnJpbmdzKSB7XG4gICAgICAgIGlmIChyaW5nLmxlbmd0aCA8IDYpIGNvbnRpbnVlO1xuICAgICAgICByaW5ncy5wdXNoKHJpbmcpO1xuICAgICAgICBvd25lcnMucHVzaChvKTtcbiAgICAgICAgdmVydGljZXMgKz0gcmluZy5sZW5ndGggLyAyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCBjb29yZHMgPSBuZXcgRmxvYXQzMkFycmF5KHZlcnRpY2VzICogMik7XG4gIGNvbnN0IG9mZnNldHMgPSBuZXcgVWludDMyQXJyYXkocmluZ3MubGVuZ3RoICsgMSk7XG4gIGxldCB2ID0gMDtcbiAgcmluZ3MuZm9yRWFjaCgocmluZywgcikgPT4ge1xuICAgIG9mZnNldHNbcl0gPSB2O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmluZy5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgY29vcmRzW3YgKiAyXSA9IChyaW5nW2ldIC0gdHgpIC8gc3g7XG4gICAgICBjb29yZHNbdiAqIDIgKyAxXSA9IChyaW5nW2kgKyAxXSAtIHR5KSAvIHN5O1xuICAgICAgdisrO1xuICAgIH1cbiAgfSk7XG4gIG9mZnNldHNbcmluZ3MubGVuZ3RoXSA9IHY7XG4gIHJldHVybiB7IGNvdW50OiByaW5ncy5sZW5ndGgsIGNvb3Jkcywgb2Zmc2V0cywgb2JzZXJ2YXRpb246IFVpbnQzMkFycmF5LmZyb20ob3duZXJzKSB9O1xufVxuXG4vKiogT25lIHBsYW5lJ3MgdGlsZXMgb2YgYSByZWdpb24gc2V0OiB0aGUgcGxhbmUncyBzbGljZSBpbmRleCAoaXRzIHBsYWNlIGFtb25nIHRoZSBzZXQncyBwbGFuZXMpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQbGFuZVRpbGVzIHtcbiAgc2xpY2U6IG51bWJlcjtcbiAgdGlsZXM6IHJlYWRvbmx5IHsgZmVhdHVyZXM6IHJlYWRvbmx5IFRpbGVGZWF0dXJlW10gfVtdO1xufVxuXG4vKipcbiAqIEVhY2ggY2VsbCdzIG91dGxpbmVzIG9uIGV2ZXJ5IHBsYW5lIGl0IHNwYW5zLCBmcm9tIHRoZSBwbGFuZXMnIHRpbGVzIChhIGZlYXR1cmUgb25jZSwgdGhvdWdoIGluXG4gKiBldmVyeSB0aWxlIGl0IG1lZXRzKSwgZm9yIHRoZSAzRCByZWNvbnN0cnVjdGlvbiBvZiBlYWNoIGNlbGwgYnkgaXRzZWxmIChgQ2VsbE91dGxpbmVzYCwgc2xpY2Uga1xuICogYXQgeiA9IGspLiBPbmx5IGNlbGxzIG9mIGBjbGFzc2VzYCAoYWxsIHdoZW4gbnVsbCksIHdob3NlIG91dGxpbmVzJyBjZW50cmUgb3ZlciBhbGwgcGxhbmVzIGlzIGluXG4gKiBgd2l0aGluYCAoYFt4MCwgeTAsIHgxLCB5MV1gLCBpbWFnZSBweDsgYW55d2hlcmUgd2hlbiBhYnNlbnQpOiB0aGUgdGlsZXMgZmV0Y2hlZCBmb3IgYW4gYXJlYSBob2xkXG4gKiB0aGUgY2VsbHMgY3Jvc3NpbmcgaXRzIGVkZ2UgdG9vLCB3aGljaCBiZWxvbmcgdG8gdGhlIGFyZWEgdGhlaXIgY2VudHJlIGlzIGluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2VsbE91dGxpbmVzRnJvbVRpbGVzKFxuICBwbGFuZXM6IHJlYWRvbmx5IFBsYW5lVGlsZXNbXSxcbiAgaW5kZXg6IFJlYWRvbmx5TWFwPHN0cmluZywgbnVtYmVyPixcbiAgY2xhc3NlczogUmVhZG9ubHlTZXQ8c3RyaW5nPiB8IG51bGwsXG4gIHdpdGhpbj86IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdLFxuKTogeyBjZWxsOiBudW1iZXI7IGxhYmVsOiBzdHJpbmcgfCBudWxsOyBzbGljZXM6IHsgejogbnVtYmVyOyByaW5nczogRmxvYXQzMkFycmF5W10gfVtdIH1bXSB7XG4gIGNvbnN0IGJ5Q2VsbCA9IG5ldyBNYXA8XG4gICAgbnVtYmVyLFxuICAgIHsgbGFiZWw6IHN0cmluZyB8IG51bGw7IHNsaWNlczogeyB6OiBudW1iZXI7IHJpbmdzOiBGbG9hdDMyQXJyYXlbXSB9W107IGJveDogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfVxuICA+KCk7XG4gIGZvciAoY29uc3QgcGxhbmUgb2YgcGxhbmVzKSB7XG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgdGlsZSBvZiBwbGFuZS50aWxlcykge1xuICAgICAgZm9yIChjb25zdCBmIG9mIHRpbGUuZmVhdHVyZXMpIHtcbiAgICAgICAgaWYgKGYub3BlbiB8fCBzZWVuLmhhcyhmLmlkKSB8fCAhZi5yaW5ncy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgICAgICBzZWVuLmFkZChmLmlkKTtcbiAgICAgICAgaWYgKGNsYXNzZXMgJiYgIWNsYXNzZXMuaGFzKGYubGFiZWwgPz8gJycpKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgY2VsbCA9IGluZGV4LmdldChjZWxsSWRPZihmLmlkKSk7XG4gICAgICAgIGlmIChjZWxsID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgICAgICBsZXQgZW50cnkgPSBieUNlbGwuZ2V0KGNlbGwpO1xuICAgICAgICBpZiAoIWVudHJ5KSB7XG4gICAgICAgICAgZW50cnkgPSB7IGxhYmVsOiBmLmxhYmVsLCBzbGljZXM6IFtdLCBib3g6IFtJbmZpbml0eSwgSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XSB9O1xuICAgICAgICAgIGJ5Q2VsbC5zZXQoY2VsbCwgZW50cnkpO1xuICAgICAgICB9XG4gICAgICAgIGVudHJ5LnNsaWNlcy5wdXNoKHsgejogcGxhbmUuc2xpY2UsIHJpbmdzOiBmLnJpbmdzIH0pO1xuICAgICAgICBjb25zdCBiID0gZW50cnkuYm94O1xuICAgICAgICBiWzBdID0gTWF0aC5taW4oYlswXSwgZi5iYm94WzBdKTtcbiAgICAgICAgYlsxXSA9IE1hdGgubWluKGJbMV0sIGYuYmJveFsxXSk7XG4gICAgICAgIGJbMl0gPSBNYXRoLm1heChiWzJdLCBmLmJib3hbMl0pO1xuICAgICAgICBiWzNdID0gTWF0aC5tYXgoYlszXSwgZi5iYm94WzNdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3Qgb3V0OiB7IGNlbGw6IG51bWJlcjsgbGFiZWw6IHN0cmluZyB8IG51bGw7IHNsaWNlczogeyB6OiBudW1iZXI7IHJpbmdzOiBGbG9hdDMyQXJyYXlbXSB9W10gfVtdID0gW107XG4gIGZvciAoY29uc3QgW2NlbGwsIGVdIG9mIGJ5Q2VsbCkge1xuICAgIGlmICh3aXRoaW4pIHtcbiAgICAgIGNvbnN0IGN4ID0gKGUuYm94WzBdICsgZS5ib3hbMl0pIC8gMjtcbiAgICAgIGNvbnN0IGN5ID0gKGUuYm94WzFdICsgZS5ib3hbM10pIC8gMjtcbiAgICAgIGlmIChjeCA8IHdpdGhpblswXSB8fCBjeCA+PSB3aXRoaW5bMl0gfHwgY3kgPCB3aXRoaW5bMV0gfHwgY3kgPj0gd2l0aGluWzNdKSBjb250aW51ZTtcbiAgICB9XG4gICAgb3V0LnB1c2goeyBjZWxsLCBsYWJlbDogZS5sYWJlbCwgc2xpY2VzOiBlLnNsaWNlcyB9KTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuIl19
|