discovery-media-player 0.1.142 → 0.1.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ What a host application may call, what it must implement, and what will not chan
9
9
  version bump. If you are integrating the player, this page and [`API.md`](https://github.com/Juli1artha/discovery-media-player/blob/main/docs/API.md) are the two you
10
10
  need.
11
11
 
12
- ## Five rules
12
+ ## Six rules
13
13
 
14
14
  1. **One source of truth.** Fix the player in the player's repository, never in a host — not even
15
15
  in a host that once contained it. A fix written host-side is a copy, and copies drift.
@@ -23,6 +23,15 @@ need.
23
23
  the context and often the fix. Releasing stays with the maintainer because publishing a version
24
24
  decides deploy order. A local workaround is fine when you are blocked, on two conditions: report
25
25
  it the same day, and remove it when the release lands.
26
+ 6. **Describe what you do — including what you think is trivial.** Not *"report deviations"*: you
27
+ cannot know what one is, because that would mean knowing this page better than we do. ⚠️ The
28
+ over-specified sentence in [the `tts-cache` section](#four-things-that-will-bite) stood for
29
+ weeks, and it took a host mentioning its own naming **as a curiosity** for anyone to look. Its
30
+ own account of it, on 27/08: *"je ne l'ai décrite que parce que je citais `preview-fr-v2` comme
31
+ une curiosité, sans savoir que c'était un écart. Si j'avais su que votre page l'interdisait, je
32
+ me serais probablement conformé."* Complying would have orphaned **908 objects, permanently**.
33
+ A rule that asks you to spot the deviation cannot work; a rule that asks you to describe your
34
+ integration asks for nothing you do not already have. Boring descriptions are the useful ones.
26
35
 
27
36
  ## Identity card
28
37
 
@@ -99,6 +108,58 @@ different question when you want a real answer:
99
108
  GET /api/doc?contract=1&schema=1
100
109
  ```
101
110
 
111
+ ⚠️ **And if that is what you poll, the lazy verdicts are ones you will never see — which is the
112
+ whole point, and worth knowing before you read a warning aimed at somebody else.** `&schema=1`
113
+ probes every expectation *before answering*, then keeps the answers for the life of the process. So
114
+ its verdict is `complet`, or `indetermine` when the witness row itself does not answer — **never**
115
+ `non-sonde`, and `partiel` only in the window where two of them race. A plain `?contract=1` on that
116
+ same process reports `complet` afterwards too, because the probing already happened.
117
+
118
+ The consequence is a split an integrating host measured on 28/08, having read `complet` for a week
119
+ from a daily cron and put it down to luck: **the readers who need the "do not mistake this for a
120
+ regression" warning and the readers who ever meet it are disjoint.** Poll with `&schema=1` and you
121
+ cannot observe the degradation the warning describes; read `?contract=1` alone and you meet it
122
+ without having asked for a probe. Neither is a defect. But if you are checking that warning against
123
+ what you see, and you poll with `&schema=1`, **your instance is not the one it is about**.
124
+
125
+ ⚠️ **`complet` means complete *for the code you are running*, never complete for the repository —
126
+ and `connues` is there so you do not have to take that on trust.** The expectation list is compiled
127
+ into the player. A migration published after your version does not appear in it, is never probed,
128
+ and can therefore never turn `manquant` red. So a host who applies the schema **before** upgrading
129
+ the code — the safe order, the one we recommend — is exactly the host this green does not inform.
130
+
131
+ The STUDIO host measured it on both sides on 30/08: on `0.1.142` they applied migration 0024, re-read
132
+ the card, and got `attendues: 9 · sondees: 9 · complet · manquant: []` — word for word what they had
133
+ read *before* applying it. They could not watch 0024 leave a list it had never entered.
134
+
135
+ No version of this server can know a migration that postdates it. What it can do, and now does, is
136
+ say what it knows:
137
+
138
+ ```
139
+ "schema": {
140
+ "couvre": "colonnes-conditionnelles",
141
+ "attendues": 10, "sondees": 10, "verdict": "complet", "manquant": [],
142
+ "connues": ["0001-destinataire-atteste.sql", "…", "0024-rotation-en-direct.sql"]
143
+ }
144
+ ```
145
+
146
+ Read it this way, in this order:
147
+
148
+ 1. **Is the migration you care about in `connues`?** If not, this card cannot speak about it, whatever
149
+ `verdict` says. Upgrade the player, or check the database directly (below).
150
+ 2. **Only then** does `verdict` answer for it. `manquant` names its files in the same strings as
151
+ `connues`, so membership is a plain comparison and not an inference about our release history.
152
+
153
+ ⚠️ **To check a migration this player does not know about, ask the database, not the card.** The
154
+ query does not depend on which version you are running, which is the only case where you need an
155
+ answer:
156
+
157
+ ```sql
158
+ select column_name, data_type, is_nullable, column_default
159
+ from information_schema.columns
160
+ where table_name = 'doc_presentations' and column_name = 'view_rotation';
161
+ ```
162
+
102
163
  The three `presence*` fields report what the host has **observed**, not what it is configured to do:
103
164
 
104
165
  | field | meaning |
@@ -251,10 +312,24 @@ Each `manquant` entry has **exactly this shape** — pin your parser to it, not
251
312
  probe "should" return:
252
313
 
253
314
  ```json
254
- { "migration": "supabase/migrations/0006-reactions-ordonnees.sql",
315
+ { "migration": "0006-reactions-ordonnees.sql",
255
316
  "fonction": "empêcher deux réactions simultanées de s'écraser" }
256
317
  ```
257
318
 
319
+ ⚠️ **`migration` is a FILE NAME, not a path — it lives in `supabase/migrations/` in this
320
+ repository.** It used to carry that prefix. A host's own guard refuses any identity card containing
321
+ `supabase|secret|key|token` — a deliberately coarse text sweep, protecting a public response against
322
+ leaking a project URL, a key or a token — and the prefix made it fire on every migration named. The
323
+ prefix is gone from what the card publishes; the directory is stated here, once, and the operator
324
+ log still prints the full path because that message is for the person reading it, not for a sweep.
325
+
326
+ ⚠️ **You do not need an exception in such a guard, and you should not add one.** Nothing this card
327
+ publishes matches that pattern, and a bench renders the real card and sweeps it — keys included —
328
+ on every change. If you carry an exception for the old prefix, remove it: an exception whose subject
329
+ can no longer appear is a pre-authorised widening nobody watches. A second bench sweeps the
330
+ migration directory itself, so a future file named `0031-refresh-token-rotation.sql` is refused
331
+ here, when it is written, rather than months later at your end.
332
+
258
333
  ⚠️ This shape went **undocumented** for two releases, and the second host typed it from memory as
259
334
  `{table, colonne, migration}` — their monitoring filter then discarded every real entry and would
260
335
  have shown an empty table on a database that was actually missing something. **No mutation on
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discovery-media-player",
3
- "version": "0.1.142",
3
+ "version": "0.1.144",
4
4
  "description": "Self-hosted document viewer: per-recipient tracked links, reading analytics, live presentation. The core knows nothing about the application hosting it — everything it borrows arrives through an injected context.",
5
5
  "keywords": [
6
6
  "pdf-viewer",
@@ -6,4 +6,4 @@
6
6
  // Injecté par api/doc.js dans un <script nonce=…> de la visionneuse. Le code navigateur du
7
7
  // player vit en modules TypeScript testés sous player/src/ — c'est ici qu'il atterrit.
8
8
  "use strict";
9
- module.exports = { PLAYER_BROWSER_JS: "\"use strict\";var Player=(()=>{var C=Object.defineProperty,We=Object.defineProperties,Ve=Object.getOwnPropertyDescriptor,ze=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ve=Object.getOwnPropertySymbols;var we=Object.prototype.hasOwnProperty,Be=Object.prototype.propertyIsEnumerable;var Me=(e,n,t)=>n in e?C(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,K=(e,n)=>{for(var t in n||(n={}))we.call(n,t)&&Me(e,t,n[t]);if(ve)for(var t of ve(n))Be.call(n,t)&&Me(e,t,n[t]);return e},xe=(e,n)=>We(e,ze(n));var M=(e,n)=>{for(var t in n)C(e,t,{get:n[t],enumerable:!0})},je=(e,n,t,r)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let o of Fe(n))!we.call(e,o)&&o!==t&&C(e,o,{get:()=>n[o],enumerable:!(r=Ve(n,o))||r.enumerable});return e};var Ge=e=>je(C({},\"__esModule\",{value:!0}),e);var Kn={};M(Kn,{bridge:()=>N,cadence:()=>L,chat:()=>U,live:()=>H,presentation:()=>D,presentationState:()=>V,tracking:()=>$,viewer:()=>W});var N={};M(N,{onHostMessage:()=>tn,onPlayerMessage:()=>nn,parseHostMessage:()=>Te,parsePlayerMessage:()=>Ee,sendToHost:()=>Xe,sendToPlayer:()=>Je,toWire:()=>Z});var Y=\"3dd-doc-\",Ke=/^[A-Za-z0-9_-]{1,64}$/,Ye=[\"close\",\"share\",\"embed-ready\",\"present-left\",\"present-denied\"],Ze=[\"embed-denied\"],qe=[\"present-invite\",\"present-handover\",\"present-switch\"],Qe=[\"handover-done\"];function Z(e){let n={type:Y+e.type};return\"slug\"in e&&e.slug&&(n.slug=e.slug),\"reason\"in e&&e.reason&&(n.reason=String(e.reason).slice(0,40)),n}function _e(e,n,t){if(!e||typeof e!=\"object\")return null;let r=e.type;if(typeof r!=\"string\"||!r.startsWith(Y))return null;let o=r.slice(Y.length);if(n.includes(o))return{type:o};if(Ze.includes(o)){let a=e.reason;return{type:o,reason:/^[a-z-]{1,40}$/.test(String(a||\"\"))?String(a):\"unknown\"}}if(!t.includes(o))return null;let s=e.slug;return typeof s!=\"string\"||!Ke.test(s)?null:{type:o,slug:s}}function Ee(e){return _e(e,Ye,qe)}function Te(e){return _e(e,Qe,[])}function Xe(e,n){try{let t=n||(typeof window!=\"undefined\"?window.parent:null);t&&t.postMessage(Z(e),\"*\")}catch(t){}}function Je(e,n){var t;try{(t=e==null?void 0:e.contentWindow)==null||t.postMessage(Z(n),\"*\")}catch(r){}}function en(e,n){var r;if(!e)return!0;let t=(r=e.contentWindow)!=null?r:e;return n===t}function nn(e,n,t){let r=n||(typeof window!=\"undefined\"?window:null);if(!r)return()=>{};let o=s=>{if(!en(t,s.source))return;let a=Ee(s.data);a&&e(a)};return r.addEventListener(\"message\",o),()=>r.removeEventListener(\"message\",o)}function tn(e,n){var s;let t=n||(typeof window!=\"undefined\"?window:null);if(!t)return()=>{};let r=(s=t.parent)!=null?s:null,o=a=>{if(!r||r===t||a.source!==r)return;let l=Te(a.data);l&&e(l)};return t.addEventListener(\"message\",o),()=>t.removeEventListener(\"message\",o)}var $={};M($,{createTracker:()=>pn});var L={};M(L,{PRESENTER_ACTIONS_PER_HOUR:()=>X,PRESENT_CACHE_MS:()=>an,PRESENT_QUOTA_MARGIN:()=>Ne,PRESENT_QUOTA_PER_HOUR:()=>un,PRESENT_READS_PER_HOUR:()=>Ie,PRESENT_READ_BURST:()=>Ae,PRESENT_READ_COALESCE_MS:()=>Ce,PRESENT_RESYNC_MS:()=>Re,PRESENT_SIGNAL_BUDGET_PER_HOUR:()=>sn,PRESENT_WRITE_TIMEOUT_MS:()=>J,READERS_PER_EGRESS:()=>O,RESYNC_READS_PER_HOUR:()=>Pe,SESSION_IDLE_MS:()=>Q,SESSION_INTERVAL_MS:()=>q,SESSION_QUOTA_PER_HOUR:()=>rn,SESSION_WRITES_PER_HOUR:()=>Se,VIEW_EVENTS_PER_READER_HOUR:()=>ke,VIEW_QUOTA_PER_HOUR:()=>on});var q=3e4,Se=Math.ceil(120),O=25,rn=Se*O,ke=720,on=ke*O,Q=18e4,Re=25e3,Pe=Math.ceil(36e5/Re),X=720,Ie=Pe+X,sn=X,Ae=20,J=1e4,Ce=400,an=Ce,Ne=4,un=(Ie+Ae)*O*Ne;var ln=[\"mousemove\",\"mousedown\",\"keydown\",\"wheel\",\"touchstart\",\"pointerdown\"];function cn(){let e=typeof globalThis!=\"undefined\"?globalThis.crypto:void 0;if(e&&typeof e.randomUUID==\"function\")return e.randomUUID().replace(/-/g,\"\");if(e&&typeof e.getRandomValues==\"function\"){let n=e.getRandomValues(new Uint8Array(16));return Array.from(n,t=>t.toString(16).padStart(2,\"0\")).join(\"\")}return Math.random().toString(36).slice(2)+Date.now().toString(36)}function dn(e,n){return t=>{try{let r=JSON.stringify(t),o=n.navigator;return o&&typeof o.sendBeacon==\"function\"?o.sendBeacon(e,new Blob([r],{type:\"application/json\"})):(n.fetch(e,{method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:r,keepalive:!0}),!0)}catch(r){return!1}}}function pn(e={}){var be,ye;let n=e.win||(typeof window!=\"undefined\"?window:null),t=e.doc||n&&n.document,r=e.now||(()=>Date.now()),o=e.endpoint||\"/api/doc\",s=(be=e.idleMs)!=null?be:Q,a=(ye=e.sessionEveryMs)!=null?ye:3e4,l=e.slug||\"\",p=e.internal||null,g=e.sessionId||cn(),f=e.send||dn(o,n),c={},u=0,b=0,d=0,w=0,v=null,T=r(),S=!1,z=!1,I=[],De=()=>!!l||!!p,ce=i=>{if(!De())return!1;try{return f(i)!==!1}catch(m){return!1}},F=()=>!!t&&t.visibilityState===\"visible\"&&!S,de=i=>{let m=r()-i,y=Math.max(0,T-i)+s;return Math.max(0,Math.min(m,y))},B=()=>{v!=null&&u>0&&(c[u]=(c[u]||0)+de(v)/1e3),v=F()?r():null},pe=()=>{B(),v=null},j=()=>{v==null&&F()&&(v=r())},G=()=>{let i=0;for(let m in c)i+=c[m];return v!=null&&(i+=de(v)/1e3),Math.round(i)},fe=()=>{let i={};for(let m in c)i[m]=Math.round(c[m]);return i},k=()=>{T=r(),S&&(S=!1,j())},me=(i,m)=>{p||ce({slug:l,event:i,page:m||b,maxPage:d,seconds:G(),sessionId:g})},ge=\"\",A=()=>{B();let i=G(),m=`${i}|${d}|${w}`;if(m===ge)return;let y={event:\"session\",sessionId:g,numPages:w,maxPage:d,totalSeconds:i,pagesTime:fe()};p?(y.internal=!0,y.docId=p.docId,y.email=p.email,y.name=p.name,p.it&&(y.it=p.it)):y.slug=l,ce(y)&&(ge=m)},R=(i,m,y,he)=>{!i||typeof i.addEventListener!=\"function\"||(i.addEventListener(m,y,he),I.push(()=>{i.removeEventListener(m,y,he)}))};return{sessionId:g,totalSeconds:G,maxPage:()=>d,pageTimes:fe,start(){if(z)return;z=!0,me(\"open\",1),u=1,T=r(),v=F()?r():null,R(t,\"visibilitychange\",()=>{t.visibilityState===\"hidden\"?(pe(),A()):(k(),j())}),R(n,\"focus\",()=>{k(),j()});for(let y of ln)R(n,y,k,{passive:!0});R(e.scrollElement,\"scroll\",k,{passive:!0}),R(n,\"beforeunload\",A);let i=n.setInterval(()=>{!S&&r()-T>s&&(S=!0,pe())},5e3),m=n.setInterval(A,a);I.push(()=>{n.clearInterval(i),n.clearInterval(m)})},setPage(i){!i||i===b||(T=r(),B(),u=i,b=i,i>d&&(d=i,me(\"page\",i)))},setPageCount(i){w=i||0},noteActivity:k,flush:A,stop(){for(;I.length;){let i=I.pop();try{i==null||i()}catch(m){}}z=!1}}}var H={};M(H,{STORAGE_KEYS:()=>x,attendeeKey:()=>bn,authorToken:()=>yn,avatarHtml:()=>ee,canModerate:()=>oe,createBudget:()=>En,createFileEcritures:()=>Tn,createScheduler:()=>xn,escapeHtml:()=>h,fetchBorne:()=>_n,flattenPresence:()=>fn,formatMessageBody:()=>ne,initials:()=>Oe,isMentioned:()=>vn,isMine:()=>_,presenceId:()=>Sn,reactorId:()=>re,referenceAuteur:()=>hn,shouldNotify:()=>Mn,unreadLabel:()=>wn});var x={attendeeKey:\"3dd-present-attkey\",authorToken:\"3dd-present-authtoken\",chatMuted:\"3dd-present-mute\",presenceId:\"3dd-present-uid\"};function h(e){return String(e==null?\"\":e).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\")}function Oe(e){let n=(e||\"?\").trim().split(/\\s+/);return(((n[0]||\"\")[0]||\"?\")+((n[1]||\"\")[0]||\"\")).toUpperCase()}function ee(e,n){return e?`<img src=\"${h(e)}\" alt=\"\">`:h(Oe(n))}function ne(e){let n=h(e);return n=n.replace(/(https?:\\/\\/[^\\s<]+)/g,t=>`<a href=\"${t}\" target=_blank rel=noreferrer class=cm-link>${t}</a>`),n=n.replace(/(^|\\s)@([\\p{L}0-9_'.-]+)/gu,(t,r,o)=>`${r}<span class=cm-mention>@${o}</span>`),n}function fn(e){let n=new Map;for(let t in e||{})for(let r of(e||{})[t]||[]){let o=String(r.uid||r.email||r.name||\"\").toLowerCase()||`_${t}_${n.size}`;(!n.get(o)||r.role===\"presenter\")&&n.set(o,r)}return[...n.values()]}function mn(e,n){try{return e?e.getItem(n):null}catch(t){return null}}function gn(e,n,t){try{e==null||e.setItem(n,t)}catch(r){}}function bn(e,n=\"anon\",t=te){try{if(!e)return`anon-${n}`;let r=e.getItem(x.attendeeKey);if(r)return r;let o=`anon-${t()}`;return e.setItem(x.attendeeKey,o),o}catch(r){return`anon-${n}`}}function te(){let e=typeof globalThis!=\"undefined\"?globalThis.crypto:void 0;if(e&&typeof e.randomUUID==\"function\")return e.randomUUID().replace(/-/g,\"\");if(e&&typeof e.getRandomValues==\"function\"){let n=e.getRandomValues(new Uint8Array(24));return Array.from(n,t=>t.toString(16).padStart(2,\"0\")).join(\"\")}try{console.warn(\"[player] crypto indisponible : jeton d'auteur affaibli\")}catch(n){}return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}function yn(e,n=te){let t=mn(e,x.authorToken);if(t)return t;let r=n();return gn(e,x.authorToken,r),r}async function hn(e,n){let t=n!==void 0?n:typeof globalThis!=\"undefined\"&&globalThis.crypto?globalThis.crypto.subtle:null;if(!t||!e)return\"\";try{let r=async o=>{let s=await t.digest(\"SHA-256\",new TextEncoder().encode(o));return Array.from(new Uint8Array(s),a=>a.toString(16).padStart(2,\"0\")).join(\"\")};return(await r(\"ref:\"+await r(e))).slice(0,16)}catch(r){return\"\"}}function re(e){return String(e&&e.ref||\"\")}function _(e,n){return!e||!n||!e.author_ref||!n.ref?!1:e.author_ref===n.ref}function oe(e){return!!(e&&e.role===\"presenter\")}function vn(e,n){if(!n||!n.name)return!1;let t=(n.name.split(/\\s+/)[0]||\"\").toLowerCase();return t?String(e&&e.body||\"\").toLowerCase().includes(`@${t}`)&&!_(e,n):!1}function Mn(e){let{msg:n,me:t,historyLoaded:r,chatHidden:o}=e;return!r||!n||n.deleted||_(n,t)?!1:o}function wn(e){return!e||e<=0?\"\":e>9?\"9+\":String(e)}function xn(e,n={}){var b;let t=(b=n.minMs)!=null?b:300,r=n.now||(()=>Date.now()),o=n.setTimer||((d,w)=>setTimeout(d,w)),s=n.clearTimer||(d=>clearTimeout(d)),a=!1,l=!1,p=-1/0,g=null,f=!1;function c(){if(f||a){l=!0;return}let d=t-(r()-p);if(d>0){u(d);return}a=!0,l=!1,p=r();let w=!1;e(()=>{w||(w=!0,a=!1,l&&!f&&c())})}function u(d){f||g!==null||(g=o(()=>{g=null,c()},Math.max(0,d)))}return{signaler(){f||c()},maintenant(){f||(p=-1/0,c())},arreter(){f=!0,g!==null&&(s(g),g=null)}}}function _n(e,n,t=J,r={}){let o=r.fetch||(typeof fetch==\"function\"?fetch:void 0);if(!o)return Promise.reject(new Error(\"fetch indisponible\"));let s=r.setTimer||((u,b)=>setTimeout(u,b)),a=r.clearTimer||(u=>clearTimeout(u)),l=null;try{l=new AbortController}catch(u){}let p=l?xe(K({},n||{}),{signal:l.signal}):K({},n||{}),g=null,f=new Promise((u,b)=>{g=s(()=>{try{l==null||l.abort()}catch(d){}b(new Error(\"delai\"))},t)}),c=()=>{try{a(g)}catch(u){}};return Promise.race([o(e,p),f]).then(u=>(c(),u),u=>{throw c(),u})}function En(e){let n=e.now||(()=>Date.now()),t=Math.max(1,e.rafale),r=t,o=n();return{prendre(){let s=n();return r=Math.min(t,r+(s-o)*e.parHeure/36e5),o=s,r<1?!1:(r-=1,!0)},restants:()=>r}}function Tn(e={}){var g;let n=(g=e.minMs)!=null?g:0,t=e.now||(()=>Date.now()),r=e.setTimer||((f,c)=>setTimeout(f,c)),o=new Map,s=!1,a=-1/0,l=!1;function p(){if(s||o.size===0)return;let f=n-(t()-a);if(f>0){if(l)return;l=!0,r(()=>{l=!1,p()},f);return}let c=o.keys().next().value,u=o.get(c);o.delete(c),s=!0,a=t(),Promise.resolve().then(u.tache).then(b=>u.regler(b),()=>u.regler(null)).then(()=>{s=!1,p()})}return{poser(f,c){return new Promise(u=>{let b=o.get(f);o.set(f,{tache:c,regler:d=>{b&&b.regler(d),u(d)}}),p()})},enAttente:()=>o.size}}function Sn(e,n=te){try{if(e){let t=e.getItem(x.presenceId);if(t)return t;let r=`p-${n()}`;return e.setItem(x.presenceId,r),r}}catch(t){}return`p-${n()}`}var U={};M(U,{messageClassName:()=>Rn,renderActions:()=>He,renderAttachment:()=>$e,renderMessage:()=>kn,renderReactions:()=>Le});function Le(e,n){let t=e&&e.reactions||{},r=re(n),o=\"\";for(let s in t){let a=t[s]||[];if(!a.length)continue;let l=a.indexOf(r)>=0;o+=`<button class=\"re-chip${l?\" on\":\"\"}\" data-e=\"${h(s)}\">${h(s)} ${a.length}</button>`}return o}function $e(e){if(!e||!e.url)return\"\";let n=h(e.url);if(e.kind===\"image\")return`<a class=cm-att href=\"${n}\" target=_blank rel=noreferrer><img src=\"${n}\" alt=\"\" loading=lazy></a>`;let t=h(e.name||\"Document.pdf\");return`<a class=cm-att-pdf href=\"${n}\" target=_blank rel=noreferrer data-pdf=\"${n}\"><span class=cm-att-ph></span><span class=cm-pdflabel>${t}</span></a>`}function He(e,n){let t=_(e,n.me),r=`<button class=cm-react title=\"R\\xE9agir\">${n.reactIcon||\"\"}</button><button class=cm-reply title=\"R\\xE9pondre\">\\u21A9</button>`;return t&&(r+='<button class=cm-edit title=\"Modifier\">\\u270E</button>'),(t||oe(n.me))&&(r+='<button class=cm-del-btn title=\"Supprimer\">\\u{1F5D1}</button>'),r}function kn(e,n){if(e.deleted)return'<span class=a></span><span class=b><div class=\"txt cm-del\">Message supprim\\xE9</div></span>';let t=e.reply_to?`<div class=cm-q><b>${h(e.reply_name||\"\")}</b> ${h(e.reply_text||\"\")}</div>`:\"\",r=e.edited?\" <span class=cm-ed>(modifi\\xE9)</span>\":\"\",o=e.body?`<div class=txt>${ne(e.body)}${r}</div>`:\"\",s=e.is_presenter?\" <span class=tag>pr\\xE9sentateur</span>\":\"\";return`<span class=a>${ee(e.author_avatar,e.author_name)}</span><span class=b><div class=who><b>${h(e.author_name||\"Invit\\xE9\")}</b>${s}</div>`+t+o+$e(e.attachment)+`<div class=cm-re>${Le(e,n.me)}</div></span><span class=cm-act>${He(e,n)}</span>`}function Rn(e,n,t){return\"cm\"+(_(e,n)?\" me\":\"\")+(e.deleted?\" isdel\":\"\")+(t?\" mentioned\":\"\")}var D={};M(D,{DEFAULT_CENTER:()=>ae,DEFAULT_ZOOM:()=>ue,MAP_TYPES:()=>P,cycleMapType:()=>Pn,initialMapContent:()=>An,mapTypeLabel:()=>In,sanitizeContent:()=>le});var P=[\"roadmap\",\"satellite\",\"hybrid\"],ae=[46.6,2.5],ue=6;function E(e){let n=Number(e);return Number.isFinite(n)?n:null}function se(e){if(!Array.isArray(e))return null;let n=E(e[0]),t=E(e[1]);return n!=null&&t!=null?[n,t]:null}var ie=(e,n,t)=>Math.max(n,Math.min(t,e));function le(e){if(!e||typeof e!=\"object\")return null;let n=e;if(n.kind===\"pdf\"||n.kind==null)return null;if(n.kind===\"streetview\"){let t=se(n.position);if(!t)return null;let r=n.pov&&typeof n.pov==\"object\"?n.pov:null,o=r?{heading:E(r.heading)||0,pitch:ie(E(r.pitch)||0,-90,90)}:{heading:0,pitch:0};return{kind:\"streetview\",position:t,pov:o,zoom:ie(E(n.zoom)||1,0,5)}}return n.kind!==\"map\"?null:{kind:\"map\",center:se(n.center)||[...ae],zoom:ie(Math.trunc(E(n.zoom)||ue),1,21),marker:se(n.marker),mapType:P.includes(n.mapType)?n.mapType:null,label:String(n.label||\"\").slice(0,160)||null}}function Pn(e){let n=P.indexOf(e);return P[(n+1)%P.length]}function In(e){return e===\"roadmap\"?\"\\u{1F6F0} Satellite\":e===\"satellite\"?\"\\u{1F5FA} Hybride\":\"\\u{1F5FA} Plan\"}function An(){return{kind:\"map\",center:[...ae],zoom:ue,marker:null,mapType:null,label:null}}var W={};M(W,{CURRENT_PAGE_MARGIN:()=>Hn,DEFAULT_ASPECT:()=>On,MAX_ZOOM:()=>Nn,MIN_PAGE_WIDTH:()=>Ln,MIN_ZOOM:()=>Cn,PRERENDER_MARGIN:()=>$n,arrowState:()=>Wn,averageColor:()=>Fn,clampPage:()=>Ue,clampZoom:()=>Un,fitWidth:()=>zn,isImageDocument:()=>Bn,progressPercent:()=>Dn});var Cn=.5,Nn=3,On=1.35,Ln=280,$n=\"500px 0px\",Hn=\"-48% 0px -48% 0px\";function Un(e){let n=Math.round((Number(e)||0)*10)/10;return Math.max(.5,Math.min(3,n))}function Ue(e,n){return Math.max(1,Math.min(n||1,Number(e)||1))}function Dn(e,n){return n?Math.round(Ue(e,n)/n*100):0}function Wn(e,n){return{prevDisabled:e<=1,nextDisabled:!!n&&e>=n}}var Vn=28;function zn(e){var a;let n=(a=e.zoom)!=null?a:1,t=Math.max(280,e.containerWidth||900)*n;if(!e.onePage)return t;let r=e.aspect||1.35,s=((e.containerHeight||600)-Vn-(e.overlap||0)-(e.reserve||0))/r;return s>120?Math.min(t,s):t}function Fn(e){let n=e.length/4;if(!n)return\"rgb(0,0,0)\";let t=0,r=0,o=0;for(let s=0;s<e.length;s+=4)t+=e[s],r+=e[s+1],o+=e[s+2];return`rgb(${Math.round(t/n)},${Math.round(r/n)},${Math.round(o/n)})`}function Bn(e,n){return/[.](png|jpe?g|webp|gif|avif)($|[?])/i.test(String(e||n||\"\"))}var V={};M(V,{presentationTransition:()=>jn,switchDocUrl:()=>Gn});function jn(e,n={}){if(!e)return[{kind:\"nothing\"}];if(e.active===!1)return[{kind:\"ended\"}];let t=le(e.content);if(t)return[{kind:\"show-map\",content:t}];let r=[{kind:\"leave-map\"}];return e.file_url&&e.file_url!==n.docUrl?(r.push({kind:\"switch-doc\",url:e.file_url,name:e.file_name||void 0,title:e.doc_title||void 0,updatedAt:e.updated_at||void 0}),r):(e.current_page&&r.push({kind:\"show-page\",page:e.current_page}),r)}function Gn(e,n){let t=encodeURIComponent(n||String(Date.now()));return`${e}${e.includes(\"?\")?\"&\":\"?\"}v=${t}`}return Ge(Kn);})();", SOURCE_HASH: "483d392a214f6bf8" };
9
+ module.exports = { PLAYER_BROWSER_JS: "\"use strict\";var Player=(()=>{var O=Object.defineProperty,Be=Object.defineProperties,je=Object.getOwnPropertyDescriptor,Ge=Object.getOwnPropertyDescriptors,Ke=Object.getOwnPropertyNames,Me=Object.getOwnPropertySymbols;var _e=Object.prototype.hasOwnProperty,Ye=Object.prototype.propertyIsEnumerable;var we=(e,n,t)=>n in e?O(e,n,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[n]=t,Z=(e,n)=>{for(var t in n||(n={}))_e.call(n,t)&&we(e,t,n[t]);if(Me)for(var t of Me(n))Ye.call(n,t)&&we(e,t,n[t]);return e},Ee=(e,n)=>Be(e,Ge(n));var M=(e,n)=>{for(var t in n)O(e,t,{get:n[t],enumerable:!0})},Ze=(e,n,t,r)=>{if(n&&typeof n==\"object\"||typeof n==\"function\")for(let o of Ke(n))!_e.call(e,o)&&o!==t&&O(e,o,{get:()=>n[o],enumerable:!(r=je(n,o))||r.enumerable});return e};var qe=e=>Ze(O({},\"__esModule\",{value:!0}),e);var Jn={};M(Jn,{bridge:()=>L,cadence:()=>H,chat:()=>W,live:()=>D,presentation:()=>V,presentationState:()=>F,tracking:()=>U,viewer:()=>z});var L={};M(L,{onHostMessage:()=>an,onPlayerMessage:()=>sn,parseHostMessage:()=>ke,parsePlayerMessage:()=>Se,sendToHost:()=>tn,sendToPlayer:()=>rn,toWire:()=>Q});var q=\"3dd-doc-\",Qe=/^[A-Za-z0-9_-]{1,64}$/,Xe=[\"close\",\"share\",\"embed-ready\",\"present-left\",\"present-denied\"],Je=[\"embed-denied\"],en=[\"present-invite\",\"present-handover\",\"present-switch\"],nn=[\"handover-done\"];function Q(e){let n={type:q+e.type};return\"slug\"in e&&e.slug&&(n.slug=e.slug),\"reason\"in e&&e.reason&&(n.reason=String(e.reason).slice(0,40)),n}function Te(e,n,t){if(!e||typeof e!=\"object\")return null;let r=e.type;if(typeof r!=\"string\"||!r.startsWith(q))return null;let o=r.slice(q.length);if(n.includes(o))return{type:o};if(Je.includes(o)){let a=e.reason;return{type:o,reason:/^[a-z-]{1,40}$/.test(String(a||\"\"))?String(a):\"unknown\"}}if(!t.includes(o))return null;let s=e.slug;return typeof s!=\"string\"||!Qe.test(s)?null:{type:o,slug:s}}function Se(e){return Te(e,Xe,en)}function ke(e){return Te(e,nn,[])}function tn(e,n){try{let t=n||(typeof window!=\"undefined\"?window.parent:null);t&&t.postMessage(Q(e),\"*\")}catch(t){}}function rn(e,n){var t;try{(t=e==null?void 0:e.contentWindow)==null||t.postMessage(Q(n),\"*\")}catch(r){}}function on(e,n){var r;if(!e)return!0;let t=(r=e.contentWindow)!=null?r:e;return n===t}function sn(e,n,t){let r=n||(typeof window!=\"undefined\"?window:null);if(!r)return()=>{};let o=s=>{if(!on(t,s.source))return;let a=Se(s.data);a&&e(a)};return r.addEventListener(\"message\",o),()=>r.removeEventListener(\"message\",o)}function an(e,n){var s;let t=n||(typeof window!=\"undefined\"?window:null);if(!t)return()=>{};let r=(s=t.parent)!=null?s:null,o=a=>{if(!r||r===t||a.source!==r)return;let u=ke(a.data);u&&e(u)};return t.addEventListener(\"message\",o),()=>t.removeEventListener(\"message\",o)}var U={};M(U,{createTracker:()=>bn});var H={};M(H,{PRESENTER_ACTIONS_PER_HOUR:()=>ee,PRESENT_CACHE_MS:()=>dn,PRESENT_QUOTA_MARGIN:()=>Le,PRESENT_QUOTA_PER_HOUR:()=>pn,PRESENT_READS_PER_HOUR:()=>Ce,PRESENT_READ_BURST:()=>Ne,PRESENT_READ_COALESCE_MS:()=>Oe,PRESENT_RESYNC_MS:()=>Ie,PRESENT_SIGNAL_BUDGET_PER_HOUR:()=>cn,PRESENT_WRITE_TIMEOUT_MS:()=>ne,READERS_PER_EGRESS:()=>$,RESYNC_READS_PER_HOUR:()=>Pe,SESSION_IDLE_MS:()=>J,SESSION_INTERVAL_MS:()=>X,SESSION_QUOTA_PER_HOUR:()=>un,SESSION_WRITES_PER_HOUR:()=>Re,VIEW_EVENTS_PER_READER_HOUR:()=>Ae,VIEW_QUOTA_PER_HOUR:()=>ln});var X=3e4,Re=Math.ceil(120),$=25,un=Re*$,Ae=720,ln=Ae*$,J=18e4,Ie=25e3,Pe=Math.ceil(36e5/Ie),ee=720,Ce=Pe+ee,cn=ee,Ne=20,ne=1e4,Oe=400,dn=Oe,Le=4,pn=(Ce+Ne)*$*Le;var mn=[\"mousemove\",\"mousedown\",\"keydown\",\"wheel\",\"touchstart\",\"pointerdown\"];function fn(){let e=typeof globalThis!=\"undefined\"?globalThis.crypto:void 0;if(e&&typeof e.randomUUID==\"function\")return e.randomUUID().replace(/-/g,\"\");if(e&&typeof e.getRandomValues==\"function\"){let n=e.getRandomValues(new Uint8Array(16));return Array.from(n,t=>t.toString(16).padStart(2,\"0\")).join(\"\")}return Math.random().toString(36).slice(2)+Date.now().toString(36)}function gn(e,n){return t=>{try{let r=JSON.stringify(t),o=n.navigator;return o&&typeof o.sendBeacon==\"function\"?o.sendBeacon(e,new Blob([r],{type:\"application/json\"})):(n.fetch(e,{method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:r,keepalive:!0}),!0)}catch(r){return!1}}}function bn(e={}){var ye,xe;let n=e.win||(typeof window!=\"undefined\"?window:null),t=e.doc||n&&n.document,r=e.now||(()=>Date.now()),o=e.endpoint||\"/api/doc\",s=(ye=e.idleMs)!=null?ye:J,a=(xe=e.sessionEveryMs)!=null?xe:3e4,u=e.slug||\"\",p=e.internal||null,d=e.sessionId||fn(),m=e.send||gn(o,n),c={},l=0,b=0,f=0,w=0,v=null,S=r(),k=!1,B=!1,C=[],Fe=()=>!!u||!!p,pe=i=>{if(!Fe())return!1;try{return m(i)!==!1}catch(g){return!1}},j=()=>!!t&&t.visibilityState===\"visible\"&&!k,me=i=>{let g=r()-i,y=Math.max(0,S-i)+s;return Math.max(0,Math.min(g,y))},G=()=>{v!=null&&l>0&&(c[l]=(c[l]||0)+me(v)/1e3),v=j()?r():null},fe=()=>{G(),v=null},K=()=>{v==null&&j()&&(v=r())},Y=()=>{let i=0;for(let g in c)i+=c[g];return v!=null&&(i+=me(v)/1e3),Math.round(i)},ge=()=>{let i={};for(let g in c)i[g]=Math.round(c[g]);return i},R=()=>{S=r(),k&&(k=!1,K())},be=(i,g)=>{p||pe({slug:u,event:i,page:g||b,maxPage:f,seconds:Y(),sessionId:d})},he=\"\",N=()=>{G();let i=Y(),g=`${i}|${f}|${w}`;if(g===he)return;let y={event:\"session\",sessionId:d,numPages:w,maxPage:f,totalSeconds:i,pagesTime:ge()};p?(y.internal=!0,y.docId=p.docId,y.email=p.email,y.name=p.name,p.it&&(y.it=p.it)):y.slug=u,pe(y)&&(he=g)},A=(i,g,y,ve)=>{!i||typeof i.addEventListener!=\"function\"||(i.addEventListener(g,y,ve),C.push(()=>{i.removeEventListener(g,y,ve)}))};return{sessionId:d,totalSeconds:Y,maxPage:()=>f,pageTimes:ge,start(){if(B)return;B=!0,be(\"open\",1),l=1,S=r(),v=j()?r():null,A(t,\"visibilitychange\",()=>{t.visibilityState===\"hidden\"?(fe(),N()):(R(),K())}),A(n,\"focus\",()=>{R(),K()});for(let y of mn)A(n,y,R,{passive:!0});A(e.scrollElement,\"scroll\",R,{passive:!0}),A(n,\"beforeunload\",N);let i=n.setInterval(()=>{!k&&r()-S>s&&(k=!0,fe())},5e3),g=n.setInterval(N,a);C.push(()=>{n.clearInterval(i),n.clearInterval(g)})},setPage(i){!i||i===b||(S=r(),G(),l=i,b=i,i>f&&(f=i,be(\"page\",i)))},setPageCount(i){w=i||0},noteActivity:R,flush:N,stop(){for(;C.length;){let i=C.pop();try{i==null||i()}catch(g){}}B=!1}}}var D={};M(D,{STORAGE_KEYS:()=>_,attendeeKey:()=>vn,authorToken:()=>Mn,avatarHtml:()=>te,canModerate:()=>ie,createBudget:()=>Rn,createFileEcritures:()=>An,createScheduler:()=>Sn,escapeHtml:()=>x,fetchBorne:()=>kn,flattenPresence:()=>hn,formatMessageBody:()=>re,initials:()=>$e,isMentioned:()=>_n,isMine:()=>E,presenceId:()=>In,reactorId:()=>se,referenceAuteur:()=>wn,shouldNotify:()=>En,unreadLabel:()=>Tn});var _={attendeeKey:\"3dd-present-attkey\",authorToken:\"3dd-present-authtoken\",chatMuted:\"3dd-present-mute\",presenceId:\"3dd-present-uid\"};function x(e){return String(e==null?\"\":e).replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/\"/g,\"&quot;\")}function $e(e){let n=(e||\"?\").trim().split(/\\s+/);return(((n[0]||\"\")[0]||\"?\")+((n[1]||\"\")[0]||\"\")).toUpperCase()}function te(e,n){return e?`<img src=\"${x(e)}\" alt=\"\">`:x($e(n))}function re(e){let n=x(e);return n=n.replace(/(https?:\\/\\/[^\\s<]+)/g,t=>`<a href=\"${t}\" target=_blank rel=noreferrer class=cm-link>${t}</a>`),n=n.replace(/(^|\\s)@([\\p{L}0-9_'.-]+)/gu,(t,r,o)=>`${r}<span class=cm-mention>@${o}</span>`),n}function hn(e){let n=new Map;for(let t in e||{})for(let r of(e||{})[t]||[]){let o=String(r.uid||r.email||r.name||\"\").toLowerCase()||`_${t}_${n.size}`;(!n.get(o)||r.role===\"presenter\")&&n.set(o,r)}return[...n.values()]}function yn(e,n){try{return e?e.getItem(n):null}catch(t){return null}}function xn(e,n,t){try{e==null||e.setItem(n,t)}catch(r){}}function vn(e,n=\"anon\",t=oe){try{if(!e)return`anon-${n}`;let r=e.getItem(_.attendeeKey);if(r)return r;let o=`anon-${t()}`;return e.setItem(_.attendeeKey,o),o}catch(r){return`anon-${n}`}}function oe(){let e=typeof globalThis!=\"undefined\"?globalThis.crypto:void 0;if(e&&typeof e.randomUUID==\"function\")return e.randomUUID().replace(/-/g,\"\");if(e&&typeof e.getRandomValues==\"function\"){let n=e.getRandomValues(new Uint8Array(24));return Array.from(n,t=>t.toString(16).padStart(2,\"0\")).join(\"\")}try{console.warn(\"[player] crypto indisponible : jeton d'auteur affaibli\")}catch(n){}return Math.random().toString(36).slice(2)+Math.random().toString(36).slice(2)}function Mn(e,n=oe){let t=yn(e,_.authorToken);if(t)return t;let r=n();return xn(e,_.authorToken,r),r}async function wn(e,n){let t=n!==void 0?n:typeof globalThis!=\"undefined\"&&globalThis.crypto?globalThis.crypto.subtle:null;if(!t||!e)return\"\";try{let r=async o=>{let s=await t.digest(\"SHA-256\",new TextEncoder().encode(o));return Array.from(new Uint8Array(s),a=>a.toString(16).padStart(2,\"0\")).join(\"\")};return(await r(\"ref:\"+await r(e))).slice(0,16)}catch(r){return\"\"}}function se(e){return String(e&&e.ref||\"\")}function E(e,n){return!e||!n||!e.author_ref||!n.ref?!1:e.author_ref===n.ref}function ie(e){return!!(e&&e.role===\"presenter\")}function _n(e,n){if(!n||!n.name)return!1;let t=(n.name.split(/\\s+/)[0]||\"\").toLowerCase();return t?String(e&&e.body||\"\").toLowerCase().includes(`@${t}`)&&!E(e,n):!1}function En(e){let{msg:n,me:t,historyLoaded:r,chatHidden:o}=e;return!r||!n||n.deleted||E(n,t)?!1:o}function Tn(e){return!e||e<=0?\"\":e>9?\"9+\":String(e)}function Sn(e,n={}){var b;let t=(b=n.minMs)!=null?b:300,r=n.now||(()=>Date.now()),o=n.setTimer||((f,w)=>setTimeout(f,w)),s=n.clearTimer||(f=>clearTimeout(f)),a=!1,u=!1,p=-1/0,d=null,m=!1;function c(){if(m||a){u=!0;return}let f=t-(r()-p);if(f>0){l(f);return}a=!0,u=!1,p=r();let w=!1;e(()=>{w||(w=!0,a=!1,u&&!m&&c())})}function l(f){m||d!==null||(d=o(()=>{d=null,c()},Math.max(0,f)))}return{signaler(){m||c()},maintenant(){m||(p=-1/0,c())},arreter(){m=!0,d!==null&&(s(d),d=null)}}}function kn(e,n,t=ne,r={}){let o=r.fetch||(typeof fetch==\"function\"?fetch:void 0);if(!o)return Promise.reject(new Error(\"fetch indisponible\"));let s=r.setTimer||((l,b)=>setTimeout(l,b)),a=r.clearTimer||(l=>clearTimeout(l)),u=null;try{u=new AbortController}catch(l){}let p=u?Ee(Z({},n||{}),{signal:u.signal}):Z({},n||{}),d=null,m=new Promise((l,b)=>{d=s(()=>{try{u==null||u.abort()}catch(f){}b(new Error(\"delai\"))},t)}),c=()=>{try{a(d)}catch(l){}};return Promise.race([o(e,p),m]).then(l=>(c(),l),l=>{throw c(),l})}function Rn(e){let n=e.now||(()=>Date.now()),t=Math.max(1,e.rafale),r=t,o=n();return{prendre(){let s=n();return r=Math.min(t,r+(s-o)*e.parHeure/36e5),o=s,r<1?!1:(r-=1,!0)},restants:()=>r}}function An(e={}){var d;let n=(d=e.minMs)!=null?d:0,t=e.now||(()=>Date.now()),r=e.setTimer||((m,c)=>setTimeout(m,c)),o=new Map,s=!1,a=-1/0,u=!1;function p(){if(s||o.size===0)return;let m=n-(t()-a);if(m>0){if(u)return;u=!0,r(()=>{u=!1,p()},m);return}let c=o.keys().next().value,l=o.get(c);o.delete(c),s=!0,a=t(),Promise.resolve().then(l.tache).then(b=>l.regler(b),()=>l.regler(null)).then(()=>{s=!1,p()})}return{poser(m,c){return new Promise(l=>{let b=o.get(m);o.set(m,{tache:c,regler:f=>{b&&b.regler(f),l(f)}}),p()})},enAttente:()=>o.size}}function In(e,n=oe){try{if(e){let t=e.getItem(_.presenceId);if(t)return t;let r=`p-${n()}`;return e.setItem(_.presenceId,r),r}}catch(t){}return`p-${n()}`}var W={};M(W,{messageClassName:()=>Cn,renderActions:()=>De,renderAttachment:()=>Ue,renderMessage:()=>Pn,renderReactions:()=>He});function He(e,n){let t=e&&e.reactions||{},r=se(n),o=\"\";for(let s in t){let a=t[s]||[];if(!a.length)continue;let u=a.indexOf(r)>=0;o+=`<button class=\"re-chip${u?\" on\":\"\"}\" data-e=\"${x(s)}\">${x(s)} ${a.length}</button>`}return o}function Ue(e){if(!e||!e.url)return\"\";let n=x(e.url);if(e.kind===\"image\")return`<a class=cm-att href=\"${n}\" target=_blank rel=noreferrer><img src=\"${n}\" alt=\"\" loading=lazy></a>`;let t=x(e.name||\"Document.pdf\");return`<a class=cm-att-pdf href=\"${n}\" target=_blank rel=noreferrer data-pdf=\"${n}\"><span class=cm-att-ph></span><span class=cm-pdflabel>${t}</span></a>`}function De(e,n){let t=E(e,n.me),r=`<button class=cm-react title=\"R\\xE9agir\">${n.reactIcon||\"\"}</button><button class=cm-reply title=\"R\\xE9pondre\">\\u21A9</button>`;return t&&(r+='<button class=cm-edit title=\"Modifier\">\\u270E</button>'),(t||ie(n.me))&&(r+='<button class=cm-del-btn title=\"Supprimer\">\\u{1F5D1}</button>'),r}function Pn(e,n){if(e.deleted)return'<span class=a></span><span class=b><div class=\"txt cm-del\">Message supprim\\xE9</div></span>';let t=e.reply_to?`<div class=cm-q><b>${x(e.reply_name||\"\")}</b> ${x(e.reply_text||\"\")}</div>`:\"\",r=e.edited?\" <span class=cm-ed>(modifi\\xE9)</span>\":\"\",o=e.body?`<div class=txt>${re(e.body)}${r}</div>`:\"\",s=e.is_presenter?\" <span class=tag>pr\\xE9sentateur</span>\":\"\";return`<span class=a>${te(e.author_avatar,e.author_name)}</span><span class=b><div class=who><b>${x(e.author_name||\"Invit\\xE9\")}</b>${s}</div>`+t+o+Ue(e.attachment)+`<div class=cm-re>${He(e,n.me)}</div></span><span class=cm-act>${De(e,n)}</span>`}function Cn(e,n,t){return\"cm\"+(E(e,n)?\" me\":\"\")+(e.deleted?\" isdel\":\"\")+(t?\" mentioned\":\"\")}var V={};M(V,{DEFAULT_CENTER:()=>le,DEFAULT_ZOOM:()=>ce,MAP_TYPES:()=>I,cycleMapType:()=>Nn,initialMapContent:()=>Ln,mapTypeLabel:()=>On,sanitizeContent:()=>de});var I=[\"roadmap\",\"satellite\",\"hybrid\"],le=[46.6,2.5],ce=6;function T(e){let n=Number(e);return Number.isFinite(n)?n:null}function ae(e){if(!Array.isArray(e))return null;let n=T(e[0]),t=T(e[1]);return n!=null&&t!=null?[n,t]:null}var ue=(e,n,t)=>Math.max(n,Math.min(t,e));function de(e){if(!e||typeof e!=\"object\")return null;let n=e;if(n.kind===\"pdf\"||n.kind==null)return null;if(n.kind===\"streetview\"){let t=ae(n.position);if(!t)return null;let r=n.pov&&typeof n.pov==\"object\"?n.pov:null,o=r?{heading:T(r.heading)||0,pitch:ue(T(r.pitch)||0,-90,90)}:{heading:0,pitch:0};return{kind:\"streetview\",position:t,pov:o,zoom:ue(T(n.zoom)||1,0,5)}}return n.kind!==\"map\"?null:{kind:\"map\",center:ae(n.center)||[...le],zoom:ue(Math.trunc(T(n.zoom)||ce),1,21),marker:ae(n.marker),mapType:I.includes(n.mapType)?n.mapType:null,label:String(n.label||\"\").slice(0,160)||null}}function Nn(e){let n=I.indexOf(e);return I[(n+1)%I.length]}function On(e){return e===\"roadmap\"?\"\\u{1F6F0} Satellite\":e===\"satellite\"?\"\\u{1F5FA} Hybride\":\"\\u{1F5FA} Plan\"}function Ln(){return{kind:\"map\",center:[...le],zoom:ce,marker:null,mapType:null,label:null}}var z={};M(z,{CURRENT_PAGE_MARGIN:()=>Vn,DEFAULT_ASPECT:()=>Un,MAX_ZOOM:()=>Hn,MIN_PAGE_WIDTH:()=>Dn,MIN_ZOOM:()=>$n,PRERENDER_MARGIN:()=>Wn,ROTATIONS:()=>Zn,ancrageApresZoom:()=>qn,arrowState:()=>Bn,aspectApresRotation:()=>ze,averageColor:()=>Kn,clampPage:()=>Ve,clampZoom:()=>zn,fitWidth:()=>Gn,isImageDocument:()=>Yn,progressPercent:()=>Fn,rotationEffective:()=>P});var $n=.5,Hn=3,Un=1.35,Dn=280,Wn=\"500px 0px\",Vn=\"-48% 0px -48% 0px\";function zn(e){let n=Math.round((Number(e)||0)*10)/10;return Math.max(.5,Math.min(3,n))}function Ve(e,n){return Math.max(1,Math.min(n||1,Number(e)||1))}function Fn(e,n){return n?Math.round(Ve(e,n)/n*100):0}function Bn(e,n){return{prevDisabled:e<=1,nextDisabled:!!n&&e>=n}}var jn=28;function Gn(e){var a;let n=(a=e.zoom)!=null?a:1,t=Math.max(280,e.containerWidth||900)*n;if(!e.onePage)return t;let r=ze(e.aspect,e.rotation),s=((e.containerHeight||600)-jn-(e.overlap||0)-(e.reserve||0))/r;return s>120?Math.min(t,s):t}function Kn(e){let n=e.length/4;if(!n)return\"rgb(0,0,0)\";let t=0,r=0,o=0;for(let s=0;s<e.length;s+=4)t+=e[s],r+=e[s+1],o+=e[s+2];return`rgb(${Math.round(t/n)},${Math.round(r/n)},${Math.round(o/n)})`}function Yn(e,n){return/[.](png|jpe?g|webp|gif|avif)($|[?])/i.test(String(e||n||\"\"))}var Zn=[0,90,180,270],h=(e,n=0)=>typeof e==\"number\"&&Number.isFinite(e)?e:n;function P(e,n){return(Math.round((h(e)+h(n))/90)%4+4)%4*90}function ze(e,n){let t=h(e,0)>0?e:1.35,r=P(0,n);return r===90||r===270?1/t:t}function We(e,n,t,r,o,s,a){let u=Math.min(Math.max(0,o),Math.max(0,r)),p=u+Math.max(0,r-u)*a,d=Math.min(Math.max(0,s),Math.max(0,r)),m=r-d>0?(p-d)/(r-d):1,c=Math.max(0,(t-r)/2),l=n+e-c,b=d+Math.max(0,l-d)*m-n;return Math.min(Math.max(0,b),Math.max(0,p-t))}function qn(e){let n=h(e.zoomAvant,0),t=h(e.zoomApres,0),r={x:h(e.defilement&&e.defilement.x),y:h(e.defilement&&e.defilement.y)};if(n<=0||t<=0)return r;let o=t/n,s=e.fixe||{largeur:0,hauteur:0},a=e.fixeDebut||{largeur:0,hauteur:0};return{x:We(r.x,h(e.point&&e.point.x),h(e.cadre&&e.cadre.largeur),h(e.contenu&&e.contenu.largeur),h(s.largeur),h(a.largeur),o),y:We(r.y,h(e.point&&e.point.y),h(e.cadre&&e.cadre.hauteur),h(e.contenu&&e.contenu.hauteur),h(s.hauteur),h(a.hauteur),o)}}var F={};M(F,{presentationTransition:()=>Qn,switchDocUrl:()=>Xn});function Qn(e,n={}){if(!e)return[{kind:\"nothing\"}];if(e.active===!1)return[{kind:\"ended\"}];let t=de(e.content);if(t)return[{kind:\"show-map\",content:t}];let r=[{kind:\"leave-map\"}],o=P(0,e.view_rotation);return o!==P(0,n.rotation)&&r.push({kind:\"rotate\",rotation:o}),e.file_url&&e.file_url!==n.docUrl?(r.push({kind:\"switch-doc\",url:e.file_url,name:e.file_name||void 0,title:e.doc_title||void 0,updatedAt:e.updated_at||void 0}),r):(e.current_page&&r.push({kind:\"show-page\",page:e.current_page}),r)}function Xn(e,n){let t=encodeURIComponent(n||String(Date.now()));return`${e}${e.includes(\"?\")?\"&\":\"?\"}v=${t}`}return qe(Jn);})();", SOURCE_HASH: "720cf1b3ec849d63" };
@@ -20,7 +20,7 @@ function presentHtml(pres, nonce, logoUrl, supaUrl, supaKey) {
20
20
  const presenter = esc(pres.presenter_name || "");
21
21
  const logo = esc(logoUrl || "");
22
22
  const fileUrl = `/api/doc?present=${encodeURIComponent(pres.slug)}&file=1`;
23
- const cfg = jsonPourScript({ fileUrl, docUrl: pres.file_url, pdfjs: PDFJS, pdfjsWorker: PDFJS_WORKER, slug: pres.slug, fileName: pres.file_name || "", page: pres.current_page || 1, active: pres.active !== false, content: pres.content || null, supaUrl, supaKey, title: pres.doc_title || pres.file_name || "Document" });
23
+ const cfg = jsonPourScript({ fileUrl, docUrl: pres.file_url, pdfjs: PDFJS, pdfjsWorker: PDFJS_WORKER, slug: pres.slug, fileName: pres.file_name || "", page: pres.current_page || 1, rotation: pres.view_rotation || 0, active: pres.active !== false, content: pres.content || null, supaUrl, supaKey, title: pres.doc_title || pres.file_name || "Document" });
24
24
  return `<!doctype html><html lang=fr><head><meta charset=utf-8>
25
25
  <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=3">
26
26
  <meta name=robots content="noindex,nofollow">
@@ -95,7 +95,7 @@ function presentHtml(pres, nonce, logoUrl, supaUrl, supaKey) {
95
95
  <script nonce="${nonce}">
96
96
  (function(){
97
97
  var CFG=${cfg};
98
- var PDF=null, total=0, cur=CFG.page||1, ready=false;
98
+ var PDF=null, total=0, cur=CFG.page||1, rot=CFG.rotation||0, ready=false;
99
99
  // ⚠️ DEUX GÉNÉRATIONS, PARCE QU'IL Y A DEUX COURSES DISTINCTES (P1 audit externe).
100
100
  //
101
101
  // docGen : le présentateur change de document pendant qu'un chargement est en cours. Le
@@ -137,9 +137,13 @@ function presentHtml(pres, nonce, logoUrl, supaUrl, supaKey) {
137
137
  // arrivait : ce résultat n'est plus celui qu'on attend. On ne le pose pas.
138
138
  if(monDoc!==docGen || monRendu!==renderGen) return;
139
139
  var availW=Math.max(120, stage.clientWidth-40), availH=Math.max(120, stage.clientHeight-40);
140
- var v1=page.getViewport({scale:1});
140
+ // ⚠️ ON COMPOSE, ON N'ÉCRASE PAS — même piège que dans la visionneuse. getViewport prend par
141
+ // défaut la rotation du fichier ; passer une valeur absolue coucherait un document numérisé qui
142
+ // était droit. La composition vit dans src/viewer.ts, où elle est éprouvée.
143
+ var rotEff=Player.viewer.rotationEffective(page.rotate,rot);
144
+ var v1=page.getViewport({scale:1,rotation:rotEff});
141
145
  var scale=Math.min(availW/v1.width, availH/v1.height); // fit entier → une page à l'écran
142
- var dpr=window.devicePixelRatio||1, vp=page.getViewport({scale:scale});
146
+ var dpr=window.devicePixelRatio||1, vp=page.getViewport({scale:scale,rotation:rotEff});
143
147
  var cv=document.createElement('canvas'); cv.width=Math.floor(vp.width*dpr); cv.height=Math.floor(vp.height*dpr);
144
148
  cv.setAttribute('role','img'); cv.setAttribute('aria-label','Page '+n+(total>1?' sur '+total:''));
145
149
  cv.style.width=vp.width+'px'; cv.style.height=vp.height+'px';
@@ -282,10 +286,10 @@ function presentHtml(pres, nonce, logoUrl, supaUrl, supaKey) {
282
286
  if(!row) return;
283
287
  // La table et la diffusion portent la même vérité : sans cette garde, chaque changement de
284
288
  // page serait rendu deux fois (scintillement), et chaque carte ré-ouverte inutilement.
285
- var sig=''; try{ sig=JSON.stringify([row.active,row.current_page,row.file_url,row.content]); }catch(e){ sig=String(Math.random()); }
289
+ var sig=''; try{ sig=JSON.stringify([row.active,row.current_page,row.file_url,row.content,row.view_rotation]); }catch(e){ sig=String(Math.random()); }
286
290
  if(sig===_etatVu) return;
287
291
  _etatVu=sig;
288
- var actions=Player.presentationState.presentationTransition(row,{docUrl:CFG.docUrl});
292
+ var actions=Player.presentationState.presentationTransition(row,{docUrl:CFG.docUrl,rotation:rot});
289
293
  for(var i=0;i<actions.length;i++){ var a=actions[i];
290
294
  if(a.kind==='ended'){ ended(); return; }
291
295
  if(a.kind==='show-map'){ if(window.Map3DD){ if(a.content.kind==='streetview') Map3DD.enterSV(a.content,false); else Map3DD.enter(a.content,false); } return; }
@@ -293,6 +297,9 @@ function presentHtml(pres, nonce, logoUrl, supaUrl, supaKey) {
293
297
  // switchDoc pose LUI-MÊME docUrl/fileName/titre : les poser ici, en partie, était
294
298
  // exactement ce qui laissait fileName en arrière.
295
299
  if(a.kind==='switch-doc'){ switchDoc(row); return; }
300
+ // ⚠️ AVANT la page, et c'est l'ordre que presentationTransition garantit : tourner après avoir
301
+ // rendu ferait rendre deux fois, la première fois pour rien.
302
+ if(a.kind==='rotate'){ rot=a.rotation; renderGen++; show(cur); }
296
303
  if(a.kind==='show-page'){ show(a.page); }
297
304
  }
298
305
  }