Compare commits

...

4 Commits

Author SHA1 Message Date
SArpnt 4907d1f38b
minor formatting tweak 2024-04-11 15:33:19 -04:00
SArpnt 6bcdd151db
delete old code-input files 2024-04-11 15:33:07 -04:00
SArpnt b3fbcf79e7
seperate out code transformation in audio worklet 2024-04-11 15:32:40 -04:00
SArpnt 81dad88520
update dependencies 2024-04-11 15:32:06 -04:00
9 changed files with 240 additions and 1125 deletions

View File

@ -13,7 +13,7 @@
'@codemirror/language': '^6.10.1',
'@codemirror/search': '^6.5.6',
'@codemirror/state': '^6.4.1',
'@codemirror/view': '^6.26.0',
'@codemirror/view': '^6.26.2',
'@lezer/highlight': '^1.2.0',
esbuild: '^0.20.2',
fflate: '^0.8.2',
@ -26,8 +26,8 @@
jest: '^29.7.0',
'jest-environment-jsdom': '^29.7.0',
prettier: '^3.2.5',
'ts-essentials': '^9.4.1',
'ts-essentials': '^9.4.2',
'ts-jest': '^29.1.2',
typescript: '^5.4.2',
typescript: '^5.4.5',
},
}

View File

@ -24,8 +24,8 @@ dependencies:
specifier: ^6.4.1
version: 6.4.1
'@codemirror/view':
specifier: ^6.26.0
version: 6.26.0
specifier: ^6.26.2
version: 6.26.2
'@lezer/highlight':
specifier: ^1.2.0
version: 1.2.0
@ -59,14 +59,14 @@ devDependencies:
specifier: ^3.2.5
version: 3.2.5
ts-essentials:
specifier: ^9.4.1
version: 9.4.1(typescript@5.4.2)
specifier: ^9.4.2
version: 9.4.2(typescript@5.4.5)
ts-jest:
specifier: ^29.1.2
version: 29.1.2(@babel/core@7.24.0)(esbuild@0.20.2)(jest@29.7.0)(typescript@5.4.2)
version: 29.1.2(@babel/core@7.24.4)(esbuild@0.20.2)(jest@29.7.0)(typescript@5.4.5)
typescript:
specifier: ^5.4.2
version: 5.4.2
specifier: ^5.4.5
version: 5.4.5
packages:
@ -128,7 +128,7 @@ packages:
is-glob: 4.0.3
iso-639-1: 2.1.15
kleur: 4.1.5
liquidjs: 10.10.1
liquidjs: 10.10.2
luxon: 3.4.4
markdown-it: 13.0.2
micromatch: 4.0.5
@ -138,7 +138,7 @@ packages:
mustache: 4.2.0
normalize-path: 3.0.0
nunjucks: 3.2.4(chokidar@3.6.0)
path-to-regexp: 6.2.1
path-to-regexp: 6.2.2
please-upgrade-node: 3.2.0
posthtml: 0.16.6
posthtml-urls: 1.0.0
@ -165,32 +165,32 @@ packages:
'@jridgewell/trace-mapping': 0.3.25
dev: true
/@babel/code-frame@7.23.5:
resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==}
/@babel/code-frame@7.24.2:
resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/highlight': 7.23.4
chalk: 2.4.2
'@babel/highlight': 7.24.2
picocolors: 1.0.0
dev: true
/@babel/compat-data@7.23.5:
resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==}
/@babel/compat-data@7.24.4:
resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==}
engines: {node: '>=6.9.0'}
dev: true
/@babel/core@7.24.0:
resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==}
/@babel/core@7.24.4:
resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==}
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.23.5
'@babel/generator': 7.23.6
'@babel/code-frame': 7.24.2
'@babel/generator': 7.24.4
'@babel/helper-compilation-targets': 7.23.6
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0)
'@babel/helpers': 7.24.0
'@babel/parser': 7.24.0
'@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4)
'@babel/helpers': 7.24.4
'@babel/parser': 7.24.4
'@babel/template': 7.24.0
'@babel/traverse': 7.24.0
'@babel/traverse': 7.24.1
'@babel/types': 7.24.0
convert-source-map: 2.0.0
debug: 4.3.4
@ -201,8 +201,8 @@ packages:
- supports-color
dev: true
/@babel/generator@7.23.6:
resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==}
/@babel/generator@7.24.4:
resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.24.0
@ -215,7 +215,7 @@ packages:
resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/compat-data': 7.23.5
'@babel/compat-data': 7.24.4
'@babel/helper-validator-option': 7.23.5
browserslist: 4.23.0
lru-cache: 5.1.1
@ -242,22 +242,22 @@ packages:
'@babel/types': 7.24.0
dev: true
/@babel/helper-module-imports@7.22.15:
resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
/@babel/helper-module-imports@7.24.3:
resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.24.0
dev: true
/@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0):
/@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4):
resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-module-imports': 7.22.15
'@babel/helper-module-imports': 7.24.3
'@babel/helper-simple-access': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/helper-validator-identifier': 7.22.20
@ -282,8 +282,8 @@ packages:
'@babel/types': 7.24.0
dev: true
/@babel/helper-string-parser@7.23.4:
resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==}
/@babel/helper-string-parser@7.24.1:
resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
engines: {node: '>=6.9.0'}
/@babel/helper-validator-identifier@7.22.20:
@ -295,159 +295,160 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
/@babel/helpers@7.24.0:
resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==}
/@babel/helpers@7.24.4:
resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/template': 7.24.0
'@babel/traverse': 7.24.0
'@babel/traverse': 7.24.1
'@babel/types': 7.24.0
transitivePeerDependencies:
- supports-color
dev: true
/@babel/highlight@7.23.4:
resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==}
/@babel/highlight@7.24.2:
resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-validator-identifier': 7.22.20
chalk: 2.4.2
js-tokens: 4.0.0
picocolors: 1.0.0
dev: true
/@babel/parser@7.24.0:
resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==}
/@babel/parser@7.24.4:
resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==}
engines: {node: '>=6.0.0'}
hasBin: true
dependencies:
'@babel/types': 7.24.0
/@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0):
/@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4):
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0):
/@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4):
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.0):
/@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4):
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0):
resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==}
/@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.4):
resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0):
/@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0):
/@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0):
/@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0):
/@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4):
resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
/@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0):
resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==}
/@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.4):
resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@babel/helper-plugin-utils': 7.24.0
dev: true
@ -455,22 +456,22 @@ packages:
resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/parser': 7.24.0
'@babel/code-frame': 7.24.2
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
dev: true
/@babel/traverse@7.24.0:
resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==}
/@babel/traverse@7.24.1:
resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/generator': 7.23.6
'@babel/code-frame': 7.24.2
'@babel/generator': 7.24.4
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
'@babel/parser': 7.24.0
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
debug: 4.3.4
globals: 11.12.0
@ -482,7 +483,7 @@ packages:
resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/helper-string-parser': 7.23.4
'@babel/helper-string-parser': 7.24.1
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
@ -490,7 +491,7 @@ packages:
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
/@codemirror/autocomplete@6.15.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.0)(@lezer/common@1.2.1):
/@codemirror/autocomplete@6.15.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.2)(@lezer/common@1.2.1):
resolution: {integrity: sha512-G2Zm0mXznxz97JhaaOdoEG2cVupn4JjPaS4AcNvZzhOsnnG9YVN68VzfoUw6dYTsIxT6a/cmoFEN47KAWhXaOg==}
peerDependencies:
'@codemirror/language': ^6.0.0
@ -500,7 +501,7 @@ packages:
dependencies:
'@codemirror/language': 6.10.1
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
'@lezer/common': 1.2.1
dev: false
@ -509,27 +510,27 @@ packages:
dependencies:
'@codemirror/language': 6.10.1
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
'@lezer/common': 1.2.1
dev: false
/@codemirror/lang-javascript@6.2.2:
resolution: {integrity: sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==}
dependencies:
'@codemirror/autocomplete': 6.15.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.0)(@lezer/common@1.2.1)
'@codemirror/autocomplete': 6.15.0(@codemirror/language@6.10.1)(@codemirror/state@6.4.1)(@codemirror/view@6.26.2)(@lezer/common@1.2.1)
'@codemirror/language': 6.10.1
'@codemirror/lint': 6.5.0
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
'@lezer/common': 1.2.1
'@lezer/javascript': 1.4.13
'@lezer/javascript': 1.4.14
dev: false
/@codemirror/language@6.10.1:
resolution: {integrity: sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==}
dependencies:
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
'@lezer/common': 1.2.1
'@lezer/highlight': 1.2.0
'@lezer/lr': 1.4.0
@ -540,7 +541,7 @@ packages:
resolution: {integrity: sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==}
dependencies:
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
crelt: 1.0.6
dev: false
@ -548,7 +549,7 @@ packages:
resolution: {integrity: sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==}
dependencies:
'@codemirror/state': 6.4.1
'@codemirror/view': 6.26.0
'@codemirror/view': 6.26.2
crelt: 1.0.6
dev: false
@ -556,8 +557,8 @@ packages:
resolution: {integrity: sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==}
dev: false
/@codemirror/view@6.26.0:
resolution: {integrity: sha512-nSSmzONpqsNzshPOxiKhK203R6BvABepugAe34QfQDbNDslyjkqBuKgrK5ZBvqNXpfxz5iLrlGTmEfhbQyH46A==}
/@codemirror/view@6.26.2:
resolution: {integrity: sha512-j6V48PlFC/O7ERAR5vRW5QKDdchzmyyfojDdt+zPsB0YXoWgcjlC1IWjmlYfx08aQZ3HN5BtALcgGgtSKGMe7A==}
dependencies:
'@codemirror/state': 6.4.1
style-mod: 4.1.2
@ -773,7 +774,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
jest-message-util: 29.7.0
jest-util: 29.7.0
@ -794,14 +795,14 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.9.0
exit: 0.1.2
graceful-fs: 4.2.11
jest-changed-files: 29.7.0
jest-config: 29.7.0(@types/node@20.11.27)
jest-config: 29.7.0(@types/node@20.12.7)
jest-haste-map: 29.7.0
jest-message-util: 29.7.0
jest-regex-util: 29.6.3
@ -829,7 +830,7 @@ packages:
dependencies:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-mock: 29.7.0
dev: true
@ -856,7 +857,7 @@ packages:
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-message-util: 29.7.0
jest-mock: 29.7.0
jest-util: 29.7.0
@ -889,7 +890,7 @@ packages:
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@jridgewell/trace-mapping': 0.3.25
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit: 0.1.2
@ -951,7 +952,7 @@ packages:
resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@jest/types': 29.6.3
'@jridgewell/trace-mapping': 0.3.25
babel-plugin-istanbul: 6.1.1
@ -977,7 +978,7 @@ packages:
'@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4
'@types/node': 20.11.27
'@types/node': 20.12.7
'@types/yargs': 17.0.32
chalk: 4.1.2
dev: true
@ -1022,8 +1023,8 @@ packages:
'@lezer/common': 1.2.1
dev: false
/@lezer/javascript@1.4.13:
resolution: {integrity: sha512-5IBr8LIO3xJdJH1e9aj/ZNLE4LSbdsx25wFmGRAZsj2zSmwAYjx26JyU/BYOCpRQlu1jcv1z3vy4NB9+UkfRow==}
/@lezer/javascript@1.4.14:
resolution: {integrity: sha512-GEdUyspTRgc5dwIGebUk+f3BekvqEWVIYsIuAC3pA8e8wcikGwBZRWRa450L0s8noGWuULwnmi4yjxTnYz9PpA==}
dependencies:
'@lezer/common': 1.2.1
'@lezer/highlight': 1.2.0
@ -1111,7 +1112,7 @@ packages:
/@types/babel__core@7.20.5:
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
dependencies:
'@babel/parser': 7.24.0
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
'@types/babel__generator': 7.6.8
'@types/babel__template': 7.4.4
@ -1127,7 +1128,7 @@ packages:
/@types/babel__template@7.4.4:
resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
dependencies:
'@babel/parser': 7.24.0
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
dev: true
@ -1140,7 +1141,7 @@ packages:
/@types/graceful-fs@4.1.9:
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
dependencies:
'@types/node': 20.11.27
'@types/node': 20.12.7
dev: true
/@types/istanbul-lib-coverage@2.0.6:
@ -1169,7 +1170,7 @@ packages:
/@types/jsdom@20.0.1:
resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
dependencies:
'@types/node': 20.11.27
'@types/node': 20.12.7
'@types/tough-cookie': 4.0.5
parse5: 7.1.2
dev: true
@ -1178,8 +1179,8 @@ packages:
resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
dev: false
/@types/node@20.11.27:
resolution: {integrity: sha512-qyUZfMnCg1KEz57r7pzFtSGt49f6RPkPBis3Vo4PbS7roQEDn22hiHzl/Lo1q4i4hDEgBJmBF/NTNg2XR0HbFg==}
/@types/node@20.12.7:
resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==}
dependencies:
undici-types: 5.26.5
dev: true
@ -1346,17 +1347,17 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
/babel-jest@29.7.0(@babel/core@7.24.0):
/babel-jest@29.7.0(@babel/core@7.24.4):
resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.8.0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@jest/transform': 29.7.0
'@types/babel__core': 7.20.5
babel-plugin-istanbul: 6.1.1
babel-preset-jest: 29.6.3(@babel/core@7.24.0)
babel-preset-jest: 29.6.3(@babel/core@7.24.4)
chalk: 4.1.2
graceful-fs: 4.2.11
slash: 3.0.0
@ -1387,35 +1388,35 @@ packages:
'@types/babel__traverse': 7.20.5
dev: true
/babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.0):
/babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.4):
resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.24.0
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0)
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0)
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0)
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0)
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0)
'@babel/core': 7.24.4
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4)
'@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.4)
'@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.4)
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4)
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4)
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4)
dev: true
/babel-preset-jest@29.6.3(@babel/core@7.24.0):
/babel-preset-jest@29.6.3(@babel/core@7.24.4):
resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
babel-plugin-jest-hoist: 29.6.3
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0)
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4)
dev: true
/babel-walk@3.0.0-canary-5:
@ -1475,8 +1476,8 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001597
electron-to-chromium: 1.4.706
caniuse-lite: 1.0.30001608
electron-to-chromium: 1.4.733
node-releases: 2.0.14
update-browserslist-db: 1.0.13(browserslist@4.23.0)
dev: true
@ -1530,8 +1531,8 @@ packages:
engines: {node: '>=10'}
dev: true
/caniuse-lite@1.0.30001597:
resolution: {integrity: sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==}
/caniuse-lite@1.0.30001608:
resolution: {integrity: sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA==}
dev: true
/chalk@2.4.2:
@ -1655,7 +1656,7 @@ packages:
/constantinople@4.0.1:
resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==}
dependencies:
'@babel/parser': 7.24.0
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
dev: false
@ -1672,7 +1673,7 @@ packages:
chalk: 4.1.2
exit: 0.1.2
graceful-fs: 4.2.11
jest-config: 29.7.0(@types/node@20.11.27)
jest-config: 29.7.0(@types/node@20.12.7)
jest-util: 29.7.0
prompts: 2.4.2
transitivePeerDependencies:
@ -1744,8 +1745,8 @@ packages:
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
dev: true
/dedent@1.5.1:
resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==}
/dedent@1.5.3:
resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==}
peerDependencies:
babel-plugin-macros: ^3.1.0
peerDependenciesMeta:
@ -1843,8 +1844,8 @@ packages:
jake: 10.8.7
dev: false
/electron-to-chromium@1.4.706:
resolution: {integrity: sha512-fO01fufoGd6jKK3HR8ofBapF3ZPfgxNJ/ua9xQAhFu93TwWIs4d+weDn3kje3GB4S7aGUTfk5nvdU5F7z5mF9Q==}
/electron-to-chromium@1.4.733:
resolution: {integrity: sha512-gUI9nhI2iBGF0OaYYLKOaOtliFMl+Bt1rY7VmEjwxOxqoYLub/D9xmduPEhbw2imE6gYkJKhIE5it+KE2ulVxQ==}
dev: true
/emittery@0.13.1:
@ -2434,8 +2435,8 @@ packages:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
engines: {node: '>=8'}
dependencies:
'@babel/core': 7.24.0
'@babel/parser': 7.24.0
'@babel/core': 7.24.4
'@babel/parser': 7.24.4
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 6.3.1
@ -2447,8 +2448,8 @@ packages:
resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==}
engines: {node: '>=10'}
dependencies:
'@babel/core': 7.24.0
'@babel/parser': 7.24.0
'@babel/core': 7.24.4
'@babel/parser': 7.24.4
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.2
semver: 7.6.0
@ -2512,10 +2513,10 @@ packages:
'@jest/expect': 29.7.0
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
co: 4.6.0
dedent: 1.5.1
dedent: 1.5.3
is-generator-fn: 2.1.0
jest-each: 29.7.0
jest-matcher-utils: 29.7.0
@ -2525,7 +2526,7 @@ packages:
jest-util: 29.7.0
p-limit: 3.1.0
pretty-format: 29.7.0
pure-rand: 6.0.4
pure-rand: 6.1.0
slash: 3.0.0
stack-utils: 2.0.6
transitivePeerDependencies:
@ -2550,7 +2551,7 @@ packages:
create-jest: 29.7.0
exit: 0.1.2
import-local: 3.1.0
jest-config: 29.7.0(@types/node@20.11.27)
jest-config: 29.7.0(@types/node@20.12.7)
jest-util: 29.7.0
jest-validate: 29.7.0
yargs: 17.7.2
@ -2561,7 +2562,7 @@ packages:
- ts-node
dev: true
/jest-config@29.7.0(@types/node@20.11.27):
/jest-config@29.7.0(@types/node@20.12.7):
resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
@ -2573,11 +2574,11 @@ packages:
ts-node:
optional: true
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
'@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
babel-jest: 29.7.0(@babel/core@7.24.0)
'@types/node': 20.12.7
babel-jest: 29.7.0(@babel/core@7.24.4)
chalk: 4.1.2
ci-info: 3.9.0
deepmerge: 4.3.1
@ -2642,7 +2643,7 @@ packages:
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
'@types/jsdom': 20.0.1
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-mock: 29.7.0
jest-util: 29.7.0
jsdom: 20.0.3
@ -2659,7 +2660,7 @@ packages:
'@jest/environment': 29.7.0
'@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-mock: 29.7.0
jest-util: 29.7.0
dev: true
@ -2675,7 +2676,7 @@ packages:
dependencies:
'@jest/types': 29.6.3
'@types/graceful-fs': 4.1.9
'@types/node': 20.11.27
'@types/node': 20.12.7
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
@ -2710,7 +2711,7 @@ packages:
resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/code-frame': 7.24.2
'@jest/types': 29.6.3
'@types/stack-utils': 2.0.3
chalk: 4.1.2
@ -2726,7 +2727,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-util: 29.7.0
dev: true
@ -2781,7 +2782,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.11
@ -2812,7 +2813,7 @@ packages:
'@jest/test-result': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
cjs-module-lexer: 1.2.3
collect-v8-coverage: 1.0.2
@ -2835,15 +2836,15 @@ packages:
resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.24.0
'@babel/generator': 7.23.6
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0)
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0)
'@babel/core': 7.24.4
'@babel/generator': 7.24.4
'@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4)
'@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4)
'@babel/types': 7.24.0
'@jest/expect-utils': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0)
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4)
chalk: 4.1.2
expect: 29.7.0
graceful-fs: 4.2.11
@ -2864,7 +2865,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
chalk: 4.1.2
ci-info: 3.9.0
graceful-fs: 4.2.11
@ -2889,7 +2890,7 @@ packages:
dependencies:
'@jest/test-result': 29.7.0
'@jest/types': 29.6.3
'@types/node': 20.11.27
'@types/node': 20.12.7
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@ -2901,7 +2902,7 @@ packages:
resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@types/node': 20.11.27
'@types/node': 20.12.7
jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
@ -3042,8 +3043,8 @@ packages:
uc.micro: 1.0.6
dev: false
/liquidjs@10.10.1:
resolution: {integrity: sha512-h699VW79OLoshCTjFF02tmRCrd8t/E49LSIsjLwlg4k0TbMVjxsCRXVUEsURXbfKl3HUln2cShlDQCrSNm2YaA==}
/liquidjs@10.10.2:
resolution: {integrity: sha512-UcuTUexKg/8CmX6I5KNghk13pl3c8Rqhm+WSWqrc17pQP9LjpYPpOLDKG9OMBeHDBQ70yyn/GOqyZ/EKJ4z5yg==}
engines: {node: '>=14'}
hasBin: true
dependencies:
@ -3344,7 +3345,7 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
dependencies:
'@babel/code-frame': 7.23.5
'@babel/code-frame': 7.24.2
error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
@ -3381,8 +3382,8 @@ packages:
/path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
/path-to-regexp@6.2.1:
resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
/path-to-regexp@6.2.2:
resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==}
dev: false
/picocolors@1.0.0:
@ -3585,8 +3586,8 @@ packages:
engines: {node: '>=6'}
dev: true
/pure-rand@6.0.4:
resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==}
/pure-rand@6.1.0:
resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==}
dev: true
/querystringify@2.2.0:
@ -3911,18 +3912,18 @@ packages:
punycode: 2.3.1
dev: true
/ts-essentials@9.4.1(typescript@5.4.2):
resolution: {integrity: sha512-oke0rI2EN9pzHsesdmrOrnqv1eQODmJpd/noJjwj2ZPC3Z4N2wbjrOEqnsEgmvlO2+4fBb0a794DCna2elEVIQ==}
/ts-essentials@9.4.2(typescript@5.4.5):
resolution: {integrity: sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==}
peerDependencies:
typescript: '>=4.1.0'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
typescript: 5.4.2
typescript: 5.4.5
dev: true
/ts-jest@29.1.2(@babel/core@7.24.0)(esbuild@0.20.2)(jest@29.7.0)(typescript@5.4.2):
/ts-jest@29.1.2(@babel/core@7.24.4)(esbuild@0.20.2)(jest@29.7.0)(typescript@5.4.5):
resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==}
engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0}
hasBin: true
@ -3943,7 +3944,7 @@ packages:
esbuild:
optional: true
dependencies:
'@babel/core': 7.24.0
'@babel/core': 7.24.4
bs-logger: 0.2.6
esbuild: 0.20.2
fast-json-stable-stringify: 2.1.0
@ -3953,7 +3954,7 @@ packages:
lodash.memoize: 4.1.2
make-error: 1.3.6
semver: 7.6.0
typescript: 5.4.2
typescript: 5.4.5
yargs-parser: 21.1.1
dev: true
@ -3967,8 +3968,8 @@ packages:
engines: {node: '>=10'}
dev: true
/typescript@5.4.2:
resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==}
/typescript@5.4.5:
resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
@ -4087,7 +4088,7 @@ packages:
resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==}
engines: {node: '>= 10.0.0'}
dependencies:
'@babel/parser': 7.24.0
'@babel/parser': 7.24.4
'@babel/types': 7.24.0
assert-never: 1.2.1
babel-walk: 3.0.0-canary-5

View File

@ -1,3 +1,4 @@
import { transformCode } from "./transform-code.ts";
import type { DrawSample } from "../oscillioscope.ts";
// @types/audioworklet is wrong, so redeclare the broken types here
@ -19,47 +20,6 @@ declare abstract class AudioWorkletProcessor {
}
declare function registerProcessor(name: string, processorCtor: AudioWorkletProcessor): void;
function jsOptimize(script: string, isExpression: boolean) {
script = script.trim();
if (isExpression) {
// detect eval(unescape(escape(<const string>).replace(/u(..)/g, "$1%")))
// TODO version for funcbeat
let hadStart = false;
const withoutStart = script.replace(
/^eval\s*\(\s*unescape\s*\(\s*escape/,
() => ((hadStart = true), ""),
);
if (hadStart) {
let hadEnd = false;
const withoutEnd = withoutStart.replace(
/\.replace\(\/u\(\.\.\)\/g,([`"'])\$1%\1\)\)\)$/,
() => ((hadEnd = true), ""),
);
if (hadEnd) {
let hadParens = false;
const content = withoutEnd.replace(
/^\s*\((?<content>.*)\)\s*$/s,
(_, content) => ((hadParens = true), content),
);
const part4 = content
.trim()
.match(hadParens ? /^(?<quote>[`"'])(?<content>.*)\1$/s : /^`(?<content>.*)`$/s);
if (part4) {
const quote = part4.groups.quote ?? "`";
const stringContent = part4.groups.content;
if (
!stringContent.includes(part4.groups.quote) &&
!stringContent.includes("\\") // TODO: improve escape handling
) {
script = unescape(escape(stringContent).replace(/u(..)/g, "$1%"));
}
}
}
}
}
return script;
}
function safeStringify(value: any, quoteString?: boolean) {
if (!quoteString && typeof value === "string") {
return value;
@ -247,14 +207,14 @@ class BytebeatProcessor extends AudioWorkletProcessor {
try {
errType = "compile";
if (this.songData.mode === "Funcbeat") {
const optimizedCode = jsOptimize(code, false);
this.func = new Function(...params, optimizedCode).bind(globalThis, ...values);
const transformedCode = transformCode(code, false);
this.func = new Function(...params, transformedCode).bind(globalThis, ...values);
} else {
const optimizedCode = jsOptimize(code, true);
const transformedCode = transformCode(code, true);
this.func = new Function(
...params,
"t",
`return 0,\n${optimizedCode || "undefined"}\n;`,
`return 0,\n${transformedCode || "undefined"}\n;`,
).bind(globalThis, ...values);
}
errType = "runtime";

View File

@ -0,0 +1,52 @@
// ideally in the future this will do far better optimizations to code by doing real code parsing
// currently this detects one not very common but important case
/**
* detect eval(unescape(escape(<const string>).replace(/u(..)/g, "$1%")))
* and replace it with the generated code
*/
function constEval(expression: string): string {
let hadStart = false;
const withoutStart = expression.replace(
/^eval\s*\(\s*unescape\s*\(\s*escape/,
() => ((hadStart = true), ""),
);
if (hadStart) {
let hadEnd = false;
const withoutEnd = withoutStart.replace(
/\.replace\(\/u\(\.\.\)\/g,([`"'])\$1%\1\)\)\)$/,
() => ((hadEnd = true), ""),
);
if (hadEnd) {
let hadParens = false;
const content = withoutEnd.replace(
/^\s*\((?<content>.*)\)\s*$/s,
(_, content) => ((hadParens = true), content),
);
const part4 = content
.trim()
.match(hadParens ? /^(?<quote>[`"'])(?<content>.*)\1$/s : /^`(?<content>.*)`$/s);
if (part4) {
const groups = part4.groups!; // the regex is a constant
const stringContent = groups.content;
if (
!stringContent.includes(groups.quote) &&
!stringContent.includes("\\") // TODO: improve escape handling
) {
return unescape(escape(stringContent).replace(/u(..)/g, "$1%"));
}
}
}
}
return expression;
}
function transformCode(script: string, isExpression: boolean): string {
script = script.trim();
if (isExpression) {
script = constEval(script);
}
return script;
}
export { transformCode };

View File

@ -1,100 +0,0 @@
/* Code-Input Compatibility */
/* By WebCoder49 */
/* First Published on CSS-Tricks.com */
code-input {
/* Allow other elems to be inside */
position: relative;
top: 0;
left: 0;
display: block;
/* Only scroll inside elems */
overflow: hidden;
/* Normal inline styles */
padding: 8px;
margin: 0!important;
width: calc(100% - 16px);
height: 250px;
font-size: normal;
font-family: monospace;
line-height: 1.5; /* Inherited to child elements */
tab-size: 2;
caret-color: darkgrey;
white-space: pre;
}
code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, code-input.code-input_pre-element-styled pre {
/* Both elements need the same text and space styling so they are directly on top of each other */
margin: 0px!important;
padding: var(--padding, 16px)!important;
border: 0;
width: calc(100% - var(--padding, 16px) * 2);
height: calc(100% - var(--padding, 16px) * 2);
}
code-input:not(.code-input_pre-element-styled) pre, code-input.code-input_pre-element-styled pre code {
/* Remove all margin and padding from others */
margin: 0px!important;
padding: 0px!important;
width: 100%;
height: 100%;
}
code-input textarea, code-input pre, code-input pre * {
/* Also add text styles to highlighing tokens */
font-size: inherit!important;
font-family: inherit!important;
line-height: inherit!important;
tab-size: inherit!important;
}
code-input textarea, code-input pre {
/* In the same place */
position: absolute;
top: 0;
left: 0;
}
/* Move the textarea in front of the result */
code-input textarea {
z-index: 1;
}
code-input pre {
z-index: 0;
}
/* Make textarea almost completely transparent */
code-input textarea {
color: transparent;
background: transparent;
caret-color: inherit!important; /* Or choose your favourite color */
}
/* Can be scrolled */
code-input textarea, code-input pre {
overflow: auto!important;
white-space: inherit;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
}
/* No resize on textarea; stop outline */
code-input textarea {
resize: none;
outline: none!important;
}
code-input:not(.code-input_registered)::before {
/* Display message to register */
content: "Use codeInput.registerTemplate to set up.";
display: block;
color: grey;
}

View File

@ -1,480 +0,0 @@
const observedAttributes = ["value", "placeholder", "lang", "template"];
const textareaSyncAttributes = [
"value",
"name",
// Form validation - https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation#using_built-in_form_validation
"required",
"minlength",
"maxlength",
"min",
"max",
"type",
"pattern",
];
const textareaSyncEvents = ["change", "selectionchange", "invalid", "input"];
const usedTemplates = {};
let defaultTemplate = undefined;
/**
* A queue of elements waiting for a template to be registered,
* allowing elements to be created in HTML with a template before
* the template is registered in JS, for ease of use.
* Key - Template Name
* Value - An array of code-input elements
* @type {Object}
*/
const templateNotYetRegisteredQueue = {};
/**
* Register a template so code-input elements with a template attribute that equals the templateName will use the template.
* See `codeInput.templates` for constructors to create templates.
* @param {string} templateName - the name to register the template under
* @param {Object} template - a Template object instance - see `codeInput.templates`
*/
function registerTemplate(templateName, template) {
codeInput.usedTemplates[templateName] = template;
// Add waiting code-input elements wanting this template from queue
if (templateName in codeInput.templateNotYetRegisteredQueue) {
for (let i in codeInput.templateNotYetRegisteredQueue[templateName]) {
elem = codeInput.templateNotYetRegisteredQueue[templateName][i];
elem.template = template;
elem.setup();
}
console.log(
`code-input: template: Added existing elements with template ${templateName}`,
);
}
if (codeInput.defaultTemplate === undefined) {
codeInput.defaultTemplate = templateName;
// Add elements with default template from queue
if (undefined in codeInput.templateNotYetRegisteredQueue) {
for (let i in codeInput.templateNotYetRegisteredQueue[undefined]) {
elem = codeInput.templateNotYetRegisteredQueue[undefined][i];
elem.template = template;
elem.setup();
}
}
console.log(
`code-input: template: Set template ${templateName} as default`,
);
}
console.log(`code-input: template: Created template ${templateName}`);
}
/// custom template instance. Pass this into `codeInput.registerTemplate` to use it.
class Template {
/**
* @param {Function} highlight - a callback to highlight the code, that takes an HTML `<code>` element inside a `<pre>` element as a parameter
* @param {boolean} preElementStyled - is the <pre> element CSS-styled as well as the `<code>` element? If true, `<pre>` element's scrolling is synchronised; if false, <code> element's scrolling is synchronised.
* @param {boolean} includeCodeInputInHighlightFunc - Setting this to true passes the `<code-input>` element as a second argument to the highlight function.
* @param {codeInput.Plugin[]} plugins - An array of plugin objects to add extra features - see `codeInput.plugins`
*/
constructor(
highlight = function () {},
preElementStyled = true,
includeCodeInputInHighlightFunc = false,
plugins = [],
) {
this.highlight = highlight;
this.includeCodeInputInHighlightFunc = includeCodeInputInHighlightFunc;
this.preElementStyled = preElementStyled;
this.plugins = plugins;
}
}
const plugins = {};
/**
* Plugins are imported from the plugins folder. They will then
* provide custom extra functionality to code-input elements.
*/
class Plugin {
constructor() {
console.log("code-input: plugin: Created plugin");
codeInput.observedAttributes = codeInput.observedAttributes.concat(
self.observedAttributes,
);
}
beforeHighlight(codeInput) {}
afterHighlight(codeInput) {}
beforeElementsAdded(codeInput) {}
afterElementsAdded(codeInput) {}
attributeChanged(codeInput, name, oldValue, newValue) {}
observedAttributes = [];
}
/* ------------------------------------
* -------------Main-------------------
* ------------------------------------ */
class CodeInput extends HTMLElement {
constructor() {
super();
}
/**
* When events are transferred to the textarea element, callbacks
* are bound to set the this variable to the code-inpute element
* rather than the textarea. This allows the callback to be converted
* to a bound one:
* Key - Callback not bound
* Value - Callback that is bound, with this equalling the code-input element in the callback
*/
boundEventCallbacks = {};
/** Trigger this event in all plugins with a optional list of arguments
* @param {string} eventName - the name of the event to trigger
* @param {Array} args - the arguments to pass into the event callback in the template after the code-input element. Normally left empty
*/
pluginEvt(eventName, args) {
for (const i in this.template.plugins) {
const plugin = this.template.plugins[i];
if (eventName in plugin) {
if (args === undefined) {
plugin[eventName](this);
} else {
plugin[eventName](this, ...args);
}
}
}
}
/* ------------------------------------
* ----------Main Functionality--------
* ------------------------------------
* The main function of a code-input element is to take
* code written in its textarea element, copy this code into
* the result (pre code) element, then use the template object
* to syntax-highlight it. */
/** Update the text value to the result element, after the textarea contents have changed.
* @param {string} value - The text value of the code-input element
*/
update(value) {
// Prevent this from running multiple times on the same input when "value" attribute is changed,
// by not running when value is already equal to the input of this (implying update has already
// been run). Thank you to peterprvy for this.
if (this.ignoreValueUpdate) return;
this.ignoreValueUpdate = true;
this.value = value;
this.ignoreValueUpdate = false;
if (this.querySelector("textarea").value != value)
this.querySelector("textarea").value = value;
let resultElement = this.querySelector("pre code");
// Handle final newlines
if (value[value.length - 1] === "\n") {
value += " ";
}
// Update code
resultElement.innerHTML = this.escapeHtml(value);
this.pluginEvt("beforeHighlight");
// Syntax Highlight
if (this.template.includeCodeInputInHighlightFunc)
this.template.highlight(resultElement, this);
else this.template.highlight(resultElement);
this.pluginEvt("afterHighlight");
}
/// Synchronise the scrolling of the textarea to the result element.
syncScroll() {
let inputElement = this.querySelector("textarea");
let resultElement = this.template.preElementStyled
? this.querySelector("pre")
: this.querySelector("pre code");
resultElement.scrollTop = inputElement.scrollTop;
resultElement.scrollLeft = inputElement.scrollLeft;
}
/// HTML-escape an arbitrary string.
escapeHtml(text) {
return text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
}
getTemplate() {
let templateName;
if (this.getAttribute("template") === undefined) {
templateName = codeInput.defaultTemplate;
} else {
templateName = this.getAttribute("template");
}
if (templateName in codeInput.usedTemplates) {
return codeInput.usedTemplates[templateName];
} else {
// Doesn't exist - add to queue
if (!(templateName in codeInput.templateNotYetRegisteredQueue)) {
codeInput.templateNotYetRegisteredQueue[templateName] = [];
}
codeInput.templateNotYetRegisteredQueue[templateName].push(this);
return undefined;
}
}
/**
* Set up and initialise the textarea.
* This will be called once the template has been added.
*/
setup() {
this.classList.add("code-input_registered"); // Remove register message
if (this.template.preElementStyled)
this.classList.add("code-input_pre-element-styled");
this.pluginEvt("beforeElementsAdded");
// First-time attribute sync
let lang = this.getAttribute("lang");
let placeholder =
this.getAttribute("placeholder") || this.getAttribute("lang") || "";
let value = this.value || this.innerHTML || "";
this.innerHTML = ""; // Clear Content
// Create textarea
let textarea = document.createElement("textarea");
textarea.placeholder = placeholder;
textarea.value = value;
textarea.setAttribute("spellcheck", "false");
// Synchronise attributes to textarea
codeInput.textareaSyncAttributes.forEach(attribute => {
if (this.hasAttribute(attribute)) {
textarea.setAttribute(attribute, this.getAttribute(attribute));
}
});
textarea.addEventListener("input", evt => {
textarea.parentElement.update(textarea.value);
textarea.parentElement.sync_scroll();
});
textarea.addEventListener("scroll", evt =>
textarea.parentElement.sync_scroll(),
);
this.append(textarea);
// Create result element
let code = document.createElement("code");
let pre = document.createElement("pre");
pre.setAttribute("aria-hidden", "true"); // Hide for screen readers
pre.append(code);
this.append(pre);
if (lang != undefined && lang != "") {
code.classList.add("language-" + lang);
}
this.pluginEvt("afterElementsAdded");
this.update(value);
}
/* ------------------------------------
* -----------Callbacks----------------
* ------------------------------------
* Implement the `HTMLElement` callbacks
* to trigger the main functionality properly. */
/**
* When the code-input element has been added to the document,
* find its template and set up the element.
*/
connectedCallback() {
this.template = this.getTemplate();
if (this.template != undefined) this.setup();
}
/**
* Get the HTML attributes that need to be monitored and reported
* to `codeInput.CodeInput.attributeChangedCallback` when modified.
*/
static get observedAttributes() {
return codeInput.observedAttributes.concat(
codeInput.textareaSyncAttributes,
);
}
/**
* Triggered when an HTML attribute in `codeInput.CodeInput.observedAttributes`
* has been modified.
* @param {string} name - The name of the attribute
* @param {string} oldValue - The value of the attribute before it was changed
* @param {string} newValue - The value of the attribute after it is changed
*/
attributeChangedCallback(name, oldValue, newValue) {
if (this.isConnected) {
this.pluginEvt("attributeChanged", [name, oldValue, newValue]);
switch (name) {
case "value":
this.update(newValue);
break;
case "placeholder":
this.querySelector("textarea").placeholder = newValue;
break;
case "template":
this.template =
codeInput.usedTemplates[newValue || codeInput.defaultTemplate];
if (this.template.preElementStyled)
this.classList.add("code-input_pre-element-styled");
else this.classList.remove("code-input_pre-element-styled");
// Syntax Highlight
this.update(this.value);
break;
case "lang":
let code = this.querySelector("pre code");
let mainTextarea = this.querySelector("textarea");
// Check not already updated
if (newValue != null) {
newValue = newValue.toLowerCase();
if (code.classList.contains(`language-${newValue}`)) break; // Already updated
}
// Case insensitive
oldValue = oldValue.toLowerCase();
// Remove old language class and add new
console.log("code-input: Language: REMOVE", "language-" + oldValue);
code.classList.remove("language-" + oldValue); // From CODE
code.parentElement.classList.remove("language-" + oldValue); // From PRE
code.classList.remove("language-none"); // Prism
code.parentElement.classList.remove("language-none"); // Prism
if (newValue != undefined && newValue != "") {
code.classList.add("language-" + newValue);
console.log("code-input: Language:ADD", "language-" + newValue);
}
if (mainTextarea.placeholder === oldValue)
mainTextarea.placeholder = newValue;
this.update(this.value);
break;
default:
if (codeInput.textareaSyncAttributes.includes(name)) {
this.querySelector("textarea").setAttribute(name, newValue);
}
break;
}
}
}
// Override/Implement ordinary HTML textarea functionality so that the <code-input>
// element acts just like a <textarea>.
addEventListener(type, listener, options = undefined) {
let boundCallback = listener.bind(this);
this.boundEventCallbacks[listener] = boundCallback;
if (codeInput.textareaSyncEvents.includes(type)) {
if (options === undefined) {
this.querySelector("textarea").addEventListener(type, boundCallback);
} else {
this.querySelector("textarea").addEventListener(
type,
boundCallback,
options,
);
}
} else {
if (options === undefined) {
super.addEventListener(type, boundCallback);
} else {
super.addEventListener(type, boundCallback, options);
}
}
}
removeEventListener(type, listener, options = null) {
let boundCallback = this.boundEventCallbacks[listener];
if (type === "change") {
if (options === null) {
this.querySelector("textarea").removeEventListener(
"change",
boundCallback,
);
} else {
this.querySelector("textarea").removeEventListener(
"change",
boundCallback,
options,
);
}
} else if (type === "selectionchange") {
if (options === null) {
this.querySelector("textarea").removeEventListener(
"selectionchange",
boundCallback,
);
} else {
this.querySelector("textarea").removeEventListener(
"selectionchange",
boundCallback,
options,
);
}
} else {
super.removeEventListener(type, listener, options);
}
}
get value() {
return this.getAttribute("value");
}
set value(val) {
return this.setAttribute("value", val);
}
get placeholder() {
return this.getAttribute("placeholder");
}
set placeholder(val) {
return this.setAttribute("placeholder", val);
}
get validity() {
return this.querySelector("textarea").validity;
}
get validationMessage() {
return this.querySelector("textarea").validationMessage;
}
setCustomValidity(error) {
return this.querySelector("textarea").setCustomValidity(error);
}
checkValidity() {
return this.querySelector("textarea").checkValidity();
}
reportValidity() {
return this.querySelector("textarea").reportValidity();
}
setAttribute(qualifiedName, value) {
super.setAttribute(qualifiedName, value); // code-input
this.querySelector("textarea").setAttribute(qualifiedName, value); // textarea
}
getAttribute(qualifiedName) {
if (this.querySelector("textarea") === null) {
return super.getAttribute(qualifiedName);
}
return this.querySelector("textarea").getAttribute(qualifiedName); // textarea
}
/**
* Allows plugins to store data in the scope of a single element.
* Key - name of the plugin
* Value - object of data to be stored; different plugins may use this differently.
*/
pluginData = {};
}
customElements.define("code-input", CodeInput);

View File

@ -1,98 +0,0 @@
/**
* Render special characters and control characters as a symbol with their hex code.
* Files: special-chars.js, special-chars.css
*/
/* Main styling */
:root, body { /* Font for hex chars */
--code-input_special-chars_0: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdjZGBgYPj///9/RhCAMcA0bg6yHgAPmh/6BoxTcQAAAABJRU5ErkJgggAA');
--code-input_special-chars_1: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdjZGBgYPj///9/RhAggwMAitIUBr9U6sYAAAAASUVORK5CYII=');
--code-input_special-chars_2: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGCEMUCCjCgyYBFGRrAKFBkAuLYT9kYcIu0AAAAASUVORK5CYII=');
--code-input_special-chars_3: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABhJREFUGFdj/P///38GKGCEMUCCjMTJAACYiBPyG8sfAgAAAABJRU5ErkJggg==');
--code-input_special-chars_4: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///39GRkZGMI3BYYACRhgDrAKZAwAYxhvyz0DRIQAAAABJRU5ErkJggg==');
--code-input_special-chars_5: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACJJREFUGFdj/P///38GKGAEcRgZGRlBfDAHLgNjgFUgywAAuR4T9hxJl2YAAAAASUVORK5CYII=');
--code-input_special-chars_6: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdj/P///38GKGAEcRgZGRlBfDAHQwasAlkGABcdF/Y4yco2AAAAAElFTkSuQmCC');
--code-input_special-chars_7: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABZJREFUGFdj/P///38GKGCEMUCCRHIAWMgT8kue3bQAAAAASUVORK5CYII=');
--code-input_special-chars_8: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GKGAEcRgZGSE0cTIAvHcb8v+mIfAAAAAASUVORK5CYII=');
--code-input_special-chars_9: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB9JREFUGFdj/P///38GKGAEcRgZGSE0igxMCVgGmQMAPqcX8hWL1K0AAAAASUVORK5CYII=');
--code-input_special-chars_A: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAACBJREFUGFdjZGBgYPj///9/RhCAMcA0iADJggCmDEw5ALdxH/aGuYHqAAAAAElFTkSuQmCC');
--code-input_special-chars_B: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABlJREFUGFdj/P///38GBgYGRhAAceA0cTIAvc0b/vRDnVoAAAAASUVORK5CYII=');
--code-input_special-chars_C: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdjZGBgYPj///9/EM0IYjAyMjIS4CDrAQC57hP+uLwvFQAAAABJRU5ErkJggg==');
--code-input_special-chars_D: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABtJREFUGFdj/P///38GBgYGRhAAceA0fg5MDwAveh/6ToN9VwAAAABJRU5ErkJggg==');
--code-input_special-chars_E: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAABxJREFUGFdj/P///38GKGAEcRgZGRlBfDCHsAwA2UwT+mVIH1MAAAAASUVORK5CYII=');
--code-input_special-chars_F: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAAXNSR0IArs4c6QAAAB5JREFUGFdj/P///38GKGAEcRgZGRlBfDAHtwxMGQDZZhP+BnB1kwAAAABJRU5ErkJggg==');
}
.code-input_special-char_container { /* pre element */
font-size: 20px;
}
.code-input_special-char {
display: inline-block;
position: relative;
top: 0;
left: 0;
height: 1em;
/* width: set by JS */
overflow: hidden;
text-decoration: none;
text-shadow: none;
vertical-align: middle;
outline: 0.1px solid currentColor;
--hex-0: var(
--code-input_special-chars_0);
--hex-1: var(
--code-input_special-chars_0);
--hex-2: var(
--code-input_special-chars_0);
--hex-3: var(
--code-input_special-chars_0);
}
/* Default - Two bytes - 4 hex chars */
.code-input_special-char::before {
margin-left: 50%;
transform: translate(-50%, 0);
content: " ";
background-color: var(--code-input_special-char_color, currentColor);
image-rendering: pixelated;
display: inline-block;
width: calc(100%-2px);
height: 100%;
mask-image: var(--hex-0), var(--hex-1), var(--hex-2), var(--hex-3);
mask-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
mask-size: 40%, 40%, 40%, 40%;
mask-position: 10% 10%, 90% 10%, 10% 90%, 90% 90%;
-webkit-mask-image: var(--hex-0), var(--hex-1), var(--hex-2), var(--hex-3);
-webkit-mask-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
-webkit-mask-size: min(40%, 0.25em), min(40%, 0.25em), min(40%, 0.25em), min(40%, 0.25em);
-webkit-mask-position: 10% 10%, min(90%, 0.5em) 10%, 10% 90%, min(90%, 0.5em) 90%;
}
.code-input_special-char_zero-width {
z-index: 1;
width: 1em;
margin-left: -0.5em;
margin-right: -0.5em;
position: relative;
opacity: 0.75;
}
/* One byte - 2 hex chars */
.code-input_special-char_one-byte::before {
height: 1.5em;
top: -1em;
content: attr(data-hex2);
}
.code-input_special-char_one-byte::after {
height: 1.5em;
bottom: -1em;
content: attr(data-hex3);
}

View File

@ -1,219 +0,0 @@
/**
* Render special characters and control characters as a symbol with their hex code.
* Files: special-chars.js, special-chars.css
*/
// INCOMPLETE: TODO Optimise regex - compile at start; Update CSS for character display; clean up + comment
codeInput.plugins.SpecialChars = class extends codeInput.Plugin {
specialCharRegExp;
cachedColors; // ascii number > [background color, text color]
cachedWidths; // font > {character > character width}
canvasContext;
/**
* Create a special characters plugin instance
* @param {Boolean} colorInSpecialChars Whether or not to give special characters custom background colors based on their hex code
* @param {Boolean} inheritTextColor If `colorInSpecialChars` is false, forces the color of the hex code to inherit from syntax highlighting. Otherwise, the base colour of the `pre code` element is used to give contrast to the small characters.
* @param {RegExp} specialCharRegExp The regular expression which matches special characters
*/
constructor(colorInSpecialChars = false, inheritTextColor = false, specialCharRegExp = /(?!\n)(?!\t)[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]|[\u{0200}-\u{FFFF}]/ug) { // By default, covers many non-renderable ASCII characters
super();
this.specialCharRegExp = specialCharRegExp;
this.colorInSpecialChars = colorInSpecialChars;
this.inheritTextColor = inheritTextColor;
this.cachedColors = {};
this.cachedWidths = {};
let canvas = document.createElement("canvas");
this.canvasContext = canvas.getContext("2d");
}
/* Runs before elements are added into a `code-input`; Params: codeInput element) */
beforeElementsAdded(codeInput) {
codeInput.classList.add("code-input_special-char_container");
}
/* Runs after elements are added into a `code-input` (useful for adding events to the textarea); Params: codeInput element) */
afterElementsAdded(codeInput) {
// For some reason, special chars aren't synced the first time - TODO is there a cleaner way to do this?
setTimeout(() => { codeInput.update(codeInput.value); }, 100);
}
/* Runs after code is highlighted; Params: codeInput element) */
afterHighlight(codeInput) {
let result_element = codeInput.querySelector("pre code");
// Reset data each highlight so can change if font size, etc. changes
codeInput.pluginData.specialChars = {};
codeInput.pluginData.specialChars.textarea = codeInput.getElementsByTagName("textarea")[0];
codeInput.pluginData.specialChars.contrastColor = window.getComputedStyle(result_element).color;
this.recursivelyReplaceText(codeInput, result_element);
this.lastFont = window.getComputedStyle(codeInput.pluginData.specialChars.textarea).font;
}
recursivelyReplaceText(codeInput, element) {
for(let i = 0; i < element.childNodes.length; i++) {
let nextNode = element.childNodes[i];
if(nextNode.nodeName == "#text" && nextNode.nodeValue != "") {
// Replace in here
let oldValue = nextNode.nodeValue;
this.specialCharRegExp.lastIndex = 0;
let searchResult = this.specialCharRegExp.exec(oldValue);
if(searchResult != null) {
let charIndex = searchResult.index; // Start as returns end
nextNode = nextNode.splitText(charIndex+1).previousSibling;
if(charIndex > 0) {
nextNode = nextNode.splitText(charIndex); // Keep those before in difft. span
}
if(nextNode.textContent != "") {
let replacementElement = this.specialCharReplacer(codeInput, nextNode.textContent);
nextNode.parentNode.insertBefore(replacementElement, nextNode);
nextNode.textContent = "";
}
}
} else if(nextNode.nodeType == 1) {
if(nextNode.className != "code-input_special-char" && nextNode.nodeValue != "") {
// Element - recurse
this.recursivelyReplaceText(codeInput, nextNode);
}
}
}
}
specialCharReplacer(codeInput, match_char) {
let hex_code = match_char.codePointAt(0);
let colors;
if(this.colorInSpecialChars) colors = this.getCharacterColor(hex_code);
hex_code = hex_code.toString(16);
hex_code = ("0000" + hex_code).substring(hex_code.length); // So 2 chars with leading 0
hex_code = hex_code.toUpperCase();
let char_width = this.getCharacterWidth(codeInput, match_char);
// Create element with hex code
let result = document.createElement("span");
result.classList.add("code-input_special-char");
result.style.setProperty("--hex-0", "var(--code-input_special-chars_" + hex_code[0] + ")");
result.style.setProperty("--hex-1", "var(--code-input_special-chars_" + hex_code[1] + ")");
result.style.setProperty("--hex-2", "var(--code-input_special-chars_" + hex_code[2] + ")");
result.style.setProperty("--hex-3", "var(--code-input_special-chars_" + hex_code[3] + ")");
// Handle zero-width chars
if(char_width == 0) result.classList.add("code-input_special-char_zero-width");
else result.style.width = char_width + "px";
if(this.colorInSpecialChars) {
result.style.backgroundColor = "#" + colors[0];
result.style.setProperty("--code-input_special-char_color", colors[1]);
} else if(!this.inheritTextColor) {
result.style.setProperty("--code-input_special-char_color", codeInput.pluginData.specialChars.contrastColor);
}
return result;
}
getCharacterColor(ascii_code) {
// Choose colors based on character code - lazy load and return [background color, text color]
let background_color;
let text_color;
if(!(ascii_code in this.cachedColors)) {
// Get background color - arbitrary bit manipulation to get a good range of colours
background_color = ascii_code^(ascii_code << 3)^(ascii_code << 7)^(ascii_code << 14)^(ascii_code << 16); // Arbitrary
background_color = background_color^0x1fc627; // Arbitrary
background_color = background_color.toString(16);
background_color = ("000000" + background_color).substring(background_color.length); // So 6 chars with leading 0
// Get most suitable text color - white or black depending on background brightness
let color_brightness = 0;
let luminance_coefficients = [0.299, 0.587, 0.114];
for(let i = 0; i < 6; i += 2) {
color_brightness += parseInt(background_color.substring(i, i+2), 16) * luminance_coefficients[i/2];
}
// Calculate darkness
text_color = color_brightness < 128 ? "white" : "black";
// console.log(background_color, color_brightness, text_color);
this.cachedColors[ascii_code] = [background_color, text_color];
return [background_color, text_color];
} else {
return this.cachedColors[ascii_code];
}
}
getCharacterWidth(codeInput, char) { // TODO: Check StackOverflow question
// Force zero-width characters
if(new RegExp("\u00AD|\u02de|[\u0300-\u036F]|[\u0483-\u0489]|\u200b").test(char) ) { return 0 }
// Non-renderable ASCII characters should all be rendered at same size
if(char != "\u0096" && new RegExp("[\u{0000}-\u{001F}]|[\u{007F}-\u{009F}]", "g").test(char)) {
let fallbackWidth = this.getCharacterWidth("\u0096");
return fallbackWidth;
}
let font = window.getComputedStyle(codeInput.pluginData.specialChars.textarea).font;
// Lazy-load - TODO: Get a cleaner way of doing this
if(this.cachedWidths[font] == undefined) {
this.cachedWidths[font] = {}; // Create new cached widths for this font
}
if(this.cachedWidths[font][char] != undefined) { // Use cached width
return this.cachedWidths[font][char];
}
// Ensure font the same
// console.log(font);
this.canvasContext.font = font;
// Try to get width from canvas
let width = this.canvasContext.measureText(char).width;
if(width > Number(font.split("px")[0])) {
width /= 2; // Fix double-width-in-canvas Firefox bug
} else if(width == 0 && char != "\u0096") {
let fallbackWidth = this.getCharacterWidth("\u0096");
return fallbackWidth; // In Firefox some control chars don't render, but all control chars are the same width
}
this.cachedWidths[font][char] = width;
// console.log(this.cachedWidths);
return width;
}
// getCharacterWidth(char) { // Doesn't work for now - from StackOverflow suggestion https://stackoverflow.com/a/76146120/21785620
// let textarea = codeInput.pluginData.specialChars.textarea;
// // Create a temporary element to measure the width of the character
// const span = document.createElement('span');
// span.textContent = char;
// // Copy the textarea's font to the temporary element
// span.style.fontSize = window.getComputedStyle(textarea).fontSize;
// span.style.fontFamily = window.getComputedStyle(textarea).fontFamily;
// span.style.fontWeight = window.getComputedStyle(textarea).fontWeight;
// span.style.visibility = 'hidden';
// span.style.position = 'absolute';
// // Add the temporary element to the document so we can measure its width
// document.body.appendChild(span);
// // Get the width of the character in pixels
// const width = span.offsetWidth;
// // Remove the temporary element from the document
// document.body.removeChild(span);
// return width;
// }
}

View File

@ -63,8 +63,7 @@ button, input {font-size:100%}
#controls :not(.text) {height:1.8rem; box-sizing:border-box; margin:0}
#controls button {width:1.8rem; padding:0; display:inline-block}
#controls :is(button, input, select) {
border-radius:0}
#controls :is(button, input, select) {border-radius:0}
#controls :is(button:first-child, input:first-child, select:first-child, .control-round-left) {
border-top-left-radius:var(--control-radius);
border-bottom-left-radius:var(--control-radius)}