From dafb90a25abc9525145941f532f5a2fbd892994f Mon Sep 17 00:00:00 2001 From: Nicolas Sanchez Date: Thu, 9 Mar 2023 08:40:03 +0100 Subject: [PATCH 1/2] sqliteification... --- .vscode/launch.json | 64 ++++++++++++ Cargo.lock | 180 ++++++++++++++++++++++++++++++++++ Cargo.toml | 3 + db/db.sql | 5 + db/db.sqlite3 | Bin 0 -> 106496 bytes pages/BPCE-SI-Notes.md | 7 +- pages/Campagne Elocal.md | 14 +++ pages/bidouille.md | 13 +-- pages/dbtest.md | 1 + pages/enveloppes.md | 2 +- pages/forbearance.md | 1 + pages/notes.md | 5 +- pages/test.md | 3 +- src/commons.rs | 6 +- src/database.rs | 12 --- src/db.rs | 51 ++++++++++ src/lib.rs | 2 +- src/main.rs | 11 ++- src/page.rs | 86 ++++++++-------- static/cheezenotes.css | 18 ++-- static/cs.png | Bin 0 -> 10853 bytes static/modules/cheezenotes.js | 6 +- static/modules/md.js | 1 + 23 files changed, 397 insertions(+), 94 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 db/db.sql create mode 100644 db/db.sqlite3 create mode 100644 pages/Campagne Elocal.md create mode 100644 pages/dbtest.md delete mode 100644 src/database.rs create mode 100644 src/db.rs create mode 100644 static/cs.png diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..656e823 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,64 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in library 'cheezenotes'", + "cargo": { + "args": [ + "test", + "--no-run", + "--lib", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "lib" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'cheezenotes'", + "cargo": { + "args": [ + "build", + "--bin=cheezenotes", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'cheezenotes'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=cheezenotes", + "--package=cheezenotes" + ], + "filter": { + "name": "cheezenotes", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 8cbb0b7..4530c42 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,6 +143,23 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "actix-session" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da8b818ae1f11049a4d218975345fe8e56ce5a5f92c11f972abcff5ff80e87" +dependencies = [ + "actix-service", + "actix-utils", + "actix-web", + "anyhow", + "async-trait", + "derive_more", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "actix-utils" version = "3.0.1" @@ -212,6 +229,41 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.7.6" @@ -256,6 +308,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" + [[package]] name = "askama" version = "0.11.1" @@ -338,6 +396,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + [[package]] name = "base64" version = "0.21.0" @@ -440,6 +504,7 @@ name = "cheezenotes" version = "0.2.0" dependencies = [ "actix-files", + "actix-session", "actix-web", "askama", "askama_actix", @@ -447,6 +512,8 @@ dependencies = [ "git2", "lazy_static", "mongodb", + "r2d2", + "r2d2_sqlite", "regex", "rusqlite", "serde", @@ -468,6 +535,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "cipher" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.1.4" @@ -527,7 +604,14 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ + "aes-gcm", + "base64 0.20.0", + "hkdf", + "hmac", "percent-encoding", + "rand", + "sha2", + "subtle", "time 0.3.17", "version_check", ] @@ -563,9 +647,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core", "typenum", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "cxx" version = "1.0.91" @@ -857,6 +951,16 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "git2" version = "0.16.1" @@ -930,6 +1034,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1046,6 +1159,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "io-lifetimes" version = "1.0.5" @@ -1407,6 +1529,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1504,6 +1632,18 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "polyval" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1558,6 +1698,27 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot", + "scheduled-thread-pool", +] + +[[package]] +name = "r2d2_sqlite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034" +dependencies = [ + "r2d2", + "rusqlite", +] + [[package]] name = "rand" version = "0.8.5" @@ -1722,6 +1883,15 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +[[package]] +name = "scheduled-thread-pool" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +dependencies = [ + "parking_lot", +] + [[package]] name = "scopeguard" version = "1.1.0" @@ -2218,6 +2388,16 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +[[package]] +name = "universal-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.7.1" diff --git a/Cargo.toml b/Cargo.toml index cc38a69..fc5bc06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ clap = { version = "4.0.18", features = ["derive"] } actix-web = "4" actix-files = "0.6.2" +actix-session = { version = "0.7.2", features = ["cookie-session"] } askama = { version = "0.11.1", features = ["with-actix-web"] } askama_actix = "0.13.0" @@ -21,6 +22,8 @@ git2 = "0.16.0" regex = "1" +r2d2 = "0.8" +r2d2_sqlite = "0.21.0" rusqlite = {version = "0.28.0", features=["bundled"]} lazy_static = "1.4.0" diff --git a/db/db.sql b/db/db.sql new file mode 100644 index 0000000..13c5378 --- /dev/null +++ b/db/db.sql @@ -0,0 +1,5 @@ +create table pages ( + page_name text primary key, + page_text text, + active boolean default true not null +); \ No newline at end of file diff --git a/db/db.sqlite3 b/db/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..ab7acf59890a6b589c5df00ae3aea7ee37c23cdc GIT binary patch literal 106496 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

qJBpccT+zCL@Q5Kud{4tD`A7MD8Y&z%5M3 zp3qYLZ#8b;Hk&2Ig9~PgaUox_=v0cU44s$7kSIe$wh2a#0znElXHd3pHiqnF;u!8A z$?F#3BVQ%pCe|`o5Cjo2tO3fB*>@!<8G$g0<&*$eLy~5+%b69V^y>4+M#jH&c+_K0 zOhWbj9ZDB=wSq7_m(m~)2+Z~2V4jA;-=m0vO9N4XvJ=`Aq?`v}$u)w3+|R2?3hLTR z9FsB7gZk@T7+^4!rvyXNwoi!fLyZKxd4g_&wFnS(q=uV8R^5lQU39%s154FIXleHe z8o5|NHeN^{j|4azyl~O}8R_$|c?I6ucW?$Y+nj6Nw$ju*6wE%$dIk)26~v0o#*4(U zJD<0z2F4+vC=}bUsQzdICm_%aQ0R`S$_m%AGW0|DAsX4ND2Wd+Y;_UpS%uiGPMgYx zB(dx`cjM?~n{0{#hs%@^5IK4acQ?x5ok2k-#~C5QB2?RvMoc*H>8K_3p@naJqkY7Co?)&I#$=Jw~fA3SHmnk13BEy_i&}8Vb8fcSo z+j}0IQ%ajjJ-+H36vn1Da6)*Pw@zn%u_5)kbI@_*)W`j~dE%fh>$t5$=O!IA+fG&+ z?jPWNpPefwv4?{c;Ruv6R0duIMr=3G`Z&qKj_dZH+X_U`-rn|@KgSub_%{fW5`!bk z(bUe54r|)Pq)AsES&=GE%TPo}YfXj{CXgcIIbo-8Y`5{-&)aQii3KL*sR82>|0TCm zqzX`T!}I*fPfI}sF*r59n4lkxrU;94r4kyx&OmWM$7K$@Sn0s}jajf-uMnVkWFj-6 z!`9B=Y;-4g0<$esoCJZn16?ZL(5&x_6fa3ogdb}}WDvu}E-N#nNyh?27LgFiyH1Fo zX!F?`3bF>dA$(#Q*sbV++oceXr0q5q8YgY3;y|WcDS2Kg5^D{*Vdwfy>Kd{I)qyMW zE+T2r|Nrd3L%&*Bx&MDT_-B7h)&KuLE&H1v9UnRQo1>%47M06R>*9kZ7bkE?>O*Po z(3Vi(_&k0LF|aExJjy8atUC&Z7(Px!rN+2OlS#^AcCHGu z1!hFu13G&^WA8cT#?GiQ(zQ4gJ8ZVF;T!Se4CSm{nuk@|lkyw<#;#Q%d23;}VjO4O zkA7vyMY=x044Hn-@YI>JIx)^3l`O&pWo(OgNW^}_J_CeQupGz`5WhlSMF9mP)86tQ zxOl>V)~O^)UAM4D)4pRuFHve_F>e!XLkO#IB08sa`baG|F~WYJGY%Pb!&N>_4uzPJ zC^ejyeU@%k;th7A4(8K!C5-h2RXy!)$dq11jYXCTBAw#+LO=6h7!gBwL1LG5lsns~ zkcxj%6ij-|`%gG~)~`}#0&no30ELvGIoUJYQJ%d(hLr!Jv3J3h0i>n7TQLm~@<1IF zq!`$flU?cFz59~7veiTx4C`XQ=93*;&W4~2T(mJZq=$5221kBXg!E2@z$AHdVgzuM zCe75&7Lx=NOeTFa-N%$%D5==93Ze{1Ua@LDkw6m9w^6Mu_DI4Xkb!l@NtuyMs3$BV zFbtVrnc#%uneUVp=m@f(1K}b4=gZa3^pw4FtVkKlkBy%1GwUht$hdk4C>wg_?)^zr z3WI*>ek@KPw*`n2xz!9j;bTk)NH{xiohG6Axa>4uSmYJO3C24VQGrQ7LoL@u+p7tAB)nDJ#<3ZldP;%XX+|luE^OqpT z!VJpcNBUWB-~D5mUO2`%jH8;DLRNi(qrWyk&w}&ywV7duRDH8fg=fw2p$zJ`jB)f1ylk^EfRG@KG z2~I9rq3>|xXPklU!dS^5;rFW5T=%DGZN?FMd`$hq27HnuhYaWfSFi4j>HG4 zG!h~0$|Q00p-MchY&LG3lh$YI47#~lnanHCw~UWIlGA|jV&(4t&bjbtiDGC)TvUd_ z>=rekLy!=51cfMzVvm=g;Ge!AxVg?IBzsbC`|LVKOxs>i&oxs^@VX0(1d3PB9wk&8E6J zEGrXLaFNAKPs#{YnGzrnG?v6-Bp69Tr+i12PcIqPjI@NodjSpZ^ok;B-#!%_h%R+T zs5taxFG#;P=`XvtG+SAUbM3p|H{%vj1&C92wRSEcKZtb$66av$I3GoJoen`vYorF7 zXkQE+n*e|)9ofI-_CdJbTTM^^!B zsbrzv077bv%dps>4b3zeyO?|4S8{;ZA6%N42emG0G=d)J%Y4HfilxGW>TzS%VD|Ao z`hGk}PfljHbfXYc@*mO`+1V1R^#=fH4R5N{s8KNj7(^94NFs{^T9U+Gsd>RyiNoay z$9SECj8MgiLY8bu$8QV(@EUG$8ACr(eK{rnN&JT1;R0mwwi%j%C6DR;98-(G(hC5l zVunl*u@(TY-7*P33wbqhWV;+RR1VeFM2Zy8g_Q!uKBw4Cb^j*79`sKJ_=X1!EU1;qe~;!?yP)fSwxNHdkWg@5`MPCs4lQ)6=AB9_)%J6>S{ zQ(WOdkVwIfIP5@o?y@#^tkT2M7U3jD!CCUcH&K(^4KJrY&QZNfmPs9nW2M9p$_R); z+fp4fhE!$yrs*>Sl>+*{1t+mMkFr%dKVe(RMXbD>3=g!FEl)Hy3q)mwN+<~A%3{O< zD-@d*s}?|gC&cIJpVE_Tj0)@?FMxJ#CDdfIX_XyIWRi&M=R>=WaIS=zO0^IAzledE zV9(t*3bkIRsxnnscxafh%xi3sN?VytJf2P4heng*Bd-y`lpatZu^`=dQh@T!bg7nE z!7<_!9GvR&BmwGfAb|Nvdzy;k?@v%VVOiT%aRrh$IiqhYuW~}IeA+H_Dz6yn#Z5=jjo&dR@|H%mEIkU`x z@z?1JLZWJE*>0smO+xs`_jCec6f3E`lH0hpFs)Q@EJ5rqmy6@l0HbrsJL-6Ca4&a@;^1>>ACSbkS2Wnhk>h+lBaAk@i=!xfp% zag4D5{Lp_i?*^TMStw^(uF{y8w2GP|QkmNEL1`b|Tpoe33xPFg2_-39mdOJ=%{2>A zcfEoyiIs%vMk}z8Ue&a$jS4#I&@1#}L<8P%;d@jAct!VQPK zxow0ZshS#5X}I7|ghHP^k}vzx7M04TvS~W_LAQzuZ_aXj-dv5*j40%>*+m1QO~LWY z?{)!og0!!yaCVVghCHHb%IU+bZ6cBgB%5Q=RZ<5L?1Rt3M{#jV85GDr8QGfGg9 z>HD>Xbac+6&0IbZ4VBLuWrbEp(>nl8S?&t!Ci%wFuF~`ki}->I3`+}(ATq0QP&8SK zNF=PxMM;~Q7MS|rK(p|nkQ-MMGKh|Y+Y0{-COcgEz0img&qznpLUUuFYzmmmaY zJy>uxgq_NFUc-HlVq#vT2xZ$95D)DPE=DR?P$bN6cR3C$UGHEF`3lAG!V?z{PDb{b zNo|wK*s0vpuv-WgI@@7wRy*Qi=qbv#h$ND?HytiorV3ZVY2*D_Q9=cyEUXYkNH^ZS zeqn0lk?$PhHna8(Vwi^=LSSX@;>lB>Wq7jNm**D+1RWf#$tzk?eofJ`@=oYqCa_AY zlsLkb=6EP|CM7*M-U#o~AlSS;LkBSGmQIZk2>fGLhB`w-wle20aZwx|aU_l&*kt_lK{iLx&`I1RA3Mqh;qiv`PMZrDIA=6kt`ou;U9=68<2$B(egm{V2J`i znO>7i(MuOCYQx!U_8LW(C0r_x3Q+WW2@9{tT1xOA<~ zl_Ay2jiDSJqfvYv=?OPGK=!wXh3}M8Nsn7Nq(QDqmmmzA6!UJWWI3in8IU)QXcnDjzRHD?A;1X`{h?zV+tTMneYJdSw%PgeJ}~r-M}KXD8mq z%ZsU#Q4qCb141FYxp@$pnI}Ry>tOmu);32|WnLLH;$hEh7X5mvsiG!64BcnfZlbz~ z>}Q2RM3j|3C*oVF%99B;E2jk>3Fb#mu06*_X%B;D3kq{pCAkfTzRI%d-xPZ8cVL6K zKuzq_bh{ic4^G!WyTVSD3Kv|n2MmLgjY3lF!|m1^?aemHT`d_kqQC+H%*Dgyq#aiP zOzf5jl(PbxP?+liD@>ch4Xh`GoTS(4gj=1N;GP)LXNDWhHqn-N@I7`22+bK0pngPh z3OG1BqlQk7>4T2~JByga>=$)~y^D8dO9b5!`h%*`!U%vF#ZEGdN1Bb6LMTqoQmj4f z7scoq$|EA{hB6D6x5Pr*@64>M#6;gVKFPe`#yy;vL~2;xfI;##$J@demSj>P0K`J) zjhNHkEikEb#!87YGdJ*_v6|YlKQyWLsFByD&p>yPl*AH5*-!h)RO&z2=Q#JVvRdUnfaY9%m3fWx8^p#z0bz zBnd&`u_AzjoD3Fd>?j{5+s{fe&gQ-vGku!P%;7@8pI&DbLo%1Dr6%#xD?f93Wa{;U zqZe>Fdv*8hPZ`9*syb)JhQ$fz6L7!SxDTR-@Ih zh!Nq^LUG#wJkP2&jS7U_lndgjAlQ(jmR@}5d%-qNyL}mO4~8RTsIm9)!xkm|T$0Kd z+g7PjPL%_I6&Z(_P7KMUa0K>I0yX_e;w2pesSIsQkOl7uE8<#DIsmoh3+5+juabLmM&*>K z1jDFW@1iLN7m!%N9;u8f>XVIXLT4H!>u%sg*9|y2nYTP5P}1qGR$4g5gTdms4v6&~ z)d>1F$vT`g0jy`)SyoUi+Efe;wL);$F9TRuz+&b8B}%r)%Y>Mj*{lpC*kV*D6M2-o zw&fQ<$i)gPo4ph_C99UcHga<0^IyL*dLc-!phYx!aE6e1hoSmgZwzgYBMbit=s&D4 zduha!z?5N#jvq3)ker)O=AM3L?wO0TE6Mz&WM%g3#rc($c~CBWzx>?XWj&Zqo|%8{ z{IZY~9o9ZQKYMxMlHQe*x#t!xeunE~=4Q{&tJjP3&p&rroi8jdJo}t=I1|RZJij=f zoWDG~F!%KQ01jLI7Z3A-B&Co6b>apFzX@-n&tjlhO%m`n?xov{ai_Wxyn?h}X_j7p z>BPv)cNRv^GZ;8Q;6k<$!?$2q%gA`%#y1g}Ou8N!0S%(jIuVTmLE+085~9)5EeodM zRmjE&X2(A6MUR}rVIfdDo@QJMT4WyT=Yriop6cU%#K??3o)2IN(JE4bTw!%PU{uqC zXpqmT?z4D$hPF<*Y1neS+QmK5kZ-|94IF};{n)3UQ3_K@yrS5%M<|6xw!M9n&0r%s zOF)ddU7;K@!-td|oksLH;yPr`;LAeLIkojz?psCGd&6>ZS@}0Od*vr?nwQP>KEdfl zV2_>`RZVk3YeXv<3$?_yLNlD;Del6-Ei8c^MeSY9HOdLUh3aPJHKse%cn&FkPG(Jo z0=oY%?L1LHU+f_>g4`}L0j3qtjC1m$?HDQRmXBW$1vP6`4yQD)_z@ZHc|!pnDXh!N z&KK3UdKtGN31K(wkm(@SxCpmK)Q4GJ%++(dc+1@Jl`V{ZbyeBUP8v&l9zjnNQHg;H zflZC1hnqj{QB?ntpu!M9X%oMcuHsS{M9ebM#bW}eDgOoSe4xGxDRO%&7x;x@2dB&y zk%^$(frNd`OBsY=SY(W15Hw}`VqYzbRPlCZG>-Pr%!fq!w!_rQ0r+7Kvc2L!RYxJ{ z|35fT`0dfZc;LUg{}YFP@YARG?9X@~0)Go2@JjphBcJ@nGoy=jYLyaiJKS5EzC{{1 z2c^J&(!ehpK7nL6P^)zL1FTIX!#w3~)-*jO@Pr|{$P{XFCicVLXHvgLH1wM6MGu)M z8r-KeFfSuY9mF$)73BGTF2G=z^>|M^K>1{TQh5=4mQP%v3e97?fid37X{7o8iLD1uAOEaWI* z+vK{zzTq6fUVP9UE|j{iXz+ zh0K&Us1;mEPOAuU>1*dcH*)RO)1!;Tk%4bE25N(erlD7De2xh{$K8sKxW-snP} z^BUJHEQ#)Emk;rXWR70%Hg9#XECJ#j^0hB~E!ufc!c8j$S?>y-Agn&fa5fx8%eE2= z#Uj%J2}9Nu+q5W2WHs%CIg&O(hMT2VMxGjZ^tD@TBQC`{+ccDNy!A%*o{h+UfsEk% z#of@U-ZB@0vf?d@vqZa~@=ItU#+oe6bP!gymj!V$oE5;2UaLr`Qzvt@1>wX5AMG>6 z40LL7oY*xoQF%#?9pUs2TC~{c*fcer3<<8%df3U^7I5ZuA%hFWbDI_UjkjBO?(|VB z6F%MKkXDXX6bW_^vx;U=$Qvm2(iN2)0%eqliOB4gdyx9s)IODv*;|$iW+-F{>j(ZO z(+PsCjH5c&g-&bd?hi$NUY`8y$kDGZj{XAGahmNl1kg@xcrmuV7HqO@zZcxa#%A9Q zIiM(qS-|7q5#;x<>-=<%s=@tEYC|kUaSvb1!TOtD{>;cD|DYHrJxm);!gQJFlCaR! zPC2t(*8*HO!ivWXOL^~6RJLEo;RvCGAsHGmnE;K!%$L#*d3A@ec76Lsy`wG&9oVFdfXwroP5)BtkD!OF zcq!J{H){=VyzXs%0Sfg3Er`0v?OPyF>s(V|5i;PRw?lcUS7FIgV3`-?=1c|4QpNG6 z=Jj_s`o)Flt8h+&c^I0C%^FS74TRP&Ei4cTcdC5p+@Xc-o$vbRU>CRr{;D}}7ck)h zE<+pzYj#DeV!91?IheEA+cW;W>KElD8R~RLvbD*(w|13br`{ z?3|c39$=gvUs4T1BqMdWU}y?dw>y?3CeVpgSskv_KB^Q5EYMg36c;8pc`ydMBCqmd z^2k`~fy^QvP9;Qf11m7_3bbRy|6B3QID7_bBM7I(TG4HZft>W@Y;b0-BM41$taU zY9E;9Y=+VY(3$wNw&+|;UJ$znl6EBoNE*5_rr}Wt(JF(f-w0&9ETeSzJzqF*=-|}@ z4}Rml>j$s$!~UOl4+1Y=pBwqu*G`VESE+1Lz2YXEt7B)E=H`pb3&l$mrxjC4E>!F1 z+D1GVTDq{g>C%+2OfiNs&OY(PQl)yM2u(io#1s5pOz5;!ZPqLR#QG;KueH71ZZ}JH zn%ku)VB@i&&1J3jS-peC*VLL~-b%6?Y<}Rt{YQ`f!}4g~ny%Q&u8y_h0`2!CE?j){ ztv62l0DjR}Q>{1J&KPUVb;9~x_($_BHoLV#qg*G-~mm6n9)?Kz#r z;FIuO#>LCOT-9AikAfrs0h8PHYL-5hdoMEhY)b)tz+wTXE?^<<&zEZ?O4+Wa<3Y{2 z*@u`ei9*bU(V(U2>oasZg|0X=ae8uUdUEEJ=GX>0qRHELe@EIV?Kc~US_YU43oFr< z4oBRAc)O%b192ph^`Me4?(P=03d#BgzAx4*t>WB9r6b6kt>4xqc1Gg$yGe1`HV_A` zt07frN=g-lSZ!d)Aq}zju1j&WUTvjc#GXz&=;oz!%ThT!tBh+oC&nkp;Fy@4qJ5fM zgDp7jSu`F?u%S%OhL()6xz4!T$xQ?)!&;+F_+;GIe=xkyJw#gdDs#)wz~$VcRS9>PE{W z%HMk9iXZ%|V-ozXEZ%ydax2*>Umdfv&?PGO)=QOJ#htRhPWKNy)X7_KZ0DNBx5cf^ zO>2LdL_p@GWVXxm%PWa>pM3x&39o$^6RC|l6rM<~sBpWG7Xyfjm10#u1UrAR4MJSC z(s#T(-_)r8sM#10k$Qqq*bIS#r!Q`)wp-{wM z?B(*(%GELcvR`zj(bnRjzB)!cp&xRcaf1zhKEq;a9cZ`axGqq|29tR%Nv$-shq&D@ zLf))!;FUSCjOsRPlo3fk6~ngL?#wyC;;sLXy`-0A5^EcQI%ur(^?Gd;rjtybjOXF% zSVbFCTnn#?lP8N4<)V&?P2_ANSfBL$YW#&+zWT{o?z^PKzLlB_T3!qb*t0N5C_p=` zIlA5g!Z?&KBL_qqDHkvvk{G=)L~Gk4K#5CIUH(nVr=^{-is%Y;RJY66}{2Jx;n|`CLtXm>Evyu3|%uONVl^m0Qjb@y(hdQMo_!gof}| zbKAkyux7D3{lkFa6X>NDAkJYKTOsedE@jMUY*>Vd36CK4eLl^oX-bw}QvOm3rnp$C zADl_qWz(TZ1s`f8v`FJHTVnu7`=ar|MU2Unvg(=ME0Z`ICx@IuF<#&P!pPC@JUjX) z-&JlVFJuZDYVGK25p5nPbe~8a>pp%#&hkKoyS+05w3TSDk|p5Q(J-GYmaJ*$9Kb^< z&Sxg>Jcgf>TqHd$#c$8SGykQn!2(Qu+UAPyg|VnGJR32*={;MW>r zhin=m<_OX$c4ojP86H4fut}6b0R@Z{ zgYnsa%#K1P^M^}sR7IB<;s#n7&CrKM0aClrZQRU|fT?4dm2OVgf}ELr>@LJqKeY2_ zjs?UDFX^g&1t^K1;6un*s;r_}63T>Wa*3kP?wU^V&0-WJ&go4ppmp?+u#l|kJoE5~ zP-Yh+^lw`r+GJUw_@*)U*ZN=%inowtte^ee5ZH&n zJ_Pn5un&R10SLVM(mC#Bd3JQr1iiP*ESjxli&*KPA)1#0-%hP(_ENjwS-KV`0>YKB zLoeSlPXWrEJ3)DgQ$xBVD!tj3Y8047Ya6?*!h@8RK-E)KF04ay+nr{y-rZsxsZZEd zQ5D@=gPP9Z+$$HIJ^n!UBDbTVt5Z+ObZsol&o}BXsf?98U`w4g{ur+uz-*!?;d-}I z{W2@zT?s4hTIt2^bt$SA3?}1*dy`0=GL=}$aWs|4EiEF=6Z7GtvB9!10&J( z(wBQ%HC$^Y><-D!F^S+JF?V(6+}S5y1dyigr)0*qzy5*$s%R*0U#+lmY0rEUWk1NQS$)r<*6891@W;AJ~=V&c@qxDP)b_Ga8%C)c=tq_nZU z*$nWgkQ8_K_t*}sJ7~y?;`Fr;JtS+#^;x-)u)LdNjrw`lZlCm6I11h#0F@r$tQO0wkR1@DL^gQ|@z@FJ6yd1rQm$Hrn0oGgC~)z5}-B>Z`qVMf%|y=_W4$j`m9!K4k;0 zCFhB$106AE1V4aG7spZ{kyFT(Aab_F? zer}_!%gak-D_lR!={|VyUmf88`+t6FA@Gk+&X1h@!wVVx%=_i;K}2ISIhliVPj^Zu z7m1lF^TXrG-2Ck6a`D{q+|uIH#igP=>rdlt!UqQ-eP&A@)hp&k-Co1#6wsWX??nSn zi3ZSS9H*iEcMYfF_&XSB)$0xsn`&vOMzILY{2b8`P>E=~w?kWN&?lL7l?IlwW*zUf zUzR;&l(`CY9l}qh6}C9)j?2XR6J6KP5#?=)3w(ZJvNTyNpD0b7)>BdDAAOzk=Zmxa zch)wIpUx_h;c{=)T+r|8`tCVWeqDdPjq4lcq6I*lZ*W01RE7Xn}kLPQT@!tIfy--|stkZH9;Hu`W zd{?&UUh5h@?2zT1)rpdbhSNq4gfq$3s`+J2viT7S%GuL1#dEU@7cYJ(5Xf_ikH59B zvH6o)@ZKX1S?iBSJ#s_%R{ElrRkpGE?oj<9J9+O>-<8D~Z<~zFV2(&U{)>o1oICXp z=B>86M8o}4Hvw(7@2 z%>l^yVt&Gid9N|w{iWqVcOG4n&^T#1f1_L0KW=`BKQ<4ylQ%VR@&cn^6Z=Qhe*T0J z^j<^1D+`wNyf8CUytFVszr65tBr+Ej8P@B}yHdPN0#Bz=Y5s%}_(z?`y9R)B6DNz8 z7nc^#MWnt=NshUn)Yc9kEx(xO|9VpO?g7v)cItCm?~cYWgeUGj;=8dd>HqH;{p^8< zer5Ethd%UEs{rp$d>;buCIt4A8upVK_LCa+lN$Du8hR80Bu8RDsll#b>`!X=!iABe zzup+dA)~Yv&rI3d+O9ZXWw$8ow7r$jaIusY+1*pGCcUUoVMR%1%AoG)>NK~ncX734 z&q`~h)z$TJB{y})cW^H1r;;3$?bhe@^Fr+@YNX7ZBBSB-%rR_ue$S>Q$nP^VF=T;VEUYBW1p35b_AE>UI_3#0dz>W*p8t0zIiZ(wreQIKo zCkldQ20YrCoSG=}ge$l4T!j?Iq{JTvy`~hJYnN>v_3dkVG9UWoCbl&uO2j;4J7^1w zluNszz+B>6n@5#&r`hhP6q)%~aiUTKLFt59QV2H{DMfEuEoUql3Lgg9mdWz1kk`MY z0AsWHdj<@8nUz;>aMuDlD{CY$8*i%ujdyt!Q1PCo>_(jRwY1l3=jN_WoV+$Md2Mp4 zl&kZq{AVmlswR@i9(J%#^3NYy{-uGk4r-Lj`yu#6vcg=W6Bc zq4MMi)7+_>OWVQ~doSM({@od&XPUo7ZIf!VwLQL59=D3)^EU}bu7gCxLU+2a{_^>e zr@r+}>bS}cWFzl=n$o%F6V0?t&+-O97C0abdW=R=(;rc-Qx=p1Da8FBN zGAnPZ6hd6q26798kKH9_3dQ1EZ(JYWI>Y<&Q#Q#`I%^VgEhBXNtb3|BlI%XogoI*~ z+*<5@rAcC4?zihda(8mvk9UQ;y5_>F=;PJzVlGk7Ltk76EN{JWc_7`;z|$>U%mNP- z+D>LXLGXmWlPB1!-|S^hJ^SrmTaR0>JZ`Oo0J`pvg<8o{yoFGw;D_rjtjx`W3yxYm z4LF#CO76!ZcLQ&amrE>r9B+LLbdaaK*ca`fcGpY9I)LaDW}sAsj!udLvz}rr2fOkT ziwi4Ub>p6M%M0?n{pf#lYNCq0VRCloC+;)LM9_0{DH5Qc2Wo{RC!ohjF-9XPmUY;P;nJCx zLb%B1uB!?LffG!kxO{1LY5D1AR*qTyzxN#Y%L5PokNowg2cEd667?sKe)aLuEG2T! z!zl-H%$qD+xd+=~(@5&LH9o(zFgJI0{CtDz(Yh1l$>NiQ(X_f=hvCUy>q$$iezMYg zlJpQ#o^BYFSe<`+jE{lT@-ECY1!_Va0$sL0Ah z8S6V`Hb}CuynIs5U`!3#kQ?8D!G&Buz#HHD)eRIli5-bo&Ze1oFfB@sv~H2GhfE+= z8?#dRQMHa?MEu~jXY{E~6{cVlAh`Pxo(CyS*1KG13&&Obk>?ew;x8=CrDQjEceRSYMY_o|_2?Uo6cMegI$ylM2SdWzf*mEn!Pn$x~_qKj|12d&m~|S~{apmB|w^5&j)< zggp5B2vR)mY!|qeKX0rGb%sd5MxY{8D3aoU&gi_*aygAk>lo@DEmejw+}03nrTPWs zC*O+dCQookyOmpzB05VG!o?o)+yS9HNl9UtbfAckOo}|xobQ_vnklXIv|mWH_#MQ8 zNgK(qEb>rqfPhUqG)@yDzxIJB}Z;tk> zQqCU4F~?Z)6ALH%xZ)>c|P=`vx>rsNsEi!j_<;WXDhZ zvK~rg0;nhj!4(mIqFF@8f$P6HZAkGuQ_7xC&)&r3IRCezEKg9XVv8yd_}tQjDKVtlWkAf^XkS_9aT9xXAu&nC4c9@K>zU*+NT6C* ziAb(L_WB1FM#_JGWOR3Zl)XjZVHH*iS0sBQB>I@qmfwOJHPD7{!&|9p!=22a_@^-l-o<*DbVKFw)XG=AqP`_cfr zkky6K>62z6lM^%$A?G$vRMV%)lU765of4GlZ@$pjE)vMPCb4}JyA)e48=mgNJ4->R zZo`I<)ynD=g&6WP1ZuBUAWpf+b0OJE`v%F@i09%i!jLv)l{~7fwNtyeRGXju;-%W^ z;>I(lzF3?4(#ffv?X%UFDtv(gPw@el!1P)A-PvmSxy4rJ#ZzljH`eB!JvFyEyFIb< z%;Iw=tNM=20JE)4RA)|{I(52QEZ54l;uIFXVx@YjUaU{oPoFw@Vrq4wZpZL~T?i2B zFm2m(KZg;c+Uqov;*F$OOCD1xrR{6Fn)WFdu&*&S18=3-eJuGhi2;0(6rWBWQ*b>R z{cRInfmo&6sOsQc(tpb7F1X+LE-8U42;d>i_6bka#GW+81ILMTJ=X= zbPZ*Njnf{s(#2rVNIt8pQ1}zdsz5-g)^ee5ZH&nPaXm<|MJSn zlV7Wh2JbB{d8jN(qRyl|NtwC;H6Zc4!^CGZX( zpmW{v1h_lN#L1cRiSmil6L+{g`c!#(;^fH_cXqX!nJD8#DxaFXgOWB`o}4~CJu|G; zL>VXJ%qd#&&*b!}nXJUFmGI55;|Fh-)k?T zUGw`amlkp{&&A3H>alf5LLD+`6}zK)sKBN1f6KIIi2_KXH*ZO!;(=7QAYC;zoYkvb z#Jh!c0^P-Gx6W-K&cleg=Z{EF?5Af`=X|@Zs+81@dM+ED@Y;zUc zrux!z;5VlT)a_e*d>$!K1(LetKpL=kd#=9I-s+;TUo?XPvT~@lXdpE;$_~bt&~?n^_1* zzj*Q7I4@DFR#oj5AE-*fSp&=`O+IOTCs9dA7xZm4OY(`clw#&{4n-cRlg$@g5XTKJW+j$9DZji_a3Lne z6nCU&T)_E<5YCf}+}S5RX7)y<+0%TM<`&fuYs?l2#FVj{qZ}4B67AjMBL6&YqPv+2 zqO1y7&!IU{&@@?o?h=!@vb?ZTJbUgO`Lmfb$5npqE|qjGE2P+JzeL9JCf2mg(s~nR z4XHG~3`*fO{=FuB@0x-YO11Xqcb+PLx_gV<>dxl1M(wGI`qb2^skJHem)i79d7^ge z)QRb-soJU4)zzt)`suW7v(dV7&0QoMY}?d6YO9QmntM~*Gscl0x(eN|ugV0kZZKQr=y zuhmB>9lJ*hOlG{qIxvR=IMQ?u@5EI3#K{@Tw8mGtXdT%3L}9)Py;WsF_q_^9;lpVF zN2qemJtm>}zfmDKrdxbaOigz?248b?VRZvrNW^_^r;x_0n{M6mFZ##fAjf@fgUY?~ z>m9{CAQ`1QzS^s;!=38e)zY!jSMR$t^7z+!qq#D=doMp1qo(4Asdt}Iy+k%PwbV7o zL*3<|ItIA7_@PHBMy7xdAQ#ZIL}}~k(}JAyNQdX?Q`1EYa~c|MLG(fx+cIu3&=)`V zL}u5ADB#~@_(%ytEnmQeheY;!-i zErE3qt5rTRefYiq^?^eNP8>M&hlgI}pLh7@)x{S^9{<(@qY^gTMF>4t3JunLS9xB@ zoQ}D2Tg0eH$@b#0iZ?S`sn=%}G*rJ?D8asKM`Q`M0*|tg@*0S834&43Dpf!UY*Wov z+s({Hf+VI|;%cvo5%R7wEIuRvaOFCqU(eVVNDrV(jrO?zG|p?U|9oB1b2p1G)mQJ; zJZ*H0&63N8_Tq!SF3d9FE=Y@>yk6dj1A+EZn)?a5CLI5K*q#wq-&`Jpma(1oM!~ikF&5B z8aEme{%%m=f`vTSqG|I0^QNV$iX+kU&azvOqBF#NF zSMPno>bG8_q)LVg?EFS=)g+hrcHDpP?MSf|X@e5$Z`#eO20pN|W>-Fm)IB{rfZX}! zsdu8Aep5RNmZ<1)sW9>UeV<$&O$%o4eYVpA+uwZub0eSsjqd24^|<%$BdzNlE&|BP zd+V&up;%D_rCykIFD^SGFB1a07{mFBnI@kns1GW_h1S%gX6dz~-WPZD${VB-t~IdB zLp9CVsOSbOtmLFPpz7E2ocvJ&WJ1iqXr#Lq&3QRoe%h;T?Hjj}_(>h~})O>Lo4|&}(ED z761_dPU$s6eq)2K^d+o={{Xq}_Ter9QE@6D)x#xo1gk23MqARkwY>q!<(qDb+y`F* zz~Q!fNkQvW&@iDup4bo|V589o9)Emp8j0_zr~+0nl9n&=g*Wnc292L0$Vc0&FDiIw z%_4$;ORLhnWnNA}gfG+32RM*A@(2vk3wF+MlfR6ga*Y%{sah99q!)@vEmhDBpL2o~ zCegu;BBi%eI&k2D>3uWWz8P)bjJ9t^gU#=o(e}+~5~1AWyl+MuYDPPJ|G@+Aeb1jB zc<9FHpFi*$_y76Gw+{V_Lzmz4r##yKvk!rv76`oj-s>Zee05|LdAWzH?8<^}W4k(L zl|^y0B(wfp3htnxiYHusPS6bDY+T!+AC48cip(=LUC=hc)HUIp5G?_AZlhkmT@SV| zH9l6qHgfFc@~9j&Xe{;C8Zz^4>)6G<*P7RS6Lk=Jb)NPz&MQ)NvvT+Mq|zWC>*Bj7 zF1IVxEjw4)Xg=|^XaDZVCtv#j#^Y9_xZZBA4Xz8dc*!XYNef z50hu^@PB^h|7tM##1nTW?@aOE40yX+KTd z^O^8mZ>ITXhX2&h37)I%Nqeeqy!}aQe}doq-88M#{**nRW@PoEdHJ}fc|OH6%~Ss? z^Pk$6C+vkLs)5Va$X>8?9(X@9HXk3ktR-to>f9&lQ!Q)Flf2SPjWm77hFEEn^Pz7} z-8soi{!gd=e>ymQr*n1W(U+G;@e(Us5m(->J4oMm6kA`c%zl2Yj0!>ntYp z+?XW>W;Dai-d?2LWR*mU@{p%UdGSl6>{rO6{VDQo^826a>KSGT(LN>`e4)F#?p;+~ z^*{e}j>hb+oa<;Bcr4pog8`ek(1oB0F2O<7=1&HJ!8wmclf_+`$*V6Wi<`|84WYtx zg&RxE-E1Wh8_|U)oCxcI-XD?Njb2)Iqi)Y`^m4MBcJfWMH}c81PtyiEtZ$%cPYnXJ zCW#&i2GC|=m5;s9gSl_?#8lf3KTtA_EELtb7K0lp2I*z9T_aq;ij)NrCFCs`@c&}a z__B4-IxMzoZ!eEm=BqDujxL|SZG67*=Hchd%SVNy-DidQmFbh_?>4>|Dg5CwtuXKa z2)h$t4^%r9Y;tjQqp zt@)g`PMk?-nTZCx6Bds?VF;oE&@TT;p4!<9sve=|#wvpnaDO3YZ@O9wZht^&z6BQX zr2Lx74>YcEdfsY4sesc9tpF_(A^TZ0QBi|(?SfizC5WD-@XOb-Se@NR=aqAK`9}FLuh6DcKY9{ICLC2)#hKU=G@jHS(-p52g@^Oz|qG0Q!Uj zMpBK7YEzac)RrRv%;V5yV$ZUM2hQO4cOU<1^+gokpf-sxmRrhVQyJ8$93tSu2=xmF9V z7UmA-X2VuBOtTDmn?ET2N#~-PB^VqV)oRF0Zd`_!6hmntzbL9Wb4QxV$ve~NW1aa| z?Y7!+y6TL{m)*GeDdd?W&=^PbYMk;pQ6c27w?@mnappxpS1yr zor^Gm>q@C;04_WHSBeB}>7h}3IolJ&D!;@m3(PS|siB*knZSS;Qc8n*h2}W#VlNfi zbqj@b)QQ@iDOc7M6M{XSzcT{Q9@37(Iy*EbXE)tIWqV>x*jKWGM(t5k>b=_O*%z`S zLQjL89xIekbLqo4XVc{EqV%EBu)W91HI@fc;yNDN+A&eap5$G3RYn`t(bX$y3Zu5N z#|KO8qF9!bZaU=>BKi@yny%-_OYh6{N3%UK;RZwb7-|u(|EplEJQhV`Z^u}^#!9;U zVl4RD7H+ef;o?l|!6W~Gk>62xF3_Tvd-W=pb16Wbftr=;xGNxW#y2J=(=5+0)Ia!` zOq69emhAZ}S}vCht^*~yw(Fi!UL9yjwOGG!6}@&I$B8)e2ch*@YjNt);CI<2Rp0JxP9USE#blH_VPL(BILFcmW4~P zEr~COrcNR>hl3!yi}lUz7rQ&OL?`}4)c5rAv+a_*ArGDMiMZppcA0W7!kZa4pgaEsTV2pjlC`e zInh=`PB#%g)ev1n7S^O82-~2W5xOVrLo?S{#sN|*T-B91Y%O>Y;)al^Wb(~(xJ*I3 zy0gq#%CRBTa~y7Omgp=$Q1^(Jl(p4U4&(%x0|=XQ?SpG5l#4zC_kr1j+i6+}zoWO} zxPzi1#(#S#6@FwPak?BcLv00ujg-unBZzxM&NS%43D*bVVPa{^!P!wG$g&Oko@Ajr#2%~2Iy zWeBgJVrhk0xX?xDpkPow<9h3L@I)BdVw}&THbTlcS@f5Qp2R+*IPq6ng5rY%#XmTR z6MyA`U9k#IuPpfb8r={E-t~2ybg%7E-W8Wd=Z=Em=YmU#< z#qA5SOyf9qL(r%9{|W2~t;Df>sRW9KeC&b!z&f>LaBk;R*g)z12GB zJdNc$snh6j76z2g37qnsCbpv{rprVWYyp00bYy)???7J{=@_dQq>97%0mCm(`vvaA zlW`P`L*i;tSK$L%X&5UiULOH!Z|1aEE*&a?|0xEc%U%pV+*%27x4e~9l~o?DMtJB7 zgGtclyW&U_Nq_E)RP5;=K2Odt6ofQ7sl)&>5ZNITef{NV#c5z~x;r~^bOTFyX(0}i zIdyik=!c$fK_uIara8cv%jz$?d0ob5Z}4rg)mz=zX}`H&WJFf(`_aw*wgjUX@U)@e zSf*+6Vnl&i`GIbUSQrc?T%&K-Sx&iP5jTOy;x_9nJVjRb58pPBgJ|)0_9?h9ncM=5 z){Y+d@NEh0<`mi!Xo5o|9(}<(Cc2xQ?F-&C*-|G-ADI8Yd;j`~zr&wl4-9)?*aO2J z81}%h2ZlW`?1BH~9{AHQYa?TSE!;~rp~6ieT?67)3k}B8NW#?Kzw<5zLx2zTJHv|^ z6#Cm3QUHToH`%J&w1=NMF&Uy&j%*vN>+&G{S$pN-Qt^TPUMq4MBA_t8yuLI&%}GS= zgUzy={yPH$Sm8+1KB~Zu$>%viUcCuxRV)TnBeNQTGVWm;)0JkI!Ks6$GF;AVW)Yf$ zlW-sCPiB=uM=@FZPYtOIeb@|r*Z>|t1(m*#%>LVG**S*;1ouqJcQzU$MwrPGoQ$1w z*$v%eFdisjrVM8m@#^wLZ`1-|!|2dfUkj7eAUpx8H8?>QL^xc6F@a%7YxEz&5HabN z5l0N3+?67sfKLO9oRJg3EkG|`S8#tkwV)C@Ukn!o_xKjy-91tL(-0rq7QbJU(6a9) zkO~!51{ZO~7`$$)gH(gJ0mKAw_bRmoYa3VrJl!7`+RH=dqr;SJty6(}AX|Wspx6x% zzCUi=Xmj3&S!662IlVO46PXE2Y>`r|bSd{uqtb4>M&YJ?Mj`O!E4`_6&8PE4-p&fkMo}^n9%|HiiJ^0rl`XW6AjikYt2*i+@u3% z{+hjjE0u5Q9eTt`mNWL20m8tgXd``i!^V-loz$QcPn~5aZvx74aV9pLR;u#yimE|Z la~H9Q3^s&^^?D8Q!|QNn9*Ym5#A=pBrZ=qgnVvDV{5Rq{NgV(H literal 0 HcmV?d00001 diff --git a/pages/BPCE-SI-Notes.md b/pages/BPCE-SI-Notes.md index 9d9efd2..5bd4a74 100644 --- a/pages/BPCE-SI-Notes.md +++ b/pages/BPCE-SI-Notes.md @@ -1,12 +1,14 @@ [Notes](notes) # Notes (BPCE-SI) ## A faire +- tiers-v2/corporateInformation -> identifiantLEI -> QrD5B3, QrD5F3, QrD17CIB00 +- Gce.SirenSiretNonDistrib : **proxy-dc.sec.bpce-it.fr** +- Récupération des bilans dans les différents clients (évolution bilans). - Voir les versions de .Net qu'on peut installer sur les serveurs batch PMM. - Millesime 2022 liasse 2033 valeur 111 sur page A à renommer 111A - Sujet Anaïs : Immatriculation avec données manquantes en base de données : 11315 509234258 - Modifier tâche de migration GIT avec les applis à migrer durant le sprint - Voir Jean-Charles Bezard pour les grands clients nationnaux en fonction du grappage -- INC00100347 - Voir avec Julien la NDS semaine du 20/01/2023 - Regarder si on peut appareiller fichier index et xml dans SurveillanceSiren. - Batch pour récupérer les siren confidentiels : tout le stock ou les mises à jour selon paramètre d'exécution. @@ -25,11 +27,12 @@ * [Forbearance](forbearance) * [SPT](SPT) * [Millésime 2022](millesime2022) +## Fonctionnel +- [Campagne Elocal]() ## Listes - [Contacts](contacts-bpce-si) - [Clients](clients-bpce-si) ## Suivi Anaïs -- [Feedback 27/01/2023](anais-feedback-27-01-2023)## Suivi Anaïs - [Feedback 27/01/2023](anais-feedback-27-01-2023) ## Bidouille - [bidouille]() \ No newline at end of file diff --git a/pages/Campagne Elocal.md b/pages/Campagne Elocal.md new file mode 100644 index 0000000..9a3c67e --- /dev/null +++ b/pages/Campagne Elocal.md @@ -0,0 +1,14 @@ +[retour](BPCE-SI-Notes) +# CampagnesElocal +## Calendrier2023 +|||campagne 1|campagne 2|campagne 3|campagne 4| +|Batchs concernés|FI_SPT|:X:|:X:|::|::| +||SOCIO|X|X|X|?| +||RETRO_SP|X||X|?| +||BILAN_SEM|?|?|X|?| +||SOCIO_EPCI (auto)|X|X|X|?| +|Périodes|Livraison INPUTS||||| +||UTI||||| +||QPA||||| +||MEP|Février|Avril|Septembre|Nov.-Déc.| +|Terminé|Date|06/02/2023|||| \ No newline at end of file diff --git a/pages/bidouille.md b/pages/bidouille.md index 14234cf..8a32f5b 100644 --- a/pages/bidouille.md +++ b/pages/bidouille.md @@ -1,13 +1,2 @@ [retour](BPCE-SI-Notes) -[](\\Prdgce7v2115\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2116\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2117\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2118\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2119\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2120\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2121\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2122\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2123\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2124\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2125\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) -[](\\Prdgce7v2126\d\gcedoc\referentielproduction\clients\csctrmif\csctrmif\Documents) +# Bidouille \ No newline at end of file diff --git a/pages/dbtest.md b/pages/dbtest.md new file mode 100644 index 0000000..e92b696 --- /dev/null +++ b/pages/dbtest.md @@ -0,0 +1 @@ +# test DB \ No newline at end of file diff --git a/pages/enveloppes.md b/pages/enveloppes.md index dcd1497..567279f 100644 --- a/pages/enveloppes.md +++ b/pages/enveloppes.md @@ -52,5 +52,5 @@ ## 10 - resumé après modification * Ajouter une zone de saisie pour permettre au conseiller de saisir la phrase (pour la synthèse) ## 11 - Synthèse (pdf) -* Grise la ligne enveloppe (gris plus clair) +* Griser la ligne enveloppe (gris plus clair) * ligne dessous, CTO numéro de compte, si nouveau : "à souscrire" \ No newline at end of file diff --git a/pages/forbearance.md b/pages/forbearance.md index 819e72a..a9aed7a 100644 --- a/pages/forbearance.md +++ b/pages/forbearance.md @@ -3,3 +3,4 @@ Rechercher les valeurs possible des états et statut. fait. * GECOCH : P34249 * Clarity : 031984-02 +* synthesecorporateserv/rechercheBilan **->** voir si on a les données Elocal suffisantes (validé etc.) diff --git a/pages/notes.md b/pages/notes.md index 7b680d2..6a84aec 100644 --- a/pages/notes.md +++ b/pages/notes.md @@ -2,6 +2,8 @@ # Notes ## BPCE-SI - [Notes](BPCE-SI-Notes) +## Cheeze Notes +- exemple [r2d2 + rusqlite](https://github.com/actix/examples/blob/master/databases/sqlite/src/main.rs) ## Rust *  [Idées](perso-idees) *  [Crates](perso-crates) @@ -15,4 +17,5 @@ ## Avec les enfants - [Bricolages]() - [mini-golf]() -- [Livres](livres enfants) \ No newline at end of file +- [Livres](livres enfants) +- lapin de race feu noir \ No newline at end of file diff --git a/pages/test.md b/pages/test.md index 4d17437..6c7b8e3 100644 --- a/pages/test.md +++ b/pages/test.md @@ -1,3 +1,4 @@ [Accueil](accueil) # Test pour développement CheezeNotes -test de gras au milieu d'un texte \ No newline at end of file +test de gras au milieu d'un texte +[!](/static/cs.png) Salut les filles ! \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index 08937c9..da976af 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -1,4 +1,6 @@ use clap::Parser; +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; #[derive(Parser)] pub struct Arguments { @@ -26,7 +28,5 @@ impl Arguments { pub struct AppData { pub name: String, pub root: String, - pub db_url: String, - pub db_user: String, - pub db_password: String, + pub pool: Pool, } diff --git a/src/database.rs b/src/database.rs deleted file mode 100644 index 39fd9a6..0000000 --- a/src/database.rs +++ /dev/null @@ -1,12 +0,0 @@ -use rusqlite::{params, Connection, Result}; - -pub struct DatabaseConnection { - connection_string: String, - connection: Option, -} - -pub fn new(connection_string: String) -> DatabaseConnection { - let mut con = DatabaseConnection{ connection_string: connection_string.to_owned(), connection: None}; - con.connection = Some(Connection::open(connection_string).unwrap()); - con -} diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..1dddb91 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,51 @@ +use actix_web::{error, web, Error}; +use serde::{Deserialize, Serialize}; + +pub type Pool = r2d2::Pool; +pub type Connection = r2d2::PooledConnection; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Page { + pub page_name: String, + pub page_text: String, +} + +pub async fn get_page_by_name(pool: &Pool, pagename: String) -> Result, Error> { + let pool = pool.clone(); + + let conn = web::block(move || pool.get()) + .await? + .map_err(error::ErrorInternalServerError)?; + + web::block(move || { + let mut stmt = conn + .prepare("SELECT page_name, page_text from pages WHERE active=true and page_name=?")?; + + stmt.query_map([pagename], |row| { + Ok(Page { + page_name: row.get(0)?, + page_text: row.get(1)?, + }) + }) + .and_then(Iterator::collect) + }) + .await? + .map_err(error::ErrorInternalServerError) +} + +pub async fn update_page(pool: &Pool, page_name: String, page_text: String) -> Result { + let pool = pool.clone(); + + let conn = web::block(move || pool.get()) + .await? + .map_err(error::ErrorInternalServerError)?; + + web::block(move || { + let mut stmt = conn + .prepare("insert or replace into pages (page_name, page_text, active) values (?, ?, true)")?; + stmt.execute([page_name, page_text, ]) + }) + .await? + .map_err(error::ErrorInternalServerError) +} + diff --git a/src/lib.rs b/src/lib.rs index 2c7a8f3..da8829f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ pub mod page; pub mod index; pub mod commons; -pub mod database; \ No newline at end of file +pub mod db; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 2cb7592..bbaf1ee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,9 @@ use actix_web::{web, App, HttpServer}; use actix_files; +use r2d2::Pool; +use r2d2_sqlite::{self, SqliteConnectionManager}; + use cheezenotes::commons::{Arguments, AppData}; use cheezenotes::{ page, index }; @@ -13,12 +16,13 @@ async fn main() -> std::io::Result<()> { let port = args.port; let root = args.root; + let manager = SqliteConnectionManager::file("db/db.sqlite3"); + let pool = Pool::new(manager).unwrap(); + let appdata = AppData { name: String::from("CheezeNotes"), root, - db_url: String::from(""), - db_user: String::from(""), - db_password: String::from(""), + pool: pool.clone(), }; HttpServer::new(move || { @@ -27,7 +31,6 @@ async fn main() -> std::io::Result<()> { .service(index::index) .service(page::page) .service(page::save_page) - //.service(page::page_link) .service(actix_files::Files::new("/static", "./static")) .service(actix_files::Files::new("/static/modules", "./static/modules")) }) diff --git a/src/page.rs b/src/page.rs index 8f04485..603c9a5 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,15 +1,14 @@ +use actix_web::{get, put, Responder}; use actix_web::{web, HttpResponse}; -use actix_web::{Responder, get, put}; use std::fs; use std::io::Write; -//use regex::Regex; use askama_actix::Template; use askama_actix::TemplateToResponse; use crate::commons::AppData; -//use crate::database::DatabaseConnection; +use crate::db; #[derive(Template)] #[template(path = "page.html")] @@ -23,57 +22,50 @@ pub struct PageTemplate { #[get("/page/{page}")] async fn page(path: web::Path<(String,)>, data: web::Data) -> impl Responder { let pagename = &path.0; + + let fut_page_datas = db::get_page_by_name(&data.pool, pagename.to_owned()); + let page_datas = fut_page_datas.await.unwrap(); + let md; + match page_datas.first() { + None => { + let filename = String::from("pages/") + pagename.as_str() + ".md"; + md = match fs::read_to_string(filename) { + Ok(txt) => { + db::update_page(&data.pool, pagename.to_owned(), txt.to_owned()) + .await + .unwrap(); + txt + } + Err(_) => String::from("# ") + pagename.replace("_", " ").as_str(), + }; + } + Some(dat) => md = (*dat.page_text).to_string(), + } + let name = data.name.to_owned() + " " + pagename.as_str(); let root = data.root.to_owned(); - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let md = match fs::read_to_string(filename) { - Ok(txt) => txt, - Err(_) => String::from("# Nouvelle page"), - }; let init = String::from("init();"); - PageTemplate { name, root, md, init }.to_response() + PageTemplate { + name, + root, + md, + init, + } + .to_response() } #[put("/page/{page}")] -async fn save_page(body: String, path: web::Path<(String,)>) -> impl Responder { +async fn save_page( + body: String, + path: web::Path<(String,)>, + data: web::Data, +) -> impl Responder { let pagename = &path.0; - /*if pagename == "index" { + if pagename == "index" { return HttpResponse::Ok(); - }*/ - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let mut file = match fs::File::create(&filename) { - Ok(f) => f, - Err(_) => return HttpResponse::Unauthorized(), - }; - match file.write_all(body.as_bytes()) { - Ok(_) => HttpResponse::Ok(), - Err(_) => HttpResponse::Unauthorized(), } + db::update_page(&data.pool, pagename.to_owned(), body) + .await + .unwrap(); + HttpResponse::Ok() } - -/*#[get("/page/{oldpage}/{page}")] -async fn page_link(path: web::Path<(String, String,)>, data: web::Data) -> impl Responder { - let pagename = &path.1; - let name = data.name.to_owned() + " " + pagename.as_str(); - let filename = String::from("pages/") + pagename.as_str() + ".md"; - let md = match fs::read_to_string(filename) { - Ok(txt) => txt, - Err(_) => String::from("# Nouvelle page"), - }; - let init = format!("init('{}')", pagename); - PageTemplate { name, md, init }.to_response() -}*/ - -/*fn normalize_pagename(pagename: String) -> Result { - let pagename = pagename.trim(); - - let space_re = Regex::new(r"[-\s]").unwrap(); - let pagename = &*space_re.replace_all(pagename, "_"); - - let re = Regex::new(r"").unwrap(); - if re.is_match(pagename) { - Ok(pagename.to_owned()) - } else { - Err(()) - } -}*/ \ No newline at end of file diff --git a/static/cheezenotes.css b/static/cheezenotes.css index c688075..db88620 100644 --- a/static/cheezenotes.css +++ b/static/cheezenotes.css @@ -14,14 +14,14 @@ html { body { margin: 0; - background-color: #f6f6f6; + background-color: #dddddd; } .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; - font-size: 20px; /* Preferred icon size */ + font-size: 24px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; @@ -37,10 +37,11 @@ body { div#buttons { white-space: nowrap; + overflow-x: auto; box-sizing: border-box; padding: .2rem; position: fixed; - background-color: #dddde5; + background-color: #dddddd; top: 0; left: 0; right: 0; @@ -53,8 +54,8 @@ div#buttons button.button { color: #444444; padding: 0; margin: 0; - height: 1.8rem; - width: 1.8rem; + height: 2.8rem; + width: 2.8rem; background-color: #eeeeee; border: 1px solid #cccccc; border-right: none; @@ -68,14 +69,14 @@ div#buttons button.separator { color: #bbbbbb; border: none; border-left: 1px solid #cccccc; - height: 1.8rem; + height: 2.8rem; margin: 0; padding: 0; } div#buttons button.text { color: #444444; - font-size: 16px; + font-size: 18px; vertical-align: bottom; } div#buttons button.text:disabled { @@ -123,7 +124,7 @@ textarea#ta { } div#cheezenotes { - margin-top: 2rem; + margin-top: 3rem; margin-left: auto; margin-right: auto; max-width: 1200; @@ -314,6 +315,7 @@ div#cheezenotes:focus div.cheezenotes_line span.token { div#cheezenotes div.body { margin-top: 0.5rem; + line-height: 1; margin-bottom: 0.5rem; } div#cheezenotes span.mono { diff --git a/static/cs.png b/static/cs.png new file mode 100644 index 0000000000000000000000000000000000000000..adae08f5b953de76e7f84234da1f6d7a9f86fabf GIT binary patch literal 10853 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

C zcDSkaxy?9H%Q;ZKijxwh3l^S$2RWheV^KW{MXuHrU=aW0$TfF zeCU?YOHo(_WQa)`Unf&#+;u_q&a$WdGOfdkxJ#}j_7wyuL}A_HG+*%ipL!vOP2>Yb@q|6R zDk&wVL?*^Jr*8#HEGqPRPD!<%V~E8T4SEr;}MNtERKsjk0RLVX4_Dum>xbROQ`Zx+EL$S{W`6&Kb%e$1h%#yESw#8)}W>?i~2(T9m(E_B*x?^n7o9x+@U0$DnvD-?zuu9w&@t@ZwSc Vq9g5K;B7[!$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '[$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '[$2]()'); line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '[]($2)'); -- 2.36.3 From 0d2cbdac9a2af3192c3098da325c2225070724c6 Mon Sep 17 00:00:00 2001 From: Nicolas Sanchez Date: Thu, 9 Mar 2023 16:51:15 +0100 Subject: [PATCH 2/2] ajout de l'historique de navigation avec repositionnement dans la page --- db/db copy.sqlite3 | Bin 0 -> 106496 bytes db/db.sqlite3 | Bin 106496 -> 106496 bytes src/page.rs | 37 ++++++++++++--- static/cheezenotes.css | 86 +++++++++++++++++++++------------- static/modules/cheezenotes.js | 46 +++++++++++++----- static/modules/md.js | 54 +++++++++++++-------- templates/page.html | 57 +++++++++++----------- 7 files changed, 182 insertions(+), 98 deletions(-) create mode 100644 db/db copy.sqlite3 diff --git a/db/db copy.sqlite3 b/db/db copy.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..a531d5d350cd9b0263740310c54fd53ef0e3f28d GIT binary patch literal 106496 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 UybaV3-8TP!DqljUXqSV31MZoo>Hq)$ literal 0 HcmV?d00001 diff --git a/db/db.sqlite3 b/db/db.sqlite3 index ab7acf59890a6b589c5df00ae3aea7ee37c23cdc..d4757bc0f04f5e94789a1e392bbbfd9c36c083df 100644 GIT binary patch delta 4547 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 PhjR?(*hi6Wk4OIl63rBQ delta 795 zcmX|-T}TvB6vywG*_qvYcgJhCex>G=nyHxSnrnV!Xp3bZNT$B{pzdz9NXqyTO5z&f zP?)4HbbAoQ0tupYSZ%bTEJ0r)^(F8@NPUnn=&ASalJxSs_kYg+9L_m|OY-27Jemal zvE(Z78_iQxMhL~x@sKt8IGv}n^c9_^Q*?qdI&Nq#A>0-5IUMQ1&!gQtZV>JXg^zxIV5I6Wo?xwx9(EzwT^ComoJ=>qg(8e z8gEaaE70x_y~)dSN4m8~@(x8z1^#xczE-t>5HS&atr2aHtRxFp=Ty7{0C z&cYrWDTTzRB|OVj94jvcg?%r9g-Cq+zu86D-7?rSo5}%zHJyXCgXU8ey!qt{n5QJN ztbogqBZ$kySVP02St-B?*<6l=W%=!SutYm;(hyP_9E)^1YEpTr49L1PWN3FJbEqEr ziDLVTL{x;t1yM&uW7fyBYh#~{B39HD_hIgzXc}E%%7sczss<3KkuLbeGt(lG9gNLTe2QvaM sMBD6R25gx-Hz5_9pz?VoyovCpp{-%-<8+^t`7EE^?u2}^SAgHrUvQ4scmMzZ diff --git a/src/page.rs b/src/page.rs index 603c9a5..505199c 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,8 +1,9 @@ +use actix_web::http::header::ContentType; use actix_web::{get, put, Responder}; use actix_web::{web, HttpResponse}; +use serde::Deserialize; use std::fs; -use std::io::Write; use askama_actix::Template; use askama_actix::TemplateToResponse; @@ -19,10 +20,12 @@ pub struct PageTemplate { pub init: String, } -#[get("/page/{page}")] -async fn page(path: web::Path<(String,)>, data: web::Data) -> impl Responder { - let pagename = &path.0; +#[derive(Debug, Deserialize)] +struct QueryParams { + pub data: Option, +} +async fn get_data(data: & web::Data, pagename: String) -> String { let fut_page_datas = db::get_page_by_name(&data.pool, pagename.to_owned()); let page_datas = fut_page_datas.await.unwrap(); let md; @@ -41,10 +44,32 @@ async fn page(path: web::Path<(String,)>, data: web::Data) -> impl Resp } Some(dat) => md = (*dat.page_text).to_string(), } + md +} + +#[get("/page/{page}")] +async fn page( + path: web::Path<(String,)>, + data: web::Data, + params: web::Query, +) -> impl Responder { + let pagename = &path.0; + + let md = get_data(&data, pagename.to_owned()).await; + + match ¶ms.data { + Some(_) => { + return HttpResponse::Ok() + .content_type(ContentType::plaintext()) + .body(md) + } + None => {} + } - let name = data.name.to_owned() + " " + pagename.as_str(); + let name = data.name.to_owned() + " - " + pagename.as_str(); let root = data.root.to_owned(); - let init = String::from("init();"); + //let init = String::from("init();"); + let init = format!("init();"); PageTemplate { name, root, diff --git a/static/cheezenotes.css b/static/cheezenotes.css index db88620..1f0cacc 100644 --- a/static/cheezenotes.css +++ b/static/cheezenotes.css @@ -7,21 +7,11 @@ url(/static/MaterialIconsOutlined-Regular.otf) format('woff'); } -html { - font-family: system-ui; - font-size: 12pt; -} - -body { - margin: 0; - background-color: #dddddd; -} - .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; - font-size: 24px; /* Preferred icon size */ + font-size: 22px; /* Preferred icon size */ display: inline-block; line-height: 1; text-transform: none; @@ -35,27 +25,71 @@ body { font-feature-settings: 'liga'; } +html { + font-family: system-ui; + font-size: 12pt; +} + +body { + margin: 0; + background-color: #dddddd; +} + +div#content { + position: absolute; + margin: 0; + padding: 0; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow: auto; +} + +div #margindiv { + max-width: 1200px; + margin-left: auto; + margin-right: auto; + top: 0; + bottom: 0; +} + +div#cheezenotes { + position: static; + margin: 0; + margin-top: 0; + margin-bottom: 3rem; + padding-top: 1rem; + padding-left: 3rem; + padding-right: 3rem; + padding-bottom: 1rem; + background-color: #ffffff; + min-height: 100%; + overflow-x: auto; +} + div#buttons { + position: sticky; white-space: nowrap; overflow-x: auto; box-sizing: border-box; - padding: .2rem; - position: fixed; + padding-top: .2rem; + padding-bottom: .2rem; background-color: #dddddd; top: 0; left: 0; right: 0; margin-left: auto; margin-right: auto; - max-width: 1200; + max-width: 1200px; } div#buttons button.button { color: #444444; padding: 0; margin: 0; - height: 2.8rem; - width: 2.8rem; + height: 2.6rem; + width: 2.6rem; background-color: #eeeeee; border: 1px solid #cccccc; border-right: none; @@ -69,12 +103,13 @@ div#buttons button.separator { color: #bbbbbb; border: none; border-left: 1px solid #cccccc; - height: 2.8rem; + height: 2.6rem; margin: 0; padding: 0; } div#buttons button.text { + line-height: 1; color: #444444; font-size: 18px; vertical-align: bottom; @@ -109,7 +144,7 @@ div#buttons #lockButtonLabel { div.ta { margin-left: auto; margin-right: auto; - max-width: 1200; + max-width: 1200px; } textarea#ta { @@ -123,21 +158,6 @@ textarea#ta { background-color: #cceeff; } -div#cheezenotes { - margin-top: 3rem; - margin-left: auto; - margin-right: auto; - max-width: 1200; - padding-top: 1rem; - padding-left: 3rem; - padding-right: 3rem; - padding-bottom: 1rem; - margin-bottom: 3rem; - background-color: #ffffff; - min-height: 90%; - overflow-x: auto; -} - /*div#cheezenotes div.cheezenotes_line {*/ /* Pour firefox : white-space: pre; */ /*}*/ diff --git a/static/modules/cheezenotes.js b/static/modules/cheezenotes.js index e409ba4..3778801 100644 --- a/static/modules/cheezenotes.js +++ b/static/modules/cheezenotes.js @@ -118,15 +118,10 @@ function onsave(e) { let saveButton = document.getElementById('saveButton'); saveButton.disabled = true; let text = save(document.getElementById('ta'), document.getElementById('cheezenotes')); - var xhttp = new XMLHttpRequest(); - xhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status != 200) { - saveButton.disabled = false; - alert(xhttp.responseText); - } - } - xhttp.open("PUT", document.location.href, true); - xhttp.send(text); + fetch(document.location.href, { method: "PUT", body: text }).catch((error) => { + saveButton.disabled = false; + alert(error); + }) } function onload(e) { @@ -338,11 +333,33 @@ function onfocus() { enableFormatButtons(); } -function init(pagename = null) { +function onpopstate(e) { + let top = 0; + let left = 0; + if (e.state.top) { + top = e.state.top; + } + if (e.state.left) { + left = e.state.left; + } + fetch(document.location.href + "?data=").then((response) => { + let ta = document.getElementById('ta'); + response.text().then((data) => { + ta.value = data; + load(document.getElementById('ta'), document.getElementById('cheezenotes')); + let content = document.getElementById('content'); + content.scrollTop = top; + content.scrollLeft = left; + }); + }).catch((error) => { alert(error); }); +} + +function init() { let cheezenotes = document.getElementById('cheezenotes'); dpwidth(cheezenotes); + window.addEventListener('popstate', onpopstate); cheezenotes.addEventListener('input', onedit); cheezenotes.addEventListener('keyup', onkeyup); cheezenotes.addEventListener('keypress', onkeypress); @@ -366,7 +383,7 @@ function init(pagename = null) { addButton('h1Button', 'H1', onh1button); addButton('h2Button', 'H2', onh2button); addButton('h3Button', 'H3', onh3button); - lastButton(addButton('bqButton', ':format_quote', onbqbutton)); + addButton('bqButton', ':format_quote', onbqbutton); addSeparator(); addOnOffButton('editModeButton', ':edit_note', ':visibility', function (e) { @@ -380,6 +397,13 @@ function init(pagename = null) { disableFormatButtons(); + /*if (pagename != null) { + fetch(pagename + "?data=").then((response) => { + let ta = document.getElementById('ta'); + response.text().then((data) => { ta.value = data; onload(); }); + }).catch((error) => { alert(error); }); + }*/ + onload(); } diff --git a/static/modules/md.js b/static/modules/md.js index ad4a12e..203d130 100644 --- a/static/modules/md.js +++ b/static/modules/md.js @@ -32,7 +32,7 @@ function appendData(div, data) { newline = formatLine(lineBegin + lines[0]); line.parentNode.replaceChild(newline, line); let prevline = newline; - for(let i=1; i { alert(error); }); } return false; } else { @@ -106,7 +120,7 @@ function onlinkout(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { cheezenotes.contentEditable = true; - } + } } function formatLine(line) { @@ -205,7 +219,7 @@ function formatLine(line) { if (elem.getElementsByClassName('tablerow').length > 0) { if (elem.childNodes[0].childNodes.length > 0) { let child = elem.childNodes[0].childNodes[0]; - while(child != null) { + while (child != null) { if (child.nodeType == 3) { let newchild = document.createElement('span'); newchild.innerText = child.nodeValue; @@ -219,7 +233,7 @@ function formatLine(line) { elem.classList.add('tablerow'); } let links = elem.getElementsByClassName('link'); - for (let i=0; i`' + mono + '`' + line.substring(matches[i]+2, line.length); + line = line.substring(0, matches[i]) + '`' + mono + '`' + line.substring(matches[i] + 2, line.length); } return line; } @@ -471,7 +485,7 @@ function removeLink(line) { if (listLink == null) { return [line, null]; } - + line = line.replace(/(\[([^\]]*?)\]\(([^\)]*?)\))/g, "[]()"); return [line, listLink.reverse()]; } @@ -492,8 +506,8 @@ function addLink(line, listLink) { cpt++; } matches = matches.reverse(); - for(let i=0; i - - - - - - - - - {{name}} - - - - -

- + + + + + + + + + + {{name}} + + + + + +
+
+
+
+
-
-
- - - +
+ + + + \ No newline at end of file -- 2.36.3