From acc0bafdabe006a521168cf68fc2609e9258ca70 Mon Sep 17 00:00:00 2001 From: Xiwei Pan Date: Wed, 16 Sep 2026 01:38:24 +0800 Subject: [PATCH 1/5] Refactor the reduction website with a shared Typst-backed graph explorer --- .github/workflows/docs.yml | 46 +- Makefile | 7 +- book.toml | 4 +- docs/paper/reductions.typ | 73 +- docs/paper/web.typ | 12 + docs/src/SUMMARY.md | 5 - docs/src/open-problems.md | 3 - docs/src/reduction-graph.md | 35 - docs/src/static/cytoscape.min.js | 31 - docs/src/static/docs-theme.css | 9 +- docs/src/static/docs-theme.js | 1 + docs/src/static/reduction-graph.css | 86 --- docs/src/static/reduction-graph.js | 464 ------------- docs/website/README.md | 73 +- docs/website/assets/details.css | 44 ++ docs/website/assets/details.js | 156 +++++ docs/website/assets/graph-layout.js | 13 + docs/website/assets/graph.css | 379 +++++++++++ docs/website/assets/graph.js | 833 +++++++++++++++++++++++ docs/website/assets/site.css | 414 ++++------- docs/website/assets/site.js | 338 +++------ docs/website/formulas/qubo.typ | 6 + docs/website/formulas/sat.typ | 3 + docs/website/graph.html | 125 ++++ docs/website/index.html | 32 +- package-lock.json | 42 ++ package.json | 2 + scripts/build_graph_details.py | 133 ++++ scripts/build_website.py | 48 +- scripts/finalize_website.py | 59 ++ scripts/generate_website_graph_layout.js | 24 + scripts/test_website.py | 645 +++++++++++++++++- scripts/test_website_build.py | 47 ++ src/registry/schema.rs | 3 + src/unit_tests/registry/schema.rs | 4 + 35 files changed, 2992 insertions(+), 1207 deletions(-) create mode 100644 docs/paper/web.typ delete mode 100644 docs/src/open-problems.md delete mode 100644 docs/src/reduction-graph.md delete mode 100644 docs/src/static/cytoscape.min.js delete mode 100644 docs/src/static/reduction-graph.css create mode 100644 docs/website/assets/details.css create mode 100644 docs/website/assets/details.js create mode 100644 docs/website/assets/graph-layout.js create mode 100644 docs/website/assets/graph.css create mode 100644 docs/website/assets/graph.js create mode 100644 docs/website/formulas/qubo.typ create mode 100644 docs/website/formulas/sat.typ create mode 100644 docs/website/graph.html create mode 100644 scripts/build_graph_details.py create mode 100644 scripts/finalize_website.py create mode 100644 scripts/generate_website_graph_layout.js create mode 100644 scripts/test_website_build.py diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 60aa9272e..f303b3bbc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,8 +7,6 @@ on: permissions: contents: read - pages: write - id-token: write concurrency: group: "pages" @@ -18,11 +16,13 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@6bed0761d98439e5a578e2877258200ad565ba87 # stable + with: + toolchain: stable - - uses: actions/setup-node@v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '22' cache: npm @@ -30,12 +30,16 @@ jobs: - name: Install mdBook run: | mkdir -p "$HOME/bin" - curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar -xz -C "$HOME/bin" + curl -fLsS https://github.com/rust-lang/mdBook/releases/download/v0.5.2/mdbook-v0.5.2-x86_64-unknown-linux-gnu.tar.gz -o mdbook.tar.gz + echo '084e4342ba564db270108763e404a7d1f309d932651a22484e93c0dc1a071f6d mdbook.tar.gz' | sha256sum --check + tar -xzf mdbook.tar.gz -C "$HOME/bin" echo "$HOME/bin" >> $GITHUB_PATH - name: Install Typst run: | - curl -sSL https://github.com/typst/typst/releases/download/v0.14.0/typst-x86_64-unknown-linux-musl.tar.xz | tar -xJ + curl -fLsS https://github.com/typst/typst/releases/download/v0.15.1/typst-x86_64-unknown-linux-musl.tar.xz -o typst.tar.xz + echo 'a6d077d0a95eed5a2eba715b2dae06be954f624ccbf85758a03f389ded33118c typst.tar.xz' | sha256sum --check + tar -xJf typst.tar.xz mv typst-x86_64-unknown-linux-musl/typst "$HOME/bin/" - name: Install Node dependencies @@ -54,9 +58,6 @@ jobs: - name: Build mdBook run: mdbook build - - name: Build research website - run: python3 scripts/build_website.py - - name: Build PDF run: typst compile --root . docs/paper/reductions.typ book/reductions.pdf @@ -68,21 +69,38 @@ jobs: mkdir -p book/api cp -r target/doc/* book/api/ - - name: Setup Pages - uses: actions/configure-pages@v4 + - name: Build research website + run: python3 scripts/build_website.py + + - name: Verify deployment artifact + run: | + python3 -m pip install playwright==1.58.0 + python3 -m playwright install --with-deps chromium + npm audit --audit-level=moderate + npm run test:reduction-graph-js + python3 -m unittest discover -s scripts -p 'test_website_build.py' + python3 -m http.server 3001 --bind 127.0.0.1 --directory book & + server_pid=$! + trap 'kill "$server_pid"' EXIT + python3 scripts/test_website.py - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 with: path: './book' deploy: + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest needs: build steps: + - name: Setup Pages + uses: actions/configure-pages@1f0c5cde4bc74cd7e1254d0cb4de8d49e9068c7d # v4 - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/Makefile b/Makefile index 1a3634480..63cf45d26 100644 --- a/Makefile +++ b/Makefile @@ -102,14 +102,17 @@ doc: node_modules/elkjs/package.json cargo build -p problemreductions-cli --bin pred bash scripts/generate_doc_snippets.sh target/debug/pred mdbook build - python3 scripts/build_website.py RUSTDOCFLAGS="--default-theme=dark" cargo doc --no-deps rm -rf book/api cp -r target/doc book/api + python3 scripts/build_website.py # Build the product website with fresh atlas data; API/PDF builds remain in doc/paper. -website: +website: node_modules/elkjs/package.json + cargo run --features "$(TEST_FEATURES)" --example export_examples + cargo run --features "$(TEST_FEATURES)" --example export_petersen_mapping cargo run --example export_graph + node scripts/generate_reduction_graph_layout.js cargo run --example export_schemas cargo build -p problemreductions-cli --bin pred bash scripts/generate_doc_snippets.sh target/debug/pred diff --git a/book.toml b/book.toml index d090aa848..530d16ae0 100644 --- a/book.toml +++ b/book.toml @@ -9,8 +9,8 @@ src = "docs/src" default-theme = "navy" git-repository-url = "https://github.com/CodingThrust/problem-reductions" edit-url-template = "https://github.com/CodingThrust/problem-reductions/edit/main/{path}" -additional-css = ["docs/src/static/docs-theme.css", "docs/src/static/theme-images.css", "docs/src/static/reduction-graph.css"] -additional-js = ["docs/src/static/docs-theme.js", "docs/src/static/cytoscape.min.js", "docs/src/static/reduction-graph.js"] +additional-css = ["docs/src/static/docs-theme.css", "docs/src/static/theme-images.css"] +additional-js = ["docs/src/static/docs-theme.js"] no-section-label = true [output.html.fold] diff --git a/docs/paper/reductions.typ b/docs/paper/reductions.typ index 588450da9..80f4c3319 100644 --- a/docs/paper/reductions.typ +++ b/docs/paper/reductions.typ @@ -51,6 +51,7 @@ #import "@preview/cetz:0.4.2": canvas, draw #import "@preview/ctheorems:1.1.3": thmbox, thmplain, thmproof, thmrules #import "lib.typ": g-node, g-edge, petersen-graph, house-graph, octahedral-graph, draw-grid-graph, draw-triangular-graph, graph-colors, selem, sregion, draw-node-highlight, draw-edge-highlight, draw-node-colors, sregion-selected, sregion-dimmed, gate-and, gate-or, gate-xor +#import "web.typ": export-details, detail-key, detail-article #set page( paper: "a4", @@ -64,6 +65,36 @@ // Set up theorem environments with ctheorems #show: thmrules.with(qed-symbol: $square$) +#show math.equation: it => context { + if export-details and target() == "html" { + html.elem(if it.block { "div" } else { "span" }, attrs: (class: "typst-math"), html.frame(it)) + } else { it } +} +#show figure: it => context { + if export-details and target() == "html" { + html.elem("figure")[ + #html.frame(it.body) + #if it.caption != none { html.elem("figcaption", it.caption.body) } + ] + } else { it } +} +#show block: it => context { + if export-details and target() == "html" { + if it.height != auto { html.frame(it) } else { html.elem("div", it.body) } + } else { it } +} +#show align: it => context { + if export-details and target() == "html" { it.body } else { it } +} +#show pad: it => context { + if export-details and target() == "html" { it.body } else { it } +} +#show grid: it => context { + if export-details and target() == "html" { html.frame(it) } else { it } +} +#show stack: it => context { + if export-details and target() == "html" { html.frame(it) } else { it } +} // === Example JSON helpers === // Load the generated canonical example database. @@ -515,6 +546,7 @@ // Render a block of pred CLI commands for reproducibility #let pred-commands(..cmds) = { + if export-details { return raw(cmds.pos().join("\n"), block: true) } block( width: 100%, fill: luma(245), @@ -545,8 +577,22 @@ ) // Problem definition wrapper: auto-adds schema, complexity, reductions list, and label -#let problem-def(name, def, body) = { - let lbl = label("def:" + name) +#show ref: it => context { + let name = str(it.target) + if export-details and target() == "html" and name.starts-with("def:") { + link(it.target, display-name.at(name.slice(4))) + } else { it } +} +#let problem-def(name, def, body, variant: none) = { + if export-details { + return detail-article("problem:" + detail-key(name, variant))[ + #html.elem("h3")[Definition] + #def + #html.elem("h3")[Background and example] + #body + ] + } + let lbl = label("def:" + detail-key(name, variant)) let title = display-name.at(name) [#definition(title)[ #def @@ -600,8 +646,23 @@ example-target-variant: none, example-caption: none, extra: none, + source-variant: none, + target-variant: none, theorem-body, proof-body, ) = { + if export-details { + return detail-article("rule:" + detail-key(source, source-variant) + "->" + detail-key(target, target-variant))[ + #html.elem("h3")[Reduction] + #theorem-body + #html.elem("h3")[Proof] + #proof-body + #if example { + html.elem("h3")[Example] + if example-caption != none { strong(example-caption) } + extra + } + ] + } let arrow = sym.arrow.r let edge = find-edge(source, target) let src-disp = if edge != none { variant-display(graph-data.nodes.at(edge.source)) } @@ -611,7 +672,7 @@ let src-lbl = label("def:" + source) let tgt-lbl = label("def:" + target) let parameters = if edge != none and edge.parameters.len() > 0 { edge.parameters } else { none } - let thm-lbl = label("thm:" + source + "-to-" + target) + let thm-lbl = label("thm:" + detail-key(source, source-variant) + "-to-" + detail-key(target, target-variant)) covered-rules.update(old => old + ((source, target),)) [ @@ -19475,4 +19536,8 @@ The following table shows concrete target-variable counts for example instances, ] #pagebreak() -#bibliography("references.bib", style: "ieee") +#if export-details { + detail-article("references")[#bibliography("references.bib", style: "ieee")] +} else { + bibliography("references.bib", style: "ieee") +} diff --git a/docs/paper/web.typ b/docs/paper/web.typ new file mode 100644 index 000000000..0bd644846 --- /dev/null +++ b/docs/paper/web.typ @@ -0,0 +1,12 @@ +// Web presentation only; all definitions, proofs, and examples stay in reductions.typ. +#let export-details = sys.inputs.at("details", default: "false") == "true" + +#let detail-key(name, variant) = { + if variant == none { return name } + name + "/" + variant.keys().sorted().map(key => key + "=" + str(variant.at(key))).join(",") +} + +#let detail-article(key, body) = { + let anchor = key.replace("problem:", "def:").replace("rule:", "thm:").replace("->", "-to-") + [#html.elem("article", attrs: ("data-detail-key": key), body)#label(anchor)] +} diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index a31b2ecf4..c2321d330 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -6,7 +6,6 @@ - [Quick start](cli.md) - [Command reference](cli-commands.md) -- [Reduction graph](reduction-graph.md) # Agents @@ -17,7 +16,3 @@ - [Getting started](getting-started.md) - [API reference](api.md) - [Design](design.md) - -# Research - -- [Open problems](open-problems.md) diff --git a/docs/src/open-problems.md b/docs/src/open-problems.md deleted file mode 100644 index c893dd887..000000000 --- a/docs/src/open-problems.md +++ /dev/null @@ -1,3 +0,0 @@ -# Open problems - -To be released. diff --git a/docs/src/reduction-graph.md b/docs/src/reduction-graph.md deleted file mode 100644 index fb87fbb55..000000000 --- a/docs/src/reduction-graph.md +++ /dev/null @@ -1,35 +0,0 @@ -# Reduction graph - - - - -
-
-
- Graph - Formula - Set - Algebraic - Misc - Variant Cast -
-
- Click a node to start path selection - - -
-
-
- Click a problem node to expand/collapse its variants. - Click a variant to filter its edges. - Click two nodes to find a reduction path. - Double-click for API docs (nodes) or source code (edges). - Scroll to zoom, drag to pan. -
-
- -You can also explore this graph from the terminal with the [CLI tool](./cli.md). For theoretical background and correctness proofs, see the [PDF manual](https://codingthrust.github.io/problem-reductions/reductions.pdf). - -For exact variants and structured output, use [CLI path queries](cli-commands.md#paths). diff --git a/docs/src/static/cytoscape.min.js b/docs/src/static/cytoscape.min.js deleted file mode 100644 index c1364fdec..000000000 --- a/docs/src/static/cytoscape.min.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2016-2025, The Cytoscape Consortium. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the “Software”), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).cytoscape=t()}(this,(function(){"use strict";function e(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}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,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,i=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw i}}}}function a(e,t,n){return(t=s(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,i,o,s=[],l=!0,u=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(s.push(r.value),s.length!==t);l=!0);}catch(e){u=!0,a=e}finally{try{if(!l&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(u)throw a}}return s}}(e,t)||u(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function o(t){return function(t){if(Array.isArray(t))return e(t)}(t)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(t)||u(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function s(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t);if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:t+""}function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function u(t,n){if(t){if("string"==typeof t)return e(t,n);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?e(t,n):void 0}}var c="undefined"==typeof window?null:window,d=c?c.navigator:null;c&&c.document;var h,f,p,v,g,y,m,b,x,w,E,k,T,C,P,S,B,D,_,A,M,R,I,N,L,z,O,V,F=l(""),X=l({}),j=l((function(){})),Y="undefined"==typeof HTMLElement?"undefined":l(HTMLElement),q=function(e){return e&&e.instanceString&&U(e.instanceString)?e.instanceString():null},W=function(e){return null!=e&&l(e)==F},U=function(e){return null!=e&&l(e)===j},H=function(e){return!$(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},K=function(e){return null!=e&&l(e)===X&&!H(e)&&e.constructor===Object},G=function(e){return null!=e&&l(e)===l(1)&&!isNaN(e)},Z=function(e){return"undefined"===Y?void 0:null!=e&&e instanceof HTMLElement},$=function(e){return Q(e)||J(e)},Q=function(e){return"collection"===q(e)&&e._private.single},J=function(e){return"collection"===q(e)&&!e._private.single},ee=function(e){return"core"===q(e)},te=function(e){return"stylesheet"===q(e)},ne=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},re=function(e){return function(e){return null!=e&&l(e)===X}(e)&&U(e.then)},ae=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;tt?1:0},ge=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n255)return;t.push(Math.floor(i))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,a,i,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+fe+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(a=parseFloat(c[3]))<0||a>100)return;if(a/=100,void 0!==(i=c[4])&&((i=parseFloat(i))<0||i>1))return;if(0===r)o=s=l=Math.round(255*a);else{var d=a<.5?a*(1+r):a+r-a*r,h=2*a-d;o=Math.round(255*u(h,d,n+1/3)),s=Math.round(255*u(h,d,n)),l=Math.round(255*u(h,d,n-1/3))}t=[o,s,l,i]}return t}(e)},me={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},be=function(e){for(var t=e.map,n=e.keys,r=n.length,a=0;a=o||t<0||g&&e-p>=c}function x(){var e=t();if(b(e))return w(e);h=setTimeout(x,function(e){var t=o-(e-f);return g?a(t,c-(e-p)):t}(e))}function w(e){return h=void 0,y&&l?m(e):(l=u=void 0,d)}function E(){var e=t(),n=b(e);if(l=arguments,u=this,f=e,n){if(void 0===h)return function(e){return p=e,h=setTimeout(x,o),v?m(e):d}(f);if(g)return clearTimeout(h),h=setTimeout(x,o),m(f)}return void 0===h&&(h=setTimeout(x,o)),d}return o=n(o)||0,e(s)&&(v=!!s.leading,c=(g="maxWait"in s)?r(n(s.maxWait)||0,o):c,y="trailing"in s?!!s.trailing:y),E.cancel=function(){void 0!==h&&clearTimeout(h),p=0,l=f=u=h=void 0},E.flush=function(){return void 0===h?d:w(t())},E},O}(),_e=Ee(De),Ae=c?c.performance:null,Me=Ae&&Ae.now?function(){return Ae.now()}:function(){return Date.now()},Re=function(){if(c){if(c.requestAnimationFrame)return function(e){c.requestAnimationFrame(e)};if(c.mozRequestAnimationFrame)return function(e){c.mozRequestAnimationFrame(e)};if(c.webkitRequestAnimationFrame)return function(e){c.webkitRequestAnimationFrame(e)};if(c.msRequestAnimationFrame)return function(e){c.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(Me())}),1e3/60)}}(),Ie=function(e){return Re(e)},Ne=Me,Le=9261,ze=5381,Oe=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Le;!(t=e.next()).done;)n=65599*n+t.value|0;return n},Ve=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:Le)+e|0},Fe=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ze;return(t<<5)+t+e|0},Xe=function(e){return 2097152*e[0]+e[1]},je=function(e,t){return[Ve(e[0],t[0]),Fe(e[1],t[1])]},Ye=function(e,t){var n={value:0,done:!1},r=0,a=e.length;return Oe({next:function(){return r=0;r--)e[r]===t&&e.splice(r,1)},dt=function(e){e.splice(0,e.length)},ht=function(e,t,n){return n&&(t=se(n,t)),e[t]},ft=function(e,t,n,r){n&&(t=se(n,t)),e[t]=r},pt="undefined"!=typeof Map?Map:function(){return n((function e(){t(this,e),this._obj={}}),[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}])}(),vt=function(){return n((function e(n){if(t(this,e),this._obj=Object.create(null),this.size=0,null!=n){var r;r=null!=n.instanceString&&n.instanceString()===this.instanceString()?n.toArray():n;for(var a=0;a2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&ee(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new gt,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==a.position.x&&(a.position.x=0),null==a.position.y&&(a.position.y=0),t.renderedPosition){var i=t.renderedPosition,o=e.pan(),s=e.zoom();a.position={x:(i.x-o.x)/s,y:(i.y-o.y)/s}}var l=[];H(t.classes)?l=t.classes:W(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,a,i,o){var s;if(null==a&&(a=0),null==o&&(o=n),a<0)throw new Error("lo must be non-negative");for(null==i&&(i=e.length);an;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;iv;0<=v?++h:--h)g.push(i(e,r));return g},p=function(e,t,r,a){var i,o,s;for(null==a&&(a=n),i=e[r];r>t&&a(i,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=i},v=function(e,t,r){var a,i,o,s,l;for(null==r&&(r=n),i=e.length,l=t,o=e[t],a=2*t+1;a0;){var w=y.pop(),E=v(w),k=w.id();if(d[k]=E,E!==1/0)for(var T=w.neighborhood().intersect(f),C=0;C0)for(n.unshift(t);c[a];){var i=c[a];n.unshift(i.edge),n.unshift(i.node),a=(r=i.node).id()}return o.spawn(n)}}}},_t={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,a=n.length,i=new Array(a),o=n,s=function(e){for(var t=0;t0;){if(l=v.pop(),u=l.id(),g.delete(u),w++,u===d){for(var E=[],k=a,T=d,C=m[T];E.unshift(k),null!=C&&E.unshift(C),null!=(k=y[T]);)C=m[T=k.id()];return{found:!0,distance:h[u],path:this.spawn(E),steps:w}}p[u]=!0;for(var P=l._private.edges,S=0;SP&&(f[C]=P,y[C]=T,m[C]=x),!a){var S=T*u+k;!a&&f[S]>P&&(f[S]=P,y[S]=k,m[S]=x)}}}for(var B=0;B1&&void 0!==arguments[1]?arguments[1]:i,r=[],a=m(e);;){if(null==a)return t.spawn();var o=y(a),l=o.edge,u=o.pred;if(r.unshift(a[0]),a.same(n)&&r.length>0)break;null!=l&&r.unshift(l),a=u}return s.spawn(r)},hasNegativeWeightCycle:p,negativeWeightCycles:v}}},zt=Math.sqrt(2),Ot=function(e,t,n){0===n.length&&nt("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],a=r[1],i=r[2],o=t[a],s=t[i],l=n,u=l.length-1;u>=0;u--){var c=l[u],d=c[1],h=c[2];(t[d]===o&&t[h]===s||t[d]===s&&t[h]===o)&&l.splice(u,1)}for(var f=0;fr;){var a=Math.floor(Math.random()*t.length);t=Ot(a,e,t),n--}return t},Ft={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var a=n.length,i=r.length,o=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),s=Math.floor(a/zt);if(!(a<2)){for(var l=[],u=0;u0?1:e<0?-1:0},Ht=function(e,t){return Math.sqrt(Kt(e,t))},Kt=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},Gt=function(e){for(var t=e.length,n=0,r=0;r=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},en=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},tn=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},nn=function(e){var t,n,r,a,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===o.length)t=n=r=a=o[0];else if(2===o.length)t=r=o[0],a=n=o[1];else if(4===o.length){var s=i(o,4);t=s[0],n=s[1],r=s[2],a=s[3]}return e.x1-=a,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},rn=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},an=function(e,t){return!(e.x1>t.x2)&&(!(t.x1>e.x2)&&(!(e.x2t.y2)&&!(t.y1>e.y2)))))))},on=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},sn=function(e,t){return on(e,t.x,t.y)},ln=function(e,t){return on(e,t.x1,t.y1)&&on(e,t.x2,t.y2)},un=null!==(Pt=Math.hypot)&&void 0!==Pt?Pt:function(e,t){return Math.sqrt(e*e+t*t)};function cn(e,t,n,r,a,i){var o=function(e,t){if(e.length<3)throw new Error("Need at least 3 vertices");var n=function(e,t){return{x:e.x+t.x,y:e.y+t.y}},r=function(e,t){return{x:e.x-t.x,y:e.y-t.y}},a=function(e,t){return{x:e.x*t,y:e.y*t}},i=function(e,t){return e.x*t.y-e.y*t.x},o=function(e,t,o,s){var l=r(t,e),u=r(s,o),c=i(l,u);if(Math.abs(c)<1e-9)return n(e,a(l,.5));var d=i(r(o,e),u)/c;return n(e,a(l,d))},s=e.map((function(e){return{x:e.x,y:e.y}}));(function(e){for(var t=0,n=0;n7&&void 0!==arguments[7]?arguments[7]:"auto",c="auto"===u?_n(a,i):u,d=a/2,h=i/2,f=(c=Math.min(c,d,h))!==d,p=c!==h;if(f){var v=r-h-o;if((s=kn(e,t,n,r,n-d+c-o,v,n+d-c+o,v,!1)).length>0)return s}if(p){var g=n+d+o;if((s=kn(e,t,n,r,g,r-h+c-o,g,r+h-c+o,!1)).length>0)return s}if(f){var y=r+h+o;if((s=kn(e,t,n,r,n-d+c-o,y,n+d-c+o,y,!1)).length>0)return s}if(p){var m=n-d-o;if((s=kn(e,t,n,r,m,r-h+c-o,m,r+h-c+o,!1)).length>0)return s}var b=n-d+c,x=r-h+c;if((l=wn(e,t,n,r,b,x,c+o)).length>0&&l[0]<=b&&l[1]<=x)return[l[0],l[1]];var w=n+d-c,E=r-h+c;if((l=wn(e,t,n,r,w,E,c+o)).length>0&&l[0]>=w&&l[1]<=E)return[l[0],l[1]];var k=n+d-c,T=r+h-c;if((l=wn(e,t,n,r,k,T,c+o)).length>0&&l[0]>=k&&l[1]>=T)return[l[0],l[1]];var C=n-d+c,P=r+h-c;return(l=wn(e,t,n,r,C,P,c+o)).length>0&&l[0]<=C&&l[1]>=P?[l[0],l[1]]:[]},hn=function(e,t,n,r,a,i,o){var s=o,l=Math.min(n,a),u=Math.max(n,a),c=Math.min(r,i),d=Math.max(r,i);return l-s<=e&&e<=u+s&&c-s<=t&&t<=d+s},fn=function(e,t,n,r,a,i,o,s,l){var u=Math.min(n,o,a)-l,c=Math.max(n,o,a)+l,d=Math.min(r,s,i)-l,h=Math.max(r,s,i)+l;return!(ec||th)},pn=function(e,t,n,r,a,i,o,s){var l=[];!function(e,t,n,r,a){var i,o,s,l,u,c,d,h;0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),i=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,a[1]=0,d=t/3,i>0?(u=(u=s+Math.sqrt(i))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(i))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),a[0]=-d+u+c,d+=(u+c)/2,a[4]=a[2]=-d,d=Math.sqrt(3)*(-c+u)/2,a[3]=d,a[5]=-d):(a[5]=a[3]=0,0===i?(h=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),a[0]=2*h-d,a[4]=a[2]=-(h+d)):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),h=2*Math.sqrt(o),a[0]=-d+h*Math.cos(l/3),a[2]=-d+h*Math.cos((l+2*Math.PI)/3),a[4]=-d+h*Math.cos((l+4*Math.PI)/3)))}(1*n*n-4*n*a+2*n*o+4*a*a-4*a*o+o*o+r*r-4*r*i+2*r*s+4*i*i-4*i*s+s*s,9*n*a-3*n*n-3*n*o-6*a*a+3*a*o+9*r*i-3*r*r-3*r*s-6*i*i+3*i*s,3*n*n-6*n*a+n*o-n*e+2*a*a+2*a*e-o*e+3*r*r-6*r*i+r*s-r*t+2*i*i+2*i*t-s*t,1*n*a-n*n+n*e-a*e+r*i-r*r+r*t-i*t,l);for(var u=[],c=0;c<6;c+=2)Math.abs(l[c+1])<1e-7&&l[c]>=0&&l[c]<=1&&u.push(l[c]);u.push(1),u.push(0);for(var d,h,f,p=-1,v=0;v=0?fl?(e-a)*(e-a)+(t-i)*(t-i):u-d},gn=function(e,t,n){for(var r,a,i,o,s=0,l=0;l=e&&e>=i||r<=e&&e<=i))continue;(e-r)/(i-r)*(o-a)+a>t&&s++}return s%2!=0},yn=function(e,t,n,r,a,i,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var d,h=Math.cos(-u),f=Math.sin(-u),p=0;p0){var v=bn(c,-l);d=mn(v)}else d=c;return gn(e,t,d)},mn=function(e){for(var t,n,r,a,i,o,s,l,u=new Array(e.length/2),c=0;c=0&&p<=1&&g.push(p),v>=0&&v<=1&&g.push(v),0===g.length)return[];var y=g[0]*s[0]+e,m=g[0]*s[1]+t;return g.length>1?g[0]==g[1]?[y,m]:[y,m,g[1]*s[0]+e,g[1]*s[1]+t]:[y,m]},En=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},kn=function(e,t,n,r,a,i,o,s,l){var u=e-a,c=n-e,d=o-a,h=t-i,f=r-t,p=s-i,v=d*h-p*u,g=c*h-f*u,y=p*c-d*f;if(0!==y){var m=v/y,b=g/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*f]:[]}return 0===v||0===g?En(e,n,o)===o?[o,s]:En(e,n,a)===a?[a,i]:En(a,o,n)===n?[n,r]:[]:[]},Tn=function(e,t,n,r,a){var i=[],o=r/2,s=a/2,l=t,u=n;i.push({x:l+o*e[0],y:u+s*e[1]});for(var c=1;c0){var m=bn(v,-s);u=mn(m)}else u=v}else u=n;for(var b=0;bu&&(u=t)},d=function(e){return l[e]},h=0;h0?b.edgesTo(m)[0]:m.edgesTo(b)[0];var w=r(x);m=m.id(),u[m]>u[v]+w&&(u[m]=u[v]+w,h.nodes.indexOf(m)<0?h.push(m):h.updateItem(m),l[m]=0,n[m]=[]),u[m]==u[v]+w&&(l[m]=l[m]+l[v],n[m].push(v))}else for(var E=0;E0;){for(var P=t.pop(),S=0;S0&&o.push(n[s]);0!==o.length&&a.push(r.collection(o))}return a}(c,l,t,r);return b=function(e){for(var t=0;t5&&void 0!==arguments[5]?arguments[5]:Qn,o=r,s=0;s=2?ar(e,t,n,0,tr,nr):ar(e,t,n,0,er)},squaredEuclidean:function(e,t,n){return ar(e,t,n,0,tr)},manhattan:function(e,t,n){return ar(e,t,n,0,er)},max:function(e,t,n){return ar(e,t,n,-1/0,rr)}};function or(e,t,n,r,a,i){var o;return o=U(e)?e:ir[e]||ir.euclidean,0===t&&U(e)?o(a,i):o(t,n,r,a,i)}ir["squared-euclidean"]=ir.squaredEuclidean,ir.squaredeuclidean=ir.squaredEuclidean;var sr=ut({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),lr=function(e){return sr(e)},ur=function(e,t,n,r,a){var i="kMedoids"!==a?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return or(e,r.length,i,(function(e){return r[e](t)}),o,s)},cr=function(e,t,n){for(var r=n.length,a=new Array(r),i=new Array(r),o=new Array(t),s=null,l=0;ln)return!1}return!0},vr=function(e,t,n){for(var r=0;ra&&(a=t[l][u],i=u);o[i].push(e[l])}for(var c=0;c=a.threshold||"dendrogram"===a.mode&&1===e.length)return!1;var f,p=t[o],v=t[r[o]];f="dendrogram"===a.mode?{left:p,right:v,key:p.key}:{value:p.value.concat(v.value),key:p.key},e[p.index]=f,e.splice(v.index,1),t[p.key]=f;for(var g=0;gn[v.key][y.key]&&(i=n[v.key][y.key])):"max"===a.linkage?(i=n[p.key][y.key],n[p.key][y.key]1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var i=0,o=e.length-1;o>=0;o--){var s=e[o];a?isFinite(s)||(e[o]=-1/0,i++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+i]:(e[u-1+i]+e[u+i])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,a=0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,a=t;ao&&(i=l,o=t[a*e+l])}i>0&&r.push(i)}for(var u=0;u=P?(S=P,P=D,B=_):D>S&&(S=D);for(var A=0;A0?1:0;k[E%u.minIterations*t+z]=O,L+=O}if(L>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var V=0,F=0;F0&&r.push(a);return r}(t,i,o),Y=function(e,t,n){for(var r=Rr(e,t,n),a=0;al&&(s=u,l=c)}n[a]=i[s]}return Rr(e,t,n)}(t,r,j),q={},W=0;W1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else d[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):d[t]=[e.source().id(),e.target().id()]}));var h={found:!1,trail:void 0};if(u)return h;if(r&&n)if(s){if(a&&r!=a)return h;a=r}else{if(a&&r!=a&&n!=a)return h;a||(a=r)}else a||(a=l[0].id());var f=function(e){for(var t,n,r,a=e,i=[e];c[a].length;)t=c[a].shift(),n=d[t][0],a!=(r=d[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),a=r):s||a==n||(c[n]=c[n].filter((function(e){return e!=t})),a=n),i.unshift(t),i.unshift(a);return i},p=[],v=[];for(v=f(a);1!=v.length;)0==c[v[0]].length?(p.unshift(l.getElementById(v.shift())),p.unshift(l.getElementById(v.shift()))):v=f(v.shift()).concat(v);for(var g in p.unshift(l.getElementById(v.shift())),c)if(c[g].length)return h;return h.found=!0,h.trail=this.spawn(p,!0),h}},Or=function(){var e=this,t={},n=0,r=0,a=[],i=[],o={},s=function(l,u,c){l===c&&(r+=1),t[u]={id:n,low:n++,cutVertex:!1};var d,h,f,p,v=e.getElementById(u).connectedEdges().intersection(e);0===v.size()?a.push(e.spawn(e.getElementById(u))):v.forEach((function(n){d=n.source().id(),h=n.target().id(),(f=d===u?h:d)!==c&&(p=n.id(),o[p]||(o[p]=!0,i.push({x:u,y:f,edge:n})),f in t?t[u].low=Math.min(t[u].low,t[f].id):(s(l,f,u),t[u].low=Math.min(t[u].low,t[f].low),t[u].id<=t[f].low&&(t[u].cutVertex=!0,function(n,r){for(var o=i.length-1,s=[],l=e.spawn();i[o].x!=n||i[o].y!=r;)s.push(i.pop().edge),o--;s.push(i.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),a=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(a.filter((function(e){return e.isLoop()}))):l.merge(a)}))})),a.push(l)}(u,f))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,s(n,n),t[n].cutVertex=r>1)}}));var l=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(l),components:a}},Vr=function(){var e=this,t={},n=0,r=[],a=[],i=e.spawn(e),o=function(s){if(a.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=a.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),d=l.merge(c);r.push(d),i=i.difference(d)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:i,components:r}},Fr={};[bt,Dt,_t,Mt,It,Lt,Ft,Nn,zn,Vn,Xn,$n,wr,Dr,Nr,zr,{hopcroftTarjanBiconnected:Or,htbc:Or,htb:Or,hopcroftTarjanBiconnectedComponents:Or},{tarjanStronglyConnected:Vr,tsc:Vr,tscc:Vr,tarjanStronglyConnectedComponents:Vr}].forEach((function(e){ge(Fr,e)})); -/*! - Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable - Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) - Licensed under The MIT License (http://opensource.org/licenses/MIT) - */ -var Xr=function(e){if(!(this instanceof Xr))return new Xr(e);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof e&&e.call(this,this.fulfill.bind(this),this.reject.bind(this))};Xr.prototype={fulfill:function(e){return jr(this,1,"fulfillValue",e)},reject:function(e){return jr(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new Xr;return n.onFulfilled.push(Wr(e,r,"fulfill")),n.onRejected.push(Wr(t,r,"reject")),Yr(n),r.proxy}};var jr=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,Yr(e)),e},Yr=function(e){1===e.state?qr(e,"onFulfilled",e.fulfillValue):2===e.state&&qr(e,"onRejected",e.rejectReason)},qr=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var a=function(){for(var e=0;e0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n-1}}(),a=function(){if(Xa)return Fa;Xa=1;var e=Li();return Fa=function(t,n){var r=this.__data__,a=e(r,t);return a<0?(++this.size,r.push([t,n])):r[a][1]=n,this},Fa}();function i(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&t%1==0&&t0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){H(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,a=[],i=0,o=n.length;i0&&this.spawn(a).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};Eo.className=Eo.classNames=Eo.classes;var ko={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:ce,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};ko.variable="(?:[\\w-.]|(?:\\\\"+ko.metaChar+"))+",ko.className="(?:[\\w-]|(?:\\\\"+ko.metaChar+"))+",ko.value=ko.string+"|"+ko.number,ko.id=ko.variable,function(){var e,t,n;for(e=ko.comparatorOp.split("|"),n=0;n=0||"="!==t&&(ko.comparatorOp+="|\\!"+t)}();var To=0,Co=1,Po=2,So=3,Bo=4,Do=5,_o=6,Ao=7,Mo=8,Ro=9,Io=10,No=11,Lo=12,zo=13,Oo=14,Vo=15,Fo=16,Xo=17,jo=18,Yo=19,qo=20,Wo=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return function(e,t){return-1*ve(e,t)}(e.selector,t.selector)})),Uo=function(){for(var e,t={},n=0;n0&&u.edgeCount>0)return at("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return at("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&at("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return W(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,i){var o=r.type,s=r.value;switch(o){case To:var l=e(s);return l.substring(0,l.length-1);case So:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case Do:var d=r.operator,h=r.field;return"["+e(d)+h+"]";case Bo:return"["+r.field+"]";case _o:var f=r.operator;return"[["+r.field+n(e(f))+t(s)+"]]";case Ao:return s;case Mo:return"#"+s;case Ro:return"."+s;case Xo:case Vo:return a(r.parent,i)+n(">")+a(r.child,i);case jo:case Fo:return a(r.ancestor,i)+" "+a(r.descendant,i);case Yo:var p=a(r.left,i),v=a(r.subject,i),g=a(r.right,i);return p+(p.length>0?" ":"")+v+g;case qo:return""}},a=function(e,t){return e.checks.reduce((function(n,a,i){return n+(t===e&&0===i?"$":"")+r(a,t)}),"")},i="",o=0;o1&&o=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(a=o||s?""+e:"",i=""+n),u&&(e=a=a.toLowerCase(),n=i=i.toLowerCase()),t){case"*=":r=a.indexOf(i)>=0;break;case"$=":r=a.indexOf(i,a.length-i.length)>=0;break;case"^=":r=0===a.indexOf(i);break;case"=":r=e===n;break;case">":d=!0,r=e>n;break;case">=":d=!0,r=e>=n;break;case"<":d=!0,r=e0;){var u=a.shift();t(u),i.add(u.id()),o&&r(a,i,u)}return e}function hs(e,t,n){if(n.isParent())for(var r=n._private.children,a=0;a1&&void 0!==arguments[1])||arguments[1],hs)},cs.forEachUp=function(e){return ds(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],fs)},cs.forEachUpAndDown=function(e){return ds(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],ps)},cs.ancestors=cs.parents,(ss=ls={data:xo.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:xo.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:xo.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:xo.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:xo.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:xo.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=ss.data,ss.removeAttr=ss.removeData;var vs,gs,ys=ls,ms={};function bs(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,a=n[0],i=a._private.edges,o=0;ot})),minIndegree:xs("indegree",(function(e,t){return et})),minOutdegree:xs("outdegree",(function(e,t){return et}))}),ge(ms,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r0,c=u;u&&(l=l[0]);var d=c?l.position():{x:0,y:0};return a={x:s.x-d.x,y:s.y-d.y},void 0===e?a:a[e]}for(var h=0;h0,g=v;v&&(p=p[0]);var y=g?p.position():{x:0,y:0};void 0!==t?f.position(e,t+y[e]):void 0!==a&&f.position({x:a.x+y.x,y:a.y+y.y})}}else if(!i)return;return this}},vs.modelPosition=vs.point=vs.position,vs.modelPositions=vs.points=vs.positions,vs.renderedPoint=vs.renderedPosition,vs.relativePoint=vs.relativePosition;var ks,Ts,Cs=gs;ks=Ts={},Ts.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),a=n.pan(),i=t.x1*r+a.x,o=t.x2*r+a.x,s=t.y1*r+a.y,l=t.y2*r+a.y;return{x1:i,x2:o,y1:s,y2:l,w:o-i,h:l-s}},Ts.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},Ts.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,a={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},i=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==i.w&&0!==i.h||((i={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-i.w/2,i.x2=o.x+i.w/2,i.y1=o.y-i.h/2,i.y2=o.y+i.h/2);var s=a.width.left.value;"px"===a.width.left.units&&a.width.val>0&&(s=100*s/a.width.val);var l=a.width.right.value;"px"===a.width.right.units&&a.width.val>0&&(l=100*l/a.width.val);var u=a.height.top.value;"px"===a.height.top.units&&a.height.val>0&&(u=100*u/a.height.val);var c=a.height.bottom.value;"px"===a.height.bottom.units&&a.height.val>0&&(c=100*c/a.height.val);var d=y(a.width.val-i.w,s,l),h=d.biasDiff,f=d.biasComplementDiff,p=y(a.height.val-i.h,u,c),v=p.biasDiff,g=p.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(i.w,i.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(i.w,a.width.val),o.x=(-h+i.x1+i.x2+f)/2,t.autoHeight=Math.max(i.h,a.height.val),o.y=(-v+i.y1+i.y2+g)/2}function y(e,t,n){var r=0,a=0,i=t+n;return e>0&&i>0&&(r=t/i*e,a=n/i*e),{biasDiff:r,biasComplementDiff:a}}}for(var r=0;re.x2?r:e.x2,e.y1=ne.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},Bs=function(e,t){return null==t?e:Ss(e,t.x1,t.y1,t.x2,t.y2)},Ds=function(e,t,n){return ht(e,t,n)},_s=function(e,t,n){if(!t.cy().headless()){var r,a,i=t._private,o=i.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,a=o.srcY):"target"===n?(r=o.tgtX,a=o.tgtY):(r=o.midX,a=o.midY);var l=i.arrowBounds=i.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=a-s,u.x2=r+s,u.y2=a+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,tn(u,1),Ss(e,u.x1,u.y1,u.x2,u.y2)}}},As=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var a=t._private,i=a.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),d=t.pstyle("text-valign"),h=Ds(i,"labelWidth",n),f=Ds(i,"labelHeight",n),p=Ds(i,"labelX",n),v=Ds(i,"labelY",n),g=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,k=f,T=h,C=T/2,P=k/2;if(m)o=p-C,s=p+C,l=v-P,u=v+P;else{switch(c.value){case"left":o=p-T,s=p;break;case"center":o=p-C,s=p+C;break;case"right":o=p,s=p+T}switch(d.value){case"top":l=v-k,u=v;break;case"center":l=v-P,u=v+P;break;case"bottom":l=v,u=v+k}}var S=g-Math.max(x,w)-E-2,B=g+Math.max(x,w)+E+2,D=y-Math.max(x,w)-E-2,_=y+Math.max(x,w)+E+2;o+=S,s+=B,l+=D,u+=_;var A=n||"main",M=a.labelBounds,R=M[A]=M[A]||{};R.x1=o,R.y1=l,R.x2=s,R.y2=u,R.w=s-o,R.h=u-l,R.leftPad=S,R.rightPad=B,R.topPad=D,R.botPad=_;var I=m&&"autorotate"===b.strValue,N=null!=b.pfValue&&0!==b.pfValue;if(I||N){var L=I?Ds(a.rstyle,"labelAngle",n):b.pfValue,z=Math.cos(L),O=Math.sin(L),V=(o+s)/2,F=(l+u)/2;if(!m){switch(c.value){case"left":V=s;break;case"right":V=o}switch(d.value){case"top":F=u;break;case"bottom":F=l}}var X=function(e,t){return{x:(e-=V)*z-(t-=F)*O+V,y:e*O+t*z+F}},j=X(o,l),Y=X(o,u),q=X(s,l),W=X(s,u);o=Math.min(j.x,Y.x,q.x,W.x),s=Math.max(j.x,Y.x,q.x,W.x),l=Math.min(j.y,Y.y,q.y,W.y),u=Math.max(j.y,Y.y,q.y,W.y)}var U=A+"Rot",H=M[U]=M[U]||{};H.x1=o,H.y1=l,H.x2=s,H.y2=u,H.w=s-o,H.h=u-l,Ss(e,o,l,s,u),Ss(a.labelBounds.all,o,l,s,u)}return e}},Ms=function(e,t){if(!t.cy().headless()){var n=t.pstyle("outline-opacity").value,r=t.pstyle("outline-width").value+t.pstyle("outline-offset").value;Rs(e,t,n,r,"outside",r/2)}},Rs=function(e,t,n,r,a,i){if(!(0===n||r<=0||"inside"===a)){var o=t.cy(),s=t.pstyle("shape").value,l=o.renderer().nodeShapes[s],u=t.position(),c=u.x,d=u.y,h=t.width(),f=t.height();if(l.hasMiterBounds){"center"===a&&(r/=2);var p=l.miterBounds(c,d,h,f,r);Bs(e,p)}else null!=i&&i>0&&nn(e,[i,i,i,i])}},Is=function(e,t){var n,r,a,i,o,s,l,u=e._private.cy,c=u.styleEnabled(),d=u.headless(),h=Jt(),f=e._private,p=e.isNode(),v=e.isEdge(),g=f.rstyle,y=p&&c?e.pstyle("bounds-expansion").pfValue:[0],m=function(e){return"none"!==e.pstyle("display").value},b=!c||m(e)&&(!v||m(e.source())&&m(e.target()));if(b){var x=0;c&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(x=e.pstyle("overlay-padding").value);var w=0;c&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(w=e.pstyle("underlay-padding").value);var E=Math.max(x,w),k=0;if(c&&(k=e.pstyle("width").pfValue/2),p&&t.includeNodes){var T=e.position();o=T.x,s=T.y;var C=e.outerWidth()/2,P=e.outerHeight()/2;Ss(h,n=o-C,a=s-P,r=o+C,i=s+P),c&&Ms(h,e),c&&t.includeOutlines&&!d&&Ms(h,e),c&&function(e,t){if(!t.cy().headless()){var n=t.pstyle("border-opacity").value,r=t.pstyle("border-width").pfValue,a=t.pstyle("border-position").value;Rs(e,t,n,r,a)}}(h,e)}else if(v&&t.includeEdges)if(c&&!d){var S=e.pstyle("curve-style").strValue;if(n=Math.min(g.srcX,g.midX,g.tgtX),r=Math.max(g.srcX,g.midX,g.tgtX),a=Math.min(g.srcY,g.midY,g.tgtY),i=Math.max(g.srcY,g.midY,g.tgtY),Ss(h,n-=k,a-=k,r+=k,i+=k),"haystack"===S){var B=g.haystackPts;if(B&&2===B.length){if(n=B[0].x,a=B[0].y,n>(r=B[1].x)){var D=n;n=r,r=D}if(a>(i=B[1].y)){var _=a;a=i,i=_}Ss(h,n-k,a-k,r+k,i+k)}}else if("bezier"===S||"unbundled-bezier"===S||ue(S,"segments")||ue(S,"taxi")){var A;switch(S){case"bezier":case"unbundled-bezier":A=g.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":A=g.linePts}if(null!=A)for(var M=0;M(r=N.x)){var L=n;n=r,r=L}if((a=I.y)>(i=N.y)){var z=a;a=i,i=z}Ss(h,n-=k,a-=k,r+=k,i+=k)}if(c&&t.includeEdges&&v&&(_s(h,e,"mid-source"),_s(h,e,"mid-target"),_s(h,e,"source"),_s(h,e,"target")),c)if("yes"===e.pstyle("ghost").value){var O=e.pstyle("ghost-offset-x").pfValue,V=e.pstyle("ghost-offset-y").pfValue;Ss(h,h.x1+O,h.y1+V,h.x2+O,h.y2+V)}var F=f.bodyBounds=f.bodyBounds||{};rn(F,h),nn(F,y),tn(F,1),c&&(n=h.x1,r=h.x2,a=h.y1,i=h.y2,Ss(h,n-E,a-E,r+E,i+E));var X=f.overlayBounds=f.overlayBounds||{};rn(X,h),nn(X,y),tn(X,1);var j=f.labelBounds=f.labelBounds||{};null!=j.all?((l=j.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):j.all=Jt(),c&&t.includeLabels&&(t.includeMainLabels&&As(h,e,null),v&&(t.includeSourceLabels&&As(h,e,"source"),t.includeTargetLabels&&As(h,e,"target")))}return h.x1=Ps(h.x1),h.y1=Ps(h.y1),h.x2=Ps(h.x2),h.y2=Ps(h.y2),h.w=Ps(h.x2-h.x1),h.h=Ps(h.y2-h.y1),h.w>0&&h.h>0&&b&&(nn(h,y),tn(h,1)),h},Ns=function(e){var t=0,n=function(e){return(e?1:0)<0&&void 0!==arguments[0]?arguments[0]:tl,t=arguments.length>1?arguments[1]:void 0,n=0;n=0;s--)o(s);return this},rl.removeAllListeners=function(){return this.removeListener("*")},rl.emit=rl.trigger=function(e,t,n){var r=this.listeners,a=r.length;return this.emitting++,H(t)||(t=[t]),ol(this,(function(e,i){null!=n&&(r=[{event:i.event,type:i.type,namespace:i.namespace,callback:n}],a=r.length);for(var o=function(){var n=r[s];if(n.type===i.type&&(!n.namespace||n.namespace===i.namespace||".*"===n.namespace)&&e.eventMatches(e.context,n,i)){var a=[i];null!=t&&function(e,t){for(var n=0;n1&&!r){var a=this.length-1,i=this[a],o=i._private.data.id;this[a]=void 0,this[e]=i,n.set(o,{ele:i,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var a=r.index;return this.unmergeAt(a),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&W(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r=0;t--){e(this[t])&&this.unmergeAt(t)}return this},map:function(e,t){for(var n=[],r=this,a=0;ar&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,a=this,i=0;i=0&&a1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){n._private.styleDirty&&(n._private.styleDirty=!1,r.style().apply(n));var a=n._private.style[e];return null!=a?a:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,a=n.style();if(K(e)){var i=e;a.applyBypass(this,i,r),this.emitAndNotify("style")}else if(W(e)){if(void 0===t){var o=this[0];return o?a.getStylePropertyValue(o,e):void 0}a.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?a.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),a=this;if(void 0===e)for(var i=0;i0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),Al.neighbourhood=Al.neighborhood,Al.closedNeighbourhood=Al.closedNeighborhood,Al.openNeighbourhood=Al.openNeighborhood,ge(Al,{source:us((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:us((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:Nl({attr:"source"}),targets:Nl({attr:"target"})}),ge(Al,{edgesWith:us(Ll(),"edgesWith"),edgesTo:us(Ll({thisIsSrc:!0}),"edgesTo")}),ge(Al,{connectedEdges:us((function(e){for(var t=[],n=0;n0);return i},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),Al.componentsOf=Al.components;var Ol=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var a=new pt,i=!1;if(t){if(t.length>0&&K(t[0])&&!Q(t[0])){i=!0;for(var o=[],s=new gt,l=0,u=t.length;l0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=this,i=a.cy(),o=i._private,s=[],l=[],u=0,c=a.length;u0){for(var I=e.length===a.length?a:new Ol(i,e),N=0;N0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],a={},i=n._private.cy;function o(e){var n=a[e.id()];t&&e.removed()||n||(a[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n0&&(e?k.emitAndNotify("remove"):t&&k.emit("remove"));for(var T=0;T=.001?function(t,r){for(var a=0;a<4;++a){var i=h(r,e,n);if(0===i)return r;r-=(d(r,e,n)-t)/i}return r}(t,o):0===l?o:function(t,r,a){var i,o,s=0;do{(i=d(o=r+(a-r)/2,e,n)-t)>0?a=o:r=o}while(Math.abs(i)>1e-7&&++s<10);return o}(t,r,r+a)}var p=!1;function v(){p=!0,e===t&&n===r||function(){for(var t=0;t<11;++t)s[t]=d(t*a,e,n)}()}var g=function(a){return p||v(),e===t&&n===r?a:0===a?0:1===a?1:d(f(a),t,r)};g.getControlPoints=function(){return[{x:e,y:t},{x:n,y:r}]};var y="generateBezier("+[e,t,n,r]+")";return g.toString=function(){return y},g} -/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */var jl=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,n,r){var a={x:t.x+r.dx*n,v:t.v+r.dv*n,tension:t.tension,friction:t.friction};return{dx:a.v,dv:e(a)}}function n(n,r){var a={dx:n.v,dv:e(n)},i=t(n,.5*r,a),o=t(n,.5*r,i),s=t(n,r,o),l=1/6*(a.dx+2*(i.dx+o.dx)+s.dx),u=1/6*(a.dv+2*(i.dv+o.dv)+s.dv);return n.x=n.x+l*r,n.v=n.v+u*r,n}return function e(t,r,a){var i,o,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,d=1e-4;for(t=parseFloat(t)||500,r=parseFloat(r)||20,a=a||null,l.tension=t,l.friction=r,o=(i=null!==a)?(c=e(t,r))/a*.016:.016;s=n(s||l,o),u.push(1+s.x),c+=16,Math.abs(s.x)>d&&Math.abs(s.v)>d;);return i?function(e){return u[e*(u.length-1)|0]}:c}}(),Yl=function(e,t,n,r){var a=Xl(e,t,n,r);return function(e,t,n){return e+(t-e)*a(n)}},ql={linear:function(e,t,n){return e+(t-e)*n},ease:Yl(.25,.1,.25,1),"ease-in":Yl(.42,0,1,1),"ease-out":Yl(0,0,.58,1),"ease-in-out":Yl(.42,0,.58,1),"ease-in-sine":Yl(.47,0,.745,.715),"ease-out-sine":Yl(.39,.575,.565,1),"ease-in-out-sine":Yl(.445,.05,.55,.95),"ease-in-quad":Yl(.55,.085,.68,.53),"ease-out-quad":Yl(.25,.46,.45,.94),"ease-in-out-quad":Yl(.455,.03,.515,.955),"ease-in-cubic":Yl(.55,.055,.675,.19),"ease-out-cubic":Yl(.215,.61,.355,1),"ease-in-out-cubic":Yl(.645,.045,.355,1),"ease-in-quart":Yl(.895,.03,.685,.22),"ease-out-quart":Yl(.165,.84,.44,1),"ease-in-out-quart":Yl(.77,0,.175,1),"ease-in-quint":Yl(.755,.05,.855,.06),"ease-out-quint":Yl(.23,1,.32,1),"ease-in-out-quint":Yl(.86,0,.07,1),"ease-in-expo":Yl(.95,.05,.795,.035),"ease-out-expo":Yl(.19,1,.22,1),"ease-in-out-expo":Yl(1,0,0,1),"ease-in-circ":Yl(.6,.04,.98,.335),"ease-out-circ":Yl(.075,.82,.165,1),"ease-in-out-circ":Yl(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return ql.linear;var r=jl(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":Yl};function Wl(e,t,n,r,a){if(1===r)return n;if(t===n)return n;var i=a(t,n,r);return null==e||((e.roundValue||e.color)&&(i=Math.round(i)),void 0!==e.min&&(i=Math.max(i,e.min)),void 0!==e.max&&(i=Math.min(i,e.max))),i}function Ul(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Hl(e,t,n,r,a){var i=null!=a?a.type:null;n<0?n=0:n>1&&(n=1);var o=Ul(e,a),s=Ul(t,a);if(G(o)&&G(s))return Wl(i,o,s,n,r);if(H(o)&&H(s)){for(var l=[],u=0;u0?("spring"===d&&h.push(o.duration),o.easingImpl=ql[d].apply(null,h)):o.easingImpl=ql[d]}var f,p=o.easingImpl;if(f=0===o.duration?1:(n-l)/o.duration,o.applying&&(f=o.progress),f<0?f=0:f>1&&(f=1),null==o.delay){var v=o.startPosition,g=o.position;if(g&&a&&!e.locked()){var y={};Gl(v.x,g.x)&&(y.x=Hl(v.x,g.x,f,p)),Gl(v.y,g.y)&&(y.y=Hl(v.y,g.y,f,p)),e.position(y)}var m=o.startPan,b=o.pan,x=i.pan,w=null!=b&&r;w&&(Gl(m.x,b.x)&&(x.x=Hl(m.x,b.x,f,p)),Gl(m.y,b.y)&&(x.y=Hl(m.y,b.y,f,p)),e.emit("pan"));var E=o.startZoom,k=o.zoom,T=null!=k&&r;T&&(Gl(E,k)&&(i.zoom=Qt(i.minZoom,Hl(E,k,f,p),i.maxZoom)),e.emit("zoom")),(w||T)&&e.emit("viewport");var C=o.style;if(C&&C.length>0&&a){for(var P=0;P=0;t--){(0,e[t])()}e.splice(0,e.length)},c=i.length-1;c>=0;c--){var d=i[c],h=d._private;h.stopped?(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.frames)):(h.playing||h.applying)&&(h.playing&&h.applying&&(h.applying=!1),h.started||Zl(0,d,e),Kl(t,d,e,n),h.applying&&(h.applying=!1),u(h.frames),null!=h.step&&h.step(e),d.completed()&&(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.completes)),s=!0)}return n||0!==i.length||0!==o.length||r.push(t),s}for(var i=!1,o=0;o0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var Ql={animate:xo.animate(),animation:xo.animation(),animated:xo.animated(),clearQueue:xo.clearQueue(),delay:xo.delay(),delayAnimation:xo.delayAnimation(),stop:xo.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){$l(n,e)}),t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&Ie((function(n){$l(n,e),t()}))}()}}},Jl={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&Q(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},eu=function(e){return W(e)?new as(e):e},tu={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new nl(Jl,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,eu(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,eu(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,eu(t),n),this},once:function(e,t,n){return this.emitter().one(e,eu(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};xo.eventAliasesOn(tu);var nu={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};nu.jpeg=nu.jpg;var ru={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var a;a=W(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var i=new r(ge({},e,{cy:t,eles:a}));return i}nt("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else nt("A `name` must be specified to make a layout");else nt("Layout options must be specified to make a layout")}};ru.createLayout=ru.makeLayout=ru.layout;var au={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var a=this.renderer();!this.destroyed()&&a&&a.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};ou.invalidateDimensions=ou.resize;var su={collection:function(e,t){return W(e)?this.$(e):$(e)?e.collection():H(e)?(t||(t={}),new Ol(this,e,t.unique,t.removed)):new Ol(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};su.elements=su.filter=su.$;var lu={},uu="t";lu.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r0;if(h||d&&f){var p=void 0;h&&f||h?p=u.properties:f&&(p=u.mappedProperties);for(var v=0;v1&&(g=1),s.color){var w=a.valueMin[0],E=a.valueMax[0],k=a.valueMin[1],T=a.valueMax[1],C=a.valueMin[2],P=a.valueMax[2],S=null==a.valueMin[3]?1:a.valueMin[3],B=null==a.valueMax[3]?1:a.valueMax[3],D=[Math.round(w+(E-w)*g),Math.round(k+(T-k)*g),Math.round(C+(P-C)*g),Math.round(S+(B-S)*g)];n={bypass:a.bypass,name:a.name,value:D,strValue:"rgb("+D[0]+", "+D[1]+", "+D[2]+")"}}else{if(!s.number)return!1;var _=a.valueMin+(a.valueMax-a.valueMin)*g;n=this.parse(a.name,_,a.bypass,h)}if(!n)return v(),!1;n.mapping=a,a=n;break;case o.data:for(var A=a.field.split("."),M=d.data,R=0;R0&&i>0){for(var s={},l=!1,u=0;u0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:i,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1)},lu.checkTrigger=function(e,t,n,r,a,i){var o=this.properties[t],s=a(o);e.removed()||null!=s&&s(n,r,e)&&i(o)},lu.checkZOrderTrigger=function(e,t,n,r){var a=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){a._private.cy.notify("zorder",e)}))},lu.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(t){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache()}))},lu.checkConnectedEdgesBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBoundsOfConnectedEdges}),(function(t){e.connectedEdges().forEach((function(e){e.dirtyBoundingBoxCache()}))}))},lu.checkParallelEdgesBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBoundsOfParallelEdges}),(function(t){e.parallelEdges().forEach((function(e){e.dirtyBoundingBoxCache()}))}))},lu.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r),this.checkConnectedEdgesBoundsTrigger(e,t,n,r),this.checkParallelEdgesBoundsTrigger(e,t,n,r)};var cu={applyBypass:function(e,t,n,r){var a=[];if("*"===t||"**"===t){if(void 0!==n)for(var i=0;it.length?i.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(i=i.replace(/[/][*](\s|.)+?[*][/]/g,"");;){if(i.match(/^\s*$/))break;var l=i.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){at("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+i);break}t=l[0];var u=l[1];if("core"!==u)if(new as(u).invalid){at("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();continue}var c=l[2],d=!1;n=c;for(var h=[];;){if(n.match(/^\s*$/))break;var f=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!f){at("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),d=!0;break}r=f[0];var p=f[1],v=f[2];if(this.properties[p])a.parse(p,v)?(h.push({name:p,val:v}),s()):(at("Skipping property: Invalid property definition in: "+r),s());else at("Skipping property: Invalid property name in: "+r),s()}if(d){o();break}a.selector(u);for(var g=0;g=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var h=s.data;return{name:e,value:u,strValue:""+t,mapped:h,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(d.multiple)return!1;var f=s.mapData;if(!d.color&&!d.number)return!1;var p=this.parse(e,c[4]);if(!p||p.mapped)return!1;var v=this.parse(e,c[5]);if(!v||v.mapped)return!1;if(p.pfValue===v.pfValue||p.strValue===v.strValue)return at("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+p.strValue+"`"),this.parse(e,p.strValue);if(d.color){var g=p.value,y=v.value;if(!(g[0]!==y[0]||g[1]!==y[1]||g[2]!==y[2]||g[3]!==y[3]&&(null!=g[3]&&1!==g[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:f,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:p.value,valueMax:v.value,bypass:n}}}if(d.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):H(t)?t:[t],d.evenMultiple&&m.length%2!=0)return null;for(var b=[],x=[],w=[],E="",k=!1,T=0;T0?" ":"")+C.strValue}return d.validate&&!d.validate(b,x)?null:d.singleEnum&&k?1===b.length&&W(b[0])?{name:e,value:b[0],strValue:b[0],bypass:n}:null:{name:e,value:b,pfValue:w,strValue:E,bypass:n,units:x}}var P,S,B=function(){for(var r=0;rd.max||d.strictMax&&t===d.max))return null;var R={name:e,value:t,strValue:""+t+(D||""),units:D,bypass:n};return d.unitless||"px"!==D&&"em"!==D?R.pfValue=t:R.pfValue="px"!==D&&D?this.getEmSizeInPixels()*t:t,"ms"!==D&&"s"!==D||(R.pfValue="ms"===D?t:1e3*t),"deg"!==D&&"rad"!==D||(R.pfValue="rad"===D?t:(P=t,Math.PI*P/180)),"%"===D&&(R.pfValue=t/100),R}if(d.propList){var I=[],N=""+t;if("none"===N);else{for(var L=N.split(/\s*,\s*|\s+/),z=0;z0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:o=(o=(o=Math.min((s-2*t)/n.w,(l-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:o)=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,a=r.pan,i=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),G(e)?n=e:K(e)&&(n=e.level,null!=e.position?t=Xt(e.position,i,a):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)t.maxZoom||!t.zoomingEnabled?i=!0:(t.zoom=s,a.push("zoom"))}if(r&&(!i||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;G(l.x)&&(t.pan.x=l.x,o=!1),G(l.y)&&(t.pan.y=l.y,o=!1),o||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(W(e)){var n=e;e=this.mutableElements().filter(n)}else $(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),a=this.width(),i=this.height();return{x:(a-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(i-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,a=this;return n.sizeCache=n.sizeCache||(r?(e=a.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};xu.centre=xu.center,xu.autolockNodes=xu.autolock,xu.autoungrabifyNodes=xu.autoungrabify;var wu={data:xo.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:xo.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:xo.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:xo.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};wu.attr=wu.data,wu.removeAttr=wu.removeData;var Eu=function(e){var t=this,n=(e=ge({},e)).container;n&&!Z(n)&&Z(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var a=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var i=void 0!==c&&void 0!==n&&!e.headless,o=e;o.layout=ge({name:i?"grid":"null"},o.layout),o.renderer=ge({name:i?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new Ol(this),listeners:[],aniEles:new Ol(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?i:o.styleEnabled,zoom:G(o.zoom)?o.zoom:1,pan:{x:K(o.pan)&&G(o.pan.x)?o.pan.x:0,y:K(o.pan)&&G(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});l.styleEnabled&&t.setStyle([]);var u=ge({},o,o.renderer);t.initRenderer(u);!function(e,t){if(e.some(re))return Hr.all(e).then(t);t(e)}([o.style,o.elements],(function(e){var n=e[0],i=e[1];l.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var a=t.mutableElements();a.length>0&&a.remove(),null!=e&&(K(e)||H(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var i=ge({},t._private.options.layout);i.eles=t.elements(),t.layout(i).run()}(i,(function(){t.startAnimationLoop(),l.ready=!0,U(o.ready)&&t.on("ready",o.ready);for(var e=0;e0,l=!!t.boundingBox,u=Jt(l?t.boundingBox:structuredClone(n.extent()));if($(t.roots))e=t.roots;else if(H(t.roots)){for(var c=[],d=0;d0;){var B=C.shift(),D=T(B,P);if(D)B.outgoers().filter((function(e){return e.isNode()&&r.has(e)})).forEach(S);else if(null===D){at("Detected double maximal shift for node `"+B.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}var _=0;if(t.avoidOverlap)for(var A=0;A0&&y[0].length<=3?i/2:0),s=2*Math.PI/y[r].length*a;return 0===r&&1===y[0].length&&(o=1),{x:q+o*Math.cos(s),y:U+o*Math.sin(s)}}var c=y[r].length,d=Math.max(1===c?0:l?(u.w-2*t.padding-K.w)/((t.grid?Z:c)-1):(u.w-2*t.padding-K.w)/((t.grid?Z:c)+1),_);return{x:q+(a+1-(c+1)/2)*d,y:U+(r+1-(O+1)/2)*G}}(e),u,Q[t.direction])})),this};var Du={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function _u(e){this.options=ge({},Du,e)}_u.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));for(var o,s=Jt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l=s.x1+s.w/2,u=s.y1+s.h/2,c=(void 0===t.sweep?2*Math.PI-2*Math.PI/i.length:t.sweep)/Math.max(1,i.length-1),d=0,h=0;h1&&t.avoidOverlap){d*=1.75;var g=Math.cos(c)-Math.cos(0),y=Math.sin(c)-Math.sin(0),m=Math.sqrt(d*d/(g*g+y*y));o=Math.max(m,o)}return r.nodes().layoutPositions(this,t,(function(e,n){var r=t.startAngle+n*c*(a?1:-1),i=o*Math.cos(r),s=o*Math.sin(r);return{x:l+i,y:u+s}})),this};var Au,Mu={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Ru(e){this.options=ge({},Mu,e)}Ru.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,a=t.eles,i=a.nodes().not(":parent"),o=Jt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s=o.x1+o.w/2,l=o.y1+o.h/2,u=[],c=0,d=0;d0)Math.abs(m[0].value-x.value)>=g&&(m=[],y.push(m));m.push(x)}var w=c+t.minNodeSpacing;if(!t.avoidOverlap){var E=y.length>0&&y[0].length>1,k=(Math.min(o.w,o.h)/2-w)/(y.length+E?1:0);w=Math.min(w,k)}for(var T=0,C=0;C1&&t.avoidOverlap){var D=Math.cos(B)-Math.cos(0),_=Math.sin(B)-Math.sin(0),A=Math.sqrt(w*w/(D*D+_*_));T=Math.max(A,T)}P.r=T,T+=w}if(t.equidistant){for(var M=0,R=0,I=0;I=e.numIter)&&(ju(r,e),r.temperature=r.temperature*e.coolingFactor,!(r.temperature=e.animationThreshold&&i(),Ie(c)):(ec(r,e),s())};c()}else{for(;u;)u=o(l),l++;ec(r,e),s()}return this},Nu.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},Nu.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var Lu=function(e,t,n){for(var r=n.eles.edges(),a=n.eles.nodes(),i=Jt(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:i.w,clientHeight:i.h,boundingBox:i},s=n.eles.components(),l={},u=0;u0){o.graphSet.push(w);for(u=0;ur.count?0:r.graph},Ou=function(e,t,n,r){var a=r.graphSet[n];if(-10)var s=(u=r.nodeOverlap*o)*a/(v=Math.sqrt(a*a+i*i)),l=u*i/v;else{var u,c=Hu(e,a,i),d=Hu(t,-1*a,-1*i),h=d.x-c.x,f=d.y-c.y,p=h*h+f*f,v=Math.sqrt(p);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/p)*h/v,l=u*f/v}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},Uu=function(e,t,n,r){if(n>0)var a=e.maxX-t.minX;else a=t.maxX-e.minX;if(r>0)var i=e.maxY-t.minY;else i=t.maxY-e.minY;return a>=0&&i>=0?Math.sqrt(a*a+i*i):0},Hu=function(e,t,n){var r=e.positionX,a=e.positionY,i=e.height||1,o=e.width||1,s=n/t,l=i/o,u={};return 0===t&&0n?(u.x=r,u.y=a+i/2,u):0t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=a-o*n/2/t,u):0=l)?(u.x=r+i*t/2/n,u.y=a+i/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-i*t/2/n,u.y=a-i/2,u):u},Ku=function(e,t){for(var n=0;n1){var p=t.gravity*d/f,v=t.gravity*h/f;c.offsetX+=p,c.offsetY+=v}}}}},Zu=function(e,t){var n=[],r=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;r<=a;){var i=n[r++],o=e.idToIndex[i],s=e.layoutNodes[o],l=s.children;if(0n)var a={x:n*e/r,y:n*t/r};else a={x:e,y:t};return a},Ju=function(e,t){var n=e.parentId;if(null!=n){var r=t.layoutNodes[t.idToIndex[n]],a=!1;return(null==r.maxX||e.maxX+r.padRight>r.maxX)&&(r.maxX=e.maxX+r.padRight,a=!0),(null==r.minX||e.minX-r.padLeftr.maxY)&&(r.maxY=e.maxY+r.padBottom,a=!0),(null==r.minY||e.minY-r.padTopp&&(d+=f+t.componentSpacing,c=0,h=0,f=0)}}},tc={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function nc(e){this.options=ge({},tc,e)}nc.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));var i=Jt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===i.h||0===i.w)r.nodes().layoutPositions(this,t,(function(e){return{x:i.x1,y:i.y1}}));else{var o=a.size(),s=Math.sqrt(o*i.h/i.w),l=Math.round(s),u=Math.round(i.w/i.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},d=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},h=t.rows,f=null!=t.cols?t.cols:t.columns;if(null!=h&&null!=f)l=h,u=f;else if(null!=h&&null==f)l=h,u=Math.ceil(o/l);else if(null==h&&null!=f)u=f,l=Math.ceil(o/u);else if(u*l>o){var p=c(),v=d();(p-1)*v>=o?c(p-1):(v-1)*p>=o&&d(v-1)}else for(;u*l=o?d(y+1):c(g+1)}var m=i.w/u,b=i.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x=u&&(A=0,_++)},R={},I=0;I(r=vn(e,t,x[w],x[w+1],x[w+2],x[w+3])))return g(n,r),!0}else if("bezier"===i.edgeType||"multibezier"===i.edgeType||"self"===i.edgeType||"compound"===i.edgeType)for(x=i.allpts,w=0;w+5(r=pn(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return g(n,r),!0;m=m||a.source,b=b||a.target;var E=o.getArrowWidth(l,c),k=[{name:"source",x:i.arrowStartX,y:i.arrowStartY,angle:i.srcArrowAngle},{name:"target",x:i.arrowEndX,y:i.arrowEndY,angle:i.tgtArrowAngle},{name:"mid-source",x:i.midX,y:i.midY,angle:i.midsrcArrowAngle},{name:"mid-target",x:i.midX,y:i.midY,angle:i.midtgtArrowAngle}];for(w=0;w0&&(y(m),y(b))}function b(e,t,n){return ht(e,t,n)}function x(n,r){var a,i=n._private,o=p;a=r?r+"-":"",n.boundingBox();var s=i.labelBounds[r||"main"],l=n.pstyle(a+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(i.rscratch,"labelX",r),c=b(i.rscratch,"labelY",r),d=b(i.rscratch,"labelAngle",r),h=n.pstyle(a+"text-margin-x").pfValue,f=n.pstyle(a+"text-margin-y").pfValue,v=s.x1-o-h,y=s.x2+o-h,m=s.y1-o-f,x=s.y2+o-f;if(d){var w=Math.cos(d),E=Math.sin(d),k=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},T=k(v,m),C=k(v,x),P=k(y,m),S=k(y,x),B=[T.x+h,T.y+f,P.x+h,P.y+f,S.x+h,S.y+f,C.x+h,C.y+f];if(gn(e,t,B))return g(n),!0}else if(on(s,e,t))return g(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){var a=this.getCachedZSortedEles().interactive,o=2/this.cy.zoom(),s=[],l=Math.min(e,n),u=Math.max(e,n),c=Math.min(t,r),d=Math.max(t,r),h=Jt({x1:e=l,y1:t=c,x2:n=u,y2:r=d}),f=[{x:h.x1,y:h.y1},{x:h.x2,y:h.y1},{x:h.x2,y:h.y2},{x:h.x1,y:h.y2}],p=[[f[0],f[1]],[f[1],f[2]],[f[2],f[3]],[f[3],f[0]]];function v(e,t,n){return ht(e,t,n)}function g(e,t){var n=e._private,r=o;e.boundingBox();var a=n.labelBounds.main;if(!a)return null;var i=v(n.rscratch,"labelX",t),s=v(n.rscratch,"labelY",t),l=v(n.rscratch,"labelAngle",t),u=e.pstyle("text-margin-x").pfValue,c=e.pstyle("text-margin-y").pfValue,d=a.x1-r-u,h=a.x2+r-u,f=a.y1-r-c,p=a.y2+r-c;if(l){var g=Math.cos(l),y=Math.sin(l),m=function(e,t){return{x:(e-=i)*g-(t-=s)*y+i,y:e*y+t*g+s}};return[m(d,f),m(h,f),m(h,p),m(d,p)]}return[{x:d,y:f},{x:h,y:f},{x:h,y:p},{x:d,y:p}]}function y(e,t,n,r){function a(e,t,n){return(n.y-e.y)*(t.x-e.x)>(t.y-e.y)*(n.x-e.x)}return a(e,n,r)!==a(t,n,r)&&a(e,t,n)!==a(e,t,r)}for(var m=0;m0?-(Math.PI-i.ang):Math.PI+i.ang),Nc(t,n,Ic),mc=Rc.nx*Ic.ny-Rc.ny*Ic.nx,bc=Rc.nx*Ic.nx-Rc.ny*-Ic.ny,Ec=Math.asin(Math.max(-1,Math.min(1,mc))),Math.abs(Ec)<1e-6)return gc=t.x,yc=t.y,void(Tc=Pc=0);xc=1,wc=!1,bc<0?Ec<0?Ec=Math.PI+Ec:(Ec=Math.PI-Ec,xc=-1,wc=!0):Ec>0&&(xc=-1,wc=!0),Pc=void 0!==t.radius?t.radius:r,kc=Ec/2,Sc=Math.min(Rc.len/2,Ic.len/2),a?(Cc=Math.abs(Math.cos(kc)*Pc/Math.sin(kc)))>Sc?(Cc=Sc,Tc=Math.abs(Cc*Math.sin(kc)/Math.cos(kc))):Tc=Pc:(Cc=Math.min(Sc,Pc),Tc=Math.abs(Cc*Math.sin(kc)/Math.cos(kc))),_c=t.x+Ic.nx*Cc,Ac=t.y+Ic.ny*Cc,gc=_c-Ic.ny*Tc*xc,yc=Ac+Ic.nx*Tc*xc,Bc=t.x+Rc.nx*Cc,Dc=t.y+Rc.ny*Cc,Mc=t};function zc(e,t){0===t.radius?e.lineTo(t.cx,t.cy):e.arc(t.cx,t.cy,t.radius,t.startAngle,t.endAngle,t.counterClockwise)}function Oc(e,t,n,r){var a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];return 0===r||0===t.radius?{cx:t.x,cy:t.y,radius:0,startX:t.x,startY:t.y,stopX:t.x,stopY:t.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(Lc(e,t,n,r,a),{cx:gc,cy:yc,radius:Tc,startX:Bc,startY:Dc,stopX:_c,stopY:Ac,startAngle:Rc.ang+Math.PI/2*xc,endAngle:Ic.ang-Math.PI/2*xc,counterClockwise:wc})}var Vc=.01,Fc=Math.sqrt(.02),Xc={};function jc(e){var t=[];if(null!=e){for(var n=0;n0?Math.max(e-t,0):Math.min(e+t,0)},S=P(T,E),B=P(C,k),D=!1;"auto"===g?v=Math.abs(S)>Math.abs(B)?a:r:g===l||g===s?(v=r,D=!0):g!==i&&g!==o||(v=a,D=!0);var _,A=v===r,M=A?B:S,R=A?C:T,I=Ut(R),N=!1;(D&&(m||x)||!(g===s&&R<0||g===l&&R>0||g===i&&R>0||g===o&&R<0)||(M=(I*=-1)*Math.abs(M),N=!0),m)?_=(b<0?1+b:b)*M:_=(b<0?M:0)+b*I;var L=function(e){return Math.abs(e)=Math.abs(M)},z=L(_),O=L(Math.abs(M)-Math.abs(_));if((z||O)&&!N)if(A){var V=Math.abs(R)<=d/2,F=Math.abs(T)<=h/2;if(V){var X=(u.x1+u.x2)/2,j=u.y1,Y=u.y2;n.segpts=[X,j,X,Y]}else if(F){var q=(u.y1+u.y2)/2,W=u.x1,U=u.x2;n.segpts=[W,q,U,q]}else n.segpts=[u.x1,u.y2]}else{var H=Math.abs(R)<=c/2,K=Math.abs(C)<=f/2;if(H){var G=(u.y1+u.y2)/2,Z=u.x1,$=u.x2;n.segpts=[Z,G,$,G]}else if(K){var Q=(u.x1+u.x2)/2,J=u.y1,ee=u.y2;n.segpts=[Q,J,Q,ee]}else n.segpts=[u.x2,u.y1]}else if(A){var te=u.y1+_+(p?d/2*I:0),ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else{var ae=u.x1+_+(p?c/2*I:0),ie=u.y1,oe=u.y2;n.segpts=[ae,ie,ae,oe]}if(n.isRound){var se=e.pstyle("taxi-radius").value,le="arc-radius"===e.pstyle("radius-type").value[0];n.radii=new Array(n.segpts.length/2).fill(se),n.isArcRadius=new Array(n.segpts.length/2).fill(le)}},Xc.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,a=t.tgtPos,i=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,d=t.srcCornerRadius,h=t.tgtCornerRadius,f=t.srcRs,p=t.tgtRs,v=!G(n.startX)||!G(n.startY),g=!G(n.arrowStartX)||!G(n.arrowStartY),y=!G(n.endX)||!G(n.endY),m=!G(n.arrowEndX)||!G(n.arrowEndY),b=3*(this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth),x=Ht({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),w=xv.poolIndex()){var g=p;p=v,v=g}var y=d.srcPos=p.position(),m=d.tgtPos=v.position(),b=d.srcW=p.outerWidth(),x=d.srcH=p.outerHeight(),E=d.tgtW=v.outerWidth(),k=d.tgtH=v.outerHeight(),T=d.srcShape=n.nodeShapes[t.getNodeShape(p)],C=d.tgtShape=n.nodeShapes[t.getNodeShape(v)],P=d.srcCornerRadius="auto"===p.pstyle("corner-radius").value?"auto":p.pstyle("corner-radius").pfValue,S=d.tgtCornerRadius="auto"===v.pstyle("corner-radius").value?"auto":v.pstyle("corner-radius").pfValue,B=d.tgtRs=v._private.rscratch,D=d.srcRs=p._private.rscratch;d.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var _=0;_=Fc||(q=Math.sqrt(Math.max(Y*Y,Vc)+Math.max(j*j,Vc)));var W=d.vector={x:Y,y:j},U=d.vectorNorm={x:W.x/q,y:W.y/q},H={x:-U.y,y:U.x};d.nodesOverlap=!G(q)||C.checkPoint(L[0],L[1],0,E,k,m.x,m.y,S,B)||T.checkPoint(O[0],O[1],0,b,x,y.x,y.y,P,D),d.vectorNormInverse=H,e={nodesOverlap:d.nodesOverlap,dirCounts:d.dirCounts,calculatedIntersection:!0,hasBezier:d.hasBezier,hasUnbundled:d.hasUnbundled,eles:d.eles,srcPos:m,srcRs:B,tgtPos:y,tgtRs:D,srcW:E,srcH:k,tgtW:b,tgtH:x,srcIntn:V,tgtIntn:z,srcShape:C,tgtShape:T,posPts:{x1:X.x2,y1:X.y2,x2:X.x1,y2:X.y1},intersectionPts:{x1:F.x2,y1:F.y2,x2:F.x1,y2:F.y1},vector:{x:-W.x,y:-W.y},vectorNorm:{x:-U.x,y:-U.y},vectorNormInverse:{x:-H.x,y:-H.y}}}var K=N?e:d;M.nodesOverlap=K.nodesOverlap,M.srcIntn=K.srcIntn,M.tgtIntn=K.tgtIntn,M.isRound=R.startsWith("round"),r&&(p.isParent()||p.isChild()||v.isParent()||v.isChild())&&(p.parents().anySame(v)||v.parents().anySame(p)||p.same(v)&&p.isParent())?t.findCompoundLoopPoints(A,K,_,I):p===v?t.findLoopPoints(A,K,_,I):R.endsWith("segments")?t.findSegmentsPoints(A,K):R.endsWith("taxi")?t.findTaxiPoints(A,K):"straight"===R||!I&&d.eles.length%2==1&&_===Math.floor(d.eles.length/2)?t.findStraightEdgePoints(A):t.findBezierPoints(A,K,_,I,N),t.findEndpoints(A),t.tryToCorrectInvalidPoints(A,K),t.checkForInvalidEdgeWarning(A),t.storeAllpts(A),t.storeEdgeProjections(A),t.calculateArrowAngles(A),t.recalculateEdgeLabelProjections(A),t.calculateLabelAngles(A)}},w=0;w0){var J=f,ee=Kt(J,Yt(i)),te=Kt(J,Yt(Q)),ne=ee;if(te2)Kt(J,{x:Q[2],y:Q[3]})0){var ge=p,ye=Kt(ge,Yt(i)),me=Kt(ge,Yt(ve)),be=ye;if(me2)Kt(ge,{x:ve[2],y:ve[3]})=u||m){c={cp:v,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-h)/x.length,E=x.t1-x.t0,k=s?x.t0+E*w:x.t1-E*w;k=Qt(0,k,1),t=$t(b.p0,b.p1,b.p2,k),a=function(e,t,n,r){var a=Qt(0,r-.001,1),i=Qt(0,r+.001,1),o=$t(e,t,n,a),s=$t(e,t,n,i);return Kc(o,s)}(b.p0,b.p1,b.p2,k);break;case"straight":case"segments":case"haystack":for(var T,C,P,S,B=0,D=r.allpts.length,_=0;_+3=u));_+=2);var A=(u-C)/T;A=Qt(0,A,1),t=function(e,t,n,r){var a=t.x-e.x,i=t.y-e.y,o=Ht(e,t),s=a/o,l=i/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(P,S,A),a=Kc(P,S)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,a)}};u("source"),u("target"),this.applyLabelDimensions(e)}},Uc.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},Uc.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),a=qe(r,e._private.labelDimsKey);if(ht(n.rscratch,"prefixedLabelDimsKey",t)!==a){ft(n.rscratch,"prefixedLabelDimsKey",t,a);var i=this.calculateLabelDimensions(e,r),o=e.pstyle("line-height").pfValue,s=e.pstyle("text-wrap").strValue,l=ht(n.rscratch,"labelWrapCachedLines",t)||[],u="wrap"!==s?1:Math.max(l.length,1),c=i.height/u,d=c*o,h=i.width,f=i.height+(u-1)*(o-1)*c;ft(n.rstyle,"labelWidth",t,h),ft(n.rscratch,"labelWidth",t,h),ft(n.rstyle,"labelHeight",t,f),ft(n.rscratch,"labelHeight",t,f),ft(n.rscratch,"labelLineHeight",t,d)}},Uc.getLabelText=function(e,t){var n=e._private,a=t?t+"-":"",i=e.pstyle(a+"label").strValue,o=e.pstyle("text-transform").value,s=function(e,r){return r?(ft(n.rscratch,e,t,r),r):ht(n.rscratch,e,t)};if(!i)return"";"none"==o||("uppercase"==o?i=i.toUpperCase():"lowercase"==o&&(i=i.toLowerCase()));var l=e.pstyle("text-wrap").value;if("wrap"===l){var u=s("labelKey");if(null!=u&&s("labelWrapKey")===u)return s("labelWrapCachedText");for(var c=i.split("\n"),d=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,f=[],p=/[\s\u200b]+|$/g,v=0;vd){var b,x="",w=0,E=r(g.matchAll(p));try{for(E.s();!(b=E.n()).done;){var k=b.value,T=k[0],C=g.substring(w,k.index);w=k.index+T.length;var P=0===x.length?C:x+C+T;this.calculateLabelDimensions(e,P).width<=d?x+=C+T:(x&&f.push(x),x=C+T)}}catch(e){E.e(e)}finally{E.f()}x.match(/^[\s\u200b]+$/)||f.push(x)}else f.push(g)}s("labelWrapCachedLines",f),i=s("labelWrapCachedText",f.join("\n")),s("labelWrapKey",u)}else if("ellipsis"===l){var S=e.pstyle("text-max-width").pfValue,B="",D=!1;if(this.calculateLabelDimensions(e,i).widthS)break;B+=i[_],_===i.length-1&&(D=!0)}return D||(B+="…"),B}return i},Uc.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},Uc.calculateLabelDimensions=function(e,t){var n=this.cy.window().document,r=e.pstyle("font-style").strValue,a=e.pstyle("font-size").pfValue,i=e.pstyle("font-family").strValue,o=e.pstyle("font-weight").strValue,s=this.labelCalcCanvas,l=this.labelCalcCanvasContext;if(!s){s=this.labelCalcCanvas=n.createElement("canvas"),l=this.labelCalcCanvasContext=s.getContext("2d");var u=s.style;u.position="absolute",u.left="-9999px",u.top="-9999px",u.zIndex="-1",u.visibility="hidden",u.pointerEvents="none"}l.font="".concat(r," ").concat(o," ").concat(a,"px ").concat(i);for(var c=0,d=0,h=t.split("\n"),f=0;f1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r=e.desktopTapThreshold2}var P=a(t);g&&(e.hoverData.tapholdCancelled=!0);n=!0,r(v,["mousemove","vmousemove","tapdrag"],t,{x:c[0],y:c[1]});var S=function(e){return{originalEvent:t,type:e,position:{x:c[0],y:c[1]}}},B=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit(S("boxstart")),p[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(g){var D=S("cxtdrag");b?b.emit(D):o.emit(D),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&v===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit(S("cxtdragout")),e.hoverData.cxtOver=v,v&&v.emit(S("cxtdragover")))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var _;if(e.hoverData.justStartedPan){var A=e.hoverData.mdownPos;_={x:(c[0]-A[0])*s,y:(c[1]-A[1])*s},e.hoverData.justStartedPan=!1}else _={x:x[0]*s,y:x[1]*s};o.panBy(_),o.emit(S("dragpan")),e.hoverData.dragged=!0}c=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=p[4]||null!=b&&!b.pannable()){if(b&&b.pannable()&&b.active()&&b.unactivate(),b&&b.grabbed()||v==y||(y&&r(y,["mouseout","tapdragout"],t,{x:c[0],y:c[1]}),v&&r(v,["mouseover","tapdragover"],t,{x:c[0],y:c[1]}),e.hoverData.last=v),b)if(g){if(o.boxSelectionEnabled()&&P)b&&b.grabbed()&&(d(w),b.emit(S("freeon")),w.emit(S("free")),e.dragData.didDrag&&(b.emit(S("dragfreeon")),w.emit(S("dragfree")))),B();else if(b&&b.grabbed()&&e.nodeIsDraggable(b)){var M=!e.dragData.didDrag;M&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||u(w,{inDragLayer:!0});var R={x:0,y:0};if(G(x[0])&&G(x[1])&&(R.x+=x[0],R.y+=x[1],M)){var I=e.hoverData.dragDelta;I&&G(I[0])&&G(I[1])&&(R.x+=I[0],R.y+=I[1])}e.hoverData.draggingEles=!0,w.silentShift(R).emit(S("position")).emit(S("drag")),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(x[0]),t.push(x[1])):(t[0]+=x[0],t[1]+=x[1])}();n=!0}else if(g){if(e.hoverData.dragging||!o.boxSelectionEnabled()||!P&&o.panningEnabled()&&o.userPanningEnabled()){if(!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()){i(b,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,p[4]=0,e.data.bgActivePosistion=Yt(h),e.redrawHint("select",!0),e.redraw())}}else B();b&&b.pannable()&&b.active()&&b.unactivate()}return p[2]=c[0],p[3]=c[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if((1!==e.hoverData.which||1===t.which||!e.hoverData.capture)&&e.hoverData.capture){e.hoverData.capture=!1;var i=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=a(t);e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate();var f=function(e){return{originalEvent:t,type:e,position:{x:o[0],y:o[1]}}};if(3===e.hoverData.which){var p=f("cxttapend");if(c?c.emit(p):i.emit(p),!e.hoverData.cxtDragged){var v=f("cxttap");c?c.emit(v):i.emit(v)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=i.multiClickDebounceTime()?(b&&clearTimeout(b),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(b=setTimeout((function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),i.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||a(t)||(i.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=i.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===i.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(i.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var g=i.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),g.length>0&&e.redrawHint("eles",!0),i.emit(f("boxend"));var y=function(e){return e.selectable()&&!e.selected()};"additive"===i.selectionType()||h||i.$(n).unmerge(g).unselect(),g.emit(f("box")).stdFilter(y).select().emit(f("boxselect")),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var m=c&&c.grabbed();d(u),m&&(c.emit(f("freeon")),u.emit(f("free")),e.dragData.didDrag&&(c.emit(f("dragfreeon")),u.emit(f("dragfree"))))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null,e.hoverData.which=null}}),!1);var k,T,C,P,S,B,D,_,A,M,R,I,N,L,z=[],O=1e5,V=function(t){var n=!1,r=t.deltaY;if(null==r&&(null!=t.wheelDeltaY?r=t.wheelDeltaY/4:null!=t.wheelDelta&&(r=t.wheelDelta/4)),0!==r){if(null==k)if(z.length>=4){var a=z;if(k=function(e,t){for(var n=0;n5}if(k)for(var o=0;o5&&(r=5*Ut(r)),h=r/-250,k&&(h/=O,h*=3),h*=e.wheelSensitivity,1===t.deltaMode&&(h*=33);var f=s.zoom()*Math.pow(10,h);"gesturechange"===t.type&&(f=e.gestureStartZoom*t.scale),s.zoom({level:f,renderedPosition:{x:d[0],y:d[1]}}),s.emit({type:"gesturechange"===t.type?"pinchzoom":"scrollzoom",originalEvent:t,position:{x:c[0],y:c[1]}})}}}};e.registerBinding(e.container,"wheel",V,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||V(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var F,X,j,Y,q,W,U,H=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},K=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",F=function(t){if(e.hasTouchStarted=!0,m(t)){f(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,a=e.touchData.now,i=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);a[0]=o[0],a[1]=o[1]}if(t.touches[1]){o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);a[2]=o[0],a[3]=o[1]}if(t.touches[2]){o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);a[4]=o[0],a[5]=o[1]}var l=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}};if(t.touches[1]){e.touchData.singleTouchMoved=!0,d(e.dragData.touchDragEles);var h=e.findContainerClientCoords();M=h[0],R=h[1],I=h[2],N=h[3],T=t.touches[0].clientX-M,C=t.touches[0].clientY-R,P=t.touches[1].clientX-M,S=t.touches[1].clientY-R,L=0<=T&&T<=I&&0<=P&&P<=I&&0<=C&&C<=N&&0<=S&&S<=N;var p=n.pan(),v=n.zoom();B=H(T,C,P,S),D=K(T,C,P,S),A=[((_=[(T+P)/2,(C+S)/2])[0]-p.x)/v,(_[1]-p.y)/v];if(D<4e4&&!t.touches[2]){var g=e.findNearestElement(a[0],a[1],!0,!0),y=e.findNearestElement(a[2],a[3],!0,!0);return g&&g.isNode()?(g.activate().emit(l("cxttapstart")),e.touchData.start=g):y&&y.isNode()?(y.activate().emit(l("cxttapstart")),e.touchData.start=y):n.emit(l("cxttapstart")),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var b=e.findNearestElements(a[0],a[1],!0,!0),x=b[0];if(null!=x&&(x.activate(),e.touchData.start=x,e.touchData.starts=b,e.nodeIsGrabbable(x))){var w=e.dragData.touchDragEles=n.collection(),E=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),x.selected()?(E=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),u(E,{addToList:w})):c(x,{addToList:w}),s(x),x.emit(l("grabon")),E?E.forEach((function(e){e.emit(l("grab"))})):x.emit(l("grab"))}r(x,["touchstart","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==x&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:a[0],y:a[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var k=e.touchData.startPosition=[null,null,null,null,null,null],z=0;z=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var E=t.touches[0].clientX-M,k=t.touches[0].clientY-R,_=t.touches[1].clientX-M,I=t.touches[1].clientY-R,N=K(E,k,_,I);if(N/D>=2.25||N>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var z=p("cxttapend");e.touchData.start?(e.touchData.start.unactivate().emit(z),e.touchData.start=null):o.emit(z)}}if(n&&e.touchData.cxt){z=p("cxtdrag");e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(z):o.emit(z),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var O=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&O===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit(p("cxtdragout")),e.touchData.cxtOver=O,O&&O.emit(p("cxtdragover")))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit(p("boxstart")),e.touchData.selecting=!0,e.touchData.didSelect=!0,a[4]=1,a&&0!==a.length&&void 0!==a[0]?(a[2]=(s[0]+s[2]+s[4])/3,a[3]=(s[1]+s[3]+s[5])/3):(a[0]=(s[0]+s[2]+s[4])/3,a[1]=(s[1]+s[3]+s[5])/3,a[2]=(s[0]+s[2]+s[4])/3+1,a[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),te=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var V=0;V0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",j=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",Y=function(t){var a=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var i=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o=e.cy,s=o.zoom(),l=e.touchData.now,u=e.touchData.earlier;if(t.touches[0]){var c=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);l[0]=c[0],l[1]=c[1]}if(t.touches[1]){c=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);l[2]=c[0],l[3]=c[1]}if(t.touches[2]){c=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);l[4]=c[0],l[5]=c[1]}var h,f=function(e){return{originalEvent:t,type:e,position:{x:l[0],y:l[1]}}};if(a&&a.unactivate(),e.touchData.cxt){if(h=f("cxttapend"),a?a.emit(h):o.emit(h),!e.touchData.cxtDragged){var p=f("cxttap");a?a.emit(p):o.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&o.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var v=o.collection(e.getAllInBox(i[0],i[1],i[2],i[3]));i[0]=void 0,i[1]=void 0,i[2]=void 0,i[3]=void 0,i[4]=0,e.redrawHint("select",!0),o.emit(f("boxend"));v.emit(f("box")).stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit(f("boxselect")),v.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=a&&a.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var g=e.dragData.touchDragEles;if(null!=a){var y=a._private.grabbed;d(g),e.redrawHint("drag",!0),e.redrawHint("eles",!0),y&&(a.emit(f("freeon")),g.emit(f("free")),e.dragData.didDrag&&(a.emit(f("dragfreeon")),g.emit(f("dragfree")))),r(a,["touchend","tapend","vmouseup","tapdragout"],t,{x:l[0],y:l[1]}),a.unactivate(),e.touchData.start=null}else{var m=e.findNearestElement(l[0],l[1],!0,!0);r(m,["touchend","tapend","vmouseup","tapdragout"],t,{x:l[0],y:l[1]})}var b=e.touchData.startPosition[0]-l[0],x=b*b,w=e.touchData.startPosition[1]-l[1],E=(x+w*w)*s*s;e.touchData.singleTouchMoved||(a||o.$(":selected").unselect(["tapunselect"]),r(a,["tap","vclick"],t,{x:l[0],y:l[1]}),q=!1,t.timeStamp-U<=o.multiClickDebounceTime()?(W&&clearTimeout(W),q=!0,U=null,r(a,["dbltap","vdblclick"],t,{x:l[0],y:l[1]})):(W=setTimeout((function(){q||r(a,["onetap","voneclick"],t,{x:l[0],y:l[1]})}),o.multiClickDebounceTime()),U=t.timeStamp)),null!=a&&!e.dragData.didDrag&&a._private.selectable&&E2){for(var f=[c[0],c[1]],p=Math.pow(f[0]-e,2)+Math.pow(f[1]-t,2),v=1;v0)return v[0]}return null},f=Object.keys(d),p=0;p0?u:dn(a,i,e,t,n,r,o,s)},checkPoint:function(e,t,n,r,a,i,o,s){var l=2*(s="auto"===s?_n(r,a):s);if(yn(e,t,this.points,i,o,r,a-l,[0,-1],n))return!0;if(yn(e,t,this.points,i,o,r-l,a,[0,-1],n))return!0;var u=r/2+2*n,c=a/2+2*n;return!!gn(e,t,[i-u,o-c,i-u,o,i+u,o,i+u,o-c])||(!!xn(e,t,l,l,i+r/2-s,o+a/2-s,n)||!!xn(e,t,l,l,i-r/2+s,o+a/2-s,n))}}},nd.registerNodeShapes=function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",Sn(3,0)),this.generateRoundPolygon("round-triangle",Sn(3,0)),this.generatePolygon("rectangle",Sn(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",Sn(5,0)),this.generateRoundPolygon("round-pentagon",Sn(5,0)),this.generatePolygon("hexagon",Sn(6,0)),this.generateRoundPolygon("round-hexagon",Sn(6,0)),this.generatePolygon("heptagon",Sn(7,0)),this.generateRoundPolygon("round-heptagon",Sn(7,0)),this.generatePolygon("octagon",Sn(8,0)),this.generateRoundPolygon("round-octagon",Sn(8,0));var r=new Array(20),a=Dn(5,0),i=Dn(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s=e.deqFastCost*v)break}else if(a){if(f>=e.deqCost*l||f>=e.deqAvgCost*s)break}else if(p>=e.deqNoDrawCost*sd)break;var g=e.deq(t,d,c);if(!(g.length>0))break;for(var y=0;y0&&(e.onDeqd(t,u),!a&&e.shouldRedraw(t,u,d,c)&&r())}),a(t))}}},ud=function(){return n((function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Je;t(this,e),this.idsByKey=new pt,this.keyForId=new pt,this.cachesByLvl=new pt,this.lvls=[],this.getKey=n,this.doesEleInvalidateKey=r}),[{key:"getIdsFor",value:function(e){null==e&&nt("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new gt,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new pt,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}])}(),cd=7.99,dd={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},hd=ut({getKey:null,doesEleInvalidateKey:Je,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:Qe,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),fd=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=hd(t);ge(n,r),n.lookup=new ud(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},pd=fd.prototype;pd.reasons=dd,pd.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},pd.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},pd.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new St((function(e,t){return t.reqs-e.reqs}))},pd.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},pd.getElement=function(e,t,n,r,a){var i=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!i.allowEdgeTxrCaching&&e.isEdge()||!i.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(Wt(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,d=t.w*u,h=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,h))return null;var f,p=l.get(e,r);if(p&&p.invalidated&&(p.invalidated=!1,p.texture.invalidatedWidth-=p.width),p)return p;if(f=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||d>1024)return null;var v=i.getTextureQueue(f),g=v[v.length-2],y=function(){return i.recycleTexture(f,d)||i.addTexture(f,d)};g||(g=v[v.length-1]),g||(g=y()),g.width-g.usedWidthr;S--)C=i.getElement(e,t,n,S,dd.downscale);P()}else{var B;if(!x&&!w&&!E)for(var D=r-1;D>=-4;D--){var _=l.get(e,D);if(_){B=_;break}}if(b(B))return i.queueElement(e,r),B;g.context.translate(g.usedWidth,0),g.context.scale(u,u),this.drawElement(g.context,e,t,h,!1),g.context.scale(1/u,1/u),g.context.translate(-g.usedWidth,0)}return p={x:g.usedWidth,texture:g,level:r,scale:u,width:d,height:c,scaledLabelShown:h},g.usedWidth+=Math.ceil(d+8),g.eleCaches.push(p),l.set(e,r,p),i.checkTextureFullness(g),p},pd.invalidateElements=function(e){for(var t=0;t=.2*e.width&&this.retireTexture(e)},pd.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?ct(t,e):e.fullnessChecks++},pd.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;ct(n,e),e.retired=!0;for(var a=e.eleCaches,i=0;i=t)return i.retired=!1,i.usedWidth=0,i.invalidatedWidth=0,i.fullnessChecks=0,dt(i.eleCaches),i.context.setTransform(1,0,0,1,0,0),i.context.clearRect(0,0,i.width,i.height),ct(r,i),n.push(i),i}},pd.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),a=this.getKey(e),i=r[a];if(i)i.level=Math.max(i.level,t),i.eles.merge(e),i.reqs++,n.updateItem(i);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:a};n.push(o),r[a]=o}},pd.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),a=[],i=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=i.hasCache(u,s.level);if(r[l]=null,!c){a.push(s);var d=t.getBoundingBox(u);t.getElement(u,d,e,s.level,dd.dequeue)}}return a},pd.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),a=n[r];null!=a&&(1===a.eles.length?(a.reqs=$e,t.updateItem(a),t.pop(),n[r]=null):a.eles.unmerge(e))},pd.onDequeue=function(e){this.onDequeues.push(e)},pd.offDequeue=function(e){ct(this.onDequeues,e)},pd.setupDequeueing=ld({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},a=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};a(1),a(-1);for(var i=c.length-1;i>=0;i--){var o=c[i];o.invalid&&ct(c,o)}}();var d=function(t){var a=(t=t||{}).after;!function(){if(!o){o=Jt();for(var t=0;t32767||s>32767)return null;if(i*s>16e6)return null;var l=r.makeLayer(o,n);if(null!=a){var d=c.indexOf(a)+1;c.splice(d,0,l)}else(void 0===t.insert||t.insert)&&c.unshift(l);return l};if(r.skipping&&!i)return null;for(var h=null,f=e.length/1,p=!i,v=0;v=f||!ln(h.bb,g.boundingBox()))&&!(h=d({insert:!0,after:h})))return null;s||p?r.queueLayer(h,g):r.drawEleInLayer(h,g,n,t),h.eles.push(g),m[n]=h}}return s||(p?null:c)},gd.getEleLevelForLayerLevel=function(e,t){return e},gd.drawEleInLayer=function(e,t,n,r){var a=this.renderer,i=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),a.setImgSmoothing(i,!1),a.drawCachedElement(i,t,null,null,n,true),a.setImgSmoothing(i,!0))},gd.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,a=0;a0)return!1;if(i.invalid)return!1;r+=i.eles.length}return r===t.length},gd.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r0){e=!0;break}}return e},gd.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=Ne(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},gd.invalidateLayer=function(e){if(this.lastInvalidationTime=Ne(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];ct(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var a=0;a3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!i||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=i?t.pstyle("opacity").value:1,c=i?t.pstyle("line-opacity").value:1,d=t.pstyle("curve-style").value,h=t.pstyle("line-style").value,f=t.pstyle("width").pfValue,p=t.pstyle("line-cap").value,v=t.pstyle("line-outline-width").value,g=t.pstyle("line-outline-color").value,y=u*c,m=u*c,b=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;"straight-triangle"===d?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=f,e.lineCap=p,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")},x=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:m;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var w=t.pstyle("ghost-offset-x").pfValue,E=t.pstyle("ghost-offset-y").pfValue,k=t.pstyle("ghost-opacity").value,T=y*k;e.translate(w,E),b(T),x(T),e.translate(-w,-E)}else!function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;e.lineWidth=f+v,e.lineCap=p,v>0?(o.colorStrokeStyle(e,g[0],g[1],g[2],n),"straight-triangle"===d?o.drawEdgeTrianglePath(t,e,s.allpts):(o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")):e.lineCap="butt"}();a&&o.drawEdgeUnderlay(e,t),b(),x(),a&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},Id=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var a=this,i=a.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||i?t.lineCap="round":t.lineCap="butt",a.colorStrokeStyle(t,l[0],l[1],l[2],r),a.drawEdgePath(n,t,o.allpts,"solid")}}}};Rd.drawEdgeOverlay=Id("overlay"),Rd.drawEdgeUnderlay=Id("underlay"),Rd.drawEdgePath=function(e,t,n,a){var i,o=e._private.rscratch,s=t,l=!1,u=this.usePaths(),c=e.pstyle("line-dash-pattern").pfValue,d=e.pstyle("line-dash-offset").pfValue;if(u){var h=n.join("$");o.pathCacheKey&&o.pathCacheKey===h?(i=t=o.pathCache,l=!0):(i=t=new Path2D,o.pathCacheKey=h,o.pathCache=i)}if(s.setLineDash)switch(a){case"dotted":s.setLineDash([1,1]);break;case"dashed":s.setLineDash(c),s.lineDashOffset=d;break;case"solid":s.setLineDash([])}if(!l&&!o.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),o.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var f=2;f+35&&void 0!==arguments[5]?arguments[5]:5,o=Math.min(i,r/2,a/2);e.beginPath(),e.moveTo(t+o,n),e.lineTo(t+r-o,n),e.quadraticCurveTo(t+r,n,t+r,n+o),e.lineTo(t+r,n+a-o),e.quadraticCurveTo(t+r,n+a,t+r-o,n+a),e.lineTo(t+o,n+a),e.quadraticCurveTo(t,n+a,t,n+a-o),e.lineTo(t,n+o),e.quadraticCurveTo(t,n,t+o,n),e.closePath()}Ld.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),a=Math.ceil(Wt(n*r));t=Math.pow(2,a)}return!(e.pstyle("font-size").pfValue*t5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(i&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),d=t.pstyle("source-label"),h=t.pstyle("target-label");if(u||(!c||!c.value)&&(!d||!d.value)&&(!h||!h.value))return;e.textAlign="center",e.textBaseline="bottom"}var f,p=!n;n&&(f=n,e.translate(-f.x1,-f.y1)),null==a?(o.drawText(e,t,null,p,i),t.isEdge()&&(o.drawText(e,t,"source",p,i),o.drawText(e,t,"target",p,i))):o.drawText(e,t,a,p,i),n&&e.translate(f.x1,f.y1)},Ld.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,a=t.pstyle("font-size").pfValue+"px",i=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+a+" "+i,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Ld.getTextAngle=function(e,t){var n,r=e._private.rscratch,a=t?t+"-":"",i=e.pstyle(a+"text-rotation");if("autorotate"===i.strValue){var o=ht(r,"labelAngle",t);n=e.isEdge()?o:0}else n="none"===i.strValue?0:i.pfValue;return n},Ld.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=t._private.rscratch,o=a?t.effectiveOpacity():1;if(!a||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=ht(i,"labelX",n),c=ht(i,"labelY",n),d=this.getLabelText(t,n);if(null!=d&&""!==d&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,a);var h,f=n?n+"-":"",p=ht(i,"labelWidth",n),v=ht(i,"labelHeight",n),g=t.pstyle(f+"text-margin-x").pfValue,y=t.pstyle(f+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=g,c+=y,0!==(h=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(h),u=0,c=0),x){case"top":break;case"center":c+=v/2;break;case"bottom":c+=v}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,k=t.pstyle("text-border-width").pfValue,T=t.pstyle("text-background-padding").pfValue,C=t.pstyle("text-background-shape").strValue,P="round-rectangle"===C||"roundrectangle"===C,S="circle"===C;if(w>0||k>0&&E>0){var B=e.fillStyle,D=e.strokeStyle,_=e.lineWidth,A=t.pstyle("text-background-color").value,M=t.pstyle("text-border-color").value,R=t.pstyle("text-border-style").value,I=w>0,N=k>0&&E>0,L=u-T;switch(b){case"left":L-=p;break;case"center":L-=p/2}var z=c-v-T,O=p+2*T,V=v+2*T;if(I&&(e.fillStyle="rgba(".concat(A[0],",").concat(A[1],",").concat(A[2],",").concat(w*o,")")),N&&(e.strokeStyle="rgba(".concat(M[0],",").concat(M[1],",").concat(M[2],",").concat(E*o,")"),e.lineWidth=k,e.setLineDash))switch(R){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=k/4,e.setLineDash([]);break;default:e.setLineDash([])}if(P?(e.beginPath(),zd(e,L,z,O,V,2)):S?(e.beginPath(),function(e,t,n,r,a){var i=Math.min(r,a)/2,o=t+r/2,s=n+a/2;e.beginPath(),e.arc(o,s,i,0,2*Math.PI),e.closePath()}(e,L,z,O,V)):(e.beginPath(),e.rect(L,z,O,V)),I&&e.fill(),N&&e.stroke(),N&&"double"===R){var F=k/2;e.beginPath(),P?zd(e,L+F,z+F,O-2*F,V-2*F,2):e.rect(L+F,z+F,O-2*F,V-2*F),e.stroke()}e.fillStyle=B,e.strokeStyle=D,e.lineWidth=_,e.setLineDash&&e.setLineDash([])}var X=2*t.pstyle("text-outline-width").pfValue;if(X>0&&(e.lineWidth=X),"wrap"===t.pstyle("text-wrap").value){var j=ht(i,"labelWrapCachedLines",n),Y=ht(i,"labelLineHeight",n),q=p/2,W=this.getLabelJustification(t);switch("auto"===W||("left"===b?"left"===W?u+=-p:"center"===W&&(u+=-q):"center"===b?"left"===W?u+=-q:"right"===W&&(u+=q):"right"===b&&("center"===W?u+=q:"right"===W&&(u+=p))),x){case"top":case"center":case"bottom":c-=(j.length-1)*Y}for(var U=0;U0&&e.strokeText(j[U],u,c),e.fillText(j[U],u,c),c+=Y}else X>0&&e.strokeText(d,u,c),e.fillText(d,u,c);0!==h&&(e.rotate(-h),e.translate(-s,-l))}}};var Od={drawNode:function(e,t,n){var r,a,i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,d=t.position();if(G(d.x)&&G(d.y)&&(!s||t.visible())){var h,f,p=s?t.effectiveOpacity():1,v=l.usePaths(),g=!1,y=t.padding();r=t.width()+2*y,a=t.height()+2*y,n&&(f=n,e.translate(-f.x1,-f.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E0&&void 0!==arguments[0]?arguments[0]:S;l.eleFillStyle(e,t,n)},Y=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:N;l.colorStrokeStyle(e,B[0],B[1],B[2],t)},q=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:V;l.colorStrokeStyle(e,z[0],z[1],z[2],t)},W=function(e,t,n,r){var a,i=l.nodePathCache=l.nodePathCache||[],o=We("polygon"===n?n+","+r.join(","):n,""+t,""+e,""+X),s=i[o],u=!1;return null!=s?(a=s,u=!0,c.pathCache=a):(a=new Path2D,i[o]=c.pathCache=a),{path:a,cacheHit:u}},U=t.pstyle("shape").strValue,H=t.pstyle("shape-polygon-points").pfValue;if(v){e.translate(d.x,d.y);var K=W(r,a,U,H);h=K.path,g=K.cacheHit}var Z=function(){if(!g){var n=d;v&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(h||e,n.x,n.y,r,a,X,c)}v?e.fill(h):e.fill()},$=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:p,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=u.backgrounding,i=0,o=0;o0&&void 0!==arguments[0]&&arguments[0],i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;l.hasPie(t)&&(l.drawPie(e,t,i),n&&(v||l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c)))},J=function(){var n=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;l.hasStripe(t)&&(e.save(),v?e.clip(c.pathCache):(l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c),e.clip()),l.drawStripe(e,t,i),e.restore(),n&&(v||l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,X,c)))},ee=function(){var t=(C>0?C:-C)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:p),n=C>0?0:255;0!==C&&(l.colorFillStyle(e,n,n,n,t),v?e.fill(h):e.fill())},te=function(){if(P>0){if(e.lineWidth=P,e.lineCap=A,e.lineJoin=_,e.setLineDash)switch(D){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash(R),e.lineDashOffset=I;break;case"solid":case"double":e.setLineDash([])}if("center"!==M){if(e.save(),e.lineWidth*=2,"inside"===M)v?e.clip(h):e.clip();else{var t=new Path2D;t.rect(-r/2-P,-a/2-P,r+2*P,a+2*P),t.addPath(h),e.clip(t,"evenodd")}v?e.stroke(h):e.stroke(),e.restore()}else v?e.stroke(h):e.stroke();if("double"===D){e.lineWidth=P/3;var n=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",v?e.stroke(h):e.stroke(),e.globalCompositeOperation=n}e.setLineDash&&e.setLineDash([])}},ne=function(){if(L>0){if(e.lineWidth=L,e.lineCap="butt",e.setLineDash)switch(O){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var n=d;v&&(n={x:0,y:0});var i=l.getNodeShape(t),o=P;"inside"===M&&(o=0),"outside"===M&&(o*=2);var s,u=(r+o+(L+F))/r,c=(a+o+(L+F))/a,h=r*u,f=a*c,p=l.nodeShapes[i].points;if(v)s=W(h,f,i,p).path;if("ellipse"===i)l.drawEllipsePath(s||e,n.x,n.y,h,f);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(i)){var g=0,y=0,m=0;"round-diamond"===i?g=1.4*(o+F+L):"round-heptagon"===i?(g=1.075*(o+F+L),m=-(o/2+F+L)/35):"round-hexagon"===i?g=1.12*(o+F+L):"round-pentagon"===i?(g=1.13*(o+F+L),m=-(o/2+F+L)/15):"round-tag"===i?(g=1.12*(o+F+L),y=.07*(o/2+L+F)):"round-triangle"===i&&(g=(o+F+L)*(Math.PI/2),m=-(o+F/2+L)/Math.PI),0!==g&&(h=r*(u=(r+g)/r),["round-hexagon","round-tag"].includes(i)||(f=a*(c=(a+g)/a)));for(var b=h/2,x=f/2,w=(X="auto"===X?An(h,f):X)+(o+L+F)/2,E=new Array(p.length/2),k=new Array(p.length/2),T=0;T0){if(r=r||n.position(),null==a||null==i){var d=n.padding();a=n.width()+2*d,i=n.height()+2*d}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,a+2*o,i+2*o,c),t.fill()}}}};Od.drawNodeOverlay=Vd("overlay"),Od.drawNodeUnderlay=Vd("underlay"),Od.hasPie=function(e){return(e=e[0])._private.hasPie},Od.hasStripe=function(e){return(e=e[0])._private.hasStripe},Od.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var a,i=t.cy().style(),o=t.pstyle("pie-size"),s=t.pstyle("pie-hole"),l=t.pstyle("pie-start-angle").pfValue,u=r.x,c=r.y,d=t.width(),h=t.height(),f=Math.min(d,h)/2,p=0;if(this.usePaths()&&(u=0,c=0),"%"===o.units?f*=o.pfValue:void 0!==o.pfValue&&(f=o.pfValue/2),"%"===s.units?a=f*s.pfValue:void 0!==s.pfValue&&(a=s.pfValue/2),!(a>=f))for(var v=1;v<=i.pieBackgroundN;v++){var g=t.pstyle("pie-"+v+"-background-size").value,y=t.pstyle("pie-"+v+"-background-color").value,m=t.pstyle("pie-"+v+"-background-opacity").value*n,b=g/100;b+p>1&&(b=1-p);var x=1.5*Math.PI+2*Math.PI*p,w=(x+=l)+2*Math.PI*b;0===g||p>=1||p+b>1||(0===a?(e.beginPath(),e.moveTo(u,c),e.arc(u,c,f,x,w),e.closePath()):(e.beginPath(),e.arc(u,c,f,x,w),e.arc(u,c,a,w,x,!0),e.closePath()),this.colorFillStyle(e,y[0],y[1],y[2],m),e.fill(),p+=b)}},Od.drawStripe=function(e,t,n,r){t=t[0],r=r||t.position();var a=t.cy().style(),i=r.x,o=r.y,s=t.width(),l=t.height(),u=0,c=this.usePaths();e.save();var d=t.pstyle("stripe-direction").value,h=t.pstyle("stripe-size");switch(d){case"vertical":break;case"righward":e.rotate(-Math.PI/2)}var f=s,p=l;"%"===h.units?(f*=h.pfValue,p*=h.pfValue):void 0!==h.pfValue&&(f=h.pfValue,p=h.pfValue),c&&(i=0,o=0),o-=f/2,i-=p/2;for(var v=1;v<=a.stripeBackgroundN;v++){var g=t.pstyle("stripe-"+v+"-background-size").value,y=t.pstyle("stripe-"+v+"-background-color").value,m=t.pstyle("stripe-"+v+"-background-opacity").value*n,b=g/100;b+u>1&&(b=1-u),0===g||u>=1||u+b>1||(e.beginPath(),e.rect(i,o+p*u,f,p*b),e.closePath(),this.colorFillStyle(e,y[0],y[1],y[2],m),e.fill(),u+=b)}e.restore()};var Fd,Xd={};function jd(e,t,n){var r=e.createShader(t);if(e.shaderSource(r,n),e.compileShader(r),!e.getShaderParameter(r,e.COMPILE_STATUS))throw new Error(e.getShaderInfoLog(r));return r}function Yd(e,t,n){void 0===n&&(n=t);var r=e.makeOffscreenCanvas(t,n),a=r.context=r.getContext("2d");return r.clear=function(){return a.clearRect(0,0,r.width,r.height)},r.clear(),r}function qd(e){var t=e.pixelRatio,n=e.cy.zoom(),r=e.cy.pan();return{zoom:n*t,pan:{x:r.x*t,y:r.y*t}}}function Wd(e){return"solid"===e.pstyle("background-fill").value&&("none"===e.pstyle("background-image").strValue&&(0===e.pstyle("border-width").value||(0===e.pstyle("border-opacity").value||"solid"===e.pstyle("border-style").value)))}function Ud(e,t){if(e.length!==t.length)return!1;for(var n=0;n>8&255)/255,n[2]=(e>>16&255)/255,n[3]=(e>>24&255)/255,n}function Gd(e){return e[0]+(e[1]<<8)+(e[2]<<16)+(e[3]<<24)}function Zd(e,t){switch(t){case"float":return[1,e.FLOAT,4];case"vec2":return[2,e.FLOAT,4];case"vec3":return[3,e.FLOAT,4];case"vec4":return[4,e.FLOAT,4];case"int":return[1,e.INT,4];case"ivec2":return[2,e.INT,4]}}function $d(e,t,n){switch(t){case e.FLOAT:return new Float32Array(n);case e.INT:return new Int32Array(n)}}function Qd(e,t,n,r,a,i){switch(t){case e.FLOAT:return new Float32Array(n.buffer,i*r,a);case e.INT:return new Int32Array(n.buffer,i*r,a)}}function Jd(e,t,n,r){var a=i(Zd(e,n),3),o=a[0],s=a[1],l=a[2],u=$d(e,s,t*o),c=o*l,d=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,d),e.bufferData(e.ARRAY_BUFFER,t*c,e.DYNAMIC_DRAW),e.enableVertexAttribArray(r),s===e.FLOAT?e.vertexAttribPointer(r,o,s,!1,c,0):s===e.INT&&e.vertexAttribIPointer(r,o,s,c,0),e.vertexAttribDivisor(r,1),e.bindBuffer(e.ARRAY_BUFFER,null);for(var h=new Array(t),f=0;ft.minMbLowQualFrames&&(t.motionBlurPxRatio=t.mbPxRBlurry)),t.clearingMotionBlur&&(t.motionBlurPxRatio=1),t.textureDrawLastFrame&&!d&&(c[t.NODE]=!0,c[t.SELECT_BOX]=!0);var m=n.style(),b=n.zoom(),x=void 0!==o?o:b,w=n.pan(),E={x:w.x,y:w.y},k={zoom:b,pan:{x:w.x,y:w.y}},T=t.prevViewport;void 0===T||k.zoom!==T.zoom||k.pan.x!==T.pan.x||k.pan.y!==T.pan.y||v&&!p||(t.motionBlurPxRatio=1),s&&(E=s),x*=l,E.x*=l,E.y*=l;var C=t.getCachedZSortedEles();function P(e,n,r,a,i){var o=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",t.colorFillStyle(e,255,255,255,t.motionBlurTransparency),e.fillRect(n,r,a,i),e.globalCompositeOperation=o}function S(e,n){var i,l,c,d;t.clearingMotionBlur||e!==u.bufferContexts[t.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[t.MOTIONBLUR_BUFFER_DRAG]?(i=E,l=x,c=t.canvasWidth,d=t.canvasHeight):(i={x:w.x*f,y:w.y*f},l=b*f,c=t.canvasWidth*f,d=t.canvasHeight*f),e.setTransform(1,0,0,1,0,0),"motionBlur"===n?P(e,0,0,c,d):r||void 0!==n&&!n||e.clearRect(0,0,c,d),a||(e.translate(i.x,i.y),e.scale(l,l)),s&&e.translate(s.x,s.y),o&&e.scale(o,o)}if(d||(t.textureDrawLastFrame=!1),d){if(t.textureDrawLastFrame=!0,!t.textureCache){t.textureCache={},t.textureCache.bb=n.mutableElements().boundingBox(),t.textureCache.texture=t.data.bufferCanvases[t.TEXTURE_BUFFER];var B=t.data.bufferContexts[t.TEXTURE_BUFFER];B.setTransform(1,0,0,1,0,0),B.clearRect(0,0,t.canvasWidth*t.textureMult,t.canvasHeight*t.textureMult),t.render({forcedContext:B,drawOnlyNodeLayer:!0,forcedPxRatio:l*t.textureMult}),(k=t.textureCache.viewport={zoom:n.zoom(),pan:n.pan(),width:t.canvasWidth,height:t.canvasHeight}).mpan={x:(0-k.pan.x)/k.zoom,y:(0-k.pan.y)/k.zoom}}c[t.DRAG]=!1,c[t.NODE]=!1;var D=u.contexts[t.NODE],_=t.textureCache.texture;k=t.textureCache.viewport;D.setTransform(1,0,0,1,0,0),h?P(D,0,0,k.width,k.height):D.clearRect(0,0,k.width,k.height);var A=m.core("outside-texture-bg-color").value,M=m.core("outside-texture-bg-opacity").value;t.colorFillStyle(D,A[0],A[1],A[2],M),D.fillRect(0,0,k.width,k.height);b=n.zoom();S(D,!1),D.clearRect(k.mpan.x,k.mpan.y,k.width/k.zoom/l,k.height/k.zoom/l),D.drawImage(_,k.mpan.x,k.mpan.y,k.width/k.zoom/l,k.height/k.zoom/l)}else t.textureOnViewport&&!r&&(t.textureCache=null);var R=n.extent(),I=t.pinching||t.hoverData.dragging||t.swipePanning||t.data.wheelZooming||t.hoverData.draggingEles||t.cy.animated(),N=t.hideEdgesOnViewport&&I,L=[];if(L[t.NODE]=!c[t.NODE]&&h&&!t.clearedForMotionBlur[t.NODE]||t.clearingMotionBlur,L[t.NODE]&&(t.clearedForMotionBlur[t.NODE]=!0),L[t.DRAG]=!c[t.DRAG]&&h&&!t.clearedForMotionBlur[t.DRAG]||t.clearingMotionBlur,L[t.DRAG]&&(t.clearedForMotionBlur[t.DRAG]=!0),c[t.NODE]||a||i||L[t.NODE]){var z=h&&!L[t.NODE]&&1!==f;S(D=r||(z?t.data.bufferContexts[t.MOTIONBLUR_BUFFER_NODE]:u.contexts[t.NODE]),h&&!z?"motionBlur":void 0),N?t.drawCachedNodes(D,C.nondrag,l,R):t.drawLayeredElements(D,C.nondrag,l,R),t.debug&&t.drawDebugPoints(D,C.nondrag),a||h||(c[t.NODE]=!1)}if(!i&&(c[t.DRAG]||a||L[t.DRAG])){z=h&&!L[t.DRAG]&&1!==f;S(D=r||(z?t.data.bufferContexts[t.MOTIONBLUR_BUFFER_DRAG]:u.contexts[t.DRAG]),h&&!z?"motionBlur":void 0),N?t.drawCachedNodes(D,C.drag,l,R):t.drawCachedElements(D,C.drag,l,R),t.debug&&t.drawDebugPoints(D,C.drag),a||h||(c[t.DRAG]=!1)}if(this.drawSelectionRectangle(e,S),h&&1!==f){var O=u.contexts[t.NODE],V=t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE],F=u.contexts[t.DRAG],X=t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG],j=function(e,n,r){e.setTransform(1,0,0,1,0,0),r||!y?e.clearRect(0,0,t.canvasWidth,t.canvasHeight):P(e,0,0,t.canvasWidth,t.canvasHeight);var a=f;e.drawImage(n,0,0,t.canvasWidth*a,t.canvasHeight*a,0,0,t.canvasWidth,t.canvasHeight)};(c[t.NODE]||L[t.NODE])&&(j(O,V,L[t.NODE]),c[t.NODE]=!1),(c[t.DRAG]||L[t.DRAG])&&(j(F,X,L[t.DRAG]),c[t.DRAG]=!1)}t.prevViewport=k,t.clearingMotionBlur&&(t.clearingMotionBlur=!1,t.motionBlurCleared=!0,t.motionBlur=!0),h&&(t.motionBlurTimeout=setTimeout((function(){t.motionBlurTimeout=null,t.clearedForMotionBlur[t.NODE]=!1,t.clearedForMotionBlur[t.DRAG]=!1,t.motionBlur=!1,t.clearingMotionBlur=!d,t.mbFrames=0,c[t.NODE]=!0,c[t.DRAG]=!0,t.redraw()}),100)),r||n.emit("render")},Xd.drawSelectionRectangle=function(e,t){var n=this,r=n.cy,a=n.data,i=r.style(),o=e.drawOnlyNodeLayer,s=e.drawAllLayers,l=a.canvasNeedsRedraw,u=e.forcedContext;if(n.showFps||!o&&l[n.SELECT_BOX]&&!s){var c=u||a.contexts[n.SELECT_BOX];if(t(c),1==n.selection[4]&&(n.hoverData.selecting||n.touchData.selecting)){var d=n.cy.zoom(),h=i.core("selection-box-border-width").value/d;c.lineWidth=h,c.fillStyle="rgba("+i.core("selection-box-color").value[0]+","+i.core("selection-box-color").value[1]+","+i.core("selection-box-color").value[2]+","+i.core("selection-box-opacity").value+")",c.fillRect(n.selection[0],n.selection[1],n.selection[2]-n.selection[0],n.selection[3]-n.selection[1]),h>0&&(c.strokeStyle="rgba("+i.core("selection-box-border-color").value[0]+","+i.core("selection-box-border-color").value[1]+","+i.core("selection-box-border-color").value[2]+","+i.core("selection-box-opacity").value+")",c.strokeRect(n.selection[0],n.selection[1],n.selection[2]-n.selection[0],n.selection[3]-n.selection[1]))}if(a.bgActivePosistion&&!n.hoverData.selecting){d=n.cy.zoom();var f=a.bgActivePosistion;c.fillStyle="rgba("+i.core("active-bg-color").value[0]+","+i.core("active-bg-color").value[1]+","+i.core("active-bg-color").value[2]+","+i.core("active-bg-opacity").value+")",c.beginPath(),c.arc(f.x,f.y,i.core("active-bg-size").pfValue/d,0,2*Math.PI),c.fill()}var p=n.lastRedrawTime;if(n.showFps&&p){p=Math.round(p);var v=Math.round(1e3/p),g="1 frame = "+p+" ms = "+v+" fps";if(c.setTransform(1,0,0,1,0,0),c.fillStyle="rgba(255, 0, 0, 0.75)",c.strokeStyle="rgba(255, 0, 0, 0.75)",c.font="30px Arial",!Fd){var y=c.measureText(g);Fd=y.actualBoundingBoxAscent}c.fillText(g,0,Fd);c.strokeRect(0,Fd+10,250,20),c.fillRect(0,Fd+10,250*Math.min(v/60,1),20)}s||(l[n.SELECT_BOX]=!1)}};var eh="undefined"!=typeof Float32Array?Float32Array:Array;function th(){var e=new eh(9);return eh!=Float32Array&&(e[1]=0,e[2]=0,e[3]=0,e[5]=0,e[6]=0,e[7]=0),e[0]=1,e[4]=1,e[8]=1,e}function nh(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=1,e[5]=0,e[6]=0,e[7]=0,e[8]=1,e}function rh(e,t,n){var r=t[0],a=t[1],i=t[2],o=t[3],s=t[4],l=t[5],u=t[6],c=t[7],d=t[8],h=n[0],f=n[1];return e[0]=r,e[1]=a,e[2]=i,e[3]=o,e[4]=s,e[5]=l,e[6]=h*r+f*o+u,e[7]=h*a+f*s+c,e[8]=h*i+f*l+d,e}function ah(e,t,n){var r=t[0],a=t[1],i=t[2],o=t[3],s=t[4],l=t[5],u=t[6],c=t[7],d=t[8],h=Math.sin(n),f=Math.cos(n);return e[0]=f*r+h*o,e[1]=f*a+h*s,e[2]=f*i+h*l,e[3]=f*o-h*r,e[4]=f*s-h*a,e[5]=f*l-h*i,e[6]=u,e[7]=c,e[8]=d,e}function ih(e,t,n){var r=n[0],a=n[1];return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=a*t[3],e[4]=a*t[4],e[5]=a*t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e}Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});var oh=function(){return n((function e(n,r,a,i){t(this,e),this.debugID=Math.floor(1e4*Math.random()),this.r=n,this.texSize=r,this.texRows=a,this.texHeight=Math.floor(r/a),this.enableWrapping=!0,this.locked=!1,this.texture=null,this.needsBuffer=!0,this.freePointer={x:0,row:0},this.keyToLocation=new Map,this.canvas=i(n,r,r),this.scratch=i(n,r,this.texHeight,"scratch")}),[{key:"lock",value:function(){this.locked=!0}},{key:"getKeys",value:function(){return new Set(this.keyToLocation.keys())}},{key:"getScale",value:function(e){var t=e.w,n=e.h,r=this.texHeight,a=this.texSize,i=r/n,o=t*i,s=n*i;return o>a&&(o=t*(i=a/t),s=n*i),{scale:i,texW:o,texH:s}}},{key:"draw",value:function(e,t,n){var r=this;if(this.locked)throw new Error("can't draw, atlas is locked");var a=this.texSize,i=this.texRows,o=this.texHeight,s=this.getScale(t),l=s.scale,u=s.texW,c=s.texH,d=function(e,r){if(n&&r){var a=r.context,i=e.x,s=e.row,u=i,c=o*s;a.save(),a.translate(u,c),a.scale(l,l),n(a,t),a.restore()}},h=[null,null],f=function(){d(r.freePointer,r.canvas),h[0]={x:r.freePointer.x,y:r.freePointer.row*o,w:u,h:c},h[1]={x:r.freePointer.x+u,y:r.freePointer.row*o,w:0,h:c},r.freePointer.x+=u,r.freePointer.x==a&&(r.freePointer.x=0,r.freePointer.row++)},p=function(){r.freePointer.x=0,r.freePointer.row++};if(this.freePointer.x+u<=a)f();else{if(this.freePointer.row>=i-1)return!1;this.freePointer.x===a?(p(),f()):this.enableWrapping?function(){var e=r.scratch,t=r.canvas;e.clear(),d({x:0,row:0},e);var n=a-r.freePointer.x,i=u-n,s=o,l=r.freePointer.x,f=r.freePointer.row*o,p=n;t.context.drawImage(e,0,0,p,s,l,f,p,s),h[0]={x:l,y:f,w:p,h:c};var v=n,g=(r.freePointer.row+1)*o,y=i;t&&t.context.drawImage(e,v,0,y,s,0,g,y,s),h[1]={x:0,y:g,w:y,h:c},r.freePointer.x=i,r.freePointer.row++}():(p(),f())}return this.keyToLocation.set(e,h),this.needsBuffer=!0,h}},{key:"getOffsets",value:function(e){return this.keyToLocation.get(e)}},{key:"isEmpty",value:function(){return 0===this.freePointer.x&&0===this.freePointer.row}},{key:"canFit",value:function(e){if(this.locked)return!1;var t=this.texSize,n=this.texRows,r=this.getScale(e).texW;return!(this.freePointer.x+r>t)||this.freePointer.row1&&void 0!==arguments[1]?arguments[1]:{},i=a.forceRedraw,o=void 0!==i&&i,s=a.filterEle,l=void 0===s?function(){return!0}:s,u=a.filterType,c=void 0===u?function(){return!0}:u,d=!1,h=!1,f=r(e);try{for(f.s();!(t=f.n()).done;){var p=t.value;if(l(p)){var v,g=r(this.renderTypes.values());try{var y=function(){var e=v.value,t=e.type;if(c(t)){var r=n.collections.get(e.collection),a=e.getKey(p),i=Array.isArray(a)?a:[a];if(o)i.forEach((function(e){return r.markKeyForGC(e)})),h=!0;else{var s=e.getID?e.getID(p):p.id(),l=n._key(t,s),u=n.typeAndIdToKey.get(l);void 0===u||Ud(i,u)||(d=!0,n.typeAndIdToKey.delete(l),u.forEach((function(e){return r.markKeyForGC(e)})))}}};for(g.s();!(v=g.n()).done;)y()}catch(e){g.e(e)}finally{g.f()}}}}catch(e){f.e(e)}finally{f.f()}return h&&(this.gc(),d=!1),d}},{key:"gc",value:function(){var e,t=r(this.collections.values());try{for(t.s();!(e=t.n()).done;){e.value.gc()}}catch(e){t.e(e)}finally{t.f()}}},{key:"getOrCreateAtlas",value:function(e,t,n,r){var a=this.renderTypes.get(t),i=this.collections.get(a.collection),o=!1,s=i.draw(r,n,(function(t){a.drawClipped?(t.save(),t.beginPath(),t.rect(0,0,n.w,n.h),t.clip(),a.drawElement(t,e,n,!0,!0),t.restore()):a.drawElement(t,e,n,!0,!0),o=!0}));if(o){var l=a.getID?a.getID(e):e.id(),u=this._key(t,l);this.typeAndIdToKey.has(u)?this.typeAndIdToKey.get(u).push(r):this.typeAndIdToKey.set(u,[r])}return s}},{key:"getAtlasInfo",value:function(e,t){var n=this,r=this.renderTypes.get(t),a=r.getKey(e);return(Array.isArray(a)?a:[a]).map((function(a){var o=r.getBoundingBox(e,a),s=n.getOrCreateAtlas(e,t,o,a),l=i(s.getOffsets(a),2),u=l[0];return{atlas:s,tex:u,tex1:u,tex2:l[1],bb:o}}))}},{key:"getDebugInfo",value:function(){var e,t=[],n=r(this.collections);try{for(n.s();!(e=n.n()).done;){var a=i(e.value,2),o=a[0],s=a[1].getCounts(),l=s.keyCount,u=s.atlasCount;t.push({type:o,keyCount:l,atlasCount:u})}}catch(e){n.e(e)}finally{n.f()}return t}}])}(),uh=function(){return n((function e(n){t(this,e),this.globalOptions=n,this.atlasSize=n.webglTexSize,this.maxAtlasesPerBatch=n.webglTexPerBatch,this.batchAtlases=[]}),[{key:"getMaxAtlasesPerBatch",value:function(){return this.maxAtlasesPerBatch}},{key:"getAtlasSize",value:function(){return this.atlasSize}},{key:"getIndexArray",value:function(){return Array.from({length:this.maxAtlasesPerBatch},(function(e,t){return t}))}},{key:"startBatch",value:function(){this.batchAtlases=[]}},{key:"getAtlasCount",value:function(){return this.batchAtlases.length}},{key:"getAtlases",value:function(){return this.batchAtlases}},{key:"canAddToCurrentBatch",value:function(e){return this.batchAtlases.length!==this.maxAtlasesPerBatch||this.batchAtlases.includes(e)}},{key:"getAtlasIndexForBatch",value:function(e){var t=this.batchAtlases.indexOf(e);if(t<0){if(this.batchAtlases.length===this.maxAtlasesPerBatch)throw new Error("cannot add more atlases to batch");this.batchAtlases.push(e),t=this.batchAtlases.length-1}return t}}])}(),ch={SCREEN:{name:"screen",screen:!0},PICKING:{name:"picking",picking:!0}},dh=1,hh=2,fh=function(){return n((function e(n,r,a){t(this,e),this.r=n,this.gl=r,this.maxInstances=a.webglBatchSize,this.atlasSize=a.webglTexSize,this.bgColor=a.bgColor,this.debug=a.webglDebug,this.batchDebugInfo=[],a.enableWrapping=!0,a.createTextureCanvas=Yd,this.atlasManager=new lh(n,a),this.batchManager=new uh(a),this.simpleShapeOptions=new Map,this.program=this._createShaderProgram(ch.SCREEN),this.pickingProgram=this._createShaderProgram(ch.PICKING),this.vao=this._createVAO()}),[{key:"addAtlasCollection",value:function(e,t){this.atlasManager.addAtlasCollection(e,t)}},{key:"addTextureAtlasRenderType",value:function(e,t){this.atlasManager.addRenderType(e,t)}},{key:"addSimpleShapeRenderType",value:function(e,t){this.simpleShapeOptions.set(e,t)}},{key:"invalidate",value:function(e){var t=(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}).type,n=this.atlasManager;return t?n.invalidate(e,{filterType:function(e){return e===t},forceRedraw:!0}):n.invalidate(e)}},{key:"gc",value:function(){this.atlasManager.gc()}},{key:"_createShaderProgram",value:function(e){var t=this.gl,n="#version 300 es\n precision highp float;\n\n uniform mat3 uPanZoomMatrix;\n uniform int uAtlasSize;\n \n // instanced\n in vec2 aPosition; // a vertex from the unit square\n \n in mat3 aTransform; // used to transform verticies, eg into a bounding box\n in int aVertType; // the type of thing we are rendering\n\n // the z-index that is output when using picking mode\n in vec4 aIndex;\n \n // For textures\n in int aAtlasId; // which shader unit/atlas to use\n in vec4 aTex; // x/y/w/h of texture in atlas\n\n // for edges\n in vec4 aPointAPointB;\n in vec4 aPointCPointD;\n in vec2 aLineWidth; // also used for node border width\n\n // simple shapes\n in vec4 aCornerRadius; // for round-rectangle [top-right, bottom-right, top-left, bottom-left]\n in vec4 aColor; // also used for edges\n in vec4 aBorderColor; // aLineWidth is used for border width\n\n // output values passed to the fragment shader\n out vec2 vTexCoord;\n out vec4 vColor;\n out vec2 vPosition;\n // flat values are not interpolated\n flat out int vAtlasId; \n flat out int vVertType;\n flat out vec2 vTopRight;\n flat out vec2 vBotLeft;\n flat out vec4 vCornerRadius;\n flat out vec4 vBorderColor;\n flat out vec2 vBorderWidth;\n flat out vec4 vIndex;\n \n void main(void) {\n int vid = gl_VertexID;\n vec2 position = aPosition; // TODO make this a vec3, simplifies some code below\n\n if(aVertType == ".concat(0,") {\n float texX = aTex.x; // texture coordinates\n float texY = aTex.y;\n float texW = aTex.z;\n float texH = aTex.w;\n\n if(vid == 1 || vid == 2 || vid == 4) {\n texX += texW;\n }\n if(vid == 2 || vid == 4 || vid == 5) {\n texY += texH;\n }\n\n float d = float(uAtlasSize);\n vTexCoord = vec2(texX / d, texY / d); // tex coords must be between 0 and 1\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n }\n else if(aVertType == ").concat(4," || aVertType == ").concat(7," \n || aVertType == ").concat(5," || aVertType == ").concat(6,") { // simple shapes\n\n // the bounding box is needed by the fragment shader\n vBotLeft = (aTransform * vec3(0, 0, 1)).xy; // flat\n vTopRight = (aTransform * vec3(1, 1, 1)).xy; // flat\n vPosition = (aTransform * vec3(position, 1)).xy; // will be interpolated\n\n // calculations are done in the fragment shader, just pass these along\n vColor = aColor;\n vCornerRadius = aCornerRadius;\n vBorderColor = aBorderColor;\n vBorderWidth = aLineWidth;\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n }\n else if(aVertType == ").concat(1,") {\n vec2 source = aPointAPointB.xy;\n vec2 target = aPointAPointB.zw;\n\n // adjust the geometry so that the line is centered on the edge\n position.y = position.y - 0.5;\n\n // stretch the unit square into a long skinny rectangle\n vec2 xBasis = target - source;\n vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));\n vec2 point = source + xBasis * position.x + yBasis * aLineWidth[0] * position.y;\n\n gl_Position = vec4(uPanZoomMatrix * vec3(point, 1.0), 1.0);\n vColor = aColor;\n } \n else if(aVertType == ").concat(2,") {\n vec2 pointA = aPointAPointB.xy;\n vec2 pointB = aPointAPointB.zw;\n vec2 pointC = aPointCPointD.xy;\n vec2 pointD = aPointCPointD.zw;\n\n // adjust the geometry so that the line is centered on the edge\n position.y = position.y - 0.5;\n\n vec2 p0, p1, p2, pos;\n if(position.x == 0.0) { // The left side of the unit square\n p0 = pointA;\n p1 = pointB;\n p2 = pointC;\n pos = position;\n } else { // The right side of the unit square, use same approach but flip the geometry upside down\n p0 = pointD;\n p1 = pointC;\n p2 = pointB;\n pos = vec2(0.0, -position.y);\n }\n\n vec2 p01 = p1 - p0;\n vec2 p12 = p2 - p1;\n vec2 p21 = p1 - p2;\n\n // Find the normal vector.\n vec2 tangent = normalize(normalize(p12) + normalize(p01));\n vec2 normal = vec2(-tangent.y, tangent.x);\n\n // Find the vector perpendicular to p0 -> p1.\n vec2 p01Norm = normalize(vec2(-p01.y, p01.x));\n\n // Determine the bend direction.\n float sigma = sign(dot(p01 + p21, normal));\n float width = aLineWidth[0];\n\n if(sign(pos.y) == -sigma) {\n // This is an intersecting vertex. Adjust the position so that there's no overlap.\n vec2 point = 0.5 * width * normal * -sigma / dot(normal, p01Norm);\n gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);\n } else {\n // This is a non-intersecting vertex. Treat it like a mitre join.\n vec2 point = 0.5 * width * normal * sigma * dot(normal, p01Norm);\n gl_Position = vec4(uPanZoomMatrix * vec3(p1 + point, 1.0), 1.0);\n }\n\n vColor = aColor;\n } \n else if(aVertType == ").concat(3," && vid < 3) {\n // massage the first triangle into an edge arrow\n if(vid == 0)\n position = vec2(-0.15, -0.3);\n if(vid == 1)\n position = vec2( 0.0, 0.0);\n if(vid == 2)\n position = vec2( 0.15, -0.3);\n\n gl_Position = vec4(uPanZoomMatrix * aTransform * vec3(position, 1.0), 1.0);\n vColor = aColor;\n }\n else {\n gl_Position = vec4(2.0, 0.0, 0.0, 1.0); // discard vertex by putting it outside webgl clip space\n }\n\n vAtlasId = aAtlasId;\n vVertType = aVertType;\n vIndex = aIndex;\n }\n "),r=this.batchManager.getIndexArray(),a="#version 300 es\n precision highp float;\n\n // declare texture unit for each texture atlas in the batch\n ".concat(r.map((function(e){return"uniform sampler2D uTexture".concat(e,";")})).join("\n\t"),"\n\n uniform vec4 uBGColor;\n uniform float uZoom;\n\n in vec2 vTexCoord;\n in vec4 vColor;\n in vec2 vPosition; // model coordinates\n\n flat in int vAtlasId;\n flat in vec4 vIndex;\n flat in int vVertType;\n flat in vec2 vTopRight;\n flat in vec2 vBotLeft;\n flat in vec4 vCornerRadius;\n flat in vec4 vBorderColor;\n flat in vec2 vBorderWidth;\n\n out vec4 outColor;\n\n ").concat("\n float circleSD(vec2 p, float r) {\n return distance(vec2(0), p) - r; // signed distance\n }\n","\n ").concat("\n float rectangleSD(vec2 p, vec2 b) {\n vec2 d = abs(p)-b;\n return distance(vec2(0),max(d,0.0)) + min(max(d.x,d.y),0.0);\n }\n","\n ").concat("\n float roundRectangleSD(vec2 p, vec2 b, vec4 cr) {\n cr.xy = (p.x > 0.0) ? cr.xy : cr.zw;\n cr.x = (p.y > 0.0) ? cr.x : cr.y;\n vec2 q = abs(p) - b + cr.x;\n return min(max(q.x, q.y), 0.0) + distance(vec2(0), max(q, 0.0)) - cr.x;\n }\n","\n ").concat("\n float ellipseSD(vec2 p, vec2 ab) {\n p = abs( p ); // symmetry\n\n // find root with Newton solver\n vec2 q = ab*(p-ab);\n float w = (q.x1.0) ? d : -d;\n }\n","\n\n vec4 blend(vec4 top, vec4 bot) { // blend colors with premultiplied alpha\n return vec4( \n top.rgb + (bot.rgb * (1.0 - top.a)),\n top.a + (bot.a * (1.0 - top.a)) \n );\n }\n\n vec4 distInterp(vec4 cA, vec4 cB, float d) { // interpolate color using Signed Distance\n // scale to the zoom level so that borders don't look blurry when zoomed in\n // note 1.5 is an aribitrary value chosen because it looks good\n return mix(cA, cB, 1.0 - smoothstep(0.0, 1.5 / uZoom, abs(d))); \n }\n\n void main(void) {\n if(vVertType == ").concat(0,") {\n // look up the texel from the texture unit\n ").concat(r.map((function(e){return"if(vAtlasId == ".concat(e,") outColor = texture(uTexture").concat(e,", vTexCoord);")})).join("\n\telse "),"\n } \n else if(vVertType == ").concat(3,") {\n // mimics how canvas renderer uses context.globalCompositeOperation = 'destination-out';\n outColor = blend(vColor, uBGColor);\n outColor.a = 1.0; // make opaque, masks out line under arrow\n }\n else if(vVertType == ").concat(4," && vBorderWidth == vec2(0.0)) { // simple rectangle with no border\n outColor = vColor; // unit square is already transformed to the rectangle, nothing else needs to be done\n }\n else if(vVertType == ").concat(4," || vVertType == ").concat(7," \n || vVertType == ").concat(5," || vVertType == ").concat(6,") { // use SDF\n\n float outerBorder = vBorderWidth[0];\n float innerBorder = vBorderWidth[1];\n float borderPadding = outerBorder * 2.0;\n float w = vTopRight.x - vBotLeft.x - borderPadding;\n float h = vTopRight.y - vBotLeft.y - borderPadding;\n vec2 b = vec2(w/2.0, h/2.0); // half width, half height\n vec2 p = vPosition - vec2(vTopRight.x - b[0] - outerBorder, vTopRight.y - b[1] - outerBorder); // translate to center\n\n float d; // signed distance\n if(vVertType == ").concat(4,") {\n d = rectangleSD(p, b);\n } else if(vVertType == ").concat(7," && w == h) {\n d = circleSD(p, b.x); // faster than ellipse\n } else if(vVertType == ").concat(7,") {\n d = ellipseSD(p, b);\n } else {\n d = roundRectangleSD(p, b, vCornerRadius.wzyx);\n }\n\n // use the distance to interpolate a color to smooth the edges of the shape, doesn't need multisampling\n // we must smooth colors inwards, because we can't change pixels outside the shape's bounding box\n if(d > 0.0) {\n if(d > outerBorder) {\n discard;\n } else {\n outColor = distInterp(vBorderColor, vec4(0), d - outerBorder);\n }\n } else {\n if(d > innerBorder) {\n vec4 outerColor = outerBorder == 0.0 ? vec4(0) : vBorderColor;\n vec4 innerBorderColor = blend(vBorderColor, vColor);\n outColor = distInterp(innerBorderColor, outerColor, d);\n } \n else {\n vec4 outerColor;\n if(innerBorder == 0.0 && outerBorder == 0.0) {\n outerColor = vec4(0);\n } else if(innerBorder == 0.0) {\n outerColor = vBorderColor;\n } else {\n outerColor = blend(vBorderColor, vColor);\n }\n outColor = distInterp(vColor, outerColor, d - innerBorder);\n }\n }\n }\n else {\n outColor = vColor;\n }\n\n ").concat(e.picking?"if(outColor.a == 0.0) discard;\n else outColor = vIndex;":"","\n }\n "),i=function(e,t,n){var r=jd(e,e.VERTEX_SHADER,t),a=jd(e,e.FRAGMENT_SHADER,n),i=e.createProgram();if(e.attachShader(i,r),e.attachShader(i,a),e.linkProgram(i),!e.getProgramParameter(i,e.LINK_STATUS))throw new Error("Could not initialize shaders");return i}(t,n,a);i.aPosition=t.getAttribLocation(i,"aPosition"),i.aIndex=t.getAttribLocation(i,"aIndex"),i.aVertType=t.getAttribLocation(i,"aVertType"),i.aTransform=t.getAttribLocation(i,"aTransform"),i.aAtlasId=t.getAttribLocation(i,"aAtlasId"),i.aTex=t.getAttribLocation(i,"aTex"),i.aPointAPointB=t.getAttribLocation(i,"aPointAPointB"),i.aPointCPointD=t.getAttribLocation(i,"aPointCPointD"),i.aLineWidth=t.getAttribLocation(i,"aLineWidth"),i.aColor=t.getAttribLocation(i,"aColor"),i.aCornerRadius=t.getAttribLocation(i,"aCornerRadius"),i.aBorderColor=t.getAttribLocation(i,"aBorderColor"),i.uPanZoomMatrix=t.getUniformLocation(i,"uPanZoomMatrix"),i.uAtlasSize=t.getUniformLocation(i,"uAtlasSize"),i.uBGColor=t.getUniformLocation(i,"uBGColor"),i.uZoom=t.getUniformLocation(i,"uZoom"),i.uTextures=[];for(var o=0;o1&&void 0!==arguments[1]?arguments[1]:ch.SCREEN;this.panZoomMatrix=e,this.renderTarget=t,this.batchDebugInfo=[],this.wrappedCount=0,this.simpleCount=0,this.startBatch()}},{key:"startBatch",value:function(){this.instanceCount=0,this.batchManager.startBatch()}},{key:"endFrame",value:function(){this.endBatch()}},{key:"_isVisible",value:function(e,t){return!!e.visible()&&(!t||!t.isVisible||t.isVisible(e))}},{key:"drawTexture",value:function(e,t,n){var a=this.atlasManager,o=this.batchManager,s=a.getRenderTypeOpts(n);if(this._isVisible(e,s)&&(!e.isEdge()||this._isValidEdge(e))){if(this.renderTarget.picking&&s.getTexPickingMode){var l=s.getTexPickingMode(e);if(l===dh)return;if(l==hh)return void this.drawPickingRectangle(e,t,n)}var u,c=r(a.getAtlasInfo(e,n));try{for(c.s();!(u=c.n()).done;){var d=u.value,h=d.atlas,f=d.tex1,p=d.tex2;o.canAddToCurrentBatch(h)||this.endBatch();for(var v=o.getAtlasIndexForBatch(h),g=0,y=[[f,!0],[p,!1]];g=this.maxInstances&&this.endBatch()}}}}catch(e){c.e(e)}finally{c.f()}}}},{key:"setTransformMatrix",value:function(e,t,n,r){var a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=0;if(n.shapeProps&&n.shapeProps.padding&&(i=e.pstyle(n.shapeProps.padding).pfValue),r){var o=r.bb,s=r.tex1,l=r.tex2,u=s.w/(s.w+l.w);a||(u=1-u);var c=this._getAdjustedBB(o,i,a,u);this._applyTransformMatrix(t,c,n,e)}else{var d=n.getBoundingBox(e),h=this._getAdjustedBB(d,i,!0,1);this._applyTransformMatrix(t,h,n,e)}}},{key:"_applyTransformMatrix",value:function(e,t,n,r){var a,i;nh(e);var o=n.getRotation?n.getRotation(r):0;if(0!==o){var s=n.getRotationPoint(r);rh(e,e,[s.x,s.y]),ah(e,e,o);var l=n.getRotationOffset(r);a=l.x+(t.xOffset||0),i=l.y+(t.yOffset||0)}else a=t.x1,i=t.y1;rh(e,e,[a,i]),ih(e,e,[t.w,t.h])}},{key:"_getAdjustedBB",value:function(e,t,n,r){var a=e.x1,i=e.y1,o=e.w,s=e.h;t&&(a-=t,i-=t,o+=2*t,s+=2*t);var l=0,u=o*r;return n&&r<1?o=u:!n&&r<1&&(a+=l=o-u,o=u),{x1:a,y1:i,w:o,h:s,xOffset:l,yOffset:e.yOffset}}},{key:"drawPickingRectangle",value:function(e,t,n){var r=this.atlasManager.getRenderTypeOpts(n),a=this.instanceCount;this.vertTypeBuffer.getView(a)[0]=4,Kd(t,this.indexBuffer.getView(a)),Hd([0,0,0],1,this.colorBuffer.getView(a));var i=this.transformBuffer.getMatrixView(a);this.setTransformMatrix(e,i,r),this.simpleCount++,this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}},{key:"drawNode",value:function(e,t,n){var r=this.simpleShapeOptions.get(n);if(this._isVisible(e,r)){var a=r.shapeProps,i=this._getVertTypeForShape(e,a.shape);if(void 0===i||r.isSimple&&!r.isSimple(e))this.drawTexture(e,t,n);else{var o=this.instanceCount;if(this.vertTypeBuffer.getView(o)[0]=i,5===i||6===i){var s=r.getBoundingBox(e),l=this._getCornerRadius(e,a.radius,s),u=this.cornerRadiusBuffer.getView(o);u[0]=l,u[1]=l,u[2]=l,u[3]=l,6===i&&(u[0]=0,u[2]=0)}Kd(t,this.indexBuffer.getView(o)),Hd(e.pstyle(a.color).value,e.pstyle(a.opacity).value,this.colorBuffer.getView(o));var c=this.lineWidthBuffer.getView(o);if(c[0]=0,c[1]=0,a.border){var d=e.pstyle("border-width").value;if(d>0){Hd(e.pstyle("border-color").value,e.pstyle("border-opacity").value,this.borderColorBuffer.getView(o));var h=e.pstyle("border-position").value;if("inside"===h)c[0]=0,c[1]=-d;else if("outside"===h)c[0]=d,c[1]=0;else{var f=d/2;c[0]=f,c[1]=-f}}}var p=this.transformBuffer.getMatrixView(o);this.setTransformMatrix(e,p,r),this.simpleCount++,this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}}},{key:"_getVertTypeForShape",value:function(e,t){switch(e.pstyle(t).value){case"rectangle":return 4;case"ellipse":return 7;case"roundrectangle":case"round-rectangle":return 5;case"bottom-round-rectangle":return 6;default:return}}},{key:"_getCornerRadius",value:function(e,t,n){var r=n.w,a=n.h;if("auto"===e.pstyle(t).value)return _n(r,a);var i=e.pstyle(t).pfValue,o=r/2,s=a/2;return Math.min(i,s,o)}},{key:"drawEdgeArrow",value:function(e,t,n){if(e.visible()){var r,a,i,o=e._private.rscratch;if("source"===n?(r=o.arrowStartX,a=o.arrowStartY,i=o.srcArrowAngle):(r=o.arrowEndX,a=o.arrowEndY,i=o.tgtArrowAngle),!(isNaN(r)||null==r||isNaN(a)||null==a||isNaN(i)||null==i))if("none"!==e.pstyle(n+"-arrow-shape").value){var s=e.pstyle(n+"-arrow-color").value,l=e.pstyle("opacity").value*e.pstyle("line-opacity").value,u=e.pstyle("width").pfValue,c=e.pstyle("arrow-scale").value,d=this.r.getArrowWidth(u,c),h=this.instanceCount,f=this.transformBuffer.getMatrixView(h);nh(f),rh(f,f,[r,a]),ih(f,f,[d,d]),ah(f,f,i),this.vertTypeBuffer.getView(h)[0]=3,Kd(t,this.indexBuffer.getView(h)),Hd(s,l,this.colorBuffer.getView(h)),this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}}}},{key:"drawEdgeLine",value:function(e,t){if(e.visible()){var n=this._getEdgePoints(e);if(n){var r=e.pstyle("opacity").value,a=e.pstyle("line-opacity").value,i=e.pstyle("width").pfValue,o=e.pstyle("line-color").value,s=r*a;if(n.length/2+this.instanceCount>this.maxInstances&&this.endBatch(),4==n.length){var l=this.instanceCount;this.vertTypeBuffer.getView(l)[0]=1,Kd(t,this.indexBuffer.getView(l)),Hd(o,s,this.colorBuffer.getView(l)),this.lineWidthBuffer.getView(l)[0]=i;var u=this.pointAPointBBuffer.getView(l);u[0]=n[0],u[1]=n[1],u[2]=n[2],u[3]=n[3],this.instanceCount++,this.instanceCount>=this.maxInstances&&this.endBatch()}else for(var c=0;c=this.maxInstances&&this.endBatch()}}}}},{key:"_isValidEdge",value:function(e){var t=e._private.rscratch;return!t.badLine&&null!=t.allpts&&!isNaN(t.allpts[0])}},{key:"_getEdgePoints",value:function(e){var t=e._private.rscratch;if(this._isValidEdge(e)){var n=t.allpts;if(4==n.length)return n;var r=this._getNumSegments(e);return this._getCurveSegmentPoints(n,r)}}},{key:"_getNumSegments",value:function(e){return Math.min(Math.max(15,5),this.maxInstances)}},{key:"_getCurveSegmentPoints",value:function(e,t){if(4==e.length)return e;for(var n=Array(2*(t+1)),r=0;r<=t;r++)if(0==r)n[0]=e[0],n[1]=e[1];else if(r==t)n[2*r]=e[e.length-2],n[2*r+1]=e[e.length-1];else{var a=r/t;this._setCurvePoint(e,a,n,2*r)}return n}},{key:"_setCurvePoint",value:function(e,t,n,r){if(!(e.length<=2)){for(var a=Array(e.length-2),i=0;i0}},u=function(e){return"yes"===e.pstyle("text-events").strValue?hh:dh},c=function(e){var t=e.position(),n=t.x,r=t.y,a=e.outerWidth(),i=e.outerHeight();return{w:a,h:i,x1:n-a/2,y1:r-i/2}};n.drawing.addAtlasCollection("node",{texRows:e.webglTexRowsNodes}),n.drawing.addAtlasCollection("label",{texRows:e.webglTexRows}),n.drawing.addTextureAtlasRenderType("node-body",{collection:"node",getKey:t.getStyleKey,getBoundingBox:t.getElementBox,drawElement:t.drawElement}),n.drawing.addSimpleShapeRenderType("node-body",{getBoundingBox:c,isSimple:Wd,shapeProps:{shape:"shape",color:"background-color",opacity:"background-opacity",radius:"corner-radius",border:!0}}),n.drawing.addSimpleShapeRenderType("node-overlay",{getBoundingBox:c,isVisible:l("overlay"),shapeProps:{shape:"overlay-shape",color:"overlay-color",opacity:"overlay-opacity",padding:"overlay-padding",radius:"overlay-corner-radius"}}),n.drawing.addSimpleShapeRenderType("node-underlay",{getBoundingBox:c,isVisible:l("underlay"),shapeProps:{shape:"underlay-shape",color:"underlay-color",opacity:"underlay-opacity",padding:"underlay-padding",radius:"underlay-corner-radius"}}),n.drawing.addTextureAtlasRenderType("label",{collection:"label",getTexPickingMode:u,getKey:gh(t.getLabelKey,null),getBoundingBox:yh(t.getLabelBox,null),drawClipped:!0,drawElement:t.drawLabel,getRotation:o(null),getRotationPoint:t.getLabelRotationPoint,getRotationOffset:t.getLabelRotationOffset,isVisible:s("label")}),n.drawing.addTextureAtlasRenderType("edge-source-label",{collection:"label",getTexPickingMode:u,getKey:gh(t.getSourceLabelKey,"source"),getBoundingBox:yh(t.getSourceLabelBox,"source"),drawClipped:!0,drawElement:t.drawSourceLabel,getRotation:o("source"),getRotationPoint:t.getSourceLabelRotationPoint,getRotationOffset:t.getSourceLabelRotationOffset,isVisible:s("source-label")}),n.drawing.addTextureAtlasRenderType("edge-target-label",{collection:"label",getTexPickingMode:u,getKey:gh(t.getTargetLabelKey,"target"),getBoundingBox:yh(t.getTargetLabelBox,"target"),drawClipped:!0,drawElement:t.drawTargetLabel,getRotation:o("target"),getRotationPoint:t.getTargetLabelRotationPoint,getRotationOffset:t.getTargetLabelRotationOffset,isVisible:s("target-label")});var d=_e((function(){console.log("garbage collect flag set"),n.data.gc=!0}),1e4);n.onUpdateEleCalcs((function(e,t){var r=!1;t&&t.length>0&&(r|=n.drawing.invalidate(t)),r&&d()})),function(e){var t=e.render;e.render=function(n){n=n||{};var r=e.cy;e.webgl&&(r.zoom()>cd?(!function(e){var t=e.data.contexts[e.WEBGL];t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT)}(e),t.call(e,n)):(!function(e){var t=function(t){t.save(),t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,e.canvasWidth,e.canvasHeight),t.restore()};t(e.data.contexts[e.NODE]),t(e.data.contexts[e.DRAG])}(e),xh(e,n,ch.SCREEN)))};var n=e.matchCanvasSize;e.matchCanvasSize=function(t){n.call(e,t),e.pickingFrameBuffer.setFramebufferAttachmentSizes(e.canvasWidth,e.canvasHeight),e.pickingFrameBuffer.needsDraw=!0},e.findNearestElements=function(t,n,a,o){return function(e,t,n){var a,o,s,l=function(e,t,n){var r,a,o,s,l=qd(e),u=l.pan,c=l.zoom,d=function(e,t,n,r,a){var i=r*n+t.x,o=a*n+t.y;return[i,o=Math.round(e.canvasHeight-o)]}(e,u,c,t,n),h=i(d,2),f=h[0],p=h[1],v=6;if(r=f-v/2,a=p-v/2,s=v,0===(o=v)||0===s)return[];var g=e.data.contexts[e.WEBGL];g.bindFramebuffer(g.FRAMEBUFFER,e.pickingFrameBuffer),e.pickingFrameBuffer.needsDraw&&(g.viewport(0,0,g.canvas.width,g.canvas.height),xh(e,null,ch.PICKING),e.pickingFrameBuffer.needsDraw=!1);var y=o*s,m=new Uint8Array(4*y);g.readPixels(r,a,o,s,g.RGBA,g.UNSIGNED_BYTE,m),g.bindFramebuffer(g.FRAMEBUFFER,null);for(var b=new Set,x=0;x=0&&b.add(w)}return b}(e,t,n),u=e.getCachedZSortedEles(),c=r(l);try{for(c.s();!(s=c.n()).done;){var d=u[s.value];if(!a&&d.isNode()&&(a=d),!o&&d.isEdge()&&(o=d),a&&o)break}}catch(e){c.e(e)}finally{c.f()}return[a,o].filter(Boolean)}(e,t,n)};var a=e.invalidateCachedZSortedEles;e.invalidateCachedZSortedEles=function(){a.call(e),e.pickingFrameBuffer.needsDraw=!0};var o=e.notify;e.notify=function(t,n){o.call(e,t,n),"viewport"===t||"bounds"===t?e.pickingFrameBuffer.needsDraw=!0:"background"===t&&e.drawing.invalidate(n,{type:"node-body"})}}(n)};var gh=function(e,t){return function(n){var r=e(n),a=vh(n,t);return a.length>1?a.map((function(e,t){return"".concat(r,"_").concat(t)})):r}},yh=function(e,t){return function(n,r){var a=e(n);if("string"==typeof r){var i=r.indexOf("_");if(i>0){var o=Number(r.substring(i+1)),s=vh(n,t),l=a.h/s.length,u=l*o,c=a.y1+u;return{x1:a.x1,w:a.w,y1:c,h:l,yOffset:u}}}return a}};function mh(e,t){var n=e.canvasWidth,r=e.canvasHeight,a=qd(e),i=a.pan,o=a.zoom;t.setTransform(1,0,0,1,0,0),t.clearRect(0,0,n,r),t.translate(i.x,i.y),t.scale(o,o)}function bh(e,t,n){var r=e.drawing;t+=1,n.isNode()?(r.drawNode(n,t,"node-underlay"),r.drawNode(n,t,"node-body"),r.drawTexture(n,t,"label"),r.drawNode(n,t,"node-overlay")):(r.drawEdgeLine(n,t),r.drawEdgeArrow(n,t,"source"),r.drawEdgeArrow(n,t,"target"),r.drawTexture(n,t,"label"),r.drawTexture(n,t,"edge-source-label"),r.drawTexture(n,t,"edge-target-label"))}function xh(e,t,n){var a;e.webglDebug&&(a=performance.now());var i=e.drawing,o=0;if(n.screen&&e.data.canvasNeedsRedraw[e.SELECT_BOX]&&function(e,t){e.drawSelectionRectangle(t,(function(t){return mh(e,t)}))}(e,t),e.data.canvasNeedsRedraw[e.NODE]||n.picking){var s=e.data.contexts[e.WEBGL];n.screen?(s.clearColor(0,0,0,0),s.enable(s.BLEND),s.blendFunc(s.ONE,s.ONE_MINUS_SRC_ALPHA)):s.disable(s.BLEND),s.clear(s.COLOR_BUFFER_BIT|s.DEPTH_BUFFER_BIT),s.viewport(0,0,s.canvas.width,s.canvas.height);var l=function(e){var t=e.canvasWidth,n=e.canvasHeight,r=qd(e),a=r.pan,i=r.zoom,o=th();rh(o,o,[a.x,a.y]),ih(o,o,[i,i]);var s=th();!function(e,t,n){e[0]=2/t,e[1]=0,e[2]=0,e[3]=0,e[4]=-2/n,e[5]=0,e[6]=-1,e[7]=1,e[8]=1}(s,t,n);var l,u,c,d,h,f,p,v,g,y,m,b,x,w,E,k,T,C,P,S,B,D=th();return l=D,c=o,d=(u=s)[0],h=u[1],f=u[2],p=u[3],v=u[4],g=u[5],y=u[6],m=u[7],b=u[8],x=c[0],w=c[1],E=c[2],k=c[3],T=c[4],C=c[5],P=c[6],S=c[7],B=c[8],l[0]=x*d+w*p+E*y,l[1]=x*h+w*v+E*m,l[2]=x*f+w*g+E*b,l[3]=k*d+T*p+C*y,l[4]=k*h+T*v+C*m,l[5]=k*f+T*g+C*b,l[6]=P*d+S*p+B*y,l[7]=P*h+S*v+B*m,l[8]=P*f+S*g+B*b,D}(e),u=e.getCachedZSortedEles();if(o=u.length,i.startFrame(l,n),n.screen){for(var c=0;c0&&i>0){h.clearRect(0,0,a,i),h.globalCompositeOperation="source-over";var f=this.getCachedZSortedEles();if(e.full)h.translate(-n.x1*l,-n.y1*l),h.scale(l,l),this.drawElements(h,f),h.scale(1/l,1/l),h.translate(n.x1*l,n.y1*l);else{var p=t.pan(),v={x:p.x*l,y:p.y*l};l*=t.zoom(),h.translate(v.x,v.y),h.scale(l,l),this.drawElements(h,f),h.scale(1/l,1/l),h.translate(-v.x,-v.y)}e.bg&&(h.globalCompositeOperation="destination-over",h.fillStyle=e.bg,h.rect(0,0,a,i),h.fill())}return d},Bh.png=function(e){return _h(e,this.bufferCanvasImage(e),"image/png")},Bh.jpg=function(e){return _h(e,this.bufferCanvasImage(e),"image/jpeg")};var Ah={nodeShapeImpl:function(e,t,n,r,a,i,o,s){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,a,i);case"polygon":return this.drawPolygonPath(t,n,r,a,i,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,a,i,o,s);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,a,i,s);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,a,i,o,s);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,a,i,s);case"barrel":return this.drawBarrelPath(t,n,r,a,i)}}},Mh=Ih,Rh=Ih.prototype;function Ih(e){var t=this,n=t.cy.window().document;e.webgl&&(Rh.CANVAS_LAYERS=t.CANVAS_LAYERS=4,console.log("webgl rendering enabled")),t.data={canvases:new Array(Rh.CANVAS_LAYERS),contexts:new Array(Rh.CANVAS_LAYERS),canvasNeedsRedraw:new Array(Rh.CANVAS_LAYERS),bufferCanvases:new Array(Rh.BUFFER_COUNT),bufferContexts:new Array(Rh.CANVAS_LAYERS)};var r="-webkit-tap-highlight-color",a="rgba(0,0,0,0)";t.data.canvasContainer=n.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[r]=a,i.position="relative",i.zIndex="0",i.overflow="hidden";var o=e.cy.container();o.appendChild(t.data.canvasContainer),o.style[r]=a;var s={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};d&&d.userAgent.match(/msie|trident|edge/i)&&(s["-ms-touch-action"]="none",s["touch-action"]="none");for(var l=0;l 0) cy.add(edgesToAdd); - - cy.edges('[edgeLevel="collapsed"]').style('display', 'element'); - cy.edges('[edgeLevel="collapsed"]').forEach(function(e) { - var src = e.source(); - var dst = e.target(); - var srcExpanded = src.data('isParent') && expandedParents[src.id()]; - var dstExpanded = dst.data('isParent') && expandedParents[dst.id()]; - if (!srcExpanded && !dstExpanded) return; - - var other = srcExpanded ? dst : src; - var otherCollapsedParent = other.data('isParent') && !expandedParents[other.id()]; - if (!otherCollapsedParent) e.style('display', 'none'); - }); - }); - } - - function toggleExpand(parentNode) { - var parentId = parentNode.id(); - var isExpanded = expandedParents[parentId]; - - if (isExpanded) { - var pos = parentNode.position(); - cy.remove(parentNode.children()); - parentNode.position(pos); - parentNode.removeClass('expanded'); - expandedParents[parentId] = false; - } else { - parentNode.addClass('expanded'); - expandedParents[parentId] = true; - addVariantNodes(parentNode); - } - - cy.elements().removeClass('faded variant-selected highlighted selected-node'); - activeVariantFilter = null; - syncExpandedState(); - } - - var tooltip = document.getElementById('cy-tooltip'); - cy.on('mouseover', 'node', function(evt) { - var d = evt.target.data(); - var title = d.fullLabel || d.label; - if (d.isParent) { - title += ' (' + d.variantCount + ' variants)'; - } - tooltip.innerHTML = '' + title + '
Double-click to view API docs'; - tooltip.style.display = 'block'; - }); - cy.on('mousemove', 'node', function(evt) { - var pos = evt.renderedPosition || evt.position; - var rect = cyContainer.getBoundingClientRect(); - tooltip.style.left = (rect.left + window.scrollX + pos.x + 15) + 'px'; - tooltip.style.top = (rect.top + window.scrollY + pos.y - 10) + 'px'; - }); - cy.on('mouseout', 'node', function() { tooltip.style.display = 'none'; }); - - cy.on('mouseover', 'edge', function(evt) { - var d = evt.target.data(); - var html = '' + evt.target.source().data('label') + ' \u2192 ' + evt.target.target().data('label') + ''; - if (d.parameters && d.parameters.length > 0) { - html += '
' + d.parameters.map(function(o) { - if (o.contract === 'exact') return '' + o.field + ' = ' + o.formula + ' (exact)'; - if (o.contract === 'upper_bound') return '' + o.field + '' + o.formula + ' (upper bound)'; - return '' + o.field + ' unavailable: ' + o.reason; - }).join('
'); - } - html += '
Click to highlight, double-click for source code'; - tooltip.innerHTML = html; - tooltip.style.display = 'block'; - }); - cy.on('mousemove', 'edge', function(evt) { - var pos = evt.renderedPosition || evt.position; - var rect = cyContainer.getBoundingClientRect(); - tooltip.style.left = (rect.left + window.scrollX + pos.x + 15) + 'px'; - tooltip.style.top = (rect.top + window.scrollY + pos.y - 10) + 'px'; - }); - cy.on('mouseout', 'edge', function() { tooltip.style.display = 'none'; }); - - cy.on('dbltap', 'node', function(evt) { - var d = evt.target.data(); - if (d.doc_path) { - window.location.href = 'api/problemreductions/' + d.doc_path; - } - }); - cy.on('dbltap', 'edge', function(evt) { - var d = evt.target.data(); - if (d.doc_path) { - var module = d.doc_path.replace('/index.html', ''); - window.open('https://github.com/CodingThrust/problem-reductions/blob/main/src/' + module + '.rs', '_blank'); - } - }); - - var selectedNode = null; - var instructions = document.getElementById('instructions'); - var clearBtn = document.getElementById('clear-btn'); - - function clearPath() { - cy.elements().removeClass('highlighted selected-node'); - selectedNode = null; - instructions.textContent = 'Click a node to start path selection'; - clearBtn.style.display = 'none'; - } - - clearBtn.addEventListener('click', clearPath); - - cy.on('tap', 'node', function(evt) { - var node = evt.target; - - if (selectedNode) { - if (node === selectedNode) { - clearPath(); - return; - } - var target = node; - var visibleElements = cy.elements().filter(function(ele) { - return ele.style('display') !== 'none'; - }); - var dijkstra = visibleElements.dijkstra({ root: selectedNode, directed: true }); - var path = dijkstra.pathTo(target); - cy.elements().removeClass('highlighted selected-node'); - if (path && path.length > 0) { - path.addClass('highlighted'); - instructions.textContent = 'Path: ' + path.nodes().map(function(n) { - return n.data('fullLabel') || n.data('label'); - }).join(' \u2192 '); - } else { - instructions.textContent = 'No path from ' + - (selectedNode.data('fullLabel') || selectedNode.data('label')) + - ' to ' + (target.data('fullLabel') || target.data('label')); - } - clearBtn.style.display = 'inline'; - selectedNode = null; - return; - } - - if (node.data('isParent')) { - toggleExpand(node); - return; - } - - if (node.data('isVariant')) { - if (activeVariantFilter === node.id()) { - cy.elements().removeClass('faded variant-selected'); - activeVariantFilter = null; - instructions.textContent = 'Click a node to start path selection'; - return; - } - activeVariantFilter = node.id(); - cy.elements().addClass('faded'); - node.removeClass('faded').addClass('variant-selected'); - var connectedEdges = node.connectedEdges('[edgeLevel="variant"]'); - connectedEdges.removeClass('faded'); - connectedEdges.connectedNodes().removeClass('faded'); - if (node.data('parent')) { - cy.getElementById(node.data('parent')).removeClass('faded'); - } - instructions.textContent = 'Showing edges for ' + node.data('fullLabel') + ' \u2014 click again to clear'; - return; - } - - selectedNode = node; - node.addClass('selected-node'); - instructions.textContent = 'Now click a target node to find path from ' + - (node.data('fullLabel') || node.data('label')); - }); - - cy.on('tap', 'edge', function(evt) { - var edge = evt.target; - var d = edge.data(); - cy.elements().removeClass('highlighted selected-node'); - edge.addClass('highlighted'); - edge.source().addClass('highlighted'); - edge.target().addClass('highlighted'); - var text = edge.source().data('label') + ' \u2192 ' + edge.target().data('label'); - if (d.parameters && d.parameters.length > 0) { - text += ' | ' + d.parameters.map(function(o) { - if (o.contract === 'exact') return o.field + ' = ' + o.formula + ' (exact)'; - if (o.contract === 'upper_bound') return o.field + ' <= ' + o.formula + ' (upper bound)'; - return o.field + ' unavailable: ' + o.reason; - }).join(', '); - } - instructions.textContent = text; - clearBtn.style.display = 'inline'; - selectedNode = null; - }); - - cy.on('tap', function(evt) { - if (evt.target === cy) { - clearPath(); - cy.elements().removeClass('faded variant-selected'); - activeVariantFilter = null; - } - }); - - var downloadBtn = document.getElementById('download-svg-btn'); - if (downloadBtn) { - downloadBtn.addEventListener('click', function() { - var svgContent = cy.svg({ scale: 1, full: true, bg: getComputedStyle(document.documentElement).getPropertyValue('--bg').trim() || '#ffffff' }); - var blob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' }); - var url = URL.createObjectURL(blob); - var a = document.createElement('a'); - a.href = url; - a.download = 'reduction-graph.svg'; - a.click(); - URL.revokeObjectURL(url); - }); - } - - var searchInput = document.getElementById('search-input'); - if (searchInput) { - searchInput.addEventListener('input', function() { - var query = this.value.trim().toLowerCase(); - if (query === '') { - cy.elements().removeClass('faded'); - return; - } - cy.nodes().forEach(function(node) { - var label = (node.data('label') || '').toLowerCase(); - var fullLabel = (node.data('fullLabel') || '').toLowerCase(); - if (label.includes(query) || fullLabel.includes(query)) { - node.removeClass('faded'); - } else { - node.addClass('faded'); - } - }); - cy.edges().addClass('faded'); - cy.nodes().not('.faded').connectedEdges().forEach(function(edge) { - if (!edge.source().hasClass('faded') && !edge.target().hasClass('faded')) { - edge.removeClass('faded'); - } - }); - }); - } - }) - .catch(function(err) { - cyContainer.innerHTML = '

Failed to load reduction graph: ' + err.message + '

'; - }); - } if (typeof module !== 'undefined' && module.exports) { module.exports = { @@ -722,7 +261,4 @@ }; } - if (typeof document !== 'undefined') { - document.addEventListener('DOMContentLoaded', installBrowserGraph); - } })(); diff --git a/docs/website/README.md b/docs/website/README.md index 582100d81..cee105313 100644 --- a/docs/website/README.md +++ b/docs/website/README.md @@ -6,8 +6,45 @@ problem variant and reduction, and an interactive vertex-cover / independent-set example. Current implementation capabilities and future research ambitions are explicitly distinguished. +The standalone `graph.html` is the primary visual explorer: the graph owns the +workspace between a problem/rule browser and an always-visible detail panel. +The browser lists registered families, expandable variants, and exact directed +rules; its search and mode switch leave the graph viewport unchanged. Selecting +an item highlights its graph counterpart. +Drag the divider to resize the +panel, or focus it and use the arrow keys (Home/End select the width limits). +On narrow screens the panel sits below the graph. +The fCoSE overview is computed at build time and published with the graph data, +so reloads retain the same positions. Expanding variants relaxes the visible local +neighborhood; collapsing restores the overview. Labels +are culled by available screen space, with full variant labels reserved in layout. + +Details compile all problem definitions and reduction rules directly from +`docs/paper/reductions.typ`, including their examples, footnotes and references. +Graph's inspector and Atlas problem/reduction pages use the same renderer and +article files. The inspector's “Open in Atlas” link retains exact variant +endpoints; family-level selections open the corresponding default record. +Selection stays at exact variant granularity: variant-specific content wins; +otherwise the parent problem or directed problem-pair content is used by default. +If neither exists, the panel explicitly reports missing documentation. +No web prose is maintained separately. `problem-def` accepts `variant: (...)`; +`reduction-rule` accepts `source-variant: (...)` and `target-variant: (...)` for +specialized content. Omit these to publish shared family content. + +`scripts/build_graph_details.py` compiles once with Typst 0.15.1 and extracts +each article into the release's `assets/details/` directory. The URL index and +articles load on selection; the 24 most recently used articles are cached. References load +when expanded. Repeated SVG glyph definitions are shared within each article. +Generated content is not copied into the website source directory or committed. +Text reflows in the panel; equations and figures use +Typst's SVG rendering to preserve mathematical notation. The existing PDF build +uses the same source and its original print presentation. HTML export remains +experimental, so the build fails on export errors. + ## Build and preview +Use mdBook 0.5.2 and Typst 0.15.1, matching the deployment workflow. + ```sh make website python3 -m http.server 3001 --bind 127.0.0.1 --directory book @@ -18,6 +55,19 @@ The deployment workflow builds the PDF and API and combines everything in `book/ The fast `make website` preview includes the guide; API/PDF links require those additional builds, as in deployment. +Website assets are published under `book/releases//assets/`. +The builder rewrites their URLs together, so old open pages cannot mix new +documentation with old registry data. If an old release is no longer available, +reload the page. Do not overwrite files inside an existing release directory. +The homepage loads a small registry summary; full Atlas data and the graph's +local-layout library load only when needed. + +Finalization runs after PDF/API assembly. It externalizes generated inline +scripts and applies a same-origin CSP (inline styles remain allowed for graph +and Typst layout). Typst articles containing active elements, event handlers, +or unsafe URLs fail the build. Deployment runs browser and build-security checks +before upload; only the deploy job has Pages/OIDC write permissions. + For CSS/JavaScript iteration after the registry exports have been generated: ```sh @@ -39,13 +89,17 @@ the website builder afterward. The GitHub Pages workflow does this automatically groups variants by problem family and does not imply that arbitrary paths compose. - Detail pages use exact variants. URLs encode problem names and variant keys, rather than transient registry indices. +- Model and rule “Open implementation” links follow GitHub `main`, not a pinned + commit. Source paths come from registry metadata and are checked against files + during the build; renamed files require a website rebuild and deployment. - Counts, schemas, capabilities, and overhead expressions come from the same generated JSON used by the documentation and paper. Nothing is manually counted. - The five-vertex example is illustrative; research activity, novelty, and live test results are never fabricated. A reduction's registration does not imply formal proof. - Navigation, filters, search, clipboard actions, and the example are keyboard accessible. Layouts adapt to mobile; motion respects reduced-motion preferences. -- No frontend framework, third-party runtime, or external font request is required. +- No frontend framework or external font request is required. The graph uses + self-hosted Cytoscape and fCoSE; dependency licenses are copied beside the scripts. The static website does not yet provide agent execution, an experiment database, or live research telemetry. The research section describes the intended loop and @@ -53,12 +107,13 @@ links to the existing agent workflows. ## Browser checks -Build the full documentation with `make doc` so API link checks have their targets, -then run these commands with the preview server running: +Build the documentation with `make doc` so API link checks have their targets, +then build the PDF and run these commands with the preview server running: ```sh -uv run --no-project --with playwright python -m playwright install chromium -uv run --no-project --with playwright python scripts/test_website.py +typst compile --root . docs/paper/reductions.typ book/reductions.pdf +uv run --no-project --with playwright==1.58.0 python -m playwright install chromium +uv run --no-project --with playwright==1.58.0 python scripts/test_website.py ``` Set `WEBSITE_BROWSER_CHANNEL=chrome` to use an installed Chrome instead, or @@ -68,9 +123,11 @@ clipboard actions, the mathematical example, legacy docs, and mobile overflow. ## Documentation -The guide has nine pages listed in `docs/src/SUMMARY.md`: an overview, the CLI -(quick start, command reference, reduction graph), agent skills, the Rust library -(getting started, API, design), and a research placeholder. Keep one example per +Open problems has its own website navigation tab at `index.html#open-problems`. + +The guide has seven pages listed in `docs/src/SUMMARY.md`: an overview, the CLI +(quick start, command reference), agent skills, the Rust library +(getting started, API, design). Keep one example per concept and link to `pred --help`, rustdoc, or `.claude/CLAUDE.md` instead of restating them. diff --git a/docs/website/assets/details.css b/docs/website/assets/details.css new file mode 100644 index 000000000..50b796423 --- /dev/null +++ b/docs/website/assets/details.css @@ -0,0 +1,44 @@ +.detail-variant { color: #c4dda6; font-size: 14px; overflow-wrap: anywhere; } +.detail-source { color: #9aa797; font-size: 13px; margin: 14px 0 22px; } +.typst-detail h3 { margin: 24px 0 10px; font-size: 17px; font-weight: 600; } +.typst-detail p { margin: 10px 0; } +.typst-detail svg { max-width: 100%; filter: invert(.9); } +.typst-math > svg { display: inline-block !important; vertical-align: baseline; } +div.typst-math { overflow-x: auto; margin: 14px 0; } +.typst-detail figure { margin: 20px 0; } +.typst-detail figure > svg { filter: none; background: #eef3e8; border-radius: 4px; padding: 16px; box-sizing: border-box; width: min(100%, 260px) !important; height: auto !important; margin-inline: auto; } +.typst-detail figcaption { color: #a9b5a4; font-size: 13px; margin-top: 10px; } +.typst-detail figcaption svg { filter: invert(.9); } +.typst-detail pre { overflow: auto; max-height: 240px; padding: 12px; border: 1px solid var(--line); border-radius: 4px; font-size: 14px; line-height: 1.7; } +:is(.graph-detail, .reference-detail) a { color: #c4dda6; text-decoration: underline; text-underline-offset: 3px; overflow-wrap: anywhere; } +.detail-references { margin-top: 26px; border-top: 1px solid var(--line); padding-top: 14px; font-size: 13px; } +.detail-references summary { cursor: pointer; } +.detail-references h2 { display: none; } +.detail-references ul { padding: 0; } +.detail-references li { margin: 14px 0; overflow-wrap: anywhere; } +.detail-pdf { display: inline-block; margin-top: 24px; font-size: 14px; } + +.graph-detail .detail-atlas { display: inline-flex; font-size: 14px; margin-bottom: 10px; padding: 7px 12px; border: 1px solid var(--line); border-radius: 4px; text-decoration: none; } +.graph-detail .detail-atlas:hover { background: var(--pale); } +.reference-detail { min-width: 0; padding-block: 12px 36px; border-top: 0; } +.reference-detail:has(.detail-references) { padding-bottom: 0; } +.reference-detail .detail-references { padding: 0; border-bottom: 0; } +.reference-detail .detail-references > summary { padding-block: 20px; font-size: 16px; font-weight: 500; } +.reference-detail .detail-references > summary::marker { color: var(--muted); } +.reference-detail .detail-references[open] { padding-bottom: 24px; } +.reference-detail > .detail-source { margin: 0 0 24px; font-size: 13px; } +.reference-detail .typst-detail { font-size: 16px; line-height: 1.9; } +.reference-detail .typst-detail h3 { font-size: 19px; margin: 36px 0 14px; } +.reference-detail .typst-detail h3:first-of-type { margin-top: 0; } +.reference-detail .typst-detail p { margin: 14px 0; } +.reference-detail .typst-detail figure { margin: 32px 0; } +.reference-detail .typst-detail figure > svg { display: block; width: min(100%, 420px) !important; padding: 24px; } +.reference-detail .typst-detail figcaption { max-width: 60ch; margin: 14px auto 0; line-height: 1.7; } +.reference-detail div.typst-math { padding-block: 12px; margin: 20px 0; text-align: center; } +.reference-detail div.typst-math > svg { max-width: none; } +.reference-detail .typst-detail pre { margin: 24px 0; padding: 16px; max-height: 180px; } +@media (max-width: 600px) { + .detail-header, .reading-layout { width: calc(100% - 36px); } + .detail-header { padding-block: 28px 24px; } + .detail-header h1 { font-size: 32px; } +} diff --git a/docs/website/assets/details.js b/docs/website/assets/details.js new file mode 100644 index 000000000..56d25f7c9 --- /dev/null +++ b/docs/website/assets/details.js @@ -0,0 +1,156 @@ +(() => { + "use strict"; + const detailCache = new Map(); + let manifest; + let renderRequest = 0; + function loadDetail(key) { + const url = window.GRAPH_DETAILS.entries[key]; + if (!url) return Promise.reject(new Error(`Missing detail file: ${key}`)); + if (!detailCache.has(url)) { + detailCache.set(url, fetch(url).then((response) => { + if (!response.ok) throw new Error(`Cannot load documentation (${response.status})`); + return response.text(); + }).catch((error) => { + detailCache.delete(url); + throw error; + })); + if (detailCache.size > 24) detailCache.delete(detailCache.keys().next().value); + } else { + const cached = detailCache.get(url); + detailCache.delete(url); + detailCache.set(url, cached); + } + return detailCache.get(url); + } + + window.renderDetails = async function(detail, title, variant, key, parentKey, onProblem) { + const request = ++renderRequest; + detail.replaceChildren(); + detail.onclick = (event) => { + const link = event.target.closest('a[href^="#"]'); + if (!link) return; + const anchor = link.hash.slice(1); + const key = window.GRAPH_DETAILS.anchors[anchor]; + if (key?.startsWith("problem:") && key !== detail.querySelector("article")?.dataset.contentKey) { + event.preventDefault(); + onProblem(key.slice("problem:".length)); + return; + } + if (link.getAttribute("role") === "doc-biblioref") { + event.preventDefault(); + const references = detail.querySelector(".detail-references"); + references.open = true; + references.scrollIntoView({ block: "nearest" }); + return; + } + const target = detail.querySelector(`[id="${CSS.escape(link.hash.slice(1))}"]`); + if (!target) { + if (key === detail.querySelector("article")?.dataset.contentKey) { + event.preventDefault(); + detail.scrollIntoView({ block: "start" }); + } + return; + } + event.preventDefault(); + const references = target.closest("details"); + if (references) references.open = true; + target.scrollIntoView({ block: "nearest" }); + }; + + if (title) { + const heading = document.createElement("h2"); + heading.textContent = title; + detail.append(heading); + } + if (variant) { + const parameters = document.createElement("p"); + parameters.className = "detail-variant"; + parameters.textContent = variant; + detail.append(parameters); + } + const article = document.createElement("article"); + article.className = "typst-detail"; + article.textContent = "Loading documentation…"; + detail.append(article); + if (!window.GRAPH_DETAILS) { + try { + manifest ||= fetch("./assets/graph-details.json").then(response => { + if (!response.ok) throw new Error("Cannot load documentation index. Reload the page to get the current release."); + return response.json(); + }); + window.GRAPH_DETAILS = await manifest; + } catch (error) { + manifest = null; + if (request === renderRequest) { + article.textContent = error.message; + article.setAttribute("role", "alert"); + } + return; + } + } + if (request !== renderRequest || !article.isConnected) return; + const contentKey = window.GRAPH_DETAILS.entries[key] ? key : parentKey; + const available = Boolean(window.GRAPH_DETAILS.entries[contentKey]); + if (!available) { + const note = document.createElement("p"); + note.className = "detail-source"; + note.textContent = "No documentation is available for this entry or its parent family."; + detail.append(note); + } + article.dataset.contentKey = contentKey; + if (available) { + article.textContent = "Loading documentation…"; + article.setAttribute("aria-busy", "true"); + } + if (!available) { article.remove(); return; } + try { + const content = await loadDetail(contentKey); + if (!article.isConnected) return; + // HTML is generated at build time from the repository's Typst source. + article.innerHTML = content; + const citations = new Set([...article.querySelectorAll('a[role="doc-biblioref"]')] + .map((link) => link.hash.slice(1))); + if (citations.size) { + const references = document.createElement("details"); + references.className = "detail-references"; + references.innerHTML = "References
"; + article.after(references); + const body = references.lastElementChild; + let loaded = false; + references.addEventListener("toggle", async () => { + if (!references.open || loaded) return; + body.textContent = "Loading references…"; + try { + body.innerHTML = await loadDetail("references"); + body.querySelectorAll("li").forEach((item) => { + if (!citations.has(item.id)) item.remove(); + }); + loaded = true; + } catch (error) { + body.textContent = error.message; + body.setAttribute("role", "alert"); + } + }); + } + if (article.querySelector('a[role="doc-noteref"]')) { + const notes = document.createElement("aside"); + const footnotes = await loadDetail("footnotes"); + if (!article.isConnected) return; + notes.className = "typst-detail detail-footnotes"; + notes.innerHTML = footnotes; + const used = new Set([...article.querySelectorAll('a[role="doc-noteref"]')].map((link) => link.hash.slice(1))); + notes.querySelectorAll('li').forEach((item) => { + if (!used.has(item.id)) item.remove(); + }); + article.after(notes); + } + } catch (error) { + if (!article.isConnected) return; + article.textContent = error.message; + article.setAttribute("role", "alert"); + } finally { + article.removeAttribute("aria-busy"); + } + } + +})(); diff --git a/docs/website/assets/graph-layout.js b/docs/website/assets/graph-layout.js new file mode 100644 index 000000000..c0bde6341 --- /dev/null +++ b/docs/website/assets/graph-layout.js @@ -0,0 +1,13 @@ +const reductionLayoutOptions = { + name: "fcose", quality: "proof", randomize: false, + animate: false, fit: false, packComponents: false, tile: true, + nodeDimensionsIncludeLabels: true, + nodeRepulsion: () => 6500, + idealEdgeLength: (edge) => edge.source().isChild() || edge.target().isChild() ? 200 : 95, + edgeElasticity: (edge) => 0.45 * Math.sqrt(Math.max( + edge.source().degree(), edge.target().degree(), + )), + gravity: 0.12, numIter: 1200, +}; + +if (typeof module !== "undefined") module.exports = reductionLayoutOptions; diff --git a/docs/website/assets/graph.css b/docs/website/assets/graph.css new file mode 100644 index 000000000..c6ce60656 --- /dev/null +++ b/docs/website/assets/graph.css @@ -0,0 +1,379 @@ +.graph-page { + height: 100vh; + overflow: hidden; +} + +.graph-page .site-header { + position: relative; +} + +.graph-header { + width: calc(100% - 40px); + max-width: none; + height: 70px; +} + +.graph-header .project-logo { + width: 215px; +} + +.graph-header nav { + flex-shrink: 0; +} + +.graph-search { + width: min(560px, 42vw); + height: 40px; + display: flex; + align-items: center; + gap: 11px; + margin-left: auto; + padding: 0 13px; + color: var(--muted); + background: #141e18; + border: 1px solid var(--line); + border-radius: 6px; +} + +.graph-search:focus-within { + border-color: #748d67; + box-shadow: 0 0 0 3px rgba(196, 221, 166, 0.08); +} + +.graph-search input { + min-width: 0; + flex: 1; + color: var(--ink); + background: transparent; + border: 0; + outline: 0; +} + +.graph-search input::placeholder { + color: #718075; +} + +.graph-search kbd { + color: #718075; + font-size: 13px; +} + +#reduction-graph { + height: calc(100vh - 70px); + min-height: 620px; + display: grid; + grid-template-rows: 48px minmax(0, 1fr); + background: #0d1410; +} + +#reduction-graph:focus { + outline: none; +} + +.graph-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + padding: 0 20px; + border-bottom: 1px solid var(--line); + background: #111a15; + font-size: 14px; +} + +.graph-toolbar > div:first-child { + display: flex; + align-items: baseline; + gap: 14px; +} + +.graph-toolbar strong { + color: var(--ink); + font-weight: 600; +} + +.graph-toolbar span { + color: #718075; +} + +.graph-view-controls { + display: flex; + align-self: stretch; +} + +.graph-view-controls button { + padding: 0 14px; + color: var(--muted); + background: transparent; + border: 0; + border-left: 1px solid var(--line); + font-size: 14px; +} + +.graph-view-controls button[aria-pressed="true"] { + color: var(--green); + background: #17231b; +} + +.graph-view-controls button:hover { + color: var(--ink); +} + +.graph-workspace { + min-height: 0; + display: grid; + grid-template-columns: 260px minmax(0, 1fr) 8px clamp(240px, var(--inspector-width, 320px), calc((100% - 260px) * 0.6)); +} + +.graph-browser { + min-height: 0; + display: flex; + flex-direction: column; + background: #111a15; + border-right: 1px solid var(--line); +} +.browser-modes { display: flex; padding: 14px 14px 10px; gap: 6px; } +.browser-modes button { + flex: 1; padding: 9px; border: 1px solid var(--line); border-radius: 5px; + background: transparent; color: var(--muted); font-size: 14px; +} +.browser-modes button[aria-pressed="true"] { background: #273622; color: var(--green); } +#browser-search { + min-width: 0; margin: 0 14px; padding: 10px; border: 1px solid var(--line); + border-radius: 4px; background: #0d1410; color: var(--ink); font-size: 15px; +} +#browser-count { margin: 12px 16px; color: var(--muted); font-size: 13px; } +#browser-list { min-height: 0; flex: 1; overflow-y: auto; } +.browser-item { + display: block; width: 100%; padding: 12px 16px; border: 0; + border-bottom: 1px solid var(--line); background: transparent; + color: var(--ink); text-align: left; font-size: 15px; overflow-wrap: anywhere; +} +.browser-item small { display: block; margin-top: 5px; color: var(--muted); font-size: 13px; line-height: 1.6; } +.browser-item:hover { background: #1b281f; } +.browser-item[aria-current="true"] { background: #35492c; color: #f0f6e9; box-shadow: inset 4px 0 #c4dda6; } +.browser-item[aria-current="true"] small { color: #c5d3bc; } +.browser-item.variant-item { padding-left: 28px; color: #c4dda6; } +.browser-empty { padding: 16px; color: var(--muted); font-size: 13px; } + +.graph-inspector { + min-width: 0; + overflow-y: auto; + background: #111a15; +} + +.graph-divider { + cursor: col-resize; + touch-action: none; + background: #111a15; + border-inline: 1px solid var(--line); +} + +.graph-divider:hover, +.graph-divider:focus-visible, +.graph-divider.dragging { + background: #748d67; + outline: none; +} + +.inspector-heading { + height: 56px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 18px; + border-bottom: 1px solid var(--line); +} + +.inspector-heading span { + color: #87958a; + font-size: 14px; +} + +.graph-detail { padding: 22px 20px 28px; font-size: 16px; line-height: 1.7; } +.graph-detail:empty { padding: 0; } +.graph-detail h2 { margin: 0 0 10px; font-size: 21px; line-height: 1.35; font-weight: 500; overflow-wrap: anywhere; } + +.graph-canvas { + min-width: 0; + min-height: 0; + position: relative; + overflow: hidden; + background-color: #0d1410; + background-image: radial-gradient(#243329 0.7px, transparent 0.7px); + background-size: 19px 19px; +} + +#cy { + width: 100%; + height: 100%; +} +#cy[aria-busy="true"] { visibility: hidden; } + +.graph-legend { + position: absolute; + left: 18px; + bottom: 17px; + display: flex; + gap: 13px; + padding: 9px 12px; + color: #91a095; + background: rgba(13, 20, 16, 0.9); + border: 1px solid var(--line); + border-radius: 5px; + backdrop-filter: blur(10px); + font-size: 13px; + pointer-events: none; +} + +.graph-legend span { + display: flex; + align-items: center; + gap: 5px; +} + +.graph-legend i { + width: 7px; + height: 7px; + border-radius: 50%; + background: var(--category-color); +} + +.category-graph { + --category-color: #b9d99b; +} +.category-formula { + --category-color: #9bbfc0; +} +.category-set { + --category-color: #d1a78d; +} +.category-algebraic { + --category-color: #d8c87e; +} +.category-misc { + --category-color: #bd9dbc; +} + +.graph-canvas-note { + position: absolute; + right: 18px; + bottom: 19px; + color: #68766c; + font-size: 13px; + pointer-events: none; +} + +.graph-detail { + padding: 24px 22px 34px; +} + +.graph-tooltip { + max-width: 260px; + display: none; + position: fixed; + z-index: 50; + padding: 8px 10px; + color: var(--ink); + background: rgba(21, 32, 25, 0.96); + border: 1px solid #465b49; + border-radius: 4px; + box-shadow: 0 12px 35px rgba(0, 0, 0, 0.3); + font-size: 14px; + pointer-events: none; +} + +@media (max-width: 1100px) { + .graph-header nav .docs-nav { + display: none; + } + .graph-canvas-note { + display: none; + } +} + +@media (max-width: 800px) { + .graph-page { + height: auto; + overflow: auto; + } + .graph-header { + min-height: 118px; + } + .graph-header .graph-search { + width: calc(100% - 230px); + order: 2; + } + .graph-header nav { + order: 3; + } + #reduction-graph { + height: auto; + min-height: 0; + } + .graph-toolbar { + min-height: 62px; + padding-block: 8px; + } + .graph-toolbar > div:first-child span { + display: none; + } + .graph-workspace { + grid-template-columns: 1fr; + grid-template-rows: 280px 62vh auto; + } + .graph-browser { grid-row: 1; border-right: 0; border-bottom: 1px solid var(--line); } + .graph-divider { + display: none; + } + .graph-canvas { + grid-row: 2; + } + .graph-inspector { + grid-row: 3; + min-height: 180px; + border-left: 0; + border-top: 1px solid var(--line); + } +} + +@media (max-width: 520px) { + .graph-header .project-logo { + width: 185px; + } + .graph-header .graph-search { + width: 100%; + order: 3; + } + .graph-header nav { + order: 2; + width: auto; + gap: 16px; + } + .graph-header nav .docs-nav { + display: none; + } + .graph-toolbar { + align-items: flex-start; + flex-direction: column; + gap: 7px; + } + #reduction-graph { + grid-template-rows: auto minmax(0, 1fr); + } + .graph-view-controls { + width: 100%; + min-height: 38px; + } + .graph-view-controls button { + flex: 1; + padding: 0 6px; + border: 1px solid var(--line); + } + .graph-legend { + right: 12px; + left: 12px; + flex-wrap: wrap; + justify-content: center; + } +} diff --git a/docs/website/assets/graph.js b/docs/website/assets/graph.js new file mode 100644 index 000000000..d242f68fd --- /dev/null +++ b/docs/website/assets/graph.js @@ -0,0 +1,833 @@ +(async () => { + "use strict"; + + const data = window.REDUCTIONS; + const schemas = new Map(data.schemas.map((schema) => [schema.name, schema])); + const aliases = new Map([ + ["MIS", "MaximumIndependentSet"], + ["MVC", "MinimumVertexCover"], + ["SAT", "Satisfiability"], + ["3SAT", "KSatisfiability"], + ["3-SAT", "KSatisfiability"], + ]); + const colors = { + graph: "#b9d99b", + formula: "#9bbfc0", + set: "#d1a78d", + algebraic: "#d8c87e", + misc: "#bd9dbc", + }; + const families = new Map(); + + data.nodes.forEach((node) => { + const family = families.get(node.name) || { + name: node.name, + category: node.category, + variants: [], + incoming: new Set(), + outgoing: new Set(), + rules: 0, + }; + family.variants.push(node); + families.set(node.name, family); + }); + + const connections = new Map(); + data.edges.forEach((edge) => { + const source = data.nodes[edge.source].name; + const target = data.nodes[edge.target].name; + if (source === target) return; + const key = `${source}\u0000${target}`; + const connection = connections.get(key) || { source, target, count: 0 }; + connection.count += 1; + connections.set(key, connection); + families.get(source).outgoing.add(target); + families.get(target).incoming.add(source); + families.get(source).rules += 1; + families.get(target).rules += 1; + }); + + const displayName = (name) => + schemas.get(name)?.display_name || + name + .replace(/([a-z0-9])([A-Z])/g, "$1 $2") + .replace(/([A-Z])([A-Z][a-z])/g, "$1 $2"); + + const variantKey = (variant) => + Object.entries(variant) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, value]) => `${key}=${value}`) + .join(","); + + const search = document.querySelector("#graph-search"); + const inspector = document.querySelector(".graph-inspector"); + const selectionType = document.querySelector("#selection-type"); + const detail = document.querySelector("#graph-detail"); + const tooltip = document.querySelector("#graph-tooltip"); + let scope = "core"; + + try { + const elements = []; + families.forEach((family) => { + const neighbors = new Set([...family.incoming, ...family.outgoing]); + const position = data.layout[family.name]; + if (!position) throw new Error(`Missing graph layout position: ${family.name}`); + elements.push({ + data: { + id: family.name, + label: displayName(family.name), + category: family.category, + rules: family.rules, + peripheral: neighbors.size < 2, + }, + position: { x: position.x * 1.15, y: position.y * 1.15 }, + }); + }); + connections.forEach((connection) => + elements.push({ + data: { + id: `edge:${connection.source}:${connection.target}`, + source: connection.source, + target: connection.target, + count: connection.count, + }, + }), + ); + + const cy = cytoscape({ + container: document.querySelector("#cy"), + elements: [], + layout: { name: "preset" }, + minZoom: 0.08, + maxZoom: 3, + wheelSensitivity: 0.22, + boxSelectionEnabled: false, + style: [ + { + selector: "node", + style: { + width: (node) => Math.min(22, 10 + Math.log2(1 + node.data("rules")) * 1.5), + height: (node) => Math.min(22, 10 + Math.log2(1 + node.data("rules")) * 1.5), + shape: "ellipse", + "background-color": (node) => + colors[node.data("category")] || colors.misc, + "border-color": "#0d1410", + "border-width": 2, + label: "", + color: "#b9c4bb", + "font-family": "DM Sans, sans-serif", + "font-size": 12, + "font-weight": 400, + "min-zoomed-font-size": 7, + "text-valign": "bottom", + "text-margin-y": 8, + "text-background-color": "#0d1410", + "text-background-opacity": 0.72, + "text-background-padding": 2, + cursor: "pointer", + }, + }, + { + selector: "node.named", + style: { label: "data(label)" }, + }, + { + selector: "edge", + style: { + width: 0.9, + "line-color": "#8fa992", + "target-arrow-shape": "none", + "mid-target-arrow-shape": "none", + "mid-target-arrow-color": "#d2e4bd", + "arrow-scale": 0.7, + "curve-style": "bezier", + opacity: 0.45, + cursor: "pointer", + }, + }, + { selector: ".core-hidden", style: { display: "none" } }, + { + selector: ".faded", + style: { opacity: 0.045, "text-opacity": 0 }, + }, + { + selector: "node.selected", + style: { + label: "data(label)", + "background-color": "#e1f1c9", + "border-color": "#5c7957", + "border-width": 2, + color: "#eef4ea", + "font-size": 12, + "text-opacity": 1, + "z-index": 20, + }, + }, + { + selector: "edge.selected", + style: { + "line-color": "#c4dda6", + "mid-target-arrow-shape": "triangle", + width: 1.2, + opacity: 0.95, + "z-index": 18, + }, + }, + { + selector: "node.neighbor", + style: { label: "", opacity: 0.8, width: 13, height: 13 }, + }, + { + selector: "node.expanded", + style: { + shape: "round-rectangle", + label: "data(label)", + "background-opacity": 0.8, + "background-color": "#0d1410", + "border-color": "#344739", + "border-width": 1, + "text-valign": "top", + "text-margin-y": -10, + padding: 24, + }, + }, + { + selector: "node[?isVariant]", + style: { + label: "data(label)", + shape: "ellipse", + width: 20, + height: 20, + "text-valign": "bottom", + "text-margin-y": 10, + "text-wrap": "wrap", + "text-max-width": 145, + "font-size": 14, + color: "#d6e2d1", + "border-width": 2, + "text-background-opacity": 1, + }, + }, + { selector: ".focus-hidden", style: { display: "none" } }, + { + selector: "node.hovered, node.named", + style: { label: "data(label)", "text-opacity": 1, "z-index": 30 }, + }, + { + selector: "edge.hovered, edge.direction", + style: { + "mid-target-arrow-shape": "triangle", + "line-color": "#b6c9a7", + opacity: 0.9, + width: 1.3, + }, + }, + { + selector: "node.search-match", + style: { + label: "data(label)", + "background-color": "#e1f1c9", + "border-color": "#8eaa7f", + "border-width": 4, + opacity: 1, + "text-opacity": 1, + "z-index": 20, + }, + }, + ], + }); + + search.disabled = true; + for (let index = 0; index < elements.length; index += 40) { + cy.batch(() => cy.add(elements.slice(index, index + 40))); + await new Promise(resolve => setTimeout(resolve, 0)); + } + + function relax(elements) { + const variants = elements.nodes("[?isVariant]"); + // Reserve the full two-line label footprint while solving, then draw compact dots. + variants.style({ width: 180, height: 120, label: "" }); + elements.layout({ + ...reductionLayoutOptions, + idealEdgeLength: 95, + edgeElasticity: 0.45, + }).run(); + variants.removeStyle("width height label"); + } + const expanded = new Set(); + const browserSearch = document.querySelector("#browser-search"); + const browserList = document.querySelector("#browser-list"); + let browseMode = "problems"; + let selectedProblem = ""; + let selectedRules = new Set(); + const overviewPositions = new Map(cy.nodes().map((node) => [node.id(), { ...node.position() }])); + const variantId = (node) => `${node.name}/${variantKey(node.variant)}`; + const describeVariant = (node) => Object.entries(node.variant) + .map(([key, value]) => `${key}: ${value}`).join(", ") || "Default variant"; + + function showDetails(title, variant, key, parentKey) { + inspector.scrollTop = 0; + window.renderDetails(detail, title, variant, key, parentKey, (problem) => { + transition(() => selectNode(cy.getElementById(problem.split("/")[0]))); + }); + const atlas = document.createElement("a"); + atlas.className = "detail-atlas"; + atlas.textContent = "Open in Atlas ↗"; + const endpoint = (value) => { + const [name, variant = ""] = value.split("/"); + return [encodeURIComponent(name), encodeURIComponent(variant)]; + }; + if (key.startsWith("problem:")) { + const [name, variant] = endpoint(key.slice(8)); + atlas.href = `./index.html#problem/${name}${variant ? `?variant=${variant}` : ""}`; + } else { + const [source, target] = key.slice(5).split("->").map(endpoint); + atlas.href = `./index.html#reduction/${source[0]}/${target[0]}${key.includes("/") ? `?from=${source[1]}&to=${target[1]}` : ""}`; + } + detail.querySelector("h2").after(atlas); + const pdf = document.createElement("a"); + pdf.href = "./reductions.pdf"; + pdf.target = "_blank"; + pdf.rel = "noopener"; + pdf.className = "detail-pdf"; + pdf.textContent = "Open PDF reference ↗"; + detail.append(pdf); + } + + const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)"); + let finishMotion; + let layoutLoaded; + let transitionRequest = 0; + + async function transition(change) { + const request = ++transitionRequest; + try { + layoutLoaded ||= new Promise((resolve, reject) => { + const script = document.createElement("script"); + script.src = "./assets/layout-bundle.js"; + script.onload = resolve; + script.onerror = () => reject(new Error("Cannot load graph layout. Reload the page to get the current release.")); + document.head.append(script); + }); + await layoutLoaded; + } catch (error) { + layoutLoaded = null; + detail.textContent = error.message; + detail.setAttribute("role", "alert"); + return; + } + if (request !== transitionRequest) return; + if (finishMotion) finishMotion(); + if (reducedMotion.matches) { + change(); + return; + } + const before = new Map(cy.nodes().map((node) => [node.id(), { + position: { ...node.position() }, data: { ...node.data() }, + }])); + const fromView = { zoom: cy.zoom(), pan: { ...cy.pan() } }; + change(); + const toView = { zoom: cy.zoom(), pan: { ...cy.pan() } }; + const moving = cy.nodes().not(":parent").map((node) => ({ + node, + from: before.get(node.id())?.position || before.get(node.data("parent")).position, + to: { ...node.position() }, + })); + const exiting = []; + before.forEach(({ data, position }, id) => { + if (!data.isVariant || cy.getElementById(id).nonempty()) return; + const target = cy.getElementById(data.parent).position(); + const ghostData = { ...data }; + delete ghostData.parent; + const ghost = cy.add({ data: ghostData, position, classes: "exiting" }); + ghost.style("events", "no"); + exiting.push(ghost); + moving.push({ node: ghost, from: position, to: { ...target } }); + }); + const mix = (a, b, t) => a + (b - a) * t; + let frame; + function draw(t) { + cy.batch(() => { + moving.forEach(({ node, from, to }) => node.position({ + x: mix(from.x, to.x, t), y: mix(from.y, to.y, t), + })); + exiting.forEach((node) => node.style("opacity", 1 - t)); + }); + cy.viewport({ zoom: mix(fromView.zoom, toView.zoom, t), pan: { + x: mix(fromView.pan.x, toView.pan.x, t), + y: mix(fromView.pan.y, toView.pan.y, t), + } }); + } + finishMotion = () => { + cancelAnimationFrame(frame); + draw(1); + exiting.forEach((node) => node.remove()); + finishMotion = null; + }; + const start = performance.now(); + draw(0); + function tick(now) { + const progress = Math.min(1, (now - start) / 350); + draw(progress * progress * (3 - 2 * progress)); + if (progress < 1) frame = requestAnimationFrame(tick); + else finishMotion(); + } + frame = requestAnimationFrame(tick); + } + + function restoreOverview() { + cy.elements().removeClass("focus-hidden named"); + cy.nodes().not(":parent").not("[?isVariant]").forEach((node) => { + node.position(overviewPositions.get(node.id())); + }); + } + + function arrangeNeighborhood(nodes, edges) { + const neighbors = edges.connectedNodes().difference(nodes).not(":parent"); + const focus = nodes.union(neighbors).union(edges).union(nodes.ancestors()); + if (nodes.first().isParent()) { + relax(focus); + } + cy.elements().difference(focus).addClass("focus-hidden"); + return focus; + } + + function rebuildEdges() { + const edges = new Map(); + data.edges.forEach((rule) => { + const from = data.nodes[rule.source]; + const to = data.nodes[rule.target]; + const source = expanded.has(from.name) ? variantId(from) : from.name; + const target = expanded.has(to.name) ? variantId(to) : to.name; + if (source === target) return; + const id = `edge:${source}:${target}`; + const edge = edges.get(id) || { id, source, target, count: 0 }; + edge.count += 1; + edges.set(id, edge); + }); + cy.edges().remove(); + cy.add([...edges.values()].map((edge) => ({ data: edge }))); + } + + function toggleVariants(node) { + const family = families.get(node.id()); + if (family.variants.length < 2) return; + const center = { ...node.position() }; + if (expanded.has(node.id())) { + node.children().remove(); + node.removeClass("expanded").removeStyle("font-size").position(center); + expanded.delete(node.id()); + } else { + expanded.add(node.id()); + node.addClass("expanded"); + const columns = Math.ceil(Math.sqrt(family.variants.length)); + const rows = Math.ceil(family.variants.length / columns); + cy.add(family.variants.map((variant, index) => ({ + data: { + id: variantId(variant), + parent: node.id(), + isVariant: true, + label: Object.entries(variant.variant) + .map(([key, value]) => `${key}: ${value}`).join("\n"), + category: family.category, + rules: 0, + }, + position: { + x: center.x + (index % columns - (columns - 1) / 2) * 175, + y: center.y + (Math.floor(index / columns) - (rows - 1) / 2) * 105, + }, + }))); + } + rebuildEdges(); + } + + const visibleElements = () => + cy.elements().filter((element) => element.style("display") !== "none"); + + function sizeFocusLabels() { + const zoom = cy.zoom(); + cy.startBatch(); + cy.nodes().not(":parent").not("[?isVariant]") + .style("font-size", (node) => (node.hasClass("selected") ? 14 : 13) / zoom); + cy.nodes(".expanded").style("font-size", 18); + cy.endBatch(); + } + let labelFrame; + function updateLabels() { + sizeFocusLabels(); + cy.nodes().removeClass("named"); + const reserved = cy.nodes("[?isVariant], :parent, .hovered, .selected") + .filter((node) => node.visible()) + .map((node) => node.renderedBoundingBox({ includeNodes: false, includeLabels: true })); + const candidates = cy.nodes().not(":parent").not("[?isVariant]").not(".selected, .hovered") + .filter((node) => node.visible() && !node.hasClass("faded")) + .sort((a, b) => b.data("rules") - a.data("rules") || a.id().localeCompare(b.id())); + candidates.addClass("named"); + const hidden = []; + candidates.forEach((node) => { + const box = node.renderedBoundingBox({ includeNodes: false, includeLabels: true }); + const overlaps = reserved.some((other) => box.x1 < other.x2 + 8 && + box.x2 > other.x1 - 8 && box.y1 < other.y2 + 5 && box.y2 > other.y1 - 5); + if (overlaps || box.x1 < 12 || box.x2 > cy.width() - 12 || + box.y1 < 12 || box.y2 > cy.height() - 55) hidden.push(node); + else reserved.push(box); + }); + cy.collection(hidden).removeClass("named"); + } + cy.on("zoom pan", () => { + cancelAnimationFrame(labelFrame); + labelFrame = requestAnimationFrame(updateLabels); + }); + + function fit(focus = visibleElements(), maxZoom = 1) { + cy.resize(); + cy.fit(focus, Math.max(32, Math.min(cy.width(), cy.height()) * 0.1)); + cy.zoom(Math.min(cy.zoom(), maxZoom)); + cy.center(focus); + cancelAnimationFrame(labelFrame); + updateLabels(); + } + + function applyScope() { + cy.nodes().removeClass("core-hidden"); + if (scope === "core") cy.nodes("[?peripheral]").addClass("core-hidden"); + } + + function clearSelection() { + [...expanded].forEach((name) => toggleVariants(cy.getElementById(name))); + restoreOverview(); + cy.elements().removeClass("selected neighbor faded search-match"); + selectionType.textContent = "Details"; + detail.replaceChildren(); + applyScope(); + fit(); + selectedProblem = ""; + selectedRules.clear(); + renderBrowser(); + } + + function openInspector(type, focus) { + selectionType.textContent = type; + fit(focus, focus.nodes(":parent").empty() && focus.nodes().length <= 12 ? 1.8 : 1); + } + + function selectNode(node) { + cy.elements().removeClass("focus-hidden"); + if (!node.data("isVariant")) { + const wasExpanded = expanded.has(node.id()); + [...expanded].forEach((name) => toggleVariants(cy.getElementById(name))); + restoreOverview(); + if (wasExpanded) { + clearSelection(); + return; + } + toggleVariants(node); + } + cy.elements().removeClass("selected neighbor faded search-match"); + cy.elements().addClass("faded"); + const nodes = node.union(node.children()); + nodes.removeClass("faded core-hidden").addClass("selected"); + node.ancestors().removeClass("faded core-hidden"); + const edges = nodes.connectedEdges(); + edges.removeClass("faded"); + if (node.data("isVariant")) edges.addClass("selected"); + edges.connectedNodes().difference(nodes).removeClass("faded core-hidden").addClass("neighbor"); + edges.connectedNodes().ancestors().removeClass("faded core-hidden"); + const focus = arrangeNeighborhood(nodes, edges); + openInspector("Problem", focus); + selectedProblem = node.id(); + const familyName = node.data("isVariant") ? node.data("parent") : node.id(); + const variant = node.data("isVariant") + ? families.get(familyName).variants.find((item) => variantId(item) === node.id()) : null; + showDetails(displayName(familyName), variant ? describeVariant(variant) : "", + `problem:${node.id()}`, `problem:${familyName}`); + setBrowseMode("problems"); + browserList.querySelector('[aria-current="true"]')?.scrollIntoView({ block: "nearest" }); + } + + function selectEdge(edge) { + cy.elements().removeClass("selected neighbor faded search-match"); + cy.elements().addClass("faded"); + edge.removeClass("faded").addClass("selected"); + edge.connectedNodes().removeClass("faded core-hidden").addClass("selected"); + edge.connectedNodes().ancestors().removeClass("faded core-hidden"); + openInspector("Reduction", edge.connectedNodes()); + selectedRules = new Set(data.edges.flatMap((rule, index) => { + const matches = (endpoint, graphNode) => graphNode.data("isVariant") + ? variantId(data.nodes[endpoint]) === graphNode.id() + : data.nodes[endpoint].name === graphNode.id(); + return matches(rule.source, edge.source()) && matches(rule.target, edge.target()) ? [index] : []; + })); + const rules = [...selectedRules].map((index) => data.edges[index]); + const source = data.nodes[rules[0].source], target = data.nodes[rules[0].target]; + const parentKey = `rule:${source.name}->${target.name}`; + showDetails(`${displayName(source.name)} → ${displayName(target.name)}`, + rules.length === 1 ? `${describeVariant(source)} → ${describeVariant(target)}` + : `${rules.length} concrete rules. Choose a variant in the list.`, + rules.length === 1 ? `rule:${variantId(source)}->${variantId(target)}` : parentKey, parentKey); + setBrowseMode("rules"); + browserList.querySelector('[aria-current="true"]')?.scrollIntoView({ block: "nearest" }); + } + + function setBrowseMode(mode) { + if (browseMode !== mode) browserSearch.value = ""; + browseMode = mode; + document.querySelectorAll("[data-browse]").forEach((button) => + button.setAttribute("aria-pressed", button.dataset.browse === mode)); + browserSearch.placeholder = `Search ${mode}…`; + renderBrowser(); + } + + function renderBrowser() { + const query = browserSearch.value.trim().toLowerCase(); + const fragment = document.createDocumentFragment(); + let count = 0; + function item(title, subtitle, selected) { + const button = document.createElement("button"); + button.className = "browser-item"; + button.setAttribute("aria-current", String(selected)); + button.textContent = title; + if (subtitle) { + const detail = document.createElement("small"); + detail.textContent = subtitle; + button.append(detail); + } + fragment.append(button); + return button; + } + const variantText = (node) => Object.entries(node.variant) + .map(([key, value]) => `${key}: ${value}`).join(", "); + if (browseMode === "problems") { + [...families.values()].sort((a, b) => displayName(a.name).localeCompare(displayName(b.name))) + .forEach((family) => { + const schema = schemas.get(family.name); + const haystack = [family.name, displayName(family.name), schema?.description, + ...(schema?.aliases || []), ...family.variants.map(variantText)].join(" ").toLowerCase(); + if (!haystack.includes(query) && aliases.get(query.toUpperCase()) !== family.name) return; + count++; + const button = item(displayName(family.name), family.variants.length > 1 ? `${family.variants.length} variants` : "", selectedProblem === family.name); + button.dataset.family = family.name; + if (family.variants.length > 1) button.setAttribute("aria-expanded", String(expanded.has(family.name))); + if (expanded.has(family.name)) family.variants.forEach((variant) => { + const child = item(variantText(variant), "", selectedProblem === variantId(variant)); + child.classList.add("variant-item"); + child.dataset.variant = variantId(variant); + }); + }); + } else { + data.edges.forEach((rule, index) => { + const source = data.nodes[rule.source], target = data.nodes[rule.target]; + const title = `${displayName(source.name)} → ${displayName(target.name)}`; + const sourceVariant = variantText(source), targetVariant = variantText(target); + const subtitle = sourceVariant && targetVariant ? `${sourceVariant} → ${targetVariant}` + : sourceVariant ? `Source: ${sourceVariant}` : targetVariant ? `Target: ${targetVariant}` : ""; + const haystack = `${title} ${subtitle} ${source.name} ${target.name}`.toLowerCase(); + const alias = aliases.get(query.toUpperCase()); + if (!haystack.includes(query) && !(alias && [source.name, target.name].includes(alias))) return; + count++; + item(title, subtitle, selectedRules.has(index)).dataset.rule = index; + }); + } + document.querySelector("#browser-count").textContent = `${count} ${browseMode}`; + if (!count) { + const empty = document.createElement("p"); + empty.className = "browser-empty"; + empty.textContent = "No matches. Try another search."; + fragment.append(empty); + } + browserList.replaceChildren(fragment); + } + + browserSearch.addEventListener("input", renderBrowser); + document.querySelectorAll("[data-browse]").forEach((button) => + button.addEventListener("click", () => setBrowseMode(button.dataset.browse))); + browserList.addEventListener("click", (event) => { + const button = event.target.closest("button"); + if (!button) return; + transition(() => { + if (button.dataset.family) selectNode(cy.getElementById(button.dataset.family)); + else if (button.dataset.variant) selectNode(cy.getElementById(button.dataset.variant)); + else { + const rule = data.edges[Number(button.dataset.rule)]; + [...expanded].forEach((name) => toggleVariants(cy.getElementById(name))); + restoreOverview(); + const source = data.nodes[rule.source], target = data.nodes[rule.target]; + new Set([source.name, target.name]).forEach((name) => toggleVariants(cy.getElementById(name))); + const from = expanded.has(source.name) ? variantId(source) : source.name; + const to = expanded.has(target.name) ? variantId(target) : target.name; + const edge = cy.getElementById(`edge:${from}:${to}`); + const endpoints = edge.connectedNodes(); + const groups = endpoints.ancestors().union(endpoints).union(endpoints.ancestors().children()); + groups.removeClass("core-hidden"); + arrangeNeighborhood(groups, edge); + selectEdge(edge); + } + }); + }); + + function applySearch() { + [...expanded].forEach((name) => toggleVariants(cy.getElementById(name))); + restoreOverview(); + selectedProblem = ""; + selectedRules.clear(); + renderBrowser(); + const query = search.value.trim().toLowerCase(); + cy.elements().removeClass("selected neighbor faded search-match"); + selectionType.textContent = "Details"; + detail.replaceChildren(); + applyScope(); + if (!query) { + fit(); + return; + } + const matches = cy.nodes().filter((node) => { + const schema = schemas.get(node.id()); + return ( + aliases.get(query.toUpperCase()) === node.id() || + [ + node.id(), + displayName(node.id()), + schema?.description, + ...(schema?.aliases || []), + ] + .filter(Boolean) + .join(" ") + .toLowerCase() + .includes(query) + ); + }); + cy.nodes().removeClass("core-hidden").addClass("faded"); + cy.edges().addClass("faded"); + matches.removeClass("faded").addClass("search-match"); + matches.connectedEdges().removeClass("faded"); + matches.connectedEdges().connectedNodes().removeClass("faded"); + if (matches.length) fit(matches.union(matches.connectedEdges())); + } + + cy.on("tap", "node", (event) => transition(() => selectNode(event.target))); + cy.on("tap", "edge", (event) => transition(() => selectEdge(event.target))); + cy.on("tap", (event) => { + if (event.target === cy) transition(clearSelection); + }); + cy.on("mouseover", "node", (event) => { + event.target.addClass("hovered"); + event.target.connectedEdges().addClass("direction"); + if (event.target.data("isVariant")) { + tooltip.textContent = `${displayName(event.target.parent().id())} · ${event.target.data("label")}`; + tooltip.style.display = "block"; + return; + } + const family = families.get(event.target.id()); + tooltip.textContent = `${displayName(family.name)} · ${family.variants.length} variant${family.variants.length === 1 ? "" : "s"} · ${family.rules} reductions`; + tooltip.style.display = "block"; + }); + cy.on("mouseover", "edge", (event) => { + event.target.addClass("hovered"); + const edge = event.target; + tooltip.textContent = `${edge.source().data("label")} → ${edge.target().data("label")} · ${edge.data("count")} concrete rule${edge.data("count") === 1 ? "" : "s"}`; + tooltip.style.display = "block"; + }); + cy.on("mousemove", "node, edge", (event) => { + tooltip.style.left = `${event.originalEvent.clientX + 14}px`; + tooltip.style.top = `${event.originalEvent.clientY + 14}px`; + }); + cy.on("mouseout", "node, edge", (event) => { + event.target.removeClass("hovered"); + if (event.target.isNode()) event.target.connectedEdges().removeClass("direction"); + tooltip.style.display = "none"; + }); + + document.querySelectorAll("[data-scope]").forEach((button) => + button.addEventListener("click", () => { + scope = button.dataset.scope; + document.querySelectorAll("[data-scope]").forEach((item) => + item.setAttribute("aria-pressed", item === button), + ); + search.value = ""; + transition(clearSelection); + }), + ); + document.querySelector("#reset-graph").addEventListener("click", () => { + search.value = ""; + transition(clearSelection); + }); + const workspace = document.querySelector(".graph-workspace"); + const divider = document.querySelector(".graph-divider"); + const maxPanelWidth = () => (workspace.clientWidth - document.querySelector(".graph-browser").offsetWidth) * 0.6; + function resizePanel(width) { + const size = Math.max(240, Math.min(maxPanelWidth(), width)); + workspace.style.setProperty("--inspector-width", `${size}px`); + } + divider.addEventListener("pointerdown", (event) => { + if (event.button !== 0) return; + if (finishMotion) finishMotion(); + event.preventDefault(); + divider.focus(); + divider.setPointerCapture(event.pointerId); + divider.classList.add("dragging"); + }); + divider.addEventListener("pointermove", (event) => { + if (divider.hasPointerCapture(event.pointerId)) { + resizePanel(workspace.getBoundingClientRect().right - event.clientX - 4); + } + }); + divider.addEventListener("pointerup", (event) => { + if (divider.hasPointerCapture(event.pointerId)) divider.releasePointerCapture(event.pointerId); + }); + divider.addEventListener("lostpointercapture", () => divider.classList.remove("dragging")); + divider.addEventListener("keydown", (event) => { + const widths = { ArrowLeft: inspector.clientWidth + 20, + ArrowRight: inspector.clientWidth - 20, Home: 240, End: maxPanelWidth() }; + if (!(event.key in widths)) return; + event.preventDefault(); + if (finishMotion) finishMotion(); + resizePanel(widths[event.key]); + }); + const canvas = document.querySelector(".graph-canvas"); + let canvasWidth = canvas.clientWidth; + let canvasHeight = canvas.clientHeight; + new ResizeObserver(([entry]) => { + const { width, height } = entry.contentRect; + if (width === canvasWidth && height === canvasHeight) return; + cy.resize(); + cy.panBy({ x: (width - canvasWidth) / 2, y: (height - canvasHeight) / 2 }); + canvasWidth = width; + canvasHeight = height; + divider.setAttribute("aria-valuenow", Math.round(inspector.getBoundingClientRect().width)); + divider.setAttribute("aria-valuemax", Math.round(maxPanelWidth())); + updateLabels(); + }).observe(canvas); + search.addEventListener("input", () => transition(applySearch)); + search.addEventListener("keydown", (event) => { + if (event.key !== "Enter") return; + transition(() => { + applySearch(); + const match = cy.nodes(".search-match").first(); + if (match.nonempty()) selectNode(match); + }); + }); + document.addEventListener("keydown", (event) => { + if (event.key === "/" && document.activeElement !== search) { + event.preventDefault(); + search.focus(); + } + if (event.key === "Escape") { + search.value = ""; + transition(clearSelection); + search.blur(); + } + }); + + applyScope(); + renderBrowser(); + requestAnimationFrame(() => { + fit(); + document.querySelector("#cy").removeAttribute("aria-busy"); + workspace.inert = false; + search.disabled = false; + }); + } catch (error) { + document.querySelector(".graph-canvas-note").textContent = `Unable to load graph: ${error.message}`; + throw error; + } +})(); diff --git a/docs/website/assets/site.css b/docs/website/assets/site.css index d98daa52b..be064e054 100644 --- a/docs/website/assets/site.css +++ b/docs/website/assets/site.css @@ -57,7 +57,7 @@ body { background: var(--paper); color: var(--ink); font-family: var(--sans); - font-size: 15px; + font-size: 16px; line-height: 1.65; -webkit-font-smoothing: antialiased; } @@ -138,7 +138,7 @@ p { } .context-label { font-family: var(--sans); - font-size: 12px; + font-size: 14px; font-weight: 400; line-height: 1.5; } @@ -181,9 +181,10 @@ p { } .site-header nav { display: flex; + flex-wrap: wrap; gap: 32px; align-items: center; - font-size: 13px; + font-size: 14px; } .site-header nav a { color: var(--muted); @@ -198,25 +199,9 @@ p { text-underline-offset: 9px; } .docs-nav span { - font-size: 12px; + font-size: 13px; margin-left: 3px; } -.search-trigger { - display: flex; - align-items: center; - gap: 9px; - background: transparent; - border: 1px solid var(--line); - border-radius: 6px; - padding: 8px 10px; - color: var(--muted); - font-size: 12px; -} -.search-trigger kbd { - font-size: 10px; - color: var(--muted); - margin-left: 20px; -} .hero { display: grid; grid-template-columns: 1fr 1.15fr; @@ -244,7 +229,7 @@ p { } .hero-description { margin-top: 26px; - font-size: 15px; + font-size: 16px; line-height: 1.75; max-width: 430px; } @@ -264,7 +249,7 @@ p { padding: 12px 20px; border: 1px solid var(--green); border-radius: 5px; - font-size: 13px; + font-size: 14px; transition: background 0.2s, transform 0.2s; @@ -287,7 +272,7 @@ p { display: inline-flex; align-items: center; gap: 15px; - font-size: 13px; + font-size: 14px; font-weight: 500; } .text-link:hover { @@ -336,7 +321,7 @@ p { r: 8; } .network-node text { - font-size: 11px; + font-size: 13px; font-family: var(--sans); fill: var(--diagram-label); paint-order: stroke; @@ -349,7 +334,7 @@ p { fill: #b3d191; } .network-node.major text { - font-size: 12px; + font-size: 13px; fill: var(--diagram-label); } .network-node.focus circle { @@ -386,12 +371,12 @@ p { font-weight: 400; } .stats-bar > div span { - font-size: 10px; + font-size: 13px; color: var(--muted); margin-top: 5px; } .stats-bar > a { - font-size: 11px; + font-size: 13px; line-height: 1.7; padding-left: 26px; border-left: 1px solid var(--line); @@ -412,7 +397,7 @@ p { .section-heading > p, .section-heading > div > p { max-width: 405px; - font-size: 14px; + font-size: 16px; line-height: 1.85; } .problem-showcase { @@ -435,7 +420,7 @@ p { background: var(--pale); } .problem-card .context-label { - font-size: 12px; + font-size: 13px; color: var(--muted); } .problem-card h3 { @@ -444,7 +429,7 @@ p { margin-bottom: 11px; } .problem-card p { - font-size: 12px; + font-size: 15px; line-height: 1.8; min-height: 44px; max-width: 290px; @@ -453,9 +438,11 @@ p { height: 112px; margin-block: 18px; } -.problem-card .mini-art svg { +.problem-card .mini-art svg, +.problem-card .mini-art img { width: 100%; height: 100%; + object-fit: contain; } .card-bottom { border-top: 1px solid var(--line); @@ -464,7 +451,7 @@ p { display: flex; justify-content: space-between; align-items: center; - font-size: 10px; + font-size: 13px; color: var(--muted); } .card-bottom span:last-child { @@ -477,7 +464,7 @@ p { gap: 25px; margin-top: 24px; color: var(--muted); - font-size: 11px; + font-size: 13px; } .research-section { background: #1a3023; @@ -506,7 +493,7 @@ p { margin-bottom: 14px; } .research-cycle p { - font-size: 12px; + font-size: 15px; line-height: 1.85; } .research-note { @@ -516,7 +503,7 @@ p { padding-top: 25px; } .research-note p { - font-size: 10px; + font-size: 13px; max-width: 690px; } .research-note strong { @@ -524,7 +511,7 @@ p { color: var(--ink); } .research-note a { - font-size: 10px; + font-size: 13px; white-space: nowrap; margin-left: auto; } @@ -550,7 +537,7 @@ p { background: #22331f; padding: 5px 8px; border-radius: 4px; - font-size: 11px; + font-size: 13px; } .featured-copy h3 { font-size: 33px; @@ -559,7 +546,7 @@ p { margin: 23px 0 17px; } .featured-copy p { - font-size: 12px; + font-size: 16px; max-width: 335px; line-height: 1.85; } @@ -584,7 +571,7 @@ p { align-items: center; } .infrastructure-section p { - font-size: 13px; + font-size: 16px; line-height: 1.9; margin-top: 23px; } @@ -603,7 +590,7 @@ p { padding: 14px 20px; border-bottom: 1px solid var(--line); font-family: var(--mono); - font-size: 8px; + font-size: 13px; color: var(--muted); } .terminal-header > span:first-child { @@ -623,7 +610,7 @@ p { border: 0; background: transparent; color: var(--green); - font-size: 10px; + font-size: 14px; padding: 4px 7px; } .copy-button:hover { @@ -634,13 +621,13 @@ pre { overflow-wrap: anywhere; font-family: var(--mono); line-height: 1.85; - font-size: 12px; + font-size: 14px; margin: 0; } .terminal pre { padding: 26px; color: #c0d7ad; - font-size: 11px; + font-size: 14px; } .terminal-comment { color: var(--muted); @@ -653,7 +640,7 @@ pre { justify-content: space-between; padding: 13px 22px; border-top: 1px solid var(--line); - font-size: 10px; + font-size: 13px; background: #19271d; } .site-footer { @@ -668,13 +655,13 @@ pre { font-size: 16px; } .site-footer p { - font-size: 10px; + font-size: 13px; margin-top: 8px; } .site-footer > div:last-child { display: flex; gap: 24px; - font-size: 10px; + font-size: 13px; } .site-footer > div:last-child > span { color: var(--muted); @@ -721,7 +708,7 @@ pre { display: flex; flex-wrap: wrap; gap: 10px; - font-size: 11px; + font-size: 13px; color: var(--muted); margin-bottom: 29px; } @@ -737,7 +724,7 @@ pre { overflow-wrap: anywhere; } .page-header > p { - font-size: 15px; + font-size: 16px; max-width: 680px; line-height: 1.8; margin-top: 20px; @@ -765,7 +752,7 @@ pre { border: 0; background: transparent; outline: none; - font-size: 13px; + font-size: 14px; } .atlas-search:focus-within { outline: 2px solid var(--green); @@ -776,7 +763,7 @@ pre { } .result-count { font-family: var(--mono); - font-size: 10px; + font-size: 13px; color: var(--muted); } .atlas-layout { @@ -808,7 +795,7 @@ pre { text-align: left; background: transparent; color: var(--muted); - font-size: 12px; + font-size: 14px; margin-block: 3px; } .filter-button[aria-pressed="true"] { @@ -820,7 +807,7 @@ pre { } .filter-button span:last-child { font-family: var(--mono); - font-size: 9px; + font-size: 13px; } .atlas-results { border-top: 1px solid var(--line); @@ -843,16 +830,17 @@ pre { overflow-wrap: anywhere; } .atlas-row p { - font-size: 12px; + font-size: 15px; margin-top: 8px; max-width: 650px; } .atlas-row-meta { display: flex; + flex-wrap: wrap; gap: 15px; margin-top: 13px; font-family: var(--mono); - font-size: 9px; + font-size: 13px; color: var(--muted); } .atlas-row > span { @@ -867,20 +855,49 @@ pre { margin-bottom: 14px; } .empty-state p { - font-size: 13px; + font-size: 16px; } .empty-state button { margin-top: 22px; } .reading-layout { display: grid; - grid-template-columns: minmax(0, 1fr) 290px; - gap: 70px; + width: min(1060px, calc(100% - 64px)); + grid-template-columns: minmax(0, 1fr) 200px; + gap: 64px; padding-bottom: 90px; } +.detail-header { + width: min(1060px, calc(100% - 64px)); + padding-block: 36px 30px; +} +.detail-header .breadcrumbs { margin-bottom: 20px; } +.detail-header h1 { font-size: clamp(30px, 3.5vw, 44px); line-height: 1.2; letter-spacing: -.035em; } +.rule-endpoints { margin: 0 0 26px; } +.rule-endpoints > div { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 16px; padding-block: 9px; } +.rule-endpoints dt { font-size: 14px; color: var(--muted); line-height: 1.8; } +.rule-endpoint { display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px 16px; margin: 0; min-width: 0; line-height: 1.6; } +.rule-endpoint a { font-size: 15px; font-weight: 500; } +.rule-endpoint a span { color: var(--green); margin-left: 4px; } +.rule-endpoint a:hover { color: var(--green); text-decoration: underline; text-underline-offset: 5px; } +.rule-endpoint span { font-size: 13px; color: var(--muted); overflow-wrap: anywhere; } +#rule-parameters { margin-bottom: 32px; } +#rule-parameters h2 { font-size: 17px; font-weight: 500; margin-bottom: 12px; } +.parameter-relation { display: flex; align-items: baseline; gap: 12px; overflow-x: auto; padding-block: 7px; font-size: 14px; } +.parameter-relation > code, .parameter-relation > math { flex-shrink: 0; } +.parameter-relation > code { font-family: math; font-size: 14px; } +.parameter-operator { font-family: math; font-size: 17px; } .reading-content { min-width: 0; } +.reference-tools { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-bottom: 28px; border-bottom: 1px solid var(--line); } +.reference-tools button { padding: 10px 0; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); font-size: 14px; cursor: pointer; } +.reference-tools button span { margin-left: 5px; color: var(--ink); font-size: 13px; } +.reference-tools button:hover, .reference-tools button[aria-expanded="true"] { color: var(--green); border-bottom-color: var(--green); } +.reference-tool-panel { margin-bottom: 32px; max-height: 440px; overflow: auto; padding: 0 2px 20px; border-bottom: 1px solid var(--line); } +.reference-tool-panel h3 { font-size: 17px; margin: 18px 0 10px; } +.reference-tool-panel > p { font-size: 15px; line-height: 1.7; } +.reference-tool-panel .code-panel { margin-top: 0; } .reading-section { padding-block: 32px; border-top: 1px solid var(--line); @@ -892,7 +909,7 @@ pre { margin-bottom: 17px; } .reading-section > p { - font-size: 14px; + font-size: 16px; line-height: 1.85; margin-block: 15px; max-width: 730px; @@ -901,28 +918,6 @@ pre { font-size: 18px; margin: 25px 0 13px; } -.formula { - background: var(--pale); - padding: 27px; - border-left: 2px solid var(--green); - font-family: var(--serif); - font-size: 27px; - color: var(--green); - line-height: 1.5; - margin-block: 23px; - overflow-x: auto; -} -.formula math { - font-family: math; -} -.formula math[display="block"] { - margin: 0; - text-align: left; -} -.formula-constraint { - margin-top: 14px; - font-size: 18px; -} .math-expression { overflow-x: auto; max-width: 100%; @@ -932,50 +927,39 @@ pre { font-family: math; font-size: 1.05em; } -.formula small { - display: block; - font-family: var(--sans); - font-size: 11px; - color: var(--muted); - margin-top: 8px; -} .reading-aside { align-self: start; position: sticky; top: 112px; - background: var(--pale); - border: 1px solid var(--line); - border-radius: 6px; - padding: 25px; + padding-top: 8px; } .metadata { - margin: 21px 0 24px; + margin: 0 0 24px; } .metadata > div { padding-block: 13px; - border-bottom: 1px solid var(--line); } .metadata dt { - font-size: 10px; + font-size: 13px; color: var(--muted); margin-bottom: 4px; } .metadata dd { margin: 0; - font-size: 12px; + font-size: 15px; overflow-wrap: anywhere; } .reading-aside > a { display: flex; justify-content: space-between; - font-size: 12px; + font-size: 15px; margin-top: 15px; } .reading-aside > a:hover { text-decoration: underline; } .reading-aside p { - font-size: 10px; + font-size: 13px; margin-top: 20px; line-height: 1.8; } @@ -985,7 +969,7 @@ pre { gap: 13px; align-items: center; margin-top: 25px; - font-size: 11px; + font-size: 14px; color: var(--muted); } .variant-control select { @@ -995,7 +979,7 @@ pre { border-radius: 4px; background: var(--surface); color: var(--ink); - font-size: 11px; + font-size: 15px; } .variant-tags { display: flex; @@ -1008,47 +992,61 @@ pre { border-radius: 3px; padding: 4px 8px; font-family: var(--mono); - font-size: 9px; + font-size: 13px; color: var(--muted); } .relation-link { - display: block; - border: 1px solid var(--line); - border-radius: 5px; - padding: 17px; - margin-bottom: 10px; - background: var(--surface); - transition: border-color 0.2s; + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + border-bottom: 1px solid var(--line); + padding: 13px 12px; } .relation-link:hover { - border-color: #89a76e; + background: var(--surface); } +.relation-main { min-width: 0; } +.connection-group + .connection-group { margin-top: 24px; } +.connection-group > header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 12px; background: var(--surface); border-radius: 4px; } +.connection-group > header h3 { margin: 0; font-size: 17px; } +.connection-group > header h3 span { display: inline-block; margin-left: 8px; color: var(--green); } +.connection-group > header > span { font-size: 13px; color: var(--muted); } .relation-title { display: flex; align-items: center; justify-content: space-between; gap: 15px; - font-size: 13px; + font-size: 15px; font-weight: 500; } .relation-link p { - font-family: var(--mono); - font-size: 9px; - margin-top: 7px; + font-family: var(--sans); + font-size: 13px; + margin-top: 4px; overflow-wrap: anywhere; } .relation-link .capability { font-family: var(--sans); - font-size: 10px; + font-size: 13px; + color: var(--muted); + flex-shrink: 0; + padding: 3px 7px; + border: 1px solid var(--line); + border-radius: 4px; +} +@media (max-width: 600px) { + .relation-link { flex-wrap: wrap; gap: 6px; } + .relation-title { overflow-wrap: anywhere; } } .schema-table { width: 100%; border-collapse: collapse; - font-size: 12px; + font-size: 15px; } .schema-table th { text-align: left; - font-size: 10px; + font-size: 14px; color: var(--muted); font-weight: 400; padding: 10px 10px 10px 0; @@ -1061,7 +1059,7 @@ pre { overflow-wrap: anywhere; } .schema-table code { - font-size: 11px; + font-size: 15px; word-break: break-word; } .table-scroll { @@ -1077,91 +1075,8 @@ pre { .code-panel pre { padding: 22px; } -.evidence-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 12px; - margin-top: 25px; -} -.evidence-item { - border: 1px solid var(--line); - border-radius: 5px; - padding: 20px; -} -.evidence-item h3 { - font-size: 14px; - margin: 12px 0 7px; -} -.evidence-item p { - font-size: 11px; - line-height: 1.8; -} -.evidence-item .context-label { - font-size: 12px; -} -.evidence-item a { - display: inline-block; - font-size: 11px; - margin-top: 12px; - text-decoration: underline; - text-underline-offset: 4px; -} -.demo-panel { - border: 1px solid var(--line); - background: var(--pale); - border-radius: 6px; - overflow: hidden; - margin-top: 25px; -} -.demo-toolbar { - padding: 16px 20px; - display: flex; - justify-content: space-between; - align-items: center; - gap: 15px; - border-bottom: 1px solid var(--line); - font-size: 11px; -} -.segmented { - display: flex; - background: #111c14; - padding: 3px; - border-radius: 5px; -} -.segmented button { - border: 0; - background: transparent; - border-radius: 3px; - padding: 7px 12px; - font-size: 10px; -} -.segmented button[aria-pressed="true"] { - background: var(--green); - color: var(--on-accent); - box-shadow: 0 1px 4px #00000020; -} -.demo-panel svg { - display: block; - max-height: 290px; - width: 100%; - padding: 20px; -} -.demo-caption { - display: flex; - justify-content: space-between; - align-items: center; - gap: 15px; - padding: 16px 20px; - border-top: 1px solid var(--line); - font-size: 11px; - color: var(--muted); -} -.demo-caption strong { - color: var(--green); - font-weight: 500; -} .notice { - font-size: 11px; + font-size: 13px; line-height: 1.85; color: var(--muted); border-left: 2px solid #799461; @@ -1174,11 +1089,11 @@ pre { } .reading-content summary { cursor: pointer; - font-size: 13px; + font-size: 14px; font-weight: 500; } .reading-content details p { - font-size: 12px; + font-size: 16px; line-height: 1.9; padding-block: 15px; } @@ -1219,9 +1134,6 @@ pre { .wordmark { font-size: 17px; } - .search-trigger kbd { - margin-left: 4px; - } .hero { gap: 18px; min-height: 620px; @@ -1233,8 +1145,8 @@ pre { .hero-graph { height: 380px; } - .hero-description { - font-size: 14px; +.hero-description { + font-size: 16px; } .hero-actions { gap: 18px; @@ -1244,7 +1156,7 @@ pre { } .reading-layout { gap: 35px; - grid-template-columns: minmax(0, 1fr) 260px; + grid-template-columns: minmax(0, 1fr) 200px; } .infrastructure-section { gap: 35px; @@ -1263,18 +1175,12 @@ pre { padding-block: 16px; row-gap: 15px; } - .site-header nav { +.site-header nav { order: 3; width: 100%; justify-content: center; - gap: 35px; - font-size: 12px; - } - .search-trigger { - margin-left: auto; - } - .search-trigger kbd { - display: none; + gap: 22px; + font-size: 14px; } .wrap { width: calc(100% - 48px); @@ -1290,8 +1196,8 @@ pre { .hero h1 br.desktop-break { display: none; } - .hero-description { - font-size: 15px; +.hero-description { + font-size: 16px; } .hero-copy { max-width: 600px; @@ -1385,7 +1291,7 @@ pre { } .research-note p { flex: 1; - font-size: 11px; + font-size: 13px; } .research-note a { width: 100%; @@ -1438,10 +1344,10 @@ pre { width: 100%; margin-bottom: 5px; } - .filter-button { +.filter-button { width: auto; gap: 15px; - font-size: 11px; + font-size: 14px; border: 1px solid var(--line); } .reading-layout { @@ -1449,8 +1355,8 @@ pre { } .reading-aside { position: static; - order: -1; - padding: 20px; + padding: 24px 0 0; + border-top: 1px solid var(--line); } .metadata { display: flex; @@ -1476,8 +1382,8 @@ pre { .page-header h1 { font-size: 48px; } - .page-header > p { - font-size: 14px; +.page-header > p { + font-size: 16px; } .atlas-controls { align-items: flex-start; @@ -1491,10 +1397,10 @@ pre { padding-inline: 5px; } .section-bottom { - font-size: 10px; + font-size: 13px; } - .section-bottom .text-link { - font-size: 11px; +.section-bottom .text-link { + font-size: 14px; } .desktop-break { display: none; @@ -1517,31 +1423,25 @@ pre { .wordmark .project-logo { width: 208px; } - .site-header nav { - gap: 25px; - font-size: 11px; - } - .search-trigger { - padding: 7px; - } - .search-trigger > span { - display: none; +.site-header nav { + gap: 13px; + font-size: 14px; } .hero h1 { font-size: 61px; } - .hero-description { - font-size: 14px; +.hero-description { + font-size: 16px; } .hero-actions { gap: 20px; } - .button { +.button { padding: 11px 16px; - font-size: 12px; + font-size: 14px; } - .hero-actions .text-link { - font-size: 12px; +.hero-actions .text-link { + font-size: 14px; } .hero-graph { height: 310px; @@ -1550,7 +1450,7 @@ pre { font-size: 28px; } .stats-bar > div span { - font-size: 9px; + font-size: 13px; } .problem-card { grid-template-columns: 1fr 85px; @@ -1559,8 +1459,8 @@ pre { .problem-card h3 { font-size: 21px; } - .problem-card p { - font-size: 11px; +.problem-card p { + font-size: 15px; } .research-cycle article { padding: 22px 16px !important; @@ -1568,20 +1468,8 @@ pre { .research-cycle h3 { font-size: 16px; } - .research-cycle p { - font-size: 11px; - } - .evidence-grid { - grid-template-columns: 1fr; - } - .demo-toolbar { - flex-direction: column; - align-items: flex-start; - } - .demo-caption { - align-items: flex-start; - flex-direction: column; - gap: 4px; +.research-cycle p { + font-size: 15px; } .section-bottom { flex-direction: column; @@ -1593,10 +1481,6 @@ pre { .variant-control select { width: 100%; } - .formula { - font-size: 23px; - padding: 20px; - } } @media (prefers-reduced-motion: reduce) { html { diff --git a/docs/website/assets/site.js b/docs/website/assets/site.js index c0cd3f96c..1bcd0c6c4 100644 --- a/docs/website/assets/site.js +++ b/docs/website/assets/site.js @@ -1,9 +1,11 @@ /* The site is a static client of the same registry exports as the book and paper. */ (() => { "use strict"; - const data = window.REDUCTIONS; + let data = window.REDUCTIONS; + let fullData; const main = document.querySelector("main"); const homeHTML = main.innerHTML; + history.scrollRestoration = "manual"; const baseTitle = "Problem Reductions"; const repo = "https://github.com/CodingThrust/problem-reductions"; const categories = { @@ -59,7 +61,6 @@ schemaOf(name)?.description || "Explore the registered variants, reduction contracts, and implementation of this computational problem."; const apiHref = (path) => `./api/problemreductions/${path}`; - const moduleName = (edge) => edge.doc_path.split("/").at(-2); const sourceHref = (edge) => `${repo}/blob/main/${edge.source_path}`; const families = [...new Set(data.nodes.map((n) => n.name))].sort(); const variantsOf = (name) => @@ -170,8 +171,8 @@ function miniArt(name) { if (name === "MaximumIndependentSet") return cycleSVG(); if (name === "Satisfiability") - return '(x₁ ∨ x₂ ∨ ¬x₃)(¬x₁ ∨ x₃ ∨ x₄)'; - return 'min xᵀQxx ∈ {0, 1}ⁿ'; + return 'Example Boolean clauses'; + return 'A quadratic objective'; } function hydrateHome() { @@ -195,10 +196,7 @@ } function atlasPage() { - main.innerHTML = /* HTML */ ` @@ -260,7 +258,7 @@ .toLowerCase() .includes(search)) ); - }); + }).sort((a, b) => nameOf(a).localeCompare(nameOf(b))); document.querySelector(".result-count").textContent = `${results.length} of ${families.length} problem families`; document.querySelector("#atlas-results").innerHTML = results.length @@ -284,35 +282,19 @@ target = data.nodes[edge.target]; const outgoing = edge.source === currentIndex; const other = outgoing ? target : source; - return `
${outgoing ? "→ " : "← "}${escape(nameOf(other.name))}

${escape(variantLabel(other))}

${[edge.witness && "Result recovery", edge.turing && "Turing reduction"].filter(Boolean).join(" · ") || "See reduction contract"}

`; - } - - function demoPanel() { - return `
Unit-weight example · five-vertex cycle
${cycleSVG("independent", true)}
No two selected vertices share an edge.Maximum size: 2
`; - } - - function bindDemo() { - document.querySelectorAll("[data-demo]").forEach((button) => - button.addEventListener("click", () => { - const mode = button.dataset.demo; - document - .querySelectorAll("[data-demo]") - .forEach((b) => b.setAttribute("aria-pressed", b === button)); - document.querySelector("#demo-graph").innerHTML = cycleSVG(mode, true); - document.querySelector("#demo-description").textContent = - mode === "independent" - ? "No two selected vertices share an edge." - : "Every edge touches a selected vertex."; - document.querySelector("#demo-value").textContent = - mode === "independent" ? "Maximum size: 2" : "Minimum size: 3"; - }), - ); + const variant = Object.keys(other.variant).length ? variantLabel(other) : ""; + return `
${outgoing ? "→ " : ""}${escape(nameOf(other.name))}${outgoing ? "" : " →"}
${variant ? `

${escape(variant)}

` : ""}
${edge.turing ? 'Turing reduction' : ""}
`; } function codePanel(command) { return `
${escape(command)}
`; } + function openReferenceProblem(key) { + const [name, variant] = key.split("/"); + location.hash = `#problem/${encodeURIComponent(name)}${variant ? `?variant=${encodeURIComponent(variant)}` : ""}`; + } + function problemPage(name, params) { const variants = variantsOf(name); if (!variants.length) return notFound(); @@ -331,17 +313,14 @@ const schema = schemaOf(name); const incoming = data.edges.filter((e) => e.target === node.index); const outgoing = data.edges.filter((e) => e.source === node.index); - const mis = name === "MaximumIndependentSet"; document.title = `${nameOf(name)} — ${baseTitle}`; - main.innerHTML = /* HTML */ `