├── .github
└── workflows
│ ├── build-demo.yml
│ └── deploy-clojars.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── build.clj
├── deps.edn
├── dev.md
├── docs
├── blog.css
├── bootstrap.min.css
├── index.html
└── js
│ ├── main.js
│ └── manifest.edn
├── inspector-resize.gif
├── inspector.gif
├── navigation.gif
├── package-lock.json
├── package.json
├── paging.gif
├── pom.xml
├── public
├── blog.css
├── bootstrap.min.css
└── index.html
├── resources
└── .keep
├── shadow-cljs.edn
├── src
└── com
│ └── phronemophobic
│ ├── viscous.cljc
│ └── viscous
│ ├── cli.clj
│ └── demo.cljs
└── test
└── com
└── phronemophobic
└── membrane
└── pretty_view_test.clj
/.github/workflows/build-demo.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deploy Web Demo
2 | on:
3 | push:
4 | jobs:
5 | build:
6 |
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Prepare java
11 | uses: actions/setup-java@v3.5.1
12 | with:
13 | distribution: 'zulu'
14 | java-version: '11'
15 |
16 | - uses: actions/checkout@v3.1.0
17 | - name: Setup Node
18 | uses: actions/setup-node@v3.5.0
19 | with:
20 | node-version: '17.4.0'
21 |
22 | - name: Install node dependencies
23 | run: npm install
24 |
25 | - name: Setup Clojure
26 | # You may pin to the exact commit or the version.
27 | # uses: DeLaGuardo/setup-clojure@5042876523f30f5efcf1d6feaa48bd1498d7814f
28 | uses: DeLaGuardo/setup-clojure@9.5
29 | with:
30 | # Clojure CLI version to make available on the path.
31 | cli: 1.10.3.1058
32 |
33 | - name: Install dependencies
34 | run: clojure -P
35 | - name: Build static
36 | run: clojure -M:shadow-cljs:cljs release app
37 | - name: Deploy 🚀
38 | uses: JamesIves/github-pages-deploy-action@v4.4.0
39 | with:
40 | branch: gh-pages # The branch the action should deploy to.
41 | folder: public # The folder the action should deploy.
42 |
43 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-clojars.yml:
--------------------------------------------------------------------------------
1 | name: Clojars deploy
2 | on:
3 | workflow_dispatch:
4 | jobs:
5 | build:
6 |
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Prepare java
11 | uses: actions/setup-java@v3.5.1
12 | with:
13 | distribution: 'zulu'
14 | java-version: '11'
15 |
16 | - uses: actions/checkout@v3.1.0
17 | - name: Setup Clojure
18 | # You may pin to the exact commit or the version.
19 | # uses: DeLaGuardo/setup-clojure@5042876523f30f5efcf1d6feaa48bd1498d7814f
20 | uses: DeLaGuardo/setup-clojure@9.5
21 | with:
22 | # Clojure CLI version to make available on the path.
23 | cli: 1.11.0.1100
24 |
25 | - name: Install dependencies
26 | run: clojure -P
27 |
28 | - name: Deploy
29 | env:
30 | CLOJARS_USERNAME: ${{ secrets.CLOJARS_USERNAME }}
31 | CLOJARS_PASSWORD: ${{ secrets.CLOJARS_PASSWORD }}
32 | run: clojure -T:build deploy
33 |
34 |
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | *.jar
5 | *.class
6 | /.calva/output-window/
7 | /.cpcache
8 | /.lein-*
9 | /.lsp/sqlite*.db
10 | /.nrepl-history
11 | /.nrepl-port
12 | /.rebel_readline_history
13 | /.socket-repl-port
14 | .hgignore
15 | .hg/
16 | out
17 | node_modules
18 | .shadow-cljs
19 | public/js
--------------------------------------------------------------------------------
/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] - 2021-04-20
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 - 2021-04-20
19 | ### Added
20 | - Files from the new template.
21 | - Widget maker public API - `make-widget-sync`.
22 |
23 | [Unreleased]: https://github.com/com.phronemophobic.membrane/pretty-view/compare/0.1.1...HEAD
24 | [0.1.1]: https://github.com/com.phronemophobic.membrane/pretty-view/compare/0.1.0...0.1.1
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
2 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
3 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
4 |
5 | 1. DEFINITIONS
6 |
7 | "Contribution" means:
8 |
9 | a) in the case of the initial Contributor, the initial code and
10 | documentation distributed under this Agreement, and
11 |
12 | b) in the case of each subsequent Contributor:
13 |
14 | i) changes to the Program, and
15 |
16 | ii) additions to the Program;
17 |
18 | where such changes and/or additions to the Program originate from and are
19 | distributed by that particular Contributor. A Contribution 'originates' from
20 | a Contributor if it was added to the Program by such Contributor itself or
21 | anyone acting on such Contributor's behalf. Contributions do not include
22 | additions to the Program which: (i) are separate modules of software
23 | distributed in conjunction with the Program under their own license
24 | agreement, and (ii) are not derivative works of the Program.
25 |
26 | "Contributor" means any person or entity that distributes the Program.
27 |
28 | "Licensed Patents" mean patent claims licensable by a Contributor which are
29 | necessarily infringed by the use or sale of its Contribution alone or when
30 | combined with the Program.
31 |
32 | "Program" means the Contributions distributed in accordance with this
33 | Agreement.
34 |
35 | "Recipient" means anyone who receives the Program under this Agreement,
36 | including all Contributors.
37 |
38 | 2. GRANT OF RIGHTS
39 |
40 | a) Subject to the terms of this Agreement, each Contributor hereby grants
41 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
42 | reproduce, prepare derivative works of, publicly display, publicly perform,
43 | distribute and sublicense the Contribution of such Contributor, if any, and
44 | such derivative works, in source code and object code form.
45 |
46 | b) Subject to the terms of this Agreement, each Contributor hereby grants
47 | Recipient a non-exclusive, worldwide, royalty-free patent license under
48 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
49 | transfer the Contribution of such Contributor, if any, in source code and
50 | object code form. This patent license shall apply to the combination of the
51 | Contribution and the Program if, at the time the Contribution is added by the
52 | Contributor, such addition of the Contribution causes such combination to be
53 | covered by the Licensed Patents. The patent license shall not apply to any
54 | other combinations which include the Contribution. No hardware per se is
55 | licensed hereunder.
56 |
57 | c) Recipient understands that although each Contributor grants the licenses
58 | to its Contributions set forth herein, no assurances are provided by any
59 | Contributor that the Program does not infringe the patent or other
60 | intellectual property rights of any other entity. Each Contributor disclaims
61 | any liability to Recipient for claims brought by any other entity based on
62 | infringement of intellectual property rights or otherwise. As a condition to
63 | exercising the rights and licenses granted hereunder, each Recipient hereby
64 | assumes sole responsibility to secure any other intellectual property rights
65 | needed, if any. For example, if a third party patent license is required to
66 | allow Recipient to distribute the Program, it is Recipient's responsibility
67 | to acquire that license before distributing the Program.
68 |
69 | d) Each Contributor represents that to its knowledge it has sufficient
70 | copyright rights in its Contribution, if any, to grant the copyright license
71 | set forth in this Agreement.
72 |
73 | 3. REQUIREMENTS
74 |
75 | A Contributor may choose to distribute the Program in object code form under
76 | its own license agreement, provided that:
77 |
78 | a) it complies with the terms and conditions of this Agreement; and
79 |
80 | b) its license agreement:
81 |
82 | i) effectively disclaims on behalf of all Contributors all warranties and
83 | conditions, express and implied, including warranties or conditions of title
84 | and non-infringement, and implied warranties or conditions of merchantability
85 | and fitness for a particular purpose;
86 |
87 | ii) effectively excludes on behalf of all Contributors all liability for
88 | damages, including direct, indirect, special, incidental and consequential
89 | damages, such as lost profits;
90 |
91 | iii) states that any provisions which differ from this Agreement are offered
92 | by that Contributor alone and not by any other party; and
93 |
94 | iv) states that source code for the Program is available from such
95 | Contributor, and informs licensees how to obtain it in a reasonable manner on
96 | or through a medium customarily used for software exchange.
97 |
98 | When the Program is made available in source code form:
99 |
100 | a) it must be made available under this Agreement; and
101 |
102 | b) a copy of this Agreement must be included with each copy of the Program.
103 |
104 | Contributors may not remove or alter any copyright notices contained within
105 | the Program.
106 |
107 | Each Contributor must identify itself as the originator of its Contribution,
108 | if any, in a manner that reasonably allows subsequent Recipients to identify
109 | the originator of the Contribution.
110 |
111 | 4. COMMERCIAL DISTRIBUTION
112 |
113 | Commercial distributors of software may accept certain responsibilities with
114 | respect to end users, business partners and the like. While this license is
115 | intended to facilitate the commercial use of the Program, the Contributor who
116 | includes the Program in a commercial product offering should do so in a
117 | manner which does not create potential liability for other Contributors.
118 | Therefore, if a Contributor includes the Program in a commercial product
119 | offering, such Contributor ("Commercial Contributor") hereby agrees to defend
120 | and indemnify every other Contributor ("Indemnified Contributor") against any
121 | losses, damages and costs (collectively "Losses") arising from claims,
122 | lawsuits and other legal actions brought by a third party against the
123 | Indemnified Contributor to the extent caused by the acts or omissions of such
124 | Commercial Contributor in connection with its distribution of the Program in
125 | a commercial product offering. The obligations in this section do not apply
126 | to any claims or Losses relating to any actual or alleged intellectual
127 | property infringement. In order to qualify, an Indemnified Contributor must:
128 | a) promptly notify the Commercial Contributor in writing of such claim, and
129 | b) allow the Commercial Contributor to control, and cooperate with the
130 | Commercial Contributor in, the defense and any related settlement
131 | negotiations. The Indemnified Contributor may participate in any such claim
132 | at its own expense.
133 |
134 | For example, a Contributor might include the Program in a commercial product
135 | offering, Product X. That Contributor is then a Commercial Contributor. If
136 | that Commercial Contributor then makes performance claims, or offers
137 | warranties related to Product X, those performance claims and warranties are
138 | such Commercial Contributor's responsibility alone. Under this section, the
139 | Commercial Contributor would have to defend claims against the other
140 | Contributors related to those performance claims and warranties, and if a
141 | court requires any other Contributor to pay any damages as a result, the
142 | Commercial Contributor must pay those damages.
143 |
144 | 5. NO WARRANTY
145 |
146 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON
147 | AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
148 | EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
149 | CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
150 | PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the
151 | appropriateness of using and distributing the Program and assumes all risks
152 | associated with its exercise of rights under this Agreement , including but
153 | not limited to the risks and costs of program errors, compliance with
154 | applicable laws, damage to or loss of data, programs or equipment, and
155 | unavailability or interruption of operations.
156 |
157 | 6. DISCLAIMER OF LIABILITY
158 |
159 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
160 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
161 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
162 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
163 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
164 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
165 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
166 | OF SUCH DAMAGES.
167 |
168 | 7. GENERAL
169 |
170 | If any provision of this Agreement is invalid or unenforceable under
171 | applicable law, it shall not affect the validity or enforceability of the
172 | remainder of the terms of this Agreement, and without further action by the
173 | parties hereto, such provision shall be reformed to the minimum extent
174 | necessary to make such provision valid and enforceable.
175 |
176 | If Recipient institutes patent litigation against any entity (including a
177 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
178 | (excluding combinations of the Program with other software or hardware)
179 | infringes such Recipient's patent(s), then such Recipient's rights granted
180 | under Section 2(b) shall terminate as of the date such litigation is filed.
181 |
182 | All Recipient's rights under this Agreement shall terminate if it fails to
183 | comply with any of the material terms or conditions of this Agreement and
184 | does not cure such failure in a reasonable period of time after becoming
185 | aware of such noncompliance. If all Recipient's rights under this Agreement
186 | terminate, Recipient agrees to cease use and distribution of the Program as
187 | soon as reasonably practicable. However, Recipient's obligations under this
188 | Agreement and any licenses granted by Recipient relating to the Program shall
189 | continue and survive.
190 |
191 | Everyone is permitted to copy and distribute copies of this Agreement, but in
192 | order to avoid inconsistency the Agreement is copyrighted and may only be
193 | modified in the following manner. The Agreement Steward reserves the right to
194 | publish new versions (including revisions) of this Agreement from time to
195 | time. No one other than the Agreement Steward has the right to modify this
196 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
197 | Eclipse Foundation may assign the responsibility to serve as the Agreement
198 | Steward to a suitable separate entity. Each new version of the Agreement will
199 | be given a distinguishing version number. The Program (including
200 | Contributions) may always be distributed subject to the version of the
201 | Agreement under which it was received. In addition, after a new version of
202 | the Agreement is published, Contributor may elect to distribute the Program
203 | (including its Contributions) under the new version. Except as expressly
204 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
205 | licenses to the intellectual property of any Contributor under this
206 | Agreement, whether expressly, by implication, estoppel or otherwise. All
207 | rights in the Program not expressly granted under this Agreement are
208 | reserved.
209 |
210 | This Agreement is governed by the laws of the State of New York and the
211 | intellectual property laws of the United States of America. No party to this
212 | Agreement will bring a legal action under this Agreement more than one year
213 | after the cause of action arose. Each party waives its rights to a jury trial
214 | in any resulting litigation.
215 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Viscous
2 |
3 | A visual data inspector/explorer that runs in constant space, time, and screen space.
4 |
5 | Built with [membrane](https://github.com/phronmophobic/membrane).
6 |
7 | ### Overview
8 |
9 | 
10 |
11 | ### Resizing
12 | 
13 |
14 | ### Paging
15 | 
16 |
17 | ### Navigating
18 | 
19 |
20 | ## Web Demo
21 |
22 | Try it! https://phronmophobic.github.io/viscous/
23 |
24 | ## Dependency
25 |
26 | #### deps.edn
27 | ```clojure
28 | com.phronemophobic/viscous {:mvn/version "1.3.5"}
29 | ```
30 |
31 | #### lein
32 | ```clojure
33 | [com.phronemophobic/viscous "1.3.5"]
34 | ```
35 |
36 | ## Programmatic Usage
37 |
38 | ```clojure
39 | (require '[com.phronemophobic.viscous :as viscous])
40 |
41 | (def my-data {:a {:b 42}})
42 |
43 | ;; open inspector window
44 | (viscous/inspect my-data)
45 |
46 | ```
47 |
48 | ## Cli usage
49 |
50 | Create an alias for viscous
51 |
52 | ```clojure
53 |
54 | {
55 | :aliases {
56 | ```
57 | ```clojure
58 | :viscous
59 | {:replace-deps {com.phronemophobic/viscous {:mvn/version "1.3.5"}
60 | org.clojure/data.json {:mvn/version "2.4.0"}}
61 | :exec-fn com.phronemophobic.viscous.cli/main}
62 | ```
63 | ```clojure
64 | }
65 | }
66 | ```
67 |
68 | Read edn from stdin:
69 | ```sh
70 | cat data.edn | clojure -X:viscous :file -
71 | ```
72 |
73 | Read edn from filename:
74 | ```sh
75 | clojure -X:viscous :file '"data.edn"'
76 | ```
77 |
78 | Read json from stdin:
79 | ```sh
80 | cat data.json | clojure -X:viscous :json-file -
81 | ```
82 |
83 | Read json from filename:
84 | ```sh
85 | clojure -X:viscous :json-file '"data.edn"'
86 | ```
87 |
88 | ## Status
89 |
90 | Viscous is in beta. Behavior is subject to change. Feedback is welcome.
91 |
92 | ## Related
93 |
94 | I'm generally interested in finding better ways to represent and explore medium sized heterogenous data. If you like viscous, you may also be interested in [treemap-clj](https://github.com/phronmophobic/treemap-clj).
95 |
96 | ## License
97 |
98 | Copyright © 2025 Adrian Smith
99 |
100 | Distributed under the Eclipse Public License version 1.0.
101 |
--------------------------------------------------------------------------------
/build.clj:
--------------------------------------------------------------------------------
1 | (ns build
2 | (:require [clojure.tools.build.api :as b]
3 | [clojure.string :as str]))
4 |
5 | (def lib 'com.phronemophobic/viscous)
6 | (def version "1.3.5")
7 | (def class-dir "target/classes")
8 | (def basis (b/create-basis {:project "deps.edn"}))
9 | (def jar-file (format "target/%s-%s.jar" (name lib) version))
10 |
11 | (defn clean [_]
12 | (b/delete {:path "target"}))
13 |
14 | (defn jar [_]
15 | (b/write-pom {:class-dir class-dir
16 | :lib lib
17 | :version version
18 | :basis basis
19 | :src-dirs ["src"]})
20 | (b/copy-dir {:src-dirs ["src" "resources"]
21 | :target-dir class-dir})
22 | (b/jar {:class-dir class-dir
23 | :jar-file jar-file}))
24 |
25 | (defn deploy [opts]
26 | (jar opts)
27 | (try ((requiring-resolve 'deps-deploy.deps-deploy/deploy)
28 | (merge {:installer :remote
29 | :artifact jar-file
30 | :pom-file (b/pom-path {:lib lib :class-dir class-dir})}
31 | opts))
32 | (catch Exception e
33 | (if-not (str/includes? (ex-message e) "redeploying non-snapshots is not allowed")
34 | (throw e)
35 | (println "This release was already deployed."))))
36 | opts)
37 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:paths ["src" "resources"]
2 | :deps {org.clojure/clojure {:mvn/version "1.10.3"}
3 | com.phronemophobic/membrane {:mvn/version "0.14.1-beta"
4 | ;; :local/root "../membrane"
5 | }}
6 | :aliases
7 | {:test {:extra-paths ["test"]
8 | :extra-deps {org.clojure/test.check {:mvn/version "1.1.0"}}}
9 |
10 |
11 | :viscous {:exec-fn com.phronemophobic.viscous.cli/main
12 | :extra-deps {org.clojure/data.json {:mvn/version "2.4.0"}}}
13 |
14 | :cljs
15 | {:extra-deps {thheller/shadow-cljs {:mvn/version "2.20.3"}}}
16 |
17 | :build {:deps {io.github.clojure/tools.build {:git/tag "v0.8.3" :git/sha "0d20256"}
18 | slipset/deps-deploy {:mvn/version "RELEASE"}}
19 | :ns-default build}
20 |
21 | :shadow-cljs
22 | {:extra-deps {thheller/shadow-cljs {:mvn/version "2.20.3"}}
23 | :main-opts ["-m" "shadow.cljs.devtools.cli"]}
24 |
25 | :project
26 | {:extra-deps {org.clojure/data.json {:mvn/version "2.4.0"}
27 | org.clojure/test.check {:mvn/version "0.9.0"}
28 | com.phronemophobic.membrane/skialib-macosx-aarch64
29 | {:mvn/version "RELEASE"
30 | ;; :local/root "csource/macos-aarch64"
31 | }}}
32 |
33 | :tagsoup
34 | {:extra-deps {
35 | org.clojure/data.xml {:mvn/version "0.0.8"}
36 | clj-tagsoup/clj-tagsoup {:mvn/version "0.3.0"
37 | :exclusions [org.clojure/data.xml]}
38 | }}
39 |
40 | :runner
41 | {:extra-deps {com.cognitect/test-runner
42 | {:git/url "https://github.com/cognitect-labs/test-runner"
43 | :sha "b6b3193fcc42659d7e46ecd1884a228993441182"}}
44 | :main-opts ["-m" "cognitect.test-runner"
45 | "-d" "test"]}
46 | :jar {:replace-deps {com.github.seancorfield/depstar {:mvn/version "2.0.211"}}
47 | :exec-fn hf.depstar/jar
48 | :exec-args {:jar "viscous.jar" :sync-pom true}}
49 | :install {:replace-deps {slipset/deps-deploy {:mvn/version "0.1.5"}}
50 | :exec-fn deps-deploy.deps-deploy/deploy
51 | :exec-args {:installer :local :artifact "viscous.jar"}}
52 | :deploy {:replace-deps {slipset/deps-deploy {:mvn/version "0.1.5"}}
53 | :exec-fn deps-deploy.deps-deploy/deploy
54 | :exec-args {:installer :remote :artifact "viscous.jar"}}}}
55 |
--------------------------------------------------------------------------------
/dev.md:
--------------------------------------------------------------------------------
1 | ## Dev notes
2 |
3 | To update web demo, run the following from the root dir:
4 |
5 | ```sh
6 | # clean first
7 | rm -rf .shadow-cljs/builds/
8 | clojure -M:shadow-cljs release app
9 | ```
10 |
11 | This will write the js file to `public/js/main.js`.
12 |
13 | ```sh
14 | cp public/js/main.js docs/js/main.js
15 | ```
16 |
17 |
--------------------------------------------------------------------------------
/docs/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Globals
3 | */
4 |
5 | @media (min-width: 48em) {
6 | html {
7 | font-size: 18px;
8 | }
9 | }
10 |
11 | /* body { */
12 | /* font-family: Georgia, "Times New Roman", Times, serif; */
13 | /* color: #555; */
14 | /* } */
15 |
16 | /* h1, .h1, */
17 | /* h2, .h2, */
18 | /* h3, .h3, */
19 | /* h4, .h4, */
20 | /* h5, .h5, */
21 | /* h6, .h6 { */
22 | /* font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; */
23 | /* font-weight: normal; */
24 | /* color: #333; */
25 | /* } */
26 |
27 |
28 | /*
29 | * Override Bootstrap's default container.
30 | */
31 |
32 | .container {
33 | max-width: 60rem;
34 | }
35 |
36 |
37 | /*
38 | * Masthead for nav
39 | */
40 |
41 | .blog-masthead {
42 | margin-bottom: 3rem;
43 | background-color: #428bca;
44 | -webkit-box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1);
45 | box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1);
46 | }
47 |
48 | /* Nav links */
49 | .nav-link {
50 | position: relative;
51 | padding: 1rem;
52 | font-weight: 500;
53 | color: #cdddeb;
54 | }
55 | .nav-link:hover,
56 | .nav-link:focus {
57 | color: #fff;
58 | background-color: transparent;
59 | }
60 |
61 | /* Active state gets a caret at the bottom */
62 | .nav-link.active {
63 | color: #fff;
64 | }
65 | .nav-link.active:after {
66 | position: absolute;
67 | bottom: 0;
68 | left: 50%;
69 | width: 0;
70 | height: 0;
71 | margin-left: -.3rem;
72 | vertical-align: middle;
73 | content: "";
74 | border-right: .3rem solid transparent;
75 | border-bottom: .3rem solid;
76 | border-left: .3rem solid transparent;
77 | }
78 |
79 |
80 | /*
81 | * Blog name and description
82 | */
83 |
84 | .blog-header {
85 | padding-bottom: 1.25rem;
86 | margin-bottom: 2rem;
87 | border-bottom: .05rem solid #eee;
88 | }
89 | .blog-title {
90 | margin-bottom: 0;
91 | font-size: 2rem;
92 | font-weight: normal;
93 | }
94 | .blog-description {
95 | font-size: 1.1rem;
96 | color: #999;
97 | }
98 |
99 | @media (min-width: 40em) {
100 | .blog-title {
101 | font-size: 3.5rem;
102 | }
103 | }
104 |
105 |
106 | /*
107 | * Main column and sidebar layout
108 | */
109 |
110 | /* Sidebar modules for boxing content */
111 | .sidebar-module {
112 | padding: 1rem;
113 | /*margin: 0 -1rem 1rem;*/
114 | }
115 | .sidebar-module-inset {
116 | padding: 1rem;
117 | background-color: #f5f5f5;
118 | border-radius: .25rem;
119 | }
120 | .sidebar-module-inset p:last-child,
121 | .sidebar-module-inset ul:last-child,
122 | .sidebar-module-inset ol:last-child {
123 | margin-bottom: 0;
124 | }
125 |
126 |
127 | /* Pagination */
128 | .blog-pagination {
129 | margin-bottom: 4rem;
130 | }
131 | .blog-pagination > .btn {
132 | border-radius: 2rem;
133 | }
134 |
135 |
136 | /*
137 | * Blog posts
138 | */
139 |
140 | .blog-post {
141 | margin-bottom: 4rem;
142 | }
143 | .blog-post-title {
144 | margin-bottom: .25rem;
145 | font-size: 2.5rem;
146 | }
147 | .blog-post-meta {
148 | margin-bottom: 1.25rem;
149 | color: #999;
150 | }
151 |
152 |
153 | /*
154 | * Footer
155 | */
156 |
157 | .blog-footer {
158 | padding: 2.5rem 0;
159 | color: #999;
160 | text-align: center;
161 | background-color: #f9f9f9;
162 | border-top: .05rem solid #e5e5e5;
163 | }
164 | .blog-footer p:last-child {
165 | margin-bottom: 0;
166 | }
167 |
168 |
169 | blockquote {
170 | /* background: #f9f9f9; */
171 | border-left: 10px solid #ccc;
172 | margin: 1.5em 10px;
173 | padding: 0.5em 10px;
174 | /* quotes: "\201C""\201D""\2018""\2019"; */
175 | }
176 | /* blockquote:before { */
177 | /* color: #ccc; */
178 | /* content: open-quote; */
179 | /* font-size: 4em; */
180 | /* line-height: 0.1em; */
181 | /* margin-right: 0.25em; */
182 | /* vertical-align: -0.4em; */
183 | /* } */
184 | blockquote p {
185 | display: inline;
186 | }
187 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Viscous Demo
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
Load Data
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
Viscous
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/js/manifest.edn:
--------------------------------------------------------------------------------
1 | [{:module-id :main, :name :main, :output-name "main.js", :entries [com.phronemophobic.viscous.demo], :depends-on nil, :sources ["goog/base.js" "goog/debug/error.js" "goog/dom/nodetype.js" "goog/asserts/asserts.js" "goog/reflect/reflect.js" "goog/math/long.js" "goog/math/integer.js" "goog/dom/asserts.js" "goog/functions/functions.js" "goog/string/typedstring.js" "goog/string/const.js" "goog/i18n/bidi.js" "goog/html/trustedtypes.js" "goog/html/safescript.js" "goog/fs/url.js" "goog/fs/blob.js" "goog/html/trustedresourceurl.js" "goog/string/internal.js" "goog/html/safeurl.js" "goog/html/safestyle.js" "goog/object/object.js" "goog/html/safestylesheet.js" "goog/dom/htmlelement.js" "goog/dom/tagname.js" "goog/array/array.js" "goog/labs/useragent/useragent.js" "goog/labs/useragent/util.js" "goog/labs/useragent/browser.js" "goog/dom/tags.js" "goog/html/safehtml.js" "goog/html/uncheckedconversions.js" "goog/dom/safe.js" "goog/string/string.js" "goog/collections/maps.js" "goog/structs/structs.js" "goog/uri/utils.js" "goog/uri/uri.js" "goog/string/stringbuffer.js" "cljs/core.cljs" "membrane/ui.cljc" "goog/promise/thenable.js" "goog/async/freelist.js" "goog/async/workqueue.js" "goog/debug/entrypointregistry.js" "goog/labs/useragent/engine.js" "goog/labs/useragent/platform.js" "goog/useragent/useragent.js" "goog/dom/browserfeature.js" "goog/math/math.js" "goog/math/coordinate.js" "goog/math/size.js" "goog/dom/dom.js" "goog/async/nexttick.js" "goog/async/throwexception.js" "goog/async/run.js" "goog/promise/resolver.js" "goog/promise/promise.js" "goog/disposable/idisposable.js" "goog/disposable/dispose.js" "goog/disposable/disposeall.js" "goog/disposable/disposable.js" "goog/debug/errorcontext.js" "goog/debug/debug.js" "goog/events/eventid.js" "goog/events/event.js" "goog/events/browserfeature.js" "goog/events/eventtype.js" "goog/events/browserevent.js" "goog/events/eventlike.js" "goog/events/listenablekey.js" "goog/events/listenable.js" "goog/events/listener.js" "goog/events/listenermap.js" "goog/debug/errorhandler.js" "goog/events/eventhandler.js" "goog/events/eventwrapper.js" "goog/events/events.js" "goog/events/eventtarget.js" "goog/timer/timer.js" "goog/json/json.js" "goog/json/hybrid.js" "goog/log/log.js" "goog/net/errorcode.js" "goog/net/eventtype.js" "goog/net/httpstatus.js" "goog/net/xhrlike.js" "goog/net/xmlhttpfactory.js" "goog/net/wrapperxmlhttpfactory.js" "goog/net/xmlhttp.js" "goog/net/xhrio.js" "clojure/string.cljs" "cljs/tools/reader/impl/utils.cljs" "cljs/tools/reader/reader_types.cljs" "cljs/tools/reader/impl/inspect.cljs" "cljs/tools/reader/impl/errors.cljs" "cljs/tools/reader/impl/commons.cljs" "cljs/tools/reader.cljs" "cljs/tools/reader/edn.cljs" "cljs/reader.cljs" "clojure/edn.cljs" "com/rpl/specter/protocols.cljc" "clojure/walk.cljs" "com/rpl/specter/impl.cljc" "com/rpl/specter/navs.cljc" "clojure/set.cljs" "com/rpl/specter.cljc" "cljs/analyzer/impl.cljc" "cljs/analyzer/passes.cljc" "cljs/analyzer/passes/and_or.cljc" "cljs/env.cljc" "cljs/tagged_literals.cljc" "cljs/analyzer.cljc" "cljs/analyzer/api.cljc" "membrane/component.cljc" "membrane/basic_components.cljc" "membrane/toolkit.cljc" "com/phronemophobic/viscous.cljc" "membrane/audio.cljs" "shadow/js.js" "shadow$empty.js" "node_modules/base64-js/index.js" "node_modules/ieee754/index.js" "node_modules/isarray/index.js" "node_modules/buffer/index.js" "node_modules/opentype_DOT_js/dist/opentype.js" "membrane/webgl.cljs" "com/phronemophobic/viscous/demo.cljs" "shadow/module/main/append.js"]}]
--------------------------------------------------------------------------------
/inspector-resize.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phronmophobic/viscous/7815e80d890d1a7a26e29ff6c311cbad8c847a44/inspector-resize.gif
--------------------------------------------------------------------------------
/inspector.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phronmophobic/viscous/7815e80d890d1a7a26e29ff6c311cbad8c847a44/inspector.gif
--------------------------------------------------------------------------------
/navigation.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phronmophobic/viscous/7815e80d890d1a7a26e29ff6c311cbad8c847a44/navigation.gif
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "viscous",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "viscous",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "buffer": "4.9.2",
13 | "opentype.js": "1.3.4"
14 | },
15 | "devDependencies": {
16 | "shadow-cljs": "^2.16.12"
17 | }
18 | },
19 | "node_modules/asn1.js": {
20 | "version": "5.4.1",
21 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
22 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
23 | "dev": true,
24 | "dependencies": {
25 | "bn.js": "^4.0.0",
26 | "inherits": "^2.0.1",
27 | "minimalistic-assert": "^1.0.0",
28 | "safer-buffer": "^2.1.0"
29 | }
30 | },
31 | "node_modules/asn1.js/node_modules/bn.js": {
32 | "version": "4.12.0",
33 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
34 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
35 | "dev": true
36 | },
37 | "node_modules/assert": {
38 | "version": "1.5.0",
39 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
40 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
41 | "dev": true,
42 | "dependencies": {
43 | "object-assign": "^4.1.1",
44 | "util": "0.10.3"
45 | }
46 | },
47 | "node_modules/assert/node_modules/inherits": {
48 | "version": "2.0.1",
49 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
50 | "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
51 | "dev": true
52 | },
53 | "node_modules/assert/node_modules/util": {
54 | "version": "0.10.3",
55 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
56 | "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
57 | "dev": true,
58 | "dependencies": {
59 | "inherits": "2.0.1"
60 | }
61 | },
62 | "node_modules/base64-js": {
63 | "version": "1.5.1",
64 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
65 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
66 | "funding": [
67 | {
68 | "type": "github",
69 | "url": "https://github.com/sponsors/feross"
70 | },
71 | {
72 | "type": "patreon",
73 | "url": "https://www.patreon.com/feross"
74 | },
75 | {
76 | "type": "consulting",
77 | "url": "https://feross.org/support"
78 | }
79 | ]
80 | },
81 | "node_modules/bn.js": {
82 | "version": "5.2.0",
83 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
84 | "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==",
85 | "dev": true
86 | },
87 | "node_modules/brorand": {
88 | "version": "1.1.0",
89 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
90 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
91 | "dev": true
92 | },
93 | "node_modules/browserify-aes": {
94 | "version": "1.2.0",
95 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
96 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
97 | "dev": true,
98 | "dependencies": {
99 | "buffer-xor": "^1.0.3",
100 | "cipher-base": "^1.0.0",
101 | "create-hash": "^1.1.0",
102 | "evp_bytestokey": "^1.0.3",
103 | "inherits": "^2.0.1",
104 | "safe-buffer": "^5.0.1"
105 | }
106 | },
107 | "node_modules/browserify-cipher": {
108 | "version": "1.0.1",
109 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
110 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
111 | "dev": true,
112 | "dependencies": {
113 | "browserify-aes": "^1.0.4",
114 | "browserify-des": "^1.0.0",
115 | "evp_bytestokey": "^1.0.0"
116 | }
117 | },
118 | "node_modules/browserify-des": {
119 | "version": "1.0.2",
120 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
121 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
122 | "dev": true,
123 | "dependencies": {
124 | "cipher-base": "^1.0.1",
125 | "des.js": "^1.0.0",
126 | "inherits": "^2.0.1",
127 | "safe-buffer": "^5.1.2"
128 | }
129 | },
130 | "node_modules/browserify-rsa": {
131 | "version": "4.1.0",
132 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
133 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
134 | "dev": true,
135 | "dependencies": {
136 | "bn.js": "^5.0.0",
137 | "randombytes": "^2.0.1"
138 | }
139 | },
140 | "node_modules/browserify-sign": {
141 | "version": "4.2.1",
142 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
143 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
144 | "dev": true,
145 | "dependencies": {
146 | "bn.js": "^5.1.1",
147 | "browserify-rsa": "^4.0.1",
148 | "create-hash": "^1.2.0",
149 | "create-hmac": "^1.1.7",
150 | "elliptic": "^6.5.3",
151 | "inherits": "^2.0.4",
152 | "parse-asn1": "^5.1.5",
153 | "readable-stream": "^3.6.0",
154 | "safe-buffer": "^5.2.0"
155 | }
156 | },
157 | "node_modules/browserify-sign/node_modules/readable-stream": {
158 | "version": "3.6.0",
159 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
160 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
161 | "dev": true,
162 | "dependencies": {
163 | "inherits": "^2.0.3",
164 | "string_decoder": "^1.1.1",
165 | "util-deprecate": "^1.0.1"
166 | },
167 | "engines": {
168 | "node": ">= 6"
169 | }
170 | },
171 | "node_modules/browserify-zlib": {
172 | "version": "0.2.0",
173 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
174 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
175 | "dev": true,
176 | "dependencies": {
177 | "pako": "~1.0.5"
178 | }
179 | },
180 | "node_modules/buffer": {
181 | "version": "4.9.2",
182 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
183 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
184 | "dependencies": {
185 | "base64-js": "^1.0.2",
186 | "ieee754": "^1.1.4",
187 | "isarray": "^1.0.0"
188 | }
189 | },
190 | "node_modules/buffer-xor": {
191 | "version": "1.0.3",
192 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
193 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
194 | "dev": true
195 | },
196 | "node_modules/builtin-status-codes": {
197 | "version": "3.0.0",
198 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
199 | "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
200 | "dev": true
201 | },
202 | "node_modules/cipher-base": {
203 | "version": "1.0.4",
204 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
205 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
206 | "dev": true,
207 | "dependencies": {
208 | "inherits": "^2.0.1",
209 | "safe-buffer": "^5.0.1"
210 | }
211 | },
212 | "node_modules/console-browserify": {
213 | "version": "1.2.0",
214 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
215 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
216 | "dev": true
217 | },
218 | "node_modules/constants-browserify": {
219 | "version": "1.0.0",
220 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
221 | "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
222 | "dev": true
223 | },
224 | "node_modules/core-util-is": {
225 | "version": "1.0.3",
226 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
227 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
228 | "dev": true
229 | },
230 | "node_modules/create-ecdh": {
231 | "version": "4.0.4",
232 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
233 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
234 | "dev": true,
235 | "dependencies": {
236 | "bn.js": "^4.1.0",
237 | "elliptic": "^6.5.3"
238 | }
239 | },
240 | "node_modules/create-ecdh/node_modules/bn.js": {
241 | "version": "4.12.0",
242 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
243 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
244 | "dev": true
245 | },
246 | "node_modules/create-hash": {
247 | "version": "1.2.0",
248 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
249 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
250 | "dev": true,
251 | "dependencies": {
252 | "cipher-base": "^1.0.1",
253 | "inherits": "^2.0.1",
254 | "md5.js": "^1.3.4",
255 | "ripemd160": "^2.0.1",
256 | "sha.js": "^2.4.0"
257 | }
258 | },
259 | "node_modules/create-hmac": {
260 | "version": "1.1.7",
261 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
262 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
263 | "dev": true,
264 | "dependencies": {
265 | "cipher-base": "^1.0.3",
266 | "create-hash": "^1.1.0",
267 | "inherits": "^2.0.1",
268 | "ripemd160": "^2.0.0",
269 | "safe-buffer": "^5.0.1",
270 | "sha.js": "^2.4.8"
271 | }
272 | },
273 | "node_modules/crypto-browserify": {
274 | "version": "3.12.0",
275 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
276 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
277 | "dev": true,
278 | "dependencies": {
279 | "browserify-cipher": "^1.0.0",
280 | "browserify-sign": "^4.0.0",
281 | "create-ecdh": "^4.0.0",
282 | "create-hash": "^1.1.0",
283 | "create-hmac": "^1.1.0",
284 | "diffie-hellman": "^5.0.0",
285 | "inherits": "^2.0.1",
286 | "pbkdf2": "^3.0.3",
287 | "public-encrypt": "^4.0.0",
288 | "randombytes": "^2.0.0",
289 | "randomfill": "^1.0.3"
290 | },
291 | "engines": {
292 | "node": "*"
293 | }
294 | },
295 | "node_modules/des.js": {
296 | "version": "1.0.1",
297 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
298 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
299 | "dev": true,
300 | "dependencies": {
301 | "inherits": "^2.0.1",
302 | "minimalistic-assert": "^1.0.0"
303 | }
304 | },
305 | "node_modules/diffie-hellman": {
306 | "version": "5.0.3",
307 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
308 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
309 | "dev": true,
310 | "dependencies": {
311 | "bn.js": "^4.1.0",
312 | "miller-rabin": "^4.0.0",
313 | "randombytes": "^2.0.0"
314 | }
315 | },
316 | "node_modules/diffie-hellman/node_modules/bn.js": {
317 | "version": "4.12.0",
318 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
319 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
320 | "dev": true
321 | },
322 | "node_modules/domain-browser": {
323 | "version": "1.2.0",
324 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
325 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
326 | "dev": true,
327 | "engines": {
328 | "node": ">=0.4",
329 | "npm": ">=1.2"
330 | }
331 | },
332 | "node_modules/elliptic": {
333 | "version": "6.5.4",
334 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
335 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
336 | "dev": true,
337 | "dependencies": {
338 | "bn.js": "^4.11.9",
339 | "brorand": "^1.1.0",
340 | "hash.js": "^1.0.0",
341 | "hmac-drbg": "^1.0.1",
342 | "inherits": "^2.0.4",
343 | "minimalistic-assert": "^1.0.1",
344 | "minimalistic-crypto-utils": "^1.0.1"
345 | }
346 | },
347 | "node_modules/elliptic/node_modules/bn.js": {
348 | "version": "4.12.0",
349 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
350 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
351 | "dev": true
352 | },
353 | "node_modules/events": {
354 | "version": "3.3.0",
355 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
356 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
357 | "dev": true,
358 | "engines": {
359 | "node": ">=0.8.x"
360 | }
361 | },
362 | "node_modules/evp_bytestokey": {
363 | "version": "1.0.3",
364 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
365 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
366 | "dev": true,
367 | "dependencies": {
368 | "md5.js": "^1.3.4",
369 | "safe-buffer": "^5.1.1"
370 | }
371 | },
372 | "node_modules/hash-base": {
373 | "version": "3.1.0",
374 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
375 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
376 | "dev": true,
377 | "dependencies": {
378 | "inherits": "^2.0.4",
379 | "readable-stream": "^3.6.0",
380 | "safe-buffer": "^5.2.0"
381 | },
382 | "engines": {
383 | "node": ">=4"
384 | }
385 | },
386 | "node_modules/hash-base/node_modules/readable-stream": {
387 | "version": "3.6.0",
388 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
389 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
390 | "dev": true,
391 | "dependencies": {
392 | "inherits": "^2.0.3",
393 | "string_decoder": "^1.1.1",
394 | "util-deprecate": "^1.0.1"
395 | },
396 | "engines": {
397 | "node": ">= 6"
398 | }
399 | },
400 | "node_modules/hash.js": {
401 | "version": "1.1.7",
402 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
403 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
404 | "dev": true,
405 | "dependencies": {
406 | "inherits": "^2.0.3",
407 | "minimalistic-assert": "^1.0.1"
408 | }
409 | },
410 | "node_modules/hmac-drbg": {
411 | "version": "1.0.1",
412 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
413 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
414 | "dev": true,
415 | "dependencies": {
416 | "hash.js": "^1.0.3",
417 | "minimalistic-assert": "^1.0.0",
418 | "minimalistic-crypto-utils": "^1.0.1"
419 | }
420 | },
421 | "node_modules/https-browserify": {
422 | "version": "1.0.0",
423 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
424 | "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
425 | "dev": true
426 | },
427 | "node_modules/ieee754": {
428 | "version": "1.2.1",
429 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
430 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
431 | "funding": [
432 | {
433 | "type": "github",
434 | "url": "https://github.com/sponsors/feross"
435 | },
436 | {
437 | "type": "patreon",
438 | "url": "https://www.patreon.com/feross"
439 | },
440 | {
441 | "type": "consulting",
442 | "url": "https://feross.org/support"
443 | }
444 | ]
445 | },
446 | "node_modules/inherits": {
447 | "version": "2.0.4",
448 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
449 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
450 | "dev": true
451 | },
452 | "node_modules/isarray": {
453 | "version": "1.0.0",
454 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
455 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
456 | },
457 | "node_modules/isexe": {
458 | "version": "2.0.0",
459 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
460 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
461 | "dev": true
462 | },
463 | "node_modules/md5.js": {
464 | "version": "1.3.5",
465 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
466 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
467 | "dev": true,
468 | "dependencies": {
469 | "hash-base": "^3.0.0",
470 | "inherits": "^2.0.1",
471 | "safe-buffer": "^5.1.2"
472 | }
473 | },
474 | "node_modules/miller-rabin": {
475 | "version": "4.0.1",
476 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
477 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
478 | "dev": true,
479 | "dependencies": {
480 | "bn.js": "^4.0.0",
481 | "brorand": "^1.0.1"
482 | },
483 | "bin": {
484 | "miller-rabin": "bin/miller-rabin"
485 | }
486 | },
487 | "node_modules/miller-rabin/node_modules/bn.js": {
488 | "version": "4.12.0",
489 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
490 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
491 | "dev": true
492 | },
493 | "node_modules/minimalistic-assert": {
494 | "version": "1.0.1",
495 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
496 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
497 | "dev": true
498 | },
499 | "node_modules/minimalistic-crypto-utils": {
500 | "version": "1.0.1",
501 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
502 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
503 | "dev": true
504 | },
505 | "node_modules/node-libs-browser": {
506 | "version": "2.2.1",
507 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
508 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
509 | "dev": true,
510 | "dependencies": {
511 | "assert": "^1.1.1",
512 | "browserify-zlib": "^0.2.0",
513 | "buffer": "^4.3.0",
514 | "console-browserify": "^1.1.0",
515 | "constants-browserify": "^1.0.0",
516 | "crypto-browserify": "^3.11.0",
517 | "domain-browser": "^1.1.1",
518 | "events": "^3.0.0",
519 | "https-browserify": "^1.0.0",
520 | "os-browserify": "^0.3.0",
521 | "path-browserify": "0.0.1",
522 | "process": "^0.11.10",
523 | "punycode": "^1.2.4",
524 | "querystring-es3": "^0.2.0",
525 | "readable-stream": "^2.3.3",
526 | "stream-browserify": "^2.0.1",
527 | "stream-http": "^2.7.2",
528 | "string_decoder": "^1.0.0",
529 | "timers-browserify": "^2.0.4",
530 | "tty-browserify": "0.0.0",
531 | "url": "^0.11.0",
532 | "util": "^0.11.0",
533 | "vm-browserify": "^1.0.1"
534 | }
535 | },
536 | "node_modules/object-assign": {
537 | "version": "4.1.1",
538 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
539 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
540 | "dev": true,
541 | "engines": {
542 | "node": ">=0.10.0"
543 | }
544 | },
545 | "node_modules/opentype.js": {
546 | "version": "1.3.4",
547 | "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
548 | "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
549 | "dependencies": {
550 | "string.prototype.codepointat": "^0.2.1",
551 | "tiny-inflate": "^1.0.3"
552 | },
553 | "bin": {
554 | "ot": "bin/ot"
555 | },
556 | "engines": {
557 | "node": ">= 8.0.0"
558 | }
559 | },
560 | "node_modules/os-browserify": {
561 | "version": "0.3.0",
562 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
563 | "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
564 | "dev": true
565 | },
566 | "node_modules/pako": {
567 | "version": "1.0.11",
568 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
569 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
570 | "dev": true
571 | },
572 | "node_modules/parse-asn1": {
573 | "version": "5.1.6",
574 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
575 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
576 | "dev": true,
577 | "dependencies": {
578 | "asn1.js": "^5.2.0",
579 | "browserify-aes": "^1.0.0",
580 | "evp_bytestokey": "^1.0.0",
581 | "pbkdf2": "^3.0.3",
582 | "safe-buffer": "^5.1.1"
583 | }
584 | },
585 | "node_modules/path-browserify": {
586 | "version": "0.0.1",
587 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
588 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
589 | "dev": true
590 | },
591 | "node_modules/pbkdf2": {
592 | "version": "3.1.2",
593 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
594 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
595 | "dev": true,
596 | "dependencies": {
597 | "create-hash": "^1.1.2",
598 | "create-hmac": "^1.1.4",
599 | "ripemd160": "^2.0.1",
600 | "safe-buffer": "^5.0.1",
601 | "sha.js": "^2.4.8"
602 | },
603 | "engines": {
604 | "node": ">=0.12"
605 | }
606 | },
607 | "node_modules/process": {
608 | "version": "0.11.10",
609 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
610 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
611 | "dev": true,
612 | "engines": {
613 | "node": ">= 0.6.0"
614 | }
615 | },
616 | "node_modules/process-nextick-args": {
617 | "version": "2.0.1",
618 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
619 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
620 | "dev": true
621 | },
622 | "node_modules/public-encrypt": {
623 | "version": "4.0.3",
624 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
625 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
626 | "dev": true,
627 | "dependencies": {
628 | "bn.js": "^4.1.0",
629 | "browserify-rsa": "^4.0.0",
630 | "create-hash": "^1.1.0",
631 | "parse-asn1": "^5.0.0",
632 | "randombytes": "^2.0.1",
633 | "safe-buffer": "^5.1.2"
634 | }
635 | },
636 | "node_modules/public-encrypt/node_modules/bn.js": {
637 | "version": "4.12.0",
638 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
639 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
640 | "dev": true
641 | },
642 | "node_modules/punycode": {
643 | "version": "1.4.1",
644 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
645 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
646 | "dev": true
647 | },
648 | "node_modules/querystring": {
649 | "version": "0.2.0",
650 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
651 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
652 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
653 | "dev": true,
654 | "engines": {
655 | "node": ">=0.4.x"
656 | }
657 | },
658 | "node_modules/querystring-es3": {
659 | "version": "0.2.1",
660 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
661 | "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
662 | "dev": true,
663 | "engines": {
664 | "node": ">=0.4.x"
665 | }
666 | },
667 | "node_modules/randombytes": {
668 | "version": "2.1.0",
669 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
670 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
671 | "dev": true,
672 | "dependencies": {
673 | "safe-buffer": "^5.1.0"
674 | }
675 | },
676 | "node_modules/randomfill": {
677 | "version": "1.0.4",
678 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
679 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
680 | "dev": true,
681 | "dependencies": {
682 | "randombytes": "^2.0.5",
683 | "safe-buffer": "^5.1.0"
684 | }
685 | },
686 | "node_modules/readable-stream": {
687 | "version": "2.3.7",
688 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
689 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
690 | "dev": true,
691 | "dependencies": {
692 | "core-util-is": "~1.0.0",
693 | "inherits": "~2.0.3",
694 | "isarray": "~1.0.0",
695 | "process-nextick-args": "~2.0.0",
696 | "safe-buffer": "~5.1.1",
697 | "string_decoder": "~1.1.1",
698 | "util-deprecate": "~1.0.1"
699 | }
700 | },
701 | "node_modules/readable-stream/node_modules/safe-buffer": {
702 | "version": "5.1.2",
703 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
704 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
705 | "dev": true
706 | },
707 | "node_modules/readable-stream/node_modules/string_decoder": {
708 | "version": "1.1.1",
709 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
710 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
711 | "dev": true,
712 | "dependencies": {
713 | "safe-buffer": "~5.1.0"
714 | }
715 | },
716 | "node_modules/readline-sync": {
717 | "version": "1.4.10",
718 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
719 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
720 | "dev": true,
721 | "engines": {
722 | "node": ">= 0.8.0"
723 | }
724 | },
725 | "node_modules/ripemd160": {
726 | "version": "2.0.2",
727 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
728 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
729 | "dev": true,
730 | "dependencies": {
731 | "hash-base": "^3.0.0",
732 | "inherits": "^2.0.1"
733 | }
734 | },
735 | "node_modules/safe-buffer": {
736 | "version": "5.2.1",
737 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
738 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
739 | "dev": true,
740 | "funding": [
741 | {
742 | "type": "github",
743 | "url": "https://github.com/sponsors/feross"
744 | },
745 | {
746 | "type": "patreon",
747 | "url": "https://www.patreon.com/feross"
748 | },
749 | {
750 | "type": "consulting",
751 | "url": "https://feross.org/support"
752 | }
753 | ]
754 | },
755 | "node_modules/safer-buffer": {
756 | "version": "2.1.2",
757 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
758 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
759 | "dev": true
760 | },
761 | "node_modules/setimmediate": {
762 | "version": "1.0.5",
763 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
764 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
765 | "dev": true
766 | },
767 | "node_modules/sha.js": {
768 | "version": "2.4.11",
769 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
770 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
771 | "dev": true,
772 | "dependencies": {
773 | "inherits": "^2.0.1",
774 | "safe-buffer": "^5.0.1"
775 | },
776 | "bin": {
777 | "sha.js": "bin.js"
778 | }
779 | },
780 | "node_modules/shadow-cljs": {
781 | "version": "2.16.12",
782 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.16.12.tgz",
783 | "integrity": "sha512-6JqOhN5X3n0IkxA/gSUcZ1lImwcW1LmpgzlaBDOC/u/pIysdNm0tiOxpOTEnExl9nKZBS/EYS7bXIIInywPJUA==",
784 | "dev": true,
785 | "dependencies": {
786 | "node-libs-browser": "^2.2.1",
787 | "readline-sync": "^1.4.7",
788 | "shadow-cljs-jar": "1.3.2",
789 | "source-map-support": "^0.4.15",
790 | "which": "^1.3.1",
791 | "ws": "^7.4.6"
792 | },
793 | "bin": {
794 | "shadow-cljs": "cli/runner.js"
795 | },
796 | "engines": {
797 | "node": ">=6.0.0"
798 | }
799 | },
800 | "node_modules/shadow-cljs-jar": {
801 | "version": "1.3.2",
802 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz",
803 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==",
804 | "dev": true
805 | },
806 | "node_modules/source-map": {
807 | "version": "0.5.7",
808 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
809 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
810 | "dev": true,
811 | "engines": {
812 | "node": ">=0.10.0"
813 | }
814 | },
815 | "node_modules/source-map-support": {
816 | "version": "0.4.18",
817 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
818 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
819 | "dev": true,
820 | "dependencies": {
821 | "source-map": "^0.5.6"
822 | }
823 | },
824 | "node_modules/stream-browserify": {
825 | "version": "2.0.2",
826 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
827 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
828 | "dev": true,
829 | "dependencies": {
830 | "inherits": "~2.0.1",
831 | "readable-stream": "^2.0.2"
832 | }
833 | },
834 | "node_modules/stream-http": {
835 | "version": "2.8.3",
836 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
837 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
838 | "dev": true,
839 | "dependencies": {
840 | "builtin-status-codes": "^3.0.0",
841 | "inherits": "^2.0.1",
842 | "readable-stream": "^2.3.6",
843 | "to-arraybuffer": "^1.0.0",
844 | "xtend": "^4.0.0"
845 | }
846 | },
847 | "node_modules/string_decoder": {
848 | "version": "1.3.0",
849 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
850 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
851 | "dev": true,
852 | "dependencies": {
853 | "safe-buffer": "~5.2.0"
854 | }
855 | },
856 | "node_modules/string.prototype.codepointat": {
857 | "version": "0.2.1",
858 | "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
859 | "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
860 | },
861 | "node_modules/timers-browserify": {
862 | "version": "2.0.12",
863 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
864 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
865 | "dev": true,
866 | "dependencies": {
867 | "setimmediate": "^1.0.4"
868 | },
869 | "engines": {
870 | "node": ">=0.6.0"
871 | }
872 | },
873 | "node_modules/tiny-inflate": {
874 | "version": "1.0.3",
875 | "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
876 | "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
877 | },
878 | "node_modules/to-arraybuffer": {
879 | "version": "1.0.1",
880 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
881 | "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
882 | "dev": true
883 | },
884 | "node_modules/tty-browserify": {
885 | "version": "0.0.0",
886 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
887 | "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
888 | "dev": true
889 | },
890 | "node_modules/url": {
891 | "version": "0.11.0",
892 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
893 | "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
894 | "dev": true,
895 | "dependencies": {
896 | "punycode": "1.3.2",
897 | "querystring": "0.2.0"
898 | }
899 | },
900 | "node_modules/url/node_modules/punycode": {
901 | "version": "1.3.2",
902 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
903 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
904 | "dev": true
905 | },
906 | "node_modules/util": {
907 | "version": "0.11.1",
908 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
909 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
910 | "dev": true,
911 | "dependencies": {
912 | "inherits": "2.0.3"
913 | }
914 | },
915 | "node_modules/util-deprecate": {
916 | "version": "1.0.2",
917 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
918 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
919 | "dev": true
920 | },
921 | "node_modules/util/node_modules/inherits": {
922 | "version": "2.0.3",
923 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
924 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
925 | "dev": true
926 | },
927 | "node_modules/vm-browserify": {
928 | "version": "1.1.2",
929 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
930 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
931 | "dev": true
932 | },
933 | "node_modules/which": {
934 | "version": "1.3.1",
935 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
936 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
937 | "dev": true,
938 | "dependencies": {
939 | "isexe": "^2.0.0"
940 | },
941 | "bin": {
942 | "which": "bin/which"
943 | }
944 | },
945 | "node_modules/ws": {
946 | "version": "7.5.6",
947 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
948 | "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
949 | "dev": true,
950 | "engines": {
951 | "node": ">=8.3.0"
952 | },
953 | "peerDependencies": {
954 | "bufferutil": "^4.0.1",
955 | "utf-8-validate": "^5.0.2"
956 | },
957 | "peerDependenciesMeta": {
958 | "bufferutil": {
959 | "optional": true
960 | },
961 | "utf-8-validate": {
962 | "optional": true
963 | }
964 | }
965 | },
966 | "node_modules/xtend": {
967 | "version": "4.0.2",
968 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
969 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
970 | "dev": true,
971 | "engines": {
972 | "node": ">=0.4"
973 | }
974 | }
975 | },
976 | "dependencies": {
977 | "asn1.js": {
978 | "version": "5.4.1",
979 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
980 | "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
981 | "dev": true,
982 | "requires": {
983 | "bn.js": "^4.0.0",
984 | "inherits": "^2.0.1",
985 | "minimalistic-assert": "^1.0.0",
986 | "safer-buffer": "^2.1.0"
987 | },
988 | "dependencies": {
989 | "bn.js": {
990 | "version": "4.12.0",
991 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
992 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
993 | "dev": true
994 | }
995 | }
996 | },
997 | "assert": {
998 | "version": "1.5.0",
999 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
1000 | "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
1001 | "dev": true,
1002 | "requires": {
1003 | "object-assign": "^4.1.1",
1004 | "util": "0.10.3"
1005 | },
1006 | "dependencies": {
1007 | "inherits": {
1008 | "version": "2.0.1",
1009 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
1010 | "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
1011 | "dev": true
1012 | },
1013 | "util": {
1014 | "version": "0.10.3",
1015 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
1016 | "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
1017 | "dev": true,
1018 | "requires": {
1019 | "inherits": "2.0.1"
1020 | }
1021 | }
1022 | }
1023 | },
1024 | "base64-js": {
1025 | "version": "1.5.1",
1026 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
1027 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
1028 | },
1029 | "bn.js": {
1030 | "version": "5.2.0",
1031 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
1032 | "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==",
1033 | "dev": true
1034 | },
1035 | "brorand": {
1036 | "version": "1.1.0",
1037 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
1038 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
1039 | "dev": true
1040 | },
1041 | "browserify-aes": {
1042 | "version": "1.2.0",
1043 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
1044 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
1045 | "dev": true,
1046 | "requires": {
1047 | "buffer-xor": "^1.0.3",
1048 | "cipher-base": "^1.0.0",
1049 | "create-hash": "^1.1.0",
1050 | "evp_bytestokey": "^1.0.3",
1051 | "inherits": "^2.0.1",
1052 | "safe-buffer": "^5.0.1"
1053 | }
1054 | },
1055 | "browserify-cipher": {
1056 | "version": "1.0.1",
1057 | "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
1058 | "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
1059 | "dev": true,
1060 | "requires": {
1061 | "browserify-aes": "^1.0.4",
1062 | "browserify-des": "^1.0.0",
1063 | "evp_bytestokey": "^1.0.0"
1064 | }
1065 | },
1066 | "browserify-des": {
1067 | "version": "1.0.2",
1068 | "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
1069 | "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
1070 | "dev": true,
1071 | "requires": {
1072 | "cipher-base": "^1.0.1",
1073 | "des.js": "^1.0.0",
1074 | "inherits": "^2.0.1",
1075 | "safe-buffer": "^5.1.2"
1076 | }
1077 | },
1078 | "browserify-rsa": {
1079 | "version": "4.1.0",
1080 | "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
1081 | "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
1082 | "dev": true,
1083 | "requires": {
1084 | "bn.js": "^5.0.0",
1085 | "randombytes": "^2.0.1"
1086 | }
1087 | },
1088 | "browserify-sign": {
1089 | "version": "4.2.1",
1090 | "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
1091 | "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
1092 | "dev": true,
1093 | "requires": {
1094 | "bn.js": "^5.1.1",
1095 | "browserify-rsa": "^4.0.1",
1096 | "create-hash": "^1.2.0",
1097 | "create-hmac": "^1.1.7",
1098 | "elliptic": "^6.5.3",
1099 | "inherits": "^2.0.4",
1100 | "parse-asn1": "^5.1.5",
1101 | "readable-stream": "^3.6.0",
1102 | "safe-buffer": "^5.2.0"
1103 | },
1104 | "dependencies": {
1105 | "readable-stream": {
1106 | "version": "3.6.0",
1107 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1108 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1109 | "dev": true,
1110 | "requires": {
1111 | "inherits": "^2.0.3",
1112 | "string_decoder": "^1.1.1",
1113 | "util-deprecate": "^1.0.1"
1114 | }
1115 | }
1116 | }
1117 | },
1118 | "browserify-zlib": {
1119 | "version": "0.2.0",
1120 | "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
1121 | "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
1122 | "dev": true,
1123 | "requires": {
1124 | "pako": "~1.0.5"
1125 | }
1126 | },
1127 | "buffer": {
1128 | "version": "4.9.2",
1129 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
1130 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
1131 | "requires": {
1132 | "base64-js": "^1.0.2",
1133 | "ieee754": "^1.1.4",
1134 | "isarray": "^1.0.0"
1135 | }
1136 | },
1137 | "buffer-xor": {
1138 | "version": "1.0.3",
1139 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
1140 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
1141 | "dev": true
1142 | },
1143 | "builtin-status-codes": {
1144 | "version": "3.0.0",
1145 | "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
1146 | "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
1147 | "dev": true
1148 | },
1149 | "cipher-base": {
1150 | "version": "1.0.4",
1151 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
1152 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
1153 | "dev": true,
1154 | "requires": {
1155 | "inherits": "^2.0.1",
1156 | "safe-buffer": "^5.0.1"
1157 | }
1158 | },
1159 | "console-browserify": {
1160 | "version": "1.2.0",
1161 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
1162 | "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
1163 | "dev": true
1164 | },
1165 | "constants-browserify": {
1166 | "version": "1.0.0",
1167 | "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
1168 | "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
1169 | "dev": true
1170 | },
1171 | "core-util-is": {
1172 | "version": "1.0.3",
1173 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
1174 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
1175 | "dev": true
1176 | },
1177 | "create-ecdh": {
1178 | "version": "4.0.4",
1179 | "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
1180 | "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
1181 | "dev": true,
1182 | "requires": {
1183 | "bn.js": "^4.1.0",
1184 | "elliptic": "^6.5.3"
1185 | },
1186 | "dependencies": {
1187 | "bn.js": {
1188 | "version": "4.12.0",
1189 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1190 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1191 | "dev": true
1192 | }
1193 | }
1194 | },
1195 | "create-hash": {
1196 | "version": "1.2.0",
1197 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
1198 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
1199 | "dev": true,
1200 | "requires": {
1201 | "cipher-base": "^1.0.1",
1202 | "inherits": "^2.0.1",
1203 | "md5.js": "^1.3.4",
1204 | "ripemd160": "^2.0.1",
1205 | "sha.js": "^2.4.0"
1206 | }
1207 | },
1208 | "create-hmac": {
1209 | "version": "1.1.7",
1210 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
1211 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
1212 | "dev": true,
1213 | "requires": {
1214 | "cipher-base": "^1.0.3",
1215 | "create-hash": "^1.1.0",
1216 | "inherits": "^2.0.1",
1217 | "ripemd160": "^2.0.0",
1218 | "safe-buffer": "^5.0.1",
1219 | "sha.js": "^2.4.8"
1220 | }
1221 | },
1222 | "crypto-browserify": {
1223 | "version": "3.12.0",
1224 | "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
1225 | "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
1226 | "dev": true,
1227 | "requires": {
1228 | "browserify-cipher": "^1.0.0",
1229 | "browserify-sign": "^4.0.0",
1230 | "create-ecdh": "^4.0.0",
1231 | "create-hash": "^1.1.0",
1232 | "create-hmac": "^1.1.0",
1233 | "diffie-hellman": "^5.0.0",
1234 | "inherits": "^2.0.1",
1235 | "pbkdf2": "^3.0.3",
1236 | "public-encrypt": "^4.0.0",
1237 | "randombytes": "^2.0.0",
1238 | "randomfill": "^1.0.3"
1239 | }
1240 | },
1241 | "des.js": {
1242 | "version": "1.0.1",
1243 | "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
1244 | "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
1245 | "dev": true,
1246 | "requires": {
1247 | "inherits": "^2.0.1",
1248 | "minimalistic-assert": "^1.0.0"
1249 | }
1250 | },
1251 | "diffie-hellman": {
1252 | "version": "5.0.3",
1253 | "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
1254 | "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
1255 | "dev": true,
1256 | "requires": {
1257 | "bn.js": "^4.1.0",
1258 | "miller-rabin": "^4.0.0",
1259 | "randombytes": "^2.0.0"
1260 | },
1261 | "dependencies": {
1262 | "bn.js": {
1263 | "version": "4.12.0",
1264 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1265 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1266 | "dev": true
1267 | }
1268 | }
1269 | },
1270 | "domain-browser": {
1271 | "version": "1.2.0",
1272 | "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
1273 | "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
1274 | "dev": true
1275 | },
1276 | "elliptic": {
1277 | "version": "6.5.4",
1278 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
1279 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
1280 | "dev": true,
1281 | "requires": {
1282 | "bn.js": "^4.11.9",
1283 | "brorand": "^1.1.0",
1284 | "hash.js": "^1.0.0",
1285 | "hmac-drbg": "^1.0.1",
1286 | "inherits": "^2.0.4",
1287 | "minimalistic-assert": "^1.0.1",
1288 | "minimalistic-crypto-utils": "^1.0.1"
1289 | },
1290 | "dependencies": {
1291 | "bn.js": {
1292 | "version": "4.12.0",
1293 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1294 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1295 | "dev": true
1296 | }
1297 | }
1298 | },
1299 | "events": {
1300 | "version": "3.3.0",
1301 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
1302 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
1303 | "dev": true
1304 | },
1305 | "evp_bytestokey": {
1306 | "version": "1.0.3",
1307 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
1308 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
1309 | "dev": true,
1310 | "requires": {
1311 | "md5.js": "^1.3.4",
1312 | "safe-buffer": "^5.1.1"
1313 | }
1314 | },
1315 | "hash-base": {
1316 | "version": "3.1.0",
1317 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
1318 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
1319 | "dev": true,
1320 | "requires": {
1321 | "inherits": "^2.0.4",
1322 | "readable-stream": "^3.6.0",
1323 | "safe-buffer": "^5.2.0"
1324 | },
1325 | "dependencies": {
1326 | "readable-stream": {
1327 | "version": "3.6.0",
1328 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
1329 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
1330 | "dev": true,
1331 | "requires": {
1332 | "inherits": "^2.0.3",
1333 | "string_decoder": "^1.1.1",
1334 | "util-deprecate": "^1.0.1"
1335 | }
1336 | }
1337 | }
1338 | },
1339 | "hash.js": {
1340 | "version": "1.1.7",
1341 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
1342 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
1343 | "dev": true,
1344 | "requires": {
1345 | "inherits": "^2.0.3",
1346 | "minimalistic-assert": "^1.0.1"
1347 | }
1348 | },
1349 | "hmac-drbg": {
1350 | "version": "1.0.1",
1351 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
1352 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
1353 | "dev": true,
1354 | "requires": {
1355 | "hash.js": "^1.0.3",
1356 | "minimalistic-assert": "^1.0.0",
1357 | "minimalistic-crypto-utils": "^1.0.1"
1358 | }
1359 | },
1360 | "https-browserify": {
1361 | "version": "1.0.0",
1362 | "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
1363 | "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
1364 | "dev": true
1365 | },
1366 | "ieee754": {
1367 | "version": "1.2.1",
1368 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1369 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
1370 | },
1371 | "inherits": {
1372 | "version": "2.0.4",
1373 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1374 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1375 | "dev": true
1376 | },
1377 | "isarray": {
1378 | "version": "1.0.0",
1379 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1380 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1381 | },
1382 | "isexe": {
1383 | "version": "2.0.0",
1384 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1385 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1386 | "dev": true
1387 | },
1388 | "md5.js": {
1389 | "version": "1.3.5",
1390 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
1391 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
1392 | "dev": true,
1393 | "requires": {
1394 | "hash-base": "^3.0.0",
1395 | "inherits": "^2.0.1",
1396 | "safe-buffer": "^5.1.2"
1397 | }
1398 | },
1399 | "miller-rabin": {
1400 | "version": "4.0.1",
1401 | "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
1402 | "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
1403 | "dev": true,
1404 | "requires": {
1405 | "bn.js": "^4.0.0",
1406 | "brorand": "^1.0.1"
1407 | },
1408 | "dependencies": {
1409 | "bn.js": {
1410 | "version": "4.12.0",
1411 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1412 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1413 | "dev": true
1414 | }
1415 | }
1416 | },
1417 | "minimalistic-assert": {
1418 | "version": "1.0.1",
1419 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
1420 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
1421 | "dev": true
1422 | },
1423 | "minimalistic-crypto-utils": {
1424 | "version": "1.0.1",
1425 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
1426 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
1427 | "dev": true
1428 | },
1429 | "node-libs-browser": {
1430 | "version": "2.2.1",
1431 | "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
1432 | "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
1433 | "dev": true,
1434 | "requires": {
1435 | "assert": "^1.1.1",
1436 | "browserify-zlib": "^0.2.0",
1437 | "buffer": "^4.3.0",
1438 | "console-browserify": "^1.1.0",
1439 | "constants-browserify": "^1.0.0",
1440 | "crypto-browserify": "^3.11.0",
1441 | "domain-browser": "^1.1.1",
1442 | "events": "^3.0.0",
1443 | "https-browserify": "^1.0.0",
1444 | "os-browserify": "^0.3.0",
1445 | "path-browserify": "0.0.1",
1446 | "process": "^0.11.10",
1447 | "punycode": "^1.2.4",
1448 | "querystring-es3": "^0.2.0",
1449 | "readable-stream": "^2.3.3",
1450 | "stream-browserify": "^2.0.1",
1451 | "stream-http": "^2.7.2",
1452 | "string_decoder": "^1.0.0",
1453 | "timers-browserify": "^2.0.4",
1454 | "tty-browserify": "0.0.0",
1455 | "url": "^0.11.0",
1456 | "util": "^0.11.0",
1457 | "vm-browserify": "^1.0.1"
1458 | }
1459 | },
1460 | "object-assign": {
1461 | "version": "4.1.1",
1462 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1463 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
1464 | "dev": true
1465 | },
1466 | "opentype.js": {
1467 | "version": "1.3.4",
1468 | "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
1469 | "integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
1470 | "requires": {
1471 | "string.prototype.codepointat": "^0.2.1",
1472 | "tiny-inflate": "^1.0.3"
1473 | }
1474 | },
1475 | "os-browserify": {
1476 | "version": "0.3.0",
1477 | "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
1478 | "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
1479 | "dev": true
1480 | },
1481 | "pako": {
1482 | "version": "1.0.11",
1483 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
1484 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
1485 | "dev": true
1486 | },
1487 | "parse-asn1": {
1488 | "version": "5.1.6",
1489 | "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
1490 | "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
1491 | "dev": true,
1492 | "requires": {
1493 | "asn1.js": "^5.2.0",
1494 | "browserify-aes": "^1.0.0",
1495 | "evp_bytestokey": "^1.0.0",
1496 | "pbkdf2": "^3.0.3",
1497 | "safe-buffer": "^5.1.1"
1498 | }
1499 | },
1500 | "path-browserify": {
1501 | "version": "0.0.1",
1502 | "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
1503 | "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
1504 | "dev": true
1505 | },
1506 | "pbkdf2": {
1507 | "version": "3.1.2",
1508 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
1509 | "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
1510 | "dev": true,
1511 | "requires": {
1512 | "create-hash": "^1.1.2",
1513 | "create-hmac": "^1.1.4",
1514 | "ripemd160": "^2.0.1",
1515 | "safe-buffer": "^5.0.1",
1516 | "sha.js": "^2.4.8"
1517 | }
1518 | },
1519 | "process": {
1520 | "version": "0.11.10",
1521 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
1522 | "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
1523 | "dev": true
1524 | },
1525 | "process-nextick-args": {
1526 | "version": "2.0.1",
1527 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
1528 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
1529 | "dev": true
1530 | },
1531 | "public-encrypt": {
1532 | "version": "4.0.3",
1533 | "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
1534 | "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
1535 | "dev": true,
1536 | "requires": {
1537 | "bn.js": "^4.1.0",
1538 | "browserify-rsa": "^4.0.0",
1539 | "create-hash": "^1.1.0",
1540 | "parse-asn1": "^5.0.0",
1541 | "randombytes": "^2.0.1",
1542 | "safe-buffer": "^5.1.2"
1543 | },
1544 | "dependencies": {
1545 | "bn.js": {
1546 | "version": "4.12.0",
1547 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
1548 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
1549 | "dev": true
1550 | }
1551 | }
1552 | },
1553 | "punycode": {
1554 | "version": "1.4.1",
1555 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
1556 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
1557 | "dev": true
1558 | },
1559 | "querystring": {
1560 | "version": "0.2.0",
1561 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
1562 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
1563 | "dev": true
1564 | },
1565 | "querystring-es3": {
1566 | "version": "0.2.1",
1567 | "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
1568 | "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
1569 | "dev": true
1570 | },
1571 | "randombytes": {
1572 | "version": "2.1.0",
1573 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
1574 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
1575 | "dev": true,
1576 | "requires": {
1577 | "safe-buffer": "^5.1.0"
1578 | }
1579 | },
1580 | "randomfill": {
1581 | "version": "1.0.4",
1582 | "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
1583 | "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
1584 | "dev": true,
1585 | "requires": {
1586 | "randombytes": "^2.0.5",
1587 | "safe-buffer": "^5.1.0"
1588 | }
1589 | },
1590 | "readable-stream": {
1591 | "version": "2.3.7",
1592 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
1593 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
1594 | "dev": true,
1595 | "requires": {
1596 | "core-util-is": "~1.0.0",
1597 | "inherits": "~2.0.3",
1598 | "isarray": "~1.0.0",
1599 | "process-nextick-args": "~2.0.0",
1600 | "safe-buffer": "~5.1.1",
1601 | "string_decoder": "~1.1.1",
1602 | "util-deprecate": "~1.0.1"
1603 | },
1604 | "dependencies": {
1605 | "safe-buffer": {
1606 | "version": "5.1.2",
1607 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1608 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1609 | "dev": true
1610 | },
1611 | "string_decoder": {
1612 | "version": "1.1.1",
1613 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
1614 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
1615 | "dev": true,
1616 | "requires": {
1617 | "safe-buffer": "~5.1.0"
1618 | }
1619 | }
1620 | }
1621 | },
1622 | "readline-sync": {
1623 | "version": "1.4.10",
1624 | "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz",
1625 | "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==",
1626 | "dev": true
1627 | },
1628 | "ripemd160": {
1629 | "version": "2.0.2",
1630 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
1631 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
1632 | "dev": true,
1633 | "requires": {
1634 | "hash-base": "^3.0.0",
1635 | "inherits": "^2.0.1"
1636 | }
1637 | },
1638 | "safe-buffer": {
1639 | "version": "5.2.1",
1640 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1641 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1642 | "dev": true
1643 | },
1644 | "safer-buffer": {
1645 | "version": "2.1.2",
1646 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1647 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1648 | "dev": true
1649 | },
1650 | "setimmediate": {
1651 | "version": "1.0.5",
1652 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
1653 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
1654 | "dev": true
1655 | },
1656 | "sha.js": {
1657 | "version": "2.4.11",
1658 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
1659 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
1660 | "dev": true,
1661 | "requires": {
1662 | "inherits": "^2.0.1",
1663 | "safe-buffer": "^5.0.1"
1664 | }
1665 | },
1666 | "shadow-cljs": {
1667 | "version": "2.16.12",
1668 | "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.16.12.tgz",
1669 | "integrity": "sha512-6JqOhN5X3n0IkxA/gSUcZ1lImwcW1LmpgzlaBDOC/u/pIysdNm0tiOxpOTEnExl9nKZBS/EYS7bXIIInywPJUA==",
1670 | "dev": true,
1671 | "requires": {
1672 | "node-libs-browser": "^2.2.1",
1673 | "readline-sync": "^1.4.7",
1674 | "shadow-cljs-jar": "1.3.2",
1675 | "source-map-support": "^0.4.15",
1676 | "which": "^1.3.1",
1677 | "ws": "^7.4.6"
1678 | }
1679 | },
1680 | "shadow-cljs-jar": {
1681 | "version": "1.3.2",
1682 | "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz",
1683 | "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==",
1684 | "dev": true
1685 | },
1686 | "source-map": {
1687 | "version": "0.5.7",
1688 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1689 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
1690 | "dev": true
1691 | },
1692 | "source-map-support": {
1693 | "version": "0.4.18",
1694 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
1695 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
1696 | "dev": true,
1697 | "requires": {
1698 | "source-map": "^0.5.6"
1699 | }
1700 | },
1701 | "stream-browserify": {
1702 | "version": "2.0.2",
1703 | "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
1704 | "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
1705 | "dev": true,
1706 | "requires": {
1707 | "inherits": "~2.0.1",
1708 | "readable-stream": "^2.0.2"
1709 | }
1710 | },
1711 | "stream-http": {
1712 | "version": "2.8.3",
1713 | "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
1714 | "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
1715 | "dev": true,
1716 | "requires": {
1717 | "builtin-status-codes": "^3.0.0",
1718 | "inherits": "^2.0.1",
1719 | "readable-stream": "^2.3.6",
1720 | "to-arraybuffer": "^1.0.0",
1721 | "xtend": "^4.0.0"
1722 | }
1723 | },
1724 | "string_decoder": {
1725 | "version": "1.3.0",
1726 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
1727 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
1728 | "dev": true,
1729 | "requires": {
1730 | "safe-buffer": "~5.2.0"
1731 | }
1732 | },
1733 | "string.prototype.codepointat": {
1734 | "version": "0.2.1",
1735 | "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
1736 | "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
1737 | },
1738 | "timers-browserify": {
1739 | "version": "2.0.12",
1740 | "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
1741 | "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
1742 | "dev": true,
1743 | "requires": {
1744 | "setimmediate": "^1.0.4"
1745 | }
1746 | },
1747 | "tiny-inflate": {
1748 | "version": "1.0.3",
1749 | "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
1750 | "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
1751 | },
1752 | "to-arraybuffer": {
1753 | "version": "1.0.1",
1754 | "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
1755 | "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
1756 | "dev": true
1757 | },
1758 | "tty-browserify": {
1759 | "version": "0.0.0",
1760 | "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
1761 | "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
1762 | "dev": true
1763 | },
1764 | "url": {
1765 | "version": "0.11.0",
1766 | "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
1767 | "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
1768 | "dev": true,
1769 | "requires": {
1770 | "punycode": "1.3.2",
1771 | "querystring": "0.2.0"
1772 | },
1773 | "dependencies": {
1774 | "punycode": {
1775 | "version": "1.3.2",
1776 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
1777 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
1778 | "dev": true
1779 | }
1780 | }
1781 | },
1782 | "util": {
1783 | "version": "0.11.1",
1784 | "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
1785 | "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
1786 | "dev": true,
1787 | "requires": {
1788 | "inherits": "2.0.3"
1789 | },
1790 | "dependencies": {
1791 | "inherits": {
1792 | "version": "2.0.3",
1793 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
1794 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
1795 | "dev": true
1796 | }
1797 | }
1798 | },
1799 | "util-deprecate": {
1800 | "version": "1.0.2",
1801 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
1802 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
1803 | "dev": true
1804 | },
1805 | "vm-browserify": {
1806 | "version": "1.1.2",
1807 | "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
1808 | "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
1809 | "dev": true
1810 | },
1811 | "which": {
1812 | "version": "1.3.1",
1813 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
1814 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
1815 | "dev": true,
1816 | "requires": {
1817 | "isexe": "^2.0.0"
1818 | }
1819 | },
1820 | "ws": {
1821 | "version": "7.5.6",
1822 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
1823 | "integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
1824 | "dev": true,
1825 | "requires": {}
1826 | },
1827 | "xtend": {
1828 | "version": "4.0.2",
1829 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1830 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1831 | "dev": true
1832 | }
1833 | }
1834 | }
1835 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "viscous",
3 | "version": "1.0.0",
4 | "description": "A visual data inspector/explorer that runs in constant space, time, and screen space.",
5 | "main": "index.js",
6 | "directories": {
7 | "doc": "doc",
8 | "example": "example",
9 | "test": "test"
10 | },
11 | "scripts": {
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "repository": {
15 | "type": "git",
16 | "url": "git+https://github.com/phronmophobic/viscous.git"
17 | },
18 | "keywords": [],
19 | "author": "",
20 | "license": "ISC",
21 | "bugs": {
22 | "url": "https://github.com/phronmophobic/viscous/issues"
23 | },
24 | "homepage": "https://github.com/phronmophobic/viscous#readme",
25 | "devDependencies": {
26 | "shadow-cljs": "^2.16.12"
27 | },
28 | "dependencies": {
29 | "buffer": "4.9.2",
30 | "opentype.js": "1.3.4"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/paging.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phronmophobic/viscous/7815e80d890d1a7a26e29ff6c311cbad8c847a44/paging.gif
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | com.phronemophobic
5 | viscous
6 | 1.2
7 | com.phronemophobic/viscous
8 | A visual data inspector/explorer that runs in constant space, time, and screen space.
9 | https://github.com/com.phronemophobic/viscous
10 |
11 |
12 | Eclipse Public License
13 | http://www.eclipse.org/legal/epl-v10.html
14 |
15 |
16 |
17 |
18 | Adrian
19 |
20 |
21 |
22 | https://github.com/com.phronemophobic/viscous
23 | scm:git:git://github.com/com.phronemophobic/viscous.git
24 | scm:git:ssh://git@github.com/com.phronemophobic/viscous.git
25 | v1.2
26 |
27 |
28 |
29 | org.clojure
30 | clojure
31 | 1.10.3
32 |
33 |
34 | com.phronemophobic
35 | membrane
36 | 0.9.31.8-beta
37 |
38 |
39 |
40 | src
41 |
42 |
43 |
44 | clojars
45 | https://repo.clojars.org/
46 |
47 |
48 |
49 |
50 | clojars
51 | Clojars repository
52 | https://clojars.org/repo
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/public/blog.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Globals
3 | */
4 |
5 | @media (min-width: 48em) {
6 | html {
7 | font-size: 18px;
8 | }
9 | }
10 |
11 | /* body { */
12 | /* font-family: Georgia, "Times New Roman", Times, serif; */
13 | /* color: #555; */
14 | /* } */
15 |
16 | /* h1, .h1, */
17 | /* h2, .h2, */
18 | /* h3, .h3, */
19 | /* h4, .h4, */
20 | /* h5, .h5, */
21 | /* h6, .h6 { */
22 | /* font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; */
23 | /* font-weight: normal; */
24 | /* color: #333; */
25 | /* } */
26 |
27 |
28 | /*
29 | * Override Bootstrap's default container.
30 | */
31 |
32 | .container {
33 | max-width: 60rem;
34 | }
35 |
36 |
37 | /*
38 | * Masthead for nav
39 | */
40 |
41 | .blog-masthead {
42 | margin-bottom: 3rem;
43 | background-color: #428bca;
44 | -webkit-box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1);
45 | box-shadow: inset 0 -.1rem .25rem rgba(0,0,0,.1);
46 | }
47 |
48 | /* Nav links */
49 | .nav-link {
50 | position: relative;
51 | padding: 1rem;
52 | font-weight: 500;
53 | color: #cdddeb;
54 | }
55 | .nav-link:hover,
56 | .nav-link:focus {
57 | color: #fff;
58 | background-color: transparent;
59 | }
60 |
61 | /* Active state gets a caret at the bottom */
62 | .nav-link.active {
63 | color: #fff;
64 | }
65 | .nav-link.active:after {
66 | position: absolute;
67 | bottom: 0;
68 | left: 50%;
69 | width: 0;
70 | height: 0;
71 | margin-left: -.3rem;
72 | vertical-align: middle;
73 | content: "";
74 | border-right: .3rem solid transparent;
75 | border-bottom: .3rem solid;
76 | border-left: .3rem solid transparent;
77 | }
78 |
79 |
80 | /*
81 | * Blog name and description
82 | */
83 |
84 | .blog-header {
85 | padding-bottom: 1.25rem;
86 | margin-bottom: 2rem;
87 | border-bottom: .05rem solid #eee;
88 | }
89 | .blog-title {
90 | margin-bottom: 0;
91 | font-size: 2rem;
92 | font-weight: normal;
93 | }
94 | .blog-description {
95 | font-size: 1.1rem;
96 | color: #999;
97 | }
98 |
99 | @media (min-width: 40em) {
100 | .blog-title {
101 | font-size: 3.5rem;
102 | }
103 | }
104 |
105 |
106 | /*
107 | * Main column and sidebar layout
108 | */
109 |
110 | /* Sidebar modules for boxing content */
111 | .sidebar-module {
112 | padding: 1rem;
113 | /*margin: 0 -1rem 1rem;*/
114 | }
115 | .sidebar-module-inset {
116 | padding: 1rem;
117 | background-color: #f5f5f5;
118 | border-radius: .25rem;
119 | }
120 | .sidebar-module-inset p:last-child,
121 | .sidebar-module-inset ul:last-child,
122 | .sidebar-module-inset ol:last-child {
123 | margin-bottom: 0;
124 | }
125 |
126 |
127 | /* Pagination */
128 | .blog-pagination {
129 | margin-bottom: 4rem;
130 | }
131 | .blog-pagination > .btn {
132 | border-radius: 2rem;
133 | }
134 |
135 |
136 | /*
137 | * Blog posts
138 | */
139 |
140 | .blog-post {
141 | margin-bottom: 4rem;
142 | }
143 | .blog-post-title {
144 | margin-bottom: .25rem;
145 | font-size: 2.5rem;
146 | }
147 | .blog-post-meta {
148 | margin-bottom: 1.25rem;
149 | color: #999;
150 | }
151 |
152 |
153 | /*
154 | * Footer
155 | */
156 |
157 | .blog-footer {
158 | padding: 2.5rem 0;
159 | color: #999;
160 | text-align: center;
161 | background-color: #f9f9f9;
162 | border-top: .05rem solid #e5e5e5;
163 | }
164 | .blog-footer p:last-child {
165 | margin-bottom: 0;
166 | }
167 |
168 |
169 | blockquote {
170 | /* background: #f9f9f9; */
171 | border-left: 10px solid #ccc;
172 | margin: 1.5em 10px;
173 | padding: 0.5em 10px;
174 | /* quotes: "\201C""\201D""\2018""\2019"; */
175 | }
176 | /* blockquote:before { */
177 | /* color: #ccc; */
178 | /* content: open-quote; */
179 | /* font-size: 4em; */
180 | /* line-height: 0.1em; */
181 | /* margin-right: 0.25em; */
182 | /* vertical-align: -0.4em; */
183 | /* } */
184 | blockquote p {
185 | display: inline;
186 | }
187 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Viscous Demo
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
Load Data
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
Viscous
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/resources/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/phronmophobic/viscous/7815e80d890d1a7a26e29ff6c311cbad8c847a44/resources/.keep
--------------------------------------------------------------------------------
/shadow-cljs.edn:
--------------------------------------------------------------------------------
1 | ;; shadow-cljs configuration
2 | {
3 | :deps {:aliases [:cljs]}
4 | :builds {:app {
5 | :modules {:main {:init-fn com.phronemophobic.viscous.demo/-main}}
6 | ;; :asset-path "js/compiled/out.webgltest"
7 | ;; :output-to "resources/public/js/compiled/webgltest.js"
8 | ;; :output-dir "resources/public/js/compiled/out.webgltest"
9 | :target :browser
10 | ;; :compiler-options
11 | ;; {
12 | ;; :source-map-timestamp true
13 | ;; ;;:optimizations :whitespace
14 | ;; }
15 | }}}
16 |
--------------------------------------------------------------------------------
/src/com/phronemophobic/viscous.cljc:
--------------------------------------------------------------------------------
1 | (ns com.phronemophobic.viscous
2 | (:require
3 | [membrane.ui :as ui]
4 | [membrane.basic-components :as basic]
5 | [clojure.string :as str]
6 | [membrane.toolkit :as tk]
7 | #?(:cljs goog.object)
8 | [membrane.alpha.component.drag-and-drop :as dnd]
9 | [membrane.component :refer [defui defeffect]
10 | :as component]))
11 |
12 | (defonce toolkit
13 | (delay
14 | #?(:clj
15 | (if-let [tk (resolve 'membrane.skia/toolkit)]
16 | @tk
17 | @(requiring-resolve 'membrane.java2d/toolkit))
18 | :cljs
19 | nil)))
20 |
21 | (def paragraph
22 | (resolve 'membrane.skia.paragraph/paragraph))
23 | (def paragraph-intrinsic-width
24 | (resolve 'membrane.skia.paragraph/intrinsic-width))
25 |
26 |
27 |
28 | (do
29 | #?@
30 | (:cljs
31 | [(def monospaced (delay
32 | (ui/font "Ubuntu Mono"
33 | nil)))
34 | (def cell-width)
35 | (def cell-height)]
36 |
37 | :clj
38 | [(def monospaced
39 | (delay
40 | (if (tk/font-exists? @toolkit (ui/font "Menlo" 11))
41 | (ui/font "Menlo" 11)
42 | (ui/font "monospaced" 11))))
43 | (def cell-width
44 | (delay
45 | (tk/font-advance-x @toolkit @monospaced " ")))
46 | (def cell-height
47 | (delay
48 | (tk/font-line-height @toolkit @monospaced)))]))
49 |
50 |
51 |
52 | (defprotocol PWrapped
53 | (-unwrap [this]))
54 |
55 | (deftype APWrapped [obj]
56 | #?@(:clj
57 | [
58 | clojure.lang.IDeref
59 | (deref [_] obj)
60 |
61 | clojure.lang.IHashEq
62 | (hasheq [_] (System/identityHashCode obj))
63 | (hashCode [_] (System/identityHashCode obj))
64 | (equals [this that]
65 | (if (instance? APWrapped that)
66 | (identical? obj (-unwrap that))
67 | false))])
68 |
69 | PWrapped
70 | (-unwrap [_]
71 | obj))
72 |
73 | (defn wrap [o]
74 | (->APWrapped o))
75 |
76 |
77 | (def colors
78 | {:keyword [0.46666666865348816 0.0 0.5333333611488342],
79 | :number
80 | [0.06666667014360428 0.4000000059604645 0.2666666805744171],
81 | :def [0.0 0.0 1.0],
82 | :positive
83 | [0.13333334028720856 0.6000000238418579 0.13333334028720856],
84 | :bracket
85 | [0.6000000238418579 0.6000000238418579 0.46666666865348816],
86 | :comment [0.6666666865348816 0.3333333432674408 0.0],
87 | :attribute [0.0 0.0 0.800000011920929],
88 | :type [0.0 0.5333333611488342 0.3333333432674408],
89 | :quote [0.0 0.6000000238418579 0.0],
90 | :header [0.0 0.0 1.0],
91 | :atom
92 | [0.13333334028720856 0.06666667014360428 0.6000000238418579],
93 | :builtin [0.20000000298023224 0.0 0.6666666865348816],
94 | :hr [0.6000000238418579 0.6000000238418579 0.6000000238418579],
95 | :string-2 [1.0 0.3333333432674408 0.0],
96 | :string
97 | [0.6666666865348816 0.06666667014360428 0.06666667014360428],
98 | :meta [0.3333333432674408 0.3333333432674408 0.3333333432674408],
99 | :tag [0.06666667014360428 0.46666666865348816 0.0],
100 | :qualifier
101 | [0.3333333432674408 0.3333333432674408 0.3333333432674408],
102 | :variable-2 [0.0 0.3333333432674408 0.6666666865348816]})
103 |
104 |
105 |
106 | (defn indent [n]
107 | (ui/spacer (* n @cell-width) 0))
108 |
109 | (defn inspector-dispatch [{:keys [obj width height]}]
110 | (if (or (<= width 0)
111 | (<= height 0))
112 | :no-space
113 | (cond
114 | (string? obj) :string
115 | (integer? obj) :integer
116 | (float? obj) :float
117 | (double? obj) :double
118 | #?@(:clj [(ratio? obj) :ratio])
119 | (char? obj) :char
120 | (map-entry? obj) :map-entry
121 | (map? obj) :map
122 | (set? obj) :set
123 | (list? obj) :list
124 | (vector? obj) :vector
125 | (symbol? obj) :symbol
126 | (keyword? obj) :keyword
127 | (boolean? obj) :boolean
128 | (nil? obj) :nil
129 | (uuid? obj) :uuid
130 |
131 | (coll? obj) :collection
132 | (seqable? obj) :seqable
133 | (tagged-literal? obj) :tagged-literal
134 | (satisfies? PWrapped obj) :pwrapped
135 | #?@(:clj [(instance? clojure.lang.IDeref obj) :deref])
136 | (fn? obj) :fn
137 | #?@(:clj [(instance? Throwable obj) :throwable])
138 | :else :object)))
139 |
140 |
141 | (defmulti inspector* inspector-dispatch)
142 |
143 | (defn ilabel [o width]
144 | (let [s (str o)
145 | len (count s)
146 | shortened
147 | (when (pos? len)
148 | (if (<= len width)
149 | s
150 | (case width
151 | 0 nil
152 | (1 2 3) (subs s 0 (min len width))
153 |
154 | ;; else
155 | (str (subs s 0 (max 0
156 | (- width 3)))
157 | "..."))))]
158 | (when shortened
159 | (ui/label shortened @monospaced))))
160 |
161 | (defn split-evenly [width n]
162 | (if (zero? n)
163 | []
164 | (let [chunk-size (max 1
165 | (int (/ width n)))]
166 | (vec
167 | (reverse
168 | (loop [partitions []
169 | width width]
170 | (cond
171 | (zero? width) partitions
172 |
173 | (>= (inc (count partitions))
174 | n)
175 | (conj partitions width)
176 |
177 | :else (recur (conj partitions chunk-size)
178 | (- width chunk-size)))))))))
179 |
180 | (defn split-ratio [width r]
181 | (let [left (int (Math/ceil (* r width)))
182 | right (- width left)]
183 | [left right]))
184 |
185 | (def one-third (/ 1 3))
186 | (defmethod inspector* :default
187 | [{:keys [obj width height]}]
188 | (let [[left right] (split-ratio width one-third)]
189 | (ui/horizontal-layout
190 | (ilabel (inspector-dispatch {:obj obj
191 | :width width
192 | :height height})
193 | left)
194 | (ilabel (type obj)
195 | right))))
196 |
197 | #?(:clj
198 | (defmethod inspector* :throwable
199 | [m]
200 | (inspector* (update m :obj Throwable->map))))
201 |
202 | (defmethod inspector* :no-space
203 | [{:keys [obj width height]}]
204 | nil)
205 |
206 | (defmethod inspector* :string
207 | [{:keys [obj width height]}]
208 | (let [;; display empty strings as ""
209 | ;; otherwise, they're invisible.
210 | ;; this does mean that empty strings and
211 | ;; the string "\"\"" are indistinguishable.
212 | obj (if (zero? (count obj))
213 | "\"\""
214 | obj)]
215 | (if (and paragraph
216 | paragraph-intrinsic-width)
217 | (ui/translate
218 | 0 3
219 | (let [ ;; upper bound
220 | ;; only necessary for very large strings
221 | max-length (* width height)
222 | s (if (> (count obj) max-length)
223 | (subs obj 0 max-length)
224 | obj)
225 | p
226 | (paragraph
227 | s
228 | (* width @cell-width)
229 | {:paragraph-style/max-lines height
230 | :paragraph-style/text-style
231 | {:text-style/color (:string colors)
232 | :text-style/font-size 11
233 | :text-style/font-families ["Menlo"
234 | "monospaced"]}})
235 | [pw ph] (ui/bounds p)
236 | intrinsic-width (paragraph-intrinsic-width p)
237 | w (min pw intrinsic-width)]
238 | (ui/fixed-bounds [w ph]
239 | p)))
240 | (ui/with-color (:string colors)
241 | (let [s obj
242 | len (count s)
243 | shortened
244 | (when (pos? len)
245 | (if (<= len (- width 2))
246 | (str "\"" s "\"")
247 | (case width
248 | 0 nil
249 |
250 | 1 "\""
251 |
252 | (2 3) (str "\"" (subs s 0 (dec width)))
253 |
254 | 4 "\"..."
255 |
256 | ;; else
257 | (str "\""
258 | (subs s 0 (max 0
259 | (- width 4)))
260 | "..."))))]
261 | (when shortened
262 | (let [shortened (str/replace shortened #"\R" "↵" )]
263 | (ui/label shortened @monospaced))))))))
264 |
265 | (defn wrap-selection [x path elem]
266 | (ui/wrap-on
267 | :mouse-down
268 | (fn [handler pos]
269 | (let [intents (handler pos)]
270 | (if (seq intents)
271 | intents
272 | [[::dnd/drag-start {::dnd/obj {:path path
273 | :x (wrap x)}}]
274 | [::select x path]])))
275 | elem))
276 |
277 | (defn wrap-highlight [path highlight-path elem]
278 | (let [body
279 | (ui/wrap-on
280 | :mouse-move
281 | (fn [handler pos]
282 | (let [intents (handler pos)]
283 | (if (seq intents)
284 | intents
285 | [[::highlight path]])))
286 | elem)]
287 | (if (= path highlight-path)
288 | (ui/fill-bordered [0.2 0.2 0.2 0.1]
289 | 0
290 | body)
291 | body)))
292 |
293 | ;; There are some data structures that implement Counted in
294 | ;; linear time. Cruel!
295 | (defprotocol IBoundedCount
296 | (-bounded-count [this n]))
297 |
298 | (extend-protocol IBoundedCount
299 | #?(:clj Object
300 | :cljs default)
301 | (-bounded-count [this n]
302 | (bounded-count n this))
303 | nil
304 | (-bounded-count [this n]
305 | 0))
306 |
307 | (defn inspector-seq-horizontal [{:keys [obj
308 | width
309 | height
310 | highlight-path
311 | path
312 | offset
313 | open close]}]
314 | (let [open-close-width (+ (count open)
315 | (count close))]
316 | (when (> width open-close-width )
317 | (let [body
318 | (loop [body []
319 | i 0
320 | width (- width
321 | (count open)
322 | (count close))
323 | ;; lazy sequences can throw here
324 | obj (try
325 | (seq obj)
326 | (catch #?(:clj Exception :cljs js/Error) e
327 | e))]
328 | (if (instance? #?(:clj Exception :cljs js/Error) obj)
329 | (conj body
330 | (inspector* {:obj obj
331 | :height height
332 | :width width
333 | :highlight-path highlight-path
334 | :path path}))
335 | (if (or (not obj)
336 | (<= width 0))
337 | body
338 | (let [x (first obj)
339 | child-path (if (map-entry? x)
340 | (list 'find (key x))
341 | (list 'nth i))
342 | path (conj path
343 | child-path)
344 | elem
345 | (wrap-highlight
346 | path
347 | highlight-path
348 | (wrap-selection
349 | x
350 | path
351 | (inspector* {:obj x
352 | :height 1
353 | :highlight-path highlight-path
354 | :path path
355 | :width width})))
356 | pix-width (ui/width elem)
357 | elem-width (int (Math/ceil (/ pix-width
358 | @cell-width)))]
359 | (recur (conj body elem)
360 | (inc i)
361 | (- width elem-width
362 | ;; add a space between elements
363 | 1
364 | )
365 | ;; lazy sequences can throw here
366 | (try
367 | (next obj)
368 | (catch #?(:clj Exception :cljs js/Error) e
369 | e)))))))]
370 | (ui/horizontal-layout
371 | (ui/with-color (:bracket colors)
372 | (ilabel open (count open)))
373 | (when (pos? (count body))
374 | (apply ui/horizontal-layout
375 | (interpose (indent 1)
376 | body)))
377 | (let [len (try
378 | (-bounded-count obj (inc (count body)))
379 | (catch #?(:clj Exception :cljs js/Error) e
380 | nil))]
381 | (when (= (count body) len)
382 | (ui/with-color (:bracket colors)
383 | (ilabel close (count close))))))))))
384 |
385 | (def chunk-size 32)
386 | (defn inspector-seq [{:keys [obj
387 | width
388 | height
389 | highlight-path
390 | path
391 | offset
392 | open close]
393 | :as m}]
394 | (let [offset (or offset 0)]
395 | (if (<= height 3)
396 | (inspector-seq-horizontal m)
397 | (let [;; realize elements
398 | ;; lazy sequences can throw errors here
399 | chunk (try
400 | (loop [obj (seq (if (pos? offset)
401 | (drop offset obj)
402 | obj))
403 | chunk []]
404 | (if (or (not obj)
405 | (>= (count chunk)
406 | chunk-size))
407 | chunk
408 | (let [x (first obj)]
409 | (let [next-obj
410 | ;; lazy sequences can throw here
411 | (try
412 | (next obj)
413 | (catch #?(:clj Exception :cljs js/Error) e
414 | e))]
415 | (if (instance? #?(:clj Exception :cljs js/Error) next-obj)
416 | (conj chunk next-obj)
417 | (recur next-obj
418 | (conj chunk x)))))))
419 | (catch #?(:clj Exception :cljs js/Error) e
420 | e))
421 |
422 | has-previous? (pos? offset)
423 | has-next? (let [len
424 | ;; lazy sequences can throw here
425 | (try
426 | (-bounded-count (drop offset obj)
427 | (inc chunk-size))
428 | (catch #?(:clj Exception :cljs js/Error) e
429 | (println e)
430 | nil))]
431 | (and len
432 | (or (> len chunk-size)
433 | (> len (- height
434 | ;; open and close
435 | 2
436 | (if has-previous?
437 | 1
438 | 0))))))
439 |
440 | children
441 | (if (instance? #?(:clj Exception :cljs js/Error) chunk)
442 | (inspector* {:obj chunk
443 | :height height
444 | :width width
445 | :highlight-path highlight-path
446 | :path path})
447 | (let [heights (split-evenly
448 | ;; space for children is
449 | (- height
450 | ;; open and close
451 | 2
452 | (if has-previous? 1 0)
453 | (if has-next? 1 0)
454 | )
455 | (count chunk))]
456 | (->> chunk
457 | (map (fn [i height obj]
458 | (let [child-path (if (map-entry? obj)
459 | (list 'find (key obj))
460 | (list 'nth i))
461 | path (conj path
462 | child-path)
463 | body
464 | (wrap-highlight
465 | path
466 | highlight-path
467 | (wrap-selection obj
468 | path
469 | (inspector* {:obj obj
470 | :height height
471 | :path path
472 | :highlight-path highlight-path
473 | :width (dec width)})))]
474 | (if (= path highlight-path)
475 | (ui/fill-bordered [0.2 0.2 0.2 0.1]
476 | 0
477 | body)
478 | body)))
479 | (range)
480 | heights)
481 | (apply ui/vertical-layout))))]
482 | (cond
483 | (instance? #?(:clj Exception :cljs js/Error) chunk)
484 | children
485 |
486 | (empty? chunk)
487 | (ui/with-color (:bracket colors)
488 | (ilabel (str open close) width))
489 |
490 | ;; else not empty
491 | :else
492 | (ui/vertical-layout
493 | (ui/with-color (:bracket colors)
494 | (ilabel open width))
495 | (ui/translate @cell-width 0
496 | (ui/vertical-layout
497 | (when has-previous?
498 | (ui/on
499 | :mouse-down
500 | (fn [_]
501 | ;; only for top level
502 | (when (empty? path)
503 | [[::previous-chunk]]))
504 | (ilabel "..." 3)))
505 | children
506 | (when has-next?
507 | (ui/on
508 | :mouse-down
509 | (fn [_]
510 | ;; only for top level
511 | (when (empty? path)
512 | [[::next-chunk (count children)]]))
513 | (ilabel "..." 3)))
514 | ))
515 | (ui/with-color (:bracket colors)
516 | (ilabel close width))))))))
517 |
518 |
519 | (defmethod inspector* :vector
520 | [{:keys [obj width height] :as m}]
521 | (inspector-seq (assoc m
522 | :open "["
523 | :close "]")))
524 |
525 | (defmethod inspector* :seqable
526 | [{:keys [obj width height] :as m}]
527 | (inspector-seq (assoc m
528 | :open "("
529 | :close ")")))
530 |
531 | (defmethod inspector* :collection
532 | [{:keys [obj width height] :as m}]
533 | (inspector-seq (assoc m
534 | :open "("
535 | :close ")")))
536 |
537 | (defmethod inspector* :list
538 | [{:keys [obj width height] :as m}]
539 | (inspector-seq (assoc m
540 | :open "("
541 | :close ")")))
542 |
543 | (defmethod inspector* :set
544 | [{:keys [obj width height] :as m}]
545 | (inspector-seq (assoc m
546 | :open "#{"
547 | :close "}")))
548 |
549 |
550 |
551 | (defmethod inspector* :map
552 | [{:keys [obj width height] :as m}]
553 | (inspector-seq (assoc m
554 | :open "{"
555 | :close "}"))
556 | )
557 |
558 | #?
559 | (:cljs
560 | (defn ->map-entry [obj k]
561 | (MapEntry. k (goog.object/get obj k) nil)))
562 |
563 | #?
564 | (:cljs
565 | (defmethod inspector* :object
566 | [{:keys [obj width height] :as m}]
567 | (inspector-seq (assoc m
568 | :obj (map #(->map-entry obj %) (js-keys obj))
569 | :open "{"
570 | :close "}"))))
571 |
572 |
573 | (defn inspector-keyword [{:keys [obj width height]}]
574 | (let [ns (namespace obj)
575 | [left right] (if ns
576 | (split-ratio (- width 2) one-third)
577 | [0 (- width 1)])]
578 | (ui/with-color (:keyword colors)
579 | (ui/horizontal-layout
580 | (ilabel ":" 1)
581 | (when ns
582 | (ui/horizontal-layout
583 | (ilabel ns left)
584 | (ilabel "/" 1)))
585 | (ilabel (name obj) right)))))
586 | (defmethod inspector* :keyword
587 | [{:keys [obj width height] :as m}]
588 | (inspector-keyword m))
589 |
590 |
591 | (defn inspector-map-entry [{:keys [obj width height path highlight-path]}]
592 | (let [[left right] (split-ratio (- width 2) one-third)
593 | [k v] obj]
594 | (ui/horizontal-layout
595 | (let [child-path (conj path '(key))]
596 | (wrap-highlight
597 | child-path
598 | highlight-path
599 | (wrap-selection k
600 | child-path
601 | (inspector* {:obj k
602 | :height height
603 | :path child-path
604 | :highlight-path highlight-path
605 | :width left}))))
606 | (indent 1)
607 | (let [child-path (conj path '(val))]
608 | (wrap-highlight
609 | child-path
610 | highlight-path
611 | (wrap-selection v
612 | child-path
613 | (inspector* {:obj v
614 | :height height
615 | :path child-path
616 | :highlight-path highlight-path
617 | :width right})))))))
618 | (defmethod inspector* :map-entry
619 | [{:keys [obj width height] :as m}]
620 | (inspector-map-entry m))
621 |
622 |
623 | #?
624 | (:clj
625 | (defn inspector-deref [{:keys [obj width height path highlight-path]}]
626 | (let [[left right] (split-ratio (- width 2) one-third)
627 | k (symbol (.getName (class obj)))
628 | v (if (instance? clojure.lang.IPending obj)
629 | (if (realized? obj)
630 | @obj
631 | "unrealized?")
632 | (deref obj))]
633 | (ui/horizontal-layout
634 | (indent 1)
635 | (inspector* {:obj k
636 | :height height
637 | :width left})
638 | (indent 1)
639 | (let [child-path (conj path '(deref))]
640 | (wrap-highlight
641 | child-path
642 | highlight-path
643 | (wrap-selection v
644 | child-path
645 | (inspector* {:obj v
646 | :height height
647 | :path child-path
648 | :highlight-path highlight-path
649 | :width right}))))))))
650 | #?
651 | (:clj
652 | (defmethod inspector* :deref
653 | [{:keys [obj width height] :as m}]
654 | (inspector-deref m)))
655 |
656 |
657 | (defn inspector-tagged-literal [{:keys [obj width height path highlight-path]}]
658 | (let [[left right] (split-ratio (- width 2) one-third)
659 | tag (:tag obj)
660 | form (:form obj)]
661 | (ui/horizontal-layout
662 | (when (pos? width)
663 | (ui/label "#"))
664 | (inspector* {:obj tag
665 | :height height
666 | :width left})
667 | (indent 1)
668 | (let [child-path path]
669 | (wrap-highlight
670 | child-path
671 | highlight-path
672 | (wrap-selection form
673 | child-path
674 | (inspector* {:obj form
675 | :height height
676 | :path child-path
677 | :highlight-path highlight-path
678 | :width right})))))))
679 |
680 | (defmethod inspector* :tagged-literal
681 | [{:keys [obj width height] :as m}]
682 | (inspector-tagged-literal m))
683 |
684 | (defn inspector-uuid [{:keys [obj width height path highlight-path]}]
685 | (let [[left right] (split-ratio (- width 1) one-third)
686 | tag (symbol "#uuid")]
687 | (ui/horizontal-layout
688 | (inspector* {:obj tag
689 | :height height
690 | :width left})
691 | (indent 1)
692 | (let [child-path (conj path '(str))]
693 | (wrap-highlight
694 | child-path
695 | highlight-path
696 | (wrap-selection (str obj)
697 | child-path
698 | (inspector* {:obj (str obj)
699 | :height height
700 | :path child-path
701 | :highlight-path highlight-path
702 | :width right})))))))
703 |
704 | (defmethod inspector* :uuid
705 | [{:keys [obj width height] :as m}]
706 | (inspector-uuid m))
707 |
708 | (defn inspector-pwrapped [{:keys [obj width height path highlight-path]}]
709 | (let [[left right] (split-ratio (- width 2) one-third)
710 | k 'PWrapped
711 | v (-unwrap obj)]
712 | (ui/horizontal-layout
713 | (indent 1)
714 | (inspector* {:obj k
715 | :height height
716 | :width left})
717 | (indent 1)
718 | (let [child-path (conj path '(-unwrap))]
719 | (wrap-highlight
720 | child-path
721 | highlight-path
722 | (wrap-selection v
723 | child-path
724 | (inspector* {:obj v
725 | :height height
726 | :path child-path
727 | :highlight-path highlight-path
728 | :width right})))))))
729 |
730 | (defmethod inspector* :pwrapped
731 | [{:keys [obj width height] :as m}]
732 | (inspector-pwrapped m))
733 |
734 | (defn inspector-fn [{:keys [obj width height]}]
735 | (ilabel "#function" width))
736 |
737 | (defmethod inspector* :fn
738 | [{:keys [obj width height] :as m}]
739 | (inspector-fn m))
740 |
741 |
742 | (defn inspector-symbol [{:keys [obj width height]}]
743 | (let [ns (namespace obj)
744 | [left right] (if ns
745 | (split-ratio (- width 1) one-third)
746 | [0 width])]
747 | (ui/with-color (:qualifier colors)
748 | (ui/horizontal-layout
749 | (when ns
750 | (ui/horizontal-layout
751 | (ilabel ns left)
752 | (ilabel "/" 1)))
753 | (ilabel (name obj) right)))))
754 | (defmethod inspector* :symbol
755 | [{:keys [obj width height] :as m}]
756 | (inspector-symbol m))
757 |
758 |
759 | (defn inspector-integer [{:keys [obj width height]}]
760 | (ui/with-color (:number colors)
761 | (ilabel obj width)))
762 | (defmethod inspector* :integer
763 | [{:keys [obj width height] :as m}]
764 | (inspector-integer m))
765 |
766 | (defn inspector-float [{:keys [obj width height]}]
767 | (ui/with-color (:number colors)
768 | (ilabel obj width)))
769 | (defmethod inspector* :float
770 | [{:keys [obj width height] :as m}]
771 | (inspector-float m))
772 |
773 | (defn inspector-double [{:keys [obj width height]}]
774 | (ui/with-color (:number colors)
775 | (ilabel obj width)))
776 | (defmethod inspector* :double
777 | [{:keys [obj width height] :as m}]
778 | (inspector-double m))
779 |
780 | (defn inspector-ratio [{:keys [obj width height]}]
781 | (ui/with-color (:number colors)
782 | (ilabel obj width)))
783 | (defmethod inspector* :ratio
784 | [{:keys [obj width height] :as m}]
785 | (inspector-ratio m))
786 |
787 |
788 | (defn inspector-char [{:keys [obj width height]}]
789 | (ui/with-color (:string colors)
790 | (ui/horizontal-layout
791 | (ilabel "\\" 1)
792 | (ilabel obj (dec width)))))
793 | (defmethod inspector* :char
794 | [{:keys [obj width height] :as m}]
795 | (inspector-char m))
796 |
797 | (defn inspector-boolean [{:keys [obj width height]}]
798 | (ui/with-color (:number colors)
799 | (ui/horizontal-layout
800 | (ilabel obj width))))
801 | (defmethod inspector* :boolean
802 | [{:keys [obj width height] :as m}]
803 | (inspector-boolean m))
804 |
805 | (defn inspector-nil [{:keys [obj width height]}]
806 | (ilabel "nil" width))
807 | (defmethod inspector* :nil
808 | [{:keys [obj width height] :as m}]
809 | (inspector-nil m))
810 |
811 |
812 | (defui wrap-resizing [{:keys [resizing?
813 | width
814 | height
815 | body]}]
816 | (if-not resizing?
817 | body
818 | (let [w (+ (* width @cell-width))
819 | h (+ (* height @cell-height))
820 | temp-width (get extra ::temp-width w)
821 | temp-height (get extra ::temp-height h)]
822 | (ui/on
823 | :mouse-up
824 | (fn [_]
825 | [[:set $resizing? false]])
826 | :mouse-move-global
827 | (fn [[x y]]
828 | [[:set $width (int (/ x @cell-width))]
829 | [:set $height (int (/ y @cell-height))]
830 | [:set $temp-width x]
831 | [:set $temp-height y]])
832 | (ui/no-events
833 | [body
834 | (ui/with-color [0.2 0.2 0.2 0.2]
835 | (ui/with-style :membrane.ui/style-stroke
836 | (ui/rectangle w h)))
837 | (ui/spacer (+ temp-width 5)
838 | (+ temp-height 5))])))))
839 |
840 | (defn wrap-drag-start [{:keys [obj path stack]} body]
841 | (ui/on
842 | ::dnd/drag-start
843 | (fn [m]
844 | (let [full-path
845 | (into []
846 | cat
847 | [path
848 | (-> m ::dnd/obj :path)])]
849 | [[::dnd/drag-start
850 | (update m
851 | ::dnd/obj
852 | #(assoc %
853 | :obj obj
854 | :path full-path))]]))
855 | body))
856 |
857 | (defui inspector [{:keys [obj width height show-context?]
858 | :or {width 40
859 | height 1}}]
860 | (let [stack (get extra [obj :stack] [])
861 | path (get extra [obj :path] [])
862 | offsets (get extra [obj :offsets] [0])
863 | offset (peek offsets)
864 | specimen (get extra [obj :specimen] obj)
865 | resizing? (get extra :resizing?)
866 | highlight-path (get extra [obj :highlight-path])]
867 | (wrap-drag-start
868 | {:obj obj
869 | :path path
870 | :stack stack}
871 | (ui/vertical-layout
872 | (when show-context?
873 | (ui/vertical-layout
874 | (basic/button {:text "pop"
875 | :on-click
876 | (fn []
877 | (when (seq stack)
878 | (let [{next-specimen :specimen
879 | next-path :path
880 | next-offsets :offets} (peek stack)]
881 | [[:set $specimen next-specimen]
882 | [:set $path next-path]
883 | [:set $offsets next-offsets]
884 | [:update $stack pop]])))})
885 | (basic/button {:text "resizing"
886 | :on-click
887 | (fn []
888 | [[:set $resizing? true]])})
889 | (ui/label (str "offset: " offset))
890 | (ui/label (str "path: " (pr-str path) ))))
891 | (wrap-resizing
892 | {:resizing? resizing?
893 | :width width
894 | :height height
895 | :body
896 | (let [elem
897 | (ui/on
898 | ::highlight
899 | (fn [path]
900 | [[:set $highlight-path path]])
901 | ::previous-chunk
902 | (fn []
903 | [[:update $offsets
904 | (fn [offsets]
905 | (if (> (count offsets) 1)
906 | (pop offsets)
907 | offsets))]])
908 | ::next-chunk
909 | (fn [delta]
910 | [[:update $offsets
911 | (fn [offsets]
912 | (let [offset (peek offsets)]
913 | (conj offsets (+ offset delta))))]])
914 |
915 | ::select
916 | (fn [x child-path]
917 | [[:update $stack conj {:specimen specimen
918 | :path path
919 | :offsets offsets}]
920 | [:delete $highlight-path]
921 | [:update $path into child-path]
922 | [:set $offsets [0]]
923 | [:set $specimen (wrap x)]])
924 | (ui/wrap-on
925 | :mouse-down
926 | (fn [handler pos]
927 | (let [intents (handler pos)]
928 | (if (seq intents)
929 | intents
930 | [[::dnd/drag-start {::dnd/obj {:x specimen}}]])))
931 | :mouse-move
932 | (fn [handler pos]
933 | (let [intents (handler pos)]
934 | (if (seq intents)
935 | intents
936 | [[:set $highlight-path nil]])))
937 | (inspector* {:obj (-unwrap specimen)
938 | :height height
939 | :path []
940 | :offset offset
941 | :highlight-path highlight-path
942 | :width width} )))
943 | [ew eh] (ui/bounds elem)
944 | pop-button
945 | (ui/on
946 | :mouse-down
947 | (fn [_]
948 | (if (seq stack)
949 | (let [{next-specimen :specimen
950 | next-path :path
951 | next-offsets :offets} (peek stack)]
952 | [[:set $specimen next-specimen]
953 | [:set $path next-path]
954 | [:set $offsets next-offsets]
955 | [:update $stack pop]])
956 | [[:delete $specimen]
957 | [:delete $path]
958 | [:delete $offsets]
959 | [:delete $stack]]))
960 | (ui/filled-rectangle [0 0 1 0.25]
961 | 8 8))
962 | resize-button
963 | (ui/on
964 | :mouse-down
965 | (fn [_]
966 | [[:set $resizing? true]])
967 | (ui/filled-rectangle [1 0 0 0.25]
968 | 8 8))
969 | [rw rh] (ui/bounds resize-button)]
970 | [elem
971 | (ui/translate (- (* width @cell-width)
972 | rw)
973 | (- (* height @cell-height)
974 | rh)
975 | resize-button)
976 | (ui/translate (- (* width @cell-width)
977 | (* 2 rw))
978 | (- (* height @cell-height)
979 | rh)
980 | pop-button)])})))))
981 |
982 |
983 |
984 |
985 |
986 | (defn inspect
987 | "Open an inspector window to view obj."
988 | ([obj]
989 | (inspect obj {}))
990 | ([obj {:keys [width height show-context? sync?] :as opts
991 | :or {show-context? true}}]
992 | (let [width (or width 80)
993 | height (or height 40)
994 | app (component/make-app #'inspector
995 | {:obj (wrap obj)
996 | :width width
997 | :show-context? show-context?
998 | :height height})
999 |
1000 | [empty-width empty-height] (ui/bounds ((component/make-app #'inspector
1001 | {:obj (wrap nil)
1002 | :width 0
1003 | :height 0})))
1004 | window-width (+ 50
1005 | (max empty-width
1006 | (* @cell-width width)))
1007 | window-height (+ 100
1008 | empty-height
1009 | height
1010 | (* @cell-height (inc height)))
1011 | run (if sync?
1012 | tk/run-sync
1013 | tk/run)]
1014 | (run @toolkit
1015 | app
1016 | {:window-title "Inspect"
1017 | :window-start-width window-width
1018 | :window-start-height window-height}))))
1019 |
1020 |
1021 |
1022 | (comment
1023 | [clojure.spec.alpha :as s]
1024 | [clojure.spec.gen.alpha :as gen]
1025 | (s/def ::anything any? )
1026 |
1027 | (do
1028 | (def obj (gen/generate (s/gen ::anything) )
1029 | )
1030 | (inspect (gen/sample (s/gen ::anything)
1031 | 100))
1032 | obj)
1033 |
1034 | (backend/run #'inspector-test)
1035 | ,)
1036 |
1037 |
1038 | (comment
1039 | (require '[pl.danieljanus.tagsoup :as tagsoup])
1040 | (require '[clojure.data.json :as json])
1041 |
1042 | (inspect (read-string (slurp "deps.edn")))
1043 |
1044 | (inspect ((requiring-resolve 'pl.danieljanus.tagsoup/parse-string) (slurp "https://clojure.org/reference/reader"))
1045 | {:height 10})
1046 |
1047 | (inspect (gen/generate (s/gen ::anything)))
1048 |
1049 | (inspect (json/read-str (slurp "https://raw.githubusercontent.com/dreadwarrior/ext-giftcertificates/5e447a7316aea57a372203f2aa8de5aef3af671a/ExtensionBuilder.json")) )
1050 |
1051 | ,
1052 | )
1053 |
1054 | (comment
1055 | (def a (atom nil))
1056 | (def b (atom a))
1057 | (reset! a b)
1058 | (inspect a)
1059 | ,)
1060 |
1061 |
--------------------------------------------------------------------------------
/src/com/phronemophobic/viscous/cli.clj:
--------------------------------------------------------------------------------
1 | (ns com.phronemophobic.viscous.cli
2 | (:require [com.phronemophobic.viscous :as viscous]
3 | [clojure.edn :as edn]
4 | [clojure.java.io :as io])
5 | (:import java.io.PushbackReader
6 | java.io.StringReader))
7 |
8 | (defn read-edn [rdr]
9 | (with-open [rdr (java.io.PushbackReader. rdr)]
10 | (edn/read {:default tagged-literal} rdr)))
11 |
12 |
13 | (defn read-json [rdr]
14 | (with-open [rdr rdr]
15 | ((requiring-resolve 'clojure.data.json/read) rdr)))
16 |
17 | (def help-text
18 | "Open a viscous data inspector.
19 |
20 | Usage:
21 |
22 | Read edn from stdin:
23 | cat data.edn | clojure -X:viscous :file -
24 |
25 | Read edn from filename:
26 | clojure -X:viscous :file data.edn
27 |
28 | Read json from stdin:
29 | cat data.json | clojure -X:viscous :json-file -
30 |
31 | Read json from filename:
32 | clojure -X:viscous :json-file data.edn
33 | ")
34 |
35 | (defn main [{:keys [file edn json-file json] :as opts}]
36 | (let [obj
37 | (cond
38 | (= (str file) "-") (read-edn (io/reader *in*))
39 | file (read-edn (io/reader (str file)))
40 | edn (read-edn (StringReader. (str edn)))
41 |
42 | (= (str json-file) "-") (read-json (io/reader *in*))
43 | json-file (read-json (io/reader (str json-file)))
44 | json (read-json (StringReader. (str json)))
45 |
46 | :else ::print-help)]
47 | (if (= obj ::print-help)
48 | (println help-text)
49 | (viscous/inspect obj
50 | (merge
51 | (select-keys opts [:width :height :show-context?])
52 | {:sync? true})))))
53 |
--------------------------------------------------------------------------------
/src/com/phronemophobic/viscous/demo.cljs:
--------------------------------------------------------------------------------
1 | (ns com.phronemophobic.viscous.demo
2 | (:require
3 | [membrane.ui :as ui]
4 | [goog.net.XhrIo :as xhr]
5 | clojure.edn
6 | [membrane.basic-components :as basic]
7 | [com.phronemophobic.viscous :as viscous]
8 | [membrane.webgl :as webgl]
9 | [membrane.component :refer [defui defeffect]
10 | :as component]))
11 |
12 |
13 | (defn $ [id]
14 | (js/document.getElementById id))
15 |
16 | (def blob-area ($ "blobarea"))
17 | (def update-btn ($ "update-btn"))
18 | (def url-input ($ "url-input"))
19 | (def fetch-example-select ($ "fetch-example-select"))
20 | (def fetch-btn ($ "fetch-btn"))
21 | (def fetch-example-btn ($ "fetch-example-btn"))
22 |
23 | (def obj {:a {:b 42}})
24 | (def width 80)
25 | (def height 40)
26 | (defonce repaint nil)
27 | (defonce demo-state (atom {:obj (viscous/wrap obj)
28 | :width 80
29 | :height 40
30 | :show-context? true}))
31 | (defn update-viscous [obj err]
32 | (swap! demo-state
33 | (fn [state]
34 | (-> state
35 | (assoc :obj (viscous/wrap obj))
36 | (dissoc :membrane.component/extra))))
37 | (repaint))
38 |
39 | (defn parse-edn-or-json [s]
40 | (try
41 | [nil (clojure.edn/read-string {:default (fn [tag x]
42 | x)}
43 | s)]
44 | (catch js/Object edn-error
45 | (prn edn-error)
46 | (try
47 | [nil (js/JSON.parse s)]
48 | (catch js/Object json-error
49 | (prn json-error)
50 | [[edn-error json-error]
51 | nil])))))
52 |
53 | (defonce button-listen (.addEventListener
54 | update-btn
55 | "click"
56 | (fn []
57 | (let [blob (.-value blob-area)
58 | [errs obj] (parse-edn-or-json blob)]
59 | (update-viscous obj errs)))))
60 |
61 |
62 |
63 | (defonce fetch-listen (.addEventListener
64 | fetch-btn
65 | "click"
66 | (fn []
67 | (let [url (.-value url-input)]
68 | (xhr/send url
69 | (fn [e]
70 | (let [x (.-target e)
71 | [errs obj] (parse-edn-or-json (.getResponseText ^js x))]
72 | (update-viscous obj errs))))))))
73 |
74 | (defonce fetch-example-listen (.addEventListener
75 | fetch-example-btn
76 | "click"
77 | (fn []
78 | (let [url (.-value fetch-example-select)]
79 | (xhr/send url
80 | (fn [e]
81 | (let [x (.-target e)
82 | [errs obj] (parse-edn-or-json (.getResponseText ^js x))]
83 | (update-viscous obj errs))))))))
84 |
85 |
86 |
87 | (def canvas (.getElementById js/document "canvas"))
88 | (defn -main []
89 | (webgl/load-font
90 | (:name @viscous/monospaced)
91 | "https://fonts.googleapis.com/css2?family=Ubuntu+Mono&display=swap"
92 | "https://fonts.gstatic.com/s/ubuntumono/v6/EgeuS9OtEmA0y_JRo03MQaCWcynf_cDxXwCLxiixG1c.ttf"
93 |
94 | (fn []
95 | (let [freetype-font (webgl/get-font @viscous/monospaced)
96 | space-glyph (-> freetype-font
97 | (.-glyphs)
98 | (.-glyphs)
99 | (aget 3))
100 | font-size (:size ui/default-font)
101 | fscale (membrane.webgl/font-scale freetype-font font-size)
102 | advance (* fscale (.-advanceWidth space-glyph))]
103 | (set! viscous/cell-width (delay advance))
104 | (set! viscous/cell-height (delay (membrane.webgl/font-line-height @viscous/monospaced))))
105 |
106 | #_(js/console.log (-> (.-fonts js/document)
107 | (.load (str
108 | (:size ui/default-font) "px"
109 | " "
110 | "\"Ubuntu Mono\""
111 | ;;(:name ui/default-font)
112 | ))))
113 |
114 | (let [
115 |
116 | app (component/make-app #'viscous/inspector
117 | demo-state)
118 |
119 | [empty-width empty-height] (ui/bounds ((component/make-app #'viscous/inspector
120 | {:obj (viscous/wrap nil)
121 | :width 0
122 | :height 0})))
123 | window-width (max empty-width
124 | (* @viscous/cell-width width))
125 | window-height (+ empty-height
126 | height
127 | (* @viscous/cell-height (inc height)))]
128 | (defonce canvas-info (membrane.webgl/run
129 | app
130 | {:container canvas}))
131 | (set! repaint (:membrane.webgl/repaint canvas-info))))))
132 |
133 |
--------------------------------------------------------------------------------
/test/com/phronemophobic/membrane/pretty_view_test.clj:
--------------------------------------------------------------------------------
1 | (ns com.phronemophobic.membrane.pretty-view-test
2 | (:require [clojure.test :refer :all]
3 | [com.phronemophobic.membrane.pretty-view :refer :all]))
4 |
5 | (deftest a-test
6 | (testing "FIXME, I fail."
7 | (is (= 0 1))))
8 |
--------------------------------------------------------------------------------