diff --git a/config.local.edn b/config.local.edn index 1a146ce..afc80cb 100644 --- a/config.local.edn +++ b/config.local.edn @@ -1 +1 @@ -{:dev/start-keys [:storage/schema]} +{:dev/start-keys []} diff --git a/deps.edn b/deps.edn index b73c0bd..9a12bf2 100644 --- a/deps.edn +++ b/deps.edn @@ -33,7 +33,10 @@ djblue/portal {:mvn/version "0.35.0"} lambdaisland/uri {:mvn/version "1.13.95"} - com.lambdaisland/facai {:mvn/version "0.7.59-alpha"}} + + ;; Test data + com.lambdaisland/facai {:mvn/version "0.8.68-alpha"} + com.lambdaisland/faker {:mvn/version "0.2.8"}} :aliases {:dev {:extra-paths ["dev"]} diff --git a/dev/user.clj b/dev/user.clj index 5b4434c..ddd117a 100644 --- a/dev/user.clj +++ b/dev/user.clj @@ -43,6 +43,9 @@ (add-tap (jit portal.api/submit)) p)) +(defn system [] + ((jit k16.gx.beta.system/values) sys-id)) + (defn value [k] (get ((jit k16.gx.beta.system/values) sys-id) k)) diff --git a/preview-image.png b/preview-image.png index f426213..a186019 100644 Binary files a/preview-image.png and b/preview-image.png differ diff --git a/preview-image.svg b/preview-image.svg index 2f14c5c..d12a437 100644 --- a/preview-image.svg +++ b/preview-image.svg @@ -9,7 +9,10 @@ id="svg5" xml:space="preserve" sodipodi:docname="preview-image.svg" - inkscape:version="1.2.1 (1:1.2.1+202210291243+9c6d41e410)" + inkscape:version="1.2.2 (1:1.2.2+202212051552+b0a8486541)" + inkscape:export-filename="preview-image.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink" @@ -26,8 +29,8 @@ inkscape:document-units="mm" showgrid="false" inkscape:zoom="0.66331437" - inkscape:cx="705.54781" - inkscape:cy="446.9977" + inkscape:cx="707.05539" + inkscape:cy="442.47496" inkscape:window-width="3840" inkscape:window-height="2083" inkscape:window-x="3840" @@ -265,5128 +268,14 @@ width="135.46666" height="94.403328" preserveAspectRatio="none" - xlink:href="data:image/png;base64,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 -2yk9VwGI3wLdK978/P84eQDym0D2BtjbBwbL5L3apu+IP785zEP8N8ef4A/pS3Sxr6GVagAAAAZi -S0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+QGEwA2HBHwM98AACAA -SURBVHja7NkxDcIAFABRihUSRgYGhLCgA11NcIADBgTgpEPxcf89Cbfecn+s+wFgoO10FgEY6fd6 -igCM9Pm+RQBGul0vIgAjHSUAAAAAAABqDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA -AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH -AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA -AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA -AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA -AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA -AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH -AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA -AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA -AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA -AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA -AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH -AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA -AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA -AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA -AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA -AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH -AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA -AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA -AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA -AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA -AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH -AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA -AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA -AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA -AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA -cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA -AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB -AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy -DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA -ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA -AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM -EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA -IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA -AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ -AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg -xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA -AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA/u3ZgQwAAADAIH/re3yl -EQAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AA -AAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYE -CAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADA -jgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAA -ANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAA -AAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAA -AAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0B -AgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACw -I0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAA -AHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAA -AADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQA -AAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeA -AAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADs -CBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAA -gB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAA -AACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEA -AAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEg -AAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7 -AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAA -YEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAA -AADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAA -AAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQI -AAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCO -AAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA -2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAA -AAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAA -AAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQEC -AAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAj -QAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAA -dgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAA -AMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAA -AAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AA -AAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwI -EAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACA -HQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAA -ALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAA -AAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAA -AAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsC -BAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABg -R4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAA -AOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAA -AACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgA -AAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4A -AQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADY -ESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAGWAPhgAABRxJREFU -AAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0B -AgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACw -I0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAA -AHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAA -AADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQA -AAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeA -AAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADs -CBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAA -gB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAA -AACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEA -AAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEg -AAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7 -AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAA -YEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAA -AADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAA -AAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQI -AAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCO -AAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA -2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAA -AAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAA -AAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQEC -AAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAj -QAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwE7v6RE3sWYf -3wAAAABJRU5ErkJggg== -" + xlink:href="data:image/png;base64,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 2yk9VwGI3wLdK978/P84eQDym0D2BtjbBwbL5L3apu+IP785zEP8N8ef4A/pS3Sxr6GVagAAAAZi S0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAAd0SU1FB+QGEwA2HBHwM98AACAA SURBVHja7NkxDcIAFABRihUSRgYGhLCgA11NcIADBgTgpEPxcf89Cbfecn+s+wFgoO10FgEY6fd6 igCM9Pm+RQBGul0vIgAjHSUAAAAAAABqDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAA AAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDH AAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAA AHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAA AAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcA AQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAA cgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA AAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwAB AAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAABy DBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAA ACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEA AAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIM EAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAA IMcAAQAAAAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAA AAAAcgwQAAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQ AAAAAAAgxwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAg xwABAAAAAAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAAAAAgxwABAAAA AAByDBAAAAAAACDHAAEAAAAAAHIMEAAAAAAAIMcAAQAAAAAAcgwQAAAA/u3ZgQwAAADAIH/re3yl EQAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AA AAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYE CAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADA jgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAA ANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAA AAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAA AAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0B AgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACw I0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAA AHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAA AADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQA AAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeA AAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADs CBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAA gB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAA AACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEA AAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEg AAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7 AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAA YEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAA AADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAA AAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQI AAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCO AAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA 2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAA AAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAA AAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQEC AAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAj QAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAA dgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAA AMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAA AAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AA AAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwI EAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACA HQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAA ALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAA AAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAA AAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsC BAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABg R4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAA AOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAA AACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgA AAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4A AQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADY ESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAGWAPhgAABRxJREFU AAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0B AgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACw I0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAA AHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAA AADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQA AAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeA AAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADs CBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAA gB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAA AACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEA AAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEg AAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7 AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAA YEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAA AADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAA AAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQI AAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAAAAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCO AAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQECAAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA 2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAjQAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAA AAA7AgQAAAAAANgRIAAAAAAAwI4AAQAAAAAAdgQIAAAAAACwI0AAAAAAAIAdAQIAAAAAAOwIEAAA AAAAYEeAAAAAAAAAOwIEAAAAAADYESAAAAAAAMCOAAEAAAAAAHYECAAAAAAAsCNAAAAAAACAHQEC AAAAAADsCBAAAAAAAGBHgAAAAAAAADsCBAAAAAAA2BEgAAAAAADAjgABAAAAAAB2BAgAAAAAALAj QAAAAAAAgB0BAgAAAAAA7AgQAAAAAABgR4AAAAAAAAA7AgQAAAAAANgRIAAAAAAAwE7v6RE3sWYf 3wAAAABJRU5ErkJggg== " id="image5427" x="-406.97867" y="196.76801" />++Episode 1 + id="tspan1224">Episode 3 JSON-LD to EDN + id="tspan1228">Factories and WebFinger diff --git a/repl_sessions/json_ld_stuff.clj b/repl_sessions/json_ld_stuff.clj index fb9a687..968662c 100644 --- a/repl_sessions/json_ld_stuff.clj +++ b/repl_sessions/json_ld_stuff.clj @@ -35,6 +35,8 @@ :http-client {:redirect-policy :normal} :as :json-string-keys})) +(json-fetch "https://toot.cat/users/plexus") + (def expand-context (memoize (fn diff --git a/repl_sessions/webfinger.clj b/repl_sessions/webfinger.clj index 55134a8..590e826 100644 --- a/repl_sessions/webfinger.clj +++ b/repl_sessions/webfinger.clj @@ -11,6 +11,28 @@ "https://toot.cat/@plexus" "http://toot.cat/users/plexus" "https://toot.cat/users/plexus" +"acct:plexus@toot.cat" + + +(for [resource ["acct:plexus@toot.cat" + "https://toot.cat/u/plexus" + "https://toot.cat/users/plexus"] + :let [origin (uri/uri "https://toot.cat")]] + (let [iri (uri/uri resource)] + (cond + (#{"http" "https"} (:scheme iri)) + (if (and (= (:scheme origin) (:scheme iri)) + (= (:host origin) (:host iri))) + (if-let [[_ _ u] (re-find #"^/(u|users)/([^/]+)$" (:path iri))] + {:domain (:host iri) + :username u})) + (#{"acct"} (:scheme iri)) + (let [[username domain] (str/split (:path iri) #"@")] + {:domain domain + :username username}) + ))) + +(into {} (uri/uri "acct://plexus@toot.cat")) ;; rel seems to be ignored diff --git a/resources/lambdaisland/souk/ActivityStreams.edn b/resources/lambdaisland/souk/ActivityStreams.edn index fd59e65..e01776d 100644 --- a/resources/lambdaisland/souk/ActivityStreams.edn +++ b/resources/lambdaisland/souk/ActivityStreams.edn @@ -1,6 +1,7 @@ {:activitystreams/Actor {:properties - [[:activitystreams/name text] + [[:souk/origin text] + [:activitystreams/name text] [:activitystreams/preferredUsername text] [:activitystreams/url rdf/iri] [:activitystreams/summary text] @@ -18,10 +19,11 @@ {:properties [[:activitystreams/summary text] [:activitystreams/content text] + [:activitystreams/published datetime] + [ :activitystreams/attributedTo rdf/iri] ]} #_ - {:rdf/type :activitystreams/Note, :rdf/id "https://plexus.osrx.chat/users/plexus/statuses/109495602955086656", :activitystreams/inReplyTo nil, diff --git a/resources/lambdaisland/souk/config.edn b/resources/lambdaisland/souk/config.edn index 094efc9..0fc283c 100644 --- a/resources/lambdaisland/souk/config.edn +++ b/resources/lambdaisland/souk/config.edn @@ -2,7 +2,7 @@ {:gx/component lambdaisland.souk.components.router/component :gx/props {:dev-router? #setting :dev/reload-routes? :storage/db (gx/ref :storage/db) - :instance/domain #setting :instance/domain}} + :instance/origin #setting :instance/origin}} :http/server {:gx/component lambdaisland.souk.components.jetty/component @@ -11,11 +11,11 @@ :storage/db {:gx/component lambdaisland.souk.components.db/component - :gx/props {:url #setting :jdbc/url + :gx/props {:url #setting :jdbc/url :schema (gx/ref :storage/schema)}} :storage/schema {:gx/component lambdaisland.souk.components.db-schema/component - :gx/props {:url #setting :jdbc/url + :gx/props {:url #setting :jdbc/url :admin-url #setting :jdbc/admin-url - :schemas [#resource "lambdaisland/souk/ActivityStreams.edn"]}}} + :schemas [#resource "lambdaisland/souk/ActivityStreams.edn"]}}} diff --git a/resources/lambdaisland/souk/settings-dev.edn b/resources/lambdaisland/souk/settings-dev.edn index 24a7682..d049bd4 100644 --- a/resources/lambdaisland/souk/settings-dev.edn +++ b/resources/lambdaisland/souk/settings-dev.edn @@ -1,4 +1,4 @@ {:dev/reload-routes? true - :jdbc/url "jdbc:pgsql://localhost:55432/souk?user=postgres" - :jdbc/admin-url "jdbc:pgsql://localhost:55432/postgres?user=postgres" - :instance/domain "dev.squid.casa"} + :jdbc/url "jdbc:pgsql://localhost:55432/souk?user=postgres" + :jdbc/admin-url "jdbc:pgsql://localhost:55432/postgres?user=postgres" + :instance/origin "https://dev.squid.casa"} diff --git a/src/lambdaisland/souk/activitypub.clj b/src/lambdaisland/souk/activitypub.clj index b638350..82dcb5e 100644 --- a/src/lambdaisland/souk/activitypub.clj +++ b/src/lambdaisland/souk/activitypub.clj @@ -1,6 +1,9 @@ (ns lambdaisland.souk.activitypub "Interact with ActivityPub instances" - (:require [lambdaisland.souk.json-ld :as ld])) + (:require + [clojure.string :as str] + [lambdaisland.souk.json-ld :as ld] + [lambdaisland.uri :as uri])) (def common-prefixes {"dcterms" "http://purl.org/dc/terms/" @@ -15,5 +18,61 @@ "rdfs" "http://www.w3.org/2000/01/rdf-schema#" "ostatus" "http://ostatus.org#"}) +(def default-context + ["https://www.w3.org/ns/activitystreams" + "https://w3id.org/security/v1" + {"identityKey" {"@type" "@id" "@id" "toot:identityKey"} + "EncryptedMessage" "toot:EncryptedMessage" + "Ed25519Key" "toot:Ed25519Key" + "devices" {"@type" "@id" "@id" "toot:devices"} + "manuallyApprovesFollowers" "as:manuallyApprovesFollowers" + "schema" "http://schema.org#" + "PropertyValue" "schema:PropertyValue" + "Curve25519Key" "toot:Curve25519Key" + "claim" {"@type" "@id" "@id" "toot:claim"} + "value" "schema:value" + "movedTo" {"@id" "as:movedTo" "@type" "@id"} + "discoverable" "toot:discoverable" + "messageType" "toot:messageType" + "messageFranking" "toot:messageFranking" + "cipherText" "toot:cipherText" + "toot" "http://joinmastodon.org/ns#" + "alsoKnownAs" {"@id" "as:alsoKnownAs" "@type" "@id"} + "featured" {"@id" "toot:featured" "@type" "@id"} + "featuredTags" {"@id" "toot:featuredTags" "@type" "@id"} + "Ed25519Signature" "toot:Ed25519Signature" + "focalPoint" {"@container" "@list" "@id" "toot:focalPoint"} + "fingerprintKey" {"@type" "@id" "@id" "toot:fingerprintKey"} + "Device" "toot:Device" + "publicKeyBase64" "toot:publicKeyBase64" + "deviceId" "toot:deviceId" + "suspended" "toot:suspended"}]) + (defn GET [url] (ld/internalize (ld/expand (:body (ld/json-get url))) common-prefixes)) + +(defn kw->iri [kw] + (if (string? kw) + kw + (let [prefix (namespace kw) + base (get common-prefixes prefix)] + (assert base (str "Base IRI not found for prefix: " prefix)) + (str base (name kw))))) + +(defn externalize [v] + (ld/externalize v default-context common-prefixes)) + +(defn parse-user-resource [origin resource] + (let [origin (uri/uri origin) + iri (uri/uri resource)] + (cond + (#{"http" "https"} (:scheme iri)) + (if (and (= (:scheme origin) (:scheme iri)) + (= (:host origin) (:host iri))) + (if-let [[_ _ u] (re-find #"^/(u|users)/([^/]+)$" (:path iri))] + {:domain (:host iri) + :username u})) + (#{"acct"} (:scheme iri)) + (let [[username domain] (str/split (:path iri) #"@")] + {:domain domain + :username username})))) diff --git a/src/lambdaisland/souk/components/db.clj b/src/lambdaisland/souk/components/db.clj index d4ff6e3..e891401 100644 --- a/src/lambdaisland/souk/components/db.clj +++ b/src/lambdaisland/souk/components/db.clj @@ -9,56 +9,15 @@ [lambdaisland.glogc :as log]) (:import (com.mchange.v2.c3p0 ComboPooledDataSource))) -(defn pg-coerce [val] - (cond - (instance? java.time.ZonedDateTime val) - (.toOffsetDateTime val) - :else - val)) - -(defn insert-sql [table entity props] - (into [(sql/sql 'insert-into table - (cons :rdf/props - (map key entity)) - 'values - (repeat (inc (count entity)) '?) - 'on-conflict [:raw "(\"rdf/id\")"] - 'do - 'update-set - (into [:commas] - (map (fn [[k]] - [k '= '?])) - entity))] - (cons - (json/encode props) - (concat - (map (comp pg-coerce val) entity) - (map (comp pg-coerce val) entity))))) - -(defn start! [{:keys [props schema]}] - (let [ds (doto (ComboPooledDataSource.) - (.setDriverClass "com.impossibl.postgres.jdbc.PGDriver") - (.setJdbcUrl (:url props)))] - (let [table-columns - (into {} - (with-open [con (jdbc/get-connection ds {})] - (let [md (.getMetaData con)] - (doall - (for [{:keys [pg_class/TABLE_NAME]} - (-> md - (.getTables nil nil nil (into-array ["TABLE" "VIEW"])) - (rs/datafiable-result-set ds {}))] - [(keyword TABLE_NAME) - (map (comp keyword :COLUMN_NAME) - (rs/datafiable-result-set (.getColumns md nil nil TABLE_NAME nil) ds {}))])))))] - {:schema table-columns - :ds ds}))) +(defn start! [{:keys [props]}] + {:schema (:schema props) + :ds (doto (ComboPooledDataSource.) + (.setDriverClass "com.impossibl.postgres.jdbc.PGDriver") + (.setJdbcUrl (:url props)))}) (defn stop! [{ds :value}] - #_(.close ds)) + ) -;; cpds.setUser("dbuser"); -;; cpds.setPassword("dbpassword"); (def component {:gx/start {:gx/processor #'start!} :gx/stop {:gx/processor #'stop!}}) diff --git a/src/lambdaisland/souk/components/db_schema.clj b/src/lambdaisland/souk/components/db_schema.clj index f184fbc..e4d2a4a 100644 --- a/src/lambdaisland/souk/components/db_schema.clj +++ b/src/lambdaisland/souk/components/db_schema.clj @@ -11,6 +11,7 @@ (def default-properties [[:rdf/id 'text 'primary-key] + [:rdf/type 'text] [:rdf/props 'jsonb 'default "{}"] [:meta/created-at 'timestamp-with-time-zone 'default [:fn 'now] 'not-null] [:meta/updated-at 'timestamp-with-time-zone]]) @@ -67,8 +68,7 @@ properties))]) (defn migrate-tables! [url schemas] - (doseq [schema schemas - [table {:keys [properties store-as]}] (aero/read-config schema) + (doseq [[table {:keys [properties store-as]}] schemas :when (not store-as)] (let [ds (jdbc/get-datasource url) table-cols (table-columns ds nil) @@ -84,7 +84,7 @@ (log/info :table/altered {:table table :new-props (map first new-props)})) (do (jdbc/execute! ds (create-table-sql table all-props)) - (jdbc/execute! ds [(sql/sql 'create-trigger :set-timestamp + (jdbc/execute! ds [(sql/sql 'create-trigger :set-timestamp 'before-update 'on table 'for-each-row @@ -103,8 +103,20 @@ (throw e)))) (let [ds (jdbc/get-datasource url)] (jdbc/execute! ds [set-ts-trigger-def]) - (migrate-tables! url schemas) - (table-columns ds))) + (let [schemas (apply merge (map aero/read-config schemas)) + _ (migrate-tables! url schemas)] + (into {} + (map (fn [[type {:keys [properties store-as]}]] + [type + (cond-> {:table (or store-as type) + :properties + (into {:rdf/id 'rdf/iri + :rdf/type 'rdf/iri} + (or properties + (get-in schemas [store-as :properties])))})])) + schemas)))) (def component {:gx/start {:gx/processor #'start!}}) + +(user/value :storage/schema) diff --git a/src/lambdaisland/souk/components/router.clj b/src/lambdaisland/souk/components/router.clj index 5b86ad5..ab97475 100644 --- a/src/lambdaisland/souk/components/router.clj +++ b/src/lambdaisland/souk/components/router.clj @@ -1,7 +1,10 @@ (ns lambdaisland.souk.components.router "Reitit routes and router" (:require + [lambdaisland.souk.activitypub :as activitypub] + [lambdaisland.souk.db :as db] [lambdaisland.souk.util.dev-router :as dev-router] + [lambdaisland.uri :as uri] [muuntaja.core :as muuntaja] [reitit.dev.pretty :as pretty] [reitit.ring :as reitit-ring] @@ -9,13 +12,60 @@ [reitit.ring.middleware.muuntaja :as reitit-muuntaja] [reitit.ring.middleware.parameters :as reitit-parameters])) +(defn db-conn [req] + (get-in req [:souk/ctx :storage/db])) + +(defn origin [req] + (get-in req [:souk/ctx :instance/origin])) + (defn routes [opts] [["/" {:get {:handler (fn [req] {:status 200 - :body "OK!"})}}]]) + :body "OK!"})}}] + ["/.well-known/webfinger" + {:get + {:handler + (fn [{:keys [query-params] :as req}] + (tap> req) + (let [{:strs [resource]} query-params + _ (tap> resource) + {:keys [domain username]} (doto (activitypub/parse-user-resource + (origin req) + resource) + tap>)] + (if-let [user (db/retrieve (db-conn req) + :activitystreams/Actor + (assoc (uri/uri (origin req)) + :path (str "/users/" username)) + )] + {:status 200 + :body + {:subject resource + :aliases [(:activitystreams/url user) + (:rdf/id user) + (str "acct:" domain "@" username)] + :links + [{:rel "http://webfinger.net/rel/profile-page" + :type "text/html" + :href (:activitystreams/url user)} + {:rel "self" + :type "application/activity+json" + :href (:rdf/id user)}]}} + {:status 404})))}}] + ["/users/:user-id" + {:get + {:handler + (fn [{:keys [path-params] :as req}] + {:status 200 + :body (activitypub/externalize + (db/retrieve + (db-conn req) + :activitystreams/Actor + (assoc (uri/uri (origin req)) + :path (str "/users/" (:user-id path-params)))))})}}]]) (defn wrap-request-context [handler ctx] (fn [req] diff --git a/src/lambdaisland/souk/db.clj b/src/lambdaisland/souk/db.clj index 0bb8c86..8da4626 100644 --- a/src/lambdaisland/souk/db.clj +++ b/src/lambdaisland/souk/db.clj @@ -1 +1,99 @@ -(ns lambdaisland.souk.db) +(ns lambdaisland.souk.db + (:require + [charred.api :as json] + [lambdaisland.souk.activitypub :as activitypub] + [lambdaisland.souk.sql :as sql] + [next.jdbc.result-set :as rs] + [next.jdbc :as jdbc])) + +(defn pg-coerce [val] + (cond + (instance? java.time.ZonedDateTime val) + (.toOffsetDateTime val) + :else + val)) + +(defn upsert-sql [table entity props] + (into [(sql/sql 'insert-into table + (cons :rdf/props + (map key entity)) + 'values + (repeat (inc (count entity)) '?) + 'on-conflict [:raw "(\"rdf/id\")"] + 'do + 'update-set + (into [:bare-list] + (map (fn [[k]] + [k '= '?])) + entity))] + (cons + (json/write-json-str props) + (concat + (map (comp pg-coerce val) entity) + (map (comp pg-coerce val) entity))))) + +(defn upsert! [{:keys [ds schema] :as conn} entity] + (let [rdf-type (:rdf/type entity) + {:keys [table properties]} (get schema rdf-type) + known-props (keys properties) + json-props (apply dissoc entity known-props) + _ + (assert table (str "Don't know how to store " + (if rdf-type rdf-type (str "entity " entity)))) + entity-props (into {} + (map (fn [[k v]] + [k + (let [type (get properties k)] + (case type + 'rdf/iri + (activitypub/kw->iri + (if (map? v) + (do + (upsert! conn v) + (:rdf/id v)) + v)) + v))])) + (select-keys entity known-props))] + (jdbc/execute! ds (upsert-sql table entity-props json-props)))) + +(defrecord MyMapResultSetBuilder [^java.sql.ResultSet rs rsmeta cols] + rs/RowBuilder + (->row [this] (transient {})) + (column-count [this] (count cols)) + (with-column [this row i] + (rs/with-column-value this row (nth cols (dec i)) + (if (= java.sql.Types/TIMESTAMP_WITH_TIMEZONE (.getColumnType rsmeta i)) + (.getObject rs ^Integer i ^Class java.time.OffsetDateTime) + (rs/read-column-by-index (.getObject rs ^Integer i) rsmeta i)))) + (with-column-value [this row col v] + (assoc! row col v)) + (row! [this row] (persistent! row)) + rs/ResultSetBuilder + (->rs [this] (transient [])) + (with-row [this mrs row] + (conj! mrs row)) + (rs! [this mrs] (persistent! mrs))) + +(defn my-builder + [rs opts] + (let [rsmeta (.getMetaData rs) + cols (rs/get-unqualified-column-names rsmeta opts)] + (->MyMapResultSetBuilder rs rsmeta cols))) + +(defn retrieve [{:keys [ds schema] :as conn} type iri] + (let [{:keys [table]} (get schema type)] + (let [{:rdf/keys [props] :as result} + (jdbc/execute-one! ds [(sql/sql 'select '* 'from table 'where :rdf/id '= '?) + (str iri)] + {:builder-fn my-builder})] + (when result + (merge (dissoc result :rdf/props) + (doto (json/read-json props :key-fn keyword) prn)))))) + +;; (upsert! +;; (user/value :storage/db) +;; p) + +;; p + +;; (retrieve (user/value :storage/db) :activitystreams/Actor "http://example.com/users/amber30") diff --git a/src/lambdaisland/souk/factories.clj b/src/lambdaisland/souk/factories.clj new file mode 100644 index 0000000..db1fc82 --- /dev/null +++ b/src/lambdaisland/souk/factories.clj @@ -0,0 +1,60 @@ +(ns lambdaisland.souk.factories + (:require + [clojure.string :as str] + [lambdaisland.facai :as f] + [lambdaisland.faker :as faker] + [lambdaisland.uri :as uri])) + +(defn fake [faker] + (fn [] + (faker/fake faker))) + +(def now #(java.time.Instant/now)) + +(def ^:dynamic *origin* "http://example.com") + +(defn local-uri [& parts] + (str (uri/join *origin* (str "/" (str/join "/" parts))))) + +(f/defactory Person + {:rdf/type :activitystreams/Person + :souk/origin (fn [] *origin*) + :activitystreams/name (fake #{[:simpsons :characters] [:tolkien :characters]}) + :activitystreams/summary (fake [:lorem :sentence]) + :activitystreams/published now} + + :after-build + (fn [ctx] + (f/update-result + ctx + (fn [{:activitystreams/keys [name] :as res}] + (let [username (str (str/lower-case (first (str/split name #" "))) + (rand-int 100))] + (assoc res + :rdf/id (local-uri "users" username) + :activitystreams/preferredUsername username + :activitystreams/url (local-uri "u" username) + :ldp/inbox (local-uri "users" username "inbox") + :activitystreams/outbox (local-uri "users" username "outbox"))))))) + +(f/defactory Note + {:rdf/id (local-uri "/notes/" (rand-int 999999999)) + :rdf/type :activitystreams/Note + :activitystreams/attributedTo Person + :activitystreams/content [:lorem :sentence]}) + +(binding [*origin* "https://dev.squid.casa"] + (Person)) + +(Note) + +(binding [*origin* "https://dev.squid.casa"] + (lambdaisland.souk.db/upsert! + (user/value :storage/db) + (Person) + )) + +@plexus@toot.cat +https://toot.cat/users/plexus +https://toot.cat/@plexus +acct:plexus@toot.cat diff --git a/src/lambdaisland/souk/json_ld.clj b/src/lambdaisland/souk/json_ld.clj index 8a5a8a0..eb65aec 100644 --- a/src/lambdaisland/souk/json_ld.clj +++ b/src/lambdaisland/souk/json_ld.clj @@ -142,6 +142,29 @@ :else v))) +(defn kw->iri [kw prefixes] + (if (keyword? kw) + (let [prefix (namespace kw) + base (get prefixes prefix)] + (if base + (str base (name kw)) + kw)) + kw)) + +(defn externalize [v context prefixes] + (let [iri->prop (into {} + (map (fn [[k v]] + [(get v "@id") k])) + (expand-context context)) + convert-val (fn [v] + (let [v (cond + (= :rdf/type v) "@type" + (= :rdf/id v) "@id" + :else v) + ?iri (kw->iri v prefixes)] + (get iri->prop ?iri ?iri)))] + (assoc (walk/postwalk convert-val v) "@context" context))) + ;; (compact ;; (expand (:body (json-get "https://toot.cat/users/plexus"))) ;; common-prefixes) diff --git a/stream-preview.png b/stream-preview.png index bc7e960..d3c7c78 100644 Binary files a/stream-preview.png and b/stream-preview.png differ diff --git a/stream-preview.svg b/stream-preview.svg index 759229e..d31de48 100644 --- a/stream-preview.svg +++ b/stream-preview.svg @@ -9,7 +9,7 @@ id="svg5" xml:space="preserve" sodipodi:docname="stream-preview.svg" - inkscape:version="1.2.1 (1:1.2.1+202210291243+9c6d41e410)" + inkscape:version="1.2.2 (1:1.2.2+202212051552+b0a8486541)" inkscape:export-filename="stream-preview.png" inkscape:export-xdpi="96" inkscape:export-ydpi="96" @@ -30,7 +30,7 @@ showgrid="false" inkscape:zoom="0.66331437" inkscape:cx="557.80489" - inkscape:cy="446.9977" + inkscape:cy="567.60417" inkscape:window-width="3840" inkscape:window-height="2083" inkscape:window-x="3840" @@ -38,6 +38,11 @@ inkscape:window-maximized="1" inkscape:current-layer="layer1" />++Implementing ActivityPub + id="tspan2086">Implementing ActivityPub in Clojurein ClojureLIVE + id="tspan2094">LIVESTARTING SOON