furifont 0.4.2 → 0.5.1

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.
Files changed (40) hide show
  1. package/dist/cli.mjs +6 -6
  2. package/dist/client/200.html +1 -1
  3. package/dist/client/404.html +1 -1
  4. package/dist/client/_nuxt/{C4V-788C.js → BWahbb7T.js} +5 -3
  5. package/dist/client/_nuxt/BWgkvUGw.js +2 -0
  6. package/dist/client/_nuxt/BqpS6BQk.js +3 -0
  7. package/dist/client/_nuxt/{Dg3RF8xB.js → CGjbjQXe.js} +1 -1
  8. package/dist/client/_nuxt/CWinwLD-.js +1 -0
  9. package/dist/client/_nuxt/Ca_1jsnD.js +1 -0
  10. package/dist/client/_nuxt/D7M8CFSK.js +5 -0
  11. package/dist/client/_nuxt/DrYLd3bw.js +3 -0
  12. package/dist/client/_nuxt/P9bf8JzX.js +1 -0
  13. package/dist/client/_nuxt/builds/latest.json +1 -1
  14. package/dist/client/_nuxt/builds/meta/6a38fc31-347d-4f29-8fb9-80c06be37854.json +1 -0
  15. package/dist/client/_nuxt/entry.CBgHh7ZX.css +1 -0
  16. package/dist/client/_nuxt/mXMd-rpi.js +3 -0
  17. package/dist/client/_nuxt/{slpK2-vu.js → wm3IDb_Q.js} +1 -1
  18. package/dist/client/customize/index.html +1 -1
  19. package/dist/client/furifont.user.js +3 -3
  20. package/dist/client/index.html +1 -1
  21. package/dist/client/okurigana.json +6 -6
  22. package/dist/client/reference/index.html +1 -1
  23. package/dist/client/report/index.html +1 -1
  24. package/dist/client/version.json +1 -1
  25. package/dist/{config-BHN-5b6L.mjs → config-CbOFGotB.mjs} +28 -8
  26. package/dist/devframe.mjs +2 -2
  27. package/dist/index.d.mts +19 -3
  28. package/dist/index.mjs +2 -2
  29. package/dist/{studio-bPS1eciv.mjs → studio-DtSmLTSj.mjs} +41 -1
  30. package/package.json +4 -5
  31. package/dist/client/_nuxt/B2JUvp84.js +0 -1
  32. package/dist/client/_nuxt/BgIj0bEj.js +0 -1
  33. package/dist/client/_nuxt/BpoWIN5A.js +0 -3
  34. package/dist/client/_nuxt/CAnB8eMp.js +0 -1
  35. package/dist/client/_nuxt/CG1cMRvM.js +0 -2
  36. package/dist/client/_nuxt/CHjPDtV4.js +0 -4
  37. package/dist/client/_nuxt/Kki0DvjP.js +0 -1
  38. package/dist/client/_nuxt/builds/meta/95075385-c519-4224-af4d-f5091c1f9663.json +0 -1
  39. package/dist/client/_nuxt/entry.C1lnNdD0.css +0 -1
  40. package/dist/client/_nuxt/ez7nRQJI.js +0 -1
@@ -1,7 +1,7 @@
1
1
  // ==UserScript==
2
2
  // @name Furifont
3
3
  // @namespace https://furifont.antfu.me
4
- // @version 0.4.2
4
+ // @version 0.5.1
5
5
  // @description Furigana on any page: Furifont turns on by itself on Japanese pages, and the menu switches family, turns it off, or turns okurigana readings (来る, 来ない) off.
6
6
  // @homepageURL https://furifont.antfu.me
7
7
  // @downloadURL https://furifont.antfu.me/furifont.user.js
@@ -16,7 +16,7 @@
16
16
  // ==/UserScript==
17
17
 
18
18
  (() => {
19
- var Furifont=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t={fonts:[{family:`Furifont Sans`,base:`Source Han Sans JP`,face:`sans`,rubyScript:`hiragana`},{family:`Furifont Sans Romaji`,base:`Source Han Sans JP`,face:`sans`,rubyScript:`hepburn`},{family:`Furifont Serif`,base:`Source Han Serif JP`,face:`serif`,rubyScript:`hiragana`},{family:`Furifont Serif Romaji`,base:`Source Han Serif JP`,face:`serif`,rubyScript:`hepburn`}],weights:[{style:`Regular`,weight:400}],variable:{style:`VF`,weights:[250,900]},options:{take:4e4}},n={base:12290,selector:65024},r=`U+2E80-2FDF,U+3000-30FF,U+3190-319F,U+31F0-31FF,U+3400-4DBF,U+4E00-9FFF,U+F900-FAFF,U+FE00-FE0F,U+FF00-FFEF,U+20000-3FFFF,U+E0100-E01EF`,i=/[\p{sc=Han}\p{sc=Hiragana}\p{sc=Katakana}]/u;function a(e){return(e.match(/\s*(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|[^,]+)/g)??[]).map(e=>e.trim()).filter(Boolean)}function o(e){return e.replace(/^(["'])(.*)\1$/,`$2`)}let s=/mono|courier|consol|menlo|monaco|等幅/i;function c(e){let t=e.map(o);return t.some(e=>e===`monospace`||e===`ui-monospace`)||s.test(t[0]??``)}async function l({family:e,url:n,fetchFont:i}){let a=(t,n=`400`)=>new FontFace(e,t,{unicodeRange:r,weight:n}).load().catch(()=>void 0),o=await Promise.all(t.weights.map(({style:t,weight:n})=>a(`local("${e} ${t}")${n===400?`,local("${e}")`:``}`,String(n)))),s=t.variable.weights.join(` `),c=o.some(Boolean)?o:[await(i?i(n).then(e=>a(e,s),()=>void 0):a(`url("${n}")`,s))];for(let e of c)e&&document.fonts.add(e);return c.some(Boolean)}function u(e){let t=/* @__PURE__ */ new Map,n=/(?<!\p{sc=Han})\p{sc=Han}+(?=\p{sc=Hiragana})/gu,r=n=>{if(!t.has(n)){let r=/* @__PURE__ */ new Map;for(let[t,i]of Object.entries(e.pairs[n]??{}))for(let e of i)r.set(e,t||null);t.set(n,r.size?{reading:r,longest:Math.max(...[...r.keys()].map(e=>e.length))}:void 0)}return t.get(n)},i=(t,n)=>{let r=t.length>[...t][0].length,i=(r?e.words[t]?.map(e=>[...e.matchAll(/\[([^\]]*)\]/g)].map(e=>e[1]).join(``)):e.readings[t])?.indexOf(n)??-1;return i>=+!!r&&i<15&&e.lone[t]!==n?i+1:0};return{find:e=>{let t=[];for(let{0:a,index:o}of e.matchAll(n)){let n=r(a),s=e.slice(o+a.length,o+a.length+(n?.longest??0)),c;for(let e=s.length;e>0&&c===void 0;e--)c=n?.reading.get(s.slice(0,e));let l=c?i(a,c):0;c&&l&&t.push({at:o,length:a.length,reading:c,salt:l})}return t},saltOf:i}}let d=/* @__PURE__ */ new Map;function f(e,t){let n=d.get(e);return n||(n=(t?t(e):fetch(e).then(t=>t.ok?t.text():Promise.reject(Error(e)))).then(JSON.parse),n.catch(()=>d.delete(e)),d.set(e,n)),n}async function p({readings:e,pairs:t,fetchText:n}){try{let[r,i]=await Promise.all([f(e,n),f(t,n)]);return r.salt===!0?u({pairs:i,readings:r.kanji,words:r.words,lone:r.lone}):void 0}catch{return}}function m(e,t){return{href:new URL(`/#downloads`,e).href,text:t.download}}function h(e,t,n){document.querySelector(`furifont-toast`)?.remove();let r=document.createElement(`furifont-toast`),i=r.attachShadow({mode:`open`}),a=new CSSStyleSheet;a.replaceSync(`:host{all:initial}div{position:fixed;z-index:2147483647;right:16px;bottom:16px;display:flex;gap:16px;align-items:start;max-width:360px;padding:12px 16px;border:1px solid #fafafa2b;background:#0a0a0a;color:#fafafa;font:14px/1.5 system-ui,sans-serif}p{margin:0}a{color:inherit;margin-right:12px}button{padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}`),i.adoptedStyleSheets=[a];let o=document.createElement(`p`);o.append(e,` `,...t.map(({href:e,text:t})=>Object.assign(document.createElement(`a`),{href:e,target:`_blank`,rel:`noopener`,textContent:t})));let s=Object.assign(document.createElement(`button`),{ariaLabel:n,textContent:`×`,onclick:()=>r.remove()}),c=Object.assign(document.createElement(`div`),{role:`alert`});c.append(o,s),i.append(c),document.body.append(r),setTimeout(()=>r.remove(),1e4)}function g(e){let[t=0,n=0,r=0]=e.split(`.`).map(Number);return t*1e3+n*100+r}function _(e){let t=document.createElement(`canvas`).getContext(`2d`);return t.font=`1000px "${e}"`,Math.round(t.measureText(String.fromCodePoint(n.base,n.selector)).width)-2e3}async function v({family:e,url:t,toast:n},r){let i=new URL(`/version.json`,t).href,a;try{a=g(JSON.parse(await(r.fetchText?r.fetchText(i):fetch(i).then(e=>e.text()))).version)}catch{return}let o=[...g(r.version)<a?[r]:[],..._(e)<a?[m(t,n)]:[]];o.length&&h(n.outdated,o,n.close)}function y(e){let t=[];for(let n of e.filter(e=>e.isConnected)){let e=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);for(let n=e.currentNode;n;n=e.nextNode())n.nodeType===Node.TEXT_NODE&&n.parentElement&&t.push(n)}return t}function b(e){let t=new Set(y(e).filter(e=>i.test(e.nodeValue??``)).map(e=>e.parentElement));for(let n of e){if(n.nodeType!==Node.ELEMENT_NODE)continue;let e=n;e.matches(`input,textarea`)&&t.add(e);for(let n of e.querySelectorAll(`input,textarea`))t.add(n)}return t}function x(e){let t=new CSSStyleSheet,n=[],r,i=0,s=()=>{for(let e of document.querySelectorAll(`[data-furifont-reading]`)){let t=r?r.saltOf(e.textContent??``,e.dataset.furifontReading):0;t?e.dataset.furifontSalt=String(t):delete e.dataset.furifontSalt}},l=e=>{if(!r)return;let t=y(e).filter(e=>/\p{sc=Han}\p{sc=Hiragana}/u.test(e.nodeValue??``)&&!e.parentElement.closest(`script,style,textarea,noscript,ruby,[contenteditable]:not([contenteditable=false]),[data-furifont-reading]`));for(let e of t)for(let{at:t,length:n,reading:i,salt:a}of r.find(e.nodeValue??``).reverse()){let r=t?e.splitText(t):e;r.length>n&&r.splitText(n);let o=document.createElement(`span`);o.dataset.furifontReading=i,o.dataset.furifontSalt=String(a),r.replaceWith(o),o.append(r)}},u={dispose:()=>{},sheet:t,family:e,restyle:()=>{let e=Array.from({length:15},(e,t)=>`[data-furifont-salt="${t+1}"]{font-feature-settings:"salt" ${t+1}!important}`).join(``),r=n.map((e,t)=>`[data-furifont="${t}"]{font-family:"${u.family}",${e}!important}`).join(``);t.replaceSync(`${r}[data-furifont-tight]{line-height:normal!important}ruby,ruby *{font-feature-settings:"ss01"!important}${e}`)},okurigana:e=>{let n=++i;r=void 0,s(),e&&!t.disabled&&p(e).then(e=>{n===i&&e&&(r=e,s(),l([document.body]))})}},d=e=>{let t=[...b(e)].filter(e=>!e.hasAttribute(`data-furifont`)).map(e=>{let{fontFamily:t,lineHeight:n,fontSize:r}=getComputedStyle(e),i=a(t);return o(i[0]??``)===u.family&&i.shift(),{element:e,stack:i,tight:Number.parseFloat(n)<1.6*Number.parseFloat(r)}}).filter(({stack:e})=>e.length&&!c(e)),r=n.length;for(let{element:e,stack:r,tight:i}of t){let t=r.join(`,`),a=n.includes(t)?n.indexOf(t):n.push(t)-1;e.setAttribute(`data-furifont`,String(a)),i&&e.setAttribute(`data-furifont-tight`,``)}n.length>r&&u.restyle()},f=new MutationObserver(e=>{let t=e.flatMap(e=>e.type===`characterData`?[e.target]:[...e.addedNodes]);d(t),l(t)});return u.dispose=()=>{f.disconnect(),i++,r=void 0,document.adoptedStyleSheets=document.adoptedStyleSheets.filter(e=>e!==t);for(let e of document.querySelectorAll(`[data-furifont],[data-furifont-tight]`))e.removeAttribute(`data-furifont`),e.removeAttribute(`data-furifont-tight`);for(let e of document.querySelectorAll(`[data-furifont-reading]`))e.replaceWith(...e.childNodes);window.furifont===u&&delete window.furifont},window.furifont=u,document.adoptedStyleSheets=[...document.adoptedStyleSheets,t],d([document.body]),f.observe(document.body,{childList:!0,characterData:!0,subtree:!0}),u}async function S(e){let{family:t,url:n,toast:r,okurigana:i,update:a}=e,o=window.furifont;o?.family===t?(o.sheet.disabled=!o.sheet.disabled,o.sheet.disabled||o.okurigana(i)):(o??=x(t),o.family=t,o.restyle(),o.sheet.disabled=!1,await l(e)?(o.okurigana(i),a&&await v(e,a)):(o.sheet.disabled=!0,o.family=``,h(r.message,[m(n,r)],r.close)))}return e.JAPANESE=i,e.UNICODE_RANGE=r,e.createOkuriganaReader=u,e.isMonospace=c,e.loadFurifont=l,e.loadOkuriganaReader=p,e.parseFontStack=a,e.showToast=h,e.toggleFurifont=S,e})({});
19
+ var Furifont=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t={fonts:[{family:`Furifont Sans`,base:`Source Han Sans JP`,face:`sans`,furiganaScript:`hiragana`},{family:`Furifont Sans Romaji`,base:`Source Han Sans JP`,face:`sans`,furiganaScript:`hepburn`},{family:`Furifont Serif`,base:`Source Han Serif JP`,face:`serif`,furiganaScript:`hiragana`},{family:`Furifont Serif Romaji`,base:`Source Han Serif JP`,face:`serif`,furiganaScript:`hepburn`}],weights:[{style:`Regular`,weight:400}],variable:{style:`VF`,weights:[250,900]},options:{take:`max`}},n={base:12290,selector:65024},r=`U+2E80-2FDF,U+3000-30FF,U+3190-319F,U+31F0-31FF,U+3400-4DBF,U+4E00-9FFF,U+F900-FAFF,U+FE00-FE0F,U+FF00-FFEF,U+20000-3FFFF,U+E0100-E01EF`,i=/[\p{sc=Han}\p{sc=Hiragana}\p{sc=Katakana}]/u;function a(e){return(e.match(/\s*(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|[^,]+)/g)??[]).map(e=>e.trim()).filter(Boolean)}function o(e){return e.replace(/^(["'])(.*)\1$/,`$2`)}let s=/mono|courier|consol|menlo|monaco|等幅/i;function c(e){let t=e.map(o);return t.some(e=>e===`monospace`||e===`ui-monospace`)||s.test(t[0]??``)}async function l({family:e,url:n,fetchFont:i}){let a=(t,n=`400`)=>new FontFace(e,t,{unicodeRange:r,weight:n}).load().catch(()=>void 0),o=await Promise.all(t.weights.map(({style:t,weight:n})=>a(`local("${e} ${t}")${n===400?`,local("${e}")`:``}`,String(n)))),s=t.variable.weights.join(` `),c=o.some(Boolean)?o:[await(i?i(n).then(e=>a(e,s),()=>void 0):a(`url("${n}")`,s))];for(let e of c)e&&document.fonts.add(e);return c.some(Boolean)}function u(e){let t=/* @__PURE__ */ new Map,n=/(?<!\p{sc=Han})\p{sc=Han}+(?=\p{sc=Hiragana})/gu,r=n=>{if(!t.has(n)){let r=/* @__PURE__ */ new Map;for(let[t,i]of Object.entries(e.pairs[n]??{}))for(let e of i)r.set(e,t||null);t.set(n,r.size?{reading:r,longest:Math.max(...[...r.keys()].map(e=>e.length))}:void 0)}return t.get(n)},i=(t,n)=>{let r=t.length>[...t][0].length,i=(r?e.words[t]?.map(e=>[...e.matchAll(/\[([^\]]*)\]/g)].map(e=>e[1]).join(``)):e.readings[t])?.indexOf(n)??-1;return i>=+!!r&&i<15&&e.lone[t]!==n?i+1:0};return{find:e=>{let t=[];for(let{0:a,index:o}of e.matchAll(n)){let n=r(a),s=e.slice(o+a.length,o+a.length+(n?.longest??0)),c;for(let e=s.length;e>0&&c===void 0;e--)c=n?.reading.get(s.slice(0,e));let l=c?i(a,c):0;c&&l&&t.push({at:o,length:a.length,reading:c,salt:l})}return t},saltOf:i}}let d=/* @__PURE__ */ new Map;function f(e,t){let n=d.get(e);return n||(n=(t?t(e):fetch(e).then(t=>t.ok?t.text():Promise.reject(Error(e)))).then(JSON.parse),n.catch(()=>d.delete(e)),d.set(e,n)),n}async function p({readings:e,pairs:t,fetchText:n}){try{let[r,i]=await Promise.all([f(e,n),f(t,n)]);return r.salt===!0?u({pairs:i,readings:r.kanji,words:r.words,lone:r.lone}):void 0}catch{return}}function m(e,t){return{href:new URL(`/#downloads`,e).href,text:t.download}}function h(e,t,n){document.querySelector(`furifont-toast`)?.remove();let r=document.createElement(`furifont-toast`),i=r.attachShadow({mode:`open`}),a=new CSSStyleSheet;a.replaceSync(`:host{all:initial}div{position:fixed;z-index:2147483647;right:16px;bottom:16px;display:flex;gap:16px;align-items:start;max-width:360px;padding:12px 16px;border:1px solid #fafafa2b;background:#0a0a0a;color:#fafafa;font:14px/1.5 system-ui,sans-serif}p{margin:0}a{color:inherit;margin-right:12px}button{padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}`),i.adoptedStyleSheets=[a];let o=document.createElement(`p`);o.append(e,` `,...t.map(({href:e,text:t})=>Object.assign(document.createElement(`a`),{href:e,target:`_blank`,rel:`noopener`,textContent:t})));let s=Object.assign(document.createElement(`button`),{ariaLabel:n,textContent:`×`,onclick:()=>r.remove()}),c=Object.assign(document.createElement(`div`),{role:`alert`});c.append(o,s),i.append(c),document.body.append(r),setTimeout(()=>r.remove(),1e4)}function g(e){let[t=0,n=0,r=0]=e.split(`.`).map(Number);return t*1e3+n*100+r}function _(e){let t=document.createElement(`canvas`).getContext(`2d`);return t.font=`1000px "${e}"`,Math.round(t.measureText(String.fromCodePoint(n.base,n.selector)).width)-2e3}async function v({family:e,url:t,toast:n},r){let i=new URL(`/version.json`,t).href,a;try{a=g(JSON.parse(await(r.fetchText?r.fetchText(i):fetch(i).then(e=>e.text()))).version)}catch{return}let o=[...g(r.version)<a?[r]:[],..._(e)<a?[m(t,n)]:[]];o.length&&h(n.outdated,o,n.close)}function y(e){let t=[];for(let n of e.filter(e=>e.isConnected)){let e=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);for(let n=e.currentNode;n;n=e.nextNode())n.nodeType===Node.TEXT_NODE&&n.parentElement&&t.push(n)}return t}function b(e){let t=new Set(y(e).filter(e=>i.test(e.nodeValue??``)).map(e=>e.parentElement));for(let n of e){if(n.nodeType!==Node.ELEMENT_NODE)continue;let e=n;e.matches(`input,textarea`)&&t.add(e);for(let n of e.querySelectorAll(`input,textarea`))t.add(n)}return t}function x(e){let t=new CSSStyleSheet,n=[],r,i=0,s=()=>{for(let e of document.querySelectorAll(`[data-furifont-reading]`)){let t=r?r.saltOf(e.textContent??``,e.dataset.furifontReading):0;t?e.dataset.furifontSalt=String(t):delete e.dataset.furifontSalt}},l=e=>{if(!r)return;let t=y(e).filter(e=>/\p{sc=Han}\p{sc=Hiragana}/u.test(e.nodeValue??``)&&!e.parentElement.closest(`script,style,textarea,noscript,ruby,[contenteditable]:not([contenteditable=false]),[data-furifont-reading]`));for(let e of t)for(let{at:t,length:n,reading:i,salt:a}of r.find(e.nodeValue??``).reverse()){let r=t?e.splitText(t):e;r.length>n&&r.splitText(n);let o=document.createElement(`span`);o.dataset.furifontReading=i,o.dataset.furifontSalt=String(a),r.replaceWith(o),o.append(r)}},u={dispose:()=>{},sheet:t,family:e,restyle:()=>{let e=Array.from({length:15},(e,t)=>`[data-furifont-salt="${t+1}"]{font-feature-settings:"salt" ${t+1}!important}`).join(``),r=n.map((e,t)=>`[data-furifont="${t}"]{font-family:"${u.family}",${e}!important}`).join(``);t.replaceSync(`${r}[data-furifont-tight]{line-height:normal!important}ruby,ruby *{font-feature-settings:"ss01"!important}${e}`)},okurigana:e=>{let n=++i;r=void 0,s(),e&&!t.disabled&&p(e).then(e=>{n===i&&e&&(r=e,s(),l([document.body]))})}},d=e=>{let t=[...b(e)].filter(e=>!e.hasAttribute(`data-furifont`)).map(e=>{let{fontFamily:t,lineHeight:n,fontSize:r}=getComputedStyle(e),i=a(t);return o(i[0]??``)===u.family&&i.shift(),{element:e,stack:i,tight:Number.parseFloat(n)<1.6*Number.parseFloat(r)}}).filter(({stack:e})=>e.length&&!c(e)),r=n.length;for(let{element:e,stack:r,tight:i}of t){let t=r.join(`,`),a=n.includes(t)?n.indexOf(t):n.push(t)-1;e.setAttribute(`data-furifont`,String(a)),i&&e.setAttribute(`data-furifont-tight`,``)}n.length>r&&u.restyle()},f=new MutationObserver(e=>{let t=e.flatMap(e=>e.type===`characterData`?[e.target]:[...e.addedNodes]);d(t),l(t)});return u.dispose=()=>{f.disconnect(),i++,r=void 0,document.adoptedStyleSheets=document.adoptedStyleSheets.filter(e=>e!==t);for(let e of document.querySelectorAll(`[data-furifont],[data-furifont-tight]`))e.removeAttribute(`data-furifont`),e.removeAttribute(`data-furifont-tight`);for(let e of document.querySelectorAll(`[data-furifont-reading]`))e.replaceWith(...e.childNodes);window.furifont===u&&delete window.furifont},window.furifont=u,document.adoptedStyleSheets=[...document.adoptedStyleSheets,t],d([document.body]),f.observe(document.body,{childList:!0,characterData:!0,subtree:!0}),u}async function S(e){let{family:t,url:n,toast:r,okurigana:i,update:a}=e,o=window.furifont;o?.family===t?(o.sheet.disabled=!o.sheet.disabled,o.sheet.disabled||o.okurigana(i)):(o??=x(t),o.family=t,o.restyle(),o.sheet.disabled=!1,await l(e)?(o.okurigana(i),a&&await v(e,a)):(o.sheet.disabled=!0,o.family=``,h(r.message,[m(n,r)],r.close)))}return e.JAPANESE=i,e.UNICODE_RANGE=r,e.createOkuriganaReader=u,e.isMonospace=c,e.loadFurifont=l,e.loadOkuriganaReader=p,e.parseFontStack=a,e.showToast=h,e.toggleFurifont=S,e})({});
20
20
  ;(function start(manager, toggle, fonts, pairs, script, toasts, menus, detect) {
21
21
  var _a;
22
22
  const locale = detect(navigator.languages);
@@ -55,7 +55,7 @@ var Furifont=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Mod
55
55
  registerOkurigana();
56
56
  if (/^ja(?:-|$)/i.test(document.documentElement.lang))
57
57
  toggle({ ...options(saved), update: update() });
58
- })({ getValue: GM_getValue, setValue: GM_setValue, registerMenuCommand: GM_registerMenuCommand, xmlHttpRequest: GM_xmlhttpRequest }, Furifont.toggleFurifont, [{"family":"Furifont Sans","url":"https://furifont.antfu.me/fonts/FurifontSansVF.woff2?v=0.4.2","readings":"https://furifont.antfu.me/fonts/FurifontSansVF.ivs.json?v=0.4.2"},{"family":"Furifont Sans Romaji","url":"https://furifont.antfu.me/fonts/FurifontSansRomajiVF.woff2?v=0.4.2","readings":"https://furifont.antfu.me/fonts/FurifontSansRomajiVF.ivs.json?v=0.4.2"},{"family":"Furifont Serif","url":"https://furifont.antfu.me/fonts/FurifontSerifVF.woff2?v=0.4.2","readings":"https://furifont.antfu.me/fonts/FurifontSerifVF.ivs.json?v=0.4.2"},{"family":"Furifont Serif Romaji","url":"https://furifont.antfu.me/fonts/FurifontSerifRomajiVF.woff2?v=0.4.2","readings":"https://furifont.antfu.me/fonts/FurifontSerifRomajiVF.ivs.json?v=0.4.2"}], "https://furifont.antfu.me/okurigana.json", {"version":"0.4.2","href":"https://furifont.antfu.me/furifont.user.js"}, {"en":{"message":"Furifont could not load its font on this page. Some sites, such as X and GitHub, do not let fonts load from other sites. On those sites, you must install Furifont on your computer.","download":"Download the fonts","close":"Close","outdated":"A newer version of Furifont is out.","userscript":"Update the userscript","bookmarklet":"Get the new bookmarklet"},"ja":{"message":"このページでは Furifont のフォントを読み込めませんでした。X や GitHub のように、他のサイトのフォントを読み込めないサイトがあります。そのようなサイトでは、パソコンに Furifont をインストールする必要があります。","download":"フォントをダウンロード","close":"閉じる","outdated":"Furifont の新しいバージョンがあります。","userscript":"ユーザースクリプトを更新","bookmarklet":"新しいブックマークレットを入手"},"zh-Hans":{"message":"Furifont 无法在此页面加载字体。有些网站(如 X 和 GitHub)不允许加载其他网站的字体。在这些网站上,需要在电脑上安装 Furifont。","download":"下载字体","close":"关闭","outdated":"Furifont 有新版本了。","userscript":"更新用户脚本","bookmarklet":"获取新的书签小工具"},"zh-Hant":{"message":"Furifont 無法在此頁面載入字型。有些網站(如 X 和 GitHub)不允許載入其他網站的字型。在這些網站上,需要在電腦上安裝 Furifont。","download":"下載字型","close":"關閉","outdated":"Furifont 有新版本了。","userscript":"更新使用者腳本","bookmarklet":"取得新的書籤小工具"}}, {"en":{"okuriganaOn":"Okurigana readings: on","okuriganaOff":"Okurigana readings: off"},"ja":{"okuriganaOn":"送り仮名の読み:オン","okuriganaOff":"送り仮名の読み:オフ"},"zh-Hans":{"okuriganaOn":"送假名读音:开","okuriganaOff":"送假名读音:关"},"zh-Hant":{"okuriganaOn":"送假名讀音:開","okuriganaOff":"送假名讀音:關"}}, function detectLocale(languages) {
58
+ })({ getValue: GM_getValue, setValue: GM_setValue, registerMenuCommand: GM_registerMenuCommand, xmlHttpRequest: GM_xmlhttpRequest }, Furifont.toggleFurifont, [{"family":"Furifont Sans","url":"https://furifont.antfu.me/fonts/FurifontSansVF.woff2?v=0.5.1","readings":"https://furifont.antfu.me/fonts/FurifontSansVF.ivs.json?v=0.5.1"},{"family":"Furifont Sans Romaji","url":"https://furifont.antfu.me/fonts/FurifontSansRomajiVF.woff2?v=0.5.1","readings":"https://furifont.antfu.me/fonts/FurifontSansRomajiVF.ivs.json?v=0.5.1"},{"family":"Furifont Serif","url":"https://furifont.antfu.me/fonts/FurifontSerifVF.woff2?v=0.5.1","readings":"https://furifont.antfu.me/fonts/FurifontSerifVF.ivs.json?v=0.5.1"},{"family":"Furifont Serif Romaji","url":"https://furifont.antfu.me/fonts/FurifontSerifRomajiVF.woff2?v=0.5.1","readings":"https://furifont.antfu.me/fonts/FurifontSerifRomajiVF.ivs.json?v=0.5.1"}], "https://furifont.antfu.me/okurigana.json", {"version":"0.5.1","href":"https://furifont.antfu.me/furifont.user.js"}, {"en":{"message":"Furifont could not load its font on this page. Some sites, such as X and GitHub, do not let fonts load from other sites. On those sites, you must install Furifont on your computer.","download":"Download the fonts","close":"Close","outdated":"A newer version of Furifont is out.","userscript":"Update the userscript","bookmarklet":"Get the new bookmarklet"},"ja":{"message":"このページでは Furifont のフォントを読み込めませんでした。X や GitHub のように、他のサイトのフォントを読み込めないサイトがあります。そのようなサイトでは、パソコンに Furifont をインストールする必要があります。","download":"フォントをダウンロード","close":"閉じる","outdated":"Furifont の新しいバージョンがあります。","userscript":"ユーザースクリプトを更新","bookmarklet":"新しいブックマークレットを入手"},"zh-Hans":{"message":"Furifont 无法在此页面加载字体。有些网站(如 X 和 GitHub)不允许加载其他网站的字体。在这些网站上,需要在电脑上安装 Furifont。","download":"下载字体","close":"关闭","outdated":"Furifont 有新版本了。","userscript":"更新用户脚本","bookmarklet":"获取新的书签小工具"},"zh-Hant":{"message":"Furifont 無法在此頁面載入字型。有些網站(如 X 和 GitHub)不允許載入其他網站的字型。在這些網站上,需要在電腦上安裝 Furifont。","download":"下載字型","close":"關閉","outdated":"Furifont 有新版本了。","userscript":"更新使用者腳本","bookmarklet":"取得新的書籤小工具"}}, {"en":{"okuriganaOn":"Okurigana readings: on","okuriganaOff":"Okurigana readings: off"},"ja":{"okuriganaOn":"送り仮名の読み:オン","okuriganaOff":"送り仮名の読み:オフ"},"zh-Hans":{"okuriganaOn":"送假名读音:开","okuriganaOff":"送假名读音:关"},"zh-Hant":{"okuriganaOn":"送假名讀音:開","okuriganaOff":"送假名讀音:關"}}, function detectLocale(languages) {
59
59
  for (const tag of languages.map((l) => l.toLowerCase())) {
60
60
  if (tag.startsWith("zh"))
61
61
  return /-(?:tw|hk|mo|hant)\b/.test(tag) ? "zh-Hant" : "zh-Hans";
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/C4V-788C.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.C1lnNdD0.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/C4V-788C.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Dg3RF8xB.js"><script type="module" src="/_nuxt/C4V-788C.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/CHjPDtV4.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B2JUvp84.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/Kki0DvjP.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"95075385-c519-4224-af4d-f5091c1f9663",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792114629473,false]</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/BWahbb7T.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.CBgHh7ZX.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BWahbb7T.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CGjbjQXe.js"><script type="module" src="/_nuxt/BWahbb7T.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/D7M8CFSK.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BqpS6BQk.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/DrYLd3bw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"6a38fc31-347d-4f29-8fb9-80c06be37854",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792139754166,false]</script></body></html>
@@ -148,7 +148,7 @@
148
148
  "晦":{"くら":["ま","み","む","め","も","ん"]},
149
149
  "海":{"かい":["コン","パン"]},
150
150
  "皆":{"み":["んなして"],"みんな":["して"]},
151
- "開":{"":["かれた","かれて","かれない","かれます","かれる","きそう","きたい","きつつ","きながら","きに","きました","きます","きません","きやすい"],"あ":["かずの","けたて","けっぴろげ"],"かい":["ループ"],"はだ":["かっ","から","かり","かる","かれ","かろ"],"ひら":["かれさせる","かれず","かれそう","かれたい","かれたシステム","かれつつ","かれなかった","かれながら","かれに","かれました","かれません","かれやすい","かれよう","かれられる","かれれば","かれろ","き","けごま","けゴマ"]},
151
+ "開":{"":["かれた","かれて","かれない","かれます","かれる","きそう","きたい","きつつ","きながら","きに","きました","きます","きません","きやすい","くな"],"あ":["かずの","けたて","けっぴろげ"],"かい":["ループ"],"はだ":["かっ","から","かり","かる","かれ","かろ"],"ひら":["かれさせる","かれず","かれそう","かれたい","かれたシステム","かれつつ","かれなかった","かれながら","かれに","かれました","かれません","かれやすい","かれよう","かれられる","かれれば","かれろ","き","く","けごま","けゴマ"]},
152
152
  "貝":{"かい":["おおい","がら","ざいく","になっ","になら","になり","になる","になれ","になろ","ボタン"]},
153
153
  "外":{"がい":["コン","タレ","リンパ"],"はず":["さ","し","す","せ","そ","れ"],"ほか":["でもな","ならな","ならぬ"]},
154
154
  "咳":{"せ":["い","かず","かせる","かない","かなかった","かれる","き","くな","け","こ"]},
@@ -686,7 +686,7 @@
686
686
  "鍾":{"しょう":["き"]},
687
687
  "鐘":{"かね":["つき"]},
688
688
  "障":{"しょう":["がい"],"つつ":["ま","み","む","め","も","ん"]},
689
- "上":{"あ":["がっ","がら","がり","がる","がれ","がろ","げ"],"うえ":["から","では","は"],"うわ":["あご","くちびる","すべり","ずっ","ずら","ずり","ずる","ずれ","ずろ","つき","ばき","まぶた"],"かみ":["さん"],"のぼ":["さ","し","す","せ","そ","っ","ら","り","る","れ","ろ"]},
689
+ "上":{"あ":["がっ","がら","がり","がる","がれ","がろ","げ"],"うえ":["から","では","に","の","は"],"うわ":["あご","くちびる","すべり","ずっ","ずら","ずり","ずる","ずれ","ずろ","つき","ばき","まぶた"],"かみ":["さん"],"のぼ":["さ","し","す","せ","そ","っ","ら","り","る","れ","ろ"]},
690
690
  "上下":{"うえした":["になっ","になら","になり","になる","になれ","になろ"]},
691
691
  "上手":{"うま":["い","かった","く","ければ","げ","さ","すぎる","そう","み"]},
692
692
  "丈":{"だけ":["に"]},
@@ -1073,7 +1073,7 @@
1073
1073
  "日替":{"ひがわ":["り"]},
1074
1074
  "日本":{"にっぽん":["のこころ","ケミコン","シイエムケイ","ハム"]},
1075
1075
  "乳":{"にゅう":["がん","たんぱく","び","りん","ガン"]},
1076
- "入":{"":["りそう","りたい","りつつ","りながら","りに","りました","ります","りません","りやすい"],"い":["り","れあげ","れさせる","れず","れそう","れたい","れつつ","れなおさ","れなおし","れなおす","れなおせ","れなおそ","れなかった","れながら","れに","れぼくろ","れました","れません","れやすい","れよう","れられる","れれば","れろ","れタイマー"],"いり":["タイマー"],"にゅう":["トラヒック"],"はい":["りきっ","りきら","りきり","りきる","りきれ","りきろ","りこま","りこみ","りこむ","りこめ","りこも","りこん","りなおさ","りなおし","りなおす","りなおせ","りなおそ"]},
1076
+ "入":{"":["りそう","りたい","りつつ","りながら","りに","りました","ります","りません","りやすい"],"い":["り","れあげ","れさせる","れず","れそう","れたい","れつつ","れなおさ","れなおし","れなおす","れなおせ","れなおそ","れなかった","れながら","れに","れぼくろ","れました","れません","れやすい","れよう","れられる","れれば","れろ","れタイマー"],"いり":["タイマー"],"にゅう":["トラヒック"],"はい":["った","って","りきっ","りきら","りきり","りきる","りきれ","りきろ","りこま","りこみ","りこむ","りこめ","りこも","りこん","りなおさ","りなおし","りなおす","りなおせ","りなおそ"]},
1077
1077
  "如":{"し":["い","か","きそう","きたい","きつつ","きながら","きに","きました","きます","きません","きやすい","くな","け","こ"],"な":["す"]},
1078
1078
  "如何":{"":["なく","なもの","にもならな"],"いか":["な","にして","にも","ばかり","ほど"]},
1079
1079
  "任":{"にん":["じ","ずる","ずれば","ぜず","にあたっ","にあたら","にあたり","にあたる","にあたれ","にあたろ"]},
@@ -1221,11 +1221,11 @@
1221
1221
  "米":{"べい":["なす","ソ","トン","ドル","ナス","ロ"]},
1222
1222
  "僻":{"へき":["させる","される","した","して","しない","します","しろ","する","すれば","せず","せよ"]},
1223
1223
  "碧":{"あお":["い","かった","く","ければ","げ","さ","すぎる","そう","み"]},
1224
- "別":{"べっ":["して"],"べつ":["と","なく","に","アカ","ウィンドウ","バージョン"],"わ":["け"],"わか":["た","ち","っ","つ","て","とう","れ"]},
1224
+ "別":{"べっ":["して"],"べつ":["と","なく","に","の","アカ","ウィンドウ","バージョン"],"わ":["け"],"わか":["た","ち","っ","つ","て","とう","れ"]},
1225
1225
  "蔑":{"ないがし":["ろ"],"なみ":["させる","される","した","して","しない","します","しろ","する","すれば","せず","せよ"]},
1226
1226
  "偏":{"ひとえ":["に"],"ふ":["れさせる","れず","れそう","れたい","れつつ","れなかった","れながら","れに","れました","れません","れやすい","れよう","れられる","れれば","れろ"],"へん":["させる","される","した","して","しない","します","しろ","する","すれば","せず","せよ"]},
1227
1227
  "変":{"かわ":["っ","ら","り","る","れ","ろ"],"へん":["じ","ずる","ずれば","ぜず","ちくりん","てこ","に"]},
1228
- "編":{"":["もう"],"す":["い","かず","かせる","かない","かなかった","かれる","き","く","け","こ"],"へん":["か","さん","も"]},
1228
+ "編":{"あ":["ま","み","む","め","もう","ん"],"す":["い","かず","かせる","かない","かなかった","かれる","き","く","け","こ"]},
1229
1229
  "辺":{"あた":["り"],"へん":["フラグ"]},
1230
1230
  "遍":{"あまね":["く"]},
1231
1231
  "便":{"たよ":["っ","ら","り","る","れ","ろ"],"びん":["せん"],"べん":["じ","ずる","ずれば","ぜず"]},
@@ -1356,7 +1356,7 @@
1356
1356
  "妖":{"あや":["し"]},
1357
1357
  "容":{"い":["れ"],"よう":["かい"]},
1358
1358
  "容易":{"たやす":["い","かった","く","ければ","げ","さ","すぎる","そう","み"]},
1359
- "様":{"ざま":["はな","みろ"],"よう":["だ","です","な","にいい","にいう","にいえ","にいお","にいっ","にいわ","にする","になっ","になら","になり","になる","になれ","になろ"]},
1359
+ "様":{"さま":["です"],"ざま":["はな","みろ"],"よう":["だ","な","にいい","にいう","にいえ","にいお","にいっ","にいわ","にする","になっ","になら","になり","になる","になれ","になろ"]},
1360
1360
  "洋":{"よう":["がらし","なし","もく","もの","ゲー","ナシ","パン","モク","モノ","ラン"]},
1361
1361
  "溶":{"よう":["てん"]},
1362
1362
  "熔":{"と":["かさ","かし","かす","かせ","かそ","け"]},
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/C4V-788C.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.C1lnNdD0.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/C4V-788C.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Dg3RF8xB.js"><script type="module" src="/_nuxt/C4V-788C.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/CHjPDtV4.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B2JUvp84.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/Kki0DvjP.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"95075385-c519-4224-af4d-f5091c1f9663",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792114629472,false]</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/BWahbb7T.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.CBgHh7ZX.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BWahbb7T.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CGjbjQXe.js"><script type="module" src="/_nuxt/BWahbb7T.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/D7M8CFSK.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BqpS6BQk.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/DrYLd3bw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"6a38fc31-347d-4f29-8fb9-80c06be37854",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792139754165,false]</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/C4V-788C.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.C1lnNdD0.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/C4V-788C.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Dg3RF8xB.js"><script type="module" src="/_nuxt/C4V-788C.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/CHjPDtV4.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B2JUvp84.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/Kki0DvjP.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"95075385-c519-4224-af4d-f5091c1f9663",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792114629472,false]</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Furifont: furigana built into the font</title><script type="importmap">{"imports":{"#entry":"/_nuxt/BWahbb7T.js"}}</script><link rel="stylesheet" href="/_nuxt/entry.CBgHh7ZX.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/_nuxt/BWahbb7T.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/y07Wd5I9.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CkUAspOr.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/D4ezFGbh.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/Cl84O_XS.js"><link rel="modulepreload" as="script" crossorigin href="/_nuxt/CGjbjQXe.js"><script type="module" src="/_nuxt/BWahbb7T.js" crossorigin></script><link rel="prefetch" as="script" crossorigin href="/_nuxt/D7M8CFSK.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/BqpS6BQk.js"><link rel="prefetch" as="script" crossorigin href="/_nuxt/DrYLd3bw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-404.CaT3AK-0.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/B4Fx_Djw.js"><link rel="prefetch" as="style" crossorigin href="/_nuxt/error-500.WL1uhYQu.css"><link rel="prefetch" as="script" crossorigin href="/_nuxt/X45Acd-Y.js"><meta name="description" content="A Japanese font that shows furigana by itself."><meta property="og:type" content="website"><meta property="og:url" content="https://furifont.antfu.me"><meta property="og:title" content="Furifont: furigana built into the font"><meta property="og:description" content="A Japanese font that shows furigana by itself."><meta property="og:image" content="https://furifont.antfu.me/og.png"><meta property="og:image:width" content="2400"><meta property="og:image:height" content="1260"><meta property="og:image:alt" content="Furifont: furigana built into the font"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="Furifont: furigana built into the font"><meta name="twitter:description" content="A Japanese font that shows furigana by itself."><meta name="twitter:image" content="https://furifont.antfu.me/og.png"><link rel="icon" type="image/svg+xml" href="favicon.svg"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{devCustomizeBase:"/__furifont/"},app:{baseURL:"/",buildId:"6a38fc31-347d-4f29-8fb9-80c06be37854",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1792139754165,false]</script></body></html>
@@ -1 +1 @@
1
- {"version":"0.4.2"}
1
+ {"version":"0.5.1"}
@@ -4,13 +4,13 @@ import { basename, join, resolve } from "node:path";
4
4
  import process from "node:process";
5
5
  import { BASE_FONTS, FONT_VERSION, compileFont, readFontInfo, toWoff2 } from "@furifont/compiler";
6
6
  import { brotli, subsetWasm } from "@furifont/compiler/node";
7
- import { DEFAULTS, PlanOptionsSchema, createFontPlanner } from "@furifont/core";
7
+ import { DEFAULTS, GLYPH_LIMIT, PlanOptionsSchema, createFontPlanner } from "@furifont/core";
8
8
  import { loadDictionary } from "@furifont/dictionary";
9
9
  import { randomUUID } from "node:crypto";
10
10
  import * as v from "valibot";
11
11
  //#region package.json
12
12
  var name = "furifont";
13
- var version = "0.4.2";
13
+ var version = "0.5.1";
14
14
  var description = "Build Japanese fonts that show furigana by themselves, from the command line or a local studio";
15
15
  var homepage = "https://github.com/antfu/furifont#readme";
16
16
  //#endregion
@@ -58,17 +58,37 @@ const coverages = /* @__PURE__ */ new Map();
58
58
  function getDictionary() {
59
59
  return dictionary ??= loadDictionary();
60
60
  }
61
- /** Plans a font for `config`; with `previewText`, only what that text needs. */
62
- async function planWithBase(config, cwd, previewText) {
61
+ /** The planner, and the base font's path with the codepoints it draws and the glyphs it has room for. */
62
+ async function plannerFor(config, cwd) {
63
63
  planner ??= getDictionary().then(createFontPlanner);
64
64
  const base = await resolveBase(config.base, cwd);
65
- let coverage = coverages.get(base);
66
- if (!coverage) coverages.set(base, coverage = readFile(base).then((font) => new Set(readFontInfo(font).codepoints)));
65
+ let info = coverages.get(base);
66
+ if (!info) coverages.set(base, info = readFile(base).then((font) => {
67
+ const { codepoints, glyphCount } = readFontInfo(font);
68
+ return {
69
+ coverage: new Set(codepoints),
70
+ glyphBudget: GLYPH_LIMIT - glyphCount
71
+ };
72
+ }));
73
+ return {
74
+ plan: await planner,
75
+ base,
76
+ ...await info
77
+ };
78
+ }
79
+ /** Plans a font for `config`; with `previewText`, only what that text needs. */
80
+ async function planWithBase(config, cwd, previewText) {
81
+ const { plan, base, coverage, glyphBudget } = await plannerFor(config, cwd);
67
82
  return {
68
- ...(await planner)(config, await coverage, previewText),
83
+ ...plan(config, coverage, previewText, glyphBudget),
69
84
  base
70
85
  };
71
86
  }
87
+ /** Every word of the dictionary, most common first, as `config` skips, takes or leaves it. */
88
+ async function bucketWords(config, cwd) {
89
+ const { plan, coverage, glyphBudget } = await plannerFor(config, cwd);
90
+ return plan.wordBuckets(config, coverage, glyphBudget);
91
+ }
72
92
  /** `<Family>-<Style>`, or a variable font's `<Family>`: its one file has every style. */
73
93
  function fileStem(config, { style, variable }) {
74
94
  const family = config.family.replaceAll(" ", "");
@@ -178,4 +198,4 @@ async function loadConfig(cwd, path = CONFIG_FILE) {
178
198
  return result.output;
179
199
  }
180
200
  //#endregion
181
- export { buildFont as a, planWithBase as c, homepage as d, name as f, loadConfig as i, previewFont as l, FONT_FORMATS as n, estimateFont as o, version as p, FurifontConfigSchema as r, getDictionary as s, CONFIG_FILE as t, description as u };
201
+ export { bucketWords as a, getDictionary as c, description as d, homepage as f, loadConfig as i, planWithBase as l, version as m, FONT_FORMATS as n, buildFont as o, name as p, FurifontConfigSchema as r, estimateFont as s, CONFIG_FILE as t, previewFont as u };
package/dist/devframe.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { d as homepage, f as name, p as version, u as description } from "./config-BHN-5b6L.mjs";
2
- import { n as STUDIO_ID, r as setupStudio } from "./studio-bPS1eciv.mjs";
1
+ import { d as description, f as homepage, m as version, p as name } from "./config-CbOFGotB.mjs";
2
+ import { n as STUDIO_ID, r as setupStudio } from "./studio-DtSmLTSj.mjs";
3
3
  import { defineDevframe } from "devframe";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/devframe.ts
package/dist/index.d.mts CHANGED
@@ -15,10 +15,10 @@ export declare const FurifontConfigSchema: v.ObjectSchema<{
15
15
  */
16
16
  readonly version: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "version must be major.minor.patch, with a minor below 10 and a patch below 100">]>, undefined>;
17
17
  readonly family: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.TrimAction, v.NonEmptyAction<string, undefined>, v.CheckAction<string, "Source is a reserved font name of the base font">]>, "Furifont Sans">;
18
- readonly rubyScript: v.OptionalSchema<v.PicklistSchema<readonly ["hiragana", "katakanaOn", "hepburn"], undefined>, "hiragana">;
18
+ readonly furiganaScript: v.OptionalSchema<v.PicklistSchema<readonly ["hiragana", "katakanaOn", "hepburn"], undefined>, "hiragana">;
19
19
  readonly sources: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<readonly ["jmdict", "ichi", "news", "spec", "gai", "nf", "tatoeba", "place", "mahjong-yaku", "jr-stations", "yojijukugo", "japan-post"], undefined>, undefined>, () => ("jmdict" | "ichi" | "news" | "spec" | "gai" | "nf" | "tatoeba" | "place" | "mahjong-yaku" | "jr-stations" | "yojijukugo" | "japan-post")[]>;
20
20
  readonly skip: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, 0>;
21
- readonly take: v.OptionalSchema<v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, v.MinValueAction<number, 1, undefined>]>, undefined>;
21
+ readonly take: v.OptionalSchema<v.UnionSchema<[v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, v.MinValueAction<number, 1, undefined>]>, v.LiteralSchema<"max", undefined>], undefined>, undefined>;
22
22
  readonly skipJlpt: v.OptionalSchema<v.PicklistSchema<readonly ["N5", "N4", "N3", "N2", "N1"], undefined>, undefined>;
23
23
  readonly isolated: v.OptionalSchema<v.BooleanSchema<undefined>, true>;
24
24
  readonly isolatedMinShare: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0.5, undefined>, v.MaxValueAction<number, 1, undefined>]>, 0.8>;
@@ -119,6 +119,21 @@ interface WordMatch {
119
119
  sources: Source[];
120
120
  }[];
121
121
  }
122
+ /** A spread of one bucket of words, as the overview lists it. */
123
+ interface WordSample {
124
+ /** Words in the bucket. */
125
+ size: number;
126
+ /** Each with its place among all the words, most common first, and its best reading. */
127
+ words: {
128
+ rank: number;
129
+ notation: string;
130
+ }[];
131
+ }
132
+ interface WordSamples {
133
+ skip: WordSample;
134
+ take: WordSample;
135
+ rest: WordSample;
136
+ }
122
137
  /** The wire contract of the functions below, as the studio page calls them. */
123
138
  interface StudioFunctions {
124
139
  'furifont:state': () => Promise<StudioState>;
@@ -130,9 +145,10 @@ interface StudioFunctions {
130
145
  };
131
146
  'furifont:save': (config: FurifontConfigInput) => Promise<string>;
132
147
  'furifont:search': (query: string) => Promise<WordMatch[]>;
148
+ 'furifont:sample': (config: FurifontConfigInput) => Promise<WordSamples>;
133
149
  }
134
150
  declare module 'devframe' {
135
151
  interface DevframeRpcServerFunctions extends StudioFunctions {}
136
152
  }
137
153
  //#endregion
138
- export { type BuildEvent, type BuildResult, type BuiltFile, DEFAULTS, type FurifontConfig, type FurifontConfigInput, PREBUILT, type PlanReport, type PreviewResult, type SizeEstimate, type StudioFunctions, type StudioState, type WordMatch };
154
+ export { type BuildEvent, type BuildResult, type BuiltFile, DEFAULTS, type FurifontConfig, type FurifontConfigInput, PREBUILT, type PlanReport, type PreviewResult, type SizeEstimate, type StudioFunctions, type StudioState, type WordMatch, type WordSample, type WordSamples };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as buildFont, i as loadConfig, l as previewFont, o as estimateFont, r as FurifontConfigSchema, t as CONFIG_FILE } from "./config-BHN-5b6L.mjs";
2
- import { n as STUDIO_ID, t as BUILD_CHANNEL } from "./studio-bPS1eciv.mjs";
1
+ import { i as loadConfig, o as buildFont, r as FurifontConfigSchema, s as estimateFont, t as CONFIG_FILE, u as previewFont } from "./config-CbOFGotB.mjs";
2
+ import { n as STUDIO_ID, t as BUILD_CHANNEL } from "./studio-DtSmLTSj.mjs";
3
3
  import { DEFAULTS, PREBUILT } from "@furifont/core";
4
4
  export { BUILD_CHANNEL, CONFIG_FILE, DEFAULTS, FurifontConfigSchema, PREBUILT, STUDIO_ID, buildFont, estimateFont, loadConfig, previewFont };
@@ -1,4 +1,4 @@
1
- import { a as buildFont, c as planWithBase, i as loadConfig, l as previewFont, o as estimateFont, r as FurifontConfigSchema, s as getDictionary, t as CONFIG_FILE } from "./config-BHN-5b6L.mjs";
1
+ import { a as bucketWords, c as getDictionary, i as loadConfig, l as planWithBase, o as buildFont, r as FurifontConfigSchema, s as estimateFont, t as CONFIG_FILE, u as previewFont } from "./config-CbOFGotB.mjs";
2
2
  import { mkdir, writeFile } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { BASE_FONTS } from "@furifont/compiler";
@@ -14,6 +14,40 @@ const BUILD_CHANNEL = "build";
14
14
  /** Where built fonts are served from, relative to the studio. */
15
15
  const FONTS_PATH = "/fonts/";
16
16
  const SEARCH_LIMIT = 40;
17
+ /** Words listed from each bucket of the overview. */
18
+ const SAMPLE_SIZE = 20;
19
+ /** How far, of one step, a sampled word may stray from its even place. */
20
+ const SAMPLE_JITTER = .6;
21
+ /** `count` indexes spread over `size`, one per step, each moved by up to half of {@link SAMPLE_JITTER} of a step either way. */
22
+ function spreadIndexes(size, count, random = Math.random) {
23
+ if (size <= count) return Array.from({ length: size }, (_, i) => i);
24
+ const step = size / count;
25
+ return Array.from({ length: count }, (_, n) => Math.min(size - 1, Math.max(0, Math.round(n * step + (random() - .5) * SAMPLE_JITTER * step))));
26
+ }
27
+ async function sampleWords(config, cwd) {
28
+ const [{ runs }, buckets] = await Promise.all([getDictionary(), bucketWords(config, cwd)]);
29
+ let offset = 0;
30
+ const sample = (words) => {
31
+ const start = offset;
32
+ offset += words.length;
33
+ return {
34
+ size: words.length,
35
+ words: spreadIndexes(words.length, SAMPLE_SIZE).map((i) => {
36
+ const form = words[i];
37
+ const [furigana] = Object.entries(runs[form] ?? {}).reduce((a, b) => b[1][0] > a[1][0] ? b : a);
38
+ return {
39
+ rank: start + i + 1,
40
+ notation: formatNotation(form, parseFurigana(furigana))
41
+ };
42
+ })
43
+ };
44
+ };
45
+ return {
46
+ skip: sample(buckets.skip),
47
+ take: sample(buckets.take),
48
+ rest: sample(buckets.rest)
49
+ };
50
+ }
17
51
  function wordReading(form, spans, [score, sources]) {
18
52
  return {
19
53
  notation: formatNotation(form, spans),
@@ -136,6 +170,12 @@ async function setupStudio(ctx) {
136
170
  type: "query",
137
171
  jsonSerializable: true,
138
172
  handler: (query) => searchWords(v.parse(Query, query))
173
+ }),
174
+ defineRpcFunction({
175
+ name: "sample",
176
+ type: "query",
177
+ jsonSerializable: true,
178
+ handler: (options) => sampleWords(parse(options), ctx.cwd)
139
179
  })
140
180
  ];
141
181
  for (const fn of functions) scope.rpc.register(fn);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "furifont",
3
3
  "type": "module",
4
- "version": "0.4.2",
4
+ "version": "0.5.1",
5
5
  "description": "Build Japanese fonts that show furigana by themselves, from the command line or a local studio",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -15,7 +15,6 @@
15
15
  "keywords": [
16
16
  "font",
17
17
  "furigana",
18
- "ruby",
19
18
  "japanese",
20
19
  "opentype",
21
20
  "devframe"
@@ -36,9 +35,9 @@
36
35
  "dist"
37
36
  ],
38
37
  "dependencies": {
39
- "@furifont/compiler": "0.4.2",
40
- "@furifont/core": "0.4.2",
41
- "@furifont/dictionary": "0.4.2",
38
+ "@furifont/compiler": "0.5.1",
39
+ "@furifont/core": "0.5.1",
40
+ "@furifont/dictionary": "0.5.1",
42
41
  "cac": "^7.1.0",
43
42
  "devframe": "^1.2.5",
44
43
  "valibot": "^1.5.0"
@@ -1 +0,0 @@
1
- var e={meta:{title:`Furifont:自带振假名的日文字体`,description:`自带振假名的日语字体。`},nav:{demo:`简介`,docs:`文档`,customize:`自定义`,report:`报告`,github:`GitHub 仓库`,light:`切换到浅色`,dark:`切换到深色`,language:`语言`,rubyOff:`隐藏振假名`,rubyOn:`显示振假名`},footer:{fonts:`字体采用{license},源自 Source Han Sans 和 Source Han Serif。`,data:`读音数据来自 {jmdict}、{jmnedict}、{kanjidic}(EDRDG)、{furigana}、{japanpost}(地名)和 {desktoptetsu}(JR 站名),采用 CC BY-SA 4.0 许可。`,code:`工具采用 MIT 许可。`,report:`报告错误读音`,source:`GitHub 上的源代码`,made:`作者:{author}`,supported:`由 {vercel} 和{sponsors}支持`,sponsors:`赞助者`},copied:`已复制`,shuffle:`换一个例句`,editable:`示例文字,可以编辑。`,scripts:{hiragana:`平假名`,hepburn:`罗马字`},faces:{sans:`黑体`,serif:`宋体`},hero:{title1:`振假名,`,title2:`交给字体。`,body:`Furifont 是一款把振假名直接显示在字体上的日语字体。它用连字(ligature)按词语的读音切换。只要支持自定义字体,哪里都能用。`,download:`下载字体`,build:`自己构建`},notice:`受字体限制,振假名可能不正确,请留意。`,sections:{try:`试一试`,how:`原理`,selectors:`选择读音`,download:`下载`,anyPage:`用于网站`},playground:{script:`振假名所用文字`,face:`字体样式`,size:`字号 / {size}px`,weight:`字重 / {weight}`,ruby:`振假名`,okurigana:`送假名读音`,okuriganaHint:`需要 JavaScript。受浏览器限制,字体无法自行处理送假名。`,textHint:`点击文字即可编辑。`,copy:`复制文本`},how:{build:{title:`定制构建`,body:`Furifont 以思源黑体或思源宋体为基础编译而成。构建时会读取包含数千个词的词典,并把振假名绘制成新的字形。得到的是普通的字体文件,不需要 JavaScript,也不需要插件。`},ligatures:{title:`由连字完成工作`,body:`字体中为每个词准备了连字。今日 会变成上方带有 きょう 的单个字形。替换发生在绘制文字时,所以文本本身不会改变。`},longest:{title:`长词优先`,body:`Furifont 把每一组汉字与几千个常用词的列表对照,先试最长的词。例如,会先选 日本語,再考虑 日本。今日 会当作一个词,读作 きょう。`},bare:{title:`拿不准就不加`,body:`只有一个汉字时,只有当某个读音明显最可能,才加振假名。大人気 可以读作 だいにんき,也可以读作 おとなげ,所以不加振假名。`},okurigana:{title:`可选的送假名支持`,body:`浏览器按字体的文字种类分别排版,所以字体看不到汉字后面的假名(称为送假名)。我们通过 JavaScript 标注,提供可选的支持。`}},selectors:{body:`有些词有多个常用读音。Furifont 显示最常见的那个。要选其他读音,就在第一个汉字后面紧跟一个变体选择器(看不见的字符)。VS226 是读音 1,VS227 是读音 2,依此类推。VS225 去掉振假名。`,lookUp:`查询读音`,default:`默认`,reading2:`读音 2(VS227)`,none:`无振假名(VS225)`},downloads:{all:`全部下载为 ZIP`,family:`字体家族`,ruby:`振假名`,variable:`可变`,formats:`OTF 和 TTF 常用于安装到电脑上。WOFF2 针对网站做了优化。我们推荐使用可变字体,体验最佳。在某些情况下,为了兼容性,你可能需要固定字重的版本。`,buildOwn:`你也可以自己制作字体。可以选择其他基础字体、词的数量、振假名所用文字或尺寸。`},anyPage:{body:`你可以在任何网站上使用 Furifont。有汉字的行会留出放振假名的空间。如果电脑上已安装 Furifont,就不用下载。否则字体会从本站加载。`,bookmarklet:`书签小工具`,bookmarkletHint:`把它拖到书签栏。在任何页面点击它,就会打开 Furifont;再点一次就会关闭。有些网站(如 X 和 GitHub)不允许加载其他网站的字体。在这些网站上,请在电脑上安装 Furifont。`,okurigana:`送假名读音`,okuriganaHint:`为送假名前的汉字选出正确的读音,例如「来る」「来ない」中的「来」。`,userscript:`用户脚本`,install:`安装用户脚本`,userscriptHint:`适用于 Tampermonkey 或 Violentmonkey(运行小脚本的浏览器扩展)。它会在日语页面自动打开 Furifont,在不允许加载其他网站字体的网站上也能用。你可以在它的菜单里切换到另一款 Furifont 字体,或将其关闭。`,toast:{message:`Furifont 无法在此页面加载字体。有些网站(如 X 和 GitHub)不允许加载其他网站的字体。在这些网站上,需要在电脑上安装 Furifont。`,download:`下载字体`,close:`关闭`,outdated:`Furifont 有新版本了。`,userscript:`更新用户脚本`,bookmarklet:`获取新的书签小工具`},menu:{okuriganaOn:`送假名读音:开`,okuriganaOff:`送假名读音:关`}},reference:{eyebrow:`参考`,title:`选择读音`,body:`Furifont 显示词最常见的读音。要显示其他读音,就在词的第一个汉字后面紧跟一个变体选择器(看不见的字符)。VS226 是读音 1,VS227 是读音 2,依此类推。单个汉字后面的选择器,选的是这个汉字的读音。VS225 显示不带振假名的汉字。`,search:`搜索词语或汉字:市場、今日、生`,searchLabel:`搜索读音`,hint:`点击读音即可复制带选择器的词语。`,unavailable:`参考表随现成字体一起提供,但这里没能加载({error})。请用 {command} 制作字体,或打开自定义。`,loading:`加载中`,words:`有多个读音的词 / {count}`,kanji:`汉字 / {count}`,copyWith:`复制带 {selector} 的「{text}」`,default:`默认`},report:{eyebrow:`报告`,title:`报告错误读音`,body:`如果 Furifont 显示了错误的假名注音,或该有注音的词没有注音,请告诉我们这些词和正确的读音。可以一次报告多个词。我们会根据报告修正词典。`,link:`报告错误读音。`,sections:{words:`词语 / {count}`,environment:`出现的位置`,note:`其他`},word:`词语`,expected:`正确读音`,shown:`显示的读音(可选)`,context:`句子(可选)`,remove:`删除 {word}`,add:`添加词语`,environment:`环境`,environments:{playground:`本站的试用区`,website:`其他网站`,desktop:`桌面应用`,mobile:`移动应用`},family:`字体`,familyAny:`(不限)`,url:`页面地址(可选)`,app:`应用(可选)`,appPlaceholder:{desktop:`Word、Pages、VS Code`,mobile:`备忘录、Kindle`},os:`系统(可选)`,notePlaceholder:`任何有帮助的信息,例如浏览器,或读音错误的原因。`,name:`你的名字(可选)`,nameHint:`修正读音时用于致谢。留空即可匿名。`,send:`发送报告`,sending:`发送中`,sent:`感谢你的报告。`,again:`继续报告`,failed:`报告发送失败,请稍后再试。`,limited:`你在短时间内发送了太多报告,请一小时后再试。`,privacy:`我们会保存你填写的内容、字体版本和浏览器名称,不会保存你的 IP 地址。`},docs:{install:`安装字体`,website:`在网站上使用`,readings:`选择读音`},customize:{connecting:`正在连接 furifont dev`,title:`自定义`,offline:{eyebrow:`自定义 / 离线`,title:`构建你自己的 Furifont`,body:`自定义是运行在你电脑上的工具。它读取基础字体,并保存制作好的字体。在任意文件夹中启动它,本页就会连接上并打开,提供实时预览、词典和构建按钮。制作好的字体保存在 {folder}。`,needs:`需要 Node 22.18 或更高版本(一个运行 JavaScript 工具的免费程序)。`,run:`在任意文件夹中启动自定义`},auth:{eyebrow:`自定义 / 已锁定`,title:`输入终端中显示的验证码`,body:`{command} 在你的终端(输入命令的窗口)中显示了一个六位数验证码。`,code:`验证码`,failed:`验证码无效,请查看终端后重试。`,unlock:`解锁`},sections:{preview:`预览`,build:`构建`,dictionary:`词典`,words:`你的词语`},options:{family:`字体名称`,base:`基础字体`,baseHint:`要加振假名的字体。可以是要下载的字体,如 Source Han Serif JP Bold,也可以是电脑上另一个字体文件的路径。`,script:`振假名所用文字`,hiragana:`平假名`,katakanaOn:`片假名`,hepburn:`罗马字`,skip:`跳过最常见的词`,skipHint:`在剩下的词中,最常见的不加振假名,因为读者已经认识。词语和单个汉字按常用程度排序,每 500 个一档。`,words:`接着加振假名的词数`,wordsHint:`接下来的词,按常用程度依次选取。共 {count} 个词加振假名。`,jlpt:`跳过 JLPT 词汇`,jlptHint:`JLPT(日本语能力测试)词表中到这个级别为止的词不加振假名。N5 是最简单的级别。`,none:`无`,all:`全部`,sources:`从以下来源选词`,source:{jmdict:{name:`JMdict 全部词语`,hint:`JMdict:所有词语,包括任何列表都没有排名的词语,例如 四字熟語。无排名的词语在没有其他内容匹配的文字上使用,会使字体增大约 700 KB。`},ichi:{name:`基础词`,hint:`JMdict“ichi1”和“ichi2”:“一万语”词表(基础词汇表)中的词。`},news:{name:`报纸用词`,hint:`JMdict“news1”和“news2”:报纸中出现最多的 24,000 个词。`},spec:{name:`日常词`,hint:`JMdict“spec1”和“spec2”:其他词表没有收录的常用词,如 日本。`},gai:{name:`外来语`,hint:`JMdict“gai1”和“gai2”:日语从其他语言借来的常用词。`},nf:{name:`报纸排名`,hint:`JMdict“nf01”至“nf48”:报纸词表中有排名的词,每 500 个词一档。`},tatoeba:{name:`Tatoeba 例句`,hint:`Tatoeba:在例句中出现三次或以上的词语,例如 留守中,即使上面的列表都没有收录。`},place:{name:`地名`,hint:`JMnedict:站名和地名。在没有常用词匹配的文字上使用。`},"mahjong-yaku":{name:`麻将役种`,hint:`麻将的役种和牌名,例如 立直。在没有常用词匹配的文字上使用。`},"jr-stations":{name:`JR 站名`,hint:`Desktop Tetsu 列表中的 JR 站名,例如 阿蘇。在没有常用词匹配的文字上使用。`},yojijukugo:{name:`四字熟语`,hint:`JMdict:四字熟语,例如 阿鼻叫喚。在没有常用词匹配的文字上使用。`},"japan-post":{name:`市区町村与町域`,hint:`日本邮政邮政编码数据中的市区町村和町域名称,例如 一宮。在没有常用词匹配的文字上使用。`}},isolated:`单个汉字也加振假名`,share:`单个汉字的把握度`,shareHint:`只有一个汉字时,只有当某个读音在词典中至少占这个比例,才加振假名。请输入 0.5 到 1 之间的数。数字越大,加振假名的汉字越少。`,rubyScale:`振假名大小(汉字的几倍)`,rubyGap:`汉字上方的间距(em)`,squeeze:`最窄压缩到(正常宽度的几倍)`,maxWidth:`振假名最大宽度(em)`,reset:`恢复默认`,resetHint:`回到自定义载入的设置。你添加的词会保留。`},preview:{compiling:`正在制作预览`,weight:`预览字重`,size:`预览字号`,stats:`{glyphs} 个字形 / {ms} ms`},build:{words:`词语`,places:`地名`,ambiguous:`多读音`,lone:`单个汉字`,protected:`你的设置`,glyphs:`振假名字形`,rules:`规则`,planning:`规划中`,estimate:{woff2:`≈ {size} WOFF2`,otf:`{size} OTF`},formats:`格式`,estimating:`正在估算大小`,run:`构建字体`,save:`保存设置`},dictionary:{search:`搜索词典:今日、生`,results:`{count} 个词`,hint:`这些词有多个常用读音。固定其中一个,它就成为默认读音。`,noTag:`不是常用词`,restore:`恢复`,remove:`不加振假名`},custom:{placeholder:`日[に]本[ほん] 或 今日[きょう]`,label:`要添加的词`,add:`添加词语`,added:`已添加 / {count}`,pinned:`已固定 / {count}`,removed:`不加振假名 / {count}`,none:`无`,takeOut:`移除 {item}`}}};export{e as default};
@@ -1 +0,0 @@
1
- import{B as e,E as t,N as n,S as r,Vt as i,W as a,Y as o,bt as s,mt as c,nt as l,pt as u,rt as d,tt as f}from"./CkUAspOr.js";import{_ as p,i as m}from"./Dg3RF8xB.js";import{C as h,T as g,_,a as v,b as y,c as b,d as x,f as S,g as C,h as w,i as T,m as E,n as D,p as O,r as k,s as A,u as j,v as M,x as N,y as P}from"./ez7nRQJI.js";var F=[`hiragana`,`katakanaOn`,`hepburn`],I=[`jmdict`,`ichi`,`news`,`spec`,`gai`,`nf`,`tatoeba`,`place`,`mahjong-yaku`,`jr-stations`,`yojijukugo`,`japan-post`],L=[`N5`,`N4`,`N3`,`N2`,`N1`],R=[...I,...L,`inflecting`,`default`],z=e=>1<<R.indexOf(e),B=w({rubyScale:C(P(E(),S(.2),j(.8)),p.plan.metrics.rubyScale),rubyGap:C(P(E(),S(0),j(.5)),p.plan.metrics.rubyGap),compressionFloor:C(P(E(),S(.3),j(1)),p.plan.metrics.compressionFloor),maxRubyWidth:C(P(E(),S(1),j(3)),p.plan.metrics.maxRubyWidth)}),V=P(E(),A(),S(0)),H=w({family:C(P(h(),g(),O(),T(e=>!/source/i.test(e),`Source is a reserved font name of the base font`)),p.plan.family),rubyScript:C(M(F),p.plan.rubyScript),sources:C(D(M(I)),()=>[...I]),skip:C(V,p.plan.skip),take:C(P(V,S(1))),skipJlpt:C(M(L)),isolated:C(k(),p.plan.isolated),isolatedMinShare:C(P(E(),S(.5),j(1)),p.plan.isolatedMinShare),words:C(w({add:C(D(h()),[]),remove:C(D(h()),[]),pin:C(D(h()),[])}),{}),metrics:C(B,{})});function U(e={}){return _(H,e)}var W=P(E(),A(),S(0),j(1114111));w({version:b(1),names:w({family:h(),description:h()}),metrics:w({rubyScale:E(),rubyGap:E(),compressionFloor:E(),maxRubyWidth:E()}),codepoints:D(W),variants:D(w({name:P(h(),N(/^[A-Z_][\w.]{0,62}$/i)),base:W,selector:W})),glyphs:D(w({name:P(h(),N(/^[A-Z_][\w.]{0,62}$/i)),bases:P(D(W),x(1)),ruby:D(w({start:E(),end:E(),text:P(h(),O())}))})),fea:h(),subset:C(D(W)),smoke:D(w({text:h(),glyphs:D(h())}))});var G=e=>typeof e==`object`&&!!e&&!Array.isArray(e),K=e=>Array.isArray(e)&&e.length===2&&e.every(Number.isInteger)&&e[0]>=0&&e[0]<=100&&e[1]>0&&e[1]<1<<R.length,q=v(e=>G(e)&&Object.values(e).every(e=>G(e)&&Object.values(e).every(K)),`Expected readings by run, each [score, sources]`),J=Object.fromEntries(R.map(e=>[e,z(e)]));w({versions:y(h(),h()),sources:v(e=>G(e)&&JSON.stringify(e)===JSON.stringify(J),`Expected the sources of this version of @furifont/core`),onyomi:y(h(),D(h())),runs:q,kanji:q,bare:D(h())});function Y(){let e=c(),t;async function n(n){await navigator.clipboard?.writeText(n).then(()=>!0,()=>!1)&&(e.value=n,clearTimeout(t),t=setTimeout(()=>e.value=void 0,1200))}return{copied:u(e),copy:n}}var{rubyScale:X,rubyGap:Z}=U().metrics,Q=1.75,ee=.88+Z+X,$=1.255,te={rubyTop:$-ee,emTop:.3749999999999999,baseline:$,emBottom:1.375},ne=[`aria-label`],re=Object.assign(n({__name:`FuriText`,props:e({family:{default:()=>m[0].family},ruby:{type:Boolean,default:!0},size:{default:32},weight:{default:400},okurigana:{}},{text:{required:!0},textModifiers:{}}),emits:[`update:text`],setup(e){let n=f(e,`text`),c=r(()=>({fontFamily:`"${e.family}", sans-serif`,fontSize:`${e.size}px`,fontWeight:e.weight,lineHeight:Q,fontFeatureSettings:e.ruby?`normal`:`"ss01"`}));function u(e){let t=[],n=0;for(let r of e.childNodes){let e=r.textContent.length;r instanceof HTMLElement&&t.push({at:n,length:e,salt:Number(r.dataset.salt)}),n+=e}return t}function p(e){let t=getSelection();if(!t?.rangeCount||!t.isCollapsed||!e.contains(t.anchorNode))return;let n=document.createRange();return n.selectNodeContents(e),n.setEnd(t.anchorNode,t.anchorOffset),n.toString().length}function m(e,t){let n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),r=t;for(let e=n.nextNode();e;e=n.nextNode()){let t=e.nodeValue.length;if(r<=t){let t=document.createRange();t.setStart(e,r),t.collapse(!0),getSelection().removeAllRanges(),getSelection().addRange(t);return}r-=t}}let h=l(`el`),g,_=!1,v;function y(t,n,r=!1){let i=e.ruby&&e.okurigana?e.okurigana.find(n):[];if(!r&&t.textContent===n&&JSON.stringify(u(t))===JSON.stringify(i.map(({at:e,length:t,salt:n})=>({at:e,length:t,salt:n}))))return;let a=p(t),o=[],s=0;for(let e of i){o.push(n.slice(s,e.at));let t=document.createElement(`span`);t.textContent=n.slice(e.at,e.at+e.length),t.dataset.salt=String(e.salt),t.style.fontFeatureSettings=`"salt" ${e.salt}`,o.push(t),s=e.at+e.length}o.push(n.slice(s)),t.replaceChildren(...o.filter(e=>e!==``)),a!==void 0&&m(t,a)}d([h,n],([e,t])=>{e&&t!==g&&y(e,t,!0)},{immediate:!0}),d([()=>e.okurigana,()=>e.ruby],()=>{h.value&&y(h.value,g??n.value)});function b(){_=!0}function x(){_=!1,S()}function S(){g=h.value.innerText,n.value=g,clearTimeout(v),v=setTimeout(()=>!_&&h.value&&y(h.value,g),300)}return a(()=>clearTimeout(v)),(e,n)=>(o(),t(`p`,{ref_key:`el`,ref:h,lang:`ja`,contenteditable:`plaintext-only`,spellcheck:`false`,role:`textbox`,"aria-multiline":`true`,"aria-label":e.$t(`editable`),class:`cursor-text whitespace-pre-wrap break-words outline-1 outline-transparent outline-offset-4 transition-[outline-color] hover:outline-dashed hover:outline-[var(--ff-line)] focus:outline-dashed focus:outline-[var(--ff-fg)]`,style:i(s(c)),onInput:S,onCompositionstart:b,onCompositionend:x},null,44,ne))}}),{__name:`FuriText`});export{L as a,Y as i,te as n,H as o,Q as r,I as s,re as t};
@@ -1,3 +0,0 @@
1
- import{A as e,C as t,E as n,Ht as r,N as i,S as a,T as o,Vt as s,Y as c,Z as l,_ as u,at as d,bt as f,gt as p,j as m,mt as h,q as g,rt as _,s as v,t as y,ut as b,yt as x}from"./CkUAspOr.js";import{st as S,t as C}from"./Cl84O_XS.js";import{a as w,d as T,f as E,g as D,h as O,i as k,l as A,m as j,o as M,p as N,r as ee,s as te,u as P}from"./Dg3RF8xB.js";import{t as F}from"./ez7nRQJI.js";import{i as I,n as L,r as R,t as z}from"./BgIj0bEj.js";import{t as B}from"#entry";import{a as ne,i as V,n as re,r as H,t as U}from"./BJuAqPpj.js";import{n as W,t as G}from"./BaBNBiev.js";var K=Object.assign(i({__name:`UiTypeGrid`,props:{size:{}},setup(e){let t=a(()=>{let t=Math.round(L.baseline*e.size),n=n=>`${Math.round(t+(n-L.baseline)*e.size)}px`,r=e=>`transparent ${n(e)}, var(--ff-line) ${n(e)} calc(${n(e)} + 1px), transparent calc(${n(e)} + 1px)`,{emTop:i,emBottom:a}=L;return{backgroundImage:[`linear-gradient(${[i,a].map(r).join(`, `)})`,`linear-gradient(90deg, var(--ff-line) 1px, transparent 1px)`].join(`, `),backgroundSize:`100% ${e.size*R}px, ${e.size}px 100%`,backgroundPosition:`100vmax 100vmax`}});return(e,r)=>(c(),n(`div`,{"aria-hidden":`true`,class:`pointer-events-none absolute -inset-[100vmax] -z-1`,style:s(f(t))},null,4))}}),{__name:`UiTypeGrid`});function q(e){let t=new Map,n=/(?<!\p{sc=Han})\p{sc=Han}+(?=\p{sc=Hiragana})/gu,r=n=>{if(!t.has(n)){let r=new Map;for(let[t,i]of Object.entries(e.pairs[n]??{}))for(let e of i)r.set(e,t||null);t.set(n,r.size?{reading:r,longest:Math.max(...[...r.keys()].map(e=>e.length))}:void 0)}return t.get(n)},i=(t,n)=>{let r=t.length>[...t][0].length,i=(r?e.words[t]?.map(e=>[...e.matchAll(/\[([^\]]*)\]/g)].map(e=>e[1]).join(``)):e.readings[t])?.indexOf(n)??-1;return i>=+!!r&&i<15&&e.lone[t]!==n?i+1:0};return{find:e=>{let t=[];for(let{0:a,index:o}of e.matchAll(n)){let n=r(a),s=e.slice(o+a.length,o+a.length+(n?.longest??0)),c;for(let e=s.length;e>0&&c===void 0;e--)c=n?.reading.get(s.slice(0,e));let l=c?i(a,c):0;c&&l&&t.push({at:o,length:a.length,reading:c,salt:l})}return t},saltOf:i}}var J=new Map;function Y(e,t){let n=J.get(e);return n||(n=(t?t(e):fetch(e).then(t=>t.ok?t.text():Promise.reject(Error(e)))).then(JSON.parse),n.catch(()=>J.delete(e)),J.set(e,n)),n}async function X({readings:e,pairs:t,fetchText:n}){try{let[r,i]=await Promise.all([Y(e,n),Y(t,n)]);return r.salt===!0?q({pairs:i,readings:r.kanji,words:r.words,lone:r.lone}):void 0}catch{return}}function Z(e){let t=v().app.baseURL,n=p();async function r(){let r=x(e),i=await X({readings:`${t}${N(r,`ivs.json`)}`,pairs:`${t}okurigana.json`});r.stem===x(e).stem&&(n.value=i)}return g(r),_(()=>x(e).stem,r),{reader:n}}var ie={class:`grid lg:grid-cols-2`},ae={class:`flex flex-col gap-8 border-base px-6 py-16 lg:border-r lg:py-24`},oe={class:`display hero-title font-semibold`},se={class:`max-w-[46ch] text-[15px] lh-1.625 color-muted ws-pre-line`},ce={class:`flex flex-wrap gap-3`},le={class:`relative isolate flex flex-col justify-center gap-4 overflow-hidden border-t border-base px-6 py-12 lg:border-t-0`},ue={class:`relative`},de={key:0,class:`label no-ruby absolute right-3 bottom-3 border border-base bg-base px-2 py-1`},fe={class:`label absolute bottom-4 left-4 border border-base bg-base px-2 py-1`},Q=44,pe=Object.assign(i({__name:`DemoHero`,emits:[`download`],setup(i,{emit:s}){let l=s,u=h(V[0].text),p=a(()=>V.find(e=>e.text===u.value)?.author),{family:g,ruby:_,okurigana:v}=B(),{reader:y}=Z(g);return(i,a)=>{let s=G,h=K,x=z;return c(),n(`div`,ie,[t(`div`,ae,[a[4]||=t(`span`,{class:`label`},`振り仮名 / furigana`,-1),t(`h1`,oe,[e(r(i.$t(`hero.title1`)),1),a[3]||=t(`br`,null,null,-1),e(r(i.$t(`hero.title2`)),1)]),t(`p`,se,r(i.$t(`hero.body`)),1),t(`div`,ce,[m(s,{variant:`solid`,icon:`i-ph-download-simple`,onClick:a[0]||=e=>l(`download`)},{default:d(()=>[e(r(i.$t(`hero.download`)),1)]),_:1}),m(s,{to:`/customize`,icon:`i-ph-sliders-horizontal`},{default:d(()=>[e(r(i.$t(`hero.build`)),1)]),_:1})])]),t(`div`,le,[m(s,{icon:`i-ph-shuffle`,class:`absolute right-3 top-3 w-9 bg-base px-0`,"aria-label":i.$t(`shuffle`),title:i.$t(`shuffle`),onClick:a[1]||=e=>u.value=(`otherSample`in i?i.otherSample:f(ne))(f(u)).text},null,8,[`aria-label`,`title`]),t(`div`,ue,[m(h,{size:Q}),m(x,{text:f(u),"onUpdate:text":a[2]||=e=>b(u)?u.value=e:null,family:f(g).family,ruby:f(_),size:Q,okurigana:f(v)?f(y):void 0},null,8,[`text`,`family`,`ruby`,`okurigana`])]),f(p)?(c(),n(`span`,de,`⁄ `+r(f(p)),1)):o(``,!0),t(`span`,fe,r(f(g).family)+` Regular / `+r(Q)+`px`,1)])])}}}),{__name:`DemoHero`}),me={class:`grid lg:grid-cols-[340px_1fr]`},he={class:`flex flex-col gap-5 border-b border-base p-6 lg:border-b-0 lg:border-r`},ge={class:`flex flex-col gap-1.5`},_e={class:`text-xs lh-1.625 color-muted`},ve={class:`flex min-w-0 flex-col`},ye={class:`min-h-72 flex-1 px-6 py-8`},be={class:`flex items-center gap-3 border-t border-base px-6 py-3`},xe={class:`text-xs color-muted`},Se=Object.assign(i({__name:`DemoPlayground`,setup(i){let a=h(`今日は日本語の勉強をします。
2
- 明日は東京の大学へ行きます。
3
- 私は毎朝新聞を読みます。桜が咲きました。`),{face:o,script:s,ruby:l,okurigana:u,family:p,faces:g,scripts:_}=B(),{reader:v}=Z(p),y=h(30),x=h(400),{copied:S,copy:C}=I();return(i,h)=>{let T=H,E=W,D=re,O=U,k=z,A=G;return c(),n(`div`,me,[t(`div`,he,[m(E,{label:i.$t(`playground.script`)},{default:d(()=>[m(T,{modelValue:f(s),"onUpdate:modelValue":h[0]||=e=>b(s)?s.value=e:null,label:i.$t(`playground.script`),options:f(_)},null,8,[`modelValue`,`label`,`options`])]),_:1},8,[`label`]),m(E,{label:i.$t(`playground.face`)},{default:d(()=>[m(T,{modelValue:f(o),"onUpdate:modelValue":h[1]||=e=>b(o)?o.value=e:null,label:i.$t(`playground.face`),options:f(g)},null,8,[`modelValue`,`label`,`options`])]),_:1},8,[`label`]),m(E,{label:i.$t(`playground.size`,{size:f(y)})},{default:d(()=>[m(D,{modelValue:f(y),"onUpdate:modelValue":h[2]||=e=>b(y)?y.value=e:null,min:16,max:64},null,8,[`modelValue`])]),_:1},8,[`label`]),m(E,{label:i.$t(`playground.weight`,{weight:f(x)})},{default:d(()=>[m(D,{modelValue:f(x),"onUpdate:modelValue":h[3]||=e=>b(x)?x.value=e:null,min:`MIN_WEIGHT`in i?i.MIN_WEIGHT:f(M),max:`MAX_WEIGHT`in i?i.MAX_WEIGHT:f(w),step:10},null,8,[`modelValue`,`min`,`max`])]),_:1},8,[`label`]),m(O,{modelValue:f(l),"onUpdate:modelValue":h[4]||=e=>b(l)?l.value=e:null},{default:d(()=>[e(r(i.$t(`playground.ruby`)),1)]),_:1},8,[`modelValue`]),t(`div`,ge,[m(O,{modelValue:f(u),"onUpdate:modelValue":h[5]||=e=>b(u)?u.value=e:null},{default:d(()=>[e(r(i.$t(`playground.okurigana`)),1)]),_:1},8,[`modelValue`]),t(`p`,_e,r(i.$t(`playground.okuriganaHint`)),1)])]),t(`div`,ve,[t(`div`,ye,[m(k,{text:f(a),"onUpdate:text":h[6]||=e=>b(a)?a.value=e:null,family:f(p).family,ruby:f(l),size:f(y),weight:f(x),okurigana:f(u)?f(v):void 0},null,8,[`text`,`family`,`ruby`,`size`,`weight`,`okurigana`])]),t(`div`,be,[t(`div`,xe,r(i.$t(`playground.textHint`)),1),h[8]||=t(`div`,{class:`flex-auto`},null,-1),m(A,{variant:`ghost`,icon:f(S)?`i-ph-check`:`i-ph-copy`,onClick:h[7]||=e=>f(C)(f(a))},{default:d(()=>[e(r(f(S)?i.$t(`copied`):i.$t(`playground.copy`)),1)]),_:1},8,[`icon`])])])])}}}),{__name:`DemoPlayground`}),Ce={class:`overflow-hidden`},we={class:`-mb-px -mr-px grid sm:grid-cols-2 lg:grid-cols-3`},Te={class:`font-mono text-xs color-muted`},Ee={class:`text-base font-semibold tracking-tight`},De={class:`text-sm lh-1.625 color-muted`},Oe=Object.assign(i({__name:`DemoHowItWorks`,setup(e){let i=[`build`,`ligatures`,`longest`,`bare`,`okurigana`];return(e,a)=>(c(),n(`div`,Ce,[t(`ol`,we,[(c(),n(u,null,l(i,(n,i)=>t(`li`,{key:n,class:`flex flex-col gap-3 border-b border-r border-base p-8`},[t(`span`,Te,r(String(i+1).padStart(2,`0`)),1),t(`h3`,Ee,r(e.$t(`how.${n}.title`)),1),t(`p`,De,r(e.$t(`how.${n}.body`)),1)])),64))])]))}}),{__name:`DemoHowItWorks`}),ke={class:`grid sm:grid-cols-[1fr_2fr] overflow-hidden`},Ae={class:`flex flex-col gap-4 border-b border-base p-6 sm:border-b-0 sm:border-r`},je={class:`text-sm lh-1.625 color-muted`},Me={class:`grid grid-cols-2 lg:grid-cols-5 -mb-px -mr-px`},Ne={class:`label`},Pe=[`onClick`],Fe=Object.assign(i({__name:`DemoSelectors`,setup(i){let a=e=>String.fromCodePoint(917984+e),o=[{label:`selectors.default`,text:`市場`,code:`市場`},{label:`selectors.reading2`,text:`市${a(2)}場`,code:`市\\u{E01E2}場`},{label:`selectors.default`,text:`今日`,code:`今日`},{label:`selectors.reading2`,text:`今${a(2)}日`,code:`今\\u{E01E2}日`},{label:`selectors.none`,text:`今${a(0)}日`,code:`今\\u{E01E0}日`}],{copied:s,copy:p}=I(),{family:h,ruby:g}=B();return(i,a)=>{let _=G,v=z;return c(),n(`div`,ke,[t(`div`,Ae,[t(`p`,je,r(i.$t(`selectors.body`)),1),m(_,{to:`/reference`,icon:`i-ph-list-magnifying-glass`,class:`self-start`},{default:d(()=>[e(r(i.$t(`selectors.lookUp`)),1)]),_:1})]),t(`ul`,Me,[(c(),n(u,null,l(o,e=>t(`li`,{key:e.code,class:`flex flex-col gap-2 border-b border-r border-base p-4 last:border-r-0`},[m(v,{text:e.text,family:f(h).family,ruby:f(g),size:36},null,8,[`text`,`family`,`ruby`]),t(`span`,Ne,r(i.$t(e.label)),1),t(`button`,{type:`button`,class:`focus-ring self-start font-mono text-xs color-muted hover:color-base`,onClick:t=>f(p)(e.text)},r(f(s)===e.text?i.$t(`copied`):e.code),9,Pe)])),64))])])}}}),{__name:`DemoSelectors`}),Ie={},Le={class:`grid lg:grid-cols-[5fr_4fr]`},Re={class:`w-full border-b border-base text-sm lg:border-b-0 lg:border-r`},ze={class:`border-b border-base text-left`},Be={class:`label px-6 py-3 font-normal`},Ve={class:`label px-3 py-3 font-normal`},He={class:`label px-3 py-3 font-normal`},Ue={class:`px-6 py-3 font-medium`},We={class:`px-3 py-3 color-muted`},Ge={class:`px-3 py-3`},Ke={class:`flex gap-3 font-mono text-xs`},qe=[`href`],Je={class:`flex gap-3 font-mono text-xs`},Ye=[`href`],Xe={class:`flex flex-col gap-4 p-6`},Ze={class:`text-sm color-muted lh-1.625`},Qe={class:`text-sm color-muted lh-1.625`};function $e(i,a){let o=G;return c(),n(`div`,Le,[t(`table`,Re,[t(`thead`,null,[t(`tr`,ze,[t(`th`,Be,r(i.$t(`downloads.family`)),1),t(`th`,Ve,r(i.$t(`downloads.ruby`)),1),t(`th`,He,r(i.$t(`downloads.variable`)),1),(c(!0),n(u,null,l(`WEIGHTS`in i?i.WEIGHTS:f(E),e=>(c(),n(`th`,{key:e.style,class:`label px-3 py-3 font-normal`},r(e.style),1))),128))])]),t(`tbody`,null,[(c(!0),n(u,null,l(`FAMILIES`in i?i.FAMILIES:f(k),e=>(c(),n(`tr`,{key:e.stem,class:`border-b border-base last:border-b-0`},[t(`td`,Ue,r(e.family),1),t(`td`,We,r(i.$t(`scripts.${e.script}`)),1),t(`td`,Ge,[t(`span`,Ke,[(c(),n(u,null,l([`ttf`,`woff2`],n=>t(`a`,{key:n,href:(`releaseUrl`in i?i.releaseUrl:f(j))(`${e.stem}VF.${n}`),class:`focus-ring underline underline-offset-3 hover:color-muted`},r(n),9,qe)),64))])]),(c(!0),n(u,null,l(`WEIGHTS`in i?i.WEIGHTS:f(E),a=>(c(),n(`td`,{key:a.style,class:`px-3 py-3`},[t(`span`,Je,[(c(),n(u,null,l([`otf`,`woff2`],n=>t(`a`,{key:n,href:(`releaseUrl`in i?i.releaseUrl:f(j))(`${e.stem}-${a.style}.${n}`),class:`focus-ring underline underline-offset-3 hover:color-muted`},r(n),9,Ye)),64))])]))),128))]))),128))])]),t(`div`,Xe,[t(`p`,Ze,r(i.$t(`downloads.formats`)),1),m(o,{href:(`releaseUrl`in i?i.releaseUrl:f(j))(`Furifont.zip`),icon:`i-ph-download-simple`,class:`self-start`},{default:d(()=>[e(r(i.$t(`downloads.all`)),1)]),_:1},8,[`href`]),t(`p`,Qe,r(i.$t(`downloads.buildOwn`)),1),m(o,{to:`/customize`,icon:`i-ph-sliders-horizontal`,class:`self-start`},{default:d(()=>[e(r(i.$t(`nav.customize`)),1)]),_:1})])])}var et=Object.assign(y(Ie,[[`render`,$e]]),{__name:`DemoDownloads`}),tt='var Furifont=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t={fonts:[{family:`Furifont Sans`,base:`Source Han Sans JP`,face:`sans`,rubyScript:`hiragana`},{family:`Furifont Sans Romaji`,base:`Source Han Sans JP`,face:`sans`,rubyScript:`hepburn`},{family:`Furifont Serif`,base:`Source Han Serif JP`,face:`serif`,rubyScript:`hiragana`},{family:`Furifont Serif Romaji`,base:`Source Han Serif JP`,face:`serif`,rubyScript:`hepburn`}],weights:[{style:`Regular`,weight:400}],variable:{style:`VF`,weights:[250,900]},options:{take:4e4}},n={base:12290,selector:65024},r=`U+2E80-2FDF,U+3000-30FF,U+3190-319F,U+31F0-31FF,U+3400-4DBF,U+4E00-9FFF,U+F900-FAFF,U+FE00-FE0F,U+FF00-FFEF,U+20000-3FFFF,U+E0100-E01EF`,i=/[\\p{sc=Han}\\p{sc=Hiragana}\\p{sc=Katakana}]/u;function a(e){return(e.match(/\\s*(?:"(?:[^"\\\\]|\\\\.)*"|\'(?:[^\'\\\\]|\\\\.)*\'|[^,]+)/g)??[]).map(e=>e.trim()).filter(Boolean)}function o(e){return e.replace(/^(["\'])(.*)\\1$/,`$2`)}let s=/mono|courier|consol|menlo|monaco|等幅/i;function c(e){let t=e.map(o);return t.some(e=>e===`monospace`||e===`ui-monospace`)||s.test(t[0]??``)}async function l({family:e,url:n,fetchFont:i}){let a=(t,n=`400`)=>new FontFace(e,t,{unicodeRange:r,weight:n}).load().catch(()=>void 0),o=await Promise.all(t.weights.map(({style:t,weight:n})=>a(`local("${e} ${t}")${n===400?`,local("${e}")`:``}`,String(n)))),s=t.variable.weights.join(` `),c=o.some(Boolean)?o:[await(i?i(n).then(e=>a(e,s),()=>void 0):a(`url("${n}")`,s))];for(let e of c)e&&document.fonts.add(e);return c.some(Boolean)}function u(e){let t=/* @__PURE__ */ new Map,n=/(?<!\\p{sc=Han})\\p{sc=Han}+(?=\\p{sc=Hiragana})/gu,r=n=>{if(!t.has(n)){let r=/* @__PURE__ */ new Map;for(let[t,i]of Object.entries(e.pairs[n]??{}))for(let e of i)r.set(e,t||null);t.set(n,r.size?{reading:r,longest:Math.max(...[...r.keys()].map(e=>e.length))}:void 0)}return t.get(n)},i=(t,n)=>{let r=t.length>[...t][0].length,i=(r?e.words[t]?.map(e=>[...e.matchAll(/\\[([^\\]]*)\\]/g)].map(e=>e[1]).join(``)):e.readings[t])?.indexOf(n)??-1;return i>=+!!r&&i<15&&e.lone[t]!==n?i+1:0};return{find:e=>{let t=[];for(let{0:a,index:o}of e.matchAll(n)){let n=r(a),s=e.slice(o+a.length,o+a.length+(n?.longest??0)),c;for(let e=s.length;e>0&&c===void 0;e--)c=n?.reading.get(s.slice(0,e));let l=c?i(a,c):0;c&&l&&t.push({at:o,length:a.length,reading:c,salt:l})}return t},saltOf:i}}let d=/* @__PURE__ */ new Map;function f(e,t){let n=d.get(e);return n||(n=(t?t(e):fetch(e).then(t=>t.ok?t.text():Promise.reject(Error(e)))).then(JSON.parse),n.catch(()=>d.delete(e)),d.set(e,n)),n}async function p({readings:e,pairs:t,fetchText:n}){try{let[r,i]=await Promise.all([f(e,n),f(t,n)]);return r.salt===!0?u({pairs:i,readings:r.kanji,words:r.words,lone:r.lone}):void 0}catch{return}}function m(e,t){return{href:new URL(`/#downloads`,e).href,text:t.download}}function h(e,t,n){document.querySelector(`furifont-toast`)?.remove();let r=document.createElement(`furifont-toast`),i=r.attachShadow({mode:`open`}),a=new CSSStyleSheet;a.replaceSync(`:host{all:initial}div{position:fixed;z-index:2147483647;right:16px;bottom:16px;display:flex;gap:16px;align-items:start;max-width:360px;padding:12px 16px;border:1px solid #fafafa2b;background:#0a0a0a;color:#fafafa;font:14px/1.5 system-ui,sans-serif}p{margin:0}a{color:inherit;margin-right:12px}button{padding:0;border:0;background:none;color:inherit;font:inherit;cursor:pointer}`),i.adoptedStyleSheets=[a];let o=document.createElement(`p`);o.append(e,` `,...t.map(({href:e,text:t})=>Object.assign(document.createElement(`a`),{href:e,target:`_blank`,rel:`noopener`,textContent:t})));let s=Object.assign(document.createElement(`button`),{ariaLabel:n,textContent:`×`,onclick:()=>r.remove()}),c=Object.assign(document.createElement(`div`),{role:`alert`});c.append(o,s),i.append(c),document.body.append(r),setTimeout(()=>r.remove(),1e4)}function g(e){let[t=0,n=0,r=0]=e.split(`.`).map(Number);return t*1e3+n*100+r}function _(e){let t=document.createElement(`canvas`).getContext(`2d`);return t.font=`1000px "${e}"`,Math.round(t.measureText(String.fromCodePoint(n.base,n.selector)).width)-2e3}async function v({family:e,url:t,toast:n},r){let i=new URL(`/version.json`,t).href,a;try{a=g(JSON.parse(await(r.fetchText?r.fetchText(i):fetch(i).then(e=>e.text()))).version)}catch{return}let o=[...g(r.version)<a?[r]:[],..._(e)<a?[m(t,n)]:[]];o.length&&h(n.outdated,o,n.close)}function y(e){let t=[];for(let n of e.filter(e=>e.isConnected)){let e=document.createTreeWalker(n,NodeFilter.SHOW_TEXT);for(let n=e.currentNode;n;n=e.nextNode())n.nodeType===Node.TEXT_NODE&&n.parentElement&&t.push(n)}return t}function b(e){let t=new Set(y(e).filter(e=>i.test(e.nodeValue??``)).map(e=>e.parentElement));for(let n of e){if(n.nodeType!==Node.ELEMENT_NODE)continue;let e=n;e.matches(`input,textarea`)&&t.add(e);for(let n of e.querySelectorAll(`input,textarea`))t.add(n)}return t}function x(e){let t=new CSSStyleSheet,n=[],r,i=0,s=()=>{for(let e of document.querySelectorAll(`[data-furifont-reading]`)){let t=r?r.saltOf(e.textContent??``,e.dataset.furifontReading):0;t?e.dataset.furifontSalt=String(t):delete e.dataset.furifontSalt}},l=e=>{if(!r)return;let t=y(e).filter(e=>/\\p{sc=Han}\\p{sc=Hiragana}/u.test(e.nodeValue??``)&&!e.parentElement.closest(`script,style,textarea,noscript,ruby,[contenteditable]:not([contenteditable=false]),[data-furifont-reading]`));for(let e of t)for(let{at:t,length:n,reading:i,salt:a}of r.find(e.nodeValue??``).reverse()){let r=t?e.splitText(t):e;r.length>n&&r.splitText(n);let o=document.createElement(`span`);o.dataset.furifontReading=i,o.dataset.furifontSalt=String(a),r.replaceWith(o),o.append(r)}},u={dispose:()=>{},sheet:t,family:e,restyle:()=>{let e=Array.from({length:15},(e,t)=>`[data-furifont-salt="${t+1}"]{font-feature-settings:"salt" ${t+1}!important}`).join(``),r=n.map((e,t)=>`[data-furifont="${t}"]{font-family:"${u.family}",${e}!important}`).join(``);t.replaceSync(`${r}[data-furifont-tight]{line-height:normal!important}ruby,ruby *{font-feature-settings:"ss01"!important}${e}`)},okurigana:e=>{let n=++i;r=void 0,s(),e&&!t.disabled&&p(e).then(e=>{n===i&&e&&(r=e,s(),l([document.body]))})}},d=e=>{let t=[...b(e)].filter(e=>!e.hasAttribute(`data-furifont`)).map(e=>{let{fontFamily:t,lineHeight:n,fontSize:r}=getComputedStyle(e),i=a(t);return o(i[0]??``)===u.family&&i.shift(),{element:e,stack:i,tight:Number.parseFloat(n)<1.6*Number.parseFloat(r)}}).filter(({stack:e})=>e.length&&!c(e)),r=n.length;for(let{element:e,stack:r,tight:i}of t){let t=r.join(`,`),a=n.includes(t)?n.indexOf(t):n.push(t)-1;e.setAttribute(`data-furifont`,String(a)),i&&e.setAttribute(`data-furifont-tight`,``)}n.length>r&&u.restyle()},f=new MutationObserver(e=>{let t=e.flatMap(e=>e.type===`characterData`?[e.target]:[...e.addedNodes]);d(t),l(t)});return u.dispose=()=>{f.disconnect(),i++,r=void 0,document.adoptedStyleSheets=document.adoptedStyleSheets.filter(e=>e!==t);for(let e of document.querySelectorAll(`[data-furifont],[data-furifont-tight]`))e.removeAttribute(`data-furifont`),e.removeAttribute(`data-furifont-tight`);for(let e of document.querySelectorAll(`[data-furifont-reading]`))e.replaceWith(...e.childNodes);window.furifont===u&&delete window.furifont},window.furifont=u,document.adoptedStyleSheets=[...document.adoptedStyleSheets,t],d([document.body]),f.observe(document.body,{childList:!0,characterData:!0,subtree:!0}),u}async function S(e){let{family:t,url:n,toast:r,okurigana:i,update:a}=e,o=window.furifont;o?.family===t?(o.sheet.disabled=!o.sheet.disabled,o.sheet.disabled||o.okurigana(i)):(o??=x(t),o.family=t,o.restyle(),o.sheet.disabled=!1,await l(e)?(o.okurigana(i),a&&await v(e,a)):(o.sheet.disabled=!0,o.family=``,h(r.message,[m(n,r)],r.close)))}return e.JAPANESE=i,e.UNICODE_RANGE=r,e.createOkuriganaReader=u,e.isMonospace=c,e.loadFurifont=l,e.loadOkuriganaReader=p,e.parseFontStack=a,e.showToast=h,e.toggleFurifont=S,e})({});',$={class:`grid lg:grid-cols-[340px_1fr]`},nt={class:`flex flex-col gap-5 border-b border-base p-6 lg:border-b-0 lg:border-r`},rt={class:`text-sm lh-1.625 color-muted`},it={class:`flex flex-col gap-1.5`},at={class:`text-xs lh-1.625 color-muted`},ot={class:`grid sm:grid-cols-2`},st={class:`flex flex-col gap-3 border-b border-base p-6 sm:border-b-0 sm:border-r`},ct={class:`label`},lt=[`href`],ut={class:`text-sm lh-1.625 color-muted`},dt={class:`flex flex-col gap-3 p-6`},ft={class:`label`},pt={class:`text-sm lh-1.625 color-muted`},mt=Object.assign(i({__name:`DemoAnyPage`,setup(i){let{t:o}=ee(),{face:s,script:l,okurigana:u,family:p,faces:h,scripts:g}=B(),_=a(()=>{let e={family:p.value.family,url:O(p.value),toast:{message:o(`anyPage.toast.message`),download:o(`anyPage.toast.download`),close:o(`anyPage.toast.close`),outdated:o(`anyPage.toast.outdated`)},okurigana:u.value?{readings:D(p.value),pairs:P}:void 0,update:{version:T,href:`${A}/#any-page`,text:o(`anyPage.toast.bookmarklet`)}};return`javascript:${encodeURIComponent(`void (()=>{${tt};Furifont.toggleFurifont(${JSON.stringify(e)})})()`)}`}),y=`${v().app.baseURL}furifont.user.js`;return(i,a)=>{let o=H,v=W,x=U,S=G;return c(),n(`div`,$,[t(`div`,nt,[t(`p`,rt,r(i.$t(`anyPage.body`)),1),m(v,{label:i.$t(`playground.script`)},{default:d(()=>[m(o,{modelValue:f(l),"onUpdate:modelValue":a[0]||=e=>b(l)?l.value=e:null,label:i.$t(`playground.script`),options:f(g)},null,8,[`modelValue`,`label`,`options`])]),_:1},8,[`label`]),m(v,{label:i.$t(`playground.face`)},{default:d(()=>[m(o,{modelValue:f(s),"onUpdate:modelValue":a[1]||=e=>b(s)?s.value=e:null,label:i.$t(`playground.face`),options:f(h)},null,8,[`modelValue`,`label`,`options`])]),_:1},8,[`label`]),t(`div`,it,[m(x,{modelValue:f(u),"onUpdate:modelValue":a[2]||=e=>b(u)?u.value=e:null},{default:d(()=>[e(r(i.$t(`anyPage.okurigana`)),1)]),_:1},8,[`modelValue`]),t(`p`,at,r(i.$t(`anyPage.okuriganaHint`)),1)])]),t(`div`,ot,[t(`div`,st,[t(`span`,ct,r(i.$t(`anyPage.bookmarklet`)),1),t(`a`,{href:f(_),class:`btn-solid focus-ring self-start`},[a[3]||=t(`span`,{class:`i-ph-bookmark-simple`},null,-1),e(` `+r(f(p).family),1)],8,lt),t(`p`,ut,r(i.$t(`anyPage.bookmarkletHint`)),1)]),t(`div`,dt,[t(`span`,ft,r(i.$t(`anyPage.userscript`)),1),m(S,{href:y,icon:`i-ph-puzzle-piece`,class:`self-start`},{default:d(()=>[e(r(i.$t(`anyPage.install`)),1)]),_:1}),t(`p`,pt,r(i.$t(`anyPage.userscriptHint`)),1)])])])}}}),{__name:`DemoAnyPage`}),ht={class:`flex items-center gap-2 border-t border-base px-6 py-3 text-xs color-muted bg-amber:5`},gt=[`href`],_t=i({__name:`index`,setup(i){function a(){document.getElementById(`downloads`)?.scrollIntoView({behavior:`smooth`})}let o=S();return g(()=>{o.hash&&document.getElementById(o.hash.slice(1))?.scrollIntoView({behavior:`smooth`})}),(i,o)=>{let s=pe,l=Se,u=F,p=Oe,h=Fe,g=C,_=et,v=mt;return c(),n(`div`,null,[m(s,{onDownload:a}),m(u,{index:`01`,title:i.$t(`sections.try`)},{default:d(()=>[m(l)]),_:1},8,[`title`]),m(u,{index:`02`,title:i.$t(`sections.how`)},{default:d(()=>[m(p)]),_:1},8,[`title`]),m(u,{index:`03`,title:i.$t(`sections.selectors`)},{default:d(()=>[m(h)]),_:1},8,[`title`]),t(`p`,ht,[o[0]||=t(`span`,{class:`i-ph-warning shrink-0 text-base text-amber`,"aria-hidden":`true`},null,-1),t(`span`,null,[e(r(i.$t(`notice`))+` `,1),m(g,{to:`/report`,class:`focus-ring underline underline-offset-3 hover:color-base`},{default:d(()=>[e(r(i.$t(`report.link`)),1)]),_:1})])]),m(u,{id:`downloads`,index:`04`,title:i.$t(`sections.download`)},{aside:d(()=>[o[1]||=t(`div`,{class:`flex-auto`},null,-1),t(`a`,{href:`RELEASE_URL`in i?i.RELEASE_URL:f(te),target:`_blank`,rel:`noopener`,class:`focus-ring self-start font-mono text-xs underline underline-offset-3 color-muted hover:color-inherit`},`v`+r(`VERSION`in i?i.VERSION:f(T)),9,gt)]),default:d(()=>[m(_)]),_:1},8,[`title`]),m(u,{id:`any-page`,index:`05`,title:i.$t(`sections.anyPage`)},{default:d(()=>[m(v)]),_:1},8,[`title`])])}}});export{_t as default};
@@ -1 +0,0 @@
1
- import{A as e,C as t,E as n,Ht as r,N as i,S as a,T as o,Y as s,Z as c,_ as l,at as u,bt as d,ft as f,j as p,mt as m,ot as h,t as g,ut as _,w as v,zt as y}from"./CkUAspOr.js";import{a as b,o as x,s as S}from"./D4ezFGbh.js";import{d as C,i as ee,l as w,r as T}from"./Dg3RF8xB.js";import{C as E,T as D,d as O,g as k,h as A,l as j,n as M,o as N,p as P,t as F,v as I,w as L,y as R}from"./ez7nRQJI.js";import{i as z}from"#entry";import{n as B,t as V}from"./BaBNBiev.js";var H=[`playground`,`website`,`desktop`,`mobile`];function U(e){return R(E(),D(),j(e))}function W(e){return R(U(e),P())}function G(e){return R(k(U(e)),L(e=>e||void 0))}var K=A({word:W(32),expected:W(64),shown:G(64),context:G(200)});A({words:R(M(K),O(1),j(20)),environment:A({type:I(H),url:G(500),app:G(100),os:G(100)}),family:G(100),version:W(32),locale:W(16),note:G(2e3),name:G(100),nickname:k(R(E(),N()))});var q={role:`status`,class:`flex flex-col items-center gap-6 px-6 py-24 text-center`},J={class:`display text-2xl font-semibold`},Y=[`onUpdate:modelValue`],X=[`onUpdate:modelValue`],Z=[`onUpdate:modelValue`],Q={class:`flex items-end gap-2 sm:col-span-3`},te=[`onUpdate:modelValue`],ne=[`aria-label`,`onClick`],re={class:`px-6 py-3`},ie={class:`grid gap-4 p-6 sm:grid-cols-2`},ae=[`value`],oe={value:``},se=[`value`],ce=[`placeholder`],le={class:`flex flex-col gap-4 p-6`},ue=[`placeholder`,`aria-label`],de={class:`flex flex-wrap items-center gap-4`},fe=[`disabled`],pe={key:0,role:`alert`,class:`text-xs color-muted`},$={class:`text-xs color-muted`},me=Object.assign(i({__name:`ReportForm`,setup(i){let g=`${w}/api/report`,{t:E,locale:D}=T(),O=()=>({word:``,expected:``,shown:``,context:``}),k=m([O()]),A=f({type:`playground`,url:``,app:``,os:``}),j=m(``),M=m(``),N=m(``),P=m(``),I=m(`idle`),L=a(()=>H.map(e=>({value:e,label:E(`report.environments.${e}`)}))),R=a(()=>k.value.every(e=>e.word.trim()&&e.expected.trim()));async function U(){I.value=`sending`;let e={words:k.value,environment:A,family:j.value,version:C,locale:D.value,note:M.value,name:N.value,nickname:P.value};try{await z(g,{method:`POST`,body:e}),I.value=`sent`}catch(e){I.value=e instanceof Error&&`statusCode`in e&&e.statusCode===429?`limited`:`failed`}}function W(){k.value=[O()],M.value=``,I.value=`idle`}return(i,a)=>{let f=V,m=F,g=B;return d(I)===`sent`?(s(),v(m,{key:0},{default:u(()=>[t(`div`,q,[a[9]||=t(`span`,{class:`i-ph-check-circle-light text-7xl`,"aria-hidden":`true`},null,-1),t(`p`,J,r(i.$t(`report.sent`)),1),p(f,{icon:`i-ph-plus`,onClick:W},{default:u(()=>[e(r(i.$t(`report.again`)),1)]),_:1})])]),_:1})):(s(),n(`form`,{key:1,onSubmit:S(U,[`prevent`])},[p(m,{index:`01`,title:i.$t(`report.sections.words`,{count:d(k).length})},{default:u(()=>[(s(!0),n(l,null,c(d(k),(e,r)=>(s(),n(`div`,{key:r,class:`grid gap-4 border-b border-base p-6 sm:grid-cols-3`},[p(g,{label:i.$t(`report.word`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":t=>e.word=t,required:``,maxlength:`32`,lang:`ja`,placeholder:`市場`,class:`input`},null,8,Y),[[x,e.word]])]),_:2},1032,[`label`]),p(g,{label:i.$t(`report.expected`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":t=>e.expected=t,required:``,maxlength:`64`,lang:`ja`,placeholder:`いちば`,class:`input`},null,8,X),[[x,e.expected]])]),_:2},1032,[`label`]),p(g,{label:i.$t(`report.shown`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":t=>e.shown=t,maxlength:`64`,lang:`ja`,placeholder:`しじょう`,class:`input`},null,8,Z),[[x,e.shown]])]),_:2},1032,[`label`]),t(`div`,Q,[p(g,{label:i.$t(`report.context`),class:`flex-1`},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":t=>e.context=t,maxlength:`200`,lang:`ja`,placeholder:`駅前の市場で魚を買った。`,class:`input`},null,8,te),[[x,e.context]])]),_:2},1032,[`label`]),d(k).length>1?(s(),n(`button`,{key:0,type:`button`,class:`btn-ghost focus-ring w-9 shrink-0 px-0`,"aria-label":i.$t(`report.remove`,{word:e.word||r+1}),onClick:e=>d(k).splice(r,1)},[...a[10]||=[t(`span`,{class:`i-ph-trash`},null,-1)]],8,ne)):o(``,!0)])]))),128)),t(`div`,re,[p(f,{variant:`ghost`,icon:`i-ph-plus`,disabled:d(k).length>=(`MAX_REPORT_WORDS`in i?i.MAX_REPORT_WORDS:d(20)),onClick:a[0]||=e=>d(k).push(O())},{default:u(()=>[e(r(i.$t(`report.add`)),1)]),_:1},8,[`disabled`])])]),_:1},8,[`title`]),p(m,{index:`02`,title:i.$t(`report.sections.environment`)},{default:u(()=>[t(`div`,ie,[p(g,{label:i.$t(`report.environment`)},{default:u(()=>[h(t(`select`,{"onUpdate:modelValue":a[1]||=e=>d(A).type=e,class:`input`},[(s(!0),n(l,null,c(d(L),e=>(s(),n(`option`,{key:e.value,value:e.value},r(e.label),9,ae))),128))],512),[[b,d(A).type]])]),_:1},8,[`label`]),p(g,{label:i.$t(`report.family`)},{default:u(()=>[h(t(`select`,{"onUpdate:modelValue":a[2]||=e=>_(j)?j.value=e:null,class:`input`},[t(`option`,oe,r(i.$t(`report.familyAny`)),1),(s(!0),n(l,null,c(`FAMILIES`in i?i.FAMILIES:d(ee),e=>(s(),n(l,{key:e.family},[(s(),n(l,null,c([`Regular`,`VF`],n=>t(`option`,{key:n,value:`${e.family} ${n}`},r(e.family)+` `+r(n),9,se)),64))],64))),128))],512),[[b,d(j)]])]),_:1},8,[`label`]),d(A).type===`website`?(s(),v(g,{key:0,label:i.$t(`report.url`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":a[3]||=e=>d(A).url=e,type:`url`,maxlength:`500`,placeholder:`https://`,class:`input`},null,512),[[x,d(A).url]])]),_:1},8,[`label`])):o(``,!0),d(A).type===`desktop`||d(A).type===`mobile`?(s(),v(g,{key:1,label:i.$t(`report.app`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":a[4]||=e=>d(A).app=e,maxlength:`100`,placeholder:i.$t(`report.appPlaceholder.${d(A).type}`),class:`input`},null,8,ce),[[x,d(A).app]])]),_:1},8,[`label`])):o(``,!0),p(g,{label:i.$t(`report.os`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":a[5]||=e=>d(A).os=e,maxlength:`100`,placeholder:`macOS 26, Windows 11, iOS 26`,class:`input`},null,512),[[x,d(A).os]])]),_:1},8,[`label`])])]),_:1},8,[`title`]),p(m,{index:`03`,title:i.$t(`report.sections.note`)},{default:u(()=>[t(`div`,le,[h(t(`textarea`,{"onUpdate:modelValue":a[6]||=e=>_(M)?M.value=e:null,maxlength:`2000`,rows:`4`,placeholder:i.$t(`report.notePlaceholder`),"aria-label":i.$t(`report.sections.note`),class:`input resize-y`},null,8,ue),[[x,d(M)]]),p(g,{label:i.$t(`report.name`),hint:i.$t(`report.nameHint`)},{default:u(()=>[h(t(`input`,{"onUpdate:modelValue":a[7]||=e=>_(N)?N.value=e:null,maxlength:`100`,autocomplete:`nickname`,class:`input`},null,512),[[x,d(N)]])]),_:1},8,[`label`,`hint`]),h(t(`input`,{"onUpdate:modelValue":a[8]||=e=>_(P)?P.value=e:null,name:`nickname`,tabindex:`-1`,autocomplete:`off`,"aria-hidden":`true`,class:`sr-only`},null,512),[[x,d(P)]]),t(`div`,de,[t(`button`,{type:`submit`,class:y([`focus-ring`,d(R)?`btn-solid`:`btn-outline`]),disabled:d(I)===`sending`},[a[11]||=t(`span`,{class:`i-ph-paper-plane-tilt`},null,-1),e(` `+r(d(I)===`sending`?i.$t(`report.sending`):i.$t(`report.send`)),1)],10,fe),d(I)===`failed`||d(I)===`limited`?(s(),n(`p`,pe,r(i.$t(`report.${d(I)}`)),1)):o(``,!0),t(`p`,$,r(i.$t(`report.privacy`)),1)])])]),_:1},8,[`title`])],32))}}}),{__name:`ReportForm`}),he={},ge={class:`flex flex-col gap-4 px-6 py-12`},_e={class:`label`},ve={class:`display text-4xl font-semibold`},ye={class:`max-w-[60ch] text-[15px] lh-1.625 color-muted ws-pre-line`};function be(e,i){let a=me;return s(),n(`div`,null,[t(`div`,ge,[t(`span`,_e,r(e.$t(`report.eyebrow`)),1),t(`h1`,ve,r(e.$t(`report.title`)),1),t(`p`,ye,r(e.$t(`report.body`)),1)]),p(a)])}var xe=g(he,[[`render`,be]]);export{xe as default};