From da3cb1d6566d70fb858bda326558aae0fc0ff2ef Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 12:38:25 +0800 Subject: [PATCH 01/95] docs(spec): local vis-network asset (drop CDN, ship vendored copy) --- ...6-06-29-local-vis-network-assets-design.md | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-29-local-vis-network-assets-design.md diff --git a/docs/superpowers/specs/2026-06-29-local-vis-network-assets-design.md b/docs/superpowers/specs/2026-06-29-local-vis-network-assets-design.md new file mode 100644 index 000000000..d9e54b715 --- /dev/null +++ b/docs/superpowers/specs/2026-06-29-local-vis-network-assets-design.md @@ -0,0 +1,202 @@ +# Design: Local vis-network Asset (drop CDN, ship vendored copy) + +**Date:** 2026-06-29 +**Branch:** v8 +**Scope:** `graphify/export.py:to_html` HTML output, three call sites, tests, package data + +--- + +## Problem + +`to_html` currently emits a ` + ``` + with: + ```html + + ``` + +That's it for the production code. The aggregated-view recursive call at line 700 inherits the change automatically. + +### Failure modes + +- Vendored file missing in installed package → `_vendored_vis_js()` raises `FileNotFoundError` → `to_html` propagates. **No silent fallback to CDN** — by design (the whole point is "no CDN"). +- Output directory not writable → `target.write_bytes` raises `PermissionError` → propagates. Caller surfaces the error as it does today. + +--- + +## 3. Test updates (`tests/test_export.py`) + +### 3.1 Delete + +`test_to_html_pins_visjs_version_with_sri` (lines 103–127). The CDN URL, SRI hash, and `crossorigin="anonymous"` assertions no longer apply. + +### 3.2 Extend + +`test_to_html_contains_visjs` (lines 93–100) — append: + +```python +assert '' in content +assert 'unpkg.com' not in content +assert 'integrity=' not in content +assert 'crossorigin="anonymous"' not in content +``` + +### 3.3 Add: `test_to_html_emits_local_vis_js_asset` + +- Call `to_html` with a `tmp` directory. +- Assert `(out.parent / "vis-network.min.js").exists()`. +- Assert its bytes equal the vendored copy (`(files("graphify") / "assets" / "vis-network.min.js").read_bytes()`). + +### 3.4 Add: `test_to_html_skips_rewrite_when_asset_unchanged` + +- First `to_html`, record `target.stat().st_mtime_ns`. +- Second `to_html` to the same directory. +- Assert `mtime_ns` unchanged. + +### 3.5 Add: `test_to_html_rewrites_asset_when_vendored_changes` + +- Monkeypatch `graphify.export._vendored_vis_js` to return `b"DIFFERENT"`. +- Call `to_html`. +- Assert `target.read_bytes() == b"DIFFERENT"`. +- Restore the original function. + +### 3.6 Other tests + +- `tests/test_pipeline.py:83` (`assert "vis-network" in html`) still passes — the literal string `vis-network` appears in the new `' in content + assert 'unpkg.com' not in content + assert 'integrity=' not in content + assert 'crossorigin="anonymous"' not in content +``` + +- [ ] **Step 2: Add a new test for the emitted local asset** + +Append to `tests/test_export.py`: + +```python +def test_to_html_emits_local_vis_network_asset(): + G = make_graph() + communities = cluster(G) + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "graph.html" + to_html(G, communities, str(out)) + asset = out.parent / "vis-network.min.js" + assert asset.exists() + # Byte-equality with the vendored copy is the correctness contract. + assert asset.read_bytes() == _vendored_vis_js() +``` + +(Note: `_vendored_vis_js` is already imported in this file via `test_vendored_vis_js_returns_committed_file_bytes`; the import inside that test's body is local. Add `from graphify.export import _vendored_vis_js` at the top of `test_export.py` to make this new test cleaner, OR keep the local import inside the test body — either is fine. Choose the local import to keep this task's diff minimal.) + +Revised test (use this version): + +```python +def test_to_html_emits_local_vis_network_asset(): + from graphify.export import _vendored_vis_js + G = make_graph() + communities = cluster(G) + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "graph.html" + to_html(G, communities, str(out)) + asset = out.parent / "vis-network.min.js" + assert asset.exists() + # Byte-equality with the vendored copy is the correctness contract. + assert asset.read_bytes() == _vendored_vis_js() +``` + +- [ ] **Step 3: Run the new/extended tests and confirm they fail** + +```bash +pytest tests/test_export.py::test_to_html_contains_visjs tests/test_export.py::test_to_html_emits_local_vis_network_asset -v +``` + +Expected: BOTH fail. `test_to_html_contains_visjs` fails on the new `assert 'unpkg.com' not in content` (the old SRI-bearing script tag is still being emitted). `test_to_html_emits_local_vis_network_asset` fails on `assert asset.exists()` (the asset file is not being copied yet). + +- [ ] **Step 4: Replace the script tag in `to_html`** + +Open `graphify/export.py`. Find the three lines currently at 790–792: + +```python + +``` + +Replace with the single line: + +```python + +``` + +(Note: leading two-space indentation is unchanged — the line still lives inside the f-string template literal at the same column as the rest of the head block.) + +- [ ] **Step 5: Wire `_emit_vis_js` into `to_html`** + +In the same file, find the final line of `to_html`: + +```python +Path(output_path).write_text(html, encoding="utf-8") # nosec +``` + +Insert the asset-emit call immediately before it: + +```python +_emit_vis_js(Path(output_path)) +Path(output_path).write_text(html, encoding="utf-8") # nosec +``` + +- [ ] **Step 6: Run the new/extended tests and confirm they pass** + +```bash +pytest tests/test_export.py::test_to_html_contains_visjs tests/test_export.py::test_to_html_emits_local_vis_network_asset -v +``` + +Expected: BOTH pass. + +- [ ] **Step 7: Commit** + +```bash +git add graphify/export.py tests/test_export.py +git commit -m "feat(export): to_html uses local vis-network, no CDN/SRI" +``` + +--- + +## Task 7: Delete the obsolete SRI/CDN test + +**Files:** +- Modify: `tests/test_export.py:103-127` (the `test_to_html_pins_visjs_version_with_sri` function) + +- [ ] **Step 1: Confirm the SRI test is still in the suite** + +```bash +grep -n "test_to_html_pins_visjs_version_with_sri" tests/test_export.py +``` + +Expected: one match at the function definition. (The SRI test will currently still pass because Task 6 has only just replaced the script tag — the docstring no longer matches reality, but the function body asserts the new tag is present and asserts the old artifacts are absent.) + +- [ ] **Step 2: Delete the entire test function** + +Open `tests/test_export.py`. Find the function `test_to_html_pins_visjs_version_with_sri`. It begins with a multi-line docstring explaining why SRI is required and a hash that no longer applies. Delete the entire function — the leading `def` line, the docstring, the body, and the trailing blank line that separates it from the next test. Leave the surrounding tests untouched. + +The exact text to delete (verify line range with `grep -n` first): + +```python +def test_to_html_pins_visjs_version_with_sri(): + """vis-network script tag must use a pinned versioned URL with a sha384 + Subresource Integrity hash and crossorigin=anonymous. Without this, + a compromised CDN could ship arbitrary JavaScript into every rendered + graph viewer. The hash was verified against the upstream file at + https://unpkg.com/vis-network@9.1.6/standalone/umd/vis-network.min.js + (sha384-Ux6phic9PEHJ38YtrijhkzyJ8yQlH8i/+buBR8s3mAZOJrP1gwyvAcIYl3GWtpX1). + Bumping the vis-network version MUST update both the URL and the hash. + """ + G = make_graph() + communities = cluster(G) + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "graph.html" + to_html(G, communities, str(out)) + content = out.read_text() + + # Versioned URL — unversioned `vis-network/standalone/...` is rejected. + assert "vis-network@9.1.6/standalone/umd/vis-network.min.js" in content + assert "https://unpkg.com/vis-network/standalone" not in content + + # SRI integrity attribute pinning the known-good hash. + assert 'integrity="sha384-Ux6phic9PEHJ38YtrijhkzyJ8yQlH8i/+buBR8s3mAZOJrP1gwyvAcIYl3GWtpX1"' in content + + # crossorigin="anonymous" is required for SRI on cross-origin scripts. + assert 'crossorigin="anonymous"' in content +``` + +- [ ] **Step 3: Confirm the function is gone** + +```bash +grep -n "test_to_html_pins_visjs_version_with_sri" tests/test_export.py +``` + +Expected: no output. + +- [ ] **Step 4: Run the test_export suite and confirm it still passes** + +```bash +pytest tests/test_export.py -v +``` + +Expected: every test passes. The 4 added in Tasks 3–6 should be visible by name. + +- [ ] **Step 5: Commit** + +```bash +git add tests/test_export.py +git commit -m "test(export): drop obsolete SRI/CDN pin test (local asset now)" +``` + +--- + +## Task 8: Tighten `tests/test_pipeline.py:83` + +**Files:** +- Modify: `tests/test_pipeline.py:83` + +- [ ] **Step 1: Read the current assertion** + +```bash +sed -n '80,86p' tests/test_pipeline.py +``` + +Expected output: shows the surrounding context of line 83, which currently is `assert "vis-network" in html`. + +- [ ] **Step 2: Replace the loose substring check with the precise path check** + +Change line 83 from: + +```python + assert "vis-network" in html +``` + +to: + +```python + assert './vis-network.min.js' in html +``` + +- [ ] **Step 3: Run the pipeline test to confirm it still passes** + +```bash +pytest tests/test_pipeline.py -v +``` + +Expected: every test in the file passes. + +- [ ] **Step 4: Commit** + +```bash +git add tests/test_pipeline.py +git commit -m "test(pipeline): tighten vis-network assertion to local path" +``` + +--- + +## Task 9: Final verification — full test suite + manual smoke test + +**Files:** none modified; this task is a check. + +- [ ] **Step 1: Run the full test suite** + +```bash +pytest +``` + +Expected: all tests pass. If any test fails, stop and investigate — every test added in this plan is by construction green at the time it was committed, so a failure here means either an unrelated regression or a missed interaction. Read the failure carefully before proceeding. + +- [ ] **Step 2: Smoke-test `to_html` end-to-end** + +Run a one-off invocation that exercises the public function. The graphify CLI itself is fine if it can be run, but a direct Python call avoids any CLI flag friction: + +```bash +python -c " +import json, tempfile +from pathlib import Path +from graphify.build import build_from_json +from graphify.cluster import cluster +from graphify.export import to_html + +with tempfile.TemporaryDirectory() as tmp: + fixture = Path('tests/fixtures/extraction.json') + G = build_from_json(json.loads(fixture.read_text())) + communities = cluster(G) + out = Path(tmp) / 'graph.html' + to_html(G, communities, str(out)) + html = out.read_text() + asset = out.parent / 'vis-network.min.js' + print('html size:', len(html), 'bytes') + print('asset size:', asset.stat().st_size, 'bytes') + print('asset = vendored:', asset.read_bytes() == (Path('graphify/assets/vis-network.min.js').read_bytes())) + print('html references local asset:', './vis-network.min.js' in html) + print('html has no unpkg:', 'unpkg.com' not in html) + print('html has no integrity:', 'integrity=' not in html) +" +``` + +Expected output (numbers approximate, the booleans must all be `True`): + +``` +html size: ~21000 bytes +asset size: 702611 bytes +asset = vendored: True +html references local asset: True +html has no unpkg: True +html has no integrity: True +``` + +- [ ] **Step 3: Open the generated HTML in a browser (manual)** + +Copy a generated `graph.html` to a fresh directory, open it in a browser, and confirm the graph renders. The page should load with no network requests to `unpkg.com` (visible in the browser devtools network tab). If the page is blank, the most likely cause is a path mismatch between the script tag and the asset file — double-check that `vis-network.min.js` sits beside `graph.html`, not one level deeper. + +- [ ] **Step 4: Final commit (only if Step 2 or 3 surfaced a fix)** + +If everything in Steps 1–3 was green, there is nothing to commit. If you had to make a tweak (e.g., a forgotten import, a path adjustment), commit it now with a `fix:` or `chore:` prefix and a one-line message describing what you fixed. + +--- + +## Self-Review Notes + +The plan was checked against `docs/superpowers/specs/2026-06-29-local-vis-network-assets-design.md`: + +- **Spec §1 (vendored file location & distribution)** → Tasks 1 and 2. +- **Spec §2 (`to_html` behavior change: constant, helpers, wire-up, script tag)** → Tasks 3, 4, 5, 6. +- **Spec §3 (test updates: delete SRI test, extend visjs test, add 3 new tests, optional pipeline tighten)** → Tasks 6, 7, 8. The spec lists three new tests (3.3, 3.4, 3.5); the plan adds them across Tasks 4, 5, and 6 in TDD order — `test_vendored_vis_js_returns_committed_file_bytes` (3.3a), `test_emit_vis_js_*` (3.3b, 3.4, 3.5), and `test_to_html_emits_local_vis_network_asset` (3.3c). +- **Spec §4 (risks)** — covered by Task 9 Step 1 (full test suite catches regressions) and Step 2 (smoke test catches the wheel/sdist packaging risk explicitly). +- **Spec §5 (file map)** — every row in the spec's summary table is touched by exactly one task in the plan. + +Type and name consistency: `_VIS_NETWORK_FILENAME` is defined in Task 3, consumed by `_vendored_vis_js()` and `_emit_vis_js()` in Tasks 4 and 5, and the on-disk name matches the string literal everywhere. `_emit_vis_js` is called once, by `to_html` in Task 6. No drift. From a9ad18ac5b48871b9a926bdbf20ba0dc95730203 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 12:45:28 +0800 Subject: [PATCH 03/95] chore(assets): vendor vis-network 9.1.6 (drop unpkg CDN) --- graphify/assets/vis-network.min.js | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 graphify/assets/vis-network.min.js diff --git a/graphify/assets/vis-network.min.js b/graphify/assets/vis-network.min.js new file mode 100644 index 000000000..5cb3e66b5 --- /dev/null +++ b/graphify/assets/vis-network.min.js @@ -0,0 +1,33 @@ +/** + * vis-network + * https://visjs.github.io/vis-network/ + * + * A dynamic, browser-based visualization library. + * + * @version 9.1.6 + * @date 2023-03-23T21:31:19.223Z + * + * @copyright (c) 2011-2017 Almende B.V, http://almende.com + * @copyright (c) 2017-2019 visjs contributors, https://github.com/visjs + * + * @license + * vis.js is dual licensed under both + * + * 1. The Apache 2.0 License + * http://www.apache.org/licenses/LICENSE-2.0 + * + * and + * + * 2. The MIT License + * http://opensource.org/licenses/MIT + * + * vis.js may be distributed under either license. + */ +!function(g,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((g="undefined"!=typeof globalThis?globalThis:g||self).vis=g.vis||{})}(this,(function(g){var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function e(g){return g&&g.__esModule&&Object.prototype.hasOwnProperty.call(g,"default")?g.default:g}var A={},C={get exports(){return A},set exports(g){A=g}},I=function(g){return g&&g.Math==Math&&g},i=I("object"==typeof globalThis&&globalThis)||I("object"==typeof window&&window)||I("object"==typeof self&&self)||I("object"==typeof t&&t)||function(){return this}()||Function("return this")(),o=function(g){try{return!!g()}catch(g){return!0}},n=!o((function(){var g=function(){}.bind();return"function"!=typeof g||g.hasOwnProperty("prototype")})),r=n,s=Function.prototype,a=s.apply,d=s.call,h="object"==typeof Reflect&&Reflect.apply||(r?d.bind(a):function(){return d.apply(a,arguments)}),l=n,c=Function.prototype,u=c.call,p=l&&c.bind.bind(u,u),f=l?p:function(g){return function(){return u.apply(g,arguments)}},v=f,y=v({}.toString),m=v("".slice),b=function(g){return m(y(g),8,-1)},w=b,x=f,k=function(g){if("Function"===w(g))return x(g)},E="object"==typeof document&&document.all,O={all:E,IS_HTMLDDA:void 0===E&&void 0!==E},T=O.all,D=O.IS_HTMLDDA?function(g){return"function"==typeof g||g===T}:function(g){return"function"==typeof g},N={},R=!o((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),P=n,M=Function.prototype.call,B=P?M.bind(M):function(){return M.apply(M,arguments)},z={},S={}.propertyIsEnumerable,Z=Object.getOwnPropertyDescriptor,F=Z&&!S.call({1:2},1);z.f=F?function(g){var t=Z(this,g);return!!t&&t.enumerable}:S;var G,j,L=function(g,t){return{enumerable:!(1&g),configurable:!(2&g),writable:!(4&g),value:t}},V=o,Y=b,W=Object,Q=f("".split),U=V((function(){return!W("z").propertyIsEnumerable(0)}))?function(g){return"String"==Y(g)?Q(g,""):W(g)}:W,_=function(g){return null==g},H=_,K=TypeError,X=function(g){if(H(g))throw K("Can't call method on "+g);return g},J=U,q=X,$=function(g){return J(q(g))},gg=D,tg=O.all,eg=O.IS_HTMLDDA?function(g){return"object"==typeof g?null!==g:gg(g)||g===tg}:function(g){return"object"==typeof g?null!==g:gg(g)},Ag={},Cg=Ag,Ig=i,ig=D,og=function(g){return ig(g)?g:void 0},ng=function(g,t){return arguments.length<2?og(Cg[g])||og(Ig[g]):Cg[g]&&Cg[g][t]||Ig[g]&&Ig[g][t]},rg=f({}.isPrototypeOf),sg="undefined"!=typeof navigator&&String(navigator.userAgent)||"",ag=i,dg=sg,hg=ag.process,lg=ag.Deno,cg=hg&&hg.versions||lg&&lg.version,ug=cg&&cg.v8;ug&&(j=(G=ug.split("."))[0]>0&&G[0]<4?1:+(G[0]+G[1])),!j&&dg&&(!(G=dg.match(/Edge\/(\d+)/))||G[1]>=74)&&(G=dg.match(/Chrome\/(\d+)/))&&(j=+G[1]);var pg=j,fg=pg,vg=o,yg=!!Object.getOwnPropertySymbols&&!vg((function(){var g=Symbol();return!String(g)||!(Object(g)instanceof Symbol)||!Symbol.sham&&fg&&fg<41})),mg=yg&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,bg=ng,wg=D,xg=rg,kg=Object,Eg=mg?function(g){return"symbol"==typeof g}:function(g){var t=bg("Symbol");return wg(t)&&xg(t.prototype,kg(g))},Og=String,Tg=function(g){try{return Og(g)}catch(g){return"Object"}},Dg=D,Ng=Tg,Rg=TypeError,Pg=function(g){if(Dg(g))return g;throw Rg(Ng(g)+" is not a function")},Mg=Pg,Bg=_,zg=function(g,t){var e=g[t];return Bg(e)?void 0:Mg(e)},Sg=B,Zg=D,Fg=eg,Gg=TypeError,jg={},Lg={get exports(){return jg},set exports(g){jg=g}},Vg=i,Yg=Object.defineProperty,Wg=function(g,t){try{Yg(Vg,g,{value:t,configurable:!0,writable:!0})}catch(e){Vg[g]=t}return t},Qg="__core-js_shared__",Ug=i[Qg]||Wg(Qg,{}),_g=Ug;(Lg.exports=function(g,t){return _g[g]||(_g[g]=void 0!==t?t:{})})("versions",[]).push({version:"3.29.0",mode:"pure",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.29.0/LICENSE",source:"https://github.com/zloirock/core-js"});var Hg=X,Kg=Object,Xg=function(g){return Kg(Hg(g))},Jg=Xg,qg=f({}.hasOwnProperty),$g=Object.hasOwn||function(g,t){return qg(Jg(g),t)},gt=f,tt=0,et=Math.random(),At=gt(1..toString),Ct=function(g){return"Symbol("+(void 0===g?"":g)+")_"+At(++tt+et,36)},It=jg,it=$g,ot=Ct,nt=yg,rt=mg,st=i.Symbol,at=It("wks"),dt=rt?st.for||st:st&&st.withoutSetter||ot,ht=function(g){return it(at,g)||(at[g]=nt&&it(st,g)?st[g]:dt("Symbol."+g)),at[g]},lt=B,ct=eg,ut=Eg,pt=zg,ft=function(g,t){var e,A;if("string"===t&&Zg(e=g.toString)&&!Fg(A=Sg(e,g)))return A;if(Zg(e=g.valueOf)&&!Fg(A=Sg(e,g)))return A;if("string"!==t&&Zg(e=g.toString)&&!Fg(A=Sg(e,g)))return A;throw Gg("Can't convert object to primitive value")},vt=TypeError,yt=ht("toPrimitive"),mt=function(g,t){if(!ct(g)||ut(g))return g;var e,A=pt(g,yt);if(A){if(void 0===t&&(t="default"),e=lt(A,g,t),!ct(e)||ut(e))return e;throw vt("Can't convert object to primitive value")}return void 0===t&&(t="number"),ft(g,t)},bt=Eg,wt=function(g){var t=mt(g,"string");return bt(t)?t:t+""},xt=eg,kt=i.document,Et=xt(kt)&&xt(kt.createElement),Ot=function(g){return Et?kt.createElement(g):{}},Tt=Ot,Dt=!R&&!o((function(){return 7!=Object.defineProperty(Tt("div"),"a",{get:function(){return 7}}).a})),Nt=R,Rt=B,Pt=z,Mt=L,Bt=$,zt=wt,St=$g,Zt=Dt,Ft=Object.getOwnPropertyDescriptor;N.f=Nt?Ft:function(g,t){if(g=Bt(g),t=zt(t),Zt)try{return Ft(g,t)}catch(g){}if(St(g,t))return Mt(!Rt(Pt.f,g,t),g[t])};var Gt=o,jt=D,Lt=/#|\.prototype\./,Vt=function(g,t){var e=Wt[Yt(g)];return e==Ut||e!=Qt&&(jt(t)?Gt(t):!!t)},Yt=Vt.normalize=function(g){return String(g).replace(Lt,".").toLowerCase()},Wt=Vt.data={},Qt=Vt.NATIVE="N",Ut=Vt.POLYFILL="P",_t=Vt,Ht=Pg,Kt=n,Xt=k(k.bind),Jt=function(g,t){return Ht(g),void 0===t?g:Kt?Xt(g,t):function(){return g.apply(t,arguments)}},qt={},$t=R&&o((function(){return 42!=Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype})),ge=eg,te=String,ee=TypeError,Ae=function(g){if(ge(g))return g;throw ee(te(g)+" is not an object")},Ce=R,Ie=Dt,ie=$t,oe=Ae,ne=wt,re=TypeError,se=Object.defineProperty,ae=Object.getOwnPropertyDescriptor,de="enumerable",he="configurable",le="writable";qt.f=Ce?ie?function(g,t,e){if(oe(g),t=ne(t),oe(e),"function"==typeof g&&"prototype"===t&&"value"in e&&le in e&&!e[le]){var A=ae(g,t);A&&A[le]&&(g[t]=e.value,e={configurable:he in e?e[he]:A[he],enumerable:de in e?e[de]:A[de],writable:!1})}return se(g,t,e)}:se:function(g,t,e){if(oe(g),t=ne(t),oe(e),Ie)try{return se(g,t,e)}catch(g){}if("get"in e||"set"in e)throw re("Accessors not supported");return"value"in e&&(g[t]=e.value),g};var ce=qt,ue=L,pe=R?function(g,t,e){return ce.f(g,t,ue(1,e))}:function(g,t,e){return g[t]=e,g},fe=i,ve=h,ye=k,me=D,be=N.f,we=_t,xe=Ag,ke=Jt,Ee=pe,Oe=$g,Te=function(g){var t=function(e,A,C){if(this instanceof t){switch(arguments.length){case 0:return new g;case 1:return new g(e);case 2:return new g(e,A)}return new g(e,A,C)}return ve(g,this,arguments)};return t.prototype=g.prototype,t},De=function(g,t){var e,A,C,I,i,o,n,r,s,a=g.target,d=g.global,h=g.stat,l=g.proto,c=d?fe:h?fe[a]:(fe[a]||{}).prototype,u=d?xe:xe[a]||Ee(xe,a,{})[a],p=u.prototype;for(I in t)A=!(e=we(d?I:a+(h?".":"#")+I,g.forced))&&c&&Oe(c,I),o=u[I],A&&(n=g.dontCallGetSet?(s=be(c,I))&&s.value:c[I]),i=A&&n?n:t[I],A&&typeof o==typeof i||(r=g.bind&&A?ke(i,fe):g.wrap&&A?Te(i):l&&me(i)?ye(i):i,(g.sham||i&&i.sham||o&&o.sham)&&Ee(r,"sham",!0),Ee(u,I,r),l&&(Oe(xe,C=a+"Prototype")||Ee(xe,C,{}),Ee(xe[C],I,i),g.real&&p&&(e||!p[I])&&Ee(p,I,i)))},Ne=Math.ceil,Re=Math.floor,Pe=Math.trunc||function(g){var t=+g;return(t>0?Re:Ne)(t)},Me=function(g){var t=+g;return t!=t||0===t?0:Pe(t)},Be=Me,ze=Math.max,Se=Math.min,Ze=function(g,t){var e=Be(g);return e<0?ze(e+t,0):Se(e,t)},Fe=Me,Ge=Math.min,je=function(g){return g>0?Ge(Fe(g),9007199254740991):0},Le=function(g){return je(g.length)},Ve=$,Ye=Ze,We=Le,Qe=function(g){return function(t,e,A){var C,I=Ve(t),i=We(I),o=Ye(A,i);if(g&&e!=e){for(;i>o;)if((C=I[o++])!=C)return!0}else for(;i>o;o++)if((g||o in I)&&I[o]===e)return g||o||0;return!g&&-1}},Ue={includes:Qe(!0),indexOf:Qe(!1)},_e={},He=$g,Ke=$,Xe=Ue.indexOf,Je=_e,qe=f([].push),$e=function(g,t){var e,A=Ke(g),C=0,I=[];for(e in A)!He(Je,e)&&He(A,e)&&qe(I,e);for(;t.length>C;)He(A,e=t[C++])&&(~Xe(I,e)||qe(I,e));return I},gA=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],tA=$e,eA=gA,AA=Object.keys||function(g){return tA(g,eA)},CA={};CA.f=Object.getOwnPropertySymbols;var IA=R,iA=f,oA=B,nA=o,rA=AA,sA=CA,aA=z,dA=Xg,hA=U,lA=Object.assign,cA=Object.defineProperty,uA=iA([].concat),pA=!lA||nA((function(){if(IA&&1!==lA({b:1},lA(cA({},"a",{enumerable:!0,get:function(){cA(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var g={},t={},e=Symbol(),A="abcdefghijklmnopqrst";return g[e]=7,A.split("").forEach((function(g){t[g]=g})),7!=lA({},g)[e]||rA(lA({},t)).join("")!=A}))?function(g,t){for(var e=dA(g),A=arguments.length,C=1,I=sA.f,i=aA.f;A>C;)for(var o,n=hA(arguments[C++]),r=I?uA(rA(n),I(n)):rA(n),s=r.length,a=0;s>a;)o=r[a++],IA&&!oA(i,n,o)||(e[o]=n[o]);return e}:lA,fA=pA;De({target:"Object",stat:!0,arity:2,forced:Object.assign!==fA},{assign:fA});var vA=Ag.Object.assign;!function(g){g.exports=vA}(C);var yA=e(A),mA={},bA={get exports(){return mA},set exports(g){mA=g}},wA=f([].slice),xA=f,kA=Pg,EA=eg,OA=$g,TA=wA,DA=n,NA=Function,RA=xA([].concat),PA=xA([].join),MA={},BA=function(g,t,e){if(!OA(MA,t)){for(var A=[],C=0;C=.1;)(l=+I[a++%i])>s&&(l=s),h=Math.sqrt(l*l/(1+r*r)),t+=h=o<0?-h:h,e+=r*h,!0===d?g.lineTo(t,e):g.moveTo(t,e),s-=l,d=!d}var JA={circle:UA,dashedLine:XA,database:KA,diamond:function(g,t,e,A){g.beginPath(),g.lineTo(t,e+A),g.lineTo(t+A,e),g.lineTo(t,e-A),g.lineTo(t-A,e),g.closePath()},ellipse:HA,ellipse_vis:HA,hexagon:function(g,t,e,A){g.beginPath();var C=2*Math.PI/6;g.moveTo(t+A,e);for(var I=1;I<6;I++)g.lineTo(t+A*Math.cos(C*I),e+A*Math.sin(C*I));g.closePath()},roundRect:_A,square:function(g,t,e,A){g.beginPath(),g.rect(t-A,e-A,2*A,2*A),g.closePath()},star:function(g,t,e,A){g.beginPath(),e+=.1*(A*=.82);for(var C=0;C<10;C++){var I=C%2==0?1.3*A:.5*A;g.lineTo(t+I*Math.sin(2*C*Math.PI/10),e-I*Math.cos(2*C*Math.PI/10))}g.closePath()},triangle:function(g,t,e,A){g.beginPath(),e+=.275*(A*=1.15);var C=2*A,I=C/2,i=Math.sqrt(3)/6*C,o=Math.sqrt(C*C-I*I);g.moveTo(t,e-(o-i)),g.lineTo(t+I,e+i),g.lineTo(t-I,e+i),g.lineTo(t,e-(o-i)),g.closePath()},triangleDown:function(g,t,e,A){g.beginPath(),e-=.275*(A*=1.15);var C=2*A,I=C/2,i=Math.sqrt(3)/6*C,o=Math.sqrt(C*C-I*I);g.moveTo(t,e+(o-i)),g.lineTo(t+I,e-i),g.lineTo(t-I,e-i),g.lineTo(t,e+(o-i)),g.closePath()}};function qA(g,t){void 0===t&&(t={});var e=t.insertAt;if(g&&"undefined"!=typeof document){var A=document.head||document.getElementsByTagName("head")[0],C=document.createElement("style");C.type="text/css","top"===e&&A.firstChild?A.insertBefore(C,A.firstChild):A.appendChild(C),C.styleSheet?C.styleSheet.cssText=g:C.appendChild(document.createTextNode(g))}}qA(".vis-overlay{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10}.vis-active{box-shadow:0 0 10px #86d5f8}");qA(".vis [class*=span]{min-height:0;width:auto}");qA('div.vis-color-picker{background-color:#fff;border-radius:15px;box-shadow:0 0 10px 0 rgba(0,0,0,.5);display:none;height:444px;left:30px;margin-left:30px;margin-top:-140px;padding:10px;position:absolute;top:0;width:310px;z-index:1}div.vis-color-picker div.vis-arrow{left:5px;position:absolute;top:147px}div.vis-color-picker div.vis-arrow:after,div.vis-color-picker div.vis-arrow:before{border:solid transparent;content:" ";height:0;pointer-events:none;position:absolute;right:100%;top:50%;width:0}div.vis-color-picker div.vis-arrow:after{border-color:hsla(0,0%,100%,0) #fff hsla(0,0%,100%,0) hsla(0,0%,100%,0);border-width:30px;margin-top:-30px}div.vis-color-picker div.vis-color{cursor:pointer;height:289px;position:absolute;width:289px}div.vis-color-picker div.vis-brightness{position:absolute;top:313px}div.vis-color-picker div.vis-opacity{position:absolute;top:350px}div.vis-color-picker div.vis-selector{background:#4c4c4c;background:-moz-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4c4c4c),color-stop(12%,#595959),color-stop(25%,#666),color-stop(39%,#474747),color-stop(50%,#2c2c2c),color-stop(51%,#000),color-stop(60%,#111),color-stop(76%,#2b2b2b),color-stop(91%,#1c1c1c),color-stop(100%,#131313));background:-webkit-linear-gradient(top,#4c4c4c,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313);background:-o-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-ms-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:linear-gradient(180deg,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313);border:1px solid #fff;border-radius:15px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#4c4c4c",endColorstr="#131313",GradientType=0);height:15px;left:137px;position:absolute;top:137px;width:15px}div.vis-color-picker div.vis-new-color{left:159px;padding-right:2px;text-align:right}div.vis-color-picker div.vis-initial-color,div.vis-color-picker div.vis-new-color{border:1px solid rgba(0,0,0,.1);border-radius:5px;color:rgba(0,0,0,.4);font-size:10px;height:20px;line-height:20px;position:absolute;top:380px;vertical-align:middle;width:140px}div.vis-color-picker div.vis-initial-color{left:10px;padding-left:2px;text-align:left}div.vis-color-picker div.vis-label{left:10px;position:absolute;width:300px}div.vis-color-picker div.vis-label.vis-brightness{top:300px}div.vis-color-picker div.vis-label.vis-opacity{top:338px}div.vis-color-picker div.vis-button{background-color:#f7f7f7;border:2px solid #d9d9d9;border-radius:10px;cursor:pointer;height:25px;line-height:25px;position:absolute;text-align:center;top:410px;vertical-align:middle;width:68px}div.vis-color-picker div.vis-button.vis-cancel{left:5px}div.vis-color-picker div.vis-button.vis-load{left:82px}div.vis-color-picker div.vis-button.vis-apply{left:159px}div.vis-color-picker div.vis-button.vis-save{left:236px}div.vis-color-picker input.vis-range{height:20px;width:290px}');qA('div.vis-configuration{display:block;float:left;font-size:12px;position:relative}div.vis-configuration-wrapper{display:block;width:700px}div.vis-configuration-wrapper:after{clear:both;content:"";display:block}div.vis-configuration.vis-config-option-container{background-color:#fff;border:2px solid #f7f8fa;border-radius:4px;display:block;left:10px;margin-top:20px;padding-left:5px;width:495px}div.vis-configuration.vis-config-button{background-color:#f7f8fa;border:2px solid #ceced0;border-radius:4px;cursor:pointer;display:block;height:25px;left:10px;line-height:25px;margin-bottom:30px;margin-top:20px;padding-left:5px;vertical-align:middle;width:495px}div.vis-configuration.vis-config-button.hover{background-color:#4588e6;border:2px solid #214373;color:#fff}div.vis-configuration.vis-config-item{display:block;float:left;height:25px;line-height:25px;vertical-align:middle;width:495px}div.vis-configuration.vis-config-item.vis-config-s2{background-color:#f7f8fa;border-radius:3px;left:10px;padding-left:5px}div.vis-configuration.vis-config-item.vis-config-s3{background-color:#e4e9f0;border-radius:3px;left:20px;padding-left:5px}div.vis-configuration.vis-config-item.vis-config-s4{background-color:#cfd8e6;border-radius:3px;left:30px;padding-left:5px}div.vis-configuration.vis-config-header{font-size:18px;font-weight:700}div.vis-configuration.vis-config-label{height:25px;line-height:25px;width:120px}div.vis-configuration.vis-config-label.vis-config-s3{width:110px}div.vis-configuration.vis-config-label.vis-config-s4{width:100px}div.vis-configuration.vis-config-colorBlock{border:1px solid #444;border-radius:2px;cursor:pointer;height:19px;margin:0;padding:0;top:1px;width:30px}input.vis-configuration.vis-config-checkbox{left:-5px}input.vis-configuration.vis-config-rangeinput{margin:0;padding:1px;pointer-events:none;position:relative;top:-5px;width:60px}input.vis-configuration.vis-config-range{-webkit-appearance:none;background-color:transparent;border:0 solid #fff;height:20px;width:300px}input.vis-configuration.vis-config-range::-webkit-slider-runnable-track{background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(180deg,#dedede 0,#c8c8c8 99%);border:1px solid #999;border-radius:3px;box-shadow:0 0 3px 0 #aaa;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#dedede",endColorstr="#c8c8c8",GradientType=0);height:5px;width:300px}input.vis-configuration.vis-config-range::-webkit-slider-thumb{-webkit-appearance:none;background:#3876c2;background:-moz-linear-gradient(top,#3876c2 0,#385380 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#3876c2),color-stop(100%,#385380));background:-webkit-linear-gradient(top,#3876c2,#385380);background:-o-linear-gradient(top,#3876c2 0,#385380 100%);background:-ms-linear-gradient(top,#3876c2 0,#385380 100%);background:linear-gradient(180deg,#3876c2 0,#385380);border:1px solid #14334b;border-radius:50%;box-shadow:0 0 1px 0 #111927;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#3876c2",endColorstr="#385380",GradientType=0);height:17px;margin-top:-7px;width:17px}input.vis-configuration.vis-config-range:focus{outline:none}input.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track{background:#9d9d9d;background:-moz-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#9d9d9d),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#9d9d9d,#c8c8c8 99%);background:-o-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:linear-gradient(180deg,#9d9d9d 0,#c8c8c8 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#9d9d9d",endColorstr="#c8c8c8",GradientType=0)}input.vis-configuration.vis-config-range::-moz-range-track{background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(180deg,#dedede 0,#c8c8c8 99%);border:1px solid #999;border-radius:3px;box-shadow:0 0 3px 0 #aaa;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#dedede",endColorstr="#c8c8c8",GradientType=0);height:10px;width:300px}input.vis-configuration.vis-config-range::-moz-range-thumb{background:#385380;border:none;border-radius:50%;height:16px;width:16px}input.vis-configuration.vis-config-range:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input.vis-configuration.vis-config-range::-ms-track{background:transparent;border-color:transparent;border-width:6px 0;color:transparent;height:5px;width:300px}input.vis-configuration.vis-config-range::-ms-fill-lower{background:#777;border-radius:10px}input.vis-configuration.vis-config-range::-ms-fill-upper{background:#ddd;border-radius:10px}input.vis-configuration.vis-config-range::-ms-thumb{background:#385380;border:none;border-radius:50%;height:16px;width:16px}input.vis-configuration.vis-config-range:focus::-ms-fill-lower{background:#888}input.vis-configuration.vis-config-range:focus::-ms-fill-upper{background:#ccc}.vis-configuration-popup{background:rgba(57,76,89,.85);border:2px solid #f2faff;border-radius:4px;color:#fff;font-size:14px;height:30px;line-height:30px;position:absolute;text-align:center;-webkit-transition:opacity .3s ease-in-out;-moz-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out;width:150px}.vis-configuration-popup:after,.vis-configuration-popup:before{border:solid transparent;content:" ";height:0;left:100%;pointer-events:none;position:absolute;top:50%;width:0}.vis-configuration-popup:after{border-color:rgba(136,183,213,0) rgba(136,183,213,0) rgba(136,183,213,0) rgba(57,76,89,.85);border-width:8px;margin-top:-8px}.vis-configuration-popup:before{border-color:rgba(194,225,245,0) rgba(194,225,245,0) rgba(194,225,245,0) #f2faff;border-width:12px;margin-top:-12px}');qA("div.vis-tooltip{background-color:#f5f4ed;border:1px solid #808074;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;box-shadow:3px 3px 10px rgba(0,0,0,.2);color:#000;font-family:verdana;font-size:14px;padding:5px;pointer-events:none;position:absolute;visibility:hidden;white-space:nowrap;z-index:5}");var $A={};!function(g){function t(g){if(g)return function(g){for(var e in t.prototype)g[e]=t.prototype[e];return g}(g)}g.exports=t,t.prototype.on=t.prototype.addEventListener=function(g,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+g]=this._callbacks["$"+g]||[]).push(t),this},t.prototype.once=function(g,t){function e(){this.off(g,e),t.apply(this,arguments)}return e.fn=t,this.on(g,e),this},t.prototype.off=t.prototype.removeListener=t.prototype.removeAllListeners=t.prototype.removeEventListener=function(g,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var e,A=this._callbacks["$"+g];if(!A)return this;if(1==arguments.length)return delete this._callbacks["$"+g],this;for(var C=0;C=o?g?"":void 0:(A=wC(I,i))<55296||A>56319||i+1===o||(C=wC(I,i+1))<56320||C>57343?g?bC(I,i):A:g?xC(I,i,i+2):C-56320+(A-55296<<10)+65536}},EC={codeAt:kC(!1),charAt:kC(!0)},OC=D,TC=i.WeakMap,DC=OC(TC)&&/native code/.test(String(TC)),NC=Ct,RC=jg("keys"),PC=function(g){return RC[g]||(RC[g]=NC(g))},MC=DC,BC=i,zC=eg,SC=pe,ZC=$g,FC=Ug,GC=PC,jC=_e,LC="Object already initialized",VC=BC.TypeError,YC=BC.WeakMap;if(MC||FC.state){var WC=FC.state||(FC.state=new YC);WC.get=WC.get,WC.has=WC.has,WC.set=WC.set,CC=function(g,t){if(WC.has(g))throw VC(LC);return t.facade=g,WC.set(g,t),t},IC=function(g){return WC.get(g)||{}},iC=function(g){return WC.has(g)}}else{var QC=GC("state");jC[QC]=!0,CC=function(g,t){if(ZC(g,QC))throw VC(LC);return t.facade=g,SC(g,QC,t),t},IC=function(g){return ZC(g,QC)?g[QC]:{}},iC=function(g){return ZC(g,QC)}}var UC={set:CC,get:IC,has:iC,enforce:function(g){return iC(g)?IC(g):CC(g,{})},getterFor:function(g){return function(t){var e;if(!zC(t)||(e=IC(t)).type!==g)throw VC("Incompatible receiver, "+g+" required");return e}}},_C=R,HC=$g,KC=Function.prototype,XC=_C&&Object.getOwnPropertyDescriptor,JC=HC(KC,"name"),qC={EXISTS:JC,PROPER:JC&&"something"===function(){}.name,CONFIGURABLE:JC&&(!_C||_C&&XC(KC,"name").configurable)},$C={},gI=R,tI=$t,eI=qt,AI=Ae,CI=$,II=AA;$C.f=gI&&!tI?Object.defineProperties:function(g,t){AI(g);for(var e,A=CI(t),C=II(t),I=C.length,i=0;I>i;)eI.f(g,e=C[i++],A[e]);return g};var iI,oI=ng("document","documentElement"),nI=Ae,rI=$C,sI=gA,aI=_e,dI=oI,hI=Ot,lI="prototype",cI="script",uI=PC("IE_PROTO"),pI=function(){},fI=function(g){return"<"+cI+">"+g+""},vI=function(g){g.write(fI("")),g.close();var t=g.parentWindow.Object;return g=null,t},yI=function(){try{iI=new ActiveXObject("htmlfile")}catch(g){}var g,t,e;yI="undefined"!=typeof document?document.domain&&iI?vI(iI):(t=hI("iframe"),e="java"+cI+":",t.style.display="none",dI.appendChild(t),t.src=String(e),(g=t.contentWindow.document).open(),g.write(fI("document.F=Object")),g.close(),g.F):vI(iI);for(var A=sI.length;A--;)delete yI[lI][sI[A]];return yI()};aI[uI]=!0;var mI,bI,wI,xI=Object.create||function(g,t){var e;return null!==g?(pI[lI]=nI(g),e=new pI,pI[lI]=null,e[uI]=g):e=yI(),void 0===t?e:rI.f(e,t)},kI=!o((function(){function g(){}return g.prototype.constructor=null,Object.getPrototypeOf(new g)!==g.prototype})),EI=$g,OI=D,TI=Xg,DI=kI,NI=PC("IE_PROTO"),RI=Object,PI=RI.prototype,MI=DI?RI.getPrototypeOf:function(g){var t=TI(g);if(EI(t,NI))return t[NI];var e=t.constructor;return OI(e)&&t instanceof e?e.prototype:t instanceof RI?PI:null},BI=pe,zI=function(g,t,e,A){return A&&A.enumerable?g[t]=e:BI(g,t,e),g},SI=o,ZI=D,FI=eg,GI=xI,jI=MI,LI=zI,VI=ht("iterator"),YI=!1;[].keys&&("next"in(wI=[].keys())?(bI=jI(jI(wI)))!==Object.prototype&&(mI=bI):YI=!0);var WI=!FI(mI)||SI((function(){var g={};return mI[VI].call(g)!==g}));ZI((mI=WI?{}:GI(mI))[VI])||LI(mI,VI,(function(){return this}));var QI={IteratorPrototype:mI,BUGGY_SAFARI_ITERATORS:YI},UI=lC,_I=oC?{}.toString:function(){return"[object "+UI(this)+"]"},HI=oC,KI=qt.f,XI=pe,JI=$g,qI=_I,$I=ht("toStringTag"),gi=function(g,t,e,A){if(g){var C=e?g:g.prototype;JI(C,$I)||KI(C,$I,{configurable:!0,value:t}),A&&!HI&&XI(C,"toString",qI)}},ti={},ei=QI.IteratorPrototype,Ai=xI,Ci=L,Ii=gi,ii=ti,oi=function(){return this},ni=f,ri=Pg,si=D,ai=String,di=TypeError,hi=function(g,t,e){try{return ni(ri(Object.getOwnPropertyDescriptor(g,t)[e]))}catch(g){}},li=Ae,ci=function(g){if("object"==typeof g||si(g))return g;throw di("Can't set "+ai(g)+" as a prototype")},ui=Object.setPrototypeOf||("__proto__"in{}?function(){var g,t=!1,e={};try{(g=hi(Object.prototype,"__proto__","set"))(e,[]),t=e instanceof Array}catch(g){}return function(e,A){return li(e),ci(A),t?g(e,A):e.__proto__=A,e}}():void 0),pi=De,fi=B,vi=function(g,t,e,A){var C=t+" Iterator";return g.prototype=Ai(ei,{next:Ci(+!A,e)}),Ii(g,C,!1,!0),ii[C]=oi,g},yi=MI,mi=gi,bi=zI,wi=ti,xi=qC.PROPER,ki=QI.BUGGY_SAFARI_ITERATORS,Ei=ht("iterator"),Oi="keys",Ti="values",Di="entries",Ni=function(){return this},Ri=function(g,t,e,A,C,I,i){vi(e,t,A);var o,n,r,s=function(g){if(g===C&&c)return c;if(!ki&&g in h)return h[g];switch(g){case Oi:case Ti:case Di:return function(){return new e(this,g)}}return function(){return new e(this)}},a=t+" Iterator",d=!1,h=g.prototype,l=h[Ei]||h["@@iterator"]||C&&h[C],c=!ki&&l||s(C),u="Array"==t&&h.entries||l;if(u&&(o=yi(u.call(new g)))!==Object.prototype&&o.next&&(mi(o,a,!0,!0),wi[a]=Ni),xi&&C==Ti&&l&&l.name!==Ti&&(d=!0,c=function(){return fi(l,this)}),C)if(n={values:s(Ti),keys:I?c:s(Oi),entries:s(Di)},i)for(r in n)(ki||d||!(r in h))&&bi(h,r,n[r]);else pi({target:t,proto:!0,forced:ki||d},n);return i&&h[Ei]!==c&&bi(h,Ei,c,{name:C}),wi[t]=c,n},Pi=function(g,t){return{value:g,done:t}},Mi=EC.charAt,Bi=pC,zi=UC,Si=Ri,Zi=Pi,Fi="String Iterator",Gi=zi.set,ji=zi.getterFor(Fi);Si(String,"String",(function(g){Gi(this,{type:Fi,string:Bi(g),index:0})}),(function(){var g,t=ji(this),e=t.string,A=t.index;return A>=e.length?Zi(void 0,!0):(g=Mi(e,A),t.index+=g.length,Zi(g,!1))}));var Li=B,Vi=Ae,Yi=zg,Wi=function(g,t,e){var A,C;Vi(g);try{if(!(A=Yi(g,"return"))){if("throw"===t)throw e;return e}A=Li(A,g)}catch(g){C=!0,A=g}if("throw"===t)throw e;if(C)throw A;return Vi(A),e},Qi=Ae,Ui=Wi,_i=ti,Hi=ht("iterator"),Ki=Array.prototype,Xi=function(g){return void 0!==g&&(_i.Array===g||Ki[Hi]===g)},Ji=D,qi=Ug,$i=f(Function.toString);Ji(qi.inspectSource)||(qi.inspectSource=function(g){return $i(g)});var go=qi.inspectSource,to=f,eo=o,Ao=D,Co=lC,Io=go,io=function(){},oo=[],no=ng("Reflect","construct"),ro=/^\s*(?:class|function)\b/,so=to(ro.exec),ao=!ro.exec(io),ho=function(g){if(!Ao(g))return!1;try{return no(io,oo,g),!0}catch(g){return!1}},lo=function(g){if(!Ao(g))return!1;switch(Co(g)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return ao||!!so(ro,Io(g))}catch(g){return!0}};lo.sham=!0;var co=!no||eo((function(){var g;return ho(ho.call)||!ho(Object)||!ho((function(){g=!0}))||g}))?lo:ho,uo=wt,po=qt,fo=L,vo=function(g,t,e){var A=uo(t);A in g?po.f(g,A,fo(0,e)):g[A]=e},yo=lC,mo=zg,bo=_,wo=ti,xo=ht("iterator"),ko=function(g){if(!bo(g))return mo(g,xo)||mo(g,"@@iterator")||wo[yo(g)]},Eo=B,Oo=Pg,To=Ae,Do=Tg,No=ko,Ro=TypeError,Po=function(g,t){var e=arguments.length<2?No(g):t;if(Oo(e))return To(Eo(e,g));throw Ro(Do(g)+" is not iterable")},Mo=Jt,Bo=B,zo=Xg,So=function(g,t,e,A){try{return A?t(Qi(e)[0],e[1]):t(e)}catch(t){Ui(g,"throw",t)}},Zo=Xi,Fo=co,Go=Le,jo=vo,Lo=Po,Vo=ko,Yo=Array,Wo=ht("iterator"),Qo=!1;try{var Uo=0,_o={next:function(){return{done:!!Uo++}},return:function(){Qo=!0}};_o[Wo]=function(){return this},Array.from(_o,(function(){throw 2}))}catch(g){}var Ho=function(g,t){if(!t&&!Qo)return!1;var e=!1;try{var A={};A[Wo]=function(){return{next:function(){return{done:e=!0}}}},g(A)}catch(g){}return e},Ko=function(g){var t=zo(g),e=Fo(this),A=arguments.length,C=A>1?arguments[1]:void 0,I=void 0!==C;I&&(C=Mo(C,A>2?arguments[2]:void 0));var i,o,n,r,s,a,d=Vo(t),h=0;if(!d||this===Yo&&Zo(d))for(i=Go(t),o=e?new this(i):Yo(i);i>h;h++)a=I?C(t[h],h):t[h],jo(o,h,a);else for(s=(r=Lo(t,d)).next,o=e?new this:[];!(n=Bo(s,r)).done;h++)a=I?So(r,C,[n.value,h],!0):n.value,jo(o,h,a);return o.length=h,o};De({target:"Array",stat:!0,forced:!Ho((function(g){Array.from(g)}))},{from:Ko});var Xo=Ag.Array.from;!function(g){g.exports=Xo}(eC);var Jo=e(tC),qo={},$o={get exports(){return qo},set exports(g){qo=g}},gn={},tn={get exports(){return gn},set exports(g){gn=g}},en=$,An=ti,Cn=UC;qt.f;var In=Ri,on=Pi,nn="Array Iterator",rn=Cn.set,sn=Cn.getterFor(nn);In(Array,"Array",(function(g,t){rn(this,{type:nn,target:en(g),index:0,kind:t})}),(function(){var g=sn(this),t=g.target,e=g.kind,A=g.index++;return!t||A>=t.length?(g.target=void 0,on(void 0,!0)):on("keys"==e?A:"values"==e?t[A]:[A,t[A]],!1)}),"values"),An.Arguments=An.Array;var an=ko,dn={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},hn=i,ln=lC,cn=pe,un=ti,pn=ht("toStringTag");for(var fn in dn){var vn=hn[fn],yn=vn&&vn.prototype;yn&&ln(yn)!==pn&&cn(yn,pn,fn),un[fn]=un.Array}var mn=an;!function(g){g.exports=mn}(tn),function(g){g.exports=gn}($o);var bn=e(qo),wn={},xn={get exports(){return wn},set exports(g){wn=g}},kn={},En=$e,On=gA.concat("length","prototype");kn.f=Object.getOwnPropertyNames||function(g){return En(g,On)};var Tn={},Dn=Ze,Nn=Le,Rn=vo,Pn=Array,Mn=Math.max,Bn=function(g,t,e){for(var A=Nn(g),C=Dn(t,A),I=Dn(void 0===e?A:e,A),i=Pn(Mn(I-C,0)),o=0;Cf;f++)if((o||f in c)&&(h=u(d=c[f],f,l),g))if(t)y[f]=h;else if(h)switch(g){case 3:return!0;case 5:return d;case 6:return f;case 2:lr(y,d)}else switch(g){case 4:return!1;case 7:lr(y,d)}return I?-1:A||C?C:y}},ur={forEach:cr(0),map:cr(1),filter:cr(2),some:cr(3),every:cr(4),find:cr(5),findIndex:cr(6),filterReject:cr(7)},pr=De,fr=i,vr=B,yr=f,mr=R,br=yg,wr=o,xr=$g,kr=rg,Er=Ae,Or=$,Tr=wt,Dr=pC,Nr=L,Rr=xI,Pr=AA,Mr=kn,Br=Tn,zr=CA,Sr=N,Zr=qt,Fr=$C,Gr=z,jr=zI,Lr=Ln,Vr=jg,Yr=_e,Wr=Ct,Qr=ht,Ur=Vn,_r=Hn,Hr=$n,Kr=gi,Xr=UC,Jr=ur.forEach,qr=PC("hidden"),$r="Symbol",gs="prototype",ts=Xr.set,es=Xr.getterFor($r),As=Object[gs],Cs=fr.Symbol,Is=Cs&&Cs[gs],is=fr.TypeError,os=fr.QObject,ns=Sr.f,rs=Zr.f,ss=Br.f,as=Gr.f,ds=yr([].push),hs=Vr("symbols"),ls=Vr("op-symbols"),cs=Vr("wks"),us=!os||!os[gs]||!os[gs].findChild,ps=mr&&wr((function(){return 7!=Rr(rs({},"a",{get:function(){return rs(this,"a",{value:7}).a}})).a}))?function(g,t,e){var A=ns(As,t);A&&delete As[t],rs(g,t,e),A&&g!==As&&rs(As,t,A)}:rs,fs=function(g,t){var e=hs[g]=Rr(Is);return ts(e,{type:$r,tag:g,description:t}),mr||(e.description=t),e},vs=function(g,t,e){g===As&&vs(ls,t,e),Er(g);var A=Tr(t);return Er(e),xr(hs,A)?(e.enumerable?(xr(g,qr)&&g[qr][A]&&(g[qr][A]=!1),e=Rr(e,{enumerable:Nr(0,!1)})):(xr(g,qr)||rs(g,qr,Nr(1,{})),g[qr][A]=!0),ps(g,A,e)):rs(g,A,e)},ys=function(g,t){Er(g);var e=Or(t),A=Pr(e).concat(xs(e));return Jr(A,(function(t){mr&&!vr(ms,e,t)||vs(g,t,e[t])})),g},ms=function(g){var t=Tr(g),e=vr(as,this,t);return!(this===As&&xr(hs,t)&&!xr(ls,t))&&(!(e||!xr(this,t)||!xr(hs,t)||xr(this,qr)&&this[qr][t])||e)},bs=function(g,t){var e=Or(g),A=Tr(t);if(e!==As||!xr(hs,A)||xr(ls,A)){var C=ns(e,A);return!C||!xr(hs,A)||xr(e,qr)&&e[qr][A]||(C.enumerable=!0),C}},ws=function(g){var t=ss(Or(g)),e=[];return Jr(t,(function(g){xr(hs,g)||xr(Yr,g)||ds(e,g)})),e},xs=function(g){var t=g===As,e=ss(t?ls:Or(g)),A=[];return Jr(e,(function(g){!xr(hs,g)||t&&!xr(As,g)||ds(A,hs[g])})),A};br||(Cs=function(){if(kr(Is,this))throw is("Symbol is not a constructor");var g=arguments.length&&void 0!==arguments[0]?Dr(arguments[0]):void 0,t=Wr(g),e=function(g){this===As&&vr(e,ls,g),xr(this,qr)&&xr(this[qr],t)&&(this[qr][t]=!1),ps(this,t,Nr(1,g))};return mr&&us&&ps(As,t,{configurable:!0,set:e}),fs(t,g)},jr(Is=Cs[gs],"toString",(function(){return es(this).tag})),jr(Cs,"withoutSetter",(function(g){return fs(Wr(g),g)})),Gr.f=ms,Zr.f=vs,Fr.f=ys,Sr.f=bs,Mr.f=Br.f=ws,zr.f=xs,Ur.f=function(g){return fs(Qr(g),g)},mr&&Lr(Is,"description",{configurable:!0,get:function(){return es(this).description}})),pr({global:!0,constructor:!0,wrap:!0,forced:!br,sham:!br},{Symbol:Cs}),Jr(Pr(cs),(function(g){_r(g)})),pr({target:$r,stat:!0,forced:!br},{useSetter:function(){us=!0},useSimple:function(){us=!1}}),pr({target:"Object",stat:!0,forced:!br,sham:!mr},{create:function(g,t){return void 0===t?Rr(g):ys(Rr(g),t)},defineProperty:vs,defineProperties:ys,getOwnPropertyDescriptor:bs}),pr({target:"Object",stat:!0,forced:!br},{getOwnPropertyNames:ws}),Hr(),Kr(Cs,$r),Yr[qr]=!0;var ks=yg&&!!Symbol.for&&!!Symbol.keyFor,Es=De,Os=ng,Ts=$g,Ds=pC,Ns=jg,Rs=ks,Ps=Ns("string-to-symbol-registry"),Ms=Ns("symbol-to-string-registry");Es({target:"Symbol",stat:!0,forced:!Rs},{for:function(g){var t=Ds(g);if(Ts(Ps,t))return Ps[t];var e=Os("Symbol")(t);return Ps[t]=e,Ms[e]=t,e}});var Bs=De,zs=$g,Ss=Eg,Zs=Tg,Fs=ks,Gs=jg("symbol-to-string-registry");Bs({target:"Symbol",stat:!0,forced:!Fs},{keyFor:function(g){if(!Ss(g))throw TypeError(Zs(g)+" is not a symbol");if(zs(Gs,g))return Gs[g]}});var js=tr,Ls=D,Vs=b,Ys=pC,Ws=f([].push),Qs=De,Us=ng,_s=h,Hs=B,Ks=f,Xs=o,Js=D,qs=Eg,$s=wA,ga=function(g){if(Ls(g))return g;if(js(g)){for(var t=g.length,e=[],A=0;Ao;)void 0!==(e=C(A,t=I[o++]))&&Wa(i,t,e);return i}});var Qa=Ag.Object.getOwnPropertyDescriptors;!function(g){g.exports=Qa}(Ba);var Ua=e(Ma),_a={},Ha={get exports(){return _a},set exports(g){_a=g}},Ka={},Xa={get exports(){return Ka},set exports(g){Ka=g}},Ja=De,qa=R,$a=$C.f;Ja({target:"Object",stat:!0,forced:Object.defineProperties!==$a,sham:!qa},{defineProperties:$a});var gd=Ag.Object,td=Xa.exports=function(g,t){return gd.defineProperties(g,t)};gd.defineProperties.sham&&(td.sham=!0);var ed=Ka;!function(g){g.exports=ed}(Ha);var Ad=e(_a),Cd={},Id={get exports(){return Cd},set exports(g){Cd=g}},id={},od={get exports(){return id},set exports(g){id=g}},nd=De,rd=R,sd=qt.f;nd({target:"Object",stat:!0,forced:Object.defineProperty!==sd,sham:!rd},{defineProperty:sd});var ad=Ag.Object,dd=od.exports=function(g,t,e){return ad.defineProperty(g,t,e)};ad.defineProperty.sham&&(dd.sham=!0);var hd=id;!function(g){g.exports=hd}(Id);var ld=e(Cd);function cd(g,t){if(!(g instanceof t))throw new TypeError("Cannot call a class as a function")}var ud={},pd={get exports(){return ud},set exports(g){ud=g}},fd={},vd=hd;!function(g){g.exports=vd}({get exports(){return fd},set exports(g){fd=g}}),function(g){g.exports=fd}(pd);var yd=e(ud),md={},bd={get exports(){return md},set exports(g){md=g}},wd={},xd={get exports(){return wd},set exports(g){wd=g}},kd=TypeError,Ed=function(g){if(g>9007199254740991)throw kd("Maximum allowed index exceeded");return g},Od=o,Td=pg,Dd=ht("species"),Nd=function(g){return Td>=51||!Od((function(){var t=[];return(t.constructor={})[Dd]=function(){return{foo:1}},1!==t[g](Boolean).foo}))},Rd=De,Pd=o,Md=tr,Bd=eg,zd=Xg,Sd=Le,Zd=Ed,Fd=vo,Gd=nr,jd=Nd,Ld=pg,Vd=ht("isConcatSpreadable"),Yd=Ld>=51||!Pd((function(){var g=[];return g[Vd]=!1,g.concat()[0]!==g})),Wd=function(g){if(!Bd(g))return!1;var t=g[Vd];return void 0!==t?!!t:Md(g)};Rd({target:"Array",proto:!0,arity:1,forced:!Yd||!jd("concat")},{concat:function(g){var t,e,A,C,I,i=zd(this),o=Gd(i,0),n=0;for(t=-1,A=arguments.length;tg.length)&&(t=g.length);for(var e=0,A=new Array(t);e1?arguments[1]:void 0)}});var Ul=FA("Array").map,_l=rg,Hl=Ul,Kl=Array.prototype,Xl=function(g){var t=g.map;return g===Kl||_l(Kl,g)&&t===Kl.map?Hl:t},Jl=Xl;!function(g){g.exports=Jl}(Wl);var ql=e(Yl),$l={},gc={get exports(){return $l},set exports(g){$l=g}},tc=Xg,ec=AA;De({target:"Object",stat:!0,forced:o((function(){ec(1)}))},{keys:function(g){return ec(tc(g))}});var Ac=Ag.Object.keys;!function(g){g.exports=Ac}(gc);var Cc=e($l),Ic={},ic={get exports(){return Ic},set exports(g){Ic=g}},oc=De,nc=Date,rc=f(nc.prototype.getTime);oc({target:"Date",stat:!0},{now:function(){return rc(new nc)}});var sc=Ag.Date.now;!function(g){g.exports=sc}(ic);var ac=e(Ic),dc={},hc={get exports(){return dc},set exports(g){dc=g}},lc=o,cc=function(g,t){var e=[][g];return!!e&&lc((function(){e.call(null,t||function(){return 1},1)}))},uc=ur.forEach,pc=cc("forEach")?[].forEach:function(g){return uc(this,g,arguments.length>1?arguments[1]:void 0)};De({target:"Array",proto:!0,forced:[].forEach!=pc},{forEach:pc});var fc=FA("Array").forEach,vc=lC,yc=$g,mc=rg,bc=fc,wc=Array.prototype,xc={DOMTokenList:!0,NodeList:!0},kc=function(g){var t=g.forEach;return g===wc||mc(wc,g)&&t===wc.forEach||yc(xc,vc(g))?bc:t};!function(g){g.exports=kc}(hc);var Ec=e(dc),Oc={},Tc={get exports(){return Oc},set exports(g){Oc=g}},Dc=De,Nc=tr,Rc=f([].reverse),Pc=[1,2];Dc({target:"Array",proto:!0,forced:String(Pc)===String(Pc.reverse())},{reverse:function(){return Nc(this)&&(this.length=this.length),Rc(this)}});var Mc=FA("Array").reverse,Bc=rg,zc=Mc,Sc=Array.prototype,Zc=function(g){var t=g.reverse;return g===Sc||Bc(Sc,g)&&t===Sc.reverse?zc:t},Fc=Zc;!function(g){g.exports=Fc}(Tc);var Gc=e(Oc),jc={},Lc={get exports(){return jc},set exports(g){jc=g}},Vc=R,Yc=tr,Wc=TypeError,Qc=Object.getOwnPropertyDescriptor,Uc=Vc&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(g){return g instanceof TypeError}}(),_c=Tg,Hc=TypeError,Kc=function(g,t){if(!delete g[t])throw Hc("Cannot delete property "+_c(t)+" of "+_c(g))},Xc=De,Jc=Xg,qc=Ze,$c=Me,gu=Le,tu=Uc?function(g,t){if(Yc(g)&&!Qc(g,"length").writable)throw Wc("Cannot set read only .length");return g.length=t}:function(g,t){return g.length=t},eu=Ed,Au=nr,Cu=vo,Iu=Kc,iu=Nd("splice"),ou=Math.max,nu=Math.min;Xc({target:"Array",proto:!0,forced:!iu},{splice:function(g,t){var e,A,C,I,i,o,n=Jc(this),r=gu(n),s=qc(g,r),a=arguments.length;for(0===a?e=A=0:1===a?(e=0,A=r-s):(e=a-2,A=nu(ou($c(t),0),r-s)),eu(r+e-A),C=Au(n,A),I=0;Ir-A+e;I--)Iu(n,I-1)}else if(e>A)for(I=r-A;I>s;I--)o=I+e-1,(i=I+A-1)in n?n[o]=n[i]:Iu(n,o);for(I=0;I1?arguments[1]:void 0)}});var vu=FA("Array").includes,yu=eg,mu=b,bu=ht("match"),wu=function(g){var t;return yu(g)&&(void 0!==(t=g[bu])?!!t:"RegExp"==mu(g))},xu=TypeError,ku=ht("match"),Eu=De,Ou=function(g){if(wu(g))throw xu("The method doesn't accept regular expressions");return g},Tu=X,Du=pC,Nu=function(g){var t=/./;try{"/./"[g](t)}catch(e){try{return t[ku]=!1,"/./"[g](t)}catch(g){}}return!1},Ru=f("".indexOf);Eu({target:"String",proto:!0,forced:!Nu("includes")},{includes:function(g){return!!~Ru(Du(Tu(this)),Du(Ou(g)),arguments.length>1?arguments[1]:void 0)}});var Pu=FA("String").includes,Mu=rg,Bu=vu,zu=Pu,Su=Array.prototype,Zu=String.prototype,Fu=function(g){var t=g.includes;return g===Su||Mu(Su,g)&&t===Su.includes?Bu:"string"==typeof g||g===Zu||Mu(Zu,g)&&t===Zu.includes?zu:t},Gu=Fu;!function(g){g.exports=Gu}(pu);var ju=e(uu),Lu={},Vu={get exports(){return Lu},set exports(g){Lu=g}},Yu=Xg,Wu=MI,Qu=kI;De({target:"Object",stat:!0,forced:o((function(){Wu(1)})),sham:!Qu},{getPrototypeOf:function(g){return Wu(Yu(g))}});var Uu=Ag.Object.getPrototypeOf;!function(g){g.exports=Uu}(Vu);var _u=e(Lu),Hu={},Ku={get exports(){return Hu},set exports(g){Hu=g}},Xu=ur.filter;De({target:"Array",proto:!0,forced:!Nd("filter")},{filter:function(g){return Xu(this,g,arguments.length>1?arguments[1]:void 0)}});var Ju=FA("Array").filter,qu=rg,$u=Ju,gp=Array.prototype,tp=function(g){var t=g.filter;return g===gp||qu(gp,g)&&t===gp.filter?$u:t},ep=tp;!function(g){g.exports=ep}(Ku);var Ap=e(Hu),Cp={},Ip={get exports(){return Cp},set exports(g){Cp=g}},ip=R,op=f,np=AA,rp=$,sp=op(z.f),ap=op([].push),dp=function(g){return function(t){for(var e,A=rp(t),C=np(A),I=C.length,i=0,o=[];I>i;)e=C[i++],ip&&!sp(A,e)||ap(o,g?[e,A[e]]:A[e]);return o}},hp={entries:dp(!0),values:dp(!1)}.values;De({target:"Object",stat:!0},{values:function(g){return hp(g)}});var lp=Ag.Object.values;!function(g){g.exports=lp}(Ip);var cp={},up={get exports(){return cp},set exports(g){cp=g}},pp="\t\n\v\f\r                 \u2028\u2029\ufeff",fp=X,vp=pC,yp=pp,mp=f("".replace),bp=RegExp("^["+yp+"]+"),wp=RegExp("(^|[^"+yp+"])["+yp+"]+$"),xp=function(g){return function(t){var e=vp(fp(t));return 1&g&&(e=mp(e,bp,"")),2&g&&(e=mp(e,wp,"$1")),e}},kp={start:xp(1),end:xp(2),trim:xp(3)},Ep=i,Op=o,Tp=f,Dp=pC,Np=kp.trim,Rp=pp,Pp=Ep.parseInt,Mp=Ep.Symbol,Bp=Mp&&Mp.iterator,zp=/^[+-]?0x/i,Sp=Tp(zp.exec),Zp=8!==Pp(Rp+"08")||22!==Pp(Rp+"0x16")||Bp&&!Op((function(){Pp(Object(Bp))}))?function(g,t){var e=Np(Dp(g));return Pp(e,t>>>0||(Sp(zp,e)?16:10))}:Pp;De({global:!0,forced:parseInt!=Zp},{parseInt:Zp});var Fp=Ag.parseInt;!function(g){g.exports=Fp}(up);var Gp=e(cp),jp={},Lp={get exports(){return jp},set exports(g){jp=g}},Vp=De,Yp=Ue.indexOf,Wp=cc,Qp=k([].indexOf),Up=!!Qp&&1/Qp([1],1,-0)<0;Vp({target:"Array",proto:!0,forced:Up||!Wp("indexOf")},{indexOf:function(g){var t=arguments.length>1?arguments[1]:void 0;return Up?Qp(this,g,t)||0:Yp(this,g,t)}});var _p=FA("Array").indexOf,Hp=rg,Kp=_p,Xp=Array.prototype,Jp=function(g){var t=g.indexOf;return g===Xp||Hp(Xp,g)&&t===Xp.indexOf?Kp:t},qp=Jp;!function(g){g.exports=qp}(Lp);var $p=e(jp),gf={},tf={get exports(){return gf},set exports(g){gf=g}},ef=qC.PROPER,Af=o,Cf=pp,If=kp.trim;De({target:"String",proto:!0,forced:function(g){return Af((function(){return!!Cf[g]()||"​…᠎"!=="​…᠎"[g]()||ef&&Cf[g].name!==g}))}("trim")},{trim:function(){return If(this)}});var of=FA("String").trim,nf=rg,rf=of,sf=String.prototype,af=function(g){var t=g.trim;return"string"==typeof g||g===sf||nf(sf,g)&&t===sf.trim?rf:t},df=af;!function(g){g.exports=df}(tf);var hf={},lf={get exports(){return hf},set exports(g){hf=g}};De({target:"Object",stat:!0,sham:!R},{create:xI});var cf=Ag.Object,uf=function(g,t){return cf.create(g,t)};!function(g){g.exports=uf}(lf);var pf=e(hf),ff={},vf={get exports(){return ff},set exports(g){ff=g}},yf=Ag,mf=h;yf.JSON||(yf.JSON={stringify:JSON.stringify});var bf=function(g,t,e){return mf(yf.JSON.stringify,null,arguments)},wf=bf;!function(g){g.exports=wf}(vf);var xf=e(ff),kf={},Ef={get exports(){return kf},set exports(g){kf=g}},Of="function"==typeof Bun&&Bun&&"string"==typeof Bun.version,Tf=TypeError,Df=function(g,t){if(ge,i=Pf(A)?A:Zf(A),o=I?zf(arguments,e):[],n=I?function(){Rf(i,this,o)}:i;return t?g(n,C):g(n)}:g},jf=De,Lf=i,Vf=Gf(Lf.setInterval,!0);jf({global:!0,bind:!0,forced:Lf.setInterval!==Vf},{setInterval:Vf});var Yf=De,Wf=i,Qf=Gf(Wf.setTimeout,!0);Yf({global:!0,bind:!0,forced:Wf.setTimeout!==Qf},{setTimeout:Qf});var Uf=Ag.setTimeout;!function(g){g.exports=Uf}(Ef);var _f=e(kf),Hf={},Kf={get exports(){return Hf},set exports(g){Hf=g}},Xf=Xg,Jf=Ze,qf=Le,$f=function(g){for(var t=Xf(this),e=qf(t),A=arguments.length,C=Jf(A>1?arguments[1]:void 0,e),I=A>2?arguments[2]:void 0,i=void 0===I?e:Jf(I,e);i>C;)t[C++]=g;return t};De({target:"Array",proto:!0},{fill:$f});var gv=FA("Array").fill,tv=rg,ev=gv,Av=Array.prototype,Cv=function(g){var t=g.fill;return g===Av||tv(Av,g)&&t===Av.fill?ev:t},Iv=Cv;!function(g){g.exports=Iv}(Kf);var iv,ov=e(Hf); +/*! Hammer.JS - v2.0.17-rc - 2019-12-16 + * http://naver.github.io/egjs + * + * Forked By Naver egjs + * Copyright (c) hammerjs + * Licensed under the MIT license */function nv(){return nv=Object.assign||function(g){for(var t=1;t-1}var qv=function(){function g(g,t){this.manager=g,this.set(t)}var t=g.prototype;return t.set=function(g){g===bv&&(g=this.compute()),mv&&this.manager.element.style&&Tv[g]&&(this.manager.element.style[yv]=g),this.actions=g.toLowerCase().trim()},t.update=function(){this.set(this.manager.options.touchAction)},t.compute=function(){var g=[];return Kv(this.manager.recognizers,(function(t){Xv(t.options.enable,[t])&&(g=g.concat(t.getTouchAction()))})),function(g){if(Jv(g,kv))return kv;var t=Jv(g,Ev),e=Jv(g,Ov);return t&&e?kv:t||e?t?Ev:Ov:Jv(g,xv)?xv:wv}(g.join(" "))},t.preventDefaults=function(g){var t=g.srcEvent,e=g.offsetDirection;if(this.manager.session.prevented)t.preventDefault();else{var A=this.actions,C=Jv(A,kv)&&!Tv[kv],I=Jv(A,Ov)&&!Tv[Ov],i=Jv(A,Ev)&&!Tv[Ev];if(C){var o=1===g.pointers.length,n=g.distance<2,r=g.deltaTime<250;if(o&&n&&r)return}if(!i||!I)return C||I&&e&Wv||i&&e&Qv?this.preventSrc(t):void 0}},t.preventSrc=function(g){this.manager.session.prevented=!0,g.preventDefault()},g}();function $v(g,t){for(;g;){if(g===t)return!0;g=g.parentNode}return!1}function gy(g){var t=g.length;if(1===t)return{x:uv(g[0].clientX),y:uv(g[0].clientY)};for(var e=0,A=0,C=0;C=pv(t)?g<0?jv:Lv:t<0?Vv:Yv}function Iy(g,t,e){return{x:t/g||0,y:e/g||0}}function iy(g,t){var e=g.session,A=t.pointers,C=A.length;e.firstInput||(e.firstInput=ty(t)),C>1&&!e.firstMultiple?e.firstMultiple=ty(t):1===C&&(e.firstMultiple=!1);var I=e.firstInput,i=e.firstMultiple,o=i?i.center:I.center,n=t.center=gy(A);t.timeStamp=fv(),t.deltaTime=t.timeStamp-I.timeStamp,t.angle=Ay(o,n),t.distance=ey(o,n),function(g,t){var e=t.center,A=g.offsetDelta||{},C=g.prevDelta||{},I=g.prevInput||{};t.eventType!==zv&&I.eventType!==Zv||(C=g.prevDelta={x:I.deltaX||0,y:I.deltaY||0},A=g.offsetDelta={x:e.x,y:e.y}),t.deltaX=C.x+(e.x-A.x),t.deltaY=C.y+(e.y-A.y)}(e,t),t.offsetDirection=Cy(t.deltaX,t.deltaY);var r,s,a=Iy(t.deltaTime,t.deltaX,t.deltaY);t.overallVelocityX=a.x,t.overallVelocityY=a.y,t.overallVelocity=pv(a.x)>pv(a.y)?a.x:a.y,t.scale=i?(r=i.pointers,ey((s=A)[0],s[1],Hv)/ey(r[0],r[1],Hv)):1,t.rotation=i?function(g,t){return Ay(t[1],t[0],Hv)+Ay(g[1],g[0],Hv)}(i.pointers,A):0,t.maxPointers=e.prevInput?t.pointers.length>e.prevInput.maxPointers?t.pointers.length:e.prevInput.maxPointers:t.pointers.length,function(g,t){var e,A,C,I,i=g.lastInterval||t,o=t.timeStamp-i.timeStamp;if(t.eventType!==Fv&&(o>Bv||void 0===i.velocity)){var n=t.deltaX-i.deltaX,r=t.deltaY-i.deltaY,s=Iy(o,n,r);A=s.x,C=s.y,e=pv(s.x)>pv(s.y)?s.x:s.y,I=Cy(n,r),g.lastInterval=t}else e=i.velocity,A=i.velocityX,C=i.velocityY,I=i.direction;t.velocity=e,t.velocityX=A,t.velocityY=C,t.direction=I}(e,t);var d,h=g.element,l=t.srcEvent;$v(d=l.composedPath?l.composedPath()[0]:l.path?l.path[0]:l.target,h)&&(h=d),t.target=h}function oy(g,t,e){var A=e.pointers.length,C=e.changedPointers.length,I=t&zv&&A-C==0,i=t&(Zv|Fv)&&A-C==0;e.isFirst=!!I,e.isFinal=!!i,I&&(g.session={}),e.eventType=t,iy(g,e),g.emit("hammer.input",e),g.recognize(e),g.session.prevInput=e}function ny(g){return g.trim().split(/\s+/g)}function ry(g,t,e){Kv(ny(t),(function(t){g.addEventListener(t,e,!1)}))}function sy(g,t,e){Kv(ny(t),(function(t){g.removeEventListener(t,e,!1)}))}function ay(g){var t=g.ownerDocument||g;return t.defaultView||t.parentWindow||window}var dy=function(){function g(g,t){var e=this;this.manager=g,this.callback=t,this.element=g.element,this.target=g.options.inputTarget,this.domHandler=function(t){Xv(g.options.enable,[g])&&e.handler(t)},this.init()}var t=g.prototype;return t.handler=function(){},t.init=function(){this.evEl&&ry(this.element,this.evEl,this.domHandler),this.evTarget&&ry(this.target,this.evTarget,this.domHandler),this.evWin&&ry(ay(this.element),this.evWin,this.domHandler)},t.destroy=function(){this.evEl&&sy(this.element,this.evEl,this.domHandler),this.evTarget&&sy(this.target,this.evTarget,this.domHandler),this.evWin&&sy(ay(this.element),this.evWin,this.domHandler)},g}();function hy(g,t,e){if(g.indexOf&&!e)return g.indexOf(t);for(var A=0;Ae[t]})):A.sort()),A}var my={touchstart:zv,touchmove:Sv,touchend:Zv,touchcancel:Fv},by="touchstart touchmove touchend touchcancel",wy=function(g){function t(){var e;return t.prototype.evTarget=by,(e=g.apply(this,arguments)||this).targetIds={},e}return rv(t,g),t.prototype.handler=function(g){var t=my[g.type],e=xy.call(this,g,t);e&&this.callback(this.manager,t,{pointers:e[0],changedPointers:e[1],pointerType:Pv,srcEvent:g})},t}(dy);function xy(g,t){var e,A,C=vy(g.touches),I=this.targetIds;if(t&(zv|Sv)&&1===C.length)return I[C[0].identifier]=!0,[C,C];var i=vy(g.changedTouches),o=[],n=this.target;if(A=C.filter((function(g){return $v(g.target,n)})),t===zv)for(e=0;e-1&&A.splice(g,1)}),Dy)}}function Py(g,t){g&zv?(this.primaryTouch=t.changedPointers[0].identifier,Ry.call(this,t)):g&(Zv|Fv)&&Ry.call(this,t)}function My(g){for(var t=g.srcEvent.clientX,e=g.srcEvent.clientY,A=0;A-1&&this.requireFail.splice(t,1),this},t.hasRequireFailures=function(){return this.requireFail.length>0},t.canRecognizeWith=function(g){return!!this.simultaneous[g.id]},t.emit=function(g){var t=this,e=this.state;function A(e){t.manager.emit(e,g)}e=Gy&&A(t.options.event+Qy(e))},t.tryEmit=function(g){if(this.canEmit())return this.emit(g);this.state=Vy},t.canEmit=function(){for(var g=0;gt.threshold&&C&t.direction},e.attrTest=function(g){return Hy.prototype.attrTest.call(this,g)&&(this.state&Zy||!(this.state&Zy)&&this.directionTest(g))},e.emit=function(t){this.pX=t.deltaX,this.pY=t.deltaY;var e=Ky(t.direction);e&&(t.additionalEvent=this.options.event+e),g.prototype.emit.call(this,t)},t}(Hy),Jy=function(g){function t(t){return void 0===t&&(t={}),g.call(this,nv({event:"swipe",threshold:10,velocity:.3,direction:Wv|Qv,pointers:1},t))||this}rv(t,g);var e=t.prototype;return e.getTouchAction=function(){return Xy.prototype.getTouchAction.call(this)},e.attrTest=function(t){var e,A=this.options.direction;return A&(Wv|Qv)?e=t.overallVelocity:A&Wv?e=t.overallVelocityX:A&Qv&&(e=t.overallVelocityY),g.prototype.attrTest.call(this,t)&&A&t.offsetDirection&&t.distance>this.options.threshold&&t.maxPointers===this.options.pointers&&pv(e)>this.options.velocity&&t.eventType&Zv},e.emit=function(g){var t=Ky(g.offsetDirection);t&&this.manager.emit(this.options.event+t,g),this.manager.emit(this.options.event,g)},t}(Hy),qy=function(g){function t(t){return void 0===t&&(t={}),g.call(this,nv({event:"pinch",threshold:0,pointers:2},t))||this}rv(t,g);var e=t.prototype;return e.getTouchAction=function(){return[kv]},e.attrTest=function(t){return g.prototype.attrTest.call(this,t)&&(Math.abs(t.scale-1)>this.options.threshold||this.state&Zy)},e.emit=function(t){if(1!==t.scale){var e=t.scale<1?"in":"out";t.additionalEvent=this.options.event+e}g.prototype.emit.call(this,t)},t}(Hy),$y=function(g){function t(t){return void 0===t&&(t={}),g.call(this,nv({event:"rotate",threshold:0,pointers:2},t))||this}rv(t,g);var e=t.prototype;return e.getTouchAction=function(){return[kv]},e.attrTest=function(t){return g.prototype.attrTest.call(this,t)&&(Math.abs(t.rotation)>this.options.threshold||this.state&Zy)},t}(Hy),gm=function(g){function t(t){var e;return void 0===t&&(t={}),(e=g.call(this,nv({event:"press",pointers:1,time:251,threshold:9},t))||this)._timer=null,e._input=null,e}rv(t,g);var e=t.prototype;return e.getTouchAction=function(){return[wv]},e.process=function(g){var t=this,e=this.options,A=g.pointers.length===e.pointers,C=g.distancee.time;if(this._input=g,!C||!A||g.eventType&(Zv|Fv)&&!I)this.reset();else if(g.eventType&zv)this.reset(),this._timer=setTimeout((function(){t.state=jy,t.tryEmit()}),e.time);else if(g.eventType&Zv)return jy;return Vy},e.reset=function(){clearTimeout(this._timer)},e.emit=function(g){this.state===jy&&(g&&g.eventType&Zv?this.manager.emit(this.options.event+"up",g):(this._input.timeStamp=fv(),this.manager.emit(this.options.event,this._input)))},t}(Uy),tm={domEvents:!1,touchAction:bv,enable:!0,inputTarget:null,inputClass:null,cssProps:{userSelect:"none",touchSelect:"none",touchCallout:"none",contentZooming:"none",userDrag:"none",tapHighlightColor:"rgba(0,0,0,0)"}},em=[[$y,{enable:!1}],[qy,{enable:!1},["rotate"]],[Jy,{direction:Wv}],[Xy,{direction:Wv},["swipe"]],[_y],[_y,{event:"doubletap",taps:2},["tap"]],[gm]];function Am(g,t){var e,A=g.element;A.style&&(Kv(g.options.cssProps,(function(C,I){e=vv(A.style,I),t?(g.oldCssProps[e]=A.style[e],A.style[e]=C):A.style[e]=g.oldCssProps[e]||""})),t||(g.oldCssProps={}))}var Cm=function(){function g(g,t){var e,A=this;this.options=dv({},tm,t||{}),this.options.inputTarget=this.options.inputTarget||g,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=g,this.input=new((e=this).options.inputClass||(Nv?fy:Rv?wy:Dv?By:Ty))(e,oy),this.touchAction=new qv(this,this.options.touchAction),Am(this,!0),Kv(this.options.recognizers,(function(g){var t=A.add(new g[0](g[1]));g[2]&&t.recognizeWith(g[2]),g[3]&&t.requireFailure(g[3])}),this)}var t=g.prototype;return t.set=function(g){return dv(this.options,g),g.touchAction&&this.touchAction.update(),g.inputTarget&&(this.input.destroy(),this.input.target=g.inputTarget,this.input.init()),this},t.stop=function(g){this.session.stopped=g?2:1},t.recognize=function(g){var t=this.session;if(!t.stopped){var e;this.touchAction.preventDefaults(g);var A=this.recognizers,C=t.curRecognizer;(!C||C&&C.state&jy)&&(t.curRecognizer=null,C=null);for(var I=0;I\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",C=window.console&&(window.console.warn||window.console.log);return C&&C.call(window.console,A,e),g.apply(this,arguments)}}var am=sm((function(g,t,e){for(var A=Object.keys(t),C=0;C=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function fm(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e2)return mm.apply(void 0,Bl(A=[ym(t[0],t[1])]).call(A,wl(Sl(t).call(t,2))));var C,I=t[0],i=t[1],o=pm(jl(i));try{for(o.s();!(C=o.n()).done;){var n=C.value;Object.prototype.propertyIsEnumerable.call(i,n)&&(i[n]===vm?delete I[n]:null===I[n]||null===i[n]||"object"!==kh(I[n])||"object"!==kh(i[n])||Vl(I[n])||Vl(i[n])?I[n]=bm(i[n]):I[n]=mm(I[n],i[n]))}}catch(g){o.e(g)}finally{o.f()}return I}function bm(g){return Vl(g)?ql(g).call(g,(function(g){return bm(g)})):"object"===kh(g)&&null!==g?mm({},g):g}function wm(g){for(var t=0,e=Cc(g);t>>0,g=(C*=g)>>>0,g+=4294967296*(C-=g)}return 2.3283064365386963e-10*(g>>>0)}}(),t=g(" "),e=g(" "),A=g(" "),C=0;C2&&void 0!==arguments[2]&&arguments[2];for(var A in g)if(void 0!==t[A])if(null===t[A]||"object"!==kh(t[A]))Bm(g,t,A,e);else{var C=g[A],I=t[A];Mm(C)&&Mm(I)&&zm(C,I,e)}}function Sm(g,t,e){var A=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(Vl(e))throw new TypeError("Arrays are not supported by deepExtend");for(var C=0;C3&&void 0!==arguments[3]&&arguments[3];if(Vl(e))throw new TypeError("Arrays are not supported by deepExtend");for(var C in e)if(Object.prototype.hasOwnProperty.call(e,C)&&!ju(g).call(g,C))if(e[C]&&e[C].constructor===Object)void 0===t[C]&&(t[C]={}),t[C].constructor===Object?Fm(t[C],e[C]):Bm(t,e,C,A);else if(Vl(e[C])){t[C]=[];for(var I=0;I2&&void 0!==arguments[2]&&arguments[2],A=arguments.length>3&&void 0!==arguments[3]&&arguments[3];for(var C in t)if(Object.prototype.hasOwnProperty.call(t,C)||!0===e)if("object"===kh(t[C])&&null!==t[C]&&_u(t[C])===Object.prototype)void 0===g[C]?g[C]=Fm({},t[C],e):"object"===kh(g[C])&&null!==g[C]&&_u(g[C])===Object.prototype?Fm(g[C],t[C],e):Bm(g,t,C,A);else if(Vl(t[C])){var I;g[C]=Sl(I=t[C]).call(I)}else Bm(g,t,C,A);return g}function Gm(g,t){var e;return Bl(e=[]).call(e,wl(g),[t])}function jm(g){return g.getBoundingClientRect().top}function Lm(g,t){if(Vl(g))for(var e=g.length,A=0;A3&&void 0!==arguments[3]?arguments[3]:{},C=function(g){return null!=g},I=function(g){return null!==g&&"object"===kh(g)};if(!I(g))throw new Error("Parameter mergeTarget must be an object");if(!I(t))throw new Error("Parameter options must be an object");if(!C(e))throw new Error("Parameter option must have a value");if(!I(A))throw new Error("Parameter globalOptions must be an object");var i=t[e],o=I(A)&&!function(g){for(var t in g)if(Object.prototype.hasOwnProperty.call(g,t))return!1;return!0}(A)?A[e]:void 0,n=o?o.enabled:void 0;if(void 0!==i){if("boolean"==typeof i)return I(g[e])||(g[e]={}),void(g[e].enabled=i);if(null===i&&!I(g[e])){if(!C(o))return;g[e]=pf(o)}if(I(i)){var r=!0;void 0!==i.enabled?r=i.enabled:void 0!==n&&(r=o.enabled),function(g,t,e){I(g[e])||(g[e]={});var A=t[e],C=g[e];for(var i in A)Object.prototype.hasOwnProperty.call(A,i)&&(C[i]=A[i])}(g,t,e),g[e].enabled=r}}}var $m={linear:function(g){return g},easeInQuad:function(g){return g*g},easeOutQuad:function(g){return g*(2-g)},easeInOutQuad:function(g){return g<.5?2*g*g:(4-2*g)*g-1},easeInCubic:function(g){return g*g*g},easeOutCubic:function(g){return--g*g*g+1},easeInOutCubic:function(g){return g<.5?4*g*g*g:(g-1)*(2*g-2)*(2*g-2)+1},easeInQuart:function(g){return g*g*g*g},easeOutQuart:function(g){return 1- --g*g*g*g},easeInOutQuart:function(g){return g<.5?8*g*g*g*g:1-8*--g*g*g*g},easeInQuint:function(g){return g*g*g*g*g},easeOutQuint:function(g){return 1+--g*g*g*g*g},easeInOutQuint:function(g){return g<.5?16*g*g*g*g*g:1+16*--g*g*g*g*g}};function gb(g,t){var e;Vl(t)||(t=[t]);var A,C=pm(g);try{for(C.s();!(A=C.n()).done;){var I=A.value;if(I){e=I[t[0]];for(var i=1;i0&&void 0!==arguments[0]?arguments[0]:1;cd(this,g),this.pixelRatio=t,this.generated=!1,this.centerCoordinates={x:144.5,y:144.5},this.r=289*.49,this.color={r:255,g:255,b:255,a:1},this.hueCircle=void 0,this.initialColor={r:255,g:255,b:255,a:1},this.previousColor=void 0,this.applied=!1,this.updateCallback=function(){},this.closeCallback=function(){},this._create()}return Bh(g,[{key:"insertTo",value:function(g){void 0!==this.hammer&&(this.hammer.destroy(),this.hammer=void 0),this.container=g,this.container.appendChild(this.frame),this._bindHammer(),this._setSize()}},{key:"setUpdateCallback",value:function(g){if("function"!=typeof g)throw new Error("Function attempted to set as colorPicker update callback is not a function.");this.updateCallback=g}},{key:"setCloseCallback",value:function(g){if("function"!=typeof g)throw new Error("Function attempted to set as colorPicker closing callback is not a function.");this.closeCallback=g}},{key:"_isColorString",value:function(g){if("string"==typeof g)return tb[g]}},{key:"setColor",value:function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if("none"!==g){var e,A=this._isColorString(g);if(void 0!==A&&(g=A),!0===Pm(g)){if(!0===Xm(g)){var C=g.substr(4).substr(0,g.length-5).split(",");e={r:C[0],g:C[1],b:C[2],a:1}}else if(!0===function(g){return Nm.test(g)}(g)){var I=g.substr(5).substr(0,g.length-6).split(",");e={r:I[0],g:I[1],b:I[2],a:I[3]}}else if(!0===Km(g)){var i=Vm(g);e={r:i.r,g:i.g,b:i.b,a:1}}}else if(g instanceof Object&&void 0!==g.r&&void 0!==g.g&&void 0!==g.b){var o=void 0!==g.a?g.a:"1.0";e={r:g.r,g:g.g,b:g.b,a:o}}if(void 0===e)throw new Error("Unknown color passed to the colorPicker. Supported are strings: rgb, hex, rgba. Object: rgb ({r:r,g:g,b:b,[a:a]}). Supplied: "+xf(g));this._setColor(e,t)}}},{key:"show",value:function(){void 0!==this.closeCallback&&(this.closeCallback(),this.closeCallback=void 0),this.applied=!1,this.frame.style.display="block",this._generateHueCircle()}},{key:"_hide",value:function(){var g=this;!0===(!(arguments.length>0&&void 0!==arguments[0])||arguments[0])&&(this.previousColor=yA({},this.color)),!0===this.applied&&this.updateCallback(this.initialColor),this.frame.style.display="none",_f((function(){void 0!==g.closeCallback&&(g.closeCallback(),g.closeCallback=void 0)}),0)}},{key:"_save",value:function(){this.updateCallback(this.color),this.applied=!1,this._hide()}},{key:"_apply",value:function(){this.applied=!0,this.updateCallback(this.color),this._updatePicker(this.color)}},{key:"_loadLast",value:function(){void 0!==this.previousColor?this.setColor(this.previousColor,!1):alert("There is no last color to load...")}},{key:"_setColor",value:function(g){!0===(!(arguments.length>1&&void 0!==arguments[1])||arguments[1])&&(this.initialColor=yA({},g)),this.color=g;var t=Um(g.r,g.g,g.b),e=2*Math.PI,A=this.r*t.s,C=this.centerCoordinates.x+A*Math.sin(e*t.h),I=this.centerCoordinates.y+A*Math.cos(e*t.h);this.colorPickerSelector.style.left=C-.5*this.colorPickerSelector.clientWidth+"px",this.colorPickerSelector.style.top=I-.5*this.colorPickerSelector.clientHeight+"px",this._updatePicker(g)}},{key:"_setOpacity",value:function(g){this.color.a=g/100,this._updatePicker(this.color)}},{key:"_setBrightness",value:function(g){var t=Um(this.color.r,this.color.g,this.color.b);t.v=g/100;var e=_m(t.h,t.s,t.v);e.a=this.color.a,this.color=e,this._updatePicker()}},{key:"_updatePicker",value:function(){var g=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.color,t=Um(g.r,g.g,g.b),e=this.colorPickerCanvas.getContext("2d");void 0===this.pixelRation&&(this.pixelRatio=(window.devicePixelRatio||1)/(e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1)),e.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);var A=this.colorPickerCanvas.clientWidth,C=this.colorPickerCanvas.clientHeight;e.clearRect(0,0,A,C),e.putImageData(this.hueCircle,0,0),e.fillStyle="rgba(0,0,0,"+(1-t.v)+")",e.circle(this.centerCoordinates.x,this.centerCoordinates.y,this.r),ov(e).call(e),this.brightnessRange.value=100*t.v,this.opacityRange.value=100*g.a,this.initialColorDiv.style.backgroundColor="rgba("+this.initialColor.r+","+this.initialColor.g+","+this.initialColor.b+","+this.initialColor.a+")",this.newColorDiv.style.backgroundColor="rgba("+this.color.r+","+this.color.g+","+this.color.b+","+this.color.a+")"}},{key:"_setSize",value:function(){this.colorPickerCanvas.style.width="100%",this.colorPickerCanvas.style.height="100%",this.colorPickerCanvas.width=289*this.pixelRatio,this.colorPickerCanvas.height=289*this.pixelRatio}},{key:"_create",value:function(){var g,t,e,A;if(this.frame=document.createElement("div"),this.frame.className="vis-color-picker",this.colorPickerDiv=document.createElement("div"),this.colorPickerSelector=document.createElement("div"),this.colorPickerSelector.className="vis-selector",this.colorPickerDiv.appendChild(this.colorPickerSelector),this.colorPickerCanvas=document.createElement("canvas"),this.colorPickerDiv.appendChild(this.colorPickerCanvas),this.colorPickerCanvas.getContext){var C=this.colorPickerCanvas.getContext("2d");this.pixelRatio=(window.devicePixelRatio||1)/(C.webkitBackingStorePixelRatio||C.mozBackingStorePixelRatio||C.msBackingStorePixelRatio||C.oBackingStorePixelRatio||C.backingStorePixelRatio||1),this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}else{var I=document.createElement("DIV");I.style.color="red",I.style.fontWeight="bold",I.style.padding="10px",I.innerText="Error: your browser does not support HTML canvas",this.colorPickerCanvas.appendChild(I)}this.colorPickerDiv.className="vis-color",this.opacityDiv=document.createElement("div"),this.opacityDiv.className="vis-opacity",this.brightnessDiv=document.createElement("div"),this.brightnessDiv.className="vis-brightness",this.arrowDiv=document.createElement("div"),this.arrowDiv.className="vis-arrow",this.opacityRange=document.createElement("input");try{this.opacityRange.type="range",this.opacityRange.min="0",this.opacityRange.max="100"}catch(g){}this.opacityRange.value="100",this.opacityRange.className="vis-range",this.brightnessRange=document.createElement("input");try{this.brightnessRange.type="range",this.brightnessRange.min="0",this.brightnessRange.max="100"}catch(g){}this.brightnessRange.value="100",this.brightnessRange.className="vis-range",this.opacityDiv.appendChild(this.opacityRange),this.brightnessDiv.appendChild(this.brightnessRange);var i=this;this.opacityRange.onchange=function(){i._setOpacity(this.value)},this.opacityRange.oninput=function(){i._setOpacity(this.value)},this.brightnessRange.onchange=function(){i._setBrightness(this.value)},this.brightnessRange.oninput=function(){i._setBrightness(this.value)},this.brightnessLabel=document.createElement("div"),this.brightnessLabel.className="vis-label vis-brightness",this.brightnessLabel.innerText="brightness:",this.opacityLabel=document.createElement("div"),this.opacityLabel.className="vis-label vis-opacity",this.opacityLabel.innerText="opacity:",this.newColorDiv=document.createElement("div"),this.newColorDiv.className="vis-new-color",this.newColorDiv.innerText="new",this.initialColorDiv=document.createElement("div"),this.initialColorDiv.className="vis-initial-color",this.initialColorDiv.innerText="initial",this.cancelButton=document.createElement("div"),this.cancelButton.className="vis-button vis-cancel",this.cancelButton.innerText="cancel",this.cancelButton.onclick=QA(g=this._hide).call(g,this,!1),this.applyButton=document.createElement("div"),this.applyButton.className="vis-button vis-apply",this.applyButton.innerText="apply",this.applyButton.onclick=QA(t=this._apply).call(t,this),this.saveButton=document.createElement("div"),this.saveButton.className="vis-button vis-save",this.saveButton.innerText="save",this.saveButton.onclick=QA(e=this._save).call(e,this),this.loadButton=document.createElement("div"),this.loadButton.className="vis-button vis-load",this.loadButton.innerText="load last",this.loadButton.onclick=QA(A=this._loadLast).call(A,this),this.frame.appendChild(this.colorPickerDiv),this.frame.appendChild(this.arrowDiv),this.frame.appendChild(this.brightnessLabel),this.frame.appendChild(this.brightnessDiv),this.frame.appendChild(this.opacityLabel),this.frame.appendChild(this.opacityDiv),this.frame.appendChild(this.newColorDiv),this.frame.appendChild(this.initialColorDiv),this.frame.appendChild(this.cancelButton),this.frame.appendChild(this.applyButton),this.frame.appendChild(this.saveButton),this.frame.appendChild(this.loadButton)}},{key:"_bindHammer",value:function(){var g=this;this.drag={},this.pinch={},this.hammer=new km(this.colorPickerCanvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.on("hammer.input",(function(t){t.isFirst&&g._moveSelector(t)})),this.hammer.on("tap",(function(t){g._moveSelector(t)})),this.hammer.on("panstart",(function(t){g._moveSelector(t)})),this.hammer.on("panmove",(function(t){g._moveSelector(t)})),this.hammer.on("panend",(function(t){g._moveSelector(t)}))}},{key:"_generateHueCircle",value:function(){if(!1===this.generated){var g=this.colorPickerCanvas.getContext("2d");void 0===this.pixelRation&&(this.pixelRatio=(window.devicePixelRatio||1)/(g.webkitBackingStorePixelRatio||g.mozBackingStorePixelRatio||g.msBackingStorePixelRatio||g.oBackingStorePixelRatio||g.backingStorePixelRatio||1)),g.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0);var t,e,A,C,I=this.colorPickerCanvas.clientWidth,i=this.colorPickerCanvas.clientHeight;g.clearRect(0,0,I,i),this.centerCoordinates={x:.5*I,y:.5*i},this.r=.49*I;var o,n=2*Math.PI/360,r=1/this.r;for(A=0;A<360;A++)for(C=0;C3&&void 0!==arguments[3]?arguments[3]:1,I=arguments.length>4&&void 0!==arguments[4]?arguments[4]:function(){return!1};cd(this,g),this.parent=t,this.changedOptions=[],this.container=e,this.allowCreation=!1,this.hideOption=I,this.options={},this.initialized=!1,this.popupCounter=0,this.defaultOptions={enabled:!1,filter:!0,container:void 0,showButton:!0},yA(this.options,this.defaultOptions),this.configureOptions=A,this.moduleOptions={},this.domElements=[],this.popupDiv={},this.popupLimit=5,this.popupHistory={},this.colorPicker=new eb(C),this.wrapper=void 0}return Bh(g,[{key:"setOptions",value:function(g){if(void 0!==g){this.popupHistory={},this._removePopup();var t=!0;if("string"==typeof g)this.options.filter=g;else if(Vl(g))this.options.filter=g.join();else if("object"===kh(g)){if(null==g)throw new TypeError("options cannot be null");void 0!==g.container&&(this.options.container=g.container),void 0!==Ap(g)&&(this.options.filter=Ap(g)),void 0!==g.showButton&&(this.options.showButton=g.showButton),void 0!==g.enabled&&(t=g.enabled)}else"boolean"==typeof g?(this.options.filter=!0,t=g):"function"==typeof g&&(this.options.filter=g,t=!0);!1===Ap(this.options)&&(t=!1),this.options.enabled=t}this._clean()}},{key:"setModuleOptions",value:function(g){this.moduleOptions=g,!0===this.options.enabled&&(this._clean(),void 0!==this.options.container&&(this.container=this.options.container),this._create())}},{key:"_create",value:function(){this._clean(),this.changedOptions=[];var g=Ap(this.options),t=0,e=!1;for(var A in this.configureOptions)Object.prototype.hasOwnProperty.call(this.configureOptions,A)&&(this.allowCreation=!1,e=!1,"function"==typeof g?e=(e=g(A,[]))||this._handleObject(this.configureOptions[A],[A],!0):!0!==g&&-1===$p(g).call(g,A)||(e=!0),!1!==e&&(this.allowCreation=!0,t>0&&this._makeItem([]),this._makeHeader(A),this._handleObject(this.configureOptions[A],[A])),t++);this._makeButton(),this._push()}},{key:"_push",value:function(){this.wrapper=document.createElement("div"),this.wrapper.className="vis-configuration-wrapper",this.container.appendChild(this.wrapper);for(var g=0;g1?e-1:0),C=1;C2&&void 0!==arguments[2]&&arguments[2],A=document.createElement("div");if(A.className="vis-configuration vis-config-label vis-config-s"+t.length,!0===e){for(;A.firstChild;)A.removeChild(A.firstChild);A.appendChild(Ab("i","b",g))}else A.innerText=g+":";return A}},{key:"_makeDropdown",value:function(g,t,e){var A=document.createElement("select");A.className="vis-configuration vis-config-select";var C=0;void 0!==t&&-1!==$p(g).call(g,t)&&(C=$p(g).call(g,t));for(var I=0;II&&1!==I&&(o.max=Math.ceil(t*s),r=o.max,n="range increased"),o.value=t}else o.value=A;var a=document.createElement("input");a.className="vis-configuration vis-config-rangeinput",a.value=o.value;var d=this;o.onchange=function(){a.value=this.value,d._update(Number(this.value),e)},o.oninput=function(){a.value=this.value};var h=this._makeLabel(e[e.length-1],e),l=this._makeItem(e,h,o,a);""!==n&&this.popupHistory[l]!==r&&(this.popupHistory[l]=r,this._setupPopup(n,l))}},{key:"_makeButton",value:function(){var g=this;if(!0===this.options.showButton){var t=document.createElement("div");t.className="vis-configuration vis-config-button",t.innerText="generate options",t.onclick=function(){g._printOptions()},t.onmouseover=function(){t.className="vis-configuration vis-config-button hover"},t.onmouseout=function(){t.className="vis-configuration vis-config-button"},this.optionsContainer=document.createElement("div"),this.optionsContainer.className="vis-configuration vis-config-option-container",this.domElements.push(this.optionsContainer),this.domElements.push(t)}}},{key:"_setupPopup",value:function(g,t){var e=this;if(!0===this.initialized&&!0===this.allowCreation&&this.popupCounter1&&void 0!==arguments[1]?arguments[1]:[],e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],A=!1,C=Ap(this.options),I=!1;for(var i in g)if(Object.prototype.hasOwnProperty.call(g,i)){A=!0;var o=g[i],n=Gm(t,i);if("function"==typeof C&&!1===(A=C(i,t))&&!Vl(o)&&"string"!=typeof o&&"boolean"!=typeof o&&o instanceof Object&&(this.allowCreation=!1,A=this._handleObject(o,n,!0),this.allowCreation=!1===e),!1!==A){I=!0;var r=this._getValue(n);if(Vl(o))this._handleArray(o,r,n);else if("string"==typeof o)this._makeTextInput(o,r,n);else if("boolean"==typeof o)this._makeCheckbox(o,r,n);else if(o instanceof Object){if(!this.hideOption(t,i,this.moduleOptions))if(void 0!==o.enabled){var s=Gm(n,"enabled"),a=this._getValue(s);if(!0===a){var d=this._makeLabel(i,n,!0);this._makeItem(n,d),I=this._handleObject(o,n)||I}else this._makeCheckbox(o,a,n)}else{var h=this._makeLabel(i,n,!0);this._makeItem(n,h),I=this._handleObject(o,n)||I}}else console.error("dont know how to handle",o,i,n)}}return I}},{key:"_handleArray",value:function(g,t,e){"string"==typeof g[0]&&"color"===g[0]?(this._makeColorField(g,t,e),g[1]!==t&&this.changedOptions.push({path:e,value:t})):"string"==typeof g[0]?(this._makeDropdown(g,t,e),g[0]!==t&&this.changedOptions.push({path:e,value:t})):"number"==typeof g[0]&&(this._makeRange(g,t,e),g[0]!==t&&this.changedOptions.push({path:e,value:Number(t)}))}},{key:"_update",value:function(g,t){var e=this._constructOptions(g,t);this.parent.body&&this.parent.body.emitter&&this.parent.body.emitter.emit&&this.parent.body.emitter.emit("configChange",e),this.initialized=!0,this.parent.setOptions(e)}},{key:"_constructOptions",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},A=e;g="false"!==(g="true"===g||g)&&g;for(var C=0;CC-this.padding&&(o=!0),I=o?this.x-e:this.x,i=n?this.y-t:this.y}else(i=this.y-t)+t+this.padding>A&&(i=A-t-this.padding),iC&&(I=C-e-this.padding),Ii.distance?" in "+g.printLocation(I.path,t,"")+"Perhaps it was misplaced? Matching option found at: "+g.printLocation(i.path,i.closestMatch,""):I.distance<=8?'. Did you mean "'+I.closestMatch+'"?'+g.printLocation(I.path,t):". Did you mean one of these: "+g.print(Cc(e))+g.printLocation(A,t),console.error('%cUnknown option detected: "'+t+'"'+C,nb),ob=!0}},{key:"findInOptions",value:function(t,e,A){var C,I=arguments.length>3&&void 0!==arguments[3]&&arguments[3],i=1e9,o="",n=[],r=t.toLowerCase(),s=void 0;for(var a in e){var d=void 0;if(void 0!==e[a].__type__&&!0===I){var h=g.findInOptions(t,e[a],Gm(A,a));i>h.distance&&(o=h.closestMatch,n=h.path,i=h.distance,s=h.indexMatch)}else{var l;-1!==$p(l=a.toLowerCase()).call(l,r)&&(s=a),i>(d=g.levenshteinDistance(t,a))&&(o=a,n=Sl(C=A).call(C),i=d)}}return{closestMatch:o,path:n,distance:i,indexMatch:s}}},{key:"printLocation",value:function(g,t){for(var e="\n\n"+(arguments.length>2&&void 0!==arguments[2]?arguments[2]:"Problem value found at: \n")+"options = {\n",A=0;A":!0,"--":!0},mb="",bb=0,wb="",xb="",kb=vb.NULL;function Eb(){bb++,wb=mb.charAt(bb)}function Ob(){return mb.charAt(bb+1)}function Tb(g){var t=g.charCodeAt(0);return t<47?35===t||46===t:t<59?t>47:t<91?t>64:t<96?95===t:t<123&&t>96}function Db(g,t){if(g||(g={}),t)for(var e in t)t.hasOwnProperty(e)&&(g[e]=t[e]);return g}function Nb(g,t,e){for(var A=t.split("."),C=g;A.length;){var I=A.shift();A.length?(C[I]||(C[I]={}),C=C[I]):C[I]=e}}function Rb(g,t){for(var e,A,C=null,I=[g],i=g;i.parent;)I.push(i.parent),i=i.parent;if(i.nodes)for(e=0,A=i.nodes.length;e=0;e--){var o,n=I[e];n.nodes||(n.nodes=[]),-1===$p(o=n.nodes).call(o,C)&&n.nodes.push(C)}t.attr&&(C.attr=Db(C.attr,t.attr))}function Pb(g,t){if(g.edges||(g.edges=[]),g.edges.push(t),g.edge){var e=Db({},g.edge);t.attr=Db(e,t.attr)}}function Mb(g,t,e,A,C){var I={from:t,to:e,type:A};return g.edge&&(I.attr=Db({},g.edge)),I.attr=Db(I.attr||{},C),null!=C&&C.hasOwnProperty("arrows")&&null!=C.arrows&&(I.arrows={to:{enabled:!0,type:C.arrows.type}},C.arrows=null),I}function Bb(){for(kb=vb.NULL,xb="";" "===wb||"\t"===wb||"\n"===wb||"\r"===wb;)Eb();do{var g=!1;if("#"===wb){for(var t=bb-1;" "===mb.charAt(t)||"\t"===mb.charAt(t);)t--;if("\n"===mb.charAt(t)||""===mb.charAt(t)){for(;""!=wb&&"\n"!=wb;)Eb();g=!0}}if("/"===wb&&"/"===Ob()){for(;""!=wb&&"\n"!=wb;)Eb();g=!0}if("/"===wb&&"*"===Ob()){for(;""!=wb;){if("*"===wb&&"/"===Ob()){Eb(),Eb();break}Eb()}g=!0}for(;" "===wb||"\t"===wb||"\n"===wb||"\r"===wb;)Eb()}while(g);if(""!==wb){var e=wb+Ob();if(yb[e])return kb=vb.DELIMITER,xb=e,Eb(),void Eb();if(yb[wb])return kb=vb.DELIMITER,xb=wb,void Eb();if(Tb(wb)||"-"===wb){for(xb+=wb,Eb();Tb(wb);)xb+=wb,Eb();return"false"===xb?xb=!1:"true"===xb?xb=!0:isNaN(Number(xb))||(xb=Number(xb)),void(kb=vb.IDENTIFIER)}if('"'===wb){for(Eb();""!=wb&&('"'!=wb||'"'===wb&&'"'===Ob());)'"'===wb?(xb+=wb,Eb()):"\\"===wb&&"n"===Ob()?(xb+="\n",Eb()):xb+=wb,Eb();if('"'!=wb)throw jb('End of string " expected');return Eb(),void(kb=vb.IDENTIFIER)}for(kb=vb.UNKNOWN;""!=wb;)xb+=wb,Eb();throw new SyntaxError('Syntax error in part "'+Lb(xb,30)+'"')}kb=vb.DELIMITER}function zb(g){for(;""!==xb&&"}"!=xb;)Sb(g),";"===xb&&Bb()}function Sb(g){var t=Zb(g);if(t)Fb(g,t);else{var e=function(g){if("node"===xb)return Bb(),g.node=Gb(),"node";if("edge"===xb)return Bb(),g.edge=Gb(),"edge";if("graph"===xb)return Bb(),g.graph=Gb(),"graph";return null}(g);if(!e){if(kb!=vb.IDENTIFIER)throw jb("Identifier expected");var A=xb;if(Bb(),"="===xb){if(Bb(),kb!=vb.IDENTIFIER)throw jb("Identifier expected");g[A]=xb,Bb()}else!function(g,t){var e={id:t},A=Gb();A&&(e.attr=A);Rb(g,e),Fb(g,t)}(g,A)}}}function Zb(g){var t=null;if("subgraph"===xb&&((t={}).type="subgraph",Bb(),kb===vb.IDENTIFIER&&(t.id=xb,Bb())),"{"===xb){if(Bb(),t||(t={}),t.parent=g,t.node=g.node,t.edge=g.edge,t.graph=g.graph,zb(t),"}"!=xb)throw jb("Angle bracket } expected");Bb(),delete t.node,delete t.edge,delete t.graph,delete t.parent,g.subgraphs||(g.subgraphs=[]),g.subgraphs.push(t)}return t}function Fb(g,t){for(;"->"===xb||"--"===xb;){var e,A=xb;Bb();var C=Zb(g);if(C)e=C;else{if(kb!=vb.IDENTIFIER)throw jb("Identifier or subgraph expected");Rb(g,{id:e=xb}),Bb()}Pb(g,Mb(g,t,e,A,Gb())),t=e}}function Gb(){for(var g,t,e=null,A={dashed:!0,solid:!1,dotted:[1,5]},C={dot:"circle",box:"box",crow:"crow",curve:"curve",icurve:"inv_curve",normal:"triangle",inv:"inv_triangle",diamond:"diamond",tee:"bar",vee:"vee"},I=new Array,i=new Array;"["===xb;){for(Bb(),e={};""!==xb&&"]"!=xb;){if(kb!=vb.IDENTIFIER)throw jb("Attribute name expected");var o=xb;if(Bb(),"="!=xb)throw jb("Equal sign = expected");if(Bb(),kb!=vb.IDENTIFIER)throw jb("Attribute value expected");var n=xb;"style"===o&&(n=A[n]),"arrowhead"===o&&(o="arrows",n={to:{enabled:!0,type:C[n]}}),"arrowtail"===o&&(o="arrows",n={from:{enabled:!0,type:C[n]}}),I.push({attr:e,name:o,value:n}),i.push(o),Bb(),","==xb&&Bb()}if("]"!=xb)throw jb("Bracket ] expected");Bb()}if(ju(i).call(i,"dir")){var r={arrows:{}};for(g=0;g"===g.type&&(t.arrows="to"),t};Ec(C=e.edges).call(C,(function(g){var t,e,C,i,o,n,r;(t=g.from instanceof Object?g.from.nodes:{id:g.from},e=g.to instanceof Object?g.to.nodes:{id:g.to},g.from instanceof Object&&g.from.edges)&&Ec(C=g.from.edges).call(C,(function(g){var t=I(g);A.edges.push(t)}));(o=e,n=function(t,e){var C=Mb(A,t.id,e.id,g.type,g.attr),i=I(C);A.edges.push(i)},Vl(i=t)?Ec(i).call(i,(function(g){Vl(o)?Ec(o).call(o,(function(t){n(g,t)})):n(g,o)})):Vl(o)?Ec(o).call(o,(function(g){n(i,g)})):n(i,o),g.to instanceof Object&&g.to.edges)&&Ec(r=g.to.edges).call(r,(function(g){var t=I(g);A.edges.push(t)}))}))}return e.attr&&(A.options=e.attr),A}var Qb=Object.freeze({__proto__:null,DOTToGraph:Wb,parseDOT:ub});function Ub(g,t){var e,A={edges:{inheritColor:!1},nodes:{fixed:!1,parseColor:!1}};null!=t&&(null!=t.fixed&&(A.nodes.fixed=t.fixed),null!=t.parseColor&&(A.nodes.parseColor=t.parseColor),null!=t.inheritColor&&(A.edges.inheritColor=t.inheritColor));var C=g.edges,I=ql(C).call(C,(function(g){var t={from:g.source,id:g.id,to:g.target};return null!=g.attributes&&(t.attributes=g.attributes),null!=g.label&&(t.label=g.label),null!=g.attributes&&null!=g.attributes.title&&(t.title=g.attributes.title),"Directed"===g.type&&(t.arrows="to"),g.color&&!1===A.edges.inheritColor&&(t.color=g.color),t}));return{nodes:ql(e=g.nodes).call(e,(function(g){var t={id:g.id,fixed:A.nodes.fixed&&null!=g.x&&null!=g.y};return null!=g.attributes&&(t.attributes=g.attributes),null!=g.label&&(t.label=g.label),null!=g.size&&(t.size=g.size),null!=g.attributes&&null!=g.attributes.title&&(t.title=g.attributes.title),null!=g.title&&(t.title=g.title),null!=g.x&&(t.x=g.x),null!=g.y&&(t.y=g.y),null!=g.color&&(!0===A.nodes.parseColor?t.color=g.color:t.color={background:g.color,border:g.color,highlight:{background:g.color,border:g.color},hover:{background:g.color,border:g.color}}),t})),edges:I}}var _b=Object.freeze({__proto__:null,parseGephi:Ub}),Hb=Object.freeze({__proto__:null,cn:{addDescription:"单击空白处放置新节点。",addEdge:"添加连接线",addNode:"添加节点",back:"返回",close:"關閉",createEdgeError:"无法将连接线连接到群集。",del:"删除选定",deleteClusterError:"无法删除群集。",edgeDescription:"单击某个节点并将该连接线拖动到另一个节点以连接它们。",edit:"编辑",editClusterError:"无法编辑群集。",editEdge:"编辑连接线",editEdgeDescription:"单击控制节点并将它们拖到节点上连接。",editNode:"编辑节点"},cs:{addDescription:"Kluknutím do prázdného prostoru můžete přidat nový vrchol.",addEdge:"Přidat hranu",addNode:"Přidat vrchol",back:"Zpět",close:"Zavřít",createEdgeError:"Nelze připojit hranu ke shluku.",del:"Smazat výběr",deleteClusterError:"Nelze mazat shluky.",edgeDescription:"Přetažením z jednoho vrcholu do druhého můžete spojit tyto vrcholy novou hranou.",edit:"Upravit",editClusterError:"Nelze upravovat shluky.",editEdge:"Upravit hranu",editEdgeDescription:"Přetažením kontrolního vrcholu hrany ji můžete připojit k jinému vrcholu.",editNode:"Upravit vrchol"},de:{addDescription:"Klicke auf eine freie Stelle, um einen neuen Knoten zu plazieren.",addEdge:"Kante hinzufügen",addNode:"Knoten hinzufügen",back:"Zurück",close:"Schließen",createEdgeError:"Es ist nicht möglich, Kanten mit Clustern zu verbinden.",del:"Lösche Auswahl",deleteClusterError:"Cluster können nicht gelöscht werden.",edgeDescription:"Klicke auf einen Knoten und ziehe die Kante zu einem anderen Knoten, um diese zu verbinden.",edit:"Editieren",editClusterError:"Cluster können nicht editiert werden.",editEdge:"Kante editieren",editEdgeDescription:"Klicke auf die Verbindungspunkte und ziehe diese auf einen Knoten, um sie zu verbinden.",editNode:"Knoten editieren"},en:{addDescription:"Click in an empty space to place a new node.",addEdge:"Add Edge",addNode:"Add Node",back:"Back",close:"Close",createEdgeError:"Cannot link edges to a cluster.",del:"Delete selected",deleteClusterError:"Clusters cannot be deleted.",edgeDescription:"Click on a node and drag the edge to another node to connect them.",edit:"Edit",editClusterError:"Clusters cannot be edited.",editEdge:"Edit Edge",editEdgeDescription:"Click on the control points and drag them to a node to connect to it.",editNode:"Edit Node"},es:{addDescription:"Haga clic en un lugar vacío para colocar un nuevo nodo.",addEdge:"Añadir arista",addNode:"Añadir nodo",back:"Atrás",close:"Cerrar",createEdgeError:"No se puede conectar una arista a un grupo.",del:"Eliminar selección",deleteClusterError:"No es posible eliminar grupos.",edgeDescription:"Haga clic en un nodo y arrastre la arista hacia otro nodo para conectarlos.",edit:"Editar",editClusterError:"No es posible editar grupos.",editEdge:"Editar arista",editEdgeDescription:"Haga clic en un punto de control y arrastrelo a un nodo para conectarlo.",editNode:"Editar nodo"},fr:{addDescription:"Cliquez dans un endroit vide pour placer un nœud.",addEdge:"Ajouter un lien",addNode:"Ajouter un nœud",back:"Retour",close:"Fermer",createEdgeError:"Impossible de créer un lien vers un cluster.",del:"Effacer la sélection",deleteClusterError:"Les clusters ne peuvent pas être effacés.",edgeDescription:"Cliquez sur un nœud et glissez le lien vers un autre nœud pour les connecter.",edit:"Éditer",editClusterError:"Les clusters ne peuvent pas être édités.",editEdge:"Éditer le lien",editEdgeDescription:"Cliquez sur les points de contrôle et glissez-les pour connecter un nœud.",editNode:"Éditer le nœud"},it:{addDescription:"Clicca per aggiungere un nuovo nodo",addEdge:"Aggiungi un vertice",addNode:"Aggiungi un nodo",back:"Indietro",close:"Chiudere",createEdgeError:"Non si possono collegare vertici ad un cluster",del:"Cancella la selezione",deleteClusterError:"I cluster non possono essere cancellati",edgeDescription:"Clicca su un nodo e trascinalo ad un altro nodo per connetterli.",edit:"Modifica",editClusterError:"I clusters non possono essere modificati.",editEdge:"Modifica il vertice",editEdgeDescription:"Clicca sui Punti di controllo e trascinali ad un nodo per connetterli.",editNode:"Modifica il nodo"},nl:{addDescription:"Klik op een leeg gebied om een nieuwe node te maken.",addEdge:"Link toevoegen",addNode:"Node toevoegen",back:"Terug",close:"Sluiten",createEdgeError:"Kan geen link maken naar een cluster.",del:"Selectie verwijderen",deleteClusterError:"Clusters kunnen niet worden verwijderd.",edgeDescription:"Klik op een node en sleep de link naar een andere node om ze te verbinden.",edit:"Wijzigen",editClusterError:"Clusters kunnen niet worden aangepast.",editEdge:"Link wijzigen",editEdgeDescription:"Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.",editNode:"Node wijzigen"},pt:{addDescription:"Clique em um espaço em branco para adicionar um novo nó",addEdge:"Adicionar aresta",addNode:"Adicionar nó",back:"Voltar",close:"Fechar",createEdgeError:"Não foi possível linkar arestas a um cluster.",del:"Remover selecionado",deleteClusterError:"Clusters não puderam ser removidos.",edgeDescription:"Clique em um nó e arraste a aresta até outro nó para conectá-los",edit:"Editar",editClusterError:"Clusters não puderam ser editados.",editEdge:"Editar aresta",editEdgeDescription:"Clique nos pontos de controle e os arraste para um nó para conectá-los",editNode:"Editar nó"},ru:{addDescription:"Кликните в свободное место, чтобы добавить новый узел.",addEdge:"Добавить ребро",addNode:"Добавить узел",back:"Назад",close:"Закрывать",createEdgeError:"Невозможно соединить ребра в кластер.",del:"Удалить выбранное",deleteClusterError:"Кластеры не могут быть удалены",edgeDescription:"Кликните на узел и протяните ребро к другому узлу, чтобы соединить их.",edit:"Редактировать",editClusterError:"Кластеры недоступны для редактирования.",editEdge:"Редактировать ребро",editEdgeDescription:"Кликните на контрольные точки и перетащите их в узел, чтобы подключиться к нему.",editNode:"Редактировать узел"},uk:{addDescription:"Kлікніть на вільне місце, щоб додати новий вузол.",addEdge:"Додати край",addNode:"Додати вузол",back:"Назад",close:"Закрити",createEdgeError:"Не можливо об'єднати краї в групу.",del:"Видалити обране",deleteClusterError:"Групи не можуть бути видалені.",edgeDescription:"Клікніть на вузол і перетягніть край до іншого вузла, щоб їх з'єднати.",edit:"Редагувати",editClusterError:"Групи недоступні для редагування.",editEdge:"Редагувати край",editEdgeDescription:"Клікніть на контрольні точки і перетягніть їх у вузол, щоб підключитися до нього.",editNode:"Редагувати вузол"}});var Kb=function(){function g(){cd(this,g),this.NUM_ITERATIONS=4,this.image=new Image,this.canvas=document.createElement("canvas")}return Bh(g,[{key:"init",value:function(){if(!this.initialized()){this.src=this.image.src;var g=this.image.width,t=this.image.height;this.width=g,this.height=t;var e=Math.floor(t/2),A=Math.floor(t/4),C=Math.floor(t/8),I=Math.floor(t/16),i=Math.floor(g/2),o=Math.floor(g/4),n=Math.floor(g/8),r=Math.floor(g/16);this.canvas.width=3*o,this.canvas.height=e,this.coordinates=[[0,0,i,e],[i,0,o,A],[i,A,n,C],[5*n,A,r,I]],this._fillMipMap()}}},{key:"initialized",value:function(){return void 0!==this.coordinates}},{key:"_fillMipMap",value:function(){var g=this.canvas.getContext("2d"),t=this.coordinates[0];g.drawImage(this.image,t[0],t[1],t[2],t[3]);for(var e=1;e2){t*=.5;for(var i=0;t>2&&i=this.NUM_ITERATIONS&&(i=this.NUM_ITERATIONS-1);var o=this.coordinates[i];g.drawImage(this.canvas,o[0],o[1],o[2],o[3],e,A,C,I)}else g.drawImage(this.image,e,A,C,I)}}]),g}(),Xb=function(){function g(t){cd(this,g),this.images={},this.imageBroken={},this.callback=t}return Bh(g,[{key:"_tryloadBrokenUrl",value:function(g,t,e){void 0!==g&&void 0!==e&&(void 0!==t?(e.image.onerror=function(){console.error("Could not load brokenImage:",t)},e.image.src=t):console.warn("No broken url image defined"))}},{key:"_redrawWithImage",value:function(g){this.callback&&this.callback(g)}},{key:"load",value:function(g,t){var e=this,A=this.images[g];if(A)return A;var C=new Kb;return this.images[g]=C,C.image.onload=function(){e._fixImageCoordinates(C.image),C.init(),e._redrawWithImage(C)},C.image.onerror=function(){console.error("Could not load image:",g),e._tryloadBrokenUrl(g,t,C)},C.image.src=g,C}},{key:"_fixImageCoordinates",value:function(g){0===g.width&&(document.body.appendChild(g),g.width=g.offsetWidth,g.height=g.offsetHeight,document.body.removeChild(g))}}]),g}(),Jb={},qb={get exports(){return Jb},set exports(g){Jb=g}},$b={},gw={get exports(){return $b},set exports(g){$b=g}},tw=o((function(){if("function"==typeof ArrayBuffer){var g=new ArrayBuffer(8);Object.isExtensible(g)&&Object.defineProperty(g,"a",{value:8})}})),ew=o,Aw=eg,Cw=b,Iw=tw,iw=Object.isExtensible,ow=ew((function(){iw(1)}))||Iw?function(g){return!!Aw(g)&&((!Iw||"ArrayBuffer"!=Cw(g))&&(!iw||iw(g)))}:iw,nw=!o((function(){return Object.isExtensible(Object.preventExtensions({}))})),rw=De,sw=f,aw=_e,dw=eg,hw=$g,lw=qt.f,cw=kn,uw=Tn,pw=ow,fw=nw,vw=!1,yw=Ct("meta"),mw=0,bw=function(g){lw(g,yw,{value:{objectID:"O"+mw++,weakData:{}}})},ww=gw.exports={enable:function(){ww.enable=function(){},vw=!0;var g=cw.f,t=sw([].splice),e={};e[yw]=1,g(e).length&&(cw.f=function(e){for(var A=g(e),C=0,I=A.length;CI;I++)if((o=p(g[I]))&&Nw(Sw,o))return o;return new zw(!1)}A=Rw(g,C)}for(n=d?g.next:A.next;!(r=kw(n,A)).done;){try{o=p(r.value)}catch(g){Mw(A,"throw",g)}if("object"==typeof o&&o&&Nw(Sw,o))return o}return new zw(!1)},Fw=rg,Gw=TypeError,jw=function(g,t){if(Fw(t,g))return g;throw Gw("Incorrect invocation")},Lw=De,Vw=i,Yw=$b,Ww=o,Qw=pe,Uw=Zw,_w=jw,Hw=D,Kw=eg,Xw=gi,Jw=qt.f,qw=ur.forEach,$w=R,gx=UC.set,tx=UC.getterFor,ex=function(g,t,e){var A,C=-1!==g.indexOf("Map"),I=-1!==g.indexOf("Weak"),i=C?"set":"add",o=Vw[g],n=o&&o.prototype,r={};if($w&&Hw(o)&&(I||n.forEach&&!Ww((function(){(new o).entries().next()})))){var s=(A=t((function(t,e){gx(_w(t,s),{type:g,collection:new o}),null!=e&&Uw(e,t[i],{that:t,AS_ENTRIES:C})}))).prototype,a=tx(g);qw(["add","clear","delete","forEach","get","has","set","keys","values","entries"],(function(g){var t="add"==g||"set"==g;!(g in n)||I&&"clear"==g||Qw(s,g,(function(e,A){var C=a(this).collection;if(!t&&I&&!Kw(e))return"get"==g&&void 0;var i=C[g](0===e?0:e,A);return t?this:i}))})),I||Jw(s,"size",{configurable:!0,get:function(){return a(this).collection.size}})}else A=e.getConstructor(t,g,C,i),Yw.enable();return Xw(A,g,!1,!0),r[g]=A,Lw({global:!0,forced:!0},r),I||e.setStrong(A,g,C),A},Ax=zI,Cx=function(g,t,e){for(var A in t)e&&e.unsafe&&g[A]?g[A]=t[A]:Ax(g,A,t[A],e);return g},Ix=ng,ix=Ln,ox=R,nx=ht("species"),rx=function(g){var t=Ix(g);ox&&t&&!t[nx]&&ix(t,nx,{configurable:!0,get:function(){return this}})},sx=xI,ax=Ln,dx=Cx,hx=Jt,lx=jw,cx=_,ux=Zw,px=Ri,fx=Pi,vx=rx,yx=R,mx=$b.fastKey,bx=UC.set,wx=UC.getterFor,xx={getConstructor:function(g,t,e,A){var C=g((function(g,C){lx(g,I),bx(g,{type:t,index:sx(null),first:void 0,last:void 0,size:0}),yx||(g.size=0),cx(C)||ux(C,g[A],{that:g,AS_ENTRIES:e})})),I=C.prototype,i=wx(t),o=function(g,t,e){var A,C,I=i(g),o=n(g,t);return o?o.value=e:(I.last=o={index:C=mx(t,!0),key:t,value:e,previous:A=I.last,next:void 0,removed:!1},I.first||(I.first=o),A&&(A.next=o),yx?I.size++:g.size++,"F"!==C&&(I.index[C]=o)),g},n=function(g,t){var e,A=i(g),C=mx(t);if("F"!==C)return A.index[C];for(e=A.first;e;e=e.next)if(e.key==t)return e};return dx(I,{clear:function(){for(var g=i(this),t=g.index,e=g.first;e;)e.removed=!0,e.previous&&(e.previous=e.previous.next=void 0),delete t[e.index],e=e.next;g.first=g.last=void 0,yx?g.size=0:this.size=0},delete:function(g){var t=this,e=i(t),A=n(t,g);if(A){var C=A.next,I=A.previous;delete e.index[A.index],A.removed=!0,I&&(I.next=C),C&&(C.previous=I),e.first==A&&(e.first=C),e.last==A&&(e.last=I),yx?e.size--:t.size--}return!!A},forEach:function(g){for(var t,e=i(this),A=hx(g,arguments.length>1?arguments[1]:void 0);t=t?t.next:e.first;)for(A(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(g){return!!n(this,g)}}),dx(I,e?{get:function(g){var t=n(this,g);return t&&t.value},set:function(g,t){return o(this,0===g?0:g,t)}}:{add:function(g){return o(this,g=0===g?0:g,g)}}),yx&&ax(I,"size",{configurable:!0,get:function(){return i(this).size}}),C},setStrong:function(g,t,e){var A=t+" Iterator",C=wx(t),I=wx(A);px(g,t,(function(g,t){bx(this,{type:A,target:g,state:C(g),kind:t,last:void 0})}),(function(){for(var g=I(this),t=g.kind,e=g.last;e&&e.removed;)e=e.previous;return g.target&&(g.last=e=e?e.next:g.state.first)?fx("keys"==t?e.key:"values"==t?e.value:[e.key,e.value],!1):(g.target=void 0,fx(void 0,!0))}),e?"entries":"values",!e,!0),vx(t)}};ex("Map",(function(g){return function(){return g(this,arguments.length?arguments[0]:void 0)}}),xx);var kx=Ag.Map;!function(g){g.exports=kx}(qb);var Ex=e(Jb),Ox=function(){function g(){cd(this,g),this.clear(),this._defaultIndex=0,this._groupIndex=0,this._defaultGroups=[{border:"#2B7CE9",background:"#97C2FC",highlight:{border:"#2B7CE9",background:"#D2E5FF"},hover:{border:"#2B7CE9",background:"#D2E5FF"}},{border:"#FFA500",background:"#FFFF00",highlight:{border:"#FFA500",background:"#FFFFA3"},hover:{border:"#FFA500",background:"#FFFFA3"}},{border:"#FA0A10",background:"#FB7E81",highlight:{border:"#FA0A10",background:"#FFAFB1"},hover:{border:"#FA0A10",background:"#FFAFB1"}},{border:"#41A906",background:"#7BE141",highlight:{border:"#41A906",background:"#A1EC76"},hover:{border:"#41A906",background:"#A1EC76"}},{border:"#E129F0",background:"#EB7DF4",highlight:{border:"#E129F0",background:"#F0B3F5"},hover:{border:"#E129F0",background:"#F0B3F5"}},{border:"#7C29F0",background:"#AD85E4",highlight:{border:"#7C29F0",background:"#D3BDF0"},hover:{border:"#7C29F0",background:"#D3BDF0"}},{border:"#C37F00",background:"#FFA807",highlight:{border:"#C37F00",background:"#FFCA66"},hover:{border:"#C37F00",background:"#FFCA66"}},{border:"#4220FB",background:"#6E6EFD",highlight:{border:"#4220FB",background:"#9B9BFD"},hover:{border:"#4220FB",background:"#9B9BFD"}},{border:"#FD5A77",background:"#FFC0CB",highlight:{border:"#FD5A77",background:"#FFD1D9"},hover:{border:"#FD5A77",background:"#FFD1D9"}},{border:"#4AD63A",background:"#C2FABC",highlight:{border:"#4AD63A",background:"#E6FFE3"},hover:{border:"#4AD63A",background:"#E6FFE3"}},{border:"#990000",background:"#EE0000",highlight:{border:"#BB0000",background:"#FF3333"},hover:{border:"#BB0000",background:"#FF3333"}},{border:"#FF6000",background:"#FF6000",highlight:{border:"#FF6000",background:"#FF6000"},hover:{border:"#FF6000",background:"#FF6000"}},{border:"#97C2FC",background:"#2B7CE9",highlight:{border:"#D2E5FF",background:"#2B7CE9"},hover:{border:"#D2E5FF",background:"#2B7CE9"}},{border:"#399605",background:"#255C03",highlight:{border:"#399605",background:"#255C03"},hover:{border:"#399605",background:"#255C03"}},{border:"#B70054",background:"#FF007E",highlight:{border:"#B70054",background:"#FF007E"},hover:{border:"#B70054",background:"#FF007E"}},{border:"#AD85E4",background:"#7C29F0",highlight:{border:"#D3BDF0",background:"#7C29F0"},hover:{border:"#D3BDF0",background:"#7C29F0"}},{border:"#4557FA",background:"#000EA1",highlight:{border:"#6E6EFD",background:"#000EA1"},hover:{border:"#6E6EFD",background:"#000EA1"}},{border:"#FFC0CB",background:"#FD5A77",highlight:{border:"#FFD1D9",background:"#FD5A77"},hover:{border:"#FFD1D9",background:"#FD5A77"}},{border:"#C2FABC",background:"#74D66A",highlight:{border:"#E6FFE3",background:"#74D66A"},hover:{border:"#E6FFE3",background:"#74D66A"}},{border:"#EE0000",background:"#990000",highlight:{border:"#FF3333",background:"#BB0000"},hover:{border:"#FF3333",background:"#BB0000"}}],this.options={},this.defaultOptions={useDefaultGroups:!0},yA(this.options,this.defaultOptions)}return Bh(g,[{key:"setOptions",value:function(g){var t=["useDefaultGroups"];if(void 0!==g)for(var e in g)if(Object.prototype.hasOwnProperty.call(g,e)&&-1===$p(t).call(t,e)){var A=g[e];this.add(e,A)}}},{key:"clear",value:function(){this._groups=new Ex,this._groupNames=[]}},{key:"get",value:function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],e=this._groups.get(g);if(void 0===e&&t)if(!1===this.options.useDefaultGroups&&this._groupNames.length>0){var A=this._groupIndex%this._groupNames.length;++this._groupIndex,(e={}).color=this._groups.get(this._groupNames[A]),this._groups.set(g,e)}else{var C=this._defaultIndex%this._defaultGroups.length;this._defaultIndex++,(e={}).color=this._defaultGroups[C],this._groups.set(g,e)}return e}},{key:"add",value:function(g,t){return this._groups.has(g)||this._groupNames.push(g),this._groups.set(g,t),t}}]),g}(),Tx={},Dx={get exports(){return Tx},set exports(g){Tx=g}};De({target:"Number",stat:!0},{isNaN:function(g){return g!=g}});var Nx=Ag.Number.isNaN;!function(g){g.exports=Nx}(Dx);var Rx=e(Tx),Px={},Mx={get exports(){return Px},set exports(g){Px=g}},Bx=i.isFinite,zx=Number.isFinite||function(g){return"number"==typeof g&&Bx(g)};De({target:"Number",stat:!0},{isFinite:zx});var Sx=Ag.Number.isFinite;!function(g){g.exports=Sx}(Mx);var Zx=e(Px),Fx={},Gx={get exports(){return Fx},set exports(g){Fx=g}},jx=ur.some;De({target:"Array",proto:!0,forced:!cc("some")},{some:function(g){return jx(this,g,arguments.length>1?arguments[1]:void 0)}});var Lx=FA("Array").some,Vx=rg,Yx=Lx,Wx=Array.prototype,Qx=function(g){var t=g.some;return g===Wx||Vx(Wx,g)&&t===Wx.some?Yx:t},Ux=Qx;!function(g){g.exports=Ux}(Gx);var _x=e(Fx);function Hx(g){if(void 0===g)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return g}var Kx={},Xx={get exports(){return Kx},set exports(g){Kx=g}},Jx={},qx=uf;!function(g){g.exports=qx}({get exports(){return Jx},set exports(g){Jx=g}}),function(g){g.exports=Jx}(Xx);var $x=e(Kx),gk={},tk={get exports(){return gk},set exports(g){gk=g}},ek={},Ak={get exports(){return ek},set exports(g){ek=g}};De({target:"Object",stat:!0},{setPrototypeOf:ui});var Ck=Ag.Object.setPrototypeOf;!function(g){g.exports=Ck}(Ak),function(g){g.exports=ek}(tk);var Ik=e(gk),ik={},ok={get exports(){return ik},set exports(g){ik=g}},nk={},rk=WA;!function(g){g.exports=rk}({get exports(){return nk},set exports(g){nk=g}}),function(g){g.exports=nk}(ok);var sk=e(ik);function ak(g,t){var e;return ak=Ik?sk(e=Ik).call(e):function(g,t){return g.__proto__=t,g},ak(g,t)}function dk(g,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");g.prototype=$x(t&&t.prototype,{constructor:{value:g,writable:!0,configurable:!0}}),yd(g,"prototype",{writable:!1}),t&&ak(g,t)}function hk(g,t){if(t&&("object"===kh(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return Hx(g)}var lk={},ck={get exports(){return lk},set exports(g){lk=g}},uk={},pk=Uu;!function(g){g.exports=pk}({get exports(){return uk},set exports(g){uk=g}}),function(g){g.exports=uk}(ck);var fk=e(lk);function vk(g){var t;return vk=Ik?sk(t=fk).call(t):function(g){return g.__proto__||fk(g)},vk(g)}var yk={},mk={get exports(){return yk},set exports(g){yk=g}},bk={};!function(g){var t=md,e=fh;function A(C){return g.exports=A="function"==typeof t&&"symbol"==typeof e?function(g){return typeof g}:function(g){return g&&"function"==typeof t&&g.constructor===t&&g!==t.prototype?"symbol":typeof g},g.exports.__esModule=!0,g.exports.default=g.exports,A(C)}g.exports=A,g.exports.__esModule=!0,g.exports.default=g.exports}({get exports(){return bk},set exports(g){bk=g}});var wk={},xk={get exports(){return wk},set exports(g){wk=g}},kk={},Ek=kc;!function(g){g.exports=Ek}({get exports(){return kk},set exports(g){kk=g}}),function(g){g.exports=kk}(xk);var Ok={},Tk={get exports(){return Ok},set exports(g){Ok=g}},Dk={},Nk={get exports(){return Dk},set exports(g){Dk=g}},Rk=$g,Pk=ja,Mk=N,Bk=qt,zk=eg,Sk=pe,Zk=Error,Fk=f("".replace),Gk=String(Zk("zxcasd").stack),jk=/\n\s*at [^:]*:[^\n]*/,Lk=jk.test(Gk),Vk=L,Yk=!o((function(){var g=Error("a");return!("stack"in g)||(Object.defineProperty(g,"stack",Vk(1,7)),7!==g.stack)})),Wk=pe,Qk=function(g,t){if(Lk&&"string"==typeof g&&!Zk.prepareStackTrace)for(;t--;)g=Fk(g,jk,"");return g},Uk=Yk,_k=Error.captureStackTrace,Hk=pC,Kk=De,Xk=rg,Jk=MI,qk=ui,$k=function(g,t,e){for(var A=Pk(t),C=Bk.f,I=Mk.f,i=0;i2&&AE(e,arguments[2]);var C=[];return IE(g,rE,{that:C}),tE(e,"errors",C),e};qk?qk(sE,nE):$k(sE,nE,{name:!0});var aE=sE.prototype=gE(nE.prototype,{constructor:eE(1,sE),message:eE(1,""),name:eE(1,"AggregateError")});Kk({global:!0,constructor:!0,arity:2},{AggregateError:sE});var dE,hE,lE,cE,uE="undefined"!=typeof process&&"process"==b(process),pE=co,fE=Tg,vE=TypeError,yE=function(g){if(pE(g))return g;throw vE(fE(g)+" is not a constructor")},mE=Ae,bE=yE,wE=_,xE=ht("species"),kE=function(g,t){var e,A=mE(g).constructor;return void 0===A||wE(e=mE(A)[xE])?t:bE(e)},EE=/(?:ipad|iphone|ipod).*applewebkit/i.test(sg),OE=i,TE=h,DE=Jt,NE=D,RE=$g,PE=o,ME=oI,BE=wA,zE=Ot,SE=Df,ZE=EE,FE=uE,GE=OE.setImmediate,jE=OE.clearImmediate,LE=OE.process,VE=OE.Dispatch,YE=OE.Function,WE=OE.MessageChannel,QE=OE.String,UE=0,_E={},HE="onreadystatechange";PE((function(){dE=OE.location}));var KE=function(g){if(RE(_E,g)){var t=_E[g];delete _E[g],t()}},XE=function(g){return function(){KE(g)}},JE=function(g){KE(g.data)},qE=function(g){OE.postMessage(QE(g),dE.protocol+"//"+dE.host)};GE&&jE||(GE=function(g){SE(arguments.length,1);var t=NE(g)?g:YE(g),e=BE(arguments,1);return _E[++UE]=function(){TE(t,void 0,e)},hE(UE),UE},jE=function(g){delete _E[g]},FE?hE=function(g){LE.nextTick(XE(g))}:VE&&VE.now?hE=function(g){VE.now(XE(g))}:WE&&!ZE?(cE=(lE=new WE).port2,lE.port1.onmessage=JE,hE=DE(cE.postMessage,cE)):OE.addEventListener&&NE(OE.postMessage)&&!OE.importScripts&&dE&&"file:"!==dE.protocol&&!PE(qE)?(hE=qE,OE.addEventListener("message",JE,!1)):hE=HE in zE("script")?function(g){ME.appendChild(zE("script"))[HE]=function(){ME.removeChild(this),KE(g)}}:function(g){setTimeout(XE(g),0)});var $E={set:GE,clear:jE},gO=function(){this.head=null,this.tail=null};gO.prototype={add:function(g){var t={item:g,next:null},e=this.tail;e?e.next=t:this.head=t,this.tail=t},get:function(){var g=this.head;if(g)return null===(this.head=g.next)&&(this.tail=null),g.item}};var tO,eO,AO,CO,IO,iO=gO,oO=/ipad|iphone|ipod/i.test(sg)&&"undefined"!=typeof Pebble,nO=/web0s(?!.*chrome)/i.test(sg),rO=i,sO=Jt,aO=N.f,dO=$E.set,hO=iO,lO=EE,cO=oO,uO=nO,pO=uE,fO=rO.MutationObserver||rO.WebKitMutationObserver,vO=rO.document,yO=rO.process,mO=rO.Promise,bO=aO(rO,"queueMicrotask"),wO=bO&&bO.value;if(!wO){var xO=new hO,kO=function(){var g,t;for(pO&&(g=yO.domain)&&g.exit();t=xO.get();)try{t()}catch(g){throw xO.head&&tO(),g}g&&g.enter()};lO||pO||uO||!fO||!vO?!cO&&mO&&mO.resolve?((CO=mO.resolve(void 0)).constructor=mO,IO=sO(CO.then,CO),tO=function(){IO(kO)}):pO?tO=function(){yO.nextTick(kO)}:(dO=sO(dO,rO),tO=function(){dO(kO)}):(eO=!0,AO=vO.createTextNode(""),new fO(kO).observe(AO,{characterData:!0}),tO=function(){AO.data=eO=!eO}),wO=function(g){xO.head||tO(),xO.add(g)}}var EO=wO,OO=function(g){try{return{error:!1,value:g()}}catch(g){return{error:!0,value:g}}},TO=i.Promise,DO="object"==typeof Deno&&Deno&&"object"==typeof Deno.version,NO=!DO&&!uE&&"object"==typeof window&&"object"==typeof document,RO=i,PO=TO,MO=D,BO=_t,zO=go,SO=ht,ZO=NO,FO=DO,GO=pg,jO=PO&&PO.prototype,LO=SO("species"),VO=!1,YO=MO(RO.PromiseRejectionEvent),WO=BO("Promise",(function(){var g=zO(PO),t=g!==String(PO);if(!t&&66===GO)return!0;if(!jO.catch||!jO.finally)return!0;if(!GO||GO<51||!/native code/.test(g)){var e=new PO((function(g){g(1)})),A=function(g){g((function(){}),(function(){}))};if((e.constructor={})[LO]=A,!(VO=e.then((function(){}))instanceof A))return!0}return!t&&(ZO||FO)&&!YO})),QO={CONSTRUCTOR:WO,REJECTION_EVENT:YO,SUBCLASSING:VO},UO={},_O=Pg,HO=TypeError,KO=function(g){var t,e;this.promise=new g((function(g,A){if(void 0!==t||void 0!==e)throw HO("Bad Promise constructor");t=g,e=A})),this.resolve=_O(t),this.reject=_O(e)};UO.f=function(g){return new KO(g)};var XO,JO,qO=De,$O=uE,gT=i,tT=B,eT=zI,AT=gi,CT=rx,IT=Pg,iT=D,oT=eg,nT=jw,rT=kE,sT=$E.set,aT=EO,dT=function(g,t){try{1==arguments.length?console.error(g):console.error(g,t)}catch(g){}},hT=OO,lT=iO,cT=UC,uT=TO,pT=UO,fT="Promise",vT=QO.CONSTRUCTOR,yT=QO.REJECTION_EVENT,mT=cT.getterFor(fT),bT=cT.set,wT=uT&&uT.prototype,xT=uT,kT=wT,ET=gT.TypeError,OT=gT.document,TT=gT.process,DT=pT.f,NT=DT,RT=!!(OT&&OT.createEvent&&gT.dispatchEvent),PT="unhandledrejection",MT=function(g){var t;return!(!oT(g)||!iT(t=g.then))&&t},BT=function(g,t){var e,A,C,I=t.value,i=1==t.state,o=i?g.ok:g.fail,n=g.resolve,r=g.reject,s=g.domain;try{o?(i||(2===t.rejection&>(t),t.rejection=1),!0===o?e=I:(s&&s.enter(),e=o(I),s&&(s.exit(),C=!0)),e===g.promise?r(ET("Promise-chain cycle")):(A=MT(e))?tT(A,e,n,r):n(e)):r(I)}catch(g){s&&!C&&s.exit(),r(g)}},zT=function(g,t){g.notified||(g.notified=!0,aT((function(){for(var e,A=g.reactions;e=A.get();)BT(e,g);g.notified=!1,t&&!g.rejection&&ZT(g)})))},ST=function(g,t,e){var A,C;RT?((A=OT.createEvent("Event")).promise=t,A.reason=e,A.initEvent(g,!1,!0),gT.dispatchEvent(A)):A={promise:t,reason:e},!yT&&(C=gT["on"+g])?C(A):g===PT&&dT("Unhandled promise rejection",e)},ZT=function(g){tT(sT,gT,(function(){var t,e=g.facade,A=g.value;if(FT(g)&&(t=hT((function(){$O?TT.emit("unhandledRejection",A,e):ST(PT,e,A)})),g.rejection=$O||FT(g)?2:1,t.error))throw t.value}))},FT=function(g){return 1!==g.rejection&&!g.parent},GT=function(g){tT(sT,gT,(function(){var t=g.facade;$O?TT.emit("rejectionHandled",t):ST("rejectionhandled",t,g.value)}))},jT=function(g,t,e){return function(A){g(t,A,e)}},LT=function(g,t,e){g.done||(g.done=!0,e&&(g=e),g.value=t,g.state=2,zT(g,!0))},VT=function(g,t,e){if(!g.done){g.done=!0,e&&(g=e);try{if(g.facade===t)throw ET("Promise can't be resolved itself");var A=MT(t);A?aT((function(){var e={done:!1};try{tT(A,t,jT(VT,e,g),jT(LT,e,g))}catch(t){LT(e,t,g)}})):(g.value=t,g.state=1,zT(g,!1))}catch(t){LT({done:!1},t,g)}}};vT&&(kT=(xT=function(g){nT(this,kT),IT(g),tT(XO,this);var t=mT(this);try{g(jT(VT,t),jT(LT,t))}catch(g){LT(t,g)}}).prototype,(XO=function(g){bT(this,{type:fT,done:!1,notified:!1,parent:!1,reactions:new lT,rejection:!1,state:0,value:void 0})}).prototype=eT(kT,"then",(function(g,t){var e=mT(this),A=DT(rT(this,xT));return e.parent=!0,A.ok=!iT(g)||g,A.fail=iT(t)&&t,A.domain=$O?TT.domain:void 0,0==e.state?e.reactions.add(A):aT((function(){BT(A,e)})),A.promise})),JO=function(){var g=new XO,t=mT(g);this.promise=g,this.resolve=jT(VT,t),this.reject=jT(LT,t)},pT.f=DT=function(g){return g===xT||undefined===g?new JO(g):NT(g)}),qO({global:!0,constructor:!0,wrap:!0,forced:vT},{Promise:xT}),AT(xT,fT,!1,!0),CT(fT);var YT=TO,WT=QO.CONSTRUCTOR||!Ho((function(g){YT.all(g).then(void 0,(function(){}))})),QT=B,UT=Pg,_T=UO,HT=OO,KT=Zw;De({target:"Promise",stat:!0,forced:WT},{all:function(g){var t=this,e=_T.f(t),A=e.resolve,C=e.reject,I=HT((function(){var e=UT(t.resolve),I=[],i=0,o=1;KT(g,(function(g){var n=i++,r=!1;o++,QT(e,t,g).then((function(g){r||(r=!0,I[n]=g,--o||A(I))}),C)})),--o||A(I)}));return I.error&&C(I.value),e.promise}});var XT=De,JT=QO.CONSTRUCTOR;TO&&TO.prototype,XT({target:"Promise",proto:!0,forced:JT,real:!0},{catch:function(g){return this.then(void 0,g)}});var qT=B,$T=Pg,gD=UO,tD=OO,eD=Zw;De({target:"Promise",stat:!0,forced:WT},{race:function(g){var t=this,e=gD.f(t),A=e.reject,C=tD((function(){var C=$T(t.resolve);eD(g,(function(g){qT(C,t,g).then(e.resolve,A)}))}));return C.error&&A(C.value),e.promise}});var AD=B,CD=UO;De({target:"Promise",stat:!0,forced:QO.CONSTRUCTOR},{reject:function(g){var t=CD.f(this);return AD(t.reject,void 0,g),t.promise}});var ID=Ae,iD=eg,oD=UO,nD=function(g,t){if(ID(g),iD(t)&&t.constructor===g)return t;var e=oD.f(g);return(0,e.resolve)(t),e.promise},rD=De,sD=TO,aD=QO.CONSTRUCTOR,dD=nD,hD=ng("Promise"),lD=!aD;rD({target:"Promise",stat:!0,forced:true},{resolve:function(g){return dD(lD&&this===hD?sD:this,g)}});var cD=B,uD=Pg,pD=UO,fD=OO,vD=Zw;De({target:"Promise",stat:!0,forced:WT},{allSettled:function(g){var t=this,e=pD.f(t),A=e.resolve,C=e.reject,I=fD((function(){var e=uD(t.resolve),C=[],I=0,i=1;vD(g,(function(g){var o=I++,n=!1;i++,cD(e,t,g).then((function(g){n||(n=!0,C[o]={status:"fulfilled",value:g},--i||A(C))}),(function(g){n||(n=!0,C[o]={status:"rejected",reason:g},--i||A(C))}))})),--i||A(C)}));return I.error&&C(I.value),e.promise}});var yD=B,mD=Pg,bD=ng,wD=UO,xD=OO,kD=Zw,ED="No one promise resolved";De({target:"Promise",stat:!0,forced:WT},{any:function(g){var t=this,e=bD("AggregateError"),A=wD.f(t),C=A.resolve,I=A.reject,i=xD((function(){var A=mD(t.resolve),i=[],o=0,n=1,r=!1;kD(g,(function(g){var s=o++,a=!1;n++,yD(A,t,g).then((function(g){a||r||(r=!0,C(g))}),(function(g){a||r||(a=!0,i[s]=g,--n||I(new e(i,ED)))}))})),--n||I(new e(i,ED))}));return i.error&&I(i.value),A.promise}});var OD=De,TD=TO,DD=o,ND=ng,RD=D,PD=kE,MD=nD,BD=TD&&TD.prototype;OD({target:"Promise",proto:!0,real:!0,forced:!!TD&&DD((function(){BD.finally.call({then:function(){}},(function(){}))}))},{finally:function(g){var t=PD(this,ND("Promise")),e=RD(g);return this.then(e?function(e){return MD(t,g()).then((function(){return e}))}:g,e?function(e){return MD(t,g()).then((function(){throw e}))}:g)}});var zD=Ag.Promise,SD=UO,ZD=OO;De({target:"Promise",stat:!0,forced:!0},{try:function(g){var t=SD.f(this),e=ZD(g);return(e.error?t.reject:t.resolve)(e.value),t.promise}});var FD=zD;!function(g){g.exports=FD}(Nk),function(g){g.exports=Dk}(Tk);var GD={},jD={get exports(){return GD},set exports(g){GD=g}},LD={},VD=Fc;!function(g){g.exports=VD}({get exports(){return LD},set exports(g){LD=g}}),function(g){g.exports=LD}(jD),function(g){var t=bk.default,e=ud,A=md,C=Kx,I=lk,i=wk,o=gk,n=Ok,r=GD,s=Yh;function a(){g.exports=a=function(){return d},g.exports.__esModule=!0,g.exports.default=g.exports;var d={},h=Object.prototype,l=h.hasOwnProperty,c=e||function(g,t,e){g[t]=e.value},u="function"==typeof A?A:{},p=u.iterator||"@@iterator",f=u.asyncIterator||"@@asyncIterator",v=u.toStringTag||"@@toStringTag";function y(g,t,A){return e(g,t,{value:A,enumerable:!0,configurable:!0,writable:!0}),g[t]}try{y({},"")}catch(g){y=function(g,t,e){return g[t]=e}}function m(g,t,e,A){var I=t&&t.prototype instanceof x?t:x,i=C(I.prototype),o=new S(A||[]);return c(i,"_invoke",{value:P(g,e,o)}),i}function b(g,t,e){try{return{type:"normal",arg:g.call(t,e)}}catch(g){return{type:"throw",arg:g}}}d.wrap=m;var w={};function x(){}function k(){}function E(){}var O={};y(O,p,(function(){return this}));var T=I&&I(I(Z([])));T&&T!==h&&l.call(T,p)&&(O=T);var D=E.prototype=x.prototype=C(O);function N(g){var t;i(t=["next","throw","return"]).call(t,(function(t){y(g,t,(function(g){return this._invoke(t,g)}))}))}function R(g,e){function A(C,I,i,o){var n=b(g[C],g,I);if("throw"!==n.type){var r=n.arg,s=r.value;return s&&"object"==t(s)&&l.call(s,"__await")?e.resolve(s.__await).then((function(g){A("next",g,i,o)}),(function(g){A("throw",g,i,o)})):e.resolve(s).then((function(g){r.value=g,i(r)}),(function(g){return A("throw",g,i,o)}))}o(n.arg)}var C;c(this,"_invoke",{value:function(g,t){function I(){return new e((function(e,C){A(g,t,e,C)}))}return C=C?C.then(I,I):I()}})}function P(g,t,e){var A="suspendedStart";return function(C,I){if("executing"===A)throw new Error("Generator is already running");if("completed"===A){if("throw"===C)throw I;return F()}for(e.method=C,e.arg=I;;){var i=e.delegate;if(i){var o=M(i,e);if(o){if(o===w)continue;return o}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if("suspendedStart"===A)throw A="completed",e.arg;e.dispatchException(e.arg)}else"return"===e.method&&e.abrupt("return",e.arg);A="executing";var n=b(g,t,e);if("normal"===n.type){if(A=e.done?"completed":"suspendedYield",n.arg===w)continue;return{value:n.arg,done:e.done}}"throw"===n.type&&(A="completed",e.method="throw",e.arg=n.arg)}}}function M(g,t){var e=t.method,A=g.iterator[e];if(void 0===A)return t.delegate=null,"throw"===e&&g.iterator.return&&(t.method="return",t.arg=void 0,M(g,t),"throw"===t.method)||"return"!==e&&(t.method="throw",t.arg=new TypeError("The iterator does not provide a '"+e+"' method")),w;var C=b(A,g.iterator,t.arg);if("throw"===C.type)return t.method="throw",t.arg=C.arg,t.delegate=null,w;var I=C.arg;return I?I.done?(t[g.resultName]=I.value,t.next=g.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,w):I:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,w)}function B(g){var t={tryLoc:g[0]};1 in g&&(t.catchLoc=g[1]),2 in g&&(t.finallyLoc=g[2],t.afterLoc=g[3]),this.tryEntries.push(t)}function z(g){var t=g.completion||{};t.type="normal",delete t.arg,g.completion=t}function S(g){this.tryEntries=[{tryLoc:"root"}],i(g).call(g,B,this),this.reset(!0)}function Z(g){if(g){var t=g[p];if(t)return t.call(g);if("function"==typeof g.next)return g;if(!isNaN(g.length)){var e=-1,A=function t(){for(;++e=0;--A){var C=this.tryEntries[A],I=C.completion;if("root"===C.tryLoc)return e("end");if(C.tryLoc<=this.prev){var i=l.call(C,"catchLoc"),o=l.call(C,"finallyLoc");if(i&&o){if(this.prev=0;--e){var A=this.tryEntries[e];if(A.tryLoc<=this.prev&&l.call(A,"finallyLoc")&&this.prev=0;--t){var e=this.tryEntries[t];if(e.finallyLoc===g)return this.complete(e.completion,e.afterLoc),z(e),w}},catch:function(g){for(var t=this.tryEntries.length-1;t>=0;--t){var e=this.tryEntries[t];if(e.tryLoc===g){var A=e.completion;if("throw"===A.type){var C=A.arg;z(e)}return C}}throw new Error("illegal catch attempt")},delegateYield:function(g,t,e){return this.delegate={iterator:Z(g),resultName:t,nextLoc:e},"next"===this.method&&(this.arg=void 0),w}},d}g.exports=a,g.exports.__esModule=!0,g.exports.default=g.exports}(mk);var YD=yk(),WD=YD;try{regeneratorRuntime=YD}catch(g){"object"==typeof globalThis?globalThis.regeneratorRuntime=YD:Function("r","regeneratorRuntime = r")(YD)}var QD={},UD={get exports(){return QD},set exports(g){QD=g}},_D=Pg,HD=Xg,KD=U,XD=Le,JD=TypeError,qD=function(g){return function(t,e,A,C){_D(e);var I=HD(t),i=KD(I),o=XD(I),n=g?o-1:0,r=g?-1:1;if(A<2)for(;;){if(n in i){C=i[n],n+=r;break}if(n+=r,g?n<0:o<=n)throw JD("Reduce of empty array with no initial value")}for(;g?n>=0:o>n;n+=r)n in i&&(C=e(C,i[n],n,I));return C}},$D={left:qD(!1),right:qD(!0)}.left;De({target:"Array",proto:!0,forced:!uE&&pg>79&&pg<83||!cc("reduce")},{reduce:function(g){var t=arguments.length;return $D(this,g,t,t>1?arguments[1]:void 0)}});var gN=FA("Array").reduce,tN=rg,eN=gN,AN=Array.prototype,CN=function(g){var t=g.reduce;return g===AN||tN(AN,g)&&t===AN.reduce?eN:t},IN=CN;!function(g){g.exports=IN}(UD);var iN=e(QD),oN={},nN={get exports(){return oN},set exports(g){oN=g}},rN=tr,sN=Le,aN=Ed,dN=Jt,hN=function(g,t,e,A,C,I,i,o){for(var n,r,s=C,a=0,d=!!i&&dN(i,o);a0&&rN(n)?(r=sN(n),s=hN(g,t,n,r,s,I-1)-1):(aN(s+1),g[s]=n),s++),a++;return s},lN=hN,cN=Pg,uN=Xg,pN=Le,fN=nr;De({target:"Array",proto:!0},{flatMap:function(g){var t,e=uN(this),A=pN(e);return cN(g),(t=fN(e,0)).length=lN(t,e,e,A,0,1,g,arguments.length>1?arguments[1]:void 0),t}});var vN=FA("Array").flatMap,yN=rg,mN=vN,bN=Array.prototype,wN=function(g){var t=g.flatMap;return g===bN||yN(bN,g)&&t===bN.flatMap?mN:t},xN=wN;!function(g){g.exports=xN}(nN);var kN=e(oN),EN={},ON={get exports(){return EN},set exports(g){EN=g}};ex("Set",(function(g){return function(){return g(this,arguments.length?arguments[0]:void 0)}}),xx);var TN=Ag.Set;!function(g){g.exports=TN}(ON);var DN=e(EN),NN={};!function(g){g.exports=bh}({get exports(){return NN},set exports(g){NN=g}});var RN=e(NN),PN={},MN={get exports(){return PN},set exports(g){PN=g}},BN={},zN=Po;!function(g){g.exports=zN}({get exports(){return BN},set exports(g){BN=g}}),function(g){g.exports=BN}(MN);var SN=e(PN),ZN={},FN={get exports(){return ZN},set exports(g){ZN=g}},GN=Bn,jN=Math.floor,LN=function(g,t){var e=g.length,A=jN(e/2);return e<8?VN(g,t):YN(g,LN(GN(g,0,A),t),LN(GN(g,A),t),t)},VN=function(g,t){for(var e,A,C=g.length,I=1;I0;)g[A]=g[--A];A!==I++&&(g[A]=e)}return g},YN=function(g,t,e,A){for(var C=t.length,I=e.length,i=0,o=0;i3)){if(oR)return!0;if(rR)return rR<603;var g,t,e,A,C="";for(g=65;g<76;g++){switch(t=String.fromCharCode(g),g){case 66:case 69:case 70:case 72:e=3;break;case 68:case 71:e=4;break;default:e=2}for(A=0;A<47;A++)sR.push({k:t+A,v:e})}for(sR.sort((function(g,t){return t.v-g.v})),A=0;AeR(e)?1:-1}}(g)),e=gR(C),A=0;A=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function PP(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);ethis.max&&this.flush(),null!=this._timeout&&(clearTimeout(this._timeout),this._timeout=null),this.queue.length>0&&"number"==typeof this.delay&&(this._timeout=_f((function(){g.flush()}),this.delay))}},{key:"flush",value:function(){var g,t;Ec(g=cu(t=this._queue).call(t,0)).call(g,(function(g){g.fn.apply(g.context||g.fn,g.args||[])}))}}],[{key:"extend",value:function(t,e){var A=new g(e);if(void 0!==t.flush)throw new Error("Target object already has a property flush");t.flush=function(){A.flush()};var C=[{name:"flush",original:void 0}];if(e&&e.replace)for(var I=0;IC&&(C=n,A=o)}return A}},{key:"min",value:function(g){var t=SN(this._pairs),e=t.next();if(e.done)return null;for(var A=e.value[1],C=g(e.value[1],e.value[0]);!(e=t.next()).done;){var I=bl(e.value,2),i=I[0],o=I[1],n=g(o,i);n1?e-1:0),C=1;CC?1:AC)&&(A=i,C=o)}}catch(g){I.e(g)}finally{I.f()}return A||null}},{key:"min",value:function(g){var t,e,A=null,C=null,I=RP(QR(t=this._data).call(t));try{for(I.s();!(e=I.n()).done;){var i=e.value,o=i[g];"number"==typeof o&&(null==C||ot.x&&g.topt.y}function cM(g){return"string"==typeof g&&""!==g}function uM(g,t,e,A){var C=A.x,I=A.y;if("function"==typeof A.distanceToBorder){var i=A.distanceToBorder(g,t),o=Math.sin(t)*i,n=Math.cos(t)*i;n===i?(C+=i,I=A.y):o===i?(C=A.x,I-=i):(C+=n,I-=o)}else A.shape.width>A.shape.height?(C=A.x+.5*A.shape.width,I=A.y-e):(C=A.x+e,I=A.y-.5*A.shape.height);return{x:C,y:I}}var pM=function(){function g(t){cd(this,g),this.measureText=t,this.current=0,this.width=0,this.height=0,this.lines=[]}return Bh(g,[{key:"_add",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"normal";void 0===this.lines[g]&&(this.lines[g]={width:0,height:0,blocks:[]});var A=t;void 0!==t&&""!==t||(A=" ");var C=this.measureText(A,e),I=yA({},QR(C));I.text=t,I.width=C.width,I.mod=e,void 0!==t&&""!==t||(I.width=0),this.lines[g].blocks.push(I),this.lines[g].width+=I.width}},{key:"curWidth",value:function(){var g=this.lines[this.current];return void 0===g?0:g.width}},{key:"append",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"normal";this._add(this.current,g,t)}},{key:"newLine",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"normal";this._add(this.current,g,t),this.current++}},{key:"determineLineHeights",value:function(){for(var g=0;gg&&(g=A.width),t+=A.height}this.width=g,this.height=t}},{key:"removeEmptyBlocks",value:function(){for(var g=[],t=0;t"://,""://,""://,"":/<\/b>/,"":/<\/i>/,"":/<\/code>/,"*":/\*/,_:/_/,"`":/`/,afterBold:/[^*]/,afterItal:/[^_]/,afterMono:/[^`]/},vM=function(){function g(t){cd(this,g),this.text=t,this.bold=!1,this.ital=!1,this.mono=!1,this.spacing=!1,this.position=0,this.buffer="",this.modStack=[],this.blocks=[]}return Bh(g,[{key:"mod",value:function(){return 0===this.modStack.length?"normal":this.modStack[0]}},{key:"modName",value:function(){return 0===this.modStack.length?"normal":"mono"===this.modStack[0]?"mono":this.bold&&this.ital?"boldital":this.bold?"bold":this.ital?"ital":void 0}},{key:"emitBlock",value:function(){this.spacing&&(this.add(" "),this.spacing=!1),this.buffer.length>0&&(this.blocks.push({text:this.buffer,mod:this.modName()}),this.buffer="")}},{key:"add",value:function(g){" "===g&&(this.spacing=!0),this.spacing&&(this.buffer+=" ",this.spacing=!1)," "!=g&&(this.buffer+=g)}},{key:"parseWS",value:function(g){return!!/[ \t]/.test(g)&&(this.mono?this.add(g):this.spacing=!0,!0)}},{key:"setTag",value:function(g){this.emitBlock(),this[g]=!0,this.modStack.unshift(g)}},{key:"unsetTag",value:function(g){this.emitBlock(),this[g]=!1,this.modStack.shift()}},{key:"parseStartTag",value:function(g,t){return!(this.mono||this[g]||!this.match(t))&&(this.setTag(g),!0)}},{key:"match",value:function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],e=bl(this.prepareRegExp(g),2),A=e[0],C=e[1],I=A.test(this.text.substr(this.position,C));return I&&t&&(this.position+=C-1),I}},{key:"parseEndTag",value:function(g,t,e){var A=this.mod()===g;return!(!(A="mono"===g?A&&this.mono:A&&!this.mono)||!this.match(t))&&(void 0!==e?(this.position===this.text.length-1||this.match(e,!1))&&this.unsetTag(g):this.unsetTag(g),!0)}},{key:"replace",value:function(g,t){return!!this.match(g)&&(this.add(t),this.position+=length-1,!0)}},{key:"prepareRegExp",value:function(g){var t,e;if(g instanceof RegExp)e=g,t=1;else{var A=fM[g];e=void 0!==A?A:new RegExp(g),t=g.length}return[e,t]}}]),g}(),yM=function(){function g(t,e,A,C){var I=this;cd(this,g),this.ctx=t,this.parent=e,this.selected=A,this.hover=C;this.lines=new pM((function(g,e){if(void 0===g)return 0;var i=I.parent.getFormattingValues(t,A,C,e),o=0;""!==g&&(o=I.ctx.measureText(g).width);return{width:o,values:i}}))}return Bh(g,[{key:"process",value:function(g){if(!cM(g))return this.lines.finalize();var t=this.parent.fontOptions;g=(g=g.replace(/\r\n/g,"\n")).replace(/\r/g,"\n");var e=String(g).split("\n"),A=e.length;if(t.multi)for(var C=0;C0)for(var i=0;i0)for(var d=0;d")||t.parseStartTag("ital","")||t.parseStartTag("mono","")||t.parseEndTag("bold","")||t.parseEndTag("ital","")||t.parseEndTag("mono",""))||e(A)||t.add(A),t.position++}return t.emitBlock(),t.blocks}},{key:"splitMarkdownBlocks",value:function(g){for(var t=this,e=new vM(g),A=!0,C=function(g){return!!/\\/.test(g)&&(e.positionthis.parent.fontOptions.maxWdt}},{key:"getLongestFit",value:function(g){for(var t="",e=0;e1&&void 0!==arguments[1]?arguments[1]:"normal",e=arguments.length>2&&void 0!==arguments[2]&&arguments[2];this.parent.getFormattingValues(this.ctx,this.selected,this.hover,t);for(var A=(g=(g=g.replace(/^( +)/g,"$1\r")).replace(/([^\r][^ ]*)( +)/g,"$1\r$2\r")).split("\r");A.length>0;){var C=this.getLongestFit(A);if(0===C){var I=A[0],i=this.getLongestFitWord(I);this.lines.newLine(Sl(I).call(I,0,i),t),A[0]=Sl(I).call(I,i)}else{var o=C;" "===A[C-1]?C--:" "===A[o]&&o++;var n=Sl(A).call(A,0,C).join("");C==A.length&&e?this.lines.append(n,t):this.lines.newLine(n,t),A=Sl(A).call(A,o)}}}}]),g}(),mM=["bold","ital","boldital","mono"],bM=function(){function g(t,e){var A=arguments.length>2&&void 0!==arguments[2]&&arguments[2];cd(this,g),this.body=t,this.pointToSelf=!1,this.baseSize=void 0,this.fontOptions={},this.setOptions(e),this.size={top:0,left:0,width:0,height:0,yLine:0},this.isEdgeLabel=A}return Bh(g,[{key:"setOptions",value:function(g){if(this.elementOptions=g,this.initFontOptions(g.font),cM(g.label)?this.labelDirty=!0:g.label=void 0,void 0!==g.font&&null!==g.font)if("string"==typeof g.font)this.baseSize=this.fontOptions.size;else if("object"===kh(g.font)){var t=g.font.size;void 0!==t&&(this.baseSize=t)}}},{key:"initFontOptions",value:function(t){var e=this;Lm(mM,(function(g){e.fontOptions[g]={}})),g.parseFontString(this.fontOptions,t)?this.fontOptions.vadjust=0:Lm(t,(function(g,t){null!=g&&"object"!==kh(g)&&(e.fontOptions[t]=g)}))}},{key:"constrain",value:function(g){var t={constrainWidth:!1,maxWdt:-1,minWdt:-1,constrainHeight:!1,minHgt:-1,valign:"middle"},e=gb(g,"widthConstraint");if("number"==typeof e)t.maxWdt=Number(e),t.minWdt=Number(e);else if("object"===kh(e)){var A=gb(g,["widthConstraint","maximum"]);"number"==typeof A&&(t.maxWdt=Number(A));var C=gb(g,["widthConstraint","minimum"]);"number"==typeof C&&(t.minWdt=Number(C))}var I=gb(g,"heightConstraint");if("number"==typeof I)t.minHgt=Number(I);else if("object"===kh(I)){var i=gb(g,["heightConstraint","minimum"]);"number"==typeof i&&(t.minHgt=Number(i));var o=gb(g,["heightConstraint","valign"]);"string"==typeof o&&("top"!==o&&"bottom"!==o||(t.valign=o))}return t}},{key:"update",value:function(g,t){this.setOptions(g,!0),this.propagateFonts(t),Fm(this.fontOptions,this.constrain(t)),this.fontOptions.chooser=hM("label",t)}},{key:"adjustSizes",value:function(g){var t=g?g.right+g.left:0;this.fontOptions.constrainWidth&&(this.fontOptions.maxWdt-=t,this.fontOptions.minWdt-=t);var e=g?g.top+g.bottom:0;this.fontOptions.constrainHeight&&(this.fontOptions.minHgt-=e)}},{key:"addFontOptionsToPile",value:function(g,t){for(var e=0;e5&&void 0!==arguments[5]?arguments[5]:"middle";if(void 0!==this.elementOptions.label){var i=this.fontOptions.size*this.body.view.scale;this.elementOptions.label&&i=this.elementOptions.scaling.label.maxVisible&&(i=Number(this.elementOptions.scaling.label.maxVisible)/this.body.view.scale),this.calculateLabelSize(g,A,C,t,e,I),this._drawBackground(g),this._drawText(g,t,this.size.yLine,I,i))}}},{key:"_drawBackground",value:function(g){if(void 0!==this.fontOptions.background&&"none"!==this.fontOptions.background){g.fillStyle=this.fontOptions.background;var t=this.getSize();g.fillRect(t.left,t.top,t.width,t.height)}}},{key:"_drawText",value:function(g,t,e){var A=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"middle",C=arguments.length>4?arguments[4]:void 0,I=bl(this._setAlignment(g,t,e,A),2);t=I[0],e=I[1],g.textAlign="left",t-=this.size.width/2,this.fontOptions.valign&&this.size.height>this.size.labelHeight&&("top"===this.fontOptions.valign&&(e-=(this.size.height-this.size.labelHeight)/2),"bottom"===this.fontOptions.valign&&(e+=(this.size.height-this.size.labelHeight)/2));for(var i=0;i0&&(g.lineWidth=s.strokeWidth,g.strokeStyle=h,g.lineJoin="round"),g.fillStyle=d,s.strokeWidth>0&&g.strokeText(s.text,t+n,e+s.vadjust),g.fillText(s.text,t+n,e+s.vadjust),n+=s.width}e+=o.height}}}},{key:"_setAlignment",value:function(g,t,e,A){if(this.isEdgeLabel&&"horizontal"!==this.fontOptions.align&&!1===this.pointToSelf){t=0,e=0;"top"===this.fontOptions.align?(g.textBaseline="alphabetic",e-=4):"bottom"===this.fontOptions.align?(g.textBaseline="hanging",e+=4):g.textBaseline="middle"}else g.textBaseline=A;return[t,e]}},{key:"_getColor",value:function(g,t,e){var A=g||"#000000",C=e||"#ffffff";if(t<=this.elementOptions.scaling.label.drawThreshold){var I=Math.max(0,Math.min(1,1-(this.elementOptions.scaling.label.drawThreshold-t)));A=Ym(A,I),C=Ym(C,I)}return[A,C]}},{key:"getTextSize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],e=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return this._processLabel(g,t,e),{width:this.size.width,height:this.size.height,lineCount:this.lineCount}}},{key:"getSize",value:function(){var g=this.size.left,t=this.size.top-1;if(this.isEdgeLabel){var e=.5*-this.size.width;switch(this.fontOptions.align){case"middle":g=e,t=.5*-this.size.height;break;case"top":g=e,t=-(this.size.height+2);break;case"bottom":g=e,t=2}}return{left:g,top:t,width:this.size.width,height:this.size.height}}},{key:"calculateLabelSize",value:function(g,t,e){var A=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,C=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,I=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"middle";this._processLabel(g,t,e),this.size.left=A-.5*this.size.width,this.size.top=C-.5*this.size.height,this.size.yLine=C+.5*(1-this.lineCount)*this.fontOptions.size,"hanging"===I&&(this.size.top+=.5*this.fontOptions.size,this.size.top+=4,this.size.yLine+=4)}},{key:"getFormattingValues",value:function(g,t,e,A){var C=function(g,t,e){return"normal"===t?"mod"===e?"":g[e]:void 0!==g[t][e]?g[t][e]:g[e]},I={color:C(this.fontOptions,A,"color"),size:C(this.fontOptions,A,"size"),face:C(this.fontOptions,A,"face"),mod:C(this.fontOptions,A,"mod"),vadjust:C(this.fontOptions,A,"vadjust"),strokeWidth:this.fontOptions.strokeWidth,strokeColor:this.fontOptions.strokeColor};(t||e)&&("normal"===A&&!0===this.fontOptions.chooser&&this.elementOptions.labelHighlightBold?I.mod="bold":"function"==typeof this.fontOptions.chooser&&this.fontOptions.chooser(I,this.elementOptions.id,t,e));var i="";return void 0!==I.mod&&""!==I.mod&&(i+=I.mod+" "),i+=I.size+"px "+I.face,g.font=i.replace(/"/g,""),I.font=g.font,I.height=I.size,I}},{key:"differentState",value:function(g,t){return g!==this.selectedState||t!==this.hoverState}},{key:"_processLabelText",value:function(g,t,e,A){return new yM(g,this,t,e).process(A)}},{key:"_processLabel",value:function(g,t,e){if(!1!==this.labelDirty||this.differentState(t,e)){var A=this._processLabelText(g,t,e,this.elementOptions.label);this.fontOptions.minWdt>0&&A.width0&&A.height0&&(this.enableBorderDashes(g,t),g.stroke(),this.disableBorderDashes(g,t)),g.restore()}},{key:"performFill",value:function(g,t){g.save(),g.fillStyle=t.color,this.enableShadow(g,t),ov(g).call(g),this.disableShadow(g,t),g.restore(),this.performStroke(g,t)}},{key:"_addBoundingBoxMargin",value:function(g){this.boundingBox.left-=g,this.boundingBox.top-=g,this.boundingBox.bottom+=g,this.boundingBox.right+=g}},{key:"_updateBoundingBox",value:function(g,t,e,A,C){void 0!==e&&this.resize(e,A,C),this.left=g-this.width/2,this.top=t-this.height/2,this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width}},{key:"updateBoundingBox",value:function(g,t,e,A,C){this._updateBoundingBox(g,t,e,A,C)}},{key:"getDimensionsFromLabel",value:function(g,t,e){this.textSize=this.labelModule.getTextSize(g,t,e);var A=this.textSize.width,C=this.textSize.height;return 0===A&&(A=14,C=14),{width:A,height:C}}}]),g}();function xM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var kM=function(g){dk(e,g);var t=xM(e);function e(g,A,C){var I;return cd(this,e),(I=t.call(this,g,A,C))._setMargins(C),I}return Bh(e,[{key:"resize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover;if(this.needsRefresh(t,e)){var A=this.getDimensionsFromLabel(g,t,e);this.width=A.width+this.margin.right+this.margin.left,this.height=A.height+this.margin.top+this.margin.bottom,this.radius=this.width/2}}},{key:"draw",value:function(g,t,e,A,C,I){this.resize(g,A,C),this.left=t-this.width/2,this.top=e-this.height/2,this.initContextForDraw(g,I),_A(g,this.left,this.top,this.width,this.height,I.borderRadius),this.performFill(g,I),this.updateBoundingBox(t,e,g,A,C),this.labelModule.draw(g,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,A,C)}},{key:"updateBoundingBox",value:function(g,t,e,A,C){this._updateBoundingBox(g,t,e,A,C);var I=this.options.shapeProperties.borderRadius;this._addBoundingBoxMargin(I)}},{key:"distanceToBorder",value:function(g,t){g&&this.resize(g);var e=this.options.borderWidth;return Math.min(Math.abs(this.width/2/Math.cos(t)),Math.abs(this.height/2/Math.sin(t)))+e}}]),e}(wM);function EM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var OM=function(g){dk(e,g);var t=EM(e);function e(g,A,C){var I;return cd(this,e),(I=t.call(this,g,A,C)).labelOffset=0,I.selected=!1,I}return Bh(e,[{key:"setOptions",value:function(g,t,e){this.options=g,void 0===t&&void 0===e||this.setImages(t,e)}},{key:"setImages",value:function(g,t){t&&this.selected?(this.imageObj=t,this.imageObjAlt=g):(this.imageObj=g,this.imageObjAlt=t)}},{key:"switchImages",value:function(g){var t=g&&!this.selected||!g&&this.selected;if(this.selected=g,void 0!==this.imageObjAlt&&t){var e=this.imageObj;this.imageObj=this.imageObjAlt,this.imageObjAlt=e}}},{key:"_getImagePadding",value:function(){var g={top:0,right:0,bottom:0,left:0};if(this.options.imagePadding){var t=this.options.imagePadding;"object"==kh(t)?(g.top=t.top,g.right=t.right,g.bottom=t.bottom,g.left=t.left):(g.top=t,g.right=t,g.bottom=t,g.left=t)}return g}},{key:"_resizeImage",value:function(){var g,t;if(!1===this.options.shapeProperties.useImageSize){var e=1,A=1;this.imageObj.width&&this.imageObj.height&&(this.imageObj.width>this.imageObj.height?e=this.imageObj.width/this.imageObj.height:A=this.imageObj.height/this.imageObj.width),g=2*this.options.size*e,t=2*this.options.size*A}else{var C=this._getImagePadding();g=this.imageObj.width+C.left+C.right,t=this.imageObj.height+C.top+C.bottom}this.width=g,this.height=t,this.radius=.5*this.width}},{key:"_drawRawCircle",value:function(g,t,e,A){this.initContextForDraw(g,A),UA(g,t,e,A.size),this.performFill(g,A)}},{key:"_drawImageAtPosition",value:function(g,t){if(0!=this.imageObj.width){g.globalAlpha=void 0!==t.opacity?t.opacity:1,this.enableShadow(g,t);var e=1;!0===this.options.shapeProperties.interpolation&&(e=this.imageObj.width/this.width/this.body.view.scale);var A=this._getImagePadding(),C=this.left+A.left,I=this.top+A.top,i=this.width-A.left-A.right,o=this.height-A.top-A.bottom;this.imageObj.drawImageAtPosition(g,e,C,I,i,o),this.disableShadow(g,t)}}},{key:"_drawImageLabel",value:function(g,t,e,A,C){var I=0;if(void 0!==this.height){I=.5*this.height;var i=this.labelModule.getTextSize(g,A,C);i.lineCount>=1&&(I+=i.height/2)}var o=e+I;this.options.label&&(this.labelOffset=I),this.labelModule.draw(g,t,o,A,C,"hanging")}}]),e}(wM);function TM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var DM=function(g){dk(e,g);var t=TM(e);function e(g,A,C){var I;return cd(this,e),(I=t.call(this,g,A,C))._setMargins(C),I}return Bh(e,[{key:"resize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover;if(this.needsRefresh(t,e)){var A=this.getDimensionsFromLabel(g,t,e),C=Math.max(A.width+this.margin.right+this.margin.left,A.height+this.margin.top+this.margin.bottom);this.options.size=C/2,this.width=C,this.height=C,this.radius=this.width/2}}},{key:"draw",value:function(g,t,e,A,C,I){this.resize(g,A,C),this.left=t-this.width/2,this.top=e-this.height/2,this._drawRawCircle(g,t,e,I),this.updateBoundingBox(t,e),this.labelModule.draw(g,this.left+this.textSize.width/2+this.margin.left,e,A,C)}},{key:"updateBoundingBox",value:function(g,t){this.boundingBox.top=t-this.options.size,this.boundingBox.left=g-this.options.size,this.boundingBox.right=g+this.options.size,this.boundingBox.bottom=t+this.options.size}},{key:"distanceToBorder",value:function(g){return g&&this.resize(g),.5*this.width}}]),e}(OM);function NM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var RM=function(g){dk(e,g);var t=NM(e);function e(g,A,C,I,i){var o;return cd(this,e),(o=t.call(this,g,A,C)).setImages(I,i),o}return Bh(e,[{key:"resize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover;if(void 0===this.imageObj.src||void 0===this.imageObj.width||void 0===this.imageObj.height){var A=2*this.options.size;return this.width=A,this.height=A,void(this.radius=.5*this.width)}this.needsRefresh(t,e)&&this._resizeImage()}},{key:"draw",value:function(g,t,e,A,C,I){this.switchImages(A),this.resize();var i=t,o=e;"top-left"===this.options.shapeProperties.coordinateOrigin?(this.left=t,this.top=e,i+=this.width/2,o+=this.height/2):(this.left=t-this.width/2,this.top=e-this.height/2),this._drawRawCircle(g,i,o,I),g.save(),g.clip(),this._drawImageAtPosition(g,I),g.restore(),this._drawImageLabel(g,i,o,A,C),this.updateBoundingBox(t,e)}},{key:"updateBoundingBox",value:function(g,t){"top-left"===this.options.shapeProperties.coordinateOrigin?(this.boundingBox.top=t,this.boundingBox.left=g,this.boundingBox.right=g+2*this.options.size,this.boundingBox.bottom=t+2*this.options.size):(this.boundingBox.top=t-this.options.size,this.boundingBox.left=g-this.options.size,this.boundingBox.right=g+this.options.size,this.boundingBox.bottom=t+this.options.size),this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset)}},{key:"distanceToBorder",value:function(g){return g&&this.resize(g),.5*this.width}}]),e}(OM);function PM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var MM=function(g){dk(e,g);var t=PM(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"resize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover,A=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{size:this.options.size};if(this.needsRefresh(t,e)){var C,I;this.labelModule.getTextSize(g,t,e);var i=2*A.size;this.width=null!==(C=this.customSizeWidth)&&void 0!==C?C:i,this.height=null!==(I=this.customSizeHeight)&&void 0!==I?I:i,this.radius=.5*this.width}}},{key:"_drawShape",value:function(g,t,e,A,C,I,i,o){var n,r=this;return this.resize(g,I,i,o),this.left=A-this.width/2,this.top=C-this.height/2,this.initContextForDraw(g,o),(n=t,Object.prototype.hasOwnProperty.call(JA,n)?JA[n]:function(g){for(var t=arguments.length,e=new Array(t>1?t-1:0),A=1;A0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height))}}]),e}(wM);function BM(g,t){var e=Cc(g);if(va){var A=va(g);t&&(A=Ap(A).call(A,(function(t){return Pa(g,t).enumerable}))),e.push.apply(e,A)}return e}function zM(g){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover;if(this.needsRefresh(t,e)){var A=this.getDimensionsFromLabel(g,t,e);this.height=2*A.height,this.width=A.width+A.height,this.radius=.5*this.width}}},{key:"draw",value:function(g,t,e,A,C,I){this.resize(g,A,C),this.left=t-.5*this.width,this.top=e-.5*this.height,this.initContextForDraw(g,I),HA(g,this.left,this.top,this.width,this.height),this.performFill(g,I),this.updateBoundingBox(t,e,g,A,C),this.labelModule.draw(g,t,e,A,C)}},{key:"distanceToBorder",value:function(g,t){g&&this.resize(g);var e=.5*this.width,A=.5*this.height,C=Math.sin(t)*e,I=Math.cos(t)*A;return e*A/Math.sqrt(C*C+I*I)}}]),e}(wM);function UM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var _M=function(g){dk(e,g);var t=UM(e);function e(g,A,C){var I;return cd(this,e),(I=t.call(this,g,A,C))._setMargins(C),I}return Bh(e,[{key:"resize",value:function(g,t,e){this.needsRefresh(t,e)&&(this.iconSize={width:Number(this.options.icon.size),height:Number(this.options.icon.size)},this.width=this.iconSize.width+this.margin.right+this.margin.left,this.height=this.iconSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}},{key:"draw",value:function(g,t,e,A,C,I){var i=this;return this.resize(g,A,C),this.options.icon.size=this.options.icon.size||50,this.left=t-this.width/2,this.top=e-this.height/2,this._icon(g,t,e,A,C,I),{drawExternalLabel:function(){if(void 0!==i.options.label){i.labelModule.draw(g,i.left+i.iconSize.width/2+i.margin.left,e+i.height/2+5,A)}i.updateBoundingBox(t,e)}}}},{key:"updateBoundingBox",value:function(g,t){if(this.boundingBox.top=t-.5*this.options.icon.size,this.boundingBox.left=g-.5*this.options.icon.size,this.boundingBox.right=g+.5*this.options.icon.size,this.boundingBox.bottom=t+.5*this.options.icon.size,void 0!==this.options.label&&this.labelModule.size.width>0){this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelModule.size.height+5)}}},{key:"_icon",value:function(g,t,e,A,C,I){var i=Number(this.options.icon.size);void 0!==this.options.icon.code?(g.font=[null!=this.options.icon.weight?this.options.icon.weight:A?"bold":"",(null!=this.options.icon.weight&&A?5:0)+i+"px",this.options.icon.face].join(" "),g.fillStyle=this.options.icon.color||"black",g.textAlign="center",g.textBaseline="middle",this.enableShadow(g,I),g.fillText(this.options.icon.code,t,e),this.disableShadow(g,I)):console.error("When using the icon shape, you need to define the code in the icon options object. This can be done per node or globally.")}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(wM);function HM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var KM=function(g){dk(e,g);var t=HM(e);function e(g,A,C,I,i){var o;return cd(this,e),(o=t.call(this,g,A,C)).setImages(I,i),o}return Bh(e,[{key:"resize",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selected,e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.hover;if(void 0===this.imageObj.src||void 0===this.imageObj.width||void 0===this.imageObj.height){var A=2*this.options.size;return this.width=A,void(this.height=A)}this.needsRefresh(t,e)&&this._resizeImage()}},{key:"draw",value:function(g,t,e,A,C,I){g.save(),this.switchImages(A),this.resize();var i=t,o=e;if("top-left"===this.options.shapeProperties.coordinateOrigin?(this.left=t,this.top=e,i+=this.width/2,o+=this.height/2):(this.left=t-this.width/2,this.top=e-this.height/2),!0===this.options.shapeProperties.useBorderWithImage){var n=this.options.borderWidth,r=this.options.borderWidthSelected||2*this.options.borderWidth,s=(A?r:n)/this.body.view.scale;g.lineWidth=Math.min(this.width,s),g.beginPath();var a=A?this.options.color.highlight.border:C?this.options.color.hover.border:this.options.color.border,d=A?this.options.color.highlight.background:C?this.options.color.hover.background:this.options.color.background;void 0!==I.opacity&&(a=Ym(a,I.opacity),d=Ym(d,I.opacity)),g.strokeStyle=a,g.fillStyle=d,g.rect(this.left-.5*g.lineWidth,this.top-.5*g.lineWidth,this.width+g.lineWidth,this.height+g.lineWidth),ov(g).call(g),this.performStroke(g,I),g.closePath()}this._drawImageAtPosition(g,I),this._drawImageLabel(g,i,o,A,C),this.updateBoundingBox(t,e),g.restore()}},{key:"updateBoundingBox",value:function(g,t){this.resize(),"top-left"===this.options.shapeProperties.coordinateOrigin?(this.left=g,this.top=t):(this.left=g-this.width/2,this.top=t-this.height/2),this.boundingBox.left=this.left,this.boundingBox.top=this.top,this.boundingBox.bottom=this.top+this.height,this.boundingBox.right=this.left+this.width,void 0!==this.options.label&&this.labelModule.size.width>0&&(this.boundingBox.left=Math.min(this.boundingBox.left,this.labelModule.size.left),this.boundingBox.right=Math.max(this.boundingBox.right,this.labelModule.size.left+this.labelModule.size.width),this.boundingBox.bottom=Math.max(this.boundingBox.bottom,this.boundingBox.bottom+this.labelOffset))}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(OM);function XM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var JM=function(g){dk(e,g);var t=XM(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"draw",value:function(g,t,e,A,C,I){return this._drawShape(g,"square",2,t,e,A,C,I)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(MM);function qM(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var $M=function(g){dk(e,g);var t=qM(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"draw",value:function(g,t,e,A,C,I){return this._drawShape(g,"hexagon",4,t,e,A,C,I)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(MM);function gB(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var tB=function(g){dk(e,g);var t=gB(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"draw",value:function(g,t,e,A,C,I){return this._drawShape(g,"star",4,t,e,A,C,I)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(MM);function eB(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var AB=function(g){dk(e,g);var t=eB(e);function e(g,A,C){var I;return cd(this,e),(I=t.call(this,g,A,C))._setMargins(C),I}return Bh(e,[{key:"resize",value:function(g,t,e){this.needsRefresh(t,e)&&(this.textSize=this.labelModule.getTextSize(g,t,e),this.width=this.textSize.width+this.margin.right+this.margin.left,this.height=this.textSize.height+this.margin.top+this.margin.bottom,this.radius=.5*this.width)}},{key:"draw",value:function(g,t,e,A,C,I){this.resize(g,A,C),this.left=t-this.width/2,this.top=e-this.height/2,this.enableShadow(g,I),this.labelModule.draw(g,this.left+this.textSize.width/2+this.margin.left,this.top+this.textSize.height/2+this.margin.top,A,C),this.disableShadow(g,I),this.updateBoundingBox(t,e,g,A,C)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(wM);function CB(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var IB=function(g){dk(e,g);var t=CB(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"draw",value:function(g,t,e,A,C,I){return this._drawShape(g,"triangle",3,t,e,A,C,I)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(MM);function iB(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var oB=function(g){dk(e,g);var t=iB(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"draw",value:function(g,t,e,A,C,I){return this._drawShape(g,"triangleDown",3,t,e,A,C,I)}},{key:"distanceToBorder",value:function(g,t){return this._distanceToBorder(g,t)}}]),e}(MM);function nB(g,t){var e=Cc(g);if(va){var A=va(g);t&&(A=Ap(A).call(A,(function(t){return Pa(g,t).enumerable}))),e.push.apply(e,A)}return e}function rB(g){for(var t=1;tg.left&&this.shape.topg.top}},{key:"isBoundingBoxOverlappingWith",value:function(g){return this.shape.boundingBox.leftg.left&&this.shape.boundingBox.topg.top}}],[{key:"checkOpacity",value:function(g){return 0<=g&&g<=1}},{key:"checkCoordinateOrigin",value:function(g){return void 0===g||"center"===g||"top-left"===g}},{key:"updateGroupOptions",value:function(t,e,A){var C;if(void 0!==A){var I=t.group;if(void 0!==e&&void 0!==e.group&&I!==e.group)throw new Error("updateGroupOptions: group values in options don't match.");if("number"==typeof I||"string"==typeof I&&""!=I){var i=A.get(I);void 0!==i.opacity&&void 0===e.opacity&&(g.checkOpacity(i.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+i.opacity),i.opacity=void 0));var o=Ap(C=dM(e)).call(C,(function(g){return null!=e[g]}));o.push("font"),Zm(o,t,i),t.color=Qm(t.color)}}}},{key:"parseOptions",value:function(t,e){var A=arguments.length>2&&void 0!==arguments[2]&&arguments[2],C=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},I=arguments.length>4?arguments[4]:void 0;if(Zm(["color","fixed","shadow"],t,e,A),g.checkMass(e),void 0!==t.opacity&&(g.checkOpacity(t.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+t.opacity),t.opacity=void 0)),void 0!==e.opacity&&(g.checkOpacity(e.opacity)||(console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+e.opacity),e.opacity=void 0)),e.shapeProperties&&!g.checkCoordinateOrigin(e.shapeProperties.coordinateOrigin)&&console.error("Invalid option for node coordinateOrigin, found: "+e.shapeProperties.coordinateOrigin),qm(t,e,"shadow",C),void 0!==e.color&&null!==e.color){var i=Qm(e.color);zm(t.color,i)}else!0===A&&null===e.color&&(t.color=Jm(C.color));void 0!==e.fixed&&null!==e.fixed&&("boolean"==typeof e.fixed?(t.fixed.x=e.fixed,t.fixed.y=e.fixed):(void 0!==e.fixed.x&&"boolean"==typeof e.fixed.x&&(t.fixed.x=e.fixed.x),void 0!==e.fixed.y&&"boolean"==typeof e.fixed.y&&(t.fixed.y=e.fixed.y))),!0===A&&null===e.font&&(t.font=Jm(C.font)),g.updateGroupOptions(t,e,I),void 0!==e.scaling&&qm(t.scaling,e.scaling,"label",C.scaling)}},{key:"checkMass",value:function(g,t){if(void 0!==g.mass&&g.mass<=0){var e="";void 0!==t&&(e=" in node id: "+t),console.error("%cNegative or zero mass disallowed"+e+", setting mass to 1.",lb),g.mass=1}}}]),g}();function aB(g,t){var e=void 0!==kl&&bn(g)||g["@@iterator"];if(!e){if(Vl(g)||(e=function(g,t){var e;if(!g)return;if("string"==typeof g)return dB(g,t);var A=Sl(e=Object.prototype.toString.call(g)).call(e,8,-1);"Object"===A&&g.constructor&&(A=g.constructor.name);if("Map"===A||"Set"===A)return Jo(g);if("Arguments"===A||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(A))return dB(g,t)}(g))||t&&g&&"number"==typeof g.length){e&&(g=e);var A=0,C=function(){};return{s:C,n:function(){return A>=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function dB(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e1?console.error("Invalid option for node opacity. Value must be between 0 and 1, found: "+g.opacity):this.options.opacity=g.opacity),void 0!==g.shape)for(var t in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&this.body.nodes[t].updateShape();if(void 0!==g.font||void 0!==g.widthConstraint||void 0!==g.heightConstraint)for(var e=0,A=Cc(this.body.nodes);e1&&void 0!==arguments[1]&&arguments[1],e=this.body.data.nodes;if(VP("id",g))this.body.data.nodes=g;else if(Vl(g))this.body.data.nodes=new GP,this.body.data.nodes.add(g);else{if(g)throw new TypeError("Array or DataSet expected");this.body.data.nodes=new GP}if(e&&Lm(this.nodesListeners,(function(g,t){e.off(t,g)})),this.body.nodes={},this.body.data.nodes){var A=this;Lm(this.nodesListeners,(function(g,t){A.body.data.nodes.on(t,g)}));var C=this.body.data.nodes.getIds();this.add(C,!0)}!1===t&&this.body.emitter.emit("_dataChanged")}},{key:"add",value:function(g){for(var t,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],A=[],C=0;C1&&void 0!==arguments[1]?arguments[1]:sB)(g,this.body,this.images,this.groups,this.options,this.defaultOptions)}},{key:"refresh",value:function(){var g=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];Lm(this.body.nodes,(function(e,A){var C=g.body.data.nodes.get(A);void 0!==C&&(!0===t&&e.setOptions({x:null,y:null}),e.setOptions({fixed:!1}),e.setOptions(C))}))}},{key:"getPositions",value:function(g){var t={};if(void 0!==g){if(!0===Vl(g)){for(var e=0;e0?(A=e/o)*A:e;return o===1/0?1/0:o*FB(C)}});var GB=Ag.Math.hypot;!function(g){g.exports=GB}(BB);var jB=e(MB);function LB(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var VB=function(){function g(){cd(this,g)}return Bh(g,null,[{key:"transform",value:function(g,t){Vl(g)||(g=[g]);for(var e=t.point.x,A=t.point.y,C=t.angle,I=t.length,i=0;i4&&void 0!==arguments[4]?arguments[4]:this.getViaNode();g.strokeStyle=this.getColor(g,t),g.lineWidth=t.width,!1!==t.dashes?this._drawDashedLine(g,t,C):this._drawLine(g,t,C)}},{key:"_drawLine",value:function(g,t,e,A,C){if(this.from!=this.to)this._line(g,t,e,A,C);else{var I=bl(this._getCircleData(g),3),i=I[0],o=I[1],n=I[2];this._circle(g,t,i,o,n)}}},{key:"_drawDashedLine",value:function(g,t,e,A,C){g.lineCap="round";var I=Vl(t.dashes)?t.dashes:[5,5];if(void 0!==g.setLineDash){if(g.save(),g.setLineDash(I),g.lineDashOffset=0,this.from!=this.to)this._line(g,t,e);else{var i=bl(this._getCircleData(g),3),o=i[0],n=i[1],r=i[2];this._circle(g,t,o,n,r)}g.setLineDash([0]),g.lineDashOffset=0,g.restore()}else{if(this.from!=this.to)XA(g,this.from.x,this.from.y,this.to.x,this.to.y,I);else{var s=bl(this._getCircleData(g),3),a=s[0],d=s[1],h=s[2];this._circle(g,t,a,d,h)}this.enableShadow(g,t),g.stroke(),this.disableShadow(g,t)}}},{key:"findBorderPosition",value:function(g,t,e){return this.from!=this.to?this._findBorderPosition(g,t,e):this._findBorderPositionCircle(g,t,e)}},{key:"findBorderPositions",value:function(g){if(this.from!=this.to)return{from:this._findBorderPosition(this.from,g),to:this._findBorderPosition(this.to,g)};var t,e=bl(Sl(t=this._getCircleData(g)).call(t,0,2),2),A=e[0],C=e[1];return{from:this._findBorderPositionCircle(this.from,g,{x:A,y:C,low:.25,high:.6,direction:-1}),to:this._findBorderPositionCircle(this.from,g,{x:A,y:C,low:.6,high:.8,direction:1})}}},{key:"_getCircleData",value:function(g){var t=this.options.selfReference.size;void 0!==g&&void 0===this.from.shape.width&&this.from.shape.resize(g);var e=uM(g,this.options.selfReference.angle,t,this.from);return[e.x,e.y,t]}},{key:"_pointOnCircle",value:function(g,t,e,A){var C=2*A*Math.PI;return{x:g+e*Math.cos(C),y:t-e*Math.sin(C)}}},{key:"_findBorderPositionCircle",value:function(g,t,e){var A,C=e.x,I=e.y,i=e.low,o=e.high,n=e.direction,r=this.options.selfReference.size,s=.5*(i+o),a=0;!0===this.options.arrowStrikethrough&&(-1===n?a=this.options.endPointOffset.from:1===n&&(a=this.options.endPointOffset.to));var d=0;do{s=.5*(i+o),A=this._pointOnCircle(C,I,r,s);var h=Math.atan2(g.y-A.y,g.x-A.x),l=g.distanceToBorder(t,h)+a-Math.sqrt(Math.pow(A.x-g.x,2)+Math.pow(A.y-g.y,2));if(Math.abs(l)<.05)break;l>0?n>0?i=s:o=s:n>0?o=s:i=s,++d}while(i<=o&&d<10);return Az(Az({},A),{},{t:s})}},{key:"getLineWidth",value:function(g,t){return!0===g?Math.max(this.selectionWidth,.3/this._body.view.scale):!0===t?Math.max(this.hoverWidth,.3/this._body.view.scale):Math.max(this.options.width,.3/this._body.view.scale)}},{key:"getColor",value:function(g,t){if(!1!==t.inheritsColor){if("both"===t.inheritsColor&&this.from.id!==this.to.id){var e=g.createLinearGradient(this.from.x,this.from.y,this.to.x,this.to.y),A=this.from.options.color.highlight.border,C=this.to.options.color.highlight.border;return!1===this.from.selected&&!1===this.to.selected?(A=Ym(this.from.options.color.border,t.opacity),C=Ym(this.to.options.color.border,t.opacity)):!0===this.from.selected&&!1===this.to.selected?C=this.to.options.color.border:!1===this.from.selected&&!0===this.to.selected&&(A=this.from.options.color.border),e.addColorStop(0,A),e.addColorStop(1,C),e}return"to"===t.inheritsColor?Ym(this.to.options.color.border,t.opacity):Ym(this.from.options.color.border,t.opacity)}return Ym(t.color,t.opacity)}},{key:"_circle",value:function(g,t,e,A,C){this.enableShadow(g,t);var I=0,i=2*Math.PI;if(!this.options.selfReference.renderBehindTheNode){var o=this.options.selfReference.angle,n=this.options.selfReference.angle+Math.PI,r=this._findBorderPositionCircle(this.from,g,{x:e,y:A,low:o,high:n,direction:-1}),s=this._findBorderPositionCircle(this.from,g,{x:e,y:A,low:o,high:n,direction:1});I=Math.atan2(r.y-A,r.x-e),i=Math.atan2(s.y-A,s.x-e)}g.beginPath(),g.arc(e,A,C,I,i,!1),g.stroke(),this.disableShadow(g,t)}},{key:"getDistanceToEdge",value:function(g,t,e,A,C,I){if(this.from!=this.to)return this._getDistanceToEdge(g,t,e,A,C,I);var i=bl(this._getCircleData(void 0),3),o=i[0],n=i[1],r=i[2],s=o-C,a=n-I;return Math.abs(Math.sqrt(s*s+a*a)-r)}},{key:"_getDistanceToLine",value:function(g,t,e,A,C,I){var i=e-g,o=A-t,n=((C-g)*i+(I-t)*o)/(i*i+o*o);n>1?n=1:n<0&&(n=0);var r=g+n*i-C,s=t+n*o-I;return Math.sqrt(r*r+s*s)}},{key:"getArrowData",value:function(g,t,e,A,C,I){var i,o,n,r,s,a,d,h=I.width;"from"===t?(n=this.from,r=this.to,s=I.fromArrowScale<0,a=Math.abs(I.fromArrowScale),d=I.fromArrowType):"to"===t?(n=this.to,r=this.from,s=I.toArrowScale<0,a=Math.abs(I.toArrowScale),d=I.toArrowType):(n=this.to,r=this.from,s=I.middleArrowScale<0,a=Math.abs(I.middleArrowScale),d=I.middleArrowType);var l=15*a+3*h;if(n!=r){var c=l/jB(n.x-r.x,n.y-r.y);if("middle"!==t)if(!0===this.options.smooth.enabled){var u=this._findBorderPosition(n,g,{via:e}),p=this.getPoint(u.t+c*("from"===t?1:-1),e);i=Math.atan2(u.y-p.y,u.x-p.x),o=u}else i=Math.atan2(n.y-r.y,n.x-r.x),o=this._findBorderPosition(n,g);else{var f=(s?-c:c)/2,v=this.getPoint(.5+f,e),y=this.getPoint(.5-f,e);i=Math.atan2(v.y-y.y,v.x-y.x),o=this.getPoint(.5,e)}}else{var m=bl(this._getCircleData(g),3),b=m[0],w=m[1],x=m[2];if("from"===t){var k=this.options.selfReference.angle,E=this.options.selfReference.angle+Math.PI,O=this._findBorderPositionCircle(this.from,g,{x:b,y:w,low:k,high:E,direction:-1});i=-2*O.t*Math.PI+1.5*Math.PI+.1*Math.PI,o=O}else if("to"===t){var T=this.options.selfReference.angle,D=this.options.selfReference.angle+Math.PI,N=this._findBorderPositionCircle(this.from,g,{x:b,y:w,low:T,high:D,direction:1});i=-2*N.t*Math.PI+1.5*Math.PI-1.1*Math.PI,o=N}else{var R=this.options.selfReference.angle/(2*Math.PI);o=this._pointOnCircle(b,w,x,R),i=-2*R*Math.PI+1.5*Math.PI+.1*Math.PI}}return{point:o,core:{x:o.x-.9*l*Math.cos(i),y:o.y-.9*l*Math.sin(i)},angle:i,length:l,type:d}}},{key:"drawArrowHead",value:function(g,t,e,A,C){g.strokeStyle=this.getColor(g,t),g.fillStyle=g.strokeStyle,g.lineWidth=t.width,tz.draw(g,C)&&(this.enableShadow(g,t),ov(g).call(g),this.disableShadow(g,t))}},{key:"enableShadow",value:function(g,t){!0===t.shadow&&(g.shadowColor=t.shadowColor,g.shadowBlur=t.shadowSize,g.shadowOffsetX=t.shadowX,g.shadowOffsetY=t.shadowY)}},{key:"disableShadow",value:function(g,t){!0===t.shadow&&(g.shadowColor="rgba(0,0,0,0)",g.shadowBlur=0,g.shadowOffsetX=0,g.shadowOffsetY=0)}},{key:"drawBackground",value:function(g,t){if(!1!==t.background){var e={strokeStyle:g.strokeStyle,lineWidth:g.lineWidth,dashes:g.dashes};g.strokeStyle=t.backgroundColor,g.lineWidth=t.backgroundSize,this.setStrokeDashed(g,t.backgroundDashes),g.stroke(),g.strokeStyle=e.strokeStyle,g.lineWidth=e.lineWidth,g.dashes=e.dashes,this.setStrokeDashed(g,t.dashes)}}},{key:"setStrokeDashed",value:function(g,t){if(!1!==t)if(void 0!==g.setLineDash){var e=Vl(t)?t:[5,5];g.setLineDash(e)}else console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.");else void 0!==g.setLineDash?g.setLineDash([]):console.warn("setLineDash is not supported in this browser. The dashed stroke cannot be used.")}}]),g}();function Iz(g,t){var e=Cc(g);if(va){var A=va(g);t&&(A=Ap(A).call(A,(function(t){return Pa(g,t).enumerable}))),e.push.apply(e,A)}return e}function iz(g){for(var t=1;t2&&void 0!==arguments[2]?arguments[2]:this._getViaCoordinates(),I=!1,i=1,o=0,n=this.to,r=this.options.endPointOffset?this.options.endPointOffset.to:0;g.id===this.from.id&&(n=this.from,I=!0,r=this.options.endPointOffset?this.options.endPointOffset.from:0),!1===this.options.arrowStrikethrough&&(r=0);var s=0;do{A=.5*(o+i),e=this.getPoint(A,C);var a=Math.atan2(n.y-e.y,n.x-e.x),d=n.distanceToBorder(t,a)+r-Math.sqrt(Math.pow(e.x-n.x,2)+Math.pow(e.y-n.y,2));if(Math.abs(d)<.2)break;d<0?!1===I?o=A:i=A:!1===I?i=A:o=A,++s}while(o<=i&&s<10);return iz(iz({},e),{},{t:A})}},{key:"_getDistanceToBezierEdge",value:function(g,t,e,A,C,I,i){var o,n,r,s,a,d=1e9,h=g,l=t;for(n=1;n<10;n++)r=.1*n,s=Math.pow(1-r,2)*g+2*r*(1-r)*i.x+Math.pow(r,2)*e,a=Math.pow(1-r,2)*t+2*r*(1-r)*i.y+Math.pow(r,2)*A,n>0&&(d=(o=this._getDistanceToLine(h,l,s,a,C,I))1&&void 0!==arguments[1]?arguments[1]:this.via;if(this.from===this.to){var e=bl(this._getCircleData(),3),A=e[0],C=e[1],I=e[2],i=2*Math.PI*(1-g);return{x:A+I*Math.sin(i),y:C+I-I*(1-Math.cos(i))}}return{x:Math.pow(1-g,2)*this.fromPoint.x+2*g*(1-g)*t.x+Math.pow(g,2)*this.toPoint.x,y:Math.pow(1-g,2)*this.fromPoint.y+2*g*(1-g)*t.y+Math.pow(g,2)*this.toPoint.y}}},{key:"_findBorderPosition",value:function(g,t){return this._findBorderPositionBezier(g,t,this.via)}},{key:"_getDistanceToEdge",value:function(g,t,e,A,C,I){return this._getDistanceToBezierEdge(g,t,e,A,C,I,this.via)}}]),e}(nz);function az(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var dz=function(g){dk(e,g);var t=az(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"_line",value:function(g,t,e){this._bezierCurve(g,t,e)}},{key:"getViaNode",value:function(){return this._getViaCoordinates()}},{key:"_getViaCoordinates",value:function(){var g,t,e=this.options.smooth.roundness,A=this.options.smooth.type,C=Math.abs(this.from.x-this.to.x),I=Math.abs(this.from.y-this.to.y);if("discrete"===A||"diagonalCross"===A){var i,o;i=o=C<=I?e*I:e*C,this.from.x>this.to.x&&(i=-i),this.from.y>=this.to.y&&(o=-o);var n=this.from.x+i,r=this.from.y+o;return"discrete"===A&&(C<=I?n=Cthis.to.x&&(g=-g),this.from.y>=this.to.y&&(t=-t);var y=this.from.x+g,m=this.from.y+t;return C<=I?y=this.from.x<=this.to.x?this.to.xy?this.to.x:y:m=this.from.y>=this.to.y?this.to.y>m?this.to.y:m:this.to.y2&&void 0!==arguments[2]?arguments[2]:{};return this._findBorderPositionBezier(g,t,e.via)}},{key:"_getDistanceToEdge",value:function(g,t,e,A,C,I){var i=arguments.length>6&&void 0!==arguments[6]?arguments[6]:this._getViaCoordinates();return this._getDistanceToBezierEdge(g,t,e,A,C,I,i)}},{key:"getPoint",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this._getViaCoordinates(),e=g;return{x:Math.pow(1-e,2)*this.fromPoint.x+2*e*(1-e)*t.x+Math.pow(e,2)*this.toPoint.x,y:Math.pow(1-e,2)*this.fromPoint.y+2*e*(1-e)*t.y+Math.pow(e,2)*this.toPoint.y}}}]),e}(nz);function hz(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var lz=function(g){dk(e,g);var t=hz(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"_getDistanceToBezierEdge2",value:function(g,t,e,A,C,I,i,o){for(var n=1e9,r=g,s=t,a=[0,0,0,0],d=1;d<10;d++){var h=.1*d;a[0]=Math.pow(1-h,3),a[1]=3*h*Math.pow(1-h,2),a[2]=3*Math.pow(h,2)*(1-h),a[3]=Math.pow(h,3);var l=a[0]*g+a[1]*i.x+a[2]*o.x+a[3]*e,c=a[0]*t+a[1]*i.y+a[2]*o.y+a[3]*A;if(d>0){var u=this._getDistanceToLine(r,s,l,c,C,I);n=uMath.abs(I)||!0===this.options.smooth.forceDirection||"horizontal"===this.options.smooth.forceDirection)&&"vertical"!==this.options.smooth.forceDirection?(t=this.from.y,A=this.to.y,g=this.from.x-i*C,e=this.to.x+i*C):(t=this.from.y-i*I,A=this.to.y+i*I,g=this.from.x,e=this.to.x),[{x:g,y:t},{x:e,y:A}]}},{key:"getViaNode",value:function(){return this._getViaCoordinates()}},{key:"_findBorderPosition",value:function(g,t){return this._findBorderPositionBezier(g,t)}},{key:"_getDistanceToEdge",value:function(g,t,e,A,C,I){var i=bl(arguments.length>6&&void 0!==arguments[6]?arguments[6]:this._getViaCoordinates(),2),o=i[0],n=i[1];return this._getDistanceToBezierEdge2(g,t,e,A,C,I,o,n)}},{key:"getPoint",value:function(g){var t=bl(arguments.length>1&&void 0!==arguments[1]?arguments[1]:this._getViaCoordinates(),2),e=t[0],A=t[1],C=g,I=[Math.pow(1-C,3),3*C*Math.pow(1-C,2),3*Math.pow(C,2)*(1-C),Math.pow(C,3)];return{x:I[0]*this.fromPoint.x+I[1]*e.x+I[2]*A.x+I[3]*this.toPoint.x,y:I[0]*this.fromPoint.y+I[1]*e.y+I[2]*A.y+I[3]*this.toPoint.y}}}]),e}(lz);function pz(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var fz=function(g){dk(e,g);var t=pz(e);function e(g,A,C){return cd(this,e),t.call(this,g,A,C)}return Bh(e,[{key:"_line",value:function(g,t){g.beginPath(),g.moveTo(this.fromPoint.x,this.fromPoint.y),g.lineTo(this.toPoint.x,this.toPoint.y),this.enableShadow(g,t),g.stroke(),this.disableShadow(g,t)}},{key:"getViaNode",value:function(){}},{key:"getPoint",value:function(g){return{x:(1-g)*this.fromPoint.x+g*this.toPoint.x,y:(1-g)*this.fromPoint.y+g*this.toPoint.y}}},{key:"_findBorderPosition",value:function(g,t){var e=this.to,A=this.from;g.id===this.from.id&&(e=this.from,A=this.to);var C=Math.atan2(e.y-A.y,e.x-A.x),I=e.x-A.x,i=e.y-A.y,o=Math.sqrt(I*I+i*i),n=(o-g.distanceToBorder(t,C))/o;return{x:(1-n)*A.x+n*e.x,y:(1-n)*A.y+n*e.y,t:0}}},{key:"_getDistanceToEdge",value:function(g,t,e,A,C,I){return this._getDistanceToLine(g,t,e,A,C,I)}}]),e}(Cz),vz=function(){function g(t,e,A,C,I){if(cd(this,g),void 0===e)throw new Error("No body provided");this.options=Jm(C),this.globalOptions=C,this.defaultOptions=I,this.body=e,this.imagelist=A,this.id=void 0,this.fromId=void 0,this.toId=void 0,this.selected=!1,this.hover=!1,this.labelDirty=!0,this.baseWidth=this.options.width,this.baseFontSize=this.options.font.size,this.from=void 0,this.to=void 0,this.edgeType=void 0,this.connected=!1,this.labelModule=new bM(this.body,this.options,!0),this.setOptions(t)}return Bh(g,[{key:"setOptions",value:function(t){if(t){var e=void 0!==t.physics&&this.options.physics!==t.physics||void 0!==t.hidden&&(this.options.hidden||!1)!==(t.hidden||!1)||void 0!==t.from&&this.options.from!==t.from||void 0!==t.to&&this.options.to!==t.to;g.parseOptions(this.options,t,!0,this.globalOptions),void 0!==t.id&&(this.id=t.id),void 0!==t.from&&(this.fromId=t.from),void 0!==t.to&&(this.toId=t.to),void 0!==t.title&&(this.title=t.title),void 0!==t.value&&(t.value=AM(t.value));var A=[t,this.options,this.defaultOptions];return this.chooser=hM("edge",A),this.updateLabelModule(t),e=this.updateEdgeType()||e,this._setInteractionWidths(),this.connect(),e}}},{key:"getFormattingValues",value:function(){var g=!0===this.options.arrows.to||!0===this.options.arrows.to.enabled,t=!0===this.options.arrows.from||!0===this.options.arrows.from.enabled,e=!0===this.options.arrows.middle||!0===this.options.arrows.middle.enabled,A=this.options.color.inherit,C={toArrow:g,toArrowScale:this.options.arrows.to.scaleFactor,toArrowType:this.options.arrows.to.type,toArrowSrc:this.options.arrows.to.src,toArrowImageWidth:this.options.arrows.to.imageWidth,toArrowImageHeight:this.options.arrows.to.imageHeight,middleArrow:e,middleArrowScale:this.options.arrows.middle.scaleFactor,middleArrowType:this.options.arrows.middle.type,middleArrowSrc:this.options.arrows.middle.src,middleArrowImageWidth:this.options.arrows.middle.imageWidth,middleArrowImageHeight:this.options.arrows.middle.imageHeight,fromArrow:t,fromArrowScale:this.options.arrows.from.scaleFactor,fromArrowType:this.options.arrows.from.type,fromArrowSrc:this.options.arrows.from.src,fromArrowImageWidth:this.options.arrows.from.imageWidth,fromArrowImageHeight:this.options.arrows.from.imageHeight,arrowStrikethrough:this.options.arrowStrikethrough,color:A?void 0:this.options.color.color,inheritsColor:A,opacity:this.options.color.opacity,hidden:this.options.hidden,length:this.options.length,shadow:this.options.shadow.enabled,shadowColor:this.options.shadow.color,shadowSize:this.options.shadow.size,shadowX:this.options.shadow.x,shadowY:this.options.shadow.y,dashes:this.options.dashes,width:this.options.width,background:this.options.background.enabled,backgroundColor:this.options.background.color,backgroundSize:this.options.background.size,backgroundDashes:this.options.background.dashes};if(this.selected||this.hover)if(!0===this.chooser){if(this.selected){var I=this.options.selectionWidth;"function"==typeof I?C.width=I(C.width):"number"==typeof I&&(C.width+=I),C.width=Math.max(C.width,.3/this.body.view.scale),C.color=this.options.color.highlight,C.shadow=this.options.shadow.enabled}else if(this.hover){var i=this.options.hoverWidth;"function"==typeof i?C.width=i(C.width):"number"==typeof i&&(C.width+=i),C.width=Math.max(C.width,.3/this.body.view.scale),C.color=this.options.color.hover,C.shadow=this.options.shadow.enabled}}else"function"==typeof this.chooser&&(this.chooser(C,this.options.id,this.selected,this.hover),void 0!==C.color&&(C.inheritsColor=!1),!1===C.shadow&&(C.shadowColor===this.options.shadow.color&&C.shadowSize===this.options.shadow.size&&C.shadowX===this.options.shadow.x&&C.shadowY===this.options.shadow.y||(C.shadow=!0)));else C.shadow=this.options.shadow.enabled,C.width=Math.max(C.width,.3/this.body.view.scale);return C}},{key:"updateLabelModule",value:function(g){var t=[g,this.options,this.globalOptions,this.defaultOptions];this.labelModule.update(this.options,t),void 0!==this.labelModule.baseSize&&(this.baseFontSize=this.labelModule.baseSize)}},{key:"updateEdgeType",value:function(){var g=this.options.smooth,t=!1,e=!0;return void 0!==this.edgeType&&((this.edgeType instanceof sz&&!0===g.enabled&&"dynamic"===g.type||this.edgeType instanceof uz&&!0===g.enabled&&"cubicBezier"===g.type||this.edgeType instanceof dz&&!0===g.enabled&&"dynamic"!==g.type&&"cubicBezier"!==g.type||this.edgeType instanceof fz&&!1===g.type.enabled)&&(e=!1),!0===e&&(t=this.cleanup())),!0===e?!0===g.enabled?"dynamic"===g.type?(t=!0,this.edgeType=new sz(this.options,this.body,this.labelModule)):"cubicBezier"===g.type?this.edgeType=new uz(this.options,this.body,this.labelModule):this.edgeType=new dz(this.options,this.body,this.labelModule):this.edgeType=new fz(this.options,this.body,this.labelModule):this.edgeType.setOptions(this.options),t}},{key:"connect",value:function(){this.disconnect(),this.from=this.body.nodes[this.fromId]||void 0,this.to=this.body.nodes[this.toId]||void 0,this.connected=void 0!==this.from&&void 0!==this.to,!0===this.connected?(this.from.attachEdge(this),this.to.attachEdge(this)):(this.from&&this.from.detachEdge(this),this.to&&this.to.detachEdge(this)),this.edgeType.connect()}},{key:"disconnect",value:function(){this.from&&(this.from.detachEdge(this),this.from=void 0),this.to&&(this.to.detachEdge(this),this.to=void 0),this.connected=!1}},{key:"getTitle",value:function(){return this.title}},{key:"isSelected",value:function(){return this.selected}},{key:"getValue",value:function(){return this.options.value}},{key:"setValueRange",value:function(g,t,e){if(void 0!==this.options.value){var A=this.options.scaling.customScalingFunction(g,t,e,this.options.value),C=this.options.scaling.max-this.options.scaling.min;if(!0===this.options.scaling.label.enabled){var I=this.options.scaling.label.max-this.options.scaling.label.min;this.options.font.size=this.options.scaling.label.min+A*I}this.options.width=this.options.scaling.min+A*C}else this.options.width=this.baseWidth,this.options.font.size=this.baseFontSize;this._setInteractionWidths(),this.updateLabelModule()}},{key:"_setInteractionWidths",value:function(){"function"==typeof this.options.hoverWidth?this.edgeType.hoverWidth=this.options.hoverWidth(this.options.width):this.edgeType.hoverWidth=this.options.hoverWidth+this.options.width,"function"==typeof this.options.selectionWidth?this.edgeType.selectionWidth=this.options.selectionWidth(this.options.width):this.edgeType.selectionWidth=this.options.selectionWidth+this.options.width}},{key:"draw",value:function(g){var t=this.getFormattingValues();if(!t.hidden){var e=this.edgeType.getViaNode();this.edgeType.drawLine(g,t,this.selected,this.hover,e),this.drawLabel(g,e)}}},{key:"drawArrows",value:function(g){var t=this.getFormattingValues();if(!t.hidden){var e=this.edgeType.getViaNode(),A={};this.edgeType.fromPoint=this.edgeType.from,this.edgeType.toPoint=this.edgeType.to,t.fromArrow&&(A.from=this.edgeType.getArrowData(g,"from",e,this.selected,this.hover,t),!1===t.arrowStrikethrough&&(this.edgeType.fromPoint=A.from.core),t.fromArrowSrc&&(A.from.image=this.imagelist.load(t.fromArrowSrc)),t.fromArrowImageWidth&&(A.from.imageWidth=t.fromArrowImageWidth),t.fromArrowImageHeight&&(A.from.imageHeight=t.fromArrowImageHeight)),t.toArrow&&(A.to=this.edgeType.getArrowData(g,"to",e,this.selected,this.hover,t),!1===t.arrowStrikethrough&&(this.edgeType.toPoint=A.to.core),t.toArrowSrc&&(A.to.image=this.imagelist.load(t.toArrowSrc)),t.toArrowImageWidth&&(A.to.imageWidth=t.toArrowImageWidth),t.toArrowImageHeight&&(A.to.imageHeight=t.toArrowImageHeight)),t.middleArrow&&(A.middle=this.edgeType.getArrowData(g,"middle",e,this.selected,this.hover,t),t.middleArrowSrc&&(A.middle.image=this.imagelist.load(t.middleArrowSrc)),t.middleArrowImageWidth&&(A.middle.imageWidth=t.middleArrowImageWidth),t.middleArrowImageHeight&&(A.middle.imageHeight=t.middleArrowImageHeight)),t.fromArrow&&this.edgeType.drawArrowHead(g,t,this.selected,this.hover,A.from),t.middleArrow&&this.edgeType.drawArrowHead(g,t,this.selected,this.hover,A.middle),t.toArrow&&this.edgeType.drawArrowHead(g,t,this.selected,this.hover,A.to)}}},{key:"drawLabel",value:function(g,t){if(void 0!==this.options.label){var e,A=this.from,C=this.to;if(this.labelModule.differentState(this.selected,this.hover)&&this.labelModule.getTextSize(g,this.selected,this.hover),A.id!=C.id){this.labelModule.pointToSelf=!1,e=this.edgeType.getPoint(.5,t),g.save();var I=this._getRotation(g);0!=I.angle&&(g.translate(I.x,I.y),g.rotate(I.angle)),this.labelModule.draw(g,e.x,e.y,this.selected,this.hover),g.restore()}else{this.labelModule.pointToSelf=!0;var i=uM(g,this.options.selfReference.angle,this.options.selfReference.size,A);e=this._pointOnCircle(i.x,i.y,this.options.selfReference.size,this.options.selfReference.angle),this.labelModule.draw(g,e.x,e.y,this.selected,this.hover)}}}},{key:"getItemsOnPoint",value:function(g){var t=[];if(this.labelModule.visible()){var e=this._getRotation();lM(this.labelModule.getSize(),g,e)&&t.push({edgeId:this.id,labelId:0})}var A={left:g.x,top:g.y};return this.isOverlappingWith(A)&&t.push({edgeId:this.id}),t}},{key:"isOverlappingWith",value:function(g){if(this.connected){var t=this.from.x,e=this.from.y,A=this.to.x,C=this.to.y,I=g.left,i=g.top;return this.edgeType.getDistanceToEdge(t,e,A,C,I,i)<10}return!1}},{key:"_getRotation",value:function(g){var t=this.edgeType.getViaNode(),e=this.edgeType.getPoint(.5,t);void 0!==g&&this.labelModule.calculateLabelSize(g,this.selected,this.hover,e.x,e.y);var A={x:e.x,y:this.labelModule.size.yLine,angle:0};if(!this.labelModule.visible())return A;if("horizontal"===this.options.font.align)return A;var C=this.from.y-this.to.y,I=this.from.x-this.to.x,i=Math.atan2(C,I);return(i<-1&&I<0||i>0&&I<0)&&(i+=Math.PI),A.angle=i,A}},{key:"_pointOnCircle",value:function(g,t,e,A){return{x:g+e*Math.cos(A),y:t-e*Math.sin(A)}}},{key:"select",value:function(){this.selected=!0}},{key:"unselect",value:function(){this.selected=!1}},{key:"cleanup",value:function(){return this.edgeType.cleanup()}},{key:"remove",value:function(){this.cleanup(),this.disconnect(),delete this.body.edges[this.id]}},{key:"endPointsValid",value:function(){return void 0!==this.body.nodes[this.fromId]&&void 0!==this.body.nodes[this.toId]}}],[{key:"parseOptions",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]&&arguments[2],A=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},C=arguments.length>4&&void 0!==arguments[4]&&arguments[4];if(Sm(["endPointOffset","arrowStrikethrough","id","from","hidden","hoverWidth","labelHighlightBold","length","line","opacity","physics","scaling","selectionWidth","selfReferenceSize","selfReference","to","title","value","width","font","chosen","widthConstraint"],g,t,e),void 0!==t.endPointOffset&&void 0!==t.endPointOffset.from&&(Zx(t.endPointOffset.from)?g.endPointOffset.from=t.endPointOffset.from:(g.endPointOffset.from=void 0!==A.endPointOffset.from?A.endPointOffset.from:0,console.error("endPointOffset.from is not a valid number"))),void 0!==t.endPointOffset&&void 0!==t.endPointOffset.to&&(Zx(t.endPointOffset.to)?g.endPointOffset.to=t.endPointOffset.to:(g.endPointOffset.to=void 0!==A.endPointOffset.to?A.endPointOffset.to:0,console.error("endPointOffset.to is not a valid number"))),cM(t.label)?g.label=t.label:cM(g.label)||(g.label=void 0),qm(g,t,"smooth",A),qm(g,t,"shadow",A),qm(g,t,"background",A),void 0!==t.dashes&&null!==t.dashes?g.dashes=t.dashes:!0===e&&null===t.dashes&&(g.dashes=pf(A.dashes)),void 0!==t.scaling&&null!==t.scaling?(void 0!==t.scaling.min&&(g.scaling.min=t.scaling.min),void 0!==t.scaling.max&&(g.scaling.max=t.scaling.max),qm(g.scaling,t.scaling,"label",A.scaling)):!0===e&&null===t.scaling&&(g.scaling=pf(A.scaling)),void 0!==t.arrows&&null!==t.arrows)if("string"==typeof t.arrows){var I=t.arrows.toLowerCase();g.arrows.to.enabled=-1!=$p(I).call(I,"to"),g.arrows.middle.enabled=-1!=$p(I).call(I,"middle"),g.arrows.from.enabled=-1!=$p(I).call(I,"from")}else{if("object"!==kh(t.arrows))throw new Error("The arrow newOptions can only be an object or a string. Refer to the documentation. You used:"+xf(t.arrows));qm(g.arrows,t.arrows,"to",A.arrows),qm(g.arrows,t.arrows,"middle",A.arrows),qm(g.arrows,t.arrows,"from",A.arrows)}else!0===e&&null===t.arrows&&(g.arrows=pf(A.arrows));if(void 0!==t.color&&null!==t.color){var i=Pm(t.color)?{color:t.color,highlight:t.color,hover:t.color,inherit:!1,opacity:1}:t.color,o=g.color;if(C)Fm(o,A.color,!1,e);else for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&delete o[n];if(Pm(o))o.color=o,o.highlight=o,o.hover=o,o.inherit=!1,void 0===i.opacity&&(o.opacity=1);else{var r=!1;void 0!==i.color&&(o.color=i.color,r=!0),void 0!==i.highlight&&(o.highlight=i.highlight,r=!0),void 0!==i.hover&&(o.hover=i.hover,r=!0),void 0!==i.inherit&&(o.inherit=i.inherit),void 0!==i.opacity&&(o.opacity=Math.min(1,Math.max(0,i.opacity))),!0===r?o.inherit=!1:void 0===o.inherit&&(o.inherit="from")}}else!0===e&&null===t.color&&(g.color=Jm(A.color));!0===e&&null===t.font&&(g.font=Jm(A.font)),Object.prototype.hasOwnProperty.call(t,"selfReferenceSize")&&(console.warn("The selfReferenceSize property has been deprecated. Please use selfReference property instead. The selfReference can be set like thise selfReference:{size:30, angle:Math.PI / 4}"),g.selfReference.size=t.selfReferenceSize)}}]),g}(),yz=function(){function g(t,e,A){var C,I=this;cd(this,g),this.body=t,this.images=e,this.groups=A,this.body.functions.createEdge=QA(C=this.create).call(C,this),this.edgesListeners={add:function(g,t){I.add(t.items)},update:function(g,t){I.update(t.items)},remove:function(g,t){I.remove(t.items)}},this.options={},this.defaultOptions={arrows:{to:{enabled:!1,scaleFactor:1,type:"arrow"},middle:{enabled:!1,scaleFactor:1,type:"arrow"},from:{enabled:!1,scaleFactor:1,type:"arrow"}},endPointOffset:{from:0,to:0},arrowStrikethrough:!0,color:{color:"#848484",highlight:"#848484",hover:"#848484",inherit:"from",opacity:1},dashes:!1,font:{color:"#343434",size:14,face:"arial",background:"none",strokeWidth:2,strokeColor:"#ffffff",align:"horizontal",multi:!1,vadjust:0,bold:{mod:"bold"},boldital:{mod:"bold italic"},ital:{mod:"italic"},mono:{mod:"",size:15,face:"courier new",vadjust:2}},hidden:!1,hoverWidth:1.5,label:void 0,labelHighlightBold:!0,length:void 0,physics:!0,scaling:{min:1,max:15,label:{enabled:!0,min:14,max:30,maxVisible:30,drawThreshold:5},customScalingFunction:function(g,t,e,A){if(t===g)return.5;var C=1/(t-g);return Math.max(0,(A-g)*C)}},selectionWidth:1.5,selfReference:{size:20,angle:Math.PI/4,renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:10,x:5,y:5},background:{enabled:!1,color:"rgba(111,111,111,1)",size:10,dashes:!1},smooth:{enabled:!0,type:"dynamic",forceDirection:"none",roundness:.5},title:void 0,width:1,value:void 0},Fm(this.options,this.defaultOptions),this.bindEventListeners()}return Bh(g,[{key:"bindEventListeners",value:function(){var g,t,e=this;this.body.emitter.on("_forceDisableDynamicCurves",(function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];"dynamic"===g&&(g="continuous");var A=!1;for(var C in e.body.edges)if(Object.prototype.hasOwnProperty.call(e.body.edges,C)){var I=e.body.edges[C],i=e.body.data.edges.get(C);if(null!=i){var o=i.smooth;void 0!==o&&!0===o.enabled&&"dynamic"===o.type&&(void 0===g?I.setOptions({smooth:!1}):I.setOptions({smooth:{type:g}}),A=!0)}}!0===t&&!0===A&&e.body.emitter.emit("_dataChanged")})),this.body.emitter.on("_dataUpdated",(function(){e.reconnectEdges()})),this.body.emitter.on("refreshEdges",QA(g=this.refresh).call(g,this)),this.body.emitter.on("refresh",QA(t=this.refresh).call(t,this)),this.body.emitter.on("destroy",(function(){Lm(e.edgesListeners,(function(g,t){e.body.data.edges&&e.body.data.edges.off(t,g)})),delete e.body.functions.createEdge,delete e.edgesListeners.add,delete e.edgesListeners.update,delete e.edgesListeners.remove,delete e.edgesListeners}))}},{key:"setOptions",value:function(g){if(void 0!==g){vz.parseOptions(this.options,g,!0,this.defaultOptions,!0);var t=!1;if(void 0!==g.smooth)for(var e in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,e)&&(t=this.body.edges[e].updateEdgeType()||t);if(void 0!==g.font)for(var A in this.body.edges)Object.prototype.hasOwnProperty.call(this.body.edges,A)&&this.body.edges[A].updateLabelModule();void 0===g.hidden&&void 0===g.physics&&!0!==t||this.body.emitter.emit("_dataChanged")}}},{key:"setData",value:function(g){var t=this,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],A=this.body.data.edges;if(VP("id",g))this.body.data.edges=g;else if(Vl(g))this.body.data.edges=new GP,this.body.data.edges.add(g);else{if(g)throw new TypeError("Array or DataSet expected");this.body.data.edges=new GP}if(A&&Lm(this.edgesListeners,(function(g,t){A.off(t,g)})),this.body.edges={},this.body.data.edges){Lm(this.edgesListeners,(function(g,e){t.body.data.edges.on(e,g)}));var C=this.body.data.edges.getIds();this.add(C,!0)}this.body.emitter.emit("_adjustEdgesForHierarchicalLayout"),!1===e&&this.body.emitter.emit("_dataChanged")}},{key:"add",value:function(g){for(var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],e=this.body.edges,A=this.body.data.edges,C=0;C1&&void 0!==arguments[1])||arguments[1];if(0!==g.length){var e=this.body.edges;Lm(g,(function(g){var t=e[g];void 0!==t&&t.remove()})),t&&this.body.emitter.emit("_dataChanged")}}},{key:"refresh",value:function(){var g=this;Lm(this.body.edges,(function(t,e){var A=g.body.data.edges.get(e);void 0!==A&&t.setOptions(A)}))}},{key:"create",value:function(g){return new vz(g,this.body,this.images,this.options,this.defaultOptions)}},{key:"reconnectEdges",value:function(){var g,t=this.body.nodes,e=this.body.edges;for(g in t)Object.prototype.hasOwnProperty.call(t,g)&&(t[g].edges=[]);for(g in e)if(Object.prototype.hasOwnProperty.call(e,g)){var A=e[g];A.from=null,A.to=null,A.connect()}}},{key:"getConnectedNodes",value:function(g){var t=[];if(void 0!==this.body.edges[g]){var e=this.body.edges[g];void 0!==e.fromId&&t.push(e.fromId),void 0!==e.toId&&t.push(e.toId)}return t}},{key:"_updateState",value:function(){this._addMissingEdges(),this._removeInvalidEdges()}},{key:"_removeInvalidEdges",value:function(){var g=this,t=[];Lm(this.body.edges,(function(e,A){var C=g.body.nodes[e.toId],I=g.body.nodes[e.fromId];void 0!==C&&!0===C.isCluster||void 0!==I&&!0===I.isCluster||void 0!==C&&void 0!==I||t.push(A)})),this.remove(t,!1)}},{key:"_addMissingEdges",value:function(){var g=this.body.data.edges;if(null!=g){var t=this.body.edges,e=[];Ec(g).call(g,(function(g,A){void 0===t[A]&&e.push(A)})),this.add(e,!0)}}}]),g}(),mz=function(){function g(t,e,A){cd(this,g),this.body=t,this.physicsBody=e,this.barnesHutTree,this.setOptions(A),this._rng=xm("BARNES HUT SOLVER")}return Bh(g,[{key:"setOptions",value:function(g){this.options=g,this.thetaInversed=1/this.options.theta,this.overlapAvoidanceFactor=1-Math.max(0,Math.min(1,this.options.avoidOverlap))}},{key:"solve",value:function(){if(0!==this.options.gravitationalConstant&&this.physicsBody.physicsNodeIndices.length>0){var g,t=this.body.nodes,e=this.physicsBody.physicsNodeIndices,A=e.length,C=this._formBarnesHutTree(t,e);this.barnesHutTree=C;for(var I=0;I0&&this._getForceContributions(C.root,g)}}},{key:"_getForceContributions",value:function(g,t){this._getForceContribution(g.children.NW,t),this._getForceContribution(g.children.NE,t),this._getForceContribution(g.children.SW,t),this._getForceContribution(g.children.SE,t)}},{key:"_getForceContribution",value:function(g,t){if(g.childrenCount>0){var e=g.centerOfMass.x-t.x,A=g.centerOfMass.y-t.y,C=Math.sqrt(e*e+A*A);C*g.calcSize>this.thetaInversed?this._calculateForces(C,e,A,t,g):4===g.childrenCount?this._getForceContributions(g,t):g.children.data.id!=t.id&&this._calculateForces(C,e,A,t,g)}}},{key:"_calculateForces",value:function(g,t,e,A,C){0===g&&(t=g=.1),this.overlapAvoidanceFactor<1&&A.shape.radius&&(g=Math.max(.1+this.overlapAvoidanceFactor*A.shape.radius,g-A.shape.radius));var I=this.options.gravitationalConstant*C.mass*A.options.mass/Math.pow(g,3),i=t*I,o=e*I;this.physicsBody.forces[A.id].x+=i,this.physicsBody.forces[A.id].y+=o}},{key:"_formBarnesHutTree",value:function(g,t){for(var e,A=t.length,C=g[t[0]].x,I=g[t[0]].y,i=g[t[0]].x,o=g[t[0]].y,n=1;n0&&(si&&(i=s),ao&&(o=a))}var d=Math.abs(i-C)-Math.abs(o-I);d>0?(I-=.5*d,o+=.5*d):(C+=.5*d,i-=.5*d);var h=Math.max(1e-5,Math.abs(i-C)),l=.5*h,c=.5*(C+i),u=.5*(I+o),p={root:{centerOfMass:{x:0,y:0},mass:0,range:{minX:c-l,maxX:c+l,minY:u-l,maxY:u+l},size:h,calcSize:1/h,children:{data:null},maxWidth:0,level:0,childrenCount:4}};this._splitBranch(p.root);for(var f=0;f0&&this._placeInTree(p.root,e);return p}},{key:"_updateBranchMass",value:function(g,t){var e=g.centerOfMass,A=g.mass+t.options.mass,C=1/A;e.x=e.x*g.mass+t.x*t.options.mass,e.x*=C,e.y=e.y*g.mass+t.y*t.options.mass,e.y*=C,g.mass=A;var I=Math.max(Math.max(t.height,t.radius),t.width);g.maxWidth=g.maxWidtht.x?C.maxY>t.y?"NW":"SW":C.maxY>t.y?"NE":"SE",this._placeInRegion(g,t,A)}},{key:"_placeInRegion",value:function(g,t,e){var A=g.children[e];switch(A.childrenCount){case 0:A.children.data=t,A.childrenCount=1,this._updateBranchMass(A,t);break;case 1:A.children.data.x===t.x&&A.children.data.y===t.y?(t.x+=this._rng(),t.y+=this._rng()):(this._splitBranch(A),this._placeInTree(A,t));break;case 4:this._placeInTree(A,t)}}},{key:"_splitBranch",value:function(g){var t=null;1===g.childrenCount&&(t=g.children.data,g.mass=0,g.centerOfMass.x=0,g.centerOfMass.y=0),g.childrenCount=4,g.children.data=null,this._insertRegion(g,"NW"),this._insertRegion(g,"NE"),this._insertRegion(g,"SW"),this._insertRegion(g,"SE"),null!=t&&this._placeInTree(g,t)}},{key:"_insertRegion",value:function(g,t){var e,A,C,I,i=.5*g.size;switch(t){case"NW":e=g.range.minX,A=g.range.minX+i,C=g.range.minY,I=g.range.minY+i;break;case"NE":e=g.range.minX+i,A=g.range.maxX,C=g.range.minY,I=g.range.minY+i;break;case"SW":e=g.range.minX,A=g.range.minX+i,C=g.range.minY+i,I=g.range.maxY;break;case"SE":e=g.range.minX+i,A=g.range.maxX,C=g.range.minY+i,I=g.range.maxY}g.children[t]={centerOfMass:{x:0,y:0},mass:0,range:{minX:e,maxX:A,minY:C,maxY:I},size:.5*g.size,calcSize:2*g.calcSize,children:{data:null},maxWidth:0,level:g.level+1,childrenCount:0}}},{key:"_debug",value:function(g,t){void 0!==this.barnesHutTree&&(g.lineWidth=1,this._drawBranch(this.barnesHutTree.root,g,t))}},{key:"_drawBranch",value:function(g,t,e){void 0===e&&(e="#FF0000"),4===g.childrenCount&&(this._drawBranch(g.children.NW,t),this._drawBranch(g.children.NE,t),this._drawBranch(g.children.SE,t),this._drawBranch(g.children.SW,t)),t.strokeStyle=e,t.beginPath(),t.moveTo(g.range.minX,g.range.minY),t.lineTo(g.range.maxX,g.range.minY),t.stroke(),t.beginPath(),t.moveTo(g.range.maxX,g.range.minY),t.lineTo(g.range.maxX,g.range.maxY),t.stroke(),t.beginPath(),t.moveTo(g.range.maxX,g.range.maxY),t.lineTo(g.range.minX,g.range.maxY),t.stroke(),t.beginPath(),t.moveTo(g.range.minX,g.range.maxY),t.lineTo(g.range.minX,g.range.minY),t.stroke()}}]),g}(),bz=function(){function g(t,e,A){cd(this,g),this._rng=xm("REPULSION SOLVER"),this.body=t,this.physicsBody=e,this.setOptions(A)}return Bh(g,[{key:"setOptions",value:function(g){this.options=g}},{key:"solve",value:function(){for(var g,t,e,A,C,I,i,o,n=this.body.nodes,r=this.physicsBody.physicsNodeIndices,s=this.physicsBody.forces,a=this.options.nodeDistance,d=-2/3/a,h=0;h0){var I=C.edges.length+1,i=this.options.centralGravity*I*C.options.mass;A[C.id].x=t*i,A[C.id].y=e*i}}}]),e}(Ez),Rz=function(){function g(t){cd(this,g),this.body=t,this.physicsBody={physicsNodeIndices:[],physicsEdgeIndices:[],forces:{},velocities:{}},this.physicsEnabled=!0,this.simulationInterval=1e3/60,this.requiresTimeout=!0,this.previousStates={},this.referenceState={},this.freezeCache={},this.renderTimer=void 0,this.adaptiveTimestep=!1,this.adaptiveTimestepEnabled=!1,this.adaptiveCounter=0,this.adaptiveInterval=3,this.stabilized=!1,this.startedStabilization=!1,this.stabilizationIterations=0,this.ready=!1,this.options={},this.defaultOptions={enabled:!0,barnesHut:{theta:.5,gravitationalConstant:-2e3,centralGravity:.3,springLength:95,springConstant:.04,damping:.09,avoidOverlap:0},forceAtlas2Based:{theta:.5,gravitationalConstant:-50,centralGravity:.01,springConstant:.08,springLength:100,damping:.4,avoidOverlap:0},repulsion:{centralGravity:.2,springLength:200,springConstant:.05,nodeDistance:100,damping:.09,avoidOverlap:0},hierarchicalRepulsion:{centralGravity:0,springLength:100,springConstant:.01,nodeDistance:120,damping:.09},maxVelocity:50,minVelocity:.75,solver:"barnesHut",stabilization:{enabled:!0,iterations:1e3,updateInterval:50,onlyDynamicEdges:!1,fit:!0},timestep:.5,adaptiveTimestep:!0,wind:{x:0,y:0}},yA(this.options,this.defaultOptions),this.timestep=.5,this.layoutFailed=!1,this.bindEventListeners()}return Bh(g,[{key:"bindEventListeners",value:function(){var g=this;this.body.emitter.on("initPhysics",(function(){g.initPhysics()})),this.body.emitter.on("_layoutFailed",(function(){g.layoutFailed=!0})),this.body.emitter.on("resetPhysics",(function(){g.stopSimulation(),g.ready=!1})),this.body.emitter.on("disablePhysics",(function(){g.physicsEnabled=!1,g.stopSimulation()})),this.body.emitter.on("restorePhysics",(function(){g.setOptions(g.options),!0===g.ready&&g.startSimulation()})),this.body.emitter.on("startSimulation",(function(){!0===g.ready&&g.startSimulation()})),this.body.emitter.on("stopSimulation",(function(){g.stopSimulation()})),this.body.emitter.on("destroy",(function(){g.stopSimulation(!1),g.body.emitter.off()})),this.body.emitter.on("_dataChanged",(function(){g.updatePhysicsData()}))}},{key:"setOptions",value:function(g){if(void 0!==g)if(!1===g)this.options.enabled=!1,this.physicsEnabled=!1,this.stopSimulation();else if(!0===g)this.options.enabled=!0,this.physicsEnabled=!0,this.startSimulation();else{this.physicsEnabled=!0,Zm(["stabilization"],this.options,g),qm(this.options,g,"stabilization"),void 0===g.enabled&&(this.options.enabled=!0),!1===this.options.enabled&&(this.physicsEnabled=!1,this.stopSimulation());var t=this.options.wind;t&&(("number"!=typeof t.x||Rx(t.x))&&(t.x=0),("number"!=typeof t.y||Rx(t.y))&&(t.y=0)),this.timestep=this.options.timestep}this.init()}},{key:"init",value:function(){var g;"forceAtlas2Based"===this.options.solver?(g=this.options.forceAtlas2Based,this.nodesSolver=new Tz(this.body,this.physicsBody,g),this.edgesSolver=new xz(this.body,this.physicsBody,g),this.gravitySolver=new Nz(this.body,this.physicsBody,g)):"repulsion"===this.options.solver?(g=this.options.repulsion,this.nodesSolver=new bz(this.body,this.physicsBody,g),this.edgesSolver=new xz(this.body,this.physicsBody,g),this.gravitySolver=new Ez(this.body,this.physicsBody,g)):"hierarchicalRepulsion"===this.options.solver?(g=this.options.hierarchicalRepulsion,this.nodesSolver=new wz(this.body,this.physicsBody,g),this.edgesSolver=new kz(this.body,this.physicsBody,g),this.gravitySolver=new Ez(this.body,this.physicsBody,g)):(g=this.options.barnesHut,this.nodesSolver=new mz(this.body,this.physicsBody,g),this.edgesSolver=new xz(this.body,this.physicsBody,g),this.gravitySolver=new Ez(this.body,this.physicsBody,g)),this.modelOptions=g}},{key:"initPhysics",value:function(){!0===this.physicsEnabled&&!0===this.options.enabled?!0===this.options.stabilization.enabled?this.stabilize():(this.stabilized=!1,this.ready=!0,this.body.emitter.emit("fit",{},this.layoutFailed),this.startSimulation()):(this.ready=!0,this.body.emitter.emit("fit"))}},{key:"startSimulation",value:function(){var g;!0===this.physicsEnabled&&!0===this.options.enabled?(this.stabilized=!1,this.adaptiveTimestep=!1,this.body.emitter.emit("_resizeNodes"),void 0===this.viewFunction&&(this.viewFunction=QA(g=this.simulationStep).call(g,this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering"))):this.body.emitter.emit("_redraw")}},{key:"stopSimulation",value:function(){var g=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];this.stabilized=!0,!0===g&&this._emitStabilized(),void 0!==this.viewFunction&&(this.body.emitter.off("initRedraw",this.viewFunction),this.viewFunction=void 0,!0===g&&this.body.emitter.emit("_stopRendering"))}},{key:"simulationStep",value:function(){var g=ac();this.physicsTick(),(ac()-g<.4*this.simulationInterval||!0===this.runDoubleSpeed)&&!1===this.stabilized&&(this.physicsTick(),this.runDoubleSpeed=!0),!0===this.stabilized&&this.stopSimulation()}},{key:"_emitStabilized",value:function(){var g=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.stabilizationIterations;(this.stabilizationIterations>1||!0===this.startedStabilization)&&_f((function(){g.body.emitter.emit("stabilized",{iterations:t}),g.startedStabilization=!1,g.stabilizationIterations=0}),0)}},{key:"physicsStep",value:function(){this.gravitySolver.solve(),this.nodesSolver.solve(),this.edgesSolver.solve(),this.moveNodes()}},{key:"adjustTimeStep",value:function(){!0===this._evaluateStepQuality()?this.timestep=1.2*this.timestep:this.timestep/1.2.3))return!1;return!0}},{key:"moveNodes",value:function(){for(var g=this.physicsBody.physicsNodeIndices,t=0,e=0,A=0;AA&&(g=g>0?A:-A),g}},{key:"_performStep",value:function(g){var t=this.body.nodes[g],e=this.physicsBody.forces[g];this.options.wind&&(e.x+=this.options.wind.x,e.y+=this.options.wind.y);var A=this.physicsBody.velocities[g];return this.previousStates[g]={x:t.x,y:t.y,vx:A.x,vy:A.y},!1===t.options.fixed.x?(A.x=this.calculateComponentVelocity(A.x,e.x,t.options.mass),t.x+=A.x*this.timestep):(e.x=0,A.x=0),!1===t.options.fixed.y?(A.y=this.calculateComponentVelocity(A.y,e.y,t.options.mass),t.y+=A.y*this.timestep):(e.y=0,A.y=0),Math.sqrt(Math.pow(A.x,2)+Math.pow(A.y,2))}},{key:"_freezeNodes",value:function(){var g=this.body.nodes;for(var t in g)if(Object.prototype.hasOwnProperty.call(g,t)&&g[t].x&&g[t].y){var e=g[t].options.fixed;this.freezeCache[t]={x:e.x,y:e.y},e.x=!0,e.y=!0}}},{key:"_restoreFrozenNodes",value:function(){var g=this.body.nodes;for(var t in g)Object.prototype.hasOwnProperty.call(g,t)&&void 0!==this.freezeCache[t]&&(g[t].options.fixed.x=this.freezeCache[t].x,g[t].options.fixed.y=this.freezeCache[t].y);this.freezeCache={}}},{key:"stabilize",value:function(){var g=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.stabilization.iterations;"number"!=typeof t&&(t=this.options.stabilization.iterations,console.error("The stabilize method needs a numeric amount of iterations. Switching to default: ",t)),0!==this.physicsBody.physicsNodeIndices.length?(this.adaptiveTimestep=this.options.adaptiveTimestep,this.body.emitter.emit("_resizeNodes"),this.stopSimulation(),this.stabilized=!1,this.body.emitter.emit("_blockRedraw"),this.targetIterations=t,!0===this.options.stabilization.onlyDynamicEdges&&this._freezeNodes(),this.stabilizationIterations=0,_f((function(){return g._stabilizationBatch()}),0)):this.ready=!0}},{key:"_startStabilizing",value:function(){return!0!==this.startedStabilization&&(this.body.emitter.emit("startStabilizing"),this.startedStabilization=!0,!0)}},{key:"_stabilizationBatch",value:function(){var g=this,t=function(){return!1===g.stabilized&&g.stabilizationIterations1&&void 0!==arguments[1]?arguments[1]:[],A=1e9,C=-1e9,I=1e9,i=-1e9;if(e.length>0)for(var o=0;o(t=g[e[o]]).shape.boundingBox.left&&(I=t.shape.boundingBox.left),it.shape.boundingBox.top&&(A=t.shape.boundingBox.top),C1&&void 0!==arguments[1]?arguments[1]:[],A=1e9,C=-1e9,I=1e9,i=-1e9;if(e.length>0)for(var o=0;o(t=g[e[o]]).x&&(I=t.x),it.y&&(A=t.y),C=g&&e.push(C.id)}for(var I=0;I0&&void 0!==arguments[0]?arguments[0]:{},e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(void 0===t.joinCondition)throw new Error("Cannot call clusterByNodeData without a joinCondition function in the options.");t=this._checkOptions(t);var A={},C={};Lm(this.body.nodes,(function(e,I){e.options&&!0===t.joinCondition(e.options)&&(A[I]=e,Lm(e.edges,(function(t){void 0===g.clusteredEdges[t.id]&&(C[t.id]=t)})))})),this._cluster(A,C,t,e)}},{key:"clusterByEdgeCount",value:function(g,t){var e=this,A=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];t=this._checkOptions(t);for(var C,I,i,o=[],n={},r=function(){var A={},r={},a=e.body.nodeIndices[s],d=e.body.nodes[a];if(void 0===n[a]){i=0,I=[];for(var h=0;h0&&Cc(r).length>0&&!0===c){var f=function(){for(var g=0;g1&&void 0!==arguments[1])||arguments[1];this.clusterByEdgeCount(1,g,t)}},{key:"clusterBridges",value:function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];this.clusterByEdgeCount(2,g,t)}},{key:"clusterByConnection",value:function(g,t){var e,A=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(void 0===g)throw new Error("No nodeId supplied to clusterByConnection!");if(void 0===this.body.nodes[g])throw new Error("The nodeId given to clusterByConnection does not exist!");var C=this.body.nodes[g];void 0===(t=this._checkOptions(t,C)).clusterNodeProperties.x&&(t.clusterNodeProperties.x=C.x),void 0===t.clusterNodeProperties.y&&(t.clusterNodeProperties.y=C.y),void 0===t.clusterNodeProperties.fixed&&(t.clusterNodeProperties.fixed={},t.clusterNodeProperties.fixed.x=C.options.fixed.x,t.clusterNodeProperties.fixed.y=C.options.fixed.y);var I={},i={},o=C.id,n=Pz.cloneOptions(C);I[o]=C;for(var r=0;r-1&&(i[p.id]=p)}this._cluster(I,i,t,A)}},{key:"_createClusterEdges",value:function(g,t,e,A){for(var C,I,i,o,n,r,s=Cc(g),a=[],d=0;d0&&void 0!==arguments[0]?arguments[0]:{};return void 0===g.clusterEdgeProperties&&(g.clusterEdgeProperties={}),void 0===g.clusterNodeProperties&&(g.clusterNodeProperties={}),g}},{key:"_cluster",value:function(g,t,e){var A=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],C=[];for(var I in g)Object.prototype.hasOwnProperty.call(g,I)&&void 0!==this.clusteredNodes[I]&&C.push(I);for(var i=0;iC?t.x:C,I=t.yi?t.y:i;return{x:.5*(A+C),y:.5*(I+i)}}},{key:"openCluster",value:function(g,t){var e=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(void 0===g)throw new Error("No clusterNodeId supplied to openCluster.");var A=this.body.nodes[g];if(void 0===A)throw new Error("The clusterNodeId supplied to openCluster does not exist.");if(!0!==A.isCluster||void 0===A.containedNodes||void 0===A.containedEdges)throw new Error("The node:"+g+" is not a valid cluster.");var C=this.findNode(g),I=$p(C).call(C,g)-1;if(I>=0){var i=C[I];return this.body.nodes[i]._openChildCluster(g),delete this.body.nodes[g],void(!0===e&&this.body.emitter.emit("_dataChanged"))}var o=A.containedNodes,n=A.containedEdges;if(void 0!==t&&void 0!==t.releaseFunction&&"function"==typeof t.releaseFunction){var r={},s={x:A.x,y:A.y};for(var a in o)if(Object.prototype.hasOwnProperty.call(o,a)){var d=this.body.nodes[a];r[a]={x:d.x,y:d.y}}var h=t.releaseFunction(s,r);for(var l in o)if(Object.prototype.hasOwnProperty.call(o,l)){var c=this.body.nodes[l];void 0!==h[l]&&(c.x=void 0===h[l].x?A.x:h[l].x,c.y=void 0===h[l].y?A.y:h[l].y)}}else Lm(o,(function(g){!1===g.options.fixed.x&&(g.x=A.x),!1===g.options.fixed.y&&(g.y=A.y)}));for(var u in o)if(Object.prototype.hasOwnProperty.call(o,u)){var p=this.body.nodes[u];p.vx=A.vx,p.vy=A.vy,p.setOptions({physics:!0}),delete this.clusteredNodes[u]}for(var f=[],v=0;v0&&C<100;){var I=t.pop();if(void 0!==I){var i=this.body.edges[I];if(void 0!==i){C++;var o=i.clusteringEdgeReplacingIds;if(void 0===o)A.push(I);else for(var n=0;nA&&(A=I.edges.length),g+=I.edges.length,t+=Math.pow(I.edges.length,2),e+=1}g/=e;var i=(t/=e)-Math.pow(g,2),o=Math.sqrt(i),n=Math.floor(g+2*o);return n>A&&(n=A),n}},{key:"_createClusteredEdge",value:function(g,t,e,A,C){var I=Pz.cloneOptions(e,"edge");Fm(I,A),I.from=g,I.to=t,I.id="clusterEdge:"+OP(),void 0!==C&&Fm(I,C);var i=this.body.functions.createEdge(I);return i.clusteringEdgeReplacingIds=[e.id],i.connect(),this.body.edges[i.id]=i,i}},{key:"_clusterEdges",value:function(g,t,e,A){if(t instanceof vz){var C=t,I={};I[C.id]=C,t=I}if(g instanceof sB){var i=g,o={};o[i.id]=i,g=o}if(null==e)throw new Error("_clusterEdges: parameter clusterNode required");for(var n in void 0===A&&(A=e.clusterEdgeProperties),this._createClusterEdges(g,t,e,A),t)if(Object.prototype.hasOwnProperty.call(t,n)&&void 0!==this.body.edges[n]){var r=this.body.edges[n];this._backupEdgeOptions(r),r.setOptions({physics:!1})}for(var s in g)Object.prototype.hasOwnProperty.call(g,s)&&(this.clusteredNodes[s]={clusterId:e.id,node:this.body.nodes[s]},this.body.nodes[s].setOptions({physics:!1}))}},{key:"_getClusterNodeForNode",value:function(g){if(void 0!==g){var t=this.clusteredNodes[g];if(void 0!==t){var e=t.clusterId;if(void 0!==e)return this.body.nodes[e]}}}},{key:"_filter",value:function(g,t){var e=[];return Lm(g,(function(g){t(g)&&e.push(g)})),e}},{key:"_updateState",value:function(){var g,t=this,e=[],A={},C=function(g){Lm(t.body.nodes,(function(t){!0===t.isCluster&&g(t)}))};for(g in this.clusteredNodes){if(Object.prototype.hasOwnProperty.call(this.clusteredNodes,g))void 0===this.body.nodes[g]&&e.push(g)}C((function(g){for(var t=0;t0}g.endPointsValid()&&C||(A[e]=e)})),C((function(g){Lm(A,(function(e){delete g.containedEdges[e],Lm(g.edges,(function(C,I){C.id!==e?C.clusteringEdgeReplacingIds=t._filter(C.clusteringEdgeReplacingIds,(function(g){return!A[g]})):g.edges[I]=null})),g.edges=t._filter(g.edges,(function(g){return null!==g}))}))})),Lm(A,(function(g){delete t.clusteredEdges[g]})),Lm(A,(function(g){delete t.body.edges[g]})),Lm(Cc(this.body.edges),(function(g){var e=t.body.edges[g],A=t._isClusteredNode(e.fromId)||t._isClusteredNode(e.toId);if(A!==t._isClusteredEdge(e.id))if(A){var C=t._getClusterNodeForNode(e.fromId);void 0!==C&&t._clusterEdges(t.body.nodes[e.fromId],e,C);var I=t._getClusterNodeForNode(e.toId);void 0!==I&&t._clusterEdges(t.body.nodes[e.toId],e,I)}else delete t._clusterEdges[g],t._restoreEdge(e)}));for(var i=!1,o=!0,n=function(){var g=[];C((function(t){var e=Cc(t.containedNodes).length,A=!0===t.options.allowSingleNodeCluster;(A&&e<1||!A&&e<2)&&g.push(t.id)}));for(var e=0;e0,i=i||o};o;)n();i&&this._updateState()}},{key:"_isClusteredNode",value:function(g){return void 0!==this.clusteredNodes[g]}},{key:"_isClusteredEdge",value:function(g){return void 0!==this.clusteredEdges[g]}}]),g}();var Sz=function(){function g(t,e){var A;cd(this,g),void 0!==window&&(A=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame),window.requestAnimationFrame=void 0===A?function(g){g()}:A,this.body=t,this.canvas=e,this.redrawRequested=!1,this.renderTimer=void 0,this.requiresTimeout=!0,this.renderingActive=!1,this.renderRequests=0,this.allowRedraw=!0,this.dragging=!1,this.zooming=!1,this.options={},this.defaultOptions={hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1},yA(this.options,this.defaultOptions),this._determineBrowserMethod(),this.bindEventListeners()}return Bh(g,[{key:"bindEventListeners",value:function(){var g,t=this;this.body.emitter.on("dragStart",(function(){t.dragging=!0})),this.body.emitter.on("dragEnd",(function(){t.dragging=!1})),this.body.emitter.on("zoom",(function(){t.zooming=!0,window.clearTimeout(t.zoomTimeoutId),t.zoomTimeoutId=_f((function(){var g;t.zooming=!1,QA(g=t._requestRedraw).call(g,t)()}),250)})),this.body.emitter.on("_resizeNodes",(function(){t._resizeNodes()})),this.body.emitter.on("_redraw",(function(){!1===t.renderingActive&&t._redraw()})),this.body.emitter.on("_blockRedraw",(function(){t.allowRedraw=!1})),this.body.emitter.on("_allowRedraw",(function(){t.allowRedraw=!0,t.redrawRequested=!1})),this.body.emitter.on("_requestRedraw",QA(g=this._requestRedraw).call(g,this)),this.body.emitter.on("_startRendering",(function(){t.renderRequests+=1,t.renderingActive=!0,t._startRendering()})),this.body.emitter.on("_stopRendering",(function(){t.renderRequests-=1,t.renderingActive=t.renderRequests>0,t.renderTimer=void 0})),this.body.emitter.on("destroy",(function(){t.renderRequests=0,t.allowRedraw=!1,t.renderingActive=!1,!0===t.requiresTimeout?clearTimeout(t.renderTimer):window.cancelAnimationFrame(t.renderTimer),t.body.emitter.off()}))}},{key:"setOptions",value:function(g){if(void 0!==g){Sm(["hideEdgesOnDrag","hideEdgesOnZoom","hideNodesOnDrag"],this.options,g)}}},{key:"_requestNextFrame",value:function(g,t){if("undefined"!=typeof window){var e,A=window;return!0===this.requiresTimeout?e=_f(g,t):A.requestAnimationFrame&&(e=A.requestAnimationFrame(g)),e}}},{key:"_startRendering",value:function(){var g;!0===this.renderingActive&&(void 0===this.renderTimer&&(this.renderTimer=this._requestNextFrame(QA(g=this._renderStep).call(g,this),this.simulationInterval)))}},{key:"_renderStep",value:function(){!0===this.renderingActive&&(this.renderTimer=void 0,!0===this.requiresTimeout&&this._startRendering(),this._redraw(),!1===this.requiresTimeout&&this._startRendering())}},{key:"redraw",value:function(){this.body.emitter.emit("setSize"),this._redraw()}},{key:"_requestRedraw",value:function(){var g=this;!0!==this.redrawRequested&&!1===this.renderingActive&&!0===this.allowRedraw&&(this.redrawRequested=!0,this._requestNextFrame((function(){g._redraw(!1)}),0))}},{key:"_redraw",value:function(){var g=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(!0===this.allowRedraw){this.body.emitter.emit("initRedraw"),this.redrawRequested=!1;var t={drawExternalLabels:null};0!==this.canvas.frame.canvas.width&&0!==this.canvas.frame.canvas.height||this.canvas.setSize(),this.canvas.setTransform();var e=this.canvas.getContext(),A=this.canvas.frame.canvas.clientWidth,C=this.canvas.frame.canvas.clientHeight;if(e.clearRect(0,0,A,C),0===this.canvas.frame.clientWidth)return;if(e.save(),e.translate(this.body.view.translation.x,this.body.view.translation.y),e.scale(this.body.view.scale,this.body.view.scale),e.beginPath(),this.body.emitter.emit("beforeDrawing",e),e.closePath(),!1===g&&(!1===this.dragging||!0===this.dragging&&!1===this.options.hideEdgesOnDrag)&&(!1===this.zooming||!0===this.zooming&&!1===this.options.hideEdgesOnZoom)&&this._drawEdges(e),!1===this.dragging||!0===this.dragging&&!1===this.options.hideNodesOnDrag){var I=this._drawNodes(e,g).drawExternalLabels;t.drawExternalLabels=I}!1===g&&(!1===this.dragging||!0===this.dragging&&!1===this.options.hideEdgesOnDrag)&&(!1===this.zooming||!0===this.zooming&&!1===this.options.hideEdgesOnZoom)&&this._drawArrows(e),null!=t.drawExternalLabels&&t.drawExternalLabels(),!1===g&&this._drawSelectionBox(e),e.beginPath(),this.body.emitter.emit("afterDrawing",e),e.closePath(),e.restore(),!0===g&&e.clearRect(0,0,A,C)}}},{key:"_resizeNodes",value:function(){this.canvas.setTransform();var g=this.canvas.getContext();g.save(),g.translate(this.body.view.translation.x,this.body.view.translation.y),g.scale(this.body.view.scale,this.body.view.scale);var t,e=this.body.nodes;for(var A in e)Object.prototype.hasOwnProperty.call(e,A)&&((t=e[A]).resize(g),t.updateBoundingBox(g,t.selected));g.restore()}},{key:"_drawNodes",value:function(g){for(var t,e,A=arguments.length>1&&void 0!==arguments[1]&&arguments[1],C=this.body.nodes,I=this.body.nodeIndices,i=[],o=[],n=this.canvas.DOMtoCanvas({x:-20,y:-20}),r=this.canvas.DOMtoCanvas({x:this.canvas.frame.canvas.clientWidth+20,y:this.canvas.frame.canvas.clientHeight+20}),s={top:n.y,left:n.x,bottom:r.y,right:r.x},a=[],d=0;d0&&void 0!==arguments[0]?arguments[0]:this.pixelRatio;!0===this.initialized&&(this.cameraState.previousWidth=this.frame.canvas.width/g,this.cameraState.previousHeight=this.frame.canvas.height/g,this.cameraState.scale=this.body.view.scale,this.cameraState.position=this.DOMtoCanvas({x:.5*this.frame.canvas.width/g,y:.5*this.frame.canvas.height/g}))}},{key:"_setCameraState",value:function(){if(void 0!==this.cameraState.scale&&0!==this.frame.canvas.clientWidth&&0!==this.frame.canvas.clientHeight&&0!==this.pixelRatio&&this.cameraState.previousWidth>0&&this.cameraState.previousHeight>0){var g=this.frame.canvas.width/this.pixelRatio/this.cameraState.previousWidth,t=this.frame.canvas.height/this.pixelRatio/this.cameraState.previousHeight,e=this.cameraState.scale;1!=g&&1!=t?e=.5*this.cameraState.scale*(g+t):1!=g?e=this.cameraState.scale*g:1!=t&&(e=this.cameraState.scale*t),this.body.view.scale=e;var A=this.DOMtoCanvas({x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight}),C={x:A.x-this.cameraState.position.x,y:A.y-this.cameraState.position.y};this.body.view.translation.x+=C.x*this.body.view.scale,this.body.view.translation.y+=C.y*this.body.view.scale}}},{key:"_prepareValue",value:function(g){if("number"==typeof g)return g+"px";if("string"==typeof g){if(-1!==$p(g).call(g,"%")||-1!==$p(g).call(g,"px"))return g;if(-1===$p(g).call(g,"%"))return g+"px"}throw new Error("Could not use the value supplied for width or height:"+g)}},{key:"_create",value:function(){for(;this.body.container.hasChildNodes();)this.body.container.removeChild(this.body.container.firstChild);if(this.frame=document.createElement("div"),this.frame.className="vis-network",this.frame.style.position="relative",this.frame.style.overflow="hidden",this.frame.tabIndex=0,this.frame.canvas=document.createElement("canvas"),this.frame.canvas.style.position="relative",this.frame.appendChild(this.frame.canvas),this.frame.canvas.getContext)this._setPixelRatio(),this.setTransform();else{var g=document.createElement("DIV");g.style.color="red",g.style.fontWeight="bold",g.style.padding="10px",g.innerText="Error: your browser does not support HTML canvas",this.frame.canvas.appendChild(g)}this.body.container.appendChild(this.frame),this.body.view.scale=1,this.body.view.translation={x:.5*this.frame.canvas.clientWidth,y:.5*this.frame.canvas.clientHeight},this._bindHammer()}},{key:"_bindHammer",value:function(){var g=this;void 0!==this.hammer&&this.hammer.destroy(),this.drag={},this.pinch={},this.hammer=new db(this.frame.canvas),this.hammer.get("pinch").set({enable:!0}),this.hammer.get("pan").set({threshold:5,direction:db.DIRECTION_ALL}),jz(this.hammer,(function(t){g.body.eventListeners.onTouch(t)})),this.hammer.on("tap",(function(t){g.body.eventListeners.onTap(t)})),this.hammer.on("doubletap",(function(t){g.body.eventListeners.onDoubleTap(t)})),this.hammer.on("press",(function(t){g.body.eventListeners.onHold(t)})),this.hammer.on("panstart",(function(t){g.body.eventListeners.onDragStart(t)})),this.hammer.on("panmove",(function(t){g.body.eventListeners.onDrag(t)})),this.hammer.on("panend",(function(t){g.body.eventListeners.onDragEnd(t)})),this.hammer.on("pinch",(function(t){g.body.eventListeners.onPinch(t)})),this.frame.canvas.addEventListener("wheel",(function(t){g.body.eventListeners.onMouseWheel(t)})),this.frame.canvas.addEventListener("mousemove",(function(t){g.body.eventListeners.onMouseMove(t)})),this.frame.canvas.addEventListener("contextmenu",(function(t){g.body.eventListeners.onContext(t)})),this.hammerFrame=new db(this.frame),Lz(this.hammerFrame,(function(t){g.body.eventListeners.onRelease(t)}))}},{key:"setSize",value:function(){var g=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.options.width,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.height;g=this._prepareValue(g),t=this._prepareValue(t);var e=!1,A=this.frame.canvas.width,C=this.frame.canvas.height,I=this.pixelRatio;if(this._setPixelRatio(),g!=this.options.width||t!=this.options.height||this.frame.style.width!=g||this.frame.style.height!=t)this._getCameraState(I),this.frame.style.width=g,this.frame.style.height=t,this.frame.canvas.style.width="100%",this.frame.canvas.style.height="100%",this.frame.canvas.width=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),this.frame.canvas.height=Math.round(this.frame.canvas.clientHeight*this.pixelRatio),this.options.width=g,this.options.height=t,this.canvasViewCenter={x:.5*this.frame.clientWidth,y:.5*this.frame.clientHeight},e=!0;else{var i=Math.round(this.frame.canvas.clientWidth*this.pixelRatio),o=Math.round(this.frame.canvas.clientHeight*this.pixelRatio);this.frame.canvas.width===i&&this.frame.canvas.height===o||this._getCameraState(I),this.frame.canvas.width!==i&&(this.frame.canvas.width=i,e=!0),this.frame.canvas.height!==o&&(this.frame.canvas.height=o,e=!0)}return!0===e&&(this.body.emitter.emit("resize",{width:Math.round(this.frame.canvas.width/this.pixelRatio),height:Math.round(this.frame.canvas.height/this.pixelRatio),oldWidth:Math.round(A/this.pixelRatio),oldHeight:Math.round(C/this.pixelRatio)}),this._setCameraState()),this.initialized=!0,e}},{key:"getContext",value:function(){return this.frame.canvas.getContext("2d")}},{key:"_determinePixelRatio",value:function(){var g=this.getContext();if(void 0===g)throw new Error("Could not get canvax context");var t=1;return"undefined"!=typeof window&&(t=window.devicePixelRatio||1),t/(g.webkitBackingStorePixelRatio||g.mozBackingStorePixelRatio||g.msBackingStorePixelRatio||g.oBackingStorePixelRatio||g.backingStorePixelRatio||1)}},{key:"_setPixelRatio",value:function(){this.pixelRatio=this._determinePixelRatio()}},{key:"setTransform",value:function(){var g=this.getContext();if(void 0===g)throw new Error("Could not get canvax context");g.setTransform(this.pixelRatio,0,0,this.pixelRatio,0,0)}},{key:"_XconvertDOMtoCanvas",value:function(g){return(g-this.body.view.translation.x)/this.body.view.scale}},{key:"_XconvertCanvasToDOM",value:function(g){return g*this.body.view.scale+this.body.view.translation.x}},{key:"_YconvertDOMtoCanvas",value:function(g){return(g-this.body.view.translation.y)/this.body.view.scale}},{key:"_YconvertCanvasToDOM",value:function(g){return g*this.body.view.scale+this.body.view.translation.y}},{key:"canvasToDOM",value:function(g){return{x:this._XconvertCanvasToDOM(g.x),y:this._YconvertCanvasToDOM(g.y)}}},{key:"DOMtoCanvas",value:function(g){return{x:this._XconvertDOMtoCanvas(g.x),y:this._YconvertDOMtoCanvas(g.y)}}}]),g}();var Yz=function(){function g(t,e){var A,C,I=this;cd(this,g),this.body=t,this.canvas=e,this.animationSpeed=1/this.renderRefreshRate,this.animationEasingFunction="easeInOutQuint",this.easingTime=0,this.sourceScale=0,this.targetScale=0,this.sourceTranslation=0,this.targetTranslation=0,this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0,this.touchTime=0,this.viewFunction=void 0,this.body.emitter.on("fit",QA(A=this.fit).call(A,this)),this.body.emitter.on("animationFinished",(function(){I.body.emitter.emit("_stopRendering")})),this.body.emitter.on("unlockNode",QA(C=this.releaseNode).call(C,this))}return Bh(g,[{key:"setOptions",value:function(){var g=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.options=g}},{key:"fit",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];g=function(g,t){var e=yA({nodes:t,minZoomLevel:Number.MIN_VALUE,maxZoomLevel:1},null!=g?g:{});if(!Vl(e.nodes))throw new TypeError("Nodes has to be an array of ids.");if(0===e.nodes.length&&(e.nodes=t),!("number"==typeof e.minZoomLevel&&e.minZoomLevel>0))throw new TypeError("Min zoom level has to be a number higher than zero.");if(!("number"==typeof e.maxZoomLevel&&e.minZoomLevel<=e.maxZoomLevel))throw new TypeError("Max zoom level has to be a number higher than min zoom level.");return e}(g,this.body.nodeIndices);var e,A,C=this.canvas.frame.canvas.clientWidth,I=this.canvas.frame.canvas.clientHeight;if(0===C||0===I)A=1,e=Pz.getRange(this.body.nodes,g.nodes);else if(!0===t){var i=0;for(var o in this.body.nodes){if(Object.prototype.hasOwnProperty.call(this.body.nodes,o))!0===this.body.nodes[o].predefinedPosition&&(i+=1)}if(i>.5*this.body.nodeIndices.length)return void this.fit(g,!1);e=Pz.getRange(this.body.nodes,g.nodes),A=12.662/(this.body.nodeIndices.length+7.4147)+.0964822,A*=Math.min(C/600,I/600)}else{this.body.emitter.emit("_resizeNodes"),e=Pz.getRange(this.body.nodes,g.nodes);var n=C/(1.1*Math.abs(e.maxX-e.minX)),r=I/(1.1*Math.abs(e.maxY-e.minY));A=n<=r?n:r}A>g.maxZoomLevel?A=g.maxZoomLevel:A1&&void 0!==arguments[1]?arguments[1]:{};if(void 0!==this.body.nodes[g]){var e={x:this.body.nodes[g].x,y:this.body.nodes[g].y};t.position=e,t.lockedOnNode=g,this.moveTo(t)}else console.error("Node: "+g+" cannot be found.")}},{key:"moveTo",value:function(g){if(void 0!==g){if(null!=g.offset){if(null!=g.offset.x){if(g.offset.x=+g.offset.x,!Zx(g.offset.x))throw new TypeError('The option "offset.x" has to be a finite number.')}else g.offset.x=0;if(null!=g.offset.y){if(g.offset.y=+g.offset.y,!Zx(g.offset.y))throw new TypeError('The option "offset.y" has to be a finite number.')}else g.offset.x=0}else g.offset={x:0,y:0};if(null!=g.position){if(null!=g.position.x){if(g.position.x=+g.position.x,!Zx(g.position.x))throw new TypeError('The option "position.x" has to be a finite number.')}else g.position.x=0;if(null!=g.position.y){if(g.position.y=+g.position.y,!Zx(g.position.y))throw new TypeError('The option "position.y" has to be a finite number.')}else g.position.x=0}else g.position=this.getViewPosition();if(null!=g.scale){if(g.scale=+g.scale,!(g.scale>0))throw new TypeError('The option "scale" has to be a number greater than zero.')}else g.scale=this.body.view.scale;void 0===g.animation&&(g.animation={duration:0}),!1===g.animation&&(g.animation={duration:0}),!0===g.animation&&(g.animation={}),void 0===g.animation.duration&&(g.animation.duration=1e3),void 0===g.animation.easingFunction&&(g.animation.easingFunction="easeInOutQuad"),this.animateView(g)}else g={}}},{key:"animateView",value:function(g){if(void 0!==g){this.animationEasingFunction=g.animation.easingFunction,this.releaseNode(),!0===g.locked&&(this.lockedOnNodeId=g.lockedOnNode,this.lockedOnNodeOffset=g.offset),0!=this.easingTime&&this._transitionRedraw(!0),this.sourceScale=this.body.view.scale,this.sourceTranslation=this.body.view.translation,this.targetScale=g.scale,this.body.view.scale=this.targetScale;var t,e,A=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),C=A.x-g.position.x,I=A.y-g.position.y;if(this.targetTranslation={x:this.sourceTranslation.x+C*this.targetScale+g.offset.x,y:this.sourceTranslation.y+I*this.targetScale+g.offset.y},0===g.animation.duration)if(null!=this.lockedOnNodeId)this.viewFunction=QA(t=this._lockedRedraw).call(t,this),this.body.emitter.on("initRedraw",this.viewFunction);else this.body.view.scale=this.targetScale,this.body.view.translation=this.targetTranslation,this.body.emitter.emit("_requestRedraw");else this.animationSpeed=1/(60*g.animation.duration*.001)||1/60,this.animationEasingFunction=g.animation.easingFunction,this.viewFunction=QA(e=this._transitionRedraw).call(e,this),this.body.emitter.on("initRedraw",this.viewFunction),this.body.emitter.emit("_startRendering")}}},{key:"_lockedRedraw",value:function(){var g=this.body.nodes[this.lockedOnNodeId].x,t=this.body.nodes[this.lockedOnNodeId].y,e=this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight}),A=e.x-g,C=e.y-t,I=this.body.view.translation,i={x:I.x+A*this.body.view.scale+this.lockedOnNodeOffset.x,y:I.y+C*this.body.view.scale+this.lockedOnNodeOffset.y};this.body.view.translation=i}},{key:"releaseNode",value:function(){void 0!==this.lockedOnNodeId&&void 0!==this.viewFunction&&(this.body.emitter.off("initRedraw",this.viewFunction),this.lockedOnNodeId=void 0,this.lockedOnNodeOffset=void 0)}},{key:"_transitionRedraw",value:function(){var g=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.easingTime+=this.animationSpeed,this.easingTime=!0===g?1:this.easingTime;var t=$m[this.animationEasingFunction](this.easingTime);if(this.body.view.scale=this.sourceScale+(this.targetScale-this.sourceScale)*t,this.body.view.translation={x:this.sourceTranslation.x+(this.targetTranslation.x-this.sourceTranslation.x)*t,y:this.sourceTranslation.y+(this.targetTranslation.y-this.sourceTranslation.y)*t},this.easingTime>=1){var e;if(this.body.emitter.off("initRedraw",this.viewFunction),this.easingTime=0,null!=this.lockedOnNodeId)this.viewFunction=QA(e=this._lockedRedraw).call(e,this),this.body.emitter.on("initRedraw",this.viewFunction);this.body.emitter.emit("animationFinished")}}},{key:"getScale",value:function(){return this.body.view.scale}},{key:"getViewPosition",value:function(){return this.canvas.DOMtoCanvas({x:.5*this.canvas.frame.canvas.clientWidth,y:.5*this.canvas.frame.canvas.clientHeight})}}]),g}();function Wz(g){var t,e=g&&g.preventDefault||!1,A=g&&g.container||window,C={},I={keydown:{},keyup:{}},i={};for(t=97;t<=122;t++)i[String.fromCharCode(t)]={code:t-97+65,shift:!1};for(t=65;t<=90;t++)i[String.fromCharCode(t)]={code:t,shift:!0};for(t=0;t<=9;t++)i[""+t]={code:48+t,shift:!1};for(t=1;t<=12;t++)i["F"+t]={code:111+t,shift:!1};for(t=0;t<=9;t++)i["num"+t]={code:96+t,shift:!1};i["num*"]={code:106,shift:!1},i["num+"]={code:107,shift:!1},i["num-"]={code:109,shift:!1},i["num/"]={code:111,shift:!1},i["num."]={code:110,shift:!1},i.left={code:37,shift:!1},i.up={code:38,shift:!1},i.right={code:39,shift:!1},i.down={code:40,shift:!1},i.space={code:32,shift:!1},i.enter={code:13,shift:!1},i.shift={code:16,shift:void 0},i.esc={code:27,shift:!1},i.backspace={code:8,shift:!1},i.tab={code:9,shift:!1},i.ctrl={code:17,shift:!1},i.alt={code:18,shift:!1},i.delete={code:46,shift:!1},i.pageup={code:33,shift:!1},i.pagedown={code:34,shift:!1},i["="]={code:187,shift:!1},i["-"]={code:189,shift:!1},i["]"]={code:221,shift:!1},i["["]={code:219,shift:!1};var o=function(g){r(g,"keydown")},n=function(g){r(g,"keyup")},r=function(g,t){if(void 0!==I[t][g.keyCode]){for(var A=I[t][g.keyCode],C=0;C700&&(this.body.emitter.emit("fit",{duration:700}),this.touchTime=(new Date).valueOf())}},{key:"_stopMovement",value:function(){for(var g in this.boundFunctions)Object.prototype.hasOwnProperty.call(this.boundFunctions,g)&&(this.body.emitter.off("initRedraw",this.boundFunctions[g]),this.body.emitter.emit("_stopRendering"));this.boundFunctions={}}},{key:"_moveUp",value:function(){this.body.view.translation.y+=this.options.keyboard.speed.y}},{key:"_moveDown",value:function(){this.body.view.translation.y-=this.options.keyboard.speed.y}},{key:"_moveLeft",value:function(){this.body.view.translation.x+=this.options.keyboard.speed.x}},{key:"_moveRight",value:function(){this.body.view.translation.x-=this.options.keyboard.speed.x}},{key:"_zoomIn",value:function(){var g=this.body.view.scale,t=this.body.view.scale*(1+this.options.keyboard.speed.zoom),e=this.body.view.translation,A=t/g,C=(1-A)*this.canvas.canvasViewCenter.x+e.x*A,I=(1-A)*this.canvas.canvasViewCenter.y+e.y*A;this.body.view.scale=t,this.body.view.translation={x:C,y:I},this.body.emitter.emit("zoom",{direction:"+",scale:this.body.view.scale,pointer:null})}},{key:"_zoomOut",value:function(){var g=this.body.view.scale,t=this.body.view.scale/(1+this.options.keyboard.speed.zoom),e=this.body.view.translation,A=t/g,C=(1-A)*this.canvas.canvasViewCenter.x+e.x*A,I=(1-A)*this.canvas.canvasViewCenter.y+e.y*A;this.body.view.scale=t,this.body.view.translation={x:C,y:I},this.body.emitter.emit("zoom",{direction:"-",scale:this.body.view.scale,pointer:null})}},{key:"configureKeyboardBindings",value:function(){var g,t,e,A,C,I,i,o,n,r,s,a,d,h,l,c,u,p,f,v,y,m,b,w,x=this;(void 0!==this.keycharm&&this.keycharm.destroy(),!0===this.options.keyboard.enabled)&&(!0===this.options.keyboard.bindToWindow?this.keycharm=Wz({container:window,preventDefault:!0}):this.keycharm=Wz({container:this.canvas.frame,preventDefault:!0}),this.keycharm.reset(),!0===this.activated&&(QA(g=this.keycharm).call(g,"up",(function(){x.bindToRedraw("_moveUp")}),"keydown"),QA(t=this.keycharm).call(t,"down",(function(){x.bindToRedraw("_moveDown")}),"keydown"),QA(e=this.keycharm).call(e,"left",(function(){x.bindToRedraw("_moveLeft")}),"keydown"),QA(A=this.keycharm).call(A,"right",(function(){x.bindToRedraw("_moveRight")}),"keydown"),QA(C=this.keycharm).call(C,"=",(function(){x.bindToRedraw("_zoomIn")}),"keydown"),QA(I=this.keycharm).call(I,"num+",(function(){x.bindToRedraw("_zoomIn")}),"keydown"),QA(i=this.keycharm).call(i,"num-",(function(){x.bindToRedraw("_zoomOut")}),"keydown"),QA(o=this.keycharm).call(o,"-",(function(){x.bindToRedraw("_zoomOut")}),"keydown"),QA(n=this.keycharm).call(n,"[",(function(){x.bindToRedraw("_zoomOut")}),"keydown"),QA(r=this.keycharm).call(r,"]",(function(){x.bindToRedraw("_zoomIn")}),"keydown"),QA(s=this.keycharm).call(s,"pageup",(function(){x.bindToRedraw("_zoomIn")}),"keydown"),QA(a=this.keycharm).call(a,"pagedown",(function(){x.bindToRedraw("_zoomOut")}),"keydown"),QA(d=this.keycharm).call(d,"up",(function(){x.unbindFromRedraw("_moveUp")}),"keyup"),QA(h=this.keycharm).call(h,"down",(function(){x.unbindFromRedraw("_moveDown")}),"keyup"),QA(l=this.keycharm).call(l,"left",(function(){x.unbindFromRedraw("_moveLeft")}),"keyup"),QA(c=this.keycharm).call(c,"right",(function(){x.unbindFromRedraw("_moveRight")}),"keyup"),QA(u=this.keycharm).call(u,"=",(function(){x.unbindFromRedraw("_zoomIn")}),"keyup"),QA(p=this.keycharm).call(p,"num+",(function(){x.unbindFromRedraw("_zoomIn")}),"keyup"),QA(f=this.keycharm).call(f,"num-",(function(){x.unbindFromRedraw("_zoomOut")}),"keyup"),QA(v=this.keycharm).call(v,"-",(function(){x.unbindFromRedraw("_zoomOut")}),"keyup"),QA(y=this.keycharm).call(y,"[",(function(){x.unbindFromRedraw("_zoomOut")}),"keyup"),QA(m=this.keycharm).call(m,"]",(function(){x.unbindFromRedraw("_zoomIn")}),"keyup"),QA(b=this.keycharm).call(b,"pageup",(function(){x.unbindFromRedraw("_zoomIn")}),"keyup"),QA(w=this.keycharm).call(w,"pagedown",(function(){x.unbindFromRedraw("_zoomOut")}),"keyup")))}}]),g}();function Uz(g,t){var e=void 0!==kl&&bn(g)||g["@@iterator"];if(!e){if(Vl(g)||(e=function(g,t){var e;if(!g)return;if("string"==typeof g)return _z(g,t);var A=Sl(e=Object.prototype.toString.call(g)).call(e,8,-1);"Object"===A&&g.constructor&&(A=g.constructor.name);if("Map"===A||"Set"===A)return Jo(g);if("Arguments"===A||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(A))return _z(g,t)}(g))||t&&g&&"number"==typeof g.length){e&&(g=e);var A=0,C=function(){};return{s:C,n:function(){return A>=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function _z(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e50&&(this.drag.pointer=this.getPointer(g.center),this.drag.pinched=!1,this.pinch.scale=this.body.view.scale,this.touchTime=(new Date).valueOf())}},{key:"onTap",value:function(g){var t=this.getPointer(g.center),e=this.selectionHandler.options.multiselect&&(g.changedPointers[0].ctrlKey||g.changedPointers[0].metaKey);this.checkSelectionChanges(t,e),this.selectionHandler.commitAndEmit(t,g),this.selectionHandler.generateClickEvent("click",g,t)}},{key:"onDoubleTap",value:function(g){var t=this.getPointer(g.center);this.selectionHandler.generateClickEvent("doubleClick",g,t)}},{key:"onHold",value:function(g){var t=this.getPointer(g.center),e=this.selectionHandler.options.multiselect;this.checkSelectionChanges(t,e),this.selectionHandler.commitAndEmit(t,g),this.selectionHandler.generateClickEvent("click",g,t),this.selectionHandler.generateClickEvent("hold",g,t)}},{key:"onRelease",value:function(g){if((new Date).valueOf()-this.touchTime>10){var t=this.getPointer(g.center);this.selectionHandler.generateClickEvent("release",g,t),this.touchTime=(new Date).valueOf()}}},{key:"onContext",value:function(g){var t=this.getPointer({x:g.clientX,y:g.clientY});this.selectionHandler.generateClickEvent("oncontext",g,t)}},{key:"checkSelectionChanges",value:function(g){!0===(arguments.length>1&&void 0!==arguments[1]&&arguments[1])?this.selectionHandler.selectAdditionalOnPoint(g):this.selectionHandler.selectOnPoint(g)}},{key:"_determineDifference",value:function(g,t){var e=function(g,t){for(var e=[],A=0;A=C.minX&&e.x<=C.maxX&&e.y>=C.minY&&e.y<=C.maxY}));Ec(I).call(I,(function(g){return t.selectionHandler.selectObject(t.body.nodes[g])}));var i=this.getPointer(g.center);this.selectionHandler.commitAndEmit(i,g),this.selectionHandler.generateClickEvent("dragEnd",g,this.getPointer(g.center),void 0,!0),this.body.emitter.emit("_requestRedraw")}else{var o=this.drag.selection;o&&o.length?(Ec(o).call(o,(function(g){g.node.options.fixed.x=g.xFixed,g.node.options.fixed.y=g.yFixed})),this.selectionHandler.generateClickEvent("dragEnd",g,this.getPointer(g.center)),this.body.emitter.emit("startSimulation")):(this.selectionHandler.generateClickEvent("dragEnd",g,this.getPointer(g.center),void 0,!0),this.body.emitter.emit("_requestRedraw"))}}},{key:"onPinch",value:function(g){var t=this.getPointer(g.center);this.drag.pinched=!0,void 0===this.pinch.scale&&(this.pinch.scale=1);var e=this.pinch.scale*g.scale;this.zoom(e,t)}},{key:"zoom",value:function(g,t){if(!0===this.options.zoomView){var e=this.body.view.scale;g<1e-5&&(g=1e-5),g>10&&(g=10);var A=void 0;void 0!==this.drag&&!0===this.drag.dragging&&(A=this.canvas.DOMtoCanvas(this.drag.pointer));var C=this.body.view.translation,I=g/e,i=(1-I)*t.x+C.x*I,o=(1-I)*t.y+C.y*I;if(this.body.view.scale=g,this.body.view.translation={x:i,y:o},null!=A){var n=this.canvas.canvasToDOM(A);this.drag.pointer.x=n.x,this.drag.pointer.y=n.y}this.body.emitter.emit("_requestRedraw"),e0&&(this.popupObj=r[s[s.length-1]],I=!0)}if(void 0===this.popupObj&&!1===I){for(var d,h=this.body.edgeIndices,l=this.body.edges,c=[],u=0;u0&&(this.popupObj=l[c[c.length-1]],i="edge")}void 0!==this.popupObj?this.popupObj.id!==C&&(void 0===this.popup&&(this.popup=new hb(this.canvas.frame)),this.popup.popupTargetType=i,this.popup.popupTargetId=this.popupObj.id,this.popup.setPosition(g.x+3,g.y-5),this.popup.setText(this.popupObj.getTitle()),this.popup.show(),this.body.emitter.emit("showPopup",this.popupObj.id)):void 0!==this.popup&&(this.popup.hide(),this.body.emitter.emit("hidePopup"))}},{key:"_checkHidePopup",value:function(g){var t=this.selectionHandler._pointerToPositionObject(g),e=!1;if("node"===this.popup.popupTargetType){if(void 0!==this.body.nodes[this.popup.popupTargetId]&&!0===(e=this.body.nodes[this.popup.popupTargetId].isOverlappingWith(t))){var A=this.selectionHandler.getNodeAt(g);e=void 0!==A&&A.id===this.popup.popupTargetId}}else void 0===this.selectionHandler.getNodeAt(g)&&void 0!==this.body.edges[this.popup.popupTargetId]&&(e=this.body.edges[this.popup.popupTargetId].isOverlappingWith(t));!1===e&&(this.popupObj=void 0,this.popup.hide(),this.body.emitter.emit("hidePopup"))}}]),g}(),Kz={},Xz={get exports(){return Kz},set exports(g){Kz=g}},Jz=f,qz=Cx,$z=$b.getWeakData,gS=jw,tS=Ae,eS=_,AS=eg,CS=Zw,IS=$g,iS=UC.set,oS=UC.getterFor,nS=ur.find,rS=ur.findIndex,sS=Jz([].splice),aS=0,dS=function(g){return g.frozen||(g.frozen=new hS)},hS=function(){this.entries=[]},lS=function(g,t){return nS(g.entries,(function(g){return g[0]===t}))};hS.prototype={get:function(g){var t=lS(this,g);if(t)return t[1]},has:function(g){return!!lS(this,g)},set:function(g,t){var e=lS(this,g);e?e[1]=t:this.entries.push([g,t])},delete:function(g){var t=rS(this.entries,(function(t){return t[0]===g}));return~t&&sS(this.entries,t,1),!!~t}};var cS,uS={getConstructor:function(g,t,e,A){var C=g((function(g,C){gS(g,I),iS(g,{type:t,id:aS++,frozen:void 0}),eS(C)||CS(C,g[A],{that:g,AS_ENTRIES:e})})),I=C.prototype,i=oS(t),o=function(g,t,e){var A=i(g),C=$z(tS(t),!0);return!0===C?dS(A).set(t,e):C[A.id]=e,g};return qz(I,{delete:function(g){var t=i(this);if(!AS(g))return!1;var e=$z(g);return!0===e?dS(t).delete(g):e&&IS(e,t.id)&&delete e[t.id]},has:function(g){var t=i(this);if(!AS(g))return!1;var e=$z(g);return!0===e?dS(t).has(g):e&&IS(e,t.id)}}),qz(I,e?{get:function(g){var t=i(this);if(AS(g)){var e=$z(g);return!0===e?dS(t).get(g):e?e[t.id]:void 0}},set:function(g,t){return o(this,g,t)}}:{add:function(g){return o(this,g,!0)}}),C}},pS=nw,fS=i,vS=f,yS=Cx,mS=$b,bS=ex,wS=uS,xS=eg,kS=UC.enforce,ES=o,OS=DC,TS=Object,DS=Array.isArray,NS=TS.isExtensible,RS=TS.isFrozen,PS=TS.isSealed,MS=TS.freeze,BS=TS.seal,zS={},SS={},ZS=!fS.ActiveXObject&&"ActiveXObject"in fS,FS=function(g){return function(){return g(this,arguments.length?arguments[0]:void 0)}},GS=bS("WeakMap",FS,wS),jS=GS.prototype,LS=vS(jS.set);if(OS)if(ZS){cS=wS.getConstructor(FS,"WeakMap",!0),mS.enable();var VS=vS(jS.delete),YS=vS(jS.has),WS=vS(jS.get);yS(jS,{delete:function(g){if(xS(g)&&!NS(g)){var t=kS(this);return t.frozen||(t.frozen=new cS),VS(this,g)||t.frozen.delete(g)}return VS(this,g)},has:function(g){if(xS(g)&&!NS(g)){var t=kS(this);return t.frozen||(t.frozen=new cS),YS(this,g)||t.frozen.has(g)}return YS(this,g)},get:function(g){if(xS(g)&&!NS(g)){var t=kS(this);return t.frozen||(t.frozen=new cS),YS(this,g)?WS(this,g):t.frozen.get(g)}return WS(this,g)},set:function(g,t){if(xS(g)&&!NS(g)){var e=kS(this);e.frozen||(e.frozen=new cS),YS(this,g)?LS(this,g,t):e.frozen.set(g,t)}else LS(this,g,t);return this}})}else pS&&ES((function(){var g=MS([]);return LS(new GS,g,1),!RS(g)}))&&yS(jS,{set:function(g,t){var e;return DS(g)&&(RS(g)?e=zS:PS(g)&&(e=SS)),LS(this,g,t),e==zS&&MS(g),e==SS&&BS(g),this}});var QS=Ag.WeakMap;!function(g){g.exports=QS}(Xz);var US,_S,HS,KS,XS,JS=e(Kz);function qS(g,t,e,A){if("a"===e&&!A)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?g!==t||!A:!t.has(g))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===e?A:"a"===e?A.call(g):A?A.value:t.get(g)}function $S(g,t,e,A,C){if("m"===A)throw new TypeError("Private method is not writable");if("a"===A&&!C)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?g!==t||!C:!t.has(g))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===A?C.call(g,e):C?C.value=e:t.set(g,e),e}function gZ(g,t){var e=void 0!==kl&&bn(g)||g["@@iterator"];if(!e){if(Vl(g)||(e=function(g,t){var e;if(!g)return;if("string"==typeof g)return tZ(g,t);var A=Sl(e=Object.prototype.toString.call(g)).call(e,8,-1);"Object"===A&&g.constructor&&(A=g.constructor.name);if("Map"===A||"Set"===A)return Jo(g);if("Arguments"===A||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(A))return tZ(g,t)}(g))||t&&g&&"number"==typeof g.length){e&&(g=e);var A=0,C=function(){};return{s:C,n:function(){return A>=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function tZ(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e0&&void 0!==arguments[0]?arguments[0]:function(){};cd(this,g),HS.set(this,new AZ),KS.set(this,new AZ),XS.set(this,void 0),$S(this,XS,t,"f")}return Bh(g,[{key:"sizeNodes",get:function(){return qS(this,HS,"f").size}},{key:"sizeEdges",get:function(){return qS(this,KS,"f").size}},{key:"getNodes",value:function(){return qS(this,HS,"f").getSelection()}},{key:"getEdges",value:function(){return qS(this,KS,"f").getSelection()}},{key:"addNodes",value:function(){var g;(g=qS(this,HS,"f")).add.apply(g,arguments)}},{key:"addEdges",value:function(){var g;(g=qS(this,KS,"f")).add.apply(g,arguments)}},{key:"deleteNodes",value:function(g){qS(this,HS,"f").delete(g)}},{key:"deleteEdges",value:function(g){qS(this,KS,"f").delete(g)}},{key:"clear",value:function(){qS(this,HS,"f").clear(),qS(this,KS,"f").clear()}},{key:"commit",value:function(){for(var g,t,e={nodes:qS(this,HS,"f").commit(),edges:qS(this,KS,"f").commit()},A=arguments.length,C=new Array(A),I=0;I=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function iZ(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e4&&void 0!==arguments[4]&&arguments[4],I=this._initBaseEvent(t,e);if(!0===C)I.nodes=[],I.edges=[];else{var i=this.getSelection();I.nodes=i.nodes,I.edges=i.edges}void 0!==A&&(I.previousSelection=A),"click"==g&&(I.items=this.getClickedItems(e)),void 0!==t.controlEdge&&(I.controlEdge=t.controlEdge),this.body.emitter.emit(g,I)}},{key:"selectObject",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.options.selectConnectedEdges;if(void 0!==g){if(g instanceof sB){var e;if(!0===t)(e=this._selectionAccumulator).addEdges.apply(e,wl(g.edges));this._selectionAccumulator.addNodes(g)}else this._selectionAccumulator.addEdges(g);return!0}return!1}},{key:"deselectObject",value:function(g){!0===g.isSelected()&&(g.selected=!1,this._removeFromSelection(g))}},{key:"_getAllNodesOverlappingWith",value:function(g){for(var t=[],e=this.body.nodes,A=0;A1&&void 0!==arguments[1])||arguments[1],e=this._pointerToPositionObject(g),A=this._getAllNodesOverlappingWith(e);return A.length>0?!0===t?this.body.nodes[A[A.length-1]]:A[A.length-1]:void 0}},{key:"_getEdgesOverlappingWith",value:function(g,t){for(var e=this.body.edges,A=0;A1&&void 0!==arguments[1])||arguments[1],e=this.canvas.DOMtoCanvas(g),A=10,C=null,I=this.body.edges,i=0;i0&&(this.generateClickEvent("deselectEdge",t,g,C),e=!0),A.nodes.deleted.length>0&&(this.generateClickEvent("deselectNode",t,g,C),e=!0),A.nodes.added.length>0&&(this.generateClickEvent("selectNode",t,g),e=!0),A.edges.added.length>0&&(this.generateClickEvent("selectEdge",t,g),e=!0),!0===e&&this.generateClickEvent("select",t,g)}},{key:"getSelection",value:function(){return{nodes:this.getSelectedNodeIds(),edges:this.getSelectedEdgeIds()}}},{key:"getSelectedNodes",value:function(){return this._selectionAccumulator.getNodes()}},{key:"getSelectedEdges",value:function(){return this._selectionAccumulator.getEdges()}},{key:"getSelectedNodeIds",value:function(){var g;return ql(g=this._selectionAccumulator.getNodes()).call(g,(function(g){return g.id}))}},{key:"getSelectedEdgeIds",value:function(){var g;return ql(g=this._selectionAccumulator.getEdges()).call(g,(function(g){return g.id}))}},{key:"setSelection",value:function(g){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!g||!g.nodes&&!g.edges)throw new TypeError("Selection must be an object with nodes and/or edges properties");if((t.unselectAll||void 0===t.unselectAll)&&this.unselectAll(),g.nodes){var e,A=IZ(g.nodes);try{for(A.s();!(e=A.n()).done;){var C=e.value,I=this.body.nodes[C];if(!I)throw new RangeError('Node with id "'+C+'" not found');this.selectObject(I,t.highlightEdges)}}catch(g){A.e(g)}finally{A.f()}}if(g.edges){var i,o=IZ(g.edges);try{for(o.s();!(i=o.n()).done;){var n=i.value,r=this.body.edges[n];if(!r)throw new RangeError('Edge with id "'+n+'" not found');this.selectObject(r)}}catch(g){o.e(g)}finally{o.f()}}this.body.emitter.emit("_requestRedraw"),this._selectionAccumulator.commit()}},{key:"selectNodes",value:function(g){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!g||void 0===g.length)throw"Selection must be an array with ids";this.setSelection({nodes:g},{highlightEdges:t})}},{key:"selectEdges",value:function(g){if(!g||void 0===g.length)throw"Selection must be an array with ids";this.setSelection({edges:g})}},{key:"updateSelection",value:function(){for(var g in this._selectionAccumulator.getNodes())Object.prototype.hasOwnProperty.call(this.body.nodes,g.id)||this._selectionAccumulator.deleteNodes(g);for(var t in this._selectionAccumulator.getEdges())Object.prototype.hasOwnProperty.call(this.body.edges,t.id)||this._selectionAccumulator.deleteEdges(t)}},{key:"getClickedItems",value:function(g){for(var t=this.canvas.DOMtoCanvas(g),e=[],A=this.body.nodeIndices,C=this.body.nodes,I=A.length-1;I>=0;I--){var i=C[A[I]].getItemsOnPoint(t);e.push.apply(e,i)}for(var o=this.body.edgeIndices,n=this.body.edges,r=o.length-1;r>=0;r--){var s=n[o[r]].getItemsOnPoint(t);e.push.apply(e,s)}return e}}]),g}(),nZ={},rZ={get exports(){return nZ},set exports(g){nZ=g}},sZ={};!function(g){!function(g){function t(g,t){if(!(g instanceof t))throw new TypeError("Cannot call a class as a function")}g.__esModule=!0,g.sort=c;var e=32,A=7,C=256,I=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9];function i(g){return g<1e5?g<100?g<10?0:1:g<1e4?g<1e3?2:3:4:g<1e7?g<1e6?5:6:g<1e9?g<1e8?7:8:9}function o(g,t){if(g===t)return 0;if(~~g===g&&~~t===t){if(0===g||0===t)return g=0)return-1;if(g>=0)return 1;g=-g,t=-t}var e=i(g),A=i(t),C=0;return eA&&(t*=I[e-A-1],g/=10,C=1),g===t?C:g=e;)t|=1&g,g>>=1;return g+t}function r(g,t,e,A){var C=t+1;if(C===e)return 1;if(A(g[C++],g[t])<0){for(;C=0;)C++;return C-t}function s(g,t,e){for(e--;t>>1;C(I,g[n])<0?o=n:i=n+1}var r=A-i;switch(r){case 3:g[i+3]=g[i+2];case 2:g[i+2]=g[i+1];case 1:g[i+1]=g[i];break;default:for(;r>0;)g[i+r]=g[i+r-1],r--}g[i]=I}}function d(g,t,e,A,C,I){var i=0,o=0,n=1;if(I(g,t[e+C])>0){for(o=A-C;n0;)i=n,(n=1+(n<<1))<=0&&(n=o);n>o&&(n=o),i+=C,n+=C}else{for(o=C+1;no&&(n=o);var r=i;i=C-n,n=C-r}for(i++;i>>1);I(g,t[e+s])>0?i=s+1:n=s}return n}function h(g,t,e,A,C,I){var i=0,o=0,n=1;if(I(g,t[e+C])<0){for(o=C+1;no&&(n=o);var r=i;i=C-n,n=C-r}else{for(o=A-C;n=0;)i=n,(n=1+(n<<1))<=0&&(n=o);n>o&&(n=o),i+=C,n+=C}for(i++;i>>1);I(g,t[e+s])<0?n=s:i=s+1}return n}var l=function(){function g(e,I){t(this,g),this.array=null,this.compare=null,this.minGallop=A,this.length=0,this.tmpStorageLength=C,this.stackLength=0,this.runStart=null,this.runLength=null,this.stackSize=0,this.array=e,this.compare=I,this.length=e.length,this.length<2*C&&(this.tmpStorageLength=this.length>>>1),this.tmp=new Array(this.tmpStorageLength),this.stackLength=this.length<120?5:this.length<1542?10:this.length<119151?19:40,this.runStart=new Array(this.stackLength),this.runLength=new Array(this.stackLength)}return g.prototype.pushRun=function(g,t){this.runStart[this.stackSize]=g,this.runLength[this.stackSize]=t,this.stackSize+=1},g.prototype.mergeRuns=function(){for(;this.stackSize>1;){var g=this.stackSize-2;if(g>=1&&this.runLength[g-1]<=this.runLength[g]+this.runLength[g+1]||g>=2&&this.runLength[g-2]<=this.runLength[g]+this.runLength[g-1])this.runLength[g-1]this.runLength[g+1])break;this.mergeAt(g)}},g.prototype.forceMergeRuns=function(){for(;this.stackSize>1;){var g=this.stackSize-2;g>0&&this.runLength[g-1]=A||u>=A);if(p)break;l<0&&(l=0),l+=2}if(this.minGallop=l,l<1&&(this.minGallop=1),1===t){for(n=0;n=0;n--)i[c+n]=i[l+n];if(0===t){v=!0;break}}if(i[a--]=o[s--],1==--C){v=!0;break}if(0!=(f=C-d(i[r],o,0,C,C-1,I))){for(C-=f,c=1+(a-=f),l=1+(s-=f),n=0;n=A||f>=A);if(v)break;u<0&&(u=0),u+=2}if(this.minGallop=u,u<1&&(this.minGallop=1),1===C){for(c=1+(a-=t),l=1+(r-=t),n=t-1;n>=0;n--)i[c+n]=i[l+n];i[a]=o[s]}else{if(0===C)throw new Error("mergeHigh preconditions were not respected");for(l=a-(C-1),n=0;n=0;n--)i[c+n]=i[l+n];i[a]=o[s]}else for(l=a-(C-1),n=0;nd&&(h=d),a(g,A,A+h,A+i,t),i=h}s.pushRun(A,i),s.mergeRuns(),I-=i,A+=i}while(0!==I);s.forceMergeRuns()}}}}(g)}(sZ),function(g){g.exports=sZ}(rZ);var aZ=e(nZ);function dZ(g){var t=function(){if("undefined"==typeof Reflect||!yP)return!1;if(yP.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(yP(Boolean,[],(function(){}))),!0}catch(g){return!1}}();return function(){var e,A=vk(g);if(t){var C=vk(this).constructor;e=yP(A,arguments,C)}else e=A.apply(this,arguments);return hk(this,e)}}var hZ=function(){function g(){cd(this,g)}return Bh(g,[{key:"abstract",value:function(){throw new Error("Can't instantiate abstract class!")}},{key:"fake_use",value:function(){}},{key:"curveType",value:function(){return this.abstract()}},{key:"getPosition",value:function(g){return this.fake_use(g),this.abstract()}},{key:"setPosition",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;this.fake_use(g,t,e),this.abstract()}},{key:"getTreeSize",value:function(g){return this.fake_use(g),this.abstract()}},{key:"sort",value:function(g){this.fake_use(g),this.abstract()}},{key:"fix",value:function(g,t){this.fake_use(g,t),this.abstract()}},{key:"shift",value:function(g,t){this.fake_use(g,t),this.abstract()}}]),g}(),lZ=function(g){dk(e,g);var t=dZ(e);function e(g){var A;return cd(this,e),(A=t.call(this)).layout=g,A}return Bh(e,[{key:"curveType",value:function(){return"horizontal"}},{key:"getPosition",value:function(g){return g.x}},{key:"setPosition",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;void 0!==e&&this.layout.hierarchical.addToOrdering(g,e),g.x=t}},{key:"getTreeSize",value:function(g){var t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,g);return{min:t.min_x,max:t.max_x}}},{key:"sort",value:function(g){nZ.sort(g,(function(g,t){return g.x-t.x}))}},{key:"fix",value:function(g,t){g.y=this.layout.options.hierarchical.levelSeparation*t,g.options.fixed.y=!0}},{key:"shift",value:function(g,t){this.layout.body.nodes[g].x+=t}}]),e}(hZ),cZ=function(g){dk(e,g);var t=dZ(e);function e(g){var A;return cd(this,e),(A=t.call(this)).layout=g,A}return Bh(e,[{key:"curveType",value:function(){return"vertical"}},{key:"getPosition",value:function(g){return g.y}},{key:"setPosition",value:function(g,t){var e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;void 0!==e&&this.layout.hierarchical.addToOrdering(g,e),g.y=t}},{key:"getTreeSize",value:function(g){var t=this.layout.hierarchical.getTreeSize(this.layout.body.nodes,g);return{min:t.min_y,max:t.max_y}}},{key:"sort",value:function(g){nZ.sort(g,(function(g,t){return g.y-t.y}))}},{key:"fix",value:function(g,t){g.x=this.layout.options.hierarchical.levelSeparation*t,g.options.fixed.x=!0}},{key:"shift",value:function(g,t){this.layout.body.nodes[g].y+=t}}]),e}(hZ),uZ={},pZ={get exports(){return uZ},set exports(g){uZ=g}},fZ=ur.every;De({target:"Array",proto:!0,forced:!cc("every")},{every:function(g){return fZ(this,g,arguments.length>1?arguments[1]:void 0)}});var vZ=FA("Array").every,yZ=rg,mZ=vZ,bZ=Array.prototype,wZ=function(g){var t=g.every;return g===bZ||yZ(bZ,g)&&t===bZ.every?mZ:t},xZ=wZ;!function(g){g.exports=xZ}(pZ);var kZ=e(uZ);function EZ(g,t){var e=void 0!==kl&&bn(g)||g["@@iterator"];if(!e){if(Vl(g)||(e=function(g,t){var e;if(!g)return;if("string"==typeof g)return OZ(g,t);var A=Sl(e=Object.prototype.toString.call(g)).call(e,8,-1);"Object"===A&&g.constructor&&(A=g.constructor.name);if("Map"===A||"Set"===A)return Jo(g);if("Arguments"===A||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(A))return OZ(g,t)}(g))||t&&g&&"number"==typeof g.length){e&&(g=e);var A=0,C=function(){};return{s:C,n:function(){return A>=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function OZ(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e=t[A])&&(t[A]=t[e]+1)})),t}function DZ(g,t,e,A){var C,I,i=pf(null),o=iN(C=wl(QR(A).call(A))).call(C,(function(g,t){return g+1+t.edges.length}),0),n=e+"Id",r="to"===e?1:-1,s=EZ(A);try{var a=function(){var C=bl(I.value,2),s=C[0],a=C[1];if(!A.has(s)||!g(a))return"continue";i[s]=0;for(var d,h=[a],l=0,c=function(){var g,C;if(!A.has(s))return"continue";var I=i[d.id]+r;if(Ec(g=Ap(C=d.edges).call(C,(function(g){return g.connected&&g.to!==g.from&&g[e]!==d&&A.has(g.toId)&&A.has(g.fromId)}))).call(g,(function(g){var A=g[n],C=i[A];(null==C||t(I,C))&&(i[A]=I,h.push(g[e]))})),l>o)return{v:{v:TZ(A,i)}};++l};d=h.pop();){var u=c();if("continue"!==u&&"object"===kh(u))return u.v}};for(s.s();!(I=s.n()).done;){var d=a();if("continue"!==d&&"object"===kh(d))return d.v}}catch(g){s.e(g)}finally{s.f()}return i}var NZ=function(){function g(){cd(this,g),this.childrenReference={},this.parentReference={},this.trees={},this.distributionOrdering={},this.levels={},this.distributionIndex={},this.isTree=!1,this.treeIndex=-1}return Bh(g,[{key:"addRelation",value:function(g,t){void 0===this.childrenReference[g]&&(this.childrenReference[g]=[]),this.childrenReference[g].push(t),void 0===this.parentReference[t]&&(this.parentReference[t]=[]),this.parentReference[t].push(g)}},{key:"checkIfTree",value:function(){for(var g in this.parentReference)if(this.parentReference[g].length>1)return void(this.isTree=!1);this.isTree=!0}},{key:"numTrees",value:function(){return this.treeIndex+1}},{key:"setTreeIndex",value:function(g,t){void 0!==t&&void 0===this.trees[g.id]&&(this.trees[g.id]=t,this.treeIndex=Math.max(t,this.treeIndex))}},{key:"ensureLevel",value:function(g){void 0===this.levels[g]&&(this.levels[g]=0)}},{key:"getMaxLevel",value:function(g){var t=this,e={};return function g(A){if(void 0!==e[A])return e[A];var C=t.levels[A];if(t.childrenReference[A]){var I=t.childrenReference[A];if(I.length>0)for(var i=0;i0&&(e.levelSeparation*=-1):e.levelSeparation<0&&(e.levelSeparation*=-1),this.setDirectionStrategy(),this.body.emitter.emit("_resetHierarchicalLayout"),this.adaptAllOptionsForHierarchicalLayout(t);if(!0===A)return this.body.emitter.emit("refresh"),Fm(t,this.optionsBackup)}return t}},{key:"_resetRNG",value:function(g){this.initialRandomSeed=g,this._rng=xm(this.initialRandomSeed)}},{key:"adaptAllOptionsForHierarchicalLayout",value:function(g){if(!0===this.options.hierarchical.enabled){var t=this.optionsBackup.physics;void 0===g.physics||!0===g.physics?(g.physics={enabled:void 0===t.enabled||t.enabled,solver:"hierarchicalRepulsion"},t.enabled=void 0===t.enabled||t.enabled,t.solver=t.solver||"barnesHut"):"object"===kh(g.physics)?(t.enabled=void 0===g.physics.enabled||g.physics.enabled,t.solver=g.physics.solver||"barnesHut",g.physics.solver="hierarchicalRepulsion"):!1!==g.physics&&(t.solver="barnesHut",g.physics={solver:"hierarchicalRepulsion"});var e=this.direction.curveType();if(void 0===g.edges)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},g.edges={smooth:!1};else if(void 0===g.edges.smooth)this.optionsBackup.edges={smooth:{enabled:!0,type:"dynamic"}},g.edges.smooth=!1;else if("boolean"==typeof g.edges.smooth)this.optionsBackup.edges={smooth:g.edges.smooth},g.edges.smooth={enabled:g.edges.smooth,type:e};else{var A=g.edges.smooth;void 0!==A.type&&"dynamic"!==A.type&&(e=A.type),this.optionsBackup.edges={smooth:{enabled:void 0===A.enabled||A.enabled,type:void 0===A.type?"dynamic":A.type,roundness:void 0===A.roundness?.5:A.roundness,forceDirection:void 0!==A.forceDirection&&A.forceDirection}},g.edges.smooth={enabled:void 0===A.enabled||A.enabled,type:e,roundness:void 0===A.roundness?.5:A.roundness,forceDirection:void 0!==A.forceDirection&&A.forceDirection}}this.body.emitter.emit("_forceDisableDynamicCurves",e)}return g}},{key:"positionInitially",value:function(g){if(!0!==this.options.hierarchical.enabled){this._resetRNG(this.initialRandomSeed);for(var t=g.length+50,e=0;eC){for(var i=g.length;g.length>C&&A<=10;){A+=1;var o=g.length;if(A%3==0?this.body.modules.clustering.clusterBridges(I):this.body.modules.clustering.clusterOutliers(I),o==g.length&&A%3!=0)return this._declusterAll(),this.body.emitter.emit("_layoutFailed"),void console.info("This network could not be positioned by this version of the improved layout algorithm. Please disable improvedLayout for better performance.")}this.body.modules.kamadaKawai.setOptions({springLength:Math.max(150,2*i)})}A>10&&console.info("The clustering didn't succeed within the amount of interations allowed, progressing with partial result."),this.body.modules.kamadaKawai.solve(g,this.body.edgeIndices,!0),this._shiftToCenter();for(var n=0;n0){var g,t,e=!1,A=!1;for(t in this.lastNodeOnLevel={},this.hierarchical=new NZ,this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,t)&&(void 0!==(g=this.body.nodes[t]).options.level?(e=!0,this.hierarchical.levels[t]=g.options.level):A=!0);if(!0===A&&!0===e)throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");if(!0===A){var C=this.options.hierarchical.sortMethod;"hubsize"===C?this._determineLevelsByHubsize():"directed"===C?this._determineLevelsDirected():"custom"===C&&this._determineLevelsCustomCallback()}for(var I in this.body.nodes)Object.prototype.hasOwnProperty.call(this.body.nodes,I)&&this.hierarchical.ensureLevel(I);var i=this._getDistribution();this._generateMap(),this._placeNodesByHierarchy(i),this._condenseHierarchy(),this._shiftToCenter()}}},{key:"_condenseHierarchy",value:function(){var g=this,t=!1,e={},A=function(t,e){var A=g.hierarchical.trees;for(var C in A)Object.prototype.hasOwnProperty.call(A,C)&&A[C]===t&&g.direction.shift(C,e)},C=function(){for(var t=[],e=0;e0)for(var I=0;I1&&void 0!==arguments[1]?arguments[1]:1e9,A=1e9,C=1e9,I=1e9,i=-1e9;for(var o in t)if(Object.prototype.hasOwnProperty.call(t,o)){var n=g.body.nodes[o],r=g.hierarchical.levels[n.id],s=g.direction.getPosition(n),a=bl(g._getSpaceAroundNode(n,t),2),d=a[0],h=a[1];A=Math.min(d,A),C=Math.min(h,C),r<=e&&(I=Math.min(s,I),i=Math.max(s,i))}return[I,i,A,C]},o=function(t,e){var A=g.hierarchical.getMaxLevel(t.id),C=g.hierarchical.getMaxLevel(e.id);return Math.min(A,C)},n=function(t,e,A){for(var C=g.hierarchical,I=0;I1)for(var n=0;n2&&void 0!==arguments[2]&&arguments[2],n=g.direction.getPosition(e),r=g.direction.getPosition(A),s=Math.abs(r-n),a=g.options.hierarchical.nodeSpacing;if(s>a){var d={},h={};I(e,d),I(A,h);var l=o(e,A),c=i(d,l),u=i(h,l),p=c[1],f=u[0],v=u[2];if(Math.abs(p-f)>a){var y=p-f+a;y<-v+a&&(y=-v+a),y<0&&(g._shiftBlock(A.id,y),t=!0,!0===C&&g._centerParent(A))}}},s=function(A,C){for(var o=C.id,n=C.edges,r=g.hierarchical.levels[C.id],s=g.options.hierarchical.levelSeparation*g.options.hierarchical.levelSeparation,a={},d=[],h=0;h0?h=Math.min(d,a-g.options.hierarchical.nodeSpacing):d<0&&(h=-Math.min(-d,s-g.options.hierarchical.nodeSpacing)),0!=h&&(g._shiftBlock(C.id,h),t=!0)}(v),function(e){var A=g.direction.getPosition(C),I=bl(g._getSpaceAroundNode(C),2),i=I[0],o=I[1],n=e-A,r=A;n>0?r=Math.min(A+(o-g.options.hierarchical.nodeSpacing),e):n<0&&(r=Math.max(A-(i-g.options.hierarchical.nodeSpacing),e)),r!==A&&(g.direction.setPosition(C,r),t=!0)}(v=f(A,n))};!0===this.options.hierarchical.blockShifting&&(function(e){var A=g.hierarchical.getLevels();A=Gc(A).call(A);for(var C=0;C0&&Math.abs(a)0&&(n=this.direction.getPosition(A[I-1])+o),this.direction.setPosition(i,n,t),this._validatePositionAndContinue(i,t,n),C++}}}}},{key:"_placeBranchNodes",value:function(g,t){var e,A=this.hierarchical.childrenReference[g];if(void 0!==A){for(var C=[],I=0;It&&void 0===this.positionedNodes[o.id]))return;var r=this.options.hierarchical.nodeSpacing,s=void 0;s=0===i?this.direction.getPosition(this.body.nodes[g]):this.direction.getPosition(C[i-1])+r,this.direction.setPosition(o,s,n),this._validatePositionAndContinue(o,n,s)}var a=this._getCenterPosition(C);this.direction.setPosition(this.body.nodes[g],a,t)}}},{key:"_validatePositionAndContinue",value:function(g,t,e){if(this.hierarchical.isTree){if(void 0!==this.lastNodeOnLevel[t]){var A=this.direction.getPosition(this.body.nodes[this.lastNodeOnLevel[t]]);if(e-Ag}),"from",g)}(e),this.hierarchical.setMinLevelToZero(this.body.nodes)}},{key:"_generateMap",value:function(){var g=this;this._crawlNetwork((function(t,e){g.hierarchical.levels[e.id]>g.hierarchical.levels[t.id]&&g.hierarchical.addRelation(t.id,e.id)})),this.hierarchical.checkIfTree()}},{key:"_crawlNetwork",value:function(){var g=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){},e=arguments.length>1?arguments[1]:void 0,A={},C=function e(C,I){if(void 0===A[C.id]){var i;g.hierarchical.setTreeIndex(C,I),A[C.id]=!0;for(var o=g._getActiveEdges(C),n=0;n=g.length?{done:!0}:{done:!1,value:g[A++]}},e:function(g){throw g},f:C}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var I,i=!0,o=!1;return{s:function(){e=e.call(g)},n:function(){var g=e.next();return i=g.done,g},e:function(g){o=!0,I=g},f:function(){try{i||null==e.return||e.return()}finally{if(o)throw I}}}}function MZ(g,t){(null==t||t>g.length)&&(t=g.length);for(var e=0,A=new Array(t);e0&&!1!==this.options.deleteNode||0===e&&!1!==this.options.deleteEdge)&&(!0===i&&this._createSeperator(4),this._createDeleteButton(I)),this._bindElementEvents(this.closeDiv,QA(g=this.toggleEditMode).call(g,this)),this._temporaryBindEvent("select",QA(t=this.showManipulatorToolbar).call(t,this))}this.body.emitter.emit("_redraw")}},{key:"addNodeMode",value:function(){var g;if(!0!==this.editMode&&this.enableEditMode(),this._clean(),this.inMode="addNode",!0===this.guiEnabled){var t,e=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(e),this._createSeperator(),this._createDescription(e.addDescription||this.options.locales.en.addDescription),this._bindElementEvents(this.closeDiv,QA(t=this.toggleEditMode).call(t,this))}this._temporaryBindEvent("click",QA(g=this._performAddNode).call(g,this))}},{key:"editNode",value:function(){var g=this;!0!==this.editMode&&this.enableEditMode(),this._clean();var t=this.selectionHandler.getSelectedNodes()[0];if(void 0!==t){if(this.inMode="editNode","function"!=typeof this.options.editNode)throw new Error("No function has been configured to handle the editing of nodes.");if(!0!==t.isCluster){var e=Fm({},t.options,!1);if(e.x=t.x,e.y=t.y,2!==this.options.editNode.length)throw new Error("The function for edit does not support two arguments (data, callback)");this.options.editNode(e,(function(t){null!=t&&"editNode"===g.inMode&&g.body.data.nodes.getDataSet().update(t),g.showManipulatorToolbar()}))}else alert(this.options.locales[this.options.locale].editClusterError||this.options.locales.en.editClusterError)}else this.showManipulatorToolbar()}},{key:"addEdgeMode",value:function(){var g,t,e,A,C;if(!0!==this.editMode&&this.enableEditMode(),this._clean(),this.inMode="addEdge",!0===this.guiEnabled){var I,i=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(i),this._createSeperator(),this._createDescription(i.edgeDescription||this.options.locales.en.edgeDescription),this._bindElementEvents(this.closeDiv,QA(I=this.toggleEditMode).call(I,this))}this._temporaryBindUI("onTouch",QA(g=this._handleConnect).call(g,this)),this._temporaryBindUI("onDragEnd",QA(t=this._finishConnect).call(t,this)),this._temporaryBindUI("onDrag",QA(e=this._dragControlNode).call(e,this)),this._temporaryBindUI("onRelease",QA(A=this._finishConnect).call(A,this)),this._temporaryBindUI("onDragStart",QA(C=this._dragStartEdge).call(C,this)),this._temporaryBindUI("onHold",(function(){}))}},{key:"editEdgeMode",value:function(){if(!0!==this.editMode&&this.enableEditMode(),this._clean(),this.inMode="editEdge","object"!==kh(this.options.editEdge)||"function"!=typeof this.options.editEdge.editWithoutDrag||(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],void 0===this.edgeBeingEditedId)){if(!0===this.guiEnabled){var g,t=this.options.locales[this.options.locale];this.manipulationDOM={},this._createBackButton(t),this._createSeperator(),this._createDescription(t.editEdgeDescription||this.options.locales.en.editEdgeDescription),this._bindElementEvents(this.closeDiv,QA(g=this.toggleEditMode).call(g,this))}if(this.edgeBeingEditedId=this.selectionHandler.getSelectedEdgeIds()[0],void 0!==this.edgeBeingEditedId){var e,A,C,I,i=this.body.edges[this.edgeBeingEditedId],o=this._getNewTargetNode(i.from.x,i.from.y),n=this._getNewTargetNode(i.to.x,i.to.y);this.temporaryIds.nodes.push(o.id),this.temporaryIds.nodes.push(n.id),this.body.nodes[o.id]=o,this.body.nodeIndices.push(o.id),this.body.nodes[n.id]=n,this.body.nodeIndices.push(n.id),this._temporaryBindUI("onTouch",QA(e=this._controlNodeTouch).call(e,this)),this._temporaryBindUI("onTap",(function(){})),this._temporaryBindUI("onHold",(function(){})),this._temporaryBindUI("onDragStart",QA(A=this._controlNodeDragStart).call(A,this)),this._temporaryBindUI("onDrag",QA(C=this._controlNodeDrag).call(C,this)),this._temporaryBindUI("onDragEnd",QA(I=this._controlNodeDragEnd).call(I,this)),this._temporaryBindUI("onMouseMove",(function(){})),this._temporaryBindEvent("beforeDrawing",(function(g){var t=i.edgeType.findBorderPositions(g);!1===o.selected&&(o.x=t.from.x,o.y=t.from.y),!1===n.selected&&(n.x=t.to.x,n.y=t.to.y)})),this.body.emitter.emit("_redraw")}else this.showManipulatorToolbar()}else{var r=this.body.edges[this.edgeBeingEditedId];this._performEditEdge(r.from.id,r.to.id)}}},{key:"deleteSelected",value:function(){var g=this;!0!==this.editMode&&this.enableEditMode(),this._clean(),this.inMode="delete";var t=this.selectionHandler.getSelectedNodeIds(),e=this.selectionHandler.getSelectedEdgeIds(),A=void 0;if(t.length>0){for(var C=0;C0&&"function"==typeof this.options.deleteEdge&&(A=this.options.deleteEdge);if("function"==typeof A){var I={nodes:t,edges:e};if(2!==A.length)throw new Error("The function for delete does not support two arguments (data, callback)");A(I,(function(t){null!=t&&"delete"===g.inMode?(g.body.data.edges.getDataSet().remove(t.edges),g.body.data.nodes.getDataSet().remove(t.nodes),g.body.emitter.emit("startSimulation"),g.showManipulatorToolbar()):(g.body.emitter.emit("startSimulation"),g.showManipulatorToolbar())}))}else this.body.data.edges.getDataSet().remove(e),this.body.data.nodes.getDataSet().remove(t),this.body.emitter.emit("startSimulation"),this.showManipulatorToolbar()}},{key:"_setup",value:function(){!0===this.options.enabled?(this.guiEnabled=!0,this._createWrappers(),!1===this.editMode?this._createEditButton():this.showManipulatorToolbar()):(this._removeManipulationDOM(),this.guiEnabled=!1)}},{key:"_createWrappers",value:function(){var g,t;(void 0===this.manipulationDiv&&(this.manipulationDiv=document.createElement("div"),this.manipulationDiv.className="vis-manipulation",!0===this.editMode?this.manipulationDiv.style.display="block":this.manipulationDiv.style.display="none",this.canvas.frame.appendChild(this.manipulationDiv)),void 0===this.editModeDiv&&(this.editModeDiv=document.createElement("div"),this.editModeDiv.className="vis-edit-mode",!0===this.editMode?this.editModeDiv.style.display="none":this.editModeDiv.style.display="block",this.canvas.frame.appendChild(this.editModeDiv)),void 0===this.closeDiv)&&(this.closeDiv=document.createElement("button"),this.closeDiv.className="vis-close",this.closeDiv.setAttribute("aria-label",null!==(g=null===(t=this.options.locales[this.options.locale])||void 0===t?void 0:t.close)&&void 0!==g?g:this.options.locales.en.close),this.closeDiv.style.display=this.manipulationDiv.style.display,this.canvas.frame.appendChild(this.closeDiv))}},{key:"_getNewTargetNode",value:function(g,t){var e=Fm({},this.options.controlNodeStyle);e.id="targetNode"+OP(),e.hidden=!1,e.physics=!1,e.x=g,e.y=t;var A=this.body.functions.createNode(e);return A.shape.boundingBox={left:g,right:g,top:t,bottom:t},A}},{key:"_createEditButton",value:function(){var g;this._clean(),this.manipulationDOM={},Rm(this.editModeDiv);var t=this.options.locales[this.options.locale],e=this._createButton("editMode","vis-edit vis-edit-mode",t.edit||this.options.locales.en.edit);this.editModeDiv.appendChild(e),this._bindElementEvents(e,QA(g=this.toggleEditMode).call(g,this))}},{key:"_clean",value:function(){this.inMode=!1,!0===this.guiEnabled&&(Rm(this.editModeDiv),Rm(this.manipulationDiv),this._cleanupDOMEventListeners()),this._cleanupTemporaryNodesAndEdges(),this._unbindTemporaryUIs(),this._unbindTemporaryEvents(),this.body.emitter.emit("restorePhysics")}},{key:"_cleanupDOMEventListeners",value:function(){var g,t,e=PZ(cu(g=this._domEventListenerCleanupQueue).call(g,0));try{for(e.s();!(t=e.n()).done;){(0,t.value)()}}catch(g){e.e(g)}finally{e.f()}}},{key:"_removeManipulationDOM",value:function(){this._clean(),Rm(this.manipulationDiv),Rm(this.editModeDiv),Rm(this.closeDiv),this.manipulationDiv&&this.canvas.frame.removeChild(this.manipulationDiv),this.editModeDiv&&this.canvas.frame.removeChild(this.editModeDiv),this.closeDiv&&this.canvas.frame.removeChild(this.closeDiv),this.manipulationDiv=void 0,this.editModeDiv=void 0,this.closeDiv=void 0}},{key:"_createSeperator",value:function(){var g=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.manipulationDOM["seperatorLineDiv"+g]=document.createElement("div"),this.manipulationDOM["seperatorLineDiv"+g].className="vis-separator-line",this.manipulationDiv.appendChild(this.manipulationDOM["seperatorLineDiv"+g])}},{key:"_createAddNodeButton",value:function(g){var t,e=this._createButton("addNode","vis-add",g.addNode||this.options.locales.en.addNode);this.manipulationDiv.appendChild(e),this._bindElementEvents(e,QA(t=this.addNodeMode).call(t,this))}},{key:"_createAddEdgeButton",value:function(g){var t,e=this._createButton("addEdge","vis-connect",g.addEdge||this.options.locales.en.addEdge);this.manipulationDiv.appendChild(e),this._bindElementEvents(e,QA(t=this.addEdgeMode).call(t,this))}},{key:"_createEditNodeButton",value:function(g){var t,e=this._createButton("editNode","vis-edit",g.editNode||this.options.locales.en.editNode);this.manipulationDiv.appendChild(e),this._bindElementEvents(e,QA(t=this.editNode).call(t,this))}},{key:"_createEditEdgeButton",value:function(g){var t,e=this._createButton("editEdge","vis-edit",g.editEdge||this.options.locales.en.editEdge);this.manipulationDiv.appendChild(e),this._bindElementEvents(e,QA(t=this.editEdgeMode).call(t,this))}},{key:"_createDeleteButton",value:function(g){var t,e;e=this.options.rtl?"vis-delete-rtl":"vis-delete";var A=this._createButton("delete",e,g.del||this.options.locales.en.del);this.manipulationDiv.appendChild(A),this._bindElementEvents(A,QA(t=this.deleteSelected).call(t,this))}},{key:"_createBackButton",value:function(g){var t,e=this._createButton("back","vis-back",g.back||this.options.locales.en.back);this.manipulationDiv.appendChild(e),this._bindElementEvents(e,QA(t=this.showManipulatorToolbar).call(t,this))}},{key:"_createButton",value:function(g,t,e){var A=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"vis-label";return this.manipulationDOM[g+"Div"]=document.createElement("button"),this.manipulationDOM[g+"Div"].className="vis-button "+t,this.manipulationDOM[g+"Label"]=document.createElement("div"),this.manipulationDOM[g+"Label"].className=A,this.manipulationDOM[g+"Label"].innerText=e,this.manipulationDOM[g+"Div"].appendChild(this.manipulationDOM[g+"Label"]),this.manipulationDOM[g+"Div"]}},{key:"_createDescription",value:function(g){this.manipulationDOM.descriptionLabel=document.createElement("div"),this.manipulationDOM.descriptionLabel.className="vis-none",this.manipulationDOM.descriptionLabel.innerText=g,this.manipulationDiv.appendChild(this.manipulationDOM.descriptionLabel)}},{key:"_temporaryBindEvent",value:function(g,t){this.temporaryEventFunctions.push({event:g,boundFunction:t}),this.body.emitter.on(g,t)}},{key:"_temporaryBindUI",value:function(g,t){if(void 0===this.body.eventListeners[g])throw new Error("This UI function does not exist. Typo? You tried: "+g+" possible are: "+xf(Cc(this.body.eventListeners)));this.temporaryUIFunctions[g]=this.body.eventListeners[g],this.body.eventListeners[g]=t}},{key:"_unbindTemporaryUIs",value:function(){for(var g in this.temporaryUIFunctions)Object.prototype.hasOwnProperty.call(this.temporaryUIFunctions,g)&&(this.body.eventListeners[g]=this.temporaryUIFunctions[g],delete this.temporaryUIFunctions[g]);this.temporaryUIFunctions={}}},{key:"_unbindTemporaryEvents",value:function(){for(var g=0;g=0;i--)if(C[i]!==this.selectedControlNode.id){I=this.body.nodes[C[i]];break}if(void 0!==I&&void 0!==this.selectedControlNode)if(!0===I.isCluster)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{var o=this.body.nodes[this.temporaryIds.nodes[0]];this.selectedControlNode.id===o.id?this._performEditEdge(I.id,A.to.id):this._performEditEdge(A.from.id,I.id)}else A.updateEdgeType(),this.body.emitter.emit("restorePhysics");this.body.emitter.emit("_redraw")}}},{key:"_handleConnect",value:function(g){if((new Date).valueOf()-this.touchTime>100){this.lastTouch=this.body.functions.getPointer(g.center),this.lastTouch.translation=yA({},this.body.view.translation),this.interactionHandler.drag.pointer=this.lastTouch,this.interactionHandler.drag.translation=this.lastTouch.translation;var t=this.lastTouch,e=this.selectionHandler.getNodeAt(t);if(void 0!==e)if(!0===e.isCluster)alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError);else{var A=this._getNewTargetNode(e.x,e.y);this.body.nodes[A.id]=A,this.body.nodeIndices.push(A.id);var C=this.body.functions.createEdge({id:"connectionEdge"+OP(),from:e.id,to:A.id,physics:!1,smooth:{enabled:!0,type:"continuous",roundness:.5}});this.body.edges[C.id]=C,this.body.edgeIndices.push(C.id),this.temporaryIds.nodes.push(A.id),this.temporaryIds.edges.push(C.id)}this.touchTime=(new Date).valueOf()}}},{key:"_dragControlNode",value:function(g){var t=this.body.functions.getPointer(g.center),e=this.selectionHandler._pointerToPositionObject(t),A=void 0;void 0!==this.temporaryIds.edges[0]&&(A=this.body.edges[this.temporaryIds.edges[0]].fromId);for(var C=this.selectionHandler._getAllNodesOverlappingWith(e),I=void 0,i=C.length-1;i>=0;i--){var o;if(-1===$p(o=this.temporaryIds.nodes).call(o,C[i])){I=this.body.nodes[C[i]];break}}if(g.controlEdge={from:A,to:I?I.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragging",g,t),void 0!==this.temporaryIds.nodes[0]){var n=this.body.nodes[this.temporaryIds.nodes[0]];n.x=this.canvas._XconvertDOMtoCanvas(t.x),n.y=this.canvas._YconvertDOMtoCanvas(t.y),this.body.emitter.emit("_redraw")}else this.interactionHandler.onDrag(g)}},{key:"_finishConnect",value:function(g){var t=this.body.functions.getPointer(g.center),e=this.selectionHandler._pointerToPositionObject(t),A=void 0;void 0!==this.temporaryIds.edges[0]&&(A=this.body.edges[this.temporaryIds.edges[0]].fromId);for(var C=this.selectionHandler._getAllNodesOverlappingWith(e),I=void 0,i=C.length-1;i>=0;i--){var o;if(-1===$p(o=this.temporaryIds.nodes).call(o,C[i])){I=this.body.nodes[C[i]];break}}this._cleanupTemporaryNodesAndEdges(),void 0!==I&&(!0===I.isCluster?alert(this.options.locales[this.options.locale].createEdgeError||this.options.locales.en.createEdgeError):void 0!==this.body.nodes[A]&&void 0!==this.body.nodes[I.id]&&this._performAddEdge(A,I.id)),g.controlEdge={from:A,to:I?I.id:void 0},this.selectionHandler.generateClickEvent("controlNodeDragEnd",g,t),this.body.emitter.emit("_redraw")}},{key:"_dragStartEdge",value:function(g){var t=this.lastTouch;this.selectionHandler.generateClickEvent("dragStart",g,t,void 0,!0)}},{key:"_performAddNode",value:function(g){var t=this,e={id:OP(),x:g.pointer.canvas.x,y:g.pointer.canvas.y,label:"new"};if("function"==typeof this.options.addNode){if(2!==this.options.addNode.length)throw this.showManipulatorToolbar(),new Error("The function for add does not support two arguments (data,callback)");this.options.addNode(e,(function(g){null!=g&&"addNode"===t.inMode&&t.body.data.nodes.getDataSet().add(g),t.showManipulatorToolbar()}))}else this.body.data.nodes.getDataSet().add(e),this.showManipulatorToolbar()}},{key:"_performAddEdge",value:function(g,t){var e=this,A={from:g,to:t};if("function"==typeof this.options.addEdge){if(2!==this.options.addEdge.length)throw new Error("The function for connect does not support two arguments (data,callback)");this.options.addEdge(A,(function(g){null!=g&&"addEdge"===e.inMode&&(e.body.data.edges.getDataSet().add(g),e.selectionHandler.unselectAll(),e.showManipulatorToolbar())}))}else this.body.data.edges.getDataSet().add(A),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}},{key:"_performEditEdge",value:function(g,t){var e=this,A={id:this.edgeBeingEditedId,from:g,to:t,label:this.body.data.edges.get(this.edgeBeingEditedId).label},C=this.options.editEdge;if("object"===kh(C)&&(C=C.editWithoutDrag),"function"==typeof C){if(2!==C.length)throw new Error("The function for edit does not support two arguments (data, callback)");C(A,(function(g){null==g||"editEdge"!==e.inMode?(e.body.edges[A.id].updateEdgeType(),e.body.emitter.emit("_redraw"),e.showManipulatorToolbar()):(e.body.data.edges.getDataSet().update(g),e.selectionHandler.unselectAll(),e.showManipulatorToolbar())}))}else this.body.data.edges.getDataSet().update(A),this.selectionHandler.unselectAll(),this.showManipulatorToolbar()}}]),g}(),zZ="string",SZ="boolean",ZZ="number",FZ="array",GZ="object",jZ=["arrow","bar","box","circle","crow","curve","diamond","image","inv_curve","inv_triangle","triangle","vee"],LZ={borderWidth:{number:ZZ},borderWidthSelected:{number:ZZ,undefined:"undefined"},brokenImage:{string:zZ,undefined:"undefined"},chosen:{label:{boolean:SZ,function:"function"},node:{boolean:SZ,function:"function"},__type__:{object:GZ,boolean:SZ}},color:{border:{string:zZ},background:{string:zZ},highlight:{border:{string:zZ},background:{string:zZ},__type__:{object:GZ,string:zZ}},hover:{border:{string:zZ},background:{string:zZ},__type__:{object:GZ,string:zZ}},__type__:{object:GZ,string:zZ}},opacity:{number:ZZ,undefined:"undefined"},fixed:{x:{boolean:SZ},y:{boolean:SZ},__type__:{object:GZ,boolean:SZ}},font:{align:{string:zZ},color:{string:zZ},size:{number:ZZ},face:{string:zZ},background:{string:zZ},strokeWidth:{number:ZZ},strokeColor:{string:zZ},vadjust:{number:ZZ},multi:{boolean:SZ,string:zZ},bold:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},boldital:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},ital:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},mono:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},__type__:{object:GZ,string:zZ}},group:{string:zZ,number:ZZ,undefined:"undefined"},heightConstraint:{minimum:{number:ZZ},valign:{string:zZ},__type__:{object:GZ,boolean:SZ,number:ZZ}},hidden:{boolean:SZ},icon:{face:{string:zZ},code:{string:zZ},size:{number:ZZ},color:{string:zZ},weight:{string:zZ,number:ZZ},__type__:{object:GZ}},id:{string:zZ,number:ZZ},image:{selected:{string:zZ,undefined:"undefined"},unselected:{string:zZ,undefined:"undefined"},__type__:{object:GZ,string:zZ}},imagePadding:{top:{number:ZZ},right:{number:ZZ},bottom:{number:ZZ},left:{number:ZZ},__type__:{object:GZ,number:ZZ}},label:{string:zZ,undefined:"undefined"},labelHighlightBold:{boolean:SZ},level:{number:ZZ,undefined:"undefined"},margin:{top:{number:ZZ},right:{number:ZZ},bottom:{number:ZZ},left:{number:ZZ},__type__:{object:GZ,number:ZZ}},mass:{number:ZZ},physics:{boolean:SZ},scaling:{min:{number:ZZ},max:{number:ZZ},label:{enabled:{boolean:SZ},min:{number:ZZ},max:{number:ZZ},maxVisible:{number:ZZ},drawThreshold:{number:ZZ},__type__:{object:GZ,boolean:SZ}},customScalingFunction:{function:"function"},__type__:{object:GZ}},shadow:{enabled:{boolean:SZ},color:{string:zZ},size:{number:ZZ},x:{number:ZZ},y:{number:ZZ},__type__:{object:GZ,boolean:SZ}},shape:{string:["custom","ellipse","circle","database","box","text","image","circularImage","diamond","dot","star","triangle","triangleDown","square","icon","hexagon"]},ctxRenderer:{function:"function"},shapeProperties:{borderDashes:{boolean:SZ,array:FZ},borderRadius:{number:ZZ},interpolation:{boolean:SZ},useImageSize:{boolean:SZ},useBorderWithImage:{boolean:SZ},coordinateOrigin:{string:["center","top-left"]},__type__:{object:GZ}},size:{number:ZZ},title:{string:zZ,dom:"dom",undefined:"undefined"},value:{number:ZZ,undefined:"undefined"},widthConstraint:{minimum:{number:ZZ},maximum:{number:ZZ},__type__:{object:GZ,boolean:SZ,number:ZZ}},x:{number:ZZ},y:{number:ZZ},__type__:{object:GZ}},VZ={configure:{enabled:{boolean:SZ},filter:{boolean:SZ,string:zZ,array:FZ,function:"function"},container:{dom:"dom"},showButton:{boolean:SZ},__type__:{object:GZ,boolean:SZ,string:zZ,array:FZ,function:"function"}},edges:{arrows:{to:{enabled:{boolean:SZ},scaleFactor:{number:ZZ},type:{string:jZ},imageHeight:{number:ZZ},imageWidth:{number:ZZ},src:{string:zZ},__type__:{object:GZ,boolean:SZ}},middle:{enabled:{boolean:SZ},scaleFactor:{number:ZZ},type:{string:jZ},imageWidth:{number:ZZ},imageHeight:{number:ZZ},src:{string:zZ},__type__:{object:GZ,boolean:SZ}},from:{enabled:{boolean:SZ},scaleFactor:{number:ZZ},type:{string:jZ},imageWidth:{number:ZZ},imageHeight:{number:ZZ},src:{string:zZ},__type__:{object:GZ,boolean:SZ}},__type__:{string:["from","to","middle"],object:GZ}},endPointOffset:{from:{number:ZZ},to:{number:ZZ},__type__:{object:GZ,number:ZZ}},arrowStrikethrough:{boolean:SZ},background:{enabled:{boolean:SZ},color:{string:zZ},size:{number:ZZ},dashes:{boolean:SZ,array:FZ},__type__:{object:GZ,boolean:SZ}},chosen:{label:{boolean:SZ,function:"function"},edge:{boolean:SZ,function:"function"},__type__:{object:GZ,boolean:SZ}},color:{color:{string:zZ},highlight:{string:zZ},hover:{string:zZ},inherit:{string:["from","to","both"],boolean:SZ},opacity:{number:ZZ},__type__:{object:GZ,string:zZ}},dashes:{boolean:SZ,array:FZ},font:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},background:{string:zZ},strokeWidth:{number:ZZ},strokeColor:{string:zZ},align:{string:["horizontal","top","middle","bottom"]},vadjust:{number:ZZ},multi:{boolean:SZ,string:zZ},bold:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},boldital:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},ital:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},mono:{color:{string:zZ},size:{number:ZZ},face:{string:zZ},mod:{string:zZ},vadjust:{number:ZZ},__type__:{object:GZ,string:zZ}},__type__:{object:GZ,string:zZ}},hidden:{boolean:SZ},hoverWidth:{function:"function",number:ZZ},label:{string:zZ,undefined:"undefined"},labelHighlightBold:{boolean:SZ},length:{number:ZZ,undefined:"undefined"},physics:{boolean:SZ},scaling:{min:{number:ZZ},max:{number:ZZ},label:{enabled:{boolean:SZ},min:{number:ZZ},max:{number:ZZ},maxVisible:{number:ZZ},drawThreshold:{number:ZZ},__type__:{object:GZ,boolean:SZ}},customScalingFunction:{function:"function"},__type__:{object:GZ}},selectionWidth:{function:"function",number:ZZ},selfReferenceSize:{number:ZZ},selfReference:{size:{number:ZZ},angle:{number:ZZ},renderBehindTheNode:{boolean:SZ},__type__:{object:GZ}},shadow:{enabled:{boolean:SZ},color:{string:zZ},size:{number:ZZ},x:{number:ZZ},y:{number:ZZ},__type__:{object:GZ,boolean:SZ}},smooth:{enabled:{boolean:SZ},type:{string:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"]},roundness:{number:ZZ},forceDirection:{string:["horizontal","vertical","none"],boolean:SZ},__type__:{object:GZ,boolean:SZ}},title:{string:zZ,undefined:"undefined"},width:{number:ZZ},widthConstraint:{maximum:{number:ZZ},__type__:{object:GZ,boolean:SZ,number:ZZ}},value:{number:ZZ,undefined:"undefined"},__type__:{object:GZ}},groups:{useDefaultGroups:{boolean:SZ},__any__:LZ,__type__:{object:GZ}},interaction:{dragNodes:{boolean:SZ},dragView:{boolean:SZ},hideEdgesOnDrag:{boolean:SZ},hideEdgesOnZoom:{boolean:SZ},hideNodesOnDrag:{boolean:SZ},hover:{boolean:SZ},keyboard:{enabled:{boolean:SZ},speed:{x:{number:ZZ},y:{number:ZZ},zoom:{number:ZZ},__type__:{object:GZ}},bindToWindow:{boolean:SZ},autoFocus:{boolean:SZ},__type__:{object:GZ,boolean:SZ}},multiselect:{boolean:SZ},navigationButtons:{boolean:SZ},selectable:{boolean:SZ},selectConnectedEdges:{boolean:SZ},hoverConnectedEdges:{boolean:SZ},tooltipDelay:{number:ZZ},zoomView:{boolean:SZ},zoomSpeed:{number:ZZ},__type__:{object:GZ}},layout:{randomSeed:{undefined:"undefined",number:ZZ,string:zZ},improvedLayout:{boolean:SZ},clusterThreshold:{number:ZZ},hierarchical:{enabled:{boolean:SZ},levelSeparation:{number:ZZ},nodeSpacing:{number:ZZ},treeSpacing:{number:ZZ},blockShifting:{boolean:SZ},edgeMinimization:{boolean:SZ},parentCentralization:{boolean:SZ},direction:{string:["UD","DU","LR","RL"]},sortMethod:{string:["hubsize","directed"]},shakeTowards:{string:["leaves","roots"]},__type__:{object:GZ,boolean:SZ}},__type__:{object:GZ}},manipulation:{enabled:{boolean:SZ},initiallyActive:{boolean:SZ},addNode:{boolean:SZ,function:"function"},addEdge:{boolean:SZ,function:"function"},editNode:{function:"function"},editEdge:{editWithoutDrag:{function:"function"},__type__:{object:GZ,boolean:SZ,function:"function"}},deleteNode:{boolean:SZ,function:"function"},deleteEdge:{boolean:SZ,function:"function"},controlNodeStyle:LZ,__type__:{object:GZ,boolean:SZ}},nodes:LZ,physics:{enabled:{boolean:SZ},barnesHut:{theta:{number:ZZ},gravitationalConstant:{number:ZZ},centralGravity:{number:ZZ},springLength:{number:ZZ},springConstant:{number:ZZ},damping:{number:ZZ},avoidOverlap:{number:ZZ},__type__:{object:GZ}},forceAtlas2Based:{theta:{number:ZZ},gravitationalConstant:{number:ZZ},centralGravity:{number:ZZ},springLength:{number:ZZ},springConstant:{number:ZZ},damping:{number:ZZ},avoidOverlap:{number:ZZ},__type__:{object:GZ}},repulsion:{centralGravity:{number:ZZ},springLength:{number:ZZ},springConstant:{number:ZZ},nodeDistance:{number:ZZ},damping:{number:ZZ},__type__:{object:GZ}},hierarchicalRepulsion:{centralGravity:{number:ZZ},springLength:{number:ZZ},springConstant:{number:ZZ},nodeDistance:{number:ZZ},damping:{number:ZZ},avoidOverlap:{number:ZZ},__type__:{object:GZ}},maxVelocity:{number:ZZ},minVelocity:{number:ZZ},solver:{string:["barnesHut","repulsion","hierarchicalRepulsion","forceAtlas2Based"]},stabilization:{enabled:{boolean:SZ},iterations:{number:ZZ},updateInterval:{number:ZZ},onlyDynamicEdges:{boolean:SZ},fit:{boolean:SZ},__type__:{object:GZ,boolean:SZ}},timestep:{number:ZZ},adaptiveTimestep:{boolean:SZ},wind:{x:{number:ZZ},y:{number:ZZ},__type__:{object:GZ}},__type__:{object:GZ,boolean:SZ}},autoResize:{boolean:SZ},clickToUse:{boolean:SZ},locale:{string:zZ},locales:{__any__:{any:"any"},__type__:{object:GZ}},height:{string:zZ},width:{string:zZ},__type__:{object:GZ}},YZ={nodes:{borderWidth:[1,0,10,1],borderWidthSelected:[2,0,10,1],color:{border:["color","#2B7CE9"],background:["color","#97C2FC"],highlight:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]},hover:{border:["color","#2B7CE9"],background:["color","#D2E5FF"]}},opacity:[0,0,1,.1],fixed:{x:!1,y:!1},font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[0,0,50,1],strokeColor:["color","#ffffff"]},hidden:!1,labelHighlightBold:!0,physics:!0,scaling:{min:[10,0,200,1],max:[30,0,200,1],label:{enabled:!1,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},shape:["ellipse","box","circle","database","diamond","dot","square","star","text","triangle","triangleDown","hexagon"],shapeProperties:{borderDashes:!1,borderRadius:[6,0,20,1],interpolation:!0,useImageSize:!1},size:[25,0,200,1]},edges:{arrows:{to:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},middle:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"},from:{enabled:!1,scaleFactor:[1,0,3,.05],type:"arrow"}},endPointOffset:{from:[0,-10,10,1],to:[0,-10,10,1]},arrowStrikethrough:!0,color:{color:["color","#848484"],highlight:["color","#848484"],hover:["color","#848484"],inherit:["from","to","both",!0,!1],opacity:[1,0,1,.05]},dashes:!1,font:{color:["color","#343434"],size:[14,0,100,1],face:["arial","verdana","tahoma"],background:["color","none"],strokeWidth:[2,0,50,1],strokeColor:["color","#ffffff"],align:["horizontal","top","middle","bottom"]},hidden:!1,hoverWidth:[1.5,0,5,.1],labelHighlightBold:!0,physics:!0,scaling:{min:[1,0,100,1],max:[15,0,100,1],label:{enabled:!0,min:[14,0,200,1],max:[30,0,200,1],maxVisible:[30,0,200,1],drawThreshold:[5,0,20,1]}},selectionWidth:[1.5,0,5,.1],selfReferenceSize:[20,0,200,1],selfReference:{size:[20,0,200,1],angle:[Math.PI/2,-6*Math.PI,6*Math.PI,Math.PI/8],renderBehindTheNode:!0},shadow:{enabled:!1,color:"rgba(0,0,0,0.5)",size:[10,0,20,1],x:[5,-30,30,1],y:[5,-30,30,1]},smooth:{enabled:!0,type:["dynamic","continuous","discrete","diagonalCross","straightCross","horizontal","vertical","curvedCW","curvedCCW","cubicBezier"],forceDirection:["horizontal","vertical","none"],roundness:[.5,0,1,.05]},width:[1,0,30,1]},layout:{hierarchical:{enabled:!1,levelSeparation:[150,20,500,5],nodeSpacing:[100,20,500,5],treeSpacing:[200,20,500,5],blockShifting:!0,edgeMinimization:!0,parentCentralization:!0,direction:["UD","DU","LR","RL"],sortMethod:["hubsize","directed"],shakeTowards:["leaves","roots"]}},interaction:{dragNodes:!0,dragView:!0,hideEdgesOnDrag:!1,hideEdgesOnZoom:!1,hideNodesOnDrag:!1,hover:!1,keyboard:{enabled:!1,speed:{x:[10,0,40,1],y:[10,0,40,1],zoom:[.02,0,.1,.005]},bindToWindow:!0,autoFocus:!0},multiselect:!1,navigationButtons:!1,selectable:!0,selectConnectedEdges:!0,hoverConnectedEdges:!0,tooltipDelay:[300,0,1e3,25],zoomView:!0,zoomSpeed:[1,.1,2,.1]},manipulation:{enabled:!1,initiallyActive:!1},physics:{enabled:!0,barnesHut:{theta:[.5,.1,1,.05],gravitationalConstant:[-2e3,-3e4,0,50],centralGravity:[.3,0,10,.05],springLength:[95,0,500,5],springConstant:[.04,0,1.2,.005],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},forceAtlas2Based:{theta:[.5,.1,1,.05],gravitationalConstant:[-50,-500,0,1],centralGravity:[.01,0,1,.005],springLength:[95,0,500,5],springConstant:[.08,0,1.2,.005],damping:[.4,0,1,.01],avoidOverlap:[0,0,1,.01]},repulsion:{centralGravity:[.2,0,10,.05],springLength:[200,0,500,5],springConstant:[.05,0,1.2,.005],nodeDistance:[100,0,500,5],damping:[.09,0,1,.01]},hierarchicalRepulsion:{centralGravity:[.2,0,10,.05],springLength:[100,0,500,5],springConstant:[.01,0,1.2,.005],nodeDistance:[120,0,500,5],damping:[.09,0,1,.01],avoidOverlap:[0,0,1,.01]},maxVelocity:[50,0,150,1],minVelocity:[.1,.01,.5,.01],solver:["barnesHut","forceAtlas2Based","repulsion","hierarchicalRepulsion"],timestep:[.5,.01,1,.01],wind:{x:[0,-10,10,.1],y:[0,-10,10,.1]}}},WZ=function(g,t,e){var A;return!(!ju(g).call(g,"physics")||!ju(A=YZ.physics.solver).call(A,t)||e.physics.solver===t||"wind"===t)},QZ=Object.freeze({__proto__:null,allOptions:VZ,configuratorHideOption:WZ,configureOptions:YZ}),UZ=function(){function g(){cd(this,g)}return Bh(g,[{key:"getDistances",value:function(g,t,e){for(var A={},C=g.edges,I=0;I2&&void 0!==arguments[2]&&arguments[2],A=this.distanceSolver.getDistances(this.body,g,t);this._createL_matrix(A),this._createK_matrix(A),this._createE_matrix();for(var C=0,I=Math.max(1e3,Math.min(10*this.body.nodeIndices.length,6e3)),i=1e9,o=0,n=0,r=0,s=0,a=0;i>.01&&C1&&a<5;){a+=1,this._moveNode(o,n,r);var h=bl(this._getEnergy(o),3);s=h[0],n=h[1],r=h[2]}}}},{key:"_getHighestEnergyNode",value:function(g){for(var t=this.body.nodeIndices,e=this.body.nodes,A=0,C=t[0],I=0,i=0,o=0;o Date: Mon, 29 Jun 2026 12:51:27 +0800 Subject: [PATCH 04/95] build: include vendored vis-network in package data --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 35e78159b..636c3535b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,7 +116,7 @@ include-package-data = false # under graphify/skills//references/, and the always-on injection blocks # under graphify/always_on/. There is no graphify/skills//SKILL.md in the # repo, so no SKILL.md glob is needed here. -graphify = ["skill.md", "skill-codex.md", "skill-opencode.md", "skill-kilo.md", "command-kilo.md", "skill-aider.md", "skill-amp.md", "skill-agents.md", "skill-copilot.md", "skill-claw.md", "skill-windows.md", "skill-droid.md", "skill-trae.md", "skill-kiro.md", "skill-vscode.md", "skill-pi.md", "skill-devin.md", "skills/*/references/*.md", "always_on/*.md"] +graphify = ["skill.md", "skill-codex.md", "skill-opencode.md", "skill-kilo.md", "command-kilo.md", "skill-aider.md", "skill-amp.md", "skill-agents.md", "skill-copilot.md", "skill-claw.md", "skill-windows.md", "skill-droid.md", "skill-trae.md", "skill-kiro.md", "skill-vscode.md", "skill-pi.md", "skill-devin.md", "skills/*/references/*.md", "always_on/*.md", "assets/vis-network.min.js"] [tool.pytest.ini_options] testpaths = ["tests"] From feb3cfde09d2116fdb5def0152331eb52372fc5e Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 13:52:13 +0800 Subject: [PATCH 05/95] feat(export): add _VIS_NETWORK_FILENAME constant --- graphify/export.py | 6 ++++++ tests/test_export.py | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/graphify/export.py b/graphify/export.py index 052dbcc6a..3feed96b0 100644 --- a/graphify/export.py +++ b/graphify/export.py @@ -30,6 +30,12 @@ ] +# Filename of the vendored vis-network UMD bundle copied next to generated +# graph.html files. The actual bytes live in graphify/assets/ and are read +# via importlib.resources at generation time. +_VIS_NETWORK_FILENAME = "vis-network.min.js" + + def backup_if_protected(out_dir: Path) -> "Path | None": """Snapshot graph artifacts to a dated subfolder before an overwrite. diff --git a/tests/test_export.py b/tests/test_export.py index 6a1a439d1..82d25d1b1 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -517,3 +517,8 @@ def test_backup_env_disable(tmp_path, monkeypatch): (tmp_path / "graph.json").write_text('{"nodes":[],"links":[]}') (tmp_path / ".graphify_semantic_marker").write_text("{}") assert backup_if_protected(tmp_path) is None + + +def test_vis_network_filename_constant(): + from graphify.export import _VIS_NETWORK_FILENAME + assert _VIS_NETWORK_FILENAME == "vis-network.min.js" From e810300463b39e1e157223ff9bd6bda099a56876 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 13:56:17 +0800 Subject: [PATCH 06/95] feat(export): add _vendored_vis_js() helper --- graphify/export.py | 10 ++++++++++ tests/test_export.py | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/graphify/export.py b/graphify/export.py index 3feed96b0..df891a18c 100644 --- a/graphify/export.py +++ b/graphify/export.py @@ -36,6 +36,16 @@ _VIS_NETWORK_FILENAME = "vis-network.min.js" +def _vendored_vis_js() -> bytes: + """Read the vendored vis-network.min.js from the installed package. + + Uses importlib.resources so it works from an in-repo editable install, + a wheel install, and an sdist install alike. + """ + from importlib.resources import files + return files("graphify").joinpath("assets", _VIS_NETWORK_FILENAME).read_bytes() + + def backup_if_protected(out_dir: Path) -> "Path | None": """Snapshot graph artifacts to a dated subfolder before an overwrite. diff --git a/tests/test_export.py b/tests/test_export.py index 82d25d1b1..066f4c10a 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -522,3 +522,11 @@ def test_backup_env_disable(tmp_path, monkeypatch): def test_vis_network_filename_constant(): from graphify.export import _VIS_NETWORK_FILENAME assert _VIS_NETWORK_FILENAME == "vis-network.min.js" + + +def test_vendored_vis_js_returns_committed_file_bytes(): + from importlib.resources import files + expected = files("graphify").joinpath("assets", "vis-network.min.js").read_bytes() + from graphify.export import _vendored_vis_js + assert _vendored_vis_js() == expected + assert len(_vendored_vis_js()) > 0 From 97a046aaeaaf9c49894a72f3c606182b8fa2aa23 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 13:59:54 +0800 Subject: [PATCH 07/95] feat(export): add _emit_vis_js() helper (idempotent copy) --- graphify/export.py | 14 ++++++++++++++ tests/test_export.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/graphify/export.py b/graphify/export.py index df891a18c..893870671 100644 --- a/graphify/export.py +++ b/graphify/export.py @@ -46,6 +46,20 @@ def _vendored_vis_js() -> bytes: return files("graphify").joinpath("assets", _VIS_NETWORK_FILENAME).read_bytes() +def _emit_vis_js(html_path: Path) -> None: + """Copy the vendored vis-network.min.js next to html_path if missing or stale. + + Skips the write when the existing file is byte-identical to the vendored + copy. The byte-equality short-circuit is what keeps build caches, file + watchers, and Obsidian sync from re-processing the file on every run. + """ + target = html_path.parent / _VIS_NETWORK_FILENAME + vendored = _vendored_vis_js() + if target.exists() and target.read_bytes() == vendored: + return + target.write_bytes(vendored) + + def backup_if_protected(out_dir: Path) -> "Path | None": """Snapshot graph artifacts to a dated subfolder before an overwrite. diff --git a/tests/test_export.py b/tests/test_export.py index 066f4c10a..227383a46 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -530,3 +530,37 @@ def test_vendored_vis_js_returns_committed_file_bytes(): from graphify.export import _vendored_vis_js assert _vendored_vis_js() == expected assert len(_vendored_vis_js()) > 0 + + +def test_emit_vis_js_creates_file_when_missing(tmp_path): + from graphify.export import _emit_vis_js, _VIS_NETWORK_FILENAME, _vendored_vis_js + target = tmp_path / "graph.html" # parent dir is what matters here + assert not (target.parent / _VIS_NETWORK_FILENAME).exists() + _emit_vis_js(target) + assert (target.parent / _VIS_NETWORK_FILENAME).exists() + assert (target.parent / _VIS_NETWORK_FILENAME).read_bytes() == _vendored_vis_js() + + +def test_emit_vis_js_skips_rewrite_when_bytes_identical(tmp_path): + from graphify.export import _emit_vis_js, _VIS_NETWORK_FILENAME, _vendored_vis_js + html = tmp_path / "graph.html" + _emit_vis_js(html) + target = html.parent / _VIS_NETWORK_FILENAME + mtime_before = target.stat().st_mtime_ns + # Force a tiny clock tick so a no-op write would still register. + import time + time.sleep(0.01) + _emit_vis_js(html) + mtime_after = target.stat().st_mtime_ns + assert mtime_after == mtime_before + assert target.read_bytes() == _vendored_vis_js() + + +def test_emit_vis_js_overwrites_when_vendored_changes(monkeypatch, tmp_path): + from graphify import export + monkeypatch.setattr(export, "_vendored_vis_js", lambda: b"DIFFERENT-BYTES") + from graphify.export import _emit_vis_js, _VIS_NETWORK_FILENAME + html = tmp_path / "graph.html" + _emit_vis_js(html) + target = html.parent / _VIS_NETWORK_FILENAME + assert target.read_bytes() == b"DIFFERENT-BYTES" From 68b2f842b3226a7816d8c413bc5a620a83654816 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 14:05:01 +0800 Subject: [PATCH 08/95] feat(export): to_html uses local vis-network, no CDN/SRI --- graphify/export.py | 5 ++--- tests/test_export.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/graphify/export.py b/graphify/export.py index 893870671..b1496aa16 100644 --- a/graphify/export.py +++ b/graphify/export.py @@ -817,9 +817,7 @@ def _js_safe(obj) -> str: graphify - {title} - + {_html_styles()} @@ -847,6 +845,7 @@ def _js_safe(obj) -> str: """ + _emit_vis_js(Path(output_path)) Path(output_path).write_text(html, encoding="utf-8") # nosec diff --git a/tests/test_export.py b/tests/test_export.py index 227383a46..189243bd4 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -98,6 +98,24 @@ def test_to_html_contains_visjs(): to_html(G, communities, str(out)) content = out.read_text() assert "vis-network" in content + # New: same-origin reference, no CDN, no SRI, no crossorigin. + assert '' in content + assert 'unpkg.com' not in content + assert 'integrity=' not in content + assert 'crossorigin="anonymous"' not in content + + +def test_to_html_emits_local_vis_network_asset(): + from graphify.export import _vendored_vis_js + G = make_graph() + communities = cluster(G) + with tempfile.TemporaryDirectory() as tmp: + out = Path(tmp) / "graph.html" + to_html(G, communities, str(out)) + asset = out.parent / "vis-network.min.js" + assert asset.exists() + # Byte-equality with the vendored copy is the correctness contract. + assert asset.read_bytes() == _vendored_vis_js() def test_to_html_pins_visjs_version_with_sri(): From 72a34bd365bce57e392edae644cba31953874bf0 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 14:09:46 +0800 Subject: [PATCH 09/95] test(export): drop obsolete SRI/CDN pin test (local asset now) --- tests/test_export.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/tests/test_export.py b/tests/test_export.py index 189243bd4..90af21f15 100644 --- a/tests/test_export.py +++ b/tests/test_export.py @@ -118,32 +118,6 @@ def test_to_html_emits_local_vis_network_asset(): assert asset.read_bytes() == _vendored_vis_js() -def test_to_html_pins_visjs_version_with_sri(): - """vis-network script tag must use a pinned versioned URL with a sha384 - Subresource Integrity hash and crossorigin=anonymous. Without this, - a compromised CDN could ship arbitrary JavaScript into every rendered - graph viewer. The hash was verified against the upstream file at - https://unpkg.com/vis-network@9.1.6/standalone/umd/vis-network.min.js - (sha384-Ux6phic9PEHJ38YtrijhkzyJ8yQlH8i/+buBR8s3mAZOJrP1gwyvAcIYl3GWtpX1). - Bumping the vis-network version MUST update both the URL and the hash. - """ - G = make_graph() - communities = cluster(G) - with tempfile.TemporaryDirectory() as tmp: - out = Path(tmp) / "graph.html" - to_html(G, communities, str(out)) - content = out.read_text() - - # Versioned URL — unversioned `vis-network/standalone/...` is rejected. - assert "vis-network@9.1.6/standalone/umd/vis-network.min.js" in content - assert "https://unpkg.com/vis-network/standalone" not in content - - # SRI integrity attribute pinning the known-good hash. - assert 'integrity="sha384-Ux6phic9PEHJ38YtrijhkzyJ8yQlH8i/+buBR8s3mAZOJrP1gwyvAcIYl3GWtpX1"' in content - - # crossorigin="anonymous" is required for SRI on cross-origin scripts. - assert 'crossorigin="anonymous"' in content - def test_to_html_contains_search(): G = make_graph() communities = cluster(G) From 9a56dd07951d40a33236d0c6f049c3c8b3d36289 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 14:11:35 +0800 Subject: [PATCH 10/95] test(pipeline): tighten vis-network assertion to local path --- tests/test_pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index ce6055d8b..aff532c28 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -80,7 +80,7 @@ def run_pipeline(tmp_path: Path) -> dict: to_html(G, communities, str(html_path), community_labels=labels) assert html_path.exists() html = html_path.read_text() - assert "vis-network" in html + assert './vis-network.min.js' in html assert "RAW_NODES" in html # Step 9: export - Obsidian vault From be19fff48540eea8a7bdbf55e116a866e2d15148 Mon Sep 17 00:00:00 2001 From: fengyca Date: Mon, 29 Jun 2026 14:16:10 +0800 Subject: [PATCH 11/95] docs(changelog): note local vis-network vendoring + SRI removal --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d01379b1..2a0c23710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Full release notes with details on each version: [GitHub Releases](https://github.com/safishamsi/graphify/releases) +## Unreleased + +- Feat: `to_html` now ships `vis-network@9.1.6` inside the `graphify` package instead of pulling it from `unpkg.com` at view time. The UMD bundle (702,611 bytes) is vendored at `graphify/assets/vis-network.min.js`, registered in `pyproject.toml` `package-data`, and copied next to each generated `graph.html` as `./vis-network.min.js` (idempotent — only rewritten when the bytes change, so file watchers / Obsidian sync don't churn). Every `graphify-out/graph.html` is now self-contained and renders offline. **Notes:** the generated `graph.html` is no longer a single-file artifact — it has a same-directory `vis-network.min.js` sibling, so copy / archive / e-mail the pair together; the wheel grows by ~700 KB; the previous `unpkg.com` `` 转义) + 内嵌进 `|<\\/script>|gi' "$1" +} + +script_for_inline() { + perl -pe 's|//# sourceMappingURL=.*$||' "$1" +} + +html_escape_text() { + printf '%s' "$1" | perl -pe 's/&/&/g; s//>/g; s/"/"/g; s/'"'"'/'/g' +} + +while [ "$#" -gt 0 ]; do + case "$1" in + -h|--help) + print_usage + exit 0 + ;; + --) + shift + break + ;; + -*) + die "未知选项: $1" + ;; + *) + break + ;; + esac +done + +[ "$#" -eq 1 ] || { + print_usage >&2 + exit 1 +} + +WIKI_ROOT="$1" + +command -v jq >/dev/null 2>&1 || { + echo "ERROR: jq is not installed. Install it via:" >&2 + print_install_hint jq + exit 1 +} + +SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +DATA="$WIKI_ROOT/wiki/graph-data.json" +LAYOUT="$WIKI_ROOT/.wiki-graph-layout.json" +ENGINE="$SKILL_DIR/packages/graph-engine/dist/engine.iife.js" +MARKED="$SKILL_DIR/deps/marked.min.js" +PURIFY="$SKILL_DIR/deps/purify.min.js" +OUTPUT="$WIKI_ROOT/wiki/knowledge-graph.html" + +[ -f "$DATA" ] || { + echo "ERROR: 未找到 $DATA" >&2 + echo " 请先运行 build-graph-data.sh 生成图谱数据" >&2 + exit 1 +} +ensure_file "$ENGINE" "graph-engine IIFE 产物" +ensure_file "$MARKED" "marked vendor" +ensure_file "$PURIFY" "purify vendor" + +WIKI_TITLE=$(jq -r '.meta.wiki_title // "知识库"' "$DATA") +NODE_COUNT=$(jq -r '.meta.total_nodes // 0' "$DATA") +EDGE_COUNT=$(jq -r '.meta.total_edges // 0' "$DATA") +BUILD_DATE=$(jq -r '.meta.build_date // ""' "$DATA") +BUILD_DATE_SHORT="${BUILD_DATE:0:10}" +[ -n "$BUILD_DATE_SHORT" ] || BUILD_DATE_SHORT="未知" +WIKI_TITLE_HTML=$(html_escape_text "$WIKI_TITLE") +NODE_COUNT_HTML=$(html_escape_text "$NODE_COUNT") +EDGE_COUNT_HTML=$(html_escape_text "$EDGE_COUNT") +BUILD_DATE_SHORT_HTML=$(html_escape_text "$BUILD_DATE_SHORT") + +layout_json='{"version":2,"pins":{},"updatedAt":""}' +if [ -f "$LAYOUT" ]; then + if layout_json_candidate=$(jq -c '{version:(.version // 1), pins:(.pins // {}), updatedAt:(.updatedAt // "")}' "$LAYOUT" 2>/dev/null); then + layout_json="$layout_json_candidate" + else + echo "WARN: 忽略损坏的钉位文件:$LAYOUT" >&2 + fi +fi + +output_dir="$(dirname "$OUTPUT")" +mkdir -p "$output_dir" +output_tmp="$OUTPUT.partial" +output_next="$OUTPUT.next" +rm -f "$output_tmp" "$output_next" + +cat > "$output_tmp" < + + + + + 知识图谱 · ${WIKI_TITLE_HTML} + + + +
+
+
+

${WIKI_TITLE_HTML} 知识舆图

+

国风知识库·数字山水图

+
+
+
+ ${NODE_COUNT_HTML} 节点 + ${EDGE_COUNT_HTML} 关联 + ${BUILD_DATE_SHORT_HTML} + +
+
+
+
+
+
+ + |<\/script>|gi' >> "$output_tmp" +cat >> "$output_tmp" <<'HTML_ENGINE' + + + + + +HTML_BOOT + +mv "$output_tmp" "$output_next" +mv "$output_next" "$OUTPUT" + +rm -f \ + "$output_dir/d3.min.js" \ + "$output_dir/rough.min.js" \ + "$output_dir/marked.min.js" \ + "$output_dir/purify.min.js" \ + "$output_dir/graph-wash.js" \ + "$output_dir/graph-wash-helpers.js" \ + "$output_dir/LICENSE-d3.txt" \ + "$output_dir/LICENSE-roughjs.txt" \ + "$output_dir/LICENSE-marked.txt" \ + "$output_dir/LICENSE-purify.txt" + +output_size=$(wc -c < "$OUTPUT" | tr -d ' ') +output_kb=$((output_size / 1024)) + +echo "交互式图谱已生成:" +echo " - $OUTPUT (${output_kb} KB)" +echo " 节点 $NODE_COUNT · 关联 $EDGE_COUNT" +echo "" +echo "查看方式:" +echo " 双击 $OUTPUT" diff --git a/graphify/bundled_skills/llm-wiki/scripts/cache.sh b/graphify/bundled_skills/llm-wiki/scripts/cache.sh new file mode 100755 index 000000000..fabd5cbf5 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/cache.sh @@ -0,0 +1,352 @@ +#!/bin/bash +# llm-wiki 缓存脚本 + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/shared-config.sh" + +usage() { + cat <<'EOF' +用法: + bash scripts/cache.sh check + bash scripts/cache.sh update + bash scripts/cache.sh invalidate +EOF +} + +require_file() { + local file_path="$1" + + [ -n "$file_path" ] || { + usage + exit 1 + } + + [ -f "$file_path" ] || { + echo "文件不存在:$file_path" >&2 + exit 1 + } +} + +find_wiki_root() { + local file_path="$1" + local dir parent + + dir="$(cd "$(dirname "$file_path")" && pwd)" + + while true; do + if [ -f "$dir/.wiki-cache.json" ] || [ -f "$dir/.wiki-schema.md" ]; then + printf '%s\n' "$dir" + return 0 + fi + + parent="$(dirname "$dir")" + [ "$parent" = "$dir" ] && return 1 + dir="$parent" + done +} + +cache_file_path() { + printf '%s/.wiki-cache.json\n' "$1" +} + +ensure_cache_file() { + local cache_file="$1" + + if [ ! -f "$cache_file" ]; then + cat > "$cache_file" <<'EOF' +{ + "version": 1, + "entries": {} +} +EOF + fi +} + +relative_path() { + require_python_cmd + + "$PYTHON_CMD" - "$1" "$2" <<'PY' +import os +import sys + +print(os.path.relpath(os.path.realpath(sys.argv[2]), os.path.realpath(sys.argv[1]))) +PY +} + +normalized_source_page() { + local wiki_root="$1" + local source_page="$2" + + if [ -z "$source_page" ]; then + printf '%s\n' "" + return 0 + fi + + case "$source_page" in + /*) + require_python_cmd + + "$PYTHON_CMD" - "$wiki_root" "$source_page" <<'PY' +import os +import sys + +wiki_root = os.path.realpath(sys.argv[1]) +source_page = os.path.realpath(sys.argv[2]) + +try: + common = os.path.commonpath([wiki_root, source_page]) +except ValueError: + common = "" + +if common == wiki_root: + print(os.path.relpath(source_page, wiki_root)) +else: + print(sys.argv[2]) +PY + ;; + *) + printf '%s\n' "$source_page" + ;; + esac +} + +file_hash() { + require_python_cmd + + "$PYTHON_CMD" - "$1" "$2" <<'PY' +import hashlib +import pathlib +import sys + +relative_path = sys.argv[1].encode("utf-8") +file_path = pathlib.Path(sys.argv[2]) +content = file_path.read_bytes() + +digest = hashlib.sha256(relative_path + b"\0" + content).hexdigest() +print(f"sha256:{digest}") +PY +} + +cache_check() { + local file_path="$1" + local wiki_root cache_file relative_path_value current_hash result + + require_file "$file_path" + wiki_root="$(find_wiki_root "$file_path")" || { + echo "未找到知识库根目录:$file_path" >&2 + exit 1 + } + cache_file="$(cache_file_path "$wiki_root")" + + if [ ! -f "$cache_file" ]; then + printf 'MISS\n' + return 0 + fi + + require_python_cmd + + relative_path_value="$(relative_path "$wiki_root" "$file_path")" + current_hash="$(file_hash "$relative_path_value" "$file_path")" + + result="$( + "$PYTHON_CMD" - "$cache_file" "$wiki_root" "$relative_path_value" "$current_hash" <<'PY' +import hashlib +import json +import os +import pathlib +import sys + +cache_file, wiki_root, relative_path, current_hash = sys.argv[1:5] + +with open(cache_file, "r", encoding="utf-8") as fh: + data = json.load(fh) + +entry = data.get("entries", {}).get(relative_path) + +# 无 cache entry → 尝试自愈(exact filename stem match + source_path 验证) +if not entry: + raw_stem = pathlib.Path(relative_path).stem + sources_dir = os.path.join(wiki_root, "wiki", "sources") + if os.path.isdir(sources_dir): + for f in os.listdir(sources_dir): + if pathlib.Path(f).stem == raw_stem and f.endswith(".md"): + source_page = os.path.join("wiki", "sources", f) + source_abs = os.path.join(wiki_root, source_page) + # 验证 source 页面的 source_path frontmatter 是否指向当前 raw 文件 + source_path_match = False + try: + with open(source_abs, "r", encoding="utf-8") as sf: + in_frontmatter = False + for line in sf: + stripped = line.strip() + if stripped == "---": + if in_frontmatter: + break # end of frontmatter + in_frontmatter = True + continue + if in_frontmatter and stripped.startswith("source_path:"): + fm_value = stripped.split(":", 1)[1].strip() + # 匹配相对路径的末尾部分 + if relative_path.endswith(fm_value) or fm_value.endswith(relative_path) or fm_value == relative_path: + source_path_match = True + break + except (OSError, UnicodeDecodeError): + pass + if not source_path_match: + # stem 匹配但 source_path 不一致 → 不信任,需要验证 + print("MISS:repaired_needs_verify") + raise SystemExit(0) + # stem + source_path 都匹配 → 安全自愈 + timestamp = __import__("datetime").datetime.now(__import__("datetime").timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") + entries = data.setdefault("entries", {}) + entries[relative_path] = { + "hash": current_hash, + "ingested_at": timestamp, + "source_page": source_page, + } + tmp_file = cache_file + ".tmp" + with open(tmp_file, "w", encoding="utf-8") as fh2: + json.dump(data, fh2, ensure_ascii=False, indent=2) + fh2.write("\n") + os.replace(tmp_file, cache_file) + print("HIT(repaired)") + raise SystemExit(0) + print("MISS:no_entry") + raise SystemExit(0) + +if entry.get("hash") != current_hash: + print("MISS:hash_changed") + raise SystemExit(0) + +source_page = entry.get("source_page") +if not source_page: + print("MISS:no_entry") + raise SystemExit(0) + +source_path = source_page +if not os.path.isabs(source_path): + source_path = os.path.join(wiki_root, source_path) + +if not os.path.isfile(source_path): + print("MISS:no_source") +else: + print("HIT") +PY + )" + + printf '%s\n' "$result" +} + +cache_update() { + local file_path="$1" + local source_page="$2" + local wiki_root cache_file relative_path_value current_hash normalized_source timestamp + + require_file "$file_path" + wiki_root="$(find_wiki_root "$file_path")" || { + echo "未找到知识库根目录:$file_path" >&2 + exit 1 + } + cache_file="$(cache_file_path "$wiki_root")" + ensure_cache_file "$cache_file" + + require_python_cmd + + relative_path_value="$(relative_path "$wiki_root" "$file_path")" + current_hash="$(file_hash "$relative_path_value" "$file_path")" + normalized_source="$(normalized_source_page "$wiki_root" "$source_page")" + timestamp="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + + "$PYTHON_CMD" - "$cache_file" "$relative_path_value" "$current_hash" "$timestamp" "$normalized_source" <<'PY' +import json +import os +import sys + +cache_file, relative_path, file_hash_value, timestamp, source_page = sys.argv[1:6] + +with open(cache_file, "r", encoding="utf-8") as fh: + data = json.load(fh) + +entries = data.setdefault("entries", {}) +entries[relative_path] = { + "hash": file_hash_value, + "ingested_at": timestamp, + "source_page": source_page, +} + +tmp_file = cache_file + ".tmp" +with open(tmp_file, "w", encoding="utf-8") as fh: + json.dump(data, fh, ensure_ascii=False, indent=2) + fh.write("\n") +os.replace(tmp_file, cache_file) +PY + + printf 'UPDATED\n' +} + +cache_invalidate() { + local file_path="$1" + local wiki_root cache_file relative_path_value + + # 不调用 require_file:文件可能已被删除(级联删除场景) + # 直接通过路径查找缓存条目 + wiki_root="$(find_wiki_root "$file_path")" || { + echo "未找到知识库根目录:$file_path" >&2 + exit 1 + } + cache_file="$(cache_file_path "$wiki_root")" + + if [ ! -f "$cache_file" ]; then + printf 'INVALIDATED\n' + return 0 + fi + + require_python_cmd + + relative_path_value="$(relative_path "$wiki_root" "$file_path")" + + "$PYTHON_CMD" - "$cache_file" "$relative_path_value" <<'PY' +import json +import os +import sys + +cache_file, relative_path = sys.argv[1:3] + +with open(cache_file, "r", encoding="utf-8") as fh: + data = json.load(fh) + +data.setdefault("entries", {}).pop(relative_path, None) + +tmp_file = cache_file + ".tmp" +with open(tmp_file, "w", encoding="utf-8") as fh: + json.dump(data, fh, ensure_ascii=False, indent=2) + fh.write("\n") +os.replace(tmp_file, cache_file) +PY + + printf 'INVALIDATED\n' +} + +command_name="${1:-}" + +case "$command_name" in + check) + [ "$#" -eq 2 ] || { usage; exit 1; } + cache_check "$2" + ;; + update) + [ "$#" -eq 3 ] || { usage; exit 1; } + cache_update "$2" "$3" + ;; + invalidate) + [ "$#" -eq 2 ] || { usage; exit 1; } + cache_invalidate "$2" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/graphify/bundled_skills/llm-wiki/scripts/create-source-page.sh b/graphify/bundled_skills/llm-wiki/scripts/create-source-page.sh new file mode 100755 index 000000000..d2958db1d --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/create-source-page.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# llm-wiki source 页面写入脚本 +# 原子写入 source 页面 + 自动更新缓存,绑定为一项操作 + +set -euo pipefail + +usage() { + cat <<'EOF' +用法: + bash scripts/create-source-page.sh + +参数: + raw_file : 原始素材文件路径(绝对或相对路径) + output_path : 目标页面路径(相对于知识库根目录,如 wiki/sources/2026-04-16-rlhf.md) + content_file : 包含待写入内容的临时文件路径 +EOF +} + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# 参数校验 +if [ "$#" -ne 3 ]; then + usage + exit 1 +fi + +raw_file="$1" +output_path="$2" +content_file="$3" + +# raw_file 和 content_file 必须存在 +if [ ! -f "$raw_file" ]; then + echo "ERROR: 原始素材文件不存在:$raw_file" >&2 + exit 1 +fi + +if [ ! -f "$content_file" ]; then + echo "ERROR: 内容文件不存在:$content_file" >&2 + exit 1 +fi + +# 通过 cache.sh 的 find_wiki_root 逻辑找到知识库根目录 +# 复用 cache.sh 里的函数 +source_cache_helpers() { + # 内联 find_wiki_root(与 cache.sh 保持一致) + find_wiki_root() { + local file_path="$1" + local dir parent + + dir="$(cd "$(dirname "$file_path")" && pwd)" + + while true; do + if [ -f "$dir/.wiki-cache.json" ] || [ -f "$dir/.wiki-schema.md" ]; then + printf '%s\n' "$dir" + return 0 + fi + + parent="$(dirname "$dir")" + [ "$parent" = "$dir" ] && return 1 + dir="$parent" + done + } +} + +source_cache_helpers + +wiki_root="$(find_wiki_root "$raw_file")" || { + echo "ERROR: 未找到知识库根目录:$raw_file" >&2 + exit 1 +} + +# 拼接完整目标路径 +full_output="$wiki_root/$output_path" + +# 确保目标目录存在 +mkdir -p "$(dirname "$full_output")" + +# 第一步:原子写入(临时文件 + rename,防止写一半崩溃) +tmp_output="${full_output}.tmp.$$" +if ! cp "$content_file" "$tmp_output"; then + rm -f "$tmp_output" 2>/dev/null || true + echo "ERROR: 写入临时文件失败" >&2 + exit 1 +fi + +if ! mv "$tmp_output" "$full_output"; then + rm -f "$tmp_output" 2>/dev/null || true + echo "ERROR: 原子重命名失败" >&2 + exit 1 +fi + +# 第二步:更新缓存 +if ! bash "$SCRIPT_DIR/cache.sh" update "$raw_file" "$output_path"; then + # 缓存更新失败 → 回滚:删除已写入的文件 + rm -f "$full_output" + echo "ERROR: 缓存更新失败,已回滚写入" >&2 + exit 1 +fi + +echo "SUCCESS" diff --git a/graphify/bundled_skills/llm-wiki/scripts/delete-helper.sh b/graphify/bundled_skills/llm-wiki/scripts/delete-helper.sh new file mode 100755 index 000000000..65d94ec25 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/delete-helper.sh @@ -0,0 +1,68 @@ +#!/bin/bash +# llm-wiki 删除辅助脚本 + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/shared-config.sh" + +usage() { + cat <<'EOF' +用法: + bash scripts/delete-helper.sh scan-refs <素材文件名> +EOF +} + +scan_refs() { + local wiki_root="$1" + local needle="$2" + local wiki_dir="$wiki_root/wiki" + + [ -n "$needle" ] || { + echo "素材文件名不能为空" >&2 + exit 1 + } + + [ -d "$wiki_dir" ] || { + echo "知识库目录不存在:$wiki_dir" >&2 + exit 1 + } + + require_python_cmd + + { + grep -rlF --include='*.md' -- "$needle" "$wiki_dir" 2>/dev/null || true + } | "$PYTHON_CMD" -c ' +import os +import sys + +wiki_root = os.path.realpath(sys.argv[1]) +seen = [] + +for line in sys.stdin: + path = line.strip() + if not path: + continue + real_path = os.path.realpath(path) + if real_path in seen: + continue + seen.append(real_path) + +for path in sorted(seen): + print(os.path.relpath(path, wiki_root)) +' "$wiki_root" +} + +command_name="${1:-}" + +case "$command_name" in + scan-refs) + [ "$#" -eq 3 ] || { usage; exit 1; } + scan_refs "$2" "$3" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/graphify/bundled_skills/llm-wiki/scripts/graph-analysis.js b/graphify/bundled_skills/llm-wiki/scripts/graph-analysis.js new file mode 100644 index 000000000..d8392ba73 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/graph-analysis.js @@ -0,0 +1,732 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const { extractFrontmatter, parseSourcesFrontmatter, sortedUnique } = require("./lib/source-signal-eligibility"); + +function readJson(filePath) { + return JSON.parse(fs.readFileSync(filePath, "utf8")); +} + +function writeJson(filePath, value) { + fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8"); +} + +function roundNumber(value, digits = 3) { + const factor = 10 ** digits; + return Math.round(value * factor) / factor; +} + +function clamp01(value) { + return Math.max(0, Math.min(1, value)); +} + +function sortedPairKey(a, b) { + return a < b ? `${a}\t${b}` : `${b}\t${a}`; +} + +function normalizeBody(text, degraded, maxLines) { + const { body } = extractFrontmatter(text); + const normalized = body.replace(/^\s+/, "").replace(/\s+$/, ""); + if (!degraded) return normalized; + return normalized.split(/\r?\n/).slice(0, maxLines).join("\n").replace(/\s+$/, ""); +} + +function loadNodeDetails(nodes, degraded, maxLines) { + const byId = {}; + + for (const node of nodes) { + const filePath = node._file_path || node.source_path; + const raw = fs.readFileSync(filePath, "utf8"); + const frontmatter = extractFrontmatter(raw); + const parsedSources = parseSourcesFrontmatter(frontmatter.frontmatter); + const normalizedNode = { + ...node, + content: normalizeBody(raw, degraded, maxLines), + _signals: { + sources: parsedSources.sources, + sourceSignalAvailable: parsedSources.signalAvailable, + sourceFieldPresent: parsedSources.hasField, + sourceFieldParsed: parsedSources.parsed + } + }; + byId[node.id] = normalizedNode; + } + + return byId; +} + +function buildInlinks(edges) { + const inlinks = new Map(); + + for (const edge of edges) { + if (!inlinks.has(edge.to)) inlinks.set(edge.to, new Set()); + inlinks.get(edge.to).add(edge.from); + } + + return inlinks; +} + +function intersectionCount(setA, setB) { + if (!setA || !setB) return 0; + let small = setA; + let large = setB; + if (setB.size < setA.size) { + small = setB; + large = setA; + } + + let count = 0; + for (const value of small) { + if (large.has(value)) count += 1; + } + return count; +} + +function typeAffinity(typeA, typeB) { + const pair = [typeA || "other", typeB || "other"].sort().join(":"); + switch (pair) { + case "entity:entity": + case "entity:topic": + return 1; + case "topic:topic": + return 0.8; + case "entity:source": + return 0.6; + case "source:source": + return 0.3; + default: + return 0.5; + } +} + +function computePairMetrics(nodesById, edges) { + const inlinks = buildInlinks(edges); + const pairMetrics = new Map(); + + for (const edge of edges) { + const pairKey = sortedPairKey(edge.from, edge.to); + if (pairMetrics.has(pairKey)) continue; + + const fromNode = nodesById[edge.from]; + const toNode = nodesById[edge.to]; + if (!fromNode || !toNode) continue; + + const fromInlinks = inlinks.get(edge.from) || new Set(); + const toInlinks = inlinks.get(edge.to) || new Set(); + const sharedInlinks = intersectionCount(fromInlinks, toInlinks); + const coCitation = sharedInlinks / Math.max(fromInlinks.size, toInlinks.size, 1); + const affinity = typeAffinity(fromNode.type, toNode.type); + + const signals = [coCitation, affinity]; + let sourceOverlap = null; + const sourceSignalAvailable = Boolean( + fromNode._signals.sourceSignalAvailable && toNode._signals.sourceSignalAvailable + ); + + if (sourceSignalAvailable) { + const fromSources = new Set(fromNode._signals.sources); + const toSources = new Set(toNode._signals.sources); + const overlap = intersectionCount(fromSources, toSources); + const minSize = Math.min(fromSources.size, toSources.size); + sourceOverlap = minSize > 0 ? overlap / minSize : 0; + signals.push(sourceOverlap); + } + + const weight = clamp01(signals.reduce((sum, value) => sum + value, 0) / signals.length); + + pairMetrics.set(pairKey, { + weight: roundNumber(weight), + signals: { + co_citation: roundNumber(coCitation), + source_overlap: sourceOverlap == null ? null : roundNumber(sourceOverlap), + type_affinity: roundNumber(affinity) + }, + source_signal_available: sourceSignalAvailable + }); + } + + return pairMetrics; +} + +function buildUndirectedGraph(nodeIds, pairMetrics) { + const adjacency = new Map(); + const degrees = new Map(); + + for (const nodeId of nodeIds) { + adjacency.set(nodeId, new Map()); + degrees.set(nodeId, 0); + } + + for (const [pairKey, metrics] of pairMetrics.entries()) { + const [left, right] = pairKey.split("\t"); + if (!adjacency.has(left) || !adjacency.has(right)) continue; + const weight = metrics.weight; + adjacency.get(left).set(right, weight); + adjacency.get(right).set(left, weight); + degrees.set(left, degrees.get(left) + weight); + degrees.set(right, degrees.get(right) + weight); + } + + return { adjacency, degrees }; +} + +function runLocalMove(graph) { + const nodes = Array.from(graph.nodes.keys()).sort(); + const communities = new Map(); + const totals = new Map(); + let moved = false; + + for (const nodeId of nodes) { + communities.set(nodeId, nodeId); + totals.set(nodeId, graph.degrees.get(nodeId) || 0); + } + + if (graph.m2 === 0) { + return { communities, changed: false }; + } + + let changedInPass = true; + let passCount = 0; + while (changedInPass && passCount < 50) { + passCount++; + changedInPass = false; + + for (const nodeId of nodes) { + const degree = graph.degrees.get(nodeId) || 0; + const currentCommunity = communities.get(nodeId); + const neighborCommunities = new Map(); + + for (const [neighborId, weight] of graph.nodes.get(nodeId).entries()) { + const communityId = communities.get(neighborId); + neighborCommunities.set(communityId, (neighborCommunities.get(communityId) || 0) + weight); + } + + totals.set(currentCommunity, (totals.get(currentCommunity) || 0) - degree); + if ((neighborCommunities.get(currentCommunity) || 0) === 0) { + neighborCommunities.set(currentCommunity, 0); + } + + let bestCommunity = currentCommunity; + let bestGain = 0; + + const candidates = Array.from(neighborCommunities.keys()).sort(); + for (const communityId of candidates) { + const inWeight = neighborCommunities.get(communityId) || 0; + const gain = inWeight - ((totals.get(communityId) || 0) * degree) / graph.m2; + if (gain > bestGain + 1e-9) { + bestGain = gain; + bestCommunity = communityId; + } + } + + communities.set(nodeId, bestCommunity); + totals.set(bestCommunity, (totals.get(bestCommunity) || 0) + degree); + + if (bestCommunity !== currentCommunity) { + changedInPass = true; + moved = true; + } + } + } + + return { communities, changed: moved }; +} + +function aggregateGraph(graph, communities) { + const communityIds = sortedUnique(Array.from(communities.values())); + const aggregatedNodes = new Map(); + const aggregatedDegrees = new Map(); + const members = new Map(); + + for (const communityId of communityIds) { + aggregatedNodes.set(communityId, new Map()); + aggregatedDegrees.set(communityId, 0); + members.set(communityId, []); + } + + for (const [nodeId, communityId] of communities.entries()) { + members.get(communityId).push(...(graph.members.get(nodeId) || [nodeId])); + } + + for (const [nodeId, neighbors] of graph.nodes.entries()) { + const sourceCommunity = communities.get(nodeId); + for (const [neighborId, weight] of neighbors.entries()) { + if (nodeId > neighborId) continue; + const targetCommunity = communities.get(neighborId); + const current = aggregatedNodes.get(sourceCommunity).get(targetCommunity) || 0; + aggregatedNodes.get(sourceCommunity).set(targetCommunity, current + weight); + if (sourceCommunity !== targetCommunity) { + const mirrored = aggregatedNodes.get(targetCommunity).get(sourceCommunity) || 0; + aggregatedNodes.get(targetCommunity).set(sourceCommunity, mirrored + weight); + } + } + } + + for (const [communityId, neighbors] of aggregatedNodes.entries()) { + let degree = 0; + for (const [neighborId, weight] of neighbors.entries()) { + degree += neighborId === communityId ? weight * 2 : weight; + } + aggregatedDegrees.set(communityId, degree); + } + + return { + nodes: aggregatedNodes, + degrees: aggregatedDegrees, + members, + m2: Array.from(aggregatedDegrees.values()).reduce((sum, value) => sum + value, 0) + }; +} + +function runLouvain(nodeIds, pairMetrics) { + const baseGraph = buildUndirectedGraph(nodeIds, pairMetrics); + let graph = { + nodes: baseGraph.adjacency, + degrees: baseGraph.degrees, + members: new Map(nodeIds.map((nodeId) => [nodeId, [nodeId]])), + m2: Array.from(baseGraph.degrees.values()).reduce((sum, value) => sum + value, 0) + }; + + let bestMembers = graph.members; + + while (true) { + const phase = runLocalMove(graph); + const nextGraph = aggregateGraph(graph, phase.communities); + bestMembers = nextGraph.members; + + if (!phase.changed || nextGraph.nodes.size === graph.nodes.size) { + break; + } + + graph = nextGraph; + } + + const finalCommunities = new Map(); + for (const [communityId, members] of bestMembers.entries()) { + for (const nodeId of members) { + finalCommunities.set(nodeId, communityId); + } + } + + return finalCommunities; +} + +function buildDirectedDegree(edges) { + const degree = new Map(); + for (const edge of edges) { + degree.set(edge.from, (degree.get(edge.from) || 0) + 1); + degree.set(edge.to, (degree.get(edge.to) || 0) + 1); + } + return degree; +} + +function chooseCommunityLabels(nodeIds, communityAssignments, nodesById, edges) { + const groups = new Map(); + const degree = buildDirectedDegree(edges); + + for (const nodeId of nodeIds) { + const communityId = communityAssignments.get(nodeId) || nodeId; + if (!groups.has(communityId)) groups.set(communityId, []); + groups.get(communityId).push(nodeId); + } + + const labeledAssignments = new Map(); + + for (const members of groups.values()) { + members.sort(); + if (members.length === 1) { + labeledAssignments.set(members[0], null); + continue; + } + + const memberNodes = members.map((memberId) => nodesById[memberId]); + const topics = memberNodes.filter((node) => node && node.type === "topic"); + const candidates = topics.length ? topics : memberNodes; + candidates.sort((left, right) => { + const degreeDiff = (degree.get(right.id) || 0) - (degree.get(left.id) || 0); + if (degreeDiff !== 0) return degreeDiff; + return left.id.localeCompare(right.id); + }); + + const label = candidates[0] ? candidates[0].id : members[0]; + for (const memberId of members) { + labeledAssignments.set(memberId, label); + } + } + + return labeledAssignments; +} + +function buildInsights(nodesById, edges, pairMetrics, communityAssignments, options) { + const directedDegree = buildDirectedDegree(edges); + const undirectedPairs = new Map(); + const adjacency = new Map(); + + for (const nodeId of Object.keys(nodesById)) { + adjacency.set(nodeId, new Set()); + } + + for (const edge of edges) { + const pairKey = sortedPairKey(edge.from, edge.to); + if (!undirectedPairs.has(pairKey)) { + undirectedPairs.set(pairKey, { + from: pairKey.split("\t")[0], + to: pairKey.split("\t")[1], + weight: pairMetrics.get(pairKey)?.weight || 0 + }); + } + adjacency.get(edge.from)?.add(edge.to); + adjacency.get(edge.to)?.add(edge.from); + } + + const isolatedNodes = Object.values(nodesById) + .filter((node) => (directedDegree.get(node.id) || 0) <= 1) + .sort((left, right) => left.id.localeCompare(right.id)) + .map((node) => ({ + id: node.id, + label: node.label, + degree: directedDegree.get(node.id) || 0, + community: communityAssignments.get(node.id) || null + })); + + const bridgeNodes = []; + for (const node of Object.values(nodesById).sort((left, right) => left.id.localeCompare(right.id))) { + const ownCommunity = communityAssignments.get(node.id) || null; + const connectedCommunities = sortedUnique( + Array.from(adjacency.get(node.id) || []) + .map((neighborId) => communityAssignments.get(neighborId) || null) + .filter((c) => c && c !== ownCommunity) + ); + + if (connectedCommunities.length >= 2) { + bridgeNodes.push({ + id: node.id, + label: node.label, + community: ownCommunity, + connected_communities: connectedCommunities, + community_count: connectedCommunities.length + }); + } + } + + const communityMembers = new Map(); + for (const node of Object.values(nodesById)) { + const communityId = communityAssignments.get(node.id) || null; + if (!communityId) continue; + if (!communityMembers.has(communityId)) communityMembers.set(communityId, []); + communityMembers.get(communityId).push(node.id); + } + + const sparseCommunities = []; + for (const [communityId, members] of Array.from(communityMembers.entries()).sort((left, right) => left[0].localeCompare(right[0]))) { + if (members.length < 3) continue; + + const memberSet = new Set(members); + let internalEdges = 0; + for (const pair of undirectedPairs.values()) { + if (memberSet.has(pair.from) && memberSet.has(pair.to)) internalEdges += 1; + } + + const possibleEdges = (members.length * (members.length - 1)) / 2; + const density = possibleEdges === 0 ? 0 : internalEdges / possibleEdges; + if (density < 0.15) { + sparseCommunities.push({ + id: communityId, + label: nodesById[communityId]?.label || communityId, + node_count: members.length, + density: roundNumber(density), + members: members.sort(), + internal_edges: internalEdges + }); + } + } + + const surprisingConnections = Array.from(undirectedPairs.values()) + .filter((pair) => { + const fromCommunity = communityAssignments.get(pair.from) || null; + const toCommunity = communityAssignments.get(pair.to) || null; + return fromCommunity && toCommunity && fromCommunity !== toCommunity && pair.weight >= 0.75; + }) + .sort((left, right) => { + if (right.weight !== left.weight) return right.weight - left.weight; + if (left.from !== right.from) return left.from.localeCompare(right.from); + return left.to.localeCompare(right.to); + }) + .slice(0, 8) + .map((pair) => ({ + from: pair.from, + to: pair.to, + weight: pair.weight, + from_community: communityAssignments.get(pair.from) || null, + to_community: communityAssignments.get(pair.to) || null + })); + + const degraded = options.nodeCount > options.maxInsightNodes || options.edgeCount > options.maxInsightEdges; + if (degraded) { + return { + surprising_connections: [], + isolated_nodes: isolatedNodes, + bridge_nodes: [], + sparse_communities: [], + meta: { + degraded: true, + node_count: options.nodeCount, + edge_count: options.edgeCount, + max_insight_nodes: options.maxInsightNodes, + max_insight_edges: options.maxInsightEdges + } + }; + } + + return { + surprising_connections: surprisingConnections, + isolated_nodes: isolatedNodes, + bridge_nodes: bridgeNodes, + sparse_communities: sparseCommunities, + meta: { + degraded: false, + node_count: options.nodeCount, + edge_count: options.edgeCount, + max_insight_nodes: options.maxInsightNodes, + max_insight_edges: options.maxInsightEdges + } + }; +} + +function buildLearning(analyzedNodes, analyzedEdges) { + const degreeMap = new Map(); + for (const edge of analyzedEdges) { + degreeMap.set(edge.from, (degreeMap.get(edge.from) || 0) + 1); + degreeMap.set(edge.to, (degreeMap.get(edge.to) || 0) + 1); + } + + const communityGroups = new Map(); + for (const node of analyzedNodes) { + if (node.community == null) continue; + if (!communityGroups.has(node.community)) communityGroups.set(node.community, []); + communityGroups.get(node.community).push(node); + } + + const communities = []; + for (const [cid, members] of communityGroups.entries()) { + const memberIds = new Set(members.map(n => n.id)); + let totalWeight = 0; + for (const edge of analyzedEdges) { + if (memberIds.has(edge.from) && memberIds.has(edge.to)) totalWeight += edge.weight; + } + const isWeak = members.length < 3; + const startNode = members.slice().sort((a, b) => { + const degDiff = (degreeMap.get(b.id) || 0) - (degreeMap.get(a.id) || 0); + if (degDiff !== 0) return degDiff; + return a.id.localeCompare(b.id); + })[0]; + + communities.push({ + id: cid, + label: (members.find(n => n.id === cid) || members[0]).label, + node_count: members.length, + source_count: members.filter(n => n.type === "source").length, + internal_edge_weight: roundNumber(totalWeight), + is_primary: false, + is_weak: isWeak, + recommended_start_node_id: startNode.id + }); + } + + communities.sort((a, b) => { + if (b.node_count !== a.node_count) return b.node_count - a.node_count; + if (b.internal_edge_weight !== a.internal_edge_weight) return b.internal_edge_weight - a.internal_edge_weight; + return a.id.localeCompare(b.id); + }); + + if (communities.length > 0) communities[0].is_primary = true; + + const primary = communities.length > 0 ? communities[0] : null; + const startNodeId = primary ? primary.recommended_start_node_id : null; + + let pathNodeIds = []; + let pathDegraded = false; + if (primary && !primary.is_weak && startNodeId) { + const primaryMemberIds = new Set(communityGroups.get(primary.id).map(n => n.id)); + const neighbors = analyzedEdges + .filter(e => (e.from === startNodeId && primaryMemberIds.has(e.to)) || + (e.to === startNodeId && primaryMemberIds.has(e.from))) + .map(e => e.from === startNodeId ? e.to : e.from); + pathNodeIds = [startNodeId, ...sortedUnique(neighbors).filter(id => id !== startNodeId)]; + if (pathNodeIds.length < 2) pathDegraded = true; + } else { + pathDegraded = true; + } + + let communityNodeIds = []; + let communityDegraded = false; + if (primary && !primary.is_weak) { + communityNodeIds = communityGroups.get(primary.id).map(n => n.id).sort(); + } else { + communityDegraded = true; + } + + const globalNodeIds = analyzedNodes.slice().sort((a, b) => { + const degDiff = (degreeMap.get(b.id) || 0) - (degreeMap.get(a.id) || 0); + if (degDiff !== 0) return degDiff; + return a.id.localeCompare(b.id); + }).map(n => n.id); + + const defaultMode = "global"; + + return { + version: 1, + entry: { + recommended_start_node_id: startNodeId, + recommended_start_reason: startNodeId ? "community_hub" : null, + default_mode: defaultMode + }, + views: { + path: { + enabled: !pathDegraded, + start_node_id: pathDegraded ? null : startNodeId, + node_ids: pathDegraded ? [] : pathNodeIds, + degraded: pathDegraded + }, + community: { + enabled: !communityDegraded, + community_id: primary && !communityDegraded ? primary.id : null, + label: primary && !communityDegraded ? primary.label : null, + node_ids: communityDegraded ? [] : communityNodeIds, + is_weak: primary ? primary.is_weak : false, + degraded: communityDegraded + }, + global: { + enabled: true, + node_ids: globalNodeIds, + degraded: false + } + }, + communities, + degraded: { + path_to_community: pathDegraded, + community_to_global: communityDegraded + } + }; +} + +function analyzeGraph(nodes, edges, options = {}) { + const degraded = options.degraded === true; + const maxLines = options.maxLines || 500; + const maxInsightNodes = options.maxInsightNodes || 250; + const maxInsightEdges = options.maxInsightEdges || 1000; + + const nodesById = loadNodeDetails(nodes, degraded, maxLines); + const pairMetrics = computePairMetrics(nodesById, edges); + const nodeIds = nodes.map((node) => node.id); + const communityAssignments = chooseCommunityLabels( + nodeIds, + runLouvain(nodeIds, pairMetrics), + nodesById, + edges + ); + + const analyzedNodes = nodes.map((node) => ({ + id: node.id, + label: node.label, + type: node.type, + source_path: node.source_path, + community: communityAssignments.get(node.id) || null, + content: nodesById[node.id].content + })); + + const analyzedEdges = edges.map((edge) => { + const pairKey = sortedPairKey(edge.from, edge.to); + const metrics = pairMetrics.get(pairKey) || { + weight: 0, + signals: { co_citation: 0, source_overlap: null, type_affinity: 0.5 }, + source_signal_available: false + }; + + return { + id: edge.id, + from: edge.from, + to: edge.to, + type: edge.type, + confidence: edge.confidence || edge.type, + relation_type: edge.relation_type || "依赖", + weight: metrics.weight, + source_signal_available: metrics.source_signal_available, + signals: metrics.signals + }; + }); + + const insights = buildInsights(nodesById, analyzedEdges, pairMetrics, communityAssignments, { + nodeCount: analyzedNodes.length, + edgeCount: analyzedEdges.length, + maxInsightNodes, + maxInsightEdges + }); + + const learning = buildLearning(analyzedNodes, analyzedEdges); + + return { nodes: analyzedNodes, edges: analyzedEdges, insights, learning }; +} + +function main(argv) { + if (argv.length < 7) { + console.error("Usage: node graph-analysis.js "); + process.exit(1); + } + + const timer = setTimeout(() => { + console.error("ERROR: graph analysis timed out (120s)"); + process.exit(2); + }, 120_000); + timer.unref(); + + const [, , nodesPath, edgesPath, outputPath, degradedRaw, maxLinesRaw, maxInsightNodesRaw, maxInsightEdgesRaw] = argv; + + for (const p of [nodesPath, edgesPath]) { + if (!fs.existsSync(p)) { + console.error(`ERROR: File not found: ${p}`); + process.exit(1); + } + } + + const analyzed = analyzeGraph(readJson(nodesPath), readJson(edgesPath), { + degraded: degradedRaw === "1", + maxLines: Number(maxLinesRaw) || 500, + maxInsightNodes: Number(maxInsightNodesRaw) || 250, + maxInsightEdges: Number(maxInsightEdgesRaw) || 1000 + }); + + writeJson(outputPath, analyzed); + clearTimeout(timer); +} + +if (require.main === module) { + try { + main(process.argv); + } catch (error) { + const code = error && error.code; + if (code === "ENOENT") { + console.error(`ERROR: File not found: ${error.path || "(unknown)"}`); + } else if (error instanceof SyntaxError) { + console.error(`ERROR: Invalid JSON in input: ${error.message}`); + } else { + console.error(`ERROR: ${error && error.message ? error.message : String(error)}`); + } + process.exit(1); + } +} + +module.exports = { + analyzeGraph, + buildInsights, + buildLearning, + chooseCommunityLabels, + computePairMetrics, + extractFrontmatter, + normalizeBody, + parseSourcesFrontmatter, + runLouvain, + typeAffinity +}; diff --git a/graphify/bundled_skills/llm-wiki/scripts/hook-session-start.sh b/graphify/bundled_skills/llm-wiki/scripts/hook-session-start.sh new file mode 100755 index 000000000..df405038b --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/hook-session-start.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# SessionStart hook: 会话开始时注入 wiki 上下文(只触发一次) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/shared-config.sh" + +WIKI_PATH="" + +if [ -f "$HOME/.llm-wiki-path" ]; then + WIKI_PATH="$(cat "$HOME/.llm-wiki-path")" +fi + +if [ -z "$WIKI_PATH" ] && [ -f .wiki-schema.md ]; then + WIKI_PATH="$(pwd)" +fi + +if [ -z "$WIKI_PATH" ] || [ ! -f "$WIKI_PATH/.wiki-schema.md" ]; then + printf '{}\n' + exit 0 +fi + +require_python_cmd + +"$PYTHON_CMD" - "$WIKI_PATH" <<'PY' +import json +import os +import sys + +# 防御性:即使上游 shared-config.sh 未设置 PYTHONIOENCODING, +# 此处也强制 stdout 为 UTF-8,避免 Agent 接到 gbk 字节 +if hasattr(sys.stdout, "reconfigure"): + sys.stdout.reconfigure(encoding="utf-8") + +wiki_path = os.path.realpath(sys.argv[1]) +message = f"[llm-wiki] 检测到知识库: {wiki_path}/index.md,回答问题时优先查阅 wiki 内容获取上下文" + +print(json.dumps({ + "hookSpecificOutput": { + "hookEventName": "SessionStart", + "additionalContext": message, + } +}, ensure_ascii=False)) +PY diff --git a/graphify/bundled_skills/llm-wiki/scripts/init-wiki.sh b/graphify/bundled_skills/llm-wiki/scripts/init-wiki.sh new file mode 100755 index 000000000..3e8bf9dbb --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/init-wiki.sh @@ -0,0 +1,95 @@ +#!/bin/bash +# llm-wiki 初始化脚本 +# 自动创建知识库的目录结构 +# 用法:bash init-wiki.sh <知识库路径> <主题> + +set -e + +WIKI_ROOT="${1:-$HOME/Documents/我的知识库}" +TOPIC="${2:-我的知识库}" +LANGUAGE="${3:-中文}" +DATE=$(date +%Y-%m-%d) +SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +# 安全的模板变量替换函数(用 perl 替代 sed,避免中文/空格/特殊字符问题) +replace_vars() { + local input_file="$1" + local output_file="$2" + TOPIC_VALUE="$TOPIC" \ + DATE_VALUE="$DATE" \ + WIKI_ROOT_VALUE="$WIKI_ROOT" \ + LANGUAGE_VALUE="$LANGUAGE" \ + perl -pe ' + s/\{\{TOPIC\}\}/$ENV{TOPIC_VALUE}/g; + s/\{\{DATE\}\}/$ENV{DATE_VALUE}/g; + s/\{\{WIKI_ROOT\}\}/$ENV{WIKI_ROOT_VALUE}/g; + s/\{\{LANGUAGE\}\}/$ENV{LANGUAGE_VALUE}/g; + ' "$input_file" > "$output_file" +} + +echo "正在创建知识库..." +echo " 路径:$WIKI_ROOT" +echo " 主题:$TOPIC" +echo " 语言:$LANGUAGE" +echo "" + +# 创建目录结构(包含小红书和知乎) +mkdir -p "$WIKI_ROOT"/raw/{articles,tweets,wechat,xiaohongshu,zhihu,pdfs,notes,assets} +mkdir -p "$WIKI_ROOT"/wiki/{entities,topics,sources,comparisons,synthesis,synthesis/sessions,queries} + +cat > "$WIKI_ROOT/.gitignore" <<'EOF' +.wiki-tmp/ +EOF + +echo "[完成] 目录结构已创建" + +# 从模板生成文件 +replace_vars "$SKILL_DIR/templates/schema-template.md" "$WIKI_ROOT/.wiki-schema.md" +echo "[完成] Schema 文件已生成" + +replace_vars "$SKILL_DIR/templates/index-template.md" "$WIKI_ROOT/index.md" +echo "[完成] 索引文件已生成" + +replace_vars "$SKILL_DIR/templates/log-template.md" "$WIKI_ROOT/log.md" +echo "[完成] 日志文件已生成" + +replace_vars "$SKILL_DIR/templates/overview-template.md" "$WIKI_ROOT/wiki/overview.md" +echo "[完成] 总览文件已生成" + +if [ "$LANGUAGE" = "English" ]; then + replace_vars "$SKILL_DIR/templates/purpose-en-template.md" "$WIKI_ROOT/purpose.md" +else + replace_vars "$SKILL_DIR/templates/purpose-template.md" "$WIKI_ROOT/purpose.md" +fi +echo "[完成] 研究方向文件已生成" + +cat > "$WIKI_ROOT/.wiki-cache.json" <<'EOF' +{ + "version": 1, + "entries": {} +} +EOF +echo "[完成] 缓存文件已生成" + +echo "" +echo "知识库创建完成!" +echo "" +echo "目录结构:" +echo " $WIKI_ROOT/" +echo " ├── raw/ (原始素材)" +echo " │ ├── articles/ 网页文章" +echo " │ ├── tweets/ X/Twitter" +echo " │ ├── wechat/ 微信公众号" +echo " │ ├── xiaohongshu/ 小红书" +echo " │ ├── zhihu/ 知乎" +echo " │ ├── pdfs/ PDF" +echo " │ ├── notes/ 笔记" +echo " │ └── assets/ 图片等附件" +echo " ├── wiki/ (知识库)" +echo " ├── index.md (索引)" +echo " ├── log.md (日志)" +echo " ├── purpose.md (研究方向)" +echo " ├── .wiki-cache.json (缓存)" +echo " └── .wiki-schema.md (配置)" +echo "" +echo "下一步:给 agent 一个链接或文件,开始构建知识库!" diff --git a/graphify/bundled_skills/llm-wiki/scripts/lib/source-signal-eligibility.js b/graphify/bundled_skills/llm-wiki/scripts/lib/source-signal-eligibility.js new file mode 100644 index 000000000..22b35ad77 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/lib/source-signal-eligibility.js @@ -0,0 +1,158 @@ +#!/usr/bin/env node +"use strict"; + +const SCAN_KINDS = [ + { subdir: "entities", pageType: "entity", applicable: true }, + { subdir: "topics", pageType: "topic", applicable: true }, + { subdir: "sources", pageType: "source", applicable: true }, + { subdir: "comparisons", pageType: "comparison", applicable: true }, + { subdir: "queries", pageType: "query", applicable: false }, + { subdir: "synthesis", pageType: "synthesis", applicable: false } +]; + +function sortedUnique(values) { + return Array.from(new Set(values)).sort(); +} + +function extractFrontmatter(text) { + if (!text.startsWith("---\n") && !text.startsWith("---\r\n")) { + return { hasFrontmatter: false, frontmatter: "", body: text }; + } + + const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/); + if (!match) { + return { hasFrontmatter: false, frontmatter: "", body: text }; + } + + return { + hasFrontmatter: true, + frontmatter: match[1], + body: match[2] + }; +} + +function normalizeSourceToken(token) { + const trimmed = String(token || "").trim(); + if (!trimmed) return null; + + let value = trimmed; + if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { + value = value.slice(1, -1).trim(); + } + + return value || null; +} + +function parseInlineSources(raw) { + const trimmed = raw.trim(); + if (trimmed === "[]") return { ok: true, values: [] }; + if (!(trimmed.startsWith("[") && trimmed.endsWith("]"))) { + return { ok: false, values: [] }; + } + + const inner = trimmed.slice(1, -1).trim(); + if (!inner) return { ok: true, values: [] }; + + const values = inner + .split(",") + .map(normalizeSourceToken) + .filter(Boolean); + + return { ok: true, values }; +} + +function parseSourcesFrontmatter(frontmatter) { + if (!frontmatter) { + return { hasField: false, parsed: false, sources: [], signalAvailable: false }; + } + + const lines = frontmatter.split(/\r?\n/); + + for (let index = 0; index < lines.length; index += 1) { + const match = lines[index].match(/^sources:\s*(.*)$/); + if (!match) continue; + + const rest = match[1].trim(); + if (rest) { + if (!rest.startsWith("[")) { + const single = normalizeSourceToken(rest); + return { + hasField: true, + parsed: Boolean(single), + sources: single ? [single] : [], + signalAvailable: Boolean(single) + }; + } + + const parsedInline = parseInlineSources(rest); + return { + hasField: true, + parsed: parsedInline.ok, + sources: parsedInline.ok ? sortedUnique(parsedInline.values) : [], + signalAvailable: parsedInline.ok && parsedInline.values.length > 0 + }; + } + + const collected = []; + let parsed = true; + let consumed = 0; + + for (let cursor = index + 1; cursor < lines.length; cursor += 1) { + const line = lines[cursor]; + if (!line.trim()) { + consumed += 1; + continue; + } + if (/^[^\s-]/.test(line)) break; + const itemMatch = line.match(/^\s*-\s*(.+)$/); + if (!itemMatch) { + parsed = false; + consumed += 1; + continue; + } + const token = normalizeSourceToken(itemMatch[1]); + if (token) collected.push(token); + consumed += 1; + } + + index += consumed; + return { + hasField: true, + parsed, + sources: parsed ? sortedUnique(collected) : [], + signalAvailable: parsed && collected.length > 0 + }; + } + + return { hasField: false, parsed: false, sources: [], signalAvailable: false }; +} + +function evaluateSourceSignalEligibility({ pageType, frontmatter }) { + const kind = SCAN_KINDS.find((k) => k.pageType === pageType); + if (!kind || !kind.applicable) { + return { eligible: false, reason: "not_applicable", sources: [] }; + } + + const parsed = parseSourcesFrontmatter(frontmatter); + + if (!parsed.hasField) { + return { eligible: false, reason: "missing_sources", sources: [] }; + } + if (!parsed.parsed) { + return { eligible: false, reason: "invalid_sources", sources: [] }; + } + if (parsed.sources.length === 0) { + return { eligible: false, reason: "empty_sources", sources: [] }; + } + + return { eligible: true, reason: "ok", sources: parsed.sources }; +} + +module.exports = { + SCAN_KINDS, + extractFrontmatter, + evaluateSourceSignalEligibility, + normalizeSourceToken, + parseSourcesFrontmatter, + sortedUnique +}; diff --git a/graphify/bundled_skills/llm-wiki/scripts/lint-fix.sh b/graphify/bundled_skills/llm-wiki/scripts/lint-fix.sh new file mode 100755 index 000000000..b0982ddc4 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/lint-fix.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# lint-fix.sh — 自动修复 lint 发现的低风险问题 +# 用法:bash scripts/lint-fix.sh [--dry-run] +# 修复范围:仅处理确定性修复(补 index 条目),不做高风险操作(删页面、改内容) +# 退出码:0 = 完成,1 = 参数错误 + +set -u +shopt -s nullglob + +WIKI_ROOT="${1:-.}" +DRY_RUN=false +[ "${2:-}" = "--dry-run" ] && DRY_RUN=true + +WIKI_DIR="$WIKI_ROOT/wiki" +INDEX_FILE="$WIKI_ROOT/index.md" + +if [ ! -d "$WIKI_DIR" ]; then + echo "ERROR: wiki directory not found: $WIKI_DIR" >&2 + exit 1 +fi +if [ ! -f "$INDEX_FILE" ]; then + echo "ERROR: index.md not found: $INDEX_FILE" >&2 + exit 1 +fi + +FIXED=0 + +index_has_entry() { + local entry="$1" + grep -ohE "\[\[[^]]+\]\]" "$INDEX_FILE" 2>/dev/null | \ + sed -e 's/\[\[//g' -e 's/\]\]//g' -e 's/|.*//' | \ + grep -Fxq "$entry" +} + +# Insert a [[link]] entry after the matching section header in index.md. +# If no matching section is found, appends to end of file as fallback. +insert_under_section() { + local index_file="$1" + local section_pattern="$2" + local entry="$3" + + # Find the line number of the section header + local line_num + line_num=$(grep -n -i -E "^#.*($section_pattern)" "$index_file" 2>/dev/null | head -1 | cut -d: -f1) + + if [ -n "$line_num" ]; then + # Scan from section header to find insert point: + # last "- [[" line before next "##" header or EOF + local total_lines last_list_line offset + total_lines=$(wc -l < "$index_file" | tr -d ' ') + last_list_line="$line_num" + offset=$((line_num + 1)) + while [ "$offset" -le "$total_lines" ]; do + local cur_line + cur_line=$(sed -n "${offset}p" "$index_file") + case "$cur_line" in + "##"*) break ;; + "- [["*) last_list_line="$offset" ;; + esac + offset=$((offset + 1)) + done + # Insert after the last list item + local tmp_file + tmp_file=$(mktemp "${index_file}.tmp.XXXXXX") || return 1 + awk -v insert_after="$last_list_line" -v entry="$entry" ' + { print } + NR == insert_after { print "- [[" entry "]]" } + ' "$index_file" > "$tmp_file" && mv "$tmp_file" "$index_file" + else + # Fallback: append to end of file + printf '\n- [[%s]]\n' "$entry" >> "$index_file" + fi +} + +echo "=== lint-fix: low-risk auto-repair ===" +echo "" + +# Fix 1: Add unlisted pages to index.md +# Only adds pages that exist in wiki/ but are not referenced in index.md +# Skips derived pages (queries/, sessions/) +echo "--- Checking for unlisted pages ---" +for _subdir in entities topics sources comparisons synthesis; do + for f in "$WIKI_DIR"/$_subdir/*.md; do + [ -f "$f" ] || continue + BASENAME=$(basename "$f" .md) + # Skip derived pages + case "$f" in + */queries/*|*/sessions/*) continue ;; + esac + if ! index_has_entry "$BASENAME"; then + SECTION_PATTERN="" + case "$_subdir" in + entities) SECTION_PATTERN="实体页|Entities" ;; + topics) SECTION_PATTERN="主题页|Topics" ;; + sources) SECTION_PATTERN="素材摘要|Sources" ;; + comparisons) SECTION_PATTERN="对比分析|Comparisons" ;; + synthesis) SECTION_PATTERN="综合分析|Synthesis" ;; + esac + if [ "$DRY_RUN" = true ]; then + echo " [dry-run] Would add [[$BASENAME]] under $_subdir section" + else + insert_under_section "$INDEX_FILE" "$SECTION_PATTERN" "$BASENAME" + echo " Fixed: added [[$BASENAME]] under $_subdir section" + fi + FIXED=$((FIXED + 1)) + fi + done +done +[ "$FIXED" -eq 0 ] && echo " (all pages already listed)" +echo "" + +echo "=== lint-fix complete: $FIXED fix(es) applied ===" +[ "$DRY_RUN" = true ] && echo "(dry-run mode — no files were modified)" +exit 0 diff --git a/graphify/bundled_skills/llm-wiki/scripts/lint-runner.sh b/graphify/bundled_skills/llm-wiki/scripts/lint-runner.sh new file mode 100755 index 000000000..b2ec87f3b --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/lint-runner.sh @@ -0,0 +1,217 @@ +#!/bin/bash +# lint-runner.sh — wiki 机械健康检查 +# 用法:bash scripts/lint-runner.sh +# 输出:结构化文本报告(供 AI 后续分析使用) +# 退出码:0 = 运行完成,1 = 脚本错误(路径不存在、wiki 结构不完整) + +set -u +shopt -s nullglob + +WIKI_ROOT="${1:-.}" +WIKI_DIR="$WIKI_ROOT/wiki" +INDEX_FILE="$WIKI_ROOT/index.md" + +if [ ! -d "$WIKI_DIR" ]; then + echo "ERROR: wiki 目录不存在:$WIKI_DIR" >&2 + echo " 请确认路径正确,或先运行 init 工作流初始化知识库。" >&2 + exit 1 +fi +if [ ! -f "$INDEX_FILE" ]; then + echo "ERROR: index.md 不存在:$INDEX_FILE" >&2 + exit 1 +fi + +index_has_entry() { + local entry="$1" + grep -ohE "\[\[[^]]+\]\]" "$INDEX_FILE" 2>/dev/null | \ + sed -e 's/\[\[//g' -e 's/\]\]//g' -e 's/|.*//' | \ + grep -Fxq "$entry" +} + +echo "=== llm-wiki lint 报告 ===" +echo "时间:$(date '+%Y-%m-%d %H:%M')" +echo "检查路径:$WIKI_DIR" +echo "" + +# 检查 1:孤立页面 +# 定义:entities/、topics/、sources/ 下的页面,除了自己之外没有任何其他 wiki 页面用 [[名称]] 引用它 +echo "--- 孤立页面(没有被其他页面引用) ---" +_ORPHANS=0 +for _subdir in entities topics sources; do + for f in "$WIKI_DIR"/$_subdir/*.md; do + [ -f "$f" ] || continue + BASENAME=$(basename "$f" .md) + if ! grep -rlF "[[$BASENAME]]" "$WIKI_DIR" 2>/dev/null | grep -vxF "$f" | grep -q .; then + echo " 孤立: $_subdir/$BASENAME" + _ORPHANS=$((_ORPHANS + 1)) + fi + done +done +[ "$_ORPHANS" -eq 0 ] && echo " (无孤立页面)" +echo "" + +# 检查 2:断链 +# 定义:wiki/ 下的页面里有 [[X]] 链接(支持 [[X|别名]] 语法),但 wiki/ 任意子目录找不到 X.md +echo "--- 断链(被链接但不存在的页面) ---" +_TMP_BROKEN=$(mktemp) +grep -rohE "\[\[[^]]+\]\]" "$WIKI_DIR" 2>/dev/null | \ + sed -e 's/\[\[//g' -e 's/\]\]//g' -e 's/|.*//' | \ + sort -u | \ + while read -r LINK; do + [ -z "$LINK" ] && continue + if ! find "$WIKI_DIR" -name "$LINK.md" 2>/dev/null | grep -q .; then + echo " 断链: [[$LINK]]" + echo "$LINK" >> "$_TMP_BROKEN" + fi + done +if [ ! -s "$_TMP_BROKEN" ]; then + echo " (无断链)" +fi +rm -f "$_TMP_BROKEN" +echo "" + +# 检查 3:index 一致性 +# 定义:index.md 里有 [[X]] 记录(去掉别名),但 wiki/ 任意子目录都找不到 X.md +echo "--- index 一致性(index.md 有记录但文件缺失) ---" +_TMP_MISSING=$(mktemp) +grep -ohE "\[\[[^]]+\]\]" "$INDEX_FILE" 2>/dev/null | \ + sed -e 's/\[\[//g' -e 's/\]\]//g' -e 's/|.*//' | \ + sort -u | \ + while read -r ENTRY; do + [ -z "$ENTRY" ] && continue + if ! find "$WIKI_DIR" -name "$ENTRY.md" 2>/dev/null | grep -q .; then + echo " index 有但文件缺失: $ENTRY" + echo "$ENTRY" >> "$_TMP_MISSING" + fi + done +if [ ! -s "$_TMP_MISSING" ]; then + echo " (index 与文件一致)" +fi +rm -f "$_TMP_MISSING" +echo "" + +# 检查 4:反向 index 一致性 +# 定义:wiki/ 下实际存在的页面,但 index.md 里没有 [[页面名]] 记录 +# 排除 derived 页面(queries/、synthesis/sessions/) +echo "--- 反向 index 一致性(文件存在但 index.md 未收录) ---" +_TMP_UNLISTED=$(mktemp) +for _subdir in entities topics sources comparisons synthesis; do + for f in "$WIKI_DIR"/$_subdir/*.md; do + [ -f "$f" ] || continue + BASENAME=$(basename "$f" .md) + # 跳过 derived 页面 + case "$f" in + */queries/*|*/sessions/*) continue ;; + esac + if ! index_has_entry "$BASENAME"; then + echo " 未收录: $_subdir/$BASENAME" + echo "$BASENAME" >> "$_TMP_UNLISTED" + fi + done +done +if [ ! -s "$_TMP_UNLISTED" ]; then + echo " (所有页面均已收录)" +fi +rm -f "$_TMP_UNLISTED" +echo "" + +# 检查 5:图片资产一致性 +# 定义:source 页面 frontmatter 中 image_paths 列出的文件,在知识库中是否实际存在 +# 支持 block list 格式和 inline array 格式 +echo "--- 图片资产一致性(image_paths 声明但文件缺失) ---" +_IMG_ISSUES=0 +for f in "$WIKI_DIR"/sources/*.md; do + [ -f "$f" ] || continue + _BASENAME=$(basename "$f" .md) + # 提取 frontmatter 中 image_paths 的值 + _IN_FM=false + _IN_IMG=false + _INLINE_VAL="" + while IFS= read -r line; do + case "$line" in + "---") + if [ "$_IN_FM" = true ]; then break; fi + _IN_FM=true + continue + ;; + esac + [ "$_IN_FM" = true ] || continue + case "$line" in + image_paths:*) + # 检查是否有 inline value(如 image_paths: ["a.png", "b.jpg"]) + _INLINE_VAL=$(echo "$line" | sed 's/^image_paths:[[:space:]]*//') + if [ -n "$_INLINE_VAL" ] && [ "$_INLINE_VAL" != "[]" ]; then + # 解析 inline array:去掉 [],按逗号分割 + echo "$_INLINE_VAL" | tr -d '[]' | tr ',' '\n' | while IFS= read -r _ITEM; do + _PATH=$(echo "$_ITEM" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//' | tr -d '"' | tr -d "'") + [ -z "$_PATH" ] && continue + if [ ! -f "$WIKI_ROOT/$_PATH" ]; then + echo " 缺失: $_BASENAME → $_PATH" + fi + done + _INLINE_COUNT=$(echo "$_INLINE_VAL" | tr -d '[]' | tr ',' '\n' | while IFS= read -r _ITEM; do + _P=$(echo "$_ITEM" | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//' | tr -d '"' | tr -d "'") + [ -z "$_P" ] && continue + [ ! -f "$WIKI_ROOT/$_P" ] && echo "x" + done | wc -l | tr -d ' ') + _IMG_ISSUES=$((_IMG_ISSUES + _INLINE_COUNT)) + _IN_IMG=false + else + _IN_IMG=true + fi + continue + ;; + " - "*) + if [ "$_IN_IMG" = true ]; then + _PATH=$(echo "$line" | sed 's/^[[:space:]]*- //' | sed 's/^[[:space:]]*//' | sed 's/[[:space:]]*$//' | tr -d '"' | tr -d "'") + [ -z "$_PATH" ] && continue + if [ ! -f "$WIKI_ROOT/$_PATH" ]; then + echo " 缺失: $_BASENAME → $_PATH" + _IMG_ISSUES=$((_IMG_ISSUES + 1)) + fi + fi + ;; + *) _IN_IMG=false ;; + esac + done < "$f" +done +[ "$_IMG_ISSUES" -eq 0 ] && echo " (无缺失图片)" +echo "" + +# 检查 6:source-signal 覆盖情况 +echo "--- source-signal 覆盖情况 ---" +_COVERAGE_SCRIPT="$(cd "$(dirname "$0")" && pwd)/source-signal-coverage.js" +if [ -f "$_COVERAGE_SCRIPT" ] && command -v node >/dev/null 2>&1; then + _COVERAGE_JSON=$(node "$_COVERAGE_SCRIPT" "$WIKI_ROOT" 2>/dev/null) + if [ $? -eq 0 ] && [ -n "$_COVERAGE_JSON" ]; then + node -e ' + const data = JSON.parse(require("fs").readFileSync("/dev/stdin", "utf8")); + const s = data.summary; + console.log(" 已参与:" + s.ok); + console.log(" 缺少 sources 字段:" + s.missing_sources); + console.log(" sources 为空:" + s.empty_sources); + console.log(" sources 格式无效:" + s.invalid_sources); + console.log(" 当前不参与:" + s.not_applicable); + const issues = data.pages.filter(p => p.reason !== "ok" && p.reason !== "not_applicable"); + if (issues.length > 0) { + const byReason = { missing_sources: [], empty_sources: [], invalid_sources: [] }; + for (const p of issues) { if (byReason[p.reason]) byReason[p.reason].push(p.path); } + for (const [reason, paths] of Object.entries(byReason)) { + if (paths.length === 0) continue; + const label = { missing_sources: "缺少 sources 字段", empty_sources: "sources 为空", invalid_sources: "sources 格式无效" }[reason]; + console.log(""); + console.log(" " + label + ":"); + for (const p of paths) console.log(" - " + p); + } + } + ' <<< "$_COVERAGE_JSON" + else + echo " (coverage 脚本执行失败,跳过覆盖检查)" + fi +else + echo " (coverage 脚本或 node 不可用,跳过覆盖检查)" +fi +echo "" + +echo "=== 机械检查完成。矛盾检测、交叉引用、置信度抽查由 AI 继续执行 ===" +exit 0 diff --git a/graphify/bundled_skills/llm-wiki/scripts/runtime-context.sh b/graphify/bundled_skills/llm-wiki/scripts/runtime-context.sh new file mode 100644 index 000000000..912c69745 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/runtime-context.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# 共享运行场景解析:供 install.sh 和 adapter-state.sh 复用 + +resolve_platform_skill_root() { + case "$1" in + claude) + printf '%s\n' "$HOME/.claude/skills" + ;; + codex) + if [ -d "$HOME/.codex/skills" ] || [ ! -d "$HOME/.Codex/skills" ]; then + printf '%s\n' "$HOME/.codex/skills" + else + printf '%s\n' "$HOME/.Codex/skills" + fi + ;; + openclaw) + printf '%s\n' "$HOME/.openclaw/skills" + ;; + hermes) + printf '%s\n' "$HOME/.hermes/skills" + ;; + *) + echo "不支持的平台:$1" >&2 + return 1 + ;; + esac +} + +detect_layout_mode() { + local bundle_root="$1" + + if [ -e "$bundle_root/.git" ]; then + printf '%s\n' "source_checkout" + return 0 + fi + + printf '%s\n' "installed_skill" +} + +resolve_layout_mode() { + local bundle_root="$1" + local override_mode="${2:-}" + + if [ -n "$override_mode" ]; then + printf '%s\n' "$override_mode" + return 0 + fi + + detect_layout_mode "$bundle_root" +} + +resolve_optional_adapter_root() { + local bundle_root="$1" + local skill_root_override="${2:-}" + local override_mode="${3:-}" + local layout_mode + + if [ -n "$skill_root_override" ]; then + printf '%s\n' "$skill_root_override" + return 0 + fi + + layout_mode="$(resolve_layout_mode "$bundle_root" "$override_mode")" + + case "$layout_mode" in + source_checkout) + printf '%s\n' "$bundle_root/deps" + ;; + installed_skill|upgrade_target) + printf '%s\n' "$(dirname "$bundle_root")" + ;; + *) + echo "未知运行模式:$layout_mode" >&2 + return 1 + ;; + esac +} diff --git a/graphify/bundled_skills/llm-wiki/scripts/shared-config.sh b/graphify/bundled_skills/llm-wiki/scripts/shared-config.sh new file mode 100644 index 000000000..91cea78db --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/shared-config.sh @@ -0,0 +1,83 @@ +#!/bin/bash +# 共享配置:被 install.sh / hook-session-start.sh / cache.sh / delete-helper.sh 等引用 +# 微信公众号提取工具的 Git 仓库地址 +WECHAT_TOOL_URL="git+https://github.com/jackwener/wechat-article-to-markdown.git" + +# Python 命令检测:Windows 默认安装为 python.exe,不存在 python3 命令 +# (Microsoft Store 的 python3 是安装提示 stub,运行会失败) +_python_version_check='import sys; sys.exit(0 if sys.version_info >= (3, 8) else 1)' + +_python_cmd_is_valid() { + local candidate="$1" + + command -v "$candidate" >/dev/null 2>&1 && "$candidate" -c "$_python_version_check" >/dev/null 2>&1 +} + +_detect_python_cmd() { + # 要求 Python 3.8+(见 README Windows 小节与下方错误消息) + if _python_cmd_is_valid python3; then + echo "python3" + elif _python_cmd_is_valid python; then + echo "python" + else + echo "" + fi +} + +require_python_cmd() { + local detected_cmd + + if [ "${PYTHON_CMD_READY:-0}" = "1" ]; then + return 0 + fi + + if [ -n "${PYTHON_CMD:-}" ] && _python_cmd_is_valid "$PYTHON_CMD"; then + export PYTHON_CMD + PYTHON_CMD_READY=1 + return 0 + fi + + detected_cmd="$(_detect_python_cmd)" + if [ -z "$detected_cmd" ]; then + echo "[llm-wiki] 错误:找不到可用的 Python 3,请先安装 Python 3.8+ 并加入 PATH" >&2 + return 1 + fi + + PYTHON_CMD="$detected_cmd" + export PYTHON_CMD + PYTHON_CMD_READY=1 +} + +# 统一 Python 子进程 stdout/stderr 编码为 UTF-8 +# Windows 中文环境下 Python 无 TTY 时 sys.stdout.encoding 默认 gbk (cp936), +# 会导致 Agent 通过 subprocess 读取的 JSON / 输出出现乱码 (issue #16) +export PYTHONIOENCODING="${PYTHONIOENCODING:-utf-8}" + +# 输出指定工具的跨平台安装提示,缩进 2 空格便于嵌套在 ERROR 消息下; +# 输出走 stderr,与 ERROR 消息保持同一通道。 +print_install_hint() { + local tool="$1" + case "$tool" in + jq) + echo " macOS: brew install jq" >&2 + echo " Linux/WSL: sudo apt-get install jq (Debian/Ubuntu)" >&2 + echo " sudo dnf install jq (RHEL/Fedora)" >&2 + echo " Windows: winget install jqlang.jq (or choco install jq)" >&2 + ;; + node) + echo " macOS: brew install node" >&2 + echo " Linux/WSL: sudo apt-get install nodejs npm" >&2 + echo " Windows: winget install OpenJS.NodeJS (or choco install nodejs)" >&2 + ;; + uv) + echo " macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh (official)" >&2 + echo " brew install uv (alternative)" >&2 + echo " Windows: powershell -c \"irm https://astral.sh/uv/install.ps1 | iex\" (official)" >&2 + echo " winget install --id=astral-sh.uv -e (alternative)" >&2 + ;; + *) + echo " unknown tool: $tool" >&2 + return 1 + ;; + esac +} diff --git a/graphify/bundled_skills/llm-wiki/scripts/source-record-contract.tsv b/graphify/bundled_skills/llm-wiki/scripts/source-record-contract.tsv new file mode 100644 index 000000000..a670c59b1 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/source-record-contract.tsv @@ -0,0 +1,10 @@ +field_name requiredness filled_by value_rule +source_id required router 必须匹配 source-registry.tsv 中的 source_id +source_label required router 必须匹配 source-registry.tsv 中的 source_label +source_category required router 必须匹配 source-registry.tsv 中的 source_category +input_mode required caller_or_router 只能是 url / file / text / asset +raw_dir required router 必须是 raw/ 下的相对目录 +original_ref required caller 保存原始 URL、文件路径或用户粘贴说明 +ingest_text required adapter_or_user 进入主线前必须是非空文本 +adapter_name required_may_be_empty router_or_adapter 核心主线和手动入口留空;外挂来源写实际 adapter 名称 +fallback_hint required router 必须给出用户可执行的手动回退提示 diff --git a/graphify/bundled_skills/llm-wiki/scripts/source-registry.sh b/graphify/bundled_skills/llm-wiki/scripts/source-registry.sh new file mode 100755 index 000000000..989d294dd --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/source-registry.sh @@ -0,0 +1,349 @@ +#!/bin/bash +# 统一来源总表读取与验证脚本 +# 权威数据文件:source-registry.tsv(来源定义)、source-record-contract.tsv(字段契约) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +CONTRACT_FILE="$SCRIPT_DIR/source-record-contract.tsv" +REGISTRY_FILE="$SCRIPT_DIR/source-registry.tsv" + +usage() { + cat <<'EOF' +用法: + bash scripts/source-registry.sh fields + bash scripts/source-registry.sh list + bash scripts/source-registry.sh get + bash scripts/source-registry.sh match-url + bash scripts/source-registry.sh match-file + bash scripts/source-registry.sh list-by-category + bash scripts/source-registry.sh unique-dependencies + bash scripts/source-registry.sh validate +EOF +} + +require_file() { + local file="$1" + + [ -f "$file" ] || { + echo "缺少文件:$file" >&2 + exit 1 + } +} + +expect_header() { + local file="$1" + local expected="$2" + local actual + + actual="$(head -n 1 "$file")" + [ "$actual" = "$expected" ] || { + echo "表头不匹配:$file" >&2 + echo "期望:$expected" >&2 + echo "实际:$actual" >&2 + exit 1 + } +} + +validate_contract() { + require_file "$CONTRACT_FILE" + expect_header "$CONTRACT_FILE" $'field_name\trequiredness\tfilled_by\tvalue_rule' + + awk -F '\t' ' + BEGIN { + required["source_id"] = 1 + required["source_label"] = 1 + required["source_category"] = 1 + required["input_mode"] = 1 + required["raw_dir"] = 1 + required["original_ref"] = 1 + required["ingest_text"] = 1 + required["adapter_name"] = 1 + required["fallback_hint"] = 1 + } + NR == 1 { next } + { + if ($1 == "" || $2 == "" || $3 == "" || $4 == "") { + printf("source-record-contract.tsv 第 %d 行存在空字段\n", NR) > "/dev/stderr" + failed = 1 + } + + seen[$1] += 1 + } + END { + for (field in required) { + if (seen[field] != 1) { + printf("source-record-contract.tsv 缺少或重复字段:%s\n", field) > "/dev/stderr" + failed = 1 + } + } + + exit failed ? 1 : 0 + } + ' "$CONTRACT_FILE" +} + +validate_registry() { + require_file "$REGISTRY_FILE" + expect_header "$REGISTRY_FILE" $'source_id\tsource_label\tsource_category\tinput_mode\tmatch_rule\traw_dir\tadapter_name\tdependency_name\tdependency_type\tfallback_hint' + + awk -F '\t' ' + NR == 1 { next } + { + if ($1 == "" || $2 == "" || $3 == "" || $4 == "" || $5 == "" || $6 == "" || $10 == "") { + printf("source-registry.tsv 第 %d 行存在空字段\n", NR) > "/dev/stderr" + failed = 1 + } + + if ($3 != "core_builtin" && $3 != "optional_adapter" && $3 != "manual_only") { + printf("source-registry.tsv 第 %d 行存在未知分类:%s\n", NR, $3) > "/dev/stderr" + failed = 1 + } + + if ($4 != "url" && $4 != "file" && $4 != "text" && $4 != "asset") { + printf("source-registry.tsv 第 %d 行存在未知输入模式:%s\n", NR, $4) > "/dev/stderr" + failed = 1 + } + + if ($4 == "url" && $5 !~ /^url_host:/) { + printf("source-registry.tsv 第 %d 行 URL 来源必须声明 url_host 规则:%s\n", NR, $5) > "/dev/stderr" + failed = 1 + } + + if ($4 == "file" && $5 !~ /^file_ext:/) { + printf("source-registry.tsv 第 %d 行文件来源必须声明 file_ext 规则:%s\n", NR, $5) > "/dev/stderr" + failed = 1 + } + + if ($4 == "text" && $5 !~ /^text:/) { + printf("source-registry.tsv 第 %d 行文本来源必须声明 text 规则:%s\n", NR, $5) > "/dev/stderr" + failed = 1 + } + + if ($4 == "asset" && $5 !~ /^asset:/) { + printf("source-registry.tsv 第 %d 行附件来源必须声明 asset 规则:%s\n", NR, $5) > "/dev/stderr" + failed = 1 + } + + if ($6 !~ /^raw\//) { + printf("source-registry.tsv 第 %d 行 raw_dir 必须位于 raw/ 下:%s\n", NR, $6) > "/dev/stderr" + failed = 1 + } + + if (seen[$1]++) { + printf("source-registry.tsv source_id 重复:%s\n", $1) > "/dev/stderr" + failed = 1 + } + + category_seen[$3] = 1 + + if ($3 == "optional_adapter") { + if ($7 == "-" || $8 == "-" || $9 == "none") { + printf("source-registry.tsv 第 %d 行 optional_adapter 缺少依赖信息\n", NR) > "/dev/stderr" + failed = 1 + } + } else if ($7 != "-" || $8 != "-" || $9 != "none") { + printf("source-registry.tsv 第 %d 行非外挂来源不应声明依赖\n", NR) > "/dev/stderr" + failed = 1 + } + } + END { + if (!category_seen["core_builtin"]) { + print "source-registry.tsv 缺少 core_builtin 来源" > "/dev/stderr" + failed = 1 + } + + if (!category_seen["optional_adapter"]) { + print "source-registry.tsv 缺少 optional_adapter 来源" > "/dev/stderr" + failed = 1 + } + + if (!category_seen["manual_only"]) { + print "source-registry.tsv 缺少 manual_only 来源" > "/dev/stderr" + failed = 1 + } + + exit failed ? 1 : 0 + } + ' "$REGISTRY_FILE" +} + +print_contract() { + validate_contract + cat "$CONTRACT_FILE" +} + +print_registry() { + validate_registry + cat "$REGISTRY_FILE" +} + +get_source() { + local source_id="$1" + + validate_registry + + awk -F '\t' -v source_id="$source_id" ' + NR == 1 { next } + $1 == source_id { + print + found = 1 + } + END { + exit found ? 0 : 1 + } + ' "$REGISTRY_FILE" +} + +extract_url_host() { + local url="$1" + local rest host + + rest="${url#*://}" + if [ "$rest" = "$url" ]; then + rest="$url" + fi + + rest="${rest#*@}" + host="${rest%%/*}" + host="${host%%\?*}" + host="${host%%#*}" + host="${host%%:*}" + + printf '%s\n' "$host" | tr '[:upper:]' '[:lower:]' +} + +host_matches_pattern() { + local host="$1" + local pattern="$2" + + case "$host" in + "$pattern"|*."$pattern") + return 0 + ;; + *) + return 1 + ;; + esac +} + +match_url() { + local url="$1" + local host row source_id source_label source_category input_mode match_rule raw_dir adapter_name dependency_name dependency_type fallback_hint + local fallback_row="" + local pattern pattern_list + + validate_registry + host="$(extract_url_host "$url")" + + while IFS=$'\t' read -r source_id source_label source_category input_mode match_rule raw_dir adapter_name dependency_name dependency_type fallback_hint; do + [ "$source_id" = "source_id" ] && continue + [ "$input_mode" = "url" ] || continue + + pattern_list="${match_rule#url_host:}" + if [ "$pattern_list" = "*" ]; then + fallback_row="$(printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$source_id" "$source_label" "$source_category" "$input_mode" "$match_rule" "$raw_dir" "$adapter_name" "$dependency_name" "$dependency_type" "$fallback_hint")" + continue + fi + + for pattern in ${pattern_list//,/ }; do + if host_matches_pattern "$host" "$pattern"; then + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$source_id" "$source_label" "$source_category" "$input_mode" "$match_rule" "$raw_dir" "$adapter_name" "$dependency_name" "$dependency_type" "$fallback_hint" + return 0 + fi + done + done < "$REGISTRY_FILE" + + [ -n "$fallback_row" ] || return 1 + printf '%s\n' "$fallback_row" +} + +match_file() { + local path="$1" + local lowered_path source_id source_label source_category input_mode match_rule raw_dir adapter_name dependency_name dependency_type fallback_hint + local extension_list extension + + validate_registry + lowered_path="$(printf '%s\n' "$path" | tr '[:upper:]' '[:lower:]')" + + while IFS=$'\t' read -r source_id source_label source_category input_mode match_rule raw_dir adapter_name dependency_name dependency_type fallback_hint; do + [ "$source_id" = "source_id" ] && continue + [ "$input_mode" = "file" ] || continue + + extension_list="${match_rule#file_ext:}" + for extension in ${extension_list//,/ }; do + case "$lowered_path" in + *"$extension") + printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$source_id" "$source_label" "$source_category" "$input_mode" "$match_rule" "$raw_dir" "$adapter_name" "$dependency_name" "$dependency_type" "$fallback_hint" + return 0 + ;; + esac + done + done < "$REGISTRY_FILE" + + return 1 +} + +list_by_category() { + local category="$1" + + validate_registry + + awk -F '\t' -v category="$category" ' + NR == 1 { next } + $3 == category { print } + ' "$REGISTRY_FILE" +} + +list_unique_dependencies() { + local dependency_type="$1" + + validate_registry + + awk -F '\t' -v dependency_type="$dependency_type" ' + NR == 1 { next } + $9 == dependency_type && $8 != "-" { print $8 } + ' "$REGISTRY_FILE" | sort -u +} + +command_name="${1:-}" + +case "$command_name" in + fields) + [ "$#" -eq 1 ] || { usage; exit 1; } + print_contract + ;; + list) + [ "$#" -eq 1 ] || { usage; exit 1; } + print_registry + ;; + get) + [ "$#" -eq 2 ] || { usage; exit 1; } + get_source "$2" + ;; + match-url) + [ "$#" -eq 2 ] || { usage; exit 1; } + match_url "$2" + ;; + match-file) + [ "$#" -eq 2 ] || { usage; exit 1; } + match_file "$2" + ;; + list-by-category) + [ "$#" -eq 2 ] || { usage; exit 1; } + list_by_category "$2" + ;; + unique-dependencies) + [ "$#" -eq 2 ] || { usage; exit 1; } + list_unique_dependencies "$2" + ;; + validate) + [ "$#" -eq 1 ] || { usage; exit 1; } + validate_contract + validate_registry + ;; + *) + usage + exit 1 + ;; +esac diff --git a/graphify/bundled_skills/llm-wiki/scripts/source-registry.tsv b/graphify/bundled_skills/llm-wiki/scripts/source-registry.tsv new file mode 100644 index 000000000..8972b2c56 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/source-registry.tsv @@ -0,0 +1,10 @@ +source_id source_label source_category input_mode match_rule raw_dir adapter_name dependency_name dependency_type fallback_hint +local_pdf PDF / 本地 PDF core_builtin file file_ext:.pdf raw/pdfs - - none 直接提供文件路径即可进入主线 +local_document Markdown/文本/HTML core_builtin file file_ext:.md,.txt,.html raw/notes - - none 直接提供文件路径即可进入主线 +plain_text 纯文本粘贴 core_builtin text text:inline raw/notes - - none 直接粘贴正文即可进入主线 +x_twitter X/Twitter optional_adapter url url_host:x.com,twitter.com raw/tweets baoyu-url-to-markdown baoyu-url-to-markdown bundled 自动提取失败时,改为复制全文粘贴 +wechat_article 微信公众号 optional_adapter url url_host:mp.weixin.qq.com raw/wechat wechat-article-to-markdown wechat-article-to-markdown install_time 自动提取失败时,在浏览器打开后复制全文粘贴 +youtube_video YouTube optional_adapter url url_host:youtube.com,youtu.be raw/articles youtube-transcript youtube-transcript bundled 自动提取失败时,提供字幕文件或手动粘贴文本 +zhihu_article 知乎 optional_adapter url url_host:zhihu.com raw/zhihu baoyu-url-to-markdown baoyu-url-to-markdown bundled 自动提取失败时,改为复制全文粘贴 +xiaohongshu_post 小红书 manual_only url url_host:xiaohongshu.com,xhslink.com raw/xiaohongshu - - none 请先从 App 或网页复制内容,再粘贴进来 +web_article 网页文章 optional_adapter url url_host:* raw/articles baoyu-url-to-markdown baoyu-url-to-markdown bundled 自动提取失败时,改为复制全文或保存为本地文件后继续 diff --git a/graphify/bundled_skills/llm-wiki/scripts/source-signal-coverage.js b/graphify/bundled_skills/llm-wiki/scripts/source-signal-coverage.js new file mode 100644 index 000000000..3e6e7f4ae --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/source-signal-coverage.js @@ -0,0 +1,83 @@ +#!/usr/bin/env node +"use strict"; + +const fs = require("fs"); +const path = require("path"); +const { + SCAN_KINDS, + extractFrontmatter, + evaluateSourceSignalEligibility +} = require("./lib/source-signal-eligibility"); + +function scanWiki(wikiRoot) { + const wikiDir = path.join(wikiRoot, "wiki"); + if (!fs.existsSync(wikiDir)) { + console.error(`ERROR: wiki 目录不存在:${wikiDir}`); + process.exit(1); + } + + const pages = []; + const summary = { + applicable_total: 0, + ok: 0, + missing_sources: 0, + empty_sources: 0, + invalid_sources: 0, + not_applicable: 0 + }; + + for (const kind of SCAN_KINDS) { + const dir = path.join(wikiDir, kind.subdir); + if (!fs.existsSync(dir)) continue; + + const files = fs.readdirSync(dir) + .filter((f) => f.endsWith(".md")) + .sort(); + + for (const file of files) { + const id = path.basename(file, ".md"); + if (["index", "log", "purpose", ".wiki-schema", "README"].includes(id)) continue; + + const filePath = path.join(dir, file); + const raw = fs.readFileSync(filePath, "utf8"); + const { frontmatter } = extractFrontmatter(raw); + const result = evaluateSourceSignalEligibility({ + pageType: kind.pageType, + frontmatter + }); + + pages.push({ + path: path.relative(wikiRoot, filePath), + id, + pageType: kind.pageType, + eligible: result.eligible, + reason: result.reason, + sourceCount: result.sources.length + }); + + summary[result.reason] += 1; + if (result.reason !== "not_applicable") { + summary.applicable_total += 1; + } + } + } + + return { summary, pages }; +} + +function main(argv) { + if (argv.length < 3) { + console.error("Usage: node scripts/source-signal-coverage.js "); + process.exit(1); + } + + const wikiRoot = path.resolve(argv[2]); + const result = scanWiki(wikiRoot); + console.log(JSON.stringify(result, null, 2)); +} + +if (require.main === module) { + main(process.argv); +} + +module.exports = { scanWiki }; diff --git a/graphify/bundled_skills/llm-wiki/scripts/validate-step1.sh b/graphify/bundled_skills/llm-wiki/scripts/validate-step1.sh new file mode 100755 index 000000000..fa9c8551a --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/validate-step1.sh @@ -0,0 +1,144 @@ +#!/bin/bash +# 验证 ingest Step 1 的 JSON 输出格式 +# 用法:bash validate-step1.sh +# 返回:0 = 格式正确,1 = 格式有问题(触发回退) + +SCRIPT_DIR="${BASH_SOURCE[0]%/*}" +[ "$SCRIPT_DIR" = "${BASH_SOURCE[0]}" ] && SCRIPT_DIR="." +SCRIPT_DIR="$(cd "$SCRIPT_DIR" && pwd)" +# shellcheck disable=SC1091 +source "$SCRIPT_DIR/shared-config.sh" + +JSON_FILE="$1" + +# 参数检查 +[ -z "$1" ] && { echo "ERROR: usage: validate-step1.sh "; exit 1; } + +# 检查 jq 是否可用(必需依赖) +command -v jq >/dev/null 2>&1 || { + echo "ERROR: jq is not installed. Install it via:" >&2 + print_install_hint jq + exit 1 +} + +# 检查文件是否存在 +[ -f "$JSON_FILE" ] || { echo "ERROR: file not found: $JSON_FILE"; exit 1; } + +# 检查是否是有效 JSON +jq empty "$JSON_FILE" 2>/dev/null || { echo "ERROR: invalid JSON format"; exit 1; } + +# 检查必需字段存在且类型正确 +jq -e '.entities | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'entities' must be an array"; exit 1; } +jq -e '.topics | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'topics' must be an array"; exit 1; } +jq -e '.connections | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'connections' must be an array"; exit 1; } +jq -e '.contradictions | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'contradictions' must be an array"; exit 1; } +jq -e '.new_vs_existing | type == "object"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'new_vs_existing' must be an object"; exit 1; } + +# 检查每个 entity 的必需子字段 +VALID_CONFIDENCE="EXTRACTED|INFERRED|AMBIGUOUS|UNVERIFIED" + +ENTITY_COUNT=$(jq '.entities | length' "$JSON_FILE" 2>/dev/null) +if [ "$ENTITY_COUNT" -gt 0 ] 2>/dev/null; then + NON_OBJECT_ENTITY_COUNT=$(jq '[.entities[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null) + if [ "$NON_OBJECT_ENTITY_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $NON_OBJECT_ENTITY_COUNT entity/entities must be objects" + exit 1 + fi + + # name, type, confidence 必须存在且非空 + BAD_ENTITY_COUNT=$(jq ' + [.entities[] | select( + (.name // "" | length) == 0 or + (.type // "" | length) == 0 or + (.confidence // "" | length) == 0 + )] | length + ' "$JSON_FILE" 2>/dev/null) + if [ "$BAD_ENTITY_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $BAD_ENTITY_COUNT entity/entities missing required fields (name/type/confidence)" + exit 1 + fi + + # confidence 值必须是四个有效值之一 + INVALID=$(jq -r '.entities[]? | (.confidence // "MISSING")' "$JSON_FILE" 2>/dev/null | \ + grep -v -E "^($VALID_CONFIDENCE)$" | head -3) + if [ -n "$INVALID" ]; then + echo "ERROR: invalid entity confidence value(s): $INVALID" + echo " Valid values: EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED" + exit 1 + fi + + # EXTRACTED 和 INFERRED 必须提供 evidence 字段 + NO_EVIDENCE_COUNT=$(jq ' + [.entities[] | select( + (.confidence == "EXTRACTED" or .confidence == "INFERRED") and + ((.evidence // "" | length) == 0) + )] | length + ' "$JSON_FILE" 2>/dev/null) + if [ "$NO_EVIDENCE_COUNT" -gt 0 ] 2>/dev/null; then + echo "WARN: $NO_EVIDENCE_COUNT entity/entities with EXTRACTED/INFERRED confidence missing 'evidence' field" + fi +fi + +# 检查每个 topic 的必需子字段 +TOPIC_COUNT=$(jq '.topics | length' "$JSON_FILE" 2>/dev/null) +if [ "$TOPIC_COUNT" -gt 0 ] 2>/dev/null; then + NON_OBJECT_TOPIC_COUNT=$(jq '[.topics[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null) + if [ "$NON_OBJECT_TOPIC_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $NON_OBJECT_TOPIC_COUNT topic(s) must be objects" + exit 1 + fi + + BAD_TOPIC_COUNT=$(jq ' + [.topics[] | select( + (.name // "" | length) == 0 + )] | length + ' "$JSON_FILE" 2>/dev/null) + if [ "$BAD_TOPIC_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $BAD_TOPIC_COUNT topic(s) missing required 'name' field" + exit 1 + fi +fi + +# 检查每个 connection 的必需子字段(from, to, confidence) +CONN_COUNT=$(jq '.connections | length' "$JSON_FILE" 2>/dev/null) +if [ "$CONN_COUNT" -gt 0 ] 2>/dev/null; then + NON_OBJECT_CONN_COUNT=$(jq '[.connections[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null) + if [ "$NON_OBJECT_CONN_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $NON_OBJECT_CONN_COUNT connection(s) must be objects" + exit 1 + fi + + BAD_CONN_COUNT=$(jq ' + [.connections[] | select( + (.from // "" | length) == 0 or + (.to // "" | length) == 0 or + (.confidence // "" | length) == 0 + )] | length + ' "$JSON_FILE" 2>/dev/null) + if [ "$BAD_CONN_COUNT" -gt 0 ] 2>/dev/null; then + echo "ERROR: $BAD_CONN_COUNT connection(s) missing required fields (from/to/confidence)" + exit 1 + fi + + INVALID_CONN_CONF=$(jq -r '.connections[]? | (.confidence // "MISSING")' "$JSON_FILE" 2>/dev/null | \ + grep -v -E "^($VALID_CONFIDENCE)$" | head -3) + if [ -n "$INVALID_CONN_CONF" ]; then + echo "ERROR: invalid connection confidence value(s): $INVALID_CONN_CONF" + echo " Valid values: EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED" + exit 1 + fi + + # EXTRACTED 和 INFERRED connections 必须提供 evidence + NO_CONN_EVIDENCE=$(jq ' + [.connections[] | select( + (.confidence == "EXTRACTED" or .confidence == "INFERRED") and + ((.evidence // "" | length) == 0) + )] | length + ' "$JSON_FILE" 2>/dev/null) + if [ "$NO_CONN_EVIDENCE" -gt 0 ] 2>/dev/null; then + echo "WARN: $NO_CONN_EVIDENCE connection(s) with EXTRACTED/INFERRED confidence missing 'evidence' field" + fi +fi + +echo "OK: Step 1 JSON validation passed" +exit 0 diff --git a/graphify/bundled_skills/llm-wiki/scripts/wiki-compat.sh b/graphify/bundled_skills/llm-wiki/scripts/wiki-compat.sh new file mode 100755 index 000000000..aa0d7572c --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/scripts/wiki-compat.sh @@ -0,0 +1,267 @@ +#!/bin/bash +# 旧知识库兼容脚本:惰性默认、目录检查、按需创建 +# 原则:migration_required=no,只有确实无法兼容时才引入显式迁移 + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +SOURCE_REGISTRY_SCRIPT="$SCRIPT_DIR/source-registry.sh" + +LEGACY_REQUIRED_RAW_DIRS=( + "raw/articles" + "raw/tweets" + "raw/wechat" + "raw/pdfs" + "raw/notes" + "raw/assets" +) + +REQUIRED_PATHS=( + ".wiki-schema.md" + "index.md" + "log.md" + "raw" + "wiki" + "wiki/entities" + "wiki/topics" + "wiki/sources" + "wiki/comparisons" + "wiki/synthesis" + "wiki/overview.md" +) + +usage() { + cat <<'EOF' +用法: + bash scripts/wiki-compat.sh inspect + bash scripts/wiki-compat.sh validate + bash scripts/wiki-compat.sh ensure-source-dir +EOF +} + +trim() { + printf '%s' "$1" | awk '{ gsub(/^[[:space:]]+|[[:space:]]+$/, "", $0); printf "%s", $0 }' +} + +require_wiki_root() { + local wiki_root="$1" + + [ -n "$wiki_root" ] || { + usage + exit 1 + } + + [ -d "$wiki_root" ] || { + echo "知识库不存在:$wiki_root" >&2 + exit 1 + } +} + +schema_field_value() { + local wiki_root="$1" + local field_name="$2" + local default_value="$3" + local schema_path value + + schema_path="$wiki_root/.wiki-schema.md" + + if [ ! -f "$schema_path" ]; then + printf '%s\n' "$default_value" + return 0 + fi + + value="$( + awk -v field_name="$field_name" ' + $0 ~ "^-[[:space:]]*" field_name "[::]" { + line = $0 + sub("^-[[:space:]]*" field_name "[::][[:space:]]*", "", line) + print line + exit + } + ' "$schema_path" + )" + + value="$(trim "$value")" + + if [ -n "$value" ]; then + printf '%s\n' "$value" + else + printf '%s\n' "$default_value" + fi +} + +resolved_language() { + local wiki_root="$1" + local raw_value + + raw_value="$(schema_field_value "$wiki_root" "语言" "")" + + case "$raw_value" in + English|english|EN|en) + printf 'en\n' + ;; + *) + printf 'zh\n' + ;; + esac +} + +resolved_schema_version() { + local wiki_root="$1" + + schema_field_value "$wiki_root" "版本" "1.0" +} + +is_legacy_required_raw_dir() { + case "$1" in + raw/articles|raw/tweets|raw/wechat|raw/pdfs|raw/notes|raw/assets) + return 0 + ;; + *) + return 1 + ;; + esac +} + +missing_optional_raw_dirs() { + local wiki_root="$1" + local raw_dir + local missing=() + + while IFS= read -r raw_dir; do + [ -n "$raw_dir" ] || continue + + if is_legacy_required_raw_dir "$raw_dir"; then + continue + fi + + if [ ! -d "$wiki_root/$raw_dir" ]; then + missing+=("$raw_dir") + fi + done < <( + bash "$SOURCE_REGISTRY_SCRIPT" list | awk -F '\t' 'NR > 1 { print $6 }' | LC_ALL=C sort -u + ) + + if [ "${#missing[@]}" -eq 0 ]; then + printf '%s\n' '-' + else + local IFS=, + printf '%s\n' "${missing[*]}" + fi +} + +file_presence() { + local wiki_root="$1" + local relative_path="$2" + + if [ -e "$wiki_root/$relative_path" ]; then + printf 'present\n' + else + printf 'missing\n' + fi +} + +validate_layout() { + local wiki_root="$1" + local failed=0 + local path + + require_wiki_root "$wiki_root" + + for path in "${REQUIRED_PATHS[@]}"; do + if [ ! -e "$wiki_root/$path" ]; then + echo "缺少必要路径:$path" >&2 + failed=1 + fi + done + + for path in "${LEGACY_REQUIRED_RAW_DIRS[@]}"; do + if [ ! -d "$wiki_root/$path" ]; then + echo "缺少必要旧目录:$path" >&2 + failed=1 + fi + done + + if [ "$failed" -ne 0 ]; then + exit 1 + fi +} + +source_raw_dir() { + local source_id="$1" + local record raw_dir + + record="$( + bash "$SOURCE_REGISTRY_SCRIPT" get "$source_id" 2>/dev/null + )" || { + echo "未知来源:$source_id" >&2 + exit 1 + } + + IFS=$'\t' read -r _ _ _ _ _ raw_dir _ _ _ _ < /dev/null + ;; + ensure-source-dir) + [ "$#" -eq 3 ] || { usage; exit 1; } + ensure_source_dir "$2" "$3" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/graphify/bundled_skills/llm-wiki/setup.sh b/graphify/bundled_skills/llm-wiki/setup.sh new file mode 100755 index 000000000..8dbdae1b6 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/setup.sh @@ -0,0 +1,8 @@ +# 已废弃:请使用 bash install.sh --platform claude +#!/bin/bash +# Claude 旧入口兼容包装 +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +exec bash "$SCRIPT_DIR/install.sh" --platform claude "$@" diff --git a/graphify/bundled_skills/llm-wiki/templates/entity-template.md b/graphify/bundled_skills/llm-wiki/templates/entity-template.md new file mode 100644 index 000000000..50a29a5dd --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/templates/entity-template.md @@ -0,0 +1,30 @@ +--- +tags: [实体] +created: {{DATE}} +updated: {{DATE}} +sources: [] +--- + +# {{ENTITY_NAME}} + +> 一句话描述这个实体是什么 + +## 简介 + +(这个实体的基本介绍) + +## 关键信息 + +- **类型**:(人物 / 组织 / 概念 / 工具 / 事件) +- **领域**:(所属领域) +- **相关概念**:(关联的其他实体) + +## 详细内容 + +(从素材中提取的关于这个实体的详细信息) + +## 不同素材中的观点 + +(不同素材对同一个实体的不同描述或评价,标注来源) + +## 相关页面 diff --git a/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/footer.html b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/footer.html new file mode 100644 index 000000000..5cc0bdbdf --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/footer.html @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash-helpers.js b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash-helpers.js new file mode 100644 index 000000000..03d0add8b --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash-helpers.js @@ -0,0 +1,1326 @@ +/* DEPRECATED: Legacy wash helpers retained for one release cycle after Stage 4 engine HTML migration. Do not extend; use packages/graph-engine instead. */ +(function (root) { + "use strict"; + + var LABEL_CJK_WIDTH = 15; + var LABEL_LATIN_WIDTH = 8.5; + var LABEL_PADDING = 22; + var LABEL_MIN_WIDTH = 72; + var LABEL_MAX_WIDTH = 180; + var LABEL_ELLIPSIS = "…"; + var LABEL_ELLIPSIS_WIDTH = 8; + var ATLAS_WORLD_WIDTH = 1000; + var ATLAS_WORLD_HEIGHT = 680; + var ATLAS_MIN_SCALE = 0.62; + var ATLAS_MAX_SCALE = 3.2; + var MINIMAP_VIEWBOX = { x: 5, y: 3, width: 150, height: 48 }; + + var labelSegmenter = + typeof Intl !== "undefined" && Intl.Segmenter + ? new Intl.Segmenter("zh", { granularity: "grapheme" }) + : null; + + function isVariationSelector(grapheme) { + var code = grapheme.codePointAt(0); + return code >= 0xFE00 && code <= 0xFE0F; + } + + function isCombiningMark(grapheme) { + var code = grapheme.codePointAt(0); + return (code >= 0x0300 && code <= 0x036F) + || (code >= 0x1AB0 && code <= 0x1AFF) + || (code >= 0x1DC0 && code <= 0x1DFF) + || (code >= 0x20D0 && code <= 0x20FF) + || (code >= 0xFE20 && code <= 0xFE2F); + } + + function isEmojiModifier(grapheme) { + var code = grapheme.codePointAt(0); + return code >= 0x1F3FB && code <= 0x1F3FF; + } + + function splitLabelGraphemes(label) { + if (labelSegmenter) { + return Array.from(labelSegmenter.segment(label), function (s) { + return s.segment; + }); + } + + var parts = Array.from(label); + if (!parts.length) return []; + + var graphemes = [parts[0]]; + for (var i = 1; i < parts.length; i++) { + var current = parts[i]; + var previous = parts[i - 1]; + if ( + current === "‍" + || previous === "‍" + || isVariationSelector(current) + || isCombiningMark(current) + || isEmojiModifier(current) + ) { + graphemes[graphemes.length - 1] += current; + } else { + graphemes.push(current); + } + } + + return graphemes; + } + + function labelCharWidth(grapheme) { + return /[一-鿿]/.test(grapheme) ? LABEL_CJK_WIDTH : LABEL_LATIN_WIDTH; + } + + function measureLabelWidth(graphemes) { + var width = 0; + for (var i = 0; i < graphemes.length; i++) { + width += labelCharWidth(graphemes[i]); + } + return width; + } + + function truncateLabel(label, maxWidth) { + if (!label || typeof label !== "string") { + return { text: "", truncated: false }; + } + + var graphemes = splitLabelGraphemes(label); + var totalWidth = measureLabelWidth(graphemes); + if (totalWidth + LABEL_PADDING <= maxWidth) { + return { text: label, truncated: false }; + } + + var out = ""; + var width = 0; + for (var i = 0; i < graphemes.length; i++) { + var gw = labelCharWidth(graphemes[i]); + if (width + gw + LABEL_ELLIPSIS_WIDTH + LABEL_PADDING > maxWidth) break; + out += graphemes[i]; + width += gw; + } + return { text: out + LABEL_ELLIPSIS, truncated: true }; + } + + function cardDims(n) { + var label = n.label || n.id; + var widthByLabel = measureLabelWidth(splitLabelGraphemes(label)); + var width = Math.max(LABEL_MIN_WIDTH, Math.min(LABEL_MAX_WIDTH, widthByLabel + LABEL_PADDING)); + var height = 36; + if (n.type === "topic") { height = 40; width += 6; } + if (n.type === "source") { height = 32; } + return { w: width, h: height }; + } + + function createSafeStorage(storage, logger) { + return { + get: function (key) { + try { return storage.getItem(key); } + catch (err) { if (logger) logger("[wiki] storage.get failed:", key, err); return null; } + }, + set: function (key, value) { + try { storage.setItem(key, value); } + catch (err) { if (logger) logger("[wiki] storage.set failed:", key, err); } + } + }; + } + + function normalizeStorageSegment(value) { + return String(value == null ? "" : value) + .trim() + .toLowerCase() + .replace(/[^a-z0-9一-鿿]+/g, "-") + .replace(/^-+|-+$/g, "") + .slice(0, 48); + } + + function hashString(value) { + var input = String(value == null ? "" : value); + var hash = 0; + for (var i = 0; i < input.length; i++) { + hash = ((hash << 5) - hash + input.charCodeAt(i)) >>> 0; + } + return hash.toString(36); + } + + function getWikiStorageNamespace(meta, pathname) { + var title = normalizeStorageSegment(meta && meta.wiki_title ? meta.wiki_title : ""); + var basis = typeof pathname === "string" && pathname + ? pathname + : (meta && meta.wiki_title) || title || "default"; + return "llm-wiki:" + (title || "default") + ":" + hashString(basis); + } + + function defaultQueue() { + return { + version: 1, + favorites: [], + notes: [], + recentNoteIds: [] + }; + } + + function normalizeQueue(raw) { + if (!raw || typeof raw !== "object") return defaultQueue(); + var d = defaultQueue(); + var favorites = Array.isArray(raw.favorites) ? raw.favorites : d.favorites; + var notes = Array.isArray(raw.notes) ? raw.notes : d.notes; + var recentNoteIds = Array.isArray(raw.recentNoteIds) ? raw.recentNoteIds : d.recentNoteIds; + var seenFavorites = {}; + var normalizedFavorites = favorites + .map(function (nodeId) { + return nodeId == null ? null : String(nodeId); + }) + .filter(function (nodeId) { + if (!nodeId || seenFavorites[nodeId]) return false; + seenFavorites[nodeId] = true; + return true; + }); + var normalizedNotes = notes + .map(function (note) { + if (!note || typeof note !== "object" || note.id == null || note.node_id == null) return null; + return { + id: String(note.id), + node_id: String(note.node_id), + label: note.label == null ? String(note.node_id) : String(note.label), + text: note.text == null ? "" : String(note.text), + created_at: note.created_at == null ? null : String(note.created_at) + }; + }) + .filter(function (note) { + return !!note; + }); + var noteIdSet = {}; + for (var i = 0; i < normalizedNotes.length; i++) { + noteIdSet[normalizedNotes[i].id] = true; + } + var seenRecent = {}; + var normalizedRecentNoteIds = recentNoteIds + .map(function (noteId) { + return noteId == null ? null : String(noteId); + }) + .filter(function (noteId) { + if (!noteId || !noteIdSet[noteId] || seenRecent[noteId]) return false; + seenRecent[noteId] = true; + return true; + }); + if (!normalizedRecentNoteIds.length && normalizedNotes.length) { + normalizedRecentNoteIds = normalizedNotes.map(function (note) { + return note.id; + }); + } + return { + version: d.version, + favorites: normalizedFavorites, + notes: normalizedNotes, + recentNoteIds: normalizedRecentNoteIds + }; + } + + function toggleQueueFavorite(queue, nodeId) { + var safe = normalizeQueue(queue); + var favoriteNodeId = nodeId == null ? "" : String(nodeId); + if (!favoriteNodeId) return safe; + var favorites = safe.favorites.slice(); + var existingIndex = favorites.indexOf(favoriteNodeId); + if (existingIndex === -1) { + favorites.unshift(favoriteNodeId); + } else { + favorites.splice(existingIndex, 1); + } + return { + version: safe.version, + favorites: favorites, + notes: safe.notes.slice(), + recentNoteIds: safe.recentNoteIds.slice() + }; + } + + function appendQueueNote(queue, note, limit) { + var safe = normalizeQueue(queue); + if (!note || typeof note !== "object" || note.id == null || note.node_id == null) return safe; + var noteLimit = Number.isFinite(Number(limit)) ? Math.max(1, Math.round(Number(limit))) : 50; + var normalizedNote = { + id: String(note.id), + node_id: String(note.node_id), + label: note.label == null ? String(note.node_id) : String(note.label), + text: note.text == null ? "" : String(note.text), + created_at: note.created_at == null ? null : String(note.created_at) + }; + var notes = [normalizedNote].concat(safe.notes.filter(function (item) { + return item.id !== normalizedNote.id; + })).slice(0, noteLimit); + var recentNoteIds = [normalizedNote.id].concat(safe.recentNoteIds.filter(function (noteId) { + return noteId !== normalizedNote.id; + })).slice(0, Math.min(noteLimit, 12)); + return { + version: safe.version, + favorites: safe.favorites.slice(), + notes: notes, + recentNoteIds: recentNoteIds + }; + } + + function summarizeQueue(queue, nodesById, limit) { + var safe = normalizeQueue(queue); + var maxItems = Number.isFinite(Number(limit)) ? Math.max(1, Math.round(Number(limit))) : 4; + var byId = nodesById && typeof nodesById === "object" ? nodesById : {}; + var notesById = {}; + var recentItems = []; + var i; + + for (i = 0; i < safe.notes.length; i++) { + notesById[safe.notes[i].id] = safe.notes[i]; + } + + for (i = 0; i < safe.recentNoteIds.length && recentItems.length < maxItems; i++) { + var note = notesById[safe.recentNoteIds[i]]; + if (!note) continue; + var noteNode = byId[note.node_id]; + recentItems.push({ + kind: "note", + node_id: note.node_id, + label: note.label || (noteNode && (noteNode.label || noteNode.id)) || note.node_id, + text: note.text || "" + }); + } + + for (i = 0; i < safe.favorites.length && recentItems.length < maxItems; i++) { + var favoriteNodeId = safe.favorites[i]; + var favoriteNode = byId[favoriteNodeId]; + recentItems.push({ + kind: "favorite", + node_id: favoriteNodeId, + label: favoriteNode && (favoriteNode.label || favoriteNode.id) ? (favoriteNode.label || favoriteNode.id) : favoriteNodeId, + text: "" + }); + } + + return { + favorite_count: safe.favorites.length, + note_count: safe.notes.length, + recent_items: recentItems + }; + } + + function defaultLearning() { + return { + version: 1, + entry: { recommended_start_node_id: null, recommended_start_reason: null, default_mode: "global" }, + views: { + path: { enabled: false, start_node_id: null, node_ids: [], degraded: true }, + community: { enabled: false, community_id: null, label: null, node_ids: [], is_weak: false, degraded: true }, + global: { enabled: true, node_ids: [], degraded: false } + }, + communities: [], + degraded: { path_to_community: true, community_to_global: true } + }; + } + + function normalizeLearning(raw) { + if (!raw || typeof raw !== "object") return defaultLearning(); + var d = defaultLearning(); + function pick(obj, key, fallback) { + return obj && obj[key] != null ? obj[key] : fallback; + } + return { + version: pick(raw, "version", d.version), + entry: { + recommended_start_node_id: pick(raw.entry, "recommended_start_node_id", d.entry.recommended_start_node_id), + recommended_start_reason: pick(raw.entry, "recommended_start_reason", d.entry.recommended_start_reason), + default_mode: pick(raw.entry, "default_mode", d.entry.default_mode) + }, + views: { + path: { + enabled: pick(raw.views && raw.views.path, "enabled", d.views.path.enabled), + start_node_id: pick(raw.views && raw.views.path, "start_node_id", d.views.path.start_node_id), + node_ids: Array.isArray(raw.views && raw.views.path && raw.views.path.node_ids) ? raw.views.path.node_ids : d.views.path.node_ids, + degraded: pick(raw.views && raw.views.path, "degraded", d.views.path.degraded) + }, + community: { + enabled: pick(raw.views && raw.views.community, "enabled", d.views.community.enabled), + community_id: pick(raw.views && raw.views.community, "community_id", d.views.community.community_id), + label: pick(raw.views && raw.views.community, "label", d.views.community.label), + node_ids: Array.isArray(raw.views && raw.views.community && raw.views.community.node_ids) ? raw.views.community.node_ids : d.views.community.node_ids, + is_weak: pick(raw.views && raw.views.community, "is_weak", d.views.community.is_weak), + degraded: pick(raw.views && raw.views.community, "degraded", d.views.community.degraded) + }, + global: { + enabled: pick(raw.views && raw.views.global, "enabled", d.views.global.enabled), + node_ids: Array.isArray(raw.views && raw.views.global && raw.views.global.node_ids) ? raw.views.global.node_ids : d.views.global.node_ids, + degraded: pick(raw.views && raw.views.global, "degraded", d.views.global.degraded) + } + }, + communities: Array.isArray(raw.communities) ? raw.communities : d.communities, + degraded: { + path_to_community: pick(raw.degraded, "path_to_community", d.degraded.path_to_community), + community_to_global: pick(raw.degraded, "community_to_global", d.degraded.community_to_global) + } + }; + } + + function resolveInitialMode(learning) { + return "global"; + } + + function getCommunityNodeIds(nodes, communityId) { + if (!Array.isArray(nodes) || !communityId) return []; + return nodes + .filter(function (node) { + return node && node.community != null && String(node.community) === String(communityId); + }) + .map(function (node) { + return node.id; + }) + .sort(); + } + + function getVisibleNodeIds(learning, mode) { + if (!learning || !learning.views) return []; + var view = learning.views[mode]; + if (!view || !view.enabled) return []; + return Array.isArray(view.node_ids) ? view.node_ids : []; + } + + function getVisibleLinks(allLinks, visibleIds) { + if (!visibleIds || !visibleIds.length) return allLinks; + var idSet = {}; + for (var i = 0; i < visibleIds.length; i++) idSet[visibleIds[i]] = true; + return allLinks.filter(function (l) { + var s = l.source.id || l.source; + var t = l.target.id || l.target; + return idSet[s] && idSet[t]; + }); + } + + function buildSearchHaystack(node) { + return ((node && (node.label || node.id || "")) + "\n" + (((node && node.content) || "").slice(0, 500))).toLowerCase(); + } + + function buildSearchIndex(nodes) { + if (!Array.isArray(nodes)) return []; + return nodes.map(function (node) { + return { node: node, haystack: buildSearchHaystack(node) }; + }); + } + + function filterLinksByTypes(allLinks, filters) { + if (!Array.isArray(allLinks)) return []; + if (!filters || typeof filters !== "object") return allLinks.slice(); + return allLinks.filter(function (link) { + var type = link && link.type ? link.type : "EXTRACTED"; + return filters[type] !== false; + }); + } + + function applySearchToNodeIds(searchIndex, query) { + if (!Array.isArray(searchIndex)) return []; + var normalizedQuery = typeof query === "string" ? query.trim().toLowerCase() : ""; + var matches = !normalizedQuery + ? searchIndex + : searchIndex.filter(function (entry) { + return entry && typeof entry.haystack === "string" && entry.haystack.indexOf(normalizedQuery) !== -1; + }); + return matches + .map(function (entry) { + return entry && entry.node ? entry.node.id : null; + }) + .filter(function (id) { + return id != null; + }); + } + + function getLinkEndpointIds(link) { + return { + sourceId: link && link.source && link.source.id ? link.source.id : link && link.source, + targetId: link && link.target && link.target.id ? link.target.id : link && link.target + }; + } + + function sortNodeIdsByScore(nodeIds, scores, nodesById) { + return nodeIds.slice().sort(function (left, right) { + var scoreDiff = (scores[right] || 0) - (scores[left] || 0); + if (scoreDiff) return scoreDiff; + var leftDegree = nodesById[left] && Number.isFinite(Number(nodesById[left].degree)) ? Number(nodesById[left].degree) : 0; + var rightDegree = nodesById[right] && Number.isFinite(Number(nodesById[right].degree)) ? Number(nodesById[right].degree) : 0; + if (rightDegree !== leftDegree) return rightDegree - leftDegree; + return String(left).localeCompare(String(right)); + }); + } + + function applyFocusMode(options) { + var safe = options && typeof options === "object" ? options : {}; + var nodes = Array.isArray(safe.nodes) ? safe.nodes : []; + var links = Array.isArray(safe.links) ? safe.links : []; + var nodeIds = Array.isArray(safe.nodeIds) ? safe.nodeIds.slice() : []; + var mode = safe.mode || "all"; + var anchorNodeId = safe.anchorNodeId != null ? String(safe.anchorNodeId) : null; + var highConfidenceThreshold = Number.isFinite(Number(safe.highConfidenceThreshold)) ? Number(safe.highConfidenceThreshold) : 0.75; + var nodesById = {}; + var idSet = {}; + var i; + + for (i = 0; i < nodes.length; i++) { + if (nodes[i] && nodes[i].id != null) nodesById[nodes[i].id] = nodes[i]; + } + for (i = 0; i < nodeIds.length; i++) idSet[nodeIds[i]] = true; + + if (!nodeIds.length) return { node_ids: [], links: [] }; + + var scopedLinks = getVisibleLinks(links, nodeIds); + if (mode === "all") return { node_ids: nodeIds.slice(), links: scopedLinks }; + + if (mode === "high_confidence") { + var strongLinks = scopedLinks.filter(function (link) { + var weight = Number(link && link.weight); + return Number.isFinite(weight) && weight >= highConfidenceThreshold; + }); + var strongIdSet = {}; + for (i = 0; i < strongLinks.length; i++) { + var strongEdge = getLinkEndpointIds(strongLinks[i]); + if (idSet[strongEdge.sourceId]) strongIdSet[strongEdge.sourceId] = true; + if (idSet[strongEdge.targetId]) strongIdSet[strongEdge.targetId] = true; + } + if (anchorNodeId && idSet[anchorNodeId]) strongIdSet[anchorNodeId] = true; + var strongNodeIds = nodeIds.filter(function (id) { + return !!strongIdSet[id]; + }); + return { node_ids: strongNodeIds, links: getVisibleLinks(strongLinks, strongNodeIds) }; + } + + if (mode === "one_hop") { + var hopAnchorNodeId = anchorNodeId && idSet[anchorNodeId] ? anchorNodeId : nodeIds[0] || null; + if (!hopAnchorNodeId) return { node_ids: [], links: [] }; + var hopIdSet = {}; + hopIdSet[hopAnchorNodeId] = true; + for (i = 0; i < scopedLinks.length; i++) { + var hopEdge = getLinkEndpointIds(scopedLinks[i]); + if (hopEdge.sourceId === hopAnchorNodeId && idSet[hopEdge.targetId]) hopIdSet[hopEdge.targetId] = true; + if (hopEdge.targetId === hopAnchorNodeId && idSet[hopEdge.sourceId]) hopIdSet[hopEdge.sourceId] = true; + } + var hopNodeIds = nodeIds.filter(function (id) { + return !!hopIdSet[id]; + }); + return { node_ids: hopNodeIds, links: getVisibleLinks(scopedLinks, hopNodeIds) }; + } + + if (mode === "core") { + if (nodeIds.length <= 3) return { node_ids: nodeIds.slice(), links: scopedLinks }; + var scores = {}; + for (i = 0; i < nodeIds.length; i++) scores[nodeIds[i]] = 0; + for (i = 0; i < scopedLinks.length; i++) { + var coreEdge = getLinkEndpointIds(scopedLinks[i]); + var weight = Number(scopedLinks[i] && scopedLinks[i].weight); + var score = Number.isFinite(weight) ? 1 + weight : 1.5; + if (scores[coreEdge.sourceId] != null) scores[coreEdge.sourceId] += score; + if (scores[coreEdge.targetId] != null) scores[coreEdge.targetId] += score; + } + var coreLimit = Number.isFinite(Number(safe.coreLimit)) ? Number(safe.coreLimit) : Math.max(3, Math.min(8, Math.round(nodeIds.length * 0.5))); + coreLimit = Math.max(1, Math.min(nodeIds.length, Math.round(coreLimit))); + var coreNodeIds = sortNodeIdsByScore(nodeIds, scores, nodesById).slice(0, coreLimit); + return { node_ids: coreNodeIds, links: getVisibleLinks(scopedLinks, coreNodeIds) }; + } + + return { node_ids: nodeIds.slice(), links: scopedLinks }; + } + + function resolveVisibleSnapshot(options) { + var safe = options && typeof options === "object" ? options : {}; + var nodes = Array.isArray(safe.nodes) ? safe.nodes : []; + var links = Array.isArray(safe.links) ? safe.links : []; + var baseNodeIds = Array.isArray(safe.baseNodeIds) + ? safe.baseNodeIds.slice() + : nodes.map(function (node) { return node.id; }); + var filteredLinks = filterLinksByTypes(links, safe.filters); + var scopedLinks = getVisibleLinks(filteredLinks, baseNodeIds); + var focusResult = applyFocusMode({ + mode: safe.focusMode, + nodes: nodes, + links: scopedLinks, + nodeIds: baseNodeIds, + anchorNodeId: safe.anchorNodeId, + highConfidenceThreshold: safe.highConfidenceThreshold, + coreLimit: safe.coreLimit + }); + var focusNodeIds = focusResult.node_ids || []; + if (!focusNodeIds.length && safe.focusMode && safe.focusMode !== "all") { + return { node_ids: [], nodes: [], links: [], searchIndex: [] }; + } + if (!focusNodeIds.length) focusNodeIds = baseNodeIds; + var focusNodes = nodes.filter(function (node) { + return focusNodeIds.indexOf(node.id) !== -1; + }); + var searchIndex = buildSearchIndex(focusNodes); + var query = typeof safe.searchQuery === "string" ? safe.searchQuery.trim() : ""; + var finalNodeIds = query ? applySearchToNodeIds(searchIndex, query) : focusNodeIds; + var idSet = {}; + for (var i = 0; i < finalNodeIds.length; i++) idSet[finalNodeIds[i]] = true; + return { + node_ids: finalNodeIds, + nodes: nodes.filter(function (node) { + return !!idSet[node.id]; + }), + links: finalNodeIds.length + ? getVisibleLinks(focusResult.links && focusResult.links.length ? focusResult.links : scopedLinks, finalNodeIds) + : [], + searchIndex: searchIndex + }; + } + + function shouldAutoOpenDrawer(mode) { + return mode === "path"; + } + + var ATLAS_CONFIDENCE_LABELS = { + EXTRACTED: "直接提取", + INFERRED: "推断关联", + AMBIGUOUS: "存在歧义", + UNVERIFIED: "未核实" + }; + + var ATLAS_TYPE_LABELS = { + topic: "主题", + entity: "实体", + source: "来源" + }; + + var ATLAS_TYPE_KINDS = { + topic: "TOPIC", + entity: "ENTITY", + source: "SOURCE" + }; + + function normalizeAtlasType(type) { + var normalized = String(type || "entity").toLowerCase(); + return ATLAS_TYPE_LABELS[normalized] ? normalized : "entity"; + } + + function normalizeAtlasConfidence(confidence) { + var normalized = String(confidence || "EXTRACTED").toUpperCase(); + return ATLAS_CONFIDENCE_LABELS[normalized] ? normalized : "EXTRACTED"; + } + + function atlasConfidenceLabel(confidence) { + var normalized = normalizeAtlasConfidence(confidence); + return ATLAS_CONFIDENCE_LABELS[normalized]; + } + + function atlasTypeLabel(type) { + var normalized = normalizeAtlasType(type); + return ATLAS_TYPE_LABELS[normalized]; + } + + function atlasNodeKind(type) { + var normalized = normalizeAtlasType(type); + return ATLAS_TYPE_KINDS[normalized]; + } + + function clampAtlasNumber(value, fallback, min, max) { + var numeric = Number(value); + if (!Number.isFinite(numeric)) numeric = fallback; + if (Number.isFinite(Number(min))) numeric = Math.max(Number(min), numeric); + if (Number.isFinite(Number(max))) numeric = Math.min(Number(max), numeric); + return numeric; + } + + function normalizeAtlasViewportSize(size) { + var safe = size && typeof size === "object" ? size : {}; + return { + width: clampAtlasNumber(safe.width, ATLAS_WORLD_WIDTH, 1, 100000), + height: clampAtlasNumber(safe.height, ATLAS_WORLD_HEIGHT, 1, 100000) + }; + } + + function normalizeAtlasViewport(viewport) { + var safe = viewport && typeof viewport === "object" ? viewport : {}; + return { + x: clampAtlasNumber(safe.x, 0, -1000000, 1000000), + y: clampAtlasNumber(safe.y, 0, -1000000, 1000000), + scale: clampAtlasNumber(safe.scale, 1, ATLAS_MIN_SCALE, ATLAS_MAX_SCALE) + }; + } + + function atlasNodePoint(node) { + var safe = node && typeof node === "object" ? node : {}; + return { + x: clampAtlasNumber(safe.x, 50, 0, 100) / 100 * ATLAS_WORLD_WIDTH, + y: clampAtlasNumber(safe.y, 50, 0, 100) / 100 * ATLAS_WORLD_HEIGHT + }; + } + + function getAtlasModelBounds(nodes, padding) { + var list = Array.isArray(nodes) ? nodes : []; + var pad = Number.isFinite(Number(padding)) ? Math.max(0, Number(padding)) : 48; + if (!list.length) { + return { + x: 0, + y: 0, + width: ATLAS_WORLD_WIDTH, + height: ATLAS_WORLD_HEIGHT, + minX: 0, + minY: 0, + maxX: ATLAS_WORLD_WIDTH, + maxY: ATLAS_WORLD_HEIGHT + }; + } + + var minX = ATLAS_WORLD_WIDTH; + var minY = ATLAS_WORLD_HEIGHT; + var maxX = 0; + var maxY = 0; + list.forEach(function (node) { + var point = atlasNodePoint(node); + minX = Math.min(minX, point.x); + minY = Math.min(minY, point.y); + maxX = Math.max(maxX, point.x); + maxY = Math.max(maxY, point.y); + }); + + minX = clampAtlasNumber(minX - pad, 0, 0, ATLAS_WORLD_WIDTH); + minY = clampAtlasNumber(minY - pad, 0, 0, ATLAS_WORLD_HEIGHT); + maxX = clampAtlasNumber(maxX + pad, ATLAS_WORLD_WIDTH, 0, ATLAS_WORLD_WIDTH); + maxY = clampAtlasNumber(maxY + pad, ATLAS_WORLD_HEIGHT, 0, ATLAS_WORLD_HEIGHT); + + return { + x: minX, + y: minY, + width: Math.max(1, maxX - minX), + height: Math.max(1, maxY - minY), + minX: minX, + minY: minY, + maxX: maxX, + maxY: maxY + }; + } + + function clampAtlasViewport(viewport, viewportSize, options) { + var size = normalizeAtlasViewportSize(viewportSize); + var safe = normalizeAtlasViewport(viewport); + var opts = options && typeof options === "object" ? options : {}; + var minScale = clampAtlasNumber(opts.minScale, ATLAS_MIN_SCALE, 0.1, ATLAS_MAX_SCALE); + var maxScale = clampAtlasNumber(opts.maxScale, ATLAS_MAX_SCALE, minScale, 10); + var marginX = clampAtlasNumber(opts.marginX, size.width * 0.38, 0, size.width); + var marginY = clampAtlasNumber(opts.marginY, size.height * 0.38, 0, size.height); + var scale = clampAtlasNumber(safe.scale, 1, minScale, maxScale); + var scaledWidth = size.width * scale; + var scaledHeight = size.height * scale; + var minX = size.width - scaledWidth - marginX; + var maxX = marginX; + var minY = size.height - scaledHeight - marginY; + var maxY = marginY; + + if (scaledWidth <= size.width) { + var centerX = (size.width - scaledWidth) / 2; + minX = centerX - marginX; + maxX = centerX + marginX; + } + if (scaledHeight <= size.height) { + var centerY = (size.height - scaledHeight) / 2; + minY = centerY - marginY; + maxY = centerY + marginY; + } + + return { + x: clampAtlasNumber(safe.x, 0, minX, maxX), + y: clampAtlasNumber(safe.y, 0, minY, maxY), + scale: scale + }; + } + + function fitAtlasViewport(bounds, viewportSize, options) { + var safeBounds = bounds && typeof bounds === "object" ? bounds : getAtlasModelBounds([]); + var size = normalizeAtlasViewportSize(viewportSize); + var opts = options && typeof options === "object" ? options : {}; + var padding = clampAtlasNumber(opts.padding, 0.84, 0.2, 1); + var minScale = clampAtlasNumber(opts.minScale, ATLAS_MIN_SCALE, 0.1, ATLAS_MAX_SCALE); + var maxScale = clampAtlasNumber(opts.maxScale, 2.15, minScale, ATLAS_MAX_SCALE); + var widthScale = ATLAS_WORLD_WIDTH * padding / Math.max(1, safeBounds.width || 1); + var heightScale = ATLAS_WORLD_HEIGHT * padding / Math.max(1, safeBounds.height || 1); + var scale = clampAtlasNumber(Math.min(widthScale, heightScale), 1, minScale, maxScale); + var centerX = (safeBounds.minX != null && safeBounds.maxX != null) + ? (safeBounds.minX + safeBounds.maxX) / 2 + : (safeBounds.x || 0) + (safeBounds.width || ATLAS_WORLD_WIDTH) / 2; + var centerY = (safeBounds.minY != null && safeBounds.maxY != null) + ? (safeBounds.minY + safeBounds.maxY) / 2 + : (safeBounds.y || 0) + (safeBounds.height || ATLAS_WORLD_HEIGHT) / 2; + + return clampAtlasViewport({ + x: size.width / 2 - scale * (centerX / ATLAS_WORLD_WIDTH * size.width), + y: size.height / 2 - scale * (centerY / ATLAS_WORLD_HEIGHT * size.height), + scale: scale + }, size, opts); + } + + function centerAtlasViewportOnPoint(point, viewportSize, scale, options) { + var safePoint = point && typeof point === "object" ? point : { x: ATLAS_WORLD_WIDTH / 2, y: ATLAS_WORLD_HEIGHT / 2 }; + var size = normalizeAtlasViewportSize(viewportSize); + var viewportScale = clampAtlasNumber(scale, 1, ATLAS_MIN_SCALE, ATLAS_MAX_SCALE); + return clampAtlasViewport({ + x: size.width / 2 - viewportScale * (safePoint.x / ATLAS_WORLD_WIDTH * size.width), + y: size.height / 2 - viewportScale * (safePoint.y / ATLAS_WORLD_HEIGHT * size.height), + scale: viewportScale + }, size, options); + } + + function zoomAtlasViewport(viewport, factor, screenPoint, viewportSize, options) { + var size = normalizeAtlasViewportSize(viewportSize); + var safe = normalizeAtlasViewport(viewport); + var point = screenPoint && typeof screenPoint === "object" + ? { x: clampAtlasNumber(screenPoint.x, size.width / 2, 0, size.width), y: clampAtlasNumber(screenPoint.y, size.height / 2, 0, size.height) } + : { x: size.width / 2, y: size.height / 2 }; + var zoomFactor = clampAtlasNumber(factor, 1, 0.2, 5); + var opts = options && typeof options === "object" ? options : {}; + var minScale = clampAtlasNumber(opts.minScale, ATLAS_MIN_SCALE, 0.1, ATLAS_MAX_SCALE); + var maxScale = clampAtlasNumber(opts.maxScale, ATLAS_MAX_SCALE, minScale, 10); + var nextScale = clampAtlasNumber(safe.scale * zoomFactor, safe.scale, minScale, maxScale); + var ratio = nextScale / safe.scale; + return clampAtlasViewport({ + x: point.x - (point.x - safe.x) * ratio, + y: point.y - (point.y - safe.y) * ratio, + scale: nextScale + }, size, opts); + } + + function atlasViewportRect(viewport, viewportSize) { + var size = normalizeAtlasViewportSize(viewportSize); + var safe = normalizeAtlasViewport(viewport); + var x = (0 - safe.x) / safe.scale / size.width * ATLAS_WORLD_WIDTH; + var y = (0 - safe.y) / safe.scale / size.height * ATLAS_WORLD_HEIGHT; + var width = size.width / safe.scale / size.width * ATLAS_WORLD_WIDTH; + var height = size.height / safe.scale / size.height * ATLAS_WORLD_HEIGHT; + var minX = clampAtlasNumber(x, 0, 0, ATLAS_WORLD_WIDTH); + var minY = clampAtlasNumber(y, 0, 0, ATLAS_WORLD_HEIGHT); + var maxX = clampAtlasNumber(x + width, ATLAS_WORLD_WIDTH, 0, ATLAS_WORLD_WIDTH); + var maxY = clampAtlasNumber(y + height, ATLAS_WORLD_HEIGHT, 0, ATLAS_WORLD_HEIGHT); + return { + x: minX, + y: minY, + width: Math.max(1, maxX - minX), + height: Math.max(1, maxY - minY), + minX: minX, + minY: minY, + maxX: maxX, + maxY: maxY + }; + } + + function atlasPointToMinimap(point) { + var safePoint = point && typeof point === "object" ? point : { x: 0, y: 0 }; + return { + x: MINIMAP_VIEWBOX.x + clampAtlasNumber(safePoint.x, 0, 0, ATLAS_WORLD_WIDTH) / ATLAS_WORLD_WIDTH * MINIMAP_VIEWBOX.width, + y: MINIMAP_VIEWBOX.y + clampAtlasNumber(safePoint.y, 0, 0, ATLAS_WORLD_HEIGHT) / ATLAS_WORLD_HEIGHT * MINIMAP_VIEWBOX.height + }; + } + + function minimapPointToAtlasPoint(point) { + var safePoint = point && typeof point === "object" ? point : { x: MINIMAP_VIEWBOX.x, y: MINIMAP_VIEWBOX.y }; + return { + x: clampAtlasNumber((safePoint.x - MINIMAP_VIEWBOX.x) / MINIMAP_VIEWBOX.width * ATLAS_WORLD_WIDTH, 0, 0, ATLAS_WORLD_WIDTH), + y: clampAtlasNumber((safePoint.y - MINIMAP_VIEWBOX.y) / MINIMAP_VIEWBOX.height * ATLAS_WORLD_HEIGHT, 0, 0, ATLAS_WORLD_HEIGHT) + }; + } + + function atlasViewportToMinimapRect(viewport, viewportSize) { + var rect = atlasViewportRect(viewport, viewportSize); + var topLeft = atlasPointToMinimap({ x: rect.x, y: rect.y }); + var bottomRight = atlasPointToMinimap({ x: rect.x + rect.width, y: rect.y + rect.height }); + return { + x: topLeft.x, + y: topLeft.y, + width: Math.max(2, bottomRight.x - topLeft.x), + height: Math.max(2, bottomRight.y - topLeft.y) + }; + } + + function atlasEndpointId(value) { + if (value && typeof value === "object" && value.id != null) return String(value.id); + return value == null ? "" : String(value); + } + + function stripAtlasMarkdown(raw) { + return String(raw || "") + .replace(/^---[\s\S]*?---\s*/m, "") + .replace(/```[\s\S]*?```/g, " ") + .replace(/!\[[^\]]*\]\([^)]+\)/g, " ") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/\[\[([^\]|]+)\|?([^\]]*)\]\]/g, function (_, target, label) { + return label || target; + }) + .replace(/^#{1,6}\s+/gm, "") + .replace(/^[-*+]\s+/gm, "") + .replace(/^\d+\.\s+/gm, "") + .replace(/[*_`>#]/g, "") + .replace(/\s+/g, " ") + .trim(); + } + + function deriveAtlasSummary(node, content) { + var explicitSummary = node && node.summary != null ? String(node.summary).trim() : ""; + if (explicitSummary) return explicitSummary.length > 170 ? explicitSummary.slice(0, 170).trim() + "…" : explicitSummary; + var summarySource = String(content || (node && node.content) || "").replace(/^#\s+.*(?:\r?\n)+/, ""); + var stripped = stripAtlasMarkdown(summarySource); + if (!stripped) return ""; + return stripped.length > 170 ? stripped.slice(0, 170).trim() + "…" : stripped; + } + + function normalizeAtlasNode(rawNode, index) { + var raw = rawNode && typeof rawNode === "object" ? rawNode : {}; + var id = raw.id == null ? "node-" + index : String(raw.id); + var label = raw.label == null || String(raw.label).trim() === "" ? id : String(raw.label).trim(); + var content = raw.content == null ? "" : String(raw.content); + var type = normalizeAtlasType(raw.type); + var community = raw.community == null || raw.community === "" ? "_none" : String(raw.community); + var x = Number(raw.x); + var y = Number(raw.y); + var hasX = (typeof raw.x === "number" || (typeof raw.x === "string" && raw.x.trim() !== "")) && Number.isFinite(x); + var hasY = (typeof raw.y === "number" || (typeof raw.y === "string" && raw.y.trim() !== "")) && Number.isFinite(y); + return { + id: id, + label: label, + type: type, + type_label: atlasTypeLabel(type), + kind: atlasNodeKind(type), + community: community, + source_path: raw.source_path || raw.source || raw.path || "", + confidence: normalizeAtlasConfidence(raw.confidence || raw.type_confidence), + confidence_label: atlasConfidenceLabel(raw.confidence || raw.type_confidence), + content: content, + summary: deriveAtlasSummary(raw, content), + unavailable: raw.unavailable === true || raw.available === false, + degree: 0, + weight: clampAtlasNumber(raw.weight != null ? raw.weight : raw.score, 50, 0, 100), + priority: 0, + idx: index, + x: hasX ? x : null, + y: hasY ? y : null + }; + } + + function normalizeAtlasEdge(rawEdge, index) { + var raw = rawEdge && typeof rawEdge === "object" ? rawEdge : {}; + var sourceId = atlasEndpointId(raw.from != null ? raw.from : raw.source); + var targetId = atlasEndpointId(raw.to != null ? raw.to : raw.target); + return { + id: raw.id == null ? "edge-" + index : String(raw.id), + source: sourceId, + target: targetId, + from: sourceId, + to: targetId, + type: normalizeAtlasConfidence(raw.type || raw.confidence), + confidence_label: atlasConfidenceLabel(raw.type || raw.confidence), + weight: clampAtlasNumber(raw.weight, 0.6, 0, 1), + signals: raw.signals && typeof raw.signals === "object" ? raw.signals : {}, + source_signal_available: raw.source_signal_available === true + }; + } + + function buildAtlasSearchHaystack(node) { + return [ + node && node.label, + node && node.id, + node && node.type_label, + node && node.source_path, + node && node.summary, + node && stripAtlasMarkdown(node.content) + ].join("\n").toLowerCase(); + } + + function buildAtlasSearchIndex(nodes) { + if (!Array.isArray(nodes)) return []; + return nodes.map(function (node) { + return { node: node, haystack: buildAtlasSearchHaystack(node) }; + }); + } + + function deriveAtlasCommunities(rawGraph, nodes, communityById) { + var learning = normalizeLearning(rawGraph && rawGraph.learning); + var fromLearning = Array.isArray(learning.communities) ? learning.communities : []; + var communities = []; + var seen = {}; + + fromLearning.forEach(function (community) { + if (!community || community.id == null) return; + var id = String(community.id); + var derived = communityById[id] || { nodes: [] }; + seen[id] = true; + communities.push({ + id: id, + label: community.label || id, + node_count: Number.isFinite(Number(community.node_count)) ? Number(community.node_count) : derived.nodes.length, + source_count: Number.isFinite(Number(community.source_count)) ? Number(community.source_count) : 0, + is_primary: community.is_primary === true, + recommended_start_node_id: community.recommended_start_node_id || null, + color_index: communities.length + }); + }); + + Object.keys(communityById).sort().forEach(function (id) { + if (seen[id]) return; + var group = communityById[id]; + var topic = group.nodes.find(function (node) { return node.type === "topic"; }); + communities.push({ + id: id, + label: id === "_none" ? "未分组" : (topic && topic.label) || id, + node_count: group.nodes.length, + source_count: group.nodes.filter(function (node) { return node.type === "source"; }).length, + is_primary: communities.length === 0, + recommended_start_node_id: null, + color_index: communities.length + }); + }); + + communities.sort(function (left, right) { + if (!!right.is_primary !== !!left.is_primary) return right.is_primary ? 1 : -1; + if ((right.node_count || 0) !== (left.node_count || 0)) return (right.node_count || 0) - (left.node_count || 0); + return String(left.label || left.id).localeCompare(String(right.label || right.id)); + }); + communities.forEach(function (community, index) { + community.color_index = index; + }); + return communities; + } + + function buildAtlasStarts(rawGraph, nodes, byId, communities) { + var starts = []; + var seen = {}; + function add(id, reason) { + if (id == null) return; + var nodeId = String(id); + if (!byId[nodeId] || seen[nodeId]) return; + seen[nodeId] = true; + starts.push({ node: byId[nodeId], reason: reason || "" }); + } + var learning = normalizeLearning(rawGraph && rawGraph.learning); + add(learning.entry && learning.entry.recommended_start_node_id, "全局推荐起点"); + communities.forEach(function (community) { + add(community.recommended_start_node_id, community.label + " · 推荐起点"); + }); + nodes.slice().sort(function (left, right) { + return (right.priority || 0) - (left.priority || 0); + }).forEach(function (node) { + if (starts.length < 6) add(node.id, atlasTypeLabel(node.type) + " · " + atlasConfidenceLabel(node.confidence)); + }); + return starts.slice(0, 6); + } + + function normalizeAtlasInsights(insights) { + var safe = insights && typeof insights === "object" ? insights : {}; + return { + surprising_connections: Array.isArray(safe.surprising_connections) ? safe.surprising_connections : [], + isolated_nodes: Array.isArray(safe.isolated_nodes) ? safe.isolated_nodes : [], + bridge_nodes: Array.isArray(safe.bridge_nodes) ? safe.bridge_nodes : [], + sparse_communities: Array.isArray(safe.sparse_communities) ? safe.sparse_communities : [], + meta: safe.meta && typeof safe.meta === "object" ? safe.meta : { degraded: false } + }; + } + + function buildAtlasModel(rawGraph) { + var raw = rawGraph && typeof rawGraph === "object" ? rawGraph : {}; + var nodes = Array.isArray(raw.nodes) ? raw.nodes.map(normalizeAtlasNode) : []; + var byId = {}; + var communityById = {}; + nodes.forEach(function (node) { + byId[node.id] = node; + if (!communityById[node.community]) communityById[node.community] = { id: node.community, nodes: [] }; + communityById[node.community].nodes.push(node); + }); + + var edges = (Array.isArray(raw.edges) ? raw.edges : []) + .map(normalizeAtlasEdge) + .filter(function (edge) { + return !!(byId[edge.source] && byId[edge.target]); + }); + + edges.forEach(function (edge) { + byId[edge.source].degree += 1; + byId[edge.target].degree += 1; + }); + nodes.forEach(function (node) { + node.priority = node.degree * 12 + node.weight + (node.type === "topic" ? 12 : node.type === "source" ? 6 : 0); + }); + + var communities = deriveAtlasCommunities(raw, nodes, communityById); + var communityMap = {}; + communities.forEach(function (community) { + communityMap[community.id] = community; + }); + + return { + meta: { + wiki_title: raw.meta && raw.meta.wiki_title ? String(raw.meta.wiki_title) : "知识库", + total_nodes: nodes.length, + total_edges: edges.length, + build_date: raw.meta && raw.meta.build_date ? String(raw.meta.build_date) : "" + }, + nodes: nodes, + edges: edges, + byId: byId, + communities: communities, + communityById: communityMap, + starts: buildAtlasStarts(raw, nodes, byId, communities), + searchIndex: buildAtlasSearchIndex(nodes), + insights: normalizeAtlasInsights(raw.insights) + }; + } + + function deriveAtlasLayout(model) { + var safe = model && typeof model === "object" ? model : { nodes: [], communities: [] }; + var centers = [ + { x: 50, y: 48 }, + { x: 30, y: 34 }, + { x: 70, y: 36 }, + { x: 30, y: 72 }, + { x: 72, y: 70 }, + { x: 18, y: 52 }, + { x: 84, y: 52 }, + { x: 50, y: 78 } + ]; + var communityIndex = {}; + (safe.communities || []).forEach(function (community, index) { + communityIndex[community.id] = index; + }); + var grouped = {}; + (safe.nodes || []).forEach(function (node) { + if (!grouped[node.community]) grouped[node.community] = []; + grouped[node.community].push(node); + }); + Object.keys(grouped).forEach(function (communityId) { + grouped[communityId].sort(function (left, right) { + return (right.priority || 0) - (left.priority || 0); + }); + var center = centers[(communityIndex[communityId] || 0) % centers.length]; + var count = grouped[communityId].length; + grouped[communityId].forEach(function (node, index) { + if (node.x != null && node.y != null && Number.isFinite(Number(node.x)) && Number.isFinite(Number(node.y))) { + node.x = clampAtlasNumber(node.x, center.x, 5, 95); + node.y = clampAtlasNumber(node.y, center.y, 8, 92); + return; + } + var ring = Math.floor(index / 8); + var ringIndex = index % 8; + var angle = ((ringIndex / Math.min(8, Math.max(1, count))) * Math.PI * 2) + ring * 0.42; + var radiusX = 7 + ring * 5 + Math.min(5, count * 0.16); + var radiusY = 5 + ring * 4 + Math.min(4, count * 0.12); + node.x = clampAtlasNumber(center.x + Math.cos(angle) * radiusX, center.x, 5, 95); + node.y = clampAtlasNumber(center.y + Math.sin(angle) * radiusY, center.y, 8, 92); + }); + }); + return { + nodes: (safe.nodes || []).slice(), + edges: (safe.edges || []).slice(), + nodePositions: (safe.nodes || []).reduce(function (out, node) { + out[node.id] = { x: node.x, y: node.y }; + return out; + }, {}) + }; + } + + function getAtlasDensityMode(count) { + var nodeCount = Number.isFinite(Number(count)) ? Number(count) : 0; + if (nodeCount > 500) return "overview"; + if (nodeCount > 200) return "point-plus-focus"; + if (nodeCount > 80) return "compact-card"; + return "card"; + } + + function atlasLabelBudget(mode, count) { + if (mode === "overview") return 40; + if (mode === "point-plus-focus") return 60; + if (mode === "compact-card") return Math.min(120, count); + return count; + } + + function atlasEdgeBudget(mode, count) { + if (mode === "overview") return 1000; + if (mode === "point-plus-focus") return 800; + return count; + } + + function resolveAtlasVisibleSnapshot(model, layout, uiState) { + var safeModel = model && typeof model === "object" ? model : buildAtlasModel({}); + var safeUI = uiState && typeof uiState === "object" ? uiState : {}; + var activeCommunityId = safeUI.activeCommunityId == null ? "all" : String(safeUI.activeCommunityId); + var query = typeof safeUI.query === "string" ? safeUI.query.trim().toLowerCase() : ""; + var focusMode = safeUI.focusMode || "all"; + var selectedNodeId = safeUI.selectedNodeId == null ? null : String(safeUI.selectedNodeId); + var filters = safeUI.filters && typeof safeUI.filters === "object" ? safeUI.filters : {}; + + var baseNodes = safeModel.nodes.filter(function (node) { + if (activeCommunityId !== "all" && node.community !== activeCommunityId) return false; + if (focusMode === "source" && node.type !== "source") return false; + return true; + }); + + if (focusMode === "core" && baseNodes.length > 8) { + var keepCount = Math.max(8, Math.ceil(baseNodes.length * 0.45)); + var keep = {}; + baseNodes.slice().sort(function (left, right) { + return (right.priority || 0) - (left.priority || 0); + }).slice(0, keepCount).forEach(function (node) { + keep[node.id] = true; + }); + if (selectedNodeId && safeModel.byId[selectedNodeId]) keep[selectedNodeId] = true; + baseNodes = baseNodes.filter(function (node) { return !!keep[node.id]; }); + } + + var baseIdSet = {}; + baseNodes.forEach(function (node) { baseIdSet[node.id] = true; }); + var searchIndex = buildAtlasSearchIndex(baseNodes); + var matchedIds = {}; + var visibleNodes = !query + ? baseNodes + : searchIndex.filter(function (entry) { + return entry.haystack.indexOf(query) !== -1; + }).map(function (entry) { + matchedIds[entry.node.id] = true; + return entry.node; + }); + var visibleIdSet = {}; + visibleNodes.forEach(function (node) { visibleIdSet[node.id] = true; }); + + var visibleEdges = safeModel.edges.filter(function (edge) { + var edgeType = edge.type || "EXTRACTED"; + if (filters[edgeType] === false) return false; + return !!(visibleIdSet[edge.source] && visibleIdSet[edge.target]); + }); + + var densityMode = getAtlasDensityMode(visibleNodes.length); + var labelBudget = atlasLabelBudget(densityMode, visibleNodes.length); + var labelNodeIds = {}; + var startNodeIds = {}; + var importantNodeIds = {}; + var visibleStartEntries = safeModel.starts.filter(function (entry) { + return !!(entry && entry.node && visibleIdSet[entry.node.id]) && + (activeCommunityId === "all" || entry.node.community === activeCommunityId); + }); + + visibleStartEntries.forEach(function (entry) { + startNodeIds[entry.node.id] = true; + importantNodeIds[entry.node.id] = true; + }); + + visibleNodes.slice().sort(function (left, right) { + return (right.priority || 0) - (left.priority || 0); + }).slice(0, Math.max(0, Math.min(8, Math.ceil(visibleNodes.length * 0.08)))).forEach(function (node) { + importantNodeIds[node.id] = true; + }); + + visibleNodes.slice().sort(function (left, right) { + var leftForced = (selectedNodeId === left.id || matchedIds[left.id] || importantNodeIds[left.id]) ? 1 : 0; + var rightForced = (selectedNodeId === right.id || matchedIds[right.id] || importantNodeIds[right.id]) ? 1 : 0; + if (rightForced !== leftForced) return rightForced - leftForced; + return (right.priority || 0) - (left.priority || 0); + }).slice(0, labelBudget).forEach(function (node) { + labelNodeIds[node.id] = true; + }); + if (selectedNodeId && visibleIdSet[selectedNodeId]) labelNodeIds[selectedNodeId] = true; + Object.keys(matchedIds).forEach(function (id) { + if (visibleIdSet[id]) { + labelNodeIds[id] = true; + importantNodeIds[id] = true; + } + }); + Object.keys(startNodeIds).forEach(function (id) { + if (visibleIdSet[id]) labelNodeIds[id] = true; + }); + if (selectedNodeId && visibleIdSet[selectedNodeId]) importantNodeIds[selectedNodeId] = true; + + var edgeBudget = atlasEdgeBudget(densityMode, visibleEdges.length); + visibleEdges = visibleEdges.slice().sort(function (left, right) { + var leftSelected = selectedNodeId && (left.source === selectedNodeId || left.target === selectedNodeId) ? 1 : 0; + var rightSelected = selectedNodeId && (right.source === selectedNodeId || right.target === selectedNodeId) ? 1 : 0; + if (rightSelected !== leftSelected) return rightSelected - leftSelected; + return (right.weight || 0) - (left.weight || 0); + }).slice(0, edgeBudget); + + return { + node_ids: visibleNodes.map(function (node) { return node.id; }), + nodes: visibleNodes, + edges: visibleEdges, + links: visibleEdges, + searchIndex: searchIndex, + densityMode: densityMode, + labelNodeIds: labelNodeIds, + matchedNodeIds: matchedIds, + importantNodeIds: importantNodeIds, + startNodeIds: startNodeIds, + starts: visibleStartEntries, + counts: { + visible_nodes: visibleNodes.length, + visible_edges: visibleEdges.length, + total_nodes: safeModel.nodes.length, + total_edges: safeModel.edges.length, + total_communities: safeModel.communities.length + } + }; + } + + function resolveAtlasSelectedNodeId(model, visibleSnapshot, selectedNodeId) { + var safeModel = model && typeof model === "object" ? model : buildAtlasModel({}); + var selected = selectedNodeId == null ? null : String(selectedNodeId); + var visible = visibleSnapshot && typeof visibleSnapshot === "object" ? visibleSnapshot : null; + var visibleIds = {}; + if (visible && Array.isArray(visible.node_ids)) { + visible.node_ids.forEach(function (id) { visibleIds[String(id)] = true; }); + } + + if (selected && safeModel.byId && safeModel.byId[selected] && (!visible || visibleIds[selected])) { + return selected; + } + return null; + } + + var helpers = { + splitLabelGraphemes: splitLabelGraphemes, + labelCharWidth: labelCharWidth, + measureLabelWidth: measureLabelWidth, + truncateLabel: truncateLabel, + cardDims: cardDims, + createSafeStorage: createSafeStorage, + getWikiStorageNamespace: getWikiStorageNamespace, + defaultQueue: defaultQueue, + normalizeQueue: normalizeQueue, + toggleQueueFavorite: toggleQueueFavorite, + appendQueueNote: appendQueueNote, + summarizeQueue: summarizeQueue, + defaultLearning: defaultLearning, + normalizeLearning: normalizeLearning, + resolveInitialMode: resolveInitialMode, + getCommunityNodeIds: getCommunityNodeIds, + getVisibleNodeIds: getVisibleNodeIds, + getVisibleLinks: getVisibleLinks, + buildSearchHaystack: buildSearchHaystack, + buildSearchIndex: buildSearchIndex, + filterLinksByTypes: filterLinksByTypes, + applySearchToNodeIds: applySearchToNodeIds, + applyFocusMode: applyFocusMode, + resolveVisibleSnapshot: resolveVisibleSnapshot, + shouldAutoOpenDrawer: shouldAutoOpenDrawer, + buildAtlasModel: buildAtlasModel, + deriveAtlasLayout: deriveAtlasLayout, + resolveAtlasVisibleSnapshot: resolveAtlasVisibleSnapshot, + resolveAtlasSelectedNodeId: resolveAtlasSelectedNodeId, + getAtlasDensityMode: getAtlasDensityMode, + normalizeAtlasViewport: normalizeAtlasViewport, + atlasNodePoint: atlasNodePoint, + getAtlasModelBounds: getAtlasModelBounds, + clampAtlasViewport: clampAtlasViewport, + fitAtlasViewport: fitAtlasViewport, + centerAtlasViewportOnPoint: centerAtlasViewportOnPoint, + zoomAtlasViewport: zoomAtlasViewport, + atlasViewportRect: atlasViewportRect, + atlasPointToMinimap: atlasPointToMinimap, + minimapPointToAtlasPoint: minimapPointToAtlasPoint, + atlasViewportToMinimapRect: atlasViewportToMinimapRect, + atlasConfidenceLabel: atlasConfidenceLabel, + atlasTypeLabel: atlasTypeLabel, + atlasNodeKind: atlasNodeKind, + stripAtlasMarkdown: stripAtlasMarkdown + }; + + root.WikiGraphWashHelpers = helpers; + if (typeof module !== "undefined" && module.exports) { + module.exports = helpers; + } +})(typeof window !== "undefined" ? window : this); diff --git a/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash.js b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash.js new file mode 100644 index 000000000..1cfa96c0e --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/graph-wash.js @@ -0,0 +1,1009 @@ +/* DEPRECATED: Legacy wash runtime retained for one release cycle after Stage 4 engine HTML migration. Do not extend; use packages/graph-engine instead. */ +/* ============================================================ + Knowledge Graph - Oriental editorial atlas runtime + ============================================================ */ +(function () { + "use strict"; + + const helpers = window.WikiGraphWashHelpers; + if (!helpers) { + console.error("[wiki] graph-wash-helpers.js is missing or failed to load"); + return; + } + + const { + createSafeStorage, + getWikiStorageNamespace, + defaultQueue, + normalizeQueue, + toggleQueueFavorite, + appendQueueNote, + summarizeQueue, + buildAtlasModel, + deriveAtlasLayout, + resolveAtlasVisibleSnapshot, + resolveAtlasSelectedNodeId, + atlasNodePoint, + getAtlasModelBounds, + fitAtlasViewport, + centerAtlasViewportOnPoint, + zoomAtlasViewport, + atlasViewportToMinimapRect, + atlasPointToMinimap, + minimapPointToAtlasPoint, + atlasConfidenceLabel, + atlasTypeLabel, + atlasNodeKind, + stripAtlasMarkdown + } = helpers; + + const DENSITY_SMALL_LIMIT = 80; + const DENSITY_MEDIUM_LIMIT = 200; + const DENSITY_LARGE_LIMIT = 500; + const QUEUE_NOTE_LIMIT = 50; + const NOTE_EXCERPT_LIMIT = 140; + const COMMUNITY_COLORS = ["#8b2e24", "#315f72", "#4b7564", "#b7791f", "#6f557f", "#3e6b4b", "#9b6a36", "#5d6f91"]; + + const dataEl = document.getElementById("graph-data"); + let DATA; + let dataError = false; + try { + DATA = dataEl ? JSON.parse(dataEl.textContent) : window.SAMPLE_GRAPH; + } catch (err) { + console.error("[wiki] graph data parse failed:", err); + DATA = { meta: {}, nodes: [], edges: [], insights: { meta: { degraded: true } } }; + dataError = true; + } + + const app = document.getElementById("app"); + const atlas = document.getElementById("atlas"); + const nodeLayer = document.getElementById("node-layer"); + const edgeLayer = document.getElementById("edge-layer"); + const communityList = document.getElementById("community-list"); + const startList = document.getElementById("start-list"); + const searchInput = document.getElementById("search"); + const noResults = document.getElementById("no-results"); + const canvasTitle = document.getElementById("canvas-title"); + const canvasSubtitle = document.getElementById("canvas-subtitle"); + const insightTitle = document.getElementById("insight-title"); + const insightCopy = document.getElementById("insight-copy"); + const drawer = document.getElementById("drawer"); + const drawerNeighbors = document.getElementById("neighbor-details"); + const drawerNeighborsHeading = drawerNeighbors ? drawerNeighbors.querySelector("summary") : null; + const neighborList = document.getElementById("neighbor-list"); + const minimapEl = document.getElementById("minimap"); + const minimapToggle = document.getElementById("minimap-toggle"); + const minimapSvg = document.getElementById("mini-map-svg"); + + if (!atlas || !nodeLayer || !edgeLayer) { + console.error("[wiki] atlas shell is incomplete"); + return; + } + + let rawLocalStorage = null; + try { + rawLocalStorage = window.localStorage; + } catch (_) {} + + const atlasModel = buildAtlasModel(DATA); + const atlasLayout = deriveAtlasLayout(atlasModel); + const safeLocalStorage = createSafeStorage(rawLocalStorage, console.warn); + const storageNamespace = getWikiStorageNamespace(atlasModel.meta, window.location && window.location.pathname); + + const state = { + atlasModel, + atlasLayout, + queue: loadQueueState(), + ui: { + selectedNodeId: null, + activeCommunityId: "all", + focusMode: "all", + query: "", + dimUnselected: false, + dataMode: dataError ? "error" : (atlasModel.nodes.length ? "normal" : "empty"), + neighborExpanded: false, + filters: { EXTRACTED: true, INFERRED: true, AMBIGUOUS: true, UNVERIFIED: true } + }, + viewport: { x: 0, y: 0, scale: 1 }, + viewportReady: false, + visible: null + }; + + let viewportPaintFrame = 0; + let panState = null; + + function queueStorageKey(name) { + return storageNamespace + ":" + name; + } + + function loadQueueState() { + const raw = safeLocalStorage.get(queueStorageKey("queue")); + if (!raw) return defaultQueue(); + try { + return normalizeQueue(JSON.parse(raw)); + } catch (err) { + console.warn("[wiki] queue storage parse failed:", err); + return defaultQueue(); + } + } + + function persistQueueState() { + safeLocalStorage.set(queueStorageKey("queue"), JSON.stringify(state.queue)); + } + + function escapeHtml(value) { + return String(value == null ? "" : value).replace(/[&<>"']/g, (ch) => ({ + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'" + })[ch]); + } + + function clampWeight(value) { + const numeric = Number(value); + if (!Number.isFinite(numeric)) return 0.6; + return Math.max(0, Math.min(1, numeric)); + } + + function edgeStrokeWidth(edge) { + return 1.1 + clampWeight(edge && edge.weight) * 1.8; + } + + function edgeOpacity(edge) { + return 0.32 + clampWeight(edge && edge.weight) * 0.44; + } + + function edgeStrengthSize(edge) { + return 6 + clampWeight(edge && edge.weight) * 8; + } + + function currentDensityMode() { + return state.visible ? state.visible.densityMode : "card"; + } + + function communityColor(communityId) { + const community = state.atlasModel.communityById[communityId]; + const index = community ? community.color_index || 0 : 0; + return COMMUNITY_COLORS[index % COMMUNITY_COLORS.length]; + } + + function getSelectedNode() { + const selectedNodeId = resolveAtlasSelectedNodeId(state.atlasModel, state.visible, state.ui.selectedNodeId); + return selectedNodeId ? state.atlasModel.byId[selectedNodeId] || null : null; + } + + function getPreviewStartEntry(visibleSnapshot) { + if (state.ui.selectedNodeId) return null; + const visible = visibleSnapshot || state.visible || refreshVisibleSnapshot(); + const visibleIds = new Set((visible.node_ids || []).map(String)); + const starts = visible.starts && visible.starts.length + ? visible.starts + : state.atlasModel.starts.filter((entry) => entry && entry.node && visibleIds.has(entry.node.id)); + if (starts.length) return starts[0]; + const fallback = (visible.nodes || []).slice().filter((node) => { + return node && (node.summary || node.content || node.source_path); + }).sort((left, right) => (right.priority || 0) - (left.priority || 0))[0]; + return fallback ? { node: fallback, reason: "当前范围 · 推荐预览" } : null; + } + + function refreshVisibleSnapshot() { + state.visible = resolveAtlasVisibleSnapshot(state.atlasModel, state.atlasLayout, state.ui); + state.ui.selectedNodeId = resolveAtlasSelectedNodeId(state.atlasModel, state.visible, state.ui.selectedNodeId); + return state.visible; + } + + function currentViewportSize() { + const rect = atlas.getBoundingClientRect(); + return { + width: rect && rect.width ? rect.width : 1000, + height: rect && rect.height ? rect.height : 680 + }; + } + + function viewportOptions() { + return { minScale: 0.62, maxScale: 3.2 }; + } + + function edgeTransformForViewport(viewport, size) { + const safeSize = size || currentViewportSize(); + const x = (viewport.x / safeSize.width) * 1000; + const y = (viewport.y / safeSize.height) * 680; + return `translate(${x} ${y}) scale(${viewport.scale})`; + } + + function applyViewportTransform() { + const size = currentViewportSize(); + if (nodeLayer) { + nodeLayer.style.transform = `translate(${state.viewport.x}px, ${state.viewport.y}px) scale(${state.viewport.scale})`; + } + if (edgeLayer) { + edgeLayer.setAttribute("transform", edgeTransformForViewport(state.viewport, size)); + } + updateMinimapViewport(); + } + + function updateMinimapViewport() { + if (!minimapSvg) return; + const rect = minimapSvg.querySelector(".mini-map-viewport"); + if (!rect) return; + const miniRect = atlasViewportToMinimapRect(state.viewport, currentViewportSize()); + rect.setAttribute("x", String(miniRect.x)); + rect.setAttribute("y", String(miniRect.y)); + rect.setAttribute("width", String(miniRect.width)); + rect.setAttribute("height", String(miniRect.height)); + } + + function scheduleViewportPaint() { + if (viewportPaintFrame) return; + viewportPaintFrame = window.requestAnimationFrame(() => { + viewportPaintFrame = 0; + applyViewportTransform(); + }); + } + + function setViewport(nextViewport, immediate) { + state.viewport = helpers.clampAtlasViewport(nextViewport, currentViewportSize(), viewportOptions()); + if (immediate) { + if (viewportPaintFrame) { + window.cancelAnimationFrame(viewportPaintFrame); + viewportPaintFrame = 0; + } + applyViewportTransform(); + } else { + scheduleViewportPaint(); + } + } + + function fitVisibleViewport() { + const visible = state.visible || refreshVisibleSnapshot(); + const bounds = getAtlasModelBounds(visible.nodes, visible.nodes.length <= 1 ? 160 : 56); + setViewport(fitAtlasViewport(bounds, currentViewportSize(), { padding: 0.82, minScale: 0.62, maxScale: 1.18 }), true); + state.viewportReady = true; + } + + function centerViewportOnNode(nodeId) { + const node = state.atlasModel.byId[nodeId]; + if (!node) return; + const scale = Math.max(1.05, Math.min(state.viewport.scale || 1, 1.6)); + setViewport(centerAtlasViewportOnPoint(atlasNodePoint(node), currentViewportSize(), scale, viewportOptions()), true); + state.viewportReady = true; + } + + function makePath(a, b, edge) { + const sourcePoint = atlasNodePoint(a); + const targetPoint = atlasNodePoint(b); + const x1 = sourcePoint.x; + const y1 = sourcePoint.y; + const x2 = targetPoint.x; + const y2 = targetPoint.y; + const mx = (x1 + x2) / 2; + const my = (y1 + y2) / 2; + const curve = Math.max(-76, Math.min(76, (a.y - b.y) * 1.8 + (clampWeight(edge.weight) - 0.5) * 24)); + return `M ${x1} ${y1} Q ${mx + curve} ${my - 22} ${x2} ${y2}`; + } + + function edgeClass(edge) { + return String(edge.type || "EXTRACTED").toLowerCase(); + } + + function connectedIds(id) { + const out = new Set([id]); + state.atlasModel.edges.forEach((edge) => { + if (edge.source === id) out.add(edge.target); + if (edge.target === id) out.add(edge.source); + }); + return out; + } + + function isNodeImportant(node) { + return !!(node && state.visible && state.visible.importantNodeIds && state.visible.importantNodeIds[node.id]); + } + + function nodeVisualRole(node, displayMode, previewNodeId) { + if (!node) return "landmark"; + if (node.id === state.ui.selectedNodeId) return "cinnabar-note"; + if (displayMode === "point" || displayMode === "overview") return "map-pin"; + if (state.visible && state.visible.matchedNodeIds[node.id]) return "index-slip"; + if (previewNodeId && node.id === previewNodeId) return "index-slip"; + if (isNodeImportant(node)) return "index-slip"; + return "landmark"; + } + + function nodeDisplayMode(node, previewNodeId) { + const mode = currentDensityMode(); + if (!node) return "card"; + if (node.id === state.ui.selectedNodeId) return "card"; + if (state.visible && state.visible.matchedNodeIds[node.id]) return "card"; + if (previewNodeId && node.id === previewNodeId && (mode === "overview" || mode === "point-plus-focus")) return "compact-card"; + if (isNodeImportant(node) && (mode === "overview" || mode === "point-plus-focus")) return "compact-card"; + if (mode === "overview") return state.visible.labelNodeIds[node.id] ? "compact-card" : "overview"; + if (mode === "point-plus-focus") return state.visible.labelNodeIds[node.id] ? "compact-card" : "point"; + return mode; + } + + function renderTopbar() { + const title = document.getElementById("wiki-title"); + if (title) title.textContent = `${state.atlasModel.meta.wiki_title} 知识舆图`; + } + + function renderSidebar() { + if (!communityList || !startList) return; + + const visible = state.visible || refreshVisibleSnapshot(); + communityList.innerHTML = ""; + + const allButton = document.createElement("button"); + allButton.className = "nav-item"; + allButton.type = "button"; + allButton.dataset.community = "all"; + allButton.setAttribute("aria-pressed", state.ui.activeCommunityId === "all" ? "true" : "false"); + allButton.innerHTML = ` + + 全部社区${state.atlasModel.nodes.length} 个节点 + ALL + `; + allButton.addEventListener("click", () => setCommunity("all")); + communityList.appendChild(allButton); + + state.atlasModel.communities.forEach((community) => { + const button = document.createElement("button"); + button.className = "nav-item"; + button.type = "button"; + button.dataset.community = community.id; + button.setAttribute("aria-pressed", state.ui.activeCommunityId === community.id ? "true" : "false"); + button.innerHTML = ` + + ${escapeHtml(community.label)}${community.node_count || 0} 个节点 + ${community.node_count || 0} + `; + button.addEventListener("click", () => setCommunity(community.id)); + communityList.appendChild(button); + }); + + startList.innerHTML = ""; + const previewEntry = getPreviewStartEntry(visible); + const previewNodeId = previewEntry && previewEntry.node ? previewEntry.node.id : null; + const starts = visible.starts.length ? visible.starts : state.atlasModel.starts; + starts.slice(0, 4).forEach((entry) => { + const node = entry.node; + const button = document.createElement("button"); + button.className = "start-card"; + button.type = "button"; + button.dataset.previewStart = node.id === previewNodeId ? "true" : "false"; + button.innerHTML = `${escapeHtml(node.label)}${escapeHtml(entry.reason || atlasTypeLabel(node.type))}`; + button.addEventListener("click", () => focusNode(node.id, true)); + startList.appendChild(button); + }); + if (!startList.children.length) { + const empty = document.createElement("div"); + empty.className = "note-card"; + empty.textContent = "暂无推荐起点。"; + startList.appendChild(empty); + } + + const summary = summarizeQueue(state.queue, state.atlasModel.byId, 3); + const metrics = document.querySelectorAll(".queue-metrics .metric b"); + if (metrics[0]) metrics[0].textContent = summary.favorite_count; + if (metrics[1]) metrics[1].textContent = summary.note_count; + const queueList = document.querySelector(".queue-list"); + if (queueList) { + queueList.innerHTML = ""; + if (!summary.recent_items.length) { + const empty = document.createElement("div"); + empty.className = "note-card"; + empty.textContent = "选中节点后可加入学习队列。"; + queueList.appendChild(empty); + return; + } + summary.recent_items.slice(0, 3).forEach((item) => { + const node = state.atlasModel.byId[item.node_id]; + const button = document.createElement("button"); + const kindLabel = item.kind === "note" ? "札记" : "待读"; + const meta = node ? `${atlasTypeLabel(node.type)} · ${atlasConfidenceLabel(node.confidence)}` : "队列条目"; + button.className = "queue-item"; + button.type = "button"; + button.dataset.kind = item.kind; + button.setAttribute("aria-current", item.node_id === state.ui.selectedNodeId ? "true" : "false"); + button.innerHTML = ` + + ${escapeHtml(item.label)}${escapeHtml(meta)} + ${kindLabel} + `; + button.addEventListener("click", () => focusNode(item.node_id, true)); + queueList.appendChild(button); + }); + } + } + + function renderCanvas() { + const visible = state.visible || refreshVisibleSnapshot(); + atlas.dataset.mode = state.ui.dataMode; + atlas.dataset.density = visible.densityMode; + + edgeLayer.innerHTML = ""; + visible.edges.forEach((edge) => { + const source = state.atlasModel.byId[edge.source]; + const target = state.atlasModel.byId[edge.target]; + if (!source || !target) return; + const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + path.setAttribute("d", makePath(source, target, edge)); + path.setAttribute("class", `edge ${edgeClass(edge)}`); + path.setAttribute("data-from", edge.source); + path.setAttribute("data-to", edge.target); + path.setAttribute("data-edge-id", edge.id); + path.style.strokeWidth = edgeStrokeWidth(edge); + path.style.opacity = edgeOpacity(edge); + edgeLayer.appendChild(path); + }); + + nodeLayer.innerHTML = ""; + const previewEntry = getPreviewStartEntry(visible); + const previewNodeId = previewEntry && previewEntry.node ? previewEntry.node.id : null; + visible.nodes.forEach((node) => { + const displayMode = nodeDisplayMode(node, previewNodeId); + const visualRole = nodeVisualRole(node, displayMode, previewNodeId); + const button = document.createElement("button"); + button.className = "node"; + if (node.unavailable) button.classList.add("is-disabled"); + if (displayMode === "compact-card") button.classList.add("is-compact"); + if (displayMode === "point") button.classList.add("is-point"); + if (displayMode === "overview") button.classList.add("is-overview"); + if (visualRole === "index-slip") button.classList.add("is-index-slip"); + if (visualRole === "cinnabar-note") button.classList.add("is-cinnabar-note"); + if (visualRole === "map-pin") button.classList.add("is-map-pin"); + if (node.id === previewNodeId) button.classList.add("is-preview-start"); + if (state.visible && !state.visible.labelNodeIds[node.id]) button.classList.add("is-label-hidden"); + button.type = "button"; + button.dataset.id = node.id; + button.dataset.type = node.type; + button.dataset.community = node.community; + button.dataset.densityMode = displayMode; + button.dataset.visualRole = visualRole; + button.dataset.startNode = state.visible && state.visible.startNodeIds[node.id] ? "true" : "false"; + button.dataset.previewStart = node.id === previewNodeId ? "true" : "false"; + button.style.left = `${node.x}%`; + button.style.top = `${node.y}%`; + button.title = node.label; + button.setAttribute("aria-pressed", node.id === state.ui.selectedNodeId ? "true" : "false"); + button.innerHTML = ` + ${node.kind} + ${escapeHtml(node.label)} + ${node.unavailable ? "来源暂不可用" : Math.round(node.priority || node.weight || 0)} + `; + button.addEventListener("click", () => selectNode(node.id)); + button.addEventListener("mouseenter", () => highlightNeighborhood(node.id)); + button.addEventListener("mouseleave", () => applyFilters()); + nodeLayer.appendChild(button); + }); + + applyFilters(); + renderMinimap(); + applyViewportTransform(); + } + + function setDrawerActions(mode, node) { + const queueAction = document.getElementById("queue-action"); + const sourceAction = document.getElementById("source-action"); + if (queueAction) { + queueAction.textContent = mode === "preview" ? "从这里开始" : "加入学习队列"; + queueAction.disabled = mode === "empty"; + } + if (sourceAction) { + sourceAction.textContent = "查看来源"; + sourceAction.disabled = !(node && node.source_path); + } + } + + function renderStartPreview(entry) { + const node = entry && entry.node; + if (!node) return false; + const neighbors = getNeighbors(node.id); + const community = state.atlasModel.communityById[node.community]; + const communityLabel = community ? community.label : "未分组"; + const excerpt = stripAtlasMarkdown(node.content || node.summary || "").slice(0, 220); + + document.getElementById("drawer-kind").innerHTML = `从这里开始 · 预览`; + document.getElementById("drawer-title").textContent = node.label; + document.getElementById("drawer-subtitle").textContent = `${entry.reason || atlasTypeLabel(node.type)} · ${communityLabel} · 点击后进入阅读态`; + document.getElementById("drawer-summary").textContent = node.summary || excerpt || "这个节点适合作为当前图谱的起点。"; + document.getElementById("drawer-neighbor-count").textContent = `${neighbors.length} 个`; + + const content = document.getElementById("drawer-content"); + if (content) { + content.innerHTML = ` +

这是一条推荐起点预览。全局图仍保持中立,点击“从这里开始”或左侧推荐起点后,才会进入选中阅读态。

+

${escapeHtml(excerpt || node.summary || "当前节点暂无正文,但可以从相邻节点继续展开。")}

+ `; + } + + if (neighborList) { + neighborList.innerHTML = ""; + if (!neighbors.length) { + const empty = document.createElement("div"); + empty.className = "note-card"; + empty.textContent = "这个起点暂时没有相邻节点。"; + neighborList.appendChild(empty); + } + neighbors.slice(0, 4).forEach((entryItem) => { + const neighbor = entryItem.node; + const button = document.createElement("button"); + button.className = "neighbor-card"; + button.type = "button"; + button.innerHTML = `${escapeHtml(neighbor.label)}${atlasTypeLabel(neighbor.type)} · ${atlasConfidenceLabel(entryItem.edge.type)}`; + button.addEventListener("click", () => focusNode(neighbor.id, true)); + neighborList.appendChild(button); + }); + } + + setDrawerActions("preview", node); + return true; + } + + function renderDrawer() { + const selected = getSelectedNode(); + if (!drawer) return; + const previewEntry = getPreviewStartEntry(); + if (app) { + app.dataset.reading = selected ? "1" : "0"; + app.dataset.startPreview = !selected && previewEntry ? "1" : "0"; + } + drawer.dataset.state = selected ? "reading" : (previewEntry ? "start-preview" : "empty"); + if (!selected && previewEntry && renderStartPreview(previewEntry)) return; + if (!selected) { + setDrawerActions("empty", null); + document.getElementById("drawer-kind").innerHTML = `当前范围`; + document.getElementById("drawer-title").textContent = "没有匹配节点"; + document.getElementById("drawer-subtitle").textContent = "调整搜索或筛选后查看知识内容"; + document.getElementById("drawer-summary").textContent = "当前范围内没有可显示的节点。"; + document.getElementById("drawer-neighbor-count").textContent = "0 个"; + const content = document.getElementById("drawer-content"); + if (content) content.innerHTML = "

清除搜索词或切回全部社区后,可以继续查看节点摘要和知识内容。

"; + if (neighborList) { + neighborList.innerHTML = ""; + const empty = document.createElement("div"); + empty.className = "note-card"; + empty.textContent = "暂无相邻节点。"; + neighborList.appendChild(empty); + } + return; + } + state.ui.selectedNodeId = selected.id; + setDrawerActions("reading", selected); + + const neighbors = getNeighbors(selected.id); + const community = state.atlasModel.communityById[selected.community]; + const communityLabel = community ? community.label : "未分组"; + + document.getElementById("drawer-kind").innerHTML = `${atlasTypeLabel(selected.type)} · 已选中`; + document.getElementById("drawer-title").textContent = selected.label; + document.getElementById("drawer-subtitle").textContent = `${communityLabel} · ${atlasConfidenceLabel(selected.confidence)}${selected.source_path ? " · " + selected.source_path : ""}`; + document.getElementById("drawer-summary").textContent = selected.summary || "暂无摘要。"; + document.getElementById("drawer-neighbor-count").textContent = `${neighbors.length} 个`; + + renderKnowledgeCard(selected, neighbors); + + if (neighborList) { + neighborList.innerHTML = ""; + if (!neighbors.length) { + const empty = document.createElement("div"); + empty.className = "note-card"; + empty.textContent = "这个节点暂时没有相邻节点。"; + neighborList.appendChild(empty); + } + neighbors.forEach((entry) => { + const node = entry.node; + const button = document.createElement("button"); + button.className = "neighbor-card"; + button.type = "button"; + button.innerHTML = `${escapeHtml(node.label)}${atlasTypeLabel(node.type)} · ${atlasConfidenceLabel(entry.edge.type)}`; + button.addEventListener("click", () => focusNode(node.id, true)); + neighborList.appendChild(button); + }); + } + } + + function renderKnowledgeCard(node, neighbors) { + const content = document.getElementById("drawer-content"); + if (!content) return; + const rawContent = String(node.content || "").trim(); + if (rawContent) { + const linked = rawContent.replace(/\[\[([^\]]+)\]\]/g, (_, inner) => { + const parts = inner.split("|"); + const target = parts[0].trim(); + const label = (parts[1] || parts[0]).trim(); + const exists = state.atlasModel.nodes.some((item) => item.id === target || item.label === target); + const cls = exists ? "wikilink" : "wikilink wikilink--dead"; + return `${escapeHtml(label)}`; + }); + const html = typeof marked === "undefined" ? `

${escapeHtml(stripAtlasMarkdown(linked))}

` : marked.parse(linked, { breaks: false, gfm: true }); + const safe = typeof DOMPurify === "undefined" + ? html + : DOMPurify.sanitize(html, { ADD_ATTR: ["target", "data-target", "tabindex"] }); + content.innerHTML = safe; + } else { + const related = neighbors.length + ? `它当前连接到 ${neighbors.map((entry) => `「${entry.node.label}」`).join("、")}。` + : "这个节点暂时没有相邻节点。"; + content.innerHTML = `

${escapeHtml(node.label)}属于知识库中的「${escapeHtml(atlasTypeLabel(node.type))}」节点。

${escapeHtml(node.summary || related)}

`; + } + + content.querySelectorAll("a.wikilink").forEach((link) => { + link.addEventListener("click", (event) => { + event.preventDefault(); + if (link.classList.contains("wikilink--dead")) return; + const target = link.getAttribute("data-target"); + const hit = state.atlasModel.nodes.find((item) => item.id === target || item.label === target); + if (hit) focusNode(hit.id, true); + }); + }); + } + + function getNeighbors(nodeId) { + const out = []; + state.atlasModel.edges.forEach((edge) => { + if (edge.source === nodeId && state.atlasModel.byId[edge.target]) { + out.push({ node: state.atlasModel.byId[edge.target], edge, direction: "to" }); + } else if (edge.target === nodeId && state.atlasModel.byId[edge.source]) { + out.push({ node: state.atlasModel.byId[edge.source], edge, direction: "from" }); + } + }); + return out.sort((left, right) => clampWeight(right.edge.weight) - clampWeight(left.edge.weight)); + } + + function renderInsights() { + if (!insightTitle || !insightCopy) return; + const visible = state.visible || refreshVisibleSnapshot(); + const insights = state.atlasModel.insights; + const bridge = insights.bridge_nodes && insights.bridge_nodes[0]; + const surprising = insights.surprising_connections && insights.surprising_connections[0]; + if (surprising) { + insightTitle.textContent = "发现跨社区强连接"; + insightCopy.textContent = `${surprising.from} 与 ${surprising.to} 的关系权重较高,适合作为下一步阅读线索。`; + } else if (bridge) { + insightTitle.textContent = "桥接节点值得优先阅读"; + insightCopy.textContent = `${bridge.label || bridge.id} 连接多个社区,可帮助从局部主题进入全局图谱。`; + } else if (visible.densityMode === "overview") { + insightTitle.textContent = "当前视图过密"; + insightCopy.textContent = "建议搜索关键词或筛选社区,先缩小图谱范围再阅读节点内容。"; + } else { + insightTitle.textContent = "从选中节点进入阅读"; + insightCopy.textContent = "右侧札记会随节点、搜索和社区筛选同步更新。"; + } + } + + function renderMinimap() { + if (!minimapSvg) return; + const visible = state.visible || refreshVisibleSnapshot(); + while (minimapSvg.firstChild) minimapSvg.removeChild(minimapSvg.firstChild); + const ns = "http://www.w3.org/2000/svg"; + const path = document.createElementNS(ns, "path"); + path.setAttribute("d", "M8 40 C34 20 54 36 76 22 C98 8 118 24 150 12"); + path.setAttribute("fill", "none"); + path.setAttribute("stroke", "#cfc4b1"); + path.setAttribute("stroke-width", "1.4"); + minimapSvg.appendChild(path); + + visible.nodes.slice(0, 60).forEach((node) => { + const point = atlasPointToMinimap(atlasNodePoint(node)); + const circle = document.createElementNS(ns, "circle"); + circle.setAttribute("cx", String(point.x)); + circle.setAttribute("cy", String(point.y)); + circle.setAttribute("r", node.id === state.ui.selectedNodeId ? "3.2" : "2.2"); + circle.setAttribute("fill", communityColor(node.community)); + if (node.id === state.ui.selectedNodeId) circle.classList.add("is-selected"); + minimapSvg.appendChild(circle); + }); + + const rect = document.createElementNS(ns, "rect"); + rect.setAttribute("class", "mini-map-viewport"); + rect.setAttribute("rx", "5"); + minimapSvg.appendChild(rect); + updateMinimapViewport(); + } + + function applyFilters() { + const visible = state.visible || refreshVisibleSnapshot(); + const visibleIds = new Set(visible.node_ids); + const selectedIds = state.ui.selectedNodeId ? connectedIds(state.ui.selectedNodeId) : new Set(); + + document.querySelectorAll(".node").forEach((nodeEl) => { + const id = nodeEl.dataset.id; + const isVisible = visibleIds.has(id); + nodeEl.classList.toggle("is-hidden", !isVisible); + const dim = state.ui.dimUnselected && state.ui.selectedNodeId && !selectedIds.has(id); + nodeEl.classList.toggle("is-dim", isVisible && dim); + nodeEl.setAttribute("aria-pressed", id === state.ui.selectedNodeId ? "true" : "false"); + }); + + document.querySelectorAll(".edge").forEach((edgeEl) => { + const from = edgeEl.dataset.from; + const to = edgeEl.dataset.to; + const visibleEdge = visibleIds.has(from) && visibleIds.has(to); + const dim = state.ui.dimUnselected && state.ui.selectedNodeId && from !== state.ui.selectedNodeId && to !== state.ui.selectedNodeId; + edgeEl.classList.toggle("is-dim", !visibleEdge || dim); + }); + + const hasNoResults = !!state.ui.query && visible.nodes.length === 0 && state.ui.dataMode === "normal"; + if (noResults) noResults.classList.toggle("is-visible", hasNoResults); + + const communityName = state.ui.activeCommunityId === "all" + ? "全局视图" + : (state.atlasModel.communityById[state.ui.activeCommunityId] || {}).label || "当前社区"; + if (canvasTitle) canvasTitle.textContent = `知识地图 · ${communityName}`; + if (canvasSubtitle) { + const densityLabel = ({ + card: "卡片", + "compact-card": "紧凑卡片", + "point-plus-focus": "点位聚焦", + overview: "总览" + })[visible.densityMode] || "卡片"; + canvasSubtitle.textContent = hasNoResults + ? "当前筛选没有匹配节点" + : `${visible.nodes.length} 个节点在当前范围内可见 · ${densityLabel}模式`; + } + } + + function highlightNeighborhood(id) { + if (state.ui.dataMode !== "normal") return; + const ids = connectedIds(id); + document.querySelectorAll(".node").forEach((nodeEl) => { + nodeEl.classList.toggle("is-dim", !ids.has(nodeEl.dataset.id)); + }); + document.querySelectorAll(".edge").forEach((edgeEl) => { + edgeEl.classList.toggle("is-dim", edgeEl.dataset.from !== id && edgeEl.dataset.to !== id); + }); + } + + function renderAtlasView(options) { + const opts = options && typeof options === "object" ? options : {}; + refreshVisibleSnapshot(); + if (app) app.dataset.reading = state.ui.selectedNodeId ? "1" : "0"; + if (opts.fitViewport || !state.viewportReady) fitVisibleViewport(); + renderTopbar(); + renderSidebar(); + renderCanvas(); + renderDrawer(); + renderInsights(); + } + + function selectNode(id) { + if (!state.atlasModel.byId[id]) return; + state.ui.selectedNodeId = id; + renderAtlasView(); + } + + function focusNode(nodeId, openDrawer) { + if (!state.atlasModel.byId[nodeId]) return; + state.ui.selectedNodeId = nodeId; + if (openDrawer !== false && drawer) { + drawer.scrollIntoView({ block: "nearest", inline: "nearest" }); + } + renderAtlasView(); + centerViewportOnNode(nodeId); + } + + function closeDrawer() { + state.ui.selectedNodeId = null; + renderAtlasView({ fitViewport: true }); + } + + function setCommunity(communityId) { + state.ui.activeCommunityId = communityId || "all"; + renderAtlasView({ fitViewport: true }); + } + + function buildNoteText(node) { + const stripped = stripAtlasMarkdown(node && node.content); + const excerpt = stripped.slice(0, NOTE_EXCERPT_LIMIT); + return node && node.label ? `${node.label}${excerpt ? ":" + excerpt : ""}` : excerpt; + } + + function handleQueueAction() { + const node = getSelectedNode(); + if (!node) { + const previewEntry = getPreviewStartEntry(); + if (previewEntry && previewEntry.node) focusNode(previewEntry.node.id, true); + return; + } + state.queue = toggleQueueFavorite(state.queue, node.id); + state.queue = appendQueueNote(state.queue, { + id: `${node.id}:${Date.now()}`, + node_id: node.id, + label: node.label, + text: buildNoteText(node), + created_at: new Date().toISOString() + }, QUEUE_NOTE_LIMIT); + persistQueueState(); + renderSidebar(); + } + + function setupSearch() { + if (!searchInput) return; + searchInput.addEventListener("input", () => { + state.ui.query = searchInput.value.trim().toLowerCase(); + renderAtlasView({ fitViewport: true }); + }); + searchInput.addEventListener("keydown", (event) => { + if (event.key !== "Enter") return; + const hit = state.visible && state.visible.nodes[0]; + if (hit) focusNode(hit.id, true); + }); + } + + function isCanvasPanTarget(target) { + return !(target && target.closest && target.closest(".node, button, a, input, textarea, summary, details")); + } + + function setupViewportInteractions() { + atlas.addEventListener("pointerdown", (event) => { + if (event.button !== 0 || !isCanvasPanTarget(event.target)) return; + panState = { + pointerId: event.pointerId, + startX: event.clientX, + startY: event.clientY, + viewport: { x: state.viewport.x, y: state.viewport.y, scale: state.viewport.scale } + }; + atlas.classList.add("is-panning"); + atlas.setPointerCapture(event.pointerId); + event.preventDefault(); + }); + + atlas.addEventListener("pointermove", (event) => { + if (!panState || panState.pointerId !== event.pointerId) return; + setViewport({ + x: panState.viewport.x + event.clientX - panState.startX, + y: panState.viewport.y + event.clientY - panState.startY, + scale: panState.viewport.scale + }); + event.preventDefault(); + }); + + function finishPan(event) { + if (!panState || panState.pointerId !== event.pointerId) return; + panState = null; + atlas.classList.remove("is-panning"); + if (atlas.hasPointerCapture && atlas.hasPointerCapture(event.pointerId)) { + atlas.releasePointerCapture(event.pointerId); + } + } + + atlas.addEventListener("pointerup", finishPan); + atlas.addEventListener("pointercancel", finishPan); + atlas.addEventListener("wheel", (event) => { + if (!isCanvasPanTarget(event.target) && !(event.target && event.target.closest && event.target.closest(".node"))) return; + const rect = atlas.getBoundingClientRect(); + const factor = Math.exp(-event.deltaY * 0.0012); + setViewport(zoomAtlasViewport(state.viewport, factor, { + x: event.clientX - rect.left, + y: event.clientY - rect.top + }, currentViewportSize(), viewportOptions())); + event.preventDefault(); + }, { passive: false }); + } + + function setupMinimapNavigation() { + if (!minimapSvg) return; + minimapSvg.addEventListener("click", (event) => { + const matrix = minimapSvg.getScreenCTM && minimapSvg.getScreenCTM(); + if (!matrix) return; + const point = minimapSvg.createSVGPoint(); + point.x = event.clientX; + point.y = event.clientY; + const local = point.matrixTransform(matrix.inverse()); + const atlasPoint = minimapPointToAtlasPoint({ x: local.x, y: local.y }); + setViewport(centerAtlasViewportOnPoint(atlasPoint, currentViewportSize(), state.viewport.scale, viewportOptions()), true); + }); + } + + function setupControls() { + document.querySelectorAll("[data-focus]").forEach((button) => { + button.addEventListener("click", () => { + state.ui.focusMode = button.dataset.focus || "all"; + document.querySelectorAll("[data-focus]").forEach((item) => { + item.setAttribute("aria-pressed", item === button ? "true" : "false"); + }); + renderAtlasView({ fitViewport: true }); + }); + }); + + document.querySelectorAll(".state-button[data-mode]").forEach((button) => { + button.addEventListener("click", () => { + state.ui.dataMode = button.dataset.mode || "normal"; + atlas.dataset.mode = state.ui.dataMode; + document.querySelectorAll(".state-button[data-mode]").forEach((item) => { + item.setAttribute("aria-pressed", item === button ? "true" : "false"); + }); + applyFilters(); + }); + }); + + const dimButton = document.getElementById("toggle-dim"); + if (dimButton) { + dimButton.addEventListener("click", () => { + state.ui.dimUnselected = !state.ui.dimUnselected; + dimButton.textContent = state.ui.dimUnselected ? "显示全部层级" : "弱化未选中"; + applyFilters(); + }); + } + + const fitButton = document.getElementById("fit-view"); + if (fitButton) { + fitButton.addEventListener("click", () => { + state.ui.activeCommunityId = "all"; + state.ui.focusMode = "all"; + state.ui.query = ""; + state.ui.selectedNodeId = null; + state.ui.dataMode = "normal"; + if (searchInput) searchInput.value = ""; + document.querySelectorAll("[data-focus]").forEach((item) => { + item.setAttribute("aria-pressed", item.dataset.focus === "all" ? "true" : "false"); + }); + document.querySelectorAll(".state-button[data-mode]").forEach((item) => { + item.setAttribute("aria-pressed", item.dataset.mode === "normal" ? "true" : "false"); + }); + renderAtlasView({ fitViewport: true }); + }); + } + + const queueAction = document.getElementById("queue-action"); + if (queueAction) queueAction.addEventListener("click", handleQueueAction); + + const sourceAction = document.getElementById("source-action"); + if (sourceAction) { + sourceAction.addEventListener("click", () => { + const previewEntry = getPreviewStartEntry(); + const node = getSelectedNode() || (previewEntry && previewEntry.node); + if (node && node.source_path) window.location.href = node.source_path; + }); + } + } + + function applyNeighborsCollapsed(collapsed) { + if (!drawerNeighbors || !drawerNeighborsHeading) return; + drawerNeighbors.open = !collapsed; + drawerNeighbors.setAttribute("data-collapsed", collapsed ? "1" : "0"); + drawerNeighborsHeading.setAttribute("aria-expanded", collapsed ? "false" : "true"); + } + + function toggleNeighbors() { + if (!drawerNeighbors) return; + const nextCollapsed = drawerNeighbors.open; + applyNeighborsCollapsed(nextCollapsed); + safeLocalStorage.set(queueStorageKey("neighbors-collapsed"), nextCollapsed ? "1" : "0"); + } + + function setupNeighborToggle() { + const storedNeighborsCollapsed = safeLocalStorage.get(queueStorageKey("neighbors-collapsed")); + applyNeighborsCollapsed(storedNeighborsCollapsed == null ? true : storedNeighborsCollapsed === "1"); + if (!drawerNeighbors || !drawerNeighborsHeading) return; + drawerNeighbors.addEventListener("toggle", () => { + state.ui.neighborExpanded = drawerNeighbors.open; + drawerNeighbors.setAttribute("data-collapsed", drawerNeighbors.open ? "0" : "1"); + drawerNeighborsHeading.setAttribute("aria-expanded", drawerNeighbors.open ? "true" : "false"); + }); + drawerNeighborsHeading.addEventListener("keydown", (e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + toggleNeighbors(); + } + }); + } + + function applyMinimapCollapsed(collapsed) { + if (!minimapEl || !minimapToggle) return; + minimapEl.setAttribute("data-collapsed", collapsed ? "1" : "0"); + minimapToggle.setAttribute("aria-expanded", collapsed ? "false" : "true"); + minimapToggle.setAttribute("aria-label", collapsed ? "展开小地图" : "折叠小地图"); + } + + setupSearch(); + setupViewportInteractions(); + setupMinimapNavigation(); + setupControls(); + setupNeighborToggle(); + applyMinimapCollapsed(false); + window.addEventListener("resize", () => renderAtlasView({ fitViewport: true })); + renderAtlasView({ fitViewport: true }); +})(); diff --git a/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/header.html b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/header.html new file mode 100644 index 000000000..81a23cfb7 --- /dev/null +++ b/graphify/bundled_skills/llm-wiki/templates/graph-styles/wash/header.html @@ -0,0 +1,2002 @@ + + + + + + + 知识图谱 · __WIKI_TITLE__ + + + + +
+
+
+ +
+

__WIKI_TITLE__ 知识舆图

+

国风知识库·数字山水图

+
+
+
+ 已生成 __NODE_COUNT__ 个索引点 + 关系 __EDGE_COUNT__ 条 + 最近更新 __BUILD_DATE__ + + + GitHub + +
+
+ +
+
+ 数字山水图谱 + __NODE_COUNT__ 点 · __EDGE_COUNT__ 关系 +
+ +
+ + + +
+
+
+ 知识地图 · 全局视图 + 社区地貌、关系路径与批注状态保持同步 +
+
+ + +
+ + + + +
+
+
+ +
+ + +
+
+ +

正在铺开知识地图

+

图谱数据已读取,正在整理社区、关系和标签。

+
+
+

这座知识库还没有图谱

+

消化素材后会自动生成节点、来源和关系。

+
+ +
当前视图过密,可搜索或筛选社区。
+
+ +
+
+ +
+ 直接提取 + 推断关联 + 存在歧义 + 未核实 +
+
+
+ + +
+
+ + 来源节点连接度偏高 +

建议从“知识编译”进入,可同时看到方法论、缓存与图谱生成的关系。

+
+
+
+ + +
+ +