@supersoniks/concorde 4.9.3 → 4.9.5

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.
package/README.md CHANGED
@@ -28,7 +28,7 @@ yarn ai-init
28
28
  node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
29
29
  ```
30
30
 
31
- Installe `.cursor/skills`, `.cursor/rules`, `.aiassistant/rules` et `AGENTS.md`. Voir [ai/README.md](ai/README.md).
31
+ Installe `.cursor/skills`, `.cursor/rules`, `.aiassistant/rules`. `AGENTS.md` n’est créé que s’il est absent ; un fichier projet existant (sans marker Concorde) est laissé intact. Voir [ai/README.md](ai/README.md).
32
32
 
33
33
  ## 📁 Structure du projet
34
34
 
package/ai/README.md CHANGED
@@ -10,12 +10,37 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
10
10
 
11
11
  Options :
12
12
 
13
- - `--overlay <dir>` — couche additionnelle (ex. kit starter)
14
- - `--merge-agents` — fusionne avec un `AGENTS.md` existant
13
+ - `--overlay <dir>` — couche projet ; lit `AGENTS.concorde.md` (legacy : `AGENTS.overlay.md`, `AGENTS.starter.md`)
14
+ - `--skip-agents` — n’écrit jamais `AGENTS.md` (skills / rules seulement)
15
+ - `--merge-agents` — opt-in : conserve le préambule projet et ajoute / rafraîchit le bloc Concorde
16
+ - `--force-agents` — opt-in : **remplace** tout `AGENTS.md` (destructif)
15
17
  - `--cursor-only` / `--jetbrains-only`
16
18
 
17
19
  Depuis le dépôt Concorde (dev) : `yarn ai-init`
18
20
 
21
+ ## Politique `AGENTS.md` (non invasive)
22
+
23
+ | Situation | Comportement par défaut |
24
+ |-----------|-------------------------|
25
+ | Pas de `AGENTS.md` | Création du guide Concorde |
26
+ | Fichier avec `<!-- concorde-ai -->` | Rafraîchit la zone gérée seulement |
27
+ | Fichier **sans** marker (notes projet) | **Laissé intact** — skills / rules suffisent |
28
+ | `--merge-agents` | Préambule projet + bloc Concorde après le marker |
29
+ | `--force-agents` | Remplacement complet |
30
+ | `--skip-agents` | Jamais d’écriture `AGENTS.md` |
31
+
32
+ ```text
33
+ [optional project preamble — short, project-only]
34
+ <!-- concorde-ai -->
35
+ <package ai/AGENTS.md>
36
+ [--- + overlay AGENTS.concorde.md]
37
+ ```
38
+
39
+ - Tout **après** `<!-- concorde-ai -->` est **régénéré** à chaque run (pas d’empilement).
40
+ - Ne pas recopier le guide Concorde dans le préambule : notes projet → `overlay/AGENTS.concorde.md`.
41
+ - Si le préambule duplique `ai/AGENTS.md`, `ai-init` le **allège / drop** et affiche un warning.
42
+ - Legacy : `AGENTS.overlay.md` / `AGENTS.starter.md` encore lus si `AGENTS.concorde.md` est absent (warning de dépréciation).
43
+
19
44
  ## Contenu
20
45
 
21
46
  | Dossier | Cible |
@@ -23,8 +48,14 @@ Depuis le dépôt Concorde (dev) : `yarn ai-init`
23
48
  | `skills/` | `.cursor/skills/` (concorde, imports, scope, theme, menu) |
24
49
  | `cursor/rules/` | `.cursor/rules/` |
25
50
  | `jetbrains/rules/` | `.aiassistant/rules/` |
26
- | `AGENTS.md` | racine du projet |
51
+ | `AGENTS.md` | racine du projet **seulement** si absent, déjà marqué, ou via `--merge-agents` / `--force-agents` |
27
52
 
28
53
  ## Template starter
29
54
 
30
55
  Le package `create-concorde-ts-starter` ajoute un overlay via `yarn ai:sync`.
56
+
57
+ ## Tests
58
+
59
+ ```bash
60
+ node --test scripts/ai-init.test.mjs
61
+ ```
package/build-infos.json CHANGED
@@ -1 +1 @@
1
- {"date":1783597327}
1
+ {"date":1785410199}
@@ -1,4 +1,4 @@
1
- (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
1
+ (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 30 2026 13:16:38 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
2
2
  * @license
3
3
  * Copyright 2017 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -742,7 +742,7 @@ const j = class j {
742
742
  return new TextDecoder().decode(h);
743
743
  }
744
744
  };
745
- j.buildDate = "Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
745
+ j.buildDate = "Thu Jul 30 2026 13:16:38 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
746
746
  let E = j;
747
747
  if (typeof window < "u") {
748
748
  const s = window;
@@ -1,4 +1,4 @@
1
- (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
1
+ (function(Z){typeof define=="function"&&define.amd?define(Z):Z()})((function(){"use strict";var M,tt;let Z=class Ft{static getLanguage(){const t=document.documentElement.lang;return localStorage.getItem("SonicSelectedLanguage")||t}static getCookies(){return document.cookie.split(";").reduce((t,i)=>{const r=i.indexOf("=");return t[i.substring(0,r).trim()]=i.substring(r+1),t},{})}static everyAncestors(t,i){for(;t;){if(!i(t))return;t=t.parentNode||t.host}}static getScrollableAncestor(t){for(;t;){const i=t;if(i.nodeType===1){const r=window.getComputedStyle(i);if(r?.overflowY==="auto"||r?.overflowY==="scroll"||r?.overflowY==="hidden"||r?.overflowX==="auto"||r?.overflowX==="scroll"||r?.overflowX==="hidden")return t}t=t.parentNode||t.host}return null}static scopeAttributeNames(t){const i=t.toLowerCase();return i===t?[t]:[t,i]}static readScopeAttributeOnElement(t,i){for(const r of Ft.scopeAttributeNames(i))if(t.hasAttribute(r))return t.getAttribute(r)??"";return null}static getAncestorAttributeValue(t,i){if(!t)return null;let r=t;for(;r;){if(r instanceof HTMLElement){const o=Ft.readScopeAttributeOnElement(r,i);if(o!=null)return o}const e=r.parentNode||r.host;if(!e)break;r=e}return null}static getApiConfiguration(t){const i=Ft.getAncestorAttributeValue(t,"token"),r=Ft.getAncestorAttributeValue(t,"addHTTPResponse")!=null,e=Ft.getAncestorAttributeValue(t,"serviceURL");let o=null,n=null;const l=Ft.getAncestorAttributeValue(t,"tokenProvider"),c=Ft.getAncestorAttributeValue(t,"eventsApiToken");i||(o=Ft.getAncestorAttributeValue(t,"userName"),n=Ft.getAncestorAttributeValue(t,"password"));const h=Ft.getAncestorAttributeValue(t,"credentials")||void 0,u=t.getAttribute("cache"),d=t.hasAttribute("blockUntilDone"),p=t.hasAttribute("keepAlive");return{serviceURL:e,token:i,userName:o,password:n,authToken:c,tokenProvider:l,addHTTPResponse:r,credentials:h,cache:u,blockUntilDone:d,keepAlive:p}}static getClosestElement(t,i){for(;!(t.nodeName&&t.nodeName.toLowerCase()===i)&&(t.parentNode||t.host);)t=t.parentNode||t.host;return t.nodeName?t:null}static getClosestForm(t){return Ft.getClosestElement(t,"form")}static getAncestorsByTagNames(t,i){const r=new Set(i.map(n=>n.toLowerCase())),e=[];let o=t.parentNode||t.host;for(;o;)o instanceof Element&&r.has(o.tagName.toLowerCase())&&e.push(o),o=o.parentNode||o.host;return e}static getAncestorsBySelectors(t,i){const r=[];let e=t.parentNode||t.host;for(;e;){if(e instanceof Element)for(const o of i)try{if(e.matches(o)){r.push(e);break}}catch{}e=e.parentNode||e.host}return r}static async loadJS(t){return new Promise(async r=>{const e=document.createElement("script");e.src=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}static async loadCSS(t){return new Promise(async r=>{const e=document.createElement("link");e.type="text/css",e.rel="stylesheet",e.href=t,e.onload=()=>r(!0),e.onerror=()=>r(!0),document.head.appendChild(e)})}};const bi=s=>{const t=document.documentElement,i=new MutationObserver(e=>{for(let o of e)o.type==="attributes"&&o.attributeName==="lang"&&s()}),r={attributes:!0,attributeFilter:["lang"]};i.observe(t,r)};let Os=class{static ucFirst(t){return typeof t!="string"?t:t.charAt(0).toUpperCase()+t.substring(1)}static minutesDuration(t,i="",r="long"){i||(i=Z.getLanguage());const e=(h,u)=>[Math.floor(h/u),h%u];function o(h,u,d){return new Intl.NumberFormat(h,{style:"unit",unit:u,unitDisplay:d}).format}const[n,l]=e(t,60),c=[];return n&&c.push(o(i,"hour",r)(n)),l&&c.push(o(i,"minute",r)(l)),new Intl.ListFormat(i,{style:"long",type:"conjunction"}).format(c)}static js(t){try{return Function("return "+t)()}catch{return""}}};class _r{constructor(t){this.path=t}toString(){return this.path}}function wr(s){return new Proxy(s,{get(t,i){if(i==="path")return t.path;if(i==="toString")return t.toString.bind(t);if(i===Symbol.toStringTag)return"DataProviderKey";if(typeof i=="symbol")return t[i];const r=t.path?`${t.path}.${String(i)}`:String(i);return wr(new _r(r))}})}const Jo=/\$\{|\{\$/;function tn(s){return Jo.test(s)}function mi(s){const t=typeof s=="string"?s:s.path;if(tn(t))throw new Error("Static publisher path required for get/set/dp. Use @subscribe, @publish, or @handle for dynamic DataProviderKey paths.");return t}const es=function(s){return this instanceof es?wr(new _r(s)):new es(s)};let nt=class oe{static shallowEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n];if(r?l!==c:l!=c)return!1}return!0}static deepEqual(t,i,r=!0){const e=Object.keys(t),o=Object.keys(i);if(e.length!==o.length&&r)return!1;for(const n of e){const l=t[n],c=i[n],h=oe.isObject(l)&&oe.isObject(c),u=r?l!==c:l!=c;if(h&&!oe.deepEqual(l,c)||!h&&u)return!1}return!0}static isObject(t){return t!=null&&typeof t=="object"}static isUndefindOrNull(t){return t==null}static isEmpty(t){return oe.isUndefindOrNull(t)?!0:Object.keys(t).length===0}static traverse(t,i,r=!1){for(const e of i){const o=t[e];if(o===void 0)return;r&&oe.isObject(o)?t=Object.assign(Array.isArray(o)?[]:{},t,o):t=t[e]}return t}static traverseDotNotation(t,i,r=!1){return oe.traverse(t,i.split("."),r)}static getURLSearchArray(t,i=""){let r=[];for(let e in t){const o=t[e];i&&(e=i+"["+e+"]"),oe.isObject(o)?r=[...r,...this.getURLSearchArray(o,e)]:r.push(`${e}=${o}`)}return r}static getURLSearchString(t){return oe.getURLSearchArray(t,"").join("&")}};const yt=nt.traverseDotNotation;let en=class{static async queueTaskPromise(){return new Promise(t=>{window.queueMicrotask(()=>t(null))})}static async delayPromise(t){return new Promise(i=>{setTimeout(i,t)})}},xr="sonic";typeof __SONIC_PREFIX__<"u"&&(xr=__SONIC_PREFIX__);let Pr=xr.replace(/-([a-z])/g,s=>s[1].toUpperCase());const Es=Pr.charAt(0).toUpperCase()+Pr.slice(1),sn=new Set(["localStorageMode","expirationDelayMs","invalidateOnPageShow"]);function Cr(s){return s==null||typeof s!="object"||Array.isArray(s)?!1:Object.keys(s).some(t=>sn.has(t))}function Ls(s){return Object.prototype.hasOwnProperty.call(s,"__value")}function ne(s){return typeof s=="object"&&s!==null}let ze="sonic";typeof __SONIC_PREFIX__>"u"&&(ze="sonic");const gi=ze=="sonic"?"publisher-proxies-data":ze+"-publisher-proxies-data",xe=class xe{constructor(t,i,r){for(this._proxies_=new Map,this._is_savable_=!1,this._expiration_delay_=1e3*60*60*12,this._invalidate_on_page_show_=!1,this._invalidateListeners_=new Set,this._formInvalidateListeners_=new Set,this._assignListeners_=new Set,this._mutationListeners_=new Set,this._fillListeners_=new Set,this._templateFillListeners_=new Set,this._lockInternalMutationPublishing_=!1,this._instanceCounter_=0,this._assignmentId_=0,this._value_=t,this.parent=i||null,this._parentKey_=r,this.root=this,this._instanceCounter_=0;this.root.parent;)this.root=this.root.parent}delete(){for(const t in this._proxies_.keys())t!="_parent_"&&this._proxies_.get(t)?.delete();this._invalidateListeners_.clear(),this._formInvalidateListeners_.clear(),this._assignListeners_.clear(),this._mutationListeners_.clear(),this._fillListeners_.clear(),this._templateFillListeners_.clear(),this._proxies_.clear(),xe.instances.delete(this._instanceCounter_)}hasListener(){return this._templateFillListeners_.size>0||this._assignListeners_.size>0||this._invalidateListeners_.size>0||this._formInvalidateListeners_.size>0||this._mutationListeners_.size>0||this._fillListeners_.size>0}_publishInternalMutation_(t=!1){if(this._mutationListeners_.forEach(i=>i()),this._is_savable_&&!E.changed){E.changed=!0,E.saveId++;const i=E.saveId;setTimeout(()=>E.getInstance().saveToLocalStorage(i),1e3)}t||this.parent&&this.parent._publishInternalMutation_()}async _publishAssignement_(t=!1){if(this._assignmentId_++,this._assignmentId_!==this._assignmentId_)return;const r=this.get();this._assignListeners_.forEach(e=>{e(r)}),this._publishInternalMutation_(t)}_publishInvalidation_(){this._invalidateListeners_.forEach(t=>t())}_publishFormInvalidation_(){this._formInvalidateListeners_.forEach(t=>t())}_publishDynamicFilling_(t,i){this._fillListeners_.forEach(r=>{r[t]!==i&&(r[t]=i)}),this._publishTemplateFilling_(t,i)}_publishTemplateFilling_(t,i){this._templateFillListeners_.forEach(r=>{const e=Object.getOwnPropertyDescriptor(r,t);e&&!e.set&&!e.writable||(r.propertyMap&&r.propertyMap[t]&&(t=r.propertyMap[t]),typeof r[t]<"u"&&r[t]!==i&&(r[t]=i))})}onAssign(t,i=!0){typeof t=="function"&&(this._assignListeners_.has(t)||(this._assignListeners_.add(t),i&&t(this.get())))}offAssign(t){this._assignListeners_.delete(t)}onInvalidate(t){typeof t=="function"&&this._invalidateListeners_.add(t)}offInvalidate(t){typeof t=="function"&&this._invalidateListeners_.delete(t)}invalidate(){this._publishInvalidation_()}onFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.add(t)}offFormInvalidate(t){typeof t=="function"&&this._formInvalidateListeners_.delete(t)}invalidateForm(){this._publishFormInvalidation_()}onInternalMutation(t){typeof t=="function"&&(this._mutationListeners_.add(t),t())}offInternalMutation(t){typeof t=="function"&&this._mutationListeners_.delete(t)}startTemplateFilling(t){if(this._templateFillListeners_.add(t),typeof this._value_=="object")for(const i in this._value_){let r=i;const e=this._value_[i];t.propertyMap&&t.propertyMap[i]&&(r=t.propertyMap[i]),typeof t[i]<"u"&&t[i]!==e&&(t[r]=e)}}stopTemplateFilling(t){this._templateFillListeners_.delete(t)}startDynamicFilling(t){this._fillListeners_.add(t);for(const i in this._value_){const r=this._value_[i];t[i]!==r&&(t[i]=r)}}stopDynamicFilling(t){this._fillListeners_.delete(t)}set(t,i=!1){if(this._value_===t||ne(this._value_)&&ne(t)&&t&&Ls(this._value_)&&Ls(t)&&this._value_.__value===t.__value||!ne(t)&&t===this._value_.__value)return!0;this._value_=ne(t)?t:{__value:t},this._cachedGet_=void 0;const r=Ls(this._value_);if(this._parentKey_&&this.parent){const e=Ls(this._value_)?this._value_.__value:this._value_;if(this.parent?.get()==null&&this.parent?.get()==null)if(isNaN(Number(this._parentKey_)))this.parent.set({[this._parentKey_]:e});else{const o=[];o[Number(this._parentKey_)]=e,this.parent.set(o)}else this.parent._value_[this._parentKey_]=e}if(r)return this._proxies_.forEach((e,o)=>{o!="_parent_"&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(i),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_.__value),!0;for(const e in this._value_)this._value_[e]===void 0&&delete this._value_[e];if(this._proxies_.forEach((e,o)=>{const n=this._value_[o];o!="_parent_"&&n===void 0&&n!==null&&isNaN(Number(o))&&(e.set(null),this._publishDynamicFilling_(o,null))}),this._publishAssignement_(),this.parent&&this._parentKey_&&this.parent._publishDynamicFilling_(this._parentKey_,this._value_),ne(this._value_))for(const e in this._value_){const o=t[e],l=ne(o)?o:{__value:o};if(!this._proxies_.has(e)){this._publishDynamicFilling_(e,o);continue}this._proxies_.get(e)?.set(l,!0),this._publishDynamicFilling_(e,o)}return!0}get(){if(rn(this),this._cachedGet_!==void 0)return this._cachedGet_;if(Object.prototype.hasOwnProperty.call(this._value_,"__value")){const t=this._value_.__value;return this._cachedGet_=t??null}return this._cachedGet_=this._value_!=null?this._value_:null}get $tag(){return this._instanceCounter_||(xe.instancesCounter++,this._instanceCounter_=xe.instancesCounter),xe.instances.set(this._instanceCounter_,this),"<"+ze+'-publisher-proxy publisher="'+this._instanceCounter_+'"></'+ze+"-publisher-proxy>"}};xe.instances=new Map,xe.instancesCounter=0;let ss=xe;const Ts=[];function rn(s){Ts.length>0&&Ts[0].add(s)}function Sr(){Ts.unshift(new Set)}function $r(){return Ts.shift()}const F=class F{constructor(){if(this.enabledLocaStorageProxies=[],this.publishers=new Map,this.localStorageData={},this.isLocalStrorageReady=null,this.initialisedData=[],F.instance!=null)throw"Singleton / use getInstance";F.instance=this,this.isLocalStrorageReady=this.cleanStorageData(),F.initPageShowHandler()}static initPageShowHandler(){F.pageShowHandlerInitialized||(F.pageShowHandlerInitialized=!0,window.addEventListener("pageshow",t=>{t.persisted&&F.getInstance().invalidateAll()}))}invalidateAll(){this.publishers.forEach(t=>{t._invalidate_on_page_show_&&t.invalidate()})}async cleanStorageData(){return new Promise(t=>{(async()=>{try{let r=localStorage.getItem(gi),e=null;if(r&&(e=await this.decompress(r,"gzip")),e)try{this.localStorageData=JSON.parse(e)}catch{this.localStorageData={}}else r=await this.compress("{}","gzip"),localStorage.setItem(gi,r),this.localStorageData={};const o=1e3*60*60*12;for(const n in this.localStorageData){const l=this.localStorageData[n],c=new Date().getTime()-(l.expirationDelayMs||o);l.lastModifiationMS<c&&delete this.localStorageData[n]}t(!0)}catch{window.requestAnimationFrame(()=>{t(!1)}),console.warn("no publisher cache in this browser")}})()})}static getInstance(t){if(t){const i=F.instances.get(t);return i||(console.warn("No PublisherManager instance registered with id:",t,"creating new one"),new F)}return F.instance==null?new F:F.instance}static get(t,i){return F.getInstance().get(t,i)}async setLocalData(t,i){await this.isLocalStrorageReady,t.set(this.localStorageData[i+"¤lang_"+Z.getLanguage()]?.data||t.get())}get(t,i){const r=i?.localStorageMode==="enabled",e=i?.invalidateOnPageShow===!0;if(!this.publishers.has(t)){const l=vi({});this.set(t,l)}const o=this.publishers.get(t);return r&&this.initialisedData.indexOf(t)===-1&&(i?.expirationDelayMs&&(o._expiration_delay_=i.expirationDelayMs),o._is_savable_=!0,this.initialisedData.push(t),this.setLocalData(o,t)),e&&(o._invalidate_on_page_show_=e),this.publishers.get(t)}set(t,i){this.publishers.set(t,i)}delete(t){return this.publishers.has(t)?(this.publishers.delete(t),!0):!1}async saveToLocalStorage(t=0){if(!(t!==F.saveId&&t%10!=0))try{if(!F.changed||F.saving)return;F.saving=!0,F.changed=!1;const i=Array.from(this.publishers.keys());let r=!1;for(const e of i){const o=this.publishers.get(e);if(!o?._is_savable_)continue;const n=o?.get();n&&(this.localStorageData[e+"¤lang_"+Z.getLanguage()]={lastModifiationMS:new Date().getTime(),expirationDelayMs:o._expiration_delay_,data:n},r=!0)}if(r){const e=await this.compress(JSON.stringify(this.localStorageData),"gzip");localStorage.setItem(gi,e)}if(F.saving=!1,F.changed){F.saveId++;const e=F.saveId;setTimeout(()=>this.saveToLocalStorage(e),1e3)}}catch{F.saving=!1}}async compress(t,i){const r=new TextEncoder().encode(t),e=window,o=new e.CompressionStream(i),n=o.writable.getWriter();n.write(r),n.close();const l=await new Response(o.readable).arrayBuffer(),c=new Uint8Array(l);let h="";for(let u=0;u<c.length;u++)h+=String.fromCharCode(c[u]);return btoa(h)}async decompress(t,i){const r=atob(t),o=Uint8Array.from(r,u=>u.charCodeAt(0)).buffer,n=window,l=new n.DecompressionStream(i),c=l.writable.getWriter();c.write(o),c.close();const h=await new Response(l.readable).arrayBuffer();return new TextDecoder().decode(h)}};F.buildDate="Thu Jul 30 2026 13:16:38 GMT+0200 (Central European Summer Time)",F.changed=!1,F.saving=!1,F.saveId=0,F.instance=null,F.instances=new Map,F.pageShowHandlerInitialized=!1;let E=F;if(typeof window<"u"){const s=window;s[Es+"PublisherManager"]=s[Es+"PublisherManager"]||E}const on=new Set(["invalidate","onInvalidate","offInvalidate","invalidateForm","onFormInvalidate","offFormInvalidate","onAssign","offAssign","startDynamicFilling","stopDynamicFilling","startTemplateFilling","stopTemplateFilling","onInternalMutation","offInternalMutation","set","get","$tag","_cachedGet_","_templateFillListeners_","_fillListeners_","_assignListeners_","_invalidateListeners_","_formInvalidateListeners_","_publishInternalMutation_","hasListener","delete","_mutationListeners_","_publishDynamicFilling_","_publishInvalidation_","_publishFormInvalidation_","_publishTemplateFilling_","_publishAssignement_","_proxies_","parent","_parentKey_","_value_","_is_savable_","_expiration_delay_","_lockInternalMutationPublishing_","_instanceCounter_","_assignmentId_","_invalidate_on_page_show_"]);function nn(s,t){return{get:function(i,r){if(typeof r=="string"&&on.has(r))return s[r];if(r==Symbol.toPrimitive)return()=>t().get();if(!s._proxies_.has(r)){const e=s._value_[r],o=vi(ne(e)?e:{__value:e},s,r);o._proxies_.set("_parent_",t()),s._proxies_.set(r,o)}return s._proxies_.get(r)},set:function(i,r,e){if(r=="_value_")return s._value_=e,!0;if(r=="_cachedGet_")return s._cachedGet_=e,!0;if(r=="_assignmentId_")return s._assignmentId_=e,!0;if(r=="_is_savable_")return s._is_savable_=e,!0;if(r=="_expiration_delay_")return s._expiration_delay_=e,!0;if(r=="_invalidate_on_page_show_")return s._invalidate_on_page_show_=e,!0;if(r=="_instanceCounter_")return s._instanceCounter_=e,!0;if(!s._proxies_.has(r)){const n=vi({},s,r);n._proxies_.set("_parent_",t()),s._proxies_.set(r,n)}return s._value_[r]!==e&&(s._value_[r]=e,s._publishDynamicFilling_(r,e),s._proxies_.get(r)?.set(ne(e)?e:{__value:e})),!0},deleteProperty:function(i,r){return s._publishDynamicFilling_(r,null),s._proxies_.get(r)?.set(null),delete s._value_[r]},has:function(i,r){return r in s._value_&&r!="_lockInternalMutationPublishing_"},defineProperty:function(i,r,e){return e&&"value"in e&&(s._value_[r]=e.value),!0},getOwnPropertyDescriptor:function(i,r){return{enumerable:!0,configurable:!0}},ownKeys:function(i){return s._value_.__value?Object.keys(s._value_.__value):Object.keys(s._value_)}}}function vi(s,t=null,i){const r=new ss(s,t,i);let e=null;const o=nn(r,()=>e);return e=new Proxy(r,o),e}class an extends HTMLElement{constructor(){super(),this.publisherId="",this.onAssign=t=>{this.innerHTML=t.toString()}}connectedCallback(){this.publisherId=this.getAttribute("publisher")||"",this.publisher=ss.instances.get(parseInt(this.publisherId)),this.publisher?.onAssign(this.onAssign)}disconnectedCallback(){this.publisher?.offAssign(this.onAssign)}}try{customElements.define(ze+"-publisher-proxy",an)}catch{}const Is=(s,t)=>{if(typeof s=="function"){const i=s;return Sr(),i(),$r()}if(typeof s=="string"){const i=s.split("."),r=i.shift()||"";let e=E.get(r,t);e=nt.traverse(e,i);const o=new Set;return o.add(e),o}return new Set([s])};function ln(s){const t=mi(s);return Is(t).values().next().value?.get()}function Ms(s,t,i){const r=mi(s);return Is(r,i).values().next().value}function cn(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function Ns(s,t){return Cr(t)?Ms(s,void 0,t):Ms(s)}function hn(s,t){const i=mi(s);Is(i).values().next().value?.set(t)}let Fs=(M=class{static disable(){this.enabled&&(this.enabled=!1,Array.from(M.observedElements.keys()).forEach(t=>M.unObserve(t)))}static observe(t){if(!t||!M.enabled||M.observedElements.has(t))return;const i=new MutationObserver(M.onMutation),r={};r.childList=!0,r.subtree=!0,r.attributes=!0,r.attributeFilter=["data-bind"],i.observe(t,r),t.querySelectorAll("[data-bind]").forEach(e=>M.addPublisherListeners(e)),M.observedElements.set(t,i)}static unObserve(t){if(!t)return;const i=this.observedElements.get(t);i&&(i.disconnect(),t.querySelectorAll("[data-bind]").forEach(r=>M.removePublisherListeners(r)))}static onAdded(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.addPublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.addPublisherListeners(i)):t.childNodes.forEach(i=>M.onAdded(i))}static onRemoved(t){t.hasAttribute&&t.hasAttribute("data-bind")&&M.removePublisherListeners(t),t.querySelectorAll?t.querySelectorAll("[data-bind]").forEach(i=>M.removePublisherListeners(i)):t.childNodes.forEach(i=>M.onRemoved(i))}static onMutation(t){for(const i of t)switch(i.type){case"attributes":M.addPublisherListeners(i.target);break;case"childList":i.addedNodes.forEach(r=>{M.onAdded(r)}),i.removedNodes.forEach(r=>{M.onRemoved(r)});break}}static removePublisherListeners(t){const i=M.publisherListeners.get(t);i&&(M.publisherListeners.delete(t),i.forEach(r=>{r.publisher?.offAssign(r.onAssign)}))}static getVariablesDescriptor(t){let i=t.match(/(\$(?:\w+\\?\.?)+)/g);return i?i=i.map(r=>r.replace("$","")):i=[t],i=i.filter(r=>r.length>0),{expression:t.replace("\\",""),variables:i.map(r=>r.split(/\b\.\b/).map(e=>e.replace("\\","")))}}static getDataBindItems(t){return"attributes"in t?Array.from(t.attributes).filter(i=>i.name.indexOf("::")==0).map(i=>({propertyToUpdate:i.name.substring(2).replace(/-((html)|\w)/g,e=>e.substring(1).toUpperCase()),bindedVariablesDescriptor:M.getVariablesDescriptor(i.value)})):[]}static getSubPublisher(t,i){if(!i)return t;for(const r of i)if(r!="_self_"){if(!t)return null;t=t[r]}return t}static addPublisherListeners(t){M.removePublisherListeners(t);const i=Z.getAncestorAttributeValue(t.parentNode||t.host||t,"dataProvider");if(!i)return;const r=E.getInstance().get(i),e=M.getDataBindItems(t),o=[];e.forEach(n=>{const l=n.bindedVariablesDescriptor,c=n.propertyToUpdate;for(const h of l.variables){const u=h;let d=r;d=M.getSubPublisher(r,u);const p=t,w={publisher:d,onAssign:()=>{const v=l.variables.map(D=>M.getSubPublisher(r,D)?.get());let m=l.expression,y=!1;if(v.length==1&&l.variables[0].join(".")==m.substring(1)){let D=v[0];D===null&&(D=""),p[c]=D;return}for(let D=0;D<v.length;D++){let f=v[D];const b=l.variables[D];f===null&&(y=!0,f=void 0),m=m.replace("$"+b.join("."),f)}if(m.indexOf("|")!=-1){const D=m.indexOf("|");if(D==0)m=Os.js(m.substring(1));else{const f=m.substring(0,D),b=m.substring(D+1),x=Os[f];m=y?"":x?x(b):m}}else m=y?"":m;p[c]=m}};d?.onAssign(w.onAssign),o.push(w)}}),M.publisherListeners.set(t,o)}},M.observedElements=new Map,M.enabled=!0,M.publisherListeners=new Map,M);Fs.observe(document.documentElement),window.SonicDataBindObserver||(window.SonicDataBindObserver=Fs);/**
2
2
  * @license
3
3
  * Copyright 2017 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
@@ -742,7 +742,7 @@ const j = class j {
742
742
  return new TextDecoder().decode(h);
743
743
  }
744
744
  };
745
- j.buildDate = "Thu Jul 09 2026 13:42:07 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
745
+ j.buildDate = "Thu Jul 30 2026 13:16:38 GMT+0200 (Central European Summer Time)", j.changed = !1, j.saving = !1, j.saveId = 0, j.instance = null, j.instances = /* @__PURE__ */ new Map(), j.pageShowHandlerInitialized = !1;
746
746
  let E = j;
747
747
  if (typeof window < "u") {
748
748
  const s = window;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supersoniks/concorde",
3
- "version": "4.9.3",
3
+ "version": "4.9.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "",
@@ -1,26 +1,56 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Installe les fichiers agent IA Concorde dans un projet.
3
+ * Install Concorde AI agent files into a project.
4
4
  *
5
5
  * Usage:
6
6
  * node node_modules/@supersoniks/concorde/scripts/ai-init.mjs [options]
7
- * yarn concorde ai-init
7
+ * yarn ai-init
8
8
  *
9
9
  * Options:
10
- * --project-root <dir> Racine du projet (défaut: cwd)
11
- * --concorde-ai <dir> Dossier ai/ Concorde (défaut: auto-detect)
12
- * --overlay <dir> Couche additionnelle (ex. starter kit)
13
- * --cursor-only N'installe que Cursor (.cursor/)
14
- * --jetbrains-only N'installe que JetBrains (.aiassistant/rules/)
15
- * --merge-agents Fusionne AGENTS.md au lieu d'écraser si existant
10
+ * --project-root <dir> Project root (default: cwd)
11
+ * --concorde-ai <dir> Concorde ai/ folder (default: auto-detect)
12
+ * --overlay <dir> Extra layer (project kit) — uses AGENTS.concorde.md
13
+ * --cursor-only Install only Cursor (.cursor/)
14
+ * --jetbrains-only Install only JetBrains (.aiassistant/rules/)
15
+ * --skip-agents Never write AGENTS.md (skills/rules only)
16
+ * --merge-agents Opt-in: keep project preamble, append/refresh Concorde block
17
+ * --force-agents Opt-in: replace AGENTS.md entirely (destructive)
18
+ *
19
+ * AGENTS.md policy (non-invasive by default):
20
+ * - Missing file → create Concorde guide
21
+ * - Existing with <!-- concorde-ai --> → refresh managed zone only
22
+ * - Existing without marker → leave untouched (project-owned, e.g. billetterie)
23
+ * unless --merge-agents or --force-agents
24
+ *
25
+ * Layout when writing:
26
+ *
27
+ * [optional project preamble — short, project-only]
28
+ * <!-- concorde-ai -->
29
+ * <package ai/AGENTS.md>
30
+ * [--- + overlay AGENTS.concorde.md]
31
+ *
32
+ * Everything AFTER the marker is owned by Concorde and replaced on every run.
33
+ * Do not copy the full Concorde guide into the preamble — use overlay/AGENTS.concorde.md
34
+ * for project-specific agent notes (endpoints, dpKeys, …).
35
+ *
36
+ * Legacy: AGENTS.starter.md / AGENTS.overlay.md still read if AGENTS.concorde.md is missing.
16
37
  */
17
38
 
18
39
  import fs from "node:fs";
19
40
  import path from "node:path";
20
- import {fileURLToPath} from "node:url";
41
+ import {fileURLToPath, pathToFileURL} from "node:url";
21
42
 
22
43
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
23
44
 
45
+ const AGENTS_MARKER = "<!-- concorde-ai -->";
46
+ /** Project Concorde notes for `--overlay` (preferred). */
47
+ const OVERLAY_AGENTS_FILE = "AGENTS.concorde.md";
48
+ /** @deprecated Prefer AGENTS.concorde.md */
49
+ const OVERLAY_AGENTS_FILE_LEGACY = [
50
+ "AGENTS.overlay.md",
51
+ "AGENTS.starter.md",
52
+ ];
53
+
24
54
  const args = process.argv.slice(2);
25
55
 
26
56
  function readArg(name) {
@@ -38,10 +68,34 @@ const overlayDir = readArg("--overlay")
38
68
 
39
69
  const cursorOnly = flags.has("--cursor-only");
40
70
  const jetbrainsOnly = flags.has("--jetbrains-only");
71
+ const skipAgents = flags.has("--skip-agents");
41
72
  const mergeAgents = flags.has("--merge-agents");
73
+ const forceAgents = flags.has("--force-agents");
42
74
  const installCursor = !jetbrainsOnly;
43
75
  const installJetbrains = !cursorOnly;
44
76
 
77
+ /**
78
+ * Decide whether / how to write AGENTS.md.
79
+ * @returns {"skip" | "create" | "refresh" | "merge" | "force"}
80
+ */
81
+ export function decideAgentsAction({
82
+ existingText = "",
83
+ skipAgents: skip = false,
84
+ mergeAgents: merge = false,
85
+ forceAgents: force = false,
86
+ } = {}) {
87
+ if (skip) return "skip";
88
+ const text = existingText.replace(/\r\n/g, "\n");
89
+ const exists = text.trim().length > 0;
90
+ const hasMarker = text.includes(AGENTS_MARKER);
91
+
92
+ if (!exists) return "create";
93
+ if (hasMarker) return "refresh";
94
+ if (force) return "force";
95
+ if (merge) return "merge";
96
+ return "skip";
97
+ }
98
+
45
99
  function detectConcordeAi() {
46
100
  const explicit = readArg("--concorde-ai");
47
101
  if (explicit) return path.resolve(explicit);
@@ -57,6 +111,33 @@ function detectConcordeAi() {
57
111
  );
58
112
  }
59
113
 
114
+ /**
115
+ * Read project Concorde AGENTS notes from `--overlay` dir.
116
+ * Prefers AGENTS.concorde.md; falls back to deprecated legacy names.
117
+ * @returns {{ content: string, warnings: string[] }}
118
+ */
119
+ export function readOverlayAgents(overlayDir) {
120
+ const warnings = [];
121
+ if (!overlayDir) return {content: "", warnings};
122
+
123
+ const preferred = path.join(overlayDir, OVERLAY_AGENTS_FILE);
124
+ if (fs.existsSync(preferred)) {
125
+ return {content: fs.readFileSync(preferred, "utf8"), warnings};
126
+ }
127
+
128
+ for (const legacyName of OVERLAY_AGENTS_FILE_LEGACY) {
129
+ const legacy = path.join(overlayDir, legacyName);
130
+ if (fs.existsSync(legacy)) {
131
+ warnings.push(
132
+ `Overlay uses deprecated ${legacyName} — rename to ${OVERLAY_AGENTS_FILE}.`,
133
+ );
134
+ return {content: fs.readFileSync(legacy, "utf8"), warnings};
135
+ }
136
+ }
137
+
138
+ return {content: "", warnings};
139
+ }
140
+
60
141
  function copyDir(src, dest) {
61
142
  if (!fs.existsSync(src)) return;
62
143
  fs.mkdirSync(dest, {recursive: true});
@@ -72,96 +153,335 @@ function copyDir(src, dest) {
72
153
  }
73
154
  }
74
155
 
75
- function mergeAgentsFile(targetPath, baseContent, overlayContent) {
76
- const marker = "<!-- concorde-ai -->";
77
- let existing = "";
78
- if (fs.existsSync(targetPath)) {
79
- existing = fs.readFileSync(targetPath, "utf8");
156
+ function normalizeHeading(title) {
157
+ return title
158
+ .normalize("NFKD")
159
+ .replace(/\p{M}/gu, "")
160
+ .toLowerCase()
161
+ .replace(/[^a-z0-9]+/g, " ")
162
+ .trim();
163
+ }
164
+
165
+ function isStockConcordeH1(title) {
166
+ // "# Agents — Concorde" with optional project suffix in parentheses
167
+ return /^agents\s+concorde(\s|$)/i.test(normalizeHeading(title));
168
+ }
169
+
170
+ /**
171
+ * Split markdown into a leading H1 block + ## sections (## title → body).
172
+ * @returns {{ h1: string | null, sections: Array<{ title: string, body: string }> }}
173
+ */
174
+ function splitAgentsSections(markdown) {
175
+ const text = markdown.replace(/\r\n/g, "\n").trim();
176
+ if (!text) return {h1: null, sections: []};
177
+
178
+ const parts = text.split(/\n(?=##\s+)/);
179
+ let h1 = null;
180
+ const sections = [];
181
+
182
+ for (const part of parts) {
183
+ const trimmed = part.trim();
184
+ if (!trimmed) continue;
185
+ if (trimmed.startsWith("## ")) {
186
+ const nl = trimmed.indexOf("\n");
187
+ const titleLine = nl === -1 ? trimmed : trimmed.slice(0, nl);
188
+ const title = titleLine.replace(/^##\s+/, "").trim();
189
+ const body = nl === -1 ? "" : trimmed.slice(nl + 1).trim();
190
+ sections.push({title, body});
191
+ } else if (h1 === null) {
192
+ h1 = trimmed;
193
+ } else {
194
+ // Orphan content without ## — keep as synthetic section
195
+ sections.push({title: "", body: trimmed});
196
+ }
197
+ }
198
+
199
+ return {h1, sections};
200
+ }
201
+
202
+ function baseHeadingSet(baseContent) {
203
+ const {sections} = splitAgentsSections(baseContent);
204
+ return new Set(sections.map((s) => normalizeHeading(s.title)).filter(Boolean));
205
+ }
206
+
207
+ /** Match "## Skills / rules" with "## Skills / rules (après installation)". */
208
+ function isSameAgentsHeading(a, b) {
209
+ if (!a || !b) return false;
210
+ if (a === b) return true;
211
+ const stripParen = (s) => s.replace(/\s*\(.*\)$/, "").trim();
212
+ const aa = stripParen(a);
213
+ const bb = stripParen(b);
214
+ if (aa === bb) return true;
215
+ return aa.startsWith(bb) || bb.startsWith(aa);
216
+ }
217
+
218
+ function isPackageHeading(titleKey, baseHeads) {
219
+ for (const bh of baseHeads) {
220
+ if (isSameAgentsHeading(titleKey, bh)) return true;
221
+ }
222
+ return false;
223
+ }
224
+
225
+ /**
226
+ * True when preamble looks like a full (or near-full) copy of package AGENTS.md.
227
+ */
228
+ export function preambleDuplicatesBase(preamble, baseContent) {
229
+ const p = preamble.trim();
230
+ const b = baseContent.trim();
231
+ if (!p || !b) return false;
232
+
233
+ const fingerprints = [
234
+ "sonic-fetch",
235
+ "publishermanager",
236
+ "formdataprovider",
237
+ "dataprovide",
238
+ "concorde-get-set-dp",
239
+ ];
240
+ const pNorm = p.toLowerCase();
241
+ const hits = fingerprints.filter((fp) => pNorm.includes(fp)).length;
242
+ const longEnough = p.length >= b.length * 0.45;
243
+ const stockTitle = /^#\s*agents\s*[—–-]\s*concorde\b/im.test(p);
244
+
245
+ return stockTitle && longEnough && hits >= 3;
246
+ }
247
+
248
+ /**
249
+ * Keep only project-specific preamble bits (unique ## vs package, short custom H1).
250
+ * Drops sections that duplicate Concorde ai/AGENTS.md so re-runs heal stacked copies.
251
+ */
252
+ export function slimPreamble(preamble, baseContent) {
253
+ const raw = preamble.trim();
254
+ if (!raw) return "";
255
+
256
+ const {h1, sections} = splitAgentsSections(raw);
257
+ const h1Title = h1?.split("\n")[0]?.replace(/^#\s+/, "").trim() ?? "";
258
+ // Full forks OR any preamble titled like Concorde AGENTS → strip package ## sections
259
+ const shouldDedup =
260
+ preambleDuplicatesBase(raw, baseContent) || isStockConcordeH1(h1Title);
261
+
262
+ if (!shouldDedup) {
263
+ return raw;
264
+ }
265
+
266
+ const baseHeads = baseHeadingSet(baseContent);
267
+ const kept = [];
268
+
269
+ for (const section of sections) {
270
+ const key = normalizeHeading(section.title);
271
+ if (!key) {
272
+ if (!preambleDuplicatesBase(section.body, baseContent)) {
273
+ kept.push(section.body);
274
+ }
275
+ continue;
276
+ }
277
+ if (!isPackageHeading(key, baseHeads)) {
278
+ kept.push(`## ${section.title}\n\n${section.body}`.trim());
279
+ }
280
+ }
281
+
282
+ let intro = "";
283
+ if (h1) {
284
+ const firstLine = h1.split("\n")[0].trim();
285
+ const title = firstLine.replace(/^#\s+/, "");
286
+ if (isStockConcordeH1(title) && /[()]/.test(title)) {
287
+ intro = firstLine;
288
+ } else if (!isStockConcordeH1(title)) {
289
+ intro = firstLine;
290
+ }
80
291
  }
81
292
 
293
+ return [intro, ...kept].filter(Boolean).join("\n\n").trim();
294
+ }
295
+
296
+ export function buildManagedAgents(baseContent, overlayContent) {
82
297
  const parts = [baseContent.trim()];
83
298
  if (overlayContent?.trim()) {
84
299
  parts.push(overlayContent.trim());
85
300
  }
301
+ return parts.join("\n\n---\n\n");
302
+ }
86
303
 
87
- const combined = parts.join("\n\n---\n\n");
304
+ /**
305
+ * Build final AGENTS.md. Never stacks managed (post-marker) content.
306
+ * @returns {{ markdown: string, warnings: string[] }}
307
+ */
308
+ export function buildAgentsFile({
309
+ existing = "",
310
+ baseContent,
311
+ overlayContent = "",
312
+ mergeAgents: merge = false,
313
+ forceAgents: force = false,
314
+ }) {
315
+ const warnings = [];
316
+ const combined = buildManagedAgents(baseContent, overlayContent);
88
317
 
89
- if (!existing) {
90
- fs.mkdirSync(path.dirname(targetPath), {recursive: true});
91
- fs.writeFileSync(targetPath, combined + "\n");
92
- return;
318
+ // Destructive replace: ignore any existing project content
319
+ if (force && !existing.replace(/\r\n/g, "\n").includes(AGENTS_MARKER)) {
320
+ return {markdown: `${combined}\n`, warnings};
93
321
  }
94
322
 
95
- if (existing.includes(marker)) {
96
- const before = existing.split(marker)[0].trimEnd();
97
- fs.writeFileSync(targetPath, `${before}\n\n${marker}\n\n${combined}\n`);
98
- return;
323
+ let preamble = "";
324
+ const existingText = existing.replace(/\r\n/g, "\n");
325
+
326
+ if (existingText.includes(AGENTS_MARKER)) {
327
+ preamble = existingText.split(AGENTS_MARKER)[0].trimEnd();
328
+ } else if (merge && existingText.trim()) {
329
+ preamble = existingText.trimEnd();
99
330
  }
100
331
 
101
- if (mergeAgents) {
102
- fs.writeFileSync(
103
- targetPath,
104
- `${existing.trimEnd()}\n\n---\n\n${marker}\n\n${combined}\n`,
105
- );
106
- return;
332
+ const hadMarker = existingText.includes(AGENTS_MARKER);
333
+
334
+ if (preamble) {
335
+ const before = preamble;
336
+ preamble = slimPreamble(preamble, baseContent);
337
+ if (before.trim() && !preamble) {
338
+ warnings.push(
339
+ "AGENTS.md preamble duplicated Concorde ai/AGENTS.md — dropped. Put project-only notes in overlay AGENTS.concorde.md (or a short preamble before <!-- concorde-ai -->).",
340
+ );
341
+ } else if (before.trim() && preamble !== before.trim()) {
342
+ warnings.push(
343
+ "AGENTS.md preamble slimmed: removed sections that duplicate package AGENTS.md.",
344
+ );
345
+ }
107
346
  }
108
347
 
109
- fs.writeFileSync(targetPath, combined + "\n");
348
+ // Always emit the marker when refreshing a marked file or merging a preamble,
349
+ // so re-runs stay idempotent even if the preamble was fully dropped.
350
+ const emitMarker = hadMarker || Boolean(preamble) || merge;
351
+ const markdown = emitMarker
352
+ ? preamble
353
+ ? `${preamble.trimEnd()}\n\n${AGENTS_MARKER}\n\n${combined}\n`
354
+ : `${AGENTS_MARKER}\n\n${combined}\n`
355
+ : `${combined}\n`;
356
+
357
+ return {markdown, warnings};
110
358
  }
111
359
 
112
- const concordeAi = detectConcordeAi();
360
+ export function mergeAgentsFile(targetPath, baseContent, overlayContent, options = {}) {
361
+ const merge = options.mergeAgents ?? false;
362
+ const force = options.forceAgents ?? false;
363
+ let existing = "";
364
+ if (fs.existsSync(targetPath)) {
365
+ existing = fs.readFileSync(targetPath, "utf8");
366
+ }
367
+
368
+ const {markdown, warnings} = buildAgentsFile({
369
+ existing,
370
+ baseContent,
371
+ overlayContent,
372
+ mergeAgents: merge,
373
+ forceAgents: force,
374
+ });
113
375
 
114
- console.log(`Concorde ai-init → ${projectRoot}`);
115
- console.log(` source: ${concordeAi}`);
116
- if (overlayDir) console.log(` overlay: ${overlayDir}`);
376
+ fs.mkdirSync(path.dirname(targetPath), {recursive: true});
377
+ fs.writeFileSync(targetPath, markdown);
378
+ return warnings;
379
+ }
117
380
 
118
- if (installCursor) {
119
- copyDir(
120
- path.join(concordeAi, "cursor", "rules"),
121
- path.join(projectRoot, ".cursor", "rules"),
122
- );
123
- copyDir(
124
- path.join(concordeAi, "skills"),
125
- path.join(projectRoot, ".cursor", "skills"),
126
- );
381
+ function main() {
382
+ const concordeAi = detectConcordeAi();
383
+
384
+ console.log(`Concorde ai-init → ${projectRoot}`);
385
+ console.log(` source: ${concordeAi}`);
386
+ if (overlayDir) console.log(` overlay: ${overlayDir}`);
127
387
 
128
- if (overlayDir) {
388
+ if (installCursor) {
129
389
  copyDir(
130
- path.join(overlayDir, "cursor", "rules"),
390
+ path.join(concordeAi, "cursor", "rules"),
131
391
  path.join(projectRoot, ".cursor", "rules"),
132
392
  );
133
393
  copyDir(
134
- path.join(overlayDir, "skills"),
394
+ path.join(concordeAi, "skills"),
135
395
  path.join(projectRoot, ".cursor", "skills"),
136
396
  );
137
- }
138
- }
139
397
 
140
- if (installJetbrains) {
141
- copyDir(
142
- path.join(concordeAi, "jetbrains", "rules"),
143
- path.join(projectRoot, ".aiassistant", "rules"),
144
- );
398
+ if (overlayDir) {
399
+ copyDir(
400
+ path.join(overlayDir, "cursor", "rules"),
401
+ path.join(projectRoot, ".cursor", "rules"),
402
+ );
403
+ copyDir(
404
+ path.join(overlayDir, "skills"),
405
+ path.join(projectRoot, ".cursor", "skills"),
406
+ );
407
+ }
408
+ }
145
409
 
146
- if (overlayDir) {
410
+ if (installJetbrains) {
147
411
  copyDir(
148
- path.join(overlayDir, "jetbrains", "rules"),
412
+ path.join(concordeAi, "jetbrains", "rules"),
149
413
  path.join(projectRoot, ".aiassistant", "rules"),
150
414
  );
415
+
416
+ if (overlayDir) {
417
+ copyDir(
418
+ path.join(overlayDir, "jetbrains", "rules"),
419
+ path.join(projectRoot, ".aiassistant", "rules"),
420
+ );
421
+ }
151
422
  }
152
- }
153
423
 
154
- const baseAgents = fs.readFileSync(path.join(concordeAi, "AGENTS.md"), "utf8");
155
- let overlayAgents = "";
156
- if (overlayDir) {
157
- const overlayPath = path.join(overlayDir, "AGENTS.starter.md");
158
- if (fs.existsSync(overlayPath)) {
159
- overlayAgents = fs.readFileSync(overlayPath, "utf8");
424
+ const agentsPath = path.join(projectRoot, "AGENTS.md");
425
+ let existingAgents = "";
426
+ if (fs.existsSync(agentsPath)) {
427
+ existingAgents = fs.readFileSync(agentsPath, "utf8");
428
+ }
429
+
430
+ const action = decideAgentsAction({
431
+ existingText: existingAgents,
432
+ skipAgents,
433
+ mergeAgents,
434
+ forceAgents,
435
+ });
436
+
437
+ if (action === "skip") {
438
+ if (skipAgents) {
439
+ console.log(" ⊘ AGENTS.md skipped (--skip-agents)");
440
+ } else if (existingAgents.trim()) {
441
+ console.log(
442
+ " ⊘ AGENTS.md left untouched (project-owned, no <!-- concorde-ai --> marker).",
443
+ );
444
+ console.log(
445
+ " Use --merge-agents to append a Concorde block, or --force-agents to replace.",
446
+ );
447
+ } else {
448
+ console.log(" ⊘ AGENTS.md skipped");
449
+ }
450
+ } else {
451
+ const baseAgents = fs.readFileSync(path.join(concordeAi, "AGENTS.md"), "utf8");
452
+ const {content: overlayAgents, warnings: overlayWarnings} =
453
+ readOverlayAgents(overlayDir);
454
+
455
+ const warnings = [
456
+ ...overlayWarnings,
457
+ ...mergeAgentsFile(agentsPath, baseAgents, overlayAgents, {
458
+ mergeAgents: action === "merge" || action === "refresh",
459
+ forceAgents: action === "force",
460
+ }),
461
+ ];
462
+ for (const w of warnings) {
463
+ console.warn(` ⚠ ${w}`);
464
+ }
465
+ const label =
466
+ action === "create"
467
+ ? "created"
468
+ : action === "merge"
469
+ ? "merged"
470
+ : action === "force"
471
+ ? "replaced (--force-agents)"
472
+ : "refreshed";
473
+ console.log(` ✓ AGENTS.md (${label})`);
160
474
  }
475
+
476
+ if (installCursor) console.log(" ✓ .cursor/skills + .cursor/rules");
477
+ if (installJetbrains) console.log(" ✓ .aiassistant/rules");
478
+ console.log("Done.");
161
479
  }
162
- mergeAgentsFile(path.join(projectRoot, "AGENTS.md"), baseAgents, overlayAgents);
163
480
 
164
- console.log(" ✓ AGENTS.md");
165
- if (installCursor) console.log(" ✓ .cursor/skills + .cursor/rules");
166
- if (installJetbrains) console.log(" ✓ .aiassistant/rules");
167
- console.log("Done.");
481
+ const isDirectRun =
482
+ process.argv[1] &&
483
+ import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href;
484
+
485
+ if (isDirectRun) {
486
+ main();
487
+ }
@@ -0,0 +1,259 @@
1
+ import assert from "node:assert/strict";
2
+ import fs from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import test from "node:test";
6
+ import {
7
+ buildAgentsFile,
8
+ decideAgentsAction,
9
+ preambleDuplicatesBase,
10
+ readOverlayAgents,
11
+ slimPreamble,
12
+ } from "./ai-init.mjs";
13
+
14
+ const base = `# Agents — Concorde
15
+
16
+ Guide for Concorde.
17
+
18
+ ## Skills / rules
19
+
20
+ | File | Role |
21
+ |------|------|
22
+ | \`.cursor/skills/concorde/SKILL.md\` | Patterns |
23
+
24
+ ## Conventions impératives
25
+
26
+ - Always **DataProvider**
27
+ - No **sonic-fetch**, no **PublisherManager**
28
+ - Forms: **formDataProvider**
29
+ - Skill **concorde-get-set-dp**
30
+ `;
31
+
32
+ const overlay = `## Conventions (project)
33
+
34
+ - HTTP routes: \`endpoints.*\`
35
+ `;
36
+
37
+ test("decideAgentsAction: missing file → create", () => {
38
+ assert.equal(decideAgentsAction({existingText: ""}), "create");
39
+ });
40
+
41
+ test("decideAgentsAction: project-owned AGENTS.md → skip by default", () => {
42
+ assert.equal(
43
+ decideAgentsAction({existingText: "# Billetterie\n\nProject notes.\n"}),
44
+ "skip",
45
+ );
46
+ });
47
+
48
+ test("decideAgentsAction: --skip-agents always skips", () => {
49
+ assert.equal(
50
+ decideAgentsAction({existingText: "", skipAgents: true}),
51
+ "skip",
52
+ );
53
+ });
54
+
55
+ test("decideAgentsAction: --merge-agents on project-owned → merge", () => {
56
+ assert.equal(
57
+ decideAgentsAction({
58
+ existingText: "# Billetterie\n\nNotes.\n",
59
+ mergeAgents: true,
60
+ }),
61
+ "merge",
62
+ );
63
+ });
64
+
65
+ test("decideAgentsAction: --force-agents on project-owned → force", () => {
66
+ assert.equal(
67
+ decideAgentsAction({
68
+ existingText: "# Billetterie\n\nNotes.\n",
69
+ forceAgents: true,
70
+ }),
71
+ "force",
72
+ );
73
+ });
74
+
75
+ test("decideAgentsAction: marked file → refresh", () => {
76
+ assert.equal(
77
+ decideAgentsAction({
78
+ existingText: "# App\n\n<!-- concorde-ai -->\n\nold\n",
79
+ }),
80
+ "refresh",
81
+ );
82
+ });
83
+
84
+ test("forceAgents replaces project-owned content", () => {
85
+ const {markdown} = buildAgentsFile({
86
+ existing: "# Old project notes\n\nkeep me",
87
+ baseContent: base,
88
+ overlayContent: "",
89
+ forceAgents: true,
90
+ });
91
+ assert.equal(markdown.includes("keep me"), false);
92
+ assert.equal(markdown.includes("<!-- concorde-ai -->"), false);
93
+ assert.match(markdown, /^# Agents — Concorde/m);
94
+ });
95
+
96
+ test("without force/merge, buildAgentsFile still builds content (caller decides skip)", () => {
97
+ const {markdown} = buildAgentsFile({
98
+ existing: "",
99
+ baseContent: base,
100
+ overlayContent: "",
101
+ });
102
+ assert.match(markdown, /^# Agents — Concorde/m);
103
+ });
104
+
105
+ test("merge without marker keeps short unique preamble", () => {
106
+ const {markdown, warnings} = buildAgentsFile({
107
+ existing: "# My app\n\nOnly project notes here.\n",
108
+ baseContent: base,
109
+ overlayContent: "",
110
+ mergeAgents: true,
111
+ });
112
+ assert.match(markdown, /# My app/);
113
+ assert.match(markdown, /<!-- concorde-ai -->/);
114
+ assert.match(markdown, /# Agents — Concorde/);
115
+ assert.equal(warnings.length, 0);
116
+ });
117
+
118
+ test("re-run with marker replaces managed zone only (idempotent)", () => {
119
+ const first = buildAgentsFile({
120
+ existing: "# My app\n\nNote.\n",
121
+ baseContent: base,
122
+ overlayContent: "v1 overlay",
123
+ mergeAgents: true,
124
+ }).markdown;
125
+
126
+ const second = buildAgentsFile({
127
+ existing: first.replace("v1 overlay", "STALE"),
128
+ baseContent: base,
129
+ overlayContent: "v2 overlay",
130
+ mergeAgents: true,
131
+ }).markdown;
132
+
133
+ assert.equal(second.includes("STALE"), false);
134
+ assert.match(second, /v2 overlay/);
135
+ assert.equal(second.split("<!-- concorde-ai -->").length, 2);
136
+ });
137
+
138
+ test("duplicate Concorde preamble is dropped", () => {
139
+ const fork = `${base}\n\nExtra copy of the same guide.\n`;
140
+ assert.equal(preambleDuplicatesBase(fork, base), true);
141
+
142
+ const {markdown, warnings} = buildAgentsFile({
143
+ existing: `${fork}\n\n<!-- concorde-ai -->\n\nold managed\n`,
144
+ baseContent: base,
145
+ overlayContent: overlay,
146
+ mergeAgents: true,
147
+ });
148
+
149
+ assert.equal(markdown.split("<!-- concorde-ai -->").length, 2);
150
+ assert.equal(
151
+ markdown.indexOf("# Agents — Concorde"),
152
+ markdown.lastIndexOf("# Agents — Concorde"),
153
+ );
154
+ assert.match(markdown, /Conventions \(project\)/);
155
+ assert.ok(warnings.some((w) => /duplicated|slimmed/i.test(w)));
156
+ });
157
+
158
+ test("slimPreamble keeps unique ## sections", () => {
159
+ const preamble = `# Agents — Concorde (my-app)
160
+
161
+ Guide.
162
+
163
+ ## Skills / rules
164
+
165
+ dup
166
+
167
+ ## Project only
168
+
169
+ - use endpoints.ts
170
+ `;
171
+ const slim = slimPreamble(preamble, base);
172
+ assert.match(slim, /Project only/);
173
+ assert.equal(slim.includes("## Skills / rules"), false);
174
+ assert.match(slim, /Concorde \(my-app\)/);
175
+ });
176
+
177
+ test("slimPreamble drops Skills even when package title has suffix", () => {
178
+ const packageBase = `# Agents — Concorde
179
+
180
+ ## Skills / rules (après installation)
181
+
182
+ table
183
+
184
+ ## Conventions impératives
185
+
186
+ - sonic-fetch
187
+ - PublisherManager
188
+ - formDataProvider
189
+ - concorde-get-set-dp
190
+ `;
191
+ const preamble = `# Agents — Concorde (app)
192
+
193
+ ## Skills / rules
194
+
195
+ dup table
196
+
197
+ ## Installation / réinstallation
198
+
199
+ custom install cmd
200
+
201
+ ## Project endpoints
202
+
203
+ - endpoints.ts
204
+ `;
205
+ const slim = slimPreamble(preamble, packageBase);
206
+ assert.equal(slim.includes("## Skills / rules"), false);
207
+ assert.match(slim, /Project endpoints/);
208
+ // Installation may stay if not in package — package has no Installation ##
209
+ assert.match(slim, /Installation \/ réinstallation|Project endpoints/);
210
+ });
211
+
212
+ test("readOverlayAgents: prefers AGENTS.concorde.md", async () => {
213
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
214
+ try {
215
+ await fs.writeFile(
216
+ path.join(dir, "AGENTS.concorde.md"),
217
+ "# overlay preferred\n",
218
+ );
219
+ await fs.writeFile(
220
+ path.join(dir, "AGENTS.starter.md"),
221
+ "# overlay legacy\n",
222
+ );
223
+ const {content, warnings} = readOverlayAgents(dir);
224
+ assert.match(content, /overlay preferred/);
225
+ assert.equal(warnings.length, 0);
226
+ } finally {
227
+ await fs.rm(dir, {recursive: true, force: true});
228
+ }
229
+ });
230
+
231
+ test("readOverlayAgents: falls back to AGENTS.starter.md with warning", async () => {
232
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
233
+ try {
234
+ await fs.writeFile(
235
+ path.join(dir, "AGENTS.starter.md"),
236
+ "# overlay legacy\n",
237
+ );
238
+ const {content, warnings} = readOverlayAgents(dir);
239
+ assert.match(content, /overlay legacy/);
240
+ assert.match(warnings[0] ?? "", /deprecated AGENTS\.starter\.md/);
241
+ } finally {
242
+ await fs.rm(dir, {recursive: true, force: true});
243
+ }
244
+ });
245
+
246
+ test("readOverlayAgents: falls back to AGENTS.overlay.md with warning", async () => {
247
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), "concorde-overlay-"));
248
+ try {
249
+ await fs.writeFile(
250
+ path.join(dir, "AGENTS.overlay.md"),
251
+ "# overlay mid legacy\n",
252
+ );
253
+ const {content, warnings} = readOverlayAgents(dir);
254
+ assert.match(content, /overlay mid legacy/);
255
+ assert.match(warnings[0] ?? "", /deprecated AGENTS\.overlay\.md/);
256
+ } finally {
257
+ await fs.rm(dir, {recursive: true, force: true});
258
+ }
259
+ });
@@ -26,16 +26,36 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
26
26
 
27
27
  | Flag | Effect |
28
28
  |------|--------|
29
- | `--merge-agents` | Append to an existing `AGENTS.md` instead of replacing it |
30
- | `--overlay <dir>` | Copy extra rules/skills from another layer (e.g. starter kit) |
29
+ | `--skip-agents` | Never write `AGENTS.md` (skills / rules only) |
30
+ | `--merge-agents` | Opt-in: keep the project preamble and append / refresh the Concorde block |
31
+ | `--force-agents` | Opt-in: **replace** the whole `AGENTS.md` (destructive) |
32
+ | `--overlay <dir>` | Extra rules/skills + optional `AGENTS.concorde.md` for project-only Concorde agent notes |
31
33
  | `--cursor-only` | Install only `.cursor/skills` and `.cursor/rules` |
32
34
  | `--jetbrains-only` | Install only `.aiassistant/rules/` |
33
35
 
36
+ ## `AGENTS.md` policy (non-invasive)
37
+
38
+ | Situation | Default |
39
+ |-----------|---------|
40
+ | No `AGENTS.md` | Create the Concorde guide |
41
+ | File with `<!-- concorde-ai -->` | Refresh the managed zone only |
42
+ | File **without** marker (project notes) | **Left untouched** — skills / rules are enough |
43
+ | `--merge-agents` / `--force-agents` / `--skip-agents` | See flags above |
44
+
45
+ ```text
46
+ [optional project preamble — short, project-only]
47
+ <!-- concorde-ai -->
48
+ <package ai/AGENTS.md>
49
+ [--- + overlay AGENTS.concorde.md]
50
+ ```
51
+
52
+ Everything **after** `<!-- concorde-ai -->` is replaced on each `ai-init` run (idempotent). Do not paste a full copy of the Concorde guide above the marker — put project-specific notes in `AGENTS.concorde.md` (overlay). If the preamble duplicates package `AGENTS.md`, `ai-init` slims or drops it and prints a warning. Legacy filenames `AGENTS.overlay.md` / `AGENTS.starter.md` are still accepted with a deprecation warning.
53
+
34
54
  ## What gets installed
35
55
 
36
56
  | Path | Role |
37
57
  |------|------|
38
- | `AGENTS.md` | Project-level guide for agents (Concorde conventions) |
58
+ | `AGENTS.md` | Created only if missing; existing project-owned files are left alone unless `--merge-agents` / `--force-agents` |
39
59
  | `.cursor/skills/concorde/` | Core Lit + DataProvider patterns |
40
60
  | `.cursor/skills/concorde-imports/` | Short `@supersoniks/concorde/…` import paths |
41
61
  | `.cursor/skills/concorde-scope/` | `serviceURL`, `formDataProvider`, API configuration |
@@ -49,7 +69,7 @@ node node_modules/@supersoniks/concorde/scripts/ai-init.mjs
49
69
 
50
70
  1. **Starter project:** [Installation](#docs/_getting-started/concorde-outside.md/concorde-outside) — `yarn ai:sync` is wired in the kit.
51
71
  2. **Existing / manual Vite project:** [Manual installation](#docs/_getting-started/concorde-manual-install.md/concorde-manual-install), then **`ai-init`** after `yarn add @supersoniks/concorde`.
52
- 3. Commit `AGENTS.md`, `.cursor/`, and `.aiassistant/` if your team shares agent settings.
72
+ 3. Commit `.cursor/` and `.aiassistant/` (and `AGENTS.md` only if you opted in / it was created) if your team shares agent settings.
53
73
  4. Re-run the same command when you bump `@supersoniks/concorde` to refresh skills from `node_modules/@supersoniks/concorde/ai/`.
54
74
  5. In Cursor, skills under `.cursor/skills/` are picked up automatically; mention a skill in chat for focused tasks (e.g. migration → `concorde-get-set-dp`).
55
75