@fscharter/flowmap-data 8.0.2-fsc.1
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/dist/FlowmapAggregateAccessors.d.ts +16 -0
- package/dist/FlowmapAggregateAccessors.d.ts.map +1 -0
- package/dist/FlowmapAggregateAccessors.js +53 -0
- package/dist/FlowmapSelectors.d.ts +143 -0
- package/dist/FlowmapSelectors.d.ts.map +1 -0
- package/dist/FlowmapSelectors.js +881 -0
- package/dist/FlowmapState.d.ts +31 -0
- package/dist/FlowmapState.d.ts.map +1 -0
- package/dist/FlowmapState.js +7 -0
- package/dist/cluster/ClusterIndex.d.ts +42 -0
- package/dist/cluster/ClusterIndex.d.ts.map +1 -0
- package/dist/cluster/ClusterIndex.js +166 -0
- package/dist/cluster/cluster.d.ts +51 -0
- package/dist/cluster/cluster.d.ts.map +1 -0
- package/dist/cluster/cluster.js +267 -0
- package/dist/colors.d.ts +103 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +487 -0
- package/dist/getViewStateForLocations.d.ts +23 -0
- package/dist/getViewStateForLocations.d.ts.map +1 -0
- package/dist/getViewStateForLocations.js +54 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/provider/FlowmapDataProvider.d.ts +21 -0
- package/dist/provider/FlowmapDataProvider.d.ts.map +1 -0
- package/dist/provider/FlowmapDataProvider.js +22 -0
- package/dist/provider/LocalFlowmapDataProvider.d.ts +31 -0
- package/dist/provider/LocalFlowmapDataProvider.d.ts.map +1 -0
- package/dist/provider/LocalFlowmapDataProvider.js +115 -0
- package/dist/selector-functions.d.ts +10 -0
- package/dist/selector-functions.d.ts.map +1 -0
- package/dist/selector-functions.js +65 -0
- package/dist/time.d.ts +24 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +131 -0
- package/dist/types.d.ts +120 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +28 -0
- package/dist/util.d.ts +5 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +16 -0
- package/package.json +48 -0
- package/src/FlowmapAggregateAccessors.ts +76 -0
- package/src/FlowmapSelectors.ts +1539 -0
- package/src/FlowmapState.ts +40 -0
- package/src/cluster/ClusterIndex.ts +261 -0
- package/src/cluster/cluster.ts +394 -0
- package/src/colors.ts +771 -0
- package/src/getViewStateForLocations.ts +86 -0
- package/src/index.ts +19 -0
- package/src/provider/FlowmapDataProvider.ts +81 -0
- package/src/provider/LocalFlowmapDataProvider.ts +185 -0
- package/src/selector-functions.ts +93 -0
- package/src/time.ts +166 -0
- package/src/types.ts +172 -0
- package/src/util.ts +17 -0
- package/tsconfig.json +11 -0
- package/typings.d.ts +1 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Flowmap.gl contributors
|
|
3
|
+
* Copyright (c) 2018-2020 Teralytics
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { min, rollup } from 'd3-array';
|
|
7
|
+
import KDBush from 'kdbush';
|
|
8
|
+
const defaultOptions = {
|
|
9
|
+
minZoom: 0,
|
|
10
|
+
maxZoom: 16,
|
|
11
|
+
radius: 40,
|
|
12
|
+
extent: 512,
|
|
13
|
+
nodeSize: 64,
|
|
14
|
+
makeClusterName: (id, numPoints) => undefined,
|
|
15
|
+
makeClusterId: (id) => `{[${id}]}`,
|
|
16
|
+
};
|
|
17
|
+
export function isLeafPoint(p) {
|
|
18
|
+
const { index } = p;
|
|
19
|
+
return index != null;
|
|
20
|
+
}
|
|
21
|
+
export function isClusterPoint(p) {
|
|
22
|
+
const { id } = p;
|
|
23
|
+
return id != null;
|
|
24
|
+
}
|
|
25
|
+
export function clusterLocations(locations, locationAccessors, getLocationWeight, options) {
|
|
26
|
+
const { getLocationLon, getLocationLat, getLocationId } = locationAccessors;
|
|
27
|
+
const opts = {
|
|
28
|
+
...defaultOptions,
|
|
29
|
+
...options,
|
|
30
|
+
};
|
|
31
|
+
const { minZoom, maxZoom, nodeSize, makeClusterName, makeClusterId } = opts;
|
|
32
|
+
const trees = new Array(maxZoom + 1);
|
|
33
|
+
// generate a cluster object for each point and index input points into a KD-tree
|
|
34
|
+
let clusters = new Array();
|
|
35
|
+
let locationsCount = 0;
|
|
36
|
+
for (const location of locations) {
|
|
37
|
+
const x = getLocationLon(location);
|
|
38
|
+
const y = getLocationLat(location);
|
|
39
|
+
clusters.push({
|
|
40
|
+
x: lngX(x), // projected point coordinates
|
|
41
|
+
y: latY(y),
|
|
42
|
+
weight: getLocationWeight(getLocationId(location)),
|
|
43
|
+
zoom: Infinity, // the last zoom the point was processed at
|
|
44
|
+
index: locationsCount, // index of the source feature in the original input array,
|
|
45
|
+
parentId: -1, // parent cluster id
|
|
46
|
+
location,
|
|
47
|
+
});
|
|
48
|
+
locationsCount++;
|
|
49
|
+
}
|
|
50
|
+
const makeBush = (points) => {
|
|
51
|
+
const bush = new KDBush(points.length, nodeSize, Float32Array);
|
|
52
|
+
for (let i = 0; i < points.length; i++) {
|
|
53
|
+
bush.add(points[i].x, points[i].y);
|
|
54
|
+
}
|
|
55
|
+
bush.finish();
|
|
56
|
+
bush.points = points;
|
|
57
|
+
return bush;
|
|
58
|
+
};
|
|
59
|
+
// cluster points on max zoom, then cluster the results on previous zoom, etc.;
|
|
60
|
+
// results in a cluster hierarchy across zoom levels
|
|
61
|
+
trees[maxZoom + 1] = makeBush(clusters);
|
|
62
|
+
let prevZoom = maxZoom + 1;
|
|
63
|
+
for (let z = maxZoom; z >= minZoom; z--) {
|
|
64
|
+
// create a new set of clusters for the zoom and index them with a KD-tree
|
|
65
|
+
const _clusters = cluster(clusters, z, trees[prevZoom], opts);
|
|
66
|
+
if (_clusters.length === clusters.length) {
|
|
67
|
+
// same number of clusters => move the higher level clusters up
|
|
68
|
+
// no need to keep the same data on multiple levels
|
|
69
|
+
trees[z] = trees[prevZoom];
|
|
70
|
+
trees[prevZoom] = undefined;
|
|
71
|
+
prevZoom = z;
|
|
72
|
+
clusters = _clusters;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
prevZoom = z;
|
|
76
|
+
clusters = _clusters;
|
|
77
|
+
trees[z] = makeBush(clusters);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (trees.length === 0) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const numbersOfClusters = trees.map((d) => d?.points.length);
|
|
84
|
+
const minClusters = min(numbersOfClusters.filter((d) => d > 0));
|
|
85
|
+
let maxAvailZoom = findIndexOfMax(numbersOfClusters) ?? numbersOfClusters.length - 1;
|
|
86
|
+
const numUniqueLocations = countUniqueLocations(locations, locationAccessors);
|
|
87
|
+
if (numUniqueLocations < locationsCount) {
|
|
88
|
+
// Duplicate locations would be clustered together at any zoom level which can lead to having too many zooms.
|
|
89
|
+
// To avoid that, we need to find the max zoom level that has less or equal clusters than unique locations
|
|
90
|
+
// and drop all zoom levels beyond that (except the unclustered level).
|
|
91
|
+
const maxClustersZoom = findLastIndex(numbersOfClusters, (d) => d <= numUniqueLocations);
|
|
92
|
+
if (maxClustersZoom >= 0) {
|
|
93
|
+
// Now, move the unclustered points to the next zoom level to avoid having a gap
|
|
94
|
+
if (maxClustersZoom < maxAvailZoom) {
|
|
95
|
+
trees[maxClustersZoom + 1] = trees[maxAvailZoom];
|
|
96
|
+
trees.splice(maxClustersZoom + 2); // Remove all zoom levels beyond maxClustersZoom
|
|
97
|
+
}
|
|
98
|
+
maxAvailZoom = maxClustersZoom + 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const minAvailZoom = Math.min(maxAvailZoom, minClusters ? numbersOfClusters.lastIndexOf(minClusters) : maxAvailZoom);
|
|
102
|
+
const clusterLevels = new Array();
|
|
103
|
+
prevZoom = NaN;
|
|
104
|
+
for (let zoom = maxAvailZoom; zoom >= minAvailZoom; zoom--) {
|
|
105
|
+
let childrenByParent;
|
|
106
|
+
const tree = trees[zoom];
|
|
107
|
+
if (!tree)
|
|
108
|
+
continue;
|
|
109
|
+
if (trees[prevZoom] && zoom < maxAvailZoom) {
|
|
110
|
+
childrenByParent = rollup(trees[prevZoom].points, (points) => points.map((p) => p.id ? makeClusterId(p.id) : getLocationId(p.location)), (point) => point.parentId);
|
|
111
|
+
}
|
|
112
|
+
const nodes = [];
|
|
113
|
+
for (const point of tree.points) {
|
|
114
|
+
const { x, y, numPoints, location } = point;
|
|
115
|
+
if (isLeafPoint(point)) {
|
|
116
|
+
nodes.push({
|
|
117
|
+
id: getLocationId(location),
|
|
118
|
+
zoom,
|
|
119
|
+
lat: getLocationLat(location),
|
|
120
|
+
lon: getLocationLon(location),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else if (isClusterPoint(point)) {
|
|
124
|
+
const { id } = point;
|
|
125
|
+
const children = childrenByParent && childrenByParent.get(id);
|
|
126
|
+
if (!children) {
|
|
127
|
+
// Might happen if there are multiple locations with same coordinates
|
|
128
|
+
console.warn(`Omitting cluster with no children, point:`, point);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const cluster = {
|
|
132
|
+
id: makeClusterId(id),
|
|
133
|
+
name: makeClusterName(id, numPoints),
|
|
134
|
+
zoom,
|
|
135
|
+
lat: yLat(y),
|
|
136
|
+
lon: xLng(x),
|
|
137
|
+
children: children ?? [],
|
|
138
|
+
};
|
|
139
|
+
nodes.push(cluster);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
clusterLevels.push({
|
|
143
|
+
zoom,
|
|
144
|
+
nodes,
|
|
145
|
+
});
|
|
146
|
+
prevZoom = zoom;
|
|
147
|
+
}
|
|
148
|
+
return clusterLevels;
|
|
149
|
+
}
|
|
150
|
+
function createCluster(x, y, id, numPoints, weight) {
|
|
151
|
+
return {
|
|
152
|
+
x, // weighted cluster center
|
|
153
|
+
y,
|
|
154
|
+
zoom: Infinity, // the last zoom the cluster was processed at
|
|
155
|
+
id, // encodes index of the first child of the cluster and its zoom level
|
|
156
|
+
parentId: -1, // parent cluster id
|
|
157
|
+
numPoints,
|
|
158
|
+
weight,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function cluster(points, zoom, tree, options) {
|
|
162
|
+
const clusters = [];
|
|
163
|
+
const { radius, extent } = options;
|
|
164
|
+
const r = radius / (extent * Math.pow(2, zoom));
|
|
165
|
+
// loop through each point
|
|
166
|
+
for (let i = 0; i < points.length; i++) {
|
|
167
|
+
const p = points[i];
|
|
168
|
+
// if we've already visited the point at this zoom level, skip it
|
|
169
|
+
if (p.zoom <= zoom) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
p.zoom = zoom;
|
|
173
|
+
// find all nearby points
|
|
174
|
+
const neighborIds = tree.within(p.x, p.y, r);
|
|
175
|
+
let weight = p.weight || 1;
|
|
176
|
+
let numPoints = isClusterPoint(p) ? p.numPoints : 1;
|
|
177
|
+
let wx = p.x * weight;
|
|
178
|
+
let wy = p.y * weight;
|
|
179
|
+
// encode both zoom and point index on which the cluster originated
|
|
180
|
+
const id = (i << 5) + (zoom + 1);
|
|
181
|
+
for (const neighborId of neighborIds) {
|
|
182
|
+
const b = tree.points[neighborId];
|
|
183
|
+
// filter out neighbors that are already processed
|
|
184
|
+
if (b.zoom <= zoom) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
b.zoom = zoom; // save the zoom (so it doesn't get processed twice)
|
|
188
|
+
const weight2 = b.weight || 1;
|
|
189
|
+
const numPoints2 = b.numPoints || 1;
|
|
190
|
+
wx += b.x * weight2; // accumulate coordinates for calculating weighted center
|
|
191
|
+
wy += b.y * weight2;
|
|
192
|
+
weight += weight2;
|
|
193
|
+
numPoints += numPoints2;
|
|
194
|
+
b.parentId = id;
|
|
195
|
+
}
|
|
196
|
+
if (numPoints === 1) {
|
|
197
|
+
clusters.push(p);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
p.parentId = id;
|
|
201
|
+
clusters.push(createCluster(wx / weight, wy / weight, id, numPoints, weight));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return clusters;
|
|
205
|
+
}
|
|
206
|
+
// spherical mercator to longitude/latitude
|
|
207
|
+
function xLng(x) {
|
|
208
|
+
return (x - 0.5) * 360;
|
|
209
|
+
}
|
|
210
|
+
function yLat(y) {
|
|
211
|
+
const y2 = ((180 - y * 360) * Math.PI) / 180;
|
|
212
|
+
return (360 * Math.atan(Math.exp(y2))) / Math.PI - 90;
|
|
213
|
+
}
|
|
214
|
+
// longitude/latitude to spherical mercator in [0..1] range
|
|
215
|
+
function lngX(lng) {
|
|
216
|
+
return lng / 360 + 0.5;
|
|
217
|
+
}
|
|
218
|
+
function latY(lat) {
|
|
219
|
+
const sin = Math.sin((lat * Math.PI) / 180);
|
|
220
|
+
const y = 0.5 - (0.25 * Math.log((1 + sin) / (1 - sin))) / Math.PI;
|
|
221
|
+
return y < 0 ? 0 : y > 1 ? 1 : y;
|
|
222
|
+
}
|
|
223
|
+
function getX(p) {
|
|
224
|
+
return p.x;
|
|
225
|
+
}
|
|
226
|
+
function getY(p) {
|
|
227
|
+
return p.y;
|
|
228
|
+
}
|
|
229
|
+
function countUniqueLocations(locations, locationAccessors) {
|
|
230
|
+
const { getLocationLon, getLocationLat } = locationAccessors;
|
|
231
|
+
const countByLatLon = new Map();
|
|
232
|
+
let uniqueCnt = 0;
|
|
233
|
+
for (const loc of locations) {
|
|
234
|
+
const lon = getLocationLon(loc);
|
|
235
|
+
const lat = getLocationLat(loc);
|
|
236
|
+
const key = `${lon},${lat}`;
|
|
237
|
+
const prev = countByLatLon.get(key);
|
|
238
|
+
if (!prev) {
|
|
239
|
+
uniqueCnt++;
|
|
240
|
+
}
|
|
241
|
+
countByLatLon.set(key, prev ? prev + 1 : 1);
|
|
242
|
+
}
|
|
243
|
+
return uniqueCnt;
|
|
244
|
+
}
|
|
245
|
+
function findIndexOfMax(arr) {
|
|
246
|
+
let max = -Infinity;
|
|
247
|
+
let maxIndex = undefined;
|
|
248
|
+
for (let i = 0; i < arr.length; i++) {
|
|
249
|
+
const value = arr[i];
|
|
250
|
+
if (typeof value === 'number') {
|
|
251
|
+
if (value > max) {
|
|
252
|
+
max = value;
|
|
253
|
+
maxIndex = i;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return maxIndex;
|
|
258
|
+
}
|
|
259
|
+
function findLastIndex(arr, predicate) {
|
|
260
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
261
|
+
if (predicate(arr[i], i, arr)) {
|
|
262
|
+
return i;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return -1;
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbHVzdGVyL2NsdXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBQyxHQUFHLEVBQUUsTUFBTSxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ3JDLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQWtDNUIsTUFBTSxjQUFjLEdBQVk7SUFDOUIsT0FBTyxFQUFFLENBQUM7SUFDVixPQUFPLEVBQUUsRUFBRTtJQUNYLE1BQU0sRUFBRSxFQUFFO0lBQ1YsTUFBTSxFQUFFLEdBQUc7SUFDWCxRQUFRLEVBQUUsRUFBRTtJQUNaLGVBQWUsRUFBRSxDQUFDLEVBQVUsRUFBRSxTQUFpQixFQUFFLEVBQUUsQ0FBQyxTQUFTO0lBQzdELGFBQWEsRUFBRSxDQUFDLEVBQVUsRUFBRSxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUk7Q0FDM0MsQ0FBQztBQXNCRixNQUFNLFVBQVUsV0FBVyxDQUFJLENBQVc7SUFDeEMsTUFBTSxFQUFDLEtBQUssRUFBQyxHQUFHLENBQWlCLENBQUM7SUFDbEMsT0FBTyxLQUFLLElBQUksSUFBSSxDQUFDO0FBQ3ZCLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUFJLENBQVc7SUFDM0MsTUFBTSxFQUFDLEVBQUUsRUFBQyxHQUFHLENBQWlCLENBQUM7SUFDL0IsT0FBTyxFQUFFLElBQUksSUFBSSxDQUFDO0FBQ3BCLENBQUM7QUFJRCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLFNBQXNCLEVBQ3RCLGlCQUF1QyxFQUN2QyxpQkFBdUMsRUFDdkMsT0FBMEI7SUFFMUIsTUFBTSxFQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFDLEdBQUcsaUJBQWlCLENBQUM7SUFDMUUsTUFBTSxJQUFJLEdBQUc7UUFDWCxHQUFHLGNBQWM7UUFDakIsR0FBRyxPQUFPO0tBQ1gsQ0FBQztJQUNGLE1BQU0sRUFBQyxPQUFP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QUVELFNBQVMsY0FBYyxDQUFDLEdBQTJCO0lBQ2pELElBQUksR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQ3BCLElBQUksUUFBUSxHQUF1QixTQUFTLENBQUM7SUFFN0MsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNwQyxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFckIsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM5QixJQUFJLEtBQUssR0FBRyxHQUFHLEVBQUUsQ0FBQztnQkFDaEIsR0FBRyxHQUFHLEtBQUssQ0FBQztnQkFDWixRQUFRLEdBQUcsQ0FBQyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxRQUFRLENBQUM7QUFDbEIsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUNwQixHQUFRLEVBQ1IsU0FBMkQ7SUFFM0QsS0FBSyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDekMsSUFBSSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIEZsb3dtYXAuZ2wgY29udHJpYnV0b3JzXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtMjAyMCBUZXJhbHl0aWNzXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7bWluLCByb2xsdXB9IGZyb20gJ2QzLWFycmF5JztcbmltcG9ydCBLREJ1c2ggZnJvbSAna2RidXNoJztcbmltcG9ydCB7TG9jYXRpb25XZWlnaHRHZXR0ZXJ9IGZyb20gJy4vQ2x1c3RlckluZGV4JztcbmltcG9ydCB7Q2x1c3RlciwgQ2x1c3RlckxldmVsLCBDbHVzdGVyTm9kZSwgTG9jYXRpb25BY2Nlc3NvcnN9IGZyb20gJy4uL3R5cGVzJztcblxuLyoqXG4gKiBUaGUgY29kZSBpbiB0aGlzIGZpbGUgaXMgYSBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vbWFwYm94L3N1cGVyY2x1c3RlclxuICpcbiAqICBJU0MgTGljZW5zZVxuICpcbiAqICBDb3B5cmlnaHQgKGMpIDIwMTYsIE1hcGJveFxuICpcbiAqICBQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZVxuICogIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2VcbiAqICBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbiAqXG4gKiAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxuICogIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkRcbiAqICBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcbiAqICBJTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TU1xuICogIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUlxuICogIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0ZcbiAqICBUSElTIFNPRlRXQVJFLlxuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9ucyB7XG4gIG1pblpvb206IG51bWJlcjsgLy8gbWluIHpvb20gdG8gZ2VuZXJhdGUgY2x1c3RlcnMgb25cbiAgbWF4Wm9vbTogbnVtYmVyOyAvLyBtYXggem9vbSBsZXZlbCB0byBjbHVzdGVyIHRoZSBwb2ludHMgb25cbiAgcmFkaXVzOiBudW1iZXI7IC8vIGNsdXN0ZXIgcmFkaXVzIGluIHBpeGVsc1xuICBleHRlbnQ6IG51bWJlcjsgLy8gdGlsZSBleHRlbnQgKHJhZGl1cyBpcyBjYWxjdWxhdGVkIHJlbGF0aXZlIHRvIGl0KVxuICBub2RlU2l6ZTogbnVtYmVyOyAvLyBzaXplIG9mIHRoZSBLRC10cmVlIGxlYWYgbm9kZSwgYWZmZWN0cyBwZXJmb3JtYW5jZVxuICBtYWtlQ2x1c3Rlck5hbWU6IChpZDogbnVtYmVyLCBudW1Qb2ludHM6IG51bWJlcikgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBtYWtlQ2x1c3RlcklkOiAoaWQ6IG51bWJlcikgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBkZWZhdWx0T3B0aW9uczogT3B0aW9ucyA9IHtcbiAgbWluWm9vbTogMCxcbiAgbWF4Wm9vbTogMTYsXG4gIHJhZGl1czogNDAsXG4gIGV4dGVudDogNTEyLFxuICBub2RlU2l6ZTogNjQsXG4gIG1ha2VDbHVzdGVyTmFtZTogKGlkOiBudW1iZXIsIG51bVBvaW50czogbnVtYmVyKSA9PiB1bmRlZmluZWQsXG4gIG1ha2VDbHVzdGVySWQ6IChpZDogbnVtYmVyKSA9PiBge1ske2lkfV19YCxcbn07XG5cbmludGVyZmFjZSBCYXNlUG9pbnQge1xuICB4OiBudW1iZXI7IC8vIHByb2plY3RlZCBwb2ludCBjb29yZGluYXRlc1xuICB5OiBudW1iZXI7XG4gIHdlaWdodDogbnVtYmVyO1xuICB6b29tOiBudW1iZXI7IC8vIHRoZSBsYXN0IHpvb20gdGhlIHBvaW50IHdhcyBwcm9jZXNzZWQgYXRcbiAgcGFyZW50SWQ6IG51bWJlcjsgLy8gcGFyZW50IGNsdXN0ZXIgaWRcbn1cblxuaW50ZXJmYWNlIExlYWZQb2ludDxMPiBleHRlbmRzIEJhc2VQb2ludCB7XG4gIGluZGV4OiBudW1iZXI7IC8vIGluZGV4IG9mIHRoZSBzb3VyY2UgZmVhdHVyZSBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgYXJyYXksXG4gIGxvY2F0aW9uOiBMO1xufVxuXG5pbnRlcmZhY2UgQ2x1c3RlclBvaW50IGV4dGVuZHMgQmFzZVBvaW50IHtcbiAgaWQ6IG51bWJlcjtcbiAgbnVtUG9pbnRzOiBudW1iZXI7XG59XG5cbnR5cGUgUG9pbnQ8TD4gPSBMZWFmUG9pbnQ8TD4gfCBDbHVzdGVyUG9pbnQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0xlYWZQb2ludDxMPihwOiBQb2ludDxMPik6IHAgaXMgTGVhZlBvaW50PEw+IHtcbiAgY29uc3Qge2luZGV4fSA9IHAgYXMgTGVhZlBvaW50PEw+O1xuICByZXR1cm4gaW5kZXggIT0gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2x1c3RlclBvaW50PEw+KHA6IFBvaW50PEw+KTogcCBpcyBDbHVzdGVyUG9pbnQge1xuICBjb25zdCB7aWR9ID0gcCBhcyBDbHVzdGVyUG9pbnQ7XG4gIHJldHVybiBpZCAhPSBudWxsO1xufVxuXG50eXBlIFpvb21MZXZlbEtEQnVzaCA9IGFueTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNsdXN0ZXJMb2NhdGlvbnM8TD4oXG4gIGxvY2F0aW9uczogSXRlcmFibGU8TD4sXG4gIGxvY2F0aW9uQWNjZXNzb3JzOiBMb2NhdGlvbkFjY2Vzc29yczxMPixcbiAgZ2V0TG9jYXRpb25XZWlnaHQ6IExvY2F0aW9uV2VpZ2h0R2V0dGVyLFxuICBvcHRpb25zPzogUGFydGlhbDxPcHRpb25zPixcbik6IENsdXN0ZXJMZXZlbFtdIHtcbiAgY29uc3Qge2dldExvY2F0aW9uTG9uLCBnZXRMb2NhdGlvbkxhdCwgZ2V0TG9jYXRpb25JZH0gPSBsb2NhdGlvbkFjY2Vzc29ycztcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICAuLi5kZWZhdWx0T3B0aW9ucyxcbiAgICAuLi5vcHRpb25zLFxuICB9O1xuICBjb25zdCB7bWluWm9vbSwgbWF4Wm9vbSwgbm9kZVNpemUsIG1ha2VDbHVzdGVyTmFtZSwgbWFrZUNsdXN0ZXJJZH0gPSBvcHRzO1xuXG4gIGNvbnN0IHRyZWVzID0gbmV3IEFycmF5PFpvb21MZXZlbEtEQnVzaD4obWF4Wm9vbSArIDEpO1xuXG4gIC8vIGdlbmVyYXRlIGEgY2x1c3RlciBvYmplY3QgZm9yIGVhY2ggcG9pbnQgYW5kIGluZGV4IGlucHV0IHBvaW50cyBpbnRvIGEgS0QtdHJlZVxuICBsZXQgY2x1c3RlcnMgPSBuZXcgQXJyYXk8UG9pbnQ8TD4+KCk7XG4gIGxldCBsb2NhdGlvbnNDb3VudCA9IDA7XG4gIGZvciAoY29uc3QgbG9jYXRpb24gb2YgbG9jYXRpb25zKSB7XG4gICAgY29uc3QgeCA9IGdldExvY2F0aW9uTG9uKGxvY2F0aW9uKTtcbiAgICBjb25zdCB5ID0gZ2V0TG9jYXRpb25MYXQobG9jYXRpb24pO1xuICAgIGNsdXN0ZXJzLnB1c2goe1xuICAgICAgeDogbG5nWCh4KSwgLy8gcHJvamVjdGVkIHBvaW50IGNvb3JkaW5hdGVzXG4gICAgICB5OiBsYXRZKHkpLFxuICAgICAgd2VpZ2h0OiBnZXRMb2NhdGlvbldlaWdodChnZXRMb2NhdGlvbklkKGxvY2F0aW9uKSksXG4gICAgICB6b29tOiBJbmZpbml0eSwgLy8gdGhlIGxhc3Qgem9vbSB0aGUgcG9pbnQgd2FzIHByb2Nlc3NlZCBhdFxuICAgICAgaW5kZXg6IGxvY2F0aW9uc0NvdW50LCAvLyBpbmRleCBvZiB0aGUgc291cmNlIGZlYXR1cmUgaW4gdGhlIG9yaWdpbmFsIGlucHV0IGFycmF5LFxuICAgICAgcGFyZW50SWQ6IC0xLCAvLyBwYXJlbnQgY2x1c3RlciBpZFxuICAgICAgbG9jYXRpb24sXG4gICAgfSk7XG4gICAgbG9jYXRpb25zQ291bnQrKztcbiAgfVxuXG4gIGNvbnN0IG1ha2VCdXNoID0gKHBvaW50czogUG9pbnQ8TD5bXSkgPT4ge1xuICAgIGNvbnN0IGJ1c2ggPSBuZXcgS0RCdXNoKHBvaW50cy5sZW5ndGgsIG5vZGVTaXplLCBGbG9hdDMyQXJyYXkpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBidXNoLmFkZChwb2ludHNbaV0ueCwgcG9pbnRzW2ldLnkpO1xuICAgIH1cbiAgICBidXNoLmZpbmlzaCgpO1xuICAgIGJ1c2gucG9pbnRzID0gcG9pbnRzO1xuICAgIHJldHVybiBidXNoO1xuICB9O1xuXG4gIC8vIGNsdXN0ZXIgcG9pbnRzIG9uIG1heCB6b29tLCB0aGVuIGNsdXN0ZXIgdGhlIHJlc3VsdHMgb24gcHJldmlvdXMgem9vbSwgZXRjLjtcbiAgLy8gcmVzdWx0cyBpbiBhIGNsdXN0ZXIgaGllcmFyY2h5IGFjcm9zcyB6b29tIGxldmVsc1xuICB0cmVlc1ttYXhab29tICsgMV0gPSBtYWtlQnVzaChjbHVzdGVycyk7XG4gIGxldCBwcmV2Wm9vbSA9IG1heFpvb20gKyAxO1xuXG4gIGZvciAobGV0IHogPSBtYXhab29tOyB6ID49IG1pblpvb207IHotLSkge1xuICAgIC8vIGNyZWF0ZSBhIG5ldyBzZXQgb2YgY2x1c3RlcnMgZm9yIHRoZSB6b29tIGFuZCBpbmRleCB0aGVtIHdpdGggYSBLRC10cmVlXG4gICAgY29uc3QgX2NsdXN0ZXJzID0gY2x1c3RlcihjbHVzdGVycywgeiwgdHJlZXNbcHJldlpvb21dLCBvcHRzKTtcbiAgICBpZiAoX2NsdXN0ZXJzLmxlbmd0aCA9PT0gY2x1c3RlcnMubGVuZ3RoKSB7XG4gICAgICAvLyBzYW1lIG51bWJlciBvZiBjbHVzdGVycyA9PiBtb3ZlIHRoZSBoaWdoZXIgbGV2ZWwgY2x1c3RlcnMgdXBcbiAgICAgIC8vIG5vIG5lZWQgdG8ga2VlcCB0aGUgc2FtZSBkYXRhIG9uIG11bHRpcGxlIGxldmVsc1xuICAgICAgdHJlZXNbel0gPSB0cmVlc1twcmV2Wm9vbV07XG4gICAgICB0cmVlc1twcmV2Wm9vbV0gPSB1bmRlZmluZWQ7XG4gICAgICBwcmV2Wm9vbSA9IHo7XG4gICAgICBjbHVzdGVycyA9IF9jbHVzdGVycztcbiAgICB9IGVsc2Uge1xuICAgICAgcHJldlpvb20gPSB6O1xuICAgICAgY2x1c3RlcnMgPSBfY2x1c3RlcnM7XG4gICAgICB0cmVlc1t6XSA9IG1ha2VCdXNoKGNsdXN0ZXJzKTtcbiAgICB9XG4gIH1cblxuICBpZiAodHJlZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbnVtYmVyc09mQ2x1c3RlcnM6IG51bWJlcltdID0gdHJlZXMubWFwKChkKSA9PiBkPy5wb2ludHMubGVuZ3RoKTtcbiAgY29uc3QgbWluQ2x1c3RlcnMgPSBtaW4obnVtYmVyc09mQ2x1c3RlcnMuZmlsdGVyKChkKSA9PiBkID4gMCkpO1xuXG4gIGxldCBtYXhBdmFpbFpvb20gPVxuICAgIGZpbmRJbmRleE9mTWF4KG51bWJlcnNPZkNsdXN0ZXJzKSA/PyBudW1iZXJzT2ZDbHVzdGVycy5sZW5ndGggLSAxO1xuXG4gIGNvbnN0IG51bVVuaXF1ZUxvY2F0aW9ucyA9IGNvdW50VW5pcXVlTG9jYXRpb25zKGxvY2F0aW9ucywgbG9jYXRpb25BY2Nlc3NvcnMpO1xuICBpZiAobnVtVW5pcXVlTG9jYXRpb25zIDwgbG9jYXRpb25zQ291bnQpIHtcbiAgICAvLyBEdXBsaWNhdGUgbG9jYXRpb25zIHdvdWxkIGJlIGNsdXN0ZXJlZCB0b2dldGhlciBhdCBhbnkgem9vbSBsZXZlbCB3aGljaCBjYW4gbGVhZCB0byBoYXZpbmcgdG9vIG1hbnkgem9vbXMuXG4gICAgLy8gVG8gYXZvaWQgdGhhdCwgd2UgbmVlZCB0byBmaW5kIHRoZSBtYXggem9vbSBsZXZlbCB0aGF0IGhhcyBsZXNzIG9yIGVxdWFsIGNsdXN0ZXJzIHRoYW4gdW5pcXVlIGxvY2F0aW9uc1xuICAgIC8vIGFuZCBkcm9wIGFsbCB6b29tIGxldmVscyBiZXlvbmQgdGhhdCAoZXhjZXB0IHRoZSB1bmNsdXN0ZXJlZCBsZXZlbCkuXG4gICAgY29uc3QgbWF4Q2x1c3RlcnNab29tID0gZmluZExhc3RJbmRleChcbiAgICAgIG51bWJlcnNPZkNsdXN0ZXJzLFxuICAgICAgKGQpID0+IGQgPD0gbnVtVW5pcXVlTG9jYXRpb25zLFxuICAgICk7XG4gICAgaWYgKG1heENsdXN0ZXJzWm9vbSA+PSAwKSB7XG4gICAgICAvLyBOb3csIG1vdmUgdGhlIHVuY2x1c3RlcmVkIHBvaW50cyB0byB0aGUgbmV4dCB6b29tIGxldmVsIHRvIGF2b2lkIGhhdmluZyBhIGdhcFxuICAgICAgaWYgKG1heENsdXN0ZXJzWm9vbSA8IG1heEF2YWlsWm9vbSkge1xuICAgICAgICB0cmVlc1ttYXhDbHVzdGVyc1pvb20gKyAxXSA9IHRyZWVzW21heEF2YWlsWm9vbV07XG4gICAgICAgIHRyZWVzLnNwbGljZShtYXhDbHVzdGVyc1pvb20gKyAyKTsgLy8gUmVtb3ZlIGFsbCB6b29tIGxldmVscyBiZXlvbmQgbWF4Q2x1c3RlcnNab29tXG4gICAgICB9XG4gICAgICBtYXhBdmFpbFpvb20gPSBtYXhDbHVzdGVyc1pvb20gKyAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1pbkF2YWlsWm9vbSA9IE1hdGgubWluKFxuICAgIG1heEF2YWlsWm9vbSxcbiAgICBtaW5DbHVzdGVycyA/IG51bWJlcnNPZkNsdXN0ZXJzLmxhc3RJbmRleE9mKG1pbkNsdXN0ZXJzKSA6IG1heEF2YWlsWm9vbSxcbiAgKTtcblxuICBjb25zdCBjbHVzdGVyTGV2ZWxzID0gbmV3IEFycmF5PENsdXN0ZXJMZXZlbD4oKTtcbiAgcHJldlpvb20gPSBOYU47XG4gIGZvciAobGV0IHpvb20gPSBtYXhBdmFpbFpvb207IHpvb20gPj0gbWluQXZhaWxab29tOyB6b29tLS0pIHtcbiAgICBsZXQgY2hpbGRyZW5CeVBhcmVudDogTWFwPG51bWJlciwgKHN0cmluZyB8IG51bWJlcilbXT4gfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgdHJlZSA9IHRyZWVzW3pvb21dO1xuICAgIGlmICghdHJlZSkgY29udGludWU7XG4gICAgaWYgKHRyZWVzW3ByZXZab29tXSAmJiB6b29tIDwgbWF4QXZhaWxab29tKSB7XG4gICAgICBjaGlsZHJlbkJ5UGFyZW50ID0gcm9sbHVwKFxuICAgICAgICB0cmVlc1twcmV2Wm9vbV0ucG9pbnRzLFxuICAgICAgICAocG9pbnRzOiBhbnlbXSkgPT5cbiAgICAgICAgICBwb2ludHMubWFwKChwOiBhbnkpID0+XG4gICAgICAgICAgICBwLmlkID8gbWFrZUNsdXN0ZXJJZChwLmlkKSA6IGdldExvY2F0aW9uSWQocC5sb2NhdGlvbiksXG4gICAgICAgICAgKSxcbiAgICAgICAgKHBvaW50OiBhbnkpID0+IHBvaW50LnBhcmVudElkLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBub2RlczogQ2x1c3Rlck5vZGVbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcG9pbnQgb2YgdHJlZS5wb2ludHMpIHtcbiAgICAgIGNvbnN0IHt4LCB5LCBudW1Qb2ludHMsIGxvY2F0aW9ufSA9IHBvaW50O1xuICAgICAgaWYgKGlzTGVhZlBvaW50KHBvaW50KSkge1xuICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICBpZDogZ2V0TG9jYXRpb25JZChsb2NhdGlvbiksXG4gICAgICAgICAgem9vbSxcbiAgICAgICAgICBsYXQ6IGdldExvY2F0aW9uTGF0KGxvY2F0aW9uKSxcbiAgICAgICAgICBsb246IGdldExvY2F0aW9uTG9uKGxvY2F0aW9uKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzQ2x1c3RlclBvaW50KHBvaW50KSkge1xuICAgICAgICBjb25zdCB7aWR9ID0gcG9pbnQ7XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gY2hpbGRyZW5CeVBhcmVudCAmJiBjaGlsZHJlbkJ5UGFyZW50LmdldChpZCk7XG4gICAgICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgICAgICAvLyBNaWdodCBoYXBwZW4gaWYgdGhlcmUgYXJlIG11bHRpcGxlIGxvY2F0aW9ucyB3aXRoIHNhbWUgY29vcmRpbmF0ZXNcbiAgICAgICAgICBjb25zb2xlLndhcm4oYE9taXR0aW5nIGNsdXN0ZXIgd2l0aCBubyBjaGlsZHJlbiwgcG9pbnQ6YCwgcG9pbnQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNsdXN0ZXIgPSB7XG4gICAgICAgICAgaWQ6IG1ha2VDbHVzdGVySWQoaWQpLFxuICAgICAgICAgIG5hbWU6IG1ha2VDbHVzdGVyTmFtZShpZCwgbnVtUG9pbnRzKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIGxhdDogeUxhdCh5KSxcbiAgICAgICAgICBsb246IHhMbmcoeCksXG4gICAgICAgICAgY2hpbGRyZW46IGNoaWxkcmVuID8/IFtdLFxuICAgICAgICB9IGFzIENsdXN0ZXI7XG4gICAgICAgIG5vZGVzLnB1c2goY2x1c3Rlcik7XG4gICAgICB9XG4gICAgfVxuICAgIGNsdXN0ZXJMZXZlbHMucHVzaCh7XG4gICAgICB6b29tLFxuICAgICAgbm9kZXMsXG4gICAgfSk7XG4gICAgcHJldlpvb20gPSB6b29tO1xuICB9XG4gIHJldHVybiBjbHVzdGVyTGV2ZWxzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDbHVzdGVyKFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbiAgaWQ6IG51bWJlcixcbiAgbnVtUG9pbnRzOiBudW1iZXIsXG4gIHdlaWdodDogbnVtYmVyLFxuKTogQ2x1c3RlclBvaW50IHtcbiAgcmV0dXJuIHtcbiAgICB4LCAvLyB3ZWlnaHRlZCBjbHVzdGVyIGNlbnRlclxuICAgIHksXG4gICAgem9vbTogSW5maW5pdHksIC8vIHRoZSBsYXN0IHpvb20gdGhlIGNsdXN0ZXIgd2FzIHByb2Nlc3NlZCBhdFxuICAgIGlkLCAvLyBlbmNvZGVzIGluZGV4IG9mIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgY2x1c3RlciBhbmQgaXRzIHpvb20gbGV2ZWxcbiAgICBwYXJlbnRJZDogLTEsIC8vIHBhcmVudCBjbHVzdGVyIGlkXG4gICAgbnVtUG9pbnRzLFxuICAgIHdlaWdodCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gY2x1c3RlcjxMPihcbiAgcG9pbnRzOiBQb2ludDxMPltdLFxuICB6b29tOiBudW1iZXIsXG4gIHRyZWU6IFpvb21MZXZlbEtEQnVzaCxcbiAgb3B0aW9uczogT3B0aW9ucyxcbikge1xuICBjb25zdCBjbHVzdGVyczogUG9pbnQ8TD5bXSA9IFtdO1xuICBjb25zdCB7cmFkaXVzLCBleHRlbnR9ID0gb3B0aW9ucztcbiAgY29uc3QgciA9IHJhZGl1cyAvIChleHRlbnQgKiBNYXRoLnBvdygyLCB6b29tKSk7XG5cbiAgLy8gbG9vcCB0aHJvdWdoIGVhY2ggcG9pbnRcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBwID0gcG9pbnRzW2ldO1xuICAgIC8vIGlmIHdlJ3ZlIGFscmVhZHkgdmlzaXRlZCB0aGUgcG9pbnQgYXQgdGhpcyB6b29tIGxldmVsLCBza2lwIGl0XG4gICAgaWYgKHAuem9vbSA8PSB6b29tKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcC56b29tID0gem9vbTtcblxuICAgIC8vIGZpbmQgYWxsIG5lYXJieSBwb2ludHNcbiAgICBjb25zdCBuZWlnaGJvcklkcyA9IHRyZWUud2l0aGluKHAueCwgcC55LCByKTtcblxuICAgIGxldCB3ZWlnaHQgPSBwLndlaWdodCB8fCAxO1xuICAgIGxldCBudW1Qb2ludHMgPSBpc0NsdXN0ZXJQb2ludChwKSA/IHAubnVtUG9pbnRzIDogMTtcbiAgICBsZXQgd3ggPSBwLnggKiB3ZWlnaHQ7XG4gICAgbGV0IHd5ID0gcC55ICogd2VpZ2h0O1xuXG4gICAgLy8gZW5jb2RlIGJvdGggem9vbSBhbmQgcG9pbnQgaW5kZXggb24gd2hpY2ggdGhlIGNsdXN0ZXIgb3JpZ2luYXRlZFxuICAgIGNvbnN0IGlkID0gKGkgPDwgNSkgKyAoem9vbSArIDEpO1xuXG4gICAgZm9yIChjb25zdCBuZWlnaGJvcklkIG9mIG5laWdoYm9ySWRzKSB7XG4gICAgICBjb25zdCBiID0gdHJlZS5wb2ludHNbbmVpZ2hib3JJZF07XG4gICAgICAvLyBmaWx0ZXIgb3V0IG5laWdoYm9ycyB0aGF0IGFyZSBhbHJlYWR5IHByb2Nlc3NlZFxuICAgICAgaWYgKGIuem9vbSA8PSB6b29tKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYi56b29tID0gem9vbTsgLy8gc2F2ZSB0aGUgem9vbSAoc28gaXQgZG9lc24ndCBnZXQgcHJvY2Vzc2VkIHR3aWNlKVxuXG4gICAgICBjb25zdCB3ZWlnaHQyID0gYi53ZWlnaHQgfHwgMTtcbiAgICAgIGNvbnN0IG51bVBvaW50czIgPSBiLm51bVBvaW50cyB8fCAxO1xuICAgICAgd3ggKz0gYi54ICogd2VpZ2h0MjsgLy8gYWNjdW11bGF0ZSBjb29yZGluYXRlcyBmb3IgY2FsY3VsYXRpbmcgd2VpZ2h0ZWQgY2VudGVyXG4gICAgICB3eSArPSBiLnkgKiB3ZWlnaHQyO1xuXG4gICAgICB3ZWlnaHQgKz0gd2VpZ2h0MjtcbiAgICAgIG51bVBvaW50cyArPSBudW1Qb2ludHMyO1xuICAgICAgYi5wYXJlbnRJZCA9IGlkO1xuICAgIH1cblxuICAgIGlmIChudW1Qb2ludHMgPT09IDEpIHtcbiAgICAgIGNsdXN0ZXJzLnB1c2gocCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHAucGFyZW50SWQgPSBpZDtcbiAgICAgIGNsdXN0ZXJzLnB1c2goXG4gICAgICAgIGNyZWF0ZUNsdXN0ZXIod3ggLyB3ZWlnaHQsIHd5IC8gd2VpZ2h0LCBpZCwgbnVtUG9pbnRzLCB3ZWlnaHQpLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2x1c3RlcnM7XG59XG5cbi8vIHNwaGVyaWNhbCBtZXJjYXRvciB0byBsb25naXR1ZGUvbGF0aXR1ZGVcbmZ1bmN0aW9uIHhMbmcoeDogbnVtYmVyKSB7XG4gIHJldHVybiAoeCAtIDAuNSkgKiAzNjA7XG59XG5cbmZ1bmN0aW9uIHlMYXQoeTogbnVtYmVyKSB7XG4gIGNvbnN0IHkyID0gKCgxODAgLSB5ICogMzYwKSAqIE1hdGguUEkpIC8gMTgwO1xuICByZXR1cm4gKDM2MCAqIE1hdGguYXRhbihNYXRoLmV4cCh5MikpKSAvIE1hdGguUEkgLSA5MDtcbn1cblxuLy8gbG9uZ2l0dWRlL2xhdGl0dWRlIHRvIHNwaGVyaWNhbCBtZXJjYXRvciBpbiBbMC4uMV0gcmFuZ2VcbmZ1bmN0aW9uIGxuZ1gobG5nOiBudW1iZXIpIHtcbiAgcmV0dXJuIGxuZyAvIDM2MCArIDAuNTtcbn1cblxuZnVuY3Rpb24gbGF0WShsYXQ6IG51bWJlcikge1xuICBjb25zdCBzaW4gPSBNYXRoLnNpbigobGF0ICogTWF0aC5QSSkgLyAxODApO1xuICBjb25zdCB5ID0gMC41IC0gKDAuMjUgKiBNYXRoLmxvZygoMSArIHNpbikgLyAoMSAtIHNpbikpKSAvIE1hdGguUEk7XG4gIHJldHVybiB5IDwgMCA/IDAgOiB5ID4gMSA/IDEgOiB5O1xufVxuXG5mdW5jdGlvbiBnZXRYPEw+KHA6IFBvaW50PEw+KSB7XG4gIHJldHVybiBwLng7XG59XG5cbmZ1bmN0aW9uIGdldFk8TD4ocDogUG9pbnQ8TD4pIHtcbiAgcmV0dXJuIHAueTtcbn1cblxuZnVuY3Rpb24gY291bnRVbmlxdWVMb2NhdGlvbnM8TD4oXG4gIGxvY2F0aW9uczogSXRlcmFibGU8TD4sXG4gIGxvY2F0aW9uQWNjZXNzb3JzOiBMb2NhdGlvbkFjY2Vzc29yczxMPixcbikge1xuICBjb25zdCB7Z2V0TG9jYXRpb25Mb24sIGdldExvY2F0aW9uTGF0fSA9IGxvY2F0aW9uQWNjZXNzb3JzO1xuICBjb25zdCBjb3VudEJ5TGF0TG9uID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgbGV0IHVuaXF1ZUNudCA9IDA7XG4gIGZvciAoY29uc3QgbG9jIG9mIGxvY2F0aW9ucykge1xuICAgIGNvbnN0IGxvbiA9IGdldExvY2F0aW9uTG9uKGxvYyk7XG4gICAgY29uc3QgbGF0ID0gZ2V0TG9jYXRpb25MYXQobG9jKTtcbiAgICBjb25zdCBrZXkgPSBgJHtsb259LCR7bGF0fWA7XG4gICAgY29uc3QgcHJldiA9IGNvdW50QnlMYXRMb24uZ2V0KGtleSk7XG4gICAgaWYgKCFwcmV2KSB7XG4gICAgICB1bmlxdWVDbnQrKztcbiAgICB9XG4gICAgY291bnRCeUxhdExvbi5zZXQoa2V5LCBwcmV2ID8gcHJldiArIDEgOiAxKTtcbiAgfVxuICByZXR1cm4gdW5pcXVlQ250O1xufVxuXG5mdW5jdGlvbiBmaW5kSW5kZXhPZk1heChhcnI6IChudW1iZXIgfCB1bmRlZmluZWQpW10pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBsZXQgbWF4ID0gLUluZmluaXR5O1xuICBsZXQgbWF4SW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHZhbHVlID0gYXJyW2ldO1xuXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGlmICh2YWx1ZSA+IG1heCkge1xuICAgICAgICBtYXggPSB2YWx1ZTtcbiAgICAgICAgbWF4SW5kZXggPSBpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtYXhJbmRleDtcbn1cblxuZnVuY3Rpb24gZmluZExhc3RJbmRleDxUPihcbiAgYXJyOiBUW10sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyLCBhcnJheTogVFtdKSA9PiBib29sZWFuLFxuKTogbnVtYmVyIHtcbiAgZm9yIChsZXQgaSA9IGFyci5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChwcmVkaWNhdGUoYXJyW2ldLCBpLCBhcnIpKSB7XG4gICAgICByZXR1cm4gaTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuIl19
|
package/dist/colors.d.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { SettingsState } from './FlowmapState';
|
|
2
|
+
export type ColorScale = (value: number) => RGBA;
|
|
3
|
+
export type RGBA = [number, number, number, number];
|
|
4
|
+
export declare function opacityFloatToInteger(opacity: number): number;
|
|
5
|
+
export declare function opacifyHex(hexCode: string, opacity: number): string;
|
|
6
|
+
export declare function colorAsRgba(color: string | number[]): RGBA;
|
|
7
|
+
export declare enum ColorScheme {
|
|
8
|
+
primary = "#162d3c"
|
|
9
|
+
}
|
|
10
|
+
export declare const GRAYISH: string[];
|
|
11
|
+
export declare const schemeTeal: string[];
|
|
12
|
+
export declare const DEFAULT_COLOR_SCHEME: string[];
|
|
13
|
+
export declare const COLOR_SCHEMES: {
|
|
14
|
+
[key: string]: string[];
|
|
15
|
+
};
|
|
16
|
+
export declare const COLOR_SCHEME_KEYS: string[];
|
|
17
|
+
export declare function getFlowmapColors(settings: SettingsState): Colors | DiffColors;
|
|
18
|
+
export declare function getColors(diffMode: boolean, colorScheme: string | string[] | undefined, darkMode: boolean, fadeEnabled: boolean, fadeOpacityEnabled: boolean, fadeAmount: number, animate: boolean): Colors | DiffColors;
|
|
19
|
+
export declare function createFlowColorScale(domain: [number, number], scheme: string[], animate: boolean | undefined): ColorScale;
|
|
20
|
+
export declare function getFlowColorScale(colors: ColorsRGBA | DiffColorsRGBA, magnitudeExtent: [number, number] | undefined, animate: boolean | undefined): (magnitude: number) => [number, number, number, number];
|
|
21
|
+
export declare function isDiffColors(colors: DiffColors | Colors): colors is DiffColors;
|
|
22
|
+
export declare function isDiffColorsRGBA(colors: DiffColorsRGBA | ColorsRGBA): colors is DiffColorsRGBA;
|
|
23
|
+
export interface FlowColors {
|
|
24
|
+
scheme?: string[];
|
|
25
|
+
highlighted?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface LocationCircleColors {
|
|
28
|
+
inner?: string;
|
|
29
|
+
outgoing?: string;
|
|
30
|
+
incoming?: string;
|
|
31
|
+
highlighted?: string;
|
|
32
|
+
empty?: string;
|
|
33
|
+
outlineEmptyMix?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface LocationAreaColors {
|
|
36
|
+
outline?: string;
|
|
37
|
+
normal?: string;
|
|
38
|
+
selected?: string;
|
|
39
|
+
highlighted?: string;
|
|
40
|
+
connected?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface BaseColors {
|
|
43
|
+
darkMode?: boolean;
|
|
44
|
+
locationAreas?: LocationAreaColors;
|
|
45
|
+
dimmedOpacity?: number;
|
|
46
|
+
outlineColor?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface Colors extends BaseColors {
|
|
49
|
+
flows?: FlowColors;
|
|
50
|
+
locationCircles?: LocationCircleColors;
|
|
51
|
+
}
|
|
52
|
+
export interface FlowAndCircleColors {
|
|
53
|
+
flows?: FlowColors;
|
|
54
|
+
locationCircles?: LocationCircleColors;
|
|
55
|
+
}
|
|
56
|
+
export interface DiffColors extends BaseColors {
|
|
57
|
+
positive?: FlowAndCircleColors;
|
|
58
|
+
negative?: FlowAndCircleColors;
|
|
59
|
+
}
|
|
60
|
+
export interface FlowColorsRGBA {
|
|
61
|
+
scheme: string[];
|
|
62
|
+
highlighted: RGBA;
|
|
63
|
+
}
|
|
64
|
+
export interface LocationCircleColorsRGBA {
|
|
65
|
+
inner: RGBA;
|
|
66
|
+
outgoing: RGBA;
|
|
67
|
+
incoming: RGBA;
|
|
68
|
+
highlighted: RGBA;
|
|
69
|
+
empty: RGBA;
|
|
70
|
+
outlineEmptyMix: number;
|
|
71
|
+
}
|
|
72
|
+
export interface LocationAreaColorsRGBA {
|
|
73
|
+
outline: RGBA;
|
|
74
|
+
normal: RGBA;
|
|
75
|
+
selected: RGBA;
|
|
76
|
+
highlighted: RGBA;
|
|
77
|
+
connected: RGBA;
|
|
78
|
+
}
|
|
79
|
+
export interface BaseColorsRGBA {
|
|
80
|
+
darkMode: boolean;
|
|
81
|
+
locationAreas: LocationAreaColorsRGBA;
|
|
82
|
+
dimmedOpacity: number;
|
|
83
|
+
outlineColor: RGBA;
|
|
84
|
+
}
|
|
85
|
+
export interface ColorsRGBA extends BaseColorsRGBA {
|
|
86
|
+
flows: FlowColorsRGBA;
|
|
87
|
+
locationCircles: LocationCircleColorsRGBA;
|
|
88
|
+
}
|
|
89
|
+
export interface FlowAndCircleColorsRGBA {
|
|
90
|
+
flows: FlowColorsRGBA;
|
|
91
|
+
locationCircles: LocationCircleColorsRGBA;
|
|
92
|
+
}
|
|
93
|
+
export interface DiffColorsRGBA extends BaseColorsRGBA {
|
|
94
|
+
positive: FlowAndCircleColorsRGBA;
|
|
95
|
+
negative: FlowAndCircleColorsRGBA;
|
|
96
|
+
}
|
|
97
|
+
export declare function getColorsRGBA(colors: Colors | undefined): ColorsRGBA;
|
|
98
|
+
export declare function getDiffColorsRGBA(colors: DiffColors | undefined): DiffColorsRGBA;
|
|
99
|
+
export declare function rgbaAsString(color: RGBA): string;
|
|
100
|
+
export declare function midpoint(a: number, b: number, zeroToOne: number): number;
|
|
101
|
+
export declare function mixColorsRGBA(color1: RGBA, color2: RGBA, zeroToOne: number): RGBA;
|
|
102
|
+
export default getColors;
|
|
103
|
+
//# sourceMappingURL=colors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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"}
|