@baleada/logic 0.22.6 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +2229 -491
- package/lib/index.d.ts +507 -71
- package/lib/index.js +2173 -485
- package/package.json +28 -16
package/lib/index.js
CHANGED
|
@@ -1,50 +1,55 @@
|
|
|
1
|
-
import { reduce, pipe, unique, toArray, slice, filter, map, concat, find, findIndex, join, some, every } from 'lazy-collections';
|
|
2
|
-
import slugify from '@sindresorhus/slugify';
|
|
3
1
|
import BezierEasing from 'bezier-easing';
|
|
4
2
|
import { mix } from '@snigo.dev/color';
|
|
3
|
+
import { pipe, concat, toArray, filter, map, reduce, slice, sort, unique, find, findIndex, join, at, includes, some, every, flatMap, reverse as reverse$1 } from 'lazy-collections';
|
|
5
4
|
import { getStroke } from 'perfect-freehand';
|
|
6
5
|
import polygonClipping from 'polygon-clipping';
|
|
6
|
+
import ky from 'ky';
|
|
7
7
|
import createDOMPurify from 'dompurify';
|
|
8
8
|
import { Searcher } from 'fast-fuzzy';
|
|
9
|
+
import { klona } from 'klona';
|
|
10
|
+
import { dequal } from 'dequal';
|
|
11
|
+
import slugify from '@sindresorhus/slugify';
|
|
12
|
+
import clsx from 'clsx';
|
|
9
13
|
|
|
10
|
-
function
|
|
11
|
-
return
|
|
12
|
-
return
|
|
13
|
-
async (accumulatorPromise, item, index) => {
|
|
14
|
-
const accumulator = await accumulatorPromise;
|
|
15
|
-
return accumulate(accumulator, item, index);
|
|
16
|
-
},
|
|
17
|
-
Promise.resolve(initialValue)
|
|
18
|
-
)(array);
|
|
14
|
+
function createClone() {
|
|
15
|
+
return (any) => {
|
|
16
|
+
return klona(any);
|
|
19
17
|
};
|
|
20
18
|
}
|
|
21
|
-
function
|
|
22
|
-
return (
|
|
19
|
+
function createEqual(compared) {
|
|
20
|
+
return (any) => dequal(any, compared);
|
|
23
21
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
|
|
23
|
+
function createConcat(...arrays) {
|
|
24
|
+
return (array) => pipe(
|
|
25
|
+
concat(array, ...arrays),
|
|
26
|
+
toArray()
|
|
27
|
+
)();
|
|
29
28
|
}
|
|
30
|
-
function
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
resolvedMaps.push(transformed);
|
|
36
|
-
return resolvedMaps;
|
|
37
|
-
},
|
|
38
|
-
[]
|
|
39
|
-
)(array);
|
|
40
|
-
};
|
|
29
|
+
function createFilter(predicate) {
|
|
30
|
+
return (array) => pipe(
|
|
31
|
+
filter(predicate),
|
|
32
|
+
toArray()
|
|
33
|
+
)(array);
|
|
41
34
|
}
|
|
42
|
-
function
|
|
43
|
-
return
|
|
44
|
-
const
|
|
45
|
-
return
|
|
35
|
+
function createInsert(item, index) {
|
|
36
|
+
return (array) => {
|
|
37
|
+
const withItems = createConcat(array, [item])([]);
|
|
38
|
+
return createReorder(
|
|
39
|
+
{ start: array.length, itemCount: 1 },
|
|
40
|
+
index
|
|
41
|
+
)(withItems);
|
|
46
42
|
};
|
|
47
43
|
}
|
|
44
|
+
function createMap(transform) {
|
|
45
|
+
return (array) => pipe(
|
|
46
|
+
map(transform),
|
|
47
|
+
toArray()
|
|
48
|
+
)(array);
|
|
49
|
+
}
|
|
50
|
+
function createReduce(accumulate, initialValue) {
|
|
51
|
+
return (array) => reduce(accumulate, initialValue)(array);
|
|
52
|
+
}
|
|
48
53
|
function createRemove(index) {
|
|
49
54
|
return (array) => {
|
|
50
55
|
return createConcat(
|
|
@@ -53,15 +58,6 @@ function createRemove(index) {
|
|
|
53
58
|
)([]);
|
|
54
59
|
};
|
|
55
60
|
}
|
|
56
|
-
function createInsert(item, index) {
|
|
57
|
-
return (array) => {
|
|
58
|
-
const withItems = createConcat(array, [item])([]);
|
|
59
|
-
return createReorder(
|
|
60
|
-
{ start: array.length, itemCount: 1 },
|
|
61
|
-
index
|
|
62
|
-
)(withItems);
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
61
|
function createReorder(from, to) {
|
|
66
62
|
return (array) => {
|
|
67
63
|
const [itemsToMoveStartIndex, itemsToMoveCount] = predicateObject(from) ? [from.start, from.itemCount] : [from, 1], insertIndex = to;
|
|
@@ -90,8 +86,34 @@ function createReorder(from, to) {
|
|
|
90
86
|
return array;
|
|
91
87
|
};
|
|
92
88
|
}
|
|
93
|
-
function
|
|
94
|
-
return
|
|
89
|
+
function createReplace(index, replacement) {
|
|
90
|
+
return createMap((item, i) => i === index ? replacement : item);
|
|
91
|
+
}
|
|
92
|
+
function createReverse() {
|
|
93
|
+
return (array) => {
|
|
94
|
+
const reversed = [];
|
|
95
|
+
for (let i = array.length - 1; i > -1; i--) {
|
|
96
|
+
reversed.push(array[i]);
|
|
97
|
+
}
|
|
98
|
+
return reversed;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function createSlice(from, to) {
|
|
102
|
+
const toSliced = to ? slice(from, to - 1) : slice(from);
|
|
103
|
+
return (array) => {
|
|
104
|
+
return from === to ? [] : pipe(
|
|
105
|
+
toSliced,
|
|
106
|
+
toArray()
|
|
107
|
+
)(array);
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function createSort(compare) {
|
|
111
|
+
return (array) => {
|
|
112
|
+
return pipe(
|
|
113
|
+
sort(compare),
|
|
114
|
+
toArray()
|
|
115
|
+
)(array);
|
|
116
|
+
};
|
|
95
117
|
}
|
|
96
118
|
function createSwap(indices) {
|
|
97
119
|
return (array) => {
|
|
@@ -113,16 +135,7 @@ function createSwap(indices) {
|
|
|
113
135
|
reorderTo: (array2) => array2
|
|
114
136
|
};
|
|
115
137
|
})();
|
|
116
|
-
return
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
function createReplace(index, item) {
|
|
120
|
-
return (array) => {
|
|
121
|
-
return createConcat(
|
|
122
|
-
createSlice(0, index)(array),
|
|
123
|
-
[item],
|
|
124
|
-
createSlice(index + 1)(array)
|
|
125
|
-
)([]);
|
|
138
|
+
return pipe(reorderFrom, reorderTo)(array);
|
|
126
139
|
};
|
|
127
140
|
}
|
|
128
141
|
function createUnique() {
|
|
@@ -131,257 +144,1986 @@ function createUnique() {
|
|
|
131
144
|
toArray()
|
|
132
145
|
)(array);
|
|
133
146
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
147
|
+
|
|
148
|
+
function createFilterAsync(predicate) {
|
|
149
|
+
return async (array) => {
|
|
150
|
+
const transformedAsync = await createMapAsync(predicate)(array);
|
|
151
|
+
return createFilter((_, index) => transformedAsync[index])(array);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function createFindAsync(predicate) {
|
|
155
|
+
return async (array) => {
|
|
156
|
+
for (let i = 0; i < array.length; i++) {
|
|
157
|
+
const item = array[i], is = await predicate(item, i);
|
|
158
|
+
if (is)
|
|
159
|
+
return item;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function createFindIndexAsync(predicate) {
|
|
164
|
+
return async (array) => {
|
|
165
|
+
for (let i = 0; i < array.length; i++) {
|
|
166
|
+
const item = array[i], is = await predicate(item, i);
|
|
167
|
+
if (is)
|
|
168
|
+
return i;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
function createForEachAsync(forEach) {
|
|
173
|
+
return async (array) => {
|
|
174
|
+
for (let i = 0; i < array.length; i++) {
|
|
175
|
+
const item = array[i];
|
|
176
|
+
await forEach(item, i);
|
|
177
|
+
}
|
|
178
|
+
return array;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function createMapAsync(transform) {
|
|
182
|
+
return async (array) => {
|
|
183
|
+
return await createReduceAsync(
|
|
184
|
+
async (resolvedMaps, item, index) => {
|
|
185
|
+
const transformed = await transform(item, index);
|
|
186
|
+
resolvedMaps.push(transformed);
|
|
187
|
+
return resolvedMaps;
|
|
188
|
+
},
|
|
189
|
+
[]
|
|
139
190
|
)(array);
|
|
140
191
|
};
|
|
141
192
|
}
|
|
142
|
-
function
|
|
143
|
-
return (array) =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
193
|
+
function createReduceAsync(accumulate, initialValue) {
|
|
194
|
+
return async (array) => {
|
|
195
|
+
return await reduce(
|
|
196
|
+
async (accumulatorPromise, item, index) => {
|
|
197
|
+
const accumulator = await accumulatorPromise;
|
|
198
|
+
return accumulate(accumulator, item, index);
|
|
199
|
+
},
|
|
200
|
+
Promise.resolve(initialValue)
|
|
201
|
+
)(array);
|
|
202
|
+
};
|
|
147
203
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
204
|
+
|
|
205
|
+
function createClip(required) {
|
|
206
|
+
return (string) => {
|
|
207
|
+
return string.replace(required, "");
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function createSlug(options) {
|
|
211
|
+
return (string) => {
|
|
212
|
+
return slugify(string, options);
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function createClamp(min, max) {
|
|
217
|
+
return (number) => {
|
|
218
|
+
const maxed = Math.max(number, min);
|
|
219
|
+
return Math.min(maxed, max);
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function createDetermine(potentialities) {
|
|
223
|
+
const predicates = createMap(({ outcome, probability }, index) => {
|
|
224
|
+
const lowerBound = index === 0 ? 0 : pipe(
|
|
225
|
+
slice(0, index - 1),
|
|
226
|
+
reduce((lowerBound2, { probability: probability2 }) => lowerBound2 + probability2, 0)
|
|
227
|
+
)(potentialities), upperBound = lowerBound + probability;
|
|
228
|
+
return {
|
|
229
|
+
outcome,
|
|
230
|
+
predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
|
|
231
|
+
};
|
|
232
|
+
})(potentialities);
|
|
233
|
+
return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function createEntries() {
|
|
237
|
+
return (object) => {
|
|
238
|
+
const entries = [];
|
|
239
|
+
for (const key in object) {
|
|
240
|
+
entries.push([key, object[key]]);
|
|
241
|
+
}
|
|
242
|
+
return entries;
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function createKeys() {
|
|
246
|
+
return (object) => {
|
|
247
|
+
const keys = [];
|
|
248
|
+
for (const key in object) {
|
|
249
|
+
keys.push(key);
|
|
250
|
+
}
|
|
251
|
+
return keys;
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function createEvery(predicate) {
|
|
255
|
+
return (object) => {
|
|
256
|
+
for (const key in object) {
|
|
257
|
+
if (!predicate(key, object[key])) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function createSome(predicate) {
|
|
265
|
+
return (object) => {
|
|
266
|
+
for (const key in object) {
|
|
267
|
+
if (predicate(key, object[key]))
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
return false;
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function createRename(from, to) {
|
|
275
|
+
return (map) => {
|
|
276
|
+
const keys = [...map.keys()], keyToRenameIndex = findIndex((k) => k === from)(keys), newKeys = createReplace(keyToRenameIndex, to)(keys), values = [...map.values()];
|
|
277
|
+
return createReduce((renamed, key, index) => renamed.set(key, values[index]), /* @__PURE__ */ new Map())(newKeys);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const defaultOptions$m = {
|
|
282
|
+
elementIsCandidate: false,
|
|
283
|
+
// Adapted from React Aria https://github.com/adobe/react-spectrum/blob/b6786da906973130a1746b2bee63215bba013ca4/packages/%40react-aria/focus/src/FocusScope.tsx#L256
|
|
284
|
+
tabbableSelector: join(':not([hidden]):not([tabindex="-1"]),')([
|
|
285
|
+
"input:not([disabled]):not([type=hidden])",
|
|
286
|
+
"select:not([disabled])",
|
|
287
|
+
"textarea:not([disabled])",
|
|
288
|
+
"button:not([disabled])",
|
|
289
|
+
"a[href]",
|
|
290
|
+
"area[href]",
|
|
291
|
+
"summary",
|
|
292
|
+
"iframe",
|
|
293
|
+
"object",
|
|
294
|
+
"embed",
|
|
295
|
+
"audio[controls]",
|
|
296
|
+
"video[controls]",
|
|
297
|
+
"[contenteditable]",
|
|
298
|
+
"[tabindex]:not([disabled])"
|
|
299
|
+
])
|
|
300
|
+
};
|
|
301
|
+
function createFocusable(order, options = {}) {
|
|
302
|
+
const { elementIsCandidate, tabbableSelector } = { ...defaultOptions$m, ...options }, predicateFocusable = (element) => element.matches(tabbableSelector);
|
|
303
|
+
return (element) => {
|
|
304
|
+
if (elementIsCandidate && predicateFocusable(element))
|
|
305
|
+
return element;
|
|
306
|
+
switch (order) {
|
|
307
|
+
case "first":
|
|
308
|
+
for (let i = 0; i < element.children.length; i++) {
|
|
309
|
+
const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
|
|
310
|
+
if (focusable)
|
|
311
|
+
return focusable;
|
|
312
|
+
}
|
|
313
|
+
break;
|
|
314
|
+
case "last":
|
|
315
|
+
for (let i = element.children.length - 1; i > -1; i--) {
|
|
316
|
+
const focusable = createFocusable(order, { elementIsCandidate: true })(element.children[i]);
|
|
317
|
+
if (focusable)
|
|
318
|
+
return focusable;
|
|
319
|
+
}
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function createToIndegree(graph) {
|
|
326
|
+
const toIncoming = createToIncoming(graph);
|
|
327
|
+
return (node) => pipe(
|
|
328
|
+
toIncoming,
|
|
329
|
+
toLength()
|
|
330
|
+
)(node);
|
|
331
|
+
}
|
|
332
|
+
function createToOutdegree(graph) {
|
|
333
|
+
const toOutgoing = createToOutgoing(graph);
|
|
334
|
+
return (node) => pipe(
|
|
335
|
+
toOutgoing,
|
|
336
|
+
toLength()
|
|
337
|
+
)(node);
|
|
338
|
+
}
|
|
339
|
+
function createToIncoming(graph) {
|
|
340
|
+
const { edges } = graph;
|
|
341
|
+
return function* (node) {
|
|
342
|
+
yield* filter(
|
|
343
|
+
({ to }) => to === node
|
|
344
|
+
)(edges);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
function createToOutgoing(graph) {
|
|
348
|
+
const { edges } = graph;
|
|
349
|
+
return function* (node) {
|
|
350
|
+
yield* filter(
|
|
351
|
+
({ from }) => from === node
|
|
352
|
+
)(edges);
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function createPredicateRoot(graph) {
|
|
356
|
+
const toIndegree = createToIndegree(graph);
|
|
357
|
+
return (node) => toIndegree(node) === 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function createFind(node) {
|
|
361
|
+
return (tree) => {
|
|
362
|
+
for (const treeNode of tree) {
|
|
363
|
+
if (treeNode.node === node)
|
|
364
|
+
return treeNode;
|
|
365
|
+
const found = createFind(node)(treeNode.children);
|
|
366
|
+
if (found)
|
|
367
|
+
return found;
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function createToLayers$1(options = {}) {
|
|
373
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
374
|
+
return function toLayers(directedAcyclic) {
|
|
375
|
+
const layers = [];
|
|
376
|
+
for (const { path } of toSteps(directedAcyclic)) {
|
|
377
|
+
const node = path.at(-1), depth = path.length - 1;
|
|
378
|
+
(layers[depth] || (layers[depth] = [])).push(node);
|
|
379
|
+
}
|
|
380
|
+
return layers;
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function createToTree$2(options = {}) {
|
|
384
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
385
|
+
return function toTree(directedAcyclic) {
|
|
386
|
+
const firstRoot = pipe(
|
|
387
|
+
createToRoots(),
|
|
388
|
+
at(0)
|
|
389
|
+
)(directedAcyclic), tree = [];
|
|
390
|
+
tree.push({
|
|
391
|
+
node: firstRoot,
|
|
392
|
+
children: []
|
|
393
|
+
});
|
|
394
|
+
for (const { path } of toSteps(directedAcyclic)) {
|
|
395
|
+
const node = path.at(-1), parent = path.at(-2);
|
|
396
|
+
if (parent) {
|
|
397
|
+
const parentTreeNode = createFind(parent)(tree);
|
|
398
|
+
if (parentTreeNode) {
|
|
399
|
+
parentTreeNode.children.push({
|
|
400
|
+
node,
|
|
401
|
+
children: []
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return tree;
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function createToCommonAncestors$2(directedAcyclic) {
|
|
410
|
+
const toNodeSteps = createToNodeSteps$2(directedAcyclic);
|
|
411
|
+
return function* (a, b) {
|
|
412
|
+
for (const { path: aPath } of toNodeSteps(a)) {
|
|
413
|
+
for (const { path: bPath } of toNodeSteps(b)) {
|
|
414
|
+
for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
|
|
415
|
+
for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
|
|
416
|
+
if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
|
|
417
|
+
yield {
|
|
418
|
+
node: aPath[aPathIndex],
|
|
419
|
+
distances: {
|
|
420
|
+
[a]: aPath.length - aPathIndex - 1,
|
|
421
|
+
[b]: bPath.length - bPathIndex - 1
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
function createPredicateAncestor$2(directedAcyclic) {
|
|
432
|
+
const toNodeSteps = createToNodeSteps$2(directedAcyclic);
|
|
433
|
+
return function(descendant, ancestor) {
|
|
434
|
+
return pipe(
|
|
435
|
+
toNodeSteps,
|
|
436
|
+
some(({ path }) => includes(ancestor)(path))
|
|
437
|
+
)(descendant);
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function createToNodeSteps$2(directedAcyclic, options = {}) {
|
|
441
|
+
const toSteps = createToSteps$2(options.createToSteps);
|
|
442
|
+
return function* (node) {
|
|
443
|
+
yield* pipe(
|
|
444
|
+
toSteps,
|
|
445
|
+
filter(({ path }) => path.at(-1) === node)
|
|
446
|
+
)(directedAcyclic);
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
const defaultCreateToStepsOptions$1 = {
|
|
450
|
+
toUnsetMetadata: () => 0,
|
|
451
|
+
toMockMetadata: (node, totalConnectionsFollowed) => totalConnectionsFollowed,
|
|
452
|
+
kind: "directed acyclic"
|
|
453
|
+
};
|
|
454
|
+
function createToSteps$2(options = {}) {
|
|
455
|
+
const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
|
|
456
|
+
return function* (directedAcyclic) {
|
|
457
|
+
const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$2(directedAcyclic), roots = pipe(
|
|
458
|
+
createToRoots({ kind }),
|
|
459
|
+
toArray()
|
|
460
|
+
)(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
|
|
461
|
+
return totalConnectionsFollowedByNode[node] === toOutdegree(node);
|
|
462
|
+
};
|
|
463
|
+
for (const node of nodes) {
|
|
464
|
+
state[node] = {
|
|
465
|
+
status: "unset",
|
|
466
|
+
metadata: toUnsetMetadata(node)
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
let location = root || at(0)(roots);
|
|
470
|
+
const path = toPath(state);
|
|
471
|
+
yield { path, state: JSON.parse(JSON.stringify(state)) };
|
|
472
|
+
function* toStep() {
|
|
473
|
+
if (predicateExhausted(location)) {
|
|
474
|
+
if (includes(location)(roots))
|
|
475
|
+
return;
|
|
476
|
+
state[location].status = "unset";
|
|
477
|
+
state[location].metadata = toUnsetMetadata(location);
|
|
478
|
+
const path3 = toPath(state);
|
|
479
|
+
location = path3.at(-2);
|
|
480
|
+
yield* toStep();
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (!(location in totalConnectionsFollowedByNode))
|
|
484
|
+
totalConnectionsFollowedByNode[location] = 0;
|
|
485
|
+
state[location].status = "set";
|
|
486
|
+
state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
|
|
487
|
+
const path2 = toPath(state);
|
|
488
|
+
yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
|
|
489
|
+
totalConnectionsFollowedByNode[location]++;
|
|
490
|
+
const newLocation = path2.at(-1);
|
|
491
|
+
if (toOutdegree(newLocation) > 0)
|
|
492
|
+
location = newLocation;
|
|
493
|
+
yield* toStep();
|
|
494
|
+
}
|
|
495
|
+
yield* toStep();
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
function createToPath$2(directedAcyclic) {
|
|
499
|
+
const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
|
|
500
|
+
createToRoots(),
|
|
501
|
+
at(0)
|
|
502
|
+
)(directedAcyclic);
|
|
503
|
+
return (state) => {
|
|
504
|
+
const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
|
|
505
|
+
while (getLastOutdegree() > 0 && getLastStatus() === "set") {
|
|
506
|
+
const edge = pipe(
|
|
507
|
+
toOutgoing,
|
|
508
|
+
find(
|
|
509
|
+
({ predicateTraversable }) => predicateTraversable(state)
|
|
510
|
+
)
|
|
511
|
+
)(path.at(-1));
|
|
512
|
+
path.push(edge.to);
|
|
513
|
+
}
|
|
514
|
+
return path;
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function createToRoots(options = {}) {
|
|
518
|
+
return function* (directedAcyclic) {
|
|
519
|
+
const { nodes } = directedAcyclic;
|
|
520
|
+
for (const node of nodes) {
|
|
521
|
+
if (createPredicateRoot(directedAcyclic)(node))
|
|
522
|
+
yield node;
|
|
523
|
+
if (options.kind === "arborescence")
|
|
524
|
+
break;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function createToLayers(options = {}) {
|
|
530
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
531
|
+
return async function toLayers(directedAcyclic) {
|
|
532
|
+
const layers = [];
|
|
533
|
+
for await (const { path } of toSteps(directedAcyclic)) {
|
|
534
|
+
const node = path.at(-1), depth = path.length - 1;
|
|
535
|
+
(layers[depth] || (layers[depth] = [])).push(node);
|
|
536
|
+
}
|
|
537
|
+
return layers;
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
function createToTree$1(options = {}) {
|
|
541
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
542
|
+
return async function toTree(directedAcyclic) {
|
|
543
|
+
const firstRoot = pipe(
|
|
544
|
+
createToRoots(),
|
|
545
|
+
at(0)
|
|
546
|
+
)(directedAcyclic), tree = [];
|
|
547
|
+
tree.push({
|
|
548
|
+
node: firstRoot,
|
|
549
|
+
children: []
|
|
550
|
+
});
|
|
551
|
+
for await (const { path } of toSteps(directedAcyclic)) {
|
|
552
|
+
const node = path.at(-1), parent = path.at(-2);
|
|
553
|
+
if (parent) {
|
|
554
|
+
const parentTreeNode = createFind(parent)(tree);
|
|
555
|
+
if (parentTreeNode) {
|
|
556
|
+
parentTreeNode.children.push({
|
|
557
|
+
node,
|
|
558
|
+
children: []
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return tree;
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
function createToCommonAncestors$1(directedAcyclic) {
|
|
567
|
+
const toNodeSteps = createToNodeSteps$1(directedAcyclic);
|
|
568
|
+
return async function* (a, b) {
|
|
569
|
+
for await (const { path: aPath } of toNodeSteps(a)) {
|
|
570
|
+
for await (const { path: bPath } of toNodeSteps(b)) {
|
|
571
|
+
for (let aPathIndex = aPath.length - 1; aPathIndex >= 0; aPathIndex--) {
|
|
572
|
+
for (let bPathIndex = bPath.length - 1; bPathIndex >= 0; bPathIndex--) {
|
|
573
|
+
if (aPath[aPathIndex] === bPath[bPathIndex] && !includes(aPath[aPathIndex])([a, b])) {
|
|
574
|
+
yield {
|
|
575
|
+
node: aPath[aPathIndex],
|
|
576
|
+
distances: {
|
|
577
|
+
[a]: aPath.length - aPathIndex - 1,
|
|
578
|
+
[b]: bPath.length - bPathIndex - 1
|
|
579
|
+
}
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function createPredicateAncestor$1(directedAcyclic) {
|
|
589
|
+
const toNodeSteps = createToNodeSteps$1(directedAcyclic);
|
|
590
|
+
return async function(descendant, ancestor) {
|
|
591
|
+
return await pipe(
|
|
592
|
+
toNodeSteps,
|
|
593
|
+
some(({ path }) => includes(ancestor)(path))
|
|
594
|
+
)(descendant);
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function createToNodeSteps$1(directedAcyclic, options = {}) {
|
|
598
|
+
const toSteps = createToSteps$1(options.createToSteps);
|
|
599
|
+
return async function* (node) {
|
|
600
|
+
yield* await pipe(
|
|
601
|
+
toSteps,
|
|
602
|
+
filter(({ path }) => path.at(-1) === node)
|
|
603
|
+
)(directedAcyclic);
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function createToSteps$1(options = {}) {
|
|
607
|
+
const { toUnsetMetadata, toMockMetadata, root, kind } = { ...defaultCreateToStepsOptions$1, ...options };
|
|
608
|
+
return async function* (directedAcyclic) {
|
|
609
|
+
const { nodes } = directedAcyclic, toOutdegree = createToOutdegree(directedAcyclic), toPath = createToPath$1(directedAcyclic), roots = pipe(
|
|
610
|
+
createToRoots({ kind }),
|
|
611
|
+
toArray()
|
|
612
|
+
)(directedAcyclic), state = {}, totalConnectionsFollowedByNode = {}, predicateExhausted = (node) => {
|
|
613
|
+
return totalConnectionsFollowedByNode[node] === toOutdegree(node);
|
|
614
|
+
};
|
|
615
|
+
for (const node of nodes) {
|
|
616
|
+
state[node] = {
|
|
617
|
+
status: "unset",
|
|
618
|
+
metadata: toUnsetMetadata(node)
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
let location = root || at(0)(roots);
|
|
622
|
+
const path = await toPath(state);
|
|
623
|
+
yield { path, state: JSON.parse(JSON.stringify(state)) };
|
|
624
|
+
async function* toStep() {
|
|
625
|
+
if (predicateExhausted(location)) {
|
|
626
|
+
if (includes(location)(roots))
|
|
627
|
+
return;
|
|
628
|
+
state[location].status = "unset";
|
|
629
|
+
state[location].metadata = toUnsetMetadata(location);
|
|
630
|
+
const path3 = await toPath(state);
|
|
631
|
+
location = path3.at(-2);
|
|
632
|
+
yield* await toStep();
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
if (!(location in totalConnectionsFollowedByNode))
|
|
636
|
+
totalConnectionsFollowedByNode[location] = 0;
|
|
637
|
+
state[location].status = "set";
|
|
638
|
+
state[location].metadata = toMockMetadata(location, totalConnectionsFollowedByNode[location]);
|
|
639
|
+
const path2 = await toPath(state);
|
|
640
|
+
yield { path: path2, state: JSON.parse(JSON.stringify(state)) };
|
|
641
|
+
totalConnectionsFollowedByNode[location]++;
|
|
642
|
+
const newLocation = path2.at(-1);
|
|
643
|
+
if (toOutdegree(newLocation) > 0)
|
|
644
|
+
location = newLocation;
|
|
645
|
+
yield* await toStep();
|
|
646
|
+
}
|
|
647
|
+
yield* await toStep();
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function createToPath$1(directedAcyclic) {
|
|
651
|
+
const toOutdegree = createToOutdegree(directedAcyclic), toOutgoing = createToOutgoing(directedAcyclic), firstRoot = pipe(
|
|
652
|
+
createToRoots(),
|
|
653
|
+
at(0)
|
|
654
|
+
)(directedAcyclic);
|
|
655
|
+
return async (state) => {
|
|
656
|
+
const path = [firstRoot], getLastOutdegree = () => toOutdegree(path.at(-1)), getLastStatus = () => state[path.at(-1)].status;
|
|
657
|
+
while (getLastOutdegree() > 0 && getLastStatus() === "set") {
|
|
658
|
+
const edge = await pipe(
|
|
659
|
+
toOutgoing,
|
|
660
|
+
toArray(),
|
|
661
|
+
createFindAsync(
|
|
662
|
+
async ({ predicateTraversable }) => await predicateTraversable(state)
|
|
663
|
+
)
|
|
664
|
+
)(path.at(-1));
|
|
665
|
+
path.push(edge.to);
|
|
666
|
+
}
|
|
667
|
+
return path;
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
const defaultCreateToStepsOptions = {
|
|
672
|
+
priorityBranch: false,
|
|
673
|
+
kind: "directed acyclic"
|
|
674
|
+
};
|
|
675
|
+
function createToTree(options = {}) {
|
|
676
|
+
const withDefaults = {
|
|
677
|
+
...options,
|
|
678
|
+
createToSteps: {
|
|
679
|
+
...defaultCreateToStepsOptions,
|
|
680
|
+
...options.createToSteps
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
return createToTree$2({
|
|
684
|
+
...withDefaults,
|
|
685
|
+
createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
function createToCommonAncestors(...params) {
|
|
689
|
+
return createToCommonAncestors$2(...params);
|
|
690
|
+
}
|
|
691
|
+
function createPredicateAncestor(...params) {
|
|
692
|
+
return createPredicateAncestor$2(...params);
|
|
693
|
+
}
|
|
694
|
+
function createToNodeSteps(decisionTree, options = {}) {
|
|
695
|
+
const withDefaults = {
|
|
696
|
+
...options,
|
|
697
|
+
createToSteps: {
|
|
698
|
+
...defaultCreateToStepsOptions,
|
|
699
|
+
...options.createToSteps
|
|
700
|
+
}
|
|
701
|
+
};
|
|
702
|
+
return createToNodeSteps$2(
|
|
703
|
+
decisionTree,
|
|
704
|
+
{
|
|
705
|
+
...withDefaults,
|
|
706
|
+
createToSteps: toCreateDirectedAcyclicToStepsOptions(withDefaults.createToSteps)
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
function createToSteps(options = {}) {
|
|
711
|
+
const withDefaults = {
|
|
712
|
+
...defaultCreateToStepsOptions,
|
|
713
|
+
...options
|
|
714
|
+
};
|
|
715
|
+
return createToSteps$2(
|
|
716
|
+
toCreateDirectedAcyclicToStepsOptions(withDefaults)
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
function createToPath(...params) {
|
|
720
|
+
return createToPath$2(...params);
|
|
721
|
+
}
|
|
722
|
+
function toCreateDirectedAcyclicToStepsOptions(options) {
|
|
723
|
+
return {
|
|
724
|
+
...defaultCreateToStepsOptions,
|
|
725
|
+
...options,
|
|
726
|
+
...{
|
|
727
|
+
toUnsetMetadata: () => false,
|
|
728
|
+
toMockMetadata: (node, totalConnectionsFollowed) => options.priorityBranch ? !totalConnectionsFollowed : !!totalConnectionsFollowed
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
function createList() {
|
|
734
|
+
return (...classValues) => clsx(...classValues);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
const defaultOptions$l = {
|
|
738
|
+
toId: (node) => node.id,
|
|
739
|
+
toChildren: (node) => node.children
|
|
740
|
+
};
|
|
741
|
+
function createToGraph(options = {}) {
|
|
742
|
+
const { toId, toChildren } = { ...defaultOptions$l, ...options };
|
|
743
|
+
return function* (tree) {
|
|
744
|
+
const root = tree[0], rootId = toId(root);
|
|
745
|
+
function* toPair(node, id) {
|
|
746
|
+
const children = toChildren(node) || [];
|
|
747
|
+
for (const child of children) {
|
|
748
|
+
const childId = toId(child);
|
|
749
|
+
yield {
|
|
750
|
+
node: childId,
|
|
751
|
+
edge: { from: id, to: childId }
|
|
752
|
+
};
|
|
753
|
+
yield* toPair(child, childId);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
yield { node: rootId };
|
|
757
|
+
yield* toPair(root, rootId);
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
const defaultOptions$k = {
|
|
762
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias)
|
|
763
|
+
};
|
|
764
|
+
const createPredicateKeycomboMatch$1 = (keycombo, options = {}) => {
|
|
765
|
+
const { toKey } = { ...defaultOptions$k, ...options }, keys = pipe(
|
|
766
|
+
fromComboToAliases,
|
|
767
|
+
map(toKey)
|
|
768
|
+
)(keycombo);
|
|
769
|
+
return (event) => {
|
|
770
|
+
const { toValue, set } = createKeyStatuses();
|
|
771
|
+
set(fromEventToKeyStatusKey(event), "down");
|
|
772
|
+
for (const modifier of modifiers) {
|
|
773
|
+
if (event[`${modifier.toLowerCase()}Key`])
|
|
774
|
+
set({ key: modifier }, "down");
|
|
775
|
+
}
|
|
776
|
+
return every(pipe(
|
|
777
|
+
toValue,
|
|
778
|
+
predicateDown
|
|
779
|
+
))(keys);
|
|
780
|
+
};
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
const defaultOptions$j = {
|
|
784
|
+
initial: [],
|
|
785
|
+
createPredicateKey: (query) => (candidate) => query === candidate
|
|
786
|
+
};
|
|
787
|
+
function createAssociativeArray(options = {}) {
|
|
788
|
+
const { initial, createPredicateKey } = { ...defaultOptions$j, ...options }, entries = [...initial];
|
|
789
|
+
const toValue = (key) => {
|
|
790
|
+
const predicateKey = createPredicateKey(key);
|
|
791
|
+
return find(
|
|
792
|
+
([candidate]) => predicateKey(candidate)
|
|
793
|
+
)(entries)?.[1];
|
|
794
|
+
};
|
|
795
|
+
const set = (key, value) => {
|
|
796
|
+
const predicateKey = createPredicateKey(key), index = findIndex(
|
|
797
|
+
([candidate]) => predicateKey(candidate)
|
|
798
|
+
)(entries);
|
|
799
|
+
if (index === -1) {
|
|
800
|
+
entries.push([key, value]);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
entries[index][1] = value;
|
|
804
|
+
};
|
|
805
|
+
const predicateHas = (key) => {
|
|
806
|
+
const predicateKey = createPredicateKey(key);
|
|
807
|
+
return findIndex(
|
|
808
|
+
([candidate]) => predicateKey(candidate)
|
|
809
|
+
)(entries) !== -1;
|
|
810
|
+
};
|
|
811
|
+
const clear = () => {
|
|
812
|
+
entries.length = 0;
|
|
813
|
+
};
|
|
814
|
+
const del = (key) => {
|
|
815
|
+
const predicateKey = createPredicateKey(key), index = findIndex(
|
|
816
|
+
([candidate]) => predicateKey(candidate)
|
|
817
|
+
)(entries);
|
|
818
|
+
if (index === -1) {
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
entries.splice(index, 1);
|
|
822
|
+
return true;
|
|
823
|
+
};
|
|
824
|
+
const toKeys = () => {
|
|
825
|
+
return createMap(([key]) => key)(entries);
|
|
826
|
+
};
|
|
827
|
+
const toValues = () => {
|
|
828
|
+
return createMap(([, value]) => value)(entries);
|
|
829
|
+
};
|
|
830
|
+
const toEntries = () => {
|
|
831
|
+
return entries;
|
|
832
|
+
};
|
|
833
|
+
return {
|
|
834
|
+
toValue,
|
|
835
|
+
set,
|
|
836
|
+
predicateHas,
|
|
837
|
+
clear,
|
|
838
|
+
delete: del,
|
|
839
|
+
toKeys,
|
|
840
|
+
toValues,
|
|
841
|
+
toEntries
|
|
842
|
+
// get: toValue,
|
|
843
|
+
// has: predicateHas,
|
|
844
|
+
// keys: toKeys,
|
|
845
|
+
// values: toValues,
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
const defaultOptions$i = {
|
|
850
|
+
minDuration: 0,
|
|
851
|
+
preventsDefaultUnlessDenied: true,
|
|
852
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
853
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
854
|
+
};
|
|
855
|
+
function createKeypress(keycomboOrKeycombos, options = {}) {
|
|
856
|
+
const {
|
|
857
|
+
minDuration,
|
|
858
|
+
preventsDefaultUnlessDenied,
|
|
859
|
+
toKey,
|
|
860
|
+
toAliases,
|
|
861
|
+
onDown,
|
|
862
|
+
onUp,
|
|
863
|
+
onVisibilitychange
|
|
864
|
+
} = { ...defaultOptions$i, ...options }, {
|
|
865
|
+
matchPredicatesByKeycombo,
|
|
866
|
+
getDownCombos,
|
|
867
|
+
predicateValid,
|
|
868
|
+
cleanup,
|
|
869
|
+
statuses
|
|
870
|
+
} = createKeyState({
|
|
871
|
+
keycomboOrKeycombos,
|
|
872
|
+
unsupportedAliases: unsupportedAliases$2,
|
|
873
|
+
toKey,
|
|
874
|
+
toAliases,
|
|
875
|
+
getRequest: () => request
|
|
876
|
+
});
|
|
877
|
+
let request;
|
|
878
|
+
let localStatus;
|
|
879
|
+
const keydown = (event, api) => {
|
|
880
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
881
|
+
if (statuses.toValue(key) === "down") {
|
|
882
|
+
onDown?.(toHookApi(api));
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
statuses.set(key, "down");
|
|
886
|
+
if (localStatus === "denied") {
|
|
887
|
+
denied();
|
|
888
|
+
onDown?.(toHookApi(api));
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
const downCombos = getDownCombos();
|
|
892
|
+
if (
|
|
893
|
+
// NOT BUILDING VALID COMBO
|
|
894
|
+
!predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
|
|
895
|
+
) {
|
|
896
|
+
denied();
|
|
897
|
+
localStatus = getStatus();
|
|
898
|
+
if (includes(event.key)(unsupportedKeys$2))
|
|
899
|
+
statuses.clear();
|
|
900
|
+
onDown?.(toHookApi(api));
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
if (preventsDefaultUnlessDenied)
|
|
904
|
+
event.preventDefault();
|
|
905
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
906
|
+
metadata.pressed = downCombos[0];
|
|
907
|
+
localStatus = "recognizing";
|
|
908
|
+
cleanup();
|
|
909
|
+
storeKeyboardTimeMetadata({
|
|
910
|
+
event,
|
|
911
|
+
api,
|
|
912
|
+
getTimeMetadata: getMetadata,
|
|
913
|
+
getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
|
|
914
|
+
setRequest: (newRequest) => request = newRequest,
|
|
915
|
+
recognize
|
|
916
|
+
});
|
|
917
|
+
onDown?.(toHookApi(api));
|
|
918
|
+
};
|
|
919
|
+
const recognize = (event, api) => {
|
|
920
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
921
|
+
if (metadata.duration >= minDuration) {
|
|
922
|
+
recognized();
|
|
923
|
+
localStatus = "recognized";
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
};
|
|
927
|
+
const keyup = (event, api) => {
|
|
928
|
+
const { denied } = api, key = fromEventToKeyStatusKey(event);
|
|
929
|
+
if (localStatus === "denied") {
|
|
930
|
+
denied();
|
|
931
|
+
if (includes(event.key)(unsupportedKeys$2))
|
|
932
|
+
statuses.clear();
|
|
933
|
+
else
|
|
934
|
+
statuses.delete(key);
|
|
935
|
+
if (!predicateSomeKeyDown(statuses))
|
|
936
|
+
localStatus = "recognizing";
|
|
937
|
+
onUp?.(toHookApi(api));
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
statuses.delete(key);
|
|
941
|
+
const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
|
|
942
|
+
if (downCombos.length && matches) {
|
|
943
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
944
|
+
metadata.pressed = downCombos[0];
|
|
945
|
+
if (preventsDefaultUnlessDenied)
|
|
946
|
+
event.preventDefault();
|
|
947
|
+
localStatus = "recognizing";
|
|
948
|
+
onUp?.(toHookApi(api));
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
denied();
|
|
952
|
+
cleanup();
|
|
953
|
+
onUp?.(toHookApi(api));
|
|
954
|
+
};
|
|
955
|
+
const visibilitychange = (event, api) => {
|
|
956
|
+
if (document.visibilityState === "hidden") {
|
|
957
|
+
statuses.clear();
|
|
958
|
+
localStatus = "recognizing";
|
|
959
|
+
cleanup();
|
|
960
|
+
}
|
|
961
|
+
onVisibilitychange?.(toHookApi(api));
|
|
962
|
+
};
|
|
963
|
+
return {
|
|
964
|
+
keydown,
|
|
965
|
+
keyup,
|
|
966
|
+
visibilitychange
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
const unsupportedAliases$2 = ["meta", "command", "cmd"];
|
|
970
|
+
const unsupportedKeys$2 = ["Meta"];
|
|
971
|
+
|
|
972
|
+
const defaultOptions$h = {
|
|
973
|
+
minDuration: 0,
|
|
974
|
+
preventsDefaultUnlessDenied: true,
|
|
975
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
976
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
977
|
+
};
|
|
978
|
+
function createKeyrelease(keycomboOrKeycombos, options = {}) {
|
|
979
|
+
const {
|
|
980
|
+
minDuration,
|
|
981
|
+
preventsDefaultUnlessDenied,
|
|
982
|
+
toKey,
|
|
983
|
+
toAliases,
|
|
984
|
+
onDown,
|
|
985
|
+
onUp,
|
|
986
|
+
onVisibilitychange
|
|
987
|
+
} = { ...defaultOptions$h, ...options }, {
|
|
988
|
+
matchPredicatesByKeycombo,
|
|
989
|
+
getDownCombos,
|
|
990
|
+
predicateValid,
|
|
991
|
+
cleanup,
|
|
992
|
+
statuses
|
|
993
|
+
} = createKeyState({
|
|
994
|
+
keycomboOrKeycombos,
|
|
995
|
+
unsupportedAliases: unsupportedAliases$1,
|
|
996
|
+
toKey,
|
|
997
|
+
toAliases,
|
|
998
|
+
getRequest: () => request
|
|
999
|
+
});
|
|
1000
|
+
let request, localStatus;
|
|
1001
|
+
const keydown = (event, api) => {
|
|
1002
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
1003
|
+
if (statuses.toValue(key) === "down") {
|
|
1004
|
+
onDown?.(toHookApi(api));
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
statuses.set(key, "down");
|
|
1008
|
+
if (localStatus === "denied") {
|
|
1009
|
+
denied();
|
|
1010
|
+
onDown?.(toHookApi(api));
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const downCombos = getDownCombos();
|
|
1014
|
+
if (
|
|
1015
|
+
// NOT BUILDING VALID COMBO
|
|
1016
|
+
!predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1])
|
|
1017
|
+
) {
|
|
1018
|
+
denied();
|
|
1019
|
+
localStatus = getStatus();
|
|
1020
|
+
if (includes(event.key)(unsupportedKeys$1))
|
|
1021
|
+
statuses.clear();
|
|
1022
|
+
onDown?.(toHookApi(api));
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
if (preventsDefaultUnlessDenied)
|
|
1026
|
+
event.preventDefault();
|
|
1027
|
+
const { getMetadata } = api;
|
|
1028
|
+
localStatus = "recognizing";
|
|
1029
|
+
cleanup();
|
|
1030
|
+
storeKeyboardTimeMetadata({
|
|
1031
|
+
event,
|
|
1032
|
+
api,
|
|
1033
|
+
getTimeMetadata: getMetadata,
|
|
1034
|
+
getShouldStore: () => downCombos.length && getDownCombos()[0] === downCombos[0],
|
|
1035
|
+
setRequest: (newRequest) => request = newRequest
|
|
1036
|
+
});
|
|
1037
|
+
onDown?.(toHookApi(api));
|
|
1038
|
+
};
|
|
1039
|
+
const keyup = (event, api) => {
|
|
1040
|
+
const {
|
|
1041
|
+
getStatus,
|
|
1042
|
+
getMetadata,
|
|
1043
|
+
denied
|
|
1044
|
+
} = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
|
|
1045
|
+
if (["denied", "recognized"].includes(localStatus)) {
|
|
1046
|
+
if (localStatus === "denied")
|
|
1047
|
+
denied();
|
|
1048
|
+
if (includes(event.key)(unsupportedKeys$1))
|
|
1049
|
+
statuses.clear();
|
|
1050
|
+
else
|
|
1051
|
+
statuses.delete(key);
|
|
1052
|
+
if (!predicateSomeKeyDown(statuses))
|
|
1053
|
+
localStatus = "recognizing";
|
|
1054
|
+
onUp?.(toHookApi(api));
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
const downCombos = getDownCombos(), matches = matchPredicatesByKeycombo[downCombos[0]]?.(statuses);
|
|
1058
|
+
statuses.delete(key);
|
|
1059
|
+
if (!downCombos.length || !matches) {
|
|
1060
|
+
onUp?.(toHookApi(api));
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
recognize(event, api);
|
|
1064
|
+
const status = getStatus();
|
|
1065
|
+
if (status === "recognized") {
|
|
1066
|
+
localStatus = status;
|
|
1067
|
+
metadata.released = downCombos[0];
|
|
1068
|
+
}
|
|
1069
|
+
if (preventsDefaultUnlessDenied)
|
|
1070
|
+
event.preventDefault();
|
|
1071
|
+
onUp?.(toHookApi(api));
|
|
1072
|
+
};
|
|
1073
|
+
const recognize = (event, api) => {
|
|
1074
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1075
|
+
if (metadata.duration < minDuration) {
|
|
1076
|
+
denied();
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
recognized();
|
|
1080
|
+
};
|
|
1081
|
+
const visibilitychange = (event, api) => {
|
|
1082
|
+
if (document.visibilityState === "hidden") {
|
|
1083
|
+
statuses.clear();
|
|
1084
|
+
localStatus = "recognizing";
|
|
1085
|
+
cleanup();
|
|
1086
|
+
}
|
|
1087
|
+
onVisibilitychange?.(toHookApi(api));
|
|
1088
|
+
};
|
|
1089
|
+
return {
|
|
1090
|
+
keydown,
|
|
1091
|
+
keyup,
|
|
1092
|
+
visibilitychange
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
const unsupportedAliases$1 = ["meta", "command", "cmd"];
|
|
1096
|
+
const unsupportedKeys$1 = ["Meta"];
|
|
1097
|
+
|
|
1098
|
+
const defaultOptions$g = {
|
|
1099
|
+
minDuration: 0,
|
|
1100
|
+
maxInterval: 5e3,
|
|
1101
|
+
// VS Code default
|
|
1102
|
+
preventsDefaultUnlessDenied: true,
|
|
1103
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
1104
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
1105
|
+
};
|
|
1106
|
+
function createKeychord(keychord, options = {}) {
|
|
1107
|
+
const {
|
|
1108
|
+
minDuration,
|
|
1109
|
+
maxInterval,
|
|
1110
|
+
preventsDefaultUnlessDenied,
|
|
1111
|
+
toKey,
|
|
1112
|
+
toAliases,
|
|
1113
|
+
onDown,
|
|
1114
|
+
onUp,
|
|
1115
|
+
onVisibilitychange
|
|
1116
|
+
} = { ...defaultOptions$g, ...options }, narrowedKeychord = keychord.split(" "), keyStates = createMap((keycombo) => createKeyState({
|
|
1117
|
+
keycomboOrKeycombos: keycombo,
|
|
1118
|
+
unsupportedAliases,
|
|
1119
|
+
toKey,
|
|
1120
|
+
toAliases,
|
|
1121
|
+
getRequest: () => request
|
|
1122
|
+
}))(narrowedKeychord), localStatuses = createMap(
|
|
1123
|
+
() => "recognizing"
|
|
1124
|
+
)(keyStates);
|
|
1125
|
+
let request, playedIndex = 0;
|
|
1126
|
+
const keydown = (event, api) => {
|
|
1127
|
+
const { denied, getStatus } = api, key = fromEventToKeyStatusKey(event);
|
|
1128
|
+
if (keyStates[playedIndex].statuses.toValue(key) === "down") {
|
|
1129
|
+
onDown?.(toHookApi(api));
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
if (localStatuses[playedIndex] === "recognized") {
|
|
1133
|
+
playedIndex++;
|
|
1134
|
+
for (const [key2, status] of keyStates[playedIndex - 1].statuses.toEntries()) {
|
|
1135
|
+
keyStates[playedIndex].statuses.set(key2, status);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
keyStates[playedIndex].statuses.set(key, "down");
|
|
1139
|
+
if (localStatuses[playedIndex] === "denied") {
|
|
1140
|
+
denied();
|
|
1141
|
+
onDown?.(toHookApi(api));
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const { getMetadata } = api, metadata = getMetadata(), downCombos = keyStates[playedIndex].getDownCombos();
|
|
1145
|
+
if (playedIndex === 0)
|
|
1146
|
+
metadata.played = [];
|
|
1147
|
+
if (
|
|
1148
|
+
// NOT BUILDING VALID COMBO
|
|
1149
|
+
!keyStates[playedIndex].predicateValid(event) || downCombos.length > 1 && fromComboToAliasesLength(downCombos[0]) === fromComboToAliasesLength(downCombos[1]) || playedIndex > 0 && event.timeStamp - metadata.played[playedIndex - 1].times.end > maxInterval
|
|
1150
|
+
) {
|
|
1151
|
+
denied();
|
|
1152
|
+
localStatuses[playedIndex] = getStatus();
|
|
1153
|
+
if (includes(event.key)(unsupportedKeys)) {
|
|
1154
|
+
for (const { statuses } of keyStates)
|
|
1155
|
+
statuses.clear();
|
|
1156
|
+
}
|
|
1157
|
+
onDown?.(toHookApi(api));
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
if (preventsDefaultUnlessDenied)
|
|
1161
|
+
event.preventDefault();
|
|
1162
|
+
localStatuses[playedIndex] = "recognizing";
|
|
1163
|
+
keyStates[playedIndex].cleanup();
|
|
1164
|
+
storeKeyboardTimeMetadata({
|
|
1165
|
+
event,
|
|
1166
|
+
api,
|
|
1167
|
+
getTimeMetadata: () => {
|
|
1168
|
+
const metadata2 = getMetadata();
|
|
1169
|
+
return metadata2.played[playedIndex] || (metadata2.played[playedIndex] = {});
|
|
1170
|
+
},
|
|
1171
|
+
getShouldStore: () => downCombos.length && keyStates[playedIndex].getDownCombos()[0] === downCombos[0],
|
|
1172
|
+
setRequest: (newRequest) => request = newRequest
|
|
1173
|
+
});
|
|
1174
|
+
onDown?.(toHookApi(api));
|
|
1175
|
+
};
|
|
1176
|
+
const keyup = (event, api) => {
|
|
1177
|
+
const {
|
|
1178
|
+
getStatus,
|
|
1179
|
+
getMetadata,
|
|
1180
|
+
denied
|
|
1181
|
+
} = api, metadata = getMetadata(), key = fromEventToKeyStatusKey(event);
|
|
1182
|
+
if (["denied", "recognized"].includes(localStatuses[playedIndex])) {
|
|
1183
|
+
if (localStatuses[playedIndex] === "denied")
|
|
1184
|
+
denied();
|
|
1185
|
+
for (const { statuses } of keyStates) {
|
|
1186
|
+
if (includes(event.key)(unsupportedKeys))
|
|
1187
|
+
statuses.clear();
|
|
1188
|
+
else
|
|
1189
|
+
statuses.delete(key);
|
|
1190
|
+
}
|
|
1191
|
+
if (!predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
|
|
1192
|
+
if (localStatuses[playedIndex] === "denied" || playedIndex === narrowedKeychord.length - 1 && localStatuses[playedIndex] === "recognized") {
|
|
1193
|
+
playedIndex = 0;
|
|
1194
|
+
for (let i = 0; i < localStatuses.length; i++)
|
|
1195
|
+
localStatuses[i] = "recognizing";
|
|
1196
|
+
for (const { statuses } of keyStates)
|
|
1197
|
+
statuses.clear();
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
onUp?.(toHookApi(api));
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
const downCombos = keyStates[playedIndex].getDownCombos(), matches = keyStates[playedIndex].matchPredicatesByKeycombo[downCombos[0]]?.(keyStates[playedIndex].statuses);
|
|
1204
|
+
keyStates[playedIndex].statuses.delete(key);
|
|
1205
|
+
if (!downCombos.length || !matches) {
|
|
1206
|
+
onUp?.(toHookApi(api));
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
recognize(event, api);
|
|
1210
|
+
const status = getStatus();
|
|
1211
|
+
if (status === "recognizing" && localStatuses[playedIndex] === "recognized" || status === "recognized") {
|
|
1212
|
+
metadata.played[playedIndex] = {
|
|
1213
|
+
...metadata.played[playedIndex],
|
|
1214
|
+
released: downCombos[0]
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
if (preventsDefaultUnlessDenied)
|
|
1218
|
+
event.preventDefault();
|
|
1219
|
+
if (playedIndex === narrowedKeychord.length - 1 && !predicateSomeKeyDown(keyStates[playedIndex].statuses)) {
|
|
1220
|
+
playedIndex = 0;
|
|
1221
|
+
for (let i = 0; i < localStatuses.length; i++)
|
|
1222
|
+
localStatuses[i] = "recognizing";
|
|
1223
|
+
for (const { statuses } of keyStates)
|
|
1224
|
+
statuses.clear();
|
|
1225
|
+
}
|
|
1226
|
+
onUp?.(toHookApi(api));
|
|
1227
|
+
};
|
|
1228
|
+
const recognize = (event, api) => {
|
|
1229
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1230
|
+
if (metadata.played[playedIndex].duration < minDuration) {
|
|
1231
|
+
denied();
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
if (playedIndex === narrowedKeychord.length - 1) {
|
|
1235
|
+
recognized();
|
|
1236
|
+
localStatuses[playedIndex] = "recognized";
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
localStatuses[playedIndex] = "recognized";
|
|
1240
|
+
};
|
|
1241
|
+
const visibilitychange = (event, api) => {
|
|
1242
|
+
if (document.visibilityState === "hidden") {
|
|
1243
|
+
for (const { statuses } of keyStates)
|
|
1244
|
+
statuses.clear();
|
|
1245
|
+
localStatuses[playedIndex] = "recognizing";
|
|
1246
|
+
keyStates[playedIndex].cleanup();
|
|
1247
|
+
playedIndex = 0;
|
|
1248
|
+
}
|
|
1249
|
+
onVisibilitychange?.(toHookApi(api));
|
|
1250
|
+
};
|
|
1251
|
+
return {
|
|
1252
|
+
keydown,
|
|
1253
|
+
keyup,
|
|
1254
|
+
visibilitychange
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
const unsupportedAliases = ["meta", "command", "cmd"];
|
|
1258
|
+
const unsupportedKeys = ["Meta"];
|
|
1259
|
+
|
|
1260
|
+
const defaultOptions$f = {
|
|
1261
|
+
minDuration: 0,
|
|
1262
|
+
minDistance: 0,
|
|
1263
|
+
getMousemoveTarget: (event) => event.target
|
|
1264
|
+
};
|
|
1265
|
+
function createMousepress(options = {}) {
|
|
1266
|
+
const {
|
|
1267
|
+
minDuration,
|
|
1268
|
+
minDistance,
|
|
1269
|
+
getMousemoveTarget,
|
|
1270
|
+
onDown,
|
|
1271
|
+
onLeave,
|
|
1272
|
+
onMove,
|
|
1273
|
+
onUp
|
|
1274
|
+
} = { ...defaultOptions$f, ...options }, cleanup = (event) => {
|
|
1275
|
+
window.cancelAnimationFrame(request);
|
|
1276
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1277
|
+
};
|
|
1278
|
+
let request;
|
|
1279
|
+
let mousemoveEffect;
|
|
1280
|
+
let mouseStatus;
|
|
1281
|
+
const mousedown = (event, api) => {
|
|
1282
|
+
mouseStatus = "down";
|
|
1283
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1284
|
+
storePointerStartMetadata(event, api);
|
|
1285
|
+
storePointerMoveMetadata(event, api);
|
|
1286
|
+
storePointerTimeMetadata(
|
|
1287
|
+
event,
|
|
1288
|
+
api,
|
|
1289
|
+
() => mouseStatus === "down",
|
|
1290
|
+
(newRequest) => request = newRequest,
|
|
1291
|
+
recognize
|
|
1292
|
+
);
|
|
1293
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1294
|
+
onDown?.(toHookApi(api));
|
|
1295
|
+
};
|
|
1296
|
+
const mousemove = (event, api) => {
|
|
1297
|
+
storePointerMoveMetadata(event, api);
|
|
1298
|
+
recognize(event, api);
|
|
1299
|
+
onMove?.(toHookApi(api));
|
|
1300
|
+
};
|
|
1301
|
+
const recognize = (event, api) => {
|
|
1302
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1303
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1304
|
+
recognized();
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
const mouseleave = (event, api) => {
|
|
1308
|
+
const { denied } = api;
|
|
1309
|
+
if (mouseStatus === "down") {
|
|
1310
|
+
denied();
|
|
1311
|
+
cleanup(event);
|
|
1312
|
+
mouseStatus = "leave";
|
|
1313
|
+
}
|
|
1314
|
+
onLeave?.(toHookApi(api));
|
|
1315
|
+
};
|
|
1316
|
+
const mouseup = (event, api) => {
|
|
1317
|
+
const { denied } = api;
|
|
1318
|
+
if (mouseStatus !== "down")
|
|
1319
|
+
return;
|
|
1320
|
+
denied();
|
|
1321
|
+
cleanup(event);
|
|
1322
|
+
mouseStatus = "up";
|
|
1323
|
+
onUp?.(toHookApi(api));
|
|
1324
|
+
};
|
|
1325
|
+
return {
|
|
1326
|
+
mousedown,
|
|
1327
|
+
mouseleave,
|
|
1328
|
+
mouseup
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
const defaultOptions$e = {
|
|
1333
|
+
minDuration: 0,
|
|
1334
|
+
minDistance: 0,
|
|
1335
|
+
minVelocity: 0,
|
|
1336
|
+
getMousemoveTarget: (event) => event.target
|
|
1337
|
+
};
|
|
1338
|
+
function createMouserelease(options = {}) {
|
|
1339
|
+
const {
|
|
1340
|
+
minDuration,
|
|
1341
|
+
minDistance,
|
|
1342
|
+
minVelocity,
|
|
1343
|
+
getMousemoveTarget,
|
|
1344
|
+
onDown,
|
|
1345
|
+
onLeave,
|
|
1346
|
+
onMove,
|
|
1347
|
+
onUp
|
|
1348
|
+
} = { ...defaultOptions$e, ...options }, cleanup = (event) => {
|
|
1349
|
+
window.cancelAnimationFrame(request);
|
|
1350
|
+
getMousemoveTarget(event).removeEventListener("mousemove", mousemoveEffect);
|
|
1351
|
+
};
|
|
1352
|
+
let request;
|
|
1353
|
+
let mousemoveEffect;
|
|
1354
|
+
let mouseStatus;
|
|
1355
|
+
const mousedown = (event, api) => {
|
|
1356
|
+
mouseStatus = "down";
|
|
1357
|
+
mousemoveEffect = (event2) => mousemove(event2, api);
|
|
1358
|
+
storePointerStartMetadata(event, api);
|
|
1359
|
+
storePointerMoveMetadata(event, api);
|
|
1360
|
+
storePointerTimeMetadata(
|
|
1361
|
+
event,
|
|
1362
|
+
api,
|
|
1363
|
+
() => mouseStatus === "down",
|
|
1364
|
+
(newRequest) => request = newRequest
|
|
1365
|
+
);
|
|
1366
|
+
getMousemoveTarget(event).addEventListener("mousemove", mousemoveEffect);
|
|
1367
|
+
onDown?.(toHookApi(api));
|
|
1368
|
+
};
|
|
1369
|
+
const mousemove = (event, api) => {
|
|
1370
|
+
storePointerMoveMetadata(event, api);
|
|
1371
|
+
onMove?.(toHookApi(api));
|
|
1372
|
+
};
|
|
1373
|
+
const mouseleave = (event, api) => {
|
|
1374
|
+
const { denied } = api;
|
|
1375
|
+
if (mouseStatus === "down") {
|
|
1376
|
+
denied();
|
|
1377
|
+
cleanup(event);
|
|
1378
|
+
mouseStatus = "leave";
|
|
1379
|
+
}
|
|
1380
|
+
onLeave?.(toHookApi(api));
|
|
1381
|
+
};
|
|
1382
|
+
const mouseup = (event, api) => {
|
|
1383
|
+
if (mouseStatus !== "down")
|
|
1384
|
+
return;
|
|
1385
|
+
storePointerMoveMetadata(event, api);
|
|
1386
|
+
cleanup(event);
|
|
1387
|
+
mouseStatus = "up";
|
|
1388
|
+
recognize(event, api);
|
|
1389
|
+
onUp?.(toHookApi(api));
|
|
1390
|
+
};
|
|
1391
|
+
const recognize = (event, api) => {
|
|
1392
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1393
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1394
|
+
recognized();
|
|
1395
|
+
} else {
|
|
1396
|
+
denied();
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
return {
|
|
1400
|
+
mousedown,
|
|
1401
|
+
mouseleave,
|
|
1402
|
+
mouseup
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
const defaultOptions$d = {
|
|
1407
|
+
minDuration: 0,
|
|
1408
|
+
minDistance: 0
|
|
1409
|
+
};
|
|
1410
|
+
function createTouchpress(options = {}) {
|
|
1411
|
+
const {
|
|
1412
|
+
minDuration,
|
|
1413
|
+
minDistance,
|
|
1414
|
+
onStart,
|
|
1415
|
+
onCancel,
|
|
1416
|
+
onMove,
|
|
1417
|
+
onEnd
|
|
1418
|
+
} = { ...defaultOptions$d, ...options }, cleanup = () => {
|
|
1419
|
+
window.cancelAnimationFrame(request);
|
|
1420
|
+
};
|
|
1421
|
+
let request;
|
|
1422
|
+
let totalTouches = 0;
|
|
1423
|
+
const touchstart = (event, api) => {
|
|
1424
|
+
const { denied } = api;
|
|
1425
|
+
totalTouches++;
|
|
1426
|
+
if (totalTouches > 1) {
|
|
1427
|
+
cleanup();
|
|
1428
|
+
denied();
|
|
1429
|
+
onStart?.(toHookApi(api));
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
storePointerStartMetadata(event, api);
|
|
1433
|
+
storePointerMoveMetadata(event, api);
|
|
1434
|
+
storePointerTimeMetadata(
|
|
1435
|
+
event,
|
|
1436
|
+
api,
|
|
1437
|
+
() => totalTouches === 1,
|
|
1438
|
+
(newRequest) => request = newRequest,
|
|
1439
|
+
recognize
|
|
1440
|
+
);
|
|
1441
|
+
onStart?.(toHookApi(api));
|
|
1442
|
+
};
|
|
1443
|
+
const touchmove = (event, api) => {
|
|
1444
|
+
const { getStatus } = api;
|
|
1445
|
+
if (getStatus() !== "denied") {
|
|
1446
|
+
storePointerMoveMetadata(event, api);
|
|
1447
|
+
recognize(event, api);
|
|
1448
|
+
}
|
|
1449
|
+
onMove?.(toHookApi(api));
|
|
1450
|
+
};
|
|
1451
|
+
const recognize = (event, api) => {
|
|
1452
|
+
const { getMetadata, recognized } = api, metadata = getMetadata();
|
|
1453
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance) {
|
|
1454
|
+
recognized();
|
|
1455
|
+
}
|
|
1456
|
+
};
|
|
1457
|
+
const touchcancel = (event, api) => {
|
|
1458
|
+
const { denied } = api;
|
|
1459
|
+
cleanup();
|
|
1460
|
+
denied();
|
|
1461
|
+
totalTouches--;
|
|
1462
|
+
onCancel?.(toHookApi(api));
|
|
1463
|
+
};
|
|
1464
|
+
const touchend = (event, api) => {
|
|
1465
|
+
const { denied } = api;
|
|
1466
|
+
cleanup();
|
|
1467
|
+
denied();
|
|
1468
|
+
totalTouches--;
|
|
1469
|
+
onEnd?.(toHookApi(api));
|
|
1470
|
+
};
|
|
1471
|
+
return {
|
|
1472
|
+
touchstart,
|
|
1473
|
+
touchmove,
|
|
1474
|
+
touchcancel,
|
|
1475
|
+
touchend
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
const defaultOptions$c = {
|
|
1480
|
+
minDuration: 0,
|
|
1481
|
+
minDistance: 0,
|
|
1482
|
+
minVelocity: 0
|
|
1483
|
+
};
|
|
1484
|
+
function createTouchrelease(options = {}) {
|
|
1485
|
+
const {
|
|
1486
|
+
minDuration,
|
|
1487
|
+
minDistance,
|
|
1488
|
+
minVelocity,
|
|
1489
|
+
onStart,
|
|
1490
|
+
onCancel,
|
|
1491
|
+
onMove,
|
|
1492
|
+
onEnd
|
|
1493
|
+
} = { ...defaultOptions$c, ...options }, cleanup = () => {
|
|
1494
|
+
window.cancelAnimationFrame(request);
|
|
1495
|
+
};
|
|
1496
|
+
let request;
|
|
1497
|
+
let totalTouches = 0;
|
|
1498
|
+
const touchstart = (event, api) => {
|
|
1499
|
+
const { denied } = api;
|
|
1500
|
+
totalTouches++;
|
|
1501
|
+
if (totalTouches > 1) {
|
|
1502
|
+
cleanup();
|
|
1503
|
+
denied();
|
|
1504
|
+
onStart?.(toHookApi(api));
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
storePointerStartMetadata(event, api);
|
|
1508
|
+
storePointerMoveMetadata(event, api);
|
|
1509
|
+
storePointerTimeMetadata(
|
|
1510
|
+
event,
|
|
1511
|
+
api,
|
|
1512
|
+
() => totalTouches === 1,
|
|
1513
|
+
(newRequest) => request = newRequest
|
|
1514
|
+
);
|
|
1515
|
+
onStart?.(toHookApi(api));
|
|
1516
|
+
};
|
|
1517
|
+
const touchmove = (event, api) => {
|
|
1518
|
+
const { getStatus } = api;
|
|
1519
|
+
if (getStatus() !== "denied")
|
|
1520
|
+
storePointerMoveMetadata(event, api);
|
|
1521
|
+
onMove?.(toHookApi(api));
|
|
1522
|
+
};
|
|
1523
|
+
const touchcancel = (event, api) => {
|
|
1524
|
+
const { denied } = api;
|
|
1525
|
+
cleanup();
|
|
1526
|
+
denied();
|
|
1527
|
+
totalTouches--;
|
|
1528
|
+
onCancel?.(toHookApi(api));
|
|
1529
|
+
};
|
|
1530
|
+
const touchend = (event, api) => {
|
|
1531
|
+
const { denied } = api;
|
|
1532
|
+
if (totalTouches !== 1) {
|
|
1533
|
+
cleanup();
|
|
1534
|
+
denied();
|
|
1535
|
+
onEnd?.(toHookApi(api));
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
storePointerMoveMetadata(event, api);
|
|
1539
|
+
cleanup();
|
|
1540
|
+
totalTouches--;
|
|
1541
|
+
recognize(event, api);
|
|
1542
|
+
onEnd?.(toHookApi(api));
|
|
1543
|
+
};
|
|
1544
|
+
const recognize = (event, api) => {
|
|
1545
|
+
const { getMetadata, recognized, denied } = api, metadata = getMetadata();
|
|
1546
|
+
if (metadata.duration >= minDuration && metadata.distance.straight.fromStart >= minDistance && metadata.velocity >= minVelocity) {
|
|
1547
|
+
recognized();
|
|
1548
|
+
} else {
|
|
1549
|
+
denied();
|
|
1550
|
+
}
|
|
1551
|
+
};
|
|
1552
|
+
return {
|
|
1553
|
+
touchstart,
|
|
1554
|
+
touchmove,
|
|
1555
|
+
touchcancel,
|
|
1556
|
+
touchend
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
const defaultOptions$b = {
|
|
1561
|
+
initial: []
|
|
1562
|
+
};
|
|
1563
|
+
function createKeyStatuses(options = {}) {
|
|
1564
|
+
return createAssociativeArray({
|
|
1565
|
+
...defaultOptions$b,
|
|
1566
|
+
...options,
|
|
1567
|
+
createPredicateKey: (query) => (key) => {
|
|
1568
|
+
for (const prop in query) {
|
|
1569
|
+
if (query[prop] !== key[prop]) {
|
|
1570
|
+
return false;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
return true;
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
function predicateDown(status) {
|
|
1578
|
+
return status === "down";
|
|
1579
|
+
}
|
|
1580
|
+
function predicateSomeKeyDown(statuses) {
|
|
1581
|
+
return includes("down")(statuses.toValues());
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
function fromComboToAliases(combo) {
|
|
1585
|
+
const delimiter = "+";
|
|
1586
|
+
return pipe(
|
|
1587
|
+
unique(),
|
|
1588
|
+
map((name) => name === "" ? delimiter : name.toLowerCase()),
|
|
1589
|
+
toArray()
|
|
1590
|
+
)(combo.split(delimiter));
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
function fromAliasToKeyStatusKey(alias) {
|
|
1594
|
+
if (alias in keysByAlias) {
|
|
1595
|
+
return { key: keysByAlias[alias] };
|
|
1596
|
+
}
|
|
1597
|
+
return {
|
|
1598
|
+
code: (() => {
|
|
1599
|
+
if (alias in codesByAlias)
|
|
1600
|
+
return codesByAlias[alias];
|
|
1601
|
+
if (letterRE.test(alias))
|
|
1602
|
+
return `Key${alias.toUpperCase()}`;
|
|
1603
|
+
if (digitRE.test(alias))
|
|
1604
|
+
return `Digit${alias}`;
|
|
1605
|
+
if (functionRE.test(alias))
|
|
1606
|
+
return alias.toUpperCase();
|
|
1607
|
+
return "unsupported";
|
|
1608
|
+
})()
|
|
1609
|
+
};
|
|
1610
|
+
}
|
|
1611
|
+
const digitRE = /^[0-9]$/;
|
|
1612
|
+
const letterRE = /^[a-zA-Z]$/;
|
|
1613
|
+
const functionRE = /^[fF][0-9]{1,2}$/;
|
|
1614
|
+
const codesByAlias = {
|
|
1615
|
+
"`": "Backquote",
|
|
1616
|
+
"~": "Backquote",
|
|
1617
|
+
"-": "Minus",
|
|
1618
|
+
_: "Minus",
|
|
1619
|
+
"=": "Equal",
|
|
1620
|
+
"+": "Equal",
|
|
1621
|
+
"[": "BracketLeft",
|
|
1622
|
+
"{": "BracketLeft",
|
|
1623
|
+
"]": "BracketRight",
|
|
1624
|
+
"}": "BracketRight",
|
|
1625
|
+
"\\": "Backslash",
|
|
1626
|
+
"|": "Backslash",
|
|
1627
|
+
";": "Semicolon",
|
|
1628
|
+
":": "Semicolon",
|
|
1629
|
+
"'": "Quote",
|
|
1630
|
+
'"': "Quote",
|
|
1631
|
+
",": "Comma",
|
|
1632
|
+
"<": "Comma",
|
|
1633
|
+
".": "Period",
|
|
1634
|
+
">": "Period",
|
|
1635
|
+
"/": "Slash",
|
|
1636
|
+
"?": "Slash",
|
|
1637
|
+
"!": "Digit1",
|
|
1638
|
+
"@": "Digit2",
|
|
1639
|
+
"#": "Digit3",
|
|
1640
|
+
$: "Digit4",
|
|
1641
|
+
"%": "Digit5",
|
|
1642
|
+
"^": "Digit6",
|
|
1643
|
+
"&": "Digit7",
|
|
1644
|
+
"*": "Digit8",
|
|
1645
|
+
"(": "Digit9",
|
|
1646
|
+
")": "Digit0",
|
|
1647
|
+
up: "ArrowUp",
|
|
1648
|
+
down: "ArrowDown",
|
|
1649
|
+
left: "ArrowLeft",
|
|
1650
|
+
right: "ArrowRight",
|
|
1651
|
+
enter: "Enter",
|
|
1652
|
+
space: "Space",
|
|
1653
|
+
tab: "Tab",
|
|
1654
|
+
esc: "Escape",
|
|
1655
|
+
backspace: "Backspace",
|
|
1656
|
+
delete: "Delete",
|
|
1657
|
+
home: "Home",
|
|
1658
|
+
end: "End",
|
|
1659
|
+
pagedown: "PageDown",
|
|
1660
|
+
pageup: "PageUp",
|
|
1661
|
+
capslock: "CapsLock",
|
|
1662
|
+
camera: "Camera"
|
|
1663
|
+
};
|
|
1664
|
+
const keysByAlias = {
|
|
1665
|
+
alt: "Alt",
|
|
1666
|
+
opt: "Alt",
|
|
1667
|
+
option: "Alt",
|
|
1668
|
+
ctrl: "Control",
|
|
1669
|
+
control: "Control",
|
|
1670
|
+
meta: "Meta",
|
|
1671
|
+
cmd: "Meta",
|
|
1672
|
+
command: "Meta",
|
|
1673
|
+
shift: "Shift"
|
|
1674
|
+
};
|
|
1675
|
+
|
|
1676
|
+
const defaultOptions$a = {
|
|
1677
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias)
|
|
1678
|
+
};
|
|
1679
|
+
const createPredicateKeycomboDown = (keycombo, options = {}) => {
|
|
1680
|
+
const { toKey } = { ...defaultOptions$a, ...options }, keys = pipe(
|
|
1681
|
+
fromComboToAliases,
|
|
1682
|
+
map(toKey)
|
|
1683
|
+
)(keycombo);
|
|
1684
|
+
return (statuses) => {
|
|
1685
|
+
const { toValue } = statuses;
|
|
1686
|
+
return every(pipe(
|
|
1687
|
+
toValue,
|
|
1688
|
+
predicateDown
|
|
1689
|
+
))(keys);
|
|
1690
|
+
};
|
|
1691
|
+
};
|
|
1692
|
+
|
|
1693
|
+
function fromEventToAliases(event) {
|
|
1694
|
+
if (event.shiftKey && event.code in aliasesByShiftCode) {
|
|
1695
|
+
return [aliasesByShiftCode[event.code]];
|
|
1696
|
+
}
|
|
1697
|
+
if (event.key in aliasListsByModifier) {
|
|
1698
|
+
return aliasListsByModifier[event.key];
|
|
1699
|
+
}
|
|
1700
|
+
return event.code in aliasesByCode ? [aliasesByCode[event.code]] : [event.code.match(aliasCaptureRE)?.[1].toLowerCase() || "unsupported"];
|
|
1701
|
+
}
|
|
1702
|
+
const aliasCaptureRE = /^(?:Digit|Key)?(F[0-9]{1,2}|[0-9]|[A-Z])$/;
|
|
1703
|
+
const aliasesByCode = {
|
|
1704
|
+
Backquote: "`",
|
|
1705
|
+
Minus: "-",
|
|
1706
|
+
Equal: "=",
|
|
1707
|
+
BracketLeft: "[",
|
|
1708
|
+
BracketRight: "]",
|
|
1709
|
+
Backslash: "\\",
|
|
1710
|
+
Semicolon: ";",
|
|
1711
|
+
Quote: "'",
|
|
1712
|
+
Comma: ",",
|
|
1713
|
+
Period: ".",
|
|
1714
|
+
Slash: "/",
|
|
1715
|
+
ArrowUp: "up",
|
|
1716
|
+
ArrowDown: "down",
|
|
1717
|
+
ArrowLeft: "left",
|
|
1718
|
+
ArrowRight: "right",
|
|
1719
|
+
Enter: "enter",
|
|
1720
|
+
Space: "space",
|
|
1721
|
+
Tab: "tab",
|
|
1722
|
+
Escape: "esc",
|
|
1723
|
+
Backspace: "backspace",
|
|
1724
|
+
Delete: "delete",
|
|
1725
|
+
Home: "home",
|
|
1726
|
+
End: "end",
|
|
1727
|
+
PageDown: "pagedown",
|
|
1728
|
+
PageUp: "pageup",
|
|
1729
|
+
CapsLock: "capslock",
|
|
1730
|
+
Camera: "camera"
|
|
1731
|
+
};
|
|
1732
|
+
const aliasesByShiftCode = {
|
|
1733
|
+
Backquote: "~",
|
|
1734
|
+
Minus: "_",
|
|
1735
|
+
Equal: "+",
|
|
1736
|
+
BracketLeft: "{",
|
|
1737
|
+
BracketRight: "}",
|
|
1738
|
+
Backslash: "|",
|
|
1739
|
+
Semicolon: ":",
|
|
1740
|
+
Quote: '"',
|
|
1741
|
+
Comma: "<",
|
|
1742
|
+
Period: ">",
|
|
1743
|
+
Slash: "?",
|
|
1744
|
+
Digit1: "!",
|
|
1745
|
+
Digit2: "@",
|
|
1746
|
+
Digit3: "#",
|
|
1747
|
+
Digit4: "$",
|
|
1748
|
+
Digit5: "%",
|
|
1749
|
+
Digit6: "^",
|
|
1750
|
+
Digit7: "&",
|
|
1751
|
+
Digit8: "*",
|
|
1752
|
+
Digit9: "(",
|
|
1753
|
+
Digit0: ")"
|
|
1754
|
+
};
|
|
1755
|
+
const aliasListsByModifier = {
|
|
1756
|
+
Alt: ["alt", "option", "opt"],
|
|
1757
|
+
Control: ["control", "ctrl"],
|
|
1758
|
+
Meta: ["meta", "command", "cmd"],
|
|
1759
|
+
Shift: ["shift"]
|
|
1760
|
+
};
|
|
1761
|
+
|
|
1762
|
+
const defaultOptions$9 = {
|
|
1763
|
+
toKey: (alias) => fromAliasToKeyStatusKey(alias),
|
|
1764
|
+
toAliases: (event) => fromEventToAliases(event)
|
|
1765
|
+
};
|
|
1766
|
+
const createPredicateKeycomboMatch = (keycombo, options = {}) => {
|
|
1767
|
+
const { toKey, toAliases } = { ...defaultOptions$9, ...options }, aliases = fromComboToAliases(keycombo), keys = map(toKey)(aliases);
|
|
1768
|
+
return (statuses) => {
|
|
1769
|
+
const { toValue } = statuses;
|
|
1770
|
+
return every(pipe(
|
|
1771
|
+
toValue,
|
|
1772
|
+
predicateDown
|
|
1773
|
+
))(keys) && every(
|
|
1774
|
+
([key, value]) => value === "up" || some(
|
|
1775
|
+
(alias) => includes(alias)(aliases)
|
|
1776
|
+
)(toAliases(key))
|
|
1777
|
+
)(statuses.toEntries());
|
|
1778
|
+
};
|
|
1779
|
+
};
|
|
1780
|
+
|
|
1781
|
+
function createKeyState({
|
|
1782
|
+
keycomboOrKeycombos,
|
|
1783
|
+
unsupportedAliases,
|
|
1784
|
+
toKey,
|
|
1785
|
+
toAliases,
|
|
1786
|
+
getRequest
|
|
1787
|
+
}) {
|
|
1788
|
+
const narrowedKeycombos = createFilter(
|
|
1789
|
+
(keycombo) => !some(
|
|
1790
|
+
(alias) => includes(alias)(unsupportedAliases)
|
|
1791
|
+
)(fromComboToAliases(keycombo))
|
|
1792
|
+
)(Array.isArray(keycomboOrKeycombos) ? keycomboOrKeycombos : [keycomboOrKeycombos]), createPredicateKeycomboDownOptions = { toKey }, downPredicatesByKeycombo = (() => {
|
|
1793
|
+
const predicates = [];
|
|
1794
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1795
|
+
predicates.push([
|
|
1796
|
+
keycombo,
|
|
1797
|
+
createPredicateKeycomboDown(
|
|
1798
|
+
keycombo,
|
|
1799
|
+
createPredicateKeycomboDownOptions
|
|
1800
|
+
)
|
|
1801
|
+
]);
|
|
1802
|
+
}
|
|
1803
|
+
return predicates;
|
|
1804
|
+
})(), createPredicateKeycomboMatchOptions = { ...createPredicateKeycomboDownOptions, toAliases }, matchPredicatesByKeycombo = (() => {
|
|
1805
|
+
const predicates = {};
|
|
1806
|
+
for (const keycombo of narrowedKeycombos) {
|
|
1807
|
+
predicates[keycombo] = createPredicateKeycomboMatch(
|
|
1808
|
+
keycombo,
|
|
1809
|
+
createPredicateKeycomboMatchOptions
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
return predicates;
|
|
1813
|
+
})(), validAliases = pipe(
|
|
1814
|
+
flatMap(fromComboToAliases),
|
|
1815
|
+
unique(),
|
|
151
1816
|
toArray()
|
|
152
|
-
)(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
1817
|
+
)(narrowedKeycombos), getDownCombos = () => pipe(
|
|
1818
|
+
filter(([, predicate]) => predicate(statuses)),
|
|
1819
|
+
map(([keycombo]) => [keycombo, fromComboToAliases(keycombo)]),
|
|
1820
|
+
sort(([, aliasesA], [, aliasesB]) => aliasesB.length - aliasesA.length),
|
|
1821
|
+
map(([keycombo]) => keycombo),
|
|
157
1822
|
toArray()
|
|
158
|
-
)()
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
1823
|
+
)(downPredicatesByKeycombo), predicateValid = (event) => {
|
|
1824
|
+
const aliases = toAliases(event);
|
|
1825
|
+
return some(
|
|
1826
|
+
(validAlias) => includes(validAlias)(aliases)
|
|
1827
|
+
)(validAliases);
|
|
1828
|
+
}, cleanup = () => {
|
|
1829
|
+
window.cancelAnimationFrame(getRequest());
|
|
1830
|
+
}, statuses = createKeyStatuses();
|
|
1831
|
+
return {
|
|
1832
|
+
narrowedKeycombos,
|
|
1833
|
+
createPredicateKeycomboDownOptions,
|
|
1834
|
+
downPredicatesByKeycombo,
|
|
1835
|
+
createPredicateKeycomboMatchOptions,
|
|
1836
|
+
matchPredicatesByKeycombo,
|
|
1837
|
+
validAliases,
|
|
1838
|
+
getDownCombos,
|
|
1839
|
+
predicateValid,
|
|
1840
|
+
cleanup,
|
|
1841
|
+
statuses
|
|
167
1842
|
};
|
|
168
1843
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
(sliced) => compare ? sliced.sort(compare) : sliced.sort()
|
|
174
|
-
);
|
|
1844
|
+
|
|
1845
|
+
function toLength() {
|
|
1846
|
+
return function toLengthFn(data) {
|
|
1847
|
+
return [...data].length;
|
|
175
1848
|
};
|
|
176
1849
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
1850
|
+
|
|
1851
|
+
const fromComboToAliasesLength = pipe(
|
|
1852
|
+
fromComboToAliases,
|
|
1853
|
+
toLength()
|
|
1854
|
+
);
|
|
1855
|
+
|
|
1856
|
+
function fromEventToKeyStatusKey({ key, code }) {
|
|
1857
|
+
return includes(key)(modifiers) ? { key } : { code };
|
|
1858
|
+
}
|
|
1859
|
+
const modifiers = ["Alt", "Control", "Meta", "Shift"];
|
|
1860
|
+
|
|
1861
|
+
function toDirection(angle, unit = "degrees") {
|
|
1862
|
+
return Object.keys(directions).find((direction) => directions[direction][unit](angle));
|
|
1863
|
+
}
|
|
1864
|
+
const directions = {
|
|
1865
|
+
up: {
|
|
1866
|
+
degrees: (degrees) => degrees >= 67.5 && degrees <= 112.5,
|
|
1867
|
+
radians: (radians) => radians >= 0.375 * Math.PI && radians <= 0.625 * Math.PI
|
|
1868
|
+
},
|
|
1869
|
+
upRight: {
|
|
1870
|
+
degrees: (degrees) => degrees >= 22.5 && degrees < 67.5,
|
|
1871
|
+
radians: (radians) => radians >= 0.125 * Math.PI && radians < 0.375 * Math.PI
|
|
1872
|
+
},
|
|
1873
|
+
right: {
|
|
1874
|
+
degrees: (degrees) => degrees > 337.5 && degrees <= 360 || degrees < 22.5 && degrees >= 0,
|
|
1875
|
+
radians: (radians) => radians > 1.875 * Math.PI && radians <= 2 * Math.PI || radians < 0.125 * Math.PI && radians >= 0
|
|
1876
|
+
},
|
|
1877
|
+
downRight: {
|
|
1878
|
+
degrees: (degrees) => degrees > 292.5 && degrees <= 337.5,
|
|
1879
|
+
radians: (radians) => radians > 1.625 * Math.PI && radians <= 1.875 * Math.PI
|
|
1880
|
+
},
|
|
1881
|
+
down: {
|
|
1882
|
+
degrees: (degrees) => degrees >= 247.5 && degrees <= 292.5,
|
|
1883
|
+
radians: (radians) => radians >= 1.375 * Math.PI && radians <= 1.625 * Math.PI
|
|
1884
|
+
},
|
|
1885
|
+
downLeft: {
|
|
1886
|
+
degrees: (degrees) => degrees >= 202.5 && degrees < 247.5,
|
|
1887
|
+
radians: (radians) => radians >= 1.125 * Math.PI && radians < 1.375 * Math.PI
|
|
1888
|
+
},
|
|
1889
|
+
left: {
|
|
1890
|
+
degrees: (degrees) => degrees > 157.5 && degrees < 202.5,
|
|
1891
|
+
radians: (radians) => radians > 0.875 * Math.PI && radians < 1.125 * Math.PI
|
|
1892
|
+
},
|
|
1893
|
+
upLeft: {
|
|
1894
|
+
degrees: (degrees) => degrees > 112.5 && degrees <= 157.5,
|
|
1895
|
+
radians: (radians) => radians > 0.625 * Math.PI && radians <= 0.875 * Math.PI
|
|
1896
|
+
}
|
|
1897
|
+
};
|
|
1898
|
+
|
|
1899
|
+
function toHookApi({
|
|
1900
|
+
getSequence,
|
|
1901
|
+
getStatus,
|
|
1902
|
+
getMetadata
|
|
1903
|
+
}) {
|
|
1904
|
+
return {
|
|
1905
|
+
sequence: getSequence(),
|
|
1906
|
+
status: getStatus(),
|
|
1907
|
+
metadata: getMetadata()
|
|
180
1908
|
};
|
|
181
1909
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
1910
|
+
|
|
1911
|
+
function toMousePoint(event) {
|
|
1912
|
+
return {
|
|
1913
|
+
x: event.clientX,
|
|
1914
|
+
y: event.clientY
|
|
185
1915
|
};
|
|
186
1916
|
}
|
|
187
|
-
function
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
|
|
1917
|
+
function toTouchMovePoint(event) {
|
|
1918
|
+
return {
|
|
1919
|
+
x: event.touches.item(0).clientX,
|
|
1920
|
+
y: event.touches.item(0).clientY
|
|
191
1921
|
};
|
|
192
1922
|
}
|
|
193
|
-
function
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
)(potentialities), upperBound = lowerBound + probability;
|
|
199
|
-
return {
|
|
200
|
-
outcome,
|
|
201
|
-
predicate: (determinant) => determinant >= lowerBound && determinant < upperBound || determinant < 0 && index === 0 || index === predicates.length - 1
|
|
202
|
-
};
|
|
203
|
-
})(potentialities);
|
|
204
|
-
return (determinant) => find(({ predicate }) => predicate(determinant))(predicates).outcome;
|
|
1923
|
+
function toTouchEndPoint(event) {
|
|
1924
|
+
return {
|
|
1925
|
+
x: event.changedTouches.item(0).clientX,
|
|
1926
|
+
y: event.changedTouches.item(0).clientY
|
|
1927
|
+
};
|
|
205
1928
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
1929
|
+
|
|
1930
|
+
function toPolarCoordinates({ xA, xB, yA, yB }) {
|
|
1931
|
+
const distance = Math.hypot(xB - xA, yB - yA), angle = Math.atan2(yA - yB, xB - xA), radians = angle >= 0 ? angle : 2 * Math.PI + angle, degrees = radians * 180 / Math.PI;
|
|
1932
|
+
return {
|
|
1933
|
+
distance,
|
|
1934
|
+
angle: { radians, degrees }
|
|
210
1935
|
};
|
|
211
1936
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
1937
|
+
|
|
1938
|
+
const initialMetadata$3 = {
|
|
1939
|
+
times: {
|
|
1940
|
+
start: 0,
|
|
1941
|
+
end: 0
|
|
1942
|
+
},
|
|
1943
|
+
duration: 0
|
|
1944
|
+
};
|
|
1945
|
+
function storeKeyboardTimeMetadata({
|
|
1946
|
+
event,
|
|
1947
|
+
api,
|
|
1948
|
+
getTimeMetadata,
|
|
1949
|
+
getShouldStore,
|
|
1950
|
+
setRequest,
|
|
1951
|
+
recognize
|
|
1952
|
+
}) {
|
|
1953
|
+
if (!getShouldStore())
|
|
1954
|
+
return;
|
|
1955
|
+
const { getStatus, onRecognized } = api, timeMetadata = getTimeMetadata();
|
|
1956
|
+
if (!timeMetadata.times)
|
|
1957
|
+
timeMetadata.times = createClone()(initialMetadata$3.times);
|
|
1958
|
+
timeMetadata.times.start = Math.round(event.timeStamp);
|
|
1959
|
+
timeMetadata.times.end = Math.round(event.timeStamp);
|
|
1960
|
+
const storeDuration = () => {
|
|
1961
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
1962
|
+
if (!getShouldStore())
|
|
1963
|
+
return;
|
|
1964
|
+
timeMetadata.times.end = Math.round(timestamp);
|
|
1965
|
+
timeMetadata.duration = Math.max(0, timeMetadata.times.end - timeMetadata.times.start);
|
|
1966
|
+
if (recognize) {
|
|
1967
|
+
recognize(event, api);
|
|
1968
|
+
if (getStatus() === "recognized")
|
|
1969
|
+
onRecognized(event);
|
|
1970
|
+
}
|
|
1971
|
+
storeDuration();
|
|
1972
|
+
});
|
|
1973
|
+
setRequest(request);
|
|
219
1974
|
};
|
|
1975
|
+
storeDuration();
|
|
220
1976
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
1977
|
+
|
|
1978
|
+
const initialMetadata$2 = {
|
|
1979
|
+
points: {
|
|
1980
|
+
start: { x: 0, y: 0 },
|
|
1981
|
+
end: { x: 0, y: 0 }
|
|
1982
|
+
}
|
|
1983
|
+
};
|
|
1984
|
+
function storePointerStartMetadata(event, api) {
|
|
1985
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
1986
|
+
const point = event instanceof MouseEvent ? toMousePoint(event) : toTouchMovePoint(event);
|
|
1987
|
+
if (!metadata.points)
|
|
1988
|
+
metadata.points = createClone()(initialMetadata$2.points);
|
|
1989
|
+
metadata.points.start = point;
|
|
1990
|
+
metadata.points.end = point;
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1993
|
+
const initialMetadata$1 = {
|
|
1994
|
+
distance: {
|
|
1995
|
+
straight: {
|
|
1996
|
+
fromStart: 0,
|
|
1997
|
+
fromPrevious: 0
|
|
1998
|
+
},
|
|
1999
|
+
horizontal: {
|
|
2000
|
+
fromStart: 0,
|
|
2001
|
+
fromPrevious: 0
|
|
2002
|
+
},
|
|
2003
|
+
vertical: {
|
|
2004
|
+
fromStart: 0,
|
|
2005
|
+
fromPrevious: 0
|
|
226
2006
|
}
|
|
227
|
-
|
|
2007
|
+
},
|
|
2008
|
+
angle: {
|
|
2009
|
+
fromPrevious: { radians: 0, degrees: 0 },
|
|
2010
|
+
fromStart: { radians: 0, degrees: 0 }
|
|
2011
|
+
},
|
|
2012
|
+
direction: {
|
|
2013
|
+
fromPrevious: "up",
|
|
2014
|
+
fromStart: "up"
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
function storePointerMoveMetadata(event, api) {
|
|
2018
|
+
const { getMetadata } = api, metadata = getMetadata();
|
|
2019
|
+
if (!metadata.distance) {
|
|
2020
|
+
metadata.distance = createClone()(initialMetadata$1.distance);
|
|
2021
|
+
metadata.angle = createClone()(initialMetadata$1.angle);
|
|
2022
|
+
metadata.direction = createClone()(initialMetadata$1.direction);
|
|
2023
|
+
}
|
|
2024
|
+
const { x: previousX, y: previousY } = metadata.points.end, { x: startX, y: startY } = metadata.points.start, { x: newX, y: newY } = (() => {
|
|
2025
|
+
if (event instanceof MouseEvent) {
|
|
2026
|
+
return toMousePoint(event);
|
|
2027
|
+
}
|
|
2028
|
+
if (event instanceof TouchEvent) {
|
|
2029
|
+
if (event.type === "touchmove") {
|
|
2030
|
+
return toTouchMovePoint(event);
|
|
2031
|
+
}
|
|
2032
|
+
return toTouchEndPoint(event);
|
|
2033
|
+
}
|
|
2034
|
+
})(), { distance: distanceFromPrevious, angle: angleFromPrevious } = toPolarCoordinates({
|
|
2035
|
+
xA: previousX,
|
|
2036
|
+
xB: newX,
|
|
2037
|
+
yA: previousY,
|
|
2038
|
+
yB: newY
|
|
2039
|
+
}), { distance: distanceFromStart, angle: angleFromStart } = toPolarCoordinates({
|
|
2040
|
+
xA: startX,
|
|
2041
|
+
xB: newX,
|
|
2042
|
+
yA: startY,
|
|
2043
|
+
yB: newY
|
|
2044
|
+
});
|
|
2045
|
+
metadata.distance.straight.fromPrevious = distanceFromPrevious;
|
|
2046
|
+
metadata.distance.horizontal.fromPrevious = newX - previousX;
|
|
2047
|
+
metadata.distance.vertical.fromPrevious = newY - previousY;
|
|
2048
|
+
metadata.angle.fromPrevious = angleFromPrevious;
|
|
2049
|
+
metadata.direction.fromPrevious = toDirection(angleFromPrevious.degrees);
|
|
2050
|
+
metadata.distance.straight.fromStart = distanceFromStart;
|
|
2051
|
+
metadata.distance.horizontal.fromStart = newX - startX;
|
|
2052
|
+
metadata.distance.vertical.fromStart = newY - startY;
|
|
2053
|
+
metadata.angle.fromStart = angleFromStart;
|
|
2054
|
+
metadata.direction.fromStart = toDirection(angleFromStart.degrees);
|
|
2055
|
+
metadata.points.end = { x: newX, y: newY };
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
const initialMetadata = {
|
|
2059
|
+
times: {
|
|
2060
|
+
start: 0,
|
|
2061
|
+
end: 0
|
|
2062
|
+
},
|
|
2063
|
+
duration: 0,
|
|
2064
|
+
velocity: 0
|
|
2065
|
+
};
|
|
2066
|
+
function storePointerTimeMetadata(event, api, getShouldStore, setRequest, recognize) {
|
|
2067
|
+
const { getMetadata, getStatus, onRecognized } = api, metadata = getMetadata();
|
|
2068
|
+
if (!metadata.times) {
|
|
2069
|
+
metadata.times = createClone()(initialMetadata.times);
|
|
2070
|
+
}
|
|
2071
|
+
metadata.times.start = Math.round(event.timeStamp);
|
|
2072
|
+
metadata.times.end = Math.round(event.timeStamp);
|
|
2073
|
+
let previousTime = metadata.times.start;
|
|
2074
|
+
const storeDuration = () => {
|
|
2075
|
+
const request = requestAnimationFrame((timestamp) => {
|
|
2076
|
+
if (getShouldStore()) {
|
|
2077
|
+
previousTime = metadata.times.end;
|
|
2078
|
+
metadata.times.end = Math.round(timestamp);
|
|
2079
|
+
metadata.duration = Math.max(0, metadata.times.end - metadata.times.start);
|
|
2080
|
+
const durationFromPrevious = Math.max(0, metadata.times.end - previousTime);
|
|
2081
|
+
metadata.velocity = metadata.distance.straight.fromPrevious / durationFromPrevious;
|
|
2082
|
+
recognize?.(event, api);
|
|
2083
|
+
if (getStatus() === "recognized")
|
|
2084
|
+
onRecognized(event);
|
|
2085
|
+
storeDuration();
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
setRequest(request);
|
|
228
2089
|
};
|
|
2090
|
+
storeDuration();
|
|
229
2091
|
}
|
|
230
|
-
|
|
231
|
-
|
|
2092
|
+
|
|
2093
|
+
function defineGraph(nodes, edges) {
|
|
2094
|
+
return { nodes, edges };
|
|
232
2095
|
}
|
|
233
|
-
function
|
|
234
|
-
return
|
|
2096
|
+
function defineGraphNodes(nodes) {
|
|
2097
|
+
return nodes;
|
|
235
2098
|
}
|
|
236
|
-
function
|
|
237
|
-
return
|
|
2099
|
+
function defineGraphEdges(edges) {
|
|
2100
|
+
return edges;
|
|
238
2101
|
}
|
|
239
|
-
function
|
|
240
|
-
return
|
|
241
|
-
if (elementIsCandidate && predicateFocusable(element))
|
|
242
|
-
return element;
|
|
243
|
-
switch (order) {
|
|
244
|
-
case "first":
|
|
245
|
-
for (let i = 0; i < element.children.length; i++) {
|
|
246
|
-
const focusable = createToFocusable(order, true)(element.children[i]);
|
|
247
|
-
if (focusable)
|
|
248
|
-
return focusable;
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
case "last":
|
|
252
|
-
for (let i = element.children.length - 1; i > -1; i--) {
|
|
253
|
-
const focusable = createToFocusable(order, true)(element.children[i]);
|
|
254
|
-
if (focusable)
|
|
255
|
-
return focusable;
|
|
256
|
-
}
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
};
|
|
2102
|
+
function defineGraphNode(node) {
|
|
2103
|
+
return node;
|
|
260
2104
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
this.state = state;
|
|
264
|
-
}
|
|
265
|
-
pipe(...fns) {
|
|
266
|
-
return createReduce((piped, fn, index) => fn(piped, index), this.state)(fns);
|
|
267
|
-
}
|
|
268
|
-
async pipeAsync(...fns) {
|
|
269
|
-
return await createReduceAsync(
|
|
270
|
-
async (piped, fn, index) => await fn(piped, index),
|
|
271
|
-
this.state
|
|
272
|
-
)(fns);
|
|
273
|
-
}
|
|
2105
|
+
function defineGraphEdge(from, to, predicateTraversable) {
|
|
2106
|
+
return { from, to, predicateTraversable };
|
|
274
2107
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return name in keysByName ? keysByName[name] : name;
|
|
2108
|
+
function defineAsyncGraph(nodes, edges) {
|
|
2109
|
+
return { nodes, edges };
|
|
278
2110
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
right: "ArrowRight",
|
|
282
|
-
down: "ArrowDown",
|
|
283
|
-
left: "ArrowLeft",
|
|
284
|
-
enter: "Enter",
|
|
285
|
-
backspace: "Backspace",
|
|
286
|
-
tab: "Tab",
|
|
287
|
-
space: " ",
|
|
288
|
-
shift: "Shift",
|
|
289
|
-
meta: "Meta",
|
|
290
|
-
command: "Meta",
|
|
291
|
-
cmd: "Meta",
|
|
292
|
-
control: "Control",
|
|
293
|
-
ctrl: "Control",
|
|
294
|
-
alt: "Alt",
|
|
295
|
-
opt: "Alt",
|
|
296
|
-
option: "Alt",
|
|
297
|
-
fn: "Fn",
|
|
298
|
-
capslock: "CapsLock",
|
|
299
|
-
end: "End",
|
|
300
|
-
home: "Home",
|
|
301
|
-
pagedown: "PageDown",
|
|
302
|
-
pageup: "PageUp",
|
|
303
|
-
esc: "Escape",
|
|
304
|
-
camera: "Camera",
|
|
305
|
-
delete: "Delete",
|
|
306
|
-
f1: "F1",
|
|
307
|
-
f2: "F2",
|
|
308
|
-
f3: "F3",
|
|
309
|
-
f4: "F4",
|
|
310
|
-
f5: "F5",
|
|
311
|
-
f6: "F6",
|
|
312
|
-
f7: "F7",
|
|
313
|
-
f8: "F8",
|
|
314
|
-
f9: "F9",
|
|
315
|
-
f10: "F10",
|
|
316
|
-
f11: "F11",
|
|
317
|
-
f12: "F12",
|
|
318
|
-
f13: "F13",
|
|
319
|
-
f14: "F14",
|
|
320
|
-
f15: "F15",
|
|
321
|
-
f16: "F16",
|
|
322
|
-
f17: "F17",
|
|
323
|
-
f18: "F18",
|
|
324
|
-
f19: "F19",
|
|
325
|
-
f20: "F20"
|
|
326
|
-
};
|
|
327
|
-
const toListenableKeycomboItems = createMap((name) => ({ name, type: fromComboItemNameToType(name) }));
|
|
328
|
-
function narrowKeycombo(type) {
|
|
329
|
-
return new Pipeable(type).pipe(
|
|
330
|
-
toCombo,
|
|
331
|
-
toListenableKeycomboItems
|
|
332
|
-
);
|
|
2111
|
+
function defineAsyncGraphEdges(edges) {
|
|
2112
|
+
return edges;
|
|
333
2113
|
}
|
|
334
|
-
function
|
|
335
|
-
return
|
|
2114
|
+
function defineAsyncGraphEdge(from, to, predicateTraversable) {
|
|
2115
|
+
return { from, to, predicateTraversable };
|
|
336
2116
|
}
|
|
337
|
-
|
|
338
|
-
|
|
2117
|
+
|
|
2118
|
+
function defineAssociativeArrayEntries(entries) {
|
|
2119
|
+
return entries;
|
|
339
2120
|
}
|
|
340
|
-
|
|
341
|
-
const toComboItems = map((name) => name === "" ? delimiter : name);
|
|
342
|
-
const delimiter = "+";
|
|
343
|
-
function toCombo(type) {
|
|
344
|
-
return pipe(
|
|
345
|
-
toUnique$1,
|
|
346
|
-
toComboItems,
|
|
347
|
-
toArray()
|
|
348
|
-
)(type.split(delimiter));
|
|
349
|
-
}
|
|
350
|
-
function fromComboItemNameToType(name) {
|
|
351
|
-
return find((type) => predicatesByType[type](name))(listenableComboItemTypes) ?? "custom";
|
|
352
|
-
}
|
|
353
|
-
const listenableComboItemTypes = /* @__PURE__ */ new Set(["singleCharacter", "arrow", "other", "modifier", "click", "pointer"]);
|
|
354
|
-
const predicatesByType = {
|
|
355
|
-
singleCharacter: (name) => typeREs["singleCharacter"].test(name),
|
|
356
|
-
arrow: (name) => typeREs["arrow"].test(name),
|
|
357
|
-
other: (name) => typeREs["other"].test(name),
|
|
358
|
-
modifier: (name) => typeREs["modifier"].test(name),
|
|
359
|
-
click: (name) => typeREs["click"].test(name),
|
|
360
|
-
pointer: (name) => typeREs["pointer"].test(name)
|
|
361
|
-
};
|
|
362
|
-
const typeREs = {
|
|
363
|
-
singleCharacter: /^!?[a-zA-Z0-9,<.>/?;:'"[{\]}\\|`~!@#$%^&*()-_=+]$/,
|
|
364
|
-
arrow: /^!?(arrow|vertical|horizontal|up|down|right|left)$/,
|
|
365
|
-
other: /^!?(enter|backspace|space|tab|esc|home|end|pagedown|pageup|capslock|f[0-9]{1,2}|camera|delete)$/,
|
|
366
|
-
modifier: /^!?(cmd|command|meta|shift|ctrl|control|alt|opt|option)$/,
|
|
367
|
-
click: /^!?(rightclick|contextmenu|click|mousedown|mouseup|dblclick)$/,
|
|
368
|
-
pointer: /^!?(pointerdown|pointerup|pointermove|pointerover|pointerout|pointerenter|pointerleave|pointercancel|gotpointercapture|lostpointercapture)$/
|
|
369
|
-
};
|
|
370
|
-
function toModifier(modifierOrAlias) {
|
|
371
|
-
return modifierOrAlias in modifiersByAlias ? modifiersByAlias[modifierOrAlias] : modifierOrAlias;
|
|
372
|
-
}
|
|
373
|
-
const modifiersByAlias = {
|
|
374
|
-
cmd: "meta",
|
|
375
|
-
command: "meta",
|
|
376
|
-
ctrl: "control",
|
|
377
|
-
opt: "alt",
|
|
378
|
-
option: "alt"
|
|
379
|
-
};
|
|
2121
|
+
|
|
380
2122
|
function createExceptAndOnlyEffect(type, effect, options) {
|
|
381
2123
|
const { except = [], only = [] } = options;
|
|
382
2124
|
if (type === "keydown" || type === "keyup") {
|
|
383
2125
|
return (event) => {
|
|
384
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2126
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
385
2127
|
if (matchesOnly) {
|
|
386
2128
|
effect(event);
|
|
387
2129
|
return;
|
|
@@ -394,7 +2136,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
394
2136
|
}
|
|
395
2137
|
if (type === "click" || type === "dblclick" || type === "contextmenu" || type.startsWith("mouse")) {
|
|
396
2138
|
return (event) => {
|
|
397
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2139
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
398
2140
|
if (matchesOnly) {
|
|
399
2141
|
effect(event);
|
|
400
2142
|
return;
|
|
@@ -407,7 +2149,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
407
2149
|
}
|
|
408
2150
|
if (type.startsWith("pointer")) {
|
|
409
2151
|
return (event) => {
|
|
410
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2152
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
411
2153
|
if (matchesOnly) {
|
|
412
2154
|
effect(event);
|
|
413
2155
|
return;
|
|
@@ -419,7 +2161,7 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
419
2161
|
};
|
|
420
2162
|
}
|
|
421
2163
|
return (event) => {
|
|
422
|
-
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false,
|
|
2164
|
+
const { target } = event, [matchesOnly, matchesExcept] = target instanceof Element ? createMap((selectors) => some((selector) => target.matches(selector))(selectors))([only, except]) : [false, false];
|
|
423
2165
|
if (matchesOnly) {
|
|
424
2166
|
effect(event, {});
|
|
425
2167
|
return;
|
|
@@ -430,27 +2172,15 @@ function createExceptAndOnlyEffect(type, effect, options) {
|
|
|
430
2172
|
}
|
|
431
2173
|
};
|
|
432
2174
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
const predicatesByModifier = {
|
|
437
|
-
shift: (event) => event.shiftKey,
|
|
438
|
-
cmd: (event) => event.metaKey,
|
|
439
|
-
command: (event) => event.metaKey,
|
|
440
|
-
meta: (event) => event.metaKey,
|
|
441
|
-
ctrl: (event) => event.ctrlKey,
|
|
442
|
-
control: (event) => event.ctrlKey,
|
|
443
|
-
alt: (event) => event.altKey,
|
|
444
|
-
opt: (event) => event.altKey,
|
|
445
|
-
option: (event) => event.altKey
|
|
446
|
-
};
|
|
447
|
-
function domIsAvailable() {
|
|
2175
|
+
|
|
2176
|
+
function getDomAvailability() {
|
|
448
2177
|
try {
|
|
449
|
-
return !!window;
|
|
2178
|
+
return !!window ? "available" : "unavailable";
|
|
450
2179
|
} catch (error) {
|
|
451
|
-
return
|
|
2180
|
+
return "unavailable";
|
|
452
2181
|
}
|
|
453
2182
|
}
|
|
2183
|
+
|
|
454
2184
|
function predicateArray(value) {
|
|
455
2185
|
return Array.isArray(value);
|
|
456
2186
|
}
|
|
@@ -469,24 +2199,8 @@ function predicateNumber(value) {
|
|
|
469
2199
|
function predicateString(value) {
|
|
470
2200
|
return typeof value === "string";
|
|
471
2201
|
}
|
|
472
|
-
|
|
473
|
-
"
|
|
474
|
-
"select:not([disabled])",
|
|
475
|
-
"textarea:not([disabled])",
|
|
476
|
-
"button:not([disabled])",
|
|
477
|
-
"a[href]",
|
|
478
|
-
"area[href]",
|
|
479
|
-
"summary",
|
|
480
|
-
"iframe",
|
|
481
|
-
"object",
|
|
482
|
-
"embed",
|
|
483
|
-
"audio[controls]",
|
|
484
|
-
"video[controls]",
|
|
485
|
-
"[contenteditable]",
|
|
486
|
-
"[tabindex]:not([disabled])"
|
|
487
|
-
]);
|
|
488
|
-
function predicateFocusable(element) {
|
|
489
|
-
return element.matches(tabbableSelector);
|
|
2202
|
+
function predicateObject(value) {
|
|
2203
|
+
return typeof value === "object";
|
|
490
2204
|
}
|
|
491
2205
|
|
|
492
2206
|
class Recognizeable {
|
|
@@ -499,7 +2213,7 @@ class Recognizeable {
|
|
|
499
2213
|
effects: {}
|
|
500
2214
|
};
|
|
501
2215
|
this.maxSequenceLength = options?.maxSequenceLength || defaultOptions.maxSequenceLength;
|
|
502
|
-
this.effects =
|
|
2216
|
+
this.effects = options?.effects || defaultOptions.effects;
|
|
503
2217
|
this.resetComputedMetadata();
|
|
504
2218
|
this.setSequence(sequence);
|
|
505
2219
|
this.effectApi = {
|
|
@@ -508,8 +2222,6 @@ class Recognizeable {
|
|
|
508
2222
|
setMetadata: (metadata) => this.computedMetadata = metadata,
|
|
509
2223
|
recognized: () => this.recognized(),
|
|
510
2224
|
denied: () => this.denied(),
|
|
511
|
-
recognizedUntilReady: () => this.recognizedUntilReady(),
|
|
512
|
-
deniedUntilReady: () => this.deniedUntilReady(),
|
|
513
2225
|
ready: () => this.ready()
|
|
514
2226
|
};
|
|
515
2227
|
this.ready();
|
|
@@ -524,12 +2236,6 @@ class Recognizeable {
|
|
|
524
2236
|
denied() {
|
|
525
2237
|
this.computedStatus = "denied";
|
|
526
2238
|
}
|
|
527
|
-
recognizedUntilReady() {
|
|
528
|
-
this.computedStatus = "recognized until ready";
|
|
529
|
-
}
|
|
530
|
-
deniedUntilReady() {
|
|
531
|
-
this.computedStatus = "denied until ready";
|
|
532
|
-
}
|
|
533
2239
|
computedStatus;
|
|
534
2240
|
ready() {
|
|
535
2241
|
this.computedStatus = "ready";
|
|
@@ -552,8 +2258,7 @@ class Recognizeable {
|
|
|
552
2258
|
return this;
|
|
553
2259
|
}
|
|
554
2260
|
recognize(sequenceItem, { onRecognized } = {}) {
|
|
555
|
-
|
|
556
|
-
this.recognizing();
|
|
2261
|
+
this.recognizing();
|
|
557
2262
|
const type = this.toType(sequenceItem), excess = predicateNumber(this.maxSequenceLength) ? Math.max(0, this.sequence.length - this.maxSequenceLength) : 0, newSequence = createConcat(
|
|
558
2263
|
createSlice(excess)(this.sequence),
|
|
559
2264
|
[sequenceItem]
|
|
@@ -561,11 +2266,10 @@ class Recognizeable {
|
|
|
561
2266
|
this.effectApi.getSequence = () => newSequence;
|
|
562
2267
|
this.effectApi.onRecognized = onRecognized || (() => {
|
|
563
2268
|
});
|
|
564
|
-
this.effects
|
|
2269
|
+
this.effects[type]?.(sequenceItem, { ...this.effectApi });
|
|
565
2270
|
switch (this.status) {
|
|
566
2271
|
case "ready":
|
|
567
2272
|
case "denied":
|
|
568
|
-
case "denied until ready":
|
|
569
2273
|
this.resetComputedMetadata();
|
|
570
2274
|
this.setSequence([]);
|
|
571
2275
|
break;
|
|
@@ -608,8 +2312,8 @@ class Listenable {
|
|
|
608
2312
|
computedActive;
|
|
609
2313
|
constructor(type, options) {
|
|
610
2314
|
if (type === "recognizeable") {
|
|
611
|
-
this.computedRecognizeable = new Recognizeable([], options?.recognizeable
|
|
612
|
-
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects
|
|
2315
|
+
this.computedRecognizeable = new Recognizeable([], options?.recognizeable);
|
|
2316
|
+
this.recognizeableEffectsKeys = Object.keys(options?.recognizeable?.effects);
|
|
613
2317
|
}
|
|
614
2318
|
this.computedActive = /* @__PURE__ */ new Set();
|
|
615
2319
|
this.setType(type);
|
|
@@ -709,24 +2413,10 @@ class Listenable {
|
|
|
709
2413
|
this.active.add({ target, id: [this.type, effect] });
|
|
710
2414
|
}
|
|
711
2415
|
recognizeableListen(effect, options) {
|
|
712
|
-
let effectStatus = "ready";
|
|
713
2416
|
const guardedEffect = (sequenceItem) => {
|
|
714
2417
|
this.recognizeable.recognize(sequenceItem, { onRecognized: (sequenceItem2) => effect(sequenceItem2) });
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
if (effectStatus === "ready") {
|
|
718
|
-
effect(sequenceItem);
|
|
719
|
-
effectStatus = "performed";
|
|
720
|
-
}
|
|
721
|
-
break;
|
|
722
|
-
case "recognized":
|
|
723
|
-
effect(sequenceItem);
|
|
724
|
-
effectStatus = "ready";
|
|
725
|
-
break;
|
|
726
|
-
default:
|
|
727
|
-
effectStatus = "ready";
|
|
728
|
-
break;
|
|
729
|
-
}
|
|
2418
|
+
if (this.recognizeable.status === "recognized")
|
|
2419
|
+
effect(sequenceItem);
|
|
730
2420
|
};
|
|
731
2421
|
for (const type of this.recognizeableEffectsKeys) {
|
|
732
2422
|
const listenable = new Listenable(type);
|
|
@@ -747,10 +2437,10 @@ class Listenable {
|
|
|
747
2437
|
}
|
|
748
2438
|
addEventListeners(eventListeners, options) {
|
|
749
2439
|
const { target = document } = options;
|
|
750
|
-
|
|
2440
|
+
for (const eventListener of eventListeners) {
|
|
751
2441
|
target.addEventListener(eventListener[0], eventListener[1], eventListener[2]);
|
|
752
2442
|
this.active.add({ target, id: eventListener });
|
|
753
|
-
}
|
|
2443
|
+
}
|
|
754
2444
|
}
|
|
755
2445
|
listening() {
|
|
756
2446
|
this.computedStatus = "listening";
|
|
@@ -862,109 +2552,22 @@ function toAddEventListenerParams(type, effect, options) {
|
|
|
862
2552
|
const { addEventListener, useCapture } = options, exceptAndOnlyEffect = createExceptAndOnlyEffect(type, effect, options), effectOptions = [addEventListener || useCapture];
|
|
863
2553
|
return { exceptAndOnlyEffect, effectOptions };
|
|
864
2554
|
}
|
|
865
|
-
function eventMatchesKeycombo(event, keycombo) {
|
|
866
|
-
return every(({ name, type }, index) => {
|
|
867
|
-
switch (type) {
|
|
868
|
-
case "singleCharacter":
|
|
869
|
-
if (name === "!")
|
|
870
|
-
return event.key === "!";
|
|
871
|
-
const keyToTest = event.altKey && fromComboItemNameToType(event.key) === "custom" ? fromCodeToSingleCharacter(event.code) : event.key.toLowerCase();
|
|
872
|
-
return name.startsWith("!") ? keyToTest !== toKey(name.slice(1)).toLowerCase() : keyToTest === toKey(name).toLowerCase();
|
|
873
|
-
case "other":
|
|
874
|
-
if (name === "!") {
|
|
875
|
-
return event.key === "!";
|
|
876
|
-
}
|
|
877
|
-
return name.startsWith("!") ? event.key.toLowerCase() !== toKey(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toKey(name).toLowerCase();
|
|
878
|
-
case "arrow":
|
|
879
|
-
return predicatesByArrow.get(name)?.({ event, name }) ?? predicatesByArrow.get("default")({ event, name });
|
|
880
|
-
case "modifier":
|
|
881
|
-
if (index === keycombo.length - 1) {
|
|
882
|
-
return name.startsWith("!") ? event.key.toLowerCase() !== toModifier(name.slice(1)).toLowerCase() : event.key.toLowerCase() === toModifier(name).toLowerCase();
|
|
883
|
-
}
|
|
884
|
-
return name.startsWith("!") ? !predicateModified({ event, alias: name.slice(1) }) : predicateModified({ event, alias: name });
|
|
885
|
-
}
|
|
886
|
-
})(keycombo);
|
|
887
|
-
}
|
|
888
|
-
function fromCodeToSingleCharacter(code) {
|
|
889
|
-
for (const c in aliasesByCode) {
|
|
890
|
-
if (c === code) {
|
|
891
|
-
return aliasesByCode[c];
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
for (const prefix of ["Key", "Digit"]) {
|
|
895
|
-
const re = new RegExp(`^${prefix}`);
|
|
896
|
-
if (re.test(code)) {
|
|
897
|
-
return createClip(re)(code).toLowerCase();
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
return code;
|
|
901
|
-
}
|
|
902
|
-
const aliasesByCode = {
|
|
903
|
-
"Backquote": "`",
|
|
904
|
-
"Minus": "-",
|
|
905
|
-
"Equal": "=",
|
|
906
|
-
"BracketLeft": "[",
|
|
907
|
-
"BracketRight": "]",
|
|
908
|
-
"Backslash": "\\",
|
|
909
|
-
"Semicolon": ";",
|
|
910
|
-
"Quote": "'",
|
|
911
|
-
"Comma": ",",
|
|
912
|
-
"Period": ".",
|
|
913
|
-
"Slash": "/"
|
|
914
|
-
};
|
|
915
|
-
const predicatesByArrow = /* @__PURE__ */ new Map([
|
|
916
|
-
[
|
|
917
|
-
"arrow",
|
|
918
|
-
({ event }) => arrows.has(event.key.toLowerCase())
|
|
919
|
-
],
|
|
920
|
-
[
|
|
921
|
-
"!arrow",
|
|
922
|
-
({ event }) => !arrows.has(event.key.toLowerCase())
|
|
923
|
-
],
|
|
924
|
-
[
|
|
925
|
-
"vertical",
|
|
926
|
-
({ event }) => verticalArrows.has(event.key.toLowerCase())
|
|
927
|
-
],
|
|
928
|
-
[
|
|
929
|
-
"!vertical",
|
|
930
|
-
({ event }) => !verticalArrows.has(event.key.toLowerCase())
|
|
931
|
-
],
|
|
932
|
-
[
|
|
933
|
-
"horizontal",
|
|
934
|
-
({ event }) => horizontalArrows.has(event.key.toLowerCase())
|
|
935
|
-
],
|
|
936
|
-
[
|
|
937
|
-
"!horizontal",
|
|
938
|
-
({ event }) => !horizontalArrows.has(event.key.toLowerCase())
|
|
939
|
-
],
|
|
940
|
-
[
|
|
941
|
-
"default",
|
|
942
|
-
({ event, name }) => name.startsWith("!") ? event.key.toLowerCase() !== `arrow${name.toLowerCase()}` : event.key.toLowerCase() === `arrow${name.toLowerCase()}`
|
|
943
|
-
]
|
|
944
|
-
]);
|
|
945
|
-
const arrows = /* @__PURE__ */ new Set(["arrowup", "arrowright", "arrowdown", "arrowleft"]);
|
|
946
|
-
const verticalArrows = /* @__PURE__ */ new Set(["arrowup", "arrowdown"]);
|
|
947
|
-
const horizontalArrows = /* @__PURE__ */ new Set(["arrowright", "arrowleft"]);
|
|
948
|
-
function eventMatchesMousecombo(event, Mousecombo) {
|
|
949
|
-
return every((name) => fromComboItemNameToType(name) === "click" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(Mousecombo);
|
|
950
|
-
}
|
|
951
|
-
function eventMatchesPointercombo(event, pointercombo) {
|
|
952
|
-
return every((name) => fromComboItemNameToType(name) === "pointer" || name.startsWith("!") && !predicateModified({ alias: name.slice(1), event }) || !name.startsWith("!") && predicateModified({ alias: name, event }))(pointercombo);
|
|
953
|
-
}
|
|
954
2555
|
const observerAssertionsByType = {
|
|
955
2556
|
intersect: (observer) => observer instanceof IntersectionObserver,
|
|
956
2557
|
mutate: (observer) => observer instanceof MutationObserver,
|
|
957
2558
|
resize: (observer) => observer instanceof ResizeObserver
|
|
958
2559
|
};
|
|
959
2560
|
|
|
960
|
-
const defaultOptions$
|
|
2561
|
+
const defaultOptions$8 = {
|
|
961
2562
|
duration: 0,
|
|
2563
|
+
// delay not supported, because it can be effectd by delayable
|
|
962
2564
|
timing: [
|
|
963
2565
|
0,
|
|
964
2566
|
0,
|
|
965
2567
|
1,
|
|
966
2568
|
1
|
|
967
2569
|
],
|
|
2570
|
+
// linear by default
|
|
968
2571
|
iterations: 1,
|
|
969
2572
|
alternates: false
|
|
970
2573
|
};
|
|
@@ -985,10 +2588,10 @@ class Animateable {
|
|
|
985
2588
|
getEaseables;
|
|
986
2589
|
getReversedEaseables;
|
|
987
2590
|
constructor(keyframes, options = {}) {
|
|
988
|
-
this.initialDuration = options?.duration || defaultOptions$
|
|
989
|
-
this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$
|
|
990
|
-
this.iterationLimit = options?.iterations || defaultOptions$
|
|
991
|
-
this.alternates = options?.alternates || defaultOptions$
|
|
2591
|
+
this.initialDuration = options?.duration || defaultOptions$8.duration;
|
|
2592
|
+
this.controlPoints = fromTimingToControlPoints(options?.timing || defaultOptions$8.timing);
|
|
2593
|
+
this.iterationLimit = options?.iterations || defaultOptions$8.iterations;
|
|
2594
|
+
this.alternates = options?.alternates || defaultOptions$8.alternates;
|
|
992
2595
|
this.reversedControlPoints = fromControlPointsToReversedControlPoints(this.controlPoints);
|
|
993
2596
|
this.toAnimationProgress = createToAnimationProgress(this.controlPoints);
|
|
994
2597
|
this.reversedToAnimationProgress = createToAnimationProgress(this.reversedControlPoints);
|
|
@@ -1064,10 +2667,11 @@ class Animateable {
|
|
|
1064
2667
|
setKeyframes(keyframes) {
|
|
1065
2668
|
this.stop();
|
|
1066
2669
|
this.computedKeyframes = Array.from(keyframes).sort(({ progress: progressA }, { progress: progressB }) => progressA - progressB);
|
|
1067
|
-
this.reversedKeyframes =
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
2670
|
+
this.reversedKeyframes = pipe(
|
|
2671
|
+
reverse$1(),
|
|
2672
|
+
map(({ progress, properties }) => ({ progress: 1 - progress, properties })),
|
|
2673
|
+
toArray()
|
|
2674
|
+
)(this.keyframes);
|
|
1071
2675
|
this.properties = toProperties(this.keyframes);
|
|
1072
2676
|
this.easeables = this.getEaseables({ keyframes: this.keyframes, properties: this.properties });
|
|
1073
2677
|
this.reversedEaseables = this.getReversedEaseables({ keyframes: this.reversedKeyframes, properties: this.properties });
|
|
@@ -1365,7 +2969,7 @@ class Animateable {
|
|
|
1365
2969
|
break;
|
|
1366
2970
|
case "reversing":
|
|
1367
2971
|
this.computedIterations += 1;
|
|
1368
|
-
if (this.
|
|
2972
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1369
2973
|
this.createAnimate("reverse")(effect, options);
|
|
1370
2974
|
} else {
|
|
1371
2975
|
this.alternateCache.status = "ready";
|
|
@@ -1374,7 +2978,7 @@ class Animateable {
|
|
|
1374
2978
|
}
|
|
1375
2979
|
} else {
|
|
1376
2980
|
this.computedIterations += 1;
|
|
1377
|
-
if (this.
|
|
2981
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1378
2982
|
this.createAnimate("play")(effect, options);
|
|
1379
2983
|
}
|
|
1380
2984
|
}
|
|
@@ -1390,7 +2994,7 @@ class Animateable {
|
|
|
1390
2994
|
switch (this.alternateCache.status) {
|
|
1391
2995
|
case "playing":
|
|
1392
2996
|
this.computedIterations += 1;
|
|
1393
|
-
if (this.
|
|
2997
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1394
2998
|
this.createAnimate("play")(effect, options);
|
|
1395
2999
|
} else {
|
|
1396
3000
|
this.alternateCache.status = "ready";
|
|
@@ -1402,7 +3006,7 @@ class Animateable {
|
|
|
1402
3006
|
}
|
|
1403
3007
|
} else {
|
|
1404
3008
|
this.computedIterations += 1;
|
|
1405
|
-
if (this.iterations < this.iterationLimit) {
|
|
3009
|
+
if (this.iterationLimit === true || this.iterations < this.iterationLimit) {
|
|
1406
3010
|
this.createAnimate("reverse")(effect, options);
|
|
1407
3011
|
}
|
|
1408
3012
|
}
|
|
@@ -1611,7 +3215,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1611
3215
|
(easeables, property) => {
|
|
1612
3216
|
const propertyKeyframes = createFilter(({ properties: properties2 }) => properties2.hasOwnProperty(property))(keyframes), fromKeyframesToEaseables = createReduce(
|
|
1613
3217
|
(propertyEaseables2, keyframe, index) => {
|
|
1614
|
-
const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? (
|
|
3218
|
+
const previous = keyframe.properties[property], next = index === propertyKeyframes.length - 1 ? previous : propertyKeyframes[index + 1].properties[property], start = keyframe.progress, end = index === propertyKeyframes.length - 1 ? 2 : propertyKeyframes[index + 1].progress, hasCustomTiming = !!keyframe.timing, toAnimationProgress = index === propertyKeyframes.length - 1 ? () => 1 : createToAnimationProgress(fromKeyframeToControlPoints({ keyframe, index, propertyKeyframes }));
|
|
1615
3219
|
propertyEaseables2.push({
|
|
1616
3220
|
property,
|
|
1617
3221
|
value: { previous, next },
|
|
@@ -1626,7 +3230,7 @@ function createGetEaseables(fromKeyframeToControlPoints) {
|
|
|
1626
3230
|
property,
|
|
1627
3231
|
value: { previous: propertyEaseables[0].value.previous, next: propertyEaseables[0].value.previous },
|
|
1628
3232
|
progress: { start: -1, end: propertyEaseables[0].progress.start },
|
|
1629
|
-
toAnimationProgress: (
|
|
3233
|
+
toAnimationProgress: () => 1,
|
|
1630
3234
|
hasCustomTiming: false
|
|
1631
3235
|
};
|
|
1632
3236
|
return createConcat(
|
|
@@ -1871,14 +3475,14 @@ const easingsNetInOutBack = [
|
|
|
1871
3475
|
1.6
|
|
1872
3476
|
];
|
|
1873
3477
|
|
|
1874
|
-
const defaultOptions$
|
|
3478
|
+
const defaultOptions$7 = {
|
|
1875
3479
|
name: "baleada"
|
|
1876
3480
|
};
|
|
1877
3481
|
class Broadcastable {
|
|
1878
3482
|
name;
|
|
1879
3483
|
constructor(state, options = {}) {
|
|
1880
3484
|
this.setState(state);
|
|
1881
|
-
this.name = options.name ?? defaultOptions$
|
|
3485
|
+
this.name = options.name ?? defaultOptions$7.name;
|
|
1882
3486
|
this.ready();
|
|
1883
3487
|
}
|
|
1884
3488
|
computedStatus;
|
|
@@ -1943,12 +3547,69 @@ function toMessageListenParams(instance, effect) {
|
|
|
1943
3547
|
];
|
|
1944
3548
|
}
|
|
1945
3549
|
|
|
3550
|
+
const defaultOptions$6 = {
|
|
3551
|
+
locales: "en",
|
|
3552
|
+
collator: { sensitivity: "base" }
|
|
3553
|
+
};
|
|
3554
|
+
class Compareable {
|
|
3555
|
+
constructor(string, options = {}) {
|
|
3556
|
+
const locales = options.locales || defaultOptions$6.locales, collatorOptions = { ...defaultOptions$6.collator, ...options.collator }, key = locales + pipe(
|
|
3557
|
+
createEntries(),
|
|
3558
|
+
sort((a, b) => a[0] < b[0] ? -1 : 1),
|
|
3559
|
+
join()
|
|
3560
|
+
)(collatorOptions);
|
|
3561
|
+
this.computedCollator = cache[key] || (cache[key] = new Intl.Collator(locales, collatorOptions));
|
|
3562
|
+
this.setString(string);
|
|
3563
|
+
this.ready();
|
|
3564
|
+
}
|
|
3565
|
+
computedStatus;
|
|
3566
|
+
ready() {
|
|
3567
|
+
this.computedStatus = "ready";
|
|
3568
|
+
}
|
|
3569
|
+
get string() {
|
|
3570
|
+
return this.computedString;
|
|
3571
|
+
}
|
|
3572
|
+
set string(string) {
|
|
3573
|
+
this.setString(string);
|
|
3574
|
+
}
|
|
3575
|
+
get status() {
|
|
3576
|
+
return this.computedStatus;
|
|
3577
|
+
}
|
|
3578
|
+
computedCollator;
|
|
3579
|
+
get collator() {
|
|
3580
|
+
return this.computedCollator;
|
|
3581
|
+
}
|
|
3582
|
+
computedComparison;
|
|
3583
|
+
get comparison() {
|
|
3584
|
+
return this.computedComparison;
|
|
3585
|
+
}
|
|
3586
|
+
computedString;
|
|
3587
|
+
setString(string) {
|
|
3588
|
+
this.computedString = string;
|
|
3589
|
+
return this;
|
|
3590
|
+
}
|
|
3591
|
+
compare(compared) {
|
|
3592
|
+
this.comparing();
|
|
3593
|
+
this.computedComparison = this.computedCollator.compare(this.string, compared);
|
|
3594
|
+
this.compared();
|
|
3595
|
+
return this;
|
|
3596
|
+
}
|
|
3597
|
+
comparing() {
|
|
3598
|
+
this.computedStatus = "comparing";
|
|
3599
|
+
}
|
|
3600
|
+
compared() {
|
|
3601
|
+
this.computedStatus = "compared";
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
const cache = {};
|
|
3605
|
+
|
|
1946
3606
|
const defaultOptions$5 = {
|
|
1947
3607
|
segment: {
|
|
1948
3608
|
from: "start",
|
|
1949
3609
|
to: "end"
|
|
1950
3610
|
},
|
|
1951
3611
|
divider: /\s/
|
|
3612
|
+
// Keep an eye out for use cases where a { before, after } object would be needed, or where multi-character dividers need to be used
|
|
1952
3613
|
};
|
|
1953
3614
|
const defaultCompleteOptions = {
|
|
1954
3615
|
select: "completionEnd"
|
|
@@ -2031,6 +3692,7 @@ class Completeable {
|
|
|
2031
3692
|
}
|
|
2032
3693
|
return this;
|
|
2033
3694
|
}
|
|
3695
|
+
// TODO: Support array of selections for multi cursor editing
|
|
2034
3696
|
computedSelection;
|
|
2035
3697
|
setSelection(selection) {
|
|
2036
3698
|
this.computedSelection = selection;
|
|
@@ -2107,12 +3769,12 @@ function toPreviousMatch({ string, re, from }) {
|
|
|
2107
3769
|
if (!re.test(string.slice(0, from)) || from === 0) {
|
|
2108
3770
|
indexOf = -1;
|
|
2109
3771
|
} else {
|
|
2110
|
-
const reversedStringBeforeFrom =
|
|
3772
|
+
const reversedStringBeforeFrom = pipe(
|
|
2111
3773
|
(string2) => string2.slice(0, from),
|
|
2112
3774
|
(sliced) => sliced.split(""),
|
|
2113
3775
|
reverse,
|
|
2114
3776
|
toString
|
|
2115
|
-
), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
3777
|
+
)(string), toNextMatchIndex = toNextMatch({ string: reversedStringBeforeFrom, re, from: 0 });
|
|
2116
3778
|
indexOf = toNextMatchIndex === -1 ? -1 : reversedStringBeforeFrom.length - 1 - toNextMatchIndex;
|
|
2117
3779
|
}
|
|
2118
3780
|
return indexOf;
|
|
@@ -2483,11 +4145,12 @@ class Fetchable {
|
|
|
2483
4145
|
computedText;
|
|
2484
4146
|
constructor(resource, options = {}) {
|
|
2485
4147
|
this.setResource(resource);
|
|
2486
|
-
this.
|
|
2487
|
-
this.
|
|
2488
|
-
this.
|
|
2489
|
-
this.
|
|
2490
|
-
this.
|
|
4148
|
+
this.computedKy = ky.create(narrowOptions(options.ky));
|
|
4149
|
+
this.computedArrayBuffer = new Resolveable(async () => "arrayBuffer" in this.response ? await this.response.arrayBuffer() : void 0);
|
|
4150
|
+
this.computedBlob = new Resolveable(async () => "blob" in this.response ? await this.response.blob() : void 0);
|
|
4151
|
+
this.computedFormData = new Resolveable(async () => "formData" in this.response ? await this.response.formData() : void 0);
|
|
4152
|
+
this.computedJson = new Resolveable(async () => "json" in this.response ? await this.response.json() : void 0);
|
|
4153
|
+
this.computedText = new Resolveable(async () => "text" in this.response ? await this.response.text() : void 0);
|
|
2491
4154
|
this.ready();
|
|
2492
4155
|
}
|
|
2493
4156
|
computedStatus;
|
|
@@ -2500,6 +4163,10 @@ class Fetchable {
|
|
|
2500
4163
|
set resource(resource) {
|
|
2501
4164
|
this.setResource(resource);
|
|
2502
4165
|
}
|
|
4166
|
+
computedKy;
|
|
4167
|
+
get ky() {
|
|
4168
|
+
return this.computedKy;
|
|
4169
|
+
}
|
|
2503
4170
|
computedAbortController;
|
|
2504
4171
|
get abortController() {
|
|
2505
4172
|
if (!this.computedAbortController) {
|
|
@@ -2513,6 +4180,10 @@ class Fetchable {
|
|
|
2513
4180
|
get response() {
|
|
2514
4181
|
return this.computedResponse;
|
|
2515
4182
|
}
|
|
4183
|
+
computedRetryCount = 0;
|
|
4184
|
+
get retryCount() {
|
|
4185
|
+
return this.computedRetryCount;
|
|
4186
|
+
}
|
|
2516
4187
|
get error() {
|
|
2517
4188
|
return this.computedError;
|
|
2518
4189
|
}
|
|
@@ -2541,7 +4212,23 @@ class Fetchable {
|
|
|
2541
4212
|
async fetch(options = {}) {
|
|
2542
4213
|
this.fetching();
|
|
2543
4214
|
try {
|
|
2544
|
-
this.computedResponse = await
|
|
4215
|
+
this.computedResponse = await this.ky(
|
|
4216
|
+
this.resource,
|
|
4217
|
+
{
|
|
4218
|
+
...options,
|
|
4219
|
+
signal: this.abortController.signal,
|
|
4220
|
+
hooks: {
|
|
4221
|
+
...options.hooks,
|
|
4222
|
+
beforeRetry: [
|
|
4223
|
+
...options.hooks?.beforeRetry || [],
|
|
4224
|
+
({ retryCount }) => {
|
|
4225
|
+
this.retrying();
|
|
4226
|
+
this.computedRetryCount = retryCount;
|
|
4227
|
+
}
|
|
4228
|
+
]
|
|
4229
|
+
}
|
|
4230
|
+
}
|
|
4231
|
+
);
|
|
2545
4232
|
this.fetched();
|
|
2546
4233
|
} catch (error) {
|
|
2547
4234
|
this.computedError = error;
|
|
@@ -2555,6 +4242,9 @@ class Fetchable {
|
|
|
2555
4242
|
fetching() {
|
|
2556
4243
|
this.computedStatus = "fetching";
|
|
2557
4244
|
}
|
|
4245
|
+
retrying() {
|
|
4246
|
+
this.computedStatus = "retrying";
|
|
4247
|
+
}
|
|
2558
4248
|
fetched() {
|
|
2559
4249
|
this.computedStatus = "fetched";
|
|
2560
4250
|
}
|
|
@@ -2565,23 +4255,27 @@ class Fetchable {
|
|
|
2565
4255
|
this.computedStatus = "errored";
|
|
2566
4256
|
}
|
|
2567
4257
|
async get(options = {}) {
|
|
2568
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4258
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "get" });
|
|
2569
4259
|
return this;
|
|
2570
4260
|
}
|
|
2571
4261
|
async patch(options = {}) {
|
|
2572
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4262
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "patch" });
|
|
2573
4263
|
return this;
|
|
2574
4264
|
}
|
|
2575
4265
|
async post(options = {}) {
|
|
2576
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4266
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "post" });
|
|
2577
4267
|
return this;
|
|
2578
4268
|
}
|
|
2579
4269
|
async put(options = {}) {
|
|
2580
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4270
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "put" });
|
|
2581
4271
|
return this;
|
|
2582
4272
|
}
|
|
2583
4273
|
async delete(options = {}) {
|
|
2584
|
-
await this.fetch({ signal: this.abortController.signal, ...
|
|
4274
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "delete" });
|
|
4275
|
+
return this;
|
|
4276
|
+
}
|
|
4277
|
+
async head(options = {}) {
|
|
4278
|
+
await this.fetch({ signal: this.abortController.signal, ...options, method: "head" });
|
|
2585
4279
|
return this;
|
|
2586
4280
|
}
|
|
2587
4281
|
abort() {
|
|
@@ -2590,16 +4284,9 @@ class Fetchable {
|
|
|
2590
4284
|
}
|
|
2591
4285
|
}
|
|
2592
4286
|
function narrowOptions(options) {
|
|
2593
|
-
|
|
2594
|
-
}
|
|
2595
|
-
|
|
2596
|
-
return {
|
|
2597
|
-
body: JSON.stringify(data),
|
|
2598
|
-
headers: {
|
|
2599
|
-
"Accept": "application/json",
|
|
2600
|
-
"Content-Type": "application/json"
|
|
2601
|
-
}
|
|
2602
|
-
};
|
|
4287
|
+
if (!options)
|
|
4288
|
+
return {};
|
|
4289
|
+
return predicateFunction(options) ? options({ stop: ky.stop }) : options;
|
|
2603
4290
|
}
|
|
2604
4291
|
|
|
2605
4292
|
class Fullscreenable {
|
|
@@ -2927,13 +4614,12 @@ class Pickable {
|
|
|
2927
4614
|
}
|
|
2928
4615
|
pick(indexOrIndices, options = {}) {
|
|
2929
4616
|
const { replace, allowsDuplicates } = { ...defaultPickOptions, ...options };
|
|
2930
|
-
this.computedPicks =
|
|
4617
|
+
this.computedPicks = pipe(
|
|
2931
4618
|
narrowIndices,
|
|
2932
4619
|
this.toPossiblePicks,
|
|
2933
4620
|
(possiblePicks) => {
|
|
2934
|
-
if (replace === "all")
|
|
4621
|
+
if (replace === "all")
|
|
2935
4622
|
return allowsDuplicates ? possiblePicks : toUnique(possiblePicks);
|
|
2936
|
-
}
|
|
2937
4623
|
const maybeWithoutDuplicates = allowsDuplicates ? possiblePicks : createFilter(
|
|
2938
4624
|
(possiblePick) => typeof find((pick) => pick === possiblePick)(this.picks || []) !== "number"
|
|
2939
4625
|
)(possiblePicks);
|
|
@@ -2950,10 +4636,11 @@ class Pickable {
|
|
|
2950
4636
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2951
4637
|
return createSlice(maybeWithoutDuplicates.length - this.picks.length)(maybeWithoutDuplicates);
|
|
2952
4638
|
}
|
|
2953
|
-
return
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
4639
|
+
return pipe(
|
|
4640
|
+
slice(maybeWithoutDuplicates.length),
|
|
4641
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4642
|
+
toArray()
|
|
4643
|
+
)(this.picks);
|
|
2957
4644
|
case "lifo":
|
|
2958
4645
|
if (maybeWithoutDuplicates.length === 0) {
|
|
2959
4646
|
return this.picks;
|
|
@@ -2964,13 +4651,14 @@ class Pickable {
|
|
|
2964
4651
|
if (maybeWithoutDuplicates.length > this.picks.length) {
|
|
2965
4652
|
return createSlice(0, maybeWithoutDuplicates.length - this.picks.length + 1)(maybeWithoutDuplicates);
|
|
2966
4653
|
}
|
|
2967
|
-
return
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
4654
|
+
return pipe(
|
|
4655
|
+
slice(0, this.picks.length - maybeWithoutDuplicates.length - 1),
|
|
4656
|
+
(array) => concat(array, maybeWithoutDuplicates),
|
|
4657
|
+
toArray()
|
|
4658
|
+
)(this.picks);
|
|
2971
4659
|
}
|
|
2972
4660
|
}
|
|
2973
|
-
);
|
|
4661
|
+
)(indexOrIndices);
|
|
2974
4662
|
this.computedFirst = Math.min(...this.picks);
|
|
2975
4663
|
this.computedLast = Math.max(...this.picks);
|
|
2976
4664
|
this.computedMultiple = toUnique(this.picks).length > 1;
|
|
@@ -3018,7 +4706,7 @@ class Sanitizeable {
|
|
|
3018
4706
|
computedDompurify;
|
|
3019
4707
|
computedStatus;
|
|
3020
4708
|
ready() {
|
|
3021
|
-
if (
|
|
4709
|
+
if (getDomAvailability() === "available") {
|
|
3022
4710
|
this.computedDompurify = createDOMPurify();
|
|
3023
4711
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3024
4712
|
}
|
|
@@ -3031,7 +4719,7 @@ class Sanitizeable {
|
|
|
3031
4719
|
this.setHtml(html);
|
|
3032
4720
|
}
|
|
3033
4721
|
get dompurify() {
|
|
3034
|
-
if (!this.computedDompurify &&
|
|
4722
|
+
if (!this.computedDompurify && getDomAvailability() === "available") {
|
|
3035
4723
|
this.computedDompurify = createDOMPurify();
|
|
3036
4724
|
this.computedDompurify.setConfig(this.domPurifyConfig);
|
|
3037
4725
|
}
|
|
@@ -3174,7 +4862,7 @@ class Storeable {
|
|
|
3174
4862
|
computedStatus;
|
|
3175
4863
|
ready() {
|
|
3176
4864
|
this.computedStatus = "ready";
|
|
3177
|
-
if (
|
|
4865
|
+
if (getDomAvailability() === "available") {
|
|
3178
4866
|
if (predicateNull(this.storage.getItem(this.computedStatusKey))) {
|
|
3179
4867
|
this.storeStatus();
|
|
3180
4868
|
}
|
|
@@ -3187,7 +4875,7 @@ class Storeable {
|
|
|
3187
4875
|
this.setKey(key);
|
|
3188
4876
|
}
|
|
3189
4877
|
get status() {
|
|
3190
|
-
if (
|
|
4878
|
+
if (getDomAvailability() === "available") {
|
|
3191
4879
|
const storedStatus = this.storage.getItem(this.computedStatusKey);
|
|
3192
4880
|
if (this.computedStatus !== storedStatus && predicateString(storedStatus)) {
|
|
3193
4881
|
this.computedStatus = storedStatus;
|
|
@@ -3275,4 +4963,4 @@ class Storeable {
|
|
|
3275
4963
|
}
|
|
3276
4964
|
}
|
|
3277
4965
|
|
|
3278
|
-
export { Animateable, Broadcastable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable,
|
|
4966
|
+
export { Animateable, Broadcastable, Compareable, Completeable, Copyable, Delayable, Drawable, Fetchable, Fullscreenable, Grantable, Listenable, Navigateable, Pickable, Recognizeable, Resolveable, Sanitizeable, Searchable, Shareable, Storeable, createAssociativeArray, createPredicateAncestor$1 as createAsyncDirectedAcyclicPredicateAncestor, createToCommonAncestors$1 as createAsyncDirectedAcyclicToCommonAncestors, createToLayers as createAsyncDirectedAcyclicToLayers, createToNodeSteps$1 as createAsyncDirectedAcyclicToNodeSteps, createToPath$1 as createAsyncDirectedAcyclicToPath, createToSteps$1 as createAsyncDirectedAcyclicToSteps, createToTree$1 as createAsyncDirectedAcyclicToTree, createClamp, createClip, createClone, createConcat, createPredicateAncestor as createDecisionTreePredicateAncestor, createToCommonAncestors as createDecisionTreeToCommonAncestors, createToNodeSteps as createDecisionTreeToNodeSteps, createToPath as createDecisionTreeToPath, createToSteps as createDecisionTreeToSteps, createToTree as createDecisionTreeToTree, createDetermine, createPredicateAncestor$2 as createDirectedAcyclicPredicateAncestor, createToCommonAncestors$2 as createDirectedAcyclicToCommonAncestors, createToLayers$1 as createDirectedAcyclicToLayers, createToNodeSteps$2 as createDirectedAcyclicToNodeSteps, createToPath$2 as createDirectedAcyclicToPath, createToRoots as createDirectedAcyclicToRoots, createToSteps$2 as createDirectedAcyclicToSteps, createToTree$2 as createDirectedAcyclicToTree, createEntries, createEqual, createEvery, createFilter, createFilterAsync, createFindAsync, createFindIndexAsync, createFocusable, createForEachAsync, createInsert, createKeychord, createKeypress, createKeyrelease, createKeys, createList, createMap, createMapAsync, createMousepress, createMouserelease, createPredicateKeycomboMatch$1 as createPredicateKeycomboMatch, createPredicateRoot, createReduce, createReduceAsync, createRemove, createRename, createReorder, createReplace, createReverse, createSlice, createSlug, createSome, createSort, createSwap, createToGraph, createToIncoming, createToIndegree, createToOutdegree, createToOutgoing, createTouchpress, createTouchrelease, createFind as createTreeFind, createUnique, defineAssociativeArrayEntries, defineAsyncGraph, defineAsyncGraphEdge, defineAsyncGraphEdges, defineGraph, defineGraphEdge, defineGraphEdges, defineGraphNode, defineGraphNodes, easingsNetInBack, easingsNetInCirc, easingsNetInCubic, easingsNetInExpo, easingsNetInOutBack, easingsNetInOutCirc, easingsNetInOutCubic, easingsNetInOutExpo, easingsNetInOutQuad, easingsNetInOutQuint, easingsNetInOutSine, easingsNetInQuad, easingsNetInQuart, easingsNetInQuint, easingsNetInSine, easingsNetOutBack, easingsNetOutCirc, easingsNetOutCubic, easingsNetOutExpo, easingsNetOutQuad, easingsNetOutQuint, easingsNetOutSine, linear, materialAccelerated, materialDecelerated, materialStandard, toD, toFlattenedD, toMessageListenParams, verouEase, verouEaseIn, verouEaseInOut, verouEaseOut };
|