From f55f5122c359c8586794f2c5c49dbafbc5f5ae13 Mon Sep 17 00:00:00 2001 From: laurentbarontini Date: Thu, 7 May 2026 21:52:27 +0200 Subject: [PATCH] Flux correction --- .../svg/parcours_fraction_support.svg | 6 +- .../__pycache__/curriculum.cpython-313.pyc | Bin 1819 -> 1792 bytes .../app/__pycache__/database.cpython-313.pyc | Bin 831 -> 866 bytes backend/app/__pycache__/main.cpython-313.pyc | Bin 9331 -> 44511 bytes .../app/__pycache__/models.cpython-313.pyc | Bin 4812 -> 10431 bytes .../app/__pycache__/schemas.cpython-313.pyc | Bin 3168 -> 12334 bytes .../app/__pycache__/services.cpython-313.pyc | Bin 8275 -> 17078 bytes backend/app/main.py | 2 + backend/app/program_content.py | 66 ++++++++++++++++++ .../svg/parcours_fraction_support.svg | 6 +- .../codex-2026-05-07-fractions-kit.json | 16 +++++ 11 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 backend/contenus_pedagogiques/review_updates/codex-2026-05-07-fractions-kit.json diff --git a/Programme/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg b/Programme/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg index 9295ec4..1df1b71 100644 --- a/Programme/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg +++ b/Programme/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg @@ -29,7 +29,7 @@ 0 1 - 3 - - 4 + 3 + + 4 diff --git a/backend/app/__pycache__/curriculum.cpython-313.pyc b/backend/app/__pycache__/curriculum.cpython-313.pyc index 773605b380ed9a70043a6184bfaaaa38da3d20a8..18c59751cfd61d8b5118f0a232631f66d431dc7b 100644 GIT binary patch delta 40 ucmbQu*TBd7nU|M~0SF>CzRow_7BS-jc2*o)W|7-HC!7)(J*fB?v2 z2oiv>kx3LlJK}qbAQwkaj;!##84@fL?oZhlH>PO4pzG?2>(#KnF<;sY}yBjarb y&btgM_ZckjGRQq-;BMi4z%STe*;P41?t-TMWqyYSo`;-b6DEr@tFTA`^#A~!H&yWf delta 298 zcmaFFwx5mnGcPX}0}y1sJDs_9BCjN4!$ft>m>7m29*`(1P+|yX31&5Af`}He$1o`| z#IOgm1+!Z+6>-F{0_8b^Ibt}1IW3usIAd6p7)+rC6mbP}Nih_0r!#7DPdsM1nU9g1 z(a}ghH?KrLC9xz?zaT$Zx1cCLO}8wwsH8MCM?WbsIXg8kML)5i0IVV@u{c$)pz;=5 zdTL30N>Y&k&|sd)_Do)kJd?Ya3`2p!sd;5ZY(U{#Y^izanR%&2ARpXfaRTZDD__a* z8RVKGevmMSO>TZlX-=wLktC4I2*ky1K;i>4BO~K&2F|+-D)$*IC#y1BvPb}h0nfxl AnE(I) diff --git a/backend/app/__pycache__/main.cpython-313.pyc b/backend/app/__pycache__/main.cpython-313.pyc index 969dd210b7d6d73296268e97c6fd56c45084ed56..74f471c1ce1f1da1909f6ad179157790a5377af6 100644 GIT binary patch literal 44511 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 diff --git a/backend/app/__pycache__/models.cpython-313.pyc b/backend/app/__pycache__/models.cpython-313.pyc index 66e37e41e28ba768aceb47e15c4cd03f1f61aead..6d7a17437e4bedc9f09813c93b724a2bf9d8e4cc 100644 GIT binary patch literal 10431 zcmc&)T~HfYc5b284?+?`5<)-x84R}kJ2tl0*y|q#8;`NgWN60oW6h{!sSz3r3E!4H z{+Ugb+GH0hl?o)8Dx4>8%?lJS+RY1(>`T_k6J1@k8@g(1YbsB?q&5Y4Ngg)m+^hZp z3+(aER@&xt_qpfZzTJJ!cfWI5TON;#gYB=r`rq6yVjTA$c%p5#+QHU47LNOx6F9+g ziyP$#*Nw*ww=AO#q+!%btfM^PM{UG5YA5zl2XTx#iIdt`Z#9m(h-y868+5#2 zyX6`65^pyb=6X269_0i_!h6=ru0@)u)(P51lh#MIF3>iav@KNY2Cc`W^;4}Ew9O`M zfNFi9Z82$sRO<(Az@%-Z+8}6KP1+FEhCth9(za1;7_a`@T%i=Vs`fjnnHe#odZy_$cU4vavolE znuzf3Gf8;qjys|xfvxJOUFNAjmCqmR&WL%jBpxr4nWRCUCHEhF;mWqaO_SdAC^;joFtqz zCzEv2`CLIP6hYxhCQGUNd6BgfH{1ci$3WUpG~o?d!SAqRs!%AFn2RNo#EI<@+77-+ zqIlYlf=7Wdt=h|_bfNeq=|YVMHO^^v_i#VcZ0c%jGAZGxX?Qx|`uEFlw=jGkm~X)! zr?%pg5DS?ExO)O_OUz3rW}c81XrlsWD=mWfDfjQe&dQx{L%lChl|I2VZ=ov>mSu&xYo$b1{WKz7gsF*`uZV z-#k?!rz_WI&&~JFT~zqf8@=yT!)xb%b>){=i}OjN8;-u4Wm+vS|idhDx0)u zgmK*vVdj|h&w@n%yq#K1w&*?liNN?_cqY3x!4KDHg?@or zj{xlvg7Jge_@qr}CE=_u9#Z)aC6R0fVGz|;hC^wB;0bly&Bt&AQDiSu{3Ic?a-tRb z`Q{(+)H9Qkq%VsklblLPQ=6TjTedJuo)q)q|1@bpa3Yt1v7Ci+K98Y7ZN^krtvQ*? zkPhg~+?={4I&VBe`caGbK=5u!9K{h7b)t+M#fD=jXk=Z$qvI%kh~f$g#BTB~3O&Zi z2|U#Uj2ytzQz&o_%<~5D=&UC28A(+T7%s8B!=*jG++Pi>99_-4JSexnUwLnKa$cBw zpz!Z+95}K3sG44RrX09fxif!mv3CLDMm)IJ8!Ttw><+NR5YiStBZNHQjISk+f zF1LlwJ!pfTGxqlGYj`PjWa_!pksERF5ftCueY>$63cOe8Cm?pBy&Sr1VEtvp`qAo- zlw;RlPRO0(2HcP9PO5}Y87_KiBX)QxsKicGZp_}DAD+9X@F!m5lGRUT?^VqyaboqI zQiYc9*(o)wHk`6PgL(s8*B#W1?2J26WY^o#fwk*WcNDzDpKXr&R2$_XoA`oNyM&ws zaQHf$F&_-WQQSfXv6)Z9;!Pma01uSP_rDO+C2|qZYyhibUTw;VQkvvuki^!UFz`oV z=xrFBVdxz^8bd*y@O?b0hmtq30R`TV^aupHS-XysyWET-p770s)q`^Qis4RIz@3&u z)rOU*5<6qK)EP!B(%(E&A_E4o7})4Kwltx1ovz%P4=q|3V!!53GvLOF>~Jd#E!?&~ z2kO0-TOn~5Y=V8zdd5QR2?s3EPQf8K0XG^Gu0#{XDYwu_aR^%x(_GrC21_KTR&|Lnnq?+09#uVp>bUFc5U^w zLJ+7(7{&?J=Fm##5P>@m32j0cW*AN2Swy=l5)-1NJsXR+lY?-H%^!eJTeYR0I(V{1 zT`8?o^G zN@++Cv;XuQw|~6?X+*IwnS(?nEs_SXSH0pRb_zLQxlmeeAV^|VXR%P8!NgN_u{|ap zj4!_f?c@du>gj!OG#2mJJIJs=pn7X5LNZ0NNX_?WF9!SzcpZH1`DA;mX+j$l}1lErlO8ttRWAiNEL;@IO6A6e zJG|JYxDWjJIzs}yaeyr&8V=~(Mz9O6J#nBJBF0D#n57S* zjHTahfh{38CR%#5*wXgIZ?g63sDQT3nvJ%HwB8ukx5KtYv#HG$@j{z{U$=A$0YCv{ zR0j4j6ku4xT0^GRklwc~5gy0nZP!*`E3^UDL}8q84Qs-5oY)R@X$N%aKy*>V0)vV_ zBSk0}ObH^Q^Hn@!1n1@Wf zSit0kt-+;S2~rzeuL)f(ah+xfJz@<*rWVN5NeQPSmXfR(5@0H*GU2k#l;l(FLE~9Z zhsNTa`@;Ek170n zZ;D2yybGVm4g^9c$89SQ?z9&dp@qcnJ@2YzX!Wx$WHUN8X$V1lrVPv=xGf3)ct5)h zvlKjl7eVO3n2Sqb7=@I0zaE&gX+0R%!5$%f4sE76FeKaA9yYZzHiXQ?ulJ7%0TRmw zeaC=6;iG+v`iC96(Uf&plozmJ zS40<4H-n-P#X}SXh0Y}EM)?CYL4glW`Zo|5^s z`xgTXPz$+Wio9J#M5wAPJzfj{s_U0s@_`R1^Y~cyb}IY_$TBiY_kc0XKphpO52k>{ zo7)kv_%LzXvIC&+6|h?JKobU=i8wS;I$$OatdOA*2O}+Lq~TLPfxso+s1-6xGjT8y zh2pf>DP%0jWi93 zL2J7Z(d(sdA!^tp+Q+dTxNEDg6=Fa`I&rib4QZ$2bitGF(4nMT=p+ZSk$9KtXHYT> zK}?wlK*welE~Ex)a6rSG@(XBUVTqWbx)=+XNtLG5CT;o0uOuN8FENd=Hz6Suh$sd% zu|XLGoyW^~w4tdEXGS;1M*`{M^b8TF!~)_V%a>Sc4v?J$nNd=0SfHLHQB~c#7gNif1VB{gAIve2(HrC@8x91s+*ZV4};2)c$Z* zLOT@rfTWACA|sp~0XTDp7u#PvtKMEazJ9kLJBz=!HiYbzvHx;%@ZkeKle}?ev?tJM z-&Iyia_2Rp)OHQZ8q0U9!z=fcu0gG|q40yc8j`85>qf)%y~@h*bJg-%T8@u024j2P zfnRgl<4cEDPs#0y8ZF&FVO@Az6Qx%!?Tk*o~;jlC_C?d z|5$eT?9V4xg@1nV@|t}31NLp}1^@hr9Oy$HrXk&~FUWg*4vX}^C{@Sh$ay14JHHV< zv}|7@E3Va>a&)9JGCMLqFbDOak+%RSd^|e<3jH0oeXGO&4;k6(zJnRT17#H?ECuOHh;FYAN9^2{lc4fT2pFl(Nm0z;FC|PL_4;7!v3P9nxc^SomU$SB zRaNx=&y|(j4f7L4GEIMn!)jxQoAhU8sr&HL zF4ByhX^{;-jMFcqth9d+Pg5vps*7xf0xEstyM7#?I)BK1E_9hZ2RlGp_Jf+=TP+sL zZ@G@&arb`1-IKX{zvC{;+~wbL(QUiS@`YtKv(4dtJL9C=4biY4lPkuZyk$^Hn;bm}ad(kS$32SP;D zp~F+Q3x@fKcC%IS+(;5kd+-a+aHeS38AZ0`Ovx;yOVnIWKh&sQR`tx1Tv$~NB_o$g z8MY~Idd|WM+RU~SQTEBF5yC!7A$F_YN9x&PGDiGt&C^qn#$7a&^W|FHFgxeZHuPf~ zJ|$!WSy#3ZylvSg8bJ{>2Cm&!+;s>r`-)IL2*co~WZ7j!HEe50Q@{}do8#ZNFaRK2& zj3dq<>Jbx&T1;sghj64o1Bf_c7=edU9;^}Up-K)A$6ouNSK}Dtaa5&mi*fKf9&1(8 zb!(Q6;%t7mHt3}Yq|VUR%Bmw4Ohu*bIN58Jmma7Ed-pev+`7D^>W-wSR)K0ITQiM) z-7PiU`IB{XwU_Z^uJ#J{t|GYZYuGzZ*%Ueuan>EERCP_Uk~_NbCZLjq1bB8axK8LG zaa?7-C|kBlAM;2%zN!sU8Z58n4^0I1q9GU6f1`39&m3bGQpnpeQw}S0f*D6R<_cA ye~iBfo+KU^bRBs#j&HJPDrH^0L}l<2_^lj^4W!xpKwq;&X30zOhkz}AXnz1Ci4$A^ diff --git a/backend/app/__pycache__/schemas.cpython-313.pyc b/backend/app/__pycache__/schemas.cpython-313.pyc index 5a728adab1bc53fd7834b75f7bdb36ba871c5364..0c429fc56f519e8d2aff3f7edc8a9a6a0f9090ca 100644 GIT binary patch literal 12334 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 literal 3168 zcmbtW&1)M+6yNWaR+1%u%TDv=zDC#BVYIa~wfnX;}>)m5nG zs#L$EtQ+7I&DC9FQKRO%wQjrS`(W3{E!TE4i#pA$XJI5OM$pDV&COA#p05;m!A)8< z5+zHN_zCG^Oy;{PNH~wv2qG^eQ9aq>&SpSa;zfRgbTcsA&7+ORwL0NiNVx8UV%Di& zBQKQIN{(kdVeEO_@w`S{YlQ^#yyrb^`5`U?Z$-}&%Z5QjqS*5&q=-UuAh^yFisOD1 z#fhH;al~M}B!+@0;gg=n5U+ZElF(qIl@K%-1A{~ODg5d}BT5!(e&R1QLMb1bTse1mdakYU<41($6C?-)%f#AhW8aIZ5LT7OZ<03uu4jNf< zIXVX~xFkc@?<$?yb3YZO*(Ct_`()Ghp)+WJ4CpipVV|-UJ%^(x&^7D=h^I;?liT^W zQySm-u9MC0+=BS+EdOJu=J}oiLLLC8oN${C06vEwf;j0mti{(O=^E6on-z=ambUz4 zjXZ1-mUPim++ninyr9PI24M`UN3wm9c^kHAL@{M33fzHVc>+dHF0SHd0UX5J|=%7Vvh+OG(eG$71)w~ z4T4*~7?ngRUb;e+C&SBv-Wmv;IjDQl*o4Rzckf7RH2j}DUhi?`*Ln0)cM-PZHdHai z^3H4$Qo|1m`Z=B#{k>XAzq+oX!SU7g1-_<5a0LfY;7)@G7DjjOLhL|{mk*4xWR6Cw zl@X|)?V2CKR}s~5E`EG)E7@)aQJsofu@M&agY8SUR1pwSDbdqJ x>gRfnrIyhi{(57YI@jJte6Hu{>e%xcTxYD8*VWQqfO-k_nZ515L7x!^`xh#gewY9N diff --git a/backend/app/__pycache__/services.cpython-313.pyc b/backend/app/__pycache__/services.cpython-313.pyc index 175f5fba249c31c960c4b3688fc26efacb79d971..7e10901d15b37808eb264d8fc7366b14ea73e7ce 100644 GIT binary patch literal 17078 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 delta 2139 zcmZ8iTWlN06`keolDk|=r1%mgO5#efByVJivg?;@DYA|DQPFvn8zM-oK%vPMvo>G7 zOZw3tB_Bad1ceh!8mk40*8OsRng9ZV{3PjL10;nd$hCuQ3Uj_rG^Wq7rm~ zxpN;gcOLiLJ0HI(Y@S$o)YauD*zA9OY5y%u$ahTWG-Zc*bWR}TH^d~SkRiZEPexeq zfJbM%m=PBwkT@@8LB-sRdr;h{Sh;j(s zvu3I@0(6=F>>#}z=pTZhsV#cVfGHf5%&vZNNrDj9bT2B|5qdHnSz$J>8RWJww}loX zW?(Uj+8(Zr?P|k|QEpMp2)D#{Edlg5wS9!2QuGn!GZVWrW9TD}-W9W#S-j9!5{v|W z&2yH1>KO=UJcRgPXzG@uKM%F#lNEdIKb|?y+Fk8W!axvxyYjLPPQw-R#iHvi)G8Ib zVTcf*zwR15b0A%*Hqym>BcHC<3X^s8FnPs>M$;;%FXjuEt!goyuh-L#1y}5XM25!1w_qu0LNc zcii;S+o9M!qBWonV2N)toQ8kI(hzyxA$HQ?(#511L??lgFb93f(9ipci@#ac9{? zumd%nTsYJ@ZBFWFaVx|@Rq1RasyT%Y_ePa&Vuo@`_9>hR{Pd0@41Q+*!4U7~y9> z5MU2F#34mXiD&4UzU`}p6?hCS z$3Y(suCl8*Xgd>@pmr5{aZ}e<*_ooEq<0!{L_|tfV;2sETD4(aYrtuoH;LWZ5CmFE zzWS@bpG_ zdNX`rQ~lYN+TDuX_~qM)Ej7@Jyd7(6M2@z@bami>{750GG1?qlexa=p+5gu0H_os3 zjNOyQzlkJQpSvH~cfsUPdT%JIc}${nnA5jV%k{qG?nf(|N1e{aY1}wuW2Pi99jAw^+eOImgWy@(e?A;J7&__Q% z67#-<(gi}@BX0`HwO5b+AnL3D!Vr=Yc5E-5_@4bRJ5qa|F3;-11bu6EI>cY$Wi&#b zkyq$nXZQa+i!6e+cGZHP9GM^L|B{MjqAOx#_zmFrwwS*Lv&>tJ&d>GgtOU9~u$IAc zUNf{GF9dww3-rp|jLy;lPB2nL;;^#TNr&y5-kpnitEjce+7ENT7yJxJM!)N+IrR2? zdd1x?!mhv21h5OuaJ@l~Y1r-Hc}7?n2lgNFGV6+V6+aB80X)rk z{CU*?_QJq6hY%yY5_8Nbvk16m*?MXeuAznfuFgM^v_(M>{z24-r1v4|dq_qelIRvO z=vOE93jOr;lj*s3e^MA&J=-QYd=%lsCy~cYYR`5FdslsJg2Nq?4}TH)@P+u8Dcd@& KpE@P6Q~VE=ngOK% diff --git a/backend/app/main.py b/backend/app/main.py index 6797270..b35b9f2 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -19,6 +19,7 @@ from .auth import ( ) from .curriculum import QUESTIONS from .program_content import ( + apply_program_review_updates, build_program_tree, decode_asset_token, format_adaptive_kit_context, @@ -52,6 +53,7 @@ async def lifespan(app: FastAPI): seed_admin_user(db) finally: db.close() + apply_program_review_updates() yield diff --git a/backend/app/program_content.py b/backend/app/program_content.py index ccb01e0..b7fa893 100644 --- a/backend/app/program_content.py +++ b/backend/app/program_content.py @@ -29,6 +29,7 @@ def default_content_root() -> Path: CONTENT_ROOT = Path(os.getenv("PROGRAM_CONTENT_ROOT", default_content_root())).resolve() LESSON_BACKGROUND = "#f8fafc" REVIEW_STATE_PATH = Path(os.getenv("PROGRAM_REVIEW_STATE_PATH", CONTENT_ROOT / ".program_review_state.json")) +REVIEW_UPDATES_PATH = Path(os.getenv("PROGRAM_REVIEW_UPDATES_PATH", CONTENT_ROOT / "review_updates")) GRADE_ALIASES = { "CM1": "cm1", @@ -298,6 +299,71 @@ def save_review_state(state: dict) -> None: ) +def iter_review_update_files() -> list[Path]: + candidates = [] + single_file = CONTENT_ROOT / ".program_review_updates.json" + if single_file.exists(): + candidates.append(single_file) + if REVIEW_UPDATES_PATH.exists(): + candidates.extend(sorted(REVIEW_UPDATES_PATH.glob("*.json"))) + return candidates + + +def apply_program_review_updates() -> dict: + state = load_review_state() + applied = 0 + skipped = 0 + errors = [] + + for path in iter_review_update_files(): + try: + payload = json.loads(path.read_text(encoding="utf-8")) + except json.JSONDecodeError as exc: + errors.append({"file": str(path), "error": f"JSON invalide: {exc}"}) + continue + + if payload.get("schema") != "professeur-top-review-updates-v1": + skipped += 1 + continue + + payload_updated_at = payload.get("updated_at") or datetime.utcnow().isoformat(timespec="seconds") + "Z" + payload_reviewer = payload.get("updated_by") or "codex" + for index, update in enumerate(payload.get("updates") or []): + node_key = update.get("node_key") or update.get("path") + if not node_key: + skipped += 1 + continue + + update_id = update.get("update_id") or f"{path.name}:{index}:{node_key}" + existing = state.get(node_key, {}) + if existing.get("codex_update_id") == update_id: + skipped += 1 + continue + + next_review = { + **existing, + "status": update.get("status") or existing.get("status") or "treated", + "comment": update.get("comment", existing.get("comment", "")), + "reviewer": update.get("reviewer") or payload_reviewer, + "updated_at": update.get("updated_at") or payload_updated_at, + "codex_update_id": update_id, + } + if update.get("treated_note"): + next_review["treated_note"] = update["treated_note"] + state[node_key] = next_review + applied += 1 + + if applied: + save_review_state(state) + + return { + "applied": applied, + "skipped": skipped, + "errors": errors, + "files": [str(path) for path in iter_review_update_files()], + } + + def collect_lesson_status(lesson: dict) -> dict: lesson_dir = CONTENT_ROOT / lesson["id"] kit_dir = lesson_dir / "kit_adaptatif" diff --git a/backend/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg b/backend/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg index 9295ec4..1df1b71 100644 --- a/backend/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg +++ b/backend/contenus_pedagogiques/cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg @@ -29,7 +29,7 @@ 0 1 - 3 - - 4 + 3 + + 4 diff --git a/backend/contenus_pedagogiques/review_updates/codex-2026-05-07-fractions-kit.json b/backend/contenus_pedagogiques/review_updates/codex-2026-05-07-fractions-kit.json new file mode 100644 index 0000000..142b825 --- /dev/null +++ b/backend/contenus_pedagogiques/review_updates/codex-2026-05-07-fractions-kit.json @@ -0,0 +1,16 @@ +{ + "schema": "professeur-top-review-updates-v1", + "updated_by": "codex", + "updated_at": "2026-05-07T19:55:00Z", + "updates": [ + { + "update_id": "codex-2026-05-07-fractions-kit-parcours-fraction-support", + "node_key": "cycle_3/mathematiques/cm1/01_nombres_calcul_resolution/01B_fractions/kit_adaptatif/svg/parcours_fraction_support.svg", + "status": "treated", + "comment": "Aucune fraction ne doit etre representee avec un trait oblique, il faut un trait horizontal avec les enfants de cet age", + "reviewer": "codex", + "updated_at": "2026-05-07T19:55:00Z", + "treated_note": "Fractions visibles remplacees par une disposition numerateur, barre horizontale, denominateur. Etiquette de la demi-droite remontee au-dessus du point vert." + } + ] +}