@peter.naydenov/cuts 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/.graphify_uncached.txt +1 -0
  2. package/.opencode/plugins/graphify.js +22 -0
  3. package/AGENTS.md +8 -0
  4. package/Changelog.md +10 -0
  5. package/README.md +154 -1
  6. package/dist/cuts.umd.js +1 -1
  7. package/graphify-out/.graphify_labels.json +56 -0
  8. package/graphify-out/.graphify_python +1 -0
  9. package/graphify-out/.graphify_root +1 -0
  10. package/graphify-out/GRAPH_REPORT.md +177 -0
  11. package/graphify-out/cache/012d3294918720b55e6b92b199990cfc018241eea880e1f6e6a0724aa6e1f17f.json +1 -0
  12. package/graphify-out/cache/01cec5959c65918486350dcf1673e6e3fc496e3f888d6872533927da64581a04.json +1 -0
  13. package/graphify-out/cache/0940319c089ade1ec8424e8d1a54cb8b4d8b5398da48bbb44dd68cefe9d33c00.json +1 -0
  14. package/graphify-out/cache/0da80b47b352499ba03cd5dee2fc281a98f09a19480e622d15faf49157df074b.json +1 -0
  15. package/graphify-out/cache/0e905bdb9bcd5a94e8d4f53d8c3a5c074283166b302d39436dbb245f2ec35e70.json +1 -0
  16. package/graphify-out/cache/0fa5cad2f351dcaa7d35b48576dee7f9ac9c5cc4b394b1f0deaff8a180e3c451.json +1 -0
  17. package/graphify-out/cache/10aa1439c5bfd598b80d729e5ba3b6cfdb58bd2b359f420c292aafc8c035a02d.json +1 -0
  18. package/graphify-out/cache/131c1daae8abc86c8218622f56273af8b1b9f9fa4aec2998ef825bca0f62913d.json +1 -0
  19. package/graphify-out/cache/17e5f2beac577cb4a9318ab14e559216c17efa10b9066767965970dbb5303aa8.json +1 -0
  20. package/graphify-out/cache/1e04390c6e1cff4babe570ffb9ca69c7dc48aedbd5a590844ad0306870c384a4.json +1 -0
  21. package/graphify-out/cache/240c8091236475ff2ee2cf2f9f9f6e80be1616c8f608aec6f0bd7df848581adc.json +1 -0
  22. package/graphify-out/cache/24418a06ce214a93595cb57c1a4c951b233e7e8fdc47122e2ba02935970a7266.json +1 -0
  23. package/graphify-out/cache/2675052ddc9cfa31333f6810c81eb9cfac04a6a627bd897a68963adcfb6a8c08.json +1 -0
  24. package/graphify-out/cache/309a7e48db971f382ade80198bb1fc2afaa016a36a2a7cfcb2a8538d79061530.json +1 -0
  25. package/graphify-out/cache/323e2198675ff4fba301afb26c3b188db91039aed029d2b3c4afd659ce75ca92.json +1 -0
  26. package/graphify-out/cache/3493a990cec8e577d0da3de4a54229b649a63400a4023ca1911c082309e27e7b.json +1 -0
  27. package/graphify-out/cache/35745072ea817929ae9707d52b4601e63a15233d033c67575cd13f4fef4a6374.json +1 -0
  28. package/graphify-out/cache/3bb336d107d9e0f7243aaf6249f4218da2af6734736192633943f0fabe04bd11.json +1 -0
  29. package/graphify-out/cache/4182a1dd2fcfa44f6ccc7615259fc5288fc1c5f23b6e41dd1d31acaad9d9672a.json +1 -0
  30. package/graphify-out/cache/4b1b786ba42a5f31760aacecaec23d8a430fdc7054d9fc94aeda68e1a814a37b.json +1 -0
  31. package/graphify-out/cache/53400873bbb9d220df1cd34714577c750185538ca2f43ce726c7e9d2064d9890.json +1 -0
  32. package/graphify-out/cache/5552036f9715ed1c0e0793131c919739e887f413ef8979efd8dac0d347d26a92.json +1 -0
  33. package/graphify-out/cache/55f4ffb8c1f3a0a68dd78016df9e1309f481b5942b468abab7f567fc8aa0f2ab.json +1 -0
  34. package/graphify-out/cache/570424b2534780740fec1c08d7435bb228af7705e3f6e9fa28ee087a6092c916.json +1 -0
  35. package/graphify-out/cache/573b92c02548ab00fcf9351dfa2c6fe7f401acca2b9315133edc7453e82a25bb.json +1 -0
  36. package/graphify-out/cache/57c611c887a762e47fff496f1438e35bff2794807b327ace69dc40b4b5126f6c.json +1 -0
  37. package/graphify-out/cache/682fea1576e6f89f0bbeecab480fdf3a3a15649f6f41b1af6db758248b4669a1.json +1 -0
  38. package/graphify-out/cache/6ca8a0aa9022e68f010ca8ece5ee0c5ba9616d31aa1716634bcb61fd7c03baf0.json +1 -0
  39. package/graphify-out/cache/7098a2a328c738b93faea79761188f18a8c8daaf530a590df89f1e3f6ecce7ed.json +1 -0
  40. package/graphify-out/cache/782b5a020c37aa0cc0163a21d32ea7af9a9677dbbf267a6c109aa9a919e5d79d.json +1 -0
  41. package/graphify-out/cache/8771f4d3ccb4ae55a13a2d1a452626e0dadb16a146ef0839dd963e42b3decfa2.json +1 -0
  42. package/graphify-out/cache/93fdbd9b92d3928bec4b31972bc7f458551868ce10157e68b624addbc310e45e.json +1 -0
  43. package/graphify-out/cache/941ca37c98b5c5e4224d8f28c98d82164fb9e047f551122ed9dd1e172c9ca210.json +1 -0
  44. package/graphify-out/cache/9603602b27e8453e47faac0e540e17de9e2473d716d2c1399b860d1ede74e649.json +1 -0
  45. package/graphify-out/cache/965a31d7d62cd7f81146f1c4c39b37535a7b0c720a800856477250781254fc23.json +1 -0
  46. package/graphify-out/cache/9a192662abf3d936dfc83c16bf18d6a46ac2ce3f16fb493050178eafcf640326.json +1 -0
  47. package/graphify-out/cache/9a4c098d43c0f0ec653bdfd3b68a482376fdd3a25c31c6b92bb92d8a49ed4de7.json +1 -0
  48. package/graphify-out/cache/9aec2f693fa17698f1d16683fff1947eab153d1fd788ee25ec4d06f6ba0b8171.json +1 -0
  49. package/graphify-out/cache/9daaa95737c689bd88ed99b880c7b4add83dfffa17ad6431aade0e8037946ce1.json +1 -0
  50. package/graphify-out/cache/a12981414bb5c59b6e9ad87b36cb4eb9c1e9b49cb7446ecb2789ab4496d1d4b3.json +1 -0
  51. package/graphify-out/cache/aa9a32d2538270661b9f591dec199134eb51488f103325c93e8eeb29f6088307.json +1 -0
  52. package/graphify-out/cache/ae75925bf4fc6a110fa7af9a0a8b20da642d6e61b8ac079b9a843c2e7848d2bf.json +1 -0
  53. package/graphify-out/cache/ast/v0.8.39/043be2e32281a59e2bacb95418b95816b558a290aa581434b22666fb9a6a3a6c.json +1 -0
  54. package/graphify-out/cache/ast/v0.8.39/151934b5e716a5f1d14f4954ebca16c64f767c94ea65182896565a0a845a99d8.json +1 -0
  55. package/graphify-out/cache/ast/v0.8.39/2b64175ef58c779348b9f3b1bc212093f30455a8c3b30e90ec66bc0c83893a17.json +1 -0
  56. package/graphify-out/cache/ast/v0.8.39/93e3201ab0f7055efb1bd85240bdae46fcc21d36089825bafeb9ba97e082b25d.json +1 -0
  57. package/graphify-out/cache/ast/v0.8.39/a54f836214535c9d3ff5d4ba866f261748789984734e148a99dff099f0977cd4.json +1 -0
  58. package/graphify-out/cache/ast/v0.8.39/ac32180db1477eed72583ce9d06051d06eb0336e02b1894789b5a039392b7255.json +1 -0
  59. package/graphify-out/cache/ast/v0.8.39/b3a576733a49496a7d162b3a08710f6ca29fd2678532e9406755046f6250acb9.json +1 -0
  60. package/graphify-out/cache/ast/v0.8.39/c2b57052ba235afaf3195c026546eabbe2ab6274aa24bc3e4481f92904fe6a9d.json +1 -0
  61. package/graphify-out/cache/b0e7e88b335107d2ebb72524803d5575fc84eeb6c065e5c8dce8e659f59b14ce.json +1 -0
  62. package/graphify-out/cache/b5bad0c1d525f2d57687ff82e3f52644140625f0bb9a91e2a40bb94f172295ba.json +1 -0
  63. package/graphify-out/cache/bb9cde14b37ae2b22720974339bda8c8698f8db8e03ae108fc4e0a1b175a5799.json +1 -0
  64. package/graphify-out/cache/bfb8682a587eb2a75f2de9a6cb68eea52c6791ce763ed9fd370e4186f2ca964d.json +1 -0
  65. package/graphify-out/cache/c0e0ab86119b69a71d7c07134e3259961c112ac293d1c1976ebdaa975c6634a1.json +1 -0
  66. package/graphify-out/cache/cbd4d1c99376a1a9cbac38a927bc9bab92bdf6715ca31f99388b02ccab3accc1.json +1 -0
  67. package/graphify-out/cache/df569c88c4ba775eea79ac5596fe3b70345f3ee7a53459d865e196e0e807d966.json +1 -0
  68. package/graphify-out/cache/f6feb53a375f42d12de35e3a7d29cc2f3263f9fca0eff30b5f0ea2dd50a4bc7f.json +1 -0
  69. package/graphify-out/cache/ffc7c58210d00973bed4dc58e0d97fe862129d2dfeba3a60ea643bcb5ae6757f.json +1 -0
  70. package/graphify-out/cache/stat-index.json +1 -0
  71. package/graphify-out/cost.json +12 -0
  72. package/graphify-out/graph.html +307 -0
  73. package/graphify-out/graph.json +5460 -0
  74. package/graphify-out/manifest.json +302 -0
  75. package/opencode.json +6 -0
  76. package/package.json +17 -13
  77. package/types/findInstructions.d.ts +1 -1
  78. package/types/findInstructions.d.ts.map +1 -1
  79. package/types/main.d.ts +76 -12
  80. package/types/main.d.ts.map +1 -1
  81. package/types/methods/hide.d.ts +1 -1
  82. package/types/methods/hide.d.ts.map +1 -1
  83. package/types/methods/jump.d.ts +1 -1
  84. package/types/methods/jump.d.ts.map +1 -1
  85. package/types/methods/jumpBack.d.ts +2 -2
  86. package/types/methods/jumpBack.d.ts.map +1 -1
  87. package/types/methods/jumpsReset.d.ts +1 -1
  88. package/types/methods/jumpsReset.d.ts.map +1 -1
  89. package/types/methods/listShortcuts.d.ts +1 -1
  90. package/types/methods/listShortcuts.d.ts.map +1 -1
  91. package/types/methods/setScenes.d.ts +11 -17
  92. package/types/methods/setScenes.d.ts.map +1 -1
  93. package/types/methods/show.d.ts +2 -2
  94. package/types/methods/show.d.ts.map +1 -1
  95. package/types/setInstruction.d.ts +1 -1
  96. package/types/setInstruction.d.ts.map +1 -1
@@ -0,0 +1 @@
1
+ README.md
@@ -0,0 +1,22 @@
1
+ // graphify OpenCode plugin
2
+ // Injects a knowledge graph reminder before bash tool calls when the graph exists.
3
+ import { existsSync } from "fs";
4
+ import { join } from "path";
5
+
6
+ export const GraphifyPlugin = async ({ directory }) => {
7
+ let reminded = false;
8
+
9
+ return {
10
+ "tool.execute.before": async (input, output) => {
11
+ if (reminded) return;
12
+ if (!existsSync(join(directory, "graphify-out", "graph.json"))) return;
13
+
14
+ if (input.tool === "bash") {
15
+ output.args.command =
16
+ 'echo "[graphify] Knowledge graph available. Read graphify-out/GRAPH_REPORT.md for god nodes and architecture context before searching files." && ' +
17
+ output.args.command;
18
+ reminded = true;
19
+ }
20
+ },
21
+ };
22
+ };
package/AGENTS.md ADDED
@@ -0,0 +1,8 @@
1
+ ## graphify
2
+
3
+ This project has a graphify knowledge graph at graphify-out/.
4
+
5
+ Rules:
6
+ - Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
7
+ - If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
8
+ - After modifying code files in this session, run `python3 -c "from graphify.watch import _rebuild_code; from pathlib import Path; _rebuild_code(Path('.'))"` to keep the graph current
package/Changelog.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # Release History
2
2
 
3
3
 
4
+ ## 2.1.1 ( 2026-07-08 )
5
+ - [x] Dependency update. @peter.naydenov/shortcuts - v.4.1.2
6
+ - [x] (fixes TypeScript declaration emit for `PluginAPI` and `ShortcutsAPI`);
7
+
8
+
9
+
10
+ ## 2.1.0 ( 2026-06-07 )
11
+ - [x] Dependency update. @peter.naydenov/shortcuts - v.4.1.0;
12
+ - [x] Now each event callback has dependencies.emit. Chains of events are getting easier;
13
+
4
14
 
5
15
  ## 2.0.3 ( 2026-04-23 )
6
16
  - [x] Dependency update. ask-for-promise - v.3.1.1;
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <img src="cuts.png" width="100%" alt="Cuts" align="center" />
1
+ <img src="https://github.com/PeterNaydenov/cuts/blob/main/cuts.png" width="100%" alt="Cuts" align="center" />
2
2
 
3
3
 
4
4
 
@@ -54,6 +54,13 @@ script.show ({ scene : 'sceneName'}) // change the current Scene
54
54
 
55
55
 
56
56
 
57
+ ## Configuration
58
+
59
+ `cuts()` accepts an options object. Currently one option is supported: [`logLevel`](#loglevel-default--1). See the [`@app-error`](#app-error) section for details on how it affects event emission.
60
+
61
+
62
+
63
+
57
64
 
58
65
  ## Screen Cuts Methods Overview
59
66
 
@@ -154,6 +161,152 @@ script.enablePlugin ( pluginHover )
154
161
 
155
162
 
156
163
 
164
+
165
+
166
+ ## Events
167
+
168
+ Cuts emits a single built-in event and exposes a passthrough for custom events.
169
+
170
+ ### `@app-error`
171
+
172
+ Triggered whenever an error is logged inside cuts (scene not found, invalid context, shortcut error, etc.). Register a handler in a scene's shortcuts:
173
+
174
+ ```js
175
+ const script = cuts ({ logLevel: 1 });
176
+
177
+ script.setScenes ([
178
+ {
179
+ name: 'home',
180
+ scene: {
181
+ show : ({ task }) => task.done(),
182
+ hide : ({ task }) => task.done(),
183
+ '@app-error' : ( logEntry ) => {
184
+ // logEntry: { type: 'error', message: 'Scene "X" is not available.', ... }
185
+ console.error ( '[cuts]', logEntry.message )
186
+ }
187
+ }
188
+ }
189
+ ])
190
+ ```
191
+
192
+ The handler receives the raw log entry produced by `@peter.naydenov/log`. It has at least `{ type: 'error', message: <string> }`; the full shape is whatever the log library reports. The event name is fixed and cannot be renamed from the cuts configuration.
193
+
194
+ #### `logLevel` (default: `1`)
195
+
196
+ Whether `@app-error` fires depends on the `logLevel` option passed to `cuts()`. Internally cuts uses `@peter.naydenov/log` to emit its log entries (scene not found, invalid context, etc.). A log entry is processed only when its level is less than or equal to the configured `logLevel`. Cuts logs only at level `1`, so the only meaningful values are:
197
+
198
+ - **`1` (default)** — errors are logged. The log callback fires for every error, which is what re-emits each one as `@app-error`. Use this when you want cuts to surface problems to your code.
199
+ - **`0`** — completely silent. No log output, and **no `@app-error` events are emitted**. Use this in production if you don't want to handle cuts errors at the event level.
200
+
201
+ ```js
202
+ // Default: errors fire @app-error
203
+ const script = cuts ();
204
+
205
+ // Silent: no @app-error events
206
+ const script = cuts ({ logLevel: 0 });
207
+ ```
208
+
209
+ The option is also exposed in `types/main.d.ts` as `logLevel: number`.
210
+
211
+ ### Custom events via `emit`
212
+
213
+ Cuts does not define additional events, but it forwards `script.emit(event, ...args)` to the underlying shortcuts manager. Custom event handlers are registered inside a scene's `scene` object - same place as `@app-error`, just under any name you choose.
214
+
215
+ Full round-trip: define, register, emit, handle.
216
+
217
+ ```js
218
+ import cuts from '@peter.naydenov/cuts'
219
+
220
+ const script = cuts ()
221
+
222
+ // 1. Register a handler inside a scene, keyed by your custom event name
223
+ script.setScenes ([
224
+ {
225
+ name: 'home',
226
+ scene: {
227
+ show : ({ task }) => task.done(),
228
+ hide : ({ task }) => task.done(),
229
+
230
+ // Custom event handler. Receives whatever args `script.emit` passed.
231
+ '@analytics' : ( payload ) => {
232
+ // payload === { event: 'scene-entered', scene: 'home', ts: 1700000000000 }
233
+ console.log ( '[analytics]', payload )
234
+ }
235
+ }
236
+ }
237
+ ])
238
+
239
+ // 2. Trigger it from anywhere you have a reference to `script`
240
+ await script.show ({ scene: 'home' })
241
+
242
+ script.emit ( '@analytics', {
243
+ event : 'scene-entered'
244
+ , scene : 'home'
245
+ , ts : Date.now ()
246
+ })
247
+ ```
248
+
249
+ Event name convention: use a plugin-style prefix to avoid collisions with built-in shortcuts (e.g. `@my-app:foo` or `@analytics`). Any string works; a leading `@` is a common convention but not required.
250
+
251
+ A handler is only active while its scene is the current context. To make a handler global, register it on every scene, or wire it to a scene that stays mounted (e.g. a root scene).
252
+
253
+ #### Emitting from inside a handler
254
+
255
+ The shortcuts library now exposes its event emitter on `dependencies.emit` in every handler. `dependencies.emit` is always present — no `setDependencies` trick is required to call it from a `click`, `key`, `hover`, `scroll` or `form` action.
256
+
257
+ A common use is **chaining** one gesture into another. A `key:ctrl+s` keystroke can fire the same handler that a "Save" click would, so the save logic lives in exactly one place:
258
+
259
+ ```js
260
+ import cuts from '@peter.naydenov/cuts'
261
+
262
+ const script = cuts ()
263
+
264
+ script.setScenes ([
265
+ {
266
+ name: 'editor',
267
+ scene: {
268
+ show : ({ task }) => task.done(),
269
+ hide : ({ task }) => task.done(),
270
+
271
+ // Single source of truth for "save the document"
272
+ 'click: left-1' : ({ target }) => {
273
+ if ( target?.id !== 'save-btn' ) return
274
+ console.log ( 'saving document' )
275
+ },
276
+
277
+ // Keyboard shortcut forwards to the click handler above
278
+ 'key: ctrl+s' : ({ dependencies }) => {
279
+ dependencies.emit ( 'click: left-1', {
280
+ target : document.getElementById ( 'save-btn' )
281
+ })
282
+ }
283
+ }
284
+ }
285
+ ])
286
+ ```
287
+
288
+ Pressing **Ctrl+S** runs the `key: ctrl+s` handler, which calls `dependencies.emit('click: left-1', { target })`. The active scene's `click: left-1` handler then fires with the synthetic target, so the save logic only exists in one place. The emitted name can be a fully-prefixed shortcut (`click: left-1`) or any custom string you register a handler for — same mechanism as `script.emit(...)` from outside.
289
+
290
+ User-supplied `setDependencies` keys are merged into the same `dependencies` bag, so you can still reach your own services next to `emit`:
291
+
292
+ ```js
293
+ script.setDependencies ({ analytics }) // merged with { emit } under the hood
294
+
295
+ 'click: left-1' : ({ target, dependencies }) => {
296
+ if ( target?.id === 'save-btn' ) {
297
+ dependencies.analytics.track ( 'save' )
298
+ dependencies.emit ( '@refresh-sidebar' ) // chain into another scene-level handler
299
+ }
300
+ },
301
+
302
+ '@refresh-sidebar' : ({ dependencies }) => {
303
+ dependencies.analytics.track ( 'sidebar-refreshed' )
304
+ }
305
+ ```
306
+
307
+
308
+
309
+
157
310
  ## Links
158
311
  - [Shortcuts documentation - @peter.naydenov/shortcuts](https://github.com/PeterNaydenov/shortcuts)
159
312
  - [History of changes](https://github.com/PeterNaydenov/cuts/blob/main/Changelog.md)
package/dist/cuts.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).cuts=t()}(this,function(){"use strict";var e={_normalizeWithPlugins:function(e,t){return function(e){const n=t.shortcuts;Object.keys(n).forEach(t=>{Object.entries(n[t]).forEach(([o,i])=>{const r=e(o);r!==o&&(delete n[t][o],n[t][r]=i)})})}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:o}=e,i=n.split(":")[0].toLowerCase().trim(),r=o._systemAction(i,"none");let s=n;return-1!==r&&(s=t.plugins[r].shortcutName(n)),s}},_setupPlugin:function(e,t){const{inAPI:n}=e,{currentContext:o,shortcuts:i,exposeShortcut:r,ERROR_EVENT_NAME:s}=t;return function(t){const{prefix:c,_normalizeShortcutName:u,_registerShortcutEvents:l,_listenDOM:a,pluginState:d,deps:p}=t,{resetState:f}=p;d.currentContext=o,d.shortcuts=i,d.exposeShortcut=r,d.ERROR_EVENT_NAME=s;const h={ev:e.ev,extra:e.extra,...p};n._normalizeWithPlugins(u);let m=l(h,d);const g=a(h,d);m>0&&g.start();const v={getPrefix:()=>c,shortcutName:e=>u(e),contextChange:()=>{f(),m=l(h,d),m<1&&g.stop(),m>0&&g.start()},mute:()=>g.stop(),unmute:()=>g.start(),destroy:()=>{g.stop(),f()}};return Object.freeze(v),v}},_systemAction:function(e,t){return function(e,n,o=null){return t.plugins.findIndex(t=>t.getPrefix()===e&&(t[n]&&t[n](o),!0))}},changeContext:function(e,t){const{shortcuts:n,currentContext:o,ERROR_EVENT_NAME:i}=t,{ev:r}=e;return function(e=!1){const s=o.name;if(!e)return r.reset(),void(o.name=null);s!==e&&(n[e]?(n[s]&&r.reset(),o.name=e,t.plugins.forEach(t=>t.contextChange(e)),Object.entries(n[e]).forEach(([e,t])=>{e.includes(":SETUP")||t.forEach(t=>r.on(e,t))}),r.on("*",(...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)})):r.emit(i,`Context '${e}' does not exist`))}},listShortcuts:function(e,t){const n=t.shortcuts;return function(e=null){if(null!=e){const t=n[e];return null==t?null:Object.entries(t).map(([e,t])=>e)}return Object.keys(n).map(e=>{const t={};return t.context=e,t.shortcuts=Object.entries(n[e]).map(([e,t])=>e),t})}},load:function(e,t){const{shortcuts:n,plugins:o}=t,{API:{changeContext:i,getContext:r}}=e;return function(e){const t=r(),s=o.map(e=>e.getPrefix().toUpperCase());let c=!1;Object.entries(e).forEach(([e,i])=>{e===t&&(c=!0),n[e]={},Object.entries(i).forEach(([t,i])=>{let r=t;const c=t.toUpperCase().trim(),u=s.map((e,t)=>c.startsWith(e)?t:null).filter(e=>null!==e);if(u.length){const e=u[0];r=o[e].shortcutName(t)}i instanceof Function&&(i=[i]),n[e][r]=i})}),c&&(i(),i(t))}},unload:function(e,t){const{currentContext:n,shortcuts:o,ERROR_EVENT_NAME:i}=t,{ev:r}=e;return function(e){n.name!==e?o[e]?delete o[e]:r.emit(i,`Context '${e}' does not exist`):r.emit(i,`Context '${e}' can't be removed during is current active context. Change the context first`)}}};function t(e,t){const{ev:n,_specialChars:o,_readKeyEvent:i,extra:r,resetState:s}=e,{currentContext:c,streamKeys:u,listenOptions:l}=t;let a=[],d=null,p=!0,f=!1;const h=()=>p=!1,m=()=>p=!0,g=()=>f=!0,v=()=>!1===p;function y(){const e=a.map(e=>[e.join("+")]),o={wait:h,end:m,ignore:g,isWaiting:v,note:c.note,context:c.name,dependencies:r,options:t.listenOptions,viewport:{X:window.scrollX,Y:window.scrollY,width:window.innerWidth,height:window.innerHeight},type:"key"};if(!p){const t=`KEY:${e.at(-1).join("+")}`;n.emit(t,o),f&&(a=a.slice(0,-1),f=!1)}if(p){const i=`KEY:${e.join(",")}`;n.emit(i,o),f&&(a=a.slice(0,-1),f=!1),a=[],clearTimeout(t.keyIgnore),t.keyIgnore=null,clearTimeout(d),d=null}}function w(n){if(clearTimeout(d),o().hasOwnProperty(n.code))return a.push(i(n,o)),u&&u({key:n.key,context:c.name,note:c.note,dependencies:e.extra}),t.keyIgnore?(clearTimeout(t.keyIgnore),t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait),void a.pop()):p&&a.length===t.maxSequence?(y(),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait))):void(p?d=setTimeout(y,l.keyWait):y())}function x(n){if(!o().hasOwnProperty(n.code)){if(clearTimeout(d),u&&u({key:n.key,context:c.name,note:c.note,dependencies:e.extra}),t.keyIgnore)return clearTimeout(t.keyIgnore),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait));if(a.push(i(n,o)),p&&a.length===t.maxSequence)return y(),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait));p?d=setTimeout(y,l.keyWait):y()}}return{start:function(){t.active||(document.addEventListener("keydown",w),document.addEventListener("keypress",x),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",w),document.removeEventListener("keypress",x),t.active=!1,d&&(clearTimeout(d),d=null),t.keyIgnore&&(clearTimeout(t.keyIgnore),t.keyIgnore=null),a=[],p=!0,f=!1)}}}function n(e){const t=e.toUpperCase(),n=/KEY\s*\:/i.test(t),o=t.indexOf(":");return n?t.includes("SETUP")?"KEY:SETUP":`KEY:${t.slice(o+1).split(",").map(e=>e.trim()).map(e=>e.split("+").map(e=>e.trim()).sort().join("+")).join(",")}`:e}function o(e,t){const{shiftKey:n,altKey:o,ctrlKey:i}=e,r=t(),s=e.code.replace("Key","").replace("Digit",""),c=[];return i&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),r.hasOwnProperty(s)?c.push(r[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function i(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{currentContext:{name:s},shortcuts:c}=t;return null==s?0:(Object.entries(c[s]).forEach(([s,c])=>{if(!r.test(s))return;if("KEY:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++;const u=s.slice(4).split(",").length;t.maxSequence<u&&(t.maxSequence=u)}),o||Object.assign(t.listenOptions,i),n)}function r(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(e,t,n){const{listenOptions:{clickTarget:o}}=t,i=n;return i===document.body?null:o.some(e=>i.hasAttribute(e))?i:s(e,t,i.parentNode)}function c(e,t){const{ev:n,_findTarget:o,_readClickEvent:i,extra:r}=e,{listenOptions:s,currentContext:c}=t;let u=null,l=null,a=null,d=null,p=0;function f(){if(!u)return;const{left:e,top:o,width:s,height:f}=u.getBoundingClientRect(),h=window.scrollX,m=window.scrollY,g=i(l,p),v={target:u,x:l.clientX,y:l.clientY,context:c.name,note:c.note,options:t.listenOptions,event:l,dependencies:r,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:f},position:{x:e,y:o},pagePosition:{x:e+h,y:o+m},type:"click"};n.emit(g,v),a=null,d=null,u=null,l=null,p=0}function h(n){let i=t.maxLeftClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=o(e,t,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(i=1),u&&"A"===u.tagName&&(i=1),l=n,p++,p>=i)return f(),void(i>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}function m(n){let i=t.maxRightClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=o(e,t,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(i=1),u&&"A"===u.tagName&&(i=1),l=n,p++,p>=i)return f(),void(i>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}return{start:function(){t.active||(window.addEventListener("contextmenu",m),document.addEventListener("click",h),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("contextmenu",m),document.removeEventListener("click",h),t.active=!1,d&&(clearTimeout(d),d=null),u=null,l=null,p=0)}}}function u(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),o=["LEFT","MIDDLE","RIGHT"],i=["ALT","SHIFT","CTRL"];let r=null,s=0;const c=[],u=t.indexOf(":");return n?t.includes("SETUP")?"CLICK:SETUP":(t.slice(u+1).trim().split("-").map(e=>e.trim()).forEach(e=>{o.includes(e)?r=e:i.includes(e)?c.push(e):isNaN(e)||(s=e)}),`CLICK:${r}-${s}${c.length>0?"-":""}${c.sort().join("-")}`):e}function l(e,t){const{shiftKey:n,altKey:o,ctrlKey:i,key:r,button:s}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${t}`,u=[];return i&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function a(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{listenOptions:s,currentContext:{name:c},shortcuts:u}=t;return null==c||(Object.entries(u[c]).forEach(([c,u])=>{if(!r.test(c))return;if("CLICK:SETUP"===c){o=!0;const n=u.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:s});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++;const[l,a]=c.slice(6).split("-");"LEFT"===l&&t.maxLeftClicks<a&&(t.maxLeftClicks=a),"RIGHT"===l&&t.maxRightClicks<a&&(t.maxRightClicks=a)}),o||Object.assign(t.listenOptions,i)),n}function d(e,t){const{ev:n}=e;let o=null;function i(e,t,n,o){const{left:i,top:r,width:s,height:c}=n.target.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:n.target,context:t.currentContext.name,note:t.currentContext.note,event:n,dependencies:e.extra,options:t.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:i,y:r},pagePosition:{x:i+u,y:r+l},type:o}}function r(o){const{callbacks:r,typeFn:s}=t;o.target;const c=i(e,t,o,"form-in"),u=`${s(c)}/in`;null!=r[u]&&n.emit(u,c,r[u])}function s(o){const{callbacks:r,typeFn:s}=t,c=i(e,t,o,"form-out"),u=`${s(c)}/out`;null!=r[u]&&n.emit(u,c,r[u])}function c(r){const{callbacks:s,typeFn:c}=t,u=i(e,t,r,"form-instant"),l=c(u),a=t.wait[`${l}`],d=`${l}/instant`;null!=s[d]&&(0!==a?(clearTimeout(o),o=setTimeout(()=>n.emit(d,u,s[d]),a)):n.emit(d,u,s[d]))}return{start:function(){t.active||(document.addEventListener("focusin",r),document.addEventListener("focusout",s),document.addEventListener("input",c),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("focusin",r),document.removeEventListener("focusout",s),document.removeEventListener("input",c),t.active=!1,o&&(clearTimeout(o),o=null))}}}function p(e){const t=e.toUpperCase(),n=/FORM\s*\:/i.test(t),o=t.indexOf(":");return n?`FORM:${t.slice(o+1).trim()}`:e}function f(e,t){const{regex:n,_defaults:o,ev:i}=e,{currentContext:{name:r,note:s},shortcuts:c,callbacks:u,ERROR_EVENT_NAME:l,defaultOptions:a}=t;let d=[],p=[],f=[],h=0;if(null==r)return!1;if(Object.entries(c[r]).forEach(([o,i])=>{if(n.test(o)){if(o.includes("SETUP")){const n=i.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},a);return void Object.assign(t.listenOptions,n)}"FORM:WATCH"===o&&(d=i),"FORM:DEFINE"===o&&(p=i),"FORM:ACTION"===o&&(f=i)}}),0===f.length)return h;const m=new Set;0===p.length&&(p=[o.define]),0===d.length&&(d=[o.watch]);const g=d.map(n=>n({dependencies:e.extra,context:r,note:s,options:t.listenOptions})).reduce((e,t)=>(e.push(t),e),[]);return t.watchList=document.querySelectorAll(g),t.watchList.forEach(n=>{const{left:o,top:i,width:c,height:u}=n.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return m.add(p[0]({target:n,context:r,note:s,dependencies:e.extra,options:t.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:o,y:i},pagePosition:{x:o+l,y:i+a}}))}),t.typeFn=p[0]?p[0]:o.define,f.forEach(n=>{if(!(n instanceof Function))return i.emit(l,"The 'form:action' should be a function."),!1;const o=n({dependencies:e.extra,options:t.listenOptions});if(!(o instanceof Array))return i.emit(l,"Warning: The 'form:action' function should RETURN an array."),!1;o.forEach(({fn:e,type:n,timing:o,wait:r=0})=>{if(m.has(n)&&e instanceof Function){const t=`${n}/${o}`,r=u.hasOwnProperty(t);r?u[t].push(e):u[t]=[e],r||i.on(t,(e,t)=>{t.forEach(t=>{t instanceof Function&&t(e)})})}"instant"===o&&(t.wait[`${n}`]=r)})}),h=Object.keys(t.callbacks).length,h}const h={watch:()=>"input, select, textarea, button, a",define:({target:e})=>"checkbox"===e.type||"radio"===e.type?"checkbox":"button"==e.type||"submit"==e.type?"button":"input"};function m(e,t,n){const{listenOptions:{hoverTarget:o}}=t,i=n;return i!==document.body&&(i!==document&&(o.some(e=>i.hasAttribute(e))?i:m(e,t,i.parentNode)))}function g(e,t){const{ev:n,_findTarget:o,resetState:i,extra:r}=e;function s(i){const s=i.clientX,c=i.clientY,{hovered:u,hoverRectangle:l,listenOptions:a,hoverTimer:d,leaveTimer:p,lastEvent:f,lastHoverTarget:h}=t,m=o(e,t,i.target);if(!function(e,t,n){return!!e&&t>=e.left&&t<=e.right&&n>=e.top&&n<=e.bottom}(l,s,c)&&m!==u){if(u&&!m){if(t.hovered=!1,t.hoverRectangle=null,d&&(clearTimeout(d),t.hoverTimer=null),"off"===f)return;return void(t.leaveTimer=setTimeout(()=>{n.emit("HOVER:OFF",g(u)),t.leaveTimer=null,t.lastEvent="off"},a.wait))}u&&(n.emit("HOVER:OFF",g(u)),t.leaveTimer=null,t.lastEvent="off"),clearTimeout(p),clearTimeout(d),t.hovered=m,t.hoverRectangle=m.getBoundingClientRect(),t.hoverTimer=setTimeout(()=>{n.emit("HOVER:ON",g(m)),t.hoverTimer=null,t.lastHoverTarget=m,t.lastEvent="on"},a.wait)}function g(e){const{left:n,top:o,width:s,height:c}=e.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:e,context:t.currentContext.name,note:t.currentContext.note,event:i,dependencies:r,options:t.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:n,y:o},pagePosition:{x:n+u,y:o+l},type:"hover"}}}return{start:function(){t.active||(document.addEventListener("mousemove",s),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("mousemove",s),i())}}}function v(e){const t=e.toUpperCase(),n=/HOVER\s*\:/i.test(t),o=t.indexOf(":");return n?`HOVER:${t.slice(o+1).trim()}`:e}function y(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r,_defaults:s,ev:c}=e,{currentContext:{name:u},shortcuts:l,ERROR_EVENT_NAME:a}=t;return null==u||(Object.entries(l[u]).forEach(([s,c])=>{if(r.test(s)){if("HOVER:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++}}),o||Object.assign(t.listenOptions,i)),n}function w(e,t){const{ev:n,resetState:o,extra:i}=e;let r=null,s=null;function c(e){e.clientX,e.clientY;const{lastPosition:o,lastDirection:c,listenOptions:u,currentContext:l}=t,{scrollWait:a,endScrollWait:d,minSpace:p}=u;if(!o)return;let f=null;const h=window.scrollX,m=window.scrollY,g=Math.abs(m-o.y),v=Math.abs(h-o.x);if(g<p&&v<p)return;const y=[];g>=p&&(m>o.y?y.push("down"):y.push("up")),v>=p&&(h>o.x?y.push("right"):y.push("left")),f=y[0]||null;const w=e=>({x:h,y:m,direction:e,context:l.name,note:l.note,dependencies:i,options:t.listenOptions,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},type:"scroll"});y.forEach(e=>{const t=`SCROLL:${e.toUpperCase()}`;n.emit(t,w(e))}),clearTimeout(r),clearTimeout(s);const x=y[y.length-1]||null;r=setTimeout(()=>{},a),s=setTimeout(()=>n.emit("SCROLL:END",w(x)),d),t.lastPosition={x:h,y:m},t.lastDirection=f}return{start:function(){t.active||(t.lastPosition={x:window.scrollX,y:window.scrollY},window.addEventListener("scroll",c),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("scroll",c),o())}}}function x(e){const t=e.toUpperCase(),n=/SCROLL\s*\:/i.test(t),o=t.indexOf(":");return n?`SCROLL:${t.slice(o+1).trim()}`:e}function E(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{currentContext:{name:s},shortcuts:c}=t;return null==s||(Object.entries(c[s]).forEach(([s,c])=>{if(r.test(s)){if("SCROLL:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++}}),o||Object.assign(t.listenOptions,i)),n}function O(t={}){const n={},o={},i=function(){let e={"*":[]},t={},n=new Set,o=!1,i="";return{on:function(t,n){e[t]||(e[t]=[]),e[t].push(n)},once:function(e,n){"*"!==e&&(t[e]||(t[e]=[]),t[e].push(n))},off:function(n,o){if(o)return e[n]&&(e[n]=e[n].filter(e=>e!==o)),t[n]&&(t[n]=t[n].filter(e=>e!==o)),e[n]&&0===e[n].length&&delete e[n],void(t[n]&&0===t[n].length&&delete e[n]);t[n]&&delete t[n],e[n]&&delete e[n]},reset:function(){e={"*":[]},t={},n=new Set},emit:function(){const[r,...s]=arguments;function c(t){let o=!1;"*"!==t&&(n.has(t)||(e[t].every(e=>{const t=e(...s);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(o=!0,!1)}),o||e["*"].forEach(e=>e(r,...s))))}if(o&&(console.log(`${i} Event "${r}" was triggered.`),s.length>0&&(console.log("Arguments:"),console.log(...s),console.log("^----"))),"*"!==r){if(t[r]){if(n.has(r))return;t[r].forEach(e=>e(...s)),delete t[r]}e[r]&&c(r)}else Object.keys(e).forEach(e=>c(e))},stop:function(o){if("*"===o){const o=Object.keys(e),i=Object.keys(t);return void(n=new Set([...i,...o]))}n.add(o)},start:function(e){"*"!==e?n.delete(e):n.clear()},debug:function(e,t){o=!!e,t&&"string"==typeof t&&(i=t)}}}(),r={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut,ERROR_EVENT_NAME:t.errorEventName?t.errorEventName:"@shortcuts-error"},s={ev:i,inAPI:n,API:o,extra:{}};return o.enablePlugin=(e,t={})=>{if("function"!=typeof e)return;const o=e(n._setupPlugin,t),i=o.getPrefix(),s=n._systemAction(i,"none");-1===s?(r.plugins.push(o),o.unmute()):(o.destroy(),r.plugins[s].unmute())},o.disablePlugin=e=>{const t=n._systemAction(e,"destroy");-1!==t&&r.plugins.splice(t,1)},o.mutePlugin=e=>n._systemAction(e,"mute"),o.unmutePlugin=e=>n._systemAction(e,"unmute"),o.listPlugins=()=>r.plugins.map(e=>e.getPrefix()),o.getContext=()=>r.currentContext.name,o.getNote=()=>r.currentContext.note,o.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(r.currentContext.note=e)},o.pause=(e="*")=>{const t=n._readShortcutWithPlugins(e);i.stop(t)},o.resume=(e="*")=>{const t=n._readShortcutWithPlugins(e);i.start(t)},o.emit=(e,...t)=>i.emit(n._readShortcutWithPlugins(e),...t),o.listContexts=()=>Object.keys(r.shortcuts),o.setDependencies=e=>Object.assign(s.extra,e),o.getDependencies=()=>s.extra,o.reset=function(){i.reset(),o.changeContext(),r.plugins.forEach(e=>e.destroy()),o.listContexts().map(e=>o.unload(e)),s.extra={},r.exposeShortcut=null},Object.entries(e).forEach(([e,t])=>{e.startsWith("_")?n[e]=t(s,r):o[e]=t(s,r)}),o}var S=Object.freeze({__proto__:null,pluginClick:function(e,t={}){const n={_findTarget:s,_readClickEvent:l,regex:/CLICK\s*\:/i},o={active:!1,maxLeftClicks:1,maxRightClicks:1,defaultOptions:{mouseWait:320,clickTarget:["data-click","href"]},listenOptions:{mouseWait:320,clickTarget:["data-click","href"]},streamKeys:!(!t.streamKeys||"function"!=typeof t.streamKeys)&&t.streamKeys};return n.resetState=function(){},e({prefix:"click",_normalizeShortcutName:u,_registerShortcutEvents:a,_listenDOM:c,pluginState:o,deps:n})},pluginForm:function(e,t={}){const n={_defaults:h,regex:/FORM\s*\:/i},o={callbacks:{},typeFn:"",watchList:[],wait:{},defaultOptions:{},listenOptions:{}};return n.resetState=function(){o.callbacks={},o.typeFn="",o.watchList=[],o.wait={}},e({prefix:"form",_normalizeShortcutName:p,_registerShortcutEvents:f,_listenDOM:d,pluginState:o,deps:n})},pluginHover:function(e,t={}){const n={_findTarget:m,regex:/HOVER\s*\:/i},o={active:!1,hovered:!1,hoverRectangle:null,hoverTimer:null,leaveTimer:null,lastEvent:"",lastHoverTarget:null,defaultOptions:{hoverTarget:["data-hover"],wait:320},listenOptions:{hoverTarget:["data-hover"],wait:320}};return n.resetState=function(){o.active=!1,o.hovered=!1,o.hoverRectangle=null,clearTimeout(o.hoverTimer),clearTimeout(o.leaveTimer),o.hoverTimer=null,o.leaveTimer=null,o.lastHoverTarget=null},e({prefix:"hover",_normalizeShortcutName:v,_registerShortcutEvents:y,_listenDOM:g,pluginState:o,deps:n})},pluginKey:function(e,s={}){const c={_specialChars:r,_readKeyEvent:o,regex:/KEY\s*\:/i},u={active:!1,maxSequence:1,keyIgnore:null,defaultOptions:{keyWait:480},listenOptions:{keyWait:480},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};return c.resetState=function(){u.active=!1,u.keyIgnore=null,u.maxSequence=1},e({prefix:"key",_normalizeShortcutName:n,_registerShortcutEvents:i,_listenDOM:t,pluginState:u,deps:c})},pluginScroll:function(e,t={}){const n={regex:/SCROLL\s*\:/i},o={active:!1,lastPosition:null,lastDirection:null,defaultOptions:{scrollWait:50,endScrollWait:400,minSpace:40},listenOptions:{scrollWait:50,endScrollWait:400,minSpace:40}};return n.resetState=function(){o.active=!1},e({prefix:"scroll",_normalizeShortcutName:x,_registerShortcutEvents:E,_listenDOM:w,pluginState:o,deps:n})},shortcuts:O});function T(e){return e?function(e){let t=e.map(e=>C()),n=t.map(e=>e.promise);t.promises=t;let o=k(Promise.all(n));function i(e){let t="pending";return e.then(()=>t="fulfilled").catch(()=>t="rejected"),t}function r(n,...o){t.forEach((t,r)=>n({value:e[r],done:t.done,cancel:t.cancel,timeout:t.timeout,state:i(t.promise)},...o))}const s={promise:Promise.all(n),promises:t,done:e=>{t.forEach(t=>t.done(e))},cancel:e=>{t.forEach(t=>t.cancel(e))},each:r,onComplete:o,timeout:()=>{}};return s.timeout=P(!0,s),s}(e):C()}function C(){let e,t;const n=new Promise((n,o)=>{e=n,t=o}),o={promise:n,promises:null,done:e,cancel:t,each:()=>{},onComplete:k(n),timeout:()=>{}};return o.timeout=P(!1,o),o.each=(n,...i)=>{n({value:null,done:e,cancel:t,timeout:o.timeout},...i)},o}function k(e){return function(t,n=null){null===n?e.then(e=>t(e)):e.then(e=>t(e),e=>n(e))}}function P(e,t){let n;return n=e?Promise.all(t.promises.map(e=>e.promise)):t.promise,function(e,o){let i,r=new Promise((t,r)=>{i=setTimeout(()=>{t(o),Promise.resolve(n)},e)});return n.then(()=>clearTimeout(i)),t.onComplete=k(Promise.race([n,r])),t}}function b({message:e,level:t,type:n,logLevel:o}){if(0===o)return null;if(o<t)return null;const i=`[Debug]: ${e}`;switch(n){case"warn":console.warn(i);break;case"error":console.error(i);break;default:console.log(i)}return i}function R(e={},t=b){return function({message:n,type:o,level:i,...r}){const{level:s,type:c,defaultMessageLevel:u}=Object.assign({},{level:1e3,type:"log",defaultMessageLevel:1},e);return o||(o=c),i||(i=u),t({message:n,type:o,level:i,logLevel:s,...r})}}function*L(e,t,n,o){let i=null,r=!0;if(null===e)return yield*o.map(e=>[e,"show"]),void(yield[n,"show"]);if(0!==o.length){if(o.includes(e)){for(let t=o.indexOf(e)+1;t<o.length;t++)yield[o[t],"show"];return void(yield[n,"show"])}if(!t)return yield[e,"hide"],void(yield*o.map(e=>[e,"show"]));if(o.every((e,n)=>t[n]===o[n]&&(i=n,!0)),null==i)return yield[e,"hide"],t.reverse(),yield*t.map(e=>[e,"hide"]),yield*o.map(e=>[e,"show"]),void(yield[n,"show"]);yield[e,"hide"];for(let e=t.length;e>i+1;e--)yield[t[e-1],"hide"];for(let e=i+1;e<o.length;e++)yield[o[e],"show"];yield[n,"show"]}else{if(yield[e,"hide"],t.includes(n)){let e=t.indexOf(n),o=t.filter((t,n)=>n>e);o.reverse(),yield*o.map(e=>[e,"hide"]),r=!1}else{let e=[...t];e.reverse(),yield*e.map(e=>[e,"hide"])}r&&(yield[n,"show"])}}function _(e){return function(t,...n){const{askForPromise:o,deps:i}=e;return function(){const e=o();return t({task:e,dependencies:i()},...n),e.promise}}}return T.sequence=function(e,...t){const n=T(),o=[];const i=function*(e){for(const t of e)yield t}(e);return function e(t,...r){t.done?n.done(o):t.value(...r).then(t=>{o.push(t),e(i.next(),...r,t)})}(i.next(),...t),n},T.all=function(e,...t){const n=T(),o=[],i=e.map((e,n)=>"function"==typeof e?e(...t).then(e=>o[n]=e):e.then(e=>o[n]=e));return Promise.all(i).then(()=>n.done(o)),n},function(e={logLevel:0}){const t=O({errorEventName:"@app-error"}),n=R({level:e.logLevel||1},e=>{const{type:n}=e;"error"===n&&t.emit("@app-error",e)}),o={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},i={},r={shortcutMngr:t,findInstructions:L,askForPromise:T,setInstruction:_({askForPromise:T,deps:t.getDependencies}),log:n};return i.hide=function(e,t){return function(n=1){const{askForPromise:o,shortcutMngr:i,setInstruction:r}=e,{currentScene:s,currentParents:c,scenes:u}=t,l=o(),a=[],d=c.length>0;let p;return i.pause(),a.push(r(u[s].hide)),d||(t.currentScene=null),d&&"*"===n&&[...c].reverse().forEach(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(r(u[e].hide))}),d&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(r(u[e].hide))}),(n=o.sequence(a)).onComplete(()=>{i.changeContext(t.currentScene),l.done()}),l.promise}}(r,o),i.listShortcuts=function(e,t){return function(e){const{scenes:n,sceneNames:o}=t;if(!o.has(e))return null;const{show:i,hide:r,parents:s,beforeUnload:c,afterLoad:u,...l}=n[e];return Object.keys(l)}}(0,o),i.setScenes=function(e,t){return function(n){const{shortcutMngr:o,log:i}=e;n.forEach(e=>{if(null==e)return;const{name:n,scene:r}=e;if(!n)return void i({message:"Scene name is not defined",level:1,type:"error"});if(null==r)return void i({message:`Scene ${n} is not defined`,level:1,type:"error"});r.parents||(r.parents=[]),t.scenes[n]=r,t.sceneNames.add(n);const{show:s,hide:c,parents:u,...l}=r,a={};a[n]=l,o.load(a)})}}(r,o),i.show=function(e,t){return function({scene:n,options:o={ssr:!1}},...i){const{shortcutMngr:r,askForPromise:s,log:c,findInstructions:u,setInstruction:l}=e,a=s(),d=s(),{opened:p,scenes:f,sceneNames:h,currentScene:m}=t;return m&&"function"==typeof f[m].beforeHide?(0,f[m].beforeHide)({done:d.done,dependencies:r.getDependencies()}):d.done(!0),d.onComplete(e=>{if(!e)return a.done(),a.promise;if(!h.has(n))return c({message:`Scene "${n}" is not available.`,level:1,type:"error"}),a.done(),a.promise;if(!p&&o.ssr)return t.opened=!0,t.currentScene=n,r.changeContext(n),a.done(),a.promise;const{show:d,parents:m=[]}=f[n];if("*"===m[0])return l(d,...i)().then(()=>a.done()),t.currentParents.push(t.currentScene),t.currentScene=n,a.promise;if(0!==m.length&&!m.every(e=>h.has(e)))return c({message:`Some of '${n}' parent scenes are not set.`,level:1,type:"error"}),a.done(),a.promise;function g([e,n]){if("show"===n)t.currentScene&&(t.currentParents=[...f[t.currentScene].parents]),t.currentScene=e;else{let n=f[e].parents.at(-1);t.currentScene=n}return f[e][n]}t.currentParents||(t.currentParents=[]);const v=u(t.currentScene,t.currentParents,n,m),y=[];for(let e of v){const t=g(e);y.push(l(t,...i))}s.sequence(y).onComplete(()=>{t.opened=!0,t.currentScene=n,t.currentParents=f[n].parents||null,r.changeContext(n),"function"==typeof f[n].afterShow&&f[n].afterShow({dependencies:r.getDependencies(),done:()=>{}}),a.done()})}),a.promise}}(r,o),i.jump=function(e,t){return function({scene:n},...o){return e.jumpStack.push(e.currentScene),t({scene:n},...o)}}(o,i.show),i.jumpBack=function(e,t){return function({hops:n}={hops:1},...o){for(let t=0;t<n-1;t++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const i=e.jumpStack.pop();return t({scene:i},...o)}}(o,i.show),i.jumpsReset=function(e){return function(){e.jumpStack=[]}}(o),i.loadPlugins=async function(e){const t=e.map(e=>`plugin${e}`),n=await Promise.resolve().then(function(){return S});return t.map(e=>n[e])},i.setDependencies=e=>t.setDependencies(e),i.getDependencies=()=>t.getDependencies(),i.setNote=e=>t.setNote(e),i.listScenes=()=>[...o.sceneNames],i.enablePlugin=(e,n)=>t.enablePlugin(e,n),i.disablePlugin=e=>t.disablePlugin(e),i.getState=()=>({scene:o.currentScene,parents:o.currentParents,opened:o.opened}),i.emit=(e,...n)=>t.emit(e,...n),i}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).cuts=t()}(this,function(){"use strict";var e={_normalizeWithPlugins:function(e,t){return function(e){const n=t.shortcuts;Object.keys(n).forEach(t=>{Object.entries(n[t]).forEach(([o,i])=>{const r=e(o);r!==o&&(delete n[t][o],n[t][r]=i)})})}},_readShortcutWithPlugins:function(e,t){return function(n){const{inAPI:o}=e,i=n.split(":")[0].toLowerCase().trim(),r=o._systemAction(i,"none");let s=n;return-1!==r&&(s=t.plugins[r].shortcutName(n)),s}},_setupPlugin:function(e,t){const{inAPI:n}=e,{currentContext:o,shortcuts:i,exposeShortcut:r,ERROR_EVENT_NAME:s}=t;return function(t){const{prefix:c,_normalizeShortcutName:u,_registerShortcutEvents:l,_listenDOM:a,pluginState:d,deps:p}=t,{resetState:f}=p;d.currentContext=o,d.shortcuts=i,d.exposeShortcut=r,d.ERROR_EVENT_NAME=s;const h={ev:e.ev,extra:e.extra,...p};n._normalizeWithPlugins(u);let m=l(h,d);const g=a(h,d);m>0&&g.start();const v={getPrefix:()=>c,shortcutName:e=>u(e),contextChange:()=>{f(),m=l(h,d),m<1&&g.stop(),m>0&&g.start()},mute:()=>g.stop(),unmute:()=>g.start(),destroy:()=>{g.stop(),f()}};return Object.freeze(v),v}},_systemAction:function(e,t){return function(e,n,o=null){return t.plugins.findIndex(t=>t.getPrefix()===e&&(t[n]&&t[n](o),!0))}},changeContext:function(e,t){const{shortcuts:n,currentContext:o,ERROR_EVENT_NAME:i}=t,{ev:r}=e;return function(e=!1){const s=o.name;if(!e)return r.reset(),void(o.name=null);s!==e&&(n[e]?(n[s]&&r.reset(),o.name=e,t.plugins.forEach(t=>t.contextChange(e)),Object.entries(n[e]).forEach(([e,t])=>{e.includes(":SETUP")||t.forEach(t=>r.on(e,t))}),r.on("*",(...e)=>{t.exposeShortcut&&t.exposeShortcut(...e)})):r.emit(i,`Context '${e}' does not exist`))}},listShortcuts:function(e,t){const n=t.shortcuts;return function(e=null){if(null!=e){const t=n[e];return null==t?null:Object.entries(t).map(([e,t])=>e)}return Object.keys(n).map(e=>{const t={};return t.context=e,t.shortcuts=Object.entries(n[e]).map(([e,t])=>e),t})}},load:function(e,t){const{shortcuts:n,plugins:o}=t,{API:{changeContext:i,getContext:r}}=e;return function(e){const t=r(),s=o.map(e=>e.getPrefix().toUpperCase());let c=!1;Object.entries(e).forEach(([e,i])=>{e===t&&(c=!0),n[e]={},Object.entries(i).forEach(([t,i])=>{let r=t;const c=t.toUpperCase().trim(),u=s.map((e,t)=>c.startsWith(e)?t:null).filter(e=>null!==e);if(u.length){const e=u[0];r=o[e].shortcutName(t)}i instanceof Function&&(i=[i]),n[e][r]=i})}),c&&(i(),i(t))}},unload:function(e,t){const{currentContext:n,shortcuts:o,ERROR_EVENT_NAME:i}=t,{ev:r}=e;return function(e){n.name!==e?o[e]?delete o[e]:r.emit(i,`Context '${e}' does not exist`):r.emit(i,`Context '${e}' can't be removed during is current active context. Change the context first`)}}};function t(e,t){const{ev:n,_specialChars:o,_readKeyEvent:i,extra:r,resetState:s}=e,{currentContext:c,streamKeys:u,listenOptions:l}=t;let a=[],d=null,p=!0,f=!1;const h=()=>p=!1,m=()=>p=!0,g=()=>f=!0,v=()=>!1===p;function y(){const e=a.map(e=>[e.join("+")]),o={wait:h,end:m,ignore:g,isWaiting:v,note:c.note,context:c.name,dependencies:r,options:t.listenOptions,viewport:{X:window.scrollX,Y:window.scrollY,width:window.innerWidth,height:window.innerHeight},type:"key"};if(!p){const t=`KEY:${e.at(-1).join("+")}`;n.emit(t,o),f&&(a=a.slice(0,-1),f=!1)}if(p){const i=`KEY:${e.join(",")}`;n.emit(i,o),f&&(a=a.slice(0,-1),f=!1),a=[],clearTimeout(t.keyIgnore),t.keyIgnore=null,clearTimeout(d),d=null}}function w(n){if(clearTimeout(d),o().hasOwnProperty(n.code))return a.push(i(n,o)),u&&u({key:n.key,context:c.name,note:c.note,dependencies:e.extra}),t.keyIgnore?(clearTimeout(t.keyIgnore),t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait),void a.pop()):p&&a.length===t.maxSequence?(y(),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait))):void(p?d=setTimeout(y,l.keyWait):y())}function x(n){if(!o().hasOwnProperty(n.code)){if(clearTimeout(d),u&&u({key:n.key,context:c.name,note:c.note,dependencies:e.extra}),t.keyIgnore)return clearTimeout(t.keyIgnore),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait));if(a.push(i(n,o)),p&&a.length===t.maxSequence)return y(),void(t.keyIgnore=setTimeout(()=>t.keyIgnore=null,l.keyWait));p?d=setTimeout(y,l.keyWait):y()}}return{start:function(){t.active||(document.addEventListener("keydown",w),document.addEventListener("keypress",x),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("keydown",w),document.removeEventListener("keypress",x),t.active=!1,d&&(clearTimeout(d),d=null),t.keyIgnore&&(clearTimeout(t.keyIgnore),t.keyIgnore=null),a=[],p=!0,f=!1)}}}function n(e){const t=e.toUpperCase(),n=/KEY\s*\:/i.test(t),o=t.indexOf(":");return n?t.includes("SETUP")?"KEY:SETUP":`KEY:${t.slice(o+1).split(",").map(e=>e.trim()).map(e=>e.split("+").map(e=>e.trim()).sort().join("+")).join(",")}`:e}function o(e,t){const{shiftKey:n,altKey:o,ctrlKey:i}=e,r=t(),s=e.code.replace("Key","").replace("Digit",""),c=[];return i&&c.push("CTRL"),n&&c.push("SHIFT"),o&&c.push("ALT"),r.hasOwnProperty(s)?c.push(r[s].toUpperCase()):["ControlLeft","ControlRight","ShiftLeft","ShiftRight","AltLeft","AltRight","Meta"].includes(s)||c.push(s.toUpperCase()),c.sort()}function i(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{currentContext:{name:s},shortcuts:c}=t;return null==s?0:(Object.entries(c[s]).forEach(([s,c])=>{if(!r.test(s))return;if("KEY:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++;const u=s.slice(4).split(",").length;t.maxSequence<u&&(t.maxSequence=u)}),o||Object.assign(t.listenOptions,i),n)}function r(){return{ArrowLeft:"LEFT",ArrowUp:"UP",ArrowRight:"RIGHT",ArrowDown:"DOWN",Enter:"ENTER",NumpadEnter:"ENTER",Escape:"ESC",Backspace:"BACKSPACE",Space:"SPACE",Tab:"TAB",Backquote:"`",BracketLeft:"[",BracketRight:"]",Equal:"=",Slash:"/",Backslash:"\\",IntlBackslash:"`",F1:"F1",F2:"F2",F3:"F3",F4:"F4",F5:"F5",F6:"F6",F7:"F7",F8:"F8",F9:"F9",F10:"F10",F11:"F11",F12:"F12"}}function s(e,t,n){const{listenOptions:{clickTarget:o}}=t,i=n;return i===document.body?null:o.some(e=>i.hasAttribute(e))?i:s(e,t,i.parentNode)}function c(e,t){const{ev:n,_findTarget:o,_readClickEvent:i,extra:r}=e,{listenOptions:s,currentContext:c}=t;let u=null,l=null,a=null,d=null,p=0;function f(){if(!u)return;const{left:e,top:o,width:s,height:f}=u.getBoundingClientRect(),h=window.scrollX,m=window.scrollY,g=i(l,p),v={target:u,x:l.clientX,y:l.clientY,context:c.name,note:c.note,options:t.listenOptions,event:l,dependencies:r,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:f},position:{x:e,y:o},pagePosition:{x:e+h,y:o+m},type:"click"};n.emit(g,v),a=null,d=null,u=null,l=null,p=0}function h(n){let i=t.maxLeftClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=o(e,t,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(i=1),u&&"A"===u.tagName&&(i=1),l=n,p++,p>=i)return f(),void(i>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}function m(n){let i=t.maxRightClicks;if(clearTimeout(a),d)return clearTimeout(d),void(d=setTimeout(()=>d=null,s.mouseWait));if(u=o(e,t,n.target),null!=u){if(u&&u.dataset.hasOwnProperty("quickClick")&&(i=1),u&&"A"===u.tagName&&(i=1),l=n,p++,p>=i)return f(),void(i>1&&(d=setTimeout(()=>d=null,s.mouseWait)));a=setTimeout(f,s.mouseWait)}}return{start:function(){t.active||(window.addEventListener("contextmenu",m),document.addEventListener("click",h),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("contextmenu",m),document.removeEventListener("click",h),t.active=!1,d&&(clearTimeout(d),d=null),u=null,l=null,p=0)}}}function u(e){const t=e.toUpperCase(),n=/CLICK\s*\:/i.test(t),o=["LEFT","MIDDLE","RIGHT"],i=["ALT","SHIFT","CTRL"];let r=null,s=0;const c=[],u=t.indexOf(":");return n?t.includes("SETUP")?"CLICK:SETUP":(t.slice(u+1).trim().split("-").map(e=>e.trim()).forEach(e=>{o.includes(e)?r=e:i.includes(e)?c.push(e):isNaN(e)||(s=e)}),`CLICK:${r}-${s}${c.length>0?"-":""}${c.sort().join("-")}`):e}function l(e,t){const{shiftKey:n,altKey:o,ctrlKey:i,key:r,button:s}=e,c=`CLICK:${["LEFT","MIDDLE","RIGHT"][s]}-${t}`,u=[];return i&&u.push("CTRL"),n&&u.push("SHIFT"),o&&u.push("ALT"),u.length>0?`${c}${u.length>0?"-":""}${u.sort().join("-")}`:`${c}`}function a(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{listenOptions:s,currentContext:{name:c},shortcuts:u}=t;return null==c||(Object.entries(u[c]).forEach(([c,u])=>{if(!r.test(c))return;if("CLICK:SETUP"===c){o=!0;const n=u.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:s});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++;const[l,a]=c.slice(6).split("-");"LEFT"===l&&t.maxLeftClicks<a&&(t.maxLeftClicks=a),"RIGHT"===l&&t.maxRightClicks<a&&(t.maxRightClicks=a)}),o||Object.assign(t.listenOptions,i)),n}function d(e,t){const{ev:n}=e;let o=null;function i(e,t,n,o){const{extra:i}=e,{left:r,top:s,width:c,height:u}=n.target.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return{target:n.target,context:t.currentContext.name,note:t.currentContext.note,event:n,dependencies:i,options:t.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:r,y:s},pagePosition:{x:r+l,y:s+a},type:o}}function r(o){const{callbacks:r,typeFn:s}=t;o.target;const c=i(e,t,o,"form"),u=`${s(c)}/in`;null!=r[u]&&n.emit(u,c,r[u])}function s(o){const{callbacks:r,typeFn:s}=t,c=i(e,t,o,"form"),u=`${s(c)}/out`;null!=r[u]&&n.emit(u,c,r[u])}function c(r){const{callbacks:s,typeFn:c}=t,u=i(e,t,r,"form"),l=c(u),a=t.wait[`${l}`],d=`${l}/instant`;null!=s[d]&&(0!==a?(clearTimeout(o),o=setTimeout(()=>n.emit(d,u,s[d]),a)):n.emit(d,u,s[d]))}return{start:function(){t.active||(document.addEventListener("focusin",r),document.addEventListener("focusout",s),document.addEventListener("input",c),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("focusin",r),document.removeEventListener("focusout",s),document.removeEventListener("input",c),t.active=!1,o&&(clearTimeout(o),o=null))}}}function p(e){const t=e.toUpperCase(),n=/FORM\s*\:/i.test(t),o=t.indexOf(":");return n?`FORM:${t.slice(o+1).trim()}`:e}function f(e,t){const{regex:n,_defaults:o,ev:i}=e,{currentContext:{name:r,note:s},shortcuts:c,callbacks:u,ERROR_EVENT_NAME:l,defaultOptions:a}=t;let d=[],p=[],f=[],h=0;if(null==r)return!1;if(Object.entries(c[r]).forEach(([o,i])=>{if(n.test(o)){if(o.includes("SETUP")){const n=i.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},a);return void Object.assign(t.listenOptions,n)}"FORM:WATCH"===o&&(d=i),"FORM:DEFINE"===o&&(p=i),"FORM:ACTION"===o&&(f=i)}}),0===f.length)return h;const m=new Set;0===p.length&&(p=[o.define]),0===d.length&&(d=[o.watch]);const g=d.map(n=>n({dependencies:e.extra,context:r,note:s,options:t.listenOptions})).reduce((e,t)=>(e.push(t),e),[]);return t.watchList=document.querySelectorAll(g),t.watchList.forEach(n=>{const{left:o,top:i,width:c,height:u}=n.getBoundingClientRect(),l=window.scrollX,a=window.scrollY;return m.add(p[0]({target:n,context:r,note:s,dependencies:e.extra,options:t.listenOptions,viewport:{X:l,Y:a,width:window.innerWidth,height:window.innerHeight},sizes:{width:c,height:u},position:{x:o,y:i},pagePosition:{x:o+l,y:i+a}}))}),t.typeFn=p[0]?p[0]:o.define,f.forEach(n=>{if(!(n instanceof Function))return i.emit(l,"The 'form:action' should be a function."),!1;const o=n({dependencies:e.extra,options:t.listenOptions});if(!(o instanceof Array))return i.emit(l,"Warning: The 'form:action' function should RETURN an array."),!1;o.forEach(({fn:e,type:n,timing:o,wait:r=0})=>{if(m.has(n)&&e instanceof Function){const t=`${n}/${o}`,r=u.hasOwnProperty(t);r?u[t].push(e):u[t]=[e],r||i.on(t,(e,t)=>{t.forEach(t=>{t instanceof Function&&t(e)})})}"instant"===o&&(t.wait[`${n}`]=r)})}),h=Object.keys(t.callbacks).length,h}const h={watch:()=>"input, select, textarea, button, a",define:({target:e})=>"checkbox"===e.type||"radio"===e.type?"checkbox":"button"==e.type||"submit"==e.type?"button":"input"};function m(e,t,n){const{listenOptions:{hoverTarget:o}}=t,i=n;return i!==document.body&&(i!==document&&(o.some(e=>i.hasAttribute(e))?i:m(e,t,i.parentNode)))}function g(e,t){const{ev:n,_findTarget:o,resetState:i,extra:r}=e;function s(i){const s=i.clientX,c=i.clientY,{hovered:u,hoverRectangle:l,listenOptions:a,hoverTimer:d,leaveTimer:p,lastEvent:f,lastHoverTarget:h}=t,m=o(e,t,i.target);if(!function(e,t,n){return!!e&&t>=e.left&&t<=e.right&&n>=e.top&&n<=e.bottom}(l,s,c)&&m!==u){if(u&&!m){if(t.hovered=!1,t.hoverRectangle=null,d&&(clearTimeout(d),t.hoverTimer=null),"off"===f)return;return void(t.leaveTimer=setTimeout(()=>{n.emit("HOVER:OFF",g(u)),t.leaveTimer=null,t.lastEvent="off"},a.wait))}u&&(n.emit("HOVER:OFF",g(u)),t.leaveTimer=null,t.lastEvent="off"),clearTimeout(p),clearTimeout(d),t.hovered=m,t.hoverRectangle=m.getBoundingClientRect(),t.hoverTimer=setTimeout(()=>{n.emit("HOVER:ON",g(m)),t.hoverTimer=null,t.lastHoverTarget=m,t.lastEvent="on"},a.wait)}function g(e){const{left:n,top:o,width:s,height:c}=e.getBoundingClientRect(),u=window.scrollX,l=window.scrollY;return{target:e,context:t.currentContext.name,note:t.currentContext.note,event:i,dependencies:r,options:t.listenOptions,viewport:{X:u,Y:l,width:window.innerWidth,height:window.innerHeight},sizes:{width:s,height:c},position:{x:n,y:o},pagePosition:{x:n+u,y:o+l},type:"hover"}}}return{start:function(){t.active||(document.addEventListener("mousemove",s),t.active=!0)},stop:function(){t.active&&(document.removeEventListener("mousemove",s),i())}}}function v(e){const t=e.toUpperCase(),n=/HOVER\s*\:/i.test(t),o=t.indexOf(":");return n?`HOVER:${t.slice(o+1).trim()}`:e}function y(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r,_defaults:s,ev:c}=e,{currentContext:{name:u},shortcuts:l,ERROR_EVENT_NAME:a}=t;return null==u||(Object.entries(l[u]).forEach(([s,c])=>{if(r.test(s)){if("HOVER:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++}}),o||Object.assign(t.listenOptions,i)),n}function w(e,t){const{ev:n,resetState:o,extra:i}=e;let r=null,s=null;function c(e){e.clientX,e.clientY;const{lastPosition:o,lastDirection:c,listenOptions:u,currentContext:l}=t,{scrollWait:a,endScrollWait:d,minSpace:p}=u;if(!o)return;let f=null;const h=window.scrollX,m=window.scrollY,g=Math.abs(m-o.y),v=Math.abs(h-o.x);if(g<p&&v<p)return;const y=[];g>=p&&(m>o.y?y.push("down"):y.push("up")),v>=p&&(h>o.x?y.push("right"):y.push("left")),f=y[0]||null;const w=e=>({x:h,y:m,direction:e,context:l.name,note:l.note,dependencies:i,options:t.listenOptions,viewport:{X:h,Y:m,width:window.innerWidth,height:window.innerHeight},type:"scroll"});y.forEach(e=>{const t=`SCROLL:${e.toUpperCase()}`;n.emit(t,w(e))}),clearTimeout(r),clearTimeout(s);const x=y[y.length-1]||null;r=setTimeout(()=>{},a),s=setTimeout(()=>n.emit("SCROLL:END",w(x)),d),t.lastPosition={x:h,y:m},t.lastDirection=f}return{start:function(){t.active||(t.lastPosition={x:window.scrollX,y:window.scrollY},window.addEventListener("scroll",c),t.active=!0)},stop:function(){t.active&&(window.removeEventListener("scroll",c),o())}}}function x(e){const t=e.toUpperCase(),n=/SCROLL\s*\:/i.test(t),o=t.indexOf(":");return n?`SCROLL:${t.slice(o+1).trim()}`:e}function O(e,t){let n=0,o=!1;const i=t.defaultOptions,{regex:r}=e,{currentContext:{name:s},shortcuts:c}=t;return null==s||(Object.entries(c[s]).forEach(([s,c])=>{if(r.test(s)){if("SCROLL:SETUP"===s){o=!0;const n=c.reduce((n,o)=>{const i=o({dependencies:e.extra,defaults:structuredClone(t.defaultOptions),options:t.listenOptions});return Object.assign(n,i)},i);return void Object.assign(t.listenOptions,n)}n++}}),o||Object.assign(t.listenOptions,i)),n}function E(t={}){const n={},o={},i=function(){let e=Object.assign(Object.create(null),{"*":[]}),t=Object.create(null),n=new Set,o=!1,i="";return{on:function(t,n){e[t]||(e[t]=[]),e[t].push(n)},once:function(e,n){"*"!==e&&(t[e]||(t[e]=[]),t[e].push(n))},off:function(n,o){if(o)return e[n]&&(e[n]=e[n].filter(e=>e!==o)),t[n]&&(t[n]=t[n].filter(e=>e!==o)),"*"!==n&&e[n]&&0===e[n].length&&delete e[n],void(t[n]&&0===t[n].length&&delete t[n]);t[n]&&delete t[n],"*"===n?e["*"]=[]:e[n]&&delete e[n]},reset:function(){e=Object.assign(Object.create(null),{"*":[]}),t=Object.create(null),n=new Set},emit:function(){const[r,...s]=arguments;function c(t){let o=!1;"*"!==t&&(n.has(t)||(e[t].every(e=>{const t=e(...s);return"string"!=typeof t||"STOP"!==t.toUpperCase()||(o=!0,!1)}),o||e["*"].forEach(e=>e(r,...s))))}if(o&&(console.log(`${i} Event "${String(r)}" was triggered.`),s.length>0&&(console.log("Arguments:"),console.log(...s),console.log("^----"))),"*"!==r){if(t[r]){if(n.has(r))return;const o=t[r];delete t[r],o.forEach(e=>e(...s)),e[r]||e["*"].forEach(e=>e(r,...s))}e[r]&&c(r)}else Reflect.ownKeys(e).forEach(e=>c(e))},stop:function(o){if("*"===o){const o=Reflect.ownKeys(e),i=Reflect.ownKeys(t);return void(n=new Set([...i,...o]))}n.add(o)},start:function(e){"*"!==e?n.delete(e):n.clear()},debug:function(e,t){o=!!e,t&&"string"==typeof t&&(i=t)}}}(),r={currentContext:{name:null,note:null},shortcuts:{},plugins:[],exposeShortcut:!(!t.onShortcut||"function"!=typeof t.onShortcut)&&t.onShortcut,ERROR_EVENT_NAME:t.errorEventName?t.errorEventName:"@shortcuts-error"},s={ev:i,inAPI:n,API:o,extra:{emit:i.emit}};return o.enablePlugin=(e,t={})=>{if("function"!=typeof e)return;const o=e(n._setupPlugin,t),i=o.getPrefix(),s=n._systemAction(i,"none");-1===s?(r.plugins.push(o),o.unmute()):(o.destroy(),r.plugins[s].unmute())},o.disablePlugin=e=>{const t=n._systemAction(e,"destroy");-1!==t&&r.plugins.splice(t,1)},o.mutePlugin=e=>n._systemAction(e,"mute"),o.unmutePlugin=e=>n._systemAction(e,"unmute"),o.listPlugins=()=>r.plugins.map(e=>e.getPrefix()),o.getContext=()=>r.currentContext.name,o.getNote=()=>r.currentContext.note,o.setNote=(e=null)=>{"string"!=typeof e&&null!=e||(r.currentContext.note=e)},o.pause=(e="*")=>{const t=n._readShortcutWithPlugins(e);i.stop(t)},o.resume=(e="*")=>{const t=n._readShortcutWithPlugins(e);i.start(t)},o.emit=(e,...t)=>i.emit(n._readShortcutWithPlugins(e),{dependencies:s.extra,type:"custom"},...t),o.listContexts=()=>Object.keys(r.shortcuts),o.setDependencies=e=>Object.assign(s.extra,e),o.getDependencies=()=>s.extra,o.reset=function(){i.reset(),o.changeContext(),r.plugins.forEach(e=>e.destroy()),o.listContexts().map(e=>o.unload(e)),s.extra={emit:i.emit},r.exposeShortcut=null},Object.entries(e).forEach(([e,t])=>{e.startsWith("_")?n[e]=t(s,r):o[e]=t(s,r)}),o}var S=Object.freeze({__proto__:null,pluginClick:function(e,t={}){const n={_findTarget:s,_readClickEvent:l,regex:/CLICK\s*\:/i},o={active:!1,maxLeftClicks:1,maxRightClicks:1,defaultOptions:{mouseWait:320,clickTarget:["data-click","href"]},listenOptions:{mouseWait:320,clickTarget:["data-click","href"]},streamKeys:!(!t.streamKeys||"function"!=typeof t.streamKeys)&&t.streamKeys};return n.resetState=function(){},e({prefix:"click",_normalizeShortcutName:u,_registerShortcutEvents:a,_listenDOM:c,pluginState:o,deps:n})},pluginForm:function(e,t={}){const n={_defaults:h,regex:/FORM\s*\:/i},o={callbacks:{},typeFn:"",watchList:[],wait:{},defaultOptions:{},listenOptions:{}};return n.resetState=function(){o.callbacks={},o.typeFn="",o.watchList=[],o.wait={}},e({prefix:"form",_normalizeShortcutName:p,_registerShortcutEvents:f,_listenDOM:d,pluginState:o,deps:n})},pluginHover:function(e,t={}){const n={_findTarget:m,regex:/HOVER\s*\:/i},o={active:!1,hovered:!1,hoverRectangle:null,hoverTimer:null,leaveTimer:null,lastEvent:"",lastHoverTarget:null,defaultOptions:{hoverTarget:["data-hover"],wait:320},listenOptions:{hoverTarget:["data-hover"],wait:320}};return n.resetState=function(){o.active=!1,o.hovered=!1,o.hoverRectangle=null,clearTimeout(o.hoverTimer),clearTimeout(o.leaveTimer),o.hoverTimer=null,o.leaveTimer=null,o.lastHoverTarget=null},e({prefix:"hover",_normalizeShortcutName:v,_registerShortcutEvents:y,_listenDOM:g,pluginState:o,deps:n})},pluginKey:function(e,s={}){const c={_specialChars:r,_readKeyEvent:o,regex:/KEY\s*\:/i},u={active:!1,maxSequence:1,keyIgnore:null,defaultOptions:{keyWait:480},listenOptions:{keyWait:480},streamKeys:!(!s.streamKeys||"function"!=typeof s.streamKeys)&&s.streamKeys};return c.resetState=function(){u.active=!1,u.keyIgnore=null,u.maxSequence=1},e({prefix:"key",_normalizeShortcutName:n,_registerShortcutEvents:i,_listenDOM:t,pluginState:u,deps:c})},pluginScroll:function(e,t={}){const n={regex:/SCROLL\s*\:/i},o={active:!1,lastPosition:null,lastDirection:null,defaultOptions:{scrollWait:50,endScrollWait:400,minSpace:40},listenOptions:{scrollWait:50,endScrollWait:400,minSpace:40}};return n.resetState=function(){o.active=!1},e({prefix:"scroll",_normalizeShortcutName:x,_registerShortcutEvents:O,_listenDOM:w,pluginState:o,deps:n})},shortcuts:E});function T(e){return e?function(e){let t=e.map(e=>C()),n=t.map(e=>e.promise);t.promises=t;let o=k(Promise.all(n));function i(e){let t="pending";return e.then(()=>t="fulfilled").catch(()=>t="rejected"),t}function r(n,...o){t.forEach((t,r)=>n({value:e[r],done:t.done,cancel:t.cancel,timeout:t.timeout,state:i(t.promise)},...o))}const s={promise:Promise.all(n),promises:t,done:e=>{t.forEach(t=>t.done(e))},cancel:e=>{t.forEach(t=>t.cancel(e))},each:r,onComplete:o,timeout:()=>{}};return s.timeout=b(!0,s),s}(e):C()}function C(){let e,t;const n=new Promise((n,o)=>{e=n,t=o}),o={promise:n,promises:null,done:e,cancel:t,each:()=>{},onComplete:k(n),timeout:()=>{}};return o.timeout=b(!1,o),o.each=(n,...i)=>{n({value:null,done:e,cancel:t,timeout:o.timeout},...i)},o}function k(e){return function(t,n=null){null===n?e.then(e=>t(e)):e.then(e=>t(e),e=>n(e))}}function b(e,t){let n;return n=e?Promise.all(t.promises.map(e=>e.promise)):t.promise,function(e,o){let i,r=new Promise((t,r)=>{i=setTimeout(()=>{t(o),Promise.resolve(n)},e)});return n.then(()=>clearTimeout(i)),t.onComplete=k(Promise.race([n,r])),t}}function P({message:e,level:t,type:n,logLevel:o}){if(0===o)return null;if(o<t)return null;const i=`[Debug]: ${e}`;switch(n){case"warn":console.warn(i);break;case"error":console.error(i);break;default:console.log(i)}return i}function R(e={},t=P){return function({message:n,type:o,level:i,...r}){const{level:s,type:c,defaultMessageLevel:u}=Object.assign({},{level:1e3,type:"log",defaultMessageLevel:1},e);return o||(o=c),i||(i=u),t({message:n,type:o,level:i,logLevel:s,...r})}}function*L(e,t,n,o){let i=null,r=!0;if(null===e)return yield*o.map(e=>[e,"show"]),void(yield[n,"show"]);if(0!==o.length){if(o.includes(e)){for(let t=o.indexOf(e)+1;t<o.length;t++)yield[o[t],"show"];return void(yield[n,"show"])}if(!t)return yield[e,"hide"],void(yield*o.map(e=>[e,"show"]));if(o.every((e,n)=>t[n]===o[n]&&(i=n,!0)),null==i)return yield[e,"hide"],t.reverse(),yield*t.map(e=>[e,"hide"]),yield*o.map(e=>[e,"show"]),void(yield[n,"show"]);yield[e,"hide"];for(let e=t.length;e>i+1;e--)yield[t[e-1],"hide"];for(let e=i+1;e<o.length;e++)yield[o[e],"show"];yield[n,"show"]}else{if(yield[e,"hide"],t.includes(n)){let e=t.indexOf(n),o=t.filter((t,n)=>n>e);o.reverse(),yield*o.map(e=>[e,"hide"]),r=!1}else{let e=[...t];e.reverse(),yield*e.map(e=>[e,"hide"])}r&&(yield[n,"show"])}}function _(e){return function(t,...n){const{askForPromise:o,deps:i}=e;return function(){const e=o();return t({task:e,dependencies:i()},...n),e.promise}}}return T.sequence=function(e,...t){const n=T(),o=[];const i=function*(e){for(const t of e)yield t}(e);return function e(t,...r){t.done?n.done(o):t.value(...r).then(t=>{o.push(t),e(i.next(),...r,t)})}(i.next(),...t),n},T.all=function(e,...t){const n=T(),o=[],i=e.map((e,n)=>"function"==typeof e?e(...t).then(e=>o[n]=e):e.then(e=>o[n]=e));return Promise.all(i).then(()=>n.done(o)),n},function(e={logLevel:0}){const t=E({errorEventName:"@app-error"}),n=R({level:e.logLevel||1},e=>{const{type:n}=e;"error"===n&&t.emit("@app-error",e)}),o={currentScene:null,currentParents:null,sceneNames:new Set,scenes:{},opened:!1,jumpStack:[]},i={},r={shortcutMngr:t,findInstructions:L,askForPromise:T,setInstruction:_({askForPromise:T,deps:t.getDependencies}),log:n};return i.hide=function(e,t){return function(n=1){const{askForPromise:o,shortcutMngr:i,setInstruction:r}=e,{currentScene:s,currentParents:c,scenes:u}=t,l=o(),a=[],d=c.length>0;let p;return i.pause(),a.push(r(u[s].hide)),d||(t.currentScene=null),d&&"*"===n&&[...c].reverse().forEach(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(r(u[e].hide))}),d&&!["*",1].includes(n)&&c.slice("-"+(n-1)).reverse().map(e=>{p=t.currentParents.at(-1),t.currentScene=p,a.push(r(u[e].hide))}),(n=o.sequence(a)).onComplete(()=>{i.changeContext(t.currentScene),l.done()}),l.promise}}(r,o),i.listShortcuts=function(e,t){return function(e){const{scenes:n,sceneNames:o}=t;if(!o.has(e))return null;const{show:i,hide:r,parents:s,beforeUnload:c,afterLoad:u,...l}=n[e];return Object.keys(l)}}(0,o),i.setScenes=function(e,t){return function(n){const{shortcutMngr:o,log:i}=e;n.forEach(e=>{if(null==e)return;const{name:n,scene:r}=e;if(!n)return void i({message:"Scene name is not defined",level:1,type:"error"});if(null==r)return void i({message:`Scene ${n} is not defined`,level:1,type:"error"});r.parents||(r.parents=[]),t.scenes[n]=r,t.sceneNames.add(n);const{show:s,hide:c,parents:u,...l}=r,a={};a[n]=l,o.load(a)})}}(r,o),i.show=function(e,t){return function({scene:n,options:o={ssr:!1}},...i){const{shortcutMngr:r,askForPromise:s,log:c,findInstructions:u,setInstruction:l}=e,a=s(),d=s(),{opened:p,scenes:f,sceneNames:h,currentScene:m}=t;return m&&"function"==typeof f[m].beforeHide?(0,f[m].beforeHide)({done:d.done,dependencies:r.getDependencies()}):d.done(!0),d.onComplete(e=>{if(!e)return a.done(),a.promise;if(!h.has(n))return c({message:`Scene "${n}" is not available.`,level:1,type:"error"}),a.done(),a.promise;if(!p&&o.ssr)return t.opened=!0,t.currentScene=n,r.changeContext(n),a.done(),a.promise;const{show:d,parents:m=[]}=f[n];if("*"===m[0])return l(d,...i)().then(()=>a.done()),t.currentParents.push(t.currentScene),t.currentScene=n,a.promise;if(0!==m.length&&!m.every(e=>h.has(e)))return c({message:`Some of '${n}' parent scenes are not set.`,level:1,type:"error"}),a.done(),a.promise;function g([e,n]){if("show"===n)t.currentScene&&(t.currentParents=[...f[t.currentScene].parents]),t.currentScene=e;else{let n=f[e].parents.at(-1);t.currentScene=n}return f[e][n]}t.currentParents||(t.currentParents=[]);const v=u(t.currentScene,t.currentParents,n,m),y=[];for(let e of v){const t=g(e);y.push(l(t,...i))}s.sequence(y).onComplete(()=>{t.opened=!0,t.currentScene=n,t.currentParents=f[n].parents||null,r.changeContext(n),"function"==typeof f[n].afterShow&&f[n].afterShow({dependencies:r.getDependencies(),done:()=>{}}),a.done()})}),a.promise}}(r,o),i.jump=function(e,t){return function({scene:n},...o){return e.jumpStack.push(e.currentScene),t({scene:n},...o)}}(o,i.show),i.jumpBack=function(e,t){return function({hops:n}={hops:1},...o){for(let t=0;t<n-1;t++)e.jumpStack.pop();if(0===e.jumpStack.length)return;const i=e.jumpStack.pop();return t({scene:i},...o)}}(o,i.show),i.jumpsReset=function(e){return function(){e.jumpStack=[]}}(o),i.loadPlugins=async function(e){const t=e.map(e=>`plugin${e}`),n=await Promise.resolve().then(function(){return S});return t.map(e=>n[e])},i.setDependencies=e=>t.setDependencies(e),i.getDependencies=()=>t.getDependencies(),i.setNote=e=>t.setNote(e),i.listScenes=()=>[...o.sceneNames],i.enablePlugin=(e,n)=>t.enablePlugin(e,n),i.disablePlugin=e=>t.disablePlugin(e),i.getState=()=>({scene:o.currentScene,parents:o.currentParents,opened:o.opened}),i.emit=(e,...n)=>t.emit(e,...n),i}});
@@ -0,0 +1,56 @@
1
+ {
2
+ "0": "Community 0",
3
+ "1": "Community 1",
4
+ "2": "Community 2",
5
+ "3": "Community 3",
6
+ "4": "Community 4",
7
+ "5": "Community 5",
8
+ "6": "Community 6",
9
+ "7": "Community 7",
10
+ "8": "Community 8",
11
+ "9": "Community 9",
12
+ "10": "Community 10",
13
+ "11": "Community 11",
14
+ "12": "Community 12",
15
+ "13": "Community 13",
16
+ "14": "Community 14",
17
+ "15": "Community 15",
18
+ "16": "Community 16",
19
+ "17": "Community 17",
20
+ "18": "Community 18",
21
+ "19": "Community 19",
22
+ "20": "Community 20",
23
+ "21": "Community 21",
24
+ "22": "Community 22",
25
+ "23": "Community 23",
26
+ "24": "Community 24",
27
+ "25": "Community 25",
28
+ "26": "Community 26",
29
+ "27": "Community 27",
30
+ "28": "Community 28",
31
+ "29": "Community 29",
32
+ "30": "Community 30",
33
+ "31": "Community 31",
34
+ "32": "Community 32",
35
+ "33": "Community 33",
36
+ "34": "Community 34",
37
+ "35": "Community 35",
38
+ "36": "Community 36",
39
+ "37": "Community 37",
40
+ "38": "Community 38",
41
+ "39": "Community 39",
42
+ "40": "Community 40",
43
+ "41": "Community 41",
44
+ "42": "Community 42",
45
+ "43": "Community 43",
46
+ "44": "Community 44",
47
+ "45": "Community 45",
48
+ "46": "Community 46",
49
+ "47": "Community 47",
50
+ "48": "Community 48",
51
+ "49": "Community 49",
52
+ "50": "Community 50",
53
+ "51": "Community 51",
54
+ "52": "Community 52",
55
+ "53": "Community 53"
56
+ }
@@ -0,0 +1 @@
1
+ /Users/peternaydenov/.local/pipx/venvs/graphifyy/bin/python
@@ -0,0 +1 @@
1
+ .
@@ -0,0 +1,177 @@
1
+ # Graph Report - git-cuts (2026-07-08)
2
+
3
+ ## Corpus Check
4
+ - 52 files · ~14,604 words
5
+ - Verdict: corpus is large enough that graph structure adds value.
6
+
7
+ ## Summary
8
+ - 257 nodes · 249 edges · 54 communities (48 shown, 6 thin omitted)
9
+ - Extraction: 88% EXTRACTED · 12% INFERRED · 0% AMBIGUOUS · INFERRED: 30 edges (avg confidence: 0.86)
10
+ - Token cost: 0 input · 0 output
11
+
12
+ ## Graph Freshness
13
+ - Built from commit: `2f6beac4`
14
+ - Run `git rev-parse HEAD` and compare to check if the graph is stale.
15
+ - Run `graphify update .` after code changes (no API cost).
16
+
17
+ ## Community Hubs (Navigation)
18
+ - [[_COMMUNITY_Community 0|Community 0]]
19
+ - [[_COMMUNITY_Community 1|Community 1]]
20
+ - [[_COMMUNITY_Community 2|Community 2]]
21
+ - [[_COMMUNITY_Community 3|Community 3]]
22
+ - [[_COMMUNITY_Community 4|Community 4]]
23
+ - [[_COMMUNITY_Community 5|Community 5]]
24
+ - [[_COMMUNITY_Community 6|Community 6]]
25
+ - [[_COMMUNITY_Community 7|Community 7]]
26
+ - [[_COMMUNITY_Community 8|Community 8]]
27
+ - [[_COMMUNITY_Community 9|Community 9]]
28
+ - [[_COMMUNITY_Community 10|Community 10]]
29
+ - [[_COMMUNITY_Community 11|Community 11]]
30
+ - [[_COMMUNITY_Community 12|Community 12]]
31
+ - [[_COMMUNITY_Community 13|Community 13]]
32
+ - [[_COMMUNITY_Community 14|Community 14]]
33
+ - [[_COMMUNITY_Community 15|Community 15]]
34
+ - [[_COMMUNITY_Community 16|Community 16]]
35
+ - [[_COMMUNITY_Community 17|Community 17]]
36
+ - [[_COMMUNITY_Community 18|Community 18]]
37
+ - [[_COMMUNITY_Community 38|Community 38]]
38
+ - [[_COMMUNITY_Community 39|Community 39]]
39
+ - [[_COMMUNITY_Community 40|Community 40]]
40
+ - [[_COMMUNITY_Community 41|Community 41]]
41
+ - [[_COMMUNITY_Community 42|Community 42]]
42
+ - [[_COMMUNITY_Community 43|Community 43]]
43
+
44
+ ## God Nodes (most connected - your core abstractions)
45
+ 1. `Release History` - 16 edges
46
+ 2. `Cuts (@peter.naydenov/cuts)` - 15 edges
47
+ 3. `Scene` - 14 edges
48
+ 4. `compilerOptions` - 12 edges
49
+ 5. `1.2.8 ( 2025-05-03)` - 12 edges
50
+ 6. `main()` - 11 edges
51
+ 7. `@peter.naydenov/shortcuts` - 9 edges
52
+ 8. `scripts` - 8 edges
53
+ 9. `Cuts Library (@peter.naydenov/cuts)` - 8 edges
54
+ 10. `exports` - 7 edges
55
+
56
+ ## Surprising Connections (you probably didn't know these)
57
+ - `Scene Hooks: afterShow and beforeHide` --references--> `Scene` [INFERRED]
58
+ Changelog.md → README.md
59
+ - `@app-error Event` --conceptually_related_to--> `Cuts Library (@peter.naydenov/cuts)` [INFERRED]
60
+ Changelog.md → README.md
61
+ - `Cuts v2.0.0 Release` --references--> `Shortcuts v4.x Upgrade` [INFERRED]
62
+ Changelog.md → Migration.guide.md
63
+ - `clickTarget Array Migration` --conceptually_related_to--> `Click plugin (mouse)` [INFERRED]
64
+ Migration.guide.md → README.md
65
+ - `hoverTarget Array Migration` --conceptually_related_to--> `Hover plugin` [INFERRED]
66
+ Migration.guide.md → README.md
67
+
68
+ ## Import Cycles
69
+ - None detected.
70
+
71
+ ## Hyperedges (group relationships)
72
+ - **v1.x to v2.x Migration Concerns** — migration_v1_to_v2, migration_shortcuts_v4, migration_click_target, migration_hover_target, migration_rationale [EXTRACTED 0.90]
73
+ - **Scene lifecycle methods** — readme_scene, readme_show, readme_hide, readme_aftershow, readme_beforehide [EXTRACTED 1.00]
74
+ - **Jump-based scene navigation flow** — readme_jump, readme_jumpback, readme_jumpsreset, readme_jumpstack, readme_scene [EXTRACTED 1.00]
75
+ - **Shortcut plugin system** — readme_loadplugins, readme_enableplugin, readme_disableplugin, readme_plugin_key, readme_plugin_click, readme_plugin_form, readme_plugin_hover, readme_plugin_scroll, readme_shortcuts [EXTRACTED 1.00]
76
+ - **Cuts Logo Visual Composition** — cuts_wordmark, cuts_film_strip_icon, cuts_background_pattern, cuts_dark_theme_design [INFERRED 0.85]
77
+
78
+ ## Communities (54 total, 6 thin omitted)
79
+
80
+ ### Community 0 - "Community 0"
81
+ Cohesion: 0.14
82
+ Nodes (17): Scene Hooks: afterShow and beforeHide, afterShow() method, beforeHide() method, hide() method, jump() method, jumpBack() method, jumpsReset() method, Jump Stack (+9 more)
83
+
84
+ ### Community 1 - "Community 1"
85
+ Cohesion: 0.15
86
+ Nodes (17): @app-error Event, Bug: SSR First Scene Loading, logLevel Configuration, Cuts v2.0.0 Release, clickTarget Array Migration, hoverTarget Array Migration, Rationale: Array Target Flexibility, Shortcuts v4.x Upgrade (+9 more)
87
+
88
+ ### Community 2 - "Community 2"
89
+ Cohesion: 0.08
90
+ Nodes (24): allowScripts, fsevents@2.3.2, fsevents@2.3.3, author, dependencies, ask-for-promise, @peter.naydenov/log, @peter.naydenov/shortcuts (+16 more)
91
+
92
+ ### Community 3 - "Community 3"
93
+ Cohesion: 0.12
94
+ Nodes (16): AfterShow and BeforeHide, Configuration, Credits, Custom events via `emit`, Cuts (@peter.naydenov/cuts), Description, Emitting from inside a handler, Events (+8 more)
95
+
96
+ ### Community 4 - "Community 4"
97
+ Cohesion: 0.33
98
+ Nodes (11): disablePlugin() method, emit() method, enablePlugin() method, loadPlugins() method, Click plugin (mouse), Form plugin (input), Hover plugin, Key plugin (keyboard) (+3 more)
99
+
100
+ ### Community 5 - "Community 5"
101
+ Cohesion: 0.38
102
+ Nodes (7): Decorative N-Pattern Background, Git-Cuts Brand Identity, Cuts Brand Logo, Dark Theme Visual Design, Film Editing Metaphor, Film Strip Icon, Cuts Wordmark
103
+
104
+ ### Community 6 - "Community 6"
105
+ Cohesion: 0.12
106
+ Nodes (15): 1.3.0 ( 2025-08-15), 1.3.1 ( 2025-08-15), 1.4.0 ( 2025-09-06), 1.4.1. ( 2025-09-24), 1.4.2 ( 2025-09-29), 1.4.3 ( 2025-09-30), 1.4.4 ( 2025-10-10), 1.5.0 ( 2025-10-23 ) (+7 more)
107
+
108
+ ### Community 7 - "Community 7"
109
+ Cohesion: 0.33
110
+ Nodes (5): GRAPH_REPORT.md, graphify, graphify-out/ Directory, graphify.watch._rebuild_code, wiki/index.md
111
+
112
+ ### Community 8 - "Community 8"
113
+ Cohesion: 0.67
114
+ Nodes (4): Dark architectural silhouette (dome + towers), lcov-report favicon, lcov HTML coverage report (parent context), Yellow/olive solid background fill
115
+
116
+ ### Community 9 - "Community 9"
117
+ Cohesion: 0.67
118
+ Nodes (3): Dependencies Object, getDependencies() method, setDependencies() method
119
+
120
+ ### Community 10 - "Community 10"
121
+ Cohesion: 0.17
122
+ Nodes (9): hide(), jump(), jumpBack(), jumpsReset(), listShortcuts(), setScenes(), show(), main() (+1 more)
123
+
124
+ ### Community 11 - "Community 11"
125
+ Cohesion: 0.13
126
+ Nodes (14): compilerOptions, allowJs, checkJs, declaration, declarationMap, emitDeclarationOnly, module, moduleResolution (+6 more)
127
+
128
+ ### Community 12 - "Community 12"
129
+ Cohesion: 0.14
130
+ Nodes (14): devDependencies, @peter.naydenov/visual-controller-for-vue3, @playwright/test, rollup, @rollup/plugin-commonjs, @rollup/plugin-node-resolve, @rollup/plugin-terser, @types/node (+6 more)
131
+
132
+ ### Community 13 - "Community 13"
133
+ Cohesion: 0.15
134
+ Nodes (12): dependencies, @peter.naydenov/shortcuts, @peter.naydenov/visual-controller-for-vue3, vue, devDependencies, vite, @vitejs/plugin-vue, name (+4 more)
135
+
136
+ ### Community 14 - "Community 14"
137
+ Cohesion: 0.17
138
+ Nodes (12): 1.0.0 (2024-05-08), 1.0.1 (2024-05-10), 1.0.2 (2024-12-12), 1.1.0 (2024-12-13), 1.2.0 (2024-12-21), 1.2.1 ( 2024-12-21 ), 1.2.2 ( 2024-12-22 ), 1.2.3 ( 2024-12-23) (+4 more)
139
+
140
+ ### Community 15 - "Community 15"
141
+ Cohesion: 0.25
142
+ Nodes (7): Backward Compatibility, Example Migration, From version 1.x.x to version 2.x.x, Migration Guides, Package Dependencies Update, Per-Context Setup Examples Updated, Plugin Target Attributes Changes
143
+
144
+ ### Community 16 - "Community 16"
145
+ Cohesion: 0.29
146
+ Nodes (7): default, exports, ./dist/*, ./package.json, ./src/*, import, require
147
+
148
+ ### Community 17 - "Community 17"
149
+ Cohesion: 0.50
150
+ Nodes (3): AskObject, sceneDescription, SceneObject
151
+
152
+ ### Community 18 - "Community 18"
153
+ Cohesion: 0.50
154
+ Nodes (3): AskObject, sceneDescription, SceneObject
155
+
156
+ ## Knowledge Gaps
157
+ - **144 isolated node(s):** `name`, `description`, `version`, `license`, `author` (+139 more)
158
+ These have ≤1 connection - possible missing edges or undocumented components.
159
+ - **6 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
160
+
161
+ ## Suggested Questions
162
+ _Questions this graph is uniquely positioned to answer:_
163
+
164
+ - **Why does `Scene` connect `Community 0` to `Community 3`, `Community 4`?**
165
+ _High betweenness centrality (0.034) - this node is a cross-community bridge._
166
+ - **Why does `@peter.naydenov/shortcuts` connect `Community 4` to `Community 0`, `Community 1`?**
167
+ _High betweenness centrality (0.027) - this node is a cross-community bridge._
168
+ - **Why does `Cuts (@peter.naydenov/cuts)` connect `Community 3` to `Community 0`?**
169
+ _High betweenness centrality (0.024) - this node is a cross-community bridge._
170
+ - **What connects `name`, `description`, `version` to the rest of the system?**
171
+ _144 weakly-connected nodes found - possible documentation gaps or missing edges._
172
+ - **Should `Community 0` be split into smaller, more focused modules?**
173
+ _Cohesion score 0.13970588235294118 - nodes in this community are weakly interconnected._
174
+ - **Should `Community 1` be split into smaller, more focused modules?**
175
+ _Cohesion score 0.14705882352941177 - nodes in this community are weakly interconnected._
176
+ - **Should `Community 2` be split into smaller, more focused modules?**
177
+ _Cohesion score 0.08 - nodes in this community are weakly interconnected._
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "agents_graphify", "label": "graphify Knowledge Graph", "file_type": "document", "source_file": "AGENTS.md", "source_location": "1", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_graphify_out", "label": "graphify-out/ Directory", "file_type": "document", "source_file": "AGENTS.md", "source_location": "3", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_graph_report", "label": "GRAPH_REPORT.md", "file_type": "document", "source_file": "AGENTS.md", "source_location": "6", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_wiki_index", "label": "wiki/index.md", "file_type": "document", "source_file": "AGENTS.md", "source_location": "7", "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_watch_rebuild", "label": "graphify.watch._rebuild_code", "file_type": "document", "source_file": "AGENTS.md", "source_location": "8", "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_graphify", "target": "agents_graphify_out", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": "3", "weight": 1.0}, {"source": "agents_graphify_out", "target": "agents_graph_report", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": "6", "weight": 1.0}, {"source": "agents_graphify_out", "target": "agents_wiki_index", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": "7", "weight": 1.0}, {"source": "agents_graphify_out", "target": "agents_watch_rebuild", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": "AGENTS.md", "source_location": "8", "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "jumpback_d", "label": "jumpBack.d.ts", "file_type": "code", "source_file": "types/methods/jumpBack.d.ts", "source_location": "L1"}], "edges": []}
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "show_d", "label": "show.d.ts", "file_type": "code", "source_file": "types/src/methods/show.d.ts", "source_location": "L1"}], "edges": []}
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "setinstruction", "label": "setInstruction.js", "file_type": "code", "source_file": "src/setInstruction.js", "source_location": "L1"}, {"id": "setinstruction_setinstruction", "label": "setInstruction()", "file_type": "code", "source_file": "src/setInstruction.js", "source_location": "L3"}], "edges": [{"source": "setinstruction", "target": "setinstruction_setinstruction", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/setInstruction.js", "source_location": "L3", "weight": 1.0}]}
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "show", "label": "show.js", "file_type": "code", "source_file": "src/methods/show.js", "source_location": "L1"}, {"id": "show_show", "label": "show()", "file_type": "code", "source_file": "src/methods/show.js", "source_location": "L5"}], "edges": [{"source": "show", "target": "show_show", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/methods/show.js", "source_location": "L5", "weight": 1.0}]}
@@ -0,0 +1 @@
1
+ {"nodes": [{"id": "main", "label": "main.js", "file_type": "code", "source_file": "main.js", "source_location": "L1"}], "edges": [{"source": "main", "target": "style_css", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "main.js", "source_location": "L1", "weight": 1.0}, {"source": "main", "target": "javascript_svg", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "main.js", "source_location": "L2", "weight": 1.0}, {"source": "main", "target": "vite_svg", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "main.js", "source_location": "L3", "weight": 1.0}, {"source": "main", "target": "main_js", "relation": "imports_from", "confidence": "EXTRACTED", "source_file": "main.js", "source_location": "L6", "weight": 1.0}]}