From ce1a7a131f7c4df8eae5c019eba2893b56f04d46 Mon Sep 17 00:00:00 2001
From: Eduardo Julian
Date: Thu, 24 Jun 2021 03:42:57 -0400
Subject: Added a macro for type-casting JVM objects.

---
 commands.md                                        |  12 +-
 .../bookmark/Probabilistic data-structure.md       |  32 --
 documentation/bookmark/Recursion schemes.md        |  16 -
 documentation/bookmark/Testing.md                  |  16 -
 documentation/bookmark/browser.md                  |   1 +
 documentation/bookmark/cryptography.md             |   1 +
 documentation/bookmark/data_science.md             |   4 +
 documentation/bookmark/database.md                 |   4 +
 documentation/bookmark/debugging.md                |   1 -
 documentation/bookmark/documentation.md            |   4 +
 documentation/bookmark/game_programming.md         |   1 +
 documentation/bookmark/inspiration.md              |   2 +-
 documentation/bookmark/machine_learning.md         |   4 +
 documentation/bookmark/math.md                     |   2 +
 documentation/bookmark/music.md                    |   4 +
 documentation/bookmark/optics.md                   |   1 +
 documentation/bookmark/platform/jvm.md             |   4 +
 .../bookmark/probabilistic_data_structure.md       |  33 ++
 documentation/bookmark/process.md                  |   4 +
 documentation/bookmark/recursion_schemes.md        |  17 +
 documentation/bookmark/security.md                 |   9 +
 documentation/bookmark/state_action_model.md       |   8 +
 documentation/bookmark/testing.md                  |  20 +
 documentation/bookmark/text_editor & ide.md        | 235 -----------
 documentation/bookmark/time.md                     |   4 +
 .../tool/integrated_development_environment.md     |   9 +
 documentation/bookmark/tool/text_editor.md         | 243 +++++++++++
 documentation/bookmark/user_interface/color.md     |   4 +
 documentation/bookmark/user_interface/desktop.md   |   4 +
 documentation/bookmark/web_framework.md            |   1 +
 licentia/source/program/licentia/document.lux      |   1 +
 stdlib/source/lux/ffi.jvm.lux                      |  20 +-
 stdlib/source/lux/math.lux                         |  39 +-
 stdlib/source/lux/math/number/complex.lux          |   4 +-
 stdlib/source/lux/test.lux                         |   7 +
 .../source/lux/tool/compiler/default/platform.lux  |   7 +-
 .../source/lux/tool/compiler/meta/io/archive.lux   |   6 +-
 .../source/lux/tool/compiler/meta/io/context.lux   |  50 +--
 stdlib/source/lux/world/file.lux                   |   2 +-
 stdlib/source/lux/world/shell.lux                  |   3 +-
 stdlib/source/program/aedifex.lux                  |   4 +-
 stdlib/source/program/aedifex/command/auto.lux     |  16 +-
 stdlib/source/program/aedifex/command/build.lux    | 128 +++---
 stdlib/source/program/aedifex/command/test.lux     |   6 +-
 stdlib/source/program/aedifex/format.lux           |   2 +-
 stdlib/source/program/aedifex/parser.lux           |   5 +-
 stdlib/source/program/aedifex/profile.lux          |  12 +-
 stdlib/source/test/aedifex/command.lux             |   9 +-
 stdlib/source/test/aedifex/command/auto.lux        |  29 +-
 stdlib/source/test/aedifex/command/build.lux       |  12 +-
 stdlib/source/test/aedifex/command/test.lux        |  10 +-
 .../source/test/aedifex/dependency/resolution.lux  | 457 +++++++++++----------
 stdlib/source/test/aedifex/input.lux               |  17 +-
 stdlib/source/test/lux/math.lux                    | 182 +++++---
 54 files changed, 985 insertions(+), 743 deletions(-)
 delete mode 100644 documentation/bookmark/Probabilistic data-structure.md
 delete mode 100644 documentation/bookmark/Recursion schemes.md
 delete mode 100644 documentation/bookmark/Testing.md
 create mode 100644 documentation/bookmark/data_science.md
 create mode 100644 documentation/bookmark/platform/jvm.md
 create mode 100644 documentation/bookmark/probabilistic_data_structure.md
 create mode 100644 documentation/bookmark/process.md
 create mode 100644 documentation/bookmark/recursion_schemes.md
 create mode 100644 documentation/bookmark/state_action_model.md
 create mode 100644 documentation/bookmark/testing.md
 delete mode 100644 documentation/bookmark/text_editor & ide.md
 create mode 100644 documentation/bookmark/time.md
 create mode 100644 documentation/bookmark/tool/integrated_development_environment.md
 create mode 100644 documentation/bookmark/tool/text_editor.md
 create mode 100644 documentation/bookmark/user_interface/color.md
 create mode 100644 documentation/bookmark/user_interface/desktop.md

diff --git a/commands.md b/commands.md
index fec682c49..89eebb4c2 100644
--- a/commands.md
+++ b/commands.md
@@ -17,22 +17,14 @@ cd ~/lux/lux-python/ && lein clean && \
 cd ~/lux/lux-lua/ && lein clean && \
 cd ~/lux/lux-ruby/ && lein clean && \
 cd ~/lux/lux-php/ && lein clean && \
-cd ~/lux/lux-cl/ && lein clean && \
 cd ~/lux/lux-scheme/ && lein clean && \
+cd ~/lux/lux-cl/ && lein clean && \
 cd ~/lux/lux-r/ && lein clean
 
 ```
 
 ---
 
-# Read generated bytecode
-
-```
-cd ~/lux/jbe/bin/ && java ee.ioc.cs.jbe.browser.BrowserApplication
-```
-
----
-
 # Old/bootstrapping compiler
 
 ## Build & install
@@ -41,7 +33,7 @@ cd ~/lux/jbe/bin/ && java ee.ioc.cs.jbe.browser.BrowserApplication
 cd ~/lux/lux-bootstrapper/ && lein clean && lein install
 ```
 
-## Run JBE
+## Run JBE (Read generated bytecode)
 
 ```
 cd ~/lux/jbe/bin/ && java ee.ioc.cs.jbe.browser.BrowserApplication
diff --git a/documentation/bookmark/Probabilistic data-structure.md b/documentation/bookmark/Probabilistic data-structure.md
deleted file mode 100644
index f7c025de2..000000000
--- a/documentation/bookmark/Probabilistic data-structure.md	
+++ /dev/null
@@ -1,32 +0,0 @@
-# Hash function
-
-1. http://fastcompression.blogspot.com/2019/03/presenting-xxh3.html
-1. http://cyan4973.github.io/xxHash/
-
-# Reference
-
-1. [Xor Filters: Faster and Smaller Than Bloom Filters](https://lemire.me/blog/2019/12/19/xor-filters-faster-and-smaller-than-bloom-filters/)
-1. [Morton Filters: Faster, Space-Efficient Cuckoo Filters via Biasing, Compression, and Decoupled Logical Sparsity](http://www.vldb.org/pvldb/vol11/p1041-breslow.pdf)
-1. https://github.com/efficient/SuRF
-1. https://medium.com/orbs-network/constructing-bloom-filters-without-false-positives-7aaf50b92f3b
-1. https://welcometotheoryland.wordpress.com/2017/10/19/what-is-a-hash-function-it-depends-on-whos-speaking/
-1. http://docs.pipelinedb.com/probabilistic.html
-1. [Probabilistic Data Structures](https://www.youtube.com/watch?v=F7EhDBfsTA8)
-1. http://www.i-programmer.info/programming/theory/4641-the-invertible-bloom-filter.html
-1. https://github.com/seiflotfy/hyperbitbit
-1. https://blog.yld.io/2017/04/19/hyperloglog-a-probabilistic-data-structure/#.WPtT_R_6zCI
-1. http://www.partow.net/programming/bloomfilter/idx.html
-1. https://github.com/pawandubey/cuckoo_filter
-1. https://cloud.google.com/blog/big-data/2017/07/counting-uniques-faster-in-bigquery-with-hyperloglog
-1. https://blog.dataweave.com/using-probabilistic-data-structures-to-build-real-time-monitoring-dashboards-25b17c968c08
-1. https://bdupras.github.io/filter-tutorial/
-1. https://sagi.io/2017/07/bloom-filters-for-the-perplexed/
-1. https://www.somethingsimilar.com/2012/05/21/the-opposite-of-a-bloom-filter/
-1. https://github.com/splatlab/cqf
-1. [LogLog-Beta and More: A New Algorithm for Cardinality Estimation Based on LogLog Counting](https://arxiv.org/ftp/arxiv/papers/1612/1612.02284.pdf)
-1. https://blog.acolyer.org/2017/08/08/a-general-purpose-counting-filter-making-every-bit-count/
-1. [Ode on a Random Urn (Functional Pearl)](https://www.youtube.com/watch?v=O37FMxLxm78)
-1. http://smalldatum.blogspot.com/2018/09/bloom-filter-and-cuckoo-filter.html
-1. https://hackernoon.com/cuckoo-filter-vs-bloom-filter-from-a-gophers-perspective-94d5e6c53299
-1. https://github.com/axiomhq/hyperminhash
-
diff --git a/documentation/bookmark/Recursion schemes.md b/documentation/bookmark/Recursion schemes.md
deleted file mode 100644
index fe65ffca6..000000000
--- a/documentation/bookmark/Recursion schemes.md	
+++ /dev/null
@@ -1,16 +0,0 @@
-# Reference
-
-1. http://maartenfokkinga.github.io/utwente/mmf91m.pdf
-1. http://blog.sumtypeofway.com/an-introduction-to-recursion-schemes/
-1. http://blog.sumtypeofway.com/recursion-schemes-part-2/
-1. http://blog.sumtypeofway.com/recursion-schemes-part-iii-folds-in-context/
-1. http://blog.sumtypeofway.com/recursion-schemes-part-iv-time-is-of-the-essence/
-1. http://comonad.com/reader/2009/recursion-schemes/
-1. [Peeling the Banana: Recursion Schemes from First Principles - Zainab Ali](https://www.youtube.com/watch?v=XZ9nPZbaYfE)
-1. https://github.com/passy/awesome-recursion-schemes
-1. [YOW! Lambda Jam 2018 - Amy Wong - Introduction to recursion scheme](https://www.youtube.com/watch?v=YnqPdlJd38o)
-1. https://bartoszmilewski.com/2018/08/20/recursion-schemes-for-higher-algebras/
-1. https://blog.sumtypeofway.com/recursion-schemes-part-6-comonads-composition-and-generality/
-1. https://chrilves.github.io/hugo/posts/recursion_schemes_intro/
-1. [Recursion Schemes: A Field Guide (Redux)](http://comonad.com/reader/2009/recursion-schemes/)
-
diff --git a/documentation/bookmark/Testing.md b/documentation/bookmark/Testing.md
deleted file mode 100644
index 92e56eff3..000000000
--- a/documentation/bookmark/Testing.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Concolic Testing
-
-1. [Robby Findler: Concolic Testing with Higher-Order Inputs](https://www.youtube.com/watch?v=aO9nOCqNdfQ)
-
-# Symbolic
-
-1. [Crux](https://crux.galois.com/)
-
-# White box
-
-1. [Ricardo Peña - White-Box Path Generation in Recursive Programs - Lambda Days 2020](https://www.youtube.com/watch?v=7RXJhPaQCkc)
-
-# Mocking
-
-1. [Testing Without Mocks: A Pattern Language](https://www.jamesshore.com/Blog/Testing-Without-Mocks.html)
-
diff --git a/documentation/bookmark/browser.md b/documentation/bookmark/browser.md
index 2521275e8..e2f95c54c 100644
--- a/documentation/bookmark/browser.md
+++ b/documentation/bookmark/browser.md
@@ -1,5 +1,6 @@
 # Exemplar
 
+1. [Stack](https://stackbrowser.com/)
 1. [Flow: The super fast, multithreaded HTML5 browser from Ekioh](https://www.ekioh.com/flow-browser/)
 1. https://refresh.study/
 1. https://github.com/breach/breach_core
diff --git a/documentation/bookmark/cryptography.md b/documentation/bookmark/cryptography.md
index 7eaf9cc9f..f86e70ccb 100644
--- a/documentation/bookmark/cryptography.md
+++ b/documentation/bookmark/cryptography.md
@@ -18,6 +18,7 @@
 
 # Library
 
+1. [aykxt/crypto](https://github.com/aykxt/crypto)
 1. [zinc: Introduce minimal cryptography library](https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/linux.git/commit/?h=zinc)
 1. https://joshlf.com/post/2018/11/06/introducing-mundane/
 1. https://github.com/akhawaja/ecc-crypto-helper
diff --git a/documentation/bookmark/data_science.md b/documentation/bookmark/data_science.md
new file mode 100644
index 000000000..d505d3178
--- /dev/null
+++ b/documentation/bookmark/data_science.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [High Performance Data With Clojure Chris Nuernberger](https://www.youtube.com/watch?v=5mUGu4RlwKE)
+
diff --git a/documentation/bookmark/database.md b/documentation/bookmark/database.md
index 8441522df..5dc141142 100644
--- a/documentation/bookmark/database.md
+++ b/documentation/bookmark/database.md
@@ -203,6 +203,10 @@
 
 1. https://blog.acolyer.org/2018/09/26/the-design-and-implementation-of-modern-column-oriented-database-systems/
 
+## Datalog
+
+1. [Open Source Clojure-Datalog Databases](https://clojurelog.github.io/)
+
 ## Log
 
 1. https://code.fb.com/core-data/logdevice-a-distributed-data-store-for-logs/
diff --git a/documentation/bookmark/debugging.md b/documentation/bookmark/debugging.md
index f870c5d94..8fb385ed6 100644
--- a/documentation/bookmark/debugging.md
+++ b/documentation/bookmark/debugging.md
@@ -21,7 +21,6 @@
 1. https://github.com/srg-imperial/SaBRe
 1. https://developer.mozilla.org/en-US/docs/Mozilla/Projects/WebReplay
 1. https://umaar.github.io/performance-debugging-devtools-2018/#/
-1. https://microsoft.github.io/debug-adapter-protocol/
 1. http://plasma-umass.org/BLeak/
 1. https://clinicjs.org/
 1. http://pev.sourceforge.net/
diff --git a/documentation/bookmark/documentation.md b/documentation/bookmark/documentation.md
index 2bb1d12e6..44f79fb5f 100644
--- a/documentation/bookmark/documentation.md
+++ b/documentation/bookmark/documentation.md
@@ -1,3 +1,7 @@
+# Architecture
+
+1. [ARCHITECTURE.md](https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html)
+
 # Programming
 
 1. [Skribilo: The Ultimate Document Programming Framework](https://www.nongnu.org/skribilo/)
diff --git a/documentation/bookmark/game_programming.md b/documentation/bookmark/game_programming.md
index 2f5b3538c..be969f87d 100644
--- a/documentation/bookmark/game_programming.md
+++ b/documentation/bookmark/game_programming.md
@@ -24,6 +24,7 @@
 
 # Procedural generation
 
+1. [Dungeon Map Generation with Locks and Keys](https://beta.aceparent.me/#/raids)
 1. [Aaron Santos - Optimizing procgen parameters using mini-batch gradient descent](https://www.youtube.com/watch?v=TsDIUuEneo4)
 1. [Brian Bucklew - Dungeon Generation via Wave Function Collapse](https://www.youtube.com/watch?v=fnFj3dOKcIQ)
 1. [So you want to build a generator…](https://galaxykate0.tumblr.com/post/139774965871/so-you-want-to-build-a-generator)
diff --git a/documentation/bookmark/inspiration.md b/documentation/bookmark/inspiration.md
index febf3a54f..6eaa9ac34 100644
--- a/documentation/bookmark/inspiration.md
+++ b/documentation/bookmark/inspiration.md
@@ -1,7 +1,7 @@
 # Possibility
 
 1. ["What next?"](https://graydon.livejournal.com/256533.html) && ["What next?"](https://graydon2.dreamwidth.org/253769.html)
-1. []()
+1. [A Case for a Native Runtime Compilation Language](https://jott.live/markdown/dynamic_compilation)
 
 # Falsehood
 
diff --git a/documentation/bookmark/machine_learning.md b/documentation/bookmark/machine_learning.md
index 4946d749b..2c05864f7 100644
--- a/documentation/bookmark/machine_learning.md
+++ b/documentation/bookmark/machine_learning.md
@@ -28,6 +28,10 @@
 1. https://heartbeat.fritz.ai/capsule-networks-a-new-and-attractive-ai-architecture-bd1198cc8ad4
 1. http://super-ms.mit.edu/rum.html
 
+# Inductive logic programming
+
+1. [Inductive logic programming at 30: a new introduction](https://arxiv.org/abs/2008.07912)
+
 # Deep learning
 
 1. [GAME2020 4. Dr. Vincent Nozick Geometric Neurons](https://www.youtube.com/watch?v=KC3c_Mdj1dk)
diff --git a/documentation/bookmark/math.md b/documentation/bookmark/math.md
index 9d5309612..333fd6591 100644
--- a/documentation/bookmark/math.md
+++ b/documentation/bookmark/math.md
@@ -363,6 +363,7 @@
 
 # Hyperbolic geometry
 
+1. [Intuitive Guide to Hyperbolic Functions](https://betterexplained.com/articles/hyperbolic-functions/)
 1. [Hyperbolic Functions and Non-Hyperbolic Claims](https://elliptigon.com/hyperbolic-functions-explained/)
 
 # Dual numbers
@@ -371,6 +372,7 @@
 
 # **Temp Cache**
 
+1. https://mathlets.org/mathlets/
 1. [Quadratic splines are useful too](https://wordsandbuttons.online/quadric_splines_are_useful_too.html)
 1. [Derivations of Applied Mathematics](http://www.derivations.org/)
 1. https://www.juliahomotopycontinuation.org/
diff --git a/documentation/bookmark/music.md b/documentation/bookmark/music.md
index e4a6124d2..e68491b50 100644
--- a/documentation/bookmark/music.md
+++ b/documentation/bookmark/music.md
@@ -1,3 +1,7 @@
+# Async music
+
+1. [async music](https://async.art/music)
+
 # Reference
 
 1. [Open Music Theory](http://openmusictheory.com/)
diff --git a/documentation/bookmark/optics.md b/documentation/bookmark/optics.md
index 903c2ff54..e3662b356 100644
--- a/documentation/bookmark/optics.md
+++ b/documentation/bookmark/optics.md
@@ -1,5 +1,6 @@
 # Reference
 
+1. [Optics By Example](https://leanpub.com/optics-by-example)
 1. [Profunctor optics, a categorical update](https://arxiv.org/abs/2001.07488)
 1. [On Lawful Lenses](https://blog.statebox.org/on-lawful-lenses-6e18a1e17bdf)
 1. https://medium.com/urbint-engineering/haskell-lens-operator-onboarding-a235481e8fac
diff --git a/documentation/bookmark/platform/jvm.md b/documentation/bookmark/platform/jvm.md
new file mode 100644
index 000000000..2ed871a36
--- /dev/null
+++ b/documentation/bookmark/platform/jvm.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [JVM Anatomy Quarks](https://shipilev.net/jvm/anatomy-quarks/)
+
diff --git a/documentation/bookmark/probabilistic_data_structure.md b/documentation/bookmark/probabilistic_data_structure.md
new file mode 100644
index 000000000..0e1fe5986
--- /dev/null
+++ b/documentation/bookmark/probabilistic_data_structure.md
@@ -0,0 +1,33 @@
+# Hash function
+
+1. http://fastcompression.blogspot.com/2019/03/presenting-xxh3.html
+1. http://cyan4973.github.io/xxHash/
+
+# Reference
+
+1. [Teaching Bloom Filters new tricks](https://toao.com/blog/teaching-bloom-filters-new-tricks)
+1. [Xor Filters: Faster and Smaller Than Bloom Filters](https://lemire.me/blog/2019/12/19/xor-filters-faster-and-smaller-than-bloom-filters/)
+1. [Morton Filters: Faster, Space-Efficient Cuckoo Filters via Biasing, Compression, and Decoupled Logical Sparsity](http://www.vldb.org/pvldb/vol11/p1041-breslow.pdf)
+1. https://github.com/efficient/SuRF
+1. https://medium.com/orbs-network/constructing-bloom-filters-without-false-positives-7aaf50b92f3b
+1. https://welcometotheoryland.wordpress.com/2017/10/19/what-is-a-hash-function-it-depends-on-whos-speaking/
+1. http://docs.pipelinedb.com/probabilistic.html
+1. [Probabilistic Data Structures](https://www.youtube.com/watch?v=F7EhDBfsTA8)
+1. http://www.i-programmer.info/programming/theory/4641-the-invertible-bloom-filter.html
+1. https://github.com/seiflotfy/hyperbitbit
+1. https://blog.yld.io/2017/04/19/hyperloglog-a-probabilistic-data-structure/#.WPtT_R_6zCI
+1. http://www.partow.net/programming/bloomfilter/idx.html
+1. https://github.com/pawandubey/cuckoo_filter
+1. https://cloud.google.com/blog/big-data/2017/07/counting-uniques-faster-in-bigquery-with-hyperloglog
+1. https://blog.dataweave.com/using-probabilistic-data-structures-to-build-real-time-monitoring-dashboards-25b17c968c08
+1. https://bdupras.github.io/filter-tutorial/
+1. https://sagi.io/2017/07/bloom-filters-for-the-perplexed/
+1. https://www.somethingsimilar.com/2012/05/21/the-opposite-of-a-bloom-filter/
+1. https://github.com/splatlab/cqf
+1. [LogLog-Beta and More: A New Algorithm for Cardinality Estimation Based on LogLog Counting](https://arxiv.org/ftp/arxiv/papers/1612/1612.02284.pdf)
+1. https://blog.acolyer.org/2017/08/08/a-general-purpose-counting-filter-making-every-bit-count/
+1. [Ode on a Random Urn (Functional Pearl)](https://www.youtube.com/watch?v=O37FMxLxm78)
+1. http://smalldatum.blogspot.com/2018/09/bloom-filter-and-cuckoo-filter.html
+1. https://hackernoon.com/cuckoo-filter-vs-bloom-filter-from-a-gophers-perspective-94d5e6c53299
+1. https://github.com/axiomhq/hyperminhash
+
diff --git a/documentation/bookmark/process.md b/documentation/bookmark/process.md
new file mode 100644
index 000000000..448461579
--- /dev/null
+++ b/documentation/bookmark/process.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [No code reviews by default](https://raycast.com/blog/no-code-reviews-by-default/)
+
diff --git a/documentation/bookmark/recursion_schemes.md b/documentation/bookmark/recursion_schemes.md
new file mode 100644
index 000000000..94951b99c
--- /dev/null
+++ b/documentation/bookmark/recursion_schemes.md
@@ -0,0 +1,17 @@
+# Reference
+
+1. [Unifying Structured Recursion Schemes](https://www.cs.ox.ac.uk/people/nicolas.wu/papers/URS.pdf)
+1. http://maartenfokkinga.github.io/utwente/mmf91m.pdf
+1. http://blog.sumtypeofway.com/an-introduction-to-recursion-schemes/
+1. http://blog.sumtypeofway.com/recursion-schemes-part-2/
+1. http://blog.sumtypeofway.com/recursion-schemes-part-iii-folds-in-context/
+1. http://blog.sumtypeofway.com/recursion-schemes-part-iv-time-is-of-the-essence/
+1. http://comonad.com/reader/2009/recursion-schemes/
+1. [Peeling the Banana: Recursion Schemes from First Principles - Zainab Ali](https://www.youtube.com/watch?v=XZ9nPZbaYfE)
+1. https://github.com/passy/awesome-recursion-schemes
+1. [YOW! Lambda Jam 2018 - Amy Wong - Introduction to recursion scheme](https://www.youtube.com/watch?v=YnqPdlJd38o)
+1. https://bartoszmilewski.com/2018/08/20/recursion-schemes-for-higher-algebras/
+1. https://blog.sumtypeofway.com/recursion-schemes-part-6-comonads-composition-and-generality/
+1. https://chrilves.github.io/hugo/posts/recursion_schemes_intro/
+1. [Recursion Schemes: A Field Guide (Redux)](http://comonad.com/reader/2009/recursion-schemes/)
+
diff --git a/documentation/bookmark/security.md b/documentation/bookmark/security.md
index 6809cd624..6439b9e20 100644
--- a/documentation/bookmark/security.md
+++ b/documentation/bookmark/security.md
@@ -1,3 +1,11 @@
+# Secrets
+
+1. [How to Handle Secrets on the Command Line](https://smallstep.com/blog/command-line-secrets/)
+
+# Capability
+
+1. [A Comparison of the Capability Systems of Encore, Pony and Rust](https://uu.diva-portal.org/smash/get/diva2:1363822/FULLTEXT01.pdf)
+
 # Homomorphic encryption
 
 1. https://github.com/Microsoft/SEAL
@@ -60,6 +68,7 @@
 
 # Reference
 
+1. [Intro to Just-In-Time Access](https://compliance.dev/2021/04/29/introduction-to-just-in-time-access/)
 1. https://www.nomoreransom.org/en/index.html
 1. [Open Source Security Foundation (OpenSSF)](https://openssf.org/)
 1. [Don't get pwned: practicing the principle of least privilege](https://cloud.google.com/blog/products/identity-security/dont-get-pwned-practicing-the-principle-of-least-privilege)
diff --git a/documentation/bookmark/state_action_model.md b/documentation/bookmark/state_action_model.md
new file mode 100644
index 000000000..bd09d8013
--- /dev/null
+++ b/documentation/bookmark/state_action_model.md
@@ -0,0 +1,8 @@
+# Reference
+
+1. [The SAM Pattern](http://sam.js.org/)
+
+# Language
+
+1. [Beads](https://beadslang.org/the-beads-project)
+
diff --git a/documentation/bookmark/testing.md b/documentation/bookmark/testing.md
new file mode 100644
index 000000000..4a1930de2
--- /dev/null
+++ b/documentation/bookmark/testing.md
@@ -0,0 +1,20 @@
+# Concolic Testing
+
+1. [Robby Findler: Concolic Testing with Higher-Order Inputs](https://www.youtube.com/watch?v=aO9nOCqNdfQ)
+
+# Symbolic
+
+1. [Crux](https://crux.galois.com/)
+
+# White box
+
+1. [Ricardo Peña - White-Box Path Generation in Recursive Programs - Lambda Days 2020](https://www.youtube.com/watch?v=7RXJhPaQCkc)
+
+# Mocking
+
+1. [Testing Without Mocks: A Pattern Language](https://www.jamesshore.com/Blog/Testing-Without-Mocks.html)
+
+# Visual Testing
+
+1. [Visual Testing Handbook](https://storybook.js.org/tutorials/visual-testing-handbook/)
+
diff --git a/documentation/bookmark/text_editor & ide.md b/documentation/bookmark/text_editor & ide.md
deleted file mode 100644
index 62e953e7b..000000000
--- a/documentation/bookmark/text_editor & ide.md	
+++ /dev/null
@@ -1,235 +0,0 @@
-# Rendering
-
-1. [Graphics for JVM](https://tonsky.me/blog/skija/)
-1. https://github.com/JetBrains/skija/
-1. https://github.com/JetBrains/skiko/
-1. https://github.com/JetBrains/compose-jb
-
-# Residential programming
-
-1. [Residential Programming without Mutable State - Thomas Getgood](https://www.youtube.com/watch?v=Kgw9fblSOx4)
-
-# Good Ideas
-
-1. https://medium.com/@NikitaVoloboev/write-once-never-write-again-c2fa1f6c4e8
-1. [Inline: Efficient Source Code Editing and Manipulation with Code Portals](https://www.youtube.com/watch?v=NQ5h2Ibw6ck)
-1. https://devclass.com/2019/02/15/atlassian-make-jira-invisible-target-developers-ides/
-1. http://lispm.de/genera-concepts
-1. Hovering/selecting an input to a function inside a function-call should display the name of the input in the function declaration. This would help understand the purpose of the value while in the function call without needing Lux/the-language to have named inputs as a feature.
-1. https://www.emacswiki.org/emacs/UndoTree
-1. https://jameshfisher.com/2014/05/11/your-syntax-highlighter-is-wrong/
-1. https://medium.com/@evnbr/coding-in-color-3a6db2743a1e
-
-# Voice
-
-1. [Speaking in code: how to program by voice](https://www.nature.com/articles/d41586-018-05588-x)
-
-# Refactoring
-
-1. https://medium.com/zoosk-engineering/refactoring-at-scale-with-abstract-syntax-trees-a3f989ec8524
-1. https://about.sourcegraph.com/
-
-# Visual programming
-
-1. https://github.com/ivanreese/visual-programming-codex
-1. [Lambda Days 2018 - Piotr Moczurad - Visual-textual functional programming with Luna](https://www.youtube.com/watch?v=6xUOuzafmO0)
-1. https://www.luna-lang.org/
-1. https://github.com/hoodiecrow/Tclook
-1. https://blog.sourcerer.io/build-interactive-diagrams-with-storm-react-diagrams-f172ae26af9d
-1. https://www.jointjs.com/opensource
-1. https://github.com/jagenjo/litegraph.js
-1. https://github.com/retejs/rete
-1. http://mikehadlow.blogspot.com/2018/10/visual-programming-why-its-bad-idea.html
-1. https://ncase.me/joy/
-1. https://www.jointjs.com/
-1. [Lambda World 2018 - Diagrammatic Execution Models for Functional Languages - Keynote](https://www.youtube.com/watch?v=sgmpVedCsNM)
-1. http://joshuahhh.com/projects/pane/
-1. [PANE: Programming with visible data](https://www.youtube.com/watch?v=fIEcXAHy6bU)
-1. https://blog.statebox.org/why-visual-programming-doesnt-suck-2c1ece2a414e
-1. https://nodered.org/
-
-# Reference
-
-1. [Build Your Own Text Editor](https://viewsourcecode.org/snaptoken/kilo/index.html)
-1. [On the design of text editors](https://arxiv.org/abs/2008.06030)
-1. [The Piece Table - the Unsung Hero of Your Text Editor](https://darrenburns.net/posts/piece-table/)
-1. [Build Your Own Text Editor](https://viewsourcecode.org/snaptoken/kilo/)
-1. [It’s 2019. Why don’t we have good code editors?](https://thoughts.thorlaksson.com/2019/09/27/its-2019-why-dont-we-have-good-code-editors/)
-1. [Text Editing Hates You Too](https://lord.io/blog/2019/text-editing-hates-you-too/)
-1. [Why ContentEditable is Terrible](https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480)
-1. [Broot: A better way to navigate directories](https://github.com/Canop/broot)
-1. https://www.simplethread.com/editor-plugins-belong-in-lock-file/
-1. [How to Design an IDE-Friendly Language with Peter Gromov @donnerpeter](https://www.youtube.com/watch?v=lubc8udiP_8)
-1. https://shaunlebron.github.io/parinfer/
-1. https://www.reddit.com/r/emacs/comments/6ztnj9/what_are_the_things_that_you_do_not_like_in_emacs/?st=j7kdafu2&sh=af9ca25d
-1. http://xenodium.com/#emacs-utilities-for-your-os
-1. https://techcrunch.com/2017/02/19/why-is-android-studio-still-such-a-gruesome-embarrassment/
-1. http://emacslife.com/
-1. http://tinyletter.com/Flowsheets/letters/flowsheets-visualizations
-1. http://www.averylaird.com/programming/editor/2017/09/30/the-piece-table/
-1. [Gallery of Programmer Interfaces](https://docs.google.com/presentation/d/1MD-CgzODFWzdpnYXr8bEgysfDmb8PDV6iCAjH5JIvaI/preview?slide=id.g1da0625f1b_0_56)
-1. https://spacevim.org/2017/02/11/use-vim-as-a-java-ide.html
-1. https://github.com/p-e-w/envy
-1. https://enotuniq.org/python_as_a_dsl.html
-1. [Lambda World 2018 - What FP can learn from Smalltalk by Aditya Siram](https://www.youtube.com/watch?v=baxtyeFVn3w)
-1. https://chris-martin.org/2017/loc
-
-# Syntax Highlighting
-
-1. [Syntax highlighting is backwards](https://www.benkuhn.net/syntax)
-1. [Coding in color](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e)
-1. https://code.visualstudio.com/blogs/2017/02/08/syntax-highlighting-optimizations
-1. https://github.com/alecthomas/chroma
-1. https://www.crockford.com/contextcoloring.html
-
-# Music
-
-1. https://www.hooktheory.com/hookpad/app
-
-# Data-Structures
-
-1. [Data Structures for Text Sequences](https://www.cs.unm.edu/~crowley/papers/sds.pdf)
-
-# Shell
-
-1. https://masteringemacs.org/article/complete-guide-mastering-eshell
-1. https://medium.com/readcomiccode/behold-z-the-unsung-jewel-that-rethinks-shell-navigation-dae262bb6bdc
-1. https://gitlab.com/emacsomancer/equake
-1. https://github.com/c-bata/go-prompt
-
-# Language Server Protocol
-
-1. https://tomassetti.me/language-server-dot-visual-studio/
-1. https://github.com/Microsoft/language-server-protocol/blob/master/README.md
-1. https://www.ncameron.org/blog/what-the-rls-can-do/
-
-# Semantic-oriented programming
-
-1. https://en.wikipedia.org/wiki/Semantic-oriented_programming
-1. https://prezi.com/gp6u1jpgkxej/what-are-soplets/
-1. http://symade.tigris.org/
-
-# Integrated Development Environment (IDE)
-
-1. [Theia 1.0 - Finally a Good Browser IDE](https://dev.to/svenefftinge/theia-1-0-finally-a-good-browser-ide-3ok0)
-1. https://www.eclipse.org/che/
-
-# Advanced AST/source-code manipulation tools
-
-1. https://caseywatts.com/2018/08/23/codemods.html
-1. https://vimeo.com/189514610
-1. https://github.com/facebook/jscodeshift
-1. http://astexplorer.net/
-1. https://github.com/avajs/ava-codemods
-
-# Extensibility
-
-1. [The Spoofax Language Workbench](https://metaborg.github.io/spoofax/)
-1. [A Language Independent Task Engine for Incremental Name and Type Analysis](https://www.researchgate.net/publication/290110229_A_Language_Independent_Task_Engine_for_Incremental_Name_and_Type_Analysis)
-1. [Extensible Type-Directed Editing](http://cattheory.com/extensibleTypeDirectedEditing.pdf)
-
-# Parsing
-
-1. [tree-sitter](http://tree-sitter.github.io/tree-sitter/)
-1. [tree-sitter: An incremental parsing system for programming tools](https://github.com/tree-sitter/tree-sitter)
-1. https://blog.github.com/2018-10-31-atoms-new-parsing-system/
-1. ["Tree-sitter - a new parsing system for programming tools" by Max Brunsfeld](https://www.youtube.com/watch?v=Jes3bD6P0To)
-
-# Notebook
-
-1. https://tiddlywiki.com/
-
-# Extension
-
-1. https://github.com/Pext/Pext
-
-# Collaborative editing
-
-1. https://github.com/gsilvamartin/RTCode
-1. https://hackernoon.com/building-conclave-a-decentralized-real-time-collaborative-text-editor-a6ab438fe79f
-1. https://github.com/xi-editor/xi-editor/issues/1187
-1. [Chronofold: a data structure for versioned text](https://arxiv.org/abs/2002.09511)
-
-# Exemplar
-
-## General
-
-1. [Left](https://100r.co/site/left.html)
-1. https://howl.io/
-1. [The Whole Code Catalog](https://futureofcoding.org/catalog/)
-1. http://substance.io/
-1. https://www.querystorm.com/
-1. http://recursivedrawing.com/
-1. http://doc.cat-v.org/bell_labs/sam_lang_tutorial/sam_tut.pdf
-1. https://github.com/typeintandem/tandem
-1. https://github.com/atom/xray
-1. http://strlen.com/treesheets/
-1. https://sekao.net/nightlight/
-1. http://cirru.org/
-1. http://www.sublimetext.com/
-1. https://atom.io/
-1. http://lighttable.com/
-1. https://www.visualstudio.com/vs/whatsnew/
-1. http://www.prototypingtools.co/
-1. https://nexttexteditor.com/
-1. https://medium.com/cirru-project/stack-editor-programming-by-functions-a961f1d9555c
-1. https://github.com/Cirru/stack-editor
-1. https://kclpure.kcl.ac.uk/portal/files/71018111/Frame_based_editing.pdf
-1. http://reactide.io/
-1. http://jumpfm.org/
-1. https://isomorf.io/#!/
-1. http://granthika.co/
-1. https://portacle.github.io/
-1. https://quokkajs.com/
-1. https://github.com/jaredly/treed
-1. https://github.com/raxod502/el-patch
-1. http://www.jgrasp.org/tutorials200/jGRASP_00_Overview.pdf
-1. http://codiad.com/
-1. https://github.com/sahilm/fuzzy
-1. https://lively-next.org/
-1. http://www.expressionsofchange.org/
-1. https://github.com/onivim/oni
-1. http://wiki.xxiivv.com/ronin
-1. https://github.com/google/xi-editor
-1. https://teletype.atom.io/
-1. https://github.com/martanne/vis
-1. http://www.graspjs.com/
-1. http://kakoune.org/
-1. https://github.com/argimenes/standoff-properties-editor
-1. https://www.conyedit.com/
-1. https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
-1. [YOW! Lambda Jam 2018 - Colin Fleming - Developing an IDE for Clojure code](https://www.youtube.com/watch?v=2sPYiGxU4kA)
-1. https://github.com/shaunlebron/history-of-lisp-parens/blob/master/editors.md
-1. https://www.leoeditor.com/
-1. https://storybook.js.org/
-1. https://grapesjs.com/
-1. https://two-wrongs.com/why-you-should-buy-into-the-emacs-platform
-1. https://docs.slatejs.org/
-1. https://github.com/pel-daniel/mind-bicyles
-1. https://github.com/metaseed/metaGo
-1. https://github.com/argimenes/standoff-properties-editor
-1. https://github.com/JeffreyBenjaminBrown/hode
-1. https://tratt.net/laurie/blog/entries/an_editor_for_composed_programs.html
-1. [Hjalfi makes smalltalk (in Javascript)](https://www.youtube.com/watch?v=JDunc6Cr7YQ)
-
-## Structured editing
-
-1. [Dion Systems - The How And Why Of Reinventing The Wheel](https://vimeo.com/485177664)
-1. [Towards Tactic Metaprogramming in Haskell](https://reasonablypolymorphic.com/blog/towards-tactics/index.html)
-1. https://github.com/Raathigesh/waypoint
-1. [Going beyond regular expressions with structural code search](https://about.sourcegraph.com/blog/going-beyond-regular-expressions-with-structural-code-search)
-1. [俺のlisp](https://github.com/illiichi/orenolisp)
-1. [豆腐 (Tofu): meaningful code editing](https://gregoor.github.io/tofu/)
-1. [Tiled Text](http://www.tiledtext.com/projects/tiledtext)
-1. [Deuce: A Lightweight User Interface for Structured Editing](https://arxiv.org/abs/1707.00015)
-1. ["Structured Editing for Elm* in Elm" by Ravi Chugh](https://www.youtube.com/watch?v=-TFL6E1uSHE)
-1. [The TeXmacs user interface and structured text editing](https://www.youtube.com/watch?v=Sc55nOSN0kQ)
-
-## Tree editor
-
-1. http://justinpombrio.net/tree-editors/survey.html
-
-## Image editor
-
-1. https://www.ludigraphix.org/
-
diff --git a/documentation/bookmark/time.md b/documentation/bookmark/time.md
new file mode 100644
index 000000000..caa6f16a6
--- /dev/null
+++ b/documentation/bookmark/time.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [Storing UTC is not a silver bullet](https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/)
+
diff --git a/documentation/bookmark/tool/integrated_development_environment.md b/documentation/bookmark/tool/integrated_development_environment.md
new file mode 100644
index 000000000..65aa01b32
--- /dev/null
+++ b/documentation/bookmark/tool/integrated_development_environment.md
@@ -0,0 +1,9 @@
+# Tools
+
+1. [Utilso: All-in-one tools for developers](https://utilso.com/)
+1. https://keycode.info/
+
+# Reference
+
+1. []()
+
diff --git a/documentation/bookmark/tool/text_editor.md b/documentation/bookmark/tool/text_editor.md
new file mode 100644
index 000000000..07d68eecd
--- /dev/null
+++ b/documentation/bookmark/tool/text_editor.md
@@ -0,0 +1,243 @@
+# Rendering
+
+1. [Text Rendering Hates You](https://gankra.github.io/blah/text-hates-you/)
+1. [Graphics for JVM](https://tonsky.me/blog/skija/)
+1. https://github.com/JetBrains/skija/
+1. https://github.com/JetBrains/skiko/
+1. https://github.com/JetBrains/compose-jb
+
+# Font
+
+1. [Google Noto Fonts: Beautiful and free fonts for all languages](https://www.google.com/get/noto/)
+
+# Residential programming
+
+1. [Residential Programming without Mutable State - Thomas Getgood](https://www.youtube.com/watch?v=Kgw9fblSOx4)
+
+# Good Ideas
+
+1. https://medium.com/@NikitaVoloboev/write-once-never-write-again-c2fa1f6c4e8
+1. [Inline: Efficient Source Code Editing and Manipulation with Code Portals](https://www.youtube.com/watch?v=NQ5h2Ibw6ck)
+1. https://devclass.com/2019/02/15/atlassian-make-jira-invisible-target-developers-ides/
+1. http://lispm.de/genera-concepts
+1. Hovering/selecting an input to a function inside a function-call should display the name of the input in the function declaration. This would help understand the purpose of the value while in the function call without needing Lux/the-language to have named inputs as a feature.
+1. https://www.emacswiki.org/emacs/UndoTree
+1. https://jameshfisher.com/2014/05/11/your-syntax-highlighter-is-wrong/
+1. https://medium.com/@evnbr/coding-in-color-3a6db2743a1e
+
+# Voice
+
+1. [Speaking in code: how to program by voice](https://www.nature.com/articles/d41586-018-05588-x)
+
+# Refactoring
+
+1. https://medium.com/zoosk-engineering/refactoring-at-scale-with-abstract-syntax-trees-a3f989ec8524
+1. https://about.sourcegraph.com/
+
+# Visual programming
+
+1. https://github.com/ivanreese/visual-programming-codex
+1. [Lambda Days 2018 - Piotr Moczurad - Visual-textual functional programming with Luna](https://www.youtube.com/watch?v=6xUOuzafmO0)
+1. https://www.luna-lang.org/
+1. https://github.com/hoodiecrow/Tclook
+1. https://blog.sourcerer.io/build-interactive-diagrams-with-storm-react-diagrams-f172ae26af9d
+1. https://www.jointjs.com/opensource
+1. https://github.com/jagenjo/litegraph.js
+1. https://github.com/retejs/rete
+1. http://mikehadlow.blogspot.com/2018/10/visual-programming-why-its-bad-idea.html
+1. https://ncase.me/joy/
+1. https://www.jointjs.com/
+1. [Lambda World 2018 - Diagrammatic Execution Models for Functional Languages - Keynote](https://www.youtube.com/watch?v=sgmpVedCsNM)
+1. http://joshuahhh.com/projects/pane/
+1. [PANE: Programming with visible data](https://www.youtube.com/watch?v=fIEcXAHy6bU)
+1. https://blog.statebox.org/why-visual-programming-doesnt-suck-2c1ece2a414e
+1. https://nodered.org/
+
+# Reference
+
+1. [Text Editing Hates You Too](https://lord.io/text-editing-hates-you-too/)
+1. [Build Your Own Text Editor](https://viewsourcecode.org/snaptoken/kilo/index.html)
+1. [On the design of text editors](https://arxiv.org/abs/2008.06030)
+1. [The Piece Table - the Unsung Hero of Your Text Editor](https://darrenburns.net/posts/piece-table/)
+1. [Build Your Own Text Editor](https://viewsourcecode.org/snaptoken/kilo/)
+1. [It’s 2019. Why don’t we have good code editors?](https://thoughts.thorlaksson.com/2019/09/27/its-2019-why-dont-we-have-good-code-editors/)
+1. [Text Editing Hates You Too](https://lord.io/blog/2019/text-editing-hates-you-too/)
+1. [Why ContentEditable is Terrible](https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480)
+1. [Broot: A better way to navigate directories](https://github.com/Canop/broot)
+1. https://www.simplethread.com/editor-plugins-belong-in-lock-file/
+1. [How to Design an IDE-Friendly Language with Peter Gromov @donnerpeter](https://www.youtube.com/watch?v=lubc8udiP_8)
+1. https://shaunlebron.github.io/parinfer/
+1. https://www.reddit.com/r/emacs/comments/6ztnj9/what_are_the_things_that_you_do_not_like_in_emacs/?st=j7kdafu2&sh=af9ca25d
+1. http://xenodium.com/#emacs-utilities-for-your-os
+1. https://techcrunch.com/2017/02/19/why-is-android-studio-still-such-a-gruesome-embarrassment/
+1. http://emacslife.com/
+1. http://tinyletter.com/Flowsheets/letters/flowsheets-visualizations
+1. http://www.averylaird.com/programming/editor/2017/09/30/the-piece-table/
+1. [Gallery of Programmer Interfaces](https://docs.google.com/presentation/d/1MD-CgzODFWzdpnYXr8bEgysfDmb8PDV6iCAjH5JIvaI/preview?slide=id.g1da0625f1b_0_56)
+1. https://spacevim.org/2017/02/11/use-vim-as-a-java-ide.html
+1. https://github.com/p-e-w/envy
+1. https://enotuniq.org/python_as_a_dsl.html
+1. [Lambda World 2018 - What FP can learn from Smalltalk by Aditya Siram](https://www.youtube.com/watch?v=baxtyeFVn3w)
+1. https://chris-martin.org/2017/loc
+
+# Syntax Highlighting
+
+1. [Syntax highlighting is backwards](https://www.benkuhn.net/syntax)
+1. [Coding in color](https://medium.com/@evnbr/coding-in-color-3a6db2743a1e)
+1. https://code.visualstudio.com/blogs/2017/02/08/syntax-highlighting-optimizations
+1. https://github.com/alecthomas/chroma
+1. https://www.crockford.com/contextcoloring.html
+
+# Music
+
+1. https://www.hooktheory.com/hookpad/app
+
+# Data-Structures
+
+1. [Data Structures for Text Sequences](https://www.cs.unm.edu/~crowley/papers/sds.pdf)
+
+# Shell
+
+1. https://masteringemacs.org/article/complete-guide-mastering-eshell
+1. https://medium.com/readcomiccode/behold-z-the-unsung-jewel-that-rethinks-shell-navigation-dae262bb6bdc
+1. https://gitlab.com/emacsomancer/equake
+1. https://github.com/c-bata/go-prompt
+
+# Language Server Protocol
+
+1. https://tomassetti.me/language-server-dot-visual-studio/
+1. https://github.com/Microsoft/language-server-protocol/blob/master/README.md
+1. https://www.ncameron.org/blog/what-the-rls-can-do/
+
+# Semantic-oriented programming
+
+1. https://en.wikipedia.org/wiki/Semantic-oriented_programming
+1. https://prezi.com/gp6u1jpgkxej/what-are-soplets/
+1. http://symade.tigris.org/
+
+# Integrated Development Environment (IDE)
+
+1. [Theia 1.0 - Finally a Good Browser IDE](https://dev.to/svenefftinge/theia-1-0-finally-a-good-browser-ide-3ok0)
+1. https://www.eclipse.org/che/
+
+# Advanced AST/source-code manipulation tools
+
+1. https://caseywatts.com/2018/08/23/codemods.html
+1. https://vimeo.com/189514610
+1. https://github.com/facebook/jscodeshift
+1. http://astexplorer.net/
+1. https://github.com/avajs/ava-codemods
+
+# Extensibility
+
+1. [The Spoofax Language Workbench](https://metaborg.github.io/spoofax/)
+1. [A Language Independent Task Engine for Incremental Name and Type Analysis](https://www.researchgate.net/publication/290110229_A_Language_Independent_Task_Engine_for_Incremental_Name_and_Type_Analysis)
+1. [Extensible Type-Directed Editing](http://cattheory.com/extensibleTypeDirectedEditing.pdf)
+
+# Parsing
+
+1. [tree-sitter](http://tree-sitter.github.io/tree-sitter/)
+1. [tree-sitter: An incremental parsing system for programming tools](https://github.com/tree-sitter/tree-sitter)
+1. https://blog.github.com/2018-10-31-atoms-new-parsing-system/
+1. ["Tree-sitter - a new parsing system for programming tools" by Max Brunsfeld](https://www.youtube.com/watch?v=Jes3bD6P0To)
+
+# Notebook
+
+1. https://tiddlywiki.com/
+
+# Extension
+
+1. https://github.com/Pext/Pext
+
+# Collaborative editing
+
+1. https://github.com/gsilvamartin/RTCode
+1. https://hackernoon.com/building-conclave-a-decentralized-real-time-collaborative-text-editor-a6ab438fe79f
+1. https://github.com/xi-editor/xi-editor/issues/1187
+1. [Chronofold: a data structure for versioned text](https://arxiv.org/abs/2002.09511)
+
+# Exemplar
+
+## General
+
+1. [Trix: A rich text editor for everyday writing.](https://trix-editor.org/)
+1. [Left](https://100r.co/site/left.html)
+1. https://howl.io/
+1. [The Whole Code Catalog](https://futureofcoding.org/catalog/)
+1. http://substance.io/
+1. https://www.querystorm.com/
+1. http://recursivedrawing.com/
+1. http://doc.cat-v.org/bell_labs/sam_lang_tutorial/sam_tut.pdf
+1. https://github.com/typeintandem/tandem
+1. https://github.com/atom/xray
+1. http://strlen.com/treesheets/
+1. https://sekao.net/nightlight/
+1. http://cirru.org/
+1. http://www.sublimetext.com/
+1. https://atom.io/
+1. http://lighttable.com/
+1. https://www.visualstudio.com/vs/whatsnew/
+1. http://www.prototypingtools.co/
+1. https://nexttexteditor.com/
+1. https://medium.com/cirru-project/stack-editor-programming-by-functions-a961f1d9555c
+1. https://github.com/Cirru/stack-editor
+1. https://kclpure.kcl.ac.uk/portal/files/71018111/Frame_based_editing.pdf
+1. http://reactide.io/
+1. http://jumpfm.org/
+1. https://isomorf.io/#!/
+1. http://granthika.co/
+1. https://portacle.github.io/
+1. https://quokkajs.com/
+1. https://github.com/jaredly/treed
+1. https://github.com/raxod502/el-patch
+1. http://www.jgrasp.org/tutorials200/jGRASP_00_Overview.pdf
+1. http://codiad.com/
+1. https://github.com/sahilm/fuzzy
+1. https://lively-next.org/
+1. http://www.expressionsofchange.org/
+1. https://github.com/onivim/oni
+1. http://wiki.xxiivv.com/ronin
+1. https://github.com/google/xi-editor
+1. https://teletype.atom.io/
+1. https://github.com/martanne/vis
+1. http://www.graspjs.com/
+1. http://kakoune.org/
+1. https://github.com/argimenes/standoff-properties-editor
+1. https://www.conyedit.com/
+1. https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
+1. [YOW! Lambda Jam 2018 - Colin Fleming - Developing an IDE for Clojure code](https://www.youtube.com/watch?v=2sPYiGxU4kA)
+1. https://github.com/shaunlebron/history-of-lisp-parens/blob/master/editors.md
+1. https://www.leoeditor.com/
+1. https://storybook.js.org/
+1. https://grapesjs.com/
+1. https://two-wrongs.com/why-you-should-buy-into-the-emacs-platform
+1. https://docs.slatejs.org/
+1. https://github.com/pel-daniel/mind-bicyles
+1. https://github.com/metaseed/metaGo
+1. https://github.com/argimenes/standoff-properties-editor
+1. https://github.com/JeffreyBenjaminBrown/hode
+1. https://tratt.net/laurie/blog/entries/an_editor_for_composed_programs.html
+1. [Hjalfi makes smalltalk (in Javascript)](https://www.youtube.com/watch?v=JDunc6Cr7YQ)
+
+## Structured editing
+
+1. [Inspiring a future Clojure editor with forgotten Lisp UX - Shaun Lebron](https://www.youtube.com/watch?v=K0Tsa3smr1w)
+1. [Dion Systems - The How And Why Of Reinventing The Wheel](https://vimeo.com/485177664)
+1. [Towards Tactic Metaprogramming in Haskell](https://reasonablypolymorphic.com/blog/towards-tactics/index.html)
+1. https://github.com/Raathigesh/waypoint
+1. [Going beyond regular expressions with structural code search](https://about.sourcegraph.com/blog/going-beyond-regular-expressions-with-structural-code-search)
+1. [俺のlisp](https://github.com/illiichi/orenolisp)
+1. [豆腐 (Tofu): meaningful code editing](https://gregoor.github.io/tofu/)
+1. [Tiled Text](http://www.tiledtext.com/projects/tiledtext)
+1. [Deuce: A Lightweight User Interface for Structured Editing](https://arxiv.org/abs/1707.00015)
+1. ["Structured Editing for Elm* in Elm" by Ravi Chugh](https://www.youtube.com/watch?v=-TFL6E1uSHE)
+1. [The TeXmacs user interface and structured text editing](https://www.youtube.com/watch?v=Sc55nOSN0kQ)
+
+## Tree editor
+
+1. http://justinpombrio.net/tree-editors/survey.html
+
+## Image editor
+
+1. https://www.ludigraphix.org/
+
diff --git a/documentation/bookmark/user_interface/color.md b/documentation/bookmark/user_interface/color.md
new file mode 100644
index 000000000..0c4c9882a
--- /dev/null
+++ b/documentation/bookmark/user_interface/color.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [How software gets color wrong](https://bottosson.github.io/posts/colorwrong/)
+
diff --git a/documentation/bookmark/user_interface/desktop.md b/documentation/bookmark/user_interface/desktop.md
new file mode 100644
index 000000000..deb487c93
--- /dev/null
+++ b/documentation/bookmark/user_interface/desktop.md
@@ -0,0 +1,4 @@
+# Browser-based
+
+1. [muon](https://github.com/ImVexed/muon)
+
diff --git a/documentation/bookmark/web_framework.md b/documentation/bookmark/web_framework.md
index 76485f924..54866447a 100644
--- a/documentation/bookmark/web_framework.md
+++ b/documentation/bookmark/web_framework.md
@@ -1,5 +1,6 @@
 # Virtual DOM
 
+1. [million: <1kb virtual DOM - it's fast!](https://million.js.org/)
 1. [Optimal Virtual DOM](https://blog.kabir.sh/posts/optimal-virtual-dom.html)
 
 # Input
diff --git a/licentia/source/program/licentia/document.lux b/licentia/source/program/licentia/document.lux
index 95c14e231..f56f0dbe7 100644
--- a/licentia/source/program/licentia/document.lux
+++ b/licentia/source/program/licentia/document.lux
@@ -30,6 +30,7 @@
 (template [<name> <word>]
   [(def: #export <name>
      (-> (List Text) Text)
+     ## https://en.wikipedia.org/wiki/Serial_comma
      (text.join_with (format ", " <word> " ")))]
 
   [or     "or"]
diff --git a/stdlib/source/lux/ffi.jvm.lux b/stdlib/source/lux/ffi.jvm.lux
index 4e684acf5..69a9ea5a3 100644
--- a/stdlib/source/lux/ffi.jvm.lux
+++ b/stdlib/source/lux/ffi.jvm.lux
@@ -1358,8 +1358,8 @@
 (syntax: #export (do_to obj {methods (<>.some partial_call^)})
   {#.doc (doc "Call a variety of methods on an object. Then, return the object."
               (do_to object
-                     (ClassName::method1 arg0 arg1 arg2)
-                     (ClassName::method2 arg3 arg4 arg5)))}
+                (ClassName::method1 arg0 arg1 arg2)
+                (ClassName::method2 arg3 arg4 arg5)))}
   (with_gensyms [g!obj]
     (wrap (list (` (let [(~ g!obj) (~ obj)]
                      (exec (~+ (list\map (complete_call$ g!obj) methods))
@@ -2023,3 +2023,19 @@
 
 (syntax: #export (type {type (..type^ (list))})
   (wrap (list (value_type #ManualPrM type))))
+
+(exception: #export (cannot_cast_to_non_object {type (Type Value)})
+  (exception.report
+   ["Signature" (..signature type)]
+   ["Reflection" (..reflection type)]))
+
+(syntax: #export (:as {type (..type^ (list))}
+                      object)
+  (case [(parser.array? type)
+         (parser.class? type)]
+    (^or [(#.Some _) _] [_ (#.Some _)])
+    (wrap (list (` (.: (~ (..value_type #ManualPrM type))
+                       ("jvm object cast" (~ object))))))
+
+    _
+    (meta.fail (exception.construct ..cannot_cast_to_non_object [type]))))
diff --git a/stdlib/source/lux/math.lux b/stdlib/source/lux/math.lux
index 1928d7c9a..e8f1433c1 100644
--- a/stdlib/source/lux/math.lux
+++ b/stdlib/source/lux/math.lux
@@ -292,31 +292,32 @@
           ## else
           floored)))
 
-(def: #export (atan2 param subject)
+(def: #export (atan/2 x y)
   (-> Frac Frac Frac)
-  (cond ("lux f64 <" param +0.0)
-        (..atan ("lux f64 /" param subject))
+  (cond ("lux f64 <" x +0.0)
+        (..atan ("lux f64 /" x y))
 
-        ("lux f64 <" +0.0 param)
-        (if (or ("lux f64 <" subject +0.0)
-                ("lux f64 =" +0.0 subject))
-          (|> subject ("lux f64 /" param) atan ("lux f64 +" pi))
-          (|> subject ("lux f64 /" param) atan ("lux f64 -" pi)))
+        ("lux f64 <" +0.0 x)
+        (if (or ("lux f64 <" y +0.0)
+                ("lux f64 =" +0.0 y))
+          (|> y ("lux f64 /" x) atan ("lux f64 +" pi))
+          (|> y ("lux f64 /" x) atan ("lux f64 -" pi)))
 
-        ## ("lux f64 =" +0.0 param)
-        (cond ("lux f64 <" subject +0.0)
+        ## ("lux f64 =" +0.0 x)
+        (cond ("lux f64 <" y +0.0)
               (|> pi ("lux f64 /" +2.0))
               
-              ("lux f64 <" +0.0 subject)
+              ("lux f64 <" +0.0 y)
               (|> pi ("lux f64 /" -2.0))
               
-              ## ("lux f64 =" +0.0 subject)
+              ## ("lux f64 =" +0.0 y)
               ("lux f64 /" +0.0 +0.0))))
 
 (def: #export (log' base input)
   (-> Frac Frac Frac)
-  ("lux f64 /" (log base)
-   (log input)))
+  ("lux f64 /"
+   (..log base)
+   (..log input)))
 
 (def: #export (factorial n)
   (-> Nat Nat)
@@ -328,20 +329,20 @@
 
 (def: #export (hypotenuse catA catB)
   (-> Frac Frac Frac)
-  (pow +0.5 ("lux f64 +"
-             (pow +2.0 catA)
-             (pow +2.0 catB))))
+  (..pow +0.5 ("lux f64 +"
+               (..pow +2.0 catA)
+               (..pow +2.0 catB))))
 
 ## Hyperbolic functions
 ## https://en.wikipedia.org/wiki/Hyperbolic_function#Definitions
 (template [<name> <comp> <inverse>]
   [(def: #export (<name> x)
      (-> Frac Frac)
-     (|> (exp x) (<comp> (exp ("lux f64 *" -1.0 x))) ("lux f64 /" +2.0)))
+     (|> (..exp x) (<comp> (..exp ("lux f64 *" -1.0 x))) ("lux f64 /" +2.0)))
 
    (def: #export (<inverse> x)
      (-> Frac Frac)
-     (|> +2.0 ("lux f64 /" (|> (exp x) (<comp> (exp ("lux f64 *" -1.0 x)))))))]
+     (|> +2.0 ("lux f64 /" (|> (..exp x) (<comp> (..exp ("lux f64 *" -1.0 x)))))))]
 
   [sinh "lux f64 -" csch]
   [cosh "lux f64 +" sech]
diff --git a/stdlib/source/lux/math/number/complex.lux b/stdlib/source/lux/math/number/complex.lux
index 3da5071b0..aad6a4364 100644
--- a/stdlib/source/lux/math/number/complex.lux
+++ b/stdlib/source/lux/math/number/complex.lux
@@ -212,7 +212,7 @@
   (-> Complex Complex)
   (let [(^slots [#real #imaginary]) subject]
     {#real (|> subject ..abs math.log)
-     #imaginary (math.atan2 real imaginary)}))
+     #imaginary (math.atan/2 real imaginary)}))
 
 (template [<name> <type> <op>]
   [(def: #export (<name> param input)
@@ -283,7 +283,7 @@
 
 (def: #export (argument (^slots [#real #imaginary]))
   (-> Complex Frac)
-  (math.atan2 real imaginary))
+  (math.atan/2 real imaginary))
 
 (def: #export (roots nth input)
   (-> Nat Complex (List Complex))
diff --git a/stdlib/source/lux/test.lux b/stdlib/source/lux/test.lux
index 513765864..bd7927a15 100644
--- a/stdlib/source/lux/test.lux
+++ b/stdlib/source/lux/test.lux
@@ -188,6 +188,13 @@
                          ("lux io log" "Time-out reached! Retrying tests...")
                          (product.right (recur prng)))))])))))
 
+## TODO: Figure out why tests sometimes freeze and fix it. Delete "seed'" afterwards.
+(def: #export (seed' millis_time_out value test)
+  (-> (Maybe Nat) Seed Test Test)
+  (<| (..times' millis_time_out 1)
+      (..seed value)
+      test))
+
 (def: #export times
   (-> Nat Test Test)
   (..times' #.None))
diff --git a/stdlib/source/lux/tool/compiler/default/platform.lux b/stdlib/source/lux/tool/compiler/default/platform.lux
index d505f5f7c..d43259443 100644
--- a/stdlib/source/lux/tool/compiler/default/platform.lux
+++ b/stdlib/source/lux/tool/compiler/default/platform.lux
@@ -340,7 +340,7 @@
                     <Signal> (as_is (Resolver <Result>))
                     <Pending> (as_is [<Return> <Signal>])
                     <Importer> (as_is (-> Module Module <Return>))
-                    <Compiler> (as_is (-> <Importer> archive.ID <Context> Module <Return>))]
+                    <Compiler> (as_is (-> Module <Importer> archive.ID <Context> Module <Return>))]
     (def: (parallel initial)
       (All [<type_vars>]
         (-> <Context>
@@ -420,7 +420,7 @@
                    
                    (#.Some [context module_id resolver])
                    (do !
-                     [result (compile import! module_id context module)
+                     [result (compile importer import! module_id context module)
                       result (case result
                                (#try.Failure error)
                                (wrap result)
@@ -487,10 +487,11 @@
                                    ((//init.compiler expander syntax.prelude (get@ #write platform)) $.key (list))))
             compiler (..parallel
                       context
-                      (function (_ import! module_id [archive state] module)
+                      (function (_ importer import! module_id [archive state] module)
                         (do {! (try.with promise.monad)}
                           [#let [state (..set_current_module module state)]
                            input (context.read (get@ #&file_system platform)
+                                               importer
                                                import
                                                compilation_sources
                                                (get@ #static.host_module_extension static)
diff --git a/stdlib/source/lux/tool/compiler/meta/io/archive.lux b/stdlib/source/lux/tool/compiler/meta/io/archive.lux
index 7fe4b96a9..e611f9f47 100644
--- a/stdlib/source/lux/tool/compiler/meta/io/archive.lux
+++ b/stdlib/source/lux/tool/compiler/meta/io/archive.lux
@@ -384,6 +384,10 @@
              (..initial_purge caches)
              load_order))
 
+(def: pseudo_module
+  Text
+  "(Lux Caching System)")
+
 (def: (load_every_reserved_module host_environment system static import contexts archive)
   (All [expression directive]
     (-> (generation.Host expression directive) (file.System Promise) Static Import (List Context) Archive
@@ -399,7 +403,7 @@
                                               (wrap [true
                                                      [module_name [module_id [descriptor document (: Output row.empty)]]]])
                                               (do !
-                                                [input (//context.read system import contexts (get@ #static.host_module_extension static) module_name)]
+                                                [input (//context.read system ..pseudo_module import contexts (get@ #static.host_module_extension static) module_name)]
                                                 (wrap [(..valid_cache? descriptor input)
                                                        [module_name [module_id [descriptor document (: Output row.empty)]]]])))))))
      load_order (|> pre_loaded_caches
diff --git a/stdlib/source/lux/tool/compiler/meta/io/context.lux b/stdlib/source/lux/tool/compiler/meta/io/context.lux
index 3bb388f5e..33f201571 100644
--- a/stdlib/source/lux/tool/compiler/meta/io/context.lux
+++ b/stdlib/source/lux/tool/compiler/meta/io/context.lux
@@ -30,14 +30,14 @@
      [descriptor (#+ Module)]]
     ["/#" // (#+ Input)]]])
 
-(template [<name>]
-  [(exception: #export (<name> {module Module})
-     (exception.report
-      ["Module" (%.text module)]))]
+(exception: #export (cannot_find_module {importer Module} {module Module})
+  (exception.report
+   ["Module" (%.text module)]
+   ["Importer" (%.text importer)]))
 
-  [cannot_find_module]
-  [cannot_read_module]
-  )
+(exception: #export (cannot_read_module {module Module})
+  (exception.report
+   ["Module" (%.text module)]))
 
 (type: #export Extension
   Text)
@@ -52,12 +52,12 @@
       (//.sanitize system)
       (format context (\ system separator))))
 
-(def: (find_source_file system contexts module extension)
-  (-> (file.System Promise) (List Context) Module Extension
+(def: (find_source_file system importer contexts module extension)
+  (-> (file.System Promise) Module (List Context) Module Extension
       (Promise (Try [Path (File Promise)])))
   (case contexts
     #.Nil
-    (promise\wrap (exception.throw ..cannot_find_module [module]))
+    (promise\wrap (exception.throw ..cannot_find_module [importer module]))
 
     (#.Cons context contexts')
     (do promise.monad
@@ -68,19 +68,19 @@
         (wrap (#try.Success [path file]))
 
         (#try.Failure _)
-        (find_source_file system contexts' module extension)))))
+        (find_source_file system importer contexts' module extension)))))
 
 (def: (full_host_extension partial_host_extension)
   (-> Extension Extension)
   (format partial_host_extension ..lux_extension))
 
-(def: (find_local_source_file system import contexts partial_host_extension module)
-  (-> (file.System Promise) Import (List Context) Extension Module
+(def: (find_local_source_file system importer import contexts partial_host_extension module)
+  (-> (file.System Promise) Module Import (List Context) Extension Module
       (Promise (Try [Path Binary])))
   ## Preference is explicitly being given to Lux files that have a host extension.
   ## Normal Lux files (i.e. without a host extension) are then picked as fallback files.
   (do {! promise.monad}
-    [outcome (..find_source_file system contexts module (..full_host_extension partial_host_extension))]
+    [outcome (..find_source_file system importer contexts module (..full_host_extension partial_host_extension))]
     (case outcome
       (#try.Success [path file])
       (do (try.with !)
@@ -89,12 +89,12 @@
 
       (#try.Failure _)
       (do (try.with !)
-        [[path file] (..find_source_file system contexts module ..lux_extension)
+        [[path file] (..find_source_file system importer contexts module ..lux_extension)
          data (!.use (\ file content) [])]
         (wrap [path data])))))
 
-(def: (find_library_source_file import partial_host_extension module)
-  (-> Import Extension Module (Try [Path Binary]))
+(def: (find_library_source_file importer import partial_host_extension module)
+  (-> Module Import Extension Module (Try [Path Binary]))
   (let [path (format module (..full_host_extension partial_host_extension))]
     (case (dictionary.get path import)
       (#.Some data)
@@ -107,27 +107,27 @@
           (#try.Success [path data])
 
           #.None
-          (exception.throw ..cannot_find_module [module]))))))
+          (exception.throw ..cannot_find_module [importer module]))))))
 
-(def: (find_any_source_file system import contexts partial_host_extension module)
-  (-> (file.System Promise) Import (List Context) Extension Module
+(def: (find_any_source_file system importer import contexts partial_host_extension module)
+  (-> (file.System Promise) Module Import (List Context) Extension Module
       (Promise (Try [Path Binary])))
   ## Preference is explicitly being given to Lux files that have a host extension.
   ## Normal Lux files (i.e. without a host extension) are then picked as fallback files.
   (do {! promise.monad}
-    [outcome (find_local_source_file system import contexts partial_host_extension module)]
+    [outcome (find_local_source_file system importer import contexts partial_host_extension module)]
     (case outcome
       (#try.Success [path data])
       (wrap outcome)
 
       (#try.Failure _)
-      (wrap (..find_library_source_file import partial_host_extension module)))))
+      (wrap (..find_library_source_file importer import partial_host_extension module)))))
 
-(def: #export (read system import contexts partial_host_extension module)
-  (-> (file.System Promise) Import (List Context) Extension Module
+(def: #export (read system importer import contexts partial_host_extension module)
+  (-> (file.System Promise) Module Import (List Context) Extension Module
       (Promise (Try Input)))
   (do (try.with promise.monad)
-    [[path binary] (..find_any_source_file system import contexts partial_host_extension module)]
+    [[path binary] (..find_any_source_file system importer import contexts partial_host_extension module)]
     (case (\ utf8.codec decode binary)
       (#try.Success code)
       (wrap {#////.module module
diff --git a/stdlib/source/lux/world/file.lux b/stdlib/source/lux/world/file.lux
index 0cb7136c4..670c1df6f 100644
--- a/stdlib/source/lux/world/file.lux
+++ b/stdlib/source/lux/world/file.lux
@@ -1,7 +1,7 @@
 (.module:
   [lux #*
-   ["." ffi]
    ["@" target]
+   ["." ffi]
    [abstract
     ["." monad (#+ Monad do)]]
    [control
diff --git a/stdlib/source/lux/world/shell.lux b/stdlib/source/lux/world/shell.lux
index 77da2c9d8..b1556d35c 100644
--- a/stdlib/source/lux/world/shell.lux
+++ b/stdlib/source/lux/world/shell.lux
@@ -277,8 +277,7 @@
                                                  (def: write
                                                    (..can_write
                                                     (function (_ message)
-                                                      (|> jvm_output
-                                                          (java/io/OutputStream::write (\ utf8.codec encode message))))))
+                                                      (java/io/OutputStream::write (\ utf8.codec encode message) jvm_output))))
                                                  (~~ (template [<name> <capability> <method>]
                                                        [(def: <name>
                                                           (<capability>
diff --git a/stdlib/source/program/aedifex.lux b/stdlib/source/program/aedifex.lux
index 4b812bef4..2d873f8a8 100644
--- a/stdlib/source/program/aedifex.lux
+++ b/stdlib/source/program/aedifex.lux
@@ -190,8 +190,8 @@
                     (#try.Success watcher)
                     (..command
                      (case auto
-                       #/cli.Build (..with_dependencies program console (/command/auto.do! watcher /command/build.do!) profile)
-                       #/cli.Test (..with_dependencies program console (/command/auto.do! watcher /command/test.do!) profile)))))
+                       #/cli.Build (..with_dependencies program console (/command/auto.do! /command/auto.delay watcher /command/build.do!) profile)
+                       #/cli.Test (..with_dependencies program console (/command/auto.do! /command/auto.delay watcher /command/test.do!) profile)))))
 
                 _
                 (undefined)))
diff --git a/stdlib/source/program/aedifex/command/auto.lux b/stdlib/source/program/aedifex/command/auto.lux
index afce4d6ff..000384ccd 100644
--- a/stdlib/source/program/aedifex/command/auto.lux
+++ b/stdlib/source/program/aedifex/command/auto.lux
@@ -42,13 +42,17 @@
       (#try.Failure error)
       (wrap (list)))))
 
-(def: (pause _)
-  (-> Any (Promise (Try Any)))
-  (promise.delay 1,000 (#try.Success [])))
+(def: #export delay
+  Nat
+  1,000)
 
-(def: #export (do! watcher command)
+(def: (pause delay)
+  (-> Nat (Promise (Try Any)))
+  (promise.delay delay (#try.Success [])))
+
+(def: #export (do! delay watcher command)
   (All [a]
-    (-> (Watcher Promise)
+    (-> Nat (Watcher Promise)
         (-> (Console Promise) (Program Promise) (file.System Promise) (Shell Promise) Resolution (Command a))
         (-> (Console Promise) (Program Promise) (file.System Promise) (Shell Promise) Resolution (Command Any))))
   (function (_ console program fs shell resolution)
@@ -65,7 +69,7 @@
              _ <call>]
             (loop [_ []]
               (do !
-                [_ (..pause [])
+                [_ (..pause delay)
                  events (\ watcher poll [])
                  _ (case events
                      (#.Cons _)
diff --git a/stdlib/source/program/aedifex/command/build.lux b/stdlib/source/program/aedifex/command/build.lux
index 7052109fb..e2d6f78b8 100644
--- a/stdlib/source/program/aedifex/command/build.lux
+++ b/stdlib/source/program/aedifex/command/build.lux
@@ -132,66 +132,82 @@
 (def: #export failure "[BUILD FAILED]")
 
 (template [<name> <capability>]
-  [(def: (<name> console process)
+  [(def: #export (<name> console process)
      (-> (Console Promise) (Process Promise) (Promise (Try Any)))
-     (do {! promise.monad}
-       [?line (!.use (\ process <capability>) [])]
-       (case ?line
-         (#try.Failure error)
-         (if (exception.match? shell.no_more_output error)
-           (wrap (#try.Success []))
-           (console.write_line error console))
-         
-         (#try.Success line)
-         (do (try.with !)
-           [_ (console.write_line line console)]
-           (log_output! console process)))))]
+     ## This is a very odd way of implementing this function.
+     ## But it's written this way because the more straightforward way (i.e. by using (try.with promise.monad))
+     ## eventually led to the function hanging/freezing.
+     ## I'm not sure why it happened, but I got this weirder implementation to work.
+     (let [[read! write!] (: [(Promise (Try Any))
+                              (promise.Resolver (Try Any))]
+                             (promise.promise []))
+           _ (|> (!.use (\ process <capability>) [])
+                 (promise.await (function (recur ?line)
+                                  (case ?line
+                                    (#try.Failure error)
+                                    (if (exception.match? shell.no_more_output error)
+                                      (write! (#try.Success []))
+                                      (promise.await write! (console.write_line error console)))
+                                    
+                                    (#try.Success line)
+                                    (promise.await (function (_ outcome)
+                                                     (case outcome
+                                                       (#try.Failure error)
+                                                       (write! (#try.Failure error))
+
+                                                       (#try.Success _)
+                                                       (promise.await recur
+                                                                      (!.use (\ process <capability>) []))))
+                                                   (console.write_line line console)))))
+                 io.run)]
+       read!))]
 
   [log_output! read]
   [log_error! error]
   )
 
-(def: #export (do! console program fs shell resolution profile)
+(def: #export (do! console program fs shell resolution)
   (-> (Console Promise) (Program Promise) (file.System Promise) (Shell Promise) Resolution (Command [Compiler Path]))
-  (case [(get@ #///.program profile)
-         (get@ #///.target profile)]
-    [#.None _]
-    (promise\wrap (exception.throw ..no_specified_program []))
-
-    [_ #.None]
-    (promise\wrap (exception.throw ..no_specified_target []))
-    
-    [(#.Some program_module) (#.Some target)]
-    (do promise.monad
-      [environment (\ program environment [])
-       home (\ program home [])
-       working_directory (\ program directory [])]
-      (do ///action.monad
-        [[resolution compiler] (promise\wrap (..compiler resolution))
-         #let [[[command compiler_params] output] (case compiler
-                                                    (#JVM dependency) [(///runtime.java (..path fs home dependency))
-                                                                       "program.jar"]
-                                                    (#JS dependency) [(///runtime.node (..path fs home dependency))
-                                                                      "program.js"])
-               / (\ fs separator)
-               cache_directory (format working_directory / target)]
-         _ (console.write_line ..start console)
-         process (!.use (\ shell execute)
-                        [environment
-                         working_directory
-                         command
-                         (list.concat (list compiler_params
-                                            (list "build")
-                                            (..plural "--library" (..libraries fs home resolution))
-                                            (..plural "--source" (set.to_list (get@ #///.sources profile)))
-                                            (..singular "--target" cache_directory)
-                                            (..singular "--module" program_module)))])
-         _ (..log_output! console process)
-         _ (..log_error! console process)
-         exit (!.use (\ process await) [])
-         _ (console.write_line (if (i.= shell.normal exit)
-                                 ..success
-                                 ..failure)
-                               console)]
-        (wrap [compiler
-               (format cache_directory / output)])))))
+  (function (_ profile)
+    (case [(get@ #///.program profile)
+           (get@ #///.target profile)]
+      [#.None _]
+      (promise\wrap (exception.throw ..no_specified_program []))
+
+      [_ #.None]
+      (promise\wrap (exception.throw ..no_specified_target []))
+      
+      [(#.Some program_module) (#.Some target)]
+      (do promise.monad
+        [environment (\ program environment [])
+         home (\ program home [])
+         working_directory (\ program directory [])]
+        (do ///action.monad
+          [[resolution compiler] (promise\wrap (..compiler resolution))
+           #let [[[command compiler_params] output] (case compiler
+                                                      (#JVM dependency) [(///runtime.java (..path fs home dependency))
+                                                                         "program.jar"]
+                                                      (#JS dependency) [(///runtime.node (..path fs home dependency))
+                                                                        "program.js"])
+                 / (\ fs separator)
+                 cache_directory (format working_directory / target)]
+           _ (console.write_line ..start console)
+           process (!.use (\ shell execute)
+                          [environment
+                           working_directory
+                           command
+                           (list.concat (list compiler_params
+                                              (list "build")
+                                              (..plural "--library" (..libraries fs home resolution))
+                                              (..plural "--source" (set.to_list (get@ #///.sources profile)))
+                                              (..singular "--target" cache_directory)
+                                              (..singular "--module" program_module)))])
+           _ (..log_output! console process)
+           _ (..log_error! console process)
+           exit (!.use (\ process await) [])
+           _ (console.write_line (if (i.= shell.normal exit)
+                                   ..success
+                                   ..failure)
+                                 console)]
+          (wrap [compiler
+                 (format cache_directory / output)]))))))
diff --git a/stdlib/source/program/aedifex/command/test.lux b/stdlib/source/program/aedifex/command/test.lux
index c3b517437..e717b7cd6 100644
--- a/stdlib/source/program/aedifex/command/test.lux
+++ b/stdlib/source/program/aedifex/command/test.lux
@@ -21,6 +21,7 @@
   ["." // #_
    ["#." build]
    ["/#" // #_
+    ["#" profile]
     ["#." action]
     ["#." command (#+ Command)]
     ["#." runtime]
@@ -37,7 +38,8 @@
     [environment (\ program environment [])
      working_directory (\ program directory [])]
     (do ///action.monad
-      [[compiler program] (//build.do! console program fs shell resolution profile)
+      [[compiler program] (//build.do! console program fs shell resolution
+                                       (set@ #///.program (get@ #///.test profile) profile))
        _ (console.write_line ..start console)
        #let [[compiler_command compiler_parameters] (case compiler
                                                       (#//build.JVM artifact) (///runtime.java program)
@@ -47,6 +49,8 @@
                        working_directory
                        compiler_command
                        compiler_parameters])
+       _ (//build.log_output! console process)
+       _ (//build.log_error! console process)
        exit (!.use (\ process await) [])
        _ (console.write_line (if (i.= shell.normal exit)
                                ..success
diff --git a/stdlib/source/program/aedifex/format.lux b/stdlib/source/program/aedifex/format.lux
index d42333fd9..6fcbb2db7 100644
--- a/stdlib/source/program/aedifex/format.lux
+++ b/stdlib/source/program/aedifex/format.lux
@@ -143,7 +143,7 @@
       (..on_maybe "target" (get@ #/.target value) code.text)
       (..on_maybe "program" (get@ #/.program value) code.text)
       (..on_maybe "test" (get@ #/.test value) code.text)
-      (..on_dictionary "deploy-repositories" (get@ #/.deploy_repositories value) code.text code.text)
+      (..on_dictionary "deploy_repositories" (get@ #/.deploy_repositories value) code.text code.text)
       ..aggregate))
 
 (def: #export project
diff --git a/stdlib/source/program/aedifex/parser.lux b/stdlib/source/program/aedifex/parser.lux
index 046c8893c..3c1b4144a 100644
--- a/stdlib/source/program/aedifex/parser.lux
+++ b/stdlib/source/program/aedifex/parser.lux
@@ -171,9 +171,6 @@
                (<>.and <c>.text
                        ..repository))))
 
-(def: default_repository
-  "https://repo1.maven.org/maven2/")
-
 (def: profile
   (Parser /.Profile)
   (do {! <>.monad}
@@ -194,7 +191,7 @@
                             (|> (..plural input "repositories" ..repository)
                                 (\ ! map (set.from_list text.hash))
                                 (<>.default (set.new text.hash))
-                                (\ ! map (set.add ..default_repository))))
+                                (\ ! map (set.add /.default_repository))))
            ^dependencies (: (Parser (Set //dependency.Dependency))
                             (|> (..plural input "dependencies" ..dependency)
                                 (\ ! map (set.from_list //dependency.hash))
diff --git a/stdlib/source/program/aedifex/profile.lux b/stdlib/source/program/aedifex/profile.lux
index fa49e41cd..592e221fd 100644
--- a/stdlib/source/program/aedifex/profile.lux
+++ b/stdlib/source/program/aedifex/profile.lux
@@ -24,8 +24,8 @@
   [//
    ["." artifact (#+ Artifact)]
    ["." dependency]
-   ["." repository #_
-    ["#" remote (#+ Address)]]])
+   [repository
+    [remote (#+ Address)]]])
 
 (type: #export Distribution
   #Repo
@@ -132,6 +132,10 @@
   Target
   "target")
 
+(def: #export default_repository
+  Address
+  "https://repo1.maven.org/maven2/")
+
 (type: #export Name
   Text)
 
@@ -143,13 +147,13 @@
   {#parents (List Name)
    #identity (Maybe Artifact)
    #info (Maybe Info)
-   #repositories (Set repository.Address)
+   #repositories (Set Address)
    #dependencies (Set dependency.Dependency)
    #sources (Set Source)
    #target (Maybe Target)
    #program (Maybe Module)
    #test (Maybe Module)
-   #deploy_repositories (Dictionary Text repository.Address)})
+   #deploy_repositories (Dictionary Text Address)})
 
 (def: #export equivalence
   (Equivalence Profile)
diff --git a/stdlib/source/test/aedifex/command.lux b/stdlib/source/test/aedifex/command.lux
index e0cb2da79..42d1c1278 100644
--- a/stdlib/source/test/aedifex/command.lux
+++ b/stdlib/source/test/aedifex/command.lux
@@ -12,11 +12,10 @@
    ["#." deploy]
 
    ["#." build]
-   ["#." test]]
+   ["#." test]
+   ["#." auto]]
   {#program
-   ["." /
-    ## ["#." auto]
-    ]})
+   ["." /]})
 
 (def: #export test
   Test
@@ -34,5 +33,5 @@
 
           /build.test
           /test.test
-          ## /auto.test
+          /auto.test
           )))
diff --git a/stdlib/source/test/aedifex/command/auto.lux b/stdlib/source/test/aedifex/command/auto.lux
index 7bac6eb5d..c23519bcc 100644
--- a/stdlib/source/test/aedifex/command/auto.lux
+++ b/stdlib/source/test/aedifex/command/auto.lux
@@ -20,7 +20,7 @@
      ["." set]
      ["." list ("#\." functor)]]]
    [math
-    ["." random]
+    ["." random (#+ Random)]
     [number
      ["n" nat]]]
    [world
@@ -56,10 +56,10 @@
     [@runs
      (function (_ console program fs shell resolution profile)
        (do {! promise.monad}
-         [[runs remaining_files] (promise.future
-                                  (atom.update (function (_ [runs remaining_files])
-                                                 [(inc runs) remaining_files])
-                                               @runs))]
+         [[_ [runs remaining_files]] (promise.future
+                                      (atom.update (function (_ [runs remaining_files])
+                                                     [(inc runs) remaining_files])
+                                                   @runs))]
          (case remaining_files
            #.Nil
            (wrap (#try.Failure end_signal))
@@ -78,15 +78,10 @@
         [#let [/ (\ file.default separator)
                [fs watcher] (watch.mock /)]
          end_signal (random.ascii/alpha 5)
+         
          program (random.ascii/alpha 5)
          target (random.ascii/alpha 5)
-         home (random.ascii/alpha 5)
-         working_directory (random.ascii/alpha 5)
-         expected_runs (\ ! map (|>> (n.% 10) (n.max 2)) random.nat)
          source (random.ascii/alpha 5)
-         dummy_files (|> (random.ascii/alpha 5)
-                         (random.set text.hash (dec expected_runs))
-                         (\ ! map (|>> set.to_list (list\map (|>> (format source /))))))
          #let [empty_profile (: Profile
                                 (\ ///.monoid identity))
                with_target (: (-> Profile Profile)
@@ -98,6 +93,14 @@
                            with_program
                            with_target
                            (set@ #///.sources (set.from_list text.hash (list source))))]
+
+         home (random.ascii/alpha 5)
+         working_directory (random.ascii/alpha 5)
+         
+         expected_runs (\ ! map (|>> (n.% 10) (n.max 2)) random.nat)
+         dummy_files (|> (random.ascii/alpha 5)
+                         (random.set text.hash (dec expected_runs))
+                         (\ ! map (|>> set.to_list (list\map (|>> (format source /))))))
          resolution @build.resolution]
         ($_ _.and
             (wrap (do promise.monad
@@ -106,11 +109,11 @@
                                 _ (!.use (\ fs create_directory) [source])
                                 _ (\ watcher poll [])]
                                (do promise.monad
-                                 [outcome ((/.do! watcher command)
+                                 [outcome ((/.do! 1 watcher command)
                                            (@version.echo "")
                                            (program.async (program.mock environment.empty home working_directory))
                                            fs
-                                           (@build.good_shell [])
+                                           (shell.async (@build.good_shell []))
                                            resolution
                                            profile)
                                   [actual_runs _] (promise.future (atom.read @runs))]
diff --git a/stdlib/source/test/aedifex/command/build.lux b/stdlib/source/test/aedifex/command/build.lux
index 85231ae33..234343fea 100644
--- a/stdlib/source/test/aedifex/command/build.lux
+++ b/stdlib/source/test/aedifex/command/build.lux
@@ -45,9 +45,9 @@
       (: (shell.Simulation [])
          (structure
           (def: (on_read state)
-            (#try.Failure "on_read"))
+            (exception.throw shell.no_more_output []))
           (def: (on_error state)
-            (#try.Failure "on_error"))
+            (exception.throw shell.no_more_output []))
           (def: (on_write input state)
             (#try.Failure "on_write"))
           (def: (on_destroy state)
@@ -63,9 +63,9 @@
       (: (shell.Simulation [])
          (structure
           (def: (on_read state)
-            (#try.Failure "on_read"))
+            (exception.throw shell.no_more_output []))
           (def: (on_error state)
-            (#try.Failure "on_error"))
+            (exception.throw shell.no_more_output []))
           (def: (on_write input state)
             (#try.Failure "on_write"))
           (def: (on_destroy state)
@@ -98,7 +98,9 @@
   Test
   (<| (_.covering /._)
       (do {! random.monad}
-        [#let [fs (file.mock (\ file.default separator))
+        [last_read (random.ascii/alpha 5)
+         last_error (random.ascii/alpha 5)
+         #let [fs (file.mock (\ file.default separator))
                shell (shell.async (..good_shell []))]
          program (random.ascii/alpha 5)
          target (random.ascii/alpha 5)
diff --git a/stdlib/source/test/aedifex/command/test.lux b/stdlib/source/test/aedifex/command/test.lux
index 9dd76ca08..36c21b520 100644
--- a/stdlib/source/test/aedifex/command/test.lux
+++ b/stdlib/source/test/aedifex/command/test.lux
@@ -5,6 +5,7 @@
     [monad (#+ do)]]
    [control
     ["." try]
+    ["." exception]
     [concurrency
      ["." promise]]
     [parser
@@ -14,7 +15,8 @@
    [data
     ["." text ("#\." equivalence)]
     [collection
-     ["." dictionary]]]
+     ["." dictionary]
+     ["." list]]]
    [math
     ["." random]]
    [world
@@ -84,15 +86,15 @@
                                                       (: (shell.Simulation [])
                                                          (structure
                                                           (def: (on_read state)
-                                                            (#try.Failure "on_read"))
+                                                            (exception.throw shell.no_more_output []))
                                                           (def: (on_error state)
-                                                            (#try.Failure "on_error"))
+                                                            (exception.throw shell.no_more_output []))
                                                           (def: (on_write input state)
                                                             (#try.Failure "on_write"))
                                                           (def: (on_destroy state)
                                                             (#try.Failure "on_destroy"))
                                                           (def: (on_await state)
-                                                            (#try.Success [state (if (text.ends_with? " build" actual_command)
+                                                            (#try.Success [state (if (list.any? (text\= "build") actual_arguments)
                                                                                    shell.normal
                                                                                    shell.error)]))))))
                                                    [])]
diff --git a/stdlib/source/test/aedifex/dependency/resolution.lux b/stdlib/source/test/aedifex/dependency/resolution.lux
index e9cd26a82..ae8c7699b 100644
--- a/stdlib/source/test/aedifex/dependency/resolution.lux
+++ b/stdlib/source/test/aedifex/dependency/resolution.lux
@@ -13,33 +13,31 @@
     [concurrency
      ["." promise]]]
    [data
+    [binary (#+ Binary)]
     ["." product]
-    ["." binary]
     ["." text
+     ["%" format (#+ format)]
      [encoding
       ["." utf8]]]
     [format
      ["." xml]]
     [collection
      ["." dictionary]
-     ["." set]]]
+     ["." set]
+     ["." list]]]
    [math
     ["." random (#+ Random)]]]
   ["$." /// #_
    ["#." package]
    ["#." repository]
-   ["#." artifact]
-   [//
-    [lux
-     [data
-      ["$." binary]]]]]
+   ["#." artifact]]
   {#program
    ["." /
     ["//#" /// #_
      ["#" profile]
      ["#." package (#+ Package)]
      ["#." hash]
-     ["#." dependency
+     ["#." dependency (#+ Dependency) ("#\." equivalence)
       ["#/." status]]
      ["#." pom]
      ["#." artifact (#+ Artifact)
@@ -94,6 +92,136 @@
      (def: (on_upload uri binary state)
        (#try.Failure "NOPE")))))
 
+(def: lux_sha1
+  Text
+  (format ///artifact/extension.lux_library ///artifact/extension.sha-1))
+
+(def: lux_md5
+  Text
+  (format ///artifact/extension.lux_library ///artifact/extension.md5))
+
+(def: pom_sha1
+  Text
+  (format ///artifact/extension.pom ///artifact/extension.sha-1))
+
+(def: pom_md5
+  Text
+  (format ///artifact/extension.pom ///artifact/extension.md5))
+
+(def: sha1
+  (-> Binary Binary)
+  (|>> ///hash.sha-1
+       (\ ///hash.sha-1_codec encode)
+       (\ utf8.codec encode)))
+
+(def: md5
+  (-> Binary Binary)
+  (|>> ///hash.md5
+       (\ ///hash.md5_codec encode)
+       (\ utf8.codec encode)))
+
+(def: (bad_sha-1 expected_artifact expected_package dummy_package)
+  (-> Artifact Package Package (Simulation Any))
+  (structure
+   (def: (on_download uri state)
+     (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
+       (cond (text.ends_with? ///artifact/extension.lux_library uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.library)
+                                      product.left)])
+
+             (text.ends_with? lux_sha1 uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.library)
+                                      product.left
+                                      sha1)])
+
+             (text.ends_with? lux_md5 uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.library)
+                                      product.left
+                                      md5)])
+             
+             (text.ends_with? ///artifact/extension.pom uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode))])
+
+             (text.ends_with? pom_sha1 uri)
+             (#try.Success [state (|> dummy_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode)
+                                      sha1)])
+
+             (text.ends_with? pom_md5 uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode)
+                                      md5)])
+
+             ## else
+             (#try.Failure "NOPE"))
+       (#try.Failure "NOPE")))
+   (def: (on_upload uri binary state)
+     (#try.Failure "NOPE"))))
+
+(def: (bad_md5 expected_artifact expected_package dummy_package)
+  (-> Artifact Package Package (Simulation Any))
+  (structure
+   (def: (on_download uri state)
+     (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
+       (cond (text.ends_with? ///artifact/extension.lux_library uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.library)
+                                      product.left)])
+
+             (text.ends_with? lux_sha1 uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.library)
+                                      product.left
+                                      sha1)])
+
+             (text.ends_with? lux_md5 uri)
+             (#try.Success [state (|> dummy_package
+                                      (get@ #///package.library)
+                                      product.left
+                                      md5)])
+             
+             (text.ends_with? ///artifact/extension.pom uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode))])
+
+             (text.ends_with? pom_sha1 uri)
+             (#try.Success [state (|> expected_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode)
+                                      sha1)])
+
+             (text.ends_with? pom_md5 uri)
+             (#try.Success [state (|> dummy_package
+                                      (get@ #///package.pom)
+                                      product.left
+                                      (\ xml.codec encode)
+                                      (\ utf8.codec encode)
+                                      md5)])
+
+             ## else
+             (#try.Failure "NOPE"))
+       (#try.Failure "NOPE")))
+   (def: (on_upload uri binary state)
+     (#try.Failure "NOPE"))))
+
 (def: one
   Test
   (do {! random.monad}
@@ -105,72 +233,8 @@
                                            not)
                                       $///package.random)
      #let [good (..single expected_artifact expected_package)
-           bad_sha-1 (: (Simulation Any)
-                        (structure
-                         (def: (on_download uri state)
-                           (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
-                             (cond (text.ends_with? ///artifact/extension.lux_library uri)
-                                   (#try.Success [state (|> expected_package
-                                                            (get@ #///package.library)
-                                                            product.left)])
-                                   
-                                   (text.ends_with? ///artifact/extension.pom uri)
-                                   (#try.Success [state (|> expected_package
-                                                            (get@ #///package.pom)
-                                                            product.left
-                                                            (\ xml.codec encode)
-                                                            (\ utf8.codec encode))])
-                                   
-                                   ## (text\= extension ///artifact/extension.sha-1)
-                                   ## (#try.Success [state (|> dummy_package
-                                   ##                          (get@ #///package.sha-1)
-                                   ##                          (\ ///hash.sha-1_codec encode)
-                                   ##                          (\ utf8.codec encode))])
-                                   
-                                   ## (text\= extension ///artifact/extension.md5)
-                                   ## (#try.Success [state (|> expected_package
-                                   ##                          (get@ #///package.md5)
-                                   ##                          (\ ///hash.md5_codec encode)
-                                   ##                          (\ utf8.codec encode))])
-
-                                   ## else
-                                   (#try.Failure "NOPE"))
-                             (#try.Failure "NOPE")))
-                         (def: (on_upload uri binary state)
-                           (#try.Failure "NOPE"))))
-           bad_md5 (: (Simulation Any)
-                      (structure
-                       (def: (on_download uri state)
-                         (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
-                           (cond (text.ends_with? ///artifact/extension.lux_library uri)
-                                 (#try.Success [state (|> expected_package
-                                                          (get@ #///package.library)
-                                                          product.left)])
-                                 
-                                 (text.ends_with? ///artifact/extension.pom uri)
-                                 (#try.Success [state (|> expected_package
-                                                          (get@ #///package.pom)
-                                                          product.left
-                                                          (\ xml.codec encode)
-                                                          (\ utf8.codec encode))])
-                                 
-                                 ## (text\= extension ///artifact/extension.sha-1)
-                                 ## (#try.Success [state (|> expected_package
-                                 ##                          (get@ #///package.sha-1)
-                                 ##                          (\ ///hash.sha-1_codec encode)
-                                 ##                          (\ utf8.codec encode))])
-                                 
-                                 ## (text\= extension ///artifact/extension.md5)
-                                 ## (#try.Success [state (|> dummy_package
-                                 ##                          (get@ #///package.md5)
-                                 ##                          (\ ///hash.md5_codec encode)
-                                 ##                          (\ utf8.codec encode))])
-
-                                 ## else
-                                 (#try.Failure "NOPE"))
-                           (#try.Failure "NOPE")))
-                       (def: (on_upload uri binary state)
-                         (#try.Failure "NOPE"))))]]
+           bad_sha-1 (..bad_sha-1 expected_artifact expected_package dummy_package)
+           bad_md5 (..bad_md5 expected_artifact expected_package dummy_package)]]
     (`` ($_ _.and
             (wrap
              (do promise.monad
@@ -216,72 +280,8 @@
                                            not)
                                       $///package.random)
      #let [good (..single expected_artifact expected_package)
-           bad_sha-1 (: (Simulation Any)
-                        (structure
-                         (def: (on_download uri state)
-                           (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
-                             (cond (text.ends_with? ///artifact/extension.lux_library uri)
-                                   (#try.Success [state (|> expected_package
-                                                            (get@ #///package.library)
-                                                            product.left)])
-                                   
-                                   (text.ends_with? ///artifact/extension.pom uri)
-                                   (#try.Success [state (|> expected_package
-                                                            (get@ #///package.pom)
-                                                            product.left
-                                                            (\ xml.codec encode)
-                                                            (\ utf8.codec encode))])
-                                   
-                                   ## (text\= extension ///artifact/extension.sha-1)
-                                   ## (#try.Success [state (|> dummy_package
-                                   ##                          (get@ #///package.sha-1)
-                                   ##                          (\ ///hash.sha-1_codec encode)
-                                   ##                          (\ utf8.codec encode))])
-                                   
-                                   ## (text\= extension ///artifact/extension.md5)
-                                   ## (#try.Success [state (|> expected_package
-                                   ##                          (get@ #///package.md5)
-                                   ##                          (\ ///hash.md5_codec encode)
-                                   ##                          (\ utf8.codec encode))])
-
-                                   ## else
-                                   (#try.Failure "NOPE"))
-                             (#try.Failure "NOPE")))
-                         (def: (on_upload uri binary state)
-                           (#try.Failure "NOPE"))))
-           bad_md5 (: (Simulation Any)
-                      (structure
-                       (def: (on_download uri state)
-                         (if (text.contains? (///artifact.uri (get@ #///artifact.version expected_artifact) expected_artifact) uri)
-                           (cond (text.ends_with? ///artifact/extension.lux_library uri)
-                                 (#try.Success [state (|> expected_package
-                                                          (get@ #///package.library)
-                                                          product.left)])
-                                 
-                                 (text.ends_with? ///artifact/extension.pom uri)
-                                 (#try.Success [state (|> expected_package
-                                                          (get@ #///package.pom)
-                                                          product.left
-                                                          (\ xml.codec encode)
-                                                          (\ utf8.codec encode))])
-                                 
-                                 ## (text\= extension ///artifact/extension.sha-1)
-                                 ## (#try.Success [state (|> expected_package
-                                 ##                          (get@ #///package.sha-1)
-                                 ##                          (\ ///hash.sha-1_codec encode)
-                                 ##                          (\ utf8.codec encode))])
-                                 
-                                 ## (text\= extension ///artifact/extension.md5)
-                                 ## (#try.Success [state (|> dummy_package
-                                 ##                          (get@ #///package.md5)
-                                 ##                          (\ ///hash.md5_codec encode)
-                                 ##                          (\ utf8.codec encode))])
-
-                                 ## else
-                                 (#try.Failure "NOPE"))
-                           (#try.Failure "NOPE")))
-                       (def: (on_upload uri binary state)
-                         (#try.Failure "NOPE"))))]]
+           bad_sha-1 (..bad_sha-1 expected_artifact expected_package dummy_package)
+           bad_md5 (..bad_md5 expected_artifact expected_package dummy_package)]]
     ($_ _.and
         (wrap
          (do promise.monad
@@ -314,77 +314,106 @@
                        false))))
         )))
 
-## (def: all
-##   Test
-##   (do {! random.monad}
-##     [dependee_artifact $///artifact.random
-##      depender_artifact (random.filter (predicate.complement
-##                                        (\ ///artifact.equivalence = dependee_artifact))
-##                                       $///artifact.random)
-##      ignored_artifact (random.filter (predicate.complement
-##                                       (predicate.unite (\ ///artifact.equivalence = dependee_artifact)
-##                                                        (\ ///artifact.equivalence = depender_artifact)))
-##                                      $///artifact.random)
-
-##      [_ dependee_package] $///package.random
-##      [_ depender_package] $///package.random
-##      [_ ignored_package] $///package.random
-
-##      #let [dependee {#///dependency.artifact dependee_artifact
-##                      #///dependency.type ///artifact/type.lux_library}
-##            depender {#///dependency.artifact depender_artifact
-##                      #///dependency.type ///artifact/type.lux_library}
-##            ignored {#///dependency.artifact ignored_artifact
-##                     #///dependency.type ///artifact/type.lux_library}
-
-##            dependee_pom (|> (\ ///.monoid identity)
-##                             (set@ #///.identity (#.Some dependee_artifact))
-##                             ///pom.write
-##                             try.assume)
-##            depender_pom (|> (\ ///.monoid identity)
-##                             (set@ #///.identity (#.Some depender_artifact))
-##                             (set@ #///.dependencies (set.from_list ///dependency.hash (list dependee)))
-##                             ///pom.write
-##                             try.assume)
-##            ignored_pom (|> (\ ///.monoid identity)
-##                            (set@ #///.identity (#.Some ignored_artifact))
-##                            ///pom.write
-##                            try.assume)
-
-##            dependee_package (set@ #///package.pom [dependee_pom #///dependency/status.Unverified] dependee_package)
-##            depender_package (set@ #///package.pom [depender_pom #///dependency/status.Unverified] depender_package)
-##            ignored_package (set@ #///package.pom [ignored_pom #///dependency/status.Unverified] ignored_package)]]
-##     ($_ _.and
-##         (wrap
-##          (do promise.monad
-##            [resolution (/.all (list (///repository.mock (..single dependee_artifact dependee_package) [])
-##                                     (///repository.mock (..single depender_artifact depender_package) [])
-##                                     (///repository.mock (..single ignored_artifact ignored_package) []))
-##                               (list depender)
-##                               /.empty)]
-##            (_.cover' [/.all]
-##                      (case resolution
-##                        (#try.Success resolution)
-##                        (and (dictionary.key? resolution depender)
-##                             (dictionary.key? resolution dependee)
-##                             (not (dictionary.key? resolution ignored)))
-
-##                        (#try.Failure error)
-##                        false))))
-##         )))
-
-## (def: #export test
-##   Test
-##   (<| (_.covering /._)
-##       (_.for [/.Resolution])
-##       ($_ _.and
-##           (_.for [/.equivalence]
-##                  ($equivalence.spec /.equivalence ..random))
-
-##           (_.cover [/.empty]
-##                    (dictionary.empty? /.empty))
-
-##           ..one
-##           ..any
-##           ..all
-##           )))
+(def: artifacts
+  (Random [Artifact Artifact Artifact])
+  (do random.monad
+    [dependee_artifact $///artifact.random
+     depender_artifact (random.filter (predicate.complement
+                                       (\ ///artifact.equivalence = dependee_artifact))
+                                      $///artifact.random)
+     ignored_artifact (random.filter (predicate.complement
+                                      (predicate.unite (\ ///artifact.equivalence = dependee_artifact)
+                                                       (\ ///artifact.equivalence = depender_artifact)))
+                                     $///artifact.random)]
+    (wrap [dependee_artifact depender_artifact ignored_artifact])))
+
+(def: (packages [dependee_artifact depender_artifact ignored_artifact])
+  (-> [Artifact Artifact Artifact]
+      (Random [[Dependency Dependency Dependency]
+               [Package Package Package]]))
+  (do random.monad
+    [[_ dependee_package] $///package.random
+     [_ depender_package] $///package.random
+     [_ ignored_package] $///package.random
+
+     #let [dependee {#///dependency.artifact dependee_artifact
+                     #///dependency.type ///artifact/type.lux_library}
+           depender {#///dependency.artifact depender_artifact
+                     #///dependency.type ///artifact/type.lux_library}
+           ignored {#///dependency.artifact ignored_artifact
+                    #///dependency.type ///artifact/type.lux_library}
+
+           dependee_pom (|> (\ ///.monoid identity)
+                            (set@ #///.identity (#.Some dependee_artifact))
+                            ///pom.write
+                            try.assume)
+           depender_pom (|> (\ ///.monoid identity)
+                            (set@ #///.identity (#.Some depender_artifact))
+                            (set@ #///.dependencies (set.from_list ///dependency.hash (list dependee)))
+                            ///pom.write
+                            try.assume)
+           ignored_pom (|> (\ ///.monoid identity)
+                           (set@ #///.identity (#.Some ignored_artifact))
+                           ///pom.write
+                           try.assume)
+
+           dependee_package (set@ #///package.pom
+                                  [dependee_pom
+                                   (|> dependee_pom (\ xml.codec encode) (\ utf8.codec encode))
+                                   #///dependency/status.Unverified]
+                                  dependee_package)
+           depender_package (set@ #///package.pom
+                                  [depender_pom
+                                   (|> depender_pom (\ xml.codec encode) (\ utf8.codec encode))
+                                   #///dependency/status.Unverified]
+                                  depender_package)
+           ignored_package (set@ #///package.pom
+                                 [ignored_pom
+                                  (|> ignored_pom (\ xml.codec encode) (\ utf8.codec encode))
+                                  #///dependency/status.Unverified]
+                                 ignored_package)]]
+    (wrap [[dependee depender ignored]
+           [dependee_package depender_package ignored_package]])))
+
+(def: all
+  Test
+  (do {! random.monad}
+    [[dependee_artifact depender_artifact ignored_artifact] ..artifacts
+
+     [[dependee depender ignored]
+      [dependee_package depender_package ignored_package]]
+     (..packages [dependee_artifact depender_artifact ignored_artifact])]
+    ($_ _.and
+        (wrap
+         (do promise.monad
+           [[successes failures resolution] (/.all (list (///repository.mock (..single dependee_artifact dependee_package) [])
+                                                         (///repository.mock (..single depender_artifact depender_package) [])
+                                                         (///repository.mock (..single ignored_artifact ignored_package) []))
+                                                   (list depender)
+                                                   /.empty)]
+           (_.cover' [/.all]
+                     (and (dictionary.key? resolution depender)
+                          (list.any? (///dependency\= depender) successes)
+                          
+                          (dictionary.key? resolution dependee)
+                          (list.any? (///dependency\= dependee) successes)
+
+                          (list.empty? failures)
+                          (not (dictionary.key? resolution ignored))))))
+        )))
+
+(def: #export test
+  Test
+  (<| (_.covering /._)
+      (_.for [/.Resolution])
+      ($_ _.and
+          (_.for [/.equivalence]
+                 ($equivalence.spec /.equivalence ..random))
+
+          (_.cover [/.empty]
+                   (dictionary.empty? /.empty))
+
+          ..one
+          ..any
+          ..all
+          )))
diff --git a/stdlib/source/test/aedifex/input.lux b/stdlib/source/test/aedifex/input.lux
index e2751381a..86771cf1f 100644
--- a/stdlib/source/test/aedifex/input.lux
+++ b/stdlib/source/test/aedifex/input.lux
@@ -13,7 +13,8 @@
     ["." binary]
     ["." text
      ["%" format (#+ format)]
-     ["." encoding]]
+     [encoding
+      ["." utf8]]]
     [collection
      ["." set (#+ Set)]]]
    [math
@@ -28,7 +29,9 @@
      ["#" profile (#+ Profile)]
      ["#." project]
      ["#." action]
-     ["#." format]]]})
+     ["#." format]
+     [repository
+      [remote (#+ Address)]]]]})
 
 (def: (with_default_source sources)
   (-> (Set //.Source) (Set //.Source))
@@ -36,6 +39,10 @@
     (set.add //.default_source sources)
     sources))
 
+(def: with_default_repository
+  (-> (Set Address) (Set Address))
+  (set.add //.default_repository))
+
 (def: #export test
   Test
   (<| (_.covering /._)
@@ -50,12 +57,14 @@
                             _ (|> expected
                                   //format.profile
                                   %.code
-                                  (\ encoding.utf8 encode)
+                                  (\ utf8.codec encode)
                                   (!.use (\ file over_write)))
                             actual (: (Promise (Try Profile))
                                       (/.read promise.monad fs //.default))]
                            (wrap (\ //.equivalence =
-                                    (update@ #//.sources ..with_default_source expected)
+                                    (|> expected
+                                        (update@ #//.sources ..with_default_source)
+                                        (update@ #//.repositories ..with_default_repository))
                                     actual)))]
                 (_.cover' [/.read]
                           (try.default false verdict)))))))
diff --git a/stdlib/source/test/lux/math.lux b/stdlib/source/test/lux/math.lux
index 403205dad..3645ef1bf 100644
--- a/stdlib/source/test/lux/math.lux
+++ b/stdlib/source/test/lux/math.lux
@@ -1,15 +1,16 @@
 (.module:
   [lux #*
-   ["%" data/text/format (#+ format)]
    ["_" test (#+ Test)]
    [abstract
     [monad (#+ do)]]
+   [macro
+    ["." template]]
    [math
     ["." random (#+ Random)]
     [number
      ["n" nat]
-     ["f" frac]
-     ["." int]]]]
+     ["i" int]
+     ["f" frac]]]]
   {1
    ["." /]}
   ["." / #_
@@ -21,71 +22,136 @@
     ["#/." continuous]
     ["#/." fuzzy]]])
 
-(def: margin
+(def: margin_of_error
   +0.0000001)
 
 (def: (trigonometric_symmetry forward backward angle)
   (-> (-> Frac Frac) (-> Frac Frac) Frac Bit)
   (let [normal (|> angle forward backward)]
-    (|> normal forward backward (f.approximately? margin normal))))
+    (|> normal forward backward (f.approximately? ..margin_of_error normal))))
 
 (def: #export test
   Test
-  (<| (_.context (%.name (name_of /._)))
+  (<| (_.covering /._)
       ($_ _.and
-          (<| (_.context "Trigonometry")
-              (do {! random.monad}
-                [angle (|> random.safe_frac (\ ! map (f.* /.tau)))]
-                ($_ _.and
-                    (_.test "Sine and arc-sine are inverse functions."
-                            (trigonometric_symmetry /.sin /.asin angle))
-                    (_.test "Cosine and arc-cosine are inverse functions."
-                            (trigonometric_symmetry /.cos /.acos angle))
-                    (_.test "Tangent and arc-tangent are inverse functions."
-                            (trigonometric_symmetry /.tan /.atan angle))
-                    )))
-          (<| (_.context "Rounding")
-              (do {! random.monad}
-                [sample (|> random.safe_frac (\ ! map (f.* +1000.0)))]
-                ($_ _.and
-                    (_.test "The ceiling will be an integer value, and will be >= the original."
-                            (let [ceil'd (/.ceil sample)]
-                              (and (|> ceil'd f.int int.frac (f.= ceil'd))
-                                   (f.>= sample ceil'd)
-                                   (f.<= +1.0 (f.- sample ceil'd)))))
-                    (_.test "The floor will be an integer value, and will be <= the original."
-                            (let [floor'd (/.floor sample)]
-                              (and (|> floor'd f.int int.frac (f.= floor'd))
-                                   (f.<= sample floor'd)
-                                   (f.<= +1.0 (f.- floor'd sample)))))
-                    (_.test "The round will be an integer value, and will be < or > or = the original."
-                            (let [round'd (/.round sample)]
-                              (and (|> round'd f.int int.frac (f.= round'd))
-                                   (f.<= +1.0 (f.abs (f.- sample round'd))))))
-                    )))
-          (<| (_.context "Exponentials and logarithms")
-              (do {! random.monad}
-                [sample (|> random.safe_frac (\ ! map (f.* +10.0)))]
-                (_.test "Logarithm is the inverse of exponential."
-                        (|> sample /.exp /.log (f.approximately? +0.000000000000001 sample)))))
-          (<| (_.context "Greatest-Common-Divisor and Least-Common-Multiple")
-              (do {! random.monad}
-                [#let [gen_nat (|> random.nat (\ ! map (|>> (n.% 1000) (n.max 1))))]
-                 x gen_nat
-                 y gen_nat]
-                ($_ _.and
-                    (_.test "GCD"
-                            (let [gcd (n.gcd x y)]
-                              (and (n.= 0 (n.% gcd x))
-                                   (n.= 0 (n.% gcd y))
-                                   (n.>= 1 gcd))))
+          (do {! random.monad}
+            [#let [~= (f.approximately? ..margin_of_error)]
+             angle (|> random.safe_frac (\ ! map (f.* /.tau)))]
+            ($_ _.and
+                (_.cover [/.sin /.asin]
+                         (trigonometric_symmetry /.sin /.asin angle))
+                (_.cover [/.cos /.acos]
+                         (trigonometric_symmetry /.cos /.acos angle))
+                (_.cover [/.tan /.atan]
+                         (trigonometric_symmetry /.tan /.atan angle))
+                (_.cover [/.tau]
+                         (and (and (~= +0.0 (/.sin /.tau))
+                                   (~= +1.0 (/.cos /.tau)))
+                              (and (~= +0.0 (/.sin (f./ +2.0 /.tau)))
+                                   (~= -1.0 (/.cos (f./ +2.0 /.tau))))
+                              (and (~= +1.0 (/.sin (f./ +4.0 /.tau)))
+                                   (~= +0.0 (/.cos (f./ +4.0 /.tau))))
+                              (and (~= -1.0 (/.sin (f.* +3.0 (f./ +4.0 /.tau))))
+                                   (~= +0.0 (/.cos (f.* +3.0 (f./ +4.0 /.tau)))))
+                              (let [x2+y2 (f.+ (/.pow +2.0 (/.sin angle))
+                                               (/.pow +2.0 (/.cos angle)))]
+                                (~= +1.0 x2+y2))))
+                (_.cover [/.pi]
+                         (~= (f./ +2.0 /.tau) /.pi))
+                ))
+          (do {! random.monad}
+            [sample (|> random.safe_frac (\ ! map (f.* +1000.0)))]
+            ($_ _.and
+                (_.cover [/.ceil]
+                         (let [ceil'd (/.ceil sample)]
+                           (and (|> ceil'd f.int i.frac (f.= ceil'd))
+                                (f.>= sample ceil'd)
+                                (f.<= +1.0 (f.- sample ceil'd)))))
+                (_.cover [/.floor]
+                         (let [floor'd (/.floor sample)]
+                           (and (|> floor'd f.int i.frac (f.= floor'd))
+                                (f.<= sample floor'd)
+                                (f.<= +1.0 (f.- floor'd sample)))))
+                (_.cover [/.round]
+                         (let [round'd (/.round sample)]
+                           (and (|> round'd f.int i.frac (f.= round'd))
+                                (f.<= +1.0 (f.abs (f.- sample round'd))))))
+                ))
+          (do {! random.monad}
+            [#let [~= (f.approximately? ..margin_of_error)]
+             sample (\ ! map (f.* +10.0) random.safe_frac)
+             power (\ ! map (|>> (n.% 10) inc n.frac) random.nat)]
+            ($_ _.and
+                (_.cover [/.exp /.log]
+                         (|> sample /.exp /.log (f.approximately? +0.000000000000001 sample)))
+                (_.cover [/.e]
+                         (~= +1.0 (/.log /.e)))
+                (_.cover [/.pow /.log']
+                         (let [sample (f.abs sample)]
+                           (|> sample
+                               (/.pow power)
+                               (/.log' sample)
+                               (~= power))))
+                ))
+          (do {! random.monad}
+            [#let [~= (f.approximately? ..margin_of_error)]
+             angle (\ ! map (f.* /.tau) random.safe_frac)
+             sample (\ ! map f.abs random.safe_frac)
+             big (\ ! map (f.* +1,000,000,000.00) random.safe_frac)]
+            (template.with [(odd! <function>)
+                            [(_.cover [<function>]
+                                      (~= (f.negate (<function> angle))
+                                          (<function> (f.negate angle))))]
 
-                    (_.test "LCM"
-                            (let [lcm (n.lcm x y)]
-                              (and (n.= 0 (n.% x lcm))
-                                   (n.= 0 (n.% y lcm))
-                                   (n.<= (n.* x y) lcm))))
-                    )))
+                            (even! <function>)
+                            [(_.cover [<function>]
+                                      (~= (<function> angle)
+                                          (<function> (f.negate angle))))]
+
+                            (inverse! <left> <right> <input>)
+                            [(_.cover [<left> <right>]
+                                      (~= (<right> <input>)
+                                          (<left> (f./ <input> +1.0))))]]
+              ($_ _.and
+                  (odd! /.sinh)
+                  (even! /.cosh)
+                  (odd! /.tanh)
+                  (odd! /.coth)
+                  (even! /.sech)
+                  (odd! /.csch)
+
+                  (inverse! /.acosh /.asech sample)
+                  (inverse! /.asinh /.acsch sample)
+                  (inverse! /.atanh /.acoth big)
+                  )))
+          (do {! random.monad}
+            [x (\ ! map (|>> (f.* +10.0) f.abs) random.safe_frac)
+             y (\ ! map (|>> (f.* +10.0) f.abs) random.safe_frac)]
+            (_.cover [/.hypotenuse]
+                     (let [h (/.hypotenuse x y)]
+                       (and (f.>= x h)
+                            (f.>= y h)))))
+          (do {! random.monad}
+            [#let [~= (f.approximately? ..margin_of_error)
+                   tau/4 (f./ +4.0 /.tau)]
+             x (\ ! map (f.* tau/4) random.safe_frac)
+             y (\ ! map (f.* tau/4) random.safe_frac)]
+            (_.cover [/.atan/2]
+                     (let [expected (/.atan/2 x y)
+                           actual (if (f.> +0.0 x)
+                                    (/.atan (f./ x y))
+                                    (if (f.< +0.0 y)
+                                      (f.- /.pi (/.atan (f./ x y)))
+                                      (f.+ /.pi (/.atan (f./ x y)))))]
+                       (and (~= expected actual)
+                            (~= tau/4 (/.atan/2 +0.0 (f.abs y)))
+                            (~= (f.negate tau/4) (/.atan/2 +0.0 (f.negate (f.abs y))))
+                            (f.not_a_number? (/.atan/2 +0.0 +0.0))))))
+          (do {! random.monad}
+            [of (\ ! map (|>> (n.% 10) inc) random.nat)]
+            (_.cover [/.factorial]
+                     (and (n.= 1 (/.factorial 0))
+                          (|> (/.factorial of) (n.% of) (n.= 0)))))
 
           /infix.test
           /modulus.test
-- 
cgit v1.2.3