├── dartclj.build_artifacts.txt
├── .clj-kondo
└── config.edn
├── npm-test-app
├── deps.edn
├── .gitignore
├── shadow-cljs.edn
├── README.md
├── src
│ └── converter
│ │ └── core.cljs
├── package.json
├── assets
│ └── index.html
└── package-lock.json
├── images
└── Screenshot 2022-05-28 at 20.11.09.png
├── .npmignore
├── doc
└── intro.md
├── Dockerfile
├── shadow-cljs.edn
├── .github
└── workflows
│ ├── gitlab_sync.yml
│ └── build-binaries.yml
├── src
└── dumch
│ ├── base64.cljs
│ ├── util.cljc
│ ├── convert.cljc
│ ├── dartclojure.cljc
│ ├── improve.cljc
│ └── parse.cljc
├── compile.sh
├── .gitignore
├── CHANGELOG.md
├── package.json
├── project.clj
├── deps.edn
├── test
└── dumch
│ ├── improve_test.cljc
│ ├── integration_test.cljc
│ └── parse_test.cljc
├── pom.xml
├── resources
└── widget-parser.bnf
└── README.md
/dartclj.build_artifacts.txt:
--------------------------------------------------------------------------------
1 | [EXECUTABLE]
2 | dartclojure
3 |
4 |
--------------------------------------------------------------------------------
/.clj-kondo/config.edn:
--------------------------------------------------------------------------------
1 | {:lint-as {instaparse.core/defparser clojure.core/def}}
2 |
--------------------------------------------------------------------------------
/npm-test-app/deps.edn:
--------------------------------------------------------------------------------
1 | {:deps {org.clojure/clojurescript {:mvn/version "1.11.54"}}}
--------------------------------------------------------------------------------
/images/Screenshot 2022-05-28 at 20.11.09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/D00mch/DartClojure/HEAD/images/Screenshot 2022-05-28 at 20.11.09.png
--------------------------------------------------------------------------------
/npm-test-app/.gitignore:
--------------------------------------------------------------------------------
1 | # Lint
2 | .clj-kondo/*
3 | !.clj-kondo/config.edn
4 | .lsp/
5 |
6 | # CLJS
7 | .cljs_node_repl/
8 | cljs-test-runner-out/
9 | .shadow-cljs/
10 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Put everything on the blacklist by default
2 | *
3 | */**
4 | **/.DS_Store
5 | */**/.DS_Store
6 |
7 | # Whitelist
8 | !target/npm-app
9 | !target/npm-lib
10 | !package.json
11 | !README.md
12 | !CHANGELOG.md
13 | !LICENSE
14 |
--------------------------------------------------------------------------------
/doc/intro.md:
--------------------------------------------------------------------------------
1 | # How to use
2 |
3 | Get jar and run it like:
4 |
5 | ```bash
6 | java -jar dartclojure.jar "Text('text')"
7 | ```
8 |
9 | Or load a library in jvm repl and run like:
10 |
11 | ```clojure
12 | (dart->clojure "Text('text')")
13 | ```
14 |
--------------------------------------------------------------------------------
/npm-test-app/shadow-cljs.edn:
--------------------------------------------------------------------------------
1 | {:source-paths ["src"]
2 | :dependencies []
3 | :dev-http {8080 "target/"}
4 | :builds {:app {:output-dir "target/"
5 | :asset-path "."
6 | :target :browser
7 | :modules {:main {:init-fn converter.core/main!}}}}}
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # build uberjar locally
2 | FROM ghcr.io/graalvm/graalvm-ce:ol8-java17 AS native
3 | WORKDIR /usr/src/app
4 | COPY . .
5 | RUN gu install native-image
6 | WORKDIR /usr/src/app
7 | COPY compile.sh .
8 | RUN chmod +x compile.sh
9 | RUN ./compile.sh
10 | CMD ["/usr/src/app/dartclojure", "Text(1)"]
11 |
--------------------------------------------------------------------------------
/npm-test-app/README.md:
--------------------------------------------------------------------------------
1 | # DartCLojure NPM test app
2 |
3 | Testing that we can consume the npm package.
4 |
5 | Install the local npm package:
6 |
7 | ```
8 | npm i ..
9 | ```
10 |
11 | Start the REPL something like so:
12 |
13 | ```sh
14 | npx shadow-cljs -d cider/cider-nrepl:0.27.4 watch :app
15 | ```
16 |
17 | Build the app for release:
18 |
19 | ```sh
20 | npm i dartclojure
21 | npm run release
22 | ```
23 |
--------------------------------------------------------------------------------
/shadow-cljs.edn:
--------------------------------------------------------------------------------
1 | {:deps {:aliases [:test-shadow-cljs]}
2 | :builds
3 | {:lib {:target :node-library
4 | :exports {:convert dumch.convert/convert}
5 | :output-to "target/npm-lib/index.js"}
6 | :app {:target :node-script
7 | :main dumch.dartclojure/node-main
8 | :output-to "target/npm-app/index.js"
9 | :devtools {:after-load dumch.dartclojure/shadow-cljs-reload}}
10 | :test {:target :node-test, :output-to "target/node-test/test.js"
11 | :autorun true}}}
--------------------------------------------------------------------------------
/.github/workflows/gitlab_sync.yml:
--------------------------------------------------------------------------------
1 | name: GitlabSync
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | delete:
8 | branches:
9 | - main
10 |
11 | jobs:
12 | sync:
13 | runs-on: ubuntu-latest
14 | name: Git Repo Sync
15 | steps:
16 | - uses: actions/checkout@v2
17 | with:
18 | fetch-depth: 0
19 | - uses: wangchucheng/git-repo-sync@v0.1.0
20 | with:
21 | target-url: ${{ secrets.TARGET_URL }}
22 | target-username: ${{ secrets.TARGET_USERNAME }}
23 | target-token: ${{ secrets.TARGET_TOKEN }}
24 |
--------------------------------------------------------------------------------
/npm-test-app/src/converter/core.cljs:
--------------------------------------------------------------------------------
1 | (ns converter.core
2 | (:require ["dartclojure" :as dartclojure]))
3 |
4 | (println "Hello")
5 |
6 | (defn ^:export convert []
7 | (try
8 | (let [dart-code (.-value (js/document.getElementById "dart"))
9 | clj-code (dartclojure/convert dart-code)]
10 | (set! (.-innerHTML (js/document.getElementById "clojure")) clj-code))
11 | (catch :default e
12 | (js/alert e))))
13 |
14 | (defn main! []
15 | (println "Hello from main"))
16 |
17 | (defn ^:dev/after-load reload! []
18 | (println "shadow-cljs reloaded"))
--------------------------------------------------------------------------------
/src/dumch/base64.cljs:
--------------------------------------------------------------------------------
1 | (ns dumch.base64)
2 |
3 | ;; NB: These functions use deprecated js/escape and js/unescape functions
4 | ;; https://developer.mozilla.org/en-US/docs/Glossary/Base64
5 |
6 | (defn utf8_to_b64
7 | "Returns `str` encoded to base64. Unicode safe."
8 | [str]
9 | (-> str
10 | js/encodeURIComponent
11 | js/unescape
12 | js/btoa))
13 |
14 | (defn b64_to_utf8
15 | "Returns `b64` decoded from base64. Unicode safe."
16 | [b64]
17 | (-> b64
18 | js/atob
19 | js/escape
20 | js/decodeURIComponent))
21 |
22 | (comment
23 | (utf8_to_b64 "a")
24 | (utf8_to_b64 "✓ à la mode")
25 | (b64_to_utf8 "4pyTIMOgIGxhIG1vZGU=")
26 | )
--------------------------------------------------------------------------------
/npm-test-app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-test-app",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "main.js",
6 | "scripts": {
7 | "watch": "shadow-cljs watch app",
8 | "compile": "shadow-cljs compile app",
9 | "release": "shadow-cljs release app",
10 | "html": "mkdir -p target && cp assets/index.html target/",
11 | "serve": "npm run html && http-server target/",
12 | "del": "rm -r target/*",
13 | "build": "npm run release && npm rum html && npm run serve"
14 | },
15 | "author": "",
16 | "license": "MIT",
17 | "devDependencies": {
18 | "http-server": "^14.1.1",
19 | "shadow-cljs": "^2.19.3"
20 | },
21 | "dependencies": {
22 | "dartclojure": "file:.."
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/compile.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 | mkdir -p META-INF/native-image
3 |
4 | echo '[
5 | {
6 | "name": "java.lang.reflect.AccessibleObject",
7 | "methods" : [{"name":"canAccess"}]
8 | }
9 | ]' | tee META-INF/native-image/logging.json
10 |
11 | # remove -H:+StaticExecutableWithDynamicLibC for m1 builds
12 |
13 | native-image -jar dartclojure.jar --no-fallback \
14 | -J-Dclojure.spec.skip.macros=true -J-Dclojure.compiler.direct-linking=true \
15 | --verbose --no-server -J-Xmx3G \
16 | --report-unsupported-elements-at-runtime --native-image-info \
17 | -H:CCompilerOption=-pipe \
18 | --features=clj_easy.graal_build_time.InitClojureClasses \
19 | -H:ReflectionConfigurationFiles=META-INF/native-image/logging.json
20 |
21 | chmod +x dartclojure
22 | echo "Size of generated native-image `ls -sh dartclojure`"
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .calva/output-window/
2 | .classpath
3 | .cpcache
4 | .DS_Store
5 | .eastwood
6 | .factorypath
7 | .hg/
8 | .hgignore
9 | .java-version
10 | .lein-*
11 | .lsp/.cache
12 | .lsp/sqlite.db
13 | .nrepl-history
14 | .nrepl-port
15 | .portal
16 | .project
17 | .rebel_readline_history
18 | .settings
19 | .socket-repl-port
20 | .sw*
21 | .vscode
22 | *.class
23 | *.jar
24 | *.swp
25 | *~
26 | /checkouts
27 | /classes
28 | /target
29 |
30 | # Native
31 | /META-INF
32 | /reports
33 | dartclojure-*-aarch64-darwin
34 | dartclojure-*-aarch64-linux
35 |
36 | # Lint
37 | .clj-kondo/*
38 | !.clj-kondo/config.edn
39 | .lsp/
40 |
41 | # CLJS
42 | .cljs_node_repl/
43 | cljs-test-runner-out/
44 | .shadow-cljs/
45 |
46 | # Node
47 | node_modules/
48 |
49 | # NPM Example App
50 | npm-test-app/target
51 |
52 | # Idea
53 | DartClojure.iml
54 | .idea/
55 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
3 |
4 | ## [Unreleased]
5 | ### Changed
6 | - Add a new arity to `make-widget-async` to provide a different widget shape.
7 |
8 | ## [0.1.1] - 2022-05-22
9 | ### Changed
10 | - Documentation on how to make the widgets.
11 |
12 | ### Removed
13 | - `make-widget-sync` - we're all async, all the time.
14 |
15 | ### Fixed
16 | - Fixed widget maker to keep working when daylight savings switches over.
17 |
18 | ## 0.1.0 - 2022-05-22
19 | ### Added
20 | - Files from the new template.
21 | - Widget maker public API - `make-widget-sync`.
22 |
23 | [Unreleased]: https://github.com/dumch/dartclojure/compare/0.1.1...HEAD
24 | [0.1.1]: https://github.com/dumch/dartclojure/compare/0.1.0...0.1.1
25 |
--------------------------------------------------------------------------------
/src/dumch/util.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.util
2 | (:require [rewrite-clj.node :as n]
3 | #?(:clj [clojure.java.io :as io]))
4 | #?(:cljs (:require-macros [dumch.util])))
5 |
6 | #?(:clj (set! *warn-on-reflection* true))
7 |
8 | (def ws (n/spaces 1))
9 | (defn spaces [sq] (interpose ws sq))
10 | (defn lists* [& args] (spaces (apply list* args)))
11 | (defn maps [f sq] (spaces (map f sq)))
12 | (defn mapcats [f sq] (spaces (mapcat f sq)))
13 |
14 | (def nl (n/newlines 1))
15 | (defn mapn [f sq] (interpose nl (map f sq)))
16 | (defn mapcatn [f sq] (interpose nl (mapcat f sq)))
17 |
18 | #?(:clj
19 | (defmacro inline-resource [resource-path]
20 | (slurp (clojure.java.io/resource resource-path))))
21 |
22 | (defn upper-case? [s]
23 | #?(:clj (Character/isUpperCase ^Character s)
24 | :cljs (and (= s (.toUpperCase s))
25 | (not= s (.toLowerCase s)))))
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dartclojure",
3 | "description": "Opinionated Dart to Clojure converter for Flutter widgets.",
4 | "version": "0.2.23",
5 | "publisher": "liverm0r",
6 | "author": {
7 | "name": "Artur Dumchev",
8 | "email": "arturdumchev@gmail.com"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/Liverm0r/DartClojure"
13 | },
14 | "license": "Apache License, Version 2.0",
15 | "main": "target/npm-lib/index.js",
16 | "bin": "target/npm-app/index.js",
17 | "scripts": {
18 | "clean": "rimraf target/npm-*",
19 | "watch": "shadow-cljs watch :app :lib :test",
20 | "compile": "shadow-cljs compile :app :lib",
21 | "release": "shadow-cljs release :app :lib",
22 | "prepublish": "npm run clean && npm run release"
23 | },
24 | "devDependencies": {
25 | "rimraf": "3.0.2",
26 | "shadow-cljs": "^2.19.3"
27 | },
28 | "dependencies": {
29 | "dartclojure": "^0.2.23"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/project.clj:
--------------------------------------------------------------------------------
1 | (defproject dartclojure "0.2.23-SNAPSHOT"
2 | :license {:name "EPL-2.0"
3 | :url "https://www.eclipse.org/legal/epl-2.0/"}
4 | :dependencies [[org.clojure/clojure "1.10.3"]
5 | [better-cond/better-cond "2.1.4"]
6 | [com.github.clj-easy/graal-build-time "1.0.5"]
7 | [instaparse/instaparse "1.4.12"]
8 | [org.clojure/tools.cli "1.0.206"]
9 | [rewrite-clj/rewrite-clj "1.1.47"]
10 | [zprint/zprint "1.2.7"]]
11 | :main dumch.dartclojure
12 | :source-paths ["src"]
13 | :resource-paths ["resources"]
14 | :profiles {:dev {:dependencies [[org.clojure/test.check "1.1.1"]
15 | [io.github.cognitect-labs/test-runner "0.5.0"]
16 | [org.clojure/clojurescript "1.11.54"]
17 | [thheller/shadow-cljs "2.19.3"]
18 | [olical/cljs-test-runner "3.8.0"]]
19 | :plugins [[slipset/deps-deploy "0.2.1"]]
20 | :main cognitect.test-runner.api/test}})
21 |
--------------------------------------------------------------------------------
/npm-test-app/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
50 |
51 |
52 |
DartClojure NPM test app
53 |
54 |
Dart code here:
55 |
56 |
57 |
Clojure code:
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/dumch/convert.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.convert
2 | (:require [dumch.improve :as improve]
3 | [dumch.parse :as parse]
4 | [instaparse.core :as insta]
5 | [rewrite-clj.zip :as z]
6 | [zprint.core :as zpr]))
7 |
8 | #?(:clj (set! *warn-on-reflection* true))
9 |
10 | (defn convert
11 | "get dart code, return clojure code
12 | pass keyword arguments, like: (convert code :format :sexpr, :material \"m\")
13 | :material — material alias name, default to \"m\";
14 | :flutter — alias for ClojureDart helper macro, default to \"f\";
15 | :format — or of :string (default), :sexpr, :zipper, :node; last 2 about rewrite-clj"
16 | [code & {m :material f :flutter frm :format :or {m "m", f "f"}}]
17 | (let [ast (parse/dart->ast code)
18 | bad? (insta/failure? ast)]
19 | (if bad?
20 | (str "Can't convert the code: " (:text ast))
21 | (let [rslt (improve/simplify (parse/ast->clj ast) :flutter f :material m)]
22 | (case frm
23 | :zipper rslt
24 | :sexpr (z/sexpr rslt)
25 | :node (z/node rslt)
26 | (-> rslt z/string (zpr/zprint-str {:parse-string? true})))))))
27 |
28 | (comment
29 | (->
30 | "
31 | (context, index) {
32 | if (index == 0) {
33 | return const Padding(
34 | padding: EdgeInsets.only(left: 15, top: 16, bottom: 8),
35 | child: Text(
36 | 'Some $field and ${Factory.create()}:',
37 | style: TextStyle(
38 | fontSize: 16,
39 | fontWeight: FontWeight.w500,
40 | ),
41 | ),
42 | );
43 | }
44 | return const SongPlaceholderTile();
45 | };
46 | "
47 | (convert :format :sexpr)))
48 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:paths ["src" "resources"]
2 | :deps {better-cond/better-cond {:mvn/version "2.1.4"}
3 | com.github.clj-easy/graal-build-time {:mvn/version "1.0.5"}
4 | instaparse/instaparse {:mvn/version "1.4.12"}
5 | org.clojure/clojure {:mvn/version "1.10.3"}
6 | org.clojure/tools.cli {:mvn/version "1.0.206"}
7 | rewrite-clj/rewrite-clj {:mvn/version "1.1.47"}
8 | zprint/zprint {:mvn/version "1.2.7"}}
9 | :aliases
10 | {:build
11 | ;; clj -T:build uber :version '"0.2.22"'
12 | {:extra-deps {io.github.clojure/tools.build
13 | {:git/url "https://github.com/clojure/tools.build"
14 | :git/sha "32d497f4f1ad07cb1dfa0855ada9e9cf17abff48"}}
15 | :ns-default build}
16 | :deploy {:extra-deps {slipset/deps-deploy {:mvn/version "0.2.1"}}
17 | :exec-fn deps-deploy.deps-deploy/deploy
18 | :exec-args {:installer :remote
19 | :artifact "dartclojure.jar"}}
20 | :test {:extra-paths ["test"]
21 | :extra-deps {org.clojure/test.check {:mvn/version "1.1.1"}
22 | io.github.cognitect-labs/test-runner
23 | {:git/tag "v0.5.0" :git/sha "48c3c67"}}
24 | :main-opts ["-m" "cognitect.test-runner"]
25 | :exec-fn cognitect.test-runner.api/test}
26 | :test-shadow-cljs {:extra-paths ["test"]}
27 | :cljs {:extra-deps {org.clojure/clojurescript {:mvn/version "1.11.54"}}}
28 | :shadow-cljs
29 | {:extra-deps {thheller/shadow-cljs {:mvn/version "2.19.3"}}
30 | :main-opts ["-m" "shadow.cljs.devtools.cli" "-d" "cider/cider-nrepl:0.28.3"]}
31 | :test-cljs
32 | {:extra-deps
33 | {olical/cljs-test-runner {:mvn/version "3.8.0"}}
34 | :extra-paths ["test"]
35 | :main-opts ["-m" "cljs-test-runner.main"]}}}
36 |
--------------------------------------------------------------------------------
/test/dumch/improve_test.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.improve-test
2 | (:require [clojure.test :refer [deftest is testing]]
3 | [dumch.improve :refer [simplify wrap-nest]]
4 | [dumch.parse :refer [dart->clojure]]
5 | [rewrite-clj.zip :as z]
6 | [rewrite-clj.parser :as p]))
7 |
8 | (def ^:private simplify-clj-str (comp z/sexpr simplify p/parse-string))
9 |
10 | (deftest nesting-test
11 | (testing "3 nested .child should be replaced with f/nest macro"
12 | (is
13 | (= '(f/widget (Container) (Box) (Padding) (Text "2"))
14 | (->
15 | "(Container
16 | .child
17 | (Box .child (Padding .child (Text \"2\"))))"
18 | z/of-string
19 | wrap-nest
20 | z/sexpr))))
21 |
22 | (testing "2- nested .child should be unchanged"
23 | (is
24 | (= '(Box .child (Padding .child (Text "2")))
25 | (-> "(Box .child (Padding .child (Text \"2\")))"
26 | z/of-string
27 | wrap-nest
28 | z/sexpr)))))
29 |
30 | (deftest redundant-do
31 | (testing "fn with do body"
32 | (is (= '(fn [a] a b)
33 | (simplify-clj-str "(fn [a] (do a b))"))))
34 | (testing "defn with do body"
35 | (is (= '(defn main [a] a b)
36 | (simplify-clj-str "(defn main [a] (do a b))")))))
37 |
38 | (deftest print-test
39 | (is (= '(fn [a b] (when a a) (dart:core/print 1) (when c c) b)
40 | (simplify-clj-str
41 | "(fn [a b] (do (when a a) (print 1) (when c c) b))"))))
42 |
43 | (deftest material-alias-test
44 | (testing "No alias on core"
45 | (is (= '(Duration .milliseconds 250)
46 | (simplify-clj-str "(Duration .milliseconds 250)"))))
47 | (testing "material alias with slash"
48 | (is (= '(m/MyDuration .milliseconds 250)
49 | (simplify-clj-str "(MyDuration .milliseconds 250)"))))
50 | (testing "material alias with dot"
51 | (is (= '(m.My/Duration .milliseconds 250)
52 | (simplify-clj-str "(My.Duration .milliseconds 250)")))))
53 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | org.clojars.liverm0r
5 | dartclojure
6 | 0.2.23-SNAPSHOT
7 | dumch/dartclojure
8 | Opinionated Dart->Clojure translater
9 | https://github.com/Liverm0r/dartclojure
10 |
11 |
12 | Apache License, Version 2.0
13 | https://www.apache.org/licenses/LICENSE-2.0
14 |
15 |
16 |
17 |
18 | M1
19 |
20 |
21 |
22 | https://github.com/Liverm0r/dartclojure
23 | scm:git:git://github.com/Liverm0r/dartclojure.git
24 | scm:git:ssh://git@github.com/Liverm0r/dartclojure.git
25 | v0.2.23-SNAPSHOT
26 |
27 |
28 |
29 | org.clojure
30 | clojure
31 | 1.10.3
32 |
33 |
34 | better-cond
35 | better-cond
36 | 2.1.4
37 |
38 |
39 | com.github.clj-easy
40 | graal-build-time
41 | 0.1.4
42 |
43 |
44 | org.clojure
45 | tools.cli
46 | 1.0.206
47 |
48 |
49 | rewrite-clj
50 | rewrite-clj
51 | 1.1.47
52 |
53 |
54 | instaparse
55 | instaparse
56 | 1.4.12
57 |
58 |
59 | zprint
60 | zprint
61 | 1.2.7
62 |
63 |
64 |
65 | src
66 |
67 |
68 |
69 | clojars
70 | https://repo.clojars.org/
71 |
72 |
73 |
74 |
75 | clojars
76 | Clojars repository
77 | https://clojars.org/repo
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/.github/workflows/build-binaries.yml:
--------------------------------------------------------------------------------
1 | name: GraalVM Native Image builds
2 | on:
3 | push:
4 | tags:
5 | - '*'
6 |
7 | jobs:
8 | create-release:
9 | name: Create release
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Create Release
13 | id: create_release
14 | uses: actions/create-release@v1
15 | env:
16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17 | with:
18 | tag_name: ${{ github.ref }}
19 | release_name: ${{ github.ref }}
20 | draft: false
21 | prerelease: false
22 |
23 | build-and-upload:
24 | needs: create-release
25 | name: Build and upload binaries with ${{ matrix.os }}
26 | runs-on: ${{ matrix.os.host }}
27 | strategy:
28 | matrix:
29 | os:
30 | - name: macos-latest
31 | architecture: x86-64
32 | host: macos-latest
33 |
34 | - name: macos-latest
35 | architecture: arm64
36 | host: macos-latest
37 |
38 | - name: openbsd
39 | architecture: arm64
40 | host: ubuntu-latest
41 |
42 | - name: netbsd
43 | architecture: x86-64
44 | host: ubuntu-latest
45 |
46 | steps:
47 | - name: Check for tag
48 | run: |
49 | if [[ "${{ github.ref }}" == refs/tags/* ]]; then
50 | echo "This is a tagged push."
51 | else
52 | echo "This is not a tagged push."
53 | exit 1
54 | fi
55 |
56 | - name: Check OS name
57 | run: |
58 | echo "os name is: ${{ matrix.os.architecture }} ${{ matrix.os.host }} "
59 |
60 | - id: get_version
61 | uses: battila7/get-version-action@v2
62 |
63 | - uses: actions/checkout@v4
64 |
65 | - uses: graalvm/setup-graalvm@v1
66 | with:
67 | java-version: '21'
68 | distribution: 'graalvm'
69 | github-token: ${{ secrets.GITHUB_TOKEN }}
70 | native-image-job-reports: 'true'
71 |
72 | - name: Prepare java
73 | uses: actions/setup-java@v3
74 | with:
75 | distribution: 'temurin'
76 | java-version: '17'
77 |
78 | - name: Install clojure tools
79 | uses: DeLaGuardo/setup-clojure@12.1
80 | with:
81 | cli: 1.11.1.1413
82 | # lein: 2.10.0
83 |
84 | - name: Build jar and native
85 | run: |
86 | clojure -T:build uber :version '"${{ steps.get_version.outputs.version-without-v }}"'
87 | cp target/dartclojure*.jar dartclojure.jar
88 | chmod +x compile.sh
89 | ./compile.sh
90 | mv dartclojure "dartclojure-${{ matrix.os.host }}-${{ matrix.os.architecture }}"
91 |
92 | - name: Attach binaries to release
93 | env:
94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
95 | run: |
96 | set -x
97 | ls -l
98 | assets=()
99 | assets+=("-a" dartclojure*latest*)
100 | githubref=${{ steps.get_version.outputs.version-without-v }}
101 | hub release edit "${assets[@]}" -m $githubref $githubref
102 |
--------------------------------------------------------------------------------
/test/dumch/integration_test.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.integration-test
2 | (:require #?(:cljs [clojure.edn :refer [read-string]])
3 | [clojure.test :refer [deftest is testing]]
4 | [dumch.convert :refer [convert]]
5 | [dumch.improve :refer [simplify]]
6 | [dumch.parse :refer [dart->clojure widget-parser]]
7 | [instaparse.core :as insta]))
8 |
9 | (def ^:private code "
10 | AnimatedContainer(
11 | transformAlignment: Alignment.center,
12 | transform: Matrix4.diagonal3Values(
13 | _isOpened ? 0.7 : 1.0,
14 | _isOpened ? 0.7 : 1.0,
15 | 1.0,
16 | ),
17 | duration: const Duration(milliseconds: 250),
18 | curve: const Interval(0.0, 0.5, curve: Curves.easeOut),
19 | child: AnimatedRotation(
20 | turns: _isOpened ? -0.1 : 0,
21 | curve: const Interval(0.25, 1.0, curve: Curves.easeInOut),
22 | duration: const Duration(milliseconds: 250),
23 | child: FloatingActionButton(
24 | onPressed: () => widget.closeHint.value = !widget.closeHint.value,
25 | backgroundColor: _isOpened ? Colors.white : theme.primaryColor,
26 | child: Icon(Icons.add, color: _isOpened ? theme.primaryColor : Colors.white),
27 | )
28 | )
29 | );
30 | ")
31 |
32 | (deftest complex-example-test
33 | (testing "no ambiguity"
34 | (is (= 1 (count (insta/parses widget-parser code)))))
35 | (testing "dart->clojure, using widget macro"
36 | (is
37 | (=
38 | (read-string (convert code))
39 | '(f/widget
40 | (m/AnimatedContainer
41 | .transformAlignment (.-center m/Alignment)
42 | .transform (.diagonal3Values
43 | m/Matrix4
44 | (if _isOpened 0.7 1.0)
45 | (if _isOpened 0.7 1.0)
46 | 1.0)
47 | .duration (Duration .milliseconds 250)
48 | .curve (m/Interval 0.0 0.5 .curve (.-easeOut m/Curves)))
49 | (m/AnimatedRotation
50 | .turns (if _isOpened -0.1 0)
51 | .curve (m/Interval 0.25 1.0 .curve (.-easeInOut m/Curves))
52 | .duration (Duration .milliseconds 250))
53 | (m/FloatingActionButton
54 | .onPressed
55 | (fn [] :unidiomatic)
56 | .backgroundColor
57 | (if _isOpened (.-white m/Colors) (.-primaryColor theme)))
58 | (m/Icon
59 | (.-add m/Icons)
60 | .color (if _isOpened (.-primaryColor theme) (.-white m/Colors))))))))
61 |
62 | (def code2 "
63 | Column(
64 | children: [
65 | Question(
66 | questions[_questionIndex]['questionText'],
67 | ),
68 | (questions[_questionIndex]['answers'] as List)
69 | .map((answer) {
70 | return Answer(_answerQuestion, answer);
71 | }).toList(),
72 | Numb(sorted: (1 < 2 && 2 < 3 && 3 < a) && (a == b)),
73 | ],
74 | ),
75 | ")
76 |
77 | (deftest complex-example-test2
78 | (testing "no ambiguity"
79 | (is (= 1 (count (insta/parses widget-parser code2)))))
80 | (testing "Complex example with list, lambda, map, compare, named arg"
81 | (is
82 | (=
83 | (-> code2 convert read-string)
84 | '(m/Column
85 | .children
86 | [(m/Question (get (get questions _questionIndex) "questionText"))
87 | (->
88 | (get (get questions _questionIndex) "answers")
89 | (.map (fn [answer] (m/Answer _answerQuestion answer)))
90 | .toList)
91 | (m/Numb .sorted (and (= a b) (< 1 2 3 a)))])))))
92 |
--------------------------------------------------------------------------------
/src/dumch/dartclojure.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.dartclojure
2 | (:require #?(:cljs ["readline" :as node-rl])
3 | #?(:cljs [clojure.edn :refer [read-string]])
4 | #?(:cljs ["fs" :as node-fs])
5 | [clojure.pprint :refer [pprint]]
6 | [clojure.tools.cli :refer [parse-opts]]
7 | [clojure.string :as str]
8 | [dumch.convert :refer [convert]]
9 | [zprint.core :as zpr])
10 | #?(:clj (:gen-class)))
11 |
12 | #?(:clj (set! *warn-on-reflection* true))
13 |
14 | (def cli-options
15 | [["-r" "--repl REPL" "Mode: repl or single command, single by default"
16 | :default false
17 | :parse-fn #?(:clj #(Boolean/parseBoolean %)
18 | :cljs read-string)
19 | :validate [boolean? "Must be either true or false"]]
20 | ["-e" "--end TEXT" "Mode: text or symbol to show the end of code"
21 | :default ""
22 | :parse-fn str]
23 | ["-m" "--material MATERIAL" "material require alias, any string"
24 | :default "m"
25 | :parse-fn str
26 | :validate [#(re-matches #"^[A-Za-z][A-Za-z0-9]*$" %)
27 | "invalid require-alias for material"]]
28 | ["-f" "--flutter FLUTTER_MACRO_PACKAGE" "flutter-macro require alias, any string"
29 | :default "f"
30 | :parse-fn str
31 | :validate [#(re-matches #"^[A-Za-z][A-Za-z0-9]*$" %)
32 | "invalid require alias for flutter-materail"]]
33 | ["-c" "--colors BOOLEAN" "colorize output"
34 | :default false
35 | :parse-fn #?(:clj #(Boolean/parseBoolean %)
36 | :cljs read-string)
37 | :validate [boolean? "Must be either true or false"]]
38 | ["-p" "--path PATH TO FILE, OR URL" "url or path to dart file to translate"
39 | :parse-fn str]
40 | ["-h" "--help"]])
41 |
42 | (defn show! [data & {:keys [colors] :or {colors false}}]
43 | (if colors
44 | (zpr/czprint data {:parse-string? true})
45 | (println data)))
46 |
47 | (defn- print-repl-instructions [end]
48 | (println (str "Paste dart code below, press enter"
49 | (when (seq end) (str ", write '" end "',"))
50 | " and see the result:\n")))
51 |
52 | #?(:clj
53 | (defn- stdin-loop! [& {:keys [material flutter end colors]}]
54 | (print-repl-instructions end)
55 | (loop [input (read-line)
56 | acc []]
57 | (if (= input end)
58 | (do
59 | (try
60 | (-> (convert (str/join "\n" acc)
61 | :material material
62 | :flutter flutter)
63 | (show! :colors colors))
64 | (catch Exception e (println "Can't convert the code; e " e)))
65 | (println)
66 | (recur (read-line) []))
67 | (recur (read-line) (conj acc input))))))
68 |
69 | #?(:cljs
70 | ;; This could have been a lambda, but then we can't update it via the REPL
71 | (defn- process-node-repl-input! [input !code {:keys [material flutter end colors]}]
72 | (if (= input end)
73 | (do
74 | (try
75 | (-> (convert (str/join "\n" @!code)
76 | :material material
77 | :flutter flutter)
78 | (show! :colors colors))
79 | (catch js/Error e (println "Can't convert the code; e " e)))
80 | (println)
81 | (reset! !code []))
82 | (swap! !code conj input))))
83 |
84 | #?(:cljs
85 | (defn- node-repl! [& {:keys [end] :as params}]
86 | (print-repl-instructions end)
87 | (let [!code (atom [])]
88 | (-> (.createInterface node-rl #js {:input js/process.stdin
89 | :output js/process.stdout
90 | :terminal false})
91 | (.on "line" (fn [input]
92 | (process-node-repl-input! input !code params)))))))
93 |
94 | (defn -main [& args]
95 | (let [{{:keys [repl help path] :as params} :options,
96 | errors :errors,
97 | args :arguments :as m}
98 | (parse-opts args cli-options)
99 | params (mapcat identity params)]
100 | (cond
101 | help (println "here is the arguments\n" m)
102 | errors (println errors)
103 | repl #?(:clj (apply stdin-loop! params)
104 | :cljs (apply node-repl! params))
105 | path (when-let [code (#?(:clj slurp
106 | :cljs #(node-fs/readFileSync % #js {:encoding "utf-8" :flag "r"})) path)]
107 | (apply show!
108 | (apply convert code params)
109 | params))
110 | :else (if args
111 | (apply show!
112 | (apply convert (first args) params)
113 | params)
114 | (println "no arguments passed")))))
115 |
116 | #?(:cljs
117 | (def node-main #'-main))
118 |
119 | #?(:cljs
120 | (defn shadow-cljs-reload []
121 | (println "shadow-cljs reloaded the code")))
122 |
--------------------------------------------------------------------------------
/src/dumch/improve.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.improve
2 | (:require
3 | [better-cond.core :as b]
4 | [clojure.string :as str]
5 | [dumch.util :refer [lists* upper-case?]]
6 | [rewrite-clj.node :as n]
7 | [rewrite-clj.paredit :as p]
8 | [rewrite-clj.zip :as z]))
9 |
10 | (defn- remove-child-named-arg [zloc]
11 | (-> zloc z/down (z/find-value z/right '.child) z/right z/remove z/remove* z/up))
12 |
13 | (defn- nested-children? [zloc times]
14 | (let [zloc (-> zloc z/down (z/find-value z/right '.child))]
15 | (cond
16 | (not= '.child (z/sexpr zloc)) false
17 | (= 1 times) true
18 | :else (recur (-> zloc z/next) (dec times)))))
19 |
20 | (defn- nest-flatten [zloc & {fl :flutter :or {fl "f"}}]
21 | (loop [zloc zloc
22 | rslt []]
23 | (if-let [child (-> zloc z/down (z/find-value z/right '.child))]
24 | (recur (-> child z/right) (conj rslt (remove-child-named-arg zloc)))
25 | (z/of-node
26 | (n/list-node (lists* (n/token-node (symbol (str (when fl (str fl "/")) "widget")))
27 | (map z/node (conj rslt zloc))))))))
28 |
29 | (defn wrap-nest [zloc & {fl :flutter :or {fl "f"}}]
30 | (z/prewalk zloc
31 | #(and (z/list? %) (nested-children? % 3))
32 | #(nest-flatten % :flutter fl)))
33 |
34 | (b/defnc- try-remove-redundant-do [zloc]
35 | :when-let [fn-node (-> zloc z/down)]
36 | :let [fn? (= (z/sexpr fn-node) 'fn)
37 | defn? (= (z/sexpr fn-node) 'defn)]
38 |
39 | :when-let [_ (or fn? defn?)
40 | fn-node (if defn? (z/right fn-node) fn-node)
41 | do-zloc (-> fn-node z/right z/right z/down)]
42 |
43 | (= (z/sexpr do-zloc) 'do)
44 | (-> do-zloc z/remove z/splice z/up))
45 |
46 | (def ^:private core-vars
47 | #{'AbstractClassInstantiationError 'ArgumentError 'AssertionError 'BidirectionalIterator
48 | 'BigIntbool 'CastError 'Comparable 'Comparator 'ConcurrentModificationError
49 | 'CyclicInitializationError 'DateTime 'double 'Duration 'Error 'Exception 'Expando
50 | 'FallThroughError 'Finalizer 'FormatException 'Function 'IndexError 'IntegerDivisionByZeroException
51 | 'Invocation 'Iterable 'Iterator 'List 'Map 'MapEntry 'Match 'NoSuchMethodError 'Null 'NullThrownError
52 | 'Object 'OutOfMemoryError 'Pattern 'pragma 'RangeError 'RegExp 'RegExpMatch 'Runes 'RuneIterator 'Set
53 | 'Sink 'StackOverflowError 'StackTrace 'StateError 'Stopwatch 'String 'StringBuffer 'StringSink
54 | 'Symbol 'Type 'TypeError 'UnimplementedError 'UnsupportedError 'Uri 'WeakReference})
55 |
56 | (b/defnc- insert-alias [symb m]
57 | :let [s (str symb)]
58 | (not (str/includes? s ".")) (symbol (str m "/" symb))
59 |
60 | :let [parts (cons m (str/split s #"\."))]
61 | (symbol (str (str/join "." (butlast parts)) "/" (last parts))))
62 |
63 | (defn simplify [node & {fl :flutter, m :material :or {fl "f", m "m"}}]
64 | (-> node
65 | z/of-node
66 | (z/postwalk
67 | (fn [zloc]
68 | (b/cond
69 | (and (z/list? zloc) (nested-children? zloc 3))
70 | (nest-flatten zloc :flutter fl)
71 |
72 | :let [undo-node (try-remove-redundant-do zloc)]
73 | undo-node undo-node
74 |
75 | :let [expr (z/sexpr zloc)]
76 | (= expr 'print) (z/edit zloc #(symbol (str "dart:core/" %)))
77 |
78 | ;; require alias
79 | (and (symbol? expr)
80 | (upper-case? (first (str expr)))
81 | (not (core-vars expr)))
82 | (z/edit zloc #(insert-alias % m))
83 |
84 | :else zloc)))))
85 |
86 | #_(-> "(Duration 39)"
87 | rewrite-clj.parser/parse-string
88 | simplify
89 | z/sexpr)
90 |
91 | (comment
92 | (def nested "(Container
93 | .child
94 | (Box .child (Padding .child (Text 1)) .a 1))")
95 |
96 | (-> nested z/of-string (nested-children? 3))
97 |
98 | (-> nested z/of-string
99 | z/down
100 | (z/find-value '.child)
101 | z/right
102 | p/raise
103 | z/up
104 | z/string
105 | )
106 |
107 | (def animation "(Column
108 | .children
109 | [(Text \"name\")
110 | (Icon m.Icons/widgets)
111 | (IgnorePointer.
112 | .ignoring (boolean @open)
113 | .child
114 | (AnimatedContainer.
115 | .transformAlignment m.Alignment/center
116 | .transform (m.Matrix4/diagonal3Values
117 | (if @open 0.7 1.0)
118 | (if @open 0.7 1.0)
119 | 1.0)
120 | .duration ^:const (Duration. .milliseconds 250)
121 | .curve ^:const (Interval. 0.0 0.5 .curve m.Curves/easeOut)
122 | .child
123 | (AnimatedOpacity.
124 | .opacity (if @open 0.0 (+ (+ 2.0 1.0) (+ -3.0) 1.0))
125 | .curve ^:const (Interval. 0.25 1.0 .curve m.Curves/easeInOut)
126 | .duration ^:const (Duration. .milliseconds 250)
127 | .child
128 | (FloatingActionButton.
129 | .onPressed toggle
130 | .child
131 | (Icon. m.Icons/create)))))])
132 | ")
133 |
134 | (z/sexpr (wrap-nest (z/of-string animation))))
135 |
--------------------------------------------------------------------------------
/resources/widget-parser.bnf:
--------------------------------------------------------------------------------
1 | s = file / code
2 | code = (expr )*
3 |
4 | metadata = ('@' qualified params? <';'>?)+
5 | file = import-block?
6 | (
7 | (method | var-declare <';'> | class | _typedef | for-in |
8 | _for | _while | _do-while | switch | try | enum | return))*
9 | = <'static'?> ? identifier lambda-args
10 | = (block | <'=>'> assign-val) <';'*>
11 | method = method-decl method-body
12 |
13 | import-block = (import <';'?>)+
14 | = (import-full | import-as | import-hide | import-show | import-naked)
15 | import-naked = im-body
16 | import-full = im-body im-as-part (im-show-part | im-hide-part)
17 | import-as = im-body im-as-part
18 | import-show = im-body im-show-part
19 | import-hide = im-body im-hide-part
20 | = <'import'> string
21 | = (<'deferred'?> <'as'> identifier)
22 | = <'show'> identifier+
23 | = <'hide'> identifier+
24 |
25 | class = <'abstract'? 'class' #'[^{}]*' '{'>
26 | ( (method | method-decl <';'> | getter-decl |
27 | var-declare <';'> | ))*
28 | <'}'>
29 | construct-decl = 'const'? identifier ('.' identifier)?
30 | '(' (
31 | (typed-arg '.')* typed-arg?
32 | (<','> (typed-arg '.')* typed-arg)*
33 | )?
34 | <','>? args-bloc?
35 | ')'
36 | ( (':' 'super' params)? ';' | ':' (identifier '=' expr (','|';'))* )
37 | args-bloc = '{' #'[^{}]*' '}'
38 | _typedef = 'typedef' dtype <'='> (dtype | method)
39 | getter-decl = 'get'
40 | identifier (block | <'=>'> assign-val | <';'>) <';'*>
41 |
42 | enum = <'enum'> identifier
43 | <'{'> enum-entry (<','> enum-entry)* <','>? <'}'>
44 | enum-entry = identifier
45 |
46 | = <(';'|#'\n'+|','|#'$')>
47 | = var-declare | _for | for-in | _while | _do-while | switch | try
48 | return = <'return'> expr? <';'>
49 |
50 | if = <'if'> if-condition if-else-body
51 | = (block | return | expr )
52 | ( (<'else'> | <'else if'> if-condition) if-else-body)*
53 | = <'('> expr <')'>
54 |
55 | var-declare = <'static'>? field-type var-init (<','> var-init)*
56 | var-init = identifier (<'='> expr)?
57 |
58 | for-in = <'for'> <'('> identifier <'in'> expr <')'> for-body
59 | _for = <'for'> <'('> for-init expr? <';'> expr-list? <')'> for-body
60 | for-init = var-declare <';'> EPSILON | expr? <';'>
61 | = (block | return | expr | statement)
62 | _while = <'while'> <'('> expr <')'> for-body
63 | _do-while = <'do'> for-body 'while' <'('> expr <')'> <';'>
64 |
65 | switch = <'switch'> <'('> expr <')'> <'{'> switch-case* default-case? <'}'>
66 | switch-case = (identifier <':'>)* cases for-body switch-exit?
67 | cases = (<'case'> expr <':'>)+
68 | default-case = (identifier <':'>)* <'default'> <':'> for-body switch-exit?
69 | switch-exit = ('break' | 'continue' | 'continue' identifier) <';'>
70 |
71 | try = <'try'> block (try-on+ finally? | finally)
72 | try-on = on-part catch block
73 | on-part = <'on'> dtype | EPSILON
74 | catch = <'catch'> <'('> identifier (<','> identifier)? <')'> | EPSILON
75 | finally = <'finally'> block
76 |
77 | lambda-args = <'('> typed-arg? (<','> typed-arg)* <')'> <'async'?>
78 | = identifier
79 | block = <'{'> ( statement <';'> | expr | method )* return? <'}'>
80 |
81 | expr-list = expr (',' expr)*
82 | = lambda-val <'!'>?
83 |
84 | = await-val | lambda
85 | lambda = lambda-args block | lambda-args <'=>'> await-val
86 | = cascade-val | await
87 | await = <'await'> await-val
88 | = assign-val | cascade
89 | cascade = cascade-val <'..'> assign-val
90 | = ternary-val | _set
91 | _set = dot-val <_operator> ternary-val
92 | = ifnull-val | ternary
93 | ternary = ternary-val <'?'> expr <':'> expr
94 | = and-val | ifnull
95 | ifnull = ifnull-val '??' and-val
96 | = or-val | and
97 | and = and-val <'&&'> or-val
98 | = equality-val | or
99 | or = or-val <'||'> equality-val
100 | = compare-val | equality
101 | equality = equality-val ( '==' | '!=' ) compare-val
102 | = add-sub-val | compare
103 | compare = compare-val !type-args ( '<' | '>' | '<=' | '>=' | 'is') add-sub-val
104 | = mul-div-val | add | sub
105 | add = add-sub-val <'+'> mul-div-val
106 | sub = add-sub-val <'-'> mul-div-val
107 | = dot-val | mul | div
108 | mul = mul-div-val <'*'> dot-val
109 | div = mul-div-val ('/' | '%' | '~/') dot-val
110 | = term | dot | dot-op
111 | dot-op = dot-val <'?'> (invoke | field)
112 | dot = dot-val (invoke | field)
113 | = value | <'('> ternary-val <')'>
114 |
115 | = (number | string | !get identifier
116 | | constructor | invoke | typecasting | const
117 | | list | map | get | _spread | if
118 | | inc | _inc | dec | _dec | identifier | number
119 | | _tilda | neg | not) <';'?>
120 |
121 | typecasting = value 'as' dtype
122 |
123 | invoke = <'.'> typed-value params <';'?>
124 | field = <'.'> identifier <';'?>
125 | neg = !number <'-'> value
126 | not = <'!'> value
127 | dec = <'--'> value
128 | inc = <'++'> value
129 | _dec = value <'--'>
130 | _inc = value <'++'>
131 | _tilda = <'~'> value
132 |
133 | const = <'const'> (constructor | get | map | list | dot | dot-op)
134 | constructor = typed-value params <';'?>
135 | = identifier
136 | params = <'('> <')'>
137 | | (<'('> argument (<','> argument)* <','?> <')'>)
138 | argument = expr | (named-arg expr)
139 | named-arg = identifier <':'>
140 |
141 | list =
142 | <'['> (list-el (<','> list-el)* <','?> | EPSILON ) <']'>
143 | = _spread | expr
144 | _spread = '...' value
145 | map =
146 | <'{'> (expr <':'> expr
147 | (<','> (identifier|string|number) <':'> expr)* <','>?
148 | | EPSILON ) <'}'>
149 | get = (get | identifier | map | dot | dot-op)
150 | <'['> (identifier | string | number | dot | dot-op) <']'>
151 |
152 | _operator = '=' | '*=' | '/=' | '~/=' | '%=' | '+=' | '<<=' | '>>='
153 | | '>>>=' | '&=' | '^=' | '|=' | '??=' | '-='
154 |
155 | (* type without name *)
156 | = !'await' (modifier | !modifier | modifier)
157 | = 'final' | 'const'
158 | = qualified type-args? <'?'?>
159 | qualified = (identifier <'.'>)* identifier
160 | type-args = <'<'> type-list <'>'>
161 | type-list = dtype (',' dtype)*
162 |
163 | string = #'r?\'([^\']*)\''
164 | identifier = !return #'[a-zA-Z_]+[a-zA-Z0-9!_]*'
165 | number = #'[+-]?[0-9]+(\.[0-9]+)?((e|E)[+-]?[0-9]+)?' | #'0x[0-9a-fA-F]+'
166 |
167 | = #'[0-9]'
168 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DartClojure
2 |
3 | [](https://clojars.org/org.clojars.liverm0r/dartclojure)
4 |
5 | Opinionated Dart to Clojure converter for Flutter widgets.
6 | It doesn't (and probably will not) convert classes, setters, or annotations—only the parts that can be reused after translation.
7 |
8 |
9 |
10 | ## How to use
11 |
12 | There are 9 options now:
13 | 1. [Calva (VSCode);](https://github.com/d00mch/DartClojure/#api-from-calva)
14 | 2. [Intellij Idea;](https://github.com/d00mch/DartClojure/#api-from-intellij-idea)
15 | 3. [Jvm/Js REPL;](https://github.com/d00mch/DartClojure/#api-from-jvmjs-repl)
16 | 4. [Clojure Cli;](https://github.com/d00mch/DartClojure/#api-from-cli)
17 | 5. [Jar;](https://github.com/d00mch/DartClojure/#api-with-jar)
18 | 6. [Native image;](https://github.com/d00mch/DartClojure/#api-with-native-image)
19 | 7. [Native image, Emacs;](https://github.com/D00mch/DartClojure#api-with-native-image-via-emacs)
20 | 8. [NPM CLI;](https://github.com/d00mch/DartClojure/#api-with-npm-cli)
21 | 9. [NPM library;](https://github.com/d00mch/DartClojure/#api-with-npm-library)
22 |
23 | ## Why is it not a full dart->clojure converter?
24 |
25 | The converted code would not be idiomatic. Instead of using
26 | classes, there is a [widget][1] macro.
27 |
28 | Setters are also useless; there would be a `:state` atom
29 | and `swap!` or `reset!` functions for changing the state.
30 |
31 | So I see little value in converting everything.
32 |
33 | But rewriting widgets is routine and most of the time translates literally:
34 |
35 | ```dart
36 | Center(
37 | child: Text(
38 | _active ? 'Active' : 'Inactive',
39 | style: const TextStyle(fontSize: 32.0, color: Colors.white),
40 | ),
41 | );
42 | ```
43 |
44 | ```clojure
45 | (m/Center
46 | .child (m/Text
47 | (if _active "Active" "Inactive")
48 | .style (m/TextStyle .fontSize 32.0 .color m.Colors/white)))
49 | ```
50 |
51 | Three more examples:
52 |
53 | 
54 |
55 |
56 | ## Supported
57 |
58 | - constructor invocation;
59 | - static, factory methods invocation;
60 | - named arguments;
61 | - (typed) lists, maps, cascade operator (`..`);
62 | - math and logical expressions;
63 | - ternary operators;
64 | - lambdas;
65 | - comments (will be removed);
66 | - nesting children with the f/nest macro;
67 | - constants;
68 | - variables in strings with $;
69 | - raw (interpreted) strings like `r'some string $dollar'`
70 | - class/methods/fields declarations (not tested well, pre-alpha);
71 | - try-catch;
72 | - for in;
73 | - switch with breaks and returns;
74 |
75 | ## Not supported
76 |
77 | - bitwise operators;
78 | - proper aliases for everything, it's not possible to get this info generally;
79 | - enums;
80 | - external keyword;
81 | - yield;
82 | - exports;
83 | - switch with continue, without breaks or returns (considered unidiomatic);
84 | - for with declaration, condition and increment (considered unidiomatic)
85 | - while (considered unidiomatic)
86 | - early exits from lambdas (ignored);
87 | - `...` operator (ignored);
88 | - typedefs (ignored);
89 | - annotations (ignored);
90 |
91 | ## TODO:
92 |
93 | - [ ] test classes and methods extensively;
94 | - [ ] handle early exit from lambdas/if/for/methods with `return`;
95 |
96 |
97 | ## How to use
98 |
99 | ### API from Calva
100 |
101 | [Calva][6] (a VSCode Clojure extension) packs DartClojure conversion into a command. This makes it easy to paste some Dart code and convert it.
102 |
103 |
104 |
105 | See [Calva ClojureDart docs][5] for a little more on the subject.
106 |
107 | ### API from IntelliJ IDEA
108 |
109 | You can use the available [api](https://github.com/d00mch/DartClojure/#how-to-use) (4, 5, 6, 7) directly from IDEA with [External Tools][3].
110 |
111 | Preferences —> Tools —> External Tools —> +
112 |
113 | `Program`: any terminal command. For example, if you have npm, install
114 | dartclojure globally and put `dartclojure` in the `Program` field. If you
115 | downloaded the native image, put the path to the native image here:
116 | `/Users/PcName/Downloads/dartclojure-aarch64-darwin`
117 |
118 | `Arguments`: `"$SelectedText$"`
119 |
120 | 
121 |
122 | That's it. Select code, press `Shift + Shift` (or `Cmd + Shift + A`), type `DartClojure` and press Enter (or set up a hotkey for it). Here's a little [video][7] showing how it looks.
123 |
124 | ### API from JVM/JS REPL
125 |
126 | [Clojars][2].
127 |
128 | Add CLI/deps:
129 | ```clojure
130 | {:deps
131 | {
132 | org.clojars.liverm0r/dartclojure {:mvn/version "0.2.23-SNAPSHOT"}
133 | }}
134 | ```
135 |
136 | Or Leiningen/Boot:
137 | ```clojure
138 | [org.clojars.liverm0r/dartclojure "0.2.23-SNAPSHOT"]
139 | ```
140 |
141 | Convert Dart code (simplify and wrap-nest under the hood):
142 | ```clojure
143 | (require '[dumch.convert :refer [convert]])
144 |
145 | (convert "1 + 1 + 2 * 1;" :format :sexpr) ; => (+ 1 1 (* 2 1))
146 | ```
147 |
148 | You may pass aliases for material and flutter-macro:
149 | ```clojure
150 | (convert "Text('1')" :material "m" :flutter "f") ; => "(m/Text "1")"
151 | ```
152 |
153 | If you just need to wrap Clojure code with nest:
154 | ```clojure
155 | (require
156 | '[dumch.improve :as impr]
157 | '[rewrite-clj.zip :as z])
158 |
159 | (-> "(Container .child (Box .child (Padding .child (:Text \"2\"))))"
160 | z/of-string
161 | impr/wrap-nest
162 | z/sexpr)
163 | ; => (f/nest (Container) (Box) (Padding) (:Text "2"))
164 | ```
165 |
166 | ### API from CLI
167 |
168 | ```bash
169 | clojure -Sdeps \
170 | '{:deps {org.clojars.liverm0r/dartclojure {:mvn/version "0.2.23-SNAPSHOT"}}}' \
171 | -e "(require '[dumch.convert :refer [convert]]) (convert \"Text('1')\" :material \"m\" :flutter \"f\")"
172 | ```
173 |
174 | ### API with Jar
175 |
176 | There are two ways to interact with the [jar][4]. The first is to run it each time:
177 |
178 | ```
179 | $ java -jar dartclojure.jar "Divider(
180 | height: 0,
181 | color: Colors.grey,
182 | )"
183 |
184 | (m/Divider .height 0 .color m.Colors/grey)
185 | ```
186 |
187 | The second is to run REPL-like console (and send code into it with your editor/IDE):
188 | ```
189 | $ java -jar dartclojure.jar -r true -m "material"
190 | Paste dart code below, press Enter and see the result:
191 |
192 | Divider(
193 | height: 0,
194 | color: Colors.grey,
195 | )
196 |
197 | (material/Divider .height 0 .color material.Colors/grey)
198 | ```
199 |
200 | Colors are also supported:
201 |
202 | 
203 |
204 | For example, you may start the REPL-like console app with `-e` key:
205 | ```
206 | $ java -jar dartclojure.jar -r true -e :end
207 | ```
208 |
209 | For all the arguments, see:
210 | ```bash
211 | $ java -jar dartclojure.jar -h
212 | ```
213 |
214 | ### API with native image:
215 |
216 | Same API as with the jar:
217 |
218 | ./dartclojure -h
219 |
220 | ./dartclojure "Text('a')" -m "m"
221 |
222 | ./dartclojure --path main.dart
223 |
224 | ./dartclojure -r true
225 |
226 | If there is no build for your architecture on [release page][4],
227 | see how to build it with graalvm below.
228 |
229 | ### API with native image via Emacs
230 |
231 | You can use the Emacs package from [dartclojure.el](https://github.com/burinc/dartclojure.el) via your favorite Emacs package manager.
232 |
233 | ### API with npm CLI
234 |
235 | Same API as with the jar and native image:
236 |
237 | ```sh
238 | npm i dartclojure
239 |
240 | npx dartclojure -h
241 |
242 | npx dartclojure "Text('a')" -m "m"
243 | ```
244 |
245 | You can, of course, also install it globally:
246 |
247 | ```sh
248 | npm i -g dartclojure
249 |
250 | dartclojure -h
251 |
252 | dartclojure "Text('a')" -m "m"
253 | ```
254 |
255 | ### API with npm library
256 |
257 | ```js
258 | const converter = require('dartclojure');
259 |
260 | const clojureCode = converter.convert("Text('a')");
261 | ```
262 |
263 | ## Contribution
264 |
265 | Build the jar:
266 |
267 | $ clj -T:build uber :version '"0.2.22"'
268 |
269 | Run tests:
270 |
271 | $ clj -X:test ; clj -M:test-cljs
272 |
273 | Run Docker, build the GraalVM image:
274 |
275 | $ cp target/dartclojure*.jar dartclojure.jar
276 | $ docker build --pull --no-cache --tag dartclojure .
277 | $ docker run --name dc -it dartclojure ./dartclojure "Text('should work')"
278 | $ docker cp dc:/usr/src/app/dartclojure.
279 |
280 | Compile a native image with GraalVM locally:
281 |
282 | # install graalvm
283 | $ chmod +x compile.sh
284 | $ ./compile.sh
285 |
286 | Remember to comment out the line with `-H:+StaticExecutableWithDynamicLibC` for OSX M1
287 | builds.
288 |
289 | Start the shadow-cljs watcher and REPL:
290 |
291 | ```
292 | clj -M:shadow-cljs watch :app :lib :test
293 | ```
294 |
295 | (You can use this for developing both the Clojure and ClojureScript library, but the test watcher will only be watching and running the ClojureScript tests.)
296 |
297 | Install the local npm package:
298 |
299 | ```
300 | npm link dartclojure
301 | ```
302 |
303 | ## License
304 |
305 | Copyright © 2022 Artur Dumchev
306 |
307 | Licensed under the Apache License, Version 2.0 (the "License");
308 | you may not use this file except in compliance with the License.
309 | You may obtain a copy of the License at
310 |
311 | http://www.apache.org/licenses/LICENSE-2.0
312 |
313 | Unless required by applicable law or agreed to in writing, software
314 | distributed under the License is distributed on an "AS IS" BASIS,
315 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
316 | See the License for the specific language governing permissions and
317 | limitations under the License.
318 |
319 | [1]: https://github.com/Tensegritics/ClojureDart/blob/main/doc/flutter-helpers.md#widget-macro
320 | [2]: https://clojars.org/org.clojars.liverm0r/dartclojure/versions/0.2.23-SNAPSHOT
321 | [3]: https://www.jetbrains.com/help/idea/configuring-third-party-tools.html
322 | [4]: https://github.com/d00mch/DartClojure/releases/tag/0.2.23
323 | [5]: https://calva.io/clojuredart/
324 | [6]: https://marketplace.visualstudio.com/items?itemName=betterthantomorrow.calva
325 | [7]: https://www.reddit.com/r/Clojure/comments/vib5ie/how_to_translate_dart_to_clojuredart_inside/
326 |
--------------------------------------------------------------------------------
/src/dumch/parse.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.parse
2 | (:require
3 | #?(:clj [clojure.java.io :as io])
4 | #?(:cljs [clojure.edn :refer [read-string]])
5 | [clojure.string :as str]
6 | [clojure.set :as set]
7 | #?(:cljs [dumch.base64 :as b64-cljs])
8 | [dumch.util :refer [ws nl maps mapn mapcats mapcatn]]
9 | #?(:cljs [dumch.util :refer-macros [inline-resource]])
10 | #?(:clj [instaparse.core :as insta :refer [defparser]]
11 | :cljs [instaparse.core :as insta :refer-macros [defparser]])
12 | [rewrite-clj.node :as n
13 | :refer [list-node map-node token-node keyword-node vector-node]
14 | :rename {list-node lnode, vector-node vnode, map-node mnode,
15 | token-node tnode, keyword-node knode}]
16 | #_[clj-java-decompiler.core :refer [decompile]]
17 | #_[criterium.core :refer [quick-bench]])
18 | #?(:clj
19 | (:import java.util.Base64)))
20 |
21 | #?(:clj (set! *warn-on-reflection* true))
22 |
23 | (defparser widget-parser
24 | #?(:clj (io/resource "widget-parser.bnf")
25 | :cljs (inline-resource "widget-parser.bnf"))
26 | :auto-whitespace :standard)
27 |
28 | (defn- dart-op->clj-op [o]
29 | (case o
30 | "is" 'dart/is?
31 | "??" 'or
32 | "==" '=
33 | "!=" 'not=
34 | "%" 'rem
35 | "~/" 'quot
36 | (symbol o)))
37 |
38 | (defn- substitute-curly-quotes [s & {f :backward}]
39 | ;; crutch for cases like ''' ' ''' and '\''
40 | (if f
41 | (-> (str/replace s #"”" "\"")
42 | (str/replace #"’" "'"))
43 | (-> (str/replace s #"\"" "”")
44 | (str/replace #"'" "’"))))
45 |
46 | (defn- split-by-$-expr [s]
47 | ;; two reasons for it to be that complex:
48 | ;; - can't make regex for nested {{}} work in jvm: (?=\{((?:[^{}]++|\{(?1)\})++)\})
49 | ;; - regex is slow anyway;
50 | (loop [stack [] ;; to count balanced curly: '{', '}'
51 | rslt []
52 | cur-str []
53 | cur-expr []
54 | i 0]
55 | (if (>= i (count s))
56 | (conj rslt (apply str (if (empty? cur-expr) cur-str cur-expr)))
57 |
58 | (let [ch (.charAt ^String s i)
59 | building-str? (empty? stack)
60 | allow-open-b? (and (> i 0) (= (.charAt ^String s (dec i)) \$))
61 | open-b? (and (or allow-open-b? (seq stack)) (= ch \{))
62 | close-b? (= ch \})
63 | expr-ends? (and close-b? (= (count stack) 1))]
64 |
65 | (if building-str?
66 | (recur
67 | (if open-b? (conj stack 1) stack)
68 | (if open-b?
69 | (conj rslt (subs (apply str cur-str) 0 (dec (count cur-str))))
70 | rslt)
71 | (if open-b? [] (conj cur-str ch))
72 | cur-expr
73 | (inc i))
74 |
75 | (recur
76 | (cond open-b? (conj stack 1)
77 | close-b? (pop stack)
78 | :else stack)
79 | (if expr-ends? (conj rslt (apply str cur-expr)) rslt)
80 | cur-str
81 | (if expr-ends? [] (conj cur-expr ch))
82 | (inc i)))))))
83 |
84 | (defn- substitute-$
85 | "Returns string AST with $ substitutions"
86 | [^:String s]
87 | (let [p #"\$[a-zA-Z_]+[a-zA-Z0-9!_]*"
88 | s (str/replace s p (fn [m] (str "${" (subs m 1) "}")))
89 | sq (split-by-$-expr s)]
90 | (if (= (count sq) 1)
91 | [:string+ s]
92 | [:strings+ (->> sq
93 | (map-indexed #(if (zero? (mod (inc %1) 2))
94 | (widget-parser %2)
95 | (when (seq %2) [:string+ %2])))
96 | (filter some?))])))
97 |
98 | (defn- node->string-ast
99 | "Returns ast, handling $, de-`substitute-curly-quotes`, commas and r (raw str)"
100 | [[_ s]]
101 | (if (-> s first (= \r))
102 | [:string+ (str/replace s #"^r.|.$" "")]
103 | (-> (str/replace s #"^.|.$" "")
104 | (substitute-curly-quotes :backward true)
105 | substitute-$)))
106 |
107 | (defn- node->number [[tag value]]
108 | (cond (not= tag :number)
109 | (throw (ex-info "node with wrong tag passed" {:tag tag}))
110 |
111 | (str/starts-with? value "0x")
112 | (symbol value)
113 |
114 | :else
115 | (-> value (str/replace #"^\." "0.") read-string)))
116 |
117 | (declare ast->clj)
118 |
119 | (defn- flatten-dot [node]
120 | (loop [[tag v1 v2 :as node] node ;; having structure like [dot [dot a b] c]
121 | stack [] ;; put here 'c', then 'b', while trying to find 'a' ^
122 | [a [tag2 n params :as b] :as rslt] [] ;; result will look like [a b c]
123 | op? false]
124 | (cond (= :dot tag) (recur v1 (conj stack v2) rslt op?)
125 | (= :dot-op tag) (recur v1 (conj stack v2) rslt true)
126 | node (recur nil (conj stack node) rslt op?)
127 | (seq stack) (recur node (pop stack) (conj rslt (peek stack)) op?)
128 | op? (lnode (list* (tnode 'some->) ws (maps ast->clj rslt)))
129 | (= (count rslt) 2)
130 | (ast->clj [tag2 n (cons :params (cons [:argument a] (next params)))])
131 | :else (lnode (list* (tnode '->) ws (maps ast->clj rslt))))))
132 |
133 | (defn- dot->clj [[tag v1 v2]]
134 | (let [dt (if (= tag :invoke) "." ".-")]
135 | (if (and v2 (> (count v2) 1))
136 | (lnode (list* (ast->clj [tag v1]) ws (ast->clj v2)))
137 | (tnode (symbol (str dt (ast->clj v1)))))))
138 |
139 | (defn flatten-same-node [[f & params]] ;; [f [f 1 2] 3] -> [f 1 2 3]
140 | (mapcat
141 | #(if (and (sequential? %) (= (first %) f))
142 | (flatten-same-node %)
143 | [%])
144 | params))
145 |
146 | (defn flatten-cascade [node]
147 | (let [flt (flatten-same-node node)]
148 | (lnode
149 | (list* (tnode 'doto) ws
150 | (ast->clj (first flt))
151 | (->> flt
152 | (drop 1)
153 | (map (fn [[tag & params :as node]]
154 | (if (= tag :constructor)
155 | (cons :invoke params)
156 | node)))
157 | (maps ast->clj))))))
158 |
159 | (defn- flatten-commutative-node [[f :as node]]
160 | (list*
161 | [:identifier (case f :and "and", :or "or", :add "+", :mul "*")]
162 | (flatten-same-node node)))
163 |
164 | (defn compare-longest-path
165 | "Getting a seq of nodes like:
166 | `([:compare [:identifier \"a\"] \">\" [:identifier \"b\"]]
167 | [:compare [:identifier \"b\"] \">\" [:identifier \"c\"]] ...)`.
168 | In other words, we have a graph here. Example:
169 | `a -> b, b -> c, b -> d, c -> e`.
170 | This function returns the seq of nodes which is the longest path.
171 | In terms of 'Example' above, it is going to be: `a -> b -> c -> e`"
172 | ([nodes]
173 | (compare-longest-path nodes (group-by #(-> % second second) nodes)))
174 | ([nodes dictionary]
175 | (apply max-key
176 | count
177 | ; node exmaple
178 | (for [[_ [_ _] _ [_ end] :as node] nodes
179 | :let [continues (get dictionary end)]]
180 | (cons
181 | node
182 | (when continues
183 | (compare-longest-path continues (dissoc dictionary end))))))))
184 |
185 | (defn- build-compare-ast [compare-vals]
186 | (list* :compare+
187 | [:identifier (nth (first compare-vals) 2)]
188 | (second (first compare-vals))
189 | (map #(nth % 3) compare-vals)))
190 |
191 | (defn- unify-compare
192 | "If we have different compare functions in the node, like `<` and `>`,
193 | replace all `<` with `>` and `<=` with `>=`.
194 | Returns grouped by function sequences"
195 | [compare-nodes]
196 | (let [compare-fns (set (map #(nth % 2) compare-nodes))]
197 | (if (<= (count compare-fns) 1)
198 | [compare-nodes]
199 | (->> compare-nodes
200 | (mapv
201 | (fn [[tag e1 f e2 :as node]]
202 | (cond (= f "<") [tag e2 ">" e1]
203 | (= f "<=") [tag e2 ">=" e1]
204 | :else node)))
205 | (group-by #(nth % 2))
206 | vals))))
207 |
208 | (defn- flatten-compare [[tag & params :as and-node]]
209 | (let [{compare-nodes true,
210 | other-nodes false} (group-by (fn [[f]] (= f :compare)) params)]
211 | (if compare-nodes
212 | ;; `seq` below means `seq of nodes`
213 | (let [compare-seqs (unify-compare compare-nodes)
214 | longest-seqs (map compare-longest-path compare-seqs)
215 | ast-seqs (map build-compare-ast longest-seqs)
216 | other-nodes (apply set/difference
217 | (set (apply concat other-nodes compare-seqs))
218 | (or (map set longest-seqs) '(#{})))]
219 | (cond (seq other-nodes)
220 | (concat [tag] other-nodes ast-seqs)
221 |
222 | (= (count ast-seqs) 1) (next (first ast-seqs))
223 |
224 | :else (cons tag ast-seqs)))
225 | and-node)))
226 |
227 | (defn dfs [f sq]
228 | (some f (tree-seq coll? seq sq)))
229 |
230 | (defn- switch-case-ok? [[tag v1 v2 v3]]
231 | (or (= tag :default-case)
232 | (and (= tag :switch-case)
233 | (= (first v1) :cases)
234 | (or (some-> v3 second (= "break"))
235 | (dfs #{:return} v2)))))
236 |
237 | (defn- if->clj [node]
238 | (case (count node)
239 | 3 (lnode (list* (tnode 'when) ws (->> node rest (maps ast->clj))))
240 | 4 (lnode (list* (tnode 'if) ws (->> node rest (maps ast->clj))))
241 | (lnode
242 | (if (even? (count node))
243 | (concat
244 | (list* (tnode 'cond) ws (->> node butlast rest (maps ast->clj)))
245 | [ws (knode :else) ws (ast->clj (peek node))])
246 | (list* (tnode 'cond) ws (->> node rest (maps ast->clj)))))))
247 |
248 | (defn- switch-ok? [[_ _ & cases]]
249 | (reduce #(and %1 %2) (map switch-case-ok? cases)))
250 |
251 | (defn- switch-case->clj-nodes [[_ [_ & cases] body]]
252 | (let [body (ast->clj body)]
253 | (mapcat
254 | #(list (ast->clj %) body)
255 | cases)))
256 |
257 | (defn- switch-branch->clj-nodes [[tag v1 :as node]]
258 | (if (= tag :switch-case)
259 | (switch-case->clj-nodes node)
260 | [(ast->clj v1)]))
261 |
262 | (defn- switch->case-or-warn [[_ expr & cases :as node]]
263 | (if (switch-ok? node)
264 | (lnode
265 | (list*
266 | (tnode 'case) ws
267 | (ast->clj expr) nl
268 | (mapcatn #(switch-branch->clj-nodes %) cases)))
269 | :unidiomatic))
270 |
271 | (defn- try-on->clj-node [[_ [_ q] [_ e] body :as on-part]]
272 | (lnode [(tnode 'catch) ws
273 | (ast->clj (or q [:identifier "Exception"])) ws
274 | (ast->clj (or e [:identifier "e"])) nl
275 | (ast->clj body)]))
276 |
277 | (defn- try-branch->clj-node [node]
278 | (if (= (count node) 2)
279 | (lnode [(tnode 'finally) ws (ast->clj (second node))])
280 | (try-on->clj-node node)))
281 |
282 | (defn- try->clj [[_ body & branches]]
283 | (lnode
284 | (list*
285 | (tnode 'try) nl
286 | (ast->clj body)
287 | (map #(try-branch->clj-node %) branches))))
288 |
289 | (defn- var-declare->clj [[_ v1 :as node]]
290 | (let [inits (filter sequential? node)
291 | const? (= v1 "const")
292 | with-const (fn [[_ n v :as var-init-node]]
293 | (if const?
294 | [:var-init [:const n] v]
295 | var-init-node))]
296 | (if (= (count inits) 1)
297 | (ast->clj (with-const (first inits)))
298 | (lnode
299 | (list* (tnode 'do) ws
300 | (->> (map with-const inits)
301 | (maps ast->clj)))))))
302 |
303 | (defn ast->clj [[tag v1 v2 v3 :as node]]
304 | #_(println :node node)
305 | (case tag
306 | :s (ast->clj v1)
307 | :code (if v2
308 | (lnode (list* (tnode 'do) nl (mapn ast->clj (rest node))))
309 | (ast->clj v1))
310 |
311 | :file (if v2
312 | (n/list-node (list* (tnode 'do) nl (mapn ast->clj (rest node))))
313 | (ast->clj v1))
314 | :import-block (lnode (list* (tnode 'require) ws (mapn ast->clj (rest node))))
315 | :import-as (vnode [(ast->clj v1) ws (knode :as) ws (ast->clj v2)])
316 | :import-naked (vnode [(ast->clj v1) ws (knode :as) ws 'give-an-alias-or-refer])
317 | :import-show (vnode [(ast->clj v1) ws
318 | (knode :refer) ws
319 | (vnode (maps ast->clj (drop 2 node)))])
320 | :import-hide (vnode [(ast->clj v1) ws (knode :as) ws 'be-aware-of-hide-here])
321 | :import-full
322 | (vnode [(ast->clj v1) ws
323 | (knode :as) ws
324 | (ast->clj v2) ws
325 | (knode :refer) ws
326 | (vnode (maps ast->clj (drop 3 node)))])
327 | :var-declare (var-declare->clj node)
328 | :var-init (lnode [(tnode 'def) ws
329 | (ast->clj v1) ws
330 | (or (some-> v2 ast->clj) (tnode 'nil))])
331 | :class
332 | (lnode (list*
333 | (tnode 'comment) nl
334 | "use flutter/widget macro instead of classes" nl
335 | (mapcat #(if (sequential? %) % [%])
336 | (mapn ast->clj (rest node)))))
337 | :method (lnode [(tnode 'defn) ws
338 | (ast->clj v1) ws
339 | (ast->clj v2) ws
340 | (ast->clj v3)])
341 |
342 | :constructor (lnode (list* (ast->clj v1) ws (ast->clj v2)))
343 | :params (mapcats ast->clj (rest node))
344 | :argument (if v2 (map ast->clj (rest node)) [(ast->clj v1)])
345 | :named-arg (tnode (symbol (str "." (ast->clj v1))))
346 |
347 | :dot (flatten-dot node)
348 | :dot-op (flatten-dot node)
349 | :invoke (dot->clj node)
350 | :field (dot->clj node)
351 |
352 | :lambda (lnode [(tnode 'fn) ws (ast->clj v1) nl (ast->clj v2)])
353 | :lambda-args (vnode (->> node rest (maps ast->clj)))
354 | :block (ast->clj (cons :code (rest node)))
355 |
356 | :ternary (ast->clj [:if v1 v2 v3])
357 | :if (if->clj node)
358 | :switch (switch->case-or-warn node)
359 | :try (try->clj node)
360 | :cascade (flatten-cascade node)
361 |
362 | :for-in (n/list-node [(tnode 'for) ws
363 | (vnode [(ast->clj v1) ws (ast->clj v2)]) nl
364 | (ast->clj v3)])
365 |
366 | :return (if v1 (ast->clj v1) (tnode 'nil))
367 | :typecasting (ast->clj v1)
368 | :const (n/meta-node (tnode :const) (ast->clj v1))
369 | :identifier (symbol (str/replace v1 #"!" ""))
370 | :qualified (tnode (symbol (str/join "." (map ast->clj (next node)))))
371 | :list (n/vector-node (maps ast->clj (rest node)))
372 | :map (mnode (maps ast->clj (rest node)))
373 | :get (lnode [(tnode 'get) ws (ast->clj v1) ws (ast->clj v2)])
374 | :string (-> node node->string-ast ast->clj)
375 | :string+ v1
376 | :strings+ (lnode (list* (tnode 'str) ws (maps ast->clj v1)))
377 | :number (node->number node)
378 |
379 | :neg (lnode [(tnode '-) ws (ast->clj v1)])
380 | :sub (lnode [(tnode '-) ws (ast->clj v1) ws (ast->clj v2)])
381 | :await (lnode [(tnode 'await) ws (ast->clj v1)])
382 |
383 | :and (->> node flatten-commutative-node flatten-compare (maps ast->clj) lnode)
384 | :compare+ (lnode (list* (ast->clj v1) ws (->> node (drop 2) (maps ast->clj))))
385 | (:or :add :mul) (lnode (maps ast->clj (flatten-commutative-node node)))
386 | (:not :dec :inc) (lnode [(tnode (symbol tag)) ws (ast->clj v1)])
387 | (:compare :div :ifnull :equality)
388 | (lnode [(tnode (dart-op->clj-op v2)) ws (ast->clj v1) ws (ast->clj v3)])
389 |
390 | (cond
391 | (and (keyword? tag) (-> tag str second (= \_))) :unidiomatic
392 | :else :unknown)))
393 |
394 | (defn- encode [^String to-encode]
395 | #?(:clj (.encodeToString (Base64/getEncoder) (.getBytes to-encode))
396 | :cljs (b64-cljs/utf8_to_b64 to-encode)))
397 |
398 | (defn- decode [^String to-decode]
399 | #?(:clj (String. (.decode (Base64/getDecoder) to-decode))
400 | :cljs (b64-cljs/b64_to_utf8 to-decode)))
401 |
402 | (defn- multiline->single [s]
403 | (let [pattern #"'{3}([\s\S]*?'{3})|\"{3}([\s\S]*?\"{3})"
404 | transform (fn [[m]] (substitute-curly-quotes m))]
405 | (-> s
406 | (str/replace pattern transform)
407 | (str/replace #"”””|’’’" "'"))))
408 |
409 | (defn clean
410 | "removes comments from string, transforms multiline string
411 | to singleline, replaces quotes (', \") with 'curly-quotes' (“)"
412 | [code]
413 | (let [str-pattern #"([\"\'])(?:(?=(\\?))\2.)*?\1"
414 | transform #(fn [[m]]
415 | (str "'" (% (subs m 1 (dec (count m)))) "'"))]
416 | (-> code
417 |
418 | ;; to simplify modifications below
419 | multiline->single
420 |
421 | ;; TODO: find another way to deal with comments
422 | ;; the problem is that comments could appear inside strings
423 | (str/replace str-pattern (transform encode)) ; encode strings to Base64
424 |
425 | ;; cleaning code from comments
426 | (str/replace #"/\*(\*(?!/)|[^*])*\*/" "") ; /* ... */
427 | (str/replace #"(//).*" "") ; // ...
428 |
429 | ;; new is optional
430 | (str/replace "new " "")
431 |
432 | (str/replace str-pattern
433 | (transform (comp substitute-curly-quotes decode))))))
434 |
435 | (defn save-read [code]
436 | (try
437 | (n/sexpr code)
438 | (catch #?(:clj Exception
439 | :cljs js/Error) e (n/string code))))
440 |
441 | (defn dart->ast [^:String dart]
442 | (insta/parse widget-parser (clean dart)))
443 |
444 | (defn dart->clojure [^:String dart]
445 | (-> dart dart->ast (ast->clj) save-read))
446 |
447 | (comment
448 |
449 | (def code "
450 | class A {
451 | static var i = 1;
452 | }
453 | ")
454 |
455 | (def code2 "
456 | Future createOrderMessage() async {
457 | var order = await fetchUserOrder();
458 | return 'Your order is: $order';
459 | }
460 | ")
461 |
462 | (insta/parses widget-parser code2)
463 |
464 | (dart->clojure code2)
465 |
466 | (-> "a && b && c"
467 | dart->ast
468 | ast->clj
469 | n/string))
470 |
--------------------------------------------------------------------------------
/test/dumch/parse_test.cljc:
--------------------------------------------------------------------------------
1 | (ns dumch.parse-test
2 | (:require #?(:cljs [clojure.edn :refer [read-string]])
3 | [clojure.test :refer [deftest testing is]]
4 | [dumch.improve :as improve :refer [simplify]]
5 | [dumch.parse :refer [clean widget-parser dart->clojure dart->ast ast->clj]]
6 | [instaparse.core :as insta]
7 | [rewrite-clj.zip :as z]
8 | [rewrite-clj.node :as n]))
9 |
10 | (def ^:private dart->clj-simplified
11 | (comp z/sexpr simplify ast->clj dart->ast))
12 |
13 | (def ^:private dart->clj-string
14 | (comp z/string simplify ast->clj dart->ast))
15 |
16 | (deftest numbers-test
17 | (testing "real numbers"
18 | (is (= (dart->clojure "1") 1))
19 | (is (= (dart->clojure "10.10") 10.1))
20 |
21 | (testing ": exponential"
22 | (is (= (dart->clojure "1.0E03") 1000.0))
23 | (is (= (dart->clojure "-1.23e+45") -1.23E45))))
24 |
25 | (testing "colors"
26 | ;; this test uses string because hex format is auto-converted to long
27 | (is (= (str (dart->clojure "new Color(0xFFE3F2FD)"))
28 | "(Color 0xFFE3F2FD)"))))
29 |
30 | (deftest import-test
31 | (testing "import with 'hide'"
32 | (is (= (dart->clojure "import 'pkg:goog/maps.dart' hide LatLng")
33 | '(require ["pkg:goog/maps.dart" :as be-aware-of-hide-here]))))
34 | (testing "import with 'show'"
35 | (is (= (dart->clojure "import 'package:f/s.dart' show Delta;")
36 | '(require ["package:f/s.dart" :refer [Delta]]))))
37 | (testing "import without specifications"
38 | (is (= (dart->clojure "import 'package:flutter/widgets.dart';")
39 | '(require ["package:flutter/widgets.dart" :as give-an-alias-or-refer]))))
40 | (testing "import with 'as' and 'show'"
41 | (is (= (dart->clojure "import 'pkg:goog/maps.dart' as GMap show LatLng;")
42 | '(require ["pkg:goog/maps.dart" :as GMap :refer [LatLng]])))))
43 |
44 | (deftest methods-test
45 | (testing "method with body"
46 | (is (= (dart->clojure
47 | "@override
48 | Widget build(BuildContext context) {
49 | return Text('name');
50 | }")
51 | '(defn build [context] (Text "name")))))
52 | (testing "static method"
53 | (is (= (dart->clojure
54 | "static void staticVoid() { print(1); }")
55 | '(defn staticVoid [] (print 1)))))
56 | (testing "void method with expression"
57 | (is (= (dart->clojure
58 | "void _toggleFavorite() => setState(() { print(1); });")
59 | '(defn _toggleFavorite [] (setState (fn [] (print 1))))))
60 | (is (= (dart->clojure
61 | "void main() => runApp(App());")
62 | '(defn main [] (runApp (App))))))
63 | (testing "method with dot in type"
64 | (is (= (dart->clojure "A.B.C a() => 1") '(defn a [] 1))))
65 | (testing "method without type"
66 | (is (= (dart->clojure "a() => 1") '(defn a [] 1)))))
67 |
68 | (deftest get-set-test
69 | (testing "getter with => and with body {}"
70 | (is (= (dart->clojure "class A {
71 | Key get dividerKey => Key('$this');
72 | Key get dividerKey2 { return 1; };
73 | }")
74 | '(comment "use flutter/widget macro instead of classes"
75 | :unknown
76 | :unknown))))
77 | (testing "setter with => and with body {}"
78 | (is (= (dart->clojure "class A {
79 | set right(double value) => left = value - width;
80 | set right(double value) { a = b; }
81 | }")
82 | '(comment
83 | "use flutter/widget macro instead of classes"
84 | (defn right [value] :unidiomatic)
85 | (defn right [value] :unidiomatic))))))
86 |
87 | (deftest invocations-name-test
88 | (testing "simple constructor"
89 | (is (= (dart->clojure "Text('text')")
90 | (-> '(Text "text")))))
91 | (testing "typed constructor"
92 | (is (= (dart->clojure "Text, C?>('text')")
93 | (-> '(Text "text")))))
94 | (testing "line invocations"
95 | (is (= (dart->clojure "One(1).two().three(2, 3)")
96 | '(-> (One 1) .two (.three 2 3)))))
97 | (testing "instance method invocation"
98 | (is (= (dart->clojure "_pinPut.copyWith(border: 1)")
99 | '(.copyWith _pinPut .border 1))))
100 | (testing "field's field.method invocation"
101 | (is (= (dart->clojure "field!.pinPut.copyWith(border: 1)")
102 | '(-> field .-pinPut (.copyWith .border 1)))))
103 | (testing "static field method invocation"
104 | (is (= (dart->clojure "SClass.field.copyWith(border: 1)")
105 | '(-> SClass .-field (.copyWith .border 1)))))
106 | (testing "invocation on list"
107 | (is (= (-> "[1].cast()" dart->clojure)
108 | '(.cast [1])))
109 | (is (= (-> "[1].length" dart->clojure)
110 | '(.-length [1]))))
111 | (testing "invocation on map"
112 | (is (= (-> "{1:1}.cast()" dart->clojure)
113 | '(.cast {1 1})))
114 | (is (= (-> "{1:1}.length" dart->clojure)
115 | '(.-length {1 1}))))
116 | (testing "long chaing of dots"
117 | (is (= (-> "a.b().c.d().e()" dart->clojure)
118 | '(-> a .b .-c .d .e)))))
119 |
120 | (deftest optional-name-test
121 | (testing "optional field somewhere in the chain"
122 | (is (= (-> "obj?.field.name?.first" dart->clojure)
123 | '(some-> obj .-field .-name .-first)))
124 | (is (= (-> "obj.field?.name" dart->clojure)
125 | '(some-> obj .-field .-name))))
126 | (testing "field in optional object"
127 | (is (= (-> "obj?.name" dart->clojure)
128 | '(some-> obj .-name))))
129 | (testing "only one optional in the chain"
130 | (is (= (-> "a.b?.c.d().e" dart->clojure)
131 | '(some-> a .-b .-c .d .-e)))))
132 |
133 | (deftest optional-invocation-test
134 | (testing "optional field somewhere in the invocation chain"
135 | (is (= (dart->clojure "SClass?.field.copyWith(border: 1)")
136 | '(some-> SClass .-field (.copyWith .border 1))))
137 | (is (= (dart->clojure "SClass.field?.copyWith()")
138 | '(some-> SClass .-field .copyWith))))
139 | (testing "invocation on optional field"
140 | (is (= (dart->clojure "instance?.copyWith(border: 1)")
141 | '(some-> instance (.copyWith .border 1))))))
142 |
143 | (deftest ^:current list-test
144 | (testing "empty list" (is (= (dart->clojure "[]") '[])))
145 | (testing "ignore spread operator"
146 | (is (= (-> "[...state.a.map((acc) => _t(ctx, acc))]"
147 | dart->clojure)
148 | '[(-> :unidiomatic .-a (.map (fn [acc] (_t ctx acc))))])))
149 | (testing "typed list"
150 | (is (= (-> "[1, 2]" dart->clojure)
151 | [1 2])))
152 | (testing "column children typeless list"
153 | (is
154 | (= (-> "Column(children: [const Text('name'),
155 | Icon(Icons.widgets)])"
156 | dart->clojure)
157 | '(Column .children [(Text "name") (Icon (.-widgets Icons))]))))
158 | (testing "ifnull and ternary list elements"
159 | (is (= (-> "[ a? 1 : b, c ?? d ]" dart->clojure)
160 | '[(if a 1 b) (or c d)]))))
161 |
162 | (deftest map-test
163 | (testing "empty map" (is (= (dart->clojure "{}") '{})))
164 | (testing "map with end comma" (is (= (dart->clojure "{1: 1,}") '{1 1})))
165 | (testing "typeless map as named parameter"
166 | (is
167 | (= (dart->clojure "ListCell.icon(m: {1 : 2, 'a' : b, c : 'd'})")
168 | '(.icon ListCell .m {1 2, "a" b, c "d"}))))
169 | (testing "typed map"
170 | (is
171 | (= (-> ">{1: [1, 2]}" dart->clojure)
172 | {1 [1 2]})))
173 | (testing "ifnull and ternary map elements"
174 | (is
175 | (= (-> ">{ a ? 1 : 2 : a ?? b}" dart->clojure)
176 | '{(if a 1 2) (or a b)}))))
177 |
178 | (deftest set!-test
179 | (is (= (dart->clojure "a = b") :unidiomatic)))
180 |
181 | (deftest get-test
182 | (testing "get for field"
183 | (is (= (dart->clojure "Colors.red[500]!")
184 | '(get (.-red Colors) 500))))
185 | (testing "single get"
186 | (is (= (dart->clojure "tabs[2]") '(get tabs 2))))
187 | (testing "serveral get in a row"
188 | (is (= (dart->clojure "questions[1]['two']")
189 | '(get (get questions 1) "two")))))
190 |
191 | (deftest logic-test
192 | (testing "and: &&"
193 | (is (= (dart->clojure "b && a") '(and b a))))
194 | (testing "or: ||, ??"
195 | (is (= (dart->clojure "b || a") '(or b a)))
196 | (is (= (dart->clojure "b ?? a") '(or b a))))
197 | (testing "compare: >, <, =>, <="
198 | (is (= (dart->clojure "b > a") '(> b a)))
199 | (is (= (dart->clojure "b < a") '(< b a)))
200 | (is (= (dart->clojure "b >= a") '(>= b a)))
201 | (is (= (dart->clojure "b <= a") '(<= b a)))
202 | (is (= (dart->clojure "1 is int") '(dart/is? 1 int))))
203 | (testing "equality: ==, !="
204 | (is (= (dart->clojure "b == a") '(= b a)))
205 | (is (= (dart->clojure "b != a") '(not= b a)))))
206 |
207 | (deftest ternary-test
208 | (testing "simple ternary"
209 | (is (= (dart->clojure "a ? b : c") '(if a b c))))
210 | (testing "lambda as ternary parameter"
211 | (is (= (dart->clojure
212 | "TextButton(onPressed: _searchEnabled ? () { pop(); } : null)")
213 | '(TextButton
214 | .onPressed
215 | (if _searchEnabled
216 | (fn [] (pop))
217 | null))))))
218 |
219 | (deftest cascade-test
220 | (is (= (dart->clojure
221 | "getAddress()
222 | ..setStreet('Elm', '13a')
223 | ..city = 'Carthage'
224 | ..state = 'Eurasia'
225 | ..zip(66666, extended: 6666);")
226 | '(doto
227 | (getAddress)
228 | (.setStreet "Elm" "13a")
229 | :unidiomatic
230 | :unidiomatic
231 | (.zip 66666 .extended 6666)))))
232 |
233 | (deftest for-test
234 | (testing "for-in, expressiong body"
235 | (is (= (dart->clojure
236 | "for (int n in names) { print(n); } ")
237 | '(for [n names] (print n)))))
238 | (testing "for-in, curly-body"
239 | (is (= (dart->clojure
240 | "for (int i in names) print(i); ")
241 | '(for [i names] (print i)))))
242 | (testing "for, curly body"
243 | (is (= (dart->clojure
244 | "for (int i = 0; i < 5; i++) {print('GeeksForGeeks');}")
245 | :unidiomatic))))
246 |
247 | (deftest while-test
248 | (testing "while"
249 | (is (= (dart->clojure "while(num >=1) { num--; }")
250 | :unidiomatic)))
251 | (testing "do-while"
252 | (is (= (dart->clojure "do { number++; } while (number < 10);")
253 | :unidiomatic))))
254 |
255 | (deftest const-test
256 | (testing "invocation const"
257 | (is (= (dart->clj-string
258 | "IconButton(padding: const EdgeInsets.all(0),);")
259 | "(m/IconButton .padding ^:const (.all m/EdgeInsets 0))")))
260 | (testing "invocation constructor"
261 | (is (= (dart->clj-string
262 | "const Icon(Icons.star)")
263 | "^:const (m/Icon (.-star m/Icons))")))
264 | (testing "invocation constructor"
265 | (is (= (dart->clj-string
266 | "const Icon(Icons.star)")
267 | "^:const (m/Icon (.-star m/Icons))"))))
268 |
269 | (deftest unary-prefix-test
270 | (testing "not" (is (= (dart->clojure "!a") '(not a))))
271 | (testing "inc" (is (= (dart->clojure "++a") '(inc a))))
272 | (testing "dec" (is (= (dart->clojure "--a") '(dec a))))
273 | (testing "-" (is (= (dart->clojure "-a") '(- a)))))
274 |
275 | (deftest math-test
276 | (testing "difference"
277 | (is (= (dart->clojure "b - a") '(- b a))))
278 | (testing "sum"
279 | (is (= (dart->clojure "b + a") '(+ b a))))
280 | (testing "remainder"
281 | (is (= (dart->clojure "b % a") '(rem b a))))
282 | (testing "divide and round"
283 | (is (= (dart->clojure "b ~/ a") '(quot b a))))
284 | (testing "division"
285 | (is (= (dart->clojure "b / a") '(/ b a))))
286 | (testing "multiply"
287 | (is (= (dart->clojure "b * a") '(* b a)))))
288 |
289 | (deftest lambda-test
290 | (testing "lambda with =>"
291 | (is (= (dart->clojure "Button(onPressed: (ctx) => 1 + 1;)")
292 | '(Button .onPressed (fn [ctx] (+ 1 1))))))
293 | (testing "lambda with body"
294 | (is (= (dart->clojure "Button(onPressed: (ctx) { println(a == a); setState(a); })")
295 | '(Button .onPressed (fn [ctx] (do (println (= a a)) (setState a)))))))
296 | (testing "lambda with typed argument"
297 | (is (= (dart->clojure "Button(onPressed: (Context ctx) => 1 + 1;)")
298 | '(Button .onPressed (fn [ctx] (+ 1 1)))))))
299 |
300 | (deftest if-test
301 | (testing "one branch if with curly body"
302 | (is (= (dart->clojure "if (a == b) print('a');")
303 | '(when (= a b) (print "a")))))
304 | (testing "if else with and without body"
305 | (is (= (dart->clojure "if (b) { print(1); return 3; } else return 2;")
306 | '(if b (do (print 1) 3) 2))))
307 | (testing "if and else-if"
308 | (is (= (dart->clojure "if (b) b; else if (a) a; else if (c) c;")
309 | '(cond b b a a c c))))
310 | (testing "if, and else-if, and else"
311 | (is (= (dart->clojure "if (b) b; else if (a) a; else c;")
312 | '(cond b b a a :else c)))))
313 |
314 | (deftest switch-test
315 | (testing "idiomatic switch with default"
316 | (is (= (dart->clojure
317 | "switch(grade) {
318 | case 'A': return 'Great!';
319 |
320 | case 'B': { print('Good'); }
321 | break;
322 |
323 | case 'C':
324 | case 'D': { print('Bad'); }
325 | break;
326 |
327 | default: print('Invalid choice');
328 | break;
329 | }")
330 | '(case grade
331 | "A" "Great!"
332 | "B" (print "Good")
333 | "C" (print "Bad")
334 | "D" (print "Bad")
335 | (print "Invalid choice")))))
336 | (testing "idiomatic switch"
337 | (is (= (dart->clojure
338 | "switch (x) {
339 | case 1: return 1;
340 | case 2: return 2;
341 | }")
342 | '(case x 1 1 2 2))))
343 | (testing "unidiomatic cases"
344 | (is (= (dart->clojure
345 | "switch (x) {
346 | case 42: print('hello');
347 | continue world;
348 | case 37: print('goodbye');
349 | break;
350 | world:
351 | case 87: print('world');
352 | }")
353 | :unidiomatic))))
354 |
355 | (deftest try-test
356 | (is (= (dart->clojure
357 | "try {
358 | breedMoreLlamas();
359 | } on Lib.OutOfLlamasException {
360 | buyMoreLlamas();
361 | } on Exception catch (e) {
362 | print('Unknown exception: $e');
363 | } catch (e) {
364 | print('Something really unknown: $e');
365 | } finally {
366 | cleanLlamaStalls();
367 | }")
368 | '(try
369 | (breedMoreLlamas)
370 | (catch Lib.OutOfLlamasException e (buyMoreLlamas))
371 | (catch Exception e (print (str "Unknown exception: " e)))
372 | (catch Exception e (print (str "Something really unknown: " e)))
373 | (finally (cleanLlamaStalls))))))
374 |
375 | (deftest comments-test
376 | (testing "line comment"
377 | (is (= (dart->clojure "Text(
378 | 'name', // comment
379 | )")
380 | '(Text "name"))))
381 | (testing "block comment"
382 | (is (= (dart->clojure "Text(widget.photo.user!.name /* comment */ )")
383 | '(Text (-> widget .-photo .-user .-name)))))
384 | (testing "comment-like structure inside string"
385 | (is (= (dart->clojure "Text(
386 | 'http://looks-like-comment',
387 | '/* one more */'
388 | )")
389 | '(Text "http://looks-like-comment" "/* one more */")))))
390 |
391 | (deftest strings-test
392 | (testing "special symbols inside string test"
393 | (is
394 | (= (->> "''' cat's name \"bob\" '''"
395 | clean
396 | dart->clojure
397 | )
398 | " cat's name \"bob\" ")))
399 | (testing "special symbols inside string test"
400 | (is
401 | (= 1
402 | (->> "'\n\t\\s\"'"
403 | clean
404 | (insta/parses widget-parser)
405 | count))))
406 | (testing "multiline string with inner comments"
407 | (is
408 | (= 1
409 | (->>
410 | "\"\"\"
411 | multiline // comment like
412 | \" some string inside multiline string \"
413 | /* another comment */ \"\"\""
414 | clean
415 | (insta/parses widget-parser)
416 | count))))
417 | (testing "$ substitution"
418 | (is (= (dart->clojure "Text('Some $field and ${Factory.create()}')")
419 | '(Text (str "Some " field " and " (.create Factory))))))
420 | (testing "ignore $-substitution on raw sting"
421 | (is (= (dart->clojure "Text(r\"Some $field and ${Factory.create()}\")")
422 | '(Text "Some $field and ${Factory.create()}")))))
423 |
424 | (deftest assignment-test
425 | (testing "typeless var assignment"
426 | (is (= (dart->clojure "var a = b;") '(def a b))))
427 | (testing "final assignment"
428 | (is (= (dart->clojure "final String s = '1'; ") '(def s "1"))))
429 | (testing "const assignment"
430 | (is (= (dart->clj-string "const bar = 100;")
431 | "(def ^:const bar 100)")))
432 | (testing "assign value with type with dot"
433 | (is (= (dart->clojure "A.C bar = 1;") '(def bar 1)))))
434 |
435 | (deftest var-declaration-test
436 | (let [code "var bar = 0;
437 | const bar = 1;
438 | static bar = 2;
439 | static final bar = 3;
440 | static const int bar = 4;
441 | static final int bar = 5;
442 | static final int bar = 6, lar;"
443 | result '((def bar 0)
444 | (def bar 1)
445 | (def bar 2)
446 | (def bar 3)
447 | (def bar 4)
448 | (def bar 5)
449 | (do (def bar 6) (def lar nil)))]
450 | (testing "lambda vars"
451 | (is (= (dart->clj-simplified (str "() { " code " }"))
452 | (cons 'fn `( [] ~@result)))))
453 | (testing "method vars"
454 | (is (= (dart->clj-simplified (str "void main() { " code " }"))
455 | (list* 'defn 'main `([] ~@result)))))
456 | (testing "class vars"
457 | (is (= (drop 2 (dart->clj-simplified (str "class A { " code " }")))
458 | result)))
459 | (testing "global vars"
460 | (is (= (next (dart->clj-simplified code))
461 | result)))))
462 |
463 | (deftest await-test
464 | (is (= (dart->clojure "await a") '(await a)))
465 | (is (= (dart->clojure "await db.collection('todos').get();")
466 | '(await (-> db (.collection "todos") .get)))))
467 |
468 | (deftest statement-test
469 | (testing "several expressions | statements in a row with | without ';'"
470 | (is (= (dart->clojure "a = 2;
471 | if (item.isLoading) {
472 | print(1)
473 | }
474 | a")
475 | '(do :unidiomatic (when (.-isLoading item) (print 1)) a)))))
476 |
477 | (deftest return-test
478 | (is (= (-> "if (a) return;" dart->clojure) '(when a nil))))
479 |
480 | (deftest annotaions-test
481 | (is (= (-> "@Foo(42)
482 | class Foo {
483 |
484 | @Deprecated('until further notice');
485 | final int x;
486 |
487 | @FOO
488 | const Foo(this.x);
489 |
490 | @override
491 | void main() {
492 | print(a);
493 | }
494 | }
495 |
496 | @JsonKey(fromJson: _variableFromJson)
497 | enum FieldType {
498 | @JsonEnum('Text') text,
499 | @JsonEnum('Number') number
500 | }"
501 | dart->clojure)
502 | '(do
503 | (comment
504 | "use flutter/widget macro instead of classes"
505 | (def x nil)
506 | (defn main [] (print a)))
507 | :unknown))))
508 |
509 | (deftest flatten-same-operators
510 | #?(:clj ; TODO: How to do this in ClojureScript?
511 | (testing "calculation results"
512 | (is (-> "(2 + 1 + 1 == 4 && true) && (1 == 1 || false) && 3 == 3"
513 | dart->clj-string
514 | read-string
515 | eval))))
516 | (testing "+, *, and, or"
517 | (doseq [sym ["+" "*" "||" "&&"]]
518 | (is (= (-> (str 1 sym 2 sym 3 sym 4 sym 5) dart->clojure)
519 | `(~(symbol (case sym "||" 'or, "&&" 'and sym)) 1 2 3 4 5)))))
520 | (testing "flatten compare operators when possible"
521 | (is (= (-> "1 < 2 && 2 < 3" dart->clojure)
522 | '(< 1 2 3)))
523 | (is (= (-> "3 > 2 && 2 > 1 && 4 > 3 && true" dart->clj-string)
524 | "(and true (> 4 3 2 1))"))
525 | (is (#{'(and (>= 4 3) (or (>= 3 2) (>= 2 1)))
526 | '(and (or (>= 3 2) (>= 2 1)) (>= 4 3))}
527 | (-> "4 >= 3 && 3 >= 2 || 2 >= 1" dart->clojure)))
528 | (is (= (-> "5 >= 4 && 4 >= 3 && 3 >= 2 || 2 >= 1" dart->clojure)
529 | '(and (or (>= 3 2) (>= 2 1)) (>= 5 4 3))))
530 |
531 |
532 | (is (= (-> "a > b || (c > d && d > e && e < f)" dart->clojure)
533 | '(or (> a b) (and (> f e) (> c d e)))))
534 | (is (= (-> "a > b || (c > d && d > e && f < e)" dart->clojure)
535 | '(or (> a b) (> c d e f))))
536 | (is (= (-> "(c <= b && a >= b) || (c > d && d > e && f < e)" dart->clojure)
537 | '(or (>= a b c) (> c d e f))))))
538 |
539 | #_(dart->clojure "4 >= 3 && 3 >= 2 || 2 >= 1")
540 |
--------------------------------------------------------------------------------
/npm-test-app/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "npm-test-app",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "npm-test-app",
9 | "version": "1.0.0",
10 | "license": "MIT",
11 | "dependencies": {
12 | "dartclojure": "file:.."
13 | },
14 | "devDependencies": {
15 | "http-server": "^14.1.1",
16 | "shadow-cljs": "^2.19.3"
17 | }
18 | },
19 | "..": {
20 | "name": "dartclojure",
21 | "version": "0.2.6",
22 | "license": "Apache License, Version 2.0",
23 | "bin": {
24 | "dartclojure": "target/npm-app/index.js"
25 | },
26 | "devDependencies": {
27 | "rimraf": "3.0.2",
28 | "shadow-cljs": "^2.19.3"
29 | }
30 | },
31 | "node_modules/asn1.js": {
32 | "version": "5.4.1",
33 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
34 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
35 | "dev": true,
36 | "dependencies": {
37 | "bn.js": "^4.0.0",
38 | "inherits": "^2.0.1",
39 | "minimalistic-assert": "^1.0.0",
40 | "safer-buffer": "^2.1.0"
41 | }
42 | },
43 | "node_modules/asn1.js/node_modules/bn.js": {
44 | "version": "4.12.0",
45 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
46 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
47 | "dev": true
48 | },
49 | "node_modules/assert": {
50 | "version": "1.5.0",
51 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
52 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
53 | "dev": true,
54 | "dependencies": {
55 | "object-assign": "^4.1.1",
56 | "util": "0.10.3"
57 | }
58 | },
59 | "node_modules/assert/node_modules/inherits": {
60 | "version": "2.0.1",
61 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
62 | "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==",
63 | "dev": true
64 | },
65 | "node_modules/assert/node_modules/util": {
66 | "version": "0.10.3",
67 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
68 | "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==",
69 | "dev": true,
70 | "dependencies": {
71 | "inherits": "2.0.1"
72 | }
73 | },
74 | "node_modules/async": {
75 | "version": "2.6.4",
76 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
77 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
78 | "dev": true,
79 | "dependencies": {
80 | "lodash": "^4.17.14"
81 | }
82 | },
83 | "node_modules/base64-js": {
84 | "version": "1.5.1",
85 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
86 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
87 | "dev": true,
88 | "funding": [
89 | {
90 | "type": "github",
91 | "url": "https://github.com/sponsors/feross"
92 | },
93 | {
94 | "type": "patreon",
95 | "url": "https://www.patreon.com/feross"
96 | },
97 | {
98 | "type": "consulting",
99 | "url": "https://feross.org/support"
100 | }
101 | ]
102 | },
103 | "node_modules/basic-auth": {
104 | "version": "2.0.1",
105 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
106 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
107 | "dev": true,
108 | "dependencies": {
109 | "safe-buffer": "5.1.2"
110 | },
111 | "engines": {
112 | "node": ">= 0.8"
113 | }
114 | },
115 | "node_modules/bn.js": {
116 | "version": "5.2.1",
117 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
118 | "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
119 | "dev": true
120 | },
121 | "node_modules/brorand": {
122 | "version": "1.1.0",
123 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
124 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
125 | "dev": true
126 | },
127 | "node_modules/browserify-aes": {
128 | "version": "1.2.0",
129 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
130 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
131 | "dev": true,
132 | "dependencies": {
133 | "buffer-xor": "^1.0.3",
134 | "cipher-base": "^1.0.0",
135 | "create-hash": "^1.1.0",
136 | "evp_bytestokey": "^1.0.3",
137 | "inherits": "^2.0.1",
138 | "safe-buffer": "^5.0.1"
139 | }
140 | },
141 | "node_modules/browserify-cipher": {
142 | "version": "1.0.1",
143 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
144 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
145 | "dev": true,
146 | "dependencies": {
147 | "browserify-aes": "^1.0.4",
148 | "browserify-des": "^1.0.0",
149 | "evp_bytestokey": "^1.0.0"
150 | }
151 | },
152 | "node_modules/browserify-des": {
153 | "version": "1.0.2",
154 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
155 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
156 | "dev": true,
157 | "dependencies": {
158 | "cipher-base": "^1.0.1",
159 | "des.js": "^1.0.0",
160 | "inherits": "^2.0.1",
161 | "safe-buffer": "^5.1.2"
162 | }
163 | },
164 | "node_modules/browserify-rsa": {
165 | "version": "4.1.0",
166 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
167 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
168 | "dev": true,
169 | "dependencies": {
170 | "bn.js": "^5.0.0",
171 | "randombytes": "^2.0.1"
172 | }
173 | },
174 | "node_modules/browserify-sign": {
175 | "version": "4.2.1",
176 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
177 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
178 | "dev": true,
179 | "dependencies": {
180 | "bn.js": "^5.1.1",
181 | "browserify-rsa": "^4.0.1",
182 | "create-hash": "^1.2.0",
183 | "create-hmac": "^1.1.7",
184 | "elliptic": "^6.5.3",
185 | "inherits": "^2.0.4",
186 | "parse-asn1": "^5.1.5",
187 | "readable-stream": "^3.6.0",
188 | "safe-buffer": "^5.2.0"
189 | }
190 | },
191 | "node_modules/browserify-sign/node_modules/readable-stream": {
192 | "version": "3.6.0",
193 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
194 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
195 | "dev": true,
196 | "dependencies": {
197 | "inherits": "^2.0.3",
198 | "string_decoder": "^1.1.1",
199 | "util-deprecate": "^1.0.1"
200 | },
201 | "engines": {
202 | "node": ">= 6"
203 | }
204 | },
205 | "node_modules/browserify-sign/node_modules/safe-buffer": {
206 | "version": "5.2.1",
207 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
208 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
209 | "dev": true,
210 | "funding": [
211 | {
212 | "type": "github",
213 | "url": "https://github.com/sponsors/feross"
214 | },
215 | {
216 | "type": "patreon",
217 | "url": "https://www.patreon.com/feross"
218 | },
219 | {
220 | "type": "consulting",
221 | "url": "https://feross.org/support"
222 | }
223 | ]
224 | },
225 | "node_modules/browserify-zlib": {
226 | "version": "0.2.0",
227 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
228 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
229 | "dev": true,
230 | "dependencies": {
231 | "pako": "~1.0.5"
232 | }
233 | },
234 | "node_modules/buffer": {
235 | "version": "4.9.2",
236 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
237 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
238 | "dev": true,
239 | "dependencies": {
240 | "base64-js": "^1.0.2",
241 | "ieee754": "^1.1.4",
242 | "isarray": "^1.0.0"
243 | }
244 | },
245 | "node_modules/buffer-xor": {
246 | "version": "1.0.3",
247 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
248 | "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
249 | "dev": true
250 | },
251 | "node_modules/builtin-status-codes": {
252 | "version": "3.0.0",
253 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
254 | "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
255 | "dev": true
256 | },
257 | "node_modules/call-bind": {
258 | "version": "1.0.2",
259 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
260 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
261 | "dev": true,
262 | "dependencies": {
263 | "function-bind": "^1.1.1",
264 | "get-intrinsic": "^1.0.2"
265 | },
266 | "funding": {
267 | "url": "https://github.com/sponsors/ljharb"
268 | }
269 | },
270 | "node_modules/cipher-base": {
271 | "version": "1.0.4",
272 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
273 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
274 | "dev": true,
275 | "dependencies": {
276 | "inherits": "^2.0.1",
277 | "safe-buffer": "^5.0.1"
278 | }
279 | },
280 | "node_modules/color-convert": {
281 | "version": "2.0.1",
282 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
283 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
284 | "dev": true,
285 | "dependencies": {
286 | "color-name": "~1.1.4"
287 | },
288 | "engines": {
289 | "node": ">=7.0.0"
290 | }
291 | },
292 | "node_modules/color-name": {
293 | "version": "1.1.4",
294 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
295 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
296 | "dev": true
297 | },
298 | "node_modules/console-browserify": {
299 | "version": "1.2.0",
300 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
301 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
302 | "dev": true
303 | },
304 | "node_modules/constants-browserify": {
305 | "version": "1.0.0",
306 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
307 | "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
308 | "dev": true
309 | },
310 | "node_modules/core-util-is": {
311 | "version": "1.0.3",
312 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
313 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
314 | "dev": true
315 | },
316 | "node_modules/corser": {
317 | "version": "2.0.1",
318 | "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
319 | "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
320 | "dev": true,
321 | "engines": {
322 | "node": ">= 0.4.0"
323 | }
324 | },
325 | "node_modules/create-ecdh": {
326 | "version": "4.0.4",
327 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
328 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
329 | "dev": true,
330 | "dependencies": {
331 | "bn.js": "^4.1.0",
332 | "elliptic": "^6.5.3"
333 | }
334 | },
335 | "node_modules/create-ecdh/node_modules/bn.js": {
336 | "version": "4.12.0",
337 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
338 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
339 | "dev": true
340 | },
341 | "node_modules/create-hash": {
342 | "version": "1.2.0",
343 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
344 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
345 | "dev": true,
346 | "dependencies": {
347 | "cipher-base": "^1.0.1",
348 | "inherits": "^2.0.1",
349 | "md5.js": "^1.3.4",
350 | "ripemd160": "^2.0.1",
351 | "sha.js": "^2.4.0"
352 | }
353 | },
354 | "node_modules/create-hmac": {
355 | "version": "1.1.7",
356 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
357 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
358 | "dev": true,
359 | "dependencies": {
360 | "cipher-base": "^1.0.3",
361 | "create-hash": "^1.1.0",
362 | "inherits": "^2.0.1",
363 | "ripemd160": "^2.0.0",
364 | "safe-buffer": "^5.0.1",
365 | "sha.js": "^2.4.8"
366 | }
367 | },
368 | "node_modules/crypto-browserify": {
369 | "version": "3.12.0",
370 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
371 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
372 | "dev": true,
373 | "dependencies": {
374 | "browserify-cipher": "^1.0.0",
375 | "browserify-sign": "^4.0.0",
376 | "create-ecdh": "^4.0.0",
377 | "create-hash": "^1.1.0",
378 | "create-hmac": "^1.1.0",
379 | "diffie-hellman": "^5.0.0",
380 | "inherits": "^2.0.1",
381 | "pbkdf2": "^3.0.3",
382 | "public-encrypt": "^4.0.0",
383 | "randombytes": "^2.0.0",
384 | "randomfill": "^1.0.3"
385 | },
386 | "engines": {
387 | "node": "*"
388 | }
389 | },
390 | "node_modules/dartclojure": {
391 | "resolved": "..",
392 | "link": true
393 | },
394 | "node_modules/des.js": {
395 | "version": "1.0.1",
396 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
397 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
398 | "dev": true,
399 | "dependencies": {
400 | "inherits": "^2.0.1",
401 | "minimalistic-assert": "^1.0.0"
402 | }
403 | },
404 | "node_modules/diffie-hellman": {
405 | "version": "5.0.3",
406 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
407 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
408 | "dev": true,
409 | "dependencies": {
410 | "bn.js": "^4.1.0",
411 | "miller-rabin": "^4.0.0",
412 | "randombytes": "^2.0.0"
413 | }
414 | },
415 | "node_modules/diffie-hellman/node_modules/bn.js": {
416 | "version": "4.12.0",
417 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
418 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
419 | "dev": true
420 | },
421 | "node_modules/domain-browser": {
422 | "version": "1.2.0",
423 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
424 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
425 | "dev": true,
426 | "engines": {
427 | "node": ">=0.4",
428 | "npm": ">=1.2"
429 | }
430 | },
431 | "node_modules/elliptic": {
432 | "version": "6.5.4",
433 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
434 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
435 | "dev": true,
436 | "dependencies": {
437 | "bn.js": "^4.11.9",
438 | "brorand": "^1.1.0",
439 | "hash.js": "^1.0.0",
440 | "hmac-drbg": "^1.0.1",
441 | "inherits": "^2.0.4",
442 | "minimalistic-assert": "^1.0.1",
443 | "minimalistic-crypto-utils": "^1.0.1"
444 | }
445 | },
446 | "node_modules/elliptic/node_modules/bn.js": {
447 | "version": "4.12.0",
448 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
449 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
450 | "dev": true
451 | },
452 | "node_modules/eventemitter3": {
453 | "version": "4.0.7",
454 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
455 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
456 | "dev": true
457 | },
458 | "node_modules/events": {
459 | "version": "3.3.0",
460 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
461 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
462 | "dev": true,
463 | "engines": {
464 | "node": ">=0.8.x"
465 | }
466 | },
467 | "node_modules/evp_bytestokey": {
468 | "version": "1.0.3",
469 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
470 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
471 | "dev": true,
472 | "dependencies": {
473 | "md5.js": "^1.3.4",
474 | "safe-buffer": "^5.1.1"
475 | }
476 | },
477 | "node_modules/follow-redirects": {
478 | "version": "1.15.1",
479 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
480 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
481 | "dev": true,
482 | "funding": [
483 | {
484 | "type": "individual",
485 | "url": "https://github.com/sponsors/RubenVerborgh"
486 | }
487 | ],
488 | "engines": {
489 | "node": ">=4.0"
490 | },
491 | "peerDependenciesMeta": {
492 | "debug": {
493 | "optional": true
494 | }
495 | }
496 | },
497 | "node_modules/function-bind": {
498 | "version": "1.1.1",
499 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
500 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
501 | "dev": true
502 | },
503 | "node_modules/get-intrinsic": {
504 | "version": "1.1.2",
505 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
506 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
507 | "dev": true,
508 | "dependencies": {
509 | "function-bind": "^1.1.1",
510 | "has": "^1.0.3",
511 | "has-symbols": "^1.0.3"
512 | },
513 | "funding": {
514 | "url": "https://github.com/sponsors/ljharb"
515 | }
516 | },
517 | "node_modules/has": {
518 | "version": "1.0.3",
519 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
520 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
521 | "dev": true,
522 | "dependencies": {
523 | "function-bind": "^1.1.1"
524 | },
525 | "engines": {
526 | "node": ">= 0.4.0"
527 | }
528 | },
529 | "node_modules/has-flag": {
530 | "version": "4.0.0",
531 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
532 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
533 | "dev": true,
534 | "engines": {
535 | "node": ">=8"
536 | }
537 | },
538 | "node_modules/has-symbols": {
539 | "version": "1.0.3",
540 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
541 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
542 | "dev": true,
543 | "engines": {
544 | "node": ">= 0.4"
545 | },
546 | "funding": {
547 | "url": "https://github.com/sponsors/ljharb"
548 | }
549 | },
550 | "node_modules/hash-base": {
551 | "version": "3.1.0",
552 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
553 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
554 | "dev": true,
555 | "dependencies": {
556 | "inherits": "^2.0.4",
557 | "readable-stream": "^3.6.0",
558 | "safe-buffer": "^5.2.0"
559 | },
560 | "engines": {
561 | "node": ">=4"
562 | }
563 | },
564 | "node_modules/hash-base/node_modules/readable-stream": {
565 | "version": "3.6.0",
566 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
567 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
568 | "dev": true,
569 | "dependencies": {
570 | "inherits": "^2.0.3",
571 | "string_decoder": "^1.1.1",
572 | "util-deprecate": "^1.0.1"
573 | },
574 | "engines": {
575 | "node": ">= 6"
576 | }
577 | },
578 | "node_modules/hash-base/node_modules/safe-buffer": {
579 | "version": "5.2.1",
580 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
581 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
582 | "dev": true,
583 | "funding": [
584 | {
585 | "type": "github",
586 | "url": "https://github.com/sponsors/feross"
587 | },
588 | {
589 | "type": "patreon",
590 | "url": "https://www.patreon.com/feross"
591 | },
592 | {
593 | "type": "consulting",
594 | "url": "https://feross.org/support"
595 | }
596 | ]
597 | },
598 | "node_modules/hash.js": {
599 | "version": "1.1.7",
600 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
601 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
602 | "dev": true,
603 | "dependencies": {
604 | "inherits": "^2.0.3",
605 | "minimalistic-assert": "^1.0.1"
606 | }
607 | },
608 | "node_modules/he": {
609 | "version": "1.2.0",
610 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
611 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
612 | "dev": true,
613 | "bin": {
614 | "he": "bin/he"
615 | }
616 | },
617 | "node_modules/hmac-drbg": {
618 | "version": "1.0.1",
619 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
620 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
621 | "dev": true,
622 | "dependencies": {
623 | "hash.js": "^1.0.3",
624 | "minimalistic-assert": "^1.0.0",
625 | "minimalistic-crypto-utils": "^1.0.1"
626 | }
627 | },
628 | "node_modules/html-encoding-sniffer": {
629 | "version": "3.0.0",
630 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
631 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
632 | "dev": true,
633 | "dependencies": {
634 | "whatwg-encoding": "^2.0.0"
635 | },
636 | "engines": {
637 | "node": ">=12"
638 | }
639 | },
640 | "node_modules/http-proxy": {
641 | "version": "1.18.1",
642 | "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
643 | "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
644 | "dev": true,
645 | "dependencies": {
646 | "eventemitter3": "^4.0.0",
647 | "follow-redirects": "^1.0.0",
648 | "requires-port": "^1.0.0"
649 | },
650 | "engines": {
651 | "node": ">=8.0.0"
652 | }
653 | },
654 | "node_modules/http-server": {
655 | "version": "14.1.1",
656 | "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
657 | "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
658 | "dev": true,
659 | "dependencies": {
660 | "basic-auth": "^2.0.1",
661 | "chalk": "^4.1.2",
662 | "corser": "^2.0.1",
663 | "he": "^1.2.0",
664 | "html-encoding-sniffer": "^3.0.0",
665 | "http-proxy": "^1.18.1",
666 | "mime": "^1.6.0",
667 | "minimist": "^1.2.6",
668 | "opener": "^1.5.1",
669 | "portfinder": "^1.0.28",
670 | "secure-compare": "3.0.1",
671 | "union": "~0.5.0",
672 | "url-join": "^4.0.1"
673 | },
674 | "bin": {
675 | "http-server": "bin/http-server"
676 | },
677 | "engines": {
678 | "node": ">=12"
679 | }
680 | },
681 | "node_modules/http-server/node_modules/ansi-styles": {
682 | "version": "4.3.0",
683 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
684 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
685 | "dev": true,
686 | "dependencies": {
687 | "color-convert": "^2.0.1"
688 | },
689 | "engines": {
690 | "node": ">=8"
691 | },
692 | "funding": {
693 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
694 | }
695 | },
696 | "node_modules/http-server/node_modules/chalk": {
697 | "version": "4.1.2",
698 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
699 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
700 | "dev": true,
701 | "dependencies": {
702 | "ansi-styles": "^4.1.0",
703 | "supports-color": "^7.1.0"
704 | },
705 | "engines": {
706 | "node": ">=10"
707 | },
708 | "funding": {
709 | "url": "https://github.com/chalk/chalk?sponsor=1"
710 | }
711 | },
712 | "node_modules/http-server/node_modules/supports-color": {
713 | "version": "7.2.0",
714 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
715 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
716 | "dev": true,
717 | "dependencies": {
718 | "has-flag": "^4.0.0"
719 | },
720 | "engines": {
721 | "node": ">=8"
722 | }
723 | },
724 | "node_modules/https-browserify": {
725 | "version": "1.0.0",
726 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
727 | "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
728 | "dev": true
729 | },
730 | "node_modules/iconv-lite": {
731 | "version": "0.6.3",
732 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
733 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
734 | "dev": true,
735 | "dependencies": {
736 | "safer-buffer": ">= 2.1.2 < 3.0.0"
737 | },
738 | "engines": {
739 | "node": ">=0.10.0"
740 | }
741 | },
742 | "node_modules/ieee754": {
743 | "version": "1.2.1",
744 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
745 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
746 | "dev": true,
747 | "funding": [
748 | {
749 | "type": "github",
750 | "url": "https://github.com/sponsors/feross"
751 | },
752 | {
753 | "type": "patreon",
754 | "url": "https://www.patreon.com/feross"
755 | },
756 | {
757 | "type": "consulting",
758 | "url": "https://feross.org/support"
759 | }
760 | ]
761 | },
762 | "node_modules/inherits": {
763 | "version": "2.0.4",
764 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
765 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
766 | "dev": true
767 | },
768 | "node_modules/isarray": {
769 | "version": "1.0.0",
770 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
771 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
772 | "dev": true
773 | },
774 | "node_modules/isexe": {
775 | "version": "2.0.0",
776 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
777 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
778 | "dev": true
779 | },
780 | "node_modules/lodash": {
781 | "version": "4.17.21",
782 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
783 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
784 | "dev": true
785 | },
786 | "node_modules/md5.js": {
787 | "version": "1.3.5",
788 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
789 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
790 | "dev": true,
791 | "dependencies": {
792 | "hash-base": "^3.0.0",
793 | "inherits": "^2.0.1",
794 | "safe-buffer": "^5.1.2"
795 | }
796 | },
797 | "node_modules/miller-rabin": {
798 | "version": "4.0.1",
799 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
800 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
801 | "dev": true,
802 | "dependencies": {
803 | "bn.js": "^4.0.0",
804 | "brorand": "^1.0.1"
805 | },
806 | "bin": {
807 | "miller-rabin": "bin/miller-rabin"
808 | }
809 | },
810 | "node_modules/miller-rabin/node_modules/bn.js": {
811 | "version": "4.12.0",
812 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
813 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
814 | "dev": true
815 | },
816 | "node_modules/mime": {
817 | "version": "1.6.0",
818 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
819 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
820 | "dev": true,
821 | "bin": {
822 | "mime": "cli.js"
823 | },
824 | "engines": {
825 | "node": ">=4"
826 | }
827 | },
828 | "node_modules/minimalistic-assert": {
829 | "version": "1.0.1",
830 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
831 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
832 | "dev": true
833 | },
834 | "node_modules/minimalistic-crypto-utils": {
835 | "version": "1.0.1",
836 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
837 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
838 | "dev": true
839 | },
840 | "node_modules/minimist": {
841 | "version": "1.2.6",
842 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
843 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
844 | "dev": true
845 | },
846 | "node_modules/mkdirp": {
847 | "version": "0.5.6",
848 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
849 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
850 | "dev": true,
851 | "dependencies": {
852 | "minimist": "^1.2.6"
853 | },
854 | "bin": {
855 | "mkdirp": "bin/cmd.js"
856 | }
857 | },
858 | "node_modules/node-libs-browser": {
859 | "version": "2.2.1",
860 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
861 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
862 | "dev": true,
863 | "dependencies": {
864 | "assert": "^1.1.1",
865 | "browserify-zlib": "^0.2.0",
866 | "buffer": "^4.3.0",
867 | "console-browserify": "^1.1.0",
868 | "constants-browserify": "^1.0.0",
869 | "crypto-browserify": "^3.11.0",
870 | "domain-browser": "^1.1.1",
871 | "events": "^3.0.0",
872 | "https-browserify": "^1.0.0",
873 | "os-browserify": "^0.3.0",
874 | "path-browserify": "0.0.1",
875 | "process": "^0.11.10",
876 | "punycode": "^1.2.4",
877 | "querystring-es3": "^0.2.0",
878 | "readable-stream": "^2.3.3",
879 | "stream-browserify": "^2.0.1",
880 | "stream-http": "^2.7.2",
881 | "string_decoder": "^1.0.0",
882 | "timers-browserify": "^2.0.4",
883 | "tty-browserify": "0.0.0",
884 | "url": "^0.11.0",
885 | "util": "^0.11.0",
886 | "vm-browserify": "^1.0.1"
887 | }
888 | },
889 | "node_modules/object-assign": {
890 | "version": "4.1.1",
891 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
892 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
893 | "dev": true,
894 | "engines": {
895 | "node": ">=0.10.0"
896 | }
897 | },
898 | "node_modules/object-inspect": {
899 | "version": "1.12.2",
900 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
901 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
902 | "dev": true,
903 | "funding": {
904 | "url": "https://github.com/sponsors/ljharb"
905 | }
906 | },
907 | "node_modules/opener": {
908 | "version": "1.5.2",
909 | "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
910 | "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
911 | "dev": true,
912 | "bin": {
913 | "opener": "bin/opener-bin.js"
914 | }
915 | },
916 | "node_modules/os-browserify": {
917 | "version": "0.3.0",
918 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
919 | "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
920 | "dev": true
921 | },
922 | "node_modules/pako": {
923 | "version": "1.0.11",
924 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
925 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
926 | "dev": true
927 | },
928 | "node_modules/parse-asn1": {
929 | "version": "5.1.6",
930 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
931 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
932 | "dev": true,
933 | "dependencies": {
934 | "asn1.js": "^5.2.0",
935 | "browserify-aes": "^1.0.0",
936 | "evp_bytestokey": "^1.0.0",
937 | "pbkdf2": "^3.0.3",
938 | "safe-buffer": "^5.1.1"
939 | }
940 | },
941 | "node_modules/path-browserify": {
942 | "version": "0.0.1",
943 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
944 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
945 | "dev": true
946 | },
947 | "node_modules/pbkdf2": {
948 | "version": "3.1.2",
949 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
950 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
951 | "dev": true,
952 | "dependencies": {
953 | "create-hash": "^1.1.2",
954 | "create-hmac": "^1.1.4",
955 | "ripemd160": "^2.0.1",
956 | "safe-buffer": "^5.0.1",
957 | "sha.js": "^2.4.8"
958 | },
959 | "engines": {
960 | "node": ">=0.12"
961 | }
962 | },
963 | "node_modules/portfinder": {
964 | "version": "1.0.28",
965 | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
966 | "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
967 | "dev": true,
968 | "dependencies": {
969 | "async": "^2.6.2",
970 | "debug": "^3.1.1",
971 | "mkdirp": "^0.5.5"
972 | },
973 | "engines": {
974 | "node": ">= 0.12.0"
975 | }
976 | },
977 | "node_modules/portfinder/node_modules/debug": {
978 | "version": "3.2.7",
979 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
980 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
981 | "dev": true,
982 | "dependencies": {
983 | "ms": "^2.1.1"
984 | }
985 | },
986 | "node_modules/portfinder/node_modules/ms": {
987 | "version": "2.1.3",
988 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
989 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
990 | "dev": true
991 | },
992 | "node_modules/process": {
993 | "version": "0.11.10",
994 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
995 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
996 | "dev": true,
997 | "engines": {
998 | "node": ">= 0.6.0"
999 | }
1000 | },
1001 | "node_modules/process-nextick-args": {
1002 | "version": "2.0.1",
1003 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1004 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
1005 | "dev": true
1006 | },
1007 | "node_modules/public-encrypt": {
1008 | "version": "4.0.3",
1009 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
1010 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
1011 | "dev": true,
1012 | "dependencies": {
1013 | "bn.js": "^4.1.0",
1014 | "browserify-rsa": "^4.0.0",
1015 | "create-hash": "^1.1.0",
1016 | "parse-asn1": "^5.0.0",
1017 | "randombytes": "^2.0.1",
1018 | "safe-buffer": "^5.1.2"
1019 | }
1020 | },
1021 | "node_modules/public-encrypt/node_modules/bn.js": {
1022 | "version": "4.12.0",
1023 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1024 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1025 | "dev": true
1026 | },
1027 | "node_modules/punycode": {
1028 | "version": "1.4.1",
1029 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
1030 | "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
1031 | "dev": true
1032 | },
1033 | "node_modules/qs": {
1034 | "version": "6.10.5",
1035 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
1036 | "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
1037 | "dev": true,
1038 | "dependencies": {
1039 | "side-channel": "^1.0.4"
1040 | },
1041 | "engines": {
1042 | "node": ">=0.6"
1043 | },
1044 | "funding": {
1045 | "url": "https://github.com/sponsors/ljharb"
1046 | }
1047 | },
1048 | "node_modules/querystring": {
1049 | "version": "0.2.0",
1050 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
1051 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
1052 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
1053 | "dev": true,
1054 | "engines": {
1055 | "node": ">=0.4.x"
1056 | }
1057 | },
1058 | "node_modules/querystring-es3": {
1059 | "version": "0.2.1",
1060 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
1061 | "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
1062 | "dev": true,
1063 | "engines": {
1064 | "node": ">=0.4.x"
1065 | }
1066 | },
1067 | "node_modules/randombytes": {
1068 | "version": "2.1.0",
1069 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
1070 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
1071 | "dev": true,
1072 | "dependencies": {
1073 | "safe-buffer": "^5.1.0"
1074 | }
1075 | },
1076 | "node_modules/randomfill": {
1077 | "version": "1.0.4",
1078 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
1079 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
1080 | "dev": true,
1081 | "dependencies": {
1082 | "randombytes": "^2.0.5",
1083 | "safe-buffer": "^5.1.0"
1084 | }
1085 | },
1086 | "node_modules/readable-stream": {
1087 | "version": "2.3.7",
1088 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
1089 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
1090 | "dev": true,
1091 | "dependencies": {
1092 | "core-util-is": "~1.0.0",
1093 | "inherits": "~2.0.3",
1094 | "isarray": "~1.0.0",
1095 | "process-nextick-args": "~2.0.0",
1096 | "safe-buffer": "~5.1.1",
1097 | "string_decoder": "~1.1.1",
1098 | "util-deprecate": "~1.0.1"
1099 | }
1100 | },
1101 | "node_modules/readline-sync": {
1102 | "version": "1.4.10",
1103 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
1104 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
1105 | "dev": true,
1106 | "engines": {
1107 | "node": ">= 0.8.0"
1108 | }
1109 | },
1110 | "node_modules/requires-port": {
1111 | "version": "1.0.0",
1112 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
1113 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
1114 | "dev": true
1115 | },
1116 | "node_modules/ripemd160": {
1117 | "version": "2.0.2",
1118 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
1119 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
1120 | "dev": true,
1121 | "dependencies": {
1122 | "hash-base": "^3.0.0",
1123 | "inherits": "^2.0.1"
1124 | }
1125 | },
1126 | "node_modules/safe-buffer": {
1127 | "version": "5.1.2",
1128 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1129 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1130 | "dev": true
1131 | },
1132 | "node_modules/safer-buffer": {
1133 | "version": "2.1.2",
1134 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1135 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1136 | "dev": true
1137 | },
1138 | "node_modules/secure-compare": {
1139 | "version": "3.0.1",
1140 | "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
1141 | "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
1142 | "dev": true
1143 | },
1144 | "node_modules/setimmediate": {
1145 | "version": "1.0.5",
1146 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
1147 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
1148 | "dev": true
1149 | },
1150 | "node_modules/sha.js": {
1151 | "version": "2.4.11",
1152 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
1153 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
1154 | "dev": true,
1155 | "dependencies": {
1156 | "inherits": "^2.0.1",
1157 | "safe-buffer": "^5.0.1"
1158 | },
1159 | "bin": {
1160 | "sha.js": "bin.js"
1161 | }
1162 | },
1163 | "node_modules/shadow-cljs": {
1164 | "version": "2.19.3",
1165 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.19.3.tgz",
1166 | "integrity": "sha512-9TsTCRlmR8m1g2ekwblgomRUgJpbifQI99VlRrlH9NMqEzklev3zYAD1dvy4d5h8BoAhgdxOOEg7ld2d45CWTA==",
1167 | "dev": true,
1168 | "dependencies": {
1169 | "node-libs-browser": "^2.2.1",
1170 | "readline-sync": "^1.4.7",
1171 | "shadow-cljs-jar": "1.3.2",
1172 | "source-map-support": "^0.4.15",
1173 | "which": "^1.3.1",
1174 | "ws": "^7.4.6"
1175 | },
1176 | "bin": {
1177 | "shadow-cljs": "cli/runner.js"
1178 | },
1179 | "engines": {
1180 | "node": ">=6.0.0"
1181 | }
1182 | },
1183 | "node_modules/shadow-cljs-jar": {
1184 | "version": "1.3.2",
1185 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz",
1186 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==",
1187 | "dev": true
1188 | },
1189 | "node_modules/side-channel": {
1190 | "version": "1.0.4",
1191 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1192 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1193 | "dev": true,
1194 | "dependencies": {
1195 | "call-bind": "^1.0.0",
1196 | "get-intrinsic": "^1.0.2",
1197 | "object-inspect": "^1.9.0"
1198 | },
1199 | "funding": {
1200 | "url": "https://github.com/sponsors/ljharb"
1201 | }
1202 | },
1203 | "node_modules/source-map": {
1204 | "version": "0.5.7",
1205 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1206 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
1207 | "dev": true,
1208 | "engines": {
1209 | "node": ">=0.10.0"
1210 | }
1211 | },
1212 | "node_modules/source-map-support": {
1213 | "version": "0.4.18",
1214 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
1215 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
1216 | "dev": true,
1217 | "dependencies": {
1218 | "source-map": "^0.5.6"
1219 | }
1220 | },
1221 | "node_modules/stream-browserify": {
1222 | "version": "2.0.2",
1223 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
1224 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
1225 | "dev": true,
1226 | "dependencies": {
1227 | "inherits": "~2.0.1",
1228 | "readable-stream": "^2.0.2"
1229 | }
1230 | },
1231 | "node_modules/stream-http": {
1232 | "version": "2.8.3",
1233 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
1234 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
1235 | "dev": true,
1236 | "dependencies": {
1237 | "builtin-status-codes": "^3.0.0",
1238 | "inherits": "^2.0.1",
1239 | "readable-stream": "^2.3.6",
1240 | "to-arraybuffer": "^1.0.0",
1241 | "xtend": "^4.0.0"
1242 | }
1243 | },
1244 | "node_modules/string_decoder": {
1245 | "version": "1.1.1",
1246 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1247 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1248 | "dev": true,
1249 | "dependencies": {
1250 | "safe-buffer": "~5.1.0"
1251 | }
1252 | },
1253 | "node_modules/timers-browserify": {
1254 | "version": "2.0.12",
1255 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
1256 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
1257 | "dev": true,
1258 | "dependencies": {
1259 | "setimmediate": "^1.0.4"
1260 | },
1261 | "engines": {
1262 | "node": ">=0.6.0"
1263 | }
1264 | },
1265 | "node_modules/to-arraybuffer": {
1266 | "version": "1.0.1",
1267 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
1268 | "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==",
1269 | "dev": true
1270 | },
1271 | "node_modules/tty-browserify": {
1272 | "version": "0.0.0",
1273 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
1274 | "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==",
1275 | "dev": true
1276 | },
1277 | "node_modules/union": {
1278 | "version": "0.5.0",
1279 | "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
1280 | "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
1281 | "dev": true,
1282 | "dependencies": {
1283 | "qs": "^6.4.0"
1284 | },
1285 | "engines": {
1286 | "node": ">= 0.8.0"
1287 | }
1288 | },
1289 | "node_modules/url": {
1290 | "version": "0.11.0",
1291 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
1292 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
1293 | "dev": true,
1294 | "dependencies": {
1295 | "punycode": "1.3.2",
1296 | "querystring": "0.2.0"
1297 | }
1298 | },
1299 | "node_modules/url-join": {
1300 | "version": "4.0.1",
1301 | "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
1302 | "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
1303 | "dev": true
1304 | },
1305 | "node_modules/url/node_modules/punycode": {
1306 | "version": "1.3.2",
1307 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
1308 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==",
1309 | "dev": true
1310 | },
1311 | "node_modules/util": {
1312 | "version": "0.11.1",
1313 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
1314 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
1315 | "dev": true,
1316 | "dependencies": {
1317 | "inherits": "2.0.3"
1318 | }
1319 | },
1320 | "node_modules/util-deprecate": {
1321 | "version": "1.0.2",
1322 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1323 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
1324 | "dev": true
1325 | },
1326 | "node_modules/util/node_modules/inherits": {
1327 | "version": "2.0.3",
1328 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
1329 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
1330 | "dev": true
1331 | },
1332 | "node_modules/vm-browserify": {
1333 | "version": "1.1.2",
1334 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
1335 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
1336 | "dev": true
1337 | },
1338 | "node_modules/whatwg-encoding": {
1339 | "version": "2.0.0",
1340 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
1341 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
1342 | "dev": true,
1343 | "dependencies": {
1344 | "iconv-lite": "0.6.3"
1345 | },
1346 | "engines": {
1347 | "node": ">=12"
1348 | }
1349 | },
1350 | "node_modules/which": {
1351 | "version": "1.3.1",
1352 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1353 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1354 | "dev": true,
1355 | "dependencies": {
1356 | "isexe": "^2.0.0"
1357 | },
1358 | "bin": {
1359 | "which": "bin/which"
1360 | }
1361 | },
1362 | "node_modules/ws": {
1363 | "version": "7.5.8",
1364 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz",
1365 | "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
1366 | "dev": true,
1367 | "engines": {
1368 | "node": ">=8.3.0"
1369 | },
1370 | "peerDependencies": {
1371 | "bufferutil": "^4.0.1",
1372 | "utf-8-validate": "^5.0.2"
1373 | },
1374 | "peerDependenciesMeta": {
1375 | "bufferutil": {
1376 | "optional": true
1377 | },
1378 | "utf-8-validate": {
1379 | "optional": true
1380 | }
1381 | }
1382 | },
1383 | "node_modules/xtend": {
1384 | "version": "4.0.2",
1385 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1386 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1387 | "dev": true,
1388 | "engines": {
1389 | "node": ">=0.4"
1390 | }
1391 | }
1392 | },
1393 | "dependencies": {
1394 | "asn1.js": {
1395 | "version": "5.4.1",
1396 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
1397 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
1398 | "dev": true,
1399 | "requires": {
1400 | "bn.js": "^4.0.0",
1401 | "inherits": "^2.0.1",
1402 | "minimalistic-assert": "^1.0.0",
1403 | "safer-buffer": "^2.1.0"
1404 | },
1405 | "dependencies": {
1406 | "bn.js": {
1407 | "version": "4.12.0",
1408 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1409 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1410 | "dev": true
1411 | }
1412 | }
1413 | },
1414 | "assert": {
1415 | "version": "1.5.0",
1416 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
1417 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
1418 | "dev": true,
1419 | "requires": {
1420 | "object-assign": "^4.1.1",
1421 | "util": "0.10.3"
1422 | },
1423 | "dependencies": {
1424 | "inherits": {
1425 | "version": "2.0.1",
1426 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
1427 | "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==",
1428 | "dev": true
1429 | },
1430 | "util": {
1431 | "version": "0.10.3",
1432 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
1433 | "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==",
1434 | "dev": true,
1435 | "requires": {
1436 | "inherits": "2.0.1"
1437 | }
1438 | }
1439 | }
1440 | },
1441 | "async": {
1442 | "version": "2.6.4",
1443 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
1444 | "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
1445 | "dev": true,
1446 | "requires": {
1447 | "lodash": "^4.17.14"
1448 | }
1449 | },
1450 | "base64-js": {
1451 | "version": "1.5.1",
1452 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
1453 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
1454 | "dev": true
1455 | },
1456 | "basic-auth": {
1457 | "version": "2.0.1",
1458 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
1459 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
1460 | "dev": true,
1461 | "requires": {
1462 | "safe-buffer": "5.1.2"
1463 | }
1464 | },
1465 | "bn.js": {
1466 | "version": "5.2.1",
1467 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz",
1468 | "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
1469 | "dev": true
1470 | },
1471 | "brorand": {
1472 | "version": "1.1.0",
1473 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
1474 | "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
1475 | "dev": true
1476 | },
1477 | "browserify-aes": {
1478 | "version": "1.2.0",
1479 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
1480 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
1481 | "dev": true,
1482 | "requires": {
1483 | "buffer-xor": "^1.0.3",
1484 | "cipher-base": "^1.0.0",
1485 | "create-hash": "^1.1.0",
1486 | "evp_bytestokey": "^1.0.3",
1487 | "inherits": "^2.0.1",
1488 | "safe-buffer": "^5.0.1"
1489 | }
1490 | },
1491 | "browserify-cipher": {
1492 | "version": "1.0.1",
1493 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
1494 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
1495 | "dev": true,
1496 | "requires": {
1497 | "browserify-aes": "^1.0.4",
1498 | "browserify-des": "^1.0.0",
1499 | "evp_bytestokey": "^1.0.0"
1500 | }
1501 | },
1502 | "browserify-des": {
1503 | "version": "1.0.2",
1504 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
1505 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
1506 | "dev": true,
1507 | "requires": {
1508 | "cipher-base": "^1.0.1",
1509 | "des.js": "^1.0.0",
1510 | "inherits": "^2.0.1",
1511 | "safe-buffer": "^5.1.2"
1512 | }
1513 | },
1514 | "browserify-rsa": {
1515 | "version": "4.1.0",
1516 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
1517 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
1518 | "dev": true,
1519 | "requires": {
1520 | "bn.js": "^5.0.0",
1521 | "randombytes": "^2.0.1"
1522 | }
1523 | },
1524 | "browserify-sign": {
1525 | "version": "4.2.1",
1526 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
1527 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
1528 | "dev": true,
1529 | "requires": {
1530 | "bn.js": "^5.1.1",
1531 | "browserify-rsa": "^4.0.1",
1532 | "create-hash": "^1.2.0",
1533 | "create-hmac": "^1.1.7",
1534 | "elliptic": "^6.5.3",
1535 | "inherits": "^2.0.4",
1536 | "parse-asn1": "^5.1.5",
1537 | "readable-stream": "^3.6.0",
1538 | "safe-buffer": "^5.2.0"
1539 | },
1540 | "dependencies": {
1541 | "readable-stream": {
1542 | "version": "3.6.0",
1543 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1544 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1545 | "dev": true,
1546 | "requires": {
1547 | "inherits": "^2.0.3",
1548 | "string_decoder": "^1.1.1",
1549 | "util-deprecate": "^1.0.1"
1550 | }
1551 | },
1552 | "safe-buffer": {
1553 | "version": "5.2.1",
1554 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1555 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1556 | "dev": true
1557 | }
1558 | }
1559 | },
1560 | "browserify-zlib": {
1561 | "version": "0.2.0",
1562 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
1563 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
1564 | "dev": true,
1565 | "requires": {
1566 | "pako": "~1.0.5"
1567 | }
1568 | },
1569 | "buffer": {
1570 | "version": "4.9.2",
1571 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
1572 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
1573 | "dev": true,
1574 | "requires": {
1575 | "base64-js": "^1.0.2",
1576 | "ieee754": "^1.1.4",
1577 | "isarray": "^1.0.0"
1578 | }
1579 | },
1580 | "buffer-xor": {
1581 | "version": "1.0.3",
1582 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
1583 | "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
1584 | "dev": true
1585 | },
1586 | "builtin-status-codes": {
1587 | "version": "3.0.0",
1588 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
1589 | "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
1590 | "dev": true
1591 | },
1592 | "call-bind": {
1593 | "version": "1.0.2",
1594 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
1595 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
1596 | "dev": true,
1597 | "requires": {
1598 | "function-bind": "^1.1.1",
1599 | "get-intrinsic": "^1.0.2"
1600 | }
1601 | },
1602 | "cipher-base": {
1603 | "version": "1.0.4",
1604 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
1605 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
1606 | "dev": true,
1607 | "requires": {
1608 | "inherits": "^2.0.1",
1609 | "safe-buffer": "^5.0.1"
1610 | }
1611 | },
1612 | "color-convert": {
1613 | "version": "2.0.1",
1614 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
1615 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
1616 | "dev": true,
1617 | "requires": {
1618 | "color-name": "~1.1.4"
1619 | }
1620 | },
1621 | "color-name": {
1622 | "version": "1.1.4",
1623 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1624 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
1625 | "dev": true
1626 | },
1627 | "console-browserify": {
1628 | "version": "1.2.0",
1629 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
1630 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
1631 | "dev": true
1632 | },
1633 | "constants-browserify": {
1634 | "version": "1.0.0",
1635 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
1636 | "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
1637 | "dev": true
1638 | },
1639 | "core-util-is": {
1640 | "version": "1.0.3",
1641 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
1642 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
1643 | "dev": true
1644 | },
1645 | "corser": {
1646 | "version": "2.0.1",
1647 | "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
1648 | "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
1649 | "dev": true
1650 | },
1651 | "create-ecdh": {
1652 | "version": "4.0.4",
1653 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
1654 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
1655 | "dev": true,
1656 | "requires": {
1657 | "bn.js": "^4.1.0",
1658 | "elliptic": "^6.5.3"
1659 | },
1660 | "dependencies": {
1661 | "bn.js": {
1662 | "version": "4.12.0",
1663 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1664 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1665 | "dev": true
1666 | }
1667 | }
1668 | },
1669 | "create-hash": {
1670 | "version": "1.2.0",
1671 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
1672 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
1673 | "dev": true,
1674 | "requires": {
1675 | "cipher-base": "^1.0.1",
1676 | "inherits": "^2.0.1",
1677 | "md5.js": "^1.3.4",
1678 | "ripemd160": "^2.0.1",
1679 | "sha.js": "^2.4.0"
1680 | }
1681 | },
1682 | "create-hmac": {
1683 | "version": "1.1.7",
1684 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
1685 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
1686 | "dev": true,
1687 | "requires": {
1688 | "cipher-base": "^1.0.3",
1689 | "create-hash": "^1.1.0",
1690 | "inherits": "^2.0.1",
1691 | "ripemd160": "^2.0.0",
1692 | "safe-buffer": "^5.0.1",
1693 | "sha.js": "^2.4.8"
1694 | }
1695 | },
1696 | "crypto-browserify": {
1697 | "version": "3.12.0",
1698 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
1699 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
1700 | "dev": true,
1701 | "requires": {
1702 | "browserify-cipher": "^1.0.0",
1703 | "browserify-sign": "^4.0.0",
1704 | "create-ecdh": "^4.0.0",
1705 | "create-hash": "^1.1.0",
1706 | "create-hmac": "^1.1.0",
1707 | "diffie-hellman": "^5.0.0",
1708 | "inherits": "^2.0.1",
1709 | "pbkdf2": "^3.0.3",
1710 | "public-encrypt": "^4.0.0",
1711 | "randombytes": "^2.0.0",
1712 | "randomfill": "^1.0.3"
1713 | }
1714 | },
1715 | "dartclojure": {
1716 | "version": "file:..",
1717 | "requires": {
1718 | "rimraf": "3.0.2",
1719 | "shadow-cljs": "^2.19.3"
1720 | }
1721 | },
1722 | "des.js": {
1723 | "version": "1.0.1",
1724 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
1725 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
1726 | "dev": true,
1727 | "requires": {
1728 | "inherits": "^2.0.1",
1729 | "minimalistic-assert": "^1.0.0"
1730 | }
1731 | },
1732 | "diffie-hellman": {
1733 | "version": "5.0.3",
1734 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
1735 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
1736 | "dev": true,
1737 | "requires": {
1738 | "bn.js": "^4.1.0",
1739 | "miller-rabin": "^4.0.0",
1740 | "randombytes": "^2.0.0"
1741 | },
1742 | "dependencies": {
1743 | "bn.js": {
1744 | "version": "4.12.0",
1745 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1746 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1747 | "dev": true
1748 | }
1749 | }
1750 | },
1751 | "domain-browser": {
1752 | "version": "1.2.0",
1753 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
1754 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
1755 | "dev": true
1756 | },
1757 | "elliptic": {
1758 | "version": "6.5.4",
1759 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
1760 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
1761 | "dev": true,
1762 | "requires": {
1763 | "bn.js": "^4.11.9",
1764 | "brorand": "^1.1.0",
1765 | "hash.js": "^1.0.0",
1766 | "hmac-drbg": "^1.0.1",
1767 | "inherits": "^2.0.4",
1768 | "minimalistic-assert": "^1.0.1",
1769 | "minimalistic-crypto-utils": "^1.0.1"
1770 | },
1771 | "dependencies": {
1772 | "bn.js": {
1773 | "version": "4.12.0",
1774 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1775 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1776 | "dev": true
1777 | }
1778 | }
1779 | },
1780 | "eventemitter3": {
1781 | "version": "4.0.7",
1782 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
1783 | "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
1784 | "dev": true
1785 | },
1786 | "events": {
1787 | "version": "3.3.0",
1788 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
1789 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
1790 | "dev": true
1791 | },
1792 | "evp_bytestokey": {
1793 | "version": "1.0.3",
1794 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
1795 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
1796 | "dev": true,
1797 | "requires": {
1798 | "md5.js": "^1.3.4",
1799 | "safe-buffer": "^5.1.1"
1800 | }
1801 | },
1802 | "follow-redirects": {
1803 | "version": "1.15.1",
1804 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
1805 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
1806 | "dev": true
1807 | },
1808 | "function-bind": {
1809 | "version": "1.1.1",
1810 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1811 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
1812 | "dev": true
1813 | },
1814 | "get-intrinsic": {
1815 | "version": "1.1.2",
1816 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
1817 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
1818 | "dev": true,
1819 | "requires": {
1820 | "function-bind": "^1.1.1",
1821 | "has": "^1.0.3",
1822 | "has-symbols": "^1.0.3"
1823 | }
1824 | },
1825 | "has": {
1826 | "version": "1.0.3",
1827 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1828 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1829 | "dev": true,
1830 | "requires": {
1831 | "function-bind": "^1.1.1"
1832 | }
1833 | },
1834 | "has-flag": {
1835 | "version": "4.0.0",
1836 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1837 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1838 | "dev": true
1839 | },
1840 | "has-symbols": {
1841 | "version": "1.0.3",
1842 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1843 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
1844 | "dev": true
1845 | },
1846 | "hash-base": {
1847 | "version": "3.1.0",
1848 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
1849 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
1850 | "dev": true,
1851 | "requires": {
1852 | "inherits": "^2.0.4",
1853 | "readable-stream": "^3.6.0",
1854 | "safe-buffer": "^5.2.0"
1855 | },
1856 | "dependencies": {
1857 | "readable-stream": {
1858 | "version": "3.6.0",
1859 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1860 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1861 | "dev": true,
1862 | "requires": {
1863 | "inherits": "^2.0.3",
1864 | "string_decoder": "^1.1.1",
1865 | "util-deprecate": "^1.0.1"
1866 | }
1867 | },
1868 | "safe-buffer": {
1869 | "version": "5.2.1",
1870 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1871 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1872 | "dev": true
1873 | }
1874 | }
1875 | },
1876 | "hash.js": {
1877 | "version": "1.1.7",
1878 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
1879 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
1880 | "dev": true,
1881 | "requires": {
1882 | "inherits": "^2.0.3",
1883 | "minimalistic-assert": "^1.0.1"
1884 | }
1885 | },
1886 | "he": {
1887 | "version": "1.2.0",
1888 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
1889 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
1890 | "dev": true
1891 | },
1892 | "hmac-drbg": {
1893 | "version": "1.0.1",
1894 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
1895 | "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
1896 | "dev": true,
1897 | "requires": {
1898 | "hash.js": "^1.0.3",
1899 | "minimalistic-assert": "^1.0.0",
1900 | "minimalistic-crypto-utils": "^1.0.1"
1901 | }
1902 | },
1903 | "html-encoding-sniffer": {
1904 | "version": "3.0.0",
1905 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
1906 | "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
1907 | "dev": true,
1908 | "requires": {
1909 | "whatwg-encoding": "^2.0.0"
1910 | }
1911 | },
1912 | "http-proxy": {
1913 | "version": "1.18.1",
1914 | "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
1915 | "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
1916 | "dev": true,
1917 | "requires": {
1918 | "eventemitter3": "^4.0.0",
1919 | "follow-redirects": "^1.0.0",
1920 | "requires-port": "^1.0.0"
1921 | }
1922 | },
1923 | "http-server": {
1924 | "version": "14.1.1",
1925 | "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
1926 | "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
1927 | "dev": true,
1928 | "requires": {
1929 | "basic-auth": "^2.0.1",
1930 | "chalk": "^4.1.2",
1931 | "corser": "^2.0.1",
1932 | "he": "^1.2.0",
1933 | "html-encoding-sniffer": "^3.0.0",
1934 | "http-proxy": "^1.18.1",
1935 | "mime": "^1.6.0",
1936 | "minimist": "^1.2.6",
1937 | "opener": "^1.5.1",
1938 | "portfinder": "^1.0.28",
1939 | "secure-compare": "3.0.1",
1940 | "union": "~0.5.0",
1941 | "url-join": "^4.0.1"
1942 | },
1943 | "dependencies": {
1944 | "ansi-styles": {
1945 | "version": "4.3.0",
1946 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
1947 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
1948 | "dev": true,
1949 | "requires": {
1950 | "color-convert": "^2.0.1"
1951 | }
1952 | },
1953 | "chalk": {
1954 | "version": "4.1.2",
1955 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
1956 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
1957 | "dev": true,
1958 | "requires": {
1959 | "ansi-styles": "^4.1.0",
1960 | "supports-color": "^7.1.0"
1961 | }
1962 | },
1963 | "supports-color": {
1964 | "version": "7.2.0",
1965 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
1966 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
1967 | "dev": true,
1968 | "requires": {
1969 | "has-flag": "^4.0.0"
1970 | }
1971 | }
1972 | }
1973 | },
1974 | "https-browserify": {
1975 | "version": "1.0.0",
1976 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
1977 | "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
1978 | "dev": true
1979 | },
1980 | "iconv-lite": {
1981 | "version": "0.6.3",
1982 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
1983 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
1984 | "dev": true,
1985 | "requires": {
1986 | "safer-buffer": ">= 2.1.2 < 3.0.0"
1987 | }
1988 | },
1989 | "ieee754": {
1990 | "version": "1.2.1",
1991 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1992 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
1993 | "dev": true
1994 | },
1995 | "inherits": {
1996 | "version": "2.0.4",
1997 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1998 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1999 | "dev": true
2000 | },
2001 | "isarray": {
2002 | "version": "1.0.0",
2003 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
2004 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
2005 | "dev": true
2006 | },
2007 | "isexe": {
2008 | "version": "2.0.0",
2009 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2010 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
2011 | "dev": true
2012 | },
2013 | "lodash": {
2014 | "version": "4.17.21",
2015 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
2016 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
2017 | "dev": true
2018 | },
2019 | "md5.js": {
2020 | "version": "1.3.5",
2021 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
2022 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
2023 | "dev": true,
2024 | "requires": {
2025 | "hash-base": "^3.0.0",
2026 | "inherits": "^2.0.1",
2027 | "safe-buffer": "^5.1.2"
2028 | }
2029 | },
2030 | "miller-rabin": {
2031 | "version": "4.0.1",
2032 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
2033 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
2034 | "dev": true,
2035 | "requires": {
2036 | "bn.js": "^4.0.0",
2037 | "brorand": "^1.0.1"
2038 | },
2039 | "dependencies": {
2040 | "bn.js": {
2041 | "version": "4.12.0",
2042 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
2043 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
2044 | "dev": true
2045 | }
2046 | }
2047 | },
2048 | "mime": {
2049 | "version": "1.6.0",
2050 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
2051 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
2052 | "dev": true
2053 | },
2054 | "minimalistic-assert": {
2055 | "version": "1.0.1",
2056 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
2057 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
2058 | "dev": true
2059 | },
2060 | "minimalistic-crypto-utils": {
2061 | "version": "1.0.1",
2062 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
2063 | "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
2064 | "dev": true
2065 | },
2066 | "minimist": {
2067 | "version": "1.2.6",
2068 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
2069 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
2070 | "dev": true
2071 | },
2072 | "mkdirp": {
2073 | "version": "0.5.6",
2074 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
2075 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
2076 | "dev": true,
2077 | "requires": {
2078 | "minimist": "^1.2.6"
2079 | }
2080 | },
2081 | "node-libs-browser": {
2082 | "version": "2.2.1",
2083 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
2084 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
2085 | "dev": true,
2086 | "requires": {
2087 | "assert": "^1.1.1",
2088 | "browserify-zlib": "^0.2.0",
2089 | "buffer": "^4.3.0",
2090 | "console-browserify": "^1.1.0",
2091 | "constants-browserify": "^1.0.0",
2092 | "crypto-browserify": "^3.11.0",
2093 | "domain-browser": "^1.1.1",
2094 | "events": "^3.0.0",
2095 | "https-browserify": "^1.0.0",
2096 | "os-browserify": "^0.3.0",
2097 | "path-browserify": "0.0.1",
2098 | "process": "^0.11.10",
2099 | "punycode": "^1.2.4",
2100 | "querystring-es3": "^0.2.0",
2101 | "readable-stream": "^2.3.3",
2102 | "stream-browserify": "^2.0.1",
2103 | "stream-http": "^2.7.2",
2104 | "string_decoder": "^1.0.0",
2105 | "timers-browserify": "^2.0.4",
2106 | "tty-browserify": "0.0.0",
2107 | "url": "^0.11.0",
2108 | "util": "^0.11.0",
2109 | "vm-browserify": "^1.0.1"
2110 | }
2111 | },
2112 | "object-assign": {
2113 | "version": "4.1.1",
2114 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
2115 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
2116 | "dev": true
2117 | },
2118 | "object-inspect": {
2119 | "version": "1.12.2",
2120 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
2121 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
2122 | "dev": true
2123 | },
2124 | "opener": {
2125 | "version": "1.5.2",
2126 | "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
2127 | "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
2128 | "dev": true
2129 | },
2130 | "os-browserify": {
2131 | "version": "0.3.0",
2132 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
2133 | "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
2134 | "dev": true
2135 | },
2136 | "pako": {
2137 | "version": "1.0.11",
2138 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
2139 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
2140 | "dev": true
2141 | },
2142 | "parse-asn1": {
2143 | "version": "5.1.6",
2144 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
2145 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
2146 | "dev": true,
2147 | "requires": {
2148 | "asn1.js": "^5.2.0",
2149 | "browserify-aes": "^1.0.0",
2150 | "evp_bytestokey": "^1.0.0",
2151 | "pbkdf2": "^3.0.3",
2152 | "safe-buffer": "^5.1.1"
2153 | }
2154 | },
2155 | "path-browserify": {
2156 | "version": "0.0.1",
2157 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
2158 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
2159 | "dev": true
2160 | },
2161 | "pbkdf2": {
2162 | "version": "3.1.2",
2163 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
2164 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
2165 | "dev": true,
2166 | "requires": {
2167 | "create-hash": "^1.1.2",
2168 | "create-hmac": "^1.1.4",
2169 | "ripemd160": "^2.0.1",
2170 | "safe-buffer": "^5.0.1",
2171 | "sha.js": "^2.4.8"
2172 | }
2173 | },
2174 | "portfinder": {
2175 | "version": "1.0.28",
2176 | "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
2177 | "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
2178 | "dev": true,
2179 | "requires": {
2180 | "async": "^2.6.2",
2181 | "debug": "^3.1.1",
2182 | "mkdirp": "^0.5.5"
2183 | },
2184 | "dependencies": {
2185 | "debug": {
2186 | "version": "3.2.7",
2187 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
2188 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
2189 | "dev": true,
2190 | "requires": {
2191 | "ms": "^2.1.1"
2192 | }
2193 | },
2194 | "ms": {
2195 | "version": "2.1.3",
2196 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2197 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
2198 | "dev": true
2199 | }
2200 | }
2201 | },
2202 | "process": {
2203 | "version": "0.11.10",
2204 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
2205 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
2206 | "dev": true
2207 | },
2208 | "process-nextick-args": {
2209 | "version": "2.0.1",
2210 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
2211 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
2212 | "dev": true
2213 | },
2214 | "public-encrypt": {
2215 | "version": "4.0.3",
2216 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
2217 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
2218 | "dev": true,
2219 | "requires": {
2220 | "bn.js": "^4.1.0",
2221 | "browserify-rsa": "^4.0.0",
2222 | "create-hash": "^1.1.0",
2223 | "parse-asn1": "^5.0.0",
2224 | "randombytes": "^2.0.1",
2225 | "safe-buffer": "^5.1.2"
2226 | },
2227 | "dependencies": {
2228 | "bn.js": {
2229 | "version": "4.12.0",
2230 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
2231 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
2232 | "dev": true
2233 | }
2234 | }
2235 | },
2236 | "punycode": {
2237 | "version": "1.4.1",
2238 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
2239 | "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
2240 | "dev": true
2241 | },
2242 | "qs": {
2243 | "version": "6.10.5",
2244 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz",
2245 | "integrity": "sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ==",
2246 | "dev": true,
2247 | "requires": {
2248 | "side-channel": "^1.0.4"
2249 | }
2250 | },
2251 | "querystring": {
2252 | "version": "0.2.0",
2253 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
2254 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
2255 | "dev": true
2256 | },
2257 | "querystring-es3": {
2258 | "version": "0.2.1",
2259 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
2260 | "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
2261 | "dev": true
2262 | },
2263 | "randombytes": {
2264 | "version": "2.1.0",
2265 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
2266 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
2267 | "dev": true,
2268 | "requires": {
2269 | "safe-buffer": "^5.1.0"
2270 | }
2271 | },
2272 | "randomfill": {
2273 | "version": "1.0.4",
2274 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
2275 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
2276 | "dev": true,
2277 | "requires": {
2278 | "randombytes": "^2.0.5",
2279 | "safe-buffer": "^5.1.0"
2280 | }
2281 | },
2282 | "readable-stream": {
2283 | "version": "2.3.7",
2284 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
2285 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
2286 | "dev": true,
2287 | "requires": {
2288 | "core-util-is": "~1.0.0",
2289 | "inherits": "~2.0.3",
2290 | "isarray": "~1.0.0",
2291 | "process-nextick-args": "~2.0.0",
2292 | "safe-buffer": "~5.1.1",
2293 | "string_decoder": "~1.1.1",
2294 | "util-deprecate": "~1.0.1"
2295 | }
2296 | },
2297 | "readline-sync": {
2298 | "version": "1.4.10",
2299 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
2300 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
2301 | "dev": true
2302 | },
2303 | "requires-port": {
2304 | "version": "1.0.0",
2305 | "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
2306 | "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
2307 | "dev": true
2308 | },
2309 | "ripemd160": {
2310 | "version": "2.0.2",
2311 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
2312 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
2313 | "dev": true,
2314 | "requires": {
2315 | "hash-base": "^3.0.0",
2316 | "inherits": "^2.0.1"
2317 | }
2318 | },
2319 | "safe-buffer": {
2320 | "version": "5.1.2",
2321 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2322 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
2323 | "dev": true
2324 | },
2325 | "safer-buffer": {
2326 | "version": "2.1.2",
2327 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2328 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2329 | "dev": true
2330 | },
2331 | "secure-compare": {
2332 | "version": "3.0.1",
2333 | "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
2334 | "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==",
2335 | "dev": true
2336 | },
2337 | "setimmediate": {
2338 | "version": "1.0.5",
2339 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
2340 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
2341 | "dev": true
2342 | },
2343 | "sha.js": {
2344 | "version": "2.4.11",
2345 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
2346 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
2347 | "dev": true,
2348 | "requires": {
2349 | "inherits": "^2.0.1",
2350 | "safe-buffer": "^5.0.1"
2351 | }
2352 | },
2353 | "shadow-cljs": {
2354 | "version": "2.19.3",
2355 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.19.3.tgz",
2356 | "integrity": "sha512-9TsTCRlmR8m1g2ekwblgomRUgJpbifQI99VlRrlH9NMqEzklev3zYAD1dvy4d5h8BoAhgdxOOEg7ld2d45CWTA==",
2357 | "dev": true,
2358 | "requires": {
2359 | "node-libs-browser": "^2.2.1",
2360 | "readline-sync": "^1.4.7",
2361 | "shadow-cljs-jar": "1.3.2",
2362 | "source-map-support": "^0.4.15",
2363 | "which": "^1.3.1",
2364 | "ws": "^7.4.6"
2365 | }
2366 | },
2367 | "shadow-cljs-jar": {
2368 | "version": "1.3.2",
2369 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz",
2370 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==",
2371 | "dev": true
2372 | },
2373 | "side-channel": {
2374 | "version": "1.0.4",
2375 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
2376 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
2377 | "dev": true,
2378 | "requires": {
2379 | "call-bind": "^1.0.0",
2380 | "get-intrinsic": "^1.0.2",
2381 | "object-inspect": "^1.9.0"
2382 | }
2383 | },
2384 | "source-map": {
2385 | "version": "0.5.7",
2386 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2387 | "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
2388 | "dev": true
2389 | },
2390 | "source-map-support": {
2391 | "version": "0.4.18",
2392 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
2393 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
2394 | "dev": true,
2395 | "requires": {
2396 | "source-map": "^0.5.6"
2397 | }
2398 | },
2399 | "stream-browserify": {
2400 | "version": "2.0.2",
2401 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
2402 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
2403 | "dev": true,
2404 | "requires": {
2405 | "inherits": "~2.0.1",
2406 | "readable-stream": "^2.0.2"
2407 | }
2408 | },
2409 | "stream-http": {
2410 | "version": "2.8.3",
2411 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
2412 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
2413 | "dev": true,
2414 | "requires": {
2415 | "builtin-status-codes": "^3.0.0",
2416 | "inherits": "^2.0.1",
2417 | "readable-stream": "^2.3.6",
2418 | "to-arraybuffer": "^1.0.0",
2419 | "xtend": "^4.0.0"
2420 | }
2421 | },
2422 | "string_decoder": {
2423 | "version": "1.1.1",
2424 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
2425 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2426 | "dev": true,
2427 | "requires": {
2428 | "safe-buffer": "~5.1.0"
2429 | }
2430 | },
2431 | "timers-browserify": {
2432 | "version": "2.0.12",
2433 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
2434 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
2435 | "dev": true,
2436 | "requires": {
2437 | "setimmediate": "^1.0.4"
2438 | }
2439 | },
2440 | "to-arraybuffer": {
2441 | "version": "1.0.1",
2442 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
2443 | "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==",
2444 | "dev": true
2445 | },
2446 | "tty-browserify": {
2447 | "version": "0.0.0",
2448 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
2449 | "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==",
2450 | "dev": true
2451 | },
2452 | "union": {
2453 | "version": "0.5.0",
2454 | "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
2455 | "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
2456 | "dev": true,
2457 | "requires": {
2458 | "qs": "^6.4.0"
2459 | }
2460 | },
2461 | "url": {
2462 | "version": "0.11.0",
2463 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
2464 | "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==",
2465 | "dev": true,
2466 | "requires": {
2467 | "punycode": "1.3.2",
2468 | "querystring": "0.2.0"
2469 | },
2470 | "dependencies": {
2471 | "punycode": {
2472 | "version": "1.3.2",
2473 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
2474 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==",
2475 | "dev": true
2476 | }
2477 | }
2478 | },
2479 | "url-join": {
2480 | "version": "4.0.1",
2481 | "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
2482 | "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
2483 | "dev": true
2484 | },
2485 | "util": {
2486 | "version": "0.11.1",
2487 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
2488 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
2489 | "dev": true,
2490 | "requires": {
2491 | "inherits": "2.0.3"
2492 | },
2493 | "dependencies": {
2494 | "inherits": {
2495 | "version": "2.0.3",
2496 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
2497 | "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
2498 | "dev": true
2499 | }
2500 | }
2501 | },
2502 | "util-deprecate": {
2503 | "version": "1.0.2",
2504 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2505 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
2506 | "dev": true
2507 | },
2508 | "vm-browserify": {
2509 | "version": "1.1.2",
2510 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
2511 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
2512 | "dev": true
2513 | },
2514 | "whatwg-encoding": {
2515 | "version": "2.0.0",
2516 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
2517 | "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
2518 | "dev": true,
2519 | "requires": {
2520 | "iconv-lite": "0.6.3"
2521 | }
2522 | },
2523 | "which": {
2524 | "version": "1.3.1",
2525 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2526 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2527 | "dev": true,
2528 | "requires": {
2529 | "isexe": "^2.0.0"
2530 | }
2531 | },
2532 | "ws": {
2533 | "version": "7.5.8",
2534 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.8.tgz",
2535 | "integrity": "sha512-ri1Id1WinAX5Jqn9HejiGb8crfRio0Qgu8+MtL36rlTA6RLsMdWt1Az/19A2Qij6uSHUMphEFaTKa4WG+UNHNw==",
2536 | "dev": true,
2537 | "requires": {}
2538 | },
2539 | "xtend": {
2540 | "version": "4.0.2",
2541 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
2542 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
2543 | "dev": true
2544 | }
2545 | }
2546 | }
2547 |
--------------------------------------------------------------------------------