├── project ├── build.properties ├── plugins.sbt └── metals.sbt ├── main.js ├── style.css ├── .scalafmt.conf ├── vite.config.mjs ├── .gitignore ├── src ├── test │ └── scala │ │ └── vistyp │ │ └── Vistyp.scala └── main │ └── scala │ └── vistyp │ ├── Monaco.scala │ ├── Utils.scala │ ├── Syntax.scala │ ├── TypstInstrument.scala │ ├── Typst.scala │ ├── TypstSemanticHighlight.scala │ ├── Parser.scala │ ├── UI.scala │ └── Vistyp.scala ├── package.json ├── index.html ├── README.md ├── typst-style.css ├── favicon.svg ├── yarn.lock └── assets └── tokyo-night.json /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.6 2 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import './style.css' 2 | import 'scalajs:main.js' -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | height: 100vh; 3 | overflow: hidden; 4 | } 5 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") 2 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = "3.7.15" 2 | runner.dialect = scala3 3 | rewrite.trailingCommas.style = "always" -------------------------------------------------------------------------------- /project/metals.sbt: -------------------------------------------------------------------------------- 1 | // format: off 2 | // DO NOT EDIT! This file is auto-generated. 3 | 4 | // This file enables sbt-bloop to create bloop config files. 5 | 6 | addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "2.0.6") 7 | 8 | // format: on 9 | -------------------------------------------------------------------------------- /vite.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { viteSingleFile } from 'vite-plugin-singlefile'; 3 | import scalaJSPlugin from "@scala-js/vite-plugin-scalajs"; 4 | 5 | export default defineConfig({ 6 | plugins: [scalaJSPlugin(), viteSingleFile()], 7 | build: { 8 | outDir: 'out', 9 | minify: false, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | null 12 | dist 13 | dist-ssr 14 | *.local 15 | /PowerShell * 16 | /target 17 | /project/target 18 | /project/project 19 | 20 | .bloop 21 | .bsp 22 | .metals 23 | 24 | # Editor directories and files 25 | .vscode/* 26 | !.vscode/extensions.json 27 | !.vscode/tasks.json 28 | .idea 29 | .DS_Store 30 | *.suo 31 | *.ntvs* 32 | *.njsproj 33 | *.sln 34 | *.sw? 35 | -------------------------------------------------------------------------------- /src/test/scala/vistyp/Vistyp.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | trait Monoid[A]: 4 | def combine(x: A, y: A): A 5 | def empty: A 6 | 7 | object Monoid: 8 | def apply[A](using monoid: Monoid[A]): Monoid[A] = monoid 9 | 10 | given Monoid[Int] with 11 | def combine(x: Int, y: Int): Int = x + y 12 | def empty: Int = 0 13 | 14 | def sum[A: Monoid](xs: List[A]): A = 15 | xs.foldLeft(Monoid[A].empty)(Monoid[A].combine) 16 | 17 | def testSum(): Unit = 18 | val result = sum(List(1, 2, 3)) 19 | assert(result == 6) 20 | 21 | class MonoidTest extends munit.FunSuite: 22 | test("sum") { 23 | testSum() 24 | } 25 | end MonoidTest 26 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Monaco.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation._ 5 | 6 | import com.raquo.laminar.api.L.{*, given} 7 | 8 | @js.native 9 | trait Monaco extends js.Object { 10 | def editor: MonacoEditor = js.native 11 | } 12 | 13 | @js.native 14 | trait MonacoEditor extends js.Object { 15 | def create(element: js.Object, options: js.Object): MonacoEditor = js.native 16 | def getValue(): String = js.native 17 | def setValue(value: String): Unit = js.native 18 | def getModel(): MonacoModel = js.native 19 | } 20 | 21 | @js.native 22 | trait MonacoModel extends js.Object { 23 | def onDidChangeContent( 24 | callback: js.Function1[MonacoModelContentChange, Unit], 25 | ): MonacoModel = js.native 26 | } 27 | 28 | @js.native 29 | trait MonacoModelContentChange extends js.Object { 30 | def isFlush: Boolean = js.native 31 | } 32 | 33 | val monacoLoadVar: Var[Option[Monaco]] = Var(None) 34 | val monacoLoadSignal = monacoLoadVar.signal 35 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Utils.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | private val escapeStrPattern = "((?:\\r\\n)|[\"\\\\\\t\\f\\r\\n])".r 4 | def escapeStr(s: String): String = { 5 | escapeStrPattern.replaceAllIn( 6 | s, 7 | (m) => { 8 | m.group(1) match { 9 | case "\"" => "\\\\\"" 10 | case "\\" => "\\\\\\\\" 11 | case "\n" => "\\\\n" 12 | case "\t" => "\\\\t" 13 | case "\r" => "\\\\r" 14 | case "\f" => "\\\\f" 15 | case "\r\n" => "\\\\n" 16 | case other => "\\" + other 17 | } 18 | }, 19 | ) 20 | } 21 | 22 | private val unescapeStrPattern = "(\\\\[\\\\tfrn\\\"])".r 23 | def unescapeStr(s: String): String = { 24 | unescapeStrPattern.replaceAllIn( 25 | s, 26 | (m) => { 27 | m.group(1) match { 28 | case "\\\"" => "\"" 29 | case "\\\\" => "\\" 30 | case "\\n" => "\n" 31 | case "\\t" => "\t" 32 | case "\\r" => "\r" 33 | case "\\f" => "\f" 34 | case other => other 35 | } 36 | }, 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@myriaddreamin/vistyp", 3 | "private": true, 4 | "version": "0.5.4", 5 | "description": "Simple visualized editor", 6 | "author": "Myriad Dreamin ", 7 | "license": "Apache-2.0", 8 | "keywords": [ 9 | "typst", 10 | "renderer" 11 | ], 12 | "repository": "https://github.com/Myriad-Dreamin/vistyp", 13 | "main": "dist/index.mjs", 14 | "files": [ 15 | "dist/index.mjs" 16 | ], 17 | "dependencies": { 18 | "@myriaddreamin/typst.ts": "0.5.4", 19 | "@myriaddreamin/typst-ts-renderer": "0.5.4", 20 | "@myriaddreamin/typst-ts-web-compiler": "0.5.4" 21 | }, 22 | "devDependencies": { 23 | "@scala-js/vite-plugin-scalajs": "^1.0.0", 24 | "vite": "^6.0.6", 25 | "vite-plugin-singlefile": "^2.1.0", 26 | "vitest": "^2.1.8", 27 | "@types/web": "^0.0.188" 28 | }, 29 | "scripts": { 30 | "dev": "vite", 31 | "build": "vite build", 32 | "preview": "vite preview", 33 | "test": "vitest", 34 | "coverage": "vitest run --coverage", 35 | "publish:dry": "npm publish --dry-run", 36 | "publish:lib": "npm publish || exit 0" 37 | }, 38 | "engines": { 39 | "node": ">=12" 40 | } 41 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vistyp Editor 8 | 9 | 10 | 13 | 14 | 15 |
16 | 17 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vistyp 2 | 3 | This is a sample project to exhibit how to develop along with/without a local built typst.ts. It was named "Cetz Editor". 4 | 5 | ### Debug the Vistyp 6 | 7 | Run the vite dev server to get hot-reloading functionality: 8 | 9 | ```bash 10 | # watch scala 11 | $ sbt "~fastLinkJS" 12 | # start a vite dev server 13 | $ yarn run dev 14 | # open the browser 15 | $ open http://localhost:5173 16 | ``` 17 | 18 | ### Build the Vistyp 19 | 20 | The Vistyp is bundled into a single html file, so you can open it directly in the browser: 21 | 22 | ```bash 23 | # bundle files 24 | $ yarn run build 25 | # open the browser 26 | $ open out/index.html 27 | ``` 28 | 29 | ### Setup the wasm modules 30 | 31 | There are three ways to run the sample project (Also see the [`src/index.mts`](./src/index.mts) file). 32 | 33 | 1. Use the wasm modules from CDN (default): 34 | 35 | - ensure that the `projects/cetz-editor` is cloned individually (not in the source tree of `typst.ts`) 36 | ```bash 37 | git clone https://github.com/Myriad-Dreamin/cetz-editor.git 38 | ``` 39 | - ensure that you can connect to jsdelivr.net 40 | - change `window.$typst$moduleSource` manually in the [`src/index.mts`](./src/index.mts) file: 41 | 42 | ```ts 43 | let moduleSource: ModuleSource = "jsdelivr"; 44 | ``` 45 | 46 | 2. Bundle the wasm modules via vite: 47 | 48 | ```ts 49 | // @ts-ignore 50 | import compiler from "@myriaddreamin/typst-ts-web-compiler/pkg/typst_ts_web_compiler_bg.wasm?url"; 51 | // @ts-ignore 52 | import renderer from "@myriaddreamin/typst-ts-renderer/pkg/typst_ts_renderer_bg.wasm?url"; 53 | ``` 54 | 55 | 3. Serve the wasm modules locally via `typst-ts-dev-server` (See [Setup the typst.ts in local](#setup-the-typstts-in-local)): 56 | 57 | - runs `yarn dev` in the `typst.ts` project to start a local server 58 | - change `window.$typst$moduleSource` manually in the [`src/index.mts`](./src/index.mts) file: 59 | 60 | ```ts 61 | window.$typst$moduleSource = "local"; 62 | ``` 63 | 64 | ### Align the version of the wasm modules with the version of the typst.ts package 65 | 66 | Note that you should align the versions: 67 | 68 | ```json 69 | { 70 | "peerDependencies": { 71 | "@myriaddreamin/typst.ts": "0.5.4", 72 | "@myriaddreamin/typst-ts-renderer": "0.5.4", 73 | "@myriaddreamin/typst-ts-web-compiler": "0.5.4" 74 | } 75 | } 76 | ``` 77 | 78 | Otherwise you will get an error like this: 79 | 80 | ```log 81 | Uncaught (in promise) LinkError: WebAssembly.instantiate(): Import #73 module="wbg" function="__wbindgen_closure_wrapper16065": function import requires a callabl 82 | ``` 83 | 84 | Or this: 85 | 86 | ```log 87 | panicked at `called Result::unwrap()` on an `Err` value: CheckBytesError(...) 88 | ``` 89 | 90 | ### Build and provide the wasm modules in local 91 | 92 | Build the typst.ts project and start a local server: 93 | 94 | ```bash 95 | # Optional: download the font assets if you haven't done so. 96 | $ git submodule update --init --recursive . 97 | # build all of typescript packages 98 | $ yarn install && yarn run build:pkg 99 | # compile typst document for demo 100 | $ cargo run --bin typst-ts-dev-server -- compile --compiler debug corpus --cat skyzh-cv 101 | # start a local server 102 | $ cargo run --bin typst-ts-dev-server -- run http --corpus ./fuzzers/corpora/ 103 | ``` 104 | 105 | ### Caution 106 | 107 | This is a quick and dirty project, so you may face some problems when you try to run it. Please feel free to open an [issue](https://github.com/Myriad-Dreamin/typst.ts/issues) or a [discussion](https://github.com/Myriad-Dreamin/typst.ts/discussions) if you have any questions. 108 | 109 | Also feel free to open a [issue](https://github.com/Myriad-Dreamin/cetz-editor/pulls) to help us improve this sample project. 110 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Syntax.scala: -------------------------------------------------------------------------------- 1 | package vistyp.syntax 2 | 3 | import vistyp.escapeStr 4 | 5 | import fastparse._ 6 | 7 | private type N = Ident 8 | private type Str = String 9 | private type Pol = Option[List[Param]] 10 | private[vistyp] type No = Option[Node] 11 | type TmplExp = Option[(Node, Option[String])] 12 | 13 | sealed abstract class Node { 14 | var offset: Int = -1; 15 | var end: Int = -1; 16 | 17 | def repr: String = { 18 | this match { 19 | case KeyedArg(key, value) => s"${key.repr}: ${value.repr}" 20 | case Ident(name) => name 21 | case StrLit(value) => s""""${escapeStr(value)}"""" 22 | case IntLit(value) => value.toString 23 | case FloatLit(value) => value.toString 24 | } 25 | } 26 | } 27 | 28 | object NodeParse { 29 | implicit class Mapper[T <: Node](n: => P[T])(implicit ctx: P[_]) { 30 | def m = { 31 | val l = ctx.index; 32 | val r = n.map(node => { node.offset = l; node.end = ctx.index; node }); 33 | ctx.asInstanceOf[P[T]] 34 | } 35 | } 36 | } 37 | 38 | // Kind: Decorators 39 | // A node that is terminated by a semicolon 40 | final case class Semi(semi: No) extends Node 41 | // A node that is decorated by another node 42 | final case class Decorate(lhs: Node, rhs: Node) extends Node 43 | 44 | // Kind: Literals 45 | final case class Err(msg: String) extends Node 46 | // Just panic on problematic impls 47 | object TodoLit extends Node 48 | // Identifier 49 | final case class Ident(name: Str) extends Node 50 | // Boolean Literal 51 | final case class BoolLit(value: Boolean) extends Node 52 | // None Literal 53 | case object NoneLit extends Node 54 | // auto Literal 55 | case object AutoLit extends Node 56 | // Integer Literal 57 | final case class IntLit(value: BigInt) extends Node 58 | // Float Literal 59 | final case class FloatLit(value: BigDecimal) extends Node 60 | final case class LengthLit(value: IntLit | FloatLit, unit: Str) extends Node 61 | final case class MarkupContent(value: Str) extends Node 62 | final case class RawContent(value: Str) extends Node 63 | final case class StrLit(value: Str) extends Node 64 | final case class LabelLit(value: Str) extends Node 65 | final case class EscapeLit(value: Str) extends Node 66 | // todo: Param Literal, remove me 67 | final case class ParamsLit(values: List[Param]) extends Node 68 | // Argument Literal (Named and Nameless Tuples) 69 | final case class ArgsLit(values: List[Node]) extends Node 70 | 71 | // Kind: Blocks 72 | // A block of statements 73 | final case class MarkupBlock(stmts: List[Node]) extends Node 74 | final case class MathBlock(stmts: List[Node]) extends Node 75 | final case class Block(stmts: List[Node]) extends Node 76 | // Kind: Var Decls 77 | // constant level-0 variable 78 | final case class LetBinding(name: N, param: Option[List[Node]], init: Node) 79 | extends Node 80 | final case class Param(name: N, init: No) extends Node 81 | final case class Apply(lhs: Node, rhs: List[Node]) extends Node 82 | final case class SetItem(rule: Node, cond: No) extends Node 83 | final case class Show(selector: No, transform: No) extends Node 84 | final case class Import(path: Node, new_name: No, items: Option[List[Node]]) 85 | extends Node 86 | final case class IncludeItem(path: Node) extends Node 87 | // Kind: Control Flow 88 | final case class While(cond: Node, body: Node) extends Node 89 | final case class For(name: N, iter: Node, body: Node) extends Node 90 | final case class If(cond: Node, cont_bb: Node, else_bb: No) extends Node 91 | final case class Break() extends Node 92 | final case class Continue() extends Node 93 | final case class Return(value: Node) extends Node 94 | // Kind: Expressions 95 | final case class UnOp(op: Str, lhs: Node) extends Node 96 | final case class BinOp(op: Str, lhs: Node, rhs: Node) extends Node 97 | final case class Select(lhs: Node, rhs: Ident) extends Node 98 | final case class Lambda(lhs: Node, rhs: Node) extends Node 99 | final case class KeyedArg(key: Node, value: Node) extends Node 100 | // Kind: Clauses 101 | -------------------------------------------------------------------------------- /typst-style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: Inter; 3 | src: local('Inter'), 4 | url('https://interactive-examples.mdn.mozilla.net/media/fonts/Inter.var.woff2'); 5 | } 6 | 7 | body { 8 | margin: 0; 9 | padding: 0; 10 | background-color: #1a1b26; 11 | color: rgba(156, 163, 175, 1); 12 | font-family: BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 13 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 14 | } 15 | 16 | .flex-row { 17 | display: flex; 18 | flex-direction: row; 19 | } 20 | 21 | .flex-column { 22 | display: flex; 23 | flex-direction: column; 24 | } 25 | 26 | .preview { 27 | display: flex; 28 | flex-direction: column; 29 | } 30 | 31 | .preview-panel { 32 | padding: 20px; 33 | min-height: 100%; 34 | background-color: white; 35 | overflow: scroll; 36 | } 37 | .typst-cetz-elem { 38 | /* pointer-events: bounding-box; */ 39 | pointer-events: all; 40 | } 41 | 42 | #svg-edit-menu { 43 | position: absolute; 44 | 45 | /* Reset */ 46 | list-style-type: none; 47 | margin: 0; 48 | padding: 0; 49 | 50 | /* Misc */ 51 | border: 1px solid #cbd5e0; 52 | border-radius: 0.25rem; 53 | background-color: #f7fafc; 54 | } 55 | 56 | .editor-menu { 57 | padding: 0 0.61rem; 58 | font-family: BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 59 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 60 | border: 0px solid #cbd5e0; 61 | border-radius: 0.25rem; 62 | transition: background-color 0.2s; 63 | } 64 | 65 | .editor-menu:hover { 66 | cursor: pointer; 67 | /* border rect */ 68 | background-color: hsla(0, 0%, 100%, 0.15); 69 | } 70 | 71 | .hidden { 72 | /* The menu is hidden at first */ 73 | display: none; 74 | } 75 | 76 | .menu-item { 77 | white-space: nowrap; 78 | } 79 | 80 | .menu-item span { 81 | float: left; 82 | } 83 | 84 | .menu-item input { 85 | float: right; 86 | } 87 | 88 | .editor-action-group, 89 | .editor-menu-group { 90 | display: inline-block; 91 | border-width: 1px; 92 | border-radius: 8px; 93 | border: 1px solid #333; 94 | padding: 3px; 95 | } 96 | 97 | #insert-name { 98 | max-width: 80px; 99 | } 100 | 101 | .editor-code-select { 102 | appearance: none; 103 | /* safari */ 104 | -webkit-appearance: none; 105 | /* other styles for aesthetics */ 106 | width: 6.5em; 107 | background-color: hsla(0, 0%, 100%, 0.1); 108 | 109 | transition: color 0.3s; 110 | } 111 | .editor-code-select:focus, 112 | .editor-code-select:focus-visible { 113 | outline: none; 114 | } 115 | 116 | .editor-code-select:hover, 117 | .editor-code-select:focus, 118 | .editor-code-select:focus-visible { 119 | color: #fff; 120 | } 121 | 122 | .editor-code-select, 123 | .editor-code-select option { 124 | text-overflow: ellipsis; 125 | padding: 0.125rem 0.25em; 126 | font-size: 1rem; 127 | border: 1px solid hsla(0, 0%, 100%, 0.1); 128 | border-radius: 0.25rem; 129 | color: #888; 130 | cursor: pointer; 131 | font-size: 0.9em; 132 | font-family: 133 | ui-monospace, 134 | SFMono-Regular, 135 | Menlo, 136 | Monaco, 137 | Consolas, 138 | Liberation Mono, 139 | Courier New, 140 | monospace; 141 | } 142 | 143 | .editor-code-select option { 144 | background-color: #1a1b26; 145 | } 146 | 147 | .editor-input-box { 148 | background-color: #1a1b26; 149 | border: 1px solid hsla(0, 0%, 100%, 0.1); 150 | border-radius: 0.25rem; 151 | transition: border-color 0.2s; 152 | color: #e5e5e5; 153 | font-family: 154 | ui-monospace, 155 | SFMono-Regular, 156 | Menlo, 157 | Monaco, 158 | Consolas, 159 | Liberation Mono, 160 | Courier New, 161 | monospace; 162 | } 163 | 164 | .editor-input-box:focus, 165 | .editor-input-box:focus-visible { 166 | outline: none; 167 | border-color: hsla(0, 0%, 100%, 0.5); 168 | } 169 | 170 | .editor-input-button { 171 | background-color: #1a1b26; 172 | border-radius: 0.25rem; 173 | border: 1px solid #a3a3a3; 174 | color: #e5e5e5; 175 | transition: border-color 0.3s; 176 | font-weight: 500; 177 | font-family: Inter, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 178 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 179 | } 180 | 181 | .editor-input-button:hover { 182 | border-color: #e5e5e5; 183 | } 184 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/TypstInstrument.scala: -------------------------------------------------------------------------------- 1 | package vistyp.instrument 2 | 3 | import org.scalajs.dom 4 | import org.scalajs.dom.{Element, SVGElement, HTMLCollection} 5 | import scala.collection.mutable.{ArrayBuffer, Map => MutableMap} 6 | 7 | object TypstSvgInstrument: 8 | 9 | end TypstSvgInstrument 10 | 11 | def processSvg(svg: SVGElement, tagMapping: Map[String, String]): SVGElement = { 12 | InstrumentWorker(tagMapping).work(svg).asInstanceOf[SVGElement] 13 | } 14 | 15 | private class InstrumentWorker(tagMapping: Map[String, String]) { 16 | 17 | def work(svg: Element): Element = { 18 | workChildren(svg, svg.children) 19 | } 20 | 21 | def workChildren( 22 | parent: Element, 23 | children: HTMLCollection[Element], 24 | ): Element = { 25 | 26 | var elementStack = List[(String, ArrayBuffer[Element])]() 27 | var results = ArrayBuffer[Element]() 28 | results.sizeHint(children.length) 29 | 30 | def pushTag(tag: String) = { 31 | val newResults = ArrayBuffer[Element]() 32 | elementStack = (tag, results) :: elementStack 33 | results = newResults 34 | } 35 | 36 | def popTag(tag: String, lastResults: ArrayBuffer[Element]) = { 37 | val newElement = dom.document.createElementNS( 38 | "http://www.w3.org/2000/svg", 39 | "g", 40 | ) 41 | newElement.setAttribute("data-element-id", s"cetz-app-${tag}") 42 | newElement.setAttribute("class", "typst-cetz-elem") 43 | newElement.append(results.toArray: _*) 44 | 45 | lastResults += newElement 46 | results = lastResults 47 | } 48 | 49 | // println(s"Check Tags ${children.map(identifyElement).toList}") 50 | for (child <- children.toArray) { 51 | identifyElement(child) match { 52 | case RawTypstElem.Just(elem) => 53 | results += work(elem) 54 | case RawTypstElem.Empty(elem) => 55 | results += elem 56 | case RawTypstElem.Tag(tag) => 57 | // println(s"Check Tag ${tag} ${elementStack}") 58 | elementStack match { 59 | case Nil => pushTag(tag) 60 | case (lastTag, lastResults) :: tail => 61 | if (lastTag == tag) { 62 | elementStack = tail 63 | popTag(tag, lastResults) 64 | } else { 65 | pushTag(tag) 66 | } 67 | } 68 | } 69 | } 70 | 71 | elementStack.foreach { case (tag, lastResults) => 72 | popTag(tag, lastResults) 73 | } 74 | 75 | parent.replaceChildren(results.toArray: _*) 76 | parent 77 | } 78 | 79 | val elements = MutableMap[Element, RawTypstElem]() 80 | 81 | /// Identify the element and return the tag 82 | /// Rule: 83 | /// 1. If the element is an empty group or all its children are "Empty", then it is "Empty" 84 | /// 2. If the element's children is either "Empty" or "Tag", then it is the only "Tag". 85 | /// 3. The rest is "Just" 86 | def identifyElement(elem: Element): RawTypstElem = { 87 | elements.getOrElse(elem, doIdentifyElement(elem)) 88 | } 89 | 90 | def doIdentifyElement(elem: Element): RawTypstElem = { 91 | // println(s"Identifying SVG ${elem} ${elem.attributes.toMap.toString()}") 92 | val strokeWidth = elem.getAttribute("stroke-width") 93 | val isInstrumentTag = 94 | strokeWidth != null && strokeWidth.toFloatOption.exists(strokeWidth => 95 | (strokeWidth - 0.00012345).abs < 1e-8, 96 | ) 97 | if (isInstrumentTag) { 98 | val stroke = elem.getAttribute("stroke") 99 | val tag = tagMapping.get(stroke) 100 | return tag match { 101 | case Some(tag) => RawTypstElem.Tag(tag) 102 | case None => RawTypstElem.Empty(elem) 103 | } 104 | } 105 | 106 | elem.tagName match { 107 | case "g" => 108 | val children = elem.children 109 | if (children.length == 0) { 110 | return RawTypstElem.Empty(elem) 111 | } 112 | val tag = children 113 | .map(identifyElement) 114 | .reduceOption((a, b) => 115 | import RawTypstElem.* 116 | (a, b) match { 117 | case (Tag(tag), Empty(_)) => Tag(tag) 118 | case (Empty(_), Tag(tag)) => Tag(tag) 119 | case (Tag(_), Tag(_)) => Just(elem) 120 | case (Just(elem), _) => Just(elem) 121 | case (_, Just(elem)) => Just(elem) 122 | case _ => b 123 | }, 124 | ) 125 | tag match { 126 | case Some(RawTypstElem.Tag(tag)) => return RawTypstElem.Tag(tag) 127 | case Some(RawTypstElem.Empty(_)) => return RawTypstElem.Empty(elem) 128 | case Some(RawTypstElem.Just(_)) | None => 129 | } 130 | case _ => 131 | } 132 | 133 | RawTypstElem.Just(elem) 134 | } 135 | } 136 | 137 | enum RawTypstElem { 138 | case Empty(elem: Element) 139 | case Just(elem: Element) 140 | case Tag(tag: String) 141 | } 142 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Typst.scala: -------------------------------------------------------------------------------- 1 | package vistyp.binding 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation._ 5 | 6 | import org.scalajs.dom 7 | 8 | @js.native 9 | @JSImport("@myriaddreamin/typst.ts/dist/esm/contrib/snippet.mjs", "$typst") 10 | private object TypstTs extends js.Object { 11 | 12 | def setCompilerInitOptions(options: js.Object): Unit = js.native 13 | def setRendererInitOptions(options: js.Object): Unit = js.native 14 | 15 | def addSource(path: String, content: String): js.Promise[Unit] = js.native 16 | 17 | def svg(options: js.Object): js.Promise[String] = js.native 18 | 19 | def getSemanticTokenLegend(): js.Promise[js.Object] = js.native 20 | def getSemanticTokens(options: js.Object): js.Promise[js.Any] = js.native 21 | } 22 | 23 | object Typst: 24 | export TypstTs.* 25 | 26 | // /// Begin of Retrieve Wasm Modules from somewhere 27 | // /// We need a compiler module and a renderer module 28 | // /// - `@myriaddreamin/typst-ts-web-compiler` 29 | // /// - `@myriaddreamin/typst-ts-renderer` 30 | def configureWasm() = { 31 | dom.console.log("TypstTs", TypstTs) 32 | 33 | // Bundle 34 | // @ts-ignore 35 | // import compiler from '@myriaddreamin/typst-ts-web-compiler/pkg/typst_ts_web_compiler_bg.wasm?url'; 36 | // @ts-ignore 37 | // import renderer from '@myriaddreamin/typst-ts-renderer/pkg/typst_ts_renderer_bg.wasm?url'; 38 | 39 | // type ModuleSource = 'local' | 'jsdelivr'; 40 | val moduleSource: String = dom.window 41 | .asInstanceOf[js.Dynamic] 42 | .$typst$moduleSource 43 | .asInstanceOf[js.UndefOr[String]] 44 | .getOrElse("jsdelivr") 45 | 46 | var compiler: js.Dynamic = js.Dynamic.literal() 47 | var renderer: js.Dynamic = js.Dynamic.literal() 48 | 49 | def fetch(url: String): js.Dynamic = { 50 | dom.window.asInstanceOf[js.Dynamic].fetch(url) 51 | } 52 | 53 | dom.console.log("moduleSource", moduleSource) 54 | moduleSource match { 55 | case "jsdelivr" => 56 | compiler = fetch( 57 | "https://cdn.jsdelivr.net/npm/@myriaddreamin/typst-ts-web-compiler@0.5.4/pkg/typst_ts_web_compiler_bg.wasm", 58 | ) 59 | renderer = fetch( 60 | "https://cdn.jsdelivr.net/npm/@myriaddreamin/typst-ts-renderer@0.5.4/pkg/typst_ts_renderer_bg.wasm", 61 | ) 62 | case "local" => 63 | compiler = fetch( 64 | "http://127.0.0.1:20810/base/node_modules/@myriaddreamin/typst-ts-web-compiler/pkg/typst_ts_web_compiler_bg.wasm", 65 | ); 66 | renderer = fetch( 67 | "http://127.0.0.1:20810/base/node_modules/@myriaddreamin/typst-ts-renderer/pkg/typst_ts_renderer_bg.wasm", 68 | ); 69 | case _ => 70 | dom.console.warn("unknown module source for importing typst module") 71 | } 72 | 73 | Typst.setCompilerInitOptions( 74 | js.Dynamic.literal( 75 | getModule = () => 76 | compiler || dom.window.asInstanceOf[js.Dynamic].$wasm$typst_compiler, 77 | ), 78 | ) 79 | 80 | Typst.setRendererInitOptions( 81 | js.Dynamic.literal( 82 | getModule = () => 83 | renderer || dom.window.asInstanceOf[js.Dynamic].$wasm$typst_renderer, 84 | ), 85 | ) 86 | } 87 | 88 | def previewSvg(mainContent: String): js.Promise[String] = { 89 | addSource("/preview.typ", mainContent) 90 | .`then`(_ => svg(js.Dynamic.literal(mainFilePath = "/preview.typ"))) 91 | .asInstanceOf[js.Promise[String]] 92 | } 93 | // await $typst.addSource('/preview.typ', mainContent); 94 | // return $typst.svg({ mainFilePath: '/preview.typ' }); 95 | 96 | // const insertSelector = document.getElementById('insert-selector'); 97 | // const insertName = document.getElementById('insert-name'); 98 | // const previewSelector = document.getElementById('preview-selector'); 99 | // const definitionSourceSelector = document.getElementById('definition-source-selector'); 100 | // const definitionSourceValue = document.getElementById('definition-source-value'); 101 | // const definitionSourceConfirm = document.getElementById('definition-source-confirm'); 102 | // const inputSvgWidth = document.getElementById('input-svg-width'); 103 | // const inputSvgHeight = document.getElementById('input-svg-height'); 104 | // inputSvgWidth.value = inputSvgHeight.value = '600'; 105 | 106 | // const checkLength = (v) => { 107 | // if (v.endsWith('pt')) { 108 | // v = v.substring(0, t.length - 2); 109 | // } 110 | // if (!v) { 111 | // v = '600'; 112 | // } 113 | 114 | // const t = Number.parseFloat(v); 115 | // if (Number.isNaN(t)) { 116 | // throw new Error('invalid number'); 117 | // } 118 | 119 | // return `${t}pt`; 120 | // }; 121 | 122 | // const triggerSyncEditorState = () => { 123 | // const defs = { 124 | // content: definitionEditor.getValue(), 125 | // width: checkLength(inputSvgWidth.value), 126 | // height: checkLength(inputSvgHeight.value), 127 | // }; 128 | // $preview.doSetDefinitions(defs); 129 | // previewSelector.innerHTML = ''; 130 | // insertSelector.innerHTML = ''; 131 | // for (const def of ['main', ...$preview.getDefinitionNames()]) { 132 | // const option = document.createElement('option'); 133 | // option.value = def; 134 | // option.innerText = def; 135 | // previewSelector.appendChild(option.cloneNode(true)); 136 | // if (def !== 'main') { 137 | // insertSelector.appendChild(option); 138 | // } 139 | // } 140 | // }; 141 | // definitionEditor.getModel().onDidChangeContent(e => { 142 | // triggerSyncEditorState(); 143 | // }); 144 | // inputSvgWidth.oninput = triggerSyncEditorState; 145 | // inputSvgHeight.oninput = triggerSyncEditorState; 146 | 147 | // const triggerSyncMain = () => { 148 | // try { 149 | // $preview.doSetMainContent({ 150 | // content: mainEditor.getValue(), 151 | // }); 152 | // } catch (e) { 153 | // console.log('error', e); 154 | // } 155 | // }; 156 | // mainEditor.getModel().onDidChangeContent(e => { 157 | // if (e.isFlush) { 158 | // return; 159 | // } 160 | // triggerSyncMain(); 161 | // }); 162 | end Typst 163 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/TypstSemanticHighlight.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.JSConverters._ 5 | import scala.scalajs.js.annotation._ 6 | import org.scalajs.dom 7 | 8 | import binding.Typst 9 | 10 | val scopeRenamingRules = js.Dynamic.literal( 11 | scopes = js.Dynamic.literal( 12 | // vscode rules 13 | "namespace" -> js.Array("entity.name.namespace"), 14 | "type" -> js.Array("entity.name.type"), 15 | "type.defaultLibrary" -> js.Array("support.type"), 16 | "struct" -> js.Array("storage.type.struct"), 17 | "class" -> js.Array("entity.name.type.class"), 18 | "class.defaultLibrary" -> js.Array("support.class"), 19 | "interface" -> js.Array("entity.name.type.interface"), 20 | "enum" -> js.Array("entity.name.type.enum"), 21 | "function" -> js.Array("entity.name.function"), 22 | "function.defaultLibrary" -> js.Array("support.function"), 23 | "method" -> js.Array("entity.name.function.member"), 24 | "macro" -> js.Array("entity.name.function.macro"), 25 | "variable" -> js.Array("variable.other.readwrite , entity.name.variable"), 26 | "variable.readonly" -> js.Array("variable.other.constant"), 27 | "variable.readonly.defaultLibrary" -> js.Array("support.constant"), 28 | "parameter" -> js.Array("variable.parameter"), 29 | "property" -> js.Array("variable.other.property"), 30 | "property.readonly" -> js.Array("variable.other.constant.property"), 31 | "enumMember" -> js.Array("variable.other.enummember"), 32 | "event" -> js.Array("variable.other.event"), 33 | 34 | // typst rules 35 | "*.strong.emph" -> js.Array("markup.bold.typst markup.italic.typst"), 36 | "*.strong" -> js.Array("markup.bold.typst"), 37 | "*.emph" -> js.Array("markup.italic.typst"), 38 | "*.math" -> js.Array("markup.math.typst"), 39 | "bool" -> js.Array("constant.language.boolean.typst"), 40 | "punct" -> js.Array("punctuation.typst", "punctuation.definition.typst"), 41 | "escape" -> js.Array( 42 | "constant.character.escape.typst", 43 | "keyword.operator.typst", 44 | "punctuation.definition.typst", 45 | ), 46 | "link" -> js.Array("markup.underline.link.typst"), 47 | "raw" -> js.Array("markup.inline.raw.typst", "markup.raw.inline.typst"), 48 | "delim.math" -> js.Array( 49 | "punctuation.definition.math.typst", 50 | "punctuation.definition.string.end.math.typst", 51 | "string.quoted.other.typst", 52 | ), 53 | "pol" -> js.Array("variable.other.readwrite , entity.name.variable"), 54 | ), 55 | ) 56 | 57 | val typstTokens = js.Array( 58 | "comment", 59 | "string", 60 | "keyword", 61 | "operator", 62 | "number", 63 | "function", 64 | "decorator", 65 | "bool", 66 | "punctuation", 67 | "escape", 68 | "link", 69 | "raw", 70 | "label", 71 | "ref", 72 | "heading", 73 | "marker", 74 | "term", 75 | "delim", 76 | "pol", 77 | "error", 78 | "text", 79 | ) 80 | 81 | // todo: rewrite me in scala 82 | def adaptVsCodeThemeForTypst(theme: js.Dynamic): js.Dynamic = { 83 | val tokenColors = theme.tokenColors.asInstanceOf[js.Array[js.Dynamic]] 84 | val semanticTokenColors = theme.semanticTokenColors.asInstanceOf[ 85 | js.Dictionary[js.Dynamic], 86 | ] 87 | dom.console.log(tokenColors) 88 | dom.console.log(semanticTokenColors) 89 | 90 | val newTokenColors = js.Array[js.Object]() 91 | val defaultSettings = js.Dynamic.literal(foreground = theme.colors.foreground) 92 | dom.console.log("defaultSettings", defaultSettings) 93 | 94 | val rules = js.Map[String, js.Dynamic]() 95 | for (tokenColor <- tokenColors) { 96 | for (s <- tokenColor.scope.asInstanceOf[js.Array[String]]) { 97 | rules.addOne(s, tokenColor) 98 | } 99 | } 100 | 101 | val semanticTokenRules = js.Map[String, js.Dynamic]() 102 | for ((k, settings) <- semanticTokenColors) { 103 | semanticTokenRules.addOne(k, settings) 104 | 105 | if (k.startsWith("*.")) { 106 | val suffix = k.slice(2, k.length()) 107 | for (token <- typstTokens) { 108 | semanticTokenRules.addOne(s"${token}.${suffix}", settings) 109 | } 110 | } 111 | } 112 | 113 | for ( 114 | (k, renamedScopes) <- scopeRenamingRules.scopes 115 | .asInstanceOf[js.Dictionary[js.Array[String]]] 116 | ) { 117 | var scopes = js.Array[String]() 118 | if (k.startsWith("*.")) { 119 | val suffix = k.slice(2, k.length()) 120 | for (token <- typstTokens) { 121 | scopes.push(s"${token}.${suffix}") 122 | } 123 | } else { 124 | scopes.push(k) 125 | } 126 | 127 | var settings: js.Dynamic = defaultSettings 128 | if (semanticTokenRules.contains(k)) { 129 | settings = semanticTokenRules.get(k).orUndefined.asInstanceOf[js.Dynamic] 130 | } else { 131 | for (i <- 0 until renamedScopes.length) { 132 | val renamedScope = renamedScopes(i) 133 | 134 | for (j <- renamedScope.length to 0 by -1) { 135 | if (j != renamedScope.length && renamedScope.charAt(j) != '.') { 136 | () 137 | } else { 138 | val rule = rules.get(renamedScope.slice(0, j)) 139 | rule.foreach { rule => 140 | settings = rule.settings 141 | } 142 | } 143 | } 144 | } 145 | } 146 | newTokenColors.push( 147 | js.Dynamic.literal( 148 | name = s"typst ${k}", 149 | scope = scopes, 150 | settings = settings, 151 | ), 152 | ) 153 | } 154 | 155 | theme.asInstanceOf[js.Dynamic].tokenColors = 156 | tokenColors.concat(newTokenColors) 157 | theme 158 | } 159 | 160 | def monacoThemeFromVscTheme(themeRaw: js.Dynamic): js.Object = { 161 | val vscodeTheme = adaptVsCodeThemeForTypst(themeRaw) 162 | val baseTokenColors = js.Array[js.Object]() 163 | for (tc <- vscodeTheme.tokenColors.asInstanceOf[js.Array[js.Dynamic]]) { 164 | def makeElement(s: String): js.Object = { 165 | val res = js.Dynamic.literal(token = s) 166 | for ((k, v) <- tc.settings.asInstanceOf[js.Dictionary[js.Any]]) { 167 | res.updateDynamic(k)(v) 168 | } 169 | res 170 | } 171 | 172 | if (js.typeOf(tc.scope) == "string") { 173 | baseTokenColors.push(makeElement(tc.scope.asInstanceOf[String])) 174 | } else { 175 | val elements = tc.scope.asInstanceOf[js.Array[String]].map(makeElement); 176 | for (element <- elements) { 177 | baseTokenColors.push(element) 178 | } 179 | } 180 | } 181 | 182 | val res = js.Dynamic.literal( 183 | base = "vs-dark", 184 | inherit = true, 185 | colors = vscodeTheme.colors, 186 | rules = baseTokenColors, 187 | ) 188 | 189 | res 190 | } 191 | 192 | @js.native @JSImport("/assets/tokyo-night.json", JSImport.Namespace) 193 | val tokyoNightThemeData: js.Dynamic = js.native 194 | 195 | def tokyoNightTheme(): js.Object = { 196 | monacoThemeFromVscTheme( 197 | // todo: readonly tokyoNightThemeData 198 | js.JSON.parse(js.JSON.stringify(tokyoNightThemeData)), 199 | ) 200 | } 201 | 202 | class SemanticTokensProvider(legend: js.Object) { 203 | @JSExport 204 | def getLegend(): js.Object = legend 205 | 206 | @JSExport 207 | def provideDocumentSemanticTokens( 208 | model: js.Dynamic, 209 | lastResultId: String, 210 | ): js.Promise[js.Object] = { 211 | val content = model.getValue().asInstanceOf[String] 212 | // todo: support incremental update 213 | Typst 214 | .addSource("/semantic-tokens.typ", content) 215 | .`then`(_ => 216 | Typst.getSemanticTokens( 217 | js.Dynamic.literal(mainFilePath = "/semantic-tokens.typ"), 218 | ), 219 | ) 220 | } 221 | 222 | @JSExport 223 | def releaseDocumentSemanticTokens(resultId: String): Unit = {} 224 | } 225 | -------------------------------------------------------------------------------- /favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 36 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Parser.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | import scala.util.chaining._ 4 | import scala.util.TupledFunction 5 | 6 | import fastparse._, fastparse.ScalaWhitespace._ 7 | 8 | import vistyp.syntax._ 9 | import vistyp.syntax.NodeParse._ 10 | 11 | implicit class SoftErr[$: P](p: => P[Unit]) { 12 | def err(msg: String): P[Unit] = p.map(_ => Err(msg)) 13 | } 14 | 15 | def parseCode(src: String): syntax.MarkupBlock = { 16 | fastparse.parse(src, Parser.markupRoot(_)) match { 17 | case Parsed.Success(ast, _) => ast 18 | case Parsed.Failure(_, index, extra) => 19 | println(extra.trace().longAggregateMsg) 20 | println(src.slice(index, index + 40)) 21 | throw new Exception("Parsing failed") 22 | } 23 | } 24 | 25 | object Parser { 26 | // Entry point 27 | def markupRoot[$: P]: P[MarkupBlock] = 28 | P((!End ~ markupExpr).rep.map(_.toList) ~ End).map(MarkupBlock.apply).m 29 | def markupMode[$: P]: P[MarkupBlock] = 30 | P((!End ~ markupExpr).rep.map(_.toList)).map(MarkupBlock.apply).m 31 | def codeMode[$: P]: P[Block] = 32 | P(("" ~ codeExpr).rep.map(_.toList)).map(Block.apply).m 33 | def mathMode[$: P]: P[MathBlock] = 34 | P(("" ~ mathExpr).rep.map(_.toList)).map(MathBlock.apply).m 35 | 36 | def markupExpr[$: P]: P[Node] = P( 37 | hashExpr | equation | blockRaw | inlineRaw | regularMarkup, 38 | ) 39 | def lazyCodeExpr[$: P]: P[Node] = P( 40 | lazyCodeBlock | lazyContentBlock | codeExpr, 41 | ) 42 | def codeExpr[$: P]: P[Node] = P(atomicExprNoPrimary | assign) 43 | def atomicExprNoPrimary[$: P]: P[Node] = P( 44 | letBindingItem | ifItem | forItem | whileItem | breakItem | continueItem | returnItem | showItem | setItem | importItem | includeItem, 45 | ) 46 | def mathExpr[$: P]: P[Node] = P( 47 | hashExpr | escapeseq.!.map(EscapeLit.apply) | regularMarkup, 48 | ) 49 | 50 | def codeBlock[$: P]: P[Node] = P( 51 | "{" ~/ codeMode ~ "}", 52 | ) 53 | def contentBlock[$: P]: P[Node] = P( 54 | "[" ~/ markupMode ~ "]", 55 | ) 56 | def equation[$: P]: P[Node] = P( 57 | "$" ~/ mathMode ~ "$", 58 | ) 59 | 60 | def hashExpr[$: P]: P[Node] = P( 61 | "#" ~ (atomicExprNoPrimary | primaryExpr), 62 | ) 63 | 64 | def lazyCodeBlock[$: P]: P[Node] = codeBlock 65 | def lazyContentBlock[$: P]: P[Node] = contentBlock 66 | 67 | // Markup 68 | 69 | def regularMarkup[$: P]: P[Node] = 70 | P(regularMarkupContent.repX.!).map(MarkupContent.apply) 71 | def regularMarkupContent[$: P]: P[Unit] = P( 72 | ("[" ~~ regularMarkupContent ~~ ("]" | End)) | 73 | !(End | "#" | "$" | "`" | "]") ~~/ (fastSkipMarkup | escapeseq), 74 | ) 75 | 76 | def fastSkipMarkup[$: P] = CharsWhile(!"#[]$`\\".contains(_)) 77 | def blockRaw[$: P]: P[Node] = P( 78 | "`" 79 | .rep(min = 3) 80 | .! 81 | .flatMapX(delim => rawBody(delim).! ~~ (delim | End)) 82 | .map(RawContent.apply), 83 | ) 84 | def inlineRaw[$: P]: P[Node] = 85 | P("``".map(_ => "") | "`" ~/ rawBody("`").! ~ "`").map(RawContent.apply) 86 | def rawBody[$: P](delim: String) = P( 87 | (!(delim | End) ~/ CharsWhile(!"`".contains(_))).rep.!, 88 | ) 89 | 90 | // Literals 91 | def whitespaceInline[$: P] = P(CharsWhileIn(" \t").rep) 92 | def whitespace[$: P] = P(CharsWhileIn(" \t\n").rep) 93 | def noneLit[$: P] = P("none").map(_ => NoneLit) 94 | def autoLit[$: P] = P("auto").map(_ => AutoLit) 95 | def booleanLit[$: P] = 96 | (P(word("true") | word("false"))).!.map(v => BoolLit(v == "true")) 97 | def numberLit[$: P]: P[FloatLit | IntLit] = P( 98 | float.map(FloatLit.apply) | int.map(IntLit.apply), 99 | ) 100 | def numberOrLengthLit[$: P] = P( 101 | P(numberLit ~~ ident.?).map { 102 | case (value, None) => value 103 | case (value, Some(unit)) => LengthLit(value, unit.name) 104 | }, 105 | ) 106 | def stringLit[$: P] = P(longStr | shortStr).map(StrLit.apply) 107 | def labelLit[$: P] = 108 | P("<" ~~/ (idCont | ":" | ".").repX.! ~~ ">").map(LabelLit.apply) 109 | 110 | // Lexer 111 | def word[$: P](s: String) = s ~~ !idCont 112 | def letter[$: P] = P(lowercase | uppercase) 113 | def lowercase[$: P] = P(CharIn("a-z")) 114 | def uppercase[$: P] = P(CharIn("A-Z")) 115 | def digit[$: P] = P(CharIn("0-9")) 116 | def id[$: P] = P((letter | "_") ~~ idCont.repX).!.filter(!keywords(_)) 117 | def idCont[$: P] = P(letter | digit | "_" | "-") 118 | 119 | def delimStr[T, $: P](d: String, body: => P[T]) = d ~~/ delimStrCont(d, body) 120 | def delimStrCont[T, $: P](d: String, body: => P[T]) = 121 | (!End ~~ !d ~~ body).repX.! ~~ (d | End.err("Unclosed string")) 122 | def shortStr[$: P] = P(shortStr0.map(unescapeStr)) 123 | def shortStr0[$: P] = delimStr("\"", strEscape) 124 | def longStr[$: P] = P("\"".repX(3).!./.flatMapX(longStr0)) 125 | def longStr0[$: P](delim: String) = P(delimStrCont(delim, longStrBody(delim))) 126 | def strEscape[$: P] = P(litCharsWhile("\\\n\"") | escapeseq) 127 | def longStrBody[$: P](delim: String) = P(longChars("\"", delim).repX.!) 128 | 129 | def longChars[$: P](mores: String, delim: String): P[Unit] = 130 | !End ~~ P(litCharsWhile(mores) | !delim ~~ "\"".repX) 131 | def litCharsWhile[$: P](mores: String) = P(CharsWhile(!mores.contains(_))) 132 | def escapeseq[$: P]: P[Unit] = P("\\" ~ AnyChar) 133 | 134 | def int[$: P]: P[BigInt] = 135 | P(octinteger | hexinteger | bininteger | decimalinteger) 136 | def decimalinteger[$: P]: P[BigInt] = 137 | P(nonzerodigit ~~ digit.rep | "0").!.map(scala.BigInt(_)) 138 | def octinteger[$: P]: P[BigInt] = P( 139 | "0" ~ ("o" | "O") ~~ octdigit.rep(1).! | "0" ~ octdigit.rep(1).!, 140 | ).map(scala.BigInt(_, 8)) 141 | def hexinteger[$: P]: P[BigInt] = 142 | P("0" ~ ("x" | "X") ~~ hexdigit.rep(1).!).map(scala.BigInt(_, 16)) 143 | def bininteger[$: P]: P[BigInt] = 144 | P("0" ~ ("b" | "B") ~~ bindigit.rep(1).!).map(scala.BigInt(_, 2)) 145 | def nonzerodigit[$: P]: P[Unit] = P(CharIn("1-9")) 146 | def octdigit[$: P]: P[Unit] = P(CharIn("0-7")) 147 | def bindigit[$: P]: P[Unit] = P("0" | "1") 148 | def hexdigit[$: P]: P[Unit] = P(digit | CharIn("a-f", "A-F")) 149 | 150 | def float[$: P]: P[BigDecimal] = P(pointfloat | exponentfloat) 151 | def pointfloat[$: P]: P[BigDecimal] = 152 | P(intpart.? ~~ fraction | intpart ~~ "." ~~ !".").!.map(BigDecimal(_)) 153 | def exponentfloat[$: P]: P[BigDecimal] = 154 | P((intpart | pointfloat) ~~ exponent).!.map(BigDecimal(_)) 155 | def intpart[$: P]: P[BigDecimal] = P(digit.rep(1)).!.map(BigDecimal(_)) 156 | def fraction[$: P]: P[Unit] = P("." ~~ digit.rep(1)) 157 | def exponent[$: P]: P[Unit] = P(("e" | "E") ~~ ("+" | "-").? ~ digit.rep(1)) 158 | 159 | // Terms 160 | def term[$: P]: P[Node] = (codeExpr | semiWrap | semi).m 161 | def termU[$: P] = P(term.map { 162 | case Semi(Some(x)) => x 163 | case x => x 164 | }) 165 | def semiWrap[$: P]: P[Node] = P(codeExpr.m ~/ semi.?).map((item, isSemi) => 166 | if isSemi.isEmpty then item else Semi(Some(item)), 167 | ) 168 | def semi[$: P] = P(";").map(_ => Semi(None)) 169 | def primaryExpr[$: P] = 170 | P(applyItem | ident | parens | literal | codeBlock | contentBlock).m 171 | def factor[$: P]: P[Node] = P(unary | primaryExpr.flatMapX(factorR)) 172 | 173 | // Braces/Args/Params 174 | def parens[$: P] = argList.map(ArgsLit.apply) 175 | def paramList[$: P]: P[List[Node]] = P( 176 | "(" ~/ (ident ~ defaultValue.?).map(Param.apply.tupled).rep(sep = ",") ~ ")", 177 | ).map(_.toList) 178 | def defaultValue[$: P] = P(":" ~/ codeExpr).m 179 | def argList[$: P]: P[List[Node]] = P( 180 | "(" ~/ (namedArg | spreadArg | codeExpr).rep(sep = ",") ~ ")", 181 | ).map(_.toList) 182 | def namedArg[$: P]: P[Node] = P( 183 | ident ~ ":" ~/ codeExpr, 184 | ).map(KeyedArg.apply.tupled) 185 | 186 | def spreadArg[$: P]: P[Node] = P(".." ~/ codeExpr).map(UnOp("..", _)) 187 | def chk[$: P](s: => P[Unit]) = P(s.?.!).map(_.nonEmpty) 188 | 189 | // Expressions 190 | def literal[$: P] = P( 191 | numberOrLengthLit | booleanLit | noneLit | autoLit | stringLit | labelLit, 192 | ).m 193 | def ident[$: P] = id.map(Ident.apply).m 194 | def anyBlock[$: P]: P[Node] = P( 195 | codeBlock | contentBlock, 196 | ) 197 | def ifItem[$: P]: P[Node] = P( 198 | "if" ~/ codeExpr ~ anyBlock ~ ("else" ~ (anyBlock | ifItem)).?, 199 | ).map(If.apply.tupled) 200 | def forItem[$: P] = P( 201 | word("for") ~ "(" ~/ ident ~ word("in") ~ term ~ ")" ~ anyBlock, 202 | ).map(For.apply.tupled) 203 | def whileItem[$: P] = P( 204 | word("while") ~/ parens ~ anyBlock, 205 | ).map(While.apply) 206 | def breakItem[$: P] = P(word("break")).map(_ => Break()) 207 | def continueItem[$: P] = P(word("continue")).map(_ => Continue()) 208 | def returnItem[$: P] = P(word("return") ~/ termU).map(Return.apply) 209 | def applyItem[$: P]: P[Node] = P(ident ~ argList).map(Apply.apply.tupled) 210 | def letBindingItem[$: P]: P[Node] = P( 211 | "let" ~/ ident ~/ paramList.? ~ "=" ~/ lazyCodeExpr, 212 | ).map(LetBinding.apply.tupled) 213 | def importItem[$: P] = 214 | P( 215 | word("import") ~/ codeExpr ~ (word( 216 | "as", 217 | ) ~/ ident).? ~ (":" ~/ (importList(false) | "(" ~/ importList( 218 | true, 219 | ) ~ ")")).?, 220 | ) 221 | .map(Import.apply.tupled) 222 | def includeItem[$: P] = P(word("include") ~/ codeExpr).map(IncludeItem.apply) 223 | def importList[$: P](allowNewLine: Boolean): P[List[Node]] = P( 224 | if allowNewLine then { 225 | importPath.rep(sep = ",").map(_.toList) 226 | } else { 227 | importPath.repX(sep = P("" ~~ whitespaceInline ~~ ",")).map(_.toList) 228 | }, 229 | ) 230 | def showItem[$: P] = 231 | P( 232 | word("show") ~/ codeExpr.? ~ (":" ~/ codeExpr.?).?.map(_.flatten), 233 | ).map(Show.apply.tupled) 234 | def setItem[$: P] = P( 235 | word("set") ~/ codeExpr ~ ("if" ~ codeExpr).?, 236 | ).map(SetItem.apply.tupled) 237 | 238 | def importPath[$: P]: P[Node] = ident 239 | // (Top) Compound expressions 240 | def compound[$: P] = andOr 241 | def moreAssigns[$: P] = 242 | "+=" | "-=" | "*=" | "/=" 243 | def assign[$: P]: P[Node] = binOp(P(P("=" ~ !">") | moreAssigns), compound) 244 | def binOp[$: P](op: => P[Unit], next: => P[Node]): P[Node] = 245 | P(next ~ (op.! ~/ next).rep).map { case (lhs, rhs) => 246 | rhs.foldLeft(lhs) { case (lhs, (op, rhs)) => BinOp(op, lhs, rhs) } 247 | } 248 | def andOr[$: P]: P[Node] = binOp(P("and" | "or"), compare) 249 | def relOp[$: P] = "<=" | ">=" | "==" | "!=" | P("<" ~ !"<") | P(">" ~ !">") 250 | def inNotIn[$: P] = word("in") | (word("not") ~ word("in")) 251 | def compare[$: P]: P[Node] = binOp(P(relOp | inNotIn), addSub) 252 | def addSub[$: P]: P[Node] = binOp(CharIn("+\\-") ~~ !"=", divMul) 253 | def divMul[$: P]: P[Node] = binOp(CharIn("*/") ~~ !"=", factor) 254 | def unaryOps[$: P] = "!" | "~" | "-" | "+" | "&" | "*" | word("context") 255 | def unary[$: P]: P[Node] = P(unaryOps.! ~ factor).map(UnOp.apply.tupled) 256 | def eBinR[$: P](e: Node) = select(e) | lambda(e) 257 | def factorR[$: P](e: Node): P[Node] = 258 | P(("" ~ eBinR(e)).flatMapX(factorR) | P("").map(_ => e)) 259 | def select[$: P](lhs: Node) = 260 | P((".") ~ ident).map((rhs) => Select(lhs, rhs)) 261 | def lambda[$: P](lhs: Node) = P("=>" ~/ compound).map(rhs => Lambda(lhs, rhs)) 262 | 263 | // Weak Keywords: from 264 | // Strong Keywords 265 | val keywords = 266 | Set( 267 | // to reduce js load time a bit 268 | "import|include|let|show|none|auto|set|break|continue|return|case|type|if|else|for|while|and|or|in|not|true|false|context" 269 | .split('|')*, 270 | ) 271 | } 272 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/UI.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.* 5 | 6 | import org.scalajs.dom 7 | import com.raquo.laminar.api.L.{*, given} 8 | import com.raquo.laminar.DomApi 9 | 10 | trait Vistyp: 11 | val previewContentSignal: Signal[(String, Map[String, String])] 12 | val programContentVar: Var[String] 13 | 14 | def updateDefinition(code: String): Unit 15 | def updateDiagram(code: String): Unit 16 | 17 | def onPreviewMounted(panel: dom.Element): Unit 18 | end Vistyp 19 | 20 | class UI(vistyp: Vistyp): 21 | import vistyp.*; 22 | 23 | val builtinDefinitions = """#let x-circle(rad: 200, inner-text: "") = { 24 | circle((0, 0), radius: rad, name: node-label) 25 | debug-label((-rad*0.7, -rad*0.7)) 26 | content(node-label, inner-text) 27 | } 28 | #let x-rect(x: 200, y: none, inner-text: "") = { 29 | let y = if y == none { 30 | x 31 | } else { 32 | y 33 | } 34 | rect((0, 0), (x, y), name: node-label) 35 | debug-label((0, 0)) 36 | content(node-label, inner-text) 37 | } 38 | #let x-arrow(start: (0, 10), end: (50, 10), inner-text: "", mark: (end: ">")) = { 39 | set-style(mark: (fill: none, size: 14)) 40 | line(start, end, name: "t", mark: mark) 41 | content("t", inner-text) 42 | } 43 | """; 44 | 45 | def mainElement(): Element = { 46 | div( 47 | cls := "editor-main flex-column", 48 | styleAttr( 49 | "height: 100vh", 50 | ), 51 | topPanel(), 52 | bottomPanel(), 53 | ) 54 | } 55 | 56 | def topPanel(): Element = { 57 | div( 58 | cls := "top-panel", 59 | styleAttr( 60 | "flex: 0 0 auto", 61 | ), 62 | div( 63 | cls := "flex-row", 64 | styleAttr( 65 | "margin: 5px; align-items: center", 66 | ), 67 | img( 68 | src := "favicon.svg", 69 | styleAttr( 70 | "height: 1rem; margin: 3px; margin-left: 2px", 71 | ), 72 | ), 73 | div( 74 | cls := "editor-menu-group", 75 | styleAttr( 76 | "margin-left: 1em; padding: 1px 3px", 77 | ), 78 | a( 79 | cls := "editor-menu export-svg", 80 | "SVG", 81 | ), 82 | a( 83 | cls := "editor-menu export-pdf", 84 | "PDF", 85 | ), 86 | a( 87 | cls := "editor-menu export-cetz", 88 | "CeTZ", 89 | ), 90 | a( 91 | cls := "editor-menu export-elem", 92 | "Element", 93 | ), 94 | ), 95 | ), 96 | ) 97 | } 98 | 99 | def bottomPanel(): Element = { 100 | div( 101 | cls := "bottom-panel flex-row", 102 | styleAttr("flex: 1"), 103 | div( 104 | styleAttr("flex: 0 0 35px"), 105 | ), 106 | div( 107 | cls := "flex-column", 108 | styleAttr("flex: 1"), 109 | div( 110 | styleAttr("margin: 5px; flex: 1"), 111 | definitionGroup(), 112 | elementGroup(), 113 | viewportGroup(), 114 | ), 115 | div( 116 | cls := "flex-row", 117 | styleAttr("flex: 1"), 118 | div( 119 | cls := "flex-column", 120 | styleAttr("flex: 4; height: 100vh"), 121 | defEditor(), 122 | mainEditor(), 123 | ), 124 | previewPanel(), 125 | ), 126 | ), 127 | ) 128 | } 129 | 130 | // $preview.bindElement(document.getElementById('preview-panel'), v => mainEditor.setValue(v)); 131 | // document.getElementById('export-svg').addEventListener('click', () => { 132 | // $preview.doExport('svg'); 133 | // }); 134 | // document.getElementById('export-pdf').addEventListener('click', () => { 135 | // $preview.doExport('pdf'); 136 | // }); 137 | // document.getElementById('export-cetz').addEventListener('click', () => { 138 | // $preview.doExport('cetz'); 139 | // }); 140 | // document.getElementById('insert-elem').addEventListener('click', () => { 141 | // let insertNameValue = insertName.value; 142 | // if (!insertNameValue) { 143 | // insertNameValue = 'node-' + Math.random().toString(36).substring(7).replace('0.', ''); 144 | // } 145 | // console.log('insertSelector.value', insertSelector.value, insertNameValue); 146 | // $preview.doInsertElem(insertSelector.value, insertNameValue); 147 | // }); 148 | 149 | def definitionGroup(): Element = { 150 | //
151 | // definition: 152 | // 153 | // from 154 | //
162 | // 171 | // 177 | // 183 | //
184 | //
185 | div() 186 | } 187 | 188 | // const checkDefinitionSource = () => { 189 | // if (definitionSourceSelector.value === 'builtin') { 190 | // definitionEditor.setValue(builtinDefinitions); 191 | // } else if (definitionSourceSelector.value === 'url') { 192 | // console.log('definitionSourceValue.value', definitionSourceValue.value); 193 | // if (definitionSourceValue.value) { 194 | // fetch(definitionSourceValue.value).then(r => r.text()).then(t => { 195 | // definitionEditor.setValue(t); 196 | // }); 197 | // } 198 | // // set url param 199 | // const urlParams = new URLSearchParams(window.location.search); 200 | // urlParams.set('url', definitionSourceValue.value); 201 | // window.history.replaceState({}, '', `${location.pathname}?${urlParams}`); 202 | // } else if (definitionSourceSelector.value === 'file') { 203 | // const input = document.createElement('input'); 204 | // input.type = 'file'; 205 | // input.onchange = () => { 206 | // const file = input.files[0]; 207 | // const reader = new FileReader(); 208 | // reader.onload = () => { 209 | // definitionEditor.setValue(reader.result); 210 | // }; 211 | // reader.readAsText(file); 212 | // definitionSourceValue.value = file.name; 213 | // }; 214 | // input.click(); 215 | // } 216 | // }; 217 | 218 | // /// check ?url=xxx option 219 | // const urlParams = new URLSearchParams(window.location.search); 220 | // const urlParamUrl = urlParams.get('url'); 221 | // if (urlParamUrl) { 222 | // definitionSourceSelector.value = 'url'; 223 | // definitionSourceValue.value = urlParamUrl; 224 | // checkDefinitionSource(); 225 | // } else { 226 | // definitionEditor.setValue(builtinDefinitions); 227 | // mainEditor.setValue(); 228 | // } 229 | 230 | // previewSelector.onchange = () => { 231 | // console.log('previewSelector.value', previewSelector.value); 232 | // $preview.doSelectDef(previewSelector.value); 233 | // }; 234 | 235 | // $preview.doSelectDef(''); 236 | 237 | // definitionSourceConfirm.onclick = checkDefinitionSource; 238 | // definitionSourceSelector.onchange = () => { 239 | // if (definitionSourceSelector.value === 'builtin' || definitionSourceSelector.value === 'file') { 240 | // checkDefinitionSource(); 241 | // } 242 | // }; 243 | 244 | def elementGroup(): Element = { 245 | //
246 | // element: 247 | //
255 | // 256 | // 262 | // 265 | //
266 | //
267 | div() 268 | } 269 | 270 | def viewportGroup(): Element = { 271 | //
272 | // viewport: 273 | // 280 | // · 281 | // 288 | //
289 | div() 290 | } 291 | 292 | def defEditor(): Element = { 293 | div( 294 | cls := "def-editor", 295 | styleAttr("flex: 5"), 296 | child.maybe <-- monacoLoadSignal.splitOption { (monaco, _) => 297 | div( 298 | styleAttr( 299 | "width: 100%; height: 100%", 300 | ), 301 | onMountCallback(ctx => { 302 | dom.console.log("defEditor mounting", ctx.thisNode.ref); 303 | 304 | val definitionEditor = monaco.editor.create( 305 | ctx.thisNode.ref, 306 | js.Dynamic.literal( 307 | "value" -> "", 308 | "language" -> "typst", 309 | "theme" -> "tokyo-night", 310 | "semanticHighlighting.enabled" -> true, 311 | "bracketPairColorization.enabled" -> true, 312 | ), 313 | ) 314 | definitionEditor.setValue(builtinDefinitions); 315 | updateDefinition(builtinDefinitions); 316 | }), 317 | ) 318 | }, 319 | ) 320 | } 321 | 322 | def mainEditor(): Element = { 323 | div( 324 | cls := "main-editor", 325 | styleAttr("flex: 2"), 326 | child.maybe <-- monacoLoadSignal.splitOption { (monaco, _) => 327 | div( 328 | styleAttr( 329 | "width: 100%; height: 100%", 330 | ), 331 | onMountCallback(ctx => { 332 | dom.console.log("mainEditor mounting", ctx.thisNode.ref); 333 | val mainEditor = monaco.editor.create( 334 | ctx.thisNode.ref, 335 | js.Dynamic.literal( 336 | "value" -> "", 337 | "language" -> "typst", 338 | "theme" -> "tokyo-night", 339 | "semanticHighlighting.enabled" -> true, 340 | "bracketPairColorization.enabled" -> true, 341 | ), 342 | ) 343 | 344 | mainEditor 345 | .getModel() 346 | .onDidChangeContent((e: MonacoModelContentChange) => { 347 | if (!e.isFlush) { 348 | updateDiagram(mainEditor.getValue()); 349 | } 350 | }) 351 | 352 | programContentVar.signal 353 | .foreach(content => { 354 | mainEditor.setValue(content); 355 | updateDiagram(content); 356 | })(ctx.owner) 357 | updateDiagram(programContentVar.now()); 358 | 359 | }), 360 | ) 361 | }, 362 | ) 363 | } 364 | 365 | def previewPanel(): Element = { 366 | import instrument.processSvg 367 | div( 368 | cls := "preview", 369 | styleAttr( 370 | "flex: 6", 371 | ), 372 | div( 373 | cls := "preview-panel", 374 | onMountCallback(ctx => { 375 | dom.console.log("previewPanel mounting", ctx.thisNode.ref); 376 | vistyp.onPreviewMounted(ctx.thisNode.ref); 377 | }), 378 | child <-- previewContentSignal.map(state => { 379 | val (content, mapping) = state 380 | val rawSvg = DomApi.unsafeParseSvgString(content) 381 | foreignSvgElement(processSvg(rawSvg, mapping)) 382 | }), 383 | ), 384 | ) 385 | } 386 | 387 | end UI 388 | -------------------------------------------------------------------------------- /src/main/scala/vistyp/Vistyp.scala: -------------------------------------------------------------------------------- 1 | package vistyp 2 | 3 | import scala.scalajs.js 4 | import scala.scalajs.js.annotation.* 5 | import scala.annotation.newMain 6 | 7 | import org.scalajs.dom 8 | import com.raquo.laminar.api.L.{*, given} 9 | 10 | import vistyp.syntax.* 11 | import binding.Typst 12 | 13 | @main 14 | def bootstrapVistyp(): Unit = 15 | renderOnDomContentLoaded( 16 | dom.document.getElementById("app"), { 17 | Typst.configureWasm() 18 | dom.window.asInstanceOf[js.Dynamic].tokyoNightTheme = 19 | () => tokyoNightTheme() 20 | dom.window.asInstanceOf[js.Dynamic].onLoadedMonaco = 21 | (monaco: Monaco) => monacoLoadVar.update(_ => Some(monaco)) 22 | 23 | dom.window.asInstanceOf[js.Dynamic].$typst$semanticTokensProvider = Typst 24 | .getSemanticTokenLegend() 25 | .`then`(new SemanticTokensProvider(_)) 26 | 27 | UI(VistypImpl).mainElement() 28 | }, 29 | ) 30 | end bootstrapVistyp 31 | 32 | // case class PreviewState( 33 | // val defMap: Map[String, Def], 34 | // val instances: List[Instance], 35 | // ) 36 | 37 | object VistypImpl extends Vistyp: 38 | var defMap: Map[String, Def] = Map.empty 39 | var instances: List[Instance] = List() 40 | 41 | def tagMapping = instances.iterator.zipWithIndex.map { 42 | case (ins, idx) => { 43 | val hex = "#" + (idx + 1).formatted("%06x") 44 | hex -> ins.name 45 | } 46 | }.toMap 47 | 48 | def updateDefinition(code: String): Unit = { 49 | this.loadDefinition(parseCode(code)) 50 | } 51 | 52 | def loadDefinition(program: syntax.MarkupBlock) = { 53 | val newDefMap = program.stmts.collect { 54 | case syntax.LetBinding(name, param, init) => 55 | name.name -> Def(name.offset, name.name, param, init) 56 | }.toMap 57 | 58 | defMap = newDefMap 59 | updatePreview() 60 | } 61 | 62 | def updateDiagram(code: String): Unit = { 63 | val program = parseCode(code) 64 | dom.console.log("diagram program", program.toString()) 65 | val newInstances = program match { 66 | case syntax.MarkupBlock(List(syntax.Block(stmts))) => 67 | stmts.flatMap(constructInstance) 68 | case program => 69 | dom.console.error("Invalid diagram program", program) 70 | List() 71 | } 72 | 73 | instances = newInstances 74 | updatePreview() 75 | } 76 | 77 | def constructInstance(node: syntax.Node): Option[Instance] = { 78 | dom.console.log("constructInstance", node.toString()) 79 | val (nodeName, nodePosRaw, ty, extraArgsRaw) = node match { 80 | case Apply( 81 | Ident("make-ins"), 82 | List(StrLit(nodeName), nodePos, StrLit(ty), extraArgs), 83 | ) => 84 | (nodeName, nodePos, ty, extraArgs) 85 | case _ => { 86 | return None 87 | } 88 | } 89 | 90 | val nodePos = nodePosRaw match { 91 | case ArgsLit(List(x, y)) => Some((getNumber(x), getNumber(y))) 92 | case _ => { 93 | dom.console.error("Invalid node position", nodePosRaw) 94 | None 95 | } 96 | } 97 | 98 | val extraArgs = extraArgsRaw match { 99 | case ArgsLit(args) => Some(args) 100 | case _ => { 101 | dom.console.error("Invalid node position", nodePosRaw) 102 | None 103 | } 104 | } 105 | 106 | Some(Instance(nodeName, nodePos, ty, extraArgs)) 107 | } 108 | 109 | def getNumber(node: syntax.Node): Double = { 110 | node match { 111 | case IntLit(value) => value.toDouble 112 | case FloatLit(value) => value.toDouble 113 | case UnOp("+", lhs) => getNumber(lhs) 114 | case UnOp("-", lhs) => -getNumber(lhs) 115 | case _ => { 116 | dom.console.error("Invalid number", node.toString()) 117 | 0 118 | } 119 | } 120 | } 121 | 122 | // val previewStateVar = Var(PreviewState(defMap, instances)) 123 | // val previewStateSignal = previewStateVar.signal 124 | 125 | val previewContentVar = Var(("", Map[String, String]())) 126 | val previewContentSignal = previewContentVar.signal 127 | 128 | def genSignatures(): String = { 129 | 130 | """ 131 | let x-circle(rad: 200, inner-text: "", node-label: "") = { 132 | circle((0, 0), radius: rad, name: node-label) 133 | debug-label((-rad*0.7, -rad*0.7)) 134 | // content(node-label, inner-text) 135 | } 136 | let x-rect(x: 200, y: none, inner-text: "", node-label: "") = { 137 | let y = if y == none { 138 | x 139 | } else { 140 | y 141 | } 142 | rect((0, 0), (x, y), name: node-label) 143 | debug-label((0, 0)) 144 | // content(node-label, inner-text) 145 | } 146 | let x-arrow(start: (0, 10), end: (50, 10), inner-text: "", mark: (end: ">"), node-label: "") = { 147 | set-style(mark: (fill: none, size: 14)) 148 | line(start, end, name: "t", mark: mark) 149 | content("t.centroid", inner-text) 150 | } 151 | """ 152 | } 153 | 154 | def genInstances(): String = { 155 | val mapping = tagMapping 156 | 157 | var initPos: (Double, Double) = (0, 0) 158 | 159 | instances.iterator.zipWithIndex 160 | .map { 161 | case (ins, idx) => { 162 | val hex = (idx + 1).formatted("%06x") 163 | val args = ins.extraArgs.iterator.flatten.map(_.repr).mkString(", ") 164 | val deltaPos = (initPos, ins.pos) match { 165 | case ((x, y), Some((dx, dy))) => { 166 | initPos = (dx, dy) 167 | // (x + dx, y - dy) 168 | (dx - x, dy - y) 169 | } 170 | case (initPos, None) => (0, 0) 171 | } 172 | 173 | s""" 174 | translate($deltaPos) 175 | rect((0, 0), (1, 1), stroke: 0.00012345pt + rgb("#$hex")) 176 | ${ins.ty}(${args}, node-label: "${ins.name}") 177 | rect((0, 0), (1, 1), stroke: 0.00012345pt + rgb("#$hex")) 178 | """ 179 | } 180 | } 181 | .mkString("\n") 182 | } 183 | 184 | def updatePreview() = { 185 | dom.console.log("update preview", instances.toString()) 186 | // dom.console.log("update preview", defMap.toString(), instances.toString()) 187 | 188 | // val state = PreviewState(defMap, instances) 189 | 190 | val width = 600 191 | val height = 600 192 | 193 | val content = s""" 194 | #import "@preview/cetz:0.3.1" 195 | // #place(dx: 0pt, dy: 0pt, circle()) 196 | // #place(dx: 50pt, dy: 50pt, square()) 197 | // #place(dx: 200pt, dy: 0pt, circle()) 198 | // #place(dx: 50pt, dy: 50pt, square()) 199 | 200 | // #set page(margin: 1pt, width: ${width + 2}pt, height: ${height + 2}pt) 201 | #let debug-label(_) = () 202 | #cetz.canvas({ 203 | import cetz.draw: * 204 | let node-label = "" 205 | ${genSignatures()} 206 | ${genInstances()} 207 | }, length: 1pt) 208 | """ 209 | // println(s"preview main $content") 210 | Typst 211 | .previewSvg(content) 212 | .`then` { svg => 213 | // dom.console.log("svgToCheck", js.Dynamic.literal(svg = svg)) 214 | previewContentVar.update(_ => (svg, tagMapping)) 215 | } 216 | } 217 | 218 | val sampleDiagram = """#{ 219 | make-ins("c0", (0, 0), "x-circle", (rad: 50)) 220 | make-ins("c1", (50, 50), "x-rect", (x: 100)) 221 | make-ins("c2", (200, 0), "x-circle", (rad: 50)) 222 | make-ins("c1toc2", (0, 0), "x-arrow", (start: "c1.center", end: "c2.center")) 223 | } 224 | """ 225 | 226 | val programContentVar = Var(sampleDiagram) 227 | val programContentSignal = programContentVar.signal 228 | 229 | def updateProgram() = { 230 | var content = instances 231 | .map { ins => 232 | val args = ins.extraArgs.iterator.flatten.map(_.repr).mkString(", ") 233 | s"""make-ins("${ins.name}", (${ins.pos.get._1}, ${ins.pos.get._2}), "${ins.ty}", (${args}))""" 234 | } 235 | .mkString("#{", "\n ", "}") 236 | 237 | programContentVar.update(_ => content) 238 | } 239 | 240 | def onPreviewMounted(panel: dom.Element): Unit = { 241 | panel.addEventListener("mousedown", e => this.startDrag(panel, e)); 242 | panel.addEventListener("mousemove", e => this.drag(panel, e)); 243 | 244 | panel.addEventListener("mouseup", e => this.endDrag(panel, e)); 245 | panel.addEventListener("mouseleave", e => this.endDrag(panel, e)); 246 | // panel.addEventListener( 247 | // "contextmenu", 248 | // e => this.doToggleContextMenu(panel, e), 249 | // ); 250 | } 251 | 252 | var selectedElem: Option[dom.Element] = None 253 | var offset: (Double, Double) = (0, 0) 254 | var svgElem: Option[dom.SVGElement] = None 255 | var transform = Option.empty[dom.SVGTransform] 256 | def startDrag(panel: dom.Element, evt: dom.WheelEvent): Unit = { 257 | 258 | val targetOpt = 259 | findTaggedTypstElement(evt.target.asInstanceOf[dom.Element]); 260 | 261 | val target = targetOpt match { 262 | case Some(target) => target 263 | case None => 264 | selectedElem = None 265 | return 266 | } 267 | svgElem = findSvgElement(panel) 268 | dom.console.log("svgElem", svgElem); 269 | 270 | selectedElem = Some(target) 271 | offset = getMousePosition(evt) 272 | 273 | val transforms = target 274 | .asInstanceOf[js.Dynamic] 275 | .transform 276 | .baseVal 277 | .asInstanceOf[js.Array[dom.SVGTransform]] 278 | if ( 279 | transforms.length == 0 || 280 | transforms(0).`type` != dom.SVGTransform.SVG_TRANSFORM_TRANSLATE 281 | ) { 282 | val translate = svgElem.get.asInstanceOf[js.Dynamic].createSVGTransform() 283 | translate.setTranslate(0, 0) 284 | target 285 | .asInstanceOf[js.Dynamic] 286 | .transform 287 | .baseVal 288 | .insertItemBefore( 289 | translate, 290 | 0, 291 | ) 292 | } 293 | 294 | transform = Some(transforms(0)) 295 | offset = 296 | (offset._1 - transform.get.matrix.e) -> (offset._2 - transform.get.matrix.f) 297 | 298 | val typstId = getTypstElementId(target) 299 | println(s"find typstId $typstId in $instances") 300 | instances = instances.map { ins => 301 | if (ins.name == typstId) { 302 | ins.copy(initPos = ins.pos) 303 | } else { 304 | ins 305 | } 306 | } 307 | } 308 | 309 | def drag(panel: dom.Element, evt: dom.WheelEvent): Unit = { 310 | val selectedElement = selectedElem match { 311 | case Some(selectedElem) => selectedElem 312 | case None => return 313 | } 314 | 315 | evt.preventDefault() 316 | val coord = getMousePosition(evt) 317 | val x = coord._1 - offset._1 318 | val y = coord._2 - offset._2 319 | transform.get.setTranslate(x, y) 320 | val typstId = getTypstElementId(selectedElement) 321 | println(s"find typstId $typstId in $instances") 322 | instances = instances.map { ins => 323 | if (ins.name == typstId) { 324 | ins.copy(pos = Some(x -> y)) 325 | } else { 326 | ins 327 | } 328 | } 329 | // updatePreview() 330 | } 331 | 332 | def endDrag(panel: dom.Element, evt: dom.WheelEvent): Unit = { 333 | val selectedElement = selectedElem match { 334 | case Some(selectedElem) => selectedElem 335 | case None => return 336 | } 337 | selectedElem = None 338 | 339 | val typstId = getTypstElementId(selectedElement) 340 | println(s"find typstId $typstId in $instances") 341 | val ins = instances.find(_.name == typstId).get 342 | if (ins.pos.isDefined) { 343 | val x = ins.initPos.get._1 + ins.pos.get._1 344 | val y = ins.initPos.get._2 - ins.pos.get._2 345 | instances = instances.map { ins => 346 | if (ins.name == typstId) { 347 | ins.copy(pos = Some(x -> y), initPos = None) 348 | } else { 349 | ins 350 | } 351 | } 352 | 353 | updateProgram() 354 | } 355 | } 356 | 357 | def getTypstElementId(target: dom.Element): String = { 358 | target.getAttribute("data-element-id").replace("cetz-app-", "") 359 | } 360 | 361 | /** A Fetch Action from DOM 362 | */ 363 | def getMousePosition(evt: dom.WheelEvent) = { 364 | val CTM = svgElem.get 365 | .asInstanceOf[js.Dynamic] 366 | .getScreenCTM() 367 | .asInstanceOf[dom.SVGMatrix] 368 | (evt.clientX - CTM.e) / CTM.a -> (evt.clientY - CTM.f) / CTM.d 369 | } 370 | 371 | def findSvgElement(panel: dom.Element): Option[dom.SVGElement] = { 372 | Some(panel.querySelector("svg").asInstanceOf[dom.SVGElement]) 373 | } 374 | 375 | def findTaggedTypstElement(target: dom.Element): Option[dom.Element] = { 376 | var current = target 377 | while (current != null) { 378 | dom.console.log("current", current) 379 | if ( 380 | current.classList != null && current.classList.contains( 381 | "typst-cetz-elem", 382 | ) 383 | ) { 384 | return Some(current) 385 | } 386 | current = 387 | current.asInstanceOf[js.Dynamic].parentElement.asInstanceOf[dom.Element] 388 | } 389 | None 390 | } 391 | 392 | end VistypImpl 393 | 394 | case class Def( 395 | val offset: Int, 396 | val name: String, 397 | val param: Option[List[syntax.Node]], 398 | val init: syntax.Node, 399 | ) 400 | 401 | case class Instance( 402 | val name: String, 403 | val pos: Option[(Double, Double)], 404 | val ty: String, 405 | val extraArgs: Option[List[syntax.Node]], 406 | val initPos: Option[(Double, Double)] = None, 407 | ) 408 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@esbuild/aix-ppc64@0.21.5": 6 | version "0.21.5" 7 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" 8 | integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== 9 | 10 | "@esbuild/aix-ppc64@0.24.2": 11 | version "0.24.2" 12 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz#38848d3e25afe842a7943643cbcd387cc6e13461" 13 | integrity sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA== 14 | 15 | "@esbuild/android-arm64@0.18.20": 16 | version "0.18.20" 17 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622" 18 | integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ== 19 | 20 | "@esbuild/android-arm64@0.21.5": 21 | version "0.21.5" 22 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" 23 | integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== 24 | 25 | "@esbuild/android-arm64@0.24.2": 26 | version "0.24.2" 27 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz#f592957ae8b5643129fa889c79e69cd8669bb894" 28 | integrity sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg== 29 | 30 | "@esbuild/android-arm@0.18.20": 31 | version "0.18.20" 32 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682" 33 | integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw== 34 | 35 | "@esbuild/android-arm@0.21.5": 36 | version "0.21.5" 37 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" 38 | integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== 39 | 40 | "@esbuild/android-arm@0.24.2": 41 | version "0.24.2" 42 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz#72d8a2063aa630308af486a7e5cbcd1e134335b3" 43 | integrity sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q== 44 | 45 | "@esbuild/android-x64@0.18.20": 46 | version "0.18.20" 47 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2" 48 | integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg== 49 | 50 | "@esbuild/android-x64@0.21.5": 51 | version "0.21.5" 52 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" 53 | integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== 54 | 55 | "@esbuild/android-x64@0.24.2": 56 | version "0.24.2" 57 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz#9a7713504d5f04792f33be9c197a882b2d88febb" 58 | integrity sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw== 59 | 60 | "@esbuild/darwin-arm64@0.18.20": 61 | version "0.18.20" 62 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1" 63 | integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA== 64 | 65 | "@esbuild/darwin-arm64@0.21.5": 66 | version "0.21.5" 67 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" 68 | integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== 69 | 70 | "@esbuild/darwin-arm64@0.24.2": 71 | version "0.24.2" 72 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz#02ae04ad8ebffd6e2ea096181b3366816b2b5936" 73 | integrity sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA== 74 | 75 | "@esbuild/darwin-x64@0.18.20": 76 | version "0.18.20" 77 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d" 78 | integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ== 79 | 80 | "@esbuild/darwin-x64@0.21.5": 81 | version "0.21.5" 82 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" 83 | integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== 84 | 85 | "@esbuild/darwin-x64@0.24.2": 86 | version "0.24.2" 87 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz#9ec312bc29c60e1b6cecadc82bd504d8adaa19e9" 88 | integrity sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA== 89 | 90 | "@esbuild/freebsd-arm64@0.18.20": 91 | version "0.18.20" 92 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54" 93 | integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw== 94 | 95 | "@esbuild/freebsd-arm64@0.21.5": 96 | version "0.21.5" 97 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" 98 | integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== 99 | 100 | "@esbuild/freebsd-arm64@0.24.2": 101 | version "0.24.2" 102 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz#5e82f44cb4906d6aebf24497d6a068cfc152fa00" 103 | integrity sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg== 104 | 105 | "@esbuild/freebsd-x64@0.18.20": 106 | version "0.18.20" 107 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e" 108 | integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ== 109 | 110 | "@esbuild/freebsd-x64@0.21.5": 111 | version "0.21.5" 112 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" 113 | integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== 114 | 115 | "@esbuild/freebsd-x64@0.24.2": 116 | version "0.24.2" 117 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz#3fb1ce92f276168b75074b4e51aa0d8141ecce7f" 118 | integrity sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q== 119 | 120 | "@esbuild/linux-arm64@0.18.20": 121 | version "0.18.20" 122 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0" 123 | integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA== 124 | 125 | "@esbuild/linux-arm64@0.21.5": 126 | version "0.21.5" 127 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" 128 | integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== 129 | 130 | "@esbuild/linux-arm64@0.24.2": 131 | version "0.24.2" 132 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz#856b632d79eb80aec0864381efd29de8fd0b1f43" 133 | integrity sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg== 134 | 135 | "@esbuild/linux-arm@0.18.20": 136 | version "0.18.20" 137 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0" 138 | integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg== 139 | 140 | "@esbuild/linux-arm@0.21.5": 141 | version "0.21.5" 142 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" 143 | integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== 144 | 145 | "@esbuild/linux-arm@0.24.2": 146 | version "0.24.2" 147 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz#c846b4694dc5a75d1444f52257ccc5659021b736" 148 | integrity sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA== 149 | 150 | "@esbuild/linux-ia32@0.18.20": 151 | version "0.18.20" 152 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7" 153 | integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA== 154 | 155 | "@esbuild/linux-ia32@0.21.5": 156 | version "0.21.5" 157 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" 158 | integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== 159 | 160 | "@esbuild/linux-ia32@0.24.2": 161 | version "0.24.2" 162 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz#f8a16615a78826ccbb6566fab9a9606cfd4a37d5" 163 | integrity sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw== 164 | 165 | "@esbuild/linux-loong64@0.18.20": 166 | version "0.18.20" 167 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d" 168 | integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg== 169 | 170 | "@esbuild/linux-loong64@0.21.5": 171 | version "0.21.5" 172 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" 173 | integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== 174 | 175 | "@esbuild/linux-loong64@0.24.2": 176 | version "0.24.2" 177 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz#1c451538c765bf14913512c76ed8a351e18b09fc" 178 | integrity sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ== 179 | 180 | "@esbuild/linux-mips64el@0.18.20": 181 | version "0.18.20" 182 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231" 183 | integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ== 184 | 185 | "@esbuild/linux-mips64el@0.21.5": 186 | version "0.21.5" 187 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" 188 | integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== 189 | 190 | "@esbuild/linux-mips64el@0.24.2": 191 | version "0.24.2" 192 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz#0846edeefbc3d8d50645c51869cc64401d9239cb" 193 | integrity sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw== 194 | 195 | "@esbuild/linux-ppc64@0.18.20": 196 | version "0.18.20" 197 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb" 198 | integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA== 199 | 200 | "@esbuild/linux-ppc64@0.21.5": 201 | version "0.21.5" 202 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" 203 | integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== 204 | 205 | "@esbuild/linux-ppc64@0.24.2": 206 | version "0.24.2" 207 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz#8e3fc54505671d193337a36dfd4c1a23b8a41412" 208 | integrity sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw== 209 | 210 | "@esbuild/linux-riscv64@0.18.20": 211 | version "0.18.20" 212 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6" 213 | integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A== 214 | 215 | "@esbuild/linux-riscv64@0.21.5": 216 | version "0.21.5" 217 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" 218 | integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== 219 | 220 | "@esbuild/linux-riscv64@0.24.2": 221 | version "0.24.2" 222 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz#6a1e92096d5e68f7bb10a0d64bb5b6d1daf9a694" 223 | integrity sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q== 224 | 225 | "@esbuild/linux-s390x@0.18.20": 226 | version "0.18.20" 227 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071" 228 | integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ== 229 | 230 | "@esbuild/linux-s390x@0.21.5": 231 | version "0.21.5" 232 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" 233 | integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== 234 | 235 | "@esbuild/linux-s390x@0.24.2": 236 | version "0.24.2" 237 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz#ab18e56e66f7a3c49cb97d337cd0a6fea28a8577" 238 | integrity sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw== 239 | 240 | "@esbuild/linux-x64@0.18.20": 241 | version "0.18.20" 242 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338" 243 | integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w== 244 | 245 | "@esbuild/linux-x64@0.21.5": 246 | version "0.21.5" 247 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" 248 | integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== 249 | 250 | "@esbuild/linux-x64@0.24.2": 251 | version "0.24.2" 252 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz#8140c9b40da634d380b0b29c837a0b4267aff38f" 253 | integrity sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q== 254 | 255 | "@esbuild/netbsd-arm64@0.24.2": 256 | version "0.24.2" 257 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz#65f19161432bafb3981f5f20a7ff45abb2e708e6" 258 | integrity sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw== 259 | 260 | "@esbuild/netbsd-x64@0.18.20": 261 | version "0.18.20" 262 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1" 263 | integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A== 264 | 265 | "@esbuild/netbsd-x64@0.21.5": 266 | version "0.21.5" 267 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" 268 | integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== 269 | 270 | "@esbuild/netbsd-x64@0.24.2": 271 | version "0.24.2" 272 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz#7a3a97d77abfd11765a72f1c6f9b18f5396bcc40" 273 | integrity sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw== 274 | 275 | "@esbuild/openbsd-arm64@0.24.2": 276 | version "0.24.2" 277 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz#58b00238dd8f123bfff68d3acc53a6ee369af89f" 278 | integrity sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A== 279 | 280 | "@esbuild/openbsd-x64@0.18.20": 281 | version "0.18.20" 282 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae" 283 | integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg== 284 | 285 | "@esbuild/openbsd-x64@0.21.5": 286 | version "0.21.5" 287 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" 288 | integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== 289 | 290 | "@esbuild/openbsd-x64@0.24.2": 291 | version "0.24.2" 292 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz#0ac843fda0feb85a93e288842936c21a00a8a205" 293 | integrity sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA== 294 | 295 | "@esbuild/sunos-x64@0.18.20": 296 | version "0.18.20" 297 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d" 298 | integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ== 299 | 300 | "@esbuild/sunos-x64@0.21.5": 301 | version "0.21.5" 302 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" 303 | integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== 304 | 305 | "@esbuild/sunos-x64@0.24.2": 306 | version "0.24.2" 307 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz#8b7aa895e07828d36c422a4404cc2ecf27fb15c6" 308 | integrity sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig== 309 | 310 | "@esbuild/win32-arm64@0.18.20": 311 | version "0.18.20" 312 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9" 313 | integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg== 314 | 315 | "@esbuild/win32-arm64@0.21.5": 316 | version "0.21.5" 317 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" 318 | integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== 319 | 320 | "@esbuild/win32-arm64@0.24.2": 321 | version "0.24.2" 322 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz#c023afb647cabf0c3ed13f0eddfc4f1d61c66a85" 323 | integrity sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ== 324 | 325 | "@esbuild/win32-ia32@0.18.20": 326 | version "0.18.20" 327 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102" 328 | integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g== 329 | 330 | "@esbuild/win32-ia32@0.21.5": 331 | version "0.21.5" 332 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" 333 | integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== 334 | 335 | "@esbuild/win32-ia32@0.24.2": 336 | version "0.24.2" 337 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz#96c356132d2dda990098c8b8b951209c3cd743c2" 338 | integrity sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA== 339 | 340 | "@esbuild/win32-x64@0.18.20": 341 | version "0.18.20" 342 | resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz" 343 | integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ== 344 | 345 | "@esbuild/win32-x64@0.21.5": 346 | version "0.21.5" 347 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" 348 | integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== 349 | 350 | "@esbuild/win32-x64@0.24.2": 351 | version "0.24.2" 352 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz#34aa0b52d0fbb1a654b596acfa595f0c7b77a77b" 353 | integrity sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg== 354 | 355 | "@jridgewell/sourcemap-codec@^1.5.0": 356 | version "1.5.0" 357 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" 358 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== 359 | 360 | "@myriaddreamin/typst-ts-renderer@0.5.4": 361 | version "0.5.4" 362 | resolved "https://registry.yarnpkg.com/@myriaddreamin/typst-ts-renderer/-/typst-ts-renderer-0.5.4.tgz#2fdaeb158015511007956fc3530ff76fb23ca052" 363 | integrity sha512-Z3wvSv78kWgUdr23EXGXvqa/QeRnPjkmLkpu6Ne8pDWPWjHHL1j+Wy7cTdZos6bhAUQGMkdFbO+ZhHoBepTgcw== 364 | 365 | "@myriaddreamin/typst-ts-web-compiler@0.5.4": 366 | version "0.5.4" 367 | resolved "https://registry.yarnpkg.com/@myriaddreamin/typst-ts-web-compiler/-/typst-ts-web-compiler-0.5.4.tgz#07485fcb94795f73e57b19640e9a392315b38e9b" 368 | integrity sha512-5jSP6EF0tW1NwQk3hRQ35j8ix4lYD92Pg9FpQma1ppz+1C8ziKbo5vtTRPSGDfxXFBI/ouCNkhwa+C30yj025g== 369 | 370 | "@myriaddreamin/typst.ts@0.5.4": 371 | version "0.5.4" 372 | resolved "https://registry.yarnpkg.com/@myriaddreamin/typst.ts/-/typst.ts-0.5.4.tgz#700cd4e1144119d520484de77f21bed6ceee03d5" 373 | integrity sha512-Zn+dwiN+UuhFkl+9vO44fxj1QwHk4yunDrvY48iG3V3pIQsfNVySVOE8wjMSVAh496Mo63BFSIqzZRQj2ShS8g== 374 | dependencies: 375 | idb "^7.1.1" 376 | 377 | "@rollup/rollup-android-arm-eabi@4.29.1": 378 | version "4.29.1" 379 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz#9bd38df6a29afb7f0336d988bc8112af0c8816c0" 380 | integrity sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw== 381 | 382 | "@rollup/rollup-android-arm64@4.29.1": 383 | version "4.29.1" 384 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz#bd1a98390e15b76eeef907175a37c5f0f9e4d214" 385 | integrity sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew== 386 | 387 | "@rollup/rollup-darwin-arm64@4.29.1": 388 | version "4.29.1" 389 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz#bc6fa8a2cc77b5f367424e5e994e3537524e6879" 390 | integrity sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw== 391 | 392 | "@rollup/rollup-darwin-x64@4.29.1": 393 | version "4.29.1" 394 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz#76059c91f06b17406347b127df10f065283b2e61" 395 | integrity sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng== 396 | 397 | "@rollup/rollup-freebsd-arm64@4.29.1": 398 | version "4.29.1" 399 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz#83178315c0be4b4c8c1fd835e1952d2dc1eb4e6e" 400 | integrity sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw== 401 | 402 | "@rollup/rollup-freebsd-x64@4.29.1": 403 | version "4.29.1" 404 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz#1ef24fa0576bf7899a0a0a649156606dbd7a0d46" 405 | integrity sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w== 406 | 407 | "@rollup/rollup-linux-arm-gnueabihf@4.29.1": 408 | version "4.29.1" 409 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz#443a6f5681bf4611caae42988994a6d8ee676216" 410 | integrity sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A== 411 | 412 | "@rollup/rollup-linux-arm-musleabihf@4.29.1": 413 | version "4.29.1" 414 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz#9738b27184102228637a683e5f35b22ea352394f" 415 | integrity sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ== 416 | 417 | "@rollup/rollup-linux-arm64-gnu@4.29.1": 418 | version "4.29.1" 419 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz#b5e9d5e30ff36a19bedd29c715ba18a1889ff269" 420 | integrity sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA== 421 | 422 | "@rollup/rollup-linux-arm64-musl@4.29.1": 423 | version "4.29.1" 424 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz#1d8f68f0829b57f746ec03432ad046f1af014a98" 425 | integrity sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA== 426 | 427 | "@rollup/rollup-linux-loongarch64-gnu@4.29.1": 428 | version "4.29.1" 429 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz#07027feb883408e74a3002c8e50caaedd288ae38" 430 | integrity sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw== 431 | 432 | "@rollup/rollup-linux-powerpc64le-gnu@4.29.1": 433 | version "4.29.1" 434 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz#544ce1b0847a9c1240425e86f33daceac7ec4e12" 435 | integrity sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w== 436 | 437 | "@rollup/rollup-linux-riscv64-gnu@4.29.1": 438 | version "4.29.1" 439 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz#64be13d51852ec1e2dfbd25d997ed5f42f35ea6d" 440 | integrity sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ== 441 | 442 | "@rollup/rollup-linux-s390x-gnu@4.29.1": 443 | version "4.29.1" 444 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz#31f51e1e05c6264552d03875d9e2e673f0fd86e3" 445 | integrity sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g== 446 | 447 | "@rollup/rollup-linux-x64-gnu@4.29.1": 448 | version "4.29.1" 449 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz#f4c95b26f4ad69ebdb64b42f0ae4da2a0f617958" 450 | integrity sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ== 451 | 452 | "@rollup/rollup-linux-x64-musl@4.29.1": 453 | version "4.29.1" 454 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz#ab7be89192f72beb9ea6e2386186fefde4f69d82" 455 | integrity sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA== 456 | 457 | "@rollup/rollup-win32-arm64-msvc@4.29.1": 458 | version "4.29.1" 459 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz#7f12efb8240b238346951559998802722944421e" 460 | integrity sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig== 461 | 462 | "@rollup/rollup-win32-ia32-msvc@4.29.1": 463 | version "4.29.1" 464 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz#353d14d6eee943004d129796e4feddd3aa260921" 465 | integrity sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng== 466 | 467 | "@rollup/rollup-win32-x64-msvc@4.29.1": 468 | version "4.29.1" 469 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz#c82f04a09ba481e13857d6f2516e072aaa51b7f4" 470 | integrity sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg== 471 | 472 | "@scala-js/vite-plugin-scalajs@^1.0.0": 473 | version "1.0.0" 474 | resolved "https://registry.yarnpkg.com/@scala-js/vite-plugin-scalajs/-/vite-plugin-scalajs-1.0.0.tgz#2a5b99a3fffec48cf94d3e6166ed59161bd19e33" 475 | integrity sha512-QqeOXFWiwZyl4LrtAg7ZMeoShVWTD+4qcmuv0M7QNCu8QYzf+h3ysozbmyWYJKVpxJYMLnuSZZSiygD8Tzh+eg== 476 | dependencies: 477 | vite "^4.1.4" 478 | 479 | "@types/estree@1.0.6", "@types/estree@^1.0.0": 480 | version "1.0.6" 481 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" 482 | integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== 483 | 484 | "@types/web@^0.0.188": 485 | version "0.0.188" 486 | resolved "https://registry.yarnpkg.com/@types/web/-/web-0.0.188.tgz#ae97a6cf2b7e957ae6cd2cdb8cd3910e8b217b19" 487 | integrity sha512-dKowKMo4P0W6f2U5i66uJ+/MlSHzBnznI0ExP1xnpcF/9/CJQT4VYvIDqz7ocWDvd0pB1QPgjOe4dVSycQrbuA== 488 | 489 | "@vitest/expect@2.1.8": 490 | version "2.1.8" 491 | resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.8.tgz#13fad0e8d5a0bf0feb675dcf1d1f1a36a1773bc1" 492 | integrity sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw== 493 | dependencies: 494 | "@vitest/spy" "2.1.8" 495 | "@vitest/utils" "2.1.8" 496 | chai "^5.1.2" 497 | tinyrainbow "^1.2.0" 498 | 499 | "@vitest/mocker@2.1.8": 500 | version "2.1.8" 501 | resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.8.tgz#51dec42ac244e949d20009249e033e274e323f73" 502 | integrity sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA== 503 | dependencies: 504 | "@vitest/spy" "2.1.8" 505 | estree-walker "^3.0.3" 506 | magic-string "^0.30.12" 507 | 508 | "@vitest/pretty-format@2.1.8", "@vitest/pretty-format@^2.1.8": 509 | version "2.1.8" 510 | resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.8.tgz#88f47726e5d0cf4ba873d50c135b02e4395e2bca" 511 | integrity sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ== 512 | dependencies: 513 | tinyrainbow "^1.2.0" 514 | 515 | "@vitest/runner@2.1.8": 516 | version "2.1.8" 517 | resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.8.tgz#b0e2dd29ca49c25e9323ea2a45a5125d8729759f" 518 | integrity sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg== 519 | dependencies: 520 | "@vitest/utils" "2.1.8" 521 | pathe "^1.1.2" 522 | 523 | "@vitest/snapshot@2.1.8": 524 | version "2.1.8" 525 | resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.8.tgz#d5dc204f4b95dc8b5e468b455dfc99000047d2de" 526 | integrity sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg== 527 | dependencies: 528 | "@vitest/pretty-format" "2.1.8" 529 | magic-string "^0.30.12" 530 | pathe "^1.1.2" 531 | 532 | "@vitest/spy@2.1.8": 533 | version "2.1.8" 534 | resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.8.tgz#bc41af3e1e6a41ae3b67e51f09724136b88fa447" 535 | integrity sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg== 536 | dependencies: 537 | tinyspy "^3.0.2" 538 | 539 | "@vitest/utils@2.1.8": 540 | version "2.1.8" 541 | resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.8.tgz#f8ef85525f3362ebd37fd25d268745108d6ae388" 542 | integrity sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA== 543 | dependencies: 544 | "@vitest/pretty-format" "2.1.8" 545 | loupe "^3.1.2" 546 | tinyrainbow "^1.2.0" 547 | 548 | assertion-error@^2.0.1: 549 | version "2.0.1" 550 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" 551 | integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== 552 | 553 | braces@^3.0.3: 554 | version "3.0.3" 555 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" 556 | integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== 557 | dependencies: 558 | fill-range "^7.1.1" 559 | 560 | cac@^6.7.14: 561 | version "6.7.14" 562 | resolved "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz" 563 | integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== 564 | 565 | chai@^5.1.2: 566 | version "5.1.2" 567 | resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" 568 | integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== 569 | dependencies: 570 | assertion-error "^2.0.1" 571 | check-error "^2.1.1" 572 | deep-eql "^5.0.1" 573 | loupe "^3.1.0" 574 | pathval "^2.0.0" 575 | 576 | check-error@^2.1.1: 577 | version "2.1.1" 578 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" 579 | integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== 580 | 581 | debug@^4.3.7: 582 | version "4.4.0" 583 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" 584 | integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== 585 | dependencies: 586 | ms "^2.1.3" 587 | 588 | deep-eql@^5.0.1: 589 | version "5.0.2" 590 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" 591 | integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== 592 | 593 | es-module-lexer@^1.5.4: 594 | version "1.6.0" 595 | resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.6.0.tgz#da49f587fd9e68ee2404fe4e256c0c7d3a81be21" 596 | integrity sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ== 597 | 598 | esbuild@^0.18.10: 599 | version "0.18.20" 600 | resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz" 601 | integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA== 602 | optionalDependencies: 603 | "@esbuild/android-arm" "0.18.20" 604 | "@esbuild/android-arm64" "0.18.20" 605 | "@esbuild/android-x64" "0.18.20" 606 | "@esbuild/darwin-arm64" "0.18.20" 607 | "@esbuild/darwin-x64" "0.18.20" 608 | "@esbuild/freebsd-arm64" "0.18.20" 609 | "@esbuild/freebsd-x64" "0.18.20" 610 | "@esbuild/linux-arm" "0.18.20" 611 | "@esbuild/linux-arm64" "0.18.20" 612 | "@esbuild/linux-ia32" "0.18.20" 613 | "@esbuild/linux-loong64" "0.18.20" 614 | "@esbuild/linux-mips64el" "0.18.20" 615 | "@esbuild/linux-ppc64" "0.18.20" 616 | "@esbuild/linux-riscv64" "0.18.20" 617 | "@esbuild/linux-s390x" "0.18.20" 618 | "@esbuild/linux-x64" "0.18.20" 619 | "@esbuild/netbsd-x64" "0.18.20" 620 | "@esbuild/openbsd-x64" "0.18.20" 621 | "@esbuild/sunos-x64" "0.18.20" 622 | "@esbuild/win32-arm64" "0.18.20" 623 | "@esbuild/win32-ia32" "0.18.20" 624 | "@esbuild/win32-x64" "0.18.20" 625 | 626 | esbuild@^0.21.3: 627 | version "0.21.5" 628 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" 629 | integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== 630 | optionalDependencies: 631 | "@esbuild/aix-ppc64" "0.21.5" 632 | "@esbuild/android-arm" "0.21.5" 633 | "@esbuild/android-arm64" "0.21.5" 634 | "@esbuild/android-x64" "0.21.5" 635 | "@esbuild/darwin-arm64" "0.21.5" 636 | "@esbuild/darwin-x64" "0.21.5" 637 | "@esbuild/freebsd-arm64" "0.21.5" 638 | "@esbuild/freebsd-x64" "0.21.5" 639 | "@esbuild/linux-arm" "0.21.5" 640 | "@esbuild/linux-arm64" "0.21.5" 641 | "@esbuild/linux-ia32" "0.21.5" 642 | "@esbuild/linux-loong64" "0.21.5" 643 | "@esbuild/linux-mips64el" "0.21.5" 644 | "@esbuild/linux-ppc64" "0.21.5" 645 | "@esbuild/linux-riscv64" "0.21.5" 646 | "@esbuild/linux-s390x" "0.21.5" 647 | "@esbuild/linux-x64" "0.21.5" 648 | "@esbuild/netbsd-x64" "0.21.5" 649 | "@esbuild/openbsd-x64" "0.21.5" 650 | "@esbuild/sunos-x64" "0.21.5" 651 | "@esbuild/win32-arm64" "0.21.5" 652 | "@esbuild/win32-ia32" "0.21.5" 653 | "@esbuild/win32-x64" "0.21.5" 654 | 655 | esbuild@^0.24.2: 656 | version "0.24.2" 657 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.24.2.tgz#b5b55bee7de017bff5fb8a4e3e44f2ebe2c3567d" 658 | integrity sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA== 659 | optionalDependencies: 660 | "@esbuild/aix-ppc64" "0.24.2" 661 | "@esbuild/android-arm" "0.24.2" 662 | "@esbuild/android-arm64" "0.24.2" 663 | "@esbuild/android-x64" "0.24.2" 664 | "@esbuild/darwin-arm64" "0.24.2" 665 | "@esbuild/darwin-x64" "0.24.2" 666 | "@esbuild/freebsd-arm64" "0.24.2" 667 | "@esbuild/freebsd-x64" "0.24.2" 668 | "@esbuild/linux-arm" "0.24.2" 669 | "@esbuild/linux-arm64" "0.24.2" 670 | "@esbuild/linux-ia32" "0.24.2" 671 | "@esbuild/linux-loong64" "0.24.2" 672 | "@esbuild/linux-mips64el" "0.24.2" 673 | "@esbuild/linux-ppc64" "0.24.2" 674 | "@esbuild/linux-riscv64" "0.24.2" 675 | "@esbuild/linux-s390x" "0.24.2" 676 | "@esbuild/linux-x64" "0.24.2" 677 | "@esbuild/netbsd-arm64" "0.24.2" 678 | "@esbuild/netbsd-x64" "0.24.2" 679 | "@esbuild/openbsd-arm64" "0.24.2" 680 | "@esbuild/openbsd-x64" "0.24.2" 681 | "@esbuild/sunos-x64" "0.24.2" 682 | "@esbuild/win32-arm64" "0.24.2" 683 | "@esbuild/win32-ia32" "0.24.2" 684 | "@esbuild/win32-x64" "0.24.2" 685 | 686 | estree-walker@^3.0.3: 687 | version "3.0.3" 688 | resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" 689 | integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== 690 | dependencies: 691 | "@types/estree" "^1.0.0" 692 | 693 | expect-type@^1.1.0: 694 | version "1.1.0" 695 | resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75" 696 | integrity sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA== 697 | 698 | fill-range@^7.1.1: 699 | version "7.1.1" 700 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" 701 | integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== 702 | dependencies: 703 | to-regex-range "^5.0.1" 704 | 705 | fsevents@~2.3.2, fsevents@~2.3.3: 706 | version "2.3.3" 707 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 708 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 709 | 710 | idb@^7.1.1: 711 | version "7.1.1" 712 | resolved "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz" 713 | integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== 714 | 715 | is-number@^7.0.0: 716 | version "7.0.0" 717 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 718 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 719 | 720 | loupe@^3.1.0, loupe@^3.1.2: 721 | version "3.1.2" 722 | resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" 723 | integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== 724 | 725 | magic-string@^0.30.12: 726 | version "0.30.17" 727 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" 728 | integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== 729 | dependencies: 730 | "@jridgewell/sourcemap-codec" "^1.5.0" 731 | 732 | micromatch@^4.0.8: 733 | version "4.0.8" 734 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" 735 | integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== 736 | dependencies: 737 | braces "^3.0.3" 738 | picomatch "^2.3.1" 739 | 740 | ms@^2.1.3: 741 | version "2.1.3" 742 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 743 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 744 | 745 | nanoid@^3.3.6: 746 | version "3.3.7" 747 | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" 748 | integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== 749 | 750 | nanoid@^3.3.7: 751 | version "3.3.8" 752 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" 753 | integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== 754 | 755 | pathe@^1.1.2: 756 | version "1.1.2" 757 | resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" 758 | integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== 759 | 760 | pathval@^2.0.0: 761 | version "2.0.0" 762 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" 763 | integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== 764 | 765 | picocolors@^1.0.0: 766 | version "1.0.0" 767 | resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" 768 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== 769 | 770 | picocolors@^1.1.1: 771 | version "1.1.1" 772 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" 773 | integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== 774 | 775 | picomatch@^2.3.1: 776 | version "2.3.1" 777 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 778 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 779 | 780 | postcss@^8.4.27: 781 | version "8.4.31" 782 | resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" 783 | integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== 784 | dependencies: 785 | nanoid "^3.3.6" 786 | picocolors "^1.0.0" 787 | source-map-js "^1.0.2" 788 | 789 | postcss@^8.4.43, postcss@^8.4.49: 790 | version "8.4.49" 791 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" 792 | integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== 793 | dependencies: 794 | nanoid "^3.3.7" 795 | picocolors "^1.1.1" 796 | source-map-js "^1.2.1" 797 | 798 | rollup@^3.27.1: 799 | version "3.29.4" 800 | resolved "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz" 801 | integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== 802 | optionalDependencies: 803 | fsevents "~2.3.2" 804 | 805 | rollup@^4.20.0, rollup@^4.23.0: 806 | version "4.29.1" 807 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.29.1.tgz#a9aaaece817e5f778489e5bf82e379cc8a5c05bc" 808 | integrity sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw== 809 | dependencies: 810 | "@types/estree" "1.0.6" 811 | optionalDependencies: 812 | "@rollup/rollup-android-arm-eabi" "4.29.1" 813 | "@rollup/rollup-android-arm64" "4.29.1" 814 | "@rollup/rollup-darwin-arm64" "4.29.1" 815 | "@rollup/rollup-darwin-x64" "4.29.1" 816 | "@rollup/rollup-freebsd-arm64" "4.29.1" 817 | "@rollup/rollup-freebsd-x64" "4.29.1" 818 | "@rollup/rollup-linux-arm-gnueabihf" "4.29.1" 819 | "@rollup/rollup-linux-arm-musleabihf" "4.29.1" 820 | "@rollup/rollup-linux-arm64-gnu" "4.29.1" 821 | "@rollup/rollup-linux-arm64-musl" "4.29.1" 822 | "@rollup/rollup-linux-loongarch64-gnu" "4.29.1" 823 | "@rollup/rollup-linux-powerpc64le-gnu" "4.29.1" 824 | "@rollup/rollup-linux-riscv64-gnu" "4.29.1" 825 | "@rollup/rollup-linux-s390x-gnu" "4.29.1" 826 | "@rollup/rollup-linux-x64-gnu" "4.29.1" 827 | "@rollup/rollup-linux-x64-musl" "4.29.1" 828 | "@rollup/rollup-win32-arm64-msvc" "4.29.1" 829 | "@rollup/rollup-win32-ia32-msvc" "4.29.1" 830 | "@rollup/rollup-win32-x64-msvc" "4.29.1" 831 | fsevents "~2.3.2" 832 | 833 | siginfo@^2.0.0: 834 | version "2.0.0" 835 | resolved "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz" 836 | integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== 837 | 838 | source-map-js@^1.0.2: 839 | version "1.0.2" 840 | resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" 841 | integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== 842 | 843 | source-map-js@^1.2.1: 844 | version "1.2.1" 845 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" 846 | integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== 847 | 848 | stackback@0.0.2: 849 | version "0.0.2" 850 | resolved "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz" 851 | integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== 852 | 853 | std-env@^3.8.0: 854 | version "3.8.0" 855 | resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.0.tgz#b56ffc1baf1a29dcc80a3bdf11d7fca7c315e7d5" 856 | integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== 857 | 858 | tinybench@^2.9.0: 859 | version "2.9.0" 860 | resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" 861 | integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== 862 | 863 | tinyexec@^0.3.1: 864 | version "0.3.2" 865 | resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2" 866 | integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA== 867 | 868 | tinypool@^1.0.1: 869 | version "1.0.2" 870 | resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.2.tgz#706193cc532f4c100f66aa00b01c42173d9051b2" 871 | integrity sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA== 872 | 873 | tinyrainbow@^1.2.0: 874 | version "1.2.0" 875 | resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" 876 | integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== 877 | 878 | tinyspy@^3.0.2: 879 | version "3.0.2" 880 | resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" 881 | integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== 882 | 883 | to-regex-range@^5.0.1: 884 | version "5.0.1" 885 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 886 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 887 | dependencies: 888 | is-number "^7.0.0" 889 | 890 | vite-node@2.1.8: 891 | version "2.1.8" 892 | resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.8.tgz#9495ca17652f6f7f95ca7c4b568a235e0c8dbac5" 893 | integrity sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg== 894 | dependencies: 895 | cac "^6.7.14" 896 | debug "^4.3.7" 897 | es-module-lexer "^1.5.4" 898 | pathe "^1.1.2" 899 | vite "^5.0.0" 900 | 901 | vite-plugin-singlefile@^2.1.0: 902 | version "2.1.0" 903 | resolved "https://registry.yarnpkg.com/vite-plugin-singlefile/-/vite-plugin-singlefile-2.1.0.tgz#b22da5b005da05fd2742a3145e70c9a4ef7b5960" 904 | integrity sha512-7tJo+UgZABlKpY/nubth/wxJ4+pUGREPnEwNOknxwl2MM0zTvF14KTU4Ln1lc140gjLLV5mjDrvuoquU7OZqCg== 905 | dependencies: 906 | micromatch "^4.0.8" 907 | 908 | vite@^4.1.4: 909 | version "4.5.5" 910 | resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.5.tgz#639b9feca5c0a3bfe3c60cb630ef28bf219d742e" 911 | integrity sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ== 912 | dependencies: 913 | esbuild "^0.18.10" 914 | postcss "^8.4.27" 915 | rollup "^3.27.1" 916 | optionalDependencies: 917 | fsevents "~2.3.2" 918 | 919 | vite@^5.0.0: 920 | version "5.4.11" 921 | resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5" 922 | integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q== 923 | dependencies: 924 | esbuild "^0.21.3" 925 | postcss "^8.4.43" 926 | rollup "^4.20.0" 927 | optionalDependencies: 928 | fsevents "~2.3.3" 929 | 930 | vite@^6.0.6: 931 | version "6.0.6" 932 | resolved "https://registry.yarnpkg.com/vite/-/vite-6.0.6.tgz#a851674fcff55b0c1962f72082354b8802e48505" 933 | integrity sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ== 934 | dependencies: 935 | esbuild "^0.24.2" 936 | postcss "^8.4.49" 937 | rollup "^4.23.0" 938 | optionalDependencies: 939 | fsevents "~2.3.3" 940 | 941 | vitest@^2.1.8: 942 | version "2.1.8" 943 | resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.8.tgz#2e6a00bc24833574d535c96d6602fb64163092fa" 944 | integrity sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ== 945 | dependencies: 946 | "@vitest/expect" "2.1.8" 947 | "@vitest/mocker" "2.1.8" 948 | "@vitest/pretty-format" "^2.1.8" 949 | "@vitest/runner" "2.1.8" 950 | "@vitest/snapshot" "2.1.8" 951 | "@vitest/spy" "2.1.8" 952 | "@vitest/utils" "2.1.8" 953 | chai "^5.1.2" 954 | debug "^4.3.7" 955 | expect-type "^1.1.0" 956 | magic-string "^0.30.12" 957 | pathe "^1.1.2" 958 | std-env "^3.8.0" 959 | tinybench "^2.9.0" 960 | tinyexec "^0.3.1" 961 | tinypool "^1.0.1" 962 | tinyrainbow "^1.2.0" 963 | vite "^5.0.0" 964 | vite-node "2.1.8" 965 | why-is-node-running "^2.3.0" 966 | 967 | why-is-node-running@^2.3.0: 968 | version "2.3.0" 969 | resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" 970 | integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== 971 | dependencies: 972 | siginfo "^2.0.0" 973 | stackback "0.0.2" 974 | -------------------------------------------------------------------------------- /assets/tokyo-night.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tokyo Night", 3 | "author": "Enkia", 4 | "maintainers": [ 5 | "Enkia " 6 | ], 7 | "type": "dark", 8 | "semanticTokenColors": { 9 | "parameter.declaration": { 10 | "foreground": "#e0af68" 11 | }, 12 | "parameter": { 13 | "foreground": "#d9d4cd" 14 | }, 15 | "property.declaration": { 16 | "foreground": "#73daca" 17 | }, 18 | "property.defaultLibrary": { 19 | "foreground": "#2ac3de" 20 | }, 21 | "*.defaultLibrary": { 22 | "foreground": "#2ac3de" 23 | }, 24 | "variable.defaultLibrary": { 25 | "foreground": "#2ac3de" 26 | }, 27 | "variable.declaration": { 28 | "foreground": "#bb9af7" 29 | }, 30 | "variable": { 31 | "foreground": "#c0caf5" 32 | } 33 | }, 34 | "semanticClass": "tokyo-night", 35 | "colors": { 36 | "foreground": "#787c99", 37 | "descriptionForeground": "#515670", 38 | "focusBorder": "#545c7e33", 39 | "errorForeground": "#515670", 40 | "widget.shadow": "#ffffff00", 41 | "scrollbar.shadow": "#00000033", 42 | "badge.background": "#7e83b230", 43 | "badge.foreground": "#acb0d0", 44 | "icon.foreground": "#787c99", 45 | "settings.headerForeground": "#6183bb", 46 | "window.activeBorder": "#0d0f17", 47 | "window.inactiveBorder": "#0d0f17", 48 | "sash.hoverBorder": "#29355a", 49 | "toolbar.activeBackground": "#202330", 50 | "toolbar.hoverBackground": "#202330", 51 | "extensionButton.prominentBackground": "#3d59a1DD", 52 | "extensionButton.prominentHoverBackground": "#3d59a1AA", 53 | "extensionButton.prominentForeground": "#ffffff", 54 | "extensionBadge.remoteBackground": "#3d59a1", 55 | "extensionBadge.remoteForeground": "#ffffff", 56 | "button.background": "#3d59a1dd", 57 | "button.hoverBackground": "#3d59a1AA", 58 | "button.secondaryBackground": "#3b3e52", 59 | "button.foreground": "#ffffff", 60 | "progressBar.background": "#3d59a1", 61 | "input.background": "#14141b", 62 | "input.foreground": "#a9b1d6", 63 | "input.border": "#0f0f14", 64 | "input.placeholderForeground": "#787c998A", 65 | "inputOption.activeForeground": "#c0caf5", 66 | "inputOption.activeBackground": "#3d59a144", 67 | "inputValidation.infoForeground": "#bbc2e0", 68 | "inputValidation.infoBackground": "#3d59a15c", 69 | "inputValidation.infoBorder": "#3d59a1", 70 | "inputValidation.warningForeground": "#000000", 71 | "inputValidation.warningBackground": "#c2985b", 72 | "inputValidation.warningBorder": "#e0af68", 73 | "inputValidation.errorForeground": "#bbc2e0", 74 | "inputValidation.errorBackground": "#85353e", 75 | "inputValidation.errorBorder": "#963c47", 76 | "dropdown.foreground": "#787c99", 77 | "dropdown.background": "#14141b", 78 | "dropdown.listBackground": "#14141b", 79 | "activityBar.background": "#16161e", 80 | "activityBar.foreground": "#787c99", 81 | "activityBar.inactiveForeground": "#3b3e52", 82 | "activityBar.border": "#16161e", 83 | "activityBarBadge.background": "#3d59a1", 84 | "activityBarBadge.foreground": "#fff", 85 | "tree.indentGuidesStroke": "#2b2b3b", 86 | "sideBar.foreground": "#787c99", 87 | "sideBar.background": "#16161e", 88 | "sideBar.border": "#101014", 89 | "sideBarTitle.foreground": "#787c99", 90 | "sideBarSectionHeader.background": "#16161e", 91 | "sideBarSectionHeader.foreground": "#a9b1d6", 92 | "sideBarSectionHeader.border": "#101014", 93 | "sideBar.dropBackground": "#1e202e", 94 | "list.dropBackground": "#1e202e", 95 | "list.deemphasizedForeground": "#787c99", 96 | "list.activeSelectionBackground": "#202330", 97 | "list.activeSelectionForeground": "#a9b1d6", 98 | "list.inactiveSelectionBackground": "#1c1d29", 99 | "list.inactiveSelectionForeground": "#a9b1d6", 100 | "list.focusBackground": "#1c1d29", 101 | "list.focusForeground": "#a9b1d6", 102 | "list.hoverBackground": "#13131a", 103 | "list.hoverForeground": "#a9b1d6", 104 | "list.highlightForeground": "#668ac4", 105 | "list.invalidItemForeground": "#c97018", 106 | "list.errorForeground": "#bb616b", 107 | "list.warningForeground": "#c49a5a", 108 | "listFilterWidget.background": "#101014", 109 | "listFilterWidget.outline": "#3d59a1", 110 | "listFilterWidget.noMatchesOutline": "#a6333f", 111 | "pickerGroup.foreground": "#a9b1d6", 112 | "pickerGroup.border": "#101014", 113 | "scrollbarSlider.background": "#868bc415", 114 | "scrollbarSlider.hoverBackground": "#868bc410", 115 | "scrollbarSlider.activeBackground": "#868bc422", 116 | "editorBracketHighlight.foreground1": "#698cd6", 117 | "editorBracketHighlight.foreground2": "#68b3de", 118 | "editorBracketHighlight.foreground3": "#9a7ecc", 119 | "editorBracketHighlight.foreground4": "#25aac2", 120 | "editorBracketHighlight.foreground5": "#80a856", 121 | "editorBracketHighlight.foreground6": "#c49a5a", 122 | "editorBracketHighlight.unexpectedBracket.foreground": "#db4b4b", 123 | "editorBracketPairGuide.activeBackground1": "#698cd6", 124 | "editorBracketPairGuide.activeBackground2": "#68b3de", 125 | "editorBracketPairGuide.activeBackground3": "#9a7ecc", 126 | "editorBracketPairGuide.activeBackground4": "#25aac2", 127 | "editorBracketPairGuide.activeBackground5": "#80a856", 128 | "editorBracketPairGuide.activeBackground6": "#c49a5a", 129 | "selection.background": "#515c7e40", 130 | "editor.background": "#1a1b26", 131 | "editor.foreground": "#a9b1d6", 132 | "editor.foldBackground": "#1111174a", 133 | "editorLink.activeForeground": "#acb0d0", 134 | "editor.selectionBackground": "#515c7e40", 135 | "editor.inactiveSelectionBackground": "#515c7e25", 136 | "editor.findMatchBackground": "#3d59a166", 137 | "editor.findMatchBorder": "#e0af68", 138 | "editor.findMatchHighlightBackground": "#3d59a166", 139 | "editor.findRangeHighlightBackground": "#515c7e33", 140 | "editor.rangeHighlightBackground": "#515c7e20", 141 | "editor.wordHighlightBackground": "#515c7e44", 142 | "editor.wordHighlightStrongBackground": "#515c7e55", 143 | "editor.selectionHighlightBackground": "#515c7e44", 144 | "editorCursor.foreground": "#c0caf5", 145 | "editorIndentGuide.background": "#1e202e", 146 | "editorIndentGuide.activeBackground": "#363b54", 147 | "editorLineNumber.foreground": "#363b54", 148 | "editorLineNumber.activeForeground": "#737aa2", 149 | "editor.lineHighlightBackground": "#1e202e", 150 | "editorWhitespace.foreground": "#363b54", 151 | "editorMarkerNavigation.background": "#16161e", 152 | "editorHoverWidget.background": "#16161e", 153 | "editorHoverWidget.border": "#101014", 154 | "editorBracketMatch.background": "#16161e", 155 | "editorBracketMatch.border": "#42465d", 156 | "editorOverviewRuler.border": "#101014", 157 | "editorOverviewRuler.errorForeground": "#db4b4b", 158 | "editorOverviewRuler.warningForeground": "#e0af68", 159 | "editorOverviewRuler.infoForeground": "#1abc9c", 160 | "editorOverviewRuler.bracketMatchForeground": "#101014", 161 | "editorOverviewRuler.findMatchForeground": "#a9b1d644", 162 | "editorOverviewRuler.rangeHighlightForeground": "#a9b1d644", 163 | "editorOverviewRuler.selectionHighlightForeground": "#a9b1d622", 164 | "editorOverviewRuler.wordHighlightForeground": "#bb9af755", 165 | "editorOverviewRuler.wordHighlightStrongForeground": "#bb9af766", 166 | "editorOverviewRuler.modifiedForeground": "#394b70", 167 | "editorOverviewRuler.addedForeground": "#164846", 168 | "editorOverviewRuler.deletedForeground": "#703438", 169 | "editorRuler.foreground": "#101014", 170 | "editorError.foreground": "#db4b4b", 171 | "editorWarning.foreground": "#e0af68", 172 | "editorInfo.foreground": "#0da0ba", 173 | "editorHint.foreground": "#0da0ba", 174 | "editorGutter.modifiedBackground": "#394b70", 175 | "editorGutter.addedBackground": "#164846", 176 | "editorGutter.deletedBackground": "#823c41", 177 | "editorGhostText.foreground": "#646e9c", 178 | "minimapGutter.modifiedBackground": "#425882", 179 | "minimapGutter.addedBackground": "#1C5957", 180 | "minimapGutter.deletedBackground": "#944449", 181 | "editorGroup.border": "#101014", 182 | "editorGroup.dropBackground": "#1e202e", 183 | "editorGroupHeader.tabsBorder": "#101014", 184 | "editorGroupHeader.tabsBackground": "#16161e", 185 | "editorGroupHeader.noTabsBackground": "#16161e", 186 | "editorGroupHeader.border": "#101014", 187 | "editorPane.background": "#16161e", 188 | "editorWidget.background": "#16161e", 189 | "editorWidget.resizeBorder": "#545c7e33", 190 | "editorSuggestWidget.background": "#16161e", 191 | "editorSuggestWidget.border": "#101014", 192 | "editorSuggestWidget.selectedBackground": "#20222c", 193 | "editorSuggestWidget.highlightForeground": "#6183bb", 194 | "editorCodeLens.foreground": "#484f70", 195 | "editorLightBulb.foreground": "#e0af68", 196 | "editorLightBulbAutoFix.foreground": "#e0af68", 197 | "peekView.border": "#101014", 198 | "peekViewEditor.background": "#16161e", 199 | "peekViewEditor.matchHighlightBackground": "#3d59a166", 200 | "peekViewTitle.background": "#101014", 201 | "peekViewTitleLabel.foreground": "#a9b1d6", 202 | "peekViewTitleDescription.foreground": "#787c99", 203 | "peekViewResult.background": "#101014", 204 | "peekViewResult.selectionForeground": "#a9b1d6", 205 | "peekViewResult.selectionBackground": "#3d59a133", 206 | "peekViewResult.lineForeground": "#a9b1d6", 207 | "peekViewResult.fileForeground": "#787c99", 208 | "peekViewResult.matchHighlightBackground": "#3d59a166", 209 | "diffEditor.insertedTextBackground": "#41a6b520", 210 | "diffEditor.removedTextBackground": "#db4b4b22", 211 | "diffEditor.insertedLineBackground": "#41a6b520", 212 | "diffEditor.removedLineBackground": "#db4b4b22", 213 | "diffEditorGutter.insertedLineBackground": "#41a6b525", 214 | "diffEditorGutter.removedLineBackground": "#db4b4b22", 215 | "diffEditorOverview.insertedForeground": "#41a6b525", 216 | "diffEditorOverview.removedForeground": "#db4b4b22", 217 | "diffEditor.diagonalFill": "#292e42", 218 | "breadcrumb.background": "#16161e", 219 | "breadcrumbPicker.background": "#16161e", 220 | "breadcrumb.foreground": "#515670", 221 | "breadcrumb.focusForeground": "#a9b1d6", 222 | "breadcrumb.activeSelectionForeground": "#a9b1d6", 223 | "tab.activeBackground": "#16161e", 224 | "tab.inactiveBackground": "#16161e", 225 | "tab.activeForeground": "#a9b1d6", 226 | "tab.hoverForeground": "#a9b1d6", 227 | "tab.activeBorder": "#3d59a1", 228 | "tab.inactiveForeground": "#787c99", 229 | "tab.border": "#101014", 230 | "tab.unfocusedActiveForeground": "#a9b1d6", 231 | "tab.unfocusedInactiveForeground": "#787c99", 232 | "tab.unfocusedHoverForeground": "#a9b1d6", 233 | "tab.activeModifiedBorder": "#1a1b26", 234 | "tab.inactiveModifiedBorder": "#1f202e", 235 | "tab.unfocusedActiveBorder": "#1f202e", 236 | "tab.lastPinnedBorder": "#222333", 237 | "panel.background": "#16161e", 238 | "panel.border": "#101014", 239 | "panelTitle.activeForeground": "#787c99", 240 | "panelTitle.inactiveForeground": "#42465d", 241 | "panelTitle.activeBorder": "#16161e", 242 | "panelInput.border": "#16161e", 243 | "statusBar.foreground": "#787c99", 244 | "statusBar.background": "#16161e", 245 | "statusBar.border": "#101014", 246 | "statusBar.noFolderBackground": "#16161e", 247 | "statusBar.debuggingBackground": "#16161e", 248 | "statusBar.debuggingForeground": "#787c99", 249 | "statusBarItem.activeBackground": "#101014", 250 | "statusBarItem.hoverBackground": "#20222c", 251 | "statusBarItem.prominentBackground": "#101014", 252 | "statusBarItem.prominentHoverBackground": "#20222c", 253 | "titleBar.activeForeground": "#787c99", 254 | "titleBar.inactiveForeground": "#787c99", 255 | "titleBar.activeBackground": "#16161e", 256 | "titleBar.inactiveBackground": "#16161e", 257 | "titleBar.border": "#101014", 258 | "walkThrough.embeddedEditorBackground": "#16161e", 259 | "textLink.foreground": "#6183bb", 260 | "textLink.activeForeground": "#7dcfff", 261 | "textPreformat.foreground": "#9699a8", 262 | "textBlockQuote.background": "#16161e", 263 | "textCodeBlock.background": "#16161e", 264 | "textSeparator.foreground": "#363b54", 265 | "debugExceptionWidget.border": "#963c47", 266 | "debugExceptionWidget.background": "#101014", 267 | "debugToolBar.background": "#101014", 268 | "debugConsole.infoForeground": "#787c99", 269 | "debugConsole.errorForeground": "#bb616b", 270 | "debugConsole.sourceForeground": "#787c99", 271 | "debugConsole.warningForeground": "#c49a5a", 272 | "debugConsoleInputIcon.foreground": "#73daca", 273 | "editor.stackFrameHighlightBackground": "#E2BD3A20", 274 | "editor.focusedStackFrameHighlightBackground": "#73daca20", 275 | "debugView.stateLabelForeground": "#787c99", 276 | "debugView.stateLabelBackground": "#14141b", 277 | "debugView.valueChangedHighlight": "#3d59a1aa", 278 | "debugTokenExpression.name": "#7dcfff", 279 | "debugTokenExpression.value": "#9aa5ce", 280 | "debugTokenExpression.string": "#9ece6a", 281 | "debugTokenExpression.boolean": "#ff9e64", 282 | "debugTokenExpression.number": "#ff9e64", 283 | "debugTokenExpression.error": "#bb616b", 284 | "debugIcon.breakpointForeground": "#db4b4b", 285 | "debugIcon.breakpointDisabledForeground": "#414761", 286 | "debugIcon.breakpointUnverifiedForeground": "#c24242", 287 | "terminal.background": "#16161e", 288 | "terminal.foreground": "#787c99", 289 | "terminal.selectionBackground": "#515c7e30", 290 | "terminal.ansiBlack": "#363b54", 291 | "terminal.ansiRed": "#f7768e", 292 | "terminal.ansiGreen": "#41a6b5", 293 | "terminal.ansiYellow": "#e0af68", 294 | "terminal.ansiBlue": "#7aa2f7", 295 | "terminal.ansiMagenta": "#bb9af7", 296 | "terminal.ansiCyan": "#7dcfff", 297 | "terminal.ansiWhite": "#787c99", 298 | "terminal.ansiBrightBlack": "#363b54", 299 | "terminal.ansiBrightRed": "#f7768e", 300 | "terminal.ansiBrightGreen": "#41a6b5", 301 | "terminal.ansiBrightYellow": "#e0af68", 302 | "terminal.ansiBrightBlue": "#7aa2f7", 303 | "terminal.ansiBrightMagenta": "#bb9af7", 304 | "terminal.ansiBrightCyan": "#7dcfff", 305 | "terminal.ansiBrightWhite": "#acb0d0", 306 | "gitDecoration.modifiedResourceForeground": "#6183bb", 307 | "gitDecoration.ignoredResourceForeground": "#515670", 308 | "gitDecoration.deletedResourceForeground": "#914c54", 309 | "gitDecoration.renamedResourceForeground": "#449dab", 310 | "gitDecoration.addedResourceForeground": "#449dab", 311 | "gitDecoration.untrackedResourceForeground": "#449dab", 312 | "gitDecoration.conflictingResourceForeground": "#e0af68cc", 313 | "gitDecoration.stageDeletedResourceForeground": "#914c54", 314 | "gitDecoration.stageModifiedResourceForeground": "#6183bb", 315 | "notebook.editorBackground": "#1a1b26", 316 | "notebook.cellEditorBackground": "#16161e", 317 | "notebook.cellBorderColor": "#101014", 318 | "notebook.focusedCellBorder": "#29355a", 319 | "notebook.cellStatusBarItemHoverBackground": "#1c1d29", 320 | "charts.red": "#f7768e", 321 | "charts.blue": "#7aa2f7", 322 | "charts.yellow": "#e0af68", 323 | "charts.orange": "#ff9e64", 324 | "charts.green": "#41a6b5", 325 | "charts.purple": "#9d7cd8", 326 | "charts.foreground": "#9AA5CE", 327 | "charts.lines": "#16161e", 328 | "merge.currentHeaderBackground": "#41a6b525", 329 | "merge.currentContentBackground": "#007a7544", 330 | "merge.incomingHeaderBackground": "#3d59a1aa", 331 | "merge.incomingContentBackground": "#3d59a144", 332 | "mergeEditor.change.background": "#41a6b525", 333 | "mergeEditor.change.word.background": "#41a6b540", 334 | "mergeEditor.conflict.unhandledUnfocused.border": "#e0af6888", 335 | "mergeEditor.conflict.unhandledFocused.border": "#e0af68b0", 336 | "mergeEditor.conflict.handledUnfocused.border": "#41a6b525", 337 | "mergeEditor.conflict.handledFocused.border": "#41a6b565", 338 | "mergeEditor.conflict.handled.minimapOverViewRuler": "#449dab", 339 | "mergeEditor.conflict.unhandled.minimapOverViewRuler": "#e0af68", 340 | "gitlens.trailingLineForegroundColor": "#444b6a", 341 | "gitlens.gutterUncommittedForegroundColor": "#444b6a", 342 | "gitlens.gutterForegroundColor": "#444b6a", 343 | "notificationCenterHeader.background": "#101014", 344 | "notifications.background": "#101014", 345 | "notificationLink.foreground": "#6183bb", 346 | "notificationsErrorIcon.foreground": "#bb616b", 347 | "notificationsWarningIcon.foreground": "#bba461", 348 | "notificationsInfoIcon.foreground": "#0da0ba", 349 | "menubar.selectionForeground": "#a9b1d6", 350 | "menubar.selectionBackground": "#1e202e", 351 | "menubar.selectionBorder": "#1b1e2e", 352 | "menu.foreground": "#787c99", 353 | "menu.background": "#16161e", 354 | "menu.selectionForeground": "#a9b1d6", 355 | "menu.selectionBackground": "#1e202e", 356 | "menu.separatorBackground": "#101014", 357 | "menu.border": "#101014" 358 | }, 359 | "tokenColors": [ 360 | { 361 | "name": "Italics - Comments, Storage, Keyword Flow, Vue attributes, Decorators", 362 | "scope": [ 363 | "comment", 364 | "meta.var.expr storage.type", 365 | "keyword.control.flow", 366 | "keyword.control.return", 367 | "meta.directive.vue punctuation.separator.key-value.html", 368 | "meta.directive.vue entity.other.attribute-name.html", 369 | "tag.decorator.js entity.name.tag.js", 370 | "tag.decorator.js punctuation.definition.tag.js", 371 | "storage.modifier" 372 | ], 373 | "settings": { 374 | "fontStyle": "italic" 375 | } 376 | }, 377 | { 378 | "name": "Fix YAML block scalar", 379 | "scope": "keyword.control.flow.block-scalar.literal", 380 | "settings": { 381 | "fontStyle": "" 382 | } 383 | }, 384 | { 385 | "name": "Comment", 386 | "scope": [ 387 | "comment", 388 | "comment.block.documentation", 389 | "punctuation.definition.comment", 390 | "comment.block.documentation punctuation" 391 | ], 392 | "settings": { 393 | "foreground": "#444b6a" 394 | } 395 | }, 396 | { 397 | "name": "Comment Doc", 398 | "scope": [ 399 | "keyword.operator.assignment.jsdoc", 400 | "comment.block.documentation variable", 401 | "comment.block.documentation storage", 402 | "comment.block.documentation keyword", 403 | "comment.block.documentation support", 404 | "comment.block.documentation markup", 405 | "comment.block.documentation markup.inline.raw.string.markdown", 406 | "meta.other.type.phpdoc.php keyword.other.type.php", 407 | "meta.other.type.phpdoc.php support.other.namespace.php", 408 | "meta.other.type.phpdoc.php punctuation.separator.inheritance.php", 409 | "meta.other.type.phpdoc.php support.class", 410 | "keyword.other.phpdoc.php", 411 | "log.date" 412 | ], 413 | "settings": { 414 | "foreground": "#5a638c" 415 | } 416 | }, 417 | { 418 | "name": "Comment Doc Emphasized", 419 | "scope": [ 420 | "meta.other.type.phpdoc.php support.class", 421 | "comment.block.documentation storage.type", 422 | "comment.block.documentation punctuation.definition.block.tag", 423 | "comment.block.documentation entity.name.type.instance" 424 | ], 425 | "settings": { 426 | "foreground": "#646e9c" 427 | } 428 | }, 429 | { 430 | "name": "Number, Boolean, Undefined, Null", 431 | "scope": [ 432 | "variable.other.constant", 433 | "punctuation.definition.constant", 434 | "constant.language", 435 | "constant.numeric", 436 | "support.constant" 437 | ], 438 | "settings": { 439 | "foreground": "#ff9e64" 440 | } 441 | }, 442 | { 443 | "name": "String, Symbols", 444 | "scope": [ 445 | "string", 446 | "constant.other.symbol", 447 | "constant.other.key", 448 | "meta.attribute-selector" 449 | ], 450 | "settings": { 451 | "fontStyle": "", 452 | "foreground": "#9ece6a" 453 | } 454 | }, 455 | { 456 | "name": "Colors", 457 | "scope": [ 458 | "constant.other.color", 459 | "constant.other.color.rgb-value.hex punctuation.definition.constant" 460 | ], 461 | "settings": { 462 | "foreground": "#9aa5ce" 463 | } 464 | }, 465 | { 466 | "name": "Invalid", 467 | "scope": [ 468 | "invalid", 469 | "invalid.illegal" 470 | ], 471 | "settings": { 472 | "foreground": "#ff5370" 473 | } 474 | }, 475 | { 476 | "name": "Invalid deprecated", 477 | "scope": "invalid.deprecated", 478 | "settings": { 479 | "foreground": "#bb9af7" 480 | } 481 | }, 482 | { 483 | "name": "Storage Type", 484 | "scope": "storage.type", 485 | "settings": { 486 | "foreground": "#bb9af7" 487 | } 488 | }, 489 | { 490 | "name": "Storage - modifier, var, const, let", 491 | "scope": [ 492 | "meta.var.expr storage.type", 493 | "storage.modifier" 494 | ], 495 | "settings": { 496 | "foreground": "#9d7cd8" 497 | } 498 | }, 499 | { 500 | "name": "Interpolation, PHP tags, Smarty tags", 501 | "scope": [ 502 | "punctuation.definition.template-expression", 503 | "punctuation.section.embedded", 504 | "meta.embedded.line.tag.smarty", 505 | "support.constant.handlebars", 506 | "punctuation.section.tag.twig" 507 | ], 508 | "settings": { 509 | "foreground": "#7dcfff" 510 | } 511 | }, 512 | { 513 | "name": "Blade, Twig, Smarty Handlebars keywords", 514 | "scope": [ 515 | "keyword.control.smarty", 516 | "keyword.control.twig", 517 | "support.constant.handlebars keyword.control", 518 | "keyword.operator.comparison.twig", 519 | "keyword.blade", 520 | "entity.name.function.blade" 521 | ], 522 | "settings": { 523 | "foreground": "#0db9d7" 524 | } 525 | }, 526 | { 527 | "name": "Spread", 528 | "scope": [ 529 | "keyword.operator.spread", 530 | "keyword.operator.rest" 531 | ], 532 | "settings": { 533 | "foreground": "#f7768e", 534 | "fontStyle": "bold" 535 | } 536 | }, 537 | { 538 | "name": "Operator, Misc", 539 | "scope": [ 540 | "keyword.operator", 541 | "keyword.control.as", 542 | "keyword.other", 543 | "keyword.operator.bitwise.shift", 544 | "punctuation", 545 | "expression.embbeded.vue punctuation.definition.tag", 546 | "text.html.twig meta.tag.inline.any.html", 547 | "meta.tag.template.value.twig meta.function.arguments.twig", 548 | "meta.directive.vue punctuation.separator.key-value.html", 549 | "punctuation.definition.constant.markdown", 550 | "punctuation.definition.string", 551 | "punctuation.support.type.property-name", 552 | "text.html.vue-html meta.tag", 553 | "punctuation.definition.keyword", 554 | "punctuation.terminator.rule", 555 | "punctuation.definition.entity", 556 | "punctuation.separator.inheritance.php", 557 | "keyword.other.template", 558 | "keyword.other.substitution", 559 | "entity.name.operator", 560 | "meta.property-list punctuation.separator.key-value", 561 | "meta.at-rule.mixin punctuation.separator.key-value", 562 | "meta.at-rule.function variable.parameter.url" 563 | ], 564 | "settings": { 565 | "foreground": "#89ddff" 566 | } 567 | }, 568 | { 569 | "name": "Import, Export, From, Default", 570 | "scope": [ 571 | "keyword.control.import", 572 | "keyword.control.export", 573 | "keyword.control.from", 574 | "keyword.control.default", 575 | "meta.import keyword.other" 576 | ], 577 | "settings": { 578 | "foreground": "#7dcfff" 579 | } 580 | }, 581 | { 582 | "name": "Keyword", 583 | "scope": [ 584 | "keyword", 585 | "keyword.control", 586 | "keyword.other.important" 587 | ], 588 | "settings": { 589 | "foreground": "#bb9af7" 590 | } 591 | }, 592 | { 593 | "name": "Keyword SQL", 594 | "scope": "keyword.other.DML", 595 | "settings": { 596 | "foreground": "#7dcfff" 597 | } 598 | }, 599 | { 600 | "name": "Keyword Operator Logical, Arrow, Ternary, Comparison", 601 | "scope": [ 602 | "keyword.operator.logical", 603 | "storage.type.function", 604 | "keyword.operator.bitwise", 605 | "keyword.operator.ternary", 606 | "keyword.operator.comparison", 607 | "keyword.operator.relational", 608 | "keyword.operator.or.regexp" 609 | ], 610 | "settings": { 611 | "foreground": "#bb9af7" 612 | } 613 | }, 614 | { 615 | "name": "Tag", 616 | "scope": "entity.name.tag", 617 | "settings": { 618 | "foreground": "#f7768e" 619 | } 620 | }, 621 | { 622 | "name": "Tag - Custom", 623 | "scope": [ 624 | "entity.name.tag support.class.component", 625 | "meta.tag.custom entity.name.tag", 626 | "meta.tag" 627 | ], 628 | "settings": { 629 | "foreground": "#de5971" 630 | } 631 | }, 632 | { 633 | "name": "Tag Punctuation", 634 | "scope": "punctuation.definition.tag", 635 | "settings": { 636 | "foreground": "#ba3c97" 637 | } 638 | }, 639 | { 640 | "name": "Globals, PHP Constants, etc", 641 | "scope": [ 642 | "constant.other.php", 643 | "variable.other.global.safer", 644 | "variable.other.global.safer punctuation.definition.variable", 645 | "variable.other.global", 646 | "variable.other.global punctuation.definition.variable", 647 | "constant.other" 648 | ], 649 | "settings": { 650 | "foreground": "#e0af68" 651 | } 652 | }, 653 | { 654 | "name": "Variables", 655 | "scope": [ 656 | "variable", 657 | "support.variable", 658 | "string constant.other.placeholder", 659 | "variable.parameter.handlebars", 660 | "variable.other.object" 661 | ], 662 | "settings": { 663 | "foreground": "#c0caf5" 664 | } 665 | }, 666 | { 667 | "name": "Variable Array Key", 668 | "scope": "meta.array.literal variable", 669 | "settings": { 670 | "foreground": "#7dcfff" 671 | } 672 | }, 673 | { 674 | "name": "Object Key", 675 | "scope": [ 676 | "meta.object-literal.key", 677 | "entity.name.type.hcl", 678 | "string.alias.graphql", 679 | "string.unquoted.graphql", 680 | "string.unquoted.alias.graphql", 681 | "meta.group.braces.curly constant.other.object.key.js string.unquoted.label.js", 682 | "meta.field.declaration.ts variable.object.property" 683 | ], 684 | "settings": { 685 | "foreground": "#73daca" 686 | } 687 | }, 688 | { 689 | "name": "Object Property", 690 | "scope": [ 691 | "variable.other.property", 692 | "support.variable.property", 693 | "support.variable.property.dom", 694 | "meta.function-call variable.other.object.property" 695 | ], 696 | "settings": { 697 | "foreground": "#7dcfff" 698 | } 699 | }, 700 | { 701 | "name": "Object Property", 702 | "scope": "variable.other.object.property", 703 | "settings": { 704 | "foreground": "#c0caf5" 705 | } 706 | }, 707 | { 708 | "name": "Object Literal Member lvl 3 (Vue Prop Validation)", 709 | "scope": "meta.objectliteral meta.object.member meta.objectliteral meta.object.member meta.objectliteral meta.object.member meta.object-literal.key", 710 | "settings": { 711 | "foreground": "#41a6b5" 712 | } 713 | }, 714 | { 715 | "name": "C-related Block Level Variables", 716 | "scope": "source.cpp meta.block variable.other", 717 | "settings": { 718 | "foreground": "#f7768e" 719 | } 720 | }, 721 | { 722 | "name": "Other Variable", 723 | "scope": "support.other.variable", 724 | "settings": { 725 | "foreground": "#f7768e" 726 | } 727 | }, 728 | { 729 | "name": "Methods", 730 | "scope": [ 731 | "meta.class-method.js entity.name.function.js", 732 | "entity.name.method.js", 733 | "variable.function.constructor", 734 | "keyword.other.special-method", 735 | "storage.type.cs" 736 | ], 737 | "settings": { 738 | "foreground": "#7aa2f7" 739 | } 740 | }, 741 | { 742 | "name": "Function Definition", 743 | "scope": [ 744 | "entity.name.function", 745 | "variable.other.enummember", 746 | "meta.function-call", 747 | "meta.function-call entity.name.function", 748 | "variable.function", 749 | "meta.definition.method entity.name.function", 750 | "meta.object-literal entity.name.function" 751 | ], 752 | "settings": { 753 | "foreground": "#7aa2f7" 754 | } 755 | }, 756 | { 757 | "name": "Function Argument", 758 | "scope": [ 759 | "variable.parameter.function.language.special", 760 | "variable.parameter", 761 | "meta.function.parameters punctuation.definition.variable", 762 | "meta.function.parameter variable" 763 | ], 764 | "settings": { 765 | "foreground": "#e0af68" 766 | } 767 | }, 768 | { 769 | "name": "Constant, Tag Attribute", 770 | "scope": [ 771 | "keyword.other.type.php", 772 | "storage.type.php", 773 | "constant.character", 774 | "constant.escape", 775 | "keyword.other.unit" 776 | ], 777 | "settings": { 778 | "foreground": "#bb9af7" 779 | } 780 | }, 781 | { 782 | "name": "Variable Definition", 783 | "scope": [ 784 | "meta.definition.variable variable.other.constant", 785 | "meta.definition.variable variable.other.readwrite", 786 | "variable.declaration.hcl variable.other.readwrite.hcl", 787 | "meta.mapping.key.hcl variable.other.readwrite.hcl", 788 | "variable.other.declaration" 789 | ], 790 | "settings": { 791 | "foreground": "#bb9af7" 792 | } 793 | }, 794 | { 795 | "name": "Inherited Class", 796 | "scope": "entity.other.inherited-class", 797 | "settings": { 798 | "fontStyle": "", 799 | "foreground": "#bb9af7" 800 | } 801 | }, 802 | { 803 | "name": "Class, Support, DOM, etc", 804 | "scope": [ 805 | "support.class", 806 | "support.type", 807 | "variable.other.readwrite.alias", 808 | "support.orther.namespace.use.php", 809 | "meta.use.php", 810 | "support.other.namespace.php", 811 | "support.type.sys-types", 812 | "support.variable.dom", 813 | "support.constant.math", 814 | "support.type.object.module", 815 | "support.constant.json", 816 | "entity.name.namespace", 817 | "meta.import.qualifier", 818 | "variable.other.constant.object" 819 | ], 820 | "settings": { 821 | "foreground": "#0db9d7" 822 | } 823 | }, 824 | { 825 | "name": "Class Name", 826 | "scope": "entity.name", 827 | "settings": { 828 | "foreground": "#c0caf5" 829 | } 830 | }, 831 | { 832 | "name": "Support Function", 833 | "scope": "support.function", 834 | "settings": { 835 | "foreground": "#0db9d7" 836 | } 837 | }, 838 | { 839 | "name": "CSS Class and Support", 840 | "scope": [ 841 | "source.css support.type.property-name", 842 | "source.sass support.type.property-name", 843 | "source.scss support.type.property-name", 844 | "source.less support.type.property-name", 845 | "source.stylus support.type.property-name", 846 | "source.postcss support.type.property-name", 847 | "support.type.property-name.css", 848 | "support.type.vendored.property-name", 849 | "support.type.map.key" 850 | ], 851 | "settings": { 852 | "foreground": "#7aa2f7" 853 | } 854 | }, 855 | { 856 | "name": "CSS Font", 857 | "scope": [ 858 | "support.constant.font-name", 859 | "meta.definition.variable" 860 | ], 861 | "settings": { 862 | "foreground": "#9ece6a" 863 | } 864 | }, 865 | { 866 | "name": "CSS Class", 867 | "scope": [ 868 | "entity.other.attribute-name.class", 869 | "meta.at-rule.mixin.scss entity.name.function.scss" 870 | ], 871 | "settings": { 872 | "foreground": "#9ece6a" 873 | } 874 | }, 875 | { 876 | "name": "CSS ID", 877 | "scope": "entity.other.attribute-name.id", 878 | "settings": { 879 | "foreground": "#fc7b7b" 880 | } 881 | }, 882 | { 883 | "name": "CSS Tag", 884 | "scope": "entity.name.tag.css", 885 | "settings": { 886 | "foreground": "#0db9d7" 887 | } 888 | }, 889 | { 890 | "name": "CSS Tag Reference, Pseudo & Class Punctuation", 891 | "scope": [ 892 | "entity.other.attribute-name.pseudo-class punctuation.definition.entity", 893 | "entity.other.attribute-name.pseudo-element punctuation.definition.entity", 894 | "entity.other.attribute-name.class punctuation.definition.entity", 895 | "entity.name.tag.reference" 896 | ], 897 | "settings": { 898 | "foreground": "#e0af68" 899 | } 900 | }, 901 | { 902 | "name": "CSS Punctuation", 903 | "scope": "meta.property-list", 904 | "settings": { 905 | "foreground": "#9abdf5" 906 | } 907 | }, 908 | { 909 | "name": "CSS at-rule fix", 910 | "scope": [ 911 | "meta.property-list meta.at-rule.if", 912 | "meta.at-rule.return variable.parameter.url", 913 | "meta.property-list meta.at-rule.else" 914 | ], 915 | "settings": { 916 | "foreground": "#ff9e64" 917 | } 918 | }, 919 | { 920 | "name": "CSS Parent Selector Entity", 921 | "scope": [ 922 | "entity.other.attribute-name.parent-selector-suffix punctuation.definition.entity.css" 923 | ], 924 | "settings": { 925 | "foreground": "#73daca" 926 | } 927 | }, 928 | { 929 | "name": "CSS Punctuation comma fix", 930 | "scope": "meta.property-list meta.property-list", 931 | "settings": { 932 | "foreground": "#9abdf5" 933 | } 934 | }, 935 | { 936 | "name": "SCSS @", 937 | "scope": [ 938 | "meta.at-rule.mixin keyword.control.at-rule.mixin", 939 | "meta.at-rule.include entity.name.function.scss", 940 | "meta.at-rule.include keyword.control.at-rule.include" 941 | ], 942 | "settings": { 943 | "foreground": "#bb9af7" 944 | } 945 | }, 946 | { 947 | "name": "SCSS Mixins, Extends, Include Keyword", 948 | "scope": [ 949 | "keyword.control.at-rule.include punctuation.definition.keyword", 950 | "keyword.control.at-rule.mixin punctuation.definition.keyword", 951 | "meta.at-rule.include keyword.control.at-rule.include", 952 | "keyword.control.at-rule.extend punctuation.definition.keyword", 953 | "meta.at-rule.extend keyword.control.at-rule.extend", 954 | "entity.other.attribute-name.placeholder.css punctuation.definition.entity.css", 955 | "meta.at-rule.media keyword.control.at-rule.media", 956 | "meta.at-rule.mixin keyword.control.at-rule.mixin", 957 | "meta.at-rule.function keyword.control.at-rule.function", 958 | "keyword.control punctuation.definition.keyword" 959 | ], 960 | "settings": { 961 | "foreground": "#9d7cd8" 962 | } 963 | }, 964 | { 965 | "name": "SCSS Include Mixin Argument", 966 | "scope": "meta.property-list meta.at-rule.include", 967 | "settings": { 968 | "foreground": "#c0caf5" 969 | } 970 | }, 971 | { 972 | "name": "CSS value", 973 | "scope": "support.constant.property-value", 974 | "settings": { 975 | "foreground": "#ff9e64" 976 | } 977 | }, 978 | { 979 | "name": "Sub-methods", 980 | "scope": [ 981 | "entity.name.module.js", 982 | "variable.import.parameter.js", 983 | "variable.other.class.js" 984 | ], 985 | "settings": { 986 | "foreground": "#c0caf5" 987 | } 988 | }, 989 | { 990 | "name": "Language methods", 991 | "scope": "variable.language", 992 | "settings": { 993 | "foreground": "#f7768e" 994 | } 995 | }, 996 | { 997 | "name": "Variable punctuation", 998 | "scope": "variable.other punctuation.definition.variable", 999 | "settings": { 1000 | "foreground": "#c0caf5" 1001 | } 1002 | }, 1003 | { 1004 | "name": "Keyword this with Punctuation, ES7 Bind Operator", 1005 | "scope": [ 1006 | "source.js constant.other.object.key.js string.unquoted.label.js", 1007 | "variable.language.this punctuation.definition.variable", 1008 | "keyword.other.this" 1009 | ], 1010 | "settings": { 1011 | "foreground": "#f7768e" 1012 | } 1013 | }, 1014 | { 1015 | "name": "HTML Attributes", 1016 | "scope": [ 1017 | "entity.other.attribute-name", 1018 | "text.html.basic entity.other.attribute-name.html", 1019 | "text.html.basic entity.other.attribute-name" 1020 | ], 1021 | "settings": { 1022 | "foreground": "#bb9af7" 1023 | } 1024 | }, 1025 | { 1026 | "name": "HTML Character Entity", 1027 | "scope": "text.html constant.character.entity", 1028 | "settings": { 1029 | "foreground": "#0DB9D7" 1030 | } 1031 | }, 1032 | { 1033 | "name": "Vue Template attributes", 1034 | "scope": [ 1035 | "entity.other.attribute-name.id.html", 1036 | "meta.directive.vue entity.other.attribute-name.html" 1037 | ], 1038 | "settings": { 1039 | "foreground": "#bb9af7" 1040 | } 1041 | }, 1042 | { 1043 | "name": "CSS ID's", 1044 | "scope": "source.sass keyword.control", 1045 | "settings": { 1046 | "foreground": "#7aa2f7" 1047 | } 1048 | }, 1049 | { 1050 | "name": "CSS psuedo selectors", 1051 | "scope": [ 1052 | "entity.other.attribute-name.pseudo-class", 1053 | "entity.other.attribute-name.pseudo-element", 1054 | "entity.other.attribute-name.placeholder", 1055 | "meta.property-list meta.property-value" 1056 | ], 1057 | "settings": { 1058 | "foreground": "#bb9af7" 1059 | } 1060 | }, 1061 | { 1062 | "name": "Inserted", 1063 | "scope": "markup.inserted", 1064 | "settings": { 1065 | "foreground": "#449dab" 1066 | } 1067 | }, 1068 | { 1069 | "name": "Deleted", 1070 | "scope": "markup.deleted", 1071 | "settings": { 1072 | "foreground": "#914c54" 1073 | } 1074 | }, 1075 | { 1076 | "name": "Changed", 1077 | "scope": "markup.changed", 1078 | "settings": { 1079 | "foreground": "#6183bb" 1080 | } 1081 | }, 1082 | { 1083 | "name": "Regular Expressions", 1084 | "scope": "string.regexp", 1085 | "settings": { 1086 | "foreground": "#b4f9f8" 1087 | } 1088 | }, 1089 | { 1090 | "name": "Regular Expressions - Punctuation", 1091 | "scope": "punctuation.definition.group", 1092 | "settings": { 1093 | "foreground": "#f7768e" 1094 | } 1095 | }, 1096 | { 1097 | "name": "Regular Expressions - Character Class", 1098 | "scope": [ 1099 | "constant.other.character-class.regexp" 1100 | ], 1101 | "settings": { 1102 | "foreground": "#bb9af7" 1103 | } 1104 | }, 1105 | { 1106 | "name": "Regular Expressions - Character Class Set", 1107 | "scope": [ 1108 | "constant.other.character-class.set.regexp", 1109 | "punctuation.definition.character-class.regexp" 1110 | ], 1111 | "settings": { 1112 | "foreground": "#e0af68" 1113 | } 1114 | }, 1115 | { 1116 | "name": "Regular Expressions - Quantifier", 1117 | "scope": "keyword.operator.quantifier.regexp", 1118 | "settings": { 1119 | "foreground": "#89ddff" 1120 | } 1121 | }, 1122 | { 1123 | "name": "Regular Expressions - Backslash", 1124 | "scope": "constant.character.escape.backslash", 1125 | "settings": { 1126 | "foreground": "#c0caf5" 1127 | } 1128 | }, 1129 | { 1130 | "name": "Escape Characters", 1131 | "scope": "constant.character.escape", 1132 | "settings": { 1133 | "foreground": "#89ddff" 1134 | } 1135 | }, 1136 | { 1137 | "name": "Decorators", 1138 | "scope": [ 1139 | "tag.decorator.js entity.name.tag.js", 1140 | "tag.decorator.js punctuation.definition.tag.js" 1141 | ], 1142 | "settings": { 1143 | "foreground": "#7aa2f7" 1144 | } 1145 | }, 1146 | { 1147 | "name": "CSS Units", 1148 | "scope": "keyword.other.unit", 1149 | "settings": { 1150 | "foreground": "#f7768e" 1151 | } 1152 | }, 1153 | { 1154 | "name": "JSON Key - Level 0", 1155 | "scope": [ 1156 | "source.json meta.structure.dictionary.json support.type.property-name.json" 1157 | ], 1158 | "settings": { 1159 | "foreground": "#7aa2f7" 1160 | } 1161 | }, 1162 | { 1163 | "name": "JSON Key - Level 1", 1164 | "scope": [ 1165 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1166 | ], 1167 | "settings": { 1168 | "foreground": "#0db9d7" 1169 | } 1170 | }, 1171 | { 1172 | "name": "JSON Key - Level 2", 1173 | "scope": [ 1174 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1175 | ], 1176 | "settings": { 1177 | "foreground": "#7dcfff" 1178 | } 1179 | }, 1180 | { 1181 | "name": "JSON Key - Level 3", 1182 | "scope": [ 1183 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1184 | ], 1185 | "settings": { 1186 | "foreground": "#bb9af7" 1187 | } 1188 | }, 1189 | { 1190 | "name": "JSON Key - Level 4", 1191 | "scope": [ 1192 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1193 | ], 1194 | "settings": { 1195 | "foreground": "#e0af68" 1196 | } 1197 | }, 1198 | { 1199 | "name": "JSON Key - Level 5", 1200 | "scope": [ 1201 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1202 | ], 1203 | "settings": { 1204 | "foreground": "#0db9d7" 1205 | } 1206 | }, 1207 | { 1208 | "name": "JSON Key - Level 6", 1209 | "scope": [ 1210 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1211 | ], 1212 | "settings": { 1213 | "foreground": "#73daca" 1214 | } 1215 | }, 1216 | { 1217 | "name": "JSON Key - Level 7", 1218 | "scope": [ 1219 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1220 | ], 1221 | "settings": { 1222 | "foreground": "#f7768e" 1223 | } 1224 | }, 1225 | { 1226 | "name": "JSON Key - Level 8", 1227 | "scope": [ 1228 | "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json support.type.property-name.json" 1229 | ], 1230 | "settings": { 1231 | "foreground": "#9ece6a" 1232 | } 1233 | }, 1234 | { 1235 | "name": "Plain Punctuation", 1236 | "scope": "punctuation.definition.list_item.markdown", 1237 | "settings": { 1238 | "foreground": "#9abdf5" 1239 | } 1240 | }, 1241 | { 1242 | "name": "Block Punctuation", 1243 | "scope": [ 1244 | "meta.block", 1245 | "meta.brace", 1246 | "punctuation.definition.block", 1247 | "punctuation.definition.use", 1248 | "punctuation.definition.class", 1249 | "punctuation.definition.begin.bracket", 1250 | "punctuation.definition.end.bracket", 1251 | "punctuation.definition.switch-expression.begin.bracket", 1252 | "punctuation.definition.switch-expression.end.bracket", 1253 | "punctuation.definition.section.switch-block.begin.bracket", 1254 | "punctuation.definition.section.switch-block.end.bracket", 1255 | "punctuation.definition.group.shell", 1256 | "punctuation.definition.parameters", 1257 | "punctuation.definition.arguments", 1258 | "punctuation.definition.dictionary", 1259 | "punctuation.definition.array", 1260 | "punctuation.section" 1261 | ], 1262 | "settings": { 1263 | "foreground": "#9abdf5" 1264 | } 1265 | }, 1266 | { 1267 | "name": "Markdown - Plain", 1268 | "scope": [ 1269 | "meta.jsx.children", 1270 | "meta.embedded.block" 1271 | ], 1272 | "settings": { 1273 | "foreground": "#c0caf5" 1274 | } 1275 | }, 1276 | { 1277 | "name": "HTML text", 1278 | "scope": [ 1279 | "text.html", 1280 | "text.log" 1281 | ], 1282 | "settings": { 1283 | "foreground": "#9aa5ce" 1284 | } 1285 | }, 1286 | { 1287 | "name": "Markdown - Markup Raw Inline", 1288 | "scope": "text.html.markdown markup.inline.raw.markdown", 1289 | "settings": { 1290 | "foreground": "#bb9af7" 1291 | } 1292 | }, 1293 | { 1294 | "name": "Markdown - Markup Raw Inline Punctuation", 1295 | "scope": "text.html.markdown markup.inline.raw.markdown punctuation.definition.raw.markdown", 1296 | "settings": { 1297 | "foreground": "#4E5579" 1298 | } 1299 | }, 1300 | { 1301 | "name": "Markdown - Heading 1", 1302 | "scope": [ 1303 | "heading.1.markdown entity.name", 1304 | "heading.1.markdown punctuation.definition.heading.markdown" 1305 | ], 1306 | "settings": { 1307 | "fontStyle": "bold", 1308 | "foreground": "#89ddff" 1309 | } 1310 | }, 1311 | { 1312 | "name": "Markdown - Heading 2", 1313 | "scope": [ 1314 | "heading.2.markdown entity.name", 1315 | "heading.2.markdown punctuation.definition.heading.markdown" 1316 | ], 1317 | "settings": { 1318 | "fontStyle": "bold", 1319 | "foreground": "#61bdf2" 1320 | } 1321 | }, 1322 | { 1323 | "name": "Markdown - Heading 3", 1324 | "scope": [ 1325 | "heading.3.markdown entity.name", 1326 | "heading.3.markdown punctuation.definition.heading.markdown" 1327 | ], 1328 | "settings": { 1329 | "fontStyle": "bold", 1330 | "foreground": "#7aa2f7" 1331 | } 1332 | }, 1333 | { 1334 | "name": "Markdown - Heading 4", 1335 | "scope": [ 1336 | "heading.4.markdown entity.name", 1337 | "heading.4.markdown punctuation.definition.heading.markdown" 1338 | ], 1339 | "settings": { 1340 | "fontStyle": "bold", 1341 | "foreground": "#6d91de" 1342 | } 1343 | }, 1344 | { 1345 | "name": "Markdown - Heading 5", 1346 | "scope": [ 1347 | "heading.5.markdown entity.name", 1348 | "heading.5.markdown punctuation.definition.heading.markdown" 1349 | ], 1350 | "settings": { 1351 | "fontStyle": "bold", 1352 | "foreground": "#9aa5ce" 1353 | } 1354 | }, 1355 | { 1356 | "name": "Markdown - Heading 6", 1357 | "scope": [ 1358 | "heading.6.markdown entity.name", 1359 | "heading.6.markdown punctuation.definition.heading.markdown" 1360 | ], 1361 | "settings": { 1362 | "fontStyle": "bold", 1363 | "foreground": "#747ca1" 1364 | } 1365 | }, 1366 | { 1367 | "name": "Markup - Italic", 1368 | "scope": [ 1369 | "markup.italic", 1370 | "markup.italic punctuation" 1371 | ], 1372 | "settings": { 1373 | "fontStyle": "italic", 1374 | "foreground": "#c0caf5" 1375 | } 1376 | }, 1377 | { 1378 | "name": "Markup - Bold", 1379 | "scope": [ 1380 | "markup.bold", 1381 | "markup.bold punctuation" 1382 | ], 1383 | "settings": { 1384 | "fontStyle": "bold", 1385 | "foreground": "#c0caf5" 1386 | } 1387 | }, 1388 | { 1389 | "name": "Markup - Bold-Italic", 1390 | "scope": [ 1391 | "markup.bold markup.italic", 1392 | "markup.bold markup.italic punctuation" 1393 | ], 1394 | "settings": { 1395 | "fontStyle": "bold italic", 1396 | "foreground": "#c0caf5" 1397 | } 1398 | }, 1399 | { 1400 | "name": "Markup - Underline", 1401 | "scope": [ 1402 | "markup.underline", 1403 | "markup.underline punctuation" 1404 | ], 1405 | "settings": { 1406 | "fontStyle": "underline" 1407 | } 1408 | }, 1409 | { 1410 | "name": "Markdown - Blockquote", 1411 | "scope": "markup.quote punctuation.definition.blockquote.markdown", 1412 | "settings": { 1413 | "foreground": "#4e5579" 1414 | } 1415 | }, 1416 | { 1417 | "name": "Markup - Quote", 1418 | "scope": "markup.quote", 1419 | "settings": { 1420 | "fontStyle": "italic" 1421 | } 1422 | }, 1423 | { 1424 | "name": "Markdown - Link", 1425 | "scope": [ 1426 | "string.other.link", 1427 | "markup.underline.link", 1428 | "constant.other.reference.link.markdown", 1429 | "string.other.link.description.title.markdown" 1430 | ], 1431 | "settings": { 1432 | "foreground": "#73daca" 1433 | } 1434 | }, 1435 | { 1436 | "name": "Markdown - Fenced Code Block", 1437 | "scope": [ 1438 | "markup.fenced_code.block.markdown", 1439 | "markup.inline.raw.string.markdown", 1440 | "variable.language.fenced.markdown" 1441 | ], 1442 | "settings": { 1443 | "foreground": "#89ddff" 1444 | } 1445 | }, 1446 | { 1447 | "name": "Markdown - Separator", 1448 | "scope": "meta.separator", 1449 | "settings": { 1450 | "fontStyle": "bold", 1451 | "foreground": "#444b6a" 1452 | } 1453 | }, 1454 | { 1455 | "name": "Markup - Table", 1456 | "scope": "markup.table", 1457 | "settings": { 1458 | "foreground": "#c0cefc" 1459 | } 1460 | }, 1461 | { 1462 | "name": "Token - Info", 1463 | "scope": "token.info-token", 1464 | "settings": { 1465 | "foreground": "#0db9d7" 1466 | } 1467 | }, 1468 | { 1469 | "name": "Token - Warn", 1470 | "scope": "token.warn-token", 1471 | "settings": { 1472 | "foreground": "#ffdb69" 1473 | } 1474 | }, 1475 | { 1476 | "name": "Token - Error", 1477 | "scope": "token.error-token", 1478 | "settings": { 1479 | "foreground": "#db4b4b" 1480 | } 1481 | }, 1482 | { 1483 | "name": "Token - Debug", 1484 | "scope": "token.debug-token", 1485 | "settings": { 1486 | "foreground": "#b267e6" 1487 | } 1488 | }, 1489 | { 1490 | "name": "Apache Tag", 1491 | "scope": "entity.tag.apacheconf", 1492 | "settings": { 1493 | "foreground": "#f7768e" 1494 | } 1495 | }, 1496 | { 1497 | "name": "Preprocessor", 1498 | "scope": [ 1499 | "meta.preprocessor" 1500 | ], 1501 | "settings": { 1502 | "foreground": "#73daca" 1503 | } 1504 | }, 1505 | { 1506 | "name": "ENV value", 1507 | "scope": "source.env", 1508 | "settings": { 1509 | "foreground": "#7aa2f7" 1510 | } 1511 | } 1512 | ] 1513 | } --------------------------------------------------------------------------------