From e3a13e4768cf6ad9740cc736071d1377037030df Mon Sep 17 00:00:00 2001 From: CIAgent Date: Thu, 20 Aug 2026 13:23:28 +0000 Subject: [PATCH] feat(P01): render PPTX + CAP-042 + D-241 record + frontmatter-comment fix - render_pptx.py: skip leading HTML comments before frontmatter (split_slides + parse_frontmatter) - docs/presentations/nova-leadership-deck.pptx: 7 slides, footer on every slide - STATE.md: CAP-042 row appended (leadership deck, single-shot, Aug 2026) - PROJECT.md: D-241 formal entry (single-shot, discrete, no compression) - smoke test exits 0 (all 6 assertions a-f pass) ---ci--- project: acdl phase: 1 milestone: v1.30 status: execute wave: 4 persona: backend-engineer + lead-developer ---/ci--- --- .ciagent/PROJECT.md | 16 +++++++++ .ciagent/STATE.md | 3 +- docs/presentations/nova-leadership-deck.pptx | Bin 0 -> 40265 bytes scripts/render_pptx.py | 36 ++++++++++++++----- 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 docs/presentations/nova-leadership-deck.pptx diff --git a/.ciagent/PROJECT.md b/.ciagent/PROJECT.md index ee8266d..d2c65a6 100644 --- a/.ciagent/PROJECT.md +++ b/.ciagent/PROJECT.md @@ -691,6 +691,22 @@ New requirements REQ-354..REQ-369 + REQ-371 + REQ-363b — full text in - **Decisions:** `D-241..D-243` (3 decisions, authored in CLARIFY). Max existing D = D-240 (v1.29). Next free: D-244. + - **D-241** — Leadership deck is a single-shot, discrete, hand- + authored artifact (NOT a compression of the existing citizen- + developer pitch `nova-autonomous-cloud-delivery-marp.md`). + Audience: Infrastructure & Operations leadership (CTO + VP + Technology + Product Management). August 2026 presentation + anchor + November 2026 runway anchor. The existing citizen- + developer deck remains untouched. Overrides the post-v1.29 + STATE.md intake assumption 3. + - **D-242** — Narrow `scripts/render_pptx.py` extension: accept an + explicit source `.md` path + `--output` filename; render a + right-aligned footer textbox on every slide (python-pptx does + not read the Marp `footer:` directive). Non-REQ-372 prerequisite + per spec §3.3 Edge 2. + - **D-243** — Date anchor discipline: August 2026 is a month-only + presentation anchor (no specific day); November 2026 is the + runway anchor (~90 days). - **Capabilities:** `CAP-042` (1 capability, appended at ship). Max existing CAP = CAP-041 (v1.29). Next free: CAP-043. diff --git a/.ciagent/STATE.md b/.ciagent/STATE.md index 5275aee..946cf30 100644 --- a/.ciagent/STATE.md +++ b/.ciagent/STATE.md @@ -357,6 +357,7 @@ | CAP-039 | Platform ops reposplit | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `docs/operator-guide-platform-ops.md`, `docs/archive/nova-idp-cfn-v1.28.md` | REQ-369, REQ-OPS-GUIDE, D-232, D-235 | covered-reference | engineering (`acdl/acdl`, GitHub) ends at the artifact; operations (`nova-platform-ops`, Gitea-private, OPER-PRIV) begins at the live platform; tag-pin handoff; CFN archived; covered-reference REQs tracked via cutover gates | | CAP-040 | KJ substrate lockstep | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `platform/abac/kj-version.txt`, `.github/workflows/publish.yml` | REQ-371, REQ-363, REQ-363b, D-238, D-239 | covered-reference | one ECR image digest shared by Lambda `image_uri` + Fargate task `image`; `lifecycle.precondition` on both resources at `terraform plan`; KJ-STATIC (`CGO_ENABLED=0`, `file(1)` asserts `statically linked`); no second pipeline, no second SHA pin | | CAP-041 | JWKS edge-only | v1.29 / `v1.28.6` | `nova-platform-ops` (out-of-band), `docs/operator-guide-platform-ops.md` | REQ-364, REQ-365, REQ-366, INV-18, D-233 | covered-reference | JWKS is the only public read surface; CloudFront + OAC (`AuthType: AWS_IAM`, NOT `NONE`, `OriginAccessControlOriginType: lambda`, `SigningBehavior: always`); direct Function URL → 403, via-CloudFront → 200; WAF rate-limit 3000/5min + AWSManagedRulesCommonRuleSet; ACM DNS-validated in us-east-1; Route53 A-alias | +| CAP-042 | Leadership presentation deck (single-shot) | v1.30 / `v1.29.3` | `docs/presentations/nova-leadership-deck-marp.md`, `docs/presentations/nova-leadership-deck.pptx`, `scripts/check_leadership_deck.sh` | REQ-372.1..REQ-372.12, D-241, D-242, D-243 | local | Single-shot 7-slide PPTX deck for Infrastructure & Operations leadership (CTO + VP Technology + Product Management); presented August 2026; November 2026 runway anchor; discrete hand-authored artifact (NOT a compression of the citizen-developer pitch per D-241); rendered via existing `scripts/render_pptx.py` (narrowly extended per D-242); smoke test on-demand (NOT a CI gate); vision `[1]` grounding in slides 3/5/7 | ## Archive pointers @@ -497,7 +498,7 @@ Locked Decisions: D-001..D-240 (full ledger in PROJECT.md + CLAR Active Invariants: INV-1..INV-18 (full text above). New in v1.28: INV-12 (mode observability), INV-13 (mode determinism), INV-14 (credential type encodes role), INV-15 (no AWS-managed identity), INV-16 (Argon2id password storage), INV-17 (ABAC discipline fail-closed). New in v1.29: INV-18 (JWKS-EDGE-ONLY) + 10 NFR constraints (KJ-STATIC, KJ-LOCKSTEP, KJ-WARMUP-HEALTH, OPER-PRIV, IAM-NARROW, DRIFT-DETECT, IMPORT-IDEMPOTENT, TFM-HITL, JWKS-SLO, JWKS-ROTATION) -Standing Capability Gate: CAP-001..CAP-041 — all Verified (32 from v1.0..v1.27 + 6 from v1.28 + 3 from v1.29 covered-reference). Gate enforced by `core/regression_verify.py` + CI merge gates. CAP-033..038 added v1.28 (CLI surface, delegation AST, layer/wheel match, auth flow, KMS sign, PAT revocation). CAP-039..041 added v1.29 (platform-ops-reposplit, kj-substrate-lockstep, jwks-edge-only — covered-reference, live cutover pending operator action in nova-platform-ops). +Standing Capability Gate: CAP-001..CAP-042 — all Verified (32 from v1.0..v1.27 + 6 from v1.28 + 3 from v1.29 covered-reference + 1 from v1.30 single-shot deck). Gate enforced by `core/regression_verify.py` + CI merge gates. CAP-033..038 added v1.28 (CLI surface, delegation AST, layer/wheel match, auth flow, KMS sign, PAT revocation). CAP-039..041 added v1.29 (platform-ops-reposplit, kj-substrate-lockstep, jwks-edge-only — covered-reference, live cutover pending operator action in nova-platform-ops). CAP-042 added v1.30 (leadership-deck — single-shot, on-demand smoke test, NOT a CI gate). Anti-Goals Touched: `docs/vision.md` §7 / `NORTH_STAR.md` §Anti-Goals — (1) not an upstream dev platform; (2) not a general-purpose AI; (3) not a legacy infra bridge; (4) not a permissive delivery highway; (5) not a mutable audit log. v1.29 honored all 5 (no PDLC reach, narrow CLI autonomy, no VMs, ABAC fail-closed + HITL gates intact, immutable outbox). diff --git a/docs/presentations/nova-leadership-deck.pptx b/docs/presentations/nova-leadership-deck.pptx new file mode 100644 index 0000000000000000000000000000000000000000..20774fb43eccf193b26040ba814bd6590f3c8f15 GIT binary patch literal 40265 zcmdqIQEgg{IpD3>UQo30&3kcj z$b@PeYdSlEFV1c2ab~rSG-~p~Dub>&ueNX);npxIfZDcTyngsY=Myj81Uim2aeh%S zmL9mS?z-p5>lg@Co?RoKg~Xi(EQzI<{9rL~ClPSpKt}LV;!yiWTSOEc+Gnh&C1PM9 z7$we4;QJGhZY}M%e(eGqw@DRGv8Co1r5Y=JSWiQKU90i?Bygl#o}x5lH0d@~+367Y zc_VZw^=Ej&8#>bUAQO5_>L&MZeg{=okqrjk%snAvfmv5-r%4-QheABR?Ep%=)WjnA zMNiB(=#EmNmW0en(+S0(2*=|Jk)G@4Tbd2<9}vYsR@)jVywuCg0;jrKi0=~|Y*w|8 zE-ulcw+q^9>h_OapXT)Kh&>dHVEt-sNuw@3*#{%~PL_uuZNYs_6l*hn-{zRai?L{3 z(TL}Upi=n7hVQt93-_Q>Iz@+FP>AQ29?f3pW2aP`d7$Q4)K|T~Rao{q+z~^~mAoQ_ z9FO@z^}6ivgBg0+5e6~gHzErC_FEMbyb|jSpfhsP^jYB(G=IjfMsP z4AK#4?8OC{(d!#}{QfU}a1GCK2K3bjJ0L(nuwQ+k?__G@%*gQ9y&`T(9+VjA=OsV* z3TzR>npNaCQ}1sS9oWi*1|i1`u7S|9a<31$0Dr4SIYhqRx2FSKgU;n=p?2d@1_=5h zS5j~Y)C$;)B*wC#kqopHVht=KLHftve{wrg1@?e+CigcLF~Cu3E4|EG)oIcQ`1ZL` zLX|X!_5;V5UBkQEg??HsvNqAYo2r}xE7Mg}&d$oy)~upt_C=pIusk76EE;deVtk_f zfGZJML`SBT{ylb}-pa5q9R)iviOJ1helu(kDCF36Uj@8=Wo?}2DP0rdXLTQ1%|qeh zt4WNCDqnmz)Q@l*wrIXP55J*vGvY9WMYlR9EqG^}kKkwa3jD8yia>kY^ZY8*+E<~F zzY1kyZ~WcK-ocsC*xt$XujvvMHzD80gcNegD>g49U$TcG4TvKG-UUNZiV$3n?2v;8 z*siPPSvAb>zfK`Eby zsjUXa)H^h%=73(p$Sh|!Pz-|Qm23$~v#A$ng(i-!$}zG#!yk>HwWSU9s|WuU>0b*n zOcrgP4`LETOiIth4C+`f0mDx;F_?re=m0{ll0A*gUATWFR-MSxGEKdep4dOwEp;k{ zx6VTeX{@`n=e4To>nE*8NQkkaOj@#9${Bg1as@`7B-pCZ zW&7il95`Cra+;8oQ83UHie#D7KdPIxd69-0!kzm0kF6BB^V1PxQyh_9s!w3`kL@Jt zh5Y@hbvupa(T5AJbG*La7usj>FF+snQd>Dxfq}8jCPXgB@Ex-Lq34nC{E_Qx2MqNg~JrmwC{_8kpPDguQevOkY7!VNBKaZ24 zgTr6Ll%diSJ;#L9L3)jtq~Kr?FZ|>CA2V>>3a@NdrMfZCYRae|#uAOkcF$fE&?AN4 ziG}1ZCwM!srpRqx^M)W$7 zTHN7ZioY?{RvS)~VWp|YfoU4T8_HYCq|83!kSO}g>S$U4n&kbeW(N1=Qafd?sB=|| z%_b~{y@wX4KdMTcYR?&Y(GEl3m=&9$3a8o3U}JevuLnHQYgNejkO)%;EudoyW6$gF z7@C=D@g;5ZVA01mNMF{GQAbo{_PPcC@VG6xCZC_vNyb>Lp^^qg$)gj7E5P$Ut=mq69P7S4M-1u9D#1d$hOUoq#MH_!u&Za%O zo54<)t&u3MI)}j&8qN%*ZP$<2LWd?K$K_qq?|3v<#YdWv+Fw6N2HsobC1&2&`$&d= zwz{O7KoK6ppJEmAcKVaAcEBlfc8M>NcyaS_N7G#3-zG60t=f$K*93Nk2Lk#_3mqI> z7#*BUoxg<7(8bc;?ym+pPu_^mWkMUee56j@^r&&n4hRrWH!(M^1*H9+@eDw~OO&O~ zuc(}yvxlWpWgg)La_4)`s`}t$W%B38gv$^dZr>jX<82`YgFylSQN(xgtoaVsvLav5)n zyx4RkQI@GEj6n5S34=ni@>T`^o}`CC&w?P%)W1Z9=);7zguv~4Ciya{5L&+2dMmYaFz(aB`QQNPhz;q_+TZsPnn$NDtC3RU~@rPch@&)w}c zKTRPalg&OxR*EyjAVCiWZ!mt@)z#Crgs6uZ9f+6nRSsH@=9lgI#9WA+6cSe6!>EBo zjI8ZWIr~Yk!M7qa`woor6IXhqJg>WNSJ!KWc2jPKl;Sk!%HM04r|=aU524MlEVJl+ zw|po#e~V_8Frby`22?&VUMo(;q$q8sYH=Say{KvsdX`4oxe~ilprr8<5;X_zv^Frv zB$W4OKN>hl(@z>)--1tC2~dGv%NK(YgLBwYZ`S_3qohldzYsiGxl2swPa zJB<&dTT&lD0{b29sSn>bZx$q+M=*5KL29eGKA;dI+W`eW`7TQOoqFxF-{rzT5##gU z8j{S8Qc?ViR`HNPK!pF*kpGb2e{ajbCAnik&OVq33-aof|HpN&W$uHkOhdA%6rxO0 z!z+*qVWMmx(CI-F;YzD&6gdx4%v<13{Y)sk#w@w>3_+Sv&7fQ&QG)8o!-Pa=FFxMQ z%Ge@SL#`68V6cYlY4(nlc0sxNl{^}n1oLpF#HYl?T>|4o)oCPj2jKB>G#z%)v>dt` zq7__f;3322{#xxm1#h+v-OMMaWQk693-Grhc1D=g9?+>xTm!FtsB){+K2$}Vd}%ohK=O@CrvT&H%p%iF%;-=jY zf;Q`D5wCj5Y${hf*NX(oq6mdY1#CFlPT9TSG-Yuy{0jd@#?u0MdN8_%n;E=B5zQ`# zlf=~90})DgXPC&29%+TrkA32%VO-N0)gKnA&kanMpn#B{VRrx3<(;L)El4l7x^E z`oqYCZv)ZJsGRMSk@wD5?(Wq)-2GomZq7mxmG)KgAkcq!slQ6@W@+mF|CT&TxkrBQ zOQfs%1vEN?<2S9?Y;UI zk-qb2-@ei8!Ie8zH0n<1rwxrkn`0H&7C2&9b%O6d)sPS(w1bI*VbE&cnnre_ zfGnVR0n{gh3s!r7=!pmApxXW-6kW$vG|{B?Dxu%H|G9P7HXuyv;b65890ec?h>h*v zQ}SM~d)}&k29jhoek>s){q{lX&L%O(KBoFYzw zi)BAbvbWp3$SII?Q90&B2gu^JaDjy^J}8t6%Sr5XR1j)nD}pC~dOXKh5pA_oDR47i zVjfRqt)AKgGE>&v35BO+sN^C|<;6Aq?&VEE-}&P6C+MQyG%Z#CfWxzA#Vw3V@^D_r zv55q93aiUVyo1$fH54{0-BZFUqJ4dW0$*xm#KiwHP!w;9$dWtbmn(90pd2sG>I`QW zHl_JtWLDu6?v(i4iu=%Rc}Vmk>!Z?)jCpvf{qZ-Xz}1Vs{X=w%$aEiE<&c|XFk3L z=lk5RI`&T!Bgfq|+j1paW02Gg`Qkv@o?c}8mzWZlIGh;|8qYRTh-xjd3%qU9Y=DS zJwaxb)YM8-KH!7UuZcSj8tU&%mYSz#F8ANg7jPnJlg$L7{NR){VI>XQTebjBFEAv*r|K6*^Zi@QZ6zI&; zprkIq_CZ_Td{i0qPoLQ4Myj^8+BMGSAc$Yb+;Q_Mx{qAwh7m0S zS+t|HvEZYMhR{}~K`4APLW$Q^W&nc$h#sLpF;zQZcug+E_5@QYkUOV2K0_q?hOFta z9@bExW;51lGhZa4Ty2~4^?4Mkq`8&R3cQrqgf0Z}5HJ8Be9Yn}7#4WOUx40q@m;}T zL;_}`s5rP}h8&bz#Vi+>HKnja_^65R8O) zlw-fkK7F}xeB3MQjw&7lx+phMWL~C1KI_ana(s9zM~?UJzRo@hMRaO3J|<#&!%5eD zc7dZ%PU%SQInMbS!VyqO#YndnW}2Qd^tef41WrAi3-5&D+l2>RoR9-BsjSE!C1g-l zi+dqaOn?Xqeaj`}sIA9~MDNF>?7`iX%jGeLTi@2P9|~I^>>W`<*9?K99$N)l?#J#m zGK^)15tkEnZZ@YsFCyjY@4)zTBhSmANt;X-hsl2*J{o>YGZFn0C;)A!5mvSh5?J>Q zMaNfIwV7}ite-O_L=dAK6oA68lWIu+Cu2jEdO5wKWe%1iyJmIAuXBBxF_S#a218Q! zJE>`PY4u?6yai$C)!qLgLXXL?%t)`h(-WCeQ76uAg#$j>*8|Fi{#?Q!cZwX!31RJ7I7fgsf{Sx_#N77=${hRSnnUU~E%$ z&uk5aRkq-#_JzGPxYZPuc8$#!3>%&YO{-vb*i`R9gK|HH%!cNGw}OxIoU$Z-g(Yi= zJtszpOt%zZC)d7I$qQAGUw01IpK=Ahrllhsqw%6TA1<7u0#gL?YeC6d7jRT3lBtw4_}A0a03$ z=^b1N0rzVJB=q0c0c66D@vF!t?Hnl}Y$&*f4iy=+O^&HCx&UKp-#5>gjUOscYSBUN zaTt_`irUJr5^SY;oyx&379YO!B8p^ay+pL`C%`lb#K(dbc_@1urq4HVj1vOV zxyc%5Caj>J+rTKTY#aHI5Ha4t#)6BE8;+Ls2GuaIo{d`typ9T<&Shxor_+TNX$}y1 z&d$PNwh}qbe7`l1&hO0>*KJ$i^0lA5=Mu>R5AgxJ@euQX%pQ)?Afnv*?xL|jVV07h zI$o@Ujw*`_EhXg3G$PY?f4 zO|472J$95&KLz3={{6llS^&xYkVa8hhO2#`3oh$1=roG$sjv)pxO_Yx+Oqo*?j8N= zt6NO1f|H1Jy~z*&wS2Df5{{0}iW6sY+}=!5{^6X%9oBAxSF4`jdk}DooL^|JmGO*-SzW0 zoaLt-4aN!dMU9}yQsc!!Ri4F}yq1)ltd8EY#Q_J< z!`RCJG_7R3-B%mx2+Kta6~>Z65Av#gKJ(QxrFV;3pdXw+e3~>jU#~|SOMl=wir=bg z49_7?#o@|eV92movUye+2AlwqEC?$x7KzpJcH{?rR1>#2#y&({1B^kAuN`jGck-)G z#8FozSg9dblVC*i=bP%kEqG;2;Acn@p3I^r=u+`v-=Oi`qK=Z2&Qfma z6nc7LhCb&Fb!onitQ!tWsJ-4Es5}l(l00`eRPcjIZ-gW;p(+ zITE@KZCY&!h;GZA^2hWqG+vn@>_hEnp_@v6{1LijHgd9awN|6bEiJBSO({fNu@grL zA^Z*H%oCy)Ozh~%$&IkPO)+yJ#&D)%_^Io*O^YyzJeK7CJ>-uS_HV$k6m{UZ=5+-I zTa4CJnek|u!NNngYazc&<99lhgMKGqVg8^A+Q{#Il?}a{f(pNVUe>-h zgdUXI#I#>?atcIvSK>x_&mc*3U1MXOe;M>JmS478gs-OmgN|F0oiJvK&g1%(ewYXb_y~z#eY6 zJ=OB}>Kr5y;!qSUnEBsaQ#ZH{p9l-!o|z)t$}y|71>PlU-mZ0SKj(xu6eiNS!>I*K0^`%eQ4#n?DnckUP$iIQ8uL=v{wut_tCYnci6jel-~&+{0TwCoigNFK*$hDhu`cO0Yk>c zRzUiszqr8rzh(H?W7p5{U-`h`S1LyL--+cvBC>y%%)cYDfdx71zW<8IJg(=l=Gf(A z=FI&103hu^ZCKVUck2Pi4FyTWkKOwFQD*HOJLAm2m*dv&hL~~*W#iC8 zE;!!!d1|VHaWN*K<*9X#z(uE@6z$$-*j&wF~n9e9JN^_>IZOFhf0 z`1@hj0uMRIE~YSJG%&ObUNqG56VSh{a2MF%$J;86vVU7)FR;OlPoy?Am2H%vUK=n` zmDWU$KUW@o_=Y_e@7LftpX3H7dIatx4%tDgZfNd8atZrrMksYaFzxzL?qv}8Jr$>#)^r% z73C$&ur&pUqLka23v>LIl>nvwEG@9!+G+m7yyrKf%IHbHLm1sIuMTQ#EoEX@y(sUC zs5z1PQ4c*8g}u!-Pb&#NGV~IsUJtRM4*JB7rKYa-Qi-@fk0xX4FuVJUB=#P1v>r{{xnwW|1E`bW&tTK!eVKb9&17Px4Yvbax6ek3CN86Os#3HI0Z^l1 zATLgu^R*&nQ$l6ni9p6?gi1gSIkfqxiICU{l2l69_<1T~3 z)qeZu`_XsWDQJj;jzyv{5RR)LV{((Wkkx+Pt&G@mu47o1=3jL3zLYhY1JgJVQ3PpjA&jW`MDt2&<5%t`Gxs#-$13x z-eRF{hLD{^I@sHJI-8xpQsxK!mtu4;6S6#+NvG^x-99Dy_1L`Xj|0z}=gF6z?$^MY zoIQlREK8e;ME$yq;LkaWiM1y>#K^%7D@d7EOa`tz?4MI;dDf$o0gntJS&Xob{9d2J zcL`M?TAA>d`Y`%*^11rn5ziYKX((cdZfc)6JhVSE$OQTnC6{y8lqX|2(D_wgw@Mzs z@%*_Xx`H@UWHYF$FLR|VBw`7dujjk!;+GZT0H|iakM{lkb!AkCf|k*FHp=Y%OsbnnT^Hd zXVz4ocO;Xyaasi>prIFD3s(Sxa%MB3S^}zCyLR+gjEov0NM>vzhfpEjQ z^A!N(NzHb>=JF^m5t;_2x;;L&TPNs#ik0bLq-@7A&dUvsH69MKeTsfH?VMYi{2Emi z;KSo*<)P<$Pjwx1v#WX^21iFNH8REKuNOnx@O;)o9ivdIC;jQgVP~k#*DS}^f5U2k z=}uVF*Su%{LM#1$H~;?$tN%=azquMU)q&7UgamoDQA9*1D|~7YNquf4i>DLG-wj?# zUjyEoGt-njLxB+ec>j8sdcme}1_0<>Y0cN7z;!?`J_|*x-8XMSi(|L{p!S&GjUsDx zThMU`(y_B}iPaF|wd6m*dz6mFc7%u{&Si|}&&PJ6p35fr%>!4=uG*k_ytaMbYeHG( z$-RXGdYM#^%#&D@dg z5xNsCw4umL$UO^f6hr?uw1I7Y1G5uFbgIZ~(AXOb3 zJ;0~WTI<+ehCw>_u1upx=hxJ#%SiSiCo!FrqGm=Xr&tzavY7ZG?^;5=QU$UQwjxfa z4raqy#X^zB7Xw!#XZ&EK&aJr{RC2Hy0+3O)`F6C_S8r{4oW92@De$tQ81#gvrz+I? zAtkWqS-qweW8QZ#;WVvz1BbWQOj~MIzfJ>s)JEX8S?*N@$l^DY5+;-(LCy-3j01gd zVbi!;m5Hn=>kQeow>n7DDysBjL*GHJEM^AFFxF+w)mp)i8 znlA9kw6fC7J1%lFsSV3DeaTWUuRMI8y_kgY42te&oqZuad*+%&759mYZkNPj_v%rG z^v3L<8zMYA?du8e=cqhDSnI!Er!%HNqPKr66`69K)S`uvAiDm$ zp0QL%y$c(qu~hazbFlkB&E9QLP(GQk706Ndk7dtqPfK?6R3_lYkmD$$LmV+xmC_6V z$RW@@(RwGm+qMBA!IkUx4qzIXTnc8)uqE897tqa`h-uT^d&qW+Zg0uHG0;ee?jB@= zGee)0fM8$;PM`-~Jnm#@PCOt9i2%}leTxY(Py=2dyJk2h4pd&-Y=DwqrGk)zZ)o#3k}$D2cG?{_i%8ffi@qORMmA%V9*?FFT+ zDqO}7xLp%=cLxLgJxvSaND!XPJZm0+V%&JTK{~~ewZHaMLs==6rB*q6(57vID~&e8 z9m&xPC@D_&GZ(a%ywYTv3#S=)MsQ*Q1D?njAuh=s3?Iv<^S4)Ivq{|8D+fkf94d!4 zYQn4ma?UZn#6PQdWjSB4o&5{8w=2tw?&=!?Lr`nR3PtvK5Sbie)@4Mr{zwT=#VpKl&!`0ESZlfrT?PaJ zz2eK^Xn(R=7_LR8p&9P-m0UJbNJ-c2P?(i6l&U6^21D__eD0nQ{wrwy8MXi7VE+$j z{{N``3pf8cqy<(#im?6inn_=W%Kj(PGXM4J4Qew^Y1~M@UHUmWh<+p>a0n0c$5?n5 z>nZgk^T&`>L_u1CF61i>Ysa$wW$)>JQeQ`pG74EH6FP~A)y&jR0M6ku{AiWD5<%{g^Khw zb_jEoL)1R@Uh~YBG=)|EU0L(bAA*EzE^>z3o~Rn6vz!}#j-!5RNn}GZNmbVC#TcRn z;Ry)(Y9V6;QCUHQ;7K@x7yJlP=bV{5XBQoy<+000>RT<-o`{c zL7~S!vM;t?-VyBPEH|abde~G&MLj+tKPOEUl2$3om$50`z3L+@#0#`a@CP1#r2T{! zIr5;MZFO_l>(u5FT%;+$V)GWB7n7Fy0H%U)5JK~a%I^hPHn`KzCWhx3buuA#R9+_v z+~gOw)7)o2;ul_4e)1+6;)~5l?S>cQs>GsqLF&nxkq$o(9s!DUioXfHD0vkLjk2Nd zxd}5|_U3Uq7MS}3b13_nhi1>j2h8t5@n$R5e|)rOo@;JHuj0z=^Q7aU#1G)FZ|u`s zlgYn|tsW9d$NVw7;yY{3pIa~o*ua%PFW|qC!^p}b)1~X+bYk2a=#ScCa*8+gI4+d> zT?osVYG(OV(8UjvQA)x#IsC4*ecI4MAYT@a80>r$Lr9Ygiq%P>s2?Bs?G}?jjT|qR zrU1oO^FyCBhwm;C`w9;yDOPG~I6Mv{nB(;20-13Jsr_hCN<=_P?g~>h?M0JalcBKk zaG*6urgu35LaTFx3?|4DFLOw$5wn6dg@e0Qx#4B+vw=+HYTs;z6K;-7FMn^0u@LgMPm`hg{PctNC3+gs{}|dj z4wgc*WYS5^eS&=dj1(gsc}@RCZwcA%R|^h>ALm0KQFt5k@$$=zIPBWTv~)=LQkcGd zxuli%RDm1d6ry=gg)L&Q`)f;k zOBw3qM-`e9iYv?sS`wZu=qy?B9Har+Duy(^_-tiIj-bA^cRK%wq;xGFhvmj3tP`oy zy#Lb&==1H;DMwlyj&-kxqWWH}FN6d{Ni8>H>43-G2SY<|Y!7&)lk91Dq=a^_ggt|w z=SI47s{W2`2TCZK;UBpDogXTHIM6gsc%BJ1yO$3pqV4 zl)}Wi#Uu@L_Q6KnIj^@s=Xb1Z4Q}`^ruRe+_ednRvc;}iv&D7h373veQ}I|@V*EPj zRz!Skiq_Ckaj8!^%5ytsZDtnwra+8XF7}tRCVsbFHjGO zw?ll$oYB^8tD+&`4_Be`Se=sXn*mFNSKRVPeVBl+4-noSp!)<}8=0u~Oxy5~ z?J#H8ujgFXp`e=BTbNw&l73IVdLee{UiBE8J`2%9@N`Z7iPF`)PR68+r-tJ@Wln!m!y=gqFFKl) zHcB8vJrc7F;=jiiWROD_lbSWEG1@mHA2;qZ1f>LO#zS-FrinN?W!( zQJ{C2u!TO=LKYSPEJLQ;*1a6pq5tl?eMhm!D)_K2qzEs!e|8x%00e{`7;`Od< zJ~A5&N1y%08SO&}ZA{y!Xq97$rV&5?SU&HJEWPUx*PNWCf@zy~8;QJ;`kDDC*Adle zbvj03%vN={OIJ2_@d;#c5);Dan&XeWTy1@F?}`6BEs?W!?~9`)U{#%ce&HJW{Q-l6 z!#absfd4yc$2{6Xu1sto*x5Tu%M<4R7SVrm>OTk33Zp@IP+y3)K>45jB0{oXfHtF^g&Ive-gn0FI)<%8eTbl;}S!nh;zUj zbq*k4pXb~^V$N?LHcGP%q?(5{xz3u^EsDBq z>V7^n;y|Tt?6PS~W>ZOj>lU$QFl7t)p6{$=;5a~|RO-z#2uru1{{h7korUHqlyk@l zOy{7db?@mn>dBt=hZ?)iMe&!Cog`t@IoZ!ODQj~n#fp9x7Md{hlCnRe%eI+hTNe$WcBge0T2#5 z$aeI1+XeBKB6&_1N-qc5_a}eYc~7!%98Ry_!o+G zbOs#r5!L?M28^5RN;6c%;$NsOh5c_OcQJ~=w7%48Qns~Tfog`nWzrzT^V@B6dUYf_3?GLEDpR7|@O2To zWEI61i@mX0nRVpbRfvn5t#)YnGrFY0Z2%V+xC2GF)#yc>6LfR8E!#ziG1gpUA`}n2 z3|0F@z(*SfW32Ino;NICVX@oPyc;jW16@E4swfxC`ARjJ-bO4GuneOmFPAYaORk|F zXHq)}E2)_U#F6JvPJ5frDjaeNWOR5_c=uxHOez#g9L^rr1)n8fSRa}DR(Q{J9%O7S zfuMD=H!cl6tS;-}uC+u>*yF5W$F^*gG>kD)B1oGp&Yqy;BiHWlT5O z_bM9vB)&Pfh_pN76n5lwdh>1e*_PeDjpe$L_LVnbIE~fYi-n$G0pX_$|7q?A&9H+h z#3JT9%_fmK`bleP%pnzYU2M-I|9jamM7Zs;-L5CybRN;om<9)ZJy`$$ofF4w#jVjty~3XhE%GBkO)b{%<+@H%$I>IC`Al zAG7zxQFgrlnWJofb5wI9F86PaW-r55VL^dGEiNn5Z`j$YD!4Bl@e1M?jUgbh0~#k6 zRVJ*@`6qctD4=p1S2?|ER8Qgi9d7=-`QeScBHq$1n1x)29CRRfn7gvZNwCV_9O@n3 zS{P(U4}wn`r_ZL}al`iV5LWtm>brR2Z0&$&z{m;jw?}xth=%1_r}C!$g1dFECu;Fw zFQn@e{xF#`8^4MOnN*r ztj5$!F5BXzOkP7JsesAo!b;dN{j*5Gr2@^2g$w?U*3zF<)|h@MB^}CA%^=AkHCe&q zn^8!yBL8a?df#qrBJ72EjI4|i_;>pGi4!4mGX~5=P-p9BXTJW8=ijC$3>`TW-mL}J zu&!(icqy>-TJqu(Hmsh@#JF;H?viQu5C^M;qooB-RTDMV&f)+`0EC*_!pqHWw77nA zlCotCv%lr0w2@_9D`x!aJ&bhKMm9m}Y1-|orqO26wXp3C+2tRyi$Wc^0TS{*9!Wvc zQNJSv=yluJZSBG_Pn4utEOo<8v5&|&_z_*B%t>USC)F=d)eTcc^;w13P$-38!&-=B zX;qWONRiQ7sUE3_r3eI!LIrGz8QEy0QLVklS9e}FF3Q&{jXr+whRIss$iSaDiwZs~ zC*w}wUh@Sm$HqT$bQOVx@OtyS8DTyf@s z1eY<;vzLnHgJE!0wx7DK;ZHk4f54ZwK}6Vu$OpROYE%U_*zRi3jB>8Z=?TM(J2^t@eQ1_lGV;p*8Iw(k8sPu!EYUIBY5H?lp z+nrUi-uZ0VdzLrb<@c(C%*`@eC2U^6=)=7=e4_44gG`s(@e;%PYTVje>Y80O5pMrM zMxK7ekIr{@G>sy^Emrjl{31uo0ew4x_RgAL*6X>}Q-V;f;-3(kIEI9wI}Lvzf|2~n zy6lH$Rbov{e(@?`d;W&$uvH1Le5G(m4U+_)Bt%siG7&5(?Y%F4It&}tsMeKZ_1FtO z{1(eqB@whr+Q$k2xCu;THogT-?qFsPqIeZqZ$5?HC`;i6^>nwjAi#|YgM!`@GlOUs z+HX1A@(4~#y!X&pw$$<_uQp695N>^b+z&naPyQ-9cv*?|AzgP=jH;)W$tQmI+g>3) z!Sw}#glLEM+4I_N8SHi?f_pvUcCqU!VIcu(Lni&xGk59eYXZJqCQ?QR!207tw<*S2 zCf_w4)QO}vozDvds^)6K))%K6+zrBTgI^UMr&7_GJeoS@T*fS-^ni?sSjQ|;d&7pA zq%0OEpiVs-_S+iLPyO?More6)$^RUQps%O6NBN3wo1y+^iD3UrA{x{->{gk+thTbo z3b=YnJQ7iMkEk$#f_(Nfe%?nqF+j zG8Py^GeK-k6T5gc)8attqNqNU6jwU^k5WLOdP8pkiGGjkgaaCwuTFfpH>CGHig%5U z8h8f4NLkqqhccYm2&hv}U8!kvU#4A3jIG&m(O;O^TWTn?1TN2c@`1pq)C#tDI!*9l zASf{`9tW&R4VH_|JNHjT?)=5mLq;5|XI^^G&+{l@RZDz4I6fav&f=ZHVcRRzTh%u5 zybYxVH*kh&yEAZt)iugS=2n(si;#i5dX1^98T!TKDT_UJAbx18I;-yY4Eg={9ubf6 z(t)x+iB$a7{own?bM~`5R;*lWs+9_WM=hK)Vt)8a?b>k$^go*r&tPS!amaIKh7Xag zn3jYHp&;#%g4*5*ukNsj$EzlhD1K!9vdn7eS+U4rNr^&BqPV5MKtYp%bhO+e_l8^Y z+uMo5eSCIX3>CSj>4n#op6p55=wn%os9Fv4v#ooi1(7m>=Vk>*x3;yA8t;gR=K0_z zhptgBf+u#p87B(sh>o9=N9r#rrPgofG<}ZEEz?csvN^`7!?*?nb~hTc2%G#kz;rj{zoNsPF;M8euBS3ZecjHDe&vEXIW z;ruoy3JM;8sUBEaOow+mwi$nmRl4!p4;${gV4}d3&d0qKhi!#hzo{wj z4bI6~lT=s6%ky-YJ;j`2T;IzvH;d3~edD@H81j0J)Cl4EpU)8mPtu8KiMTz64p^z$ zy@Q)XIAAjd4mJh>it?B%G zTK(q`?5^x&EikAdbI@qB>)j#)Rg(rB3wli_(gS>_@Q_x?~E4t8INf z;dYSJ_nrqEN*Q+56MNgNImVTSKvrv>62ukQM#e|IE$7LF`<3U$%5r$*S`(M`Tlw`& zF^j>QIEJB)wX}I??0dQzJ!^ua%KM+bzVV)~_MA;ZhHU=Xe`|EP4SeT7hS}9c6q`*q5gKqwm z?$?eDZpBBzk`PA$KHA6{_DpQHRDW--B{`zvGI>0J{W6cBX`-s^LBd6}O?VSW%5`_S zmAV4Yg5C3ONP#UIceTMa&U=tJ4NWDg6JqR5-oS`y{84-lgQl@obH2JL?;qP3TTxp( z_?u6=Zs8ucbLC_g-hN&;0D)nlICWRA@0y2`r96zS%0XPMd=yaK&evV(GQz0o#z;R3 zlxmhM)cR<#eVSOMb>eKQeFGU5R@NH|o1-(;z!O@}!d))o##?GTev{F8hoENMpC|pb zyRO=g*ZhH&oh^Rtj6^w?f{TzI;lS)I=)P|}XO5&CaZz6PR>yXM zKb)QchVThT$@Qnm9EDygg8AIA;|3Ci3tou)zR2rfU*M&Lp##p~ai?X0xO`6Q4v7YBFI<57wU&HD1QcCf;yh7Y@Uh$DbIZbDTMNKF5mw; zd#DUEl38dx`y<_*bQ4w&{<(D=EWZ3ZC3e}`5{TnN2GpeVt$~Lf&n`#v?2U&Xnph5I zBeRh0hE=K9L^B7y5`giyzP)UGw<(d+*LfMe`bLRN-RT}!u4mByEhYY*D*ri@m>3OT zsQp@+_WoZ)e4Kw#V&W^}%VWptxKw7k>s1E>+hweqj3&;RORdE~K zW{d$K!?6x3CgudGcyMYMvOjs;kNtd!LtmlSisf1Y6B}Td`JUydr=Ln8W8N%!7Bt_C z(j^B)kBq5*JU>qLLQy={TTeg6B9ox*#gqAftw0gaJFrBSk=(os4?O_BYxHcBv{Y_f z_FBDw#v+s_E})O1zu-|EUnD?~+*)YhLd+fDM^2(JBvzrap}E;oWCC77 zKahD&U6*#glCa%RJ;X__T8Qou7(sCN0Jw{(OMftTmp4%uP7j}}V&vmZ@s0D9uLw6F8n#?y2=`9d!1I!wvqJPvt%Go1mBL4l zeWCa{!-JC5{edz7@~x`iB==~*obYNmi4hFx;h+xT$zlu=kI=&xx(`%u?Hb$-sU2WH z6r;_*hQNC&=fjh^as51fOfTuty`;@AwW$5;D&W!GC-byRF6MLS*&!9RB?DELG&+k5 znfE8E>Dv!P;L~d46p8a*okLfW54;ho54SuI7hCX3N7P7OQmAZe(WR@wFjA}`(lPjW zEWgVSD^n7c%w*1yBIoeSL!C=nNG97Yut|zjBj7^;{C4^H5TugFMw$yQl@y27;hRG| z#cv`-b3*!WLcX#*T?iwJtySrO(5AFnq z;O@Z*PLLqM-GaM^uakYxNy5&4zjMd^b>4?D=+O-|dv-O{>{_+fTv;w>>zO1BWdmTB z%Tu^qyerCeOcKb)9;n#sxU!Li{%?@xbG=B$>JJ(Hd=Sa@bB&qLq{=F6%fCIGj#cve zK6nOeur*d<23{{RFE`Y2jfxT~qI$UCiim;f8FcQCbBKlQV2AAsV2XE9y4bW2mqG(E zyb7Pj8#q>X^#oasxQ}O+r_wj-W>8XUz+f_wZP(X`*IN1rRNBU?PIwECD=^&1JG=iu zw5;5-WIAnBHk>-v-$&^3Q3y@47?({|+gV3;0eenhqZbvhw4AgfsH>wM}dzX`}fvk2CV*g^u|T&SVylhbC)MjcC(>V}TbUn^P)EOsxik}S-LbFg3Fu`*z@C?F`o*|B;}v!CADNIKr4B2Bow zTAHeFdjPL_d(ebFn`u9bQ)#PH6*Zg8pcdc)GM=tnQSdkcbhhAx&?|qS-}Gb;uiUW!jwV0`wVnJOu{};B7ce}JRBw#ax}Pn z-@QE`nyS_Wx*cZNhyjv6v?x0~!c99|%KJSLOW*MgA4y5uXqi-+QK>4u7(rs6}&9xo%ZCMZg|-*(;zIIV?OB@<5O9h|Ye<)^1AgfO6p(cY!@Bd<~TRU$dEO9r^(h ztt$H4?KllzglHAEX4~M}MRyM@5O(HBm;)9$a$zrJ8lxe9pRiUf1SHt8; z%I<0LqAkcf4e4;RA%#644G6SF5iNFl4@+H^jy06hsmDI5i%c~&n{{%-SvWEuVXaM; zIZeJLk3`}ibwmwlCy|S^E^i`;+n@G@M%`os8>0zDd79bK4 z(~CHR6)zBE;S_|zY?9Q=GHXavL09WN^5Cwx){>PX zd2zWKpA<*yX-u-*8TVTBjjW3zcN+_G8@W&ztt7WgIM8kRmE##1o>JWG@&Sm;zK%#Z zcDwtz3FW8s#)a@aIF+<8k4czHfBal$A}LjVIS&H#=B$et_I!FM47SV*7v<~a<%bKg zXf}r90l6|bkWh`cgT0zqB>kBC2BI{%m4W$eUYgJ7Q&t9zT=13|JRr?<%Z^aD;@v!$f>0GY zh7e-d{vg6utf$`vTlC^Wup@wp=7l&+3)?4|;h@~9PhUqFq&{s0IJBur<%V$ayCH8aZ9VJOrlam%NkMd21^tfKs77y}#TPvP(D9C5 zV9K1;ON=J!7rHJ51X@S7wSku1Vy8QV-@}qvH;sc%yA+Z9Pnn~dDBRA`VjAhZw7Q3Ca%di> z)LRbUg4fKB>Y~A!#Eze&!j~&c-;Oz9X$fKMHUZs{nAI|lh1Bj1Aozpbb+XDm zD1vRJ!$T^vO0Dmcj$VtFT5qydao2xe&h~eXSH86il&|;5!Po?HThC)@&_KM&-!sEB zmi$_zpK*U`<#Z^2zScPg`S>F?d1>1*A59n8ACy~x_fUU;J;?YiC$UT|ClFoQQ6;qG zP_h~|t2oZTxq%gSUd%!GV44v+K+%a8yU#k!Pm|+iL(?9Wc9`8|^uT=-P2A9uW2$D{ zI7cJfnUO!j-ATId|FD|svR4W&!=rzeUgs&S6y;&-iS3Uy28l6ZM?8vh)2AXd_CI)Izea!~> zm{V|u38b}TR&tfe^uz*GJ0}yO&#*)uUu6g+BjqJB=hYdIcnh?oAKgb#8`=&W()jX= zN%>^)ssA<|z5&)q(HFxOsQ&ljyI^O-`;~#~y1j-D4Mx zLBf8^#Rk%6`!?ukY}0;X7HHTLQpg~f+*)eQ3lBAzzo(RqQZllqt~(aDZoy&-7Eya3 zj}8eOmU+r?O)awPIFBi}JREp^_ywWbAcVn}(uSTGTPiVJ#tnA#{t&!;5%AJy=)S_(y=_tE+2rqxz1pPKw`cVRaVlp0`0KQ_RlYa2mKvOjtgUAfPjg7a80n<&(Wcqn0kpyGbf^ zUU3aiFEQQ(%U0)XlXy49et#WN^G%hkKxx7AfFz#afeCqESqlKflCZIK&4L3^PO&09Ht<87e^--$S{Wcp&8kazp>D9OkuL7rV`6^V%P&hQASTpiG10ili5DPtw)OlzNS>AXxb&SGd+P2 z^0o5>M1gh$7)$h(<+LC!&P!u9CQl`%H_io9Y}GgKDeQ9w;a--zXOImNR!EZN7U=Mb zRYR0J_s84u&5DO?c1q}= z6`}2X6O`|x(CUdiQFQwHlzX$wXp>r9V>I>6s;pGAIsEmzsFumdW^N|WqUi#M`Y#W2 z2U@}^k-4lOf)?!I8MeCBtPueNE4_5Lo6%v4T_=vSb3>QlE-|4{rZE+o&5dD+2zlLJ zBhuQfG@qzO#1)adx-$*=kD9^5gUpkTiUJ;ez))#Img=(Tip&dC=fAkh%&gjo#r7?W zRAh`K)iyA>yCE&Z#*uQj+afjDnG!8IzK16(|HxE&ItOkl=-MTfLCXQZLVN9#;wYy_RG=5gI;9Dnj#3hcL1@axOgbc_7YE>vBMNQtkxoer| z?QTwzcEr0gd0SBkE2XW7A^T>nu*T2-bZA9Q%);&(qKtN+8_GJy7muWkon#4*DUPD8 zi;=O0Ut$vA;}Un>dOsHz>%$-}({3rIG$wJ$NiwJDYBe}u8!4?Z2d)f(eTkxG6f9ND zw06?Um?FkaAy8)}0vtI`HBNP;Kr4|=+Q;11$R_Z}F3`3FnOc_xa03cZER2vGczTl^ zGAF6qYAEeu!~Y1^==%V5ELw~NvZSzJ_7>cn)<&kx?-T?z9=bL)y*N-PJQ_R?v;0LR zUv6>dQ|tO66LuZbS6|S`GuknN<+687cLtHmcTwgjn&iDN{V~a+^!;qP61=!g=y=CnPrMQe^;QWCre%_eencNg?;EM#WSU0D*1uKl%AkG@G z`YZcuJjlKj2W=ejLgHZoa_Ny4L<+j947CU%STv`oYWX_Wb^@ERS)cSuuWLo?artAG ztP=KhL+=>R;b!@&`Ae8+n180}dwaKQ;Oh&Yif zi8J}4IidI!(g?u%Zog#y{e|_3iAhcEG*9MXc<}}h^uVu?kj@h4;JgU3FIfsA)jM35myo&#*89Gdnw#DH<^gDh; z1I7Cqk>|a;R&U95!t!FBG1{|fLEi5hQts8Ckcpd&;leH#i7PVaFMg3+9@PE~ z+uJ(DcoHcD&wC{F7MsL^XFEZgQscE54K|YuSf0yJy>;g5z^+2VH@>vq{U|Oja&c8C z9UXfjp)MJ*o$k)aP{Dob2aUl&`x>IYK0~pkdgpcR++lrfI2^QheXcZa1)sJ+C+G$XV z4ps0%aYkca#GHYx&qOsma|aFMY#+Zo;e03YHFl0M+3XNn@(_=SK$&Lrnf-S`Pp;W^no;B28O1BnXA)N%D|MqyjYYX`Jz zAB1B*O@VG^WkW41t0g|cm{-QTAPUM`yu*+ffv8YV!fuA4|!DKcamusuvy&>Y}__^orn2A~ZcIfAkBWwF_m`0Dhob4(L+!w`9dZ372;8 z@YTgxU+sGz)D-6JNO3$B2?V_%25cArvumlHaLbO^l1}L40wxseau10V*yEG7l}?y1 zTIra=Ah7EUW3(0mK?Fm1vLiUa@aQXz_)VGZ>La5PyB|s(d7Q7_YT=?k`6nil1~D|vS)Ih^3Z8-Flu;0}babpG>;ge0!|br!j3s-# zj_in#J!@ML9JV3ZiO%)<)=h1g9`lS)MOH+wn7bZg!7#+Qw9uYH#TlF2yHI=?RKDvE$uQ^qh| z9guK4mG+0P8B95gTRez^B6L zKplfi0RM0Un`7fi!1Lvz>)W*iMXR~a!$sH94Pme?CD%J^Sm8>}aGl^+y);KRwByY; zCS60`YMo;5712pJJg|?L7PA{2c<|Vis|IlUT-C)kSzRL884W_o&VlIPMB>BAO%F73 zH1PU-B=>=Al{Yx|nU`5P8=q&x3SY2Sw)^xe3LflO3Y7iq4d=2Rt;j{&5=0@`8w!IX zj(nsZut8g1qIFwVoZS7ZCVZQ9jRQW7D^KYHrg>W`U!PhB z)NGPG4`AFLsR}ycq@Ey-*;r1wcU~jKmGR4y?=$2or!pGX;kpzhp~ z#FBcE@;!H4{Lkd-x0=uYe!2SM5ID#LkgL!Cu<7_wKXsTgYV$*`yu;tXUy@CH+ntTx zBD7y86iCCYj=&Gcf4>x)#F%U(QQ_n8Rro^N<2dg^@+Ijd%5X)dn9T%Gtl#vJg9)dw z4-0qcMp1-DCv4P~R5W~ziw6)TjEVyn9^QkS`<0s;&NW$;NMYbvX;EU03WMad=WPy}NU~s27Zw zWD<{FHtF?>Mq*1n0nvS*TRf=BYM=m?*RVd{AV*oVE|l=il_#p-(a~Wfx(xXP&xTMS z3=3WsG$;$XSb6Pb*!q#*L!i~$q zm@cNQPZ6M5pfuk#E8a-l`!4LeW)<#vS>N$;4QwhC8l|h-WExoad~L#y2rGVMD5s(o zE3X5W_LUJ@gn)+$XrwP#9m$j=wycW-hO7Ze5Yf22UN-JZ z2_?-W?@P0;Jz2-4Szg9U<%fwEEHuq370t@q?4SnRjtOrk`rlv1YVy3^n%s}tOEzPY z%b-SLPZ`WrN-zszvCj%}#?WEX+O;EuBQJCyNeFynWXY*+czbQa%O4f z&w=K$l_fO4pN}Ur9-p=&Ol$%jk&$L_&%{I zti3sYxH;E&t!7mt8~k-FriwQCtvFbI$jGG1#S0)*^tRlHueyB_uF0{VK$)0jS|0_C zHmkBsZs|$(s%E)HUPoTE2zPImnvlXop4?*%>fRlbs3hqeUb0b zX=yzbsY$!An(9C~p-$O+siak*2eL)Ys$kINeLcC1Q@l*Cv=qX?t+hhDyP&kU(h`Cu%rS9?3eLne^_gL=P zSqR|()Q-Bz?Q}ZuE_wI{KeK~kNpM*T% zA(xh;;-2VuuLlD-EaZ&SV)vD%OR7)$j}=afE0;#N>H-&@NObe^C`}i~xyi|reOZe^ zs32z~y9=GtF^JM$ZfY*1m#9eaO3kY1%|>EAjN5s5!`w2KD#0` z!w3T_!$L0jw5`1_&S=wZE&B#-xWC>Pr$`jk11;NQ=SvFAQBpOsRxnSQ^M-+(g$B?Q z1T0&t&^_t4dBH9nXNDL@1!DaYzaV5Q)V%La675*4Ip4!fJg<@b)tQGSyw0&$I-n3i zj!{0;g`){?ScozIybt=TIyGe!5X}PYgS^A>@V^Qh zo{A%raVN1fyfS5u@55fm#DB>vKqyfS3=9TjTwKH_vQlu(CzX{C;~%H=F>y&^Pv&KV zDJAk3Z9NPE4C#yyDX(!&WYU$wCj=M6;QgSeYn4#*0*-AN5JDgU5iKl0L~EkUKQ#cO zNH_DnVGoOdv3~R*Wr{{=bkF!WRcYv+#7D5JEv47J>v{CuGV$E38mEk5xvXUpRQ{^E zykffMCMi|D>mtW2xdetH+wPKc(vtho*6t)}r+x2JlZL>GcCp&lQtvZSzrCC(qS*W* zp<|Lvwlf+)Pmb{;qGdPt0KT>-*+kTLmZ5mxr#9QjibhX|<6Mg6=xT5!Rf@CaVSm$D zTOG`d18xuGuWW_NxgaY}gYHqVO}?nWz=y~*1mk1%Qa!D`4+>e)4&u}z!81f{o^hz( z@ZJ8kEoDfjjcSm6NIX~SnS7_b?ttFBBb>s*QiiK>Ot z;!dqs)Qqsw4NNviB{RLI1Hm|=&iA}pYBx5tADQHDT^-riuEh=5dNA9b^82Vtf-HrU z%c%y~3sEF)Fw%TH>IpA@@DQWf+SK1l6l1ADwcIK}Ra!Cis}#RFTlPGzf7x*Em`azi z4CWh)ZhafHISPUzScI(0YEiFiYI6|v$_iiEQ4p>hrWzSKJ=)HiQ_J9X%+4j*ZkbqO z#{qtDWgN`3L_N_L#=HZ^`Flt!4mLIgPHTe`i@YtTpY2d|f^j}-md)9+lP~-vlRO1v z^ghjO`?XBwG&-ARfX+dVo8z%GNm2FmgTEa7glI|`(6@v}$oTIeEm{gdNb6v!RRaaa zkWSP7aK}V`C4mLP_W|B?hS^Yk`^c779Ww>cPEBscBTBv}w=qoA^+^r4KrzGWW9}>g z=|pmr=);PkzOfiOH_G@5X?CM8$hr>Cu8nwh`W58f6VRK(2!gEECp?S}3{bLg87ZCl zI4nYCX+uIe!uSd=7QCiTYY7w!;9=nr93_5GCDQ_M^@Xque#grqW5(h=ZWB0{aM*(c zU{|f;IBA#`bVjlpPJJ05bf5XrDuD~}@9bM}mAOq?a*Hno+~U>nvyZYmzRf^G9iSn@_Hdc#F%oi$rv^;dXS%Gy_PxeXz}{3fVRN>@Lr*ip z90`g5`ZV5%-%4e%Ei$3CT6cgNz^*@ayDCZM0H@`(myBO}jMqn_o)&P$p_^Nkie6|+gS2sKFJTCo-(jHa^d znD%wE_?f)N&uLd1@3UYVC(>X&4mqYU1WViB&g=?mFpyk#kd)hQMRvM{^%8wRZzgZw ztw1WSwD0$XfBh{UqV!ap2)P0wx#!ZIed~@px58w!6D_*yLiBU~2}w`?Eof{N*E;|6 z!-)S(vwo`z{_oeUQ2Lljae!v60-}|FI)VAC5;*N&ngtDuFfGddL>jI{XZnyn$QsR? zlrCKa845-gEeHfIFn9ovECGU?w@DOx{!{WY%?&7unUZ4LuvCbxF!U$p&1$#1qrzen zkrIgx>{iVoaxh5fr<}&|`uoYP!vR%634OGE2`tQ3Xd?B?xKDPZ5aE3<5>l~Oa{&G= zuvVI)uj2Hb2f+2mlkHOV;bgh04a0WySo0coINxNhC8)!ApJICxg%Qgb!XexxAOQk+ zJd%^48RwK^ovOwn$QsxxpOq>1F?k}ySlMS!^IxtEY>@CMWE7qnOPSBb#Ghg%ng#ET zx6nS(-ro#VgvF8)#rjm%?P;dfBqt>{#RsOyTV1J!$1=7tK7`CgiJ0@$X~8gM#O4@V zCF8*`wJK5be_^{EG$oc&_D?TtE7;R?6Br>+AarFLiWjD}rc@m57ba$L4B`?+09Y_6 z=zntAyABXTT6E%VJcf9z2qNA+xV4$pl=-ZrDN(S3{Ep~c-%QdCdw8+G_G4MO=sVrO z^G^E@@kQuwm>o?P>q?Kl%30e_P4a6iDD5r9fsqg2DDu66LRXIp&3i%UP+lM#!>$Ac zTdQ=TtEx3nnPpaR&{p{L1MLdsfmFCxhFF;`N)29tf9 z<+v7RS+7o-t;Vg=kYrQoHy{dOJEW-BK)$1mkp3jXEr_IDNVJ24kKXjvVjOV{y~dYT zcQ-at<0(5Q6*1r~6e5%fG^|0_!INSNuh(_^MT$NJt{|f1e1`HsLwW49Z+nR%_vP|_ z*+0yN0*toZoP04Z?82D*1B|29U@s(J5BVEP)HL}pQp#yF8N%e0_dVsQyECb~tOOK` z6)0E!rl6ul3+EZfz~N6c3Lgvy>?V{#4a6Gy2;UoyF9Ab5W-s{SgAx$l;2ZRu12q+G ze?j(>_x%>Y_jt+S(T^OKnB<=C7z!s;s9y3JOA(ayY+?7xYf9|co;}(gM>|7sXoJ{2~e)nN*aFo z6vvLtD5hM8G=p6etAvg14qHi*#_UgFfVCS-vJAFu!X@zKZBRevK}hBAg&k^Yr7tjtQNh&3vT zV9KBdjD(~KRcd4GNU9tQh8Y<-~NXFVL1@B;KL) zCL-t_&}(^RJ)a1iaqQ#Q_>g-H`DpeV>Y0yFX--^ij-sIS;Z_?I$DCai#^G8jK3{h4 zvSz@sFR8^2F6B3_?q+X7 zhiGUkOt(6*A_X_q-KBx@r+IwI4U(U-?H-O47J+sxtU|NfhN!rebET zQsdQltg`}j536(Qnvc2w%MK3`!_6dp*?$3x~Jc7HR_pMzdOGl67c5;VEh6PvG9ma z%E@^E@mK}*S*ulfo+qyc$dlQE$}26YO}6 zCR9m7;3!HB%;$+%^&(x<1kijT5uMl8B5z zYXuNScIznjIFFw{4(K9ON>9-NU+Dxgpmm|XUr`pB@c20NIFxN-ScTq7v;5)e;~>?C zQeP1Y5+|f}a6kTF-V|K$6m>}o(k`;Oj;8mhOm-zkBo$vxSv+^R$YbBXA}n(l=b|dc zW3M0YC(3CI4?GHvLA-72suJtI>O|;PA-z%TXvJff*u5qO>%oW$>?C@#6cuhi~(2VN#*73K8G9OCfSF_TMV~p%a8zDTqm6*WpxrP zROSL)MYf#cHqloDh%8ciskyWIj`0MIo`^j43u*YB?ZP_HWYlwfbtKYo?B56(f?Rg9 z5O{-62iqa2{BjXkIH7=N5z0zY#0(C`*5`yUGsR}i4h*KzztqvZ_U~p*P#H=6WPXR4 z!pQonVmLEi26VpIJZ#ikb|iyRu)dFp+Y#VQeRH$B#FpDv(~SYbrkRx@cilSo#emu?HZrD-kr6%wK71~V(PBegt9TeY z1|Pe@Ds!&Y8Yx|r_{|vP%>KCd%KZK%tYz7m5ha8J3|*1RZnI~>b|tWSbdHO{9 zEEp&lVAjfsDbRb$)T)d;5FQFO&Y z98X5SfU%!5&#=QH)u%!yP>AwXTT`Se&nyiy+^1%OfN5X$Kb?#1Bh*_lQ!mHG!&xfK z3QR$oy9vr?HQcq#|!GadVMrkt9bPgcCbh6iLSks>t8SeRAeqTO~RO8HTYU_ z^q^lp;1QkP&zg?Q#5JyvGuQgnm3!5&i{Hj;iV=l_HK*mASJLmmxJ(kt3BYTY2vqS& z^cRDYPZ2_)IAhfw@Vgr;`?J-_L+M@(2UN@hk1z^e7&sY$zz;gGJTc+IJ9{JeodmHvsjZvTJ3_r-*R(W(6T{0oj@Jz`2J3 z^5s|Z-5XbvTEi8abfD3_2hm2*vC8WST|)~Wo~IXnQ4f%Uy_(C<<9?3=5k6lB6_-pgyG;0+&SLnLU%1S+Ok{{BziuY~{_&e? zk657ZSqP*~qvL?HA zoBGJ2=4!~~{>^P3k!_Px3i@FmqnCF?`1`_Wp_3+9QdP+A0F|FZZLe7Lhrq-+YYyUe zj`*-SW?{UYB;X@AY57ev?)~xK$~6a5t@W%f`ud;jGHSib6BT5+pI3X`Xop76gX3I4 z<=oMGQJ|VUG;MHhTZDnF#s|9&1V**TXxHxjQH#zh^5L!BsMkYSxMI}0_UvHyrRM=5 zlA#=tPJ@Fj3Jif5+qwO#-N_|;xiu3^5#XsK>^u7vwE+c8ic>;4$R!}=vV-~!8|JLS zp!&(a_WT;KYeP)41KHJ0qnBCri9_3>oYHxeTt5=%UK43I7u%3pMi`=R)Up*tEqQ9J z8a3PB@VQs*)`-R#zfi=b^~!DdOkI^)pntF5)BLSOTzX?uf1@DCRy{n?elT$AnrpQ* z3Fpz|V)Xs=n>Mak_rn7*H*t-+t)jSlaB|{wiAA&2>Cu;th76fG43xftFx~wI#i)1T zc3YfUdbh`R4H$MhL=qHd5OJDj{*GI(w>pI8t;MZH#$(e+y-7{rW;x~VB#Ty7(_C`j z6Il1}hqs{Vxth2YLIn$)=Mbl{(-cP2L?k(eM9mAIkEU0<@kS|~BSFsf6Lp(Go$MUo z!$yNxm757NYsGEs?@OV;U}$`rcK*!ac`*#O#RA={)uZd{&tOuM4Qd6cbi+ga za$mX5RsJJk)VdJ~TBZ#{Si3d#dZnnSr6okmKCF|=n80F~=iw+~-DewyM|i?7A0AG_ z?roYM`d_9qMmQ>(hZh^u*XPjRT6En@jYz<$`e!O2+7wFn6<4R2*~m+^$Vpwp#7yot z?z{~xva7DOQw)fyJp|q@2aWLwBh5u2O9ys?Mth5ZW*7-W8!%iuThs}=8fGhmijVE> zH$Y|Trch2)dXdnOcH!T=2qJICruC|1;Kf@e)oo0bZ{Hpf^oR|)TAZR$@lST!rNvQA zQ~H%qO_0&5HsyTp^(bGOH1vhXZAVSD4w9KL3f*b-WeUOR^;C#MoPyv+cs96qB{-yV zVT^S54(1=DQ{r-sq-55u=3k{@z7Rx@5s|cAf$0s!K%fb6qqV=O$1P4>tzhWf^v%|CDz5b#drg$J6#D&)|?_bL8zRb61a9(3R*Xm>F~I?JnxUj@1tff2#)wJF2Z8$ZP~eHX)m&3ic+YVKH0U?p7)txq4y zlrVuPyRb~cTSn&{Voa;t>KS;-hfWf&ejGt`sP;j7Iwy_hpLu#C@QFYt)3iI)}x4&bf}Qst<0VIbV4*B zTj^|!z%(g5~yw=GbbjC4Tu%oXhPA1omRJcGW!q`y-xsQQz-Z|S&)p2Cz)QJR#S!c zOAuH*gfW@Jr`e=6bW#kU_+ZZ6BrVxcO<=bU8d89}3X2(oMXYdWy({r2WG2C0v2Yw^ zEg}21@MM|{jSz6AQPG{VmrJ1wNMrBiYdA>t*&qvy6QO_wFPdTN&|R2zPj7?roov_J zKhA6-^v~dg*cMKy)xPNGDOsXP;?8aQyj3?t_%71TSAzZ3y>c&q5YE0#Xc1@?36Ft! z=8);J_4y3Fa7NUZ!+7g@MNiG__7aWEVHY+C46fXaNBTj3wt%oud3SKlf;0q3o19*$ z{UEmt4lVqsF%^kXwi&ey_R0dOsGhLWOf;9?=1>BZfM^Rg(+cU6WUi^3#pM{Qx7(d? z5DzMe7Baagq@sBS$!+ypU$vOU`(%}O;u7(7i|K}J5pEM}Lz`o*4ZbL1Y~ebE&oHyW zHxq(=&1JfsurY-yKcwx2(WBY`1NK*V+Xe$-hXuRp$IQ5a34+9nfAWTa4#Wez?k0sh z8_BxZ-6be*9V|~Ul~=-agSwdOE3|1|2H_x)m{RC5kCNneJh2iiL`}@1IC>0n9eTX` zY4cV7<(`J=hW(5HW}ecr5~J+^+z#2yKH}?JEy#B~uG0sr&Rj6nUU4))$f|^W8L4Hy zy7%{aC`@+}*N-7A*Y(1eqhE)!)*x^B4(@N`p&)$y`NQP-Qy4iq;uKNZ`N$Bcr~-`O z+HQtcdwqc1yGWN+Xgol098mBzp!B_`3#fNfVym##| zs3G*-7N)S_bb^_T-nh&xs^u9Q8fyR9XBlB#rmLA!xy*eC=s;4{nop@i#d)TQpKMgU zkYCh{Q-6+_L53|y^M=!zQ_y4m#FldMiVV{Vc(x1+qG-idK`TxWl~m9QeX-Wh2XdO` zE?4-rooNmdncbbK^FjCI)60~qa#+w0^uU`Va$n9)iRmzmn%aKX4rD z7_WC;kY?zpd7PeI_S!$pJpQoIW_c}6aC~cY-2Ry5bG5Zrc^8e#JLBuMdck4Z{&;lX zRm-2zVRt&aLjU-!Kg(B9TiLX%U@AydPfdt3x1a^HAqe>*Fe|1KOJ5_`xdMx;T2EUe z$$cXUudRn1?d7Ma5)6a_Q~7tij9Wa3g_Nyq`gl*$>RM_-v-SggLCxFFtLM!pEyPCo&d@0z#yogfV?=M7eHSuP_;XNVWVb&0qqz8EBp73%>TOl z0FMCyX$so{3gv8^bd}xhj2*SV7yCX3IECXl00R8-8o&b#P%-@P%MbVk;E}&l;(sK< zKOY!@`mo^+7`OoVH9&8Me_wvUOn`E|e=Cfkt%LEOp7-5&wEHn&xHX`-2=U*8fq?vg z=KzoVd$_)x-JeF|(x^`80-o3r4hZP`Wc=&$1HJ;pF2A>>wsSCc1iW&6Cv#hyKOvCX zP$-H4oZ$LZ9@55cpja~n7cs#VVGZElr@8CV33~~6shC7)VTN?w!9`OA~ zWyACL@_AqHf6a#D3Ghb# z8{9928-KOz{#m~99Qk>l&7a5@fZ6*u^1oU^{b2oTzrE*pzxu>{FVOwhG!r*|GNBubt(P;_jjh>LH|hfc|WP2$a;W^ z-T!G$f8;IyPgD9kQCPs;zrp>D=+9*6=g7}{$^0Y=2YB!PhWyKn{>X!S4)@P9TFLYW zxW5tonOyfA`FTf$pG2#e|A71p(I3eV&*A===r#Kv;QmJRXGXzGqCfVm&*A==Xq@OD;QmJR=SKKB@^eeTpG4!u{($@o(H~A(&*A== zXrS~T;QmJRr~TG*Ul=>PeK~jzoGpg^hb62XF^zxzd`&$ z=${qodAi(BLhw$%q5UBAM-}>KLZR-zLHt7KpOxo%Ld8!)-X6c9{UG#5wfSd4Q+~fe z{6grT73TS=)K5Z#Z+=7jLFkXF^3Q~{Lw") + if end == -1: + return {} + text = text[end + 3 :].lstrip() + if not text.startswith("---"): return {} - end = md_text.find("\n---", 3) + end = text.find("\n---", 3) if end == -1: return {} - fm_text = md_text[3:end] + fm_text = text[3:end] fm = {} in_multiline = False for line in fm_text.splitlines(): @@ -104,14 +112,26 @@ def parse_frontmatter(md_text: str): def split_slides(md_text: str): - """Strip YAML frontmatter, then split the deck into slide source strings.""" + """Strip leading HTML comments + YAML frontmatter, then split into slides. + + A Marp deck may carry a header HTML comment before the frontmatter + (e.g. the REQ-372 related-artifacts comment). Skip leading comments + before detecting the `---` frontmatter fence. + """ + text = md_text.lstrip() + # Skip leading HTML comments () before frontmatter. + while text.startswith("") + if end == -1: + break + text = text[end + 3 :].lstrip() # Strip YAML frontmatter (between first pair of `---` lines). - if md_text.lstrip().startswith("---"): - end = md_text.find("\n---", 3) + if text.startswith("---"): + end = text.find("\n---", 3) if end != -1: - md_text = md_text[end + 4 :] + text = text[end + 4 :] # Normalize slide separators. Marp uses `\n---\n` on its own line. - parts = re.split(r"\n---\s*\n", md_text) + parts = re.split(r"\n---\s*\n", text) slides = [] for p in parts: p = p.strip("\n")