@plait/core 0.77.3 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/fesm2022/plait-core.mjs.map +1 -1
  2. package/package.json +1 -3
  3. package/esm2022/constants/cursor.mjs +0 -13
  4. package/esm2022/constants/index.mjs +0 -20
  5. package/esm2022/constants/keycodes.mjs +0 -127
  6. package/esm2022/constants/selection.mjs +0 -6
  7. package/esm2022/constants/zoom.mjs +0 -4
  8. package/esm2022/context.mjs +0 -23
  9. package/esm2022/core/element/context-change.mjs +0 -13
  10. package/esm2022/core/element/context.mjs +0 -2
  11. package/esm2022/core/element/element-flavour.mjs +0 -140
  12. package/esm2022/core/element/element-ref.mjs +0 -2
  13. package/esm2022/core/list-render.mjs +0 -217
  14. package/esm2022/differs/default_iterable_differ.mjs +0 -614
  15. package/esm2022/differs/iterable_differs.mjs +0 -9
  16. package/esm2022/interfaces/board.mjs +0 -108
  17. package/esm2022/interfaces/custom-types.mjs +0 -5
  18. package/esm2022/interfaces/direction.mjs +0 -8
  19. package/esm2022/interfaces/element.mjs +0 -43
  20. package/esm2022/interfaces/group.mjs +0 -6
  21. package/esm2022/interfaces/history.mjs +0 -5
  22. package/esm2022/interfaces/index.mjs +0 -19
  23. package/esm2022/interfaces/node.mjs +0 -57
  24. package/esm2022/interfaces/operation.mjs +0 -96
  25. package/esm2022/interfaces/path-ref.mjs +0 -15
  26. package/esm2022/interfaces/path.mjs +0 -183
  27. package/esm2022/interfaces/plugin.mjs +0 -6
  28. package/esm2022/interfaces/point.mjs +0 -27
  29. package/esm2022/interfaces/pointer.mjs +0 -6
  30. package/esm2022/interfaces/rectangle-client.mjs +0 -171
  31. package/esm2022/interfaces/selection.mjs +0 -13
  32. package/esm2022/interfaces/svg-arc-command.mjs +0 -2
  33. package/esm2022/interfaces/theme.mjs +0 -49
  34. package/esm2022/interfaces/viewport.mjs +0 -7
  35. package/esm2022/plait-core.mjs +0 -5
  36. package/esm2022/plugins/create-board.mjs +0 -122
  37. package/esm2022/plugins/index.mjs +0 -11
  38. package/esm2022/plugins/with-board.mjs +0 -20
  39. package/esm2022/plugins/with-hand.mjs +0 -113
  40. package/esm2022/plugins/with-history.mjs +0 -91
  41. package/esm2022/plugins/with-hotkey.mjs +0 -96
  42. package/esm2022/plugins/with-i18n.mjs +0 -13
  43. package/esm2022/plugins/with-moving.mjs +0 -282
  44. package/esm2022/plugins/with-options.mjs +0 -13
  45. package/esm2022/plugins/with-related-fragment.mjs +0 -23
  46. package/esm2022/plugins/with-selection.mjs +0 -230
  47. package/esm2022/public-api.mjs +0 -16
  48. package/esm2022/testing/core/create-board.mjs +0 -15
  49. package/esm2022/testing/core/fake-weak-map.mjs +0 -18
  50. package/esm2022/testing/core/index.mjs +0 -3
  51. package/esm2022/testing/fake-events/event-objects.mjs +0 -131
  52. package/esm2022/testing/fake-events/index.mjs +0 -2
  53. package/esm2022/testing/index.mjs +0 -3
  54. package/esm2022/testing/test-element.mjs +0 -9
  55. package/esm2022/transforms/board.mjs +0 -137
  56. package/esm2022/transforms/element.mjs +0 -22
  57. package/esm2022/transforms/general.mjs +0 -146
  58. package/esm2022/transforms/group.mjs +0 -64
  59. package/esm2022/transforms/index.mjs +0 -17
  60. package/esm2022/transforms/node.mjs +0 -37
  61. package/esm2022/transforms/selection.mjs +0 -26
  62. package/esm2022/transforms/theme.mjs +0 -8
  63. package/esm2022/transforms/viewport.mjs +0 -8
  64. package/esm2022/transforms/z-index.mjs +0 -20
  65. package/esm2022/utils/angle.mjs +0 -164
  66. package/esm2022/utils/board.mjs +0 -18
  67. package/esm2022/utils/clipboard/clipboard.mjs +0 -40
  68. package/esm2022/utils/clipboard/common.mjs +0 -82
  69. package/esm2022/utils/clipboard/data-transfer.mjs +0 -33
  70. package/esm2022/utils/clipboard/index.mjs +0 -3
  71. package/esm2022/utils/clipboard/navigator-clipboard.mjs +0 -71
  72. package/esm2022/utils/clipboard/types.mjs +0 -13
  73. package/esm2022/utils/common.mjs +0 -79
  74. package/esm2022/utils/debug.mjs +0 -91
  75. package/esm2022/utils/dnd.mjs +0 -8
  76. package/esm2022/utils/dom/common.mjs +0 -75
  77. package/esm2022/utils/dom/environment.mjs +0 -2
  78. package/esm2022/utils/dom/foreign.mjs +0 -26
  79. package/esm2022/utils/dom/index.mjs +0 -4
  80. package/esm2022/utils/drawing/arrow.mjs +0 -23
  81. package/esm2022/utils/drawing/circle.mjs +0 -4
  82. package/esm2022/utils/drawing/line.mjs +0 -47
  83. package/esm2022/utils/drawing/rectangle.mjs +0 -36
  84. package/esm2022/utils/element.mjs +0 -90
  85. package/esm2022/utils/environment.mjs +0 -14
  86. package/esm2022/utils/fragment.mjs +0 -27
  87. package/esm2022/utils/group.mjs +0 -239
  88. package/esm2022/utils/helper.mjs +0 -68
  89. package/esm2022/utils/history.mjs +0 -96
  90. package/esm2022/utils/hotkeys.mjs +0 -109
  91. package/esm2022/utils/id-creator.mjs +0 -11
  92. package/esm2022/utils/index.mjs +0 -35
  93. package/esm2022/utils/iterable.mjs +0 -32
  94. package/esm2022/utils/math.mjs +0 -480
  95. package/esm2022/utils/mobile.mjs +0 -6
  96. package/esm2022/utils/moving-element.mjs +0 -17
  97. package/esm2022/utils/pointer.mjs +0 -13
  98. package/esm2022/utils/position.mjs +0 -9
  99. package/esm2022/utils/selected-element.mjs +0 -145
  100. package/esm2022/utils/selection.mjs +0 -151
  101. package/esm2022/utils/snap/snap-moving.mjs +0 -199
  102. package/esm2022/utils/snap/snap.mjs +0 -211
  103. package/esm2022/utils/to-image.mjs +0 -204
  104. package/esm2022/utils/to-point.mjs +0 -74
  105. package/esm2022/utils/tree.mjs +0 -22
  106. package/esm2022/utils/viewport.mjs +0 -227
  107. package/esm2022/utils/weak-maps.mjs +0 -27
  108. package/esm2022/utils/z-index.mjs +0 -166
@@ -1,480 +0,0 @@
1
- import { Point } from '../interfaces';
2
- import { RectangleClient } from '../interfaces/rectangle-client';
3
- // https://stackoverflow.com/a/6853926/232122
4
- export function distanceBetweenPointAndSegment(x, y, x1, y1, x2, y2) {
5
- const A = x - x1;
6
- const B = y - y1;
7
- const C = x2 - x1;
8
- const D = y2 - y1;
9
- const dot = A * C + B * D;
10
- const lenSquare = C * C + D * D;
11
- let param = -1;
12
- if (lenSquare !== 0) {
13
- // in case of 0 length line
14
- param = dot / lenSquare;
15
- }
16
- let xx, yy;
17
- if (param < 0) {
18
- xx = x1;
19
- yy = y1;
20
- }
21
- else if (param > 1) {
22
- xx = x2;
23
- yy = y2;
24
- }
25
- else {
26
- xx = x1 + param * C;
27
- yy = y1 + param * D;
28
- }
29
- const dx = x - xx;
30
- const dy = y - yy;
31
- return Math.hypot(dx, dy);
32
- }
33
- export function getNearestPointBetweenPointAndSegment(point, linePoints) {
34
- const x = point[0], y = point[1], x1 = linePoints[0][0], y1 = linePoints[0][1], x2 = linePoints[1][0], y2 = linePoints[1][1];
35
- const A = x - x1;
36
- const B = y - y1;
37
- const C = x2 - x1;
38
- const D = y2 - y1;
39
- const dot = A * C + B * D;
40
- const lenSquare = C * C + D * D;
41
- let param = -1;
42
- if (lenSquare !== 0) {
43
- // in case of 0 length line
44
- param = dot / lenSquare;
45
- }
46
- let xx, yy;
47
- if (param < 0) {
48
- xx = x1;
49
- yy = y1;
50
- }
51
- else if (param > 1) {
52
- xx = x2;
53
- yy = y2;
54
- }
55
- else {
56
- xx = x1 + param * C;
57
- yy = y1 + param * D;
58
- }
59
- return [xx, yy];
60
- }
61
- export function distanceBetweenPointAndSegments(point, points) {
62
- const len = points.length;
63
- let distance = Infinity;
64
- if (points.length === 1) {
65
- return distanceBetweenPointAndPoint(...points[0], ...point);
66
- }
67
- for (let i = 0; i < len - 1; i++) {
68
- const p = points[i];
69
- const p2 = points[i + 1];
70
- const currentDistance = distanceBetweenPointAndSegment(point[0], point[1], p[0], p[1], p2[0], p2[1]);
71
- if (currentDistance < distance) {
72
- distance = currentDistance;
73
- }
74
- }
75
- return distance;
76
- }
77
- export function getNearestPointBetweenPointAndSegments(point, points, isClose = true) {
78
- const len = points.length;
79
- let distance = Infinity;
80
- let result = point;
81
- for (let i = 0; i < len; i++) {
82
- const p = points[i];
83
- if (i === len - 1 && !isClose)
84
- continue;
85
- const p2 = i === len - 1 ? points[0] : points[i + 1];
86
- const currentDistance = distanceBetweenPointAndSegment(point[0], point[1], p[0], p[1], p2[0], p2[1]);
87
- if (currentDistance < distance) {
88
- distance = currentDistance;
89
- result = getNearestPointBetweenPointAndSegment(point, [p, p2]);
90
- }
91
- }
92
- return result;
93
- }
94
- export function getNearestPointBetweenPointAndDiscreteSegments(point, segments) {
95
- let minDistance = Infinity;
96
- let nearestPoint = point;
97
- for (const segment of segments) {
98
- const currentNearestPoint = getNearestPointBetweenPointAndSegment(point, segment);
99
- const currentDistance = distanceBetweenPointAndPoint(point[0], point[1], currentNearestPoint[0], currentNearestPoint[1]);
100
- if (currentDistance < minDistance) {
101
- minDistance = currentDistance;
102
- nearestPoint = currentNearestPoint;
103
- }
104
- }
105
- return nearestPoint;
106
- }
107
- export function getNearestPointBetweenPointAndEllipse(point, center, rx, ry) {
108
- const rectangleClient = {
109
- x: center[0] - rx,
110
- y: center[1] - ry,
111
- height: ry * 2,
112
- width: rx * 2
113
- };
114
- // https://stackoverflow.com/a/46007540/232122
115
- const px = Math.abs(point[0] - rectangleClient.x - rectangleClient.width / 2);
116
- const py = Math.abs(point[1] - rectangleClient.y - rectangleClient.height / 2);
117
- let tx = 0.707;
118
- let ty = 0.707;
119
- const a = Math.abs(rectangleClient.width) / 2;
120
- const b = Math.abs(rectangleClient.height) / 2;
121
- [0, 1, 2, 3].forEach((x) => {
122
- const xx = a * tx;
123
- const yy = b * ty;
124
- const ex = ((a * a - b * b) * tx ** 3) / a;
125
- const ey = ((b * b - a * a) * ty ** 3) / b;
126
- const rx = xx - ex;
127
- const ry = yy - ey;
128
- const qx = px - ex;
129
- const qy = py - ey;
130
- const r = Math.hypot(ry, rx);
131
- const q = Math.hypot(qy, qx);
132
- tx = Math.min(1, Math.max(0, ((qx * r) / q + ex) / a));
133
- ty = Math.min(1, Math.max(0, ((qy * r) / q + ey) / b));
134
- const t = Math.hypot(ty, tx);
135
- tx /= t;
136
- ty /= t;
137
- });
138
- const signX = point[0] > center[0] ? 1 : -1;
139
- const signY = point[1] > center[1] ? 1 : -1;
140
- return [center[0] + a * tx * signX, center[1] + b * ty * signY];
141
- }
142
- export function rotate(x1, y1, x2, y2, angle) {
143
- // 𝑎′𝑥=(𝑎𝑥−𝑐𝑥)cos𝜃−(𝑎𝑦−𝑐𝑦)sin𝜃+𝑐𝑥
144
- // 𝑎′𝑦=(𝑎𝑥−𝑐𝑥)sin𝜃+(𝑎𝑦−𝑐𝑦)cos𝜃+𝑐𝑦.
145
- // https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
146
- return [(x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle) + x2, (x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2];
147
- }
148
- export function distanceBetweenPointAndPoint(x1, y1, x2, y2) {
149
- const dx = x1 - x2;
150
- const dy = y1 - y2;
151
- return Math.hypot(dx, dy);
152
- }
153
- // https://stackoverflow.com/questions/5254838/calculating-distance-between-a-point-and-a-rectangular-box-nearest-point
154
- export function distanceBetweenPointAndRectangle(x, y, rect) {
155
- var dx = Math.max(rect.x - x, 0, x - (rect.x + rect.width));
156
- var dy = Math.max(rect.y - y, 0, y - (rect.y + rect.height));
157
- return Math.sqrt(dx * dx + dy * dy);
158
- }
159
- export const isLineHitLine = (a, b, c, d) => {
160
- if (Point.isEquals(a, b) && Point.isEquals(c, d) && !Point.isEquals(a, c)) {
161
- return false;
162
- }
163
- const crossProduct = (v1, v2) => v1[0] * v2[1] - v1[1] * v2[0];
164
- const ab = [b[0] - a[0], b[1] - a[1]];
165
- const ac = [c[0] - a[0], c[1] - a[1]];
166
- const ad = [d[0] - a[0], d[1] - a[1]];
167
- const ca = [a[0] - c[0], a[1] - c[1]];
168
- const cb = [b[0] - c[0], b[1] - c[1]];
169
- const cd = [d[0] - c[0], d[1] - c[1]];
170
- return crossProduct(ab, ac) * crossProduct(ab, ad) <= 0 && crossProduct(cd, ca) * crossProduct(cd, cb) <= 0;
171
- };
172
- export const isLineHitRectangle = (points, rectangle) => {
173
- if (points.length === 1) {
174
- return RectangleClient.isPointInRectangle(rectangle, points[0]);
175
- }
176
- const rectanglePoints = RectangleClient.getCornerPoints(rectangle);
177
- const len = points.length;
178
- for (let i = 0; i < len; i++) {
179
- const p1 = points[i];
180
- const p2 = points[(i + 1) % len];
181
- if (i === len - 1 && Point.isEquals(p1, p2))
182
- continue;
183
- const isHit = isSingleLineHitRectangleEdge(p1, p2, rectangle);
184
- if (isHit || isPointInPolygon(p1, rectanglePoints) || isPointInPolygon(p2, rectanglePoints)) {
185
- return true;
186
- }
187
- }
188
- return false;
189
- };
190
- export const isLineHitRectangleEdge = (points, rectangle, isClose = true) => {
191
- const len = points.length;
192
- for (let i = 0; i < len; i++) {
193
- if (i === len - 1 && !isClose)
194
- continue;
195
- const p1 = points[i];
196
- const p2 = points[(i + 1) % len];
197
- const isHit = isSingleLineHitRectangleEdge(p1, p2, rectangle);
198
- if (isHit) {
199
- return true;
200
- }
201
- }
202
- return false;
203
- };
204
- export const isSingleLineHitRectangleEdge = (p1, p2, rectangle) => {
205
- const rectanglePoints = RectangleClient.getCornerPoints(rectangle);
206
- return (isLineHitLine(p1, p2, rectanglePoints[0], rectanglePoints[1]) ||
207
- isLineHitLine(p1, p2, rectanglePoints[1], rectanglePoints[2]) ||
208
- isLineHitLine(p1, p2, rectanglePoints[2], rectanglePoints[3]) ||
209
- isLineHitLine(p1, p2, rectanglePoints[3], rectanglePoints[0]));
210
- };
211
- //https://stackoverflow.com/questions/22521982/check-if-point-is-inside-a-polygon
212
- export const isPointInPolygon = (point, points) => {
213
- // ray-casting algorithm based on
214
- // https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html
215
- const x = point[0], y = point[1];
216
- let inside = false;
217
- for (var i = 0, j = points.length - 1; i < points.length; j = i++) {
218
- let xi = points[i][0], yi = points[i][1];
219
- let xj = points[j][0], yj = points[j][1];
220
- let intersect = yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
221
- if (intersect)
222
- inside = !inside;
223
- }
224
- return inside;
225
- };
226
- export const isPointInEllipse = (point, center, rx, ry, angle = 0) => {
227
- const cosAngle = Math.cos(angle);
228
- const sinAngle = Math.sin(angle);
229
- const x1 = (point[0] - center[0]) * cosAngle + (point[1] - center[1]) * sinAngle;
230
- const y1 = (point[1] - center[1]) * cosAngle - (point[0] - center[0]) * sinAngle;
231
- return (x1 * x1) / (rx * rx) + (y1 * y1) / (ry * ry) <= 1;
232
- };
233
- export const isPointInRoundRectangle = (point, rectangle, radius, angle = 0) => {
234
- const { x: rectX, y: rectY, width, height } = rectangle;
235
- const isInRectangle = point[0] >= rectX && point[0] <= rectX + width && point[1] >= rectY && point[1] <= rectY + height;
236
- const handleLeftTop = point[0] >= rectX &&
237
- point[0] <= rectX + radius &&
238
- point[1] >= rectY &&
239
- point[1] <= rectY + radius &&
240
- Math.hypot(point[0] - (rectX + radius), point[1] - (rectY + radius)) > radius;
241
- const handleLeftBottom = point[0] >= rectX &&
242
- point[0] <= rectX + radius &&
243
- point[1] >= rectY + height &&
244
- point[1] <= rectY + height - radius &&
245
- Math.hypot(point[0] - (rectX + radius), point[1] - (rectY + height - radius)) > radius;
246
- const handleRightTop = point[0] >= rectX + width - radius &&
247
- point[0] <= rectX + width &&
248
- point[1] >= rectY &&
249
- point[1] <= rectY + radius &&
250
- Math.hypot(point[0] - (rectX + width - radius), point[1] - (rectY + radius)) > radius;
251
- const handleRightBottom = point[0] >= rectX + width - radius &&
252
- point[0] <= rectX + width &&
253
- point[1] >= rectY + height - radius &&
254
- point[1] <= rectY + height &&
255
- Math.hypot(point[0] - (rectX + width - radius), point[1] - (rectY + height - radius)) > radius;
256
- const isInCorner = handleLeftTop || handleLeftBottom || handleRightTop || handleRightBottom;
257
- return isInRectangle && !isInCorner;
258
- };
259
- // https://gist.github.com/nicholaswmin/c2661eb11cad5671d816
260
- export const catmullRomFitting = function (points) {
261
- const alpha = 0.5;
262
- let p0, p1, p2, p3, bp1, bp2, d1, d2, d3, A, B, N, M;
263
- var d3powA, d2powA, d3pow2A, d2pow2A, d1pow2A, d1powA;
264
- const result = [];
265
- result.push([Math.round(points[0][0]), Math.round(points[0][1])]);
266
- var length = points.length;
267
- for (var i = 0; i < length - 1; i++) {
268
- p0 = i == 0 ? points[0] : points[i - 1];
269
- p1 = points[i];
270
- p2 = points[i + 1];
271
- p3 = i + 2 < length ? points[i + 2] : p2;
272
- d1 = Math.sqrt(Math.pow(p0[0] - p1[0], 2) + Math.pow(p0[1] - p1[1], 2));
273
- d2 = Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
274
- d3 = Math.sqrt(Math.pow(p2[0] - p3[0], 2) + Math.pow(p2[1] - p3[1], 2));
275
- // Catmull-Rom to Cubic Bezier conversion matrix
276
- // A = 2d1^2a + 3d1^a * d2^a + d3^2a
277
- // B = 2d3^2a + 3d3^a * d2^a + d2^2a
278
- // [ 0 1 0 0 ]
279
- // [ -d2^2a /N A/N d1^2a /N 0 ]
280
- // [ 0 d3^2a /M B/M -d2^2a /M ]
281
- // [ 0 0 1 0 ]
282
- d3powA = Math.pow(d3, alpha);
283
- d3pow2A = Math.pow(d3, 2 * alpha);
284
- d2powA = Math.pow(d2, alpha);
285
- d2pow2A = Math.pow(d2, 2 * alpha);
286
- d1powA = Math.pow(d1, alpha);
287
- d1pow2A = Math.pow(d1, 2 * alpha);
288
- A = 2 * d1pow2A + 3 * d1powA * d2powA + d2pow2A;
289
- B = 2 * d3pow2A + 3 * d3powA * d2powA + d2pow2A;
290
- N = 3 * d1powA * (d1powA + d2powA);
291
- if (N > 0) {
292
- N = 1 / N;
293
- }
294
- M = 3 * d3powA * (d3powA + d2powA);
295
- if (M > 0) {
296
- M = 1 / M;
297
- }
298
- bp1 = [(-d2pow2A * p0[0] + A * p1[0] + d1pow2A * p2[0]) * N, (-d2pow2A * p0[1] + A * p1[1] + d1pow2A * p2[1]) * N];
299
- bp2 = [(d3pow2A * p1[0] + B * p2[0] - d2pow2A * p3[0]) * M, (d3pow2A * p1[1] + B * p2[1] - d2pow2A * p3[1]) * M];
300
- if (bp1[0] == 0 && bp1[1] == 0) {
301
- bp1 = p1;
302
- }
303
- if (bp2[0] == 0 && bp2[1] == 0) {
304
- bp2 = p2;
305
- }
306
- result.push(bp1, bp2, p2);
307
- }
308
- return result;
309
- };
310
- /**
311
- * the result of slope is based on Cartesian coordinate system
312
- * x, y are based on the position in the Cartesian coordinate system
313
- */
314
- export function getEllipseTangentSlope(x, y, a, b) {
315
- if (Math.abs(y) === 0) {
316
- return x > 0 ? -Infinity : Infinity;
317
- }
318
- const k = (-b * b * x) / (a * a * y);
319
- return k;
320
- }
321
- /**
322
- * x, y are based on the position in the Cartesian coordinate system
323
- */
324
- export function getVectorFromPointAndSlope(x, y, slope) {
325
- if (slope === Infinity) {
326
- return [0, -1];
327
- }
328
- else if (slope === -Infinity) {
329
- return [0, 1];
330
- }
331
- let vector = [1, -slope];
332
- if (y < 0) {
333
- vector = [-vector[0], -vector[1]];
334
- }
335
- return vector;
336
- }
337
- /**
338
- * The DOM likes values to be fixed to 3 decimal places
339
- */
340
- export function toDomPrecision(v) {
341
- return +v.toFixed(4);
342
- }
343
- export function toFixed(v) {
344
- return +v.toFixed(2);
345
- }
346
- export function ceilToDecimal(value, decimalPlaces) {
347
- const factor = Math.pow(10, decimalPlaces);
348
- return Math.ceil(value * factor) / factor;
349
- }
350
- /**
351
- * Whether two numbers numbers a and b are approximately equal.
352
- *
353
- * @param a - The first point.
354
- * @param b - The second point.
355
- * @public
356
- */
357
- export function approximately(a, b, precision = 0.000001) {
358
- return Math.abs(a - b) <= precision;
359
- }
360
- // https://medium.com/@steveruiz/find-the-points-where-a-line-segment-intercepts-an-angled-ellipse-in-javascript-typescript-e451524beece
361
- export function getCrossingPointsBetweenEllipseAndSegment(startPoint, endPoint, cx, cy, rx, ry, segment_only = true) {
362
- // If the ellipse or line segment are empty, return no tValues.
363
- if (rx === 0 || ry === 0 || (startPoint[0] === endPoint[0] && startPoint[1] === endPoint[1])) {
364
- return [];
365
- }
366
- rx = rx < 0 ? rx : -rx;
367
- ry = ry < 0 ? ry : -ry;
368
- startPoint[0] -= cx;
369
- startPoint[1] -= cy;
370
- endPoint[0] -= cx;
371
- endPoint[1] -= cy;
372
- // Calculate the quadratic parameters.
373
- var A = ((endPoint[0] - startPoint[0]) * (endPoint[0] - startPoint[0])) / rx / rx +
374
- ((endPoint[1] - startPoint[1]) * (endPoint[1] - startPoint[1])) / ry / ry;
375
- var B = (2 * startPoint[0] * (endPoint[0] - startPoint[0])) / rx / rx + (2 * startPoint[1] * (endPoint[1] - startPoint[1])) / ry / ry;
376
- var C = (startPoint[0] * startPoint[0]) / rx / rx + (startPoint[1] * startPoint[1]) / ry / ry - 1;
377
- // Make a list of t values (normalized points on the line where intersections occur).
378
- var tValues = [];
379
- // Calculate the discriminant.
380
- var discriminant = B * B - 4 * A * C;
381
- if (discriminant === 0) {
382
- // One real solution.
383
- tValues.push(-B / 2 / A);
384
- }
385
- else if (discriminant > 0) {
386
- // Two real solutions.
387
- tValues.push((-B + Math.sqrt(discriminant)) / 2 / A);
388
- tValues.push((-B - Math.sqrt(discriminant)) / 2 / A);
389
- }
390
- return (tValues
391
- // Filter to only points that are on the segment.
392
- .filter((t) => !segment_only || (t >= 0 && t <= 1))
393
- // Solve for points.
394
- .map((t) => [startPoint[0] + (endPoint[0] - startPoint[0]) * t + cx, startPoint[1] + (endPoint[1] - startPoint[1]) * t + cy]));
395
- }
396
- /**
397
- * Get a point between two points.
398
- * @param x0 The x-axis coordinate of the first point.
399
- * @param y0 The y-axis coordinate of the first point.
400
- * @param x1 The x-axis coordinate of the second point.
401
- * @param y1 The y-axis coordinate of the second point.
402
- * @param d Normalized
403
- */
404
- export function getPointBetween(x0, y0, x1, y1, d = 0.5) {
405
- return [x0 + (x1 - x0) * d, y0 + (y1 - y0) * d];
406
- }
407
- /**
408
- * 获取点到半椭圆弧段的最近点
409
- * @param point 目标点
410
- * @param startPoint 弧段起点
411
- * @param arcCommand SVG 弧形命令参数
412
- */
413
- /**
414
- * 计算椭圆弧的中心点和实际半径
415
- */
416
- export function getEllipseArcCenter(startPoint, arcCommand) {
417
- // 1. 将坐标转换到标准位置
418
- const dx = (arcCommand.endX - startPoint[0]) / 2;
419
- const dy = (arcCommand.endY - startPoint[1]) / 2;
420
- const cosAngle = Math.cos(arcCommand.xAxisRotation);
421
- const sinAngle = Math.sin(arcCommand.xAxisRotation);
422
- // 旋转到椭圆坐标系
423
- const x1 = cosAngle * dx + sinAngle * dy;
424
- const y1 = -sinAngle * dx + cosAngle * dy;
425
- // 2. 计算中心点
426
- const rx = Math.abs(arcCommand.rx);
427
- const ry = Math.abs(arcCommand.ry);
428
- // 确保半径足够大
429
- const lambda = (x1 * x1) / (rx * rx) + (y1 * y1) / (ry * ry);
430
- const factor = lambda > 1 ? Math.sqrt(lambda) : 1;
431
- const adjustedRx = rx * factor;
432
- const adjustedRy = ry * factor;
433
- // 计算中心点坐标
434
- const sign = arcCommand.largeArcFlag === arcCommand.sweepFlag ? -1 : 1;
435
- const sq = (adjustedRx * adjustedRx * adjustedRy * adjustedRy - adjustedRx * adjustedRx * y1 * y1 - adjustedRy * adjustedRy * x1 * x1) /
436
- (adjustedRx * adjustedRx * y1 * y1 + adjustedRy * adjustedRy * x1 * x1);
437
- const coef = sign * Math.sqrt(Math.max(0, sq));
438
- const centerX = coef * ((adjustedRx * y1) / adjustedRy);
439
- const centerY = coef * (-(adjustedRy * x1) / adjustedRx);
440
- // 3. 转换回原始坐标系
441
- const cx = cosAngle * centerX - sinAngle * centerY + (startPoint[0] + arcCommand.endX) / 2;
442
- const cy = sinAngle * centerX + cosAngle * centerY + (startPoint[1] + arcCommand.endY) / 2;
443
- return {
444
- center: [cx, cy],
445
- rx: adjustedRx,
446
- ry: adjustedRy
447
- };
448
- }
449
- export function getNearestPointBetweenPointAndArc(point, startPoint, arcCommand) {
450
- const { center, rx, ry } = getEllipseArcCenter(startPoint, arcCommand);
451
- // 获取椭圆上的最近点
452
- const nearestPoint = getNearestPointBetweenPointAndEllipse(point, center, rx, ry);
453
- // 判断最近点是否在弧段上
454
- const startAngle = Math.atan2(startPoint[1] - center[1], startPoint[0] - center[0]);
455
- const endAngle = Math.atan2(arcCommand.endY - center[1], arcCommand.endX - center[0]);
456
- const pointAngle = Math.atan2(nearestPoint[1] - center[1], nearestPoint[0] - center[0]);
457
- // 检查点是否在弧段范围内
458
- const isInArc = isAngleBetween(pointAngle, startAngle, endAngle, arcCommand.sweepFlag === 1);
459
- if (isInArc) {
460
- return nearestPoint;
461
- }
462
- // 如果不在弧段上,返回最近的端点
463
- const distanceToStart = distanceBetweenPointAndPoint(point[0], point[1], startPoint[0], startPoint[1]);
464
- const distanceToEnd = distanceBetweenPointAndPoint(point[0], point[1], arcCommand.endX, arcCommand.endY);
465
- return distanceToStart < distanceToEnd ? startPoint : [arcCommand.endX, arcCommand.endY];
466
- }
467
- function isAngleBetween(angle, start, end, clockwise) {
468
- // 标准化角度到 [0, 2π]
469
- const normalize = (a) => ((a % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);
470
- const a = normalize(angle);
471
- const s = normalize(start);
472
- const e = normalize(end);
473
- if (clockwise) {
474
- return s <= e ? a >= s && a <= e : a >= s || a <= e;
475
- }
476
- else {
477
- return s >= e ? a <= s && a >= e : a <= s || a >= e;
478
- }
479
- }
480
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3V0aWxzL21hdGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDckQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWpFLDZDQUE2QztBQUM3QyxNQUFNLFVBQVUsOEJBQThCLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxFQUFVLEVBQUUsRUFBVSxFQUFFLEVBQVUsRUFBRSxFQUFVO0lBQy9HLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDakIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNqQixNQUFNLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFFbEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNmLElBQUksU0FBUyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xCLDJCQUEyQjtRQUMzQixLQUFLLEdBQUcsR0FBRyxHQUFHLFNBQVMsQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQ1gsSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDWixFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ1IsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNaLENBQUM7U0FBTSxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNuQixFQUFFLEdBQUcs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QzNDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRTNDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDbkIsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUVuQixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQ25CLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFFbkIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFN0IsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDN0IsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNSLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDWixDQUFDLENBQUMsQ0FBQztJQUNILE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxN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RyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0UsTUFBTSxFQUFFLEdBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QyxNQUFNLEVBQUUsR0FBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sRUFBRSxHQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0MsTUFBTSxFQUFFLEdBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QyxNQUFNLEVBQUUsR0FBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sRUFBRSxHQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFN0MsT0FBTyxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLFlBQVksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJ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QUNwQixRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2xCLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFFbEIsc0NBQXNDO0lBQ3RDLElBQUksQ0FBQyxHQUNELENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtRQUN6RSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUM5RSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDdEksSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUVsRyxxRkFBcUY7SUFDckYsSUFB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QUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFbkMsVUFBVTtJQUNWLE1BQU0sTUFBTSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzdELE1BQU0sTUFBTSxHQUFHLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVsRCxNQUFNLFVBQVUsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBQy9CLE1BQU0sVUFBVSxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFFL0IsVUFBVTtJQUNWLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxZQUFZLEtBQUssVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RSxNQUFNLEVBQUUsR0FDSixDQUFDLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsVUFBVSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsVUFBVSxHQUFHLFVBQVUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1FBQzNILENBQUMsVUFBVSxHQUFHLFVBQVUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLFVBQVUsR0FBRyxVQUFVLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFL0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxVQUFVLEdBQUcsRUFBRSxDQUFDLEdB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Q0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFckYsTUFBTSxDQUFDLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNCLE1BQU0sQ0FBQyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixNQUFNLENBQUMsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFekIsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNaLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEQsQ0FBQztTQUFNLENBQUM7UUFDSixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hELENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUG9pbnQsIFNWR0FyY0NvbW1hbmQgfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFJlY3RhbmdsZUNsaWVudCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVjdGFuZ2xlLWNsaWVudCc7XG5cbi8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS82ODUzOTI2LzIzMjEyMlxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlQmV0d2VlblBvaW50QW5kU2VnbWVudCh4OiBudW1iZXIsIHk6IG51bWJlciwgeDE6IG51bWJlciwgeTE6IG51bWJlciwgeDI6IG51bWJlciwgeTI6IG51bWJlcikge1xuICAgIGNvbnN0IEEgPSB4IC0geDE7XG4gICAgY29uc3QgQiA9IHkgLSB5MTtcbiAgICBjb25zdCBDID0geDIgLSB4MTtcbiAgICBjb25zdCBEID0geTIgLSB5MTtcblxuICAgIGNvbnN0IGRvdCA9IEEgKiBDICsgQiAqIEQ7XG4gICAgY29uc3QgbGVuU3F1YXJlID0gQyAqIEMgKyBEICogRDtcbiAgICBsZXQgcGFyYW0gPSAtMTtcbiAgICBpZiAobGVuU3F1YXJlICE9PSAwKSB7XG4gICAgICAgIC8vIGluIGNhc2Ugb2YgMCBsZW5ndGggbGluZVxuICAgICAgICBwYXJhbSA9IGRvdCAvIGxlblNxdWFyZTtcbiAgICB9XG5cbiAgICBsZXQgeHgsIHl5O1xuICAgIGlmIChwYXJhbSA8IDApIHtcbiAgICAgICAgeHggPSB4MTtcbiAgICAgICAgeXkgPSB5MTtcbiAgICB9IGVsc2UgaWYgKHBhcmFtID4gMSkge1xuICAgICAgICB4eCA9IHgyO1xuICAgICAgICB5eSA9IHkyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHh4ID0geDEgKyBwYXJhbSAqIEM7XG4gICAgICAgIHl5ID0geTEgKyBwYXJhbSAqIEQ7XG4gICAgfVxuXG4gICAgY29uc3QgZHggPSB4IC0geHg7XG4gICAgY29uc3QgZHkgPSB5IC0geXk7XG4gICAgcmV0dXJuIE1hdGguaHlwb3QoZHgsIGR5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5lYXJlc3RQb2ludEJldHdlZW5Qb2ludEFuZFNlZ21lbnQocG9pbnQ6IFBvaW50LCBsaW5lUG9pbnRzOiBbUG9pbnQsIFBvaW50XSkge1xuICAgIGNvbnN0IHggPSBwb2ludFswXSxcbiAgICAgICAgeSA9IHBvaW50WzFdLFxuICAgICAgICB4MSA9IGxpbmVQb2ludHNbMF1bMF0sXG4gICAgICAgIHkxID0gbGluZVBvaW50c1swXVsxXSxcbiAgICAgICAgeDIgPSBsaW5lUG9pbnRzWzFdWzBdLFxuICAgICAgICB5MiA9IGxpbmVQb2ludHNbMV1bMV07XG4gICAgY29uc3QgQSA9IHggLSB4MTtcbiAgICBjb25zdCBCID0geSAtIHkxO1xuICAgIGNvbnN0IEMgPSB4MiAtIHgxO1xuICAgIGNvbnN0IEQgPSB5MiAtIHkxO1xuXG4gICAgY29uc3QgZG90ID0gQSAqIEMgKyBCICogRDtcbiAgICBjb25zdCBsZW5TcXVhcmUgPSBDICogQyArIEQgKiBEO1xuICAgIGxldCBwYXJhbSA9IC0xO1xuICAgIGlmIChsZW5TcXVhcmUgIT09IDApIHtcbiAgICAgICAgLy8gaW4gY2FzZSBvZiAwIGxlbmd0aCBsaW5lXG4gICAgICAgIHBhcmFtID0gZG90IC8gbGVuU3F1YXJlO1xuICAgIH1cblxuICAgIGxldCB4eCwgeXk7XG4gICAgaWYgKHBhcmFtIDwgMCkge1xuICAgICAgICB4eCA9IHgxO1xuICAgICAgICB5eSA9IHkxO1xuICAgIH0gZWxzZSBpZiAocGFyYW0gPiAxKSB7XG4gICAgICAgIHh4ID0geDI7XG4gICAgICAgIHl5ID0geTI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeHggPSB4MSArIHBhcmFtICogQztcbiAgICAgICAgeXkgPSB5MSArIHBhcmFtICogRDtcbiAgICB9XG5cbiAgICByZXR1cm4gW3h4LCB5eV0gYXMgUG9pbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZUJldHdlZW5Qb2ludEFuZFNlZ21lbnRzKHBvaW50OiBQb2ludCwgcG9pbnRzOiBQb2ludFtdKSB7XG4gICAgY29uc3QgbGVuID0gcG9pbnRzLmxlbmd0aDtcbiAgICBsZXQgZGlzdGFuY2UgPSBJbmZpbml0eTtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXR1cm4gZGlzdGFuY2VCZXR3ZWVuUG9pbnRBbmRQb2ludCguLi5wb2ludHNbMF0sIC4uLnBvaW50KTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICAgICAgY29uc3QgcCA9IHBvaW50c1tpXTtcbiAgICAgICAgY29uc3QgcDIgPSBwb2ludHNbaSArIDFdO1xuICAgICAgICBjb25zdCBjdXJyZW50RGlzdGFuY2UgPSBkaXN0YW5jZUJldHdlZW5Qb2ludEFuZFNlZ21lbnQocG9pbnRbMF0sIHBvaW50WzFdLCBwWzBdLCBwWzFdLCBwMlswXSwgcDJbMV0pO1xuICAgICAgICBpZiAoY3VycmVudERpc3RhbmNlIDwgZGlzdGFuY2UpIHtcbiAgICAgICAgICAgIGRpc3RhbmNlID0gY3VycmVudERpc3RhbmNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkaXN0YW5jZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5lYXJlc3RQb2ludEJldHdlZW5Qb2ludEFuZFNlZ21lbnRzKHBvaW50OiBQb2ludCwgcG9pbnRzOiBQb2ludFtdLCBpc0Nsb3NlOiBCb29sZWFuID0gdHJ1ZSkge1xuICAgIGNvbnN0IGxlbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgbGV0IGRpc3RhbmNlID0gSW5maW5pdHk7XG4gICAgbGV0IHJlc3VsdDogUG9pbnQgPSBwb2ludDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgY29uc3QgcCA9IHBvaW50c1tpXTtcbiAgICAgICAgaWYgKGkgPT09IGxlbiAtIDEgJiYgIWlzQ2xvc2UpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBwMiA9IGkgPT09IGxlbiAtIDEgPyBwb2ludHNbMF0gOiBwb2ludHNbaSArIDFdO1xuICAgICAgICBjb25zdCBjdXJyZW50RGlzdGFuY2UgPSBkaXN0YW5jZUJldHdlZW5Qb2ludEFuZFNlZ21lbnQocG9pbnRbMF0sIHBvaW50WzFdLCBwWzBdLCBwWzFdLCBwMlswXSwgcDJbMV0pO1xuICAgICAgICBpZiAoY3VycmVudERpc3RhbmNlIDwgZGlzdGFuY2UpIHtcbiAgICAgICAgICAgIGRpc3RhbmNlID0gY3VycmVudERpc3RhbmNlO1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0TmVhcmVzdFBvaW50QmV0d2VlblBvaW50QW5kU2VnbWVudChwb2ludCwgW3AsIHAyXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5lYXJlc3RQb2ludEJldHdlZW5Qb2ludEFuZERpc2NyZXRlU2VnbWVudHMocG9pbnQ6IFBvaW50LCBzZWdtZW50czogW1BvaW50LCBQb2ludF1bXSk6IFBvaW50IHtcbiAgICBsZXQgbWluRGlzdGFuY2UgPSBJbmZpbml0eTtcbiAgICBsZXQgbmVhcmVzdFBvaW50ID0gcG9pbnQ7XG5cbiAgICBmb3IgKGNvbnN0IHNlZ21lbnQgb2Ygc2VnbWVudHMpIHtcbiAgICAgICAgY29uc3QgY3VycmVudE5lYXJlc3RQb2ludCA9IGdldE5lYXJlc3RQb2ludEJldHdlZW5Qb2ludEFuZFNlZ21lbnQocG9pbnQsIHNlZ21lbnQpO1xuICAgICAgICBjb25zdCBjdXJyZW50RGlzdGFuY2UgPSBkaXN0YW5jZUJldHdlZW5Qb2ludEFuZFBvaW50KHBvaW50WzBdLCBwb2ludFsxXSwgY3VycmVudE5lYXJlc3RQb2ludFswXSwgY3VycmVudE5lYXJlc3RQb2ludFsxXSk7XG5cbiAgICAgICAgaWYgKGN1cnJlbnREaXN0YW5jZSA8IG1pbkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBtaW5EaXN0YW5jZSA9IGN1cnJlbnREaXN0YW5jZTtcbiAgICAgICAgICAgIG5lYXJlc3RQb2ludCA9IGN1cnJlbnROZWFyZXN0UG9pbnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmVhcmVzdFBvaW50O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmVhcmVzdFBvaW50QmV0d2VlblBvaW50QW5kRWxsaXBzZShwb2ludDogUG9pbnQsIGNlbnRlcjogUG9pbnQsIHJ4OiBudW1iZXIsIHJ5OiBudW1iZXIpOiBQb2ludCB7XG4gICAgY29uc3QgcmVjdGFuZ2xlQ2xpZW50ID0ge1xuICAgICAgICB4OiBjZW50ZXJbMF0gLSByeCxcbiAgICAgICAgeTogY2VudGVyWzFdIC0gcnksXG4gICAgICAgIGhlaWdodDogcnkgKiAyLFxuICAgICAgICB3aWR0aDogcnggKiAyXG4gICAgfTtcbiAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNDYwMDc1NDAvMjMyMTIyXG4gICAgY29uc3QgcHggPSBNYXRoLmFicyhwb2ludFswXSAtIHJlY3RhbmdsZUNsaWVudC54IC0gcmVjdGFuZ2xlQ2xpZW50LndpZHRoIC8gMik7XG4gICAgY29uc3QgcHkgPSBNYXRoLmFicyhwb2ludFsxXSAtIHJlY3RhbmdsZUNsaWVudC55IC0gcmVjdGFuZ2xlQ2xpZW50LmhlaWdodCAvIDIpO1xuXG4gICAgbGV0IHR4ID0gMC43MDc7XG4gICAgbGV0IHR5ID0gMC43MDc7XG5cbiAgICBjb25zdCBhID0gTWF0aC5hYnMocmVjdGFuZ2xlQ2xpZW50LndpZHRoKSAvIDI7XG4gICAgY29uc3QgYiA9IE1hdGguYWJzKHJlY3RhbmdsZUNsaWVudC5oZWlnaHQpIC8gMjtcblxuICAgIFswLCAxLCAyLCAzXS5mb3JFYWNoKCh4KSA9PiB7XG4gICAgICAgIGNvbnN0IHh4ID0gYSAqIHR4O1xuICAgICAgICBjb25zdCB5eSA9IGIgKiB0eTtcblxuICAgICAgICBjb25zdCBleCA9ICgoYSAqIGEgLSBiICogYikgKiB0eCAqKiAzKSAvIGE7XG4gICAgICAgIGNvbnN0IGV5ID0gKChiICogYiAtIGEgKiBhKSAqIHR5ICoqIDMpIC8gYjtcblxuICAgICAgICBjb25zdCByeCA9IHh4IC0gZXg7XG4gICAgICAgIGNvbnN0IHJ5ID0geXkgLSBleTtcblxuICAgICAgICBjb25zdCBxeCA9IHB4IC0gZXg7XG4gICAgICAgIGNvbnN0IHF5ID0gcHkgLSBleTtcblxuICAgICAgICBjb25zdCByID0gTWF0aC5oeXBvdChyeSwgcngpO1xuICAgICAgICBjb25zdCBxID0gTWF0aC5oeXBvdChxeSwgcXgpO1xuXG4gICAgICAgIHR4ID0gTWF0aC5taW4oMSwgTWF0aC5tYXgoMCwgKChxeCAqIHIpIC8gcSArIGV4KSAvIGEpKTtcbiAgICAgICAgdHkgPSBNYXRoLm1pbigxLCBNYXRoLm1heCgwLCAoKHF5ICogcikgLyBxICsgZXkpIC8gYikpO1xuICAgICAgICBjb25zdCB0ID0gTWF0aC5oeXBvdCh0eSwgdHgpO1xuICAgICAgICB0eCAvPSB0O1xuICAgICAgICB0eSAvPSB0O1xuICAgIH0pO1xuICAgIGNvbnN0IHNpZ25YID0gcG9pbnRbMF0gPiBjZW50ZXJbMF0gPyAxIDogLTE7XG4gICAgY29uc3Qgc2lnblkgPSBwb2ludFsxXSA+IGNlbnRlclsxXSA/IDEgOiAtMTtcblxuICAgIHJldHVybiBbY2VudGVyWzBdICsgYSAqIHR4ICogc2lnblgsIGNlbnRlclsxXSArIGIgKiB0eSAqIHNpZ25ZXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJvdGF0ZSh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyLCBhbmdsZTogbnVtYmVyKSB7XG4gICAgLy8g8J2RjuKAsvCdkaU9KPCdkY7wnZGl4oiS8J2RkPCdkaUpY29z8J2cg+KIkijwnZGO8J2RpuKIkvCdkZDwnZGmKXNpbvCdnIMr8J2RkPCdkaVcbiAgICAvLyDwnZGO4oCy8J2Rpj0o8J2RjvCdkaXiiJLwnZGQ8J2RpSlzaW7wnZyDKyjwnZGO8J2RpuKIkvCdkZDwnZGmKWNvc/CdnIMr8J2RkPCdkaYuXG4gICAgLy8gaHR0cHM6Ly9tYXRoLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8yMjA0NTIwL2hvdy1kby1pLXJvdGF0ZS1hLWxpbmUtc2VnbWVudC1pbi1hLXNwZWNpZmljLXBvaW50LW9uLXRoZS1saW5lXG4gICAgcmV0dXJuIFsoeDEgLSB4MikgKiBNYXRoLmNvcyhhbmdsZSkgLSAoeTEgLSB5MikgKiBNYXRoLnNpbihhbmdsZSkgKyB4MiwgKHgxIC0geDIpICogTWF0aC5zaW4oYW5nbGUpICsgKHkxIC0geTIpICogTWF0aC5jb3MoYW5nbGUpICsgeTJdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGlzdGFuY2VCZXR3ZWVuUG9pbnRBbmRQb2ludCh4MTogbnVtYmVyLCB5MTogbnVtYmVyLCB4MjogbnVtYmVyLCB5MjogbnVtYmVyKSB7XG4gICAgY29uc3QgZHggPSB4MSAtIHgyO1xuICAgIGNvbnN0IGR5ID0geTEgLSB5MjtcbiAgICByZXR1cm4gTWF0aC5oeXBvdChkeCwgZHkpO1xufVxuXG4vLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81MjU0ODM4L2NhbGN1bGF0aW5nLWRpc3RhbmNlLWJldHdlZW4tYS1wb2ludC1hbmQtYS1yZWN0YW5ndWxhci1ib3gtbmVhcmVzdC1wb2ludFxuZXhwb3J0IGZ1bmN0aW9uIGRpc3RhbmNlQmV0d2VlblBvaW50QW5kUmVjdGFuZ2xlKHg6IG51bWJlciwgeTogbnVtYmVyLCByZWN0OiBSZWN0YW5nbGVDbGllbnQpIHtcbiAgICB2YXIgZHggPSBNYXRoLm1heChyZWN0LnggLSB4LCAwLCB4IC0gKHJlY3QueCArIHJlY3Qud2lkdGgpKTtcbiAgICB2YXIgZHkgPSBNYXRoLm1heChyZWN0LnkgLSB5LCAwLCB5IC0gKHJlY3QueSArIHJlY3QuaGVpZ2h0KSk7XG4gICAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG59XG5cbmV4cG9ydCBjb25zdCBpc0xpbmVIaXRMaW5lID0gKGE6IFBvaW50LCBiOiBQb2ludCwgYzogUG9pbnQsIGQ6IFBvaW50KTogYm9vbGVhbiA9PiB7XG4gICAgaWYgKFBvaW50LmlzRXF1YWxzKGEsIGIpICYmIFBvaW50LmlzRXF1YWxzKGMsIGQpICYmICFQb2ludC5pc0VxdWFscyhhLCBjKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgY3Jvc3NQcm9kdWN0ID0gKHYxOiBQb2ludCwgdjI6IFBvaW50KSA9PiB2MVswXSAqIHYyWzFdIC0gdjFbMV0gKiB2MlswXTtcblxuICAgIGNvbnN0IGFiOiBQb2ludCA9IFtiWzBdIC0gYVswXSwgYlsxXSAtIGFbMV1dO1xuICAgIGNvbnN0IGFjOiBQb2ludCA9IFtjWzBdIC0gYVswXSwgY1sxXSAtIGFbMV1dO1xuICAgIGNvbnN0IGFkOiBQb2ludCA9IFtkWzBdIC0gYVswXSwgZFsxXSAtIGFbMV1dO1xuXG4gICAgY29uc3QgY2E6IFBvaW50ID0gW2FbMF0gLSBjWzBdLCBhWzFdIC0gY1sxXV07XG4gICAgY29uc3QgY2I6IFBvaW50ID0gW2JbMF0gLSBjWzBdLCBiWzFdIC0gY1sxXV07XG4gICAgY29uc3QgY2Q6IFBvaW50ID0gW2RbMF0gLSBjWzBdLCBkWzFdIC0gY1sxXV07XG5cbiAgICByZXR1cm4gY3Jvc3NQcm9kdWN0KGFiLCBhYykgKiBjcm9zc1Byb2R1Y3QoYWIsIGFkKSA8PSAwICYmIGNyb3NzUHJvZHVjdChjZCwgY2EpICogY3Jvc3NQcm9kdWN0KGNkLCBjYikgPD0gMDtcbn07XG5cbmV4cG9ydCBjb25zdCBpc0xpbmVIaXRSZWN0YW5nbGUgPSAocG9pbnRzOiBQb2ludFtdLCByZWN0YW5nbGU6IFJlY3RhbmdsZUNsaWVudCkgPT4ge1xuICAgIGlmIChwb2ludHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiBSZWN0YW5nbGVDbGllbnQuaXNQb2ludEluUmVjdGFuZ2xlKHJlY3RhbmdsZSwgcG9pbnRzWzBdKTtcbiAgICB9XG4gICAgY29uc3QgcmVjdGFuZ2xlUG9pbnRzID0gUmVjdGFuZ2xlQ2xpZW50LmdldENvcm5lclBvaW50cyhyZWN0YW5nbGUpO1xuICAgIGNvbnN0IGxlbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjb25zdCBwMSA9IHBvaW50c1tpXTtcbiAgICAgICAgY29uc3QgcDIgPSBwb2ludHNbKGkgKyAxKSAlIGxlbl07XG4gICAgICAgIGlmIChpID09PSBsZW4gLSAxICYmIFBvaW50LmlzRXF1YWxzKHAxLCBwMikpIGNvbnRpbnVlO1xuICAgICAgICBjb25zdCBpc0hpdCA9IGlzU2luZ2xlTGluZUhpdFJlY3RhbmdsZUVkZ2UocDEsIHAyLCByZWN0YW5nbGUpO1xuICAgICAgICBpZiAoaXNIaXQgfHwgaXNQb2ludEluUG9seWdvbihwMSwgcmVjdGFuZ2xlUG9pbnRzKSB8fCBpc1BvaW50SW5Qb2x5Z29uKHAyLCByZWN0YW5nbGVQb2ludHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgY29uc3QgaXNMaW5lSGl0UmVjdGFuZ2xlRWRnZSA9IChwb2ludHM6IFBvaW50W10sIHJlY3RhbmdsZTogUmVjdGFuZ2xlQ2xpZW50LCBpc0Nsb3NlOiBib29sZWFuID0gdHJ1ZSkgPT4ge1xuICAgIGNvbnN0IGxlbiA9IHBvaW50cy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBpZiAoaSA9PT0gbGVuIC0gMSAmJiAhaXNDbG9zZSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IHAxID0gcG9pbnRzW2ldO1xuICAgICAgICBjb25zdCBwMiA9IHBvaW50c1soaSArIDEpICUgbGVuXTtcbiAgICAgICAgY29uc3QgaXNIaXQgPSBpc1NpbmdsZUxpbmVIaXRSZWN0YW5nbGVFZGdlKHAxLCBwMiwgcmVjdGFuZ2xlKTtcbiAgICAgICAgaWYgKGlzSGl0KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5leHBvcnQgY29uc3QgaXNTaW5nbGVMaW5lSGl0UmVjdGFuZ2xlRWRnZSA9IChwMTogUG9pbnQsIHAyOiBQb2ludCwgcmVjdGFuZ2xlOiBSZWN0YW5nbGVDbGllbnQpID0+IHtcbiAgICBjb25zdCByZWN0YW5nbGVQb2ludHMgPSBSZWN0YW5nbGVDbGllbnQuZ2V0Q29ybmVyUG9pbnRzKHJlY3RhbmdsZSk7XG4gICAgcmV0dXJuIChcbiAgICAgICAgaXNMaW5lSGl0TGluZShwMSwgcDIsIHJlY3RhbmdsZVBvaW50c1swXSwgcmVjdGFuZ2xlUG9pbnRzWzFdKSB8fFxuICAgICAgICBpc0xpbmVIaXRMaW5lKHAxLCBwMiwgcmVjdGFuZ2xlUG9pbnRzWzFdLCByZWN0YW5nbGVQb2ludHNbMl0pIHx8XG4gICAgICAgIGlzTGluZUhpdExpbmUocDEsIHAyLCByZWN0YW5nbGVQb2ludHNbMl0sIHJlY3RhbmdsZVBvaW50c1szXSkgfHxcbiAgICAgICAgaXNMaW5lSGl0TGluZShwMSwgcDIsIHJlY3RhbmdsZVBvaW50c1szXSwgcmVjdGFuZ2xlUG9pbnRzWzBdKVxuICAgICk7XG59O1xuXG4vL2h0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzIyNTIxOTgyL2NoZWNrLWlmLXBvaW50LWlzLWluc2lkZS1hLXBvbHlnb25cbmV4cG9ydCBjb25zdCBpc1BvaW50SW5Qb2x5Z29uID0gKHBvaW50OiBQb2ludCwgcG9pbnRzOiBQb2ludFtdKSA9PiB7XG4gICAgLy8gcmF5LWNhc3RpbmcgYWxnb3JpdGhtIGJhc2VkIG9uXG4gICAgLy8gaHR0cHM6Ly93cmYuZWNzZS5ycGkuZWR1L1Jlc2VhcmNoL1Nob3J0X05vdGVzL3BucG9seS5odG1sXG5cbiAgICBjb25zdCB4ID0gcG9pbnRbMF0sXG4gICAgICAgIHkgPSBwb2ludFsxXTtcblxuICAgIGxldCBpbnNpZGUgPSBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMCwgaiA9IHBvaW50cy5sZW5ndGggLSAxOyBpIDwgcG9pbnRzLmxlbmd0aDsgaiA9IGkrKykge1xuICAgICAgICBsZXQgeGkgPSBwb2ludHNbaV1bMF0sXG4gICAgICAgICAgICB5aSA9IHBvaW50c1tpXVsxXTtcbiAgICAgICAgbGV0IHhqID0gcG9pbnRzW2pdWzBdLFxuICAgICAgICAgICAgeWogPSBwb2ludHNbal1bMV07XG5cbiAgICAgICAgbGV0IGludGVyc2VjdCA9IHlpID4geSAhPSB5aiA+IHkgJiYgeCA8ICgoeGogLSB4aSkgKiAoeSAtIHlpKSkgLyAoeWogLSB5aSkgKyB4aTtcbiAgICAgICAgaWYgKGludGVyc2VjdCkgaW5zaWRlID0gIWluc2lkZTtcbiAgICB9XG4gICAgcmV0dXJuIGluc2lkZTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc1BvaW50SW5FbGxpcHNlID0gKHBvaW50OiBQb2ludCwgY2VudGVyOiBQb2ludCwgcng6IG51bWJlciwgcnk6IG51bWJlciwgYW5nbGUgPSAwKSA9PiB7XG4gICAgY29uc3QgY29zQW5nbGUgPSBNYXRoLmNvcyhhbmdsZSk7XG4gICAgY29uc3Qgc2luQW5nbGUgPSBNYXRoLnNpbihhbmdsZSk7XG4gICAgY29uc3QgeDEgPSAocG9pbnRbMF0gLSBjZW50ZXJbMF0pICogY29zQW5nbGUgKyAocG9pbnRbMV0gLSBjZW50ZXJbMV0pICogc2luQW5nbGU7XG4gICAgY29uc3QgeTEgPSAocG9pbnRbMV0gLSBjZW50ZXJbMV0pICogY29zQW5nbGUgLSAocG9pbnRbMF0gLSBjZW50ZXJbMF0pICogc2luQW5nbGU7XG5cbiAgICByZXR1cm4gKHgxICogeDEpIC8gKHJ4ICogcngpICsgKHkxICogeTEpIC8gKHJ5ICogcnkpIDw9IDE7XG59O1xuXG5leHBvcnQgY29uc3QgaXNQb2ludEluUm91bmRSZWN0YW5nbGUgPSAocG9pbnQ6IFBvaW50LCByZWN0YW5nbGU6IFJlY3RhbmdsZUNsaWVudCwgcmFkaXVzOiBudW1iZXIsIGFuZ2xlID0gMCkgPT4ge1xuICAgIGNvbnN0IHsgeDogcmVjdFgsIHk6IHJlY3RZLCB3aWR0aCwgaGVpZ2h0IH0gPSByZWN0YW5nbGU7XG4gICAgY29uc3QgaXNJblJlY3RhbmdsZSA9IHBvaW50WzBdID49IHJlY3RYICYmIHBvaW50WzBdIDw9IHJlY3RYICsgd2lkdGggJiYgcG9pbnRbMV0gPj0gcmVjdFkgJiYgcG9pbnRbMV0gPD0gcmVjdFkgKyBoZWlnaHQ7XG4gICAgY29uc3QgaGFuZGxlTGVmdFRvcCA9XG4gICAgICAgIHBvaW50WzBdID49IHJlY3RYICYmXG4gICAgICAgIHBvaW50WzBdIDw9IHJlY3RYICsgcmFkaXVzICYmXG4gICAgICAgIHBvaW50WzFdID49IHJlY3RZICYmXG4gICAgICAgIHBvaW50WzFdIDw9IHJlY3RZICsgcmFkaXVzICYmXG4gICAgICAgIE1hdGguaHlwb3QocG9pbnRbMF0gLSAocmVjdFggKyByYWRpdXMpLCBwb2ludFsxXSAtIChyZWN0WSArIHJhZGl1cykpID4gcmFkaXVzO1xuICAgIGNvbnN0IGhhbmRsZUxlZnRCb3R0b20gPVxuICAgICAgICBwb2ludFswXSA+PSByZWN0WCAmJlxuICAgICAgICBwb2ludFswXSA8PSByZWN0WCArIHJhZGl1cyAmJlxuICAgICAgICBwb2ludFsxXSA+PSByZWN0WSArIGhlaWdodCAmJlxuICAgICAgICBwb2ludFsxXSA8PSByZWN0WSArIGhlaWdodCAtIHJhZGl1cyAmJlxuICAgICAgICBNYXRoLmh5cG90KHBvaW50WzBdIC0gKHJlY3RYICsgcmFkaXVzKSwgcG9pbnRbMV0gLSAocmVjdFkgKyBoZWlnaHQgLSByYWRpdXMpKSA+IHJhZGl1cztcbiAgICBjb25zdCBoYW5kbGVSaWdodFRvcCA9XG4gICAgICAgIHBvaW50WzBdID49IHJlY3RYICsgd2lkdGggLSByYWRpdXMgJiZcbiAgICAgICAgcG9pbnRbMF0gPD0gcmVjdFggKyB3aWR0aCAmJlxuICAgICAgICBwb2ludFsxXSA+PSByZWN0WSAmJlxuICAgICAgICBwb2ludFsxXSA8PSByZWN0WSArIHJhZGl1cyAmJlxuICAgICAgICBNYXRoLmh5cG90KHBvaW50WzBdIC0gKHJlY3RYICsgd2lkdGggLSByYWRpdXMpLCBwb2ludFsxXSAtIChyZWN0WSArIHJhZGl1cykpID4gcmFkaXVzO1xuICAgIGNvbnN0IGhhbmRsZVJpZ2h0Qm90dG9tID1cbiAgICAgICAgcG9pbnRbMF0gPj0gcmVjdFggKyB3aWR0aCAtIHJhZGl1cyAmJlxuICAgICAgICBwb2ludFswXSA8PSByZWN0WCArIHdpZHRoICYmXG4gICAgICAgIHBvaW50WzFdID49IHJlY3RZICsgaGVpZ2h0IC0gcmFkaXVzICYmXG4gICAgICAgIHBvaW50WzFdIDw9IHJlY3RZICsgaGVpZ2h0ICYmXG4gICAgICAgIE1hdGguaHlwb3QocG9pbnRbMF0gLSAocmVjdFggKyB3aWR0aCAtIHJhZGl1cyksIHBvaW50WzFdIC0gKHJlY3RZICsgaGVpZ2h0IC0gcmFkaXVzKSkgPiByYWRpdXM7XG4gICAgY29uc3QgaXNJbkNvcm5lciA9IGhhbmRsZUxlZnRUb3AgfHwgaGFuZGxlTGVmdEJvdHRvbSB8fCBoYW5kbGVSaWdodFRvcCB8fCBoYW5kbGVSaWdodEJvdHRvbTtcblxuICAgIHJldHVybiBpc0luUmVjdGFuZ2xlICYmICFpc0luQ29ybmVyO1xufTtcblxuLy8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbmljaG9sYXN3bWluL2MyNjYxZWIxMWNhZDU2NzFkODE2XG5leHBvcnQgY29uc3QgY2F0bXVsbFJvbUZpdHRpbmcgPSBmdW5jdGlvbiAocG9pbnRzOiBQb2ludFtdKSB7XG4gICAgY29uc3QgYWxwaGEgPSAwLjU7XG4gICAgbGV0IHAwLCBwMSwgcDIsIHAzLCBicDEsIGJwMiwgZDEsIGQyLCBkMywgQSwgQiwgTiwgTTtcbiAgICB2YXIgZDNwb3dBLCBkMnBvd0EsIGQzcG93MkEsIGQycG93MkEsIGQxcG93MkEsIGQxcG93QTtcbiAgICBjb25zdCByZXN1bHQ6IFBvaW50W10gPSBbXTtcbiAgICByZXN1bHQucHVzaChbTWF0aC5yb3VuZChwb2ludHNbMF1bMF0pLCBNYXRoLnJvdW5kKHBvaW50c1swXVsxXSldKTtcbiAgICB2YXIgbGVuZ3RoID0gcG9pbnRzLmxlbmd0aDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBwMCA9IGkgPT0gMCA/IHBvaW50c1swXSA6IHBvaW50c1tpIC0gMV07XG4gICAgICAgIHAxID0gcG9pbnRzW2ldO1xuICAgICAgICBwMiA9IHBvaW50c1tpICsgMV07XG4gICAgICAgIHAzID0gaSArIDIgPCBsZW5ndGggPyBwb2ludHNbaSArIDJdIDogcDI7XG5cbiAgICAgICAgZDEgPSBNYXRoLnNxcnQoTWF0aC5wb3cocDBbMF0gLSBwMVswXSwgMikgKyBNYXRoLnBvdyhwMFsxXSAtIHAxWzFdLCAyKSk7XG4gICAgICAgIGQyID0gTWF0aC5zcXJ0KE1hdGgucG93KHAxWzBdIC0gcDJbMF0sIDIpICsgTWF0aC5wb3cocDFbMV0gLSBwMlsxXSwgMikpO1xuICAgICAgICBkMyA9IE1hdGguc3FydChNYXRoLnBvdyhwMlswXSAtIHAzWzBdLCAyKSArIE1hdGgucG93KHAyWzFdIC0gcDNbMV0sIDIpKTtcblxuICAgICAgICAvLyBDYXRtdWxsLVJvbSB0byBDdWJpYyBCZXppZXIgY29udmVyc2lvbiBtYXRyaXhcbiAgICAgICAgLy8gQSA9IDJkMV4yYSArIDNkMV5hICogZDJeYSArIGQzXjJhXG4gICAgICAgIC8vIEIgPSAyZDNeMmEgKyAzZDNeYSAqIGQyXmEgKyBkMl4yYVxuICAgICAgICAvLyBbICAgMCAgICAgICAgICAgICAxICAgICAgICAgICAgMCAgICAgICAgICAwICAgICAgICAgIF1cbiAgICAgICAgLy8gWyAgIC1kMl4yYSAvTiAgICAgQS9OICAgICAgICAgIGQxXjJhIC9OICAgMCAgICAgICAgICBdXG4gICAgICAgIC8vIFsgICAwICAgICAgICAgICAgIGQzXjJhIC9NICAgICBCL00gICAgICAgIC1kMl4yYSAvTSAgXVxuICAgICAgICAvLyBbICAgMCAgICAgICAgICAgICAwICAgICAgICAgICAgMSAgICAgICAgICAwICAgICAgICAgIF1cblxuICAgICAgICBkM3Bvd0EgPSBNYXRoLnBvdyhkMywgYWxwaGEpO1xuICAgICAgICBkM3BvdzJBID0gTWF0aC5wb3coZDMsIDIgKiBhbHBoYSk7XG4gICAgICAgIGQycG93QSA9IE1hdGgucG93KGQyLCBhbHBoYSk7XG4gICAgICAgIGQycG93MkEgPSBNYXRoLnBvdyhkMiwgMiAqIGFscGhhKTtcbiAgICAgICAgZDFwb3dBID0gTWF0aC5wb3coZDEsIGFscGhhKTtcbiAgICAgICAgZDFwb3cyQSA9IE1hdGgucG93KGQxLCAyICogYWxwaGEpO1xuXG4gICAgICAgIEEgPSAyICogZDFwb3cyQSArIDMgKiBkMXBvd0EgKiBkMnBvd0EgKyBkMnBvdzJBO1xuICAgICAgICBCID0gMiAqIGQzcG93MkEgKyAzICogZDNwb3dBICogZDJwb3dBICsgZDJwb3cyQTtcbiAgICAgICAgTiA9IDMgKiBkMXBvd0EgKiAoZDFwb3dBICsgZDJwb3dBKTtcbiAgICAgICAgaWYgKE4gPiAwKSB7XG4gICAgICAgICAgICBOID0gMSAvIE47XG4gICAgICAgIH1cbiAgICAgICAgTSA9IDMgKiBkM3Bvd0EgKiAoZDNwb3dBICsgZDJwb3dBKTtcbiAgICAgICAgaWYgKE0gPiAwKSB7XG4gICAgICAgICAgICBNID0gMSAvIE07XG4gICAgICAgIH1cblxuICAgICAgICBicDEgPSBbKC1kMnBvdzJBICogcDBbMF0gKyBBICogcDFbMF0gKyBkMXBvdzJBICogcDJbMF0pICogTiwgKC1kMnBvdzJBICogcDBbMV0gKyBBICogcDFbMV0gKyBkMXBvdzJBICogcDJbMV0pICogTl07XG4gICAgICAgIGJwMiA9IFsoZDNwb3cyQSAqIHAxWzBdICsgQiAqIHAyWzBdIC0gZDJwb3cyQSAqIHAzWzBdKSAqIE0sIChkM3BvdzJBICogcDFbMV0gKyBCICogcDJbMV0gLSBkMnBvdzJBICogcDNbMV0pICogTV07XG5cbiAgICAgICAgaWYgKGJwMVswXSA9PSAwICYmIGJwMVsxXSA9PSAwKSB7XG4gICAgICAgICAgICBicDEgPSBwMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnAyWzBdID09IDAgJiYgYnAyWzFdID09IDApIHtcbiAgICAgICAgICAgIGJwMiA9IHAyO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0LnB1c2goYnAxIGFzIFBvaW50LCBicDIgYXMgUG9pbnQsIHAyIGFzIFBvaW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyoqXG4gKiB0aGUgcmVzdWx0IG9mIHNsb3BlIGlzIGJhc2VkIG9uIENhcnRlc2lhbiBjb29yZGluYXRlIHN5c3RlbVxuICogeCwgeSBhcmUgYmFzZWQgb24gdGhlIHBvc2l0aW9uIGluIHRoZSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBzeXN0ZW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEVsbGlwc2VUYW5nZW50U2xvcGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIGE6IG51bWJlciwgYjogbnVtYmVyKSB7XG4gICAgaWYgKE1hdGguYWJzKHkpID09PSAwKSB7XG4gICAgICAgIHJldHVybiB4ID4gMCA/IC1JbmZpbml0eSA6IEluZmluaXR5O1xuICAgIH1cbiAgICBjb25zdCBrID0gKC1iICogYiAqIHgpIC8gKGEgKiBhICogeSk7XG4gICAgcmV0dXJuIGs7XG59XG5cbi8qKlxuICogeCwgeSBhcmUgYmFzZWQgb24gdGhlIHBvc2l0aW9uIGluIHRoZSBDYXJ0ZXNpYW4gY29vcmRpbmF0ZSBzeXN0ZW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZlY3RvckZyb21Qb2ludEFuZFNsb3BlKHg6IG51bWJlciwgeTogbnVtYmVyLCBzbG9wZTogbnVtYmVyKSB7XG4gICAgaWYgKHNsb3BlID09PSBJbmZpbml0eSkge1xuICAgICAgICByZXR1cm4gWzAsIC0xXSBhcyBQb2ludDtcbiAgICB9IGVsc2UgaWYgKHNsb3BlID09PSAtSW5maW5pdHkpIHtcbiAgICAgICAgcmV0dXJuIFswLCAxXSBhcyBQb2ludDtcbiAgICB9XG4gICAgbGV0IHZlY3RvciA9IFsxLCAtc2xvcGVdIGFzIFBvaW50O1xuICAgIGlmICh5IDwgMCkge1xuICAgICAgICB2ZWN0b3IgPSBbLXZlY3RvclswXSwgLXZlY3RvclsxXV07XG4gICAgfVxuICAgIHJldHVybiB2ZWN0b3IgYXMgUG9pbnQ7XG59XG5cbi8qKlxuICogVGhlIERPTSBsaWtlcyB2YWx1ZXMgdG8gYmUgZml4ZWQgdG8gMyBkZWNpbWFsIHBsYWNlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9Eb21QcmVjaXNpb24odjogbnVtYmVyKSB7XG4gICAgcmV0dXJuICt2LnRvRml4ZWQoNCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0ZpeGVkKHY6IG51bWJlcikge1xuICAgIHJldHVybiArdi50b0ZpeGVkKDIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2VpbFRvRGVjaW1hbCh2YWx1ZTogbnVtYmVyLCBkZWNpbWFsUGxhY2VzOiBudW1iZXIpIHtcbiAgICBjb25zdCBmYWN0b3IgPSBNYXRoLnBvdygxMCwgZGVjaW1hbFBsYWNlcyk7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh2YWx1ZSAqIGZhY3RvcikgLyBmYWN0b3I7XG59XG5cbi8qKlxuICogV2hldGhlciB0d28gbnVtYmVycyBudW1iZXJzIGEgYW5kIGIgYXJlIGFwcHJveGltYXRlbHkgZXF1YWwuXG4gKlxuICogQHBhcmFtIGEgLSBUaGUgZmlyc3QgcG9pbnQuXG4gKiBAcGFyYW0gYiAtIFRoZSBzZWNvbmQgcG9pbnQuXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHByb3hpbWF0ZWx5KGE6IG51bWJlciwgYjogbnVtYmVyLCBwcmVjaXNpb24gPSAwLjAwMDAwMSkge1xuICAgIHJldHVybiBNYXRoLmFicyhhIC0gYikgPD0gcHJlY2lzaW9uO1xufVxuXG4vLyBodHRwczovL21lZGl1bS5jb20vQHN0ZXZlcnVpei9maW5kLXRoZS1wb2ludHMtd2hlcmUtYS1saW5lLXNlZ21lbnQtaW50ZXJjZXB0cy1hbi1hbmdsZWQtZWxsaXBzZS1pbi1qYXZhc2NyaXB0LXR5cGVzY3JpcHQtZTQ1MTUyNGJlZWNlXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3Jvc3NpbmdQb2ludHNCZXR3ZWVuRWxsaXBzZUFuZFNlZ21lbnQoXG4gICAgc3RhcnRQb2ludDogUG9pbnQsXG4gICAgZW5kUG9pbnQ6IFBvaW50LFxuICAgIGN4OiBudW1iZXIsXG4gICAgY3k6IG51bWJlcixcbiAgICByeDogbnVtYmVyLFxuICAgIHJ5OiBudW1iZXIsXG4gICAgc2VnbWVudF9vbmx5ID0gdHJ1ZVxuKSB7XG4gICAgLy8gSWYgdGhlIGVsbGlwc2Ugb3IgbGluZSBzZWdtZW50IGFyZSBlbXB0eSwgcmV0dXJuIG5vIHRWYWx1ZXMuXG4gICAgaWYgKHJ4ID09PSAwIHx8IHJ5ID09PSAwIHx8IChzdGFydFBvaW50WzBdID09PSBlbmRQb2ludFswXSAmJiBzdGFydFBvaW50WzFdID09PSBlbmRQb2ludFsxXSkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJ4ID0gcnggPCAwID8gcnggOiAtcng7XG4gICAgcnkgPSByeSA8IDAgPyByeSA6IC1yeTtcblxuICAgIHN0YXJ0UG9pbnRbMF0gLT0gY3g7XG4gICAgc3RhcnRQb2ludFsxXSAtPSBjeTtcbiAgICBlbmRQb2ludFswXSAtPSBjeDtcbiAgICBlbmRQb2ludFsxXSAtPSBjeTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgcXVhZHJhdGljIHBhcmFtZXRlcnMuXG4gICAgdmFyIEEgPVxuICAgICAgICAoKGVuZFBvaW50WzBdIC0gc3RhcnRQb2ludFswXSkgKiAoZW5kUG9pbnRbMF0gLSBzdGFydFBvaW50WzBdKSkgLyByeCAvIHJ4ICtcbiAgICAgICAgKChlbmRQb2ludFsxXSAtIHN0YXJ0UG9pbnRbMV0pICogKGVuZFBvaW50WzFdIC0gc3RhcnRQb2ludFsxXSkpIC8gcnkgLyByeTtcbiAgICB2YXIgQiA9ICgyICogc3RhcnRQb2ludFswXSAqIChlbmRQb2ludFswXSAtIHN0YXJ0UG9pbnRbMF0pKSAvIHJ4IC8gcnggKyAoMiAqIHN0YXJ0UG9pbnRbMV0gKiAoZW5kUG9pbnRbMV0gLSBzdGFydFBvaW50WzFdKSkgLyByeSAvIHJ5O1xuICAgIHZhciBDID0gKHN0YXJ0UG9pbnRbMF0gKiBzdGFydFBvaW50WzBdKSAvIHJ4IC8gcnggKyAoc3RhcnRQb2ludFsxXSAqIHN0YXJ0UG9pbnRbMV0pIC8gcnkgLyByeSAtIDE7XG5cbiAgICAvLyBNYWtlIGEgbGlzdCBvZiB0IHZhbHVlcyAobm9ybWFsaXplZCBwb2ludHMgb24gdGhlIGxpbmUgd2hlcmUgaW50ZXJzZWN0aW9ucyBvY2N1cikuXG4gICAgdmFyIHRWYWx1ZXM6IG51bWJlcltdID0gW107XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGRpc2NyaW1pbmFudC5cbiAgICB2YXIgZGlzY3JpbWluYW50ID0gQiAqIEIgLSA0ICogQSAqIEM7XG5cbiAgICBpZiAoZGlzY3JpbWluYW50ID09PSAwKSB7XG4gICAgICAgIC8vIE9uZSByZWFsIHNvbHV0aW9uLlxuICAgICAgICB0VmFsdWVzLnB1c2goLUIgLyAyIC8gQSk7XG4gICAgfSBlbHNlIGlmIChkaXNjcmltaW5hbnQgPiAwKSB7XG4gICAgICAgIC8vIFR3byByZWFsIHNvbHV0aW9ucy5cbiAgICAgICAgdFZhbHVlcy5wdXNoKCgtQiArIE1hdGguc3FydChkaXNjcmltaW5hbnQpKSAvIDIgLyBBKTtcbiAgICAgICAgdFZhbHVlcy5wdXNoKCgtQiAtIE1hdGguc3FydChkaXNjcmltaW5hbnQpKSAvIDIgLyBBKTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgICAgdFZhbHVlc1xuICAgICAgICAgICAgLy8gRmlsdGVyIHRvIG9ubHkgcG9pbnRzIHRoYXQgYXJlIG9uIHRoZSBzZWdtZW50LlxuICAgICAgICAgICAgLmZpbHRlcigodCkgPT4gIXNlZ21lbnRfb25seSB8fCAodCA+PSAwICYmIHQgPD0gMSkpXG4gICAgICAgICAgICAvLyBTb2x2ZSBmb3IgcG9pbnRzLlxuICAgICAgICAgICAgLm1hcCgodCkgPT4gW3N0YXJ0UG9pbnRbMF0gKyAoZW5kUG9pbnRbMF0gLSBzdGFydFBvaW50WzBdKSAqIHQgKyBjeCwgc3RhcnRQb2ludFsxXSArIChlbmRQb2ludFsxXSAtIHN0YXJ0UG9pbnRbMV0pICogdCArIGN5XSlcbiAgICApO1xufVxuXG4vKipcbiAqIEdldCBhIHBvaW50IGJldHdlZW4gdHdvIHBvaW50cy5cbiAqIEBwYXJhbSB4MCBUaGUgeC1heGlzIGNvb3JkaW5hdGUgb2YgdGhlIGZpcnN0IHBvaW50LlxuICogQHBhcmFtIHkwIFRoZSB5LWF4aXMgY29vcmRpbmF0ZSBvZiB0aGUgZmlyc3QgcG9pbnQuXG4gKiBAcGFyYW0geDEgVGhlIHgtYXhpcyBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuXG4gKiBAcGFyYW0geTEgVGhlIHktYXhpcyBjb29yZGluYXRlIG9mIHRoZSBzZWNvbmQgcG9pbnQuXG4gKiBAcGFyYW0gZCBOb3JtYWxpemVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQb2ludEJldHdlZW4oeDA6IG51bWJlciwgeTA6IG51bWJlciwgeDE6IG51bWJlciwgeTE6IG51bWJlciwgZCA9IDAuNSkge1xuICAgIHJldHVybiBbeDAgKyAoeDEgLSB4MCkgKiBkLCB5MCArICh5MSAtIHkwKSAqIGRdO1xufVxuXG4vKipcbiAqIOiOt+WPlueCueWIsOWNiuakreWchuW8p+auteeahOacgOi/keeCuVxuICogQHBhcmFtIHBvaW50IOebruagh+eCuVxuICogQHBhcmFtIHN0YXJ0UG9pbnQg5byn5q616LW354K5XG4gKiBAcGFyYW0gYXJjQ29tbWFuZCBTVkcg5byn5b2i5ZG95Luk5Y+C5pWwXG4gKi9cbi8qKlxuICog6K6h566X5qSt5ZyG5byn55qE5Lit5b+D54K55ZKM5a6e6ZmF5Y2K5b6EXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbGxpcHNlQXJjQ2VudGVyKHN0YXJ0UG9pbnQ6IFBvaW50LCBhcmNDb21tYW5kOiBTVkdBcmNDb21tYW5kKTogeyBjZW50ZXI6IFBvaW50OyByeDogbnVtYmVyOyByeTogbnVtYmVyIH0ge1xuICAgIC8vIDEuIOWwhuWdkOagh+i9rOaNouWIsOagh+WHhuS9jee9rlxuICAgIGNvbnN0IGR4ID0gKGFyY0NvbW1hbmQuZW5kWCAtIHN0YXJ0UG9pbnRbMF0pIC8gMjtcbiAgICBjb25zdCBkeSA9IChhcmNDb21tYW5kLmVuZFkgLSBzdGFydFBvaW50WzFdKSAvIDI7XG4gICAgY29uc3QgY29zQW5nbGUgPSBNYXRoLmNvcyhhcmNDb21tYW5kLnhBeGlzUm90YXRpb24pO1xuICAgIGNvbnN0IHNpbkFuZ2xlID0gTWF0aC5zaW4oYXJjQ29tbWFuZC54QXhpc1JvdGF0aW9uKTtcblxuICAgIC8vIOaXi+i9rOWIsOakreWchuWdkOagh+ezu1xuICAgIGNvbnN0IHgxID0gY29zQW5nbGUgKiBkeCArIHNpbkFuZ2xlICogZHk7XG4gICAgY29uc3QgeTEgPSAtc2luQW5nbGUgKiBkeCArIGNvc0FuZ2xlICogZHk7XG5cbiAgICAvLyAyLiDorqHnrpfkuK3lv4PngrlcbiAgICBjb25zdCByeCA9IE1hdGguYWJzKGFyY0NvbW1hbmQucngpO1xuICAgIGNvbnN0IHJ5ID0gTWF0aC5hYnMoYXJjQ29tbWFuZC5yeSk7XG5cbiAgICAvLyDnoa7kv53ljYrlvoTotrPlpJ/lpKdcbiAgICBjb25zdCBsYW1iZGEgPSAoeDEgKiB4MSkgLyAocnggKiByeCkgKyAoeTEgKiB5MSkgLyAocnkgKiByeSk7XG4gICAgY29uc3QgZmFjdG9yID0gbGFtYmRhID4gMSA/IE1hdGguc3FydChsYW1iZGEpIDogMTtcblxuICAgIGNvbnN0IGFkanVzdGVkUnggPSByeCAqIGZhY3RvcjtcbiAgICBjb25zdCBhZGp1c3RlZFJ5ID0gcnkgKiBmYWN0b3I7XG5cbiAgICAvLyDorqHnrpfkuK3lv4PngrnlnZDmoIdcbiAgICBjb25zdCBzaWduID0gYXJjQ29tbWFuZC5sYXJnZUFyY0ZsYWcgPT09IGFyY0NvbW1hbmQuc3dlZXBGbGFnID8gLTEgOiAxO1xuICAgIGNvbnN0IHNxID1cbiAgICAgICAgKGFkanVzdGVkUnggKiBhZGp1c3RlZFJ4ICogYWRqdXN0ZWRSeSAqIGFkanVzdGVkUnkgLSBhZGp1c3RlZFJ4ICogYWRqdXN0ZWRSeCAqIHkxICogeTEgLSBhZGp1c3RlZFJ5ICogYWRqdXN0ZWRSeSAqIHgxICogeDEpIC9cbiAgICAgICAgKGFkanVzdGVkUnggKiBhZGp1c3RlZFJ4ICogeTEgKiB5MSArIGFkanVzdGVkUnkgKiBhZGp1c3RlZFJ5ICogeDEgKiB4MSk7XG4gICAgY29uc3QgY29lZiA9IHNpZ24gKiBNYXRoLnNxcnQoTWF0aC5tYXgoMCwgc3EpKTtcblxuICAgIGNvbnN0IGNlbnRlclggPSBjb2VmICogKChhZGp1c3RlZFJ4ICogeTEpIC8gYWRqdXN0ZWRSeSk7XG4gICAgY29uc3QgY2VudGVyWSA9IGNvZWYgKiAoLShhZGp1c3RlZFJ5ICogeDEpIC8gYWRqdXN0ZWRSeCk7XG5cbiAgICAvLyAzLiDovazmjaLlm57ljp/lp4vlnZDmoIfns7tcbiAgICBjb25zdCBjeCA9IGNvc0FuZ2xlICogY2VudGVyWCAtIHNpbkFuZ2xlICogY2VudGVyWSArIChzdGFydFBvaW50WzBdICsgYXJjQ29tbWFuZC5lbmRYKSAvIDI7XG4gICAgY29uc3QgY3kgPSBzaW5BbmdsZSAqIGNlbnRlclggKyBjb3NBbmdsZSAqIGNlbnRlclkgKyAoc3RhcnRQb2ludFsxXSArIGFyY0NvbW1hbmQuZW5kWSkgLyAyO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgICAgY2VudGVyOiBbY3gsIGN5XSxcbiAgICAgICAgcng6IGFkanVzdGVkUngsXG4gICAgICAgIHJ5OiBhZGp1c3RlZFJ5XG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5lYXJlc3RQb2ludEJldHdlZW5Qb2ludEFuZEFyYyhwb2ludDogUG9pbnQsIHN0YXJ0UG9pbnQ6IFBvaW50LCBhcmNDb21tYW5kOiBTVkdBcmNDb21tYW5kKTogUG9pbnQge1xuICAgIGNvbnN0IHsgY2VudGVyLCByeCwgcnkgfSA9IGdldEVsbGlwc2VBcmNDZW50ZXIoc3RhcnRQb2ludCwgYXJjQ29tbWFuZCk7XG5cbiAgICAvLyDojrflj5bmpK3lnIbkuIrnmoTmnIDov5HngrlcbiAgICBjb25zdCBuZWFyZXN0UG9pbnQgPSBnZXROZWFyZXN0UG9pbnRCZXR3ZWVuUG9pbnRBbmRFbGxpcHNlKHBvaW50LCBjZW50ZXIsIHJ4LCByeSk7XG5cbiAgICAvLyDliKTmlq3mnIDov5HngrnmmK/lkKblnKjlvKfmrrXkuIpcbiAgICBjb25zdCBzdGFydEFuZ2xlID0gTWF0aC5hdGFuMihzdGFydFBvaW50WzFdIC0gY2VudGVyWzFdLCBzdGFydFBvaW50WzBdIC0gY2VudGVyWzBdKTtcbiAgICBjb25zdCBlbmRBbmdsZSA9IE1hdGguYXRhbjIoYXJjQ29tbWFuZC5lbmRZIC0gY2VudGVyWzFdLCBhcmNDb21tYW5kLmVuZFggLSBjZW50ZXJbMF0pO1xuICAgIGNvbnN0IHBvaW50QW5nbGUgPSBNYXRoLmF0YW4yKG5lYXJlc3RQb2ludFsxXSAtIGNlbnRlclsxXSwgbmVhcmVzdFBvaW50WzBdIC0gY2VudGVyWzBdKTtcblxuICAgIC8vIOajgOafpeeCueaYr+WQpuWcqOW8p+auteiMg+WbtOWGhVxuICAgIGNvbnN0IGlzSW5BcmMgPSBpc0FuZ2xlQmV0d2Vlbihwb2ludEFuZ2xlLCBzdGFydEFuZ2xlLCBlbmRBbmdsZSwgYXJjQ29tbWFuZC5zd2VlcEZsYWcgPT09IDEpO1xuXG4gICAgaWYgKGlzSW5BcmMpIHtcbiAgICAgICAgcmV0dXJuIG5lYXJlc3RQb2ludDtcbiAgICB9XG5cbiAgICAvLyDlpoLmnpzkuI3lnKjlvKfmrrXkuIrvvIzov5Tlm57mnIDov5HnmoTnq6/ngrlcbiAgICBjb25zdCBkaXN0YW5jZVRvU3RhcnQgPSBkaXN0YW5jZUJldHdlZW5Qb2ludEFuZFBvaW50KHBvaW50WzBdLCBwb2ludFsxXSwgc3RhcnRQb2ludFswXSwgc3RhcnRQb2ludFsxXSk7XG4gICAgY29uc3QgZGlzdGFuY2VUb0VuZCA9IGRpc3RhbmNlQmV0d2VlblBvaW50QW5kUG9pbnQocG9pbnRbMF0sIHBvaW50WzFdLCBhcmNDb21tYW5kLmVuZFgsIGFyY0NvbW1hbmQuZW5kWSk7XG4gICAgcmV0dXJuIGRpc3RhbmNlVG9TdGFydCA8IGRpc3RhbmNlVG9FbmQgPyBzdGFydFBvaW50IDogW2FyY0NvbW1hbmQuZW5kWCwgYXJjQ29tbWFuZC5lbmRZXTtcbn1cblxuZnVuY3Rpb24gaXNBbmdsZUJldHdlZW4oYW5nbGU6IG51bWJlciwgc3RhcnQ6IG51bWJlciwgZW5kOiBudW1iZXIsIGNsb2Nrd2lzZTogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIC8vIOagh+WHhuWMluinkuW6puWIsCBbMCwgMs+AXVxuICAgIGNvbnN0IG5vcm1hbGl6ZSA9IChhOiBudW1iZXIpID0+ICgoYSAlICgyICogTWF0aC5QSSkpICsgMiAqIE1hdGguUEkpICUgKDIgKiBNYXRoLlBJKTtcblxuICAgIGNvbnN0IGEgPSBub3JtYWxpemUoYW5nbGUpO1xuICAgIGNvbnN0IHMgPSBub3JtYWxpemUoc3RhcnQpO1xuICAgIGNvbnN0IGUgPSBub3JtYWxpemUoZW5kKTtcblxuICAgIGlmIChjbG9ja3dpc2UpIHtcbiAgICAgICAgcmV0dXJuIHMgPD0gZSA/IGEgPj0gcyAmJiBhIDw9IGUgOiBhID49IHMgfHwgYSA8PSBlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzID49IGUgPyBhIDw9IHMgJiYgYSA+PSBlIDogYSA8PSBzIHx8IGEgPj0gZTtcbiAgICB9XG59XG4iXX0=
@@ -1,6 +0,0 @@
1
- import { PlaitBoard, PlaitPointerType } from '../interfaces';
2
- import { isMobileDeviceEvent } from './pointer';
3
- export const isSmartHand = (board, event) => {
4
- return PlaitBoard.isPointer(board, PlaitPointerType.selection) && isMobileDeviceEvent(event);
5
- };
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9iaWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvdXRpbHMvbW9iaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWhELE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxDQUFDLEtBQWlCLEVBQUUsS0FBbUIsRUFBRSxFQUFFO0lBQ2xFLE9BQU8sVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLElBQUksbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakcsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGxhaXRCb2FyZCwgUGxhaXRQb2ludGVyVHlwZSB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgaXNNb2JpbGVEZXZpY2VFdmVudCB9IGZyb20gJy4vcG9pbnRlcic7XG5cbmV4cG9ydCBjb25zdCBpc1NtYXJ0SGFuZCA9IChib2FyZDogUGxhaXRCb2FyZCwgZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgIHJldHVybiBQbGFpdEJvYXJkLmlzUG9pbnRlcihib2FyZCwgUGxhaXRQb2ludGVyVHlwZS5zZWxlY3Rpb24pICYmIGlzTW9iaWxlRGV2aWNlRXZlbnQoZXZlbnQpO1xufTtcbiJdfQ==
@@ -1,17 +0,0 @@
1
- import { setDragging } from './dnd';
2
- import { BOARD_TO_MOVING_ELEMENT } from './weak-maps';
3
- export const getMovingElements = (board) => {
4
- return BOARD_TO_MOVING_ELEMENT.get(board) || [];
5
- };
6
- export const isMovingElements = (board) => {
7
- return (BOARD_TO_MOVING_ELEMENT.get(board) || []).length > 0;
8
- };
9
- export const removeMovingElements = (board) => {
10
- BOARD_TO_MOVING_ELEMENT.delete(board);
11
- setDragging(board, false);
12
- };
13
- export const cacheMovingElements = (board, elements) => {
14
- BOARD_TO_MOVING_ELEMENT.set(board, elements);
15
- setDragging(board, true);
16
- };
17
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW92aW5nLWVsZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy91dGlscy9tb3ZpbmctZWxlbWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV0RCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRTtJQUNuRCxPQUFPLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDcEQsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUU7SUFDbEQsT0FBTyxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQ2pFLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFO0lBQ3RELHVCQUF1QixDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxXQUFXLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzlCLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsS0FBaUIsRUFBRSxRQUF3QixFQUFFLEVBQUU7SUFDL0UsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3QyxXQUFXLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzdCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBsYWl0Qm9hcmQsIFBsYWl0RWxlbWVudCB9IGZyb20gJy4uL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgc2V0RHJhZ2dpbmcgfSBmcm9tICcuL2RuZCc7XG5pbXBvcnQgeyBCT0FSRF9UT19NT1ZJTkdfRUxFTUVOVCB9IGZyb20gJy4vd2Vhay1tYXBzJztcblxuZXhwb3J0IGNvbnN0IGdldE1vdmluZ0VsZW1lbnRzID0gKGJvYXJkOiBQbGFpdEJvYXJkKSA9PiB7XG4gICAgcmV0dXJuIEJPQVJEX1RPX01PVklOR19FTEVNRU5ULmdldChib2FyZCkgfHwgW107XG59O1xuXG5leHBvcnQgY29uc3QgaXNNb3ZpbmdFbGVtZW50cyA9IChib2FyZDogUGxhaXRCb2FyZCkgPT4ge1xuICAgIHJldHVybiAoQk9BUkRfVE9fTU9WSU5HX0VMRU1FTlQuZ2V0KGJvYXJkKSB8fCBbXSkubGVuZ3RoID4gMDtcbn07XG5cbmV4cG9ydCBjb25zdCByZW1vdmVNb3ZpbmdFbGVtZW50cyA9IChib2FyZDogUGxhaXRCb2FyZCkgPT4ge1xuICAgIEJPQVJEX1RPX01PVklOR19FTEVNRU5ULmRlbGV0ZShib2FyZCk7XG4gICAgc2V0RHJhZ2dpbmcoYm9hcmQsIGZhbHNlKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjYWNoZU1vdmluZ0VsZW1lbnRzID0gKGJvYXJkOiBQbGFpdEJvYXJkLCBlbGVtZW50czogUGxhaXRFbGVtZW50W10pID0+IHtcbiAgICBCT0FSRF9UT19NT1ZJTkdfRUxFTUVOVC5zZXQoYm9hcmQsIGVsZW1lbnRzKTtcbiAgICBzZXREcmFnZ2luZyhib2FyZCwgdHJ1ZSk7XG59O1xuIl19