@teamvelix/velix 5.2.6 → 5.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/index.js +3 -3
- package/dist/chunk-BQ4HFLRL.js +16 -0
- package/dist/chunk-BQ4HFLRL.js.map +1 -0
- package/dist/{chunk-HGP4TUJS.js → chunk-HMCBOHTD.js} +472 -605
- package/dist/chunk-HMCBOHTD.js.map +1 -0
- package/dist/{chunk-MLLSS7Y5.js → chunk-RU23OKU5.js} +143 -8
- package/dist/chunk-RU23OKU5.js.map +1 -0
- package/dist/{chunk-3LWUS6AC.js → chunk-YZDIHMDS.js} +7 -3
- package/dist/chunk-YZDIHMDS.js.map +1 -0
- package/dist/client/index.js +1 -1
- package/dist/config.js +1 -1
- package/dist/{image-optimizer-KPRXE5VI.js → image-optimizer-QDXS3LHQ.js} +3 -3
- package/dist/{image-optimizer-KPRXE5VI.js.map → image-optimizer-QDXS3LHQ.js.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/islands/index.js +1 -1
- package/dist/runtime/start-build.js +164 -21
- package/dist/runtime/start-build.js.map +1 -1
- package/dist/runtime/start-dev.js +425 -416
- package/dist/runtime/start-dev.js.map +1 -1
- package/dist/runtime/start-prod.js +425 -416
- package/dist/runtime/start-prod.js.map +1 -1
- package/dist/server/index.js +3 -3
- package/package.json +3 -3
- package/dist/chunk-3LWUS6AC.js.map +0 -1
- package/dist/chunk-4S5YQJHB.js +0 -11
- package/dist/chunk-4S5YQJHB.js.map +0 -1
- package/dist/chunk-HGP4TUJS.js.map +0 -1
- package/dist/chunk-MLLSS7Y5.js.map +0 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
3
9
|
var __esm = (fn, res) => function __init() {
|
|
4
10
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
11
|
};
|
|
@@ -701,7 +707,7 @@ init_esm_shims();
|
|
|
701
707
|
|
|
702
708
|
// version.ts
|
|
703
709
|
init_esm_shims();
|
|
704
|
-
var VERSION = "5.2.
|
|
710
|
+
var VERSION = "5.2.8";
|
|
705
711
|
|
|
706
712
|
// logger.ts
|
|
707
713
|
var colors = {
|
|
@@ -1620,511 +1626,514 @@ function generateDevToolsHtml(isDev, ctx = {}) {
|
|
|
1620
1626
|
|
|
1621
1627
|
// server/error-pages.ts
|
|
1622
1628
|
init_esm_shims();
|
|
1629
|
+
function escapeHtml2(str) {
|
|
1630
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1631
|
+
}
|
|
1623
1632
|
function generate404Page(pathname = "/") {
|
|
1624
1633
|
return `<!DOCTYPE html>
|
|
1625
1634
|
<html lang="en">
|
|
1626
1635
|
<head>
|
|
1627
1636
|
<meta charset="UTF-8">
|
|
1628
1637
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1629
|
-
<title>404 - Page Not Found | Velix
|
|
1638
|
+
<title>404 - Page Not Found | Velix v${VERSION}</title>
|
|
1630
1639
|
<link rel="icon" href="/favicon.webp">
|
|
1631
1640
|
<style>
|
|
1632
|
-
|
|
1633
|
-
body {
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
text-align: center;
|
|
1643
|
-
overflow: hidden;
|
|
1644
|
-
}
|
|
1645
|
-
.container {
|
|
1646
|
-
max-width: 700px;
|
|
1647
|
-
padding: 60px 40px;
|
|
1648
|
-
position: relative;
|
|
1649
|
-
z-index: 10;
|
|
1650
|
-
}
|
|
1651
|
-
.bg-pattern {
|
|
1652
|
-
position: absolute;
|
|
1653
|
-
inset: 0;
|
|
1654
|
-
background-image: radial-gradient(circle at 20% 50%, rgba(34, 211, 238, 0.1) 0%, transparent 50%),
|
|
1655
|
-
radial-gradient(circle at 80% 80%, rgba(37, 99, 235, 0.1) 0%, transparent 50%);
|
|
1656
|
-
z-index: 1;
|
|
1657
|
-
}
|
|
1658
|
-
h1 {
|
|
1659
|
-
font-size: 180px;
|
|
1660
|
-
font-weight: 900;
|
|
1661
|
-
margin: 0;
|
|
1662
|
-
background: linear-gradient(135deg, #22D3EE 0%, #2563EB 100%);
|
|
1663
|
-
-webkit-background-clip: text;
|
|
1664
|
-
-webkit-text-fill-color: transparent;
|
|
1665
|
-
line-height: 1;
|
|
1666
|
-
letter-spacing: -0.05em;
|
|
1667
|
-
animation: fadeInUp 0.6s ease-out;
|
|
1668
|
-
}
|
|
1669
|
-
h2 {
|
|
1670
|
-
font-size: 36px;
|
|
1671
|
-
font-weight: 800;
|
|
1672
|
-
margin: 30px 0 15px;
|
|
1673
|
-
color: #F8FAFC;
|
|
1674
|
-
animation: fadeInUp 0.6s ease-out 0.1s backwards;
|
|
1641
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1642
|
+
body {
|
|
1643
|
+
background: #0a0a0a;
|
|
1644
|
+
color: #ededed;
|
|
1645
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
1646
|
+
display: flex;
|
|
1647
|
+
align-items: center;
|
|
1648
|
+
justify-content: center;
|
|
1649
|
+
min-height: 100vh;
|
|
1650
|
+
-webkit-font-smoothing: antialiased;
|
|
1675
1651
|
}
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
animation: fadeInUp 0.6s ease-out 0.2s backwards;
|
|
1652
|
+
.container {
|
|
1653
|
+
display: flex;
|
|
1654
|
+
align-items: center;
|
|
1655
|
+
gap: 32px;
|
|
1656
|
+
padding: 32px;
|
|
1682
1657
|
}
|
|
1683
|
-
code {
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
border: 1px solid rgba(34, 211, 238, 0.2);
|
|
1658
|
+
.code {
|
|
1659
|
+
font-size: 48px;
|
|
1660
|
+
font-weight: 700;
|
|
1661
|
+
line-height: 1;
|
|
1662
|
+
color: #fff;
|
|
1663
|
+
border-right: 1px solid rgba(255,255,255,0.15);
|
|
1664
|
+
padding-right: 32px;
|
|
1691
1665
|
}
|
|
1692
|
-
.
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
animation: fadeInUp 0.6s ease-out 0.3s backwards;
|
|
1666
|
+
.body h1 {
|
|
1667
|
+
font-size: 18px;
|
|
1668
|
+
font-weight: 600;
|
|
1669
|
+
color: #ededed;
|
|
1670
|
+
margin-bottom: 8px;
|
|
1698
1671
|
}
|
|
1699
|
-
.
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
text-decoration: none;
|
|
1704
|
-
padding: 14px 36px;
|
|
1705
|
-
border-radius: 12px;
|
|
1706
|
-
font-weight: 600;
|
|
1707
|
-
font-size: 16px;
|
|
1708
|
-
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
1709
|
-
box-shadow: 0 10px 30px rgba(37, 99, 235, 0.3);
|
|
1710
|
-
border: none;
|
|
1711
|
-
cursor: pointer;
|
|
1672
|
+
.body p {
|
|
1673
|
+
font-size: 14px;
|
|
1674
|
+
color: #888;
|
|
1675
|
+
margin-bottom: 20px;
|
|
1712
1676
|
}
|
|
1713
|
-
.
|
|
1714
|
-
|
|
1715
|
-
|
|
1677
|
+
.body p code {
|
|
1678
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1679
|
+
font-size: 13px;
|
|
1680
|
+
background: rgba(255,255,255,0.07);
|
|
1681
|
+
padding: 2px 6px;
|
|
1682
|
+
border-radius: 4px;
|
|
1683
|
+
color: #ccc;
|
|
1716
1684
|
}
|
|
1717
|
-
.
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1685
|
+
.actions { display: flex; gap: 10px; }
|
|
1686
|
+
.btn {
|
|
1687
|
+
display: inline-block;
|
|
1688
|
+
padding: 8px 18px;
|
|
1689
|
+
border-radius: 8px;
|
|
1690
|
+
font-size: 14px;
|
|
1691
|
+
font-weight: 500;
|
|
1692
|
+
text-decoration: none;
|
|
1693
|
+
transition: all .15s;
|
|
1694
|
+
border: 1px solid transparent;
|
|
1722
1695
|
}
|
|
1723
|
-
.btn-
|
|
1724
|
-
background:
|
|
1725
|
-
|
|
1696
|
+
.btn-primary {
|
|
1697
|
+
background: #fff;
|
|
1698
|
+
color: #000;
|
|
1726
1699
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
to {
|
|
1733
|
-
opacity: 1;
|
|
1734
|
-
transform: translateY(0);
|
|
1735
|
-
}
|
|
1700
|
+
.btn-primary:hover { background: #e5e5e5; }
|
|
1701
|
+
.btn-secondary {
|
|
1702
|
+
background: rgba(255,255,255,0.06);
|
|
1703
|
+
color: #ededed;
|
|
1704
|
+
border-color: rgba(255,255,255,0.1);
|
|
1736
1705
|
}
|
|
1706
|
+
.btn-secondary:hover { background: rgba(255,255,255,0.1); }
|
|
1737
1707
|
</style>
|
|
1738
1708
|
</head>
|
|
1739
1709
|
<body>
|
|
1740
|
-
<div class="bg-pattern"></div>
|
|
1741
1710
|
<div class="container">
|
|
1742
|
-
<
|
|
1743
|
-
<
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1711
|
+
<div class="code">404</div>
|
|
1712
|
+
<div class="body">
|
|
1713
|
+
<h1>This page could not be found</h1>
|
|
1714
|
+
<p>The path <code>${escapeHtml2(pathname)}</code> does not exist.</p>
|
|
1715
|
+
<div class="actions">
|
|
1716
|
+
<a href="/" class="btn btn-primary">Return Home</a>
|
|
1717
|
+
<a href="javascript:history.back()" class="btn btn-secondary">Go Back</a>
|
|
1718
|
+
</div>
|
|
1748
1719
|
</div>
|
|
1749
1720
|
</div>
|
|
1750
1721
|
</body>
|
|
1751
1722
|
</html>`;
|
|
1752
1723
|
}
|
|
1753
1724
|
function generate500Page(options) {
|
|
1754
|
-
const {
|
|
1755
|
-
let
|
|
1756
|
-
let
|
|
1725
|
+
const { message, stack, isDev, pathname } = options;
|
|
1726
|
+
let frames = [];
|
|
1727
|
+
let sourceSnippet = "";
|
|
1728
|
+
let errorLine = 0;
|
|
1729
|
+
let errorFile = "";
|
|
1757
1730
|
if (isDev && stack) {
|
|
1758
|
-
const stackLines = stack.split("\n").filter((
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
const
|
|
1763
|
-
if (
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1731
|
+
const stackLines = stack.split("\n").filter((l) => l.trim());
|
|
1732
|
+
frames = stackLines.slice(1).filter((line) => line.includes("at ")).map((frame) => {
|
|
1733
|
+
const m1 = frame.match(/at\s+(.+?)\s+\((.+?):(\d+):\d+\)/);
|
|
1734
|
+
if (m1) return { call: m1[1].trim(), file: m1[2], line: parseInt(m1[3], 10) };
|
|
1735
|
+
const m2 = frame.match(/at\s+(.+?):(\d+):\d+/);
|
|
1736
|
+
if (m2) return { call: "(anonymous)", file: m2[1].trim(), line: parseInt(m2[2], 10) };
|
|
1737
|
+
return { call: frame.replace(/^\s*at\s+/, "").trim(), file: "", line: null };
|
|
1738
|
+
});
|
|
1739
|
+
const firstUserFrame = frames.find((f) => f.file && !f.file.includes("node_modules")) || frames[0];
|
|
1740
|
+
if (firstUserFrame) {
|
|
1741
|
+
errorFile = firstUserFrame.file;
|
|
1742
|
+
errorLine = firstUserFrame.line || 0;
|
|
1743
|
+
if (errorFile && errorLine > 0) {
|
|
1744
|
+
try {
|
|
1745
|
+
const fs8 = __require("fs");
|
|
1746
|
+
if (fs8.existsSync(errorFile)) {
|
|
1747
|
+
const src = fs8.readFileSync(errorFile, "utf-8").split("\n");
|
|
1748
|
+
const start = Math.max(0, errorLine - 4);
|
|
1749
|
+
const end = Math.min(src.length, errorLine + 3);
|
|
1750
|
+
sourceSnippet = src.slice(start, end).map((l, i) => {
|
|
1751
|
+
const num = start + i + 1;
|
|
1752
|
+
const isErr = num === errorLine;
|
|
1753
|
+
const numStr = String(num).padStart(3, " ");
|
|
1754
|
+
if (isErr) {
|
|
1755
|
+
return `<div class="src-line src-err"><span class="ln">${numStr}</span>${escapeHtml2(l)}</div>`;
|
|
1756
|
+
}
|
|
1757
|
+
return `<div class="src-line"><span class="ln">${numStr}</span>${escapeHtml2(l)}</div>`;
|
|
1758
|
+
}).join("");
|
|
1759
|
+
}
|
|
1760
|
+
} catch (_) {
|
|
1761
|
+
}
|
|
1775
1762
|
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
const userFrames = frames.filter((f) => f.file && !f.file.includes("node_modules"));
|
|
1766
|
+
const ignoredFrames = frames.filter((f) => !f.file || f.file.includes("node_modules"));
|
|
1767
|
+
const shortFile = errorFile.replace(/\\/g, "/").replace(/.*\/(?=app\/|server\/|src\/|pages\/)/, "");
|
|
1768
|
+
if (!isDev) {
|
|
1769
|
+
return `<!DOCTYPE html>
|
|
1770
|
+
<html lang="en">
|
|
1771
|
+
<head>
|
|
1772
|
+
<meta charset="UTF-8">
|
|
1773
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1774
|
+
<title>500 - Internal Server Error | Velix</title>
|
|
1775
|
+
<link rel="icon" href="/favicon.webp">
|
|
1776
|
+
<style>
|
|
1777
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1778
|
+
body {
|
|
1779
|
+
background: #0a0a0a;
|
|
1780
|
+
color: #ededed;
|
|
1781
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
1782
|
+
display: flex; align-items: center; justify-content: center;
|
|
1783
|
+
min-height: 100vh;
|
|
1784
|
+
-webkit-font-smoothing: antialiased;
|
|
1785
|
+
}
|
|
1786
|
+
.container { display: flex; align-items: center; gap: 32px; padding: 32px; }
|
|
1787
|
+
.code { font-size: 48px; font-weight: 700; color: #fff; border-right: 1px solid rgba(255,255,255,0.15); padding-right: 32px; }
|
|
1788
|
+
.body h1 { font-size: 18px; font-weight: 600; color: #ededed; margin-bottom: 8px; }
|
|
1789
|
+
.body p { font-size: 14px; color: #888; margin-bottom: 20px; }
|
|
1790
|
+
.btn { display: inline-block; padding: 8px 18px; border-radius: 8px; font-size: 14px; font-weight: 500; text-decoration: none; background: #fff; color: #000; transition: all .15s; }
|
|
1791
|
+
.btn:hover { background: #e5e5e5; }
|
|
1792
|
+
</style>
|
|
1793
|
+
</head>
|
|
1794
|
+
<body>
|
|
1795
|
+
<div class="container">
|
|
1796
|
+
<div class="code">500</div>
|
|
1797
|
+
<div class="body">
|
|
1798
|
+
<h1>Internal Server Error</h1>
|
|
1799
|
+
<p>A server-side exception has occurred. Please try again later.</p>
|
|
1800
|
+
<a href="/" class="btn">Return Home</a>
|
|
1801
|
+
</div>
|
|
1802
|
+
</div>
|
|
1803
|
+
</body>
|
|
1804
|
+
</html>`;
|
|
1778
1805
|
}
|
|
1779
1806
|
return `<!DOCTYPE html>
|
|
1780
1807
|
<html lang="en">
|
|
1781
1808
|
<head>
|
|
1782
1809
|
<meta charset="UTF-8">
|
|
1783
1810
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1784
|
-
<title>Error | Velix
|
|
1811
|
+
<title>Error | Velix v${VERSION}</title>
|
|
1785
1812
|
<link rel="icon" href="/favicon.webp">
|
|
1786
1813
|
<style>
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
background:
|
|
1791
|
-
color: #
|
|
1792
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
1814
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
1815
|
+
|
|
1816
|
+
body {
|
|
1817
|
+
background: rgba(0, 0, 0, 0.85);
|
|
1818
|
+
color: #ededed;
|
|
1819
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
|
|
1793
1820
|
min-height: 100vh;
|
|
1794
|
-
|
|
1821
|
+
display: flex;
|
|
1822
|
+
align-items: center;
|
|
1823
|
+
justify-content: center;
|
|
1824
|
+
padding: 24px;
|
|
1825
|
+
-webkit-font-smoothing: antialiased;
|
|
1795
1826
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1827
|
+
|
|
1828
|
+
/* \u2500\u2500 Overlay Card \u2500\u2500 */
|
|
1829
|
+
.overlay {
|
|
1830
|
+
width: 100%;
|
|
1831
|
+
max-width: 940px;
|
|
1832
|
+
background: #111;
|
|
1833
|
+
border: 1px solid #2a2a2a;
|
|
1834
|
+
border-radius: 12px;
|
|
1835
|
+
box-shadow: 0 24px 64px rgba(0,0,0,0.6);
|
|
1836
|
+
overflow: hidden;
|
|
1837
|
+
display: flex;
|
|
1838
|
+
flex-direction: column;
|
|
1839
|
+
max-height: calc(100vh - 48px);
|
|
1800
1840
|
}
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
padding: 20px 28px;
|
|
1805
|
-
border-radius: 16px;
|
|
1841
|
+
|
|
1842
|
+
/* \u2500\u2500 Header Bar \u2500\u2500 */
|
|
1843
|
+
.header {
|
|
1806
1844
|
display: flex;
|
|
1807
1845
|
align-items: center;
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
}
|
|
1814
|
-
.error-header svg {
|
|
1815
|
-
width: 24px;
|
|
1816
|
-
height: 24px;
|
|
1846
|
+
justify-content: space-between;
|
|
1847
|
+
padding: 12px 20px;
|
|
1848
|
+
background: #161616;
|
|
1849
|
+
border-bottom: 1px solid #2a2a2a;
|
|
1850
|
+
gap: 12px;
|
|
1817
1851
|
flex-shrink: 0;
|
|
1818
1852
|
}
|
|
1819
|
-
.
|
|
1820
|
-
display:
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
padding: 6px 16px;
|
|
1824
|
-
border-radius: 8px;
|
|
1853
|
+
.header-left {
|
|
1854
|
+
display: flex;
|
|
1855
|
+
align-items: center;
|
|
1856
|
+
gap: 8px;
|
|
1825
1857
|
font-size: 13px;
|
|
1826
|
-
|
|
1827
|
-
margin-bottom: 18px;
|
|
1828
|
-
text-transform: uppercase;
|
|
1829
|
-
letter-spacing: 0.8px;
|
|
1830
|
-
box-shadow: 0 4px 12px rgba(30, 64, 175, 0.3);
|
|
1858
|
+
color: #888;
|
|
1831
1859
|
}
|
|
1832
|
-
.
|
|
1833
|
-
background:
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
font-size:
|
|
1838
|
-
|
|
1839
|
-
font-
|
|
1840
|
-
box-shadow: 0 4px 12px rgba(12, 74, 110, 0.3);
|
|
1841
|
-
border: 1px solid rgba(34, 211, 238, 0.2);
|
|
1842
|
-
}
|
|
1843
|
-
.error-message {
|
|
1844
|
-
background: rgba(239, 68, 68, 0.1);
|
|
1845
|
-
border-left: 4px solid #EF4444;
|
|
1846
|
-
padding: 18px 20px;
|
|
1847
|
-
border-radius: 10px;
|
|
1848
|
-
margin-bottom: 32px;
|
|
1849
|
-
}
|
|
1850
|
-
.error-message-text {
|
|
1851
|
-
color: #FCA5A5;
|
|
1852
|
-
font-size: 16px;
|
|
1853
|
-
font-weight: 600;
|
|
1854
|
-
line-height: 1.6;
|
|
1855
|
-
font-family: 'Courier New', monospace;
|
|
1856
|
-
}
|
|
1857
|
-
.stack-section {
|
|
1858
|
-
margin-top: 32px;
|
|
1860
|
+
.counter-badge {
|
|
1861
|
+
background: #1e1e1e;
|
|
1862
|
+
border: 1px solid #333;
|
|
1863
|
+
border-radius: 6px;
|
|
1864
|
+
padding: 2px 8px;
|
|
1865
|
+
font-size: 12px;
|
|
1866
|
+
color: #999;
|
|
1867
|
+
font-variant-numeric: tabular-nums;
|
|
1859
1868
|
}
|
|
1860
|
-
.
|
|
1869
|
+
.nav-btn {
|
|
1870
|
+
background: #1e1e1e;
|
|
1871
|
+
border: 1px solid #333;
|
|
1872
|
+
border-radius: 6px;
|
|
1873
|
+
color: #888;
|
|
1874
|
+
cursor: pointer;
|
|
1875
|
+
width: 24px;
|
|
1876
|
+
height: 24px;
|
|
1861
1877
|
display: flex;
|
|
1862
1878
|
align-items: center;
|
|
1863
|
-
justify-content:
|
|
1864
|
-
|
|
1879
|
+
justify-content: center;
|
|
1880
|
+
font-size: 13px;
|
|
1881
|
+
transition: all .15s;
|
|
1865
1882
|
}
|
|
1866
|
-
.
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
color: #F1F5F9;
|
|
1883
|
+
.nav-btn:hover:not(:disabled) { background: #2a2a2a; color: #fff; }
|
|
1884
|
+
.nav-btn:disabled { opacity: 0.3; cursor: default; }
|
|
1885
|
+
.framework-tag {
|
|
1870
1886
|
display: flex;
|
|
1871
1887
|
align-items: center;
|
|
1872
|
-
gap:
|
|
1888
|
+
gap: 6px;
|
|
1889
|
+
font-size: 12px;
|
|
1890
|
+
color: #666;
|
|
1873
1891
|
}
|
|
1874
|
-
.
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
border-radius:
|
|
1879
|
-
|
|
1892
|
+
.framework-tag::before {
|
|
1893
|
+
content: '';
|
|
1894
|
+
display: inline-block;
|
|
1895
|
+
width: 6px; height: 6px;
|
|
1896
|
+
border-radius: 50%;
|
|
1897
|
+
background: #3b82f6;
|
|
1898
|
+
}
|
|
1899
|
+
|
|
1900
|
+
/* \u2500\u2500 Scrollable Content \u2500\u2500 */
|
|
1901
|
+
.content {
|
|
1902
|
+
overflow-y: auto;
|
|
1903
|
+
flex: 1;
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
/* \u2500\u2500 Error Summary \u2500\u2500 */
|
|
1907
|
+
.error-summary {
|
|
1908
|
+
padding: 28px 24px 20px;
|
|
1909
|
+
border-bottom: 1px solid #1e1e1e;
|
|
1910
|
+
}
|
|
1911
|
+
.error-label {
|
|
1912
|
+
display: inline-flex;
|
|
1913
|
+
align-items: center;
|
|
1914
|
+
gap: 6px;
|
|
1915
|
+
font-size: 11px;
|
|
1880
1916
|
font-weight: 700;
|
|
1881
|
-
|
|
1917
|
+
letter-spacing: 0.08em;
|
|
1918
|
+
text-transform: uppercase;
|
|
1919
|
+
color: #f87171;
|
|
1920
|
+
background: rgba(248, 113, 113, 0.1);
|
|
1921
|
+
border: 1px solid rgba(248, 113, 113, 0.25);
|
|
1922
|
+
padding: 3px 8px;
|
|
1923
|
+
border-radius: 4px;
|
|
1924
|
+
margin-bottom: 14px;
|
|
1882
1925
|
}
|
|
1883
|
-
.error-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
display: none;
|
|
1926
|
+
.error-label svg { width: 10px; height: 10px; fill: currentColor; }
|
|
1927
|
+
.error-message {
|
|
1928
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1929
|
+
font-size: 18px;
|
|
1930
|
+
font-weight: 600;
|
|
1931
|
+
line-height: 1.5;
|
|
1932
|
+
color: #fff;
|
|
1933
|
+
word-break: break-word;
|
|
1892
1934
|
}
|
|
1893
|
-
.error-
|
|
1894
|
-
|
|
1895
|
-
|
|
1935
|
+
.error-location {
|
|
1936
|
+
margin-top: 10px;
|
|
1937
|
+
font-size: 13px;
|
|
1938
|
+
color: #888;
|
|
1896
1939
|
}
|
|
1897
|
-
.error-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1940
|
+
.error-location strong { color: #ccc; }
|
|
1941
|
+
|
|
1942
|
+
/* \u2500\u2500 Source Block \u2500\u2500 */
|
|
1943
|
+
.source-block {
|
|
1944
|
+
border-bottom: 1px solid #1e1e1e;
|
|
1901
1945
|
}
|
|
1902
|
-
.
|
|
1946
|
+
.source-topbar {
|
|
1903
1947
|
display: flex;
|
|
1904
|
-
justify-content: space-between;
|
|
1905
1948
|
align-items: center;
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
font-size: 15px;
|
|
1911
|
-
font-weight: 700;
|
|
1912
|
-
font-family: 'Courier New', monospace;
|
|
1913
|
-
}
|
|
1914
|
-
.card-number {
|
|
1915
|
-
background: rgba(34, 211, 238, 0.2);
|
|
1916
|
-
color: #22D3EE;
|
|
1917
|
-
padding: 4px 10px;
|
|
1918
|
-
border-radius: 6px;
|
|
1949
|
+
padding: 10px 16px;
|
|
1950
|
+
background: #161616;
|
|
1951
|
+
border-bottom: 1px solid #1e1e1e;
|
|
1952
|
+
gap: 8px;
|
|
1919
1953
|
font-size: 12px;
|
|
1920
|
-
|
|
1954
|
+
color: #666;
|
|
1921
1955
|
}
|
|
1922
|
-
.
|
|
1923
|
-
|
|
1956
|
+
.source-topbar .filepath { color: #aaa; font-family: ui-monospace, monospace; }
|
|
1957
|
+
.source-code {
|
|
1958
|
+
background: #0d0d0d;
|
|
1959
|
+
overflow-x: auto;
|
|
1960
|
+
padding: 10px 0;
|
|
1961
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1924
1962
|
font-size: 13px;
|
|
1925
|
-
|
|
1926
|
-
word-break: break-all;
|
|
1927
|
-
line-height: 1.6;
|
|
1963
|
+
line-height: 1.7;
|
|
1928
1964
|
}
|
|
1929
|
-
.
|
|
1965
|
+
.src-line {
|
|
1930
1966
|
display: flex;
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1967
|
+
align-items: flex-start;
|
|
1968
|
+
padding: 0 20px;
|
|
1969
|
+
white-space: pre;
|
|
1970
|
+
color: #555;
|
|
1935
1971
|
}
|
|
1936
|
-
.
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
font-weight: 600;
|
|
1944
|
-
cursor: pointer;
|
|
1945
|
-
transition: all 0.2s;
|
|
1972
|
+
.src-line .ln {
|
|
1973
|
+
color: #3a3a3a;
|
|
1974
|
+
text-align: right;
|
|
1975
|
+
width: 36px;
|
|
1976
|
+
margin-right: 16px;
|
|
1977
|
+
flex-shrink: 0;
|
|
1978
|
+
user-select: none;
|
|
1946
1979
|
}
|
|
1947
|
-
.
|
|
1948
|
-
background:
|
|
1949
|
-
color: #
|
|
1950
|
-
|
|
1951
|
-
box-shadow: 0 6px 20px rgba(34, 211, 238, 0.4);
|
|
1980
|
+
.src-err {
|
|
1981
|
+
background: rgba(239, 68, 68, 0.08);
|
|
1982
|
+
color: #fca5a5;
|
|
1983
|
+
position: relative;
|
|
1952
1984
|
}
|
|
1953
|
-
.
|
|
1954
|
-
|
|
1955
|
-
|
|
1985
|
+
.src-err .ln { color: #ef4444; }
|
|
1986
|
+
.src-err::before {
|
|
1987
|
+
content: '';
|
|
1988
|
+
position: absolute;
|
|
1989
|
+
left: 0;
|
|
1990
|
+
top: 0; bottom: 0;
|
|
1991
|
+
width: 3px;
|
|
1992
|
+
background: #ef4444;
|
|
1956
1993
|
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1994
|
+
|
|
1995
|
+
/* \u2500\u2500 Call Stack \u2500\u2500 */
|
|
1996
|
+
.callstack {
|
|
1997
|
+
padding: 20px 24px;
|
|
1961
1998
|
}
|
|
1962
|
-
.
|
|
1963
|
-
margin-top: 48px;
|
|
1964
|
-
padding-top: 28px;
|
|
1965
|
-
border-top: 1px solid rgba(34, 211, 238, 0.2);
|
|
1999
|
+
.callstack-header {
|
|
1966
2000
|
display: flex;
|
|
1967
|
-
justify-content: space-between;
|
|
1968
2001
|
align-items: center;
|
|
1969
|
-
|
|
1970
|
-
|
|
2002
|
+
justify-content: space-between;
|
|
2003
|
+
margin-bottom: 14px;
|
|
2004
|
+
}
|
|
2005
|
+
.callstack-title {
|
|
2006
|
+
font-size: 13px;
|
|
2007
|
+
font-weight: 600;
|
|
2008
|
+
color: #aaa;
|
|
2009
|
+
text-transform: uppercase;
|
|
2010
|
+
letter-spacing: 0.06em;
|
|
1971
2011
|
}
|
|
1972
|
-
.
|
|
2012
|
+
.ignore-btn {
|
|
2013
|
+
font-size: 12px;
|
|
2014
|
+
color: #555;
|
|
2015
|
+
background: none;
|
|
2016
|
+
border: none;
|
|
2017
|
+
cursor: pointer;
|
|
1973
2018
|
display: flex;
|
|
1974
2019
|
align-items: center;
|
|
1975
|
-
gap:
|
|
1976
|
-
|
|
1977
|
-
color: #22D3EE;
|
|
1978
|
-
font-size: 15px;
|
|
1979
|
-
}
|
|
1980
|
-
.brand img {
|
|
1981
|
-
width: 20px;
|
|
1982
|
-
height: 20px;
|
|
2020
|
+
gap: 4px;
|
|
2021
|
+
transition: color .15s;
|
|
1983
2022
|
}
|
|
1984
|
-
.
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2023
|
+
.ignore-btn:hover { color: #aaa; }
|
|
2024
|
+
.ignore-caret { transition: transform .2s; }
|
|
2025
|
+
.ignore-btn.open .ignore-caret { transform: rotate(90deg); }
|
|
2026
|
+
|
|
2027
|
+
.frame {
|
|
2028
|
+
padding: 10px 12px;
|
|
2029
|
+
border-radius: 6px;
|
|
2030
|
+
margin-bottom: 4px;
|
|
2031
|
+
font-size: 13px;
|
|
2032
|
+
cursor: default;
|
|
1988
2033
|
}
|
|
1989
|
-
.
|
|
1990
|
-
|
|
1991
|
-
|
|
2034
|
+
.frame:hover { background: rgba(255,255,255,0.03); }
|
|
2035
|
+
.frame-call {
|
|
2036
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1992
2037
|
font-weight: 600;
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
}
|
|
1996
|
-
.footer-links a:hover {
|
|
1997
|
-
color: #22D3EE;
|
|
1998
|
-
transform: translateY(-1px);
|
|
2038
|
+
color: #e2e8f0;
|
|
2039
|
+
margin-bottom: 3px;
|
|
1999
2040
|
}
|
|
2000
|
-
.
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
padding: 32px;
|
|
2005
|
-
color: #FCA5A5;
|
|
2006
|
-
text-align: center;
|
|
2007
|
-
font-size: 15px;
|
|
2008
|
-
}
|
|
2009
|
-
@keyframes slideIn {
|
|
2010
|
-
from {
|
|
2011
|
-
opacity: 0;
|
|
2012
|
-
transform: translateY(10px);
|
|
2013
|
-
}
|
|
2014
|
-
to {
|
|
2015
|
-
opacity: 1;
|
|
2016
|
-
transform: translateY(0);
|
|
2017
|
-
}
|
|
2041
|
+
.frame-loc {
|
|
2042
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
2043
|
+
font-size: 12px;
|
|
2044
|
+
color: #555;
|
|
2018
2045
|
}
|
|
2046
|
+
.frame.ignored .frame-call { color: #444; }
|
|
2047
|
+
|
|
2048
|
+
.ignored-section { margin-top: 8px; display: none; }
|
|
2049
|
+
.ignored-section.open { display: block; }
|
|
2019
2050
|
</style>
|
|
2020
2051
|
</head>
|
|
2021
2052
|
<body>
|
|
2022
|
-
<div class="
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2053
|
+
<div class="overlay">
|
|
2054
|
+
|
|
2055
|
+
<!-- Header bar -->
|
|
2056
|
+
<div class="header">
|
|
2057
|
+
<div class="header-left">
|
|
2058
|
+
<button class="nav-btn" disabled>\u2039</button>
|
|
2059
|
+
<span class="counter-badge">1 / 1</span>
|
|
2060
|
+
<button class="nav-btn" disabled>\u203A</button>
|
|
2061
|
+
<span style="margin-left: 4px;">Unhandled Runtime Error</span>
|
|
2062
|
+
</div>
|
|
2063
|
+
<div class="framework-tag">Velix v${VERSION} \xB7 esbuild</div>
|
|
2064
|
+
</div>
|
|
2065
|
+
|
|
2066
|
+
<!-- Scrollable content -->
|
|
2067
|
+
<div class="content">
|
|
2068
|
+
|
|
2069
|
+
<!-- Error summary -->
|
|
2070
|
+
<div class="error-summary">
|
|
2071
|
+
<div class="error-label">
|
|
2072
|
+
<svg viewBox="0 0 16 16"><path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm-.75 3.5a.75.75 0 0 1 1.5 0v4a.75.75 0 0 1-1.5 0v-4zm.75 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5z"/></svg>
|
|
2073
|
+
Runtime Error
|
|
2074
|
+
</div>
|
|
2075
|
+
<div class="error-message">${escapeHtml2(message)}</div>
|
|
2076
|
+
${pathname ? `<div class="error-location">in <strong>${escapeHtml2(pathname)}</strong></div>` : ""}
|
|
2028
2077
|
</div>
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
<
|
|
2078
|
+
|
|
2079
|
+
${sourceSnippet ? `
|
|
2080
|
+
<!-- Source code snippet -->
|
|
2081
|
+
<div class="source-block">
|
|
2082
|
+
<div class="source-topbar">
|
|
2083
|
+
<svg width="12" height="12" fill="none" viewBox="0 0 24 24"><path stroke="#666" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8l-6-6z"/><polyline stroke="#666" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" points="14 2 14 8 20 8"/></svg>
|
|
2084
|
+
<span class="filepath">${escapeHtml2(shortFile)}${errorLine ? `:${errorLine}` : ""}</span>
|
|
2085
|
+
</div>
|
|
2086
|
+
<div class="source-code">${sourceSnippet}</div>
|
|
2035
2087
|
</div>
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
${callStackCards}
|
|
2050
|
-
</div>
|
|
2051
|
-
${frameCount > 1 ? `
|
|
2052
|
-
<div class="pagination">
|
|
2053
|
-
<button class="pagination-btn" id="prev-btn" onclick="changePage(-1)">
|
|
2054
|
-
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="display:inline;vertical-align:middle;margin-right:4px;">
|
|
2055
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
2056
|
-
</svg>
|
|
2057
|
-
Previous
|
|
2058
|
-
</button>
|
|
2059
|
-
<div class="pagination-info">
|
|
2060
|
-
<span id="current-page">1</span> / <span id="total-pages">${frameCount}</span>
|
|
2061
|
-
</div>
|
|
2062
|
-
<button class="pagination-btn" id="next-btn" onclick="changePage(1)">
|
|
2063
|
-
Next
|
|
2064
|
-
<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="display:inline;vertical-align:middle;margin-left:4px;">
|
|
2065
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
2066
|
-
</svg>
|
|
2067
|
-
</button>
|
|
2068
|
-
</div>
|
|
2088
|
+
` : ""}
|
|
2089
|
+
|
|
2090
|
+
<!-- Call stack -->
|
|
2091
|
+
<div class="callstack">
|
|
2092
|
+
<div class="callstack-header">
|
|
2093
|
+
<div class="callstack-title">Call Stack</div>
|
|
2094
|
+
${ignoredFrames.length > 0 ? `
|
|
2095
|
+
<button class="ignore-btn" id="ignoreBtn" onclick="toggleIgnored()">
|
|
2096
|
+
<svg class="ignore-caret" width="12" height="12" viewBox="0 0 12 12" fill="none">
|
|
2097
|
+
<path d="M4.5 3L7.5 6L4.5 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
2098
|
+
</svg>
|
|
2099
|
+
${ignoredFrames.length} ignored frames
|
|
2100
|
+
</button>
|
|
2069
2101
|
` : ""}
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2102
|
+
</div>
|
|
2103
|
+
|
|
2104
|
+
<!-- User frames -->
|
|
2105
|
+
${userFrames.map((f) => `
|
|
2106
|
+
<div class="frame">
|
|
2107
|
+
<div class="frame-call">${escapeHtml2(f.call)}</div>
|
|
2108
|
+
<div class="frame-loc">${escapeHtml2(f.file.replace(/\\/g, "/").replace(/.*\/(?=app\/|server\/|src\/|pages\/)/, ""))}${f.line ? `:${f.line}` : ""}</div>
|
|
2109
|
+
</div>
|
|
2110
|
+
`).join("")}
|
|
2111
|
+
|
|
2112
|
+
<!-- Ignored frames -->
|
|
2113
|
+
${ignoredFrames.length > 0 ? `
|
|
2114
|
+
<div class="ignored-section" id="ignoredSection">
|
|
2115
|
+
${ignoredFrames.map((f) => `
|
|
2116
|
+
<div class="frame ignored">
|
|
2117
|
+
<div class="frame-call">${escapeHtml2(f.call)}</div>
|
|
2118
|
+
<div class="frame-loc">${escapeHtml2(f.file)}${f.line ? `:${f.line}` : ""}</div>
|
|
2083
2119
|
</div>
|
|
2120
|
+
`).join("")}
|
|
2121
|
+
</div>
|
|
2122
|
+
` : ""}
|
|
2084
2123
|
</div>
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2124
|
+
|
|
2125
|
+
</div><!-- /content -->
|
|
2126
|
+
</div><!-- /overlay -->
|
|
2127
|
+
|
|
2088
2128
|
<script>
|
|
2089
|
-
|
|
2090
|
-
const
|
|
2091
|
-
const
|
|
2092
|
-
|
|
2093
|
-
const
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
function showPage(page) {
|
|
2097
|
-
cards.forEach((card, index) => {
|
|
2098
|
-
card.classList.remove('active');
|
|
2099
|
-
if (index === page - 1) {
|
|
2100
|
-
card.classList.add('active');
|
|
2101
|
-
}
|
|
2102
|
-
});
|
|
2103
|
-
|
|
2104
|
-
currentPage = page;
|
|
2105
|
-
currentPageSpan.textContent = page;
|
|
2106
|
-
|
|
2107
|
-
if (prevBtn) prevBtn.disabled = page === 1;
|
|
2108
|
-
if (nextBtn) nextBtn.disabled = page === totalPages;
|
|
2109
|
-
}
|
|
2110
|
-
|
|
2111
|
-
function changePage(direction) {
|
|
2112
|
-
const newPage = currentPage + direction;
|
|
2113
|
-
if (newPage >= 1 && newPage <= totalPages) {
|
|
2114
|
-
showPage(newPage);
|
|
2115
|
-
}
|
|
2116
|
-
}
|
|
2117
|
-
|
|
2118
|
-
// Show first page on load
|
|
2119
|
-
showPage(1);
|
|
2120
|
-
|
|
2121
|
-
// Keyboard navigation
|
|
2122
|
-
document.addEventListener('keydown', (e) => {
|
|
2123
|
-
if (e.key === 'ArrowLeft') changePage(-1);
|
|
2124
|
-
if (e.key === 'ArrowRight') changePage(1);
|
|
2125
|
-
});
|
|
2129
|
+
function toggleIgnored() {
|
|
2130
|
+
const btn = document.getElementById('ignoreBtn');
|
|
2131
|
+
const sec = document.getElementById('ignoredSection');
|
|
2132
|
+
if (!btn || !sec) return;
|
|
2133
|
+
const open = sec.classList.toggle('open');
|
|
2134
|
+
btn.classList.toggle('open', open);
|
|
2135
|
+
}
|
|
2126
2136
|
</script>
|
|
2127
|
-
` : ""}
|
|
2128
2137
|
</body>
|
|
2129
2138
|
</html>`;
|
|
2130
2139
|
}
|