├── .gitignore
├── screenshot.png
├── embed
├── favicon.ico
├── ConsolasNerdFont.woff2
├── index.html
├── htm.js
├── script.js
├── floating-ui.dom.js
├── preact.js
└── floating-ui.core.js
├── justfile
├── .github
└── workflows
│ └── release.yml
├── Cargo.toml
├── .vscode
└── launch.json
├── README.md
├── notes.md
├── src
└── main.rs
└── Cargo.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | stdin.txt
3 | stdout.txt
4 | vte.txt
5 | .DS_Store
6 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rgwood/escape-artist/HEAD/screenshot.png
--------------------------------------------------------------------------------
/embed/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rgwood/escape-artist/HEAD/embed/favicon.ico
--------------------------------------------------------------------------------
/embed/ConsolasNerdFont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rgwood/escape-artist/HEAD/embed/ConsolasNerdFont.woff2
--------------------------------------------------------------------------------
/embed/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Escape Artist
8 |
9 |
10 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/justfile:
--------------------------------------------------------------------------------
1 | set shell := ["nu", "-c"]
2 |
3 | # this doesn't quite work perfectly because the terminal is stuck in raw mode after the restart
4 | watch:
5 | watchexec --exts=rs,js,html,css --on-busy-update=restart -- cargo run
6 |
7 | run:
8 | cargo run
9 |
10 | test:
11 | cargo test
12 |
13 | watch-tests:
14 | watch . { cargo test } --glob=**/*.rs
15 |
16 | expected_filename := if os_family() == "windows" { "escape-artist.exe" } else { "escape-artist" }
17 |
18 | build-release:
19 | cargo build --release
20 | ls target/release
21 |
22 | publish-to-local-bin: build-release
23 | cp target/release/{{expected_filename}} ~/bin/
24 |
25 | build-linux-x64:
26 | cross build --target x86_64-unknown-linux-gnu --release
27 |
28 | build-linux-arm64:
29 | cross build --target aarch64-unknown-linux-gnu --release
30 |
31 | build-windows-on-linux:
32 | cross build --target x86_64-pc-windows-gnu --release
33 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | on:
2 | release:
3 | types: [created]
4 |
5 | jobs:
6 | upload-assets:
7 | strategy:
8 | matrix:
9 | include:
10 | - target: aarch64-unknown-linux-musl
11 | os: ubuntu-latest
12 | - target: x86_64-unknown-linux-musl
13 | os: ubuntu-latest
14 | - target: x86_64-pc-windows-msvc
15 | os: windows-latest
16 | - target: x86_64-apple-darwin
17 | os: macos-latest
18 | - target: aarch64-apple-darwin
19 | os: macos-latest
20 | runs-on: ${{ matrix.os }}
21 | steps:
22 | - uses: actions/checkout@v4
23 | - uses: taiki-e/upload-rust-binary-action@v1
24 | with:
25 | # (required) Comma-separated list of binary names (non-extension portion of filename) to build and upload.
26 | # Note that glob pattern is not supported yet.
27 | bin: escape-artist
28 | target: ${{ matrix.target }}
29 | # (required) GitHub token for uploading assets to GitHub Releases.
30 | token: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "escape-artist"
3 | description = "A visualizer for terminal escape sequences"
4 | homepage = "https://github.com/rgwood/escape-artist"
5 | repository = "https://github.com/rgwood/escape-artist"
6 | version = "0.6.7"
7 | edition = "2021"
8 | license = "MIT"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [build-dependencies]
13 | is-docker = "0.2.0"
14 |
15 | [dependencies]
16 | anyhow = "1.0.70"
17 | crossterm = "0.27.0"
18 | portable-pty = "0.8.1"
19 |
20 | axum = { version = "0.7.4", features = ["macros", "ws"] }
21 | serde = { version = "1.0.159", features = ["derive", "rc"] }
22 | serde_json = "1.0.95"
23 | tokio = { version = "1.27.0", features = ["full"] }
24 | clap = { version = "4.5.4", features = ["derive"] }
25 | rust-embed = { version = "8.2.0", features = ["axum-ex"] }
26 | mime_guess = "2.0.4"
27 | open = "5.0.1"
28 | rand = "0.8.5"
29 | signal-hook = "0.3.15"
30 | termwiz = "0.22.0"
31 | ansi_colours = "1.2.2"
32 | iconify = "0.3.0"
33 |
34 | [profile.release]
35 | lto = true # Enable Link Time Optimization
36 | opt-level = 'z' # Optimize for size.
37 | panic = 'abort' # Abort on panic
38 |
39 |
40 | # codegen-units = 1 # Set low to increase optimizations. Kills compile time though
41 | # strip = true # Strip symbols from binary. Big gains but idk if it's worth bad stack traces
42 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "lldb",
9 | "request": "launch",
10 | "name": "Debug executable 'escape-artist'",
11 | "cargo": {
12 | "args": [
13 | "build",
14 | "--bin=escape-artist",
15 | "--package=escape-artist"
16 | ],
17 | "filter": {
18 | "name": "escape-artist",
19 | "kind": "bin"
20 | }
21 | },
22 | "args": [],
23 | "cwd": "${workspaceFolder}"
24 | },
25 | {
26 | "type": "lldb",
27 | "request": "launch",
28 | "name": "Debug unit tests in executable 'escape-artist'",
29 | "cargo": {
30 | "args": [
31 | "test",
32 | "--no-run",
33 | "--bin=escape-artist",
34 | "--package=escape-artist"
35 | ],
36 | "filter": {
37 | "name": "escape-artist",
38 | "kind": "bin"
39 | }
40 | },
41 | "args": [],
42 | "cwd": "${workspaceFolder}"
43 | }
44 | ]
45 | }
--------------------------------------------------------------------------------
/embed/htm.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bundled by jsDelivr using Rollup v2.74.1 and Terser v5.15.1.
3 | * Original file: /npm/htm@3.1.1/dist/htm.module.js
4 | *
5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6 | */
7 | var n=function(t,s,r,e){var u;s[0]=0;for(var h=1;h=5&&((e||!n&&5===r)&&(h.push(r,0,e,s),r=6),n&&(h.push(r,n,0,s),r=6)),e=""},a=0;a"===t?(r=1,e=""):e=t+e[0]:u?t===u?u="":e+=t:'"'===t||"'"===t?u=t:">"===t?(p(),r=1):r&&("="===t?(r=5,s=e,e=""):"/"===t&&(r<5||">"===n[a][l+1])?(p(),3===r&&(h=h[0]),r=h,(h=h[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(p(),r=2):e+=t),3===r&&"!--"===e&&(r=4,h=h[0])}return p(),h}(s)),r),arguments,[])).length>1?r:r[0]}export{s as default};
8 | //# sourceMappingURL=/sm/3761d505ff1a3e54bcae3398870b93c29140cc811be53bcd0f48a4808c639b51.map
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Escape Artist
2 |
3 | Escape Artist is a tool for seeing ANSI escape codes in terminal applications. You interact with your shell just like you normally would, and it shows the normally-invisible escape codes in a web UI:
4 |
5 | 
6 |
7 | ## Installation
8 |
9 | Binaries for major OSs+architectures are attached to the GitHub releases, download+expand one and put it in your PATH. Alternately, you can build+install with Rust's Cargo package manager. [Install Rust](https://rustup.rs/), then run `cargo install escape-artist`
10 |
11 | After that, you can launch Escape Artist by running `escape-artist` in your terminal.
12 |
13 | ## Project Status
14 |
15 | This was hacked together for the [Handmade Network Visibility Jam](https://handmade.network/jam/visibility-2023), so it might be a little rough around the edges. It's primarily been developed on Linux, but I used cross-platform libraries and my limited testing on Windows+macOS has gone well.
16 |
17 | ## FAQ
18 |
19 | **Q:** What are ANSI escape codes?
20 |
21 | **A:** "Invisible" byte sequences that are printed by console applications to stdout and stderr, then interpreted by your terminal emulator. For example, an escape code might tell the terminal to paint all text green until further notice. There are several kinds of escape sequences, [this page](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797) is a great reference.
22 |
23 | **Q:** What does Escape Artist do?
24 |
25 | **A:** It launches your shell in a [pseudoterminal](https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/#enter-the-pseudo-terminal-pty) (AKA a pty) and starts a web interface where you can view the output of the shell with escape sequences made visible. You can mouse over individual escape codes to see their raw bytes and (sometimes) a description of what the escape code does.
26 |
27 | **Q:** Why is this useful?
28 |
29 | **A:** It's kinda like View Source for the terminal. Maybe you're curious about what your shell is doing to render your cool new prompt. Maybe you work on a shell or a TUI application and you need to debug it.
30 |
31 | **Q:** How can I configure Escape Artist?
32 |
33 | **A:** Run Escape Artist with the `-h` or `--help` flag to see all possible options.
34 |
35 | ## Contributions
36 |
37 | Contributions are welcome! This project could certainly use some polish.
38 |
39 | Note that I am trying to keep the web front-end of this project as simple as possible. The project currently has no front-end build step, and I would like to keep it that way unless a *very* compelling reason comes along.
--------------------------------------------------------------------------------
/notes.md:
--------------------------------------------------------------------------------
1 | https://asciinema.org/docs/how-it-works
2 |
3 | > A pseudo terminal is a pair of pseudo-devices, one of which, the slave, emulates a real text terminal device, the other of which, the master, provides the means by which a terminal emulator process controls the slave.
4 |
5 | > The role of the terminal emulator process is to interact with the user; to feed text input to the master pseudo-device for use by the shell (which is connected to the slave pseudo-device) and to read text output from the master pseudo-device and show it to the user.
6 |
7 | We need to:
8 |
9 | 1. spin up a pty
10 | 2. launch Nu and hook it up to the pty
11 | 1. base this on: https://github.com/rgwood/pty-driver/blob/master/src/main.rs
12 | 3. handle output from Nu and input from the keyboard
13 |
14 | Useful reading:
15 | https://poor.dev/blog/terminal-anatomy/
16 |
17 | # TO DO
18 |
19 | - [ ] Centralize the "add an Action to the Vec of all records and send the new action to any listeners (debounced)" logic
20 | - [ ] Make newlines take up less vertical space. Solution: Add a new InvisibleLineBreak dto that we send before+after CR+LF
21 | - [ ] Show colours in tooltip (border?) instead of just "PaletteIndex(2)" or whatever
22 | - [x] use a nerd font
23 | - [x] handle failure to get a socket with a nicer error message
24 | - [x] print stack trace automatically
25 | - [ ] show raw bytes for line breaks
26 | - [x] embed all js libs so it works offline
27 | - [x] add an option to log to a file
28 | - [x] coalesce multiple chars into a single string event, cut down on data transfer and work for the front-end
29 | - [x] add a favicon
30 | - [x] use open-rs to launch to page in a browser
31 | - [x] add help page
32 | - [x] use rust-embed to serve files https://github.com/pyrossh/rust-embed
33 | - [x] show raw bytes for other
34 | - [x] display raw bytes better. replace control codes
35 | - [x] hide tooltip description when not exists
36 | - [x] use floating-ui for a custom tooltip
37 | - [x] display raw bytes in tooltip
38 | - [x] wrap items, don't overflow horizontally
39 | - [x] Use clap or argh or similar
40 | - [x] Debounce/chunk streaming events to cut down on #renders
41 | - [x] send a "disconnected" message to web browser when exiting
42 | - [x] Move more logic to Rust. Send to-be-displayed info as a new type
43 | - [x] Start using VTE to parse output stream: https://github.com/alacritty/vte
44 | - [x] Spin up web UI (Axum?)
45 | - [x] Start logging all events
46 | - [x] Send tokens to web UI
47 | - [x] Why doesn't it render prompt?
48 | - Maybe because the cursor is on the prompt line. Do I need to disable cursor?
49 | - Was because I was forgetting to flush stdin
50 | - [x] Figure out why update is so infrequent (and only prompted by several keypresses)
51 | - [x] Reset raw mode etc. when child Nu exits
52 | - [x] Can/should I detect ctrl+D/SIGQUIT? Or when the child dies more generally?
53 | - if we get an EOF from nu stdout...
--------------------------------------------------------------------------------
/embed/script.js:
--------------------------------------------------------------------------------
1 | import { h, render } from "/preact.js";
2 | import htm from "/htm.js";
3 | import {
4 | computePosition,
5 | flip,
6 | shift,
7 | offset,
8 | arrow
9 | } from '/floating-ui.dom.js'
10 |
11 | const html = htm.bind(h);
12 |
13 | let url = new URL("/events", window.location.href);
14 | // http => ws
15 | // https => wss
16 | url.protocol = url.protocol.replace("http", "ws");
17 |
18 | let events = [];
19 |
20 | function showTooltip(event) {
21 | const tooltip = document.querySelector('#tooltip');
22 | tooltip.style.display = 'block';
23 | update(event.target);
24 | }
25 |
26 | function Event(props) {
27 | let dto = props.dto;
28 | const shared_classes = "w-fit outline outline-1 rounded-sm px-1 m-1 bg-slate-800"
29 | switch (dto.type) {
30 | case "Print":
31 | if (!!dto.color && !!dto.bg_color) {
32 | return html`${dto.string} `
33 | } else if (!!dto.color) {
34 | return html`${dto.string} `
35 | } else if (!!dto.bg_color) {
36 | return html`${dto.string} `
37 | } else {
38 | return html`${dto.string} `;
39 | }
40 | case "GenericEscape": {
41 | let svg = dto.icon_svg ? html` ` : html``;
42 | let title = dto.title ? html`${dto.title} ` : ``;
43 | return html`
52 | ${svg}
53 | ${title}
54 |
`;
55 | }
56 | case "ColorEscape": {
57 | let svg = dto.icon_svg ? html` ` : html``;
58 | let title = dto.title ? html`${dto.title} ` : ``;
59 | return html`
68 | ${svg}
69 | ${title}
70 |
`;
71 | }
72 | case "InvisibleLineBreak": {
73 | return html`
`;
74 | }
75 | case "LineBreak": {
76 | return html`
77 |
78 | ${dto.title}
79 | `;
80 | }
81 | case "Disconnected": {
82 | return html`
83 | Disconnected
84 |
`;
85 | }
86 | default:
87 | return html`${dto.type} `;
88 | }
89 | }
90 |
91 | let ws = new WebSocket(url.href);
92 | ws.onmessage = async (ev) => {
93 | let deserialized = JSON.parse(ev.data);
94 | for (const event of deserialized) {
95 | events.push(event);
96 | // console.log(event);
97 | }
98 | renderAndScroll();
99 | };
100 |
101 | ws.onclose = (_) => {
102 | events.push({ type: "Disconnected" });
103 | renderAndScroll();
104 | };
105 |
106 | function renderAndScroll() {
107 | render(
108 | html`
109 |
116 | ${events.map((event) => html`<${Event} dto="${event}" />`)}
117 | `,
118 | document.body
119 | );
120 | window.scrollTo(0, document.body.scrollHeight);
121 | }
122 |
123 | function update(element) {
124 | const tooltip = document.querySelector('#tooltip');
125 | const arrowElement = document.querySelector('#arrow');
126 |
127 | const tooltipDescriptionElement = tooltip.querySelector("#description");
128 | if (!!element.dataset.tooltip) {
129 | tooltipDescriptionElement.style.display = 'block';
130 | tooltipDescriptionElement.innerHTML = element.dataset.tooltip;
131 | } else {
132 | tooltipDescriptionElement.style.display = 'none';
133 | }
134 |
135 | const tooltipRawBytes = tooltip.querySelector("#rawbytes");
136 | tooltipRawBytes.innerHTML = element.dataset.rawbytes;
137 |
138 | computePosition(element, tooltip, {
139 | placement: 'top',
140 | middleware: [
141 | offset(6),
142 | flip(),
143 | shift({ padding: 5 }),
144 | arrow({ element: arrowElement }),
145 | ],
146 | }).then(({ x, y, placement, middlewareData }) => {
147 | Object.assign(tooltip.style, {
148 | left: `${x}px`,
149 | top: `${y}px`,
150 | });
151 |
152 | const { x: arrowX, y: arrowY } = middlewareData.arrow;
153 | const staticSide = {
154 | top: 'bottom',
155 | right: 'left',
156 | bottom: 'top',
157 | left: 'right',
158 | }[placement.split('-')[0]];
159 |
160 | Object.assign(arrowElement.style, {
161 | left: arrowX != null ? `${arrowX}px` : '',
162 | top: arrowY != null ? `${arrowY}px` : '',
163 | right: '',
164 | bottom: '',
165 | [staticSide]: '-4px',
166 | });
167 | });
168 |
169 | }
170 |
171 | function hideTooltip() {
172 | const tooltip = document.querySelector('#tooltip');
173 | tooltip.style.display = 'none';
174 | }
175 |
--------------------------------------------------------------------------------
/embed/floating-ui.dom.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bundled by jsDelivr using Rollup v2.74.1 and Terser v5.15.1.
3 | * Original file: /npm/@floating-ui/dom@1.2.6/dist/floating-ui.dom.browser.min.mjs
4 | *
5 | * modified by reilly to reference a local @floating-ui/core
6 | */
7 | import{rectToClientRect as t,computePosition as e}from"/floating-ui.core.js";
8 | export{arrow,autoPlacement,detectOverflow,flip,hide,inline,limitShift,offset,shift,size}from"/floating-ui.core.js";
9 | function n(t){var e;return(null==(e=t.ownerDocument)?void 0:e.defaultView)||window}function o(t){return n(t).getComputedStyle(t)}function i(t){return t instanceof n(t).Node}function r(t){return i(t)?(t.nodeName||"").toLowerCase():""}let l;function c(){if(l)return l;const t=navigator.userAgentData;return t&&Array.isArray(t.brands)?(l=t.brands.map((t=>t.brand+"/"+t.version)).join(" "),l):navigator.userAgent}function s(t){return t instanceof n(t).HTMLElement}function f(t){return t instanceof n(t).Element}function u(t){return"undefined"!=typeof ShadowRoot&&(t instanceof n(t).ShadowRoot||t instanceof ShadowRoot)}function a(t){const{overflow:e,overflowX:n,overflowY:i,display:r}=o(t);return/auto|scroll|overlay|hidden|clip/.test(e+i+n)&&!["inline","contents"].includes(r)}function d(t){return["table","td","th"].includes(r(t))}function h(t){const e=/firefox/i.test(c()),n=o(t),i=n.backdropFilter||n.WebkitBackdropFilter;return"none"!==n.transform||"none"!==n.perspective||!!i&&"none"!==i||e&&"filter"===n.willChange||e&&!!n.filter&&"none"!==n.filter||["transform","perspective"].some((t=>n.willChange.includes(t)))||["paint","layout","strict","content"].some((t=>{const e=n.contain;return null!=e&&e.includes(t)}))}function p(){return/^((?!chrome|android).)*safari/i.test(c())}function m(t){return["html","body","#document"].includes(r(t))}const g=Math.min,y=Math.max,x=Math.round;function w(t){const e=o(t);let n=parseFloat(e.width),i=parseFloat(e.height);const r=s(t),l=r?t.offsetWidth:n,c=r?t.offsetHeight:i,f=x(n)!==l||x(i)!==c;return f&&(n=l,i=c),{width:n,height:i,fallback:f}}function v(t){return f(t)?t:t.contextElement}const b={x:1,y:1};function L(t){const e=v(t);if(!s(e))return b;const n=e.getBoundingClientRect(),{width:o,height:i,fallback:r}=w(e);let l=(r?x(n.width):n.width)/o,c=(r?x(n.height):n.height)/i;return l&&Number.isFinite(l)||(l=1),c&&Number.isFinite(c)||(c=1),{x:l,y:c}}function E(e,o,i,r){var l,c;void 0===o&&(o=!1),void 0===i&&(i=!1);const s=e.getBoundingClientRect(),u=v(e);let a=b;o&&(r?f(r)&&(a=L(r)):a=L(e));const d=u?n(u):window,h=p()&&i;let m=(s.left+(h&&(null==(l=d.visualViewport)?void 0:l.offsetLeft)||0))/a.x,g=(s.top+(h&&(null==(c=d.visualViewport)?void 0:c.offsetTop)||0))/a.y,y=s.width/a.x,x=s.height/a.y;if(u){const t=n(u),e=r&&f(r)?n(r):r;let o=t.frameElement;for(;o&&r&&e!==t;){const t=L(o),e=o.getBoundingClientRect(),i=getComputedStyle(o);e.x+=(o.clientLeft+parseFloat(i.paddingLeft))*t.x,e.y+=(o.clientTop+parseFloat(i.paddingTop))*t.y,m*=t.x,g*=t.y,y*=t.x,x*=t.y,m+=e.x,g+=e.y,o=n(o).frameElement}}return t({width:y,height:x,x:m,y:g})}function T(t){return((i(t)?t.ownerDocument:t.document)||window.document).documentElement}function R(t){return f(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop}:{scrollLeft:t.pageXOffset,scrollTop:t.pageYOffset}}function C(t){return E(T(t)).left+R(t).scrollLeft}function F(t){if("html"===r(t))return t;const e=t.assignedSlot||t.parentNode||u(t)&&t.host||T(t);return u(e)?e.host:e}function W(t){const e=F(t);return m(e)?e.ownerDocument.body:s(e)&&a(e)?e:W(e)}function A(t,e){var o;void 0===e&&(e=[]);const i=W(t),r=i===(null==(o=t.ownerDocument)?void 0:o.body),l=n(i);return r?e.concat(l,l.visualViewport||[],a(i)?i:[]):e.concat(i,A(i))}function D(e,i,r){let l;if("viewport"===i)l=function(t,e){const o=n(t),i=T(t),r=o.visualViewport;let l=i.clientWidth,c=i.clientHeight,s=0,f=0;if(r){l=r.width,c=r.height;const t=p();(!t||t&&"fixed"===e)&&(s=r.offsetLeft,f=r.offsetTop)}return{width:l,height:c,x:s,y:f}}(e,r);else if("document"===i)l=function(t){const e=T(t),n=R(t),i=t.ownerDocument.body,r=y(e.scrollWidth,e.clientWidth,i.scrollWidth,i.clientWidth),l=y(e.scrollHeight,e.clientHeight,i.scrollHeight,i.clientHeight);let c=-n.scrollLeft+C(t);const s=-n.scrollTop;return"rtl"===o(i).direction&&(c+=y(e.clientWidth,i.clientWidth)-r),{width:r,height:l,x:c,y:s}}(T(e));else if(f(i))l=function(t,e){const n=E(t,!0,"fixed"===e),o=n.top+t.clientTop,i=n.left+t.clientLeft,r=s(t)?L(t):{x:1,y:1};return{width:t.clientWidth*r.x,height:t.clientHeight*r.y,x:i*r.x,y:o*r.y}}(i,r);else{const t={...i};if(p()){var c,u;const o=n(e);t.x-=(null==(c=o.visualViewport)?void 0:c.offsetLeft)||0,t.y-=(null==(u=o.visualViewport)?void 0:u.offsetTop)||0}l=t}return t(l)}function S(t,e){return s(t)&&"fixed"!==o(t).position?e?e(t):t.offsetParent:null}function H(t,e){const i=n(t);if(!s(t))return i;let l=S(t,e);for(;l&&d(l)&&"static"===o(l).position;)l=S(l,e);return l&&("html"===r(l)||"body"===r(l)&&"static"===o(l).position&&!h(l))?i:l||function(t){let e=F(t);for(;s(e)&&!m(e);){if(h(e))return e;e=F(e)}return null}(t)||i}function O(t,e,n){const o=s(e),i=T(e),l=E(t,!0,"fixed"===n,e);let c={scrollLeft:0,scrollTop:0};const f={x:0,y:0};if(o||!o&&"fixed"!==n)if(("body"!==r(e)||a(i))&&(c=R(e)),s(e)){const t=E(e,!0);f.x=t.x+e.clientLeft,f.y=t.y+e.clientTop}else i&&(f.x=C(i));return{x:l.left+c.scrollLeft-f.x,y:l.top+c.scrollTop-f.y,width:l.width,height:l.height}}const V={getClippingRect:function(t){let{element:e,boundary:n,rootBoundary:i,strategy:l}=t;const c="clippingAncestors"===n?function(t,e){const n=e.get(t);if(n)return n;let i=A(t).filter((t=>f(t)&&"body"!==r(t))),l=null;const c="fixed"===o(t).position;let s=c?F(t):t;for(;f(s)&&!m(s);){const t=o(s),e=h(s);"fixed"===t.position&&(l=null),(c?e||l:e||"static"!==t.position||!l||!["absolute","fixed"].includes(l.position))?l=t:i=i.filter((t=>t!==s)),s=F(s)}return e.set(t,i),i}(e,this._c):[].concat(n),s=[...c,i],u=s[0],a=s.reduce(((t,n)=>{const o=D(e,n,l);return t.top=y(o.top,t.top),t.right=g(o.right,t.right),t.bottom=g(o.bottom,t.bottom),t.left=y(o.left,t.left),t}),D(e,u,l));return{width:a.right-a.left,height:a.bottom-a.top,x:a.left,y:a.top}},convertOffsetParentRelativeRectToViewportRelativeRect:function(t){let{rect:e,offsetParent:n,strategy:o}=t;const i=s(n),l=T(n);if(n===l)return e;let c={scrollLeft:0,scrollTop:0},f={x:1,y:1};const u={x:0,y:0};if((i||!i&&"fixed"!==o)&&(("body"!==r(n)||a(l))&&(c=R(n)),s(n))){const t=E(n);f=L(n),u.x=t.x+n.clientLeft,u.y=t.y+n.clientTop}return{width:e.width*f.x,height:e.height*f.y,x:e.x*f.x-c.scrollLeft*f.x+u.x,y:e.y*f.y-c.scrollTop*f.y+u.y}},isElement:f,getDimensions:function(t){return w(t)},getOffsetParent:H,getDocumentElement:T,getScale:L,async getElementRects(t){let{reference:e,floating:n,strategy:o}=t;const i=this.getOffsetParent||H,r=this.getDimensions;return{reference:O(e,await i(n),o),floating:{x:0,y:0,...await r(n)}}},getClientRects:t=>Array.from(t.getClientRects()),isRTL:t=>"rtl"===o(t).direction};function P(t,e,n,o){void 0===o&&(o={});const{ancestorScroll:i=!0,ancestorResize:r=!0,elementResize:l=!0,animationFrame:c=!1}=o,s=i&&!c,u=s||r?[...f(t)?A(t):t.contextElement?A(t.contextElement):[],...A(e)]:[];u.forEach((t=>{s&&t.addEventListener("scroll",n,{passive:!0}),r&&t.addEventListener("resize",n)}));let a,d=null;l&&(d=new ResizeObserver((()=>{n()})),f(t)&&!c&&d.observe(t),f(t)||!t.contextElement||c||d.observe(t.contextElement),d.observe(e));let h=c?E(t):null;return c&&function e(){const o=E(t);!h||o.x===h.x&&o.y===h.y&&o.width===h.width&&o.height===h.height||n(),h=o,a=requestAnimationFrame(e)}(),n(),()=>{var t;u.forEach((t=>{s&&t.removeEventListener("scroll",n),r&&t.removeEventListener("resize",n)})),null==(t=d)||t.disconnect(),d=null,c&&cancelAnimationFrame(a)}}const z=(t,n,o)=>{const i=new Map,r={platform:V,...o},l={...r.platform,_c:i};return e(t,n,{...r,platform:l})};export{P as autoUpdate,z as computePosition,A as getOverflowAncestors,V as platform};export default null;
10 | //# sourceMappingURL=/sm/62f33e65313515a4dbd66159fdaef9f3d2feaa0eee1ec4c18863e731f360a2e3.map
--------------------------------------------------------------------------------
/embed/preact.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bundled by jsDelivr using Rollup v2.74.1 and Terser v5.15.1.
3 | * Original file: /npm/preact@10.13.2/dist/preact.module.js
4 | *
5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6 | */
7 | var e,n,t,_,l,o,r,i,u,s={},c=[],f=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function p(e,n){for(var t in n)e[t]=n[t];return e}function a(e){var n=e.parentNode;n&&n.removeChild(e)}function d(n,t,_){var l,o,r,i={};for(r in t)"key"==r?l=t[r]:"ref"==r?o=t[r]:i[r]=t[r];if(arguments.length>2&&(i.children=arguments.length>3?e.call(arguments,2):_),"function"==typeof n&&null!=n.defaultProps)for(r in n.defaultProps)void 0===i[r]&&(i[r]=n.defaultProps[r]);return h(n,i,l,o,null)}function h(e,_,l,o,r){var i={type:e,props:_,key:l,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++t:r};return null==r&&null!=n.vnode&&n.vnode(i),i}function v(){return{current:null}}function y(e){return e.children}function m(e,n){this.props=e,this.context=n}function g(e,n){if(null==n)return e.__?g(e.__,e.__.__k.indexOf(e)+1):null;for(var t;nn&&l.sort(i));x.__r=0}function C(e,n,t,_,l,o,r,i,u,f){var p,a,d,v,m,k,b,x=_&&_.__k||c,C=x.length;for(t.__k=[],p=0;p0?h(v.type,v.props,v.key,v.ref?v.ref:null,v.__v):v)){if(v.__=t,v.__b=t.__b+1,null===(d=x[p])||d&&v.key==d.key&&v.type===d.type)x[p]=void 0;else for(a=0;a=0;n--)if((t=e.__k[n])&&(_=E(t)))return _;return null}function U(e,n,t,_,l){var o;for(o in t)"children"===o||"key"===o||o in n||D(e,o,null,t[o],_);for(o in n)l&&"function"!=typeof n[o]||"children"===o||"key"===o||"value"===o||"checked"===o||t[o]===n[o]||D(e,o,n[o],t[o],_)}function A(e,n,t){"-"===n[0]?e.setProperty(n,null==t?"":t):e[n]=null==t?"":"number"!=typeof t||f.test(n)?t:t+"px"}function D(e,n,t,_,l){var o;e:if("style"===n)if("string"==typeof t)e.style.cssText=t;else{if("string"==typeof _&&(e.style.cssText=_=""),_)for(n in _)t&&n in t||A(e.style,n,"");if(t)for(n in t)_&&t[n]===_[n]||A(e.style,n,t[n])}else if("o"===n[0]&&"n"===n[1])o=n!==(n=n.replace(/Capture$/,"")),n=n.toLowerCase()in e?n.toLowerCase().slice(2):n.slice(2),e.l||(e.l={}),e.l[n+o]=t,t?_||e.addEventListener(n,o?N:T,o):e.removeEventListener(n,o?N:T,o);else if("dangerouslySetInnerHTML"!==n){if(l)n=n.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==n&&"height"!==n&&"href"!==n&&"list"!==n&&"form"!==n&&"tabIndex"!==n&&"download"!==n&&n in e)try{e[n]=null==t?"":t;break e}catch(e){}"function"==typeof t||(null==t||!1===t&&"-"!==n[4]?e.removeAttribute(n):e.setAttribute(n,t))}}function T(e){return this.l[e.type+!1](n.event?n.event(e):e)}function N(e){return this.l[e.type+!0](n.event?n.event(e):e)}function W(e,t,_,l,o,r,i,u,s){var c,f,a,d,h,v,g,k,b,x,S,P,w,E,U,A=t.type;if(void 0!==t.constructor)return null;null!=_.__h&&(s=_.__h,u=t.__e=_.__e,t.__h=null,r=[u]),(c=n.__b)&&c(t);try{e:if("function"==typeof A){if(k=t.props,b=(c=A.contextType)&&l[c.__c],x=c?b?b.props.value:c.__:l,_.__c?g=(f=t.__c=_.__c).__=f.__E:("prototype"in A&&A.prototype.render?t.__c=f=new A(k,x):(t.__c=f=new m(k,x),f.constructor=A,f.render=R),b&&b.sub(f),f.props=k,f.state||(f.state={}),f.context=x,f.__n=l,a=f.__d=!0,f.__h=[],f._sb=[]),null==f.__s&&(f.__s=f.state),null!=A.getDerivedStateFromProps&&(f.__s==f.state&&(f.__s=p({},f.__s)),p(f.__s,A.getDerivedStateFromProps(k,f.__s))),d=f.props,h=f.state,f.__v=t,a)null==A.getDerivedStateFromProps&&null!=f.componentWillMount&&f.componentWillMount(),null!=f.componentDidMount&&f.__h.push(f.componentDidMount);else{if(null==A.getDerivedStateFromProps&&k!==d&&null!=f.componentWillReceiveProps&&f.componentWillReceiveProps(k,x),!f.__e&&null!=f.shouldComponentUpdate&&!1===f.shouldComponentUpdate(k,f.__s,x)||t.__v===_.__v){for(t.__v!==_.__v&&(f.props=k,f.state=f.__s,f.__d=!1),f.__e=!1,t.__e=_.__e,t.__k=_.__k,t.__k.forEach((function(e){e&&(e.__=t)})),S=0;S2&&(i.children=arguments.length>3?e.call(arguments,2):_),h(n.type,i,l||n.key,o||n.ref,null)}function V(e,n){var t={__c:n="__cC"+u++,__:e,Consumer:function(e,n){return e.children(n)},Provider:function(e){var t,_;return this.getChildContext||(t=[],(_={})[n]=this,this.getChildContext=function(){return _},this.shouldComponentUpdate=function(e){this.props.value!==e.value&&t.some((function(e){e.__e=!0,b(e)}))},this.sub=function(e){t.push(e);var n=e.componentWillUnmount;e.componentWillUnmount=function(){t.splice(t.indexOf(e),1),n&&n.call(e)}}),e.children}};return t.Provider.__=t.Consumer.contextType=t}e=c.slice,n={__e:function(e,n,t,_){for(var l,o,r;n=n.__;)if((l=n.__c)&&!l.__)try{if((o=l.constructor)&&null!=o.getDerivedStateFromError&&(l.setState(o.getDerivedStateFromError(e)),r=l.__d),null!=l.componentDidCatch&&(l.componentDidCatch(e,_||{}),r=l.__d),r)return l.__E=l}catch(n){e=n}throw e}},t=0,_=function(e){return null!=e&&void 0===e.constructor},m.prototype.setState=function(e,n){var t;t=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=p({},this.state),"function"==typeof e&&(e=e(p({},t),this.props)),e&&p(t,e),null!=e&&this.__v&&(n&&this._sb.push(n),b(this))},m.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),b(this))},m.prototype.render=y,l=[],r="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,i=function(e,n){return e.__v.__b-n.__v.__b},x.__r=0,u=0;export{m as Component,y as Fragment,B as cloneElement,V as createContext,d as createElement,v as createRef,d as h,O as hydrate,_ as isValidElement,n as options,I as render,P as toChildArray};export default null;
8 | //# sourceMappingURL=/sm/dec0c4067c9ef4363240642b0bdf3856d5c2009b70ca3ce526c13620b48009a4.map
--------------------------------------------------------------------------------
/embed/floating-ui.core.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bundled by jsDelivr using Rollup v2.74.1 and Terser v5.15.1.
3 | * Original file: /npm/@floating-ui/core@1.2.6/dist/floating-ui.core.browser.min.mjs
4 | *
5 | * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
6 | */
7 | function t(t){return t.split("-")[1]}function e(t){return"y"===t?"height":"width"}function n(t){return t.split("-")[0]}function o(t){return["top","bottom"].includes(n(t))?"x":"y"}function i(i,r,a){let{reference:l,floating:s}=i;const c=l.x+l.width/2-s.width/2,f=l.y+l.height/2-s.height/2,m=o(r),u=e(m),g=l[u]/2-s[u]/2,d="x"===m;let p;switch(n(r)){case"top":p={x:c,y:l.y-s.height};break;case"bottom":p={x:c,y:l.y+l.height};break;case"right":p={x:l.x+l.width,y:f};break;case"left":p={x:l.x-s.width,y:f};break;default:p={x:l.x,y:l.y}}switch(t(r)){case"start":p[m]-=g*(a&&d?-1:1);break;case"end":p[m]+=g*(a&&d?-1:1)}return p}const r=async(t,e,n)=>{const{placement:o="bottom",strategy:r="absolute",middleware:a=[],platform:l}=n,s=a.filter(Boolean),c=await(null==l.isRTL?void 0:l.isRTL(e));let f=await l.getElementRects({reference:t,floating:e,strategy:r}),{x:m,y:u}=i(f,o,c),g=o,d={},p=0;for(let n=0;n({name:"arrow",options:n,async fn(i){const{element:r,padding:l=0}=n||{},{x:s,y:c,placement:f,rects:u,platform:g,elements:d}=i;if(null==r)return{};const p=a(l),h={x:s,y:c},y=o(f),x=e(y),w=await g.getDimensions(r),v="y"===y,b=v?"top":"left",A=v?"bottom":"right",R=v?"clientHeight":"clientWidth",P=u.reference[x]+u.reference[y]-h[y]-u.floating[x],T=h[y]-u.reference[y],E=await(null==g.getOffsetParent?void 0:g.getOffsetParent(r));let D=E?E[R]:0;D&&await(null==g.isElement?void 0:g.isElement(E))||(D=d.floating[R]||u.floating[x]);const L=P/2-T/2,O=p[b],k=D-w[x]-p[A],C=D/2-w[x]/2+L,B=m(O,C,k),H=null!=t(f)&&C!=B&&u.reference[x]/2-(Ct.concat(e,e+"-start",e+"-end")),[]),p={left:"right",right:"left",bottom:"top",top:"bottom"};function h(t){return t.replace(/left|right|bottom|top/g,(t=>p[t]))}function y(n,i,r){void 0===r&&(r=!1);const a=t(n),l=o(n),s=e(l);let c="x"===l?a===(r?"end":"start")?"right":"left":"start"===a?"bottom":"top";return i.reference[s]>i.floating[s]&&(c=h(c)),{main:c,cross:h(c)}}const x={start:"end",end:"start"};function w(t){return t.replace(/start|end/g,(t=>x[t]))}const v=function(e){return void 0===e&&(e={}),{name:"autoPlacement",options:e,async fn(o){var i,r,a;const{rects:l,middlewareData:c,placement:f,platform:m,elements:u}=o,{crossAxis:g=!1,alignment:p,allowedPlacements:h=d,autoAlignment:x=!0,...v}=e,b=void 0!==p||h===d?function(e,o,i){return(e?[...i.filter((n=>t(n)===e)),...i.filter((n=>t(n)!==e))]:i.filter((t=>n(t)===t))).filter((n=>!e||t(n)===e||!!o&&w(n)!==n))}(p||null,x,h):h,A=await s(o,v),R=(null==(i=c.autoPlacement)?void 0:i.index)||0,P=b[R];if(null==P)return{};const{main:T,cross:E}=y(P,l,await(null==m.isRTL?void 0:m.isRTL(u.floating)));if(f!==P)return{reset:{placement:b[0]}};const D=[A[n(P)],A[T],A[E]],L=[...(null==(r=c.autoPlacement)?void 0:r.overflows)||[],{placement:P,overflows:D}],O=b[R+1];if(O)return{data:{index:R+1,overflows:L},reset:{placement:O}};const k=L.map((e=>{const n=t(e.placement);return[e.placement,n&&g?e.overflows.slice(0,2).reduce(((t,e)=>t+e),0):e.overflows[0],e.overflows]})).sort(((t,e)=>t[1]-e[1])),C=(null==(a=k.filter((e=>e[2].slice(0,t(e[0])?2:3).every((t=>t<=0))))[0])?void 0:a[0])||k[0][0];return C!==f?{data:{index:R+1,overflows:L},reset:{placement:C}}:{}}}},b=function(e){return void 0===e&&(e={}),{name:"flip",options:e,async fn(o){var i;const{placement:r,middlewareData:a,rects:l,initialPlacement:c,platform:f,elements:m}=o,{mainAxis:u=!0,crossAxis:g=!0,fallbackPlacements:d,fallbackStrategy:p="bestFit",fallbackAxisSideDirection:x="none",flipAlignment:v=!0,...b}=e,A=n(r),R=n(c)===c,P=await(null==f.isRTL?void 0:f.isRTL(m.floating)),T=d||(R||!v?[h(c)]:function(t){const e=h(t);return[w(t),e,w(e)]}(c));d||"none"===x||T.push(...function(e,o,i,r){const a=t(e);let l=function(t,e,n){const o=["left","right"],i=["right","left"],r=["top","bottom"],a=["bottom","top"];switch(t){case"top":case"bottom":return n?e?i:o:e?o:i;case"left":case"right":return e?r:a;default:return[]}}(n(e),"start"===i,r);return a&&(l=l.map((t=>t+"-"+a)),o&&(l=l.concat(l.map(w)))),l}(c,v,x,P));const E=[c,...T],D=await s(o,b),L=[];let O=(null==(i=a.flip)?void 0:i.overflows)||[];if(u&&L.push(D[A]),g){const{main:t,cross:e}=y(r,l,P);L.push(D[t],D[e])}if(O=[...O,{placement:r,overflows:L}],!L.every((t=>t<=0))){var k,C;const t=((null==(k=a.flip)?void 0:k.index)||0)+1,e=E[t];if(e)return{data:{index:t,overflows:O},reset:{placement:e}};let n=null==(C=O.filter((t=>t.overflows[0]<=0)).sort(((t,e)=>t.overflows[1]-e.overflows[1]))[0])?void 0:C.placement;if(!n)switch(p){case"bestFit":{var B;const t=null==(B=O.map((t=>[t.placement,t.overflows.filter((t=>t>0)).reduce(((t,e)=>t+e),0)])).sort(((t,e)=>t[1]-e[1]))[0])?void 0:B[0];t&&(n=t);break}case"initialPlacement":n=c}if(r!==n)return{reset:{placement:n}}}return{}}}};function A(t,e){return{top:t.top-e.height,right:t.right-e.width,bottom:t.bottom-e.height,left:t.left-e.width}}function R(t){return g.some((e=>t[e]>=0))}const P=function(t){return void 0===t&&(t={}),{name:"hide",options:t,async fn(e){const{strategy:n="referenceHidden",...o}=t,{rects:i}=e;switch(n){case"referenceHidden":{const t=A(await s(e,{...o,elementContext:"reference"}),i.reference);return{data:{referenceHiddenOffsets:t,referenceHidden:R(t)}}}case"escaped":{const t=A(await s(e,{...o,altBoundary:!0}),i.floating);return{data:{escapedOffsets:t,escaped:R(t)}}}default:return{}}}}};function T(t){const e=c(...t.map((t=>t.left))),n=c(...t.map((t=>t.top)));return{x:e,y:n,width:f(...t.map((t=>t.right)))-e,height:f(...t.map((t=>t.bottom)))-n}}const E=function(t){return void 0===t&&(t={}),{name:"inline",options:t,async fn(e){const{placement:i,elements:r,rects:s,platform:m,strategy:u}=e,{padding:g=2,x:d,y:p}=t,h=Array.from(await(null==m.getClientRects?void 0:m.getClientRects(r.reference))||[]),y=function(t){const e=t.slice().sort(((t,e)=>t.y-e.y)),n=[];let o=null;for(let t=0;to.height/2?n.push([i]):n[n.length-1].push(i),o=i}return n.map((t=>l(T(t))))}(h),x=l(T(h)),w=a(g),v=await m.getElementRects({reference:{getBoundingClientRect:function(){if(2===y.length&&y[0].left>y[1].right&&null!=d&&null!=p)return y.find((t=>d>t.left-w.left&&dt.top-w.top&&p=2){if("x"===o(i)){const t=y[0],e=y[y.length-1],o="top"===n(i),r=t.top,a=e.bottom,l=o?t.left:e.left,s=o?t.right:e.right;return{top:r,bottom:a,left:l,right:s,width:s-l,height:a-r,x:l,y:r}}const t="left"===n(i),e=f(...y.map((t=>t.right))),r=c(...y.map((t=>t.left))),a=y.filter((n=>t?n.left===r:n.right===e)),l=a[0].top,s=a[a.length-1].bottom;return{top:l,bottom:s,left:r,right:e,width:e-r,height:s-l,x:r,y:l}}return x}},floating:r.floating,strategy:u});return s.reference.x!==v.reference.x||s.reference.y!==v.reference.y||s.reference.width!==v.reference.width||s.reference.height!==v.reference.height?{reset:{rects:v}}:{}}}},D=function(e){return void 0===e&&(e=0),{name:"offset",options:e,async fn(i){const{x:r,y:a}=i,l=await async function(e,i){const{placement:r,platform:a,elements:l}=e,s=await(null==a.isRTL?void 0:a.isRTL(l.floating)),c=n(r),f=t(r),m="x"===o(r),u=["left","top"].includes(c)?-1:1,g=s&&m?-1:1,d="function"==typeof i?i(e):i;let{mainAxis:p,crossAxis:h,alignmentAxis:y}="number"==typeof d?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:0,crossAxis:0,alignmentAxis:null,...d};return f&&"number"==typeof y&&(h="end"===f?-1*y:y),m?{x:h*g,y:p*u}:{x:p*u,y:h*g}}(i,e);return{x:r+l.x,y:a+l.y,data:l}}}};function L(t){return"x"===t?"y":"x"}const O=function(t){return void 0===t&&(t={}),{name:"shift",options:t,async fn(e){const{x:i,y:r,placement:a}=e,{mainAxis:l=!0,crossAxis:c=!1,limiter:f={fn:t=>{let{x:e,y:n}=t;return{x:e,y:n}}},...u}=t,g={x:i,y:r},d=await s(e,u),p=o(n(a)),h=L(p);let y=g[p],x=g[h];if(l){const t="y"===p?"bottom":"right";y=m(y+d["y"===p?"top":"left"],y,y-d[t])}if(c){const t="y"===h?"bottom":"right";x=m(x+d["y"===h?"top":"left"],x,x-d[t])}const w=f.fn({...e,[p]:y,[h]:x});return{...w,data:{x:w.x-i,y:w.y-r}}}}},k=function(t){return void 0===t&&(t={}),{options:t,fn(e){const{x:i,y:r,placement:a,rects:l,middlewareData:s}=e,{offset:c=0,mainAxis:f=!0,crossAxis:m=!0}=t,u={x:i,y:r},g=o(a),d=L(g);let p=u[g],h=u[d];const y="function"==typeof c?c(e):c,x="number"==typeof y?{mainAxis:y,crossAxis:0}:{mainAxis:0,crossAxis:0,...y};if(f){const t="y"===g?"height":"width",e=l.reference[g]-l.floating[t]+x.mainAxis,n=l.reference[g]+l.reference[t]-x.mainAxis;pn&&(p=n)}if(m){var w,v;const t="y"===g?"width":"height",e=["top","left"].includes(n(a)),o=l.reference[d]-l.floating[t]+(e&&(null==(w=s.offset)?void 0:w[d])||0)+(e?0:x.crossAxis),i=l.reference[d]+l.reference[t]+(e?0:(null==(v=s.offset)?void 0:v[d])||0)-(e?x.crossAxis:0);hi&&(h=i)}return{[g]:p,[d]:h}}}},C=function(e){return void 0===e&&(e={}),{name:"size",options:e,async fn(i){const{placement:r,rects:a,platform:l,elements:m}=i,{apply:u=(()=>{}),...g}=e,d=await s(i,g),p=n(r),h=t(r),y="x"===o(r),{width:x,height:w}=a.floating;let v,b;"top"===p||"bottom"===p?(v=p,b=h===(await(null==l.isRTL?void 0:l.isRTL(m.floating))?"start":"end")?"left":"right"):(b=p,v="end"===h?"top":"bottom");const A=w-d[v],R=x-d[b],P=!i.middlewareData.shift;let T=A,E=R;if(y){const t=x-d.left-d.right;E=h||P?c(R,t):t}else{const t=w-d.top-d.bottom;T=h||P?c(A,t):t}if(P&&!h){const t=f(d.left,0),e=f(d.right,0),n=f(d.top,0),o=f(d.bottom,0);y?E=x-2*(0!==t||0!==e?t+e:f(d.left,d.right)):T=w-2*(0!==n||0!==o?n+o:f(d.top,d.bottom))}await u({...i,availableWidth:E,availableHeight:T});const D=await l.getDimensions(m.floating);return x!==D.width||w!==D.height?{reset:{rects:!0}}:{}}}};export{u as arrow,v as autoPlacement,r as computePosition,s as detectOverflow,b as flip,P as hide,E as inline,k as limitShift,D as offset,l as rectToClientRect,O as shift,C as size};export default null;
8 | //# sourceMappingURL=/sm/e9d95297f010b33d5d314b59c8757cb464c79ed6a5a99a53734f5e6b37127795.map
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::{
2 | fs::File,
3 | io::{stdout, Read, Write},
4 | mem::take,
5 | net::SocketAddr,
6 | sync::{
7 | atomic::{AtomicBool, AtomicI64, Ordering},
8 | Arc,
9 | },
10 | thread,
11 | time::Duration,
12 | };
13 |
14 | use ansi_colours::rgb_from_ansi256;
15 | use anyhow::{bail, Result};
16 | use axum::{
17 | body::Body,
18 | extract::{
19 | ws::{Message, WebSocket},
20 | State, WebSocketUpgrade,
21 | },
22 | http::{header, Response, StatusCode, Uri},
23 | response::{Html, IntoResponse},
24 | routing::get,
25 | Router,
26 | };
27 | use clap::{
28 | builder::{StyledStr, Styles},
29 | Parser as ClapParser,
30 | };
31 | use crossterm::{cursor, execute, style::Stylize, terminal};
32 | use portable_pty::{native_pty_system, CommandBuilder, PtySize};
33 | use rust_embed::RustEmbed;
34 | use serde::Serialize;
35 | use termwiz::{
36 | color::ColorSpec,
37 | escape::{
38 | csi::{Edit, EraseInDisplay, EraseInLine, Sgr},
39 | parser::Parser,
40 | Action, ControlCode, Esc, EscCode, OperatingSystemCommand, CSI,
41 | },
42 | };
43 | use tokio::{
44 | net::TcpListener,
45 | sync::{
46 | broadcast,
47 | mpsc::{channel, Receiver, Sender},
48 | Mutex,
49 | },
50 | time::{timeout_at, Instant},
51 | };
52 |
53 | #[derive(clap::Parser, Clone)]
54 | #[command(author, version, about, long_about = None, styles = clap_v3_style(), after_help = after_help())]
55 | struct Cli {
56 | /// The port for the web server
57 | #[arg(short, long, default_value = "3000")]
58 | port: u16,
59 |
60 | #[arg(short, long)]
61 | replay_file: Option,
62 |
63 | /// Log stdout to a file (stdout.txt)
64 | #[arg(short, long, default_value = "false")]
65 | log_to_file: bool,
66 |
67 | /// Command to be launched, optionally with args. If not specified, will use the $SHELL environment variable
68 | #[arg(last = true)]
69 | argv: Vec,
70 | }
71 |
72 | fn main() -> Result<()> {
73 | initialize_environment();
74 | let resize_signaled = Arc::new(AtomicBool::new(false));
75 |
76 | // No SIGWINCH on Windows, but it seems like there's no great alternative: https://github.com/microsoft/terminal/issues/281
77 | #[cfg(not(windows))]
78 | {
79 | use signal_hook::consts::SIGWINCH;
80 | let _ = signal_hook::flag::register(SIGWINCH, resize_signaled.clone());
81 | }
82 |
83 | let cli = Cli::parse();
84 |
85 | if cli.replay_file.is_some() && !cli.argv.is_empty() {
86 | bail!("Cannot specify a replay file and a command to run at the same time")
87 | }
88 |
89 | let (tx, _) = broadcast::channel::(10000); // capacity arbitrarily chosen
90 | let state = AppState {
91 | sequence_count: Arc::new(AtomicI64::new(0)),
92 | all_dtos: Arc::new(Mutex::new(vec![])),
93 | tx,
94 | };
95 |
96 | let runtime = tokio::runtime::Runtime::new()?;
97 |
98 | if let Some(file) = &cli.replay_file {
99 | println!(
100 | "{}{}{}{} 🎨",
101 | "Replaying ".cyan(),
102 | file.clone().magenta(),
103 | " in Escape Artist v".cyan(),
104 | env!("CARGO_PKG_VERSION").cyan(),
105 | );
106 | let (action_sender, action_receiver) = channel::<(Action, Vec)>(10000);
107 |
108 | let reader = File::open(file)?;
109 | // Watch the child's output, pump it into the VTE parser/performer, and forward it to the terminal
110 | // We use a thread here because reading from the pty is blocking
111 | thread::spawn(move || {
112 | parse_raw_output(cli.log_to_file, false, Box::new(reader), action_sender)
113 | });
114 |
115 | let cloned_state = state.clone();
116 | runtime.spawn(process_actions(action_receiver, cloned_state));
117 |
118 | println!(
119 | "{}{}{}",
120 | "Open ".cyan(),
121 | format!("http://localhost:{}", &cli.port).magenta(),
122 | " to view terminal escape codes, type CTRL+D to exit".cyan()
123 | );
124 |
125 | terminal::enable_raw_mode()?;
126 | let _clean_up = CleanUp;
127 |
128 | // start web server and attempt to open it in browser
129 | let cloned_state = state.clone();
130 | runtime.spawn(run_webserver(cloned_state, cli));
131 |
132 | // read stdin, exit on ctrl+d
133 | let mut stdin = std::io::stdin();
134 | let mut buffer = [0; 1024];
135 | loop {
136 | let n = stdin.read(&mut buffer)?;
137 | let bytes = buffer[..n].to_vec();
138 | if bytes.iter().any(|b| *b == 0x4) {
139 | // EOF
140 | break;
141 | }
142 | }
143 |
144 | return Ok(());
145 | }
146 |
147 | let argv = if cli.argv.is_empty() {
148 | if let Ok(shell) = std::env::var("SHELL") {
149 | vec![shell]
150 | } else {
151 | bail!("SHELL environment variable not found; either set it or use --shell")
152 | }
153 | } else {
154 | cli.argv.clone()
155 | };
156 |
157 | println!(
158 | "{}{}{}{} 🎨",
159 | "Launching ".cyan(),
160 | argv.join(" ").magenta(),
161 | " in Escape Artist v".cyan(),
162 | env!("CARGO_PKG_VERSION").cyan(),
163 | );
164 |
165 | let pty_system = native_pty_system();
166 |
167 | let (cols, rows) = terminal::size()?;
168 | let pair = pty_system.openpty(PtySize {
169 | rows,
170 | cols,
171 | pixel_width: 0,
172 | pixel_height: 0,
173 | })?;
174 |
175 | println!(
176 | "{}{}{}",
177 | "Open ".cyan(),
178 | format!("http://localhost:{}", &cli.port).magenta(),
179 | " to view terminal escape codes, type CTRL+D to exit".cyan()
180 | );
181 | println!();
182 | terminal::enable_raw_mode()?;
183 | let _clean_up = CleanUp;
184 |
185 | let mut stdin = std::io::stdin();
186 |
187 | let mut command = CommandBuilder::new(argv[0].clone());
188 | command.args(&argv[1..]);
189 | if let Ok(cwd) = std::env::current_dir() {
190 | command.cwd(cwd);
191 | }
192 |
193 | // Spawn the child process (shell usually), wired up to the PTY
194 | let child = pair.slave.spawn_command(command)?;
195 | // This reads output (stderr and stdout multiplexed into 1 stream) from child
196 | let mut reader = pair.master.try_clone_reader()?;
197 |
198 | if let Some(file) = &cli.replay_file {
199 | reader = Box::new(std::fs::File::open(file)?);
200 | }
201 |
202 | let (action_sender, action_receiver) = channel::<(Action, Vec)>(10000);
203 |
204 | // Watch the child's output, pump it into the VTE parser/performer, and forward it to the terminal
205 | // We use a thread here because reading from the pty is blocking
206 | thread::spawn(move || parse_raw_output(cli.log_to_file, true, reader, action_sender));
207 |
208 | let cloned_state = state.clone();
209 | runtime.spawn(process_actions(action_receiver, cloned_state));
210 |
211 | // start web server and attempt to open it in browser
212 | let cloned_state = state.clone();
213 | let _webserver = runtime.spawn(run_webserver(cloned_state, cli));
214 |
215 | let mut child_stdin = pair.master.take_writer()?;
216 | // forward all input from this process to the child
217 | loop {
218 | if resize_signaled.load(Ordering::Relaxed) {
219 | let (cols, rows) = terminal::size()?;
220 | pair.master
221 | .resize(PtySize {
222 | rows,
223 | cols,
224 | pixel_width: 0,
225 | pixel_height: 0,
226 | })
227 | .unwrap();
228 | resize_signaled.store(false, Ordering::Relaxed);
229 | }
230 |
231 | let mut buffer = [0; 1024];
232 | let n = stdin.read(&mut buffer[..])?;
233 | let bytes = buffer[..n].to_vec();
234 | child_stdin.write_all(&bytes)?;
235 |
236 | if bytes.iter().any(|b| *b == 0x4) {
237 | // EOF
238 | _ = child.clone_killer().kill();
239 | drop(_clean_up);
240 | let sequence_count = state.sequence_count.load(Ordering::Relaxed);
241 | println!(
242 | "\n{}{}",
243 | "Exited. Processed ".cyan(),
244 | format!("{} escape sequences", sequence_count).magenta()
245 | );
246 | // print_all_events(&state.all_events.blocking_lock());
247 | return Ok(());
248 | }
249 | }
250 | }
251 |
252 | async fn run_webserver(cloned_state: AppState, cli: Cli) {
253 | let app = Router::new()
254 | .route("/", get(root))
255 | .route("/events", get(events_websocket))
256 | .route("/*file", get(static_handler))
257 | .with_state(cloned_state);
258 | let url = format!("http://localhost:{}", cli.port);
259 | let _ = open::that(url);
260 | let addr = SocketAddr::from(([127, 0, 0, 1], cli.port));
261 | let listener = TcpListener::bind(addr)
262 | .await
263 | .expect("Failed to bind to socket. Maybe another service is already using the same port");
264 | axum::serve(listener, app)
265 | .await
266 | .expect("Failed to start HTTP server.");
267 | }
268 |
269 | fn parse_raw_output(
270 | log_to_file: bool,
271 | write_to_stdout: bool,
272 | mut reader: Box,
273 | action_sender: Sender<(Action, Vec)>,
274 | ) -> Result<()> {
275 | let mut parser = Parser::new();
276 | let mut recording = if log_to_file {
277 | Some(std::fs::File::create("stdout.txt")?)
278 | } else {
279 | None
280 | };
281 | let mut buf = [0u8; 8192];
282 | let mut curr_cmd_bytes = Vec::new();
283 | loop {
284 | let size = reader.read(&mut buf)?;
285 | let bytes = buf[0..size].to_vec();
286 |
287 | for byte in &bytes {
288 | curr_cmd_bytes.push(*byte);
289 |
290 | let actions = parser.parse_as_vec(&[*byte]);
291 | if !actions.is_empty() {
292 | // 1 byte sequence can represent multiple actions
293 | let cmd_bytes = take(&mut curr_cmd_bytes);
294 | for action in actions {
295 | // this may fail if the receiver has been dropped because we're exiting
296 | let _ = action_sender.blocking_send((action, cmd_bytes.clone()));
297 | }
298 | }
299 | }
300 |
301 | if write_to_stdout {
302 | stdout().write_all(&bytes)?;
303 | stdout().flush()?;
304 | }
305 |
306 | if let Some(recording) = &mut recording {
307 | recording.write_all(&bytes)?;
308 | }
309 | }
310 | }
311 |
312 | async fn process_actions(mut action_receiver: Receiver<(Action, Vec)>, state: AppState) {
313 | let mut fg_color = ColorSpec::Default;
314 | let mut bg_color = ColorSpec::Default;
315 | let mut last_was_line_break = false;
316 | while let Some((action, raw_bytes)) = action_receiver.recv().await {
317 | // optimization: if the last DTO was a print and this action is a print, concatenate them
318 | // this greatly cuts down on the number of events sent to the front-end
319 | if let Some(VteEventDto::Print {
320 | string: last_string,
321 | ..
322 | }) = state.all_dtos.lock().await.last_mut()
323 | {
324 | if let Action::Print(c) = &action {
325 | last_string.push(*c);
326 | let tuple = (action, raw_bytes);
327 | let dto = VteEventDto::from(&tuple);
328 | let _ = state.tx.send(dto);
329 | continue;
330 | }
331 | } else {
332 | state.sequence_count.fetch_add(1, Ordering::Relaxed);
333 | }
334 |
335 | // otherwise, carry on; update global colours if needed and add the event to the list
336 |
337 | update_global_colors(&action, &mut fg_color, &mut bg_color);
338 | let tuple = (action, raw_bytes);
339 | let mut dto = VteEventDto::from(&tuple);
340 | update_print_colors(&mut dto, fg_color, bg_color);
341 |
342 | // emit an invisible line break DTO if we're transitioning from a line break to a non-line break or vice versa
343 | let is_line_break = matches!(&dto, VteEventDto::LineBreak { .. });
344 | let dtos_to_send = if is_line_break && !last_was_line_break {
345 | vec![VteEventDto::InvisibleLineBreak {}, dto]
346 | } else if !is_line_break && last_was_line_break {
347 | vec![VteEventDto::InvisibleLineBreak {}, dto]
348 | } else {
349 | vec![dto]
350 | };
351 | last_was_line_break = is_line_break;
352 |
353 | {
354 | let mut dtos = state.all_dtos.lock().await;
355 | for dto in dtos_to_send.iter() {
356 | dtos.push(dto.clone());
357 | }
358 | }
359 |
360 | for dto in dtos_to_send {
361 | let _ = state.tx.send(dto);
362 | }
363 | }
364 | }
365 |
366 | fn initialize_environment() {
367 | std::env::set_var("RUST_BACKTRACE", "1");
368 | let default_panic = std::panic::take_hook();
369 | std::panic::set_hook(Box::new(move |info| {
370 | terminal::disable_raw_mode().expect("Could not disable raw mode");
371 | execute!(stdout(), cursor::SetCursorStyle::DefaultUserShape).unwrap();
372 | default_panic(info);
373 | }));
374 | }
375 |
376 | #[derive(Clone)]
377 | struct AppState {
378 | sequence_count: Arc,
379 | all_dtos: Arc>>,
380 | tx: broadcast::Sender,
381 | }
382 |
383 | #[axum::debug_handler]
384 | async fn root() -> impl IntoResponse {
385 | Html(include_str!("../embed/index.html"))
386 | }
387 |
388 | #[axum::debug_handler]
389 | async fn static_handler(uri: Uri) -> impl IntoResponse {
390 | let path = uri.path().trim_start_matches('/').to_string();
391 | StaticFile(path)
392 | }
393 |
394 | #[derive(RustEmbed)]
395 | #[folder = "embed/"]
396 | struct Asset;
397 |
398 | #[axum::debug_handler]
399 | async fn events_websocket(
400 | ws: WebSocketUpgrade,
401 | State(state): State,
402 | ) -> impl IntoResponse {
403 | ws.on_upgrade(|ws: WebSocket| async { stream_events(state, ws).await })
404 | }
405 |
406 | fn hex_color(color: &ColorSpec) -> Option {
407 | match color {
408 | ColorSpec::Default => None,
409 | ColorSpec::PaletteIndex(i) => {
410 | let (r, g, b) = rgb_from_ansi256(*i);
411 | Some(format!("#{:02x}{:02x}{:02x}", r, g, b))
412 | }
413 | ColorSpec::TrueColor(srgba) => Some(srgba.to_rgb_string()),
414 | }
415 | }
416 |
417 | // send all the already-logged events over the socket right away, then stream them as they occur
418 | async fn stream_events(app_state: AppState, mut ws: WebSocket) {
419 | let dtos = app_state.all_dtos.lock().await;
420 | for chunk in dtos.chunks(100) {
421 | ws.send(Message::Text(serde_json::to_string(&chunk).unwrap()))
422 | .await
423 | .unwrap();
424 | }
425 | drop(dtos);
426 |
427 | let mut rx = app_state.tx.subscribe();
428 | // throttle event sending so we can cut down on renders
429 | const THROTTLE_DURATION: Duration = Duration::from_millis(100);
430 | let mut batch = vec![];
431 | let mut next_send = Instant::now() + THROTTLE_DURATION;
432 |
433 | loop {
434 | if let Ok(Ok(e)) = timeout_at(next_send, rx.recv()).await {
435 | // TODO rebuild this
436 | // optimization: if this is a string and the last item in the batch is also a string, concatenate them
437 | // this greatly cuts down on the number of events sent to the front-end
438 | if let VteEventDto::Print { string, .. } = &e {
439 | if let Some(VteEventDto::Print {
440 | string: last_string,
441 | ..
442 | }) = batch.last_mut()
443 | {
444 | last_string.push_str(string);
445 | continue;
446 | }
447 | }
448 |
449 | batch.push(e)
450 | }
451 |
452 | if Instant::now() > next_send {
453 | if !batch.is_empty() {
454 | if ws
455 | .send(Message::Text(serde_json::to_string(&batch).unwrap()))
456 | .await
457 | .is_err()
458 | {
459 | // if this failed it's probably because the client disconnected
460 | return;
461 | }
462 | batch.clear();
463 | }
464 | next_send = Instant::now() + THROTTLE_DURATION;
465 | }
466 | }
467 | }
468 |
469 | fn update_print_colors(dto: &mut VteEventDto, fg_color: ColorSpec, bg_color: ColorSpec) {
470 | if let VteEventDto::Print {
471 | color: dto_color,
472 | bg_color: dto_bg_color,
473 | ..
474 | } = dto
475 | {
476 | *dto_color = hex_color(&fg_color);
477 | *dto_bg_color = hex_color(&bg_color);
478 | }
479 | }
480 |
481 | fn update_global_colors(action: &Action, fg_color: &mut ColorSpec, bg_color: &mut ColorSpec) {
482 | if let Action::CSI(CSI::Sgr(sgr)) = action {
483 | match sgr {
484 | Sgr::Foreground(color) => {
485 | *fg_color = *color;
486 | }
487 | Sgr::Background(color) => {
488 | *bg_color = *color;
489 | }
490 | Sgr::Reset => {
491 | *fg_color = ColorSpec::Default;
492 | *bg_color = ColorSpec::Default;
493 | }
494 | _ => {}
495 | }
496 | }
497 | }
498 |
499 | struct CleanUp;
500 |
501 | impl Drop for CleanUp {
502 | fn drop(&mut self) {
503 | terminal::disable_raw_mode().expect("Could not disable raw mode");
504 | execute!(stdout(), cursor::SetCursorStyle::DefaultUserShape).unwrap();
505 | }
506 | }
507 |
508 | #[derive(Debug, Serialize, Clone)]
509 | #[serde(tag = "type")] // give each JSON record a "type" field indicating the enum type, easier to consume from JS
510 | enum VteEventDto {
511 | Print {
512 | string: String,
513 | color: Option,
514 | bg_color: Option,
515 | },
516 | GenericEscape {
517 | title: Option,
518 | icon_svg: Option,
519 | tooltip: Option,
520 | raw_bytes: String,
521 | },
522 | ColorEscape {
523 | title: Option,
524 | icon_svg: Option,
525 | tooltip: Option,
526 | color: String,
527 | raw_bytes: String,
528 | },
529 | InvisibleLineBreak {},
530 | LineBreak {
531 | title: String,
532 | },
533 | }
534 |
535 | impl From<&(Action, Vec)> for VteEventDto {
536 | fn from(value: &(Action, Vec)) -> Self {
537 | let (action, raw_bytes) = value;
538 | match action {
539 | Action::Print(c) => VteEventDto::Print {
540 | string: c.to_string(),
541 | color: None,
542 | bg_color: None,
543 | },
544 | Action::PrintString(s) => VteEventDto::Print {
545 | string: s.clone(),
546 | color: None,
547 | bg_color: None,
548 | },
549 | Action::Control(ctrl) => ctrl_to_dto(ctrl),
550 | Action::DeviceControl(dcm) => VteEventDto::GenericEscape {
551 | title: Some("DCM".into()),
552 | icon_svg: None,
553 | tooltip: Some(format!("{dcm:?}")),
554 | raw_bytes: sanitize_raw_bytes(raw_bytes),
555 | },
556 | Action::OperatingSystemCommand(osc) => osc_to_dto(osc, raw_bytes),
557 | Action::CSI(csi) => csi_to_dto(csi, sanitize_raw_bytes(raw_bytes)),
558 | Action::Esc(e) => esc_to_dto(e, raw_bytes),
559 | Action::Sixel(_) => VteEventDto::GenericEscape {
560 | title: Some("Sixel".into()),
561 | icon_svg: Some(iconify::svg!("mdi:image").into()),
562 | tooltip: Some("Sixel image".into()),
563 | raw_bytes: sanitize_raw_bytes(raw_bytes),
564 | },
565 | Action::XtGetTcap(x) => VteEventDto::GenericEscape {
566 | title: Some("XTGETTCAP".into()),
567 | icon_svg: None,
568 | tooltip: Some(format!("Get termcap, terminfo for: {}", x.join(", "))),
569 | raw_bytes: sanitize_raw_bytes(raw_bytes),
570 | },
571 | Action::KittyImage(_) => VteEventDto::GenericEscape {
572 | title: Some("Kitty".into()),
573 | icon_svg: Some(iconify::svg!("mdi:image").into()),
574 | tooltip: Some("Kitty image".into()),
575 | raw_bytes: sanitize_raw_bytes(raw_bytes),
576 | },
577 | }
578 | }
579 | }
580 |
581 | fn osc_to_dto(osc: &OperatingSystemCommand, raw_bytes: &[u8]) -> VteEventDto {
582 | let raw_bytes_str = sanitize_raw_bytes(raw_bytes);
583 | match osc {
584 | OperatingSystemCommand::SetHyperlink(link) => match link {
585 | Some(link) => VteEventDto::GenericEscape {
586 | title: None,
587 | icon_svg: Some(iconify::svg!("mdi:link").into()),
588 | tooltip: Some(format!("Set hyperlink: {link}")),
589 | raw_bytes: raw_bytes_str,
590 | },
591 | None => VteEventDto::GenericEscape {
592 | title: None,
593 | icon_svg: Some(iconify::svg!("mdi:link-off").into()),
594 | tooltip: Some("Clear hyperlink".into()),
595 | raw_bytes: raw_bytes_str,
596 | },
597 | },
598 | _ => VteEventDto::GenericEscape {
599 | title: Some("OSC".into()),
600 | icon_svg: None,
601 | tooltip: Some(format!("{osc:?}")),
602 | raw_bytes: sanitize_raw_bytes(raw_bytes),
603 | },
604 | }
605 | }
606 |
607 | fn esc_to_dto(esc: &Esc, raw_bytes: &[u8]) -> VteEventDto {
608 | let raw_bytes_str = sanitize_raw_bytes(raw_bytes);
609 | match esc {
610 | Esc::Unspecified { .. } => VteEventDto::GenericEscape {
611 | title: None,
612 | icon_svg: Some(iconify::svg!("mdi:question-mark-box").into()),
613 | tooltip: Some("Unspecified escape sequence".into()),
614 | raw_bytes: raw_bytes_str,
615 | },
616 | Esc::Code(code) => match code {
617 | EscCode::StringTerminator => VteEventDto::GenericEscape {
618 | title: Some("\\".into()),
619 | icon_svg: None,
620 | tooltip: Some("ST / String Terminator".into()),
621 | raw_bytes: raw_bytes_str,
622 | },
623 | EscCode::DecSaveCursorPosition => VteEventDto::GenericEscape {
624 | title: None,
625 | icon_svg: Some(iconify::svg!("mdi:content-save").into()),
626 | tooltip: Some("Save cursor position".into()),
627 | raw_bytes: raw_bytes_str,
628 | },
629 | EscCode::DecRestoreCursorPosition => VteEventDto::GenericEscape {
630 | title: None,
631 | icon_svg: Some(iconify::svg!("mdi:file-restore").into()),
632 | tooltip: Some("Restore cursor position".into()),
633 | raw_bytes: raw_bytes_str,
634 | },
635 | EscCode::AsciiCharacterSetG0 | EscCode::AsciiCharacterSetG1 => {
636 | VteEventDto::GenericEscape {
637 | title: None,
638 | icon_svg: Some(iconify::svg!("mdi:alphabetical-variant").into()),
639 | tooltip: Some(format!("{code:?}")),
640 | raw_bytes: raw_bytes_str,
641 | }
642 | }
643 | _ => VteEventDto::GenericEscape {
644 | title: Some("ESC".into()),
645 | icon_svg: None,
646 | tooltip: Some(format!("{code:?}")),
647 | raw_bytes: raw_bytes_str,
648 | },
649 | },
650 | }
651 | }
652 |
653 | fn ctrl_to_dto(ctrl: &ControlCode) -> VteEventDto {
654 | let as_byte = *ctrl as u8;
655 | let raw_bytes = format!("{:#02x}", as_byte);
656 |
657 | match ctrl {
658 | ControlCode::Bell => VteEventDto::GenericEscape {
659 | title: None,
660 | icon_svg: Some(iconify::svg!("mdi:bell").into()),
661 | tooltip: Some("Bell".into()),
662 | raw_bytes,
663 | },
664 | ControlCode::Backspace => VteEventDto::GenericEscape {
665 | title: None,
666 | icon_svg: Some(iconify::svg!("mdi:backspace").into()),
667 | tooltip: Some("Backspace".into()),
668 | raw_bytes,
669 | },
670 | ControlCode::HorizontalTab => VteEventDto::GenericEscape {
671 | title: None,
672 | icon_svg: Some(iconify::svg!("mdi:keyboard-tab").into()),
673 | tooltip: Some("Tab".into()),
674 | raw_bytes,
675 | },
676 | ControlCode::LineFeed => VteEventDto::LineBreak { title: "LF".into() },
677 | ControlCode::CarriageReturn => VteEventDto::LineBreak { title: "CR".into() },
678 | _ => VteEventDto::GenericEscape {
679 | title: Some(format!("{ctrl:?}")),
680 | icon_svg: None,
681 | tooltip: None,
682 | raw_bytes,
683 | },
684 | }
685 | }
686 |
687 | fn csi_to_dto(csi: &CSI, raw_bytes: String) -> VteEventDto {
688 | let (title, tooltip, icon_svg) = match csi {
689 | CSI::Sgr(sgr) => match sgr {
690 | Sgr::Reset => (
691 | None,
692 | Some("SGR (Select Graphic Rendition) Reset (reset all styles)".into()),
693 | Some(iconify::svg!("carbon:reset").into()),
694 | ),
695 | Sgr::Foreground(color) => {
696 | return VteEventDto::ColorEscape {
697 | title: Some("FG".into()),
698 | icon_svg: None,
699 | tooltip: Some(format!("Set foreground color to: {color:?}")),
700 | color: hex_color(color).unwrap_or("black".into()),
701 | raw_bytes,
702 | }
703 | }
704 | Sgr::Background(color) => {
705 | return VteEventDto::ColorEscape {
706 | title: Some("BG".into()),
707 | icon_svg: None,
708 | tooltip: Some(format!("Set background color to: {color:?}")),
709 | color: hex_color(color).unwrap_or("black".into()),
710 | raw_bytes,
711 | }
712 | }
713 | _ => (Some("SGR".into()), Some(format!("Set {sgr:?}")), None),
714 | },
715 | CSI::Cursor(cursor) => (
716 | None,
717 | Some(format!("Update cursor: {cursor:?}")),
718 | Some(iconify::svg!("ph:cursor-text-fill").into()),
719 | ),
720 | CSI::Edit(edit) => match edit {
721 | Edit::EraseInLine(erase) => (
722 | None,
723 | Some(match erase {
724 | EraseInLine::EraseToEndOfLine => "Erase to end of line".into(),
725 | EraseInLine::EraseToStartOfLine => "Erase to start of line".into(),
726 | EraseInLine::EraseLine => "Erase line".into(),
727 | }),
728 | Some(iconify::svg!("mdi:eraser").into()),
729 | ),
730 | Edit::EraseInDisplay(erase) => (
731 | None,
732 | Some(match erase {
733 | EraseInDisplay::EraseToEndOfDisplay => "Erase to end of display".into(),
734 | EraseInDisplay::EraseToStartOfDisplay => "Erase to start of display".into(),
735 | EraseInDisplay::EraseDisplay => "Erase display".into(),
736 | EraseInDisplay::EraseScrollback => "Erase scrollback".into(),
737 | }),
738 | Some(iconify::svg!("mdi:eraser").into()),
739 | ),
740 | _ => (Some("Edit".into()), Some(format!("{edit:?}")), None),
741 | },
742 | // CSI::Edit(_) => todo!(),
743 | // CSI::Mode(_) => todo!(),
744 | // CSI::Device(_) => todo!(),
745 | // CSI::Mouse(_) => todo!(),
746 | // CSI::Window(_) => todo!(),
747 | // CSI::Keyboard(_) => todo!(),
748 | // CSI::SelectCharacterPath(_, _) => todo!(),
749 | // CSI::Unspecified(_) => todo!(),
750 | _ => (Some("CSI".into()), Some(format!("{csi:?}")), None),
751 | };
752 |
753 | VteEventDto::GenericEscape {
754 | title,
755 | tooltip,
756 | icon_svg,
757 | raw_bytes,
758 | }
759 | }
760 |
761 | /// Convert escape code bytes into a user-facing string,
762 | /// replacing control codes with their \0x hex representations
763 | fn sanitize_raw_bytes(raw_bytes: &[u8]) -> String {
764 | let ret = String::from_utf8_lossy(raw_bytes);
765 | // TODO: there's gotta be a better way to do this than a line for every interesting control char
766 | ret.replace("", r"\x1b")
767 | }
768 |
769 | pub struct StaticFile(pub T);
770 |
771 | impl IntoResponse for StaticFile
772 | where
773 | T: Into,
774 | {
775 | fn into_response(self) -> Response {
776 | let path = self.0.into();
777 |
778 | match Asset::get(path.as_str()) {
779 | Some(content) => {
780 | let body = Body::from(content.data);
781 | let mime = mime_guess::from_path(path).first_or_octet_stream();
782 | Response::builder()
783 | .header(header::CONTENT_TYPE, mime.as_ref())
784 | .body(body)
785 | .unwrap()
786 | }
787 | None => Response::builder()
788 | .status(StatusCode::NOT_FOUND)
789 | .body(Body::from("404"))
790 | .unwrap(),
791 | }
792 | }
793 | }
794 |
795 | // IMO the v3 style was nice and it's dumb that clap removed colour in v4
796 | pub fn clap_v3_style() -> Styles {
797 | use clap::builder::styling::AnsiColor;
798 | Styles::styled()
799 | .header(AnsiColor::Yellow.on_default())
800 | .usage(AnsiColor::Green.on_default())
801 | .literal(AnsiColor::Green.on_default())
802 | .placeholder(AnsiColor::Green.on_default())
803 | }
804 |
805 | fn after_help() -> StyledStr {
806 | format!("{}\n{}\n\n{}",
807 | "More Info:".yellow(),
808 | "This is a tool for seeing ANSI escape codes in terminal applications. You interact with your shell, and it shows the normally-invisible escape codes in a web UI.",
809 | "It's written+maintained by Reilly Wood, and the latest version can be found at https://github.com/rgwood/escape-artist/")
810 | .into()
811 | }
812 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "aho-corasick"
7 | version = "1.1.3"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
10 | dependencies = [
11 | "memchr",
12 | ]
13 |
14 | [[package]]
15 | name = "ansi_colours"
16 | version = "1.2.2"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "6a1558bd2075d341b9ca698ec8eb6fcc55a746b1fc4255585aad5b141d918a80"
19 | dependencies = [
20 | "rgb",
21 | ]
22 |
23 | [[package]]
24 | name = "anstream"
25 | version = "0.6.13"
26 | source = "registry+https://github.com/rust-lang/crates.io-index"
27 | checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
28 | dependencies = [
29 | "anstyle",
30 | "anstyle-parse",
31 | "anstyle-query",
32 | "anstyle-wincon",
33 | "colorchoice",
34 | "utf8parse",
35 | ]
36 |
37 | [[package]]
38 | name = "anstyle"
39 | version = "1.0.6"
40 | source = "registry+https://github.com/rust-lang/crates.io-index"
41 | checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
42 |
43 | [[package]]
44 | name = "anstyle-parse"
45 | version = "0.2.3"
46 | source = "registry+https://github.com/rust-lang/crates.io-index"
47 | checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
48 | dependencies = [
49 | "utf8parse",
50 | ]
51 |
52 | [[package]]
53 | name = "anstyle-query"
54 | version = "1.0.2"
55 | source = "registry+https://github.com/rust-lang/crates.io-index"
56 | checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
57 | dependencies = [
58 | "windows-sys 0.52.0",
59 | ]
60 |
61 | [[package]]
62 | name = "anstyle-wincon"
63 | version = "3.0.2"
64 | source = "registry+https://github.com/rust-lang/crates.io-index"
65 | checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
66 | dependencies = [
67 | "anstyle",
68 | "windows-sys 0.52.0",
69 | ]
70 |
71 | [[package]]
72 | name = "anyhow"
73 | version = "1.0.70"
74 | source = "registry+https://github.com/rust-lang/crates.io-index"
75 | checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
76 |
77 | [[package]]
78 | name = "arrayref"
79 | version = "0.3.7"
80 | source = "registry+https://github.com/rust-lang/crates.io-index"
81 | checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
82 |
83 | [[package]]
84 | name = "arrayvec"
85 | version = "0.7.4"
86 | source = "registry+https://github.com/rust-lang/crates.io-index"
87 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
88 |
89 | [[package]]
90 | name = "async-trait"
91 | version = "0.1.68"
92 | source = "registry+https://github.com/rust-lang/crates.io-index"
93 | checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
94 | dependencies = [
95 | "proc-macro2",
96 | "quote",
97 | "syn 2.0.58",
98 | ]
99 |
100 | [[package]]
101 | name = "atomic"
102 | version = "0.5.3"
103 | source = "registry+https://github.com/rust-lang/crates.io-index"
104 | checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
105 |
106 | [[package]]
107 | name = "autocfg"
108 | version = "1.1.0"
109 | source = "registry+https://github.com/rust-lang/crates.io-index"
110 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
111 |
112 | [[package]]
113 | name = "axum"
114 | version = "0.7.4"
115 | source = "registry+https://github.com/rust-lang/crates.io-index"
116 | checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e"
117 | dependencies = [
118 | "async-trait",
119 | "axum-core",
120 | "axum-macros",
121 | "base64",
122 | "bytes",
123 | "futures-util",
124 | "http",
125 | "http-body",
126 | "http-body-util",
127 | "hyper",
128 | "hyper-util",
129 | "itoa",
130 | "matchit",
131 | "memchr",
132 | "mime",
133 | "percent-encoding",
134 | "pin-project-lite",
135 | "rustversion",
136 | "serde",
137 | "serde_json",
138 | "serde_path_to_error",
139 | "serde_urlencoded",
140 | "sha1",
141 | "sync_wrapper",
142 | "tokio",
143 | "tokio-tungstenite",
144 | "tower",
145 | "tower-layer",
146 | "tower-service",
147 | "tracing",
148 | ]
149 |
150 | [[package]]
151 | name = "axum-core"
152 | version = "0.4.3"
153 | source = "registry+https://github.com/rust-lang/crates.io-index"
154 | checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
155 | dependencies = [
156 | "async-trait",
157 | "bytes",
158 | "futures-util",
159 | "http",
160 | "http-body",
161 | "http-body-util",
162 | "mime",
163 | "pin-project-lite",
164 | "rustversion",
165 | "sync_wrapper",
166 | "tower-layer",
167 | "tower-service",
168 | "tracing",
169 | ]
170 |
171 | [[package]]
172 | name = "axum-macros"
173 | version = "0.4.1"
174 | source = "registry+https://github.com/rust-lang/crates.io-index"
175 | checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
176 | dependencies = [
177 | "heck 0.4.1",
178 | "proc-macro2",
179 | "quote",
180 | "syn 2.0.58",
181 | ]
182 |
183 | [[package]]
184 | name = "base64"
185 | version = "0.21.0"
186 | source = "registry+https://github.com/rust-lang/crates.io-index"
187 | checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
188 |
189 | [[package]]
190 | name = "bit-set"
191 | version = "0.5.3"
192 | source = "registry+https://github.com/rust-lang/crates.io-index"
193 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
194 | dependencies = [
195 | "bit-vec",
196 | ]
197 |
198 | [[package]]
199 | name = "bit-vec"
200 | version = "0.6.3"
201 | source = "registry+https://github.com/rust-lang/crates.io-index"
202 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
203 |
204 | [[package]]
205 | name = "bitflags"
206 | version = "1.3.2"
207 | source = "registry+https://github.com/rust-lang/crates.io-index"
208 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
209 |
210 | [[package]]
211 | name = "bitflags"
212 | version = "2.4.2"
213 | source = "registry+https://github.com/rust-lang/crates.io-index"
214 | checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
215 |
216 | [[package]]
217 | name = "blake3"
218 | version = "1.5.1"
219 | source = "registry+https://github.com/rust-lang/crates.io-index"
220 | checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52"
221 | dependencies = [
222 | "arrayref",
223 | "arrayvec",
224 | "cc",
225 | "cfg-if",
226 | "constant_time_eq",
227 | ]
228 |
229 | [[package]]
230 | name = "block-buffer"
231 | version = "0.10.4"
232 | source = "registry+https://github.com/rust-lang/crates.io-index"
233 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
234 | dependencies = [
235 | "generic-array",
236 | ]
237 |
238 | [[package]]
239 | name = "bytemuck"
240 | version = "1.15.0"
241 | source = "registry+https://github.com/rust-lang/crates.io-index"
242 | checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
243 |
244 | [[package]]
245 | name = "byteorder"
246 | version = "1.4.3"
247 | source = "registry+https://github.com/rust-lang/crates.io-index"
248 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
249 |
250 | [[package]]
251 | name = "bytes"
252 | version = "1.4.0"
253 | source = "registry+https://github.com/rust-lang/crates.io-index"
254 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
255 |
256 | [[package]]
257 | name = "cc"
258 | version = "1.0.90"
259 | source = "registry+https://github.com/rust-lang/crates.io-index"
260 | checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
261 |
262 | [[package]]
263 | name = "cfg-if"
264 | version = "1.0.0"
265 | source = "registry+https://github.com/rust-lang/crates.io-index"
266 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
267 |
268 | [[package]]
269 | name = "clap"
270 | version = "4.5.4"
271 | source = "registry+https://github.com/rust-lang/crates.io-index"
272 | checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
273 | dependencies = [
274 | "clap_builder",
275 | "clap_derive",
276 | ]
277 |
278 | [[package]]
279 | name = "clap_builder"
280 | version = "4.5.2"
281 | source = "registry+https://github.com/rust-lang/crates.io-index"
282 | checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
283 | dependencies = [
284 | "anstream",
285 | "anstyle",
286 | "clap_lex",
287 | "strsim 0.11.1",
288 | ]
289 |
290 | [[package]]
291 | name = "clap_derive"
292 | version = "4.5.4"
293 | source = "registry+https://github.com/rust-lang/crates.io-index"
294 | checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
295 | dependencies = [
296 | "heck 0.5.0",
297 | "proc-macro2",
298 | "quote",
299 | "syn 2.0.58",
300 | ]
301 |
302 | [[package]]
303 | name = "clap_lex"
304 | version = "0.7.0"
305 | source = "registry+https://github.com/rust-lang/crates.io-index"
306 | checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
307 |
308 | [[package]]
309 | name = "colorchoice"
310 | version = "1.0.0"
311 | source = "registry+https://github.com/rust-lang/crates.io-index"
312 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
313 |
314 | [[package]]
315 | name = "constant_time_eq"
316 | version = "0.3.0"
317 | source = "registry+https://github.com/rust-lang/crates.io-index"
318 | checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
319 |
320 | [[package]]
321 | name = "cpufeatures"
322 | version = "0.2.6"
323 | source = "registry+https://github.com/rust-lang/crates.io-index"
324 | checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
325 | dependencies = [
326 | "libc",
327 | ]
328 |
329 | [[package]]
330 | name = "crossterm"
331 | version = "0.27.0"
332 | source = "registry+https://github.com/rust-lang/crates.io-index"
333 | checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
334 | dependencies = [
335 | "bitflags 2.4.2",
336 | "crossterm_winapi",
337 | "libc",
338 | "mio",
339 | "parking_lot",
340 | "signal-hook",
341 | "signal-hook-mio",
342 | "winapi",
343 | ]
344 |
345 | [[package]]
346 | name = "crossterm_winapi"
347 | version = "0.9.1"
348 | source = "registry+https://github.com/rust-lang/crates.io-index"
349 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
350 | dependencies = [
351 | "winapi",
352 | ]
353 |
354 | [[package]]
355 | name = "crypto-common"
356 | version = "0.1.6"
357 | source = "registry+https://github.com/rust-lang/crates.io-index"
358 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
359 | dependencies = [
360 | "generic-array",
361 | "typenum",
362 | ]
363 |
364 | [[package]]
365 | name = "csscolorparser"
366 | version = "0.6.2"
367 | source = "registry+https://github.com/rust-lang/crates.io-index"
368 | checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf"
369 | dependencies = [
370 | "lab",
371 | "phf",
372 | ]
373 |
374 | [[package]]
375 | name = "data-encoding"
376 | version = "2.5.0"
377 | source = "registry+https://github.com/rust-lang/crates.io-index"
378 | checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
379 |
380 | [[package]]
381 | name = "deltae"
382 | version = "0.3.2"
383 | source = "registry+https://github.com/rust-lang/crates.io-index"
384 | checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4"
385 |
386 | [[package]]
387 | name = "digest"
388 | version = "0.10.6"
389 | source = "registry+https://github.com/rust-lang/crates.io-index"
390 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
391 | dependencies = [
392 | "block-buffer",
393 | "crypto-common",
394 | ]
395 |
396 | [[package]]
397 | name = "directories"
398 | version = "5.0.1"
399 | source = "registry+https://github.com/rust-lang/crates.io-index"
400 | checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
401 | dependencies = [
402 | "dirs-sys 0.4.1",
403 | ]
404 |
405 | [[package]]
406 | name = "dirs"
407 | version = "4.0.0"
408 | source = "registry+https://github.com/rust-lang/crates.io-index"
409 | checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
410 | dependencies = [
411 | "dirs-sys 0.3.7",
412 | ]
413 |
414 | [[package]]
415 | name = "dirs-sys"
416 | version = "0.3.7"
417 | source = "registry+https://github.com/rust-lang/crates.io-index"
418 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
419 | dependencies = [
420 | "libc",
421 | "redox_users",
422 | "winapi",
423 | ]
424 |
425 | [[package]]
426 | name = "dirs-sys"
427 | version = "0.4.1"
428 | source = "registry+https://github.com/rust-lang/crates.io-index"
429 | checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
430 | dependencies = [
431 | "libc",
432 | "option-ext",
433 | "redox_users",
434 | "windows-sys 0.48.0",
435 | ]
436 |
437 | [[package]]
438 | name = "downcast-rs"
439 | version = "1.2.0"
440 | source = "registry+https://github.com/rust-lang/crates.io-index"
441 | checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
442 |
443 | [[package]]
444 | name = "equivalent"
445 | version = "1.0.1"
446 | source = "registry+https://github.com/rust-lang/crates.io-index"
447 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
448 |
449 | [[package]]
450 | name = "errno"
451 | version = "0.3.8"
452 | source = "registry+https://github.com/rust-lang/crates.io-index"
453 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
454 | dependencies = [
455 | "libc",
456 | "windows-sys 0.52.0",
457 | ]
458 |
459 | [[package]]
460 | name = "escape-artist"
461 | version = "0.6.7"
462 | dependencies = [
463 | "ansi_colours",
464 | "anyhow",
465 | "axum",
466 | "clap",
467 | "crossterm",
468 | "iconify",
469 | "is-docker",
470 | "mime_guess",
471 | "open",
472 | "portable-pty",
473 | "rand",
474 | "rust-embed",
475 | "serde",
476 | "serde_json",
477 | "signal-hook",
478 | "termwiz",
479 | "tokio",
480 | ]
481 |
482 | [[package]]
483 | name = "euclid"
484 | version = "0.22.9"
485 | source = "registry+https://github.com/rust-lang/crates.io-index"
486 | checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787"
487 | dependencies = [
488 | "num-traits",
489 | ]
490 |
491 | [[package]]
492 | name = "fancy-regex"
493 | version = "0.11.0"
494 | source = "registry+https://github.com/rust-lang/crates.io-index"
495 | checksum = "b95f7c0680e4142284cf8b22c14a476e87d61b004a3a0861872b32ef7ead40a2"
496 | dependencies = [
497 | "bit-set",
498 | "regex",
499 | ]
500 |
501 | [[package]]
502 | name = "fastrand"
503 | version = "2.0.2"
504 | source = "registry+https://github.com/rust-lang/crates.io-index"
505 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
506 |
507 | [[package]]
508 | name = "filedescriptor"
509 | version = "0.8.2"
510 | source = "registry+https://github.com/rust-lang/crates.io-index"
511 | checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
512 | dependencies = [
513 | "libc",
514 | "thiserror",
515 | "winapi",
516 | ]
517 |
518 | [[package]]
519 | name = "finl_unicode"
520 | version = "1.2.0"
521 | source = "registry+https://github.com/rust-lang/crates.io-index"
522 | checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
523 |
524 | [[package]]
525 | name = "fixedbitset"
526 | version = "0.4.2"
527 | source = "registry+https://github.com/rust-lang/crates.io-index"
528 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
529 |
530 | [[package]]
531 | name = "fnv"
532 | version = "1.0.7"
533 | source = "registry+https://github.com/rust-lang/crates.io-index"
534 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
535 |
536 | [[package]]
537 | name = "form_urlencoded"
538 | version = "1.2.1"
539 | source = "registry+https://github.com/rust-lang/crates.io-index"
540 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
541 | dependencies = [
542 | "percent-encoding",
543 | ]
544 |
545 | [[package]]
546 | name = "futures-channel"
547 | version = "0.3.28"
548 | source = "registry+https://github.com/rust-lang/crates.io-index"
549 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
550 | dependencies = [
551 | "futures-core",
552 | ]
553 |
554 | [[package]]
555 | name = "futures-core"
556 | version = "0.3.28"
557 | source = "registry+https://github.com/rust-lang/crates.io-index"
558 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
559 |
560 | [[package]]
561 | name = "futures-sink"
562 | version = "0.3.28"
563 | source = "registry+https://github.com/rust-lang/crates.io-index"
564 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
565 |
566 | [[package]]
567 | name = "futures-task"
568 | version = "0.3.28"
569 | source = "registry+https://github.com/rust-lang/crates.io-index"
570 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
571 |
572 | [[package]]
573 | name = "futures-util"
574 | version = "0.3.28"
575 | source = "registry+https://github.com/rust-lang/crates.io-index"
576 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
577 | dependencies = [
578 | "futures-core",
579 | "futures-sink",
580 | "futures-task",
581 | "pin-project-lite",
582 | "pin-utils",
583 | "slab",
584 | ]
585 |
586 | [[package]]
587 | name = "generic-array"
588 | version = "0.14.7"
589 | source = "registry+https://github.com/rust-lang/crates.io-index"
590 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
591 | dependencies = [
592 | "typenum",
593 | "version_check",
594 | ]
595 |
596 | [[package]]
597 | name = "getrandom"
598 | version = "0.2.12"
599 | source = "registry+https://github.com/rust-lang/crates.io-index"
600 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
601 | dependencies = [
602 | "cfg-if",
603 | "libc",
604 | "wasi",
605 | ]
606 |
607 | [[package]]
608 | name = "h2"
609 | version = "0.4.2"
610 | source = "registry+https://github.com/rust-lang/crates.io-index"
611 | checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943"
612 | dependencies = [
613 | "bytes",
614 | "fnv",
615 | "futures-core",
616 | "futures-sink",
617 | "futures-util",
618 | "http",
619 | "indexmap",
620 | "slab",
621 | "tokio",
622 | "tokio-util",
623 | "tracing",
624 | ]
625 |
626 | [[package]]
627 | name = "hashbrown"
628 | version = "0.14.3"
629 | source = "registry+https://github.com/rust-lang/crates.io-index"
630 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
631 |
632 | [[package]]
633 | name = "heck"
634 | version = "0.4.1"
635 | source = "registry+https://github.com/rust-lang/crates.io-index"
636 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
637 |
638 | [[package]]
639 | name = "heck"
640 | version = "0.5.0"
641 | source = "registry+https://github.com/rust-lang/crates.io-index"
642 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
643 |
644 | [[package]]
645 | name = "hermit-abi"
646 | version = "0.2.6"
647 | source = "registry+https://github.com/rust-lang/crates.io-index"
648 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
649 | dependencies = [
650 | "libc",
651 | ]
652 |
653 | [[package]]
654 | name = "hex"
655 | version = "0.4.3"
656 | source = "registry+https://github.com/rust-lang/crates.io-index"
657 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
658 |
659 | [[package]]
660 | name = "http"
661 | version = "1.0.0"
662 | source = "registry+https://github.com/rust-lang/crates.io-index"
663 | checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea"
664 | dependencies = [
665 | "bytes",
666 | "fnv",
667 | "itoa",
668 | ]
669 |
670 | [[package]]
671 | name = "http-body"
672 | version = "1.0.0"
673 | source = "registry+https://github.com/rust-lang/crates.io-index"
674 | checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
675 | dependencies = [
676 | "bytes",
677 | "http",
678 | ]
679 |
680 | [[package]]
681 | name = "http-body-util"
682 | version = "0.1.0"
683 | source = "registry+https://github.com/rust-lang/crates.io-index"
684 | checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840"
685 | dependencies = [
686 | "bytes",
687 | "futures-util",
688 | "http",
689 | "http-body",
690 | "pin-project-lite",
691 | ]
692 |
693 | [[package]]
694 | name = "httparse"
695 | version = "1.8.0"
696 | source = "registry+https://github.com/rust-lang/crates.io-index"
697 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
698 |
699 | [[package]]
700 | name = "httpdate"
701 | version = "1.0.2"
702 | source = "registry+https://github.com/rust-lang/crates.io-index"
703 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
704 |
705 | [[package]]
706 | name = "hyper"
707 | version = "1.1.0"
708 | source = "registry+https://github.com/rust-lang/crates.io-index"
709 | checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75"
710 | dependencies = [
711 | "bytes",
712 | "futures-channel",
713 | "futures-util",
714 | "h2",
715 | "http",
716 | "http-body",
717 | "httparse",
718 | "httpdate",
719 | "itoa",
720 | "pin-project-lite",
721 | "tokio",
722 | ]
723 |
724 | [[package]]
725 | name = "hyper-util"
726 | version = "0.1.3"
727 | source = "registry+https://github.com/rust-lang/crates.io-index"
728 | checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
729 | dependencies = [
730 | "bytes",
731 | "futures-util",
732 | "http",
733 | "http-body",
734 | "hyper",
735 | "pin-project-lite",
736 | "socket2 0.5.5",
737 | "tokio",
738 | ]
739 |
740 | [[package]]
741 | name = "iconify"
742 | version = "0.3.0"
743 | source = "registry+https://github.com/rust-lang/crates.io-index"
744 | checksum = "ff54b2be3f3c0a20d41a2ea159b63ecb2e5f71585e00a068b19c6edc5183631a"
745 | dependencies = [
746 | "blake3",
747 | "directories",
748 | "hex",
749 | "proc-macro2",
750 | "quote",
751 | "syn 2.0.58",
752 | "ureq",
753 | "url",
754 | ]
755 |
756 | [[package]]
757 | name = "idna"
758 | version = "0.5.0"
759 | source = "registry+https://github.com/rust-lang/crates.io-index"
760 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
761 | dependencies = [
762 | "unicode-bidi",
763 | "unicode-normalization",
764 | ]
765 |
766 | [[package]]
767 | name = "indexmap"
768 | version = "2.2.2"
769 | source = "registry+https://github.com/rust-lang/crates.io-index"
770 | checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
771 | dependencies = [
772 | "equivalent",
773 | "hashbrown",
774 | ]
775 |
776 | [[package]]
777 | name = "ioctl-rs"
778 | version = "0.1.6"
779 | source = "registry+https://github.com/rust-lang/crates.io-index"
780 | checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d"
781 | dependencies = [
782 | "libc",
783 | ]
784 |
785 | [[package]]
786 | name = "is-docker"
787 | version = "0.2.0"
788 | source = "registry+https://github.com/rust-lang/crates.io-index"
789 | checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
790 | dependencies = [
791 | "once_cell",
792 | ]
793 |
794 | [[package]]
795 | name = "is-wsl"
796 | version = "0.4.0"
797 | source = "registry+https://github.com/rust-lang/crates.io-index"
798 | checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
799 | dependencies = [
800 | "is-docker",
801 | "once_cell",
802 | ]
803 |
804 | [[package]]
805 | name = "itoa"
806 | version = "1.0.6"
807 | source = "registry+https://github.com/rust-lang/crates.io-index"
808 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
809 |
810 | [[package]]
811 | name = "lab"
812 | version = "0.11.0"
813 | source = "registry+https://github.com/rust-lang/crates.io-index"
814 | checksum = "bf36173d4167ed999940f804952e6b08197cae5ad5d572eb4db150ce8ad5d58f"
815 |
816 | [[package]]
817 | name = "lazy_static"
818 | version = "1.4.0"
819 | source = "registry+https://github.com/rust-lang/crates.io-index"
820 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
821 |
822 | [[package]]
823 | name = "libc"
824 | version = "0.2.153"
825 | source = "registry+https://github.com/rust-lang/crates.io-index"
826 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
827 |
828 | [[package]]
829 | name = "libredox"
830 | version = "0.0.1"
831 | source = "registry+https://github.com/rust-lang/crates.io-index"
832 | checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
833 | dependencies = [
834 | "bitflags 2.4.2",
835 | "libc",
836 | "redox_syscall 0.4.1",
837 | ]
838 |
839 | [[package]]
840 | name = "linux-raw-sys"
841 | version = "0.4.13"
842 | source = "registry+https://github.com/rust-lang/crates.io-index"
843 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
844 |
845 | [[package]]
846 | name = "lock_api"
847 | version = "0.4.9"
848 | source = "registry+https://github.com/rust-lang/crates.io-index"
849 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
850 | dependencies = [
851 | "autocfg",
852 | "scopeguard",
853 | ]
854 |
855 | [[package]]
856 | name = "log"
857 | version = "0.4.17"
858 | source = "registry+https://github.com/rust-lang/crates.io-index"
859 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
860 | dependencies = [
861 | "cfg-if",
862 | ]
863 |
864 | [[package]]
865 | name = "mac_address"
866 | version = "1.1.5"
867 | source = "registry+https://github.com/rust-lang/crates.io-index"
868 | checksum = "4863ee94f19ed315bf3bc00299338d857d4b5bc856af375cc97d237382ad3856"
869 | dependencies = [
870 | "nix 0.23.2",
871 | "winapi",
872 | ]
873 |
874 | [[package]]
875 | name = "matchit"
876 | version = "0.7.0"
877 | source = "registry+https://github.com/rust-lang/crates.io-index"
878 | checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40"
879 |
880 | [[package]]
881 | name = "memchr"
882 | version = "2.5.0"
883 | source = "registry+https://github.com/rust-lang/crates.io-index"
884 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
885 |
886 | [[package]]
887 | name = "memmem"
888 | version = "0.1.1"
889 | source = "registry+https://github.com/rust-lang/crates.io-index"
890 | checksum = "a64a92489e2744ce060c349162be1c5f33c6969234104dbd99ddb5feb08b8c15"
891 |
892 | [[package]]
893 | name = "memoffset"
894 | version = "0.6.5"
895 | source = "registry+https://github.com/rust-lang/crates.io-index"
896 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
897 | dependencies = [
898 | "autocfg",
899 | ]
900 |
901 | [[package]]
902 | name = "memoffset"
903 | version = "0.7.1"
904 | source = "registry+https://github.com/rust-lang/crates.io-index"
905 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
906 | dependencies = [
907 | "autocfg",
908 | ]
909 |
910 | [[package]]
911 | name = "mime"
912 | version = "0.3.17"
913 | source = "registry+https://github.com/rust-lang/crates.io-index"
914 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
915 |
916 | [[package]]
917 | name = "mime_guess"
918 | version = "2.0.4"
919 | source = "registry+https://github.com/rust-lang/crates.io-index"
920 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
921 | dependencies = [
922 | "mime",
923 | "unicase",
924 | ]
925 |
926 | [[package]]
927 | name = "minimal-lexical"
928 | version = "0.2.1"
929 | source = "registry+https://github.com/rust-lang/crates.io-index"
930 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
931 |
932 | [[package]]
933 | name = "mio"
934 | version = "0.8.6"
935 | source = "registry+https://github.com/rust-lang/crates.io-index"
936 | checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
937 | dependencies = [
938 | "libc",
939 | "log",
940 | "wasi",
941 | "windows-sys 0.45.0",
942 | ]
943 |
944 | [[package]]
945 | name = "nix"
946 | version = "0.23.2"
947 | source = "registry+https://github.com/rust-lang/crates.io-index"
948 | checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
949 | dependencies = [
950 | "bitflags 1.3.2",
951 | "cc",
952 | "cfg-if",
953 | "libc",
954 | "memoffset 0.6.5",
955 | ]
956 |
957 | [[package]]
958 | name = "nix"
959 | version = "0.25.1"
960 | source = "registry+https://github.com/rust-lang/crates.io-index"
961 | checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
962 | dependencies = [
963 | "autocfg",
964 | "bitflags 1.3.2",
965 | "cfg-if",
966 | "libc",
967 | "memoffset 0.6.5",
968 | "pin-utils",
969 | ]
970 |
971 | [[package]]
972 | name = "nix"
973 | version = "0.26.4"
974 | source = "registry+https://github.com/rust-lang/crates.io-index"
975 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
976 | dependencies = [
977 | "bitflags 1.3.2",
978 | "cfg-if",
979 | "libc",
980 | "memoffset 0.7.1",
981 | "pin-utils",
982 | ]
983 |
984 | [[package]]
985 | name = "nom"
986 | version = "7.1.3"
987 | source = "registry+https://github.com/rust-lang/crates.io-index"
988 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
989 | dependencies = [
990 | "memchr",
991 | "minimal-lexical",
992 | ]
993 |
994 | [[package]]
995 | name = "num-derive"
996 | version = "0.3.3"
997 | source = "registry+https://github.com/rust-lang/crates.io-index"
998 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
999 | dependencies = [
1000 | "proc-macro2",
1001 | "quote",
1002 | "syn 1.0.109",
1003 | ]
1004 |
1005 | [[package]]
1006 | name = "num-traits"
1007 | version = "0.2.18"
1008 | source = "registry+https://github.com/rust-lang/crates.io-index"
1009 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
1010 | dependencies = [
1011 | "autocfg",
1012 | ]
1013 |
1014 | [[package]]
1015 | name = "num_cpus"
1016 | version = "1.15.0"
1017 | source = "registry+https://github.com/rust-lang/crates.io-index"
1018 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
1019 | dependencies = [
1020 | "hermit-abi",
1021 | "libc",
1022 | ]
1023 |
1024 | [[package]]
1025 | name = "once_cell"
1026 | version = "1.17.1"
1027 | source = "registry+https://github.com/rust-lang/crates.io-index"
1028 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
1029 |
1030 | [[package]]
1031 | name = "open"
1032 | version = "5.0.1"
1033 | source = "registry+https://github.com/rust-lang/crates.io-index"
1034 | checksum = "90878fb664448b54c4e592455ad02831e23a3f7e157374a8b95654731aac7349"
1035 | dependencies = [
1036 | "is-wsl",
1037 | "libc",
1038 | "pathdiff",
1039 | ]
1040 |
1041 | [[package]]
1042 | name = "option-ext"
1043 | version = "0.2.0"
1044 | source = "registry+https://github.com/rust-lang/crates.io-index"
1045 | checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
1046 |
1047 | [[package]]
1048 | name = "ordered-float"
1049 | version = "4.2.0"
1050 | source = "registry+https://github.com/rust-lang/crates.io-index"
1051 | checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e"
1052 | dependencies = [
1053 | "num-traits",
1054 | ]
1055 |
1056 | [[package]]
1057 | name = "parking_lot"
1058 | version = "0.12.1"
1059 | source = "registry+https://github.com/rust-lang/crates.io-index"
1060 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
1061 | dependencies = [
1062 | "lock_api",
1063 | "parking_lot_core",
1064 | ]
1065 |
1066 | [[package]]
1067 | name = "parking_lot_core"
1068 | version = "0.9.7"
1069 | source = "registry+https://github.com/rust-lang/crates.io-index"
1070 | checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
1071 | dependencies = [
1072 | "cfg-if",
1073 | "libc",
1074 | "redox_syscall 0.2.16",
1075 | "smallvec",
1076 | "windows-sys 0.45.0",
1077 | ]
1078 |
1079 | [[package]]
1080 | name = "pathdiff"
1081 | version = "0.2.1"
1082 | source = "registry+https://github.com/rust-lang/crates.io-index"
1083 | checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
1084 |
1085 | [[package]]
1086 | name = "percent-encoding"
1087 | version = "2.3.1"
1088 | source = "registry+https://github.com/rust-lang/crates.io-index"
1089 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
1090 |
1091 | [[package]]
1092 | name = "pest"
1093 | version = "2.7.8"
1094 | source = "registry+https://github.com/rust-lang/crates.io-index"
1095 | checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8"
1096 | dependencies = [
1097 | "memchr",
1098 | "thiserror",
1099 | "ucd-trie",
1100 | ]
1101 |
1102 | [[package]]
1103 | name = "pest_derive"
1104 | version = "2.7.8"
1105 | source = "registry+https://github.com/rust-lang/crates.io-index"
1106 | checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026"
1107 | dependencies = [
1108 | "pest",
1109 | "pest_generator",
1110 | ]
1111 |
1112 | [[package]]
1113 | name = "pest_generator"
1114 | version = "2.7.8"
1115 | source = "registry+https://github.com/rust-lang/crates.io-index"
1116 | checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80"
1117 | dependencies = [
1118 | "pest",
1119 | "pest_meta",
1120 | "proc-macro2",
1121 | "quote",
1122 | "syn 2.0.58",
1123 | ]
1124 |
1125 | [[package]]
1126 | name = "pest_meta"
1127 | version = "2.7.8"
1128 | source = "registry+https://github.com/rust-lang/crates.io-index"
1129 | checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293"
1130 | dependencies = [
1131 | "once_cell",
1132 | "pest",
1133 | "sha2",
1134 | ]
1135 |
1136 | [[package]]
1137 | name = "phf"
1138 | version = "0.11.2"
1139 | source = "registry+https://github.com/rust-lang/crates.io-index"
1140 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
1141 | dependencies = [
1142 | "phf_macros",
1143 | "phf_shared",
1144 | ]
1145 |
1146 | [[package]]
1147 | name = "phf_codegen"
1148 | version = "0.11.2"
1149 | source = "registry+https://github.com/rust-lang/crates.io-index"
1150 | checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
1151 | dependencies = [
1152 | "phf_generator",
1153 | "phf_shared",
1154 | ]
1155 |
1156 | [[package]]
1157 | name = "phf_generator"
1158 | version = "0.11.2"
1159 | source = "registry+https://github.com/rust-lang/crates.io-index"
1160 | checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
1161 | dependencies = [
1162 | "phf_shared",
1163 | "rand",
1164 | ]
1165 |
1166 | [[package]]
1167 | name = "phf_macros"
1168 | version = "0.11.2"
1169 | source = "registry+https://github.com/rust-lang/crates.io-index"
1170 | checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
1171 | dependencies = [
1172 | "phf_generator",
1173 | "phf_shared",
1174 | "proc-macro2",
1175 | "quote",
1176 | "syn 2.0.58",
1177 | ]
1178 |
1179 | [[package]]
1180 | name = "phf_shared"
1181 | version = "0.11.2"
1182 | source = "registry+https://github.com/rust-lang/crates.io-index"
1183 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
1184 | dependencies = [
1185 | "siphasher",
1186 | ]
1187 |
1188 | [[package]]
1189 | name = "pin-project"
1190 | version = "1.0.12"
1191 | source = "registry+https://github.com/rust-lang/crates.io-index"
1192 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
1193 | dependencies = [
1194 | "pin-project-internal",
1195 | ]
1196 |
1197 | [[package]]
1198 | name = "pin-project-internal"
1199 | version = "1.0.12"
1200 | source = "registry+https://github.com/rust-lang/crates.io-index"
1201 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
1202 | dependencies = [
1203 | "proc-macro2",
1204 | "quote",
1205 | "syn 1.0.109",
1206 | ]
1207 |
1208 | [[package]]
1209 | name = "pin-project-lite"
1210 | version = "0.2.9"
1211 | source = "registry+https://github.com/rust-lang/crates.io-index"
1212 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
1213 |
1214 | [[package]]
1215 | name = "pin-utils"
1216 | version = "0.1.0"
1217 | source = "registry+https://github.com/rust-lang/crates.io-index"
1218 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1219 |
1220 | [[package]]
1221 | name = "portable-pty"
1222 | version = "0.8.1"
1223 | source = "registry+https://github.com/rust-lang/crates.io-index"
1224 | checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be"
1225 | dependencies = [
1226 | "anyhow",
1227 | "bitflags 1.3.2",
1228 | "downcast-rs",
1229 | "filedescriptor",
1230 | "lazy_static",
1231 | "libc",
1232 | "log",
1233 | "nix 0.25.1",
1234 | "serial",
1235 | "shared_library",
1236 | "shell-words",
1237 | "winapi",
1238 | "winreg",
1239 | ]
1240 |
1241 | [[package]]
1242 | name = "ppv-lite86"
1243 | version = "0.2.17"
1244 | source = "registry+https://github.com/rust-lang/crates.io-index"
1245 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
1246 |
1247 | [[package]]
1248 | name = "proc-macro2"
1249 | version = "1.0.79"
1250 | source = "registry+https://github.com/rust-lang/crates.io-index"
1251 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
1252 | dependencies = [
1253 | "unicode-ident",
1254 | ]
1255 |
1256 | [[package]]
1257 | name = "quote"
1258 | version = "1.0.35"
1259 | source = "registry+https://github.com/rust-lang/crates.io-index"
1260 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
1261 | dependencies = [
1262 | "proc-macro2",
1263 | ]
1264 |
1265 | [[package]]
1266 | name = "rand"
1267 | version = "0.8.5"
1268 | source = "registry+https://github.com/rust-lang/crates.io-index"
1269 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
1270 | dependencies = [
1271 | "libc",
1272 | "rand_chacha",
1273 | "rand_core",
1274 | ]
1275 |
1276 | [[package]]
1277 | name = "rand_chacha"
1278 | version = "0.3.1"
1279 | source = "registry+https://github.com/rust-lang/crates.io-index"
1280 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
1281 | dependencies = [
1282 | "ppv-lite86",
1283 | "rand_core",
1284 | ]
1285 |
1286 | [[package]]
1287 | name = "rand_core"
1288 | version = "0.6.4"
1289 | source = "registry+https://github.com/rust-lang/crates.io-index"
1290 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1291 | dependencies = [
1292 | "getrandom",
1293 | ]
1294 |
1295 | [[package]]
1296 | name = "redox_syscall"
1297 | version = "0.2.16"
1298 | source = "registry+https://github.com/rust-lang/crates.io-index"
1299 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
1300 | dependencies = [
1301 | "bitflags 1.3.2",
1302 | ]
1303 |
1304 | [[package]]
1305 | name = "redox_syscall"
1306 | version = "0.4.1"
1307 | source = "registry+https://github.com/rust-lang/crates.io-index"
1308 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
1309 | dependencies = [
1310 | "bitflags 1.3.2",
1311 | ]
1312 |
1313 | [[package]]
1314 | name = "redox_users"
1315 | version = "0.4.4"
1316 | source = "registry+https://github.com/rust-lang/crates.io-index"
1317 | checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
1318 | dependencies = [
1319 | "getrandom",
1320 | "libredox",
1321 | "thiserror",
1322 | ]
1323 |
1324 | [[package]]
1325 | name = "regex"
1326 | version = "1.9.4"
1327 | source = "registry+https://github.com/rust-lang/crates.io-index"
1328 | checksum = "12de2eff854e5fa4b1295edd650e227e9d8fb0c9e90b12e7f36d6a6811791a29"
1329 | dependencies = [
1330 | "aho-corasick",
1331 | "memchr",
1332 | "regex-automata",
1333 | "regex-syntax",
1334 | ]
1335 |
1336 | [[package]]
1337 | name = "regex-automata"
1338 | version = "0.3.7"
1339 | source = "registry+https://github.com/rust-lang/crates.io-index"
1340 | checksum = "49530408a136e16e5b486e883fbb6ba058e8e4e8ae6621a77b048b314336e629"
1341 | dependencies = [
1342 | "aho-corasick",
1343 | "memchr",
1344 | "regex-syntax",
1345 | ]
1346 |
1347 | [[package]]
1348 | name = "regex-syntax"
1349 | version = "0.7.5"
1350 | source = "registry+https://github.com/rust-lang/crates.io-index"
1351 | checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
1352 |
1353 | [[package]]
1354 | name = "rgb"
1355 | version = "0.8.37"
1356 | source = "registry+https://github.com/rust-lang/crates.io-index"
1357 | checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8"
1358 | dependencies = [
1359 | "bytemuck",
1360 | ]
1361 |
1362 | [[package]]
1363 | name = "ring"
1364 | version = "0.17.8"
1365 | source = "registry+https://github.com/rust-lang/crates.io-index"
1366 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
1367 | dependencies = [
1368 | "cc",
1369 | "cfg-if",
1370 | "getrandom",
1371 | "libc",
1372 | "spin",
1373 | "untrusted",
1374 | "windows-sys 0.52.0",
1375 | ]
1376 |
1377 | [[package]]
1378 | name = "rust-embed"
1379 | version = "8.2.0"
1380 | source = "registry+https://github.com/rust-lang/crates.io-index"
1381 | checksum = "a82c0bbc10308ed323529fd3c1dce8badda635aa319a5ff0e6466f33b8101e3f"
1382 | dependencies = [
1383 | "axum",
1384 | "mime_guess",
1385 | "rust-embed-impl",
1386 | "rust-embed-utils",
1387 | "tokio",
1388 | "walkdir",
1389 | ]
1390 |
1391 | [[package]]
1392 | name = "rust-embed-impl"
1393 | version = "8.2.0"
1394 | source = "registry+https://github.com/rust-lang/crates.io-index"
1395 | checksum = "6227c01b1783cdfee1bcf844eb44594cd16ec71c35305bf1c9fb5aade2735e16"
1396 | dependencies = [
1397 | "proc-macro2",
1398 | "quote",
1399 | "rust-embed-utils",
1400 | "syn 2.0.58",
1401 | "walkdir",
1402 | ]
1403 |
1404 | [[package]]
1405 | name = "rust-embed-utils"
1406 | version = "8.2.0"
1407 | source = "registry+https://github.com/rust-lang/crates.io-index"
1408 | checksum = "8cb0a25bfbb2d4b4402179c2cf030387d9990857ce08a32592c6238db9fa8665"
1409 | dependencies = [
1410 | "sha2",
1411 | "walkdir",
1412 | ]
1413 |
1414 | [[package]]
1415 | name = "rustix"
1416 | version = "0.38.32"
1417 | source = "registry+https://github.com/rust-lang/crates.io-index"
1418 | checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
1419 | dependencies = [
1420 | "bitflags 2.4.2",
1421 | "errno",
1422 | "libc",
1423 | "linux-raw-sys",
1424 | "windows-sys 0.52.0",
1425 | ]
1426 |
1427 | [[package]]
1428 | name = "rustls"
1429 | version = "0.22.3"
1430 | source = "registry+https://github.com/rust-lang/crates.io-index"
1431 | checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c"
1432 | dependencies = [
1433 | "log",
1434 | "ring",
1435 | "rustls-pki-types",
1436 | "rustls-webpki",
1437 | "subtle",
1438 | "zeroize",
1439 | ]
1440 |
1441 | [[package]]
1442 | name = "rustls-pki-types"
1443 | version = "1.4.1"
1444 | source = "registry+https://github.com/rust-lang/crates.io-index"
1445 | checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247"
1446 |
1447 | [[package]]
1448 | name = "rustls-webpki"
1449 | version = "0.102.2"
1450 | source = "registry+https://github.com/rust-lang/crates.io-index"
1451 | checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
1452 | dependencies = [
1453 | "ring",
1454 | "rustls-pki-types",
1455 | "untrusted",
1456 | ]
1457 |
1458 | [[package]]
1459 | name = "rustversion"
1460 | version = "1.0.12"
1461 | source = "registry+https://github.com/rust-lang/crates.io-index"
1462 | checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
1463 |
1464 | [[package]]
1465 | name = "ryu"
1466 | version = "1.0.13"
1467 | source = "registry+https://github.com/rust-lang/crates.io-index"
1468 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
1469 |
1470 | [[package]]
1471 | name = "same-file"
1472 | version = "1.0.6"
1473 | source = "registry+https://github.com/rust-lang/crates.io-index"
1474 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1475 | dependencies = [
1476 | "winapi-util",
1477 | ]
1478 |
1479 | [[package]]
1480 | name = "scopeguard"
1481 | version = "1.1.0"
1482 | source = "registry+https://github.com/rust-lang/crates.io-index"
1483 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1484 |
1485 | [[package]]
1486 | name = "semver"
1487 | version = "0.11.0"
1488 | source = "registry+https://github.com/rust-lang/crates.io-index"
1489 | checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
1490 | dependencies = [
1491 | "semver-parser",
1492 | ]
1493 |
1494 | [[package]]
1495 | name = "semver-parser"
1496 | version = "0.10.2"
1497 | source = "registry+https://github.com/rust-lang/crates.io-index"
1498 | checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
1499 | dependencies = [
1500 | "pest",
1501 | ]
1502 |
1503 | [[package]]
1504 | name = "serde"
1505 | version = "1.0.159"
1506 | source = "registry+https://github.com/rust-lang/crates.io-index"
1507 | checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
1508 | dependencies = [
1509 | "serde_derive",
1510 | ]
1511 |
1512 | [[package]]
1513 | name = "serde_derive"
1514 | version = "1.0.159"
1515 | source = "registry+https://github.com/rust-lang/crates.io-index"
1516 | checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
1517 | dependencies = [
1518 | "proc-macro2",
1519 | "quote",
1520 | "syn 2.0.58",
1521 | ]
1522 |
1523 | [[package]]
1524 | name = "serde_json"
1525 | version = "1.0.95"
1526 | source = "registry+https://github.com/rust-lang/crates.io-index"
1527 | checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
1528 | dependencies = [
1529 | "itoa",
1530 | "ryu",
1531 | "serde",
1532 | ]
1533 |
1534 | [[package]]
1535 | name = "serde_path_to_error"
1536 | version = "0.1.11"
1537 | source = "registry+https://github.com/rust-lang/crates.io-index"
1538 | checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0"
1539 | dependencies = [
1540 | "serde",
1541 | ]
1542 |
1543 | [[package]]
1544 | name = "serde_urlencoded"
1545 | version = "0.7.1"
1546 | source = "registry+https://github.com/rust-lang/crates.io-index"
1547 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
1548 | dependencies = [
1549 | "form_urlencoded",
1550 | "itoa",
1551 | "ryu",
1552 | "serde",
1553 | ]
1554 |
1555 | [[package]]
1556 | name = "serial"
1557 | version = "0.4.0"
1558 | source = "registry+https://github.com/rust-lang/crates.io-index"
1559 | checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86"
1560 | dependencies = [
1561 | "serial-core",
1562 | "serial-unix",
1563 | "serial-windows",
1564 | ]
1565 |
1566 | [[package]]
1567 | name = "serial-core"
1568 | version = "0.4.0"
1569 | source = "registry+https://github.com/rust-lang/crates.io-index"
1570 | checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581"
1571 | dependencies = [
1572 | "libc",
1573 | ]
1574 |
1575 | [[package]]
1576 | name = "serial-unix"
1577 | version = "0.4.0"
1578 | source = "registry+https://github.com/rust-lang/crates.io-index"
1579 | checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7"
1580 | dependencies = [
1581 | "ioctl-rs",
1582 | "libc",
1583 | "serial-core",
1584 | "termios 0.2.2",
1585 | ]
1586 |
1587 | [[package]]
1588 | name = "serial-windows"
1589 | version = "0.4.0"
1590 | source = "registry+https://github.com/rust-lang/crates.io-index"
1591 | checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162"
1592 | dependencies = [
1593 | "libc",
1594 | "serial-core",
1595 | ]
1596 |
1597 | [[package]]
1598 | name = "sha1"
1599 | version = "0.10.5"
1600 | source = "registry+https://github.com/rust-lang/crates.io-index"
1601 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
1602 | dependencies = [
1603 | "cfg-if",
1604 | "cpufeatures",
1605 | "digest",
1606 | ]
1607 |
1608 | [[package]]
1609 | name = "sha2"
1610 | version = "0.10.6"
1611 | source = "registry+https://github.com/rust-lang/crates.io-index"
1612 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
1613 | dependencies = [
1614 | "cfg-if",
1615 | "cpufeatures",
1616 | "digest",
1617 | ]
1618 |
1619 | [[package]]
1620 | name = "shared_library"
1621 | version = "0.1.9"
1622 | source = "registry+https://github.com/rust-lang/crates.io-index"
1623 | checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
1624 | dependencies = [
1625 | "lazy_static",
1626 | "libc",
1627 | ]
1628 |
1629 | [[package]]
1630 | name = "shell-words"
1631 | version = "1.1.0"
1632 | source = "registry+https://github.com/rust-lang/crates.io-index"
1633 | checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
1634 |
1635 | [[package]]
1636 | name = "signal-hook"
1637 | version = "0.3.17"
1638 | source = "registry+https://github.com/rust-lang/crates.io-index"
1639 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
1640 | dependencies = [
1641 | "libc",
1642 | "signal-hook-registry",
1643 | ]
1644 |
1645 | [[package]]
1646 | name = "signal-hook-mio"
1647 | version = "0.2.3"
1648 | source = "registry+https://github.com/rust-lang/crates.io-index"
1649 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
1650 | dependencies = [
1651 | "libc",
1652 | "mio",
1653 | "signal-hook",
1654 | ]
1655 |
1656 | [[package]]
1657 | name = "signal-hook-registry"
1658 | version = "1.4.1"
1659 | source = "registry+https://github.com/rust-lang/crates.io-index"
1660 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
1661 | dependencies = [
1662 | "libc",
1663 | ]
1664 |
1665 | [[package]]
1666 | name = "siphasher"
1667 | version = "0.3.11"
1668 | source = "registry+https://github.com/rust-lang/crates.io-index"
1669 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
1670 |
1671 | [[package]]
1672 | name = "slab"
1673 | version = "0.4.8"
1674 | source = "registry+https://github.com/rust-lang/crates.io-index"
1675 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
1676 | dependencies = [
1677 | "autocfg",
1678 | ]
1679 |
1680 | [[package]]
1681 | name = "smallvec"
1682 | version = "1.10.0"
1683 | source = "registry+https://github.com/rust-lang/crates.io-index"
1684 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
1685 |
1686 | [[package]]
1687 | name = "socket2"
1688 | version = "0.4.9"
1689 | source = "registry+https://github.com/rust-lang/crates.io-index"
1690 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
1691 | dependencies = [
1692 | "libc",
1693 | "winapi",
1694 | ]
1695 |
1696 | [[package]]
1697 | name = "socket2"
1698 | version = "0.5.5"
1699 | source = "registry+https://github.com/rust-lang/crates.io-index"
1700 | checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
1701 | dependencies = [
1702 | "libc",
1703 | "windows-sys 0.48.0",
1704 | ]
1705 |
1706 | [[package]]
1707 | name = "spin"
1708 | version = "0.9.8"
1709 | source = "registry+https://github.com/rust-lang/crates.io-index"
1710 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
1711 |
1712 | [[package]]
1713 | name = "strsim"
1714 | version = "0.10.0"
1715 | source = "registry+https://github.com/rust-lang/crates.io-index"
1716 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
1717 |
1718 | [[package]]
1719 | name = "strsim"
1720 | version = "0.11.1"
1721 | source = "registry+https://github.com/rust-lang/crates.io-index"
1722 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
1723 |
1724 | [[package]]
1725 | name = "subtle"
1726 | version = "2.5.0"
1727 | source = "registry+https://github.com/rust-lang/crates.io-index"
1728 | checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
1729 |
1730 | [[package]]
1731 | name = "syn"
1732 | version = "1.0.109"
1733 | source = "registry+https://github.com/rust-lang/crates.io-index"
1734 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
1735 | dependencies = [
1736 | "proc-macro2",
1737 | "quote",
1738 | "unicode-ident",
1739 | ]
1740 |
1741 | [[package]]
1742 | name = "syn"
1743 | version = "2.0.58"
1744 | source = "registry+https://github.com/rust-lang/crates.io-index"
1745 | checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
1746 | dependencies = [
1747 | "proc-macro2",
1748 | "quote",
1749 | "unicode-ident",
1750 | ]
1751 |
1752 | [[package]]
1753 | name = "sync_wrapper"
1754 | version = "0.1.2"
1755 | source = "registry+https://github.com/rust-lang/crates.io-index"
1756 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
1757 |
1758 | [[package]]
1759 | name = "tempfile"
1760 | version = "3.10.1"
1761 | source = "registry+https://github.com/rust-lang/crates.io-index"
1762 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
1763 | dependencies = [
1764 | "cfg-if",
1765 | "fastrand",
1766 | "rustix",
1767 | "windows-sys 0.52.0",
1768 | ]
1769 |
1770 | [[package]]
1771 | name = "terminfo"
1772 | version = "0.8.0"
1773 | source = "registry+https://github.com/rust-lang/crates.io-index"
1774 | checksum = "666cd3a6681775d22b200409aad3b089c5b99fb11ecdd8a204d9d62f8148498f"
1775 | dependencies = [
1776 | "dirs",
1777 | "fnv",
1778 | "nom",
1779 | "phf",
1780 | "phf_codegen",
1781 | ]
1782 |
1783 | [[package]]
1784 | name = "termios"
1785 | version = "0.2.2"
1786 | source = "registry+https://github.com/rust-lang/crates.io-index"
1787 | checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a"
1788 | dependencies = [
1789 | "libc",
1790 | ]
1791 |
1792 | [[package]]
1793 | name = "termios"
1794 | version = "0.3.3"
1795 | source = "registry+https://github.com/rust-lang/crates.io-index"
1796 | checksum = "411c5bf740737c7918b8b1fe232dca4dc9f8e754b8ad5e20966814001ed0ac6b"
1797 | dependencies = [
1798 | "libc",
1799 | ]
1800 |
1801 | [[package]]
1802 | name = "termwiz"
1803 | version = "0.22.0"
1804 | source = "registry+https://github.com/rust-lang/crates.io-index"
1805 | checksum = "5a75313e21da5d4406ea31402035b3b97aa74c04356bdfafa5d1043ab4e551d1"
1806 | dependencies = [
1807 | "anyhow",
1808 | "base64",
1809 | "bitflags 2.4.2",
1810 | "fancy-regex",
1811 | "filedescriptor",
1812 | "finl_unicode",
1813 | "fixedbitset",
1814 | "hex",
1815 | "lazy_static",
1816 | "libc",
1817 | "log",
1818 | "memmem",
1819 | "nix 0.26.4",
1820 | "num-derive",
1821 | "num-traits",
1822 | "ordered-float",
1823 | "pest",
1824 | "pest_derive",
1825 | "phf",
1826 | "semver",
1827 | "sha2",
1828 | "signal-hook",
1829 | "siphasher",
1830 | "tempfile",
1831 | "terminfo",
1832 | "termios 0.3.3",
1833 | "thiserror",
1834 | "ucd-trie",
1835 | "unicode-segmentation",
1836 | "vtparse",
1837 | "wezterm-bidi",
1838 | "wezterm-blob-leases",
1839 | "wezterm-color-types",
1840 | "wezterm-dynamic",
1841 | "wezterm-input-types",
1842 | "winapi",
1843 | ]
1844 |
1845 | [[package]]
1846 | name = "thiserror"
1847 | version = "1.0.40"
1848 | source = "registry+https://github.com/rust-lang/crates.io-index"
1849 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
1850 | dependencies = [
1851 | "thiserror-impl",
1852 | ]
1853 |
1854 | [[package]]
1855 | name = "thiserror-impl"
1856 | version = "1.0.40"
1857 | source = "registry+https://github.com/rust-lang/crates.io-index"
1858 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
1859 | dependencies = [
1860 | "proc-macro2",
1861 | "quote",
1862 | "syn 2.0.58",
1863 | ]
1864 |
1865 | [[package]]
1866 | name = "tinyvec"
1867 | version = "1.6.0"
1868 | source = "registry+https://github.com/rust-lang/crates.io-index"
1869 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
1870 | dependencies = [
1871 | "tinyvec_macros",
1872 | ]
1873 |
1874 | [[package]]
1875 | name = "tinyvec_macros"
1876 | version = "0.1.1"
1877 | source = "registry+https://github.com/rust-lang/crates.io-index"
1878 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1879 |
1880 | [[package]]
1881 | name = "tokio"
1882 | version = "1.27.0"
1883 | source = "registry+https://github.com/rust-lang/crates.io-index"
1884 | checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
1885 | dependencies = [
1886 | "autocfg",
1887 | "bytes",
1888 | "libc",
1889 | "mio",
1890 | "num_cpus",
1891 | "parking_lot",
1892 | "pin-project-lite",
1893 | "signal-hook-registry",
1894 | "socket2 0.4.9",
1895 | "tokio-macros",
1896 | "windows-sys 0.45.0",
1897 | ]
1898 |
1899 | [[package]]
1900 | name = "tokio-macros"
1901 | version = "2.0.0"
1902 | source = "registry+https://github.com/rust-lang/crates.io-index"
1903 | checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
1904 | dependencies = [
1905 | "proc-macro2",
1906 | "quote",
1907 | "syn 2.0.58",
1908 | ]
1909 |
1910 | [[package]]
1911 | name = "tokio-tungstenite"
1912 | version = "0.21.0"
1913 | source = "registry+https://github.com/rust-lang/crates.io-index"
1914 | checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
1915 | dependencies = [
1916 | "futures-util",
1917 | "log",
1918 | "tokio",
1919 | "tungstenite",
1920 | ]
1921 |
1922 | [[package]]
1923 | name = "tokio-util"
1924 | version = "0.7.8"
1925 | source = "registry+https://github.com/rust-lang/crates.io-index"
1926 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
1927 | dependencies = [
1928 | "bytes",
1929 | "futures-core",
1930 | "futures-sink",
1931 | "pin-project-lite",
1932 | "tokio",
1933 | "tracing",
1934 | ]
1935 |
1936 | [[package]]
1937 | name = "tower"
1938 | version = "0.4.13"
1939 | source = "registry+https://github.com/rust-lang/crates.io-index"
1940 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
1941 | dependencies = [
1942 | "futures-core",
1943 | "futures-util",
1944 | "pin-project",
1945 | "pin-project-lite",
1946 | "tokio",
1947 | "tower-layer",
1948 | "tower-service",
1949 | "tracing",
1950 | ]
1951 |
1952 | [[package]]
1953 | name = "tower-layer"
1954 | version = "0.3.2"
1955 | source = "registry+https://github.com/rust-lang/crates.io-index"
1956 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
1957 |
1958 | [[package]]
1959 | name = "tower-service"
1960 | version = "0.3.2"
1961 | source = "registry+https://github.com/rust-lang/crates.io-index"
1962 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
1963 |
1964 | [[package]]
1965 | name = "tracing"
1966 | version = "0.1.37"
1967 | source = "registry+https://github.com/rust-lang/crates.io-index"
1968 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
1969 | dependencies = [
1970 | "cfg-if",
1971 | "log",
1972 | "pin-project-lite",
1973 | "tracing-core",
1974 | ]
1975 |
1976 | [[package]]
1977 | name = "tracing-core"
1978 | version = "0.1.30"
1979 | source = "registry+https://github.com/rust-lang/crates.io-index"
1980 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
1981 | dependencies = [
1982 | "once_cell",
1983 | ]
1984 |
1985 | [[package]]
1986 | name = "tungstenite"
1987 | version = "0.21.0"
1988 | source = "registry+https://github.com/rust-lang/crates.io-index"
1989 | checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
1990 | dependencies = [
1991 | "byteorder",
1992 | "bytes",
1993 | "data-encoding",
1994 | "http",
1995 | "httparse",
1996 | "log",
1997 | "rand",
1998 | "sha1",
1999 | "thiserror",
2000 | "url",
2001 | "utf-8",
2002 | ]
2003 |
2004 | [[package]]
2005 | name = "typenum"
2006 | version = "1.16.0"
2007 | source = "registry+https://github.com/rust-lang/crates.io-index"
2008 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
2009 |
2010 | [[package]]
2011 | name = "ucd-trie"
2012 | version = "0.1.6"
2013 | source = "registry+https://github.com/rust-lang/crates.io-index"
2014 | checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
2015 |
2016 | [[package]]
2017 | name = "unicase"
2018 | version = "2.6.0"
2019 | source = "registry+https://github.com/rust-lang/crates.io-index"
2020 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
2021 | dependencies = [
2022 | "version_check",
2023 | ]
2024 |
2025 | [[package]]
2026 | name = "unicode-bidi"
2027 | version = "0.3.13"
2028 | source = "registry+https://github.com/rust-lang/crates.io-index"
2029 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
2030 |
2031 | [[package]]
2032 | name = "unicode-ident"
2033 | version = "1.0.8"
2034 | source = "registry+https://github.com/rust-lang/crates.io-index"
2035 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
2036 |
2037 | [[package]]
2038 | name = "unicode-normalization"
2039 | version = "0.1.22"
2040 | source = "registry+https://github.com/rust-lang/crates.io-index"
2041 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
2042 | dependencies = [
2043 | "tinyvec",
2044 | ]
2045 |
2046 | [[package]]
2047 | name = "unicode-segmentation"
2048 | version = "1.11.0"
2049 | source = "registry+https://github.com/rust-lang/crates.io-index"
2050 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
2051 |
2052 | [[package]]
2053 | name = "untrusted"
2054 | version = "0.9.0"
2055 | source = "registry+https://github.com/rust-lang/crates.io-index"
2056 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
2057 |
2058 | [[package]]
2059 | name = "ureq"
2060 | version = "2.9.6"
2061 | source = "registry+https://github.com/rust-lang/crates.io-index"
2062 | checksum = "11f214ce18d8b2cbe84ed3aa6486ed3f5b285cf8d8fbdbce9f3f767a724adc35"
2063 | dependencies = [
2064 | "base64",
2065 | "log",
2066 | "once_cell",
2067 | "rustls",
2068 | "rustls-pki-types",
2069 | "rustls-webpki",
2070 | "url",
2071 | "webpki-roots",
2072 | ]
2073 |
2074 | [[package]]
2075 | name = "url"
2076 | version = "2.5.0"
2077 | source = "registry+https://github.com/rust-lang/crates.io-index"
2078 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
2079 | dependencies = [
2080 | "form_urlencoded",
2081 | "idna",
2082 | "percent-encoding",
2083 | ]
2084 |
2085 | [[package]]
2086 | name = "utf-8"
2087 | version = "0.7.6"
2088 | source = "registry+https://github.com/rust-lang/crates.io-index"
2089 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
2090 |
2091 | [[package]]
2092 | name = "utf8parse"
2093 | version = "0.2.1"
2094 | source = "registry+https://github.com/rust-lang/crates.io-index"
2095 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
2096 |
2097 | [[package]]
2098 | name = "uuid"
2099 | version = "1.8.0"
2100 | source = "registry+https://github.com/rust-lang/crates.io-index"
2101 | checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
2102 | dependencies = [
2103 | "atomic",
2104 | "getrandom",
2105 | ]
2106 |
2107 | [[package]]
2108 | name = "version_check"
2109 | version = "0.9.4"
2110 | source = "registry+https://github.com/rust-lang/crates.io-index"
2111 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
2112 |
2113 | [[package]]
2114 | name = "vtparse"
2115 | version = "0.6.2"
2116 | source = "registry+https://github.com/rust-lang/crates.io-index"
2117 | checksum = "6d9b2acfb050df409c972a37d3b8e08cdea3bddb0c09db9d53137e504cfabed0"
2118 | dependencies = [
2119 | "utf8parse",
2120 | ]
2121 |
2122 | [[package]]
2123 | name = "walkdir"
2124 | version = "2.3.3"
2125 | source = "registry+https://github.com/rust-lang/crates.io-index"
2126 | checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
2127 | dependencies = [
2128 | "same-file",
2129 | "winapi-util",
2130 | ]
2131 |
2132 | [[package]]
2133 | name = "wasi"
2134 | version = "0.11.0+wasi-snapshot-preview1"
2135 | source = "registry+https://github.com/rust-lang/crates.io-index"
2136 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
2137 |
2138 | [[package]]
2139 | name = "webpki-roots"
2140 | version = "0.26.1"
2141 | source = "registry+https://github.com/rust-lang/crates.io-index"
2142 | checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
2143 | dependencies = [
2144 | "rustls-pki-types",
2145 | ]
2146 |
2147 | [[package]]
2148 | name = "wezterm-bidi"
2149 | version = "0.2.3"
2150 | source = "registry+https://github.com/rust-lang/crates.io-index"
2151 | checksum = "0c0a6e355560527dd2d1cf7890652f4f09bb3433b6aadade4c9b5ed76de5f3ec"
2152 | dependencies = [
2153 | "log",
2154 | "wezterm-dynamic",
2155 | ]
2156 |
2157 | [[package]]
2158 | name = "wezterm-blob-leases"
2159 | version = "0.1.0"
2160 | source = "registry+https://github.com/rust-lang/crates.io-index"
2161 | checksum = "8e5a5e0adf7eed68976410def849a4bdab6f6e9f6163f152de9cb89deea9e60b"
2162 | dependencies = [
2163 | "getrandom",
2164 | "mac_address",
2165 | "once_cell",
2166 | "sha2",
2167 | "thiserror",
2168 | "uuid",
2169 | ]
2170 |
2171 | [[package]]
2172 | name = "wezterm-color-types"
2173 | version = "0.3.0"
2174 | source = "registry+https://github.com/rust-lang/crates.io-index"
2175 | checksum = "7de81ef35c9010270d63772bebef2f2d6d1f2d20a983d27505ac850b8c4b4296"
2176 | dependencies = [
2177 | "csscolorparser",
2178 | "deltae",
2179 | "lazy_static",
2180 | "wezterm-dynamic",
2181 | ]
2182 |
2183 | [[package]]
2184 | name = "wezterm-dynamic"
2185 | version = "0.2.0"
2186 | source = "registry+https://github.com/rust-lang/crates.io-index"
2187 | checksum = "dfb128bacfa86734e07681fb6068e34c144698e84ee022d6e009145d1abb77b5"
2188 | dependencies = [
2189 | "log",
2190 | "ordered-float",
2191 | "strsim 0.10.0",
2192 | "thiserror",
2193 | "wezterm-dynamic-derive",
2194 | ]
2195 |
2196 | [[package]]
2197 | name = "wezterm-dynamic-derive"
2198 | version = "0.1.0"
2199 | source = "registry+https://github.com/rust-lang/crates.io-index"
2200 | checksum = "0c9f5ef318442d07b3d071f9f43ea40b80992f87faee14bb4d017b6991c307f0"
2201 | dependencies = [
2202 | "proc-macro2",
2203 | "quote",
2204 | "syn 1.0.109",
2205 | ]
2206 |
2207 | [[package]]
2208 | name = "wezterm-input-types"
2209 | version = "0.1.0"
2210 | source = "registry+https://github.com/rust-lang/crates.io-index"
2211 | checksum = "7012add459f951456ec9d6c7e6fc340b1ce15d6fc9629f8c42853412c029e57e"
2212 | dependencies = [
2213 | "bitflags 1.3.2",
2214 | "euclid",
2215 | "lazy_static",
2216 | "wezterm-dynamic",
2217 | ]
2218 |
2219 | [[package]]
2220 | name = "winapi"
2221 | version = "0.3.9"
2222 | source = "registry+https://github.com/rust-lang/crates.io-index"
2223 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
2224 | dependencies = [
2225 | "winapi-i686-pc-windows-gnu",
2226 | "winapi-x86_64-pc-windows-gnu",
2227 | ]
2228 |
2229 | [[package]]
2230 | name = "winapi-i686-pc-windows-gnu"
2231 | version = "0.4.0"
2232 | source = "registry+https://github.com/rust-lang/crates.io-index"
2233 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
2234 |
2235 | [[package]]
2236 | name = "winapi-util"
2237 | version = "0.1.5"
2238 | source = "registry+https://github.com/rust-lang/crates.io-index"
2239 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
2240 | dependencies = [
2241 | "winapi",
2242 | ]
2243 |
2244 | [[package]]
2245 | name = "winapi-x86_64-pc-windows-gnu"
2246 | version = "0.4.0"
2247 | source = "registry+https://github.com/rust-lang/crates.io-index"
2248 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
2249 |
2250 | [[package]]
2251 | name = "windows-sys"
2252 | version = "0.45.0"
2253 | source = "registry+https://github.com/rust-lang/crates.io-index"
2254 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
2255 | dependencies = [
2256 | "windows-targets 0.42.2",
2257 | ]
2258 |
2259 | [[package]]
2260 | name = "windows-sys"
2261 | version = "0.48.0"
2262 | source = "registry+https://github.com/rust-lang/crates.io-index"
2263 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
2264 | dependencies = [
2265 | "windows-targets 0.48.0",
2266 | ]
2267 |
2268 | [[package]]
2269 | name = "windows-sys"
2270 | version = "0.52.0"
2271 | source = "registry+https://github.com/rust-lang/crates.io-index"
2272 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
2273 | dependencies = [
2274 | "windows-targets 0.52.4",
2275 | ]
2276 |
2277 | [[package]]
2278 | name = "windows-targets"
2279 | version = "0.42.2"
2280 | source = "registry+https://github.com/rust-lang/crates.io-index"
2281 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
2282 | dependencies = [
2283 | "windows_aarch64_gnullvm 0.42.2",
2284 | "windows_aarch64_msvc 0.42.2",
2285 | "windows_i686_gnu 0.42.2",
2286 | "windows_i686_msvc 0.42.2",
2287 | "windows_x86_64_gnu 0.42.2",
2288 | "windows_x86_64_gnullvm 0.42.2",
2289 | "windows_x86_64_msvc 0.42.2",
2290 | ]
2291 |
2292 | [[package]]
2293 | name = "windows-targets"
2294 | version = "0.48.0"
2295 | source = "registry+https://github.com/rust-lang/crates.io-index"
2296 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
2297 | dependencies = [
2298 | "windows_aarch64_gnullvm 0.48.0",
2299 | "windows_aarch64_msvc 0.48.0",
2300 | "windows_i686_gnu 0.48.0",
2301 | "windows_i686_msvc 0.48.0",
2302 | "windows_x86_64_gnu 0.48.0",
2303 | "windows_x86_64_gnullvm 0.48.0",
2304 | "windows_x86_64_msvc 0.48.0",
2305 | ]
2306 |
2307 | [[package]]
2308 | name = "windows-targets"
2309 | version = "0.52.4"
2310 | source = "registry+https://github.com/rust-lang/crates.io-index"
2311 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
2312 | dependencies = [
2313 | "windows_aarch64_gnullvm 0.52.4",
2314 | "windows_aarch64_msvc 0.52.4",
2315 | "windows_i686_gnu 0.52.4",
2316 | "windows_i686_msvc 0.52.4",
2317 | "windows_x86_64_gnu 0.52.4",
2318 | "windows_x86_64_gnullvm 0.52.4",
2319 | "windows_x86_64_msvc 0.52.4",
2320 | ]
2321 |
2322 | [[package]]
2323 | name = "windows_aarch64_gnullvm"
2324 | version = "0.42.2"
2325 | source = "registry+https://github.com/rust-lang/crates.io-index"
2326 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
2327 |
2328 | [[package]]
2329 | name = "windows_aarch64_gnullvm"
2330 | version = "0.48.0"
2331 | source = "registry+https://github.com/rust-lang/crates.io-index"
2332 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
2333 |
2334 | [[package]]
2335 | name = "windows_aarch64_gnullvm"
2336 | version = "0.52.4"
2337 | source = "registry+https://github.com/rust-lang/crates.io-index"
2338 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
2339 |
2340 | [[package]]
2341 | name = "windows_aarch64_msvc"
2342 | version = "0.42.2"
2343 | source = "registry+https://github.com/rust-lang/crates.io-index"
2344 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
2345 |
2346 | [[package]]
2347 | name = "windows_aarch64_msvc"
2348 | version = "0.48.0"
2349 | source = "registry+https://github.com/rust-lang/crates.io-index"
2350 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
2351 |
2352 | [[package]]
2353 | name = "windows_aarch64_msvc"
2354 | version = "0.52.4"
2355 | source = "registry+https://github.com/rust-lang/crates.io-index"
2356 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
2357 |
2358 | [[package]]
2359 | name = "windows_i686_gnu"
2360 | version = "0.42.2"
2361 | source = "registry+https://github.com/rust-lang/crates.io-index"
2362 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
2363 |
2364 | [[package]]
2365 | name = "windows_i686_gnu"
2366 | version = "0.48.0"
2367 | source = "registry+https://github.com/rust-lang/crates.io-index"
2368 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
2369 |
2370 | [[package]]
2371 | name = "windows_i686_gnu"
2372 | version = "0.52.4"
2373 | source = "registry+https://github.com/rust-lang/crates.io-index"
2374 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
2375 |
2376 | [[package]]
2377 | name = "windows_i686_msvc"
2378 | version = "0.42.2"
2379 | source = "registry+https://github.com/rust-lang/crates.io-index"
2380 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
2381 |
2382 | [[package]]
2383 | name = "windows_i686_msvc"
2384 | version = "0.48.0"
2385 | source = "registry+https://github.com/rust-lang/crates.io-index"
2386 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
2387 |
2388 | [[package]]
2389 | name = "windows_i686_msvc"
2390 | version = "0.52.4"
2391 | source = "registry+https://github.com/rust-lang/crates.io-index"
2392 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
2393 |
2394 | [[package]]
2395 | name = "windows_x86_64_gnu"
2396 | version = "0.42.2"
2397 | source = "registry+https://github.com/rust-lang/crates.io-index"
2398 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
2399 |
2400 | [[package]]
2401 | name = "windows_x86_64_gnu"
2402 | version = "0.48.0"
2403 | source = "registry+https://github.com/rust-lang/crates.io-index"
2404 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
2405 |
2406 | [[package]]
2407 | name = "windows_x86_64_gnu"
2408 | version = "0.52.4"
2409 | source = "registry+https://github.com/rust-lang/crates.io-index"
2410 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
2411 |
2412 | [[package]]
2413 | name = "windows_x86_64_gnullvm"
2414 | version = "0.42.2"
2415 | source = "registry+https://github.com/rust-lang/crates.io-index"
2416 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
2417 |
2418 | [[package]]
2419 | name = "windows_x86_64_gnullvm"
2420 | version = "0.48.0"
2421 | source = "registry+https://github.com/rust-lang/crates.io-index"
2422 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
2423 |
2424 | [[package]]
2425 | name = "windows_x86_64_gnullvm"
2426 | version = "0.52.4"
2427 | source = "registry+https://github.com/rust-lang/crates.io-index"
2428 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
2429 |
2430 | [[package]]
2431 | name = "windows_x86_64_msvc"
2432 | version = "0.42.2"
2433 | source = "registry+https://github.com/rust-lang/crates.io-index"
2434 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
2435 |
2436 | [[package]]
2437 | name = "windows_x86_64_msvc"
2438 | version = "0.48.0"
2439 | source = "registry+https://github.com/rust-lang/crates.io-index"
2440 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
2441 |
2442 | [[package]]
2443 | name = "windows_x86_64_msvc"
2444 | version = "0.52.4"
2445 | source = "registry+https://github.com/rust-lang/crates.io-index"
2446 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
2447 |
2448 | [[package]]
2449 | name = "winreg"
2450 | version = "0.10.1"
2451 | source = "registry+https://github.com/rust-lang/crates.io-index"
2452 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
2453 | dependencies = [
2454 | "winapi",
2455 | ]
2456 |
2457 | [[package]]
2458 | name = "zeroize"
2459 | version = "1.7.0"
2460 | source = "registry+https://github.com/rust-lang/crates.io-index"
2461 | checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
2462 |
--------------------------------------------------------------------------------