switch to codemirror
This commit is contained in:
20
playground/.eslintrc
Normal file
20
playground/.eslintrc
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"commonjs": true,
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 6,
|
||||||
|
"sourceType": "module",
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"jsx": true,
|
||||||
|
"classes": true,
|
||||||
|
"defaultParams": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"curly": ["error", "multi"]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
|
||||||
<title>Newt Playground</title>
|
<title>Newt Playground</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
412
playground/package-lock.json
generated
412
playground/package-lock.json
generated
@@ -9,15 +9,113 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@preact/signals": "^1.3.0",
|
"@preact/signals": "^1.3.0",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
"monaco-editor": "^0.52.0",
|
"monaco-editor": "^0.52.0",
|
||||||
"preact": "^10.24.3"
|
"preact": "^10.24.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
|
"@lezer/generator": "^1.7.3",
|
||||||
|
"@lezer/lr": "^1.4.2",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"typescript": "~5.6.2",
|
"typescript": "~5.6.2",
|
||||||
"vite": "^6.1.0"
|
"vite": "^6.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@codemirror/autocomplete": {
|
||||||
|
"version": "6.18.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
|
||||||
|
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.17.0",
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/commands": {
|
||||||
|
"version": "6.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz",
|
||||||
|
"integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.4.0",
|
||||||
|
"@codemirror/view": "^6.27.0",
|
||||||
|
"@lezer/common": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/language": {
|
||||||
|
"version": "6.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.1.tgz",
|
||||||
|
"integrity": "sha512-5kS1U7emOGV84vxC+ruBty5sUgcD0te6dyupyRVG2zaSjhTDM73LhVKUtVwiqSe6QwmEoA4SCiU8AKPFyumAWQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.23.0",
|
||||||
|
"@lezer/common": "^1.1.0",
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0",
|
||||||
|
"style-mod": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/lint": {
|
||||||
|
"version": "6.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz",
|
||||||
|
"integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.35.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/search": {
|
||||||
|
"version": "6.5.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz",
|
||||||
|
"integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/state": {
|
||||||
|
"version": "6.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||||
|
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@marijn/find-cluster-break": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/theme-one-dark": {
|
||||||
|
"version": "6.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
|
||||||
|
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/highlight": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/view": {
|
||||||
|
"version": "6.37.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.37.2.tgz",
|
||||||
|
"integrity": "sha512-XD3LdgQpxQs5jhOOZ2HRVT+Rj59O4Suc7g2ULvZ+Yi8eCkickrkZ5JFuoDhs2ST1mNI5zSsNYgR3NGa4OUrbnw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.5.0",
|
||||||
|
"crelt": "^1.0.6",
|
||||||
|
"style-mod": "^4.1.0",
|
||||||
|
"w3c-keyname": "^2.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@esbuild/aix-ppc64": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.25.0",
|
"version": "0.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz",
|
||||||
@@ -443,6 +541,50 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@lezer/common": {
|
||||||
|
"version": "1.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
|
||||||
|
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/generator": {
|
||||||
|
"version": "1.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/generator/-/generator-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-vAI2O1tPF8QMMgp+bdUeeJCneJNkOZvqsrtyb4ohnFVFdboSqPwBEacnt0HH4E+5h+qsIwTHUSAhffU4hzKl1A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/common": "^1.1.0",
|
||||||
|
"@lezer/lr": "^1.3.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"lezer-generator": "src/lezer-generator.cjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/highlight": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/lr": {
|
||||||
|
"version": "1.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
||||||
|
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/common": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@marijn/find-cluster-break": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@preact/signals": {
|
"node_modules/@preact/signals": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@preact/signals/-/signals-1.3.2.tgz",
|
||||||
@@ -470,9 +612,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.43.0.tgz",
|
||||||
"integrity": "sha512-l6CtzHYo8D2TQ3J7qJNpp3Q1Iye56ssIAtqbM2H8axxCEEwvN7o8Ze9PuIapbxFL3OHrJU2JBX6FIIVnP/rYyw==",
|
"integrity": "sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -484,9 +626,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm64": {
|
"node_modules/@rollup/rollup-android-arm64": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.43.0.tgz",
|
||||||
"integrity": "sha512-KvyJpFUueUnSp53zhAa293QBYqwm94TgYTIfXyOTtidhm5V0LbLCJQRGkQClYiX3FXDQGSvPxOTD/6rPStMMDg==",
|
"integrity": "sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -498,9 +640,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.43.0.tgz",
|
||||||
"integrity": "sha512-jq87CjmgL9YIKvs8ybtIC98s/M3HdbqXhllcy9EdLV0yMg1DpxES2gr65nNy7ObNo/vZ/MrOTxt0bE5LinL6mA==",
|
"integrity": "sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -512,9 +654,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-darwin-x64": {
|
"node_modules/@rollup/rollup-darwin-x64": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.43.0.tgz",
|
||||||
"integrity": "sha512-rSI/m8OxBjsdnMMg0WEetu/w+LhLAcCDEiL66lmMX4R3oaml3eXz3Dxfvrxs1FbzPbJMaItQiksyMfv1hoIxnA==",
|
"integrity": "sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -526,9 +668,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.43.0.tgz",
|
||||||
"integrity": "sha512-oIoJRy3ZrdsXpFuWDtzsOOa/E/RbRWXVokpVrNnkS7npz8GEG++E1gYbzhYxhxHbO2om1T26BZjVmdIoyN2WtA==",
|
"integrity": "sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -540,9 +682,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.43.0.tgz",
|
||||||
"integrity": "sha512-X++QSLm4NZfZ3VXGVwyHdRf58IBbCu9ammgJxuWZYLX0du6kZvdNqPwrjvDfwmi6wFdvfZ/s6K7ia0E5kI7m8Q==",
|
"integrity": "sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -554,9 +696,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.43.0.tgz",
|
||||||
"integrity": "sha512-Z0TzhrsNqukTz3ISzrvyshQpFnFRfLunYiXxlCRvcrb3nvC5rVKI+ZXPFG/Aa4jhQa1gHgH3A0exHaRRN4VmdQ==",
|
"integrity": "sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -568,9 +710,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.43.0.tgz",
|
||||||
"integrity": "sha512-nkznpyXekFAbvFBKBy4nNppSgneB1wwG1yx/hujN3wRnhnkrYVugMTCBXED4+Ni6thoWfQuHNYbFjgGH0MBXtw==",
|
"integrity": "sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -582,9 +724,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-KCjlUkcKs6PjOcxolqrXglBDcfCuUCTVlX5BgzgoJHw+1rWH1MCkETLkLe5iLLS9dP5gKC7mp3y6x8c1oGBUtA==",
|
"integrity": "sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -596,9 +738,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.43.0.tgz",
|
||||||
"integrity": "sha512-uFLJFz6+utmpbR313TTx+NpPuAXbPz4BhTQzgaP0tozlLnGnQ6rCo6tLwaSa6b7l6gRErjLicXQ1iPiXzYotjw==",
|
"integrity": "sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -610,9 +752,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-ws8pc68UcJJqCpneDFepnwlsMUFoWvPbWXT/XUrJ7rWUL9vLoIN3GAasgG+nCvq8xrE3pIrd+qLX/jotcLy0Qw==",
|
"integrity": "sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"loong64"
|
"loong64"
|
||||||
],
|
],
|
||||||
@@ -624,9 +766,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-vrDk9JDa/BFkxcS2PbWpr0C/LiiSLxFbNOBgfbW6P8TBe9PPHx9Wqbvx2xgNi1TOAyQHQJ7RZFqBiEohm79r0w==",
|
"integrity": "sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -638,9 +780,23 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-rB+ejFyjtmSo+g/a4eovDD1lHWHVqizN8P0Hm0RElkINpS0XOdpaXloqM4FBkF9ZWEzg6bezymbpLmeMldfLTw==",
|
"integrity": "sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||||
|
"version": "4.43.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.43.0.tgz",
|
||||||
|
"integrity": "sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -652,9 +808,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-nNXNjo4As6dNqRn7OrsnHzwTgtypfRA3u3AKr0B3sOOo+HkedIbn8ZtFnB+4XyKJojIfqDKmbIzO1QydQ8c+Pw==",
|
"integrity": "sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -666,9 +822,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.43.0.tgz",
|
||||||
"integrity": "sha512-9kPVf9ahnpOMSGlCxXGv980wXD0zRR3wyk8+33/MXQIpQEOpaNe7dEHm5LMfyRZRNt9lMEQuH0jUKj15MkM7QA==",
|
"integrity": "sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -680,9 +836,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.43.0.tgz",
|
||||||
"integrity": "sha512-7wJPXRWTTPtTFDFezA8sle/1sdgxDjuMoRXEKtx97ViRxGGkVQYovem+Q8Pr/2HxiHp74SSRG+o6R0Yq0shPwQ==",
|
"integrity": "sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -694,9 +850,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.43.0.tgz",
|
||||||
"integrity": "sha512-MN7aaBC7mAjsiMEZcsJvwNsQVNZShgES/9SzWp1HC9Yjqb5OpexYnRjF7RmE4itbeesHMYYQiAtUAQaSKs2Rfw==",
|
"integrity": "sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -708,9 +864,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.43.0.tgz",
|
||||||
"integrity": "sha512-aeawEKYswsFu1LhDM9RIgToobquzdtSc4jSVqHV8uApz4FVvhFl/mKh92wc8WpFc6aYCothV/03UjY6y7yLgbg==",
|
"integrity": "sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -722,9 +878,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.43.0.tgz",
|
||||||
"integrity": "sha512-4ZedScpxxIrVO7otcZ8kCX1mZArtH2Wfj3uFCxRJ9NO80gg1XV0U/b2f/MKaGwj2X3QopHfoWiDQ917FRpwY3w==",
|
"integrity": "sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -736,12 +892,33 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
||||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/codemirror": {
|
||||||
|
"version": "6.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/lint": "^6.0.0",
|
||||||
|
"@codemirror/search": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/crelt": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.25.0",
|
"version": "0.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
|
||||||
@@ -783,6 +960,21 @@
|
|||||||
"@esbuild/win32-x64": "0.25.0"
|
"@esbuild/win32-x64": "0.25.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fdir": {
|
||||||
|
"version": "6.4.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz",
|
||||||
|
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"picomatch": "^3 || ^4"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"picomatch": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
@@ -830,6 +1022,19 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.3",
|
"version": "8.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||||
@@ -870,13 +1075,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rollup": {
|
"node_modules/rollup": {
|
||||||
"version": "4.34.7",
|
"version": "4.43.0",
|
||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.7.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.43.0.tgz",
|
||||||
"integrity": "sha512-8qhyN0oZ4x0H6wmBgfKxJtxM7qS98YJ0k0kNh5ECVtuchIJ7z9IVVvzpmtQyT10PXKMtBxYr1wQ5Apg8RS8kXQ==",
|
"integrity": "sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.6"
|
"@types/estree": "1.0.7"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
@@ -886,25 +1091,26 @@
|
|||||||
"npm": ">=8.0.0"
|
"npm": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rollup/rollup-android-arm-eabi": "4.34.7",
|
"@rollup/rollup-android-arm-eabi": "4.43.0",
|
||||||
"@rollup/rollup-android-arm64": "4.34.7",
|
"@rollup/rollup-android-arm64": "4.43.0",
|
||||||
"@rollup/rollup-darwin-arm64": "4.34.7",
|
"@rollup/rollup-darwin-arm64": "4.43.0",
|
||||||
"@rollup/rollup-darwin-x64": "4.34.7",
|
"@rollup/rollup-darwin-x64": "4.43.0",
|
||||||
"@rollup/rollup-freebsd-arm64": "4.34.7",
|
"@rollup/rollup-freebsd-arm64": "4.43.0",
|
||||||
"@rollup/rollup-freebsd-x64": "4.34.7",
|
"@rollup/rollup-freebsd-x64": "4.43.0",
|
||||||
"@rollup/rollup-linux-arm-gnueabihf": "4.34.7",
|
"@rollup/rollup-linux-arm-gnueabihf": "4.43.0",
|
||||||
"@rollup/rollup-linux-arm-musleabihf": "4.34.7",
|
"@rollup/rollup-linux-arm-musleabihf": "4.43.0",
|
||||||
"@rollup/rollup-linux-arm64-gnu": "4.34.7",
|
"@rollup/rollup-linux-arm64-gnu": "4.43.0",
|
||||||
"@rollup/rollup-linux-arm64-musl": "4.34.7",
|
"@rollup/rollup-linux-arm64-musl": "4.43.0",
|
||||||
"@rollup/rollup-linux-loongarch64-gnu": "4.34.7",
|
"@rollup/rollup-linux-loongarch64-gnu": "4.43.0",
|
||||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.7",
|
"@rollup/rollup-linux-powerpc64le-gnu": "4.43.0",
|
||||||
"@rollup/rollup-linux-riscv64-gnu": "4.34.7",
|
"@rollup/rollup-linux-riscv64-gnu": "4.43.0",
|
||||||
"@rollup/rollup-linux-s390x-gnu": "4.34.7",
|
"@rollup/rollup-linux-riscv64-musl": "4.43.0",
|
||||||
"@rollup/rollup-linux-x64-gnu": "4.34.7",
|
"@rollup/rollup-linux-s390x-gnu": "4.43.0",
|
||||||
"@rollup/rollup-linux-x64-musl": "4.34.7",
|
"@rollup/rollup-linux-x64-gnu": "4.43.0",
|
||||||
"@rollup/rollup-win32-arm64-msvc": "4.34.7",
|
"@rollup/rollup-linux-x64-musl": "4.43.0",
|
||||||
"@rollup/rollup-win32-ia32-msvc": "4.34.7",
|
"@rollup/rollup-win32-arm64-msvc": "4.43.0",
|
||||||
"@rollup/rollup-win32-x64-msvc": "4.34.7",
|
"@rollup/rollup-win32-ia32-msvc": "4.43.0",
|
||||||
|
"@rollup/rollup-win32-x64-msvc": "4.43.0",
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -918,6 +1124,29 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/style-mod": {
|
||||||
|
"version": "4.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
||||||
|
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/tinyglobby": {
|
||||||
|
"version": "0.2.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
|
||||||
|
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"fdir": "^6.4.4",
|
||||||
|
"picomatch": "^4.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.6.3",
|
"version": "5.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
|
||||||
@@ -933,15 +1162,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "6.2.5",
|
"version": "6.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
|
||||||
"integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==",
|
"integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
|
"fdir": "^6.4.4",
|
||||||
|
"picomatch": "^4.0.2",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"rollup": "^4.30.1"
|
"rollup": "^4.34.9",
|
||||||
|
"tinyglobby": "^0.2.13"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"vite": "bin/vite.js"
|
"vite": "bin/vite.js"
|
||||||
@@ -1003,6 +1235,12 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/w3c-keyname": {
|
||||||
|
"version": "2.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||||
|
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||||
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,16 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@codemirror/theme-one-dark": "^6.1.2",
|
||||||
|
"@lezer/generator": "^1.7.3",
|
||||||
|
"@lezer/lr": "^1.4.2",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"typescript": "~5.6.2",
|
"typescript": "~5.6.2",
|
||||||
"vite": "^6.1.0"
|
"vite": "^6.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@preact/signals": "^1.3.0",
|
"@preact/signals": "^1.3.0",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
"monaco-editor": "^0.52.0",
|
"monaco-editor": "^0.52.0",
|
||||||
"preact": "^10.24.3"
|
"preact": "^10.24.3"
|
||||||
}
|
}
|
||||||
|
|||||||
196
playground/src/cmeditor.ts
Normal file
196
playground/src/cmeditor.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
import { AbstractEditor, EditorDelegate, Marker } from "./types";
|
||||||
|
import { basicSetup } from "codemirror";
|
||||||
|
import { EditorView, hoverTooltip, Tooltip } from "@codemirror/view";
|
||||||
|
import { Compartment } from "@codemirror/state";
|
||||||
|
import { parser } from "./parser.js";
|
||||||
|
import { oneDark, oneDark as themeOneDark } from "@codemirror/theme-one-dark";
|
||||||
|
import { styleTags, tags as t } from "@lezer/highlight";
|
||||||
|
import { linter, Diagnostic } from "@codemirror/lint";
|
||||||
|
import {
|
||||||
|
LanguageSupport,
|
||||||
|
LRLanguage,
|
||||||
|
StreamLanguage,
|
||||||
|
StringStream,
|
||||||
|
} from "@codemirror/language";
|
||||||
|
|
||||||
|
let parserWithMetadata = parser.configure({
|
||||||
|
props: [
|
||||||
|
styleTags({
|
||||||
|
Identifier: t.variableName,
|
||||||
|
LineComment: t.lineComment,
|
||||||
|
"if then else data where": t.keyword,
|
||||||
|
}),
|
||||||
|
// indentNodeProp, foldNodeProp
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const newtLanguage = LRLanguage.define({
|
||||||
|
parser: parserWithMetadata,
|
||||||
|
languageData: {
|
||||||
|
commentTokens: {
|
||||||
|
line: "--",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// prettier did this...
|
||||||
|
const keywords = [
|
||||||
|
"let",
|
||||||
|
"in",
|
||||||
|
"where",
|
||||||
|
"case",
|
||||||
|
"of",
|
||||||
|
"data",
|
||||||
|
"U",
|
||||||
|
"do",
|
||||||
|
"ptype",
|
||||||
|
"pfunc",
|
||||||
|
"module",
|
||||||
|
"infixl",
|
||||||
|
"infixr",
|
||||||
|
"infix",
|
||||||
|
"∀",
|
||||||
|
"forall",
|
||||||
|
"import",
|
||||||
|
"uses",
|
||||||
|
"class",
|
||||||
|
"instance",
|
||||||
|
"record",
|
||||||
|
"constructor",
|
||||||
|
"if",
|
||||||
|
"then",
|
||||||
|
"else",
|
||||||
|
"$",
|
||||||
|
"λ",
|
||||||
|
"?",
|
||||||
|
"@",
|
||||||
|
".",
|
||||||
|
"->",
|
||||||
|
"→",
|
||||||
|
":",
|
||||||
|
"=>",
|
||||||
|
":=",
|
||||||
|
"$=",
|
||||||
|
"=",
|
||||||
|
"<-",
|
||||||
|
"\\",
|
||||||
|
"_",
|
||||||
|
"|",
|
||||||
|
];
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
tokenizer(stream: StringStream, state: State): string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tokenizer(stream: StringStream, state: State): string | null {
|
||||||
|
stream.eatSpace();
|
||||||
|
if (stream.match("--")) {
|
||||||
|
stream.skipToEnd();
|
||||||
|
return "comment";
|
||||||
|
}
|
||||||
|
if (stream.match(/^[/]-/)) {
|
||||||
|
state.tokenizer = commentTokenizer;
|
||||||
|
return state.tokenizer(stream, state);
|
||||||
|
}
|
||||||
|
if (stream.match(/^[\w_][\w\d_']*/)) {
|
||||||
|
let word = stream.current();
|
||||||
|
if (keywords.includes(word)) return "keyword";
|
||||||
|
if (word[0] >= "A" && word[0] <= "Z") return "typename";
|
||||||
|
return "identifier";
|
||||||
|
}
|
||||||
|
// unhandled
|
||||||
|
stream.next();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function commentTokenizer(stream: StringStream, state: State): string | null {
|
||||||
|
console.log("ctok");
|
||||||
|
let dash = false;
|
||||||
|
let ch;
|
||||||
|
while ((ch = stream.next())) {
|
||||||
|
if (dash && ch === "/") {
|
||||||
|
state.tokenizer = tokenizer;
|
||||||
|
return "comment";
|
||||||
|
}
|
||||||
|
dash = ch === "-";
|
||||||
|
}
|
||||||
|
console.log("XX", stream.current());
|
||||||
|
return "comment";
|
||||||
|
}
|
||||||
|
|
||||||
|
const newtLanguage2 = StreamLanguage.define({
|
||||||
|
startState: () => ({ tokenizer }),
|
||||||
|
token(stream, st) {
|
||||||
|
return st.tokenizer(stream, st);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function newt() {
|
||||||
|
return new LanguageSupport(newtLanguage2);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CMEditor implements AbstractEditor {
|
||||||
|
view: EditorView;
|
||||||
|
delegate: EditorDelegate;
|
||||||
|
theme: Compartment;
|
||||||
|
constructor(container: HTMLElement, doc: string, delegate: EditorDelegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.theme = new Compartment();
|
||||||
|
|
||||||
|
this.view = new EditorView({
|
||||||
|
doc,
|
||||||
|
parent: container,
|
||||||
|
extensions: [
|
||||||
|
basicSetup,
|
||||||
|
linter((view) => this.delegate.lint(view)),
|
||||||
|
this.theme.of(EditorView.baseTheme({})),
|
||||||
|
hoverTooltip((view, pos) => {
|
||||||
|
let cursor = this.view.state.doc.lineAt(pos);
|
||||||
|
let line = cursor.number;
|
||||||
|
let range = this.view.state.wordAt(pos);
|
||||||
|
console.log(range);
|
||||||
|
if (range) {
|
||||||
|
let col = range.from - cursor.from;
|
||||||
|
let word = this.view.state.doc.sliceString(range.from, range.to);
|
||||||
|
let entry = this.delegate.getEntry(word, line, col);
|
||||||
|
console.log("entry", entry);
|
||||||
|
if (entry) {
|
||||||
|
let rval: Tooltip = {
|
||||||
|
pos: range.head,
|
||||||
|
above: true,
|
||||||
|
create: () => {
|
||||||
|
let dom = document.createElement("div");
|
||||||
|
dom.className = "tooltip";
|
||||||
|
dom.textContent = entry.type;
|
||||||
|
return { dom };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// we'll iterate the syntax tree for word.
|
||||||
|
// let entry = delegate.getEntry(word, line, col)
|
||||||
|
return null;
|
||||||
|
}),
|
||||||
|
newt(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setDark(isDark: boolean) {
|
||||||
|
this.view.dispatch({
|
||||||
|
effects: this.theme.reconfigure(
|
||||||
|
isDark ? oneDark : EditorView.baseTheme({})
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setValue(_doc: string) {
|
||||||
|
// Is this all we can do?
|
||||||
|
this.view.dispatch({
|
||||||
|
changes: { from: 0, to: this.view.state.doc.length, insert: _doc },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getValue() {
|
||||||
|
// maybe?
|
||||||
|
return this.view.state.doc.toString();
|
||||||
|
}
|
||||||
|
setMarkers(_: Marker[]) {}
|
||||||
|
}
|
||||||
@@ -1,91 +1,25 @@
|
|||||||
import { effect, signal } from "@preact/signals";
|
import { effect, signal } from "@preact/signals";
|
||||||
import { newtConfig, newtTokens } from "./monarch.ts";
|
import { Diagnostic } from "@codemirror/lint";
|
||||||
import * as monaco from "monaco-editor";
|
|
||||||
import { useEffect, useRef, useState } from "preact/hooks";
|
import { useEffect, useRef, useState } from "preact/hooks";
|
||||||
import { h, render } from "preact";
|
import { h, render } from "preact";
|
||||||
import { ChangeEvent } from "preact/compat";
|
import { ChangeEvent } from "preact/compat";
|
||||||
import { archive, preload } from "./preload.ts";
|
import { archive, preload } from "./preload.ts";
|
||||||
import { CompileReq, CompileRes, Message } from "./types.ts";
|
import {
|
||||||
import { ABBREV } from "./abbrev.ts";
|
AbstractEditor,
|
||||||
|
EditorDelegate,
|
||||||
// editor.(createModel / setModel / getModels) to switch files
|
CompileReq,
|
||||||
|
CompileRes,
|
||||||
// TODO - remember files and allow switching?
|
Message,
|
||||||
|
TopData,
|
||||||
// static zip filesystem with user changes overlaid via localStorage
|
Marker,
|
||||||
// download individual files (we could use the cheap compression from the pdflib or no compression to make zip download)
|
} from "./types.ts";
|
||||||
// would need way to reset/delete
|
import { CMEditor } from "./cmeditor.ts";
|
||||||
|
|
||||||
interface FC {
|
|
||||||
file: string;
|
|
||||||
line: number;
|
|
||||||
col: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TopEntry {
|
|
||||||
fc: FC;
|
|
||||||
name: String;
|
|
||||||
type: String;
|
|
||||||
}
|
|
||||||
interface TopData {
|
|
||||||
context: TopEntry[];
|
|
||||||
}
|
|
||||||
|
|
||||||
let topData: undefined | TopData;
|
let topData: undefined | TopData;
|
||||||
|
|
||||||
// we need to fix the definition of word
|
|
||||||
monaco.languages.register({ id: "newt" });
|
|
||||||
monaco.languages.setMonarchTokensProvider("newt", newtTokens);
|
|
||||||
monaco.languages.setLanguageConfiguration("newt", newtConfig);
|
|
||||||
monaco.languages.registerDefinitionProvider("newt", {
|
|
||||||
provideDefinition(model, position, token) {
|
|
||||||
if (!topData) return;
|
|
||||||
// HACK - we don't know our filename which was generated from `module` decl, so
|
|
||||||
// assume the last context entry is in our file.
|
|
||||||
let last = topData.context[topData.context.length - 1];
|
|
||||||
let file = last.fc.file;
|
|
||||||
|
|
||||||
const info = model.getWordAtPosition(position);
|
|
||||||
if (!info) return;
|
|
||||||
let entry = topData.context.find((entry) => entry.name === info.word);
|
|
||||||
// we can't switch files at the moment
|
|
||||||
if (!entry || entry.fc.file !== file) return;
|
|
||||||
let lineNumber = entry.fc.line + 1;
|
|
||||||
let column = entry.fc.col + 1;
|
|
||||||
let word = model.getWordAtPosition({ lineNumber, column });
|
|
||||||
let range = new monaco.Range(lineNumber, column, lineNumber, column);
|
|
||||||
if (word) {
|
|
||||||
range = new monaco.Range(
|
|
||||||
lineNumber,
|
|
||||||
word.startColumn,
|
|
||||||
lineNumber,
|
|
||||||
word.endColumn
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return { uri: model.uri, range };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
monaco.languages.registerHoverProvider("newt", {
|
|
||||||
provideHover(model, position, token, context) {
|
|
||||||
if (!topData) return;
|
|
||||||
const info = model.getWordAtPosition(position);
|
|
||||||
if (!info) return;
|
|
||||||
let entry = topData.context.find((entry) => entry.name === info.word);
|
|
||||||
if (!entry) return;
|
|
||||||
return {
|
|
||||||
range: new monaco.Range(
|
|
||||||
position.lineNumber,
|
|
||||||
info.startColumn,
|
|
||||||
position.lineNumber,
|
|
||||||
info.endColumn
|
|
||||||
),
|
|
||||||
contents: [{ value: `${entry.name} : ${entry.type}` }],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const newtWorker = new Worker("worker.js");
|
const newtWorker = new Worker("worker.js");
|
||||||
|
// :FIXME use because Safari
|
||||||
let postMessage = (msg: CompileReq) => newtWorker.postMessage(msg);
|
let postMessage = (msg: CompileReq) => newtWorker.postMessage(msg);
|
||||||
|
|
||||||
// Safari/MobileSafari have small stacks in webworkers.
|
// Safari/MobileSafari have small stacks in webworkers.
|
||||||
if (navigator.vendor.includes("Apple")) {
|
if (navigator.vendor.includes("Apple")) {
|
||||||
const workerFrame = document.createElement("iframe");
|
const workerFrame = document.createElement("iframe");
|
||||||
@@ -104,7 +38,7 @@ document.body.appendChild(iframe);
|
|||||||
function run(src: string) {
|
function run(src: string) {
|
||||||
console.log("SEND TO", iframe.contentWindow);
|
console.log("SEND TO", iframe.contentWindow);
|
||||||
const fileName = state.currentFile.value;
|
const fileName = state.currentFile.value;
|
||||||
postMessage({ type: "compileRequest", fileName, src });
|
// postMessage({ type: "compileRequest", fileName, src });
|
||||||
}
|
}
|
||||||
|
|
||||||
function runOutput() {
|
function runOutput() {
|
||||||
@@ -134,6 +68,9 @@ function setOutput(output: string) {
|
|||||||
state.output.value = output;
|
state.output.value = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastID = 0;
|
||||||
|
const nextID = () => "" + lastID++;
|
||||||
|
|
||||||
window.onmessage = (ev: MessageEvent<Message>) => {
|
window.onmessage = (ev: MessageEvent<Message>) => {
|
||||||
console.log("window got", ev.data);
|
console.log("window got", ev.data);
|
||||||
if ("messages" in ev.data) state.messages.value = ev.data.messages;
|
if ("messages" in ev.data) state.messages.value = ev.data.messages;
|
||||||
@@ -142,28 +79,47 @@ window.onmessage = (ev: MessageEvent<Message>) => {
|
|||||||
}
|
}
|
||||||
// safari callback
|
// safari callback
|
||||||
if ("output" in ev.data) {
|
if ("output" in ev.data) {
|
||||||
|
newtWorker.onmessage?.(ev)
|
||||||
setOutput(ev.data.output);
|
setOutput(ev.data.output);
|
||||||
state.javascript.value = ev.data.javascript;
|
state.javascript.value = ev.data.javascript;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO wrap up IPC
|
||||||
|
|
||||||
|
type Suspense<T> = {
|
||||||
|
resolve: (value: T | PromiseLike<T>) => void;
|
||||||
|
reject: (reason?: any) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const callbacks: Record<string, Suspense<string>> = {};
|
||||||
|
|
||||||
newtWorker.onmessage = (ev: MessageEvent<CompileRes>) => {
|
newtWorker.onmessage = (ev: MessageEvent<CompileRes>) => {
|
||||||
|
let suspense = callbacks[ev.data.id];
|
||||||
|
if (suspense) {
|
||||||
|
suspense.resolve(ev.data.output);
|
||||||
|
delete callbacks[ev.data.id];
|
||||||
|
}
|
||||||
|
console.log('result', ev.data, 'suspense', suspense)
|
||||||
|
// FIXME - we want to have the callback take a response for its command
|
||||||
setOutput(ev.data.output);
|
setOutput(ev.data.output);
|
||||||
state.javascript.value = ev.data.javascript;
|
state.javascript.value = ev.data.javascript;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.MonacoEnvironment = {
|
function runCommand(req: CompileReq) {
|
||||||
getWorkerUrl(moduleId, _label) {
|
return new Promise<string>(
|
||||||
console.log("Get worker", moduleId);
|
(resolve, reject) => {
|
||||||
return moduleId;
|
callbacks[req.id] = { resolve, reject }
|
||||||
},
|
postMessage(req);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
output: signal(""),
|
output: signal(""),
|
||||||
javascript: signal(""),
|
javascript: signal(""),
|
||||||
messages: signal<string[]>([]),
|
messages: signal<string[]>([]),
|
||||||
editor: signal<monaco.editor.IStandaloneCodeEditor | null>(null),
|
editor: signal<AbstractEditor | null>(null),
|
||||||
dark: signal(false),
|
dark: signal(false),
|
||||||
files: signal<string[]>(["Tour.newt"]),
|
files: signal<string[]>(["Tour.newt"]),
|
||||||
currentFile: signal<string>(localStorage.currentFile ?? "Tour.newt"),
|
currentFile: signal<string>(localStorage.currentFile ?? "Tour.newt"),
|
||||||
@@ -174,13 +130,15 @@ if (window.matchMedia) {
|
|||||||
function checkDark(ev: { matches: boolean }) {
|
function checkDark(ev: { matches: boolean }) {
|
||||||
console.log("CHANGE", ev);
|
console.log("CHANGE", ev);
|
||||||
if (ev.matches) {
|
if (ev.matches) {
|
||||||
monaco.editor.setTheme("vs-dark");
|
// monaco.editor.setTheme("vs-dark");
|
||||||
document.body.className = "dark";
|
document.body.className = "dark";
|
||||||
state.dark.value = true;
|
state.dark.value = true;
|
||||||
|
state.editor.value?.setDark(true);
|
||||||
} else {
|
} else {
|
||||||
monaco.editor.setTheme("vs");
|
// monaco.editor.setTheme("vs");
|
||||||
document.body.className = "light";
|
document.body.className = "light";
|
||||||
state.dark.value = false;
|
state.dark.value = false;
|
||||||
|
state.editor.value?.setDark(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let query = window.matchMedia("(prefers-color-scheme: dark)");
|
let query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
@@ -215,69 +173,76 @@ let initialVertical = localStorage.vertical == "true";
|
|||||||
effect(() => {
|
effect(() => {
|
||||||
let text = state.output.value;
|
let text = state.output.value;
|
||||||
let editor = state.editor.value;
|
let editor = state.editor.value;
|
||||||
if (editor) processOutput(editor, text);
|
// TODO - abstract this for both editors
|
||||||
|
// if (editor) processOutput(editor, text);
|
||||||
});
|
});
|
||||||
|
|
||||||
interface EditorProps {
|
interface EditorProps {
|
||||||
initialValue: string;
|
initialValue: string;
|
||||||
}
|
}
|
||||||
|
const language: EditorDelegate = {
|
||||||
|
getEntry(word, _row, _col) {
|
||||||
|
return topData?.context.find((entry) => entry.name === word);
|
||||||
|
},
|
||||||
|
onChange(value) {
|
||||||
|
// clearTimeout(timeout);
|
||||||
|
// timeout = setTimeout(() => {
|
||||||
|
// run(value);
|
||||||
|
// localStorage.code = value;
|
||||||
|
// }, 1000);
|
||||||
|
},
|
||||||
|
getFileName() {
|
||||||
|
if (!topData) return "";
|
||||||
|
let last = topData.context[topData.context.length - 1];
|
||||||
|
return last.fc.file;
|
||||||
|
},
|
||||||
|
async lint(view) {
|
||||||
|
console.log("LINT");
|
||||||
|
let src = view.state.doc.toString();
|
||||||
|
const fileName = state.currentFile.value;
|
||||||
|
console.log("FN", fileName);
|
||||||
|
// console.log("SRC", src);
|
||||||
|
try {
|
||||||
|
let out = await runCommand({
|
||||||
|
id: nextID(),
|
||||||
|
type: "compileRequest",
|
||||||
|
fileName,
|
||||||
|
src,
|
||||||
|
});
|
||||||
|
console.log("OUT", out);
|
||||||
|
let markers = processOutput(out);
|
||||||
|
let diags: Diagnostic[] = []
|
||||||
|
for (let marker of markers) {
|
||||||
|
let col = marker.startColumn
|
||||||
|
|
||||||
|
let line = view.state.doc.line(marker.startLineNumber)
|
||||||
|
const pos = line.from + col - 1;
|
||||||
|
let word = view.state.wordAt(pos)
|
||||||
|
diags.push({
|
||||||
|
from: word?.from ?? pos,
|
||||||
|
to: word?.to ?? pos+1,
|
||||||
|
severity: marker.severity,
|
||||||
|
message: marker.message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return diags
|
||||||
|
} catch (e) {
|
||||||
|
console.log("ERR", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
function Editor({ initialValue }: EditorProps) {
|
function Editor({ initialValue }: EditorProps) {
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = ref.current!;
|
const container = ref.current!;
|
||||||
const editor = monaco.editor.create(container, {
|
const editor = new CMEditor(container, value, language);
|
||||||
value,
|
// const editor = new MonacoEditor(container, value, language)
|
||||||
language: "newt",
|
|
||||||
fontFamily: "Comic Code, Menlo, Monaco, Courier New, sans",
|
|
||||||
automaticLayout: true,
|
|
||||||
acceptSuggestionOnEnter: "off",
|
|
||||||
unicodeHighlight: { ambiguousCharacters: false },
|
|
||||||
minimap: { enabled: false },
|
|
||||||
});
|
|
||||||
state.editor.value = editor;
|
state.editor.value = editor;
|
||||||
|
editor.setDark(state.dark.value);
|
||||||
editor.onDidChangeModelContent((ev) => {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
let value = editor.getValue();
|
|
||||||
run(value);
|
|
||||||
localStorage.code = value;
|
|
||||||
}, 1000);
|
|
||||||
let last = ev.changes[ev.changes.length - 1];
|
|
||||||
const model = editor.getModel();
|
|
||||||
// figure out heuristics here, what chars do we want to trigger?
|
|
||||||
// the lean one will only be active if it sees you type \
|
|
||||||
// and bail if it decides you've gone elsewhere
|
|
||||||
// it maintains an underline annotation, too.
|
|
||||||
if (model && last.text && " ')\\".includes(last.text)) {
|
|
||||||
console.log('LAST', last)
|
|
||||||
let { startLineNumber, startColumn } = last.range;
|
|
||||||
const text = model.getValueInRange(
|
|
||||||
new monaco.Range(
|
|
||||||
startLineNumber,
|
|
||||||
Math.max(1, startColumn - 10),
|
|
||||||
startLineNumber,
|
|
||||||
startColumn
|
|
||||||
)
|
|
||||||
);
|
|
||||||
const m = text.match(/(\\[^ ]+)$/);
|
|
||||||
if (m) {
|
|
||||||
let cand = m[0];
|
|
||||||
console.log("GOT", cand);
|
|
||||||
let text = ABBREV[cand];
|
|
||||||
if (text) {
|
|
||||||
const range = new monaco.Range(
|
|
||||||
startLineNumber,
|
|
||||||
startColumn - cand.length,
|
|
||||||
startLineNumber,
|
|
||||||
startColumn
|
|
||||||
);
|
|
||||||
editor.executeEdits("replaceSequence", [{ range, text: text }]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (initialValue === LOADING) loadFile("Tour.newt");
|
if (initialValue === LOADING) loadFile("Tour.newt");
|
||||||
else run(initialValue);
|
else run(initialValue);
|
||||||
}, []);
|
}, []);
|
||||||
@@ -431,11 +396,12 @@ let timeout: number | undefined;
|
|||||||
// Adapted from the vscode extension, but types are slightly different
|
// Adapted from the vscode extension, but types are slightly different
|
||||||
// and positions are 1-based.
|
// and positions are 1-based.
|
||||||
const processOutput = (
|
const processOutput = (
|
||||||
editor: monaco.editor.IStandaloneCodeEditor,
|
// editor: AbstractEditor,
|
||||||
output: string
|
output: string
|
||||||
) => {
|
) => {
|
||||||
let model = editor.getModel()!;
|
// let model = editor.getModel()!;
|
||||||
let markers: monaco.editor.IMarkerData[] = [];
|
console.log('process output', output)
|
||||||
|
let markers: Marker[] = [];
|
||||||
let lines = output.split("\n");
|
let lines = output.split("\n");
|
||||||
let m = lines[0].match(/.*Process (.*)/);
|
let m = lines[0].match(/.*Process (.*)/);
|
||||||
let fn = "";
|
let fn = "";
|
||||||
@@ -451,11 +417,8 @@ const processOutput = (
|
|||||||
if (fn && fn !== file) {
|
if (fn && fn !== file) {
|
||||||
lineNumber = column = 0;
|
lineNumber = column = 0;
|
||||||
}
|
}
|
||||||
let start = { column, lineNumber };
|
|
||||||
// we don't have the full range, so grab the surrounding word
|
// we don't have the full range, so grab the surrounding word
|
||||||
let endColumn = column + 1;
|
let endColumn = column + 1;
|
||||||
let word = model.getWordAtPosition(start);
|
|
||||||
if (word) endColumn = word.endColumn;
|
|
||||||
|
|
||||||
// heuristics to grab the entire message:
|
// heuristics to grab the entire message:
|
||||||
// anything indented
|
// anything indented
|
||||||
@@ -464,13 +427,9 @@ const processOutput = (
|
|||||||
while (lines[i + 1]?.match(/^( )/)) {
|
while (lines[i + 1]?.match(/^( )/)) {
|
||||||
message += "\n" + lines[++i];
|
message += "\n" + lines[++i];
|
||||||
}
|
}
|
||||||
const severity =
|
|
||||||
kind === "ERROR"
|
|
||||||
? monaco.MarkerSeverity.Error
|
|
||||||
: monaco.MarkerSeverity.Info;
|
|
||||||
if (kind === "ERROR" || lineNumber)
|
if (kind === "ERROR" || lineNumber)
|
||||||
markers.push({
|
markers.push({
|
||||||
severity,
|
severity: kind === 'ERROR' ? 'error' : 'info',
|
||||||
message,
|
message,
|
||||||
startLineNumber: lineNumber,
|
startLineNumber: lineNumber,
|
||||||
endLineNumber: lineNumber,
|
endLineNumber: lineNumber,
|
||||||
@@ -479,5 +438,7 @@ const processOutput = (
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
monaco.editor.setModelMarkers(model, "newt", markers);
|
console.log('markers', markers)
|
||||||
|
// editor.setMarkers(markers)
|
||||||
|
return markers;
|
||||||
};
|
};
|
||||||
|
|||||||
210
playground/src/monaco.ts
Normal file
210
playground/src/monaco.ts
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
import { ABBREV } from "./abbrev.ts";
|
||||||
|
import { newtConfig, newtTokens } from "./monarch.ts";
|
||||||
|
import * as monaco from "monaco-editor";
|
||||||
|
import { AbstractEditor, EditorDelegate, Marker } from "./types.ts";
|
||||||
|
|
||||||
|
// we need to fix the definition of word
|
||||||
|
monaco.languages.register({ id: "newt" });
|
||||||
|
monaco.languages.setMonarchTokensProvider("newt", newtTokens);
|
||||||
|
monaco.languages.setLanguageConfiguration("newt", newtConfig);
|
||||||
|
|
||||||
|
self.MonacoEnvironment = {
|
||||||
|
getWorkerUrl(moduleId, _label) {
|
||||||
|
console.log("Get worker", moduleId);
|
||||||
|
return moduleId;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export class MonacoEditor implements AbstractEditor {
|
||||||
|
editor: monaco.editor.IStandaloneCodeEditor;
|
||||||
|
delegate: EditorDelegate;
|
||||||
|
|
||||||
|
constructor(container: HTMLElement, value: string, language: EditorDelegate) {
|
||||||
|
this.delegate = language;
|
||||||
|
let editor = (this.editor = monaco.editor.create(container, {
|
||||||
|
value,
|
||||||
|
language: "newt",
|
||||||
|
fontFamily: "Comic Code, Menlo, Monaco, Courier New, sans",
|
||||||
|
automaticLayout: true,
|
||||||
|
acceptSuggestionOnEnter: "off",
|
||||||
|
unicodeHighlight: { ambiguousCharacters: false },
|
||||||
|
minimap: { enabled: false },
|
||||||
|
}));
|
||||||
|
monaco.languages.registerDefinitionProvider("newt", {
|
||||||
|
provideDefinition(model, position, token) {
|
||||||
|
const info = model.getWordAtPosition(position);
|
||||||
|
if (!info) return;
|
||||||
|
let entry = language.getEntry(
|
||||||
|
info.word,
|
||||||
|
position.lineNumber,
|
||||||
|
info.startColumn
|
||||||
|
);
|
||||||
|
if (!entry) return;
|
||||||
|
|
||||||
|
// HACK - we don't know our filename which was generated from `module` decl, so
|
||||||
|
// assume the last context entry is in our file.
|
||||||
|
|
||||||
|
let file = language.getFileName();
|
||||||
|
if (!entry || entry.fc.file !== file) return;
|
||||||
|
let lineNumber = entry.fc.line + 1;
|
||||||
|
let column = entry.fc.col + 1;
|
||||||
|
let word = model.getWordAtPosition({ lineNumber, column });
|
||||||
|
let range = new monaco.Range(lineNumber, column, lineNumber, column);
|
||||||
|
if (word) {
|
||||||
|
range = new monaco.Range(
|
||||||
|
lineNumber,
|
||||||
|
word.startColumn,
|
||||||
|
lineNumber,
|
||||||
|
word.endColumn
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return { uri: model.uri, range };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
monaco.languages.registerHoverProvider("newt", {
|
||||||
|
provideHover(model, position, token, context) {
|
||||||
|
const info = model.getWordAtPosition(position);
|
||||||
|
if (!info) return;
|
||||||
|
let entry = language.getEntry(
|
||||||
|
info.word,
|
||||||
|
position.lineNumber,
|
||||||
|
info.startColumn
|
||||||
|
);
|
||||||
|
if (!entry) return;
|
||||||
|
return {
|
||||||
|
range: new monaco.Range(
|
||||||
|
position.lineNumber,
|
||||||
|
info.startColumn,
|
||||||
|
position.lineNumber,
|
||||||
|
info.endColumn
|
||||||
|
),
|
||||||
|
contents: [{ value: `${entry.name} : ${entry.type}` }],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
editor.onDidChangeModelContent((ev) => {
|
||||||
|
this.delegate.onChange(editor.getValue());
|
||||||
|
|
||||||
|
let last = ev.changes[ev.changes.length - 1];
|
||||||
|
const model = editor.getModel();
|
||||||
|
// figure out heuristics here, what chars do we want to trigger?
|
||||||
|
// the lean one will only be active if it sees you type \
|
||||||
|
// and bail if it decides you've gone elsewhere
|
||||||
|
// it maintains an underline annotation, too.
|
||||||
|
if (model && last.text && " ')\\".includes(last.text)) {
|
||||||
|
console.log("LAST", last);
|
||||||
|
let { startLineNumber, startColumn } = last.range;
|
||||||
|
const text = model.getValueInRange(
|
||||||
|
new monaco.Range(
|
||||||
|
startLineNumber,
|
||||||
|
Math.max(1, startColumn - 10),
|
||||||
|
startLineNumber,
|
||||||
|
startColumn
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const m = text.match(/(\\[^ ]+)$/);
|
||||||
|
if (m) {
|
||||||
|
let cand = m[0];
|
||||||
|
console.log("GOT", cand);
|
||||||
|
let text = ABBREV[cand];
|
||||||
|
if (text) {
|
||||||
|
const range = new monaco.Range(
|
||||||
|
startLineNumber,
|
||||||
|
startColumn - cand.length,
|
||||||
|
startLineNumber,
|
||||||
|
startColumn
|
||||||
|
);
|
||||||
|
editor.executeEdits("replaceSequence", [{ range, text: text }]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setValue(value: string) {
|
||||||
|
this.editor.setValue(value);
|
||||||
|
}
|
||||||
|
getValue() {
|
||||||
|
return this.editor.getValue();
|
||||||
|
}
|
||||||
|
setMarkers(markers: Marker[]) {
|
||||||
|
let model = this.editor.getModel()!;
|
||||||
|
const mapMarker = (marker: Marker): monaco.editor.IMarkerData => {
|
||||||
|
let severity =
|
||||||
|
marker.severity === "ERROR"
|
||||||
|
? monaco.MarkerSeverity.Error
|
||||||
|
: monaco.MarkerSeverity.Info;
|
||||||
|
// translate to surrounding word
|
||||||
|
// FIXME - we have `getWord` in monaco, but probably belongs to the delegate
|
||||||
|
// and eventually we have better FC
|
||||||
|
let { message, startColumn, endColumn, startLineNumber, endLineNumber } =
|
||||||
|
marker;
|
||||||
|
let word = model.getWordAtPosition({
|
||||||
|
column: startColumn,
|
||||||
|
lineNumber: startLineNumber,
|
||||||
|
});
|
||||||
|
if (word) endColumn = word.endColumn;
|
||||||
|
return {
|
||||||
|
message,
|
||||||
|
startColumn,
|
||||||
|
endColumn,
|
||||||
|
startLineNumber,
|
||||||
|
endLineNumber,
|
||||||
|
severity,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
monaco.editor.setModelMarkers(model, "newt", markers.map(mapMarker));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scratch
|
||||||
|
const processOutput = (
|
||||||
|
editor: monaco.editor.IStandaloneCodeEditor,
|
||||||
|
output: string
|
||||||
|
) => {
|
||||||
|
let model = editor.getModel()!;
|
||||||
|
let markers: monaco.editor.IMarkerData[] = [];
|
||||||
|
let lines = output.split("\n");
|
||||||
|
let m = lines[0].match(/.*Process (.*)/);
|
||||||
|
let fn = "";
|
||||||
|
if (m) fn = m[1];
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
const match = line.match(/(INFO|ERROR) at (.*):\((\d+), (\d+)\):\s*(.*)/);
|
||||||
|
if (match) {
|
||||||
|
let [_full, kind, file, line, col, message] = match;
|
||||||
|
let lineNumber = +line + 1;
|
||||||
|
let column = +col + 1;
|
||||||
|
// FIXME - pass the real path in
|
||||||
|
if (fn && fn !== file) {
|
||||||
|
lineNumber = column = 0;
|
||||||
|
}
|
||||||
|
let start = { column, lineNumber };
|
||||||
|
// we don't have the full range, so grab the surrounding word
|
||||||
|
let endColumn = column + 1;
|
||||||
|
let word = model.getWordAtPosition(start);
|
||||||
|
if (word) endColumn = word.endColumn;
|
||||||
|
|
||||||
|
// heuristics to grab the entire message:
|
||||||
|
// anything indented
|
||||||
|
// Context:, or Goal: are part of PRINTME
|
||||||
|
// unexpected / expecting appear in parse errors
|
||||||
|
while (lines[i + 1]?.match(/^( )/)) {
|
||||||
|
message += "\n" + lines[++i];
|
||||||
|
}
|
||||||
|
const severity =
|
||||||
|
kind === "ERROR"
|
||||||
|
? monaco.MarkerSeverity.Error
|
||||||
|
: monaco.MarkerSeverity.Info;
|
||||||
|
if (kind === "ERROR" || lineNumber)
|
||||||
|
markers.push({
|
||||||
|
severity,
|
||||||
|
message,
|
||||||
|
startLineNumber: lineNumber,
|
||||||
|
endLineNumber: lineNumber,
|
||||||
|
startColumn: column,
|
||||||
|
endColumn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
monaco.editor.setModelMarkers(model, "newt", markers);
|
||||||
|
};
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
|
import { EditorView } from "codemirror";
|
||||||
|
import { linter, Diagnostic } from "@codemirror/lint";
|
||||||
|
|
||||||
export interface CompileReq {
|
export interface CompileReq {
|
||||||
|
id: string
|
||||||
type: "compileRequest";
|
type: "compileRequest";
|
||||||
fileName: string;
|
fileName: string;
|
||||||
src: string;
|
src: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompileRes {
|
export interface CompileRes {
|
||||||
|
id: string
|
||||||
type: "compileResult";
|
type: "compileResult";
|
||||||
output: string;
|
output: string;
|
||||||
javascript: string;
|
javascript: string;
|
||||||
@@ -26,3 +31,44 @@ export interface ExecCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Message = CompileReq | CompileRes | ConsoleList | ConsoleItem | ExecCode
|
export type Message = CompileReq | CompileRes | ConsoleList | ConsoleItem | ExecCode
|
||||||
|
// editor.(createModel / setModel / getModels) to switch files
|
||||||
|
// TODO - remember files and allow switching?
|
||||||
|
// static zip filesystem with user changes overlaid via localStorage
|
||||||
|
// download individual files (we could use the cheap compression from the pdflib or no compression to make zip download)
|
||||||
|
// would need way to reset/delete
|
||||||
|
export interface FC {
|
||||||
|
file: string;
|
||||||
|
line: number;
|
||||||
|
col: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TopEntry {
|
||||||
|
fc: FC;
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TopData {
|
||||||
|
context: TopEntry[];
|
||||||
|
}
|
||||||
|
export interface EditorDelegate {
|
||||||
|
getEntry(word: string, row: number, col: number): TopEntry | undefined
|
||||||
|
onChange(value: string): unknown
|
||||||
|
getFileName(): string
|
||||||
|
lint(view: EditorView): Promise<Diagnostic[]> | Diagnostic[]
|
||||||
|
}
|
||||||
|
export interface Marker {
|
||||||
|
severity: 'error' | 'info' | 'warning'
|
||||||
|
message: string
|
||||||
|
startColumn: number
|
||||||
|
startLineNumber: number
|
||||||
|
endColumn: number
|
||||||
|
endLineNumber: number
|
||||||
|
}
|
||||||
|
export interface AbstractEditor {
|
||||||
|
setValue: (_: string) => unknown;
|
||||||
|
getValue: () => string;
|
||||||
|
setMarkers: (_: Marker[]) => unknown
|
||||||
|
setDark(isDark: boolean): unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const handleMessage = async function (ev: { data: CompileReq }) {
|
|||||||
console.log("message", ev.data);
|
console.log("message", ev.data);
|
||||||
await preload;
|
await preload;
|
||||||
shim.archive = archive;
|
shim.archive = archive;
|
||||||
let { src, fileName } = ev.data;
|
let { id, src, fileName } = ev.data;
|
||||||
const outfile = "out.js";
|
const outfile = "out.js";
|
||||||
shim.process.argv = ["browser", "newt", fileName, "-o", outfile, "--top"];
|
shim.process.argv = ["browser", "newt", fileName, "-o", outfile, "--top"];
|
||||||
shim.files[fileName] = new TextEncoder().encode(src);
|
shim.files[fileName] = new TextEncoder().encode(src);
|
||||||
@@ -29,7 +29,7 @@ const handleMessage = async function (ev: { data: CompileReq }) {
|
|||||||
console.log(`process ${fileName} in ${duration} ms`);
|
console.log(`process ${fileName} in ${duration} ms`);
|
||||||
let javascript = new TextDecoder().decode(shim.files[outfile]);
|
let javascript = new TextDecoder().decode(shim.files[outfile]);
|
||||||
let output = shim.stdout;
|
let output = shim.stdout;
|
||||||
sendResponse({ type: 'compileResult', javascript, output, duration });
|
sendResponse({ id, type: 'compileResult', javascript, output, duration });
|
||||||
};
|
};
|
||||||
|
|
||||||
// hooks for worker.html to override
|
// hooks for worker.html to override
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
svg.icon path {
|
svg.icon path {
|
||||||
stroke: black;
|
stroke: black;
|
||||||
fill: none;
|
fill: none;
|
||||||
@@ -87,3 +90,6 @@ svg.icon path {
|
|||||||
white-space: pre;
|
white-space: pre;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
.tooltip {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
"outDir": "out",
|
"outDir": "out",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user