diff --git a/deps-lock.json b/deps-lock.json index 6b26bba..8579cce 100644 --- a/deps-lock.json +++ b/deps-lock.json @@ -10,6 +10,16 @@ } ], "mvn-deps": [ + { + "mvn-path": "aero/aero/1.1.6/aero-1.1.6.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-9LCpJy2lDICRxVKcn+NVxHI08e65X+kiluLCP3h/PSI=" + }, + { + "mvn-path": "aero/aero/1.1.6/aero-1.1.6.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-WUXPjq14D3SX6G8piWPyeGgdUZrpshvpSfrFQg8F01A=" + }, { "mvn-path": "babashka/fs/0.5.24/fs-0.5.24.jar", "mvn-repo": "https://repo.clojars.org/", @@ -40,6 +50,31 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-LVp6g6ymqHa1ZOMHYD0CRaNxZ4osT0xoEH7dC5sLv7s=" }, + { + "mvn-path": "ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-mMPxj10NZCzV8yfMckVmzRlklibH2I9wFDvXBMlBV9U=" + }, + { + "mvn-path": "ch/qos/logback/logback-classic/1.1.3/logback-classic-1.1.3.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Ond3RjIf1uIuOMzf1PY0vKNysA7mIAPlJ/aqRkkF8+g=" + }, + { + "mvn-path": "ch/qos/logback/logback-core/1.1.3/logback-core-1.1.3.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-R8D9NCmV0zFbj6zKzDJLKnYUOyfEMNSy1qKeq8MfXBQ=" + }, + { + "mvn-path": "ch/qos/logback/logback-core/1.1.3/logback-core-1.1.3.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-ziBX5rWqOWLWyNtAxJ6LzhFQqaobNhXtS6b1I9O5pwA=" + }, + { + "mvn-path": "ch/qos/logback/logback-parent/1.1.3/logback-parent-1.1.3.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-ag4n7GeP9dkLjMZku0UZifXitbMAamW95Lld7BmHOHE=" + }, { "mvn-path": "cheshire/cheshire/6.1.0/cheshire-6.1.0.jar", "mvn-repo": "https://repo.clojars.org/", @@ -125,6 +160,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-dXkdZHooK97QEyeXodFSC942EiB9B8MlHUNZlbH8nvI=" }, + { + "mvn-path": "com/nextjournal/beholder/1.0.2/beholder-1.0.2.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-iQOMTbidIDu1sSpfsa2qkpXgWirEsk+u2ZbJNOqJ0Xo=" + }, + { + "mvn-path": "com/nextjournal/beholder/1.0.2/beholder-1.0.2.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-LRJkSGdQPfLoeGjLwU3deFKoaum2dW/QJ46lCK0d4u4=" + }, { "mvn-path": "com/rpl/specter/1.1.6/specter-1.1.6.jar", "mvn-repo": "https://repo.clojars.org/", @@ -195,6 +240,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-2OgLA0KFMl6QX1RkmhWYtoe5pKmaOk9LlO7TWXyyEEg=" }, + { + "mvn-path": "expound/expound/0.9.0/expound-0.9.0.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-1qNyYJkY4DUb+mqL1pPRi8GZ6Lp6r67BHola+uAY+Vw=" + }, + { + "mvn-path": "expound/expound/0.9.0/expound-0.9.0.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-kJSODD3MvE8aCvaABWue2JizAcvtLd4/9CR5eWmXxdk=" + }, { "mvn-path": "fipp/fipp/0.6.27/fipp-0.6.27.jar", "mvn-repo": "https://repo.clojars.org/", @@ -205,6 +260,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-ugagpDW5XBNQMTr+1z3s6r5TXwbF/pw6Ffrcc4Tzlvk=" }, + { + "mvn-path": "hawk/hawk/0.2.11/hawk-0.2.11.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-6UPy8MSHxsWmsg5wzpHdXzHkBIlXCRe7oT/OpzyaekM=" + }, + { + "mvn-path": "hawk/hawk/0.2.11/hawk-0.2.11.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-q4PzoWHUY53W2TZWihPpw+qXB4QWWVnS1iW3WlvIxFg=" + }, { "mvn-path": "hiccup/hiccup/2.0.0-RC4/hiccup-2.0.0-RC4.jar", "mvn-repo": "https://repo.clojars.org/", @@ -235,6 +300,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-7Vh2tzj7zXYdGd03xiyTExP/beuWSi8Nn1NmRKkw9bQ=" }, + { + "mvn-path": "io/methvin/directory-watcher/0.17.3/directory-watcher-0.17.3.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-BSPdOKOTpjt15DIP9SMDSgrDzqaX9hUaesiok8MiUx4=" + }, + { + "mvn-path": "io/methvin/directory-watcher/0.17.3/directory-watcher-0.17.3.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Y/C4zR1No0m2Dfk4kdHgDF0/0sm9M9jlvu0HWijNiFQ=" + }, { "mvn-path": "lambdaisland/clj-diff/1.4.78/clj-diff-1.4.78.jar", "mvn-repo": "https://repo.clojars.org/", @@ -255,6 +330,26 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-rW/85js2hSWVc36e2BcTRmkahJHc2TjGIEfvForuToY=" }, + { + "mvn-path": "lambdaisland/kaocha/1.91.1392/kaocha-1.91.1392.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-W7EV1MqxeIVqyTyt6lV9vpZrLRc+TWQKnmNfiPoieug=" + }, + { + "mvn-path": "lambdaisland/kaocha/1.91.1392/kaocha-1.91.1392.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-p6+0cuuFYlJU5YlhGIbnuHt1d6yOZXx/FhwAM6wCyzg=" + }, + { + "mvn-path": "lambdaisland/tools.namespace/0.3.256/tools.namespace-0.3.256.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-jt141ljkjv97etTTE995zZnqiZfoFnyt0g2hwmuOU8M=" + }, + { + "mvn-path": "lambdaisland/tools.namespace/0.3.256/tools.namespace-0.3.256.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-n+46BXjy57A8898EXgyplEyyqf/S5qocf140ZbglV64=" + }, { "mvn-path": "medley/medley/1.4.0/medley-1.4.0.jar", "mvn-repo": "https://repo.clojars.org/", @@ -265,6 +360,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-JhEgB4cMXujVcrvDw4n8a9bMZG1cUAdfbolYQMWGEMA=" }, + { + "mvn-path": "meta-merge/meta-merge/1.0.0/meta-merge-1.0.0.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-1/7i4+PXBuDlRWLnKqNxIQjXAYahLLwJDhBoBYLrAsc=" + }, + { + "mvn-path": "meta-merge/meta-merge/1.0.0/meta-merge-1.0.0.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-sAogZY/OzCvRNBAx85T1LWjFP7SAxEVBNMyqwgTqWTE=" + }, { "mvn-path": "mvxcvi/arrangement/2.1.0/arrangement-2.1.0.jar", "mvn-repo": "https://repo.clojars.org/", @@ -285,6 +390,26 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-SzmvI+F2QOnCPH5H6OKH124pbohIazXgPG3PhqH0VZA=" }, + { + "mvn-path": "net/incongru/watchservice/barbary-watchservice/1.0/barbary-watchservice-1.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-VMbKvYIJPIUV9uFOQ9lL/n6fx5XRV4nzlDoUGNgmOrU=" + }, + { + "mvn-path": "net/incongru/watchservice/barbary-watchservice/1.0/barbary-watchservice-1.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-k7OxHaltUXiIDfjFBT8Yz8eByv8Nnd9LPGRyRKnRws8=" + }, + { + "mvn-path": "net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-kagUrE9A1g3ukdhC4aith0xiGXmEQD0OPDDTnlXPU7M=" + }, + { + "mvn-path": "net/java/dev/jna/jna/5.12.1/jna-5.12.1.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Zf8lhJuthZVUtQMXeS9Wia20UprkAx6aUkYxnLK4U1Y=" + }, { "mvn-path": "org/apache/apache/23/apache-23.pom", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -500,6 +625,16 @@ "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-M0EOuKpz1S2Vez3G4KZfOZisBiPL2BPZDDPm5onEJCk=" }, + { + "mvn-path": "org/clojure/java.classpath/1.0.0/java.classpath-1.0.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-wU4OEDBKXlz9LMdC+976wfUpPuxgcML/6JA/tcf+fW8=" + }, + { + "mvn-path": "org/clojure/java.classpath/1.0.0/java.classpath-1.0.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-C+AThRRX/CTENM5FU0ZD8iblwQgASGJT/Tc/LglUXig=" + }, { "mvn-path": "org/clojure/java.data/1.3.113/java.data-1.3.113.jar", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -515,6 +650,11 @@ "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-RoC9g43MuowXwlgXE0fxb1uq5rXft4Grc4K8Y4X/gAY=" }, + { + "mvn-path": "org/clojure/pom.contrib/0.2.2/pom.contrib-0.2.2.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-4OoifEnFw+MHVM0m/MV75+Telz/kOqXMZmdAHsXBAyM=" + }, { "mvn-path": "org/clojure/pom.contrib/0.3.0/pom.contrib-0.3.0.pom", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -575,6 +715,16 @@ "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-UZ45jnJMYvCsnWsZ15+P8QAdqYWD/eAb1wUrB+Ga1ow=" }, + { + "mvn-path": "org/clojure/tools.cli/1.1.230/tools.cli-1.1.230.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-kWYwtTmkP/RotN0BbGKFfitMtdpmhvEpdYfN1DyhAs0=" + }, + { + "mvn-path": "org/clojure/tools.cli/1.1.230/tools.cli-1.1.230.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-v7Yh5LAaW4vOEWpgcIQNzdWUnomceEaNgRtuiqqf0cc=" + }, { "mvn-path": "org/clojure/tools.logging/1.3.0/tools.logging-1.3.0.jar", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -595,6 +745,16 @@ "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-cGCU9H2ljugXofq5uAwxLs0nZHK85uHVRCOfFAcR2zE=" }, + { + "mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-EdGzHyxlwzVbKSu5tEuPyv2lS0TaY+NKuXt5qKs7uOA=" + }, + { + "mvn-path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-rvXugot8sUocWPRbn4oQ/zQMV2mSXqDvXDXR5J2SC+o=" + }, { "mvn-path": "org/junit/junit-bom/5.11.0/junit-bom-5.11.0.pom", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -640,11 +800,51 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-oLLU3iXdPWNptThQLeay5UJcKxyOM6GQKZgIS4o4EWs=" }, + { + "mvn-path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA=" + }, + { + "mvn-path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-+wRqnCKUN5KLsRwtJ8i113PriiXmDL0lPZhSEN7cJoQ=" + }, + { + "mvn-path": "org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-aZgMA4yhsTGSZWFZFhfZwl+r/Hspgor5FZfKhXDPNf4=" + }, + { + "mvn-path": "org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-NTkEp6bCgwTQ3KyA+tMMSM2Jj22wO5PwWtbJDdQtmK0=" + }, + { + "mvn-path": "org/slf4j/slf4j-parent/1.7.36/slf4j-parent-1.7.36.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-uziNN/vN083mTDzt4hg4aTIY3EUfBAQMXfNgp47X6BI=" + }, + { + "mvn-path": "org/slf4j/slf4j-parent/1.7.7/slf4j-parent-1.7.7.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-Hf+uPOdo0FR+JhyWiYz12dGUv/1WAPWXyXUcxqc9M9Q=" + }, { "mvn-path": "org/sonatype/oss/oss-parent/7/oss-parent-7.pom", "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-tR+IZ8kranIkmVV/w6H96ne9+e9XRyL+kM5DailVlFQ=" }, + { + "mvn-path": "org/tcrawley/dynapath/1.1.0/dynapath-1.1.0.jar", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-n8eqO+Y4XaOtIqBlJvFaXTNdnonUDzm/L5oA4Lu9iug=" + }, + { + "mvn-path": "org/tcrawley/dynapath/1.1.0/dynapath-1.1.0.pom", + "mvn-repo": "https://repo1.maven.org/maven2/", + "hash": "sha256-5OPOTeIWKm8U9QjB0Nv0s9tsrBk5E+kVeAhcGLesJho=" + }, { "mvn-path": "org/xerial/sqlite-jdbc/3.47.1.0/sqlite-jdbc-3.47.1.0.jar", "mvn-repo": "https://repo1.maven.org/maven2/", @@ -655,6 +855,16 @@ "mvn-repo": "https://repo1.maven.org/maven2/", "hash": "sha256-Z3XeNvNR9MdFCL/+qtZAIceVhx/ZRIXsdsPhduUwU7g=" }, + { + "mvn-path": "progrock/progrock/0.1.2/progrock-0.1.2.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-Aln+tbAkduswC31k5UPrVM5Kw9yuU5gxDxZCdo/VPyo=" + }, + { + "mvn-path": "progrock/progrock/0.1.2/progrock-0.1.2.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-6rULcjyeeEkPWDy5n7HUa8KA/xH9X4Ujub7XamTq8CM=" + }, { "mvn-path": "riddley/riddley/0.1.12/riddley-0.1.12.jar", "mvn-repo": "https://repo.clojars.org/", @@ -730,6 +940,16 @@ "mvn-repo": "https://repo.clojars.org/", "hash": "sha256-HHmMD/cPNu7HwRubeajXYOBDYK1y9x9F9KhRytq2AQw=" }, + { + "mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.jar", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-porCK/LqPNVM4023D9aYRNYx71SfZFDCeMMOb3nfY/M=" + }, + { + "mvn-path": "slingshot/slingshot/0.12.2/slingshot-0.12.2.pom", + "mvn-repo": "https://repo.clojars.org/", + "hash": "sha256-SrxOK5ppxzvTc+gy0/AOWQZ4Q/+DUe/V7rsfOCTbnFE=" + }, { "mvn-path": "tigris/tigris/0.1.2/tigris-0.1.2.jar", "mvn-repo": "https://repo.clojars.org/", diff --git a/doerg/deps.edn b/doerg/deps.edn index fde0f8d..2c1cbff 100644 --- a/doerg/deps.edn +++ b/doerg/deps.edn @@ -8,7 +8,8 @@ hiccup/hiccup {:mvn/version "2.0.0-RC4"} com.rpl/specter {:mvn/version "1.1.6"} lambdaisland/deep-diff2 {:mvn/version "2.12.219"} - mvxcvi/clj-cbor {:mvn/version "1.1.1"}} + mvxcvi/clj-cbor {:mvn/version "1.1.1"} + ch.qos.logback/logback-classic {:mvn/version "1.1.3"}} :paths ["src" "resources" "test"] :aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}} diff --git a/doerg/doerg-tex/default.nix b/doerg/doerg-tex/default.nix index 74b5e06..998402d 100644 --- a/doerg/doerg-tex/default.nix +++ b/doerg/doerg-tex/default.nix @@ -3,7 +3,6 @@ , makeWrapper , ibm-plex , callPackage -, our-tex ? callPackage ./our-tex.nix {} }: buildNpmPackage { @@ -13,7 +12,4 @@ buildNpmPackage { npmDeps = importNpmLock { npmRoot = ./.; }; npmConfigHook = importNpmLock.npmConfigHook; dontNpmBuild = true; - buildInputs = [ - our-tex - ]; } diff --git a/doerg/doerg-tex/our-tex.nix b/doerg/our-tex.nix similarity index 100% rename from doerg/doerg-tex/our-tex.nix rename to doerg/our-tex.nix diff --git a/doerg/package.nix b/doerg/package.nix index 978b948..b0909fd 100644 --- a/doerg/package.nix +++ b/doerg/package.nix @@ -1,8 +1,13 @@ { mkCljBin , callPackage +, lib , doerg-parser +, doerg-tex , ibm-plex-web , fake-git +, our-tex ? callPackage ./our-tex.nix {} +, makeWrapper +, breakpointHook }: let @@ -19,6 +24,11 @@ let plex = ibm-plex-web.override { families = [ "math" "serif" "sans" "sans-kr" ]; }; + bin-path = lib.makeBinPath [ + doerg-parser + our-tex + doerg-tex + ]; in mkCljBin' { name = "net.deertopia/doerg"; version = "0.1.0"; @@ -27,9 +37,32 @@ in mkCljBin' { main-ns = "net.deertopia.doerg.main"; nativeBuildInputs = [ plex + makeWrapper + breakpointHook ]; buildInputs = [ doerg-parser + doerg-tex plex + our-tex ]; + nativeCheckInputs = [ + doerg-parser + doerg-tex + plex + our-tex + ]; + doCheck = true; + checkPhase = '' + clojure -M:test + ''; + postInstall = '' + wrapProgram $out/bin/doerg \ + --prefix PATH : ${bin-path} + ''; + # installPhase= '' + # runHook preInstall + # exit 1 + # runHook postInstall + # ''; } diff --git a/doerg/src/net/deertopia/doerg/config.clj b/doerg/src/net/deertopia/doerg/config.clj index 49cdf03..2cee006 100644 --- a/doerg/src/net/deertopia/doerg/config.clj +++ b/doerg/src/net/deertopia/doerg/config.clj @@ -4,16 +4,32 @@ [spec-dict.main :refer [dict]])) (s/def ::config - (s/keys :req [::ibm-plex-web])) + (s/keys :req [::ibm-plex-web + ::latex + ::dvisvgm])) + +(s/def ::file + #(or (instance? java.io.File %) + (string? %))) (def default {::ibm-plex-web - (fs/file - (or (System/getenv "IBM_PLEX_WEB") - (some #(let [x (fs/path % "ibm-plex-web")] - (and (fs/exists? x) x)) - (fs/split-paths (System/getenv "XDG_DATA_DIRS")))))}) + (or (System/getenv "DOERG_IBM_PLEX_WEB") + (fs/file (some #(let [x (fs/path % "ibm-plex-web")] + (and (fs/exists? x) x)) + (fs/split-paths (System/getenv "XDG_DATA_DIRS"))))) + ::latex "xelatex" + ::dvisvgm "dvisvgm" + ;; TODO: Can we automatically set this to "./doerg-tex/index.js" in + ;; a development environment? + ::doerg-tex "doerg-tex"}) (def ^:dynamic *cfg* default) -(s/def ::ibm-plex-web #(instance? java.io.File %)) +(s/def ::ibm-plex-web ::file) + +(s/def ::latex ::file) + +(s/def ::dvisvgm ::file) + +(s/def ::doerg-tex ::file) diff --git a/doerg/src/net/deertopia/doerg/render.clj b/doerg/src/net/deertopia/doerg/render.clj index ed6bb17..0619019 100644 --- a/doerg/src/net/deertopia/doerg/render.clj +++ b/doerg/src/net/deertopia/doerg/render.clj @@ -200,10 +200,7 @@ (deliver promise (hiccup/raw temml)))) (catch Exception e (lr/error e) - (throw e)))) - (when (fs/exists? "/tmp/doerg-svgs") - (fs/delete-tree "/tmp/doerg-svgs")) - (fs/copy-tree svg-dir "/tmp/doerg-svgs")))) + (throw e))))))) fut (future-call (bound-fn* f))] ;; Time out after eight seconds. With all the LaTeX and IPC, there ;; are so many opportunities for things to go wrong