mnfst 0.5.93 → 0.5.94

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.
@@ -344,7 +344,7 @@
344
344
 
345
345
  /* Indent code when line numbers present */
346
346
  &:has(.lines) code {
347
- padding-inline-start: calc(calc(var(--spacing, 0.25rem) * 6) + 2ch)
347
+ padding-inline-start: calc(calc(var(--spacing, 0.25rem) * 8) + 2ch)
348
348
  }
349
349
 
350
350
  /* Code */
@@ -88,6 +88,17 @@ function injectScript(src) {
88
88
  });
89
89
  }
90
90
 
91
+ // Sentinel used by both loaders to detect whether `window.hljs` is already
92
+ // the FULL bundle (which registers ~190 languages) vs the lean core (which
93
+ // starts with very few). Threshold of 50 separates the two reliably —
94
+ // neither the lean core nor any realistic per-language top-up will reach
95
+ // 50 languages before the full bundle does, and the full bundle always
96
+ // ships well above that.
97
+ function hljsIsFullBundle() {
98
+ return typeof window.hljs?.listLanguages === 'function'
99
+ && window.hljs.listLanguages().length > 50;
100
+ }
101
+
91
102
  async function loadHighlightFull() {
92
103
  if (hljsFullPromise) return hljsFullPromise;
93
104
  hljsFullPromise = injectScript(HLJS_FULL_URL).then(() => {
@@ -98,6 +109,15 @@ async function loadHighlightFull() {
98
109
  }
99
110
 
100
111
  async function loadHighlightCore() {
112
+ // Don't downgrade. If the full bundle is already loaded on window.hljs
113
+ // (because the hero editor — or any other caller — asked for full mode
114
+ // first), returning the lean core would mean OVERWRITING window.hljs
115
+ // with a 4-language instance, deleting the full bundle's grammars.
116
+ // Per-block callers downstream would then re-request languages,
117
+ // re-fire reactive bumps, and feed an Alpine re-eval loop. Just hand
118
+ // back the full instance — registerLanguage's "already includes"
119
+ // check below makes the rest of the lean path a no-op.
120
+ if (hljsIsFullBundle()) return window.hljs;
101
121
  if (hljsCorePromise) return hljsCorePromise;
102
122
  hljsCorePromise = import(HLJS_CORE_URL).then(mod => {
103
123
  // esm.run's CJS→ESM shim exposes hljs as the default export. Mirror
@@ -105,6 +125,10 @@ async function loadHighlightCore() {
105
125
  // editor, etc.) that read `hljs` as a global keep working.
106
126
  const hl = mod.default;
107
127
  if (!hl) throw new Error('hljs undefined after core ESM import');
128
+ // Second guard: even after we awaited the dynamic import, the full
129
+ // bundle may have arrived in the meantime (its <script> tag races
130
+ // our ESM fetch). Don't clobber it with the lean core.
131
+ if (hljsIsFullBundle()) return window.hljs;
108
132
  window.hljs = hl;
109
133
  return hl;
110
134
  });
@@ -1 +1 @@
1
- @import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap");:root{--icon-code-copy:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/g%3E%3C/svg%3E");--icon-code-copied:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1jb3B5LWNoZWNrLWljb24gbHVjaWRlLWNvcHktY2hlY2siIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0ibTEyIDE1IDIgMiA0LTQiLz48cmVjdCB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHg9IjgiIHk9IjgiIHJ4PSIyIiByeT0iMiIvPjxwYXRoIGQ9Ik00IDE2Yy0xLjEgMC0yLS45LTItMlY0YzAtMS4xLjktMiAyLTJoMTBjMS4xIDAgMiAuOSAyIDIiLz48L3N2Zz4=");--icon-code-expand:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--color-code-keyword:#b8860b;--color-code-string:#8b4513;--color-code-comment:gray;--color-code-function:peru;--color-code-number:sienna;--color-code-operator:#2f4f4f;--color-code-class-name:#daa520;--color-code-tag:#4682b4;--color-code-attr-name:#ff8c00;--color-code-attr-value:#8b4513;--color-code-property:sienna;--color-code-selector:#4682b4;--color-code-punctuation:#2f4f4f;--color-code-builtin:#b8860b;--color-code-constant:sienna;--color-code-boolean:sienna;--color-code-regex:#8b4513;--color-code-symbol:#daa520;--color-code-entity:#daa520;--color-code-url:sienna;--color-code-atrule:#b8860b;--color-code-rule:#4682b4;--color-code-doctype:gray;--color-code-cdata:gray;--color-code-prolog:gray;--color-code-namespace:gray;--color-code-important:#b8860b;--color-code-inserted:#228b22;--color-code-deleted:#dc143c;--color-code-char:#8b4513}.dark{--color-code-keyword:#f4a460;--color-code-string:#deb887;--color-code-comment:#8b8b8b;--color-code-function:#daa520;--color-code-number:tan;--color-code-operator:wheat;--color-code-class-name:peru;--color-code-tag:#87ceeb;--color-code-attr-name:gold;--color-code-attr-value:#deb887;--color-code-property:tan;--color-code-selector:#87ceeb;--color-code-punctuation:wheat;--color-code-builtin:#f4a460;--color-code-constant:tan;--color-code-boolean:tan;--color-code-regex:#deb887;--color-code-symbol:peru;--color-code-entity:peru;--color-code-url:tan;--color-code-atrule:#f4a460;--color-code-rule:#98fb98;--color-code-doctype:#8b8b8b;--color-code-cdata:#8b8b8b;--color-code-prolog:#8b8b8b;--color-code-namespace:#8b8b8b;--color-code-important:#f4a460;--color-code-inserted:#98fb98;--color-code-deleted:#f08080;--color-code-char:#deb887}@layer utilities{.hljs-comment{color:var(--color-code-comment)!important}.hljs-keyword{color:var(--color-code-keyword)!important}.hljs-string{color:var(--color-code-string)!important}.hljs-number{color:var(--color-code-number)!important}.hljs-literal{color:var(--color-code-constant)!important}.hljs-type{color:var(--color-code-class-name)!important}.hljs-variable{color:var(--color-code-property)!important}.hljs-variable.language_{color:var(--color-code-keyword)!important}.hljs-variable.constant_{color:var(--color-code-constant)!important}.hljs-title{color:var(--color-code-function)!important}.hljs-title.class_.inherited__{color:var(--color-code-class-name)!important}.hljs-title.function_.invoke__{color:var(--color-code-function)!important}.hljs-params{color:var(--color-code-property)!important}.hljs-doctag{color:var(--color-code-keyword)!important;font-weight:600!important}.hljs-meta{color:var(--color-code-comment)!important}.hljs-meta.keyword_,.hljs-meta.prompt_{color:var(--color-code-keyword)!important}.hljs-meta.string_{color:var(--color-code-string)!important}.hljs-section{color:var(--color-code-keyword)!important;font-weight:600!important}.hljs-name{color:var(--color-code-tag)!important}.hljs-attribute{color:var(--color-code-attr-name)!important}.hljs-bullet{color:var(--color-code-punctuation)!important}.hljs-code{color:var(--color-code-property)!important}.hljs-formula{color:var(--color-code-number)!important}.hljs-quote{color:var(--color-code-string)!important}.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo{color:var(--color-code-selector)!important}.hljs-template-tag{color:var(--color-code-tag)!important}.hljs-template-variable{color:var(--color-code-property)!important}.hljs-subst{color:var(--color-code-string)!important}}@layer components{:where(code[role=button]){height:fit-content}:where(.code-copied-icon){background-color:currentColor;display:inline-block;height:1em;mask-image:var(--icon-code-copied);mask-position:center;mask-repeat:no-repeat;mask-size:contain;width:1em}:where([x-code],[x-code-group]):not(.unstyle){position:relative;:where(header):not(:where(:is(aside.frame) header)){align-items:center;background-color:color-mix(in oklch,var(--color-content-stark,#2f4f4f) 8%,transparent);color:var(--color-content-neutral,gray);display:flex;flex-direction:row;font-family:var(--font-sans,sans-serif);font-size:inherit;min-height:var(--spacing-field-height,2.25rem);padding-inline-end:var(--spacing-field-height);padding-inline-start:calc(var(--spacing, .25rem)*4);width:100%;&:has(button[role=tab]){padding-inline-start:calc(var(--spacing, .25rem)*2)}& [role=tablist]{display:flex;flex-direction:row;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;&::-webkit-scrollbar{display:none}& button[role=tab]{background:transparent;border:0;color:inherit;flex-shrink:0;font-family:inherit;font-size:inherit;height:fit-content;justify-content:start;&:hover{background-color:var(--color-field-surface,color-mix(#2f4f4f 10%,transparent));color:var(--color-content-stark,#2f4f4f)}&[aria-selected=true]{color:var(--color-brand-content,#daa520);pointer-events:none;position:relative}}}}& button.copy{background-color:transparent;font-size:75%;inset-inline-end:0;position:absolute;top:0;&:hover{background-color:transparent;&:after{background-color:var(--color-field-inverse,#2f4f4f)}}&:after{background-color:var(--color-content-neutral,gray);content:"";display:block;height:.8125rem;mask-image:var(--icon-code-copy);mask-repeat:no-repeat;mask-size:contain;width:.8125rem}&.copied:after{mask-image:var(--icon-code-copied)}}:where(header)::-webkit-scrollbar{display:none}& .lines{background-color:var(--color-page,#fff);color:var(--color-content-subtle,#a9a9a9);display:inline-flex;flex-direction:column;font-family:inherit;font-size:inherit;inset-inline-start:0;line-height:inherit;padding:calc(var(--spacing, .25rem)*4);pointer-events:none;position:absolute;text-align:end;user-select:none}&:has(.lines) code{padding-inline-start:calc(var(--spacing, .25rem)*6 + 2ch)}:where(code):not(:where(:is(aside.frame) code)){flex:1 1 100%;min-width:0;white-space:pre;white-space-collapse:preserve}& button.expand{align-items:center;background:transparent;border:0;border-radius:0;color:var(--color-content-subtle,#a9a9a9);cursor:pointer;display:flex;font-family:var(--font-sans,sans-serif);font-size:inherit;height:var(--spacing-field-height,2.25rem);justify-content:center;order:99;padding:0 calc(var(--spacing, .25rem)*2);transition:var(--transition,all .05s ease-in-out);width:100%;&:hover{background:color-mix(in oklch,var(--color-content-stark,#2f4f4f) 8%,transparent);color:var(--color-content-neutral,gray)}}&[data-collapsed] .lines,&[data-collapsed] code{mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 3em),transparent calc(100% - .75em),transparent);max-height:calc(var(--collapse-lines, 20)*1.7em + var(--spacing, .25rem)*8);overflow:hidden}:where(aside.frame){background:unset;border:0;box-shadow:unset;color:unset;font-family:unset;font-size:unset;font-weight:unset;line-height:unset;white-space:normal;white-space-collapse:collapse}}:where([x-code-group]){flex-flow:column;:where([x-code]){background:transparent;border:0;border-radius:0}}:where([x-code]):has(>header){& .lines{top:var(--spacing-field-height,2.25rem)}}}
1
+ @import url("https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap");:root{--icon-code-copy:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2'%3E%3Crect width='14' height='14' x='8' y='8' rx='2' ry='2'/%3E%3Cpath d='M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2'/%3E%3C/g%3E%3C/svg%3E");--icon-code-copied:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJjdXJyZW50Q29sb3IiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBjbGFzcz0ibHVjaWRlIGx1Y2lkZS1jb3B5LWNoZWNrLWljb24gbHVjaWRlLWNvcHktY2hlY2siIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0ibTEyIDE1IDIgMiA0LTQiLz48cmVjdCB3aWR0aD0iMTQiIGhlaWdodD0iMTQiIHg9IjgiIHk9IjgiIHJ4PSIyIiByeT0iMiIvPjxwYXRoIGQ9Ik00IDE2Yy0xLjEgMC0yLS45LTItMlY0YzAtMS4xLjktMiAyLTJoMTBjMS4xIDAgMiAuOSAyIDIiLz48L3N2Zz4=");--icon-code-expand:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--color-code-keyword:#b8860b;--color-code-string:#8b4513;--color-code-comment:gray;--color-code-function:peru;--color-code-number:sienna;--color-code-operator:#2f4f4f;--color-code-class-name:#daa520;--color-code-tag:#4682b4;--color-code-attr-name:#ff8c00;--color-code-attr-value:#8b4513;--color-code-property:sienna;--color-code-selector:#4682b4;--color-code-punctuation:#2f4f4f;--color-code-builtin:#b8860b;--color-code-constant:sienna;--color-code-boolean:sienna;--color-code-regex:#8b4513;--color-code-symbol:#daa520;--color-code-entity:#daa520;--color-code-url:sienna;--color-code-atrule:#b8860b;--color-code-rule:#4682b4;--color-code-doctype:gray;--color-code-cdata:gray;--color-code-prolog:gray;--color-code-namespace:gray;--color-code-important:#b8860b;--color-code-inserted:#228b22;--color-code-deleted:#dc143c;--color-code-char:#8b4513}.dark{--color-code-keyword:#f4a460;--color-code-string:#deb887;--color-code-comment:#8b8b8b;--color-code-function:#daa520;--color-code-number:tan;--color-code-operator:wheat;--color-code-class-name:peru;--color-code-tag:#87ceeb;--color-code-attr-name:gold;--color-code-attr-value:#deb887;--color-code-property:tan;--color-code-selector:#87ceeb;--color-code-punctuation:wheat;--color-code-builtin:#f4a460;--color-code-constant:tan;--color-code-boolean:tan;--color-code-regex:#deb887;--color-code-symbol:peru;--color-code-entity:peru;--color-code-url:tan;--color-code-atrule:#f4a460;--color-code-rule:#98fb98;--color-code-doctype:#8b8b8b;--color-code-cdata:#8b8b8b;--color-code-prolog:#8b8b8b;--color-code-namespace:#8b8b8b;--color-code-important:#f4a460;--color-code-inserted:#98fb98;--color-code-deleted:#f08080;--color-code-char:#deb887}@layer utilities{.hljs-comment{color:var(--color-code-comment)!important}.hljs-keyword{color:var(--color-code-keyword)!important}.hljs-string{color:var(--color-code-string)!important}.hljs-number{color:var(--color-code-number)!important}.hljs-literal{color:var(--color-code-constant)!important}.hljs-type{color:var(--color-code-class-name)!important}.hljs-variable{color:var(--color-code-property)!important}.hljs-variable.language_{color:var(--color-code-keyword)!important}.hljs-variable.constant_{color:var(--color-code-constant)!important}.hljs-title{color:var(--color-code-function)!important}.hljs-title.class_.inherited__{color:var(--color-code-class-name)!important}.hljs-title.function_.invoke__{color:var(--color-code-function)!important}.hljs-params{color:var(--color-code-property)!important}.hljs-doctag{color:var(--color-code-keyword)!important;font-weight:600!important}.hljs-meta{color:var(--color-code-comment)!important}.hljs-meta.keyword_,.hljs-meta.prompt_{color:var(--color-code-keyword)!important}.hljs-meta.string_{color:var(--color-code-string)!important}.hljs-section{color:var(--color-code-keyword)!important;font-weight:600!important}.hljs-name{color:var(--color-code-tag)!important}.hljs-attribute{color:var(--color-code-attr-name)!important}.hljs-bullet{color:var(--color-code-punctuation)!important}.hljs-code{color:var(--color-code-property)!important}.hljs-formula{color:var(--color-code-number)!important}.hljs-quote{color:var(--color-code-string)!important}.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo{color:var(--color-code-selector)!important}.hljs-template-tag{color:var(--color-code-tag)!important}.hljs-template-variable{color:var(--color-code-property)!important}.hljs-subst{color:var(--color-code-string)!important}}@layer components{:where(code[role=button]){height:fit-content}:where(.code-copied-icon){background-color:currentColor;display:inline-block;height:1em;mask-image:var(--icon-code-copied);mask-position:center;mask-repeat:no-repeat;mask-size:contain;width:1em}:where([x-code],[x-code-group]):not(.unstyle){position:relative;:where(header):not(:where(:is(aside.frame) header)){align-items:center;background-color:color-mix(in oklch,var(--color-content-stark,#2f4f4f) 8%,transparent);color:var(--color-content-neutral,gray);display:flex;flex-direction:row;font-family:var(--font-sans,sans-serif);font-size:inherit;min-height:var(--spacing-field-height,2.25rem);padding-inline-end:var(--spacing-field-height);padding-inline-start:calc(var(--spacing, .25rem)*4);width:100%;&:has(button[role=tab]){padding-inline-start:calc(var(--spacing, .25rem)*2)}& [role=tablist]{display:flex;flex-direction:row;overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;&::-webkit-scrollbar{display:none}& button[role=tab]{background:transparent;border:0;color:inherit;flex-shrink:0;font-family:inherit;font-size:inherit;height:fit-content;justify-content:start;&:hover{background-color:var(--color-field-surface,color-mix(#2f4f4f 10%,transparent));color:var(--color-content-stark,#2f4f4f)}&[aria-selected=true]{color:var(--color-brand-content,#daa520);pointer-events:none;position:relative}}}}& button.copy{background-color:transparent;font-size:75%;inset-inline-end:0;position:absolute;top:0;&:hover{background-color:transparent;&:after{background-color:var(--color-field-inverse,#2f4f4f)}}&:after{background-color:var(--color-content-neutral,gray);content:"";display:block;height:.8125rem;mask-image:var(--icon-code-copy);mask-repeat:no-repeat;mask-size:contain;width:.8125rem}&.copied:after{mask-image:var(--icon-code-copied)}}:where(header)::-webkit-scrollbar{display:none}& .lines{background-color:var(--color-page,#fff);color:var(--color-content-subtle,#a9a9a9);display:inline-flex;flex-direction:column;font-family:inherit;font-size:inherit;inset-inline-start:0;line-height:inherit;padding:calc(var(--spacing, .25rem)*4);pointer-events:none;position:absolute;text-align:end;user-select:none}&:has(.lines) code{padding-inline-start:calc(var(--spacing, .25rem)*8 + 2ch)}:where(code):not(:where(:is(aside.frame) code)){flex:1 1 100%;min-width:0;white-space:pre;white-space-collapse:preserve}& button.expand{align-items:center;background:transparent;border:0;border-radius:0;color:var(--color-content-subtle,#a9a9a9);cursor:pointer;display:flex;font-family:var(--font-sans,sans-serif);font-size:inherit;height:var(--spacing-field-height,2.25rem);justify-content:center;order:99;padding:0 calc(var(--spacing, .25rem)*2);transition:var(--transition,all .05s ease-in-out);width:100%;&:hover{background:color-mix(in oklch,var(--color-content-stark,#2f4f4f) 8%,transparent);color:var(--color-content-neutral,gray)}}&[data-collapsed] .lines,&[data-collapsed] code{mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 3em),transparent calc(100% - .75em),transparent);max-height:calc(var(--collapse-lines, 20)*1.7em + var(--spacing, .25rem)*8);overflow:hidden}:where(aside.frame){background:unset;border:0;box-shadow:unset;color:unset;font-family:unset;font-size:unset;font-weight:unset;line-height:unset;white-space:normal;white-space-collapse:collapse}}:where([x-code-group]){flex-flow:column;:where([x-code]){background:transparent;border:0;border-radius:0}}:where([x-code]):has(>header){& .lines{top:var(--spacing-field-height,2.25rem)}}}
@@ -2,7 +2,7 @@
2
2
  "manifest.appwrite.auth.js": "sha384-to37ssZJXGeOS6+rf2VI47ox2mEqgsi5oQ1E5vv8XU/lDspbDFE1KHEMm8TxBhxW",
3
3
  "manifest.appwrite.data.js": "sha384-00ulLT+GAIuPHA/rRT9p98vYlsyDzkyKXtg86BDQ6FGQa5vVVN+W6kuforniBAsz",
4
4
  "manifest.appwrite.presence.js": "sha384-uxRpx9/Jj0kGtklH5QmUlAzD3zdSvFRfK6bcJQqxl+Bsf5tOo4zgwqJTQgtZoHQP",
5
- "manifest.code.js": "sha384-r0cbKtg4/bih6lzNiIdnwiCurW2ohbC8E8zNljSSoO5r+5ewPQcWP4QT+jZp3Oec",
5
+ "manifest.code.js": "sha384-jYW7i5F+K+mL5d/HKpw/Xoo0vOz/pmlvotGd7MUPOu+CB+O28OohqgPAEI4y6bSS",
6
6
  "manifest.color.js": "sha384-Z9G/lzt0vVMxjz4wkPuGG1X9mmQAJR15aOoGX3ephf7r2wnlUWet5GLgkUMtT4vt",
7
7
  "manifest.colorpicker.js": "sha384-0EVn+Ha06h7FIvOxc6WjZYnKYXzi+zba08yKvczSEGTRkWRxyKN2TFrZHI1SDCXu",
8
8
  "manifest.components.js": "sha384-3dCTD5EwCZTiX+1obYtDNM3WWwPh2JDQUQQsdRUUK3gs6FXjse1ShkKaT/2jsNaI",
@@ -10,7 +10,7 @@
10
10
  "manifest.dropdowns.js": "sha384-WMrFoSpKfJuo81dyrwhVrDO8rq+rDwh2x8x4nH01BY5ZHkvjE+/SaT2gWCI0zOn+",
11
11
  "manifest.export.js": "sha384-qvdGz1TiGEDOeWJ5os1z03RURdKX+ezZEQ1KyV+9iC7X0esLK83mtY87t4MQv45t",
12
12
  "manifest.icons.js": "sha384-uOkboYrovjCpl22eey3Jaxpey+pOnot5NDnRRumcRxiR7IOVaRh1i20gYnWXR5dW",
13
- "manifest.localization.js": "sha384-eR418BsWisFmFnmhNnNEqx5SMUJywngz6MjWJW7EQWAu1PilepjO/Rp99Z2MTbH5",
13
+ "manifest.localization.js": "sha384-Uw2x2kBJyr5u6BnPieR68Iz0kCdMK/lvIJQajxZGwqBSfa3204W9Sz7X8DYerC9b",
14
14
  "manifest.markdown.js": "sha384-3LgPiHrftPqAIJGhxi87C0TtfJXbsH0Qj4JmfmYgV4y5UjSx7nVSP+ppsRUWT0Xs",
15
15
  "manifest.resize.js": "sha384-Ak5gf44ERfh9pOSAD1qZzJSysslpwBCkevIlz7R3dszTUyzUKGKGF4pn5arOtgG0",
16
16
  "manifest.router.js": "sha384-n6xmIfWnYzd/0kkVTFuHhFzHuxiDgZ1Lg1W0yB6/w3Myw5pQ6PgE6SJBHfVsO7/D",
@@ -24,6 +24,13 @@ window.__manifestSetLocale = setLocale;
24
24
 
25
25
  function initializeLocalizationPlugin() {
26
26
 
27
+ // Snapshot the original <html lang> attribute before any locale mutation.
28
+ // This is the developer's declared default — the value baked into
29
+ // index.html's <html lang="…"> tag. Used by $locale.reset() to restore
30
+ // the project to its declared default language regardless of current
31
+ // runtime state (which gets mutated by set/toggle/URL detection).
32
+ const originalHtmlLang = document.documentElement.lang || '';
33
+
27
34
  // Environment detection for debug logging
28
35
  const isDevelopment = window.location.hostname === 'localhost' ||
29
36
  window.location.hostname === '127.0.0.1' ||
@@ -190,6 +197,14 @@ function initializeLocalizationPlugin() {
190
197
  } catch (error) {
191
198
  return false;
192
199
  }
200
+ },
201
+ remove: (key) => {
202
+ try {
203
+ localStorage.removeItem(key);
204
+ return true;
205
+ } catch (error) {
206
+ return false;
207
+ }
193
208
  }
194
209
  };
195
210
 
@@ -633,47 +648,96 @@ function registerLocaleMagic() {
633
648
  }
634
649
  };
635
650
  }
636
- // $locale.reset([href]) — strip any leading locale segment from
637
- // the URL (or from a passed-in href) and navigate there. Pairs
638
- // with the router's sticky-locale rewriter: that adds the
639
- // current locale to outgoing same-origin links automatically,
640
- // and this method is the opt-out for a developer who wants to
641
- // surface a "go to default locale" action without hard-coding
642
- // the default's language code.
651
+ // $locale.reset([href]) — restore the project's default
652
+ // locale. Reset clears the user's stored language preference,
653
+ // recomputes the default from the developer's declarations,
654
+ // and applies it to the live store + <html lang>/<html dir>.
655
+ //
656
+ // Default resolution (matches initial detection minus the
657
+ // URL and localStorage layers, since reset explicitly opts
658
+ // out of both):
659
+ // 1. Original <html lang> baked into index.html
660
+ // (snapshotted at plugin init, before any mutation)
661
+ // 2. Browser language (navigator.language) if it matches
662
+ // an available locale
663
+ // 3. First locale registered in manifest.json
643
664
  //
644
- // Behaviour:
645
- // $locale.reset() → reset current URL to no prefix
646
- // $locale.reset('/foo') → strip prefix from /foo (no-op
647
- // if there isn't one) and navigate
648
- // $locale.reset('/fr/foo') → 'fr' is stripped → /foo
665
+ // As a side effect, any leading locale slug in the URL is
666
+ // stripped (since the URL prefix would otherwise re-detect
667
+ // back into a non-default locale on the next page load).
649
668
  //
650
- // Routing path: if Manifest's SPA navigation is active
651
- // (`history.pushState` + `manifest:route-change` event), this
652
- // is a SPA hop with no full reload. In prerendered MPA mode
653
- // we use `window.location.assign` so the new URL's
654
- // prerendered HTML loads from disk.
669
+ // Forms:
670
+ // $locale.reset() → reset current URL
671
+ // $locale.reset('/fr/foo') strip prefix from given href,
672
+ // then navigate (useful for
673
+ // "View in default language"
674
+ // links anywhere on the page)
675
+ //
676
+ // Routing path: SPA hop via history.pushState when running
677
+ // in the live SPA; full navigation via location.assign in
678
+ // prerendered MPA mode so the new URL's prerendered HTML
679
+ // loads from disk.
655
680
  if (prop === 'reset') {
656
681
  return (href) => {
657
682
  const store = Alpine.store('locale');
658
- const available = store?.available || [document.documentElement.lang || 'en'];
683
+ const available = store?.available || [originalHtmlLang || 'en'];
684
+
685
+ // Clear stored UI-toggle preference so future
686
+ // page loads re-detect from scratch.
687
+ safeStorage.remove('lang');
688
+
689
+ // Resolve the default locale from declarations.
690
+ let defaultLocale = null;
691
+ if (originalHtmlLang
692
+ && isValidLanguageCode(originalHtmlLang)
693
+ && available.includes(originalHtmlLang)) {
694
+ defaultLocale = originalHtmlLang;
695
+ } else if (navigator.language) {
696
+ const browserLang = navigator.language.split('-')[0];
697
+ if (isValidLanguageCode(browserLang)
698
+ && available.includes(browserLang)) {
699
+ defaultLocale = browserLang;
700
+ }
701
+ }
702
+ if (!defaultLocale) {
703
+ defaultLocale = available[0] || 'en';
704
+ }
659
705
 
660
- // Resolve target URL: passed-in href, or current URL
706
+ // Resolve target URL (passed-in href or current)
707
+ // and strip its leading locale segment, if any.
661
708
  let target;
662
709
  try {
663
710
  target = new URL(href || window.location.href, window.location.href);
664
711
  } catch {
665
712
  return false;
666
713
  }
667
-
668
- // Strip leading locale segment if present
669
714
  const segs = target.pathname.split('/').filter(Boolean);
670
715
  if (segs.length && available.includes(segs[0])) {
671
716
  segs.shift();
672
717
  }
673
718
  target.pathname = '/' + segs.join('/');
674
719
 
675
- // Same-origin navigation only external URLs are
676
- // passed through unchanged via window.location.assign.
720
+ // Apply the default locale to the live store + DOM
721
+ // before navigating, so $locale.current and any
722
+ // reactive readers update immediately. Skip the
723
+ // setLocale wrapper because it would attempt URL
724
+ // updates of its own — we're handling navigation
725
+ // explicitly below.
726
+ if (store && store.current !== defaultLocale) {
727
+ store.current = defaultLocale;
728
+ store.direction = isRTL(defaultLocale) ? 'rtl' : 'ltr';
729
+ try {
730
+ document.documentElement.lang = defaultLocale;
731
+ document.documentElement.dir = store.direction;
732
+ } catch { /* DOM unavailable */ }
733
+ try {
734
+ window.dispatchEvent(new CustomEvent('localechange', {
735
+ detail: { locale: defaultLocale }
736
+ }));
737
+ } catch { /* event dispatch unavailable */ }
738
+ }
739
+
740
+ // Navigate to the locale-stripped URL.
677
741
  const isSameOrigin = target.origin === window.location.origin;
678
742
  const isPrerendered = !!document.querySelector('meta[name="manifest:prerendered"]:not([content="0"]):not([content="false"])');
679
743
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.93",
3
+ "version": "0.5.94",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",