mirror of
https://github.com/HananoshikaYomaru/openfreebooks.git
synced 2026-11-12 20:45:52 +00:00
Refactor CatalogApp to replace JSON canvas viewer with Mermaid for chapter map generation, update related components and styles for improved interactivity, and enhance contributing guidelines to reflect new features. Remove unused canvas-related code and dependencies to streamline the project.
This commit is contained in:
parent
9ddcce79c6
commit
df556227e4
149 changed files with 10825 additions and 1196 deletions
|
|
@ -31,7 +31,7 @@ content/{subject}/{slug}/ → actual chapter page (when status is "live")
|
|||
themes/.../partials/... → chapter HTML content (today)
|
||||
```
|
||||
|
||||
- **Catalog** (`/catalog/`) — **List** (numbered cards; live = whole card links) and **Map** (`?view=tree`; live = title link only with `→` and hover underline).
|
||||
- **Catalog** (`/catalog/`) — **List** (numbered cards; live = whole card links) and **Map** (`?view=tree`, Mermaid; live = title link only with `→` and hover underline).
|
||||
- **`/math/`** redirects to `/catalog/?subject=math`.
|
||||
- **Curriculum names** (DSE, IB, …) appear only in the catalog — not inside chapter text ([spec.md](spec.md)).
|
||||
- Every chapter needs a **`description`** in curriculum JSON (map clamps to three lines).
|
||||
|
|
@ -207,7 +207,7 @@ Example: adding **GCSE**.
|
|||
bun install
|
||||
bun run build:js # after frontend/ changes
|
||||
zola serve
|
||||
bun test # catalog map layout (catalog-to-canvas)
|
||||
bun test # catalog map generation (catalog-to-mermaid)
|
||||
bun run build
|
||||
```
|
||||
|
||||
|
|
|
|||
223
bun.lock
223
bun.lock
|
|
@ -6,9 +6,10 @@
|
|||
"name": "openfreebooks",
|
||||
"dependencies": {
|
||||
"defuddle": "^0.18.1",
|
||||
"json-canvas-viewer": "^4.3.2",
|
||||
"katex": "^0.16.47",
|
||||
"mermaid": "^11.15.0",
|
||||
"solid-js": "^1.9.5",
|
||||
"svg-pan-zoom": "^3.6.2",
|
||||
"three": "^0.184.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -19,7 +20,7 @@
|
|||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ahmedsemih/color-fns": ["@ahmedsemih/color-fns@1.3.0", "", {}, "sha512-KjPMB+bUqOrJRvCCHVtbpHaCy621xD/Pn2LlJyAZx2lVwuc8d1FzDXSDIzM4iTNu/xUWoT/yfKQAuB2vFmeBnQ=="],
|
||||
"@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
|
||||
|
||||
"@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="],
|
||||
|
||||
|
|
@ -57,6 +58,10 @@
|
|||
|
||||
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
||||
|
||||
"@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="],
|
||||
|
||||
"@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="],
|
||||
|
|
@ -109,6 +114,10 @@
|
|||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
|
||||
|
||||
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
|
||||
|
||||
"@iconify/utils": ["@iconify/utils@3.1.3", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "import-meta-resolve": "^4.2.0" } }, "sha512-LPKOXPn/zV+zis1oOfGWogaXVpqUybF3ZS6SCZIsz8vg0ivVp9+fVqyYB7xq0aiST/VhUQYGO1qo6uoYSiEJqw=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||
|
||||
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||
|
|
@ -119,9 +128,9 @@
|
|||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="],
|
||||
"@mermaid-js/parser": ["@mermaid-js/parser@1.1.1", "", { "dependencies": { "@chevrotain/types": "~11.1.1" } }, "sha512-VuHdsYMK1bT6X2JbcAaWAhugTRvRBRyuZgd+c22swUeI9g/ntaxF7CY7dYarhZovofCbUNO0G7JesfmNtjYOCw=="],
|
||||
|
||||
"@needle-di/core": ["@needle-di/core@1.1.2", "", {}, "sha512-9CVnXjK33JeqUwAz5k/D+ti4ZfJ17m5AXsUcOwErbQ8baTNDPt1erVFGjipxxwcUj86Oxap3dALz6U70xsUsFg=="],
|
||||
"@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="],
|
||||
|
||||
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.4", "", { "os": "android", "cpu": "arm" }, "sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ=="],
|
||||
|
||||
|
|
@ -181,10 +190,76 @@
|
|||
|
||||
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
|
||||
|
||||
"@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="],
|
||||
|
||||
"@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
|
||||
|
||||
"@types/d3-axis": ["@types/d3-axis@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw=="],
|
||||
|
||||
"@types/d3-brush": ["@types/d3-brush@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A=="],
|
||||
|
||||
"@types/d3-chord": ["@types/d3-chord@3.0.6", "", {}, "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="],
|
||||
|
||||
"@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="],
|
||||
|
||||
"@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="],
|
||||
|
||||
"@types/d3-delaunay": ["@types/d3-delaunay@6.0.4", "", {}, "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="],
|
||||
|
||||
"@types/d3-dispatch": ["@types/d3-dispatch@3.0.7", "", {}, "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA=="],
|
||||
|
||||
"@types/d3-drag": ["@types/d3-drag@3.0.7", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ=="],
|
||||
|
||||
"@types/d3-dsv": ["@types/d3-dsv@3.0.7", "", {}, "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="],
|
||||
|
||||
"@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="],
|
||||
|
||||
"@types/d3-fetch": ["@types/d3-fetch@3.0.7", "", { "dependencies": { "@types/d3-dsv": "*" } }, "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA=="],
|
||||
|
||||
"@types/d3-force": ["@types/d3-force@3.0.10", "", {}, "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="],
|
||||
|
||||
"@types/d3-format": ["@types/d3-format@3.0.4", "", {}, "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="],
|
||||
|
||||
"@types/d3-geo": ["@types/d3-geo@3.1.0", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ=="],
|
||||
|
||||
"@types/d3-hierarchy": ["@types/d3-hierarchy@3.1.7", "", {}, "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="],
|
||||
|
||||
"@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="],
|
||||
|
||||
"@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
|
||||
|
||||
"@types/d3-polygon": ["@types/d3-polygon@3.0.2", "", {}, "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="],
|
||||
|
||||
"@types/d3-quadtree": ["@types/d3-quadtree@3.0.6", "", {}, "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="],
|
||||
|
||||
"@types/d3-random": ["@types/d3-random@3.0.3", "", {}, "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="],
|
||||
|
||||
"@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
|
||||
|
||||
"@types/d3-scale-chromatic": ["@types/d3-scale-chromatic@3.1.0", "", {}, "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="],
|
||||
|
||||
"@types/d3-selection": ["@types/d3-selection@3.0.11", "", {}, "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="],
|
||||
|
||||
"@types/d3-shape": ["@types/d3-shape@3.1.8", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w=="],
|
||||
|
||||
"@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
|
||||
|
||||
"@types/d3-time-format": ["@types/d3-time-format@4.0.3", "", {}, "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="],
|
||||
|
||||
"@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="],
|
||||
|
||||
"@types/d3-transition": ["@types/d3-transition@3.0.9", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg=="],
|
||||
|
||||
"@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
|
||||
|
||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||
|
||||
"@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="],
|
||||
|
||||
"@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="],
|
||||
|
||||
"babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.40.7", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "parse5": "^7.1.2" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-/O6JWUmjv03OI9lL2ry9bUjpD5S3PclM55RRJEyCdcFZ5W2SEA/59d+l2hNsk3gI6kiWRdRPdOtqZmsQzFN1pQ=="],
|
||||
|
|
@ -203,6 +278,8 @@
|
|||
|
||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
||||
"cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
|
||||
|
||||
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
|
||||
|
||||
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
|
||||
|
|
@ -211,10 +288,86 @@
|
|||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"cytoscape": ["cytoscape@3.33.4", "", {}, "sha512-HIN5Pmd9MrX9BkV7tDwnOcEJCSFvCpc8X97h3f508J6I5FsqAY65wKOCvgH2CuP42CaahWaz4tuh32SOOIH7ww=="],
|
||||
|
||||
"cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="],
|
||||
|
||||
"cytoscape-fcose": ["cytoscape-fcose@2.2.0", "", { "dependencies": { "cose-base": "^2.2.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ=="],
|
||||
|
||||
"d3": ["d3@7.9.0", "", { "dependencies": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", "d3-dsv": "3", "d3-ease": "3", "d3-fetch": "3", "d3-force": "3", "d3-format": "3", "d3-geo": "3", "d3-hierarchy": "3", "d3-interpolate": "3", "d3-path": "3", "d3-polygon": "3", "d3-quadtree": "3", "d3-random": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "d3-selection": "3", "d3-shape": "3", "d3-time": "3", "d3-time-format": "4", "d3-timer": "3", "d3-transition": "3", "d3-zoom": "3" } }, "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA=="],
|
||||
|
||||
"d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
|
||||
|
||||
"d3-axis": ["d3-axis@3.0.0", "", {}, "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="],
|
||||
|
||||
"d3-brush": ["d3-brush@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "3", "d3-transition": "3" } }, "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ=="],
|
||||
|
||||
"d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="],
|
||||
|
||||
"d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
|
||||
|
||||
"d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="],
|
||||
|
||||
"d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="],
|
||||
|
||||
"d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="],
|
||||
|
||||
"d3-drag": ["d3-drag@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" } }, "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="],
|
||||
|
||||
"d3-dsv": ["d3-dsv@3.0.1", "", { "dependencies": { "commander": "7", "iconv-lite": "0.6", "rw": "1" }, "bin": { "csv2json": "bin/dsv2json.js", "csv2tsv": "bin/dsv2dsv.js", "dsv2dsv": "bin/dsv2dsv.js", "dsv2json": "bin/dsv2json.js", "json2csv": "bin/json2dsv.js", "json2dsv": "bin/json2dsv.js", "json2tsv": "bin/json2dsv.js", "tsv2csv": "bin/dsv2dsv.js", "tsv2json": "bin/dsv2json.js" } }, "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="],
|
||||
|
||||
"d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="],
|
||||
|
||||
"d3-fetch": ["d3-fetch@3.0.1", "", { "dependencies": { "d3-dsv": "1 - 3" } }, "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw=="],
|
||||
|
||||
"d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="],
|
||||
|
||||
"d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="],
|
||||
|
||||
"d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="],
|
||||
|
||||
"d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="],
|
||||
|
||||
"d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
|
||||
|
||||
"d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
|
||||
|
||||
"d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="],
|
||||
|
||||
"d3-quadtree": ["d3-quadtree@3.0.1", "", {}, "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="],
|
||||
|
||||
"d3-random": ["d3-random@3.0.1", "", {}, "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="],
|
||||
|
||||
"d3-sankey": ["d3-sankey@0.12.3", "", { "dependencies": { "d3-array": "1 - 2", "d3-shape": "^1.2.0" } }, "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ=="],
|
||||
|
||||
"d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
|
||||
|
||||
"d3-scale-chromatic": ["d3-scale-chromatic@3.1.0", "", { "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" } }, "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ=="],
|
||||
|
||||
"d3-selection": ["d3-selection@3.0.0", "", {}, "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="],
|
||||
|
||||
"d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
|
||||
|
||||
"d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
|
||||
|
||||
"d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
|
||||
|
||||
"d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
|
||||
|
||||
"d3-transition": ["d3-transition@3.0.1", "", { "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", "d3-ease": "1 - 3", "d3-interpolate": "1 - 3", "d3-timer": "1 - 3" }, "peerDependencies": { "d3-selection": "2 - 3" } }, "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="],
|
||||
|
||||
"d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="],
|
||||
|
||||
"dagre-d3-es": ["dagre-d3-es@7.0.14", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg=="],
|
||||
|
||||
"dayjs": ["dayjs@1.11.20", "", {}, "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"defuddle": ["defuddle@0.18.1", "", { "dependencies": { "commander": "^12.1.0" }, "optionalDependencies": { "linkedom": "^0.18.12", "mathml-to-latex": "^1.5.0", "temml": "^0.13.1", "turndown": "^7.2.0" }, "bin": { "defuddle": "dist/cli.js" } }, "sha512-AvFPFOsoDjt5xUOA1QxzafSSzJ5dqEIC63yO72tHYtSjj1DYY/XM0XTPUCsHkm5A2f1X9ulBvoSVFJrd4s2ckA=="],
|
||||
|
||||
"delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
|
@ -229,6 +382,8 @@
|
|||
|
||||
"entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="],
|
||||
|
||||
"es-toolkit": ["es-toolkit@1.46.1", "", {}, "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ=="],
|
||||
|
||||
"esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
|
||||
|
||||
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
|
||||
|
|
@ -239,34 +394,48 @@
|
|||
|
||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
|
||||
"hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="],
|
||||
|
||||
"html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="],
|
||||
|
||||
"html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
|
||||
|
||||
"htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="],
|
||||
|
||||
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"import-meta-resolve": ["import-meta-resolve@4.2.0", "", {}, "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg=="],
|
||||
|
||||
"internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
|
||||
|
||||
"is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="],
|
||||
|
||||
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
|
||||
|
||||
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
|
||||
|
||||
"json-canvas-viewer": ["json-canvas-viewer@4.3.2", "", { "dependencies": { "@ahmedsemih/color-fns": "^1.3.0", "@needle-di/core": "^1.1.2", "dompurify": "^3.4.1", "marked": "^18.0.2", "pointeract": "^1.2.0" } }, "sha512-zCUHfD3jnvAsqmJvuENWxWEolSntmkp1cRRG8HNyfo2HGkfHMgzmaZfMkH/NMbC7Jj3cQ3l14zYj9rlXpPNX/Q=="],
|
||||
|
||||
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
|
||||
|
||||
"katex": ["katex@0.16.47", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg=="],
|
||||
|
||||
"khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="],
|
||||
|
||||
"layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="],
|
||||
|
||||
"linkedom": ["linkedom@0.18.12", "", { "dependencies": { "css-select": "^5.1.0", "cssom": "^0.5.0", "html-escaper": "^3.0.3", "htmlparser2": "^10.0.0", "uhyphen": "^0.2.0" }, "peerDependencies": { "canvas": ">= 2" }, "optionalPeers": ["canvas"] }, "sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q=="],
|
||||
|
||||
"lodash-es": ["lodash-es@4.18.1", "", {}, "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A=="],
|
||||
|
||||
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"marked": ["marked@18.0.4", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-c/BTaKzg0G6ezQx97DAkYU7k0HM6ys0FqYeKBL6hlBByZwy+ycA1+f0vDdjMHKKeEjdgkx0GOv9Il6D+85cOqA=="],
|
||||
"marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="],
|
||||
|
||||
"mathml-to-latex": ["mathml-to-latex@1.5.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.10" } }, "sha512-rrWn0eEvcEcdMM4xfHcSGIy+i01DX9byOdXTLWg+w1iJ6O6ohP5UXY1dVzNUZLhzfl3EGcRekWLhY7JT5Omaew=="],
|
||||
|
||||
"merge-anything": ["merge-anything@5.1.7", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="],
|
||||
|
||||
"mermaid": ["mermaid@11.15.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.1.1", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "es-toolkit": "^1.45.1", "katex": "^0.16.25", "khroma": "^2.1.0", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0 || ^12 || ^13 || ^14.0.0" } }, "sha512-pTMbcf3rWdtLiYGpmoTjHEpeY8seiy6sR+9nD7LOs8KfUbHE4lOUAprTRqRAcWSQ6MQpdX+YEsxShtGsINtPtw=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
|
||||
|
|
@ -275,18 +444,32 @@
|
|||
|
||||
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
|
||||
|
||||
"package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
|
||||
|
||||
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
|
||||
|
||||
"path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
|
||||
|
||||
"pointeract": ["pointeract@1.2.0", "", {}, "sha512-rmc1IoG+B+OyYoRibFwUgPqG28CYRpMaWQZPHdEnHLG6zrLC6ThduE5ss5FqxCPtUf6gw/WqmJ2D2gqD7T0vrg=="],
|
||||
"points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="],
|
||||
|
||||
"points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="],
|
||||
|
||||
"postcss": ["postcss@8.5.14", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg=="],
|
||||
|
||||
"robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
|
||||
|
||||
"rollup": ["rollup@4.60.4", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.4", "@rollup/rollup-android-arm64": "4.60.4", "@rollup/rollup-darwin-arm64": "4.60.4", "@rollup/rollup-darwin-x64": "4.60.4", "@rollup/rollup-freebsd-arm64": "4.60.4", "@rollup/rollup-freebsd-x64": "4.60.4", "@rollup/rollup-linux-arm-gnueabihf": "4.60.4", "@rollup/rollup-linux-arm-musleabihf": "4.60.4", "@rollup/rollup-linux-arm64-gnu": "4.60.4", "@rollup/rollup-linux-arm64-musl": "4.60.4", "@rollup/rollup-linux-loong64-gnu": "4.60.4", "@rollup/rollup-linux-loong64-musl": "4.60.4", "@rollup/rollup-linux-ppc64-gnu": "4.60.4", "@rollup/rollup-linux-ppc64-musl": "4.60.4", "@rollup/rollup-linux-riscv64-gnu": "4.60.4", "@rollup/rollup-linux-riscv64-musl": "4.60.4", "@rollup/rollup-linux-s390x-gnu": "4.60.4", "@rollup/rollup-linux-x64-gnu": "4.60.4", "@rollup/rollup-linux-x64-musl": "4.60.4", "@rollup/rollup-openbsd-x64": "4.60.4", "@rollup/rollup-openharmony-arm64": "4.60.4", "@rollup/rollup-win32-arm64-msvc": "4.60.4", "@rollup/rollup-win32-ia32-msvc": "4.60.4", "@rollup/rollup-win32-x64-gnu": "4.60.4", "@rollup/rollup-win32-x64-msvc": "4.60.4", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g=="],
|
||||
|
||||
"roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="],
|
||||
|
||||
"rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
|
||||
|
||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||
|
||||
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"seroval": ["seroval@1.5.4", "", {}, "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw=="],
|
||||
|
|
@ -299,12 +482,20 @@
|
|||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"stylis": ["stylis@4.4.0", "", {}, "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA=="],
|
||||
|
||||
"svg-pan-zoom": ["svg-pan-zoom@3.6.2", "", {}, "sha512-JwnvRWfVKw/Xzfe6jriFyfey/lWJLq4bUh2jwoR5ChWQuQoOH8FEh1l/bEp46iHHKHEJWIyFJETbazraxNWECg=="],
|
||||
|
||||
"temml": ["temml@0.13.3", "", {}, "sha512-GLNEdf5qBWux3adbOxFus4jlds8nCdEIkkKq99m/4GGTfqnsjlVlK/i371Ux7yYSg/WNmOyAkNT/GJlZoJ0v+w=="],
|
||||
|
||||
"three": ["three@0.184.0", "", {}, "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg=="],
|
||||
|
||||
"tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="],
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
|
||||
|
||||
"ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="],
|
||||
|
||||
"turndown": ["turndown@7.2.4", "", { "dependencies": { "@mixmark-io/domino": "^2.2.0" } }, "sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
|
@ -313,6 +504,8 @@
|
|||
|
||||
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
|
||||
|
||||
"uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="],
|
||||
|
||||
"vite": ["vite@6.4.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ=="],
|
||||
|
||||
"vite-plugin-solid": ["vite-plugin-solid@2.11.12", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-FgjPcx2OwX9h6f28jli7A4bG7PP3te8uyakE5iqsmpq3Jqi1TWLgSroC9N6cMfGRU2zXsl4Q6ISvTr2VL0QHpA=="],
|
||||
|
|
@ -323,10 +516,24 @@
|
|||
|
||||
"babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="],
|
||||
|
||||
"cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="],
|
||||
|
||||
"d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
|
||||
|
||||
"d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
|
||||
|
||||
"d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="],
|
||||
|
||||
"dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
|
||||
|
||||
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="],
|
||||
|
||||
"d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="],
|
||||
|
||||
"d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
{
|
||||
"id": "crafted",
|
||||
"title": "Crafted",
|
||||
"body": "Books are authored HTML with care: figures, interactives, and JSON Canvas where they help understanding — not generated slop or print PDFs pasted on the web. Quality is a deliberate choice on every page."
|
||||
"body": "Books are authored HTML with care: figures, interactives, and Mermaid maps where they help understanding — not generated slop or print PDFs pasted on the web. Quality is a deliberate choice on every page."
|
||||
},
|
||||
{
|
||||
"id": "inspectable",
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
{ "from": "deductive-geometry", "to": "circle-properties" },
|
||||
{ "from": "coordinate-circles", "to": "loci" },
|
||||
{ "from": "circle-properties", "to": "loci" },
|
||||
{ "from": "directed-numbers-rates", "to": "statistical-charts-averages" },
|
||||
{ "from": "statistical-charts-averages", "to": "measures-dispersion" },
|
||||
{ "from": "statistical-charts-averages", "to": "basic-probability" },
|
||||
{ "from": "basic-probability", "to": "permutations-combinations-probability" },
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { createMemo, createSignal, For, lazy, onCleanup, onMount, Show, Suspense } from "solid-js";
|
||||
import { subjectToCanvas } from "../lib/catalog-to-canvas";
|
||||
import { watchSiteTheme } from "../lib/catalog-canvas-theme";
|
||||
import { createMemo, createSignal, For, lazy, Show, Suspense } from "solid-js";
|
||||
import { subjectToMermaid } from "../lib/catalog-to-mermaid";
|
||||
import { CatalogChapterCard } from "./catalog-chapter-card";
|
||||
import { CatalogFiltersMenu } from "./catalog-filters-menu";
|
||||
import type {
|
||||
|
|
@ -11,8 +10,8 @@ import type {
|
|||
CatalogViewMode,
|
||||
} from "../../../data/catalog.types";
|
||||
|
||||
const CatalogCanvasView = lazy(() =>
|
||||
import("./catalog-canvas-view").then((m) => ({ default: m.CatalogCanvasView }))
|
||||
const CatalogMermaidView = lazy(() =>
|
||||
import("./catalog-mermaid-view").then((m) => ({ default: m.CatalogMermaidView }))
|
||||
);
|
||||
|
||||
function readCatalogData(): CatalogData | null {
|
||||
|
|
@ -66,16 +65,6 @@ export function CatalogApp() {
|
|||
const [currentSubjectId, setCurrentSubjectId] = createSignal(initialSubjectId(data.subjects));
|
||||
const [activeFilters, setActiveFilters] = createSignal<Set<string>>(new Set());
|
||||
const [viewMode, setViewMode] = createSignal<CatalogViewMode>(initialViewMode());
|
||||
const [canvasThemeTick, setCanvasThemeTick] = createSignal(0);
|
||||
const [mapLayoutReady, setMapLayoutReady] = createSignal(!document.fonts);
|
||||
|
||||
onMount(() => {
|
||||
const stopThemeWatch = watchSiteTheme(() => setCanvasThemeTick((tick) => tick + 1));
|
||||
if (document.fonts) {
|
||||
void document.fonts.ready.then(() => setMapLayoutReady(true));
|
||||
}
|
||||
onCleanup(stopThemeWatch);
|
||||
});
|
||||
|
||||
const currentSubject = createMemo(
|
||||
() => data.subjects.find((s) => s.id === currentSubjectId()) ?? data.subjects[0]
|
||||
|
|
@ -89,23 +78,9 @@ export function CatalogApp() {
|
|||
() => (chapter: CatalogChapter) => chapterMatchesFilters(chapter, activeFilters())
|
||||
);
|
||||
|
||||
const canvasData = createMemo(() => {
|
||||
canvasThemeTick();
|
||||
if (!mapLayoutReady()) return undefined;
|
||||
return subjectToCanvas(currentSubject(), chapterFilter());
|
||||
});
|
||||
|
||||
const visibleChapters = createMemo(() => {
|
||||
const map: Record<string, CatalogChapter> = {};
|
||||
for (const strand of currentSubject().strands) {
|
||||
for (const chapter of strand.chapters) {
|
||||
if (chapterFilter()(chapter)) {
|
||||
map[chapter.slug] = chapter;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
});
|
||||
const mermaidData = createMemo(() =>
|
||||
subjectToMermaid(currentSubject(), chapterFilter(), currentSubjectId())
|
||||
);
|
||||
|
||||
const statsLabel = createMemo(() => {
|
||||
const count = visibleCount();
|
||||
|
|
@ -253,7 +228,6 @@ export function CatalogApp() {
|
|||
chapter={chapter}
|
||||
index={index()}
|
||||
subjectId={currentSubjectId()}
|
||||
variant="list"
|
||||
/>
|
||||
</li>
|
||||
)}
|
||||
|
|
@ -264,20 +238,14 @@ export function CatalogApp() {
|
|||
</For>
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={canvasData()}
|
||||
fallback={<p class="catalog-canvas-loading">Loading chapter map…</p>}
|
||||
>
|
||||
{(canvas) => (
|
||||
<Suspense fallback={<p class="catalog-canvas-loading">Loading chapter map…</p>}>
|
||||
<CatalogCanvasView
|
||||
canvas={canvas()}
|
||||
subjectId={currentSubjectId()}
|
||||
chapters={visibleChapters()}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
</Show>
|
||||
<Suspense fallback={<p class="catalog-canvas-loading">Loading chapter map…</p>}>
|
||||
<Show
|
||||
when={mermaidData()}
|
||||
fallback={<p class="catalog-canvas-loading">Loading chapter map…</p>}
|
||||
>
|
||||
{(diagram) => <CatalogMermaidView diagram={diagram()} />}
|
||||
</Show>
|
||||
</Suspense>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,153 +0,0 @@
|
|||
import { createEffect, onCleanup, onMount } from "solid-js";
|
||||
import type {
|
||||
JSONCanvas,
|
||||
JSONCanvasTextNode,
|
||||
JSONCanvasViewerInterface,
|
||||
} from "json-canvas-viewer";
|
||||
import {
|
||||
JSONCanvasViewer,
|
||||
MistouchPreventer,
|
||||
Controls,
|
||||
Minimap,
|
||||
parser,
|
||||
} from "json-canvas-viewer";
|
||||
import type { CatalogChapter } from "../../../data/catalog.types";
|
||||
import { renderCatalogChapterCardElement } from "./catalog-chapter-card";
|
||||
import { chapterSlugFromNodeId } from "../lib/catalog-to-canvas";
|
||||
import {
|
||||
syncViewerTheme,
|
||||
VIEWER_THEME_COLORS,
|
||||
siteCanvasTheme,
|
||||
watchSiteTheme,
|
||||
} from "../lib/catalog-canvas-theme";
|
||||
import { focusReadableCatalogView } from "../lib/catalog-canvas-viewport";
|
||||
|
||||
type CatalogCanvasViewProps = {
|
||||
canvas: JSONCanvas;
|
||||
subjectId: string;
|
||||
chapters: Record<string, CatalogChapter>;
|
||||
};
|
||||
|
||||
function serializeCanvas(canvas: JSONCanvas): string {
|
||||
return JSON.stringify(canvas);
|
||||
}
|
||||
|
||||
function waitForLayout(el: HTMLElement): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
const check = () => {
|
||||
if (el.clientWidth >= 1 && el.clientHeight >= 1) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
requestAnimationFrame(check);
|
||||
};
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
function bindPageScrollWheel(container: HTMLElement): () => void {
|
||||
const onWheel = (event: WheelEvent) => {
|
||||
if (event.ctrlKey || event.metaKey) return;
|
||||
event.stopPropagation();
|
||||
};
|
||||
container.addEventListener("wheel", onWheel, { capture: true, passive: true });
|
||||
return () => container.removeEventListener("wheel", onWheel, { capture: true });
|
||||
}
|
||||
|
||||
function buildNodeComponents(
|
||||
subjectId: string,
|
||||
chapters: Record<string, CatalogChapter>
|
||||
) {
|
||||
return {
|
||||
text: ({
|
||||
container,
|
||||
node,
|
||||
}: {
|
||||
container: HTMLDivElement;
|
||||
node: JSONCanvasTextNode;
|
||||
}) => {
|
||||
const slug = chapterSlugFromNodeId(node.id);
|
||||
if (!slug) return;
|
||||
const chapter = chapters[slug];
|
||||
if (!chapter) return;
|
||||
container.replaceChildren();
|
||||
container.appendChild(renderCatalogChapterCardElement(chapter, subjectId, "map"));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function CatalogCanvasView(props: CatalogCanvasViewProps) {
|
||||
let container!: HTMLDivElement;
|
||||
let viewer: JSONCanvasViewerInterface | undefined;
|
||||
let lastSerialized = "";
|
||||
let loadGeneration = 0;
|
||||
let unbindWheel: (() => void) | undefined;
|
||||
|
||||
const chaptersKey = (chapters: Record<string, CatalogChapter>) =>
|
||||
JSON.stringify(
|
||||
Object.entries(chapters).map(([slug, ch]) => [slug, ch.title, ch.description, ch.status])
|
||||
);
|
||||
|
||||
const loadCanvas = async (canvas: JSONCanvas, chapters: Record<string, CatalogChapter>) => {
|
||||
const cacheKey = `${serializeCanvas(canvas)}|${chaptersKey(chapters)}`;
|
||||
if (!viewer || cacheKey === lastSerialized) return;
|
||||
|
||||
const generation = ++loadGeneration;
|
||||
|
||||
await waitForLayout(container);
|
||||
if (generation !== loadGeneration || !viewer) return;
|
||||
|
||||
lastSerialized = cacheKey;
|
||||
viewer.load({ canvas });
|
||||
syncViewerTheme(viewer);
|
||||
focusReadableCatalogView(viewer, container);
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
let stopThemeWatch: (() => void) | undefined;
|
||||
|
||||
unbindWheel = bindPageScrollWheel(container);
|
||||
|
||||
viewer = new JSONCanvasViewer(
|
||||
{
|
||||
container,
|
||||
parser,
|
||||
theme: siteCanvasTheme(),
|
||||
colors: VIEWER_THEME_COLORS,
|
||||
loading: "none",
|
||||
preventMistouchAtStart: false,
|
||||
mistouchPreventerBannerText: "Click the map to pan and zoom",
|
||||
minimapCollapsed: true,
|
||||
nodeComponents: buildNodeComponents(props.subjectId, props.chapters),
|
||||
},
|
||||
[MistouchPreventer, Controls, Minimap]
|
||||
);
|
||||
|
||||
stopThemeWatch = watchSiteTheme(() => syncViewerTheme(viewer));
|
||||
|
||||
void loadCanvas(props.canvas, props.chapters);
|
||||
|
||||
onCleanup(() => {
|
||||
loadGeneration += 1;
|
||||
stopThemeWatch?.();
|
||||
unbindWheel?.();
|
||||
unbindWheel = undefined;
|
||||
viewer?.dispose();
|
||||
viewer = undefined;
|
||||
lastSerialized = "";
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (!viewer) return;
|
||||
viewer.options.nodeComponents = buildNodeComponents(
|
||||
props.subjectId,
|
||||
props.chapters
|
||||
);
|
||||
void loadCanvas(props.canvas, props.chapters);
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={container} class="catalog-canvas-view" role="application" aria-label="Chapter map" />
|
||||
);
|
||||
}
|
||||
|
|
@ -6,153 +6,25 @@ export type CatalogChapterCardProps = {
|
|||
chapter: CatalogChapter;
|
||||
subjectId: string;
|
||||
index?: number;
|
||||
variant?: "list" | "map";
|
||||
};
|
||||
|
||||
function chapterHref(subjectId: string, slug: string): string {
|
||||
return `/${subjectId}/${slug}/`;
|
||||
}
|
||||
|
||||
function appendMeta(parent: HTMLElement, chapter: CatalogChapter) {
|
||||
const meta = document.createElement("div");
|
||||
meta.className = "catalog-chapter-card__meta";
|
||||
|
||||
for (const curriculum of chapter.curriculums) {
|
||||
const badge = document.createElement("span");
|
||||
badge.className = `catalog-badge ${curriculumBadgeClass(curriculum)}`;
|
||||
badge.textContent = curriculum;
|
||||
meta.appendChild(badge);
|
||||
}
|
||||
|
||||
const tierLabel = tierBadgeLabel(chapter.tier);
|
||||
if (tierLabel) {
|
||||
const tier = document.createElement("span");
|
||||
tier.className = "catalog-badge catalog-badge--extension";
|
||||
tier.textContent = tierLabel;
|
||||
meta.appendChild(tier);
|
||||
}
|
||||
|
||||
if (chapter.status === "planned") {
|
||||
const soon = document.createElement("span");
|
||||
soon.className = "book-chapter-badge book-chapter-badge--planned";
|
||||
soon.textContent = "Coming soon";
|
||||
meta.appendChild(soon);
|
||||
}
|
||||
|
||||
parent.appendChild(meta);
|
||||
}
|
||||
|
||||
function appendMapTitle(
|
||||
body: HTMLElement,
|
||||
chapter: CatalogChapter,
|
||||
subjectId: string
|
||||
) {
|
||||
const heading = document.createElement("h3");
|
||||
heading.className = "catalog-chapter-card__title";
|
||||
|
||||
if (chapter.status === "live") {
|
||||
const link = document.createElement("a");
|
||||
link.className = "catalog-chapter-card__title-link";
|
||||
link.href = chapterHref(subjectId, chapter.slug);
|
||||
link.addEventListener("click", (event) => event.stopPropagation());
|
||||
|
||||
const text = document.createElement("span");
|
||||
text.className = "catalog-chapter-card__title-text";
|
||||
text.textContent = chapter.title;
|
||||
|
||||
const arrow = document.createElement("span");
|
||||
arrow.className = "catalog-chapter-card__title-arrow";
|
||||
arrow.setAttribute("aria-hidden", "true");
|
||||
arrow.textContent = "→";
|
||||
|
||||
link.append(text, arrow);
|
||||
heading.appendChild(link);
|
||||
} else {
|
||||
heading.textContent = chapter.title;
|
||||
}
|
||||
|
||||
body.appendChild(heading);
|
||||
}
|
||||
|
||||
/** DOM builder for json-canvas-viewer `nodeComponents.text` (same markup/classes as list view). */
|
||||
export function renderCatalogChapterCardElement(
|
||||
chapter: CatalogChapter,
|
||||
subjectId: string,
|
||||
variant: "list" | "map" = "map"
|
||||
): HTMLElement {
|
||||
const root = document.createElement("div");
|
||||
root.className = [
|
||||
"catalog-chapter-card",
|
||||
variant === "map" ? "catalog-chapter-card--map" : "",
|
||||
chapter.status === "planned" ? "catalog-chapter-card--planned" : "",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
root.dataset.chapterSlug = chapter.slug;
|
||||
|
||||
const body = document.createElement("div");
|
||||
body.className = "catalog-chapter-card__body";
|
||||
|
||||
if (variant === "map") {
|
||||
appendMapTitle(body, chapter, subjectId);
|
||||
} else {
|
||||
const title = document.createElement("h3");
|
||||
title.className = "catalog-chapter-card__title";
|
||||
title.textContent = chapter.title;
|
||||
body.appendChild(title);
|
||||
}
|
||||
|
||||
if (chapter.description) {
|
||||
const description = document.createElement("p");
|
||||
description.className = "catalog-chapter-card__description";
|
||||
description.textContent = chapter.description;
|
||||
body.appendChild(description);
|
||||
}
|
||||
|
||||
appendMeta(body, chapter);
|
||||
root.appendChild(body);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
function MapChapterTitle(props: {
|
||||
chapter: CatalogChapter;
|
||||
subjectId: string;
|
||||
}) {
|
||||
return (
|
||||
<h3 class="catalog-chapter-card__title">
|
||||
<Show
|
||||
when={props.chapter.status === "live"}
|
||||
fallback={props.chapter.title}
|
||||
>
|
||||
<a class="catalog-chapter-card__title-link" href={chapterHref(props.subjectId, props.chapter.slug)}>
|
||||
<span class="catalog-chapter-card__title-text">{props.chapter.title}</span>
|
||||
<span class="catalog-chapter-card__title-arrow" aria-hidden="true">
|
||||
→
|
||||
</span>
|
||||
</a>
|
||||
</Show>
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
export function CatalogChapterCard(props: CatalogChapterCardProps) {
|
||||
const variant = () => props.variant ?? "list";
|
||||
const href = () => chapterHref(props.subjectId, props.chapter.slug);
|
||||
const number = () =>
|
||||
props.index === undefined ? undefined : String(props.index + 1).padStart(2, "0");
|
||||
|
||||
const inner = (
|
||||
<div class="catalog-chapter-card__body">
|
||||
<Show when={variant() === "list" && number()}>
|
||||
<Show when={number()}>
|
||||
<div class="catalog-chapter-card__main">
|
||||
<span class="catalog-chapter-card__number">{number()}</span>
|
||||
<h3 class="catalog-chapter-card__title">{props.chapter.title}</h3>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={variant() === "map"}>
|
||||
<MapChapterTitle chapter={props.chapter} subjectId={props.subjectId} />
|
||||
</Show>
|
||||
<Show when={props.chapter.description}>
|
||||
<p class="catalog-chapter-card__description">{props.chapter.description}</p>
|
||||
</Show>
|
||||
|
|
@ -174,25 +46,17 @@ export function CatalogChapterCard(props: CatalogChapterCardProps) {
|
|||
|
||||
return (
|
||||
<Show
|
||||
when={props.chapter.status === "live" && variant() === "list"}
|
||||
when={props.chapter.status === "live"}
|
||||
fallback={
|
||||
<div
|
||||
class="catalog-chapter-card"
|
||||
classList={{
|
||||
"catalog-chapter-card--map": variant() === "map",
|
||||
"catalog-chapter-card--planned": props.chapter.status === "planned",
|
||||
}}
|
||||
class="catalog-chapter-card catalog-chapter-card--planned"
|
||||
data-chapter-slug={props.chapter.slug}
|
||||
>
|
||||
{inner}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<a
|
||||
class="catalog-chapter-card"
|
||||
href={href()}
|
||||
data-chapter-slug={props.chapter.slug}
|
||||
>
|
||||
<a class="catalog-chapter-card" href={href()} data-chapter-slug={props.chapter.slug}>
|
||||
{inner}
|
||||
</a>
|
||||
</Show>
|
||||
|
|
|
|||
161
frontend/src/components/catalog-mermaid-view.tsx
Normal file
161
frontend/src/components/catalog-mermaid-view.tsx
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
import { createEffect, onCleanup, onMount } from "solid-js";
|
||||
import type { MermaidCatalogDiagram } from "../lib/catalog-to-mermaid";
|
||||
import { siteCanvasTheme, watchSiteTheme } from "../lib/catalog-canvas-theme";
|
||||
|
||||
type CatalogMermaidViewProps = {
|
||||
diagram: MermaidCatalogDiagram;
|
||||
};
|
||||
|
||||
type MermaidModule = typeof import("mermaid");
|
||||
type SvgPanZoomModule = typeof import("svg-pan-zoom")["default"];
|
||||
|
||||
export function CatalogMermaidView(props: CatalogMermaidViewProps) {
|
||||
let container!: HTMLDivElement;
|
||||
|
||||
let panZoom: SvgPanZoom.Instance | undefined;
|
||||
let resizeObserver: ResizeObserver | undefined;
|
||||
let renderGeneration = 0;
|
||||
let lastSource = "";
|
||||
let lastTheme: "light" | "dark" = siteCanvasTheme();
|
||||
let mermaidModule: MermaidModule["default"] | undefined;
|
||||
let svgPanZoomModule: SvgPanZoomModule | undefined;
|
||||
|
||||
const disposePanZoom = () => {
|
||||
panZoom?.destroy();
|
||||
panZoom = undefined;
|
||||
};
|
||||
|
||||
const ensureModules = async () => {
|
||||
if (!mermaidModule || !svgPanZoomModule) {
|
||||
const [{ default: mermaid }, { default: svgPanZoom }] = await Promise.all([
|
||||
import("mermaid"),
|
||||
import("svg-pan-zoom"),
|
||||
]);
|
||||
mermaidModule = mermaid;
|
||||
svgPanZoomModule = svgPanZoom;
|
||||
}
|
||||
};
|
||||
|
||||
const renderDiagram = async () => {
|
||||
const source = props.diagram.source;
|
||||
const theme = siteCanvasTheme();
|
||||
if (!container || (source === lastSource && theme === lastTheme)) return;
|
||||
lastSource = source;
|
||||
lastTheme = theme;
|
||||
|
||||
const generation = ++renderGeneration;
|
||||
disposePanZoom();
|
||||
|
||||
await ensureModules();
|
||||
if (generation !== renderGeneration || !mermaidModule || !svgPanZoomModule) return;
|
||||
|
||||
mermaidModule.initialize({
|
||||
startOnLoad: false,
|
||||
securityLevel: "loose",
|
||||
theme: theme === "dark" ? "dark" : "default",
|
||||
flowchart: {
|
||||
htmlLabels: true,
|
||||
curve: "monotoneY",
|
||||
nodeSpacing: 70,
|
||||
rankSpacing: 95,
|
||||
},
|
||||
});
|
||||
|
||||
const { svg, bindFunctions } = await mermaidModule.render(
|
||||
`catalog-mermaid-${generation}`,
|
||||
source
|
||||
);
|
||||
if (generation !== renderGeneration) return;
|
||||
|
||||
container.innerHTML = svg;
|
||||
bindFunctions?.(container);
|
||||
|
||||
const renderedSvg = container.querySelector<SVGSVGElement>("svg");
|
||||
if (!renderedSvg) return;
|
||||
renderedSvg.classList.add("catalog-mermaid-view__svg");
|
||||
renderedSvg.removeAttribute("style");
|
||||
renderedSvg.style.height = "100%";
|
||||
renderedSvg.style.width = "100%";
|
||||
|
||||
panZoom = svgPanZoomModule(renderedSvg, {
|
||||
zoomEnabled: true,
|
||||
panEnabled: true,
|
||||
controlIconsEnabled: false,
|
||||
fit: true,
|
||||
center: true,
|
||||
minZoom: 0.3,
|
||||
maxZoom: 8,
|
||||
dblClickZoomEnabled: true,
|
||||
mouseWheelZoomEnabled: true,
|
||||
});
|
||||
|
||||
panZoom.resize();
|
||||
panZoom.fit();
|
||||
panZoom.center();
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
void renderDiagram();
|
||||
|
||||
const stopThemeWatch = watchSiteTheme(() => {
|
||||
void renderDiagram();
|
||||
});
|
||||
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
panZoom?.resize();
|
||||
panZoom?.fit();
|
||||
panZoom?.center();
|
||||
});
|
||||
resizeObserver.observe(container);
|
||||
|
||||
onCleanup(() => {
|
||||
renderGeneration += 1;
|
||||
stopThemeWatch();
|
||||
resizeObserver?.disconnect();
|
||||
resizeObserver = undefined;
|
||||
disposePanZoom();
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
props.diagram.source;
|
||||
void renderDiagram();
|
||||
});
|
||||
|
||||
const resetView = () => {
|
||||
if (!panZoom) return;
|
||||
panZoom.reset();
|
||||
panZoom.fit();
|
||||
panZoom.center();
|
||||
};
|
||||
|
||||
const zoomIn = () => {
|
||||
panZoom?.zoomIn();
|
||||
};
|
||||
|
||||
const zoomOut = () => {
|
||||
panZoom?.zoomOut();
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="catalog-mermaid-stage">
|
||||
<div
|
||||
ref={container}
|
||||
class="catalog-mermaid-view"
|
||||
role="application"
|
||||
aria-label="Chapter map (Mermaid)"
|
||||
/>
|
||||
<div class="catalog-mermaid-controls">
|
||||
<button type="button" class="catalog-mermaid-controls__btn" onClick={zoomOut}>
|
||||
Zoom out
|
||||
</button>
|
||||
<button type="button" class="catalog-mermaid-controls__btn" onClick={zoomIn}>
|
||||
Zoom in
|
||||
</button>
|
||||
<button type="button" class="catalog-mermaid-controls__btn" onClick={resetView}>
|
||||
Reset view
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,21 +1,3 @@
|
|||
import type { JSONCanvasViewerInterface } from "json-canvas-viewer";
|
||||
|
||||
/** Node/edge colors (hex) aligned with OFB tokens in _tokens.scss */
|
||||
export const CANVAS_NODE = {
|
||||
groupBorder: "#9a6b2e",
|
||||
live: "#9a6b2e",
|
||||
planned: "#8f8a80",
|
||||
/** 8-digit hex — json-canvas-viewer only accepts hex for node/edge colors */
|
||||
edge: "#9a6b2e66",
|
||||
} as const;
|
||||
|
||||
export const CANVAS_NODE_DARK = {
|
||||
groupBorder: "#c4924a",
|
||||
live: "#c4924a",
|
||||
planned: "#8f8a80",
|
||||
edge: "#c4924a73",
|
||||
} as const;
|
||||
|
||||
export function siteCanvasTheme(): "light" | "dark" {
|
||||
if (typeof document === "undefined") return "light";
|
||||
const attr = document.documentElement.getAttribute("data-theme");
|
||||
|
|
@ -23,26 +5,6 @@ export function siteCanvasTheme(): "light" | "dark" {
|
|||
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
}
|
||||
|
||||
/** Passed to JSONCanvasViewer `colors` option (named theme tokens). */
|
||||
export const VIEWER_THEME_COLORS = {
|
||||
light: {
|
||||
background: "#f5f4f1",
|
||||
"background-secondary": "#ffffff",
|
||||
border: "rgba(154, 107, 46, 0.22)",
|
||||
text: "#1a1a1a",
|
||||
dots: "rgba(26, 26, 26, 0.09)",
|
||||
shadow: "0 4px 18px rgba(20, 20, 20, 0.06)",
|
||||
},
|
||||
dark: {
|
||||
background: "#1a1917",
|
||||
"background-secondary": "#24221f",
|
||||
border: "rgba(196, 146, 74, 0.3)",
|
||||
text: "#eceae4",
|
||||
dots: "rgba(236, 234, 228, 0.07)",
|
||||
shadow: "0 4px 18px rgba(0, 0, 0, 0.28)",
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function watchSiteTheme(onChange: (theme: "light" | "dark") => void): () => void {
|
||||
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
const observer = new MutationObserver(() => onChange(siteCanvasTheme()));
|
||||
|
|
@ -61,11 +23,3 @@ export function watchSiteTheme(onChange: (theme: "light" | "dark") => void): ()
|
|||
media.removeEventListener("change", onMedia);
|
||||
};
|
||||
}
|
||||
|
||||
export function syncViewerTheme(viewer: JSONCanvasViewerInterface | undefined) {
|
||||
viewer?.changeTheme?.(siteCanvasTheme());
|
||||
}
|
||||
|
||||
export function canvasNodeColors(): typeof CANVAS_NODE | typeof CANVAS_NODE_DARK {
|
||||
return siteCanvasTheme() === "dark" ? CANVAS_NODE_DARK : CANVAS_NODE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
import { internal, type JSONCanvasViewerInterface } from "json-canvas-viewer";
|
||||
import { CHAPTER_NODE_WIDTH, STRAND_GAP_X } from "./catalog-to-canvas";
|
||||
|
||||
/** Roughly one strand column plus peek of the next — readable card text, not full board. */
|
||||
const READABLE_COLUMNS_IN_VIEW = 1.15;
|
||||
const MIN_READABLE_SCALE = 0.78;
|
||||
const MAX_READABLE_SCALE = 1.08;
|
||||
|
||||
export function focusReadableCatalogView(
|
||||
viewer: JSONCanvasViewerInterface,
|
||||
container: HTMLElement
|
||||
): void {
|
||||
const dm = viewer.container.get(internal.DataManager);
|
||||
const bounds = dm.data.nodeBounds;
|
||||
if (bounds.width <= 0 || bounds.height <= 0) return;
|
||||
|
||||
const viewportW = container.clientWidth;
|
||||
const viewportH = container.clientHeight;
|
||||
if (viewportW < 1 || viewportH < 1) return;
|
||||
|
||||
const columnSpan = CHAPTER_NODE_WIDTH + STRAND_GAP_X;
|
||||
const scaleByWidth = viewportW / (columnSpan * READABLE_COLUMNS_IN_VIEW);
|
||||
const scale = Math.min(MAX_READABLE_SCALE, Math.max(MIN_READABLE_SCALE, scaleByWidth));
|
||||
|
||||
const focusX = bounds.minX + Math.min(bounds.width * 0.28, columnSpan * 0.65);
|
||||
const focusY = bounds.minY + Math.min(bounds.height * 0.22, 280);
|
||||
|
||||
dm.data.scale = scale;
|
||||
dm.data.offsetX = viewportW / 2 - focusX * scale;
|
||||
dm.data.offsetY = viewportH / 2 - focusY * scale;
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
import type { CatalogChapter } from "../../../data/catalog.types";
|
||||
import { renderCatalogChapterCardElement } from "../components/catalog-chapter-card";
|
||||
|
||||
export const MAP_CARD_NODE_WIDTH = 300;
|
||||
|
||||
/** Slack for json-canvas-viewer overlay rounding and border. */
|
||||
const MAP_NODE_HEIGHT_FUDGE = 10;
|
||||
|
||||
let measureHost: HTMLElement | null = null;
|
||||
|
||||
function getMeasureHost(): HTMLElement {
|
||||
if (!measureHost) {
|
||||
const host = document.createElement("div");
|
||||
host.className = "catalog-canvas catalog-map-measure-host";
|
||||
host.setAttribute("aria-hidden", "true");
|
||||
Object.assign(host.style, {
|
||||
position: "fixed",
|
||||
left: "-10000px",
|
||||
top: "0",
|
||||
opacity: "0",
|
||||
pointerEvents: "none",
|
||||
overflow: "visible",
|
||||
});
|
||||
document.body.appendChild(host);
|
||||
measureHost = host;
|
||||
}
|
||||
return measureHost;
|
||||
}
|
||||
|
||||
function measureCardInShell(card: HTMLElement, nodeWidth: number): number {
|
||||
const shell = document.createElement("div");
|
||||
shell.className = "catalog-map-measure-shell";
|
||||
shell.style.width = `${nodeWidth}px`;
|
||||
card.style.width = "100%";
|
||||
shell.appendChild(card);
|
||||
getMeasureHost().replaceChildren(shell);
|
||||
return Math.ceil(card.scrollHeight) + MAP_NODE_HEIGHT_FUDGE;
|
||||
}
|
||||
|
||||
/** Measure every visible chapter card (same markup as the map). */
|
||||
export function measureAllMapChapterCardHeights(
|
||||
visible: Map<string, CatalogChapter>,
|
||||
nodeWidth: number,
|
||||
subjectId: string
|
||||
): Map<string, number> {
|
||||
const heights = new Map<string, number>();
|
||||
if (typeof document === "undefined") {
|
||||
for (const [slug] of visible) {
|
||||
heights.set(slug, 200);
|
||||
}
|
||||
return heights;
|
||||
}
|
||||
|
||||
for (const [slug, chapter] of visible) {
|
||||
const card = renderCatalogChapterCardElement(chapter, subjectId, "map");
|
||||
heights.set(slug, measureCardInShell(card, nodeWidth));
|
||||
}
|
||||
|
||||
return heights;
|
||||
}
|
||||
|
||||
/** Heights from cards already mounted in the canvas viewer (ground truth). */
|
||||
export function measureRenderedMapChapterCards(container: HTMLElement): Map<string, number> {
|
||||
const heights = new Map<string, number>();
|
||||
for (const card of container.querySelectorAll<HTMLElement>(".catalog-chapter-card--map")) {
|
||||
const slug = card.dataset.chapterSlug;
|
||||
if (!slug) continue;
|
||||
const measured = Math.ceil(card.scrollHeight) + MAP_NODE_HEIGHT_FUDGE;
|
||||
const prev = heights.get(slug) ?? 0;
|
||||
heights.set(slug, Math.max(prev, measured));
|
||||
}
|
||||
return heights;
|
||||
}
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import type { JSONCanvas } from "json-canvas-viewer";
|
||||
import type {
|
||||
CatalogChapter,
|
||||
CatalogGraphEdge,
|
||||
CatalogSubject,
|
||||
} from "../../../data/catalog.types";
|
||||
import {
|
||||
CHAPTER_NODE_WIDTH,
|
||||
chapterNodeId,
|
||||
chapterSlugFromNodeId,
|
||||
relayoutCanvasChapterHeights,
|
||||
subjectToCanvas,
|
||||
} from "./catalog-to-canvas";
|
||||
|
||||
const GAP_Y = 48;
|
||||
|
||||
function chapter(
|
||||
slug: string,
|
||||
overrides: Partial<CatalogChapter> = {}
|
||||
): CatalogChapter {
|
||||
return {
|
||||
slug,
|
||||
title: slug,
|
||||
description: "Test chapter description for layout.",
|
||||
status: "planned",
|
||||
curriculums: ["DSE"],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function miniSubject(chapters: CatalogChapter[], edges: CatalogGraphEdge[] = []): CatalogSubject {
|
||||
return {
|
||||
id: "math",
|
||||
name: "Mathematics",
|
||||
strands: [
|
||||
{
|
||||
id: "number-algebra",
|
||||
title: "Number & Algebra",
|
||||
chapters,
|
||||
},
|
||||
],
|
||||
graph: { edges },
|
||||
};
|
||||
}
|
||||
|
||||
function textNode(canvas: JSONCanvas, slug: string) {
|
||||
return (canvas.nodes ?? []).find((node) => node.id === chapterNodeId(slug) && node.type === "text");
|
||||
}
|
||||
|
||||
function bottomY(node: { y: number; height?: number }) {
|
||||
return node.y + (node.height ?? 0);
|
||||
}
|
||||
|
||||
describe("chapterNodeId", () => {
|
||||
test("maps slug to node id and back", () => {
|
||||
expect(chapterNodeId("quadratic-equations")).toBe("chapter-quadratic-equations");
|
||||
expect(chapterSlugFromNodeId("chapter-quadratic-equations")).toBe("quadratic-equations");
|
||||
expect(chapterSlugFromNodeId("group-strand")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("subjectToCanvas", () => {
|
||||
test("returns null when no chapters match filter", () => {
|
||||
const subject = miniSubject([chapter("a")]);
|
||||
expect(subjectToCanvas(subject, () => false)).toBeNull();
|
||||
});
|
||||
|
||||
test("uses only explicit graph edges (no implicit strand chain)", () => {
|
||||
const subject = miniSubject(
|
||||
[chapter("first"), chapter("second")],
|
||||
[]
|
||||
);
|
||||
const canvas = subjectToCanvas(subject, () => true);
|
||||
expect(canvas?.edges ?? []).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("assigns longest-path levels on y axis", () => {
|
||||
const subject = miniSubject(
|
||||
[chapter("a"), chapter("b"), chapter("c")],
|
||||
[
|
||||
{ from: "a", to: "b" },
|
||||
{ from: "b", to: "c" },
|
||||
]
|
||||
);
|
||||
const canvas = subjectToCanvas(subject, () => true)!;
|
||||
const a = textNode(canvas, "a")!;
|
||||
const b = textNode(canvas, "b")!;
|
||||
const c = textNode(canvas, "c")!;
|
||||
|
||||
expect(b.y).toBeGreaterThan(bottomY(a));
|
||||
expect(c.y).toBeGreaterThan(bottomY(b));
|
||||
});
|
||||
|
||||
test("stacks siblings that share a level in one column", () => {
|
||||
const subject = miniSubject(
|
||||
[chapter("alpha"), chapter("beta"), chapter("merge")],
|
||||
[
|
||||
{ from: "alpha", to: "merge" },
|
||||
{ from: "beta", to: "merge" },
|
||||
]
|
||||
);
|
||||
const canvas = subjectToCanvas(subject, () => true)!;
|
||||
const alpha = textNode(canvas, "alpha")!;
|
||||
const beta = textNode(canvas, "beta")!;
|
||||
const merge = textNode(canvas, "merge")!;
|
||||
|
||||
expect(alpha.x).toBe(beta.x);
|
||||
expect(beta.y).toBeGreaterThanOrEqual(bottomY(alpha) + GAP_Y);
|
||||
expect(merge.y).toBeGreaterThan(bottomY(alpha));
|
||||
expect(merge.y).toBeGreaterThan(bottomY(beta));
|
||||
});
|
||||
|
||||
test("places strand columns at increasing x", () => {
|
||||
const subject: CatalogSubject = {
|
||||
id: "math",
|
||||
name: "Mathematics",
|
||||
strands: [
|
||||
{
|
||||
id: "number-algebra",
|
||||
title: "Number & Algebra",
|
||||
chapters: [chapter("na")],
|
||||
},
|
||||
{
|
||||
id: "data-handling",
|
||||
title: "Data Handling",
|
||||
chapters: [chapter("dh")],
|
||||
},
|
||||
],
|
||||
graph: { edges: [] },
|
||||
};
|
||||
const canvas = subjectToCanvas(subject, () => true)!;
|
||||
const na = textNode(canvas, "na")!;
|
||||
const dh = textNode(canvas, "dh")!;
|
||||
|
||||
expect(dh.x).toBeGreaterThan(na.x);
|
||||
expect(dh.x - na.x).toBeGreaterThanOrEqual(CHAPTER_NODE_WIDTH);
|
||||
});
|
||||
|
||||
test("throws when the graph has a cycle", () => {
|
||||
const subject = miniSubject(
|
||||
[chapter("a"), chapter("b"), chapter("c")],
|
||||
[
|
||||
{ from: "a", to: "b" },
|
||||
{ from: "b", to: "c" },
|
||||
{ from: "c", to: "a" },
|
||||
]
|
||||
);
|
||||
expect(() => subjectToCanvas(subject, () => true)).toThrow(/cycle/i);
|
||||
});
|
||||
});
|
||||
|
||||
describe("relayoutCanvasChapterHeights", () => {
|
||||
test("handles canvas with undefined nodes and edges", () => {
|
||||
expect(relayoutCanvasChapterHeights({}, new Map())).toBeNull();
|
||||
});
|
||||
|
||||
test("returns null when layout unchanged", () => {
|
||||
const subject = miniSubject([chapter("solo")], []);
|
||||
const canvas = subjectToCanvas(subject, () => true)!;
|
||||
const node = textNode(canvas, "solo")!;
|
||||
const heights = new Map([["solo", node.height ?? 0]]);
|
||||
expect(relayoutCanvasChapterHeights(canvas, heights)).toBeNull();
|
||||
});
|
||||
|
||||
test("bumps y when a taller height is supplied for a sibling stack", () => {
|
||||
const subject = miniSubject(
|
||||
[chapter("top"), chapter("bottom")],
|
||||
[]
|
||||
);
|
||||
const canvas = subjectToCanvas(subject, () => true)!;
|
||||
const top = textNode(canvas, "top")!;
|
||||
const bottom = textNode(canvas, "bottom")!;
|
||||
|
||||
const firstSlug = top.y <= bottom.y ? "top" : "bottom";
|
||||
const secondSlug = firstSlug === "top" ? "bottom" : "top";
|
||||
const first = textNode(canvas, firstSlug)!;
|
||||
const second = textNode(canvas, secondSlug)!;
|
||||
|
||||
const taller = (first.height ?? 0) + 80;
|
||||
const fitted = relayoutCanvasChapterHeights(
|
||||
canvas,
|
||||
new Map([
|
||||
[firstSlug, taller],
|
||||
[secondSlug, second.height ?? 0],
|
||||
])
|
||||
);
|
||||
|
||||
expect(fitted).not.toBeNull();
|
||||
const moved = textNode(fitted!, secondSlug)!;
|
||||
expect(moved.y).toBeGreaterThanOrEqual(first.y + taller + GAP_Y);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,419 +0,0 @@
|
|||
import type { JSONCanvas, JSONCanvasEdge, JSONCanvasNode } from "json-canvas-viewer";
|
||||
import type {
|
||||
CatalogChapter,
|
||||
CatalogGraphEdge,
|
||||
CatalogSubject,
|
||||
} from "../../../data/catalog.types";
|
||||
import { canvasNodeColors } from "./catalog-canvas-theme";
|
||||
import { measureAllMapChapterCardHeights } from "./catalog-chapter-card-layout";
|
||||
|
||||
export const CHAPTER_NODE_WIDTH = 300;
|
||||
/** Horizontal gap between strand columns (groups must not overlap). */
|
||||
export const STRAND_GAP_X = 112;
|
||||
const GAP_Y = 48;
|
||||
const GROUP_PAD = 28;
|
||||
|
||||
export function chapterNodeId(slug: string): string {
|
||||
return `chapter-${slug}`;
|
||||
}
|
||||
|
||||
export function chapterSlugFromNodeId(nodeId: string): string | null {
|
||||
return nodeId.startsWith("chapter-") ? nodeId.slice("chapter-".length) : null;
|
||||
}
|
||||
|
||||
function strandGroupId(strandId: string): string {
|
||||
return `strand-${strandId}`;
|
||||
}
|
||||
|
||||
function collectVisibleChapters(
|
||||
subject: CatalogSubject,
|
||||
matches: (chapter: CatalogChapter) => boolean
|
||||
): Map<string, CatalogChapter> {
|
||||
const map = new Map<string, CatalogChapter>();
|
||||
for (const strand of subject.strands) {
|
||||
for (const chapter of strand.chapters) {
|
||||
if (matches(chapter)) {
|
||||
map.set(chapter.slug, chapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
function buildEdgeList(
|
||||
subject: CatalogSubject,
|
||||
visible: Map<string, CatalogChapter>
|
||||
): CatalogGraphEdge[] {
|
||||
const seen = new Set<string>();
|
||||
const edges: CatalogGraphEdge[] = [];
|
||||
|
||||
const add = (from: string, to: string, label?: string) => {
|
||||
if (!visible.has(from) || !visible.has(to)) return;
|
||||
const key = `${from}->${to}`;
|
||||
if (seen.has(key)) return;
|
||||
seen.add(key);
|
||||
edges.push({ from, to, label });
|
||||
};
|
||||
|
||||
for (const edge of subject.graph?.edges ?? []) {
|
||||
add(edge.from, edge.to, edge.label);
|
||||
}
|
||||
|
||||
return edges;
|
||||
}
|
||||
|
||||
function assertAcyclic(edges: CatalogGraphEdge[], slugs: Iterable<string>): void {
|
||||
const nodes = new Set(slugs);
|
||||
const adj = new Map<string, string[]>();
|
||||
for (const slug of nodes) {
|
||||
adj.set(slug, []);
|
||||
}
|
||||
for (const { from, to } of edges) {
|
||||
adj.get(from)?.push(to);
|
||||
}
|
||||
|
||||
const visiting = new Set<string>();
|
||||
const visited = new Set<string>();
|
||||
|
||||
const visit = (node: string) => {
|
||||
if (visited.has(node)) return;
|
||||
if (visiting.has(node)) {
|
||||
throw new Error(`Catalog graph has a cycle involving "${node}"`);
|
||||
}
|
||||
visiting.add(node);
|
||||
for (const next of adj.get(node) ?? []) {
|
||||
visit(next);
|
||||
}
|
||||
visiting.delete(node);
|
||||
visited.add(node);
|
||||
};
|
||||
|
||||
for (const node of nodes) {
|
||||
visit(node);
|
||||
}
|
||||
}
|
||||
|
||||
/** Longest-path rank: level(to) >= level(from) + 1 for every required edge; roots at 0. */
|
||||
function assignLevels(edges: CatalogGraphEdge[], slugs: string[]): Map<string, number> {
|
||||
const levels = new Map<string, number>();
|
||||
for (const slug of slugs) {
|
||||
levels.set(slug, 0);
|
||||
}
|
||||
|
||||
for (let pass = 0; pass < slugs.length; pass++) {
|
||||
let changed = false;
|
||||
for (const { from, to } of edges) {
|
||||
const next = (levels.get(from) ?? 0) + 1;
|
||||
if (next > (levels.get(to) ?? 0)) {
|
||||
levels.set(to, next);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (!changed) break;
|
||||
}
|
||||
|
||||
return levels;
|
||||
}
|
||||
|
||||
function yOffsetInColumn(level: number, levelRowHeights: Map<number, number>): number {
|
||||
let y = 0;
|
||||
for (let l = 0; l < level; l++) {
|
||||
y += (levelRowHeights.get(l) ?? 0) + GAP_Y;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
type ChapterLayoutSlot = {
|
||||
slug: string;
|
||||
columnX: number;
|
||||
level: number;
|
||||
height: number;
|
||||
sortIndex: number;
|
||||
};
|
||||
|
||||
/** Stack chapters that share a level within one strand column (avoids overlapping cards). */
|
||||
function layoutChapterPositions(
|
||||
slots: ChapterLayoutSlot[]
|
||||
): Map<string, { x: number; y: number; height: number }> {
|
||||
const byColumn = new Map<number, ChapterLayoutSlot[]>();
|
||||
for (const slot of slots) {
|
||||
const column = byColumn.get(slot.columnX) ?? [];
|
||||
column.push(slot);
|
||||
byColumn.set(slot.columnX, column);
|
||||
}
|
||||
|
||||
const positions = new Map<string, { x: number; y: number; height: number }>();
|
||||
|
||||
for (const [columnX, columnSlots] of byColumn) {
|
||||
const byLevel = new Map<number, ChapterLayoutSlot[]>();
|
||||
for (const slot of columnSlots) {
|
||||
const levelSlots = byLevel.get(slot.level) ?? [];
|
||||
levelSlots.push(slot);
|
||||
byLevel.set(slot.level, levelSlots);
|
||||
}
|
||||
|
||||
const levelRowHeights = new Map<number, number>();
|
||||
for (const [level, levelSlots] of byLevel) {
|
||||
levelSlots.sort((a, b) => a.sortIndex - b.sortIndex);
|
||||
let rowHeight = 0;
|
||||
for (let i = 0; i < levelSlots.length; i++) {
|
||||
rowHeight += levelSlots[i].height;
|
||||
if (i < levelSlots.length - 1) rowHeight += GAP_Y;
|
||||
}
|
||||
levelRowHeights.set(level, rowHeight);
|
||||
}
|
||||
|
||||
for (const [level, levelSlots] of byLevel) {
|
||||
levelSlots.sort((a, b) => a.sortIndex - b.sortIndex);
|
||||
let y = yOffsetInColumn(level, levelRowHeights);
|
||||
for (const slot of levelSlots) {
|
||||
positions.set(slot.slug, { x: columnX, y, height: slot.height });
|
||||
y += slot.height + GAP_Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return positions;
|
||||
}
|
||||
|
||||
function buildStrandChapterOrder(subject: CatalogSubject): Map<string, number> {
|
||||
const order = new Map<string, number>();
|
||||
for (const strand of subject.strands) {
|
||||
strand.chapters.forEach((chapter, index) => {
|
||||
order.set(chapter.slug, index);
|
||||
});
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
function layoutNodes(
|
||||
subject: CatalogSubject,
|
||||
visible: Map<string, CatalogChapter>,
|
||||
edges: CatalogGraphEdge[]
|
||||
): JSONCanvasNode[] {
|
||||
const slugs = [...visible.keys()];
|
||||
const levels = assignLevels(edges, slugs);
|
||||
|
||||
const slugToStrandId = new Map<string, string>();
|
||||
const strandColumnX = new Map<string, number>();
|
||||
subject.strands.forEach((strand, index) => {
|
||||
strandColumnX.set(strand.id, index * (CHAPTER_NODE_WIDTH + STRAND_GAP_X));
|
||||
for (const chapter of strand.chapters) {
|
||||
slugToStrandId.set(chapter.slug, strand.id);
|
||||
}
|
||||
});
|
||||
|
||||
const heightBySlug = measureAllMapChapterCardHeights(
|
||||
visible,
|
||||
CHAPTER_NODE_WIDTH,
|
||||
subject.id
|
||||
);
|
||||
|
||||
const strandChapterOrder = buildStrandChapterOrder(subject);
|
||||
const slots: ChapterLayoutSlot[] = [];
|
||||
|
||||
for (const [slug] of visible) {
|
||||
const strandId = slugToStrandId.get(slug);
|
||||
const columnX = strandId ? (strandColumnX.get(strandId) ?? 0) : 0;
|
||||
slots.push({
|
||||
slug,
|
||||
columnX,
|
||||
level: levels.get(slug) ?? 0,
|
||||
height: heightBySlug.get(slug) ?? 0,
|
||||
sortIndex: strandChapterOrder.get(slug) ?? 0,
|
||||
});
|
||||
}
|
||||
|
||||
const positions = layoutChapterPositions(slots);
|
||||
|
||||
const groups: JSONCanvasNode[] = [];
|
||||
const nodes: JSONCanvasNode[] = [];
|
||||
const colors = canvasNodeColors();
|
||||
|
||||
for (const strand of subject.strands) {
|
||||
const strandSlugs = strand.chapters
|
||||
.map((ch) => ch.slug)
|
||||
.filter((slug) => visible.has(slug));
|
||||
if (strandSlugs.length === 0) continue;
|
||||
|
||||
let minX = Infinity;
|
||||
let minY = Infinity;
|
||||
let maxX = -Infinity;
|
||||
let maxY = -Infinity;
|
||||
|
||||
for (const slug of strandSlugs) {
|
||||
const pos = positions.get(slug);
|
||||
if (!pos) continue;
|
||||
minX = Math.min(minX, pos.x);
|
||||
minY = Math.min(minY, pos.y);
|
||||
maxX = Math.max(maxX, pos.x + CHAPTER_NODE_WIDTH);
|
||||
maxY = Math.max(maxY, pos.y + pos.height);
|
||||
}
|
||||
|
||||
if (!Number.isFinite(minX)) continue;
|
||||
|
||||
groups.push({
|
||||
id: strandGroupId(strand.id),
|
||||
type: "group",
|
||||
label: strand.title,
|
||||
x: minX - GROUP_PAD,
|
||||
y: minY - GROUP_PAD,
|
||||
width: maxX - minX + GROUP_PAD * 2,
|
||||
height: maxY - minY + GROUP_PAD * 2,
|
||||
color: colors.groupBorder,
|
||||
});
|
||||
}
|
||||
|
||||
for (const [slug, chapter] of visible) {
|
||||
const pos = positions.get(slug);
|
||||
if (!pos) continue;
|
||||
nodes.push({
|
||||
id: chapterNodeId(slug),
|
||||
type: "text",
|
||||
text: chapter.slug,
|
||||
x: pos.x,
|
||||
y: pos.y,
|
||||
width: CHAPTER_NODE_WIDTH,
|
||||
height: pos.height,
|
||||
color: chapter.status === "live" ? colors.live : colors.planned,
|
||||
});
|
||||
}
|
||||
|
||||
return [...groups, ...nodes];
|
||||
}
|
||||
|
||||
function toCanvasEdges(edgeList: CatalogGraphEdge[]): JSONCanvasEdge[] {
|
||||
const edgeColor = canvasNodeColors().edge;
|
||||
return edgeList.map((edge) => ({
|
||||
id: `edge-${edge.from}-${edge.to}`,
|
||||
fromNode: chapterNodeId(edge.from),
|
||||
toNode: chapterNodeId(edge.to),
|
||||
fromSide: "bottom",
|
||||
toSide: "top",
|
||||
toEnd: "arrow",
|
||||
label: edge.label,
|
||||
color: edgeColor,
|
||||
}));
|
||||
}
|
||||
|
||||
function edgesFromCanvas(canvas: JSONCanvas): CatalogGraphEdge[] {
|
||||
const edges: CatalogGraphEdge[] = [];
|
||||
for (const edge of canvas.edges ?? []) {
|
||||
const from = chapterSlugFromNodeId(edge.fromNode);
|
||||
const to = chapterSlugFromNodeId(edge.toNode);
|
||||
if (!from || !to) continue;
|
||||
edges.push({ from, to, label: edge.label });
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
/** Recompute chapter Y/height (and strand groups) after measuring rendered cards. */
|
||||
export function relayoutCanvasChapterHeights(
|
||||
canvas: JSONCanvas,
|
||||
heightBySlug: Map<string, number>
|
||||
): JSONCanvas | null {
|
||||
const canvasNodes = canvas.nodes ?? [];
|
||||
const chapterNodes = canvasNodes.filter(
|
||||
(node) => node.type === "text" && node.id.startsWith("chapter-")
|
||||
);
|
||||
if (chapterNodes.length === 0) return null;
|
||||
|
||||
const slugs = chapterNodes
|
||||
.map((node) => chapterSlugFromNodeId(node.id))
|
||||
.filter((slug): slug is string => Boolean(slug));
|
||||
const levels = assignLevels(edgesFromCanvas(canvas), slugs);
|
||||
|
||||
const mergedHeights = new Map<string, number>();
|
||||
for (const node of chapterNodes) {
|
||||
const slug = chapterSlugFromNodeId(node.id);
|
||||
if (!slug) continue;
|
||||
const measured = heightBySlug.get(slug);
|
||||
if (measured !== undefined) {
|
||||
mergedHeights.set(slug, measured);
|
||||
} else {
|
||||
mergedHeights.set(slug, node.height ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
const slots: ChapterLayoutSlot[] = chapterNodes.map((node, index) => {
|
||||
const slug = chapterSlugFromNodeId(node.id) ?? "";
|
||||
return {
|
||||
slug,
|
||||
columnX: node.x,
|
||||
level: levels.get(slug) ?? 0,
|
||||
height: mergedHeights.get(slug) ?? node.height ?? 0,
|
||||
sortIndex: node.y * 1000 + index,
|
||||
};
|
||||
});
|
||||
|
||||
const positions = layoutChapterPositions(slots);
|
||||
|
||||
let changed = false;
|
||||
const updatedChapters = chapterNodes.map((node) => {
|
||||
const slug = chapterSlugFromNodeId(node.id);
|
||||
if (!slug) return node;
|
||||
const pos = positions.get(slug);
|
||||
if (!pos) return node;
|
||||
const height = pos.height;
|
||||
if (pos.y !== node.y || height !== node.height) changed = true;
|
||||
return { ...node, y: pos.y, height };
|
||||
});
|
||||
|
||||
if (!changed) return null;
|
||||
|
||||
const chapterById = new Map(updatedChapters.map((node) => [node.id, node]));
|
||||
|
||||
let nodes = canvasNodes.map((node) => {
|
||||
if (node.type === "text" && node.id.startsWith("chapter-")) {
|
||||
return chapterById.get(node.id) ?? node;
|
||||
}
|
||||
return node;
|
||||
});
|
||||
|
||||
nodes = nodes.map((node) => {
|
||||
if (node.type !== "group") return node;
|
||||
const inGroup = updatedChapters.filter(
|
||||
(chapter) =>
|
||||
chapter.x + chapter.width / 2 >= node.x + GROUP_PAD &&
|
||||
chapter.x + chapter.width / 2 <= node.x + node.width - GROUP_PAD
|
||||
);
|
||||
if (inGroup.length === 0) return node;
|
||||
|
||||
let minX = Infinity;
|
||||
let minY = Infinity;
|
||||
let maxX = -Infinity;
|
||||
let maxY = -Infinity;
|
||||
for (const chapter of inGroup) {
|
||||
minX = Math.min(minX, chapter.x);
|
||||
minY = Math.min(minY, chapter.y);
|
||||
maxX = Math.max(maxX, chapter.x + chapter.width);
|
||||
maxY = Math.max(maxY, chapter.y + chapter.height);
|
||||
}
|
||||
|
||||
return {
|
||||
...node,
|
||||
x: minX - GROUP_PAD,
|
||||
y: minY - GROUP_PAD,
|
||||
width: maxX - minX + GROUP_PAD * 2,
|
||||
height: maxY - minY + GROUP_PAD * 2,
|
||||
};
|
||||
});
|
||||
|
||||
return { ...canvas, nodes };
|
||||
}
|
||||
|
||||
export function subjectToCanvas(
|
||||
subject: CatalogSubject,
|
||||
matches: (chapter: CatalogChapter) => boolean
|
||||
): JSONCanvas | null {
|
||||
const visible = collectVisibleChapters(subject, matches);
|
||||
if (visible.size === 0) return null;
|
||||
|
||||
const edgeList = buildEdgeList(subject, visible);
|
||||
assertAcyclic(edgeList, visible.keys());
|
||||
|
||||
return {
|
||||
nodes: layoutNodes(subject, visible, edgeList),
|
||||
edges: toCanvasEdges(edgeList),
|
||||
};
|
||||
}
|
||||
67
frontend/src/lib/catalog-to-mermaid.test.ts
Normal file
67
frontend/src/lib/catalog-to-mermaid.test.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import type { CatalogChapter, CatalogSubject } from "../../../data/catalog.types";
|
||||
import { subjectToMermaid } from "./catalog-to-mermaid";
|
||||
|
||||
function chapter(
|
||||
slug: string,
|
||||
overrides: Partial<CatalogChapter> = {}
|
||||
): CatalogChapter {
|
||||
return {
|
||||
slug,
|
||||
title: slug,
|
||||
description: "desc",
|
||||
status: "planned",
|
||||
curriculums: ["DSE"],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const subject: CatalogSubject = {
|
||||
id: "math",
|
||||
name: "Mathematics",
|
||||
strands: [
|
||||
{
|
||||
id: "strand-a",
|
||||
title: "Strand A",
|
||||
chapters: [
|
||||
chapter("a", { status: "live", title: "A" }),
|
||||
chapter("b", { status: "planned", title: "B" }),
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "strand-b",
|
||||
title: "Strand B",
|
||||
chapters: [chapter("c", { status: "live", title: "C" })],
|
||||
},
|
||||
],
|
||||
graph: {
|
||||
edges: [
|
||||
{ from: "a", to: "c" },
|
||||
{ from: "a", to: "c" },
|
||||
{ from: "b", to: "c", label: "after" },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe("subjectToMermaid", () => {
|
||||
test("returns null when no chapter is visible", () => {
|
||||
expect(subjectToMermaid(subject, () => false, "math")).toBeNull();
|
||||
});
|
||||
|
||||
test("builds diagram with deduped edges and live chapter links only", () => {
|
||||
const diagram = subjectToMermaid(subject, () => true, "math");
|
||||
expect(diagram).not.toBeNull();
|
||||
const source = diagram!.source;
|
||||
|
||||
expect(source).toContain("flowchart TB");
|
||||
expect(source.match(/chapter_a --> chapter_c/g)?.length).toBe(1);
|
||||
expect(source).toContain('chapter_b -->|after| chapter_c');
|
||||
expect(source).toContain('click chapter_a href "/math/a/"');
|
||||
expect(source).toContain('click chapter_c href "/math/c/"');
|
||||
expect(source).not.toContain('click chapter_b');
|
||||
expect(source).toContain("catalog-mermaid-node__title");
|
||||
expect(source).toContain("catalog-mermaid-node__description");
|
||||
expect(source).toContain("catalog-mermaid-node__meta");
|
||||
expect(source).toContain("catalog-badge--dse");
|
||||
});
|
||||
});
|
||||
136
frontend/src/lib/catalog-to-mermaid.ts
Normal file
136
frontend/src/lib/catalog-to-mermaid.ts
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
import type { CatalogChapter, CatalogGraphEdge, CatalogSubject } from "../../../data/catalog.types";
|
||||
import { curriculumBadgeClass, tierBadgeLabel } from "./catalog-badge";
|
||||
|
||||
export type MermaidCatalogDiagram = {
|
||||
source: string;
|
||||
};
|
||||
|
||||
function collectVisibleChapters(
|
||||
subject: CatalogSubject,
|
||||
matches: (chapter: CatalogChapter) => boolean
|
||||
): Map<string, CatalogChapter> {
|
||||
const visible = new Map<string, CatalogChapter>();
|
||||
for (const strand of subject.strands) {
|
||||
for (const chapter of strand.chapters) {
|
||||
if (matches(chapter)) {
|
||||
visible.set(chapter.slug, chapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
function buildEdgeList(
|
||||
subject: CatalogSubject,
|
||||
visible: Map<string, CatalogChapter>
|
||||
): CatalogGraphEdge[] {
|
||||
const dedup = new Set<string>();
|
||||
const edges: CatalogGraphEdge[] = [];
|
||||
for (const edge of subject.graph?.edges ?? []) {
|
||||
if (!visible.has(edge.from) || !visible.has(edge.to)) continue;
|
||||
const key = `${edge.from}->${edge.to}`;
|
||||
if (dedup.has(key)) continue;
|
||||
dedup.add(key);
|
||||
edges.push(edge);
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
function escapeLabel(text: string): string {
|
||||
return text
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">");
|
||||
}
|
||||
|
||||
function nodeId(slug: string): string {
|
||||
return `chapter_${slug.replaceAll(/[^a-zA-Z0-9_]/g, "_")}`;
|
||||
}
|
||||
|
||||
function classListNodeIds(
|
||||
visible: Map<string, CatalogChapter>,
|
||||
status: CatalogChapter["status"]
|
||||
): string[] {
|
||||
const ids: string[] = [];
|
||||
for (const [slug, chapter] of visible) {
|
||||
if (chapter.status === status) {
|
||||
ids.push(nodeId(slug));
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
function chapterNodeLabel(chapter: CatalogChapter): string {
|
||||
const title = `<h3 class='catalog-mermaid-node__title'>${escapeLabel(chapter.title)}</h3>`;
|
||||
const description = chapter.description
|
||||
? `<p class='catalog-mermaid-node__description'>${escapeLabel(chapter.description)}</p>`
|
||||
: "";
|
||||
const curriculumBadges = chapter.curriculums
|
||||
.map(
|
||||
(curriculum) =>
|
||||
`<span class='catalog-badge ${curriculumBadgeClass(curriculum)}'>${escapeLabel(curriculum)}</span>`
|
||||
)
|
||||
.join("");
|
||||
const tier = tierBadgeLabel(chapter.tier);
|
||||
const tierBadge = tier
|
||||
? `<span class='catalog-badge catalog-badge--extension'>${escapeLabel(tier)}</span>`
|
||||
: "";
|
||||
const planned =
|
||||
chapter.status === "planned"
|
||||
? "<span class='book-chapter-badge book-chapter-badge--planned'>Coming soon</span>"
|
||||
: "";
|
||||
const meta = `<div class='catalog-mermaid-node__meta'>${curriculumBadges}${tierBadge}${planned}</div>`;
|
||||
return `<div class='catalog-mermaid-node'>${title}${description}${meta}</div>`;
|
||||
}
|
||||
|
||||
export function subjectToMermaid(
|
||||
subject: CatalogSubject,
|
||||
matches: (chapter: CatalogChapter) => boolean,
|
||||
subjectId: string
|
||||
): MermaidCatalogDiagram | null {
|
||||
const visible = collectVisibleChapters(subject, matches);
|
||||
if (visible.size === 0) return null;
|
||||
|
||||
const edges = buildEdgeList(subject, visible);
|
||||
const lines: string[] = ["flowchart TB"];
|
||||
|
||||
for (const strand of subject.strands) {
|
||||
const strandChapters = strand.chapters.filter((chapter) => visible.has(chapter.slug));
|
||||
if (strandChapters.length === 0) continue;
|
||||
|
||||
lines.push(` subgraph strand_${strand.id.replaceAll(/[^a-zA-Z0-9_]/g, "_")}["${escapeLabel(strand.title)}"]`);
|
||||
lines.push(" direction TB");
|
||||
for (const chapter of strandChapters) {
|
||||
const id = nodeId(chapter.slug);
|
||||
const label = chapterNodeLabel(chapter);
|
||||
lines.push(` ${id}["${label}"]`);
|
||||
}
|
||||
lines.push(" end");
|
||||
}
|
||||
|
||||
for (const edge of edges) {
|
||||
const from = nodeId(edge.from);
|
||||
const to = nodeId(edge.to);
|
||||
const withLabel = edge.label ? `|${escapeLabel(edge.label)}|` : "";
|
||||
lines.push(` ${from} -->${withLabel} ${to}`);
|
||||
}
|
||||
|
||||
for (const [slug, chapter] of visible) {
|
||||
if (chapter.status !== "live") continue;
|
||||
lines.push(` click ${nodeId(slug)} href "/${subjectId}/${slug}/"`);
|
||||
}
|
||||
|
||||
const liveIds = classListNodeIds(visible, "live");
|
||||
const plannedIds = classListNodeIds(visible, "planned");
|
||||
if (liveIds.length) {
|
||||
lines.push(` class ${liveIds.join(",")} liveNode`);
|
||||
}
|
||||
if (plannedIds.length) {
|
||||
lines.push(` class ${plannedIds.join(",")} plannedNode`);
|
||||
}
|
||||
lines.push(" classDef liveNode stroke-width:2px;");
|
||||
lines.push(" classDef plannedNode stroke-dasharray: 5 3;");
|
||||
|
||||
return { source: lines.join("\n") };
|
||||
}
|
||||
|
|
@ -12,9 +12,10 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"defuddle": "^0.18.1",
|
||||
"json-canvas-viewer": "^4.3.2",
|
||||
"katex": "^0.16.47",
|
||||
"mermaid": "^11.15.0",
|
||||
"solid-js": "^1.9.5",
|
||||
"svg-pan-zoom": "^3.6.2",
|
||||
"three": "^0.184.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
4
spec.md
4
spec.md
|
|
@ -4,7 +4,7 @@ this project is free internet textbooks for elementary schools to university stu
|
|||
|
||||
this project is build using zola. interactivity by solid js. deployed to cloudflare.
|
||||
|
||||
canvas feature use [jsoncanvas](https://jsoncanvas.org/spec/1.0/) standard by Obsidian. Viewer is [JSON canvas viewer](https://github.com/Hesprs/JSON-Canvas-Viewer).
|
||||
catalog map feature uses Mermaid with pan and zoom interactions.
|
||||
|
||||
not markdown, html based. but in every page, we should have a copy as md button using [defuddle](https://github.com/kepano/defuddle).
|
||||
|
||||
|
|
@ -12,4 +12,4 @@ we don't i18n. i18n will be solved in future by big companies.
|
|||
|
||||
search is supported by pagefind.
|
||||
|
||||
we have a catalog of subjects. Each subject will have chapters. Each chapters can be labelled (multiple) cirriculum. E.g. DSE, IB, A level. so that user knows if a chapter is needed in a cirriculum. Each subject should show all chapters by default (all cirriculum). chapters should be sequential in a tree structure. users can filter by themselves. in the chapter we don't specify or mention the cirriculum anymore.
|
||||
we have a catalog of subjects. Each subject will have chapters. Each chapters can be labelled (multiple) cirriculum. E.g. DSE, IB, A level. so that user knows if a chapter is needed in a cirriculum. Each subject should show all chapters by default (all cirriculum). chapters should be sequential in a tree structure. users can filter by themselves. in the chapter we don't specify or mention the cirriculum anymore.
|
||||
|
|
|
|||
|
|
@ -358,108 +358,171 @@
|
|||
color: var(--muted);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Map canvas viewer
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
.catalog-canvas-view {
|
||||
.catalog-mermaid-stage {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
background: var(--paper);
|
||||
}
|
||||
|
||||
.catalog-mermaid-controls {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
z-index: 4;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.catalog-mermaid-controls__btn {
|
||||
border: 1px solid var(--card-border);
|
||||
border-radius: 8px;
|
||||
padding: 6px 10px;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
color: var(--ink);
|
||||
background: color-mix(in srgb, var(--paper) 88%, transparent);
|
||||
cursor: pointer;
|
||||
transition: border-color 180ms ease, color 180ms ease;
|
||||
|
||||
&:hover,
|
||||
&:focus-visible {
|
||||
border-color: var(--accent);
|
||||
color: var(--accent);
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.catalog-mermaid-view {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
border-radius: 0;
|
||||
background: var(--paper);
|
||||
overflow: hidden;
|
||||
background:
|
||||
radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--line) 55%, transparent) 1px, transparent 0)
|
||||
center / 16px 16px;
|
||||
|
||||
:global(.JSON-Canvas-Viewer) {
|
||||
border-radius: 0;
|
||||
:global(.catalog-mermaid-view__svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:global(.JCV-controls) {
|
||||
--jcv-control-bg: var(--card-bg);
|
||||
--jcv-control-border: var(--card-border);
|
||||
--jcv-control-fg: var(--ink);
|
||||
:global(svg[id^="catalog-mermaid-"]) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
:global(.JCV-markdown-content) {
|
||||
:global(.catalog-mermaid-view__svg .node rect),
|
||||
:global(.catalog-mermaid-view__svg .node polygon),
|
||||
:global(.catalog-mermaid-view__svg .cluster rect) {
|
||||
fill: color-mix(in srgb, var(--paper) 92%, transparent);
|
||||
stroke: color-mix(in srgb, var(--card-border) 88%, var(--line));
|
||||
stroke-width: 1.3px;
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-view__svg .cluster-label span),
|
||||
:global(.catalog-mermaid-view__svg .nodeLabel p),
|
||||
:global(.catalog-mermaid-view__svg .nodeLabel span) {
|
||||
color: var(--ink);
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.45;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
p + p {
|
||||
margin-top: 0.35rem;
|
||||
color: var(--muted);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
em {
|
||||
color: var(--muted);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:global(.JCV-minimap-container) {
|
||||
border-color: var(--card-border);
|
||||
background: var(--card-bg);
|
||||
:global(.catalog-mermaid-view__svg .edgeLabel span) {
|
||||
background: color-mix(in srgb, var(--card-bg) 94%, transparent);
|
||||
color: var(--soft-ink);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 6px;
|
||||
padding: 2px 6px;
|
||||
font-family: var(--mono);
|
||||
font-size: 0.68rem;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
:global(.JCV-overlay-container .JCV-content) {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
:global(.catalog-mermaid-view__svg .liveNode rect),
|
||||
:global(.catalog-mermaid-view__svg .liveNode polygon) {
|
||||
stroke: var(--accent);
|
||||
fill: color-mix(in srgb, var(--paper) 94%, var(--accent) 6%);
|
||||
}
|
||||
|
||||
:global(.catalog-chapter-card--map) {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: 0;
|
||||
box-sizing: border-box;
|
||||
:global(.catalog-mermaid-view__svg .plannedNode rect),
|
||||
:global(.catalog-mermaid-view__svg .plannedNode polygon) {
|
||||
stroke: color-mix(in srgb, var(--muted) 85%, transparent);
|
||||
fill: color-mix(in srgb, var(--paper) 92%, var(--muted) 8%);
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-view__svg .edge-path path) {
|
||||
stroke: color-mix(in srgb, var(--accent) 65%, var(--muted));
|
||||
stroke-width: 1.8px;
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-view__svg .cluster rect) {
|
||||
fill: color-mix(in srgb, var(--paper) 78%, transparent);
|
||||
stroke: color-mix(in srgb, var(--accent) 26%, var(--line));
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-node) {
|
||||
width: min(300px, 46vw);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
pointer-events: auto;
|
||||
cursor: default;
|
||||
gap: 8px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
:global(.catalog-chapter-card--map .catalog-chapter-card__title-link) {
|
||||
@include catalog-chapter-title-link-with-arrow;
|
||||
:global(.catalog-mermaid-node__title) {
|
||||
margin: 0;
|
||||
font-family: var(--font-heading);
|
||||
font-size: 1rem;
|
||||
line-height: 1.2;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
:global(.catalog-chapter-card--map .catalog-chapter-card__title-arrow) {
|
||||
@include catalog-chapter-title-arrow;
|
||||
}
|
||||
|
||||
:global(.catalog-chapter-card--map .catalog-chapter-card__meta) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
:global(.catalog-chapter-card--map .catalog-chapter-card__description) {
|
||||
:global(.catalog-mermaid-node__description) {
|
||||
margin: 0;
|
||||
font-size: 0.82rem;
|
||||
line-height: 1.4;
|
||||
color: var(--soft-ink);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-node__meta) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-node .catalog-badge) {
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[data-theme="dark"] .catalog-mermaid-view {
|
||||
:global(.catalog-mermaid-view__svg .node rect),
|
||||
:global(.catalog-mermaid-view__svg .node polygon),
|
||||
:global(.catalog-mermaid-view__svg .cluster rect) {
|
||||
stroke: color-mix(in srgb, var(--accent) 78%, #ffffff 22%);
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-view__svg .edge-path path),
|
||||
:global(.catalog-mermaid-view__svg .arrowheadPath) {
|
||||
stroke: color-mix(in srgb, var(--accent) 88%, #ffffff 12%);
|
||||
fill: color-mix(in srgb, var(--accent) 88%, #ffffff 12%);
|
||||
}
|
||||
|
||||
:global(.catalog-mermaid-view__svg .edgeLabel span) {
|
||||
border-color: color-mix(in srgb, var(--accent) 52%, var(--line));
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -827,7 +890,7 @@ a.catalog-chapter-card {
|
|||
}
|
||||
|
||||
.catalog-content {
|
||||
padding: 24px 20px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.catalog-content--tree {
|
||||
|
|
@ -835,6 +898,11 @@ a.catalog-chapter-card {
|
|||
min-height: min(70vh, 560px);
|
||||
max-height: min(70vh, 560px);
|
||||
}
|
||||
|
||||
.catalog-mermaid-controls {
|
||||
right: 12px;
|
||||
top: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
function e(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}export{e as g};
|
||||
1
themes/openfreebooks/static/js/arc-DHD47I7T.js
Normal file
1
themes/openfreebooks/static/js/arc-DHD47I7T.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{bl as ln,aO as an,H as z,b8 as w,F as G,ah as un,W as y,bd as tn,b9 as J,aI as _,c as rn,m as o,aG as on,j as sn,d as fn}from"./mermaid.core--pqIgmQ1.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,j,I,v,A,H,a){var q=j-l,i=I-h,n=H-v,d=a-A,u=d*q-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*q,h+u*i]}function U(l,h,j,I,v,A,H){var a=l-j,q=h-I,i=(H?A:-A)/J(a*a+q*q),n=i*q,d=-i*a,u=l+n,s=h+d,f=j+n,c=I+d,S=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,D=(g<0?-1:1)*J(on(0,T*T*R-P*P)),E=(P*g-m*D)/R,F=(-P*m-g*D)/R,b=(P*g+m*D)/R,p=(-P*m+g*D)/R,x=E-S,e=F-t,r=b-S,W=p-t;return x*x+e*e>r*r+W*W&&(E=b,F=p),{cx:E,cy:F,x01:-n,y01:-d,x11:E*(v/T-1),y11:F*(v/T-1)}}function hn(){var l=cn,h=yn,j=G(0),I=null,v=gn,A=dn,H=mn,a=null,q=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,S=rn(c-f),t=c>f;if(a||(a=n=q()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(S>tn-y)a.moveTo(s*z(f),s*w(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*z(c),u*w(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=S,D=S,E=H.apply(this,arguments)/2,F=E>y&&(I?+I.apply(this,arguments):J(u*u+s*s)),b=_(rn(s-u)/2,+j.apply(this,arguments)),p=b,x=b,e,r;if(F>y){var W=sn(F/u*w(E)),K=sn(F/s*w(E));(P-=W*2)>y?(W*=t?1:-1,R+=W,T-=W):(P=0,R=T=(f+c)/2),(D-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(D=0,m=g=(f+c)/2)}var B=s*z(m),C=s*w(m),L=u*z(T),M=u*w(T);if(b>y){var N=s*z(g),Q=s*w(g),V=u*z(R),X=u*w(R),O;if(S<an)if(O=pn(B,C,V,X,N,Q,L,M)){var Y=B-O[0],Z=C-O[1],$=N-O[0],k=Q-O[1],nn=1/w(fn((Y*$+Z*k)/(J(Y*Y+Z*Z)*J($*$+k*k)))/2),en=J(O[0]*O[0]+O[1]*O[1]);p=_(b,(u-en)/(nn-1)),x=_(b,(s-en)/(nn+1))}else p=x=0}D>y?x>y?(e=U(V,X,B,C,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<b?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(B,C),a.arc(0,0,s,m,g,!t)):a.moveTo(B,C),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(B,C,V,X,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<b?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[z(d)*n,w(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:G(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:G(+n),i):h},i.cornerRadius=function(n){return arguments.length?(j=typeof n=="function"?n:G(+n),i):j},i.padRadius=function(n){return arguments.length?(I=n==null?null:typeof n=="function"?n:G(+n),i):I},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:G(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:G(+n),i):A},i.padAngle=function(n){return arguments.length?(H=typeof n=="function"?n:G(+n),i):H},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|
||||
1
themes/openfreebooks/static/js/arc-fR8_0ZTC.js
Normal file
1
themes/openfreebooks/static/js/arc-fR8_0ZTC.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{bk as ln,aO as an,H as k,b7 as w,F as G,ah as un,W as y,bc as tn,b8 as C,aI as _,c as rn,m as o,aG as on,j as sn,d as fn}from"./mermaid.core-qDFbsd8h.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,j,I,v,A,H,a){var q=j-l,i=I-h,n=H-v,d=a-A,u=d*q-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*q,h+u*i]}function Q(l,h,j,I,v,A,H){var a=l-j,q=h-I,i=(H?A:-A)/C(a*a+q*q),n=i*q,d=-i*a,u=l+n,s=h+d,f=j+n,c=I+d,S=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,D=(g<0?-1:1)*C(on(0,T*T*R-P*P)),E=(P*g-m*D)/R,F=(-P*m-g*D)/R,b=(P*g+m*D)/R,p=(-P*m+g*D)/R,x=E-S,e=F-t,r=b-S,W=p-t;return x*x+e*e>r*r+W*W&&(E=b,F=p),{cx:E,cy:F,x01:-n,y01:-d,x11:E*(v/T-1),y11:F*(v/T-1)}}function hn(){var l=cn,h=yn,j=G(0),I=null,v=gn,A=dn,H=mn,a=null,q=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,S=rn(c-f),t=c>f;if(a||(a=n=q()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(S>tn-y)a.moveTo(s*k(f),s*w(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*k(c),u*w(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=S,D=S,E=H.apply(this,arguments)/2,F=E>y&&(I?+I.apply(this,arguments):C(u*u+s*s)),b=_(rn(s-u)/2,+j.apply(this,arguments)),p=b,x=b,e,r;if(F>y){var W=sn(F/u*w(E)),J=sn(F/s*w(E));(P-=W*2)>y?(W*=t?1:-1,R+=W,T-=W):(P=0,R=T=(f+c)/2),(D-=J*2)>y?(J*=t?1:-1,m+=J,g-=J):(D=0,m=g=(f+c)/2)}var z=s*k(m),B=s*w(m),K=u*k(T),L=u*w(T);if(b>y){var M=s*k(g),N=s*w(g),U=u*k(R),V=u*w(R),O;if(S<an)if(O=pn(z,B,U,V,M,N,K,L)){var X=z-O[0],Y=B-O[1],Z=M-O[0],$=N-O[1],nn=1/w(fn((X*Z+Y*$)/(C(X*X+Y*Y)*C(Z*Z+$*$)))/2),en=C(O[0]*O[0]+O[1]*O[1]);p=_(b,(u-en)/(nn-1)),x=_(b,(s-en)/(nn+1))}else p=x=0}D>y?x>y?(e=Q(U,V,z,B,s,x,t),r=Q(M,N,K,L,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<b?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(z,B),a.arc(0,0,s,m,g,!t)):a.moveTo(z,B),!(u>y)||!(P>y)?a.lineTo(K,L):p>y?(e=Q(K,L,M,N,u,-p,t),r=Q(z,B,U,V,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<b?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[k(d)*n,w(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:G(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:G(+n),i):h},i.cornerRadius=function(n){return arguments.length?(j=typeof n=="function"?n:G(+n),i):j},i.padRadius=function(n){return arguments.length?(I=n==null?null:typeof n=="function"?n:G(+n),i):I},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:G(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:G(+n),i):A},i.padAngle=function(n){return arguments.length?(H=typeof n=="function"?n:G(+n),i):H},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
132
themes/openfreebooks/static/js/blockDiagram-GPEHLZMM-2n8LZvm9.js
Normal file
132
themes/openfreebooks/static/js/blockDiagram-GPEHLZMM-2n8LZvm9.js
Normal file
File diff suppressed because one or more lines are too long
132
themes/openfreebooks/static/js/blockDiagram-GPEHLZMM-CDHcuPF-.js
Normal file
132
themes/openfreebooks/static/js/blockDiagram-GPEHLZMM-CDHcuPF-.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-BHxMrGhx.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-BHxMrGhx.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DVnYihDg.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DVnYihDg.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DWjNi8Pf.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DWjNi8Pf.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DeN6WaNm.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DeN6WaNm.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-Di63SZWf.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-Di63SZWf.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DnPe6Xp3.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DnPe6Xp3.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DwQhsvKO.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DwQhsvKO.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-DxZC2XAn.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-DxZC2XAn.js
Normal file
File diff suppressed because one or more lines are too long
3
themes/openfreebooks/static/js/catalog-app-QgKNX1Gh.js
Normal file
3
themes/openfreebooks/static/js/catalog-app-QgKNX1Gh.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-BEMEfCQ7.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-BEMEfCQ7.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-BPQD55gc.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-BPQD55gc.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-Bk6l6JF6.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-Bk6l6JF6.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-CxRB9G0z.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-CxRB9G0z.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-D6jnCV4A.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-D6jnCV4A.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-Dd57kmKO.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-Dd57kmKO.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-Djqvy574.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-Djqvy574.js
Normal file
File diff suppressed because one or more lines are too long
448
themes/openfreebooks/static/js/catalog-canvas-view-DmvQWj_p.js
Normal file
448
themes/openfreebooks/static/js/catalog-canvas-view-DmvQWj_p.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as M,o as E,e as L,u as A,t as z,_ as f,i as C}from"./bundle.js";import{s as $,w as R}from"./catalog-app-DxZC2XAn.js";var T=z('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function B(b){let r,e,c,u=0,v="",w=$(),m,g;const _=()=>{e==null||e.destroy(),e=void 0},S=async()=>{if(!m||!g){const[{default:i},{default:t}]=await Promise.all([f(()=>import("./mermaid.core-qDFbsd8h.js").then(o=>o.aH),__vite__mapDeps([0,1,2,3])),f(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(o=>o.s),__vite__mapDeps([4,2]))]);m=i,g=t}},h=async()=>{const i=b.diagram.source,t=$();if(!r||i===v&&t===w)return;v=i,w=t;const o=++u;if(_(),await S(),o!==u||!m||!g)return;m.initialize({startOnLoad:!1,securityLevel:"loose",theme:t==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"monotoneY",nodeSpacing:70,rankSpacing:95}});const{svg:d,bindFunctions:n}=await m.render(`catalog-mermaid-${o}`,i);if(o!==u)return;r.innerHTML=d,n==null||n(r);const a=r.querySelector("svg");a&&(a.classList.add("catalog-mermaid-view__svg"),a.removeAttribute("style"),a.style.height="100%",a.style.width="100%",e=g(a,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};M(()=>{h();const i=R(()=>{h()});c=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),c.observe(r),E(()=>{u+=1,i(),c==null||c.disconnect(),c=void 0,_()})}),L(()=>{b.diagram.source,h()});const y=()=>{e&&(e.reset(),e.fit(),e.center())},x=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},p=()=>{const i=r.querySelector("svg.catalog-mermaid-view__svg");if(!i)return;const t=i.cloneNode(!0);t.removeAttribute("style"),t.setAttribute("xmlns","http://www.w3.org/2000/svg"),t.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");const o=t.viewBox.baseVal;if(o.width>0&&o.height>0)t.setAttribute("width",String(Math.ceil(o.width))),t.setAttribute("height",String(Math.ceil(o.height)));else{const s=i.getBBox();t.setAttribute("viewBox",`0 0 ${Math.ceil(s.width)} ${Math.ceil(s.height)}`),t.setAttribute("width",String(Math.ceil(s.width))),t.setAttribute("height",String(Math.ceil(s.height)))}const d=new XMLSerializer().serializeToString(t),n=new Blob([d],{type:"image/svg+xml;charset=utf-8"}),a=URL.createObjectURL(n),l=document.createElement("a");l.href=a,l.download="catalog-map-mermaid.svg",document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(a)};return(()=>{var i=T(),t=i.firstChild,o=t.nextSibling,d=o.firstChild,n=d.nextSibling,a=n.nextSibling,l=a.nextSibling,s=r;return typeof s=="function"?A(s,t):r=t,d.$$click=k,n.$$click=x,a.$$click=y,l.$$click=p,i})()}C(["click"]);export{B as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as p,o as z,e as C,u as M,t as R,_ as h,i as T}from"./bundle.js";import{s as w,w as x}from"./catalog-app-DnPe6Xp3.js";var O=R('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function V(v){let l,e,s,d=0,g="",b=w(),c,m;const _=()=>{e==null||e.destroy(),e=void 0},$=async()=>{if(!c||!m){const[{default:t},{default:o}]=await Promise.all([h(()=>import("./mermaid.core-qDFbsd8h.js").then(r=>r.aH),__vite__mapDeps([0,1,2,3])),h(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(r=>r.s),__vite__mapDeps([4,2]))]);c=t,m=o}},u=async()=>{const t=v.diagram.source,o=w();if(!l||t===g&&o===b)return;g=t,b=o;const r=++d;if(_(),await $(),r!==d||!c||!m)return;c.initialize({startOnLoad:!1,securityLevel:"loose",theme:o==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:n,bindFunctions:a}=await c.render(`catalog-mermaid-${r}`,t);if(r!==d)return;l.innerHTML=n,a==null||a(l);const i=l.querySelector("svg");i&&(i.classList.add("catalog-mermaid-view__svg"),i.removeAttribute("style"),i.style.height="100%",i.style.width="100%",e=m(i,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};p(()=>{u();const t=x(()=>{u()});s=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),s.observe(l),z(()=>{d+=1,t(),s==null||s.disconnect(),s=void 0,_()})}),C(()=>{v.diagram.source,u()});const y=()=>{e&&(e.reset(),e.fit(),e.center())},S=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},E=()=>{const t=l.querySelector("svg.catalog-mermaid-view__svg");if(!t)return;const o=new XMLSerializer().serializeToString(t),r=new Blob([o],{type:"image/svg+xml;charset=utf-8"}),n=URL.createObjectURL(r),a=document.createElement("a");a.href=n,a.download="catalog-map-mermaid.svg",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)};return(()=>{var t=O(),o=t.firstChild,r=o.nextSibling,n=r.firstChild,a=n.nextSibling,i=a.nextSibling,L=i.nextSibling,f=l;return typeof f=="function"?M(f,o):l=o,n.$$click=k,a.$$click=S,i.$$click=y,L.$$click=E,t})()}T(["click"]);export{V as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core--pqIgmQ1.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as M,o as p,e as L,u as S,t as z,_ as w,i as P}from"./bundle.js";function v(){if(typeof document>"u")return"light";const a=document.documentElement.getAttribute("data-theme");return a==="dark"||a==="light"?a:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}function T(a){const t=window.matchMedia("(prefers-color-scheme: dark)"),e=new MutationObserver(()=>a(v()));e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]});const n=()=>{document.documentElement.getAttribute("data-theme")||a(v())};return t.addEventListener("change",n),()=>{e.disconnect(),t.removeEventListener("change",n)}}var C=z('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view');function x(a){let t,e,n,d=0,g="",h=v(),l,m;const b=()=>{e==null||e.destroy(),e=void 0},E=async()=>{if(!l||!m){const[{default:r},{default:o}]=await Promise.all([w(()=>import("./mermaid.core--pqIgmQ1.js").then(i=>i.aH),__vite__mapDeps([0,1,2])),w(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(i=>i.s),__vite__mapDeps([3,2]))]);l=r,m=o}},f=async()=>{const r=a.diagram.source,o=v();if(!t||r===g&&o===h)return;g=r,h=o;const i=++d;if(b(),await E(),i!==d||!l||!m)return;l.initialize({startOnLoad:!1,securityLevel:"loose",theme:o==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"monotoneY",nodeSpacing:70,rankSpacing:95}});const{svg:u,bindFunctions:c}=await l.render(`catalog-mermaid-${i}`,r);if(i!==d)return;t.innerHTML=u,c==null||c(t);const s=t.querySelector("svg");s&&(s.classList.add("catalog-mermaid-view__svg"),s.removeAttribute("style"),s.style.height="100%",s.style.width="100%",e=m(s,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};M(()=>{f();const r=T(()=>{f()});n=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),n.observe(t),p(()=>{d+=1,r(),n==null||n.disconnect(),n=void 0,b()})}),L(()=>{a.diagram.source,f()});const $=()=>{e&&(e.reset(),e.fit(),e.center())},k=()=>{e==null||e.zoomIn()},y=()=>{e==null||e.zoomOut()};return(()=>{var r=C(),o=r.firstChild,i=o.nextSibling,u=i.firstChild,c=u.nextSibling,s=c.nextSibling,_=t;return typeof _=="function"?S(_,o):t=o,u.$$click=y,c.$$click=k,s.$$click=$,r})()}P(["click"]);export{x as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as M,o as E,e as L,u as A,t as z,_ as f,i as C}from"./bundle.js";import{s as $,w as R}from"./catalog-app-DwQhsvKO.js";var T=z('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function B(b){let r,e,c,u=0,v="",w=$(),m,g;const _=()=>{e==null||e.destroy(),e=void 0},S=async()=>{if(!m||!g){const[{default:i},{default:t}]=await Promise.all([f(()=>import("./mermaid.core-qDFbsd8h.js").then(o=>o.aH),__vite__mapDeps([0,1,2,3])),f(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(o=>o.s),__vite__mapDeps([4,2]))]);m=i,g=t}},h=async()=>{const i=b.diagram.source,t=$();if(!r||i===v&&t===w)return;v=i,w=t;const o=++u;if(_(),await S(),o!==u||!m||!g)return;m.initialize({startOnLoad:!1,securityLevel:"loose",theme:t==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"monotoneX",nodeSpacing:70,rankSpacing:95}});const{svg:d,bindFunctions:n}=await m.render(`catalog-mermaid-${o}`,i);if(o!==u)return;r.innerHTML=d,n==null||n(r);const a=r.querySelector("svg");a&&(a.classList.add("catalog-mermaid-view__svg"),a.removeAttribute("style"),a.style.height="100%",a.style.width="100%",e=g(a,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};M(()=>{h();const i=R(()=>{h()});c=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),c.observe(r),E(()=>{u+=1,i(),c==null||c.disconnect(),c=void 0,_()})}),L(()=>{b.diagram.source,h()});const y=()=>{e&&(e.reset(),e.fit(),e.center())},x=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},p=()=>{const i=r.querySelector("svg.catalog-mermaid-view__svg");if(!i)return;const t=i.cloneNode(!0);t.removeAttribute("style"),t.setAttribute("xmlns","http://www.w3.org/2000/svg"),t.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");const o=t.viewBox.baseVal;if(o.width>0&&o.height>0)t.setAttribute("width",String(Math.ceil(o.width))),t.setAttribute("height",String(Math.ceil(o.height)));else{const s=i.getBBox();t.setAttribute("viewBox",`0 0 ${Math.ceil(s.width)} ${Math.ceil(s.height)}`),t.setAttribute("width",String(Math.ceil(s.width))),t.setAttribute("height",String(Math.ceil(s.height)))}const d=new XMLSerializer().serializeToString(t),n=new Blob([d],{type:"image/svg+xml;charset=utf-8"}),a=URL.createObjectURL(n),l=document.createElement("a");l.href=a,l.download="catalog-map-mermaid.svg",document.body.appendChild(l),l.click(),document.body.removeChild(l),URL.revokeObjectURL(a)};return(()=>{var i=T(),t=i.firstChild,o=t.nextSibling,d=o.firstChild,n=d.nextSibling,a=n.nextSibling,l=a.nextSibling,s=r;return typeof s=="function"?A(s,t):r=t,d.$$click=k,n.$$click=x,a.$$click=y,l.$$click=p,i})()}C(["click"]);export{B as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as p,o as E,e as L,u as A,t as z,_ as f,i as C}from"./bundle.js";import{s as $,w as R}from"./catalog-app-DeN6WaNm.js";var T=z('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function B(b){let r,e,c,m=0,v="",w=$(),u,g;const _=()=>{e==null||e.destroy(),e=void 0},y=async()=>{if(!u||!g){const[{default:i},{default:t}]=await Promise.all([f(()=>import("./mermaid.core-qDFbsd8h.js").then(o=>o.aH),__vite__mapDeps([0,1,2,3])),f(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(o=>o.s),__vite__mapDeps([4,2]))]);u=i,g=t}},h=async()=>{const i=b.diagram.source,t=$();if(!r||i===v&&t===w)return;v=i,w=t;const o=++m;if(_(),await y(),o!==m||!u||!g)return;u.initialize({startOnLoad:!1,securityLevel:"loose",theme:t==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:d,bindFunctions:l}=await u.render(`catalog-mermaid-${o}`,i);if(o!==m)return;r.innerHTML=d,l==null||l(r);const a=r.querySelector("svg");a&&(a.classList.add("catalog-mermaid-view__svg"),a.removeAttribute("style"),a.style.height="100%",a.style.width="100%",e=g(a,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};p(()=>{h();const i=R(()=>{h()});c=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),c.observe(r),E(()=>{m+=1,i(),c==null||c.disconnect(),c=void 0,_()})}),L(()=>{b.diagram.source,h()});const S=()=>{e&&(e.reset(),e.fit(),e.center())},x=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},M=()=>{const i=r.querySelector("svg.catalog-mermaid-view__svg");if(!i)return;const t=i.cloneNode(!0);t.removeAttribute("style"),t.setAttribute("xmlns","http://www.w3.org/2000/svg"),t.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink");const o=t.viewBox.baseVal;if(o.width>0&&o.height>0)t.setAttribute("width",String(Math.ceil(o.width))),t.setAttribute("height",String(Math.ceil(o.height)));else{const n=i.getBBox();t.setAttribute("viewBox",`0 0 ${Math.ceil(n.width)} ${Math.ceil(n.height)}`),t.setAttribute("width",String(Math.ceil(n.width))),t.setAttribute("height",String(Math.ceil(n.height)))}const d=new XMLSerializer().serializeToString(t),l=new Blob([d],{type:"image/svg+xml;charset=utf-8"}),a=URL.createObjectURL(l),s=document.createElement("a");s.href=a,s.download="catalog-map-mermaid.svg",document.body.appendChild(s),s.click(),document.body.removeChild(s),URL.revokeObjectURL(a)};return(()=>{var i=T(),t=i.firstChild,o=t.nextSibling,d=o.firstChild,l=d.nextSibling,a=l.nextSibling,s=a.nextSibling,n=r;return typeof n=="function"?A(n,t):r=t,d.$$click=k,l.$$click=x,a.$$click=S,s.$$click=M,i})()}C(["click"]);export{B as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as z,o as B,e as O,u as b,t as R,_ as E,i as q}from"./bundle.js";import{s as M,w as H}from"./catalog-app-Di63SZWf.js";var W=R('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-minimap aria-hidden=true><div class=catalog-mermaid-minimap__content></div><svg class=catalog-mermaid-minimap__overlay><rect class=catalog-mermaid-minimap__viewport>');function x(f,r,l){return Math.min(l,Math.max(r,f))}function X(f){let r,l,_,m,t,d,p=0,S="",A=M(),h,w;const C=()=>{t==null||t.destroy(),t=void 0},g=()=>{const a=r.querySelector("svg.catalog-mermaid-view__svg"),e=a==null?void 0:a.viewBox.baseVal;if(!a||!e||!t||e.width<=0||e.height<=0)return;_.setAttribute("viewBox",`${e.x} ${e.y} ${e.width} ${e.height}`);const i=t.getZoom(),o=t.getPan(),n=r.clientWidth/i,s=r.clientHeight/i,u=-o.x/i,v=-o.y/i,c=x(u,e.x,e.x+e.width),y=x(v,e.y,e.y+e.height),V=x(n,0,e.width),k=x(s,0,e.height);m.setAttribute("x",String(c)),m.setAttribute("y",String(y)),m.setAttribute("width",String(V)),m.setAttribute("height",String(k))},P=()=>{l.replaceChildren();const a=r.querySelector("svg.catalog-mermaid-view__svg");if(!a)return;const e=a.cloneNode(!0);e.removeAttribute("width"),e.removeAttribute("height"),e.classList.add("catalog-mermaid-view__svg--minimap"),e.querySelectorAll("a").forEach(i=>i.removeAttribute("href")),l.appendChild(e)},L=async()=>{if(!h||!w){const[{default:a},{default:e}]=await Promise.all([E(()=>import("./mermaid.core-qDFbsd8h.js").then(i=>i.aH),__vite__mapDeps([0,1,2,3])),E(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(i=>i.s),__vite__mapDeps([4,2]))]);h=a,w=e}},$=async()=>{const a=f.diagram.source,e=M();if(!r||a===S&&e===A)return;S=a,A=e;const i=++p;if(C(),await L(),i!==p||!h||!w)return;h.initialize({startOnLoad:!1,securityLevel:"loose",theme:e==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:o,bindFunctions:n}=await h.render(`catalog-mermaid-${i}`,a);if(i!==p)return;r.innerHTML=o,n==null||n(r);const s=r.querySelector("svg");s&&(s.classList.add("catalog-mermaid-view__svg"),s.removeAttribute("style"),t=w(s,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!0,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),t.setOnPan(g),t.setOnZoom(g),t.resize(),t.fit(),t.center(),P(),g())};z(()=>{$();const a=H(()=>{$()});d=new ResizeObserver(()=>{t==null||t.resize(),t==null||t.fit(),t==null||t.center(),g()}),d.observe(r),B(()=>{p+=1,a(),d==null||d.disconnect(),d=void 0,C()})}),O(()=>{f.diagram.source,$()});const T=a=>{const e=r.querySelector("svg.catalog-mermaid-view__svg"),i=e==null?void 0:e.viewBox.baseVal;if(!t||!i)return;const o=_.getBoundingClientRect();if(o.width<=0||o.height<=0)return;const n=(a.clientX-o.left)/o.width,s=(a.clientY-o.top)/o.height,u=i.x+n*i.width,v=i.y+s*i.height,c=t.getZoom();t.pan({x:r.clientWidth/2-u*c,y:r.clientHeight/2-v*c}),g()};return(()=>{var a=W(),e=a.firstChild,i=e.nextSibling,o=i.firstChild,n=o.nextSibling,s=n.firstChild,u=r;typeof u=="function"?b(u,e):r=e;var v=l;typeof v=="function"?b(v,o):l=o,n.$$click=T;var c=_;typeof c=="function"?b(c,n):_=n;var y=m;return typeof y=="function"?b(y,s):m=s,a})()}q(["click"]);export{X as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as B,o as q,e as H,u as x,t as W,_ as k,i as D}from"./bundle.js";import{s as R,w as U}from"./catalog-app-DWjNi8Pf.js";var X=W('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG</button></div><div class=catalog-mermaid-minimap aria-hidden=true><div class=catalog-mermaid-minimap__content></div><svg class=catalog-mermaid-minimap__overlay><rect class=catalog-mermaid-minimap__viewport>');function S(_,a,m){return Math.min(m,Math.max(a,_))}function Z(_){let a,m,f,u,t,g,w=0,E="",L=R(),h,p;const M=()=>{t==null||t.destroy(),t=void 0},v=()=>{const o=a.querySelector("svg.catalog-mermaid-view__svg"),e=o==null?void 0:o.viewBox.baseVal;if(!o||!e||!t||e.width<=0||e.height<=0)return;f.setAttribute("viewBox",`${e.x} ${e.y} ${e.width} ${e.height}`);const i=t.getZoom(),r=t.getPan(),n=a.clientWidth/i,s=a.clientHeight/i,l=-r.x/i,c=-r.y/i,d=S(l,e.x,e.x+e.width),b=S(c,e.y,e.y+e.height),y=S(n,0,e.width),$=S(s,0,e.height);u.setAttribute("x",String(d)),u.setAttribute("y",String(b)),u.setAttribute("width",String(y)),u.setAttribute("height",String($))},P=()=>{m.replaceChildren();const o=a.querySelector("svg.catalog-mermaid-view__svg");if(!o)return;const e=o.cloneNode(!0);e.removeAttribute("width"),e.removeAttribute("height"),e.classList.add("catalog-mermaid-view__svg--minimap"),e.querySelectorAll("a").forEach(i=>i.removeAttribute("href")),m.appendChild(e)},T=async()=>{if(!h||!p){const[{default:o},{default:e}]=await Promise.all([k(()=>import("./mermaid.core-qDFbsd8h.js").then(i=>i.aH),__vite__mapDeps([0,1,2,3])),k(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(i=>i.s),__vite__mapDeps([4,2]))]);h=o,p=e}},C=async()=>{const o=_.diagram.source,e=R();if(!a||o===E&&e===L)return;E=o,L=e;const i=++w;if(M(),await T(),i!==w||!h||!p)return;h.initialize({startOnLoad:!1,securityLevel:"loose",theme:e==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:r,bindFunctions:n}=await h.render(`catalog-mermaid-${i}`,o);if(i!==w)return;a.innerHTML=r,n==null||n(a);const s=a.querySelector("svg");s&&(s.classList.add("catalog-mermaid-view__svg"),s.removeAttribute("style"),t=p(s,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!0,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),t.setOnPan(v),t.setOnZoom(v),t.resize(),t.fit(),t.center(),P(),v())};B(()=>{C();const o=U(()=>{C()});g=new ResizeObserver(()=>{t==null||t.resize(),t==null||t.fit(),t==null||t.center(),v()}),g.observe(a),q(()=>{w+=1,o(),g==null||g.disconnect(),g=void 0,M()})}),H(()=>{_.diagram.source,C()});const V=o=>{const e=a.querySelector("svg.catalog-mermaid-view__svg"),i=e==null?void 0:e.viewBox.baseVal;if(!t||!i)return;const r=f.getBoundingClientRect();if(r.width<=0||r.height<=0)return;const n=(o.clientX-r.left)/r.width,s=(o.clientY-r.top)/r.height,l=i.x+n*i.width,c=i.y+s*i.height,d=t.getZoom();t.pan({x:a.clientWidth/2-l*d,y:a.clientHeight/2-c*d}),v()},z=()=>{t&&(t.reset(),t.fit(),t.center(),v())},O=()=>{const o=a.querySelector("svg.catalog-mermaid-view__svg");if(!o)return;const e=new XMLSerializer().serializeToString(o),i=new Blob([e],{type:"image/svg+xml;charset=utf-8"}),r=URL.createObjectURL(i),n=document.createElement("a");n.href=r,n.download="catalog-map-mermaid.svg",document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(r)};return(()=>{var o=X(),e=o.firstChild,i=e.nextSibling,r=i.firstChild,n=r.nextSibling,s=i.nextSibling,l=s.firstChild,c=l.nextSibling,d=c.firstChild,b=a;typeof b=="function"?x(b,e):a=e,r.$$click=z,n.$$click=O;var y=m;typeof y=="function"?x(y,l):m=l,c.$$click=V;var $=f;typeof $=="function"?x($,c):f=c;var A=u;return typeof A=="function"?x(A,d):u=d,o})()}D(["click"]);export{Z as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as p,o as z,e as C,u as M,t as R,_ as h,i as T}from"./bundle.js";import{s as w,w as x}from"./catalog-app-DVnYihDg.js";var O=R('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function V(v){let l,e,s,d=0,g="",b=w(),c,m;const _=()=>{e==null||e.destroy(),e=void 0},$=async()=>{if(!c||!m){const[{default:t},{default:o}]=await Promise.all([h(()=>import("./mermaid.core-qDFbsd8h.js").then(r=>r.aH),__vite__mapDeps([0,1,2,3])),h(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(r=>r.s),__vite__mapDeps([4,2]))]);c=t,m=o}},u=async()=>{const t=v.diagram.source,o=w();if(!l||t===g&&o===b)return;g=t,b=o;const r=++d;if(_(),await $(),r!==d||!c||!m)return;c.initialize({startOnLoad:!1,securityLevel:"loose",theme:o==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:n,bindFunctions:a}=await c.render(`catalog-mermaid-${r}`,t);if(r!==d)return;l.innerHTML=n,a==null||a(l);const i=l.querySelector("svg");i&&(i.classList.add("catalog-mermaid-view__svg"),i.removeAttribute("style"),i.style.height="100%",i.style.width="100%",e=m(i,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};p(()=>{u();const t=x(()=>{u()});s=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),s.observe(l),z(()=>{d+=1,t(),s==null||s.disconnect(),s=void 0,_()})}),C(()=>{v.diagram.source,u()});const y=()=>{e&&(e.reset(),e.fit(),e.center())},S=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},E=()=>{const t=l.querySelector("svg.catalog-mermaid-view__svg");if(!t)return;const o=new XMLSerializer().serializeToString(t),r=new Blob([o],{type:"image/svg+xml;charset=utf-8"}),n=URL.createObjectURL(r),a=document.createElement("a");a.href=n,a.download="catalog-map-mermaid.svg",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)};return(()=>{var t=O(),o=t.firstChild,r=o.nextSibling,n=r.firstChild,a=n.nextSibling,i=a.nextSibling,L=i.nextSibling,f=l;return typeof f=="function"?M(f,o):l=o,n.$$click=k,a.$$click=S,i.$$click=y,L.$$click=E,t})()}T(["click"]);export{V as CatalogMermaidView};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/mermaid.core-qDFbsd8h.js","js/bundle.js","js/_commonjsHelpers-CqkleIqs.js","js/purify.es-DxCUJf2h.js","js/svg-pan-zoom-CiC2DUUX.js"])))=>i.map(i=>d[i]);
|
||||
import{k as p,o as z,e as C,u as M,t as R,_ as h,i as T}from"./bundle.js";import{s as w,w as x}from"./catalog-app-QgKNX1Gh.js";var O=R('<div class=catalog-mermaid-stage><div class=catalog-mermaid-view role=application aria-label="Chapter map (Mermaid)"></div><div class=catalog-mermaid-controls><button type=button class=catalog-mermaid-controls__btn>Zoom out</button><button type=button class=catalog-mermaid-controls__btn>Zoom in</button><button type=button class=catalog-mermaid-controls__btn>Reset view</button><button type=button class=catalog-mermaid-controls__btn>Download SVG');function V(v){let l,e,s,d=0,g="",b=w(),c,m;const _=()=>{e==null||e.destroy(),e=void 0},$=async()=>{if(!c||!m){const[{default:t},{default:o}]=await Promise.all([h(()=>import("./mermaid.core-qDFbsd8h.js").then(r=>r.aH),__vite__mapDeps([0,1,2,3])),h(()=>import("./svg-pan-zoom-CiC2DUUX.js").then(r=>r.s),__vite__mapDeps([4,2]))]);c=t,m=o}},u=async()=>{const t=v.diagram.source,o=w();if(!l||t===g&&o===b)return;g=t,b=o;const r=++d;if(_(),await $(),r!==d||!c||!m)return;c.initialize({startOnLoad:!1,securityLevel:"loose",theme:o==="dark"?"dark":"default",flowchart:{htmlLabels:!0,curve:"basis"}});const{svg:n,bindFunctions:a}=await c.render(`catalog-mermaid-${r}`,t);if(r!==d)return;l.innerHTML=n,a==null||a(l);const i=l.querySelector("svg");i&&(i.classList.add("catalog-mermaid-view__svg"),i.removeAttribute("style"),i.style.height="100%",i.style.width="100%",e=m(i,{zoomEnabled:!0,panEnabled:!0,controlIconsEnabled:!1,fit:!0,center:!0,minZoom:.3,maxZoom:8,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0}),e.resize(),e.fit(),e.center())};p(()=>{u();const t=x(()=>{u()});s=new ResizeObserver(()=>{e==null||e.resize(),e==null||e.fit(),e==null||e.center()}),s.observe(l),z(()=>{d+=1,t(),s==null||s.disconnect(),s=void 0,_()})}),C(()=>{v.diagram.source,u()});const y=()=>{e&&(e.reset(),e.fit(),e.center())},S=()=>{e==null||e.zoomIn()},k=()=>{e==null||e.zoomOut()},E=()=>{const t=l.querySelector("svg.catalog-mermaid-view__svg");if(!t)return;const o=new XMLSerializer().serializeToString(t),r=new Blob([o],{type:"image/svg+xml;charset=utf-8"}),n=URL.createObjectURL(r),a=document.createElement("a");a.href=n,a.download="catalog-map-mermaid.svg",document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)};return(()=>{var t=O(),o=t.firstChild,r=o.nextSibling,n=r.firstChild,a=n.nextSibling,i=a.nextSibling,L=i.nextSibling,f=l;return typeof f=="function"?M(f,o):l=o,n.$$click=k,a.$$click=S,i.$$click=y,L.$$click=E,t})()}T(["click"]);export{V as CatalogMermaidView};
|
||||
1
themes/openfreebooks/static/js/channel-B4iWkumv.js
Normal file
1
themes/openfreebooks/static/js/channel-B4iWkumv.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{U as a,C as n}from"./mermaid.core--pqIgmQ1.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
||||
1
themes/openfreebooks/static/js/channel-BeztyYca.js
Normal file
1
themes/openfreebooks/static/js/channel-BeztyYca.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{U as a,C as n}from"./mermaid.core-qDFbsd8h.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as a,E as w,aD as x}from"./mermaid.core-qDFbsd8h.js";var g=a((e,t,i,o)=>{e.attr("class",i);const{width:r,height:h,x:n,y:c}=u(e,t);w(e,h,r,o);const s=B(n,c,r,h,t);e.attr("viewBox",s),x.debug(`viewBox configured: ${s} with padding: ${t}`)},"setupViewPortForSVG"),u=a((e,t)=>{var o;const i=((o=e.node())==null?void 0:o.getBBox())||{width:0,height:0,x:0,y:0};return{width:i.width+t*2,height:i.height+t*2,x:i.x,y:i.y}},"calculateDimensionsWithPadding"),B=a((e,t,i,o,r)=>`${e-r} ${t-r} ${i} ${o}`,"createViewBox");export{g as s};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as a,E as w,aD as x}from"./mermaid.core--pqIgmQ1.js";var g=a((e,t,i,o)=>{e.attr("class",i);const{width:r,height:h,x:n,y:c}=u(e,t);w(e,h,r,o);const s=B(n,c,r,h,t);e.attr("viewBox",s),x.debug(`viewBox configured: ${s} with padding: ${t}`)},"setupViewPortForSVG"),u=a((e,t)=>{var o;const i=((o=e.node())==null?void 0:o.getBBox())||{width:0,height:0,x:0,y:0};return{width:i.width+t*2,height:i.height+t*2,x:i.x,y:i.y}},"calculateDimensionsWithPadding"),B=a((e,t,i,o,r)=>`${e-r} ${t-r} ${i} ${o}`,"createViewBox");export{g as s};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as l}from"./mermaid.core--pqIgmQ1.js";function m(e,c){var i,t,o;e.accDescr&&((i=c.setAccDescription)==null||i.call(c,e.accDescr)),e.accTitle&&((t=c.setAccTitle)==null||t.call(c,e.accTitle)),e.title&&((o=c.setDiagramTitle)==null||o.call(c,e.title))}l(m,"populateCommonDb");export{m as p};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as l}from"./mermaid.core-qDFbsd8h.js";function m(e,c){var i,t,o;e.accDescr&&((i=c.setAccDescription)==null||i.call(c,e.accDescr)),e.accTitle&&((t=c.setAccTitle)==null||t.call(c,e.accTitle)),e.title&&((o=c.setDiagramTitle)==null||o.call(c,e.title))}l(m,"populateCommonDb");export{m as p};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as a,aZ as o}from"./mermaid.core-qDFbsd8h.js";var g=a((t,e)=>{let n;return e==="sandbox"&&(n=o("#i"+t)),(e==="sandbox"?o(n.nodes()[0].contentDocument.body):o("body")).select(`[id="${t}"]`)},"getDiagramElement");export{g};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as a,a_ as o}from"./mermaid.core--pqIgmQ1.js";var g=a((t,e)=>{let n;return e==="sandbox"&&(n=o("#i"+t)),(e==="sandbox"?o(n.nodes()[0].contentDocument.body):o("body")).select(`[id="${t}"]`)},"getDiagramElement");export{g};
|
||||
206
themes/openfreebooks/static/js/chunk-727SXJPM-CQV2NHjD.js
Normal file
206
themes/openfreebooks/static/js/chunk-727SXJPM-CQV2NHjD.js
Normal file
File diff suppressed because one or more lines are too long
206
themes/openfreebooks/static/js/chunk-727SXJPM-CS0a2Thu.js
Normal file
206
themes/openfreebooks/static/js/chunk-727SXJPM-CS0a2Thu.js
Normal file
File diff suppressed because one or more lines are too long
231
themes/openfreebooks/static/js/chunk-AQP2D5EJ-BVGx0Uoy.js
Normal file
231
themes/openfreebooks/static/js/chunk-AQP2D5EJ-BVGx0Uoy.js
Normal file
File diff suppressed because one or more lines are too long
231
themes/openfreebooks/static/js/chunk-AQP2D5EJ-DbilLVEX.js
Normal file
231
themes/openfreebooks/static/js/chunk-AQP2D5EJ-DbilLVEX.js
Normal file
File diff suppressed because one or more lines are too long
15
themes/openfreebooks/static/js/chunk-FMBD7UC4-Bc0aUKy7.js
Normal file
15
themes/openfreebooks/static/js/chunk-FMBD7UC4-Bc0aUKy7.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import{b as e}from"./mermaid.core--pqIgmQ1.js";var l=e(()=>`
|
||||
/* Font Awesome icon styling - consolidated */
|
||||
.label-icon {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
overflow: visible;
|
||||
vertical-align: -0.125em;
|
||||
}
|
||||
|
||||
.node .label-icon path {
|
||||
fill: currentColor;
|
||||
stroke: revert;
|
||||
stroke-width: revert;
|
||||
}
|
||||
`,"getIconStyles");export{l as g};
|
||||
15
themes/openfreebooks/static/js/chunk-FMBD7UC4-CXZHiTPS.js
Normal file
15
themes/openfreebooks/static/js/chunk-FMBD7UC4-CXZHiTPS.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import{b as e}from"./mermaid.core-qDFbsd8h.js";var l=e(()=>`
|
||||
/* Font Awesome icon styling - consolidated */
|
||||
.label-icon {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
overflow: visible;
|
||||
vertical-align: -0.125em;
|
||||
}
|
||||
|
||||
.node .label-icon path {
|
||||
fill: currentColor;
|
||||
stroke: revert;
|
||||
stroke-width: revert;
|
||||
}
|
||||
`,"getIconStyles");export{l as g};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as i,a_ as l,aB as d,V as o}from"./mermaid.core--pqIgmQ1.js";var x=i((r,t)=>{const e=r.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const s in t.attrs)e.attr(s,t.attrs[s]);return t.class&&e.attr("class",t.class),e},"drawRect"),p=i((r,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};x(r,e).lower()},"drawBackgroundRect"),y=i((r,t)=>{const e=t.text.replace(d," "),s=r.append("text");s.attr("x",t.x),s.attr("y",t.y),s.attr("class","legend"),s.style("text-anchor",t.anchor),t.class&&s.attr("class",t.class);const a=s.append("tspan");return a.attr("x",t.x+t.textMargin*2),a.text(e),s},"drawText"),m=i((r,t,e,s)=>{const a=r.append("image");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",n)},"drawImage"),g=i((r,t,e,s)=>{const a=r.append("use");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",`#${n}`)},"drawEmbeddedImage"),h=i(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),f=i(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj"),w=i(()=>{let r=l(".mermaidTooltip");return r.empty()&&(r=l("body").append("div").attr("class","mermaidTooltip").style("opacity",0).style("position","absolute").style("text-align","center").style("max-width","200px").style("padding","2px").style("font-size","12px").style("background","#ffffde").style("border","1px solid #333").style("border-radius","2px").style("pointer-events","none").style("z-index","100")),r},"createTooltip");export{g as a,m as b,w as c,p as d,x as e,y as f,h as g,f as h};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as i,aZ as l,aB as d,V as o}from"./mermaid.core-qDFbsd8h.js";var x=i((r,t)=>{const e=r.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const s in t.attrs)e.attr(s,t.attrs[s]);return t.class&&e.attr("class",t.class),e},"drawRect"),p=i((r,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};x(r,e).lower()},"drawBackgroundRect"),y=i((r,t)=>{const e=t.text.replace(d," "),s=r.append("text");s.attr("x",t.x),s.attr("y",t.y),s.attr("class","legend"),s.style("text-anchor",t.anchor),t.class&&s.attr("class",t.class);const a=s.append("tspan");return a.attr("x",t.x+t.textMargin*2),a.text(e),s},"drawText"),m=i((r,t,e,s)=>{const a=r.append("image");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",n)},"drawImage"),g=i((r,t,e,s)=>{const a=r.append("use");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",`#${n}`)},"drawEmbeddedImage"),h=i(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),f=i(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj"),w=i(()=>{let r=l(".mermaidTooltip");return r.empty()&&(r=l("body").append("div").attr("class","mermaidTooltip").style("opacity",0).style("position","absolute").style("text-align","center").style("max-width","200px").style("padding","2px").style("font-size","12px").style("background","#ffffde").style("border","1px solid #333").style("border-radius","2px").style("pointer-events","none").style("z-index","100")),r},"createTooltip");export{g as a,m as b,w as c,p as d,x as e,y as f,h as g,f as h};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as s}from"./mermaid.core-qDFbsd8h.js";var t,e=(t=class{constructor(i){this.init=i,this.records=this.init()}reset(){this.records=this.init()}},s(t,"ImperativeState"),t);export{e as I};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{b as s}from"./mermaid.core--pqIgmQ1.js";var t,e=(t=class{constructor(i){this.init=i,this.records=this.init()}reset(){this.records=this.init()}},s(t,"ImperativeState"),t);export{e as I};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-CQV2NHjD.js";import{b as i}from"./mermaid.core--pqIgmQ1.js";import"./chunk-FMBD7UC4-Bc0aUKy7.js";import"./chunk-ND2GUHAM-Ci2Uced7.js";import"./chunk-55IACEB6-DKrRRHUF.js";import"./chunk-2J33WTMH-gAZA5DgB.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-CS0a2Thu.js";import{b as i}from"./mermaid.core-qDFbsd8h.js";import"./chunk-FMBD7UC4-CXZHiTPS.js";import"./chunk-ND2GUHAM-csH3zcum.js";import"./chunk-55IACEB6-5l5MVsCt.js";import"./chunk-2J33WTMH-C8D1eUWb.js";import"./purify.es-DxCUJf2h.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-CQV2NHjD.js";import{b as i}from"./mermaid.core--pqIgmQ1.js";import"./chunk-FMBD7UC4-Bc0aUKy7.js";import"./chunk-ND2GUHAM-Ci2Uced7.js";import"./chunk-55IACEB6-DKrRRHUF.js";import"./chunk-2J33WTMH-gAZA5DgB.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{s as a,a as s,c as e,C as t}from"./chunk-727SXJPM-CS0a2Thu.js";import{b as i}from"./mermaid.core-qDFbsd8h.js";import"./chunk-FMBD7UC4-CXZHiTPS.js";import"./chunk-ND2GUHAM-csH3zcum.js";import"./chunk-55IACEB6-5l5MVsCt.js";import"./chunk-2J33WTMH-C8D1eUWb.js";import"./purify.es-DxCUJf2h.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["js/index.full-BYsIATXF.js","js/_commonjsHelpers-CqkleIqs.js"])))=>i.map(i=>d[i]);
|
||||
import{_ as C,h as b,j as d,d as _,m as k,g as E,t as y,i as M,s as S}from"./bundle.js";const x="Open Free Books";let u=null;function T(){return u||(u=C(()=>import("./index.full-BYsIATXF.js").then(e=>e.i),__vite__mapDeps([0,1]))),u}function P(e){return/[\n:"\\]/.test(e)||e.startsWith(" ")||e.endsWith(" ")?`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:e}function $(e){return`---
|
||||
${Object.entries(e).map(([r,n])=>`${r}: ${P(n)}`).join(`
|
||||
`)}
|
||||
---
|
||||
|
||||
`}function A(){const e=document.querySelector(".book-chapter");if(!e)throw new Error("Chapter content not found on this page.");const t=e.cloneNode(!0);return t.querySelectorAll(".math-widget-mount, [data-copy-exclude]").forEach(r=>{r.remove()}),t}function D(e){const t=document.implementation.createHTMLDocument("copy");return t.body.appendChild(e),t}function L(e,t){var i;const r=e.trim();if(r)return r;const n=t.querySelector("h1");return((i=n==null?void 0:n.textContent)==null?void 0:i.trim())??"Untitled chapter"}async function R(){var s;const e=A(),t=D(e),r=window.location.href,{default:n}=await T(),i=new n(t,{markdown:!0,url:r,useAsync:!1,contentSelector:".book-chapter"}).parse(),l=L(i.title,e),c=i.content.trim(),a=$({title:l,source:r,site:x})+c;if(!((s=navigator.clipboard)!=null&&s.writeText))throw new Error("Clipboard is not available in this browser.");await navigator.clipboard.writeText(a)}var I=y('<svg class=copy-page-button__icon width=16 height=16 viewBox="0 0 16 16"aria-hidden=true><rect x=5 y=5 width=9 height=9 rx=1.5 fill=none stroke=currentColor stroke-width=1.25></rect><path d="M3 11V3.5A1.5 1.5 0 0 1 4.5 2H11"fill=none stroke=currentColor stroke-width=1.25 stroke-linecap=round>'),O=y('<div class=copy-page-button-wrap><button type=button class=copy-page-button title="Copy page as Markdown for LLMs"><span class=copy-page-button__label></span></button><p class=copy-page-button__status aria-live=polite>');const w=2e3;function j(){return I()}function B(){const[e,t]=b("idle"),[r,n]=b(""),i=()=>{switch(e()){case"loading":return"Preparing…";case"copied":return"Copied!";case"error":return"Copy failed";default:return"Copy page"}},l=async()=>{if(e()!=="loading"){t("loading"),n("");try{await R(),t("copied"),window.setTimeout(()=>{e()==="copied"&&t("idle")},w)}catch(c){t("error"),n(c instanceof Error?c.message:"Could not copy page."),window.setTimeout(()=>{e()==="error"&&(t("idle"),n(""))},w)}}};return(()=>{var c=O(),a=c.firstChild,s=a.firstChild,v=a.nextSibling;return a.$$click=l,d(a,_(j,{}),s),d(s,i),d(v,(()=>{var o=k(()=>e()==="error");return()=>o()?r():e()==="copied"?"Page copied to clipboard.":""})()),E(o=>{var p=e()==="loading",g=e()==="copied",f=e()==="error",h=e()==="loading",m=i();return p!==o.e&&a.classList.toggle("copy-page-button--loading",o.e=p),g!==o.t&&a.classList.toggle("copy-page-button--copied",o.t=g),f!==o.a&&a.classList.toggle("copy-page-button--error",o.a=f),h!==o.o&&(a.disabled=o.o=h),m!==o.i&&S(a,"aria-label",o.i=m),o},{e:void 0,t:void 0,a:void 0,o:void 0,i:void 0}),c})()}M(["click"]);export{B as CopyPageButton};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
331
themes/openfreebooks/static/js/cytoscape.esm-LDYqcvCF.js
Normal file
331
themes/openfreebooks/static/js/cytoscape.esm-LDYqcvCF.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
themes/openfreebooks/static/js/defaultLocale-CrowFXzY.js
Normal file
1
themes/openfreebooks/static/js/defaultLocale-CrowFXzY.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
function J(n){return Math.abs(n=Math.round(n))>=1e21?n.toLocaleString("en").replace(/,/g,""):n.toString(10)}function j(n,t){if(!isFinite(n)||n===0)return null;var e=(n=t?n.toExponential(t-1):n.toExponential()).indexOf("e"),i=n.slice(0,e);return[i.length>1?i[0]+i.slice(2):i,+n.slice(e+1)]}function K(n){return n=j(Math.abs(n)),n?n[1]:NaN}function Q(n,t){return function(e,i){for(var o=e.length,a=[],c=0,h=n[0],M=0;o>0&&h>0&&(M+h+1>i&&(h=Math.max(1,i-M)),a.push(e.substring(o-=h,o+h)),!((M+=h+1)>i));)h=n[c=(c+1)%n.length];return a.reverse().join(t)}}function V(n){return function(t){return t.replace(/[0-9]/g,function(e){return n[+e]})}}var W=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function $(n){if(!(t=W.exec(n)))throw new Error("invalid format: "+n);var t;return new L({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}$.prototype=L.prototype;function L(n){this.fill=n.fill===void 0?" ":n.fill+"",this.align=n.align===void 0?">":n.align+"",this.sign=n.sign===void 0?"-":n.sign+"",this.symbol=n.symbol===void 0?"":n.symbol+"",this.zero=!!n.zero,this.width=n.width===void 0?void 0:+n.width,this.comma=!!n.comma,this.precision=n.precision===void 0?void 0:+n.precision,this.trim=!!n.trim,this.type=n.type===void 0?"":n.type+""}L.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function _(n){n:for(var t=n.length,e=1,i=-1,o;e<t;++e)switch(n[e]){case".":i=o=e;break;case"0":i===0&&(i=e),o=e;break;default:if(!+n[e])break n;i>0&&(i=0);break}return i>0?n.slice(0,i)+n.slice(o+1):n}var N;function v(n,t){var e=j(n,t);if(!e)return N=void 0,n.toPrecision(t);var i=e[0],o=e[1],a=o-(N=Math.max(-8,Math.min(8,Math.floor(o/3)))*3)+1,c=i.length;return a===c?i:a>c?i+new Array(a-c+1).join("0"):a>0?i.slice(0,a)+"."+i.slice(a):"0."+new Array(1-a).join("0")+j(n,Math.max(0,t+a-1))[0]}function X(n,t){var e=j(n,t);if(!e)return n+"";var i=e[0],o=e[1];return o<0?"0."+new Array(-o).join("0")+i:i.length>o+1?i.slice(0,o+1)+"."+i.slice(o+1):i+new Array(o-i.length+2).join("0")}const O={"%":(n,t)=>(n*100).toFixed(t),b:n=>Math.round(n).toString(2),c:n=>n+"",d:J,e:(n,t)=>n.toExponential(t),f:(n,t)=>n.toFixed(t),g:(n,t)=>n.toPrecision(t),o:n=>Math.round(n).toString(8),p:(n,t)=>X(n*100,t),r:X,s:v,X:n=>Math.round(n).toString(16).toUpperCase(),x:n=>Math.round(n).toString(16)};function R(n){return n}var U=Array.prototype.map,Y=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function nn(n){var t=n.grouping===void 0||n.thousands===void 0?R:Q(U.call(n.grouping,Number),n.thousands+""),e=n.currency===void 0?"":n.currency[0]+"",i=n.currency===void 0?"":n.currency[1]+"",o=n.decimal===void 0?".":n.decimal+"",a=n.numerals===void 0?R:V(U.call(n.numerals,String)),c=n.percent===void 0?"%":n.percent+"",h=n.minus===void 0?"−":n.minus+"",M=n.nan===void 0?"NaN":n.nan+"";function T(f,g){f=$(f);var b=f.fill,p=f.align,m=f.sign,w=f.symbol,S=f.zero,E=f.width,F=f.comma,y=f.precision,C=f.trim,d=f.type;d==="n"?(F=!0,d="g"):O[d]||(y===void 0&&(y=12),C=!0,d="g"),(S||b==="0"&&p==="=")&&(S=!0,b="0",p="=");var q=(g&&g.prefix!==void 0?g.prefix:"")+(w==="$"?e:w==="#"&&/[boxX]/.test(d)?"0"+d.toLowerCase():""),B=(w==="$"?i:/[%p]/.test(d)?c:"")+(g&&g.suffix!==void 0?g.suffix:""),D=O[d],H=/[defgprs%]/.test(d);y=y===void 0?6:/[gprs]/.test(d)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y));function G(r){var l=q,u=B,x,I,k;if(d==="c")u=D(r)+u,r="";else{r=+r;var P=r<0||1/r<0;if(r=isNaN(r)?M:D(Math.abs(r),y),C&&(r=_(r)),P&&+r==0&&m!=="+"&&(P=!1),l=(P?m==="("?m:h:m==="-"||m==="("?"":m)+l,u=(d==="s"&&!isNaN(r)&&N!==void 0?Y[8+N/3]:"")+u+(P&&m==="("?")":""),H){for(x=-1,I=r.length;++x<I;)if(k=r.charCodeAt(x),48>k||k>57){u=(k===46?o+r.slice(x+1):r.slice(x))+u,r=r.slice(0,x);break}}}F&&!S&&(r=t(r,1/0));var z=l.length+r.length+u.length,s=z<E?new Array(E-z+1).join(b):"";switch(F&&S&&(r=t(s+r,s.length?E-u.length:1/0),s=""),p){case"<":r=l+r+u+s;break;case"=":r=l+s+r+u;break;case"^":r=s.slice(0,z=s.length>>1)+l+r+u+s.slice(z);break;default:r=s+l+r+u;break}return a(r)}return G.toString=function(){return f+""},G}function Z(f,g){var b=Math.max(-8,Math.min(8,Math.floor(K(g)/3)))*3,p=Math.pow(10,-b),m=T((f=$(f),f.type="f",f),{suffix:Y[8+b/3]});return function(w){return m(p*w)}}return{format:T,formatPrefix:Z}}var A,tn,rn;en({thousands:",",grouping:[3],currency:["$",""]});function en(n){return A=nn(n),tn=A.format,rn=A.formatPrefix,A}export{rn as a,$ as b,K as e,tn as f};
|
||||
43
themes/openfreebooks/static/js/diagram-2AECGRRQ-B_iSiIFa.js
Normal file
43
themes/openfreebooks/static/js/diagram-2AECGRRQ-B_iSiIFa.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import{b0 as k,a1 as R,a5 as E,b3 as I,a2 as D,b1 as F,b as l,a$ as _,t as z,s as y,a3 as C,S as G,aD as P,ae as W,E as B}from"./mermaid.core--pqIgmQ1.js";import{p as V}from"./chunk-4BX2VUAB-BcOh58Ni.js";import{p as H}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var x={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},b={axes:[],curves:[],options:x},m=structuredClone(b),j=G.radar,N=l(()=>y({...j,...C().radar}),"getConfig"),w=l(()=>m.axes,"getAxes"),U=l(()=>m.curves,"getCurves"),X=l(()=>m.options,"getOptions"),Y=l(a=>{m.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Z=l(a=>{m.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:q(t.entries)}))},"setCurves"),q=l(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=w();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>{var o;return((o=s.axis)==null?void 0:o.$refText)===e.name});if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),J=l(a=>{var e,r,s,o,i;const t=a.reduce((n,c)=>(n[c.name]=c,n),{});m.options={showLegend:((e=t.showLegend)==null?void 0:e.value)??x.showLegend,ticks:((r=t.ticks)==null?void 0:r.value)??x.ticks,max:((s=t.max)==null?void 0:s.value)??x.max,min:((o=t.min)==null?void 0:o.value)??x.min,graticule:((i=t.graticule)==null?void 0:i.value)??x.graticule}},"setOptions"),K=l(()=>{z(),m=structuredClone(b)},"clear"),$={getAxes:w,getCurves:U,getOptions:X,setAxes:Y,setCurves:Z,setOptions:J,getConfig:N,clear:K,setAccTitle:F,getAccTitle:D,setDiagramTitle:I,getDiagramTitle:E,getAccDescription:R,setAccDescription:k},Q=l(a=>{V(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),tt={parse:l(async a=>{const t=await H("radar",a);P.debug(t),Q(t)},"parse")},et=l((a,t,e,r)=>{const s=r.db,o=s.getAxes(),i=s.getCurves(),n=s.getOptions(),c=s.getConfig(),d=s.getDiagramTitle(),p=_(t),u=at(p,c),g=n.max??Math.max(...i.map(f=>Math.max(...f.entries))),h=n.min,v=Math.min(c.width,c.height)/2;rt(u,o,v,n.ticks,n.graticule),st(u,o,v,c),M(u,o,i,h,g,n.graticule,c),T(u,i,n.showLegend,c),u.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-c.height/2-c.marginTop)},"draw"),at=l((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return B(a,r,e,t.useMaxWidth??!0),a.attr("viewBox",`0 0 ${e} ${r}`),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),rt=l((a,t,e,r,s)=>{if(s==="circle")for(let o=0;o<r;o++){const i=e*(o+1)/r;a.append("circle").attr("r",i).attr("class","radarGraticule")}else if(s==="polygon"){const o=t.length;for(let i=0;i<r;i++){const n=e*(i+1)/r,c=t.map((d,p)=>{const u=2*p*Math.PI/o-Math.PI/2,g=n*Math.cos(u),h=n*Math.sin(u);return`${g},${h}`}).join(" ");a.append("polygon").attr("points",c).attr("class","radarGraticule")}}},"drawGraticule"),st=l((a,t,e,r)=>{const s=t.length;for(let o=0;o<s;o++){const i=t[o].label,n=2*o*Math.PI/s-Math.PI/2;a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*Math.cos(n)).attr("y2",e*r.axisScaleFactor*Math.sin(n)).attr("class","radarAxisLine"),a.append("text").text(i).attr("x",e*r.axisLabelFactor*Math.cos(n)).attr("y",e*r.axisLabelFactor*Math.sin(n)).attr("class","radarAxisLabel")}},"drawAxes");function M(a,t,e,r,s,o,i){const n=t.length,c=Math.min(i.width,i.height)/2;e.forEach((d,p)=>{if(d.entries.length!==n)return;const u=d.entries.map((g,h)=>{const v=2*Math.PI*h/n-Math.PI/2,f=A(g,r,s,c),S=f*Math.cos(v),O=f*Math.sin(v);return{x:S,y:O}});o==="circle"?a.append("path").attr("d",L(u,i.curveTension)).attr("class",`radarCurve-${p}`):o==="polygon"&&a.append("polygon").attr("points",u.map(g=>`${g.x},${g.y}`).join(" ")).attr("class",`radarCurve-${p}`)})}l(M,"drawCurves");function A(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}l(A,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const o=a[(s-1+e)%e],i=a[s],n=a[(s+1)%e],c=a[(s+2)%e],d={x:i.x+(n.x-o.x)*t,y:i.y+(n.y-o.y)*t},p={x:n.x-(c.x-i.x)*t,y:n.y-(c.y-i.y)*t};r+=` C${d.x},${d.y} ${p.x},${p.y} ${n.x},${n.y}`}return`${r} Z`}l(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,o=-(r.height/2+r.marginTop)*3/4,i=20;t.forEach((n,c)=>{const d=a.append("g").attr("transform",`translate(${s}, ${o+c*i})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${c}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}l(T,"drawLegend");var nt={draw:et},ot=l((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=`
|
||||
.radarCurve-${r} {
|
||||
color: ${s};
|
||||
fill: ${s};
|
||||
fill-opacity: ${t.curveOpacity};
|
||||
stroke: ${s};
|
||||
stroke-width: ${t.curveStrokeWidth};
|
||||
}
|
||||
.radarLegendBox-${r} {
|
||||
fill: ${s};
|
||||
fill-opacity: ${t.curveOpacity};
|
||||
stroke: ${s};
|
||||
}
|
||||
`}return e},"genIndexStyles"),it=l(a=>{const t=W(),e=C(),r=y(t,e.themeVariables),s=y(r.radar,a);return{themeVariables:r,radarOptions:s}},"buildRadarStyleOptions"),lt=l(({radar:a}={})=>{const{themeVariables:t,radarOptions:e}=it(a);return`
|
||||
.radarTitle {
|
||||
font-size: ${t.fontSize};
|
||||
color: ${t.titleColor};
|
||||
dominant-baseline: hanging;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.radarAxisLine {
|
||||
stroke: ${e.axisColor};
|
||||
stroke-width: ${e.axisStrokeWidth};
|
||||
}
|
||||
.radarAxisLabel {
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
font-size: ${e.axisLabelFontSize}px;
|
||||
color: ${e.axisColor};
|
||||
}
|
||||
.radarGraticule {
|
||||
fill: ${e.graticuleColor};
|
||||
fill-opacity: ${e.graticuleOpacity};
|
||||
stroke: ${e.graticuleColor};
|
||||
stroke-width: ${e.graticuleStrokeWidth};
|
||||
}
|
||||
.radarLegendText {
|
||||
text-anchor: start;
|
||||
font-size: ${e.legendFontSize}px;
|
||||
dominant-baseline: hanging;
|
||||
}
|
||||
${ot(t,e)}
|
||||
`},"styles"),mt={parser:tt,db:$,renderer:nt,styles:lt};export{mt as diagram};
|
||||
43
themes/openfreebooks/static/js/diagram-2AECGRRQ-D_C0G3Tn.js
Normal file
43
themes/openfreebooks/static/js/diagram-2AECGRRQ-D_C0G3Tn.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import{a$ as k,a1 as R,a5 as E,b2 as I,a2 as _,b0 as D,b as l,a_ as F,t as z,s as y,a3 as C,S as G,aD as P,ae as W,E as B}from"./mermaid.core-qDFbsd8h.js";import{p as V}from"./chunk-4BX2VUAB-CXdTzE3J.js";import{p as H}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";import"./purify.es-DxCUJf2h.js";var x={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},b={axes:[],curves:[],options:x},m=structuredClone(b),j=G.radar,N=l(()=>y({...j,...C().radar}),"getConfig"),w=l(()=>m.axes,"getAxes"),U=l(()=>m.curves,"getCurves"),X=l(()=>m.options,"getOptions"),Y=l(a=>{m.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Z=l(a=>{m.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:q(t.entries)}))},"setCurves"),q=l(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=w();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>{var o;return((o=s.axis)==null?void 0:o.$refText)===e.name});if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),J=l(a=>{var e,r,s,o,i;const t=a.reduce((n,c)=>(n[c.name]=c,n),{});m.options={showLegend:((e=t.showLegend)==null?void 0:e.value)??x.showLegend,ticks:((r=t.ticks)==null?void 0:r.value)??x.ticks,max:((s=t.max)==null?void 0:s.value)??x.max,min:((o=t.min)==null?void 0:o.value)??x.min,graticule:((i=t.graticule)==null?void 0:i.value)??x.graticule}},"setOptions"),K=l(()=>{z(),m=structuredClone(b)},"clear"),$={getAxes:w,getCurves:U,getOptions:X,setAxes:Y,setCurves:Z,setOptions:J,getConfig:N,clear:K,setAccTitle:D,getAccTitle:_,setDiagramTitle:I,getDiagramTitle:E,getAccDescription:R,setAccDescription:k},Q=l(a=>{V(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),tt={parse:l(async a=>{const t=await H("radar",a);P.debug(t),Q(t)},"parse")},et=l((a,t,e,r)=>{const s=r.db,o=s.getAxes(),i=s.getCurves(),n=s.getOptions(),c=s.getConfig(),d=s.getDiagramTitle(),p=F(t),u=at(p,c),g=n.max??Math.max(...i.map(f=>Math.max(...f.entries))),h=n.min,v=Math.min(c.width,c.height)/2;rt(u,o,v,n.ticks,n.graticule),st(u,o,v,c),M(u,o,i,h,g,n.graticule,c),T(u,i,n.showLegend,c),u.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-c.height/2-c.marginTop)},"draw"),at=l((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return B(a,r,e,t.useMaxWidth??!0),a.attr("viewBox",`0 0 ${e} ${r}`),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),rt=l((a,t,e,r,s)=>{if(s==="circle")for(let o=0;o<r;o++){const i=e*(o+1)/r;a.append("circle").attr("r",i).attr("class","radarGraticule")}else if(s==="polygon"){const o=t.length;for(let i=0;i<r;i++){const n=e*(i+1)/r,c=t.map((d,p)=>{const u=2*p*Math.PI/o-Math.PI/2,g=n*Math.cos(u),h=n*Math.sin(u);return`${g},${h}`}).join(" ");a.append("polygon").attr("points",c).attr("class","radarGraticule")}}},"drawGraticule"),st=l((a,t,e,r)=>{const s=t.length;for(let o=0;o<s;o++){const i=t[o].label,n=2*o*Math.PI/s-Math.PI/2;a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*Math.cos(n)).attr("y2",e*r.axisScaleFactor*Math.sin(n)).attr("class","radarAxisLine"),a.append("text").text(i).attr("x",e*r.axisLabelFactor*Math.cos(n)).attr("y",e*r.axisLabelFactor*Math.sin(n)).attr("class","radarAxisLabel")}},"drawAxes");function M(a,t,e,r,s,o,i){const n=t.length,c=Math.min(i.width,i.height)/2;e.forEach((d,p)=>{if(d.entries.length!==n)return;const u=d.entries.map((g,h)=>{const v=2*Math.PI*h/n-Math.PI/2,f=A(g,r,s,c),S=f*Math.cos(v),O=f*Math.sin(v);return{x:S,y:O}});o==="circle"?a.append("path").attr("d",L(u,i.curveTension)).attr("class",`radarCurve-${p}`):o==="polygon"&&a.append("polygon").attr("points",u.map(g=>`${g.x},${g.y}`).join(" ")).attr("class",`radarCurve-${p}`)})}l(M,"drawCurves");function A(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}l(A,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const o=a[(s-1+e)%e],i=a[s],n=a[(s+1)%e],c=a[(s+2)%e],d={x:i.x+(n.x-o.x)*t,y:i.y+(n.y-o.y)*t},p={x:n.x-(c.x-i.x)*t,y:n.y-(c.y-i.y)*t};r+=` C${d.x},${d.y} ${p.x},${p.y} ${n.x},${n.y}`}return`${r} Z`}l(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,o=-(r.height/2+r.marginTop)*3/4,i=20;t.forEach((n,c)=>{const d=a.append("g").attr("transform",`translate(${s}, ${o+c*i})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${c}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}l(T,"drawLegend");var nt={draw:et},ot=l((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=`
|
||||
.radarCurve-${r} {
|
||||
color: ${s};
|
||||
fill: ${s};
|
||||
fill-opacity: ${t.curveOpacity};
|
||||
stroke: ${s};
|
||||
stroke-width: ${t.curveStrokeWidth};
|
||||
}
|
||||
.radarLegendBox-${r} {
|
||||
fill: ${s};
|
||||
fill-opacity: ${t.curveOpacity};
|
||||
stroke: ${s};
|
||||
}
|
||||
`}return e},"genIndexStyles"),it=l(a=>{const t=W(),e=C(),r=y(t,e.themeVariables),s=y(r.radar,a);return{themeVariables:r,radarOptions:s}},"buildRadarStyleOptions"),lt=l(({radar:a}={})=>{const{themeVariables:t,radarOptions:e}=it(a);return`
|
||||
.radarTitle {
|
||||
font-size: ${t.fontSize};
|
||||
color: ${t.titleColor};
|
||||
dominant-baseline: hanging;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.radarAxisLine {
|
||||
stroke: ${e.axisColor};
|
||||
stroke-width: ${e.axisStrokeWidth};
|
||||
}
|
||||
.radarAxisLabel {
|
||||
dominant-baseline: middle;
|
||||
text-anchor: middle;
|
||||
font-size: ${e.axisLabelFontSize}px;
|
||||
color: ${e.axisColor};
|
||||
}
|
||||
.radarGraticule {
|
||||
fill: ${e.graticuleColor};
|
||||
fill-opacity: ${e.graticuleOpacity};
|
||||
stroke: ${e.graticuleColor};
|
||||
stroke-width: ${e.graticuleStrokeWidth};
|
||||
}
|
||||
.radarLegendText {
|
||||
text-anchor: start;
|
||||
font-size: ${e.legendFontSize}px;
|
||||
dominant-baseline: hanging;
|
||||
}
|
||||
${ot(t,e)}
|
||||
`},"styles"),xt={parser:tt,db:$,renderer:nt,styles:lt};export{xt as diagram};
|
||||
10
themes/openfreebooks/static/js/diagram-5GNKFQAL-3vvGYB9L.js
Normal file
10
themes/openfreebooks/static/js/diagram-5GNKFQAL-3vvGYB9L.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import{b2 as x,b0 as f,a$ as C,a5 as B,a1 as T,a2 as y,b as s,s as u,aD as k,a_ as V,E as S,a3 as _,t as D,S as N}from"./mermaid.core-qDFbsd8h.js";import{p as $}from"./chunk-4BX2VUAB-CXdTzE3J.js";import{I as A}from"./chunk-QZHKN3VN-BlHAStey.js";import{p as I}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";import"./purify.es-DxCUJf2h.js";var l=new A(()=>({cnt:1,stack:[{id:0,level:-1,name:"/",children:[]}]})),X=s(()=>{l.reset(),D()},"clear"),z=s(()=>l.records.stack[0],"getRoot"),E=s(()=>l.records.cnt,"getCount"),H=N.treeView,L=s(()=>u(H,_().treeView),"getConfig"),R=s((e,t)=>{for(;e<=l.records.stack[l.records.stack.length-1].level;)l.records.stack.pop();const a={id:l.records.cnt++,level:e,name:t,children:[]};l.records.stack[l.records.stack.length-1].children.push(a),l.records.stack.push(a)},"addNode"),W={clear:X,addNode:R,getRoot:z,getCount:E,getConfig:L,getAccTitle:y,getAccDescription:T,getDiagramTitle:B,setAccDescription:C,setAccTitle:f,setDiagramTitle:x},w=W,M=s(e=>{$(e,w),e.nodes.map(t=>w.addNode(t.indent?parseInt(t.indent):0,t.name))},"populate"),F={parse:s(async e=>{const t=await I("treeView",e);k.debug(t),M(t)},"parse")},Y=s((e,t,a,n,o)=>{const c=n.append("text").text(a.name).attr("dominant-baseline","middle").attr("class","treeView-node-label"),{height:p,width:r}=c.node().getBBox(),d=p+o.paddingY*2,i=r+o.paddingX*2;c.attr("x",e+o.paddingX),c.attr("y",t+d/2),a.BBox={x:e,y:t,width:i,height:d}},"positionLabel"),b=s((e,t,a,n,o,c)=>e.append("line").attr("x1",t).attr("y1",a).attr("x2",n).attr("y2",o).attr("stroke-width",c).attr("class","treeView-node-line"),"positionLine"),j=s((e,t,a)=>{let n=0,o=0;const c=s((r,d,i,h)=>{const v=h*(i.rowIndent+i.paddingX);Y(v,n,d,r,i);const{height:g,width:m}=d.BBox;b(r,v-i.rowIndent,n+g/2,v,n+g/2,i.lineThickness),o=Math.max(o,v+m),n+=g},"drawNode"),p=s((r,d=0)=>{c(e,r,a,d),r.children.forEach(g=>{p(g,d+1)});const{x:i,y:h,height:v}=r.BBox;if(r.children.length){const{y:g,height:m}=r.children[r.children.length-1].BBox;b(e,i+a.paddingX,h+v,i+a.paddingX,g+m/2+a.lineThickness/2,a.lineThickness)}},"processNode");return p(t),{totalHeight:n,totalWidth:o}},"drawTree"),q=s((e,t,a,n)=>{k.debug(`Rendering treeView diagram
|
||||
`+e);const o=n.db,c=o.getRoot(),p=o.getConfig(),r=V(t),d=r.append("g");d.attr("class","tree-view");const{totalHeight:i,totalWidth:h}=j(d,c,p);r.attr("viewBox",`-${p.lineThickness/2} 0 ${h} ${i}`),S(r,i,h,p.useMaxWidth)},"draw"),G={draw:q},J=G,K={labelFontSize:"16px",labelColor:"black",lineColor:"black"},O=s(({treeView:e})=>{const{labelFontSize:t,labelColor:a,lineColor:n}=u(K,e);return`
|
||||
.treeView-node-label {
|
||||
font-size: ${t};
|
||||
fill: ${a};
|
||||
}
|
||||
.treeView-node-line {
|
||||
stroke: ${n};
|
||||
}
|
||||
`},"styles"),P=O,se={db:w,renderer:J,parser:F,styles:P};export{se as diagram};
|
||||
10
themes/openfreebooks/static/js/diagram-5GNKFQAL-9oUvF2Ho.js
Normal file
10
themes/openfreebooks/static/js/diagram-5GNKFQAL-9oUvF2Ho.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import{b3 as x,b1 as f,b0 as C,a5 as B,a1 as T,a2 as y,b as s,s as u,aD as k,a$ as V,E as S,a3 as D,t as N,S as _}from"./mermaid.core--pqIgmQ1.js";import{p as $}from"./chunk-4BX2VUAB-BcOh58Ni.js";import{I as A}from"./chunk-QZHKN3VN-Bvp-TMtd.js";import{p as I}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var l=new A(()=>({cnt:1,stack:[{id:0,level:-1,name:"/",children:[]}]})),X=s(()=>{l.reset(),N()},"clear"),z=s(()=>l.records.stack[0],"getRoot"),E=s(()=>l.records.cnt,"getCount"),H=_.treeView,L=s(()=>u(H,D().treeView),"getConfig"),R=s((e,t)=>{for(;e<=l.records.stack[l.records.stack.length-1].level;)l.records.stack.pop();const a={id:l.records.cnt++,level:e,name:t,children:[]};l.records.stack[l.records.stack.length-1].children.push(a),l.records.stack.push(a)},"addNode"),W={clear:X,addNode:R,getRoot:z,getCount:E,getConfig:L,getAccTitle:y,getAccDescription:T,getDiagramTitle:B,setAccDescription:C,setAccTitle:f,setDiagramTitle:x},m=W,M=s(e=>{$(e,m),e.nodes.map(t=>m.addNode(t.indent?parseInt(t.indent):0,t.name))},"populate"),F={parse:s(async e=>{const t=await I("treeView",e);k.debug(t),M(t)},"parse")},Y=s((e,t,a,n,o)=>{const c=n.append("text").text(a.name).attr("dominant-baseline","middle").attr("class","treeView-node-label"),{height:g,width:r}=c.node().getBBox(),d=g+o.paddingY*2,i=r+o.paddingX*2;c.attr("x",e+o.paddingX),c.attr("y",t+d/2),a.BBox={x:e,y:t,width:i,height:d}},"positionLabel"),w=s((e,t,a,n,o,c)=>e.append("line").attr("x1",t).attr("y1",a).attr("x2",n).attr("y2",o).attr("stroke-width",c).attr("class","treeView-node-line"),"positionLine"),j=s((e,t,a)=>{let n=0,o=0;const c=s((r,d,i,h)=>{const v=h*(i.rowIndent+i.paddingX);Y(v,n,d,r,i);const{height:p,width:b}=d.BBox;w(r,v-i.rowIndent,n+p/2,v,n+p/2,i.lineThickness),o=Math.max(o,v+b),n+=p},"drawNode"),g=s((r,d=0)=>{c(e,r,a,d),r.children.forEach(p=>{g(p,d+1)});const{x:i,y:h,height:v}=r.BBox;if(r.children.length){const{y:p,height:b}=r.children[r.children.length-1].BBox;w(e,i+a.paddingX,h+v,i+a.paddingX,p+b/2+a.lineThickness/2,a.lineThickness)}},"processNode");return g(t),{totalHeight:n,totalWidth:o}},"drawTree"),q=s((e,t,a,n)=>{k.debug(`Rendering treeView diagram
|
||||
`+e);const o=n.db,c=o.getRoot(),g=o.getConfig(),r=V(t),d=r.append("g");d.attr("class","tree-view");const{totalHeight:i,totalWidth:h}=j(d,c,g);r.attr("viewBox",`-${g.lineThickness/2} 0 ${h} ${i}`),S(r,i,h,g.useMaxWidth)},"draw"),G={draw:q},J=G,K={labelFontSize:"16px",labelColor:"black",lineColor:"black"},O=s(({treeView:e})=>{const{labelFontSize:t,labelColor:a,lineColor:n}=u(K,e);return`
|
||||
.treeView-node-label {
|
||||
font-size: ${t};
|
||||
fill: ${a};
|
||||
}
|
||||
.treeView-node-line {
|
||||
stroke: ${n};
|
||||
}
|
||||
`},"styles"),P=O,re={db:m,renderer:J,parser:F,styles:P};export{re as diagram};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
24
themes/openfreebooks/static/js/diagram-LMA3HP47-Chz9eTgS.js
Normal file
24
themes/openfreebooks/static/js/diagram-LMA3HP47-Chz9eTgS.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import{b,s as m,a_ as B,E as C,aD as w,b0 as S,a2 as D,b2 as T,a5 as E,a1 as P,a$ as z,a3 as F,S as A,t as W}from"./mermaid.core-qDFbsd8h.js";import{p as _}from"./chunk-4BX2VUAB-CXdTzE3J.js";import{p as N}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";import"./purify.es-DxCUJf2h.js";var L=A.packet,u,v=(u=class{constructor(){this.packet=[],this.setAccTitle=S,this.getAccTitle=D,this.setDiagramTitle=T,this.getDiagramTitle=E,this.getAccDescription=P,this.setAccDescription=z}getConfig(){const t=m({...L,...F().packet});return t.showBits&&(t.paddingY+=10),t}getPacket(){return this.packet}pushWord(t){t.length>0&&this.packet.push(t)}clear(){W(),this.packet=[]}},b(u,"PacketDB"),u),M=1e4,Y=b((e,t)=>{_(e,t);let o=-1,r=[],n=1;const{bitsPerRow:l}=t.getConfig();for(let{start:a,end:i,bits:d,label:c}of e.blocks){if(a!==void 0&&i!==void 0&&i<a)throw new Error(`Packet block ${a} - ${i} is invalid. End must be greater than start.`);if(a??(a=o+1),a!==o+1)throw new Error(`Packet block ${a} - ${i??a} is not contiguous. It should start from ${o+1}.`);if(d===0)throw new Error(`Packet block ${a} is invalid. Cannot have a zero bit field.`);for(i??(i=a+(d??1)-1),d??(d=i-a+1),o=i,w.debug(`Packet block ${a} - ${o} with label ${c}`);r.length<=l+1&&t.getPacket().length<M;){const[p,s]=I({start:a,end:i,bits:d,label:c},n,l);if(r.push(p),p.end+1===n*l&&(t.pushWord(r),r=[],n++),!s)break;({start:a,end:i,bits:d,label:c}=s)}}t.pushWord(r)},"populate"),I=b((e,t,o)=>{if(e.start===void 0)throw new Error("start should have been set during first phase");if(e.end===void 0)throw new Error("end should have been set during first phase");if(e.start>e.end)throw new Error(`Block start ${e.start} is greater than block end ${e.end}.`);if(e.end+1<=t*o)return[e,void 0];const r=t*o-1,n=t*o;return[{start:e.start,end:r,label:e.label,bits:r-e.start},{start:n,end:e.end,label:e.label,bits:e.end-n}]},"getNextFittingBlock"),x={parser:{yy:void 0},parse:b(async e=>{var r;const t=await N("packet",e),o=(r=x.parser)==null?void 0:r.yy;if(!(o instanceof v))throw new Error("parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");w.debug(t),Y(t,o)},"parse")},O=b((e,t,o,r)=>{const n=r.db,l=n.getConfig(),{rowHeight:a,paddingY:i,bitWidth:d,bitsPerRow:c}=l,p=n.getPacket(),s=n.getDiagramTitle(),h=a+i,g=h*(p.length+1)-(s?0:a),k=d*c+2,f=B(t);f.attr("viewBox",`0 0 ${k} ${g}`),C(f,g,k,l.useMaxWidth);for(const[y,$]of p.entries())j(f,$,y,l);f.append("text").text(s).attr("x",k/2).attr("y",g-h/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),j=b((e,t,o,{rowHeight:r,paddingX:n,paddingY:l,bitWidth:a,bitsPerRow:i,showBits:d})=>{const c=e.append("g"),p=o*(r+l)+l;for(const s of t){const h=s.start%i*a+1,g=(s.end-s.start+1)*a-n;if(c.append("rect").attr("x",h).attr("y",p).attr("width",g).attr("height",r).attr("class","packetBlock"),c.append("text").attr("x",h+g/2).attr("y",p+r/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(s.label),!d)continue;const k=s.end===s.start,f=p-2;c.append("text").attr("x",h+(k?g/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(s.start),k||c.append("text").attr("x",h+g).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(s.end)}},"drawWord"),G={draw:O},H={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},K=b(({packet:e}={})=>{const t=m(H,e);return`
|
||||
.packetByte {
|
||||
font-size: ${t.byteFontSize};
|
||||
}
|
||||
.packetByte.start {
|
||||
fill: ${t.startByteColor};
|
||||
}
|
||||
.packetByte.end {
|
||||
fill: ${t.endByteColor};
|
||||
}
|
||||
.packetLabel {
|
||||
fill: ${t.labelColor};
|
||||
font-size: ${t.labelFontSize};
|
||||
}
|
||||
.packetTitle {
|
||||
fill: ${t.titleColor};
|
||||
font-size: ${t.titleFontSize};
|
||||
}
|
||||
.packetBlock {
|
||||
stroke: ${t.blockStrokeColor};
|
||||
stroke-width: ${t.blockStrokeWidth};
|
||||
fill: ${t.blockFillColor};
|
||||
}
|
||||
`},"styles"),V={parser:x,get db(){return new v},renderer:G,styles:K};export{V as diagram};
|
||||
24
themes/openfreebooks/static/js/diagram-LMA3HP47-DiIOVIss.js
Normal file
24
themes/openfreebooks/static/js/diagram-LMA3HP47-DiIOVIss.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import{b,s as m,a$ as B,E as C,aD as w,b1 as S,a2 as D,b3 as T,a5 as E,a1 as P,b0 as z,a3 as F,S as A,t as W}from"./mermaid.core--pqIgmQ1.js";import{p as _}from"./chunk-4BX2VUAB-BcOh58Ni.js";import{p as N}from"./wardley-L42UT6IY-v_rX5FW_.js";import"./bundle.js";import"./_commonjsHelpers-CqkleIqs.js";var L=A.packet,u,v=(u=class{constructor(){this.packet=[],this.setAccTitle=S,this.getAccTitle=D,this.setDiagramTitle=T,this.getDiagramTitle=E,this.getAccDescription=P,this.setAccDescription=z}getConfig(){const t=m({...L,...F().packet});return t.showBits&&(t.paddingY+=10),t}getPacket(){return this.packet}pushWord(t){t.length>0&&this.packet.push(t)}clear(){W(),this.packet=[]}},b(u,"PacketDB"),u),M=1e4,Y=b((e,t)=>{_(e,t);let s=-1,r=[],n=1;const{bitsPerRow:l}=t.getConfig();for(let{start:a,end:i,bits:d,label:c}of e.blocks){if(a!==void 0&&i!==void 0&&i<a)throw new Error(`Packet block ${a} - ${i} is invalid. End must be greater than start.`);if(a??(a=s+1),a!==s+1)throw new Error(`Packet block ${a} - ${i??a} is not contiguous. It should start from ${s+1}.`);if(d===0)throw new Error(`Packet block ${a} is invalid. Cannot have a zero bit field.`);for(i??(i=a+(d??1)-1),d??(d=i-a+1),s=i,w.debug(`Packet block ${a} - ${s} with label ${c}`);r.length<=l+1&&t.getPacket().length<M;){const[p,o]=I({start:a,end:i,bits:d,label:c},n,l);if(r.push(p),p.end+1===n*l&&(t.pushWord(r),r=[],n++),!o)break;({start:a,end:i,bits:d,label:c}=o)}}t.pushWord(r)},"populate"),I=b((e,t,s)=>{if(e.start===void 0)throw new Error("start should have been set during first phase");if(e.end===void 0)throw new Error("end should have been set during first phase");if(e.start>e.end)throw new Error(`Block start ${e.start} is greater than block end ${e.end}.`);if(e.end+1<=t*s)return[e,void 0];const r=t*s-1,n=t*s;return[{start:e.start,end:r,label:e.label,bits:r-e.start},{start:n,end:e.end,label:e.label,bits:e.end-n}]},"getNextFittingBlock"),x={parser:{yy:void 0},parse:b(async e=>{var r;const t=await N("packet",e),s=(r=x.parser)==null?void 0:r.yy;if(!(s instanceof v))throw new Error("parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");w.debug(t),Y(t,s)},"parse")},O=b((e,t,s,r)=>{const n=r.db,l=n.getConfig(),{rowHeight:a,paddingY:i,bitWidth:d,bitsPerRow:c}=l,p=n.getPacket(),o=n.getDiagramTitle(),h=a+i,g=h*(p.length+1)-(o?0:a),k=d*c+2,f=B(t);f.attr("viewBox",`0 0 ${k} ${g}`),C(f,g,k,l.useMaxWidth);for(const[y,$]of p.entries())j(f,$,y,l);f.append("text").text(o).attr("x",k/2).attr("y",g-h/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),j=b((e,t,s,{rowHeight:r,paddingX:n,paddingY:l,bitWidth:a,bitsPerRow:i,showBits:d})=>{const c=e.append("g"),p=s*(r+l)+l;for(const o of t){const h=o.start%i*a+1,g=(o.end-o.start+1)*a-n;if(c.append("rect").attr("x",h).attr("y",p).attr("width",g).attr("height",r).attr("class","packetBlock"),c.append("text").attr("x",h+g/2).attr("y",p+r/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(o.label),!d)continue;const k=o.end===o.start,f=p-2;c.append("text").attr("x",h+(k?g/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(o.start),k||c.append("text").attr("x",h+g).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(o.end)}},"drawWord"),G={draw:O},H={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},K=b(({packet:e}={})=>{const t=m(H,e);return`
|
||||
.packetByte {
|
||||
font-size: ${t.byteFontSize};
|
||||
}
|
||||
.packetByte.start {
|
||||
fill: ${t.startByteColor};
|
||||
}
|
||||
.packetByte.end {
|
||||
fill: ${t.endByteColor};
|
||||
}
|
||||
.packetLabel {
|
||||
fill: ${t.labelColor};
|
||||
font-size: ${t.labelFontSize};
|
||||
}
|
||||
.packetTitle {
|
||||
fill: ${t.titleColor};
|
||||
font-size: ${t.titleFontSize};
|
||||
}
|
||||
.packetBlock {
|
||||
stroke: ${t.blockStrokeColor};
|
||||
stroke-width: ${t.blockStrokeWidth};
|
||||
fill: ${t.blockFillColor};
|
||||
}
|
||||
`},"styles"),Q={parser:x,get db(){return new v},renderer:G,styles:K};export{Q as diagram};
|
||||
24
themes/openfreebooks/static/js/diagram-OG6HWLK6-Du0FYRMa.js
Normal file
24
themes/openfreebooks/static/js/diagram-OG6HWLK6-Du0FYRMa.js
Normal file
File diff suppressed because one or more lines are too long
24
themes/openfreebooks/static/js/diagram-OG6HWLK6-l1gHsg9X.js
Normal file
24
themes/openfreebooks/static/js/diagram-OG6HWLK6-l1gHsg9X.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
162
themes/openfreebooks/static/js/flowDiagram-I6XJVG4X-Cg59DpsN.js
Normal file
162
themes/openfreebooks/static/js/flowDiagram-I6XJVG4X-Cg59DpsN.js
Normal file
File diff suppressed because one or more lines are too long
162
themes/openfreebooks/static/js/flowDiagram-I6XJVG4X-pfwD2eLL.js
Normal file
162
themes/openfreebooks/static/js/flowDiagram-I6XJVG4X-pfwD2eLL.js
Normal file
File diff suppressed because one or more lines are too long
292
themes/openfreebooks/static/js/ganttDiagram-6RSMTGT7-BIJMFWLy.js
Normal file
292
themes/openfreebooks/static/js/ganttDiagram-6RSMTGT7-BIJMFWLy.js
Normal file
File diff suppressed because one or more lines are too long
292
themes/openfreebooks/static/js/ganttDiagram-6RSMTGT7-D2U4Lrk-.js
Normal file
292
themes/openfreebooks/static/js/ganttDiagram-6RSMTGT7-D2U4Lrk-.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue