From 4e891ce3a4b3503bf5f78886018adfff96d0e64e Mon Sep 17 00:00:00 2001 From: TQ Hirsch Date: Fri, 12 May 2023 20:58:50 +0200 Subject: [PATCH] Added JS client --- Cargo.lock | 23 ++ d3270d/Cargo.toml | 1 + d3270d/src/main.rs | 18 +- d3270d/src/ws_server.rs | 53 +++ js3270/.gitignore | 24 ++ js3270/.postcssrc.yml | 3 + js3270/index.html | 14 + js3270/package.json | 17 + js3270/public/vite.svg | 1 + js3270/src/main.ts | 246 +++++++++++++ js3270/src/style.css | 141 +++++++ js3270/src/suite3270.ts | 251 +++++++++++++ js3270/src/vite-env.d.ts | 1 + js3270/tsconfig.json | 23 ++ js3270/yarn.lock | 772 +++++++++++++++++++++++++++++++++++++++ 15 files changed, 1587 insertions(+), 1 deletion(-) create mode 100644 d3270d/src/ws_server.rs create mode 100644 js3270/.gitignore create mode 100644 js3270/.postcssrc.yml create mode 100644 js3270/index.html create mode 100644 js3270/package.json create mode 100644 js3270/public/vite.svg create mode 100644 js3270/src/main.ts create mode 100644 js3270/src/style.css create mode 100644 js3270/src/suite3270.ts create mode 100644 js3270/src/vite-env.d.ts create mode 100644 js3270/tsconfig.json create mode 100644 js3270/yarn.lock diff --git a/Cargo.lock b/Cargo.lock index 3a72d89..47aaa76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -723,6 +723,7 @@ dependencies = [ "serde", "serde_json", "tide", + "tide-tracing", "tide-websockets", "tokio", "tokio-stream", @@ -2063,6 +2064,18 @@ dependencies = [ "serde_json", ] +[[package]] +name = "tide-tracing" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500f567f8c4d65210e6a7c9978661cc7ad6be1dc97e32c3e88bf8f0f0599c23d" +dependencies = [ + "async-trait", + "tide", + "tracing", + "tracing-futures", +] + [[package]] name = "tide-websockets" version = "0.4.0" @@ -2242,6 +2255,16 @@ dependencies = [ "tracing-subscriber 0.1.6", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.3" diff --git a/d3270d/Cargo.toml b/d3270d/Cargo.toml index 3163259..228e5f2 100644 --- a/d3270d/Cargo.toml +++ b/d3270d/Cargo.toml @@ -12,6 +12,7 @@ anyhow = "1.0.71" tokio = { version = "1.28.0", features = ["full"] } tide = "0.16.0" tide-websockets = "0.4.0" +tide-tracing = "0.0.12" d3270-common = {path = "../d3270-common"} bytes = "1.4.0" tracing = "0.1.37" diff --git a/d3270d/src/main.rs b/d3270d/src/main.rs index 8b58f2c..871a1ee 100644 --- a/d3270d/src/main.rs +++ b/d3270d/src/main.rs @@ -18,6 +18,7 @@ use d3270_common::b3270::operation::Action; pub mod arbiter; pub mod gen_connection; pub mod tcp_server; +pub mod ws_server; struct TaggedJoinHandle { handle: JoinHandle, @@ -65,6 +66,7 @@ async fn main() -> anyhow::Result<()> { let mut args_iter = std::env::args_os().peekable(); let mut connect_str = None; let mut tcp_listen = None; + let mut http_listen = None; args_iter.next(); // skip program name. @@ -94,7 +96,17 @@ async fn main() -> anyhow::Result<()> { .map_err(|_| anyhow!("Failed to parse tcp-listen address"))? .parse() .map(Some) - .map_err(|_| anyhow!("Invalid listen address"))?; + .map_err(|_| anyhow!("Failed to parse tcp-listen address"))?; + } + "-http-listen" => { + http_listen = args_iter + .next() + .ok_or_else(|| anyhow!("Arg required for -http-listen"))? + .into_string() + .map_err(|_| anyhow!("Failed to parse http-listen address"))? + .parse() + .map(Some) + .map_err(|_| anyhow!("Failed to parse http-listen address"))?; } "-e" => { 'skip: while let Some(arg) = args_iter.peek() { @@ -131,6 +143,10 @@ async fn main() -> anyhow::Result<()> { let tcp_listener = tcp_server::listener_proc(addr, arbiter_req.clone()).await?; handles.push(tcp_listener.tagged("tcp_listener")); } + if let Some(addr) = http_listen { + let ws_listener = ws_server::start_ws_server(addr, arbiter_req.clone()).await?; + handles.push(ws_listener.tagged("ws_server")); + } let ((source, error), _, _) = select_all(handles).await; error!(source, %error, "A core task failed"); diff --git a/d3270d/src/ws_server.rs b/d3270d/src/ws_server.rs new file mode 100644 index 0000000..986b851 --- /dev/null +++ b/d3270d/src/ws_server.rs @@ -0,0 +1,53 @@ +use std::net::SocketAddr; +use anyhow::anyhow; +use tide::prelude::*; +use tide::Request; +use tide_websockets::{WebSocketConnection, self as ws}; +use tokio::select; +use tokio::task::JoinHandle; +use crate::arbiter::ArbiterHandleRequester; +use crate::gen_connection::GenConnection; +use futures::stream::StreamExt; +use tracing::{info, warn}; +use d3270_common::b3270::Indication; + +pub async fn start_ws_server(socket: SocketAddr, handle_requester: ArbiterHandleRequester, ) -> anyhow::Result> { + let mut app = tide::Server::with_state(handle_requester); + app.with(tide_tracing::TraceMiddleware::new()); + app.at("/api/ws").get(tide_websockets::WebSocket::new(handle_websocket)); + + let mut listener = app.bind(socket.clone()).await?; + Ok(tokio::task::spawn(async move { + info!(%socket, "Starting HTTP server"); + listener.accept().await + .map(|()| anyhow!("HTTP server returned early")) + .unwrap_or_else(Into::into) + })) +} + +async fn handle_websocket(req: Request, mut ws: WebSocketConnection) -> tide::Result<()> { + let mut arbiter = GenConnection::new(req.state().clone()).await?; + + // TODO: do authenticatey things + + 'main: loop { + select! { + msg = ws.next() => { + let msg: ws::Message = if let Some(msg) = msg { msg? } else { break 'main; }; + match msg { + ws::Message::Text(text) => arbiter.handle_client_line(text).await?, + ws::Message::Binary(_) => warn!("Unexpected binary message from client"), + ws::Message::Ping(data) => ws.send(ws::Message::Pong(data)).await?, + ws::Message::Close(_) => break 'main, + _ => (), + } + }, + msg = arbiter.next_indication() => { + let msg: Indication = if let Some(msg) = msg { msg } else { break 'main; }; + ws.send_json(&msg).await?; + } + } + } + + Ok(()) +} \ No newline at end of file diff --git a/js3270/.gitignore b/js3270/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/js3270/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/js3270/.postcssrc.yml b/js3270/.postcssrc.yml new file mode 100644 index 0000000..c75efde --- /dev/null +++ b/js3270/.postcssrc.yml @@ -0,0 +1,3 @@ +plugins: + postcss-simple-vars: {} + postcss-preset-env: {} diff --git a/js3270/index.html b/js3270/index.html new file mode 100644 index 0000000..510ecd1 --- /dev/null +++ b/js3270/index.html @@ -0,0 +1,14 @@ + + + + + + + + 3270 Console + + +
+ + + diff --git a/js3270/package.json b/js3270/package.json new file mode 100644 index 0000000..fd01d9f --- /dev/null +++ b/js3270/package.json @@ -0,0 +1,17 @@ +{ + "name": "js3270", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "typescript": "^5.0.2", + "vite": "^4.3.2", + "postcss-preset-env": "^8.3.2", + "postcss-simple-vars": "^7.0.1" + } +} diff --git a/js3270/public/vite.svg b/js3270/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/js3270/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/js3270/src/main.ts b/js3270/src/main.ts new file mode 100644 index 0000000..71a2482 --- /dev/null +++ b/js3270/src/main.ts @@ -0,0 +1,246 @@ +import './style.css' +import typescriptLogo from './typescript.svg' +import viteLogo from '/vite.svg' +import {Action, Color, Cursor, IndErase, Indication, IndScreen, InitializeIndication, Operation} from "./suite3270.ts"; + +type GrElement = "underline" | "blink" | "highlight" | "selectable" | "reverse" | "wide" | "order" | "private-use" | "no-copy" | "wrap"; +class CharCell { + td: HTMLElement + char: string + fg: Color + bg: Color + gr: Set + + constructor(td: HTMLElement) { + this.td = td; + this.char = ' '; + this.fg = "neutralWhite"; + this.bg = "neutralBlack"; + this.gr = new Set(); + } + + update() { + let cell = this; + let grset = []; + for (let grattr of cell.gr) { + grset.push(grattr); + } + cell.td.dataset.gr = grset.join(" "); + cell.td.dataset.fg = cell.fg; + cell.td.dataset.bg = cell.bg; + cell.td.replaceChildren(cell.char) + + } +} + +class Js3270 { + private character_tbl: HTMLTableElement; + private cgrid: CharCell[][]; + private oia_row: HTMLDivElement; + private ws: WebSocket; + + private def_fg: Color; + private def_bg: Color; + private cursor: Cursor; + private cursor_cell: CharCell|null; + + constructor(root: HTMLDivElement) { + // set up default properties + this.def_fg = "neutralWhite"; + this.def_bg = "neutralBlack"; + + this.character_tbl = document.createElement("table"); + this.character_tbl.className = "cgrid"; + this.cursor = {enabled: true, row: 1, column: 1}; + this.cursor_cell = null; + this.cgrid = []; + + + this.oia_row = document.createElement("div"); + // TODO: make this lookup the address based on where it's loaded from + this.ws = new WebSocket("ws://127.0.0.1:13270/api/ws"); + this.ws.addEventListener("message", this.on_message.bind(this)) + + root.replaceChildren(this.character_tbl, this.oia_row); + + window.addEventListener("keydown", this.on_keydown.bind(this)) + } + + private send(actions: Action[]) { + let op: Operation = {run: {actions: actions}}; + this.ws.send(JSON.stringify(op)); + } + + private keymap: {[k: string]: [string, string[]]} = { + "PageUp": ["Scroll", ["backward"]], + "PageDown": ["Scroll", ["forward"]], + "Backspace": ["Backspace", []], + "Enter": ["Enter", []], + "Tab": ["Tab", []], + "S+Tab": ["Backtab", []], + "ArrowUp": ["Up", []], + "ArrowDown": ["Down", []], + "ArrowRight": ["Right", []], + "ArrowLeft": ["Left", []], + "M+r": ["Reset", []], + "M+a": ["Attn", []], + } + private on_keydown(evt: KeyboardEvent) { + let key_str = [ + evt.ctrlKey? "C+":"", + evt.altKey?"M+":"", + evt.shiftKey?"S+":"", + evt.key + ].join(""); + + if (evt.key.length == 1 && !evt.altKey) { + this.send([{action: "Key", args: [evt.key]}]); + evt.stopPropagation(); + return; + } else if (key_str in this.keymap) { + let [action, args] = this.keymap[key_str]; + this.send([{action, args}]); + evt.preventDefault(); + evt.stopPropagation(); + } else if (evt.key[0] == "F" && evt.key.substring(1).match("[0-9]+")) { + let fn = evt.key.substring(1); + if (evt.shiftKey) { + fn = ((fn as any - 0) + 13) + ""; + } + this.send([{action: "PF", args: [fn]}]); + evt.stopImmediatePropagation(); + evt.stopPropagation(); + evt.preventDefault(); + } else { + console.log(key_str); + } + } + + private handle_indication(ind: Indication | InitializeIndication) { + if ("initialize" in ind) { + for (let subind of ind.initialize) { + this.handle_indication(subind); + } + } else if ("screen-mode" in ind) { + let mode = ind["screen-mode"]; + this.resize_screen(mode.rows, mode.columns); + } else if ("screen" in ind) { + this.handle_ind_screen(ind.screen) + } else if ("erase" in ind) { + this.handle_ind_erase(ind.erase); + } + } + + private resize_screen(rows: number, columns: number) { + this.cgrid = []; + + let tbody = document.createElement("tbody"); + + for (let y = 0; y < rows; y++) { + let row: CharCell[] = []; + let tr = document.createElement("tr"); + for (let x = 0; x < columns; x++) { + let td = document.createElement("td"); + let cc = new CharCell(td); + cc.fg = this.def_fg; + cc.bg = this.def_bg; + row.push(cc); + + tr.append(td); + } + tbody.append(tr); + this.cgrid.push(row); + } + this.redraw_screen(); + this.character_tbl.replaceChildren(tbody); + } + + private on_message(ev: MessageEvent) { + let ind = JSON.parse(ev.data) as Indication; + this.handle_indication(ind); + // console.log(ind); + } + + private redraw_screen() { + for (let row of this.cgrid) { + for (let cell of row) { + cell.update() + } + } + this.move_cursor(); + } + + private redraw_region(row: number, col_start: number, count: number) { + let c_row = this.cgrid[row]; + for (let i = col_start; i < col_start + count; i++) { + c_row[i].update() + } + } + + private move_cursor() { + if (this.cursor_cell) { + delete this.cursor_cell.td.dataset.cursor; + this.cursor_cell = null; + } + if (this.cursor.enabled) { + this.cursor_cell = this.cgrid[this.cursor.row-1][this.cursor.column-1]; + this.cursor_cell.td.dataset.cursor = ""; + } + } + + private handle_ind_screen(screen: IndScreen) { + let rows = screen.rows || []; + for (let row_e of rows) { + let row_c = this.cgrid[row_e.row - 1]; + for (let change of row_e.changes) { + let col_start = change.column - 1; + let count = ("text" in change) ? change.text.length : change.count; + let text = ("text" in change) ? change.text : null; + + let new_gr: Set | null = null; + if (change.gr) { + new_gr = new Set(); + new_gr.clear(); + if (change.gr != "none") { + for (let gritem of change.gr.split(",")) { + new_gr.add(gritem as GrElement); + } + } + } + for (let i = 0; i < count; i++) { + let cell = row_c[col_start+i]; + + cell.fg = change.fg || cell.fg; + cell.bg = change.bg || cell.bg; + cell.gr = new_gr || cell.gr; + if (text) { + cell.char = text[i]; + } + cell.update(); + } + } + } + if (screen.cursor) { + this.cursor = screen.cursor; + this.move_cursor(); + } + } + + + private handle_ind_erase(erase: IndErase) { + if ("fg" in erase) { + this.def_bg = erase.bg + this.def_fg = erase.fg + } + if ("logical_rows" in erase) { + this.resize_screen(erase.logical_rows, erase.logical_cols); + } else { + this.resize_screen(this.cgrid.length, this.cgrid[0].length) + } + } +} + +let app = document.querySelector('#app')!; +// @ts-ignore +window.js3270 = new Js3270(app); + diff --git a/js3270/src/style.css b/js3270/src/style.css new file mode 100644 index 0000000..d36b5f9 --- /dev/null +++ b/js3270/src/style.css @@ -0,0 +1,141 @@ +$chroma: 100%; +$lightnessMain: 75%; +$lightnessIntense: 85%; +$lightnessDark: 60%; + +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + /*line-height: 1.25;*/ + font-synthesis: weight; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + /*box-sizing: content-box;*/ + + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; + + --chroma: 90%; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #3178c6aa); +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} + +.cgrid { + border-spacing: 0; +} + +table.cgrid td { + white-space: pre; + font-family: "IBM P", "Operator Mono", monospace; + font-weight: 300; + padding: 0; +} + +.cgrid [data-bg="neutralBlack"] { + background: oklch(0 0 0); +} + +.cgrid [data-fg="neutralBlack"] { color: oklch(0.2 0 0); } +.cgrid [data-fg="blue"] { color: oklch($lightnessMain $chroma 240deg); } +.cgrid [data-fg="red"] { color: oklch($lightnessMain $chroma 20deg); } +.cgrid [data-fg="pink"] { color: oklch($lightnessMain $chroma 340deg); } +.cgrid [data-fg="green"] { color: oklch($lightnessMain $chroma 150deg); } +.cgrid [data-fg="turquoise"] { color: oklch($lightnessMain $chroma 190deg); } +.cgrid [data-fg="yellow"] { color: oklch($lightnessMain $chroma 110deg); } +.cgrid [data-fg="neutralWhite"] { color: oklch($lightnessMain 0 0); } +.cgrid [data-fg="black"] {color: #000; } +.cgrid [data-fg="deepBlue"] {color: oklch($lightnessDark $chroma 240deg); } +.cgrid [data-fg="orange"] {color: oklch($lightnessDark $chroma 70deg); } +.cgrid [data-fg="purple"] { color: oklch($lightnessDark $chroma 320deg);} +.cgrid [data-fg="paleGreen"] { color: oklch(92% $chroma 150deg); } +.cgrid [data-fg="paleTurquoise"] { color: oklch(95% $chroma 190deg); } +.cgrid [data-fg="gray"] { color: oklch(55% 0 0); } +.cgrid [data-fg="white"] { color: oklch($lightnessIntense 0 0); } + +.cgrid [data-cursor] { box-shadow: inset 0px 0px 0 1px lime; } + +.cgrid [data-gr~="underline"] { text-decoration: underline; } +.cgrid [data-gr~="highlight"] { font-synthesis: weight; font-weight: 400; } diff --git a/js3270/src/suite3270.ts b/js3270/src/suite3270.ts new file mode 100644 index 0000000..14acf04 --- /dev/null +++ b/js3270/src/suite3270.ts @@ -0,0 +1,251 @@ +export type CodePage = { + name: string, + aliases?: string[], +} + +export type ActionCause = + "command" | "default" | "file-transfer" | "httpd" | "idle" | + "keymap" | "macro" | "none" | "password" | "paste" | "peek" | + "screen-redraw" | "script" | "typeahead" | "ui" + +export type ConnectionState = + "not-connected" | "reconnecting" | "resolving" | + "tcp-pending" | "tls-pending" | "telnet-pending" | + "connected-nvt" | "connected-nvt-charmode" | + "connected-3270" | "connected-unbound" | + "connected-e-nvt" | "connected-sscp" | + "connected-tn3270e" + +export type IndConnection = { + state: ConnectionState, + host?: string, + cause?: ActionCause, +} + +export type ComposeType = "std" | "ge" +export type Color = + "neutralBlack" | "blue" | "red" | "pink" | "green" | "turquoise" | + "yellow" | "neutralWhite" | "black" | "deepBlue" | "orange" | "purple" | + "paleGreen" | "paleTurquoise" | "gray" | "white" + +export type IndErase = ({logical_rows: number, logical_cols: number} | {}) & + ({fg: Color, bg: Color} | {}) + +export type IndHello = {version: string, build: string, copyright: string} +export type IndModel = { + model: number, + rows: number, + columns: number, +} + +export type OiaCompose = { field: "compose"} & + ( + {value: true, char: string, type: ComposeType} | + {value: false} + ) +export type OiaInsert = {field: "insert", value: boolean} +export type OiaLock = { field: "lock", value?: string } +export type OiaLu = { field: "lu", value: string, lu?: string } +export type OiaNotUndera = { field: "not-undera", value: boolean } +export type OiaReverseInput = { field: "reverse-input", value: boolean } +export type OiaScreenTrace = { field: "screen-trace", value?: number } +export type OiaScript = { field: "script", value: boolean } +export type OiaTiming = { field: "timing", value?: string } +export type OiaTypeahead = { field: "typeahead", value: boolean } +export type IndOia = + OiaCompose | OiaInsert | OiaLock | OiaLu | OiaNotUndera | OiaReverseInput | + OiaScreenTrace | OiaScript | OiaTiming | OiaTypeahead +export type OiaFieldName = IndOia["field"] + +export type IndProxy = { + name: string, + username: boolean, + port?: number, +} + +export type IndSetting = { + name: string, + value?: any, // Todo: enhance this + cause?: ActionCause, +} + +export type IndScreenMode = { + model: number, + rows: number, + columns: number, + color: boolean, + oversize: boolean, + extended: boolean, +} + +export type IndTlsHello = { + supported: boolean, + provider: string, + options?: string[], +} + +export type IndTls = + ( { secure: true, verified: boolean } | { secure:false } ) & + { + session?: string, + "host-cert"?: string, + } + +export type IndConnectAttempt = { "host-ip": string, port: string } +export type Cursor = {enabled: false} | {enabled:true, row: number, column: number } +export type IndFileTransfer = { cause: ActionCause } & ( + { state: "awaiting" } | + { state: "running", bytes: number } | + { state: "aborting" } | + { state: "complete", text: string, success: boolean } + ) + +export type IndPassthru = { + "p-tag": string, + "parent-r-tag"?: string, + action: string, + args?: string[], +} + +export type IndPopup = { + type: "connect-error" | "error" | "info" | "result" | "printer" | "child" + text: string, + // todo: refine + error?: string, +} + +export type Change = { + column: number + // TODO: determine if this is a + gr?: string, // there's more structure than this, but can't represent in TS + fg?: Color, + bg?: Color, +} & ({count: number} | {text: string}) + +export type IndScreen = { + cursor?: Cursor, + rows?: { + row: number, + changes: Change[] + }[] +} + +export type IndRunResult = { + "r-tag"?: string, + success: boolean, + text?: string[] + abort?: boolean + time: number +} + +export type IndScroll = { + // TODO: refine + fg?: Color, + bg?: Color, +} + +export type IndStats = { + "bytes-received": number, + "bytes-sent": number, + "records-received": number, + "records-sent": number, +} + +export type IndTerminalName = { + text: string, + override: boolean, +} + +export type IndThumb = { + top: number, + shown: number + saved: number + screen: number + back: number +} + +export type IndTraceFile = { + name?: string +} + +export type IndUiError = { + fatal: boolean + text: string + operation?: string + member?: string + line?: number + column?: number +} + +// operations +export type OpRun = { + "r-tag"?: string, + type?: string, + // This is true of d3270, but b3270 offers more options + actions: Action[] +} + +export type Action = { + action: string, + args?: string[], +} + +export type OpRegister = { + name: string, + "help-text"?: string, + "help-params": string, +} + +export type OpResult = { + "p-tag": string, + text?: string[] +} + +export type Operation = + {run: OpRun} | + {register: OpRegister} | + {fail: OpResult} | + {succeed: OpResult} + +export type Indication = + {bell: {}} | + {connection: IndConnection} | + {"connect-attempt": IndConnectAttempt} | + {erase: IndErase} | + {flipped: {value: boolean}} | + {font: {text: string}} | + {formatted: {state: boolean}} | + {ft: IndFileTransfer} | + {icon: {text: string}} | + {initialize: InitializeIndication[]} | + {oia: IndOia} | + {passthru: IndPassthru} | + {popup: IndPopup} | + {"run-result": IndRunResult} | + {screen: IndScreen} | + {"screen-mode": IndScreenMode} | + {scroll: IndScroll} | + {setting: IndSetting} | + {stats: IndStats} | + {thumb: IndThumb} | + {"trace-file": IndTraceFile} | + {tls: IndTls} | + {"ui-error": IndUiError} | + {"window-title": {text: string}} + +export type InitializeIndication = + {"code-pages": CodePage[]} | + {connection: IndConnection} | + {erase: IndErase} | + {hello: IndHello} | + {models: IndModel} | + {oia: IndOia} | + {prefixes: {value: string}} | + {proxies: IndProxy[]} | + {"screen-mode": IndScreenMode} | + {setting: IndSetting} | + {"terminal-name": IndTerminalName} | + {thumb: IndThumb} | + {"tls-hello": IndTlsHello} | + {tls: IndTls} | + {"trace-file": IndTraceFile} diff --git a/js3270/src/vite-env.d.ts b/js3270/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/js3270/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/js3270/tsconfig.json b/js3270/tsconfig.json new file mode 100644 index 0000000..75abdef --- /dev/null +++ b/js3270/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/js3270/yarn.lock b/js3270/yarn.lock new file mode 100644 index 0000000..a8998af --- /dev/null +++ b/js3270/yarn.lock @@ -0,0 +1,772 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@csstools/cascade-layer-name-parser@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-1.0.2.tgz#35253f57c6c83d684fe396672486c644e6a84127" + integrity sha512-xm7Mgwej/wBfLoK0K5LfntmPJzoULayl1XZY9JYgQgT29JiqNw++sLnx95u5y9zCihblzkyaRYJrsRMhIBzRdg== + +"@csstools/color-helpers@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-2.0.0.tgz#4ac578cb00b4e853b94f2250267d85ba957c4fc9" + integrity sha512-VcPjEnp07RNgz/D+oI2uIALg+IPCSl6mj0XhA3pl3F2bM2B95vgzatExmmzSg/X0zkh+R2v+jFY/J2pV/bnwpw== + +"@csstools/css-calc@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-1.1.1.tgz#c622728b7f0c9aae70952623c2b0d3d114752987" + integrity sha512-Nh+iLCtjlooTzuR0lpmB8I6hPX/VupcGQ3Z1U2+wgJJ4fa8+cWkub+lCsbZcYPzBGsZLEL8fQAg+Na5dwEFJxg== + +"@csstools/css-color-parser@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-1.1.2.tgz#e5956c0fe9c30d9f228b0e37173ff61f0dd89dad" + integrity sha512-MjW/VspbFSkvbuou7tUUu2+FAlAR7VJ/PA69M9EGKltThbONC8nyW33wHRzNvLzRLGstZLEO5X5oR7IMhMDi0A== + dependencies: + "@csstools/color-helpers" "^2.0.0" + "@csstools/css-calc" "^1.1.1" + +"@csstools/css-parser-algorithms@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.1.1.tgz#7b62e6412a468a2d1096ed267edd1e4a7fd4a119" + integrity sha512-viRnRh02AgO4mwIQb2xQNJju0i+Fh9roNgmbR5xEuG7J3TGgxjnE95HnBLgsFJOJOksvcfxOUCgODcft6Y07cA== + +"@csstools/css-tokenizer@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.1.1.tgz#07ae11a0a06365d7ec686549db7b729bc036528e" + integrity sha512-GbrTj2Z8MCTUv+52GE0RbFGM527xuXZ0Xa5g0Z+YN573uveS4G0qi6WNOMyz3yrFM/jaILTTwJ0+umx81EzqfA== + +"@csstools/media-query-list-parser@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.4.tgz#466bd254041530dfd1e88bcb1921e8ca4af75b6a" + integrity sha512-GyYot6jHgcSDZZ+tLSnrzkR7aJhF2ZW6d+CXH66mjy5WpAQhZD4HDke2OQ36SivGRWlZJpAz7TzbW6OKlEpxAA== + +"@csstools/postcss-cascade-layers@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-3.0.1.tgz#d839386e90428b448e3f75276bc01d516e852a0d" + integrity sha512-dD8W98dOYNOH/yX4V4HXOhfCOnvVAg8TtsL+qCGNoKXuq5z2C/d026wGWgySgC8cajXXo/wNezS31Glj5GcqrA== + dependencies: + "@csstools/selector-specificity" "^2.0.2" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-color-function@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-2.2.1.tgz#fa28cc742c29ae63dbe0812dd9a03998a67dd318" + integrity sha512-T52iiqmzyKk09B9iNTQbuWa9Tn83SztXY7o6r2+j+o1BS/7+CiCjTgN2HgzybDmx8cr6XYhQ1BzqgV9tJzhrmw== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + +"@csstools/postcss-color-mix-function@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-1.0.1.tgz#587f7df69d40f84c7bb4e9d7f178266cb7f6851b" + integrity sha512-NSVrzjVcI4TMzDfh6GKZXvEuelT81xpXzruuTNJrwKMTZXEBHY9G2gvmr0eC0wwmL8EF1TblXyPPfBbZobvfXg== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + +"@csstools/postcss-font-format-keywords@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-2.0.2.tgz#d798d96f4af6cddcfee459f598c976e6011042d2" + integrity sha512-iKYZlIs6JsNT7NKyRjyIyezTCHLh4L4BBB3F5Nx7Dc4Z/QmBgX+YJFuUSar8IM6KclGiAUFGomXFdYxAwJydlA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-gradients-interpolation-method@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-3.0.4.tgz#c03402087c41feee0115f714cc87696e6424ba92" + integrity sha512-GgKoY7OlvL65UPigEdlrvMAUCR5kOQCjtue2/36TPrBNoRS6KM2KOqmjIVsxEwYYwK+L28pdnM8r10m03hhZxA== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + +"@csstools/postcss-hwb-function@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-2.2.1.tgz#ab50918104e4ef500c42e55e4ccdd27fc33d52b9" + integrity sha512-eiqB4DIs+xqProAly7KwIgE04oze1YHb0QSCw/Y7062d9gpw+Cdif3Y0Z+Te+U7JROYdO0/0j91A6Qy8fo/Rlw== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + +"@csstools/postcss-ic-unit@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-2.0.2.tgz#5a5e481c53977deec3d63793788eec924d4c5f7d" + integrity sha512-N84qGTJkfLTPj2qOG5P4CIqGjpZBbjOEMKMn+UjO5wlb9lcBTfBsxCF0lQsFdWJUzBHYFOz19dL66v71WF3Pig== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-3.2.0.tgz#1277cc187bdb075013341dab42b4140d1cafae27" + integrity sha512-uooelBL99jMg8ZD6xy0Pj1hSalchWmplcin00eI+JHpv1jW2iwbi1cn2UnVsToM4JLwJSZFzTSWCgSpmlyhe3A== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-logical-float-and-clear@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-1.0.1.tgz#d255ea7aad18880930b63d8a04164f56182f2ecf" + integrity sha512-eO9z2sMLddvlfFEW5Fxbjyd03zaO7cJafDurK4rCqyRt9P7aaWwha0LcSzoROlcZrw1NBV2JAp2vMKfPMQO1xw== + +"@csstools/postcss-logical-resize@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-resize/-/postcss-logical-resize-1.0.1.tgz#826d3de929d7d786c32c2c118f78e813a1c2cdec" + integrity sha512-x1ge74eCSvpBkDDWppl+7FuD2dL68WP+wwP2qvdUcKY17vJksz+XoE1ZRV38uJgS6FNUwC0AxrPW5gy3MxsDHQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-logical-viewport-units@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-1.0.3.tgz#63e212954015ecdc493878601c3daa4da6ba6714" + integrity sha512-6zqcyRg9HSqIHIPMYdt6THWhRmE5/tyHKJQLysn2TeDf/ftq7Em9qwMTx98t2C/7UxIsYS8lOiHHxAVjWn2WUg== + dependencies: + "@csstools/css-tokenizer" "^2.1.1" + +"@csstools/postcss-media-minmax@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-1.0.2.tgz#77efc4fdd96c7ff97f0d714c940187d25fd87619" + integrity sha512-DsEykSINZTqlBefi1uSQBym1Rj0NQOj92dLRd5jUQpSy8yBVaXXmkiUgBUbb+gQh8imAdqPpz2v4sAUnw8yXXA== + dependencies: + "@csstools/css-calc" "^1.1.1" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.0.4" + +"@csstools/postcss-media-queries-aspect-ratio-number-values@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-1.0.2.tgz#23ca3c3decc79d9089c2028ded20a97a2c784eee" + integrity sha512-rOSR5p+5m0joXUoitYgCyMqNCu97yfLsLG3cnNaM8VeJRCWHGEu5hE9Gv0M7n9A4wo2pYF8QqaxkTlWbSJY9Fg== + dependencies: + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.0.4" + +"@csstools/postcss-nested-calc@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-2.0.2.tgz#a0857650ef88b1aa7b094c7ea8ea1378c35695e0" + integrity sha512-jbwrP8rN4e7LNaRcpx3xpMUjhtt34I9OV+zgbcsYAAk6k1+3kODXJBf95/JMYWhu9g1oif7r06QVUgfWsKxCFw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-2.0.1.tgz#35dc188c5b4713cf902959fe3c8ce613fcb7543e" + integrity sha512-TQT5g3JQ5gPXC239YuRK8jFceXF9d25ZvBkyjzBGGoW5st5sPXFVQS8OjYb9IJ/K3CdfK4528y483cgS2DJR/w== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-2.2.1.tgz#4f8f4d8d69e6e479e094b5d327c7b259352e8b81" + integrity sha512-g4wrVopp6xXr1KetUK4Lj36P+PFPwvUUtd2gaqo7X/0xgJHmMtKMPhD9p77H9bmIpPtkIYQ8b7+7cdmrWNEVAw== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + +"@csstools/postcss-progressive-custom-properties@^2.0.0", "@csstools/postcss-progressive-custom-properties@^2.1.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-2.1.1.tgz#82df9314451db63bf7f4975a4d32f148e85db490" + integrity sha512-6p8eO5+j+9hn4h2Klr9dbmya0GIb9SRrnPaCxqR1muVlV1waAZq6YkmlApEwXrox9qxggSwGZD5TnLRIY9f7WA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-scope-pseudo-class@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-2.0.2.tgz#6325e1e3b321093c59b008ec670bb772e17f06fe" + integrity sha512-6Pvo4uexUCXt+Hz5iUtemQAcIuCYnL+ePs1khFR6/xPgC92aQLJ0zGHonWoewiBE+I++4gXK3pr+R1rlOFHe5w== + dependencies: + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-stepped-value-functions@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-2.1.1.tgz#f31aa0e7bd0ce3e4a0450573e1e27ce5e602b100" + integrity sha512-YCvdF0GCZK35nhLgs7ippcxDlRVe5QsSht3+EghqTjnYnyl3BbWIN6fYQ1dKWYTJ+7Bgi41TgqQFfJDcp9Xy/w== + dependencies: + "@csstools/css-calc" "^1.1.1" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + +"@csstools/postcss-text-decoration-shorthand@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-2.2.3.tgz#e634a488aa5ba252907deb787ad6cc24b8c2bb0a" + integrity sha512-PADJidg/tdhDk120aWlGuDxsp5ZTc9Nx7GhJ8t0qBCk5fOgLK6V3DsB9X6sOAhDokIihXKzjtUu15puac5McWw== + dependencies: + "@csstools/color-helpers" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-trigonometric-functions@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-2.1.1.tgz#871a2048b0f81495d6cd8858ffb1fb04231ca741" + integrity sha512-XcXmHEFfHXhvYz40FtDlA4Fp4NQln2bWTsCwthd2c+MCnYArUYU3YaMqzR5CrKP3pMoGYTBnp5fMqf1HxItNyw== + dependencies: + "@csstools/css-calc" "^1.1.1" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + +"@csstools/postcss-unset-value@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-2.0.1.tgz#67091dd6cff556bff896c95053eb070cc6b21c25" + integrity sha512-oJ9Xl29/yU8U7/pnMJRqAZd4YXNCfGEdcP4ywREuqm/xMqcgDNDppYRoCGDt40aaZQIEKBS79LytUDN/DHf0Ew== + +"@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.1", "@csstools/selector-specificity@^2.0.2": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz#2cbcf822bf3764c9658c4d2e568bd0c0cb748016" + integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw== + +"@esbuild/android-arm64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz#4aa8d8afcffb4458736ca9b32baa97d7cb5861ea" + integrity sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw== + +"@esbuild/android-arm@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.18.tgz#74a7e95af4ee212ebc9db9baa87c06a594f2a427" + integrity sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw== + +"@esbuild/android-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.18.tgz#1dcd13f201997c9fe0b204189d3a0da4eb4eb9b6" + integrity sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg== + +"@esbuild/darwin-arm64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz#444f3b961d4da7a89eb9bd35cfa4415141537c2a" + integrity sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ== + +"@esbuild/darwin-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz#a6da308d0ac8a498c54d62e0b2bfb7119b22d315" + integrity sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A== + +"@esbuild/freebsd-arm64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz#b83122bb468889399d0d63475d5aea8d6829c2c2" + integrity sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA== + +"@esbuild/freebsd-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz#af59e0e03fcf7f221b34d4c5ab14094862c9c864" + integrity sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew== + +"@esbuild/linux-arm64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz#8551d72ba540c5bce4bab274a81c14ed01eafdcf" + integrity sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ== + +"@esbuild/linux-arm@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz#e09e76e526df4f665d4d2720d28ff87d15cdf639" + integrity sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg== + +"@esbuild/linux-ia32@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz#47878860ce4fe73a36fd8627f5647bcbbef38ba4" + integrity sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ== + +"@esbuild/linux-loong64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz#3f8fbf5267556fc387d20b2e708ce115de5c967a" + integrity sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ== + +"@esbuild/linux-mips64el@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz#9d896d8f3c75f6c226cbeb840127462e37738226" + integrity sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA== + +"@esbuild/linux-ppc64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz#3d9deb60b2d32c9985bdc3e3be090d30b7472783" + integrity sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ== + +"@esbuild/linux-riscv64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz#8a943cf13fd24ff7ed58aefb940ef178f93386bc" + integrity sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA== + +"@esbuild/linux-s390x@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz#66cb01f4a06423e5496facabdce4f7cae7cb80e5" + integrity sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw== + +"@esbuild/linux-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz#23c26050c6c5d1359c7b774823adc32b3883b6c9" + integrity sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA== + +"@esbuild/netbsd-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz#789a203d3115a52633ff6504f8cbf757f15e703b" + integrity sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg== + +"@esbuild/openbsd-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz#d7b998a30878f8da40617a10af423f56f12a5e90" + integrity sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA== + +"@esbuild/sunos-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz#ecad0736aa7dae07901ba273db9ef3d3e93df31f" + integrity sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg== + +"@esbuild/win32-arm64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz#58dfc177da30acf956252d7c8ae9e54e424887c4" + integrity sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg== + +"@esbuild/win32-ia32@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz#340f6163172b5272b5ae60ec12c312485f69232b" + integrity sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw== + +"@esbuild/win32-x64@0.17.18": + version "0.17.18" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz#3a8e57153905308db357fd02f57c180ee3a0a1fa" + integrity sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg== + +autoprefixer@^10.4.14: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +browserslist@^4.21.5: + version "4.21.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== + dependencies: + caniuse-lite "^1.0.30001449" + electron-to-chromium "^1.4.284" + node-releases "^2.0.8" + update-browserslist-db "^1.0.10" + +caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001464: + version "1.0.30001486" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz#56a08885228edf62cbe1ac8980f2b5dae159997e" + integrity sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg== + +css-blank-pseudo@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-5.0.2.tgz#3df5cd950f64de960974da05e76954fd3d7442f9" + integrity sha512-aCU4AZ7uEcVSUzagTlA9pHciz7aWPKA/YzrEkpdSopJ2pvhIxiQ5sYeMz1/KByxlIo4XBdvMNJAVKMg/GRnhfw== + dependencies: + postcss-selector-parser "^6.0.10" + +css-has-pseudo@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-5.0.2.tgz#8798118c705d858b7aeb9d839a39edd901c1cc83" + integrity sha512-q+U+4QdwwB7T9VEW/LyO6CFrLAeLqOykC5mDqJXc7aKZAhDbq7BvGT13VGJe+IwBfdN2o3Xdw2kJ5IxwV1Sc9Q== + dependencies: + "@csstools/selector-specificity" "^2.0.1" + postcss-selector-parser "^6.0.10" + postcss-value-parser "^4.2.0" + +css-prefers-color-scheme@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-8.0.2.tgz#a0671f54eb19ed0d30b952574c0af11ec355fb6d" + integrity sha512-OvFghizHJ45x7nsJJUSYLyQNTzsCU8yWjxAc/nhPQg1pbs18LMoET8N3kOweFDPy0JV0OSXN2iqRFhPBHYOeMA== + +cssdb@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.5.4.tgz#e34dafee5184d67634604e345e389ca79ac179ea" + integrity sha512-fGD+J6Jlq+aurfE1VDXlLS4Pt0VtNlu2+YgfGOdMxRyl/HQ9bDiHTwSck1Yz8A97Dt/82izSK6Bp/4nVqacOsg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +electron-to-chromium@^1.4.284: + version "1.4.392" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.392.tgz#57ec91fa02393ab32e46df6925ef309642a44680" + integrity sha512-TXQOMW9tnhIms3jGy/lJctLjICOgyueZFJ1KUtm6DTQ+QpxX3p7ZBwB6syuZ9KBuT5S4XX7bgY1ECPgfxKUdOg== + +esbuild@^0.17.5: + version "0.17.18" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.18.tgz#f4f8eb6d77384d68cd71c53eb6601c7efe05e746" + integrity sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w== + optionalDependencies: + "@esbuild/android-arm" "0.17.18" + "@esbuild/android-arm64" "0.17.18" + "@esbuild/android-x64" "0.17.18" + "@esbuild/darwin-arm64" "0.17.18" + "@esbuild/darwin-x64" "0.17.18" + "@esbuild/freebsd-arm64" "0.17.18" + "@esbuild/freebsd-x64" "0.17.18" + "@esbuild/linux-arm" "0.17.18" + "@esbuild/linux-arm64" "0.17.18" + "@esbuild/linux-ia32" "0.17.18" + "@esbuild/linux-loong64" "0.17.18" + "@esbuild/linux-mips64el" "0.17.18" + "@esbuild/linux-ppc64" "0.17.18" + "@esbuild/linux-riscv64" "0.17.18" + "@esbuild/linux-s390x" "0.17.18" + "@esbuild/linux-x64" "0.17.18" + "@esbuild/netbsd-x64" "0.17.18" + "@esbuild/openbsd-x64" "0.17.18" + "@esbuild/sunos-x64" "0.17.18" + "@esbuild/win32-arm64" "0.17.18" + "@esbuild/win32-ia32" "0.17.18" + "@esbuild/win32-x64" "0.17.18" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +node-releases@^2.0.8: + version "2.0.10" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +postcss-attribute-case-insensitive@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-6.0.2.tgz#e843091859323342e461878d201ee70278809e01" + integrity sha512-IRuCwwAAQbgaLhxQdQcIIK0dCVXg3XDUnzgKD8iwdiYdwU4rMWRWyl/W9/0nA4ihVpq5pyALiHB2veBJ0292pw== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-5.0.2.tgz#6d03c928aa3a13487703af86c301bdcd501e7430" + integrity sha512-M6ygxWOyd6eWf3sd1Lv8xi4SeF4iBPfJvkfMU4ITh8ExJc1qhbvh/U8Cv/uOvBgUVOMDdScvCdlg8+hREQzs7w== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-9.0.2.tgz#6d3ed50342802469880981a1999515d003ff7d79" + integrity sha512-SfPjgr//VQ/DOCf80STIAsdAs7sbIbxATvVmd+Ec7JvR8onz9pjawhq3BJM3Pie40EE3TyB0P6hft16D33Nlyg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-8.0.2.tgz#c0f2dcf1ef4dd393314920aa181cca8c390a2648" + integrity sha512-xWf/JmAxVoB5bltHpXk+uGRoGFwu4WDAR7210el+iyvTdqiKpDhtcT8N3edXMoVJY0WHFMrKMUieql/wRNiXkw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-media@^9.1.3: + version "9.1.3" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-9.1.3.tgz#68bb2ae377bb07c19f03f252930cc380af894dce" + integrity sha512-W1C4Fu6KAZ7sKYQCuGMr8gyaE4BtjTQGPLVS4m0WCaWM6l7PgVbvmDeb4ClBc5R/7kdwESYf0hdxGtEPhi9CLA== + dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/media-query-list-parser" "^2.0.4" + +postcss-custom-properties@^13.1.5: + version "13.1.5" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-13.1.5.tgz#75567e3b4a664f820bcc3ba8b6ae3c8d27db05d1" + integrity sha512-98DXk81zTGqMVkGANysMHbGIg3voH383DYo3/+c+Abzay3nao+vM/f4Jgzsakk9S7BDsEw5DiW7sFy5G4W2wLA== + dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + postcss-value-parser "^4.2.0" + +postcss-custom-selectors@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-7.1.3.tgz#047e2bc4726fe8e448c23047c99785fcdbe1ef87" + integrity sha512-GTVscax6O/8s7agFF0HsOoIyjrnAbLjgCUle8tn+0oDGJuVx7p56U7ClSRoC49poxFuMfu2B4Q8GnxSCOeuFKw== + dependencies: + "@csstools/cascade-layer-name-parser" "^1.0.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-7.0.2.tgz#71618b7eb4abe067845d11b3c8f322760c9b3e88" + integrity sha512-cMnslilYxBf9k3qejnovrUONZx1rXeUZJw06fgIUBzABJe3D2LiLL5WAER7Imt3nrkaIgG05XZBztueLEf5P8w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-double-position-gradients@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-4.0.2.tgz#855a23201f26be447210504e9b668429cbf4640c" + integrity sha512-GXL1RmFREDK4Q9aYvI2RhVrA6a6qqSMQQ5ke8gSH1xgV6exsqbcJpIumC7AOgooH6/WIG3/K/T8xxAiVHy/tJg== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-focus-visible@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-8.0.2.tgz#a7ac26ffe3e9c2bd17d7200d75e2d79ee8110891" + integrity sha512-f/Vd+EC/GaKElknU59esVcRYr/Y3t1ZAQyL4u2xSOgkDy4bMCmG7VP5cGvj3+BTLNE9ETfEuz2nnt4qkZwTTeA== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-focus-within@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-7.0.2.tgz#5d2c866030e66ed22b204c9506de640943310b1c" + integrity sha512-AHAJ89UQBcqBvFgQJE9XasGuwMNkKsGj4D/f9Uk60jFmEBHpAL14DrnSk3Rj+SwZTr/WUG+mh+Rvf8fid/346w== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-4.0.1.tgz#0347d6a84a46bfbe88bedc542cc4b354e04a8338" + integrity sha512-V5OuQGw4lBumPlwHWk/PRfMKjaq/LTGR4WDTemIMCaMevArVfCCA9wBJiL1VjDAd+rzuCIlkRoRvDsSiAaZ4Fg== + +postcss-image-set-function@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-5.0.2.tgz#088e0f535f43e74d6ea8033ff7b0482e2735ea6e" + integrity sha512-Sszjwo0ubETX0Fi5MvpYzsONwrsjeabjMoc5YqHvURFItXgIu3HdCjcVuVKGMPGzKRhgaknmdM5uVWInWPJmeg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== + +postcss-lab-function@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-5.2.1.tgz#a1f324fa5c098bddf36de221abcc32070c77b5db" + integrity sha512-u71Adr4nWi+4EmSZq5EV/fg9d1dYO6W26RNtT9LISEyjhH1q23vJIUkSqRwHgD6v7xxsxLOY5cSdVyaNE6rqzw== + dependencies: + "@csstools/css-color-parser" "^1.1.2" + "@csstools/css-parser-algorithms" "^2.1.1" + "@csstools/css-tokenizer" "^2.1.1" + "@csstools/postcss-progressive-custom-properties" "^2.0.0" + +postcss-logical@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-6.1.0.tgz#c33ae75d3edaea7eb821e76dc4e6d0ecedc3200d" + integrity sha512-qb1+LpClhYjxac8SfOcWotnY3unKZesDqIOm+jnGt8rTl7xaIWpE2bPGZHxflOip1E/4ETo79qlJyRL3yrHn1g== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-nesting@^11.2.1: + version "11.2.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-11.2.2.tgz#ddedfea5a1fdcd8d753298d82297ad15d5640c0f" + integrity sha512-aOTiUniAB1bcPE6GGiynWRa6PZFPhOTAm5q3q5cem6QeSijIHHkWr6gs65ukCZMXeak8yXeZVbBJET3VM+HlhA== + dependencies: + "@csstools/selector-specificity" "^2.0.0" + postcss-selector-parser "^6.0.10" + +postcss-opacity-percentage@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-2.0.0.tgz#c0a56060cd4586e3f954dbde1efffc2deed53002" + integrity sha512-lyDrCOtntq5Y1JZpBFzIWm2wG9kbEdujpNt4NLannF+J9c8CgFIzPa80YQfdza+Y+yFfzbYj/rfoOsYsooUWTQ== + +postcss-overflow-shorthand@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-4.0.1.tgz#cb61ca24d8c4e1dbf14d85181b017cfa6953aa34" + integrity sha512-HQZ0qi/9iSYHW4w3ogNqVNr2J49DHJAl7r8O2p0Meip38jsdnRPgiDW7r/LlLrrMBMe3KHkvNtAV2UmRVxzLIg== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-8.0.1.tgz#408d7a27e99192df51c95fe62a3a34def62aa66a" + integrity sha512-Ow2LedN8sL4pq8ubukO77phSVt4QyCm35ZGCYXKvRFayAwcpgB0sjNJglDoTuRdUL32q/ZC1VkPBo0AOEr4Uiw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-preset-env@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-8.3.2.tgz#9ec368e0f0df9c693d52b69d525d366fe4b1833a" + integrity sha512-VSAOsfxTXzO/gX5QljC8x8hN3ABbD9iqqLgqHqohBdNI5FhJptwpl96kpu+kYvvzK7BWwaHYou0IeYrp+NqmcQ== + dependencies: + "@csstools/postcss-cascade-layers" "^3.0.1" + "@csstools/postcss-color-function" "^2.2.1" + "@csstools/postcss-color-mix-function" "^1.0.1" + "@csstools/postcss-font-format-keywords" "^2.0.2" + "@csstools/postcss-gradients-interpolation-method" "^3.0.4" + "@csstools/postcss-hwb-function" "^2.2.1" + "@csstools/postcss-ic-unit" "^2.0.2" + "@csstools/postcss-is-pseudo-class" "^3.2.0" + "@csstools/postcss-logical-float-and-clear" "^1.0.1" + "@csstools/postcss-logical-resize" "^1.0.1" + "@csstools/postcss-logical-viewport-units" "^1.0.3" + "@csstools/postcss-media-minmax" "^1.0.2" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^1.0.2" + "@csstools/postcss-nested-calc" "^2.0.2" + "@csstools/postcss-normalize-display-values" "^2.0.1" + "@csstools/postcss-oklab-function" "^2.2.1" + "@csstools/postcss-progressive-custom-properties" "^2.1.0" + "@csstools/postcss-scope-pseudo-class" "^2.0.2" + "@csstools/postcss-stepped-value-functions" "^2.1.1" + "@csstools/postcss-text-decoration-shorthand" "^2.2.3" + "@csstools/postcss-trigonometric-functions" "^2.1.1" + "@csstools/postcss-unset-value" "^2.0.1" + autoprefixer "^10.4.14" + browserslist "^4.21.5" + css-blank-pseudo "^5.0.2" + css-has-pseudo "^5.0.2" + css-prefers-color-scheme "^8.0.2" + cssdb "^7.5.3" + postcss-attribute-case-insensitive "^6.0.2" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^5.0.2" + postcss-color-hex-alpha "^9.0.2" + postcss-color-rebeccapurple "^8.0.2" + postcss-custom-media "^9.1.3" + postcss-custom-properties "^13.1.5" + postcss-custom-selectors "^7.1.3" + postcss-dir-pseudo-class "^7.0.2" + postcss-double-position-gradients "^4.0.2" + postcss-focus-visible "^8.0.2" + postcss-focus-within "^7.0.2" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^4.0.1" + postcss-image-set-function "^5.0.2" + postcss-initial "^4.0.1" + postcss-lab-function "^5.2.1" + postcss-logical "^6.1.0" + postcss-nesting "^11.2.1" + postcss-opacity-percentage "^2.0.0" + postcss-overflow-shorthand "^4.0.1" + postcss-page-break "^3.0.4" + postcss-place "^8.0.1" + postcss-pseudo-class-any-link "^8.0.2" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^7.0.1" + postcss-value-parser "^4.2.0" + +postcss-pseudo-class-any-link@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-8.0.2.tgz#f5738503f2045de0c4dc216eca99bd835f74e42e" + integrity sha512-FYTIuRE07jZ2CW8POvctRgArQJ43yxhr5vLmImdKUvjFCkR09kh8pIdlCwdx/jbFm7MiW4QP58L4oOUv3grQYA== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-7.0.1.tgz#8142e90c8eb6c8c5faecb3e9d96d4353d02e94fb" + integrity sha512-1zT5C27b/zeJhchN7fP0kBr16Cc61mu7Si9uWWLoA3Px/D9tIJPKchJCkUH3tPO5D0pCFmGeApAv8XpXBQJ8SQ== + dependencies: + postcss-selector-parser "^6.0.10" + +postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.4: + version "6.0.12" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.12.tgz#2efae5ffab3c8bfb2b7fbf0c426e3bca616c4abb" + integrity sha512-NdxGCAZdRrwVI1sy59+Wzrh+pMMHxapGnpfenDVlMEXoOcvt4pGE0JLK9YY2F5dLxcFYA/YbVQKhcGU+FtSYQg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-simple-vars@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz#836b3097a54dcd13dbd3c36a5dbdd512fad2954c" + integrity sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A== + +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.23: + version "8.4.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab" + integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +rollup@^3.21.0: + version "3.21.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.21.6.tgz#f5649ccdf8fcc7729254faa457cbea9547eb86db" + integrity sha512-SXIICxvxQxR3D4dp/3LDHZIJPC8a4anKMHd4E3Jiz2/JnY+2bEjqrOokAauc5ShGVNFHlEFjBXAXlaxkJqIqSg== + optionalDependencies: + fsevents "~2.3.2" + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +typescript@^5.0.2: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + +update-browserslist-db@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +vite@^4.3.2: + version "4.3.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.3.5.tgz#3871fe0f4b582ea7f49a85386ac80e84826367d9" + integrity sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA== + dependencies: + esbuild "^0.17.5" + postcss "^8.4.23" + rollup "^3.21.0" + optionalDependencies: + fsevents "~2.3.2"